]> git.sur5r.net Git - cc65/blob - libsrc/atmos/atmos-228-200-3.s
Save some bytes by sharing the code doing the actual vector setting. Note: Jumping...
[cc65] / libsrc / atmos / atmos-228-200-3.s
1 ;
2 ; Graphics driver for the 228x200x3 palette mode on the Atmos
3 ;
4 ; Stefan Haubenthal <polluks@sdf.lonestar.org>
5 ; 2012-08-11, Greg King <greg.king5@verizon.net>
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "tgi-kernel.inc"
11         .include        "tgi-error.inc"
12         .include        "atmos.inc"
13
14         .macpack        generic
15
16 XSIZE   =       6               ; System font width
17 YSIZE   =       8               ; System font height
18
19 ; ------------------------------------------------------------------------
20 ; Header. Includes jump table and constants.
21
22 .segment        "JUMPTABLE"
23
24 ; The first part of the header is a structure that has a signature,
25 ; and defines the capabilities of the driver.
26
27         .byte   "tgi"
28         .byte   TGI_API_VERSION ; TGI API version number
29         .word   228             ; x resolution
30         .word   200             ; y resolution
31         .byte   3               ; Number of drawing colors
32         .byte   1               ; Number of screens available
33         .byte   XSIZE           ; System font x size
34         .byte   YSIZE           ; System font y size
35         .word   $011C           ; Aspect ratio (based on 4/3 display)
36         .byte   0               ; TGI driver flags
37
38 ; Next comes the jump table. Currently, all entries must be valid;
39 ; and, may point to an RTS, for test versions (function not implemented).
40
41         .addr   INSTALL
42         .addr   UNINSTALL
43         .addr   INIT
44         .addr   DONE
45         .addr   GETERROR
46         .addr   CONTROL
47         .addr   CLEAR
48         .addr   SETVIEWPAGE
49         .addr   SETDRAWPAGE
50         .addr   SETCOLOR
51         .addr   SETPALETTE
52         .addr   GETPALETTE
53         .addr   GETDEFPALETTE
54         .addr   SETPIXEL
55         .addr   GETPIXEL
56         .addr   LINE
57         .addr   BAR
58         .addr   TEXTSTYLE
59         .addr   OUTTEXT
60         .addr   0               ; IRQ entry is unused
61
62 ; ------------------------------------------------------------------------
63 ; Data.
64
65 ; Variables mapped to the zero-page segment variables. These are
66 ; used for passing parameters to the driver.
67
68 X1      :=      ptr1
69 Y1      :=      ptr2
70 X2      :=      ptr3
71 Y2      :=      ptr4
72
73 ; Absolute variables used in the code
74
75 .bss
76
77 ERROR:          .res    1       ; Error code
78 MODE:           .res    1       ; Graphics mode
79 PALETTE:        .res    2
80
81 ; Constants and table
82 ; BASIC 1.1 addresses
83 PATTERN :=      $213
84 PARAM1  :=      $2E1            ; & $2E2
85 PARAM2  :=      $2E3            ; & $2E4
86 PARAM3  :=      $2E5            ; & $2E6
87 TEXT    :=      $EC21
88 HIRES   :=      $EC33
89 CURSET  :=      $F0C8
90 CURMOV  :=      $F0FD
91 DRAW    :=      $F110
92 CHAR    :=      $F12D
93 POINT   :=      $F1C8
94 PAPER   :=      $F204
95 INK     :=      $F210
96
97 .rodata
98
99 ; Default colors: black background, white foreground
100 ; (The third "color" actually flips a pixel
101 ; between the foreground and background colors.)
102 ;
103 DEFPALETTE:     .byte   0, 1
104
105 .code
106
107 ; ------------------------------------------------------------------------
108 ; INIT: Changes an already installed device from text mode to graphics mode.
109 ; Note that INIT/DONE may be called multiple times while the driver
110 ; is loaded, while INSTALL is called only once. So, any code that is needed
111 ; to initialize variables and so on must go here. Setting palette and
112 ; clearing the screen are not needed because they are called by the graphics
113 ; kernel later.
114 ; The graphics kernel never will call INIT when a graphics mode is already
115 ; active, so there is no need to protect against that.
116 ;
117 ; Must set an error code: YES
118 ;
119
120 INIT:
121
122 ; Switch into graphics mode.
123
124         jsr     HIRES
125
126 ; Done, reset the error code.
127
128 ; ------------------------------------------------------------------------
129 ; GETERROR: Return the error code in A, and clear it.
130
131 GETERROR:
132         ldx     #TGI_ERR_OK
133         lda     ERROR
134         stx     ERROR
135
136 ; ------------------------------------------------------------------------
137 ; INSTALL routine. Is called after the driver is loaded into memory. May
138 ; initialize anything that has to be done just once. Is probably empty
139 ; most of the time.
140 ;
141 ; Must set an error code: NO
142 ;
143
144 INSTALL:
145
146 ; ------------------------------------------------------------------------
147 ; UNINSTALL routine. Is called before the driver is removed from memory. May
148 ; clean up anything done by INSTALL, but probably is empty most of the time.
149 ;
150 ; Must set an error code: NO
151 ;
152
153 UNINSTALL:
154         rts
155
156 ; ------------------------------------------------------------------------
157 ; DONE: Will be called to switch the graphics device back into text mode.
158 ; The graphics kernel never will call DONE when no graphics mode is active,
159 ; so there is no need to protect against that.
160 ;
161 ; Must set an error code: NO
162 ;
163
164 DONE    :=      TEXT
165
166 ; ------------------------------------------------------------------------
167 ; CONTROL: Platform-/driver-specific entry point.
168 ;
169 ; Must set an error code: YES
170 ;
171
172 CONTROL:
173         sta     PATTERN
174         lda     #TGI_ERR_OK
175         sta     ERROR
176         rts
177
178 ; ------------------------------------------------------------------------
179 ; CLEAR: Clears the screen.
180 ;
181 ; Must set an error code: NO
182 ;
183
184 CLEAR   :=      HIRES
185
186 ; ------------------------------------------------------------------------
187 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
188 ; The page number already is checked to be valid, by the graphics kernel.
189 ;
190 ; Must set an error code: NO (will be called only if page OK)
191 ;
192
193 SETVIEWPAGE:
194
195 ; ------------------------------------------------------------------------
196 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
197 ; The page number already is checked to be valid, by the graphics kernel.
198 ;
199 ; Must set an error code: NO (will be called only if page OK)
200 ;
201
202 SETDRAWPAGE:
203         rts
204
205 ; ------------------------------------------------------------------------
206 ; SETCOLOR: Set the drawing color (in A). The new color already is checked
207 ; to be in a valid range (0..maxcolor-1).
208 ;
209 ; Must set an error code: NO (will be called only if color OK)
210 ;
211
212 SETCOLOR:
213         sta     MODE
214         rts
215
216 ; ------------------------------------------------------------------------
217 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
218 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
219 ; are not supported.
220 ;
221 ; Must set an error code: YES
222 ;
223
224 SETPALETTE:
225         ldy     #0
226         jsr     flipcolor
227         sty     PARAM1+1
228         jsr     PAPER
229         ldy     #1
230         jsr     flipcolor
231         dey                     ; TGI_ERR_OK
232         sty     ERROR
233         sty     PARAM1+1
234         jmp     INK
235
236 flipcolor:
237         lda     (ptr1),y
238         sta     PALETTE,y
239         cmp     #1
240         beq     @flip
241         cmp     #7
242         bne     @keep
243 @flip:  eor     #1 ^ 7
244 @keep:  sta     PARAM1
245         rts
246
247 ; ------------------------------------------------------------------------
248 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
249 ; set the palette should return the default palette here, so there's no
250 ; way for this function to fail.
251 ;
252 ; Must set an error code: NO
253 ;
254
255 GETPALETTE:
256         lda     #<PALETTE
257         ldx     #>PALETTE
258         rts
259
260 ; ------------------------------------------------------------------------
261 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
262 ; drivers should return something reasonable here, even drivers that don't
263 ; support palettes; otherwise, the caller has no way to determine the colors
264 ; of the (not changeable) palette.
265 ;
266 ; Must set an error code: NO (all drivers must have a default palette)
267 ;
268
269 GETDEFPALETTE:
270         lda     #<DEFPALETTE
271         ldx     #>DEFPALETTE
272         rts
273
274 ; ------------------------------------------------------------------------
275 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
276 ; color. The co-ordinates passed to this function are never outside the
277 ; visible screen area, so there is no need for clipping inside this function.
278 ;
279 ; Must set an error code: NO
280 ;
281
282 SETPIXEL:
283         lda     Y1
284         sta     PARAM2
285         lda     MODE
286 mymode: sta     PARAM3
287         lda     X1
288         add     #2 * XSIZE      ; Skip screen attribute columns
289         sta     PARAM1
290         lda     #0
291         sta     PARAM1+1
292         sta     PARAM2+1
293         sta     PARAM3+1
294         jmp     CURSET
295
296 ; ------------------------------------------------------------------------
297 ; GETPIXEL: Read the color value of a pixel, and return it in A/X. The
298 ; co-ordinates passed to this function are never outside the visible screen
299 ; area, so there is no need for clipping inside this function.
300
301 GETPIXEL:
302         lda     X1
303         sta     PARAM1
304         lda     Y1
305         sta     PARAM2
306         lda     #0
307         sta     PARAM1+1
308         sta     PARAM2+1
309         jsr     POINT
310         lda     PARAM1
311         and     #%00000001
312         ldx     #0
313         rts
314
315 ; ------------------------------------------------------------------------
316 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
317 ; X2/Y2 = ptr3/ptr4, using the current drawing color.
318 ;
319 ; Must set an error code: NO
320 ;
321
322 LINE:
323         jsr     SETPIXEL
324         lda     X2
325         sub     X1
326         sta     PARAM1
327         lda     X2+1
328         sbc     X1+1
329         sta     PARAM1+1
330         lda     Y2
331         sub     Y1
332         sta     PARAM2
333         lda     Y2+1
334         sbc     Y1+1
335         sta     PARAM2+1
336         lda     MODE
337         sta     PARAM3
338         ldx     #>0
339         stx     PARAM3+1
340         jmp     DRAW
341
342 ; ------------------------------------------------------------------------
343 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
344 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4, using the current drawing color.
345 ; Contrary to most other functions, the graphics kernel will sort and clip
346 ; the co-ordinates before calling the driver; so, on entry, the following
347 ; conditions are valid:
348 ;       X1 <= X2
349 ;       Y1 <= Y2
350 ;       (X1 >= 0) && (X1 < XRES)
351 ;       (X2 >= 0) && (X2 < XRES)
352 ;       (Y1 >= 0) && (Y1 < YRES)
353 ;       (Y2 >= 0) && (Y2 < YRES)
354 ;
355 ; Must set an error code: NO
356 ;
357
358 BAR:
359         inc     Y2
360 @L1:    lda     Y2
361         pha
362         lda     Y1
363         sta     Y2
364         jsr     LINE
365         pla
366         sta     Y2
367         inc     Y1
368         cmp     Y1
369         bne     @L1
370         rts
371
372 ; ------------------------------------------------------------------------
373 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in the x
374 ; and y directions is passend in X/Y, the text direction is passed in A.
375 ;
376 ; Must set an error code: NO
377 ;
378
379 TEXTSTYLE:
380         rts
381
382
383 ; ------------------------------------------------------------------------
384 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
385 ; current text style. The text to output is given as a zero-terminated
386 ; string with its address in ptr3.
387 ;
388 ; Must set an error code: NO
389 ;
390
391 OUTTEXT:
392         lda     Y1
393         sub     #(YSIZE - 1)
394         sta     PARAM2
395         lda     #3              ; (Move graphics cursor; don't draw)
396         jsr     mymode
397
398         ldy     #0
399 @next:  lda     (ptr3),y
400         beq     @end
401         sta     PARAM1
402         lda     #0
403         sta     PARAM2
404         sta     PARAM1+1
405         sta     PARAM2+1
406         sta     PARAM3+1
407         lda     MODE
408         sta     PARAM3
409         tya
410         pha
411         jsr     CHAR
412         lda     #XSIZE
413         sta     PARAM1
414         lda     #0
415         sta     PARAM2
416         sta     PARAM1+1
417         sta     PARAM2+1
418         sta     PARAM3+1
419         lda     #3
420         sta     PARAM3
421         jsr     CURMOV
422         pla
423         tay
424         iny
425         bne     @next
426 @end:   rts