diff --git a/arm7tdmi/src/arm/mod.rs b/arm7tdmi/src/arm/mod.rs index 5f8a378..f3a08df 100644 --- a/arm7tdmi/src/arm/mod.rs +++ b/arm7tdmi/src/arm/mod.rs @@ -146,7 +146,7 @@ impl InstructionDecoder for ArmInstruction { fn decode(raw: u32, addr: Addr) -> Self { let fmt = ArmFormat::from(raw); - ArmInstruction {fmt, raw, pc: addr } + ArmInstruction { fmt, raw, pc: addr } } fn decode_from_bytes(bytes: &[u8], addr: Addr) -> Self { diff --git a/arm7tdmi/src/lib.rs b/arm7tdmi/src/lib.rs index 8d3aaf2..f9b8b6b 100644 --- a/arm7tdmi/src/lib.rs +++ b/arm7tdmi/src/lib.rs @@ -21,10 +21,9 @@ pub mod alu; pub mod memory; pub use alu::*; use memory::Addr; +pub mod disass; pub mod exception; pub mod psr; -pub use psr::*; -pub mod disass; pub mod registers_consts { pub const REG_PC: usize = 15; diff --git a/arm7tdmi/src/memory.rs b/arm7tdmi/src/memory.rs index f3a30dc..0048c11 100644 --- a/arm7tdmi/src/memory.rs +++ b/arm7tdmi/src/memory.rs @@ -169,3 +169,90 @@ impl Arm7tdmiCore { } } } + +/// Simple trait for accessing bus peripherals (higher level API than the low-level MemoryInterface) +pub trait BusIO { + fn read_32(&mut self, addr: Addr) -> u32 { + self.read_16(addr) as u32 | (self.read_16(addr + 2) as u32) << 16 + } + + fn read_16(&mut self, addr: Addr) -> u16 { + self.default_read_16(addr) + } + + #[inline(always)] + fn default_read_16(&mut self, addr: Addr) -> u16 { + self.read_8(addr) as u16 | (self.read_8(addr + 1) as u16) << 8 + } + + fn read_8(&mut self, addr: Addr) -> u8; + + fn write_32(&mut self, addr: Addr, value: u32) { + self.write_16(addr, (value & 0xffff) as u16); + self.write_16(addr + 2, (value >> 16) as u16); + } + + fn write_16(&mut self, addr: Addr, value: u16) { + self.default_write_16(addr, value) + } + + #[inline(always)] + fn default_write_16(&mut self, addr: Addr, value: u16) { + self.write_8(addr, (value & 0xff) as u8); + self.write_8(addr + 1, ((value >> 8) & 0xff) as u8); + } + + fn write_8(&mut self, addr: Addr, value: u8); + + fn get_bytes(&mut self, range: std::ops::Range) -> Vec { + let mut bytes = Vec::new(); + for b in range { + bytes.push(self.read_8(b)); + } + bytes + } +} + +/// Helper trait for reading memory as if we were an all-powerfull debugger +pub trait DebugRead: BusIO { + fn debug_read_32(&mut self, addr: Addr) -> u32 { + self.debug_read_16(addr) as u32 | (self.debug_read_16(addr + 2) as u32) << 16 + } + + fn debug_read_16(&mut self, addr: Addr) -> u16 { + self.debug_read_8(addr) as u16 | (self.debug_read_8(addr + 1) as u16) << 8 + } + + fn debug_read_8(&mut self, addr: Addr) -> u8; + + fn debug_get_bytes(&mut self, range: std::ops::Range) -> Vec { + let mut bytes = Vec::new(); + for b in range { + bytes.push(self.debug_read_8(b)); + } + bytes + } +} + +/// The caller is assumed to handle out of bound accesses, +/// For performance reasons, this impl trusts that 'addr' is within the array range. +impl BusIO for Box<[u8]> { + #[inline] + fn read_8(&mut self, addr: Addr) -> u8 { + unsafe { *self.get_unchecked(addr as usize) } + } + + #[inline] + fn write_8(&mut self, addr: Addr, value: u8) { + unsafe { + *self.get_unchecked_mut(addr as usize) = value; + } + } +} + +impl DebugRead for Box<[u8]> { + #[inline] + fn debug_read_8(&mut self, addr: Addr) -> u8 { + self[addr as usize] + } +} diff --git a/arm7tdmi/src/psr.rs b/arm7tdmi/src/psr.rs index d75d78f..61eee4b 100644 --- a/arm7tdmi/src/psr.rs +++ b/arm7tdmi/src/psr.rs @@ -30,6 +30,7 @@ impl From for CpuState { } #[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)] +#[repr(transparent)] pub struct RegPSR { raw: u32, } diff --git a/core/src/bios.rs b/core/src/bios.rs index 6fca0ff..8f67ba2 100644 --- a/core/src/bios.rs +++ b/core/src/bios.rs @@ -1,6 +1,8 @@ -use super::bus::{Bus, DebugRead}; use super::SysBus; -use arm7tdmi::{memory::Addr, Arm7tdmiCore}; +use arm7tdmi::{ + memory::{Addr, BusIO, DebugRead}, + Arm7tdmiCore, +}; use rustboyadvance_utils::WeakPointer; @@ -35,7 +37,7 @@ impl Bios { } /// Impl of Bus trait for Bios -impl Bus for Bios { +impl BusIO for Bios { #[inline] fn read_32(&mut self, addr: Addr) -> u32 { if self.read_allowed() { diff --git a/core/src/bus.rs b/core/src/bus.rs deleted file mode 100644 index 172dbcf..0000000 --- a/core/src/bus.rs +++ /dev/null @@ -1,87 +0,0 @@ -pub use arm7tdmi::memory::Addr; // re-export - -pub trait Bus { - fn read_32(&mut self, addr: Addr) -> u32 { - self.read_16(addr) as u32 | (self.read_16(addr + 2) as u32) << 16 - } - - fn read_16(&mut self, addr: Addr) -> u16 { - self.default_read_16(addr) - } - - #[inline(always)] - fn default_read_16(&mut self, addr: Addr) -> u16 { - self.read_8(addr) as u16 | (self.read_8(addr + 1) as u16) << 8 - } - - fn read_8(&mut self, addr: Addr) -> u8; - - fn write_32(&mut self, addr: Addr, value: u32) { - self.write_16(addr, (value & 0xffff) as u16); - self.write_16(addr + 2, (value >> 16) as u16); - } - - fn write_16(&mut self, addr: Addr, value: u16) { - self.default_write_16(addr, value) - } - - #[inline(always)] - fn default_write_16(&mut self, addr: Addr, value: u16) { - self.write_8(addr, (value & 0xff) as u8); - self.write_8(addr + 1, ((value >> 8) & 0xff) as u8); - } - - fn write_8(&mut self, addr: Addr, value: u8); - - fn get_bytes(&mut self, range: std::ops::Range) -> Vec { - let mut bytes = Vec::new(); - for b in range { - bytes.push(self.read_8(b)); - } - bytes - } -} - -/// Helper trait for reading memory as if we were an all-powerfull debugger -pub trait DebugRead: Bus { - fn debug_read_32(&mut self, addr: Addr) -> u32 { - self.debug_read_16(addr) as u32 | (self.debug_read_16(addr + 2) as u32) << 16 - } - - fn debug_read_16(&mut self, addr: Addr) -> u16 { - self.debug_read_8(addr) as u16 | (self.debug_read_8(addr + 1) as u16) << 8 - } - - fn debug_read_8(&mut self, addr: Addr) -> u8; - - fn debug_get_bytes(&mut self, range: std::ops::Range) -> Vec { - let mut bytes = Vec::new(); - for b in range { - bytes.push(self.debug_read_8(b)); - } - bytes - } -} - -/// The caller is assumed to handle out of bound accesses, -/// For performance reasons, this impl trusts that 'addr' is within the array range. -impl Bus for Box<[u8]> { - #[inline] - fn read_8(&mut self, addr: Addr) -> u8 { - unsafe { *self.get_unchecked(addr as usize) } - } - - #[inline] - fn write_8(&mut self, addr: Addr, value: u8) { - unsafe { - *self.get_unchecked_mut(addr as usize) = value; - } - } -} - -impl DebugRead for Box<[u8]> { - #[inline] - fn debug_read_8(&mut self, addr: Addr) -> u8 { - self[addr as usize] - } -} diff --git a/core/src/cartridge/backup/eeprom.rs b/core/src/cartridge/backup/eeprom.rs index b7de9c3..71f8cd1 100644 --- a/core/src/cartridge/backup/eeprom.rs +++ b/core/src/cartridge/backup/eeprom.rs @@ -152,8 +152,9 @@ impl EepromChip { RxInstruction => { // If instruction was recvd, proceed to recv the address if self.rx_count >= 2 { - let insn = SpiInstruction::from_u64(self.rx_buffer).unwrap_or_else(|| panic!("invalid spi command {:#010b}", - self.rx_buffer as u8)); + let insn = SpiInstruction::from_u64(self.rx_buffer).unwrap_or_else(|| { + panic!("invalid spi command {:#010b}", self.rx_buffer as u8) + }); next_state = Some(RxAddress(insn)); self.reset_rx_buffer(); } diff --git a/core/src/cartridge/backup/flash.rs b/core/src/cartridge/backup/flash.rs index d3731d2..93a7d92 100644 --- a/core/src/cartridge/backup/flash.rs +++ b/core/src/cartridge/backup/flash.rs @@ -149,7 +149,6 @@ impl Flash { pub fn read(&self, addr: u32) -> u8 { let offset = (addr & 0xffff) as usize; - if self.mode == FlashMode::ChipId { match offset { diff --git a/core/src/cartridge/builder.rs b/core/src/cartridge/builder.rs index 684ce99..80790ca 100644 --- a/core/src/cartridge/builder.rs +++ b/core/src/cartridge/builder.rs @@ -216,8 +216,7 @@ fn create_backup(backup_type: BackupType, rom_path: Option) -> BackupMe } fn detect_backup_type(bytes: &[u8]) -> Option { - const ID_STRINGS: &[&str] = - &["EEPROM", "SRAM", "FLASH_", "FLASH512_", "FLASH1M_"]; + const ID_STRINGS: &[&str] = &["EEPROM", "SRAM", "FLASH_", "FLASH512_", "FLASH1M_"]; for i in 0..5 { let search = TwoWaySearcher::new(ID_STRINGS[i].as_bytes()); diff --git a/core/src/cartridge/mod.rs b/core/src/cartridge/mod.rs index e2062a7..1b543ed 100644 --- a/core/src/cartridge/mod.rs +++ b/core/src/cartridge/mod.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; -use super::bus::*; +use arm7tdmi::memory::{Addr, BusIO, DebugRead}; pub mod header; use header::CartridgeHeader; @@ -109,7 +109,7 @@ fn is_gpio_access(addr: u32) -> bool { } } -impl Bus for Cartridge { +impl BusIO for Cartridge { fn read_8(&mut self, addr: Addr) -> u8 { let offset = (addr & 0x01ff_ffff) as usize; match addr & 0xff000000 { diff --git a/core/src/gba.rs b/core/src/gba.rs index bf06260..868fa99 100644 --- a/core/src/gba.rs +++ b/core/src/gba.rs @@ -397,8 +397,8 @@ mod tests { use std::cell::RefCell; use std::rc::Rc; - use super::super::bus::Bus; - use super::super::cartridge::GamepakBuilder; + use crate::cartridge::GamepakBuilder; + use arm7tdmi::memory::BusIO; struct DummyInterface {} diff --git a/core/src/gpu/mod.rs b/core/src/gpu/mod.rs index c315784..8ad8ac6 100644 --- a/core/src/gpu/mod.rs +++ b/core/src/gpu/mod.rs @@ -6,9 +6,9 @@ use std::rc::Rc; use num::FromPrimitive; use serde::{Deserialize, Serialize}; +use arm7tdmi::memory::{Addr, BusIO, DebugRead}; use rustboyadvance_utils::index2d; -use super::bus::*; use super::dma::{DmaNotifer, TIMING_HBLANK, TIMING_VBLANK}; use super::interrupt::{self, Interrupt, InterruptConnect, SharedInterruptFlags}; use super::sched::{EventType, FutureEvent, GpuEvent, Scheduler}; @@ -455,7 +455,7 @@ impl Gpu { } } -impl Bus for Gpu { +impl BusIO for Gpu { fn read_8(&mut self, addr: Addr) -> u8 { let page = (addr >> 24) as usize; match page { diff --git a/core/src/iodev.rs b/core/src/iodev.rs index 2714bd2..c30ff3c 100644 --- a/core/src/iodev.rs +++ b/core/src/iodev.rs @@ -1,6 +1,7 @@ use std::cmp; -use super::bus::*; +use arm7tdmi::memory::{Addr, BusIO, DebugRead}; + use super::dma::DmaController; use super::gpu::regs::GpuMemoryMappedIO; use super::gpu::regs::WindowFlags; @@ -92,7 +93,7 @@ impl SchedulerConnect for IoDevices { } } -impl Bus for IoDevices { +impl BusIO for IoDevices { fn read_16(&mut self, addr: Addr) -> u16 { let io = self; let io_addr = addr + IO_BASE; diff --git a/core/src/lib.rs b/core/src/lib.rs index 670c21c..65c25bf 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -10,7 +10,6 @@ extern crate debug_stub_derive; #[macro_use] extern crate enum_primitive_derive; - #[macro_use] extern crate bitfield; #[macro_use] @@ -27,8 +26,6 @@ extern crate smart_default; extern crate cfg_if; - - use std::error::Error; use std::fmt; diff --git a/core/src/sysbus.rs b/core/src/sysbus.rs index 9e4f050..6518156 100644 --- a/core/src/sysbus.rs +++ b/core/src/sysbus.rs @@ -1,8 +1,9 @@ use serde::{Deserialize, Serialize}; -use super::arm7tdmi::memory::*; +use super::arm7tdmi::memory::{ + Addr, BusIO, DebugRead, MemoryAccess, MemoryAccessWidth, MemoryInterface, +}; use super::bios::Bios; -use super::bus::*; use super::cartridge::Cartridge; use super::dma::DmaNotifer; use super::iodev::{IoDevices, WaitControl}; @@ -305,7 +306,7 @@ impl SysBus { } /// Todo - implement bound checks for EWRAM/IWRAM -impl Bus for SysBus { +impl BusIO for SysBus { #[inline] fn read_32(&mut self, addr: Addr) -> u32 { match addr & 0xff000000 {