]> git.sur5r.net Git - cc65/blob - libsrc/nes/tgi/nes-64-56-2.s
Renamed JUMPTABLE and cleaned up module.cfg.
[cc65] / libsrc / nes / tgi / nes-64-56-2.s
1 ;
2 ; Graphics driver for the lores 64x56x2 mode on the NES
3 ;
4 ; Stefan Haubenthal, 2009-03-10
5 ; Based on Maciej Witkowiak's line routine.
6 ;
7
8         .include        "zeropage.inc"
9
10         .include        "tgi-kernel.inc"
11         .include        "tgi-error.inc"
12         .include        "nes.inc"
13         .include        "get_tv.inc"
14         .import         _clrscr, setcursor, putchar
15         .import         paldata
16
17         .macpack        generic
18
19 ; ------------------------------------------------------------------------
20 ; Header. Includes jump table and constants.
21
22 .segment        "HEADER"
23
24 ; First part of the header is a structure that has a magic and defines the
25 ; capabilities of the driver
26
27         .byte   $74, $67, $69           ; "tgi"
28         .byte   TGI_API_VERSION         ; TGI API version number
29         .addr   $0000                   ; Library reference
30 xres:   .word   charsperline*2          ; Max X resolution
31 yres:   .word   56                      ; Max Y resolution
32         .byte   2                       ; Number of drawing colors
33         .byte   1                       ; Number of screens available
34         .byte   2                       ; System font X size
35         .byte   2                       ; System font Y size
36         .word   $0100                   ; Aspect ratio
37         .byte   0                       ; TGI driver flags
38
39 ; Next comes the jump table. Currently all entries must be valid and may point
40 ; to an RTS for test versions (function not implemented).
41
42         .addr   INSTALL
43         .addr   UNINSTALL
44         .addr   INIT
45         .addr   DONE
46         .addr   GETERROR
47         .addr   CONTROL
48         .addr   CLEAR
49         .addr   SETVIEWPAGE
50         .addr   SETDRAWPAGE
51         .addr   SETCOLOR
52         .addr   SETPALETTE
53         .addr   GETPALETTE
54         .addr   GETDEFPALETTE
55         .addr   SETPIXEL
56         .addr   GETPIXEL
57         .addr   LINE
58         .addr   BAR
59         .addr   TEXTSTYLE
60         .addr   OUTTEXT
61         .addr   0                       ; IRQ entry is unused
62
63 ; ------------------------------------------------------------------------
64 ; Data.
65
66 ; Variables mapped to the zero page segment variables. Some of these are
67 ; used for passing parameters to the driver.
68
69 X1              = ptr1
70 Y1              = ptr2
71 X2              = ptr3
72 Y2              = ptr4
73 RADIUS          = tmp1
74
75 ADDR            = tmp1
76 TEMP            = tmp3
77 TEMP2           = tmp4
78 TEMP3           = sreg
79 TEMP4           = sreg+1
80
81 ; Line routine stuff (must be on zpage)
82 PB              = ptr3          ; (2)   LINE
83 UB              = ptr4          ; (2)   LINE
84 ERR             = regsave       ; (2)   LINE
85 NX              = regsave+2     ; (2)   LINE
86
87 ; Absolute variables used in the code
88
89 .bss
90
91 MEM:            .res    charsperline*2*56/4
92 MEMEND:
93 ERROR:          .res    1       ; Error code
94 COLOR:          .res    1       ; Current color
95 PALETTE:        .res    2       ; The current palette
96
97 ; Line routine stuff
98
99 OGora:
100 COUNT:          .res    2
101 OUkos:
102 NY:             .res    2
103 Y3:
104 DX:             .res    1
105 DY:             .res    1
106 AY:             .res    1
107
108 ; Constants and tables
109
110 .rodata
111
112 DEFPALETTE:     .byte   $0, $1
113 OFFSET:         .byte   8, 4, 2, 1
114 ;                       00  00  00  00  01  01  01  01
115 ;                       00  01  10  11  00  01  10  11
116 CODE:           .byte   32, 29, 26, 25, 28, 24+128, 31+128, 30+128
117 ;                       10  10  10  10  11  11  11  11
118 ;                       00  01  10  11  00  01  10  11
119                 .byte   30, 31, 24, 28+128, 25+128, 26+128, 29+128, 32+128
120
121 .code
122
123 ; ------------------------------------------------------------------------
124 ; INSTALL routine. Is called after the driver is loaded into memory. May
125 ; initialize anything that has to be done just once. Is probably empty
126 ; most of the time.
127 ;
128 ; Must set an error code: NO
129 ;
130
131 INSTALL:
132         jsr     _get_tv
133         cmp     #TV::NTSC
134         beq     ntsc
135 ; TODO ROM!
136         inc     yres
137         inc     yres
138 ntsc:;  rts
139
140 ; ------------------------------------------------------------------------
141 ; UNINSTALL routine. Is called before the driver is removed from memory. May
142 ; clean up anything done by INSTALL but is probably empty most of the time.
143 ;
144 ; Must set an error code: NO
145 ;
146
147 UNINSTALL:
148         rts
149
150 ; ------------------------------------------------------------------------
151 ; INIT: Changes an already installed device from text mode to graphics
152 ; mode.
153 ; Note that INIT/DONE may be called multiple times while the driver
154 ; is loaded, while INSTALL is only called once, so any code that is needed
155 ; to initializes variables and so on must go here. Setting palette and
156 ; clearing the screen is not needed because this is called by the graphics
157 ; kernel later.
158 ; The graphics kernel will never call INIT when a graphics mode is already
159 ; active, so there is no need to protect against that.
160 ;
161 ; Must set an error code: YES
162 ;
163
164 INIT:
165
166 ; Done, reset the error code
167
168         lda     #TGI_ERR_OK
169         sta     ERROR
170 ;       rts
171
172 ; ------------------------------------------------------------------------
173 ; DONE: Will be called to switch the graphics device back into text mode.
174 ; The graphics kernel will never call DONE when no graphics mode is active,
175 ; so there is no need to protect against that.
176 ;
177 ; Must set an error code: NO
178 ;
179
180 DONE:
181         rts
182
183 ; ------------------------------------------------------------------------
184 ; GETERROR: Return the error code in A and clear it.
185
186 GETERROR:
187         lda     ERROR
188         ldx     #TGI_ERR_OK
189         stx     ERROR
190         rts
191
192 ; ------------------------------------------------------------------------
193 ; CONTROL: Platform/driver specific entry point.
194 ;
195 ; Must set an error code: YES
196 ;
197
198 CONTROL:
199         lda     #TGI_ERR_INV_FUNC
200         sta     ERROR
201         rts
202
203 ; ------------------------------------------------------------------------
204 ; CLEAR: Clears the screen.
205 ;
206 ; Must set an error code: NO
207 ;
208
209 CLEAR:
210         ldx     #<MEM
211         stx     TEMP
212         ldx     #>MEM
213         stx     TEMP+1
214         lda     #0
215         tay
216 @L1:    sta     (TEMP),y
217         iny
218         bne     @L1
219         inc     TEMP+1
220         inx
221         cpx     #>MEMEND
222         bne     @L1
223         jmp     _clrscr
224
225 ; ------------------------------------------------------------------------
226 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
227 ; to be in a valid range (0..maxcolor-1).
228 ;
229 ; Must set an error code: NO (will only be called if color ok)
230 ;
231
232 SETCOLOR:
233         sta     COLOR
234 ;       rts
235
236 ; ------------------------------------------------------------------------
237 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
238 ; The page number is already checked to be valid by the graphics kernel.
239 ;
240 ; Must set an error code: NO (will only be called if page ok)
241 ;
242
243 SETVIEWPAGE:
244
245 ; ------------------------------------------------------------------------
246 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
247 ; The page number is already checked to be valid by the graphics kernel.
248 ;
249 ; Must set an error code: NO (will only be called if page ok)
250 ;
251
252 SETDRAWPAGE:
253         rts
254
255 ; ------------------------------------------------------------------------
256 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
257 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
258 ; are not supported
259 ;
260 ; Must set an error code: YES
261 ;
262
263 SETPALETTE:
264 ; Wait for v-blank
265 @wait:  lda     PPU_STATUS
266         bpl     @wait
267
268         lda     #$3F
269         sta     PPU_VRAM_ADDR2
270         lda     #$00
271         sta     PPU_VRAM_ADDR2
272
273         ldy     #0
274         lda     (ptr1),y
275         sta     PALETTE
276         tax
277         lda     paldata,x
278 ;       sta     PPU_VRAM_IO
279
280         iny
281         lda     (ptr1),y
282         sta     PALETTE+1
283         tax
284         lda     paldata,x
285         sta     PPU_VRAM_IO
286
287         lda     #TGI_ERR_OK
288         sta     ERROR
289         rts
290
291 ; ------------------------------------------------------------------------
292 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
293 ; set the palette should return the default palette here, so there's no
294 ; way for this function to fail.
295 ;
296 ; Must set an error code: NO
297 ;
298
299 GETPALETTE:
300         lda     #<PALETTE
301         ldx     #>PALETTE
302         rts
303
304 ; ------------------------------------------------------------------------
305 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
306 ; drivers should return something reasonable here, even drivers that don't
307 ; support palettes, otherwise the caller has no way to determine the colors
308 ; of the (not changeable) palette.
309 ;
310 ; Must set an error code: NO (all drivers must have a default palette)
311 ;
312
313 GETDEFPALETTE:
314         lda     #<DEFPALETTE
315         ldx     #>DEFPALETTE
316         rts
317
318 ; ------------------------------------------------------------------------
319 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
320 ; color. The coordinates passed to this function are never outside the
321 ; visible screen area, so there is no need for clipping inside this function.
322 ;
323 ; Must set an error code: NO
324 ;
325
326 SETPIXEL:
327         ldx     Y1              ; y+2<yres
328         inx
329         inx
330         cpx     yres
331         bcc     @L2
332         ldx     X1              ; x+2<xres
333         inx
334         inx
335         cpx     xres
336         bcc     @L2
337         rts
338 @L2:    lda     X1
339         lsr
340         tay
341         lda     Y1
342         lsr
343         tax
344         clc
345         jsr     setcursor
346         jsr     CALC
347         ldx     COLOR
348         bne     @set2
349         eor     #%00001111
350 @set2:  sta     TEMP3
351
352         lda     (TEMP),y
353         ldx     COLOR
354         bne     @set
355         and     TEMP3
356         .byte   $2c
357 @set:   ora     TEMP3
358         sta     (TEMP),y
359         tax
360         lda     CODE,x
361 @normal:jmp     putchar
362
363 ; ------------------------------------------------------------------------
364 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
365 ; coordinates passed to this function are never outside the visible screen
366 ; area, so there is no need for clipping inside this function.
367
368
369 GETPIXEL:
370         jsr     CALC
371         sta     TEMP3
372         lda     (TEMP),y
373         and     TEMP3
374         beq     @L1
375         lda     #1
376 @L1:    ldx     #0
377         rts
378
379 ; ------------------------------------------------------------------------
380 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
381 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
382 ; Contrary to most other functions, the graphics kernel will sort and clip
383 ; the coordinates before calling the driver, so on entry the following
384 ; conditions are valid:
385 ;       X1 <= X2
386 ;       Y1 <= Y2
387 ;       (X1 >= 0) && (X1 < XRES)
388 ;       (X2 >= 0) && (X2 < XRES)
389 ;       (Y1 >= 0) && (Y1 < YRES)
390 ;       (Y2 >= 0) && (Y2 < YRES)
391 ;
392 ; Must set an error code: NO
393 ;
394
395 BAR:
396         inc     Y2
397 @L1:    lda     X1
398         pha
399 @L2:    jsr     SETPIXEL
400         inc     X1
401         lda     X2
402         cmp     X1
403         bne     @L2
404         pla
405         sta     X1
406         inc     Y1
407         lda     Y2
408         cmp     Y1
409         bne     @L1
410         rts
411
412 ; ------------------------------------------------------------------------
413 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
414 ; direction is passend in X/Y, the text direction is passed in A.
415 ;
416 ; Must set an error code: NO
417 ;
418
419 TEXTSTYLE:
420         rts
421
422 ; ------------------------------------------------------------------------
423 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
424 ; current text style. The text to output is given as a zero terminated
425 ; string with address in ptr3.
426 ;
427 ; Must set an error code: NO
428 ;
429
430 OUTTEXT:
431         lda     ptr1
432         lsr
433         tay
434         lda     ptr2
435         lsr
436         tax
437         clc
438         jsr     setcursor
439         ldy     #0
440 @L1:    lda     (ptr3),y
441         jsr     putchar
442         iny
443         cmp     #$0
444         bne     @L1
445         rts
446
447 ; ------------------------------------------------------------------------
448 ; Calculate all variables to plot the pixel at X1/Y1. If the point is out
449 ; of range, a carry is returned and INRANGE is set to a value !0 zero. If
450 ; the coordinates are valid, INRANGE is zero and the carry clear.
451
452 CALC:   lda     xres
453         sta     TEMP
454         lda     #0
455         sta     TEMP+1
456         ldy     Y1
457 @L1:    lda     TEMP
458         add     xres
459         lsr
460         sta     TEMP
461         lda     TEMP+1
462         adc     #0
463         lsr
464         sta     TEMP+1
465         dey
466         bne     @L1
467         lda     TEMP
468         add     X1
469         lsr
470         sta     TEMP
471         lda     TEMP+1
472         adc     #0
473         lsr
474         sta     TEMP+1
475         lda     TEMP
476         add     #<MEM
477         sta     TEMP
478         lda     TEMP+1
479         adc     #>MEM
480         sta     TEMP+1
481
482         lda     X1
483         and     #%00000001
484         sta     TEMP3
485         lda     Y1
486         asl
487         and     #%00000010
488         ora     TEMP3
489         tax
490         lda     OFFSET,x
491         rts
492
493 ; ------------------------------------------------------------------------
494
495 .include        "../../tgi/tgidrv_line.inc"