home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / coregraf / gz.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-01-06  |  35.2 KB  |  1,326 lines

  1. /************************************************************************/
  2. /* This module is based upon David Troendle's article in the May-June   */
  3. /* issue of SEXtant.  The module may be freely used for public domain   */
  4. /* software, but remains the sole property of the author, and may not   */
  5. /* included in any software offered for sale without the express written*/
  6. /* consent of the author: Wayne J. Parnin II (70310,362)                */
  7. /************************************************************************/
  8. /*        bugs...
  9.     Needs special code for vertical and horizontal lines.
  10.     Should combine line drawing, erasing, & flipping routines.
  11.  
  12.         history...
  13.             12 Aug 85 JVZ
  14.     Resetting screen modes to power-up default before setting them.
  15.             11 Aug 85 JVZ
  16.     Combined 225*640 and 400*640 modes.
  17.             4 Jul 85 JVZ
  18.     Changed names to set_intensity(), set_color(), inquire_intensity(),
  19.     and inquire_color() per revised CORE standard.
  20.             11 May 85 JVZ
  21.     declaring that cursor keys aren't preceded by anything.
  22.     Handling vertical lines as a special case.
  23.             27 Apr 85 JVZ
  24.     exporting "down_arrow" rather than "cursor_down", etc.
  25.             21 Apr 85 JVZ
  26.     Exporting pointers to line routines & definitions of cursor keys.
  27.             25 Mar 85 JVZ
  28.     gotoxy() added.  set_intensity() now takes double argument.  Character
  29.     parameters exported.
  30.             7 Feb 85  JVZ
  31.     Clearing screen with ESC E rather than lots of carriage returns.
  32.             6 Feb 85  JVZ
  33.     Using shifts instead of multiplies and divides in pixel_addr().
  34.             1 Feb 85 JVZ
  35.     moved iline(), ierase(), imove(), icline(), icerase(), current_x, and
  36.     current_y to g3.c
  37.             20 Jan 85 JVZ
  38.     draw and erase no longer have color arguments,
  39.     set_current_color() sets the variables current_color and ram_page.
  40.     draw() and erase() use "simultaneous write" to write into
  41.     more than one plane at a time. (Doesn't work if some pixels in
  42.     different planes differ.)
  43.             19 Jan 85 JVZ
  44.     In each inner loop, DI is compared with zero rather than DX. DX now
  45.     carries twice as large a value, so it need only be added to (or
  46.     subtracted from) DI once .   Together, these changes resulted in a 7%
  47.     increase in speed.
  48.     Debug [  ]    V1.0  13-May-84  WJP    Initial Release    
  49.     Debug [  ]   Vn.n  dd-mmm-yy  WJP    Description of change
  50. /************************************************************************/
  51. /* Z100 Graphics utilities:                                             */
  52. /*  address = pixel_addr(x, y)       Calculate pixel address              */
  53. /*  draw(x1,y1, x2,y2) Draw line between points             */
  54. /*  erase(x1,y1,x2,y2) Erase line between points            */
  55. /************************************************************************/
  56.  
  57. /************************************************************************/
  58. /* LOCAL DEFINITIONS ****************************************************/
  59.  
  60. /* */
  61. /* Constants */
  62. /* */
  63.  
  64. #define BLUE    1
  65. #define P_BLUE  0xC000
  66. #define RED    2
  67. #define P_RED    0xD000
  68. #define GREEN    4
  69. #define P_GREEN 0xE000
  70.  
  71. #define VIDEO_LATCH_ADDR 0xD8
  72.  
  73. int current_color=GREEN;            /* Line color code: RED, BLUE, or GREEN */
  74. double current_intensity=.5714;        /* current intensity (0 to 1) */
  75. static unsigned ram_page=P_GREEN;    /* segment for brightest plane in use */
  76. static int color_ram=1;                /* nonzero if color RAM installed */
  77. static int color_code=2;            /* internal code for color (see below) */
  78. static int draw(), erase();            /* straight line routines */
  79.  
  80. /*    exported function pointers (initialized at end of listing) */
  81.  
  82. extern int (*draw_line)(), (*erase_line)();
  83.  
  84. /*    exported graphics variables    */
  85.  
  86. char *machine="Z-100";
  87. int max_color=7;
  88.                         /* height/width parameters of screen */
  89. int pixels_wide=640;
  90. int pixels_high=225;
  91. double best_width=1.;
  92. double best_height=.872;
  93.                         /* text parameters */
  94. int char_rows=25;
  95. int char_columns=80;
  96. int char_height=9;
  97. int char_width=8;
  98. int x_offset=0;
  99. int y_offset=8;
  100.                         /* cursor key codes */
  101. int up_arrow=0xa5;
  102. int down_arrow=0xa6;
  103. int right_arrow=0xa7;
  104. int left_arrow=0xa8;
  105. int escaped_arrows=0;
  106. int escape_char=0;
  107.  
  108. /* an 'A' on row r, column c  has lower left corner on raster 
  109.                 r*char_height + y_offset 
  110.     at pixel
  111.                 c*char_width + x_offset            */
  112.  
  113. /*    set_color - set color to be used for subsequent primitives
  114.     internal relative
  115.       code    intensity    color    monochrome
  116.         0        0        black         0%
  117.         4        1        blue        11%
  118.         1        2        red            30%
  119.         5        3        magenta        41%
  120.         2        4        green        59%
  121.         6        5        cyan        70%
  122.         3        6        yellow        89%
  123.         7        7        white       100%
  124. */
  125. set_color(color) int color;
  126. {    if(color_ram)
  127.         {current_color=color&7; color_code=0;
  128.         if(current_color&BLUE) {ram_page=P_BLUE; color_code+=4;}
  129.         if(current_color&RED) {ram_page=P_RED; color_code+=1;}
  130.         if(current_color&GREEN) {ram_page=P_GREEN; color_code+=2;}
  131.         current_intensity=current_color/7.;
  132.         }
  133. }    
  134. set_intensity(intensity) double intensity;
  135. {    int i;
  136.     i=(int)(intensity*8.);
  137.     if(i<0) i=0;
  138.     else if(i>7) i=7;
  139.     set_color(i);
  140. }
  141. inquire_color() {return (current_color);}
  142. double inquire_intensity() {return (current_intensity);}
  143.  
  144. /* */
  145. /* Calculate address of pixel on Z100 color plane (9 lines/char) */
  146. /*  address = pixel_addr(x, y);
  147. /* */
  148.    
  149. pixel_addr(x, y)
  150.  
  151. int    x, y;    /* Coordinates (x:0 - 639, y:0 - 224) */
  152.  
  153. {  int    row_start;    /* Address of first byte in row */
  154.    int    pixel_byte;    /* Location of pixel byte in row */
  155.  
  156.    row_start  = ((y/9)<<4) + (y%9);
  157.    pixel_byte = x>>3;
  158.  
  159.    return( (row_start*128) + pixel_byte );
  160.  
  161. }
  162.  
  163. static int pattern[8]={0,128,192,224,240,248,252,254};
  164.  
  165. /* */
  166. /* Draw line on Z100 display */
  167. /*  draw1(x1,y1, x2,y2) */
  168. /* */
  169.  
  170. static int draw1(x1,y1, x2,y2)
  171.  
  172. int    x1,y1;        /* Coordinates of first point */
  173. int    x2,y2;        /* Coordinates of last point */
  174.  
  175. {
  176.    static int start_addr;    /* Initial display address line (min y) */
  177.    static int delta_x, delta_y;
  178.    static int pixel_bit,cnt,i;
  179.    int video_latch_setting;
  180.    static unsigned ram_page;
  181.  
  182.    if(current_color==0)return;    /* black lines */
  183.    delta_y = y2-y1;
  184.  
  185.                 /* enable video RAM access and "simultaneous write" to all
  186.                     planes which should be active for the current color */
  187.    video_latch_setting = _inb(VIDEO_LATCH_ADDR);
  188.    _outb( ((video_latch_setting&0x7F)|0x70)^(color_code<<4),
  189.            VIDEO_LATCH_ADDR );
  190.  
  191.  
  192.  
  193. /*        cases for different line directions...
  194.                                                        8   4
  195.                                                     7         3   
  196.                                                    9           10
  197.                                                     1         5     
  198.                                                        2   6 
  199.  */        
  200.     if (delta_y == 0)                            /* horizontal? */
  201.         {if( x2 > x1 )
  202.             {start_addr = pixel_addr(x1,y1);            /* case 10 */
  203.             pixel_bit  = 0x0100 >> (x1 & 7);
  204.               delta_x    = x2-x1+1;
  205.               }
  206.         else
  207.               {start_addr = pixel_addr(x2,y2);        /* case 9 */
  208.               pixel_bit  = 0x0100 >> (x2 & 7);
  209.               delta_x    = x1-x2+1;
  210.               }
  211.         cnt=delta_x;
  212.         while(pixel_bit!=1)
  213.               {
  214. #asm
  215. ;                pixel_bit>>=1;
  216.       MOV    BX,WORD draw1_pixel_bit_    ; BX-    Pixel map 
  217.       ROR    BX,1        ;    Next pixel
  218.       MOV    WORD draw1_pixel_bit_,BX
  219. ;                pixel_insert(start_addr,pixel_bit);
  220. ;      MOV    DI,AX
  221.       MOV    SI,WORD draw1_start_addr_    ; SI-    RAM pointer
  222.       PUSH    DS
  223.       MOV    AX,WORD ram_page_
  224.       MOV    DS,AX
  225. ;      MOV    AX,DI
  226.       OR    DS:[SI],BL    ;    Set bit in ram (turn pixel on)
  227.       POP    DS
  228. #endasm
  229.             if(--cnt ==0)return;
  230.             }
  231.         i=cnt>>3;
  232. #asm                    ; case 9
  233. dcase1_9:
  234. ;            while(i--)
  235. ;                {byte_insert(++start_addr,255);
  236.       MOV    CX,WORD draw1_i_                ; CX-    Length of line
  237.       OR    CX,CX
  238.       JZ    dcase1_91                        ; z => no iterations
  239.       MOV    DI,WORD draw1_start_addr_    ; DI-    RAM pointer
  240.       INC    DI
  241.       PUSH    ES
  242.       MOV    AX,WORD ram_page_
  243.       MOV    ES,AX
  244.       MOV    AX,0FFH
  245.       REP    STOSB        ; MOV    ES:[DI],AL    CX times;    Set bits in ram
  246.       DEC    DI
  247.       MOV    WORD draw1_start_addr_,DI    ; DI-    RAM pointer
  248.       POP    ES
  249. dcase1_91:
  250. ;                }
  251. #endasm
  252.  
  253.         pixel_bit=pattern[cnt&7];
  254. #asm
  255. ;                pixel_insert(++start_addr,pixel_bit);
  256.       MOV    AX,WORD draw1_pixel_bit_        ; AX-    Pixel map 
  257.       MOV    DI,AX
  258.       MOV    SI,WORD draw1_start_addr_    ; SI-    RAM pointer
  259.       INC    SI
  260.       PUSH    DS
  261.       MOV    AX,WORD ram_page_
  262.       MOV    DS,AX
  263.       MOV    AX,DI
  264.       OR    DS:[SI],AL    ;    Set bits in ram (turn pixels on)
  265.       POP    DS
  266. #endasm
  267.  
  268.         return;
  269.         }
  270.    if( delta_y > 0 ) {
  271.       start_addr = pixel_addr(x1,y1);            /* cases 3,4,7,8 */
  272.       pixel_bit  = 0x0100 >> ((x1 & 7) + 1);
  273.       delta_x    = x2-x1;
  274.    }
  275.    else {
  276.       start_addr = pixel_addr(x2,y2);        /* cases 1,2,5,6 */
  277.       pixel_bit  = 0x0100 >> ((x2 & 7) + 1);
  278.       delta_x    = x1-x2;
  279.    }
  280.  
  281.    if(delta_x > 0 ) {                /* cases 1,2 (3,4) */
  282.  
  283.       delta_x = abs(delta_x);
  284.       delta_y = abs(delta_y);
  285.  
  286.     if(delta_x==0)                            /* vertical */
  287.         {
  288. #asm                    ; case 7
  289. dcase1_7:
  290.       MOV    DI,WORD draw1_pixel_bit_        ; AX-    Pixel map 
  291.       MOV    BX,WORD draw1_delta_x_
  292.       MOV    CX,WORD draw1_delta_y_        ; CX-    length of line
  293.       INC    CX                            ;        number of iterations
  294.       MOV    SI,WORD draw1_start_addr_    ; SI-    RAM pointer
  295.       PUSH    DS
  296.       MOV    AX,WORD ram_page_
  297.       MOV    DS,AX
  298.       MOV    AX,DI
  299. dcase1_70:
  300.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  301.       TEST    SI,0400H    ;    On line 8 of "character" ?
  302.       JZ    dcase1_71        ;    No
  303.       ADD    SI,0380H    ;      Yes, skip lines 9 thru 15
  304. dcase1_71:
  305.       ADD    SI,80H        ;    Increment to next line
  306.       LOOP    dcase1_70
  307.       POP    DS
  308. #endasm
  309.         return;
  310.         }
  311.       if( delta_x > delta_y ) {            /* case 1 (3) */
  312.  
  313. #asm                    ; case 1
  314. dcase1_1:
  315.       MOV    DI,WORD draw1_pixel_bit_    ; AX-    Pixel map 
  316.       MOV    BX,WORD draw1_delta_y_
  317.       ADD    BX,BX                ; BX-    Deviation increment
  318.       MOV    DX,WORD draw1_delta_x_    ; DX-    Deviation decrement/2
  319.       MOV    CX,DX                ; CX-    Length of line
  320.       INC    CX                    ;    number of iterations
  321.       MOV    SI,WORD draw1_start_addr_    ; SI-    RAM pointer
  322.       PUSH    DS
  323.       MOV    AX,WORD ram_page_
  324.       MOV    DS,AX
  325.       MOV    AX,DI
  326.       MOV    DI,0                ; DI-    DEV
  327.       SUB    DI,DX
  328.       ADD    DX,DX
  329. dcase1_10:
  330.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  331.       ROR    AL,1        ;    Next pixel
  332.       ADC    SI,0        ;    Next byte, if required
  333. dcase1_11:    
  334.       ADD    DI,BX        ;     DEV + DELTA_P
  335.       JL    dcase1_13
  336.       TEST    SI,0400H    ;      On line 8 OF "character" ?
  337.       JZ    dcase1_12        ;      No
  338.       ADD    SI,0380H    ;        Yes, skip lines 9 thru 15
  339. dcase1_12:
  340.       ADD    SI,80H        ;      Increment to next line
  341.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  342. dcase1_13:
  343.       LOOP    dcase1_10
  344.       POP    DS
  345. #
  346.       }
  347.       else {                    /* case 2 (4) */
  348.  
  349. #asm                    ; case 2
  350. dcase1_2:
  351.       MOV    DI,WORD draw1_pixel_bit_    ; AX-    Pixel map 
  352.       MOV    BX,WORD draw1_delta_x_
  353.       ADD    BX,BX                ; BX-    Deviation increment
  354.       MOV    DX,WORD draw1_delta_y_    ; DX-    Deviation decrement/2
  355.       MOV    CX,DX                ; CX-    Length of line
  356.       INC    CX                    ;    number of iterations
  357.       MOV    SI,WORD draw1_start_addr_    ; SI-    RAM pointer
  358.       PUSH    DS
  359.       MOV    AX,WORD ram_page_
  360.       MOV    DS,AX
  361.       MOV    AX,DI
  362.       MOV    DI,0                ; DI-    DEV
  363.       SUB    DI,DX
  364.       ADD    DX,DX
  365. dcase1_20:
  366.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  367.       TEST    SI,0400H    ;    On line 8 of "character" ?
  368.       JZ    dcase1_21        ;    No
  369.       ADD    SI,0380H    ;      Yes, skip lines 9 thru 15
  370. dcase1_21:
  371.       ADD    SI,80H        ;    Increment to next line
  372.       ADD    DI,BX        ;     DEV + DELTA_P
  373.       JL    dcase1_23
  374.       ROR    AL,1
  375.       ADC      SI,0
  376.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  377. dcase1_23:
  378.       LOOP    dcase1_20
  379.       POP    DS
  380. #
  381.       }
  382.    }
  383.    else {                    /* delta_x < 0: cases 5,6 (7,8) */
  384.  
  385.       delta_x = abs(delta_x);
  386.       delta_y = abs(delta_y);
  387.  
  388.       if( delta_x > delta_y ) {            /* case 5 (7) */
  389.  
  390. #asm                    ; case 5
  391. dcase1_5:
  392.       MOV    DI,WORD draw1_pixel_bit_    ; AX-    Pixel map 
  393.       MOV    BX,WORD draw1_delta_y_
  394.       ADD    BX,BX                ; BX-    Deviation increment
  395.       MOV    DX,WORD draw1_delta_x_    ; DX-    Deviation decrement/2
  396.       MOV    CX,DX                ; CX-    Length of line
  397.       INC    CX                    ;    number of iterations
  398.       MOV    SI,WORD draw1_start_addr_    ; SI-    RAM pointer
  399.       PUSH    DS
  400.       MOV    AX,WORD ram_page_
  401.       MOV    DS,AX
  402.       MOV    AX,DI
  403.       MOV    DI,0                ; DI-    DEV
  404.       SUB    DI,DX
  405.       ADD    DX,DX
  406. dcase1_50:
  407.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  408.       ROL    AL,1        ;    Next pixel
  409.       SBB    SI,0        ;    Next byte
  410. dcase1_51:    
  411.       ADD    DI,BX        ;     DEV + DELTA_P
  412.       JL    dcase1_53
  413.       TEST    SI,0400H    ;      On line 8 OF "character" ?
  414.       JZ    dcase1_52        ;      No
  415.       ADD    SI,0380H    ;        Yes, skip lines 9 thru 15
  416. dcase1_52:
  417.       ADD    SI,80H        ;      Increment to next line
  418.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  419. dcase1_53:
  420.       LOOP    dcase1_50
  421.       POP    DS
  422. #
  423.       }
  424.       else {                    /* case 6 (8) */
  425.  
  426. #asm                    ; case 6
  427. dcase1_6:
  428.       MOV    DI,WORD draw1_pixel_bit_    ; AX-    Pixel map 
  429.       MOV    BX,WORD draw1_delta_x_
  430.       ADD    BX,BX                ; BX-    Deviation increment
  431.       MOV    DX,WORD draw1_delta_y_    ; DX-    Deviation decrement/2
  432.       MOV    CX,DX                ; CX-    Length of line
  433.       INC    CX                    ;    number of iterations
  434.       MOV    SI,WORD draw1_start_addr_    ; SI-    RAM pointer
  435.       PUSH    DS
  436.       MOV    AX,WORD ram_page_
  437.       MOV    DS,AX
  438.       MOV    AX,DI
  439.       MOV    DI,0                ; DI-    DEV
  440.       SUB    DI,DX
  441.       ADD    DX,DX
  442. dcase1_60:
  443.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  444.       TEST    SI,0400H    ;    On line 8 of "character" ?
  445.       JZ    dcase1_61        ;    No
  446.       ADD    SI,0380H    ;      Yes, skip lines 9 thru 15
  447. dcase1_61:
  448.       ADD    SI,80H        ;    Increment to next line
  449.       ADD    DI,BX        ;     DEV + DELTA_P
  450.       JL    dcase1_63
  451.       ROL    AL,1
  452.       SBB    SI,0
  453.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  454. dcase1_63:
  455.       LOOP    dcase1_60
  456.       POP    DS
  457. #
  458.       }
  459.    }
  460.    _outb( video_latch_setting, VIDEO_LATCH_ADDR );
  461. }
  462.  
  463.  
  464. /* */
  465. /* Erase line from Z100 display */
  466. /*  erase(x1,y1, x2,y2) */
  467. /* */
  468.  
  469. static int erase1(x1,y1, x2,y2)
  470.  
  471. int    x1,y1;        /* Coordinates of first point */
  472. int    x2,y2;        /* Coordinates of last point */
  473.  
  474. {
  475.    static int start_addr;    /* Initial display address line (min y) */
  476.    static int delta_x, delta_y;
  477.    static int pixel_bit;
  478.    int video_latch_setting;
  479.  
  480.    delta_y = y2-y1;
  481.  
  482.    video_latch_setting = _inb(VIDEO_LATCH_ADDR);
  483.    _outb( ((video_latch_setting&0x7F)|0x70)^(color_code<<4),
  484.            VIDEO_LATCH_ADDR );
  485.  
  486.    if( delta_y > 0 ) {
  487.       start_addr = pixel_addr(x1,y1);            /* cases 3,4,7,8 */
  488.       pixel_bit  = ~(0x0100 >> ((x1 & 7) + 1));
  489.       delta_x    = x2-x1;
  490.    }
  491.    else {
  492.       start_addr = pixel_addr(x2,y2);        /* cases 1,2,5,6 */
  493.       pixel_bit  = ~(0x0100 >> ((x2 & 7) + 1));
  494.       delta_x    = x1-x2;
  495.    }
  496.  
  497.    if(delta_x > 0 ) {                /* cases 1,2 (3,4) */
  498.  
  499.       delta_x = abs(delta_x);
  500.       delta_y = abs(delta_y);
  501.  
  502.       if( delta_x > delta_y ) {            /* case 1 (3) */
  503.  
  504. #asm                    ; CASE 1
  505. ecase1_1:
  506.       MOV    DI,WORD erase1_pixel_bit_    ; AX-    Pixel map 
  507.       MOV    BX,WORD erase1_delta_y_
  508.       ADD    BX,BX                ; BX-    Deviation increment
  509.       MOV    DX,WORD erase1_delta_x_    ; DX-    Deviation decrement/2
  510.       MOV    CX,DX                ; CX-    Length of line
  511.       INC    CX                    ;    number of iterations
  512.       MOV    SI,WORD erase1_start_addr_    ; SI-    RAM pointer
  513.       PUSH    DS
  514.       MOV    AX,WORD ram_page_
  515.       MOV    DS,AX
  516.       MOV    AX,DI
  517.       MOV    DI,0                ; DI-    DEV
  518.       SUB    DI,DX
  519.       ADD    DX,DX
  520. ecase1_10:
  521.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  522.       ROR    AL,1        ;    Next pixel
  523.       CMC
  524.       ADC    SI,0        ;    Next byte, if required
  525. ecase1_11:    
  526.       ADD    DI,BX        ;     DEV + DELTA_P
  527.       JL    ecase1_13
  528.       TEST    SI,0400H    ;      On line 8 OF "character" ?
  529.       JZ    ecase1_12        ;      No
  530.       ADD    SI,0380H    ;        Yes, skip lines 9 thru 15
  531. ecase1_12:
  532.       ADD    SI,80H        ;      Increment to next line
  533.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  534. ecase1_13:
  535.       LOOP    ecase1_10
  536.       POP    DS
  537. #
  538.       }
  539.       else {                    /* CASE 2 (4) */
  540.  
  541. #asm                    ; CASE 2
  542. ecase1_2:
  543.       MOV    DI,WORD erase1_pixel_bit_    ; AX-    Pixel map 
  544.       MOV    BX,WORD erase1_delta_x_
  545.       ADD    BX,BX                ; BX-    Deviation increment
  546.       MOV    DX,WORD erase1_delta_y_    ; DX-    Deviation decrement/2
  547.       MOV    CX,DX                ; CX-    Length of line
  548.       INC    CX                    ;    number of iterations
  549.       MOV    SI,WORD erase1_start_addr_    ; SI-    RAM pointer
  550.       PUSH    DS
  551.       MOV    AX,WORD ram_page_
  552.       MOV    DS,AX
  553.       MOV    AX,DI
  554.       MOV    DI,0                ; DI-    DEV
  555.       SUB    DI,DX
  556.       ADD    DX,DX
  557. ecase1_20:
  558.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  559.       TEST    SI,0400H    ;    On line 8 of "character" ?
  560.       JZ    ecase1_21        ;    No
  561.       ADD    SI,0380H    ;      Yes, skip lines 9 thru 15
  562. ecase1_21:
  563.       ADD    SI,80H        ;    Increment to next line
  564.       ADD    DI,BX        ;     DEV + DELTA_P
  565.       JL    ecase1_23
  566.       ROR    AL,1
  567.       CMC 
  568.       ADC      SI,0
  569.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  570. ecase1_23:
  571.       LOOP    ecase1_20
  572.       POP    DS
  573. #
  574.       }
  575.    }
  576.    else {                    /* CASEs 5,6 (7,8) */
  577.  
  578.       delta_x = abs(delta_x);
  579.       delta_y = abs(delta_y);
  580.  
  581.       if( delta_x > delta_y ) {            /* CASE 5 (7) */
  582.  
  583. #asm                    ; CASE 5
  584. ecase1_5:
  585.       MOV    DI,WORD erase1_pixel_bit_    ; AX-    Pixel map 
  586.       MOV    BX,WORD erase1_delta_y_
  587.       ADD    BX,BX                ; BX-    Deviation increment
  588.       MOV    DX,WORD erase1_delta_x_    ; DX-    Deviation decrement/2
  589.       MOV    CX,DX                ; CX-    Length of line
  590.       INC    CX                    ;    number of iterations
  591.       MOV    SI,WORD erase1_start_addr_    ; SI-    RAM pointer
  592.       PUSH    DS
  593.       MOV    AX,WORD ram_page_
  594.       MOV    DS,AX
  595.       MOV    AX,DI
  596.       MOV    DI,0                ; DI-    DEV
  597.       SUB    DI,DX
  598.       ADD    DX,DX
  599. ecase1_50:
  600.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  601.       ROL    AL,1        ;    Next pixel
  602.       CMC
  603.       SBB    SI,0        ;    Next byte
  604. ecase1_51:    
  605.       ADD    DI,BX        ;     DEV + DELTA_P
  606.       JL    ecase1_53
  607.       TEST    SI,0400H    ;      On line 8 OF "character" ?
  608.       JZ    ecase1_52        ;      No
  609.       ADD    SI,0380H    ;        Yes, skip lines 9 thru 15
  610. ecase1_52:
  611.       ADD    SI,80H        ;      Increment to next line
  612.         SUB    DI,DX        ;    DEV - 2*DELTA_M
  613. ecase1_53:
  614.       LOOP    ecase1_50
  615.       POP    DS
  616. #
  617.       }
  618.       else {                    /* CASE 6 (8) */
  619.  
  620. #asm                    ; CASE 6
  621. ecase1_6:
  622.       MOV    DI,WORD erase1_pixel_bit_    ; AX-    Pixel map 
  623.       MOV    BX,WORD erase1_delta_x_
  624.       ADD    BX,BX                ; BX-    Deviation increment
  625.       MOV    DX,WORD erase1_delta_y_    ; DX-    Deviation decrement/2
  626.       MOV    CX,DX                ; CX-    Length of line
  627.       INC    CX                    ;    number of iterations
  628.       MOV    SI,WORD erase1_start_addr_    ; SI-    RAM pointer
  629.       PUSH    DS
  630.       MOV    AX,WORD ram_page_
  631.       MOV    DS,AX
  632.       MOV    AX,DI
  633.       MOV    DI,0                ; DI-    DEV
  634.       SUB    DI,DX
  635.       ADD    DX,DX
  636. ecase1_60:
  637.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  638.       TEST    SI,0400H    ;    On line 8 of "character" ?
  639.       JZ    ecase1_61        ;    No
  640.       ADD    SI,0380H    ;      Yes, skip lines 9 thru 15
  641. ecase1_61:
  642.       ADD    SI,80H        ;    Increment to next line
  643.       ADD    DI,BX        ;     DEV + DELTA_P
  644.       JL    ecase1_63
  645.       ROL    AL,1
  646.       CMC
  647.       SBB    SI,0
  648.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  649. ecase1_63:
  650.       LOOP    ecase1_60
  651.       POP    DS
  652. #
  653.       }
  654.    }
  655.    _outb( video_latch_setting, VIDEO_LATCH_ADDR );
  656. }
  657.  
  658. /*    clear_graphics - clear screen in .1077 sec */
  659. clear_graphics()
  660. {
  661. /*    puts("\033E");        easy way to clear 24 lines */
  662. #asm
  663.     push    es
  664.     mov    al,08h        ;d7=0        VRAM cpu access enabled
  665.                      ;d6=d5=d4=0    simultaneous write for all planes
  666.                      ;d3=1        VRAM data displayed
  667.                      ;d2=d1=d0=0    all planes displayed
  668.     out    0d8h,al
  669.  
  670.     mov    ax,0d000H    ;starting address
  671.     mov    es,ax
  672.     mov    ax,0        ;used to clear memory
  673.     mov    bx,ax        ;displacement for first raster
  674.     mov    dx,400        ;rasters cleared
  675.     cld
  676. next_line:
  677.     mov    di,bx
  678.     mov    cx,64        ;words cleared per raster
  679.     rep    stosw        ;clear one raster
  680.     add    bx,128        ;displacement to next raster
  681.     dec    dx
  682.     jnz    next_line
  683.  
  684.     mov    al,88h        ;d7=1        VRAM cpu access disabled
  685.                      ;d6=d5=d4=0    simultaneous write for all planes
  686.                      ;d3=1        VRAM data displayed
  687.                      ;d2=d1=d0=0    all planes displayed
  688.     out    0d8h,al
  689.     pop    es
  690. #endasm
  691.     puts("\033Y  ");    /* home the cursor */
  692. }
  693.  
  694. /*    gotoxy - direct cursor positioning */
  695. gotoxy(x,y) int x,y;
  696. {    if(y<0) y=0; else if (y>=char_rows) y=char_rows-1;
  697.     if(x<0) x=0; else if (x>=char_columns) x=char_columns-1;
  698.     puts("\033Y"); putchar(y+32); putchar(x+32);
  699. }
  700.  
  701. /* */
  702. /* Calculate address of pixel on Z100 color plane (16 lines/char) */
  703. /*  address = pixel2_addr(x, y);
  704. /* */
  705.    
  706. pixel2_addr(x, y)
  707.  
  708. int    x, y;    /* Coordinates (x:0 - 639, y:0 - 399) */
  709.  
  710. {  int    row_start;    /* Address of first byte in row */
  711.    int    pixel_byte;    /* Location of pixel byte in row */
  712.  
  713.    row_start  = y;
  714.    pixel_byte = x>>3;
  715.  
  716.    return( (row_start*128) + pixel_byte );
  717.  
  718. }
  719.  
  720.  
  721. /* */
  722. /* Draw line on Z100 display */
  723. /*  draw(x1,y1, x2,y2) */
  724. /* */
  725.  
  726. static draw2(x1,y1, x2,y2)
  727.  
  728. int    x1,y1;        /* Coordinates of first point */
  729. int    x2,y2;        /* Coordinates of last point */
  730.  
  731. {
  732.    static int start_addr;    /* Initial display address line (min y) */
  733.    static int delta_x, delta_y;
  734.    static int pixel_bit;
  735.    int video_latch_setting;
  736.    static unsigned ram_page;
  737.  
  738.    if(current_color==0)return;
  739.  
  740.    delta_y = y2-y1;
  741.  
  742.                 /* enable video RAM access and "simultaneous write" to all
  743.                     planes which should be active for the current color */
  744.    video_latch_setting = _inb(VIDEO_LATCH_ADDR);
  745.    _outb( ((video_latch_setting&0x7F)|0x70)^(color_code<<4),
  746.            VIDEO_LATCH_ADDR );
  747.  
  748.  
  749.  
  750. /*        CASEs for different line directions...
  751.                                                        8   4
  752.                                                     7         3   
  753.                                                           
  754.                                                     1         5     
  755.                                                        2   6 
  756.  */        
  757.    if( delta_y > 0 ) {
  758.       start_addr = pixel2_addr(x1,y1);            /* CASEs 3,4,7,8 */
  759.       pixel_bit  = 0x0100 >> ((x1 & 7) + 1);
  760.       delta_x    = x2-x1;
  761.    }
  762.    else {
  763.       start_addr = pixel2_addr(x2,y2);        /* CASEs 1,2,5,6 */
  764.       pixel_bit  = 0x0100 >> ((x2 & 7) + 1);
  765.       delta_x    = x1-x2;
  766.    }
  767.  
  768.    if(delta_x > 0 ) {                /* CASEs 1,2 (3,4) */
  769.  
  770.       delta_x = abs(delta_x);
  771.       delta_y = abs(delta_y);
  772.  
  773.       if( delta_x > delta_y ) {            /* CASE 1 (3) */
  774.  
  775. #asm                    ; CASE 1
  776. dcase2_1:
  777.       MOV    DI,WORD draw2_pixel_bit_    ; AX-    Pixel map 
  778.       MOV    BX,WORD draw2_delta_y_
  779.       ADD    BX,BX                ; BX-    Deviation increment
  780.       MOV    DX,WORD draw2_delta_x_    ; DX-    Deviation decrement/2
  781.       MOV    CX,DX                ; CX-    Length of line
  782.       INC    CX                ; number of interations
  783.       MOV    SI,WORD draw2_start_addr_    ; SI-    RAM pointer
  784.       PUSH    DS
  785.       MOV    AX,WORD ram_page_
  786.       MOV    DS,AX
  787.       MOV    AX,DI
  788.       MOV    DI,0                ; DI-    DEV
  789.       SUB    DI,DX
  790.       ADD    DX,DX
  791. dcase2_10:
  792.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  793.       ROR    AL,1        ;    Next pixel
  794.       ADC    SI,0        ;    Next byte, if required
  795. dcase2_11:    
  796.       ADD    DI,BX        ;     DEV + DELTA_P
  797.       JL    dcase2_13
  798.       ADD    SI,80H        ;      Increment to next line
  799.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  800. dcase2_13:
  801.       LOOP    dcase2_10
  802.       POP    DS
  803. #
  804.       }
  805.       else {                    /* CASE 2 (4) */
  806.  
  807. #asm                    ; CASE 2
  808. dcase2_2:
  809.       MOV    DI,WORD draw2_pixel_bit_    ; AX-    Pixel map 
  810.       MOV    BX,WORD draw2_delta_x_
  811.       ADD    BX,BX                ; BX-    Deviation increment
  812.       MOV    DX,WORD draw2_delta_y_    ; DX-    Deviation decrement/2
  813.       MOV    CX,DX                ; CX-    Length of line
  814.       INC    CX                ; number of interations
  815.       MOV    SI,WORD draw2_start_addr_    ; SI-    RAM pointer
  816.       PUSH    DS
  817.       MOV    AX,WORD ram_page_
  818.       MOV    DS,AX
  819.       MOV    AX,DI
  820.       MOV    DI,0                ; DI-    DEV
  821.       SUB    DI,DX
  822.       ADD    DX,DX
  823. dcase2_20:
  824.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  825.       ADD    SI,80H        ;    Increment to next line
  826.       ADD    DI,BX        ;     DEV + DELTA_P
  827.       JL    dcase2_23
  828.       ROR    AL,1
  829.       ADC      SI,0
  830.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  831. dcase2_23:
  832.       LOOP    dcase2_20
  833.       POP    DS
  834. #
  835.       }
  836.    }
  837.    else {                    /* CASEs 5,6 (7,8) */
  838.  
  839.       delta_x = abs(delta_x);
  840.       delta_y = abs(delta_y);
  841.  
  842.       if( delta_x > delta_y ) {            /* CASE 5 (7) */
  843.  
  844. #asm                    ; CASE 5
  845. dcase2_5:
  846.       MOV    DI,WORD draw2_pixel_bit_    ; AX-    Pixel map 
  847.       MOV    BX,WORD draw2_delta_y_
  848.       ADD    BX,BX                ; BX-    Deviation increment
  849.       MOV    DX,WORD draw2_delta_x_    ; DX-    Deviation decrement/2
  850.       MOV    CX,DX                ; CX-    Length of line
  851.       INC    CX                ; number of interations
  852.       MOV    SI,WORD draw2_start_addr_    ; SI-    RAM pointer
  853.       PUSH    DS
  854.       MOV    AX,WORD ram_page_
  855.       MOV    DS,AX
  856.       MOV    AX,DI
  857.       MOV    DI,0                ; DI-    DEV
  858.       SUB    DI,DX
  859.       ADD    DX,DX
  860. dcase2_50:
  861.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  862.       ROL    AL,1        ;    Next pixel
  863.       SBB    SI,0        ;    Next byte
  864. dcase2_51:    
  865.       ADD    DI,BX        ;     DEV + DELTA_P
  866.       JL    dcase2_53
  867.       ADD    SI,80H        ;      Increment to next line
  868.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  869. dcase2_53:
  870.       LOOP    dcase2_50
  871.       POP    DS
  872. #
  873.       }
  874.       else {                    /* CASE 6 (8) */
  875.  
  876. #asm                    ; CASE 6
  877. dcase2_6:
  878.       MOV    DI,WORD draw2_pixel_bit_    ; AX-    Pixel map 
  879.       MOV    BX,WORD draw2_delta_x_
  880.       ADD    BX,BX                ; BX-    Deviation increment
  881.       MOV    DX,WORD draw2_delta_y_    ; DX-    Deviation decrement/2
  882.       MOV    CX,DX                ; CX-    Length of line
  883.       INC    CX                ; number of interations
  884.       MOV    SI,WORD draw2_start_addr_    ; SI-    RAM pointer
  885.       PUSH    DS
  886.       MOV    AX,WORD ram_page_
  887.       MOV    DS,AX
  888.       MOV    AX,DI
  889.       MOV    DI,0                ; DI-    DEV
  890.       SUB    DI,DX
  891.       ADD    DX,DX
  892. dcase2_60:
  893.       OR    DS:[SI],AL    ;    Set bit in ram (turn pixel on)
  894.       ADD    SI,80H        ;    Increment to next line
  895.       ADD    DI,BX        ;     DEV + DELTA_P
  896.       JL    dcase2_63
  897.       ROL    AL,1
  898.       SBB    SI,0
  899.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  900. dcase2_63:
  901.       LOOP    dcase2_60
  902.       POP    DS
  903. #
  904.       }
  905.    }
  906.    _outb( video_latch_setting, VIDEO_LATCH_ADDR );
  907. }
  908.  
  909.  
  910. /* */
  911. /* Erase line from Z100 display */
  912. /*  erase2(x1,y1, x2,y2) */
  913. /* */
  914.  
  915. static erase2(x1,y1, x2,y2)
  916.  
  917. int    x1,y1;        /* Coordinates of first point */
  918. int    x2,y2;        /* Coordinates of last point */
  919.  
  920. {
  921.    static int start_addr;    /* Initial display address line (min y) */
  922.    static int delta_x, delta_y;
  923.    static int pixel_bit;
  924.    int video_latch_setting;
  925.  
  926.    delta_y = y2-y1;
  927.  
  928.    video_latch_setting = _inb(VIDEO_LATCH_ADDR);
  929.    _outb( ((video_latch_setting&0x7F)|0x70)^(color_code<<4),
  930.            VIDEO_LATCH_ADDR );
  931.  
  932.    if( delta_y > 0 ) {
  933.       start_addr = pixel2_addr(x1,y1);            /* CASEs 3,4,7,8 */
  934.       pixel_bit  = ~(0x0100 >> ((x1 & 7) + 1));
  935.       delta_x    = x2-x1;
  936.    }
  937.    else {
  938.       start_addr = pixel2_addr(x2,y2);        /* CASEs 1,2,5,6 */
  939.       pixel_bit  = ~(0x0100 >> ((x2 & 7) + 1));
  940.       delta_x    = x1-x2;
  941.    }
  942.  
  943.    if(delta_x > 0 ) {                /* CASEs 1,2 (3,4) */
  944.  
  945.       delta_x = abs(delta_x);
  946.       delta_y = abs(delta_y);
  947.  
  948.       if( delta_x > delta_y ) {            /* CASE 1 (3) */
  949.  
  950. #asm                    ; CASE 1
  951. ecase2_1:
  952.       MOV    DI,WORD erase2_pixel_bit_    ; AX-    Pixel map 
  953.       MOV    BX,WORD erase2_delta_y_
  954.       ADD    BX,BX                ; BX-    Deviation increment
  955.       MOV    DX,WORD erase2_delta_x_    ; DX-    Deviation decrement/2
  956.       MOV    CX,DX                ; CX-    Length of line
  957.       INC    CX                ; number of interations
  958.       MOV    SI,WORD erase2_start_addr_    ; SI-    RAM pointer
  959.       PUSH    DS
  960.       MOV    AX,WORD ram_page_
  961.       MOV    DS,AX
  962.       MOV    AX,DI
  963.       MOV    DI,0                ; DI-    DEV
  964.       SUB    DI,DX
  965.       ADD    DX,DX
  966. ecase2_10:
  967.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  968.       ROR    AL,1        ;    Next pixel
  969.       CMC
  970.       ADC    SI,0        ;    Next byte, if required
  971. ecase2_11:    
  972.       ADD    DI,BX        ;     DEV + DELTA_P
  973.       JL    ecase2_13
  974.       ADD    SI,80H        ;      Increment to next line
  975.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  976. ecase2_13:
  977.       LOOP    ecase2_10
  978.       POP    DS
  979. #
  980.       }
  981.       else {                    /* CASE 2 (4) */
  982.  
  983. #asm                    ; CASE 2
  984. ecase2_2:
  985.       MOV    DI,WORD erase2_pixel_bit_    ; AX-    Pixel map 
  986.       MOV    BX,WORD erase2_delta_x_
  987.       ADD    BX,BX                ; BX-    Deviation increment
  988.       MOV    DX,WORD erase2_delta_y_    ; DX-    Deviation decrement/2
  989.       MOV    CX,DX                ; CX-    Length of line
  990.       INC    CX                ; number of interations
  991.       MOV    SI,WORD erase2_start_addr_    ; SI-    RAM pointer
  992.       PUSH    DS
  993.       MOV    AX,WORD ram_page_
  994.       MOV    DS,AX
  995.       MOV    AX,DI
  996.       MOV    DI,0                ; DI-    DEV
  997.       SUB    DI,DX
  998.       ADD    DX,DX
  999. ecase2_20:
  1000.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  1001.       ADD    SI,80H        ;    Increment to next line
  1002.       ADD    DI,BX        ;     DEV + DELTA_P
  1003.       JL    ecase2_23
  1004.       ROR    AL,1
  1005.       CMC 
  1006.       ADC      SI,0
  1007.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  1008. ecase2_23:
  1009.       LOOP    ecase2_20
  1010.       POP    DS
  1011. #
  1012.       }
  1013.    }
  1014.    else {                    /* CASEs 5,6 (7,8) */
  1015.  
  1016.       delta_x = abs(delta_x);
  1017.       delta_y = abs(delta_y);
  1018.  
  1019.       if( delta_x > delta_y ) {            /* CASE 5 (7) */
  1020.  
  1021. #asm                    ; CASE 5
  1022. ecase2_5:
  1023.       MOV    DI,WORD erase2_pixel_bit_    ; AX-    Pixel map 
  1024.       MOV    BX,WORD erase2_delta_y_
  1025.       ADD    BX,BX                ; BX-    Deviation increment
  1026.       MOV    DX,WORD erase2_delta_x_    ; DX-    Deviation decrement/2
  1027.       MOV    CX,DX                ; CX-    Length of line
  1028.       INC    CX                ; number of interations
  1029.       MOV    SI,WORD erase2_start_addr_    ; SI-    RAM pointer
  1030.       PUSH    DS
  1031.       MOV    AX,WORD ram_page_
  1032.       MOV    DS,AX
  1033.       MOV    AX,DI
  1034.       MOV    DI,0                ; DI-    DEV
  1035.       SUB    DI,DX
  1036.       ADD    DX,DX
  1037. ecase2_50:
  1038.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  1039.       ROL    AL,1        ;    Next pixel
  1040.       CMC
  1041.       SBB    SI,0        ;    Next byte
  1042. ecase2_51:    
  1043.       ADD    DI,BX        ;     DEV + DELTA_P
  1044.       JL    ecase2_53
  1045.       ADD    SI,80H        ;      Increment to next line
  1046.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  1047. ecase2_53:
  1048.       LOOP    ecase2_50
  1049.       POP    DS
  1050. #
  1051.       }
  1052.       else {                    /* CASE 6 (8) */
  1053.  
  1054. #asm                    ; CASE 6
  1055. ecase2_6:
  1056.       MOV    DI,WORD erase2_pixel_bit_    ; AX-    Pixel map 
  1057.       MOV    BX,WORD erase2_delta_x_
  1058.       ADD    BX,BX                ; BX-    Deviation increment
  1059.       MOV    DX,WORD erase2_delta_y_    ; DX-    Deviation decrement/2
  1060.       MOV    CX,DX                ; CX-    Length of line
  1061.       INC    CX                ; number of interations
  1062.       MOV    SI,WORD erase2_start_addr_    ; SI-    RAM pointer
  1063.       PUSH    DS
  1064.       MOV    AX,WORD ram_page_
  1065.       MOV    DS,AX
  1066.       MOV    AX,DI
  1067.       MOV    DI,0                ; DI-    DEV
  1068.       SUB    DI,DX
  1069.       ADD    DX,DX
  1070. ecase2_60:
  1071.       AND    DS:[SI],AL    ;    Clear bit in ram (turn pixel off)
  1072.       ADD    SI,80H        ;    Increment to next line
  1073.       ADD    DI,BX        ;     DEV + DELTA_P
  1074.       JL    ecase2_63
  1075.       ROL    AL,1
  1076.       CMC
  1077.       SBB    SI,0
  1078.       SUB    DI,DX        ;    DEV - 2*DELTA_M
  1079. ecase2_63:
  1080.       LOOP    ecase2_60
  1081.       POP    DS
  1082. #
  1083.       }
  1084.    }
  1085.    _outb( video_latch_setting, VIDEO_LATCH_ADDR );
  1086. }
  1087.  
  1088. /*    init_graphics - initialize hardware for graphics */
  1089. init_graphics()
  1090. {    static int result,not_z100;
  1091.     char buf[25];
  1092.  
  1093.     puts("\033z");        /* reset video parameters and clear screen */
  1094.     puts("\033y?");        /* disable key expansion */
  1095.     puts("\033x1");        /* enable 25th line */
  1096. #asm
  1097.     push    es
  1098.     mov    al,78h        ;d7=0        VRAM cpu access enabled
  1099.                      ;d6=d5=d4=1    no simultaneous write
  1100.                      ;d3=1        VRAM data displayed
  1101.                      ;d2=d1=d0=0    all planes displayed
  1102.     out    0d8h,al
  1103.  
  1104.     mov    bx,3
  1105.     mov    ax,0c000H    ;BLUE plane
  1106.     mov    es,ax
  1107.     mov    cx,es:[0]
  1108.     push cx
  1109.     mov    es:[0],bx
  1110.                     ;                color ram        green plane only
  1111.     add    bx,es:[0]    ;                3+3 => 6        3+(-1) => 2
  1112.     mov    ax,0d000H    ;RED plane
  1113.     mov    es,ax
  1114.     mov    cx,es:[0]
  1115.     push cx
  1116.     mov    es:[0],bx
  1117.     add    bx,es:[0]    ;                6+6 => 12        2+(-1) => 1
  1118.     mov    ax,0e000H    ;GREEN plane
  1119.     mov    es,ax
  1120.     mov    cx,es:[0]
  1121.     push cx
  1122.     mov    es:[0],bx
  1123.     add    bx,es:[0]    ;                12+12 => 24        1+1 => 2
  1124.     mov    word init_graphics_result_,bx
  1125.  
  1126.     mov    al,08h        ;d7=0        VRAM cpu access enabled
  1127.                      ;d6=d5=d4=0    simultaneous write to all planes
  1128.                      ;d3=1        VRAM data displayed
  1129.                      ;d2=d1=d0=0    all planes displayed
  1130.     out    0d8h,al
  1131.     mov    ax,0c000H    ;BLUE plane
  1132.     mov    es,ax
  1133.     mov    word es:[0],0    ;                clear all planes (if Z-100)
  1134.     mov    ax,0e000H    ;GREEN plane
  1135.     mov    es,ax
  1136.     mov    ax,es:[0]    ;get one of the cleared (?) bytes
  1137.     mov    word init_graphics_not_z100_,ax
  1138.  
  1139.     mov    al,78h        ;d7=0        VRAM cpu access enabled
  1140.                      ;d6=d5=d4=1    no simultaneous write
  1141.                      ;d3=1        VRAM data displayed
  1142.                      ;d2=d1=d0=0    all planes displayed
  1143.     out    0d8h,al
  1144.     mov    ax,0e000H    ;GREEN plane
  1145.     mov    es,ax
  1146.     pop    cx
  1147.     mov    es:[0],cx
  1148.     mov    ax,0d000H    ;RED plane
  1149.     mov    es,ax
  1150.     pop    cx
  1151.     mov    es:[0],cx
  1152.     mov    ax,0c000H    ;BLUE plane
  1153.     mov    es,ax
  1154.     pop    cx
  1155.     mov    es:[0],cx
  1156.  
  1157.     mov    al,88h        ;d7=1        VRAM cpu access disabled
  1158.                      ;d6=d5=d4=0    simultaneous write for all planes
  1159.                      ;d3=1        VRAM data displayed
  1160.                      ;d2=d1=d0=0    all planes displayed
  1161.     out    0d8h,al
  1162.     pop    es
  1163. #endasm
  1164. /*    printf("init_graphics...result=%d\n",result); */
  1165.     if(not_z100)
  1166.         {puts("This version is for the Z-100, not this machine!\007\n");
  1167.         exit(1);
  1168.         }
  1169.     clear_graphics();
  1170.     color_ram=(result==24);
  1171.     envsearch("GRAPHICS",buf);
  1172.     if(buf[0]==0 | strcmp(buf,"1")==0) {}    /* leave in 225 * 640 mode */
  1173.     else if(strcmp(buf,"2")==0)
  1174.         {
  1175. #asm
  1176.     cli                ; disable interrupts, accessing CRTC
  1177.  
  1178.     mov    al,4        ; 30 -> R4 = vertical total
  1179.     out    0dch,al
  1180.     mov    al,30
  1181.     out    0ddh,al
  1182.  
  1183.     mov    al,5        ; 9  -> R5 = vertical adjust
  1184.     out    0dch,al
  1185.     mov    al,9
  1186.     out    0ddh,al
  1187.                     ; 25 -> R6 = vertical displayed (default)
  1188.                     ; 28 -> R7 = sync position (default)
  1189.     mov    al,8        ; 3  -> R8 = interlace sync & video
  1190.     out    0dch,al
  1191.     mov    al,011B
  1192.     out    0ddh,al
  1193.  
  1194.     mov    al,9        ; 14 -> R9 = rasters per char
  1195.     out    0dch,al
  1196.     mov    al,14
  1197.     out    0ddh,al
  1198.  
  1199.     sti                ;enable interrupts
  1200.  
  1201.     push    es
  1202.     mov    al,78h        ;d7=0        VRAM cpu access enabled
  1203.                      ;d6=d5=d4=1    no simultaneous write
  1204.                      ;d3=1        VRAM data displayed
  1205.                      ;d2=d1=d0=0    all planes displayed
  1206.     out    0d8h,al
  1207.  
  1208.     mov    bx,3
  1209.     mov    ax,0c000H    ;BLUE plane
  1210.     mov    es,ax
  1211.     mov    cx,es:[0]
  1212.     push cx
  1213.     mov    es:[0],bx
  1214.                     ;                color ram        green plane only
  1215.     add    bx,es:[0]    ;                3+3 => 6        3+(-1) => 2
  1216.     mov    ax,0d000H    ;RED plane
  1217.     mov    es,ax
  1218.     mov    cx,es:[0]
  1219.     push cx
  1220.     mov    es:[0],bx
  1221.     add    bx,es:[0]    ;                6+6 => 12        2+(-1) => 1
  1222.     mov    ax,0e000H    ;GREEN plane
  1223.     mov    es,ax
  1224.     mov    cx,es:[0]
  1225.     push cx
  1226.     mov    es:[0],bx
  1227.     add    bx,es:[0]    ;                12+12 => 24        1+1 => 2
  1228.     mov    word init_graphics_result_,bx
  1229.  
  1230.     mov    al,08h        ;d7=0        VRAM cpu access enabled
  1231.                      ;d6=d5=d4=0    simultaneous write to all planes
  1232.                      ;d3=1        VRAM data displayed
  1233.                      ;d2=d1=d0=0    all planes displayed
  1234.     out    0d8h,al
  1235.     mov    ax,0c000H    ;BLUE plane
  1236.     mov    es,ax
  1237.     mov    word es:[0],0    ;                clear all planes (if Z-100)
  1238.     mov    ax,0e000H    ;GREEN plane
  1239.     mov    es,ax
  1240.     mov    ax,es:[0]    ;get one of the cleared (?) bytes
  1241.     mov    word init_graphics_not_z100_,ax
  1242.  
  1243.     mov    al,78h        ;d7=0        VRAM cpu access enabled
  1244.                      ;d6=d5=d4=1    no simultaneous write
  1245.                      ;d3=1        VRAM data displayed
  1246.                      ;d2=d1=d0=0    all planes displayed
  1247.     out    0d8h,al
  1248.     mov    ax,0e000H    ;GREEN plane
  1249.     mov    es,ax
  1250.     pop    cx
  1251.     mov    es:[0],cx
  1252.     mov    ax,0d000H    ;RED plane
  1253.     mov    es,ax
  1254.     pop    cx
  1255.     mov    es:[0],cx
  1256.     mov    ax,0c000H    ;BLUE plane
  1257.     mov    es,ax
  1258.     pop    cx
  1259.     mov    es:[0],cx
  1260.  
  1261.     mov    al,88h        ;d7=1        VRAM cpu access disabled
  1262.                      ;d6=d5=d4=0    simultaneous write for all planes
  1263.                      ;d3=1        VRAM data displayed
  1264.                      ;d2=d1=d0=0    all planes displayed
  1265.     out    0d8h,al
  1266.     pop    es
  1267. #endasm
  1268.                             /* height/width parameters of screen */
  1269.         pixels_wide=640;
  1270.         pixels_high=400;
  1271.         best_width=1.;
  1272.         best_height=.777;
  1273.         clear_graphics();
  1274.         color_ram=(result==24);
  1275.         draw_line=draw2;    /* pointers to line routines */
  1276.         erase_line=erase2;
  1277.         char_rows=25;        /* text parameters */
  1278.         char_columns=80;
  1279.         char_height=16;
  1280.         char_width=8;
  1281.         x_offset=0;
  1282.         y_offset=15;
  1283.         }
  1284.     else
  1285.         {puts("graphics mode "); puts(buf); puts(" not implemented");
  1286.         getchar();
  1287.         }
  1288. }
  1289.  
  1290. /*    finish_graphics - clean up after graphics */
  1291. finish_graphics()
  1292. {    puts("\033z");    /* reset video parameters and clear screen */
  1293. }
  1294.  
  1295.  
  1296. /*    exported function pointers (initialized at end of listing) */
  1297.  
  1298. int (*draw_line)()=draw1, (*erase_line)()=erase1;
  1299.  
  1300. /*    envsearch - search environment for given string */
  1301.  
  1302. envsearch(target,value) char *target,*value;
  1303. {    char buf[256],*s,t[25],*env;
  1304.     int nt,offset;
  1305.  
  1306.     s=t;
  1307.     while(*target) *s++=toupper(*target++);
  1308.     *s++= '='; *s=0;
  1309.     nt = strlen(t);
  1310.     offset=0;
  1311.     _lmove(2,44,_showcs()-0x10,&env,_showds());
  1312.     while(1)
  1313.         {_lmove(256,offset,env,buf,_showds());
  1314.         s=buf;
  1315.         if(*s)
  1316.             {/* printf("examining entry: %s \n",s); getchar(); */
  1317.             if (strncmp(t,s,nt)==0) return (strcpy(value,s+nt));
  1318.             }
  1319.         else
  1320.             {*value=0;
  1321.             return;
  1322.             }
  1323.         offset+=strlen(buf)+1;
  1324.         }
  1325. }
  1326.