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