From 35a33f86e13bb5243a6c424b5d1d335f2edac670 Mon Sep 17 00:00:00 2001 From: Rob McMullen Date: Tue, 24 Jul 2018 19:20:14 -0700 Subject: [PATCH] Added support for arbitrarily wide and tall tiles * common usage is probably 2x2 tiles, but can handle bigger --- asmgen.py | 73 +- demo/transposed_fonts/Makefile | 20 +- .../transposed_fonts/asmsgen_font_compare.dsk | Bin 143360 -> 143360 bytes demo/transposed_fonts/driver_2x2_tiles.s | 111 + demo/transposed_fonts/driver_4x4_tiles.s | 113 + .../transposed_fonts/test3--transposed_font.s | 400 ++-- demo/transposed_fonts/tiles2x2a.s | 953 +++++++++ demo/transposed_fonts/tiles4x4a.s | 1851 +++++++++++++++++ tiles/tiles_ramp_2x2.dat | Bin 0 -> 1024 bytes tiles/tiles_ramp_4x4.dat | Bin 0 -> 2048 bytes 10 files changed, 3291 insertions(+), 230 deletions(-) create mode 100644 demo/transposed_fonts/driver_2x2_tiles.s create mode 100644 demo/transposed_fonts/driver_4x4_tiles.s create mode 100644 demo/transposed_fonts/tiles2x2a.s create mode 100644 demo/transposed_fonts/tiles4x4a.s create mode 100644 tiles/tiles_ramp_2x2.dat create mode 100644 tiles/tiles_ramp_4x4.dat diff --git a/asmgen.py b/asmgen.py index fd532fc..fe05f71 100755 --- a/asmgen.py +++ b/asmgen.py @@ -934,15 +934,16 @@ class BackingStoreDriver(Listing): class FastFont(Listing): - def __init__(self, assembler, screen, font, double_buffer): + def __init__(self, assembler, screen, font, double_buffer, byte_width=1, byte_height=8): Listing.__init__(self, assembler) self.slug = "fastfont" - self.generate_table(screen, "H1", 0x2000) + self.row_slug = "TransposedFontRow" + self.generate_table(screen, "H1", 0x2000, byte_width, byte_height) if double_buffer: - self.generate_table(screen, "H2", 0x4000) - self.generate_transposed_font(screen, font) + self.generate_table(screen, "H2", 0x4000, byte_width, byte_height) + self.generate_transposed_font(screen, font, byte_width, byte_height) - def generate_table(self, screen, suffix, hgrbase): + def generate_table(self, screen, suffix, hgrbase, byte_width, byte_height): label = "FASTFONT_%s" % suffix self.label(label) @@ -950,46 +951,51 @@ class FastFont(Listing): # taking the hi/lo bytes of an address - 1 self.comment("A = character, X = column, Y = row; A is clobbered, X&Y are not") self.asm("pha") - self.asm("lda %s_JMP_HI,y" % label) - self.asm("sta %s_JMP+2" % label) - self.asm("lda %s_JMP_LO,y" % label) - self.asm("sta %s_JMP+1" % label) + self.asm(f"lda {label}_JMP_HI,y") + self.asm(f"sta {label}_JMP+2") + self.asm(f"lda {label}_JMP_LO,y") + self.asm(f"sta {label}_JMP+1") self.asm("sty scratch_0") self.asm("pla") self.asm("tay") - self.label("%s_JMP" % label) + self.label(f"{label}_JMP") self.asm("jmp $ffff\n") + num_rows = screen.screen_height // byte_height + # Bit-shift jump table for generic 6502 self.out() - self.label("%s_JMP_HI" % label) - for r in range(24): - self.asm(".byte >%s_%d" % (label, r)) - self.label("%s_JMP_LO" % label) - for r in range(24): - self.asm(".byte <%s_%d" % (label, r)) + self.label(f"{label}_JMP_HI") + for r in range(num_rows): + self.asm(f".byte >{label}_{r}") + self.label(f"{label}_JMP_LO") + for r in range(num_rows): + self.asm(f".byte <{label}_{r}") self.out() hgr1 = screen.generate_row_addresses(hgrbase) - for r in range(24): - self.label("%s_%d" % (label, r)) - for i in range(8): - self.asm("lda TransposedFontRow%d,y" % i) - self.asm("sta $%04x,x" % (hgr1[r*8 + i])) + for r in range(num_rows): + self.label(f"{label}_{r}") + for b in range(byte_width): + for h in range(byte_height): + self.asm(f"lda {self.row_slug}{b}_{h},y") + self.asm("sta $%04x,x" % (hgr1[r*byte_height + h] + b)) self.asm("ldy scratch_0") self.asm("rts") self.out() - def generate_transposed_font(self, screen, font): + def generate_transposed_font(self, screen, font, byte_width, byte_height): with open(font, 'rb') as fh: data = fh.read() num_bytes = len(data) - num_chars = num_bytes // 8 - for r in range(8): - self.label("TransposedFontRow%d" % r) - for i in range(num_chars): - index = i * 8 + r - self.byte("$%02x" % data[index], 16) + char_size = byte_height * byte_width + num_chars = num_bytes // char_size + for h in range(byte_height): + for b in range(byte_width): + self.label(f"{self.row_slug}{b}_{h}") + for i in range(num_chars): + index = i * char_size + (h * byte_width + b) + self.byte("$%02x" % data[index], 16) class CompiledFastFont(Listing): @@ -1522,6 +1528,7 @@ if __name__ == "__main__": parser.add_argument("-d", "--double-buffer", action="store_true", default=False, help="add code blit to either page (default: page 1 only)") parser.add_argument("-g", "--damage", action="store_true", default=False, help="add code to report size of sprite upon return. Can be used in a damage list to restore an area from a pristine source.") parser.add_argument("-f", "--font", action="store", default="", help="generate a fast font blitter for text on the hgr screen using the specified binary font file") + parser.add_argument("--font-size", "--fs", action="store", default="1x8", help="specify font dimensions in bytes (default: %(default)s)") parser.add_argument("--compiled-font", action="store", default="", help="generate a font-compiled fairly fast font blitter for text on the hgr screen using the specified binary font file") parser.add_argument("-o", "--output-prefix", default="", help="Base name to create a set of output files. If not supplied, all code will be sent to stdout.") parser.add_argument("files", metavar="IMAGE", nargs="*", help="a PNG image [or a list of them]. PNG files must not have an alpha channel!") @@ -1603,8 +1610,16 @@ if __name__ == "__main__": if options.cols: listings.append(ColLookup(assembler, screen)) + if options.font_size: + w, h = options.font_size.lower().split("x", 1) + w = int(w) + h = int(h) + else: + w = 1 + h = 8 + if options.font: - listings.append(FastFont(assembler, screen, options.font, options.double_buffer)) + listings.append(FastFont(assembler, screen, options.font, options.double_buffer, w, h)) if options.compiled_font: listings.append(CompiledFastFont(assembler, screen, options.compiled_font, options.double_buffer)) diff --git a/demo/transposed_fonts/Makefile b/demo/transposed_fonts/Makefile index c248e26..2048e5b 100644 --- a/demo/transposed_fonts/Makefile +++ b/demo/transposed_fonts/Makefile @@ -3,7 +3,7 @@ ASSEMBLER = "mac65" ASMGEN = python ../../asmgen.py -TARGETS = TEST1A.BIN TEST1B.BIN TEST1C.BIN TEST1D.BIN TEST2.BIN test3--transposed_font.s TEST3.BIN +TARGETS = TEST1A.BIN TEST1B.BIN TEST1C.BIN TEST1D.BIN TEST2.BIN test3--transposed_font.s TEST3.BIN tiles2x2a.s TILES2X2A.BIN tiles4x4a.s TILES4X4A.BIN all: $(TARGETS) @@ -50,5 +50,23 @@ TEST3.BIN: driver.s test3--transposed_font.s atrcopy . assemble -f -s temp.s -r 0x5000 -o $@ atrcopy asmsgen_font_compare.dsk add $@ -f +tiles2x2a.s: ../../tiles/tiles_ramp_2x2.dat + $(ASMGEN) -a $(ASSEMBLER) -f ../../tiles/tiles_ramp_2x2.dat --fs 2x16 > tiles2x2a.s + +TILES2X2A.BIN: driver_2x2_tiles.s tiles2x2a.s + rm -f $@ + cat $^ > temp.s + atrcopy . assemble -f -s temp.s -r 0x5000 -o $@ + atrcopy asmsgen_font_compare.dsk add $@ -f + +tiles4x4a.s: ../../tiles/tiles_ramp_4x4.dat + $(ASMGEN) -a $(ASSEMBLER) -f ../../tiles/tiles_ramp_4x4.dat --fs 4x32 > tiles4x4a.s + +TILES4X4A.BIN: driver_4x4_tiles.s tiles4x4a.s + rm -f $@ + cat $^ > temp.s + atrcopy . assemble -f -s temp.s -r 0x5000 -o $@ + atrcopy asmsgen_font_compare.dsk add $@ -f + clean: rm -f asmsgen_font_compare.dsk $(TARGETS) temp.s temp.s.lst temp.s.err diff --git a/demo/transposed_fonts/asmsgen_font_compare.dsk b/demo/transposed_fonts/asmsgen_font_compare.dsk index 0695cd3d5f59fef5e4ce61ec85dc8802ee7930ce..d338976806580a4abe7f328562900360dbdb8dd6 100644 GIT binary patch delta 10440 zcmc(kNo*Y1eTUhkcClNc6KAm}mRf6dw>E0uWyMb7B%Zjc+a7zg#KRFqQA#F>vN*d- z(!|Im0){ZMTpkhv4$un*vBn0BcgUgu6WB;5=;}@Y=MoGrhJiqbx%!aFSKpY9?Sp;N z@bY6d`F~_R>V5sOe!BPOrh9L0`eNl@rqU>6_ntGkN97 zH#UCtpQc}V^M#MZN9n^art$C7hkuv;$+s4}AAS4nG;4P{AOFO2&wcV!&wuUDKK7pf z{Hv=USoy-OW_;!9)_UnLL3C*+ZM@M@Si9$z9)$5+Yo@yXS2kNIoi zUd{qOuz+L%$%5jgJacN2TvM8i!SbQ7~~;)I(x<0dY+3Ff(D z=1JyB=1JzcZ{|tn$qVkG?jH8Kheo-FymHV@%({saZsLraU;($x0+IzJ3rOaS8Za1;tO|;y^ zVK;HiO`LKQ=iJ04{~?&?j+rN!Cz&Ui=f0UInI|u~hu!XBf6U9%)N&Jt-NZ3Bamr1c za}zA!mRUgVcN5HW%{+I^Jjp!CJbCHcdq^ZAk%&Yh5{XD8B9VwB7l}k9x+2k)h^|C* zC88@4U5V&QL{}mj648)|hD0o5Q&CFG$f)S z5e#8x)RZlh=xQoB%&b^4T)$-L_;DP648^0UP(kAdLq#iiC&3B=t)FR zB6_PtBodKGL?RK1L?jZCNJJtLi9~cIqAL+yiRem1S0cI+(LERQSFeYzNHj#E!3n<- z8WPcvh=xQoB%&b^4TLg$Rr|@h)g0fiO3`(lZawxUSeH{L?IG|k|-pi zkcdJeid7;~iAW_Pm55X#Qi(_O2kkih7vK9h@nIbB_flEOd>Lg$Rr|@h)g1~l88KHB2kD$p(F~4C?ukgh(aO? zi6~ZyNF^ebh*Tm{iAW_Pm55X#Qi&K!#84uJ5-~g+^C#EBP$Y&TF;o&miO3`(lZZ?r zGKt6}B9n+rA~K06B%+XrLLv%@C?ukgh(aQYl8A|Qo2IwtKl&5T?A((aICA{-`44{h zBOgsa{;6v(%rE}xZ~XS}{gDGt`Rn=ir~Ctc(D$#b-<(%x-ush3Ro~kem_&D$^C{hi-p3E0YBvX=bxS0xOLl){P_EK?B3rxeC*V@OCS2V zU;J3-lUF}|-p3E0YBvXPqD+L$M1h;dc*X_=}ps{r?*URot~bq zPS>WlRVS*I>ST55^Og1gHI)|c^Lg#B-+5l!Rz9!!#P&bs6WfMY{+lPZFQpG(OJhtQ zKKjlRTj#mwuYLL-|M~T={_DTT;>GeQZRSS#l$Mc6Tp|y|f;l6jJOlKDI36I4brPhN;CFY>&!GuCgEkAZV!5|_yXafLh* z>+|Jf;2e26E|cfu%6$14Sif052F{VplgyLMFO-jgb0qU5^9!L;kM&!jvNz6=jkru6 zj4R}9tS^R2ej?8C;Y?g6xueDM5v_i^d_dNEAyjI%ew zOC4@pzv+9UqhDW94RenR$|Vl6jK(h43=- zB=aQmB=fhzR6SlM_s08VBR(b%#>!%tnvIupKAed6$usdWc_CJAhnHDEvVdd($$~rK zWfqXklgyL;1yq8tOAz)6LQ@b93Bpl9I4KBc1>vF~Fwd#qmrDW*c)1mUnC92107f^bd{E(rqj9DC+T=1JyB<~jV#ll;BD#D_~I36))fuul-0 zf^bL>jtas_K{zW27X^WNjy>}v^Ca^m^BjKWN#;rB0b#cw>=%TVARLY>IV2pDgj0fW zP7t^uKwtsKo&_WeNEVRHbNHDjnI|s^!Y)DBCkRbJI3x&11>vM1oE3zNg1|iQKMz>I z;b#HK0+IzBeio1{AXxwiy9HstAhZPGupk^0gj0fWP7t^uKwzF@&pgRI$vnwChoAX7 zA%DOEUR;VL2)hJfpCB{^;gBF46@-(5a8?j53Ig*Se&$K$N#;5B%#+NM%#+M>>~{;o zenDsnLVj2hj>XFy{!@Z*P7t^ujy(%V7LY6;ndjIuPclz3Px?#-2(%P4Hv%n1Mrs6F zih^s6KueL$heRV#QWW!fprx3(8E7dovQ$E#r6@>^KueJ=1X_wEQX|kH%-jkz2pOpn zXb=jnH3AJnwisv-mPn02gD`VD&>&=_Mxa3`xYh_c6+(6=P$4XlDuEiLej`wW%#j*_ z8f1lQjX(`DHy@}$mPw634N|`us6pmPjnLBwv>^3`KnpTQYJ{FfprNSW3N#dRWUdmZ zC{}o(5~wKV76TQ5vV9uxYh_%6mxe16~!{C5tbJ}*h=tAxHv=(FHv=xc<&M(AsVzDDS4gr-JlYJ{dnXljI}Mrdk;rbcLL zguX`TYlOZ==xc=jY|LlxguY7XtAsvpz&AomBeXO^OCz*2LQ5mGG(t-wv^2s%BMdac zKqCw^!aySoG{Qh53^YPZBeZyf=l!Rp5?U&u#XJ0BXlaC&Mrdh-fkqf;gn>pFXoP`A z7-)onMi{IbftIKQK_k!-Epe?8Xo+S(KqDk)^HK@4M8$mB63uYzSwLz8TA~sJjX+CO zf}jy-iHe0lgHwW_5omChxYh_XI5Ql6jX;A_f}jy-a7qv~0u9a**F3M5B&Y-`oDu{U zkQ#v+ssuqJP(v+qtr4i9>KuNJKn+!bpb@B{N)R*xEz~mC8i5w71VJOvLM?Nx5on0& z{QjwkN)l886;TO-MxY`pLC^?PL@SGdil_uZBTx}7bFC4mi0T}EjX*_If}jza8lkBX zni`?05t zfkqf;gn>pFXoP`A7-)o6t`b@*p`{X98lj~TS{k9H5n38ypb-WdVW1HP8eyOj1{z_Y z5eBP9prr!@TDpwX2&qP(q?_UQPfM502U3%EjR z1X@6hKnn;6MXnO4=<2ru6&)Z@(Jhl2fr_ra7^vs~fr@UK)Cg2`fIvkzM`{Erx)rW9 z0u>!bprQkWLL;;_LR%xWH9}h>w2$QF-$ref&{hd;9}-3yVWbg88eyanMjBzH5k?we zq!HR0p{)_x8lkNb+8Uv)5!xD|tr12VVYD~qcW;N0N*Jkxkq-$YjWE&(BaP6}2px^k z(Fh%l(9sATjnL5u9gQ&72xE;f)(B&bFxCiTjWA|DUkGEB&`}8;9}+qmp`#Hx8lj^R zIvSy)5yl!}tP#c^nE4FH zUL{armLT|$K!aI=pb=;=OAs^yHEaojMxcgW=2|0A!`3v`Zu8p{)|yDxvK|LR%xWHNr?Ej5NYXBaAe{NF$6i!bl^G zG(uY=v^7FoBeXR_TO+hJLR%xWH9|g82_uy-QVAoCFwzJkjWE&(BaP6}2px^k(Fh%l z(9sATjnL5u9gQ&72xE;f)(B&bFxCj;TqTTE!dNAAG(txsbTmRoBXl%EMZ$-B{gJ z-CW&L-CCWlR;#t@w%SCkQk$$z)z;P4*EZBP);85P*S6HQ)~0LKTCKM2OZC_PVaH!= zuPiPNrzhY3->-aTd*#nryKdcoeC^*}AHVkX*B<}n-|VQo7rktoc;|Cp{`!~S`CR20 U{uAucpH_BMzEasS`S$kz13V6k`Tzg` delta 63 zcmZp8z|ru4V*}%{%?TeC$U_JL)%{%41Q;{;{vTjq`2QbFASTFONT_H1_0 + .byte >FASTFONT_H1_1 + .byte >FASTFONT_H1_2 + .byte >FASTFONT_H1_3 + .byte >FASTFONT_H1_4 + .byte >FASTFONT_H1_5 + .byte >FASTFONT_H1_6 + .byte >FASTFONT_H1_7 + .byte >FASTFONT_H1_8 + .byte >FASTFONT_H1_9 + .byte >FASTFONT_H1_10 + .byte >FASTFONT_H1_11 +FASTFONT_H1_JMP_LO + .byte FASTFONT_H1_0 + .byte >FASTFONT_H1_1 + .byte >FASTFONT_H1_2 + .byte >FASTFONT_H1_3 + .byte >FASTFONT_H1_4 + .byte >FASTFONT_H1_5 +FASTFONT_H1_JMP_LO + .byte k006*j+uX8kb1mDp?fUf|y1RgYUx5S>ObDTb5l#e=L=jC4vBVKi0*NG% zObV%_kxmAgWRXn{x#W>g0fiJ%%pd+zLMdgGQ$ZzFR8vDOb=1>9BTY2ZLMv^w(?KU) zbkjpGee^THAVUl@!YE^m^N$JsGszUw%rMIw^DMB)63eWx${Oozu*nwN?6Auo`y6n{ l5yzZx${FWeaLEo?xANFG%8`#7awy}d<>;W$oJOKaz literal 0 HcmV?d00001