mirror of
https://github.com/transistorfet/moa.git
synced 2024-10-31 19:04:37 +00:00
Added bit field instructions, and fixed some bugs
This commit is contained in:
parent
758621c410
commit
32d2d591ce
@ -29,6 +29,8 @@ const OPCG_RESERVED1: u8 = 0xA;
|
|||||||
const OPCG_RESERVED2: u8 = 0xF;
|
const OPCG_RESERVED2: u8 = 0xF;
|
||||||
|
|
||||||
|
|
||||||
|
pub type Register = u8;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum Sign {
|
pub enum Sign {
|
||||||
Signed,
|
Signed,
|
||||||
@ -53,6 +55,13 @@ pub enum XRegister {
|
|||||||
Address(u8),
|
Address(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub enum RegOrImmediate {
|
||||||
|
DReg(u8),
|
||||||
|
Immediate(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum ControlRegister {
|
pub enum ControlRegister {
|
||||||
VBR,
|
VBR,
|
||||||
@ -88,13 +97,13 @@ pub enum Condition {
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum Target {
|
pub enum Target {
|
||||||
Immediate(u32),
|
Immediate(u32),
|
||||||
DirectDReg(u8),
|
DirectDReg(Register),
|
||||||
DirectAReg(u8),
|
DirectAReg(Register),
|
||||||
IndirectAReg(u8),
|
IndirectAReg(Register),
|
||||||
IndirectARegInc(u8),
|
IndirectARegInc(Register),
|
||||||
IndirectARegDec(u8),
|
IndirectARegDec(Register),
|
||||||
IndirectARegOffset(u8, i32),
|
IndirectARegOffset(Register, i32),
|
||||||
IndirectARegXRegOffset(u8, XRegister, i32, u8, Size),
|
IndirectARegXRegOffset(Register, XRegister, i32, u8, Size),
|
||||||
IndirectMemory(u32),
|
IndirectMemory(u32),
|
||||||
IndirectPCOffset(i32),
|
IndirectPCOffset(i32),
|
||||||
IndirectPCXRegOffset(XRegister, i32, u8, Size),
|
IndirectPCXRegOffset(XRegister, i32, u8, Size),
|
||||||
@ -116,41 +125,49 @@ pub enum Instruction {
|
|||||||
BCLR(Target, Target, Size),
|
BCLR(Target, Target, Size),
|
||||||
BSET(Target, Target, Size),
|
BSET(Target, Target, Size),
|
||||||
BTST(Target, Target, Size),
|
BTST(Target, Target, Size),
|
||||||
|
BFCHG(Target, RegOrImmediate, RegOrImmediate),
|
||||||
|
BFCLR(Target, RegOrImmediate, RegOrImmediate),
|
||||||
|
BFEXTS(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||||
|
BFEXTU(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||||
|
BFFFO(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||||
|
BFINS(Register, Target, RegOrImmediate, RegOrImmediate),
|
||||||
|
BFSET(Target, RegOrImmediate, RegOrImmediate),
|
||||||
|
BFTST(Target, RegOrImmediate, RegOrImmediate),
|
||||||
BKPT(u8),
|
BKPT(u8),
|
||||||
|
|
||||||
CHK(Target, u8, Size),
|
CHK(Target, Register, Size),
|
||||||
CLR(Target, Size),
|
CLR(Target, Size),
|
||||||
CMP(Target, Target, Size),
|
CMP(Target, Target, Size),
|
||||||
CMPA(Target, u8, Size),
|
CMPA(Target, Register, Size),
|
||||||
|
|
||||||
DBcc(Condition, u8, i16),
|
DBcc(Condition, Register, i16),
|
||||||
DIV(Target, Target, Size, Sign),
|
DIV(Target, Target, Size, Sign),
|
||||||
|
|
||||||
EOR(Target, Target, Size),
|
EOR(Target, Target, Size),
|
||||||
EORtoCCR(u8),
|
EORtoCCR(u8),
|
||||||
EORtoSR(u16),
|
EORtoSR(u16),
|
||||||
EXG(Target, Target),
|
EXG(Target, Target),
|
||||||
EXT(u8, Size, Size),
|
EXT(Register, Size, Size),
|
||||||
|
|
||||||
ILLEGAL,
|
ILLEGAL,
|
||||||
|
|
||||||
JMP(Target),
|
JMP(Target),
|
||||||
JSR(Target),
|
JSR(Target),
|
||||||
|
|
||||||
LEA(Target, u8),
|
LEA(Target, Register),
|
||||||
LINK(u8, i16),
|
LINK(Register, i16),
|
||||||
LSd(Target, Target, Size, ShiftDirection),
|
LSd(Target, Target, Size, ShiftDirection),
|
||||||
|
|
||||||
MOVE(Target, Target, Size),
|
MOVE(Target, Target, Size),
|
||||||
MOVEA(Target, u8, Size),
|
MOVEA(Target, Register, Size),
|
||||||
MOVEfromSR(Target),
|
MOVEfromSR(Target),
|
||||||
MOVEtoSR(Target),
|
MOVEtoSR(Target),
|
||||||
MOVEfromCCR(Target),
|
MOVEfromCCR(Target),
|
||||||
MOVEtoCCR(Target),
|
MOVEtoCCR(Target),
|
||||||
MOVEC(Target, ControlRegister, Direction),
|
MOVEC(Target, ControlRegister, Direction),
|
||||||
MOVEM(Target, Size, Direction, u16),
|
MOVEM(Target, Size, Direction, u16),
|
||||||
MOVEP(u8, Target, Size, Direction),
|
MOVEP(Register, Target, Size, Direction),
|
||||||
MOVEQ(u8, u8),
|
MOVEQ(u8, Register),
|
||||||
MOVEUSP(Target, Direction),
|
MOVEUSP(Target, Direction),
|
||||||
MUL(Target, Target, Size, Sign),
|
MUL(Target, Target, Size, Sign),
|
||||||
|
|
||||||
@ -179,14 +196,14 @@ pub enum Instruction {
|
|||||||
Scc(Condition, Target),
|
Scc(Condition, Target),
|
||||||
STOP(u16),
|
STOP(u16),
|
||||||
SUB(Target, Target, Size),
|
SUB(Target, Target, Size),
|
||||||
SWAP(u8),
|
SWAP(Register),
|
||||||
|
|
||||||
TAS(Target),
|
TAS(Target),
|
||||||
TST(Target, Size),
|
TST(Target, Size),
|
||||||
TRAP(u8),
|
TRAP(u8),
|
||||||
TRAPV,
|
TRAPV,
|
||||||
|
|
||||||
UNLK(u8),
|
UNLK(Register),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -686,14 +703,44 @@ impl M68kDecoder {
|
|||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
let target = self.decode_lower_effective_address(memory, ins, Some(Size::Word))?;
|
let target = self.decode_lower_effective_address(memory, ins, Some(Size::Word))?;
|
||||||
let count = Target::Immediate(1);
|
|
||||||
|
|
||||||
match (ins & 0x0600) >> 9 {
|
let count = Target::Immediate(1);
|
||||||
0b00 => Ok(Instruction::ASd(count, target, Size::Word, dir)),
|
if (ins & 0x800) == 0 {
|
||||||
0b01 => Ok(Instruction::LSd(count, target, Size::Word, dir)),
|
match (ins & 0x0600) >> 9 {
|
||||||
0b10 => Ok(Instruction::ROXd(count, target, Size::Word, dir)),
|
0b00 => Ok(Instruction::ASd(count, target, Size::Word, dir)),
|
||||||
0b11 => Ok(Instruction::ROd(count, target, Size::Word, dir)),
|
0b01 => Ok(Instruction::LSd(count, target, Size::Word, dir)),
|
||||||
_ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
0b10 => Ok(Instruction::ROXd(count, target, Size::Word, dir)),
|
||||||
|
0b11 => Ok(Instruction::ROd(count, target, Size::Word, dir)),
|
||||||
|
_ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||||
|
}
|
||||||
|
} else if self.cputype > M68kType::MC68020 {
|
||||||
|
// Bitfield instructions (MC68020+)
|
||||||
|
let ext = self.read_instruction_word(memory)?;
|
||||||
|
let reg = ((ext & 0x7000) >> 12) as u8;
|
||||||
|
|
||||||
|
let offset = match (ext & 0x0800) == 0 {
|
||||||
|
true => RegOrImmediate::Immediate(((ext & 0x07C0) >> 6) as u8),
|
||||||
|
false => RegOrImmediate::DReg(((ext & 0x01C0) >> 6) as u8),
|
||||||
|
};
|
||||||
|
|
||||||
|
let width = match (ext & 0x0020) == 0 {
|
||||||
|
true => RegOrImmediate::Immediate((ext & 0x001F) as u8),
|
||||||
|
false => RegOrImmediate::DReg((ext & 0x0007) as u8),
|
||||||
|
};
|
||||||
|
|
||||||
|
match (ins & 0x0700) >> 8 {
|
||||||
|
0b010 => Ok(Instruction::BFCHG(target, offset, width)),
|
||||||
|
0b100 => Ok(Instruction::BFCLR(target, offset, width)),
|
||||||
|
0b011 => Ok(Instruction::BFEXTS(target, offset, width, reg)),
|
||||||
|
0b001 => Ok(Instruction::BFEXTU(target, offset, width, reg)),
|
||||||
|
0b101 => Ok(Instruction::BFFFO(target, offset, width, reg)),
|
||||||
|
0b111 => Ok(Instruction::BFINS(reg, target, offset, width)),
|
||||||
|
0b110 => Ok(Instruction::BFSET(target, offset, width)),
|
||||||
|
0b000 => Ok(Instruction::BFTST(target, offset, width)),
|
||||||
|
_ => return Err(Error::processor(Exceptions::IllegalInstruction as u32)),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::processor(Exceptions::IllegalInstruction as u32));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -732,7 +779,7 @@ impl M68kDecoder {
|
|||||||
let xreg = if (brief_extension & 0x8000) == 0 { XRegister::Data(xreg_num) } else { XRegister::Address(xreg_num) };
|
let xreg = if (brief_extension & 0x8000) == 0 { XRegister::Data(xreg_num) } else { XRegister::Address(xreg_num) };
|
||||||
let size = if (brief_extension & 0x0800) == 0 { Size::Word } else { Size::Long };
|
let size = if (brief_extension & 0x0800) == 0 { Size::Word } else { Size::Long };
|
||||||
let scale = ((brief_extension & 0x0600) >> 9) as u8;
|
let scale = ((brief_extension & 0x0600) >> 9) as u8;
|
||||||
let use_full = (brief_extension & 0x0100) == 1;
|
let use_full = (brief_extension & 0x0100) != 0;
|
||||||
|
|
||||||
if !use_full {
|
if !use_full {
|
||||||
let displacement = sign_extend_to_long((brief_extension & 0x00FF) as u32, Size::Byte);
|
let displacement = sign_extend_to_long((brief_extension & 0x00FF) as u32, Size::Byte);
|
||||||
@ -1062,7 +1109,10 @@ impl fmt::Display for Instruction {
|
|||||||
Direction::ToTarget => write!(f, "movem{}\t{}, {}", size, fmt_movem_mask(*mask), target),
|
Direction::ToTarget => write!(f, "movem{}\t{}, {}", size, fmt_movem_mask(*mask), target),
|
||||||
Direction::FromTarget => write!(f, "movem{}\t{}, {}", size, target, fmt_movem_mask(*mask)),
|
Direction::FromTarget => write!(f, "movem{}\t{}, {}", size, target, fmt_movem_mask(*mask)),
|
||||||
},
|
},
|
||||||
//Instruction::MOVEP(reg, target, size, dir),
|
Instruction::MOVEP(reg, target, size, dir) => match dir {
|
||||||
|
Direction::ToTarget => write!(f, "movep{}\t%d{}, {}", size, reg, target),
|
||||||
|
Direction::FromTarget => write!(f, "movep{}\t{}, %d{}", size, target, reg),
|
||||||
|
},
|
||||||
Instruction::MOVEQ(value, reg) => write!(f, "moveq\t#{:02x}, %d{}", value, reg),
|
Instruction::MOVEQ(value, reg) => write!(f, "moveq\t#{:02x}, %d{}", value, reg),
|
||||||
Instruction::MOVEUSP(target, dir) => match dir {
|
Instruction::MOVEUSP(target, dir) => match dir {
|
||||||
Direction::ToTarget => write!(f, "movel\t%usp, {}", target),
|
Direction::ToTarget => write!(f, "movel\t%usp, {}", target),
|
||||||
|
@ -12,7 +12,9 @@ use super::decode::{
|
|||||||
Condition,
|
Condition,
|
||||||
ShiftDirection,
|
ShiftDirection,
|
||||||
ControlRegister,
|
ControlRegister,
|
||||||
|
Register,
|
||||||
XRegister,
|
XRegister,
|
||||||
|
RegOrImmediate,
|
||||||
sign_extend_to_long
|
sign_extend_to_long
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,7 +80,9 @@ impl M68k {
|
|||||||
Status::Running => {
|
Status::Running => {
|
||||||
match self.cycle_one(system) {
|
match self.cycle_one(system) {
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(Error { err: ErrorType::Processor, native, .. }) => {
|
//Err(Error { err: ErrorType::Processor, native, .. }) => {
|
||||||
|
// TODO temporary: we are passing illegal instructions upward in order to fix them
|
||||||
|
Err(Error { err: ErrorType::Processor, native, .. }) if native != Exceptions::IllegalInstruction as u32 => {
|
||||||
self.exception(system, native as u8)?;
|
self.exception(system, native as u8)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
@ -152,8 +156,6 @@ impl M68k {
|
|||||||
|
|
||||||
if self.debugger.use_tracing {
|
if self.debugger.use_tracing {
|
||||||
self.decoder.dump_decoded(system);
|
self.decoder.dump_decoded(system);
|
||||||
// TODO for debugging temporarily
|
|
||||||
self.dump_state(system);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.debugger.use_debugger {
|
if self.debugger.use_debugger {
|
||||||
@ -249,6 +251,65 @@ impl M68k {
|
|||||||
value = value | mask;
|
value = value | mask;
|
||||||
self.set_target_value(system, target, value, size)?;
|
self.set_target_value(system, target, value, size)?;
|
||||||
},
|
},
|
||||||
|
Instruction::BFCHG(target, offset, width) => {
|
||||||
|
let (offset, width) = self.get_bit_field_args(offset, width);
|
||||||
|
let mask = get_bit_field_mask(offset, width);
|
||||||
|
let value = self.get_target_value(system, target, Size::Long)?;
|
||||||
|
let field = value & mask;
|
||||||
|
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
|
||||||
|
self.set_target_value(system, target, (value & !mask) | (!field & mask), Size::Long)?;
|
||||||
|
},
|
||||||
|
Instruction::BFCLR(target, offset, width) => {
|
||||||
|
let (offset, width) = self.get_bit_field_args(offset, width);
|
||||||
|
let mask = get_bit_field_mask(offset, width);
|
||||||
|
let value = self.get_target_value(system, target, Size::Long)?;
|
||||||
|
let field = value & mask;
|
||||||
|
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
|
||||||
|
self.set_target_value(system, target, value & !mask, Size::Long)?;
|
||||||
|
},
|
||||||
|
Instruction::BFEXTS(target, offset, width, reg) => {
|
||||||
|
let (offset, width) = self.get_bit_field_args(offset, width);
|
||||||
|
let mask = get_bit_field_mask(offset, width);
|
||||||
|
let value = self.get_target_value(system, target, Size::Long)?;
|
||||||
|
let field = value & mask;
|
||||||
|
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
|
||||||
|
|
||||||
|
let right_offset = 32 - offset - width;
|
||||||
|
let mut ext = 0;
|
||||||
|
for i in 0..(offset + right_offset) {
|
||||||
|
ext = (ext >> 1) | 0x80000000;
|
||||||
|
}
|
||||||
|
self.state.d_reg[reg as usize] = (field >> right_offset) | ext;
|
||||||
|
},
|
||||||
|
Instruction::BFEXTU(target, offset, width, reg) => {
|
||||||
|
let (offset, width) = self.get_bit_field_args(offset, width);
|
||||||
|
let mask = get_bit_field_mask(offset, width);
|
||||||
|
let value = self.get_target_value(system, target, Size::Long)?;
|
||||||
|
let field = value & mask;
|
||||||
|
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
|
||||||
|
self.state.d_reg[reg as usize] = field >> (32 - offset - width);
|
||||||
|
},
|
||||||
|
//Instruction::BFFFO(target, offset, width, reg) => {
|
||||||
|
//},
|
||||||
|
//Instruction::BFINS(reg, target, offset, width) => {
|
||||||
|
//},
|
||||||
|
Instruction::BFSET(target, offset, width) => {
|
||||||
|
let (offset, width) = self.get_bit_field_args(offset, width);
|
||||||
|
let mask = get_bit_field_mask(offset, width);
|
||||||
|
let value = self.get_target_value(system, target, Size::Long)?;
|
||||||
|
let field = value & mask;
|
||||||
|
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
|
||||||
|
self.set_target_value(system, target, value | mask, Size::Long)?;
|
||||||
|
},
|
||||||
|
Instruction::BFTST(target, offset, width) => {
|
||||||
|
let (offset, width) = self.get_bit_field_args(offset, width);
|
||||||
|
let mask = get_bit_field_mask(offset, width);
|
||||||
|
let value = self.get_target_value(system, target, Size::Long)?;
|
||||||
|
let field = value & mask;
|
||||||
|
self.set_bit_field_test_flags(field, get_bit_field_msb(offset));
|
||||||
|
},
|
||||||
|
//Instruction::BKPT(u8) => {
|
||||||
|
//},
|
||||||
Instruction::CLR(target, size) => {
|
Instruction::CLR(target, size) => {
|
||||||
self.set_target_value(system, target, 0, size)?;
|
self.set_target_value(system, target, 0, size)?;
|
||||||
// Clear flags except Zero flag
|
// Clear flags except Zero flag
|
||||||
@ -722,6 +783,22 @@ impl M68k {
|
|||||||
Ok(addr)
|
Ok(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_bit_field_args(&self, offset: RegOrImmediate, width: RegOrImmediate) -> (u32, u32) {
|
||||||
|
let offset = self.get_reg_or_immediate(offset);
|
||||||
|
let mut width = self.get_reg_or_immediate(width) % 32;
|
||||||
|
if width == 0 {
|
||||||
|
width = 32;
|
||||||
|
}
|
||||||
|
(offset, width)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_reg_or_immediate(&self, value: RegOrImmediate) -> u32 {
|
||||||
|
match value {
|
||||||
|
RegOrImmediate::DReg(reg) => self.state.d_reg[reg as usize],
|
||||||
|
RegOrImmediate::Immediate(value) => value as u32,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_control_reg_mut(&mut self, control_reg: ControlRegister) -> &mut u32 {
|
fn get_control_reg_mut(&mut self, control_reg: ControlRegister) -> &mut u32 {
|
||||||
match control_reg {
|
match control_reg {
|
||||||
ControlRegister::VBR => &mut self.state.vbr,
|
ControlRegister::VBR => &mut self.state.vbr,
|
||||||
@ -734,7 +811,7 @@ impl M68k {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_a_reg_mut(&mut self, reg: u8) -> &mut u32 {
|
fn get_a_reg_mut(&mut self, reg: Register) -> &mut u32 {
|
||||||
if reg == 7 {
|
if reg == 7 {
|
||||||
if self.is_supervisor() { &mut self.state.msp } else { &mut self.state.usp }
|
if self.is_supervisor() { &mut self.state.msp } else { &mut self.state.usp }
|
||||||
} else {
|
} else {
|
||||||
@ -809,6 +886,16 @@ impl M68k {
|
|||||||
mask
|
mask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_bit_field_test_flags(&mut self, field: u32, msb_mask: u32) {
|
||||||
|
let mut flags = 0x0000;
|
||||||
|
if (field & msb_mask) != 0 {
|
||||||
|
flags |= Flags::Negative as u16;
|
||||||
|
}
|
||||||
|
if field == 0 {
|
||||||
|
flags |= Flags::Zero as u16;
|
||||||
|
}
|
||||||
|
self.state.sr = (self.state.sr & 0xFFF0) | flags;
|
||||||
|
}
|
||||||
|
|
||||||
fn get_current_condition(&self, cond: Condition) -> bool {
|
fn get_current_condition(&self, cond: Condition) -> bool {
|
||||||
match cond {
|
match cond {
|
||||||
@ -959,3 +1046,16 @@ fn get_msb_mask(value: u32, size: Size) -> u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_bit_field_mask(offset: u32, width: u32) -> u32 {
|
||||||
|
let mut mask = 0;
|
||||||
|
for i in 0..width {
|
||||||
|
mask = (mask >> 1) | 0x80000000;
|
||||||
|
}
|
||||||
|
mask >> offset
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_bit_field_msb(offset: u32) -> u32 {
|
||||||
|
0x80000000 >> offset
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
17
todo.txt
17
todo.txt
@ -1,22 +1,19 @@
|
|||||||
|
|
||||||
* can you make Bus be an AddressableDeviceBox so that the CPU can have a ref to it instead of calling system.get_bus()
|
* can you eventually make the system connections all configurable via a config file?
|
||||||
the alternative is having system.get_bus() take an argument or something to figure out what bus to return of multiple, for multibus systems
|
|
||||||
* can you eventually make this all configurable via a config file?
|
|
||||||
|
|
||||||
* test using mpsc to pass messages with the tty IO thread, and test if it's slower than what you have now
|
* test using mpsc to pass messages with the tty IO thread, and test if it's slower than what you have now
|
||||||
|
|
||||||
* make it possible to break out of the current execution, into the debugger, by using a certain keystroke
|
* 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 MC68020+ indexing modes, implement the full extension word for MC68020+
|
||||||
* add support for FPU
|
|
||||||
* make tests for each instruction
|
* make tests for each instruction
|
||||||
|
|
||||||
* unimplemented: ABCD, ADDX, BKPT, CHK, EXG, ILLEGAL, MOVEfromCCR, MOVEP, RTR, RTD, SBCD, SUBX
|
* unimplemented: ABCD, ADDX, BFFFO, BFINS, BKPT, CHK, EXG, ILLEGAL, MOVEfromCCR, MOVEP, RTR, RTD, SBCD, SUBX
|
||||||
* undecoded: ADDX, SUBX
|
* undecoded: ADDX, SUBX
|
||||||
* modify execution for >=MC68020: DIVSL, DIVUL, 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 undecoded & unimplemented: CALLM, CAS, CAS2, CHK2, CMP2, PACK
|
||||||
|
|
||||||
* >=MC68020 instructions: BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, CALLM, CAS, CAS2, CHK2, CMP2, PACK
|
* add support for MMU
|
||||||
|
* add support for FPU
|
||||||
* Coprocessor instructions: cpBcc, cpDBcc, cpGEN, cpScc, cpTRAPcc
|
* Coprocessor instructions: cpBcc, cpDBcc, cpGEN, cpScc, cpTRAPcc
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user