Refactor bus interface

Former-commit-id: f325cda23f5e9946b367456d82ba71bb92bdd46e
This commit is contained in:
Michel Heily 2019-07-15 07:30:52 +03:00
parent f08da850c7
commit 0500d33cb7
5 changed files with 92 additions and 54 deletions

View file

@ -2,8 +2,6 @@ use std::fmt;
use std::io; use std::io;
use std::ops::Add; use std::ops::Add;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use super::Addr; use super::Addr;
#[derive(Debug)] #[derive(Debug)]
@ -50,29 +48,12 @@ impl fmt::Display for MemoryAccess {
} }
pub trait Bus { pub trait Bus {
fn read_32(&self, addr: Addr) -> u32 { fn read_32(&self, addr: Addr) -> u32;
self.get_bytes(addr).read_u32::<LittleEndian>().unwrap() fn read_16(&self, addr: Addr) -> u16;
} fn read_8(&self, addr: Addr) -> u8;
fn write_32(&mut self, addr: Addr, value: u32);
fn read_16(&self, addr: Addr) -> u16 { fn write_16(&mut self, addr: Addr, value: u16);
self.get_bytes(addr).read_u16::<LittleEndian>().unwrap() fn write_8(&mut self, addr: Addr, value: u8);
}
fn read_8(&self, addr: Addr) -> u8 {
self.get_bytes(addr)[0]
}
fn write_32(&mut self, addr: Addr, value: u32) -> Result<(), io::Error> {
self.get_bytes_mut(addr).write_u32::<LittleEndian>(value)
}
fn write_16(&mut self, addr: Addr, value: u16) -> Result<(), io::Error> {
self.get_bytes_mut(addr).write_u16::<LittleEndian>(value)
}
fn write_8(&mut self, addr: Addr, value: u8) -> Result<(), io::Error> {
self.get_bytes_mut(addr).write_u8(value)
}
/// Return a slice of bytes /// Return a slice of bytes
fn get_bytes(&self, addr: Addr) -> &[u8]; fn get_bytes(&self, addr: Addr) -> &[u8];

View file

@ -236,21 +236,21 @@ impl Core {
let cycle_type = self.cycle_type(addr); let cycle_type = self.cycle_type(addr);
self.add_cycles(addr, bus, cycle_type + MemoryAccess32); self.add_cycles(addr, bus, cycle_type + MemoryAccess32);
self.memreq = addr; self.memreq = addr;
bus.write_32(addr, value).expect("store_32 error"); bus.write_32(addr, value);
} }
pub fn store_16(&mut self, addr: Addr, value: u16, bus: &mut Bus) { pub fn store_16(&mut self, addr: Addr, value: u16, bus: &mut Bus) {
let cycle_type = self.cycle_type(addr); let cycle_type = self.cycle_type(addr);
self.add_cycles(addr, bus, cycle_type + MemoryAccess16); self.add_cycles(addr, bus, cycle_type + MemoryAccess16);
self.memreq = addr; self.memreq = addr;
bus.write_16(addr, value).expect("store_16 error"); bus.write_16(addr, value);
} }
pub fn store_8(&mut self, addr: Addr, value: u8, bus: &mut Bus) { pub fn store_8(&mut self, addr: Addr, value: u8, bus: &mut Bus) {
let cycle_type = self.cycle_type(addr); let cycle_type = self.cycle_type(addr);
self.add_cycles(addr, bus, cycle_type + MemoryAccess8); self.add_cycles(addr, bus, cycle_type + MemoryAccess8);
self.memreq = addr; self.memreq = addr;
bus.write_8(addr, value).expect("store_16 error"); bus.write_8(addr, value);
} }
pub fn check_arm_cond(&self, cond: ArmCond) -> bool { pub fn check_arm_cond(&self, cond: ArmCond) -> bool {

View file

@ -1,5 +1,7 @@
use std::str::from_utf8; use std::str::from_utf8;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use crate::arm7tdmi::{ use crate::arm7tdmi::{
bus::{Bus, MemoryAccess, MemoryAccessWidth}, bus::{Bus, MemoryAccess, MemoryAccessWidth},
Addr, Addr,
@ -93,6 +95,38 @@ impl Cartridge {
} }
impl Bus for Cartridge { impl Bus for Cartridge {
fn read_32(&self, addr: Addr) -> u32 {
(&self.bytes[addr as usize..])
.read_u32::<LittleEndian>()
.unwrap()
}
fn read_16(&self, addr: Addr) -> u16 {
(&self.bytes[addr as usize..])
.read_u16::<LittleEndian>()
.unwrap()
}
fn read_8(&self, addr: Addr) -> u8 {
(&self.bytes[addr as usize..])[0]
}
fn write_32(&mut self, addr: Addr, value: u32) {
(&mut self.bytes[addr as usize..])
.write_u32::<LittleEndian>(value)
.unwrap()
}
fn write_16(&mut self, addr: Addr, value: u16) {
(&mut self.bytes[addr as usize..])
.write_u16::<LittleEndian>(value)
.unwrap()
}
fn write_8(&mut self, addr: Addr, value: u8) {
(&mut self.bytes[addr as usize..]).write_u8(value).unwrap()
}
fn get_bytes(&self, addr: Addr) -> &[u8] { fn get_bytes(&self, addr: Addr) -> &[u8] {
&self.bytes[addr as usize..] &self.bytes[addr as usize..]
} }

View file

@ -168,19 +168,19 @@ impl Bus for IoRegs {
self.read_reg(IO_BASE + addr) as u8 self.read_reg(IO_BASE + addr) as u8
} }
fn write_32(&mut self, addr: Addr, value: u32) -> Result<(), io::Error> { fn write_32(&mut self, addr: Addr, value: u32) {
self.get_bytes_mut(addr).write_u32::<LittleEndian>(value) self.get_bytes_mut(addr)
.write_u32::<LittleEndian>(value)
.unwrap()
} }
fn write_16(&mut self, addr: Addr, value: u16) -> Result<(), io::Error> { fn write_16(&mut self, addr: Addr, value: u16) {
self.write_reg(IO_BASE + addr, value); self.write_reg(IO_BASE + addr, value);
Ok(())
} }
fn write_8(&mut self, addr: Addr, value: u8) -> Result<(), io::Error> { fn write_8(&mut self, addr: Addr, value: u8) {
let new_value = self.read_reg(IO_BASE + addr) & 0xff00 | (value as u16); let new_value = self.read_reg(IO_BASE + addr) & 0xff00 | (value as u16);
self.write_reg(IO_BASE + addr, new_value); self.write_reg(IO_BASE + addr, new_value);
Ok(())
} }
/// Return a slice of bytes /// Return a slice of bytes

View file

@ -1,5 +1,7 @@
use std::io; use std::io;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use super::{cartridge::Cartridge, ioregs::IoRegs}; use super::{cartridge::Cartridge, ioregs::IoRegs};
use super::arm7tdmi::bus::{Bus, MemoryAccess, MemoryAccessWidth}; use super::arm7tdmi::bus::{Bus, MemoryAccess, MemoryAccessWidth};
@ -48,6 +50,38 @@ impl Default for WaitState {
} }
impl Bus for BoxedMemory { impl Bus for BoxedMemory {
fn read_32(&self, addr: Addr) -> u32 {
(&self.0[addr as usize..])
.read_u32::<LittleEndian>()
.unwrap()
}
fn read_16(&self, addr: Addr) -> u16 {
(&self.0[addr as usize..])
.read_u16::<LittleEndian>()
.unwrap()
}
fn read_8(&self, addr: Addr) -> u8 {
(&self.0[addr as usize..])[0]
}
fn write_32(&mut self, addr: Addr, value: u32) {
(&mut self.0[addr as usize..])
.write_u32::<LittleEndian>(value)
.unwrap()
}
fn write_16(&mut self, addr: Addr, value: u16) {
(&mut self.0[addr as usize..])
.write_u16::<LittleEndian>(value)
.unwrap()
}
fn write_8(&mut self, addr: Addr, value: u8) {
(&mut self.0[addr as usize..]).write_u8(value).unwrap()
}
fn get_bytes(&self, addr: Addr) -> &[u8] { fn get_bytes(&self, addr: Addr) -> &[u8] {
&self.0[addr as usize..] &self.0[addr as usize..]
} }
@ -81,17 +115,12 @@ impl Bus for DummyBus {
0 0
} }
fn write_32(&mut self, _addr: Addr, _value: u32) -> Result<(), io::Error> { fn write_32(&mut self, _addr: Addr, _value: u32) {}
Ok(())
}
fn write_16(&mut self, _addr: Addr, _value: u16) -> Result<(), io::Error> { fn write_16(&mut self, _addr: Addr, _value: u16) {}
Ok(())
} fn write_8(&mut self, _addr: Addr, _value: u8) {}
fn write_8(&mut self, _addr: Addr, _value: u8) -> Result<(), io::Error> {
Ok(())
}
fn get_bytes(&self, _addr: Addr) -> &[u8] { fn get_bytes(&self, _addr: Addr) -> &[u8] {
&self.0 &self.0
} }
@ -153,10 +182,7 @@ impl SysBus {
0x0600_0000...0x0601_7fff => &self.vram, 0x0600_0000...0x0601_7fff => &self.vram,
0x0700_0000...0x0700_03ff => &self.oam, 0x0700_0000...0x0700_03ff => &self.oam,
0x0800_0000...0x09ff_ffff => &self.gamepak, 0x0800_0000...0x09ff_ffff => &self.gamepak,
_ => { _ => &self.dummy,
println!("unmapped address @0x{:08x}", addr);
&self.dummy
}
} }
} }
@ -171,10 +197,7 @@ impl SysBus {
0x0600_0000...0x0601_7fff => &mut self.vram, 0x0600_0000...0x0601_7fff => &mut self.vram,
0x0700_0000...0x0700_03ff => &mut self.oam, 0x0700_0000...0x0700_03ff => &mut self.oam,
0x0800_0000...0x09ff_ffff => &mut self.gamepak, 0x0800_0000...0x09ff_ffff => &mut self.gamepak,
_ => { _ => &mut self.dummy,
println!("unmapped address @0x{:08x}", addr);
&mut self.dummy
}
} }
} }
} }
@ -192,15 +215,15 @@ impl Bus for SysBus {
self.map(addr).read_8(addr & 0xff_ffff) self.map(addr).read_8(addr & 0xff_ffff)
} }
fn write_32(&mut self, addr: Addr, value: u32) -> Result<(), io::Error> { fn write_32(&mut self, addr: Addr, value: u32) {
self.map_mut(addr).write_32(addr & 0xff_ffff, value) self.map_mut(addr).write_32(addr & 0xff_ffff, value)
} }
fn write_16(&mut self, addr: Addr, value: u16) -> Result<(), io::Error> { fn write_16(&mut self, addr: Addr, value: u16) {
self.map_mut(addr).write_16(addr & 0xff_ffff, value) self.map_mut(addr).write_16(addr & 0xff_ffff, value)
} }
fn write_8(&mut self, addr: Addr, value: u8) -> Result<(), io::Error> { fn write_8(&mut self, addr: Addr, value: u8) {
self.map_mut(addr).write_8(addr & 0xff_ffff, value) self.map_mut(addr).write_8(addr & 0xff_ffff, value)
} }