PAGE,132 PUBLIC DRAWLINE ; DAN ROLLINS (213) 246-5021 ; ;8088 self-modifying program implements fast-vector algorithm ;described by Michalsky, Doctor Dobb's Journal #74, 12/82 ;see also: FAST-LINE DRAWING TECHNIQUE, BYTE, Aug 81 ; ;routine expects to be called with DS:SI pointing ;to a list of 2-byte arguments: ; ; si+0 = x1 starting clm (0-319) ; si+2 = y1 starting row (0-159) ; si+4 = x2 ending clm ; si+6 = y2 ending row ; si+8 = color (0,1,2,3) ; si+10 = length ; 0 = draw entire line ; else = draw sub- or super-set of this vector ; si+12 = skip length ; number of pels to go before starting to draw ; 0 = draw entire line ;destroys all registers execpt si and segment regs code group cseg cseg segment public 'code ' assume CS:cseg,DS:nothing,ES:nothing ;make it easier to acceess variables and arguments x1 equ word ptr [si] y1 equ word ptr [si+2] x2 equ word ptr [si+4] y2 equ word ptr [si+6] color equ byte ptr [si+8] len equ word ptr [si+10] skip equ word ptr [si+12] ;these are values that will be overlayed in the code INC_X EQU 41H DEC_X EQU 49H INC_Y EQU 42H DEC_Y EQU 4AH ;these are the addresses where new code is overlayed ADJ_LONG_AXIS EQU BYTE PTR CS:[DI] ADJ_MASTER EQU WORD PTR CS:[DI+3] TEST_MASTER EQU WORD PTR CS:[DI+7] ALT_ADJ_MASTER EQU WORD PTR CS:[DI+13] ADJ_SHRT_AXIS EQU BYTE PTR CS:[DI+15] DRAWLINE PROC FAR MOV BL,INC_X ;ASSUME XSTEP = +1 MOV AX,X2 SUB AX,X1 JGE DL1 ;IF X1 <= X2 THEN NO CHANGE MOV BL,DEC_X ;XSTEP = -1 NEG AX ;Xdist = ABS(Xdist) dl1: MOV CX,AX ;SAVE XDIST MOV BH,INC_Y ;ASSUME YSTEP = +1 MOV AX,Y2 SUB AX,Y1 JGE DL2 ;IF Y1 <= Y2 THEN NO CHANGE MOV BH,DEC_Y ;YSTEP = -1 NEG AX ;YDIST = ABS(YDIST) DL2: MOV DX,AX ;SAVE YDIST MOV DI,OFFSET CS:MODIFY_BASE ;POINT TO THE CODE ;TO MODIFY CMP DX,CX ;DETERMINE LONGEST AXIS JGE DL3 ;Y IS LONGER, SO SKIP XCHG CX,DX ;SWAP XDIST, YDIST XCHG BL,BH ;SWAP INC/DEC X/Y VALUES DL3: ;MODIFY: MOV ADJ_LONG_AXIS,BH ;THE 1st INC/DEC CODE MOV ADJ_MASTER,CX ;MAIN DUTY MASTER ADJUSTMENT SHR CX,1 ;SET UP CYCLE TESTER MOV TEST_MASTER,CX ;TEST FOR CYCLING MOV ALT_ADJ_MASTER,DX ;ALTERNATE ADJUSTMENT MOV ADJ_SHRT_AXIS,BL ;ALTERNATE INC/DEC CODE MOV DI,DX ;DI IS COUNTER: LONG AXIS LENGTH CMP LEN,0 ;IF LENGTH ARG > 0 JE DL4 MOV DI,LEN ;THEN USE IT AS COUNTER DL4: MOV BP,SKIP ;GET SKIP COUNT MOV CX,X1 ; AND OTHER ARGS MOV DX,Y1 MOV AL,COLOR XOR BX,BX ;DUTY MASTER STARTS = 0 ;--------TOP OF VECTOR PLOTTING LOOP-------------------- DL5: CMP BP,0 ;TEST SKIP COUNT JE OK_PLOT DEC BP JMP SHORT NO_PLOT OK_PLOT: CALL PLOTDOT ;PLOT A DOT ; ;MOST OF THE FOLLOWING CODE IS MODIFIED BY THE PREVIOUS SEQUENCE. ;THE 1111H'S ARE DUMMY VALUES THAT ARE ALWAYS OVERLAYED. ; MODIFY_BASE LABEL BYTE NO_PLOT: INC CX ;INC/DEC CX/DX: ADJUST LONG AXIS PTR ADD BX,1111H ;XDIST OR YDIST: ADJUST DUTY MASTER CMP BX,1111H ;YDIST OR XDIST: CHECK CYCLE POSITION JLE DL6 ;SKIP IF SHORT AXIS IS STILL OK SUB BX,1111H ;XDIST OR YDIST: ADJUST DUTY MASTER INC DX ;INC/DEC DX/CX: ADJUST SHORT AXIS PTR DL6: DEC DI ;DI IS USED AS COUNTER JGE DL5 ;DO NEXT DOT IF NOT FINISHED ;-------------------------------------------------- RET ;FAR RETURN BACK TO CALLER DRAWLINE ENDP ;this routine plots the pixel at column CX (0-319) or (0-639) ; row DX (0-199) ; color AL (0-3) or (0-1) in high res ;note: a much faster routine ; can be wiritten to plot dots ; PLOTDOT PROC NEAR PUSH AX PUSH DI ;BIOS DESTROYS THESE REGISTERS PUSH BP MOV AH,12 ;WRITE_DOT FUNCTION INT 10H ; VIDEO I/O CALL POP BP POP DI POP AX RET ;NEAR RETURN TO DRAWLINE PROC PLOTDOT ENDP CSEG ENDS