home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
C-ASM_VI.ARJ
/
PROGASM.ZIP
/
PROG086.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-04-10
|
12KB
|
329 lines
;************************************************************************
; 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