mirror of
https://github.com/transistorfet/moa.git
synced 2024-06-25 18:29:33 +00:00
Refactored address space again
This commit is contained in:
parent
f2a23a21cb
commit
59019d9c8e
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(())
|
||||
},
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
109
src/memory.rs
109
src/memory.rs
|
@ -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,
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user