2 ; Generic Atari graphics driver
5 ; ******************************************************************************
7 ; ----------------------------------------------------------------------
9 ; Header. Includes jump table and constants.
11 ; ----------------------------------------------------------------------
17 .byte $74, $67, $69 ; "tgi"
18 .byte TGI_API_VERSION ; TGI API version number
19 .word x_res ; X resolution
20 .word y_res ; Y resolution
21 .byte colors ; Number of drawing colors
22 .byte pages ; Number of screens available
23 .byte 8 ; System font X size
24 .byte 8 ; System font Y size
25 .word aspect ; Aspect ratio
48 .addr 0 ; IRQ entry is unused
50 ; ******************************************************************************
52 ; ----------------------------------------------------------------------
56 ; ----------------------------------------------------------------------
64 ; ******************************************************************************
66 ; ----------------------------------------------------------------------
70 ; ----------------------------------------------------------------------
77 .if grmode = 9 || grmode = 11
78 palette = default_palette
81 .res colors ; The current palette
84 .res 1 ; Current pixel mask
86 .res 1 ; IOCB channel number for graphics
90 .res 1 ; High byte of screen address for screen page 0
92 .res 1 ; High byte of display list address for screen page 0
93 ; Page 1's addresses are 8K higher
98 .byte 1 ; Horizontal text scaling factor
100 .byte 1 ; Vertical text scaling factor
102 .word 8 ; Horizontal text scaling factor * 8
104 .word 8 ; Vertical text scaling factor * 8
106 .byte 0 ; Text direction,
110 ; ******************************************************************************
114 ; ----------------------------------------------------------------------
116 ; Put a pixel at (sptr),y using x as the bit mask offset
118 ; ----------------------------------------------------------------------
127 ; ******************************************************************************
131 .byte "S:",$9B ; Device code for screen
132 screen_device_length := * - screen_device
138 ; ----------------------------------------------------------------------
140 ; INIT: Switch to graphics mode
142 ; ----------------------------------------------------------------------
146 ; Initialize drawing color
161 nores: lda #TGI_ERR_NO_RES
165 found: ; Check if enough RAM is available
177 ; Switch into graphics mode
188 lda #<screen_device_length
190 lda #>screen_device_length
195 ; Reserve 8K of high memory
199 ; Close and reopen graphics
214 lda #<screen_device_length
216 lda #>screen_device_length
219 ; Save screen poniters
227 ; Reset the error code and return
233 ; ******************************************************************************
237 ; ----------------------------------------------------------------------
239 ; DONE: Switch back to text mode
241 ; ----------------------------------------------------------------------
245 ; Free 8K of high memory
256 ; Close the S: device
261 ; Reopen it in Graphics 0
272 lda #<screen_device_length
274 lda #>screen_device_length
278 ; Now close it again; we don't need it anymore
284 ; ******************************************************************************
288 ; ----------------------------------------------------------------------
290 ; GETERROR: Return the error code in A and clear it
292 ; ----------------------------------------------------------------------
301 ; ******************************************************************************
305 ; ----------------------------------------------------------------------
307 ; CLEAR: Clear the screen
309 ; ----------------------------------------------------------------------
312 ; Load the screen address in sptr
322 ; Clear full pages if any
333 ; Clear the rest, if any
344 ; ******************************************************************************
348 ; ----------------------------------------------------------------------
350 ; GETPALETTE: Return the current palette in A/X
352 ; ----------------------------------------------------------------------
360 ; ******************************************************************************
364 ; ----------------------------------------------------------------------
366 ; GETDEFPALETTE: Return the default palette in A/X
368 ; ----------------------------------------------------------------------
371 lda #<default_palette
372 ldx #>default_palette
376 ; ******************************************************************************
380 ; ----------------------------------------------------------------------
382 ; SETCOLOR: Set the drawing color (in A)
384 ; ----------------------------------------------------------------------
389 ; Map colors like this: 0 -> 0, 1 -> 15, 2 -> 1, 3 -> 2 etc.
401 ; ******************************************************************************
405 ; ----------------------------------------------------------------------
407 ; CALC: Calculate the screen address
409 ; x1 (ptr1) x coordinate
410 ; y1 (ptr2) y coordinate
412 ; sptr + y screen address
415 ; ----------------------------------------------------------------------
420 ; calculate line offset
427 .elseif x_res / ppb = 20
429 .elseif x_res / ppb = 10
450 ; calculate bit mask offset
455 ; calculate row offset
485 ; ******************************************************************************
489 ; ----------------------------------------------------------------------
491 ; Draw one pixel at x1, y1
493 ; ----------------------------------------------------------------------
501 ; ******************************************************************************
505 ; ----------------------------------------------------------------------
507 ; GETPIXEL: Read the color value of a pixel and return it in A/X
509 ; ----------------------------------------------------------------------
542 ; Map colors like this: 0 -> 0, 15 -> 1, 2 -> 3, 3 -> 4 etc.
552 ; Map out-of-range colors like this:
572 ; ******************************************************************************
576 ; ----------------------------------------------------------------------
578 ; LINE: Draw a line from x1,y1 to x2,y2
580 ; ----------------------------------------------------------------------
599 ; if dx is positive, no problem
602 ; if dx is negative, swap x1,y1 with x2,y2
603 lda x1 ; x1 <-> x2, low byte
607 lda x1 + 1 ; x1 <-> x2, high byte
611 lda y1 ; y1 <-> y2, low byte
615 lda y1 + 1 ; y1 <-> y2, high byte
644 lda #<(65536 - x_res / ppb)
646 lda #>(65536 - x_res / ppb)
648 bne skip_iy_1 ; always
681 ; dx is the major axis
728 ; loop while dx-- >= 0
742 ; dy is the major axis
788 ; loop while dy-- >= 0
802 ; ******************************************************************************
806 ; ----------------------------------------------------------------------
810 ; ----------------------------------------------------------------------
847 ; ******************************************************************************
851 ; ----------------------------------------------------------------------
853 ; BAR: Draw a filled rectangle with the corners at x1,y1,x2,y2
855 ; ----------------------------------------------------------------------
871 ; Calculate upper left corner
882 ; Calculate upper right corner
900 ; Calculate memory difference between x1 and x2
938 cont: ; Go to next row
944 skipm: ; Loop while --dy > 0
952 ; ******************************************************************************
956 ; ----------------------------------------------------------------------
958 ; TEXTSTYLE: Set text style. Scale factors in X and Y and direction in A
960 ; ----------------------------------------------------------------------
965 ; Save text direction in bit 8 so that we can use BIT instruction later
969 ; Save 8 * scaling factors
991 ; ******************************************************************************
995 ; ----------------------------------------------------------------------
997 ; OUTTEXT: Draw text at x1, y1. String is in ptr3
999 ; ----------------------------------------------------------------------
1007 ataint: .byte 64,0,32,96
1010 .if >(x_res - 1) > 0
1021 ; Don't draw zero sized characters
1027 @cont: ; Save string address, ptr3 is needed by BAR
1041 .if >(x_res - 1) > 0
1050 ; Calculate y2 and adjust y1
1062 ; Calculate for vertical text
1088 skiph: ; Save coords
1090 ; Draw one character
1097 bne loop ; Check for null character
1100 ; --------------------
1101 ; Output one character
1103 ; Convert to ANTIC code
1114 ; Save and clear inverse video bit
1117 ; Calculate font data address
1139 .if >(x_res - 1) > 0
1147 ; Put one row of the glyph
1156 ; Put one column of the row
1176 ; Restore old values
1188 .if >(x_res - 1) > 0
1203 ; -------------------------
1204 inc_x: ; increase x coords
1228 ; -------------------------
1229 dec_y: ; decrease y coords
1257 ; -------------------------
1258 save_text_y: ; Save text's height coords
1270 .if >(x_res - 1) > 0
1278 ; -------------------------
1279 restore_text_y: ; Position to next char
1310 .if >(x_res - 1) > 0
1335 ; ******************************************************************************
1339 ; ----------------------------------------------------------------------
1341 ; SETVIEWPAGE, page in A
1343 ; ----------------------------------------------------------------------
1352 beq done ; We're already in the desired page
1357 ; Wait until next VBLANK
1358 wait: cpx RTCLOK + 2
1365 ; ******************************************************************************
1369 ; ----------------------------------------------------------------------
1371 ; SETDRAWPAGE, page in A
1373 ; ----------------------------------------------------------------------
1385 ; ******************************************************************************
1387 ; ----------------------------------------------------------------------
1389 ; Unimplemented functions that require an error code
1391 ; ----------------------------------------------------------------------
1394 lda #TGI_ERR_INV_FUNC
1398 ; ******************************************************************************
1400 ; ----------------------------------------------------------------------
1402 ; Unimplemented functions that don't require an error code
1404 ; ----------------------------------------------------------------------