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