diff --git a/src/Memory.s b/src/Memory.s index 65d4214..4973f05 100644 --- a/src/Memory.s +++ b/src/Memory.s @@ -212,8 +212,8 @@ lite_base EXT ldy #lite_base :loop2 lda BTableHigh ; This is the same value for the lite blitter - sta BRowTableHigh+2,x - sta BRowTableHigh+{26*2}+2,x + sta BRowTableHigh,x + sta BRowTableHigh+{26*2},x tya sta BRowTableLow,x diff --git a/src/Render.s b/src/Render.s index 6099d61..e011658 100644 --- a/src/Render.s +++ b/src/Render.s @@ -631,12 +631,8 @@ _RenderLite sta RenderFlags jsr _DoTimers ; Run any pending timer tasks -; brk $65 jsr _ApplyBG0YPosLite ; Set stack addresses for the virtual lines to the physical screen -; brk $66 jsr _ApplyBG0XPosPre ; Lock in certain rendering variables (not lite/non-lite specific) -; brk $67 - jsr _UpdateBG0TileMap ; and the tile maps. These subroutines build up a list of tiles jsr _ApplyTiles ; This function actually draws the new tiles into the code field @@ -652,7 +648,7 @@ _RenderLite ; jsr _DrawObjShadow ; Draw the background ; jsr _DrawDirectSprites ; Draw the sprites directly to the Bank $01 graphics buffer (skipping the render-to-tile step) ; -; jsr _ShadowOn ; Turn shadowing back on + jsr _ShadowOn ; Turn shadowing back on ; ; jsr _DrawFinalPass diff --git a/src/Tiles.s b/src/Tiles.s index 125bc82..251588e 100644 --- a/src/Tiles.s +++ b/src/Tiles.s @@ -125,7 +125,8 @@ InitTiles bra :out :fast lda #0 ; Initialize with Tile 0 - ldy #FastProcs +; ldy #FastProcs + ldy #LiteProcs jsr _SetTileProcs bra :out @@ -275,7 +276,8 @@ _SetNormalTileProcs ; the tile priority bit is set, and whether this is the special tile 0 or not. :setTileFast pla ; Throw away tile ID copy - ldy #FastProcs +; ldy #FastProcs + ldy #LiteProcs pla jmp _SetTileProcs @@ -465,6 +467,22 @@ FastCopyTmpDataA plb rts +LiteCopyTmpDataA + pei USER_TILE_CODE_PTR+2 + ldy USER_TILE_CODE_PTR + plb + +]line equ 0 + lup 8 + lda tmp_tile_data+{]line*4} + sta: $0004+{]line*_LINE_SIZE},y + lda tmp_tile_data+{]line*4}+2 + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + plb + rts + ; X = Tile Store offset ; Y = Engine Mode Base Table address ; A = Table proc index @@ -544,6 +562,18 @@ FastUnderZV dw ConstTile0Fast,SpriteUnder0Fast,SpriteUnder0Fast FastUnderNA dw CopyTileAFast,SpriteUnderAFast,OneSpriteFastUnderA FastUnderNV dw CopyTileVFast,SpriteUnderVFast,OneSpriteFastUnderV +; "Lite" procs. For when the engine is in GTE Lite mode. Different +; stride than the "Fast" procs. +LiteProcs +LiteOverZA dw ConstTile0Lite,SpriteOver0Lite,OneSpriteLiteOver0 +LiteOverZV dw ConstTile0Lite,SpriteOver0Lite,OneSpriteLiteOver0 +LiteOverNA dw CopyTileALite,SpriteOverALite,OneSpriteLiteOverA +LiteOverNV dw CopyTileVLite,SpriteOverVLite,OneSpriteLiteOverV +LiteUnderZA dw ConstTile0Lite,SpriteUnder0Lite,SpriteUnder0Lite +LiteUnderZV dw ConstTile0Lite,SpriteUnder0Lite,SpriteUnder0Lite +LiteUnderNA dw CopyTileALite,SpriteUnderALite,OneSpriteLiteUnderA +LiteUnderNV dw CopyTileVLite,SpriteUnderVLite,OneSpriteLiteUnderV + ; "Slow" procs. These are duplicates of the "Fast" functions, but also ; set the PEA opcode in all cases. SlowProcs diff --git a/src/Tool.s b/src/Tool.s index b69c171..ded21ad 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -1120,6 +1120,7 @@ _TSEnableBackground put SpriteRender.s put Render.s put render/Render.s + put render/Lite.s put render/Fast.s put render/Slow.s put render/Dynamic.s diff --git a/src/blitter/BlitterLite.s b/src/blitter/BlitterLite.s index 09ae3df..8d8abeb 100644 --- a/src/blitter/BlitterLite.s +++ b/src/blitter/BlitterLite.s @@ -17,6 +17,8 @@ _BltRangeLite :exit_ptr equ tmp0 :jmp_low_save equ tmp2 + phb + clc dey tya ; Get the address of the line that we want to return from @@ -52,7 +54,11 @@ _BltRangeLite php ; save the current processor flags sep #$20 ; run the lite blitter in 8-bit accumulator mode - brk $99 + + lda :exit_ptr+2 ; set the bank to the code field + pha + plb + sei ; disable interrupts _R0W1 tsx ; save the stack pointer in Y @@ -72,4 +78,6 @@ blt_return_lite ENT ldy #_EXIT_EVEN+1 lda :jmp_low_save sta [:exit_ptr],y + + plb rts diff --git a/src/blitter/HorzLite.s b/src/blitter/HorzLite.s index 179d397..cac6eb8 100644 --- a/src/blitter/HorzLite.s +++ b/src/blitter/HorzLite.s @@ -81,7 +81,7 @@ _RestoreBG0OpcodesAltLite sta :exit_address sec - CopyXToYPrep :do_restore + CopyXToYPrep :do_restore;:draw_count_x6 ldx :low_save_addr ldy :exit_address @@ -300,7 +300,7 @@ _ApplyBG0XPosAltLite ldal BTableLow,x ; Get the address of the code field line sta :base_address ; Will use this address a few times - adc #_ENTRY_JMP ; Add the offsets in order to get absolaute addresses + adc #_ENTRY_JMP ; Add the offsets in order to get absolute addresses sta :entry_jmp_addr adc #{_LOW_SAVE-_ENTRY_JMP} sta :low_save_addr @@ -314,8 +314,8 @@ _ApplyBG0XPosAltLite ; then overwrite it with the branch instruction. sec ; These macros preform subtractions that do not underflow - CopyXToYPrep :do_save_entry_e - LiteSetConstPrep :do_set_bra_e + CopyXToYPrep :do_save_entry_e;:draw_count_x6 + LiteSetConstPrep :do_set_bra_e;:draw_count_x3 stal :do_setopcode_e+1 stal :do_set_rel_e+1 @@ -358,6 +358,7 @@ _ApplyBG0XPosAltLite txa ; StartXMod164 - 1 clc adc ScreenWidth + cmp #164 ; Keep the value in range bcc *+5 sbc #164 @@ -429,9 +430,9 @@ _ApplyBG0XPosAltLite ; Setup the jumps into the unrolled loops sec - CopyXToYPrep :do_save_entry_o + CopyXToYPrep :do_save_entry_o;:draw_count_x6 stal :do_save_high_byte+1 - LiteSetConstPrep :do_set_bra_o + LiteSetConstPrep :do_set_bra_o;:draw_count_x3 stal :do_setopcode_o+1 stal :do_set_rel_o+1 stal :do_odd_code_entry+1 @@ -453,7 +454,7 @@ _ApplyBG0XPosAltLite ldy :low_save_addr :do_save_entry_o jsr $0000 ; Save the low word of the exit into a save location for restore later - ldx :exit_address + ldy :exit_address lda :exit_bra :do_set_bra_o jsr $0000 ; Insert a BRA instruction over the saved word @@ -623,7 +624,7 @@ _ApplyScanlineBG0XPosLite ; X = value CopyXToYPrep mac lda #x2y_bottom - sbc blttmp+10 ; Copy from above, :draw_count_x6 equ blttmp+10 + sbc ]2 ; count_x6 stal ]1+1 ; A jmp/jsr instruction <<< ]line equ 199 @@ -639,7 +640,7 @@ x2y_bottom rts ; Y = code field offset LiteSetConstPrep mac lda #lsc_bottom - sbc blttmp+8 ; Copy from above, :draw_count_x3 equ blttmp+8 + sbc ]2 ; count_x3 stal ]1+1 ; A jmp/jsr instruction <<< diff --git a/src/blitter/TemplateLite.s b/src/blitter/TemplateLite.s index 31e542b..274bd81 100644 --- a/src/blitter/TemplateLite.s +++ b/src/blitter/TemplateLite.s @@ -36,7 +36,7 @@ lite_entry_jmp brl $0000 ; If the screen is odd-align ; relative offset of the instruction field in the register ; and falls through to the next instruction. - lda: $0001,x ; Get the low byte and push onto the stack + lda: *+1,x ; Get the low byte and push onto the stack pha lite_odd_entry brl $0000 ; unconditionally jump into the "next" instruction in the ; code field. This is OK, even if the entry point was the @@ -74,7 +74,7 @@ lite_loop_exit_3 jmp lite_even_exit ; +255 mx %10 lite_odd_exit lda #0 ; get the high byte of the saved PEA operand (odd-case is already in 8-bit mode) pha -lite_even_exit jmp $0000 ; Jump to the next line. +lite_even_exit jmp *+5 ; Jump to the next line. dfb $F4,$00 ; low-word of the saved PEA instruction ; Now repeat the code above 207 more times. Loop 206 times and then manually do the last one @@ -83,7 +83,7 @@ lite_even_exit jmp $0000 ; Jump to the next line. ldx #0000 txs dfb $82,$00,$00 - lda: 1,x + lda: *+1,x pha dfb $82,$00,$00 @@ -198,7 +198,7 @@ lite_even_exit jmp $0000 ; Jump to the next line. mx %10 lda #0 pha - jmp $0000 + jmp *+5 dfb $F4,$00 ]line equ ]line+1 --^ @@ -206,7 +206,7 @@ lite_even_exit jmp $0000 ; Jump to the next line. :entry_207 ldx #0000 txs dfb $82,$00,$00 ; brl $0000 starts at the next instruction - lda: 1,x + lda: *+1,x sep #$20 pha dfb $82,$00,$00 diff --git a/src/render/Fast.s b/src/render/Fast.s index 76bb6a3..3eb11d3 100644 --- a/src/render/Fast.s +++ b/src/render/Fast.s @@ -284,7 +284,6 @@ CopyTileAFast ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated) plb - tax _CopyTileAFast ]line equ 0 diff --git a/src/render/Lite.s b/src/render/Lite.s new file mode 100644 index 0000000..fdd99e2 --- /dev/null +++ b/src/render/Lite.s @@ -0,0 +1,282 @@ +; Collection of render function used when the engine is in "GTE Lite" mode. In this mode +; there are no dynamic tile or two layer tiles enabled, so all of the tiles are comprised +; of PEA opcodes. These functions take advantage of this and the fact that masks are +; not needed to improve rendering speed. +; +; The GTE Lite mode uses a compact code field that fits in a single bank of memory, so +; all of the rendering routines are basically the same as those in Fast.s, but use a +; different stride. + +SpriteUnder0Lite +ConstTile0Lite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + plb + + lda #0 +]line equ 0 + lup 8 + sta: {_LINE_SIZE*]line}+$0001,y + sta: {_LINE_SIZE*]line}+$0004,y +]line equ ]line+1 + --^ + plb + rts + +SpriteOverALite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + lda TileStore+TS_TILE_ADDR,x + tax + plb + +_SpriteOverALite +]line equ 0 + lup 8 + ldal tiledata+{]line*4},x + and tmp_sprite_mask+{]line*4} + ora tmp_sprite_data+{]line*4} + sta: $0004+{]line*_LINE_SIZE},y + + ldal tiledata+{]line*4}+2,x + and tmp_sprite_mask+{]line*4}+2 + ora tmp_sprite_data+{]line*4}+2 + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + + plb + rts + +SpriteOverVLite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + lda TileStore+TS_TILE_ADDR,x + tax + plb + +_SpriteOverVLite +]src equ 7 +]dest equ 0 + lup 8 + ldal tiledata+{]src*4},x + and tmp_sprite_mask+{]dest*4} + ora tmp_sprite_data+{]dest*4} + sta: $0004+{]dest*_LINE_SIZE},y + + ldal tiledata+{]src*4}+2,x + and tmp_sprite_mask+{]dest*4}+2 + ora tmp_sprite_data+{]dest*4}+2 + sta: $0001+{]dest*_LINE_SIZE},y +]src equ ]src-1 +]dest equ ]dest+1 + --^ + plb + rts + +SpriteOver0Lite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + plb + +_SpriteOver0Lite +]line equ 0 + lup 8 + lda tmp_sprite_data+{]line*4} + sta: $0004+{]line*_LINE_SIZE},y + + lda tmp_sprite_data+{]line*4}+2 + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + + plb + rts + +SpriteUnderALite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + lda TileStore+TS_TILE_ADDR,x + tax + plb + +_SpriteUnderALite +]line equ 0 + lup 8 + lda tmp_sprite_data+{]line*4} + andl tiledata+{]line*4}+32,x + oral tiledata+{]line*4},x + sta: $0004+{]line*_LINE_SIZE},y + + lda tmp_sprite_data+{]line*4}+2 + andl tiledata+{]line*4}+32+2,x + oral tiledata+{]line*4}+2,x + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + + plb + rts + +SpriteUnderVLite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + lda TileStore+TS_TILE_ADDR,x + tax + plb + +_SpriteUnderVLite +]src equ 7 +]dest equ 0 + lup 8 + lda tmp_sprite_data+{]dest*4} + andl tiledata+{]src*4}+32,x + oral tiledata+{]src*4},x + sta: $0004+{]dest*_LINE_SIZE},y + + lda tmp_sprite_data+{]dest*4}+2 + andl tiledata+{]src*4}+32+2,x + oral tiledata+{]src*4}+2,x + sta: $0001+{]dest*_LINE_SIZE},y +]src equ ]src-1 +]dest equ ]dest+1 + --^ + + plb + rts + +CopyTileALite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated) + plb + tax +; brk $ac +_CopyTileALite +]line equ 0 + lup 8 + ldal tiledata+{]line*4},x + sta: $0004+{]line*_LINE_SIZE},y + ldal tiledata+{]line*4}+2,x + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + plb + rts + +CopyTileVLite + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + lda TileStore+TS_TILE_ADDR,x ; load the address of this tile's data (pre-calculated) + plb + + tax +_CopyTileVLite +]src equ 7 +]dest equ 0 + lup 8 + ldal tiledata+{]src*4},x + sta: $0004+{]dest*_LINE_SIZE},y + ldal tiledata+{]src*4}+2,x + sta: $0001+{]dest*_LINE_SIZE},y +]src equ ]src-1 +]dest equ ]dest+1 + --^ + plb + rts + +OneSpriteLiteOver0 + ldy TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + phy ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + tax ; VBuff address from SpriteBitsToVBuffAddrs macro + plb ; set to the code field bank + +_OneSpriteLiteOver0 +]line equ 0 + lup 8 + ldal spritedata+{]line*SPRITE_PLANE_SPAN},x + sta: $0004+{]line*_LINE_SIZE},y + ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + + plb ; Restore the TileStore bank + rts + +; Next implementation; drawing a sprite onto a regular tile. The 1-sprite dispatch preserves the +; X-register, so it already points to the TileStore + +OneSpriteLiteOverV + jsr FastCopyTileDataV + bra _OneSpriteLiteOver + +OneSpriteLiteOverA + jsr FastCopyTileDataA + +_OneSpriteLiteOver + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + ldx sprite_ptr0 + plb + +_OneSpriteLiteOverA +_OneSpriteLiteOverV +]line equ 0 + lup 8 + lda tmp_tile_data+{]line*4} + andl spritemask+{]line*SPRITE_PLANE_SPAN},x + oral spritedata+{]line*SPRITE_PLANE_SPAN},x + sta: $0004+{]line*_LINE_SIZE},y + + lda tmp_tile_data+{]line*4}+2 + andl spritemask+{]line*SPRITE_PLANE_SPAN}+2,x + oral spritedata+{]line*SPRITE_PLANE_SPAN}+2,x + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + plb + rts + +OneSpriteLiteUnderA + jsr FastCopyTileDataAndMaskA + bra _OneSpriteLiteUnder + +OneSpriteLiteUnderV + jsr FastCopyTileDataAndMaskV + +_OneSpriteLiteUnder + lda TileStore+TS_CODE_ADDR_HIGH,x ; load the bank of the target code field line + pha ; and put on the stack for later. Has TileStore bank in high byte. + ldy TileStore+TS_CODE_ADDR_LOW,x ; load the address of the code field + ldx sprite_ptr0 + plb + +_OneSpriteLiteUnderA +_OneSpriteLiteUnderV +]line equ 0 + lup 8 + ldal spritedata+{]line*SPRITE_PLANE_SPAN},x + and tmp_tile_mask+{]line*4} + ora tmp_tile_data+{]line*4} + sta: $0004+{]line*_LINE_SIZE},y + + ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x + and tmp_tile_mask+{]line*4}+2 + ora tmp_tile_data+{]line*4}+2 + sta: $0001+{]line*_LINE_SIZE},y +]line equ ]line+1 + --^ + + plb + rts diff --git a/src/render/README.txt b/src/render/README.txt index 0dbffdf..82c9869 100644 --- a/src/render/README.txt +++ b/src/render/README.txt @@ -1,8 +1,8 @@ This folder contains the rendering tuples for the different type of tile rendering modes that are defined by both the engine mode and the specific tile attributes. There are -a *lot* or variants, so they are cataloged here. +a *lot* of variants, so they are cataloged here. -The top-level TileRender function in the main entry point that defined the overal tile render +The top-level TileRender function in the main entry point that defines the overal tile render flow as well as the register parameters and calling conventions for each of the modular components. @@ -50,7 +50,7 @@ There are 5 pluggable functions that make up a rendering mode 4. K_TS_COPY_TILE_DATA & K_TS_APPLY_TILE_DATA - A pair of function that copye tile data (and possible mask information) into a temporary + A pair of function that copy tile data (and possible mask information) into a temporary direct page space and then render that workspace into the code field. These functions are used as building blocks by the generic Over/Under multi-sprite