Final round of bugfixes, documentation fixes and clippy warning fixes.

This commit is contained in:
Alissa Rao 2022-09-15 23:21:31 -07:00
parent 821098dd26
commit 8f3e438070
No known key found for this signature in database
GPG key ID: 9314D8F6745E881E
5 changed files with 38 additions and 45 deletions

View file

@ -7,7 +7,7 @@
@ @
agb_thumb_func agb_rs__WramReadByte agb_thumb_func agb_rs__WramReadByte
ldrb r0, [r0] ldrb r0, [r0]
mov pc, lr bx lr
agb_thumb_end agb_rs__WramReadByte agb_thumb_end agb_rs__WramReadByte
@ @
@ -45,5 +45,5 @@ agb_thumb_func agb_rs__WramXferBuf
ldrb r3, [r0,r2] ldrb r3, [r0,r2]
strb r3, [r1,r2] strb r3, [r1,r2]
bne 0b bne 0b
mov pc, lr bx lr
agb_thumb_end agb_rs__WramXferBuf agb_thumb_end agb_rs__WramXferBuf

View file

@ -17,7 +17,7 @@ extern "C" {
/// This uses raw addresses into the memory space. Use with care. /// This uses raw addresses into the memory space. Use with care.
#[inline(always)] #[inline(always)]
pub unsafe fn read_raw_buf(dst: &mut [u8], src: usize) { pub unsafe fn read_raw_buf(dst: &mut [u8], src: usize) {
if dst.len() != 0 { if !dst.is_empty() {
agb_rs__WramXferBuf(src as _, dst.as_mut_ptr(), dst.len()); agb_rs__WramXferBuf(src as _, dst.as_mut_ptr(), dst.len());
} }
} }
@ -30,7 +30,7 @@ pub unsafe fn read_raw_buf(dst: &mut [u8], src: usize) {
/// This uses raw addresses into the memory space. Use with care. /// This uses raw addresses into the memory space. Use with care.
#[inline(always)] #[inline(always)]
pub unsafe fn write_raw_buf(dst: usize, src: &[u8]) { pub unsafe fn write_raw_buf(dst: usize, src: &[u8]) {
if src.len() != 0 { if !src.is_empty() {
agb_rs__WramXferBuf(src.as_ptr(), dst as _, src.len()); agb_rs__WramXferBuf(src.as_ptr(), dst as _, src.len());
} }
} }
@ -44,7 +44,7 @@ pub unsafe fn write_raw_buf(dst: usize, src: &[u8]) {
/// This uses raw addresses into the memory space. Use with care. /// This uses raw addresses into the memory space. Use with care.
#[inline(always)] #[inline(always)]
pub unsafe fn verify_raw_buf(buf1: &[u8], buf2: usize) -> bool { pub unsafe fn verify_raw_buf(buf1: &[u8], buf2: usize) -> bool {
if buf1.len() != 0 { if !buf1.is_empty() {
agb_rs__WramVerifyBuf(buf1.as_ptr(), buf2 as _, buf1.len() - 1) agb_rs__WramVerifyBuf(buf1.as_ptr(), buf2 as _, buf1.len() - 1)
} else { } else {
true true

View file

@ -93,6 +93,7 @@ struct EepromProperties {
} }
impl EepromProperties { impl EepromProperties {
/// Reads a block from the save media. /// Reads a block from the save media.
#[allow(clippy::needless_range_loop)]
fn read_sector(&self, word: usize) -> [u8; 8] { fn read_sector(&self, word: usize) -> [u8; 8] {
// Set address command. The command is two one bits, followed by the // Set address command. The command is two one bits, followed by the
// address, followed by a zero bit. // address, followed by a zero bit.
@ -117,6 +118,7 @@ impl EepromProperties {
} }
/// Writes a sector directly. /// Writes a sector directly.
#[allow(clippy::needless_range_loop)]
fn write_sector_raw( fn write_sector_raw(
&self, word: usize, block: &[u8], timeout: &mut Timeout, &self, word: usize, block: &[u8], timeout: &mut Timeout,
) -> Result<(), Error> { ) -> Result<(), Error> {
@ -178,7 +180,7 @@ impl EepromProperties {
/// Implements EEPROM reads. /// Implements EEPROM reads.
fn read(&self, mut offset: usize, mut buf: &mut [u8]) -> Result<(), Error> { fn read(&self, mut offset: usize, mut buf: &mut [u8]) -> Result<(), Error> {
self.check_offset(offset, buf.len())?; self.check_offset(offset, buf.len())?;
while buf.len() != 0 { while !buf.is_empty() {
let start = offset & SECTOR_MASK; let start = offset & SECTOR_MASK;
let end_len = cmp::min(SECTOR_LEN - start, buf.len()); let end_len = cmp::min(SECTOR_LEN - start, buf.len());
let sector = self.read_sector(offset >> SECTOR_SHIFT); let sector = self.read_sector(offset >> SECTOR_SHIFT);
@ -192,10 +194,10 @@ impl EepromProperties {
/// Implements EEPROM verifies. /// Implements EEPROM verifies.
fn verify(&self, mut offset: usize, mut buf: &[u8]) -> Result<bool, Error> { fn verify(&self, mut offset: usize, mut buf: &[u8]) -> Result<bool, Error> {
self.check_offset(offset, buf.len())?; self.check_offset(offset, buf.len())?;
while buf.len() != 0 { while !buf.is_empty() {
let start = offset & SECTOR_MASK; let start = offset & SECTOR_MASK;
let end_len = cmp::min(SECTOR_LEN - start, buf.len()); let end_len = cmp::min(SECTOR_LEN - start, buf.len());
if &buf[..end_len] != &self.read_sector(offset >> SECTOR_SHIFT) { if buf[..end_len] != self.read_sector(offset >> SECTOR_SHIFT) {
return Ok(false); return Ok(false);
} }
buf = &buf[end_len..]; buf = &buf[end_len..];
@ -207,7 +209,7 @@ impl EepromProperties {
/// Implements EEPROM writes. /// Implements EEPROM writes.
fn write(&self, mut offset: usize, mut buf: &[u8], timeout: &mut Timeout) -> Result<(), Error> { fn write(&self, mut offset: usize, mut buf: &[u8], timeout: &mut Timeout) -> Result<(), Error> {
self.check_offset(offset, buf.len())?; self.check_offset(offset, buf.len())?;
while buf.len() != 0 { while !buf.is_empty() {
let start = offset & SECTOR_MASK; let start = offset & SECTOR_MASK;
let end_len = cmp::min(SECTOR_LEN - start, buf.len()); let end_len = cmp::min(SECTOR_LEN - start, buf.len());
self.write_sector(offset >> SECTOR_SHIFT, &buf[..end_len], start, timeout)?; self.write_sector(offset >> SECTOR_SHIFT, &buf[..end_len], start, timeout)?;

View file

@ -227,8 +227,8 @@ static CHIP_INFO_GENERIC_128K: ChipInfo = ChipInfo {
impl FlashChipType { impl FlashChipType {
/// Returns the internal info for this chip. /// Returns the internal info for this chip.
fn chip_info(&self) -> &'static ChipInfo { fn chip_info(self) -> &'static ChipInfo {
match *self { match self {
FlashChipType::Sst64K => &CHIP_INFO_SST_64K, FlashChipType::Sst64K => &CHIP_INFO_SST_64K,
FlashChipType::Macronix64K => &CHIP_INFO_MACRONIX_64K, FlashChipType::Macronix64K => &CHIP_INFO_MACRONIX_64K,
FlashChipType::Panasonic64K => &CHIP_INFO_PANASONIC_64K, FlashChipType::Panasonic64K => &CHIP_INFO_PANASONIC_64K,
@ -284,7 +284,7 @@ impl ChipInfo {
/// Reads a buffer from save media into memory. /// Reads a buffer from save media into memory.
fn read_buffer(&self, mut offset: usize, mut buf: &mut [u8]) -> Result<(), Error> { fn read_buffer(&self, mut offset: usize, mut buf: &mut [u8]) -> Result<(), Error> {
while buf.len() != 0 { while !buf.is_empty() {
self.set_bank(offset >> BANK_SHIFT)?; self.set_bank(offset >> BANK_SHIFT)?;
let start = offset & BANK_MASK; let start = offset & BANK_MASK;
let end_len = cmp::min(BANK_LEN - start, buf.len()); let end_len = cmp::min(BANK_LEN - start, buf.len());
@ -299,7 +299,7 @@ impl ChipInfo {
/// Verifies that a buffer was properly stored into save media. /// Verifies that a buffer was properly stored into save media.
fn verify_buffer(&self, mut offset: usize, mut buf: &[u8]) -> Result<bool, Error> { fn verify_buffer(&self, mut offset: usize, mut buf: &[u8]) -> Result<bool, Error> {
while buf.len() != 0 { while !buf.is_empty() {
self.set_bank(offset >> BANK_SHIFT)?; self.set_bank(offset >> BANK_SHIFT)?;
let start = offset & BANK_MASK; let start = offset & BANK_MASK;
let end_len = cmp::min(BANK_LEN - start, buf.len()); let end_len = cmp::min(BANK_LEN - start, buf.len());
@ -355,6 +355,7 @@ impl ChipInfo {
} }
/// Writes an entire buffer to the save media. /// Writes an entire buffer to the save media.
#[allow(clippy::needless_range_loop)]
fn write_buffer(&self, offset: usize, buf: &[u8], timeout: &mut Timeout) -> Result<(), Error> { fn write_buffer(&self, offset: usize, buf: &[u8], timeout: &mut Timeout) -> Result<(), Error> {
self.set_bank(offset >> BANK_SHIFT)?; self.set_bank(offset >> BANK_SHIFT)?;
for i in 0..buf.len() { for i in 0..buf.len() {
@ -368,6 +369,7 @@ impl ChipInfo {
} }
/// Erases and writes an entire 128b sector on Atmel devices. /// Erases and writes an entire 128b sector on Atmel devices.
#[allow(clippy::needless_range_loop)]
fn write_atmel_sector_raw( fn write_atmel_sector_raw(
&self, offset: usize, buf: &[u8], timeout: &mut Timeout, &self, offset: usize, buf: &[u8], timeout: &mut Timeout,
) -> Result<(), Error> { ) -> Result<(), Error> {
@ -453,7 +455,7 @@ impl RawSaveAccess for FlashAccess {
chip.check_len(offset, buf.len())?; chip.check_len(offset, buf.len())?;
if chip.uses_atmel_api { if chip.uses_atmel_api {
while buf.len() != 0 { while !buf.is_empty() {
let start = offset & 127; let start = offset & 127;
let end_len = cmp::min(128 - start, buf.len()); let end_len = cmp::min(128 - start, buf.len());
chip.write_atmel_sector(offset & !127, &buf[..end_len], start, timeout)?; chip.write_atmel_sector(offset & !127, &buf[..end_len], start, timeout)?;

View file

@ -25,18 +25,17 @@
//! To use save media in your game, you must set which type to use. This is done //! To use save media in your game, you must set which type to use. This is done
//! by calling one of the following functions at startup: //! by calling one of the following functions at startup:
//! //!
//! * For 32 KiB battery-backed SRAM, call [`use_sram`]. //! * For 32 KiB battery-backed SRAM, call [`init_sram`].
//! * For 64 KiB flash memory, call [`use_flash_64k`]. //! * For 64 KiB flash memory, call [`init_flash_64k`].
//! * For 128 KiB flash memory, call [`use_flash_128k`]. //! * For 128 KiB flash memory, call [`init_flash_128k`].
//! * For 512 byte EEPROM, call [`use_eeprom_512b`]. //! * For 512 byte EEPROM, call [`init_eeprom_512b`].
//! * For 8 KiB EEPROM, call [`use_eeprom_8k`]. //! * For 8 KiB EEPROM, call [`init_eeprom_8k`].
//! //!
//! TODO Update example //! [`init_sram`]: SaveManager::init_sram
//! ```rust,norun //! [`init_flash_64k`]: SaveManager::init_flash_64k
//! # use gba::save; //! [`init_flash_128k`]: SaveManager::init_flash_128k
//! save::use_flash_128k(); //! [`init_eeprom_512b`]: SaveManager::init_eeprom_512b
//! save::set_timer_for_timeout(3); // Uses timer 3 for save media timeouts. //! [`init_eeprom_8k`]: SaveManager::init_eeprom_8k
//! ```
//! //!
//! ## Using save media //! ## Using save media
//! //!
@ -46,29 +45,10 @@
//! Reading data from the savegame is simple. Use [`read`] to copy data from an //! Reading data from the savegame is simple. Use [`read`] to copy data from an
//! offset in the savegame into a buffer in memory. //! offset in the savegame into a buffer in memory.
//! //!
//! TODO Update example
//! ```rust,norun
//! # use gba::{info, save::SaveAccess};
//! let mut buf = [0; 1000];
//! SaveAccess::new()?.read(1000, &mut buf)?;
//! info!("Memory result: {:?}", buf);
//! ```
//!
//! Writing to save media requires you to prepare the area for writing by calling //! Writing to save media requires you to prepare the area for writing by calling
//! the [`prepare_write`] method to return a [`SavePreparedBlock`], which contains //! the [`prepare_write`] method to return a [`SavePreparedBlock`], which contains
//! the actual [`write`] method. //! the actual [`write`] method.
//! //!
//! TODO Update example
//! ```rust,norun
//! # use gba::{info, save::SaveAccess};
//! let access = SaveAccess::new()?;
//! access.prepare_write(500..600)?;
//! access.write(500, &[10; 25])?;
//! access.write(525, &[20; 25])?;
//! access.write(550, &[30; 25])?;
//! access.write(575, &[40; 25])?;
//! ```
//!
//! The `prepare_write` method leaves everything in a sector that overlaps the //! The `prepare_write` method leaves everything in a sector that overlaps the
//! range passed to it in an implementation defined state. On some devices it may //! range passed to it in an implementation defined state. On some devices it may
//! do nothing, and on others, it may clear the entire range to `0xFF`. //! do nothing, and on others, it may clear the entire range to `0xFF`.
@ -169,11 +149,14 @@ pub struct MediaInfo {
impl MediaInfo { impl MediaInfo {
/// Returns the sector size of the save media. It is generally optimal to /// Returns the sector size of the save media. It is generally optimal to
/// write data in blocks that are aligned to the sector size. /// write data in blocks that are aligned to the sector size.
#[must_use]
pub fn sector_size(&self) -> usize { pub fn sector_size(&self) -> usize {
1 << self.sector_shift 1 << self.sector_shift
} }
/// Returns the total length of this save media. /// Returns the total length of this save media.
#[must_use]
#[allow(clippy::len_without_is_empty)] // is_empty() would always be false
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.sector_count << self.sector_shift self.sector_count << self.sector_shift
} }
@ -222,22 +205,27 @@ impl SaveData {
} }
/// Returns the media info underlying this accessor. /// Returns the media info underlying this accessor.
#[must_use]
pub fn media_info(&self) -> &'static MediaInfo { pub fn media_info(&self) -> &'static MediaInfo {
self.info self.info
} }
/// Returns the save media type being used. /// Returns the save media type being used.
#[must_use]
pub fn media_type(&self) -> MediaType { pub fn media_type(&self) -> MediaType {
self.info.media_type self.info.media_type
} }
/// Returns the sector size of the save media. It is generally optimal to /// Returns the sector size of the save media. It is generally optimal to
/// write data in blocks that are aligned to the sector size. /// write data in blocks that are aligned to the sector size.
#[must_use]
pub fn sector_size(&self) -> usize { pub fn sector_size(&self) -> usize {
self.info.sector_size() self.info.sector_size()
} }
/// Returns the total length of this save media. /// Returns the total length of this save media.
#[must_use]
#[allow(clippy::len_without_is_empty)] // is_empty() would always be false
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.info.len() self.info.len()
} }
@ -271,6 +259,7 @@ impl SaveData {
/// ///
/// This can be used to calculate which blocks would be erased by a call /// This can be used to calculate which blocks would be erased by a call
/// to [`prepare_write`](`SaveAccess::prepare_write`) /// to [`prepare_write`](`SaveAccess::prepare_write`)
#[must_use]
pub fn align_range(&self, range: Range<usize>) -> Range<usize> { pub fn align_range(&self, range: Range<usize>) -> Range<usize> {
let shift = self.info.sector_shift; let shift = self.info.sector_shift;
let mask = (1 << shift) - 1; let mask = (1 << shift) - 1;
@ -311,7 +300,7 @@ impl<'a> SavePreparedBlock<'a> {
/// state. If an error is returned, the contents of the save media is /// state. If an error is returned, the contents of the save media is
/// unpredictable. /// unpredictable.
pub fn write(&mut self, offset: usize, buffer: &[u8]) -> Result<(), Error> { pub fn write(&mut self, offset: usize, buffer: &[u8]) -> Result<(), Error> {
if buffer.len() == 0 { if buffer.is_empty() {
Ok(()) Ok(())
} else if !self.range.contains(&offset) || } else if !self.range.contains(&offset) ||
!self.range.contains(&(offset + buffer.len() - 1)) { !self.range.contains(&(offset + buffer.len() - 1)) {