]> git.sur5r.net Git - cc65/blob - libsrc/apple2/tgi/a2.lo.s
Create static drivers directly from source files.
[cc65] / libsrc / apple2 / tgi / a2.lo.s
1 ;
2 ; Graphics driver for the 40x48x16 mode on the Apple II
3 ;
4 ; Stefan Haubenthal <polluks@sdf.lonestar.org>
5 ; Oliver Schmidt <ol.sc@web.de>
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "tgi-kernel.inc"
11         .include        "tgi-error.inc"
12         .include        "apple2.inc"
13
14         .macpack        module
15
16 ; ------------------------------------------------------------------------
17
18 ; Zero page stuff
19
20 H2      :=      $2C
21 COLOR   :=      $30
22
23 ; ROM entry points
24
25 TEXT    :=      $F399
26 PLOT    :=      $F800
27 HLINE   :=      $F819
28 CLRSC2  :=      $F838
29 SETCOL  :=      $F864
30 SCRN    :=      $F871
31 SETGR   :=      $FB40
32 HOME    :=      $FC58
33
34 ; Used for passing parameters to the driver
35
36 X1      :=      ptr1
37 Y1      :=      ptr2
38 X2      :=      ptr3
39 Y2      :=      ptr4
40
41 ; ------------------------------------------------------------------------
42
43         .ifdef  __APPLE2ENH__
44         module_header   _a2e_lo_tgi
45         .else
46         module_header   _a2_lo_tgi
47         .endif
48
49 ; Header. Includes jump table and constants.
50
51 ; First part of the header is a structure that has a magic and defines the
52 ; capabilities of the driver
53
54         .byte   $74, $67, $69   ; "tgi"
55         .byte   TGI_API_VERSION ; TGI API version number
56         .addr   $0000           ; Library reference
57         .word   40              ; X resolution
58         .word   48              ; Y resolution
59         .byte   16              ; Number of drawing colors
60         .byte   1               ; Number of screens available
61         .byte   8               ; System font X size
62         .byte   8               ; System font Y size
63         .word   $0198           ; Aspect ratio (based on 4/3 display)
64         .byte   0               ; TGI driver flags
65
66 ; Next comes the jump table. With the exception of IRQ, all entries must be
67 ; valid and may point to an RTS for test versions (function not implemented).
68
69         .addr   INSTALL
70         .addr   UNINSTALL
71         .addr   INIT
72         .addr   DONE
73         .addr   GETERROR
74         .addr   CONTROL
75         .addr   CLEAR
76         .addr   SETVIEWPAGE
77         .addr   SETDRAWPAGE
78         .addr   SETCOLOR
79         .addr   SETPALETTE
80         .addr   GETPALETTE
81         .addr   GETDEFPALETTE
82         .addr   SETPIXEL
83         .addr   GETPIXEL
84         .addr   LINE
85         .addr   BAR
86         .addr   TEXTSTYLE
87         .addr   OUTTEXT
88         .addr   0               ; IRQ entry is unused
89
90 ; ------------------------------------------------------------------------
91
92         .bss
93
94 ERROR:  .res    1               ; Error code
95 MIX:    .res    1               ; 4 lines of text
96
97 ; ------------------------------------------------------------------------
98
99         .rodata
100
101 DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
102             .byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
103
104 TGI2COL:    .byte $00, $0C, $03, $0F, $01, $09, $06, $02
105             .byte $04, $05, $07, $08, $0A, $0B, $0D, $0E
106
107 COL2TGI:    .byte $00, $04, $07, $02, $08, $09, $06, $0A
108             .byte $0B, $05, $0C, $0D, $01, $0E, $0F, $03
109
110 MAXY:   .byte 47, 39
111
112 ; ------------------------------------------------------------------------
113
114         .code
115
116 ; INIT: Changes an already installed device from text mode to graphics mode.
117 ; Note that INIT/DONE may be called multiple times while the driver
118 ; is loaded, while INSTALL is only called once, so any code that is needed
119 ; to initializes variables and so on must go here. Setting palette and
120 ; clearing the screen is not needed because this is called by the graphics
121 ; kernel later.
122 ; The graphics kernel will never call INIT when a graphics mode is already
123 ; active, so there is no need to protect against that.
124 ; Must set an error code: YES
125 INIT:
126         ; Switch into graphics mode
127         bit     $C082           ; Switch in ROM
128         jsr     SETGR
129         bit     MIXCLR
130         bit     $C080           ; Switch in LC bank 2 for R/O
131
132         ; Done, reset the error code
133         lda     #TGI_ERR_OK
134         sta     ERROR
135         sta     MIX
136
137         ; Fall through
138
139 ; INSTALL routine. Is called after the driver is loaded into memory. May
140 ; initialize anything that has to be done just once. Is probably empty
141 ; most of the time.
142 ; Must set an error code: NO
143 INSTALL:
144         ; Fall through
145
146 ; UNINSTALL routine. Is called before the driver is removed from memory. May
147 ; clean up anything done by INSTALL but is probably empty most of the time.
148 ; Must set an error code: NO
149 UNINSTALL:
150         ; Fall through
151
152 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
153 ; The page number is already checked to be valid by the graphics kernel.
154 ; Must set an error code: NO (will only be called if page ok)
155 SETVIEWPAGE:
156         ; Fall through
157
158 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
159 ; The page number is already checked to be valid by the graphics kernel.
160 ; Must set an error code: NO (will only be called if page ok)
161 SETDRAWPAGE:
162         ; Fall through
163
164 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
165 ; direction is passend in X/Y, the text direction is passed in A.
166 ; Must set an error code: NO
167 TEXTSTYLE:
168         ; Fall through
169
170 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
171 ; current text style. The text to output is given as a zero terminated
172 ; string with address in ptr3.
173 ; Must set an error code: NO
174 OUTTEXT:
175         rts
176
177 ; DONE: Will be called to switch the graphics device back into text mode.
178 ; The graphics kernel will never call DONE when no graphics mode is active,
179 ; so there is no need to protect against that.
180 ; Must set an error code: NO
181 DONE:
182         bit     $C082           ; Switch in ROM
183         jsr     TEXT
184         jsr     HOME
185         bit     $C080           ; Switch in LC bank 2 for R/O
186         rts
187
188 ; GETERROR: Return the error code in A and clear it.
189 GETERROR:
190         lda     ERROR
191         ldx     #TGI_ERR_OK
192         stx     ERROR
193         rts
194
195 ; CLEAR: Clears the screen.
196 ; Must set an error code: NO
197 CLEAR:
198         bit     $C082           ; Switch in ROM
199         lda     COLOR           ; Save current drawing color
200         pha
201         ldx     MIX
202         ldy     MAXY,x          ; Max Y depends on 4 lines of text
203         jsr     CLRSC2
204         pla
205         sta     COLOR           ; Restore current drawing color
206         bit     $C080           ; Switch in LC bank 2 for R/O
207         rts
208
209 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
210 ; to be in a valid range (0..maxcolor-1).
211 ; Must set an error code: NO (will only be called if color ok)
212 SETCOLOR:
213         bit     $C082           ; Switch in ROM
214         tax
215         lda     TGI2COL,x
216         jsr     SETCOL
217         bit     $C080           ; Switch in LC bank 2 for R/O
218         rts
219
220 ; CONTROL: Platform/driver specific entry point.
221 ; Must set an error code: YES
222 CONTROL:
223         ; Check data msb and code to be 0
224         ora     ptr1+1
225         bne     err
226
227         ; Check data lsb to be [0..1]
228         lda     ptr1
229         cmp     #1+1
230         bcs     err
231         bit     $C082           ; Switch in ROM
232
233         ; Switch 4 lines of text
234         tax
235         .assert MIXCLR + 1 = MIXSET, error
236         lda     MIXCLR,x        ; No BIT absolute,X available
237
238         ; Save current switch setting
239         txa
240         sta     MIX
241         bne     text
242
243         ; Clear 8 lines of graphics
244         lda     COLOR           ; Save current drawing color
245         pha
246         lda     #39             ; Rightmost column
247         sta     H2
248         ldx     #40             ; First line
249 :       txa
250         ldy     #$00            ; Leftmost column
251         sty     COLOR           ; Black
252         jsr     HLINE           ; Preserves X
253         inx
254         cpx     #47+1           ; Last line
255         bcc     :-
256         pla
257         sta     COLOR           ; Restore current drawing color
258         bcs     :+              ; Branch always
259
260         ; Clear 4 lines of text
261 text:   jsr     HOME
262 :       bit     $C080           ; Switch in LC bank 2 for R/O
263
264         ; Done, reset the error code
265         lda     #TGI_ERR_OK
266         beq     :+              ; Branch always
267
268         ; Done, set the error code
269 err:    lda     #TGI_ERR_INV_ARG
270 :       sta     ERROR
271         rts
272
273 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
274 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
275 ; are not supported
276 ; Must set an error code: YES
277 SETPALETTE:
278         lda     #TGI_ERR_INV_FUNC
279         sta     ERROR
280         rts
281
282 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
283 ; set the palette should return the default palette here, so there's no
284 ; way for this function to fail.
285 ; Must set an error code: NO
286 GETPALETTE:
287         ; Fall through
288
289 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
290 ; drivers should return something reasonable here, even drivers that don't
291 ; support palettes, otherwise the caller has no way to determine the colors
292 ; of the (not changeable) palette.
293 ; Must set an error code: NO (all drivers must have a default palette)
294 GETDEFPALETTE:
295         lda     #<DEFPALETTE
296         ldx     #>DEFPALETTE
297         rts
298
299 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
300 ; color. The coordinates passed to this function are never outside the
301 ; visible screen area, so there is no need for clipping inside this function.
302 ; Must set an error code: NO
303 SETPIXEL:
304         bit     $C082           ; Switch in ROM
305         ldy     X1
306         lda     Y1
307         jsr     PLOT
308         bit     $C080           ; Switch in LC bank 2 for R/O
309         rts
310
311 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
312 ; coordinates passed to this function are never outside the visible screen
313 ; area, so there is no need for clipping inside this function.
314 GETPIXEL:
315         bit     $C082           ; Switch in ROM
316         ldy     X1
317         lda     Y1
318         jsr     SCRN
319         tax
320         lda     COL2TGI,x
321         ldx     #$00
322         bit     $C080           ; Switch in LC bank 2 for R/O
323         rts
324
325 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
326 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
327 ; Contrary to most other functions, the graphics kernel will sort and clip
328 ; the coordinates before calling the driver, so on entry the following
329 ; conditions are valid:
330 ;       X1 <= X2
331 ;       Y1 <= Y2
332 ;       (X1 >= 0) && (X1 < XRES)
333 ;       (X2 >= 0) && (X2 < XRES)
334 ;       (Y1 >= 0) && (Y1 < YRES)
335 ;       (Y2 >= 0) && (Y2 < YRES)
336 ; Must set an error code: NO
337 BAR:
338         bit     $C082           ; Switch in ROM
339         lda     X2
340         sta     H2
341         inc     Y2
342         ldx     Y1
343 :       txa
344         ldy     X1
345         jsr     HLINE           ; Preserves X
346         inx
347         cpx     Y2
348         bcc     :-
349         bit     $C080           ; Switch in LC bank 2 for R/O
350         rts
351
352 ; ------------------------------------------------------------------------
353
354 .include        "../../tgi/tgidrv_line.inc"