Fixing memory shadow's bank offset

This commit is contained in:
Anonymus Raccoon
2020-04-06 15:49:46 +02:00
parent 9d5cbb4ed2
commit e60c6d7bd7
6 changed files with 98 additions and 5 deletions
+3 -1
View File
@@ -95,7 +95,9 @@ add_executable(unit_tests
sources/Models/Components.hpp sources/Models/Components.hpp
sources/CPU/Instruction.hpp sources/CPU/Instruction.hpp
sources/Exceptions/DebuggableError.hpp sources/Exceptions/DebuggableError.hpp
tests/CPU/Math/testOthersMath.cpp) tests/CPU/Math/testOthersMath.cpp
tests/testRectangleMemory.cpp
)
# include criterion & coverage # include criterion & coverage
target_link_libraries(unit_tests criterion -lgcov) target_link_libraries(unit_tests criterion -lgcov)
+1
View File
@@ -5,6 +5,7 @@
#include <iostream> #include <iostream>
#include "ARectangleMemory.hpp" #include "ARectangleMemory.hpp"
#include "../Exceptions/InvalidAddress.hpp" #include "../Exceptions/InvalidAddress.hpp"
#include "../Utility/Utility.hpp"
namespace ComSquare::Memory namespace ComSquare::Memory
{ {
+1 -1
View File
@@ -12,7 +12,7 @@ namespace ComSquare::Memory
{ {
//! @brief Superset of the AMemory to map non continuous rectangle to the memory. (A rectangle that spam across more than one bank but that does not start at 0000 or end at FFFF). //! @brief Superset of the AMemory to map non continuous rectangle to the memory. (A rectangle that spam across more than one bank but that does not start at 0000 or end at FFFF).
class ARectangleMemory : public AMemory { class ARectangleMemory : public AMemory {
private: protected:
//! @brief The first bank to map to. //! @brief The first bank to map to.
uint8_t _startBank = 0; uint8_t _startBank = 0;
//! @brief The last bank to map to. //! @brief The last bank to map to.
+3 -2
View File
@@ -3,6 +3,7 @@
// //
#include "RectangleShadow.hpp" #include "RectangleShadow.hpp"
#include "../Utility/Utility.hpp"
#include <utility> #include <utility>
#include <iostream> #include <iostream>
@@ -17,13 +18,13 @@ namespace ComSquare::Memory
uint8_t RectangleShadow::read_internal(uint24_t addr) uint8_t RectangleShadow::read_internal(uint24_t addr)
{ {
addr += this->_bankOffset << 16u; addr += this->_bankOffset * (this->_endPage - this->_startPage);
return this->_initial->read_internal(addr); return this->_initial->read_internal(addr);
} }
void RectangleShadow::write_internal(uint24_t addr, uint8_t data) void RectangleShadow::write_internal(uint24_t addr, uint8_t data)
{ {
addr += this->_bankOffset << 16u; addr += this->_bankOffset * (this->_endPage - this->_startPage);
this->_initial->write_internal(addr, data); this->_initial->write_internal(addr, data);
} }
+1 -1
View File
@@ -22,7 +22,7 @@ namespace ComSquare::Memory
explicit RectangleShadow(std::shared_ptr<ARectangleMemory> initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage); explicit RectangleShadow(std::shared_ptr<ARectangleMemory> initial, uint8_t startBank, uint8_t endBank, uint16_t startPage, uint16_t endPage);
RectangleShadow(const RectangleShadow &) = default; RectangleShadow(const RectangleShadow &) = default;
RectangleShadow &operator=(const RectangleShadow &) = default; RectangleShadow &operator=(const RectangleShadow &) = default;
~RectangleShadow() = default; ~RectangleShadow() override = default;
//! @brief Internal component read. Implement this as you would implement a basic AMemory's read. //! @brief Internal component read. Implement this as you would implement a basic AMemory's read.
//! @param addr The local address to read from. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous //! @param addr The local address to read from. 0x0 refer to the first byte of your data and the address is in the component's space. That means that you can consider this address as continuous
+89
View File
@@ -0,0 +1,89 @@
//
// Created by anonymus-raccoon on 4/6/20.
//
#include <criterion/criterion.h>
#include <criterion/redirect.h>
#include "tests.hpp"
#include "../sources/SNES.hpp"
#include "../sources/Renderer/NoRenderer.hpp"
#include "../sources/PPU/PPU.hpp"
#include "../sources/Memory/RectangleShadow.hpp"
#include "../sources/Utility/Utility.hpp"
using namespace ComSquare;
Test(RectangleMemory, HorizontalRamRead)
{
Ram::Ram ram(0xFF, Component::Rom, "Rom");
ram.setMemoryRegion(0x00, 0xFF, 0x0000, 0x0001);
for (int i = 0x00; i < 0xFF; i++)
ram._data[i] = i;
for (uint24_t i = 0x000000; i < 0xFF0000; i += 0x010000)
cr_assert_eq(ram.read(i), i >> 16u, "The ram's read returned 0x%x but the internal ram value was: 0x%x (addr: 0x%06x)", ram.read(i), i >> 16, i);
}
Test(RectangleMemory, HorizontalRamWrite)
{
Ram::Ram ram(0xFF, Component::Rom, "Rom");
ram.setMemoryRegion(0x00, 0xFF, 0x0000, 0x0001);
for (uint24_t i = 0x000000; i < 0xFF0000; i += 0x010000)
ram.write(i, i >> 16u);
for (int i = 0x00; i < 0xFF; i++)
cr_assert_eq(ram._data[i], i, "The ram's write put 0x%x but it should had put: 0x%x (addr: 0x%06x)", ram._data[i], i, i << 16u);
}
Test(RectangleMemory, DualLineRamRead)
{
Ram::Ram ram(0xFF * 2, Component::Rom, "Rom");
ram.setMemoryRegion(0x00, 0xFF, 0x0000, 0x0002);
for (int i = 0x00; i < 0xFF * 2; i++)
ram._data[i] = i;
for (uint24_t i = 0x000000, v = 0; v < 0xFF * 2; i += 0x010000, v += 2) {
cr_assert_eq(ram.read(i), (uint8_t)(v), "The ram's read returned 0x%x but the internal ram value was: 0x%x (addr: 0x%06x)", ram.read(i), (uint8_t)(v), i);
cr_assert_eq(ram.read(i + 1), (uint8_t)(v + 1), "The ram's read returned 0x%x but the internal ram value was: 0x%x (addr: 0x%06x)", ram.read(i + 1), (uint8_t)(v + 1), i + 1);
}
}
Test(RectangleMemory, HorizontalRamShadowRead)
{
std::shared_ptr<Ram::Ram> ram = std::make_shared<Ram::Ram>(0xFF, Component::Rom, "Rom");
ram->setMemoryRegion(0x00, 0xFF, 0x0000, 0x0001);
Memory::RectangleShadow shadow(ram, 0x00, 0xFF, 0x8000, 0x8001);
for (int i = 0x00; i < 0xFF; i++)
ram->_data[i] = i;
for (uint24_t i = 0x008000; i < 0xFF8000; i += 0x010000) {
uint8_t v = shadow.read(i - shadow.getStart());
cr_assert_eq(v, i >> 16u, "The ram's read returned 0x%x but the internal ram value was: 0x%x (addr: 0x%06x)", v, i >> 16, i);
}}
Test(RectangleMemory, HorizontalRamShadowReadWithBankOffset)
{
std::shared_ptr<Ram::Ram> ram = std::make_shared<Ram::Ram>(0xFF, Component::Rom, "Rom");
ram->setMemoryRegion(0x00, 0xFF, 0x0000, 0x0001);
Memory::RectangleShadow shadow(ram, 0x80, 0xFF, 0x8000, 0x8001);
for (int i = 0x00; i < 0xFF; i++)
ram->_data[i] = i;
shadow.setBankOffset(0x80);
for (uint24_t i = 0x808000; i < 0xFF8000; i += 0x010000) {
uint8_t v = shadow.read(i - shadow.getStart());
cr_assert_eq(v, i >> 16u, "The ram's read returned 0x%x but the internal ram value was: 0x%x (addr: 0x%06x)", v, i >> 16, i);
}
}
Test(RectangleMemory, ShadowOffsetCartridge)
{
std::shared_ptr<Ram::Ram> ram = std::make_shared<Ram::Ram>(0x3fff80, Component::Rom, "Rom");
ram->setMemoryRegion(0x80, 0xFF, 0x8000, 0xFFFF);
Memory::RectangleShadow shadow(ram, 0xC0, 0xEF, 0x0000, 0x7FFF);
for (int i = 0x00; i < 0x3fff80; i++)
ram->_data[i] = i;
shadow.setBankOffset(0x40);
for (uint24_t i = 0xC00000; i < 0xEF7FFF; i += 0x1) {
if ((uint16_t)i > 0x7FFFu)
i += 0x010000 - 0x8000;
uint8_t v = shadow.read(i - shadow.getStart());
uint8_t r = ram->read(i + 0x8000 - ram->getStart());
cr_assert_eq(v, r, "The ram's read returned 0x%x but the internal ram value was: 0x%x (addr: 0x%06x)", v, r, i);
}
}