]> git.sur5r.net Git - cc65/blob - libsrc/apple2/apple2-280-192-6.s
New loadable mouse drivers
[cc65] / libsrc / apple2 / apple2-280-192-6.s
1 ;
2 ; Graphics driver for the 280x192x6 mode on the Apple II
3 ;
4 ; Stefan Haubenthal <polluks@sdf.lonestar.org>
5 ; Based on Maciej Witkowiak's circle routine
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "tgi-kernel.inc"
11         .include        "tgi-mode.inc"
12         .include        "tgi-error.inc"
13         .include        "apple2.inc"
14
15         .macpack        generic
16
17 ; ------------------------------------------------------------------------
18 ; Header. Includes jump table and constants.
19
20 .segment        "JUMPTABLE"
21
22 ; First part of the header is a structure that has a magic and defines the
23 ; capabilities of the driver
24
25         .byte   $74, $67, $69           ; "tgi"
26         .byte   TGI_API_VERSION         ; TGI API version number
27 xres:   .word   280                     ; X resolution
28 yres:   .word   192                     ; Y resolution
29         .byte   8                       ; Number of drawing colors
30         .byte   2                       ; Number of screens available
31         .byte   8                       ; System font X size
32         .byte   8                       ; System font Y size
33         .res    4, $00                  ; Reserved for future extensions
34
35 ; Next comes the jump table. Currently all entries must be valid and may point
36 ; to an RTS for test versions (function not implemented).
37
38         .word   INSTALL
39         .word   UNINSTALL
40         .word   INIT
41         .word   DONE
42         .word   GETERROR
43         .word   CONTROL
44         .word   CLEAR
45         .word   SETVIEWPAGE
46         .word   SETDRAWPAGE
47         .word   SETCOLOR
48         .word   SETPALETTE
49         .word   GETPALETTE
50         .word   GETDEFPALETTE
51         .word   SETPIXEL
52         .word   GETPIXEL
53         .word   LINE
54         .word   BAR
55         .word   CIRCLE
56         .word   TEXTSTYLE
57         .word   OUTTEXT
58
59 ; ------------------------------------------------------------------------
60 ; Data.
61
62 ; Variables mapped to the zero page segment variables. Some of these are
63 ; used for passing parameters to the driver.
64
65 X1              = ptr1
66 Y1              = ptr2
67 X2              = ptr3
68 Y2              = ptr4
69 RADIUS          = tmp1
70
71 ADDR            = tmp1
72 TEMP            = tmp3
73 TEMP2           = tmp4
74 TEMP3           = sreg
75 TEMP4           = sreg+1
76
77 ; Circle stuff
78 XX              = ptr3          ; (2)   CIRCLE
79 YY              = ptr4          ; (2)   CIRCLE
80 MaxO            = sreg          ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
81 XS              = regsave       ; (2)   CIRCLE
82 YS              = regsave+2     ; (2)   CIRCLE
83
84 ; Absolute variables used in the code
85
86 .bss
87
88 ERROR:          .res    1       ; Error code
89
90 ; Line routine stuff (combined with CIRCLE to save space)
91
92 OGora:          .res    2
93 OUkos:          .res    2
94 Y3:             .res    2
95
96 ; Text output stuff
97 TEXTMAGX        = $E7
98 TEXTMAGY        = $E7
99 TEXTDIR         = $F9
100
101 ; Constants and tables
102
103 .rodata
104
105 DEFPALETTE:     .byte   $00, $05, $04, $01, $00, $08, $06, $01; 6 unique colors
106
107 SHAPE:  .byte   $64,$01,$d0,$00,$d5,$00,$da,$00,$e0,$00,$ef,$00,$fe,$00,$0c,$01
108         .byte   $19,$01,$1d,$01,$25,$01,$2d,$01,$3d,$01,$46,$01,$4b,$01,$52,$01
109         .byte   $56,$01,$60,$01,$70,$01,$77,$01,$83,$01,$8e,$01,$9a,$01,$a7,$01
110         .byte   $b6,$01,$bf,$01,$ce,$01,$dd,$01,$e2,$01,$e7,$01,$f9,$01,$03,$02
111         .byte   $15,$02,$1f,$02,$32,$02,$42,$02,$52,$02,$5e,$02,$6c,$02,$79,$02
112         .byte   $85,$02,$91,$02,$a1,$02,$a9,$02,$b2,$02,$bf,$02,$c5,$02,$d5,$02
113         .byte   $e5,$02,$f4,$02,$00,$03,$10,$03,$1f,$03,$2d,$03,$35,$03,$44,$03
114         .byte   $53,$03,$63,$03,$71,$03,$7b,$03,$85,$03,$91,$03,$97,$03,$a3,$03
115         .byte   $b6,$03,$bf,$03,$c3,$03,$cf,$03,$dc,$03,$e4,$03,$f3,$03,$00,$04
116         .byte   $0a,$04,$19,$04,$25,$04,$2a,$04,$32,$04,$3c,$04,$43,$04,$50,$04
117         .byte   $5a,$04,$66,$04,$72,$04,$7e,$04,$87,$04,$94,$04,$9c,$04,$a8,$04
118         .byte   $b4,$04,$c1,$04,$cc,$04,$db,$04,$e6,$04,$ee,$04,$f3,$04,$fb,$04
119         .byte   $04,$05,$1a,$05,$1f,$05,$24,$05,$29,$05,$22,$01,$00,$00,$00,$00
120         .byte   $09,$89,$92,$92,$00,$36,$36,$16,$0e,$00,$0d,$fe,$6e,$96,$52,$00
121         .byte   $69,$fe,$17,$2d,$2d,$1e,$1f,$17,$2d,$2d,$1e,$1f,$6e,$4e,$00,$09
122         .byte   $8d,$3f,$bf,$0d,$15,$3f,$0e,$0d,$1e,$3f,$77,$71,$09,$00,$6d,$11
123         .byte   $df,$77,$09,$1e,$17,$4d,$3a,$df,$4e,$29,$0e,$00,$a9,$1f,$6e,$1e
124         .byte   $17,$0d,$0d,$1e,$df,$0e,$6d,$0e,$00,$36,$96,$52,$00,$09,$1e,$17
125         .byte   $36,$15,$0e,$0e,$00,$15,$0e,$36,$1e,$17,$4e,$01,$00,$09,$8d,$1f
126         .byte   $1f,$0e,$2d,$1e,$17,$2d,$15,$1f,$1f,$4e,$4e,$01,$00,$89,$6e,$3a
127         .byte   $3f,$77,$31,$56,$09,$00,$92,$8a,$f6,$0d,$00,$52,$89,$3f,$b7,$52
128         .byte   $49,$00,$92,$92,$0e,$00,$49,$11,$17,$1e,$17,$1e,$56,$49,$01,$00
129         .byte   $29,$ad,$df,$33,$4d,$35,$1f,$1f,$2e,$4d,$fe,$1b,$0e,$2d,$4e,$00
130         .byte   $31,$77,$36,$be,$2d,$0e,$00,$29,$ad,$df,$73,$49,$1e,$bf,$1e,$2e
131         .byte   $2d,$75,$00,$2d,$2d,$be,$3e,$4e,$fe,$1b,$0e,$2d,$4e,$00,$49,$3e
132         .byte   $17,$0d,$fe,$33,$2d,$2d,$1e,$76,$01,$00,$2d,$2d,$de,$1b,$2e,$2d
133         .byte   $15,$36,$df,$73,$2d,$4e,$00,$09,$2d,$de,$bb,$4d,$3a,$3f,$6e,$09
134         .byte   $fe,$1b,$0e,$2d,$4e,$00,$2d,$2d,$be,$1e,$17,$36,$4e,$09,$00,$29
135         .byte   $ad,$df,$33,$4d,$f1,$3f,$17,$4d,$31,$df,$73,$2d,$4e,$00,$29,$ad
136         .byte   $df,$33,$4d,$31,$3f,$77,$09,$1e,$df,$2a,$75,$09,$00,$12,$16,$96
137         .byte   $01,$00,$52,$b2,$f6,$0d,$00,$49,$3e,$17,$2d,$2d,$35,$3f,$3f,$3f
138         .byte   $0e,$2d,$2d,$f5,$1b,$77,$4e,$09,$00,$12,$2d,$2d,$de,$9b,$2d,$2d
139         .byte   $96,$01,$00,$49,$15,$ff,$13,$2d,$2d,$ad,$3f,$3f,$3f,$2e,$2d,$2d
140         .byte   $1e,$37,$4e,$09,$00,$29,$ad,$df,$73,$09,$1e,$b6,$4e,$01,$00,$09
141         .byte   $2d,$3e,$37,$2d,$3e,$ff,$2a,$2d,$2d,$f5,$3f,$3f,$0e,$2d,$1e,$4d
142         .byte   $01,$00,$09,$15,$1f,$17,$4d,$31,$df,$33,$2d,$2d,$fe,$1b,$6e,$09
143         .byte   $0e,$00,$2d,$ad,$df,$33,$4d,$f1,$3f,$37,$4d,$31,$df,$33,$2d,$75
144         .byte   $01,$00,$29,$ad,$df,$33,$36,$4d,$11,$df,$73,$2d,$4e,$00,$2d,$ad
145         .byte   $df,$6e,$31,$df,$6e,$31,$df,$17,$2d,$75,$01,$00,$2d,$2d,$de,$1b
146         .byte   $6e,$11,$3f,$37,$36,$2d,$2d,$0e,$00,$2d,$2d,$de,$1b,$6e,$11,$3f
147         .byte   $37,$36,$4e,$49,$00,$29,$ad,$df,$33,$36,$4d,$35,$df,$73,$2d,$75
148         .byte   $00,$4d,$31,$df,$33,$4d,$31,$3f,$3f,$6e,$09,$fe,$1b,$6e,$09,$0e
149         .byte   $00,$2d,$1e,$36,$36,$17,$2d,$0e,$00,$49,$31,$36,$36,$df,$73,$2d
150         .byte   $4e,$00,$4d,$f1,$df,$6e,$1e,$37,$0d,$15,$df,$6e,$09,$0e,$00,$36
151         .byte   $36,$36,$2d,$75,$00,$4d,$31,$ff,$37,$0d,$0d,$fe,$1f,$6e,$09,$fe
152         .byte   $1b,$6e,$09,$0e,$00,$4d,$31,$df,$33,$6d,$31,$1f,$1f,$6e,$29,$fe
153         .byte   $1b,$6e,$09,$0e,$00,$29,$ad,$df,$33,$4d,$31,$df,$33,$4d,$31,$df
154         .byte   $73,$2d,$4e,$00,$2d,$ad,$df,$33,$4d,$f1,$3f,$37,$36,$4e,$49,$00
155         .byte   $29,$ad,$df,$33,$4d,$31,$df,$33,$0d,$0d,$1e,$df,$0e,$6d,$0e,$00
156         .byte   $2d,$ad,$df,$33,$4d,$f1,$3f,$37,$0d,$15,$df,$6e,$09,$0e,$00,$29
157         .byte   $ad,$df,$33,$4d,$3a,$77,$09,$fe,$1b,$0e,$2d,$4e,$00,$2d,$2d,$de
158         .byte   $36,$36,$76,$09,$00,$4d,$31,$df,$33,$4d,$31,$df,$33,$4d,$31,$df
159         .byte   $73,$2d,$4e,$00,$4d,$31,$df,$33,$4d,$31,$df,$33,$4d,$f1,$1f,$0e
160         .byte   $4e,$01,$00,$4d,$31,$df,$33,$4d,$31,$1f,$1f,$6e,$0d,$3e,$1f,$37
161         .byte   $4d,$71,$00,$4d,$31,$df,$73,$0d,$1e,$17,$0d,$15,$df,$33,$4d,$71
162         .byte   $00,$4d,$31,$df,$73,$0d,$1e,$36,$76,$09,$00,$2d,$2d,$be,$1e,$17
163         .byte   $1e,$2e,$2d,$75,$00,$2d,$2d,$de,$3b,$2e,$3e,$2e,$3e,$2e,$2d,$75
164         .byte   $00,$72,$15,$0e,$15,$56,$00,$2d,$2d,$3e,$2e,$3e,$2e,$3e,$df,$2a
165         .byte   $2d,$75,$00,$49,$15,$3f,$17,$2d,$2d,$15,$3f,$3f,$3f,$4e,$2d,$3e
166         .byte   $37,$2d,$3e,$6f,$49,$00,$92,$92,$49,$11,$3f,$3f,$4d,$09,$00,$76
167         .byte   $96,$52,$00,$52,$2d,$35,$df,$33,$4d,$31,$ff,$73,$6d,$0e,$00,$36
168         .byte   $2d,$ad,$df,$33,$4d,$31,$df,$33,$2d,$75,$01,$00,$52,$2d,$de,$33
169         .byte   $76,$2d,$0e,$00,$49,$31,$df,$2a,$2d,$fe,$1b,$6e,$09,$fe,$1b,$0e
170         .byte   $2d,$75,$00,$52,$2d,$15,$df,$33,$2d,$2d,$de,$1b,$0e,$2d,$75,$00
171         .byte   $09,$f5,$33,$8d,$3f,$77,$36,$4e,$01,$00,$52,$2d,$35,$df,$33,$4d
172         .byte   $31,$3f,$77,$09,$1e,$3f,$4d,$01,$00,$36,$2d,$ad,$df,$33,$4d,$31
173         .byte   $df,$33,$4d,$71,$00,$16,$36,$36,$0e,$00,$09,$9e,$35,$36,$f6,$6f
174         .byte   $01,$00,$36,$4d,$1e,$1f,$2e,$15,$1f,$6e,$71,$00,$35,$36,$36,$17
175         .byte   $2d,$0e,$00,$12,$2d,$ad,$1f,$1f,$6e,$0d,$fe,$1f,$6e,$0d,$0e,$00
176         .byte   $12,$2d,$15,$df,$6e,$31,$df,$6e,$71,$00,$52,$2d,$15,$df,$33,$4d
177         .byte   $31,$df,$73,$2d,$4e,$00,$12,$2d,$ad,$df,$33,$4d,$f1,$3f,$37,$6e
178         .byte   $49,$00,$52,$2d,$35,$df,$33,$4d,$31,$3f,$77,$09,$2e,$00,$12,$0d
179         .byte   $ad,$df,$37,$36,$4e,$49,$00,$52,$2d,$f5,$db,$0e,$2d,$15,$df,$13
180         .byte   $2d,$75,$01,$00,$31,$17,$2d,$f5,$33,$76,$75,$00,$12,$4d,$31,$df
181         .byte   $33,$4d,$31,$ff,$73,$6d,$0e,$00,$12,$4d,$31,$df,$33,$4d,$f1,$1f
182         .byte   $0e,$4e,$01,$00,$12,$4d,$31,$df,$33,$0d,$0d,$fe,$1f,$0e,$0d,$4e
183         .byte   $00,$12,$4d,$f1,$1f,$0e,$15,$1f,$17,$4d,$71,$00,$12,$4d,$31,$df
184         .byte   $33,$4d,$31,$3f,$77,$09,$1e,$3f,$4d,$01,$00,$12,$2d,$2d,$1e,$17
185         .byte   $1e,$17,$2d,$2d,$0e,$00,$09,$f5,$33,$1e,$0e,$76,$75,$00,$36,$36
186         .byte   $36,$2e,$00,$ad,$ae,$17,$fe,$2a,$4e,$01,$00,$69,$11,$1f,$1f,$4e
187         .byte   $b1,$92,$09,$00,$2d,$2d,$35,$3f,$3f,$37,$2d,$2d,$35,$3f,$3f,$37
188         .byte   $2d,$2d,$35,$3f,$3f,$37,$2d,$2d,$75,$00,$40,$c0,$40,$18,$00,$40
189         .byte   $c0,$40,$43,$00,$40,$c0,$40,$08,$00,$19,$00,$00
190
191 .code
192
193 ; ------------------------------------------------------------------------
194 ; INSTALL routine. Is called after the driver is loaded into memory. May
195 ; initialize anything that has to be done just once. Is probably empty
196 ; most of the time.
197 ;
198 ; Must set an error code: NO
199 ;
200
201 INSTALL:
202
203
204 ; ------------------------------------------------------------------------
205 ; UNINSTALL routine. Is called before the driver is removed from memory. May
206 ; clean up anything done by INSTALL but is probably empty most of the time.
207 ;
208 ; Must set an error code: NO
209 ;
210
211 UNINSTALL:
212         rts
213
214
215 ; ------------------------------------------------------------------------
216 ; INIT: Changes an already installed device from text mode to graphics
217 ; mode.
218 ; Note that INIT/DONE may be called multiple times while the driver
219 ; is loaded, while INSTALL is only called once, so any code that is needed
220 ; to initializes variables and so on must go here. Setting palette and
221 ; clearing the screen is not needed because this is called by the graphics
222 ; kernel later.
223 ; The graphics kernel will never call INIT when a graphics mode is already
224 ; active, so there is no need to protect against that.
225 ;
226 ; Must set an error code: YES
227 ;
228
229 INIT:
230
231 ; Switch into graphics mode
232
233         jsr     HGR
234         bit     MIXOFF
235
236 ; Done, reset the error code
237
238         lda     #TGI_ERR_OK
239         sta     ERROR
240         rts
241
242 ; ------------------------------------------------------------------------
243 ; DONE: Will be called to switch the graphics device back into text mode.
244 ; The graphics kernel will never call DONE when no graphics mode is active,
245 ; so there is no need to protect against that.
246 ;
247 ; Must set an error code: NO
248 ;
249
250 DONE            = TEXT
251
252 ; ------------------------------------------------------------------------
253 ; GETERROR: Return the error code in A and clear it.
254
255 GETERROR:
256         ldx     #TGI_ERR_OK
257         lda     ERROR
258         stx     ERROR
259         rts
260
261 ; ------------------------------------------------------------------------
262 ; CONTROL: Platform/driver specific entry point.
263 ;
264 ; Must set an error code: YES
265 ;
266
267 CONTROL:
268         lda     #TGI_ERR_INV_FUNC
269         sta     ERROR
270         rts
271
272 ; ------------------------------------------------------------------------
273 ; CLEAR: Clears the screen.
274 ;
275 ; Must set an error code: NO
276 ;
277
278 CLEAR           = HCLR
279
280 ; ------------------------------------------------------------------------
281 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
282 ; The page number is already checked to be valid by the graphics kernel.
283 ;
284 ; Must set an error code: NO (will only be called if page ok)
285 ;
286
287 SETVIEWPAGE:
288         tax
289         beq     @L1
290         bit     PG2ON
291         rts
292 @L1:    bit     PG2OFF
293         rts
294
295 ; ------------------------------------------------------------------------
296 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
297 ; The page number is already checked to be valid by the graphics kernel.
298 ;
299 ; Must set an error code: NO (will only be called if page ok)
300 ;
301
302 SETDRAWPAGE:
303         tax
304         beq     @L1
305         lda     #>$4000                 ; Page 2
306         .byte   $2C
307 @L1:    lda     #>$2000                 ; Page 1
308         sta     $E6
309         rts
310
311 ; ------------------------------------------------------------------------
312 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
313 ; to be in a valid range (0..maxcolor-1).
314 ;
315 ; Must set an error code: NO (will only be called if color ok)
316 ;
317
318 SETCOLOR:
319         tax
320         jmp     SETHCOL
321
322 ; ------------------------------------------------------------------------
323 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
324 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
325 ; are not supported
326 ;
327 ; Must set an error code: YES
328 ;
329
330 SETPALETTE:
331         lda     #TGI_ERR_INV_FUNC
332         sta     ERROR
333         rts
334
335 ; ------------------------------------------------------------------------
336 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
337 ; set the palette should return the default palette here, so there's no
338 ; way for this function to fail.
339 ;
340 ; Must set an error code: NO
341 ;
342
343 GETPALETTE:
344
345 ; ------------------------------------------------------------------------
346 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
347 ; drivers should return something reasonable here, even drivers that don't
348 ; support palettes, otherwise the caller has no way to determine the colors
349 ; of the (not changeable) palette.
350 ;
351 ; Must set an error code: NO (all drivers must have a default palette)
352 ;
353
354 GETDEFPALETTE:
355         lda     #<DEFPALETTE
356         ldx     #>DEFPALETTE
357         rts
358
359 ; ------------------------------------------------------------------------
360 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
361 ; color. The coordinates passed to this function are never outside the
362 ; visible screen area, so there is no need for clipping inside this function.
363 ;
364 ; Must set an error code: NO
365 ;
366
367 SETPIXELCLIP:
368         lda     Y1+1
369         bmi     @finito         ; y<0
370         lda     X1+1
371         bmi     @finito         ; x<0
372         lda     X1
373         ldx     X1+1
374         sta     ADDR
375         stx     ADDR+1
376         ldx     #ADDR
377         lda     xres
378         ldy     xres+1
379         jsr     icmp            ; ( x < xres ) ...
380         bcs     @finito
381         lda     Y1
382         ldx     Y1+1
383         sta     ADDR
384         stx     ADDR+1
385         ldx     #ADDR
386         lda     yres
387         ldy     yres+1
388         jsr     icmp            ; ... && ( y < yres )
389         bcc     SETPIXEL
390 @finito:rts
391
392 SETPIXEL:
393         ldx     X1
394         ldy     X1+1
395         lda     Y1
396         jmp     HPLOT
397
398 ; ------------------------------------------------------------------------
399 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
400 ; coordinates passed to this function are never outside the visible screen
401 ; area, so there is no need for clipping inside this function.
402
403
404 GETPIXEL:
405         ldx     X1
406         ldy     X1+1
407         lda     Y1
408         jsr     HPOSN           ; 1st pixel
409 HBASL   =       $26
410 HMASK   =       $30
411         ldx     #0
412         lda     (HBASL),y
413         and     HMASK
414         beq     @L1
415         inx
416 @L1:    stx     tmp1
417
418         lda     $E0             ; which neighbour
419         tax
420         and     #$01
421         bne     @odd
422         asl     tmp1
423         inx
424         .byte   $24
425 @odd:   dex
426
427         ldy     $E1
428         lda     $E2
429         jsr     HPOSN           ; 2nd pixel
430         ldx     #0
431         lda     (HBASL),y
432         and     HMASK
433         beq     @L2
434         inx
435 @L2:    txa
436         ora     tmp1
437         ldx     #0
438         rts
439
440 ; ------------------------------------------------------------------------
441 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
442 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
443 ;
444 ; Must set an error code: NO
445 ;
446
447 LINE:
448         ldx     X1
449         ldy     X1+1
450         lda     Y1
451         jsr     HPOSN
452         lda     X2
453         ldx     X2+1
454         ldy     Y2
455         jmp     HLIN
456
457 ; ------------------------------------------------------------------------
458 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
459 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
460 ; Contrary to most other functions, the graphics kernel will sort and clip
461 ; the coordinates before calling the driver, so on entry the following
462 ; conditions are valid:
463 ;       X1 <= X2
464 ;       Y1 <= Y2
465 ;       (X1 >= 0) && (X1 < XRES)
466 ;       (X2 >= 0) && (X2 < XRES)
467 ;       (Y1 >= 0) && (Y1 < YRES)
468 ;       (Y2 >= 0) && (Y2 < YRES)
469 ;
470 ; Must set an error code: NO
471 ;
472
473 BAR:
474         inc     Y2
475 @L1:    lda     Y2
476         pha
477         lda     Y1
478         sta     Y2
479         jsr     LINE
480         pla
481         sta     Y2
482         inc     Y1
483         cmp     Y1
484         bne     @L1
485         rts
486
487 ; ------------------------------------------------------------------------
488 ; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
489 ; radius in tmp1 and the current drawing color.
490 ;
491 ; Must set an error code: NO
492 ;
493
494 CIRCLE:
495         lda     RADIUS
496         bne     @L1
497         jmp     SETPIXELCLIP    ; Plot as a point
498
499 @L1:    sta     XX
500         ; x = r;
501         lda     #0
502         sta     XX+1
503         sta     YY
504         sta     YY+1
505         sta     MaxO
506         sta     MaxO+1
507         ; y =0; mo=0;
508         lda     X1
509         ldx     X1+1
510         sta     XS
511         stx     XS+1
512         lda     Y1
513         ldx     Y1+1
514         sta     YS
515         stx     YS+1            ; XS/YS to remember the center
516
517         ; while (y<x) {
518 @L013B: ldx     #YY
519         lda     XX
520         ldy     XX+1
521         jsr     icmp
522         bcc     @L12
523         rts
524 @L12:   ; plot points in 8 slices...
525         lda     XS
526         add     XX
527         sta     X1
528         lda     XS+1
529         adc     XX+1
530         sta     X1+1            ; x1 = xs+x
531         lda     YS
532         add     YY
533         sta     Y1
534         pha
535         lda     YS+1
536         adc     YY+1
537         sta     Y1+1            ; (stack)=ys+y, y1=(stack)
538         pha
539         jsr     SETPIXELCLIP    ; plot(xs+x,ys+y)
540         lda     YS
541         sub     YY
542         sta     Y1
543         sta     Y3
544         lda     YS+1
545         sbc     YY+1
546         sta     Y1+1            ; y3 = y1 = ys-y
547         sta     Y3+1
548         jsr     SETPIXELCLIP    ; plot(xs+x,ys-y)
549         pla
550         sta     Y1+1
551         pla
552         sta     Y1              ; y1 = ys+y
553         lda     XS
554         sub     XX
555         sta     X1
556         lda     XS+1
557         sbc     XX+1
558         sta     X1+1
559         jsr     SETPIXELCLIP    ; plot (xs-x,ys+y)
560         lda     Y3
561         sta     Y1
562         lda     Y3+1
563         sta     Y1+1
564         jsr     SETPIXELCLIP    ; plot (xs-x,ys-y)
565
566         lda     XS
567         add     YY
568         sta     X1
569         lda     XS+1
570         adc     YY+1
571         sta     X1+1            ; x1 = xs+y
572         lda     YS
573         add     XX
574         sta     Y1
575         pha
576         lda     YS+1
577         adc     XX+1
578         sta     Y1+1            ; (stack)=ys+x, y1=(stack)
579         pha
580         jsr     SETPIXELCLIP    ; plot(xs+y,ys+x)
581         lda     YS
582         sub     XX
583         sta     Y1
584         sta     Y3
585         lda     YS+1
586         sbc     XX+1
587         sta     Y1+1            ; y3 = y1 = ys-x
588         sta     Y3+1
589         jsr     SETPIXELCLIP    ; plot(xs+y,ys-x)
590         pla
591         sta     Y1+1
592         pla
593         sta     Y1              ; y1 = ys+x(stack)
594         lda     XS
595         sub     YY
596         sta     X1
597         lda     XS+1
598         sbc     YY+1
599         sta     X1+1
600         jsr     SETPIXELCLIP    ; plot (xs-y,ys+x)
601         lda     Y3
602         sta     Y1
603         lda     Y3+1
604         sta     Y1+1
605         jsr     SETPIXELCLIP    ; plot (xs-y,ys-x)
606
607         ; og = mo+y+y+1
608         lda     MaxO
609         ldx     MaxO+1
610         add     YY
611         tay
612         txa
613         adc     YY+1
614         tax
615         tya
616         add     YY
617         tay
618         txa
619         adc     YY+1
620         tax
621         tya
622         add     #1
623         bcc     @L0143
624         inx
625 @L0143: sta     OGora
626         stx     OGora+1
627         ; ou = og-x-x+1
628         sub     XX
629         tay
630         txa
631         sbc     XX+1
632         tax
633         tya
634         sub     XX
635         tay
636         txa
637         sbc     XX+1
638         tax
639         tya
640         add     #1
641         bcc     @L0146
642         inx
643 @L0146: sta     OUkos
644         stx     OUkos+1
645         ; ++y
646         inc     YY
647         bne     @L0148
648         inc     YY+1
649 @L0148: ; if (abs(ou)<abs(og))
650         lda     OUkos
651         ldy     OUkos+1
652         jsr     abs
653         sta     TEMP3
654         sty     TEMP4
655         lda     OGora
656         ldy     OGora+1
657         jsr     abs
658         ldx     #TEMP3
659         jsr     icmp
660         bpl     @L0149
661         ; { --x;
662         lda     XX
663         sub     #1
664         sta     XX
665         bcs     @L014E
666         dec     XX+1
667 @L014E: ; mo = ou; }
668         lda     OUkos
669         ldx     OUkos+1
670         jmp     @L014G
671         ; else { mo = og }
672 @L0149: lda     OGora
673         ldx     OGora+1
674 @L014G: sta     MaxO
675         stx     MaxO+1
676         ; }
677         jmp     @L013B
678
679 ; ------------------------------------------------------------------------
680 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
681 ; direction is passend in X/Y, the text direction is passed in A.
682 ;
683 ; Must set an error code: NO
684 ;
685
686 TEXTSTYLE:
687         stx     TEXTMAGX
688         sty     TEXTMAGY
689         asl                             ; 16 <=> 90°
690         asl
691         asl
692         asl
693         sta     TEXTDIR
694         rts
695
696
697 ; ------------------------------------------------------------------------
698 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
699 ; current text style. The text to output is given as a zero terminated
700 ; string with address in ptr3.
701 ;
702 ; Must set an error code: NO
703 ;
704
705 OUTTEXT:
706         ldx     X1
707         ldy     X1+1
708         lda     Y1
709         jsr     HPOSN
710         lda     SHAPE+2*99
711         add     #<SHAPE
712         sta     tmp3
713         lda     SHAPE+2*99+1
714         adc     #>SHAPE
715         sta     tmp3+1
716
717         ldy     #0
718 @L1:    lda     (ptr3),y
719         beq     @end
720         sub     #31                     ; no controls
721         asl                             ; offset*2
722         tax
723         lda     SHAPE,x
724         add     #<SHAPE
725         sta     tmp1
726         lda     SHAPE+1,x
727         adc     #>SHAPE
728         sta     tmp1+1
729         tya
730         pha
731         ldx     tmp1
732         ldy     tmp1+1
733         lda     TEXTDIR
734         jsr     DRAW
735         ldx     tmp3
736         ldy     tmp3+1
737         lda     TEXTDIR
738         jsr     DRAW
739         pla
740         tay
741         iny
742         bne     @L1
743 @end:   rts
744
745 ;-------------
746 ; copies of some runtime routines
747
748 abs:
749         ; a/y := abs(a/y)
750         cpy     #0
751         bpl     @L1
752         ; negay
753         clc
754         eor     #$ff
755         adc     #1
756         pha
757         tya
758         eor     #$ff
759         adc     #0
760         tay
761         pla
762 @L1:    rts
763
764 icmp:
765         ; compare a/y to zp,x
766         sta     TEMP            ; TEMP/TEMP2 - arg2
767         sty     TEMP2
768         lda     $0,x
769         pha
770         lda     $1,x
771         tay
772         pla
773         tax
774         tya                     ; x/a - arg1 (a=high)
775
776         sub     TEMP2
777         bne     @L4
778         cpx     TEMP
779         beq     @L3
780         adc     #$ff
781         ora     #$01
782 @L3:    rts
783 @L4:    bvc     @L3
784         eor     #$ff
785         ora     #$01
786         rts