diff --git a/src/Tiles.s b/src/Tiles.s index b86d32d..7aa7120 100644 --- a/src/Tiles.s +++ b/src/Tiles.s @@ -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 ; diff --git a/src/Tool.s b/src/Tool.s index 312e354..2d76117 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -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 diff --git a/src/render/Dynamic.s b/src/render/Dynamic.s index 1249d33..041106c 100644 --- a/src/render/Dynamic.s +++ b/src/render/Dynamic.s @@ -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 \ No newline at end of file diff --git a/src/render/Sprite1.s b/src/render/Sprite1.s index 4e4528c..31f6321 100644 --- a/src/render/Sprite1.s +++ b/src/render/Sprite1.s @@ -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 diff --git a/src/render/TwoLayer.s b/src/render/TwoLayer.s new file mode 100644 index 0000000..738445f --- /dev/null +++ b/src/render/TwoLayer.s @@ -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 \ No newline at end of file