diff --git a/src/cpus/m68k/execute.rs b/src/cpus/m68k/execute.rs index 385ff82..5e57006 100644 --- a/src/cpus/m68k/execute.rs +++ b/src/cpus/m68k/execute.rs @@ -135,6 +135,11 @@ impl MC68010 { ).collect(); debug!("{:#010x}: {}\n\t{:?}\n", current_ins_addr, ins_data?, ins); + // Single Step + self.dump_state(); + let mut buffer = String::new(); + std::io::stdin().read_line(&mut buffer).unwrap(); + match ins { Instruction::ADD(src, dest, size) => { let value = self.get_target_value(space, src, size)?; diff --git a/src/devices/mc68681.rs b/src/devices/mc68681.rs new file mode 100644 index 0000000..6594d4d --- /dev/null +++ b/src/devices/mc68681.rs @@ -0,0 +1,63 @@ + +use std::slice::Iter; + +use crate::memory::{Address, Addressable}; + + +const REG_MR1A_MR2A: Address = 0x01; +const REG_SRA_RD: Address = 0x03; +const REG_CSRA_WR: Address = 0x03; +const REG_CRA_WR: Address = 0x05; +const REG_TBA_WR: Address = 0x07; +const REG_RBA_RD: Address = 0x07; +const REG_ACR_WR: Address = 0x09; + +const REG_CTUR_WR: Address = 0x0D; +const REG_CTLR_WR: Address = 0x0F; +const REG_START_RD: Address = 0x1D; +const REG_STOP_RD: Address = 0x1F; + +const REG_IPCR_RD: Address = 0x09; +const REG_OPCR_WR: Address = 0x1B; +const REG_INPUT_RD: Address = 0x1B; +const REG_OUT_SET: Address = 0x1D; +const REG_OUT_RESET: Address = 0x1F; + +const REG_ISR_RD: Address = 0x0B; +const REG_IMR_WR: Address = 0x0B; +const REG_IVR_WR: Address = 0x19; + +const DEV_NAME: &'static str = "mc68681"; + +pub struct MC68681 { + pub input: [u8; 1], +} + +impl MC68681 { + pub fn new() -> Self { + MC68681 { + input: [0], + } + } +} + +impl Addressable for MC68681 { + fn len(&self) -> usize { + 0x30 + } + + fn read(&self, addr: Address) -> Iter { + match addr { + REG_TBA_WR => self.input.iter(), + _ => { println!("{}: reading from {:0x}", DEV_NAME, addr); self.input.iter() }, + } + } + + fn write(&mut self, mut addr: Address, data: &[u8]) { + match addr { + REG_TBA_WR => { println!(">>> {}", data[0]); }, + _ => { println!("{}: writing {:0x} to {:0x}", DEV_NAME, data[0], addr); }, + } + } +} + diff --git a/src/devices/mod.rs b/src/devices/mod.rs new file mode 100644 index 0000000..a6376a4 --- /dev/null +++ b/src/devices/mod.rs @@ -0,0 +1,3 @@ + +pub mod mc68681; + diff --git a/src/main.rs b/src/main.rs index f195d18..93c940d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,23 +3,25 @@ mod error; mod memory; mod cpus; +mod devices; -use crate::memory::{AddressSpace, Segment}; +use crate::memory::{AddressSpace, MemoryBlock}; use crate::cpus::m68k::MC68010; +use crate::devices::mc68681::MC68681; fn main() { let mut space = AddressSpace::new(); - let monitor = Segment::load(0x00000000, "monitor.bin").unwrap(); + let monitor = MemoryBlock::load("monitor.bin").unwrap(); for byte in monitor.contents.iter() { print!("{:02x} ", byte); } - space.insert(monitor); + space.insert(0x00000000, Box::new(monitor)); - let ram = Segment::new(0x00100000, vec![0; 0x00100000]); - space.insert(ram); + let ram = MemoryBlock::new(vec![0; 0x00100000]); + space.insert(0x00100000, Box::new(ram)); - let serial = Segment::new(0x00700000, vec![0; 0x30]); - space.insert(serial); + let serial = MC68681::new(); + space.insert(0x00700000, Box::new(serial)); let mut cpu = MC68010::new(); while cpu.is_running() { diff --git a/src/memory.rs b/src/memory.rs index 258e450..1b05d41 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -7,41 +7,44 @@ use crate::error::Error; pub type Address = u64; -trait Addressable { +pub trait Addressable { + fn len(&self) -> usize; fn read(&self, addr: Address) -> Iter; fn write(&mut self, addr: Address, data: &[u8]); } -pub struct Segment { - pub base: Address, +pub struct MemoryBlock { pub contents: Vec, } -impl Segment { - pub fn new(base: Address, contents: Vec) -> Segment { - Segment { - base, - contents, +impl MemoryBlock { + pub fn new(contents: Vec) -> MemoryBlock { + MemoryBlock { + contents } } - pub fn load(base: Address, filename: &str) -> Result { + pub fn load(filename: &str) -> Result { match fs::read(filename) { - Ok(contents) => Ok(Segment::new(base, contents)), + Ok(contents) => Ok(MemoryBlock::new(contents)), Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))), } } } -impl Addressable for Segment { +impl Addressable for MemoryBlock { + fn len(&self) -> usize { + self.contents.len() + } + fn read(&self, addr: Address) -> Iter { - self.contents[(addr - self.base) as usize .. ].iter() + self.contents[(addr) as usize .. ].iter() } fn write(&mut self, mut addr: Address, data: &[u8]) { for byte in data { - self.contents[(addr - self.base) as usize] = *byte; + self.contents[addr as usize] = *byte; addr += 1; } } @@ -49,6 +52,20 @@ impl Addressable for Segment { +pub struct Segment { + pub base: Address, + pub contents: Box, +} + +impl Segment { + pub fn new(base: Address, contents: Box) -> Segment { + Segment { + base, + contents, + } + } +} + pub struct AddressSpace { pub segments: Vec, } @@ -60,7 +77,8 @@ impl AddressSpace { } } - pub fn insert(&mut self, seg: Segment) { + pub fn insert(&mut self, base: Address, contents: Box) { + let seg = Segment::new(base, contents); for i in 0..self.segments.len() { if self.segments[i].base > seg.base { self.segments.insert(i, seg); @@ -91,28 +109,29 @@ impl AddressSpace { pub fn read(&self, addr: Address) -> Result, Error> { let seg = self.get_segment(addr)?; - Ok(seg.contents[(addr - seg.base) as usize .. ].iter()) + Ok(seg.contents.read(addr - seg.base)) } pub fn read_u8(&self, addr: Address) -> Result { let seg = self.get_segment(addr)?; - Ok(*seg.read(addr).next().unwrap()) + Ok(*seg.contents.read(addr - seg.base).next().unwrap()) } pub fn read_beu16(&self, addr: Address) -> Result { let seg = self.get_segment(addr)?; - Ok(read_beu16(seg.read(addr))) + Ok(read_beu16(seg.contents.read(addr - seg.base))) } pub fn read_beu32(&self, addr: Address) -> Result { let seg = self.get_segment(addr)?; - Ok(read_beu32(seg.read(addr))) + Ok(read_beu32(seg.contents.read(addr - seg.base))) } + pub fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> { let seg = self.get_segment_mut(addr)?; let data = [value]; - Ok(seg.write(addr, &data)) + Ok(seg.contents.write(addr - seg.base, &data)) } pub fn write_beu16(&mut self, addr: Address, value: u16) -> Result<(), Error> { @@ -121,7 +140,7 @@ impl AddressSpace { (value >> 8) as u8, value as u8, ]; - Ok(seg.write(addr, &data)) + Ok(seg.contents.write(addr - seg.base, &data)) } pub fn write_beu32(&mut self, addr: Address, value: u32) -> Result<(), Error> { @@ -132,7 +151,7 @@ impl AddressSpace { (value >> 8) as u8, value as u8, ]; - Ok(seg.write(addr, &data)) + Ok(seg.contents.write(addr - seg.base, &data)) } }