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