home *** CD-ROM | disk | FTP | other *** search
- ;
- ; EGA GRAPHICS DRIVER
- ;
- ; supports raster graphics on the Enhanced Adapter
- ;
- ; Tim Krauskopf Spring 1986
- ; Modified by
- ; Quincey Koziol January 1989
- ;
- ; National Center for Supercomputing Applications
- ; 605 E. Springfield
- ; Champaign, IL 61820
- ; (217) 244-0074
- ;
- ;
- TITLE EGA GRAPHICS RASTER DRIVER
- NAME EGA
- INCLUDE DOS.MAC
- SETX
- ;
- ; Define where the registers are
- ;
- SEQ EQU 03C4H
- MAPREG EQU 2
- MAPMASK EQU 03C5H
- GCHIP EQU 03CEH
- DRREG EQU 3
- MODEREG EQU 5
- BITREG EQU 8
- BITMASK EQU 03CFH
- ;
- DSEG
- FLAG DB 0 ; HAVE WE SET REGS UP
-
- MAP_LEFT DB ? ; BIT MAP FOR LEFT EDGE OF MIDDLE LINES
- MAP_RIGHT DB ? ; BIT MAP FOR RIGHT EDGE OF MIDDLE LINES
- MAP_TOPL DB ? ; BIT MAP FOR TOP & BOTTOM LINES LEFT EDGE
- MAP_TOPR DB ? ; BIT MAP FOR TOP & BOTTOM LINES RIGHT EDGE
- RIGHT_EDGE DW ? ; BYTE OFFSET OF LEFT EDGE
- LEFT_EDGE DW ? ; BYTE OFFSET OF RIGHT EDGE
- X_WIDTH DW ? ; WIDTH OF TOP & BOTTOM LINES IN BYTES
- Y_HEIGHT DW ? ; HEIGHT OF THE ENTIRE OUTLINE
- RIGHT_BIT DW ? ; BIT OFFSET OF RIGHT EDGE
- TOP1_BYTE DW ? ; BYTE OFFSET OF TOP LINE +1
- BOTTOM_BYTE DW ? ; BYTE OFFSET OF BOTTOM LINE
- TOP_BYTE DW ? ; BYTE OFFSET OF TOP LINE
- X_OFF DW ? ; HORIZONTAL OFFSET INTO THE BLOCK BEING PROCESSED
- Y_OFF DW ? ; OFFSET INTO THE BLOCK BEING PROCESSED
- X_TEMP DW ? ; TEMPORARY X VALUE
- BLKOFF DW ? ; THE OFFSET OF A BLOCK PASSED TO EGABLOCK
- BLKSEG DW ? ; THE SEGMENT OF A BLOCK PASSED TO EGABLOCK
- ENDDS
-
- PSEG
- PUBLIC _EGAPT,_EGALINE,_EGALINE2,_EGALINEA
- PUBLIC _INITEGA,_RESETEGA,_EGAPAL,_PUTMAPE;,_OUTLINEE
- PUBLIC _INVERSEE,_EGABLOCK,_SETTRANS
- PUBLIC _INVERT10,_LINE10,_CIRCLE10,_INCIRC10
-
- ;
- ;NAME: PIXELADDR10
- ;
- ;CALLER: AX = Y-COORDINATE
- ; BX = X-COORDINATE
- ;
- ;RETURNS: AH = BITMASK
- ; BX = BYTE OFFSET IN BUFFER
- ; CL = NUMBER OF BITS TO SHIFT LEFT
- ; ES = VIDEO BUFFER SEGMENT
- ;
- ;
- ;
- BYTESPERLINE EQU 80
- ORIGINOFFSET EQU 0
- VIDEOBUFFERSEG EQU 0A000H
- PIXELADDR10 PROC NEAR
-
- MOV CL, BL
- PUSH DX
-
- MOV DX, BYTESPERLINE
- MUL DX
-
- POP DX
- SHR BX, 1
- SHR BX, 1
- SHR BX, 1
- ADD BX, AX
- ADD BX, ORIGINOFFSET
-
- MOV AX, VIDEOBUFFERSEG
- MOV ES, AX
-
- AND CL, 7
- XOR CL, 7
- MOV AH, 1
- RET
-
- PIXELADDR10 ENDP
-
- TRANSOFF DW ? ; THE OFFSET OF THE TRANSLATION ARRAY
- TRANSSEG DW ? ; THE SEGMENT OF THE TRANSLATION ARRAY
- TRANS_TAB DB 256 DUP(?) ; ALLOCATE ROOM FOR THE TRANSLATIONS TABLE
- ;******************************************************************
- ; INITEGA
- ; use the BIOS to set mode 10 on the EGA board
- ;
- _INITEGA PROC FAR
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
- MOV AX,0010H ; set to hi-res mode for EGA
- INT 10h ; video
- POP DI
- POP SI
- POP ES
- POP DS
- RET
- _INITEGA ENDP
-
- _RESETEGA PROC FAR
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
- MOV AX,3 ; set to color character mode
- INT 10h
- POP DI
- POP SI
- POP ES
- POP DS
- RET
- _RESETEGA ENDP
-
- ;*******************************************************************
- ; PALETTE
- ; set one element of the EGA's palette select
- ;
- ; usage: egapal(reg,setting);
- ; reg (0-15) EGA's palette regs
- ; setting one byte, what to write there
- ;
- _EGAPAL PROC FAR
- PUSH BP
- MOV BP,SP
-
- MOV BL,[BP+X] ; register #
- MOV BH,[BP+X+2] ; value
- MOV AX,01000H ; set palette element
- INT 10h
-
- POP BP
- RET
- _EGAPAL ENDP
-
- ;
- ; TAKES A TABLE OF PALETTE SETTINGS AND USES BIOS CALL TO PUT THEM INTO THE PALETTE
- ; USAGE: PUTMAPE(&TABLE)
- ;
- _PUTMAPE PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV DX,[BP+X] ; GET THE OFFSET OF THE PALETTE LIST
- MOV AX,[BP+X+2] ; GET THE SEGMENT OF THE PALETTE LIST
- MOV ES,AX ; MOVE THE SEGMENT INTO THE PROPER REGISTER
- MOV AX,01002H ; MOVE THE CODE FOR SETTING ALL PALETTE REGISTERS INTO THE AX
- INT 10H ; DO A VIDEO BIOS CALL TO SET THE PALETTE REGISTERS
-
- POP ES
- POP DS
- POP BP
- RET
- _PUTMAPE ENDP
-
- ;*****************************************************************
- ; Puts an absolute pixel in the given color
- ;
- ; usage: egapoint(x,y,color,table)
- ; x,y = point location
- ; color = integer color number 0 to 255
- ; table = translation table of 256 bytes for XLAT
- ;
- ; BUG: will only write on black background, see egaline for
- ; clearing all four planes before writing to specified planes
- ; in that color
- ;
- _EGAPT PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH ES
- PUSH DI
-
- MOV AL,FLAG
- OR AL,AL
- JNZ NOSETUP
- CALL SETUPG ; set up the mask regs
- MOV FLAG,1 ; set the flag
- NOSETUP:
- MOV CX,TRANSSEG ; get segment of transtable
- MOV BX,TRANSOFF ; get offset of transtable
- MOV AX,[BP+X+4] ; get the color param = 3rd param
- PUSH DS
- MOV DS,CX ; set ds for the transtable
- XLATB ; pick up translated color
- POP DS
- MOV DX,MAPMASK
- OUT DX,AL ; set the mask to this color
- MOV AX,0A000H
- MOV ES,AX ; set for addressing
- MOV AX,[BP+X+2] ; get y value 0 < y < 350
- MOV BX,80
- MUL BX ; multiply by 80 bytes/line
- MOV DI,AX ; put in DI
- MOV AX,[BP+X] ; get x value 0 < x < 640
- MOV BX,AX ; save it
- MOV CL,3
- SHR AX,CL ; divide by 8
- ADD DI,AX ; add it to di = byte offset
- ;
- MOV CX,BX
- AND CX,0007H ; save only the right three bits
- MOV BL,80H ; here's a bit
- SHR BL,CL ; move it over some
- MOV DX,BITMASK ; set the mask
- MOV AL,BL
- OUT DX,AL ; send it
- ;
- MOV AL,0FFH ; set all bits
- MOV AH,ES:[DI] ; latch the bytes
- STOSB ; place that bit on bit mask
-
- POP DI
- POP ES
- POP BP
- RET
- _EGAPT ENDP
-
- SETUPG:
- MOV DX,GCHIP
- MOV AL,MODEREG
- OUT DX,AL ; choose write mode 0
- INC DX
- MOV AL,0
- OUT DX,AL ; clear mode reg to 0
- DEC DX
- MOV AL,DRREG ; clear function select = Replace
- OUT DX,AL
- INC DX
- MOV AL,0h ; clear all
- OUT DX,AL
- ;
- MOV AL,MAPREG ; want to access mapreg from
- MOV DX,SEQ ; sequencer set of regs
- OUT DX,AL
- MOV AL,BITREG ; want to access bitreg from
- MOV DX,GCHIP ; graphics chip's regs
- OUT DX,AL
- MOV DX,BITMASK ; set up the bitmask = no masking
- MOV AL,0FFH ; all bits on
- OUT DX,AL
- RET
- ;
- ;**************************************************************************
- ; EGALINE
- ;
- ; Write a stream of colors (represented by bytes) to the EGA, with
- ; a translation table for the EGA color map.
- ;
- ; Usage: egaline(x,y,colorbuffer,xoff,n)
- ; x,y = point to start line at on the screen
- ; colorbuffer = 4 byte pointer to stream of
- ; n bytes.
- ; xoff = offset into the line to be sent to the screen
-
- _EGALINE PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- MOV AL,FLAG
- OR AL,AL
- JNZ NOSETUP2
- CALL SETUPG ; set up the mask regs
- MOV FLAG,1 ; set the flag
- NOSETUP2:
- MOV AX,[BP+X+6] ; get color table segment
- MOV DS,AX ; use it now
-
- MOV AX,0A000H
- MOV ES,AX ; set for addressing
- MOV AX,[BP+X+8] ; GET THE X OFFSET INTO THE ARRAY
- CMP AX,0 ; CHECK FOR NEGATIVE OFFSET
- JGE OKSIGN ; JUMP AROUND FIXING THE WINDOW IF POSITIVE
- NEG AX ; TAKE THE OPPOSITE VALUE
- ADD AX,[BP+X] ; AND ADD IT TO THE POSITION ON THE SCREEN
- MOV [BP+X],AX ; AND RE-STORE THE POSITION
- MOV AX,[BP+X+8] ; GET THE NEGATIVE OFFSET AGAIN
- ADD AX,[BP+X+10] ; REDUCE THE NUMBER OF BYTES TO COPY TO THE SCREEN
- MOV [BP+X+10],AX ; AND STORE THE NUMBER OF BYTES AGAIN
- OKSIGN:
- ; MOV [BP+X+8],AX ; PUT THE OFFSET BACK
- ;
- MOV AX,[BP+X+2] ; get y value 0 < y < 350
- MOV BX,80
- MUL BX ; multiply by 80 bytes/line
- MOV DI,AX ; put in DI
- MOV AX,[BP+X] ; get x value 0 < x < 640
- MOV BX,AX ; save it
- MOV CL,3
- SHR AX,CL ; divide by 8
- ADD DI,AX ; add it to di = byte offset
- ;
- MOV CX,BX
- AND CX,0007H ; save only the right three bits
- MOV BL,080H ; here's a bit
- ROR BL,CL ; move it over some
- ;
- ; At this point, bl has the bit mask for the first bit in the line
- ; Keep rotating it and set the mask for each bit to write
- ;
- MOV CX,[BP+X+10] ; get count of bytes
- CMP CX,0 ; CHECK FOR ZERO BYTES
- JL LINEDONE ; JUMP TO THE END OF THE ROUTINE
- MOV SI,[BP+X+4] ; where to get the new colors
- ADD SI,[BP+X+8] ; add in the x offset into the line
-
- MOV AH,BL ; keep bit rotation in ah
- MOV DX,TRANSSEG ; get segment of transtable
- MOV BX,TRANSOFF ; get offset of transtable
- NEXTBIT:
- LODSB ; get the next color to al
- PUSH DS
- MOV DS,DX ; set ds for the transtable
- XLATB ; pick up translated color to al
- PUSH AX ; need it later
-
- MOV DX,BITMASK ; set the bitmask to current rotation
- MOV AL,AH
- OUT DX,AL ; send it
-
- MOV DX,MAPMASK
- MOV AL,0FH ; open all bit planes
- OUT DX,AL ; send it
-
- MOV AL,ES:[DI] ; latch the whole set of bytes
- MOV BYTE PTR ES:[DI],0H ; clear all four planes to 0 at this bit
- POP AX ; get real color back
- OUT DX,AL ; send it to set the color planes
-
- MOV DX,DS ; recover what was in dx
- POP DS
- ;
- MOV AL,0FFH ; set all bits
- CMP AH,01 ; see if we are at end of byte
- JZ INCSTORE
-
- NONINC:
- MOV ES:[DI],AL ; write the bit from bitmask
- ROR AH,1 ; rotate me
- LOOP NEXTBIT ; go back for next one
- JMP LINEDONE
-
- INCSTORE:
- STOSB ; place that bit on bit mask and next byte
- ROR AH,1 ; rotate me
- LOOP NEXTBIT
-
- LINEDONE:
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _EGALINE ENDP
-
-
- _EGALINE2 PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- MOV AL,FLAG
- OR AL,AL
- JNZ NO2SETUP2
- CALL SETUPG ; set up the mask regs
- MOV FLAG,1 ; set the flag
- NO2SETUP2:
- MOV AX,[BP+X+6] ; get color table segment
- MOV DS,AX ; use it now
-
- MOV AX,0A000H
- MOV ES,AX ; set for addressing
- MOV AX,[BP+X+2] ; get y value 0 < y < 350
- MOV BX,80
- MUL BX ; multiply by 80 bytes/line
- MOV DI,AX ; put in DI
- MOV AX,[BP+X] ; get x value 0 < x < 640
- MOV BX,AX ; save it
- MOV CL,3
- SHR AX,CL ; divide by 8
- ADD DI,AX ; add it to di = byte offset
- ;
- MOV CX,BX
- AND CX,0007H ; save only the right three bits
- MOV BL,0C0H ; here's 2 bits
- ROR BL,CL ; move it over some
- ;
- ; At this point, bl has the bit mask for the first bit in the line
- ; Keep rotating it and set the mask for each bit to write
- ;
- MOV CX,[BP+X+8] ; get count of bytes
- MOV SI,[BP+X+4] ; where to get the new colors
-
- MOV AH,BL ; keep bit rotation in ah
- MOV DX,[BP+X+12] ; get segment of transtable
- MOV BX,[BP+X+10] ; get offset of transtable
-
- NEXT2BIT:
- LODSB ; get the next color to al
- PUSH DS
- MOV DS,DX ; set ds for the transtable
- XLATB ; pick up translated color to al
- PUSH AX ; need it later
-
- MOV DX,BITMASK ; set the bitmask to current rotation
- MOV AL,AH
- OUT DX,AL ; send it
-
- MOV DX,MAPMASK
- MOV AL,0FH ; open all bit planes
- OUT DX,AL ; send it
-
- MOV AL,ES:[DI] ; latch the whole set of bytes
- MOV BYTE PTR ES:[DI],0H ; clear all four planes to 0 at this bit
- POP AX ; get real color back
- OUT DX,AL ; send it to set the color planes
-
- MOV DX,DS ; recover what was in dx
- POP DS
- ;
- MOV AL,0FFH ; set all bits
- CMP AH,03 ; see if we are at end of byte
- JZ INC2STORE
-
- NON2INC:
- MOV ES:[DI],AL ; write the bit from bitmask
- ROR AH,1 ; rotate me
- ROR AH,1 ; rotate me
- LOOP NEXT2BIT ; go back for next one
- JMP LINE2DONE
-
- INC2STORE:
- STOSB ; place that bit on bit mask and next byte
- ROR AH,1 ; rotate me
- ROR AH,1 ; again
- LOOP NEXT2BIT
-
- LINE2DONE:
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _EGALINE2 ENDP
-
- ;**************************************************************************
- ; EGALINEA
- ;
- ; Write a stream of colors (represented by bytes) to the EGA, with
- ; a translation table for the EGA color map. This one includes arbitrary
- ; width expansion.
- ;
- ; Usage: egalinea(x,y,colorbuffer,n,table,expansion)
- ; x,y = point to start line
- ; colorbuffer = 4 byte pointer to stream of
- ; n bytes.
- ; table = 4 byte pointer to translation table, 256 bytes
- ; long for XLAT instruction
- ; expansion = how much horizontal pixel expansion you want
- ;
-
- _EGALINEA PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- MOV AL,FLAG
- OR AL,AL
- JNZ NOSETA
- CALL SETUPG ; set up the mask regs
- MOV FLAG,1 ; set the flag
- NOSETA:
- MOV AX,[BP+X+6] ; get color table segment
- MOV DS,AX ; use it now
-
- MOV AX,0A000H
- MOV ES,AX ; set for addressing
- MOV AX,[BP+X+2] ; get y value 0 < y < 350
- MOV BX,80
- MUL BX ; multiply by 80 bytes/line
- MOV DI,AX ; put in DI
-
- MOV AX,[BP+X] ; get x value 0 < x < 640
- MOV BX,AX ; save it
- MOV CL,3
- SHR AX,CL ; divide by 8
- ADD DI,AX ; add it to di = byte offset
- ;
- MOV CX,BX
- AND CX,0007H ; save only the right three bits
- MOV BL,080H ; here's a bit
- ROR BL,CL ; move it over some
- ;
- ; At this point, bl has the bit mask for the first bit in the line
- ; Keep rotating it and set the mask for each bit to write
- ;
- MOV SI,[BP+X+4] ; where to get the new colors
-
- MOV AH,BL ; keep bit rotation in ah
- MOV DX,TRANSSEG ; get segment of transtable
- MOV BX,TRANSOFF ; get offset of transtable
-
- NEXTBYTE:
- MOV CX,[BP+X+10] ; pixel expansion number
- LODSB ; the next color to write
- PUSH DS
- MOV DS,DX ; get the seg for xlat from dx
- XLATB ; color translation
- MOV [BP+X],AL ; used as a local var for translated color
-
- NEXTP:
- MOV DX,BITMASK ; set the bitmask to current rotation
- MOV AL,AH
- OUT DX,AL ; send it
-
- MOV DX,MAPMASK
- MOV AL,0FH ; open all bit planes
- OUT DX,AL ; send it
-
- MOV AL,ES:[DI] ; latch the whole set of bytes
- MOV BYTE PTR ES:[DI],0H ; clear all four planes to 0 at this bit
- MOV AL,[BP+X] ; get real color from local var
- OUT DX,AL ; send it to set the color planes
- ;
- MOV AL,0FFH ; set all bits
- MOV ES:[DI],AL ; set it!
- CMP AH,01 ; see if we are at end of byte
- JNZ SAMEBYTE
- INC DI ; get us to the next destination byte
- SAMEBYTE:
- ROR AH,1 ; rotate me
- LOOP NEXTP ; go back for next one
-
- MOV DX,DS ; reset xlat segment into dx
- POP DS ; get data input seg back
- DEC WORD PTR [BP+X+8] ; number of data points
- JNZ NEXTBYTE ; do another, if necessary
-
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _EGALINEA ENDP
- ifdef QAK
- ;
- ; DRAWS AN INVERTED BOX ON THE EGA SCREEN
- ; USAGE: OUTLINEE(X1,Y1,X2,Y2);
- ;
- _OUTLINEE PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV AX,[BP+X+2] ; GET THE FIRST Y VALUE
- CMP AX,[BP+X+6] ; COMPARE THE SECOND Y VALUE
- JLE CHECKX ; OK ORDER, CHECK THE X VALUES
- MOV CX,AX ; SWAP THE Y VALUES
- MOV AX,[BP+X+6] ;
- MOV [BP+X+2],AX ;
- MOV [BP+X+6],CX ;
- CHECKX:
- MOV AX,[BP+X] ; GET THE FIRST X VALUE
- CMP AX,[BP+X+4] ; COMPARE THE SECOND X VALUE
- JLE MAKELEN ; OK ORDER, COMPUTE THE LENGTHS
- MOV CX,AX ; SWAP THE X VALUES
- MOV AX,[BP+X+4] ;
- MOV [BP+X],AX ;
- MOV [BP+X+4],CX ;
- MAKELEN: ; COMPUTE THE X AND Y LENGTH OF THE BOX TO BE INVERTED
- MOV AX,[BP+X+4] ; GET THE LARGER OF THE TWO X VALUES
- SUB AX,[BP+X] ; SUBTRACT THE SMALLER VALUE TO GET THE LENGTH
- ADD AX,1 ;
- MOV X_WIDTH,AX ; STORE THE LENGTH IN THE OLD LOCATION FOR THE 2ND VALUE
- MOV AX,[BP+X+6] ; GET THE LARGER OF THE 2 Y VALUES
- SUB AX,[BP+X+2] ; SUBTRACT THE SMALLER TO FIND THE LENGTH
- ADD AX,1 ; SUBTRACT FOR THE TOP AND BOTTOM EDGES
- MOV Y_HEIGHT,AX ; STORE THE Y LENGTH IN THE OLD LOCATION FOR THE 2ND Y VALUE
- ; SET UP THE REST OF THE PARAMETERS
- MOV AX,[BP+X] ; THE PIXEL POSITION OF THE LEFT EDGE
- MOV X_OFF,AX
- MOV AX,[BP+X+2] ; THE PIXEL POSITION OF THE TOP LINE
- MOV Y_OFF,AX
- ; MAKE THE TOP LINE
- MOV CX,X_WIDTH ; GET THE NUMBER OF PIXELS TO WRITE
- OUTLOOP1:
- PUSH CX ; SAVE THE COUNT FOR LATER
- MOV BH,0 ; USE THE ZERO GRAPHICS PAGE
- MOV DX,Y_OFF ; SET THE POSITION OF THE TOP LINE
- MOV AX,0C8FH ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
- MOV CX,X_OFF ; GET THE CURRENT X LOCATION
- INC X_OFF ; MOV THE X LOCATION TO THE NEXT PLACE
- INT 10H ; DO BIOS VIDEO INTERUPT
- POP CX ; GET COUNT BACK
- LOOP OUTLOOP1 ; GO BACK AND FINISH THE LINE
- ; MAKE THE MIDDLE LINES
- MOV AX,[BP+X] ; GET THE LEFT HAND EDGE
- MOV X_OFF,AX
- MOV AX,[BP+X+4] ; GET THE RIGHT HAND EDGE
- MOV X_TEMP,AX
- INC Y_OFF ; GO TO THE NEXT LINE
- MOV DX,Y_OFF
- CMP DX,[BP+X+6] ; CHECK FOR THIS BEING FURTHER THAN THE BOTTOM LINE
- JLE OUTLOOP2 ; NOT TO WORRY
- DEC Y_OFF ; FIX DX BACK TO BE THE LINE
- JMP ENDLOOP2 ; JUMP TO DOING THE BOTTOM LINE
- OUTLOOP2:
- CMP DX,[BP+X+6] ; CHECK FOR THE BOTTOM OF THE OUTLINE DONE
- JE ENDLOOP2 ; IF WE ARE THAN THE BOTTOM EDGE THEN JUMP TO BOTTOM LINE
- MOV BH,0 ; USE THE ZERO GRAPHICS PAGE
- MOV DX,Y_OFF ;
- MOV AX,0C8FH ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
- MOV CX,X_OFF ; MOVE THE VALUE FOR THE LEFT EDGE
- INT 10H ; DO BIOS VIDEO INTERUPT
- MOV BH,0 ; USE THE ZERO GRAPHICS PAGE
- MOV DX,Y_OFF ;
- MOV AX,0C8FH ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
- MOV CX,X_TEMP ; MOVE THE VALUE FOR THE RIGHT EDGE
- INT 10H ; DO BIOS VIDEO INTERUPT
- INC Y_OFF ; GO TO NEXT VERTICAL VALUE
- JMP OUTLOOP2 ; GO BACK TO TOP OF THE LOOP
-
- ;MAKE THE BOTTOM LINE (Y_OFF IS ALREADY SET TO THE CORRECT VALUE)
- ENDLOOP2:
- MOV CX,X_WIDTH ; GET THE NUMBER OF PIXELS TO WRITE
- OUTLOOP3:
- PUSH CX ; SAVE THE COUNT FOR LATER
- MOV BH,0 ; USE THE ZERO GRAPHICS PAGE
- MOV DX,Y_OFF ; SET THE POSITION OF THE TOP LINE
- MOV AX,0C8FH ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
- MOV CX,X_OFF ; GET THE CURRENT X LOCATION
- INC X_OFF ; MOV THE X LOCATION TO THE NEXT PLACE
- INT 10H ; DO BIOS VIDEO INTERUPT
- POP CX ; GET COUNT BACK
- LOOP OUTLOOP3 ; GO BACK AND FINISH THE LINE
-
- DONE:
- POP ES
- POP DS
- POP BP
- RET
- _OUTLINEE ENDP
- endif
- ;
- ; DRAWS AN INVERTED BOX ON THE EGA SCREEN
- ; USAGE: INVERSEE(X1,Y1,WIDTH,HEIGHT);
- ;
- _INVERSEE PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MAKEINV: ; COMPUTE THE X AND Y LENGTH OF THE BOX TO BE INVERTED
- MOV AX,[BP+X+4] ; GET THE WIDTH
- MOV X_WIDTH,AX ; STORE THE WIDTH
- MOV AX,[BP+X+6] ; GET THE HEIGHT
- MOV Y_HEIGHT,AX ; STORE THE HEIGHT
- ; SET UP THE REST OF THE PARAMETERS
- MOV AX,[BP+X+2] ; THE PIXEL POSITION OF THE TOP LINE
- MOV Y_OFF,AX
- MOV CX,Y_HEIGHT ; GET THE HEIGHT OF THE BLOCK TO INVERSE
- INVTOP1:
- PUSH CX ; SAVE THE HEIGHT VALUE
- MOV AX,[BP+X] ; THE PIXEL POSITION OF THE LEFT EDGE
- MOV X_OFF,AX
- MOV CX,X_WIDTH ; GET THE WIDTH OF THE BLOCK TO INVERSE
- INVTOP2:
- PUSH CX ; SAVE THE WIDTH VALUE
- MOV BH,0 ; USE THE ZERO GRAPHICS PAGE
- MOV DX,Y_OFF ; SET THE POSITION OF THE TOP LINE
- MOV AX,0C8FH ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
- MOV CX,X_OFF ; GET THE CURRENT X LOCATION
- INC X_OFF ; MOV THE X LOCATION TO THE NEXT PLACE
- INT 10H ; DO BIOS VIDEO INTERUPT
- POP CX ; GET HORIZONTAL COUNT BACK
- LOOP INVTOP2 ; GO BACK AND FINISH THE LINE
-
- INC Y_OFF ; INCREMENT THE VERTICAL LINE WE ARE ON
- POP CX ; GET THE VERTICAL COUNT BACK
- LOOP INVTOP1 ; GO BACK AND FINISH THE BLOCK
-
- DONEINV:
- POP ES
- POP DS
- POP BP
- RET
- _INVERSEE ENDP
- ;
- ; DRAWS A BLOCK ON THE EGA SCREEN
- ; USAGE: egablock(&block,x1,y1,width,height);
- ;
- _EGABLOCK PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- MOV AX,[BP+X+8] ; GET THE WIDTH
- MOV X_WIDTH,AX ; STORE THE WIDTH
- MOV AX,[BP+X+10] ; GET THE HEIGHT
- MOV Y_HEIGHT,AX ; STORE THE HEIGHT
- ; SET UP THE REST OF THE PARAMETERS
- MOV AX,[BP+X] ; GET THE OFFSET OF THE ARRAY OF INFORMATION
- MOV BLKOFF,AX ; SAVE THE OFFSET OF THE ARRAY
- MOV AX,[BP+X+2] ; GET THE SEGMENT OF THE ARRAY
- MOV BLKSEG,AX ; SAVE THE SEGMENT
- MOV AX,[BP+X+6] ; THE PIXEL POSITION OF THE TOP LINE
- MOV Y_OFF,AX
- MOV CX,Y_HEIGHT ; GET THE HEIGHT OF THE BLOCK TO COPY
- BLKTOP1:
- PUSH CX ; SAVE THE HEIGHT VALUE
- PUSH DS
- MOV AX,[BP+X+4] ; THE PIXEL POSITION OF THE LEFT EDGE
- MOV X_OFF,AX
- MOV CX,X_WIDTH ; GET THE WIDTH OF THE BLOCK TO COPY
- BLKTOP2:
- PUSH CX ; SAVE THE WIDTH VALUE
- MOV DI,BLKOFF ; GET THE BLOCK OFFSET
- MOV ES,BLKSEG ; GET THE BLOCK SEGMENT
- MOV AL,BYTE PTR ES:[DI] ; GET THE VALUE FROM THE BLOCK
- INC BLKOFF ; GO ON TO THE NEXT LOCATION IN THE BLOCK
- PUSH DS
- MOV BX,TRANSOFF ; get offset of transtable
- MOV DS,TRANSSEG ; get segment of transtable
- XLATB ; pick up translated color
- POP DS
- MOV DX,Y_OFF ; SET THE POSITION OF THE TOP LINE
- MOV AH,0CH ; SET THE PIXEL TO WRITE TO INVERT THE COLOR
- MOV BH,0 ; USE THE ZERO GRAPHICS PAGE
- MOV CX,X_OFF ; GET THE CURRENT X LOCATION
- INC X_OFF ; MOV THE X LOCATION TO THE NEXT PLACE
- INT 10H ; DO BIOS VIDEO INTERUPT
- POP CX ; GET HORIZONTAL COUNT BACK
- LOOP BLKTOP2 ; GO BACK AND FINISH THE LINE
-
- INC Y_OFF ; INCREMENT THE VERTICAL LINE WE ARE ON
- POP DS ; GET THE FIRST DATA SEGMENT BACK
- POP CX ; GET THE VERTICAL COUNT BACK
- LOOP BLKTOP1 ; GO BACK AND FINISH THE BLOCK
-
- DONEBLK:
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _EGABLOCK ENDP
-
- TESTVAR1 DW ?
- TESTVERT DW ?
- TESTCOLOR DB ?
-
- _SETTRANS PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- MOV TRANSOFF,OFFSET TRANS_TAB ; GET THE OFFSET OF THE TRANSLATION TABLE
- MOV TRANSSEG,SEG TRANS_TAB ; GET THE SEGMENT OF THE TRANSLATION TABLE
-
- MOV DI,TRANSOFF ; GET THE OFFSET OF THE OLD TRANSLATION TABLE
- MOV ES,TRANSSEG ; GET THE SEGMENT OF THE OLD TRANSLATION TABLE
-
- LDS SI,DWORD PTR [BP+X] ; GET THE OFFSET OF THE NEW TRANSLATION TABLE
-
- MOV CX,128 ; COPY 256 BYTES
-
- REP MOVSW ; COPY THE ARRAY
-
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _SETTRANS ENDP
-
- ARGX1 EQU WORD PTR [BP+6]
- ARGY1 EQU WORD PTR [BP+8]
- ARGX2 EQU WORD PTR [BP+10]
- ARGY2 EQU WORD PTR [BP+12]
- ARGN EQU BYTE PTR [BP+14]
-
- VARVERTINCR EQU WORD PTR [BP-6]
- VARINCR1 EQU WORD PTR [BP-8]
- VARINCR2 EQU WORD PTR [BP-10]
- VARROUTINE EQU WORD PTR [BP-12]
-
- BYTEOFFSETSHIFT EQU 3
- BYTESPERLINE EQU 80
- RMWBITS EQU 0
-
- _LINE10 PROC FAR
-
- PUSH BP
- MOV BP, SP
- SUB SP, 16H
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ;CONFIGURE THE GRAPHICS CONTROLLER
- MOV DX, 3CEH
-
- MOV AH, ARGN
- XOR AL, AL
- OUT DX, AX
-
- MOV AX,0F01H
-
- OUT DX, AX
- MOV AH, RMWBITS
- MOV AL, 3
- OUT DX, AX
-
- ;CHECK FOR VERTICAL LINE
- MOV SI, BYTESPERLINE
-
- MOV CX, ARGX2
- SUB CX, ARGX1
- JZ VERTLINE10
-
- ;FORCE X1 < X2
- JNS L01
-
- NEG CX
- MOV BX, ARGX2
- XCHG BX, ARGX1
- MOV ARGX2,BX
- MOV BX, ARGY2
- XCHG BX, ARGY1
- MOV ARGY2,BX
-
- ;CALCULATE DY = ABS (Y2-Y1)
-
- L01:
- MOV BX, ARGY2
- SUB BX, ARGY1
- JZ HORIZLINE10
-
- JNS L03
-
- NEG BX
- NEG SI
-
- ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
-
- L03:
- MOV VARVERTINCR,SI
-
- MOV VARROUTINE, OFFSET LOSLOPELINE10
- CMP BX, CX
- JLE L04
- MOV VARROUTINE, OFFSET HISLOPELINE10
- XCHG BX, CX
-
- ;CALCULATE INITIAL DECISION VARIABLE AND INCREMENTS
-
- L04:
- SHL BX, 1
- MOV VARINCR1, BX
- SUB BX, CX
- MOV SI,BX
- SUB BX,CX
- MOV VARINCR2, BX
-
- ;CALCULATE FIRST PIXEL ADDRESS
-
- PUSH CX
- MOV AX, ARGY1
- MOV BX, ARGX1
- CALL PIXELADDR10
-
- MOV DI, BX
- SHL AH, CL
- MOV BL, AH
- MOV AL, 8
-
- POP CX
- INC CX
- JMP VARROUTINE
-
- ;ROUTINE FOR VERTICAL LINES
-
- VERTLINE10:
- MOV AX, ARGY1
- MOV BX, ARGY2
- MOV CX, BX
- SUB CX, AX
- JGE L31
-
- NEG CX
- MOV AX, BX
-
- L31:
- INC CX
- MOV BX, ARGX1
- PUSH CX
- CALL PIXELADDR10
-
- ;SET UP GRAPHICS CONTROLLER
-
- SHL AH, CL
- MOV AL, 8
- OUT DX, AX
-
- POP CX
-
- ;DRAW THE LINE
- L32:
- OR ES:[BX], AL
- ADD BX, SI
- LOOP L32
-
- JMP LEXIT
-
- ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
-
- HORIZLINE10:
- PUSH DS
- MOV AX, ARGY1
- MOV BX, ARGX1
- CALL PIXELADDR10
-
- MOV DI, BX
- MOV DH, AH
- NOT DH
- SHL DH, CL
- NOT DH
- MOV CX, ARGX2
- AND CL, 7
- XOR CL, 7
- MOV DL, 0FFH
-
- SHL DL, CL
-
- ;DETERMINE BYTE OFFSET OF FIRST AND LAST PIXEL IN THE LINE
-
- MOV AX, ARGX2
- MOV BX, ARGX1
-
- MOV CL, BYTEOFFSETSHIFT
-
- SHR AX, CL
- SHR BX, CL
- MOV CX, AX
- SUB CX, BX
-
- ;GET GRAPHICS CONTROLLER PORT ADDRESS INTO DX
-
- MOV BX, DX
-
- MOV DX, 3CEH
- MOV AL, 8
-
- ;MAKE VIDEO BUFFER ADDRESSABLE THROUGH DS:SI
-
- PUSH ES
- POP DS
- MOV SI, DI
-
- ;SET PIXELS IN LEFTMOST BYTE OF THE LINE
-
- OR BH, BH
- JS L43
-
- OR CX, CX
- JNZ L42
-
- AND BL, BH
- JMP SHORT L44
-
- L42:
- MOV AH, BH
- OUT DX, AX
-
- MOVSB
- DEC CX
-
- ;USE A FAST 8086 MACHINE INSTRUCTION TO DRAW THE REMAINDER OF THE LINE
-
- L43:
- MOV AH, 11111111B
- OUT DX, AX
- REP MOVSB
-
- ;SET PIXELS IN THE RIGHTMOST BYTE OF THE LINE
-
- L44:
- MOV AH, BL
- OUT DX, AX
- MOVSB
-
- POP DS
- JMP SHORT LEXIT
-
- ;ROUTINE FOR DY>=DX (SLOPE<=1)
-
- LOSLOPELINE10:
-
- L10:
- MOV AH, BL
- L11:
- OR AH,BL
- ROR BL, 1
- JC L14
-
- ;BIT MASK NOT SHIFTED OUT
-
- OR SI, SI
- JNS L12
- ADD SI, VARINCR1
- LOOP L11
- OUT DX, AX
- OR ES:[DI], AL
- JMP SHORT LEXIT
-
- L12:
- ADD SI, VARINCR2
- OUT DX, AX
-
- OR ES:[DI], AL
-
- ADD DI, VARVERTINCR
- LOOP L10
- JMP SHORT LEXIT
-
- ;BIT MASK SHIFTED OUT
-
- L14:
- OUT DX, AX
-
- OR ES:[DI], AL
- INC DI
-
- OR SI, SI
- JNS L15
-
- ADD SI, VARINCR1
- LOOP L10
- JMP SHORT LEXIT
-
- L15:
- ADD SI, VARINCR2
- ADD DI, VARVERTINCR
- LOOP L10
- JMP SHORT LEXIT
-
- ;ROUTINE FOR DY>DX (SLOPE >1)
-
- HISLOPELINE10:
- MOV BX, VARVERTINCR
- L21:
- OUT DX, AX
- OR ES:[DI], AL
-
- ADD DI, BX
-
- L22:
- OR SI, SI
- JNS L23
-
- ADD SI, VARINCR1
- LOOP L21
- JMP SHORT LEXIT
-
- L23:
- ADD SI, VARINCR2
- ROR AH, 1
- ADC DI, 0
-
- LOOP L21
-
- ;RESTORE DEFAULT GRAPHICS CONTROLLER STATE AND RETURN TO CALLER
-
- LEXIT:
- XOR AX, AX
- OUT DX, AX
- INC AX
- OUT DX, AX
- MOV AL, 3
- OUT DX, AX
- MOV AX, 0FF08H
- OUT DX, AX
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
-
- _LINE10 ENDP
-
- RMWBITS2 EQU 24
-
- _INVERT10 PROC FAR
-
- PUSH BP
- MOV BP, SP
- SUB SP, 16H
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ;CONFIGURE THE GRAPHICS CONTROLLER
- MOV DX, 3CEH
-
- MOV AH, ARGN
- XOR AL, AL
- OUT DX, AX
-
- MOV AX,0F01H
-
- OUT DX, AX
- MOV AH, RMWBITS2
- MOV AL, 3
- OUT DX, AX
-
- ;CHECK FOR VERTICAL LINE
- MOV SI, BYTESPERLINE
-
- MOV CX, ARGX2
- SUB CX, ARGX1
- JZ IVERTLINE10
-
- ;FORCE X1 < X2
- JNS IL01
-
- NEG CX
- MOV BX, ARGX2
- XCHG BX, ARGX1
- MOV ARGX2,BX
- MOV BX, ARGY2
- XCHG BX, ARGY1
- MOV ARGY2,BX
-
- ;CALCULATE DY = ABS (Y2-Y1)
-
- IL01:
- MOV BX, ARGY2
- SUB BX, ARGY1
- JZ IHORIZLINE10
-
- JNS IL03
-
- NEG BX
- NEG SI
-
- ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
-
- IL03:
- MOV VARVERTINCR,SI
-
- MOV VARROUTINE, OFFSET ILOSLOPELINE10
- CMP BX, CX
- JLE IL04
- MOV VARROUTINE, OFFSET IHISLOPELINE10
- XCHG BX, CX
-
- ;CALCULATE INITIAL DECISION VARIABLE AND INCREMENTS
-
- IL04:
- SHL BX, 1
- MOV VARINCR1, BX
- SUB BX, CX
- MOV SI,BX
- SUB BX,CX
- MOV VARINCR2, BX
-
- ;CALCULATE FIRST PIXEL ADDRESS
-
- PUSH CX
- MOV AX, ARGY1
- MOV BX, ARGX1
- CALL PIXELADDR10
-
- MOV DI, BX
- SHL AH, CL
- MOV BL, AH
- MOV AL, 8
-
- POP CX
- INC CX
- JMP VARROUTINE
-
- ;ROUTINE FOR VERTICAL LINES
-
- IVERTLINE10:
- MOV AX, ARGY1
- MOV BX, ARGY2
- MOV CX, BX
- SUB CX, AX
- JGE IL31
-
- NEG CX
- MOV AX, BX
-
- IL31:
- INC CX
- MOV BX, ARGX1
- PUSH CX
- CALL PIXELADDR10
-
- ;SET UP GRAPHICS CONTROLLER
-
- SHL AH, CL
- MOV AL, 8
- OUT DX, AX
-
- POP CX
-
- ;DRAW THE LINE
- IL32:
- OR ES:[BX], AL
- ADD BX, SI
- LOOP IL32
-
- JMP ILEXIT
-
- ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
-
- IHORIZLINE10:
- PUSH DS
- MOV AX, ARGY1
- MOV BX, ARGX1
- CALL PIXELADDR10
-
- MOV DI, BX
- MOV DH, AH
- NOT DH
- SHL DH, CL
- NOT DH
- MOV CX, ARGX2
- AND CL, 7
- XOR CL, 7
- MOV DL, 0FFH
-
- SHL DL, CL
-
- ;DETERMINE BYTE OFFSET OF FIRST AND LAST PIXEL IN THE LINE
-
- MOV AX, ARGX2
- MOV BX, ARGX1
-
- MOV CL, BYTEOFFSETSHIFT
-
- SHR AX, CL
- SHR BX, CL
- MOV CX, AX
- SUB CX, BX
-
- ;GET GRAPHICS CONTROLLER PORT ADDRESS INTO DX
-
- MOV BX, DX
-
- MOV DX, 3CEH
- MOV AL, 8
-
- ;MAKE VIDEO BUFFER ADDRESSABLE THROUGH DS:SI
-
- PUSH ES
- POP DS
- MOV SI, DI
-
- ;SET PIXELS IN LEFTMOST BYTE OF THE LINE
-
- OR BH, BH
- JS IL43
-
- OR CX, CX
- JNZ IL42
-
- AND BL, BH
- JMP SHORT IL44
-
- IL42:
- MOV AH, BH
- OUT DX, AX
-
- MOVSB
- DEC CX
-
- ;USE A FAST 8086 MACHINE INSTRUCTION TO DRAW THE REMAINDER OF THE LINE
-
- IL43:
- MOV AH, 11111111B
- OUT DX, AX
- REP MOVSB
-
- ;SET PIXELS IN THE RIGHTMOST BYTE OF THE LINE
-
- IL44:
- MOV AH, BL
- OUT DX, AX
- MOVSB
-
- POP DS
- JMP SHORT ILEXIT
-
- ;ROUTINE FOR DY>=DX (SLOPE<=1)
-
- ILOSLOPELINE10:
-
- IL10:
- MOV AH, BL
- IL11:
- OR AH,BL
- ROR BL, 1
- JC IL14
-
- ;BIT MASK NOT SHIFTED OUT
-
- OR SI, SI
- JNS IL12
- ADD SI, VARINCR1
- LOOP IL11
- OUT DX, AX
- OR ES:[DI], AL
- JMP SHORT ILEXIT
-
- IL12:
- ADD SI, VARINCR2
- OUT DX, AX
-
- OR ES:[DI], AL
-
- ADD DI, VARVERTINCR
- LOOP IL10
- JMP SHORT ILEXIT
-
- ;BIT MASK SHIFTED OUT
-
- IL14:
- OUT DX, AX
-
- OR ES:[DI], AL
- INC DI
-
- OR SI, SI
- JNS IL15
-
- ADD SI, VARINCR1
- LOOP IL10
- JMP SHORT ILEXIT
-
- IL15:
- ADD SI, VARINCR2
- ADD DI, VARVERTINCR
- LOOP IL10
- JMP SHORT ILEXIT
-
- ;ROUTINE FOR DY>DX (SLOPE >1)
-
- IHISLOPELINE10:
- MOV BX, VARVERTINCR
- IL21:
- OUT DX, AX
- OR ES:[DI], AL
-
- ADD DI, BX
-
- IIL23:
- OR SI, SI
- JNS IL23
-
- ADD SI, VARINCR1
- LOOP IL21
- JMP SHORT ILEXIT
-
- IL23:
- ADD SI, VARINCR2
- ROR AH, 1
- ADC DI, 0
-
- LOOP IL21
-
- ;RESTORE DEFAULT GRAPHICS CONTROLLER STATE AND RETURN TO CALLER
-
- ILEXIT:
- XOR AX, AX
- OUT DX, AX
- INC AX
- OUT DX, AX
- MOV AL, 3
- OUT DX, AX
- MOV AX, 0FF08H
- OUT DX, AX
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
-
- _INVERT10 ENDP
-
- ;NAME: ELLIPSE10
- ;
- ARGXC EQU WORD PTR [BP+6]
- ARGYC EQU WORD PTR [BP+8]
- ARGA EQU WORD PTR [BP+10]
- ARGB EQU WORD PTR [BP+12]
- ARGN EQU BYTE PTR [BP+14]
-
- ULADDR EQU WORD PTR [BP-6]
- URADDR EQU WORD PTR [BP-8]
- LLADDR EQU WORD PTR [BP-10]
- LRADDR EQU WORD PTR [BP-12]
- LMASK EQU BYTE PTR [BP-14]
- RMASK EQU BYTE PTR [BP-16]
-
-
- VARD EQU WORD PTR [BP-20]
- VARDX EQU WORD PTR [BP-24]
- VARDY EQU WORD PTR [BP-28]
- ASQUARED EQU WORD PTR [BP-32]
- BSQUARED EQU WORD PTR [BP-36]
- TWOASQUARED EQU WORD PTR [BP-40]
- TWOBSQUARED EQU WORD PTR [BP-44]
-
- RMWBITS EQU 00H
- BYTESPERLINE EQU 80
-
- _CIRCLE10 PROC FAR
- PUSH BP
- MOV BP,SP
- SUB SP,50
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ;SET GRAPHICS CONTROLLER MODE REGISTER
- MOV DX,3CEH
- MOV AX,0005H
- OUT DX,AX
-
- ;SET DATA ROTATE/FUNCTION SELECT REGISTER
- MOV AH,RMWBITS
- MOV AL,3
- OUT DX,AX
-
- ;SET SET/RESET AND ENABLE SET/RESET REGISTERS
- MOV AH,ARGN
- MOV AL,0
- OUT DX,AX
- MOV AX,0F01H
- OUT DX,AX
-
- ;INITIAL CONSTANTS
- MOV AX,ARGA
- MUL AX
- MOV ASQUARED,AX
- MOV ASQUARED+2,DX
- SHL AX,1
- RCL DX,1
- MOV TWOASQUARED,AX
- MOV TWOASQUARED+2,DX
- MOV AX,ARGB
- MUL AX
- MOV BSQUARED,AX
- MOV BSQUARED+2,DX
- SHL AX,1
- RCL DX,1
- MOV TWOBSQUARED,AX
- MOV TWOBSQUARED+2,DX
-
- ;PLOT PIXELS FROM (0,B) UNTIL DY/DX =-1
- ;INITIAL BUFFER ADDRESS AND BIT MASK
- MOV AX,BYTESPERLINE
- MUL ARGB
- MOV SI,AX
- MOV DI,AX
- MOV AX,ARGYC
- MOV BX,ARGXC
- CALL PIXELADDR10
-
- MOV AH,1
- SHL AH,CL
- MOV LMASK,AH
- MOV RMASK,AH
-
- ADD SI,BX
- MOV ULADDR,SI
- MOV URADDR,SI
- SUB BX,DI
- MOV LLADDR,BX
- MOV LRADDR,BX
-
- ;INITIAL DECISION VARIABLES
- XOR AX,AX
- MOV VARDX,AX
- MOV VARDX+2,AX
-
- MOV AX,TWOASQUARED
- MOV DX,TWOASQUARED+2
- MOV CX,ARGB
- CALL LONGMULTIPLY
- MOV VARDY,AX
- MOV VARDY+2,DX
-
- MOV AX,ASQUARED
- MOV DX,ASQUARED+2
- SAR DX,1
- RCR AX,1
- SAR DX,1
- RCR AX,1
-
- ADD AX,BSQUARED
- ADC DX,BSQUARED+2
- MOV VARD,AX
- MOV VARD+2,DX
-
- MOV AX,ASQUARED
- MOV DX,ASQUARED+2
- MOV CX,ARGB
- CALL LONGMULTIPLY
- SUB VARD,AX
- SBB VARD+2,DX
-
- ;LOOP UNTIL DY/DX>=-1
- MOV BX,ARGB
- XOR CX,CX
-
- C10:
- MOV AX,VARDX
- MOV DX,VARDX+2
- SUB AX,VARDY
- SBB DX,VARDY+2
- JNS C20
-
- CALL SET4PIXELS
- MOV CX,1
- CMP VARD+2,0
- JS C11
- MOV CH,1
- DEC BX
-
- MOV AX,VARDY
- MOV DX,VARDY+2
- SUB AX,TWOASQUARED
- SBB DX,TWOASQUARED+2
- MOV VARDY,AX
- MOV VARDY+2,DX
-
- SUB VARD,AX
- SBB VARD+2,DX
-
- C11:
- MOV AX,VARDX
- MOV DX,VARDX+2
- ADD AX,TWOBSQUARED
- ADC DX,TWOBSQUARED+2
- MOV VARDX,AX
- MOV VARDX+2,DX
- ADD AX,BSQUARED
- ADC DX,BSQUARED+2
- ADD VARD,AX
- ADC VARD+2,DX
- JMP C10
-
- ;PLOT PIXELS FROM CURRENT (X,Y) UNTIL Y<0
-
- C20:
- PUSH BX
- PUSH CX
- MOV AX,ASQUARED
- MOV DX,ASQUARED+2
- SUB AX,BSQUARED
- SBB DX,BSQUARED+2
- MOV BX,AX
- MOV CX,DX
-
- SAR DX,1
- RCR AX,1
- ADD AX,BX
- ADC DX,CX
-
- SUB AX,VARDX
- SBB DX,VARDX+2
- SUB AX,VARDY
- SBB DX,VARDY+2
-
- SAR DX,1
- RCR AX,1
-
- ADD VARD,AX
- ADC VARD+2,DX
-
- ;LOOP UNTIL Y<0
- POP CX
- POP BX
- C21:
- CALL SET4PIXELS
- MOV CX,100H
-
- CMP VARD+2,0
- JNS C22
-
- MOV CL,1
- MOV AX,VARDX
- MOV DX,VARDX+2
- ADD AX,TWOBSQUARED
- ADC DX,TWOBSQUARED+2
- MOV VARDX,AX
- MOV VARDX+2,DX
-
- ADD VARD,AX
- ADC VARD+2,DX
-
- C22:
- MOV AX,VARDY
- MOV DX,VARDY+2
- SUB AX,TWOASQUARED
- SBB DX,TWOASQUARED+2
- MOV VARDY,AX
- MOV VARDY+2,DX
-
- SUB AX,ASQUARED
- SBB DX,ASQUARED+2
- SUB VARD,AX
- SBB VARD+2,DX
-
- DEC BX
- JNS C21
-
- ;RESTORE DEFAULT GRAPHICS CONTROLLER REGISTERS
- CEXIT:
- MOV AX,0FF08H
- MOV DX,3CEH
- OUT DX,AX
- MOV AX,0003
- OUT DX,AX
- MOV AX,0001
- OUT DX,AX
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
-
- _CIRCLE10 ENDP
-
- ;NAME: INCIRC10
- ;
- ARGXC EQU WORD PTR [BP+6]
- ARGYC EQU WORD PTR [BP+8]
- ARGA EQU WORD PTR [BP+10]
- ARGB EQU WORD PTR [BP+12]
-
- ULADDR EQU WORD PTR [BP-6]
- URADDR EQU WORD PTR [BP-8]
- LLADDR EQU WORD PTR [BP-10]
- LRADDR EQU WORD PTR [BP-12]
- LMASK EQU BYTE PTR [BP-14]
- RMASK EQU BYTE PTR [BP-16]
-
-
- VARD EQU WORD PTR [BP-20]
- VARDX EQU WORD PTR [BP-24]
- VARDY EQU WORD PTR [BP-28]
- ASQUARED EQU WORD PTR [BP-32]
- BSQUARED EQU WORD PTR [BP-36]
- TWOASQUARED EQU WORD PTR [BP-40]
- TWOBSQUARED EQU WORD PTR [BP-44]
-
- RMWBITS2 EQU 24
- BYTESPERLINE EQU 80
-
- _INCIRC10 PROC FAR
- PUSH BP
- MOV BP,SP
- SUB SP,50
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ;SET GRAPHICS CONTROLLER MODE REGISTER
- MOV DX,3CEH
- MOV AX,0005H
- OUT DX,AX
-
- ;SET DATA ROTATE/FUNCTION SELECT REGISTER
- MOV AH,RMWBITS2
- MOV AL,3
- OUT DX,AX
-
- ;SET SET/RESET AND ENABLE SET/RESET REGISTERS
- MOV AH,0 ; ARGN
- MOV AL,0
- OUT DX,AX
- MOV AX,0F01H
- OUT DX,AX
-
- ;INITIAL CONSTANTS
- MOV AX,ARGA
- MUL AX
- MOV ASQUARED,AX
- MOV ASQUARED+2,DX
- SHL AX,1
- RCL DX,1
- MOV TWOASQUARED,AX
- MOV TWOASQUARED+2,DX
- MOV AX,ARGB
- MUL AX
- MOV BSQUARED,AX
- MOV BSQUARED+2,DX
- SHL AX,1
- RCL DX,1
- MOV TWOBSQUARED,AX
- MOV TWOBSQUARED+2,DX
-
- ;PLOT PIXELS FROM (0,B) UNTIL DY/DX =-1
- ;INITIAL BUFFER ADDRESS AND BIT MASK
- MOV AX,BYTESPERLINE
- MUL ARGB
- MOV SI,AX
- MOV DI,AX
- MOV AX,ARGYC
- MOV BX,ARGXC
- CALL PIXELADDR10
-
- MOV AH,1
- SHL AH,CL
- MOV LMASK,AH
- MOV RMASK,AH
-
- ADD SI,BX
- MOV ULADDR,SI
- MOV URADDR,SI
- SUB BX,DI
- MOV LLADDR,BX
- MOV LRADDR,BX
-
- ;INITIAL DECISION VARIABLES
- XOR AX,AX
- MOV VARDX,AX
- MOV VARDX+2,AX
-
- MOV AX,TWOASQUARED
- MOV DX,TWOASQUARED+2
- MOV CX,ARGB
- CALL LONGMULTIPLY
- MOV VARDY,AX
- MOV VARDY+2,DX
-
- MOV AX,ASQUARED
- MOV DX,ASQUARED+2
- SAR DX,1
- RCR AX,1
- SAR DX,1
- RCR AX,1
-
- ADD AX,BSQUARED
- ADC DX,BSQUARED+2
- MOV VARD,AX
- MOV VARD+2,DX
-
- MOV AX,ASQUARED
- MOV DX,ASQUARED+2
- MOV CX,ARGB
- CALL LONGMULTIPLY
- SUB VARD,AX
- SBB VARD+2,DX
-
- ;LOOP UNTIL DY/DX>=-1
- MOV BX,ARGB
- XOR CX,CX
-
- IC10:
- MOV AX,VARDX
- MOV DX,VARDX+2
- SUB AX,VARDY
- SBB DX,VARDY+2
- JNS IC20
-
- CALL SET4PIXELS
- MOV CX,1
- CMP VARD+2,0
- JS IC11
- MOV CH,1
- DEC BX
-
- MOV AX,VARDY
- MOV DX,VARDY+2
- SUB AX,TWOASQUARED
- SBB DX,TWOASQUARED+2
- MOV VARDY,AX
- MOV VARDY+2,DX
-
- SUB VARD,AX
- SBB VARD+2,DX
-
- IC11:
- MOV AX,VARDX
- MOV DX,VARDX+2
- ADD AX,TWOBSQUARED
- ADC DX,TWOBSQUARED+2
- MOV VARDX,AX
- MOV VARDX+2,DX
- ADD AX,BSQUARED
- ADC DX,BSQUARED+2
- ADD VARD,AX
- ADC VARD+2,DX
- JMP IC10
-
- ;PLOT PIXELS FROM CURRENT (X,Y) UNTIL Y<0
-
- IC20:
- PUSH BX
- PUSH CX
- MOV AX,ASQUARED
- MOV DX,ASQUARED+2
- SUB AX,BSQUARED
- SBB DX,BSQUARED+2
- MOV BX,AX
- MOV CX,DX
-
- SAR DX,1
- RCR AX,1
- ADD AX,BX
- ADC DX,CX
-
- SUB AX,VARDX
- SBB DX,VARDX+2
- SUB AX,VARDY
- SBB DX,VARDY+2
-
- SAR DX,1
- RCR AX,1
-
- ADD VARD,AX
- ADC VARD+2,DX
-
- ;LOOP UNTIL Y<0
- POP CX
- POP BX
- IC21:
- CALL SET4PIXELS
- MOV CX,100H
-
- CMP VARD+2,0
- JNS IC22
-
- MOV CL,1
- MOV AX,VARDX
- MOV DX,VARDX+2
- ADD AX,TWOBSQUARED
- ADC DX,TWOBSQUARED+2
- MOV VARDX,AX
- MOV VARDX+2,DX
-
- ADD VARD,AX
- ADC VARD+2,DX
-
- IC22:
- MOV AX,VARDY
- MOV DX,VARDY+2
- SUB AX,TWOASQUARED
- SBB DX,TWOASQUARED+2
- MOV VARDY,AX
- MOV VARDY+2,DX
-
- SUB AX,ASQUARED
- SBB DX,ASQUARED+2
- SUB VARD,AX
- SBB VARD+2,DX
-
- DEC BX
- JNS IC21
-
- ;RESTORE DEFAULT GRAPHICS CONTROLLER REGISTERS
- ICEXIT:
- MOV AX,0FF08H
- MOV DX,3CEH
- OUT DX,AX
- MOV AX,0003
- OUT DX,AX
- MOV AX,0001
- OUT DX,AX
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
- _INCIRC10 ENDP
-
- SET4PIXELS PROC NEAR
- PUSH AX
- PUSH BX
- PUSH DX
- MOV DX,3CEH
- XOR BX,BX
- TEST CH,CH
- JZ C30
- MOV BX,BYTESPERLINE
- NEG BX
- C30:
- MOV AL,8
-
- ;PIXELS AR (XC-X,YC+Y) AND XC-C,YC-Y)
-
- XOR SI,SI
- MOV AH,LMASK
- ROL AH,CL
- RCL SI,1
- NEG SI
- MOV DI,SI
- ADD SI,ULADDR
- ADD SI,BX
- ADD DI,LLADDR
- SUB DI,BX
- MOV LMASK,AH
- MOV ULADDR,SI
- MOV LLADDR,DI
- OUT DX,AX
- MOV CH,ES:[SI]
- MOV ES:[SI],CH
- MOV CH,ES:[DI]
- MOV ES:[DI],CH
-
- ;PIXELS AT (XC+X,YC+Y) AND (XC+X,YC+Y)
-
- XOR SI,SI
- MOV AH,RMASK
- ROR AH,CL
- RCL SI,1
- MOV DI,SI
-
- ADD SI,URADDR
- ADD SI,BX
- ADD DI,LRADDR
- SUB DI,BX
-
- MOV RMASK,AH
- MOV URADDR,SI
- MOV LRADDR,DI
-
- OUT DX,AX
- MOV CH,ES:[SI]
- MOV ES:[SI],CH
- MOV CH,ES:[DI]
- MOV ES:[DI],CH
-
- POP DX
- POP BX
- POP AX
- RET
-
- SET4PIXELS ENDP
-
- LONGMULTIPLY PROC NEAR
-
- PUSH AX
- MOV AX,DX
- MUL CX
- XCHG AX,CX
- POP DX
- MUL DX
- ADD DX,CX
- RET
-
- LONGMULTIPLY ENDP
-
-
- ENDPS
- END
-