Skip to main content

gcrecomp_runtime/memory/
aram.rs

1// Audio RAM simulation (16MB)
2use anyhow::Result;
3
4pub struct ARam {
5    data: Vec<u8>,
6    size: usize,
7}
8
9impl ARam {
10    pub fn new() -> Self {
11        const ARAM_SIZE: usize = 16 * 1024 * 1024; // 16MB
12        Self {
13            data: vec![0; ARAM_SIZE],
14            size: ARAM_SIZE,
15        }
16    }
17
18    pub fn read_u16(&self, address: u32) -> Result<u16> {
19        let addr = (address & 0x00FFFFFF) as usize; // 24-bit addressing
20        if addr + 2 <= self.size {
21            Ok(u16::from_be_bytes([self.data[addr], self.data[addr + 1]]))
22        } else {
23            anyhow::bail!("ARAM read out of bounds: 0x{:08X}", address);
24        }
25    }
26
27    pub fn write_u16(&mut self, address: u32, value: u16) -> Result<()> {
28        let addr = (address & 0x00FFFFFF) as usize;
29        if addr + 2 <= self.size {
30            let bytes = value.to_be_bytes();
31            self.data[addr..addr + 2].copy_from_slice(&bytes);
32            Ok(())
33        } else {
34            anyhow::bail!("ARAM write out of bounds: 0x{:08X}", address);
35        }
36    }
37
38    pub fn read_bytes(&self, address: u32, len: usize) -> Result<Vec<u8>> {
39        let addr = (address & 0x00FFFFFF) as usize;
40        if addr + len <= self.size {
41            Ok(self.data[addr..addr + len].to_vec())
42        } else {
43            anyhow::bail!("ARAM read out of bounds: 0x{:08X} len {}", address, len);
44        }
45    }
46
47    pub fn write_bytes(&mut self, address: u32, data: &[u8]) -> Result<()> {
48        let addr = (address & 0x00FFFFFF) as usize;
49        if addr + data.len() <= self.size {
50            self.data[addr..addr + data.len()].copy_from_slice(data);
51            Ok(())
52        } else {
53            anyhow::bail!(
54                "ARAM write out of bounds: 0x{:08X} len {}",
55                address,
56                data.len()
57            );
58        }
59    }
60}