mirror of
https://github.com/transistorfet/moa.git
synced 2024-11-24 23:32:46 +00:00
Added serial device
This commit is contained in:
parent
92342c23ed
commit
b7148d3b06
@ -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
63
src/devices/mc68681.rs
Normal 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
3
src/devices/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
pub mod mc68681;
|
||||
|
16
src/main.rs
16
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() {
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user