2021-09-28 23:09:38 +00:00
|
|
|
|
|
|
|
use std::fs;
|
|
|
|
use std::slice::Iter;
|
|
|
|
|
|
|
|
use crate::error::Error;
|
|
|
|
|
|
|
|
|
|
|
|
pub type Address = u64;
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
pub trait Addressable {
|
|
|
|
fn len(&self) -> usize;
|
2021-10-01 19:25:23 +00:00
|
|
|
fn read(&mut self, addr: Address, count: usize) -> Vec<u8>;
|
2021-09-28 23:09:38 +00:00
|
|
|
fn write(&mut self, addr: Address, data: &[u8]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
pub struct MemoryBlock {
|
2021-09-28 23:09:38 +00:00
|
|
|
pub contents: Vec<u8>,
|
|
|
|
}
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
impl MemoryBlock {
|
|
|
|
pub fn new(contents: Vec<u8>) -> MemoryBlock {
|
|
|
|
MemoryBlock {
|
|
|
|
contents
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
pub fn load(filename: &str) -> Result<MemoryBlock, Error> {
|
2021-09-28 23:09:38 +00:00
|
|
|
match fs::read(filename) {
|
2021-09-30 06:21:11 +00:00
|
|
|
Ok(contents) => Ok(MemoryBlock::new(contents)),
|
2021-09-28 23:09:38 +00:00
|
|
|
Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))),
|
|
|
|
}
|
|
|
|
}
|
2021-10-03 16:55:20 +00:00
|
|
|
|
|
|
|
pub fn load_at(&mut self, mut addr: Address, filename: &str) -> Result<(), Error> {
|
|
|
|
match fs::read(filename) {
|
|
|
|
Ok(contents) => {
|
|
|
|
for byte in contents {
|
|
|
|
self.contents[addr as usize] = byte;
|
|
|
|
addr += 1;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
},
|
|
|
|
Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))),
|
|
|
|
}
|
|
|
|
}
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
impl Addressable for MemoryBlock {
|
|
|
|
fn len(&self) -> usize {
|
|
|
|
self.contents.len()
|
|
|
|
}
|
|
|
|
|
2021-10-01 19:25:23 +00:00
|
|
|
fn read(&mut self, addr: Address, count: usize) -> Vec<u8> {
|
2021-10-04 04:05:10 +00:00
|
|
|
self.contents[(addr as usize) .. (addr as usize + count)].to_vec()
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
2021-09-30 04:52:38 +00:00
|
|
|
fn write(&mut self, mut addr: Address, data: &[u8]) {
|
2021-09-28 23:09:38 +00:00
|
|
|
for byte in data {
|
2021-09-30 06:21:11 +00:00
|
|
|
self.contents[addr as usize] = *byte;
|
2021-09-30 04:52:38 +00:00
|
|
|
addr += 1;
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-28 23:09:38 +00:00
|
|
|
pub struct AddressSpace {
|
|
|
|
pub segments: Vec<Segment>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AddressSpace {
|
|
|
|
pub fn new() -> AddressSpace {
|
|
|
|
AddressSpace {
|
|
|
|
segments: vec!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
pub fn insert(&mut self, base: Address, contents: Box<dyn Addressable>) {
|
|
|
|
let seg = Segment::new(base, contents);
|
2021-09-28 23:09:38 +00:00
|
|
|
for i in 0..self.segments.len() {
|
|
|
|
if self.segments[i].base > seg.base {
|
|
|
|
self.segments.insert(i, seg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.segments.insert(0, seg);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_segment(&self, addr: Address) -> Result<&Segment, Error> {
|
|
|
|
for i in 0..self.segments.len() {
|
|
|
|
if addr >= self.segments[i].base && addr <= (self.segments[i].base + self.segments[i].contents.len() as Address) {
|
|
|
|
return Ok(&self.segments[i]);
|
|
|
|
}
|
|
|
|
}
|
2021-09-30 04:52:38 +00:00
|
|
|
return Err(Error::new(&format!("No segment found at {:#08x}", addr)));
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_segment_mut(&mut self, addr: Address) -> Result<&mut Segment, Error> {
|
|
|
|
for i in 0..self.segments.len() {
|
|
|
|
if addr >= self.segments[i].base && addr <= (self.segments[i].base + self.segments[i].contents.len() as Address) {
|
|
|
|
return Ok(&mut self.segments[i]);
|
|
|
|
}
|
|
|
|
}
|
2021-09-30 04:52:38 +00:00
|
|
|
return Err(Error::new(&format!("No segment found at {:#08x}", addr)));
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-01 19:25:23 +00:00
|
|
|
pub fn dump_memory(&mut self, mut addr: Address, mut count: Address) {
|
2021-09-30 19:58:11 +00:00
|
|
|
while count > 0 {
|
|
|
|
let mut line = format!("{:#010x}: ", addr);
|
Added MUL, DIV, NEG, DBcc, and Scc instructions, and fixed issue with ADD/SUB flags
With ADDA, SUBA, and ADDQ/SUBQ when the target is an address register, the condition
flags should not be changed, but the code was changing them, which caused problems.
I've fixed it by making the ADD/SUB executions check for an address target and
will not update flags in that case. This should only occur when the actual instruction
was an ADDA or ADDQ with an address register target
2021-10-03 04:59:28 +00:00
|
|
|
|
2021-10-02 00:53:55 +00:00
|
|
|
let to = if count < 16 { count / 2 } else { 8 };
|
|
|
|
for i in 0..to {
|
2021-10-02 05:06:53 +00:00
|
|
|
let word = self.read_beu16(addr);
|
|
|
|
if word.is_err() {
|
|
|
|
println!("{}", line);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
line += &format!("{:#06x} ", word.unwrap());
|
2021-09-30 19:58:11 +00:00
|
|
|
addr += 2;
|
|
|
|
count -= 2;
|
|
|
|
}
|
|
|
|
println!("{}", line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-01 19:25:23 +00:00
|
|
|
pub fn read(&mut self, addr: Address, count: usize) -> Result<Vec<u8>, Error> {
|
|
|
|
let mut seg = self.get_segment_mut(addr)?;
|
2021-10-04 04:05:10 +00:00
|
|
|
let relative_addr = addr - seg.base;
|
2021-10-04 18:13:10 +00:00
|
|
|
if relative_addr as usize + count > seg.contents.len() {
|
2021-10-04 04:05:10 +00:00
|
|
|
Err(Error::new(&format!("Error reading address {:#010x}", addr)))
|
|
|
|
} else {
|
|
|
|
Ok(seg.contents.read(relative_addr, count))
|
|
|
|
}
|
2021-09-30 04:52:38 +00:00
|
|
|
}
|
|
|
|
|
2021-10-01 19:25:23 +00:00
|
|
|
pub fn read_u8(&mut self, addr: Address) -> Result<u8, Error> {
|
2021-10-04 04:05:10 +00:00
|
|
|
Ok(self.read(addr, 1)?[0])
|
2021-09-30 00:11:48 +00:00
|
|
|
}
|
|
|
|
|
2021-10-01 19:25:23 +00:00
|
|
|
pub fn read_beu16(&mut self, addr: Address) -> Result<u16, Error> {
|
2021-10-04 04:05:10 +00:00
|
|
|
Ok(read_beu16(&self.read(addr, 2)?))
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
2021-10-01 19:25:23 +00:00
|
|
|
pub fn read_beu32(&mut self, addr: Address) -> Result<u32, Error> {
|
2021-10-04 04:05:10 +00:00
|
|
|
Ok(read_beu32(&self.read(addr, 4)?))
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
2021-09-30 06:21:11 +00:00
|
|
|
|
2021-10-04 04:05:10 +00:00
|
|
|
pub fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Error> {
|
2021-09-30 00:11:48 +00:00
|
|
|
let seg = self.get_segment_mut(addr)?;
|
2021-10-04 04:05:10 +00:00
|
|
|
Ok(seg.contents.write(addr - seg.base, data))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write_u8(&mut self, addr: Address, value: u8) -> Result<(), Error> {
|
2021-09-30 00:11:48 +00:00
|
|
|
let data = [value];
|
2021-10-04 04:05:10 +00:00
|
|
|
self.write(addr, &data)
|
2021-09-30 00:11:48 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 23:09:38 +00:00
|
|
|
pub fn write_beu16(&mut self, addr: Address, value: u16) -> Result<(), Error> {
|
|
|
|
let data = [
|
|
|
|
(value >> 8) as u8,
|
|
|
|
value as u8,
|
|
|
|
];
|
2021-10-04 04:05:10 +00:00
|
|
|
self.write(addr, &data)
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
];
|
2021-10-04 04:05:10 +00:00
|
|
|
self.write(addr, &data)
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-04 04:05:10 +00:00
|
|
|
#[inline(always)]
|
|
|
|
pub fn read_beu16(mut data: &[u8]) -> u16 {
|
|
|
|
(data[0] as u16) << 8 |
|
|
|
|
(data[1] as u16)
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|
2021-10-04 04:05:10 +00:00
|
|
|
#[inline(always)]
|
|
|
|
pub fn read_beu32(mut data: &[u8]) -> u32 {
|
|
|
|
(data[0] as u32) << 24 |
|
|
|
|
(data[1] as u32) << 16 |
|
|
|
|
(data[2] as u32) << 8 |
|
|
|
|
(data[3] as u32)
|
2021-09-28 23:09:38 +00:00
|
|
|
}
|
|
|
|
|