]> git.sur5r.net Git - cc65/blob - libsrc/geos/devel/geos-tgi.s
Remove the load address since it's supplied in its own module now.
[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   TEXTSTYLE
75         .word   OUTTEXT
76         .word   0                       ; IRQ entry is unused
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
89 ; Absolute variables used in the code
90
91 .bss
92
93 SCRBASE:        .res    1       ; High byte of screen base (64k VDC only)
94
95 ERROR:          .res    1       ; Error code
96 PALETTE:        .res    2       ; The current palette
97
98 BITMASK:        .res    1       ; $00 = clear, $01 = set pixels
99
100 OLDCOLOR:       .res    1       ; colors before entering gfx mode
101
102 ; Line routine stuff
103
104 OGora:           .res   2
105 OUkos:           .res   2
106 Y3:              .res   2
107
108 ; Text output stuff
109 TEXTMAGX:       .res    1
110 TEXTMAGY:       .res    1
111 TEXTDIR:        .res    1
112
113 ; Constants and tables
114
115 .rodata
116
117 DEFPALETTE:     .byte   $00, $0f        ; White on black
118 PALETTESIZE     = * - DEFPALETTE
119
120 ; color translation table (indexed by VIC color)
121 COLTRANS:       .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
122                 .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
123                 ; colors BROWN and GRAY3 are wrong
124
125 .code
126
127 ; ------------------------------------------------------------------------
128 ; INSTALL routine. Is called after the driver is loaded into memory. May
129 ; initialize anything that has to be done just once. Is probably empty
130 ; most of the time.
131 ;
132 ; Must set an error code: NO
133 ;
134
135 INSTALL:
136         lda version             ; if GEOS 1.0...
137         and #$f0
138         cmp #$10
139         beq @L40
140         lda c128Flag            ; at least GEOS 2.0, but we're on C128?
141         bpl @L40
142         lda graphMode           ; GEOS 2.0, C128, but is 80 column screen enabled?
143         bmi @L80
144 @L40:   rts                     ; leave default values for 40 column screen
145
146         ; check for VDC version and update register $19 value
147
148 @L80:
149         lda     #<640
150         ldx     #>640
151         sta     xres
152         stx     xres+1
153
154         ; update number of available screens
155
156         ldx     #VDC_CSET       ; determine size of RAM...
157         jsr     VDCReadReg
158         sta     tmp1
159         ora     #%00010000
160         jsr     VDCWriteReg     ; turn on 64k
161
162         jsr     settestadr1     ; save original value of test byte
163         jsr     VDCReadByte
164         sta     tmp2
165
166         lda     #$55            ; write $55 here
167         ldy     #ptr1
168         jsr     test64k         ; read it here and there
169         lda     #$aa            ; write $aa here
170         ldy     #ptr2
171         jsr     test64k         ; read it here and there
172
173         jsr     settestadr1
174         lda     tmp2
175         jsr     VDCWriteByte    ; restore original value of test byte
176
177         lda     ptr1            ; do bytes match?
178         cmp     ptr1+1
179         bne     @have64k
180         lda     ptr2
181         cmp     ptr2+1
182         bne     @have64k
183
184         ldx     #VDC_CSET
185         lda     tmp1
186         jsr     VDCWriteReg     ; restore 16/64k flag
187         jmp     @endok          ; and leave default values for 16k
188
189 @have64k:
190         lda     #4
191         sta     pages
192 @endok:
193         lda     #0
194         sta     SCRBASE         ; draw page 0 as default
195         rts
196
197 test64k:
198         sta     tmp1
199         sty     ptr3
200         lda     #0
201         sta     ptr3+1
202         jsr     settestadr1
203         lda     tmp1
204         jsr     VDCWriteByte            ; write $55
205         jsr     settestadr1
206         jsr     VDCReadByte             ; read here
207         pha
208         jsr     settestadr2
209         jsr     VDCReadByte             ; and there
210         ldy     #1
211         sta     (ptr3),y
212         pla
213         dey
214         sta     (ptr3),y
215         rts
216
217 settestadr1:
218         ldy     #$02                    ; test page 2 (here)
219         .byte   $2c
220 settestadr2:
221         ldy     #$42                    ; or page 64+2 (there)
222         lda     #0
223         jmp     VDCSetSourceAddr
224
225 ; ------------------------------------------------------------------------
226 ; UNINSTALL routine. Is called before the driver is removed from memory. May
227 ; clean up anything done by INSTALL but is probably empty most of the time.
228 ;
229 ; Must set an error code: NO
230 ;
231
232 UNINSTALL:
233         rts
234
235
236 ; ------------------------------------------------------------------------
237 ; INIT: Changes an already installed device from text mode to graphics
238 ; mode.
239 ; Note that INIT/DONE may be called multiple times while the driver
240 ; is loaded, while INSTALL is only called once, so any code that is needed
241 ; to initializes variables and so on must go here. Setting palette and
242 ; clearing the screen is not needed because this is called by the graphics
243 ; kernel later.
244 ; The graphics kernel will never call INIT when a graphics mode is already
245 ; active, so there is no need to protect against that.
246 ;
247 ; Must set an error code: YES
248 ;
249
250 INIT:
251         ldx #$01
252         stx BITMASK             ; solid black as pattern
253         lda #1
254         jsr SetPattern
255         lda #ST_WR_FORE         ; write only on foreground
256         sta dispBufferOn
257
258         lda graphMode
259         bmi @L80
260
261 ; Remember current color value (40 columns)
262         lda screencolors
263         sta OLDCOLOR
264         jmp @L99
265
266 ; Remember current color value (80 columns)
267 @L80:   lda scr80colors
268         sta OLDCOLOR
269 @L99:   lda #0
270         jsr SETVIEWPAGE         ; switch into viewpage 0
271
272 ; Done, reset the error code
273
274         lda     #TGI_ERR_OK
275         sta     ERROR
276         rts
277
278 ; ------------------------------------------------------------------------
279 ; DONE: Will be called to switch the graphics device back into text mode.
280 ; The graphics kernel will never call DONE when no graphics mode is active,
281 ; so there is no need to protect against that.
282 ;
283 ; Must set an error code: NO
284 ;
285
286 DONE:
287         lda #0
288         jsr SETVIEWPAGE         ; switch into viewpage 0
289
290         lda graphMode
291         bmi @L80
292
293         lda OLDCOLOR
294         sta screencolors        ; restore color for 40 columns
295         ldx #0
296 @L1:    sta COLOR_MATRIX,x
297         sta COLOR_MATRIX+$0100,x
298         sta COLOR_MATRIX+$0200,x
299         sta COLOR_MATRIX+1000-256,x
300         inx
301         bne @L1
302         rts
303
304 @L80:   lda OLDCOLOR            ; restore color for 80 columns
305         ldx #VDC_COLORS
306         jmp VDCWriteReg
307
308 ; ------------------------------------------------------------------------
309 ; GETERROR: Return the error code in A and clear it.
310
311 GETERROR:
312         ldx     #TGI_ERR_OK
313         lda     ERROR
314         stx     ERROR
315         rts
316
317 ; ------------------------------------------------------------------------
318 ; CONTROL: Platform/driver specific entry point.
319 ;
320 ; Must set an error code: YES
321 ;
322
323 CONTROL:
324         lda     #TGI_ERR_INV_FUNC
325         sta     ERROR
326         rts
327
328 ; ------------------------------------------------------------------------
329 ; CLEAR: Clears the screen.
330 ;
331 ; Must set an error code: NO
332 ;
333
334 CLEAR:
335             lda curPattern
336             pha
337             lda #0
338             jsr SetPattern
339             ldx #0
340             stx r3L
341             stx r3H
342             stx r2L
343             lda #199
344             sta r2H
345             lda graphMode
346             bpl @L40
347             lda #>639                   ; 80 columns
348             ldx #<639
349             bne @L99
350 @L40:       lda #>319                   ; 40 columns
351             ldx #<319
352 @L99:       sta r4H
353             stx r4L
354             jsr Rectangle
355             pla
356             sta curPattern
357             rts
358
359 ; ------------------------------------------------------------------------
360 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
361 ; The page number is already checked to be valid by the graphics kernel.
362 ;
363 ; Must set an error code: NO (will only be called if page ok)
364 ;
365
366 SETVIEWPAGE:
367         ldx graphMode
368         bmi @L80
369         rts
370 @L80:   clc
371         ror
372         ror
373         ror
374         ldx     #VDC_DSP_HI
375         jmp     VDCWriteReg
376
377 ; ------------------------------------------------------------------------
378 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
379 ; The page number is already checked to be valid by the graphics kernel.
380 ;
381 ; Must set an error code: NO (will only be called if page ok)
382 ;
383
384 SETDRAWPAGE:
385         ldx graphMode
386         bmi @L80
387         rts
388 @L80:   clc
389         ror
390         ror
391         ror
392         sta     SCRBASE
393         rts
394
395 ; ------------------------------------------------------------------------
396 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
397 ; to be in a valid range (0..maxcolor-1).
398 ;
399 ; Must set an error code: NO (will only be called if color ok)
400 ;
401
402 SETCOLOR:
403         tax
404         beq     @L1
405         lda     #1
406 @L1:    sta     BITMASK
407         jmp     SetPattern      ; need to have either 0 or 1
408
409 ; ------------------------------------------------------------------------
410 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
411 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
412 ; are not supported
413 ;
414 ; Must set an error code: YES
415 ;
416
417 SETPALETTE:
418         jsr     GETERROR        ; clear error (if any)
419
420         ldy     #PALETTESIZE - 1
421 @L1:    lda     (ptr1),y        ; Copy the palette
422         and     #$0F            ; Make a valid color
423         sta     PALETTE,y
424         dey
425         bpl     @L1
426
427 ; Put colors from palette into screen
428
429         lda     graphMode
430         bmi     @L80
431
432         lda     PALETTE+1       ; foreground
433         asl     a
434         asl     a
435         asl     a
436         asl     a
437         ora     PALETTE         ; background
438         ldx     #0
439 @L2:    sta     COLOR_MATRIX,x
440         sta     COLOR_MATRIX+$0100,x
441         sta     COLOR_MATRIX+$0200,x
442         sta     COLOR_MATRIX+1000-256,x
443         inx
444         bne     @L2
445         rts
446
447 @L80:   ldy     PALETTE+1       ; Foreground color
448         lda     COLTRANS,y
449         asl     a
450         asl     a
451         asl     a
452         asl     a
453         ldy     PALETTE         ; Background color
454         ora     COLTRANS,y
455
456         ldx     #VDC_COLORS
457         jmp     VDCWriteReg
458
459 ; ------------------------------------------------------------------------
460 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
461 ; set the palette should return the default palette here, so there's no
462 ; way for this function to fail.
463 ;
464 ; Must set an error code: NO
465 ;
466
467 GETPALETTE:
468         lda     #<PALETTE
469         ldx     #>PALETTE
470         rts
471
472 ; ------------------------------------------------------------------------
473 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
474 ; drivers should return something reasonable here, even drivers that don't
475 ; support palettes, otherwise the caller has no way to determine the colors
476 ; of the (not changeable) palette.
477 ;
478 ; Must set an error code: NO (all drivers must have a default palette)
479 ;
480
481 GETDEFPALETTE:
482         lda     #<DEFPALETTE
483         ldx     #>DEFPALETTE
484         rts
485
486 ; ------------------------------------------------------------------------
487 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
488 ; color. The coordinates passed to this function are never outside the
489 ; visible screen area, so there is no need for clipping inside this function.
490 ;
491 ; Must set an error code: NO
492 ;
493
494 SETPIXEL:
495         lda     X1
496         ldx     X1+1
497         ldy     Y1
498         sta     r3L
499         stx     r3H
500         sty     r11L
501         sec
502         lda     BITMASK         ; set or clear C flag
503         bne     @L1
504         clc
505 @L1:    lda     #0
506         jmp     DrawPoint
507
508 ; ------------------------------------------------------------------------
509 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
510 ; coordinates passed to this function are never outside the visible screen
511 ; area, so there is no need for clipping inside this function.
512
513
514 GETPIXEL:
515         lda     X1
516         ldx     X1+1
517         ldy     Y1
518         sta     r3L
519         stx     r3H
520         sty     r11L
521         jsr     TestPoint
522         ldx     #0
523         bcc     @L1
524         inx
525 @L1:    txa
526         ldx     #0
527         rts
528
529 ; ------------------------------------------------------------------------
530 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
531 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
532 ;
533 ; Must set an error code: NO
534 ;
535
536 LINE:
537         lda     X1
538         ldx     X1+1
539         ldy     Y1
540         sta     r3L
541         stx     r3H
542         sty     r11L
543         lda     X2
544         ldx     X2+1
545         ldy     Y2
546         sta     r4L
547         stx     r4H
548         sty     r11H
549         sec
550         lda     BITMASK         ; set or clear C flag
551         bne     @L1
552         clc
553 @L1:    lda     #0
554         jmp     DrawLine
555
556 ; ------------------------------------------------------------------------
557 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
558 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
559 ; Contrary to most other functions, the graphics kernel will sort and clip
560 ; the coordinates before calling the driver, so on entry the following
561 ; conditions are valid:
562 ;       X1 <= X2
563 ;       Y1 <= Y2
564 ;       (X1 >= 0) && (X1 < XRES)
565 ;       (X2 >= 0) && (X2 < XRES)
566 ;       (Y1 >= 0) && (Y1 < YRES)
567 ;       (Y2 >= 0) && (Y2 < YRES)
568 ;
569 ; Must set an error code: NO
570 ;
571
572 BAR:
573         lda     X1
574         ldx     X1+1
575         ldy     Y1
576         sta     r3L
577         stx     r3H
578         sty     r2L
579         lda     X2
580         ldx     X2+1
581         ldy     Y2
582         sta     r4L
583         stx     r4H
584         sty     r2H
585         jmp     Rectangle
586
587 ; ------------------------------------------------------------------------
588 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
589 ; direction is passend in X/Y, the text direction is passed in A.
590 ;
591 ; Must set an error code: NO
592 ;
593
594 TEXTSTYLE:
595         stx     TEXTMAGX
596         sty     TEXTMAGY
597         sta     TEXTDIR
598         rts
599
600
601 ; ------------------------------------------------------------------------
602 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
603 ; current text style. The text to output is given as a zero terminated
604 ; string with address in ptr3.
605 ;
606 ; Must set an error code: NO
607 ;
608
609 OUTTEXT:
610         lda     TEXTDIR
611 ;       cmp     #TGI_TEXT_HORIZONTAL    ; this is equal 0
612         bne     @vertical
613
614         lda     X1              ; horizontal text output
615         ldx     X1+1
616         ldy     Y1
617         sta     r11L
618         stx     r11H
619         sty     r1H
620         lda     ptr3
621         ldx     ptr3+1
622         sta     r0L
623         stx     r0H
624         jmp     PutString
625
626 @vertical:
627         lda     X1              ; vertical text output
628         ldx     X1+1
629         ldy     Y1
630         sta     r11L
631         stx     r11H
632         sty     r1H
633         ldy     #0
634         lda     (ptr3),y
635         beq     @end
636         jsr     PutChar
637         inc     ptr3
638         bne     @L1
639         inc     ptr3+1
640 @L1:    lda     Y1
641         clc
642         adc     #8
643         sta     Y1
644         bne     @vertical
645 @end:   rts
646
647 ;-------------
648 ; VDC helpers
649
650 VDCSetSourceAddr:
651         pha
652         tya
653         ldx     #VDC_DATA_HI
654         jsr     VDCWriteReg
655         pla
656         ldx     #VDC_DATA_LO
657         bne     VDCWriteReg
658
659 VDCReadByte:
660         ldx     #VDC_DATA
661 VDCReadReg:
662         stx     VDC_ADDR_REG
663 @L0:    bit     VDC_ADDR_REG
664         bpl     @L0
665         lda     VDC_DATA_REG
666         rts
667
668 VDCWriteByte:
669         ldx     #VDC_DATA
670 VDCWriteReg:
671         stx     VDC_ADDR_REG
672 @L0:    bit     VDC_ADDR_REG
673         bpl     @L0
674         sta     VDC_DATA_REG
675         rts
676