home *** CD-ROM | disk | FTP | other *** search
-
- ;************************************************************************
- ; Line (x0, y0, x1, y1,c ): draw line from (x0,y0) to (x1,y1) *
- ; with a color (c). *
- ; This routine is divided into three parts. Horizontal *
- ; lines are done in the first part, vertical lines in *
- ; second part, and rest in the third part. The lines *
- ; in the third part are done using the Bresenhams *
- ; algorithm. *
- ; entry : sp + 2 = x0 *
- ; sp + 4 = y0 *
- ; sp + 6 = x1 *
- ; sp + 8 = y1 *
- ; sp + 10= color *
- ;************************************************************************
-
- X0 EQU [BP+4]
- Y0 EQU [BP+6]
- X1 EQU [BP+8]
- Y1 EQU [BP+10]
- Color EQU [BP+12]
-
- PUBLIC _Line
-
- _Line PROC NEAR
- PUSH BP
- MOV BP,SP
- SUB SP,6 ;Declare three local variables
-
- PUSH DI
- PUSH SI
- PUSH DS
- PUSH ES
-
- MOV AX,X0 ; make sure that x1 >= x0
- MOV CX,X1
- CMP CX,AX
- JGE Get_Offset
- MOV BX,Y0
- MOV DX,Y1
- MOV X0,CX
- MOV Y0,DX
- MOV X1,AX
- MOV Y1,BX
-
- ;-------COMPUTE ADDRESS AND MASK FOR FIRST PIXEL -------------
- Get_Offset:
- ;--- Compute offset and save on stack
- MOV CL,4 ; offset = 80 * y + x/8
- MOV AX,Y0
- SHL AX,CL
- MOV BX,AX
- SHL AX,1
- SHL AX,1
- ADD AX,BX
- MOV BX,X0 ; + x/8
- MOV CL,3
- SHR BX,CL
- ADD AX,BX
- PUSH AX ; save offset on stack, later pop to DI
-
- ;--- Compute mask and save on the stack
-
- MOV CX,X0 ; compute which bit (x mod 8) to modify
- AND CL,7
- MOV BX,80h
- SHR BX,CL
- PUSH BX ; save mask on stack, later pop to SI
- MOV DX,03CEh ; enable only the bit(within a byte)
- MOV AL,08H ; to be changed
- OUT DX,AL
- INC DX
- MOV AL,BL ; ... reg-bx has the correct bit
- OUT DX,AL
-
- ;--- Load set/reset registers with current color
-
- MOV DX,03CEh ; move color into reset register
- XOR AL,AL
- OUT DX,AL
- INC DX
- MOV AX,Color
- OUT DX,AL
- DEC DX ; enable use of reset register
- MOV AL,1
- OUT DX,AL
- INC DX
- MOV AL,0FH
- OUT DX,AL
- MOV DX,03C4h ; enable all four planes for writting
- MOV AL,2
- OUT DX,AL
- INC DX
- MOV AL,0FH
- OUT DX,AL
-
- ;--- Load segment register
-
- MOV DX,0A000h
- MOV DS,DX
- MOV ES,DX
-
- ;-------COMPUTE DX AND DY ----------------------------------------
- ; DETERMINE IF HORIZONTAL, VERTICAL OR DIAGONNAL LINE
-
- MOV AX,80 ; set raster increment
- MOV [bp-6],AX
- MOV SI,X1 ; compute dx reg-si
- SUB SI,X0
- MOV DI,Y1 ; compute dy reg-di
- SUB DI,Y0
- JGE DyIsPos
- NEG AX
- MOV [bp-6],AX
- NEG DI
- DyIsPos:
- CMP SI,0 ; jump according to type of line
- JZ Vert
- CMP DI,0
- JZ Horiz
- JMP Diag
-
- ;-------GENERATE A VERTICAL LINE -----------------
-
- Vert: MOV cx,di ; set up counter
- INC cx
- MOV bx,[bp-6]
-
- POP SI ; fetch mask
- MOV DX,03CEh ; set mask
- MOV AL,08h
- OUT DX,AL
- INC DX
- MOV AX,SI
- OUT DX,AL
-
- POP DI ; fetch offset
- LoopVert:
- MOV AL,[DI] ; latch data(to preserve other 7 bits i
- MOV [DI],AL ; write new data (only one bit will be
- ADD DI,BX ; update offset
- LOOP LoopVert
- JMP LineDone
-
- ;-------GENERATE A HORIZONTAL LINE ---------------
-
- Horiz: MOV CX,SI ; set counter of pixels
- POP SI ; fetch mask
- POP DI ; fetch offset
-
- ;--- draw pixels from the leading partial byte
-
- MOV AX,X0
- AND AX,07h ; check for partial byte
- JZ FullBytes
- MOV BX,0FFh ; compute the mask
- PUSH CX
- MOV CX,AX
- SHR BX,CL
- POP CX
- ADD CX,AX ; update counter
- SUB CX,08h
- JGE MaskSet ; modify mask if only one byte
- NEG CX
- SHR BX,CL
- SHL BX,CL
- XOR CX,CX ; restore counter
- MaskSet:
- MOV DX,03CEh ; set the mask
- MOV AL,08h
- OUT DX,AL
- INC DX
- MOV AL,BL
- OUT DX,AL
- MOV AH,[DI] ; latch data
- MOV [DI],AL ; write new data
- INC DI ; update offset
-
- ;--- draw pixels from the middle complete bytes
- FullBytes: ;
- MOV BX,CX ; check if any bytes to set
- CMP DX,8
- JL TrailBytes
- SHR CX,1 ; compute count
- SHR CX,1
- SHR CX,1
- MOV DX,03CEh ; set the mask
- MOV AL,08h
- OUT DX,AL
- INC DX
- MOV AL,0FFh
- OUT DX,AL
-
- REP STOSB ; fill complete bytes
-
- ;--- draw pixels from the trailing partial byte
- TrailBytes:
- AND BX,07h
- JZ HorizDone
- MOV AX,0FFFFh ; compute mask
- MOV CX,BX
- SHR AX,CL
- XOR AH,0FFh ; set the mask
- MOV DX,03CEh
- MOV AL,08h
- OUT DX,AL
- INC DX
- MOV AL,AH
- OUT DX,AL
- MOV AL,[DI] ; latch data
- MOV [DI],AL ; set new data
- HorizDone:
- JMP LineDone
-
- ;----------------------- GENERATE A DIAGONAL LINE -----------------
-
- ;--- figure out which quarter does the line lie in
-
- Diag: CMP SI,DI ; Is dy > dx
- JLE oct12 ; ...Yes, do processing in octants
- ; 1 and 2
- ; Compute constants for octant zero and three
- ; This is where x is the major direction and y is minor
-
- oct03: MOV CX,SI ; set counter to dx+1
- INC CX
- SAL DI,1 ; d1 = dy*2 reg-di
- MOV BX,DI ; d = dy*2-dx reg-bx
- SUB BX,SI
- NEG SI ; d2 = dy*2-dx-dx reg-si
- ADD SI,BX
-
- MOV [bp-2],di ; save d1
- MOV [bp-4],si ; save d2
- MOV DX,03CEh ; select BIT MASK register
- MOV AL,08h
- OUT DX,AL
- INC DX
- POP AX ; fetch mask
- POP DI ; fetch address
-
- ;-------------- GENERATE LINE IN THE OCTANT ZERO AND THREE ------
-
- next0: OUT DX,AL ; enable a bit in a byte
- MOV AH,[DI] ; latch old data
- MOV [DI],AH ; modify (enabled bits)
-
- ROR AL,1 ; update mask
- ADC DI,0 ; update byte address
-
- TEST BX,8000H ; if d >= 0 then ...
- JNZ dneg0
- ADD BX,[BP-4] ; ... d = d + d2
- ADD DI,[BP-6] ; update offset to next scan line
- LOOP next0
- JMP LineDone
-
- dneg0: ADD BX,[BP-2] ; if d < 0 then d = d + d1
- LOOP next0
- JMP LineDone
-
- ;----------------------------------------------------------------
-
- ;--- Compute constants for octant one and two
-
- oct12: MOV CX,DI ; set counter to dy+1
- INC CX
- SAL SI,1 ; d1 = dx * 2
- MOV BX,SI ; d = dx * 2 - dy
- SUB BX,DI
- NEG DI ; d2 = -dy + dx * 2 - dy
- ADD DI,BX
-
- MOV [BP-4],DI ; save d2
- MOV [BP-2],SI ; save d1
- MOV dx,03CEh ; select BIT MASK register
- MOV al,08h
- OUT DX,AL
- INC DX
- POP AX ; fetch mask
- POP DI ; fetch address
- OUT DX,AL ; enable a bit in a byte
-
- ;-----GENERATE A LINE IN THE OCTANT ONE AND TWO -----------------
-
- next1: MOV AH,[DI] ; latch old data
- MOV [DI],AH ; modify (enabled bits)
-
- ADD DI,[BP-6] ; update offset (y = y+1)
-
- TEST BX,8000H ; if d >= 0 then ...
- JNZ dneg1
-
- ADD BX,[BP-4] ; ... d = d + d2
- ROR AL,1 ; ... update mask (x = x+1)
- ADC DI,0 ; ... update offset
- OUT DX,AL ; Enable next bit within a byte
- LOOP next1
- JMP LineDone
-
- dneg1: ADD BX,[BP-2] ; if d < 0 then d = d + d1
- LOOP next1
-
- ;----------------------------------------------------------------
- ;--- Restore PLANE ENABLE and BIT MASK registers
- LineDone:
- MOV DX,03CEh ; Enable all 8-bits in a byte for write
- MOV AL,08h ; by setting BIT MASK register to Fhex
- OUT DX,AL
- INC DX
- MOV AL,0FFh
- OUT DX,AL
-
- DEC DX ; Disable SET/RESET function
- MOV AL,1
- OUT DX,AL
- INC DX
- XOR AX,AX
- OUT DX,AL
-
- POP ES
- POP DS
- POP SI
- POP DI
- MOV SP,BP
- POP BP
- RET
- _Line ENDP