home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / pcshow / src / msc5_1 / ega.asm < prev    next >
Encoding:
Assembly Source File  |  1990-01-06  |  37.1 KB  |  2,021 lines

  1. ;
  2. ;  EGA GRAPHICS DRIVER 
  3. ;
  4. ;  supports raster graphics on the Enhanced Adapter
  5. ;
  6. ;      Tim Krauskopf               Spring 1986
  7. ;    Modified by
  8. ;        Quincey Koziol    January 1989
  9. ;
  10. ;  National Center for Supercomputing Applications
  11. ;  605 E. Springfield
  12. ;  Champaign, IL 61820
  13. ;  (217) 244-0074
  14. ;
  15. ;
  16.         TITLE   EGA GRAPHICS RASTER DRIVER
  17.         NAME    EGA
  18.         INCLUDE DOS.MAC
  19.         SETX
  20. ;
  21. ;  Define where the registers are
  22. ;
  23. SEQ        EQU        03C4H
  24. MAPREG    EQU        2
  25. MAPMASK    EQU        03C5H
  26. GCHIP    EQU        03CEH
  27. DRREG    EQU        3
  28. MODEREG EQU        5
  29. BITREG    EQU        8
  30. BITMASK    EQU        03CFH
  31. ;
  32.         DSEG
  33. FLAG    DB    0            ; HAVE WE SET REGS UP
  34.  
  35. MAP_LEFT    DB    ?        ; BIT MAP FOR LEFT EDGE OF MIDDLE LINES
  36. MAP_RIGHT    DB    ?        ; BIT MAP FOR RIGHT EDGE OF MIDDLE LINES
  37. MAP_TOPL    DB    ?        ; BIT MAP FOR TOP & BOTTOM LINES LEFT EDGE
  38. MAP_TOPR    DB    ?        ; BIT MAP FOR TOP & BOTTOM LINES RIGHT EDGE
  39. RIGHT_EDGE    DW    ?        ; BYTE OFFSET OF LEFT EDGE
  40. LEFT_EDGE    DW    ?        ; BYTE OFFSET OF RIGHT EDGE
  41. X_WIDTH        DW    ?        ; WIDTH OF TOP & BOTTOM LINES IN BYTES
  42. Y_HEIGHT    DW    ?        ; HEIGHT OF THE ENTIRE OUTLINE
  43. RIGHT_BIT    DW    ?        ; BIT OFFSET OF RIGHT EDGE
  44. TOP1_BYTE    DW    ?        ; BYTE OFFSET OF TOP LINE +1
  45. BOTTOM_BYTE    DW    ?        ; BYTE OFFSET OF BOTTOM LINE
  46. TOP_BYTE    DW    ?        ; BYTE OFFSET OF TOP LINE
  47. X_OFF        DW    ?        ; HORIZONTAL OFFSET INTO THE BLOCK BEING PROCESSED
  48. Y_OFF        DW    ?        ; OFFSET INTO THE BLOCK BEING PROCESSED
  49. X_TEMP        DW    ?        ; TEMPORARY X VALUE
  50. BLKOFF        DW    ?        ; THE OFFSET OF A BLOCK PASSED TO EGABLOCK
  51. BLKSEG        DW    ?        ; THE SEGMENT OF A BLOCK PASSED TO EGABLOCK
  52.         ENDDS
  53.  
  54.         PSEG
  55.         PUBLIC  _EGAPT,_EGALINE,_EGALINE2,_EGALINEA
  56.         PUBLIC    _INITEGA,_RESETEGA,_EGAPAL,_PUTMAPE;,_OUTLINEE
  57.         PUBLIC    _INVERSEE,_EGABLOCK,_SETTRANS
  58.         PUBLIC    _INVERT10,_LINE10,_CIRCLE10,_INCIRC10
  59.  
  60. ;
  61. ;NAME:        PIXELADDR10
  62. ;
  63. ;CALLER:    AX = Y-COORDINATE
  64. ;        BX = X-COORDINATE
  65. ;
  66. ;RETURNS:    AH = BITMASK
  67. ;            BX = BYTE OFFSET IN BUFFER
  68. ;            CL = NUMBER OF BITS TO SHIFT LEFT
  69. ;            ES = VIDEO BUFFER SEGMENT
  70. ;
  71. ;
  72. ;
  73. BYTESPERLINE    EQU    80
  74. ORIGINOFFSET    EQU    0
  75. VIDEOBUFFERSEG    EQU    0A000H
  76. PIXELADDR10    PROC    NEAR
  77.  
  78.     MOV        CL, BL
  79.     PUSH    DX
  80.  
  81.     MOV        DX, BYTESPERLINE
  82.     MUL        DX
  83.  
  84.     POP        DX
  85.     SHR        BX, 1
  86.     SHR        BX, 1
  87.     SHR        BX, 1
  88.     ADD        BX, AX
  89.     ADD        BX, ORIGINOFFSET
  90.  
  91.     MOV        AX, VIDEOBUFFERSEG
  92.     MOV        ES, AX
  93.  
  94.     AND        CL, 7
  95.     XOR        CL, 7
  96.     MOV        AH,    1
  97.     RET
  98.  
  99. PIXELADDR10    ENDP
  100.  
  101. TRANSOFF    DW    ?        ; THE OFFSET OF THE TRANSLATION ARRAY
  102. TRANSSEG    DW    ?        ; THE SEGMENT OF THE TRANSLATION ARRAY
  103. TRANS_TAB    DB    256 DUP(?)    ; ALLOCATE ROOM FOR THE TRANSLATIONS TABLE
  104. ;******************************************************************
  105. ;  INITEGA
  106. ;    use the BIOS to set mode 10 on the EGA board
  107. ;
  108. _INITEGA    PROC    FAR
  109.     PUSH    DS
  110.     PUSH    ES
  111.     PUSH    SI
  112.     PUSH    DI
  113.     MOV    AX,0010H        ; set to hi-res mode for EGA
  114.     INT    10h                ; video
  115.     POP        DI
  116.     POP        SI
  117.     POP        ES
  118.     POP        DS
  119.     RET
  120. _INITEGA    ENDP
  121.  
  122. _RESETEGA    PROC    FAR
  123.     PUSH    DS
  124.     PUSH    ES
  125.     PUSH    SI
  126.     PUSH    DI
  127.     MOV    AX,3            ; set to color character mode
  128.     INT    10h
  129.     POP        DI
  130.     POP        SI
  131.     POP        ES
  132.     POP        DS
  133.     RET
  134. _RESETEGA    ENDP
  135.  
  136. ;*******************************************************************
  137. ;  PALETTE 
  138. ;     set one element of the EGA's palette select
  139. ;
  140. ;  usage:  egapal(reg,setting);
  141. ;             reg (0-15)        EGA's palette regs
  142. ;             setting            one byte, what to write there
  143. ;
  144. _EGAPAL    PROC    FAR
  145.     PUSH    BP
  146.     MOV    BP,SP
  147.  
  148.     MOV    BL,[BP+X]        ; register #
  149.     MOV    BH,[BP+X+2]        ; value
  150.     MOV    AX,01000H        ; set palette element
  151.     INT    10h
  152.  
  153.     POP    BP
  154.     RET
  155. _EGAPAL    ENDP
  156.  
  157. ;
  158. ;    TAKES A TABLE OF PALETTE SETTINGS AND USES BIOS CALL TO PUT THEM INTO THE PALETTE
  159. ;    USAGE:    PUTMAPE(&TABLE)
  160. ;
  161. _PUTMAPE    PROC    FAR
  162.     PUSH    BP
  163.     MOV    BP,SP
  164.     PUSH    DS
  165.     PUSH    ES
  166.  
  167.     MOV    DX,[BP+X]        ; GET THE OFFSET OF THE PALETTE LIST
  168.     MOV    AX,[BP+X+2]        ; GET THE SEGMENT OF THE PALETTE LIST
  169.     MOV    ES,AX            ; MOVE THE SEGMENT INTO THE PROPER REGISTER
  170.     MOV    AX,01002H        ; MOVE THE CODE FOR SETTING ALL PALETTE REGISTERS INTO THE AX
  171.     INT    10H                ; DO A VIDEO BIOS CALL TO SET THE PALETTE REGISTERS
  172.         
  173.     POP    ES
  174.     POP    DS
  175.     POP    BP
  176.     RET
  177. _PUTMAPE    ENDP
  178.  
  179. ;*****************************************************************
  180. ;  Puts an absolute pixel in the given color
  181. ;
  182. ;   usage:   egapoint(x,y,color,table)
  183. ;            x,y = point location
  184. ;            color = integer color number  0 to 255
  185. ;            table = translation table of 256 bytes for XLAT
  186. ;
  187. ;   BUG:  will only write on black background, see egaline for
  188. ;         clearing all four planes before writing to specified planes
  189. ;         in that color
  190. ;
  191. _EGAPT    PROC    FAR
  192.     PUSH    BP
  193.     MOV    BP,SP
  194.     PUSH    ES
  195.     PUSH    DI
  196.  
  197.     MOV AL,FLAG  
  198.     OR    AL,AL
  199.     JNZ NOSETUP
  200.     CALL    SETUPG        ; set up the mask regs
  201.     MOV FLAG,1            ; set the flag
  202. NOSETUP:
  203.     MOV CX,TRANSSEG        ; get segment of transtable
  204.     MOV BX,TRANSOFF        ; get offset of transtable
  205.     MOV    AX,[BP+X+4]        ; get the color param = 3rd param
  206.     PUSH DS
  207.     MOV DS,CX            ; set ds for the transtable
  208.     XLATB                ; pick up translated color
  209.     POP DS
  210.     MOV    DX,MAPMASK
  211.     OUT    DX,AL            ; set the mask to this color
  212.     MOV    AX,0A000H
  213.     MOV ES,AX            ; set for addressing
  214.     MOV    AX,[BP+X+2]        ; get y value 0 < y < 350
  215.     MOV    BX,80
  216.     MUL BX                ; multiply by 80 bytes/line
  217.     MOV DI,AX            ; put in DI
  218.     MOV AX,[BP+X]        ; get x value 0 < x < 640
  219.     MOV BX,AX            ; save it
  220.     MOV CL,3
  221.     SHR AX,CL            ; divide by 8
  222.     ADD DI,AX            ; add it to di = byte offset
  223. ;
  224.     MOV CX,BX
  225.     AND CX,0007H        ; save only the right three bits
  226.     MOV BL,80H            ; here's a bit
  227.     SHR    BL,CL            ; move it over some
  228.     MOV DX,BITMASK        ; set the mask
  229.     MOV AL,BL             
  230.     OUT DX,AL            ;  send it
  231. ;
  232.     MOV    AL,0FFH            ; set all bits
  233.     MOV    AH,ES:[DI]        ; latch the bytes
  234.     STOSB                ; place that bit on bit mask
  235.  
  236.     POP    DI
  237.     POP    ES
  238.     POP    BP
  239.     RET
  240. _EGAPT    ENDP
  241.  
  242. SETUPG:
  243.     MOV    DX,GCHIP
  244.     MOV    AL,MODEREG
  245.     OUT    DX,AL            ; choose write mode 0
  246.     INC    DX
  247.     MOV    AL,0
  248.     OUT    DX,AL            ; clear mode reg to 0
  249.     DEC DX
  250.     MOV    AL,DRREG        ; clear function select = Replace
  251.     OUT    DX,AL
  252.     INC DX
  253.     MOV    AL,0h            ; clear all
  254.     OUT    DX,AL
  255. ;
  256.     MOV    AL,MAPREG        ; want to access mapreg from 
  257.     MOV    DX,SEQ            ; sequencer set of regs
  258.     OUT    DX,AL
  259.     MOV    AL,BITREG        ; want to access bitreg from
  260.     MOV DX,GCHIP        ; graphics chip's regs
  261.     OUT    DX,AL
  262.     MOV    DX,BITMASK        ; set up the bitmask = no masking
  263.     MOV    AL,0FFH            ; all bits on
  264.     OUT    DX,AL
  265.     RET
  266. ;
  267. ;**************************************************************************
  268. ;  EGALINE
  269. ;
  270. ;   Write a stream of colors (represented by bytes) to the EGA, with 
  271. ;   a translation table for the EGA color map.
  272. ;
  273. ;   Usage:     egaline(x,y,colorbuffer,xoff,n)
  274. ;            x,y = point to start line at on the screen
  275. ;            colorbuffer = 4 byte pointer to stream of 
  276. ;            n    bytes.
  277. ;            xoff    = offset into the line to be sent to the screen
  278.  
  279. _EGALINE    PROC    FAR
  280.     PUSH    BP
  281.     MOV    BP,SP
  282.     PUSH    DS
  283.     PUSH    ES
  284.     PUSH    SI
  285.     PUSH    DI
  286.  
  287.     MOV AL,FLAG  
  288.     OR    AL,AL
  289.     JNZ NOSETUP2
  290.     CALL    SETUPG        ; set up the mask regs
  291.     MOV FLAG,1            ; set the flag
  292. NOSETUP2:
  293.     MOV AX,[BP+X+6]        ; get color table segment
  294.     MOV DS,AX            ; use it now
  295.  
  296.     MOV    AX,0A000H
  297.     MOV ES,AX            ; set for addressing
  298.     MOV    AX,[BP+X+8]        ; GET THE X OFFSET INTO THE ARRAY
  299.     CMP    AX,0            ; CHECK FOR NEGATIVE OFFSET
  300.     JGE    OKSIGN            ; JUMP AROUND FIXING THE WINDOW IF POSITIVE
  301.     NEG    AX                ; TAKE THE OPPOSITE VALUE
  302.     ADD    AX,[BP+X]        ; AND ADD IT TO THE POSITION ON THE SCREEN
  303.     MOV    [BP+X],AX        ; AND RE-STORE THE POSITION
  304.     MOV    AX,[BP+X+8]        ; GET THE NEGATIVE OFFSET AGAIN
  305.     ADD    AX,[BP+X+10]    ; REDUCE THE NUMBER OF BYTES TO COPY TO THE SCREEN
  306.     MOV    [BP+X+10],AX    ; AND STORE THE NUMBER OF BYTES AGAIN
  307. OKSIGN:
  308. ;    MOV    [BP+X+8],AX        ; PUT THE OFFSET BACK
  309. ;
  310.     MOV    AX,[BP+X+2]        ; get y value 0 < y < 350
  311.     MOV    BX,80
  312.     MUL BX                ; multiply by 80 bytes/line
  313.     MOV DI,AX            ; put in DI
  314.     MOV AX,[BP+X]        ; get x value 0 < x < 640
  315.     MOV BX,AX            ; save it
  316.     MOV CL,3
  317.     SHR AX,CL            ; divide by 8
  318.     ADD DI,AX            ; add it to di = byte offset
  319. ;
  320.     MOV CX,BX
  321.     AND CX,0007H        ; save only the right three bits
  322.     MOV BL,080H            ; here's a bit
  323.     ROR    BL,CL            ; move it over some
  324. ;
  325. ;  At this point, bl has the bit mask for the first bit in the line
  326. ;  Keep rotating it and set the mask for each bit to write
  327. ;
  328.     MOV CX,[BP+X+10]    ; get count of bytes
  329.     CMP    CX,0            ; CHECK FOR ZERO BYTES
  330.     JL    LINEDONE        ; JUMP TO THE END OF THE ROUTINE
  331.     MOV SI,[BP+X+4]        ; where to get the new colors
  332.     ADD    SI,[BP+X+8]        ; add in the x offset into the line
  333.  
  334.     MOV AH,BL            ; keep bit rotation in ah
  335.     MOV DX,TRANSSEG        ; get segment of transtable
  336.     MOV BX,TRANSOFF        ; get offset of transtable
  337. NEXTBIT:
  338.     LODSB                ; get the next color to al
  339.     PUSH DS
  340.     MOV DS,DX            ; set ds for the transtable
  341.     XLATB                ; pick up translated color to al
  342.     PUSH AX                ; need it later
  343.  
  344.     MOV DX,BITMASK        ; set the bitmask to current rotation
  345.     MOV AL,AH
  346.     OUT DX,AL            ;  send it
  347.  
  348.     MOV    DX,MAPMASK
  349.     MOV AL,0FH            ; open all bit planes
  350.     OUT    DX,AL            ; send it
  351.  
  352.     MOV    AL,ES:[DI]        ; latch the whole set of bytes
  353.     MOV BYTE PTR ES:[DI],0H  ; clear all four planes to 0 at this bit
  354.     POP    AX                ; get real color back
  355.     OUT    DX,AL            ; send it to set the color planes
  356.  
  357.     MOV DX,DS            ;  recover what was in dx
  358.     POP DS
  359. ;
  360.     MOV    AL,0FFH            ; set all bits
  361.     CMP AH,01            ; see if we are at end of byte
  362.     JZ    INCSTORE
  363.  
  364. NONINC:
  365.     MOV ES:[DI],AL        ; write the bit from bitmask
  366.     ROR AH,1            ; rotate me
  367.     LOOP    NEXTBIT        ; go back for next one
  368.     JMP LINEDONE
  369.  
  370. INCSTORE:
  371.     STOSB                ; place that bit on bit mask and next byte
  372.     ROR AH,1            ; rotate me
  373.     LOOP    NEXTBIT
  374.  
  375. LINEDONE:
  376.     POP        DI
  377.     POP        SI
  378.     POP        ES
  379.     POP        DS
  380.     POP    BP
  381.     RET
  382. _EGALINE    ENDP
  383.  
  384.         
  385. _EGALINE2    PROC    FAR
  386.     PUSH    BP
  387.     MOV    BP,SP
  388.     PUSH    DS
  389.     PUSH    ES
  390.     PUSH    SI
  391.     PUSH    DI
  392.  
  393.     MOV AL,FLAG  
  394.     OR  AL,AL
  395.     JNZ NO2SETUP2
  396.     CALL    SETUPG        ; set up the mask regs
  397.     MOV FLAG,1            ; set the flag
  398. NO2SETUP2:
  399.     MOV AX,[BP+X+6]        ; get color table segment
  400.     MOV DS,AX            ; use it now
  401.  
  402.     MOV    AX,0A000H
  403.     MOV ES,AX            ; set for addressing
  404.     MOV    AX,[BP+X+2]        ; get y value 0 < y < 350
  405.     MOV    BX,80
  406.     MUL BX                ; multiply by 80 bytes/line
  407.     MOV DI,AX            ; put in DI
  408.     MOV AX,[BP+X]        ; get x value 0 < x < 640
  409.     MOV BX,AX            ; save it
  410.     MOV CL,3
  411.     SHR AX,CL            ; divide by 8
  412.     ADD DI,AX            ; add it to di = byte offset
  413. ;
  414.     MOV CX,BX
  415.     AND CX,0007H        ; save only the right three bits
  416.     MOV BL,0C0H            ; here's 2 bits
  417.     ROR    BL,CL            ; move it over some
  418. ;
  419. ;  At this point, bl has the bit mask for the first bit in the line
  420. ;  Keep rotating it and set the mask for each bit to write
  421. ;
  422.     MOV CX,[BP+X+8]        ; get count of bytes
  423.     MOV SI,[BP+X+4]        ; where to get the new colors
  424.  
  425.     MOV AH,BL            ; keep bit rotation in ah
  426.     MOV DX,[BP+X+12]    ; get segment of transtable
  427.     MOV BX,[BP+X+10]    ; get offset of transtable
  428.  
  429. NEXT2BIT:
  430.     LODSB                ; get the next color to al
  431.     PUSH DS
  432.     MOV DS,DX            ; set ds for the transtable
  433.     XLATB                ; pick up translated color to al
  434.     PUSH AX                ; need it later
  435.  
  436.     MOV DX,BITMASK        ; set the bitmask to current rotation
  437.     MOV AL,AH
  438.     OUT DX,AL            ;  send it
  439.  
  440.     MOV    DX,MAPMASK
  441.     MOV AL,0FH            ; open all bit planes
  442.     OUT    DX,AL            ; send it
  443.  
  444.     MOV    AL,ES:[DI]        ; latch the whole set of bytes
  445.     MOV BYTE PTR ES:[DI],0H  ; clear all four planes to 0 at this bit
  446.     POP    AX                ; get real color back
  447.     OUT    DX,AL            ; send it to set the color planes
  448.  
  449.     MOV DX,DS            ;  recover what was in dx
  450.     POP DS
  451. ;
  452.     MOV    AL,0FFH            ; set all bits
  453.     CMP AH,03            ; see if we are at end of byte
  454.     JZ INC2STORE
  455.  
  456. NON2INC:
  457.     MOV ES:[DI],AL        ; write the bit from bitmask
  458.     ROR AH,1            ; rotate me
  459.     ROR AH,1            ; rotate me
  460.     LOOP    NEXT2BIT    ; go back for next one
  461.     JMP LINE2DONE
  462.  
  463. INC2STORE:
  464.     STOSB                ; place that bit on bit mask and next byte
  465.     ROR AH,1            ; rotate me
  466.     ROR AH,1            ; again
  467.     LOOP    NEXT2BIT
  468.  
  469. LINE2DONE:
  470.     POP        DI
  471.     POP        SI
  472.     POP        ES
  473.     POP        DS
  474.     POP    BP
  475.     RET
  476. _EGALINE2    ENDP
  477.  
  478. ;**************************************************************************
  479. ;  EGALINEA
  480. ;
  481. ;   Write a stream of colors (represented by bytes) to the EGA, with 
  482. ;   a translation table for the EGA color map.  This one includes arbitrary
  483. ;   width expansion.
  484. ;
  485. ;   Usage:     egalinea(x,y,colorbuffer,n,table,expansion)
  486. ;            x,y = point to start line
  487. ;            colorbuffer = 4 byte pointer to stream of 
  488. ;            n    bytes.
  489. ;            table  = 4 byte pointer to translation table, 256 bytes
  490. ;                      long for XLAT instruction
  491. ;            expansion = how much horizontal pixel expansion you want
  492. ;
  493.  
  494. _EGALINEA    PROC    FAR
  495.     PUSH    BP
  496.     MOV    BP,SP
  497.     PUSH    DS
  498.     PUSH    ES
  499.     PUSH    SI
  500.     PUSH    DI
  501.  
  502.     MOV AL,FLAG  
  503.     OR  AL,AL
  504.     JNZ NOSETA
  505.     CALL    SETUPG        ; set up the mask regs
  506.     MOV FLAG,1            ; set the flag
  507. NOSETA:
  508.     MOV AX,[BP+X+6]         ; get color table segment
  509.     MOV DS,AX            ; use it now
  510.  
  511.     MOV    AX,0A000H
  512.     MOV ES,AX            ; set for addressing
  513.     MOV    AX,[BP+X+2]        ; get y value 0 < y < 350
  514.     MOV    BX,80
  515.     MUL BX                ; multiply by 80 bytes/line
  516.     MOV DI,AX            ; put in DI
  517.  
  518.     MOV AX,[BP+X]        ; get x value 0 < x < 640
  519.     MOV BX,AX            ;  save it
  520.     MOV CL,3
  521.     SHR AX,CL            ; divide by 8
  522.     ADD DI,AX            ; add it to di = byte offset
  523. ;
  524.     MOV CX,BX
  525.     AND CX,0007H        ; save only the right three bits
  526.     MOV BL,080H            ; here's a bit
  527.     ROR    BL,CL            ; move it over some
  528. ;
  529. ;  At this point, bl has the bit mask for the first bit in the line
  530. ;  Keep rotating it and set the mask for each bit to write
  531. ;
  532.     MOV SI,[BP+X+4]           ; where to get the new colors
  533.  
  534.     MOV AH,BL            ; keep bit rotation in ah
  535.     MOV DX,TRANSSEG        ; get segment of transtable
  536.     MOV    BX,TRANSOFF    ; get offset of transtable
  537.  
  538. NEXTBYTE:
  539.     MOV    CX,[BP+X+10]    ; pixel expansion number
  540.     LODSB                ; the next color to write
  541.     PUSH     DS
  542.     MOV    DS,DX            ; get the seg for xlat from dx
  543.     XLATB                ; color translation
  544.     MOV    [BP+X],AL        ; used as a local var for translated color
  545.  
  546. NEXTP:
  547.     MOV     DX,BITMASK        ; set the bitmask to current rotation
  548.     MOV     AL,AH
  549.     OUT     DX,AL            ;  send it
  550.  
  551.     MOV    DX,MAPMASK
  552.     MOV     AL,0FH            ; open all bit planes
  553.     OUT    DX,AL            ; send it
  554.  
  555.     MOV    AL,ES:[DI]        ; latch the whole set of bytes
  556.     MOV    BYTE PTR ES:[DI],0H  ; clear all four planes to 0 at this bit
  557.     MOV    AL,[BP+X]        ; get real color from local var
  558.     OUT    DX,AL            ; send it to set the color planes
  559. ;
  560.     MOV    AL,0FFH            ; set all bits
  561.     MOV    ES:[DI],AL        ; set it!
  562.     CMP     AH,01            ; see if we are at end of byte
  563.     JNZ     SAMEBYTE
  564.     INC        DI            ; get us to the next destination byte
  565. SAMEBYTE:
  566.     ROR     AH,1            ; rotate me
  567.     LOOP    NEXTP        ; go back for next one
  568.  
  569.     MOV    DX,DS            ; reset xlat segment into dx
  570.     POP    DS                ; get data input seg back
  571.     DEC    WORD PTR [BP+X+8] ; number of data points
  572.     JNZ    NEXTBYTE        ; do another, if necessary
  573.  
  574.     POP        DI
  575.     POP        SI
  576.     POP        ES
  577.     POP        DS
  578.     POP    BP
  579.     RET
  580. _EGALINEA    ENDP
  581. ifdef QAK
  582. ;
  583. ;    DRAWS AN INVERTED BOX ON THE EGA SCREEN
  584. ;    USAGE:    OUTLINEE(X1,Y1,X2,Y2);
  585. ;
  586. _OUTLINEE    PROC    FAR
  587.     PUSH    BP
  588.     MOV        BP,SP
  589.     PUSH    DS
  590.     PUSH    ES
  591.  
  592.     MOV    AX,[BP+X+2]            ; GET THE FIRST Y VALUE
  593.     CMP    AX,[BP+X+6]            ; COMPARE THE SECOND Y VALUE
  594.     JLE    CHECKX                ; OK ORDER, CHECK THE X VALUES
  595.     MOV    CX,AX                ; SWAP THE Y VALUES
  596.     MOV    AX,[BP+X+6]            ;
  597.     MOV    [BP+X+2],AX            ;
  598.     MOV    [BP+X+6],CX            ;
  599. CHECKX:
  600.     MOV    AX,[BP+X]            ; GET THE FIRST X VALUE
  601.     CMP    AX,[BP+X+4]            ; COMPARE THE SECOND X VALUE
  602.     JLE    MAKELEN                ; OK ORDER, COMPUTE THE LENGTHS
  603.     MOV    CX,AX                ; SWAP THE X VALUES
  604.     MOV    AX,[BP+X+4]            ;
  605.     MOV    [BP+X],AX            ;
  606.     MOV    [BP+X+4],CX            ;
  607. MAKELEN:                    ; COMPUTE THE X AND Y LENGTH OF THE BOX TO BE INVERTED
  608.     MOV    AX,[BP+X+4]            ; GET THE LARGER OF THE TWO X VALUES
  609.     SUB    AX,[BP+X]            ; SUBTRACT THE SMALLER VALUE TO GET THE LENGTH
  610.     ADD    AX,1                ;
  611.     MOV    X_WIDTH,AX            ; STORE THE LENGTH IN THE OLD LOCATION FOR THE 2ND VALUE
  612.     MOV    AX,[BP+X+6]            ; GET THE LARGER OF THE 2 Y VALUES
  613.     SUB    AX,[BP+X+2]            ; SUBTRACT THE SMALLER TO FIND THE LENGTH
  614.     ADD    AX,1                ; SUBTRACT FOR THE TOP AND BOTTOM EDGES
  615.     MOV    Y_HEIGHT,AX            ; STORE THE Y LENGTH IN THE OLD LOCATION FOR THE 2ND Y VALUE
  616. ; SET UP THE REST OF THE PARAMETERS
  617.     MOV    AX,[BP+X]            ; THE PIXEL POSITION OF THE LEFT EDGE
  618.     MOV    X_OFF,AX        
  619.     MOV    AX,[BP+X+2]            ; THE PIXEL POSITION OF THE TOP LINE
  620.     MOV    Y_OFF,AX
  621. ; MAKE THE TOP LINE
  622.     MOV    CX,X_WIDTH            ; GET THE NUMBER OF PIXELS TO WRITE
  623. OUTLOOP1:
  624.     PUSH    CX                ; SAVE THE COUNT FOR LATER
  625.     MOV    BH,0                ; USE THE ZERO GRAPHICS PAGE
  626.     MOV    DX,Y_OFF            ; SET THE POSITION OF THE TOP LINE
  627.     MOV    AX,0C8FH            ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
  628.     MOV    CX,X_OFF            ; GET THE CURRENT X LOCATION
  629.     INC    X_OFF                ; MOV THE X LOCATION TO THE NEXT PLACE
  630.     INT    10H                    ; DO BIOS VIDEO INTERUPT
  631.     POP    CX                    ; GET COUNT BACK
  632.     LOOP    OUTLOOP1        ; GO BACK AND FINISH THE LINE
  633. ; MAKE THE MIDDLE LINES
  634.     MOV    AX,[BP+X]            ; GET THE LEFT HAND EDGE
  635.     MOV    X_OFF,AX
  636.     MOV    AX,[BP+X+4]            ; GET THE RIGHT HAND EDGE
  637.     MOV    X_TEMP,AX
  638.     INC    Y_OFF                ; GO TO THE NEXT LINE
  639.     MOV    DX,Y_OFF
  640.     CMP    DX,[BP+X+6]            ; CHECK FOR THIS BEING FURTHER THAN THE BOTTOM LINE
  641.     JLE OUTLOOP2            ; NOT TO WORRY
  642.     DEC    Y_OFF                ; FIX DX BACK TO BE THE LINE
  643.     JMP    ENDLOOP2            ; JUMP TO DOING THE BOTTOM LINE
  644. OUTLOOP2:
  645.     CMP    DX,[BP+X+6]            ; CHECK FOR THE BOTTOM OF THE OUTLINE DONE
  646.     JE    ENDLOOP2            ; IF WE ARE THAN THE BOTTOM EDGE THEN JUMP TO BOTTOM LINE
  647.     MOV    BH,0                ; USE THE ZERO GRAPHICS PAGE
  648.     MOV    DX,Y_OFF            ; 
  649.     MOV    AX,0C8FH            ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
  650.     MOV    CX,X_OFF            ; MOVE THE VALUE FOR THE LEFT EDGE
  651.     INT    10H                    ; DO BIOS VIDEO INTERUPT
  652.     MOV    BH,0                ; USE THE ZERO GRAPHICS PAGE
  653.     MOV    DX,Y_OFF            ; 
  654.     MOV    AX,0C8FH            ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
  655.     MOV    CX,X_TEMP            ; MOVE THE VALUE FOR THE RIGHT EDGE
  656.     INT    10H                    ; DO BIOS VIDEO INTERUPT
  657.     INC    Y_OFF                ; GO TO NEXT VERTICAL VALUE
  658.     JMP OUTLOOP2            ; GO BACK TO TOP OF THE LOOP
  659.  
  660. ;MAKE THE BOTTOM LINE (Y_OFF IS ALREADY SET TO THE CORRECT VALUE)
  661. ENDLOOP2:
  662.     MOV    CX,X_WIDTH            ; GET THE NUMBER OF PIXELS TO WRITE
  663. OUTLOOP3:
  664.     PUSH    CX                ; SAVE THE COUNT FOR LATER
  665.     MOV    BH,0                ; USE THE ZERO GRAPHICS PAGE
  666.     MOV    DX,Y_OFF            ; SET THE POSITION OF THE TOP LINE
  667.     MOV    AX,0C8FH            ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
  668.     MOV    CX,X_OFF            ; GET THE CURRENT X LOCATION
  669.     INC    X_OFF                ; MOV THE X LOCATION TO THE NEXT PLACE
  670.     INT    10H                    ; DO BIOS VIDEO INTERUPT
  671.     POP    CX                    ; GET COUNT BACK
  672.     LOOP    OUTLOOP3        ; GO BACK AND FINISH THE LINE
  673.  
  674. DONE:
  675.     POP    ES
  676.     POP    DS
  677.     POP    BP
  678.     RET
  679. _OUTLINEE    ENDP
  680. endif
  681. ;
  682. ;    DRAWS AN INVERTED BOX ON THE EGA SCREEN
  683. ;    USAGE:    INVERSEE(X1,Y1,WIDTH,HEIGHT);
  684. ;
  685. _INVERSEE    PROC    FAR
  686.     PUSH    BP
  687.     MOV        BP,SP
  688.     PUSH    DS
  689.     PUSH    ES
  690.  
  691. MAKEINV:                    ; COMPUTE THE X AND Y LENGTH OF THE BOX TO BE INVERTED
  692.     MOV    AX,[BP+X+4]            ; GET THE WIDTH
  693.     MOV    X_WIDTH,AX            ; STORE THE WIDTH
  694.     MOV    AX,[BP+X+6]            ; GET THE HEIGHT
  695.     MOV    Y_HEIGHT,AX            ; STORE THE HEIGHT
  696. ; SET UP THE REST OF THE PARAMETERS
  697.     MOV    AX,[BP+X+2]            ; THE PIXEL POSITION OF THE TOP LINE
  698.     MOV    Y_OFF,AX
  699.     MOV    CX,Y_HEIGHT            ; GET THE HEIGHT OF THE BLOCK TO INVERSE
  700. INVTOP1:
  701.     PUSH    CX                ; SAVE THE HEIGHT VALUE
  702.     MOV    AX,[BP+X]            ; THE PIXEL POSITION OF THE LEFT EDGE
  703.     MOV    X_OFF,AX        
  704.     MOV    CX,X_WIDTH            ; GET THE WIDTH OF THE BLOCK TO INVERSE
  705. INVTOP2:
  706.     PUSH    CX                ; SAVE THE WIDTH VALUE
  707.     MOV    BH,0                ; USE THE ZERO GRAPHICS PAGE
  708.     MOV    DX,Y_OFF            ; SET THE POSITION OF THE TOP LINE
  709.     MOV    AX,0C8FH            ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
  710.     MOV    CX,X_OFF            ; GET THE CURRENT X LOCATION
  711.     INC    X_OFF                ; MOV THE X LOCATION TO THE NEXT PLACE
  712.     INT    10H                    ; DO BIOS VIDEO INTERUPT
  713.     POP    CX                    ; GET HORIZONTAL COUNT BACK
  714.     LOOP    INVTOP2            ; GO BACK AND FINISH THE LINE
  715.  
  716.     INC    Y_OFF                ; INCREMENT THE VERTICAL LINE WE ARE ON
  717.     POP    CX                    ; GET THE VERTICAL COUNT BACK
  718.     LOOP    INVTOP1            ; GO BACK AND FINISH THE BLOCK
  719.  
  720. DONEINV:
  721.     POP    ES
  722.     POP    DS
  723.     POP    BP
  724.     RET
  725. _INVERSEE    ENDP
  726. ;
  727. ;    DRAWS A BLOCK ON THE EGA SCREEN
  728. ;        USAGE:    egablock(&block,x1,y1,width,height);
  729. ;
  730. _EGABLOCK    PROC    FAR
  731.     PUSH    BP
  732.     MOV        BP,SP
  733.     PUSH    DS
  734.     PUSH    ES
  735.     PUSH    SI
  736.     PUSH    DI
  737.  
  738.     MOV    AX,[BP+X+8]            ; GET THE WIDTH
  739.     MOV    X_WIDTH,AX            ; STORE THE WIDTH
  740.     MOV    AX,[BP+X+10]        ; GET THE HEIGHT
  741.     MOV    Y_HEIGHT,AX            ; STORE THE HEIGHT
  742. ; SET UP THE REST OF THE PARAMETERS
  743.     MOV    AX,[BP+X]            ; GET THE OFFSET OF THE ARRAY OF INFORMATION
  744.     MOV    BLKOFF,AX            ; SAVE THE OFFSET OF THE ARRAY
  745.     MOV    AX,[BP+X+2]            ; GET THE SEGMENT OF THE ARRAY
  746.     MOV    BLKSEG,AX            ; SAVE THE SEGMENT
  747.     MOV    AX,[BP+X+6]            ; THE PIXEL POSITION OF THE TOP LINE
  748.     MOV    Y_OFF,AX
  749.     MOV    CX,Y_HEIGHT            ; GET THE HEIGHT OF THE BLOCK TO COPY
  750. BLKTOP1:
  751.     PUSH    CX                ; SAVE THE HEIGHT VALUE
  752.     PUSH    DS
  753.     MOV    AX,[BP+X+4]            ; THE PIXEL POSITION OF THE LEFT EDGE
  754.     MOV    X_OFF,AX        
  755.     MOV    CX,X_WIDTH            ; GET THE WIDTH OF THE BLOCK TO COPY
  756. BLKTOP2:
  757.     PUSH    CX                ; SAVE THE WIDTH VALUE
  758.     MOV    DI,BLKOFF            ; GET THE BLOCK OFFSET
  759.     MOV    ES,BLKSEG            ; GET THE BLOCK SEGMENT
  760.     MOV    AL,BYTE PTR ES:[DI]    ; GET THE VALUE FROM THE BLOCK
  761.     INC    BLKOFF                ; GO ON TO THE NEXT LOCATION IN THE BLOCK
  762.     PUSH    DS
  763.     MOV    BX,TRANSOFF            ; get offset of transtable
  764.     MOV    DS,TRANSSEG            ; get segment of transtable
  765.     XLATB                    ; pick up translated color
  766.     POP    DS
  767.     MOV    DX,Y_OFF            ; SET THE POSITION OF THE TOP LINE
  768.     MOV    AH,0CH                ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
  769.     MOV    BH,0                ; USE THE ZERO GRAPHICS PAGE
  770.     MOV    CX,X_OFF            ; GET THE CURRENT X LOCATION
  771.     INC    X_OFF                ; MOV THE X LOCATION TO THE NEXT PLACE
  772.     INT    10H                    ; DO BIOS VIDEO INTERUPT
  773.     POP    CX                    ; GET HORIZONTAL COUNT BACK
  774.     LOOP    BLKTOP2            ; GO BACK AND FINISH THE LINE
  775.  
  776.     INC    Y_OFF                ; INCREMENT THE VERTICAL LINE WE ARE ON
  777.     POP    DS                    ; GET THE FIRST DATA SEGMENT BACK
  778.     POP    CX                    ; GET THE VERTICAL COUNT BACK
  779.     LOOP    BLKTOP1            ; GO BACK AND FINISH THE BLOCK
  780.  
  781. DONEBLK:
  782.     POP        DI
  783.     POP        SI
  784.     POP    ES
  785.     POP    DS
  786.     POP    BP
  787.     RET
  788. _EGABLOCK    ENDP
  789.  
  790. TESTVAR1    DW    ?
  791. TESTVERT    DW    ?
  792. TESTCOLOR    DB    ?
  793.  
  794. _SETTRANS    PROC    FAR
  795.     PUSH    BP
  796.     MOV        BP,SP
  797.     PUSH    DS
  798.     PUSH    ES
  799.     PUSH    SI
  800.     PUSH    DI
  801.  
  802.     MOV        TRANSOFF,OFFSET TRANS_TAB    ; GET THE OFFSET OF THE TRANSLATION TABLE
  803.     MOV        TRANSSEG,SEG TRANS_TAB    ; GET THE SEGMENT OF THE TRANSLATION TABLE
  804.  
  805.     MOV        DI,TRANSOFF            ; GET THE OFFSET OF THE OLD TRANSLATION TABLE
  806.     MOV        ES,TRANSSEG            ; GET THE SEGMENT OF THE OLD TRANSLATION TABLE
  807.  
  808.     LDS        SI,DWORD PTR [BP+X]    ; GET THE OFFSET OF THE NEW TRANSLATION TABLE
  809.  
  810.     MOV        CX,128                ; COPY 256 BYTES
  811.  
  812.     REP        MOVSW                ; COPY THE ARRAY
  813.  
  814.     POP        DI
  815.     POP        SI
  816.     POP        ES
  817.     POP        DS
  818.     POP        BP
  819.     RET
  820. _SETTRANS    ENDP
  821.  
  822. ARGX1    EQU WORD PTR [BP+6]
  823. ARGY1    EQU    WORD PTR [BP+8]
  824. ARGX2    EQU    WORD PTR [BP+10]
  825. ARGY2    EQU WORD PTR [BP+12]
  826. ARGN    EQU BYTE PTR [BP+14]
  827.  
  828. VARVERTINCR    EQU    WORD PTR [BP-6]
  829. VARINCR1    EQU    WORD PTR [BP-8]
  830. VARINCR2    EQU    WORD PTR [BP-10]
  831. VARROUTINE    EQU    WORD PTR [BP-12]
  832.  
  833. BYTEOFFSETSHIFT    EQU    3
  834. BYTESPERLINE    EQU    80
  835. RMWBITS            EQU 0
  836.  
  837. _LINE10    PROC    FAR
  838.  
  839.     PUSH     BP
  840.     MOV        BP, SP
  841.     SUB     SP, 16H
  842.     PUSH    DS
  843.     PUSH    ES
  844.     PUSH    SI
  845.     PUSH     DI
  846.  
  847. ;CONFIGURE THE GRAPHICS CONTROLLER
  848.     MOV        DX, 3CEH
  849.     
  850.     MOV        AH, ARGN
  851.     XOR        AL, AL
  852.     OUT     DX, AX
  853.     
  854.     MOV     AX,0F01H
  855.  
  856.     OUT     DX, AX
  857.     MOV     AH, RMWBITS
  858.     MOV     AL, 3
  859.     OUT     DX, AX
  860.  
  861. ;CHECK FOR VERTICAL LINE
  862.     MOV        SI, BYTESPERLINE
  863.     
  864.     MOV     CX, ARGX2
  865.     SUB     CX, ARGX1
  866.     JZ         VERTLINE10
  867.  
  868. ;FORCE X1 < X2
  869.     JNS     L01
  870.  
  871.     NEG     CX
  872.     MOV     BX, ARGX2    
  873.     XCHG    BX, ARGX1
  874.     MOV        ARGX2,BX
  875.     MOV        BX, ARGY2
  876.     XCHG    BX, ARGY1
  877.     MOV        ARGY2,BX    
  878.     
  879. ;CALCULATE DY = ABS (Y2-Y1)
  880.  
  881. L01:    
  882.     MOV     BX, ARGY2
  883.     SUB        BX, ARGY1
  884.     JZ        HORIZLINE10
  885.  
  886.     JNS        L03
  887.     
  888.     NEG     BX
  889.     NEG        SI
  890.  
  891. ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
  892.  
  893. L03: 
  894.     MOV     VARVERTINCR,SI
  895.  
  896.     MOV        VARROUTINE, OFFSET LOSLOPELINE10
  897.     CMP        BX, CX
  898.     JLE        L04
  899.     MOV        VARROUTINE, OFFSET HISLOPELINE10
  900.     XCHG    BX, CX
  901.  
  902. ;CALCULATE INITIAL DECISION VARIABLE AND INCREMENTS
  903.  
  904. L04:
  905.     SHL        BX, 1
  906.     MOV        VARINCR1, BX
  907.     SUB        BX, CX
  908.     MOV        SI,BX
  909.     SUB        BX,CX
  910.     MOV        VARINCR2, BX
  911.         
  912. ;CALCULATE FIRST PIXEL ADDRESS
  913.  
  914.     PUSH     CX
  915.     MOV        AX, ARGY1
  916.     MOV     BX, ARGX1
  917.     CALL    PIXELADDR10
  918.  
  919.     MOV        DI, BX
  920.     SHL        AH, CL
  921.     MOV        BL, AH
  922.     MOV     AL, 8
  923.  
  924.     POP        CX
  925.     INC        CX
  926.     JMP        VARROUTINE
  927.  
  928. ;ROUTINE FOR VERTICAL LINES
  929.  
  930. VERTLINE10:
  931.     MOV        AX, ARGY1
  932.     MOV        BX, ARGY2
  933.     MOV        CX, BX
  934.     SUB        CX, AX
  935.     JGE        L31
  936.  
  937.     NEG        CX
  938.     MOV        AX, BX
  939.  
  940. L31:    
  941.     INC        CX
  942.     MOV        BX, ARGX1
  943.     PUSH    CX
  944.     CALL    PIXELADDR10
  945.     
  946. ;SET UP GRAPHICS CONTROLLER
  947.  
  948.     SHL        AH, CL
  949.     MOV        AL, 8
  950.     OUT     DX, AX
  951.  
  952.     POP     CX
  953.  
  954. ;DRAW THE LINE
  955. L32:    
  956.     OR        ES:[BX], AL
  957.     ADD     BX, SI
  958.     LOOP    L32
  959.     
  960.     JMP        LEXIT
  961.  
  962. ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
  963.  
  964. HORIZLINE10:
  965.     PUSH    DS
  966.     MOV        AX, ARGY1
  967.     MOV     BX, ARGX1
  968.     CALL    PIXELADDR10
  969.  
  970.     MOV        DI, BX
  971.     MOV        DH, AH
  972.     NOT        DH
  973.     SHL        DH, CL
  974.     NOT     DH
  975.     MOV        CX, ARGX2
  976.     AND        CL, 7
  977.     XOR     CL, 7
  978.     MOV        DL, 0FFH
  979.     
  980.     SHL        DL, CL
  981.         
  982. ;DETERMINE BYTE OFFSET OF FIRST AND LAST PIXEL IN THE LINE
  983.     
  984.     MOV     AX, ARGX2
  985.     MOV     BX, ARGX1
  986.  
  987.     MOV        CL, BYTEOFFSETSHIFT
  988.  
  989.     SHR        AX, CL
  990.     SHR        BX, CL
  991.     MOV     CX, AX
  992.     SUB        CX, BX
  993.     
  994. ;GET GRAPHICS CONTROLLER PORT ADDRESS INTO DX
  995.  
  996.     MOV         BX, DX
  997.  
  998.     MOV     DX, 3CEH
  999.     MOV     AL, 8
  1000.         
  1001. ;MAKE VIDEO BUFFER ADDRESSABLE THROUGH DS:SI
  1002.  
  1003.     PUSH     ES
  1004.     POP     DS
  1005.     MOV     SI, DI
  1006.     
  1007. ;SET PIXELS IN LEFTMOST BYTE OF THE LINE
  1008.  
  1009.     OR        BH, BH
  1010.     JS        L43
  1011.  
  1012.     OR         CX, CX
  1013.     JNZ        L42
  1014.     
  1015.     AND        BL, BH
  1016.     JMP        SHORT L44
  1017.     
  1018. L42:
  1019.     MOV        AH, BH
  1020.     OUT        DX, AX
  1021.  
  1022.     MOVSB
  1023.     DEC        CX
  1024.     
  1025. ;USE A FAST 8086 MACHINE INSTRUCTION TO DRAW THE REMAINDER OF THE LINE
  1026.  
  1027. L43:    
  1028.     MOV        AH, 11111111B
  1029.     OUT        DX, AX
  1030.     REP        MOVSB
  1031.  
  1032. ;SET PIXELS IN THE RIGHTMOST BYTE OF THE LINE
  1033.  
  1034. L44:    
  1035.     MOV        AH, BL
  1036.     OUT        DX, AX
  1037.     MOVSB
  1038.     
  1039.     POP     DS
  1040.     JMP        SHORT LEXIT
  1041.  
  1042. ;ROUTINE FOR DY>=DX (SLOPE<=1)
  1043.  
  1044. LOSLOPELINE10:
  1045.  
  1046. L10:    
  1047.     MOV     AH, BL
  1048. L11:    
  1049.     OR         AH,BL
  1050.     ROR        BL, 1
  1051.     JC        L14
  1052.  
  1053. ;BIT MASK NOT SHIFTED OUT
  1054.  
  1055.     OR         SI, SI
  1056.     JNS        L12
  1057.     ADD        SI, VARINCR1
  1058.     LOOP    L11
  1059.     OUT     DX, AX
  1060.     OR         ES:[DI], AL
  1061.     JMP        SHORT LEXIT
  1062.  
  1063. L12:    
  1064.     ADD        SI, VARINCR2
  1065.     OUT        DX, AX
  1066.  
  1067.     OR        ES:[DI], AL
  1068.     
  1069.     ADD        DI, VARVERTINCR
  1070.     LOOP    L10
  1071.     JMP        SHORT LEXIT
  1072.  
  1073. ;BIT MASK SHIFTED OUT
  1074.  
  1075. L14:    
  1076.     OUT        DX, AX
  1077.  
  1078.     OR        ES:[DI], AL
  1079.     INC        DI
  1080.     
  1081.     OR        SI, SI
  1082.     JNS        L15
  1083.  
  1084.     ADD     SI, VARINCR1
  1085.     LOOP     L10
  1086.     JMP     SHORT LEXIT
  1087.  
  1088. L15:    
  1089.     ADD     SI, VARINCR2
  1090.     ADD        DI, VARVERTINCR
  1091.     LOOP    L10
  1092.     JMP        SHORT LEXIT
  1093.  
  1094. ;ROUTINE FOR DY>DX (SLOPE >1)
  1095.  
  1096. HISLOPELINE10:
  1097.     MOV        BX, VARVERTINCR
  1098. L21:    
  1099.     OUT     DX, AX
  1100.     OR        ES:[DI], AL
  1101.     
  1102.     ADD        DI, BX
  1103.  
  1104. L22:    
  1105.     OR        SI, SI
  1106.     JNS        L23
  1107.     
  1108.     ADD        SI, VARINCR1
  1109.     LOOP    L21
  1110.     JMP        SHORT LEXIT
  1111.  
  1112. L23:    
  1113.     ADD        SI, VARINCR2
  1114.     ROR        AH, 1
  1115.     ADC        DI, 0
  1116.     
  1117.     LOOP     L21
  1118.  
  1119. ;RESTORE DEFAULT GRAPHICS CONTROLLER STATE AND RETURN TO CALLER
  1120.  
  1121. LEXIT:    
  1122.     XOR        AX, AX
  1123.     OUT     DX, AX
  1124.     INC     AX
  1125.     OUT        DX, AX
  1126.     MOV     AL, 3
  1127.     OUT        DX, AX
  1128.     MOV        AX, 0FF08H
  1129.     OUT        DX, AX
  1130.     POP     DI
  1131.     POP     SI
  1132.     POP        ES
  1133.     POP        DS
  1134.     MOV     SP,BP
  1135.     POP     BP
  1136.     RET
  1137.  
  1138. _LINE10    ENDP
  1139.  
  1140. RMWBITS2    EQU        24
  1141.  
  1142. _INVERT10    PROC    FAR
  1143.  
  1144.     PUSH     BP
  1145.     MOV        BP, SP
  1146.     SUB     SP, 16H
  1147.     PUSH    DS
  1148.     PUSH    ES
  1149.     PUSH    SI
  1150.     PUSH     DI
  1151.  
  1152. ;CONFIGURE THE GRAPHICS CONTROLLER
  1153.     MOV        DX, 3CEH
  1154.     
  1155.     MOV        AH, ARGN
  1156.     XOR        AL, AL
  1157.     OUT     DX, AX
  1158.     
  1159.     MOV     AX,0F01H
  1160.  
  1161.     OUT     DX, AX
  1162.     MOV     AH, RMWBITS2
  1163.     MOV     AL, 3
  1164.     OUT     DX, AX
  1165.  
  1166. ;CHECK FOR VERTICAL LINE
  1167.     MOV        SI, BYTESPERLINE
  1168.     
  1169.     MOV     CX, ARGX2
  1170.     SUB     CX, ARGX1
  1171.     JZ         IVERTLINE10
  1172.  
  1173. ;FORCE X1 < X2
  1174.     JNS     IL01
  1175.  
  1176.     NEG     CX
  1177.     MOV     BX, ARGX2    
  1178.     XCHG    BX, ARGX1
  1179.     MOV        ARGX2,BX
  1180.     MOV        BX, ARGY2
  1181.     XCHG    BX, ARGY1
  1182.     MOV        ARGY2,BX    
  1183.     
  1184. ;CALCULATE DY = ABS (Y2-Y1)
  1185.  
  1186. IL01:    
  1187.     MOV     BX, ARGY2
  1188.     SUB        BX, ARGY1
  1189.     JZ        IHORIZLINE10
  1190.  
  1191.     JNS        IL03
  1192.     
  1193.     NEG     BX
  1194.     NEG        SI
  1195.  
  1196. ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
  1197.  
  1198. IL03: 
  1199.     MOV     VARVERTINCR,SI
  1200.  
  1201.     MOV        VARROUTINE, OFFSET ILOSLOPELINE10
  1202.     CMP        BX, CX
  1203.     JLE        IL04
  1204.     MOV        VARROUTINE, OFFSET IHISLOPELINE10
  1205.     XCHG    BX, CX
  1206.  
  1207. ;CALCULATE INITIAL DECISION VARIABLE AND INCREMENTS
  1208.  
  1209. IL04:
  1210.     SHL        BX, 1
  1211.     MOV        VARINCR1, BX
  1212.     SUB        BX, CX
  1213.     MOV        SI,BX
  1214.     SUB        BX,CX
  1215.     MOV        VARINCR2, BX
  1216.         
  1217. ;CALCULATE FIRST PIXEL ADDRESS
  1218.  
  1219.     PUSH     CX
  1220.     MOV        AX, ARGY1
  1221.     MOV     BX, ARGX1
  1222.     CALL    PIXELADDR10
  1223.  
  1224.     MOV        DI, BX
  1225.     SHL        AH, CL
  1226.     MOV        BL, AH
  1227.     MOV     AL, 8
  1228.  
  1229.     POP        CX
  1230.     INC        CX
  1231.     JMP        VARROUTINE
  1232.  
  1233. ;ROUTINE FOR VERTICAL LINES
  1234.  
  1235. IVERTLINE10:
  1236.     MOV        AX, ARGY1
  1237.     MOV        BX, ARGY2
  1238.     MOV        CX, BX
  1239.     SUB        CX, AX
  1240.     JGE        IL31
  1241.  
  1242.     NEG        CX
  1243.     MOV        AX, BX
  1244.  
  1245. IL31:    
  1246.     INC        CX
  1247.     MOV        BX, ARGX1
  1248.     PUSH    CX
  1249.     CALL    PIXELADDR10
  1250.     
  1251. ;SET UP GRAPHICS CONTROLLER
  1252.  
  1253.     SHL        AH, CL
  1254.     MOV        AL, 8
  1255.     OUT     DX, AX
  1256.  
  1257.     POP     CX
  1258.  
  1259. ;DRAW THE LINE
  1260. IL32:    
  1261.     OR        ES:[BX], AL
  1262.     ADD     BX, SI
  1263.     LOOP    IL32
  1264.     
  1265.     JMP        ILEXIT
  1266.  
  1267. ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
  1268.  
  1269. IHORIZLINE10:
  1270.     PUSH    DS
  1271.     MOV        AX, ARGY1
  1272.     MOV     BX, ARGX1
  1273.     CALL    PIXELADDR10
  1274.  
  1275.     MOV        DI, BX
  1276.     MOV        DH, AH
  1277.     NOT        DH
  1278.     SHL        DH, CL
  1279.     NOT     DH
  1280.     MOV        CX, ARGX2
  1281.     AND        CL, 7
  1282.     XOR     CL, 7
  1283.     MOV        DL, 0FFH
  1284.     
  1285.     SHL        DL, CL
  1286.         
  1287. ;DETERMINE BYTE OFFSET OF FIRST AND LAST PIXEL IN THE LINE
  1288.     
  1289.     MOV     AX, ARGX2
  1290.     MOV     BX, ARGX1
  1291.  
  1292.     MOV        CL, BYTEOFFSETSHIFT
  1293.  
  1294.     SHR        AX, CL
  1295.     SHR        BX, CL
  1296.     MOV     CX, AX
  1297.     SUB        CX, BX
  1298.     
  1299. ;GET GRAPHICS CONTROLLER PORT ADDRESS INTO DX
  1300.  
  1301.     MOV         BX, DX
  1302.  
  1303.     MOV     DX, 3CEH
  1304.     MOV     AL, 8
  1305.         
  1306. ;MAKE VIDEO BUFFER ADDRESSABLE THROUGH DS:SI
  1307.  
  1308.     PUSH     ES
  1309.     POP     DS
  1310.     MOV     SI, DI
  1311.     
  1312. ;SET PIXELS IN LEFTMOST BYTE OF THE LINE
  1313.  
  1314.     OR        BH, BH
  1315.     JS        IL43
  1316.  
  1317.     OR         CX, CX
  1318.     JNZ        IL42
  1319.     
  1320.     AND        BL, BH
  1321.     JMP        SHORT IL44
  1322.     
  1323. IL42:
  1324.     MOV        AH, BH
  1325.     OUT        DX, AX
  1326.  
  1327.     MOVSB
  1328.     DEC        CX
  1329.     
  1330. ;USE A FAST 8086 MACHINE INSTRUCTION TO DRAW THE REMAINDER OF THE LINE
  1331.  
  1332. IL43:    
  1333.     MOV        AH, 11111111B
  1334.     OUT        DX, AX
  1335.     REP        MOVSB
  1336.  
  1337. ;SET PIXELS IN THE RIGHTMOST BYTE OF THE LINE
  1338.  
  1339. IL44:    
  1340.     MOV        AH, BL
  1341.     OUT        DX, AX
  1342.     MOVSB
  1343.     
  1344.     POP     DS
  1345.     JMP        SHORT ILEXIT
  1346.  
  1347. ;ROUTINE FOR DY>=DX (SLOPE<=1)
  1348.  
  1349. ILOSLOPELINE10:
  1350.  
  1351. IL10:    
  1352.     MOV     AH, BL
  1353. IL11:    
  1354.     OR         AH,BL
  1355.     ROR        BL, 1
  1356.     JC        IL14
  1357.  
  1358. ;BIT MASK NOT SHIFTED OUT
  1359.  
  1360.     OR         SI, SI
  1361.     JNS        IL12
  1362.     ADD        SI, VARINCR1
  1363.     LOOP    IL11
  1364.     OUT     DX, AX
  1365.     OR         ES:[DI], AL
  1366.     JMP        SHORT ILEXIT
  1367.  
  1368. IL12:    
  1369.     ADD        SI, VARINCR2
  1370.     OUT        DX, AX
  1371.  
  1372.     OR        ES:[DI], AL
  1373.     
  1374.     ADD        DI, VARVERTINCR
  1375.     LOOP    IL10
  1376.     JMP        SHORT ILEXIT
  1377.  
  1378. ;BIT MASK SHIFTED OUT
  1379.  
  1380. IL14:    
  1381.     OUT        DX, AX
  1382.  
  1383.     OR        ES:[DI], AL
  1384.     INC        DI
  1385.     
  1386.     OR        SI, SI
  1387.     JNS        IL15
  1388.  
  1389.     ADD     SI, VARINCR1
  1390.     LOOP     IL10
  1391.     JMP     SHORT ILEXIT
  1392.  
  1393. IL15:    
  1394.     ADD     SI, VARINCR2
  1395.     ADD        DI, VARVERTINCR
  1396.     LOOP    IL10
  1397.     JMP        SHORT ILEXIT
  1398.  
  1399. ;ROUTINE FOR DY>DX (SLOPE >1)
  1400.  
  1401. IHISLOPELINE10:
  1402.     MOV        BX, VARVERTINCR
  1403. IL21:    
  1404.     OUT     DX, AX
  1405.     OR        ES:[DI], AL
  1406.     
  1407.     ADD        DI, BX
  1408.  
  1409. IIL23:    
  1410.     OR        SI, SI
  1411.     JNS        IL23
  1412.     
  1413.     ADD        SI, VARINCR1
  1414.     LOOP    IL21
  1415.     JMP        SHORT ILEXIT
  1416.  
  1417. IL23:    
  1418.     ADD        SI, VARINCR2
  1419.     ROR        AH, 1
  1420.     ADC        DI, 0
  1421.     
  1422.     LOOP     IL21
  1423.  
  1424. ;RESTORE DEFAULT GRAPHICS CONTROLLER STATE AND RETURN TO CALLER
  1425.  
  1426. ILEXIT:    
  1427.     XOR        AX, AX
  1428.     OUT     DX, AX
  1429.     INC     AX
  1430.     OUT        DX, AX
  1431.     MOV     AL, 3
  1432.     OUT        DX, AX
  1433.     MOV        AX, 0FF08H
  1434.     OUT        DX, AX
  1435.     POP     DI
  1436.     POP     SI
  1437.     POP        ES
  1438.     POP        DS
  1439.     MOV     SP,BP
  1440.     POP     BP
  1441.     RET
  1442.  
  1443. _INVERT10    ENDP
  1444.  
  1445. ;NAME:    ELLIPSE10
  1446. ;
  1447. ARGXC    EQU WORD PTR [BP+6]
  1448. ARGYC    EQU WORD PTR [BP+8]
  1449. ARGA    EQU WORD PTR [BP+10]
  1450. ARGB    EQU WORD PTR [BP+12]
  1451. ARGN    EQU    BYTE PTR [BP+14]
  1452.  
  1453. ULADDR    EQU WORD PTR [BP-6]
  1454. URADDR    EQU WORD PTR [BP-8]
  1455. LLADDR    EQU WORD PTR [BP-10]
  1456. LRADDR    EQU WORD PTR [BP-12]
  1457. LMASK    EQU BYTE PTR [BP-14]
  1458. RMASK    EQU BYTE PTR [BP-16]
  1459.  
  1460.  
  1461. VARD        EQU WORD PTR [BP-20]
  1462. VARDX        EQU WORD PTR [BP-24]
  1463. VARDY        EQU WORD PTR [BP-28]
  1464. ASQUARED    EQU WORD PTR [BP-32]
  1465. BSQUARED    EQU WORD PTR [BP-36]
  1466. TWOASQUARED    EQU WORD PTR [BP-40]
  1467. TWOBSQUARED    EQU WORD PTR [BP-44]
  1468.  
  1469. RMWBITS        EQU    00H
  1470. BYTESPERLINE EQU    80
  1471.  
  1472. _CIRCLE10    PROC    FAR
  1473.     PUSH    BP
  1474.     MOV    BP,SP
  1475.     SUB    SP,50
  1476.     PUSH    DS
  1477.     PUSH    ES
  1478.     PUSH    SI
  1479.     PUSH    DI
  1480.     
  1481. ;SET GRAPHICS CONTROLLER MODE REGISTER
  1482.     MOV    DX,3CEH
  1483.     MOV    AX,0005H
  1484.     OUT    DX,AX
  1485.  
  1486. ;SET DATA ROTATE/FUNCTION SELECT REGISTER
  1487.     MOV    AH,RMWBITS
  1488.     MOV    AL,3
  1489.     OUT DX,AX
  1490.  
  1491. ;SET SET/RESET AND ENABLE SET/RESET REGISTERS
  1492.     MOV AH,ARGN
  1493.     MOV    AL,0
  1494.     OUT DX,AX
  1495.     MOV    AX,0F01H
  1496.     OUT DX,AX
  1497.  
  1498. ;INITIAL CONSTANTS
  1499.     MOV AX,ARGA
  1500.     MUL    AX
  1501.     MOV ASQUARED,AX
  1502.     MOV    ASQUARED+2,DX
  1503.     SHL    AX,1
  1504.     RCL    DX,1
  1505.     MOV    TWOASQUARED,AX
  1506.     MOV    TWOASQUARED+2,DX
  1507.     MOV    AX,ARGB
  1508.     MUL    AX
  1509.     MOV BSQUARED,AX
  1510.     MOV BSQUARED+2,DX
  1511.     SHL    AX,1
  1512.     RCL DX,1
  1513.     MOV TWOBSQUARED,AX
  1514.     MOV TWOBSQUARED+2,DX
  1515.  
  1516. ;PLOT PIXELS FROM (0,B) UNTIL DY/DX =-1
  1517. ;INITIAL BUFFER ADDRESS AND BIT MASK
  1518.     MOV    AX,BYTESPERLINE
  1519.     MUL    ARGB
  1520.     MOV    SI,AX
  1521.     MOV    DI,AX
  1522.     MOV    AX,ARGYC
  1523.     MOV    BX,ARGXC
  1524.     CALL    PIXELADDR10
  1525.  
  1526.     MOV    AH,1
  1527.     SHL    AH,CL
  1528.     MOV LMASK,AH
  1529.     MOV RMASK,AH
  1530.     
  1531.     ADD    SI,BX
  1532.     MOV    ULADDR,SI
  1533.     MOV URADDR,SI
  1534.     SUB    BX,DI
  1535.     MOV    LLADDR,BX
  1536.     MOV    LRADDR,BX
  1537.  
  1538. ;INITIAL DECISION VARIABLES
  1539.     XOR    AX,AX
  1540.     MOV    VARDX,AX
  1541.     MOV    VARDX+2,AX
  1542.  
  1543.     MOV    AX,TWOASQUARED
  1544.     MOV DX,TWOASQUARED+2
  1545.     MOV CX,ARGB
  1546.     CALL LONGMULTIPLY
  1547.     MOV VARDY,AX
  1548.     MOV VARDY+2,DX
  1549.  
  1550.     MOV AX,ASQUARED
  1551.     MOV    DX,ASQUARED+2
  1552.     SAR DX,1
  1553.     RCR    AX,1
  1554.     SAR    DX,1
  1555.     RCR AX,1
  1556.  
  1557.     ADD AX,BSQUARED
  1558.     ADC    DX,BSQUARED+2
  1559.     MOV    VARD,AX
  1560.     MOV VARD+2,DX
  1561.  
  1562.     MOV    AX,ASQUARED
  1563.     MOV    DX,ASQUARED+2
  1564.     MOV CX,ARGB
  1565.     CALL LONGMULTIPLY
  1566.     SUB    VARD,AX
  1567.     SBB    VARD+2,DX
  1568.     
  1569.     ;LOOP UNTIL DY/DX>=-1
  1570.     MOV    BX,ARGB
  1571.     XOR    CX,CX
  1572.     
  1573. C10:    
  1574.     MOV    AX,VARDX
  1575.     MOV    DX,VARDX+2
  1576.     SUB    AX,VARDY
  1577.     SBB    DX,VARDY+2
  1578.     JNS    C20
  1579.     
  1580.     CALL    SET4PIXELS
  1581.     MOV CX,1
  1582.     CMP    VARD+2,0
  1583.     JS    C11
  1584.     MOV    CH,1
  1585.     DEC    BX
  1586.     
  1587.     MOV AX,VARDY
  1588.     MOV    DX,VARDY+2
  1589.     SUB AX,TWOASQUARED
  1590.     SBB    DX,TWOASQUARED+2
  1591.     MOV VARDY,AX
  1592.     MOV    VARDY+2,DX
  1593.  
  1594.     SUB    VARD,AX
  1595.     SBB    VARD+2,DX
  1596.     
  1597. C11:
  1598.     MOV AX,VARDX
  1599.     MOV DX,VARDX+2
  1600.     ADD    AX,TWOBSQUARED
  1601.     ADC    DX,TWOBSQUARED+2
  1602.     MOV VARDX,AX
  1603.     MOV VARDX+2,DX
  1604.     ADD    AX,BSQUARED
  1605.     ADC    DX,BSQUARED+2
  1606.     ADD VARD,AX
  1607.     ADC    VARD+2,DX
  1608.     JMP    C10
  1609.     
  1610. ;PLOT PIXELS FROM CURRENT (X,Y) UNTIL Y<0
  1611.     
  1612. C20:
  1613.     PUSH    BX
  1614.     PUSH    CX
  1615.     MOV    AX,ASQUARED
  1616.     MOV    DX,ASQUARED+2
  1617.     SUB    AX,BSQUARED
  1618.     SBB    DX,BSQUARED+2
  1619.     MOV BX,AX
  1620.     MOV CX,DX
  1621.     
  1622.     SAR DX,1
  1623.     RCR    AX,1
  1624.     ADD AX,BX
  1625.     ADC    DX,CX
  1626.     
  1627.     SUB AX,VARDX
  1628.     SBB    DX,VARDX+2
  1629.     SUB    AX,VARDY
  1630.     SBB    DX,VARDY+2
  1631.     
  1632.     SAR    DX,1
  1633.     RCR    AX,1
  1634.     
  1635.     ADD    VARD,AX
  1636.     ADC    VARD+2,DX
  1637.     
  1638. ;LOOP UNTIL Y<0
  1639.     POP CX
  1640.     POP BX
  1641. C21:
  1642.     CALL SET4PIXELS
  1643.     MOV CX,100H
  1644.     
  1645.     CMP    VARD+2,0
  1646.     JNS    C22
  1647.     
  1648.     MOV CL,1
  1649.     MOV AX,VARDX
  1650.     MOV DX,VARDX+2
  1651.     ADD AX,TWOBSQUARED
  1652.     ADC    DX,TWOBSQUARED+2
  1653.     MOV    VARDX,AX
  1654.     MOV    VARDX+2,DX
  1655.     
  1656.     ADD    VARD,AX
  1657.     ADC    VARD+2,DX
  1658.     
  1659. C22:    
  1660.     MOV AX,VARDY
  1661.     MOV    DX,VARDY+2
  1662.     SUB    AX,TWOASQUARED
  1663.     SBB    DX,TWOASQUARED+2
  1664.     MOV    VARDY,AX
  1665.     MOV    VARDY+2,DX
  1666.  
  1667.     SUB    AX,ASQUARED
  1668.     SBB    DX,ASQUARED+2
  1669.     SUB    VARD,AX
  1670.     SBB    VARD+2,DX
  1671.     
  1672.     DEC    BX
  1673.     JNS    C21
  1674.     
  1675. ;RESTORE DEFAULT GRAPHICS CONTROLLER REGISTERS
  1676. CEXIT:
  1677.     MOV    AX,0FF08H
  1678.     MOV    DX,3CEH
  1679.     OUT    DX,AX
  1680.     MOV    AX,0003
  1681.     OUT    DX,AX
  1682.     MOV AX,0001
  1683.     OUT DX,AX
  1684.     POP        DI
  1685.     POP        SI
  1686.     POP        ES
  1687.     POP        DS
  1688.     MOV SP,BP
  1689.     POP    BP
  1690.     RET
  1691.     
  1692. _CIRCLE10    ENDP
  1693.  
  1694. ;NAME:    INCIRC10
  1695. ;
  1696. ARGXC    EQU WORD PTR [BP+6]
  1697. ARGYC    EQU WORD PTR [BP+8]
  1698. ARGA    EQU WORD PTR [BP+10]
  1699. ARGB    EQU WORD PTR [BP+12]
  1700.  
  1701. ULADDR    EQU WORD PTR [BP-6]
  1702. URADDR    EQU WORD PTR [BP-8]
  1703. LLADDR    EQU WORD PTR [BP-10]
  1704. LRADDR    EQU WORD PTR [BP-12]
  1705. LMASK    EQU BYTE PTR [BP-14]
  1706. RMASK    EQU BYTE PTR [BP-16]
  1707.  
  1708.  
  1709. VARD        EQU WORD PTR [BP-20]
  1710. VARDX        EQU WORD PTR [BP-24]
  1711. VARDY        EQU WORD PTR [BP-28]
  1712. ASQUARED    EQU WORD PTR [BP-32]
  1713. BSQUARED    EQU WORD PTR [BP-36]
  1714. TWOASQUARED    EQU WORD PTR [BP-40]
  1715. TWOBSQUARED    EQU WORD PTR [BP-44]
  1716.  
  1717. RMWBITS2    EQU    24
  1718. BYTESPERLINE EQU    80
  1719.  
  1720. _INCIRC10    PROC    FAR
  1721.     PUSH    BP
  1722.     MOV    BP,SP
  1723.     SUB    SP,50
  1724.     PUSH    DS
  1725.     PUSH    ES
  1726.     PUSH    SI
  1727.     PUSH    DI
  1728.     
  1729. ;SET GRAPHICS CONTROLLER MODE REGISTER
  1730.     MOV    DX,3CEH
  1731.     MOV    AX,0005H
  1732.     OUT    DX,AX
  1733.  
  1734. ;SET DATA ROTATE/FUNCTION SELECT REGISTER
  1735.     MOV    AH,RMWBITS2
  1736.     MOV    AL,3
  1737.     OUT DX,AX
  1738.  
  1739. ;SET SET/RESET AND ENABLE SET/RESET REGISTERS
  1740.     MOV AH,0                ; ARGN
  1741.     MOV    AL,0
  1742.     OUT DX,AX
  1743.     MOV    AX,0F01H
  1744.     OUT DX,AX
  1745.  
  1746. ;INITIAL CONSTANTS
  1747.     MOV AX,ARGA
  1748.     MUL    AX
  1749.     MOV ASQUARED,AX
  1750.     MOV    ASQUARED+2,DX
  1751.     SHL    AX,1
  1752.     RCL    DX,1
  1753.     MOV    TWOASQUARED,AX
  1754.     MOV    TWOASQUARED+2,DX
  1755.     MOV    AX,ARGB
  1756.     MUL    AX
  1757.     MOV BSQUARED,AX
  1758.     MOV BSQUARED+2,DX
  1759.     SHL    AX,1
  1760.     RCL DX,1
  1761.     MOV TWOBSQUARED,AX
  1762.     MOV TWOBSQUARED+2,DX
  1763.  
  1764. ;PLOT PIXELS FROM (0,B) UNTIL DY/DX =-1
  1765. ;INITIAL BUFFER ADDRESS AND BIT MASK
  1766.     MOV    AX,BYTESPERLINE
  1767.     MUL    ARGB
  1768.     MOV    SI,AX
  1769.     MOV    DI,AX
  1770.     MOV    AX,ARGYC
  1771.     MOV    BX,ARGXC
  1772.     CALL    PIXELADDR10
  1773.  
  1774.     MOV    AH,1
  1775.     SHL    AH,CL
  1776.     MOV LMASK,AH
  1777.     MOV RMASK,AH
  1778.     
  1779.     ADD    SI,BX
  1780.     MOV    ULADDR,SI
  1781.     MOV URADDR,SI
  1782.     SUB    BX,DI
  1783.     MOV    LLADDR,BX
  1784.     MOV    LRADDR,BX
  1785.  
  1786. ;INITIAL DECISION VARIABLES
  1787.     XOR    AX,AX
  1788.     MOV    VARDX,AX
  1789.     MOV    VARDX+2,AX
  1790.  
  1791.     MOV    AX,TWOASQUARED
  1792.     MOV DX,TWOASQUARED+2
  1793.     MOV CX,ARGB
  1794.     CALL LONGMULTIPLY
  1795.     MOV VARDY,AX
  1796.     MOV VARDY+2,DX
  1797.  
  1798.     MOV AX,ASQUARED
  1799.     MOV    DX,ASQUARED+2
  1800.     SAR DX,1
  1801.     RCR    AX,1
  1802.     SAR    DX,1
  1803.     RCR AX,1
  1804.  
  1805.     ADD AX,BSQUARED
  1806.     ADC    DX,BSQUARED+2
  1807.     MOV    VARD,AX
  1808.     MOV VARD+2,DX
  1809.  
  1810.     MOV    AX,ASQUARED
  1811.     MOV    DX,ASQUARED+2
  1812.     MOV CX,ARGB
  1813.     CALL LONGMULTIPLY
  1814.     SUB    VARD,AX
  1815.     SBB    VARD+2,DX
  1816.     
  1817.     ;LOOP UNTIL DY/DX>=-1
  1818.     MOV    BX,ARGB
  1819.     XOR    CX,CX
  1820.     
  1821. IC10:    
  1822.     MOV    AX,VARDX
  1823.     MOV    DX,VARDX+2
  1824.     SUB    AX,VARDY
  1825.     SBB    DX,VARDY+2
  1826.     JNS    IC20
  1827.     
  1828.     CALL    SET4PIXELS
  1829.     MOV CX,1
  1830.     CMP    VARD+2,0
  1831.     JS    IC11
  1832.     MOV    CH,1
  1833.     DEC    BX
  1834.     
  1835.     MOV AX,VARDY
  1836.     MOV    DX,VARDY+2
  1837.     SUB AX,TWOASQUARED
  1838.     SBB    DX,TWOASQUARED+2
  1839.     MOV VARDY,AX
  1840.     MOV    VARDY+2,DX
  1841.  
  1842.     SUB    VARD,AX
  1843.     SBB    VARD+2,DX
  1844.     
  1845. IC11:
  1846.     MOV AX,VARDX
  1847.     MOV DX,VARDX+2
  1848.     ADD    AX,TWOBSQUARED
  1849.     ADC    DX,TWOBSQUARED+2
  1850.     MOV VARDX,AX
  1851.     MOV VARDX+2,DX
  1852.     ADD    AX,BSQUARED
  1853.     ADC    DX,BSQUARED+2
  1854.     ADD VARD,AX
  1855.     ADC    VARD+2,DX
  1856.     JMP    IC10
  1857.     
  1858. ;PLOT PIXELS FROM CURRENT (X,Y) UNTIL Y<0
  1859.     
  1860. IC20:
  1861.     PUSH    BX
  1862.     PUSH    CX
  1863.     MOV    AX,ASQUARED
  1864.     MOV    DX,ASQUARED+2
  1865.     SUB    AX,BSQUARED
  1866.     SBB    DX,BSQUARED+2
  1867.     MOV BX,AX
  1868.     MOV CX,DX
  1869.     
  1870.     SAR DX,1
  1871.     RCR    AX,1
  1872.     ADD AX,BX
  1873.     ADC    DX,CX
  1874.     
  1875.     SUB AX,VARDX
  1876.     SBB    DX,VARDX+2
  1877.     SUB    AX,VARDY
  1878.     SBB    DX,VARDY+2
  1879.     
  1880.     SAR    DX,1
  1881.     RCR    AX,1
  1882.     
  1883.     ADD    VARD,AX
  1884.     ADC    VARD+2,DX
  1885.     
  1886. ;LOOP UNTIL Y<0
  1887.     POP CX
  1888.     POP BX
  1889. IC21:
  1890.     CALL SET4PIXELS
  1891.     MOV CX,100H
  1892.     
  1893.     CMP    VARD+2,0
  1894.     JNS    IC22
  1895.     
  1896.     MOV CL,1
  1897.     MOV AX,VARDX
  1898.     MOV DX,VARDX+2
  1899.     ADD AX,TWOBSQUARED
  1900.     ADC    DX,TWOBSQUARED+2
  1901.     MOV    VARDX,AX
  1902.     MOV    VARDX+2,DX
  1903.     
  1904.     ADD    VARD,AX
  1905.     ADC    VARD+2,DX
  1906.     
  1907. IC22:    
  1908.     MOV AX,VARDY
  1909.     MOV    DX,VARDY+2
  1910.     SUB    AX,TWOASQUARED
  1911.     SBB    DX,TWOASQUARED+2
  1912.     MOV    VARDY,AX
  1913.     MOV    VARDY+2,DX
  1914.  
  1915.     SUB    AX,ASQUARED
  1916.     SBB    DX,ASQUARED+2
  1917.     SUB    VARD,AX
  1918.     SBB    VARD+2,DX
  1919.     
  1920.     DEC    BX
  1921.     JNS    IC21
  1922.     
  1923. ;RESTORE DEFAULT GRAPHICS CONTROLLER REGISTERS
  1924. ICEXIT:
  1925.     MOV    AX,0FF08H
  1926.     MOV    DX,3CEH
  1927.     OUT    DX,AX
  1928.     MOV    AX,0003
  1929.     OUT    DX,AX
  1930.     MOV AX,0001
  1931.     OUT DX,AX
  1932.     POP        DI
  1933.     POP        SI
  1934.     POP        ES
  1935.     POP        DS
  1936.     MOV SP,BP
  1937.     POP    BP
  1938.     RET
  1939. _INCIRC10    ENDP
  1940.  
  1941. SET4PIXELS    PROC    NEAR
  1942.     PUSH    AX
  1943.     PUSH    BX
  1944.     PUSH    DX
  1945.     MOV DX,3CEH
  1946.     XOR    BX,BX
  1947.     TEST    CH,CH
  1948.     JZ    C30
  1949.     MOV    BX,BYTESPERLINE
  1950.     NEG    BX
  1951. C30:
  1952.     MOV    AL,8
  1953.     
  1954. ;PIXELS AR (XC-X,YC+Y) AND XC-C,YC-Y)
  1955.  
  1956.     XOR    SI,SI
  1957.     MOV    AH,LMASK
  1958.     ROL    AH,CL
  1959.     RCL    SI,1
  1960.     NEG    SI
  1961.     MOV DI,SI
  1962.     ADD    SI,ULADDR
  1963.     ADD    SI,BX
  1964.     ADD    DI,LLADDR
  1965.     SUB    DI,BX
  1966.     MOV    LMASK,AH
  1967.     MOV    ULADDR,SI
  1968.     MOV    LLADDR,DI
  1969.     OUT    DX,AX
  1970.     MOV    CH,ES:[SI]
  1971.     MOV    ES:[SI],CH
  1972.     MOV    CH,ES:[DI]
  1973.     MOV    ES:[DI],CH
  1974.     
  1975. ;PIXELS AT (XC+X,YC+Y) AND (XC+X,YC+Y)
  1976.  
  1977.     XOR    SI,SI
  1978.     MOV    AH,RMASK
  1979.     ROR    AH,CL
  1980.     RCL    SI,1
  1981.     MOV    DI,SI
  1982.     
  1983.     ADD    SI,URADDR
  1984.     ADD SI,BX
  1985.     ADD    DI,LRADDR
  1986.     SUB    DI,BX
  1987.     
  1988.     MOV    RMASK,AH
  1989.     MOV    URADDR,SI
  1990.     MOV    LRADDR,DI
  1991.     
  1992.     OUT    DX,AX
  1993.     MOV    CH,ES:[SI]
  1994.     MOV    ES:[SI],CH
  1995.     MOV    CH,ES:[DI]
  1996.     MOV ES:[DI],CH
  1997.     
  1998.     POP    DX
  1999.     POP BX
  2000.     POP AX
  2001.     RET
  2002.  
  2003. SET4PIXELS    ENDP
  2004.  
  2005. LONGMULTIPLY    PROC    NEAR
  2006.  
  2007.     PUSH    AX
  2008.     MOV    AX,DX
  2009.     MUL    CX
  2010.     XCHG    AX,CX
  2011.     POP DX
  2012.     MUL DX
  2013.     ADD    DX,CX
  2014.     RET
  2015.  
  2016. LONGMULTIPLY    ENDP
  2017.  
  2018.  
  2019.         ENDPS
  2020.         END
  2021.