]> git.sur5r.net Git - cc65/blob - libsrc/apple2/apple2-280-192-8.s
Changes to the TGI driver API:
[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 ;
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
19 ; Zero page stuff
20
21 HBASL   :=      $26
22 HMASK   :=      $30
23 PAGE    :=      $E6
24 SCALE   :=      $E7
25 ROT     :=      $F9
26
27 ; Graphics entry points, by cbmnut (applenut??) cbmnut@hushmail.com
28
29 TEXT    :=      $F399   ; Return to text screen
30 HGR2    :=      $F3D8   ; Initialize and clear hi-res page 2.
31 HGR     :=      $F3E2   ; Initialize and clear hi-res page 1.
32 HCLR    :=      $F3F2   ; Clear the current hi-res screen to black.
33 BKGND   :=      $F3F6   ; Clear the current hi-res screen to the
34                         ; last plotted color (from ($1C).
35 HPOSN   :=      $F411   ; Positions the hi-res cursor without
36                         ; plotting a point.
37                         ; Enter with (A) = Y-coordinate, and
38                         ; (Y,X) = X-coordinate.
39 HPLOT   :=      $F457   ; Calls HPOSN and tries to plot a dot at
40                         ; the cursor's position.  If you are
41                         ; trying to plot a non-white color at
42                         ; a complementary color position, no
43                         ; dot will be plotted.
44 HLIN    :=      $F53A   ; Draws a line from the last plotted
45                         ; point or line destination to:
46                         ; (X,A) = X-coordinate, and
47                         ; (Y) = Y-coordinate.
48 HFIND   :=      $F5CB   ; Converts the hi-res coursor's position
49                         ; back to X- and Y-coordinates; stores
50                         ; X-coordinate at $E0,E1 and Y-coordinate
51                         ; at $E2.
52 DRAW    :=      $F601   ; Draws a shape.  Enter with (Y,X) = the
53                         ; address of the shape table, and (A) =
54                         ; the rotation factor.  Uses the current
55                         ; color.
56 XDRAW   :=      $F65D   ; Draws a shape by inverting the existing
57                         ; color of the dots the shape draws over.
58                         ; Same entry parameters as DRAW.
59 SETHCOL :=      $F6EC   ; Set the hi-res color to (X), where (X)
60                         ; must be between 0 and 7.
61
62 ; ------------------------------------------------------------------------
63
64 ; Variables mapped to the zero page segment variables. Some of these are
65 ; used for passing parameters to the driver.
66
67 X1      :=      ptr1
68 Y1      :=      ptr2
69 X2      :=      ptr3
70 Y2      :=      ptr4
71
72 ; ------------------------------------------------------------------------
73
74         .segment        "JUMPTABLE"
75
76 ; Header. Includes jump table and constants.
77
78 ; First part of the header is a structure that has a magic and defines the
79 ; capabilities of the driver
80
81         .byte   $74, $67, $69   ; "tgi"
82         .byte   TGI_API_VERSION ; TGI API version number
83 xres:   .word   280             ; X resolution
84 yres:   .word   192             ; Y resolution
85         .byte   8               ; Number of drawing colors
86         .byte   2               ; Number of screens available
87         .byte   8               ; System font X size
88         .byte   8               ; System font Y size
89         .word   $100            ; Aspect ratio
90
91 ; Next comes the jump table. With the exception of IRQ, all entries must be
92 ; valid and may point to an RTS for test versions (function not implemented).
93
94         .addr   INSTALL
95         .addr   UNINSTALL
96         .addr   INIT
97         .addr   DONE
98         .addr   GETERROR
99         .addr   CONTROL
100         .addr   CLEAR
101         .addr   SETVIEWPAGE
102         .addr   SETDRAWPAGE
103         .addr   SETCOLOR
104         .addr   SETPALETTE
105         .addr   GETPALETTE
106         .addr   GETDEFPALETTE
107         .addr   SETPIXEL
108         .addr   GETPIXEL
109         .addr   LINE
110         .addr   BAR
111         .addr   TEXTSTYLE
112         .addr   OUTTEXT
113         .addr   0               ; IRQ entry is unused
114
115 ; ------------------------------------------------------------------------
116
117         .bss
118
119 ; Absolute variables used in the code
120
121 ERROR:  .res    1               ; Error code
122
123         .ifdef  __APPLE2ENH__
124 Set80:  .res    1               ; Set 80 column store
125         .endif
126
127 ; ------------------------------------------------------------------------
128
129         .rodata
130
131 ; Constants and tables
132
133 DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
134
135 SHAPE:  .byte   $64,$01,$D0,$00,$D5,$00,$DA,$00,$E0,$00,$EF,$00,$FE,$00,$0C,$01
136         .byte   $19,$01,$1D,$01,$25,$01,$2D,$01,$3D,$01,$46,$01,$4B,$01,$52,$01
137         .byte   $56,$01,$60,$01,$70,$01,$77,$01,$83,$01,$8E,$01,$9A,$01,$A7,$01
138         .byte   $B6,$01,$BF,$01,$CE,$01,$DD,$01,$E2,$01,$E7,$01,$F9,$01,$03,$02
139         .byte   $15,$02,$1F,$02,$32,$02,$42,$02,$52,$02,$5E,$02,$6C,$02,$79,$02
140         .byte   $85,$02,$91,$02,$A1,$02,$A9,$02,$B2,$02,$BF,$02,$C5,$02,$D5,$02
141         .byte   $E5,$02,$F4,$02,$00,$03,$10,$03,$1F,$03,$2D,$03,$35,$03,$44,$03
142         .byte   $53,$03,$63,$03,$71,$03,$7B,$03,$85,$03,$91,$03,$97,$03,$A3,$03
143         .byte   $B6,$03,$BF,$03,$C3,$03,$CF,$03,$DC,$03,$E4,$03,$F3,$03,$00,$04
144         .byte   $0A,$04,$19,$04,$25,$04,$2A,$04,$32,$04,$3C,$04,$43,$04,$50,$04
145         .byte   $5A,$04,$66,$04,$72,$04,$7E,$04,$87,$04,$94,$04,$9C,$04,$A8,$04
146         .byte   $B4,$04,$C1,$04,$CC,$04,$DB,$04,$E6,$04,$EE,$04,$F3,$04,$FB,$04
147         .byte   $04,$05,$1A,$05,$1F,$05,$24,$05,$29,$05,$22,$01,$00,$00,$00,$00
148         .byte   $09,$89,$92,$92,$00,$36,$36,$16,$0E,$00,$0D,$FE,$6E,$96,$52,$00
149         .byte   $69,$FE,$17,$2D,$2D,$1E,$1F,$17,$2D,$2D,$1E,$1F,$6E,$4E,$00,$09
150         .byte   $8D,$3F,$BF,$0D,$15,$3F,$0E,$0D,$1E,$3F,$77,$71,$09,$00,$6D,$11
151         .byte   $DF,$77,$09,$1E,$17,$4D,$3A,$DF,$4E,$29,$0E,$00,$A9,$1F,$6E,$1E
152         .byte   $17,$0D,$0D,$1E,$DF,$0E,$6D,$0E,$00,$36,$96,$52,$00,$09,$1E,$17
153         .byte   $36,$15,$0E,$0E,$00,$15,$0E,$36,$1E,$17,$4E,$01,$00,$09,$8D,$1F
154         .byte   $1F,$0E,$2D,$1E,$17,$2D,$15,$1F,$1F,$4E,$4E,$01,$00,$89,$6E,$3A
155         .byte   $3F,$77,$31,$56,$09,$00,$92,$8A,$F6,$0D,$00,$52,$89,$3F,$B7,$52
156         .byte   $49,$00,$92,$92,$0E,$00,$49,$11,$17,$1E,$17,$1E,$56,$49,$01,$00
157         .byte   $29,$AD,$DF,$33,$4D,$35,$1F,$1F,$2E,$4D,$FE,$1B,$0E,$2D,$4E,$00
158         .byte   $31,$77,$36,$BE,$2D,$0E,$00,$29,$AD,$DF,$73,$49,$1E,$BF,$1E,$2E
159         .byte   $2D,$75,$00,$2D,$2D,$BE,$3E,$4E,$FE,$1B,$0E,$2D,$4E,$00,$49,$3E
160         .byte   $17,$0D,$FE,$33,$2D,$2D,$1E,$76,$01,$00,$2D,$2D,$DE,$1B,$2E,$2D
161         .byte   $15,$36,$DF,$73,$2D,$4E,$00,$09,$2D,$DE,$BB,$4D,$3A,$3F,$6E,$09
162         .byte   $FE,$1B,$0E,$2D,$4E,$00,$2D,$2D,$BE,$1E,$17,$36,$4E,$09,$00,$29
163         .byte   $AD,$DF,$33,$4D,$F1,$3F,$17,$4D,$31,$DF,$73,$2D,$4E,$00,$29,$AD
164         .byte   $DF,$33,$4D,$31,$3F,$77,$09,$1E,$DF,$2A,$75,$09,$00,$12,$16,$96
165         .byte   $01,$00,$52,$B2,$F6,$0D,$00,$49,$3E,$17,$2D,$2D,$35,$3F,$3F,$3F
166         .byte   $0E,$2D,$2D,$F5,$1B,$77,$4E,$09,$00,$12,$2D,$2D,$DE,$9B,$2D,$2D
167         .byte   $96,$01,$00,$49,$15,$FF,$13,$2D,$2D,$AD,$3F,$3F,$3F,$2E,$2D,$2D
168         .byte   $1E,$37,$4E,$09,$00,$29,$AD,$DF,$73,$09,$1E,$B6,$4E,$01,$00,$09
169         .byte   $2D,$3E,$37,$2D,$3E,$FF,$2A,$2D,$2D,$F5,$3F,$3F,$0E,$2D,$1E,$4D
170         .byte   $01,$00,$09,$15,$1F,$17,$4D,$31,$DF,$33,$2D,$2D,$FE,$1B,$6E,$09
171         .byte   $0E,$00,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$4D,$31,$DF,$33,$2D,$75
172         .byte   $01,$00,$29,$AD,$DF,$33,$36,$4D,$11,$DF,$73,$2D,$4E,$00,$2D,$AD
173         .byte   $DF,$6E,$31,$DF,$6E,$31,$DF,$17,$2D,$75,$01,$00,$2D,$2D,$DE,$1B
174         .byte   $6E,$11,$3F,$37,$36,$2D,$2D,$0E,$00,$2D,$2D,$DE,$1B,$6E,$11,$3F
175         .byte   $37,$36,$4E,$49,$00,$29,$AD,$DF,$33,$36,$4D,$35,$DF,$73,$2D,$75
176         .byte   $00,$4D,$31,$DF,$33,$4D,$31,$3F,$3F,$6E,$09,$FE,$1B,$6E,$09,$0E
177         .byte   $00,$2D,$1E,$36,$36,$17,$2D,$0E,$00,$49,$31,$36,$36,$DF,$73,$2D
178         .byte   $4E,$00,$4D,$F1,$DF,$6E,$1E,$37,$0D,$15,$DF,$6E,$09,$0E,$00,$36
179         .byte   $36,$36,$2D,$75,$00,$4D,$31,$FF,$37,$0D,$0D,$FE,$1F,$6E,$09,$FE
180         .byte   $1B,$6E,$09,$0E,$00,$4D,$31,$DF,$33,$6D,$31,$1F,$1F,$6E,$29,$FE
181         .byte   $1B,$6E,$09,$0E,$00,$29,$AD,$DF,$33,$4D,$31,$DF,$33,$4D,$31,$DF
182         .byte   $73,$2D,$4E,$00,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$36,$4E,$49,$00
183         .byte   $29,$AD,$DF,$33,$4D,$31,$DF,$33,$0D,$0D,$1E,$DF,$0E,$6D,$0E,$00
184         .byte   $2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$0D,$15,$DF,$6E,$09,$0E,$00,$29
185         .byte   $AD,$DF,$33,$4D,$3A,$77,$09,$FE,$1B,$0E,$2D,$4E,$00,$2D,$2D,$DE
186         .byte   $36,$36,$76,$09,$00,$4D,$31,$DF,$33,$4D,$31,$DF,$33,$4D,$31,$DF
187         .byte   $73,$2D,$4E,$00,$4D,$31,$DF,$33,$4D,$31,$DF,$33,$4D,$F1,$1F,$0E
188         .byte   $4E,$01,$00,$4D,$31,$DF,$33,$4D,$31,$1F,$1F,$6E,$0D,$3E,$1F,$37
189         .byte   $4D,$71,$00,$4D,$31,$DF,$73,$0D,$1E,$17,$0D,$15,$DF,$33,$4D,$71
190         .byte   $00,$4D,$31,$DF,$73,$0D,$1E,$36,$76,$09,$00,$2D,$2D,$BE,$1E,$17
191         .byte   $1E,$2E,$2D,$75,$00,$2D,$2D,$DE,$3B,$2E,$3E,$2E,$3E,$2E,$2D,$75
192         .byte   $00,$72,$15,$0E,$15,$56,$00,$2D,$2D,$3E,$2E,$3E,$2E,$3E,$DF,$2A
193         .byte   $2D,$75,$00,$49,$15,$3F,$17,$2D,$2D,$15,$3F,$3F,$3F,$4E,$2D,$3E
194         .byte   $37,$2D,$3E,$6F,$49,$00,$92,$92,$49,$11,$3F,$3F,$4D,$09,$00,$76
195         .byte   $96,$52,$00,$52,$2D,$35,$DF,$33,$4D,$31,$FF,$73,$6D,$0E,$00,$36
196         .byte   $2D,$AD,$DF,$33,$4D,$31,$DF,$33,$2D,$75,$01,$00,$52,$2D,$DE,$33
197         .byte   $76,$2D,$0E,$00,$49,$31,$DF,$2A,$2D,$FE,$1B,$6E,$09,$FE,$1B,$0E
198         .byte   $2D,$75,$00,$52,$2D,$15,$DF,$33,$2D,$2D,$DE,$1B,$0E,$2D,$75,$00
199         .byte   $09,$F5,$33,$8D,$3F,$77,$36,$4E,$01,$00,$52,$2D,$35,$DF,$33,$4D
200         .byte   $31,$3F,$77,$09,$1E,$3F,$4D,$01,$00,$36,$2D,$AD,$DF,$33,$4D,$31
201         .byte   $DF,$33,$4D,$71,$00,$16,$36,$36,$0E,$00,$09,$9E,$35,$36,$F6,$6F
202         .byte   $01,$00,$36,$4D,$1E,$1F,$2E,$15,$1F,$6E,$71,$00,$35,$36,$36,$17
203         .byte   $2D,$0E,$00,$12,$2D,$AD,$1F,$1F,$6E,$0D,$FE,$1F,$6E,$0D,$0E,$00
204         .byte   $12,$2D,$15,$DF,$6E,$31,$DF,$6E,$71,$00,$52,$2D,$15,$DF,$33,$4D
205         .byte   $31,$DF,$73,$2D,$4E,$00,$12,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$6E
206         .byte   $49,$00,$52,$2D,$35,$DF,$33,$4D,$31,$3F,$77,$09,$2E,$00,$12,$0D
207         .byte   $AD,$DF,$37,$36,$4E,$49,$00,$52,$2D,$F5,$DB,$0E,$2D,$15,$DF,$13
208         .byte   $2D,$75,$01,$00,$31,$17,$2D,$F5,$33,$76,$75,$00,$12,$4D,$31,$DF
209         .byte   $33,$4D,$31,$FF,$73,$6D,$0E,$00,$12,$4D,$31,$DF,$33,$4D,$F1,$1F
210         .byte   $0E,$4E,$01,$00,$12,$4D,$31,$DF,$33,$0D,$0D,$FE,$1F,$0E,$0D,$4E
211         .byte   $00,$12,$4D,$F1,$1F,$0E,$15,$1F,$17,$4D,$71,$00,$12,$4D,$31,$DF
212         .byte   $33,$4D,$31,$3F,$77,$09,$1E,$3F,$4D,$01,$00,$12,$2D,$2D,$1E,$17
213         .byte   $1E,$17,$2D,$2D,$0E,$00,$09,$F5,$33,$1E,$0E,$76,$75,$00,$36,$36
214         .byte   $36,$2E,$00,$AD,$AE,$17,$FE,$2A,$4E,$01,$00,$69,$11,$1F,$1F,$4E
215         .byte   $B1,$92,$09,$00,$2D,$2D,$35,$3F,$3F,$37,$2D,$2D,$35,$3F,$3F,$37
216         .byte   $2D,$2D,$35,$3F,$3F,$37,$2D,$2D,$75,$00,$40,$C0,$40,$18,$00,$40
217         .byte   $C0,$40,$43,$00,$40,$C0,$40,$08,$00,$19,$00,$00
218
219 ; ------------------------------------------------------------------------
220
221         .code
222
223 ; INIT: Changes an already installed device from text mode to graphics mode.
224 ; Note that INIT/DONE may be called multiple times while the driver
225 ; is loaded, while INSTALL is only called once, so any code that is needed
226 ; to initializes variables and so on must go here. Setting palette and
227 ; clearing the screen is not needed because this is called by the graphics
228 ; kernel later.
229 ; The graphics kernel will never call INIT when a graphics mode is already
230 ; active, so there is no need to protect against that.
231 ; Must set an error code: YES
232 INIT:
233         .ifdef  __APPLE2ENH__
234         ; Save and clear 80 column store
235         lda     RD80COL
236         sta     Set80
237         sta     CLR80COL
238         .endif
239
240         ; Switch into graphics mode
241         bit     HIRES
242         bit     MIXCLR
243         bit     TXTCLR
244
245         ; Done, reset the error code
246         lda     #TGI_ERR_OK
247         sta     ERROR
248
249         ; Fall through
250
251 ; INSTALL routine. Is called after the driver is loaded into memory. May
252 ; initialize anything that has to be done just once. Is probably empty
253 ; most of the time.
254 ; Must set an error code: NO
255 INSTALL:
256         ; Fall through
257
258 ; UNINSTALL routine. Is called before the driver is removed from memory. May
259 ; clean up anything done by INSTALL but is probably empty most of the time.
260 ; Must set an error code: NO
261 UNINSTALL:
262         rts
263
264 ; DONE: Will be called to switch the graphics device back into text mode.
265 ; The graphics kernel will never call DONE when no graphics mode is active,
266 ; so there is no need to protect against that.
267 ; Must set an error code: NO
268 DONE:
269         ; Switch into text mode
270         bit     TXTSET
271         bit     LOWSCR
272
273         .ifdef  __APPLE2ENH__
274         ; Restore 80 column store
275         lda     Set80
276         bpl     :+
277         sta     SET80COL
278 :       bit     LORES           ; Limit SET80COL-HISCR to text
279         .endif
280         rts
281
282 ; GETERROR: Return the error code in A and clear it.
283 GETERROR:
284         lda     ERROR
285         ldx     #TGI_ERR_OK
286         stx     ERROR
287         rts
288
289 ; CLEAR: Clears the screen.
290 ; Must set an error code: NO
291 CLEAR:
292         bit     $C082           ; Switch in ROM
293         jsr     HCLR
294         bit     $C080           ; Switch in LC bank 2 for R/O
295         rts
296
297 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
298 ; The page number is already checked to be valid by the graphics kernel.
299 ; Must set an error code: NO (will only be called if page ok)
300 SETVIEWPAGE:
301         tax
302         .assert LOWSCR + 1 = HISCR, error
303         lda     LOWSCR,x        ; No BIT absolute,X available
304         rts
305
306 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
307 ; The page number is already checked to be valid by the graphics kernel.
308 ; Must set an error code: NO (will only be called if page ok)
309 SETDRAWPAGE:
310         tax
311         beq     :+
312         lda     #>$4000         ; Page 2
313         .byte   $2C             ; BIT absolute
314 :       lda     #>$2000         ; Page 1
315         sta     PAGE
316         rts
317
318 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
319 ; to be in a valid range (0..maxcolor-1).
320 ; Must set an error code: NO (will only be called if color ok)
321 SETCOLOR:
322         bit     $C082           ; Switch in ROM
323         tax
324         jsr     SETHCOL
325         bit     $C080           ; Switch in LC bank 2 for R/O
326         rts
327
328 ; CONTROL: Platform/driver specific entry point.
329 ; Must set an error code: YES
330 CONTROL:
331         ; Fall through
332
333 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
334 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
335 ; are not supported
336 ; Must set an error code: YES
337 SETPALETTE:
338         lda     #TGI_ERR_INV_FUNC
339         sta     ERROR
340         rts
341
342 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
343 ; set the palette should return the default palette here, so there's no
344 ; way for this function to fail.
345 ; Must set an error code: NO
346 GETPALETTE:
347         ; Fall through
348
349 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
350 ; drivers should return something reasonable here, even drivers that don't
351 ; support palettes, otherwise the caller has no way to determine the colors
352 ; of the (not changeable) palette.
353 ; Must set an error code: NO (all drivers must have a default palette)
354 GETDEFPALETTE:
355         lda     #<DEFPALETTE
356         ldx     #>DEFPALETTE
357         rts
358
359 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
360 ; color. The coordinates passed to this function are never outside the
361 ; visible screen area, so there is no need for clipping inside this function.
362 ; Must set an error code: NO
363 SETPIXEL:
364         bit     $C082           ; Switch in ROM
365         ldx     X1
366         ldy     X1+1
367         lda     Y1
368         jsr     HPLOT
369         bit     $C080           ; Switch in LC bank 2 for R/O
370         rts
371
372 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
373 ; coordinates passed to this function are never outside the visible screen
374 ; area, so there is no need for clipping inside this function.
375 GETPIXEL:
376         bit     $C082           ; Switch in ROM
377         ldx     X1
378         ldy     X1+1
379         lda     Y1
380         jsr     HPOSN
381         lda     (HBASL),y
382         and     HMASK
383         asl
384         beq     :+              ; 0 (black)
385         lda     #$03            ; 3 (white)
386 :       bcc     :+
387         adc     #$03            ; += 4 (black -> black2, white -> white2)
388 :       ldx     #$00
389         bit     $C080           ; Switch in LC bank 2 for R/O
390         rts
391
392 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
393 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
394 ; Must set an error code: NO
395 LINE:
396         bit     $C082           ; Switch in ROM
397         ldx     X1
398         ldy     X1+1
399         lda     Y1
400         jsr     HPOSN
401         lda     X2
402         ldx     X2+1
403         ldy     Y2
404         jsr     HLIN
405         bit     $C080           ; Switch in LC bank 2 for R/O
406         rts
407
408 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
409 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
410 ; Contrary to most other functions, the graphics kernel will sort and clip
411 ; the coordinates before calling the driver, so on entry the following
412 ; conditions are valid:
413 ;       X1 <= X2
414 ;       Y1 <= Y2
415 ;       (X1 >= 0) && (X1 < XRES)
416 ;       (X2 >= 0) && (X2 < XRES)
417 ;       (Y1 >= 0) && (Y1 < YRES)
418 ;       (Y2 >= 0) && (Y2 < YRES)
419 ; Must set an error code: NO
420 BAR:
421         inc     Y2
422 :       lda     Y2
423         pha
424         lda     Y1
425         sta     Y2
426         jsr     LINE
427         pla
428         sta     Y2
429         inc     Y1
430         cmp     Y1
431         bne     :-
432         rts
433
434 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
435 ; direction is passend in X/Y, the text direction is passed in A.
436 ; Must set an error code: NO
437 TEXTSTYLE:
438         stx     SCALE
439         asl                     ; 16 <=> 90รพ
440         asl
441         asl
442         asl
443         sta     ROT
444         rts
445
446 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
447 ; current text style. The text to output is given as a zero terminated
448 ; string with address in ptr3.
449 ; Must set an error code: NO
450 OUTTEXT:
451         bit     $C082           ; Switch in ROM
452         ldx     X1
453         ldy     X1+1
454         lda     Y1
455         jsr     HPOSN
456         lda     SHAPE+2*99
457         add     #<SHAPE
458         sta     tmp3
459         lda     SHAPE+2*99+1
460         adc     #>SHAPE
461         sta     tmp3+1
462
463         ldy     #$00
464 :       lda     (ptr3),y
465         beq     :+
466         sub     #$1F            ; No controls
467         asl                     ; Offset * 2
468         tax
469         lda     SHAPE,x
470         add     #<SHAPE
471         sta     tmp1
472         lda     SHAPE+1,x
473         adc     #>SHAPE
474         sta     tmp1+1
475         tya
476         pha
477         ldx     tmp1
478         ldy     tmp1+1
479         lda     ROT
480         jsr     DRAW
481         ldx     tmp3
482         ldy     tmp3+1
483         lda     ROT
484         jsr     DRAW
485         pla
486         tay
487         iny
488         bne     :-
489 :       bit     $C080           ; Switch in LC bank 2 for R/O
490         rts