1use crate::device::IoHandler;
2use crate::mmu::{MemRead, MemWrite, Mmu};
3use log::*;
4
5pub struct Dma {
6 on: bool,
7 src: u8,
8}
9
10impl Dma {
11 pub fn new() -> Self {
12 Self { on: false, src: 0 }
13 }
14
15 pub fn step(&mut self, mmu: &mut Mmu) {
16 if self.on {
17 assert!(self.src <= 0x80 || self.src >= 0x9f);
18 debug!("Perform DMA transfer: {:02x}", self.src);
19
20 let src = (self.src as u16) << 8;
21 for i in 0..0xa0 {
22 mmu.set8(0xfe00 + i, mmu.get8(src + i));
23 }
24
25 self.on = false;
26 }
27 }
28}
29
30impl IoHandler for Dma {
31 fn on_write(&mut self, _mmu: &Mmu, addr: u16, value: u8) -> MemWrite {
32 assert_eq!(addr, 0xff46);
33 debug!("Start DMA transfer: {:02x}", self.src);
34 self.on = true;
35 self.src = value;
36 MemWrite::Block
37 }
38
39 fn on_read(&mut self, _mmu: &Mmu, _addr: u16) -> MemRead {
40 MemRead::Replace(0)
41 }
42}