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)