Completed most of the instruction decode

This commit is contained in:
transistor 2021-09-29 12:24:04 -07:00
parent 6a4f53ca2b
commit f22aa23dfa
2 changed files with 523 additions and 68 deletions

View File

@ -43,6 +43,22 @@ enum Sign {
Unsigned,
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum Direction {
FromTarget,
ToTarget,
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum ShiftDirection {
Right,
Left,
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum ControlRegister {
VBR,
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum Size {
Byte,
@ -52,18 +68,22 @@ enum Size {
#[derive(Copy, Clone, Debug, PartialEq)]
enum Condition {
True,
False,
High,
LowOrSame,
CarryClear,
CarrySet,
Equal,
NotEqual,
GreaterThanOrEqual,
GreaterThan,
LessThanOrEqual,
LessThan,
Minus,
Plus,
Equal,
OverflowClear,
OverflowSet,
Plus,
Minus,
GreaterThanOrEqual,
LessThan,
GreaterThan,
LessThanOrEqual,
}
#[derive(Clone, Debug, PartialEq)]
@ -75,22 +95,28 @@ enum Target {
IndirectARegInc(u8),
IndirectARegDec(u8),
IndirectARegOffset(u8, u16),
IndirectARegDRegOffset(u8, u8, u16),
IndirectARegXRegOffset(u8, Box<Target>, u16, Size),
IndirectMemory(u32),
IndirectPCOffset(u16),
IndirectPCRegOffset(u8, u16),
IndirectPCXRegOffset(Box<Target>, u16, Size),
}
#[derive(Clone, Debug, PartialEq)]
enum Instruction {
//ABCD
ADD(Target, Target, Size),
AND(Target, Target, Size),
ANDCCR(u8),
ANDSR(u16),
ANDtoCCR(u8),
ANDtoSR(u16),
ASd(Target, Target, Size, ShiftDirection),
Bcc(Condition, u16),
BRA(u16),
BSR(u16),
BTST(Target, Target, Size),
BCHG(Target, Target, Size),
BCLR(Target, Target, Size),
BSET(Target, Target, Size),
CLR(Target, Size),
CMP(Target, Target, Size),
@ -98,16 +124,70 @@ enum Instruction {
DBcc(Condition, u16),
DIV(Target, Target, Size, Sign),
LEA(Target, u8),
JSR(Target),
EOR(Target, Target, Size),
EORtoCCR(u8),
EORtoSR(u16),
EXG(Target, Target),
EXT(u8, Size),
ILLEGAL,
JMP(Target),
JSR(Target),
LEA(Target, u8),
LINK(u8, u16),
LSd(Target, Target, Size, ShiftDirection),
MOVE(Target, Target, Size),
MOVEfromSR(Target),
MOVEtoSR(Target),
MOVEtoCCR(Target),
MOVEC(Target, ControlRegister, Direction),
MOVEUSP(Target, Direction),
MOVEM(Target, Size, Direction, u16),
MOVEQ(u8, u8),
MUL(Target, Target, Size, Sign),
NBCD(Target),
NEG(Target, Size),
NEGX(Target, Size),
NOP,
NOT(Target, Size),
OR(Target, Target, Size),
ORtoCCR(u8),
ORtoSR(u16),
PEA(Target),
RESET,
ROd(Target, Target, Size, ShiftDirection),
ROXd(Target, Target, Size, ShiftDirection),
RTE,
RTR,
RTS,
//SBCD
//Scc
STOP(u16),
SUB(Target, Target, Size),
SWAP(u8),
TAS(Target),
TST(Target, Size),
TRAP(u8),
TRAPV,
UNLK(u8),
}
const OPCG_BIT_OPS: u8 = 0x0;
const OPCG_MOVE_BYTE: u8 = 0x1;
const OPCG_MOVE_WORD: u8 = 0x2;
const OPCG_MOVE_LONG: u8 = 0x3;
const OPCG_MOVE_LONG: u8 = 0x2;
const OPCG_MOVE_WORD: u8 = 0x3;
const OPCG_MISC: u8 = 0x04;
const OPCG_ADDQ_SUBQ: u8 = 0x5;
const OPCG_BRANCH: u8 = 0x6;
@ -116,7 +196,7 @@ const OPCG_DIV_OR: u8 = 0x8;
const OPCG_SUB: u8 = 0x9;
const OPCG_RESERVED1: u8 = 0xA;
const OPCG_CMP_EOR: u8 = 0xB;
const OPCG_MUL_EXCH: u8 = 0xC;
const OPCG_MUL_AND: u8 = 0xC;
const OPCG_ADD: u8 = 0xD;
const OPCG_SHIFT: u8 = 0xE;
const OPCG_RESERVED2: u8 = 0xF;
@ -195,14 +275,18 @@ impl MC68010 {
}
fn execute_one(&mut self, space: &mut AddressSpace) -> Result<(), Error> {
let addr = self.pc;
let ins = self.decode_one(space)?;
println!("{:08x}: {:?}", addr, ins);
match ins {
/*
Instruction::JSR(target) => {
self.push_long(space, self.pc)?;
self.pc = self.get_target_value(space, target)?;
},
_ => panic!(""),
*/
_ => { /* panic!(""); */ },
}
Ok(())
@ -221,105 +305,423 @@ impl MC68010 {
match ((ins & 0xF000) >> 12) as u8 {
OPCG_BIT_OPS => {
panic!("");
let optype = (ins & 0x0F00) >> 8;
if (ins & 0x3F) == 0b111100 {
match (ins & 0x00C0) >> 6 {
0b00 => {
let data = self.read_instruction_word(space)?;
match optype {
0b0000 => Ok(Instruction::ORtoCCR(data as u8)),
0b0001 => Ok(Instruction::ANDtoCCR(data as u8)),
0b1010 => Ok(Instruction::EORtoCCR(data as u8)),
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
},
0b01 => {
let data = self.read_instruction_word(space)?;
match optype {
0b0000 => Ok(Instruction::ORtoSR(data)),
0b0001 => Ok(Instruction::ANDtoSR(data)),
0b1010 => Ok(Instruction::EORtoSR(data)),
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
},
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
} else if (ins & 0x0100) == 0x0100 || (ins & 0x0F00) == 0x0800 {
let bitnum = if (ins & 0x0100) == 0x0100 {
Target::DirectDReg(get_high_reg(ins))
} else {
Target::Immediate(self.read_instruction_word(space)? as u32)
};
let target = self.decode_lower_effective_address(space, ins, Some(Size::Byte))?;
let size = match target {
Target::DirectAReg(_) | Target::DirectDReg(_) => Size::Long,
_ => Size::Byte,
};
match (ins & 0x00C0) >> 6 {
0b00 => Ok(Instruction::BTST(bitnum, target, size)),
0b01 => Ok(Instruction::BCHG(bitnum, target, size)),
0b10 => Ok(Instruction::BCLR(bitnum, target, size)),
0b11 => Ok(Instruction::BSET(bitnum, target, size)),
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
} else {
let size = get_size(ins);
let target = self.decode_lower_effective_address(space, ins, size)?;
let data = match size {
Some(Size::Long) => self.read_instruction_long(space)?,
Some(size) => self.read_instruction_word(space)? as u32,
None => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
};
match optype {
0b0000 => Ok(Instruction::OR(Target::Immediate(data), target, size.unwrap())),
0b0010 => Ok(Instruction::AND(Target::Immediate(data), target, size.unwrap())),
0b0100 => Ok(Instruction::SUB(Target::Immediate(data), target, size.unwrap())),
0b0110 => Ok(Instruction::ADD(Target::Immediate(data), target, size.unwrap())),
0b1010 => Ok(Instruction::EOR(Target::Immediate(data), target, size.unwrap())),
0b1100 => Ok(Instruction::CMP(Target::Immediate(data), target, size.unwrap())),
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
}
},
OPCG_MOVE_BYTE => {
let data = self.read_instruction_word(space)?;
panic!("");
},
OPCG_MOVE_WORD => {
let data = self.read_instruction_word(space)?;
panic!("");
let src = self.decode_lower_effective_address(space, ins, Some(Size::Byte))?;
let dest = self.decode_upper_effective_address(space, ins, Some(Size::Byte))?;
Ok(Instruction::MOVE(src, dest, Size::Byte))
},
OPCG_MOVE_LONG => {
let data = self.read_instruction_long(space)?;
panic!("");
let src = self.decode_lower_effective_address(space, ins, Some(Size::Long))?;
let dest = self.decode_upper_effective_address(space, ins, Some(Size::Long))?;
Ok(Instruction::MOVE(src, dest, Size::Long))
},
OPCG_MOVE_WORD => {
let src = self.decode_lower_effective_address(space, ins, Some(Size::Word))?;
let dest = self.decode_upper_effective_address(space, ins, Some(Size::Word))?;
Ok(Instruction::MOVE(src, dest, Size::Word))
},
OPCG_MISC => {
if (ins & 0b111000000) == 0b111000000 {
// LEA Instruction
debug!("LEA");
let src = self.decode_lower_effective_address(space, ins)?;
if (ins & 0b000101000000) == 0b000100000000 {
// CHK Instruction
panic!("Not Implemented");
} else if (ins & 0b000111000000) == 0b000111000000 {
let src = self.decode_lower_effective_address(space, ins, None)?;
let dest = get_high_reg(ins);
Ok(Instruction::LEA(src, dest))
} else if (ins & 0b101000000) == 0b100000000 {
// CHK Instruction
panic!("");
} else if (ins & 0b101110000000) == 0b100010000000 {
// MOVEM Instruction
panic!("");
let target = self.decode_lower_effective_address(space, ins, None)?;
let data = self.read_instruction_word(space)?;
let size = if (ins & 0x0040) == 0 { Size::Word } else { Size::Long };
let dir = if (ins & 0x0200) == 0 { Direction::ToTarget } else { Direction::FromTarget };
Ok(Instruction::MOVEM(target, size, dir, data))
} else if (ins & 0b100000000000) == 0 {
let target = self.decode_lower_effective_address(space, ins, Some(Size::Word))?;
match (ins & 0x0700) >> 8 {
0b000 => {
match get_size(ins) {
Some(size) => Ok(Instruction::NEGX(target, size)),
None => Ok(Instruction::MOVEfromSR(target)),
}
},
0b010 => {
match get_size(ins) {
Some(size) => Ok(Instruction::CLR(target, size)),
None => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
},
0b100 => {
match get_size(ins) {
Some(size) => Ok(Instruction::NEG(target, size)),
None => Ok(Instruction::MOVEtoCCR(target)),
}
},
0b110 => {
match get_size(ins) {
Some(size) => Ok(Instruction::NOT(target, size)),
None => Ok(Instruction::MOVEtoSR(target)),
}
},
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
} else if (ins & 0b111100000000) == 0b101000000000 {
let target = self.decode_lower_effective_address(space, ins, Some(Size::Word))?;
match get_size(ins) {
Some(size) => Ok(Instruction::TST(target, size)),
None => Ok(Instruction::TAS(target)),
}
} else if (ins & 0b111100000000) == 0b100000000000 {
let subselect = (ins & 0x01C0) >> 6;
let mode = get_low_mode(ins);
match (subselect, mode) {
(0b010, 0b000) => {
Ok(Instruction::EXT(get_low_reg(ins), Size::Word))
},
(0b011, 0b000) => {
Ok(Instruction::EXT(get_low_reg(ins), Size::Long))
},
(0b000, mode) => {
let target = self.decode_lower_effective_address(space, ins, Some(Size::Byte))?;
Ok(Instruction::NBCD(target))
},
(0b001, 0b000) => {
Ok(Instruction::SWAP(get_low_reg(ins)))
},
(0b001, mode) => {
let target = self.decode_lower_effective_address(space, ins, None)?;
Ok(Instruction::PEA(target))
},
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
} else if (ins & 0b111110000000) == 0b111010000000 {
// JMP/JSR Instruction
let target = self.decode_lower_effective_address(space, ins)?;
let target = self.decode_lower_effective_address(space, ins, None)?;
if (ins & 0b01000000) == 0 {
Ok(Instruction::JSR(target))
} else {
Ok(Instruction::JMP(target))
}
} else if (ins & 0b111111110000) == 0b111001010000 {
let reg = get_low_reg(ins);
if (ins & 0b1000) == 0 {
let data = self.read_instruction_word(space)?;
Ok(Instruction::LINK(reg, data))
} else {
Ok(Instruction::UNLK(reg))
}
} else if (ins & 0b111111110000) == 0b111001100000 {
let reg = get_low_reg(ins);
let dir = if (ins & 0b1000) == 0 { Direction::FromTarget } else { Direction::ToTarget };
Ok(Instruction::MOVEUSP(Target::DirectAReg(reg), dir))
} else {
panic!("");
match ins & 0x0FFF {
0xAFC => Ok(Instruction::ILLEGAL),
0xE70 => Ok(Instruction::RESET),
0xE71 => Ok(Instruction::NOP),
0xE72 => {
let data = self.read_instruction_word(space)?;
Ok(Instruction::STOP(data))
},
0xE73 => Ok(Instruction::RTE),
0xE75 => Ok(Instruction::RTS),
0xE76 => Ok(Instruction::TRAPV),
0xE77 => Ok(Instruction::RTR),
0xE7A | 0xE7B => {
let dir = if ins & 0x01 == 0 { Direction::ToTarget } else { Direction::FromTarget };
let ins2 = self.read_instruction_word(space)?;
let target = match ins2 & 0x8000 {
0 => Target::DirectDReg(((ins2 & 0x7000) >> 12) as u8),
_ => Target::DirectAReg(((ins2 & 0x7000) >> 12) as u8),
};
let creg = match ins2 & 0xFFF {
0x801 => ControlRegister::VBR,
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
};
Ok(Instruction::MOVEC(target, creg, dir))
},
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
}
},
OPCG_ADDQ_SUBQ => {
let size = match get_size(ins) {
Some(size) => size,
None => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
};
panic!("");
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
let mut data = ((ins & 0x0E00) >> 9) as u32;
if data == 0 {
data = 8;
}
if (ins & 0x0100) == 0 {
Ok(Instruction::ADD(Target::Immediate(data), target, size))
} else {
Ok(Instruction::SUB(Target::Immediate(data), target, size))
}
},
OPCG_BRANCH => {
panic!("");
let mut disp = (ins & 0xFF);
if disp == 0 {
disp = self.read_instruction_word(space)?;
}
let condition = get_condition(ins);
match condition {
Condition::True => Ok(Instruction::BRA(disp)),
Condition::False => Ok(Instruction::BSR(disp)),
_ => Ok(Instruction::Bcc(condition, disp)),
}
},
OPCG_MOVEQ => {
panic!("");
// TODO make sure the 9th bit is 0
let reg = get_high_reg(ins);
let data = (ins & 0xFF) as u8;
Ok(Instruction::MOVEQ(data, reg))
},
OPCG_DIV_OR => {
let size = get_size(ins);
panic!("");
if size.is_none() {
let sign = if (ins & 0x0100) == 0 { Sign::Unsigned } else { Sign::Signed };
let data_reg = Target::DirectDReg(get_high_reg(ins));
let effective_addr = self.decode_lower_effective_address(space, ins, size)?;
Ok(Instruction::DIV(effective_addr, data_reg, Size::Word, sign))
} else if (ins & 0b000111110000) == 0b000100000000 {
// TODO SBCD
panic!("Not Implemented");
} else {
let data_reg = Target::DirectDReg(get_high_reg(ins));
let effective_addr = self.decode_lower_effective_address(space, ins, size)?;
let (from, to) = if (ins & 0x0100) == 0 { (effective_addr, data_reg) } else { (data_reg, effective_addr) };
Ok(Instruction::OR(from, to, size.unwrap()))
}
},
OPCG_SUB => {
panic!("");
// TODO need to decode the SUBX instruction (would likely be erroneously decoded atm)
let reg = get_high_reg(ins);
let dir = (ins & 0x0100) >> 8;
let size = get_size(ins);
match size {
Some(size) => {
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
if dir == 0 {
Ok(Instruction::SUB(target, Target::DirectDReg(reg), size))
} else {
Ok(Instruction::SUB(Target::DirectDReg(reg), target, size))
}
},
None => {
let size = if dir == 0 { Size::Word } else { Size::Long };
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
Ok(Instruction::SUB(target, Target::DirectAReg(reg), size))
},
}
},
OPCG_CMP_EOR => {
panic!("");
let reg = get_high_reg(ins);
let optype = (ins & 0x0100) >> 8;
let size = get_size(ins);
match (optype, size) {
(0b1, Some(size)) => {
// TODO need to decode the CMPM instruction (mode == 0b001) (would likely be erroneously decoded atm)
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
Ok(Instruction::EOR(Target::DirectDReg(reg), target, size))
},
(0b0, Some(size)) => {
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
Ok(Instruction::CMP(Target::DirectDReg(reg), target, size))
},
(size, None) => {
let size = if optype == 0 { Size::Word } else { Size::Long };
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
Ok(Instruction::CMP(target, Target::DirectAReg(reg), size))
},
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
},
OPCG_MUL_EXCH => {
OPCG_MUL_AND => {
let size = get_size(ins);
panic!("");
if size.is_none() {
let sign = if (ins & 0x0100) == 0 { Sign::Unsigned } else { Sign::Signed };
let data_reg = Target::DirectDReg(get_high_reg(ins));
let effective_addr = self.decode_lower_effective_address(space, ins, size)?;
Ok(Instruction::MUL(effective_addr, data_reg, Size::Word, sign))
} else if (ins & 0b000111110000) == 0b000100000000 {
// TODO ABCD or EXG
panic!("Not Implemented");
} else {
let data_reg = Target::DirectDReg(get_high_reg(ins));
let effective_addr = self.decode_lower_effective_address(space, ins, size)?;
let (from, to) = if (ins & 0x0100) == 0 { (effective_addr, data_reg) } else { (data_reg, effective_addr) };
Ok(Instruction::AND(from, to, size.unwrap()))
}
},
OPCG_ADD => {
panic!("");
// TODO need to decode the ADDX instruction (would likely be erroneously decoded atm)
let reg = get_high_reg(ins);
let dir = (ins & 0x0100) >> 8;
let size = get_size(ins);
match size {
Some(size) => {
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
if dir == 0 {
Ok(Instruction::ADD(target, Target::DirectDReg(reg), size))
} else {
Ok(Instruction::ADD(Target::DirectDReg(reg), target, size))
}
},
None => {
let size = if dir == 0 { Size::Word } else { Size::Long };
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
Ok(Instruction::ADD(target, Target::DirectAReg(reg), size))
},
}
},
OPCG_SHIFT => {
let dir = if (ins & 0x0100) == 0 { ShiftDirection::Right } else { ShiftDirection::Left };
match get_size(ins) {
Some(size) => {
let reg = get_low_reg(ins);
let rotation = get_high_reg(ins);
let count = if (ins & 0x0020) == 0 {
Target::Immediate(rotation as u32)
} else {
Target::DirectDReg(rotation)
};
panic!("");
match (ins & 0x0018) >> 3 {
0b00 => Ok(Instruction::ASd(count, Target::DirectDReg(reg), size, dir)),
0b01 => Ok(Instruction::LSd(count, Target::DirectDReg(reg), size, dir)),
0b10 => Ok(Instruction::ROXd(count, Target::DirectDReg(reg), size, dir)),
0b11 => Ok(Instruction::ROd(count, Target::DirectDReg(reg), size, dir)),
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
},
None => {
let target = self.decode_lower_effective_address(space, ins, Some(Size::Word))?;
let count = Target::Immediate(1);
match (ins & 0x0600) >> 9 {
0b00 => Ok(Instruction::ASd(count, target, Size::Word, dir)),
0b01 => Ok(Instruction::LSd(count, target, Size::Word, dir)),
0b10 => Ok(Instruction::ROXd(count, target, Size::Word, dir)),
0b11 => Ok(Instruction::ROd(count, target, Size::Word, dir)),
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
},
}
},
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
}
fn decode_lower_effective_address(&mut self, space: &mut AddressSpace, ins: u16) -> Result<Target, Error> {
fn decode_lower_effective_address(&mut self, space: &mut AddressSpace, ins: u16, size: Option<Size>) -> Result<Target, Error> {
let reg = get_low_reg(ins);
let mode = get_mode(ins);
self.get_mode_as_target(space, mode, reg)
let mode = get_low_mode(ins);
self.get_mode_as_target(space, mode, reg, size)
}
fn get_mode_as_target(&mut self, space: &mut AddressSpace, mode: u8, reg: u8) -> Result<Target, Error> {
fn decode_upper_effective_address(&mut self, space: &mut AddressSpace, ins: u16, size: Option<Size>) -> Result<Target, Error> {
let reg = get_high_reg(ins);
let mode = get_high_mode(ins);
self.get_mode_as_target(space, mode, reg, size)
}
fn decode_brief_extension_word(&self, brief_extension: u16) -> (Target, u16, Size) {
let data = brief_extension & 0x00FF;
let reg = ((brief_extension & 0x7000) >> 12) as u8;
let size = if (brief_extension & 0x0800) == 0 { Size::Word } else { Size::Long };
let target = if (brief_extension & 0x8000) == 0 {
Target::DirectDReg(reg)
} else {
Target::DirectAReg(reg)
};
(target, data, size)
}
fn get_mode_as_target(&mut self, space: &mut AddressSpace, mode: u8, reg: u8, size: Option<Size>) -> Result<Target, Error> {
let value = match mode {
0b000 => Target::DirectDReg(reg),
0b001 => Target::DirectAReg(reg),
0b010 => Target::IndirectAReg(reg),
0b011 => Target::IndirectARegInc(reg),
0b100 => Target::IndirectARegDec(reg),
0b101 => {
let d16 = self.read_instruction_word(space)?;
Target::IndirectARegOffset(reg, d16)
},
0b110 => {
let brief_extension = self.read_instruction_word(space)?;
let (target, data, size) = self.decode_brief_extension_word(brief_extension);
Target::IndirectARegXRegOffset(reg, Box::new(target), data, size)
},
0b111 => {
match reg {
0b000 => {
@ -334,6 +736,19 @@ panic!("");
let d16 = self.read_instruction_word(space)?;
Target::IndirectPCOffset(d16)
},
0b011 => {
let brief_extension = self.read_instruction_word(space)?;
let (target, data, size) = self.decode_brief_extension_word(brief_extension);
Target::IndirectPCXRegOffset(Box::new(target), data, size)
},
0b100 => {
let data = match size {
Some(Size::Byte) | Some(Size::Word) => self.read_instruction_word(space)? as u32,
Some(Size::Long) => self.read_instruction_long(space)?,
None => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
};
Target::Immediate(data)
},
_ => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
}
},
@ -341,11 +756,12 @@ panic!("");
};
Ok(value)
}
}
#[inline(always)]
fn get_high_reg(ins: u16) -> u8 {
((ins & 0x0D00) >> 9) as u8
((ins & 0x0E00) >> 9) as u8
}
#[inline(always)]
@ -354,10 +770,49 @@ fn get_low_reg(ins: u16) -> u8 {
}
#[inline(always)]
fn get_mode(ins: u16) -> u8 {
fn get_high_mode(ins: u16) -> u8 {
((ins & 0x01C0) >> 6) as u8
}
#[inline(always)]
fn get_low_mode(ins: u16) -> u8 {
((ins & 0x0038) >> 3) as u8
}
#[inline(always)]
fn get_size(ins: u16) -> Option<Size> {
match (ins & 0x00C0) >> 6 {
0b00 => Some(Size::Byte),
0b01 => Some(Size::Word),
0b10 => Some(Size::Long),
_ => None,
}
}
#[inline(always)]
fn get_condition(ins: u16) -> Condition {
match (ins & 0x0F00) >> 8 {
0b0000 => Condition::True,
0b0001 => Condition::False,
0b0010 => Condition::High,
0b0011 => Condition::LowOrSame,
0b0100 => Condition::CarryClear,
0b0101 => Condition::CarrySet,
0b0110 => Condition::NotEqual,
0b0111 => Condition::Equal,
0b1000 => Condition::OverflowClear,
0b1001 => Condition::OverflowSet,
0b1010 => Condition::Plus,
0b1011 => Condition::Minus,
0b1100 => Condition::GreaterThanOrEqual,
0b1101 => Condition::LessThan,
0b1110 => Condition::GreaterThan,
0b1111 => Condition::LessThanOrEqual,
_ => Condition::True,
}
}
/*
impl Processor for MC68010 {

View File

@ -75,7 +75,7 @@ impl AddressSpace {
return Ok(&self.segments[i]);
}
}
return Err(Error::new("No segment found"));
return Err(Error::new(&format!("No segment found at {:08x}", addr)));
}
pub fn get_segment_mut(&mut self, addr: Address) -> Result<&mut Segment, Error> {
@ -84,7 +84,7 @@ impl AddressSpace {
return Ok(&mut self.segments[i]);
}
}
return Err(Error::new("No segment found"));
return Err(Error::new(&format!("No segment found at {:08x}", addr)));
}