Skip to content

Commit 74b781e

Browse files
committed
A5200: implements line drawing in graphics modes.
1 parent b101902 commit 74b781e

2 files changed

Lines changed: 200 additions & 9 deletions

File tree

src/a5200cart.asm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ COLRSH: .res 1 ; Used as DLI pointer
5353
DINDEX: .res 1 ; Display mode index
5454

5555
SAVMSC: .res 2
56-
COLCRS: .res 2
5756
ROWCRS: .res 1
57+
COLCRS: .res 2
5858

5959
; ZP locations used by FastBasic:
6060
array_ptr: .res 2 ; Top of array memory

src/interp/a5200/drawto.asm

Lines changed: 199 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,26 @@
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
3535
mask: .res 1
3636
color_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
4862
do_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:
137328
ok_mask:
138329
sta color_s
139330

140-
ldy tmp1
331+
ldy colpos
141332
rts
142333
.endproc
143334

0 commit comments

Comments
 (0)