Added serial device

This commit is contained in:
transistor 2021-09-29 23:21:11 -07:00
parent 92342c23ed
commit b7148d3b06
5 changed files with 120 additions and 28 deletions

View File

@ -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)?;

63
src/devices/mc68681.rs Normal file
View File

@ -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<u8> {
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); },
}
}
}

3
src/devices/mod.rs Normal file
View File

@ -0,0 +1,3 @@
pub mod mc68681;

View File

@ -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() {

View File

@ -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<u8>;
fn write(&mut self, addr: Address, data: &[u8]);
}
pub struct Segment {
pub base: Address,
pub struct MemoryBlock {
pub contents: Vec<u8>,
}
impl Segment {
pub fn new(base: Address, contents: Vec<u8>) -> Segment {
Segment {
base,
contents,
impl MemoryBlock {
pub fn new(contents: Vec<u8>) -> MemoryBlock {
MemoryBlock {
contents
}
}
pub fn load(base: Address, filename: &str) -> Result<Segment, Error> {
pub fn load(filename: &str) -> Result<MemoryBlock, Error> {
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<u8> {
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<dyn Addressable>,
}
impl Segment {
pub fn new(base: Address, contents: Box<dyn Addressable>) -> Segment {
Segment {
base,
contents,
}
}
}
pub struct AddressSpace {
pub segments: Vec<Segment>,
}
@ -60,7 +77,8 @@ impl AddressSpace {
}
}
pub fn insert(&mut self, seg: Segment) {
pub fn insert(&mut self, base: Address, contents: Box<dyn Addressable>) {
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<Iter<u8>, 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<u8, Error> {
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<u16, Error> {
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<u32, Error> {
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))
}
}