Add TwoLayer rendering stubs

This commit is contained in:
Lucas Scharenbroich 2022-06-22 15:29:09 -05:00
parent 280d19876c
commit 3292572261
5 changed files with 596 additions and 154 deletions

View File

@ -393,10 +393,16 @@ DynUnder dw CopyDynamicTile,DynamicUnder,OneSpriteDynamicUnder
; To improve the performance when two-layer rendering is enabled,
; the TILE_SOLID_BIT hint bit can be set to indicate that a tile
; has no transparency. This allows one of the faster routines
; to be selected.
; to be selected from the other Proc tables
TwoLyrProcs
TwoLyrOverZA dw Tile0TwoLyr,SpriteOver0TwoLyr,OneSpriteOver0TwoLyr
TwoLyrOverZV dw Tile0TwoLyr,SpriteOver0TwoLyr,OneSpriteOver0TwoLyr
TwoLyrOverNA dw CopyTileATwoLyr,SpriteOverATwoLyr,OneSpriteTwoLyrOverA
TwoLyrOverNV dw CopyTileVTwoLyr,SpriteOverVTwoLyr,OneSpriteTwoLyrOverV
TwoLyrUnderZA dw Tile0TwoLyr,SpriteOver0TwoLyr,OneSpriteOver0TwoLyr ; if sprites are over or under the transparent tile, same rendering code
TwoLyrUnderZV dw Tile0TwoLyr,SpriteOver0TwoLyr,OneSpriteOver0TwoLyr
TwoLyrUnderNA dw CopyTileATwoLyr,SpriteUnderATwoLyr,OneSpriteTwoLyrUnderA
TwoLyrUnderNV dw CopyTileVTwoLyr,SpriteUnderVTwoLyr,OneSpriteTwoLyrUnderV
; SetBG0XPos
;

View File

@ -387,6 +387,7 @@ _TSCopyTileToDynamic
put render/Fast.s
put render/Slow.s
put render/Dynamic.s
put render/TwoLayer.s
put render/Sprite1.s
put render/Sprite2.s
put tiles/DirtyTileQueue.s

View File

@ -4,16 +4,16 @@ CopyDynamicTile
and #$007F
ora #$4800
]line equ 0 ; render the first column
]line equ 0 ; render the first column
lup 8
sta: $0004+{]line*$1000},y
]line equ ]line+1
--^
inc ; advance to the next word
inc ; advance to the next word
inc
]line equ 0 ; render the second column
]line equ 0 ; render the second column
lup 8
sta: $0001+{]line*$1000},y
]line equ ]line+1
@ -48,10 +48,10 @@ DynamicOver
sta _JTBL_CACHE
lda TileStore+TS_TILE_ID,x ; Get the original tile descriptor
and #$007F ; clamp to < (32 * 4)
and #$007F ; clamp to < (32 * 4)
ora #$B500
xba
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
lda TileStore+TS_CODE_ADDR_HIGH,x
pha
@ -69,12 +69,12 @@ DynamicOver
sec
lda _JTBL_CACHE
sbc #SNIPPET_SIZE ; Advance to the next snippet (Reverse indexing)
sbc #SNIPPET_SIZE ; Advance to the next snippet (Reverse indexing)
sta _JTBL_CACHE
clc
lda _OP_CACHE
adc #$0200 ; Advance to the next word
adc #$0200 ; Advance to the next word
sta _OP_CACHE
CopyDynOver 2;$0000
@ -94,10 +94,10 @@ DynamicUnder
sta _JTBL_CACHE
lda TileStore+TS_TILE_ID,x ; Get the original tile descriptor
and #$007F ; clamp to < (32 * 4)
ora #$3580 ; Pre-calc the AND $80,x opcode + operand
and #$007F ; clamp to < (32 * 4)
ora #$3580 ; Pre-calc the AND $80,x opcode + operand
xba
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
lda TileStore+TS_CODE_ADDR_HIGH,x
pha
@ -120,7 +120,7 @@ DynamicUnder
clc
lda _OP_CACHE
adc #$0200 ; Advance to the next word
adc #$0200 ; Advance to the next word
sta _OP_CACHE
CopyDynUnder 2;$0000
@ -133,25 +133,25 @@ DynamicUnder
CopyDynUnder 30;$7000
; Now fill in the JMP opcodes
sep #$20
lda #$4C
sep #$20
lda #$4C
sta: $0000,y
sta: $0003,y
sta $1000,y
sta $1003,y
sta $2000,y
sta $2003,y
sta $3000,y
sta $3003,y
sta $4000,y
sta $4003,y
sta $5000,y
sta $5003,y
sta $6000,y
sta $6003,y
sta $7000,y
sta $7003,y
rep #$20
sta $1000,y
sta $1003,y
sta $2000,y
sta $2003,y
sta $3000,y
sta $3003,y
sta $4000,y
sta $4003,y
sta $5000,y
sta $5003,y
sta $6000,y
sta $6003,y
sta $7000,y
sta $7003,y
rep #$20
plb
rts
@ -164,52 +164,52 @@ DynamicUnder
;
; ]1 : sprite buffer offset
; ]2 : code field offset
CopyDynOver mac
lda tmp_sprite_mask+{]1} ; load the mask value
bne mixed ; a non-zero value may be mixed
CopyDynOver mac
lda tmp_sprite_mask+{]1} ; load the mask value
bne mixed ; a non-zero value may be mixed
; This is a solid word
lda #$00F4 ; PEA instruction
sta: ]2,y
lda tmp_sprite_data+{]1} ; load the sprite data
sta: ]2+1,y ; PEA operand
bra next
lda #$00F4 ; PEA instruction
sta: ]2,y
lda tmp_sprite_data+{]1} ; load the sprite data
sta: ]2+1,y ; PEA operand
bra next
mixed cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
beq transparent
mixed cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
beq transparent
lda #$004C ; JMP to handler
sta: {]2},y
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$7000} ; adjust for the current row offset
sta: {]2}+1,y
tax ; This becomes the new address that we use to patch in
lda #$004C ; JMP to handler
sta: {]2},y
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$7000} ; adjust for the current row offset
sta: {]2}+1,y
tax ; This becomes the new address that we use to patch in
lda _OP_CACHE ; Get the LDA dp,x instruction for this column
sta: $0000,x
lda _OP_CACHE ; Get the LDA dp,x instruction for this column
sta: $0000,x
lda #$0029 ; AND #SPRITE_MASK
sta: $0002,x
lda tmp_sprite_mask+{]1}
sta: $0003,x
lda #$0029 ; AND #SPRITE_MASK
sta: $0002,x
lda tmp_sprite_mask+{]1}
sta: $0003,x
lda #$0009 ; ORA #SPRITE_DATA
sta: $0005,x
lda tmp_sprite_data+{]1}
sta: $0006,x
lda #$0009 ; ORA #SPRITE_DATA
sta: $0005,x
lda tmp_sprite_data+{]1}
sta: $0006,x
lda #$0D80 ; branch to the prologue (BRA *+15)
sta: $0008,x
bra next
lda #$0D80 ; branch to the prologue (BRA *+15)
sta: $0008,x
bra next
; This is a transparent word, so just show the dynamic data
transparent
lda #$4800 ; Put the PHA in the third byte
sta: {]2}+1,y
lda _OP_CACHE ; Store the LDA dp,x instruction with operand
sta: {]2},y
lda #$4800 ; Put the PHA in the third byte
sta: {]2}+1,y
lda _OP_CACHE ; Store the LDA dp,x instruction with operand
sta: {]2},y
next
<<<
<<<
; Masked renderer for a dynamic tile on top of the sprite data. There are no transparent vs
; solid vs mixed considerations here. This only sets the JMP address, setting the JMP opcodes
@ -227,24 +227,24 @@ CopyDynUnder MAC
; ora $00,x
; bra *+16
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$7000} ; adjust for the current row offset
sta: {]2}+1,y
tax ; This becomes the new address that we use to patch in
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$7000} ; adjust for the current row offset
sta: {]2}+1,y
tax ; This becomes the new address that we use to patch in
lda #$00A9 ; LDA #DATA
sta: $0000,x
lda tmp_sprite_data+{]1}
sta: $0001,x
lda #$00A9 ; LDA #DATA
sta: $0000,x
lda tmp_sprite_data+{]1}
sta: $0001,x
lda _OP_CACHE
sta: $0003,x ; AND $80,x
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
sta: $0005,x ; ORA $00,x
lda _OP_CACHE
sta: $0003,x ; AND $80,x
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
sta: $0005,x ; ORA $00,x
lda #$0E80 ; branch to the prologue (BRA *+16)
sta: $0007,x
eom
lda #$0E80 ; branch to the prologue (BRA *+16)
sta: $0007,x
eom
; Helper functions to move tile data into the dynamic tile space
@ -253,59 +253,59 @@ CopyDynUnder MAC
; Y = dynamic tile ID
CopyTileToDyn
txa
jsr _GetTileAddr
jsr _GetTileAddr
tax
tya
and #$001F ; Maximum of 32 dynamic tiles
and #$001F ; Maximum of 32 dynamic tiles
asl
asl ; 4 bytes per page
adc BlitterDP ; Add to the bank 00 base address
adc #$0100 ; Go to the next page
asl ; 4 bytes per page
adc BlitterDP ; Add to the bank 00 base address
adc #$0100 ; Go to the next page
tay
jsr CopyTileDToDyn ; Copy the tile data
jmp CopyTileMToDyn ; Copy the tile mask
jsr CopyTileDToDyn ; Copy the tile data
jmp CopyTileMToDyn ; Copy the tile mask
; X = address of tile
; Y = tile address in bank 0
CopyTileDToDyn
phb
pea $0000
pea $0000
plb
plb
ldal tiledata+0,x
sta: $0000,y
ldal tiledata+2,x
sta: $0002,y
ldal tiledata+4,x
sta $0100,y
ldal tiledata+6,x
sta $0102,y
ldal tiledata+8,x
sta $0200,y
ldal tiledata+10,x
sta $0202,y
ldal tiledata+12,x
sta $0300,y
ldal tiledata+14,x
sta $0302,y
ldal tiledata+16,x
sta $0400,y
ldal tiledata+18,x
sta $0402,y
ldal tiledata+20,x
sta $0500,y
ldal tiledata+22,x
sta $0502,y
ldal tiledata+24,x
sta $0600,y
ldal tiledata+26,x
sta $0602,y
ldal tiledata+28,x
sta $0700,y
ldal tiledata+30,x
sta $0702,y
ldal tiledata+0,x
sta: $0000,y
ldal tiledata+2,x
sta: $0002,y
ldal tiledata+4,x
sta $0100,y
ldal tiledata+6,x
sta $0102,y
ldal tiledata+8,x
sta $0200,y
ldal tiledata+10,x
sta $0202,y
ldal tiledata+12,x
sta $0300,y
ldal tiledata+14,x
sta $0302,y
ldal tiledata+16,x
sta $0400,y
ldal tiledata+18,x
sta $0402,y
ldal tiledata+20,x
sta $0500,y
ldal tiledata+22,x
sta $0502,y
ldal tiledata+24,x
sta $0600,y
ldal tiledata+26,x
sta $0602,y
ldal tiledata+28,x
sta $0700,y
ldal tiledata+30,x
sta $0702,y
plb
rts
@ -324,42 +324,42 @@ CopyTileDToDyn
; jsr CopyTileMToDyn
CopyTileMToDyn
phb
pea $0000
pea $0000
plb
plb
ldal tiledata+32+0,x
sta: $0080,y
ldal tiledata+32+2,x
sta: $0082,y
ldal tiledata+32+4,x
sta $0180,y
ldal tiledata+32+6,x
sta $0182,y
ldal tiledata+32+8,x
sta $0280,y
ldal tiledata+32+10,x
sta $0282,y
ldal tiledata+32+12,x
sta $0380,y
ldal tiledata+32+14,x
sta $0382,y
ldal tiledata+32+16,x
sta $0480,y
ldal tiledata+32+18,x
sta $0482,y
ldal tiledata+32+20,x
sta $0580,y
ldal tiledata+32+22,x
sta $0582,y
ldal tiledata+32+24,x
sta $0680,y
ldal tiledata+32+26,x
sta $0682,y
ldal tiledata+32+28,x
sta $0780,y
ldal tiledata+32+30,x
sta $0782,y
ldal tiledata+32+0,x
sta: $0080,y
ldal tiledata+32+2,x
sta: $0082,y
ldal tiledata+32+4,x
sta $0180,y
ldal tiledata+32+6,x
sta $0182,y
ldal tiledata+32+8,x
sta $0280,y
ldal tiledata+32+10,x
sta $0282,y
ldal tiledata+32+12,x
sta $0380,y
ldal tiledata+32+14,x
sta $0382,y
ldal tiledata+32+16,x
sta $0480,y
ldal tiledata+32+18,x
sta $0482,y
ldal tiledata+32+20,x
sta $0580,y
ldal tiledata+32+22,x
sta $0582,y
ldal tiledata+32+24,x
sta $0680,y
ldal tiledata+32+26,x
sta $0682,y
ldal tiledata+32+28,x
sta $0780,y
ldal tiledata+32+30,x
sta $0782,y
plb
rts

View File

@ -188,3 +188,56 @@ OneSpriteDynamicOver
tyx
jmp DynamicOver
;-------------------------------
; Two Layer tiles with one sprite. Just copy the data and go through the generic sprite path
_CopySpriteDataAndMaskToDP
]line equ 0
lup 8
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
sta tmp_sprite_data+{]line*4}
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
sta tmp_sprite_data+{]line*4}+2
ldal spritemask+{]line*SPRITE_PLANE_SPAN},x
sta tmp_sprite_mask+{]line*4}
ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
sta tmp_sprite_mask+{]line*4}+2
]line equ ]line+1
--^
rts
OneSpriteOver0TwoLyr
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteOver0TwoLyr
OneSpriteTwoLyrOverA
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteOverATwoLyr
OneSpriteTwoLyrOverV
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteOverVTwoLyr
OneSpriteTwoLyrUnderA
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteUnderATwoLyr
OneSpriteTwoLyrUnderV
txy
tax
jsr _CopySpriteDataAndMaskToDP
tyx
jmp SpriteUnderVTwoLyr

382
src/render/TwoLayer.s Normal file
View File

@ -0,0 +1,382 @@
; Collection of render function used when the engine is in "Two Layer" mode. Other than the Tile 0
; routines, there's nothing in here that is particularly well optimized.
Tile0TwoLyr
and #$00FF
ora #$4800
sta: $0004,y
sta $1004,y
sta $2004,y
sta $3004,y
sta $4004,y
sta $5004,y
sta $6004,y
sta $7004,y
inc
inc
sta: $0001,y
sta $1001,y
sta $2001,y
sta $3001,y
sta $4001,y
sta $5001,y
sta $6001,y
sta $7001,y
sep #$20
lda #$B1 ; This is a special case where we can set all the words to LDA (DP),y
sta: $0000,y
sta: $0003,y
sta $1000,y
sta $1003,y
sta $2000,y
sta $2003,y
sta $3000,y
sta $3003,y
sta $4000,y
sta $4003,y
sta $5000,y
sta $5003,y
sta $6000,y
sta $6003,y
sta $7000,y
sta $7003,y
rep #$20
rts
; Draw from the sprite buffer into a fully transparent tile
SpriteOver0TwoLyr
lda TileStore+TS_JMP_ADDR,x ; Get the address of the exception handler
sta _JTBL_CACHE
lda TileStore+TS_WORD_OFFSET,x ; Load the word offset of this tile (0 to 82 in steps of 2)
ora #$B100 ; Pre-calc the LDA (dp),y opcode + operand
xba
sta _OP_CACHE
lda TileStore+TS_CODE_ADDR_HIGH,x
pha
ldy TileStore+TS_CODE_ADDR_LOW,x
plb
CopyTwoLayerOver tmp_sprite_data+0;$0003
CopyTwoLayerOver tmp_sprite_data+4;$1003
CopyTwoLayerOver tmp_sprite_data+8;$2003
CopyTwoLayerOver tmp_sprite_data+12;$3003
CopyTwoLayerOver tmp_sprite_data+16;$4003
CopyTwoLayerOver tmp_sprite_data+20;$5003
CopyTwoLayerOver tmp_sprite_data+24;$6003
CopyTwoLayerOver tmp_sprite_data+28;$7003
sec
lda _JTBL_CACHE
sbc #SNIPPET_SIZE ; Advance to the next snippet (Reverse indexing)
sta _JTBL_CACHE
clc
lda _OP_CACHE
adc #$0200 ; Advance to the next word
sta _OP_CACHE
CopyTwoLayerOver tmp_sprite_data+2;$0000
CopyTwoLayerOver tmp_sprite_data+6;$1000
CopyTwoLayerOver tmp_sprite_data+10;$2000
CopyTwoLayerOver tmp_sprite_data+14;$3000
CopyTwoLayerOver tmp_sprite_data+18;$4000
CopyTwoLayerOver tmp_sprite_data+22;$5000
CopyTwoLayerOver tmp_sprite_data+26;$6000
CopyTwoLayerOver tmp_sprite_data+30;$7000
plb
rts
TmpTileDataToCodeField
lda TileStore+TS_JMP_ADDR,x ; Get the address of the exception handler
sta _JTBL_CACHE
lda TileStore+TS_WORD_OFFSET,x ; Load the word offset of this tile (0 to 82 in steps of 2)
ora #$B100 ; Pre-calc the LDA (dp),y opcode + operand
xba
sta _OP_CACHE
lda TileStore+TS_CODE_ADDR_HIGH,x
pha
ldy TileStore+TS_CODE_ADDR_LOW,x
plb
_TmpTileDataToCodeField
CopyTwoLayerOver tmp_tile_data+0;$0003
CopyTwoLayerOver tmp_tile_data+4;$1003
CopyTwoLayerOver tmp_tile_data+8;$2003
CopyTwoLayerOver tmp_tile_data+12;$3003
CopyTwoLayerOver tmp_tile_data+16;$4003
CopyTwoLayerOver tmp_tile_data+20;$5003
CopyTwoLayerOver tmp_tile_data+24;$6003
CopyTwoLayerOver tmp_tile_data+28;$7003
sec
lda _JTBL_CACHE
sbc #SNIPPET_SIZE ; Advance to the next snippet (Reverse indexing)
sta _JTBL_CACHE
clc
lda _OP_CACHE
adc #$0200 ; Advance to the next word
sta _OP_CACHE
CopyTwoLayerOver tmp_tile_data+2;$0000
CopyTwoLayerOver tmp_tile_data+6;$1000
CopyTwoLayerOver tmp_tile_data+10;$2000
CopyTwoLayerOver tmp_tile_data+14;$3000
CopyTwoLayerOver tmp_tile_data+18;$4000
CopyTwoLayerOver tmp_tile_data+22;$5000
CopyTwoLayerOver tmp_tile_data+26;$6000
CopyTwoLayerOver tmp_tile_data+30;$7000
plb
rts
; Copy a tile into the tile data buffer and then render to the code field
CopyTileATwoLyr
lda TileStore+TS_JMP_ADDR,x ; Get the address of the exception handler
sta _JTBL_CACHE
lda TileStore+TS_WORD_OFFSET,x ; Load the word offset of this tile (0 to 82 in steps of 2)
ora #$B100 ; Pre-calc the LDA (dp),y opcode + operand
xba
sta _OP_CACHE
lda TileStore+TS_CODE_ADDR_HIGH,x
pha
ldy TileStore+TS_CODE_ADDR_LOW,x
lda TileStore+TS_TILE_ADDR,x
tax
plb
]line equ 0
lup 8
ldal tiledata+{]line*4},x
sta tmp_tile_data+{]line*4}
ldal tiledata+{]line*4}+32,x
sta tmp_tile_mask+{]line*4}
ldal tiledata+{]line*4}+2,x
sta tmp_tile_data+{]line*4}+2
ldal tiledata+{]line*4}+32+2,x
sta tmp_tile_mask+{]line*4}+2
]line equ ]line+1
--^
jmp _TmpTileDataToCodeField
CopyTileVTwoLyr
lda TileStore+TS_JMP_ADDR,x ; Get the address of the exception handler
sta _JTBL_CACHE
lda TileStore+TS_WORD_OFFSET,x ; Load the word offset of this tile (0 to 82 in steps of 2)
ora #$B100 ; Pre-calc the LDA (dp),y opcode + operand
xba
sta _OP_CACHE
lda TileStore+TS_CODE_ADDR_HIGH,x
pha
ldy TileStore+TS_CODE_ADDR_LOW,x
lda TileStore+TS_TILE_ADDR,x
tax
plb
]src equ 7
]dest equ 0
lup 8
ldal tiledata+{]src*4},x
sta tmp_tile_data+{]dest*4}
ldal tiledata+{]src*4}+32,x
sta tmp_tile_mask+{]dest*4}
ldal tiledata+{]src*4}+2,x
sta tmp_tile_data+{]dest*4}+2
ldal tiledata+{]src*4}+32+2,x
sta tmp_tile_mask+{]dest*4}+2
]src equ ]src-1
]dest equ ]dest+1
--^
jmp _TmpTileDataToCodeField
; Handle sprites + tiles. Strategy is to merge the sprite and tile data and write it to the
; temporary space an defer the actual work to the _TmpTileDataToCodeField helper
SpriteOverATwoLyr
ldy TileStore+TS_TILE_ADDR,x
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
]line equ 0
lup 8
lda tiledata+{]line*4},y
and tmp_sprite_mask+{]line*4}
ora tmp_sprite_data+{]line*4}
sta tmp_tile_data+{]line*4}
lda tiledata+{]line*4}+32,y
and tmp_sprite_mask+{]line*4}
sta tmp_tile_mask+{]line*4}
lda tiledata+{]line*4}+2,y
and tmp_sprite_mask+{]line*4}+2
ora tmp_sprite_data+{]line*4}+2
sta tmp_tile_data+{]line*4}+2
lda tiledata+{]line*4}+32+2,y
and tmp_sprite_mask+{]line*4}+2
sta tmp_tile_mask+{]line*4}+2
]line equ ]line+1
--^
plb
jmp TmpTileDataToCodeField
SpriteOverVTwoLyr
ldy TileStore+TS_TILE_ADDR,x
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
]src equ 7
]dest equ 0
lup 8
lda tiledata+{]src*4},y
and tmp_sprite_mask+{]dest*4}
ora tmp_sprite_data+{]dest*4}
sta tmp_tile_data+{]dest*4}
lda tiledata+{]src*4}+32,y
and tmp_sprite_mask+{]dest*4}
sta tmp_tile_mask+{]dest*4}
lda tiledata+{]src*4}+2,y
and tmp_sprite_mask+{]dest*4}+2
ora tmp_sprite_data+{]dest*4}+2
sta tmp_tile_data+{]dest*4}+2
lda tiledata+{]src*4}+32+2,y
and tmp_sprite_mask+{]dest*4}+2
sta tmp_tile_mask+{]dest*4}+2
]src equ ]src-1
]dest equ ]dest+1
--^
plb
jmp TmpTileDataToCodeField
SpriteUnderATwoLyr
ldy TileStore+TS_TILE_ADDR,x
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
]line equ 0
lup 8
lda tmp_sprite_data+{]line*4}
and tiledata+{]line*4}+32,y
ora tiledata+{]line*4},y
sta tmp_tile_data+{]line*4}
lda tiledata+{]line*4}+32,y
and tmp_sprite_mask+{]line*4}
sta tmp_tile_mask+{]line*4}
lda tmp_sprite_data+{]line*4}+2
and tiledata+{]line*4}+32+2,y
ora tiledata+{]line*4}+2,y
sta tmp_tile_data+{]line*4}+2
lda tiledata+{]line*4}+32+2,y
and tmp_sprite_mask+{]line*4}+2
sta tmp_tile_mask+{]line*4}+2
]line equ ]line+1
--^
plb
jmp TmpTileDataToCodeField
SpriteUnderVTwoLyr
ldy TileStore+TS_TILE_ADDR,x
pei DP2_TILEDATA_AND_TILESTORE_BANKS
plb
]src equ 7
]dest equ 0
lup 8
lda tmp_sprite_data+{]dest*4}
and tiledata+{]src*4}+32,y
ora tiledata+{]src*4},y
sta tmp_tile_data+{]dest*4}
lda tiledata+{]src*4}+32,y
and tmp_sprite_mask+{]dest*4}
sta tmp_tile_mask+{]dest*4}
lda tmp_sprite_data+{]dest*4}+2
and tiledata+{]src*4}+32+2,y
ora tiledata+{]src*4}+2,y
sta tmp_tile_data+{]dest*4}+2
lda tiledata+{]src*4}+32+2,y
and tmp_sprite_mask+{]dest*4}+2
sta tmp_tile_mask+{]dest*4}+2
]src equ ]src-1
]dest equ ]dest+1
--^
plb
jmp TmpTileDataToCodeField
; Macro to fill in the code field from a direct page temporary buffer
;
; ]1 : direct page address with data, the mask direct page address is data + 32
; ]2 : code field offset
;
; Y is the code field address
CopyTwoLayerOver mac
lda {]1}+32 ; load the mask value
bne mixed ; a non-zero value may be mixed
; This is a solid word
lda #$00F4 ; PEA instruction
sta: ]2,y
lda {]1} ; load the tile data
sta: ]2+1,y ; PEA operand
bra next
mixed cmp #$FFFF ; All 1's in the mask is fully transparent
beq transparent
lda #$004C ; JMP instruction
sta: {]2},y
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$7000} ; adjust for the current row offset
sta: {]2}+1,y
tax ; This becomes the new address that we use to patch in
lda #$29
sta: $0002,x ; AND #$0000 opcode
lda #$09
sta: $0005,x ; ORA #$0000 opcode
lda _OP_CACHE ; Get the LDA (dp),y instruction for this column
sta: $0000,x
lda {]1}+32 ; insert the tile mask and data into the exception
sta: $0003,x ; handler.
lda {]1}
sta: $0006,x
lda #$0D80 ; branch to the prologue (BRA *+15)
sta: $0008,x
bra next
; This is a transparent word, so just show the second background layer
transparent
lda #$4800 ; put a PHA after the offset
sta: {]2}+1,y
lda _OP_CACHE
sta: {]2},y
next
eom