Refactored address space again

This commit is contained in:
transistor 2021-10-05 19:58:22 -07:00
parent f2a23a21cb
commit 59019d9c8e
8 changed files with 81 additions and 64 deletions

View File

@ -1,6 +1,6 @@
use crate::error::Error;
use crate::memory::{Address, AddressSpace};
use crate::memory::{Address, Addressable, AddressSpace};
use super::execute::{MC68010};
use super::decode::{Instruction, Target, Size, Direction, Condition, ControlRegister, RegisterType};

View File

@ -2,7 +2,7 @@
use std::fmt;
use crate::error::Error;
use crate::memory::{Address, AddressSpace};
use crate::memory::{Address, Addressable, AddressSpace};
use super::execute::ERR_ILLEGAL_INSTRUCTION;

View File

@ -1,7 +1,7 @@
use crate::error::Error;
use crate::timers::CpuTimer;
use crate::memory::{Address, AddressSpace};
use crate::memory::{Address, Addressable, AddressSpace};
use super::debugger::M68kDebugger;
use super::decode::{
@ -142,9 +142,9 @@ impl MC68010 {
self.execute_current(space)?;
self.timer.cycle.end(timer);
//if (self.timer.cycle.events % 500) == 0 {
// println!("{}", self.timer);
//}
if (self.timer.cycle.events % 500) == 0 {
println!("{}", self.timer);
}
Ok(())
},

View File

@ -1,5 +1,5 @@
use crate::memory::{Address, AddressSpace, MemoryBlock};
use crate::memory::{Address, Addressable, AddressSpace, MemoryBlock};
use super::execute::MC68010;
use super::decode::{Instruction, Target, Size, Sign, ShiftDirection};
@ -27,7 +27,7 @@ fn init_test() -> (MC68010, AddressSpace) {
#[cfg(test)]
mod tests {
use crate::memory::Address;
use crate::memory::{Address, Addressable};
use super::{init_test, INIT_ADDR};
use super::{Instruction, Target, Size, Sign, ShiftDirection};

View File

@ -64,7 +64,7 @@ impl Addressable for AtaDevice {
0x30
}
fn read(&mut self, addr: Address, count: usize) -> Vec<u8> {
fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
let mut data = vec![0; count];
match addr {
@ -87,10 +87,10 @@ println!(">> {:x}", data[0]);
_ => { println!("{}: reading from {:0x}", DEV_NAME, addr); },
}
data
Ok(data)
}
fn write(&mut self, mut addr: Address, data: &[u8]) {
fn write(&mut self, mut addr: Address, data: &[u8]) -> Result<(), Error> {
println!("{}: write to register {:x} with {:x}", DEV_NAME, addr, data[0]);
match addr {
ATA_REG_DRIVE_HEAD => { self.selected_sector |= ((data[0] & 0x1F) as u32) << 24; },
@ -115,6 +115,7 @@ println!(">> {:x}", data[0]);
},
_ => { println!("{}: writing {:0x} to {:0x}", DEV_NAME, data[0], addr); },
}
Ok(())
}
}

View File

@ -116,7 +116,7 @@ impl Addressable for MC68681 {
0x30
}
fn read(&mut self, addr: Address, count: usize) -> Vec<u8> {
fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
let mut data = vec![0; count];
// TODO this is temporary
@ -133,10 +133,10 @@ impl Addressable for MC68681 {
_ => { println!("{}: reading from {:0x}", DEV_NAME, addr); data[0] = self.input; },
}
data
Ok(data)
}
fn write(&mut self, mut addr: Address, data: &[u8]) {
fn write(&mut self, mut addr: Address, data: &[u8]) -> Result<(), Error> {
match addr {
REG_TBA_WR => {
println!("{}: {}", DEV_NAME, data[0] as char);
@ -144,6 +144,7 @@ impl Addressable for MC68681 {
},
_ => { println!("{}: writing {:0x} to {:0x}", DEV_NAME, data[0], addr); },
}
Ok(())
}
}

View File

@ -32,12 +32,12 @@ fn main() {
space.insert(0x00700000, Box::new(serial));
let mut cpu = MC68010::new();
cpu.enable_tracing();
//cpu.enable_tracing();
//cpu.add_breakpoint(0x0c94);
//cpu.add_breakpoint(0x103234);
cpu.add_breakpoint(0x224);
cpu.add_breakpoint(0x10407e);
//cpu.add_breakpoint(0x224);
//cpu.add_breakpoint(0x10407e);
while cpu.is_running() {
match cpu.step(&mut space) {

View File

@ -9,8 +9,35 @@ pub type Address = u64;
pub trait Addressable {
fn len(&self) -> usize;
fn read(&mut self, addr: Address, count: usize) -> Vec<u8>;
fn write(&mut self, addr: Address, data: &[u8]);
fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error>;
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error>;
fn read_u8(&mut self, addr: Address) -> Result<u8, Error> {
Ok(self.read(addr, 1)?[0])
}
fn read_beu16(&mut self, addr: Address) -> Result<u16, Error> {
Ok(read_beu16(&self.read(addr, 2)?))
}
fn read_beu32(&mut self, addr: Address) -> Result<u32, Error> {
Ok(read_beu32(&self.read(addr, 4)?))
}
fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> {
let data = [value];
self.write(addr, &data)
}
fn write_beu16(&mut self, addr: Address, value: u16) -> Result<(), Error> {
let data = write_beu16(value);
self.write(addr, &data)
}
fn write_beu32(&mut self, addr: Address, value: u32) -> Result<(), Error> {
let data = write_beu32(value);
self.write(addr, &data)
}
}
@ -51,15 +78,16 @@ impl Addressable for MemoryBlock {
self.contents.len()
}
fn read(&mut self, addr: Address, count: usize) -> Vec<u8> {
self.contents[(addr as usize) .. (addr as usize + count)].to_vec()
fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
Ok(self.contents[(addr as usize) .. (addr as usize + count)].to_vec())
}
fn write(&mut self, mut addr: Address, data: &[u8]) {
fn write(&mut self, mut addr: Address, data: &[u8]) -> Result<(), Error> {
for byte in data {
self.contents[addr as usize] = *byte;
addr += 1;
}
Ok(())
}
}
@ -138,71 +166,58 @@ impl AddressSpace {
println!("{}", line);
}
}
}
impl Addressable for AddressSpace {
fn len(&self) -> usize {
let seg = &self.segments[self.segments.len() - 1];
(seg.base as usize) + seg.contents.len()
}
pub fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
let mut seg = self.get_segment_mut(addr)?;
let relative_addr = addr - seg.base;
if relative_addr as usize + count > seg.contents.len() {
Err(Error::new(&format!("Error reading address {:#010x}", addr)))
} else {
Ok(seg.contents.read(relative_addr, count))
seg.contents.read(relative_addr, count)
}
}
pub fn read_u8(&mut self, addr: Address) -> Result<u8, Error> {
Ok(self.read(addr, 1)?[0])
}
pub fn read_beu16(&mut self, addr: Address) -> Result<u16, Error> {
Ok(read_beu16(&self.read(addr, 2)?))
}
pub fn read_beu32(&mut self, addr: Address) -> Result<u32, Error> {
Ok(read_beu32(&self.read(addr, 4)?))
}
pub fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
let seg = self.get_segment_mut(addr)?;
Ok(seg.contents.write(addr - seg.base, data))
}
pub fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> {
let data = [value];
self.write(addr, &data)
}
pub fn write_beu16(&mut self, addr: Address, value: u16) -> Result<(), Error> {
let data = [
(value >> 8) as u8,
value as u8,
];
self.write(addr, &data)
}
pub fn write_beu32(&mut self, addr: Address, value: u32) -> Result<(), Error> {
let data = [
(value >> 24) as u8,
(value >> 16) as u8,
(value >> 8) as u8,
value as u8,
];
self.write(addr, &data)
seg.contents.write(addr - seg.base, data)
}
}
#[inline(always)]
pub fn read_beu16(mut data: &[u8]) -> u16 {
pub fn read_beu16(data: &[u8]) -> u16 {
(data[0] as u16) << 8 |
(data[1] as u16)
}
#[inline(always)]
pub fn read_beu32(mut data: &[u8]) -> u32 {
pub fn read_beu32(data: &[u8]) -> u32 {
(data[0] as u32) << 24 |
(data[1] as u32) << 16 |
(data[2] as u32) << 8 |
(data[3] as u32)
}
#[inline(always)]
pub fn write_beu16(value: u16) -> [u8; 2] {
[
(value >> 8) as u8,
value as u8,
]
}
#[inline(always)]
pub fn write_beu32(value: u32) -> [u8; 4] {
[
(value >> 24) as u8,
(value >> 16) as u8,
(value >> 8) as u8,
value as u8,
]
}