1use crate::save::asm_utils::*;
7use crate::save::utils::Timeout;
8use crate::save::{Error, MediaInfo, MediaType, RawSaveAccess};
9
10const SRAM_SIZE: usize = 32 * 1024; fn check_bounds(offset: usize, len: usize) -> Result<(), Error> {
14 if offset.checked_add(len).is_none() || offset + len > SRAM_SIZE {
15 return Err(Error::OutOfBounds);
16 }
17 Ok(())
18}
19
20pub struct BatteryBackedAccess;
22impl RawSaveAccess for BatteryBackedAccess {
23 fn info(&self) -> Result<&'static MediaInfo, Error> {
24 Ok(&MediaInfo {
25 media_type: MediaType::Sram32K,
26 sector_shift: 0,
27 sector_count: SRAM_SIZE,
28 uses_prepare_write: false,
29 })
30 }
31
32 fn read(&self, offset: usize, buffer: &mut [u8], _: &mut Timeout) -> Result<(), Error> {
33 check_bounds(offset, buffer.len())?;
34 unsafe {
35 read_raw_buf(buffer, 0x0E000000 + offset);
36 }
37 Ok(())
38 }
39
40 fn verify(&self, offset: usize, buffer: &[u8], _: &mut Timeout) -> Result<bool, Error> {
41 check_bounds(offset, buffer.len())?;
42 let val = unsafe { verify_raw_buf(buffer, 0x0E000000 + offset) };
43 Ok(val)
44 }
45
46 fn prepare_write(&self, _: usize, _: usize, _: &mut Timeout) -> Result<(), Error> {
47 Ok(())
48 }
49
50 fn write(&self, offset: usize, buffer: &[u8], _: &mut Timeout) -> Result<(), Error> {
51 check_bounds(offset, buffer.len())?;
52 unsafe {
53 write_raw_buf(0x0E000000 + offset, buffer);
54 }
55 Ok(())
56 }
57}