diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp index 0b503a3..9b91a58 100644 --- a/sources/CPU/CPU.cpp +++ b/sources/CPU/CPU.cpp @@ -265,6 +265,12 @@ namespace ComSquare::CPU case Instructions::LDA_SR: this->LDA(this->_getStackRelativeAddr()); return 4 + !this->_registers.p.m; case Instructions::LDA_SRYi: this->LDA(this->_getStackRelativeIndirectIndexedYAddr()); return 7 + !this->_registers.p.m; + case Instructions::LDX_IM: this->LDX(this->_getImmediateAddr()); return 2 + !this->_registers.p.m; + case Instructions::LDX_ABS: this->LDX(this->_getAbsoluteAddr()); return 4 + !this->_registers.p.m; + case Instructions::LDX_DP: this->LDX(this->_getDirectAddr()); return 3 + !this->_registers.p.m + this->_registers.dl != 0; + case Instructions::LDX_ABSY: this->LDX(this->_getAbsoluteIndexedByYAddr()); return 4 + !this->_registers.p.m + this->_hasIndexCrossedPageBoundary; + case Instructions::LDX_DPY: this->LDX(this->_getDirectIndexedByYAddr()); return 4 + !this->_registers.p.m + this->_registers.dl != 0; + default: throw InvalidOpcode("CPU", opcode); } diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index 63352da..20d9440 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -247,7 +247,13 @@ namespace ComSquare::CPU LDA_DPYi = 0xB1, LDA_DPYil = 0xB7, LDA_SR = 0xA3, - LDA_SRYi = 0xB3 + LDA_SRYi = 0xB3, + + LDX_IM = 0xA2, + LDX_ABS = 0xAE, + LDX_DP = 0xA6, + LDX_ABSY = 0xBE, + LDX_DPY = 0xB6 }; //! @brief The main CPU @@ -342,6 +348,8 @@ namespace ComSquare::CPU void STZ(uint24_t addr); //! @brief Load the accumulator from memory. void LDA(uint24_t addr); + //! @brief Load the X index register from memory. + void LDX(uint24_t addr); public: explicit CPU(std::shared_ptr bus, Cartridge::Header &cartridgeHeader); CPU(const CPU &) = default; diff --git a/sources/CPU/Instructions/MemoryInstructions.cpp b/sources/CPU/Instructions/MemoryInstructions.cpp index ac24496..1b8a9c8 100644 --- a/sources/CPU/Instructions/MemoryInstructions.cpp +++ b/sources/CPU/Instructions/MemoryInstructions.cpp @@ -55,4 +55,17 @@ namespace ComSquare::CPU } this->_registers.p.z = this->_registers.a == 0x0; } + + void CPU::LDX(uint24_t addr) + { + if (this->_registers.p.x_b) { + this->_registers.x = this->_bus->read(addr); + this->_registers.p.n = this->_registers.xl & 0xF0u; + } else { + this->_registers.xl = this->_bus->read(addr); + this->_registers.xh = this->_bus->read(addr + 1); + this->_registers.p.n = this->_registers.x & 0xF000u; + } + this->_registers.p.z = this->_registers.x == 0x0; + } } \ No newline at end of file diff --git a/tests/CPU/testStore.cpp b/tests/CPU/testStore.cpp index f7dbc5f..2c61114 100644 --- a/tests/CPU/testStore.cpp +++ b/tests/CPU/testStore.cpp @@ -90,78 +90,78 @@ Test(STZ, 16bits) cr_assert_eq(data, 0x00, "The stored value should be 0x00 but it was 0x%x.", data); } -Test(LDA, 8bits) +Test(LDX, 8bits) { auto pair = Init(); - pair.second.cpu->_registers.p.m = true; + pair.second.cpu->_registers.p.x_b = true; pair.second.wram->_data[0] = 0x01; - pair.second.cpu->LDA(0x0); - auto data = pair.second.cpu->_registers.a; + pair.second.cpu->LDX(0x0); + auto data = pair.second.cpu->_registers.x; cr_assert_eq(data, 0x01, "The stored value should be 0x01 but it was 0x%x.", data); cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag register should not be set."); cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag register should not be set."); } -Test(LDA, 8bitsNegative) +Test(LDX, 8bitsNegative) { auto pair = Init(); - pair.second.cpu->_registers.p.m = true; + pair.second.cpu->_registers.p.x_b = true; pair.second.wram->_data[0] = 0x11; - pair.second.cpu->LDA(0x0); - auto data = pair.second.cpu->_registers.a; + pair.second.cpu->LDX(0x0); + auto data = pair.second.cpu->_registers.x; cr_assert_eq(data, 0x11, "The stored value should be 0x11 but it was 0x%x.", data); cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag register should not be set."); cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag register should be set."); } -Test(LDA, 8bitsZero) +Test(LDX, 8bitsZero) { auto pair = Init(); - pair.second.cpu->_registers.p.m = true; + pair.second.cpu->_registers.p.x_b = true; pair.second.wram->_data[0] = 0x00; pair.second.wram->_data[1] = 0x11; - pair.second.cpu->LDA(0x0); - auto data = pair.second.cpu->_registers.a; + pair.second.cpu->LDX(0x0); + auto data = pair.second.cpu->_registers.x; cr_assert_eq(data, 0x00, "The stored value should be 0x00 but it was 0x%x.", data); cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag register should be set."); cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag register should not be set."); } -Test(LDA, 16bits) +Test(LDX, 16bits) { auto pair = Init(); - pair.second.cpu->_registers.p.m = false; + pair.second.cpu->_registers.p.x_b = false; pair.second.wram->_data[0] = 0xAB; pair.second.wram->_data[1] = 001; - pair.second.cpu->LDA(0x0); - auto data = pair.second.cpu->_registers.a; + pair.second.cpu->LDX(0x0); + auto data = pair.second.cpu->_registers.x; cr_assert_eq(data, 0x01AB, "The stored value should be 0x01AB but it was 0x%x.", data); cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag register should not be set."); cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag register should not be set."); } -Test(LDA, 16bitsNegative) +Test(LDX, 16bitsNegative) { auto pair = Init(); - pair.second.cpu->_registers.p.m = false; + pair.second.cpu->_registers.p.x_b = false; pair.second.wram->_data[0] = 0xAB; pair.second.wram->_data[1] = 0x11; - pair.second.cpu->LDA(0x0); - auto data = pair.second.cpu->_registers.a; + pair.second.cpu->LDX(0x0); + auto data = pair.second.cpu->_registers.x; cr_assert_eq(data, 0x11AB, "The stored value should be 0x11AB but it was 0x%x.", data); cr_assert_eq(pair.second.cpu->_registers.p.z, false, "The zero flag register should not be set."); cr_assert_eq(pair.second.cpu->_registers.p.n, true, "The negative flag register should be set."); } -Test(LDA, 16bitsZero) +Test(LDX, 16bitsZero) { auto pair = Init(); - pair.second.cpu->_registers.p.m = false; + pair.second.cpu->_registers.p.x_b = false; pair.second.wram->_data[0] = 0x00; pair.second.wram->_data[1] = 0x00; - pair.second.cpu->LDA(0x0); - auto data = pair.second.cpu->_registers.a; + pair.second.cpu->LDX(0x0); + auto data = pair.second.cpu->_registers.x; cr_assert_eq(data, 0x0000, "The stored value should be 0x0000 but it was 0x%x.", data); cr_assert_eq(pair.second.cpu->_registers.p.z, true, "The zero flag register should be set."); cr_assert_eq(pair.second.cpu->_registers.p.n, false, "The negative flag register should not be set."); -} +} \ No newline at end of file