Since I now have an approved fork rather than contributing back to Quinn, changing to more PEP-8 python style
* changed some assembly variables and categorized them by address to hopefully make debugging easier
This commit is contained in:
parent
e04491e324
commit
527cd2226c
314
HiSprite.py
314
HiSprite.py
|
@ -225,15 +225,15 @@ class Sprite(Listing):
|
||||||
self.slug = slugify(name)
|
self.slug = slugify(name)
|
||||||
self.width = pngdata[0]
|
self.width = pngdata[0]
|
||||||
self.height = pngdata[1]
|
self.height = pngdata[1]
|
||||||
self.pixelData = list(pngdata[2])
|
self.pixel_data = list(pngdata[2])
|
||||||
self.jumpTable()
|
self.jump_table()
|
||||||
for i in range(self.screen.numShifts):
|
for i in range(self.screen.num_shifts):
|
||||||
self.blitShift(i)
|
self.blit_shift(i)
|
||||||
|
|
||||||
def jumpTable(self):
|
def jump_table(self):
|
||||||
# Prologue
|
# Prologue
|
||||||
self.label("%s" % self.slug)
|
self.label("%s" % self.slug)
|
||||||
self.comment("%d bytes per row" % self.screen.byteWidth(self.width))
|
self.comment("%d bytes per row" % self.screen.byte_width(self.width))
|
||||||
|
|
||||||
if self.processor == "any":
|
if self.processor == "any":
|
||||||
self.out(".ifpC02")
|
self.out(".ifpC02")
|
||||||
|
@ -275,22 +275,22 @@ class Sprite(Listing):
|
||||||
def jump65C02(self):
|
def jump65C02(self):
|
||||||
if not self.clobber:
|
if not self.clobber:
|
||||||
self.save_axy_65C02()
|
self.save_axy_65C02()
|
||||||
self.asm("ldy PARAM0")
|
self.asm("ldy param_x")
|
||||||
self.asm("ldx MOD%d_%d,y" % (self.screen.numShifts, self.screen.bitsPerPixel))
|
self.asm("ldx MOD%d_%d,y" % (self.screen.num_shifts, self.screen.bits_per_pixel))
|
||||||
|
|
||||||
self.asm("jmp (%s_JMP,x)\n" % (self.slug))
|
self.asm("jmp (%s_JMP,x)\n" % (self.slug))
|
||||||
offset_suffix = ""
|
offset_suffix = ""
|
||||||
|
|
||||||
# Bit-shift jump table for 65C02
|
# Bit-shift jump table for 65C02
|
||||||
self.label("%s_JMP" % (self.slug))
|
self.label("%s_JMP" % (self.slug))
|
||||||
for shift in range(self.screen.numShifts):
|
for shift in range(self.screen.num_shifts):
|
||||||
self.addr("%s_SHIFT%d" % (self.slug, shift))
|
self.addr("%s_SHIFT%d" % (self.slug, shift))
|
||||||
|
|
||||||
def jump6502(self):
|
def jump6502(self):
|
||||||
if not self.clobber:
|
if not self.clobber:
|
||||||
self.save_axy_6502()
|
self.save_axy_6502()
|
||||||
self.asm("ldy PARAM0")
|
self.asm("ldy param_x")
|
||||||
self.asm("ldx MOD%d_%d,y" % (self.screen.numShifts, self.screen.bitsPerPixel))
|
self.asm("ldx MOD%d_%d,y" % (self.screen.num_shifts, self.screen.bits_per_pixel))
|
||||||
|
|
||||||
# Fast jump table routine; faster and smaller than self-modifying code
|
# Fast jump table routine; faster and smaller than self-modifying code
|
||||||
self.asm("lda %s_JMP+1,x" % (self.slug))
|
self.asm("lda %s_JMP+1,x" % (self.slug))
|
||||||
|
@ -301,33 +301,33 @@ class Sprite(Listing):
|
||||||
|
|
||||||
# Bit-shift jump table for generic 6502
|
# Bit-shift jump table for generic 6502
|
||||||
self.label("%s_JMP" % (self.slug))
|
self.label("%s_JMP" % (self.slug))
|
||||||
for shift in range(self.screen.numShifts):
|
for shift in range(self.screen.num_shifts):
|
||||||
self.addr("%s_SHIFT%d-1" % (self.slug,shift))
|
self.addr("%s_SHIFT%d-1" % (self.slug,shift))
|
||||||
|
|
||||||
def blitShift(self, shift):
|
def blit_shift(self, shift):
|
||||||
# Blitting functions
|
# Blitting functions
|
||||||
self.out("\n")
|
self.out("\n")
|
||||||
|
|
||||||
# Track cycle count of the blitter. We start with fixed overhead:
|
# Track cycle count of the blitter. We start with fixed overhead:
|
||||||
# SAVE_AXY + RESTORE_AXY + rts + sprite jump table
|
# SAVE_AXY + RESTORE_AXY + rts + sprite jump table
|
||||||
cycleCount = 9 + 12 + 6 + 3 + 4 + 6
|
cycle_count = 9 + 12 + 6 + 3 + 4 + 6
|
||||||
|
|
||||||
baselabel = "%s_SHIFT%d" % (self.slug,shift)
|
baselabel = "%s_SHIFT%d" % (self.slug,shift)
|
||||||
self.label(baselabel)
|
self.label(baselabel)
|
||||||
|
|
||||||
colorStreams = self.screen.byteStreamsFromPixels(shift, self)
|
color_streams = self.screen.byte_streams_from_pixels(shift, self)
|
||||||
maskStreams = self.screen.byteStreamsFromPixels(shift, self, True)
|
mask_streams = self.screen.byte_streams_from_pixels(shift, self, True)
|
||||||
for c, m in zip(colorStreams, maskStreams):
|
for c, m in zip(color_streams, mask_streams):
|
||||||
self.comment_line(str(c) + " " + str(m))
|
self.comment_line(str(c) + " " + str(m))
|
||||||
self.out("")
|
self.out("")
|
||||||
|
|
||||||
if self.backing_store:
|
if self.backing_store:
|
||||||
byteWidth = len(colorStreams[0])
|
byte_width = len(color_streams[0])
|
||||||
self.asm("jsr savebg_%dx%d" % (byteWidth, self.height))
|
self.asm("jsr savebg_%dx%d" % (byte_width, self.height))
|
||||||
self.backing_store_sizes.add((byteWidth, self.height))
|
self.backing_store_sizes.add((byte_width, self.height))
|
||||||
cycleCount += 6
|
cycle_count += 6
|
||||||
|
|
||||||
cycleCount, optimizationCount = self.generateBlitter(colorStreams, maskStreams, cycleCount, baselabel)
|
cycle_count, optimization_count = self.generate_blitter(color_streams, mask_streams, cycle_count, baselabel)
|
||||||
|
|
||||||
if not self.clobber:
|
if not self.clobber:
|
||||||
if self.processor == "any":
|
if self.processor == "any":
|
||||||
|
@ -343,46 +343,46 @@ class Sprite(Listing):
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Processor %s not supported" % self.processor)
|
raise RuntimeError("Processor %s not supported" % self.processor)
|
||||||
if self.damage:
|
if self.damage:
|
||||||
# the caller knows PARAM0 and PARAM1 for location, so no need to
|
# the caller knows param_x and param_y for location, so no need
|
||||||
# report those again. But the size varies by sprite (and perhaps by
|
# to report those again. But the size varies by sprite (and perhaps
|
||||||
# shift amount?) so store it here
|
# by shift amount?) so store it here
|
||||||
byteWidth = len(colorStreams[0])
|
byte_width = len(color_streams[0])
|
||||||
self.asm("lda #%d" % byteWidth)
|
self.asm("lda #%d" % byte_width)
|
||||||
self.asm("sta DAMAGE_W")
|
self.asm("sta DAMAGE_W")
|
||||||
self.asm("lda #%d" % self.height)
|
self.asm("lda #%d" % self.height)
|
||||||
self.asm("sta DAMAGE_H")
|
self.asm("sta DAMAGE_H")
|
||||||
self.out()
|
self.out()
|
||||||
self.asm("rts")
|
self.asm("rts")
|
||||||
self.comment("Cycle count: %d, Optimized %d rows." % (cycleCount,optimizationCount))
|
self.comment("Cycle count: %d, Optimized %d rows." % (cycle_count,optimization_count))
|
||||||
|
|
||||||
def generateBlitter(self, colorStreams, maskStreams, baseCycleCount, baselabel):
|
def generate_blitter(self, color_streams, mask_streams, base_cycle_count, baselabel):
|
||||||
byteWidth = len(colorStreams[0])
|
byte_width = len(color_streams[0])
|
||||||
|
|
||||||
cycleCount = baseCycleCount
|
cycle_count = base_cycle_count
|
||||||
optimizationCount = 0
|
optimization_count = 0
|
||||||
|
|
||||||
order = list(range(self.height))
|
order = list(range(self.height))
|
||||||
|
|
||||||
for row in order:
|
for row in order:
|
||||||
cycleCount += self.rowStartCalculatorCode(row, baselabel)
|
cycle_count += self.row_start_calculator_code(row, baselabel)
|
||||||
|
|
||||||
byteSplits = colorStreams[row]
|
byte_splits = color_streams[row]
|
||||||
maskSplits = maskStreams[row]
|
mask_splits = mask_streams[row]
|
||||||
byteCount = len(byteSplits)
|
byte_count = len(byte_splits)
|
||||||
|
|
||||||
# number of trailing iny to remove due to unchanged bytes at the
|
# number of trailing iny to remove due to unchanged bytes at the
|
||||||
# end of the row
|
# end of the row
|
||||||
skip_iny = 0
|
skip_iny = 0
|
||||||
|
|
||||||
# Generate blitting code
|
# Generate blitting code
|
||||||
for index, (value, mask) in enumerate(zip(byteSplits, maskSplits)):
|
for index, (value, mask) in enumerate(zip(byte_splits, mask_splits)):
|
||||||
if index > 0:
|
if index > 0:
|
||||||
self.asm("iny")
|
self.asm("iny")
|
||||||
cycleCount += 2
|
cycle_count += 2
|
||||||
|
|
||||||
# Optimization
|
# Optimization
|
||||||
if mask == "01111111":
|
if mask == "01111111":
|
||||||
optimizationCount += 1
|
optimization_count += 1
|
||||||
self.comment_line("byte %d: skipping! unchanged byte (mask = %s)" % (index, mask))
|
self.comment_line("byte %d: skipping! unchanged byte (mask = %s)" % (index, mask))
|
||||||
skip_iny += 1
|
skip_iny += 1
|
||||||
else:
|
else:
|
||||||
|
@ -390,40 +390,40 @@ class Sprite(Listing):
|
||||||
skip_iny = 0
|
skip_iny = 0
|
||||||
# Store byte into video memory
|
# Store byte into video memory
|
||||||
if self.xdraw:
|
if self.xdraw:
|
||||||
self.asm("lda (SCRATCH0),y")
|
self.asm("lda (scratch_addr),y")
|
||||||
self.asm("eor %s" % value)
|
self.asm("eor %s" % value)
|
||||||
self.asm("sta (SCRATCH0),y");
|
self.asm("sta (scratch_addr),y");
|
||||||
cycleCount += 5 + 2 + 6
|
cycle_count += 5 + 2 + 6
|
||||||
elif self.use_mask:
|
elif self.use_mask:
|
||||||
if mask == "00000000":
|
if mask == "00000000":
|
||||||
# replacing all the bytes; no need for and/or!
|
# replacing all the bytes; no need for and/or!
|
||||||
self.asm("lda %s" % value)
|
self.asm("lda %s" % value)
|
||||||
self.asm("sta (SCRATCH0),y");
|
self.asm("sta (scratch_addr),y");
|
||||||
cycleCount += 2 + 5
|
cycle_count += 2 + 5
|
||||||
else:
|
else:
|
||||||
mask = self.binary_constant(mask)
|
mask = self.binary_constant(mask)
|
||||||
self.asm("lda (SCRATCH0),y")
|
self.asm("lda (scratch_addr),y")
|
||||||
self.asm("and %s" % mask)
|
self.asm("and %s" % mask)
|
||||||
self.asm("ora %s" % value)
|
self.asm("ora %s" % value)
|
||||||
self.asm("sta (SCRATCH0),y");
|
self.asm("sta (scratch_addr),y");
|
||||||
cycleCount += 5 + 2 + 2 + 6
|
cycle_count += 5 + 2 + 2 + 6
|
||||||
else:
|
else:
|
||||||
self.asm("lda %s" % value)
|
self.asm("lda %s" % value)
|
||||||
self.asm("sta (SCRATCH0),y");
|
self.asm("sta (scratch_addr),y");
|
||||||
cycleCount += 2 + 6
|
cycle_count += 2 + 6
|
||||||
|
|
||||||
while skip_iny > 0:
|
while skip_iny > 0:
|
||||||
self.pop_asm("iny")
|
self.pop_asm("iny")
|
||||||
skip_iny -= 1
|
skip_iny -= 1
|
||||||
cycleCount -= 2
|
cycle_count -= 2
|
||||||
|
|
||||||
return cycleCount, optimizationCount
|
return cycle_count, optimization_count
|
||||||
|
|
||||||
def rowStartCalculatorCode(self, row, baselabel):
|
def row_start_calculator_code(self, row, baselabel):
|
||||||
self.out()
|
self.out()
|
||||||
self.comment_line("row %d" % row)
|
self.comment_line("row %d" % row)
|
||||||
if row == 0:
|
if row == 0:
|
||||||
self.asm("ldx PARAM1")
|
self.asm("ldx param_y")
|
||||||
cycles = 3
|
cycles = 3
|
||||||
else:
|
else:
|
||||||
cycles = 0
|
cycles = 0
|
||||||
|
@ -435,31 +435,31 @@ class Sprite(Listing):
|
||||||
# and 6th bit
|
# and 6th bit
|
||||||
self.asm("eor HGRSELECT")
|
self.asm("eor HGRSELECT")
|
||||||
cycles += 3
|
cycles += 3
|
||||||
self.asm("sta SCRATCH1")
|
self.asm("sta scratch_addr+1")
|
||||||
self.asm("lda HGRROWS_L+%d,x" % row)
|
self.asm("lda HGRROWS_L+%d,x" % row)
|
||||||
self.asm("sta SCRATCH0")
|
self.asm("sta scratch_addr")
|
||||||
cycles += 3 + 4 + 3
|
cycles += 3 + 4 + 3
|
||||||
if row == 0:
|
if row == 0:
|
||||||
self.asm("ldy PARAM0")
|
self.asm("ldy param_x")
|
||||||
self.asm("lda DIV%d_%d,y" % (self.screen.numShifts, self.screen.bitsPerPixel))
|
self.asm("lda DIV%d_%d,y" % (self.screen.num_shifts, self.screen.bits_per_pixel))
|
||||||
self.asm("sta PARAM2") # save the mod lookup; it doesn't change
|
self.asm("sta scratch_col") # save the mod lookup; it doesn't change
|
||||||
self.asm("tay")
|
self.asm("tay")
|
||||||
cycles += 3 + 4 + 3 + 2
|
cycles += 3 + 4 + 3 + 2
|
||||||
else:
|
else:
|
||||||
self.asm("ldy PARAM2")
|
self.asm("ldy scratch_col")
|
||||||
cycles += 2
|
cycles += 2
|
||||||
return cycles;
|
return cycles;
|
||||||
|
|
||||||
|
|
||||||
def shiftStringRight(string, shift, bitsPerPixel, fillerBit):
|
def shift_string_right(string, shift, bits_per_pixel, filler_bit):
|
||||||
if shift==0:
|
if shift==0:
|
||||||
return string
|
return string
|
||||||
|
|
||||||
shift *= bitsPerPixel
|
shift *= bits_per_pixel
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
for i in range(shift):
|
for i in range(shift):
|
||||||
result += fillerBit
|
result += filler_bit
|
||||||
|
|
||||||
result += string
|
result += string
|
||||||
return result
|
return result
|
||||||
|
@ -467,49 +467,49 @@ def shiftStringRight(string, shift, bitsPerPixel, fillerBit):
|
||||||
|
|
||||||
|
|
||||||
class ScreenFormat(object):
|
class ScreenFormat(object):
|
||||||
numShifts = 8
|
num_shifts = 8
|
||||||
|
|
||||||
bitsPerPixel = 1
|
bits_per_pixel = 1
|
||||||
|
|
||||||
screenWidth = 320
|
screen_width = 320
|
||||||
|
|
||||||
screenHeight = 192
|
screen_height = 192
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.offsets = self.generate_row_offsets()
|
self.offsets = self.generate_row_offsets()
|
||||||
self.numX = self.screenWidth / self.bitsPerPixel
|
self.numX = self.screen_width / self.bits_per_pixel
|
||||||
|
|
||||||
def byteWidth(self, png_width):
|
def byte_width(self, png_width):
|
||||||
return (png_width * self.bitsPerPixel + self.numShifts - 1) // self.numShifts + 1
|
return (png_width * self.bits_per_pixel + self.num_shifts - 1) // self.num_shifts + 1
|
||||||
|
|
||||||
def bitsForColor(self, pixel):
|
def bits_for_color(self, pixel):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def bitsForMask(self, pixel):
|
def bits_for_mask(self, pixel):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def pixelColor(self, pixelData, row, col):
|
def pixel_color(self, pixel_data, row, col):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def generate_row_offsets(self):
|
def generate_row_offsets(self):
|
||||||
offsets = [40 * y for y in range(self.screenHeight)]
|
offsets = [40 * y for y in range(self.screen_height)]
|
||||||
return offsets
|
return offsets
|
||||||
|
|
||||||
def generate_row_addresses(self, baseAddr):
|
def generate_row_addresses(self, base_addr):
|
||||||
addrs = [baseAddr + offset for offset in self.offsets]
|
addrs = [base_addr + offset for offset in self.offsets]
|
||||||
return addrs
|
return addrs
|
||||||
|
|
||||||
|
|
||||||
class HGR(ScreenFormat):
|
class HGR(ScreenFormat):
|
||||||
numShifts = 7
|
num_shifts = 7
|
||||||
|
|
||||||
bitsPerPixel = 2
|
bits_per_pixel = 2
|
||||||
|
|
||||||
screenWidth = 280
|
screen_width = 280
|
||||||
|
|
||||||
black,magenta,green,orange,blue,white,key = range(7)
|
black,magenta,green,orange,blue,white,key = range(7)
|
||||||
|
|
||||||
def bitsForColor(self, pixel):
|
def bits_for_color(self, pixel):
|
||||||
if pixel == self.black or pixel == self.key:
|
if pixel == self.black or pixel == self.key:
|
||||||
return "00"
|
return "00"
|
||||||
else:
|
else:
|
||||||
|
@ -522,27 +522,27 @@ class HGR(ScreenFormat):
|
||||||
# blue or magenta
|
# blue or magenta
|
||||||
return "10"
|
return "10"
|
||||||
|
|
||||||
def bitsForMask(self, pixel):
|
def bits_for_mask(self, pixel):
|
||||||
if pixel == self.key:
|
if pixel == self.key:
|
||||||
return "11"
|
return "11"
|
||||||
|
|
||||||
return "00"
|
return "00"
|
||||||
|
|
||||||
def highBitForColor(self, pixel):
|
def high_bit_for_color(self, pixel):
|
||||||
# Note that we prefer high-bit white because blue fringe is less noticeable than magenta.
|
# Note that we prefer high-bit white because blue fringe is less noticeable than magenta.
|
||||||
highBit = "0"
|
high_bit = "0"
|
||||||
if pixel == self.orange or pixel == self.blue or pixel == self.white:
|
if pixel == self.orange or pixel == self.blue or pixel == self.white:
|
||||||
highBit = "1"
|
high_bit = "1"
|
||||||
|
|
||||||
return highBit
|
return high_bit
|
||||||
|
|
||||||
def highBitForMask(self, pixel):
|
def high_bit_for_mask(self, pixel):
|
||||||
return "0"
|
return "0"
|
||||||
|
|
||||||
def pixelColor(self, pixelData, row, col):
|
def pixel_color(self, pixel_data, row, col):
|
||||||
r = pixelData[row][col*3]
|
r = pixel_data[row][col*3]
|
||||||
g = pixelData[row][col*3+1]
|
g = pixel_data[row][col*3+1]
|
||||||
b = pixelData[row][col*3+2]
|
b = pixel_data[row][col*3+2]
|
||||||
|
|
||||||
rhi = r == 255
|
rhi = r == 255
|
||||||
rlo = r == 0
|
rlo = r == 0
|
||||||
|
@ -568,68 +568,68 @@ class HGR(ScreenFormat):
|
||||||
color = self.key
|
color = self.key
|
||||||
return color
|
return color
|
||||||
|
|
||||||
def byteStreamsFromPixels(self, shift, source, mask=False):
|
def byte_streams_from_pixels(self, shift, source, mask=False):
|
||||||
byteStreams = ["" for x in range(source.height)]
|
byte_streams = ["" for x in range(source.height)]
|
||||||
byteWidth = self.byteWidth(source.width)
|
byte_width = self.byte_width(source.width)
|
||||||
|
|
||||||
if mask:
|
if mask:
|
||||||
bitDelegate = self.bitsForMask
|
bit_delegate = self.bits_for_mask
|
||||||
highBitDelegate = self.highBitForMask
|
high_bit_delegate = self.high_bit_for_mask
|
||||||
fillerBit = "1"
|
filler_bit = "1"
|
||||||
else:
|
else:
|
||||||
bitDelegate = self.bitsForColor
|
bit_delegate = self.bits_for_color
|
||||||
highBitDelegate = self.highBitForColor
|
high_bit_delegate = self.high_bit_for_color
|
||||||
fillerBit = "0"
|
filler_bit = "0"
|
||||||
|
|
||||||
for row in range(source.height):
|
for row in range(source.height):
|
||||||
bitStream = ""
|
bit_stream = ""
|
||||||
highBit = "0"
|
high_bit = "0"
|
||||||
highBitFound = False
|
high_bit_found = False
|
||||||
|
|
||||||
# Compute raw bitstream for row from PNG pixels
|
# Compute raw bitstream for row from PNG pixels
|
||||||
for pixelIndex in range(source.width):
|
for pixel_index in range(source.width):
|
||||||
pixel = self.pixelColor(source.pixelData,row,pixelIndex)
|
pixel = self.pixel_color(source.pixel_data,row,pixel_index)
|
||||||
bitStream += bitDelegate(pixel)
|
bit_stream += bit_delegate(pixel)
|
||||||
|
|
||||||
# Determine palette bit from first non-black pixel on each row
|
# Determine palette bit from first non-black pixel on each row
|
||||||
if not highBitFound and pixel != self.black and pixel != self.key:
|
if not high_bit_found and pixel != self.black and pixel != self.key:
|
||||||
highBit = highBitDelegate(pixel)
|
high_bit = high_bit_delegate(pixel)
|
||||||
highBitFound = True
|
high_bit_found = True
|
||||||
|
|
||||||
# Shift bit stream as needed
|
# Shift bit stream as needed
|
||||||
bitStream = shiftStringRight(bitStream, shift, self.bitsPerPixel, fillerBit)
|
bit_stream = shift_string_right(bit_stream, shift, self.bits_per_pixel, filler_bit)
|
||||||
bitStream = bitStream[:byteWidth*8]
|
bit_stream = bit_stream[:byte_width*8]
|
||||||
|
|
||||||
# Split bitstream into bytes
|
# Split bitstream into bytes
|
||||||
bitPos = 0
|
bit_pos = 0
|
||||||
byteSplits = [0 for x in range(byteWidth)]
|
byte_splits = [0 for x in range(byte_width)]
|
||||||
|
|
||||||
for byteIndex in range(byteWidth):
|
for byte_index in range(byte_width):
|
||||||
remainingBits = len(bitStream) - bitPos
|
remaining_bits = len(bit_stream) - bit_pos
|
||||||
|
|
||||||
bitChunk = ""
|
bit_chunk = ""
|
||||||
|
|
||||||
if remainingBits < 0:
|
if remaining_bits < 0:
|
||||||
bitChunk = fillerBit * 7
|
bit_chunk = filler_bit * 7
|
||||||
else:
|
else:
|
||||||
if remainingBits < 7:
|
if remaining_bits < 7:
|
||||||
bitChunk = bitStream[bitPos:]
|
bit_chunk = bit_stream[bit_pos:]
|
||||||
bitChunk += fillerBit * (7-remainingBits)
|
bit_chunk += filler_bit * (7-remaining_bits)
|
||||||
else:
|
else:
|
||||||
bitChunk = bitStream[bitPos:bitPos+7]
|
bit_chunk = bit_stream[bit_pos:bit_pos+7]
|
||||||
|
|
||||||
bitChunk = bitChunk[::-1]
|
bit_chunk = bit_chunk[::-1]
|
||||||
|
|
||||||
byteSplits[byteIndex] = highBit + bitChunk
|
byte_splits[byte_index] = high_bit + bit_chunk
|
||||||
bitPos += 7
|
bit_pos += 7
|
||||||
|
|
||||||
byteStreams[row] = byteSplits;
|
byte_streams[row] = byte_splits;
|
||||||
|
|
||||||
return byteStreams
|
return byte_streams
|
||||||
|
|
||||||
def generate_row_offsets(self):
|
def generate_row_offsets(self):
|
||||||
offsets = []
|
offsets = []
|
||||||
for y in range(self.screenHeight):
|
for y in range(self.screen_height):
|
||||||
# From Apple Graphics and Arcade Game Design
|
# From Apple Graphics and Arcade Game Design
|
||||||
a = y // 64
|
a = y // 64
|
||||||
d = y - (64 * a)
|
d = y - (64 * a)
|
||||||
|
@ -640,23 +640,23 @@ class HGR(ScreenFormat):
|
||||||
|
|
||||||
|
|
||||||
class HGRBW(HGR):
|
class HGRBW(HGR):
|
||||||
bitsPerPixel = 1
|
bits_per_pixel = 1
|
||||||
|
|
||||||
def bitsForColor(self, pixel):
|
def bits_for_color(self, pixel):
|
||||||
if pixel == self.white:
|
if pixel == self.white:
|
||||||
return "1"
|
return "1"
|
||||||
else:
|
else:
|
||||||
return "0"
|
return "0"
|
||||||
|
|
||||||
def bitsForMask(self, pixel):
|
def bits_for_mask(self, pixel):
|
||||||
if pixel == self.key:
|
if pixel == self.key:
|
||||||
return "1"
|
return "1"
|
||||||
return "0"
|
return "0"
|
||||||
|
|
||||||
def pixelColor(self, pixelData, row, col):
|
def pixel_color(self, pixel_data, row, col):
|
||||||
r = pixelData[row][col*3]
|
r = pixel_data[row][col*3]
|
||||||
g = pixelData[row][col*3+1]
|
g = pixel_data[row][col*3+1]
|
||||||
b = pixelData[row][col*3+2]
|
b = pixel_data[row][col*3+2]
|
||||||
color = self.black
|
color = self.black
|
||||||
|
|
||||||
if abs(r - g) < 16 and abs(g - b) < 16 and r!=0 and r!=255: # Any grayish color is chroma key
|
if abs(r - g) < 16 and abs(g - b) < 16 and r!=0 and r!=255: # Any grayish color is chroma key
|
||||||
|
@ -693,21 +693,21 @@ class RowLookup(Listing):
|
||||||
class ColLookup(Listing):
|
class ColLookup(Listing):
|
||||||
def __init__(self, assembler, screen):
|
def __init__(self, assembler, screen):
|
||||||
Listing.__init__(self, assembler)
|
Listing.__init__(self, assembler)
|
||||||
self.slug = "hgrcols-%dx%d" % (screen.numShifts, screen.bitsPerPixel)
|
self.slug = "hgrcols-%dx%d" % (screen.num_shifts, screen.bits_per_pixel)
|
||||||
self.generate_x(screen)
|
self.generate_x(screen)
|
||||||
|
|
||||||
def generate_x(self, screen):
|
def generate_x(self, screen):
|
||||||
self.out("\n")
|
self.out("\n")
|
||||||
self.label("DIV%d_%d" % (screen.numShifts, screen.bitsPerPixel))
|
self.label("DIV%d_%d" % (screen.num_shifts, screen.bits_per_pixel))
|
||||||
for pixel in range(screen.numX):
|
for pixel in range(screen.numX):
|
||||||
self.byte("$%02x" % ((pixel / screen.numShifts) * screen.bitsPerPixel), screen.numShifts)
|
self.byte("$%02x" % ((pixel / screen.num_shifts) * screen.bits_per_pixel), screen.num_shifts)
|
||||||
|
|
||||||
self.out("\n")
|
self.out("\n")
|
||||||
self.label("MOD%d_%d" % (screen.numShifts, screen.bitsPerPixel))
|
self.label("MOD%d_%d" % (screen.num_shifts, screen.bits_per_pixel))
|
||||||
for pixel in range(screen.numX):
|
for pixel in range(screen.numX):
|
||||||
# This is the index into the jump table, so it's always multiplied
|
# This is the index into the jump table, so it's always multiplied
|
||||||
# by 2
|
# by 2
|
||||||
self.byte("$%02x" % ((pixel % screen.numShifts) * 2), screen.numShifts)
|
self.byte("$%02x" % ((pixel % screen.num_shifts) * 2), screen.num_shifts)
|
||||||
|
|
||||||
|
|
||||||
class BackingStore(Listing):
|
class BackingStore(Listing):
|
||||||
|
@ -752,22 +752,22 @@ class BackingStore(Listing):
|
||||||
self.asm("lda #>%s" % self.restore_label)
|
self.asm("lda #>%s" % self.restore_label)
|
||||||
self.asm("sta (bgstore),y")
|
self.asm("sta (bgstore),y")
|
||||||
self.asm("iny")
|
self.asm("iny")
|
||||||
self.asm("lda PARAM0")
|
self.asm("lda param_x")
|
||||||
self.asm("sta (bgstore),y")
|
self.asm("sta (bgstore),y")
|
||||||
self.asm("iny")
|
self.asm("iny")
|
||||||
self.asm("lda PARAM1")
|
self.asm("lda param_y")
|
||||||
|
|
||||||
# Note that we can't clobber PARAM1 like the restore routine can
|
# Note that we can't clobber param_y like the restore routine can
|
||||||
# because this is called in the sprite drawing routine and these
|
# because this is called in the sprite drawing routine and these
|
||||||
# values must be retained to draw the sprite in the right place!
|
# values must be retained to draw the sprite in the right place!
|
||||||
self.asm("sta SCRATCH0")
|
self.asm("sta scratch_addr")
|
||||||
self.asm("sta (bgstore),y")
|
self.asm("sta (bgstore),y")
|
||||||
self.asm("iny")
|
self.asm("iny")
|
||||||
|
|
||||||
# The unrolled code is taken from Quinn's row sweep backing store
|
# The unrolled code is taken from Quinn's row sweep backing store
|
||||||
# code in a previous version of HiSprite
|
# code in a previous version of HiSprite
|
||||||
|
|
||||||
loop_label, col_label = self.smc_row_col(self.save_label, "SCRATCH0")
|
loop_label, col_label = self.smc_row_col(self.save_label, "scratch_addr")
|
||||||
|
|
||||||
for c in range(self.byte_width):
|
for c in range(self.byte_width):
|
||||||
self.label(col_label % c)
|
self.label(col_label % c)
|
||||||
|
@ -778,7 +778,7 @@ class BackingStore(Listing):
|
||||||
# last loop doesn't need this
|
# last loop doesn't need this
|
||||||
self.asm("inx")
|
self.asm("inx")
|
||||||
|
|
||||||
self.asm("inc SCRATCH0")
|
self.asm("inc scratch_addr")
|
||||||
|
|
||||||
self.asm("cpy #%d" % self.space_needed)
|
self.asm("cpy #%d" % self.space_needed)
|
||||||
self.asm("bcc %s" % loop_label)
|
self.asm("bcc %s" % loop_label)
|
||||||
|
@ -788,7 +788,7 @@ class BackingStore(Listing):
|
||||||
def smc_row_col(self, label, row_var):
|
def smc_row_col(self, label, row_var):
|
||||||
# set up smc for hires column, because the starting column doesn't
|
# set up smc for hires column, because the starting column doesn't
|
||||||
# change when moving to the next row
|
# change when moving to the next row
|
||||||
self.asm("ldx PARAM0")
|
self.asm("ldx param_x")
|
||||||
self.asm("lda DIV7_1,x")
|
self.asm("lda DIV7_1,x")
|
||||||
smc_label = "%s_smc1" % label
|
smc_label = "%s_smc1" % label
|
||||||
self.asm("sta %s+1" % smc_label)
|
self.asm("sta %s+1" % smc_label)
|
||||||
|
@ -815,16 +815,16 @@ class BackingStore(Listing):
|
||||||
# screen, which is 4 bytes into the bgstore array. Everything before
|
# 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
|
# 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,
|
# 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.
|
# and param_x and param_y will be filled with the x & y values.
|
||||||
#
|
#
|
||||||
# also, no need to save registers because this is being called from a
|
# also, no need to save registers because this is being called from a
|
||||||
# driver that will do all of that.
|
# driver that will do all of that.
|
||||||
self.label(self.restore_label)
|
self.label(self.restore_label)
|
||||||
|
|
||||||
# we can clobber the heck out of PARAM1 because we're being called from
|
# we can clobber the heck out of param_y because we're being called from
|
||||||
# the restore driver and when we return we are just going to load it up
|
# the restore driver and when we return we are just going to load it up
|
||||||
# with the next value anyway.
|
# with the next value anyway.
|
||||||
loop_label, col_label = self.smc_row_col(self.restore_label, "PARAM1")
|
loop_label, col_label = self.smc_row_col(self.restore_label, "param_y")
|
||||||
|
|
||||||
for c in range(self.byte_width):
|
for c in range(self.byte_width):
|
||||||
self.asm("lda (bgstore),y")
|
self.asm("lda (bgstore),y")
|
||||||
|
@ -835,7 +835,7 @@ class BackingStore(Listing):
|
||||||
# last loop doesn't need this
|
# last loop doesn't need this
|
||||||
self.asm("inx")
|
self.asm("inx")
|
||||||
|
|
||||||
self.asm("inc PARAM1")
|
self.asm("inc param_y")
|
||||||
self.asm("cpy #%d" % self.space_needed)
|
self.asm("cpy #%d" % self.space_needed)
|
||||||
self.asm("bcc %s" % loop_label)
|
self.asm("bcc %s" % loop_label)
|
||||||
|
|
||||||
|
@ -850,8 +850,8 @@ class BackingStoreDriver(Listing):
|
||||||
# variables used:
|
# variables used:
|
||||||
# bgstore: (lo byte, hi byte) 1 + the first byte of free memory.
|
# bgstore: (lo byte, hi byte) 1 + the first byte of free memory.
|
||||||
# I.e. points just beyond the last byte
|
# I.e. points just beyond the last byte
|
||||||
# PARAM0: (byte) x coord
|
# param_x: (byte) x coord
|
||||||
# PARAM1: (byte) y coord
|
# param_y: (byte) y coord
|
||||||
#
|
#
|
||||||
# everything else is known because the sizes of each erase/restore
|
# everything else is known because the sizes of each erase/restore
|
||||||
# routine are hardcoded because this is a sprite *compiler*.
|
# routine are hardcoded because this is a sprite *compiler*.
|
||||||
|
@ -900,10 +900,10 @@ class BackingStoreDriver(Listing):
|
||||||
self.asm("sta restorebg_jsr_smc+2")
|
self.asm("sta restorebg_jsr_smc+2")
|
||||||
self.asm("iny")
|
self.asm("iny")
|
||||||
self.asm("lda (bgstore),y")
|
self.asm("lda (bgstore),y")
|
||||||
self.asm("sta PARAM0")
|
self.asm("sta param_x")
|
||||||
self.asm("iny ")
|
self.asm("iny ")
|
||||||
self.asm("lda (bgstore),y")
|
self.asm("lda (bgstore),y")
|
||||||
self.asm("sta PARAM1")
|
self.asm("sta param_y")
|
||||||
self.asm("iny")
|
self.asm("iny")
|
||||||
self.label("restorebg_jsr_smc")
|
self.label("restorebg_jsr_smc")
|
||||||
self.asm("jsr $ffff")
|
self.asm("jsr $ffff")
|
||||||
|
@ -942,7 +942,7 @@ class FastFont(Listing):
|
||||||
self.asm("sta %s_JMP+2" % label)
|
self.asm("sta %s_JMP+2" % label)
|
||||||
self.asm("lda %s_JMP_LO,y" % label)
|
self.asm("lda %s_JMP_LO,y" % label)
|
||||||
self.asm("sta %s_JMP+1" % label)
|
self.asm("sta %s_JMP+1" % label)
|
||||||
self.asm("sty FASTFONT_SCRATCH0")
|
self.asm("sty scratch_0")
|
||||||
self.asm("pla")
|
self.asm("pla")
|
||||||
self.asm("tay")
|
self.asm("tay")
|
||||||
self.label("%s_JMP" % label)
|
self.label("%s_JMP" % label)
|
||||||
|
@ -962,9 +962,9 @@ class FastFont(Listing):
|
||||||
for r in range(24):
|
for r in range(24):
|
||||||
self.label("%s_%d" % (label, r))
|
self.label("%s_%d" % (label, r))
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
self.asm("lda TRANSPOSED_FONT_ROW%d,y" % i)
|
self.asm("lda TransposedFontRow%d,y" % i)
|
||||||
self.asm("sta $%04x,x" % (hgr1[r*8 + i]))
|
self.asm("sta $%04x,x" % (hgr1[r*8 + i]))
|
||||||
self.asm("ldy FASTFONT_SCRATCH0")
|
self.asm("ldy scratch_0")
|
||||||
self.asm("rts")
|
self.asm("rts")
|
||||||
self.out()
|
self.out()
|
||||||
|
|
||||||
|
@ -974,7 +974,7 @@ class FastFont(Listing):
|
||||||
num_bytes = len(data)
|
num_bytes = len(data)
|
||||||
num_chars = num_bytes / 8
|
num_chars = num_bytes / 8
|
||||||
for r in range(8):
|
for r in range(8):
|
||||||
self.label("TRANSPOSED_FONT_ROW%d" % r)
|
self.label("TransposedFontRow%d" % r)
|
||||||
for i in range(num_chars):
|
for i in range(num_chars):
|
||||||
index = i * 8 + r
|
index = i * 8 + r
|
||||||
self.byte("$%02x" % ord(data[index]), 16)
|
self.byte("$%02x" % ord(data[index]), 16)
|
||||||
|
|
193
cpbg.s
193
cpbg.s
|
@ -12,35 +12,52 @@ SETHIRES = $c057
|
||||||
COUT = $fded
|
COUT = $fded
|
||||||
ROMWAIT = $fca8
|
ROMWAIT = $fca8
|
||||||
|
|
||||||
; Zero page locations we use (unused by Monitor, Applesoft, or ProDOS)
|
; Zero page locations. Using the whole thing because we aren't using any
|
||||||
PARAM0 = $06
|
; ROM routines
|
||||||
PARAM1 = $07
|
|
||||||
PARAM2 = $08
|
*= $0006
|
||||||
PARAM3 = $09
|
; parameters: these should not be changed by child subroutines
|
||||||
SCRATCH0 = $19
|
param_x .ds 1
|
||||||
SCRATCH1 = $1a
|
param_y .ds 1
|
||||||
SPRITEPTR_L = $1b
|
param_col .ds 1
|
||||||
SPRITEPTR_H = $1c
|
param_row .ds 1
|
||||||
RENDERCOUNT = $ce
|
param_index .ds 1
|
||||||
DRAWPAGE = $d7 ; pos = page1, neg = page2
|
param_count .ds 1
|
||||||
BGSTORE = $fa
|
|
||||||
TEMPADDR = $fc
|
*= $0010
|
||||||
COUNTER1 = $80
|
; scratch areas: these may be modified by child subroutines
|
||||||
HGRHI = $82 ; either $20 or $40, the base of each hgr screen
|
scratch_addr .ds 2
|
||||||
HGRSELECT = $83 ; either $00 or $60, used as xor mask to turn HGRROWS_H1 into address of either page
|
scratch_ptr .ds 2
|
||||||
TEXTPTR = $84
|
scratch_0 .ds 1
|
||||||
HGRPTR = $86
|
scratch_1 .ds 1
|
||||||
TEMPROW = $88
|
scratch_index .ds 1
|
||||||
TEMPCOL = $89
|
scratch_col .ds 1
|
||||||
DAMAGE_W = $8a
|
|
||||||
DAMAGE_H = $8b
|
*= $0020
|
||||||
DAMAGEPTR = $8c
|
; required variables for HiSprite
|
||||||
DAMAGEPTR1 = $8e
|
bgstore .ds 2
|
||||||
DAMAGEINDEX1 = $91
|
damage_w .ds 1
|
||||||
DAMAGEPTR2 = $92
|
damage_h .ds 1
|
||||||
DAMAGEINDEX2 = $94
|
damageptr .ds 2
|
||||||
DAMAGEINDEX = $95
|
damageindex .ds 1
|
||||||
FASTFONT_SCRATCH0 = $96
|
damageptr1 .ds 2
|
||||||
|
damageindex1 .ds 1
|
||||||
|
damageptr2 .ds 2
|
||||||
|
damageindex2 .ds 1
|
||||||
|
hgrhi .ds 1 ; either $20 or $40, the base of each hgr screen
|
||||||
|
hgrselect .ds 1 ; either $00 or $60, used as xor mask for HGRROWS_H1
|
||||||
|
|
||||||
|
*= $0030
|
||||||
|
; global variables for this program
|
||||||
|
rendercount .ds 1
|
||||||
|
drawpage .ds 1 ; pos = page1, neg = page2
|
||||||
|
tempaddr .ds 2
|
||||||
|
counter1 .ds 1
|
||||||
|
textptr .ds 2
|
||||||
|
hgrptr .ds 2
|
||||||
|
temprow .ds 1
|
||||||
|
tempcol .ds 1
|
||||||
|
|
||||||
|
|
||||||
DAMAGEPAGE1 = $bf ; page number of first byte beyond top of backing store stack
|
DAMAGEPAGE1 = $bf ; page number of first byte beyond top of backing store stack
|
||||||
DAMAGEPAGE2 = $be
|
DAMAGEPAGE2 = $be
|
||||||
|
@ -80,16 +97,16 @@ fasttoggle
|
||||||
|
|
||||||
initonce
|
initonce
|
||||||
lda #0
|
lda #0
|
||||||
sta DRAWPAGE
|
sta drawpage
|
||||||
sta DAMAGEINDEX1
|
sta damageindex1
|
||||||
sta DAMAGEINDEX2
|
sta damageindex2
|
||||||
sta DAMAGEPTR
|
sta damageptr
|
||||||
sta DAMAGEPTR1
|
sta damageptr1
|
||||||
sta DAMAGEPTR2
|
sta damageptr2
|
||||||
lda #DAMAGEPAGE1
|
lda #damagepage1
|
||||||
sta DAMAGEPTR+1
|
sta damageptr+1
|
||||||
sta DAMAGEPTR1+1
|
sta damageptr1+1
|
||||||
sta DAMAGEPTR2+1
|
sta damageptr2+1
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,38 +217,38 @@ copytexthgrslow
|
||||||
|
|
||||||
|
|
||||||
pageflip
|
pageflip
|
||||||
lda DRAWPAGE
|
lda drawpage
|
||||||
eor #$80
|
eor #$80
|
||||||
sta DRAWPAGE
|
sta drawpage
|
||||||
bpl pageflip1 ; pos = show 1, draw 2; neg = show 1, draw 1
|
bpl pageflip1 ; pos = show 1, draw 2; neg = show 1, draw 1
|
||||||
bit TXTPAGE2 ; show page 2, work on page 1
|
bit TXTPAGE2 ; show page 2, work on page 1
|
||||||
lda #$00
|
lda #$00
|
||||||
sta HGRSELECT
|
sta hgrselect
|
||||||
lda #$20
|
lda #$20
|
||||||
sta HGRHI
|
sta hgrhi
|
||||||
lda DAMAGEPTR ; save other page's damage pointer
|
lda damageptr ; save other page's damage pointer
|
||||||
sta DAMAGEPTR2
|
sta damageptr2
|
||||||
lda DAMAGEPTR1
|
lda damageptr1
|
||||||
sta DAMAGEPTR
|
sta damageptr
|
||||||
lda DAMAGEPTR1+1
|
lda damageptr1+1
|
||||||
sta DAMAGEPTR+1
|
sta damageptr+1
|
||||||
lda DAMAGEINDEX1
|
lda damageindex1
|
||||||
sta DAMAGEINDEX
|
sta damageindex
|
||||||
rts
|
rts
|
||||||
pageflip1
|
pageflip1
|
||||||
bit TXTPAGE1 ; show page 1, work on page 2
|
bit TXTPAGE1 ; show page 1, work on page 2
|
||||||
lda #$60
|
lda #$60
|
||||||
sta HGRSELECT
|
sta hgrselect
|
||||||
lda #$40
|
lda #$40
|
||||||
sta HGRHI
|
sta hgrhi
|
||||||
lda DAMAGEPTR ; save other page's damage pointer
|
lda damageptr ; save other page's damage pointer
|
||||||
sta DAMAGEPTR1
|
sta damageptr1
|
||||||
lda DAMAGEPTR2
|
lda damageptr2
|
||||||
sta DAMAGEPTR
|
sta damageptr
|
||||||
lda DAMAGEPTR2+1
|
lda damageptr2+1
|
||||||
sta DAMAGEPTR+1
|
sta damageptr+1
|
||||||
lda DAMAGEINDEX2
|
lda damageindex2
|
||||||
sta DAMAGEINDEX
|
sta damageindex
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
@ -247,15 +264,15 @@ restorebg_driver
|
||||||
; Draw sprites by looping through the list of sprites
|
; Draw sprites by looping through the list of sprites
|
||||||
renderstart
|
renderstart
|
||||||
lda #sprite_l - sprite_active
|
lda #sprite_l - sprite_active
|
||||||
sta RENDERCOUNT
|
sta param_count
|
||||||
inc renderroundrobin_smc+1
|
inc renderroundrobin_smc+1
|
||||||
|
|
||||||
renderroundrobin_smc
|
renderroundrobin_smc
|
||||||
ldy #0
|
ldy #0
|
||||||
sty PARAM3
|
sty param_index
|
||||||
|
|
||||||
renderloop
|
renderloop
|
||||||
lda PARAM3
|
lda param_index
|
||||||
and #sprite_l - sprite_active - 1
|
and #sprite_l - sprite_active - 1
|
||||||
tay
|
tay
|
||||||
lda sprite_active,y
|
lda sprite_active,y
|
||||||
|
@ -265,42 +282,42 @@ renderloop
|
||||||
lda sprite_h,y
|
lda sprite_h,y
|
||||||
sta jsrsprite_smc+2
|
sta jsrsprite_smc+2
|
||||||
lda sprite_x,y
|
lda sprite_x,y
|
||||||
sta PARAM0
|
sta param_x
|
||||||
lda sprite_y,y
|
lda sprite_y,y
|
||||||
sta PARAM1
|
sta param_y
|
||||||
jmp jsrsprite_smc
|
jmp jsrsprite_smc
|
||||||
jsrsprite_smc
|
jsrsprite_smc
|
||||||
jsr $ffff ; wish you could JSR ($nnnn)
|
jsr $ffff ; wish you could JSR ($nnnn)
|
||||||
|
|
||||||
ldy DAMAGEINDEX
|
ldy damageindex
|
||||||
lda PARAM2 ; contains the byte index into the line
|
lda scratch_col ; contains the byte index into the line
|
||||||
sta (DAMAGEPTR),y
|
sta (damageptr),y
|
||||||
iny
|
iny
|
||||||
clc
|
clc
|
||||||
adc DAMAGE_W
|
adc damage_w
|
||||||
sta (DAMAGEPTR),y
|
sta (damageptr),y
|
||||||
iny
|
iny
|
||||||
|
|
||||||
; need to convert HGR y values to char rows
|
; need to convert hgr y values to char rows
|
||||||
lda PARAM1
|
lda param_y
|
||||||
lsr a
|
lsr a
|
||||||
lsr a
|
lsr a
|
||||||
lsr a
|
lsr a
|
||||||
sta (DAMAGEPTR),y
|
sta (damageptr),y
|
||||||
iny
|
iny
|
||||||
lda PARAM1
|
lda param_y
|
||||||
clc
|
clc
|
||||||
adc DAMAGE_H
|
adc damage_h
|
||||||
lsr a
|
lsr a
|
||||||
lsr a
|
lsr a
|
||||||
lsr a
|
lsr a
|
||||||
sta (DAMAGEPTR),y
|
sta (damageptr),y
|
||||||
iny
|
iny
|
||||||
sty DAMAGEINDEX
|
sty damageindex
|
||||||
|
|
||||||
renderskip
|
renderskip
|
||||||
inc PARAM3
|
inc param_index
|
||||||
dec RENDERCOUNT
|
dec param_count
|
||||||
bne renderloop
|
bne renderloop
|
||||||
|
|
||||||
renderend
|
renderend
|
||||||
|
@ -309,7 +326,7 @@ renderend
|
||||||
|
|
||||||
movestart
|
movestart
|
||||||
lda #sprite_l - sprite_active
|
lda #sprite_l - sprite_active
|
||||||
sta RENDERCOUNT
|
sta param_count
|
||||||
ldy #0
|
ldy #0
|
||||||
|
|
||||||
moveloop
|
moveloop
|
||||||
|
@ -377,7 +394,7 @@ movey_end
|
||||||
|
|
||||||
movenext
|
movenext
|
||||||
iny
|
iny
|
||||||
dec RENDERCOUNT
|
dec param_count
|
||||||
bne moveloop
|
bne moveloop
|
||||||
|
|
||||||
moveend
|
moveend
|
||||||
|
@ -434,19 +451,19 @@ clrouter
|
||||||
ldx #0
|
ldx #0
|
||||||
clrloop
|
clrloop
|
||||||
lda HGRROWS_H1,x
|
lda HGRROWS_H1,x
|
||||||
sta SCRATCH1
|
sta scratch_addr+1
|
||||||
lda HGRROWS_H2,x
|
lda HGRROWS_H2,x
|
||||||
sta TEMPADDR+1
|
sta scratch_ptr+1
|
||||||
lda HGRROWS_L,x
|
lda HGRROWS_L,x
|
||||||
sta SCRATCH0
|
sta scratch_addr
|
||||||
sta TEMPADDR
|
sta scratch_ptr
|
||||||
lda tophalf,y
|
lda tophalf,y
|
||||||
cpx #96
|
cpx #96
|
||||||
bcc clrwrite
|
bcc clrwrite
|
||||||
lda bothalf,y
|
lda bothalf,y
|
||||||
clrwrite
|
clrwrite
|
||||||
sta (SCRATCH0),y
|
sta (scratch_addr),y
|
||||||
sta (TEMPADDR),y
|
sta (scratch_ptr),y
|
||||||
inx
|
inx
|
||||||
cpx #192
|
cpx #192
|
||||||
bcc clrloop
|
bcc clrloop
|
||||||
|
|
|
@ -58,7 +58,7 @@ DrawCharCol ; A=%PQRstuvw
|
||||||
; ORG $034C ; Listing 4a
|
; ORG $034C ; Listing 4a
|
||||||
_DrawChar1
|
_DrawChar1
|
||||||
LDX hgrptr+1
|
LDX hgrptr+1
|
||||||
STX scratch0
|
STX scratch_0
|
||||||
; ORG $0350 ; Listing 1
|
; ORG $0350 ; Listing 1
|
||||||
_DrawChar
|
_DrawChar
|
||||||
LDX #7
|
LDX #7
|
||||||
|
@ -74,7 +74,7 @@ _LoadFont ; A = font[ offset ]
|
||||||
; ORG $0363 ; Listing 4a
|
; ORG $0363 ; Listing 4a
|
||||||
IncCursorCol
|
IncCursorCol
|
||||||
INY
|
INY
|
||||||
LDX scratch0 ; Move cursor back to top of scanline
|
LDX scratch_0 ; Move cursor back to top of scanline
|
||||||
STX hgrptr+1
|
STX hgrptr+1
|
||||||
RTS
|
RTS
|
||||||
; ORG $0369 ; Listing 10
|
; ORG $0369 ; Listing 10
|
||||||
|
|
Loading…
Reference in New Issue