]> git.sur5r.net Git - cc65/blob - libsrc/tgi/tgidrv_line.inc
Factored out generic LINE implementation based on SETPIXEL from the three drivers...
[cc65] / libsrc / tgi / tgidrv_line.inc
1 ;
2 ; Oliver Schmidt <ol.sc@web.de>
3 ;
4 ; Generic LINE implementation based on SETPIXEL for TGI driver inclusion
5 ; Code previously present in a2.lo.tgi, c128-vdc.tgi and c128-vdc2.tgi
6 ;
7
8 ; ------------------------------------------------------------------------
9
10 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
11 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
12 ; Must set an error code: NO
13
14         .proc   LINE
15
16 ; Used for passing parameters to the driver.
17
18 X1      :=      ptr1
19 Y1      :=      ptr2
20 X2      :=      ptr3
21 Y2      :=      ptr4
22
23 ; These ones must be on zpage.
24
25 TEMP1   :=      tmp3
26 TEMP2   :=      tmp4
27 TEMP3   :=      sreg
28 TEMP4   :=      sreg+1
29 PB      :=      ptr3
30 UB      :=      ptr4
31 ERR     :=      regsave
32 NX      :=      regsave+2
33
34 ; ------------------------------------------------------------------------
35
36         .bss
37
38 COUNT:  .res    2
39 NY:     .res    2
40 DX:     .res    1
41 DY:     .res    1
42 AX:     .res    1
43 AY:     .res    1
44
45 ; ------------------------------------------------------------------------
46
47         .code
48
49         ; nx = abs (x2 - x1)
50         sec
51         lda     X2
52         sbc     X1
53         sta     NX
54         lda     X2+1
55         sbc     X1+1
56         tay
57         lda     NX
58         jsr     abs
59         sta     NX
60         sty     NX+1
61
62         ; ny = abs (y2 - y1)
63         sec
64         lda     Y2
65         sbc     Y1
66         sta     NY
67         lda     Y2+1
68         sbc     Y1+1
69         tay
70         lda     NY
71         jsr     abs
72         sta     NY
73         sty     NY+1
74
75         ; if (x2 >= x1)
76         ldx     #X2
77         lda     X1
78         ldy     X1+1
79         jsr     icmp
80         bcc     :+
81
82         ;    dx = 1
83         lda     #$01
84         bne     :++
85
86         ; else
87         ;    dx = -1
88 :       lda     #$FF
89 :       sta     DX
90
91         ; if (y2 >= y1)
92         ldx     #Y2
93         lda     Y1
94         ldy     Y1+1
95         jsr     icmp
96         bcc     :+
97
98         ;    dy = 1
99         lda     #$01
100         bne     :++
101
102         ; else
103         ;    dy = -1
104 :       lda     #$FF
105 :       sta     DY
106
107         ; err = ax = ay = 0
108         lda     #$00
109         sta     ERR
110         sta     ERR+1
111         sta     AX
112         sta     AY
113
114         ; if (nx < ny) {
115         ldx     #NX
116         lda     NY
117         ldy     NY+1
118         jsr     icmp
119         bcs     :+
120
121         ;    nx <-> ny
122         lda     NX
123         ldx     NY
124         sta     NY
125         stx     NX
126         lda     NX+1
127         ldx     NY+1
128         sta     NY+1
129         stx     NX+1
130
131         ;    ax = dx
132         lda     DX
133         sta     AX
134
135         ;    ay = dy
136         lda     DY
137         sta     AY
138
139         ;    dx = dy = 0 }
140         lda     #$00
141         sta     DX
142         sta     DY
143
144         ; ny = - ny
145 :       lda     NY
146         ldy     NY+1
147         jsr     neg
148         sta     NY
149         sty     NY+1
150
151         ; for (count = nx; count > 0; --count) {
152         lda     NX
153         ldx     NX+1
154         sta     COUNT
155         stx     COUNT+1
156 for:    lda     COUNT           ; count > 0
157         ora     COUNT+1
158         bne     :+
159         rts
160
161         ;    setpixel (X1, Y1)
162 :       jsr     SETPIXEL
163
164         ;    pb = err + ny
165         clc
166         lda     ERR
167         adc     NY
168         sta     PB
169         lda     ERR+1
170         adc     NY+1
171         sta     PB+1
172         tax
173
174         ;    ub = pb + nx
175         clc
176         lda     PB
177         adc     NX
178         sta     UB
179         txa
180         adc     NX+1
181         sta     UB+1
182
183         ;    x1 = x1 + dx
184         ldx     #$00
185         lda     DX
186         bpl     :+
187         dex
188 :       clc
189         adc     X1
190         sta     X1
191         txa
192         adc     X1+1
193         sta     X1+1
194
195         ;    y1 = y1 + ay
196         ldx     #$00
197         lda     AY
198         bpl     :+
199         dex
200 :       clc
201         adc     Y1
202         sta     Y1
203         txa
204         adc     Y1+1
205         sta     Y1+1
206
207         ;    if (abs (pb) < abs (ub)) {
208         lda     PB
209         ldy     PB+1
210         jsr     abs
211         sta     TEMP3
212         sty     TEMP4
213         lda     UB
214         ldy     UB+1
215         jsr     abs
216         ldx     #TEMP3
217         jsr     icmp
218         bpl     :+
219
220         ;       err = pb }
221         lda     PB
222         ldx     PB+1
223         jmp     next
224
225         ;    else { x1 = x1 + ax
226 :       ldx     #$00
227         lda     AX
228         bpl     :+
229         dex
230 :       clc
231         adc     X1
232         sta     X1
233         txa
234         adc     X1+1
235         sta     X1+1
236
237         ;       y1 = y1 + dy
238         ldx     #$00
239         lda     DY
240         bpl     :+
241         dex
242 :       clc
243         adc     Y1
244         sta     Y1
245         txa
246         adc     Y1+1
247         sta     Y1+1
248
249         ;       err = ub }
250         lda     UB
251         ldx     UB+1
252 next:   sta     ERR
253         stx     ERR+1
254
255         ; } (--count)
256         lda     COUNT
257         sec
258         sbc     #$01
259         sta     COUNT
260         bcc     :+
261         jmp     for
262 :       dec     COUNT+1
263         jmp     for
264
265
266 ; Copies of some runtime routines
267
268 abs:
269         ; A/Y := abs (A/Y)
270         cpy     #$00
271         bpl     :+
272         
273         ; A/Y := neg (A/Y)
274 neg:    clc
275         eor     #$FF
276         adc     #$01
277         pha
278         tya
279         eor     #$FF
280         adc     #$00
281         tay
282         pla
283 :       rts
284
285 icmp:
286         ; Compare A/Y to zp,X
287         sta     TEMP1           ; TEMP1/TEMP2 - arg2
288         sty     TEMP2
289         lda     $00,x
290         pha
291         lda     $01,x
292         tay
293         pla
294         tax
295         tya                     ; X/A - arg1 (a = high)
296
297         sec
298         sbc     TEMP2
299         bne     :++
300         cpx     TEMP1
301         beq     :+
302         adc     #$FF
303         ora     #$01
304 :       rts
305 :       bvc     :+
306         eor     #$FF
307         ora     #$01
308 :       rts
309
310         .endproc