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