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