diff --git a/demos/tool/App.Main.s b/demos/tool/App.Main.s index 124b444..03aa30c 100644 --- a/demos/tool/App.Main.s +++ b/demos/tool/App.Main.s @@ -15,7 +15,7 @@ TSZelda EXT ; tileset buffer -MAX_SPRITES equ 16 +MAX_SPRITES equ 1 ScreenX equ 0 ScreenY equ 2 @@ -24,6 +24,8 @@ Tmp1 equ 6 KeyState equ 8 Selected equ 10 Flips equ 12 +DTile equ 14 +Tmp2 equ 16 ; Typical init phk @@ -95,6 +97,8 @@ HERO_SPRITE equ SPRITE_16X16+1 ; Manually fill in the 41x26 tiles of the TileStore with a test pattern of trees +; lda #TILE_DYN_BIT+TILE_PRIORITY_BIT+0 ; fill the screen the the dynamic tile slot 0 + lda #TILE_DYN_BIT+0 ; fill the screen the the dynamic tile slot 0 jsr _fillTileStore ldx #0 @@ -145,6 +149,14 @@ HERO_SPRITE equ SPRITE_16X16+1 ldy #6 jsr _drawTreeFront +; Set up the dynamic tile + lda #65 + sta DTile + + pei DTile + pea $0000 + _GTECopyTileToDynamic ; Copy DTile into the first dynamic tile slot + ; Initialize the frame counter stz FrameCount @@ -273,9 +285,19 @@ HERO_SPRITE equ SPRITE_16X16+1 brl :next :10 cmp #$0A - bne :next + bne :11 dec ScreenY +:11 cmp #'y' + bne :next + lda DTile + inc + and #$007F + sta DTile + pha + pea $0000 + _GTECopyTileToDynamic + :next ; inc ScreenX @@ -283,7 +305,7 @@ HERO_SPRITE equ SPRITE_16X16+1 pei ScreenY _GTESetBG0Origin -; brl no_animate + brl no_animate stz Tmp0 stz Tmp1 @@ -433,11 +455,11 @@ GTEStartUp brk $02 :ok2 - clc ; Give GTE a page of direct page memory + clc ; Give GTE a page of direct page memory tdc adc #$0100 pha - pea $0000 ; No extra capabilities + pea #ENGINE_MODE_DYN_TILES ; Enable Dynamic Tiles lda MyUserId ; Pass the userId for memory allocation pha _GTEStartUp @@ -448,15 +470,20 @@ GTEStartUp rts _fillTileStore + sta Tmp2 stz Tmp0 :oloop stz Tmp1 :iloop pei Tmp1 pei Tmp0 - pea #129 + pei Tmp2 _GTESetTile + lda Tmp2 + eor #TILE_PRIORITY_BIT + sta Tmp2 + lda Tmp1 inc sta Tmp1 diff --git a/src/Tiles.s b/src/Tiles.s index e27397c..b86d32d 100644 --- a/src/Tiles.s +++ b/src/Tiles.s @@ -150,7 +150,7 @@ InitTiles asl ; of this tile asl sta TileStore+TS_WORD_OFFSET,x ; This is the offset from 0 to 82, used in LDA (dp),y instruction - + tay lda Col2CodeOffset+2,y clc @@ -158,6 +158,11 @@ InitTiles ; adc TileStore+TS_BASE_ADDR,x sta TileStore+TS_CODE_ADDR_LOW,x ; Low word of the tile address in the code field + lda JTableOffset,y + clc + adc :base + sta TileStore+TS_JMP_ADDR,x ; Address of the snippet handler for this tile + dec :col bpl :hop dec :row @@ -269,7 +274,7 @@ _SetTile lda newTileId ; Otherwise chose one of the two dynamic tuples and #TILE_PRIORITY_BIT beq :pickDynProc ; If the Priority bit is not set, pick the first entry - lda #1 ; If the Priority bit is set, pick the other one + lda #1 ; If the Priority bit is set, pick the other one :pickDynProc ldy #DynProcs jsr _SetTileProcs diff --git a/src/Tool.s b/src/Tool.s index 9d4da09..312e354 100644 --- a/src/Tool.s +++ b/src/Tool.s @@ -58,6 +58,8 @@ _CallTable adrl _TSRemoveSprite-1 adrl _TSGetSeconds-1 + + adrl _TSCopyTileToDynamic-1 _CTEnd _GTEAddSprite MAC UserTool $1000+GTEToolNum @@ -351,6 +353,24 @@ _TSGetSeconds _TSExit #0;#0 +_TSCopyTileToDynamic +:dynId equ FirstParam+0 +:tileId equ FirstParam+2 + _TSEntry + + lda EngineMode + bit #ENGINE_MODE_DYN_TILES + beq :notEnabled + + lda :tileId,s + tax + lda :dynId,s + tay + jsr CopyTileToDyn + +:notEnabled + _TSExit #0;#4 + ; Insert the GTE code put Math.s diff --git a/src/blitter/Tiles.s b/src/blitter/Tiles.s index 5a55228..8a7adf4 100644 --- a/src/blitter/Tiles.s +++ b/src/blitter/Tiles.s @@ -351,123 +351,6 @@ ClearTile rep #$20 rts -; Helper functions to copy tile data to the appropriate location in Bank 0 -; X = tile ID -; Y = dynamic tile ID -CopyTileToDyn ENT - txa - jsr _GetTileAddr - tax - - tya - 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 - tay - jsr CopyTileDToDyn ; Copy the tile data - jsr CopyTileMToDyn ; Copy the tile mask - rtl - -; X = address of tile -; Y = tile address in bank 0 -CopyTileDToDyn - phb - 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 - - plb - rts - -; Helper function to copy tile mask to the appropriate location in Bank 0 -; -; X = address of tile -; Y = tile address in bank 0 -; -; Argument are the same as CopyTileDToDyn, the code takes care of adjust offsets. -; This make is possible to call the two functions back-to-back -; -; ldx tileAddr -; ldy dynTileAddr -; jsr CopyTileDToDyn -; jsr CopyTileMToDyn -CopyTileMToDyn - phb - 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 - - plb - rts - ; CopyBG0Tile ; ; A low-level function that copies 8x8 tiles directly into the code field space. diff --git a/src/render/Dynamic.s b/src/render/Dynamic.s index 6cebb99..1249d33 100644 --- a/src/render/Dynamic.s +++ b/src/render/Dynamic.s @@ -69,8 +69,8 @@ DynamicOver sec lda _JTBL_CACHE - sbc #32 ; All the snippets are 32 bytes wide and, since we're - sta _JTBL_CACHE ; within one tile, the second column is consecutive + sbc #SNIPPET_SIZE ; Advance to the next snippet (Reverse indexing) + sta _JTBL_CACHE clc lda _OP_CACHE @@ -95,7 +95,7 @@ DynamicUnder lda TileStore+TS_TILE_ID,x ; Get the original tile descriptor and #$007F ; clamp to < (32 * 4) - ora #$B500 + 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 @@ -115,8 +115,8 @@ DynamicUnder sec lda _JTBL_CACHE - sbc #32 ; All the snippets are 32 bytes wide and, since we're - sta _JTBL_CACHE ; within one tile, the second column is consecutive + sbc #SNIPPET_SIZE + sta _JTBL_CACHE clc lda _OP_CACHE @@ -181,7 +181,7 @@ mixed cmp #$FFFF ; All 1's in the mask is a fully 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 + 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 @@ -228,22 +228,138 @@ CopyDynUnder MAC ; 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 + 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,y - ldal tmp_sprite_data+{]1},x - sta: $0001,y + sta: $0000,x + lda tmp_sprite_data+{]1} + sta: $0001,x lda _OP_CACHE - sta: $0003,y ; AND $80,x + sta: $0003,x ; 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 + sta: $0005,x ; ORA $00,x lda #$0E80 ; branch to the prologue (BRA *+16) - sta: $0007,y + sta: $0007,x + eom - ldy _Y_REG ; restore original y-register value and move on - eom \ No newline at end of file +; Helper functions to move tile data into the dynamic tile space + +; Helper functions to copy tile data to the appropriate location in Bank 0 +; X = tile ID +; Y = dynamic tile ID +CopyTileToDyn + txa + jsr _GetTileAddr + tax + + tya + 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 + tay + 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 + 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 + + plb + rts + +; Helper function to copy tile mask to the appropriate location in Bank 0 +; +; X = address of tile +; Y = tile address in bank 0 +; +; Argument are the same as CopyTileDToDyn, the code takes care of adjust offsets. +; This make is possible to call the two functions back-to-back +; +; ldx tileAddr +; ldy dynTileAddr +; jsr CopyTileDToDyn +; jsr CopyTileMToDyn +CopyTileMToDyn + phb + 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 + + plb + rts \ No newline at end of file diff --git a/src/render/Render.s b/src/render/Render.s index 1d57fed..82f311a 100644 --- a/src/render/Render.s +++ b/src/render/Render.s @@ -34,77 +34,6 @@ ThreeSprites tyx FourSprites tyx jmp CopyFourSpritesDataAndMaskToDP - -; Simple pair of routines that copies just the tile data to the direct page workspace. Data Bank -; must be set to the TileData bank in entry. -; -; Preserves the X-register -CopyTileDataToDPA -]line equ 0 - lup 8 - lda tiledata+{]line*4},y - sta tmp_tile_data+{]line*4} - - lda tiledata+{]line*4}+2,y - sta tmp_tile_data+{]line*4}+2 -]line equ ]line+1 - --^ - rts - - -; Given a populate tmp_sprite_data buffer to use as a base, merge it with a tile and write to the -; code field -MergeSpriteWithTileFast - ldx TileStore+TS_TILE_ADDR,y - lda TileStore+TS_CODE_ADDR_HIGH,y ; load the bank of the target code field line - pha ; and put on the stack for later. Has TileStore bank in high byte. - lda TileStore+TS_CODE_ADDR_LOW,y ; load the address of the code field - tay - plb - -]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*$1000},y - - lda tmp_sprite_data+{]line*4}+2 - andl tiledata+{]line*4}+32+2,x - oral tiledata+{]line*4}+2,x - sta: $0001+{]line*$1000},y -]line equ ]line+1 - --^ - plb - rts - -MergeSpriteWithTileSlow - ldx TileStore+TS_TILE_ADDR,y - lda TileStore+TS_CODE_ADDR_HIGH,y ; load the bank of the target code field line - pha ; and put on the stack for later. Has TileStore bank in high byte. - lda TileStore+TS_CODE_ADDR_LOW,y ; load the address of the code field - tay - plb - -]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*$1000},y - - lda tmp_sprite_data+{]line*4}+2 - andl tiledata+{]line*4}+32+2,x - oral tiledata+{]line*4}+2,x - sta: $0001+{]line*$1000},y -]line equ ]line+1 - --^ - jmp _FillPEAOpcode - - - - - ; Now, implement the generic Two, Three and Four sprite routines for both Over and Under rendering. These ; are fairly involved, so we try to only have a single implementation of them for now without excessve ; specialization. diff --git a/src/render/Sprite1.s b/src/render/Sprite1.s index 1143e9f..4e4528c 100644 --- a/src/render/Sprite1.s +++ b/src/render/Sprite1.s @@ -156,7 +156,8 @@ OneSpriteSlowUnderV ; Dynamic tiles with one sprite. OneSpriteDynamicUnder - ldx sprite_ptr0 + txy + tax ]line equ 0 lup 8 ldal spritedata+{]line*SPRITE_PLANE_SPAN},x @@ -165,10 +166,12 @@ OneSpriteDynamicUnder sta tmp_sprite_data+{]line*4}+2 ]line equ ]line+1 --^ + tyx jmp DynamicUnder OneSpriteDynamicOver - ldx sprite_ptr0 + txy + tax ]line equ 0 lup 8 ldal spritedata+{]line*SPRITE_PLANE_SPAN},x @@ -178,9 +181,10 @@ OneSpriteDynamicOver ldal spritemask+{]line*SPRITE_PLANE_SPAN},x sta tmp_sprite_mask+{]line*4} - ldal spritedata+{]line*SPRITE_PLANE_SPAN}+2,x + ldal spritemask+{]line*SPRITE_PLANE_SPAN}+2,x sta tmp_sprite_mask+{]line*4}+2 ]line equ ]line+1 --^ + tyx jmp DynamicOver