mirror of
https://github.com/robmcmullen/asmgen.git
synced 2025-01-03 13:30:19 +00:00
generateBlitter: restructured to use self.asm and optimization to remove trailing iny when at the end of a row
This commit is contained in:
parent
8951869372
commit
b3a4a5b5b4
151
HiSprite.py
151
HiSprite.py
@ -54,12 +54,13 @@ def slugify(s):
|
|||||||
|
|
||||||
class AssemblerSyntax(object):
|
class AssemblerSyntax(object):
|
||||||
extension = "s"
|
extension = "s"
|
||||||
|
comment_char = ";"
|
||||||
|
|
||||||
def asm(self, text):
|
def asm(self, text):
|
||||||
return "\t%s" % text
|
return "\t%s" % text
|
||||||
|
|
||||||
def comment(self, text):
|
def comment(self, text):
|
||||||
return "\t; %s" % text
|
return "\t%s %s" % (self.comment_char, text)
|
||||||
|
|
||||||
def label(self, text):
|
def label(self, text):
|
||||||
return text
|
return text
|
||||||
@ -132,13 +133,25 @@ class Listing(object):
|
|||||||
fh.write(str(self))
|
fh.write(str(self))
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def out(self, line):
|
def out(self, line=""):
|
||||||
self.flush_stash()
|
self.flush_stash()
|
||||||
self.lines.append(line)
|
self.lines.append(line)
|
||||||
|
|
||||||
def out_append_last(self, line):
|
def out_append_last(self, line):
|
||||||
self.lines[-1] += line
|
self.lines[-1] += line
|
||||||
|
|
||||||
|
def pop_asm(self, cmd=""):
|
||||||
|
self.flush_stash()
|
||||||
|
if cmd:
|
||||||
|
search = self.assembler.asm(cmd)
|
||||||
|
i = -1
|
||||||
|
while self.lines[i].strip().startswith(self.assembler.comment_char):
|
||||||
|
i -= 1
|
||||||
|
if self.lines[i] == search:
|
||||||
|
self.lines.pop(i)
|
||||||
|
else:
|
||||||
|
self.lines.pop(-1)
|
||||||
|
|
||||||
def label(self, text):
|
def label(self, text):
|
||||||
self.out(self.assembler.label(text))
|
self.out(self.assembler.label(text))
|
||||||
|
|
||||||
@ -303,18 +316,9 @@ class Sprite(Listing):
|
|||||||
byteWidth = len(colorStreams[0])
|
byteWidth = len(colorStreams[0])
|
||||||
self.asm("jsr savebg_%dx%d" % (byteWidth, self.height))
|
self.asm("jsr savebg_%dx%d" % (byteWidth, self.height))
|
||||||
self.backing_store_sizes.add((byteWidth, self.height))
|
self.backing_store_sizes.add((byteWidth, self.height))
|
||||||
|
cycleCount += 6
|
||||||
self.asm("ldx PARAM1")
|
|
||||||
cycleCount += 3
|
|
||||||
rowStartCode,extraCycles = self.rowStartCalculatorCode();
|
|
||||||
self.out(rowStartCode)
|
|
||||||
cycleCount += extraCycles
|
|
||||||
|
|
||||||
spriteChunks, cycleCount, optimizationCount = self.generateBlitter(colorStreams, maskStreams, cycleCount)
|
cycleCount, optimizationCount = self.generateBlitter(colorStreams, maskStreams, cycleCount)
|
||||||
|
|
||||||
for row in range(self.height):
|
|
||||||
for chunkIndex in range(len(spriteChunks)):
|
|
||||||
self.out(spriteChunks[chunkIndex][row])
|
|
||||||
|
|
||||||
if self.processor == "any":
|
if self.processor == "any":
|
||||||
self.out(".ifpC02")
|
self.out(".ifpC02")
|
||||||
@ -333,70 +337,83 @@ class Sprite(Listing):
|
|||||||
|
|
||||||
def generateBlitter(self, colorStreams, maskStreams, baseCycleCount):
|
def generateBlitter(self, colorStreams, maskStreams, baseCycleCount):
|
||||||
byteWidth = len(colorStreams[0])
|
byteWidth = len(colorStreams[0])
|
||||||
spriteChunks = [["" for y in range(self.height)] for x in range(byteWidth)]
|
|
||||||
|
|
||||||
cycleCount = baseCycleCount
|
cycleCount = baseCycleCount
|
||||||
optimizationCount = 0
|
optimizationCount = 0
|
||||||
|
|
||||||
for row in range(self.height):
|
for row in range(self.height):
|
||||||
|
cycleCount += self.rowStartCalculatorCode(row)
|
||||||
|
|
||||||
byteSplits = colorStreams[row]
|
byteSplits = colorStreams[row]
|
||||||
maskSplits = maskStreams[row]
|
maskSplits = maskStreams[row]
|
||||||
|
byteCount = len(byteSplits)
|
||||||
# Generate blitting code
|
|
||||||
for chunkIndex in range(len(byteSplits)):
|
|
||||||
|
|
||||||
# Optimization
|
|
||||||
if maskSplits[chunkIndex] == "01111111" and not self.backing_store:
|
|
||||||
optimizationCount += 1
|
|
||||||
else:
|
|
||||||
value = self.binary_constant(byteSplits[chunkIndex])
|
|
||||||
|
|
||||||
# Store byte into video memory
|
# number of trailing iny to remove due to unchanged bytes at the
|
||||||
if self.xdraw:
|
# end of the row
|
||||||
spriteChunks[chunkIndex][row] = \
|
skip_iny = 0
|
||||||
"\tlda (SCRATCH0),y\n" + \
|
|
||||||
"\teor %s\n" % value + \
|
# Generate blitting code
|
||||||
"\tsta (SCRATCH0),y\n";
|
for index, (value, mask) in enumerate(zip(byteSplits, maskSplits)):
|
||||||
cycleCount += 5 + 2 + 6
|
if index > 0:
|
||||||
elif self.use_mask:
|
self.asm("iny")
|
||||||
mask = self.binary_constant(maskSplits[chunkIndex])
|
|
||||||
spriteChunks[chunkIndex][row] = \
|
|
||||||
"\tlda (SCRATCH0),y\n" + \
|
|
||||||
"\tand %s\n" % mask + \
|
|
||||||
"\tora %s\n" % value + \
|
|
||||||
"\tsta (SCRATCH0),y\n";
|
|
||||||
cycleCount += 5 + 2 + 6
|
|
||||||
else:
|
|
||||||
spriteChunks[chunkIndex][row] = \
|
|
||||||
"\tlda %s\n" % value + \
|
|
||||||
"\tsta (SCRATCH0),y\n";
|
|
||||||
cycleCount += 2 + 6
|
|
||||||
|
|
||||||
# Increment indices
|
|
||||||
if chunkIndex == len(byteSplits)-1:
|
|
||||||
spriteChunks[chunkIndex][row] += "\n"
|
|
||||||
else:
|
|
||||||
spriteChunks[chunkIndex][row] += "\tiny"
|
|
||||||
cycleCount += 2
|
cycleCount += 2
|
||||||
|
|
||||||
# Finish the row
|
# Optimization
|
||||||
if row<self.height-1:
|
if mask == "01111111":
|
||||||
rowStartCode, extraCycles = self.rowStartCalculatorCode()
|
optimizationCount += 1
|
||||||
spriteChunks[chunkIndex][row] += "\tinx\n" + rowStartCode;
|
self.comment_line("byte %d: skipping! unchanged byte (mask = %s)" % (index, mask))
|
||||||
cycleCount += 2 + extraCycles
|
skip_iny += 1
|
||||||
|
else:
|
||||||
return spriteChunks, cycleCount, optimizationCount
|
value = self.binary_constant(value)
|
||||||
|
skip_iny = 0
|
||||||
|
# Store byte into video memory
|
||||||
|
if self.xdraw:
|
||||||
|
self.asm("lda (SCRATCH0),y")
|
||||||
|
self.asm("eor %s" % value)
|
||||||
|
self.asm("sta (SCRATCH0),y");
|
||||||
|
cycleCount += 5 + 2 + 6
|
||||||
|
elif self.use_mask:
|
||||||
|
if mask == "00000000":
|
||||||
|
# replacing all the bytes; no need for and/or!
|
||||||
|
self.asm("lda %s" % value)
|
||||||
|
self.asm("sta (SCRATCH0),y");
|
||||||
|
cycleCount += 2 + 5
|
||||||
|
else:
|
||||||
|
mask = self.binary_constant(mask)
|
||||||
|
self.asm("lda (SCRATCH0),y")
|
||||||
|
self.asm("and %s" % mask)
|
||||||
|
self.asm("ora %s" % value)
|
||||||
|
self.asm("sta (SCRATCH0),y");
|
||||||
|
cycleCount += 5 + 2 + 2 + 6
|
||||||
|
else:
|
||||||
|
self.asm("lda %s" % value)
|
||||||
|
self.asm("sta (SCRATCH0),y");
|
||||||
|
cycleCount += 2 + 6
|
||||||
|
|
||||||
def rowStartCalculatorCode(self):
|
while skip_iny > 0:
|
||||||
return \
|
self.pop_asm("iny")
|
||||||
"\tlda HGRROWS_H1,x\n" + \
|
skip_iny -= 1
|
||||||
"\tsta SCRATCH1\n" + \
|
cycleCount -= 2
|
||||||
"\tlda HGRROWS_L,x\n" + \
|
|
||||||
"\tsta SCRATCH0\n" + \
|
return cycleCount, optimizationCount
|
||||||
"\tldy PARAM0\n" + \
|
|
||||||
"\tlda DIV%d_%d,y\n" % (self.screen.numShifts, self.screen.bitsPerPixel) + \
|
def rowStartCalculatorCode(self, row):
|
||||||
"\ttay\n", 4 + 3 + 4 + 3 + 3 + 4 + 2;
|
self.out()
|
||||||
|
self.comment_line("row %d" % row)
|
||||||
|
if row == 0:
|
||||||
|
self.asm("ldx PARAM1")
|
||||||
|
cycles = 3
|
||||||
|
else:
|
||||||
|
self.asm("inx")
|
||||||
|
cycles = 2
|
||||||
|
self.asm("lda HGRROWS_H1,x")
|
||||||
|
self.asm("sta SCRATCH1")
|
||||||
|
self.asm("lda HGRROWS_L,x")
|
||||||
|
self.asm("sta SCRATCH0")
|
||||||
|
self.asm("ldy PARAM0")
|
||||||
|
self.asm("lda DIV%d_%d,y" % (self.screen.numShifts, self.screen.bitsPerPixel))
|
||||||
|
self.asm("tay")
|
||||||
|
return cycles + 4 + 3 + 4 + 3 + 3 + 4 + 2;
|
||||||
|
|
||||||
|
|
||||||
def shiftStringRight(string, shift, bitsPerPixel, fillerBit):
|
def shiftStringRight(string, shift, bitsPerPixel, fillerBit):
|
||||||
@ -698,7 +715,7 @@ if __name__ == "__main__":
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
listings = []
|
listings = []
|
||||||
luts = {}
|
luts = {} # dict of lookup tables to prevent duplication in output files
|
||||||
|
|
||||||
for pngfile in options.files:
|
for pngfile in options.files:
|
||||||
try:
|
try:
|
||||||
|
BIN
multitest.dsk
BIN
multitest.dsk
Binary file not shown.
Loading…
Reference in New Issue
Block a user