Invalid opcode error handle

This commit is contained in:
2022-04-28 18:20:44 -05:00
parent fc289a670b
commit 02c75c3cae
2 changed files with 29 additions and 10 deletions
+9 -10
View File
@@ -11,7 +11,7 @@ pub struct CPU {
pc: Word, // program counter, address of the low byte of the instruction pc: Word, // program counter, address of the low byte of the instruction
dp: Word, // data pointer, address of the low byte of one cell above the data stack dp: Word, // data pointer, address of the low byte of one cell above the data stack
sp: Word, // stack pointer, address of the low byte of the return stack sp: Word, // stack pointer, address of the low byte of the return stack
iv: [Word; 256], // interrupt vectors iv: [Word; 16], // interrupt vectors
int_enabled: bool, // interrupt enable bit int_enabled: bool, // interrupt enable bit
halted: bool, // Whether the CPU is halted halted: bool, // Whether the CPU is halted
sp_top: Word, // The last value given for the sp, or 0x400 sp_top: Word, // The last value given for the sp, or 0x400
@@ -31,6 +31,7 @@ enum ExecutionError {
DataUnderflow, DataUnderflow,
StackUnderflow, StackUnderflow,
Overflow, Overflow,
InvalidOpcode,
} }
impl PeekPoke for CPU { impl PeekPoke for CPU {
@@ -55,7 +56,7 @@ impl CPU {
pc: 1024.into(), pc: 1024.into(),
dp: 256.into(), dp: 256.into(),
sp: 1024.into(), sp: 1024.into(),
iv: [1024.into(); 256], iv: [1024.into(); 16],
int_enabled: false, int_enabled: false,
halted: true, halted: true,
sp_top: 0x400.into(), sp_top: 0x400.into(),
@@ -67,7 +68,7 @@ impl CPU {
self.pc = 1024.into(); self.pc = 1024.into();
self.dp = 256.into(); self.dp = 256.into();
self.sp = 1024.into(); self.sp = 1024.into();
self.iv = [1024.into(); 256]; self.iv = [1024.into(); 16];
self.int_enabled = false; self.int_enabled = false;
self.halted = true; self.halted = true;
self.sp_top = 0x400.into(); self.sp_top = 0x400.into();
@@ -194,7 +195,7 @@ impl CPU {
} }
} }
Opcode::Setiv => { Opcode::Setiv => {
self.iv[u8::from(x) as usize] = y; self.iv[usize::from(x % 16)] = y;
} }
_ => unreachable!(), _ => unreachable!(),
} }
@@ -354,6 +355,7 @@ impl CPU {
ExecutionError::DataUnderflow => 1, ExecutionError::DataUnderflow => 1,
ExecutionError::StackUnderflow => 2, ExecutionError::StackUnderflow => 2,
ExecutionError::Overflow => 3, ExecutionError::Overflow => 3,
ExecutionError::InvalidOpcode => 4,
}; };
self.int_enabled = false; self.int_enabled = false;
self.push_call(self.pc); self.push_call(self.pc);
@@ -374,10 +376,7 @@ impl CPU {
} }
} }
Err(invalid_opcode) => { Err(_) => self.pc = self.handle_error(ExecutionError::InvalidOpcode),
self.halted = true;
println!("Error: {}", invalid_opcode)
}
} }
} }
@@ -398,7 +397,7 @@ impl CPU {
pub fn get_stack(&self) -> Vec<Word> { pub fn get_stack(&self) -> Vec<Word> {
let mut v = Vec::new(); let mut v = Vec::new();
let mut curr = Word::from(self.dp_btm); let mut curr = self.dp_btm;
while curr < self.dp { while curr < self.dp {
v.push(self.memory.peek24(curr)); v.push(self.memory.peek24(curr));
curr += 3 curr += 3
@@ -408,7 +407,7 @@ impl CPU {
pub fn get_call(&self) -> Vec<Word> { pub fn get_call(&self) -> Vec<Word> {
let mut v = Vec::new(); let mut v = Vec::new();
let mut curr = Word::from(self.sp_top); let mut curr = self.sp_top;
while curr > self.sp { while curr > self.sp {
curr -= 3; curr -= 3;
v.push(self.memory.peek24(curr)); v.push(self.memory.peek24(curr));
+20
View File
@@ -421,3 +421,23 @@ fn test_overflow_promotion() {
// Stack is now the previous bottom values, minus three cells: // Stack is now the previous bottom values, minus three cells:
assert_eq!((22.into(), 16.into()), cpu.sdp()); assert_eq!((22.into(), 16.into()), cpu.sdp());
} }
#[test]
fn test_invalid_opcode() {
let cpu = test_mem(
".org 0x400
push onop
setiv 4 ; set the overflow handler
push 1
push 2 ; fine so far
.org 0x4ff ; bunch of nops and then...
.db 0xf6 ; this isn't an instruction!
store ; never happens
onop: hlt"
.lines(),
[(256, 1), (259, 2)].into(), // expect the two successful pushes to be still there
);
// Call stack contains the address of the offending instruction
assert_eq!(vec![Word::from(0x4ff)], cpu.get_call());
}