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