2 ; Graphics driver for the 40x40x16 mode on the Apple II
4 ; Stefan Haubenthal <polluks@sdf.lonestar.org>
5 ; Based on Maciej Witkowiak's line and circle routine
8 .include "zeropage.inc"
10 .include "tgi-kernel.inc"
11 .include "tgi-mode.inc"
12 .include "tgi-error.inc"
17 ; ------------------------------------------------------------------------
29 ; ------------------------------------------------------------------------
32 COUT := $FDED ; Vector to user output routine
33 TEXT := $F399 ; Return to text screen
35 ; ------------------------------------------------------------------------
36 ; Header. Includes jump table and constants.
40 ; First part of the header is a structure that has a magic and defines the
41 ; capabilities of the driver
43 .byte $74, $67, $69 ; "tgi"
44 .byte TGI_API_VERSION ; TGI API version number
45 xres: .word 40 ; X resolution
46 yres: .word 40 ; Y resolution
47 .byte 16 ; Number of drawing colors
48 .byte 1 ; Number of screens available
49 .byte 8 ; System font X size
50 .byte 8 ; System font Y size
51 .res 4, $00 ; Reserved for future extensions
53 ; Next comes the jump table. Currently all entries must be valid and may point
54 ; to an RTS for test versions (function not implemented).
77 ; ------------------------------------------------------------------------
80 ; Variables mapped to the zero page segment variables. Some of these are
81 ; used for passing parameters to the driver.
95 ; Line routine stuff (must be on zpage)
98 ERR = regsave ; (2) LINE
99 NX = regsave+2 ; (2) LINE
101 XX = ptr3 ; (2) CIRCLE
102 YY = ptr4 ; (2) CIRCLE
103 MaxO = sreg ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
104 XS = regsave ; (2) CIRCLE
105 YS = regsave+2 ; (2) CIRCLE
107 ; Absolute variables used in the code
111 ERROR: .res 1 ; Error code
113 ; Line routine stuff (combined with CIRCLE to save space)
124 ; Constants and tables
128 DEFPALETTE: .byte $00, $0F, $01, $0E, $03, $04, $02, $0D
129 .byte $09, $08, $0B, $05, $0A, $0C, $06, $07
133 ; ------------------------------------------------------------------------
134 ; INSTALL routine. Is called after the driver is loaded into memory. May
135 ; initialize anything that has to be done just once. Is probably empty
138 ; Must set an error code: NO
144 ; ------------------------------------------------------------------------
145 ; UNINSTALL routine. Is called before the driver is removed from memory. May
146 ; clean up anything done by INSTALL but is probably empty most of the time.
148 ; Must set an error code: NO
155 ; ------------------------------------------------------------------------
156 ; INIT: Changes an already installed device from text mode to graphics
158 ; Note that INIT/DONE may be called multiple times while the driver
159 ; is loaded, while INSTALL is only called once, so any code that is needed
160 ; to initializes variables and so on must go here. Setting palette and
161 ; clearing the screen is not needed because this is called by the graphics
163 ; The graphics kernel will never call INIT when a graphics mode is already
164 ; active, so there is no need to protect against that.
166 ; Must set an error code: YES
171 ; Switch into graphics mode
175 ; Done, reset the error code
181 ; ------------------------------------------------------------------------
182 ; DONE: Will be called to switch the graphics device back into text mode.
183 ; The graphics kernel will never call DONE when no graphics mode is active,
184 ; so there is no need to protect against that.
186 ; Must set an error code: NO
191 ; ------------------------------------------------------------------------
192 ; GETERROR: Return the error code in A and clear it.
200 ; ------------------------------------------------------------------------
201 ; CONTROL: Platform/driver specific entry point.
203 ; Must set an error code: YES
207 lda #TGI_ERR_INV_FUNC
211 ; ------------------------------------------------------------------------
212 ; CLEAR: Clears the screen.
214 ; Must set an error code: NO
219 ; ------------------------------------------------------------------------
220 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
221 ; The page number is already checked to be valid by the graphics kernel.
223 ; Must set an error code: NO (will only be called if page ok)
228 ; ------------------------------------------------------------------------
229 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
230 ; The page number is already checked to be valid by the graphics kernel.
232 ; Must set an error code: NO (will only be called if page ok)
238 ; ------------------------------------------------------------------------
239 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
240 ; to be in a valid range (0..maxcolor-1).
242 ; Must set an error code: NO (will only be called if color ok)
247 ; ------------------------------------------------------------------------
248 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
249 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
252 ; Must set an error code: YES
256 lda #TGI_ERR_INV_FUNC
260 ; ------------------------------------------------------------------------
261 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
262 ; set the palette should return the default palette here, so there's no
263 ; way for this function to fail.
265 ; Must set an error code: NO
270 ; ------------------------------------------------------------------------
271 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
272 ; drivers should return something reasonable here, even drivers that don't
273 ; support palettes, otherwise the caller has no way to determine the colors
274 ; of the (not changeable) palette.
276 ; Must set an error code: NO (all drivers must have a default palette)
284 ; ------------------------------------------------------------------------
285 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
286 ; color. The coordinates passed to this function are never outside the
287 ; visible screen area, so there is no need for clipping inside this function.
289 ; Must set an error code: NO
304 jsr icmp ; ( x < xres ) ...
313 jsr icmp ; ... && ( y < yres )
322 ; ------------------------------------------------------------------------
323 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
324 ; coordinates passed to this function are never outside the visible screen
325 ; area, so there is no need for clipping inside this function.
335 ; ------------------------------------------------------------------------
336 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
337 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
339 ; Must set an error code: NO
427 ; for (count=nx;count>0;--count) {
432 @L0166: lda COUNT ; count>0
437 @L0167: jsr SETPIXELCLIP
473 ; if (abs(pb)<abs(ub)) {
489 ; } else { x1 = x1 + ay
526 ; ------------------------------------------------------------------------
527 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
528 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
529 ; Contrary to most other functions, the graphics kernel will sort and clip
530 ; the coordinates before calling the driver, so on entry the following
531 ; conditions are valid:
534 ; (X1 >= 0) && (X1 < XRES)
535 ; (X2 >= 0) && (X2 < XRES)
536 ; (Y1 >= 0) && (Y1 < YRES)
537 ; (Y2 >= 0) && (Y2 < YRES)
539 ; Must set an error code: NO
555 ; ------------------------------------------------------------------------
556 ; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
557 ; radius in tmp1 and the current drawing color.
559 ; Must set an error code: NO
565 jmp SETPIXELCLIP ; Plot as a point
583 stx YS+1 ; XS/YS to remember the center
592 @L12: ; plot points in 8 slices...
605 sta Y1+1 ; (stack)=ys+y, y1=(stack)
607 jsr SETPIXELCLIP ; plot(xs+x,ys+y)
614 sta Y1+1 ; y3 = y1 = ys-y
616 jsr SETPIXELCLIP ; plot(xs+x,ys-y)
627 jsr SETPIXELCLIP ; plot (xs-x,ys+y)
632 jsr SETPIXELCLIP ; plot (xs-x,ys-y)
646 sta Y1+1 ; (stack)=ys+x, y1=(stack)
648 jsr SETPIXELCLIP ; plot(xs+y,ys+x)
655 sta Y1+1 ; y3 = y1 = ys-x
657 jsr SETPIXELCLIP ; plot(xs+y,ys-x)
661 sta Y1 ; y1 = ys+x(stack)
668 jsr SETPIXELCLIP ; plot (xs-y,ys+x)
673 jsr SETPIXELCLIP ; plot (xs-y,ys-x)
717 @L0148: ; if (abs(ou)<abs(og))
747 ; ------------------------------------------------------------------------
748 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
749 ; direction is passend in X/Y, the text direction is passed in A.
751 ; Must set an error code: NO
758 ; ------------------------------------------------------------------------
759 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
760 ; current text style. The text to output is given as a zero terminated
761 ; string with address in ptr3.
763 ; Must set an error code: NO
781 ; copies of some runtime routines
800 ; compare a/y to zp,x
801 sta TEMP ; TEMP/TEMP2 - arg2
809 tya ; x/a - arg1 (a=high)