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(); }