summaryrefslogtreecommitdiff
path: root/vdp.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2022-10-03 02:59:26 +0300
committerOxore <oxore@protonmail.com>2022-10-03 02:59:26 +0300
commit46696e1d57aa33b3bf1cd54cc78ef58dc14c8079 (patch)
tree5f36e6a9739c002e617a1d8c25f42e912fa4355e /vdp.cpp
parentb5397045db290c234a1e779b64538933f93b37b6 (diff)
Impl DMA VRAM fill
Diffstat (limited to 'vdp.cpp')
-rw-r--r--vdp.cpp81
1 files changed, 59 insertions, 22 deletions
diff --git a/vdp.cpp b/vdp.cpp
index 0395d30..b1f5817 100644
--- a/vdp.cpp
+++ b/vdp.cpp
@@ -94,7 +94,24 @@ void VDP::Write(const uint32_t offset, const enum bitness bitness, const uint32_
bitness * 2,
value);
}
- if (bitness == BITNESS_32) {
+ if (_dma_ready) {
+ _dma_ready = false;
+ if (DEBUG_TRACE_VDP_ACCESS) {
+ printf(": Running DMA VRAM Fill");
+ }
+ const uint16_t destination_address = _address;
+ const uint16_t transfer_size =
+ _reg[static_cast<size_t>(RegID::kDMALengthCounterLow)] |
+ (_reg[static_cast<size_t>(RegID::kDMALengthCounterHigh)] << 8);
+ const uint8_t increment = _reg[static_cast<size_t>(RegID::kAutoIncrement)];
+ runDMAVRAMFill(
+ baseFromAddressMode(_address_mode),
+ destination_address,
+ transfer_size,
+ increment,
+ value);
+ _address += transfer_size * increment / 2;
+ } else if (bitness == BITNESS_32) {
if (offset == 0) {
writeData(_address_mode, _address & 0xfffe, (value >> 16) & 0xffff);
_address += _reg[static_cast<size_t>(RegID::kAutoIncrement)];
@@ -142,6 +159,8 @@ void VDP::Reset()
{
_status = {};
_control_write_second_word = {};
+ _dma_ready = {};
+ _lines_counter = {};
_address_mode = {};
_address = {};
memset(_reg, 0, kRegistersCount);
@@ -233,6 +252,7 @@ void VDP::writeControl(const uint16_t value)
const uint16_t transfer_size =
_reg[static_cast<size_t>(RegID::kDMALengthCounterLow)] |
(_reg[static_cast<size_t>(RegID::kDMALengthCounterHigh)] << 8);
+ const uint8_t increment = _reg[static_cast<size_t>(RegID::kAutoIncrement)];
const uint8_t dma_action =
DMASRCADRHIGH_DMD_GET(_reg[static_cast<size_t>(RegID::kDMASourceAddressHigh)]);
switch (dma_action) {
@@ -240,7 +260,7 @@ void VDP::writeControl(const uint16_t value)
case 1:
{
if (DEBUG_TRACE_VDP_ACCESS) {
- printf(": Running DMA Memory to VRAM\n");
+ printf(": Running DMA Memory to VRAM");
}
const uint32_t source_address =
_reg[static_cast<size_t>(RegID::kDMASourceAddressLow)] |
@@ -250,23 +270,26 @@ void VDP::writeControl(const uint16_t value)
baseFromAddressMode(_address_mode),
source_address,
destination_address,
- transfer_size);
+ transfer_size,
+ increment);
+ _address += transfer_size * increment / 2;
}
break;
case 2:
{
if (DEBUG_TRACE_VDP_ACCESS) {
- printf(": Running DMA VRAM Fill\n");
+ printf(": Ready to run DMA VRAM Fill");
}
- runDMAVRAMFill(baseFromAddressMode(_address_mode));
+ _dma_ready = true;
}
break;
case 3:
{
if (DEBUG_TRACE_VDP_ACCESS) {
- printf(": Running DMA VRAM Copy\n");
+ printf(": Running DMA VRAM Copy");
}
runDMAVRAMCopy(baseFromAddressMode(_address_mode));
+ _address += transfer_size * increment / 2;
}
break;
}
@@ -527,33 +550,47 @@ void VDP::runDMAMemoryToVRAM(
uint8_t* const base,
const uint32_t source_address,
const uint16_t destination_address,
- const uint16_t transfer_size)
+ const uint16_t transfer_size,
+ const uint8_t increment)
{
constexpr size_t kDumpWidth = 16;
- constexpr size_t kVisualColumnWidth = 8;
- for (size_t i = 0; i < transfer_size; i++) {
+ for (size_t i = 0, o = 0; i < transfer_size; i += 2, o += increment) {
const uint32_t src_addr = source_address + i;
- const uint32_t dst_addr = destination_address + i;
- const uint8_t value = m68k_read_memory_8(src_addr);
+ const uint32_t dst_addr = destination_address + o;
+ const uint16_t value = m68k_read_memory_16(src_addr);
if (DEBUG_TRACE_VDP_ACCESS) {
if (i % kDumpWidth == 0) {
- printf("%06x:%06x: ", src_addr, dst_addr);
- }
- printf("%02x ", value);
- if (i % kVisualColumnWidth == kVisualColumnWidth - 1) {
- printf(" ");
- } else if (i % kDumpWidth == kDumpWidth - 1) {
- printf("\n");
+ printf("\n%06x:%06x: ", src_addr, dst_addr);
}
+ printf("%04x ", value);
}
- base[dst_addr] = value;
+ base[dst_addr + 0] = (value >> 8) & 0xff;
+ base[dst_addr + 1] = value & 0xff;
}
}
-void VDP::runDMAVRAMFill(uint8_t* base)
+void VDP::runDMAVRAMFill(
+ uint8_t* const base,
+ const uint16_t destination_address,
+ const uint16_t transfer_size,
+ const uint8_t increment,
+ const uint16_t filler)
{
- (void) base;
- // TODO
+ if (DEBUG_TRACE_VDP_ACCESS) {
+ printf(
+ "\nVDP DMA Fill @%06x..%06x = 0x%04x",
+ destination_address,
+ destination_address + transfer_size,
+ filler);
+ }
+ for (size_t i = 0, o = 0; i < transfer_size; i += 2, o += increment) {
+ // TODO: There must some complex byte order shit be happening, depending
+ // on odd/even destination address
+ const uint16_t dst_addr = destination_address + o;
+ const uint16_t value = filler;
+ base[dst_addr + 0] = (value >> 8) & 0xff;
+ base[dst_addr + 1] = value & 0xff;
+ }
}
void VDP::runDMAVRAMCopy(uint8_t* base)