diff --git a/src/gamemode/branch.asm b/src/gamemode/branch.asm index 333697be..b3111a1c 100644 --- a/src/gamemode/branch.asm +++ b/src/gamemode/branch.asm @@ -1,14 +1,14 @@ +; 2nd and 3rd instances of playAndEndingHighScore_jmp used to be demo and startDemo respectively branchOnGameMode: - lda gameMode - jsr switch_s_plus_2a - .addr gameMode_bootScreen - .addr gameMode_waitScreen - .addr gameMode_gameTypeMenu - .addr gameMode_levelMenu - .addr gameMode_playAndEndingHighScore_jmp - .addr gameMode_playAndEndingHighScore_jmp ; use to be demo - .addr gameMode_playAndEndingHighScore_jmp ; used to be startDemo - .addr gameMode_speedTest + branchTo gameMode, \ + gameMode_bootScreen, \ + gameMode_waitScreen, \ + gameMode_gameTypeMenu, \ + gameMode_levelMenu, \ + gameMode_playAndEndingHighScore_jmp, \ + gameMode_playAndEndingHighScore_jmp, \ + gameMode_playAndEndingHighScore_jmp, \ + gameMode_speedTest .include "bootscreen.asm" .include "waitscreen.asm" diff --git a/src/gamemode/gametypemenu/linecap.asm b/src/gamemode/gametypemenu/linecap.asm index 11982391..e112f078 100644 --- a/src/gamemode/gametypemenu/linecap.asm +++ b/src/gamemode/gametypemenu/linecap.asm @@ -104,11 +104,10 @@ linecapMenuControls: rts linecapMenuControlsLR: - lda linecapCursorIndex - jsr switch_s_plus_2a - .addr linecapMenuControlsWhen - .addr linecapMenuControlsLinesLevel - .addr linecapMenuControlsHow + branchTo linecapCursorIndex, \ + linecapMenuControlsWhen, \ + linecapMenuControlsLinesLevel, \ + linecapMenuControlsHow linecapMenuControlsWhen: lda newlyPressedButtons_player1 and #BUTTON_LEFT|BUTTON_RIGHT diff --git a/src/gamemode/levelmenu.asm b/src/gamemode/levelmenu.asm index 481c53d5..751b4810 100644 --- a/src/gamemode/levelmenu.asm +++ b/src/gamemode/levelmenu.asm @@ -189,13 +189,12 @@ makeNotReady: rts levelControl: - lda levelControlMode - jsr switch_s_plus_2a - .addr levelControlNormal - .addr levelControlCustomLevel - .addr levelControlHearts - .addr levelControlClearHighScores - .addr levelControlClearHighScoresConfirm + branchTo levelControlMode, \ + levelControlNormal, \ + levelControlCustomLevel, \ + levelControlHearts, \ + levelControlClearHighScores, \ + levelControlClearHighScoresConfirm levelControlClearHighScores: lda #$20 diff --git a/src/gamemodestate/branch.asm b/src/gamemodestate/branch.asm index f8453481..8ae60ecd 100644 --- a/src/gamemodestate/branch.asm +++ b/src/gamemodestate/branch.asm @@ -1,17 +1,25 @@ ; the return value of this routine dictates if we should wait for nmi or not right after +; initGameBackground gms: 1 acc: 0 - ne +; initGameState gms: 2 acc: 4/0 - ne +; updateCountersAndNonPlayerState gms: 3 acc: 0/1 - ne +; handleGameOver gms: 4 acc: eq (set to $9) if gameOver, $1 otherwise (ne) +; updatePlayer1 gms: 5 acc: $FF - ne +; next gms: 6 acc: $1 ne +; checkForResetKeyCombo gms: 7 acc: 0 or heldButtons - eq if holding down, left and right +; handlePause gms: 8 acc: 0/3 - ne +; vblankThenRunState2 gms: 2 acc eq (set to $2) branchOnGameModeState: - lda gameModeState - jsr switch_s_plus_2a - .addr gameModeState_initGameBackground ; gms: 1 acc: 0 - ne - .addr gameModeState_initGameState ; gms: 2 acc: 4/0 - ne - .addr gameModeState_updateCountersAndNonPlayerState ; gms: 3 acc: 0/1 - ne - .addr gameModeState_handleGameOver ; gms: 4 acc: eq (set to $9) if gameOver, $1 otherwise (ne) - .addr gameModeState_updatePlayer1 ; gms: 5 acc: $FF - ne - .addr gameModeState_next ; gms: 6 acc: $1 ne - .addr gameModeState_checkForResetKeyCombo ; gms: 7 acc: 0 or heldButtons - eq if holding down, left and right - .addr gameModeState_handlePause ; gms: 8 acc: 0/3 - ne - .addr gameModeState_vblankThenRunState2 ; gms: 2 acc eq (set to $2) + branchTo gameModeState, \ + gameModeState_initGameBackground, \ + gameModeState_initGameState, \ + gameModeState_updateCountersAndNonPlayerState, \ + gameModeState_handleGameOver, \ + gameModeState_updatePlayer1, \ + gameModeState_next, \ + gameModeState_checkForResetKeyCombo, \ + gameModeState_handlePause, \ + gameModeState_vblankThenRunState2 gameModeState_next: ; used to be updatePlayer2 inc gameModeState diff --git a/src/macros.asm b/src/macros.asm new file mode 100644 index 00000000..8ec5742f --- /dev/null +++ b/src/macros.asm @@ -0,0 +1,58 @@ +.macro _makeRtsTable byte, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 + .if .strat (byte, 0) = '>' + .byte >(a0-1) + .elseif .strat (byte, 0) = '<' + .byte <(a0-1) + .endif + .ifnblank a1 ; recurse until end of argument list + _makeRtsTable byte, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 + .endif +.endmacro + +.macro branchTo dest, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 +.scope + ; add additional arguments as needed, max a255 + + .if .blank(a1) + ; single destination. 3 cycles. + .warning "branchTo defined with single destination, converting to jmp" + jmp a0 + + .elseif .blank(a4) + ; 2-4 destinations use branching. 8-19 cycles + ldx dest + beq addr0 + .ifnblank a2 + dex + beq addr1 + .ifnblank a3 + dex + beq addr2 + addr3: + jmp a3 + .endif + addr2: + jmp a2 + .endif + addr1: + jmp a1 + addr0: + jmp a0 + + .else + ; 5+ destinations, use rts branch. 23-26 cycles + ; uses each destination-1 and rts to branch + ldx dest + lda hiBytes,x + pha + lda loBytes,x + pha + rts + + hiBytes: + _makeRtsTable ">", a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 + loBytes: + _makeRtsTable "<", a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 + .endif +.endscope +.endmacro diff --git a/src/main.asm b/src/main.asm index 000f7ae9..3633188f 100644 --- a/src/main.asm +++ b/src/main.asm @@ -5,6 +5,7 @@ ; ; TetrisGYM - A Tetris Practise ROM +.include "macros.asm" .include "charmap.asm" .include "constants.asm" .include "io.asm" @@ -12,6 +13,7 @@ .include "chr.asm" .setcpu "6502" +.linecont .segment "PRG_chunk1": absolute diff --git a/src/modes/garbage.asm b/src/modes/garbage.asm index 9cbaed15..285fe0ad 100644 --- a/src/modes/garbage.asm +++ b/src/modes/garbage.asm @@ -1,11 +1,11 @@ prepareNextGarbage: - lda garbageModifier - jsr switch_s_plus_2a - .addr garbageAlwaysTetrisReady - .addr garbageNormal - .addr garbageSmart - .addr garbageHard - .addr garbageTypeC ; infinite dig + branchTo garbageModifier, \ + garbageAlwaysTetrisReady, \ + garbageNormal, \ + garbageSmart, \ + garbageHard, \ + garbageTypeC + ; garbageTypeC = infinite dig garbageTypeC: jsr findTopBulky diff --git a/src/nmi/render.asm b/src/nmi/render.asm index 3b468942..1858e84d 100644 --- a/src/nmi/render.asm +++ b/src/nmi/render.asm @@ -1,14 +1,13 @@ -render: lda renderMode - jsr switch_s_plus_2a - .addr render_mode_static - .addr render_mode_scroll - .addr render_mode_congratulations_screen - .addr render_mode_play_and_demo - .addr render_mode_pause - .addr render_mode_rocket - .addr render_mode_speed_test - .addr render_mode_level_menu - .addr render_mode_linecap_menu +render: branchTo renderMode, \ + render_mode_static, \ + render_mode_scroll, \ + render_mode_congratulations_screen, \ + render_mode_play_and_demo, \ + render_mode_pause, \ + render_mode_rocket, \ + render_mode_speed_test, \ + render_mode_level_menu, \ + render_mode_linecap_menu .include "render_mode_level_menu.asm" ; no rts / jmp diff --git a/src/playstate/branch.asm b/src/playstate/branch.asm index d5e4b45c..aa5b982d 100644 --- a/src/playstate/branch.asm +++ b/src/playstate/branch.asm @@ -1,18 +1,18 @@ +; prepareNext used to be bTypeGoalCheck branchOnPlayStatePlayer1: - lda playState - jsr switch_s_plus_2a - .addr playState_unassignOrientationId - .addr playState_playerControlsActiveTetrimino - .addr playState_lockTetrimino - .addr playState_checkForCompletedRows - .addr playState_noop - .addr playState_updateLinesAndStatistics - .addr playState_prepareNext ; used to be bTypeGoalCheck - .addr playState_receiveGarbage - .addr playState_spawnNextTetrimino - .addr playState_noop - .addr playState_checkStartGameOver - .addr playState_incrementPlayState + branchTo playState, \ + playState_unassignOrientationId, \ + playState_playerControlsActiveTetrimino, \ + playState_lockTetrimino, \ + playState_checkForCompletedRows, \ + playState_noop, \ + playState_updateLinesAndStatistics, \ + playState_prepareNext , \ + playState_receiveGarbage, \ + playState_spawnNextTetrimino, \ + playState_noop, \ + playState_checkStartGameOver, \ + playState_incrementPlayState playState_unassignOrientationId: lda #$13 diff --git a/src/ram.asm b/src/ram.asm index f021f206..7ba9824b 100644 --- a/src/ram.asm +++ b/src/ram.asm @@ -5,8 +5,6 @@ tmp3: .res 1 tmpX: .res 1 ; $0003 tmpY: .res 1 ; $0004 tmpZ: .res 1 ; $0005 -switchTmp1 := tmpX ; for switch_s_plus_2a -switchTmp2 := tmpY tmpBulkCopyToPpuReturnAddr: .res 2 ; $0006 ; 2 bytes binScore: .res 4 ; $8 ; 4 bytes binary diff --git a/src/util/core.asm b/src/util/core.asm index 9204e1fd..26d921d4 100644 --- a/src/util/core.asm +++ b/src/util/core.asm @@ -285,19 +285,3 @@ memset_page: inx bne @setByte rts - -switch_s_plus_2a: - asl a - tay - iny - pla - sta switchTmp1 - pla - sta switchTmp2 - lda (switchTmp1),y - tax - iny - lda (switchTmp1),y - sta switchTmp2 - stx switchTmp1 - jmp (switchTmp1) diff --git a/tests/Cargo.lock b/tests/Cargo.lock index 9c7dddf8..a4cffd9d 100644 --- a/tests/Cargo.lock +++ b/tests/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "autocfg" @@ -234,7 +234,7 @@ dependencies = [ "gumdrop", "md5", "minifb", - "rusticnes-core", + "rustico-core", ] [[package]] @@ -456,9 +456,9 @@ dependencies = [ ] [[package]] -name = "rusticnes-core" +name = "rustico-core" version = "0.2.0" -source = "git+https://github.com/zeta0134/rusticnes-core.git#c3fce7960c3335eb5707242f5db22fa35a6d682d" +source = "git+https://github.com/zeta0134/rustico.git?rev=d31d380b1e15bf7cc80e8827730e56a6df77ae46#d31d380b1e15bf7cc80e8827730e56a6df77ae46" [[package]] name = "rustix" diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 9326ce1a..9f2f3c32 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] gumdrop = "0.8.1" -rusticnes-core = { git = "https://github.com/zeta0134/rusticnes-core.git", version = "0.2.0" } +rustico-core = { git = "https://github.com/zeta0134/rustico.git", rev = "d31d380b1e15bf7cc80e8827730e56a6df77ae46" } minifb = "0.27" # for patch testing diff --git a/tests/README.md b/tests/README.md index 3f6a2146..571aa09e 100644 --- a/tests/README.md +++ b/tests/README.md @@ -12,4 +12,4 @@ to verify various behaviour in the game, first build the ROM then run; cargo run --release -- --test ``` -uses [rusticnes-core](https://github.com/zeta0134/rusticnes-core) +uses [rustico-core](https://github.com/zeta0134/rustico) diff --git a/tests/src/crunch.rs b/tests/src/crunch.rs index b7765fe6..a4eeac30 100644 --- a/tests/src/crunch.rs +++ b/tests/src/crunch.rs @@ -1,4 +1,4 @@ -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; use crate::{util, labels, playfield}; diff --git a/tests/src/garbage.rs b/tests/src/garbage.rs index 0f322763..6da54e0d 100644 --- a/tests/src/garbage.rs +++ b/tests/src/garbage.rs @@ -1,5 +1,5 @@ use crate::{util, labels, playfield}; -use rusticnes_core::memory::read_byte; +use rustico_core::memory::read_byte; pub fn test_garbage4_crash() { let mut emu = util::emulator(None); diff --git a/tests/src/harddrop.rs b/tests/src/harddrop.rs index 7e3b85bc..f9ba2599 100644 --- a/tests/src/harddrop.rs +++ b/tests/src/harddrop.rs @@ -1,5 +1,5 @@ -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; use crate::{ util, labels, playfield}; @@ -209,9 +209,11 @@ fn test_harddropped_piece(emu: &mut NesState, start: &str, finish: &str, piece: // stage ghost piece let temp_pc = emu.registers.pc; + let temp_tick = emu.cpu.tick; emu.registers.pc = stage_sprite; let stage_cycles = util::cycles_to_return(emu); emu.registers.pc = temp_pc; + emu.cpu.tick = temp_tick; util::run_n_vblanks(emu, 1); diff --git a/tests/src/hz_display.rs b/tests/src/hz_display.rs index 62060904..f1624a0b 100644 --- a/tests/src/hz_display.rs +++ b/tests/src/hz_display.rs @@ -1,5 +1,5 @@ use crate::{labels, util}; -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; pub fn test() { test_standard(); diff --git a/tests/src/main.rs b/tests/src/main.rs index 244f9c48..c47905fd 100644 --- a/tests/src/main.rs +++ b/tests/src/main.rs @@ -160,8 +160,8 @@ fn main() { emu.memory.iram_raw[rng_seed] = (seed >> 8) as u8; emu.memory.iram_raw[rng_seed + 1] = *seed as u8; - rusticnes_core::opcodes::push(&mut emu, (main_loop >> 8) as u8); - rusticnes_core::opcodes::push(&mut emu, main_loop as u8); + rustico_core::opcodes::push(&mut emu, (main_loop >> 8) as u8); + rustico_core::opcodes::push(&mut emu, main_loop as u8); for _ in 0..23 { emu.run_until_vblank(); diff --git a/tests/src/mapper.rs b/tests/src/mapper.rs index b268cd7d..066a1d51 100755 --- a/tests/src/mapper.rs +++ b/tests/src/mapper.rs @@ -4,7 +4,7 @@ use crate::{ playfield, util, }; -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; pub fn get_expected_tilesets() -> (Vec, Vec) { diff --git a/tests/src/playfield.rs b/tests/src/playfield.rs index 1568b18f..09253f2e 100644 --- a/tests/src/playfield.rs +++ b/tests/src/playfield.rs @@ -1,4 +1,4 @@ -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; use crate::labels; pub fn set(emu: &mut NesState, x: u16, y: u16, value: u8) { diff --git a/tests/src/score.rs b/tests/src/score.rs index 6535f76d..96f938d6 100644 --- a/tests/src/score.rs +++ b/tests/src/score.rs @@ -1,4 +1,4 @@ -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; use crate::{labels, score, util}; pub fn set(emu: &mut NesState, score: u32) { diff --git a/tests/src/sps.rs b/tests/src/sps.rs index 8197b061..4fcdca3e 100644 --- a/tests/src/sps.rs +++ b/tests/src/sps.rs @@ -1,5 +1,5 @@ use crate::{block, labels, util}; -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; pub struct SPS { emu: NesState, diff --git a/tests/src/util.rs b/tests/src/util.rs index d230b4d9..a27fe0de 100644 --- a/tests/src/util.rs +++ b/tests/src/util.rs @@ -1,5 +1,5 @@ -pub use rusticnes_core::nes::NesState; -use rusticnes_core::{ cartridge, opcodes, opcode_info }; +pub use rustico_core::nes::NesState; +use rustico_core::{ cartridge, opcodes, opcode_info }; use crate::{input, labels}; pub static ROM: &'static [u8] = include_bytes!("../../tetris.nes"); diff --git a/tests/src/video.rs b/tests/src/video.rs index 884cfc3c..17db4527 100644 --- a/tests/src/video.rs +++ b/tests/src/video.rs @@ -1,4 +1,4 @@ -use rusticnes_core::nes::NesState; +use rustico_core::nes::NesState; use minifb::{Window, WindowOptions, Key, KeyRepeat}; pub const WIDTH: usize = 256;