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