Fixed tests and clippy warnings

This commit is contained in:
transistor 2023-06-10 17:39:20 -07:00
parent 3bd4c24ea8
commit e3861f33b5
27 changed files with 253 additions and 256 deletions

View File

@ -95,6 +95,7 @@ impl ClockDuration {
}
#[inline]
#[allow(clippy::unnecessary_cast)]
pub const fn as_picos(self) -> u128 {
(self.femtos / Self::FEMTOS_PER_PICOSEC) as u128
}

View File

@ -27,7 +27,7 @@ impl MemoryBlock {
pub fn load(filename: &str) -> Result<MemoryBlock, Error> {
match fs::read(filename) {
Ok(contents) => Ok(MemoryBlock::new(contents)),
Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))),
Err(_) => Err(Error::new(format!("Error reading contents of {}", filename))),
}
}
@ -37,7 +37,7 @@ impl MemoryBlock {
self.contents[(addr as usize)..(addr as usize) + contents.len()].copy_from_slice(&contents);
Ok(())
},
Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))),
Err(_) => Err(Error::new(format!("Error reading contents of {}", filename))),
}
}
@ -62,7 +62,7 @@ impl Addressable for MemoryBlock {
fn write(&mut self, _clock: ClockTime, addr: Address, data: &[u8]) -> Result<(), Error> {
if self.read_only {
return Err(Error::breakpoint(&format!("Attempt to write to read-only memory at {:x} with data {:?}", addr, data)));
return Err(Error::breakpoint(format!("Attempt to write to read-only memory at {:x} with data {:?}", addr, data)));
}
self.contents[(addr as usize) .. (addr as usize) + data.len()].copy_from_slice(data);
@ -188,11 +188,11 @@ impl Bus {
if relative_addr as usize + count <= block.size {
return Ok((block.dev.clone(), relative_addr));
} else {
return Err(Error::new(&format!("Error reading address {:#010x}", addr)));
return Err(Error::new(format!("Error reading address {:#010x}", addr)));
}
}
}
Err(Error::new(&format!("No segment found at {:#010x}", addr)))
Err(Error::new(format!("No segment found at {:#010x}", addr)))
}
pub fn dump_memory(&mut self, clock: ClockTime, mut addr: Address, mut count: Address) {

View File

@ -53,7 +53,7 @@ impl System {
}
pub fn get_device(&self, name: &str) -> Result<Device, Error> {
self.devices.get(name).cloned().ok_or_else(|| Error::new(&format!("system: no device named {}", name)))
self.devices.get(name).cloned().ok_or_else(|| Error::new(format!("system: no device named {}", name)))
}
pub fn add_device(&mut self, name: &str, device: Device) -> Result<(), Error> {

View File

@ -38,7 +38,7 @@ impl Disallow {
if (*self as usize) & (disallow as usize) == 0 {
Ok(())
} else {
Err(Error::new(&format!("error at line {}: invalid addressing mode for the instruction", lineno)))
Err(Error::new(format!("error at line {}: invalid addressing mode for the instruction", lineno)))
}
}
}
@ -122,7 +122,7 @@ impl M68kAssembler {
match reloc.rtype {
RelocationType::Displacement => {
// TODO this doesn't yet take into accound the origin
let location = *self.labels.get(&reloc.label).ok_or_else(|| Error::new(&format!("error during relocation, label undefined {:?}", reloc.label)))?;
let location = *self.labels.get(&reloc.label).ok_or_else(|| Error::new(format!("error during relocation, label undefined {:?}", reloc.label)))?;
self.output[reloc.index] |= ((self.output[reloc.index] as i8 * 2 + 2) - (location as i8 * 2)) as u16 & 0x00ff;
},
_ => panic!("relocation type unimplemented"),
@ -199,7 +199,7 @@ impl M68kAssembler {
}
fn convert_sized_instruction(&mut self, lineno: usize, mneumonic: &str, args: &[AssemblyOperand]) -> Result<(), Error> {
let operation_size = get_size_from_mneumonic(mneumonic).ok_or_else(|| Error::new(&format!("error at line {}: expected a size specifier (b/w/l)", lineno)));
let operation_size = get_size_from_mneumonic(mneumonic).ok_or_else(|| Error::new(format!("error at line {}: expected a size specifier (b/w/l)", lineno)));
match &mneumonic[..mneumonic.len() - 1] {
"addi" => {
self.convert_common_immediate_instruction(lineno, 0x0600, args, operation_size?, Disallow::NoARegImmediateOrPC)?;
@ -300,7 +300,7 @@ impl M68kAssembler {
},
// TODO complete remaining instructions
_ => return Err(Error::new(&format!("unrecognized instruction at line {}: {:?}", lineno, mneumonic))),
_ => return Err(Error::new(format!("unrecognized instruction at line {}: {:?}", lineno, mneumonic))),
}
Ok(())
}
@ -369,14 +369,14 @@ impl M68kAssembler {
} else if dirstr == "l" {
1 << 8
} else {
return Err(Error::new(&format!("error at line {}: expected direction of (l)eft or (r)ight, but found {:?}", lineno, dirstr)));
return Err(Error::new(format!("error at line {}: expected direction of (l)eft or (r)ight, but found {:?}", lineno, dirstr)));
};
match &args {
[AssemblyOperand::Immediate(_), AssemblyOperand::Register(_)] => {
let mut immediate = parser::expect_immediate(lineno, &args[0])?;
if !(1..=8).contains(&immediate) {
return Err(Error::new(&format!("error at line {}: immediate value must be between 1 and 8, found {:?}", lineno, args)));
return Err(Error::new(format!("error at line {}: immediate value must be between 1 and 8, found {:?}", lineno, args)));
} else if immediate == 8 {
immediate = 0;
}
@ -394,7 +394,7 @@ impl M68kAssembler {
// self.output.push(opcode | effective_address);
// self.output.extend(additional_words);
//},
_ => return Err(Error::new(&format!("error at line {}: unexpected addressing mode, found {:?}", lineno, args))),
_ => return Err(Error::new(format!("error at line {}: unexpected addressing mode, found {:?}", lineno, args))),
}
Ok(())
}
@ -422,7 +422,7 @@ fn convert_target(lineno: usize, operand: &AssemblyOperand, size: Size, disallow
}
}
}
Err(Error::new(&format!("error at line {}: post-increment operator can only be used with a single address register", lineno)))
Err(Error::new(format!("error at line {}: post-increment operator can only be used with a single address register", lineno)))
},
AssemblyOperand::IndirectPre(operator, args) => {
disallow.check(lineno, Disallow::NoIndirectPre)?;
@ -436,9 +436,9 @@ fn convert_target(lineno: usize, operand: &AssemblyOperand, size: Size, disallow
}
}
}
Err(Error::new(&format!("error at line {}: pre-decrement operator can only be used with a single address register", lineno)))
Err(Error::new(format!("error at line {}: pre-decrement operator can only be used with a single address register", lineno)))
},
_ => Err(Error::new(&format!("not implemented: {:?}", operand))),
_ => Err(Error::new(format!("not implemented: {:?}", operand))),
}
}
@ -458,7 +458,7 @@ fn convert_register(lineno: usize, name: &str, disallow: Disallow) -> Result<(u1
disallow.check(lineno, Disallow::NoAReg)?;
Ok(((0b001 << 3) | 7, vec![]))
},
_ => Err(Error::new(&format!("error at line {}: invalid register {:?}", lineno, name))),
_ => Err(Error::new(format!("error at line {}: invalid register {:?}", lineno, name))),
}
}
@ -501,7 +501,7 @@ fn convert_indirect(lineno: usize, args: &[AssemblyOperand], disallow: Disallow)
},
// TODO add the MC68020 address options
_ => {
Err(Error::new(&format!("error at line {}: expected valid indirect addressing mode, but found {:?}", lineno, args)))
Err(Error::new(format!("error at line {}: expected valid indirect addressing mode, but found {:?}", lineno, args)))
}
}
}
@ -515,7 +515,7 @@ fn convert_reg_and_other(lineno: usize, args: &[AssemblyOperand], _disallow: Dis
Ok(((0b0 << 8), expect_reg_num(lineno, reg)?, effective_address))
},
_ => {
Err(Error::new(&format!("error at line {}: expected register and effective address, but found {:?}", lineno, args)))
Err(Error::new(format!("error at line {}: expected register and effective address, but found {:?}", lineno, args)))
}
}
}
@ -526,14 +526,14 @@ fn convert_immediate(lineno: usize, value: usize, size: Size) -> Result<Vec<u16>
if value <= u8::MAX as usize {
Ok(vec![value as u16])
} else {
Err(Error::new(&format!("error at line {}: immediate number is out of range; must be less than {}, but number is {:?}", lineno, u8::MAX, value)))
Err(Error::new(format!("error at line {}: immediate number is out of range; must be less than {}, but number is {:?}", lineno, u8::MAX, value)))
}
},
Size::Word => {
if value <= u16::MAX as usize {
Ok(vec![value as u16])
} else {
Err(Error::new(&format!("error at line {}: immediate number is out of range; must be less than {}, but number is {:?}", lineno, u16::MAX, value)))
Err(Error::new(format!("error at line {}: immediate number is out of range; must be less than {}, but number is {:?}", lineno, u16::MAX, value)))
}
},
Size::Long => Ok(vec![(value >> 16) as u16, value as u16]),
@ -546,7 +546,7 @@ fn expect_data_register(lineno: usize, operand: &AssemblyOperand) -> Result<u16,
return expect_reg_num(lineno, name);
}
}
Err(Error::new(&format!("error at line {}: expected a data register, but found {:?}", lineno, operand)))
Err(Error::new(format!("error at line {}: expected a data register, but found {:?}", lineno, operand)))
}
fn expect_address_register(lineno: usize, operand: &AssemblyOperand) -> Result<u16, Error> {
@ -555,14 +555,14 @@ fn expect_address_register(lineno: usize, operand: &AssemblyOperand) -> Result<u
return expect_reg_num(lineno, name);
}
}
Err(Error::new(&format!("error at line {}: expected an address register, but found {:?}", lineno, operand)))
Err(Error::new(format!("error at line {}: expected an address register, but found {:?}", lineno, operand)))
}
fn expect_address_reg_num(lineno: usize, name: &str) -> Result<u16, Error> {
if name.starts_with('a') {
return expect_reg_num(lineno, name);
}
Err(Error::new(&format!("error at line {}: expected an address register, but found {:?}", lineno, name)))
Err(Error::new(format!("error at line {}: expected an address register, but found {:?}", lineno, name)))
}
fn expect_reg_num(lineno: usize, name: &str) -> Result<u16, Error> {
@ -571,14 +571,14 @@ fn expect_reg_num(lineno: usize, name: &str) -> Result<u16, Error> {
return Ok(number);
}
}
Err(Error::new(&format!("error at line {}: no such register {:?}", lineno, name)))
Err(Error::new(format!("error at line {}: no such register {:?}", lineno, name)))
}
fn expect_a_instruction_size(lineno: usize, size: Size) -> Result<u16, Error> {
match size {
Size::Word => Ok(0),
Size::Long => Ok(0b1 << 8),
_ => Err(Error::new(&format!("error at line {}: address instructions can only be word or long size", lineno))),
_ => Err(Error::new(format!("error at line {}: address instructions can only be word or long size", lineno))),
}
}
@ -614,7 +614,7 @@ fn encode_size_bit(size: Size) -> Result<u16, Error> {
match size {
Size::Word => Ok(0b01 << 6),
Size::Long => Ok(0b10 << 6),
_ => Err(Error::new(&format!("invalid size for this operation: {:?}", size)))
_ => Err(Error::new(format!("invalid size for this operation: {:?}", size)))
}
}

View File

@ -897,13 +897,13 @@ impl M68k {
let post_addr = match target {
Target::IndirectARegInc(_) => {
if dir != Direction::FromTarget {
return Err(Error::new(&format!("Cannot use {:?} with {:?}", target, dir)));
return Err(Error::new(format!("Cannot use {:?} with {:?}", target, dir)));
}
self.move_memory_to_registers(addr, size, mask)?
},
Target::IndirectARegDec(_) => {
if dir != Direction::ToTarget {
return Err(Error::new(&format!("Cannot use {:?} with {:?}", target, dir)));
return Err(Error::new(format!("Cannot use {:?} with {:?}", target, dir)));
}
self.move_registers_to_memory_reverse(addr, size, mask)?
},
@ -1000,7 +1000,7 @@ impl M68k {
let mut addr = (*self.get_a_reg_mut(areg)).wrapping_add_signed(offset as i32) as Address;
while shift >= 0 {
let byte = self.get_address_sized(addr, Size::Byte)?;
self.state.d_reg[dreg as usize] |= (byte as u32) << shift;
self.state.d_reg[dreg as usize] |= byte << shift;
addr += 2;
shift -= 8;
}
@ -1445,7 +1445,7 @@ impl M68k {
Target::IndirectMemory(addr, _) => {
self.set_address_sized(addr as Address, value, size)?;
},
_ => return Err(Error::new(&format!("Unimplemented addressing target: {:?}", target))),
_ => return Err(Error::new(format!("Unimplemented addressing target: {:?}", target))),
}
Ok(())
}
@ -1473,7 +1473,7 @@ impl M68k {
Target::IndirectMemory(addr, _) => {
addr
},
_ => return Err(Error::new(&format!("Invalid addressing target: {:?}", target))),
_ => return Err(Error::new(format!("Invalid addressing target: {:?}", target))),
};
Ok(addr)
}

View File

@ -4,25 +4,26 @@ mod decode_unit_tests {
use std::rc::Rc;
use std::cell::RefCell;
use moa_core::{Bus, BusPort, ClockTime, Address, Addressable, MemoryBlock, wrap_transmutable};
use moa_core::{Bus, BusPort, ClockTime, Address, Addressable, MemoryBlock, Device};
use crate::M68kType;
use crate::instructions::{Target, Size, XRegister, BaseRegister, IndexRegister};
use crate::decode::M68kDecoder;
use crate::memory::M68kBusPort;
const INIT_ADDR: Address = 0x00000000;
fn init_decode_test(cputype: M68kType) -> (BusPort, M68kDecoder) {
fn init_decode_test(cputype: M68kType) -> (M68kBusPort, M68kDecoder) {
let bus = Rc::new(RefCell::new(Bus::default()));
let mem = MemoryBlock::new(vec![0; 0x0000100]);
bus.borrow_mut().insert(0x00000000, wrap_transmutable(mem));
bus.borrow_mut().insert(0x00000000, Device::new(mem));
let port = if cputype <= M68kType::MC68010 {
BusPort::new(0, 24, 16, bus)
M68kBusPort::new(BusPort::new(0, 24, 16, bus))
} else {
BusPort::new(0, 32, 32, bus)
M68kBusPort::new(BusPort::new(0, 32, 32, bus))
};
let decoder = M68kDecoder::new(cputype, ClockTime::START, 0);
let decoder = M68kDecoder::new(cputype, true, 0);
(port, decoder)
}
@ -57,7 +58,7 @@ mod decode_unit_tests {
let size = Size::Long;
let expected = 0x12345678;
port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b010, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectAReg(2));
@ -70,7 +71,7 @@ mod decode_unit_tests {
let size = Size::Long;
let expected = 0x12345678;
port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b011, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectARegInc(2));
@ -83,7 +84,7 @@ mod decode_unit_tests {
let size = Size::Long;
let expected = 0x12345678;
port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b100, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectARegDec(2));
@ -96,7 +97,7 @@ mod decode_unit_tests {
let size = Size::Long;
let offset = -8;
port.write_beu16(ClockTime::START, INIT_ADDR, (offset as i16) as u16).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, (offset as i16) as u16).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b101, 0b100, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(4), None, offset));
@ -110,8 +111,8 @@ mod decode_unit_tests {
let offset = -8;
let brief_extension = 0x3800 | (((offset as i8) as u8) as u16);
port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.write_beu16(ClockTime::START, INIT_ADDR + 2, (offset as i16) as u16).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR + 2, (offset as i16) as u16).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b110, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(2), Some(IndexRegister { xreg: XRegister::DReg(3), scale: 0, size: size }), offset));
@ -125,8 +126,8 @@ mod decode_unit_tests {
let offset = -1843235 as i32;
let brief_extension = 0xF330;
port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b110, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(2), Some(IndexRegister { xreg: XRegister::AReg(7), scale: 1, size: size }), offset));
@ -140,8 +141,8 @@ mod decode_unit_tests {
let offset = -1843235 as i32;
let brief_extension = 0xF3B0;
port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b110, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::None, Some(IndexRegister { xreg: XRegister::AReg(7), scale: 1, size: size }), offset));
@ -155,8 +156,8 @@ mod decode_unit_tests {
let offset = -1843235 as i32;
let brief_extension = 0xF370;
port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b110, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(2), None, offset));
@ -169,7 +170,7 @@ mod decode_unit_tests {
let size = Size::Long;
let offset = -8;
port.write_beu16(ClockTime::START, INIT_ADDR, (offset as i16) as u16).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, (offset as i16) as u16).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b111, 0b010, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::PC, None, offset));
@ -183,8 +184,8 @@ mod decode_unit_tests {
let offset = -8;
let brief_extension = 0x3000 | (((offset as i8) as u8) as u16);
port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.write_beu16(ClockTime::START, INIT_ADDR + 2, (offset as i16) as u16).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR + 2, (offset as i16) as u16).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b111, 0b011, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::PC, Some(IndexRegister { xreg: XRegister::DReg(3), scale: 0, size: size }), offset));
@ -198,8 +199,8 @@ mod decode_unit_tests {
let offset = -1843235 as i32;
let brief_extension = 0xF330;
port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, brief_extension).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR + 2, offset as u32).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b111, 0b011, Some(size)).unwrap();
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::PC, Some(IndexRegister { xreg: XRegister::AReg(7), scale: 1, size: size }), offset));
@ -213,7 +214,7 @@ mod decode_unit_tests {
let size = Size::Word;
let expected = 0x1234;
port.write_beu16(ClockTime::START, INIT_ADDR, expected as u16).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, expected as u16).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b111, 0b000, Some(size)).unwrap();
assert_eq!(target, Target::IndirectMemory(expected, Size::Word));
@ -226,7 +227,7 @@ mod decode_unit_tests {
let size = Size::Word;
let expected = 0x12345678;
port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
port.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b111, 0b001, Some(size)).unwrap();
assert_eq!(target, Target::IndirectMemory(expected, Size::Long));
@ -239,7 +240,7 @@ mod decode_unit_tests {
let size = Size::Word;
let expected = 0x1234;
port.write_beu16(ClockTime::START, INIT_ADDR, expected as u16).unwrap();
port.port.write_beu16(ClockTime::START, INIT_ADDR, expected as u16).unwrap();
let target = decoder.get_mode_as_target(&mut port, 0b111, 0b100, Some(size)).unwrap();
assert_eq!(target, Target::Immediate(expected));
@ -249,7 +250,7 @@ mod decode_unit_tests {
#[cfg(test)]
mod execute_unit_tests {
use moa_core::{System, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, Steppable, wrap_transmutable};
use moa_core::{System, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, Steppable, Device};
use crate::{M68k, M68kType};
use crate::execute::Used;
@ -264,7 +265,7 @@ mod execute_unit_tests {
// Insert basic initialization
let data = vec![0; 0x00100000];
let mem = MemoryBlock::new(data);
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x00000000, Device::new(mem)).unwrap();
system.get_bus().write_beu32(system.clock, 0, INIT_STACK as u32).unwrap();
system.get_bus().write_beu32(system.clock, 4, INIT_ADDR as u32).unwrap();
@ -275,7 +276,7 @@ mod execute_unit_tests {
};
let mut cpu = M68k::new(cputype, Frequency::from_mhz(10), port);
cpu.step(&system).unwrap();
cpu.decoder.init(system.clock, cpu.state.pc);
cpu.decoder.init(true, cpu.state.pc);
assert_eq!(cpu.state.pc, INIT_ADDR as u32);
assert_eq!(cpu.state.ssp, INIT_STACK as u32);
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
@ -319,7 +320,7 @@ mod execute_unit_tests {
let size = Size::Long;
let expected = 0x12345678;
let target = Target::IndirectAReg(2);
cpu.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
cpu.port.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
cpu.state.a_reg[2] = INIT_ADDR as u32;
let result = cpu.get_target_value(target, size, Used::Once).unwrap();
@ -333,7 +334,7 @@ mod execute_unit_tests {
let size = Size::Long;
let expected = 0x12345678;
let target = Target::IndirectARegInc(2);
cpu.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
cpu.port.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
cpu.state.a_reg[2] = INIT_ADDR as u32;
let result = cpu.get_target_value(target, size, Used::Once).unwrap();
@ -348,7 +349,7 @@ mod execute_unit_tests {
let size = Size::Long;
let expected = 0x12345678;
let target = Target::IndirectARegDec(2);
cpu.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
cpu.port.port.write_beu32(ClockTime::START, INIT_ADDR, expected).unwrap();
cpu.state.a_reg[2] = (INIT_ADDR as u32) + 4;
let result = cpu.get_target_value(target, size, Used::Once).unwrap();

View File

@ -1,8 +1,8 @@
use moa_core::{System, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, wrap_transmutable};
use moa_core::{System, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, Device};
use moa_m68k::{M68k, M68kType};
use moa_m68k::instructions::{Instruction, Target, Size, Sign, XRegister, BaseRegister, IndexRegister, Direction, ShiftDirection};
use moa_m68k::instructions::{Instruction, Target, Size, Sign, XRegister, BaseRegister, IndexRegister, Direction};
use moa_m68k::assembler::M68kAssembler;
const INIT_STACK: Address = 0x00002000;
@ -67,7 +67,7 @@ fn init_decode_test(cputype: M68kType) -> (M68k, System) {
// Insert basic initialization
let data = vec![0; 0x00100000];
let mem = MemoryBlock::new(data);
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x00000000, Device::new(mem)).unwrap();
system.get_bus().write_beu32(ClockTime::START, 0, INIT_STACK as u32).unwrap();
system.get_bus().write_beu32(ClockTime::START, 4, INIT_ADDR as u32).unwrap();
@ -78,11 +78,11 @@ fn init_decode_test(cputype: M68kType) -> (M68k, System) {
BusPort::new(0, 24, 16, system.bus.clone())
};
let mut cpu = M68k::new(cputype, Frequency::from_mhz(10), port);
cpu.init().unwrap();
cpu.reset_cpu().unwrap();
assert_eq!(cpu.state.pc, INIT_ADDR as u32);
assert_eq!(cpu.state.ssp, INIT_STACK as u32);
cpu.decoder.init(ClockTime::START, INIT_ADDR as u32);
cpu.decoder.init(true, INIT_ADDR as u32);
assert_eq!(cpu.decoder.start, INIT_ADDR as u32);
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
(cpu, system)

View File

@ -1,9 +1,9 @@
use moa_core::{System, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, Steppable, wrap_transmutable};
use moa_core::{System, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, Steppable, Device};
use moa_m68k::{M68k, M68kType};
use moa_m68k::state::M68kState;
use moa_m68k::instructions::{Instruction, Target, Size, Sign, ShiftDirection, Direction, Condition};
use moa_m68k::instructions::{Instruction, Target, Size, Sign, Direction, Condition};
const INIT_STACK: Address = 0x00002000;
const INIT_ADDR: Address = 0x00000010;
@ -38,7 +38,7 @@ fn init_execute_test(cputype: M68kType) -> (M68k, System) {
// Insert basic initialization
let data = vec![0; 0x00100000];
let mem = MemoryBlock::new(data);
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x00000000, Device::new(mem)).unwrap();
system.get_bus().write_beu32(ClockTime::START, 0, INIT_STACK as u32).unwrap();
system.get_bus().write_beu32(ClockTime::START, 4, INIT_ADDR as u32).unwrap();
@ -49,7 +49,7 @@ fn init_execute_test(cputype: M68kType) -> (M68k, System) {
};
let mut cpu = M68k::new(cputype, Frequency::from_mhz(10), port);
cpu.step(&system).unwrap();
cpu.decoder.init(system.clock, cpu.state.pc);
cpu.decoder.init(true, cpu.state.pc);
assert_eq!(cpu.state.pc, INIT_ADDR as u32);
assert_eq!(cpu.state.ssp, INIT_STACK as u32);
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
@ -79,7 +79,7 @@ fn run_test(case: &TestCase) {
let (mut cpu, system) = init_execute_test(case.cputype);
let init_state = build_state(&case.init);
let mut expected_state = build_state(&case.fini);
let expected_state = build_state(&case.fini);
system.get_bus().write_beu32(system.clock, MEM_ADDR as Address, case.init.mem).unwrap();
load_memory(&system, case.data);
@ -89,7 +89,6 @@ fn run_test(case: &TestCase) {
assert_eq!(cpu.decoder.instruction, case.ins);
cpu.execute_current().unwrap();
expected_state.request = cpu.state.request.clone();
assert_eq!(cpu.state, expected_state);
let mem = system.get_bus().read_beu32(system.clock, MEM_ADDR as Address).unwrap();
@ -237,7 +236,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "asl",
ins: Instruction::ASd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left),
ins: Instruction::ASL(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE300 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000001, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -245,7 +244,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "asr",
ins: Instruction::ASd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right),
ins: Instruction::ASR(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE200 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000081, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -414,7 +413,7 @@ const TEST_CASES: &'static [TestCase] = &[
TestCase {
name: "lsl",
ins: Instruction::LSd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left),
ins: Instruction::LSL(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE308 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000001, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x271F, mem: 0x00000000 },
@ -422,7 +421,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "lsl with bit out",
ins: Instruction::LSd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left),
ins: Instruction::LSL(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE308 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000081, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -430,7 +429,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "lsr",
ins: Instruction::LSd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right),
ins: Instruction::LSR(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE208 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000081, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -604,7 +603,7 @@ const TEST_CASES: &'static [TestCase] = &[
TestCase {
name: "rol",
ins: Instruction::ROd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left),
ins: Instruction::ROL(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE318 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000080, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -612,7 +611,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "ror",
ins: Instruction::ROd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right),
ins: Instruction::ROR(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE218 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000001, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -620,7 +619,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "roxl",
ins: Instruction::ROXd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left),
ins: Instruction::ROXL(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE310 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000080, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -628,7 +627,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "roxr",
ins: Instruction::ROXd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right),
ins: Instruction::ROXR(Target::Immediate(1), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE210 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000001, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -636,7 +635,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "roxl two bits",
ins: Instruction::ROXd(Target::Immediate(2), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left),
ins: Instruction::ROXL(Target::Immediate(2), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE510 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000080, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },
@ -644,7 +643,7 @@ const TEST_CASES: &'static [TestCase] = &[
},
TestCase {
name: "roxr two bits",
ins: Instruction::ROXd(Target::Immediate(2), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right),
ins: Instruction::ROXR(Target::Immediate(2), Target::DirectDReg(0), Size::Byte),
data: &[ 0xE410 ],
cputype: M68kType::MC68010,
init: TestState { pc: 0x00000000, ssp: 0x00000000, usp: 0x00000000, d0: 0x00000001, d1: 0x00000000, a0: 0x00000000, a1: 0x00000000, sr: 0x2700, mem: 0x00000000 },

View File

@ -1,8 +1,8 @@
use moa_core::{System, Error, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, wrap_transmutable};
use moa_core::{System, Error, MemoryBlock, BusPort, ClockTime, Frequency, Address, Addressable, Device};
use moa_m68k::{M68k, M68kType};
use moa_m68k::instructions::{Instruction, Target, Size, Sign, Condition, XRegister, BaseRegister, IndexRegister, Direction, ShiftDirection};
use moa_m68k::instructions::{Instruction, Target, Size, Sign, Condition, XRegister, BaseRegister, IndexRegister, Direction};
use moa_m68k::timing::M68kInstructionTiming;
@ -15,7 +15,7 @@ fn init_decode_test(cputype: M68kType) -> (M68k, System) {
// Insert basic initialization
let data = vec![0; 0x00100000];
let mem = MemoryBlock::new(data);
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x00000000, Device::new(mem)).unwrap();
system.get_bus().write_beu32(ClockTime::START, 0, INIT_STACK as u32).unwrap();
system.get_bus().write_beu32(ClockTime::START, 4, INIT_ADDR as u32).unwrap();
@ -26,11 +26,11 @@ fn init_decode_test(cputype: M68kType) -> (M68k, System) {
BusPort::new(0, 24, 16, system.bus.clone())
};
let mut cpu = M68k::new(cputype, Frequency::from_mhz(10), port);
cpu.init_cycle().unwrap();
cpu.init_cycle(ClockTime::START);
assert_eq!(cpu.state.pc, INIT_ADDR as u32);
assert_eq!(cpu.state.ssp, INIT_STACK as u32);
cpu.decoder.init(ClockTime::START, INIT_ADDR as u32);
cpu.decoder.init(true, INIT_ADDR as u32);
assert_eq!(cpu.decoder.start, INIT_ADDR as u32);
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
(cpu, system)
@ -65,7 +65,7 @@ fn run_timing_test(case: &TimingCase) -> Result<(), Error> {
Ok(())
} else {
println!("{:?}", timing);
Err(Error::new(&format!("expected {} but found {}", expected, result)))
Err(Error::new(format!("expected {} but found {}", expected, result)))
}
}
@ -318,32 +318,32 @@ pub const TIMING_TESTS: &'static [TimingCase] = &[
TimingCase { cpu: M68kType::MC68000, data: &[0x02B0], timing: ( 34, 34, 11), ins: Instruction::AND(Target::Immediate(00000000), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0x02A0], timing: ( 30, 30, 9), ins: Instruction::AND(Target::Immediate(00000000), Target::IndirectARegDec(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0x0298], timing: ( 28, 28, 8), ins: Instruction::AND(Target::Immediate(00000000), Target::IndirectARegInc(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE120], timing: ( 6, 6, 8), ins: Instruction::ASd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE100], timing: ( 6, 6, 8), ins: Instruction::ASd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1D0], timing: ( 12, 12, 10), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1F9], timing: ( 20, 20, 10), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1F8], timing: ( 16, 16, 10), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1E8], timing: ( 16, 16, 11), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1F0], timing: ( 18, 18, 13), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1E0], timing: ( 14, 14, 11), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1D8], timing: ( 12, 12, 10), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE160], timing: ( 6, 6, 8), ins: Instruction::ASd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE140], timing: ( 6, 6, 8), ins: Instruction::ASd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1A0], timing: ( 8, 8, 8), ins: Instruction::ASd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE180], timing: ( 8, 8, 8), ins: Instruction::ASd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE020], timing: ( 6, 6, 6), ins: Instruction::ASd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE000], timing: ( 6, 6, 6), ins: Instruction::ASd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0D0], timing: ( 12, 12, 9), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0F9], timing: ( 20, 20, 9), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0F8], timing: ( 16, 16, 9), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0E8], timing: ( 16, 16, 10), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0F0], timing: ( 18, 18, 12), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0E0], timing: ( 14, 14, 10), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0D8], timing: ( 12, 12, 9), ins: Instruction::ASd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE060], timing: ( 6, 6, 6), ins: Instruction::ASd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE040], timing: ( 6, 6, 6), ins: Instruction::ASd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0A0], timing: ( 8, 8, 6), ins: Instruction::ASd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE080], timing: ( 8, 8, 6), ins: Instruction::ASd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE120], timing: ( 6, 6, 8), ins: Instruction::ASL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE100], timing: ( 6, 6, 8), ins: Instruction::ASL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1D0], timing: ( 12, 12, 10), ins: Instruction::ASL(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1F9], timing: ( 20, 20, 10), ins: Instruction::ASL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1F8], timing: ( 16, 16, 10), ins: Instruction::ASL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1E8], timing: ( 16, 16, 11), ins: Instruction::ASL(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1F0], timing: ( 18, 18, 13), ins: Instruction::ASL(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1E0], timing: ( 14, 14, 11), ins: Instruction::ASL(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1D8], timing: ( 12, 12, 10), ins: Instruction::ASL(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE160], timing: ( 6, 6, 8), ins: Instruction::ASL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE140], timing: ( 6, 6, 8), ins: Instruction::ASL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1A0], timing: ( 8, 8, 8), ins: Instruction::ASL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE180], timing: ( 8, 8, 8), ins: Instruction::ASL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE020], timing: ( 6, 6, 6), ins: Instruction::ASR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE000], timing: ( 6, 6, 6), ins: Instruction::ASR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0D0], timing: ( 12, 12, 9), ins: Instruction::ASR(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0F9], timing: ( 20, 20, 9), ins: Instruction::ASR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0F8], timing: ( 16, 16, 9), ins: Instruction::ASR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0E8], timing: ( 16, 16, 10), ins: Instruction::ASR(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0F0], timing: ( 18, 18, 12), ins: Instruction::ASR(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0E0], timing: ( 14, 14, 10), ins: Instruction::ASR(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0D8], timing: ( 12, 12, 9), ins: Instruction::ASR(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE060], timing: ( 6, 6, 6), ins: Instruction::ASR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE040], timing: ( 6, 6, 6), ins: Instruction::ASR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0A0], timing: ( 8, 8, 6), ins: Instruction::ASR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE080], timing: ( 8, 8, 6), ins: Instruction::ASR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0x6400], timing: ( 8, 8, 6), ins: Instruction::Bcc(Condition::CarryClear, 0x00000000) },
TimingCase { cpu: M68kType::MC68000, data: &[0x6400], timing: ( 10, 10, 6), ins: Instruction::Bcc(Condition::CarryClear, 0x00000000) },
TimingCase { cpu: M68kType::MC68000, data: &[0x0150], timing: ( 12, 12, 8), ins: Instruction::BCHG(Target::DirectDReg(0), Target::IndirectAReg(0), Size::Byte) },
@ -681,32 +681,32 @@ pub const TIMING_TESTS: &'static [TimingCase] = &[
TimingCase { cpu: M68kType::MC68000, data: &[0x41FA], timing: ( 8, 8, 7), ins: Instruction::LEA(Target::IndirectRegOffset(BaseRegister::PC, None, 0x00000000), 0) },
TimingCase { cpu: M68kType::MC68000, data: &[0x41FB], timing: ( 12, 12, 9), ins: Instruction::LEA(Target::IndirectRegOffset(BaseRegister::PC, Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), 0) },
TimingCase { cpu: M68kType::MC68000, data: &[0x4E50], timing: ( 16, 16, 5), ins: Instruction::LINK(0, 0x00000000) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE128], timing: ( 6, 6, 6), ins: Instruction::LSd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE108], timing: ( 6, 6, 4), ins: Instruction::LSd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3D0], timing: ( 12, 12, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3F9], timing: ( 20, 20, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3F8], timing: ( 16, 16, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3E8], timing: ( 16, 16, 10), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3F0], timing: ( 18, 18, 12), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3E0], timing: ( 14, 14, 10), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3D8], timing: ( 12, 12, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE168], timing: ( 6, 6, 6), ins: Instruction::LSd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE148], timing: ( 6, 6, 4), ins: Instruction::LSd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1A8], timing: ( 8, 8, 6), ins: Instruction::LSd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE188], timing: ( 8, 8, 4), ins: Instruction::LSd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE028], timing: ( 6, 6, 6), ins: Instruction::LSd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE008], timing: ( 6, 6, 4), ins: Instruction::LSd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2D0], timing: ( 12, 12, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2F9], timing: ( 20, 20, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2F8], timing: ( 16, 16, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2E8], timing: ( 16, 16, 10), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2F0], timing: ( 18, 18, 12), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2E0], timing: ( 14, 14, 10), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2D8], timing: ( 12, 12, 9), ins: Instruction::LSd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE068], timing: ( 6, 6, 6), ins: Instruction::LSd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE048], timing: ( 6, 6, 4), ins: Instruction::LSd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0A8], timing: ( 8, 8, 6), ins: Instruction::LSd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE088], timing: ( 8, 8, 4), ins: Instruction::LSd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE128], timing: ( 6, 6, 6), ins: Instruction::LSL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE108], timing: ( 6, 6, 4), ins: Instruction::LSL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3D0], timing: ( 12, 12, 9), ins: Instruction::LSL(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3F9], timing: ( 20, 20, 9), ins: Instruction::LSL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3F8], timing: ( 16, 16, 9), ins: Instruction::LSL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3E8], timing: ( 16, 16, 10), ins: Instruction::LSL(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3F0], timing: ( 18, 18, 12), ins: Instruction::LSL(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3E0], timing: ( 14, 14, 10), ins: Instruction::LSL(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE3D8], timing: ( 12, 12, 9), ins: Instruction::LSL(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE168], timing: ( 6, 6, 6), ins: Instruction::LSL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE148], timing: ( 6, 6, 4), ins: Instruction::LSL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1A8], timing: ( 8, 8, 6), ins: Instruction::LSL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE188], timing: ( 8, 8, 4), ins: Instruction::LSL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE028], timing: ( 6, 6, 6), ins: Instruction::LSR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE008], timing: ( 6, 6, 4), ins: Instruction::LSR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2D0], timing: ( 12, 12, 9), ins: Instruction::LSR(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2F9], timing: ( 20, 20, 9), ins: Instruction::LSR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2F8], timing: ( 16, 16, 9), ins: Instruction::LSR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2E8], timing: ( 16, 16, 10), ins: Instruction::LSR(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2F0], timing: ( 18, 18, 12), ins: Instruction::LSR(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2E0], timing: ( 14, 14, 10), ins: Instruction::LSR(Target::Immediate(00000001), Target::IndirectARegDec