home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 04 / quellen / draw4.inc < prev    next >
Encoding:
Text File  |  1979-12-31  |  8.0 KB  |  330 lines

  1. (*****************************************************************************)
  2. (*                            DRAW4.INC                                      *)
  3. (*                                                                           *)
  4. (*               Unterprogramm-Modul zum Zeichnen der Funktion               *)
  5. (*                   Speziell fuer Apple II+/e mit SoftCard                  *)
  6. (*****************************************************************************)
  7.  
  8. PROCEDURE plotfunction;
  9.  
  10. VAR xmin,xmax, ymin,ymax, dx,dy,x,d, s1,f1,f2   : REAL;
  11.     s,grad,i,j : INTEGER;
  12.     key        : CHAR;
  13.     ok         : BOOLEAN;
  14.  
  15.    (* Hier beginnt der hardwareabhaengige Teil *)
  16.  
  17. CONST screenxmax = 279;  (* Anzahl Bildpunkte horizontal                 *)
  18.       screenymax = 191;  (*                   vertikal                   *)
  19.       left       =  5;   (* Abstand Zeichenflaeche-linker Bildschirmrand *)
  20.       bottom     =  5;   (*                       -unterer               *)
  21.       unit       = 4;    (* halbe Breite der Achsenunterteilungsstriche  *)
  22.       hgrpage    = 2;    (* Grafikseite; fuer SoftCard immer 2 !         *)
  23.  
  24. VAR   conoutptr_bak : INTEGER;
  25.  
  26. { 6502 - Interface fuer Turbo-Pascal unter SoftCard}
  27.  
  28. VAR  A_REG   : BYTE    ABSOLUTE $F045;
  29.      X_REG   : BYTE    ABSOLUTE $F046;
  30.      Y_REG   : BYTE    ABSOLUTE $F047;
  31.      XY_REG  : INTEGER ABSOLUTE $F046;
  32.      AX_REG  : INTEGER ABSOLUTE $F045;
  33.      A_RES   : BYTE    ABSOLUTE $F045;
  34.      X_RES   : BYTE    ABSOLUTE $F046;
  35.      Y_RES   : BYTE    ABSOLUTE $F047;
  36.  
  37.  
  38. FUNCTION CHADDR(ADR : INTEGER) : INTEGER;
  39. BEGIN
  40.   CASE HI(ADR) OF
  41.     $00..$0F : CHADDR := ADR + $F000;
  42.     $10..$BF : CHADDR := ADR - $1000;
  43.     $C0..$CF : CHADDR := ADR + $2000;
  44.     $D0..$FF : CHADDR := ADR - $2000;
  45.   END
  46. END;
  47.  
  48. FUNCTION R6502(ADR : INTEGER) : BYTE;
  49. BEGIN
  50.  R6502 := MEM[CHADDR(ADR)]
  51. END;
  52.  
  53. PROCEDURE W6502(ADR : INTEGER; VAL : BYTE);
  54. BEGIN
  55.   MEM[CHADDR(ADR)] := VAL
  56. END;
  57.  
  58. PROCEDURE S6502(ADR : INTEGER);
  59. VAR DUMMY : BYTE;
  60. BEGIN
  61.   MEM[CHADDR(ADR)] := 0
  62. END;
  63.  
  64. PROCEDURE CALL6502(ADR : INTEGER);
  65. BEGIN
  66.   INLINE ($2A/ADR/
  67.           $22/$F3D0/
  68.           $2A/$F3DE/
  69.           $77)
  70. END;
  71.  
  72. { Ende des Interface-Blocks fuer SoftCard }
  73. {====================================================================}
  74.  
  75.   PROCEDURE dummy( a : CHAR);  (* faengt Bildschirmausgabe ab *)
  76.   BEGIN END;
  77.  
  78.   PROCEDURE color(cl : INTEGER);
  79.  
  80.   BEGIN
  81.     x_reg := cl;
  82.     call6502($f6f0);
  83.   END;
  84.  
  85.   PROCEDURE initgraphic;     (* Voreinstellungen fuer Grafikbetrieb *)
  86.  
  87.   CONST gr = $c050;
  88.         nomix = $c052;
  89.         pageslct = $c053;
  90.         hires = $c057;
  91.         apple_io = $c000;
  92.         screen_80 = $c00c;
  93.         page = $e6;
  94.  
  95.   BEGIN
  96.     Clrscr;
  97.     w6502(page,hgrpage * $20);
  98.     call6502($f3f2);
  99.     color(3);
  100.     w6502(screen_80,0);
  101.     w6502(apple_io,0);
  102.     s6502(gr);
  103.     s6502(nomix);
  104.     s6502(pageslct + hgrpage);
  105.     s6502(hires);
  106.     conoutptr_bak := conoutptr;
  107.     conoutptr := addr(dummy);
  108.   END;
  109.  
  110.   PROCEDURE leavegraphic;    (* Voreinstellungen fuer Textbetrieb *)
  111.  
  112.   CONST txt = $c051;
  113.         pageslct = $c053;
  114.         nohires = $c056;
  115.         secoff = $c054;
  116.         apple_io = $c001;
  117.         screen_80 = $c00d;
  118.  
  119.   BEGIN
  120.     s6502(nohires);
  121.     s6502(secoff);
  122.     s6502(pageslct);
  123.     s6502(txt);
  124.     w6502(apple_io,0);
  125.     w6502(screen_80,0);
  126.     conoutptr := conoutptr_bak;
  127.     Clrscr;
  128.   END;
  129.  
  130.   FUNCTION checkkoord(VAR x,y : INTEGER) : BOOLEAN;
  131.  
  132.   VAR ok : BOOLEAN;
  133.  
  134.   BEGIN
  135.     ok := TRUE;
  136.     IF x < 0
  137.       THEN
  138.         BEGIN
  139.           x := 0 ;
  140.           ok := FALSE
  141.         END
  142.       ELSE
  143.         IF x > screenxmax
  144.           THEN
  145.             BEGIN
  146.               x := screenxmax;
  147.               ok := FALSE
  148.             END;
  149.     IF y < 0
  150.       THEN
  151.         BEGIN
  152.           y := 0;
  153.           ok := FALSE
  154.         END
  155.       ELSE
  156.         IF y > screenymax
  157.           THEN
  158.             BEGIN
  159.               y := screenymax;
  160.               ok := FALSE
  161.             END;
  162.     checkkoord := ok
  163.   END;
  164.  
  165.   PROCEDURE position (x,y : INTEGER);
  166.  
  167.   BEGIN
  168.     a_reg := screenymax - y;
  169.     xy_reg := x;
  170.     call6502($f411);
  171.   END;
  172.  
  173.   PROCEDURE plot (x,y :INTEGER);    (* Punkt bei (x,y) zeichnen *)
  174.  
  175.   BEGIN
  176.     IF checkkoord(x,y)
  177.       THEN
  178.         BEGIN
  179.           xy_reg := x;
  180.           a_reg  := screenymax - y;
  181.           call6502 ($f457)
  182.         END
  183.       ELSE
  184.         position(x,y);
  185.   END;
  186.  
  187.   PROCEDURE draw (x1,y1,x2,y2 :INTEGER);(* Linie von (x1,y1) nach (x2,y2) *)
  188.  
  189.   BEGIN
  190.     plot(x1,y1);
  191.     IF checkkoord(x2,y2)
  192.       THEN
  193.         BEGIN
  194.           ax_reg := x2;
  195.           y_reg  := screenymax - y2;
  196.           call6502 ($f53a)
  197.         END
  198.       ELSE
  199.         position(x2,y2)
  200.   END;
  201.    (* hier endet der hardwareabhaengige Teil *)
  202.  
  203.   PROCEDURE worldtoscreen (x,y :REAL; VAR xs,ys :INTEGER);
  204.  
  205.   VAR a,b : REAL;
  206.  
  207.   BEGIN
  208.     a := (x - xmin)*(screenxmax-left)/(xmax-xmin);
  209.     b := (y - ymin)*(screenymax-bottom)/(ymax-ymin);
  210.     IF Abs(a) > 32000.0
  211.       THEN
  212.         a := sign(a)*32000.0;
  213.     IF Abs(b) > 32000.0
  214.       THEN
  215.         b := sign(b)*32000.0;
  216.     xs := Round(a) + left;
  217.     ys := Round(b) + bottom
  218.   END;
  219.  
  220.   PROCEDURE drawpoint (x,y :REAL);(* zeichnet Punkt in Weltkoordinaten *)
  221.  
  222.   VAR xp,yp : INTEGER;
  223.  
  224.   BEGIN
  225.     worldtoscreen (x,y,xp,yp);
  226.     plot (xp,yp)
  227.   END;
  228.  
  229.   PROCEDURE drawline (x1,y1,x2,y2 :REAL);(* zeichnet Linie in Weltkoordinaten *)
  230.  
  231.   VAR xp1,yp1,xp2,yp2 : INTEGER;
  232.  
  233.   BEGIN
  234.     worldtoscreen (x1,y1,xp1,yp1);
  235.     worldtoscreen (x2,y2,xp2,yp2);
  236.     draw (xp1,yp1,xp2,yp2)
  237.   END;
  238.  
  239.   PROCEDURE drawaxis;   (* zeichnet das Achsenkreuz *)
  240.  
  241.   VAR x,y,dist : REAL;
  242.  
  243.   BEGIN
  244.     draw (left,bottom,left,screenymax);
  245.     draw (left,bottom,screenxmax,bottom);
  246.     drawline (xmin,0,xmax,0);
  247.     drawline (0,ymin,0,ymax);
  248.     dist := dy*(screenymax-bottom)/(ymax-ymin);(* Abstand y-Unterteilung *)
  249.     x := left;
  250.     y := bottom;
  251.     WHILE y<=screenymax DO
  252.       BEGIN
  253.         draw (Round(x-unit),Round(y),Round(x+unit),Round(y));
  254.         y := y + dist
  255.       END;
  256.     dist := dx*(screenxmax-left)/(xmax-xmin);(* Abstand y-Unterteilung *)
  257.     x := left;
  258.     y := bottom;
  259.     WHILE x<=screenxmax DO
  260.       BEGIN
  261.         draw (Round(x),Round(y-unit),Round(x),Round(y+unit));
  262.         x := x + dist
  263.       END;
  264.   END;
  265.  
  266. BEGIN
  267.   Clrscr;
  268.   Writeln ('Funktion zeichnen');
  269.   REPEAT
  270.     Writeln;
  271.     formulaln (xmin,'im Bereich von xmin = ');
  272.     formulaln (xmax,'           bis xmax = ');
  273.   UNTIL xmin < xmax;
  274.   REPEAT
  275.     formulaln (dx, 'mit Schrittweite dx = ');
  276.   UNTIL dx > 0.0;
  277.   REPEAT
  278.     Writeln;
  279.     formulaln (ymin,'           von ymin = ');
  280.     formulaln (ymax,'           bis ymax = ');
  281.   UNTIL ymin < ymax;
  282.   REPEAT
  283.     formulaln (dy, ' mit Schrittweite dy = ');
  284.   UNTIL dy > 0.0;
  285.   Writeln;
  286.   REPEAT
  287.     formulaln (s1,'Anzahl der zu berechnenden Stuetzstellen : ');
  288.     s := Round(s1);
  289.   UNTIL s >= 0;
  290.   if s = 0 THEN s := screenxmax-left;
  291.   Writeln;
  292.   Writeln('Welche Funktion soll gezeichnet werden ?');
  293.   Writeln;
  294.   for i := 0 to maxgrad do
  295.   BEGIN
  296.     Write('         f');
  297.     for j := 1 to i do Write('''');
  298.     Write('':maxgrad-i, '  : ',i:3);
  299.     WriteLn
  300.   END;
  301.   Writeln;
  302.   Write('Bitte waehlen :   ');
  303.   REPEAT
  304.     Read(kbd,key);
  305.   UNTIL key in ['0'..chr(maxgrad+ord('0'))];
  306.   grad := ord(key) - ord('0');
  307.   initgraphic;                               (* Grafik initialisieren *)
  308.   drawaxis;                                  (* Achsenkreuz zeichnen  *)
  309.   x := xmin;
  310.   d := (xmax-xmin)/s;
  311.   f1 := fn(x,grad);
  312.   ok := calcresult;
  313.   f2 := fn(x+d,grad);
  314.   ok := ok AND calcresult;
  315.   WHILE (x+d<=xmax) AND NOT Keypressed DO
  316.     BEGIN
  317.       IF ok
  318.         THEN
  319.           drawline (x,f1,x+d,f2);     (* Zeichnen der Funktion *)
  320.       x := x + d;
  321.       f1 := fn(x,grad);
  322.       ok := calcresult;
  323.       f2 := fn(x+d,grad);
  324.       ok := ok AND calcresult;
  325.     END;
  326.   REPEAT UNTIL keypressed;
  327.   leavegraphic
  328. END;
  329.  
  330.