From 8be5c65c731a27a3a8ea3197e8a6328376a8cd97 Mon Sep 17 00:00:00 2001 From: Ry Date: Thu, 15 Sep 2022 17:17:29 -0700 Subject: [PATCH] Fix many issues relating to paging, split page fault into 2 vectors --- src/cpu.rs | 450 ++++++++++++++++++++++++++------------------------ src/main.rs | 4 + src/memory.rs | 108 +++++++----- src/setjmp.rs | 56 +++++++ 4 files changed, 358 insertions(+), 260 deletions(-) create mode 100644 src/setjmp.rs diff --git a/src/cpu.rs b/src/cpu.rs index 248983a..83ebe87 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -4,6 +4,7 @@ // move this up to match all of the other ones (or move all of the other ones down, which would probably be better anyways) use crate::Bus; +use crate::setjmp::{JumpEnv, setjmp}; const DEBUG: bool = false; @@ -35,7 +36,8 @@ impl std::convert::From for Flag { pub enum Exception { DivideByZero, InvalidOpcode(u32), - PageFault(u32), + PageFaultRead(u32), + PageFaultWrite(u32), } #[derive(Debug)] @@ -53,6 +55,8 @@ pub struct Cpu { pub halted: bool, pub bus: Bus, + + pub onfault: JumpEnv, } impl Cpu { @@ -64,8 +68,12 @@ impl Cpu { flag: Flag { interrupt: false, carry: false, zero: false }, halted: false, bus, + onfault: JumpEnv::new(), } } + pub unsafe fn setjmp(&self) -> Option { + setjmp(&self.onfault) + } fn check_condition(&self, condition: Condition) -> bool { match condition { Condition::Always => true, @@ -84,39 +92,39 @@ impl Cpu { let mut instruction_pointer_offset = 2; // increment past opcode half let source_value = match source { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let value = self.read_register(register); instruction_pointer_offset += 1; // increment past 8 bit register number value } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); - let value = self.bus.memory.read_32(pointer); + let value = self.bus.memory.read_32(&self.onfault, pointer); instruction_pointer_offset += 1; // increment past 8 bit register number value } Operand::Immediate8 => { - let value = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let value = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); instruction_pointer_offset += 1; // increment past 8 bit immediate value as u32 } Operand::Immediate16 => { - let value = self.bus.memory.read_16(self.instruction_pointer + instruction_pointer_offset); + let value = self.bus.memory.read_16(&self.onfault, self.instruction_pointer + instruction_pointer_offset); instruction_pointer_offset += 2; // increment past 16 bit immediate value as u32 } Operand::Immediate32 => { - let value = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let value = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); instruction_pointer_offset += 4; // increment past 32 bit immediate value } Operand::ImmediatePtr(size) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let value = match size { - Size::Byte => self.bus.memory.read_8(pointer) as u32, - Size::Half => self.bus.memory.read_16(pointer) as u32, - Size::Word => self.bus.memory.read_32(pointer), + Size::Byte => self.bus.memory.read_8(&self.onfault, pointer) as u32, + Size::Half => self.bus.memory.read_16(&self.onfault, pointer) as u32, + Size::Word => self.bus.memory.read_32(&self.onfault, pointer), }; instruction_pointer_offset += 4; // increment past 32 bit pointer value @@ -163,7 +171,7 @@ impl Cpu { self.bus.memory.write_8(self.stack_pointer, byte); } pub fn pop_stack_8(&mut self) -> u8 { - let byte = self.bus.memory.read_8(self.stack_pointer); + let byte = self.bus.memory.read_8(&self.onfault, self.stack_pointer); let incremented_stack_pointer = self.stack_pointer.overflowing_add(1); self.stack_pointer = incremented_stack_pointer.0; byte @@ -174,7 +182,7 @@ impl Cpu { self.bus.memory.write_16(self.stack_pointer, half); } pub fn pop_stack_16(&mut self) -> u16 { - let half = self.bus.memory.read_16(self.stack_pointer); + let half = self.bus.memory.read_16(&self.onfault, self.stack_pointer); let incremented_stack_pointer = self.stack_pointer.overflowing_add(2); self.stack_pointer = incremented_stack_pointer.0; half @@ -185,7 +193,7 @@ impl Cpu { self.bus.memory.write_32(self.stack_pointer, word); } pub fn pop_stack_32(&mut self) -> u32 { - let word = self.bus.memory.read_32(self.stack_pointer); + let word = self.bus.memory.read_32(&self.onfault, self.stack_pointer); let incremented_stack_pointer = self.stack_pointer.overflowing_add(4); self.stack_pointer = incremented_stack_pointer.0; word @@ -207,10 +215,14 @@ impl Cpu { let vector: u16 = 1; self.handle_exception(vector, Some(opcode)); } - Exception::PageFault(virtual_address) => { + Exception::PageFaultRead(virtual_address) => { let vector: u16 = 2; self.handle_exception(vector, Some(virtual_address)); } + Exception::PageFaultWrite(virtual_address) => { + let vector: u16 = 3; + self.handle_exception(vector, Some(virtual_address)); + } } } } @@ -219,7 +231,10 @@ impl Cpu { fn handle_interrupt(&mut self, vector: u16) { if DEBUG { println!("interrupt!!! vector: {:#04X}", vector); } let address_of_pointer = vector as u32 * 4; - let address = self.bus.memory.read_32(address_of_pointer); + let old_mmu_state = *self.bus.memory.mmu_enabled(); + *self.bus.memory.mmu_enabled() = false; + let address = self.bus.memory.read_32(&self.onfault, address_of_pointer); + *self.bus.memory.mmu_enabled() = old_mmu_state; self.push_stack_32(self.instruction_pointer); self.push_stack_8(u8::from(self.flag)); self.flag.interrupt = false; // prevent interrupts while already servicing an interrupt @@ -228,7 +243,10 @@ impl Cpu { fn handle_exception(&mut self, vector: u16, operand: Option) { if DEBUG { println!("exception!!! vector: {:#04X}, operand: {:?}", vector, operand); } let address_of_pointer = (256 + vector) as u32 * 4; - let address = self.bus.memory.read_32(address_of_pointer); + let old_mmu_state = *self.bus.memory.mmu_enabled(); + *self.bus.memory.mmu_enabled() = false; + let address = self.bus.memory.read_32(&self.onfault, address_of_pointer); + *self.bus.memory.mmu_enabled() = old_mmu_state; self.push_stack_32(self.instruction_pointer); self.push_stack_8(u8::from(self.flag)); if let Some(operand) = operand { @@ -239,7 +257,7 @@ impl Cpu { } // execute instruction from memory at the current instruction pointer pub fn execute_memory_instruction(&mut self) { - let opcode = self.bus.memory.read_16(self.instruction_pointer); + let opcode = self.bus.memory.read_16(&self.onfault, self.instruction_pointer); if let Some(instruction) = Instruction::from_half(opcode) { if DEBUG { println!("{:#010X}: {:?}", self.instruction_pointer, instruction); } @@ -291,7 +309,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -321,11 +339,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_add(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_add(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; @@ -333,7 +351,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_add(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_add(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; @@ -341,7 +359,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_add(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_add(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -352,10 +370,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_add(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_add(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; @@ -363,7 +381,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_add(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_add(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; @@ -371,7 +389,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_add(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_add(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -390,7 +408,7 @@ impl Cpu { let should_run = self.check_condition(condition); match source { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -420,12 +438,12 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { if should_run { - let result = self.bus.memory.read_8(pointer).overflowing_add(1); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_add(1); self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -433,7 +451,7 @@ impl Cpu { } Size::Half => { if should_run { - let result = self.bus.memory.read_16(pointer).overflowing_add(1); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_add(1); self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -441,7 +459,7 @@ impl Cpu { } Size::Word => { if should_run { - let result = self.bus.memory.read_32(pointer).overflowing_add(1); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_add(1); self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -451,11 +469,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { - let result = self.bus.memory.read_8(pointer).overflowing_add(1); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_add(1); self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -463,7 +481,7 @@ impl Cpu { } Size::Half => { if should_run { - let result = self.bus.memory.read_16(pointer).overflowing_add(1); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_add(1); self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -471,7 +489,7 @@ impl Cpu { } Size::Word => { if should_run { - let result = self.bus.memory.read_32(pointer).overflowing_add(1); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_add(1); self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -489,7 +507,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -519,11 +537,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_sub(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_sub(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; @@ -531,7 +549,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_sub(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_sub(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; @@ -539,7 +557,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_sub(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_sub(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -550,10 +568,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_sub(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_sub(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; @@ -561,7 +579,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_sub(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_sub(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; @@ -569,7 +587,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_sub(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_sub(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -588,7 +606,7 @@ impl Cpu { let should_run = self.check_condition(condition); match source { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -618,12 +636,12 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { if should_run { - let result = self.bus.memory.read_8(pointer).overflowing_sub(1); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_sub(1); self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -631,7 +649,7 @@ impl Cpu { } Size::Half => { if should_run { - let result = self.bus.memory.read_16(pointer).overflowing_sub(1); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_sub(1); self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -639,7 +657,7 @@ impl Cpu { } Size::Word => { if should_run { - let result = self.bus.memory.read_32(pointer).overflowing_sub(1); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_sub(1); self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -649,11 +667,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { - let result = self.bus.memory.read_8(pointer).overflowing_sub(1); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_sub(1); self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -661,7 +679,7 @@ impl Cpu { } Size::Half => { if should_run { - let result = self.bus.memory.read_16(pointer).overflowing_sub(1); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_sub(1); self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -669,7 +687,7 @@ impl Cpu { } Size::Word => { if should_run { - let result = self.bus.memory.read_32(pointer).overflowing_sub(1); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_sub(1); self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -687,7 +705,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -717,11 +735,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_mul(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_mul(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; @@ -729,7 +747,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_mul(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_mul(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; @@ -737,7 +755,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_mul(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_mul(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -748,10 +766,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_mul(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_mul(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; @@ -759,7 +777,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_mul(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_mul(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; @@ -767,7 +785,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_mul(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_mul(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -786,7 +804,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -813,25 +831,25 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_div(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_div(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_div(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_div(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_div(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_div(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -841,24 +859,24 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_div(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_div(source_value as u8); if should_run { self.bus.memory.write_8(pointer, result.0); self.flag.zero = result.0 == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_div(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_div(source_value as u16); if should_run { self.bus.memory.write_16(pointer, result.0); self.flag.zero = result.0 == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_div(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_div(source_value); if should_run { self.bus.memory.write_32(pointer, result.0); self.flag.zero = result.0 == 0; @@ -876,7 +894,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -903,25 +921,25 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) % source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) % source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) % source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) % source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) % source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) % source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -931,24 +949,24 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) % source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) % source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) % source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) % source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) % source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) % source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -967,7 +985,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -994,25 +1012,25 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) & source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) & source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) & source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) & source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) & source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) & source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1022,24 +1040,24 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) & source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) & source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) & source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) & source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) & source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) & source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1057,7 +1075,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1084,25 +1102,25 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) | source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) | source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) | source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) | source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) | source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) | source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1112,24 +1130,24 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) | source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) | source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) | source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) | source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) | source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) | source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1147,7 +1165,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1174,25 +1192,25 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) ^ source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) ^ source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) ^ source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) ^ source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) ^ source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) ^ source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1202,24 +1220,24 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) ^ source_value as u8; + let result = self.bus.memory.read_8(&self.onfault, pointer) ^ source_value as u8; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) ^ source_value as u16; + let result = self.bus.memory.read_16(&self.onfault, pointer) ^ source_value as u16; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) ^ source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) ^ source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1237,7 +1255,7 @@ impl Cpu { let should_run = self.check_condition(condition); match source { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1264,25 +1282,25 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result =!self.bus.memory.read_8(pointer); + let result =!self.bus.memory.read_8(&self.onfault, pointer); if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = !self.bus.memory.read_16(pointer); + let result = !self.bus.memory.read_16(&self.onfault, pointer); if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = !self.bus.memory.read_32(pointer); + let result = !self.bus.memory.read_32(&self.onfault, pointer); if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1292,24 +1310,24 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = !self.bus.memory.read_8(pointer); + let result = !self.bus.memory.read_8(&self.onfault, pointer); if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; } } Size::Half => { - let result = !self.bus.memory.read_16(pointer); + let result = !self.bus.memory.read_16(&self.onfault, pointer); if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; } } Size::Word => { - let result = !self.bus.memory.read_32(pointer); + let result = !self.bus.memory.read_32(&self.onfault, pointer); if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1327,7 +1345,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1357,11 +1375,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) << source_value; + let result = self.bus.memory.read_8(&self.onfault, pointer) << source_value; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1369,7 +1387,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer) << source_value; + let result = self.bus.memory.read_16(&self.onfault, pointer) << source_value; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1377,7 +1395,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer) << source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) << source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1388,10 +1406,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) << source_value; + let result = self.bus.memory.read_8(&self.onfault, pointer) << source_value; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1399,7 +1417,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer) << source_value; + let result = self.bus.memory.read_16(&self.onfault, pointer) << source_value; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1407,7 +1425,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer) << source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) << source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1426,7 +1444,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1456,11 +1474,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) >> source_value as i32; + let result = self.bus.memory.read_8(&self.onfault, pointer) >> source_value as i32; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1468,7 +1486,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer) >> source_value as i32; + let result = self.bus.memory.read_16(&self.onfault, pointer) >> source_value as i32; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1476,7 +1494,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer) >> source_value as i32; + let result = self.bus.memory.read_32(&self.onfault, pointer) >> source_value as i32; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1487,10 +1505,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) >> source_value as i32; + let result = self.bus.memory.read_8(&self.onfault, pointer) >> source_value as i32; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1498,7 +1516,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer) >> source_value as i32; + let result = self.bus.memory.read_16(&self.onfault, pointer) >> source_value as i32; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1506,7 +1524,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer) >> source_value as i32; + let result = self.bus.memory.read_32(&self.onfault, pointer) >> source_value as i32; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1525,7 +1543,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1555,11 +1573,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) >> source_value; + let result = self.bus.memory.read_8(&self.onfault, pointer) >> source_value; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1567,7 +1585,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer) >> source_value; + let result = self.bus.memory.read_16(&self.onfault, pointer) >> source_value; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1575,7 +1593,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer) >> source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) >> source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1586,10 +1604,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) >> source_value; + let result = self.bus.memory.read_8(&self.onfault, pointer) >> source_value; if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1597,7 +1615,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer) >> source_value; + let result = self.bus.memory.read_16(&self.onfault, pointer) >> source_value; if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1605,7 +1623,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer) >> source_value; + let result = self.bus.memory.read_32(&self.onfault, pointer) >> source_value; if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1624,7 +1642,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1654,11 +1672,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).rotate_left(source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer).rotate_left(source_value); if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1666,7 +1684,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).rotate_left(source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer).rotate_left(source_value); if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1674,7 +1692,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).rotate_left(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).rotate_left(source_value); if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1685,10 +1703,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).rotate_left(source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer).rotate_left(source_value); if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1696,7 +1714,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).rotate_left(source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer).rotate_left(source_value); if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1704,7 +1722,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).rotate_left(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).rotate_left(source_value); if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1723,7 +1741,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -1753,11 +1771,11 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).rotate_right(source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer).rotate_right(source_value); if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1765,7 +1783,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).rotate_right(source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer).rotate_right(source_value); if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1773,7 +1791,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).rotate_right(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).rotate_right(source_value); if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1784,10 +1802,10 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).rotate_right(source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer).rotate_right(source_value); if should_run { self.bus.memory.write_8(pointer, result); self.flag.zero = result == 0; @@ -1795,7 +1813,7 @@ impl Cpu { } } Size::Half => { - let result = self.bus.memory.read_16(pointer).rotate_right(source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer).rotate_right(source_value); if should_run { self.bus.memory.write_16(pointer, result); self.flag.zero = result == 0; @@ -1803,7 +1821,7 @@ impl Cpu { } } Size::Word => { - let result = self.bus.memory.read_32(pointer).rotate_right(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).rotate_right(source_value); if should_run { self.bus.memory.write_32(pointer, result); self.flag.zero = result == 0; @@ -1823,7 +1841,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { let result = self.read_register(register) as u8 | (1 << source_value); @@ -1847,23 +1865,23 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) | (1 << source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer) | (1 << source_value); if should_run { self.bus.memory.write_8(pointer, result); } } Size::Half => { - let result = self.bus.memory.read_16(pointer) | (1 << source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer) | (1 << source_value); if should_run { self.bus.memory.write_16(pointer, result); } } Size::Word => { - let result = self.bus.memory.read_32(pointer) | (1 << source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer) | (1 << source_value); if should_run { self.bus.memory.write_32(pointer, result); } @@ -1872,22 +1890,22 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) | (1 << source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer) | (1 << source_value); if should_run { self.bus.memory.write_8(pointer, result); } } Size::Half => { - let result = self.bus.memory.read_16(pointer) | (1 << source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer) | (1 << source_value); if should_run { self.bus.memory.write_16(pointer, result); } } Size::Word => { - let result = self.bus.memory.read_32(pointer) | (1 << source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer) | (1 << source_value); if should_run { self.bus.memory.write_32(pointer, result); } @@ -1904,7 +1922,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { let result = self.read_register(register) as u8 & !(1 << source_value); @@ -1928,23 +1946,23 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) & !(1 << source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer) & !(1 << source_value); if should_run { self.bus.memory.write_8(pointer, result); } } Size::Half => { - let result = self.bus.memory.read_16(pointer) & !(1 << source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer) & !(1 << source_value); if should_run { self.bus.memory.write_16(pointer, result); } } Size::Word => { - let result = self.bus.memory.read_32(pointer) & !(1 << source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer) & !(1 << source_value); if should_run { self.bus.memory.write_32(pointer, result); } @@ -1953,22 +1971,22 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) & !(1 << source_value); + let result = self.bus.memory.read_8(&self.onfault, pointer) & !(1 << source_value); if should_run { self.bus.memory.write_8(pointer, result); } } Size::Half => { - let result = self.bus.memory.read_16(pointer) & !(1 << source_value); + let result = self.bus.memory.read_16(&self.onfault, pointer) & !(1 << source_value); if should_run { self.bus.memory.write_16(pointer, result); } } Size::Word => { - let result = self.bus.memory.read_32(pointer) & !(1 << source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer) & !(1 << source_value); if should_run { self.bus.memory.write_32(pointer, result); } @@ -1985,7 +2003,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { let result = self.read_register(register) as u8 & (1 << source_value) == 0; @@ -2009,23 +2027,23 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) & (1 << source_value) == 0; + let result = self.bus.memory.read_8(&self.onfault, pointer) & (1 << source_value) == 0; if should_run { self.flag.zero = result; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) & (1 << source_value) == 0; + let result = self.bus.memory.read_16(&self.onfault, pointer) & (1 << source_value) == 0; if should_run { self.flag.zero = result; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) & (1 << source_value) == 0; + let result = self.bus.memory.read_32(&self.onfault, pointer) & (1 << source_value) == 0; if should_run { self.flag.zero = result; } @@ -2034,22 +2052,22 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer) & (1 << source_value) == 0; + let result = self.bus.memory.read_8(&self.onfault, pointer) & (1 << source_value) == 0; if should_run { self.flag.zero = result; } } Size::Half => { - let result = self.bus.memory.read_16(pointer) & (1 << source_value) == 0; + let result = self.bus.memory.read_16(&self.onfault, pointer) & (1 << source_value) == 0; if should_run { self.flag.zero = result; } } Size::Word => { - let result = self.bus.memory.read_32(pointer) & (1 << source_value) == 0; + let result = self.bus.memory.read_32(&self.onfault, pointer) & (1 << source_value) == 0; if should_run { self.flag.zero = result; } @@ -2067,7 +2085,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -2094,25 +2112,25 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_sub(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_sub(source_value as u8); if should_run { self.flag.zero = result.0 == 0; self.flag.carry = result.1; } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_sub(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_sub(source_value as u16); if should_run { self.flag.zero = result.0 == 0; self.flag.carry = result.1; } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_sub(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_sub(source_value); if should_run { self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -2122,24 +2140,24 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { - let result = self.bus.memory.read_8(pointer).overflowing_sub(source_value as u8); + let result = self.bus.memory.read_8(&self.onfault, pointer).overflowing_sub(source_value as u8); if should_run { self.flag.zero = result.0 == 0; self.flag.carry = result.1; } } Size::Half => { - let result = self.bus.memory.read_16(pointer).overflowing_sub(source_value as u16); + let result = self.bus.memory.read_16(&self.onfault, pointer).overflowing_sub(source_value as u16); if should_run { self.flag.zero = result.0 == 0; self.flag.carry = result.1; } } Size::Word => { - let result = self.bus.memory.read_32(pointer).overflowing_sub(source_value); + let result = self.bus.memory.read_32(&self.onfault, pointer).overflowing_sub(source_value); if should_run { self.flag.zero = result.0 == 0; self.flag.carry = result.1; @@ -2157,7 +2175,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -2178,7 +2196,7 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { @@ -2200,7 +2218,7 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -2229,7 +2247,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -2328,14 +2346,14 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); if should_run { self.write_register(register, self.relative_to_absolute(source_value)); } instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.relative_to_absolute(self.read_register(register)); if should_run { // INFO: register contains a relative address instead of an absolute address @@ -2344,7 +2362,7 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let word = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let word = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.relative_to_absolute(word); if should_run { self.bus.memory.write_32(pointer, self.relative_to_absolute(source_value)); @@ -2383,7 +2401,7 @@ impl Cpu { let should_run = self.check_condition(condition); match source { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -2407,7 +2425,7 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); match size { Size::Byte => { @@ -2432,7 +2450,7 @@ impl Cpu { instruction_pointer_offset += 1; // increment past 8 bit register number } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { if should_run { @@ -2484,7 +2502,7 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let value = self.bus.read_io(source_value); instruction_pointer_offset += 1; // increment past 8 bit register number if should_run { @@ -2492,7 +2510,7 @@ impl Cpu { } } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); let value = self.bus.read_io(source_value); instruction_pointer_offset += 1; // increment past 8 bit register number @@ -2501,7 +2519,7 @@ impl Cpu { } } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let value = self.bus.read_io(source_value); instruction_pointer_offset += 4; // increment past 32 bit pointer if should_run { @@ -2517,26 +2535,26 @@ impl Cpu { let should_run = self.check_condition(condition); match destination { Operand::Register => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); instruction_pointer_offset += 1; // increment past 8 bit register number if should_run { self.bus.write_io(self.read_register(register), source_value); } } Operand::RegisterPtr => { - let register = self.bus.memory.read_8(self.instruction_pointer + instruction_pointer_offset); + let register = self.bus.memory.read_8(&self.onfault, self.instruction_pointer + instruction_pointer_offset); let pointer = self.read_register(register); instruction_pointer_offset += 1; // increment past 8 bit register number if should_run { - let word = self.bus.memory.read_32(pointer); + let word = self.bus.memory.read_32(&self.onfault, pointer); self.bus.write_io(word, source_value); } } Operand::ImmediatePtr(_) => { - let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); + let pointer = self.bus.memory.read_32(&self.onfault, self.instruction_pointer + instruction_pointer_offset); instruction_pointer_offset += 4; // increment past 32 bit pointer if should_run { - let word = self.bus.memory.read_32(pointer); + let word = self.bus.memory.read_32(&self.onfault, pointer); self.bus.write_io(word, source_value); } } diff --git a/src/main.rs b/src/main.rs index 940d28a..87a0875 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ pub mod cpu; pub mod keyboard; pub mod mouse; pub mod disk; +pub mod setjmp; use audio::AudioChannel; use bus::Bus; @@ -158,6 +159,9 @@ fn main() { builder.spawn({ move || { loop { + if let Some(exception) = unsafe { cpu.setjmp() } { + cpu.interrupt(Interrupt::Exception(exception)); + } while !cpu.halted { if let Ok(exception) = exception_receiver.try_recv() { cpu.interrupt(Interrupt::Exception(exception)); diff --git a/src/memory.rs b/src/memory.rs index b2e3944..0c53fb0 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -2,6 +2,7 @@ use crate::error; use crate::cpu::Exception; +use crate::setjmp::{JumpEnv, longjmp}; use std::cell::UnsafeCell; use std::collections::HashMap; @@ -111,26 +112,39 @@ impl Memory { let old_state = *self.mmu_enabled(); *self.mmu_enabled() = false; let directory_address = *self.paging_directory_address(); - let directory = self.read_32(directory_address + (page_directory_index * 4)); - let dir_present = directory & 0b1 != 0; - let dir_address = directory & 0xFFFFF000; - if dir_present { - let table = self.read_32(dir_address + (page_table_index * 4)); - let table_present = table & 0b01 != 0; - let table_rw = table & 0b10 != 0; - let table_address = table & 0xFFFFF000; + let directory = self.read_opt_32(directory_address + (page_directory_index * 4)); + match directory { + Some(directory) => { + let dir_present = directory & 0b1 != 0; + let dir_address = directory & 0xFFFFF000; + if dir_present { + let table = self.read_opt_32(dir_address + (page_table_index * 4)); + match table { + Some(table) => { + let table_present = table & 0b01 != 0; + let table_rw = table & 0b10 != 0; + let table_address = table & 0xFFFFF000; - if table_present { - let tlb_entry = MemoryPage { - physical_address: table_address, - present: table_present, - rw: table_rw, - }; - self.tlb().entry((page_directory_index << 22) | (page_table_index << 12)).or_insert(tlb_entry); + if table_present { + let tlb_entry = MemoryPage { + physical_address: table_address, + present: table_present, + rw: table_rw, + }; + self.tlb().entry((page_directory_index << 22) | (page_table_index << 12)).or_insert(tlb_entry); + } + }, + None => {} + } + } + *self.mmu_enabled() = old_state; + dir_present + }, + None => { + *self.mmu_enabled() = old_state; + false } } - *self.mmu_enabled() = old_state; - dir_present } pub fn virtual_to_physical(&mut self, virtual_address: u32) -> Option<(u32, bool)> { @@ -170,47 +184,53 @@ impl Memory { physical_address } - pub fn read_8(&mut self, mut address: u32) -> u8 { + pub fn read_opt_8(&mut self, mut address: u32) -> Option { if *self.mmu_enabled() { - (address, _) = self.virtual_to_physical(address as u32).unwrap_or_else(|| { - self.exception_sender().send(Exception::PageFault(address)).unwrap(); - (0, false) - }); + let address_maybe = self.virtual_to_physical(address as u32); + match address_maybe { + Some(addr) => address = addr.0, + None => return None, + } } let address = address as usize; - let result = if address >= MEMORY_ROM_START && address < MEMORY_ROM_START + MEMORY_ROM_SIZE { - self.rom().get(address - MEMORY_ROM_START) + if address >= MEMORY_ROM_START && address < MEMORY_ROM_START + MEMORY_ROM_SIZE { + self.rom().get(address - MEMORY_ROM_START).map(|value| *value) } else { - self.ram().get(address - MEMORY_RAM_START) - }; - - match result { - Some(value) => { - *value - } - None => { - error(&format!("attempting to read from unmapped physical memory address: {:#010X}", address)); - } + self.ram().get(address - MEMORY_RAM_START).map(|value| *value) } } - pub fn read_16(&mut self, address: u32) -> u16 { - (self.read_8(address) as u16) | - (self.read_8(address + 1) as u16) << 8 + pub fn read_opt_16(&mut self, address: u32) -> Option { + Some( + (self.read_opt_8(address)? as u16) | + (self.read_opt_8(address + 1)? as u16) << 8 + ) } - pub fn read_32(&mut self, address: u32) -> u32 { - (self.read_8(address) as u32) | - (self.read_8(address + 1) as u32) << 8 | - (self.read_8(address + 2) as u32) << 16 | - (self.read_8(address + 3) as u32) << 24 + pub fn read_opt_32(&mut self, address: u32) -> Option { + Some( + (self.read_opt_8(address)? as u32) | + (self.read_opt_8(address + 1)? as u32) << 8 | + (self.read_opt_8(address + 2)? as u32) << 16 | + (self.read_opt_8(address + 3)? as u32) << 24 + ) + } + + pub fn read_8(&mut self, onfault: &JumpEnv, address: u32) -> u8 { + self.read_opt_8(address).unwrap_or_else(|| unsafe { longjmp(onfault, Exception::PageFaultRead(address)) }) + } + pub fn read_16(&mut self, onfault: &JumpEnv, address: u32) -> u16 { + self.read_opt_16(address).unwrap_or_else(|| unsafe { longjmp(onfault, Exception::PageFaultRead(address)) }) + } + pub fn read_32(&mut self, onfault: &JumpEnv, address: u32) -> u32 { + self.read_opt_32(address).unwrap_or_else(|| unsafe { longjmp(onfault, Exception::PageFaultRead(address)) }) } pub fn write_8(&mut self, mut address: u32, byte: u8) { let mut writable = true; if *self.mmu_enabled() { (address, writable) = self.virtual_to_physical(address as u32).unwrap_or_else(|| { - self.exception_sender().send(Exception::PageFault(address)).unwrap(); + self.exception_sender().send(Exception::PageFaultWrite(address)).unwrap(); (0, false) }); } @@ -231,7 +251,7 @@ impl Memory { } } } else { - self.exception_sender().send(Exception::PageFault(address)).unwrap(); + self.exception_sender().send(Exception::PageFaultWrite(address)).unwrap(); } } pub fn write_16(&mut self, address: u32, half: u16) { diff --git a/src/setjmp.rs b/src/setjmp.rs new file mode 100644 index 0000000..fc42e4f --- /dev/null +++ b/src/setjmp.rs @@ -0,0 +1,56 @@ +// setjmp.rs + +use std::os::raw::*; + +mod internal { + use std::os::raw::*; + use std::cell::*; + + extern "C" { + pub fn setjmp(env: *mut c_void) -> c_int; + pub fn longjmp(env: *mut c_void, status: c_int) -> !; + } + + pub type JumpBuf = [u8; 512]; + + pub struct JumpEnv{ + buffer: Box>, + value: Cell>, + } + + impl JumpEnv { + pub fn new() -> Self { + Self { + buffer: Box::new(RefCell::new([0u8; 512])), + value: Cell::default(), + } + } + + pub fn buffer(&self) -> RefMut { + self.buffer.borrow_mut() + } + + pub fn value_set(&self, value: T) { + self.value.set(Some(value)); + } + + pub fn value_take(&self) -> Option { + self.value.take() + } + } +} + +pub use internal::JumpEnv; + +pub unsafe fn setjmp(env: &JumpEnv) -> Option { + if internal::setjmp(env.buffer().as_mut_ptr() as *mut c_void) != 0 { + env.value_take() + } else { + None + } +} + +pub unsafe fn longjmp(env: &JumpEnv, value: T) -> ! { + env.value_set(value); + internal::longjmp(env.buffer().as_mut_ptr() as *mut c_void, 1) +}