home *** CD-ROM | disk | FTP | other *** search
- ;
- ; VGA support routines for raster oriented graphics
- ;
- ; Quincey Koziol January 1989
- ;
- ; National Center for Supercomputing Applications, University of Illinois
- ; 153 Water Resources Building
- ; 605 E. Springfield Ave.
- ; Champaign, Ill 61820
- ; (217)244-0072
- ;
- TITLE VGA GRAPHICS SUPPORT
- .model LARGE
- .code
- X EQU 6
- ; INCLUDE DOS.MAC
- ; SETX
- ; PSEG
- PUBLIC _PUTMAPV,_GETMAP,_VGALINE1,_VGACHUNK,_VGAPT,_VGAMODE,_VGAOFF,_VGAON
- PUBLIC _OUTLINEV,_BALL,_VGABLOCK,_INVERSEV,_INVERT13,_LINE13
- PUBLIC _SHOWPALV,_NOPALV
- PUBLIC _CIRCLE13,_INCIRC13
-
- ; name: PIXELADDR13
- ;
- ; FUNCTION: CALCULATE THE BUFFER ADDRESS OF PIXEL IN 320X200 256 COLOR MODE
- ;
- ; CALLER: AX = Y COOR. (0-199)
- ; BX = X COOR. (0-319)
- ;
- ;
- ; RETURNS: BX = BYTE OFFSET IN BUFFER
- ; ES = VIDEO BUFFER SEGMENT
- ;
- ORIGINOFFSET EQU 0
- VIDEOBUFFSEG EQU 0A000H
- PIXELADDR13 PROC NEAR
- XCHG AH,AL
- ADD BX,AX
- SHR AX,1
- SHR AX,1
- ADD BX,AX
- ADD BX,ORIGINOFFSET
- MOV AX,VIDEOBUFFSEG
- MOV ES,AX
- RET
- PIXELADDR13 ENDP
-
- ;
- ; take three arrays of color tables and interleave them into the
- ; VGA registers in the fashion Red, Green, Blue.
- ;
-
- _PUTMAPV PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
- ;
- LDS SI,DWORD PTR [BP+X] ; WHERE TO GET RED
- MOV DI,[BP+X+4] ; WHERE TO GET GREEN
- MOV BP,[BP+X+8] ; WHERE TO GET BLUE
- MOV DX,03C8H ; I/O PORT FOR PEL TABLE
- MOV AL,0 ; VALUE FOR BEGINNING OF TABLE
- OUT DX,AL ; START OUTPUTTING VALUES
- INC DX ; INCREMENT DX TO OUTPUT TABLE
- MOV CX,256 ; LENGTH OF THE TABLE IN BYTE TRIPLES
-
- DORGB:
- MOV AL,DS:[SI] ; GET A RED BYTE
- SHR AL,1
- SHR AL,1 ; GET RID OF TWO HIGHEST BITS
- OUT DX,AL
- INC SI
- ;
- MOV AL,DS:[DI] ; GET A GREEN BYTE
- SHR AL,1
- SHR AL,1 ; GET RID OF TWO HIGHEST BITS
- OUT DX,AL
- INC DI
- ;
- MOV AL,DS:[BP] ; GET A BLUE BYTE
- SHR AL,1
- SHR AL,1 ; GET RID OF TWO HIGHEST BITS
- OUT DX,AL
- INC BP
- ;
- LOOP DORGB ; CONTINUE PRINTING UNTIL ALL 768 BYTES ARE WRITTEN
- ;
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
-
- _PUTMAPV ENDP
-
- _GETMAP PROC FAR
- RET
- _GETMAP ENDP
-
- ;
- ; Transfer line to vga screen
- ;
- ; usage : vgaline1(x,y,buf,xoff,linelen)
- ;
- _VGALINE1 PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- LDS SI,DWORD PTR [BP+X+4] ; WHERE DATA WILL COME FROM
- ADD SI,[BP+X+8] ; ADD THE OFFSET TO THE OFFSET OF THE ARRAY
- ;
-
- MOV AX,[BP+X+2] ; GET THE Y VALUE
- MOV BX,[BP+X] ; GET THE X VALUE
- CALL PIXELADDR13 ; CALCULATE THE ADDRESS OF THE PIXEL
- MOV DI,BX ; PREPARE FOR MOVS
-
- MOV CX,[BP+X+10] ; HOW MANY BYTES?
- SHR CX,1 ; CHECK WHETHER THIS CAN BE WORD MOV'ED OR NOT
- JC DOBYTES ; NO, CANNOT USE WORD MOVE
- REP MOVSW ; MOVE WORDS
- JMP SHORT DONEBYTES ; JUMP AROUND THE BYTE COPY
-
- DOBYTES:
- MOV CX,[BP+X+10] ; GET THE COUNT OF BYTES TO MOVE
- REP MOVSB ; MOV THE MEMORY
-
- DONEBYTES:
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _VGALINE1 ENDP
-
-
- ;
- ; Transfer chunk to vga screen
- ;
- ; usage : vgachunk(x,y,buf,xoff,yoff,width,height,linelen)
- ; int x,y; the position to place the block on the screen
- ; char *buf; the chunk to display
- ; int xoff,yoff; the x and y offset into the chunk
- ; int width,height; the width and height of the chunk part to display
- ; int linelen; the length of a horizontal raster line in the chunk
- ;
- _VGACHUNK PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- LDS SI,DWORD PTR [BP+X+4] ; WHERE DATA WILL COME FROM
- MOV AX,[BP+X+10] ; GET THE OFFSET IN THE Y DIRECTION
- JZ ADD_X_OFF ; IF THE Y OFFSET IS ZERO THEN JUST ADD IN THE X OFFSET
- MOV DX,[BP+X+16] ; GET THE LINE LENGTH
- MUL DX ; CALCULATE THE AMOUNT OF OFFSET IN THE Y DIRECTION
- ADD SI,AX ; ADD IN THE Y OFFSET
- ADD_X_OFF:
- ADD SI,[BP+X+8] ; ADD THE OFFSET TO THE OFFSET OF THE ARRAY
- ;
-
- MOV AX,[BP+X+2] ; GET THE Y VALUE
- MOV BX,[BP+X] ; GET THE X VALUE
- CALL PIXELADDR13 ; CALCULATE THE ADDRESS OF THE PIXEL
- MOV DI,BX ; PREPARE FOR MOVS
-
- MOV CX,[BP+X+12] ; HOW MANY BYTES?
- SHR CX,1 ; CHECK WHETHER THIS CAN BE WORD MOV'ED OR NOT
- JC CHUNKLOOPB ; NO, CANNOT USE WORD MOVE
- MOV [BP+X+12],CX ; STORE THE NUMBER OF WORDS TO COPY
-
- CHUNKLOOPW:
- PUSH SI ; PUSH THE SOURCE INDEX
- PUSH DI ; PUSH THE DESTINATION INDEX
- MOV CX,[BP+X+12] ; GET THE COUNT OF BYTES TO MOVE
- REP MOVSW ; MOVE WORDS
-
- POP DI
- ADD DI,320 ; ADD IN THE WIDTH OF THE SCREEN
- POP SI
- ADD SI,[BP+X+16] ; ADD IN THE OFFSET FOR THE NEXT LINE THE CHUNK TO COPY
- DEC WORD PTR [BP+X+14] ; DECREMENT THE NUMBER OF LINES TO COPY
- JNZ CHUNKLOOPW ; CONTINUE TO BLAST OUT LINES UNTIL WE HAVE DONE THEM ALL
- JMP SHORT ENDCHUNK
-
- CHUNKLOOPB:
- PUSH SI ; PUSH THE SOURCE INDEX
- PUSH DI ; PUSH THE DESTINATION INDEX
- MOV CX,[BP+X+12] ; GET THE COUNT OF BYTES TO MOVE
- REP MOVSB ; MOV THE MEMORY
-
- POP DI
- ADD DI,320 ; ADD IN THE WIDTH OF THE SCREEN
- POP SI
- ADD SI,[BP+X+16] ; ADD IN THE OFFSET FOR THE NEXT LINE THE CHUNK TO COPY
- DEC WORD PTR [BP+X+14] ; DECREMENT THE NUMBER OF LINES TO COPY
- JNZ CHUNKLOOPB ; CONTINUE TO BLAST OUT LINES UNTIL WE HAVE DONE THEM ALL
-
- ENDCHUNK:
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _VGACHUNK ENDP
-
- ; draw a point on vga screen
- ;
- ; usage : vgapt(x,y,color)
- ;
- _VGAPT PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH DI
-
- ;
- ; READY TO PUT THE POINT
- ;
- POKBANK:
- MOV AX,[BP+X+2] ; GET THE Y VALUE
- MOV BX,[BP+X] ; GET THE X VALUE
- CALL PIXELADDR13 ; CALCULATE THE PIXEL ADDRESS
- MOV DI,BX ; PREPARE FOR MOVS
- MOV AL,[BP+X+4] ; GET COLOR TO PUT THERE
-
- STOSB ; PUT IT
-
- POP DI
- POP ES
- POP DS
- POP BP
- RET
- _VGAPT ENDP
-
- _VGAMODE PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV AX,[BP+X] ;GET SCREEN MODE TO SWITCH TO
- XOR AH,AH ;ENTER VIDEO_IO ROUTINE (SET MODE=0)
- INT 10H ;VIDEO INTERUPT
-
- POP ES
- POP DS
- POP BP
- RET
- _VGAMODE ENDP
-
-
- _VGAOFF PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV DX,03C4H ;ADDRESS OF THE SEQ CONTROLLER
- MOV AL,01H ;INDEX OF THE CLOCKING MODE REGISTER
- OUT DX,AL ;SET UP TO READ THE CLOCKING MODE REGISTER
- MOV DX,03C5H ;ADDRESS TO READ FROM
- IN AL,DX ;GET THE CLOCKING MODE REGISTER
- OR AL,20H ;MASK OFF THE SCREEN ENABLE BIT
- MOV BL,AL ;KEEP THAT AROUND
- MOV DX,03C4H ;ADDRESS OF THE SEQ CONTROLLER
- MOV AL,01H ;INDEX OF THE CLOCKING REGISTER
- OUT DX,AL ;SET UP TO WRITE BACK THE CLOCKING MODE REGISTER
- INC DX ;SET TO ADDRESS TO WRITE TO
- MOV AL,BL ;GET BACK THE PROPER VALUE
- OUT DX,AL ;TURNS OFF THE VGA SCREEN
-
- POP ES
- POP DS
- POP BP
- RET
- _VGAOFF ENDP
-
- _VGAON PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
-
- MOV DX,03C4H ;ADDRESS OF THE SEQ CONTROLLER
- MOV AL,01H ;INDEX OF THE CLOCKING MODE REGISTER
- OUT DX,AL ;SET UP TO READ THE CLOCKING MODE REGISTER
- INC DX ;ADDRESS TO READ FROM
- IN AL,DX ;GET THE CLOCKING MODE REGISTER
- AND AL,0DFH ;TURN ON THE SCREEN ENABLE BIT
- MOV BL,AL ;KEEP THAT AROUND
- MOV DX,03C4H ;ADDRESS OF THE SEQ CONTROLLER
- MOV AL,01H ;INDEX OF THE CLOCKING REGISTER
- OUT DX,AL ;SET UP TO WRITE BACK THE CLOCKING MODE REGISTER
- INC DX ;SET TO ADDRESS TO WRITE TO
- MOV AL,BL ;GET BACK THE PROPER VALUE
- OUT DX,AL ;TURNS ON THE VGA SCREEN
-
- POP ES
- POP DS
- POP BP
- RET
- _VGAON ENDP
-
- ;
- ; showpalv(&palstore,pal_xoff,pal_yoff);
- ;
- _SHOWPALV PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
-
- MOV AX,[BP+X] ;GET OFFSET OF ARRAY
- MOV DI,AX
- MOV AX,[BP+X+2] ;GET SEGMENT OF STORAGE ARRAY
- MOV ES,AX
-
- MOV AX,[BP+X+6] ;GET LINE TO START PALETTE ON
- MOV DX,320 ;GET THE LINE LENGTH
- MUL DX ;GET THE OFFSET INTO THE SCREEN
- ADD AX,[BP+X+4] ;ADD IN THE X OFFSET
- JNC NO_ROLLOVER ;ADDITION DIDN'T CARRY
- INC DX ;INCREMENT THE DX REGISTER ON A CARRY
- NO_ROLLOVER:
- MOV SI,AX ;KEEP TRACK OF THE OFFSET
- MOV BX,SI ;IN TWO PLACES
- MOV AX,320 ;GET THE LINE LENGTH
- MOV DX,8 ;GET THE NUMBER OF LINES
- MUL DX ;GET THE NUMBER OF BYTES TO COPY
- MOV CX,AX ;MOVE INTO COUNTER
- MOV AX,0A000H
- MOV DS,AX ;GET THE SEGMENT FOR THE SOURCE
- ZIP:
- REP MOVSB ;COPY THAT SECTION OF SCREEN
-
- MOV CH,0 ;THE NUMBER OF LINES COPIED SO FAR
- MOV CL,00 ;THE NUMBER OF PIXELS
- TOP1:
- MOV SI,BX ;GET THE CORRECT OFFSET TO BE COPIED TO
- MOV AX,0A000H
- MOV ES,AX ;GET THE SEGMENT TO BE COPIED TO
- TOP2:
- MOV ES:[SI],CL ;COPY ACROSS THE SCREEN INCREMENTING VALUES
- INC SI ;MOVE TO NEXT PIXEL
- INC CL ;INCREMENT COUNTER
- JNE TOP2 ;IF COUNTER NOT EQUAL TO ZERO THEN COPY AGAIN
-
- ADD BX,320 ;MOVE DOWN TO NEXT LINE
- INC CH ;INCREMENT THE LINE COUNTER
- CMP CH,8 ;CHECK IF ALL THE LINES ARE DONE
- JNE TOP1 ;IF LINE COUNT <8 THEN COPY ANOTHER LINE
-
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _SHOWPALV ENDP
-
- ;
- ; nopalv(&palstore,pal_xoff,pal_yoff);
- ;
- _NOPALV PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- MOV AX,[BP+X] ;GET OFFSET OF ARRAY
- MOV SI,AX
- MOV AX,[BP+X+2] ;GET SEGMENT OF STORAGE ARRAY
- MOV DS,AX
-
- MOV AX,[BP+X+6] ;GET LINE TO COPY SCREEN BACK ONTO
- MOV DX,320 ;GET THE LINE LENGTH
- MUL DX ;GET THE OFFSET INTO THE SCREEN
- ADD AX,[BP+X+4] ;ADD IN THE X OFFSET
- JNC NO_ROLL2 ;ADDITION DIDN'T CARRY
- INC DX ;INCREMENT THE DX REGISTER ON A CARRY
- NO_ROLL2:
- MOV DI,AX ;KEEP TRACK OF THE OFFSET
- MOV AX,320 ;GET THE LINE LENGTH
- MOV DX,8 ;GET THE NUMBER OF LINES
- MUL DX ;GET THE NUMBER OF BYTES TO COPY
- MOV CX,AX ;MOVE INTO COUNTER
- MOV AX,0A000H
- MOV ES,AX ;GET THE SEGMENT FOR THE SOURCE
- ZOOM:
- REP MOVSB ;COPY THAT SECTION OF SCREEN
-
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _NOPALV ENDP
-
- ;
- ; Invert A BOX ON THE SCREEN
- ;
- ; usage : outlinev(x1,y1,x2,y2)
- ;
- _OUTLINEV PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- MOV AX,[BP+X+2] ; GET FIRST Y VALUE
- CMP AX,[BP+X+6] ; COMPARE WITH THE SECOND Y - VALUE
- JLE CHECKX ; OK ORDER GOTO CHECKING THE X VALUES
- MOV CX,AX ; SWAP THE TWO VALUES
- MOV AX,[BP+X+6] ;
- MOV [BP+X+2],AX ;
- MOV AX,CX ;
- MOV [BP+X+6],AX ;
- CHECKX:
- MOV AX,[BP+X] ; GET FIRST X VALUE
- CMP AX,[BP+X+4] ; COMPARE WITH THE SECOND X - VALUE
- JLE MAKELEN ; OK ORDER GOTO COMPUTING THE LENGTHS
- MOV CX,AX ; SWAP THE TWO VALUES
- MOV AX,[BP+X+4] ;
- MOV [BP+X],AX ;
- MOV AX,CX ;
- MOV [BP+X+4],AX ;
- MAKELEN: ; COMPUTE THE X AND Y WIDTHS FOR 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 FIND THE LENGTH
- ADD AX,1 ;
- MOV [BP+X+4],AX ; STORE IT IN THE OLD LOCATION FOR THE 2ND X VALUE
- MOV AX,[BP+X+6] ; GET THE LARGER OF THE TWO Y VALUES
- SUB AX,[BP+X+2] ; SUBTRACT THE SMALLER VALUE TO FIND THE LENGTH
- SUB AX,1 ; SUBTRACT TWO FOR THE TOP AND BOTTOM EDGES
- CMP AX,0 ; CHECK IF IT IS LESS THAN ZERO
- JG POSITIVE ; JUMP AROUND ZEROING THE ACC.
- MOV AX,0
- POSITIVE:
- MOV [BP+X+6],AX ; STORE IT IN THE OLD LOCATION FOR THE 2ND Y VALUE
- MOV AX,320 ; COMPUTE THE VALUE TO ADD TO THE DI FOR COMPLETE WRAPAROUND
- SUB AX,[BP+X+4] ;
- MOV SI,AX ; KEEP TRACK OF IT
-
- ; MOV AX,0A000H ; DATA BUFFER
- ; MOV ES,AX
- ;
- MOV AX,[BP+X+2] ; GET THE Y VALUE
- MOV BX,[BP+X] ; GET THE X VALUE
- CALL PIXELADDR13 ; CALCULATE THE PIXEL ADDRESS
- MOV DI,BX ; PREPARE FOR MOVS
-
- MOV CX,[BP+X+4] ; HOW MANY BYTES?
- BLASTA:
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT THE VALUE THERE
- MOV ES:[DI],AL ; REPLACE THE VALUE
- INC DI ; INCREMENT TO NEXT POSITION
- LOOP BLASTA ; LOOP UNTIL ALL HAVE BEEN DONE
-
- ADD DI,SI ; MOVE OVER TO THE BEGINNING OF THE NEXT LINE
- MOV CX,[BP+X+6] ; COUNT VALUE FOR THE NEXT SERIES
- CMP CX,0 ; CHECK FOR NO LINES IN BETWEEN
- JLE BLAST2A ; JUMP AROUND PUTTING THE LINES IN BETWEEN
- BLAST2:
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT IT
- MOV ES:[DI],AL ; REPLACE THE INVERTED VALUE
- ADD DI,[BP+X+4] ; GO TO THE LAST VALUE TO INVERT ON THAT LINE
- SUB DI,1 ;
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT IT
- MOV ES:[DI],AL ; REPLACE THE INVERTED VALUE
- ADD DI,SI ; GET THE VALUE FOR THE BEGINNING OF THE NEXT LINE
- INC DI ;
- LOOP BLAST2 ; DO THE NEXT LINE
-
- BLAST2A:
- MOV CX,[BP+X+4] ; PREPARE FOR LAST LINE
- BLAST3:
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT THE VALUE THERE
- MOV ES:[DI],AL ; REPLACE THE VALUE
- INC DI ; INCREMENT TO NEXT POSITION
- LOOP BLAST3 ; LOOP UNTIL ALL HAVE BEEN DONE
-
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _OUTLINEV ENDP
- ;
- ; Draw a 4x4 ball on the vga screen
- ;
- ; usage : ball(x,y)
- ;
- _BALL PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH DI
-
- MOV AX,[BP+X+2] ; GET THE Y VALUE
- MOV BX,[BP+X] ; GET THE X VALUE
- CALL PIXELADDR13 ; CALCULATE THE PIXEL ADDRESS
- MOV DI,BX ; PREPARE FOR MOVS
-
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT IT
- MOV ES:[DI],AL ; REPLACE THE VALUE
- INC DI ; MOVE OVER ONE BYTE
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT IT
- MOV ES:[DI],AL ; REPLACE THE VALUE
-
- ADD DI,318 ; MOVE TO THE NEXT LINE
- MOV CX,4 ; HOW MANY BYTES?
- BLASTB:
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT THE VALUE THERE
- MOV ES:[DI],AL ; REPLACE THE VALUE
- INC DI ; INCREMENT TO NEXT POSITION
- LOOP BLASTB ; LOOP UNTIL ALL HAVE BEEN DONE
-
- MOV CX,4 ; COUNT VALUE FOR THE NEXT SERIES
- ADD DI,316 ; MOVE OVER TO THE BEGINNING OF THE NEXT LINE
- BLASTC:
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT IT
- MOV ES:[DI],AL ; REPLACE THE INVERTED VALUE
- INC DI ;
- LOOP BLASTC ; DO THE NEXT LINE
-
- ADD DI,317 ; MOVE ONE BYTE OVER INTO THE NEXT LINE
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT IT
- MOV ES:[DI],AL ; REPLACE THE VALUE
- INC DI ; MOVE OVER ONE BYTE
- MOV AL,ES:[DI] ; GET THE VALUE TO INVERT
- NOT AL ; INVERT IT
- MOV ES:[DI],AL ; REPLACE THE VALUE
-
- POP DI
- POP ES
- POP DS
- POP BP
- RET
- _BALL ENDP
-
- ;
- ; Draw a block on the vga screen
- ;
- ; usage : vgablock(&block,x,y,xmax,ymax)
- ;
- X_SIZE DW ? ; X WIDTH OF THE BLOCK
- X_WRAP DW ? ; THE NUMBER OF BYTES TO WRAP AROUND THE SCREEN
- Y_SIZE DW ? ; THE Y HEIGHT OF THE BLOCK
- _VGABLOCK PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ; MOV AX,0A000H ; DATA BUFFER
- ; MOV ES,AX
-
- MOV AX,[BP+X+8] ; GET THE X SIZE
- MOV X_SIZE,AX ; STORE THE X SIZE
-
- MOV AX,320 ; GET THE SCREEN SIZE
- SUB AX,X_SIZE ; CALCULATE THE X_WRAP VALUE
- MOV X_WRAP,AX ; STORE THE X_WRAP VALUE
-
- MOV AX,[BP+X+10]; GET THE Y SIZE
- MOV Y_SIZE,AX ; STORE THE Y SIZE
- MOV AX,[BP+X+6] ; GET THE Y VALUE
- MOV BX,[BP+X+4] ; GET THE X VALUE
- CALL PIXELADDR13 ; CALCULATE THE PIXEL OFFSET
- MOV DI,BX ; PREPARE FOR MOVS
-
- MOV AX,[BP+X] ; GET THE OFFSET OF THE BLOCK
- MOV SI,AX ; STORE THE OFFSET OF THE ARRAY
- MOV AX,[BP+X+2] ; GET THE SEGMENT OF THE ARRAY
- MOV DS,AX ; STORE THE SEGMENT
- BLASTBLOCK:
- MOV CX,X_SIZE ; GET THE NUMBER OF BYTES TO MOVE
- REP MOVSB ; PUT A HORIZONTAL LINE OF THE BLOCK ON THE SCREEN
-
- ADD DI,X_WRAP ; MOVE THE DESTINATION POINTER TO THE BEGINNING OF THE NEXT BLOCK
- DEC Y_SIZE ; DECREMENT THE VERTICAL COUNTER
- JG BLASTBLOCK ; IF THE COUNTER IS NOT ZERO THEN DO ANOTHER LINE
-
- POP DI
- POP SI
- POP ES
- POP DS
- POP BP
- RET
- _VGABLOCK ENDP
-
- ;
- ; Inverse a block on the vga screen
- ;
- ; usage : vgablock(x0,y0,width,height)
- ;
- _INVERSEV PROC FAR
- PUSH BP
- MOV BP,SP
- PUSH DS
- PUSH ES
- PUSH DI
-
- MOV BX,[BP+X+4] ; GET THE X SIZE
- MOV X_SIZE,BX ; STORE THE X SIZE
-
- MOV AX,320 ; GET THE SCREEN SIZE
- SUB AX,BX ; CALCULATE THE X_WRAP VALUE
- MOV X_WRAP,AX ; STORE THE X_WRAP VALUE
-
- MOV AX,[BP+X+6] ; GET THE Y SIZE
- MOV Y_SIZE,AX ; STORE THE Y SIZE
- ;
- MOV AX,[BP+X+2]; GET THE Y VALUE
- MOV BX,[BP+X] ; GET THE X VALUE
- CALL PIXELADDR13 ; CALCULATE THE PIXEL ADDRESS (RETURNS WITH ES:VIDEO BUFF SEG, BX:OFFSET)
- MOV DI,BX ; PREPARE FOR MOVS
-
- INVERSEBLOCK:
- MOV CX,X_SIZE ; GET THE NUMBER OF BYTES TO MOVE
- INVERSELINE:
- MOV AL,BYTE PTR ES:[DI] ; GET THE BYTE TO INVERSE
- NOT AL ; INVERSE IT
- MOV BYTE PTR ES:[DI],AL ; PUT THE BYTE BACK
- INC DI
- LOOP INVERSELINE
-
- ADD DI,X_WRAP ; MOVE THE DESTINATION POINTER TO THE BEGINNING OF THE NEXT BLOCK
- DEC Y_SIZE ; DECREMENT THE VERTICAL COUNTER
- JG INVERSEBLOCK ; IF THE COUNTER IS NOT ZERO THEN DO ANOTHER LINE
-
- POP DI
- POP ES
- POP DS
- POP BP
- RET
- _INVERSEV ENDP
-
- ; CALLER MICROSOFT C
- ;
- ; VOID(_LINE13(X1,Y1,X2,Y2,N);
- ;
- ; INT X1,Y1,X2,Y2; /* PIXEL COOR. */
- ;
- ; INT N; /* PIXEL VALUE */
- ;
-
- ARGX1 EQU WORD PTR [BP+6] ; STACK FRAME ADDRESSING
- ARGY1 EQU WORD PTR [BP+8]
- ARGX2 EQU WORD PTR [BP+10]
- ARGY2 EQU WORD PTR [BP+12]
- ARGN EQU BYTE PTR [BP+14]
- VARINCR1 EQU WORD PTR [BP-6]
- VARINCR2 EQU WORD PTR [BP-8]
- VARROUTINE EQU WORD PTR [BP-10]
-
- BYTESPERLINE EQU 320
-
- _LINE13 PROC FAR
- PUSH BP
- MOV BP,SP
- SUB SP,16H
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ; CHECK FOR VERTICAL LINE
- MOV SI,BYTESPERLINE
-
- MOV CX,ARGX2
- SUB CX,ARGX1
- JZ VERT_LINE13
-
- ; 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 HORIZ_LINE13
-
- JNS L03
-
- NEG BX
- NEG SI
- ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
- L03:
- PUSH SI
- MOV VARROUTINE,OFFSET LOSLOPE_LINE13
- CMP BX,CX
- JLE L04
- MOV VARROUTINE,OFFSET HISLOPE_LINE13
- 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 PIXELADDR13
-
- MOV DI,BX
-
- POP CX
- INC CX
-
- POP BX
- JMP VARROUTINE
-
- ;ROUTINE FOR VERTICAL LINES
- VERT_LINE13:
- 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 PIXELADDR13
- POP CX
- MOV DI,BX
- DEC SI
-
- MOV AL,ARGN
- L32:
- STOSB
- ADD DI,SI
- LOOP L32
- JMP LEXIT
-
- ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
- HORIZ_LINE13:
- PUSH CX
- MOV AX,ARGY1
- MOV BX,ARGX1
- CALL PIXELADDR13
- MOV DI,BX
-
- POP CX
- INC CX
-
- MOV AL,ARGN
-
- REP STOSB
- JMP LEXIT
-
- ;ROUTINE FOR DY<=DX (SLOPE<=1)
- LOSLOPE_LINE13:
- MOV AL,ARGN
- L11:
- STOSB
- OR SI,SI
- JNS L12
- ADD SI,VARINCR1
- LOOP L11
- JMP SHORT LEXIT
- L12:
- ADD SI,VARINCR2
- ADD DI,BX
- LOOP L11
- JMP SHORT LEXIT
-
- ;ROUTINE FOR DY>DX (SLOPE>1)
- HISLOPE_LINE13:
- MOV AL,ARGN
- L21:
- STOSB
- ADD DI,BX
- L22:
- OR SI,SI
- JNS L23
- ADD SI,VARINCR1
- DEC DI
- LOOP L21
- JMP SHORT LEXIT
- L23:
- ADD SI,VARINCR2
- LOOP L21
-
- LEXIT:
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
- _LINE13 ENDP
-
- _INVERT13 PROC FAR
- PUSH BP
- MOV BP,SP
- SUB SP,16H
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ; CHECK FOR VERTICAL LINE
- MOV SI,BYTESPERLINE
-
- MOV CX,ARGX2
- SUB CX,ARGX1
- JZ IVERT_LINE13
-
- ; 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 IHORIZ_LINE13
-
- JNS IL03
-
- NEG BX
- NEG SI
- ;SELECT APPROPRIATE ROUTINE FOR SLOPE OF LINE
- IL03:
- PUSH SI
- MOV VARROUTINE,OFFSET ILOSLOPE_LINE13
- CMP BX,CX
- JLE IL04
- MOV VARROUTINE,OFFSET IHISLOPE_LINE13
- 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 PIXELADDR13
-
- MOV DI,BX
-
- POP CX
- INC CX
-
- POP BX
- JMP VARROUTINE
-
- ;ROUTINE FOR VERTICAL LINES
- IVERT_LINE13:
- 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 PIXELADDR13
- POP CX
- MOV DI,BX
- DEC SI
-
- MOV AL,0FFH
- IL32:
- XOR ES:[DI],AL
- INC DI
- ; STOSB
- ADD DI,SI
- LOOP IL32
- JMP ILEXIT
-
- ;ROUTINE FOR HORIZONTAL LINES (SLOPE=0)
- IHORIZ_LINE13:
- PUSH CX
- MOV AX,ARGY1
- MOV BX,ARGX1
- CALL PIXELADDR13
- MOV DI,BX
-
- POP CX
- INC CX
- MOV AL,0ffh
-
- IL51:
- XOR ES:[DI],AL
- INC DI
- LOOP IL51
- ;REP STOSB
- JMP ILEXIT
-
- ;ROUTINE FOR DY<=DX (SLOPE<=1)
- ILOSLOPE_LINE13:
- MOV AL,0ffh
- IL11:
- XOR ES:[DI],AL
- INC DI
- ; STOSB
- OR SI,SI
- JNS IL12
- ADD SI,VARINCR1
- LOOP IL11
- JMP SHORT ILEXIT
- IL12:
- ADD SI,VARINCR2
- ADD DI,BX
- LOOP IL11
- JMP SHORT ILEXIT
-
- ;ROUTINE FOR DY>DX (SLOPE>1)
- IHISLOPE_LINE13:
- MOV AL,0ffh
- IL21:
- XOR ES:[DI],AL
- INC DI
- ; STOSB
- ADD DI,BX
- IL22:
- OR SI,SI
- JNS IL23
- ADD SI,VARINCR1
- DEC DI
- LOOP IL21
- JMP SHORT ILEXIT
- IL23:
- ADD SI,VARINCR2
- LOOP IL21
-
- ILEXIT:
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
- _INVERT13 ENDP
-
- ;NAME: _CIRCLE13
- ; _CIRCLE13(XC,YC,A,B,N)
- ;
- 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]
-
- BYTESPERLINE EQU 320
-
- _CIRCLE13 PROC FAR
- PUSH BP
- MOV BP,SP
- SUB SP,50
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
- ;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 PIXELADDR13
-
- 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:
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
- _CIRCLE13 ENDP
-
- ;NAME: CIRCLE13
- ; CIRCLE13(XC,YC,A,B,N)
- ;
- 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]
-
- RMWBITS EQU 00H
- BYTESPERLINE EQU 320
-
- _INCIRC13 PROC FAR
- PUSH BP
- MOV BP,SP
- SUB SP,50
- PUSH DS
- PUSH ES
- PUSH SI
- PUSH DI
-
-
- ;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 PIXELADDR13
-
- 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 INVERT4PIXELS
- 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 INVERT4PIXELS
- 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:
- POP DI
- POP SI
- POP ES
- POP DS
- MOV SP,BP
- POP BP
- RET
-
- _INCIRC13 ENDP
-
- SET4PIXELS PROC NEAR
- PUSH AX
- PUSH BX
- PUSH DX
- MOV AL,ARGN ; GET THE COLOR VALUE
- XOR BX,BX
- TEST CH,CH
- JZ C30
- MOV BX,BYTESPERLINE
- NEG BX
- C30:
-
- ;PIXELS AT (XC-X,YC+Y) AND XC-X,YC-Y)
-
- XOR SI,SI
- TEST CL,CL
- JZ C31
- MOV SI,-1
- C31:
-
- MOV DI,SI
- ADD SI,ULADDR
- ADD SI,BX
- ADD DI,LLADDR
- SUB DI,BX
- MOV ULADDR,SI
- MOV LLADDR,DI
- MOV ES:[SI],AL
- MOV ES:[DI],AL
-
- ;PIXELS AT (XC+X,YC+Y) AND (XC+X,YC+Y)
-
- XOR SI,SI
- TEST CL,CL
- JZ C32
- MOV SI,1
- C32:
- MOV DI,SI
-
- ADD SI,URADDR
- ADD SI,BX
- ADD DI,LRADDR
- SUB DI,BX
-
- MOV URADDR,SI
- MOV LRADDR,DI
-
- MOV ES:[SI],AL
- MOV ES:[DI],AL
-
- POP DX
- POP BX
- POP AX
- RET
-
- SET4PIXELS ENDP
-
- INVERT4PIXELS PROC NEAR
- PUSH AX
- PUSH BX
- PUSH DX
- XOR BX,BX
- TEST CH,CH
- JZ IC30
- MOV BX,BYTESPERLINE
- NEG BX
- IC30:
-
- ;PIXELS AT (XC-X,YC+Y) AND XC-X,YC-Y)
-
- XOR SI,SI
- TEST CL,CL
- JZ IC31
- MOV SI,-1
- IC31:
-
- MOV DI,SI
- ADD SI,ULADDR
- ADD SI,BX
- ADD DI,LLADDR
- SUB DI,BX
- MOV ULADDR,SI
- MOV LLADDR,DI
- MOV AL,ES:[SI]
- XOR AL,0FFH
- MOV ES:[SI],AL
- MOV AL,ES:[DI]
- XOR AL,0FFH
- MOV ES:[DI],AL
-
- ;PIXELS AT (XC+X,YC+Y) AND (XC+X,YC+Y)
-
- XOR SI,SI
- TEST CL,CL
- JZ IC32
- MOV SI,1
- IC32:
- MOV DI,SI
-
- ADD SI,URADDR
- ADD SI,BX
- ADD DI,LRADDR
- SUB DI,BX
-
- MOV URADDR,SI
- MOV LRADDR,DI
-
- MOV AL,ES:[SI]
- XOR AL,0FFH
- MOV ES:[SI],AL
- MOV AL,ES:[DI]
- XOR AL,0FFH
- MOV ES:[DI],AL
-
- POP DX
- POP BX
- POP AX
- RET
-
- INVERT4PIXELS 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
-