From fe0483473160f702112323c8c0961691892c4faa Mon Sep 17 00:00:00 2001 From: AnonymusRaccoon Date: Tue, 11 Feb 2020 13:45:55 +0100 Subject: [PATCH] Adding indexed direct and absolute addressing modes --- sources/CPU/CPU.cpp | 37 +++++++++++++++++++++ sources/CPU/CPU.hpp | 8 +++++ tests/CPU/testAddressingMode.cpp | 55 ++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp index 170578b..ddb3ea2 100644 --- a/sources/CPU/CPU.cpp +++ b/sources/CPU/CPU.cpp @@ -334,4 +334,41 @@ namespace ComSquare::CPU int16_t mod = val2 > 0x7F ? (static_cast(val2) * 256 - val1) : (val1 | val2 << 8u); return pc + mod; } + + uint24_t CPU::_getAbsoluteIndirectAddr() + { + uint16_t abs = this->_bus->read(this->_registers.pac++); + abs += this->_bus->read(this->_registers.pac++) << 8u; + uint24_t effective = this->_bus->read(abs); + effective += this->_bus->read(abs + 1) << 8u; + return effective; + } + + uint24_t CPU::_getAbsoluteIndexedIndirectAddr() + { + uint24_t abs = this->_bus->read(this->_registers.pac++); + abs += this->_bus->read(this->_registers.pac++) << 8u; + abs += this->_registers.x; + uint24_t effective = this->_bus->read(abs); + effective += this->_bus->read(abs + 1) << 8u; + return effective; + } + + uint24_t CPU::_getDirectIndirectAddr() + { + uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; + uint24_t effective = this->_bus->read(dp); + effective += this->_bus->read(dp + 1) << 8u; + effective += this->_registers.dbr << 16u; + return effective; + } + + uint24_t CPU::_getDirectIndirectLongAddr() + { + uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; + uint24_t effective = this->_bus->read(dp); + effective += this->_bus->read(++dp) << 8u; + effective += this->_bus->read(++dp) << 16u; + return effective; + } } \ No newline at end of file diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index 9d1e206..d606f8e 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -222,6 +222,14 @@ namespace ComSquare::CPU uint24_t _getProgramCounterRelativeAddr(); //! @brief The <16-bit signed exp> is added to PC (program counter) to form the new location. uint24_t _getProgramCounterRelativeLongAddr(); + //! @brief 2 bytes are pulled from the to form the effective address. + uint24_t _getAbsoluteIndirectAddr(); + //! @brief The is added with X, then 2 bytes are pulled from that address to form the new location. + uint24_t _getAbsoluteIndexedIndirectAddr(); + //! @brief 2 bytes are pulled from the direct page address to form the 16-bit address. It is combined with DBR to form a 24-bit effective address. + uint24_t _getDirectIndirectAddr(); + //! @brief 3 bytes are pulled from the direct page address to form an effective address. + uint24_t _getDirectIndirectLongAddr(); //! @brief Execute a single instruction. diff --git a/tests/CPU/testAddressingMode.cpp b/tests/CPU/testAddressingMode.cpp index e51aa0b..48ebe3b 100644 --- a/tests/CPU/testAddressingMode.cpp +++ b/tests/CPU/testAddressingMode.cpp @@ -202,4 +202,59 @@ Test(AddrMode, ProgramCounterRelativeLongNegative) auto addr = pair.second.cpu->_getProgramCounterRelativeLongAddr(); cr_assert_eq(addr, 0x806B00, "Returned address was %x but was expecting 0x806B00.", addr); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808012); +} + +Test(AddrMode, AbsoluteIndirect) +{ + auto pair = Init(); + pair.second.cpu->_registers.pac = 0x808000; + pair.second.cartridge->_data[0] = 0xAB; + pair.second.cartridge->_data[1] = 0x01; + pair.second.wram->_data[0x01AB] = 0xEF; + pair.second.wram->_data[0x01AC] = 0x01; + auto addr = pair.second.cpu->_getAbsoluteIndirectAddr(); + cr_assert_eq(addr, 0x01EF, "Returned address was %x but was expecting 0x01EF.", addr); + cr_assert_eq(pair.second.cpu->_registers.pac, 0x808002); +} + +Test(AddrMode, AbsoluteIndexedIndirect) +{ + auto pair = Init(); + pair.second.cpu->_registers.pac = 0x808000; + pair.second.cartridge->_data[0] = 0xAB; + pair.second.cartridge->_data[1] = 0x01; + pair.second.cpu->_registers.x = 2; + pair.second.wram->_data[0x01AD] = 0xEF; + pair.second.wram->_data[0x01AE] = 0x01; + auto addr = pair.second.cpu->_getAbsoluteIndexedIndirectAddr(); + cr_assert_eq(addr, 0x01EF, "Returned address was %x but was expecting 0x01EF.", addr); + cr_assert_eq(pair.second.cpu->_registers.pac, 0x808002); +} + +Test(AddrMode, DirectIndirect) +{ + auto pair = Init(); + pair.second.cpu->_registers.pac = 0x808000; + pair.second.cartridge->_data[0] = 0x01; + pair.second.cpu->_registers.d = 0x1010; + pair.second.wram->_data[0x1011] = 0xEF; + pair.second.wram->_data[0x1012] = 0x01; + pair.second.cpu->_registers.dbr = 0x88; + auto addr = pair.second.cpu->_getDirectIndirectAddr(); + cr_assert_eq(addr, 0x8801EF, "Returned address was %x but was expecting 0x8801EF.", addr); + cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); +} + +Test(AddrMode, DirectIndirectLong) +{ + auto pair = Init(); + pair.second.cpu->_registers.pac = 0x808000; + pair.second.cartridge->_data[0] = 0x06; + pair.second.cpu->_registers.d = 0x1010; + pair.second.wram->_data[0x1016] = 0xEF; + pair.second.wram->_data[0x1017] = 0x01; + pair.second.wram->_data[0x1018] = 0x88; + auto addr = pair.second.cpu->_getDirectIndirectLongAddr(); + cr_assert_eq(addr, 0x8801EF, "Returned address was %x but was expecting 0x8801EF.", addr); + cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); } \ No newline at end of file