diff --git a/CMakeLists.txt b/CMakeLists.txt index 9766372..5ab3a26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ add_executable(unit_tests sources/CPU/Instructions/CommonInstructions.hpp sources/Exceptions/InvalidOpcode.hpp sources/CPU/Instructions/Interrupts.cpp - sources/CPU/Instructions/MathematicalOperations.cpp tests/CPU/Math/testADC.cpp) + sources/CPU/Instructions/MathematicalOperations.cpp tests/CPU/Math/testADC.cpp tests/CPU/testStore.cpp) # include criterion & coverage target_link_libraries(unit_tests criterion -lgcov) diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp index aeeefa0..40246b7 100644 --- a/sources/CPU/CPU.cpp +++ b/sources/CPU/CPU.cpp @@ -441,4 +441,15 @@ namespace ComSquare::CPU base += this->_registers.dbr << 16u; return base + this->_registers.y; } + + unsigned CPU::STA(uint24_t addr) + { + if (this->_registers.p.m) + this->_bus->write(addr, this->_registers.al); + else { + this->_bus->write(addr, this->_registers.al); + this->_bus->write(addr + 1, this->_registers.ah); + } + return 0; + } } \ No newline at end of file diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index 960dbae..f74a8bf 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -288,6 +288,8 @@ namespace ComSquare::CPU //! @brief Add with carry - Adds operand to the Accumulator; adds an additional 1 if carry is set. //! @return The number of extra cycles that this operation took. unsigned ADC(uint24_t valueAddr); + //! @brief Store the accumulator to memory. + unsigned STA(uint24_t addr); public: explicit CPU(std::shared_ptr bus, Cartridge::Header &cartridgeHeader); //! @brief This function continue to execute the Cartridge code. diff --git a/sources/Exceptions/InvalidAction.hpp b/sources/Exceptions/InvalidAction.hpp index a7827ea..8b9c06a 100644 --- a/sources/Exceptions/InvalidAction.hpp +++ b/sources/Exceptions/InvalidAction.hpp @@ -11,7 +11,7 @@ namespace ComSquare { //! @brief Exception thrown when someone tries to load an invalid rom. - class InvalidAction : std::exception { + class InvalidAction : public std::exception { private: std::string _msg; public: diff --git a/sources/Exceptions/InvalidAddress.hpp b/sources/Exceptions/InvalidAddress.hpp index beb3d8c..09724ae 100644 --- a/sources/Exceptions/InvalidAddress.hpp +++ b/sources/Exceptions/InvalidAddress.hpp @@ -13,7 +13,7 @@ namespace ComSquare { //! @brief Exception thrown when trying to read/write to an invalid address. - class InvalidAddress : std::exception { + class InvalidAddress : public std::exception { private: std::string _msg; public: @@ -25,6 +25,24 @@ namespace ComSquare } const char *what() const noexcept override { return this->_msg.c_str(); } }; + + //! @brief Exception thrown when trying to read/write to an invalid address in a rectangle memory region. + class InvalidRectangleAddress : public std::exception { + private: + std::string _msg; + public: + InvalidRectangleAddress(std::string where, int32_t addr, int16_t subaddr, int16_t start, int16_t end) + { + std::stringstream stream; + stream << "Could not read/write data at address: 0x" << std::hex << addr << " from " << where; + if (subaddr < start) + stream << " (" << std::hex << subaddr << " < " << start << ")"; + else + stream << " (" << std::hex << subaddr << " > " << end << ")"; + this->_msg = stream.str(); + } + const char *what() const noexcept override { return this->_msg.c_str(); } + }; } #endif //COMSQUARE_INVALIDADDRESS_HPP diff --git a/sources/Exceptions/InvalidRom.hpp b/sources/Exceptions/InvalidRom.hpp index acbf0b3..433c478 100644 --- a/sources/Exceptions/InvalidRom.hpp +++ b/sources/Exceptions/InvalidRom.hpp @@ -11,7 +11,7 @@ namespace ComSquare { //! @brief Exception thrown when someone tries to load an invalid rom. - class InvalidRomException : std::exception { + class InvalidRomException : public std::exception { private: std::string _msg; public: diff --git a/sources/Exceptions/NotImplementedException.hpp b/sources/Exceptions/NotImplementedException.hpp index 762c655..8aba3e6 100644 --- a/sources/Exceptions/NotImplementedException.hpp +++ b/sources/Exceptions/NotImplementedException.hpp @@ -10,7 +10,7 @@ namespace ComSquare { //! @brief When this is thrown, it means that we should work more. - class NotImplementedException : std::exception { + class NotImplementedException : public std::exception { public: explicit NotImplementedException() = default; const char *what() const noexcept override { return "Not implemented yet."; } diff --git a/sources/Memory/IRectangleMemory.cpp b/sources/Memory/IRectangleMemory.cpp index df5e7ef..9340572 100644 --- a/sources/Memory/IRectangleMemory.cpp +++ b/sources/Memory/IRectangleMemory.cpp @@ -31,10 +31,10 @@ namespace ComSquare::Memory unsigned bankCount = bank - this->_startBank; unsigned pageCount = this->_endPage - this->_startPage; - if (bank < this->_startBank || bank >= this->_endBank) - throw InvalidAddress("Rectangle memory write Invalid Bank", addr); - if (page < this->_startPage || page >= this->_endPage) - throw InvalidAddress("Rectangle memory write Invalid Page", addr); + if (bank < this->_startBank || bank > this->_endBank) + throw InvalidRectangleAddress("Rectangle memory write Invalid Bank", addr, bank, this->_startBank, this->_endBank); + if (page < this->_startPage || page > this->_endPage) + throw InvalidRectangleAddress("Rectangle memory write Invalid Page", addr, page, this->_startPage, this->_endPage); page -= this->_startPage; page += pageCount * bankCount; this->write_internal(page, data); diff --git a/tests/CPU/testAddressingMode.cpp b/tests/CPU/testAddressingMode.cpp index e52b695..3d09508 100644 --- a/tests/CPU/testAddressingMode.cpp +++ b/tests/CPU/testAddressingMode.cpp @@ -20,6 +20,8 @@ Test(AddrMode, Immediate) { auto pair = Init(); pair.second.cpu->_registers.pac = 0x000015; + pair.second.cpu->_isEmulationMode = true; + pair.second.cpu->_registers.p.m = false; cr_assert_eq(pair.second.cpu->_getImmediateAddr(), 0x000015, "Got %x, Expected 0x000015"); cr_assert_eq(pair.second.cpu->_registers.pac, 0x000016); } @@ -27,6 +29,7 @@ Test(AddrMode, Immediate) Test(AddrMode, ImmediateMemoryFlag) { auto pair = Init(); + pair.second.cpu->_isEmulationMode = true; pair.second.cpu->_registers.pac = 0x000015; pair.second.cpu->_registers.p.m = true; cr_assert_eq(pair.second.cpu->_getImmediateAddr(), 0x000015, "Got %x, Expected 0x000015"); @@ -37,6 +40,7 @@ Test(AddrMode, ImmediateBankChange) { auto pair = Init(); pair.second.cpu->_registers.pac = 0x00FFFF; + pair.second.cpu->_registers.p.m = false; cr_assert_eq(pair.second.cpu->_getImmediateAddr(), 0x00FFFF); cr_assert_eq(pair.second.cpu->_registers.pac, 0x010000); } diff --git a/tests/CPU/testStore.cpp b/tests/CPU/testStore.cpp new file mode 100644 index 0000000..914ecfc --- /dev/null +++ b/tests/CPU/testStore.cpp @@ -0,0 +1,20 @@ +// +// Created by anonymus-raccoon on 2/12/20. +// + +#include +#include +#include +#include "../tests.hpp" +#include "../../sources/SNES.hpp" +using namespace ComSquare; +// +//Test(STA, 8bits) +//{ +// auto pair = Init(); +// pair.second.cpu->_registers.p.m = false; +// pair.second.cpu->_registers.a = 0x11; +// pair.second.cpu->STA(0x0); +// auto data = pair.second.wram->_data[0]; +// cr_assert_eq(data, 0x11, "The stored value should be 0x11 but it was 0x%x.", data); +//} \ No newline at end of file diff --git a/tests/testMemoryBus.cpp b/tests/testMemoryBus.cpp index ed9488d..b79ca1e 100644 --- a/tests/testMemoryBus.cpp +++ b/tests/testMemoryBus.cpp @@ -261,12 +261,31 @@ Test(BusAccessor, GetRomMirror3) cr_assert_eq(accessor->_initial.get(), pair.second.cartridge.get()); } +Test(BusAccessor, Get0x0) +{ + auto pair = Init(); + std::shared_ptr accessor = nullptr; + + accessor = std::static_pointer_cast(pair.first->getAccessor(0x0)); + cr_assert_eq(accessor->_initial.get(), pair.second.wram.get()); +} + /////////////////////////// // // // MemoryBus::read tests // // // /////////////////////////// +Test(BusRead, Read0x0) +{ + auto pair = Init(); + uint8_t data; + + pair.second.wram->_data[0] = 123; + data = pair.first->read(0x0); + cr_assert_eq(data, 123); +} + Test(BusRead, ReadOutside, .init = cr_redirect_stdout) { auto pair = Init(); @@ -394,6 +413,19 @@ Test(BusRead, ReadWRAMMirror) // // //////////////////////////// +Test(BusWrite, Write0x0) +{ + auto pair = Init(); + + try { + pair.first->write(0x0, 123); + } catch (std::exception &ex) { + std::cout << ex.what() << std::endl; + } + cr_assert_eq(pair.second.wram->_data[0], 123); +} + + Test(BusWrite, WriteAPU) { auto pair = Init();