2 ; Graphics driver for the 160x102x16 mode on the Lynx.
4 ; Based on Stephen L. Judds GRLIB code
7 .include "zeropage.inc"
9 .include "tgi-kernel.inc"
10 .include "tgi-mode.inc"
11 .include "tgi-error.inc"
18 ; ------------------------------------------------------------------------
19 ; Header. Includes jump table and constants.
23 ; First part of the header is a structure that has a magic and defines the
24 ; capabilities of the driver
26 .byte $74, $67, $69 ; "tgi"
27 .byte TGI_API_VERSION ; TGI API version number
28 .word 160 ; X resolution
29 .word 102 ; Y resolution
30 .byte 16 ; Number of drawing colors
31 .byte 1 ; Number of screens available
32 .byte 8 ; System font X size
33 .byte 8 ; System font Y size
34 .res 4, $00 ; Reserved for future extensions
36 ; Next comes the jump table. Currently all entries must be valid and may point
37 ; to an RTS for test versions (function not implemented). A future version may
38 ; allow for emulation: In this case the vector will be zero. Emulation means
39 ; that the graphics kernel will emulate the function by using lower level
40 ; primitives - for example ploting a line by using calls to SETPIXEL.
63 ; ------------------------------------------------------------------------
66 ; Variables mapped to the zero page segment variables. Some of these are
67 ; used for passing parameters to the driver.
75 ROW := tmp2 ; Bitmap row...
76 COL := tmp3 ; ...and column, both set by PLOT
80 INRANGE := regsave+2 ; PLOT variable, $00 = coordinates in range
82 CHUNK := X2 ; Used in the line routine
83 OLDCHUNK := X2+1 ; Dito
85 ; Absolute variables used in the code
89 ERROR: .res 1 ; Error code
91 DRAWINDEX: .res 1 ; Pen to use for drawing
96 OLDD018: .res 1 ; Old register value
102 ; Circle routine stuff, overlaid by BAR variables
107 BROW: .res 1 ; Bottom row
108 TROW: .res 1 ; Top row
110 LCOL: .res 1 ; Left column
111 RCOL: .res 1 ; Right column
123 ; Constants and tables
127 DEFPALETTE: .byte >$000
160 PALETTESIZE = * - DEFPALETTE
162 BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
163 BITCHUNK: .byte $FF,$7F,$3F,$1F,$0F,$07,$03,$01
165 VBASE = $E000 ; Video memory base address
166 CBASE = $D000 ; Color memory base address
171 ; ------------------------------------------------------------------------
172 ; INSTALL routine. Is called after the driver is loaded into memory. May
173 ; initialize anything that has to be done just once. Is probably empty
176 ; Must set an error code: NO
183 ; ------------------------------------------------------------------------
184 ; UNINSTALL routine. Is called before the driver is removed from memory. May
185 ; clean up anything done by INSTALL but is probably empty most of the time.
187 ; Must set an error code: NO
194 ; ------------------------------------------------------------------------
195 ; INIT: Changes an already installed device from text mode to graphics
197 ; Note that INIT/DONE may be called multiple times while the driver
198 ; is loaded, while INSTALL is only called once, so any code that is needed
199 ; to initializes variables and so on must go here. Setting palette and
200 ; clearing the screen is not needed because this is called by the graphics
202 ; The graphics kernel will never call INIT when a graphics mode is already
203 ; active, so there is no need to protect against that.
205 ; Must set an error code: YES
209 ; Done, reset the error code
215 ; ------------------------------------------------------------------------
216 ; DONE: Will be called to switch the graphics device back into text mode.
217 ; The graphics kernel will never call DONE when no graphics mode is active,
218 ; so there is no need to protect against that.
220 ; Must set an error code: NO
226 ; ------------------------------------------------------------------------
227 ; GETERROR: Return the error code in A and clear it.
235 ; ------------------------------------------------------------------------
236 ; CONTROL: Platform/driver specific entry point.
238 ; Must set an error code: YES
242 lda #TGI_ERR_INV_FUNC
246 ; ------------------------------------------------------------------------
247 ; CLEAR: Clears the screen.
249 ; Must set an error code: NO
254 .byte 3,%10000100,%00000000, $0 ; A pixel bitmap
256 .byte %00000001 ; A pixel sprite
267 CLEAR: lda #<cls_sprite
282 ; ------------------------------------------------------------------------
283 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
284 ; The page number is already checked to be valid by the graphics kernel.
286 ; Must set an error code: NO (will only be called if page ok)
291 lda #<$fe00-8160-8160
292 ldx #>$fe00-8160-8160
294 @L1: lda #<$fe00-8160
296 @L2: sta DISPADRL ; $FD94
302 ; ------------------------------------------------------------------------
303 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
304 ; The page number is already checked to be valid by the graphics kernel.
306 ; Must set an error code: NO (will only be called if page ok)
311 lda #<$fe00-8160-8160
312 ldx #>$fe00-8160-8160
314 @L1: lda #<$fe00-8160
316 @L2: sta VIDBASL ; $FD94
320 ; ------------------------------------------------------------------------
321 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
322 ; to be in a valid range (0..maxcolor-1).
324 ; Must set an error code: NO (will only be called if color ok)
331 ; ------------------------------------------------------------------------
332 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
333 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
336 ; Must set an error code: YES
342 sta GCOLMAP,y ; $FDA0
346 ; Done, reset the error code
352 ; ------------------------------------------------------------------------
353 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
354 ; set the palette should return the default palette here, so there's no
355 ; way for this function to fail.
357 ; Must set an error code: NO
361 lda #<GCOLMAP ; $FDA0
365 ; ------------------------------------------------------------------------
366 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
367 ; drivers should return something reasonable here, even drivers that don't
368 ; support palettes, otherwise the caller has no way to determine the colors
369 ; of the (not changeable) palette.
371 ; Must set an error code: NO (all drivers must have a default palette)
379 ; ------------------------------------------------------------------------
380 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
381 ; color. The coordinates passed to this function are never outside the
382 ; visible screen area, so there is no need for clipping inside this function.
384 ; Must set an error code: NO
389 .byte %00000001 ; A pixel sprite
411 ; ------------------------------------------------------------------------
412 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
413 ; coordinates passed to this function are never outside the visible screen
414 ; area, so there is no need for clipping inside this function.
419 sta MATHD ; Hardware multiply
450 ; ------------------------------------------------------------------------
451 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
452 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
454 ; To deal with off-screen coordinates, the current row
455 ; and column (40x25) is kept track of. These are set
456 ; negative when the point is off the screen, and made
457 ; positive when the point is within the visible screen.
459 ; X1,X2 etc. are set up above (x2=LINNUM in particular)
460 ; Format is LINE x2,y2,x1,y1
462 ; Must set an error code: NO
468 ; ------------------------------------------------------------------------
469 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
470 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
471 ; Contrary to most other functions, the graphics kernel will sort and clip
472 ; the coordinates before calling the driver, so on entry the following
473 ; conditions are valid:
476 ; (X1 >= 0) && (X1 < XRES)
477 ; (X2 >= 0) && (X2 < XRES)
478 ; (Y1 >= 0) && (Y1 < YRES)
479 ; (Y2 >= 0) && (Y2 < YRES)
481 ; Must set an error code: NO
486 .byte %00000001 ; A pixel sprite
515 ; ------------------------------------------------------------------------
516 ; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
517 ; radius in tmp1 and the current drawing color.
519 ; Must set an error code: NO
525 ; ------------------------------------------------------------------------
526 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
527 ; direction is passend in X/Y, the text direction is passed in A.
529 ; Must set an error code: NO
539 ; ------------------------------------------------------------------------
540 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
541 ; current text style. The text to output is given as a zero terminated
542 ; string with address in ptr3.
544 ; Must set an error code: NO