Mapping the DMA's channels to the bus

This commit is contained in:
Anonymus Raccoon
2020-05-27 15:04:01 +02:00
parent 56d51425f3
commit 4c965e916f
5 changed files with 80 additions and 7 deletions
+7 -2
View File
@@ -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());
}
}
+3
View File
@@ -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<DMA, 8> _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;
+54
View File
@@ -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);
}
}
}
+15 -4
View File
@@ -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;
};
}