Working through integration bugs

* Gave active list dedicated direct page space
* Change active list bit test from ror to asl to avoid barrel shift
* Various address fixes
This commit is contained in:
Lucas Scharenbroich 2022-02-21 10:31:35 -06:00
parent 7f9f4de228
commit 8b9415a7a5
6 changed files with 77 additions and 48 deletions

View File

@ -84,12 +84,11 @@ LastRender equ 96 ; Record which reder function was last
; DamagedSprites equ 98
SpriteMap equ 100 ; Bitmap of open sprite slots.
ActiveSpriteCount equ 102
Next equ 104
BankLoad equ 128
BankLoad equ 104
Next equ 106
activeSpriteList equ 128 ; 32 bytes for the active sprite list (can persist across frames)
AppSpace equ 160 ; 16 bytes of space reserved for application use
tiletmp equ 178 ; 16 bytes of temp storage for the tile renderers
blttmp equ 192 ; 32 bytes of local cache/scratch space for blitter

View File

@ -46,7 +46,7 @@
; edges of the rendered play field.
; The render function is the point of committment -- most of the APIs that set sprintes and
; The render function is the point of committment -- most of the APIs that set sprites and
; update coordinates are lazy; they simply save the value and set a dirty flag in the
; DirtyBits word.
;
@ -78,11 +78,13 @@ _Render
jsr _ApplyBG0XPosPre
jsr _ApplyBG1XPosPre
nop
jsr _RenderSprites ; Once the BG0 X and Y positions are committed, update sprite data
jsr _UpdateBG0TileMap ; and the tile maps. These subroutines build up a list of tiles
jsr _UpdateBG1TileMap ; that need to be updated in the code field
nop
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode
@ -199,6 +201,14 @@ _RenderDirtyTile
jsr BuildActiveSpriteArray ; Build the sprite index list from the bit field
lda TileStore+TS_VBUFF_ARRAY_ADDR,y ; Scratch space
sta _SPR_X_REG
phy
ldy spriteIdx
lda (_SPR_X_REG),y
sta _SPR_X_REG
ply
; ldx TileStore+TS_SPRITE_ADDR,y
; stx _SPR_X_REG
@ -276,7 +286,11 @@ _TBDirtySpriteTile_VH
jsr _TBCopyTileDataToCBuffV
jmp _TBApplyDirtySpriteData
; Just copy in the data from the first sprite
_TBApplyDirtySpriteData
_TBApplyDirtySpriteData0
ldx _SPR_X_REG ; set to the unaligned tile block address in the sprite plane
]line equ 0
@ -320,16 +334,16 @@ BuildActiveSpriteArray
]step equ 0
lup 4
ror
lsr
bcc :skip_1
pea ]step
:skip_1 ror
:skip_1 lsr
bcc :skip_2
pea ]step+2
:skip_2 ror
:skip_2 lsr
bcc :skip_3
pea ]step+4
:skip_3 ror
:skip_3 lsr
bcc :skip_4
pea ]step+6
:skip_4 beq :end_1

View File

@ -36,14 +36,15 @@ VBUFF_TILE_ROW_BYTES equ 8*VBUFF_STRIDE_BYTES
VBUFF_SPRITE_STEP equ VBUFF_TILE_ROW_BYTES*3
VBUFF_SPRITE_START equ {8*VBUFF_TILE_ROW_BYTES}+4
ldx #{MAX_SPRITES-1}*2
ldx #0
lda #VBUFF_SPRITE_START
clc
:loop4 sta _Sprites+VBUFF_ADDR,x
adc #VBUFF_SPRITE_STEP
dex
dex
bpl :loop4
inx
inx
cpx #MAX_SPRITES*2
bcc :loop4
; Precalculate some bank values
jsr _CacheSpriteBanks
@ -231,8 +232,6 @@ _ClearSpriteFromTileStore
; Tile Store locations are marked as dirty. It is important to recognize that the sprites themselves
; can be marked dirty, and the underlying tiles in the tile store are independently marked dirty.
activeSpriteList equ blttmp
phase1 dw :phase1_0
dw :phase1_1,:phase1_2,:phase1_3,:phase1_4
dw :phase1_5,:phase1_6,:phase1_7,:phase1_8
@ -408,16 +407,16 @@ RebuildSpriteArray
pea $FFFF ; end-of-list marker
]step equ 0
lup 4
ror
lsr
bcc :skip_1
pea ]step
:skip_1 ror
:skip_1 lsr
bcc :skip_2
pea ]step+2
:skip_2 ror
:skip_2 lsr
bcc :skip_3
pea ]step+4
:skip_3 ror
:skip_3 lsr
bcc :skip_4
pea ]step+6
:skip_4 beq :end_1
@ -432,7 +431,7 @@ RebuildSpriteArray
:loop
pla
bmi :out
sta blttmp,x
sta activeSpriteList,x
inx
inx
bra :loop
@ -545,7 +544,7 @@ _CacheSpriteBanks
rts
; This is 13 blocks wide
SPRITE_PLANE_SPAN equ 52 ; 256
SPRITE_PLANE_SPAN equ VBUFF_STRIDE_BYTES ; 52
; A = x coordinate
; Y = y coordinate

View File

@ -151,17 +151,19 @@ _MarkDirtySprite
and #$FFFE ; Same pre-multiply by 2 for later
sta ColLeft
; Sneak a pre-calculation here. Calculate the tile-aligned upper-left corner of the sprite in the sprite plane.
; We can reuse this in all of the routines below. This is not the (x,y) of the sprite itself, but
; the corner of the tile it overlaps with, relative to the sprite's VBUFF_ADDR.
; Calculate the modified origin address for the sprite. We need to look at the sprite flip bits
; to determine which of the four sprite stamps is the correct one to use. Then, offset that origin
; based on the (x, y) and (startx, starty) positions.
lda _Sprites+SPRITE_DISP,y ; Each stamp is 12 bytes
and #$0006
tax
lda :stamp_step,x
clc
lda TileTop
; adc #NUM_BUFF_LINES
xba
clc
adc TileLeft
sta VBuffOrigin ; Save once to use later (constant offsets)
adc _Sprites+VBUFF_ADDR,y
sta VBuffOrigin
lda #^TileStore
sta tmp1
; Calculate the number of columns and dispatch
@ -180,6 +182,7 @@ _MarkDirtySprite
dw :mark3x1,:mark3x2,:mark3x3,mdsOut
dw mdsOut,mdsOut,mdsOut,mdsOut
:stamp_step dw 0,12,24,36
; Dispatch to the calculated sizing
; Begin a list of subroutines to cover all of the valid sprite size compinations. This is all unrolled code,
@ -329,7 +332,7 @@ _MarkDirtySprite
sta tmp0
lda VBuffOrigin
sta (tmp0),y
sta [tmp0],y
; lda VBuffOrigin ; This is an interesting case. The mapping between the tile store
; adc #{0*4}+{0*256} ; and the sprite buffers changes as the StartX, StartY values change
@ -360,7 +363,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{0*4}+{1*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x
@ -380,7 +383,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{0*4}+{2*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x
@ -401,7 +404,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{1*4}+{0*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x
@ -422,7 +425,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{1*4}+{1*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x
@ -443,7 +446,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{1*4}+{2*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x
@ -464,7 +467,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{2*4}+{0*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x
@ -485,7 +488,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{2*4}+{1*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x
@ -506,7 +509,7 @@ _MarkDirtySprite
lda VBuffOrigin
adc #{2*4}+{2*8*SPRITE_PLANE_SPAN}
sta (tmp0),y
sta [tmp0],y
lda SpriteBit
oral TileStore+TS_SPRITE_FLAG,x

View File

@ -8,13 +8,13 @@ DISP_MASK equ $00F9
phx
lda _Sprites+VBUFF_ADDR,y
lda _Sprites+VBUFF_ADDR,x
sta tmp1
lda _Sprites+TILE_DATA_OFFSET,y
lda _Sprites+TILE_DATA_OFFSET,x
sta tmp2
lda _Sprites+SPRITE_DISP,y
lda _Sprites+SPRITE_DISP,x
and #DISP_MASK ; dispatch to all of the different orientations
sta tmp3

View File

@ -104,16 +104,30 @@ _RenderTileBG1
;
; Y = address of tile
_RenderTile2
pea >TileStore ; Need that addressing flexibility here. Callers responsible for restoring bank reg
pea >TileStore ; Need that addressing flexibility here. Caller is responsible for restoring bank reg
plb
plb
txy ; We can be better than this....
lda TileStore+TS_TILE_ID,y ; build the finalized tile descriptor
ldx TileStore+TS_SPRITE_FLAG,y ; This is a bitfield of all the sprites that intersect this tile, only care if non-zero or not
; beq :nosprite
beq :nosprite
; ora #TILE_SPRITE_BIT
; ldx TileStore+TS_SPRITE_ADDR,y ; TODO: collapse sprites
txa
jsr BuildActiveSpriteArray ; Build the max 4 array of active sprites for this tile
sta ActiveSpriteCount
lda TileStore+TS_VBUFF_ARRAY_ADDR,y ; Scratch space
sta _SPR_X_REG
phy
ldy spriteIdx
lda (_SPR_X_REG),y
sta _SPR_X_REG
ply
lda TileStore+TS_TILE_ID,y
ora #TILE_SPRITE_BIT
; ldx TileStore+TS_VBUFF_ARRAY_ADDR,y
; stx _SPR_X_REG
:nosprite
@ -757,11 +771,11 @@ _ApplyTiles
bra :begin
:loop
; Retrieve the offset of the next dirty Tile Store items in the Y-register
; Retrieve the offset of the next dirty Tile Store items in the X-register
jsr _PopDirtyTile2
; Call the generic dispatch with the Tile Store record pointer at by the Y-register.
; Call the generic dispatch with the Tile Store record pointer at by the X-register.
phb
jsr _RenderTile2