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