mirror of
https://github.com/transistorfet/moa.git
synced 2025-02-16 11:30:33 +00:00
Added MUL, DIV, NEG, DBcc, and Scc instructions, and fixed issue with ADD/SUB flags
With ADDA, SUBA, and ADDQ/SUBQ when the target is an address register, the condition flags should not be changed, but the code was changing them, which caused problems. I've fixed it by making the ADD/SUB executions check for an address target and will not update flags in that case. This should only occur when the actual instruction was an ADDA or ADDQ with an address register target
This commit is contained in:
parent
98883e3daa
commit
10e905674b
@ -115,7 +115,7 @@ pub enum Instruction {
|
||||
CMP(Target, Target, Size),
|
||||
CMPA(Target, u8, Size),
|
||||
|
||||
DBcc(Condition, i16),
|
||||
DBcc(Condition, u8, i16),
|
||||
DIV(Target, Target, Size, Sign),
|
||||
|
||||
EOR(Target, Target, Size),
|
||||
@ -165,7 +165,7 @@ pub enum Instruction {
|
||||
RTS,
|
||||
|
||||
//SBCD
|
||||
//Scc
|
||||
Scc(Condition, Target),
|
||||
STOP(u16),
|
||||
SUB(Target, Target, Size),
|
||||
SWAP(u8),
|
||||
@ -252,12 +252,13 @@ impl M68kDecoder {
|
||||
|
||||
} else {
|
||||
let size = get_size(ins);
|
||||
let target = self.decode_lower_effective_address(space, ins, size)?;
|
||||
let data = match size {
|
||||
Some(Size::Byte) => (self.read_instruction_word(space)? as u32 & 0xFF),
|
||||
Some(Size::Word) => self.read_instruction_word(space)? as u32,
|
||||
Some(Size::Long) => self.read_instruction_long(space)?,
|
||||
Some(_) => self.read_instruction_word(space)? as u32,
|
||||
None => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
|
||||
};
|
||||
let target = self.decode_lower_effective_address(space, ins, size)?;
|
||||
|
||||
match optype {
|
||||
0b0000 => Ok(Instruction::OR(Target::Immediate(data), target, size.unwrap())),
|
||||
@ -337,8 +338,8 @@ impl M68kDecoder {
|
||||
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 target = self.decode_lower_effective_address(space, ins, None)?;
|
||||
let dir = if (ins & 0x0400) == 0 { Direction::ToTarget } else { Direction::FromTarget };
|
||||
Ok(Instruction::MOVEM(target, size, dir, data))
|
||||
}
|
||||
@ -417,21 +418,33 @@ impl M68kDecoder {
|
||||
}
|
||||
},
|
||||
OPCG_ADDQ_SUBQ => {
|
||||
let size = match get_size(ins) {
|
||||
Some(size) => size,
|
||||
None => return Err(Error::processor(ERR_ILLEGAL_INSTRUCTION)),
|
||||
};
|
||||
match get_size(ins) {
|
||||
Some(size) => {
|
||||
let target = self.decode_lower_effective_address(space, ins, Some(size))?;
|
||||
let mut data = ((ins & 0x0E00) >> 9) as u32;
|
||||
if data == 0 {
|
||||
data = 8;
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let mode = get_low_mode(ins);
|
||||
let condition = get_condition(ins);
|
||||
|
||||
if (ins & 0x0100) == 0 {
|
||||
Ok(Instruction::ADD(Target::Immediate(data), target, size))
|
||||
} else {
|
||||
Ok(Instruction::SUB(Target::Immediate(data), target, size))
|
||||
if mode == 0b001 {
|
||||
let reg = get_low_reg(ins);
|
||||
let disp = self.read_instruction_word(space)? as i16;
|
||||
Ok(Instruction::DBcc(condition, reg, disp))
|
||||
} else {
|
||||
let target = self.decode_lower_effective_address(space, ins, Some(Size::Byte))?;
|
||||
Ok(Instruction::Scc(condition, target))
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
OPCG_BRANCH => {
|
||||
|
@ -8,6 +8,7 @@ use super::decode::{
|
||||
Instruction,
|
||||
Target,
|
||||
Size,
|
||||
Sign,
|
||||
Direction,
|
||||
Condition,
|
||||
ShiftDirection,
|
||||
@ -140,7 +141,7 @@ impl MC68010 {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn decode_next(&mut self, space: &mut AddressSpace) -> Result<(), Error> {
|
||||
pub fn decode_next(&mut self, space: &mut AddressSpace) -> Result<(), Error> {
|
||||
self.check_breakpoints();
|
||||
|
||||
self.decoder = M68kDecoder::decode_at(space, self.state.pc)?;
|
||||
@ -162,23 +163,16 @@ impl MC68010 {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn execute_current(&mut self, space: &mut AddressSpace) -> Result<(), Error> {
|
||||
pub fn execute_current(&mut self, space: &mut AddressSpace) -> Result<(), Error> {
|
||||
match self.decoder.instruction {
|
||||
Instruction::ADD(src, dest, size) => {
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let existing = self.get_target_value(space, dest, size)?;
|
||||
let (result, overflow) = match size {
|
||||
Size::Byte => {
|
||||
let (result, overflow) = (existing as u8).overflowing_add(value as u8);
|
||||
(result as u32, overflow)
|
||||
},
|
||||
Size::Word => {
|
||||
let (result, overflow) = (existing as u16).overflowing_add(value as u16);
|
||||
(result as u32, overflow)
|
||||
},
|
||||
Size::Long => existing.overflowing_add(value),
|
||||
};
|
||||
self.set_compare_flags(result, size, overflow);
|
||||
let (result, carry) = overflowing_add_sized(existing, value, size);
|
||||
match dest {
|
||||
Target::DirectAReg(_) => { },
|
||||
_ => self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, size)),
|
||||
}
|
||||
self.set_target_value(space, dest, result, size)?;
|
||||
},
|
||||
Instruction::AND(src, dest, size) => {
|
||||
@ -200,7 +194,7 @@ impl MC68010 {
|
||||
for _ in 0..count {
|
||||
pair = shift_operation(pair.0, size, shift_dir, true);
|
||||
}
|
||||
self.set_compare_flags(pair.0, size, false);
|
||||
self.set_logic_flags(pair.0, size);
|
||||
if pair.1 {
|
||||
self.state.sr |= FLAGS_EXTEND | FLAGS_CARRY;
|
||||
}
|
||||
@ -256,17 +250,38 @@ impl MC68010 {
|
||||
Instruction::CMP(src, dest, size) => {
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let existing = self.get_target_value(space, dest, size)?;
|
||||
let result = self.subtract_sized_with_flags(existing, value, size);
|
||||
let (result, carry) = overflowing_sub_sized(existing, value, size);
|
||||
self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, size));
|
||||
},
|
||||
Instruction::CMPA(src, reg, size) => {
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let existing = sign_extend_to_long(*self.get_a_reg_mut(reg), size) as u32;
|
||||
let result = self.subtract_sized_with_flags(existing, value, Size::Long);
|
||||
let (result, carry) = overflowing_sub_sized(existing, value, Size::Long);
|
||||
self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, Size::Long));
|
||||
},
|
||||
Instruction::DBcc(cond, reg, offset) => {
|
||||
let condition_true = self.get_current_condition(cond);
|
||||
if !condition_true {
|
||||
let next = (get_value_sized(self.state.d_reg[reg as usize], Size::Word) as u16) as i16 - 1;
|
||||
set_value_sized(&mut self.state.d_reg[reg as usize], next as u32, Size::Word);
|
||||
if next != -1 {
|
||||
self.state.pc = (self.decoder.start + 2).wrapping_add(offset as u32);
|
||||
}
|
||||
}
|
||||
},
|
||||
Instruction::DIV(src, dest, size, sign) => {
|
||||
if size == Size::Long {
|
||||
return Err(Error::new("Unsupported multiplication size"));
|
||||
}
|
||||
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let existing = self.get_target_value(space, dest, Size::Long)?;
|
||||
let result = match sign {
|
||||
Sign::Signed => ((existing as i16 % value as i16) as u32) << 16 | (0xFFFF & (existing as i16 / value as i16) as u32),
|
||||
Sign::Unsigned => ((existing as u16 % value as u16) as u32) << 16 | (0xFFFF & (existing as u16 / value as u16) as u32),
|
||||
};
|
||||
self.set_target_value(space, dest, result, Size::Long)?;
|
||||
},
|
||||
//Instruction::DBcc(Condition, u16) => {
|
||||
//},
|
||||
//Instruction::DIV(Target, Target, Size, Sign) => {
|
||||
//},
|
||||
Instruction::EOR(src, dest, size) => {
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let existing = self.get_target_value(space, dest, size)?;
|
||||
@ -288,7 +303,8 @@ impl MC68010 {
|
||||
Size::Word => ((byte as i16) as u16) as u32,
|
||||
Size::Long => (byte as i32) as u32,
|
||||
};
|
||||
self.state.d_reg[reg as usize] = result;
|
||||
set_value_sized(&mut self.state.d_reg[reg as usize], result, size);
|
||||
self.set_logic_flags(result, size);
|
||||
},
|
||||
//Instruction::ILLEGAL => {
|
||||
//},
|
||||
@ -318,7 +334,7 @@ impl MC68010 {
|
||||
for _ in 0..count {
|
||||
pair = shift_operation(pair.0, size, shift_dir, false);
|
||||
}
|
||||
self.set_compare_flags(pair.0, size, false);
|
||||
self.set_logic_flags(pair.0, size);
|
||||
if pair.1 {
|
||||
self.state.sr |= FLAGS_EXTEND | FLAGS_CARRY;
|
||||
}
|
||||
@ -326,13 +342,14 @@ impl MC68010 {
|
||||
},
|
||||
Instruction::MOVE(src, dest, size) => {
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
self.set_compare_flags(value, size, false);
|
||||
self.set_logic_flags(value, size);
|
||||
self.set_target_value(space, dest, value, size)?;
|
||||
},
|
||||
Instruction::MOVEA(src, reg, size) => {
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let value = sign_extend_to_long(value, size) as u32;
|
||||
let addr = self.get_a_reg_mut(reg);
|
||||
*addr = sign_extend_to_long(value, size) as u32;
|
||||
*addr = value;
|
||||
},
|
||||
Instruction::MOVEfromSR(target) => {
|
||||
self.set_target_value(space, target, self.state.sr as u32, Size::Word)?;
|
||||
@ -404,14 +421,29 @@ impl MC68010 {
|
||||
Instruction::MOVEQ(data, reg) => {
|
||||
let value = sign_extend_to_long(data as u32, Size::Byte) as u32;
|
||||
self.state.d_reg[reg as usize] = value;
|
||||
self.set_compare_flags(value, Size::Long, false);
|
||||
self.set_logic_flags(value, Size::Long);
|
||||
},
|
||||
Instruction::MUL(src, dest, size, sign) => {
|
||||
if size == Size::Long {
|
||||
return Err(Error::new("Unsupported multiplication size"));
|
||||
}
|
||||
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let existing = self.get_target_value(space, dest, size)?;
|
||||
let result = match sign {
|
||||
Sign::Signed => (sign_extend_to_long(existing, Size::Word) * sign_extend_to_long(value, Size::Word)) as u32,
|
||||
Sign::Unsigned => existing as u32 * value as u32,
|
||||
};
|
||||
self.set_target_value(space, dest, result, Size::Long)?;
|
||||
},
|
||||
//Instruction::MUL(Target, Target, Size, Sign) => {
|
||||
//},
|
||||
//Instruction::NBCD(Target) => {
|
||||
//},
|
||||
//Instruction::NEG(Target, Size) => {
|
||||
//},
|
||||
Instruction::NEG(target, size) => {
|
||||
let original = self.get_target_value(space, target, size)?;
|
||||
let (value, _) = (0 as u32).overflowing_sub(original);
|
||||
self.set_target_value(space, target, value, size);
|
||||
self.set_compare_flags(value, size, value != 0, get_overflow(0, original, value, size));
|
||||
},
|
||||
//Instruction::NEGX(Target, Size) => {
|
||||
//},
|
||||
Instruction::NOP => { },
|
||||
@ -450,12 +482,24 @@ impl MC68010 {
|
||||
Instruction::RTS => {
|
||||
self.state.pc = self.pop_long(space)?;
|
||||
},
|
||||
Instruction::Scc(cond, target) => {
|
||||
let condition_true = self.get_current_condition(cond);
|
||||
if condition_true {
|
||||
self.set_target_value(space, target, 0xFF, Size::Byte);
|
||||
} else {
|
||||
self.set_target_value(space, target, 0x00, Size::Byte);
|
||||
}
|
||||
},
|
||||
//Instruction::STOP(u16) => {
|
||||
//},
|
||||
Instruction::SUB(src, dest, size) => {
|
||||
let value = self.get_target_value(space, src, size)?;
|
||||
let existing = self.get_target_value(space, dest, size)?;
|
||||
let result = self.subtract_sized_with_flags(existing, value, size);
|
||||
let (result, carry) = overflowing_sub_sized(existing, value, size);
|
||||
match dest {
|
||||
Target::DirectAReg(_) => { },
|
||||
_ => self.set_compare_flags(result, size, carry, get_overflow(existing, value, result, size)),
|
||||
}
|
||||
self.set_target_value(space, dest, result, size)?;
|
||||
},
|
||||
Instruction::SWAP(reg) => {
|
||||
@ -466,7 +510,7 @@ impl MC68010 {
|
||||
//},
|
||||
Instruction::TST(target, size) => {
|
||||
let value = self.get_target_value(space, target, size)?;
|
||||
self.set_compare_flags(value, size, false);
|
||||
self.set_logic_flags(value, size);
|
||||
},
|
||||
//Instruction::TRAP(u8) => {
|
||||
//},
|
||||
@ -479,7 +523,7 @@ impl MC68010 {
|
||||
let addr = self.get_a_reg_mut(reg);
|
||||
*addr = new_value;
|
||||
},
|
||||
_ => { panic!(""); },
|
||||
_ => { panic!("Unsupported instruction"); },
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -524,9 +568,7 @@ impl MC68010 {
|
||||
Target::IndirectARegXRegOffset(reg, rtype, xreg, offset, target_size) => {
|
||||
let reg_offset = sign_extend_to_long(self.get_x_reg_value(rtype, xreg), target_size);
|
||||
let addr = self.get_a_reg_mut(reg);
|
||||
let result = get_address_sized(space, (*addr).wrapping_add(reg_offset as u32).wrapping_add(offset as u32) as Address, size);
|
||||
println!(">>> {:x} has {:x}", (*addr).wrapping_add(reg_offset as u32).wrapping_add(offset as u32), result.as_ref().unwrap());
|
||||
result
|
||||
get_address_sized(space, (*addr).wrapping_add(reg_offset as u32).wrapping_add(offset as u32) as Address, size)
|
||||
},
|
||||
Target::IndirectMemory(addr) => {
|
||||
get_address_sized(space, addr as Address, size)
|
||||
@ -606,22 +648,6 @@ println!(">>> {:x} has {:x}", (*addr).wrapping_add(reg_offset as u32).wrapping_a
|
||||
Ok(addr)
|
||||
}
|
||||
|
||||
fn subtract_sized_with_flags(&mut self, existing: u32, diff: u32, size: Size) -> u32 {
|
||||
let (result, overflow) = match size {
|
||||
Size::Byte => {
|
||||
let (result, overflow) = (existing as u8).overflowing_sub(diff as u8);
|
||||
(result as u32, overflow)
|
||||
},
|
||||
Size::Word => {
|
||||
let (result, overflow) = (existing as u16).overflowing_sub(diff as u16);
|
||||
(result as u32, overflow)
|
||||
},
|
||||
Size::Long => existing.overflowing_sub(diff),
|
||||
};
|
||||
self.set_compare_flags(result, size, overflow);
|
||||
result
|
||||
}
|
||||
|
||||
fn get_control_reg_mut(&mut self, control_reg: ControlRegister) -> &mut u32 {
|
||||
match control_reg {
|
||||
ControlRegister::VBR => &mut self.state.vbr,
|
||||
@ -645,7 +671,7 @@ println!(">>> {:x} has {:x}", (*addr).wrapping_add(reg_offset as u32).wrapping_a
|
||||
fn get_x_reg_value(&self, rtype: RegisterType, reg: u8) -> u32 {
|
||||
match rtype {
|
||||
RegisterType::Data => self.state.d_reg[reg as usize],
|
||||
RegisterType::Address => self.state.d_reg[reg as usize],
|
||||
RegisterType::Address => self.state.a_reg[reg as usize],
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,7 +687,7 @@ println!(">>> {:x} has {:x}", (*addr).wrapping_add(reg_offset as u32).wrapping_a
|
||||
}
|
||||
}
|
||||
|
||||
fn set_compare_flags(&mut self, value: u32, size: Size, carry: bool) {
|
||||
fn set_compare_flags(&mut self, value: u32, size: Size, carry: bool, overflow: bool) {
|
||||
let value = sign_extend_to_long(value, size);
|
||||
|
||||
let mut flags = 0x0000;
|
||||
@ -672,7 +698,10 @@ println!(">>> {:x} has {:x}", (*addr).wrapping_add(reg_offset as u32).wrapping_a
|
||||
flags |= FLAGS_ZERO
|
||||
}
|
||||
if carry {
|
||||
flags |= FLAGS_CARRY | FLAGS_OVERFLOW;
|
||||
flags |= FLAGS_CARRY;
|
||||
}
|
||||
if overflow {
|
||||
flags |= FLAGS_OVERFLOW;
|
||||
}
|
||||
self.state.sr = (self.state.sr & 0xFFF0) | flags;
|
||||
}
|
||||
@ -685,7 +714,7 @@ println!(">>> {:x} has {:x}", (*addr).wrapping_add(reg_offset as u32).wrapping_a
|
||||
if value == 0 {
|
||||
flags |= FLAGS_ZERO
|
||||
}
|
||||
self.state.sr |= (self.state.sr & 0xFFF0) | flags;
|
||||
self.state.sr = (self.state.sr & 0xFFF0) | flags;
|
||||
}
|
||||
|
||||
fn set_bit_test_flags(&mut self, value: u32, bitnum: u32, size: Size) -> u32 {
|
||||
@ -723,6 +752,52 @@ println!(">>> {:x} has {:x}", (*addr).wrapping_add(reg_offset as u32).wrapping_a
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn overflowing_add_sized(operand1: u32, operand2: u32, size: Size) -> (u32, bool) {
|
||||
match size {
|
||||
Size::Byte => {
|
||||
let (result, carry) = (operand1 as u8).overflowing_add(operand2 as u8);
|
||||
(result as u32, carry)
|
||||
},
|
||||
Size::Word => {
|
||||
let (result, carry) = (operand1 as u16).overflowing_add(operand2 as u16);
|
||||
(result as u32, carry)
|
||||
},
|
||||
Size::Long => operand1.overflowing_add(operand2),
|
||||
}
|
||||
}
|
||||
|
||||
fn overflowing_sub_sized(operand1: u32, operand2: u32, size: Size) -> (u32, bool) {
|
||||
match size {
|
||||
Size::Byte => {
|
||||
let (result, carry) = (operand1 as u8).overflowing_sub(operand2 as u8);
|
||||
(result as u32, carry)
|
||||
},
|
||||
Size::Word => {
|
||||
let (result, carry) = (operand1 as u16).overflowing_sub(operand2 as u16);
|
||||
(result as u32, carry)
|
||||
},
|
||||
Size::Long => operand1.overflowing_sub(operand2),
|
||||
}
|
||||
}
|
||||
|
||||
fn shift_operation(value: u32, size: Size, dir: ShiftDirection, arithmetic: bool) -> (u32, bool) {
|
||||
match dir {
|
||||
ShiftDirection::Left => {
|
||||
match size {
|
||||
Size::Byte => (((value as u8) << 1) as u32, get_msb(value, size)),
|
||||
Size::Word => (((value as u16) << 1) as u32, get_msb(value, size)),
|
||||
Size::Long => ((value << 1) as u32, get_msb(value, size)),
|
||||
}
|
||||
},
|
||||
ShiftDirection::Right => {
|
||||
let mask = if arithmetic { get_msb_mask(value, size) } else { 0 };
|
||||
((value >> 1) | mask, (value & 0x1) != 0)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_value_sized(value: u32, size: Size) -> u32 {
|
||||
match size {
|
||||
Size::Byte => { 0x000000FF & value },
|
||||
@ -755,20 +830,12 @@ fn set_address_sized(space: &mut AddressSpace, addr: Address, value: u32, size:
|
||||
}
|
||||
}
|
||||
|
||||
fn shift_operation(value: u32, size: Size, dir: ShiftDirection, arithmetic: bool) -> (u32, bool) {
|
||||
match dir {
|
||||
ShiftDirection::Left => {
|
||||
match size {
|
||||
Size::Byte => (((value as u8) << 1) as u32, get_msb(value, size)),
|
||||
Size::Word => (((value as u16) << 1) as u32, get_msb(value, size)),
|
||||
Size::Long => ((value << 1) as u32, get_msb(value, size)),
|
||||
}
|
||||
},
|
||||
ShiftDirection::Right => {
|
||||
let mask = if arithmetic { get_msb_mask(value, size) } else { 0 };
|
||||
((value >> 1) | mask, (value & 0x1) != 0)
|
||||
},
|
||||
}
|
||||
fn get_overflow(operand1: u32, operand2: u32, result: u32, size: Size) -> bool {
|
||||
let msb1 = get_msb(operand1, size);
|
||||
let msb2 = get_msb(operand2, size);
|
||||
let msb_res = get_msb(result, size);
|
||||
|
||||
msb1 && msb2 && !msb_res
|
||||
}
|
||||
|
||||
fn get_msb(value: u32, size: Size) -> bool {
|
||||
|
@ -1,8 +1,8 @@
|
||||
|
||||
mod decode;
|
||||
mod execute;
|
||||
mod debugger;
|
||||
mod tests;
|
||||
pub mod decode;
|
||||
pub mod execute;
|
||||
pub mod debugger;
|
||||
pub mod tests;
|
||||
|
||||
pub use self::execute::MC68010;
|
||||
|
||||
|
@ -95,5 +95,17 @@ mod tests {
|
||||
cpu.execute_current(&mut space).unwrap();
|
||||
assert_eq!(cpu.state.sr & 0x0F, 0x00);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn instruction_movel() {
|
||||
let (mut cpu, mut space) = init_test();
|
||||
|
||||
space.write_beu16(INIT_ADDR, 0x2F49).unwrap();
|
||||
space.write_beu16(INIT_ADDR + 2, 0x0034).unwrap();
|
||||
cpu.decode_next(&mut space).unwrap();
|
||||
assert_eq!(cpu.decoder.instruction, Instruction::MOVE(Target::DirectAReg(0x01), Target::IndirectARegOffset(7, 52), Size::Long));
|
||||
//cpu.execute_current(&mut space).unwrap();
|
||||
//assert_eq!(cpu.state.sr & 0x0F, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
src/main.rs
14
src/main.rs
@ -25,13 +25,11 @@ fn main() {
|
||||
space.insert(0x00700000, Box::new(serial));
|
||||
|
||||
let mut cpu = MC68010::new();
|
||||
//cpu.add_breakpoint(0x07f8);
|
||||
//cpu.add_breakpoint(0x0836);
|
||||
//cpu.add_breakpoint(0x0838);
|
||||
//cpu.add_breakpoint(0x0ea0);
|
||||
//cpu.enable_tracing();
|
||||
|
||||
//cpu.add_breakpoint(0x0c94);
|
||||
//cpu.add_breakpoint(0x0cf2);
|
||||
|
||||
cpu.add_breakpoint(0x0034);
|
||||
cpu.enable_tracing();
|
||||
while cpu.is_running() {
|
||||
match cpu.step(&mut space) {
|
||||
Ok(()) => { },
|
||||
@ -44,9 +42,9 @@ fn main() {
|
||||
//serial.step();
|
||||
}
|
||||
|
||||
// TODO I need to add a way to decode and dump the assembly for a section of code, in debugger
|
||||
/*
|
||||
cpu.state.pc = 0x07f8;
|
||||
// TODO I need to add a way to decode and dump the assembly for a section of code, in debugger
|
||||
cpu.state.pc = 0x0db4;
|
||||
while cpu.is_running() {
|
||||
cpu.decode_next(&mut space).unwrap();
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ impl AddressSpace {
|
||||
pub fn dump_memory(&mut self, mut addr: Address, mut count: Address) {
|
||||
while count > 0 {
|
||||
let mut line = format!("{:#010x}: ", addr);
|
||||
|
||||
let to = if count < 16 { count / 2 } else { 8 };
|
||||
for i in 0..to {
|
||||
let word = self.read_beu16(addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user