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