iigs-game-engine/src/blitter/Tiles10001.s

211 lines
8.4 KiB
ArmAsm

; _TBDynamicSpriteTile
;
; This tile type does not explicitly support horizontal or vertical flipping. An appropriate tile
; descriptor should be passed into CopyTileToDyn to put the horizontally or vertically flipped source
; data into the dynamic tile buffer
_TBDynamicSpriteTile
sta _X_REG
ldal TileStore+TS_JMP_ADDR,x ; Get the address of the exception handler
sta _JTBL_CACHE
ldal TileStore+TS_TILE_ID,x ; Get the original tile descriptor
and #$007F ; clamp to < (32 * 4)
ora #$B500
xba
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
CopyDynWord 0;$0003
CopyDynWord 4;$1003
CopyDynWord 8;$2003
CopyDynWord 12;$3003
CopyDynWord 16;$4003
CopyDynWord 20;$5003
CopyDynWord 24;$6003
CopyDynWord 28;$7003
clc
lda _JTBL_CACHE
adc #32 ; All the snippets are 32 bytes wide and, since we're
sta _JTBL_CACHE ; within one tile, the second column is consecutive
lda _OP_CACHE
adc #$0200 ; Advance to the next word
sta _OP_CACHE
CopyDynWord 2;$0000
CopyDynWord 6;$1000
CopyDynWord 10;$2000
CopyDynWord 14;$3000
CopyDynWord 18;$4000
CopyDynWord 22;$5000
CopyDynWord 26;$6000
CopyDynWord 30;$7000
plb
rts
_TBDynamicSpriteTile_00
sty _Y_REG ; This is restored in the macro
sta _X_REG ; Cache some column values derived from _X_REG
tax
clc
ldal JTableOffset,x ; Get the address offset and add to the base address
adc _BASE_ADDR ; of the current code field line
sta _JTBL_CACHE
lda _TILE_ID ; Get the original tile descriptor
and #$007F ; clamp to < (32 * 4)
ora #$B500
xba
sta _OP_CACHE ; This is the 2-byte opcode for to load the data
ldx _SPR_X_REG
CopyDynSpriteWord {0*SPRITE_PLANE_SPAN};$0003
CopyDynSpriteWord {1*SPRITE_PLANE_SPAN};$1003
CopyDynSpriteWord {2*SPRITE_PLANE_SPAN};$2003
CopyDynSpriteWord {3*SPRITE_PLANE_SPAN};$3003
CopyDynSpriteWord {4*SPRITE_PLANE_SPAN};$4003
CopyDynSpriteWord {5*SPRITE_PLANE_SPAN};$5003
CopyDynSpriteWord {6*SPRITE_PLANE_SPAN};$6003
CopyDynSpriteWord {7*SPRITE_PLANE_SPAN};$7003
ldx _X_REG
clc
ldal JTableOffset+2,x ; Get the address offset and add to the base address
adc _BASE_ADDR ; of the current code field line
sta _JTBL_CACHE
lda _OP_CACHE
adc #$0200
sta _OP_CACHE
ldx _SPR_X_REG
CopyDynSpriteWord {0*SPRITE_PLANE_SPAN}+2;$0000
CopyDynSpriteWord {1*SPRITE_PLANE_SPAN}+2;$1000
CopyDynSpriteWord {2*SPRITE_PLANE_SPAN}+2;$2000
CopyDynSpriteWord {3*SPRITE_PLANE_SPAN}+2;$3000
CopyDynSpriteWord {4*SPRITE_PLANE_SPAN}+2;$4000
CopyDynSpriteWord {5*SPRITE_PLANE_SPAN}+2;$5000
CopyDynSpriteWord {6*SPRITE_PLANE_SPAN}+2;$6000
CopyDynSpriteWord {7*SPRITE_PLANE_SPAN}+2;$7000
rts
; Create a masked render based on data in the direct page temporary buffer
;
; ]1 : sprite buffer offset
; ]2 : code field offset
CopyDynWord 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
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&$F000} ; 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 #$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 #$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
next
<<<
; Masked renderer for a dynamic tile with sprite data overlaid.
;
; ]1 : sprite plane offset
; ]2 : code field offset
CopyDynSpriteWord MAC
; Need to fill in the first 10 bytes of the JMP handler with the following code sequence where
; the data and mask from from the sprite plane
;
; lda $00,x
; and #MASK
; ora #DATA
; bra *+15
;
; If MASK == 0, then we can do a PEA. If MASK == $FFFF, then fall back to the simple Dynamic Tile
; code.
ldal spritemask+{]1},x ; 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
ldal spritedata+{]1},x ; 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
lda #$004C ; JMP to handler
sta: ]2,y
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
ora #{]2&$F000} ; adjust for the current row offset
sta: ]2+1,y
tay ; 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,y
lda #$0029 ; AND #SPRITE_MASK
sta: $0002,y
ldal spritemask+{]1},x
sta: $0003,y
lda #$0009 ; ORA #SPRITE_DATA
sta: $0005,y
ldal spritedata+{]1},x
sta: $0006,y
lda #$0D80 ; branch to the prologue (BRA *+15)
sta: $0008,y
ldy _Y_REG ; restore original y-register value and move on
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
next
eom