From 536136d8c922ce992707d17a666c2c8c2762cf3c Mon Sep 17 00:00:00 2001 From: scawful Date: Sat, 19 Aug 2023 20:12:56 -0400 Subject: [PATCH] DirectPage and DirectPageIndirect --- src/app/emu/cpu.cc | 7 +++--- src/app/emu/cpu.h | 24 +++++++++++++------ src/app/emu/mem.h | 23 ------------------ src/app/emu/snes.h | 4 ++-- test/cpu_test.cc | 58 +++++++++++++++++++++------------------------- 5 files changed, 49 insertions(+), 67 deletions(-) diff --git a/src/app/emu/cpu.cc b/src/app/emu/cpu.cc index 74d4cf07..0ebed9fd 100644 --- a/src/app/emu/cpu.cc +++ b/src/app/emu/cpu.cc @@ -54,8 +54,10 @@ int16_t CPU::FetchSignedWord() { } uint8_t CPU::FetchByteDirectPage(uint8_t operand) { + uint16_t distance = D * 0x100; + // Calculate the effective address in the Direct Page - uint16_t effectiveAddress = D + operand; + uint16_t effectiveAddress = operand + distance; // Fetch the byte from memory uint8_t fetchedByte = memory.ReadByte(effectiveAddress); @@ -81,8 +83,7 @@ void CPU::ExecuteInstruction(uint8_t opcode) { ADC(operand); break; case 0x65: // ADC Direct Page - operand = FetchByteDirectPage(PC); - ADC(operand); + ADC(FetchByteDirectPage(PC)); break; case 0x67: // ADC DP Indirect Long operand = memory.ReadByte(DirectPageIndirectLong()); diff --git a/src/app/emu/cpu.h b/src/app/emu/cpu.h index e28e5250..adc396a7 100644 --- a/src/app/emu/cpu.h +++ b/src/app/emu/cpu.h @@ -75,7 +75,7 @@ class CPU : public Memory { // JMP (addr, X) uint16_t AbsoluteIndexedIndirect() { uint16_t address = FetchWord() + X; - return memory.ReadWord(address); + return memory.ReadWord(address & 0xFFFF); // Consider PBR if needed } // Effective Address: @@ -136,7 +136,10 @@ class CPU : public Memory { // High/low: Direct Page Register plus operand byte // // LDA dp - uint16_t DirectPage() { return FetchByte(); } + uint16_t DirectPage() { + uint8_t dp = FetchByte(); + return D + dp; + } // Effective Address: // Bank: Zero @@ -168,7 +171,9 @@ class CPU : public Memory { // LDA (dp, X) uint16_t DirectPageIndexedIndirectX() { uint8_t dp = FetchByte(); - return memory.ReadWord((dp + X) & 0xFF); + uint16_t effective_address = D + dp + X; + uint16_t indirect_address = memory.ReadWord(effective_address & 0xFFFF); + return indirect_address; } // Effective Address: @@ -180,7 +185,9 @@ class CPU : public Memory { // LDA (dp) uint16_t DirectPageIndirect() { uint8_t dp = FetchByte(); - return memory.ReadWord(dp); + // Add the Direct Page register to the fetched operand + uint16_t effective_address = D + dp; + return memory.ReadWord(effective_address); } // Effective Address: @@ -191,7 +198,8 @@ class CPU : public Memory { // LDA [dp] uint16_t DirectPageIndirectLong() { uint8_t dp = FetchByte(); - return memory.ReadWordLong(dp); + uint16_t effective_address = D + dp; + return memory.ReadWordLong(effective_address); } // Effective Address: @@ -204,7 +212,8 @@ class CPU : public Memory { // LDA (dp), Y uint16_t DirectPageIndirectIndexedY() { uint8_t dp = FetchByte(); - return memory.ReadWord(dp) + Y; + uint16_t effective_address = D + dp; + return memory.ReadWord(effective_address) + Y; } // Effective Address: @@ -218,7 +227,8 @@ class CPU : public Memory { // LDA (dp), Y uint16_t DirectPageIndirectLongIndexedY() { uint8_t dp = FetchByte(); - return memory.ReadWordLong(dp) + Y; + uint16_t effective_address = D + dp; + return memory.ReadWordLong(effective_address) + Y; } // 8-bit data: Data Operand Byte diff --git a/src/app/emu/mem.h b/src/app/emu/mem.h index be30d790..0101750f 100644 --- a/src/app/emu/mem.h +++ b/src/app/emu/mem.h @@ -9,20 +9,6 @@ namespace yaze { namespace app { namespace emu { -class DirectPageMemory { - public: - explicit DirectPageMemory(size_t size = 256) : memory_(size, 0) {} - - uint8_t ReadByte(uint8_t address) const { return memory_[address]; } - - void WriteByte(uint8_t address, uint8_t value) { memory_[address] = value; } - - auto size() const { return memory_.size(); } - - private: - std::vector memory_; -}; - // memory.h class Memory { public: @@ -55,16 +41,10 @@ class Memory { class MemoryImpl : public Memory { public: uint8_t ReadByte(uint16_t address) const override { - if (address < dp_memory_.size()) { - return dp_memory_.ReadByte(static_cast(address)); - } uint32_t mapped_address = GetMappedAddress(address); return memory_.at(mapped_address); } uint16_t ReadWord(uint16_t address) const override { - if (address < dp_memory_.size()) { - return dp_memory_.ReadByte(static_cast(address)); - } uint32_t mapped_address = GetMappedAddress(address); return static_cast(memory_.at(mapped_address)) | (static_cast(memory_.at(mapped_address + 1)) << 8); @@ -172,9 +152,6 @@ class MemoryImpl : public Memory { } } - // Direct Page Memory - DirectPageMemory dp_memory_; - // Define memory regions std::vector rom_; std::vector ram_; diff --git a/src/app/emu/snes.h b/src/app/emu/snes.h index f96db879..35a36804 100644 --- a/src/app/emu/snes.h +++ b/src/app/emu/snes.h @@ -13,8 +13,8 @@ namespace emu { class SNES { public: - SNES()=default; - ~SNES()=default; + SNES() = default; + ~SNES() = default; // Initialization void Init(ROM& rom); diff --git a/test/cpu_test.cc b/test/cpu_test.cc index f16296a0..179082ea 100644 --- a/test/cpu_test.cc +++ b/test/cpu_test.cc @@ -110,7 +110,6 @@ class MockMemory : public Memory { }); } - private: std::vector memory_; uint16_t SP_ = 0x01FF; }; @@ -209,58 +208,53 @@ TEST_F(CPUTest, ADC_AbsoluteLong) { EXPECT_EQ(cpu.A, 0x06); } -/** - * Direct Page Unimplemented - * TEST_F(CPUTest, ADC_DirectPage) { - - cpu.A = 0x01; cpu.D = 0x0001; - std::vector data = {0x65, 0x01, 0x05}; + std::vector data = {0x65, 0x01, 0x00}; mock_memory.SetMemoryContents(data); + mock_memory.InsertMemory(0x100, {0x05, 0x05, 0x05}); - EXPECT_CALL(mock_memory, ReadByte(_)).WillOnce(Return(0x01)); + EXPECT_CALL(mock_memory, ReadByte(0x100)).WillOnce(Return(0x05)); cpu.ExecuteInstruction(0x65); // ADC Direct Page EXPECT_EQ(cpu.A, 0x06); } +// ADC Direct Page Indirect TEST_F(CPUTest, ADC_DirectPageIndirect) { - - - cpu.A = 0x01; // A register - cpu.X = 0x02; // X register - cpu.PC = 0; // PC register - cpu.status = 0x00; // 16-bit mode - std::vector data = {0x72, 0x04, 0x00, 0x00, 0x20, 0x05, 0xFF}; + cpu.A = 0x02; + cpu.D = 0x2000; // Setting Direct Page register to 0x2000 + std::vector data = {0x72, 0x10}; // ADC (dp) mock_memory.SetMemoryContents(data); + mock_memory.InsertMemory(0x2010, {0x00, 0x30}); // [0x2010] = 0x3000 + mock_memory.InsertMemory(0x3000, {0x05}); // [0x3000] = 0x05 - // Get the absolute address - EXPECT_CALL(mock_memory, ReadWord(0x0001)).WillOnce(Return(0x0004)); + EXPECT_CALL(mock_memory, ReadByte(0x0000)).WillOnce(Return(0x10)); + EXPECT_CALL(mock_memory, ReadWord(0x2010)).WillOnce(Return(0x3000)); + EXPECT_CALL(mock_memory, ReadByte(0x3000)).WillOnce(Return(0x05)); - cpu.ExecuteInstruction(0x72); // ADC Indirect Indexed with X - EXPECT_EQ(cpu.A, 0x06); + cpu.ExecuteInstruction(0x72); // ADC (dp) + EXPECT_EQ(cpu.A, 0x07); // 0x02 + 0x05 = 0x07 } +// ADC Direct Page Indexed Indirect, X TEST_F(CPUTest, ADC_DirectPageIndexedIndirectX) { - - - cpu.A = 0x01; - cpu.X = 0x02; - cpu.PC = 1; - cpu.status = 0x00; // 16-bit mode - std::vector data = {0x61, 0x01, 0x18, 0x00, 0x05}; + cpu.A = 0x03; + cpu.D = 0x2000; // Setting Direct Page register to 0x2000 + std::vector data = {0x61, 0x10}; // ADC (dp, X) mock_memory.SetMemoryContents(data); + mock_memory.InsertMemory(0x2012, {0x00, 0x30}); // [0x2012] = 0x3000 + mock_memory.InsertMemory(0x3000, {0x06}); // [0x3000] = 0x06 - EXPECT_CALL(mock_memory, ReadByte(0x0001)).WillOnce(Return(0x0001)); + cpu.X = 0x02; // X register + EXPECT_CALL(mock_memory, ReadByte(0x0000)).WillOnce(Return(0x10)); + EXPECT_CALL(mock_memory, ReadWord(0x2012)).WillOnce(Return(0x3000)); + EXPECT_CALL(mock_memory, ReadByte(0x3000)).WillOnce(Return(0x06)); - EXPECT_CALL(mock_memory, ReadWord(0x0003)).WillOnce(Return(0x0005)); - - cpu.ExecuteInstruction(0x61); // ADC Indexed Indirect - EXPECT_EQ(cpu.A, 0x06); + cpu.ExecuteInstruction(0x61); // ADC (dp, X) + EXPECT_EQ(cpu.A, 0x09); // 0x03 + 0x06 = 0x09 } -**/ TEST_F(CPUTest, ADC_CheckCarryFlag) { cpu.A = 0xFF;