// // instructions.rs // // @author Natesh Narain // @date Mar 23 2020 // mod common; use nescore::{Nes, Cartridge}; #[test] fn nestest() { let cart = Cartridge::from_path("tests/roms/nestest/nestest.nes").unwrap(); // Set the CPU entry point to $C000 for nestest "automation" mode let mut nes = Nes::default().with_cart(cart).entry(0xC000).debug_mode(true); // According to nestest logs the test ends at $C66E nes.run_until(0xC66E); // Fetch error codes let official_opcode_result = nes.read_cpu_ram(0x02); let unofficial_opcode_result = nes.read_cpu_ram(0x03); assert_eq!(official_opcode_result, 0, "Official opcodes exited with code ${:02X}", official_opcode_result); assert_eq!(unofficial_opcode_result, 0, "Unofficial opcodes exited with code ${:02X}", unofficial_opcode_result); } #[test] fn nes_instr_implied() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/01-implied.nes"); common::run_test(&mut nes, "Implied instructions exited with"); } #[test] fn nes_instr_immediate() { // Fail on implementation for ARR and AXS instructions. Apparently these are sketchy // https://wiki.nesdev.com/w/index.php/Talk:Programming_with_unofficial_opcodes#ARR_and_AXS_instructions let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/02-immediate.nes"); common::run_test_with_ignore(&mut nes, "Immediate instructions exited with", vec![String::from("arr"), String::from("axs")]); } #[test] fn nes_instr_zeropage() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/03-zero_page.nes"); common::run_test(&mut nes, "Zeropage instructions exited with"); } #[test] fn nes_instr_zp_xy() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/04-zp_xy.nes"); common::run_test(&mut nes, "Zeropage XY instructions exited with"); } #[test] fn nes_instr_absolute() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/05-absolute.nes"); common::run_test(&mut nes, "Absolute instructions exited with"); } #[test] fn nes_instr_abs_xy() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/06-abs_xy.nes"); common::run_test_with_ignore(&mut nes, "Absolute XY instructions exited with", vec![String::from("sxa"), String::from("sya")]); } #[test] fn nes_instr_ind_x() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/07-ind_x.nes"); common::run_test(&mut nes, "Indirect X instructions exited with"); } #[test] fn nes_instr_ind_y() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/08-ind_y.nes"); common::run_test(&mut nes, "Indirect Y instructions exited with"); } #[test] fn nes_instr_branches() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/09-branches.nes"); common::run_test(&mut nes, "Branch instructions exited with"); } #[test] fn nes_instr_stack() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/10-stack.nes"); common::run_test(&mut nes, "Branch instructions exited with"); } #[test] fn nes_instr_special() { let mut nes = common::init_nes("tests/roms/nes-test-roms/nes_instr_test/rom_singles/11-special.nes"); common::run_test(&mut nes, "Special instructions exited with"); }