diff --git a/src/app/rom.h b/src/app/rom.h index 597ed24a..f79ecaf0 100644 --- a/src/app/rom.h +++ b/src/app/rom.h @@ -473,6 +473,7 @@ class Rom : public core::ExperimentFlags { auto filename() const { return filename_; } auto is_loaded() const { return is_loaded_; } auto version() const { return version_; } + auto renderer() const { return renderer_; } uint8_t& operator[](int i) { if (i > size_) { diff --git a/src/app/zelda3/dungeon/object_renderer.cc b/src/app/zelda3/dungeon/object_renderer.cc index 35c5c6a3..c22ef468 100644 --- a/src/app/zelda3/dungeon/object_renderer.cc +++ b/src/app/zelda3/dungeon/object_renderer.cc @@ -106,7 +106,6 @@ void DungeonObjectRenderer::RenderObject(const SubtypeInfo& info) { while (true) { uint8_t opcode = cpu.ReadByte(cpu.PB << 16 | cpu.PC); cpu.ExecuteInstruction(opcode); - cpu.HandleInterrupts(); if ((i != 0 && (cpu.ReadWord((0x00 << 16 | cpu.SP() + 2)) == info.routine_ptr) || diff --git a/src/app/zelda3/dungeon/object_renderer.h b/src/app/zelda3/dungeon/object_renderer.h index 7d1aac3e..aa25fa75 100644 --- a/src/app/zelda3/dungeon/object_renderer.h +++ b/src/app/zelda3/dungeon/object_renderer.h @@ -48,7 +48,8 @@ class DungeonObjectRenderer : public SharedRom { std::vector rom_data_; emu::memory::MemoryImpl memory_; emu::ClockImpl clock_; - emu::Cpu cpu{memory_, clock_}; + emu::memory::CpuCallbacks cpu_callbacks_; + emu::Cpu cpu{memory_, clock_, cpu_callbacks_}; emu::video::Ppu ppu{memory_, clock_}; gfx::Bitmap bitmap_; PseudoVram vram_; diff --git a/src/cli/command_handler.h b/src/cli/command_handler.h index 86863ce2..cb1f93a1 100644 --- a/src/cli/command_handler.h +++ b/src/cli/command_handler.h @@ -316,38 +316,6 @@ class Emulator : public CommandHandler { std::string filename = arg_vec[0]; RETURN_IF_ERROR(rom_.LoadFromFile(filename)) - bool step = false; - if (arg_vec[1].empty()) { - snes.SetCpuMode(0); - } else { - snes.SetCpuMode(1); - step = true; - } - - snes.Init(rom_); - - if (!step) { - int i = 0; - while (i < 80000) { - snes.Run(); - i++; - } - } else { - // This loop should take in input from the keyboard, such as pressing - // space to step through the loop and pressing x to end the execution. - bool stepping = true; - std::cout << "Press space to step, x to exit" << std::endl; - while (stepping) { - char input; - std::cin.get(input); - if (input == 'x') { - break; - } else { - snes.StepRun(); - } - } - } - return absl::OkStatus(); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4c9e2914..46c2315f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,6 +31,7 @@ add_executable( ../src/app/emu/video/ppu.cc ../src/app/emu/audio/dsp.cc ../src/app/emu/audio/spc700.cc + ../src/app/emu/memory/memory.cc ../src/app/editor/context/gfx_context.cc ../src/app/gfx/bitmap.cc ../src/app/gfx/snes_tile.cc diff --git a/test/emu/cpu_test.cc b/test/emu/cpu_test.cc index 8a56f462..d85595d6 100644 --- a/test/emu/cpu_test.cc +++ b/test/emu/cpu_test.cc @@ -14,6 +14,7 @@ namespace emu_test { using yaze::app::emu::AsmParser; using yaze::app::emu::Cpu; +using yaze::app::emu::memory::CpuCallbacks; using yaze::app::emu::memory::MockClock; using yaze::app::emu::memory::MockMemory; @@ -31,7 +32,8 @@ class CpuTest : public ::testing::Test { AsmParser asm_parser; MockMemory mock_memory; MockClock mock_clock; - Cpu cpu{mock_memory, mock_clock}; + CpuCallbacks cpu_callbacks; + Cpu cpu{mock_memory, mock_clock, cpu_callbacks}; }; using ::testing::_; @@ -57,6 +59,18 @@ TEST_F(CpuTest, AsmParserTokenizerOk) { EXPECT_THAT(tokens, ::testing::ContainerEq(expected_tokens)); } +TEST_F(CpuTest, AsmParserSingleInstructionOk) { + AsmParser asm_parser; + std::string instruction = "ADC.b #$01"; + std::vector tokens = asm_parser.Tokenize(instruction); + + std::vector expected_tokens = {"ADC", ".b", "#", "$", "01"}; + EXPECT_THAT(tokens, ::testing::ContainerEq(expected_tokens)); + + auto opcode = asm_parser.Parse(instruction); + EXPECT_EQ(opcode[0], 0x69); +} + TEST_F(CpuTest, CheckMemoryContents) { MockMemory memory; std::vector data = {0x00, 0x01, 0x02, 0x03, 0x04}; @@ -500,10 +514,10 @@ TEST_F(CpuTest, AND_DirectPageIndirect) { } TEST_F(CpuTest, AND_StackRelativeIndirectIndexedY) { - cpu.A = 0b11110000; // A register - cpu.Y = 0x02; // Y register - cpu.DB = 0x10; // Setting Data Bank register to 0x20 - cpu.SetSP(0x01FF); // Setting Stack Pointer to 0x01FF + cpu.A = 0b11110000; // A register + cpu.Y = 0x02; // Y register + cpu.DB = 0x10; // Setting Data Bank register to 0x20 + mock_memory.SetSP(0x01FF); // Setting Stack Pointer to 0x01FF std::vector data = {0x33, 0x02}; mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x0201, {0x00, 0x30}); // [0x0201] = 0x3000 @@ -1096,7 +1110,7 @@ TEST_F(CpuTest, CMP_DirectPageIndexedIndirectX) { TEST_F(CpuTest, CMP_StackRelative) { cpu.A = 0x80; - cpu.SetSP(0x01FF); + mock_memory.SetSP(0x01FF); std::vector data = {0xC3, 0x02}; mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x0201, {0x40, 0x9F}); @@ -1238,10 +1252,10 @@ TEST_F(CpuTest, CMP_DirectPageIndirect) { } TEST_F(CpuTest, CMP_StackRelativeIndirectIndexedY) { - cpu.A = 0x03; // A register - cpu.Y = 0x02; // Y register - cpu.DB = 0x10; // Setting Data Bank register to 0x20 - cpu.SetSP(0x01FF); // Setting Stack Pointer to 0x01FF + cpu.A = 0x03; // A register + cpu.Y = 0x02; // Y register + cpu.DB = 0x10; // Setting Data Bank register to 0x20 + mock_memory.SetSP(0x01FF); // Setting Stack Pointer to 0x01FF std::vector data = {0xD3, 0x02}; // ADC sr, Y mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x0201, {0x00, 0x30}); // [0x0201] = 0x3000 @@ -1576,9 +1590,9 @@ TEST_F(CpuTest, EOR_DirectPageIndexedIndirectX) { } TEST_F(CpuTest, EOR_StackRelative) { - cpu.A = 0b10101010; // A register - cpu.status = 0xFF; // 8-bit mode - cpu.SetSP(0x01FF); // Set Stack Pointer to 0x01FF + cpu.A = 0b10101010; // A register + cpu.status = 0xFF; // 8-bit mode + mock_memory.SetSP(0x01FF); // Set Stack Pointer to 0x01FF std::vector data = {0x43, 0x02}; mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x0201, {0b01010101}); // [0x0201] = 0b01010101 @@ -2030,7 +2044,7 @@ TEST_F(CpuTest, LDA_DirectPageIndexedIndirectX) { TEST_F(CpuTest, LDA_StackRelative) { cpu.SetAccumulatorSize(true); // Set A register to 8-bit mode cpu.status = 0xFF; // 8-bit mode - cpu.SetSP(0x01FF); // Set Stack Pointer to 0x01FF + mock_memory.SetSP(0x01FF); // Set Stack Pointer to 0x01FF std::vector data = {0xA3, 0x02}; mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x0201, {0x7F}); @@ -2488,7 +2502,7 @@ TEST_F(CpuTest, ORA_DirectPageIndexedIndirectX) { TEST_F(CpuTest, ORA_StackRelative) { cpu.SetAccumulatorSize(true); // Set A register to 8-bit mode cpu.status = 0xFF; // 8-bit mode - cpu.SetSP(0x01FF); // Set Stack Pointer to 0x01FF + mock_memory.SetSP(0x01FF); // Set Stack Pointer to 0x01FF std::vector data = {0x03, 0x02}; mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x0201, {0x7F}); @@ -3322,7 +3336,7 @@ TEST_F(CpuTest, SBC_StackRelative) { mock_memory.SetMemoryContents(data); cpu.SetAccumulatorSize(true); // Set A register to 8-bit mode cpu.status = 0xFF; // 8-bit mode - cpu.SetSP(0x01FF); // Set Stack Pointer to 0x01FF + mock_memory.SetSP(0x01FF); // Set Stack Pointer to 0x01FF mock_memory.InsertMemory(0x00003E, {0x02}); mock_memory.InsertMemory(0x2002, {0x80}); @@ -3464,7 +3478,7 @@ TEST_F(CpuTest, SBC_StackRelativeIndirectIndexedY) { cpu.Y = 0x02; // Set Y register to 0x02 cpu.A = 0xFF; // Set A register to 0x80 cpu.status = 0xFF; // 8-bit mode - cpu.SetSP(0x01FF); // Set Stack Pointer to 0x01FF + mock_memory.SetSP(0x01FF); // Set Stack Pointer to 0x01FF std::vector data = {0xF3, 0x02}; mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x0201, {0x00, 0x30}); @@ -3633,7 +3647,7 @@ TEST_F(CpuTest, STA_DirectPageIndexedIndirectX) { TEST_F(CpuTest, STA_StackRelative) { cpu.SetAccumulatorSize(true); // Set A register to 8-bit mode cpu.A = 0x42; - cpu.SetSP(0x01FF); // Set Stack Pointer to 0x01FF + mock_memory.SetSP(0x01FF); // Set Stack Pointer to 0x01FF std::vector data = {0x83, 0x3C}; mock_memory.SetMemoryContents(data); @@ -3727,8 +3741,8 @@ TEST_F(CpuTest, STA_DirectPageIndirect) { TEST_F(CpuTest, STA_StackRelativeIndirectIndexedY) { cpu.SetAccumulatorSize(true); // Set A register to 8-bit mode cpu.A = 0x42; - cpu.Y = 0x02; // Set Y register to 0x02 - cpu.SetSP(0x01FF); // Set Stack Pointer to 0x01FF + cpu.Y = 0x02; // Set Y register to 0x02 + mock_memory.SetSP(0x01FF); // Set Stack Pointer to 0x01FF std::vector data = {0x93, 0x3C}; mock_memory.SetMemoryContents(data); mock_memory.InsertMemory(0x00023B, {0x00, 0x10}); @@ -4049,7 +4063,7 @@ TEST_F(CpuTest, TSB_Absolute) { TEST_F(CpuTest, TSC) { cpu.SetAccumulatorSize(true); // Set A register to 8-bit mode - cpu.SetSP(0x42); + mock_memory.SetSP(0x42); std::vector data = {0x3B}; mock_memory.SetMemoryContents(data); @@ -4061,7 +4075,7 @@ TEST_F(CpuTest, TSC) { TEST_F(CpuTest, TSX) { cpu.SetAccumulatorSize(true); // Set A register to 8-bit mode - cpu.SetSP(0x42); + mock_memory.SetSP(0x42); std::vector data = {0xBA}; mock_memory.SetMemoryContents(data); @@ -4090,7 +4104,7 @@ TEST_F(CpuTest, TXS) { mock_memory.SetMemoryContents(data); cpu.ExecuteInstruction(0x9A); // TXS - EXPECT_EQ(cpu.SP(), 0x42); + EXPECT_EQ(mock_memory.SP(), 0x42); } // ============================================================================ diff --git a/test/emu/ppu_test.cc b/test/emu/ppu_test.cc index 8e0a671f..637aebec 100644 --- a/test/emu/ppu_test.cc +++ b/test/emu/ppu_test.cc @@ -110,27 +110,27 @@ class PpuTest : public ::testing::Test { // Test Initialization TEST_F(PpuTest, InitializationSetsCorrectFrameBufferSize) { - // EXPECT_CALL(mock_ppu, Init()).Times(1); - // mock_ppu.Init(); - // EXPECT_EQ(mock_ppu.GetFrameBuffer().size(), 256 * 240); + EXPECT_CALL(mock_ppu, Init()).Times(1); + mock_ppu.Init(); + EXPECT_EQ(mock_ppu.GetFrameBuffer().size(), 256 * 240); } // Test State Reset TEST_F(PpuTest, ResetClearsFrameBuffer) { - // EXPECT_CALL(mock_ppu, Reset()).Times(1); - // mock_ppu.Reset(); - // auto frameBuffer = mock_ppu.GetFrameBuffer(); - // EXPECT_TRUE(std::all_of(frameBuffer.begin(), frameBuffer.end(), - // [](uint8_t val) { return val == 0; })); + EXPECT_CALL(mock_ppu, Reset()).Times(1); + mock_ppu.Reset(); + auto frameBuffer = mock_ppu.GetFrameBuffer(); + EXPECT_TRUE(std::all_of(frameBuffer.begin(), frameBuffer.end(), + [](uint8_t val) { return val == 0; })); } // Test Memory Interaction TEST_F(PpuTest, ReadWriteVRAM) { - // uint16_t address = testVRAMAddress; - // uint8_t value = testVRAMValue; - // EXPECT_CALL(mock_ppu, Write(address, value)).Times(1); - // mock_ppu.Write(address, value); - // EXPECT_EQ(mock_ppu.Read(address), value); + uint16_t address = testVRAMAddress; + uint8_t value = testVRAMValue; + EXPECT_CALL(mock_ppu, Write(address, value)).Times(1); + mock_ppu.Write(address, value); + EXPECT_EQ(mock_ppu.Read(address), value); } // Test Rendering Mechanics diff --git a/test/emu/spc700_test.cc b/test/emu/spc700_test.cc index 03175d1b..7ecb9628 100644 --- a/test/emu/spc700_test.cc +++ b/test/emu/spc700_test.cc @@ -9,6 +9,7 @@ namespace emu_test { using testing::_; using testing::Return; +using yaze::app::emu::audio::ApuCallbacks; using yaze::app::emu::audio::AudioRam; using yaze::app::emu::audio::Spc700; @@ -70,7 +71,8 @@ class Spc700Test : public ::testing::Test { } testing::StrictMock audioRAM; - Spc700 spc700{audioRAM}; + ApuCallbacks callbacks_; + Spc700 spc700{audioRAM, callbacks_}; }; // ========================================================