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