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