]> git.sur5r.net Git - cc65/blob - libsrc/lynx/lynx-160-102-16.s
add posixdirent.s by Stefan Haubenthal
[cc65] / libsrc / lynx / lynx-160-102-16.s
1 ;
2 ; Graphics driver for the 160x102x16 mode on the Lynx.
3 ;
4 ; All the drawing functions are simply done by sprites as the sprite
5 ; engine is the only way to do fast graphics on a Lynx.
6 ;
7 ; So the code is not really based on any algorithms done by somebody.
8 ; I have looked at other routines in the cc65 libs to see what kind of
9 ; entry points we need. And I have looked at the old cc65 libs by
10 ; Bastian Schick to see how things worked in the past.
11 ;
12 ; This code is written by Karri Kaksonen, 2004 for the cc65 compiler.
13 ;
14
15         .include        "zeropage.inc"
16         .include        "extzp.inc"
17
18         .include        "tgi-kernel.inc"
19         .include        "tgi-mode.inc"
20         .include        "tgi-error.inc"
21
22         .include        "lynx.inc"
23
24         .macpack        generic
25
26 ; ------------------------------------------------------------------------
27 ; Header. Includes jump table and constants.
28
29 .segment        "JUMPTABLE"
30
31 ; First part of the header is a structure that has a magic and defines the
32 ; capabilities of the driver
33
34         .byte   $74, $67, $69           ; "tgi"
35         .byte   TGI_API_VERSION         ; TGI API version number
36         .word   160                     ; X resolution
37         .word   102                     ; Y resolution
38         .byte   16                      ; Number of drawing colors
39         .byte   2                       ; Number of screens available
40         .byte   8                       ; System font X size
41         .byte   8                       ; System font Y size
42         .res    4, $00                  ; Reserved for future extensions
43
44 ; Next comes the jump table. Currently all entries must be valid and may point
45 ; to an RTS for test versions (function not implemented). A future version may
46 ; allow for emulation: In this case the vector will be zero. Emulation means
47 ; that the graphics kernel will emulate the function by using lower level
48 ; primitives - for example ploting a line by using calls to SETPIXEL.
49
50         .addr   INSTALL
51         .addr   UNINSTALL
52         .addr   INIT
53         .addr   DONE
54         .addr   GETERROR
55         .addr   CONTROL
56         .addr   CLEAR
57         .addr   SETVIEWPAGE
58         .addr   SETDRAWPAGE
59         .addr   SETCOLOR
60         .addr   SETPALETTE
61         .addr   GETPALETTE
62         .addr   GETDEFPALETTE
63         .addr   SETPIXEL
64         .addr   GETPIXEL
65         .addr   LINE
66         .addr   BAR
67         .addr   CIRCLE
68         .addr   TEXTSTYLE
69         .addr   OUTTEXT
70         .addr   IRQ
71
72
73 ; ------------------------------------------------------------------------
74 ; Data.
75
76 ; Variables mapped to the zero page segment variables. Some of these are
77 ; used for passing parameters to the driver.
78
79 X1              := ptr1
80 Y1              := ptr2
81 X2              := ptr3
82 Y2              := ptr4
83
84 STRPTR          := ptr3
85 FONTOFF         := ptr4
86 STROFF          := tmp3
87 STRLEN          := tmp4
88
89 ; Absolute variables used in the code
90
91 .bss
92
93 ERROR:          .res    1       ; Error code
94
95 DRAWINDEX:      .res    1       ; Pen to use for drawing
96 VIEWPAGEL:      .res    1
97 VIEWPAGEH:      .res    1
98 DRAWPAGEL:      .res    1
99 DRAWPAGEH:      .res    1
100
101 ; Text output stuff
102 TEXTMAGX:       .res    1
103 TEXTMAGY:       .res    1
104 TEXTDIR:        .res    1
105 BGINDEX:        .res    1       ; Pen to use for text background
106
107 ; Double buffer IRQ stuff
108 DRAWPAGE:       .res    1
109 SWAPREQUEST:    .res    1
110
111 text_bitmap:    .res    8*(1+20+1)+1
112 ; 8 rows with (one offset-byte plus 20 character bytes plus one fill-byte) plus one 0-offset-byte
113
114 ; Constants and tables
115
116 .rodata
117
118 DEFPALETTE:     .byte   >$000
119                 .byte   >$007
120                 .byte   >$070
121                 .byte   >$700
122                 .byte   >$077
123                 .byte   >$770
124                 .byte   >$707
125                 .byte   >$777
126                 .byte   >$333
127                 .byte   >$00F
128                 .byte   >$0F0
129                 .byte   >$F00
130                 .byte   >$0FF
131                 .byte   >$FF0
132                 .byte   >$F0F
133                 .byte   >$FFF
134                 .byte   <$000
135                 .byte   <$007
136                 .byte   <$070
137                 .byte   <$700
138                 .byte   <$077
139                 .byte   <$770
140                 .byte   <$707
141                 .byte   <$777
142                 .byte   <$333
143                 .byte   <$00F
144                 .byte   <$0F0
145                 .byte   <$F00
146                 .byte   <$0FF
147                 .byte   <$FF0
148                 .byte   <$F0F
149                 .byte   <$FFF
150
151 PALETTESIZE     = * - DEFPALETTE
152
153 .code
154
155 ; ------------------------------------------------------------------------
156 ; INSTALL routine. Is called after the driver is loaded into memory. May
157 ; initialize anything that has to be done just once. Is probably empty
158 ; most of the time.
159 ;
160 ; Must set an error code: NO
161 ;
162
163 INSTALL:
164         lda     #1
165         sta     TEXTMAGX
166         sta     TEXTMAGY
167         stz     BGINDEX
168         stz     DRAWPAGE
169         stz     SWAPREQUEST
170         rts
171
172
173 ; ------------------------------------------------------------------------
174 ; UNINSTALL routine. Is called before the driver is removed from memory. May
175 ; clean up anything done by INSTALL but is probably empty most of the time.
176 ;
177 ; Must set an error code: NO
178 ;
179
180 UNINSTALL:
181         rts
182
183
184 ; ------------------------------------------------------------------------
185 ; INIT: Changes an already installed device from text mode to graphics
186 ; mode.
187 ; Note that INIT/DONE may be called multiple times while the driver
188 ; is loaded, while INSTALL is only called once, so any code that is needed
189 ; to initializes variables and so on must go here. Setting palette and
190 ; clearing the screen is not needed because this is called by the graphics
191 ; kernel later.
192 ; The graphics kernel will never call INIT when a graphics mode is already
193 ; active, so there is no need to protect against that.
194 ;
195 ; Must set an error code: YES
196 ;
197
198 INIT:
199 ; Enable interrupts for VBL
200         lda     #$80
201         tsb     VTIMCTLA
202 ; Set up collision buffer to $A058
203         lda     #$58
204         sta     COLLBASL
205         lda     #$A0
206         sta     COLLBASH
207 ; Put collision index before sprite data
208         lda     #$FE
209         sta     COLLOFFL
210         lda     #$FF
211         sta     COLLOFFH
212 ; Done, reset the error code
213         lda     #TGI_ERR_OK
214         sta     ERROR
215         rts
216
217 ; ------------------------------------------------------------------------
218 ; DONE: Will be called to switch the graphics device back into text mode.
219 ; The graphics kernel will never call DONE when no graphics mode is active,
220 ; so there is no need to protect against that.
221 ;
222 ; Must set an error code: NO
223 ;
224
225 DONE:
226         rts
227
228 ; ------------------------------------------------------------------------
229 ; GETERROR: Return the error code in A and clear it.
230
231 GETERROR:
232         ldx     #TGI_ERR_OK
233         lda     ERROR
234         stx     ERROR
235         rts
236
237 ; ------------------------------------------------------------------------
238 ; CONTROL: Platform/driver specific entry point.
239 ;
240 ; Must set an error code: YES
241 ;
242 ; The TGI lacks a way to draw sprites. As that functionality is vital to
243 ; Lynx games we borrow this CONTROL function to implement the still
244 ; missing tgi_draw_sprite funtion. To use this in your C-program
245 ; do a #define tgi_draw_sprite(spr) tgi_ioctl(0, spr)
246 ;
247 ; To do a flip-screen call tgi_ioctl(1, 0)
248 ;
249 ; To set the background index for text outputs call tgi_ioctl(2, bgindex)
250 ;
251 ; To set the frame rate for the display hardware call tgi_ioctl(3, rate)
252 ;
253 ; To check if the drawing engine is busy with the previous swap you can
254 ; call tgi_ioctl(4, 0). It returns 0 if idle and 1 if busy
255 ;
256 ; To update displays you can call tgi_ioctl(4, 1) it will wait for the
257 ; next VBL interrupt and swap draw and view buffers.
258 ;
259 ; Activate or deactivate collision detection by calling tgi_ioctl(5, 0/1).
260
261 CONTROL:
262         pha                     ; Almost all control routines succeed
263         lda     #TGI_ERR_OK
264         sta     ERROR
265         pla
266
267         cmp     #5
268         bne     ControlSwap
269         lda     ptr1
270         bne     @L0
271         lda     __sprsys
272         ora     #$20
273         bra     @L1
274 @L0:    lda     __sprsys
275         and     #$df
276 @L1:    sta     __sprsys
277         sta     SPRSYS
278         rts
279
280 ControlSwap:
281         cmp     #4
282         bne     ControlFramerate
283
284         lda     ptr1            ; Swap request
285         bne     @L0
286         lda     SWAPREQUEST
287         rts
288 @L0:    sta     SWAPREQUEST
289         rts
290
291 ControlFramerate:
292         cmp     #3
293         bne     ControlTextBG
294
295         lda     ptr1
296         cmp     #75             ; Set framerate
297         beq     rate75
298         cmp     #60
299         beq     rate60
300         cmp     #50
301         beq     rate50
302         lda     #TGI_ERR_INV_ARG
303         sta     ERROR
304         rts
305 rate50: lda     #$bd            ; 50 Hz
306         ldx     #$31
307         bra     setRate
308 rate60: lda     #$9e            ; 60 Hz
309         ldx     #$29
310         bra     setRate
311 rate75: lda     #$7e            ; 75 Hz
312         ldx     #$20
313 setRate:
314         sta     HTIMBKUP
315         stx     PBKUP
316         rts
317
318 ControlTextBG:
319         cmp     #2
320         bne     ControlFlipScreen
321
322         lda     ptr1            ; Set text background color
323         sta     BGINDEX
324         rts
325
326 ControlFlipScreen:
327         cmp     #1
328         bne     ControlDrawSprite
329
330         lda     __sprsys        ; Flip screen
331         eor     #8
332         sta     __sprsys
333         sta     SPRSYS
334         lda     __viddma
335         eor     #2
336         sta     __viddma
337         sta     DISPCTL
338         ldy     VIEWPAGEL
339         ldx     VIEWPAGEH
340         and     #2
341         beq     NotFlipped
342         clc
343         tya
344         adc     #<8159
345         tay
346         txa
347         adc     #>8159
348         tax
349 NotFlipped:
350         sty     DISPADRL
351         stx     DISPADRH
352         rts
353
354 ControlDrawSprite:
355         lda     ptr1            ; Get the sprite address
356         ldx     ptr1+1
357
358 draw_sprite:                    ; Draw it in render buffer
359         sta     SCBNEXTL
360         stx     SCBNEXTH
361         lda     DRAWPAGEL
362         ldx     DRAWPAGEH
363         sta     VIDBASL
364         stx     VIDBASH
365         lda     #1
366         sta     SPRGO
367         stz     SDONEACK
368 @L0:    stz     CPUSLEEP
369         lda     SPRSYS
370         lsr
371         bcs     @L0
372         stz     SDONEACK
373         lda     #TGI_ERR_OK
374         sta     ERROR
375         rts
376
377 ; ------------------------------------------------------------------------
378 ; CLEAR: Clears the screen.
379 ;
380 ; Must set an error code: NO
381 ;
382
383 .rodata
384 pixel_bitmap:
385         .byte   3,%10000100,%00000000, $0       ; A pixel bitmap
386 cls_sprite:
387         .byte   %00000001                       ; A pixel sprite
388         .byte   %00010000
389         .byte   %00100000
390         .addr   0,pixel_bitmap
391         .word   0
392         .word   0
393         .word   $a000                           ; 160
394         .word   $6600                           ; 102
395         .byte   $00
396
397 .code
398 CLEAR:  lda     #<cls_sprite
399         ldx     #>cls_sprite
400         bra     draw_sprite
401
402 ; ------------------------------------------------------------------------
403 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
404 ; The page number is already checked to be valid by the graphics kernel.
405 ;
406 ; Must set an error code: NO (will only be called if page ok)
407 ;
408 ; It is a good idea to call this function during the vertical blanking
409 ; period. If you call it in the middle of the screen update then half of
410 ; the drawn frame will be from the old buffer and the other half is
411 ; from the new buffer. This is usually noticed by the user.
412
413 SETVIEWPAGE:
414         cmp     #1
415         beq     @L1             ; page == maxpages-1
416         ldy     #<$e018         ; page 0
417         ldx     #>$e018
418         bra     @L2
419 @L1:
420         ldy     #<$c038         ; page 1
421         ldx     #>$c038
422 @L2:
423         sty     VIEWPAGEL       ; Save viewpage for getpixel
424         stx     VIEWPAGEH
425
426         lda     __viddma        ; Process flipped displays
427         and     #2
428         beq     @L3
429         clc
430         tya
431         adc     #<8159
432         tay
433         txa
434         adc     #>8159
435         tax
436 @L3:
437         sty     DISPADRL        ; $FD94
438         stx     DISPADRH        ; $FD95
439         rts
440
441 ; ------------------------------------------------------------------------
442 ; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
443 ; The page number is already checked to be valid by the graphics kernel.
444 ;
445 ; Must set an error code: NO (will only be called if page ok)
446 ;
447
448 SETDRAWPAGE:
449         cmp     #1
450         beq     @L1                 ; page == maxpages-1
451         lda     #<$e018             ; page 0
452         ldx     #>$e018
453         bra     @L2
454 @L1:
455         lda     #<$c038             ; page 1
456         ldx     #>$c038
457 @L2:
458         sta     DRAWPAGEL
459         stx     DRAWPAGEH
460         rts
461
462 ; ------------------------------------------------------------------------
463 ; IRQ: VBL interrupt handler
464 ;
465
466 IRQ:
467         lda     INTSET          ; Poll all pending interrupts
468         and     #VBL_INTERRUPT
469         beq     IRQEND          ; Exit if not a VBL interrupt
470
471         lda     SWAPREQUEST
472         beq     @L0
473         lda     DRAWPAGE
474         jsr     SETVIEWPAGE
475         lda     DRAWPAGE
476         eor     #1
477         sta     DRAWPAGE
478         jsr     SETDRAWPAGE
479         stz     SWAPREQUEST
480 @L0:
481 IRQEND:
482         clc
483         rts
484
485 ; ------------------------------------------------------------------------
486 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
487 ; to be in a valid range (0..maxcolor-1).
488 ;
489 ; Must set an error code: NO (will only be called if color ok)
490 ;
491
492 SETCOLOR:
493         sta     DRAWINDEX
494         rts
495
496 ; ------------------------------------------------------------------------
497 ; SETPALETTE: Set the palette (not available with all drivers/hardware).
498 ; A pointer to the palette is passed in ptr1. Must set an error if palettes
499 ; are not supported
500 ;
501 ; Must set an error code: YES
502 ;
503
504 SETPALETTE:
505         ldy     #31
506 @L1:    lda     (ptr1),y
507         sta     GCOLMAP,y   ; $FDA0
508         dey
509         bpl     @L1
510
511 ; Done, reset the error code
512
513         lda     #TGI_ERR_OK
514         sta     ERROR
515         rts
516
517 ; ------------------------------------------------------------------------
518 ; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
519 ; set the palette should return the default palette here, so there's no
520 ; way for this function to fail.
521 ;
522 ; Must set an error code: NO
523 ;
524
525 GETPALETTE:
526         lda     #<GCOLMAP       ; $FDA0
527         ldx     #>GCOLMAP
528         rts
529
530 ; ------------------------------------------------------------------------
531 ; GETDEFPALETTE: Return the default palette for the driver in A/X. All
532 ; drivers should return something reasonable here, even drivers that don't
533 ; support palettes, otherwise the caller has no way to determine the colors
534 ; of the (not changeable) palette.
535 ;
536 ; Must set an error code: NO (all drivers must have a default palette)
537 ;
538
539 GETDEFPALETTE:
540         lda     #<DEFPALETTE
541         ldx     #>DEFPALETTE
542         rts
543
544 ; ------------------------------------------------------------------------
545 ; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
546 ; color. The coordinates passed to this function are never outside the
547 ; visible screen area, so there is no need for clipping inside this function.
548 ;
549 ; Must set an error code: NO
550 ;
551
552 .data
553 pixel_sprite:
554         .byte   %00000001                       ; A pixel sprite
555         .byte   %00010000
556         .byte   %00100000
557         .addr   0,pixel_bitmap
558 pix_x:  .word   0
559 pix_y:  .word   0
560         .word   $100
561         .word   $100
562 pix_c:  .byte   $00
563
564 .code
565 SETPIXEL:
566         lda     X1
567         sta     pix_x
568         lda     Y1
569         sta     pix_y
570         lda     DRAWINDEX
571         sta     pix_c
572         lda     #<pixel_sprite
573         ldx     #>pixel_sprite
574         jmp     draw_sprite
575
576 ; ------------------------------------------------------------------------
577 ; GETPIXEL: Read the color value of a pixel and return it in A/X. The
578 ; coordinates passed to this function are never outside the visible screen
579 ; area, so there is no need for clipping inside this function.
580
581
582 GETPIXEL:
583         lda     Y1
584         sta     MATHD   ; Hardware multiply
585         stz     MATHC
586         lda     #80
587         sta     MATHB
588         stz     MATHA
589         lda     X1
590         lsr     A
591         php
592         tay
593
594         clc
595         lda     VIEWPAGEL
596         adc     MATHH
597         sta     ptr1
598         lda     VIEWPAGEH
599         adc     MATHG
600         sta     ptr1+1
601
602         ldx     #0
603         lda     #15
604         sta     MAPCTL
605         lda     (ptr1),y
606         tay
607         lda     #$0c
608         sta     MAPCTL
609         tya
610         plp
611         bcc     @L1
612         and     #$f
613         rts
614
615 @L1:    lsr     A
616         lsr     A
617         lsr     A
618         lsr     A
619         rts
620
621 ; ------------------------------------------------------------------------
622 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
623 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
624 ;
625 ; Must set an error code: NO
626 ;
627
628 .data
629 line_sprite:
630         .byte   0               ; Will be replaced by the code
631         .byte   %00110000
632         .byte   %00100000
633         .word   0,pixel_bitmap
634 line_x:
635         .word    0
636 line_y:
637         .word    0
638 line_sx:
639         .word    $100
640 line_sy:
641         .word    $100
642         .word    0
643 line_tilt:
644         .word    0
645 line_c:
646         .byte    $e
647
648 .code
649 LINE:
650         lda     DRAWINDEX
651         sta     line_c
652         stz     line_sx
653         stz     line_sy
654
655         sec
656         lda     X2
657         sbc     X1
658         lda     X2+1
659         sbc     X1+1
660         bpl     @L1
661         lda     X1
662         ldx     X2
663         sta     X2
664         stx     X1
665         lda     X1+1
666         ldx     X2+1
667         sta     X2+1
668         stx     X1+1
669         lda     Y1
670         ldx     Y2
671         sta     Y2
672         stx     Y1
673         lda     Y1+1
674         ldx     Y2+1
675         sta     Y2+1
676         stx     Y1+1
677 @L1:
678         lda     #%00000000      ; Not flipped
679         sta     line_sprite
680
681         sec
682         lda     Y2
683         sbc     Y1
684         sta     Y2
685         lda     Y2+1
686         sbc     Y1+1
687         sta     Y2+1
688         bpl     @L2
689         sec
690         lda     #0
691         sbc     Y2
692         sta     Y2
693         lda     #0
694         sbc     Y2+1
695         sta     Y2+1
696         lda     #%00010000      ; Vertical flip
697         sta     line_sprite
698 @L2:
699         lda     X1
700         sta     line_x
701         lda     X1+1
702         sta     line_x+1
703         lda     Y1
704         sta     line_y
705         lda     Y1+1
706         sta     line_y+1
707
708         lda     Y2
709         ina
710         sta     line_sy+1
711         sta     MATHP           ; hardware divide
712         stz     MATHN
713
714         stz     MATHH
715         stz     MATHG
716         sec
717         lda     X2
718         sbc     X1
719         ina
720         sta     MATHF
721         stz     MATHE
722 @L3:
723         lda     SPRSYS
724         bmi     @L3             ; wait for math done (bit 7 of sprsys)
725         lda     MATHC
726         sta     line_tilt
727         lda     MATHB
728         sta     line_tilt+1
729         bne     @L4
730         lda     #1
731         sta     line_sx+1
732         bra     @L6
733 @L4:
734         bit     line_tilt
735         bpl     @L5
736         ina
737 @L5:
738         sta     line_sx+1
739 @L6:
740         lda     #<line_sprite
741         ldx     #>line_sprite
742         jmp     draw_sprite
743
744 ; ------------------------------------------------------------------------
745 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
746 ; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
747 ; Contrary to most other functions, the graphics kernel will sort and clip
748 ; the coordinates before calling the driver, so on entry the following
749 ; conditions are valid:
750 ;       X1 <= X2
751 ;       Y1 <= Y2
752 ;       (X1 >= 0) && (X1 < XRES)
753 ;       (X2 >= 0) && (X2 < XRES)
754 ;       (Y1 >= 0) && (Y1 < YRES)
755 ;       (Y2 >= 0) && (Y2 < YRES)
756 ;
757 ; Must set an error code: NO
758 ;
759
760 .data
761 bar_sprite:
762         .byte   %00000001                       ; A pixel sprite
763         .byte   %00010000
764         .byte   %00100000
765         .addr   0,pixel_bitmap
766 bar_x:  .word   0
767 bar_y:  .word   0
768 bar_sx: .word   $0100
769 bar_sy: .word   $0100
770 bar_c:  .byte   $00
771
772 .code
773 BAR:    lda     X1
774         sta     bar_x
775         lda     Y1
776         sta     bar_y
777         lda     X2
778         sec
779         sbc     X1
780         ina
781         sta     bar_sx+1
782         lda     Y2
783         sec
784         sbc     Y1
785         ina
786         sta     bar_sy+1
787         lda     DRAWINDEX
788         sta     bar_c
789         lda     #<bar_sprite
790         ldx     #>bar_sprite
791         jmp     draw_sprite
792
793 ; ------------------------------------------------------------------------
794 ; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
795 ; radius in tmp1 and the current drawing color.
796 ;
797 ; Must set an error code: NO
798 ;
799 ; There is no sensible way of drawing a circle on a Lynx. As I would
800 ; have to use line elements to do the circle I rather do it in C than
801 ; create it here in the driver.
802
803 ; To do a circle please add this to your C program
804
805 ;int sintbl[9] = {
806 ;       0,     //  0    degrees
807 ;       3196,  // 11.25 degrees
808 ;       6270,  // 22.5  degrees
809 ;       9102,  // 33.75 degrees
810 ;       11585, // 45    degrees
811 ;       13623, // 56.25 degrees
812 ;       15137, // 67.5  degrees
813 ;       16069, // 78.75 degrees
814 ;       16384  // 90    degrees
815 ;};
816
817 ;int sin(char d)
818 ;{
819 ;    char neg;
820 ;    d = d & 31;
821 ;    neg = d > 16;
822 ;    d = d & 15;
823 ;    if (d > 8)
824 ;        d = 16 - d;
825 ;    if (neg)
826 ;       return -sintbl[d];
827 ;    else
828 ;       return sintbl[d];
829 ;}
830
831 ;void tgi_Circle(int x0, int y0, unsigned char r)
832 ;{
833 ;       char i;
834 ;       int x1, y1, x2, y2;
835 ;
836 ;       x1 = ((long)sin(0) * r + 8192) / 16384 + x0;
837 ;       y1 = ((long)sin(8) * r + 8192) / 16384 + y0;
838 ;       for (i = 1; i <= 32; i++) {
839 ;               x2 = ((long)sin(i) * r + 8192) / 16384 + x0;
840 ;               y2 = ((long)sin(i+8) * r + 8192) / 16384 + y0;
841 ;               tgi_line(x1, y1, x2, y2);
842 ;               x1 = x2;
843 ;               y1 = y2;
844 ;       }
845 ;}
846
847 ;#define tgi_circle tgi_Circle
848
849 CIRCLE:
850         rts
851
852 ; ------------------------------------------------------------------------
853 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
854 ; direction is passend in X/Y, the text direction is passed in A.
855 ;
856 ; Must set an error code: NO
857 ;
858
859 TEXTSTYLE:
860         stx     TEXTMAGX
861         sty     TEXTMAGY
862         sta     TEXTDIR
863         rts
864
865 ; ------------------------------------------------------------------------
866 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
867 ; current text style. The text to output is given as a zero terminated
868 ; string with address in ptr3.
869 ;
870 ; Must set an error code: NO
871 ;
872
873 OUTTEXT:
874         lda     TEXTMAGX        ; Scale sprite
875         sta     text_sx+1
876         lda     TEXTMAGY
877         sta     text_sy+1
878
879         stz     text_sprite     ; Set normal sprite
880         lda     BGINDEX
881         bne     @L1
882         lda     #4
883         sta     text_sprite     ; Set opaque sprite
884 @L1:
885         lda     DRAWINDEX       ; Set color
886         asl
887         asl
888         asl
889         asl
890         ora     BGINDEX
891         sta     text_c
892
893         lda     X1              ; Set start position
894         sta     text_x
895         lda     X1+1
896         sta     text_x+1
897         lda     Y1
898         sta     text_y
899         lda     Y1+1
900         sta     text_y+1
901
902         ldy     #-1             ; Calculate string length
903 @L2:
904         iny
905         lda     (STRPTR),y
906         bne     @L2
907         cpy     #20
908         bmi     @L3
909         ldy     #20
910 @L3:
911         sty     STRLEN
912         bne     @L4
913         rts                     ; Zero length string
914 @L4:
915         iny                     ; Prepare text_bitmap
916         iny
917         sty     STROFF
918
919         ldy     #8-1            ; 8 pixel lines per character
920         ldx     #0
921         clc
922 @L5:
923         lda     STROFF
924         sta     text_bitmap,x
925         txa
926         adc     STROFF
927         tax
928         lda     #$ff
929         sta     text_bitmap-1,x
930         dey
931         bpl     @L5
932         stz     text_bitmap,x
933
934         stz     tmp2
935         iny
936 @L6:
937         lda     (STRPTR),y
938         sty     tmp1
939
940         sec                     ; (ch-' ') * 8
941         sbc     #32
942         stz     FONTOFF
943         stz     FONTOFF+1
944         asl
945         asl
946         rol     FONTOFF+1
947         asl
948         rol     FONTOFF+1
949         clc                     ; Choose font
950         adc     #<font
951         sta     FONTOFF
952         lda     FONTOFF+1
953         adc     #>font
954         sta     FONTOFF+1
955
956 ; and now copy the 8 bytes of that char
957
958         ldx     tmp2
959         inx
960         stx     tmp2
961
962 ; draw char from top to bottom, reading char-data from offset 8-1 to offset 0
963         ldy     #8-1
964 @L7:
965         lda     (FONTOFF),y         ; *chptr
966         sta     text_bitmap,x    ;textbuf[y*(1+len+1)+1+x]
967
968         txa
969         adc     STROFF
970         tax
971
972         dey
973         bpl     @L7
974
975         ; goto next char
976         ldy     tmp1
977         iny
978         dec     STRLEN
979         bne     @L6
980
981         lda     #<text_sprite
982         ldx     #>text_sprite
983         jmp     draw_sprite
984
985 .data
986 text_sprite:
987         .byte $00,$90,$20
988         .addr 0, text_bitmap
989 text_x:
990         .word 0
991 text_y:
992         .word 0
993 text_sx:
994         .word $100
995 text_sy:
996         .word $100
997 text_c:
998         .byte 0
999
1000 .rodata
1001 ; The Font
1002 ; 96 characters from ASCII 32 to 127
1003 ; 8 pixels wide, 8 pixels high
1004 ; bit value 0 = foreground, bit value 1 = background / transparent
1005 font:
1006 ; VERSAIL
1007         .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF  ;32
1008         .byte $FF, $E7, $FF, $FF, $E7, $E7, $E7, $E7  ;33
1009         .byte $FF, $FF, $FF, $FF, $FF, $99, $99, $99  ;34
1010         .byte $FF, $99, $99, $00, $99, $00, $99, $99  ;35
1011         .byte $FF, $E7, $83, $F9, $C3, $9F, $C1, $E7  ;36
1012         .byte $FF, $B9, $99, $CF, $E7, $F3, $99, $9D  ;37
1013         .byte $FF, $C0, $99, $98, $C7, $C3, $99, $C3  ;38
1014         .byte $FF, $FF, $FF, $FF, $FF, $E7, $F3, $F9  ;39
1015         .byte $FF, $F3, $E7, $CF, $CF, $CF, $E7, $F3  ;40
1016         .byte $FF, $CF, $E7, $F3, $F3, $F3, $E7, $CF  ;41
1017         .byte $FF, $FF, $99, $C3, $00, $C3, $99, $FF  ;42
1018         .byte $FF, $FF, $E7, $E7, $81, $E7, $E7, $FF  ;43
1019         .byte $CF, $E7, $E7, $FF, $FF, $FF, $FF, $FF  ;44
1020         .byte $FF, $FF, $FF, $FF, $81, $FF, $FF, $FF  ;45
1021         .byte $FF, $E7, $E7, $FF, $FF, $FF, $FF, $FF  ;46
1022         .byte $FF, $9F, $CF, $E7, $F3, $F9, $FC, $FF  ;47
1023         .byte $FF, $C3, $99, $99, $89, $91, $99, $C3  ;48
1024         .byte $FF, $81, $E7, $E7, $E7, $C7, $E7, $E7  ;49
1025         .byte $FF, $81, $9F, $CF, $F3, $F9, $99, $C3  ;50
1026         .byte $FF, $C3, $99, $F9, $E3, $F9, $99, $C3  ;51
1027         .byte $FF, $F9, $F9, $80, $99, $E1, $F1, $F9  ;52
1028         .byte $FF, $C3, $99, $F9, $F9, $83, $9F, $81  ;53
1029         .byte $FF, $C3, $99, $99, $83, $9F, $99, $C3  ;54
1030         .byte $FF, $E7, $E7, $E7, $E7, $F3, $99, $81  ;55
1031         .byte $FF, $C3, $99, $99, $C3, $99, $99, $C3  ;56
1032         .byte $FF, $C3, $99, $F9, $C1, $99, $99, $C3  ;57
1033         .byte $FF, $FF, $E7, $FF, $FF, $E7, $FF, $FF  ;58
1034         .byte $CF, $E7, $E7, $FF, $FF, $E7, $FF, $FF  ;59
1035         .byte $FF, $F1, $E7, $CF, $9F, $CF, $E7, $F1  ;60
1036         .byte $FF, $FF, $FF, $81, $FF, $81, $FF, $FF  ;61
1037         .byte $FF, $8F, $E7, $F3, $F9, $F3, $E7, $8F  ;62
1038         .byte $FF, $E7, $FF, $E7, $F3, $F9, $99, $C3  ;63
1039
1040
1041         .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3  ;0
1042         .byte $FF, $99, $99, $99, $81, $99, $C3, $E7  ;1
1043         .byte $FF, $83, $99, $99, $83, $99, $99, $83  ;2
1044         .byte $FF, $C3, $99, $9F, $9F, $9F, $99, $C3  ;3
1045         .byte $FF, $87, $93, $99, $99, $99, $93, $87  ;4
1046         .byte $FF, $81, $9F, $9F, $87, $9F, $9F, $81  ;5
1047         .byte $FF, $9F, $9F, $9F, $87, $9F, $9F, $81  ;6
1048         .byte $FF, $C3, $99, $99, $91, $9F, $99, $C3  ;7
1049         .byte $FF, $99, $99, $99, $81, $99, $99, $99  ;8
1050         .byte $FF, $C3, $E7, $E7, $E7, $E7, $E7, $C3  ;9
1051         .byte $FF, $C7, $93, $F3, $F3, $F3, $F3, $E1  ;10
1052         .byte $FF, $99, $93, $87, $8F, $87, $93, $99  ;11
1053         .byte $FF, $81, $9F, $9F, $9F, $9F, $9F, $9F  ;12
1054         .byte $FF, $9C, $9C, $9C, $94, $80, $88, $9C  ;13
1055         .byte $FF, $99, $99, $91, $81, $81, $89, $99  ;14
1056         .byte $FF, $C3, $99, $99, $99, $99, $99, $C3  ;15
1057         .byte $FF, $9F, $9F, $9F, $83, $99, $99, $83  ;16
1058         .byte $FF, $F1, $C3, $99, $99, $99, $99, $C3  ;17
1059         .byte $FF, $99, $93, $87, $83, $99, $99, $83  ;18
1060         .byte $FF, $C3, $99, $F9, $C3, $9F, $99, $C3  ;19
1061         .byte $FF, $E7, $E7, $E7, $E7, $E7, $E7, $81  ;20
1062         .byte $FF, $C3, $99, $99, $99, $99, $99, $99  ;21
1063         .byte $FF, $E7, $C3, $99, $99, $99, $99, $99  ;22
1064         .byte $FF, $9C, $88, $80, $94, $9C, $9C, $9C  ;23
1065         .byte $FF, $99, $99, $C3, $E7, $C3, $99, $99  ;24
1066         .byte $FF, $E7, $E7, $E7, $C3, $99, $99, $99  ;25
1067         .byte $FF, $81, $9F, $CF, $E7, $F3, $F9, $81  ;26
1068         .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3  ;27
1069         .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3  ;28
1070         .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3  ;29
1071         .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF  ;30
1072         .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF  ;31
1073
1074
1075 ; gemena
1076         .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3  ;224
1077         .byte $FF, $C1, $99, $C1, $F9, $C3, $FF, $FF  ;225
1078         .byte $FF, $83, $99, $99, $83, $9F, $9F, $FF  ;226
1079         .byte $FF, $C3, $9F, $9F, $9F, $C3, $FF, $FF  ;227
1080         .byte $FF, $C1, $99, $99, $C1, $F9, $F9, $FF  ;228
1081         .byte $FF, $C3, $9F, $81, $99, $C3, $FF, $FF  ;229
1082         .byte $FF, $E7, $E7, $E7, $C1, $E7, $F1, $FF  ;230
1083         .byte $83, $F9, $C1, $99, $99, $C1, $FF, $FF  ;231
1084         .byte $FF, $99, $99, $99, $83, $9F, $9F, $FF  ;232
1085         .byte $FF, $C3, $E7, $E7, $C7, $FF, $E7, $FF  ;233
1086         .byte $C3, $F9, $F9, $F9, $F9, $FF, $F9, $FF  ;234
1087         .byte $FF, $99, $93, $87, $93, $9F, $9F, $FF  ;235
1088         .byte $FF, $C3, $E7, $E7, $E7, $E7, $C7, $FF  ;236
1089         .byte $FF, $9C, $94, $80, $80, $99, $FF, $FF  ;237
1090         .byte $FF, $99, $99, $99, $99, $83, $FF, $FF  ;238
1091         .byte $FF, $C3, $99, $99, $99, $C3, $FF, $FF  ;239
1092         .byte $9F, $9F, $83, $99, $99, $83, $FF, $FF  ;240
1093         .byte $F9, $F9, $C1, $99, $99, $C1, $FF, $FF  ;241
1094         .byte $FF, $9F, $9F, $9F, $99, $83, $FF, $FF  ;242
1095         .byte $FF, $83, $F9, $C3, $9F, $C1, $FF, $FF  ;243
1096         .byte $FF, $F1, $E7, $E7, $E7, $81, $E7, $FF  ;244
1097         .byte $FF, $C1, $99, $99, $99, $99, $FF, $FF  ;245
1098         .byte $FF, $E7, $C3, $99, $99, $99, $FF, $FF  ;246
1099         .byte $FF, $C9, $C1, $80, $94, $9C, $FF, $FF  ;247
1100         .byte $FF, $99, $C3, $E7, $C3, $99, $FF, $FF  ;248
1101         .byte $87, $F3, $C1, $99, $99, $99, $FF, $FF  ;249
1102         .byte $FF, $81, $CF, $E7, $F3, $81, $FF, $FF  ;250
1103         .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3  ;251
1104         .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3  ;252
1105         .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3  ;253
1106         .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF  ;254
1107         .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF  ;255