2 ; Graphics driver for the 320x200x2 or 640x200x2 mode on GEOS 64/128
3 ; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
6 .include "zeropage.inc"
8 .include "tgi-kernel.inc"
9 .include "tgi-mode.inc"
10 .include "tgi-error.inc"
12 .include "../inc/const.inc"
13 .include "../inc/jumptab.inc"
14 .include "../inc/geossym.inc"
15 .include "../inc/geossym2.inc"
19 ; ------------------------------------------------------------------------
22 VDC_ADDR_REG = $D600 ; VDC address
23 VDC_DATA_REG = $D601 ; VDC data
25 VDC_DSP_HI = 12 ; registers used
36 ; ------------------------------------------------------------------------
37 ; Header. Includes jump table and constants.
41 ; First part of the header is a structure that has a magic and defines the
42 ; capabilities of the driver
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
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).
76 .word 0 ; IRQ entry is unused
78 ; ------------------------------------------------------------------------
81 ; Variables mapped to the zero page segment variables. Some of these are
82 ; used for passing parameters to the driver.
89 ; Absolute variables used in the code
93 SCRBASE: .res 1 ; High byte of screen base (64k VDC only)
95 ERROR: .res 1 ; Error code
96 PALETTE: .res 2 ; The current palette
98 BITMASK: .res 1 ; $00 = clear, $01 = set pixels
100 OLDCOLOR: .res 1 ; colors before entering gfx mode
113 ; Constants and tables
117 DEFPALETTE: .byte $00, $0f ; White on black
118 PALETTESIZE = * - DEFPALETTE
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
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
132 ; Must set an error code: NO
136 lda version ; if GEOS 1.0...
140 lda c128Flag ; at least GEOS 2.0, but we're on C128?
142 lda graphMode ; GEOS 2.0, C128, but is 80 column screen enabled?
144 @L40: rts ; leave default values for 40 column screen
146 ; check for VDC version and update register $19 value
154 ; update number of available screens
156 ldx #VDC_CSET ; determine size of RAM...
160 jsr VDCWriteReg ; turn on 64k
162 jsr settestadr1 ; save original value of test byte
166 lda #$55 ; write $55 here
168 jsr test64k ; read it here and there
169 lda #$aa ; write $aa here
171 jsr test64k ; read it here and there
175 jsr VDCWriteByte ; restore original value of test byte
177 lda ptr1 ; do bytes match?
186 jsr VDCWriteReg ; restore 16/64k flag
187 jmp @endok ; and leave default values for 16k
194 sta SCRBASE ; draw page 0 as default
204 jsr VDCWriteByte ; write $55
206 jsr VDCReadByte ; read here
209 jsr VDCReadByte ; and there
218 ldy #$02 ; test page 2 (here)
221 ldy #$42 ; or page 64+2 (there)
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.
229 ; Must set an error code: NO
236 ; ------------------------------------------------------------------------
237 ; INIT: Changes an already installed device from text mode to graphics
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
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.
247 ; Must set an error code: YES
252 stx BITMASK ; solid black as pattern
255 lda #ST_WR_FORE ; write only on foreground
261 ; Remember current color value (40 columns)
266 ; Remember current color value (80 columns)
267 @L80: lda scr80colors
270 jsr SETVIEWPAGE ; switch into viewpage 0
272 ; Done, reset the error code
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.
283 ; Must set an error code: NO
288 jsr SETVIEWPAGE ; switch into viewpage 0
294 sta screencolors ; restore color for 40 columns
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
304 @L80: lda OLDCOLOR ; restore color for 80 columns
308 ; ------------------------------------------------------------------------
309 ; GETERROR: Return the error code in A and clear it.
317 ; ------------------------------------------------------------------------
318 ; CONTROL: Platform/driver specific entry point.
320 ; Must set an error code: YES
324 lda #TGI_ERR_INV_FUNC
328 ; ------------------------------------------------------------------------
329 ; CLEAR: Clears the screen.
331 ; Must set an error code: NO
347 lda #>639 ; 80 columns
350 @L40: lda #>319 ; 40 columns
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.
363 ; Must set an error code: NO (will only be called if page ok)
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.
381 ; Must set an error code: NO (will only be called if page ok)
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).
399 ; Must set an error code: NO (will only be called if color ok)
407 jmp SetPattern ; need to have either 0 or 1
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
414 ; Must set an error code: YES
418 jsr GETERROR ; clear error (if any)
421 @L1: lda (ptr1),y ; Copy the palette
422 and #$0F ; Make a valid color
427 ; Put colors from palette into screen
432 lda PALETTE+1 ; foreground
437 ora PALETTE ; background
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
447 @L80: ldy PALETTE+1 ; Foreground color
453 ldy PALETTE ; Background color
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.
464 ; Must set an error code: NO
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.
478 ; Must set an error code: NO (all drivers must have a default palette)
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.
491 ; Must set an error code: NO
502 lda BITMASK ; set or clear C flag
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.
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.
533 ; Must set an error code: NO
550 lda BITMASK ; set or clear C flag
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:
564 ; (X1 >= 0) && (X1 < XRES)
565 ; (X2 >= 0) && (X2 < XRES)
566 ; (Y1 >= 0) && (Y1 < YRES)
567 ; (Y2 >= 0) && (Y2 < YRES)
569 ; Must set an error code: NO
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.
591 ; Must set an error code: NO
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.
606 ; Must set an error code: NO
611 ; cmp #TGI_TEXT_HORIZONTAL ; this is equal 0
614 lda X1 ; horizontal text output
627 lda X1 ; vertical text output
663 @L0: bit VDC_ADDR_REG
672 @L0: bit VDC_ADDR_REG