2 ; Generic Atari graphics driver
13 ; ******************************************************************************
15 ; ----------------------------------------------------------------------
17 ; Header. Includes jump table and constants.
19 ; ----------------------------------------------------------------------
25 .byte $74, $67, $69 ; "tgi"
26 .byte TGI_API_VERSION ; TGI API version number
27 libref: .addr $0000 ; Library reference
28 .word x_res ; X resolution
29 .word y_res ; Y resolution
30 .byte colors ; Number of drawing colors
31 .byte pages ; Number of screens available
32 .byte 8 ; System font X size
33 .byte 8 ; System font Y size
34 .word aspect ; Aspect ratio
35 .byte 0 ; TGI driver flags
58 .addr 0 ; IRQ entry is unused
60 ; ******************************************************************************
62 ; ----------------------------------------------------------------------
66 ; ----------------------------------------------------------------------
74 ; ******************************************************************************
76 ; ----------------------------------------------------------------------
80 ; ----------------------------------------------------------------------
88 .if ::grmode = 9 || ::grmode = 11
89 palette = default_palette
92 .res colors ; The current palette
96 .res 1 ; Current pixel mask
98 .res 1 ; IOCB channel number for graphics
102 .res 1 ; High byte of screen address for screen page 0
104 .res 1 ; High byte of display list address for screen page 0
105 ; Page 1's addresses are 8K higher
110 .byte 1 ; Horizontal text scaling factor
112 .byte 1 ; Vertical text scaling factor
114 .word 8 ; Horizontal text scaling factor * 8
116 .word 8 ; Vertical text scaling factor * 8
118 .byte 0 ; Text direction,
126 ; ******************************************************************************
130 ; ----------------------------------------------------------------------
132 ; Put a pixel at (sptr),y using x as the bit mask offset
134 ; ----------------------------------------------------------------------
143 ; ******************************************************************************
147 .byte "S:",$9B ; Device code for screen
148 screen_device_length := * - screen_device
154 ; ----------------------------------------------------------------------
156 ; INIT: Switch to graphics mode
158 ; ----------------------------------------------------------------------
162 ; Initialize drawing color
176 ; setup pointer to CIO
194 ; Not enough resources available (free IOCB or memory)
195 ; enter with C cleared!
196 nores: lda #TGI_ERR_NO_RES
199 found: ; Check if enough RAM is available
209 bcc nores ; not enough memory
211 ; Switch into graphics mode
222 lda #<screen_device_length
224 lda #>screen_device_length
229 ; Reserve 8K of high memory
233 ; Close and reopen graphics
248 lda #<screen_device_length
250 lda #>screen_device_length
253 ; Save screen pointers
262 ; Reset the error code and return
268 ; ******************************************************************************
272 ; ----------------------------------------------------------------------
274 ; DONE: Switch back to text mode
276 ; ----------------------------------------------------------------------
281 ; Free 8K of high memory
292 ; Close the S: device
297 ; Reopen it in Graphics 0
308 lda #<screen_device_length
310 lda #>screen_device_length
314 ; Now close it again; we don't need it anymore :)
320 ; ******************************************************************************
324 ; ----------------------------------------------------------------------
326 ; GETERROR: Return the error code in A and clear it
328 ; ----------------------------------------------------------------------
337 ; ******************************************************************************
341 ; ----------------------------------------------------------------------
343 ; CLEAR: Clear the screen
345 ; ----------------------------------------------------------------------
348 ; Load the screen address in sptr
359 ; Clear full pages if any
370 ; Clear the rest, if any
380 ; ******************************************************************************
384 ; ----------------------------------------------------------------------
386 ; GETPALETTE: Return the current palette in A/X
388 ; ----------------------------------------------------------------------
396 ; ******************************************************************************
400 ; ----------------------------------------------------------------------
402 ; GETDEFPALETTE: Return the default palette in A/X
404 ; ----------------------------------------------------------------------
407 lda #<default_palette
408 ldx #>default_palette
412 ; ******************************************************************************
416 ; ----------------------------------------------------------------------
418 ; SETCOLOR: Set the drawing color (in A)
420 ; ----------------------------------------------------------------------
426 ; Map colors like this: 0 -> 0, 1 -> 15, 2 -> 1, 3 -> 2 etc.
440 ; ******************************************************************************
444 ; ----------------------------------------------------------------------
446 ; CALC: Calculate the screen address
448 ; x1 (ptr1) x coordinate
449 ; y1 (ptr2) y coordinate
451 ; sptr + y screen address
454 ; ----------------------------------------------------------------------
459 ; calculate line offset
464 .if ::x_res / ::ppb = 40
466 .elseif ::x_res / ::ppb = 20
468 .elseif ::x_res / ::ppb = 10
492 ; calculate bit mask offset
497 ; calculate row offset
529 ; ******************************************************************************
533 ; ----------------------------------------------------------------------
535 ; Draw one pixel at x1, y1
537 ; ----------------------------------------------------------------------
545 ; ******************************************************************************
549 ; ----------------------------------------------------------------------
551 ; GETPIXEL: Read the color value of a pixel and return it in A/X
553 ; ----------------------------------------------------------------------
589 ; Map colors like this: 0 -> 0, 15 -> 1, 2 -> 3, 3 -> 4 etc.
600 ; Map out of range colors like this:
614 .endif ; ::grmode = 10
623 ; ******************************************************************************
627 ; ----------------------------------------------------------------------
629 ; LINE: Draw a line from x1,y1 to x2,y2
631 ; ----------------------------------------------------------------------
635 ; position ptr1, ptr2
685 ; if dx is positive, no problem
688 ; if dx is negative, swap x1,y1 with x2,y2
689 lda x1 ; x1 <-> x2, low byte
693 lda x1 + 1 ; x1 <-> x2, high byte
697 lda y1 ; y1 <-> y2, low byte
701 lda y1 + 1 ; y1 <-> y2, high byte
730 lda #<(65536 - x_res / ppb)
732 lda #>(65536 - x_res / ppb)
734 bne skip_iy_1 ; always
767 ; dx is the major axis
814 ; loop while dx-- >= 0
828 ; dy is the major axis
874 ; loop while dy-- >= 0
886 .endif ; USE_CIO_LINE
889 ; ******************************************************************************
893 ; ----------------------------------------------------------------------
895 ; Clip and draw bar, this function will disappear when text clipping
896 ; will be done int the TGI kernel
898 ; ----------------------------------------------------------------------
909 .if >(::x_res - 1) > 0
928 .if >(::x_res - 1) > 0
939 ; ******************************************************************************
943 ; ----------------------------------------------------------------------
945 ; BAR: Draw a filled rectangle with the corners at x1,y1,x2,y2
947 ; ----------------------------------------------------------------------
963 ; Calculate upper left corner
974 ; Calculate upper right corner
978 .if >(::x_res - 1) > 0
994 ; Calculate memory difference between x1 and x2
1032 cont: ; Go to next row
1038 skipm: ; Loop while --dy > 0
1046 ; ******************************************************************************
1050 ; ----------------------------------------------------------------------
1052 ; TEXTSTYLE: Set text style. Scale factors in X and Y and direction in A
1054 ; ----------------------------------------------------------------------
1059 ; Save text direction in bit 8 so that we can use BIT instruction later
1063 ; Save 8 * scaling factors
1089 ; ******************************************************************************
1093 ; ----------------------------------------------------------------------
1095 ; OUTTEXT: Draw text at x1, y1. String is in ptr3
1097 ; ----------------------------------------------------------------------
1105 ataint: .byte 64,0,32,96
1109 .if >(::x_res - 1) > 0
1122 ; Don't draw zero sized characters
1128 not0: ; Save string address, ptr3 is needed by BAR
1143 .if >(::x_res - 1) > 0
1152 ; Calculate y2 and adjust y1
1164 ; Calculate for vertical text
1190 skiph: ; Save coords
1205 .if >(::x_res - 1) > 0
1212 ; Draw one character
1213 ; Convert to ANTIC code
1224 ; Save and clear inverse video bit
1227 ; Calculate font data address
1252 .if >(::x_res - 1) > 0
1261 ; Put one row of the glyph
1270 ; Put one column of the row
1338 ; Restore old values
1351 .if >(::x_res - 1) > 0
1397 .if >(::x_res - 1) > 0
1420 jne loop ; Check for null character
1426 ; ******************************************************************************
1430 ; ----------------------------------------------------------------------
1432 ; SETVIEWPAGE, page in A
1434 ; ----------------------------------------------------------------------
1443 beq done ; We're already in the desired page
1448 ; Wait until next VBLANK
1449 wait: cpx RTCLOK + 2
1456 ; ******************************************************************************
1460 ; ----------------------------------------------------------------------
1462 ; SETDRAWPAGE, page in A
1464 ; ----------------------------------------------------------------------
1476 ; ******************************************************************************
1478 ; ----------------------------------------------------------------------
1480 ; Unimplemented functions that require an error code
1482 ; ----------------------------------------------------------------------
1485 lda #TGI_ERR_INV_FUNC
1489 ; ******************************************************************************
1491 ; ----------------------------------------------------------------------
1493 ; Unimplemented functions that don't require an error code
1495 ; ----------------------------------------------------------------------