View difference between Paste ID: yskWCjgx and Zcgx8KP9
SHOW: | | - or go back to the newest paste.
1
; designed for NASM generating .com file...
2
3
cpu 386
4
org 100h 
5
6
section .text 
7
Start:      
8
9
	mov ax,0x13 ;SetVideoMode: 320x200x8
10
	int 0x10
11
		
12
	;array assumes ds=ss
13
	mov bp, LineArrayStart
14
.NextLine:
15-
    xchg bp,sp    ; array <-> stack
15+
	xchg bp,sp    ; array <-> stack
16
	pop si ;X0
17
	pop di ;Y0
18
	pop cx ;X1
19
	pop dx ;Y1
20
	pop ax ;Color	
21
	xchg bp,sp    ; stack <-> array
22
	call DrawLine
23
	cmp bp, LineArrayEnd
24
	jl .NextLine
25
	mov sp, bp ;restore sp
26
	
27
	mov ah,0x7  ;wait for a key
28
	int 0x21
29
	
30
	mov ax,0x3  ;SetVideoMode: 80x25 (text)
31
	int 0x10
32
	
33
	int 0x20    ;end program
34
35
LineArrayStart:
36
	;   X0  Y0   X1  Y1  Color
37
	dw   1,  0, 318,  0 , 9
38
	dw 319,  1, 319,198 ,11
39
	dw 318,199,   1,199 ,13
40
	dw   0,198,   0,  1 ,15
41
	dw   8,  8, 311,191 ,10
42
	dw 311,  8,   8,191 ,14
43
LineArrayEnd:
44
;=========================================================================
45
;=========================================================================
46
;=========================================================================
47
	
48
;-----------------------------------------------
49
; Draw Line (si,di) to (cx,dx) with color (al) ;
50
; ----------------------------------------------
51
; unused... AH,BP,SP (selfmod is using CS: to not assume CS=DS)
52
DrawLine:
53
	push ds                  ;save old DS
54
	push 0xA000              ;make new DS to be screen segment
55
	pop ds
56
	
57
	;   dx = abs(x1 - x0)
58
	;   dy = abs(y1 - y0)
59
	;   (x0 < x1) ? sx = 1 : sx = -1
60
	;   (y0 < y1) ? sx = 1 : sx = -1
61
	;   err = dx - dy
62
	
63
	mov bx, dx               ; bx = Y1*320+X1 
64
	imul bx, 320             ; (end position)
65
	add bx, cx               ; 
66
	mov [cs:.EndOff-2], bx   ; self-mod ending offset for the line!
67
	
68
	mov bx, 1                ; SX = 1
69
	sub cx,si                ; cx = (X1-X0)
70
	jnb .ChkH                ; jump if not negative
71
	neg bx                   ; SX = -1
72
	neg cx                   ; cx = -cx (abs DX)
73
.ChkH:
74
	mov [cs:.SX-2], bx       ; self-mod setting (in code SX)
75
	
76-
	mov bx, -320             ; SY = "-1"  (inverse because -dy , 320 because 'row')
76+
	mov bx, -320             ; SY = "-1"  (inverse because -DY , 320 because 'row')
77
	sub dx,di                ; dx = (Y1-Y0)
78
	jb .ChkV                 ; jump if negative
79
	neg bx                   ; SY = "1"
80
	neg dx                   ; dx = -dx (-abs DY)
81
.ChkV: 
82
	mov [cs:.SY-2], bx       ; self-mod setting (in code SY)	
83
	
84
	imul di, 320             ; di = Y0*320+X0
85
	add di, si               ; (start position)
86
	
87-
	mov si, cx               ; ERR = DX+DY
87+
	;mov si, cx               ; ERR = DX+DY
88-
	add si, dx               ; (add because DY was negated)
88+
	;add si, dx               ; (add because DY was negated)		
89
	lea bx,[ecx+edx]
90
	add bx,bx
91
92
;   loop
93
;     printPixel(x0, y0, colour)
94
;     if (x0 = x1) and (y0 = y1) exit loop
95
;     e2 = 2 * err
96
;     if (e2 > -dy) then
97
;       err = err - dy
98
;       x0 = x0 + sx
99
;     end if
100
;     if (e2 < dx) then
101
;       err = err + dx
102
;       y0 = y0 + sy
103
;     end if
104
;   end loop
105
	
106
.NextPixel:
107
	mov [di], al             ; store pixel
108
	cmp di, 0x5555           ; check if done drawing the line (SELF-MOD!)
109
.EndOff:
110-
	mov bx, si               ; E2 = ERR*2
110+
111-
	add bx, bx
111+
112
	;lea bx,[esi+esi]
113
	;;mov bx, si               ; E2 = ERR*2
114-
	jle .SX                  ; (inverse jump)
114+
	;;add bx, bx
115-
	add si, dx               ; ERR = ERR - DY (DY negativated)
115+
116
	cmp bx, dx               ; if (E2 > -DY) then
117
	jle .NoAddY              ; (inverse jump)
118
	;add si, dx              ; ERR = ERR - DY (DY negativated)
119
	add di, 0x5555           ; X0 = X0 + SX (Self-Mod SX (-1 or 1))
120-
	add si, cx               ; ERR = ERR + DX
120+
121
	cmp bx, cx               ; if (E2 < DX) then
122
	lea bx,[ebx+edx*2]	     ; duplicate code because both DX/DY comparsion must use the same BX
123
	jl .DoAdd                ; so i do it before the lea (which does not change registers)
124
	jmp .NextPixel           ; and jump to add part in positive case (better!!)
125
.NoAddY:	                
126
	cmp bx, cx               ; if (E2 < DX) then
127
	jge .NextPixel           ; (inverse jump) (optimized jump)
128
	;add si, cx               ; ERR = ERR + DX
129
.DoAdd:	
130
	lea bx,[ebx+ecx*2]	
131
	add di, 0x5555           ; Y0 = Y0 + SY (Self-Mod SX {-1(-320) or 1(320)}
132
.SY:
133
	jmp .NextPixel           
134
.Done:
135
	pop ds                   ; restore previous DS
136
	ret                      ; and return
137
	
138
;-----------------------------------------------