From 86986426362323e624e5137e4496a5c6b9c32851 Mon Sep 17 00:00:00 2001
From: AnonymusRaccoon
Date: Tue, 28 Jan 2020 13:24:49 +0100
Subject: [PATCH] Adding implementations of read/write for the CPU's internal
registers
---
sources/CPU/CPU.cpp | 164 +++++++++++++++++++++++++-
sources/CPU/CPU.hpp | 6 +-
sources/Cartridge/Cartridge.cpp | 4 +-
sources/Exceptions/InvalidAddress.hpp | 4 +-
4 files changed, 165 insertions(+), 13 deletions(-)
diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp
index 81d88d3..4041c34 100644
--- a/sources/CPU/CPU.cpp
+++ b/sources/CPU/CPU.cpp
@@ -3,25 +3,177 @@
//
#include "CPU.hpp"
+
+#include
#include "../Exceptions/NotImplementedException.hpp"
+#include "../Exceptions/InvalidAddress.hpp"
namespace ComSquare::CPU
{
CPU::CPU(std::shared_ptr bus)
- : _bus(bus)
+ : _bus(std::move(bus))
{ }
+ //! @bref The CPU's internal registers starts at $4200 and finish at $421F.
uint8_t CPU::read(uint24_t addr)
{
- (void)addr;
- throw NotImplementedException();
+ switch (addr) {
+ case 0x0:
+ return this->_internalRegisters.nmitimen;
+ case 0x1:
+ return this->_internalRegisters.wrio;
+ case 0x2:
+ return this->_internalRegisters.wrmpya;
+ case 0x3:
+ return this->_internalRegisters.wrmpyb;
+ case 0x4:
+ return this->_internalRegisters.wrdivl;
+ case 0x5:
+ return this->_internalRegisters.wrdivh;
+ case 0x6:
+ return this->_internalRegisters.wrdivb;
+ case 0x7:
+ return this->_internalRegisters.htimel;
+ case 0x8:
+ return this->_internalRegisters.htimeh;
+ case 0x9:
+ return this->_internalRegisters.vtimel;
+ case 0xA:
+ return this->_internalRegisters.vtimeh;
+ case 0xB:
+ return this->_internalRegisters.mdmaen;
+ case 0xC:
+ return this->_internalRegisters.hdmaen;
+ case 0x10:
+ return this->_internalRegisters.rdnmi;
+ case 0x11:
+ return this->_internalRegisters.timeup;
+ case 0x12:
+ return this->_internalRegisters.hvbjoy;
+ case 0x13:
+ return this->_internalRegisters.rdio;
+ case 0x14:
+ return this->_internalRegisters.rddivl;
+ case 0x15:
+ return this->_internalRegisters.rddivh;
+ case 0x16:
+ return this->_internalRegisters.rdmpyl;
+ case 0x17:
+ return this->_internalRegisters.rdmpyh;
+ case 0x18:
+ return this->_internalRegisters.joy1l;
+ case 0x19:
+ return this->_internalRegisters.joy1h;
+ case 0x1A:
+ return this->_internalRegisters.joy2l;
+ case 0x1B:
+ return this->_internalRegisters.joy2h;
+ case 0x1C:
+ return this->_internalRegisters.joy3l;
+ case 0x1D:
+ return this->_internalRegisters.joy3h;
+ case 0x1E:
+ return this->_internalRegisters.joy4l;
+ case 0x1F:
+ return this->_internalRegisters.joy4h;
+ default:
+ throw InvalidAddress("CPU Internal Registers read", addr);
+ }
}
void CPU::write(uint24_t addr, uint8_t data)
{
- (void)addr;
- (void)data;
- throw NotImplementedException();
+ switch (addr) {
+ case 0x0:
+ this->_internalRegisters.nmitimen = data;
+ break;
+ case 0x1:
+ this->_internalRegisters.wrio = data;
+ break;
+ case 0x2:
+ this->_internalRegisters.wrmpya = data;
+ break;
+ case 0x3:
+ this->_internalRegisters.wrmpyb = data;
+ break;
+ case 0x4:
+ this->_internalRegisters.wrdivl = data;
+ break;
+ case 0x5:
+ this->_internalRegisters.wrdivh = data;
+ break;
+ case 0x6:
+ this->_internalRegisters.wrdivb = data;
+ break;
+ case 0x7:
+ this->_internalRegisters.htimel = data;
+ break;
+ case 0x8:
+ this->_internalRegisters.htimeh = data;
+ break;
+ case 0x9:
+ this->_internalRegisters.vtimel = data;
+ break;
+ case 0xA:
+ this->_internalRegisters.vtimeh = data;
+ break;
+ case 0xB:
+ this->_internalRegisters.mdmaen = data;
+ break;
+ case 0xC:
+ this->_internalRegisters.hdmaen = data;
+ break;
+ case 0x10:
+ this->_internalRegisters.rdnmi = data;
+ break;
+ case 0x11:
+ this->_internalRegisters.timeup = data;
+ break;
+ case 0x12:
+ this->_internalRegisters.hvbjoy = data;
+ break;
+ case 0x13:
+ this->_internalRegisters.rdio = data;
+ break;
+ case 0x14:
+ this->_internalRegisters.rddivl = data;
+ break;
+ case 0x15:
+ this->_internalRegisters.rddivh = data;
+ break;
+ case 0x16:
+ this->_internalRegisters.rdmpyl = data;
+ break;
+ case 0x17:
+ this->_internalRegisters.rdmpyh = data;
+ break;
+ case 0x18:
+ this->_internalRegisters.joy1l = data;
+ break;
+ case 0x19:
+ this->_internalRegisters.joy1h = data;
+ break;
+ case 0x1A:
+ this->_internalRegisters.joy2l = data;
+ break;
+ case 0x1B:
+ this->_internalRegisters.joy2h = data;
+ break;
+ case 0x1C:
+ this->_internalRegisters.joy3l = data;
+ break;
+ case 0x1D:
+ this->_internalRegisters.joy3h = data;
+ break;
+ case 0x1E:
+ this->_internalRegisters.joy4l = data;
+ break;
+ case 0x1F:
+ this->_internalRegisters.joy4h = data;
+ break;
+ default:
+ throw InvalidAddress("CPU Internal Registers write", addr);
+ }
}
int CPU::update()
diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp
index d64008c..51b9b53 100644
--- a/sources/CPU/CPU.hpp
+++ b/sources/CPU/CPU.hpp
@@ -177,11 +177,11 @@ namespace ComSquare::CPU
class CPU : IMemory {
private:
//! @brief All the registers of the CPU
- Registers _registers;
+ Registers _registers{};
//! @brief Is the CPU running in emulation mode (in 8bits)
- bool _isEmulationMode;
+ bool _isEmulationMode{};
//! @brief Internal registers of the CPU (accessible from the bus via addr $4200 to $421F).
- InternalRegisters _internalRegisters;
+ InternalRegisters _internalRegisters{};
//! @brief The memory bus to use for read/write.
std::shared_ptr _bus;
diff --git a/sources/Cartridge/Cartridge.cpp b/sources/Cartridge/Cartridge.cpp
index 96dbe2f..b39f728 100644
--- a/sources/Cartridge/Cartridge.cpp
+++ b/sources/Cartridge/Cartridge.cpp
@@ -40,14 +40,14 @@ namespace ComSquare::Cartridge
uint8_t Cartridge::read(uint24_t addr)
{
if (addr >= this->_size)
- throw InvalidAddress(addr);
+ throw InvalidAddress("Cartridge read", addr);
return this->_data[addr];
}
void Cartridge::write(uint24_t addr, uint8_t data)
{
if (addr >= this->_size)
- throw InvalidAddress(addr);
+ throw InvalidAddress("Cartridge write", addr);
this->_data[addr] = data;
}
}
\ No newline at end of file
diff --git a/sources/Exceptions/InvalidAddress.hpp b/sources/Exceptions/InvalidAddress.hpp
index 95e2b47..beb3d8c 100644
--- a/sources/Exceptions/InvalidAddress.hpp
+++ b/sources/Exceptions/InvalidAddress.hpp
@@ -17,10 +17,10 @@ namespace ComSquare
private:
std::string _msg;
public:
- explicit InvalidAddress(int32_t addr)
+ InvalidAddress(std::string where, int32_t addr)
{
std::stringstream stream;
- stream << "Could not read/write data at address: 0x" << std::hex << addr;
+ stream << "Could not read/write data at address: 0x" << std::hex << addr << " from " << where;
this->_msg = stream.str();
}
const char *what() const noexcept override { return this->_msg.c_str(); }