]> git.sur5r.net Git - cc65/blob - libsrc/lynx/lynx-160-102-16.s
d9899271f028f1316cd3f14dfbc056729fb114fd
[cc65] / libsrc / lynx / lynx-160-102-16.s
1 ;
2 ; Graphics driver for the 160x102x16 mode on the Lynx.
3 ;
4 ; Based on Stephen L. Judds GRLIB code
5 ;
6
7         .include        "zeropage.inc"
8
9         .include        "tgi-kernel.inc"
10         .include        "tgi-mode.inc"
11         .include        "tgi-error.inc"
12
13         .include        "lynx.inc"
14
15         .macpack        generic
16
17
18 ; ------------------------------------------------------------------------
19 ; Header. Includes jump table and constants.
20
21 .segment        "JUMPTABLE"
22
23 ; First part of the header is a structure that has a magic and defines the
24 ; capabilities of the driver
25
26         .byte   $74, $67, $69           ; "tgi"
27         .byte   TGI_API_VERSION         ; TGI API version number
28         .word   160                     ; X resolution
29         .word   102                     ; Y resolution
30         .byte   16                      ; Number of drawing colors
31         .byte   1                       ; Number of screens available
32         .byte   8                       ; System font X size
33         .byte   8                       ; System font Y size
34         .res    4, $00                  ; Reserved for future extensions
35
36 ; Next comes the jump table. Currently all entries must be valid and may point
37 ; to an RTS for test versions (function not implemented). A future version may
38 ; allow for emulation: In this case the vector will be zero. Emulation means
39 ; that the graphics kernel will emulate the function by using lower level
40 ; primitives - for example ploting a line by using calls to SETPIXEL.
41
42         .word   INSTALL
43         .word   UNINSTALL
44         .word   INIT
45         .word   DONE
46         .word   GETERROR
47         .word   CONTROL
48         .word   CLEAR
49         .word   SETVIEWPAGE
50         .word   SETDRAWPAGE
51         .word   SETCOLOR
52         .word   SETPALETTE
53         .word   GETPALETTE
54         .word   GETDEFPALETTE
55         .word   SETPIXEL
56         .word   GETPIXEL
57         .word   LINE
58         .word   BAR
59         .word   CIRCLE
60         .word   TEXTSTYLE
61         .word   OUTTEXT
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 ROW             := tmp2         ; Bitmap row...
76 COL             := tmp3         ; ...and column, both set by PLOT
77 TEMP            := tmp4
78 TEMP2           := sreg
79 POINT           := regsave
80 INRANGE         := regsave+2    ; PLOT variable, $00 = coordinates in range
81
82 CHUNK           := X2           ; Used in the line routine
83 OLDCHUNK        := X2+1         ; Dito
84
85 ; Absolute variables used in the code
86
87 .bss
88
89 ERROR:          .res    1       ; Error code
90
91 DRAWINDEX:      .res    1       ; Pen to use for drawing
92 VIEWPAGEL:      .res    1
93 VIEWPAGEH:      .res    1
94
95 ; INIT/DONE
96 OLDD018:        .res    1       ; Old register value
97
98 ; Line routine stuff
99 DX:             .res    2
100 DY:             .res    2
101
102 ; Circle routine stuff, overlaid by BAR variables
103 X1SAVE:
104 CURX:           .res    1
105 CURY:           .res    1
106 Y1SAVE:
107 BROW:           .res    1       ; Bottom row
108 TROW:           .res    1       ; Top row
109 X2SAVE:
110 LCOL:           .res    1       ; Left column
111 RCOL:           .res    1       ; Right column
112 Y2SAVE:
113 CHUNK1:         .res    1
114 OLDCH1:         .res    1
115 CHUNK2:         .res    1
116 OLDCH2:         .res    1
117
118 ; Text output stuff
119 TEXTMAGX:       .res    1
120 TEXTMAGY:       .res    1
121 TEXTDIR:        .res    1
122
123 ; Constants and tables
124
125 .rodata
126
127 DEFPALETTE:     .byte   >$000
128                 .byte   >$007
129                 .byte   >$070
130                 .byte   >$700
131                 .byte   >$077
132                 .byte   >$770
133                 .byte   >$707
134                 .byte   >$777
135                 .byte   >$333
136                 .byte   >$00F
137                 .byte   >$0F0
138                 .byte   >$F00
139                 .byte   >$0FF
140                 .byte   >$FF0
141                 .byte   >$F0F
142                 .byte   >$FFF
143                 .byte   <$000
144                 .byte   <$007
145                 .byte   <$070
146                 .byte   <$700
147                 .byte   <$077
148                 .byte   <$770
149                 .byte   <$707
150                 .byte   <$777
151                 .byte   <$333
152                 .byte   <$00F
153                 .byte   <$0F0
154                 .byte   <$F00
155                 .byte   <$0FF
156                 .byte   <$FF0
157                 .byte   <$F0F
158                 .byte   <$FFF
159
160 PALETTESIZE     = * - DEFPALETTE
161
162 BITTAB:         .byte   $80,$40,$20,$10,$08,$04,$02,$01
163 BITCHUNK:       .byte   $FF,$7F,$3F,$1F,$0F,$07,$03,$01
164
165 VBASE           = $E000         ; Video memory base address
166 CBASE           = $D000         ; Color memory base address
167
168
169 .code
170
171 ; ------------------------------------------------------------------------
172 ; INSTALL routine. Is called after the driver is loaded into memory. May
173 ; initialize anything that has to be done just once. Is probably empty
174 ; most of the time.
175 ;
176 ; Must set an error code: NO
177 ;
178
179 INSTALL:
180         rts
181
182
183 ; ------------------------------------------------------------------------
184 ; UNINSTALL routine. Is called before the driver is removed from memory. May
185 ; clean up anything done by INSTALL but is probably empty most of the time.
186 ;
187 ; Must set an error code: NO
188 ;
189
190 UNINSTALL:
191         rts
192
193
194 ; ------------------------------------------------------------------------
195 ; INIT: Changes an already installed device from text mode to graphics
196 ; mode.
197 ; Note that INIT/DONE may be called multiple times while the driver
198 ; is loaded, while INSTALL is only called once, so any code that is needed
199 ; to initializes variables and so on must go here. Setting palette and
200 ; clearing the screen is not needed because this is called by the graphics
201 ; kernel later.
202 ; The graphics kernel will never call INIT when a graphics mode is already
203 ; active, so there is no need to protect against that.
204 ;
205 ; Must set an error code: YES
206 ;
207
208 INIT:
209 ; Done, reset the error code
210
211         lda     #TGI_ERR_OK
212         sta     ERROR
213         rts
214
215 ; ------------------------------------------------------------------------
216 ; DONE: Will be called to switch the graphics device back into text mode.
217 ; The graphics kernel will never call DONE when no graphics mode is active,
218 ; so there is no need to protect against that.
219 ;
220 ; Must set an error code: NO
221 ;
222
223 DONE:
224         rts
225
226 ; ------------------------------------------------------------------------
227 ; GETERROR: Return the error code in A and clear it.
228
229 GETERROR:
230         ldx     #TGI_ERR_OK
231         lda     ERROR
232         stx     ERROR
233         rts
234
235 ; ------------------------------------------------------------------------
236 ; CONTROL: Platform/driver specific entry point.
237 ;
238 ; Must set an error code: YES
239 ;
240
241 CONTROL:
242         lda     #TGI_ERR_INV_FUNC
243         sta     ERROR
244         rts
245
246 ; ------------------------------------------------------------------------
247 ; CLEAR: Clears the screen.
248 ;
249 ; Must set an error code: NO
250 ;
251
252 .rodata
253 pixel_bitmap:
254         .byte   3,%10000100,%00000000, $0       ; A pixel bitmap
255 cls_sprite:
256         .byte   %00000001                       ; A pixel sprite
257         .byte   %00010000
258         .byte   %00100000
259         .addr   0,pixel_bitmap
260         .word   0
261         .word   0
262         .word   $a000                           ; 160
263         .word   $6600                           ; 102
264         .byte   $00
265
266 .code
267 CLEAR:  lda     #<cls_sprite
268         ldx     #>cls_sprite
269 draw_sprite:
270         sta     $fc10
271         stx     $fc11
272         lda     #1
273         sta     $fc91
274         stz     $fd90
275 @L3:    stz     CPUSLEEP
276         lda     $fc92
277         lsr
278         bcs     @L3
279         stz     $fd90
280         rts
281
282 ; ------------------------------------------------------------------------
283 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
284 ; The page number is already checked to be valid by the graphics kernel.
285 ;
286 ; Must set an error code: NO (will only be called if page ok)
287 ;
288
289 SETVIEWPAGE:
290         beq     @L1
291         lda     #<$fe00-8160-8160
292         ldx     #>$fe00-8160-8160
293         bra     @L2
294 @L1:    lda     #<$fe00-8160
295         ldx     #>$fe00-8160
296 @L2:    sta     DISPADRL            ; $FD94
297         sta     VIEWPAGEL
298         stx     DISPADRH            ; $FD95
299         sta     VIEWPAGEH
300         rts
301
302 ; ------------------------------------------------------------------------
303 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
304 ; The page number is already checked to be valid by the graphics kernel.
305 ;
306 ; Must set an error code: NO (will only be called if page ok)
307 ;
308
309 SETDRAWPAGE:
310         beq     @L1
311         lda     #<$fe00-8160-8160
312         ldx     #>$fe00-8160-8160
313         bra     @L2
314 @L1:    lda     #<$fe00-8160
315         ldx     #>$fe00-8160
316 @L2:    sta     VIDBASL            ; $FD94
317         stx     VIDBASH            ; $FD95
318         rts
319
320 ; ------------------------------------------------------------------------
321 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
322 ; to be in a valid range (0..maxcolor-1).
323 ;
324 ; Must set an error code: NO (will only be called if color ok)
325 ;
326
327 SETCOLOR:
328         sta     DRAWINDEX
329         rts
330
331 ; ------------------------------------------------------------------------
332 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
333 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
334 ; are not supported
335 ;
336 ; Must set an error code: YES
337 ;
338
339 SETPALETTE:
340         ldy     #31
341 @L1:    lda     (ptr1),y
342         sta     GCOLMAP,y   ; $FDA0
343         dey
344         bpl     @L1
345
346 ; Done, reset the error code
347
348         lda     #TGI_ERR_OK
349         sta     ERROR
350         rts
351
352 ; ------------------------------------------------------------------------
353 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
354 ; set the palette should return the default palette here, so there's no
355 ; way for this function to fail.
356 ;
357 ; Must set an error code: NO
358 ;
359
360 GETPALETTE:
361         lda     #<GCOLMAP       ; $FDA0
362         ldx     #>GCOLMAP
363         rts
364
365 ; ------------------------------------------------------------------------
366 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
367 ; drivers should return something reasonable here, even drivers that don't
368 ; support palettes, otherwise the caller has no way to determine the colors
369 ; of the (not changeable) palette.
370 ;
371 ; Must set an error code: NO (all drivers must have a default palette)
372 ;
373
374 GETDEFPALETTE:
375         lda     #<DEFPALETTE
376         ldx     #>DEFPALETTE
377         rts
378
379 ; ------------------------------------------------------------------------
380 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
381 ; color. The coordinates passed to this function are never outside the
382 ; visible screen area, so there is no need for clipping inside this function.
383 ;
384 ; Must set an error code: NO
385 ;
386                 
387 .data
388 pixel_sprite:
389         .byte   %00000001                       ; A pixel sprite
390         .byte   %00010000
391         .byte   %00100000
392         .addr   0,pixel_bitmap
393 pix_x:  .word   0
394 pix_y:  .word   0
395         .word   $0100
396         .word   $0100
397 pix_c:  .byte   $00
398        
399 .code
400 SETPIXEL:
401         lda     X1
402         sta     pix_x
403         lda     Y1
404         sta     pix_y
405         lda     DRAWINDEX
406         sta     pix_c
407         lda     #<pixel_sprite
408         ldx     #>pixel_sprite
409         jmp     draw_sprite
410
411 ; ------------------------------------------------------------------------
412 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
413 ; coordinates passed to this function are never outside the visible screen
414 ; area, so there is no need for clipping inside this function.
415
416
417 GETPIXEL:
418         lda     Y1
419         sta     MATHD   ; Hardware multiply
420         stz     MATHC
421         lda     #80
422         sta     MATHB
423         stz     MATHA
424         lda     X1
425         lsr     A
426         php
427         tay
428
429         clc
430         lda     VIEWPAGEL
431         adc     MATHH
432         sta     ptr1
433         lda     VIEWPAGEH
434         adc     MATHG
435         sta     ptr1+1
436
437         ldx     #0
438         lda     (ptr1),y
439         plp
440         bcc     @L1
441         and     #$f
442         rts
443
444 @L1:    lsr     A
445         lsr     A
446         lsr     A
447         lsr     A
448         rts
449
450 ; ------------------------------------------------------------------------
451 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
452 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
453 ;
454 ; To deal with off-screen coordinates, the current row
455 ; and column (40x25) is kept track of.  These are set
456 ; negative when the point is off the screen, and made
457 ; positive when the point is within the visible screen.
458 ;
459 ; X1,X2 etc. are set up above (x2=LINNUM in particular)
460 ; Format is LINE x2,y2,x1,y1
461 ;
462 ; Must set an error code: NO
463 ;
464
465 LINE:
466         rts
467
468 ; ------------------------------------------------------------------------
469 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
470 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
471 ; Contrary to most other functions, the graphics kernel will sort and clip
472 ; the coordinates before calling the driver, so on entry the following
473 ; conditions are valid:
474 ;       X1 <= X2
475 ;       Y1 <= Y2
476 ;       (X1 >= 0) && (X1 < XRES)
477 ;       (X2 >= 0) && (X2 < XRES)
478 ;       (Y1 >= 0) && (Y1 < YRES)
479 ;       (Y2 >= 0) && (Y2 < YRES)
480 ;
481 ; Must set an error code: NO
482 ;
483
484 .data
485 bar_sprite:
486         .byte   %00000001                       ; A pixel sprite
487         .byte   %00010000
488         .byte   %00100000
489         .addr   0,pixel_bitmap
490 bar_x:  .word   0
491 bar_y:  .word   0
492 bar_sx: .word   $0100
493 bar_sy: .word   $0100
494 bar_c:  .byte   $00
495
496 .code
497 BAR:    lda     X1
498         sta     bar_x
499         lda     Y1
500         sta     bar_y
501         lda     X2
502         sec
503         sbc     X1
504         sta     bar_sx+1
505         lda     Y2
506         sec
507         sbc     Y1
508         sta     bar_sy+1
509         lda     DRAWINDEX
510         sta     bar_c
511         lda     #<bar_sprite
512         ldx     #>bar_sprite
513         jmp     draw_sprite
514
515 ; ------------------------------------------------------------------------
516 ; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
517 ; radius in tmp1 and the current drawing color.
518 ;
519 ; Must set an error code: NO
520 ;
521
522 CIRCLE:
523         rts
524
525 ; ------------------------------------------------------------------------
526 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
527 ; direction is passend in X/Y, the text direction is passed in A.
528 ;
529 ; Must set an error code: NO
530 ;
531
532 TEXTSTYLE:
533         stx     TEXTMAGX
534         sty     TEXTMAGY
535         sta     TEXTDIR
536         rts
537
538
539 ; ------------------------------------------------------------------------
540 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
541 ; current text style. The text to output is given as a zero terminated
542 ; string with address in ptr3.
543 ;
544 ; Must set an error code: NO
545 ;
546
547 OUTTEXT:
548         rts
549