mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-11-25 15:32:59 +00:00
Streamlining tile blitter macros
This commit is contained in:
parent
4c31a0d056
commit
b4871efe8f
@ -340,110 +340,66 @@ transparent
|
|||||||
next
|
next
|
||||||
eom
|
eom
|
||||||
|
|
||||||
; Masked renderer for a dynamic tile. What's interesting about this renderer is that the mask
|
|
||||||
; value is not used directly, but simply indicates if we can use a LDA 0,x / PHA sequence,
|
|
||||||
; a LDA (00),y / PHA, or a JMP to a blended render
|
|
||||||
;
|
|
||||||
; If a dynamic tile is animated, there is the possibility to create a special mask that marks
|
|
||||||
; words of the tile that a front / back / mixed across all frames.
|
|
||||||
;
|
|
||||||
; ]1 : tiledata offset
|
|
||||||
; ]2 : tilemask offset
|
|
||||||
; ]3 : code field offset
|
|
||||||
CopyMaskedDWord MAC
|
|
||||||
|
|
||||||
; Need to fill in the first 6 bytes of the JMP handler with the following code sequence
|
|
||||||
;
|
|
||||||
; lda (00),y
|
|
||||||
; and $80,x
|
|
||||||
; ora $00,x
|
|
||||||
|
|
||||||
ldx _X_REG ; Get the addressing offset
|
|
||||||
ldal JTableOffset,x ; Get the address offset and add to the base address
|
|
||||||
adc _BASE_ADDR ; of the current code field line
|
|
||||||
adc #{]1&$F000} ; adjust for the current row offset
|
|
||||||
sta: ]1+1,y
|
|
||||||
|
|
||||||
tax ; This becomes the new address that we use to patch in
|
|
||||||
lda _X_REG ; Get the offset and render a LDA (dp),y instruction
|
|
||||||
|
|
||||||
sep #$20 ; Easier to do 8-bit operations
|
|
||||||
sta: $0001,x ; Set the LDA (00),y operand
|
|
||||||
lda #$B1
|
|
||||||
sta: $0000,x ; Set the LDA (00),y opcode
|
|
||||||
|
|
||||||
lda _T_PTR
|
|
||||||
sta: $0005,x ; Set ORA 00,x operand
|
|
||||||
ora #$80
|
|
||||||
sta: $0003,x ; Set AND 00,x operand
|
|
||||||
lda #$35
|
|
||||||
sta: $0002,x ; Set AND 00,x opcode
|
|
||||||
lda #$15
|
|
||||||
sta: $0004,x ; Set ORA 00,x opcode
|
|
||||||
rep #$30
|
|
||||||
|
|
||||||
lda #$0F80 ; branch to the prologue (BRA *+17)
|
|
||||||
sta: $0006,x
|
|
||||||
eom
|
|
||||||
|
|
||||||
|
|
||||||
; Masked renderer for a dynamic tile with sprite data overlaid.
|
; Masked renderer for a dynamic tile with sprite data overlaid.
|
||||||
;
|
;
|
||||||
; If a dynamic tile is animated, there is the possibility to create a special mask that marks
|
; ]1 : sprite plane offset
|
||||||
; words of the tile that a front / back / mixed across all frames.
|
; ]2 : code field offset
|
||||||
;
|
CopyDynSpriteWord MAC
|
||||||
; ]1 : tiledata offset
|
|
||||||
; ]2 : tilemask offset
|
|
||||||
; ]3 : code field offset
|
|
||||||
CopyMaskedDynSpriteWord MAC
|
|
||||||
|
|
||||||
; Need to fill in the first 12 bytes of the JMP handler with the following code sequence
|
; 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),y
|
; lda $00,x
|
||||||
; and $80,x
|
|
||||||
; ora $00,x
|
|
||||||
; and #MASK
|
; and #MASK
|
||||||
; ora #DATA
|
; ora #DATA
|
||||||
; bra *+11
|
; bra *+15
|
||||||
;
|
;
|
||||||
; If MASK == 0, then we can do a PEA. If MASK == $FFFF, then fall back to the simple Dynamic Masked
|
; If MASK == 0, then we can do a PEA. If MASK == $FFFF, then fall back to the simple Dynamic Tile
|
||||||
; code.
|
; 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
|
||||||
|
|
||||||
ldx _X_REG ; Get the addressing offset
|
mixed cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
|
||||||
ldal JTableOffset,x ; Get the address offset and add to the base address
|
beq transparent
|
||||||
adc _BASE_ADDR ; of the current code field line
|
|
||||||
|
lda _JTBL_CACHE ; Get the offset to the exception handler for this column
|
||||||
adc #{]1&$F000} ; adjust for the current row offset
|
adc #{]1&$F000} ; adjust for the current row offset
|
||||||
sta: ]1+1,y
|
sta: ]1+1,y
|
||||||
|
|
||||||
tax ; This becomes the new address that we use to patch in
|
tay ; This becomes the new address that we use to patch in
|
||||||
lda _X_REG ; Get the offset and render a LDA (dp),y instruction
|
ldx _SPR_X_REG ; Offset into the sprite plane
|
||||||
|
|
||||||
sep #$20 ; Easier to do 8-bit operations
|
lda _OP_CACHE ; Get the LDA dp,x instruction for this column
|
||||||
sta: $0001,x ; Set the LDA (00),y operand
|
sta: $0000,y
|
||||||
lda #$B1
|
|
||||||
sta: $0000,x ; Set the LDA (00),y opcode
|
|
||||||
|
|
||||||
lda _T_PTR
|
lda #$0029 ; AND #SPRITE_MASK
|
||||||
sta: $0005,x ; Set ORA 00,x operand
|
sta: $0002,y
|
||||||
ora #$80
|
ldal spritemask+]1,x
|
||||||
sta: $0003,x ; Set AND 00,x operand
|
sta: $0003,y
|
||||||
lda #$35
|
|
||||||
sta: $0002,x ; Set AND 00,x opcode
|
|
||||||
lda #$15
|
|
||||||
sta: $0004,x ; Set ORA 00,x opcode
|
|
||||||
|
|
||||||
lda #$29
|
lda #$0009 ; ORA #SPRITE_DATA
|
||||||
sta: $0006,y ; AND #$0000 opcode
|
sta: $0005,y
|
||||||
lda #$09
|
ldal spritedata+]1,x
|
||||||
sta: $0009,y ; ORA #$0000 opcode
|
sta: $0006,y
|
||||||
rep #$20
|
|
||||||
|
|
||||||
lda ]1+32 ; insert the tile mask and data into the exception
|
lda #$0D80 ; branch to the prologue (BRA *+15)
|
||||||
sta: $0007,y ; handler.
|
sta: $0008,y
|
||||||
lda ]1
|
|
||||||
sta: $000A,y
|
|
||||||
|
|
||||||
lda #$0990 ; BCC *+11
|
ldy _Y_REG ; restore original y-register value and move on
|
||||||
sta: $000C,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
|
||||||
eom
|
eom
|
||||||
|
@ -412,7 +412,7 @@ ReadControl ENT
|
|||||||
put blitter/Tiles00011.s ; dynamic masked tiles
|
put blitter/Tiles00011.s ; dynamic masked tiles
|
||||||
|
|
||||||
put blitter/Tiles10000.s ; normal tiles + sprites
|
put blitter/Tiles10000.s ; normal tiles + sprites
|
||||||
; put blitter/Tiles10001.s
|
put blitter/Tiles10001.s
|
||||||
put blitter/Tiles10010.s ; normal masked tiles + sprites
|
put blitter/Tiles10010.s ; normal masked tiles + sprites
|
||||||
; put blitter/Tiles10011.s
|
; put blitter/Tiles10011.s
|
||||||
put blitter/Tiles11000.s ; normal high priority tile + sprites
|
put blitter/Tiles11000.s ; normal high priority tile + sprites
|
||||||
|
@ -48,6 +48,9 @@ _Y_REG equ tiletmp+2
|
|||||||
_T_PTR equ tiletmp+4 ; Copy of the tile address pointer
|
_T_PTR equ tiletmp+4 ; Copy of the tile address pointer
|
||||||
_BASE_ADDR equ tiletmp+6 ; Copy of BTableLow for this tile
|
_BASE_ADDR equ tiletmp+6 ; Copy of BTableLow for this tile
|
||||||
_SPR_X_REG equ tiletmp+8 ; Cache address of sprite plane source for a tile
|
_SPR_X_REG equ tiletmp+8 ; Cache address of sprite plane source for a tile
|
||||||
|
_JTBL_CACHE equ tiletmp+10 ; Cache the offset to the exception handler for a column
|
||||||
|
_OP_CACHE equ tiletmp+12 ; Cache of a relevant operand / oeprator
|
||||||
|
_TILE_ID equ tiletmp+14 ; Copy of the tile descriptor
|
||||||
|
|
||||||
; Low-level function to take a tile descriptor and return the address in the tiledata
|
; Low-level function to take a tile descriptor and return the address in the tiledata
|
||||||
; bank. This is not too useful in the fast-path because the fast-path does more
|
; bank. This is not too useful in the fast-path because the fast-path does more
|
||||||
@ -119,7 +122,7 @@ _RenderTile2
|
|||||||
stx _SPR_X_REG
|
stx _SPR_X_REG
|
||||||
|
|
||||||
:nosprite
|
:nosprite
|
||||||
sta tmp0 ; Some tile blitters need to get the tile descriptor
|
sta _TILE_ID ; Some tile blitters need to get the tile descriptor
|
||||||
and #TILE_CTRL_MASK
|
and #TILE_CTRL_MASK
|
||||||
xba
|
xba
|
||||||
tax
|
tax
|
||||||
@ -180,10 +183,11 @@ TileProcs dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolid
|
|||||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00
|
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00
|
||||||
|
|
||||||
; Here are all the sprite variants of the tiles
|
; Here are all the sprite variants of the tiles
|
||||||
dw _TBSolidSpriteTile_00,_TBSolidSpriteTile_0H,
|
dw _TBSolidSpriteTile_00,_TBSolidSpriteTile_0H
|
||||||
dw _TBSolidSpriteTile_V0,_TBSolidSpriteTile_VH ; 10000 : normal tiles w/sprite
|
dw _TBSolidSpriteTile_V0,_TBSolidSpriteTile_VH ; 10000 : normal tiles w/sprite
|
||||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10001 : dynamic tiles w/sprite
|
dw _TBDynamicSpriteTile_00,_TBDynamicSpriteTile_00
|
||||||
dw _TBMaskedSpriteTile_00,_TBMaskedSpriteTile_0H,
|
dw _TBDynamicSpriteTile_00,_TBDynamicSpriteTile_00 ; 10001 : dynamic tiles w/sprite
|
||||||
|
dw _TBMaskedSpriteTile_00,_TBMaskedSpriteTile_0H
|
||||||
dw _TBMaskedSpriteTile_V0,_TBMaskedSpriteTile_VH ; 10010 : masked normal tiles w/sprite
|
dw _TBMaskedSpriteTile_V0,_TBMaskedSpriteTile_VH ; 10010 : masked normal tiles w/sprite
|
||||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10011 : masked dynamic tiles w/sprite
|
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10011 : masked dynamic tiles w/sprite
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ _TBDynamicTile_00
|
|||||||
; LDA 00,x / PHA where the operand is fixed when the tile is rendered
|
; LDA 00,x / PHA where the operand is fixed when the tile is rendered
|
||||||
; $B5 $00 $48
|
; $B5 $00 $48
|
||||||
_TBDynamicData
|
_TBDynamicData
|
||||||
lda tmp0 ; Get the original tile descriptor
|
lda _TILE_ID ; Get the original tile descriptor
|
||||||
and #$007F ; clamp to < (32 * 4)
|
and #$007F ; clamp to < (32 * 4)
|
||||||
ora #$4800 ; insert the PHA instruction
|
ora #$4800 ; insert the PHA instruction
|
||||||
|
|
||||||
|
@ -8,11 +8,26 @@ _TBDynamicMaskTile_00
|
|||||||
|
|
||||||
; A = dynamic tile id (must be <32)
|
; A = dynamic tile id (must be <32)
|
||||||
_TBDynamicDataAndMask
|
_TBDynamicDataAndMask
|
||||||
sta _X_REG
|
sta _X_REG ; Cache some column values derived from _X_REG
|
||||||
|
tax
|
||||||
|
ora #$B100 ; Pre-calc the LDA (dp),y opcode + operand
|
||||||
|
xba
|
||||||
|
sta _OP_CACHE
|
||||||
|
|
||||||
lda tmp0 ; get the original tile descriptor
|
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
|
||||||
|
|
||||||
|
; We need to do an AND dp|$80,x / ORA dp,x. The opcode values are $35 and $15, respectively.
|
||||||
|
; We pre-calculate the AND opcode with the high bit of the operand set and then, in the macro
|
||||||
|
; perform and EOR #$2080 to covert the opcode and operand in one instruction
|
||||||
|
|
||||||
|
lda _TILE_ID ; Get the original tile descriptor
|
||||||
and #$007F ; clamp to < (32 * 4)
|
and #$007F ; clamp to < (32 * 4)
|
||||||
sta _T_PTR
|
ora #$3580 ; Pre-calc the AND $80,x opcode + operand
|
||||||
|
xba
|
||||||
|
sta _T_PTR ; This is an op to load the dynamic tile data
|
||||||
|
|
||||||
CopyMaskedDWord $0003
|
CopyMaskedDWord $0003
|
||||||
CopyMaskedDWord $1003
|
CopyMaskedDWord $1003
|
||||||
@ -23,10 +38,20 @@ _TBDynamicDataAndMask
|
|||||||
CopyMaskedDWord $6003
|
CopyMaskedDWord $6003
|
||||||
CopyMaskedDWord $7003
|
CopyMaskedDWord $7003
|
||||||
|
|
||||||
inc _T_PTR ; Move to the next column
|
ldx _X_REG
|
||||||
inc _T_PTR
|
inx
|
||||||
inc _X_REG ; Move to the next column
|
inx
|
||||||
inc _X_REG
|
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 _OP_CACHE
|
||||||
|
adc #$0200
|
||||||
|
sta _OP_CACHE
|
||||||
|
lda _T_PTR
|
||||||
|
adc #$0200
|
||||||
|
sta _T_PTR
|
||||||
|
|
||||||
CopyMaskedDWord $0000
|
CopyMaskedDWord $0000
|
||||||
CopyMaskedDWord $1000
|
CopyMaskedDWord $1000
|
||||||
@ -61,3 +86,39 @@ _TBFillJMPOpcode
|
|||||||
sta $7003,y
|
sta $7003,y
|
||||||
rep #$20
|
rep #$20
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; Masked renderer for a dynamic tile. What's interesting about this renderer is that the mask
|
||||||
|
; value is not used directly, but simply indicates if we can use a LDA 0,x / PHA sequence,
|
||||||
|
; a LDA (00),y / PHA, or a JMP to a blended render
|
||||||
|
;
|
||||||
|
; If a dynamic tile is animated, there is the possibility to create a special mask that marks
|
||||||
|
; words of the tile that a front / back / mixed across all frames.
|
||||||
|
;
|
||||||
|
; ]1 : code field offset
|
||||||
|
;
|
||||||
|
; This macro does not set the opcode since they will all be JMP instructions, they can be
|
||||||
|
; filled more efficiently in a separate routine.
|
||||||
|
CopyMaskedDWord MAC
|
||||||
|
|
||||||
|
; Need to fill in the first 6 bytes of the JMP handler with the following code sequence
|
||||||
|
;
|
||||||
|
; lda (00),y
|
||||||
|
; and $80,x
|
||||||
|
; ora $00,x
|
||||||
|
; bra *+17
|
||||||
|
|
||||||
|
lda _JTBL_CACHE
|
||||||
|
ora #{]1&$F000} ; adjust for the current row offset
|
||||||
|
sta: ]1+1,y
|
||||||
|
|
||||||
|
tax ; This becomes the new address that we use to patch in
|
||||||
|
lda _OP_CACHE
|
||||||
|
sta: $0000,x ; LDA (00),y
|
||||||
|
lda _T_PTR
|
||||||
|
sta: $0002,x ; AND $80,x
|
||||||
|
eor #$2080 ; Switch the opcode to an ORA and remove the high bit of the operand
|
||||||
|
sta: $0004,x ; ORA $00,x
|
||||||
|
lda #$0F80 ; branch to the prologue (BRA *+17)
|
||||||
|
sta: $0006,x
|
||||||
|
eom
|
52
src/blitter/Tiles10001.s
Normal file
52
src/blitter/Tiles10001.s
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
; _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_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
|
||||||
|
|
||||||
|
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
|
||||||
|
inx
|
||||||
|
inx
|
||||||
|
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 _OP_CACHE
|
||||||
|
adc #$0200
|
||||||
|
sta _OP_CACHE
|
||||||
|
|
||||||
|
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
|
Loading…
Reference in New Issue
Block a user