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
165 found: ; Check if enough RAM is available
178 nomem: lda #TGI_ERR_NO_MEM
182 ; Switch into graphics mode
193 lda #<screen_device_length
195 lda #>screen_device_length
200 ; Reserve 8K of high memory
204 ; Close and reopen graphics
219 lda #<screen_device_length
221 lda #>screen_device_length
224 ; Save screen poniters
232 ; Reset the error code and return
238 ; ******************************************************************************
242 ; ----------------------------------------------------------------------
244 ; DONE: Switch back to text mode
246 ; ----------------------------------------------------------------------
250 ; Free 8K of high memory
261 ; Close the S: device
266 ; Reopen it in Graphics 0
277 lda #<screen_device_length
279 lda #>screen_device_length
283 ; Now close it again; we don't need it anymore
289 ; ******************************************************************************
293 ; ----------------------------------------------------------------------
295 ; GETERROR: Return the error code in A and clear it
297 ; ----------------------------------------------------------------------
306 ; ******************************************************************************
310 ; ----------------------------------------------------------------------
312 ; CLEAR: Clear the screen
314 ; ----------------------------------------------------------------------
317 ; Load the screen address in sptr
327 ; Clear full pages if any
338 ; Clear the rest, if any
349 ; ******************************************************************************
353 ; ----------------------------------------------------------------------
355 ; GETPALETTE: Return the current palette in A/X
357 ; ----------------------------------------------------------------------
365 ; ******************************************************************************
369 ; ----------------------------------------------------------------------
371 ; GETDEFPALETTE: Return the default palette in A/X
373 ; ----------------------------------------------------------------------
376 lda #<default_palette
377 ldx #>default_palette
381 ; ******************************************************************************
385 ; ----------------------------------------------------------------------
387 ; SETCOLOR: Set the drawing color (in A)
389 ; ----------------------------------------------------------------------
394 ; Map colors like this: 0 -> 0, 1 -> 15, 2 -> 1, 3 -> 2 etc.
406 ; ******************************************************************************
410 ; ----------------------------------------------------------------------
412 ; CALC: Calculate the screen address
414 ; x1 (ptr1) x coordinate
415 ; y1 (ptr2) y coordinate
417 ; sptr + y screen address
420 ; ----------------------------------------------------------------------
425 ; calculate line offset
432 .elseif x_res / ppb = 20
434 .elseif x_res / ppb = 10
455 ; calculate bit mask offset
460 ; calculate row offset
490 ; ******************************************************************************
494 ; ----------------------------------------------------------------------
496 ; Draw one pixel at x1, y1
498 ; ----------------------------------------------------------------------
506 ; ******************************************************************************
510 ; ----------------------------------------------------------------------
512 ; GETPIXEL: Read the color value of a pixel and return it in A/X
514 ; ----------------------------------------------------------------------
547 ; Map colors like this: 0 -> 0, 15 -> 1, 2 -> 3, 3 -> 4 etc.
557 ; Map out of range colors like this:
577 ; ******************************************************************************
581 ; ----------------------------------------------------------------------
583 ; LINE: Draw a line from x1,y1 to x2,y2
585 ; ----------------------------------------------------------------------
604 ; if dx is positive, no problem
607 ; if dx is negative, swap x1,y1 with x2,y2
608 lda x1 ; x1 <-> x2, low byte
612 lda x1 + 1 ; x1 <-> x2, high byte
616 lda y1 ; y1 <-> y2, low byte
620 lda y1 + 1 ; y1 <-> y2, high byte
649 lda #<(65536 - x_res / ppb)
651 lda #>(65536 - x_res / ppb)
653 bne skip_iy_1 ; always
686 ; dx is the major axis
733 ; loop while dx-- >= 0
747 ; dy is the major axis
793 ; loop while dy-- >= 0
807 ; ******************************************************************************
811 ; ----------------------------------------------------------------------
815 ; ----------------------------------------------------------------------
852 ; ******************************************************************************
856 ; ----------------------------------------------------------------------
858 ; BAR: Draw a filled rectangle with the corners at x1,y1,x2,y2
860 ; ----------------------------------------------------------------------
876 ; Calculate upper left corner
887 ; Calculate upper right corner
905 ; Calculate memory difference between x1 and x2
943 cont: ; Go to next row
949 skipm: ; Loop while --dy > 0
957 ; ******************************************************************************
961 ; ----------------------------------------------------------------------
963 ; TEXTSTYLE: Set text style. Scale factors in X and Y and direction in A
965 ; ----------------------------------------------------------------------
970 ; Save text direction in bit 8 so that we can use BIT instruction later
974 ; Save 8 * scaling factors
996 ; ******************************************************************************
1000 ; ----------------------------------------------------------------------
1002 ; OUTTEXT: Draw text at x1, y1. String is in ptr3
1004 ; ----------------------------------------------------------------------
1012 ataint: .byte 64,0,32,96
1015 .if >(x_res - 1) > 0
1026 ; Don't draw zero sized characters
1032 @cont: ; Save string address, ptr3 is needed by BAR
1046 .if >(x_res - 1) > 0
1055 ; Calculate y2 and adjust y1
1067 ; Calculate for vertical text
1093 skiph: ; Save coords
1095 ; Draw one character
1102 bne loop ; Check for null character
1105 ; --------------------
1106 ; Output one character
1108 ; Convert to ANTIC code
1119 ; Save and clear inverse video bit
1122 ; Calculate font data address
1144 .if >(x_res - 1) > 0
1152 ; Put one row of the glyph
1161 ; Put one column of the row
1181 ; Restore old values
1193 .if >(x_res - 1) > 0
1208 ; -------------------------
1209 inc_x: ; increase x coords
1233 ; -------------------------
1234 dec_y: ; decrease y coords
1262 ; -------------------------
1263 save_text_y: ; Save text's height coords
1275 .if >(x_res - 1) > 0
1283 ; -------------------------
1284 restore_text_y: ; Position to next char
1315 .if >(x_res - 1) > 0
1340 ; ******************************************************************************
1344 ; ----------------------------------------------------------------------
1346 ; SETVIEWPAGE, page in A
1348 ; ----------------------------------------------------------------------
1357 beq done ; We're already in the desired page
1362 ; Wait until next VBLANK
1363 wait: cpx RTCLOK + 2
1370 ; ******************************************************************************
1374 ; ----------------------------------------------------------------------
1376 ; SETDRAWPAGE, page in A
1378 ; ----------------------------------------------------------------------
1390 ; ******************************************************************************
1392 ; ----------------------------------------------------------------------
1394 ; Unimplemented functions that require an error code
1396 ; ----------------------------------------------------------------------
1399 lda #TGI_ERR_INV_FUNC
1403 ; ******************************************************************************
1405 ; ----------------------------------------------------------------------
1407 ; Unimplemented functions that don't require an error code
1409 ; ----------------------------------------------------------------------