Skip to content
Snippets Groups Projects
Verified Commit 999f66d1 authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

fix: support for pending number of bytes in DMA transfer

This is a way of controlling the bytes that have already been written by the DMA controller.
parent 88d80ff2
No related branches found
No related tags found
No related merge requests found
Pipeline #4039 passed
......@@ -13,6 +13,7 @@ pub struct Dma {
source: u16,
destination: u16,
length: u16,
pending: u16,
mode: DmaMode,
active: bool,
}
......@@ -23,6 +24,7 @@ impl Dma {
source: 0x0,
destination: 0x0,
length: 0x0,
pending: 0x0,
mode: DmaMode::General,
active: false,
}
......@@ -32,6 +34,7 @@ impl Dma {
self.source = 0x0;
self.destination = 0x0;
self.length = 0x0;
self.pending = 0x0;
self.mode = DmaMode::General;
self.active = false;
}
......@@ -41,7 +44,7 @@ impl Dma {
pub fn read(&mut self, addr: u16) -> u8 {
match addr {
// 0xFF55 — HDMA5: VRAM DMA length/mode/start (CGB only)
HDMA5_ADDR => ((self.length >> 4) - 1) as u8 | ((self.active as u8) << 7),
HDMA5_ADDR => ((self.pending >> 4) as u8).wrapping_sub(1) | ((!self.active as u8) << 7),
_ => {
warnln!("Reading from unknown DMA location 0x{:04x}", addr);
0xff
......@@ -67,6 +70,7 @@ impl Dma {
1 => DmaMode::HBlank,
_ => DmaMode::General,
};
self.pending = self.length;
self.active = true;
}
_ => warnln!("Writing to unknown DMA location 0x{:04x}", addr),
......@@ -97,6 +101,14 @@ impl Dma {
self.length = value;
}
pub fn pending(&self) -> u16 {
self.pending
}
pub fn set_pending(&mut self, value: u16) {
self.pending = value;
}
pub fn mode(&self) -> DmaMode {
self.mode
}
......@@ -136,6 +148,7 @@ mod tests {
dma.source = 0x1234;
dma.destination = 0x5678;
dma.length = 0x9abc;
dma.pending = 0x9abc;
dma.mode = DmaMode::HBlank;
dma.active = true;
......@@ -144,6 +157,7 @@ mod tests {
assert_eq!(dma.source, 0x0);
assert_eq!(dma.destination, 0x0);
assert_eq!(dma.length, 0x0);
assert_eq!(dma.pending, 0x0);
assert_eq!(dma.mode, DmaMode::General);
assert!(!dma.active);
}
......
......@@ -285,9 +285,10 @@ impl Mmu {
// this avoids issues when writing to DMG unmapped registers
// that would otherwise cause the system to crash
if self.mode == GameBoyMode::Cgb {
let data = self.read_many(self.dma.source(), self.dma.length());
let data = self.read_many(self.dma.source(), self.dma.pending());
self.write_many(self.dma.destination(), &data);
}
self.dma.set_pending(0);
self.dma.set_active(false);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment