agb/save/asm_utils.rs
1//! A module containing low-level assembly functions that can be loaded into
2//! WRAM. Both flash media and battery-backed SRAM require reads to be
3//! performed via code in WRAM and cannot be accessed by DMA.
4
5unsafe extern "C" {
6 fn agb_rs__WramTransferBuf(src: *const u8, dst: *mut u8, count: usize);
7 fn agb_rs__WramReadByte(src: *const u8) -> u8;
8 fn agb_rs__WramVerifyBuf(buf1: *const u8, buf2: *const u8, count: usize) -> bool;
9}
10
11/// Copies data from a given memory address into a buffer.
12///
13/// This should be used to access any data found in flash or battery-backed
14/// SRAM, as you must read those one byte at a time and from code stored
15/// in WRAM.
16///
17/// This uses raw addresses into the memory space. Use with care.
18#[inline(always)]
19pub unsafe fn read_raw_buf(dst: &mut [u8], src: usize) {
20 if !dst.is_empty() {
21 unsafe {
22 agb_rs__WramTransferBuf(src as _, dst.as_mut_ptr(), dst.len());
23 }
24 }
25}
26
27/// Copies data from a buffer into a given memory address.
28///
29/// This is not strictly needed to write into save media, but reuses the
30/// optimized loop used in `read_raw_buf`, and will often be faster.
31///
32/// This uses raw addresses into the memory space. Use with care.
33#[inline(always)]
34pub unsafe fn write_raw_buf(dst: usize, src: &[u8]) {
35 if !src.is_empty() {
36 unsafe {
37 agb_rs__WramTransferBuf(src.as_ptr(), dst as _, src.len());
38 }
39 }
40}
41
42/// Verifies that the data in a buffer matches that in a given memory address.
43///
44/// This should be used to access any data found in flash or battery-backed
45/// SRAM, as you must read those one byte at a time and from code stored
46/// in WRAM.
47///
48/// This uses raw addresses into the memory space. Use with care.
49#[inline(always)]
50pub unsafe fn verify_raw_buf(buf1: &[u8], buf2: usize) -> bool {
51 if !buf1.is_empty() {
52 unsafe { agb_rs__WramVerifyBuf(buf1.as_ptr(), buf2 as _, buf1.len() - 1) }
53 } else {
54 true
55 }
56}
57
58/// Reads a byte from a given memory address.
59///
60/// This should be used to access any data found in flash or battery-backed
61/// SRAM, as you must read those from code found in WRAM.
62///
63/// This uses raw addresses into the memory space. Use with care.
64#[inline(always)]
65pub unsafe fn read_raw_byte(src: usize) -> u8 {
66 unsafe { agb_rs__WramReadByte(src as _) }
67}