Backing store driver and sample implementation for 3 byte * 11 row sprites

This commit is contained in:
Rob McMullen 2017-06-29 11:48:25 -07:00
parent 5d550a6ef0
commit b2842a1c39
6 changed files with 224 additions and 17 deletions

View File

@ -166,7 +166,7 @@ class Listing(object):
class Sprite(Listing):
def __init__(self, pngfile, assembler, screen, xdraw=False, use_mask=False, processor="any", name=""):
def __init__(self, pngfile, assembler, screen, xdraw=False, use_mask=False, backing_store=False, processor="any", name=""):
Listing.__init__(self, assembler)
self.screen = screen
@ -175,6 +175,7 @@ class Sprite(Listing):
self.xdraw = xdraw
self.use_mask = use_mask
self.backing_store = backing_store
self.processor = processor
if not name:
name = os.path.splitext(pngfile)[0]
@ -274,6 +275,10 @@ class Sprite(Listing):
self.comment_line(str(c) + " " + str(m))
self.out("")
if self.backing_store:
byteWidth = len(colorStreams[0])
self.asm("jsr savebg_%dx%d" % (byteWidth, self.height))
self.asm("ldx PARAM1")
cycleCount += 3
rowStartCode,extraCycles = self.rowStartCalculatorCode();
@ -317,7 +322,7 @@ class Sprite(Listing):
for chunkIndex in range(len(byteSplits)):
# Optimization
if maskSplits[chunkIndex] == "01111111":
if maskSplits[chunkIndex] == "01111111" and not self.backing_store:
optimizationCount += 1
else:
value = self.binary_constant(byteSplits[chunkIndex])
@ -638,6 +643,7 @@ if __name__ == "__main__":
parser.add_argument("-r", "--rows", action="store_true", default=False, help="output row (y position) lookup tables")
parser.add_argument("-x", "--xdraw", action="store_true", default=False, help="use XOR for sprite drawing")
parser.add_argument("-m", "--mask", action="store_true", default=False, help="use mask for sprite drawing")
parser.add_argument("-b", "--backing-store", action="store_true", default=False, help="add code to store background")
parser.add_argument("-a", "--assembler", default="cc65", choices=["cc65","mac65"], help="Assembler syntax (default: %(default)s)")
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)")
@ -667,7 +673,7 @@ if __name__ == "__main__":
for pngfile in options.files:
try:
listings.append(Sprite(pngfile, assembler, screen, options.xdraw, options.mask, options.processor, options.name))
listings.append(Sprite(pngfile, assembler, screen, options.xdraw, options.mask, options.backing_store, options.processor, options.name))
except RuntimeError, e:
print "%s: %s" % (pngfile, e)
sys.exit(1)

View File

@ -15,7 +15,7 @@ collookupcolor.s: HiSprite.py
python HiSprite.py -a mac65 -p 6502 -c > collookupcolor.s
bwsprite.s: HiSprite.py collookupbw.s rowlookup.s $(BWSPRITE)
python HiSprite.py -a mac65 -p 6502 -s hgrbw $(BWSPRITE) -n bwsprite -m > bwsprite.s
python HiSprite.py -a mac65 -p 6502 -s hgrbw $(BWSPRITE) -n bwsprite -m -b > bwsprite.s
colorsprite.s: HiSprite.py collookupcolor.s rowlookup.s $(COLORSPRITE)
python HiSprite.py -a mac65 -p 6502 -s hgrcolor $(COLORSPRITE) -n colorsprite -m > colorsprite.s

133
backingstore-3x11.s Normal file
View File

@ -0,0 +1,133 @@
; backing store test, hardcoded for 3x11 apple.png-sized sprite
;
; The backing store memory starts from some high address
; and grows downward in order to facilitate speedier restoring, because
; there will be different sized chunks to restore
;
;
;
;
; needs:
; bgstore: (lo byte, hi byte) 1 + the first byte of free memory.
; I.e. points just beyond the last byte
; PARAM0: (byte) x coord
; PARAM1: (byte) y coord
;
; everything else is known because the sizes of each erase/restore
; routine will be hardcoded.
; modification of quinn's column sweep
; memory needed for this chunk of background:
; 2: address of restore routine
; 1: x coordinate
; 1: y coordinate
; 33: number of bytes of background to save
SIZE_3X11 = 2 + 1 + 1 + 3*11
savebg_3x11
sec
lda bgstore
sbc #SIZE_3X11
sta bgstore
lda bgstore+1
sbc #0
sta bgstore+1
ldy #0
lda #<restorebg_3x11
sta (bgstore),y
iny
lda #>restorebg_3x11
sta (bgstore),y
iny
lda PARAM0
sta (bgstore),y
iny
lda PARAM1
sta bgline
sta (bgstore),y
iny
savebg_3x11_line
ldx bgline ; Calculate Y line
lda HGRROWS_H1,x ; Compute hires row
sta savebg_3x11_col0+2
sta savebg_3x11_col1+2
sta savebg_3x11_col2+2
lda HGRROWS_L,x
sta savebg_3x11_col0+1
sta savebg_3x11_col1+1
sta savebg_3x11_col2+1
ldx PARAM0 ; Compute hires column
lda DIV7_1,x
tax
savebg_3x11_col0
lda $2000,x
sta (bgstore),y
iny
inx
savebg_3x11_col1
lda $2000,x
sta (bgstore),y
iny
inx
savebg_3x11_col2
lda $2000,x
sta (bgstore),y
iny
inc bgline
cpy #SIZE_3X11
bcc savebg_3x11_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_3x11
ldx PARAM1 ; Calculate Y line
lda HGRROWS_H1,x ; Compute hires row
sta restorebg_3x11_col0+2
sta restorebg_3x11_col1+2
sta restorebg_3x11_col2+2
lda HGRROWS_L,x
sta restorebg_3x11_col0+1
sta restorebg_3x11_col1+1
sta restorebg_3x11_col2+1
ldx PARAM0 ; Compute hires column
lda DIV7_1,x
tax
lda (bgstore),y
restorebg_3x11_col0
sta $2000,x
iny
inx
lda (bgstore),y
restorebg_3x11_col1
sta $2000,x
iny
inx
lda (bgstore),y
restorebg_3x11_col2
sta $2000,x
iny
inc PARAM1
cpy #SIZE_3X11
bcc restorebg_3x11
rts

59
backingstore.s Normal file
View File

@ -0,0 +1,59 @@
; Driver to restore the screen using all the saved data.
;
; The backing store is a stack that grows downward in order to restore the
; chunks in reverse order that they were saved. Each entry in the stack
; includes:
;
; 2 bytes: address of restore routine
; 1 byte: x coordinate
; 1 byte: y coordinate
; nn: x * y bytes of data, in lists of rows
;
; Note that sprites of different sizes will have different sized entries
; in the stack, so the entire list has to be processed in order. But you want
; that anyway, so it's not a big deal.
;
; The global variable 'bgstore' is used as the stack pointer. It musts be
; initialized to a page boundary, the stack grows downward from there.
; starting from the last byte on the previous page. E.g. if the initial
; value is $c000, the stack grows down using $bfff as the highest address,
; the initial bgstore value must point to 1 + the last usable byte
;
; All registers are clobbered because there's no real need to save them since
; this will be called from the main game loop.
restorebg_init
lda #0 ; init backing store to end of free memory, $c000
sta bgstore
lda #BGTOP
sta bgstore+1
rts
restorebg_driver
ldy #0
lda (bgstore),y
sta restorebg_jsr+1
iny
lda (bgstore),y
sta restorebg_jsr+2
iny
lda (bgstore),y
sta PARAM0
iny
lda (bgstore),y
sta PARAM1
iny
restorebg_jsr
jsr $ffff
clc
lda bgstore
adc #SIZE_3X11
sta bgstore
lda bgstore+1
adc #0
sta bgstore+1
cmp #BGTOP
bcc restorebg_driver
rts

Binary file not shown.

View File

@ -22,6 +22,10 @@ SCRATCH1 = $1a
SPRITEPTR_L = $1b
SPRITEPTR_H = $1c
BGTOP = $c0 ; page number of first byte beyond top of backing store stack
bgstore = $80
bgline = $82
; constants
MAXPOSX = 127 ; This demo doesn't wanna do 16 bit math
MAXPOSY = 127
@ -42,12 +46,12 @@ gameloop
jsr renderstart
jsr movestart
jsr wait
jsr erasestart
jsr restorebg_driver
jmp gameloop
initsprites
nop
jsr restorebg_init
rts
@ -132,12 +136,9 @@ flipY
clc
adc #1
sta sprite_dy,y
jmp moveloop
jmp movenext
erasestart
rts
wait
ldy #$06 ; Loop a bit
@ -176,26 +177,32 @@ clr1
bcc clr1
rts
; 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.
sprite_active
.byte 1, 1, 0, $ff ; 1 = active, 0 = skip, $ff = end of list
.byte 1, 1, 1, 1, 1, 1, 1, 1, $ff ; 1 = active, 0 = skip, $ff = end of list
sprite_l
.byte <COLORSPRITE, <BWSPRITE, 0, 0
.byte <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE, <BWSPRITE
sprite_h
.byte >COLORSPRITE, >BWSPRITE, 0, 0
.byte >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE, >BWSPRITE
sprite_x
.byte 80, 64, 0, 0
.byte 80, 64, 33, 83, 4, 9, 55, 18
sprite_y
.byte 116, 126, 0, 0
.byte 116, 126, 40, 60, 80, 100, 120, 140
sprite_dx
.byte -1, 4, 0, 0
.byte -1, -2, -3, -4, 1, 2, 3, 4
sprite_dy
.byte -3, 1, 0, 0
.byte -4, -3, -2, -1, 4, 3, 2, 1
.include colorsprite.s
@ -203,3 +210,5 @@ sprite_dy
.include rowlookup.s
.include collookupbw.s
.include collookupcolor.s
.include backingstore.s
.include backingstore-3x11.s