diff --git a/Makefile.rob b/Makefile.rob index 53e3c75..0bfd5b1 100644 --- a/Makefile.rob +++ b/Makefile.rob @@ -3,7 +3,7 @@ COLORSPRITE = moldy_burger.png #COLORSPRITE = apple.png BWSPRITE = apple-sprite9x11.png -all: multitest.dsk +all: cpbg.dsk fonttest.dsk rowlookup.s: HiSprite.py python HiSprite.py -a mac65 -p 6502 -r > rowlookup.s @@ -35,8 +35,25 @@ multitest.dsk: HiSprite.py multitest.s multitest-sprite-driver.s atasm -omultitest.xex multitest.s -Lmultitest.var -gmultitest.lst atrcopy multitest.dsk boot -b multitest.xex --brun 6000 -f +multitestbg.dsk: HiSprite.py multitestbg.s + atasm -omultitest.xex multitestbg.s -Lmultitestbg.var -gmultitestbg.lst + atrcopy multitest.dsk boot -b multitest.xex --brun 6000 -f + +cpbg-sprite-driver.s: HiSprite.py $(BWSPRITE) + python HiSprite.py -a mac65 -p 6502 -s hgrbw -m -k -d -g -f fatfont128.dat -o cpbg $(BWSPRITE) $(COLORSPRITE) + +cpbg.dsk: HiSprite.py cpbg.s cpbg-sprite-driver.s + atasm -ocpbg.xex cpbg.s -Lcpbg.var -gcpbg.lst + #atrcopy cpbg.dsk boot -d partycrasher-software.hgr@2000 player-missile.hgr@4000 -b cpbg.xex --brun 6000 -f + atrcopy cpbg.dsk boot -b cpbg.xex --brun 6000 -f + +fonttest.dsk: fonttest.s fatfont.s + atasm -ofonttest.xex fonttest.s -Lfonttest.var -gfonttest.lst + atrcopy fonttest.dsk boot -b fonttest.xex --brun 6000 -f + clean: rm -f rowlookup.s collookupbw.s collookupcolor.s rm -f bwtest.dsk bwtest.xex bwtest.var bwtest.lst rm -f colortest.dsk colortest.xex colortest.var colortest.lst rm -f multitest.dsk multitest.xex multitest.var multitest.lst multitest-sprite-driver.s multitest-bwsprite.s multitest-hgrcols-7x1.s multitest-hgrrows.s + rm -f cpbg.dsk cpbg.xex cpbg.var cpbg.lst cpbg-sprite-driver.s cpbg-bwsprite.s cpbg-hgrcols-7x1.s cpbg-hgrrows.s diff --git a/cpbg.s b/cpbg.s new file mode 100644 index 0000000..9bee35a --- /dev/null +++ b/cpbg.s @@ -0,0 +1,519 @@ +; os memory map +CLRTEXT = $c050 +SETTEXT = $c051 +CLRMIXED = $c052 +SETMIXED = $c053 +TXTPAGE1 = $c054 +TXTPAGE2 = $c055 +CLRHIRES = $c056 +SETHIRES = $c057 + +; ROM entry points +COUT = $fded +ROMWAIT = $fca8 + +; Zero page locations we use (unused by Monitor, Applesoft, or ProDOS) +PARAM0 = $06 +PARAM1 = $07 +PARAM2 = $08 +PARAM3 = $09 +SCRATCH0 = $19 +SCRATCH1 = $1a +SPRITEPTR_L = $1b +SPRITEPTR_H = $1c +RENDERCOUNT = $ce +DRAWPAGE = $d7 ; pos = page1, neg = page2 +BGSTORE = $fa +TEMPADDR = $fc +COUNTER1 = $80 +HGRHI = $82 ; either $20 or $40, the base of each hgr screen +HGRSELECT = $83 ; either $00 or $60, used as xor mask to turn HGRROWS_H1 into address of either page +TEXTPTR = $84 +HGRPTR = $86 +TEMPROW = $88 +TEMPCOL = $89 +DAMAGE_W = $8a +DAMAGE_H = $8b +DAMAGEPTR = $8c +DAMAGEPTR1 = $8e +DAMAGEINDEX1 = $91 +DAMAGEPTR2 = $92 +DAMAGEINDEX2 = $94 +DAMAGEINDEX = $95 +FASTFONT_SCRATCH0 = $96 + +DAMAGEPAGE1 = $bf ; page number of first byte beyond top of backing store stack +DAMAGEPAGE2 = $be + +; constants +MAXPOSX = 250 +MAXPOSY = 192 - 16 + + + *= $6000 + +start + bit CLRTEXT ; start with HGR page 1, full screen + bit CLRMIXED + bit TXTPAGE2 + bit SETHIRES + + jsr clrscr + jsr initonce + jsr initsprites + jsr initbackground + +gameloop + jsr renderstart + jsr pageflip + jsr movestart + dec fasttoggle + bpl gofast + jsr wait +gofast + jsr restorebg_driver + jmp gameloop + +fasttoggle + .byte 0 + + +initonce + lda #0 + sta DRAWPAGE + sta DAMAGEINDEX1 + sta DAMAGEINDEX2 + sta DAMAGEPTR + sta DAMAGEPTR1 + sta DAMAGEPTR2 + lda #DAMAGEPAGE1 + sta DAMAGEPTR+1 + sta DAMAGEPTR1+1 + sta DAMAGEPTR2+1 + rts + + +initsprites + jsr restorebg_init + rts + +initbackground + jsr filltext + jsr pageflip + jsr copytexthgr + jsr clrscr + jsr pageflip + jsr copytexthgr + rts + + +filltext + ldy #0 ; Loop a bit + sty COUNTER1 +ib_outer + lda textrow_h,y + ora #4 + sta textptr+1 + lda textrow_l,y + sta textptr + tya + adc #32 + ldx #0 + ldy #0 +ib_inner + sta (textptr),y + adc #1 + inx + iny + cpy #40 + bcc ib_inner + ldy counter1 + iny + sty counter1 + cpy #24 + bcc ib_outer + rts + + +copytexthgr + lda HGRSELECT + beq copytexthgr_page1 + ldx #FASTFONT_H2 + bne copytexthgr_store_dest ; always true: hi byte of subroutine is > 0 +copytexthgr_page1 ldx #FASTFONT_H1 +copytexthgr_store_dest + stx copytexthgr_dest_smc+1 + sty copytexthgr_dest_smc+2 + ldy #0 ; y is rows +copytexthgr_outer + lda textrow_h,y + ora #4 + sta copytexthgr_src_smc+2 + lda textrow_l,y + sta copytexthgr_src_smc+1 + ldx #0 ; x is columns +copytexthgr_src_smc + lda $ffff,x +copytexthgr_dest_smc + jsr FASTFONT_H1 + inx + cpx #40 + bcc copytexthgr_src_smc + iny + cpy #24 + bcc copytexthgr_outer + rts + +copytexthgrslow + LDA #0 + STA temprow + +?1 LDY temprow ; Y = row + CPY #24 ; 24 rows is #$18 + BCS ?3 ; Y >= 24 + LDX #0 + STX tempcol ; X = col + JSR SetCursorColRow + and ~10011111 + clc ; A = HgrHiY[ row ] + adc #4 ; Convert HgrHiY to TextHiY byte + STA TEXTPTR+1 ; A -= 0x1C -> TxtHi + LDA hgrptr ; A = HgrLoY[ row ] + STA TEXTPTR ; -> TxtLo + LDY tempcol +?2 LDA (TEXTPTR),Y + AND #$7F + JSR DrawCharCol + CPY #$28 ; 40 cols is #$28 + BCC ?2 ; Y < 40 + INC temprow + BNE ?1 ; always +?3 RTS + + rts + + +pageflip + lda DRAWPAGE + eor #$80 + sta DRAWPAGE + bpl pageflip1 ; pos = show 1, draw 2; neg = show 1, draw 1 + bit TXTPAGE2 ; show page 2, work on page 1 + lda #$00 + sta HGRSELECT + lda #$20 + sta HGRHI + lda DAMAGEPTR ; save other page's damage pointer + sta DAMAGEPTR2 + lda DAMAGEPTR1 + sta DAMAGEPTR + lda DAMAGEPTR1+1 + sta DAMAGEPTR+1 + lda DAMAGEINDEX1 + sta DAMAGEINDEX + rts +pageflip1 + bit TXTPAGE1 ; show page 1, work on page 2 + lda #$60 + sta HGRSELECT + lda #$40 + sta HGRHI + lda DAMAGEPTR ; save other page's damage pointer + sta DAMAGEPTR1 + lda DAMAGEPTR2 + sta DAMAGEPTR + lda DAMAGEPTR2+1 + sta DAMAGEPTR+1 + lda DAMAGEINDEX2 + sta DAMAGEINDEX + rts + + +restorebg_init + rts + +restorebg_driver + ; copy damaged characters back to screen + rts + + + +; Draw sprites by looping through the list of sprites +renderstart + lda #sprite_l - sprite_active + sta RENDERCOUNT + inc renderroundrobin_smc+1 + +renderroundrobin_smc + ldy #0 + sty PARAM3 + +renderloop + lda PARAM3 + and #sprite_l - sprite_active - 1 + tay + lda sprite_active,y + beq renderskip ; skip if zero + lda sprite_l,y + sta jsrsprite_smc+1 + lda sprite_h,y + sta jsrsprite_smc+2 + lda sprite_x,y + sta PARAM0 + lda sprite_y,y + sta PARAM1 + jmp jsrsprite_smc +jsrsprite_smc + jsr $ffff ; wish you could JSR ($nnnn) + + ldy DAMAGEINDEX + lda PARAM2 ; contains the byte index into the line + sta (DAMAGEPTR),y + iny + clc + adc DAMAGE_W + sta (DAMAGEPTR),y + iny + + ; need to convert HGR y values to char rows + lda PARAM1 + lsr a + lsr a + lsr a + sta (DAMAGEPTR),y + iny + lda PARAM1 + clc + adc DAMAGE_H + lsr a + lsr a + lsr a + sta (DAMAGEPTR),y + iny + sty DAMAGEINDEX + +renderskip + inc PARAM3 + dec RENDERCOUNT + bne renderloop + +renderend + rts + + +movestart + lda #sprite_l - sprite_active + sta RENDERCOUNT + ldy #0 + +moveloop + lda sprite_active,y + bmi moveend + beq movenext + +movex + ; Apply X velocity to X coordinate + lda sprite_dirx,y + bpl move_right + sec + lda sprite_x,y + sbc sprite_dx,y + cmp #MAXPOSX + bcc movex_end + lda #1 + sta sprite_dirx,y + lda #0 + sta sprite_x,y + bpl movey + +move_right + clc + lda sprite_x,y + adc sprite_dx,y + cmp #MAXPOSX + bcc movex_end + lda #-1 + sta sprite_dirx,y + lda #MAXPOSX + +movex_end + ; Store the new X + sta sprite_x,y + +movey + ; Apply Y velocity to Y coordinate + lda sprite_diry,y + bpl move_down + sec + lda sprite_y,y + sbc sprite_dy,y + cmp #MAXPOSY ; checking wraparound + bcc movey_end ; less than => not wrapped + lda #1 + sta sprite_diry,y + lda #0 + sta sprite_y,y + bpl movenext + +move_down + clc + lda sprite_y,y + adc sprite_dy,y + cmp #MAXPOSY + bcc movey_end + lda #-1 + sta sprite_diry,y + lda #MAXPOSY + +movey_end + ; Store the new X + sta sprite_y,y + +movenext + iny + dec RENDERCOUNT + bne moveloop + +moveend + rts + + + +wait + ldy #$06 ; Loop a bit +wait_outer + ldx #$ff +wait_inner + nop + nop + nop + nop + nop + nop + nop + dex + bne wait_inner + dey + bne wait_outer + rts + + +clrscr + lda #0 + sta clr1+1 + sta clr2+1 + lda #$20 + sta clr1+2 + lda #$40 + sta clr2+2 +clr0 + lda #0 + ldy #0 +clr1 + sta $ffff,y +clr2 + sta $ffff,y + iny + bne clr1 + inc clr1+2 + inc clr2+2 + ldx clr1+2 + cpx #$40 + bcc clr1 + +; put the same info on both screens +clrscr2 + ldy #1 +clrouter + ldx #0 +clrloop + lda HGRROWS_H1,x + sta SCRATCH1 + lda HGRROWS_H2,x + sta TEMPADDR+1 + lda HGRROWS_L,x + sta SCRATCH0 + sta TEMPADDR + lda tophalf,y + cpx #96 + bcc clrwrite + lda bothalf,y +clrwrite + sta (SCRATCH0),y + sta (TEMPADDR),y + inx + cpx #192 + bcc clrloop + iny + cpy #40 + bcs clrend + bne clrouter +clrend + rts + +tophalf + .byte 0 + .byte $88, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101 + .byte $08, ~00101010, ~01010101, ~00101010, ~01010101, ~00101010 + .byte $10, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101 + .byte $1c, ~00101010, ~01010101, ~00101010, ~01010101, ~00101010 + .byte $88, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101 + .byte $9c, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101 + .byte $9c, ~00101010, ~01010101, ~00101010, ~01010101, ~00101010 + .byte $1c, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101 + +bothalf + .byte 0 + .byte $9c, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101 + .byte ~10001000, ~10101010, ~11010101, ~10101010, ~11010101, ~10101010 + .byte ~00010000, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101 + .byte $08, ~10101010, ~11010101, ~10101010, ~11010101, ~10101010 + .byte $9c, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101 + .byte $9c, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101 + .byte $88, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101 + .byte $08, ~10101010, ~11010101, ~10101010, ~11010101, ~10101010 + + + +; Sprite data is interleaved so a simple indexed mode can be used. This is not +; convenient to set up but makes faster accessing because you don't have to +; increment the index register. For example, all the info about sprite #2 can +; be indexed using Y = 2 on the indexed operators, e.g. "lda sprite_active,y", +; "lda sprite_x,y", etc. +; +; Number of sprites must be a power of 2 + +sprite_active + .byte 1, 1, 1, 1, 1, 1, 1, 1 ; 1 = active, 0 = skip + +sprite_l + .byte APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >MOLDY_BURGER, >MOLDY_BURGER + +sprite_x + .byte 80, 164, 33, 245, 4, 9, 255, 18 + +sprite_y + .byte 116, 126, 40, 60, 80, 100, 120, 140 + +sprite_dx + .byte 1, 2, 3, 4, 1, 2, 3, 4 + +sprite_dirx + .byte -1, -1, -1, -1, 1, 1, 1, 1 + +sprite_dy + .byte 4, 3, 2, 1, 4, 3, 2, 1 + +sprite_diry + .byte 1, 1, 1, 1, -1, -1, -1, -1 + + + +.include cpbg-sprite-driver.s +.include drawfont.s +.include fatfont.s diff --git a/drawfont.s b/drawfont.s new file mode 100644 index 0000000..4069587 --- /dev/null +++ b/drawfont.s @@ -0,0 +1,113 @@ +DrawHexByte + PHA ; save low nibble + ROR ; shift high nibble + ROR ; to low nibble + ROR ; + ROR ; + JSR DrawHexNib ; print high nib in hex + PLA ; pritn low nib in hex +DrawHexNib + AND #$F ; base 16 + TAX ; + LDA NIB2HEX,X ; nibble to ASCII +; ORG $0310 ; Listing 5 +DrawChar + JMP DrawCharCol +; ORG $0313 ; Listing 9 +SetCursorRow + LDA TEXTROW_L,X ; TEXTROW_L[ row ] + STA hgrptr + LDA TEXTROW_H,X ; TEXTROW_H[ row ] + ORA HgrHi + STA hgrptr+1 + RTS +; ORG $0321 ; Listing 11 + + + + +SetCursorColRow + STX hgrptr + LDA TEXTROW_L,Y ; TEXTROW_L[ row ] + CLC + ADC hgrptr ; add column + STA hgrptr + LDA TEXTROW_H,Y ; TEXTROW_H[ row ] + ORA HgrHi + STA hgrptr+1 + RTS + NOP ; pad +; ORG $0335 ; Listing 6 +DrawCharColRow + PHA + JSR SetCursorRow + PLA +; ORG $033A ; Listing 7 +DrawCharCol ; A=%PQRstuvw + ROL ; C=P A=%QRstuvw? + ROL ; C=Q A=%Rstuvw?P + ROL ; C=R A=%stuvw?PQ + TAX ; X=%stuvw?PQ push glyph + AND #$F8 ; A=%stuvw000 + STA _LoadFont+1; AddressLo = (c*8) + TXA ; A=%stuvw?PQ pop glyph + AND #3 ; Optimization: s=0 implicit CLC ! + ROL ; C=s A=%00000PQR and 1 last ROL to get R + ADC #>FatFont ; += FontHi; Carry=0 since s=0 from above + STA _LoadFont+2; AddressHi = FontHi + (c/32) +; ORG $034C ; Listing 4a +_DrawChar1 + LDX hgrptr+1 + STX scratch0 +; ORG $0350 ; Listing 1 +_DrawChar + LDX #7 +_LoadFont ; A = font[ offset ] + LDA FatFont,X + STA (hgrptr),Y ; screen[col] = A + CLC + LDA hgrptr+1 ; + ADC #4 ; screen += 0x400 + STA hgrptr+1 + DEX + BPL _LoadFont +; ORG $0363 ; Listing 4a +IncCursorCol + INY + LDX scratch0 ; Move cursor back to top of scanline + STX hgrptr+1 + RTS +; ORG $0369 ; Listing 10 +SetCursorColRowYX + JSR SetCursorRow + CLC + TYA + ADC hgrptr + STA hgrptr + RTS +; ORG $037E ; Listing 12 +DrawString + STY tempaddr+0 + STX tempaddr+1 + LDY #0 +_ds1 LDA (tempaddr),Y + BEQ _ds2 ; null byte? Done + SEC + SBC #$20 + JSR DrawChar ; or DrawCharCol for speed + CPY #40 ; col < 40? + BCC _ds1 +_ds2 RTS + +; ORG $0390 ; Listing 8 +NIB2HEX + .byte "0123456789ABCDEF" +; ORG $03A0 ; Listing 9a +TEXTROW_L + .byte $00,$80,$00,$80,$00,$80,$00,$80 + .byte $28,$A8,$28,$A8,$28,$A8,$28,$A8 + .byte $50,$D0,$50,$D0,$50,$D0,$50,$D0 +TEXTROW_H + .byte $00,$00,$01,$01,$02,$02,$03,$03 + .byte $00,$00,$01,$01,$02,$02,$03,$03 + .byte $00,$00,$01,$01,$02,$02,$03,$03 diff --git a/fatfont.s b/fatfont.s new file mode 100644 index 0000000..72f0c8b --- /dev/null +++ b/fatfont.s @@ -0,0 +1,194 @@ + *= $1600 +FatFont + .byte $80, $80, $80, $80 + .byte $80, $80, $80, $80 + .byte $80, $87, $87, $80 + .byte $87, $87, $87, $87 + .byte $80, $80, $80, $80 + .byte $b6, $a4, $b6, $b6 + .byte $80, $9e, $9e, $bf + .byte $9e, $bf, $9e, $9e + .byte $80, $8c, $9f, $b0 + .byte $9e, $83, $be, $8c + .byte $80, $bb, $bb, $86 + .byte $8c, $98, $b7, $b7 + .byte $80, $ae, $9b, $bb + .byte $8f, $86, $8f, $86 + .byte $80, $80, $80, $80 + .byte $8c, $88, $8c, $8c + .byte $80, $b8, $9c, $8e + .byte $8e, $8e, $9c, $b8 + .byte $80, $87, $8e, $9c + .byte $9c, $9c, $8e, $87 + .byte $80, $88, $aa, $9c + .byte $be, $9c, $aa, $88 + .byte $80, $80, $8c, $8c + .byte $bf, $bf, $8c, $8c + .byte $83, $86, $87, $80 + .byte $80, $80, $80, $80 + .byte $80, $80, $80, $80 + .byte $be, $be, $80, $80 + .byte $80, $87, $87, $80 + .byte $80, $80, $80, $80 + .byte $80, $83, $87, $8e + .byte $9c, $b8, $f0, $e0 + .byte $80, $9e, $b3, $b3 + .byte $b3, $b3, $b3, $9e + .byte $80, $bf, $8c, $8c + .byte $8c, $8f, $8e, $8c + .byte $80, $bf, $bf, $8e + .byte $38, $b3, $bf, $9e + .byte $80, $9e, $bf, $b0 + .byte $be, $b0, $bf, $9e + .byte $80, $b0, $b0, $bf + .byte $b3, $b6, $bc, $b8 + .byte $80, $9e, $bf, $b0 + .byte $9f, $83, $bf, $bf + .byte $80, $9e, $bf, $b3 + .byte $9f, $83, $bf, $9e + .byte $80, $8c, $8c, $8c + .byte $98, $b0, $bf, $bf + .byte $80, $9e, $bf, $b3 + .byte $9e, $b3, $bf, $9e + .byte $80, $9e, $bf, $b0 + .byte $be, $b3, $bf, $9e + .byte $80, $9c, $9c, $80 + .byte $80, $9c, $9c, $80 + .byte $83, $86, $87, $80 + .byte $80, $87, $87, $80 + .byte $80, $f0, $b8, $9c + .byte $8e, $9c, $b8, $f0 + .byte $80, $80, $80, $be + .byte $80, $be, $80, $80 + .byte $80, $87, $8e, $9c + .byte $b8, $9c, $8e, $87 + .byte $80, $8c, $80, $8c + .byte $98, $b3, $bf, $9e + .byte $80, $be, $83, $bb + .byte $bb, $b3, $b3, $9e + .byte $80, $b3, $b3, $bf + .byte $bf, $b3, $bf, $9e + .byte $80, $9f, $bf, $b3 + .byte $9f, $b3, $bf, $9f + .byte $80, $9e, $bf, $b3 + .byte $83, $b3, $bf, $9e + .byte $80, $9f, $bf, $b3 + .byte $b3, $b3, $bf, $9f + .byte $80, $bf, $bf, $83 + .byte $9f, $83, $bf, $bf + .byte $80, $83, $83, $9f + .byte $9f, $83, $bf, $bf + .byte $80, $9e, $bf, $b3 + .byte $bb, $83, $bf, $9e + .byte $80, $b3, $b3, $bf + .byte $bf, $b3, $b3, $b3 + .byte $80, $bf, $bf, $8c + .byte $8c, $8c, $bf, $bf + .byte $80, $9e, $bf, $b3 + .byte $b0, $b0, $b0, $b0 + .byte $80, $b3, $bb, $9f + .byte $8f, $9f, $bb, $b3 + .byte $80, $bf, $bf, $83 + .byte $83, $83, $83, $83 + .byte $80, $b3, $b3, $b3 + .byte $b3, $b3, $bf, $b3 + .byte $80, $b3, $b3, $bb + .byte $bf, $b7, $b3, $b3 + .byte $80, $9e, $bf, $b3 + .byte $b3, $b3, $bf, $9e + .byte $80, $83, $83, $9f + .byte $bf, $b3, $bf, $9f + .byte $80, $ae, $93, $ab + .byte $a3, $a3, $bf, $9e + .byte $80, $b3, $bb, $9f + .byte $bf, $b3, $bf, $9f + .byte $80, $9e, $bf, $b8 + .byte $9e, $87, $bf, $9e + .byte $80, $8c, $8c, $8c + .byte $8c, $8c, $bf, $bf + .byte $80, $9e, $bf, $b3 + .byte $b3, $b3, $b3, $b3 + .byte $80, $8c, $9e, $b3 + .byte $b3, $b3, $b3, $b3 + .byte $80, $b3, $bf, $b3 + .byte $b3, $b3, $b3, $b3 + .byte $80, $33, $9b, $1e + .byte $8e, $1e, $9b, $33 + .byte $80, $8c, $8c, $8c + .byte $9e, $b3, $b3, $b3 + .byte $80, $bf, $bf, $86 + .byte $8c, $98, $bf, $bf + .byte $80, $bc, $bc, $8c + .byte $8c, $8c, $bc, $bc + .byte $80, $e0, $f0, $b8 + .byte $9c, $8e, $87, $83 + .byte $80, $8f, $8f, $8c + .byte $8c, $8c, $8f, $8f + .byte $80, $80, $80, $80 + .byte $80, $bf, $9e, $8c + .byte $80, $ff, $ff, $80 + .byte $80, $80, $80, $80 + .byte $80, $80, $80, $80 + .byte $80, $98, $8c, $86 + .byte $80, $be, $b3, $be + .byte $b0, $9e, $80, $80 + .byte $80, $9f, $b3, $b3 + .byte $b3, $9f, $83, $83 + .byte $80, $9e, $b3, $83 + .byte $b3, $9e, $80, $80 + .byte $80, $be, $b3, $b3 + .byte $b3, $be, $b0, $b0 + .byte $80, $9e, $83, $9f + .byte $b3, $9e, $80, $80 + .byte $80, $86, $86, $86 + .byte $9f, $86, $b6, $9c + .byte $9e, $b0, $be, $b3 + .byte $b3, $9e, $80, $80 + .byte $80, $b3, $b3, $b3 + .byte $b3, $9f, $83, $83 + .byte $80, $8c, $8c, $8c + .byte $8c, $80, $8c, $80 + .byte $9e, $b3, $b3, $b0 + .byte $b0, $b0, $80, $b0 + .byte $80, $b3, $9b, $8f + .byte $9b, $b3, $83, $83 + .byte $80, $9e, $8c, $8c + .byte $8c, $8c, $8c, $8e + .byte $80, $b3, $b3, $b3 + .byte $bf, $b3, $80, $80 + .byte $80, $b3, $b3, $b3 + .byte $b3, $9f, $80, $80 + .byte $80, $9e, $b3, $b3 + .byte $b3, $9e, $80, $80 + .byte $83, $83, $9f, $b3 + .byte $b3, $9f, $80, $80 + .byte $b0, $b0, $be, $b3 + .byte $b3, $be, $80, $80 + .byte $80, $83, $83, $83 + .byte $b3, $9f, $80, $80 + .byte $80, $9e, $b0, $9e + .byte $83, $9e, $80, $80 + .byte $80, $9c, $b6, $86 + .byte $86, $9f, $86, $86 + .byte $80, $be, $b3, $b3 + .byte $b3, $b3, $80, $80 + .byte $80, $8c, $9e, $b3 + .byte $b3, $b3, $80, $80 + .byte $80, $b3, $bf, $b3 + .byte $b3, $b3, $80, $80 + .byte $80, $b3, $9e, $8c + .byte $9e, $b3, $80, $80 + .byte $9e, $b0, $be, $b3 + .byte $b3, $b3, $80, $80 + .byte $80, $bf, $86, $8c + .byte $98, $bf, $80, $80 + .byte $80, $9c, $9e, $86 + .byte $87, $86, $9e, $9c + .byte $8c, $8c, $8c, $8c + .byte $8c, $8c, $8c, $8c + .byte $80, $8e, $9e, $98 + .byte $b8, $98, $9e, $8e + .byte $80, $80, $80, $80 + .byte $80, $98, $bf, $86 + .byte $00, $00, $00, $00 + .byte $00, $00, $00, $00 diff --git a/fatfont128.dat b/fatfont128.dat new file mode 100644 index 0000000..d8daa9b Binary files /dev/null and b/fatfont128.dat differ