]> git.sur5r.net Git - cc65/blob - libsrc/apple2/apple2-280-192-8.s
c152b343e656de370a254875500343ab3fbbc2c4
[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 ; ------------------------------------------------------------------------
16
17 ; Zero page stuff
18
19 HBASL   :=      $26
20 HMASK   :=      $30
21 PAGE    :=      $E6
22 SCALE   :=      $E7
23 ROT     :=      $F9
24
25 ; Graphics entry points, by cbmnut (applenut??) cbmnut@hushmail.com
26
27 TEXT    :=      $F399   ; Return to text screen
28 HGR2    :=      $F3D8   ; Initialize and clear hi-res page 2.
29 HGR     :=      $F3E2   ; Initialize and clear hi-res page 1.
30 HCLR    :=      $F3F2   ; Clear the current hi-res screen to black.
31 BKGND   :=      $F3F6   ; Clear the current hi-res screen to the
32                         ; last plotted color (from ($1C).
33 HPOSN   :=      $F411   ; Positions the hi-res cursor without
34                         ; plotting a point.
35                         ; Enter with (A) = Y-coordinate, and
36                         ; (Y,X) = X-coordinate.
37 HPLOT   :=      $F457   ; Calls HPOSN and tries to plot a dot at
38                         ; the cursor's position.  If you are
39                         ; trying to plot a non-white color at
40                         ; a complementary color position, no
41                         ; dot will be plotted.
42 HLIN    :=      $F53A   ; Draws a line from the last plotted
43                         ; point or line destination to:
44                         ; (X,A) = X-coordinate, and
45                         ; (Y) = Y-coordinate.
46 HFIND   :=      $F5CB   ; Converts the hi-res coursor's position
47                         ; back to X- and Y-coordinates; stores
48                         ; X-coordinate at $E0,E1 and Y-coordinate
49                         ; at $E2.
50 DRAW    :=      $F601   ; Draws a shape.  Enter with (Y,X) = the
51                         ; address of the shape table, and (A) =
52                         ; the rotation factor.  Uses the current
53                         ; color.
54 XDRAW   :=      $F65D   ; Draws a shape by inverting the existing
55                         ; color of the dots the shape draws over.
56                         ; Same entry parameters as DRAW.
57 SETHCOL :=      $F6EC   ; Set the hi-res color to (X), where (X)
58                         ; must be between 0 and 7.
59
60 ; ------------------------------------------------------------------------
61
62 ; Variables mapped to the zero page segment variables. Some of these are
63 ; used for passing parameters to the driver.
64
65 X1      :=      ptr1
66 Y1      :=      ptr2
67 X2      :=      ptr3
68 Y2      :=      ptr4
69
70 ; ------------------------------------------------------------------------
71
72         .segment        "JUMPTABLE"
73
74 ; Header. Includes jump table and constants.
75
76 ; First part of the header is a structure that has a magic and defines the
77 ; capabilities of the driver
78
79         .byte   $74, $67, $69   ; "tgi"
80         .byte   TGI_API_VERSION ; TGI API version number
81 xres:   .word   280             ; X resolution
82 yres:   .word   192             ; Y resolution
83         .byte   8               ; Number of drawing colors
84         .byte   2               ; Number of screens available
85         .byte   8               ; System font X size
86         .byte   8               ; System font Y size
87         .word   $100            ; Aspect ratio
88
89 ; Next comes the jump table. With the exception of IRQ, all entries must be
90 ; valid and may point to an RTS for test versions (function not implemented).
91
92         .addr   INSTALL
93         .addr   UNINSTALL
94         .addr   INIT
95         .addr   DONE
96         .addr   GETERROR
97         .addr   CONTROL
98         .addr   CLEAR
99         .addr   SETVIEWPAGE
100         .addr   SETDRAWPAGE
101         .addr   SETCOLOR
102         .addr   SETPALETTE
103         .addr   GETPALETTE
104         .addr   GETDEFPALETTE
105         .addr   SETPIXEL
106         .addr   GETPIXEL
107         .addr   LINE
108         .addr   BAR
109         .addr   TEXTSTYLE
110         .addr   OUTTEXT
111         .addr   0               ; IRQ entry is unused
112
113 ; ------------------------------------------------------------------------
114
115         .bss
116
117 ; Absolute variables used in the code
118
119 ERROR:  .res    1               ; Error code
120
121         .ifdef  __APPLE2ENH__
122 Set80:  .res    1               ; Set 80 column store
123         .endif
124
125 ; ------------------------------------------------------------------------
126
127         .rodata
128
129 ; Constants and tables
130
131 DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
132
133 SHAPE:
134         ; Beagle Bros Shape Mechanic font F.ASCII.SMALL
135         .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         ; Beagle Bros Shape Mechanic fonts don't
246         ; scale well so use fixed scaling factor
247         lda     #1
248         sta     SCALE
249
250         ; Done, reset the error code
251         lda     #TGI_ERR_OK
252         sta     ERROR
253
254         ; Fall through
255
256 ; INSTALL routine. Is called after the driver is loaded into memory. May
257 ; initialize anything that has to be done just once. Is probably empty
258 ; most of the time.
259 ; Must set an error code: NO
260 INSTALL:
261         ; Fall through
262
263 ; UNINSTALL routine. Is called before the driver is removed from memory. May
264 ; clean up anything done by INSTALL but is probably empty most of the time.
265 ; Must set an error code: NO
266 UNINSTALL:
267         rts
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 ; Must set an error code: NO
273 DONE:
274         ; Switch into text mode
275         bit     TXTSET
276         bit     LOWSCR
277
278         .ifdef  __APPLE2ENH__
279         ; Restore 80 column store
280         lda     Set80
281         bpl     :+
282         sta     SET80COL
283 :       bit     LORES           ; Limit SET80COL-HISCR to text
284         .endif
285         rts
286
287 ; GETERROR: Return the error code in A and clear it.
288 GETERROR:
289         lda     ERROR
290         ldx     #TGI_ERR_OK
291         stx     ERROR
292         rts
293
294 ; CLEAR: Clears the screen.
295 ; Must set an error code: NO
296 CLEAR:
297         bit     $C082           ; Switch in ROM
298         jsr     HCLR
299         bit     $C080           ; Switch in LC bank 2 for R/O
300         rts
301
302 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
303 ; The page number is already checked to be valid by the graphics kernel.
304 ; Must set an error code: NO (will only be called if page ok)
305 SETVIEWPAGE:
306         tax
307         .assert LOWSCR + 1 = HISCR, error
308         lda     LOWSCR,x        ; No BIT absolute,X available
309         rts
310
311 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
312 ; The page number is already checked to be valid by the graphics kernel.
313 ; Must set an error code: NO (will only be called if page ok)
314 SETDRAWPAGE:
315         tax
316         beq     :+
317         lda     #>$4000         ; Page 2
318         .byte   $2C             ; BIT absolute
319 :       lda     #>$2000         ; Page 1
320         sta     PAGE
321         rts
322
323 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
324 ; to be in a valid range (0..maxcolor-1).
325 ; Must set an error code: NO (will only be called if color ok)
326 SETCOLOR:
327         bit     $C082           ; Switch in ROM
328         tax
329         jsr     SETHCOL
330         bit     $C080           ; Switch in LC bank 2 for R/O
331         rts
332
333 ; CONTROL: Platform/driver specific entry point.
334 ; Must set an error code: YES
335 CONTROL:
336         ; Fall through
337
338 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
339 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
340 ; are not supported
341 ; Must set an error code: YES
342 SETPALETTE:
343         lda     #TGI_ERR_INV_FUNC
344         sta     ERROR
345         rts
346
347 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
348 ; set the palette should return the default palette here, so there's no
349 ; way for this function to fail.
350 ; Must set an error code: NO
351 GETPALETTE:
352         ; Fall through
353
354 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
355 ; drivers should return something reasonable here, even drivers that don't
356 ; support palettes, otherwise the caller has no way to determine the colors
357 ; of the (not changeable) palette.
358 ; Must set an error code: NO (all drivers must have a default palette)
359 GETDEFPALETTE:
360         lda     #<DEFPALETTE
361         ldx     #>DEFPALETTE
362         rts
363
364 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
365 ; color. The coordinates passed to this function are never outside the
366 ; visible screen area, so there is no need for clipping inside this function.
367 ; Must set an error code: NO
368 SETPIXEL:
369         bit     $C082           ; Switch in ROM
370         ldx     X1
371         ldy     X1+1
372         lda     Y1
373         jsr     HPLOT
374         bit     $C080           ; Switch in LC bank 2 for R/O
375         rts
376
377 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
378 ; coordinates passed to this function are never outside the visible screen
379 ; area, so there is no need for clipping inside this function.
380 GETPIXEL:
381         bit     $C082           ; Switch in ROM
382         ldx     X1
383         ldy     X1+1
384         lda     Y1
385         jsr     HPOSN
386         lda     (HBASL),y
387         and     HMASK
388         asl
389         beq     :+              ; 0 (black)
390         lda     #$03            ; 3 (white)
391 :       bcc     :+
392         adc     #$03            ; += 4 (black -> black2, white -> white2)
393 :       ldx     #$00
394         bit     $C080           ; Switch in LC bank 2 for R/O
395         rts
396
397 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
398 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
399 ; Must set an error code: NO
400 LINE:
401         bit     $C082           ; Switch in ROM
402         ldx     X1
403         ldy     X1+1
404         lda     Y1
405         jsr     HPOSN
406         lda     X2
407         ldx     X2+1
408         ldy     Y2
409         jsr     HLIN
410         bit     $C080           ; Switch in LC bank 2 for R/O
411         rts
412
413 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
414 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
415 ; Contrary to most other functions, the graphics kernel will sort and clip
416 ; the coordinates before calling the driver, so on entry the following
417 ; conditions are valid:
418 ;       X1 <= X2
419 ;       Y1 <= Y2
420 ;       (X1 >= 0) && (X1 < XRES)
421 ;       (X2 >= 0) && (X2 < XRES)
422 ;       (Y1 >= 0) && (Y1 < YRES)
423 ;       (Y2 >= 0) && (Y2 < YRES)
424 ; Must set an error code: NO
425 BAR:
426         inc     Y2
427 :       lda     Y2
428         pha
429         lda     Y1
430         sta     Y2
431         jsr     LINE
432         pla
433         sta     Y2
434         inc     Y1
435         cmp     Y1
436         bne     :-
437         rts
438
439 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
440 ; direction is passend in X/Y, the text direction is passed in A.
441 ; Must set an error code: NO
442 TEXTSTYLE:
443         cmp     #TGI_TEXT_VERTICAL
444         bne     :+
445         lda     #48
446 :       sta     ROT
447         rts
448
449 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
450 ; current text style. The text to output is given as a zero terminated
451 ; string with address in ptr3.
452 ; Must set an error code: NO
453 OUTTEXT:
454         bit     $C082           ; Switch in ROM
455         lda     X1
456         ldy     X1+1
457         ldx     ROT
458         php                     ; Save Z flag
459         beq     :+              ; Not horizontal
460         sec
461         sbc     #7              ; Adjust X
462         bcs     :+
463         dey
464 :       tax
465         lda     Y1
466         plp                     ; Restore Z flag
467         bne     :+              ; Not vertical
468         sec
469         sbc     #7              ; Adjust Y
470 :       jsr     HPOSN
471         clc
472         lda     SHAPE+2*99      ; "connection char"
473         adc     #<SHAPE
474         sta     ptr4
475         lda     SHAPE+2*99+1    ; "connection char"
476         adc     #>SHAPE
477         sta     ptr4+1
478         ldy     #$00
479 :       lda     (ptr3),y
480         beq     :+
481         sty     tmp1            ; Save string index
482         sec
483         sbc     #$1F            ; No control chars
484         asl                     ; Offset * 2
485         tay
486         clc
487         lda     SHAPE,y
488         adc     #<SHAPE
489         tax
490         lda     SHAPE+1,y
491         adc     #>SHAPE
492         tay
493         lda     ROT
494         jsr     DRAW            ; Draw char from string
495         ldx     ptr4
496         ldy     ptr4+1
497         lda     ROT
498         jsr     DRAW            ; Draw "connection char"
499         ldy     tmp1            ; Restore string index
500         iny
501         bne     :-              ; Branch always
502 :       bit     $C080           ; Switch in LC bank 2 for R/O
503         rts