Bring up to date with Rust 1.51.0
This commit is contained in:
parent
f67bb140c8
commit
bdd3f2c992
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "dmd_core"
|
||||
description = "AT&T / Teletype DMD 5620 Terminal Emulator - Core Library"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
authors = ["Seth Morabito <web@loomcom.com>"]
|
||||
homepage = "https://github.com/sethm/dmd_core"
|
||||
repository = "https://github.com/sethm/dmd_core"
|
||||
|
@ -11,8 +11,8 @@ license = "MIT"
|
|||
categories = ["simulation"]
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "^1.4.0"
|
||||
libc = "^0.2.66"
|
||||
lazy_static = "~1.4"
|
||||
libc = "~0.2"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
|
21
src/bus.rs
21
src/bus.rs
|
@ -1,8 +1,8 @@
|
|||
#![allow(clippy::unreadable_literal)]
|
||||
|
||||
use crate::duart::Duart;
|
||||
use crate::err::BusError;
|
||||
use crate::mem::Mem;
|
||||
use crate::duart::Duart;
|
||||
use crate::mouse::Mouse;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Range;
|
||||
|
@ -23,13 +23,12 @@ pub enum AccessCode {
|
|||
OperandFetch,
|
||||
Write,
|
||||
IrqAck,
|
||||
IFAfterPCDisc,
|
||||
IfAfterPcDisc,
|
||||
InstrPrefetch,
|
||||
InstrFetch,
|
||||
NoOp,
|
||||
}
|
||||
|
||||
|
||||
/// A virtual device on the bus.
|
||||
pub trait Device: Send + Sync + Debug {
|
||||
fn address_range(&self) -> &Range<usize>;
|
||||
|
@ -60,8 +59,8 @@ pub struct Bus {
|
|||
rom: Mem,
|
||||
duart: Duart,
|
||||
mouse: Mouse,
|
||||
vid: Mem, // TODO: Figure out what device this really is
|
||||
bbram: Mem, // TODO: change to BBRAM when implemented
|
||||
vid: Mem, // TODO: Figure out what device this really is
|
||||
bbram: Mem, // TODO: change to BBRAM when implemented
|
||||
ram: Mem,
|
||||
}
|
||||
|
||||
|
@ -82,23 +81,23 @@ impl Bus {
|
|||
return Ok(&mut self.rom);
|
||||
}
|
||||
|
||||
if address >= 0x200000 && address < 0x200040 {
|
||||
if (0x200000..0x200040).contains(&address) {
|
||||
return Ok(&mut self.duart);
|
||||
}
|
||||
|
||||
if address >= 0x400000 && address < 0x400004 {
|
||||
if (0x400000..0x400004).contains(&address) {
|
||||
return Ok(&mut self.mouse);
|
||||
}
|
||||
|
||||
if address >= 0x500000 && address < 0x500002 {
|
||||
if (0x500000..0x500002).contains(&address) {
|
||||
return Ok(&mut self.vid);
|
||||
}
|
||||
|
||||
if address >= 0x600000 && address < 0x602000 {
|
||||
if (0x600000..0x602000).contains(&address) {
|
||||
return Ok(&mut self.bbram);
|
||||
}
|
||||
|
||||
if address >= 0x700000 && address < 0x800000 {
|
||||
if (0x700000..0x800000).contains(&address) {
|
||||
return Ok(&mut self.ram);
|
||||
}
|
||||
|
||||
|
@ -214,7 +213,7 @@ impl Bus {
|
|||
}
|
||||
|
||||
pub fn set_nvram(&mut self, nvram: &[u8]) {
|
||||
for (i, b) in nvram.into_iter().enumerate() {
|
||||
for (i, b) in nvram.iter().enumerate() {
|
||||
self.bbram[i] = *b;
|
||||
}
|
||||
}
|
||||
|
|
161
src/cpu.rs
161
src/cpu.rs
|
@ -39,21 +39,15 @@ const R_ISP: usize = 14;
|
|||
const R_PC: usize = 15;
|
||||
|
||||
const IPL_TABLE: [u32; 64] = [
|
||||
0, 14, 14, 14, 14, 14, 14, 14,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15,
|
||||
0, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
];
|
||||
|
||||
const WE32100_VERSION: u32 = 0x1a;
|
||||
const HALFWORD_MNEMONIC_COUNT: usize = 11;
|
||||
|
||||
pub enum ExceptionType {
|
||||
ExternalMemory
|
||||
ExternalMemory,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
|
@ -67,8 +61,8 @@ pub enum AddrMode {
|
|||
HalfwordDisplacementDeferred,
|
||||
WordDisplacement,
|
||||
WordDisplacementDeferred,
|
||||
APShortOffset,
|
||||
FPShortOffset,
|
||||
ApShortOffset,
|
||||
FpShortOffset,
|
||||
ByteImmediate,
|
||||
HalfwordImmediate,
|
||||
WordImmediate,
|
||||
|
@ -460,10 +454,9 @@ static BYTE_MNEMONICS: [Option<Mnemonic>; 256] = [
|
|||
Some(mn!(0xFC, Data::Word, "SUBW3", [OpType::Src, OpType::Src, OpType::Dest, OpType::None])),
|
||||
None,
|
||||
Some(mn!(0xFE, Data::Half, "SUBH3", [OpType::Src, OpType::Src, OpType::Dest, OpType::None])),
|
||||
Some(mn!(0xFF, Data::Byte, "SUBB3", [OpType::Src, OpType::Src, OpType::Dest, OpType::None]))
|
||||
Some(mn!(0xFF, Data::Byte, "SUBB3", [OpType::Src, OpType::Src, OpType::Dest, OpType::None])),
|
||||
];
|
||||
|
||||
|
||||
static HALFWORD_MNEMONICS: [Option<Mnemonic>; HALFWORD_MNEMONIC_COUNT] = [
|
||||
Some(mn!(0x3009, Data::None, "MVERNO", [OpType::None, OpType::None, OpType::None, OpType::None])),
|
||||
Some(mn!(0x300d, Data::None, "ENBVJMP", [OpType::None, OpType::None, OpType::None, OpType::None])),
|
||||
|
@ -475,7 +468,7 @@ static HALFWORD_MNEMONICS: [Option<Mnemonic>; HALFWORD_MNEMONIC_COUNT] = [
|
|||
Some(mn!(0x3045, Data::None, "RETG", [OpType::None, OpType::None, OpType::None, OpType::None])),
|
||||
Some(mn!(0x3061, Data::None, "GATE", [OpType::None, OpType::None, OpType::None, OpType::None])),
|
||||
Some(mn!(0x30ac, Data::None, "CALLPS", [OpType::None, OpType::None, OpType::None, OpType::None])),
|
||||
Some(mn!(0x30c8, Data::None, "RETPS", [OpType::None, OpType::None, OpType::None, OpType::None]))
|
||||
Some(mn!(0x30c8, Data::None, "RETPS", [OpType::None, OpType::None, OpType::None, OpType::None])),
|
||||
];
|
||||
|
||||
static NULL_MNEMONIC: Option<Mnemonic> = None;
|
||||
|
@ -514,8 +507,8 @@ impl Cpu {
|
|||
Operand::new(0, AddrMode::None, Data::None, None, None, 0),
|
||||
Operand::new(0, AddrMode::None, Data::None, None, None, 0),
|
||||
Operand::new(0, AddrMode::None, Data::None, None, None, 0),
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,7 +547,6 @@ impl Cpu {
|
|||
|
||||
/// Compute the effective address for an Operand.
|
||||
fn effective_address(&mut self, bus: &mut Bus, index: usize) -> Result<u32, CpuError> {
|
||||
|
||||
let embedded = self.ir.operands[index].embedded;
|
||||
let mode = self.ir.operands[index].mode;
|
||||
let register = self.ir.operands[index].register;
|
||||
|
@ -569,8 +561,8 @@ impl Cpu {
|
|||
}
|
||||
AddrMode::Absolute => embedded,
|
||||
AddrMode::AbsoluteDeferred => bus.read_word(embedded as usize, AccessCode::AddressFetch)?,
|
||||
AddrMode::FPShortOffset => add_offset(self.r[R_FP], sign_extend_byte(embedded as u8)),
|
||||
AddrMode::APShortOffset => add_offset(self.r[R_AP], sign_extend_byte(embedded as u8)),
|
||||
AddrMode::FpShortOffset => add_offset(self.r[R_FP], sign_extend_byte(embedded as u8)),
|
||||
AddrMode::ApShortOffset => add_offset(self.r[R_AP], sign_extend_byte(embedded as u8)),
|
||||
AddrMode::WordDisplacement => {
|
||||
let r = match register {
|
||||
Some(v) => v,
|
||||
|
@ -623,7 +615,6 @@ impl Cpu {
|
|||
|
||||
/// Read the value pointed at by an Operand
|
||||
pub fn read_op(&mut self, bus: &mut Bus, index: usize) -> Result<u32, CpuError> {
|
||||
|
||||
let mut op = self.ir.operands[index];
|
||||
|
||||
let val: u32 = match op.mode {
|
||||
|
@ -861,7 +852,7 @@ impl Cpu {
|
|||
self.context_switch_3(bus).unwrap();
|
||||
}
|
||||
|
||||
#[allow(clippy::cyclomatic_complexity)]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn dispatch(&mut self, bus: &mut Bus) -> Result<i32, CpuError> {
|
||||
self.steps += 1;
|
||||
|
||||
|
@ -1561,8 +1552,7 @@ impl Cpu {
|
|||
|
||||
// TODO: Check for illegal level change
|
||||
|
||||
new_psw &= !(F_IPL | F_CFD | F_QIE | F_CD |
|
||||
F_R | F_ISC | F_TM | F_ET);
|
||||
new_psw &= !(F_IPL | F_CFD | F_QIE | F_CD | F_R | F_ISC | F_TM | F_ET);
|
||||
|
||||
new_psw |= self.r[R_PSW] & F_IPL;
|
||||
new_psw |= self.r[R_PSW] & F_CFD;
|
||||
|
@ -1642,36 +1632,34 @@ impl Cpu {
|
|||
|
||||
pc_increment = 0;
|
||||
}
|
||||
RETPS => {
|
||||
match self.priv_level() {
|
||||
CpuLevel::Kernel => {
|
||||
let new_pcbp = self.irq_pop(bus)?;
|
||||
let new_psw = bus.read_word(new_pcbp as usize, AccessCode::AddressFetch)?;
|
||||
self.r[R_PSW] &= !F_R;
|
||||
self.r[R_PSW] |= new_psw & F_R;
|
||||
RETPS => match self.priv_level() {
|
||||
CpuLevel::Kernel => {
|
||||
let new_pcbp = self.irq_pop(bus)?;
|
||||
let new_psw = bus.read_word(new_pcbp as usize, AccessCode::AddressFetch)?;
|
||||
self.r[R_PSW] &= !F_R;
|
||||
self.r[R_PSW] |= new_psw & F_R;
|
||||
|
||||
self.context_switch_2(bus, new_pcbp)?;
|
||||
self.context_switch_3(bus)?;
|
||||
self.context_switch_2(bus, new_pcbp)?;
|
||||
self.context_switch_3(bus)?;
|
||||
|
||||
if self.r[R_PSW] & F_R != 0 {
|
||||
self.r[R_FP] = bus.read_word((new_pcbp + 24) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[0] = bus.read_word((new_pcbp + 28) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[1] = bus.read_word((new_pcbp + 32) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[2] = bus.read_word((new_pcbp + 36) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[3] = bus.read_word((new_pcbp + 40) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[4] = bus.read_word((new_pcbp + 44) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[5] = bus.read_word((new_pcbp + 48) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[6] = bus.read_word((new_pcbp + 52) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[7] = bus.read_word((new_pcbp + 56) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[8] = bus.read_word((new_pcbp + 60) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[R_AP] = bus.read_word((new_pcbp + 20) as usize, AccessCode::AddressFetch)?;
|
||||
}
|
||||
if self.r[R_PSW] & F_R != 0 {
|
||||
self.r[R_FP] = bus.read_word((new_pcbp + 24) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[0] = bus.read_word((new_pcbp + 28) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[1] = bus.read_word((new_pcbp + 32) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[2] = bus.read_word((new_pcbp + 36) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[3] = bus.read_word((new_pcbp + 40) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[4] = bus.read_word((new_pcbp + 44) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[5] = bus.read_word((new_pcbp + 48) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[6] = bus.read_word((new_pcbp + 52) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[7] = bus.read_word((new_pcbp + 56) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[8] = bus.read_word((new_pcbp + 60) as usize, AccessCode::AddressFetch)?;
|
||||
self.r[R_AP] = bus.read_word((new_pcbp + 20) as usize, AccessCode::AddressFetch)?;
|
||||
}
|
||||
|
||||
pc_increment = 0;
|
||||
},
|
||||
_ => return Err(CpuError::Exception(CpuException::PrivilegedOpcode)),
|
||||
pc_increment = 0;
|
||||
}
|
||||
}
|
||||
_ => return Err(CpuError::Exception(CpuException::PrivilegedOpcode)),
|
||||
},
|
||||
SAVE => {
|
||||
bus.write_word(self.r[R_SP] as usize, self.r[R_FP])?;
|
||||
|
||||
|
@ -1779,7 +1767,7 @@ impl Cpu {
|
|||
|
||||
fn on_exception(&mut self, bus: &mut Bus, exc: &ExceptionType) -> Result<(), CpuError> {
|
||||
let (et, isc) = match exc {
|
||||
ExceptionType::ExternalMemory => (3, 5)
|
||||
ExceptionType::ExternalMemory => (3, 5),
|
||||
};
|
||||
|
||||
// TODO: Don't trap integer overflow
|
||||
|
@ -1855,7 +1843,7 @@ impl Cpu {
|
|||
data_type: Data,
|
||||
expanded_type: Option<Data>,
|
||||
register: Option<usize>,
|
||||
embedded: u32
|
||||
embedded: u32,
|
||||
) {
|
||||
self.ir.operands[index].size = size;
|
||||
self.ir.operands[index].mode = mode;
|
||||
|
@ -1939,7 +1927,7 @@ impl Cpu {
|
|||
}
|
||||
11 => {
|
||||
// Illegal
|
||||
return Err(CpuError::Exception(CpuException::IllegalOpcode))
|
||||
return Err(CpuError::Exception(CpuException::IllegalOpcode));
|
||||
}
|
||||
_ => {
|
||||
// Register Deferred Mode
|
||||
|
@ -1956,7 +1944,7 @@ impl Cpu {
|
|||
}
|
||||
_ => {
|
||||
// FP Short Offset
|
||||
self.set_operand(index, dsize, AddrMode::FPShortOffset, dtype, etype, Some(R_FP), u32::from(r));
|
||||
self.set_operand(index, dsize, AddrMode::FpShortOffset, dtype, etype, Some(R_FP), u32::from(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1969,7 +1957,7 @@ impl Cpu {
|
|||
}
|
||||
_ => {
|
||||
// AP Short Offset
|
||||
self.set_operand(index, dsize, AddrMode::APShortOffset, dtype, etype, Some(R_AP), u32::from(r));
|
||||
self.set_operand(index, dsize, AddrMode::ApShortOffset, dtype, etype, Some(R_AP), u32::from(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1989,7 +1977,15 @@ impl Cpu {
|
|||
_ => {
|
||||
// Word Displacement Deferred
|
||||
let disp = bus.read_op_word(addr + 1)?;
|
||||
self.set_operand(index, dsize + 4, AddrMode::WordDisplacementDeferred, dtype, etype, Some(r as usize), disp);
|
||||
self.set_operand(
|
||||
index,
|
||||
dsize + 4,
|
||||
AddrMode::WordDisplacementDeferred,
|
||||
dtype,
|
||||
etype,
|
||||
Some(r as usize),
|
||||
disp,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1999,7 +1995,15 @@ impl Cpu {
|
|||
_ => {
|
||||
// Halfword Displacement
|
||||
let disp = bus.read_op_half(addr + 1)?;
|
||||
self.set_operand(index, dsize + 2, AddrMode::HalfwordDisplacement, dtype, etype, Some(r as usize), u32::from(disp));
|
||||
self.set_operand(
|
||||
index,
|
||||
dsize + 2,
|
||||
AddrMode::HalfwordDisplacement,
|
||||
dtype,
|
||||
etype,
|
||||
Some(r as usize),
|
||||
u32::from(disp),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2027,7 +2031,15 @@ impl Cpu {
|
|||
_ => {
|
||||
// Byte Displacement
|
||||
let disp = bus.read_byte(addr + 1, AccessCode::OperandFetch)?;
|
||||
self.set_operand(index, dsize + 1, AddrMode::ByteDisplacement, dtype, etype, Some(r as usize), u32::from(disp));
|
||||
self.set_operand(
|
||||
index,
|
||||
dsize + 1,
|
||||
AddrMode::ByteDisplacement,
|
||||
dtype,
|
||||
etype,
|
||||
Some(r as usize),
|
||||
u32::from(disp),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2037,7 +2049,15 @@ impl Cpu {
|
|||
_ => {
|
||||
// Byte Displacement Deferred
|
||||
let disp = bus.read_byte(addr + 1, AccessCode::OperandFetch)?;
|
||||
self.set_operand(index, dsize + 1, AddrMode::ByteDisplacementDeferred, dtype, etype, Some(r as usize), u32::from(disp));
|
||||
self.set_operand(
|
||||
index,
|
||||
dsize + 1,
|
||||
AddrMode::ByteDisplacementDeferred,
|
||||
dtype,
|
||||
etype,
|
||||
Some(r as usize),
|
||||
u32::from(disp),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2052,13 +2072,17 @@ impl Cpu {
|
|||
let w = bus.read_op_word(addr + 1)?;
|
||||
self.set_operand(index, dsize + 4, AddrMode::AbsoluteDeferred, dtype, etype, None, w);
|
||||
}
|
||||
_ => { return Err(CpuError::Exception(CpuException::IllegalOpcode)); }
|
||||
_ => {
|
||||
return Err(CpuError::Exception(CpuException::IllegalOpcode));
|
||||
}
|
||||
},
|
||||
15 => {
|
||||
// Negative Literal
|
||||
self.set_operand(index, 1, AddrMode::NegativeLiteral, dtype, etype, None, u32::from(descriptor_byte));
|
||||
},
|
||||
_ => { return Err(CpuError::Exception(CpuException::IllegalOpcode)); }
|
||||
}
|
||||
_ => {
|
||||
return Err(CpuError::Exception(CpuException::IllegalOpcode));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
@ -2077,7 +2101,7 @@ impl Cpu {
|
|||
match ot {
|
||||
OpType::Lit => self.decode_literal_operand(bus, index, mn, addr),
|
||||
OpType::Src | OpType::Dest => self.decode_descriptor_operand(bus, index, mn.dtype, etype, addr, false),
|
||||
OpType::None => Ok(())
|
||||
OpType::None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2138,7 +2162,7 @@ impl Cpu {
|
|||
self.ir.data_type = mn.dtype;
|
||||
self.ir.bytes = total_bytes as u8;
|
||||
}
|
||||
None => return Err(CpuError::Exception(CpuException::IllegalOpcode))
|
||||
None => return Err(CpuError::Exception(CpuException::IllegalOpcode)),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -2249,7 +2273,7 @@ impl Cpu {
|
|||
0 => CpuLevel::Kernel,
|
||||
1 => CpuLevel::Executive,
|
||||
2 => CpuLevel::Supervisor,
|
||||
3 | _ => CpuLevel::User,
|
||||
_ => CpuLevel::User,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2452,7 +2476,7 @@ mod tests {
|
|||
|
||||
do_with_program(&program, |cpu, mut bus| {
|
||||
cpu.decode_descriptor_operand(&mut bus, 0, Data::Word, None, BASE + 1, false).unwrap();
|
||||
assert_eq!(cpu.ir.operands[0], Operand::new(1, AddrMode::FPShortOffset, Data::Word, None, Some(R_FP), 12));
|
||||
assert_eq!(cpu.ir.operands[0], Operand::new(1, AddrMode::FpShortOffset, Data::Word, None, Some(R_FP), 12));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2482,7 +2506,7 @@ mod tests {
|
|||
|
||||
do_with_program(&program, |cpu, mut bus| {
|
||||
cpu.decode_descriptor_operand(&mut bus, 0, Data::Word, None, BASE + 1, false).unwrap();
|
||||
assert_eq!(cpu.ir.operands[0], Operand::new(1, AddrMode::APShortOffset, Data::Word, None, Some(R_AP), 4));
|
||||
assert_eq!(cpu.ir.operands[0], Operand::new(1, AddrMode::ApShortOffset, Data::Word, None, Some(R_AP), 4));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2522,7 +2546,10 @@ mod tests {
|
|||
|
||||
do_with_program(&program, |cpu, mut bus| {
|
||||
cpu.decode_descriptor_operand(&mut bus, 0, Data::Byte, None, BASE + 1, false).unwrap();
|
||||
assert_eq!(cpu.ir.operands[0], Operand::new(3, AddrMode::HalfwordDisplacementDeferred, Data::Byte, None, Some(2), 0x4050,));
|
||||
assert_eq!(
|
||||
cpu.ir.operands[0],
|
||||
Operand::new(3, AddrMode::HalfwordDisplacementDeferred, Data::Byte, None, Some(2), 0x4050,)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
28
src/err.rs
28
src/err.rs
|
@ -21,15 +21,6 @@ impl fmt::Display for CpuException {
|
|||
}
|
||||
|
||||
impl Error for CpuException {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
CpuException::IllegalOpcode => "illegal opcode",
|
||||
CpuException::InvalidDescriptor => "invalid descriptor",
|
||||
CpuException::PrivilegedOpcode => "privileged opcode",
|
||||
CpuException::IntegerZeroDivide => "integer zero divide",
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&dyn Error> {
|
||||
match *self {
|
||||
CpuException::IllegalOpcode => None,
|
||||
|
@ -66,18 +57,6 @@ impl fmt::Display for BusError {
|
|||
}
|
||||
|
||||
impl Error for BusError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
BusError::Init => "initialize",
|
||||
BusError::Read(_) => "read",
|
||||
BusError::Write(_) => "store",
|
||||
BusError::NoDevice(_) => "no device",
|
||||
BusError::Range => "out of range",
|
||||
BusError::Permission => "invalid permission",
|
||||
BusError::Alignment => "alignment",
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&dyn Error> {
|
||||
match *self {
|
||||
BusError::Init => None,
|
||||
|
@ -107,13 +86,6 @@ impl fmt::Display for CpuError {
|
|||
}
|
||||
|
||||
impl Error for CpuError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
CpuError::Exception(ref e) => e.description(),
|
||||
CpuError::Bus(ref e) => e.description(),
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&dyn Error> {
|
||||
match *self {
|
||||
CpuError::Exception(ref e) => Some(e),
|
||||
|
|
Loading…
Reference in New Issue