From 4c965e916fd39d8797d8a4b807f1b09fbada7068 Mon Sep 17 00:00:00 2001 From: Anonymus Raccoon Date: Wed, 27 May 2020 15:04:01 +0200 Subject: [PATCH] Mapping the DMA's channels to the bus --- sources/CPU/CPU.cpp | 9 ++++-- sources/CPU/CPU.hpp | 3 ++ sources/CPU/DMA/DMA.cpp | 54 ++++++++++++++++++++++++++++++++++++ sources/CPU/DMA/DMA.hpp | 19 ++++++++++--- sources/Memory/MemoryBus.cpp | 2 +- 5 files changed, 80 insertions(+), 7 deletions(-) diff --git a/sources/CPU/CPU.cpp b/sources/CPU/CPU.cpp index 88ce592..738bd00 100644 --- a/sources/CPU/CPU.cpp +++ b/sources/CPU/CPU.cpp @@ -91,8 +91,10 @@ namespace ComSquare::CPU return this->_internalRegisters.joy4l; case 0x1F: return this->_internalRegisters.joy4h; + case 0x100 ... 0x180: + return this->_dmaChannels[(addr - 0x100) >> 8u].read(addr & 0xF); default: - throw InvalidAddress("CPU Internal Registers read", addr); + throw InvalidAddress("CPU Internal Registers read", addr + this->getStart()); } } @@ -189,8 +191,11 @@ namespace ComSquare::CPU case 0x1F: this->_internalRegisters.joy4h = data; break; + case 0x100 ... 0x180: + this->_dmaChannels[(addr - 0x100) >> 8u].write(addr & 0xF, data); + break; default: - throw InvalidAddress("CPU Internal Registers write", addr); + throw InvalidAddress("CPU Internal Registers write", addr + this->getStart()); } } diff --git a/sources/CPU/CPU.hpp b/sources/CPU/CPU.hpp index 20db347..8143d14 100644 --- a/sources/CPU/CPU.hpp +++ b/sources/CPU/CPU.hpp @@ -11,6 +11,7 @@ #include "../Cartridge/Cartridge.hpp" #include "../Memory/AMemory.hpp" #include "Instruction.hpp" +#include "DMA/DMA.hpp" namespace ComSquare::CPU { @@ -201,6 +202,8 @@ namespace ComSquare::CPU //! @brief The cartridge header (stored for interrupt vectors.. Cartridge::Header &_cartridgeHeader; + std::array _dmaChannels; + //! @brief True if an addressing mode with an iterator (x, y) has crossed the page. (Used because crossing the page boundary take one more cycle to run certain instructions). bool _hasIndexCrossedPageBoundary = false; diff --git a/sources/CPU/DMA/DMA.cpp b/sources/CPU/DMA/DMA.cpp index 9acda15..83bb3ad 100644 --- a/sources/CPU/DMA/DMA.cpp +++ b/sources/CPU/DMA/DMA.cpp @@ -3,3 +3,57 @@ // #include "DMA.hpp" +#include "../../Exceptions/InvalidAddress.hpp" + +namespace ComSquare::CPU +{ + uint8_t DMA::read(uint8_t addr) + { + switch (addr) { + case 0x0: + return this->controlRegister.raw; + case 0x1: + return this->port; + case 0x2: + return this->aAddress.bytes[0]; + case 0x3: + return this->aAddress.bytes[1]; + case 0x4: + return this->aAddress.bytes[2]; + case 0x5: + return this->count.bytes[0]; + case 0x6: + return this->count.bytes[1]; + default: + throw InvalidAddress("DMA read", addr); + } + } + + void DMA::write(uint8_t addr, uint8_t data) + { + switch (addr) { + case 0x0: + this->controlRegister.raw = data; + break; + case 0x1: + this->port = data; + break; + case 0x2: + this->aAddress.bytes[0] = data; + break; + case 0x3: + this->aAddress.bytes[1] = data; + case 0x4: + this->aAddress.bytes[2] = data; + break; + case 0x5: + this->count.bytes[0] = data; + break; + case 0x6: + this->count.bytes[1] = data; + break; + default: + throw InvalidAddress("DMA read", addr); + } + } +} \ No newline at end of file diff --git a/sources/CPU/DMA/DMA.hpp b/sources/CPU/DMA/DMA.hpp index 1a8ce4b..1fa4f0a 100644 --- a/sources/CPU/DMA/DMA.hpp +++ b/sources/CPU/DMA/DMA.hpp @@ -46,13 +46,24 @@ namespace ComSquare::CPU //! @brief If this is 'xx', the register accessed will be $21xx. uint8_t port; //! @brief The absolute long address of the data from the A bus. - uint24_t aAddress; + union { + uint8_t bytes[3]; + uint24_t raw: 24; + } aAddress; //! @brief The number of bytes to be transferred. - uint16_t count; + union { + uint8_t bytes[2]; + uint16_t raw; + } count; + + //! @brief Bus helper to read from this channel. + uint8_t read(uint8_t addr); + //! @brief Bus helper to write to this channel. + void write(uint8_t addr, uint8_t data); DMA() = default; - DMA(DMA &) = default; - DMA &operator=(DMA &) = default; + DMA(const DMA &) = default; + DMA &operator=(const DMA &) = default; ~DMA() = default; }; } diff --git a/sources/Memory/MemoryBus.cpp b/sources/Memory/MemoryBus.cpp index 1b823e3..dca92ed 100644 --- a/sources/Memory/MemoryBus.cpp +++ b/sources/Memory/MemoryBus.cpp @@ -69,7 +69,7 @@ namespace ComSquare::Memory console.apu->setMemoryRegion(0x2140, 0x2143); this->_memoryAccessors.push_back(console.apu); - console.cpu->setMemoryRegion(0x4200, 0x421F); + console.cpu->setMemoryRegion(0x4200, 0x44FF); this->_memoryAccessors.push_back(console.cpu); // TODO implement DMA & HDMA (4220 to 4300)