Make sure certain instructions are only executed in supervisor mode
This commit is contained in:
parent
6bbc879244
commit
8c6e26005d
43
src/m68k.rs
43
src/m68k.rs
@ -335,7 +335,13 @@ impl M68K {
|
|||||||
Instruction::OriCcr(val) => {
|
Instruction::OriCcr(val) => {
|
||||||
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) | u16::from(val));
|
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) | u16::from(val));
|
||||||
}
|
}
|
||||||
Instruction::OriSr(val) => self.sr |= val,
|
Instruction::OriSr(val) => {
|
||||||
|
if !self.is_supervisor() {
|
||||||
|
self.trap(8)?;
|
||||||
|
return Err(InsExecError::AbnormalTrap);
|
||||||
|
}
|
||||||
|
self.sr |= val;
|
||||||
|
}
|
||||||
Instruction::Ori(size, dst, val) => {
|
Instruction::Ori(size, dst, val) => {
|
||||||
let dst_val = self.read_effective(dst, size)?;
|
let dst_val = self.read_effective(dst, size)?;
|
||||||
let res = dst_val | val;
|
let res = dst_val | val;
|
||||||
@ -353,7 +359,13 @@ impl M68K {
|
|||||||
Instruction::AndiCcr(val) => {
|
Instruction::AndiCcr(val) => {
|
||||||
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) & u16::from(val));
|
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) & u16::from(val));
|
||||||
}
|
}
|
||||||
Instruction::AndiSr(val) => self.sr &= val,
|
Instruction::AndiSr(val) => {
|
||||||
|
if !self.is_supervisor() {
|
||||||
|
self.trap(8)?;
|
||||||
|
return Err(InsExecError::AbnormalTrap);
|
||||||
|
}
|
||||||
|
self.sr &= val;
|
||||||
|
}
|
||||||
Instruction::Andi(size, dst, val) => {
|
Instruction::Andi(size, dst, val) => {
|
||||||
let dst_val = self.read_effective(dst, size)?;
|
let dst_val = self.read_effective(dst, size)?;
|
||||||
let res = dst_val & val;
|
let res = dst_val & val;
|
||||||
@ -377,7 +389,13 @@ impl M68K {
|
|||||||
Instruction::EoriCcr(val) => {
|
Instruction::EoriCcr(val) => {
|
||||||
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) ^ u16::from(val));
|
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) ^ u16::from(val));
|
||||||
}
|
}
|
||||||
Instruction::EoriSr(val) => self.sr ^= val,
|
Instruction::EoriSr(val) => {
|
||||||
|
if !self.is_supervisor() {
|
||||||
|
self.trap(8)?;
|
||||||
|
return Err(InsExecError::AbnormalTrap);
|
||||||
|
}
|
||||||
|
self.sr ^= val;
|
||||||
|
}
|
||||||
Instruction::Eori(size, dst, val) => {
|
Instruction::Eori(size, dst, val) => {
|
||||||
let dst_val = self.read_effective(dst, size)?;
|
let dst_val = self.read_effective(dst, size)?;
|
||||||
let res = dst_val ^ val;
|
let res = dst_val ^ val;
|
||||||
@ -526,6 +544,10 @@ impl M68K {
|
|||||||
self.sr = (self.sr & 0xFF00) | src_val as u16;
|
self.sr = (self.sr & 0xFF00) | src_val as u16;
|
||||||
}
|
}
|
||||||
Instruction::MoveToSr(src) => {
|
Instruction::MoveToSr(src) => {
|
||||||
|
if !self.is_supervisor() {
|
||||||
|
self.trap(8)?;
|
||||||
|
return Err(InsExecError::AbnormalTrap);
|
||||||
|
}
|
||||||
let src_val = self.read_effective(src, Size::Word)?;
|
let src_val = self.read_effective(src, Size::Word)?;
|
||||||
self.sr = src_val as u16;
|
self.sr = src_val as u16;
|
||||||
}
|
}
|
||||||
@ -621,6 +643,10 @@ impl M68K {
|
|||||||
self.write_effective(dst, old_dst, Size::Long)?;
|
self.write_effective(dst, old_dst, Size::Long)?;
|
||||||
}
|
}
|
||||||
Instruction::MoveUsp(dir, areg) => {
|
Instruction::MoveUsp(dir, areg) => {
|
||||||
|
if !self.is_supervisor() {
|
||||||
|
self.trap(8)?;
|
||||||
|
return Err(InsExecError::AbnormalTrap);
|
||||||
|
}
|
||||||
let areg = EffectiveAddress::AddressReg(areg);
|
let areg = EffectiveAddress::AddressReg(areg);
|
||||||
match dir {
|
match dir {
|
||||||
MoveDirection::MemToReg => self.write_effective(areg, self.usp, Size::Long)?,
|
MoveDirection::MemToReg => self.write_effective(areg, self.usp, Size::Long)?,
|
||||||
@ -632,11 +658,19 @@ impl M68K {
|
|||||||
}
|
}
|
||||||
Instruction::Nop => (),
|
Instruction::Nop => (),
|
||||||
Instruction::Stop(sr) => {
|
Instruction::Stop(sr) => {
|
||||||
|
if !self.is_supervisor() {
|
||||||
|
self.trap(8)?;
|
||||||
|
return Err(InsExecError::AbnormalTrap);
|
||||||
|
}
|
||||||
self.sr = sr;
|
self.sr = sr;
|
||||||
self.stopped = true;
|
self.stopped = true;
|
||||||
}
|
}
|
||||||
Instruction::Rte => {
|
Instruction::Rte => {
|
||||||
self.sr = self.pop(Size::Word)? as u16;
|
if !self.is_supervisor() {
|
||||||
|
self.trap(8)?;
|
||||||
|
return Err(InsExecError::AbnormalTrap);
|
||||||
|
}
|
||||||
|
let orig_sr = self.pop(Size::Word)? as u16;
|
||||||
self.pc = self.pop(Size::Long)?;
|
self.pc = self.pop(Size::Long)?;
|
||||||
let format = (self.pop(Size::Word)? & 0xf000) >> 12;
|
let format = (self.pop(Size::Word)? & 0xf000) >> 12;
|
||||||
if format == 8 {
|
if format == 8 {
|
||||||
@ -707,6 +741,7 @@ impl M68K {
|
|||||||
self.stored_mem_cycles.pop();
|
self.stored_mem_cycles.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.sr = orig_sr;
|
||||||
}
|
}
|
||||||
Instruction::Rts => self.pc = self.pop(Size::Long)?,
|
Instruction::Rts => self.pc = self.pop(Size::Long)?,
|
||||||
Instruction::Trapv => {
|
Instruction::Trapv => {
|
||||||
|
Loading…
Reference in New Issue
Block a user