diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp index d91dc7b..e2e5139 100644 --- a/sources/CPU/CPU.cpp +++ b/sources/CPU/CPU.cpp @@ -199,24 +199,24 @@ namespace ComSquare::CPU uint8_t opcode = this->_bus->read(this->_registers.pc); switch (opcode) { - case 0x0: - return this->BRK(); - case 0x61: - case 0x63: - case 0x65: - case 0x67: - case 0x69: - case 0x6D: - case 0x6F: - case 0x71: - case 0x72: - case 0x73: - case 0x75: - case 0x77: - case 0x79: - case 0x7D: - case 0x7F: - return this->ADC(); + case Instructions::BRK: return this->BRK(); + + case Instructions::ADC_DPXi: return this->ADC(this->_getDirectIndirectIndexedXAddr()); + case Instructions::ADC_SR: return this->ADC(this->_getStackRelativeAddr()); + case Instructions::ADC_DP: return this->ADC(this->_getDirectAddr()); + case Instructions::ADC_DPil: return this->ADC(this->_getDirectIndirectLongAddr()); + case Instructions::ADC_IM: return this->ADC(this->_getImmediateAddr()); + case Instructions::ADC_ABS: return this->ADC(this->_getAbsoluteAddr()); + case Instructions::ADC_ABSl: return this->ADC(this->_getAbsoluteLongAddr()); + case Instructions::ADC_DPYi: return this->ADC(this->_getDirectIndirectIndexedYAddr()); + case Instructions::ADC_DPi: return this->ADC(this->_getDirectIndirectAddr()); + case Instructions::ADC_SRYi: return this->ADC(this->_getStackRelativeIndirectIndexedYAddr()); + case Instructions::ADC_DPX: return this->ADC(this->_getDirectIndexedByXAddr()); + case Instructions::ADC_DPYil:return this->ADC(this->_getDirectIndirectIndexedYLongAddr()); + case Instructions::ADC_ABSY: return this->ADC(this->_getAbsoluteIndexedByYAddr()); + case Instructions::ADC_ABSX: return this->ADC(this->_getAbsoluteIndexedByXAddr()); + case Instructions::ADC_ABSXl:return this->ADC(this->_getAbsoluteIndexedByXLongAddr()); + default: throw InvalidOpcode("CPU", opcode); } @@ -253,7 +253,7 @@ namespace ComSquare::CPU return addr; } - uint24_t CPU::_getDirectIndirectIndexedAddr() + uint24_t CPU::_getDirectIndirectIndexedYAddr() { uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; uint24_t base = this->_bus->read(dp); @@ -262,7 +262,7 @@ namespace ComSquare::CPU return base + this->_registers.y; } - uint24_t CPU::_getDirectIndirectIndexedLongAddr() + uint24_t CPU::_getDirectIndirectIndexedYLongAddr() { uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; uint24_t base = this->_bus->read(dp); @@ -271,7 +271,7 @@ namespace ComSquare::CPU return base; } - uint24_t CPU::_getDirectIndexedIndirectAddr() + uint24_t CPU::_getDirectIndirectIndexedXAddr() { uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; dp += this->_registers.x; @@ -311,7 +311,7 @@ namespace ComSquare::CPU return effective + this->_registers.y; } - uint24_t CPU::_getAbsoluteLongIndexedByXAddr() + uint24_t CPU::_getAbsoluteIndexedByXLongAddr() { uint24_t lng = this->_bus->read(this->_registers.pac++); lng += this->_bus->read(this->_registers.pac++) << 8u; @@ -377,7 +377,7 @@ namespace ComSquare::CPU return this->_bus->read(this->_registers.pac++) + this->_registers.s; } - uint24_t CPU::_getStackRelativeIndirectIndexedAddr() + uint24_t CPU::_getStackRelativeIndirectIndexedYAddr() { uint24_t base = this->_bus->read(this->_registers.pac++) + this->_registers.s; base += this->_registers.dbr << 16u; diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index 8a3c9b8..4835fe7 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -180,6 +180,30 @@ namespace ComSquare::CPU uint8_t joy4h; }; + //! @brief All the instructions opcode of the main CPI. + //! @info The name of the instruction followed by their parameters (after an underscore) if any. + //! @info Addr mode with an i at the end means indirect. + //! @info Addr mode with an l at the end means long. + enum Instructions + { + BRK = 0x00, + ADC_DPXi = 0x61, + ADC_SR = 0x63, + ADC_DP = 0x65, + ADC_DPil = 0x67, + ADC_IM = 0x69, + ADC_ABS = 0x6D, + ADC_ABSl = 0x6F, + ADC_DPYi = 0x71, + ADC_DPi = 0x72, + ADC_SRYi = 0x73, + ADC_DPX = 0x75, + ADC_DPYil = 0x77, + ADC_ABSY = 0x79, + ADC_ABSX = 0x7D, + ADC_ABSXl = 0x7F + }; + //! @brief The main CPU class CPU : public CommonInstructions, public Memory::IMemory { private: @@ -203,11 +227,11 @@ namespace ComSquare::CPU //! @brief The effective address is the expression. (This functions returns the 24bit space address of the value). uint24_t _getAbsoluteLongAddr(); //! @brief The address is DBR:$(read($($Value + D)) + Y). (This functions returns the 24bit space address of the value). - uint24_t _getDirectIndirectIndexedAddr(); + uint24_t _getDirectIndirectIndexedYAddr(); //! @brief This mode is like the previous addressing mode, but the difference is that rather than pulling 2 bytes from the DP address, it pulls 3 bytes to form the effective address. - uint24_t _getDirectIndirectIndexedLongAddr(); + uint24_t _getDirectIndirectIndexedYLongAddr(); //! @brief The direct page address is calculated and added with x. 2 bytes from the dp address combined with DBR will form the effective address. - uint24_t _getDirectIndexedIndirectAddr(); + uint24_t _getDirectIndirectIndexedXAddr(); //! @brief The DP address is added to X to form the effective address. The effective address is always in bank 0. uint24_t _getDirectIndexedByXAddr(); //! @brief The DP address is added to Y to form the effective address. The effective address is always in bank 0. @@ -217,7 +241,7 @@ namespace ComSquare::CPU //! @brief The absolute expression is added with Y and combined with DBR to form the effective address. uint24_t _getAbsoluteIndexedByYAddr(); //! @brief The effective address is formed by adding the with X. - uint24_t _getAbsoluteLongIndexedByXAddr(); + uint24_t _getAbsoluteIndexedByXLongAddr(); //! @brief The <8-bit signed exp> is added to PC (program counter) to form the new location. uint24_t _getProgramCounterRelativeAddr(); //! @brief The <16-bit signed exp> is added to PC (program counter) to form the new location. @@ -233,17 +257,17 @@ namespace ComSquare::CPU //! @brief The stack register is added to the <8-bit exp> to form the effective address. uint24_t _getStackRelativeAddr(); //! @brief The <8-bit exp> is added to S and combined with DBR to form the base address. Y is added to the base address to form the effective address. - uint24_t _getStackRelativeIndirectIndexedAddr(); + uint24_t _getStackRelativeIndirectIndexedYAddr(); //! @brief Execute a single instruction. //! @return The number of CPU cycles that the instruction took. int executeInstruction(); - //! @brief Break instruction (0x00) - Causes a software break. The PC is loaded from a vector table. + //! @brief Break instruction - Causes a software break. The PC is loaded from a vector table. int BRK(); - //! @brief Add with carry (0x61, 0x63, 0x65, 0x67, 0x69, 0x6D, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x77, 0x79, 0x7D, 0x7F) - Adds operand to the Accumulator; adds an additional 1 if carry is set. - int ADC(); + //! @brief Add with carry - Adds operand to the Accumulator; adds an additional 1 if carry is set. + int ADC(uint24_t valueAddr); public: explicit CPU(std::shared_ptr bus, Cartridge::Header &cartridgeHeader); //! @brief This function continue to execute the Cartridge code. diff --git a/sources/CPU/Instructions/MathematicalOperations.cpp b/sources/CPU/Instructions/MathematicalOperations.cpp index fb53ff2..2a70d42 100644 --- a/sources/CPU/Instructions/MathematicalOperations.cpp +++ b/sources/CPU/Instructions/MathematicalOperations.cpp @@ -6,7 +6,7 @@ namespace ComSquare::CPU { - int CPU::ADC() + int CPU::ADC(uint24_t valueAddr) { // this->_registers.a += } diff --git a/tests/CPU/testAddressingMode.cpp b/tests/CPU/testAddressingMode.cpp index b7a5491..a9c6326 100644 --- a/tests/CPU/testAddressingMode.cpp +++ b/tests/CPU/testAddressingMode.cpp @@ -75,7 +75,8 @@ Test(AddrMode, DirectIndirectIndexed) pair.second.cpu->_registers.dbr = 0x80; pair.second.cpu->_registers.y = 0x0001; pair.second.cpu->_registers.d = 0x1000; - cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedAddr(), 0x804031, "Returned address was %x but was expecting 0x804031.", pair.second.cpu->_getDirectIndirectIndexedAddr()); + cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedYAddr(), 0x804031, "Returned address was %x but was expecting 0x804031.", + pair.second.cpu->_getDirectIndirectIndexedYAddr()); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); } @@ -88,7 +89,8 @@ Test(AddrMode, DirectIndirectIndexedLong) pair.second.wram->_data[0x1010] = 0x30; pair.second.wram->_data[0x1011] = 0x40; pair.second.wram->_data[0x1012] = 0x23; - cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedLongAddr(), 0x234030, "Returned address was %x but was expecting 0x234030.", pair.second.cpu->_getDirectIndirectIndexedLongAddr()); + cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedYLongAddr(), 0x234030, "Returned address was %x but was expecting 0x234030.", + pair.second.cpu->_getDirectIndirectIndexedYLongAddr()); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); } @@ -102,7 +104,8 @@ Test(AddrMode, DirectIndexedIndirect) pair.second.wram->_data[0x1013] = 0x40; pair.second.cpu->_registers.dbr = 0x80; pair.second.cpu->_registers.pac = 0x808000; - cr_assert_eq(pair.second.cpu->_getDirectIndexedIndirectAddr(), 0x804030, "Returned address was %x but was expecting 0x804030.", pair.second.cpu->_getDirectIndexedIndirectAddr()); + cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedXAddr(), 0x804030, "Returned address was %x but was expecting 0x804030.", + pair.second.cpu->_getDirectIndirectIndexedXAddr()); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); } @@ -160,7 +163,8 @@ Test(AddrMode, AbsoluteLongIndexByX) pair.second.cartridge->_data[1] = 0xAC; pair.second.cartridge->_data[2] = 0xEF; pair.second.cpu->_registers.x = 0x0005; - cr_assert_eq(pair.second.cpu->_getAbsoluteLongIndexedByXAddr(), 0xEFAC15, "Returned address was %x but was expecting 0xEFAC15.", pair.second.cpu->_getAbsoluteLongIndexedByXAddr()); + cr_assert_eq(pair.second.cpu->_getAbsoluteIndexedByXLongAddr(), 0xEFAC15, "Returned address was %x but was expecting 0xEFAC15.", + pair.second.cpu->_getAbsoluteIndexedByXLongAddr()); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808003); } @@ -278,7 +282,7 @@ Test(AddrMode, StackRelativeIndirectIndexed) pair.second.cpu->_registers.s = 0x1010; pair.second.cpu->_registers.y = 0x5; pair.second.cpu->_registers.dbr = 0x88; - auto addr = pair.second.cpu->_getStackRelativeIndirectIndexedAddr(); + auto addr = pair.second.cpu->_getStackRelativeIndirectIndexedYAddr(); cr_assert_eq(addr, 0x88101B, "Returned address was %x but was expecting 0x88101B.", addr); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); } \ No newline at end of file