]> git.sur5r.net Git - cc65/blob - libsrc/geos/devel/geos-tgi.s
Minor comment adjustment.
[cc65] / libsrc / geos / devel / geos-tgi.s
1 ;
2 ; Graphics driver for the 320x200x2 or 640x200x2 mode on GEOS 64/128
3 ; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
4 ; 28-31.12.2002
5
6         .include        "zeropage.inc"
7
8         .include        "tgi-kernel.inc"
9         .include        "tgi-mode.inc"
10         .include        "tgi-error.inc"
11
12         .include        "../inc/const.inc"
13         .include        "../inc/jumptab.inc"
14         .include        "../inc/geossym.inc"
15         .include        "../inc/geossym2.inc"
16
17         .macpack        generic
18
19 ; ------------------------------------------------------------------------
20 ; Constants
21
22 VDC_ADDR_REG      = $D600                 ; VDC address
23 VDC_DATA_REG      = $D601                 ; VDC data
24
25 VDC_DSP_HI        = 12                    ; registers used
26 VDC_DSP_LO        = 13
27 VDC_DATA_HI       = 18
28 VDC_DATA_LO       = 19
29 VDC_VSCROLL       = 24
30 VDC_HSCROLL       = 25
31 VDC_COLORS        = 26
32 VDC_CSET          = 28
33 VDC_COUNT         = 30
34 VDC_DATA          = 31
35
36 ; ------------------------------------------------------------------------
37 ; Header. Includes jump table and constants.
38
39 .segment        "JUMPTABLE"
40
41 ; First part of the header is a structure that has a magic and defines the
42 ; capabilities of the driver
43
44         .byte   $74, $67, $69           ; "tgi"
45         .byte   TGI_API_VERSION         ; TGI API version number
46 xres:   .word   320                     ; X resolution
47 yres:   .word   200                     ; Y resolution
48         .byte   2                       ; Number of drawing colors
49 pages:  .byte   1                       ; Number of screens available
50         .byte   8                       ; System font X size
51         .byte   8                       ; System font Y size
52         .res    4, $00                  ; Reserved for future extensions
53
54 ; Next comes the jump table. Currently all entries must be valid and may point
55 ; to an RTS for test versions (function not implemented).
56
57         .word   INSTALL
58         .word   UNINSTALL
59         .word   INIT
60         .word   DONE
61         .word   GETERROR
62         .word   CONTROL
63         .word   CLEAR
64         .word   SETVIEWPAGE
65         .word   SETDRAWPAGE
66         .word   SETCOLOR
67         .word   SETPALETTE
68         .word   GETPALETTE
69         .word   GETDEFPALETTE
70         .word   SETPIXEL
71         .word   GETPIXEL
72         .word   LINE
73         .word   BAR
74         .word   CIRCLE
75         .word   TEXTSTYLE
76         .word   OUTTEXT
77
78 ; ------------------------------------------------------------------------
79 ; Data.
80
81 ; Variables mapped to the zero page segment variables. Some of these are
82 ; used for passing parameters to the driver.
83
84 X1              = ptr1
85 Y1              = ptr2
86 X2              = ptr3
87 Y2              = ptr4
88 RADIUS          = tmp1
89
90 ADDR            = tmp1
91 TEMP            = tmp3
92 TEMP2           = tmp4
93 TEMP3           = sreg
94 TEMP4           = sreg+1
95
96 ; Circle stuff
97 XX              = ptr3          ; (2)   CIRCLE
98 YY              = ptr4          ; (2)   CIRCLE
99 MaxO            = sreg          ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
100 XS              = regsave       ; (2)   CIRCLE
101 YS              = regsave+2     ; (2)   CIRCLE
102
103 ; Absolute variables used in the code
104
105 .bss
106
107 SCRBASE:        .res    1       ; High byte of screen base (64k VDC only)
108
109 ERROR:          .res    1       ; Error code
110 PALETTE:        .res    2       ; The current palette
111
112 BITMASK:        .res    1       ; $00 = clear, $01 = set pixels
113
114 OLDCOLOR:       .res    1       ; colors before entering gfx mode
115
116 ; Line routine stuff (combined with CIRCLE to save space)
117
118 OGora:           .res   2
119 OUkos:           .res   2
120 Y3:              .res   2
121
122 ; Text output stuff
123 TEXTMAGX:       .res    1
124 TEXTMAGY:       .res    1
125 TEXTDIR:        .res    1
126
127 ; Constants and tables
128
129 .rodata
130
131 DEFPALETTE:     .byte   $00, $0f        ; White on black
132 PALETTESIZE     = * - DEFPALETTE
133
134 ; color translation table (indexed by VIC color)
135 COLTRANS:       .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
136                 .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
137                 ; colors BROWN and GRAY3 are wrong
138
139 .code
140
141 ; ------------------------------------------------------------------------
142 ; INSTALL routine. Is called after the driver is loaded into memory. May
143 ; initialize anything that has to be done just once. Is probably empty
144 ; most of the time.
145 ;
146 ; Must set an error code: NO
147 ;
148
149 INSTALL:
150         lda version             ; if GEOS 1.0...
151         and #$f0
152         cmp #$10
153         beq @L40
154         lda c128Flag            ; at least GEOS 2.0, but we're on C128?
155         bpl @L40
156         lda graphMode           ; GEOS 2.0, C128, but is 80 column screen enabled?
157         bmi @L80
158 @L40:   rts                     ; leave default values for 40 column screen
159
160         ; check for VDC version and update register $19 value
161
162 @L80:
163         lda     #<640
164         ldx     #>640
165         sta     xres
166         stx     xres+1
167
168         ; update number of available screens
169
170         ldx     #VDC_CSET       ; determine size of RAM...
171         jsr     VDCReadReg
172         sta     tmp1
173         ora     #%00010000
174         jsr     VDCWriteReg     ; turn on 64k
175
176         jsr     settestadr1     ; save original value of test byte
177         jsr     VDCReadByte
178         sta     tmp2
179
180         lda     #$55            ; write $55 here
181         ldy     #ptr1
182         jsr     test64k         ; read it here and there
183         lda     #$aa            ; write $aa here
184         ldy     #ptr2
185         jsr     test64k         ; read it here and there
186
187         jsr     settestadr1
188         lda     tmp2
189         jsr     VDCWriteByte    ; restore original value of test byte
190
191         lda     ptr1            ; do bytes match?
192         cmp     ptr1+1
193         bne     @have64k
194         lda     ptr2
195         cmp     ptr2+1
196         bne     @have64k
197
198         ldx     #VDC_CSET
199         lda     tmp1
200         jsr     VDCWriteReg     ; restore 16/64k flag
201         jmp     @endok          ; and leave default values for 16k
202
203 @have64k:
204         lda     #4
205         sta     pages
206 @endok:
207         lda     #0
208         sta     SCRBASE         ; draw page 0 as default
209         rts
210
211 test64k:
212         sta     tmp1
213         sty     ptr3
214         lda     #0
215         sta     ptr3+1
216         jsr     settestadr1
217         lda     tmp1
218         jsr     VDCWriteByte            ; write $55
219         jsr     settestadr1
220         jsr     VDCReadByte             ; read here
221         pha
222         jsr     settestadr2
223         jsr     VDCReadByte             ; and there
224         ldy     #1
225         sta     (ptr3),y
226         pla
227         dey
228         sta     (ptr3),y
229         rts
230
231 settestadr1:
232         ldy     #$02                    ; test page 2 (here)
233         .byte   $2c
234 settestadr2:
235         ldy     #$42                    ; or page 64+2 (there)
236         lda     #0
237         jmp     VDCSetSourceAddr
238
239 ; ------------------------------------------------------------------------
240 ; UNINSTALL routine. Is called before the driver is removed from memory. May
241 ; clean up anything done by INSTALL but is probably empty most of the time.
242 ;
243 ; Must set an error code: NO
244 ;
245
246 UNINSTALL:
247         rts
248
249
250 ; ------------------------------------------------------------------------
251 ; INIT: Changes an already installed device from text mode to graphics
252 ; mode.
253 ; Note that INIT/DONE may be called multiple times while the driver
254 ; is loaded, while INSTALL is only called once, so any code that is needed
255 ; to initializes variables and so on must go here. Setting palette and
256 ; clearing the screen is not needed because this is called by the graphics
257 ; kernel later.
258 ; The graphics kernel will never call INIT when a graphics mode is already
259 ; active, so there is no need to protect against that.
260 ;
261 ; Must set an error code: YES
262 ;
263
264 INIT:
265         ldx #$01
266         stx BITMASK             ; solid black as pattern
267         lda #1
268         jsr SetPattern
269         lda #ST_WR_FORE         ; write only on foreground
270         sta dispBufferOn
271
272         lda graphMode
273         bmi @L80
274
275 ; Remember current color value (40 columns)
276         lda screencolors
277         sta OLDCOLOR
278         jmp @L99
279
280 ; Remember current color value (80 columns)
281 @L80:   lda scr80colors
282         sta OLDCOLOR
283 @L99:   lda #0
284         jsr SETVIEWPAGE         ; switch into viewpage 0
285
286 ; Done, reset the error code
287
288         lda     #TGI_ERR_OK
289         sta     ERROR
290         rts
291
292 ; ------------------------------------------------------------------------
293 ; DONE: Will be called to switch the graphics device back into text mode.
294 ; The graphics kernel will never call DONE when no graphics mode is active,
295 ; so there is no need to protect against that.
296 ;
297 ; Must set an error code: NO
298 ;
299
300 DONE:
301         lda #0
302         jsr SETVIEWPAGE         ; switch into viewpage 0
303
304         lda graphMode
305         bmi @L80
306
307         lda OLDCOLOR
308         sta screencolors        ; restore color for 40 columns
309         ldx #0
310 @L1:    sta COLOR_MATRIX,x
311         sta COLOR_MATRIX+$0100,x
312         sta COLOR_MATRIX+$0200,x
313         sta COLOR_MATRIX+1000-256,x
314         inx
315         bne @L1
316         rts
317
318 @L80:   lda OLDCOLOR            ; restore color for 80 columns
319         ldx #VDC_COLORS
320         jmp VDCWriteReg
321
322 ; ------------------------------------------------------------------------
323 ; GETERROR: Return the error code in A and clear it.
324
325 GETERROR:
326         ldx     #TGI_ERR_OK
327         lda     ERROR
328         stx     ERROR
329         rts
330
331 ; ------------------------------------------------------------------------
332 ; CONTROL: Platform/driver specific entry point.
333 ;
334 ; Must set an error code: YES
335 ;
336
337 CONTROL:
338         lda     #TGI_ERR_INV_FUNC
339         sta     ERROR
340         rts
341
342 ; ------------------------------------------------------------------------
343 ; CLEAR: Clears the screen.
344 ;
345 ; Must set an error code: NO
346 ;
347
348 CLEAR:
349             lda curPattern
350             pha
351             lda #0
352             jsr SetPattern
353             ldx #0
354             stx r3L
355             stx r3H
356             stx r2L
357             lda #199
358             sta r2H
359             lda graphMode
360             bpl @L40
361             lda #>639                   ; 80 columns
362             ldx #<639
363             bne @L99
364 @L40:       lda #>319                   ; 40 columns
365             ldx #<319
366 @L99:       sta r4H
367             stx r4L
368             jsr Rectangle
369             pla
370             sta curPattern
371             rts
372
373 ; ------------------------------------------------------------------------
374 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
375 ; The page number is already checked to be valid by the graphics kernel.
376 ;
377 ; Must set an error code: NO (will only be called if page ok)
378 ;
379
380 SETVIEWPAGE:
381         ldx graphMode
382         bmi @L80
383         rts
384 @L80:   clc
385         ror
386         ror
387         ror
388         ldx     #VDC_DSP_HI
389         jmp     VDCWriteReg
390
391 ; ------------------------------------------------------------------------
392 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
393 ; The page number is already checked to be valid by the graphics kernel.
394 ;
395 ; Must set an error code: NO (will only be called if page ok)
396 ;
397
398 SETDRAWPAGE:
399         ldx graphMode
400         bmi @L80
401         rts
402 @L80:   clc
403         ror
404         ror
405         ror
406         sta     SCRBASE
407         rts
408
409 ; ------------------------------------------------------------------------
410 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
411 ; to be in a valid range (0..maxcolor-1).
412 ;
413 ; Must set an error code: NO (will only be called if color ok)
414 ;
415
416 SETCOLOR:
417         tax
418         beq     @L1
419         lda     #1
420 @L1:    sta     BITMASK
421         jmp     SetPattern      ; need to have either 0 or 1
422
423 ; ------------------------------------------------------------------------
424 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
425 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
426 ; are not supported
427 ;
428 ; Must set an error code: YES
429 ;
430
431 SETPALETTE:
432         jsr     GETERROR        ; clear error (if any)
433
434         ldy     #PALETTESIZE - 1
435 @L1:    lda     (ptr1),y        ; Copy the palette
436         and     #$0F            ; Make a valid color
437         sta     PALETTE,y
438         dey
439         bpl     @L1
440
441 ; Put colors from palette into screen
442
443         lda     graphMode
444         bmi     @L80
445
446         lda     PALETTE+1       ; foreground
447         asl     a
448         asl     a
449         asl     a
450         asl     a
451         ora     PALETTE         ; background
452         ldx     #0
453 @L2:    sta     COLOR_MATRIX,x
454         sta     COLOR_MATRIX+$0100,x
455         sta     COLOR_MATRIX+$0200,x
456         sta     COLOR_MATRIX+1000-256,x
457         inx
458         bne     @L2
459         rts
460
461 @L80:   ldy     PALETTE+1       ; Foreground color
462         lda     COLTRANS,y
463         asl     a
464         asl     a
465         asl     a
466         asl     a
467         ldy     PALETTE         ; Background color
468         ora     COLTRANS,y
469
470         ldx     #VDC_COLORS
471         jmp     VDCWriteReg
472
473 ; ------------------------------------------------------------------------
474 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
475 ; set the palette should return the default palette here, so there's no
476 ; way for this function to fail.
477 ;
478 ; Must set an error code: NO
479 ;
480
481 GETPALETTE:
482         lda     #<PALETTE
483         ldx     #>PALETTE
484         rts
485
486 ; ------------------------------------------------------------------------
487 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
488 ; drivers should return something reasonable here, even drivers that don't
489 ; support palettes, otherwise the caller has no way to determine the colors
490 ; of the (not changeable) palette.
491 ;
492 ; Must set an error code: NO (all drivers must have a default palette)
493 ;
494
495 GETDEFPALETTE:
496         lda     #<DEFPALETTE
497         ldx     #>DEFPALETTE
498         rts
499
500 ; ------------------------------------------------------------------------
501 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
502 ; color. The coordinates passed to this function are never outside the
503 ; visible screen area, so there is no need for clipping inside this function.
504 ;
505 ; Must set an error code: NO
506 ;
507
508 SETPIXELCLIP:
509         lda     Y1+1
510         bmi     @finito         ; y<0
511         lda     X1+1
512         bmi     @finito         ; x<0
513         lda     X1
514         ldx     X1+1
515         sta     ADDR
516         stx     ADDR+1
517         ldx     #ADDR
518         lda     xres
519         ldy     xres+1
520         jsr     icmp            ; ( x < xres ) ...
521         bcs     @finito
522         lda     Y1
523         ldx     Y1+1
524         sta     ADDR
525         stx     ADDR+1
526         ldx     #ADDR
527         lda     yres
528         ldy     yres+1
529         jsr     icmp            ; ... && ( y < yres )
530         bcc     SETPIXEL
531 @finito:rts
532
533 SETPIXEL:
534         lda     X1
535         ldx     X1+1
536         ldy     Y1
537         sta     r3L
538         stx     r3H
539         sty     r11L
540         sec
541         lda     BITMASK         ; set or clear C flag
542         bne     @L1
543         clc
544 @L1:    lda     #0
545         jmp     DrawPoint
546
547 ; ------------------------------------------------------------------------
548 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
549 ; coordinates passed to this function are never outside the visible screen
550 ; area, so there is no need for clipping inside this function.
551
552
553 GETPIXEL:
554         lda     X1
555         ldx     X1+1
556         ldy     Y1
557         sta     r3L
558         stx     r3H
559         sty     r11L
560         jsr     TestPoint
561         ldx     #0
562         bcc     @L1
563         inx
564 @L1:    txa
565         ldx     #0
566         rts
567
568 ; ------------------------------------------------------------------------
569 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
570 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
571 ;
572 ; Must set an error code: NO
573 ;
574
575 LINE:
576         lda     X1
577         ldx     X1+1
578         ldy     Y1
579         sta     r3L
580         stx     r3H
581         sty     r11L
582         lda     X2
583         ldx     X2+1
584         ldy     Y2
585         sta     r4L
586         stx     r4H
587         sty     r11H
588         sec
589         lda     BITMASK         ; set or clear C flag
590         bne     @L1
591         clc
592 @L1:    lda     #0
593         jmp     DrawLine
594
595 ; ------------------------------------------------------------------------
596 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
597 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
598 ; Contrary to most other functions, the graphics kernel will sort and clip
599 ; the coordinates before calling the driver, so on entry the following
600 ; conditions are valid:
601 ;       X1 <= X2
602 ;       Y1 <= Y2
603 ;       (X1 >= 0) && (X1 < XRES)
604 ;       (X2 >= 0) && (X2 < XRES)
605 ;       (Y1 >= 0) && (Y1 < YRES)
606 ;       (Y2 >= 0) && (Y2 < YRES)
607 ;
608 ; Must set an error code: NO
609 ;
610
611 BAR:
612         lda     X1
613         ldx     X1+1
614         ldy     Y1
615         sta     r3L
616         stx     r3H
617         sty     r2L
618         lda     X2
619         ldx     X2+1
620         ldy     Y2
621         sta     r4L
622         stx     r4H
623         sty     r2H
624         jmp     Rectangle
625
626 ; ------------------------------------------------------------------------
627 ; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
628 ; radius in tmp1 and the current drawing color.
629 ;
630 ; Must set an error code: NO
631 ;
632
633 CIRCLE:
634         lda     RADIUS
635         bne     @L1
636         jmp     SETPIXELCLIP    ; Plot as a point
637
638 @L1:    sta     XX
639         ; x = r;
640         lda     #0
641         sta     XX+1
642         sta     YY
643         sta     YY+1
644         sta     MaxO
645         sta     MaxO+1
646         ; y =0; mo=0;
647         lda     X1
648         ldx     X1+1
649         sta     XS
650         stx     XS+1
651         lda     Y1
652         ldx     Y1+1
653         sta     YS
654         stx     YS+1            ; XS/YS to remember the center
655
656         ; while (y<x) {
657 @L013B: ldx     #YY
658         lda     XX
659         ldy     XX+1
660         jsr     icmp
661         bcc     @L12
662         rts
663 @L12:   ; plot points in 8 slices...
664         lda     XS
665         clc
666         adc     XX
667         sta     X1
668         lda     XS+1
669         adc     XX+1
670         sta     X1+1            ; x1 = xs+x
671         lda     YS
672         clc
673         adc     YY
674         sta     Y1
675         pha
676         lda     YS+1
677         adc     YY+1
678         sta     Y1+1            ; (stack)=ys+y, y1=(stack)
679         pha
680         jsr     SETPIXELCLIP    ; plot(xs+x,ys+y)
681         lda     YS
682         sec
683         sbc     YY
684         sta     Y1
685         sta     Y3
686         lda     YS+1
687         sbc     YY+1
688         sta     Y1+1            ; y3 = y1 = ys-y
689         sta     Y3+1
690         jsr     SETPIXELCLIP    ; plot(xs+x,ys-y)
691         pla
692         sta     Y1+1
693         pla
694         sta     Y1              ; y1 = ys+y
695         lda     XS
696         sec
697         sbc     XX
698         sta     X1
699         lda     XS+1
700         sbc     XX+1
701         sta     X1+1
702         jsr     SETPIXELCLIP    ; plot (xs-x,ys+y)
703         lda     Y3
704         sta     Y1
705         lda     Y3+1
706         sta     Y1+1
707         jsr     SETPIXELCLIP    ; plot (xs-x,ys-y)
708
709         lda     XS
710         clc
711         adc     YY
712         sta     X1
713         lda     XS+1
714         adc     YY+1
715         sta     X1+1            ; x1 = xs+y
716         lda     YS
717         clc
718         adc     XX
719         sta     Y1
720         pha
721         lda     YS+1
722         adc     XX+1
723         sta     Y1+1            ; (stack)=ys+x, y1=(stack)
724         pha
725         jsr     SETPIXELCLIP    ; plot(xs+y,ys+x)
726         lda     YS
727         sec
728         sbc     XX
729         sta     Y1
730         sta     Y3
731         lda     YS+1
732         sbc     XX+1
733         sta     Y1+1            ; y3 = y1 = ys-x
734         sta     Y3+1
735         jsr     SETPIXELCLIP    ; plot(xs+y,ys-x)
736         pla
737         sta     Y1+1
738         pla
739         sta     Y1              ; y1 = ys+x(stack)
740         lda     XS
741         sec
742         sbc     YY
743         sta     X1
744         lda     XS+1
745         sbc     YY+1
746         sta     X1+1
747         jsr     SETPIXELCLIP    ; plot (xs-y,ys+x)
748         lda     Y3
749         sta     Y1
750         lda     Y3+1
751         sta     Y1+1
752         jsr     SETPIXELCLIP    ; plot (xs-y,ys-x)
753
754         ; og = mo+y+y+1
755         lda     MaxO
756         ldx     MaxO+1
757         clc
758         adc     YY
759         tay
760         txa
761         adc     YY+1
762         tax
763         tya
764         clc
765         adc     YY
766         tay
767         txa
768         adc     YY+1
769         tax
770         tya
771         clc
772         adc     #1
773         bcc     @L0143
774         inx
775 @L0143: sta     OGora
776         stx     OGora+1
777         ; ou = og-x-x+1
778         sec
779         sbc     XX
780         tay
781         txa
782         sbc     XX+1
783         tax
784         tya
785         sec
786         sbc     XX
787         tay
788         txa
789         sbc     XX+1
790         tax
791         tya
792         clc
793         adc     #1
794         bcc     @L0146
795         inx
796 @L0146: sta     OUkos
797         stx     OUkos+1
798         ; ++y
799         inc     YY
800         bne     @L0148
801         inc     YY+1
802 @L0148: ; if (abs(ou)<abs(og))
803         lda     OUkos
804         ldy     OUkos+1
805         jsr     abs
806         sta     TEMP3
807         sty     TEMP4
808         lda     OGora
809         ldy     OGora+1
810         jsr     abs
811         ldx     #TEMP3
812         jsr     icmp
813         bpl     @L0149
814         ; { --x;
815         sec
816         lda     XX
817         sbc     #1
818         sta     XX
819         bcs     @L014E
820         dec     XX+1
821 @L014E: ; mo = ou; }
822         lda     OUkos
823         ldx     OUkos+1
824         jmp     @L014G
825         ; else { mo = og }
826 @L0149: lda     OGora
827         ldx     OGora+1
828 @L014G: sta     MaxO
829         stx     MaxO+1
830         ; }
831         jmp     @L013B
832
833 ; ------------------------------------------------------------------------
834 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
835 ; direction is passend in X/Y, the text direction is passed in A.
836 ;
837 ; Must set an error code: NO
838 ;
839
840 TEXTSTYLE:
841         stx     TEXTMAGX
842         sty     TEXTMAGY
843         sta     TEXTDIR
844         rts
845
846
847 ; ------------------------------------------------------------------------
848 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
849 ; current text style. The text to output is given as a zero terminated
850 ; string with address in ptr3.
851 ;
852 ; Must set an error code: NO
853 ;
854
855 OUTTEXT:
856         lda     TEXTDIR
857 ;       cmp     #TGI_TEXT_HORIZONTAL    ; this is equal 0
858         bne     @vertical
859
860         lda     X1              ; horizontal text output
861         ldx     X1+1
862         ldy     Y1
863         sta     r11L
864         stx     r11H
865         sty     r1H
866         lda     ptr3
867         ldx     ptr3+1
868         sta     r0L
869         stx     r0H
870         jmp     PutString
871
872 @vertical:
873         lda     X1              ; vertical text output
874         ldx     X1+1
875         ldy     Y1
876         sta     r11L
877         stx     r11H
878         sty     r1H
879         ldy     #0
880         lda     (ptr3),y
881         beq     @end
882         jsr     PutChar
883         inc     ptr3
884         bne     @L1
885         inc     ptr3+1
886 @L1:    lda     Y1
887         clc
888         adc     #8
889         sta     Y1
890         bne     @vertical
891 @end:   rts
892
893 ;-------------
894 ; copies of some runtime routines
895
896 abs:
897         ; a/y := abs(a/y)
898         dey
899         iny
900         bpl     @L1
901         ; negay
902         clc
903         eor     #$ff
904         adc     #1
905         pha
906         tya
907         eor     #$ff
908         adc     #0
909         tay
910         pla
911 @L1:    rts
912
913 icmp:
914         ; compare a/y to zp,x
915         sta     TEMP            ; TEMP/TEMP2 - arg2
916         sty     TEMP2
917         lda     $0,x
918         pha
919         lda     $1,x
920         tay
921         pla
922         tax
923         tya                     ; x/a - arg1 (a=high)
924
925         sec
926         sbc     TEMP2
927         bne     @L4
928         cpx     TEMP
929         beq     @L3
930         adc     #$ff
931         ora     #$01
932 @L3:    rts
933 @L4:    bvc     @L3
934         eor     #$ff
935         ora     #$01
936         rts
937
938 ;-------------
939 ; VDC helpers
940
941 VDCSetSourceAddr:
942         pha
943         tya
944         ldx     #VDC_DATA_HI
945         jsr     VDCWriteReg
946         pla
947         ldx     #VDC_DATA_LO
948         bne     VDCWriteReg
949
950 VDCReadByte:
951         ldx     #VDC_DATA
952 VDCReadReg:
953         stx     VDC_ADDR_REG
954 @L0:    bit     VDC_ADDR_REG
955         bpl     @L0
956         lda     VDC_DATA_REG
957         rts
958
959 VDCWriteByte:
960         ldx     #VDC_DATA
961 VDCWriteReg:
962         stx     VDC_ADDR_REG
963 @L0:    bit     VDC_ADDR_REG
964         bpl     @L0
965         sta     VDC_DATA_REG
966         rts
967