Added supervisor checks

This commit is contained in:
transistor 2021-10-16 10:01:14 -07:00
parent ffd4faa9a3
commit 24e050a840
2 changed files with 49 additions and 18 deletions

View File

@ -1,6 +1,6 @@
use crate::error::Error;
use crate::system::System;
use crate::error::{ErrorType, Error};
use crate::memory::{Address, Addressable};
use crate::devices::{Clock, Steppable, Interruptable};
@ -65,6 +65,26 @@ impl M68k {
Status::Init => self.init(system),
Status::Stopped => Err(Error::new("CPU stopped")),
Status::Running => {
match self.cycle_one(system) {
Ok(()) => Ok(()),
Err(Error { err: ErrorType::Processor, native, .. }) => {
self.exception(system, native as u8)?;
Ok(())
},
Err(err) => Err(err),
}
},
}
}
pub fn init(&mut self, system: &System) -> Result<(), Error> {
self.state.msp = system.get_bus().read_beu32(0)?;
self.state.pc = system.get_bus().read_beu32(4)?;
self.state.status = Status::Running;
Ok(())
}
pub fn cycle_one(&mut self, system: &System) -> Result<(), Error> {
let timer = self.timer.cycle.start();
self.decode_next(system)?;
self.execute_current(system)?;
@ -75,16 +95,6 @@ impl M68k {
//}
self.check_pending_interrupts(system)?;
Ok(())
},
}
}
pub fn init(&mut self, system: &System) -> Result<(), Error> {
self.state.msp = system.get_bus().read_beu32(0)?;
self.state.pc = system.get_bus().read_beu32(4)?;
self.state.status = Status::Running;
Ok(())
}
@ -167,6 +177,7 @@ impl M68k {
self.state.sr = self.state.sr & (value as u16);
},
Instruction::ANDtoSR(value) => {
self.require_supervisor()?;
self.state.sr = self.state.sr & value;
},
Instruction::ASd(count, target, size, shift_dir) => {
@ -286,6 +297,7 @@ impl M68k {
self.state.sr = self.state.sr ^ (value as u16);
},
Instruction::EORtoSR(value) => {
self.require_supervisor()?;
self.state.sr = self.state.sr ^ value;
},
//Instruction::EXG(Target, Target) => {
@ -350,9 +362,11 @@ impl M68k {
*addr = value;
},
Instruction::MOVEfromSR(target) => {
self.require_supervisor()?;
self.set_target_value(system, target, self.state.sr as u32, Size::Word)?;
},
Instruction::MOVEtoSR(target) => {
self.require_supervisor()?;
self.state.sr = self.get_target_value(system, target, Size::Word)? as u16;
},
Instruction::MOVEtoCCR(target) => {
@ -360,6 +374,7 @@ impl M68k {
self.state.sr = (self.state.sr & 0xFF00) | (value & 0x00FF);
},
Instruction::MOVEC(target, control_reg, dir) => {
self.require_supervisor()?;
match dir {
Direction::FromTarget => {
let value = self.get_target_value(system, target, Size::Long)?;
@ -374,6 +389,7 @@ impl M68k {
}
},
Instruction::MOVEUSP(target, dir) => {
self.require_supervisor()?;
match dir {
Direction::ToTarget => self.set_target_value(system, target, self.state.usp, Size::Long)?,
Direction::FromTarget => { self.state.usp = self.get_target_value(system, target, Size::Long)?; },
@ -474,6 +490,7 @@ impl M68k {
self.state.sr = self.state.sr | (value as u16);
},
Instruction::ORtoSR(value) => {
self.require_supervisor()?;
self.state.sr = self.state.sr | value;
},
Instruction::PEA(target) => {
@ -481,6 +498,7 @@ impl M68k {
self.push_long(system, value)?;
},
//Instruction::RESET => {
// self.require_supervisor()?;
//},
Instruction::ROd(count, target, size, shift_dir) => {
let count = self.get_target_value(system, count, size)? % 64;
@ -497,6 +515,7 @@ impl M68k {
//Instruction::ROXd(Target, Target, Size, ShiftDirection) => {
//},
Instruction::RTE => {
self.require_supervisor()?;
self.state.sr = self.pop_word(system)?;
self.state.pc = self.pop_long(system)?;
let _ = self.pop_word(system)?;
@ -516,6 +535,7 @@ impl M68k {
}
},
Instruction::STOP(flags) => {
self.require_supervisor()?;
self.state.sr = flags;
self.state.status = Status::Stopped;
},
@ -718,10 +738,20 @@ impl M68k {
}
}
#[inline(always)]
fn is_supervisor(&self) -> bool {
self.state.sr & (Flags:: Supervisor as u16) != 0
}
#[inline(always)]
fn require_supervisor(&self) -> Result<(), Error> {
if self.is_supervisor() {
Ok(())
} else {
Err(Error::processor(Exceptions::PrivilegeViolation as u32))
}
}
#[inline(always)]
fn get_flag(&self, flag: Flags) -> bool {
(self.state.sr & (flag as u16)) != 0

View File

@ -1,14 +1,15 @@
* add exception for privileged instructions. Should you separate them in the `match` or just put a guard into the instructions, and if the latter, can
you use the emulator's errors to surface the execption up to the `step_internal` function but not to `System`?
* make IO in mc68681 use a separate thread... will that improve performance of mc68681.step()?
* make it possible to break out of the current execution, into the debugger
* how can you add 68030 support? Should it be all one module that checks maybe during decode if the instruction is supported? Should it 'inherit' from the MC68010 object
* make it possible to break out of the current execution, into the debugger, by using a certain keystroke
* add support for MC68020+ indexing modes
* add support for MMU
* add support for FPU
* make tests for each instruction
* unimplemented: ABCD, ADDX, BKPT, CHK, EXG, ILLEGAL, MOVEfromCCR, MOVEP, RTR, RTD, SBCD, SUBX
* undecoded: ADDX, SUBX
* modify execution for >=MC68020: DIVSL, DIVUL, EXTB, LINK, MOVEM, MULSL, MULUL, RTM, TRAPcc, UNPK
* modify execution for >=MC68020: DIVSL, DIVUL, LINK, MOVEM, MULSL, MULUL, RTM, TRAPcc, UNPK
* implement the full extension word for MC68020+
* >=MC68020 instructions: BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, CALLM, CAS, CAS2, CHK2, CMP2, PACK