mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2024-12-28 18:29:19 +00:00
Merge pull request #3 from lscharen/expand-exception-handler-space
Expand exception handler space
This commit is contained in:
commit
c08a4f7278
@ -36,10 +36,13 @@ DOWN_ARROW equ $0A
|
||||
jsl SetPalette
|
||||
|
||||
ldx #5 ; Mode 0 is full-screen, mode 5 is 256x160
|
||||
ldx #320
|
||||
ldy #144
|
||||
jsl SetScreenMode
|
||||
|
||||
; Set up our level data
|
||||
jsr BG0SetUp
|
||||
jsr TileAnimInit
|
||||
jsr SetLimits
|
||||
|
||||
jsr InitOverlay ; Initialize the status bar
|
||||
@ -239,7 +242,11 @@ EvtLoop
|
||||
ldy PlayerY
|
||||
jsl UpdateSprite ; Move the sprite to this local position
|
||||
|
||||
; Update the timers
|
||||
jsl DoTimers
|
||||
|
||||
; Let's see what it looks like!
|
||||
|
||||
lda vsync
|
||||
beq :no_vsync
|
||||
:vsyncloop jsl GetVerticalCounter ; 8-bit value
|
||||
@ -281,7 +288,7 @@ Exit
|
||||
bcs Fatal
|
||||
Fatal brk $00
|
||||
|
||||
BG1DataFile strl '1/octane.c1'
|
||||
BG1DataFile strl '1/sunset.c1'
|
||||
|
||||
; Color palette
|
||||
; MyPalette dw $068F,$0EDA,$0000,$0E51,$0BF1,$00A0,$0EEE,$0456,$0FA4,$0F59,$0E30,$01CE,$02E3,$0870,$0F93,$0FD7
|
||||
|
@ -208,7 +208,7 @@ App_TileMapBG0
|
||||
dw $1021,$1021,$1031,$1032,$1021,$1021,$100f,$0010,$0011,$1012,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$100f,$0010,$0011,$1012,$1021,$1021,$0007,$0008,$0007,$0008,$0007,$0008,$0007,$0008,$0007,$0008,$0007,$0008,$0007,$0008,$0007,$0008,$1021,$1021,$1021,$1021
|
||||
dw $1021,$1021,$1030,$0015,$0015,$0015,$0015,$1033,$1021,$1021,$1021,$1021,$1009,$100a,$1021,$1021,$1021,$1021,$1021,$1021,$001a,$001a,$001a,$001a,$0040,$0040,$001a,$001a,$001a,$001a,$1021,$1021
|
||||
|
||||
dw $1021,$1030,$0015,$0036,$0015,$0015,$0036,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1022,$1023,$1022,$1023,$1022,$1023,$1021,$1021,$1021,$1030,$0015,$0036,$1230,$1021,$1021,$1057,$1056,$1057,$1056,$1057,$1056,$1057,$1056,$1021,$1022,$1023,$1021,$1021,$1057,$1056,$1057,$1056,$1013,$0014,$0015,$1016,$1021,$1021,$1021,$1021
|
||||
dw $1021,$1030,$0015,$0036,$0015,$0015,$0036,$0015,$1033,$1021,$1800,$1804,$0800,$0804,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1022,$1023,$1022,$1023,$1022,$1023,$1021,$1021,$1021,$1030,$0015,$0036,$1230,$1021,$1021,$1057,$1056,$1057,$1056,$1057,$1056,$1057,$1056,$1021,$1022,$1023,$1021,$1021,$1057,$1056,$1057,$1056,$1013,$0014,$0015,$1016,$1021,$1021,$1021,$1021
|
||||
dw $1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1013,$0014,$0015,$1016,$1021,$1021,$1021,$1021,$1022,$1023,$1022,$1023,$1021,$1021,$1021,$1021,$1013,$0014,$0015,$1016,$1021,$1030,$0015,$0036,$0015,$0015,$0036,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1013,$0014,$0015,$1016,$1021,$1021,$1022,$1023,$1022,$1023,$1022,$1023,$1021,$1021
|
||||
dw $1021,$1030,$0015,$0036,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1022,$1023,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1022,$1023,$1022,$1023,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021
|
||||
dw $1021,$1030,$0015,$0036,$0015,$0015,$0036,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1022,$1023,$1022,$1023,$1022,$1023,$1021,$1021,$1021,$1030,$0015,$0036,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1022,$1023,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021
|
||||
@ -216,7 +216,7 @@ App_TileMapBG0
|
||||
dw $1021,$1030,$0015,$0036,$1033,$1021,$1013,$0014,$0015,$1016,$1021,$1021,$1021,$1021,$0000,$1021,$1022,$1023,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1013,$0014,$0015,$1016,$0005,$0006,$0005,$0006,$0005,$0006,$0005,$0006,$0005,$0006,$0005,$0006,$0005,$0006,$0005,$0006,$0005,$0006,$1021,$1021,$1021,$1021
|
||||
dw $1021,$1030,$0015,$0036,$0015,$0015,$0036,$0015,$1033,$1021,$1021,$1021,$0005,$0006,$1021,$1021,$1021,$1021,$1021,$1021,$001a,$001a,$001a,$001a,$0040,$0040,$001a,$001a,$001a,$001a,$1021,$1021
|
||||
|
||||
dw $1030,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1024,$0025,$0025,$0025,$0025,$0025,$0025,$1026,$1021,$1030,$0015,$0015,$0015,$0015,$1230,$1021,$1077,$1076,$1077,$1076,$1077,$1076,$1077,$1076,$1024,$0025,$0025,$1026,$1021,$1077,$1076,$1077,$1076,$1013,$0014,$0015,$1016,$1021,$1021,$1021,$1021
|
||||
dw $1030,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$1033,$1808,$180C,$0808,$080C,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1024,$0025,$0025,$0025,$0025,$0025,$0025,$1026,$1021,$1030,$0015,$0015,$0015,$0015,$1230,$1021,$1077,$1076,$1077,$1076,$1077,$1076,$1077,$1076,$1024,$0025,$0025,$1026,$1021,$1077,$1076,$1077,$1076,$1013,$0014,$0015,$1016,$1021,$1021,$1021,$1021
|
||||
dw $1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1013,$0014,$0015,$1016,$1021,$1021,$1021,$1024,$0025,$0025,$0025,$0025,$1026,$1021,$1021,$1021,$1013,$0014,$0015,$1016,$1030,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1013,$0014,$0015,$1016,$1021,$1024,$0025,$0025,$0025,$0025,$0025,$0025,$1026,$1021
|
||||
dw $1030,$0015,$0015,$0015,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1024,$0025,$0025,$1026,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1024,$0025,$0025,$0025,$0025,$1026,$1021,$1021,$1021,$1021,$1021,$1021,$1021
|
||||
dw $1030,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1024,$0025,$0025,$0025,$0025,$0025,$0025,$1026,$1021,$1030,$0015,$0015,$0015,$0015,$1033,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1024,$0025,$0025,$1026,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021,$1021
|
||||
|
@ -219,7 +219,7 @@ mixed cmp #$FFFF ; All 1's in the mask is fully transparent
|
||||
; This is the slowest path because there is a *lot* of work to do. So much that it's
|
||||
; worth it to change up the environment to optimize things a bit more.
|
||||
;
|
||||
; Need to fill in the first 8 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
|
||||
;
|
||||
; lda (00),y
|
||||
; and #MASK
|
||||
@ -252,6 +252,9 @@ mixed cmp #$FFFF ; All 1's in the mask is fully transparent
|
||||
lda ]1
|
||||
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
|
||||
|
||||
@ -321,6 +324,9 @@ mixed cmp #$FFFF ; All 1's in the mask is fully transparent
|
||||
ldal ]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
|
||||
|
||||
@ -333,103 +339,3 @@ transparent
|
||||
sta: ]3+1,y
|
||||
next
|
||||
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 8 bytes of the JMP handler with the following code sequence
|
||||
;
|
||||
; lda (00),y
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; bcc *+4
|
||||
|
||||
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 operand
|
||||
lda #$15
|
||||
sta: $0004,x ; Set ORA 00,x operand
|
||||
rep #$30
|
||||
|
||||
lda #$0290 ; BCC *+4
|
||||
sta: $0006,x
|
||||
eom
|
||||
|
||||
|
||||
; Masked renderer for a dynamic tile with sprite data overlaid. 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
|
||||
CopyMaskedDynSpriteWord MAC
|
||||
|
||||
; Need to fill in the first 12(!!) bytes of the JMP handler with the following code sequence
|
||||
;
|
||||
; lda (00),y
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
;
|
||||
; If MASK == 0, then we can do a PEA. If MASK == $FFFF, then fall back to the simple Dynamic Masked
|
||||
; code.
|
||||
|
||||
|
||||
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 operand
|
||||
lda #$15
|
||||
sta: $0004,x ; Set ORA 00,x operand
|
||||
rep #$30
|
||||
|
||||
lda #$0290 ; BCC *+4
|
||||
sta: $0006,x
|
||||
eom
|
||||
|
13
src/Core.s
13
src/Core.s
@ -8,7 +8,7 @@
|
||||
use .\Defs.s
|
||||
|
||||
; Feature flags
|
||||
NO_INTERRUPTS equ 1 ; turn off for crossrunner debugging
|
||||
NO_INTERRUPTS equ 0 ; turn off for crossrunner debugging
|
||||
NO_MUSIC equ 1 ; turn music + tool loading off
|
||||
|
||||
; External data provided by the main program segment
|
||||
@ -412,10 +412,15 @@ ReadControl ENT
|
||||
put blitter/Tiles00011.s ; dynamic masked tiles
|
||||
|
||||
put blitter/Tiles10000.s ; normal tiles + sprites
|
||||
; put blitter/Tiles10001.s
|
||||
put blitter/Tiles10001.s ; dynamic tiles + sprites
|
||||
put blitter/Tiles10010.s ; normal masked tiles + sprites
|
||||
; put blitter/Tiles10011.s
|
||||
put blitter/Tiles11000.s ; normal high priority tile + sprites
|
||||
put blitter/Tiles10011.s ; dynamic masked tiles + sprites
|
||||
|
||||
put blitter/Tiles11000.s ; normal high priority tiles + sprites
|
||||
put blitter/Tiles11001.s ; dynamic high priority tiles + sprites
|
||||
put blitter/Tiles11010.s ; normal high priority masked tiles + sprites
|
||||
put blitter/Tiles11011.s ; dynamic high priority masked tiles + sprites
|
||||
|
||||
put blitter/TilesBG1.s
|
||||
put blitter/Vert.s
|
||||
put blitter/BG0.s
|
||||
|
@ -37,8 +37,18 @@ PagePatches da {long_0-base+2}
|
||||
da {loop_back-base+2}
|
||||
da {loop_exit_3-base+2}
|
||||
da {even_exit-base+2}
|
||||
da {jmp_rtn_1-base+2}
|
||||
da {jmp_rtn_2-base+2}
|
||||
|
||||
]index equ 0
|
||||
lup 82 ; All the snippet addresses. The two JMP
|
||||
da {snippets-base+{]index*32}+31} ; instructino are at the end of each of
|
||||
da {snippets-base+{]index*32}+28} ; the 32-byte buffers
|
||||
]index equ ]index+1
|
||||
--^
|
||||
PagePatchNum equ *-PagePatches
|
||||
|
||||
; Location that need a bank byte set for long addressing modes
|
||||
BankPatches da {long_0-base+3}
|
||||
da {long_1-base+3}
|
||||
da {long_2-base+3}
|
||||
@ -483,7 +493,9 @@ BuildBank
|
||||
; 13 banks for a total of 208 lines, which is what is required to render 26 tiles
|
||||
; to cover the full screen vertical scrolling.
|
||||
;
|
||||
; The 'base' location is always assumed to be on a 4kb ($1000) boundary
|
||||
; The 'base' location is always assumed to be on a 4kb ($1000) boundary. We make sure that
|
||||
; the code is assembled on a page boundary to help will alignment
|
||||
ds \,$00 ; pad to the next page boundary
|
||||
base
|
||||
entry_1 ldx #0000 ; Used for LDA 00,x addressing
|
||||
entry_2 ldy #0000 ; Used for LDA (00),y addressing
|
||||
@ -538,7 +550,7 @@ long_3 stal *+5-base
|
||||
full_return jml blt_return ; Full exit
|
||||
|
||||
; Re-enable interrupts and continue -- the even_exit JMP from the previous line will jump here every
|
||||
; 8 or 16 lines in order to give the system some extra time to handle interrupts.
|
||||
; 8 or 16 lines in order to give the system time to handle interrupts.
|
||||
enable_int ldal stk_save+1 ; restore the stack
|
||||
tcs
|
||||
sep #$20 ; 8-bit mode
|
||||
@ -554,13 +566,26 @@ enable_int ldal stk_save+1 ; restore the stack
|
||||
rep #$20
|
||||
bra entry_1
|
||||
|
||||
; The even/odd branch of this line's exception handler will return here. This is mostly
|
||||
; a space-saving measure to allow for more code in the exeption handers themselved, but
|
||||
; also simplified the relocation process since we only have to update a single address
|
||||
; in each exception handler, rather than two.
|
||||
;
|
||||
; Oce working, this code should be able to be interleaved with the r_jmp_rtn code
|
||||
; above to eliminate a couple of branches
|
||||
jmp_rtn
|
||||
bvs jmp_rtn_v ; overflow set means this is the right edge (entry)
|
||||
clc ; carry is set only for edge operations; force clear
|
||||
jmp_rtn_1 jmp l_jmp_rtn-base
|
||||
jmp_rtn_v rep #$41 ; clear V and C
|
||||
jmp_rtn_2 jmp r_jmp_rtn-base
|
||||
|
||||
; This is the spot that needs to be page-aligned. In addition to simplifying the entry address
|
||||
; and only needing to update a byte instad of a word, because the code breaks out of the
|
||||
; code field with a BRA instruction, we keep everything within a page to avoid the 1-cycle
|
||||
; page-crossing penalty of the branch.
|
||||
|
||||
ds 166
|
||||
ds \,$00 ; pad to the next page boundary
|
||||
loop_exit_1 jmp odd_exit-base ; +0 Alternate exit point depending on whether the left edge is
|
||||
loop_exit_2 jmp even_exit-base ; +3 odd-aligned
|
||||
|
||||
@ -685,32 +710,25 @@ epilogue_1 tsc
|
||||
; r_edge rep #$41
|
||||
; brl r_jmp_rtn ; 3
|
||||
|
||||
|
||||
; Each snippet is provided 32 bytes of space. The constant code is filled in from the end and
|
||||
; it is the responsibility of the code that fills in the hander to create valid program in the
|
||||
; first 23 bytes are available to be manipulated.
|
||||
;
|
||||
; Note that the code that's assembled in the first bytes of these snippets is just an example. Every
|
||||
; routine that created an exception handler *MUST* write a full set of instructions since there is
|
||||
; no guarantee of what was written previously.
|
||||
ds \,$00 ; pad to the next page boundary
|
||||
]index equ 0
|
||||
snippets lup 82
|
||||
ds 2 ; space for a 2-byte sequence; LDA (00),y LDA 00,x LDA 0,s
|
||||
ds 2 ; space for all exception handlers
|
||||
and #$0000 ; the mask operand will be set when the tile is drawn
|
||||
ora #$0000 ; the data operand will be set when the tile is drawn
|
||||
bcs *+6
|
||||
pha
|
||||
brl loop+3+{3*]index} ; use relative branch for convenience
|
||||
bvs *+6 ; overflow set means this is the right edge (entry)
|
||||
clc ; carry is set only for edge operations; force clear
|
||||
brl l_jmp_rtn
|
||||
rep #$41 ; clear V and C
|
||||
brl r_jmp_rtn ; 25 bytes
|
||||
ds 7 ; padding
|
||||
ds 15 ; extra padding
|
||||
|
||||
bcs :byte ; if C = 0, just push the data and return
|
||||
pha ; 1 byte
|
||||
jmp loop+3+{3*]index}-base ; 3 bytes : use relative branch for convenience
|
||||
:byte jmp jmp_rtn-base ; 3 bytes
|
||||
]index equ ]index+1
|
||||
--^
|
||||
top
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
top
|
@ -48,6 +48,9 @@ _Y_REG equ tiletmp+2
|
||||
_T_PTR equ tiletmp+4 ; Copy of the tile address pointer
|
||||
_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
|
||||
_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
|
||||
; bank. This is not too useful in the fast-path because the fast-path does more
|
||||
@ -119,6 +122,7 @@ _RenderTile2
|
||||
stx _SPR_X_REG
|
||||
|
||||
:nosprite
|
||||
sta _TILE_ID ; Some tile blitters need to get the tile descriptor
|
||||
and #TILE_CTRL_MASK
|
||||
xba
|
||||
tax
|
||||
@ -179,12 +183,14 @@ TileProcs dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolid
|
||||
dw _TBDynamicMaskTile_00,_TBDynamicMaskTile_00
|
||||
|
||||
; 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 _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10001 : dynamic tiles w/sprite
|
||||
dw _TBMaskedSpriteTile_00,_TBMaskedSpriteTile_0H,
|
||||
dw _TBDynamicSpriteTile_00,_TBDynamicSpriteTile_00
|
||||
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 _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10011 : masked dynamic tiles w/sprite
|
||||
dw _TBDynamicMaskedSpriteTile_00,_TBDynamicMaskedSpriteTile_00
|
||||
dw _TBDynamicMaskedSpriteTile_00,_TBDynamicMaskedSpriteTile_00 ; 10011 : masked dynamic tiles w/sprite
|
||||
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10100 : fringed normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 10101 : fringed dynamic tiles w/sprite
|
||||
@ -193,9 +199,12 @@ TileProcs dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolid
|
||||
|
||||
dw _TBSolidPrioritySpriteTile_00,_TBSolidPrioritySpriteTile_0H,
|
||||
dw _TBSolidPrioritySpriteTile_V0,_TBSolidPrioritySpriteTile_VH ; 11000 : high-priority normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11001 : high-priority dynamic tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11010 : high-priority masked normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11011 : high-priority masked dynamic tiles w/sprite
|
||||
dw _TBDynamicPrioritySpriteTile_00,_TBDynamicPrioritySpriteTile_00
|
||||
dw _TBDynamicPrioritySpriteTile_00,_TBDynamicPrioritySpriteTile_00 ; 11001 : high-priority dynamic tiles w/sprite
|
||||
dw _TBMaskedPrioritySpriteTile_00,_TBMaskedPrioritySpriteTile_0H
|
||||
dw _TBMaskedPrioritySpriteTile_V0,_TBMaskedPrioritySpriteTile_VH ; 11010 : high-priority masked normal tiles w/sprite
|
||||
dw _TBDynamicMaskedPrioritySpriteTile_00,_TBDynamicMaskedPrioritySpriteTile_00
|
||||
dw _TBDynamicMaskedPrioritySpriteTile_00,_TBDynamicMaskedPrioritySpriteTile_00 ; 11011 : high-priority masked dynamic tiles w/sprite
|
||||
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11100 : high-priority fringed normal tiles w/sprite
|
||||
dw _TBSolidTile_00,_TBSolidTile_0H,_TBSolidTile_V0,_TBSolidTile_VH ; 11101 : high-priority fringed dynamic tiles w/sprite
|
||||
|
@ -17,11 +17,7 @@ _TBDynamicTile_00
|
||||
; LDA 00,x / PHA where the operand is fixed when the tile is rendered
|
||||
; $B5 $00 $48
|
||||
_TBDynamicData
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
xba ; Undo the x128 we just need x4
|
||||
lda _TILE_ID ; Get the original tile descriptor
|
||||
and #$007F ; clamp to < (32 * 4)
|
||||
ora #$4800 ; insert the PHA instruction
|
||||
|
||||
|
@ -8,9 +8,26 @@ _TBDynamicMaskTile_00
|
||||
|
||||
; A = dynamic tile id (must be <32)
|
||||
_TBDynamicDataAndMask
|
||||
and #$007F ; clamp to < (32 * 4)
|
||||
sta _T_PTR
|
||||
stx _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
|
||||
|
||||
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)
|
||||
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 $1003
|
||||
@ -21,10 +38,18 @@ _TBDynamicDataAndMask
|
||||
CopyMaskedDWord $6003
|
||||
CopyMaskedDWord $7003
|
||||
|
||||
inc _T_PTR ; Move to the next column
|
||||
inc _T_PTR
|
||||
inc _X_REG ; Move to the next column
|
||||
inc _X_REG
|
||||
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
|
||||
lda _T_PTR
|
||||
adc #$0200
|
||||
sta _T_PTR
|
||||
|
||||
CopyMaskedDWord $0000
|
||||
CopyMaskedDWord $1000
|
||||
@ -59,3 +84,39 @@ _TBFillJMPOpcode
|
||||
sta $7003,y
|
||||
rep #$20
|
||||
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 #$8020 ; 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
|
119
src/blitter/Tiles10001.s
Normal file
119
src/blitter/Tiles10001.s
Normal file
@ -0,0 +1,119 @@
|
||||
; _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
|
||||
|
||||
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
|
||||
|
||||
|
||||
; 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
|
@ -4,7 +4,6 @@
|
||||
_TBMaskedSpriteTile_00
|
||||
sta _X_REG ; Immedately stash the parameters
|
||||
sty _Y_REG
|
||||
; stx _T_PTR
|
||||
|
||||
jsr _TBCopyTileDataToCBuff ; Copy the tile data into the compositing buffer (using correct x-register)
|
||||
jsr _TBCopyTileMaskToCBuff ; Copy the tile mask into the compositing buffer (using correct x-register)
|
||||
|
134
src/blitter/Tiles10011.s
Normal file
134
src/blitter/Tiles10011.s
Normal file
@ -0,0 +1,134 @@
|
||||
; _TBDynamicMaskedSpriteTile
|
||||
;
|
||||
; 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
|
||||
;
|
||||
; When rendering, the background, via lda (dp),y, is shown behind the animate sprite
|
||||
_TBDynamicMaskedSpriteTile_00
|
||||
sty _Y_REG ; This is restored in the macro
|
||||
|
||||
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
|
||||
|
||||
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 #$3580 ; Pre-calc the AND $80,x opcode + operand
|
||||
xba
|
||||
sta _T_PTR ; This is an op to load the dynamic tile data
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynMaskedSpriteWord {0*SPRITE_PLANE_SPAN};$0003
|
||||
CopyDynMaskedSpriteWord {1*SPRITE_PLANE_SPAN};$1003
|
||||
CopyDynMaskedSpriteWord {2*SPRITE_PLANE_SPAN};$2003
|
||||
CopyDynMaskedSpriteWord {3*SPRITE_PLANE_SPAN};$3003
|
||||
CopyDynMaskedSpriteWord {4*SPRITE_PLANE_SPAN};$4003
|
||||
CopyDynMaskedSpriteWord {5*SPRITE_PLANE_SPAN};$5003
|
||||
CopyDynMaskedSpriteWord {6*SPRITE_PLANE_SPAN};$6003
|
||||
CopyDynMaskedSpriteWord {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
|
||||
lda _T_PTR
|
||||
adc #$0200
|
||||
sta _T_PTR
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynMaskedSpriteWord {0*SPRITE_PLANE_SPAN}+2;$0000
|
||||
CopyDynMaskedSpriteWord {1*SPRITE_PLANE_SPAN}+2;$1000
|
||||
CopyDynMaskedSpriteWord {2*SPRITE_PLANE_SPAN}+2;$2000
|
||||
CopyDynMaskedSpriteWord {3*SPRITE_PLANE_SPAN}+2;$3000
|
||||
CopyDynMaskedSpriteWord {4*SPRITE_PLANE_SPAN}+2;$4000
|
||||
CopyDynMaskedSpriteWord {5*SPRITE_PLANE_SPAN}+2;$5000
|
||||
CopyDynMaskedSpriteWord {6*SPRITE_PLANE_SPAN}+2;$6000
|
||||
CopyDynMaskedSpriteWord {7*SPRITE_PLANE_SPAN}+2;$7000
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; Masked renderer for a masked dynamic tile with sprite data overlaid.
|
||||
;
|
||||
; ]1 : sprite plane offset
|
||||
; ]2 : code field offset
|
||||
CopyDynMaskedSpriteWord MAC
|
||||
|
||||
; Need to fill in the first 14 bytes of the JMP handler with the following code sequence where
|
||||
; the data and mask from from the sprite plane
|
||||
;
|
||||
; lda ($00),y
|
||||
; and $80,x
|
||||
; ora $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 and eliminate the constanct AND/ORA instructions.
|
||||
|
||||
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
|
||||
|
||||
; We will always do a JMP to the eception handler, so set that up, then check for sprite
|
||||
; transparency
|
||||
mixed
|
||||
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
|
||||
sta: $0000,y ; LDA (00),y
|
||||
lda _T_PTR
|
||||
sta: $0002,y ; AND $80,x
|
||||
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
|
||||
sta: $0004,y ; ORA $00,x
|
||||
|
||||
lda #$0029 ; AND #SPRITE_MASK
|
||||
sta: $0006,y
|
||||
ldal spritemask+]1,x
|
||||
cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
|
||||
beq transparent ; so we can use the Tile00011 method
|
||||
sta: $0007,y
|
||||
|
||||
lda #$0009 ; ORA #SPRITE_DATA
|
||||
sta: $0009,y
|
||||
ldal spritedata+]1,x
|
||||
sta: $000A,y
|
||||
|
||||
lda #$0980 ; branch to the prologue (BRA *+11)
|
||||
sta: $000C,y
|
||||
bra next
|
||||
|
||||
; This is a transparent word, so just show the dynamic data
|
||||
transparent
|
||||
lda #$0F80 ; branch to the epilogue (BRA *+17)
|
||||
sta: $0006,y
|
||||
next
|
||||
ldy _Y_REG ; restore original y-register value and move on
|
||||
eom
|
92
src/blitter/Tiles11001.s
Normal file
92
src/blitter/Tiles11001.s
Normal file
@ -0,0 +1,92 @@
|
||||
; _TBDynamicPrioritySpriteTile
|
||||
;
|
||||
; Variant of _TBDynamicSpriteTile (Tile10001), but draw the sprite data behind the dynamic tile
|
||||
_TBDynamicPrioritySpriteTile_00
|
||||
jsr _TBDynamicPriorityDataAndMask
|
||||
jmp _TBFillJMPOpcode
|
||||
|
||||
_TBDynamicPriorityDataAndMask
|
||||
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 #$3580 ; Pre-calc the AND $80,x opcode + operand
|
||||
xba
|
||||
sta _OP_CACHE ; This is an op to load the dynamic tile data
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynPriSpriteWord {0*SPRITE_PLANE_SPAN};$0003
|
||||
CopyDynPriSpriteWord {1*SPRITE_PLANE_SPAN};$1003
|
||||
CopyDynPriSpriteWord {2*SPRITE_PLANE_SPAN};$2003
|
||||
CopyDynPriSpriteWord {3*SPRITE_PLANE_SPAN};$3003
|
||||
CopyDynPriSpriteWord {4*SPRITE_PLANE_SPAN};$4003
|
||||
CopyDynPriSpriteWord {5*SPRITE_PLANE_SPAN};$5003
|
||||
CopyDynPriSpriteWord {6*SPRITE_PLANE_SPAN};$6003
|
||||
CopyDynPriSpriteWord {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
|
||||
|
||||
CopyDynPriSpriteWord {0*SPRITE_PLANE_SPAN}+2;$0000
|
||||
CopyDynPriSpriteWord {1*SPRITE_PLANE_SPAN}+2;$1000
|
||||
CopyDynPriSpriteWord {2*SPRITE_PLANE_SPAN}+2;$2000
|
||||
CopyDynPriSpriteWord {3*SPRITE_PLANE_SPAN}+2;$3000
|
||||
CopyDynPriSpriteWord {4*SPRITE_PLANE_SPAN}+2;$4000
|
||||
CopyDynPriSpriteWord {5*SPRITE_PLANE_SPAN}+2;$5000
|
||||
CopyDynPriSpriteWord {6*SPRITE_PLANE_SPAN}+2;$6000
|
||||
CopyDynPriSpriteWord {7*SPRITE_PLANE_SPAN}+2;$7000
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; Masked renderer for a dynamic tile with sprite data overlaid.
|
||||
;
|
||||
; ]1 : sprite plane offset
|
||||
; ]2 : code field offset
|
||||
CopyDynPriSpriteWord MAC
|
||||
|
||||
; Need to fill in the first 9 bytes of the JMP handler with the following code sequence where
|
||||
; the data and mask from from the sprite plane
|
||||
;
|
||||
; lda #DATA
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; bra *+16
|
||||
|
||||
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 #$00A9 ; LDA #DATA
|
||||
sta: $0000,y
|
||||
ldal spritedata+]1,x
|
||||
sta: $0001,y
|
||||
|
||||
lda _OP_CACHE
|
||||
sta: $0003,y ; AND $80,x
|
||||
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
|
||||
sta: $0005,y ; ORA $00,x
|
||||
|
||||
lda #$0E80 ; branch to the prologue (BRA *+16)
|
||||
sta: $0007,y
|
||||
|
||||
ldy _Y_REG ; restore original y-register value and move on
|
||||
eom
|
61
src/blitter/Tiles11010.s
Normal file
61
src/blitter/Tiles11010.s
Normal file
@ -0,0 +1,61 @@
|
||||
; _TBMaskedPrioritySpriteTile
|
||||
;
|
||||
; Renders a composited tile with masking to the code field. The sprite is underlaid
|
||||
_TBMaskedPrioritySpriteTile_00
|
||||
sta _X_REG ; Immedately stash the parameters
|
||||
sty _Y_REG
|
||||
|
||||
jsr _TBCopyTileDataToCBuff ; Copy the tile data into the compositing buffer (using correct x-register)
|
||||
jsr _TBCopyTileMaskToCBuff ; Copy the tile mask into the compositing buffer (using correct x-register)
|
||||
jsr _TBUnderlaySpriteDataAndMask ; Underlay the data and mask from the sprite plane into the compositing buffer
|
||||
jmp _TBMaskedCBuff ; Render the masked tile from the compositing buffer into the code field
|
||||
|
||||
_TBMaskedPrioritySpriteTile_0H
|
||||
sta _X_REG
|
||||
sty _Y_REG
|
||||
jsr _TBCopyTileDataToCBuffH
|
||||
jsr _TBCopyTileMaskToCBuffH
|
||||
jsr _TBUnderlaySpriteDataAndMask
|
||||
jmp _TBMaskedCBuff
|
||||
|
||||
_TBMaskedPrioritySpriteTile_V0
|
||||
sta _X_REG
|
||||
sty _Y_REG
|
||||
jsr _TBCopyTileDataToCBuffV
|
||||
jsr _TBCopyTileMaskToCBuffV
|
||||
jsr _TBUnderlaySpriteDataAndMask
|
||||
jmp _TBMaskedCBuff
|
||||
|
||||
_TBMaskedPrioritySpriteTile_VH
|
||||
sta _X_REG
|
||||
sty _Y_REG
|
||||
jsr _TBCopyTileDataToCBuffVH
|
||||
jsr _TBCopyTileMaskToCBuffVH
|
||||
jsr _TBUnderlaySpriteDataAndMask
|
||||
jmp _TBMaskedCBuff
|
||||
|
||||
_TBUnderlaySpriteDataAndMask
|
||||
ldx _SPR_X_REG ; set to the unaligned tile block address in the sprite plane
|
||||
|
||||
]line equ 0
|
||||
lup 8
|
||||
ldal spritedata+{]line*SPRITE_PLANE_SPAN},x
|
||||
and blttmp+{]line*4}+32
|
||||
ora blttmp+{]line*4} ; Maybe this can be a TSB???
|
||||
sta blttmp+{]line*4}
|
||||
|
||||
ldal spritemask+{]line*SPRITE_PLANE_SPAN},x
|
||||
and blttmp+{]line*4}+32
|
||||
sta blttmp+{]line*4}+32
|
||||
|
||||
ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
and blttmp+{]line*4}+32+2
|
||||
ora blttmp+{]line*4}+2
|
||||
sta blttmp+{]line*4}+2
|
||||
|
||||
ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x
|
||||
and blttmp+{]line*4}+32+2
|
||||
sta blttmp+{]line*4}+32+2
|
||||
]line equ ]line+1
|
||||
--^
|
||||
rts
|
123
src/blitter/Tiles11011.s
Normal file
123
src/blitter/Tiles11011.s
Normal file
@ -0,0 +1,123 @@
|
||||
; _TBDynamicMaskedPrioritySpriteTile
|
||||
;
|
||||
; 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
|
||||
_TBDynamicMaskedPrioritySpriteTile_00
|
||||
sty _Y_REG ; This is restored in the macro
|
||||
|
||||
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
|
||||
|
||||
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 #$3580 ; Pre-calc the AND $80,x opcode + operand
|
||||
xba
|
||||
sta _T_PTR ; This is an op to load the dynamic tile data
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynPrioMaskedSpriteWord {0*SPRITE_PLANE_SPAN};$0003
|
||||
CopyDynPrioMaskedSpriteWord {1*SPRITE_PLANE_SPAN};$1003
|
||||
CopyDynPrioMaskedSpriteWord {2*SPRITE_PLANE_SPAN};$2003
|
||||
CopyDynPrioMaskedSpriteWord {3*SPRITE_PLANE_SPAN};$3003
|
||||
CopyDynPrioMaskedSpriteWord {4*SPRITE_PLANE_SPAN};$4003
|
||||
CopyDynPrioMaskedSpriteWord {5*SPRITE_PLANE_SPAN};$5003
|
||||
CopyDynPrioMaskedSpriteWord {6*SPRITE_PLANE_SPAN};$6003
|
||||
CopyDynPrioMaskedSpriteWord {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
|
||||
lda _T_PTR
|
||||
adc #$0200
|
||||
sta _T_PTR
|
||||
|
||||
ldx _SPR_X_REG
|
||||
|
||||
CopyDynPrioMaskedSpriteWord {0*SPRITE_PLANE_SPAN}+2;$0000
|
||||
CopyDynPrioMaskedSpriteWord {1*SPRITE_PLANE_SPAN}+2;$1000
|
||||
CopyDynPrioMaskedSpriteWord {2*SPRITE_PLANE_SPAN}+2;$2000
|
||||
CopyDynPrioMaskedSpriteWord {3*SPRITE_PLANE_SPAN}+2;$3000
|
||||
CopyDynPrioMaskedSpriteWord {4*SPRITE_PLANE_SPAN}+2;$4000
|
||||
CopyDynPrioMaskedSpriteWord {5*SPRITE_PLANE_SPAN}+2;$5000
|
||||
CopyDynPrioMaskedSpriteWord {6*SPRITE_PLANE_SPAN}+2;$6000
|
||||
CopyDynPrioMaskedSpriteWord {7*SPRITE_PLANE_SPAN}+2;$7000
|
||||
|
||||
rts
|
||||
|
||||
|
||||
; Masked renderer for a masked dynamic tile with sprite data underlaid.
|
||||
;
|
||||
; ]1 : sprite plane offset
|
||||
; ]2 : code field offset
|
||||
CopyDynPrioMaskedSpriteWord MAC
|
||||
|
||||
; Need to fill in the first 14 bytes of the JMP handler with the following code sequence where
|
||||
; the data and mask from from the sprite plane
|
||||
;
|
||||
; lda ($00),y
|
||||
; and #MASK
|
||||
; ora #DATA
|
||||
; and $80,x
|
||||
; ora $00,x
|
||||
; bra *+15
|
||||
|
||||
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
|
||||
sta: $0000,y ; LDA (00),y
|
||||
|
||||
lda #$0029 ; AND #SPRITE_MASK
|
||||
sta: $0002,y
|
||||
|
||||
ldal spritemask+]1,x
|
||||
cmp #$FFFF ; All 1's in the mask is a fully transparent sprite word
|
||||
beq transparent ; so we can use the Tile00011 method
|
||||
sta: $0003,y
|
||||
|
||||
lda #$0009 ; ORA #SPRITE_DATA
|
||||
sta: $0005,y
|
||||
ldal spritedata+]1,x
|
||||
sta: $0006,y
|
||||
|
||||
lda _T_PTR
|
||||
sta: $0008,y ; AND $80,x
|
||||
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
|
||||
sta: $000A,y ; ORA $00,x
|
||||
|
||||
lda #$0980 ; branch to the prologue (BRA *+11)
|
||||
sta: $000C,y
|
||||
bra next
|
||||
|
||||
; This is a transparent word, so just show the dynamic data
|
||||
transparent
|
||||
lda _T_PTR
|
||||
sta: $0002,y ; AND $80,x
|
||||
eor #$8020 ; Switch the opcode to an ORA and remove the high bit of the operand
|
||||
sta: $0004,y ; ORA $00,x
|
||||
|
||||
lda #$0F80 ; branch to the epilogue (BRA *+17)
|
||||
sta: $0006,y
|
||||
next
|
||||
ldy _Y_REG ; restore original y-register value and move on
|
||||
eom
|
@ -308,11 +308,6 @@ function buildTile(options, buff, _mask, width, x, y) {
|
||||
if (mask.some(h => h != 0)) {
|
||||
tile.isSolid = false;
|
||||
}
|
||||
|
||||
if (x === 120 && y === 8) {
|
||||
console.warn(`isSolid: ${tile.isSolid}` );
|
||||
console.warn(data.map(d => d.toString(16)), mask);
|
||||
}
|
||||
}
|
||||
|
||||
for (dy = 0; dy < 8; dy += 1) {
|
||||
|
@ -460,6 +460,7 @@ function convertTileID(tileId, tileset) {
|
||||
}
|
||||
const mask_bit = (!tileset[tileIndex - 1].isSolid || tileIndex === GLOBALS.emptyTile) && ((GLOBALS.tileLayers.length !== 1) || GLOBALS.forceMasked);
|
||||
|
||||
/*
|
||||
if (tileIndex === 48) {
|
||||
console.warn('isSolid: ', tileset[tileIndex - 1].isSolid);
|
||||
console.warn('GLOBALS.emptyTile: ', GLOBALS.emptyTile);
|
||||
@ -467,6 +468,7 @@ function convertTileID(tileId, tileset) {
|
||||
console.warn('GLOBALS.forceMasked: ', GLOBALS.forceMasked);
|
||||
console.warn('mask_bit: ', mask_bit);
|
||||
}
|
||||
*/
|
||||
|
||||
// Build up a partial set of control bits
|
||||
let control_bits = (mask_bit ? GTE_MASK_BIT : 0) + (hflip ? GTE_HFLIP_BIT : 0) + (vflip ? GTE_VFLIP_BIT : 0);
|
||||
@ -477,6 +479,11 @@ function convertTileID(tileId, tileset) {
|
||||
const animation = tileset[tileIndex - 1].animation;
|
||||
tileId = animation.dynTileId;
|
||||
control_bits = GTE_DYN_BIT;
|
||||
|
||||
console.warn('Dyanmic animation tile found!');
|
||||
console.warn('isSolid: ', tileset[tileIndex - 1].isSolid);
|
||||
console.warn('dynTileId: ', animation.dynTileId);
|
||||
console.warn('mask_bit: ', mask_bit);
|
||||
}
|
||||
|
||||
return (tileId & 0x1FFFFFFF) + control_bits;
|
||||
|
Loading…
Reference in New Issue
Block a user