home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
asmutil
/
bluebook.zip
/
GRAPHICS.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-05-08
|
24KB
|
894 lines
COMMENT ~
GRAPHICS.ASM -- Graphic Plotting Procedures
From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
by Christopher L. Morgan
Copyright (C) 1984 by The Waite Group, Inc.
Contents:
---------
CLS -- Clear the screen
GET_COLOR -- Get the color of a point on the med res color screen
GMSG_OUT -- Plot a string
PAINT -- Fill an area with specified color
RCHAR -- Plot a raster character
SCHAR -- Plot a stroke character
SET_BOX -- Fill a rectangular box with specified color
SET_LIN -- Draw a line
SET_PT -- Plot a point
XOR_BOX -- Fill a rectangular box using XOR
XOR_PT -- Plot a point using XOR
>>>>> See GRAPHICS.DOC for complete descriptions of these routines. <<<<<
------------------------------------------------------------------------------
These variables need to be defined in the source code calling the GRAPHICS
routines. See GRAPHICS.DOC. ~
EXTRN CBYTES:BYTE, COLOR:WORD, DELDE:WORD, DELDX:WORD
EXTRN DELDY:WORD, DELP:WORD, DELS:WORD, DELSE:WORD
EXTRN DELSX:WORD, DELSY:WORD, FONT:BYTE, PAINT_STAK:WORD
EXTRN X0:WORD, X1:WORD, X2:WORD, XMAGN:BYTE
EXTRN XMSG:WORD, Y0:WORD, Y1:WORD, Y2:WORD
EXTRN YMAGN:BYTE, YMSG:WORD
;______________________________________________________________________________
;These tables would be better included in the source code calling the
; GRAPHICS routines, and then commented out here. See GRAPHICS.DOC
;
DATAS SEGMENT PUBLIC
CTABLE DW 0003FH,0403FH,0803FH,0C03FH
DW 000CFH,010CFH,020CFH,030CFH
DW 000F3H,004F3H,008F3H,00CF3H
DW 000FCH,001FCH,002FCH,003FCH
PTABLE DW 32 DUP(?) ;A dummy (See GRAPHICS.DOC)
XTABLE DW 0FFC0H,0FFF0H,0FFFCH,0FFFFH
DW 03FC0H,03FF0H,03FFCH,03FFFH
DW 00FC0H,00FF0H,00FFCH,00FFFH
DW 003C0H,003F0H,003FCH,003FFH
DATAS ENDS
;______________________________________________________________________________
;
CODES SEGMENT
PUBLIC CLS,SET_PT,XOR_PT,GET_COLOR,SET_BOX,XOR_BOX
PUBLIC SET_LIN,SCHAR,RCHAR,GMSG_OUT,PAINT
ASSUME CS:CODES,DS:DATAS
;____________________________I/O ROUTINES______________________________________
;Routine to clear the graphics screen
;
CLS PROC FAR
PUSH CX ;Save registers
PUSH AX
;
;Set up the registers
MOV CX,2000H ;Word count of whole screen
MOV AX,0 ;Zero pattern for the screen
MOV DI,AX ;Set starting address
CLD ;Go in forward direction
;
;Clear the screen with a single string operation
REP STOSW ;This clears the screen
;
POP AX ;Restore registers
POP CX
RET
CLS ENDP
;------------------------------------------------------------------------------
;Routine to plot a point on medium resolution color screen
;
SET_PT PROC FAR
PUSH BX ;Save registers
PUSH SI
PUSH AX
;
;Multiply Y-coord by bytes/row & adjust for even/odd lines
MOV AX,DI ;Get Y-coordinate into part
MOV AH,AL ; and into high part
AND AX,01FEH ;Mask off unwanted parts
SAL AX,1 ;Times 4
SAL AX,1 ;Times 8
SAL AX,1 ;Times 16
MOV BX,AX ;Goes into address
AND BH,7 ; without adjustment
SAL AX,1 ;Times 32
SAL AX,1 ;Times 64
ADD BX,AX ;Addr gets Y-coord times 80
;
;Add X-coordinate to address
MOV AX,SI ;Get X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
ADD BX,AX ;Here is the address
;
;Compute the rotated mask and color
AND SI,3 ;Just pixel position into index
SAL SI,1 ;Index times 2
SAL SI,1 ;Index times 4
ADD SI,DX ;4 * pixel position + color
SAL SI,1 ;8 * pixel position + 2 * color
MOV AX,CTABLE[SI] ;Look up rotated color & mask
;
;Insert the color into the video byte
AND AL,ES:[BX] ;Get old byte & remove old pixel
OR AL,AH ;Insert new color
MOV ES:[BX],AL ;Put the byte back
;
POP AX ;Restore registers
POP SI
POP BX
RET
SET_PT ENDP
;------------------------------------------------------------------------------
;Routine to XOR a point onto medium resolution color screen
;
XOR_PT PROC FAR
PUSH BX ;Save registers
PUSH SI
PUSH AX
;
;Multiply Y-coord by bytes/row & adjust for even/odd lines
MOV AX,DI ;Get Y-coordinate into part
MOV AH,AL ; and into high part
AND AX,01FEH ;Mask off unwanted parts
SAL AX,1 ;Times 4
SAL AX,1 ;Times 8
SAL AX,1 ;Times 16
MOV BX,AX ;Goes into address
AND BH,7 ; without adjustment
SAL AX,1 ;Times 32
SAL AX,1 ;Times 64
ADD BX,AX ;Addr gets Y-coord times 80
;
;Add X-coordinate to address
MOV AX,SI ;Get X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
ADD BX,AX ;Here is the address
;
;Compute the mask for color and use it
AND SI,3 ;Just the bit count into index
SAL SI,1 ;Index times 2
SAL SI,1 ;Index times 4
ADD SI,DX ;4 * pixel position + color
SAL SI,1 ;8 * pixel position + 2 * color
MOV AX,CTABLE[SI] ;Look up rotated color & mask
XOR ES:[BX],AH ;XOR the byte with the color
;
POP AX ;Restore registers
POP SI
POP BX
RET
XOR_PT ENDP
;------------------------------------------------------------------------------
;Routine to return color of a point on med res color screen
;
GET_COLOR PROC FAR
PUSH BX ;Save registers
PUSH CX
;
;Multiply Y-coord by bytes/row & adjust for even/odd lines
MOV AX,DI ;Get Y-coordinate into part
MOV AH,AL ; and into high part
AND AX,01FEH ;Mask off unwanted parts
SAL AX,1 ;Times 4
SAL AX,1 ;Times 8
SAL AX,1 ;Times 16
MOV BX,AX ;Goes into address
AND BH,7 ; without adjustment
SAL AX,1 ;Times 32
SAL AX,1 ;Times 64
ADD BX,AX ;Addr gets Y-coord times 80
;
;Add X-coordinate to address
MOV AX,SI ;Get X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
ADD BX,AX ;Here is the address
;
;Compute the position of the pixel in the byte
MOV CX,SI ;Use X-coord to determine count
AND CX,3 ;Just the bit count
INC CX ; plus one
SAL CX,1 ;2 bits/pixel
;
;Get the byte and rotate into place
MOV AL,ES:[BX] ;Get old byte
ROL AL,CL ;Rotate left this many times
AND AX,3 ;Just the pixel color
;
POP CX ;Restore registers
POP BX
RET
GET_COLOR ENDP
;------------------------------------------------------------------------------
;Routine to set & fill a rectangular box
;
SET_BOX PROC FAR
PUSH SI ;Save registers
PUSH DI
PUSH DX
PUSH BX
PUSH CX
PUSH AX
;
;Determine byte position for start
;
;Get Y contribution
MOV AX,Y1 ;Get starting Y-coordinate
MOV AH,AL ;Replicate for odd/even bank
AND AX,01FEH ;Mask off unwanted parts
SAL AX,1 ;Times 4
SAL AX,1 ;Times 8
SAL AX,1 ;Times 16
MOV DI,AX ;Addr gets Y-coord * 16
AND DI,7FFH ;Not the odd/even bit
SAL AX,1 ;Times 32
SAL AX,1 ;Times 64
ADD DI,AX ;Addr gets Y-coord * 80
;
;Add in X contribution
MOV AX,X1 ;Get X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
ADD DI,AX ;Beginning of offset
;
;Count for outer loop
MOV CX,Y2 ;Ending Y-coordinate
SUB CX,Y1 ; minus starting Y-coordinate
INC CX ; plus one
;
;Count for inner loop
MOV SI,X2 ;Ending X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
MOV AX,X1 ;Starting X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
SUB SI,AX ;Take the difference
;Get the color
MOV BX,COLOR ;Get the color
AND BX,3 ;Just between 0 & 3
MOV DL,CBYTES[BX] ;Look up color pattern
;
;Determine mask for start & ending bytes
MOV BX,X1 ;Starting byte
AND BX,3 ;Just the pixel position
SAL BX,1 ;Times 2
SAL BX,1 ;Times 4
MOV AX,X2 ;Ending byte
AND AX,3 ;Just the pixel position
ADD BX,AX ;4 * starting + ending
SAL BX,1 ;8 * starting + 2 * ending
MOV BX,XTABLE[BX] ;Look up the masks
;
;Set up masked color bytes
MOV DH,DL ;Color for left bytes
MOV AH,DL ;Color for middle bytes
AND DX,BX ;Mask left & right color bytes
;
CLD ;Forward
SBOXLOOP:
PUSH CX ;Save count of outer loop
PUSH DI ;Save initial byte position
;
MOV CX,SI ;Count for inner loop
;
;Check for only one byte
MOV AL,BH ;Get the mask
JCXZ SBOXLOOP2 ;If ending byte coincides
;
;Color leftmost byte of the scan line
NOT AL ;Reverse the mask for clearing
AND AL,ES:[DI] ;Get byte frm mem & clr pixels
OR AL,DH ;Put color in place
STOSB ;Put byte in place
;
;Check for just two bytes
DEC CX ;Count the byte
JCXZ SBOXLOOP1 ;Done?
;
;Color middle bytes of the scan line
;
MOV AL,AH ;Color for middle bytes
REP STOSB ;Put middle bytes in place
;
;Handle rightmost byte of the scan line
;
;Come here if two or more bytes
SBOXLOOP1:
MOV AL,0FFH ;Set full mask
;
;In any case, come here to adjust the masks
SBOXLOOP2:
AND AL,BL ;Bring in right part of mask
AND DL,AL ;Clear left part of color
;
;Color the byte
NOT AL ;Reverse the mask for clearing
AND AL,ES:[DI] ;Get byte from mem & clr pixels
OR AL,DL ;Put pixels in the byte
STOSB ;Put byte back into video RAM
;
;Compute next scan line
POP DI ;Restor addr of lft side of box
TEST DI,2000H ;Odd or even line?
JZ SBOXLOOP3 ;Skip if even
ADD DI,80 ; else add 80 bytes/line
SBOXLOOP3:
XOR DI,2000H ;Change banks in any case
POP CX ;Restore outer loop count
LOOP SBOXLOOP ;Next scan line
;
POP AX ;Restore registers
POP CX
POP BX
POP DX
POP DI
POP SI
RET
SET_BOX ENDP
;------------------------------------------------------------------------------
;Routine to fill a rectangular box with color using XOR
;
XOR_BOX PROC FAR
PUSH SI ;Save registers
PUSH DI
PUSH DX
PUSH BX
PUSH CX
PUSH AX
;
;Determine byte position for start
;
;Get Y contribution
MOV AX,Y1 ;Get starting Y-coordinate
MOV AH,AL ;Replicate for odd/even bank
AND AX,01FEH ;Mask off unwanted parts
SAL AX,1 ;Times 4
SAL AX,1 ;Times 8
SAL AX,1 ;Times 16
MOV DI,AX ;Addr gets Y-coord * 16
AND DI,7FFH ;Not the odd/even bit
SAL AX,1 ;Times 32
SAL AX,1 ;Times 64
ADD DI,AX ;Addr gets Y-coord * 80
;
;Add in X contribution
MOV AX,X1 ;Get X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
ADD DI,AX ;Beginning of offset
;
;Count for outer loop
MOV CX,Y2 ;Ending Y-coordinate
SUB CX,Y1 ; minus starting Y-coordinate
INC CX ; plus one
;
;Count for inner loop
MOV SI,X2 ;Ending X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
MOV AX,X1 ;Starting X-coordinate
SAR AX,1 ;Divide
SAR AX,1 ; by 4
SUB SI,AX ;Take the difference
;
;Get the color
MOV BX,COLOR ;Get the color
AND BX,3 ;Just between 0 & 3
MOV DL,CBYTES[BX] ;Look up color pattern
;
;Determine mask for start and ending bytes
MOV BX,X1 ;Starting bytes
AND BX,3 ;Just the pixel position
SAL BX,1 ;Times 2
SAL BX,1 ;Times 4
MOV AX,X2 ;Ending byte
AND AX,3 ;Just the pixel position
ADD BX,AX ;4 * starting + ending
SAL BX,1 ;8 * starting + 2 * ending
MOV BX,XTABLE[BX] ;Look up the masks
;
;Set up masked color bytes
MOV DH,DL ;Color for left bytes
MOV AH,DL ;Color for middle bytes
AND DX,BX ;Mask left & right color bytes
;
CLD ;Forward
XBOXLOOP:
PUSH CX ;Save count of outer loop
PUSH DI ;Save initial byte position
;
MOV CX,SI ;Count for inner loop
;
;Check if only one byte in a scan line
MOV AL,BH ;Get the mask
JCXZ XBOXLOOP3 ;If ending byte coincides
;
;XOR the leftmost byte
XOR ES:[DI],DH ;XOR color into memory
INC DI ;Next byte
DEC CX ;Count it
JCXZ XBOXLOOP2 ;Done?
;
;XOR the middle bytes
XBOXLOOP1:
XOR ES:[DI],AH ;XOR color byte into memory
INC DI ;Next byte
LOOP XBOXLOOP1 ;Loop to get all the middle
;
;Handle rightmost byte
;
;Come here if two or more bytes
XBOXLOOP2:
MOV AL,0FFH ;Set full mask
;
;In any case, come here to adjust the masks
XBOXLOOP3:
AND AL,BL ;Bring in right part of mask
AND DL,AL ;Clear left part of color
;
;XOR the rightmost byte
XOR ES:[DI],DL ;XOR byte into memory
INC DI ;Next byte
;
POP DI ;Restore the leftmost address
TEST DI,2000H ;Odd or even line?
JZ XBOXLOOP4 ;Skip if even
ADD DI,80 ; else add 80 bytes/line
XBOXLOOP4:
XOR DI,2000H ;Change banks in any case
POP CX ;Restore outer loop count
LOOP XBOXLOOP ;Next scan line
;
POP AX ;Restore registers
POP CX
POP BX
POP DX
POP DI
POP SI
RET
XOR_BOX ENDP
;------------------------------------------------------------------------------
;Routine to draw a line
;
SET_LIN PROC FAR
PUSH BX ;Save registers
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH AX
;
;Set up X and Y updates
MOV SI,1 ;Start with positive 1 for
MOV DI,1 ; X and Y update
;
;Find |Y2-Y1|
MOV DX,Y2 ;Get Y2
SUB DX,Y1 ;Subtract Y1
JGE STOR_Y ;Skip if Y2-Y1 is not negative
NEG DI ;Mov in negative Y direction
NEG DX ;Absolute value of Y2-Y1
STOR_Y:
MOV DELDY,DI ;Store Y update for diag moves
;
;Find |X2-X1|
MOV CX,X2 ;Get X2
SUB CX,X1 ;Subtract X1
JGE STOR_X ;Skip if X2-X1 is not negative
NEG SI ;Mov in negative X direction
NEG CX ;Absolute value of X2-X1
STOR_X:
MOV DELDX,SI ;Store X update for diag moves
;
;Sort |Y2-Y1| & |X2-X1|
CMP CX,DX ;Compare DELS with DELP
JGE SET_DIAG ;Skip if straight move along X
MOV SI,0 ;If straight=vert, kill X updat
XCHG CX,DX ; & exchange differences
JMP STOR_DELSXY
SET_DIAG:
MOV DI,0 ;If straight=horz, kill Y updat
;
;Store DELS, DELP, DELSX, & DELSY
STOR_DELSXY:
MOV DELS,CX ;Change in straight direction
MOV DELP,DX ;Change in perpndic to straight
MOV DELSX,SI ;X update in straight direction
MOV DELSY,DI ;Y update in straight direction
;
;Get initial values for X & Y
MOV SI,X1 ;X-coordinate
MOV DI,Y1 ;Y-coordinate
;
;Compute initial value & increments for error function
MOV AX,DELP
SAL AX,1 ;2 * DELP
MOV DELSE,AX ;Change if straight move
;
SUB AX,CX ;2 * DELP - DELS
MOV BX,AX ;Initial value
;
SUB AX,CX ;2 * DELP - 2 * DELS
MOV DELDE,AX ;Change if diagonal move
;
;Adjust count
INC CX
;
;Set the color
MOV DX,COLOR ;Get the color
;
;Main loop structure
LIN_LOOP:
CALL SET_PT ;Plot the point
CMP BX,0 ;Determine straight or
JGE DIAGONAL ; diagonal move?
;
;Straight move case
STRAIGHT:
ADD SI,DELSX ;Update X
ADD DI,DELSY ;Update Y
ADD BX,DELSE ;Update error term
LOOP LIN_LOOP ;Next point
JMP LIN_XIT
;Diagonal move case
DIAGONAL:
ADD SI,DELDX ;Update X
ADD DI,DELDY ;Update Y
ADD BX,DELDE ;Update error term
LOOP LIN_LOOP ;Next point
LIN_XIT:
POP AX ;Restore registers
POP DI
POP SI
POP DX
POP CX
POP BX
RET
SET_LIN ENDP
;------------------------------------------------------------------------------
;Routine to plot a stroke character
;
SCHAR PROC FAR
PUSH SI ;Save registers
PUSH CX
PUSH AX
;
CBW ;Make ASCII code into 16-bit
SAL AX,1 ;Times 2
MOV SI,AX ;Into the index
MOV SI,PTABLE[SI] ;Look up the particular char
MOV AX,X0 ;X-coord of upper left corner
MOV X2,AX
MOV AX,Y0 ;Y-coord of upper left corner
MOV Y2,AX
;
;Run through the strokes
NEWSTROKE:
LODSB ;Get the code byte
CMP AL,1AH ;End of strokes?
JZ SCHAR_XIT
MOV DL,AL ;Save code
;
;Update X-coordinate of current position
MOV AX,X2 ;Old X-coordinate
MOV X1,AX ; gets pushed back
LODSB ;New X-coordinate
MOV CL,XMAGN ; times XMAGN
MUL CL ;Multiply
ADD AX,X0 ;Add to upper left corner
MOV X2,AX ; & put into current position
;
;Update Y-coordinate of current position
MOV AX,Y2 ;Old Y-coordinate
MOV Y1,AX ; gets pushed back
LODSB ;New Y-coordinate
MOV CL,YMAGN ; times YMAGN
MUL CL ;Multiply
ADD AX,Y0 ;Add to upper left corner
MOV Y2,AX ; & put into current position
;
CMP DL,'U' ;Pen up?
JE NEWSTROKE ;Skip, if so
;
CALL SET_LIN ;Draw the stroke
;
JMP NEWSTROKE ;Get next stroke
SCHAR_XIT:
POP AX ;Restore registers
POP CX
POP SI
RET
SCHAR ENDP
;------------------------------------------------------------------------------
;Routine to plot a raster character
;
RCHAR PROC FAR
PUSH SI ;Save registers
PUSH DX
PUSH CX
PUSH AX
;
;Look up pattern for character
CBW ;Make ASCII code into 16-bit
SAL AX,1 ;Times 2
SAL AX,1 ;Times 4
SAL AX,1 ;Times 8
ADD AX,0FA6EH + 7 ;Character table + pattern end
MOV SI,AX ;Here is the offset
;
MOV DX,DS ;Save old DS
MOV AX,0F000H ;Point DS to ROM segment
MOV DS,AX ;Here is the data segment
;
;Store the pattern on the stack
MOV CX,8 ;For a count of 8 bytes
STD ;Backward direction
RCHAR1:
LODSB ;Load
PUSH AX ;Push onto stack
LOOP RCHAR1
;
MOV DS,DX ;Restore data segment
;
;Get the starting point
MOV AX,X0 ;Get X-coordinate
MOV X1,AX
MOV AX,Y0 ;Get Y-coordinate
MOV Y1,AX
;
MOV CX,8 ;For a count of 8 rows
RCHAR2:
POP DX ;Get the next row
PUSH CX ;Save the count
;
MOV AL,YMAGN ;Vertical sizing
CBW
DEC AX ;One less
ADD AX,Y1 ;Add to new dot position
MOV Y2,AX
;
MOV CX,8 ;For a count of 8 dots
RCHAR3:
PUSH CX ;Save the count
;
MOV AL,XMAGN ;Horizontal sizing
CBW
DEC AX ;One less
ADD AX,X1 ;Add to new dot position
MOV X2,AX
;
TEST DL,80H ;Check the dot
JZ RCHAR4 ; & skip if zero
;
CALL SET_BOX ;Plot if a one
RCHAR4:
MOV AX,X2 ;Next column
INC AX ;One over from end of box
MOV X1,AX ;Into next dot position
ROL DL,1 ;Next dot from pattern
POP CX ;Restore count of dots
LOOP RCHAR3 ;Loop for next dot
;
MOV AX,X0 ;Restore to first column
MOV X1,AX ;Beginning of row
MOV AX,Y2 ;Next row
INC AX ;One down from end of box
MOV Y1,AX ;Into next row position
POP CX ;Restore count of rows
LOOP RCHAR2 ;Loop for next row
;
POP AX ;Restore registers
POP CX
POP DX
POP SI
RET
RCHAR ENDP
;------------------------------------------------------------------------------
;Routine to print a message on the graphics screen
;
GMSG_OUT PROC FAR
;
;Get (X,Y) location of message on the screen
MOV AX,XMSG ;Get X-coordinate on screen
MOV X0,AX ; for first character
MOV AX,YMSG ;Get Y-coordinate on screen
MOV Y0,AX ; for first character
CLD ;Go in forward direction
;
;Main loop through characters of the message
GMSG_LOOP:
CLD ;Forward direction
LODSB ;Get the ASCII code
CMP AL,0 ;End of string?
JE GMSG_XIT
;
;Check for fonts
FONT0:
CMP FONT,0 ;Use font 0?
JNE FONT1
CALL SCHAR ;Use stroke characters
FONT1:
CMP FONT,1 ;Use font 1?
JNE NEXTCHAR
CALL RCHAR ;Use raster characters
NEXTCHAR:
MOV AL,8 ;Character cell width
MOV CL,XMAGN ;Times horizontal magnitude
MUL CL ;Multiply
ADD X0,AX ;Add to loc of previous char
;
JMP GMSG_LOOP ;Loop for next character
GMSG_XIT:
RET
GMSG_OUT ENDP
;------------------------------------------------------------------------------
;Routine to fill an area with a specified color
; Uses two subroutines: PUSHPAINT & POPPAINT
;
;PUSHPAINT pushes X- & Y-coordinates on paint stack
PUSHPAINT PROC NEAR
DEC BP ;BP is the paint stack pointer
DEC BP ; & gets decremented first
MOV [BP],SI ;Push X
DEC BP
DEC BP
MOV [BP],DI ;Push Y
RET
PUSHPAINT ENDP
;
;POPPAINT pops X- & Y-coordinates on paint stack
POPPAINT PROC NEAR
MOV DI,[BP] ;Pop Y
INC BP ; then increment stack
INC BP
MOV SI,[BP] ;Pop X
INC BP
INC BP
RET
POPPAINT ENDP
;
;Main PAINT routine
PAINT PROC FAR
;
;Initialize paint color
MOV DX,COLOR
;
;Initialize paint stack
LEA BP,PAINT_STAK ;BP is set to top of stack
CALL PUSHPAINT ;Push seed onto stack
;
;Main loop for painting
PAINT1:
LEA AX,PAINT_STAK ;Stack empty?
CMP BP,AX
JNE PAINT2 ;Continue, if not
JMP PAINT_XIT ;Else exit
;
;Get the next place to paint
PAINT2:
CALL POPPAINT ;Pop the next place to paint
CALL GET_COLOR ;Color is returned in AL
CMP AL,DL ;Is it filled?
JE PAINT1
CMP AL,DH ;Is it boundary?
JE PAINT1
CMP DI,0 ;Top of screen?
JL PAINT1
CMP DI,199 ;Bottom of screen?
JG PAINT1
;
;Move right until boundary is reached
PAINT3:
INC SI ;X <-- X + 1
CALL GET_COLOR ;Look right
DEC SI ;Restore X
;
CMP AL,DL ;Is it filled?
JE PAINT4
CMP AL,DH ;Is it boundary color?
JE PAINT4
CMP SI,319 ;At right screen boundary?
JE PAINT4
INC SI ;X <-- X + 1
JMP PAINT3
;
;Push above and below
PAINT4:
DEC DI ;Y <-- Y - 1
CALL GET_COLOR ;Check above
MOV BH,AL ;Save above state
CMP AL,DL ;Is it filled?
JE PAINT5
CMP AL,DH ;Is it boundary color?
JE PAINT5
CALL PUSHPAINT ;Push above
PAINT5:
INC DI ;Restore Y
INC DI ;Y <-- Y + 1
CALL GET_COLOR ;Check below
MOV BL,AL ;Save below state
CMP AL,DL ;Is it filled?
JE PAINT6
CMP AL,DH ;Is it boundary color?
JE PAINT6
CALL PUSHPAINT ;Push below
PAINT6:
DEC DI ;Restore Y
;
;Anchor the end point of the scan line
MOV X2,SI ;Store X-coord, end of scan lin
MOV Y2,DI ;Store Y-coord, end of scan lin
;
;Plot as we scan left, checking above & below
PAINT7:
;Check above
DEC DI ;Y <-- Y - 1
CALL GET_COLOR ;Check above
CMP AL,DL ;Is it filled?
JE PAINT9
CMP AL,DH ;Is it boundary color?
JE PAINT9
;
CMP BH,DL ;Last above filled?
JE PAINT8
CMP BH,DH ;Was it boundary color?
JE PAINT8
JMP PAINT9
PAINT8:
CALL PUSHPAINT ;Push above if new place
; to paint
PAINT9:
MOV BH,AL ;Update last above
;
INC DI ;Restore Y
;
;Check below
INC DI ;Y <-- Y + 1
CALL GET_COLOR ;Check below
CMP AL,DL ;Is it filled?
JE PAINT11
CMP AL,DH ;Is it boundary color?
JE PAINT11
;
CMP BL,DL ;Last below filled?
JE PAINT10
CMP BL,DH ;Was it boundary color?
JE PAINT10
JMP PAINT11
PAINT10:
CALL PUSHPAINT ;Push below if new place
; to paint
PAINT11:
DEC DI
MOV BL,AL ;Update last below
;
INC DI ;Restore Y
;
;Move left
DEC SI ;X <-- X - 1
JL PAINT12 ;Stop the scan if too far left
CALL GET_COLOR ;Check the point
CMP AL,DL ;Is it filled yet?
JE PAINT12 ; if so, next scan line
CMP AL,DH ;Is it boundary yet?
JE PAINT12 ; if so, next scan line
JMP PAINT7 ;Continue painting scan line
PAINT12:
INC SI ;Restore X
MOV X1,SI ;Store X-coordinate of start
MOV Y1,DI ;Store Y-coordinate of start
CALL SET_BOX ;Plot the scan line
JMP PAINT1 ;Next place to paint
;
PAINT_XIT:
RET
PAINT ENDP
;------------------------------------------------------------------------------
CODES ENDS
;
END
;______________________________________________________________________________
;>>>>> Physical EOF GRAPHICS.ASM <<<<<