mirror of
https://github.com/robmcmullen/asmgen.git
synced 2025-04-05 06:37:44 +00:00
Added multi-file generation in one step using a prefix
* changed testcase to use second type of sprite * added hand-coded 3x8 backing store
This commit is contained in:
parent
6c794b855e
commit
8951869372
69
HiSprite.py
69
HiSprite.py
@ -53,6 +53,8 @@ def slugify(s):
|
||||
|
||||
|
||||
class AssemblerSyntax(object):
|
||||
extension = "s"
|
||||
|
||||
def asm(self, text):
|
||||
return "\t%s" % text
|
||||
|
||||
@ -74,6 +76,9 @@ class AssemblerSyntax(object):
|
||||
def origin(self, text):
|
||||
return self.asm("*= %s" % text)
|
||||
|
||||
def include(self, text):
|
||||
return self.asm(".include \"%s\"" % text)
|
||||
|
||||
def binary_constant(self, value):
|
||||
try:
|
||||
# already a string
|
||||
@ -97,6 +102,8 @@ class Mac65(AssemblerSyntax):
|
||||
|
||||
|
||||
class CC65(AssemblerSyntax):
|
||||
extension = "s"
|
||||
|
||||
def label(self, text):
|
||||
return "%s:" % text
|
||||
|
||||
@ -108,11 +115,23 @@ class Listing(object):
|
||||
self.current = None
|
||||
self.desired_count = 1
|
||||
self.stash_list = []
|
||||
self.slug = "sprite-driver"
|
||||
|
||||
def __str__(self):
|
||||
self.flush_stash()
|
||||
return "\n".join(self.lines) + "\n"
|
||||
|
||||
def get_filename(self, basename):
|
||||
return "%s-%s.%s" % (basename, self.slug.lower(), self.assembler.extension)
|
||||
|
||||
def write(self, basename, disclaimer):
|
||||
filename = self.get_filename(basename)
|
||||
print("Writing to %s" % filename)
|
||||
with open(filename, "w") as fh:
|
||||
fh.write(disclaimer + "\n\n")
|
||||
fh.write(str(self))
|
||||
return filename
|
||||
|
||||
def out(self, line):
|
||||
self.flush_stash()
|
||||
self.lines.append(line)
|
||||
@ -135,6 +154,9 @@ class Listing(object):
|
||||
def addr(self, text):
|
||||
self.out(self.assembler.address(text))
|
||||
|
||||
def include(self, text):
|
||||
self.out(self.assembler.include(text))
|
||||
|
||||
def flush_stash(self):
|
||||
if self.current is not None and len(self.stash_list) > 0:
|
||||
self.lines.append(self.current(", ".join(self.stash_list)))
|
||||
@ -166,6 +188,8 @@ class Listing(object):
|
||||
|
||||
|
||||
class Sprite(Listing):
|
||||
backing_store_sizes = set()
|
||||
|
||||
def __init__(self, pngfile, assembler, screen, xdraw=False, use_mask=False, backing_store=False, processor="any", name=""):
|
||||
Listing.__init__(self, assembler)
|
||||
self.screen = screen
|
||||
@ -179,7 +203,7 @@ class Sprite(Listing):
|
||||
self.processor = processor
|
||||
if not name:
|
||||
name = os.path.splitext(pngfile)[0]
|
||||
self.niceName = slugify(name)
|
||||
self.slug = slugify(name)
|
||||
self.width = pngdata[0]
|
||||
self.height = pngdata[1]
|
||||
self.pixelData = list(pngdata[2])
|
||||
@ -189,7 +213,7 @@ class Sprite(Listing):
|
||||
|
||||
def jumpTable(self):
|
||||
# Prologue
|
||||
self.label("%s" % self.niceName)
|
||||
self.label("%s" % self.slug)
|
||||
self.comment("%d bytes per row" % self.screen.byteWidth(self.width))
|
||||
|
||||
if self.processor == "any":
|
||||
@ -234,13 +258,13 @@ class Sprite(Listing):
|
||||
self.asm("ldy PARAM0")
|
||||
self.asm("ldx MOD%d_%d,y" % (self.screen.numShifts, self.screen.bitsPerPixel))
|
||||
|
||||
self.asm("jmp (%s_JMP,x)\n" % (self.niceName))
|
||||
self.asm("jmp (%s_JMP,x)\n" % (self.slug))
|
||||
offset_suffix = ""
|
||||
|
||||
# Bit-shift jump table for 65C02
|
||||
self.label("%s_JMP" % (self.niceName))
|
||||
self.label("%s_JMP" % (self.slug))
|
||||
for shift in range(self.screen.numShifts):
|
||||
self.addr("%s_SHIFT%d" % (self.niceName, shift))
|
||||
self.addr("%s_SHIFT%d" % (self.slug, shift))
|
||||
|
||||
def jump6502(self):
|
||||
self.save_axy_6502()
|
||||
@ -248,16 +272,16 @@ class Sprite(Listing):
|
||||
self.asm("ldx MOD%d_%d,y" % (self.screen.numShifts, self.screen.bitsPerPixel))
|
||||
|
||||
# Fast jump table routine; faster and smaller than self-modifying code
|
||||
self.asm("lda %s_JMP+1,x" % (self.niceName))
|
||||
self.asm("lda %s_JMP+1,x" % (self.slug))
|
||||
self.asm("pha")
|
||||
self.asm("lda %s_JMP,x" % (self.niceName))
|
||||
self.asm("lda %s_JMP,x" % (self.slug))
|
||||
self.asm("pha")
|
||||
self.asm("rts\n")
|
||||
|
||||
# Bit-shift jump table for generic 6502
|
||||
self.label("%s_JMP" % (self.niceName))
|
||||
self.label("%s_JMP" % (self.slug))
|
||||
for shift in range(self.screen.numShifts):
|
||||
self.addr("%s_SHIFT%d-1" % (self.niceName,shift))
|
||||
self.addr("%s_SHIFT%d-1" % (self.slug,shift))
|
||||
|
||||
def blitShift(self, shift):
|
||||
# Blitting functions
|
||||
@ -267,7 +291,7 @@ class Sprite(Listing):
|
||||
# SAVE_AXY + RESTORE_AXY + rts + sprite jump table
|
||||
cycleCount = 9 + 12 + 6 + 3 + 4 + 6
|
||||
|
||||
self.label("%s_SHIFT%d" % (self.niceName,shift))
|
||||
self.label("%s_SHIFT%d" % (self.slug,shift))
|
||||
|
||||
colorStreams = self.screen.byteStreamsFromPixels(shift, self)
|
||||
maskStreams = self.screen.byteStreamsFromPixels(shift, self, True)
|
||||
@ -278,6 +302,7 @@ class Sprite(Listing):
|
||||
if self.backing_store:
|
||||
byteWidth = len(colorStreams[0])
|
||||
self.asm("jsr savebg_%dx%d" % (byteWidth, self.height))
|
||||
self.backing_store_sizes.add((byteWidth, self.height))
|
||||
|
||||
self.asm("ldx PARAM1")
|
||||
cycleCount += 3
|
||||
@ -594,6 +619,7 @@ class HGRBW(HGR):
|
||||
class RowLookup(Listing):
|
||||
def __init__(self, assembler, screen):
|
||||
Listing.__init__(self, assembler)
|
||||
self.slug = "hgrrows"
|
||||
self.generate_y(screen)
|
||||
|
||||
def generate_y(self, screen):
|
||||
@ -615,6 +641,7 @@ class RowLookup(Listing):
|
||||
class ColLookup(Listing):
|
||||
def __init__(self, assembler, screen):
|
||||
Listing.__init__(self, assembler)
|
||||
self.slug = "hgrcols-%dx%d" % (screen.numShifts, screen.bitsPerPixel)
|
||||
self.generate_x(screen)
|
||||
|
||||
def generate_x(self, screen):
|
||||
@ -648,6 +675,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument("-p", "--processor", default="any", choices=["any","6502", "65C02"], help="Processor type (default: %(default)s)")
|
||||
parser.add_argument("-s", "--screen", default="hgrcolor", choices=["hgrcolor","hgrbw"], help="Screen format (default: %(default)s)")
|
||||
parser.add_argument("-n", "--name", default="", help="Name for generated assembly function (default: based on image filename)")
|
||||
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!")
|
||||
options, extra_args = parser.parse_known_args()
|
||||
|
||||
@ -670,6 +698,7 @@ if __name__ == "__main__":
|
||||
sys.exit(1)
|
||||
|
||||
listings = []
|
||||
luts = {}
|
||||
|
||||
for pngfile in options.files:
|
||||
try:
|
||||
@ -680,6 +709,13 @@ if __name__ == "__main__":
|
||||
except png.Error, e:
|
||||
print "%s: %s" % (pngfile, e)
|
||||
sys.exit(1)
|
||||
if options.output_prefix:
|
||||
r = RowLookup(assembler, screen)
|
||||
luts[r.slug] = r
|
||||
c = ColLookup(assembler, screen)
|
||||
luts[c.slug] = c
|
||||
|
||||
listings.extend([luts[k] for k in sorted(luts.keys())])
|
||||
|
||||
if options.rows:
|
||||
listings.append(RowLookup(assembler, screen))
|
||||
@ -688,7 +724,14 @@ if __name__ == "__main__":
|
||||
listings.append(ColLookup(assembler, screen))
|
||||
|
||||
if listings:
|
||||
print disclaimer
|
||||
if options.output_prefix:
|
||||
driver = Listing(assembler)
|
||||
for source in listings:
|
||||
genfile = source.write(options.output_prefix, disclaimer)
|
||||
driver.include(genfile)
|
||||
driver.write(options.output_prefix, disclaimer)
|
||||
else:
|
||||
print disclaimer
|
||||
|
||||
for section in listings:
|
||||
print section
|
||||
for section in listings:
|
||||
print section
|
||||
|
@ -28,7 +28,10 @@ colortest.dsk: HiSprite.py colortest.s bwsprite.s
|
||||
atasm -ocolortest.xex colortest.s -Lcolortest.var -gcolortest.lst
|
||||
atrcopy colortest.dsk boot -b colortest.xex --brun 6000 -f
|
||||
|
||||
multitest.dsk: HiSprite.py multitest.s colorsprite.s bwsprite.s
|
||||
multitest-sprite-driver.s: HiSprite.py $(BWSPRITE)
|
||||
python HiSprite.py -a mac65 -p 6502 -s hgrbw -m -b -o multitest $(BWSPRITE) $(COLORSPRITE)
|
||||
|
||||
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
|
||||
|
||||
@ -36,4 +39,4 @@ 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
|
||||
rm -f multitest.dsk multitest.xex multitest.var multitest.lst multitest-sprite-driver.s multitest-bwsprite.s multitest-hgrcols-7x1.s multitest-hgrrows.s
|
||||
|
@ -26,6 +26,7 @@
|
||||
SIZE_3X11 = 2 + 1 + 1 + 3*11
|
||||
|
||||
savebg_3x11
|
||||
; reserve space in the backing store stack
|
||||
sec
|
||||
lda bgstore
|
||||
sbc #SIZE_3X11
|
||||
@ -33,8 +34,9 @@ savebg_3x11
|
||||
lda bgstore+1
|
||||
sbc #0
|
||||
sta bgstore+1
|
||||
ldy #0
|
||||
|
||||
; save the metadata
|
||||
ldy #0
|
||||
lda #<restorebg_3x11
|
||||
sta (bgstore),y
|
||||
iny
|
||||
@ -45,12 +47,13 @@ savebg_3x11
|
||||
sta (bgstore),y
|
||||
iny
|
||||
lda PARAM1
|
||||
sta bgline
|
||||
sta SCRATCH0
|
||||
sta (bgstore),y
|
||||
iny
|
||||
|
||||
savebg_3x11_line
|
||||
ldx bgline ; Calculate Y line
|
||||
; save a line, starting from the topmost and working down
|
||||
ldx SCRATCH0 ; Calculate Y line
|
||||
|
||||
lda HGRROWS_H1,x ; Compute hires row
|
||||
sta savebg_3x11_col0+2
|
||||
@ -80,7 +83,7 @@ savebg_3x11_col2
|
||||
sta (bgstore),y
|
||||
iny
|
||||
|
||||
inc bgline
|
||||
inc SCRATCH0
|
||||
|
||||
cpy #SIZE_3X11
|
||||
bcc savebg_3x11_line
|
||||
@ -131,3 +134,116 @@ restorebg_3x11_col2
|
||||
cpy #SIZE_3X11
|
||||
bcc restorebg_3x11
|
||||
rts
|
||||
|
||||
|
||||
SIZE_3X8 = 2 + 1 + 1 + 3*8
|
||||
|
||||
savebg_3X8
|
||||
; reserve space in the backing store stack
|
||||
sec
|
||||
lda bgstore
|
||||
sbc #SIZE_3X8
|
||||
sta bgstore
|
||||
lda bgstore+1
|
||||
sbc #0
|
||||
sta bgstore+1
|
||||
|
||||
; save the metadata
|
||||
ldy #0
|
||||
lda #<restorebg_3X8
|
||||
sta (bgstore),y
|
||||
iny
|
||||
lda #>restorebg_3X8
|
||||
sta (bgstore),y
|
||||
iny
|
||||
lda PARAM0
|
||||
sta (bgstore),y
|
||||
iny
|
||||
lda PARAM1
|
||||
sta SCRATCH0
|
||||
sta (bgstore),y
|
||||
iny
|
||||
|
||||
savebg_3X8_line
|
||||
; save a line, starting from the topmost and working down
|
||||
ldx SCRATCH0 ; Calculate Y line
|
||||
|
||||
lda HGRROWS_H1,x ; Compute hires row
|
||||
sta savebg_3X8_col0+2
|
||||
sta savebg_3X8_col1+2
|
||||
sta savebg_3X8_col2+2
|
||||
lda HGRROWS_L,x
|
||||
sta savebg_3X8_col0+1
|
||||
sta savebg_3X8_col1+1
|
||||
sta savebg_3X8_col2+1
|
||||
|
||||
ldx PARAM0 ; Compute hires column
|
||||
lda DIV7_1,x
|
||||
tax
|
||||
|
||||
savebg_3X8_col0
|
||||
lda $2000,x
|
||||
sta (bgstore),y
|
||||
iny
|
||||
inx
|
||||
savebg_3X8_col1
|
||||
lda $2000,x
|
||||
sta (bgstore),y
|
||||
iny
|
||||
inx
|
||||
savebg_3X8_col2
|
||||
lda $2000,x
|
||||
sta (bgstore),y
|
||||
iny
|
||||
|
||||
inc SCRATCH0
|
||||
|
||||
cpy #SIZE_3X8
|
||||
bcc savebg_3X8_line
|
||||
|
||||
rts
|
||||
|
||||
; bgstore will be pointing right to the data to be blitted back to the screen,
|
||||
; which is 4 bytes into the bgstore array. Everything before the data will have
|
||||
; already been pulled off by the driver in order to figure out which restore
|
||||
; routine to call. Y will be 4 upon entry, and PARAM0 and PARAM1 will be
|
||||
; filled with the x & y values.
|
||||
;
|
||||
; also, no need to save registers because this is being called from a driver
|
||||
; that will do all of that.
|
||||
restorebg_3X8
|
||||
ldx PARAM1 ; Calculate Y line
|
||||
|
||||
lda HGRROWS_H1,x ; Compute hires row
|
||||
sta restorebg_3X8_col0+2
|
||||
sta restorebg_3X8_col1+2
|
||||
sta restorebg_3X8_col2+2
|
||||
lda HGRROWS_L,x
|
||||
sta restorebg_3X8_col0+1
|
||||
sta restorebg_3X8_col1+1
|
||||
sta restorebg_3X8_col2+1
|
||||
|
||||
ldx PARAM0 ; Compute hires column
|
||||
lda DIV7_1,x
|
||||
tax
|
||||
|
||||
lda (bgstore),y
|
||||
restorebg_3X8_col0
|
||||
sta $2000,x
|
||||
iny
|
||||
inx
|
||||
lda (bgstore),y
|
||||
restorebg_3X8_col1
|
||||
sta $2000,x
|
||||
iny
|
||||
inx
|
||||
lda (bgstore),y
|
||||
restorebg_3X8_col2
|
||||
sta $2000,x
|
||||
iny
|
||||
|
||||
inc PARAM1
|
||||
|
||||
cpy #SIZE_3X8
|
||||
bcc restorebg_3X8
|
||||
rts
|
||||
|
@ -48,8 +48,8 @@ restorebg_jsr
|
||||
jsr $ffff
|
||||
|
||||
clc
|
||||
lda bgstore
|
||||
adc #SIZE_3X11
|
||||
tya ; y contains the number of bytes processed
|
||||
adc bgstore
|
||||
sta bgstore
|
||||
lda bgstore+1
|
||||
adc #0
|
||||
|
BIN
multitest.dsk
BIN
multitest.dsk
Binary file not shown.
17
multitest.s
17
multitest.s
@ -21,10 +21,9 @@ SCRATCH0 = $19
|
||||
SCRATCH1 = $1a
|
||||
SPRITEPTR_L = $1b
|
||||
SPRITEPTR_H = $1c
|
||||
BGSTORE = $fa
|
||||
|
||||
BGTOP = $c0 ; page number of first byte beyond top of backing store stack
|
||||
bgstore = $80
|
||||
bgline = $82
|
||||
|
||||
; constants
|
||||
MAXPOSX = 250
|
||||
@ -204,10 +203,10 @@ sprite_active
|
||||
.byte 1, 1, 1, 1, 1, 1, 1, 1, $ff ; 1 = active, 0 = skip, $ff = end of list
|
||||
|
||||
sprite_l
|
||||
.byte <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE
|
||||
.byte <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <MOLDY_BURGER, <MOLDY_BURGER
|
||||
|
||||
sprite_h
|
||||
.byte >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE
|
||||
.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
|
||||
@ -229,10 +228,6 @@ sprite_diry
|
||||
|
||||
|
||||
|
||||
.include colorsprite.s
|
||||
.include bwsprite.s
|
||||
.include rowlookup.s
|
||||
.include collookupbw.s
|
||||
.include collookupcolor.s
|
||||
.include backingstore.s
|
||||
.include backingstore-3x11.s
|
||||
.include multitest-sprite-driver.s
|
||||
.include backingstore.s
|
||||
.include backingstore-3x11.s
|
||||
|
Loading…
x
Reference in New Issue
Block a user