From a6c3e54f9fab0665dccfb28e17e26541a883e417 Mon Sep 17 00:00:00 2001
From: AnonymusRaccoon
Date: Thu, 13 Feb 2020 11:09:18 +0100
Subject: [PATCH] Fixing a bug with the write in 0x0
---
CMakeLists.txt | 2 +-
sources/CPU/CPU.cpp | 11 +++++++
sources/CPU/CPU.hpp | 2 ++
sources/Exceptions/InvalidAction.hpp | 2 +-
sources/Exceptions/InvalidAddress.hpp | 20 +++++++++++-
sources/Exceptions/InvalidRom.hpp | 2 +-
.../Exceptions/NotImplementedException.hpp | 2 +-
sources/Memory/IRectangleMemory.cpp | 8 ++---
tests/CPU/testAddressingMode.cpp | 4 +++
tests/CPU/testStore.cpp | 20 ++++++++++++
tests/testMemoryBus.cpp | 32 +++++++++++++++++++
11 files changed, 96 insertions(+), 9 deletions(-)
create mode 100644 tests/CPU/testStore.cpp
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();