]> git.sur5r.net Git - cc65/blobdiff - libsrc/lynx/lynx-160-102-16.s
add posixdirent.s by Stefan Haubenthal
[cc65] / libsrc / lynx / lynx-160-102-16.s
index d9899271f028f1316cd3f14dfbc056729fb114fd..83e0c10afd8d8a8f1e99cc154554223e3b19c7a1 100644 (file)
@@ -1,10 +1,19 @@
 ;
 ; Graphics driver for the 160x102x16 mode on the Lynx.
 ;
-; Based on Stephen L. Judds GRLIB code
+; All the drawing functions are simply done by sprites as the sprite
+; engine is the only way to do fast graphics on a Lynx.
+;
+; So the code is not really based on any algorithms done by somebody.
+; I have looked at other routines in the cc65 libs to see what kind of
+; entry points we need. And I have looked at the old cc65 libs by
+; Bastian Schick to see how things worked in the past.
+;
+; This code is written by Karri Kaksonen, 2004 for the cc65 compiler.
 ;
 
        .include        "zeropage.inc"
+       .include        "extzp.inc"
 
        .include        "tgi-kernel.inc"
         .include        "tgi-mode.inc"
@@ -14,7 +23,6 @@
 
         .macpack        generic
 
-
 ; ------------------------------------------------------------------------
 ; Header. Includes jump table and constants.
 
@@ -28,7 +36,7 @@
         .word   160                     ; X resolution
         .word   102                     ; Y resolution
         .byte   16                      ; Number of drawing colors
-        .byte   1                       ; Number of screens available
+        .byte   2                       ; Number of screens available
         .byte   8                       ; System font X size
         .byte   8                       ; System font Y size
         .res    4, $00                  ; Reserved for future extensions
 ; that the graphics kernel will emulate the function by using lower level
 ; primitives - for example ploting a line by using calls to SETPIXEL.
 
-        .word   INSTALL
-        .word   UNINSTALL
-        .word   INIT
-        .word   DONE
-       .word   GETERROR
-        .word   CONTROL
-        .word   CLEAR
-        .word   SETVIEWPAGE
-        .word   SETDRAWPAGE
-        .word   SETCOLOR
-        .word   SETPALETTE
-        .word   GETPALETTE
-        .word   GETDEFPALETTE
-        .word   SETPIXEL
-        .word   GETPIXEL
-        .word   LINE
-        .word   BAR
-        .word   CIRCLE
-        .word   TEXTSTYLE
-        .word   OUTTEXT
+        .addr   INSTALL
+        .addr   UNINSTALL
+        .addr   INIT
+        .addr   DONE
+        .addr  GETERROR
+        .addr   CONTROL
+        .addr   CLEAR
+        .addr   SETVIEWPAGE
+        .addr   SETDRAWPAGE
+        .addr   SETCOLOR
+        .addr   SETPALETTE
+        .addr   GETPALETTE
+        .addr   GETDEFPALETTE
+        .addr   SETPIXEL
+        .addr   GETPIXEL
+        .addr   LINE
+        .addr   BAR
+        .addr   CIRCLE
+        .addr   TEXTSTYLE
+        .addr   OUTTEXT
+        .addr   IRQ
+
 
 ; ------------------------------------------------------------------------
 ; Data.
@@ -70,17 +80,11 @@ X1              := ptr1
 Y1              := ptr2
 X2              := ptr3
 Y2              := ptr4
-RADIUS          := tmp1
-
-ROW             := tmp2         ; Bitmap row...
-COL             := tmp3         ; ...and column, both set by PLOT
-TEMP            := tmp4
-TEMP2           := sreg
-POINT           := regsave
-INRANGE         := regsave+2    ; PLOT variable, $00 = coordinates in range
 
-CHUNK           := X2           ; Used in the line routine
-OLDCHUNK        := X2+1         ; Dito
+STRPTR         := ptr3
+FONTOFF                := ptr4
+STROFF         := tmp3
+STRLEN         := tmp4
 
 ; Absolute variables used in the code
 
@@ -91,34 +95,21 @@ ERROR:      .res    1       ; Error code
 DRAWINDEX:      .res    1      ; Pen to use for drawing
 VIEWPAGEL:     .res    1
 VIEWPAGEH:     .res    1
-
-; INIT/DONE
-OLDD018:        .res    1       ; Old register value
-
-; Line routine stuff
-DX:             .res    2
-DY:             .res    2
-
-; Circle routine stuff, overlaid by BAR variables
-X1SAVE:
-CURX:           .res    1
-CURY:           .res    1
-Y1SAVE:
-BROW:           .res    1       ; Bottom row
-TROW:           .res    1       ; Top row
-X2SAVE:
-LCOL:           .res    1       ; Left column
-RCOL:           .res    1       ; Right column
-Y2SAVE:
-CHUNK1:         .res    1
-OLDCH1:         .res    1
-CHUNK2:         .res    1
-OLDCH2:         .res    1
+DRAWPAGEL:     .res    1
+DRAWPAGEH:     .res    1
 
 ; Text output stuff
 TEXTMAGX:       .res    1
 TEXTMAGY:       .res    1
 TEXTDIR:        .res    1
+BGINDEX:        .res    1      ; Pen to use for text background
+
+; Double buffer IRQ stuff
+DRAWPAGE:      .res    1
+SWAPREQUEST:   .res    1
+
+text_bitmap:    .res   8*(1+20+1)+1
+; 8 rows with (one offset-byte plus 20 character bytes plus one fill-byte) plus one 0-offset-byte
 
 ; Constants and tables
 
@@ -159,13 +150,6 @@ DEFPALETTE:     .byte   >$000
 
 PALETTESIZE     = * - DEFPALETTE
 
-BITTAB:         .byte   $80,$40,$20,$10,$08,$04,$02,$01
-BITCHUNK:       .byte   $FF,$7F,$3F,$1F,$0F,$07,$03,$01
-
-VBASE                  = $E000         ; Video memory base address
-CBASE           = $D000         ; Color memory base address
-
-
 .code
 
 ; ------------------------------------------------------------------------
@@ -177,6 +161,12 @@ CBASE           = $D000         ; Color memory base address
 ;
 
 INSTALL:
+       lda     #1
+       sta     TEXTMAGX
+       sta     TEXTMAGY
+       stz     BGINDEX
+       stz     DRAWPAGE
+       stz     SWAPREQUEST
         rts
 
 
@@ -206,8 +196,20 @@ UNINSTALL:
 ;
 
 INIT:
+; Enable interrupts for VBL
+       lda     #$80
+       tsb     VTIMCTLA
+; Set up collision buffer to $A058
+       lda     #$58
+       sta     COLLBASL
+       lda     #$A0
+       sta     COLLBASH
+; Put collision index before sprite data
+       lda     #$FE
+       sta     COLLOFFL
+       lda     #$FF
+       sta     COLLOFFH
 ; Done, reset the error code
-
         lda     #TGI_ERR_OK
         sta     ERROR
         rts
@@ -237,9 +239,138 @@ GETERROR:
 ;
 ; Must set an error code: YES
 ;
+; The TGI lacks a way to draw sprites. As that functionality is vital to
+; Lynx games we borrow this CONTROL function to implement the still
+; missing tgi_draw_sprite funtion. To use this in your C-program
+; do a #define tgi_draw_sprite(spr) tgi_ioctl(0, spr)
+;
+; To do a flip-screen call tgi_ioctl(1, 0)
+;
+; To set the background index for text outputs call tgi_ioctl(2, bgindex)
+;
+; To set the frame rate for the display hardware call tgi_ioctl(3, rate)
+;
+; To check if the drawing engine is busy with the previous swap you can
+; call tgi_ioctl(4, 0). It returns 0 if idle and 1 if busy
+;
+; To update displays you can call tgi_ioctl(4, 1) it will wait for the
+; next VBL interrupt and swap draw and view buffers.
+;
+; Activate or deactivate collision detection by calling tgi_ioctl(5, 0/1).
 
 CONTROL:
-       lda     #TGI_ERR_INV_FUNC
+        pha                    ; Almost all control routines succeed
+        lda     #TGI_ERR_OK
+       sta     ERROR
+       pla
+
+       cmp     #5
+       bne     ControlSwap
+       lda     ptr1
+       bne     @L0
+       lda     __sprsys
+       ora     #$20
+       bra     @L1
+@L0:   lda     __sprsys
+       and     #$df
+@L1:   sta     __sprsys
+       sta     SPRSYS
+       rts
+
+ControlSwap:
+       cmp     #4
+       bne     ControlFramerate
+
+       lda     ptr1            ; Swap request
+       bne     @L0
+       lda     SWAPREQUEST
+       rts
+@L0:    sta    SWAPREQUEST
+       rts
+
+ControlFramerate:
+       cmp     #3
+       bne     ControlTextBG
+
+       lda     ptr1
+               cmp     #75             ; Set framerate
+               beq     rate75
+               cmp     #60
+               beq     rate60
+        cmp     #50
+               beq     rate50
+        lda     #TGI_ERR_INV_ARG
+       sta     ERROR
+        rts
+rate50: lda     #$bd           ; 50 Hz
+               ldx     #$31
+               bra     setRate
+rate60: lda     #$9e           ; 60 Hz
+               ldx     #$29
+               bra     setRate
+rate75: lda     #$7e           ; 75 Hz
+               ldx     #$20
+setRate:
+        sta     HTIMBKUP
+               stx     PBKUP
+       rts
+
+ControlTextBG:
+       cmp     #2
+       bne     ControlFlipScreen
+
+       lda     ptr1            ; Set text background color
+       sta     BGINDEX
+       rts
+
+ControlFlipScreen:
+       cmp     #1
+       bne     ControlDrawSprite
+
+       lda     __sprsys        ; Flip screen
+       eor     #8
+       sta     __sprsys
+       sta     SPRSYS
+       lda     __viddma
+       eor     #2
+       sta     __viddma
+       sta     DISPCTL
+       ldy     VIEWPAGEL
+       ldx     VIEWPAGEH
+       and     #2
+       beq     NotFlipped
+       clc
+       tya
+       adc     #<8159
+       tay
+       txa
+       adc     #>8159
+       tax
+NotFlipped:
+       sty     DISPADRL
+       stx     DISPADRH
+        rts
+
+ControlDrawSprite:
+       lda     ptr1            ; Get the sprite address
+       ldx     ptr1+1
+
+draw_sprite:                   ; Draw it in render buffer
+               sta     SCBNEXTL
+               stx     SCBNEXTH
+       lda     DRAWPAGEL
+       ldx     DRAWPAGEH
+       sta     VIDBASL
+               stx     VIDBASH
+               lda     #1
+               sta     SPRGO
+               stz     SDONEACK
+@L0:    stz     CPUSLEEP
+               lda     SPRSYS
+               lsr
+               bcs     @L0
+               stz     SDONEACK
+        lda     #TGI_ERR_OK
        sta     ERROR
         rts
 
@@ -266,18 +397,7 @@ cls_sprite:
 .code
 CLEAR:  lda     #<cls_sprite
                ldx     #>cls_sprite
-draw_sprite:
-               sta     $fc10
-               stx     $fc11
-               lda     #1
-               sta     $fc91
-               stz     $fd90
-@L3:    stz     CPUSLEEP
-               lda     $fc92
-               lsr
-               bcs     @L3
-               stz     $fd90
-       rts
+       bra     draw_sprite
 
 ; ------------------------------------------------------------------------
 ; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
@@ -285,18 +405,37 @@ draw_sprite:
 ;
 ; Must set an error code: NO (will only be called if page ok)
 ;
+; It is a good idea to call this function during the vertical blanking
+; period. If you call it in the middle of the screen update then half of
+; the drawn frame will be from the old buffer and the other half is
+; from the new buffer. This is usually noticed by the user.
 
 SETVIEWPAGE:
-               beq     @L1
-               lda     #<$fe00-8160-8160
-               ldx     #>$fe00-8160-8160
+       cmp     #1
+               beq     @L1             ; page == maxpages-1
+               ldy     #<$e018         ; page 0
+               ldx     #>$e018
                bra     @L2
-@L1:    lda     #<$fe00-8160
-               ldx     #>$fe00-8160
-@L2:    sta     DISPADRL            ; $FD94
-               sta     VIEWPAGEL
-               stx     DISPADRH            ; $FD95
-               sta     VIEWPAGEH
+@L1:
+       ldy     #<$c038         ; page 1
+               ldx     #>$c038
+@L2:
+               sty     VIEWPAGEL       ; Save viewpage for getpixel
+               stx     VIEWPAGEH
+
+       lda     __viddma        ; Process flipped displays
+       and     #2
+       beq     @L3
+       clc
+       tya
+       adc     #<8159
+       tay
+       txa
+       adc     #>8159
+       tax
+@L3:
+        sty     DISPADRL        ; $FD94
+               stx     DISPADRH        ; $FD95
         rts
 
 ; ------------------------------------------------------------------------
@@ -307,16 +446,42 @@ SETVIEWPAGE:
 ;
 
 SETDRAWPAGE:
-               beq     @L1
-               lda     #<$fe00-8160-8160
-               ldx     #>$fe00-8160-8160
+               cmp     #1
+               beq     @L1                 ; page == maxpages-1
+               lda     #<$e018             ; page 0
+               ldx     #>$e018
                bra     @L2
-@L1:    lda     #<$fe00-8160
-               ldx     #>$fe00-8160
-@L2:    sta     VIDBASL            ; $FD94
-               stx     VIDBASH            ; $FD95
+@L1:
+        lda     #<$c038             ; page 1
+               ldx     #>$c038
+@L2:
+        sta     DRAWPAGEL
+               stx     DRAWPAGEH
         rts
 
+; ------------------------------------------------------------------------
+; IRQ: VBL interrupt handler
+;
+
+IRQ:
+               lda     INTSET          ; Poll all pending interrupts
+               and     #VBL_INTERRUPT
+        beq            IRQEND          ; Exit if not a VBL interrupt
+
+               lda     SWAPREQUEST
+               beq     @L0
+               lda     DRAWPAGE
+               jsr     SETVIEWPAGE
+               lda     DRAWPAGE
+               eor     #1
+               sta     DRAWPAGE
+               jsr     SETDRAWPAGE
+               stz     SWAPREQUEST
+@L0:
+IRQEND:
+               clc
+               rts
+
 ; ------------------------------------------------------------------------
 ; SETCOLOR: Set the drawing color (in A). The new color is already checked
 ; to be in a valid range (0..maxcolor-1).
@@ -383,7 +548,7 @@ GETDEFPALETTE:
 ;
 ; Must set an error code: NO
 ;
-                
+
 .data
 pixel_sprite:
         .byte   %00000001                      ; A pixel sprite
@@ -392,10 +557,10 @@ pixel_sprite:
                .addr   0,pixel_bitmap
 pix_x:         .word   0
 pix_y:         .word   0
-               .word   $0100
-               .word   $0100
+       .word   $100
+       .word   $100
 pix_c:         .byte   $00
-       
+
 .code
 SETPIXEL:
         lda     X1
@@ -435,7 +600,13 @@ GETPIXEL:
                sta     ptr1+1
 
                ldx     #0
+       lda     #15
+       sta     MAPCTL
                lda     (ptr1),y
+       tay
+       lda     #$0c
+       sta     MAPCTL
+       tya
                plp
                bcc     @L1
                and     #$f
@@ -451,19 +622,124 @@ GETPIXEL:
 ; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
 ; X2/Y2 = ptr3/ptr4 using the current drawing color.
 ;
-; To deal with off-screen coordinates, the current row
-; and column (40x25) is kept track of.  These are set
-; negative when the point is off the screen, and made
-; positive when the point is within the visible screen.
-;
-; X1,X2 etc. are set up above (x2=LINNUM in particular)
-; Format is LINE x2,y2,x1,y1
-;
 ; Must set an error code: NO
 ;
 
+.data
+line_sprite:
+       .byte   0               ; Will be replaced by the code
+       .byte   %00110000
+       .byte   %00100000
+       .word   0,pixel_bitmap
+line_x:
+       .word    0
+line_y:
+       .word    0
+line_sx:
+       .word    $100
+line_sy:
+       .word    $100
+       .word    0
+line_tilt:
+       .word    0
+line_c:
+       .byte    $e
+
+.code
 LINE:
-        rts
+       lda     DRAWINDEX
+       sta     line_c
+       stz     line_sx
+       stz     line_sy
+
+       sec
+       lda     X2
+       sbc     X1
+       lda     X2+1
+       sbc     X1+1
+       bpl     @L1
+       lda     X1
+       ldx     X2
+       sta     X2
+       stx     X1
+       lda     X1+1
+       ldx     X2+1
+       sta     X2+1
+       stx     X1+1
+       lda     Y1
+       ldx     Y2
+       sta     Y2
+       stx     Y1
+       lda     Y1+1
+       ldx     Y2+1
+       sta     Y2+1
+       stx     Y1+1
+@L1:
+       lda     #%00000000      ; Not flipped
+       sta     line_sprite
+
+       sec
+       lda     Y2
+       sbc     Y1
+       sta     Y2
+       lda     Y2+1
+       sbc     Y1+1
+       sta     Y2+1
+       bpl     @L2
+       sec
+       lda     #0
+       sbc     Y2
+       sta     Y2
+       lda     #0
+       sbc     Y2+1
+       sta     Y2+1
+       lda     #%00010000      ; Vertical flip
+       sta     line_sprite
+@L2:
+       lda     X1
+       sta     line_x
+       lda     X1+1
+       sta     line_x+1
+       lda     Y1
+       sta     line_y
+       lda     Y1+1
+       sta     line_y+1
+
+       lda     Y2
+       ina
+       sta     line_sy+1
+       sta     MATHP           ; hardware divide
+       stz     MATHN
+
+       stz     MATHH
+       stz     MATHG
+       sec
+       lda     X2
+       sbc     X1
+       ina
+       sta     MATHF
+       stz     MATHE
+@L3:
+       lda     SPRSYS
+       bmi     @L3             ; wait for math done (bit 7 of sprsys)
+       lda     MATHC
+       sta     line_tilt
+       lda     MATHB
+       sta     line_tilt+1
+       bne     @L4
+       lda     #1
+       sta     line_sx+1
+       bra     @L6
+@L4:
+       bit     line_tilt
+       bpl     @L5
+       ina
+@L5:
+       sta     line_sx+1
+@L6:
+       lda     #<line_sprite
+       ldx     #>line_sprite
+       jmp     draw_sprite
 
 ; ------------------------------------------------------------------------
 ; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
@@ -501,10 +777,12 @@ BAR:    lda     X1
                lda     X2
                sec
                sbc     X1
+       ina
                sta     bar_sx+1
                lda     Y2
                sec
                sbc     Y1
+       ina
                sta     bar_sy+1
                lda     DRAWINDEX
                sta     bar_c
@@ -518,9 +796,58 @@ BAR:    lda     X1
 ;
 ; Must set an error code: NO
 ;
+; There is no sensible way of drawing a circle on a Lynx. As I would
+; have to use line elements to do the circle I rather do it in C than
+; create it here in the driver.
+
+; To do a circle please add this to your C program
+
+;int sintbl[9] = {
+;      0,     //  0    degrees
+;      3196,  // 11.25 degrees
+;      6270,  // 22.5  degrees
+;      9102,  // 33.75 degrees
+;      11585, // 45    degrees
+;      13623, // 56.25 degrees
+;      15137, // 67.5  degrees
+;      16069, // 78.75 degrees
+;      16384  // 90    degrees
+;};
+
+;int sin(char d)
+;{
+;    char neg;
+;    d = d & 31;
+;    neg = d > 16;
+;    d = d & 15;
+;    if (d > 8)
+;        d = 16 - d;
+;    if (neg)
+;      return -sintbl[d];
+;    else
+;      return sintbl[d];
+;}
+
+;void tgi_Circle(int x0, int y0, unsigned char r)
+;{
+;      char i;
+;      int x1, y1, x2, y2;
+;
+;      x1 = ((long)sin(0) * r + 8192) / 16384 + x0;
+;      y1 = ((long)sin(8) * r + 8192) / 16384 + y0;
+;      for (i = 1; i <= 32; i++) {
+;              x2 = ((long)sin(i) * r + 8192) / 16384 + x0;
+;              y2 = ((long)sin(i+8) * r + 8192) / 16384 + y0;
+;              tgi_line(x1, y1, x2, y2);
+;              x1 = x2;
+;              y1 = y2;
+;      }
+;}
+
+;#define tgi_circle tgi_Circle
 
 CIRCLE:
-        rts
+       rts
 
 ; ------------------------------------------------------------------------
 ; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
@@ -535,7 +862,6 @@ TEXTSTYLE:
         sta     TEXTDIR
         rts
 
-
 ; ------------------------------------------------------------------------
 ; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
 ; current text style. The text to output is given as a zero terminated
@@ -545,5 +871,237 @@ TEXTSTYLE:
 ;
 
 OUTTEXT:
-        rts
+       lda     TEXTMAGX        ; Scale sprite
+       sta     text_sx+1
+       lda     TEXTMAGY
+       sta     text_sy+1
+
+       stz     text_sprite     ; Set normal sprite
+       lda     BGINDEX
+       bne     @L1
+       lda     #4
+       sta     text_sprite     ; Set opaque sprite
+@L1:
+       lda     DRAWINDEX       ; Set color
+       asl
+       asl
+       asl
+       asl
+       ora     BGINDEX
+       sta     text_c
+
+       lda     X1              ; Set start position
+       sta     text_x
+       lda     X1+1
+       sta     text_x+1
+       lda     Y1
+       sta     text_y
+       lda     Y1+1
+       sta     text_y+1
+
+       ldy     #-1             ; Calculate string length
+@L2:
+       iny
+       lda     (STRPTR),y
+       bne     @L2
+       cpy     #20
+       bmi     @L3
+       ldy     #20
+@L3:
+       sty     STRLEN
+        bne    @L4
+        rts                    ; Zero length string
+@L4:
+       iny                     ; Prepare text_bitmap
+        iny
+        sty    STROFF
+
+        ldy    #8-1            ; 8 pixel lines per character
+        ldx    #0
+        clc
+@L5:
+        lda    STROFF
+        sta    text_bitmap,x
+        txa
+        adc    STROFF
+        tax
+        lda    #$ff
+        sta    text_bitmap-1,x
+        dey
+        bpl    @L5
+        stz    text_bitmap,x
+
+        stz    tmp2
+        iny
+@L6:
+        lda    (STRPTR),y
+        sty    tmp1
+
+        sec                    ; (ch-' ') * 8
+        sbc    #32
+        stz    FONTOFF
+        stz    FONTOFF+1
+        asl
+        asl
+        rol    FONTOFF+1
+        asl
+        rol    FONTOFF+1
+        clc                    ; Choose font
+        adc    #<font
+        sta    FONTOFF
+        lda    FONTOFF+1
+        adc    #>font
+        sta    FONTOFF+1
+
+; and now copy the 8 bytes of that char
+
+        ldx    tmp2
+        inx
+        stx    tmp2
+
+; draw char from top to bottom, reading char-data from offset 8-1 to offset 0
+        ldy    #8-1
+@L7:
+        lda    (FONTOFF),y         ; *chptr
+        sta    text_bitmap,x    ;textbuf[y*(1+len+1)+1+x]
+
+        txa
+        adc    STROFF
+        tax
+
+        dey
+        bpl    @L7
+
+        ; goto next char
+        ldy    tmp1
+        iny
+        dec    STRLEN
+        bne    @L6
+
+        lda    #<text_sprite
+        ldx    #>text_sprite
+        jmp    draw_sprite
+
+.data
+text_sprite:
+        .byte $00,$90,$20
+        .addr 0, text_bitmap
+text_x:
+        .word 0
+text_y:
+        .word 0
+text_sx:
+        .word $100
+text_sy:
+        .word $100
+text_c:
+        .byte 0
 
+.rodata
+; The Font
+; 96 characters from ASCII 32 to 127
+; 8 pixels wide, 8 pixels high
+; bit value 0 = foreground, bit value 1 = background / transparent
+font:
+; VERSAIL
+       .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF  ;32
+       .byte $FF, $E7, $FF, $FF, $E7, $E7, $E7, $E7  ;33
+       .byte $FF, $FF, $FF, $FF, $FF, $99, $99, $99  ;34
+       .byte $FF, $99, $99, $00, $99, $00, $99, $99  ;35
+       .byte $FF, $E7, $83, $F9, $C3, $9F, $C1, $E7  ;36
+       .byte $FF, $B9, $99, $CF, $E7, $F3, $99, $9D  ;37
+       .byte $FF, $C0, $99, $98, $C7, $C3, $99, $C3  ;38
+       .byte $FF, $FF, $FF, $FF, $FF, $E7, $F3, $F9  ;39
+       .byte $FF, $F3, $E7, $CF, $CF, $CF, $E7, $F3  ;40
+       .byte $FF, $CF, $E7, $F3, $F3, $F3, $E7, $CF  ;41
+       .byte $FF, $FF, $99, $C3, $00, $C3, $99, $FF  ;42
+       .byte $FF, $FF, $E7, $E7, $81, $E7, $E7, $FF  ;43
+       .byte $CF, $E7, $E7, $FF, $FF, $FF, $FF, $FF  ;44
+       .byte $FF, $FF, $FF, $FF, $81, $FF, $FF, $FF  ;45
+       .byte $FF, $E7, $E7, $FF, $FF, $FF, $FF, $FF  ;46
+       .byte $FF, $9F, $CF, $E7, $F3, $F9, $FC, $FF  ;47
+       .byte $FF, $C3, $99, $99, $89, $91, $99, $C3  ;48
+       .byte $FF, $81, $E7, $E7, $E7, $C7, $E7, $E7  ;49
+       .byte $FF, $81, $9F, $CF, $F3, $F9, $99, $C3  ;50
+       .byte $FF, $C3, $99, $F9, $E3, $F9, $99, $C3  ;51
+       .byte $FF, $F9, $F9, $80, $99, $E1, $F1, $F9  ;52
+       .byte $FF, $C3, $99, $F9, $F9, $83, $9F, $81  ;53
+       .byte $FF, $C3, $99, $99, $83, $9F, $99, $C3  ;54
+       .byte $FF, $E7, $E7, $E7, $E7, $F3, $99, $81  ;55
+       .byte $FF, $C3, $99, $99, $C3, $99, $99, $C3  ;56
+       .byte $FF, $C3, $99, $F9, $C1, $99, $99, $C3  ;57
+       .byte $FF, $FF, $E7, $FF, $FF, $E7, $FF, $FF  ;58
+       .byte $CF, $E7, $E7, $FF, $FF, $E7, $FF, $FF  ;59
+       .byte $FF, $F1, $E7, $CF, $9F, $CF, $E7, $F1  ;60
+       .byte $FF, $FF, $FF, $81, $FF, $81, $FF, $FF  ;61
+       .byte $FF, $8F, $E7, $F3, $F9, $F3, $E7, $8F  ;62
+       .byte $FF, $E7, $FF, $E7, $F3, $F9, $99, $C3  ;63
+
+
+       .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3  ;0
+       .byte $FF, $99, $99, $99, $81, $99, $C3, $E7  ;1
+       .byte $FF, $83, $99, $99, $83, $99, $99, $83  ;2
+       .byte $FF, $C3, $99, $9F, $9F, $9F, $99, $C3  ;3
+       .byte $FF, $87, $93, $99, $99, $99, $93, $87  ;4
+       .byte $FF, $81, $9F, $9F, $87, $9F, $9F, $81  ;5
+       .byte $FF, $9F, $9F, $9F, $87, $9F, $9F, $81  ;6
+       .byte $FF, $C3, $99, $99, $91, $9F, $99, $C3  ;7
+       .byte $FF, $99, $99, $99, $81, $99, $99, $99  ;8
+       .byte $FF, $C3, $E7, $E7, $E7, $E7, $E7, $C3  ;9
+       .byte $FF, $C7, $93, $F3, $F3, $F3, $F3, $E1  ;10
+       .byte $FF, $99, $93, $87, $8F, $87, $93, $99  ;11
+       .byte $FF, $81, $9F, $9F, $9F, $9F, $9F, $9F  ;12
+       .byte $FF, $9C, $9C, $9C, $94, $80, $88, $9C  ;13
+       .byte $FF, $99, $99, $91, $81, $81, $89, $99  ;14
+       .byte $FF, $C3, $99, $99, $99, $99, $99, $C3  ;15
+       .byte $FF, $9F, $9F, $9F, $83, $99, $99, $83  ;16
+       .byte $FF, $F1, $C3, $99, $99, $99, $99, $C3  ;17
+       .byte $FF, $99, $93, $87, $83, $99, $99, $83  ;18
+       .byte $FF, $C3, $99, $F9, $C3, $9F, $99, $C3  ;19
+       .byte $FF, $E7, $E7, $E7, $E7, $E7, $E7, $81  ;20
+       .byte $FF, $C3, $99, $99, $99, $99, $99, $99  ;21
+       .byte $FF, $E7, $C3, $99, $99, $99, $99, $99  ;22
+       .byte $FF, $9C, $88, $80, $94, $9C, $9C, $9C  ;23
+       .byte $FF, $99, $99, $C3, $E7, $C3, $99, $99  ;24
+       .byte $FF, $E7, $E7, $E7, $C3, $99, $99, $99  ;25
+       .byte $FF, $81, $9F, $CF, $E7, $F3, $F9, $81  ;26
+       .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3  ;27
+       .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3  ;28
+       .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3  ;29
+       .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF  ;30
+       .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF  ;31
+
+
+; gemena
+       .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3  ;224
+       .byte $FF, $C1, $99, $C1, $F9, $C3, $FF, $FF  ;225
+       .byte $FF, $83, $99, $99, $83, $9F, $9F, $FF  ;226
+       .byte $FF, $C3, $9F, $9F, $9F, $C3, $FF, $FF  ;227
+       .byte $FF, $C1, $99, $99, $C1, $F9, $F9, $FF  ;228
+       .byte $FF, $C3, $9F, $81, $99, $C3, $FF, $FF  ;229
+       .byte $FF, $E7, $E7, $E7, $C1, $E7, $F1, $FF  ;230
+       .byte $83, $F9, $C1, $99, $99, $C1, $FF, $FF  ;231
+       .byte $FF, $99, $99, $99, $83, $9F, $9F, $FF  ;232
+       .byte $FF, $C3, $E7, $E7, $C7, $FF, $E7, $FF  ;233
+       .byte $C3, $F9, $F9, $F9, $F9, $FF, $F9, $FF  ;234
+       .byte $FF, $99, $93, $87, $93, $9F, $9F, $FF  ;235
+       .byte $FF, $C3, $E7, $E7, $E7, $E7, $C7, $FF  ;236
+       .byte $FF, $9C, $94, $80, $80, $99, $FF, $FF  ;237
+       .byte $FF, $99, $99, $99, $99, $83, $FF, $FF  ;238
+       .byte $FF, $C3, $99, $99, $99, $C3, $FF, $FF  ;239
+       .byte $9F, $9F, $83, $99, $99, $83, $FF, $FF  ;240
+       .byte $F9, $F9, $C1, $99, $99, $C1, $FF, $FF  ;241
+       .byte $FF, $9F, $9F, $9F, $99, $83, $FF, $FF  ;242
+       .byte $FF, $83, $F9, $C3, $9F, $C1, $FF, $FF  ;243
+       .byte $FF, $F1, $E7, $E7, $E7, $81, $E7, $FF  ;244
+       .byte $FF, $C1, $99, $99, $99, $99, $FF, $FF  ;245
+       .byte $FF, $E7, $C3, $99, $99, $99, $FF, $FF  ;246
+       .byte $FF, $C9, $C1, $80, $94, $9C, $FF, $FF  ;247
+       .byte $FF, $99, $C3, $E7, $C3, $99, $FF, $FF  ;248
+       .byte $87, $F3, $C1, $99, $99, $99, $FF, $FF  ;249
+       .byte $FF, $81, $CF, $E7, $F3, $81, $FF, $FF  ;250
+       .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3  ;251
+       .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3  ;252
+       .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3  ;253
+       .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF  ;254
+       .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF  ;255