mirror of
https://github.com/transistorfet/moa.git
synced 2024-11-21 19:30:52 +00:00
Fixed instruction decode for MOVEM and EXT
It's now possible to run the monitor program until it loops waiting for the serial transmitter to be ready for writing
This commit is contained in:
parent
e40663ee9a
commit
7868bc3014
@ -285,13 +285,7 @@ impl MC68010 {
|
||||
let src = self.decode_lower_effective_address(space, ins, None)?;
|
||||
let dest = get_high_reg(ins);
|
||||
Ok(Instruction::LEA(src, dest))
|
||||
} else if (ins & 0b101110000000) == 0b100010000000 {
|
||||
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 {
|
||||
} else if (ins & 0b100000000000) == 0b000000000000 {
|
||||
let target = self.decode_lower_effective_address(space, ins, Some(Size::Word))?;
|
||||
match (ins & 0x0700) >> 8 {
|
||||
0b000 => {
|
||||
@ -320,22 +314,22 @@ impl MC68010 {
|
||||
},
|
||||
_ => 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 & 0b101110000000) == 0b100010000000 {
|
||||
let mode = get_low_mode(ins);
|
||||
let size = if (ins & 0x0040) == 0 { Size::Word } else { Size::Long };
|
||||
|
||||
if mode == 0b000 {
|
||||
Ok(Instruction::EXT(get_low_reg(ins), size))
|
||||
} else {
|
||||
let target = self.decode_lower_effective_address(space, ins, None)?;
|
||||
let data = self.read_instruction_word(space)?;
|
||||
let dir = if (ins & 0x0200) == 0 { Direction::ToTarget } else { Direction::FromTarget };
|
||||
Ok(Instruction::MOVEM(target, size, dir, data))
|
||||
}
|
||||
} 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, _) => {
|
||||
let target = self.decode_lower_effective_address(space, ins, Some(Size::Byte))?;
|
||||
Ok(Instruction::NBCD(target))
|
||||
@ -349,6 +343,12 @@ impl MC68010 {
|
||||
},
|
||||
_ => 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 & 0b111110000000) == 0b111010000000 {
|
||||
let target = self.decode_lower_effective_address(space, ins, None)?;
|
||||
if (ins & 0b01000000) == 0 {
|
||||
|
@ -32,6 +32,8 @@ pub struct MC68010 {
|
||||
|
||||
pub current_instruction_addr: u32,
|
||||
pub current_instruction: Instruction,
|
||||
pub breakpoint: u32,
|
||||
pub use_debugger: bool,
|
||||
}
|
||||
|
||||
const FLAGS_ON_RESET: u16 = 0x2700;
|
||||
@ -62,6 +64,8 @@ impl MC68010 {
|
||||
|
||||
current_instruction_addr: 0,
|
||||
current_instruction: Instruction::NOP,
|
||||
breakpoint: 0,
|
||||
use_debugger: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +82,8 @@ impl MC68010 {
|
||||
|
||||
self.current_instruction_addr = 0;
|
||||
self.current_instruction = Instruction::NOP;
|
||||
self.breakpoint = 0;
|
||||
self.use_debugger = false;
|
||||
}
|
||||
|
||||
pub fn is_running(&self) -> bool {
|
||||
@ -94,6 +100,10 @@ impl MC68010 {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_breakpoint(&mut self, addr: Address) {
|
||||
self.breakpoint = addr as u32;
|
||||
}
|
||||
|
||||
pub fn step(&mut self, space: &mut AddressSpace) -> Result<(), Error> {
|
||||
match self.state {
|
||||
State::Init => self.init(space),
|
||||
@ -146,19 +156,23 @@ impl MC68010 {
|
||||
self.current_instruction_addr = self.pc;
|
||||
self.current_instruction = self.decode_one(space)?;
|
||||
|
||||
/*
|
||||
// Print instruction bytes for debugging
|
||||
let ins_data: Result<String, Error> =
|
||||
(0..((self.pc - current_ins_addr) / 2)).map(|offset|
|
||||
Ok(format!("{:04x} ", space.read_beu16((current_ins_addr + (offset * 2)) as Address)?))
|
||||
).collect();
|
||||
debug!("{:#010x}: {}\n\t{:?}\n", current_ins_addr, ins_data?, ins);
|
||||
if self.breakpoint == self.current_instruction_addr {
|
||||
self.use_debugger = true;
|
||||
}
|
||||
|
||||
// Single Step
|
||||
self.dump_state();
|
||||
let mut buffer = String::new();
|
||||
std::io::stdin().read_line(&mut buffer).unwrap();
|
||||
*/
|
||||
if self.use_debugger {
|
||||
// Print instruction bytes for debugging
|
||||
let ins_data: Result<String, Error> =
|
||||
(0..((self.pc - self.current_instruction_addr) / 2)).map(|offset|
|
||||
Ok(format!("{:04x} ", space.read_beu16((self.current_instruction_addr + (offset * 2)) as Address)?))
|
||||
).collect();
|
||||
debug!("{:#010x}: {}\n\t{:?}\n", self.current_instruction_addr, ins_data?, self.current_instruction);
|
||||
|
||||
// Single Step
|
||||
self.dump_state(space);
|
||||
let mut buffer = String::new();
|
||||
std::io::stdin().read_line(&mut buffer).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -236,8 +250,10 @@ impl MC68010 {
|
||||
//},
|
||||
//Instruction::EXG(Target, Target) => {
|
||||
//},
|
||||
//Instruction::EXT(u8, Size) => {
|
||||
//},
|
||||
Instruction::EXT(reg, size) => {
|
||||
let data: u8 = self.d_reg[reg as usize] as u8;
|
||||
self.d_reg[reg as usize] = sign_extend_byte(data, size);
|
||||
},
|
||||
//Instruction::ILLEGAL => {
|
||||
//},
|
||||
Instruction::JMP(target) => {
|
||||
@ -266,8 +282,10 @@ impl MC68010 {
|
||||
Instruction::MOVEtoSR(target) => {
|
||||
self.sr = self.get_target_value(space, target, Size::Word)? as u16;
|
||||
},
|
||||
//Instruction::MOVEtoCCR(Target) => {
|
||||
//},
|
||||
Instruction::MOVEtoCCR(target) => {
|
||||
let value = self.get_target_value(space, target, Size::Word)? as u16;
|
||||
self.sr = (self.sr & 0xFF00) | (value & 0x00FF);
|
||||
},
|
||||
Instruction::MOVEC(target, control_reg, dir) => {
|
||||
match dir {
|
||||
Direction::FromTarget => {
|
||||
@ -286,7 +304,7 @@ impl MC68010 {
|
||||
//},
|
||||
Instruction::MOVEM(target, size, dir, mask) => {
|
||||
// TODO moving words requires a sign extension to 32 bits
|
||||
if size != Size::Long { panic!("Unsupported size in MOVEM instruction"); }
|
||||
if size != Size::Long { return Err(Error::new("Unsupported size in MOVEM instruction")); }
|
||||
|
||||
if dir == Direction::ToTarget {
|
||||
let mut mask = mask;
|
||||
@ -321,7 +339,7 @@ impl MC68010 {
|
||||
}
|
||||
},
|
||||
Instruction::MOVEQ(data, reg) => {
|
||||
let value = ((data as i8) as i32) as u32;
|
||||
let value = sign_extend_byte(data, Size::Long);
|
||||
self.d_reg[reg as usize] = value;
|
||||
},
|
||||
//Instruction::MUL(Target, Target, Size, Sign) => {
|
||||
@ -558,7 +576,7 @@ impl MC68010 {
|
||||
if carry {
|
||||
flags |= FLAGS_CARRY | FLAGS_OVERFLOW;
|
||||
}
|
||||
self.sr |= (self.sr & 0xFFF0) | flags;
|
||||
self.sr = (self.sr & 0xFFF0) | flags;
|
||||
}
|
||||
|
||||
fn set_logic_flags(&mut self, value: u32, size: Size) {
|
||||
@ -635,6 +653,14 @@ fn set_address_sized(space: &mut AddressSpace, addr: Address, value: u32, size:
|
||||
}
|
||||
}
|
||||
|
||||
fn sign_extend_byte(value: u8, size: Size) -> u32 {
|
||||
let value = (value as i8);
|
||||
match size {
|
||||
Size::Byte => (value as u8) as u32,
|
||||
Size::Word => ((value as i16) as u16) as u32,
|
||||
Size::Long => (value as i32) as u32,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl Processor for MC68010 {
|
||||
|
@ -24,6 +24,7 @@ fn main() {
|
||||
space.insert(0x00700000, Box::new(serial));
|
||||
|
||||
let mut cpu = MC68010::new();
|
||||
cpu.set_breakpoint(0x0838);
|
||||
while cpu.is_running() {
|
||||
match cpu.step(&mut space) {
|
||||
Ok(()) => { },
|
||||
|
Loading…
Reference in New Issue
Block a user