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

  1. ;    
  2. ;    VGA support routines for raster oriented graphics
  3. ;
  4. ;    Quincey Koziol        January 1989
  5. ;
  6. ;    National Center for Supercomputing Applications,    University of Illinois
  7. ;    153    Water Resources Building
  8. ;    605 E. Springfield Ave.
  9. ;    Champaign, Ill    61820
  10. ;    (217)244-0072
  11. ;
  12.     TITLE      VGA GRAPHICS SUPPORT
  13. .model LARGE
  14. .code
  15. X    EQU        6
  16. ;    INCLUDE DOS.MAC
  17. ;    SETX
  18. ;    PSEG
  19.     PUBLIC    _PUTMAPV,_GETMAP,_VGALINE1,_VGACHUNK,_VGAPT,_VGAMODE,_VGAOFF,_VGAON
  20.     PUBLIC    _OUTLINEV,_BALL,_VGABLOCK,_INVERSEV,_INVERT13,_LINE13
  21.     PUBLIC    _SHOWPALV,_NOPALV
  22.     PUBLIC    _CIRCLE13,_INCIRC13
  23.  
  24. ;    name:     PIXELADDR13
  25. ;
  26. ;    FUNCTION: CALCULATE THE BUFFER ADDRESS OF PIXEL IN 320X200 256 COLOR MODE
  27. ;
  28. ;    CALLER:    AX = Y COOR. (0-199)
  29. ;            BX = X COOR. (0-319)
  30. ;
  31. ;
  32. ;    RETURNS:    BX = BYTE OFFSET IN BUFFER
  33. ;                ES = VIDEO BUFFER SEGMENT
  34. ;
  35. ORIGINOFFSET    EQU    0
  36. VIDEOBUFFSEG    EQU    0A000H
  37. PIXELADDR13    PROC    NEAR
  38.     XCHG    AH,AL
  39.     ADD        BX,AX
  40.     SHR        AX,1
  41.     SHR        AX,1
  42.     ADD        BX,AX
  43.     ADD        BX,ORIGINOFFSET
  44.     MOV        AX,VIDEOBUFFSEG
  45.     MOV        ES,AX
  46.     RET
  47. PIXELADDR13    ENDP
  48.  
  49. ;
  50. ;    take three arrays of color tables and interleave them into the
  51. ;    VGA registers in the fashion Red, Green, Blue.
  52. ;
  53.  
  54. _PUTMAPV    PROC    FAR
  55.     PUSH    BP
  56.     MOV        BP,SP
  57.     PUSH    DS
  58.     PUSH    ES
  59.     PUSH    SI
  60.     PUSH    DI
  61. ;
  62.     LDS    SI,DWORD PTR [BP+X]        ; WHERE TO GET RED
  63.     MOV DI,[BP+X+4]        ; WHERE TO GET GREEN
  64.     MOV BP,[BP+X+8]        ; WHERE TO GET BLUE
  65.     MOV    DX,03C8H        ; I/O PORT FOR PEL TABLE
  66.     MOV AL,0            ; VALUE FOR BEGINNING OF TABLE
  67.     OUT DX,AL            ; START OUTPUTTING VALUES
  68.     INC DX                ; INCREMENT DX TO OUTPUT TABLE
  69.     MOV CX,256            ; LENGTH OF THE TABLE IN BYTE TRIPLES
  70.  
  71. DORGB:
  72.     MOV AL,DS:[SI]        ; GET A RED BYTE
  73.     SHR AL,1
  74.     SHR AL,1            ; GET RID OF TWO HIGHEST BITS
  75.     OUT DX,AL            
  76.     INC SI
  77. ;
  78.     MOV AL,DS:[DI]        ; GET A GREEN BYTE
  79.     SHR    AL,1
  80.     SHR AL,1            ; GET RID OF TWO HIGHEST BITS
  81.     OUT DX,AL
  82.     INC DI
  83. ;
  84.     MOV    AL,DS:[BP]        ; GET A BLUE BYTE
  85.     SHR AL,1
  86.     SHR AL,1            ; GET RID OF TWO HIGHEST BITS
  87.     OUT DX,AL            
  88.     INC BP
  89. ;
  90.     LOOP DORGB            ; CONTINUE PRINTING UNTIL ALL 768 BYTES ARE WRITTEN
  91. ;
  92.     POP        DI
  93.     POP        SI
  94.     POP    ES
  95.     POP    DS
  96.     POP    BP
  97.     RET
  98.  
  99. _PUTMAPV    ENDP
  100.  
  101. _GETMAP    PROC    FAR
  102.     RET
  103. _GETMAP    ENDP
  104.  
  105. ;
  106. ;  Transfer line to vga screen
  107. ;
  108. ;   usage : vgaline1(x,y,buf,xoff,linelen)
  109. ;
  110. _VGALINE1    PROC    FAR
  111.     PUSH    BP
  112.     MOV        BP,SP
  113.     PUSH    DS
  114.     PUSH    ES
  115.     PUSH    SI
  116.     PUSH    DI
  117.  
  118.     LDS    SI,DWORD PTR [BP+X+4]    ; WHERE DATA WILL COME FROM
  119.     ADD    SI,[BP+X+8]        ; ADD THE OFFSET TO THE OFFSET OF THE ARRAY
  120. ;
  121.  
  122.     MOV    AX,[BP+X+2]    ; GET THE Y VALUE
  123.     MOV    BX,[BP+X]    ; GET THE X VALUE
  124.     CALL    PIXELADDR13    ; CALCULATE THE ADDRESS OF THE PIXEL
  125.     MOV    DI,BX        ; PREPARE FOR MOVS
  126.  
  127.     MOV    CX,[BP+X+10]    ; HOW MANY BYTES?
  128.     SHR    CX,1                        ; CHECK WHETHER THIS CAN BE WORD MOV'ED OR NOT
  129.     JC    DOBYTES                        ; NO, CANNOT USE WORD MOVE
  130.     REP    MOVSW                        ; MOVE WORDS
  131.     JMP    SHORT    DONEBYTES            ; JUMP AROUND THE BYTE COPY
  132.  
  133. DOBYTES:
  134.     MOV    CX,[BP+X+10]                ; GET THE COUNT OF BYTES TO MOVE
  135.     REP    MOVSB                        ; MOV THE MEMORY
  136.  
  137. DONEBYTES:
  138.     POP        DI
  139.     POP        SI
  140.     POP    ES
  141.     POP    DS
  142.     POP    BP
  143.     RET
  144. _VGALINE1    ENDP
  145.  
  146.  
  147. ;
  148. ;  Transfer chunk to vga screen
  149. ;
  150. ;   usage : vgachunk(x,y,buf,xoff,yoff,width,height,linelen)
  151. ;                int x,y;  the position to place the block on the screen
  152. ;                char *buf; the chunk to display
  153. ;                int xoff,yoff; the x and y offset into the chunk
  154. ;                int width,height; the width and height of the chunk part to display
  155. ;                int linelen;  the length of a horizontal raster line in the chunk
  156. ;
  157. _VGACHUNK    PROC    FAR
  158.     PUSH    BP
  159.     MOV        BP,SP
  160.     PUSH    DS
  161.     PUSH    ES
  162.     PUSH    SI
  163.     PUSH    DI
  164.  
  165.     LDS    SI,DWORD PTR [BP+X+4]    ; WHERE DATA WILL COME FROM
  166.     MOV    AX,[BP+X+10]    ; GET THE OFFSET IN THE Y DIRECTION
  167.     JZ    ADD_X_OFF        ; IF THE Y OFFSET IS ZERO THEN JUST ADD IN THE X OFFSET
  168.     MOV    DX,[BP+X+16]    ; GET THE LINE LENGTH
  169.     MUL    DX                ; CALCULATE THE AMOUNT OF OFFSET IN THE Y DIRECTION
  170.     ADD    SI,AX            ; ADD IN THE Y OFFSET
  171. ADD_X_OFF:
  172.     ADD    SI,[BP+X+8]        ; ADD THE OFFSET TO THE OFFSET OF THE ARRAY
  173. ;
  174.  
  175.     MOV    AX,[BP+X+2]        ; GET THE Y VALUE
  176.     MOV    BX,[BP+X]        ; GET THE X VALUE
  177.     CALL    PIXELADDR13    ; CALCULATE THE ADDRESS OF THE PIXEL
  178.     MOV    DI,BX            ; PREPARE FOR MOVS
  179.  
  180.     MOV    CX,[BP+X+12]    ; HOW MANY BYTES?
  181.     SHR    CX,1            ; CHECK WHETHER THIS CAN BE WORD MOV'ED OR NOT
  182.     JC    CHUNKLOOPB        ; NO, CANNOT USE WORD MOVE
  183.     MOV    [BP+X+12],CX    ; STORE THE NUMBER OF WORDS TO COPY
  184.  
  185. CHUNKLOOPW:
  186.     PUSH    SI            ; PUSH THE SOURCE INDEX
  187.     PUSH    DI            ; PUSH THE DESTINATION INDEX
  188.     MOV    CX,[BP+X+12]    ; GET THE COUNT OF BYTES TO MOVE
  189.     REP    MOVSW            ; MOVE WORDS
  190.  
  191.     POP    DI
  192.     ADD DI,320            ; ADD IN THE WIDTH OF THE SCREEN
  193.     POP    SI
  194.     ADD    SI,[BP+X+16]    ; ADD IN THE OFFSET FOR THE NEXT LINE THE CHUNK TO COPY
  195.     DEC WORD PTR [BP+X+14]        ; DECREMENT THE NUMBER OF LINES TO COPY
  196.     JNZ    CHUNKLOOPW        ; CONTINUE TO BLAST OUT LINES UNTIL WE HAVE DONE THEM ALL
  197.     JMP    SHORT    ENDCHUNK
  198.  
  199. CHUNKLOOPB:
  200.     PUSH    SI            ; PUSH THE SOURCE INDEX
  201.     PUSH    DI            ; PUSH THE DESTINATION INDEX
  202.     MOV    CX,[BP+X+12]    ; GET THE COUNT OF BYTES TO MOVE
  203.     REP    MOVSB            ; MOV THE MEMORY
  204.  
  205.     POP    DI
  206.     ADD DI,320            ; ADD IN THE WIDTH OF THE SCREEN
  207.     POP    SI
  208.     ADD    SI,[BP+X+16]    ; ADD IN THE OFFSET FOR THE NEXT LINE THE CHUNK TO COPY
  209.     DEC WORD PTR [BP+X+14]        ; DECREMENT THE NUMBER OF LINES TO COPY
  210.     JNZ    CHUNKLOOPB        ; CONTINUE TO BLAST OUT LINES UNTIL WE HAVE DONE THEM ALL
  211.  
  212. ENDCHUNK:
  213.     POP        DI
  214.     POP        SI
  215.     POP    ES
  216.     POP    DS
  217.     POP    BP
  218.     RET
  219. _VGACHUNK    ENDP
  220.  
  221. ;  draw a point on vga screen
  222. ;
  223. ;   usage : vgapt(x,y,color)
  224. ;
  225. _VGAPT    PROC    FAR
  226.     PUSH    BP
  227.     MOV        BP,SP
  228.     PUSH    DS
  229.     PUSH    ES
  230.     PUSH    DI
  231.  
  232. ;
  233. ;   READY TO PUT THE POINT
  234. ;
  235. POKBANK:
  236.     MOV    AX,[BP+X+2]    ; GET THE Y VALUE
  237.     MOV    BX,[BP+X]    ; GET THE X VALUE
  238.     CALL PIXELADDR13    ; CALCULATE THE PIXEL ADDRESS
  239.     MOV    DI,BX        ; PREPARE FOR MOVS
  240.     MOV    AL,[BP+X+4]    ; GET COLOR TO PUT THERE
  241.  
  242.     STOSB            ; PUT IT
  243.  
  244.     POP        DI
  245.     POP    ES
  246.     POP    DS
  247.     POP    BP
  248.     RET
  249. _VGAPT    ENDP
  250.  
  251. _VGAMODE        PROC    FAR
  252.     PUSH    BP
  253.     MOV        BP,SP
  254.     PUSH    DS
  255.     PUSH    ES
  256.     
  257.     MOV        AX,[BP+X]        ;GET SCREEN MODE TO SWITCH TO
  258.     XOR        AH,AH            ;ENTER VIDEO_IO ROUTINE (SET MODE=0)
  259.     INT        10H                ;VIDEO INTERUPT
  260.  
  261.     POP    ES
  262.     POP    DS
  263.     POP    BP
  264.     RET
  265. _VGAMODE    ENDP
  266.  
  267.  
  268. _VGAOFF        PROC    FAR
  269.     PUSH    BP
  270.     MOV        BP,SP
  271.     PUSH    DS
  272.     PUSH    ES
  273.     
  274.     MOV        DX,03C4H        ;ADDRESS OF THE SEQ CONTROLLER
  275.     MOV        AL,01H            ;INDEX OF THE CLOCKING MODE REGISTER
  276.     OUT        DX,AL            ;SET UP TO READ THE CLOCKING MODE REGISTER
  277.     MOV        DX,03C5H        ;ADDRESS TO READ FROM
  278.     IN        AL,DX            ;GET THE CLOCKING MODE REGISTER
  279.     OR        AL,20H            ;MASK OFF THE SCREEN ENABLE BIT    
  280.     MOV        BL,AL            ;KEEP THAT AROUND
  281.     MOV        DX,03C4H        ;ADDRESS OF THE SEQ CONTROLLER
  282.     MOV        AL,01H            ;INDEX OF THE CLOCKING REGISTER
  283.     OUT        DX,AL            ;SET UP TO WRITE BACK THE CLOCKING MODE REGISTER
  284.     INC        DX                ;SET TO ADDRESS TO WRITE TO
  285.     MOV        AL,BL            ;GET BACK THE PROPER VALUE
  286.     OUT        DX,AL            ;TURNS OFF THE VGA SCREEN
  287.  
  288.     POP    ES
  289.     POP    DS
  290.     POP    BP
  291.     RET
  292. _VGAOFF    ENDP
  293.  
  294. _VGAON        PROC    FAR
  295.     PUSH    BP
  296.     MOV        BP,SP
  297.     PUSH    DS
  298.     PUSH    ES
  299.     
  300.     MOV        DX,03C4H        ;ADDRESS OF THE SEQ CONTROLLER
  301.     MOV        AL,01H            ;INDEX OF THE CLOCKING MODE REGISTER
  302.     OUT        DX,AL            ;SET UP TO READ THE CLOCKING MODE REGISTER
  303.     INC        DX                ;ADDRESS TO READ FROM
  304.     IN        AL,DX            ;GET THE CLOCKING MODE REGISTER
  305.     AND        AL,0DFH            ;TURN ON THE SCREEN ENABLE BIT    
  306.     MOV        BL,AL            ;KEEP THAT AROUND
  307.     MOV        DX,03C4H        ;ADDRESS OF THE SEQ CONTROLLER
  308.     MOV        AL,01H            ;INDEX OF THE CLOCKING REGISTER
  309.     OUT        DX,AL            ;SET UP TO WRITE BACK THE CLOCKING MODE REGISTER
  310.     INC        DX                ;SET TO ADDRESS TO WRITE TO
  311.     MOV        AL,BL            ;GET BACK THE PROPER VALUE
  312.     OUT        DX,AL            ;TURNS ON THE VGA SCREEN
  313.  
  314.     POP    ES
  315.     POP    DS
  316.     POP    BP
  317.     RET
  318. _VGAON    ENDP
  319.  
  320. ;
  321. ;    showpalv(&palstore,pal_xoff,pal_yoff);
  322. ;    
  323. _SHOWPALV        PROC    FAR
  324.     PUSH    BP
  325.     MOV        BP,SP
  326.     PUSH    DS
  327.     PUSH    ES
  328.     PUSH    SI
  329.     PUSH    DI
  330.  
  331.  
  332.     MOV     AX,[BP+X]        ;GET OFFSET OF ARRAY
  333.     MOV        DI,AX
  334.     MOV        AX,[BP+X+2]        ;GET SEGMENT OF STORAGE ARRAY
  335.     MOV        ES,AX            
  336.  
  337.     MOV        AX,[BP+X+6]        ;GET LINE TO START PALETTE ON
  338.     MOV        DX,320            ;GET THE LINE LENGTH
  339.     MUL        DX                ;GET THE OFFSET INTO THE SCREEN
  340.     ADD        AX,[BP+X+4]        ;ADD IN THE X OFFSET
  341.     JNC        NO_ROLLOVER        ;ADDITION DIDN'T CARRY
  342.     INC        DX                ;INCREMENT THE DX REGISTER ON A CARRY
  343. NO_ROLLOVER:
  344.     MOV        SI,AX            ;KEEP TRACK OF THE OFFSET
  345.     MOV        BX,SI            ;IN TWO PLACES
  346.     MOV        AX,320            ;GET THE LINE LENGTH
  347.     MOV        DX,8            ;GET THE NUMBER OF LINES
  348.     MUL        DX                ;GET THE NUMBER OF BYTES TO COPY
  349.     MOV        CX,AX            ;MOVE INTO COUNTER
  350.     MOV        AX,0A000H
  351.     MOV        DS,AX            ;GET THE SEGMENT FOR THE SOURCE
  352. ZIP:
  353.     REP        MOVSB            ;COPY THAT SECTION OF SCREEN
  354.     
  355.     MOV        CH,0            ;THE NUMBER OF LINES COPIED SO FAR
  356.     MOV        CL,00            ;THE NUMBER OF PIXELS
  357. TOP1:
  358.     MOV        SI,BX            ;GET THE CORRECT OFFSET TO BE COPIED TO
  359.     MOV        AX,0A000H
  360.     MOV        ES,AX            ;GET THE SEGMENT TO BE COPIED TO
  361. TOP2:
  362.     MOV        ES:[SI],CL        ;COPY ACROSS THE SCREEN INCREMENTING VALUES
  363.     INC        SI                ;MOVE TO NEXT PIXEL
  364.     INC        CL                ;INCREMENT COUNTER
  365.     JNE        TOP2            ;IF COUNTER NOT EQUAL TO ZERO THEN COPY AGAIN
  366.     
  367.     ADD        BX,320            ;MOVE DOWN TO NEXT LINE
  368.     INC        CH                ;INCREMENT THE LINE COUNTER
  369.     CMP        CH,8            ;CHECK IF ALL THE LINES ARE DONE
  370.     JNE        TOP1            ;IF LINE COUNT <8 THEN COPY ANOTHER LINE
  371.  
  372.     POP    DI
  373.     POP    SI
  374.     POP    ES
  375.     POP    DS
  376.     POP    BP
  377.     RET
  378. _SHOWPALV    ENDP
  379.  
  380. ;
  381. ;    nopalv(&palstore,pal_xoff,pal_yoff);
  382. ;
  383. _NOPALV        PROC    FAR
  384.     PUSH    BP
  385.     MOV        BP,SP
  386.     PUSH    DS
  387.     PUSH    ES
  388.     PUSH    SI
  389.     PUSH    DI
  390.  
  391.     MOV     AX,[BP+X]        ;GET OFFSET OF ARRAY
  392.     MOV        SI,AX
  393.     MOV        AX,[BP+X+2]        ;GET SEGMENT OF STORAGE ARRAY
  394.     MOV        DS,AX            
  395.  
  396.     MOV        AX,[BP+X+6]        ;GET LINE TO COPY SCREEN BACK ONTO
  397.     MOV        DX,320            ;GET THE LINE LENGTH
  398.     MUL        DX                ;GET THE OFFSET INTO THE SCREEN
  399.     ADD        AX,[BP+X+4]        ;ADD IN THE X OFFSET
  400.     JNC        NO_ROLL2        ;ADDITION DIDN'T CARRY
  401.     INC        DX                ;INCREMENT THE DX REGISTER ON A CARRY
  402. NO_ROLL2:
  403.     MOV        DI,AX            ;KEEP TRACK OF THE OFFSET
  404.     MOV        AX,320            ;GET THE LINE LENGTH
  405.     MOV        DX,8            ;GET THE NUMBER OF LINES
  406.     MUL        DX                ;GET THE NUMBER OF BYTES TO COPY
  407.     MOV        CX,AX            ;MOVE INTO COUNTER
  408.     MOV        AX,0A000H
  409.     MOV        ES,AX            ;GET THE SEGMENT FOR THE SOURCE
  410. ZOOM:
  411.     REP        MOVSB            ;COPY THAT SECTION OF SCREEN
  412.  
  413.     POP    DI
  414.     POP    SI
  415.     POP    ES
  416.     POP    DS
  417.     POP    BP
  418.     RET
  419. _NOPALV    ENDP
  420.  
  421. ;
  422. ;  Invert A BOX ON THE SCREEN
  423. ;
  424. ;   usage : outlinev(x1,y1,x2,y2)
  425. ;
  426. _OUTLINEV    PROC    FAR
  427.     PUSH    BP
  428.     MOV    BP,SP
  429.     PUSH    DS
  430.     PUSH    ES
  431.     PUSH    SI
  432.     PUSH    DI
  433.  
  434.     MOV    AX,[BP+X+2]    ; GET FIRST Y VALUE
  435.     CMP    AX,[BP+X+6]    ; COMPARE WITH THE SECOND Y - VALUE
  436.     JLE    CHECKX        ; OK ORDER GOTO CHECKING THE X VALUES
  437.     MOV    CX,AX        ; SWAP THE TWO VALUES
  438.     MOV    AX,[BP+X+6]    ;
  439.     MOV    [BP+X+2],AX    ;
  440.     MOV    AX,CX        ;
  441.     MOV    [BP+X+6],AX    ;
  442. CHECKX:
  443.     MOV    AX,[BP+X]    ; GET FIRST X VALUE
  444.     CMP    AX,[BP+X+4]    ; COMPARE WITH THE SECOND X - VALUE
  445.     JLE    MAKELEN        ; OK ORDER GOTO COMPUTING THE LENGTHS
  446.     MOV    CX,AX        ; SWAP THE TWO VALUES
  447.     MOV    AX,[BP+X+4]    ;
  448.     MOV    [BP+X],AX    ;
  449.     MOV    AX,CX        ;
  450.     MOV    [BP+X+4],AX    ;
  451. MAKELEN:            ; COMPUTE THE X AND Y WIDTHS FOR THE BOX TO BE INVERTED
  452.     MOV    AX,[BP+X+4]    ; GET THE LARGER OF THE TWO X VALUES
  453.     SUB    AX,[BP+X]    ; SUBTRACT THE SMALLER VALUE TO FIND THE LENGTH
  454.     ADD    AX,1        ;
  455.     MOV    [BP+X+4],AX    ; STORE IT IN THE OLD LOCATION FOR THE 2ND X VALUE
  456.     MOV    AX,[BP+X+6]    ; GET THE LARGER OF THE TWO Y VALUES
  457.     SUB    AX,[BP+X+2]    ; SUBTRACT THE SMALLER VALUE TO FIND THE LENGTH
  458.     SUB    AX,1        ; SUBTRACT TWO FOR THE TOP AND BOTTOM EDGES
  459.     CMP    AX,0        ; CHECK IF IT IS LESS THAN ZERO
  460.     JG     POSITIVE    ; JUMP AROUND ZEROING THE ACC.
  461.     MOV    AX,0
  462. POSITIVE:
  463.     MOV    [BP+X+6],AX    ; STORE IT IN THE OLD LOCATION FOR THE 2ND Y VALUE
  464.     MOV    AX,320        ; COMPUTE THE VALUE TO ADD TO THE DI FOR COMPLETE WRAPAROUND
  465.     SUB    AX,[BP+X+4]    ;
  466.     MOV    SI,AX        ; KEEP TRACK OF IT
  467.     
  468. ;    MOV    AX,0A000H    ; DATA BUFFER
  469. ;    MOV    ES,AX
  470. ;
  471.     MOV    AX,[BP+X+2]    ; GET THE Y VALUE
  472.     MOV    BX,[BP+X]    ; GET THE X VALUE
  473.     CALL    PIXELADDR13    ; CALCULATE THE PIXEL ADDRESS
  474.     MOV    DI,BX        ; PREPARE FOR MOVS
  475.  
  476.     MOV    CX,[BP+X+4]    ; HOW MANY BYTES?
  477. BLASTA:
  478.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  479.     NOT    AL        ; INVERT THE VALUE THERE
  480.     MOV    ES:[DI],AL    ; REPLACE THE VALUE
  481.     INC    DI        ; INCREMENT TO NEXT POSITION
  482.     LOOP     BLASTA        ; LOOP UNTIL ALL HAVE BEEN DONE
  483.  
  484.     ADD    DI,SI        ; MOVE OVER TO THE BEGINNING OF THE NEXT LINE
  485.     MOV    CX,[BP+X+6]    ; COUNT VALUE FOR THE NEXT SERIES
  486.     CMP    CX,0        ; CHECK FOR NO LINES IN BETWEEN
  487.     JLE    BLAST2A        ; JUMP AROUND PUTTING THE LINES IN BETWEEN
  488. BLAST2:
  489.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  490.     NOT    AL            ; INVERT IT
  491.     MOV    ES:[DI],AL    ; REPLACE THE INVERTED VALUE
  492.     ADD    DI,[BP+X+4]    ; GO TO THE LAST VALUE TO INVERT ON THAT LINE
  493.     SUB    DI,1        ;
  494.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  495.     NOT    AL        ; INVERT IT
  496.     MOV    ES:[DI],AL    ; REPLACE THE INVERTED VALUE
  497.     ADD    DI,SI        ; GET THE VALUE FOR THE BEGINNING OF THE NEXT LINE
  498.     INC    DI        ;
  499.     LOOP    BLAST2        ; DO THE NEXT LINE
  500.  
  501. BLAST2A:
  502.     MOV    CX,[BP+X+4]    ; PREPARE FOR LAST LINE
  503. BLAST3:
  504.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  505.     NOT    AL            ; INVERT THE VALUE THERE
  506.     MOV    ES:[DI],AL    ; REPLACE THE VALUE
  507.     INC    DI            ; INCREMENT TO NEXT POSITION
  508.     LOOP    BLAST3        ; LOOP UNTIL ALL HAVE BEEN DONE
  509.  
  510.     POP        DI
  511.     POP        SI
  512.     POP    ES
  513.     POP    DS
  514.     POP    BP
  515.     RET
  516. _OUTLINEV    ENDP
  517. ;
  518. ;  Draw a 4x4 ball on the vga screen
  519. ;
  520. ;   usage : ball(x,y)
  521. ;
  522. _BALL        PROC    FAR
  523.     PUSH    BP
  524.     MOV        BP,SP
  525.     PUSH    DS
  526.     PUSH    ES
  527.     PUSH    DI
  528.  
  529.     MOV    AX,[BP+X+2] ; GET THE Y VALUE
  530.     MOV    BX,[BP+X]    ; GET THE X VALUE
  531.     CALL    PIXELADDR13    ; CALCULATE THE PIXEL ADDRESS
  532.     MOV    DI,BX        ; PREPARE FOR MOVS
  533.  
  534.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  535.     NOT    AL            ; INVERT IT
  536.     MOV    ES:[DI],AL    ; REPLACE THE VALUE
  537.     INC    DI            ; MOVE OVER ONE BYTE
  538.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  539.     NOT    AL            ; INVERT IT
  540.     MOV    ES:[DI],AL    ; REPLACE THE VALUE
  541.  
  542.     ADD    DI,318        ; MOVE TO THE NEXT LINE
  543.     MOV    CX,4        ; HOW MANY BYTES?
  544. BLASTB:
  545.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  546.     NOT    AL            ; INVERT THE VALUE THERE
  547.     MOV    ES:[DI],AL    ; REPLACE THE VALUE
  548.     INC    DI            ; INCREMENT TO NEXT POSITION
  549.     LOOP BLASTB        ; LOOP UNTIL ALL HAVE BEEN DONE
  550.  
  551.     MOV    CX,4        ; COUNT VALUE FOR THE NEXT SERIES
  552.     ADD    DI,316        ; MOVE OVER TO THE BEGINNING OF THE NEXT LINE
  553. BLASTC:
  554.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  555.     NOT    AL            ; INVERT IT
  556.     MOV    ES:[DI],AL    ; REPLACE THE INVERTED VALUE
  557.     INC DI            ;
  558.     LOOP    BLASTC    ; DO THE NEXT LINE
  559.  
  560.     ADD    DI,317        ; MOVE ONE BYTE OVER INTO THE NEXT LINE
  561.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  562.     NOT    AL            ; INVERT IT
  563.     MOV    ES:[DI],AL    ; REPLACE THE VALUE
  564.     INC    DI            ; MOVE OVER ONE BYTE
  565.     MOV    AL,ES:[DI]    ; GET THE VALUE TO INVERT
  566.     NOT    AL            ; INVERT IT
  567.     MOV    ES:[DI],AL    ; REPLACE THE VALUE
  568.  
  569.     POP        DI
  570.     POP    ES
  571.     POP    DS
  572.     POP    BP
  573.     RET
  574. _BALL    ENDP
  575.  
  576. ;
  577. ;  Draw a block on the vga screen
  578. ;
  579. ;   usage : vgablock(&block,x,y,xmax,ymax)
  580. ;
  581. X_SIZE    DW    ?        ; X WIDTH OF THE BLOCK
  582. X_WRAP    DW    ?        ; THE NUMBER OF BYTES TO WRAP AROUND THE SCREEN
  583. Y_SIZE    DW    ?        ; THE Y HEIGHT OF THE BLOCK
  584. _VGABLOCK    PROC    FAR
  585.     PUSH    BP
  586.     MOV        BP,SP
  587.     PUSH    DS
  588.     PUSH    ES
  589.     PUSH    SI
  590.     PUSH    DI
  591.  
  592. ;    MOV    AX,0A000H    ; DATA BUFFER
  593. ;    MOV    ES,AX
  594.     
  595.     MOV    AX,[BP+X+8]    ; GET THE X SIZE
  596.     MOV    X_SIZE,AX    ; STORE THE X SIZE
  597.     
  598.     MOV    AX,320        ; GET THE SCREEN SIZE
  599.     SUB    AX,X_SIZE    ; CALCULATE THE X_WRAP VALUE
  600.     MOV    X_WRAP,AX    ; STORE THE X_WRAP VALUE
  601.     
  602.     MOV    AX,[BP+X+10]; GET THE Y SIZE
  603.     MOV    Y_SIZE,AX    ; STORE THE Y SIZE
  604.     MOV    AX,[BP+X+6]    ; GET THE Y VALUE
  605.     MOV    BX,[BP+X+4]    ; GET THE X VALUE
  606.     CALL    PIXELADDR13 ; CALCULATE THE PIXEL OFFSET
  607.     MOV    DI,BX        ; PREPARE FOR MOVS
  608.     
  609.     MOV    AX,[BP+X]    ; GET THE OFFSET OF THE BLOCK
  610.     MOV    SI,AX        ; STORE THE OFFSET OF THE ARRAY
  611.     MOV    AX,[BP+X+2]    ; GET THE SEGMENT OF THE ARRAY
  612.     MOV    DS,AX        ; STORE THE SEGMENT
  613. BLASTBLOCK:
  614.     MOV    CX,X_SIZE    ; GET THE NUMBER OF BYTES TO MOVE
  615.     REP    MOVSB        ; PUT A HORIZONTAL LINE OF THE BLOCK ON THE SCREEN
  616.     
  617.     ADD    DI,X_WRAP    ; MOVE THE DESTINATION POINTER TO THE BEGINNING OF THE NEXT BLOCK
  618.     DEC    Y_SIZE        ; DECREMENT THE VERTICAL COUNTER
  619.     JG    BLASTBLOCK    ; IF THE COUNTER IS NOT ZERO THEN DO ANOTHER LINE
  620.     
  621.     POP        DI
  622.     POP        SI
  623.     POP    ES
  624.     POP    DS
  625.     POP    BP
  626.     RET
  627. _VGABLOCK    ENDP
  628.  
  629. ;
  630. ;   Inverse a block on the vga screen
  631. ;
  632. ;   usage : vgablock(x0,y0,width,height)
  633. ;
  634. _INVERSEV    PROC    FAR
  635.     PUSH    BP
  636.     MOV        BP,SP
  637.     PUSH    DS
  638.     PUSH    ES
  639.     PUSH    DI
  640.  
  641.     MOV    BX,[BP+X+4]    ; GET THE X SIZE
  642.     MOV    X_SIZE,BX    ; STORE THE X SIZE
  643.     
  644.     MOV    AX,320        ; GET THE SCREEN SIZE
  645.     SUB    AX,BX        ; CALCULATE THE X_WRAP VALUE
  646.     MOV    X_WRAP,AX    ; STORE THE X_WRAP VALUE
  647.     
  648.     MOV    AX,[BP+X+6]    ; GET THE Y SIZE
  649.     MOV    Y_SIZE,AX    ; STORE THE Y SIZE
  650. ;
  651.     MOV    AX,[BP+X+2]; GET THE Y VALUE
  652.     MOV    BX,[BP+X]    ; GET THE X VALUE
  653.     CALL    PIXELADDR13        ; CALCULATE THE PIXEL ADDRESS (RETURNS WITH ES:VIDEO BUFF SEG, BX:OFFSET)
  654.     MOV    DI,BX        ; PREPARE FOR MOVS
  655.     
  656. INVERSEBLOCK:
  657.     MOV    CX,X_SIZE    ; GET THE NUMBER OF BYTES TO MOVE
  658. INVERSELINE:
  659.     MOV    AL,BYTE PTR ES:[DI]    ; GET THE BYTE TO INVERSE
  660.     NOT    AL            ; INVERSE IT
  661.     MOV    BYTE PTR ES:[DI],AL    ; PUT THE BYTE BACK
  662.     INC    DI
  663.     LOOP INVERSELINE
  664.     
  665.     ADD    DI,X_WRAP    ; MOVE THE DESTINATION POINTER TO THE BEGINNING OF THE NEXT BLOCK
  666.     DEC    Y_SIZE        ; DECREMENT THE VERTICAL COUNTER
  667.     JG    INVERSEBLOCK    ; IF THE COUNTER IS NOT ZERO THEN DO ANOTHER LINE
  668.     
  669.     POP        DI
  670.     POP    ES
  671.     POP    DS
  672.     POP    BP
  673.     RET
  674. _INVERSEV    ENDP
  675.  
  676. ;    CALLER         MICROSOFT C
  677. ;
  678. ;                    VOID(_LINE13(X1,Y1,X2,Y2,N);
  679. ;
  680. ;                        INT X1,Y1,X2,Y2;    /* PIXEL COOR. */
  681. ;
  682. ;                        INT N;            /* PIXEL VALUE */
  683. ;
  684.  
  685. ARGX1        EQU    WORD PTR [BP+6]    ; STACK FRAME ADDRESSING
  686. ARGY1        EQU    WORD PTR [BP+8]
  687. ARGX2        EQU    WORD PTR [BP+10]
  688. ARGY2        EQU WORD PTR [BP+12]
  689. ARGN        EQU    BYTE PTR [BP+14]
  690. VARINCR1    EQU    WORD PTR [BP-6]
  691. VARINCR2    EQU WORD PTR [BP-8]
  692. VARROUTINE    EQU WORD PTR [BP-10]
  693.  
  694. BYTESPERLINE    EQU    320
  695.  
  696. _LINE13    PROC    FAR
  697.     PUSH    BP
  698.     MOV        BP,SP
  699.     SUB        SP,16H
  700.     PUSH    DS
  701.     PUSH    ES
  702.     PUSH    SI
  703.     PUSH    DI
  704.  
  705. ; CHECK FOR VERTICAL LINE
  706.     MOV        SI,BYTESPERLINE
  707.  
  708.     MOV        CX,ARGX2
  709.     SUB        CX,ARGX1
  710.     JZ        VERT_LINE13
  711.  
  712. ; FORCE X1<X2
  713.     JNS        L01
  714.  
  715.     NEG     CX
  716.  
  717.     MOV        BX,ARGX2
  718.     XCHG    BX,ARGX1
  719.     MOV        ARGX2,BX
  720.  
  721.     MOV        BX,ARGY2
  722.     XCHG    BX,ARGY1
  723.     MOV        ARGY2,BX
  724.  
  725. ; CALCULATE DY=ABS(Y2-Y1)
  726. L01:
  727.     MOV        BX,ARGY2
  728.     SUB        BX,ARGY1
  729.     JZ        HORIZ_LINE13
  730.  
  731.     JNS        L03
  732.  
  733.     NEG        BX
  734.     NEG        SI
  735. ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
  736. L03:
  737.     PUSH    SI
  738.     MOV        VARROUTINE,OFFSET LOSLOPE_LINE13
  739.     CMP        BX,CX
  740.     JLE        L04
  741.     MOV        VARROUTINE,OFFSET HISLOPE_LINE13
  742.     XCHG    BX,CX
  743.  
  744. ;CALCULATE INITIAL DECISION VARIABLE AND INCREMENTS
  745. L04:
  746.     SHL        BX,1
  747.     MOV        VARINCR1,BX
  748.     SUB        BX,CX
  749.     MOV        SI,BX
  750.  
  751.     SUB        BX,CX
  752.     MOV        VARINCR2,BX
  753.  
  754. ;CALCULATE FIRST PIXEL ADDRESS
  755.     PUSH    CX
  756.     MOV        AX,ARGY1
  757.     MOV        BX,ARGX1
  758.     CALL    PIXELADDR13
  759.  
  760.     MOV        DI,BX
  761.  
  762.     POP        CX
  763.     INC        CX
  764.  
  765.     POP        BX
  766.     JMP        VARROUTINE
  767.  
  768. ;ROUTINE FOR VERTICAL LINES
  769. VERT_LINE13:
  770.     MOV        AX,ARGY1
  771.     MOV        BX,ARGY2
  772.     MOV        CX,BX
  773.     SUB        CX,AX
  774.     JGE        L31
  775.  
  776.     NEG        CX
  777.     MOV        AX,BX
  778. L31:
  779.     INC        CX
  780.     MOV        BX,ARGX1
  781.     PUSH    CX
  782.     CALL    PIXELADDR13
  783.     POP        CX
  784.     MOV        DI,BX
  785.     DEC        SI
  786.  
  787.     MOV        AL,ARGN
  788. L32:
  789.     STOSB
  790.     ADD        DI,SI
  791.     LOOP    L32
  792.     JMP        LEXIT
  793.  
  794. ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
  795. HORIZ_LINE13:
  796.     PUSH    CX
  797.     MOV        AX,ARGY1
  798.     MOV        BX,ARGX1
  799.     CALL    PIXELADDR13
  800.     MOV        DI,BX
  801.  
  802.     POP        CX
  803.     INC        CX
  804.  
  805.     MOV        AL,ARGN
  806.  
  807.     REP        STOSB
  808.     JMP        LEXIT
  809.  
  810. ;ROUTINE FOR DY<=DX (SLOPE<=1)
  811. LOSLOPE_LINE13:
  812.     MOV        AL,ARGN
  813. L11:
  814.     STOSB
  815.     OR        SI,SI
  816.     JNS        L12
  817.     ADD        SI,VARINCR1
  818.     LOOP    L11
  819.     JMP        SHORT    LEXIT
  820. L12:
  821.     ADD        SI,VARINCR2
  822.     ADD        DI,BX
  823.     LOOP    L11
  824.     JMP        SHORT LEXIT
  825.  
  826. ;ROUTINE FOR DY>DX (SLOPE>1)
  827. HISLOPE_LINE13:
  828.     MOV        AL,ARGN
  829. L21:
  830.     STOSB
  831.     ADD        DI,BX
  832. L22:
  833.     OR        SI,SI
  834.     JNS        L23
  835.     ADD        SI,VARINCR1
  836.     DEC        DI
  837.     LOOP    L21
  838.     JMP        SHORT    LEXIT
  839. L23:
  840.     ADD        SI,VARINCR2
  841.     LOOP    L21
  842.  
  843. LEXIT:
  844.     POP        DI
  845.     POP        SI
  846.     POP        ES
  847.     POP        DS
  848.     MOV        SP,BP
  849.     POP        BP
  850.     RET
  851. _LINE13        ENDP
  852.  
  853. _INVERT13    PROC    FAR
  854.     PUSH    BP
  855.     MOV        BP,SP
  856.     SUB        SP,16H
  857.     PUSH    DS
  858.     PUSH    ES
  859.     PUSH    SI
  860.     PUSH    DI
  861.  
  862. ; CHECK FOR VERTICAL LINE
  863.     MOV        SI,BYTESPERLINE
  864.  
  865.     MOV        CX,ARGX2
  866.     SUB        CX,ARGX1
  867.     JZ        IVERT_LINE13
  868.  
  869. ; FORCE X1<X2
  870.     JNS        IL01
  871.  
  872.     NEG     CX
  873.  
  874.     MOV        BX,ARGX2
  875.     XCHG    BX,ARGX1
  876.     MOV        ARGX2,BX
  877.  
  878.     MOV        BX,ARGY2
  879.     XCHG    BX,ARGY1
  880.     MOV        ARGY2,BX
  881.  
  882. ; CALCULATE DY=ABS(Y2-Y1)
  883. IL01:
  884.     MOV        BX,ARGY2
  885.     SUB        BX,ARGY1
  886.     JZ        IHORIZ_LINE13
  887.  
  888.     JNS        IL03
  889.  
  890.     NEG        BX
  891.     NEG        SI
  892. ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
  893. IL03:
  894.     PUSH    SI
  895.     MOV        VARROUTINE,OFFSET ILOSLOPE_LINE13
  896.     CMP        BX,CX
  897.     JLE        IL04
  898.     MOV        VARROUTINE,OFFSET IHISLOPE_LINE13
  899.     XCHG    BX,CX
  900.  
  901. ;CALCULATE INITIAL DECISION VARIABLE AND INCREMENTS
  902. IL04:
  903.     SHL        BX,1
  904.     MOV        VARINCR1,BX
  905.     SUB        BX,CX
  906.     MOV        SI,BX
  907.  
  908.     SUB        BX,CX
  909.     MOV        VARINCR2,BX
  910.  
  911. ;CALCULATE FIRST PIXEL ADDRESS
  912.     PUSH    CX
  913.     MOV        AX,ARGY1
  914.     MOV        BX,ARGX1
  915.     CALL    PIXELADDR13
  916.  
  917.     MOV        DI,BX
  918.  
  919.     POP        CX
  920.     INC        CX
  921.  
  922.     POP        BX
  923.     JMP        VARROUTINE
  924.  
  925. ;ROUTINE FOR VERTICAL LINES
  926. IVERT_LINE13:
  927.     MOV        AX,ARGY1
  928.     MOV        BX,ARGY2
  929.     MOV        CX,BX
  930.     SUB        CX,AX
  931.     JGE        IL31
  932.  
  933.     NEG        CX
  934.     MOV        AX,BX
  935. IL31:
  936.     INC        CX
  937.     MOV        BX,ARGX1
  938.     PUSH    CX
  939.     CALL    PIXELADDR13
  940.     POP        CX
  941.     MOV        DI,BX
  942.     DEC        SI
  943.  
  944.     MOV        AL,0FFH
  945. IL32:
  946.     XOR        ES:[DI],AL
  947.     INC        DI
  948. ;    STOSB
  949.     ADD        DI,SI
  950.     LOOP    IL32
  951.     JMP        ILEXIT
  952.  
  953. ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
  954. IHORIZ_LINE13:
  955.     PUSH    CX
  956.     MOV        AX,ARGY1
  957.     MOV        BX,ARGX1
  958.     CALL    PIXELADDR13
  959.     MOV        DI,BX
  960.  
  961.     POP        CX
  962.     INC        CX
  963.     MOV        AL,0ffh
  964.  
  965. IL51:
  966.     XOR        ES:[DI],AL
  967.     INC        DI
  968.     LOOP    IL51
  969. ;REP    STOSB
  970.     JMP        ILEXIT
  971.  
  972. ;ROUTINE FOR DY<=DX (SLOPE<=1)
  973. ILOSLOPE_LINE13:
  974.     MOV        AL,0ffh
  975. IL11:
  976.     XOR        ES:[DI],AL
  977.     INC        DI
  978. ;    STOSB
  979.     OR        SI,SI
  980.     JNS        IL12
  981.     ADD        SI,VARINCR1
  982.     LOOP    IL11
  983.     JMP        SHORT    ILEXIT
  984. IL12:
  985.     ADD        SI,VARINCR2
  986.     ADD        DI,BX
  987.     LOOP    IL11
  988.     JMP        SHORT ILEXIT
  989.  
  990. ;ROUTINE FOR DY>DX (SLOPE>1)
  991. IHISLOPE_LINE13:
  992.     MOV        AL,0ffh
  993. IL21:
  994.     XOR        ES:[DI],AL
  995.     INC        DI
  996. ;    STOSB
  997.     ADD        DI,BX
  998. IL22:
  999.     OR        SI,SI
  1000.     JNS        IL23
  1001.     ADD        SI,VARINCR1
  1002.     DEC        DI
  1003.     LOOP    IL21
  1004.     JMP        SHORT    ILEXIT
  1005. IL23:
  1006.     ADD        SI,VARINCR2
  1007.     LOOP    IL21
  1008.  
  1009. ILEXIT:
  1010.     POP        DI
  1011.     POP        SI
  1012.     POP        ES
  1013.     POP        DS
  1014.     MOV        SP,BP
  1015.     POP        BP
  1016.     RET
  1017. _INVERT13        ENDP
  1018.  
  1019. ;NAME:    _CIRCLE13
  1020. ;    _CIRCLE13(XC,YC,A,B,N)
  1021. ;
  1022. ARGXC    EQU WORD PTR [BP+6]
  1023. ARGYC    EQU WORD PTR [BP+8]
  1024. ARGA    EQU WORD PTR [BP+10]
  1025. ARGB    EQU WORD PTR [BP+12]
  1026. ARGN    EQU    BYTE PTR [BP+14]
  1027.  
  1028. ULADDR    EQU WORD PTR [BP-6]
  1029. URADDR    EQU WORD PTR [BP-8]
  1030. LLADDR    EQU WORD PTR [BP-10]
  1031. LRADDR    EQU WORD PTR [BP-12]
  1032. LMASK    EQU BYTE PTR [BP-14]
  1033. RMASK    EQU BYTE PTR [BP-16]
  1034.  
  1035. VARD        EQU WORD PTR [BP-20]
  1036. VARDX        EQU WORD PTR [BP-24]
  1037. VARDY        EQU WORD PTR [BP-28]
  1038. ASQUARED    EQU WORD PTR [BP-32]
  1039. BSQUARED    EQU WORD PTR [BP-36]
  1040. TWOASQUARED    EQU WORD PTR [BP-40]
  1041. TWOBSQUARED    EQU WORD PTR [BP-44]
  1042.  
  1043. BYTESPERLINE EQU    320
  1044.  
  1045. _CIRCLE13    PROC    FAR
  1046.     PUSH    BP
  1047.     MOV    BP,SP
  1048.     SUB    SP,50
  1049.     PUSH    DS
  1050.     PUSH    ES
  1051.     PUSH    SI
  1052.     PUSH    DI
  1053.  
  1054. ;INITIAL CONSTANTS
  1055.     MOV AX,ARGA
  1056.     MUL    AX
  1057.     MOV ASQUARED,AX
  1058.     MOV    ASQUARED+2,DX
  1059.     SHL    AX,1
  1060.     RCL    DX,1
  1061.     MOV    TWOASQUARED,AX
  1062.     MOV    TWOASQUARED+2,DX
  1063.     MOV    AX,ARGB
  1064.     MUL    AX
  1065.     MOV BSQUARED,AX
  1066.     MOV BSQUARED+2,DX
  1067.     SHL    AX,1
  1068.     RCL DX,1
  1069.     MOV TWOBSQUARED,AX
  1070.     MOV TWOBSQUARED+2,DX
  1071.  
  1072. ;PLOT PIXELS FROM (0,B) UNTIL DY/DX =-1
  1073. ;INITIAL BUFFER ADDRESS AND BIT MASK
  1074.     MOV    AX,BYTESPERLINE
  1075.     MUL    ARGB
  1076.     MOV    SI,AX
  1077.     MOV    DI,AX
  1078.     MOV    AX,ARGYC
  1079.     MOV    BX,ARGXC
  1080.     CALL    PIXELADDR13
  1081.  
  1082.     ADD    SI,BX
  1083.     MOV    ULADDR,SI
  1084.     MOV URADDR,SI
  1085.     SUB    BX,DI
  1086.     MOV    LLADDR,BX
  1087.     MOV    LRADDR,BX
  1088.  
  1089. ;INITIAL DECISION VARIABLES
  1090.     XOR    AX,AX
  1091.     MOV    VARDX,AX
  1092.     MOV    VARDX+2,AX
  1093.  
  1094.     MOV    AX,TWOASQUARED
  1095.     MOV DX,TWOASQUARED+2
  1096.     MOV CX,ARGB
  1097.     CALL LONGMULTIPLY
  1098.     MOV VARDY,AX
  1099.     MOV VARDY+2,DX
  1100.  
  1101.     MOV AX,ASQUARED
  1102.     MOV    DX,ASQUARED+2
  1103.     SAR DX,1
  1104.     RCR    AX,1
  1105.     SAR    DX,1
  1106.     RCR AX,1
  1107.  
  1108.     ADD AX,BSQUARED
  1109.     ADC    DX,BSQUARED+2
  1110.     MOV    VARD,AX
  1111.     MOV VARD+2,DX
  1112.  
  1113.     MOV    AX,ASQUARED
  1114.     MOV    DX,ASQUARED+2
  1115.     MOV CX,ARGB
  1116.     CALL LONGMULTIPLY
  1117.     SUB    VARD,AX
  1118.     SBB    VARD+2,DX
  1119.     
  1120.     ;LOOP UNTIL DY/DX>=-1
  1121.     MOV    BX,ARGB
  1122.     XOR    CX,CX
  1123.     
  1124. C10:    
  1125.     MOV    AX,VARDX
  1126.     MOV    DX,VARDX+2
  1127.     SUB    AX,VARDY
  1128.     SBB    DX,VARDY+2
  1129.     JNS    C20
  1130.     
  1131.     CALL    SET4PIXELS
  1132.     MOV CX,1
  1133.     CMP    VARD+2,0
  1134.     JS    C11
  1135.     MOV    CH,1
  1136.     DEC    BX
  1137.     
  1138.     MOV AX,VARDY
  1139.     MOV    DX,VARDY+2
  1140.     SUB AX,TWOASQUARED
  1141.     SBB    DX,TWOASQUARED+2
  1142.     MOV VARDY,AX
  1143.     MOV    VARDY+2,DX
  1144.  
  1145.     SUB    VARD,AX
  1146.     SBB    VARD+2,DX
  1147.     
  1148. C11:
  1149.     MOV AX,VARDX
  1150.     MOV DX,VARDX+2
  1151.     ADD    AX,TWOBSQUARED
  1152.     ADC    DX,TWOBSQUARED+2
  1153.     MOV VARDX,AX
  1154.     MOV VARDX+2,DX
  1155.     ADD    AX,BSQUARED
  1156.     ADC    DX,BSQUARED+2
  1157.     ADD VARD,AX
  1158.     ADC    VARD+2,DX
  1159.     JMP    C10
  1160.     
  1161. ;PLOT PIXELS FROM CURRENT (X,Y) UNTIL Y<0
  1162.     
  1163. C20:
  1164.     PUSH    BX
  1165.     PUSH    CX
  1166.     MOV    AX,ASQUARED
  1167.     MOV    DX,ASQUARED+2
  1168.     SUB    AX,BSQUARED
  1169.     SBB    DX,BSQUARED+2
  1170.     MOV BX,AX
  1171.     MOV CX,DX
  1172.     
  1173.     SAR DX,1
  1174.     RCR    AX,1
  1175.     ADD AX,BX
  1176.     ADC    DX,CX
  1177.     
  1178.     SUB AX,VARDX
  1179.     SBB    DX,VARDX+2
  1180.     SUB    AX,VARDY
  1181.     SBB    DX,VARDY+2
  1182.     
  1183.     SAR    DX,1
  1184.     RCR    AX,1
  1185.     
  1186.     ADD    VARD,AX
  1187.     ADC    VARD+2,DX
  1188.     
  1189. ;LOOP UNTIL Y<0
  1190.     POP CX
  1191.     POP BX
  1192. C21:
  1193.     CALL SET4PIXELS
  1194.     MOV CX,100H
  1195.     
  1196.     CMP    VARD+2,0
  1197.     JNS    C22
  1198.     
  1199.     MOV CL,1
  1200.     MOV AX,VARDX
  1201.     MOV DX,VARDX+2
  1202.     ADD AX,TWOBSQUARED
  1203.     ADC    DX,TWOBSQUARED+2
  1204.     MOV    VARDX,AX
  1205.     MOV    VARDX+2,DX
  1206.     
  1207.     ADD    VARD,AX
  1208.     ADC    VARD+2,DX
  1209.     
  1210. C22:    
  1211.     MOV AX,VARDY
  1212.     MOV    DX,VARDY+2
  1213.     SUB    AX,TWOASQUARED
  1214.     SBB    DX,TWOASQUARED+2
  1215.     MOV    VARDY,AX
  1216.     MOV    VARDY+2,DX
  1217.  
  1218.     SUB    AX,ASQUARED
  1219.     SBB    DX,ASQUARED+2
  1220.     SUB    VARD,AX
  1221.     SBB    VARD+2,DX
  1222.     
  1223.     DEC    BX
  1224.     JNS    C21
  1225.     
  1226. ;RESTORE DEFAULT GRAPHICS CONTROLLER REGISTERS
  1227. CEXIT:
  1228.     POP DI
  1229.     POP SI
  1230.     POP    ES
  1231.     POP    DS
  1232.     MOV SP,BP
  1233.     POP    BP
  1234.     RET
  1235. _CIRCLE13    ENDP
  1236.  
  1237. ;NAME:    CIRCLE13
  1238. ;    CIRCLE13(XC,YC,A,B,N)
  1239. ;
  1240. ARGXC    EQU WORD PTR [BP+6]
  1241. ARGYC    EQU WORD PTR [BP+8]
  1242. ARGA    EQU WORD PTR [BP+10]
  1243. ARGB    EQU WORD PTR [BP+12]
  1244.  
  1245. ULADDR    EQU WORD PTR [BP-6]
  1246. URADDR    EQU WORD PTR [BP-8]
  1247. LLADDR    EQU WORD PTR [BP-10]
  1248. LRADDR    EQU WORD PTR [BP-12]
  1249. LMASK    EQU BYTE PTR [BP-14]
  1250. RMASK    EQU BYTE PTR [BP-16]
  1251.  
  1252.  
  1253. VARD        EQU WORD PTR [BP-20]
  1254. VARDX        EQU WORD PTR [BP-24]
  1255. VARDY        EQU WORD PTR [BP-28]
  1256. ASQUARED    EQU WORD PTR [BP-32]
  1257. BSQUARED    EQU WORD PTR [BP-36]
  1258. TWOASQUARED    EQU WORD PTR [BP-40]
  1259. TWOBSQUARED    EQU WORD PTR [BP-44]
  1260.  
  1261. RMWBITS        EQU    00H
  1262. BYTESPERLINE EQU    320
  1263.  
  1264. _INCIRC13    PROC    FAR
  1265.     PUSH    BP
  1266.     MOV    BP,SP
  1267.     SUB    SP,50
  1268.     PUSH    DS
  1269.     PUSH    ES
  1270.     PUSH    SI
  1271.     PUSH    DI
  1272.  
  1273.  
  1274. ;INITIAL CONSTANTS
  1275.     MOV AX,ARGA
  1276.     MUL    AX
  1277.     MOV ASQUARED,AX
  1278.     MOV    ASQUARED+2,DX
  1279.     SHL    AX,1
  1280.     RCL    DX,1
  1281.     MOV    TWOASQUARED,AX
  1282.     MOV    TWOASQUARED+2,DX
  1283.     MOV    AX,ARGB
  1284.     MUL    AX
  1285.     MOV BSQUARED,AX
  1286.     MOV BSQUARED+2,DX
  1287.     SHL    AX,1
  1288.     RCL DX,1
  1289.     MOV TWOBSQUARED,AX
  1290.     MOV TWOBSQUARED+2,DX
  1291.  
  1292. ;PLOT PIXELS FROM (0,B) UNTIL DY/DX =-1
  1293. ;INITIAL BUFFER ADDRESS AND BIT MASK
  1294.     MOV    AX,BYTESPERLINE
  1295.     MUL    ARGB
  1296.     MOV    SI,AX
  1297.     MOV    DI,AX
  1298.     MOV    AX,ARGYC
  1299.     MOV    BX,ARGXC
  1300.     CALL    PIXELADDR13
  1301.  
  1302.     ADD    SI,BX
  1303.     MOV    ULADDR,SI
  1304.     MOV URADDR,SI
  1305.     SUB    BX,DI
  1306.     MOV    LLADDR,BX
  1307.     MOV    LRADDR,BX
  1308.  
  1309. ;INITIAL DECISION VARIABLES
  1310.     XOR    AX,AX
  1311.     MOV    VARDX,AX
  1312.     MOV    VARDX+2,AX
  1313.  
  1314.     MOV    AX,TWOASQUARED
  1315.     MOV DX,TWOASQUARED+2
  1316.     MOV CX,ARGB
  1317.     CALL LONGMULTIPLY
  1318.     MOV VARDY,AX
  1319.     MOV VARDY+2,DX
  1320.  
  1321.     MOV AX,ASQUARED
  1322.     MOV    DX,ASQUARED+2
  1323.     SAR DX,1
  1324.     RCR    AX,1
  1325.     SAR    DX,1
  1326.     RCR AX,1
  1327.  
  1328.     ADD AX,BSQUARED
  1329.     ADC    DX,BSQUARED+2
  1330.     MOV    VARD,AX
  1331.     MOV VARD+2,DX
  1332.  
  1333.     MOV    AX,ASQUARED
  1334.     MOV    DX,ASQUARED+2
  1335.     MOV CX,ARGB
  1336.     CALL LONGMULTIPLY
  1337.     SUB    VARD,AX
  1338.     SBB    VARD+2,DX
  1339.     
  1340.     ;LOOP UNTIL DY/DX>=-1
  1341.     MOV    BX,ARGB
  1342.     XOR    CX,CX
  1343.     
  1344. IC10:    
  1345.     MOV    AX,VARDX
  1346.     MOV    DX,VARDX+2
  1347.     SUB    AX,VARDY
  1348.     SBB    DX,VARDY+2
  1349.     JNS    IC20
  1350.     
  1351.     CALL    INVERT4PIXELS
  1352.     MOV CX,1
  1353.     CMP    VARD+2,0
  1354.     JS    IC11
  1355.     MOV    CH,1
  1356.     DEC    BX
  1357.     
  1358.     MOV AX,VARDY
  1359.     MOV    DX,VARDY+2
  1360.     SUB AX,TWOASQUARED
  1361.     SBB    DX,TWOASQUARED+2
  1362.     MOV VARDY,AX
  1363.     MOV    VARDY+2,DX
  1364.  
  1365.     SUB    VARD,AX
  1366.     SBB    VARD+2,DX
  1367.     
  1368. IC11:
  1369.     MOV AX,VARDX
  1370.     MOV DX,VARDX+2
  1371.     ADD    AX,TWOBSQUARED
  1372.     ADC    DX,TWOBSQUARED+2
  1373.     MOV VARDX,AX
  1374.     MOV VARDX+2,DX
  1375.     ADD    AX,BSQUARED
  1376.     ADC    DX,BSQUARED+2
  1377.     ADD VARD,AX
  1378.     ADC    VARD+2,DX
  1379.     JMP    IC10
  1380.     
  1381. ;PLOT PIXELS FROM CURRENT (X,Y) UNTIL Y<0
  1382.     
  1383. IC20:
  1384.     PUSH    BX
  1385.     PUSH    CX
  1386.     MOV    AX,ASQUARED
  1387.     MOV    DX,ASQUARED+2
  1388.     SUB    AX,BSQUARED
  1389.     SBB    DX,BSQUARED+2
  1390.     MOV BX,AX
  1391.     MOV CX,DX
  1392.     
  1393.     SAR DX,1
  1394.     RCR    AX,1
  1395.     ADD AX,BX
  1396.     ADC    DX,CX
  1397.     
  1398.     SUB AX,VARDX
  1399.     SBB    DX,VARDX+2
  1400.     SUB    AX,VARDY
  1401.     SBB    DX,VARDY+2
  1402.     
  1403.     SAR    DX,1
  1404.     RCR    AX,1
  1405.     
  1406.     ADD    VARD,AX
  1407.     ADC    VARD+2,DX
  1408.     
  1409. ;LOOP UNTIL Y<0
  1410.     POP CX
  1411.     POP BX
  1412. IC21:
  1413.     CALL INVERT4PIXELS
  1414.     MOV CX,100H
  1415.     
  1416.     CMP    VARD+2,0
  1417.     JNS    IC22
  1418.     
  1419.     MOV CL,1
  1420.     MOV AX,VARDX
  1421.     MOV DX,VARDX+2
  1422.     ADD AX,TWOBSQUARED
  1423.     ADC    DX,TWOBSQUARED+2
  1424.     MOV    VARDX,AX
  1425.     MOV    VARDX+2,DX
  1426.     
  1427.     ADD    VARD,AX
  1428.     ADC    VARD+2,DX
  1429.     
  1430. IC22:    
  1431.     MOV AX,VARDY
  1432.     MOV    DX,VARDY+2
  1433.     SUB    AX,TWOASQUARED
  1434.     SBB    DX,TWOASQUARED+2
  1435.     MOV    VARDY,AX
  1436.     MOV    VARDY+2,DX
  1437.  
  1438.     SUB    AX,ASQUARED
  1439.     SBB    DX,ASQUARED+2
  1440.     SUB    VARD,AX
  1441.     SBB    VARD+2,DX
  1442.     
  1443.     DEC    BX
  1444.     JNS    IC21
  1445.     
  1446. ;RESTORE DEFAULT GRAPHICS CONTROLLER REGISTERS
  1447. ICEXIT:
  1448.     POP DI
  1449.     POP SI
  1450.     POP    ES
  1451.     POP    DS
  1452.     MOV SP,BP
  1453.     POP    BP
  1454.     RET
  1455.  
  1456. _INCIRC13    ENDP
  1457.  
  1458. SET4PIXELS    PROC    NEAR
  1459.     PUSH    AX
  1460.     PUSH    BX
  1461.     PUSH    DX
  1462.     MOV        AL,ARGN        ; GET THE COLOR VALUE
  1463.     XOR    BX,BX
  1464.     TEST    CH,CH
  1465.     JZ    C30
  1466.     MOV    BX,BYTESPERLINE
  1467.     NEG    BX
  1468. C30:
  1469.     
  1470. ;PIXELS AT (XC-X,YC+Y) AND XC-X,YC-Y)
  1471.  
  1472.     XOR    SI,SI
  1473.     TEST    CL,CL
  1474.     JZ    C31
  1475.     MOV    SI,-1
  1476. C31:
  1477.  
  1478.     MOV DI,SI
  1479.     ADD    SI,ULADDR
  1480.     ADD    SI,BX
  1481.     ADD    DI,LLADDR
  1482.     SUB    DI,BX
  1483.     MOV    ULADDR,SI
  1484.     MOV    LLADDR,DI
  1485.     MOV    ES:[SI],AL
  1486.     MOV    ES:[DI],AL
  1487.     
  1488. ;PIXELS AT (XC+X,YC+Y) AND (XC+X,YC+Y)
  1489.  
  1490.     XOR    SI,SI
  1491.     TEST    CL,CL
  1492.     JZ    C32
  1493.     MOV    SI,1
  1494. C32:
  1495.     MOV    DI,SI
  1496.     
  1497.     ADD    SI,URADDR
  1498.     ADD SI,BX
  1499.     ADD    DI,LRADDR
  1500.     SUB    DI,BX
  1501.     
  1502.     MOV    URADDR,SI
  1503.     MOV    LRADDR,DI
  1504.     
  1505.     MOV    ES:[SI],AL
  1506.     MOV ES:[DI],AL
  1507.     
  1508.     POP    DX
  1509.     POP BX
  1510.     POP AX
  1511.     RET
  1512.  
  1513. SET4PIXELS    ENDP
  1514.  
  1515. INVERT4PIXELS    PROC    NEAR
  1516.     PUSH    AX
  1517.     PUSH    BX
  1518.     PUSH    DX
  1519.     XOR    BX,BX
  1520.     TEST    CH,CH
  1521.     JZ    IC30
  1522.     MOV    BX,BYTESPERLINE
  1523.     NEG    BX
  1524. IC30:
  1525.     
  1526. ;PIXELS AT (XC-X,YC+Y) AND XC-X,YC-Y)
  1527.  
  1528.     XOR    SI,SI
  1529.     TEST    CL,CL
  1530.     JZ    IC31
  1531.     MOV    SI,-1
  1532. IC31:
  1533.  
  1534.     MOV DI,SI
  1535.     ADD    SI,ULADDR
  1536.     ADD    SI,BX
  1537.     ADD    DI,LLADDR
  1538.     SUB    DI,BX
  1539.     MOV    ULADDR,SI
  1540.     MOV    LLADDR,DI
  1541.     MOV    AL,ES:[SI]
  1542.     XOR AL,0FFH
  1543.     MOV    ES:[SI],AL
  1544.     MOV    AL,ES:[DI]
  1545.     XOR AL,0FFH
  1546.     MOV    ES:[DI],AL
  1547.     
  1548. ;PIXELS AT (XC+X,YC+Y) AND (XC+X,YC+Y)
  1549.  
  1550.     XOR    SI,SI
  1551.     TEST    CL,CL
  1552.     JZ    IC32
  1553.     MOV    SI,1
  1554. IC32:
  1555.     MOV    DI,SI
  1556.     
  1557.     ADD    SI,URADDR
  1558.     ADD SI,BX
  1559.     ADD    DI,LRADDR
  1560.     SUB    DI,BX
  1561.     
  1562.     MOV    URADDR,SI
  1563.     MOV    LRADDR,DI
  1564.     
  1565.     MOV    AL,ES:[SI]
  1566.     XOR AL,0FFH
  1567.     MOV    ES:[SI],AL
  1568.     MOV    AL,ES:[DI]
  1569.     XOR AL,0FFH
  1570.     MOV    ES:[DI],AL
  1571.     
  1572.     POP    DX
  1573.     POP BX
  1574.     POP AX
  1575.     RET
  1576.  
  1577. INVERT4PIXELS    ENDP
  1578.  
  1579. LONGMULTIPLY    PROC    NEAR
  1580.  
  1581.     PUSH    AX
  1582.     MOV    AX,DX
  1583.     MUL    CX
  1584.     XCHG    AX,CX
  1585.     POP DX
  1586.     MUL DX
  1587.     ADD    DX,CX
  1588.     RET
  1589.  
  1590. LONGMULTIPLY    ENDP
  1591.  
  1592. ;    ENDPS
  1593.     END
  1594.