Skip to main content

rgy/
dma.rs

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}