2828; ------------
2929
3030 .importzp DINDEX, COLOR, IOERROR, COLCRS, ROWCRS, tmp4
31- .importzp SAVMSC , next_instruction , tmp1
31+ .importzp SAVMSC, next_instruction, tmp1, tmp2, tmp3
3232 .import gr_mask_p, gr_shift_x, gr_mask_s, EXE_PUT
3333
3434 .zeropage
3535mask: .res 1
3636color_s: .res 1
37+ colpos = tmp1
38+
39+ OLDROW: .res 1
40+ OLDCOL: .res 2
41+
42+ comp: .res 2
43+ error: .res 2
44+
45+ row_add: .res 1
46+ col_add: .res 2
47+
48+ delta_x = tmp2
49+ delta_y = tmp3
50+ old_err = tmp1 + 1
3751
3852
3953; TODO: implement line drawing for all graphic modes
@@ -46,6 +60,13 @@ color_s:.res 1
4660 lda COLOR
4761 jmp EXE_PUT
4862do_plot:
63+
64+ ldx #2
65+ cp_pos: lda ROWCRS, x
66+ sta OLDROW, x
67+ dex
68+ bpl cp_pos
69+
4970 jsr get_addr
5071 lda mask
5172 eor #$FF
@@ -55,13 +76,183 @@ do_plot:
5576 jmp next_instruction
5677.endproc
5778
79+
5880.proc EXE_DRAWTO ; Draw line from last position to current
81+
82+ ; Fast Bresenham line implementation, updating memory pointers
83+
84+ ; Get DY - easy as it is only 8 bits
85+ ldy #1
86+
87+ lda ROWCRS
88+ sec
89+ sbc OLDROW
90+ bcs dr_ypos
91+
92+ ; Y direction negative
93+ eor #$FF ; This is cheaper than lda/sbc again
94+ adc #$01
95+
96+ ldy #255
97+ dr_ypos:
98+ sta delta_y
99+ sty row_add
100+
101+ ; Get DX
102+ lda #0
103+ sta col_add+1
104+ ldx #1
105+
106+ lda COLCRS
107+ sec
108+ sbc OLDCOL
109+ tay
110+ lda COLCRS+1
111+ sbc OLDCOL+1
112+ bcs dr_xpos
113+
114+ ; X direction negative
115+ eor #$FF
116+ pha
117+ tya
118+ eor #$FF
119+ adc #$01
120+ tay
121+ pla
122+ adc #0
123+
124+ dec col_add+1
125+ ldx #$FF
126+
127+ dr_xpos:
128+ sta delta_x+1
129+ sty delta_x
130+ stx col_add
131+
132+ ; Pseudo-code for this line-drawing algorithm:
133+ ;
134+ ; dx = ABS(x1-x0)
135+ ; dy = ABS(y1-y0)
136+ ; sx = SGN(x1-x0)
137+ ; sy = SGN(y1-y0)
138+ ;
139+ ; error = dx - (dy / 2)
140+ ; comp = (dx + dy) / 2
141+ ;
142+ ; DO
143+ ; orig_error = error;
144+ ; IF error < comp
145+ ;
146+ ; IF y0 = y1
147+ ; EXIT
148+ ;
149+ ; error = error + dx
150+ ; y0 = y0 + sy
151+ ;
152+ ; If orig_error >= 0
153+ ;
154+ ; IF x0 = x1
155+ ; EXIT
156+ ;
157+ ; error = error - dy
158+ ; x0 = x0 + sx
159+ ;
160+ ; PLOT x0, y0
161+ ; LOOP
162+
163+ ; Get's comp
164+ lda delta_x
165+ adc delta_y
166+ sta comp
167+ lda delta_x+1
168+ adc #0
169+ lsr
170+ sta comp+1
171+ ror comp
172+
173+ ; Get's error
174+ lda delta_y
175+ lsr
176+ eor #$FF
177+ sec ; Can be avoided - only ads slight round error
178+ adc delta_x
179+ sta error
180+ lda delta_x+1
181+ adc #$FF
182+ sta error+1
183+
184+ ; Now, begin loop:
185+ jmp line_start
186+
187+ no_inc_x:
188+ ; Plots current pixel
189+ jsr get_addr
190+ lda mask
191+ eor #$FF
192+ and (tmp4), y
193+ ora color_s
194+ sta (tmp4), y
195+
196+ line_start:
197+ ; Compare with "comp"
198+ lda error
199+ cmp comp
200+ lda error+1
201+ sta old_err ; Store old error
202+ sbc comp+1
203+ bpl no_inc_y
204+
205+ clc
206+ lda error
207+ adc delta_x
208+ sta error
209+ lda error+1
210+ adc delta_x+1
211+ sta error+1
212+
213+ lda OLDROW
214+ cmp ROWCRS
215+ beq end_line
216+
217+ clc
218+ adc row_add
219+ sta OLDROW
220+
221+ no_inc_y:
222+ ; Compare old error with 0
223+ bit old_err
224+ bmi no_inc_x
225+
226+ sec
227+ lda error
228+ sbc delta_y
229+ sta error
230+ lda error+1
231+ adc #$FF
232+ sta error+1
233+
234+ lda OLDCOL
235+ ldx OLDCOL+1
236+ cmp COLCRS
237+ bne no_eol
238+ cpx COLCRS+1
239+ beq end_line
240+ no_eol:
241+ clc
242+ adc col_add
243+ sta OLDCOL
244+ txa
245+ adc col_add+1
246+ sta OLDCOL+1
247+ jmp no_inc_x
248+
249+ end_line:
59250 jmp next_instruction
60251.endproc
61252
62253
63254.proc get_addr
64- lda ROWCRS
255+ lda OLDROW
65256
66257 ; Multiply A by 4, overflowing to X
67258 ldx #0
@@ -74,7 +265,7 @@ L1: asl
74265 clc
75266
76267 ; Add to original, multiply by 5
77- L2: adc ROWCRS
268+ L2: adc OLDROW
78269 bcc :+
79270 inx
80271:
@@ -104,13 +295,13 @@ L2: adc ROWCRS
104295 ldy gr_shift_x, x
105296
106297 ; First shift is 16 bits
107- lda COLCRS + 1
298+ lda OLDCOL +1
108299 lsr
109- lda COLCRS
110- sta tmp1
300+ lda OLDCOL
301+ sta colpos
111302 lda #192
112303 ; Next shifts are 8 bits
113- shift: ror tmp1 ; Shift column position
304+ shift: ror colpos ; Shift column position
114305 ror ; Shift bit position
115306 dey
116307 bne shift
@@ -137,7 +328,7 @@ rol_mask:
137328ok_mask:
138329 sta color_s
139330
140- ldy tmp1
331+ ldy colpos
141332 rts
142333.endproc
143334
0 commit comments