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(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE2D8], timing: ( 12, 12, 9), ins: Instruction::LSR(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE068], timing: ( 6, 6, 6), ins: Instruction::LSR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE048], timing: ( 6, 6, 4), ins: Instruction::LSR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0A8], timing: ( 8, 8, 6), ins: Instruction::LSR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE088], timing: ( 8, 8, 4), ins: Instruction::LSR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0x1090], timing: ( 12, 12, 8), ins: Instruction::MOVE(Target::IndirectAReg(0), Target::IndirectAReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0x10B9], timing: ( 20, 20, 8), ins: Instruction::MOVE(Target::IndirectMemory(0x00000000, Size::Long), Target::IndirectAReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0x10B8], timing: ( 16, 16, 8), ins: Instruction::MOVE(Target::IndirectMemory(0x00000000, Size::Word), Target::IndirectAReg(0), Size::Byte) },
@ -1266,58 +1266,58 @@ pub const TIMING_TESTS: &'static [TimingCase] = &[
TimingCase { cpu: M68kType::MC68000, data: &[0x4870], timing: ( 20, 20, 12), ins: Instruction::PEA(Target::IndirectRegOffset(BaseRegister::AReg(0), Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000)) },
TimingCase { cpu: M68kType::MC68000, data: &[0x487A], timing: ( 16, 16, 10), ins: Instruction::PEA(Target::IndirectRegOffset(BaseRegister::PC, None, 0x00000000)) },
TimingCase { cpu: M68kType::MC68000, data: &[0x487B], timing: ( 20, 20, 12), ins: Instruction::PEA(Target::IndirectRegOffset(BaseRegister::PC, Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Word }), 0x00000000)) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE138], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE118], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7D0], timing: ( 12, 12, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7F9], timing: ( 20, 20, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7F8], timing: ( 16, 16, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7E8], timing: ( 16, 16, 12), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7F0], timing: ( 18, 18, 14), ins: Instruction::ROd(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: &[0xE7E0], timing: ( 14, 14, 12), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7D8], timing: ( 12, 12, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE178], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE158], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1B8], timing: ( 8, 8, 8), ins: Instruction::ROd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE198], timing: ( 8, 8, 8), ins: Instruction::ROd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE038], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE018], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6D0], timing: ( 12, 12, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6F9], timing: ( 20, 20, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6F8], timing: ( 16, 16, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6E8], timing: ( 16, 16, 12), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6F0], timing: ( 18, 18, 14), ins: Instruction::ROd(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: &[0xE6E0], timing: ( 14, 14, 12), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6D8], timing: ( 12, 12, 11), ins: Instruction::ROd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE078], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE058], timing: ( 6, 6, 8), ins: Instruction::ROd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0B8], timing: ( 8, 8, 8), ins: Instruction::ROd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE098], timing: ( 8, 8, 8), ins: Instruction::ROd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE130], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE110], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5D0], timing: ( 12, 12, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5F9], timing: ( 20, 20, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5F8], timing: ( 16, 16, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5E8], timing: ( 16, 16, 10), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5F0], timing: ( 18, 18, 12), ins: Instruction::ROXd(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: &[0xE5E0], timing: ( 14, 14, 10), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5D8], timing: ( 12, 12, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE170], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE150], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1B0], timing: ( 8, 8, 12), ins: Instruction::ROXd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE190], timing: ( 8, 8, 12), ins: Instruction::ROXd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Left) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE030], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE010], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4D0], timing: ( 12, 12, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4F9], timing: ( 20, 20, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4F8], timing: ( 16, 16, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4E8], timing: ( 16, 16, 10), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4F0], timing: ( 18, 18, 12), ins: Instruction::ROXd(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: &[0xE4E0], timing: ( 14, 14, 10), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4D8], timing: ( 12, 12, 9), ins: Instruction::ROXd(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE070], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE050], timing: ( 6, 6, 12), ins: Instruction::ROXd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0B0], timing: ( 8, 8, 12), ins: Instruction::ROXd(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE090], timing: ( 8, 8, 12), ins: Instruction::ROXd(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long, ShiftDirection::Right) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE138], timing: ( 6, 6, 8), ins: Instruction::ROL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE118], timing: ( 6, 6, 8), ins: Instruction::ROL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7D0], timing: ( 12, 12, 11), ins: Instruction::ROL(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7F9], timing: ( 20, 20, 11), ins: Instruction::ROL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7F8], timing: ( 16, 16, 11), ins: Instruction::ROL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7E8], timing: ( 16, 16, 12), ins: Instruction::ROL(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7F0], timing: ( 18, 18, 14), ins: Instruction::ROL(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: &[0xE7E0], timing: ( 14, 14, 12), ins: Instruction::ROL(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE7D8], timing: ( 12, 12, 11), ins: Instruction::ROL(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE178], timing: ( 6, 6, 8), ins: Instruction::ROL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE158], timing: ( 6, 6, 8), ins: Instruction::ROL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1B8], timing: ( 8, 8, 8), ins: Instruction::ROL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE198], timing: ( 8, 8, 8), ins: Instruction::ROL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE038], timing: ( 6, 6, 8), ins: Instruction::ROR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE018], timing: ( 6, 6, 8), ins: Instruction::ROR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6D0], timing: ( 12, 12, 11), ins: Instruction::ROR(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6F9], timing: ( 20, 20, 11), ins: Instruction::ROR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6F8], timing: ( 16, 16, 11), ins: Instruction::ROR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6E8], timing: ( 16, 16, 12), ins: Instruction::ROR(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6F0], timing: ( 18, 18, 14), ins: Instruction::ROR(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: &[0xE6E0], timing: ( 14, 14, 12), ins: Instruction::ROR(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE6D8], timing: ( 12, 12, 11), ins: Instruction::ROR(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE078], timing: ( 6, 6, 8), ins: Instruction::ROR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE058], timing: ( 6, 6, 8), ins: Instruction::ROR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0B8], timing: ( 8, 8, 8), ins: Instruction::ROR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE098], timing: ( 8, 8, 8), ins: Instruction::ROR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE130], timing: ( 6, 6, 12), ins: Instruction::ROXL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE110], timing: ( 6, 6, 12), ins: Instruction::ROXL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5D0], timing: ( 12, 12, 9), ins: Instruction::ROXL(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5F9], timing: ( 20, 20, 9), ins: Instruction::ROXL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5F8], timing: ( 16, 16, 9), ins: Instruction::ROXL(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5E8], timing: ( 16, 16, 10), ins: Instruction::ROXL(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5F0], timing: ( 18, 18, 12), ins: Instruction::ROXL(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: &[0xE5E0], timing: ( 14, 14, 10), ins: Instruction::ROXL(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE5D8], timing: ( 12, 12, 9), ins: Instruction::ROXL(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE170], timing: ( 6, 6, 12), ins: Instruction::ROXL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE150], timing: ( 6, 6, 12), ins: Instruction::ROXL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE1B0], timing: ( 8, 8, 12), ins: Instruction::ROXL(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE190], timing: ( 8, 8, 12), ins: Instruction::ROXL(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE030], timing: ( 6, 6, 12), ins: Instruction::ROXR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE010], timing: ( 6, 6, 12), ins: Instruction::ROXR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Byte) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4D0], timing: ( 12, 12, 9), ins: Instruction::ROXR(Target::Immediate(00000001), Target::IndirectAReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4F9], timing: ( 20, 20, 9), ins: Instruction::ROXR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Long), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4F8], timing: ( 16, 16, 9), ins: Instruction::ROXR(Target::Immediate(00000001), Target::IndirectMemory(0x00000000, Size::Word), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4E8], timing: ( 16, 16, 10), ins: Instruction::ROXR(Target::Immediate(00000001), Target::IndirectRegOffset(BaseRegister::AReg(0), None, 0x00000000), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4F0], timing: ( 18, 18, 12), ins: Instruction::ROXR(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: &[0xE4E0], timing: ( 14, 14, 10), ins: Instruction::ROXR(Target::Immediate(00000001), Target::IndirectARegDec(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE4D8], timing: ( 12, 12, 9), ins: Instruction::ROXR(Target::Immediate(00000001), Target::IndirectARegInc(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE070], timing: ( 6, 6, 12), ins: Instruction::ROXR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE050], timing: ( 6, 6, 12), ins: Instruction::ROXR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Word) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE0B0], timing: ( 8, 8, 12), ins: Instruction::ROXR(Target::DirectDReg(0), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0xE090], timing: ( 8, 8, 12), ins: Instruction::ROXR(Target::Immediate(00000008), Target::DirectDReg(0), Size::Long) },
TimingCase { cpu: M68kType::MC68000, data: &[0x4E73], timing: ( 20, 24, 20), ins: Instruction::RTE },
TimingCase { cpu: M68kType::MC68000, data: &[0x4E77], timing: ( 20, 20, 14), ins: Instruction::RTR },
TimingCase { cpu: M68kType::MC68000, data: &[0x4E75], timing: ( 16, 16, 10), ins: Instruction::RTS },

View File

@ -1,5 +1,5 @@
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};
@ -27,7 +27,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();
@ -38,11 +38,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)
@ -77,7 +77,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)))
}
}

View File

@ -214,7 +214,7 @@ impl Z80 {
Instruction::SUB(target) => self.execute_sub(target),
Instruction::XOR(target) => self.execute_xor(target),
_ => {
Err(Error::new(&format!("{}: unimplemented instruction: {:?}", DEV_NAME, self.decoder.instruction)))
Err(Error::new(format!("{}: unimplemented instruction: {:?}", DEV_NAME, self.decoder.instruction)))
}
}
}

View File

@ -203,11 +203,7 @@ impl From<u8> for InterruptMode {
impl RegisterPair {
pub(crate) fn is_index_reg(&self) -> bool {
match self {
RegisterPair::IX |
RegisterPair::IY => true,
_ => false,
}
matches!(self, RegisterPair::IX | RegisterPair::IY)
}
}

View File

@ -1,5 +1,5 @@
use moa_core::{System, MemoryBlock, BusPort, Frequency, Address, Addressable, wrap_transmutable};
use moa_core::{System, MemoryBlock, BusPort, Frequency, Address, Addressable, Device};
use moa_z80::{Z80, Z80Type};
use moa_z80::instructions::{Instruction, LoadTarget, Target, Register, RegisterPair, IndexRegister, IndexRegisterHalf};
@ -10,11 +10,11 @@ fn init_decode_test() -> (Z80, System) {
// Insert basic initialization
let data = vec![0; 0x10000];
let mem = MemoryBlock::new(data);
system.add_addressable_device(0x0000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x0000, Device::new(mem)).unwrap();
// Initialize the CPU and make sure it's in the expected state
let mut cpu = Z80::new(Z80Type::Z80, Frequency::from_mhz(4), BusPort::new(0, 16, 8, system.bus.clone()), None);
cpu.init().unwrap();
cpu.reset().unwrap();
(cpu, system)
}

View File

@ -1,5 +1,5 @@
use moa_core::{System, MemoryBlock, BusPort, Frequency, Address, Addressable, wrap_transmutable};
use moa_core::{System, MemoryBlock, BusPort, Frequency, Address, Addressable, Device};
use moa_z80::{Z80, Z80Type};
use moa_z80::state::Z80State;
@ -486,7 +486,7 @@ fn init_execute_test() -> (Z80, System) {
// Insert basic initialization
let data = vec![0; 0x10000];
let mem = MemoryBlock::new(data);
system.add_addressable_device(0x0000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x0000, Device::new(mem)).unwrap();
// Initialize the CPU and make sure it's in the expected state
let mut cpu = Z80::new(Z80Type::Z80, Frequency::from_mhz(4), BusPort::new(0, 16, 8, system.bus.clone()), None);

View File

@ -2,7 +2,7 @@
use std::thread;
use std::time::Duration;
use moa_core::{System, Frequency, MemoryBlock, BusPort, wrap_transmutable};
use moa_core::{System, Frequency, MemoryBlock, BusPort, Device};
use moa_m68k::{M68k, M68kType};
use moa_peripherals_generic::AtaDevice;
@ -13,18 +13,18 @@ fn main() {
let mut system = System::default();
let monitor = MemoryBlock::load("binaries/computie/monitor.bin").unwrap();
system.add_addressable_device(0x00000000, wrap_transmutable(monitor)).unwrap();
system.add_addressable_device(0x00000000, Device::new(monitor)).unwrap();
let mut ram = MemoryBlock::new(vec![0; 0x00100000]);
ram.load_at(0, "binaries/computie/kernel.bin").unwrap();
system.add_addressable_device(0x00100000, wrap_transmutable(ram)).unwrap();
system.add_addressable_device(0x00100000, Device::new(ram)).unwrap();
let mut ata = AtaDevice::default();
ata.load("binaries/computie/disk-with-partition-table.img").unwrap();
system.add_addressable_device(0x00600000, wrap_transmutable(ata)).unwrap();
system.add_addressable_device(0x00600000, Device::new(ata)).unwrap();
let serial = MC68681::default();
system.add_addressable_device(0x00700000, wrap_transmutable(serial)).unwrap();
system.add_addressable_device(0x00700000, Device::new(serial)).unwrap();
let cpu = M68k::new(M68kType::MC68010, Frequency::from_mhz(8), BusPort::new(0, 24, 16, system.bus.clone()));
@ -38,9 +38,9 @@ fn main() {
//cpu.decoder.dump_disassembly(&mut system, 0x100000, 0x2000);
//cpu.decoder.dump_disassembly(&mut system, 0x2ac, 0x200);
system.add_interruptable_device("cpu", wrap_transmutable(cpu)).unwrap();
system.add_interruptable_device("cpu", Device::new(cpu)).unwrap();
system.run_loop();
system.run_forever().unwrap();
});
thread::sleep(Duration::from_secs(10));
}

View File

@ -8,7 +8,7 @@ fn main() {
let mut frontend = ConsoleFrontend::new();
let mut system = build_computie(&mut frontend).unwrap();
let system = build_computie(&mut frontend).unwrap();
frontend.start(matches, system);
}

View File

@ -2,7 +2,7 @@
use moa_peripherals_yamaha::{Ym2612, Sn76489};
use moa_core::host::{self, Host, Frame, FrameSender, PixelEncoding, Key, KeyEvent, EventReceiver};
use moa_core::{System, Error, ClockTime, ClockDuration, Frequency, Address, Addressable, Steppable, Transmutable, TransmutableBox, wrap_transmutable};
use moa_core::{System, Error, ClockTime, ClockDuration, Frequency, Address, Addressable, Steppable, Transmutable, Device};
const SCREEN_WIDTH: u32 = 384;
const SCREEN_HEIGHT: u32 = 128;
@ -61,7 +61,7 @@ fn set_register(device: &mut dyn Addressable, bank: u8, reg: u8, data: u8) -> Re
Ok(())
}
fn initialize_ym(ym_sound: TransmutableBox) -> Result<(), Error> {
fn initialize_ym(ym_sound: Device) -> Result<(), Error> {
let mut borrow = ym_sound.borrow_mut();
let device = borrow.as_addressable().unwrap();
@ -85,14 +85,14 @@ fn main() {
let (frame_sender, frame_receiver) = host::frame_queue(SCREEN_WIDTH, SCREEN_HEIGHT);
let (key_sender, key_receiver) = host::event_queue();
let control = wrap_transmutable(SynthControl::new(key_receiver, frame_sender));
let control = Device::new(SynthControl::new(key_receiver, frame_sender));
system.add_device("control", control)?;
let ym_sound = wrap_transmutable(Ym2612::new(host, Frequency::from_hz(7_670_454))?);
let ym_sound = Device::new(Ym2612::new(host, Frequency::from_hz(7_670_454))?);
initialize_ym(ym_sound.clone())?;
system.add_addressable_device(0x00, ym_sound)?;
let sn_sound = wrap_transmutable(Sn76489::new(host, Frequency::from_hz(3_579_545))?);
let sn_sound = Device::new(Sn76489::new(host, Frequency::from_hz(3_579_545))?);
system.add_addressable_device(0x10, sn_sound)?;
host.add_video_source(frame_receiver)?;

View File

@ -1,5 +1,5 @@
use clap::Arg;
use clap::{Arg, ArgAction};
use moa_systems_trs80::{build_trs80, Trs80Options};
@ -8,13 +8,13 @@ fn main() {
.arg(Arg::new("ROM")
.short('r')
.long("rom")
.takes_value(true)
.action(ArgAction::SetTrue)
.value_name("FILE")
.help("ROM file to load at the start of memory"))
.get_matches();
let mut options = Trs80Options::default();
if let Some(filename) = matches.value_of("ROM") {
if let Some(filename) = matches.get_one::<String>("ROM") {
options.rom = filename.to_string();
}

View File

@ -269,13 +269,13 @@ impl MiniFrontend {
let mut last_frame = Frame::new(size.0, size.1, PixelEncoding::ARGB);
while window.is_open() && !window.is_key_down(Key::Escape) {
if run_debugger {
if let Some(mut system) = system.as_mut() {
debugger.print_step(&mut system).unwrap();
if debugger.check_auto_command(&mut system).unwrap() != DebugControl::Continue {
if let Some(system) = system.as_mut() {
debugger.print_step(system).unwrap();
if debugger.check_auto_command(system).unwrap() != DebugControl::Continue {
let mut buffer = String::new();
io::stdout().write_all(b"> ").unwrap();
io::stdin().read_line(&mut buffer).unwrap();
match debugger.run_command(&mut system, &buffer) {
match debugger.run_command(system, &buffer) {
Ok(DebugControl::Exit) => {
run_debugger = false;
},

View File

@ -73,7 +73,7 @@ impl<'input> AssemblyParser<'input> {
}
},
_ => {
return Err(Error::new(&format!("parse error at line {}: expected word, found {:?}", self.lexer.lineno(), token)));
return Err(Error::new(format!("parse error at line {}: expected word, found {:?}", self.lexer.lineno(), token)));
},
};
@ -174,7 +174,7 @@ fn parse_any_number(lineno: usize, string: &str) -> Result<usize, Error> {
(10, string)
};
usize::from_str_radix(numeric, radix)
.map_err(|_| Error::new(&format!("parse error at line {}: expected number after #, but found {:?}", lineno, string)))
.map_err(|_| Error::new(format!("parse error at line {}: expected number after #, but found {:?}", lineno, string)))
}
@ -204,7 +204,7 @@ impl<'input> AssemblyLexer<'input> {
pub fn get_next(&mut self) -> Option<String> {
if self.peeked.is_some() {
let result = std::mem::replace(&mut self.peeked, None);
let result = self.peeked.take();
return result;
}
@ -231,7 +231,7 @@ impl<'input> AssemblyLexer<'input> {
}
pub fn expect_next(&mut self) -> Result<String, Error> {
self.get_next().ok_or_else(|| Error::new(&format!("unexpected end of input at line {}", self.lineno)))
self.get_next().ok_or_else(|| Error::new(format!("unexpected end of input at line {}", self.lineno)))
}
pub fn expect_token(&mut self, expected: &str) -> Result<(), Error> {
@ -239,7 +239,7 @@ impl<'input> AssemblyLexer<'input> {
if token == expected {
Ok(())
} else {
Err(Error::new(&format!("parse error at line {}: expected {:?}, found {:?}", self.lineno, expected, token)))
Err(Error::new(format!("parse error at line {}: expected {:?}, found {:?}", self.lineno, expected, token)))
}
}
@ -248,7 +248,7 @@ impl<'input> AssemblyLexer<'input> {
if token.is_none() || token.as_ref().unwrap() == "\n" {
Ok(())
} else {
Err(Error::new(&format!("expected end of line at {}: found {:?}", self.lineno, token)))
Err(Error::new(format!("expected end of line at {}: found {:?}", self.lineno, token)))
}
}
@ -294,18 +294,18 @@ impl<'input> AssemblyLexer<'input> {
}
fn is_word(ch: char) -> bool {
('a'..='z').contains(&ch) || ('A'..='Z').contains(&ch) || ('0'..='9').contains(&ch) || (ch == '_')
ch.is_ascii_lowercase() || ch.is_ascii_uppercase() || ch.is_ascii_digit() || (ch == '_')
}
fn is_digit(ch: char) -> bool {
('0'..='9').contains(&ch)
ch.is_ascii_digit()
}
pub fn expect_args(lineno: usize, args: &[AssemblyOperand], expected: usize) -> Result<(), Error> {
if args.len() == expected {
Ok(())
} else {
Err(Error::new(&format!("error at line {}: expected {} args, but found {}", lineno, expected, args.len())))
Err(Error::new(format!("error at line {}: expected {} args, but found {}", lineno, expected, args.len())))
}
}
@ -314,7 +314,7 @@ pub fn expect_label(lineno: usize, args: &[AssemblyOperand]) -> Result<String, E
if let AssemblyOperand::Label(name) = &args[0] {
Ok(name.clone())
} else {
Err(Error::new(&format!("error at line {}: expected a label, but found {:?}", lineno, args)))
Err(Error::new(format!("error at line {}: expected a label, but found {:?}", lineno, args)))
}
}
@ -322,7 +322,7 @@ pub fn expect_immediate(lineno: usize, operand: &AssemblyOperand) -> Result<usiz
if let AssemblyOperand::Immediate(value) = operand {
Ok(*value)
} else {
Err(Error::new(&format!("error at line {}: expected an immediate value, but found {:?}", lineno, operand)))
Err(Error::new(format!("error at line {}: expected an immediate value, but found {:?}", lineno, operand)))
}
}

View File

@ -47,7 +47,7 @@ impl AtaDevice {
self.contents = contents;
Ok(())
},
Err(_) => Err(Error::new(&format!("Error reading contents of {}", filename))),
Err(_) => Err(Error::new(format!("Error reading contents of {}", filename))),
}
}
}

View File

@ -408,9 +408,9 @@ impl PhaseGenerator {
let detune_index = (self.detune & 0x03) as usize;
let detune = DETUNE_TABLE[keycode * 4 + detune_index] as u32;
let increment = if sign == 0 {
increment + detune
increment.saturating_add(detune)
} else {
increment - detune
increment.saturating_sub(detune)
}.min(0x1FFFF);
// Apply multiple

View File

@ -854,7 +854,7 @@ impl Addressable for Ym7101 {
if data.len() == 4 {
let value = read_beu16(&data[2..]);
if (value & 0xC000) != 0x8000 {
return Err(Error::new(&format!("{}: unexpected second byte {:x}", DEV_NAME, value)));
return Err(Error::new(format!("{}: unexpected second byte {:x}", DEV_NAME, value)));
}
self.set_register(value);
}

View File

@ -11,7 +11,7 @@ pub fn smd_to_bin(input: Vec<u8>) -> Result<Vec<u8>, Error> {
let mut output = vec![0; input.len() - SMD_HEADER];
if &input[8..10] != SMD_MAGIC {
return Err(Error::new(&format!("smd: magic not found: {:?}", &input[8..10])));
return Err(Error::new(format!("smd: magic not found: {:?}", &input[8..10])));
}
let calculated_blocks = (input.len() - SMD_HEADER) / SMD_BLOCK_SIZE;
@ -31,7 +31,7 @@ pub fn smd_to_bin(input: Vec<u8>) -> Result<Vec<u8>, Error> {
}
pub fn load_rom_file(filename: &str) -> Result<Vec<u8>, Error> {
let mut contents = fs::read(filename).map_err(|_| Error::new(&format!("Error reading contents of {}", filename)))?;
let mut contents = fs::read(filename).map_err(|_| Error::new(format!("Error reading contents of {}", filename)))?;
if filename.ends_with(".smd") {
contents = smd_to_bin(contents)?;

View File

@ -86,7 +86,7 @@ impl Addressable for Mainboard {
// Debugger
Ok(())
} else {
Err(Error::new(&format!("Error reading address {:#010x}", addr)))
Err(Error::new(format!("Error reading address {:#010x}", addr)))
}
}
@ -104,7 +104,7 @@ impl Addressable for Mainboard {
} else if (0xF00000..0xF80000).contains(&addr) {
self.phase_read.write(clock, addr, data)
} else {
Err(Error::new(&format!("Error writing address {:#010x}", addr)))
Err(Error::new(format!("Error writing address {:#010x}", addr)))
}
}
}

View File

@ -11,7 +11,7 @@ use clap::{Parser, ArgEnum};
use flate2::read::GzDecoder;
use serde_derive::Deserialize;
use moa_core::{System, Error, MemoryBlock, BusPort, Frequency, Address, Addressable, Steppable, wrap_transmutable};
use moa_core::{System, Error, MemoryBlock, BusPort, Frequency, Address, Addressable, Steppable, Device};
use moa_m68k::{M68k, M68kType};
use moa_m68k::state::Status;
@ -142,7 +142,7 @@ fn init_execute_test(cputype: M68kType, state: &TestState) -> Result<(M68k, Syst
// Insert basic initialization
let data = vec![0; 0x01000000];
let mem = MemoryBlock::new(data);
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x00000000, Device::new(mem)).unwrap();
let port = if cputype <= M68kType::MC68010 {
BusPort::new(0, 24, 16, system.bus.clone())

View File

@ -13,7 +13,7 @@ use clap::Parser;
use flate2::read::GzDecoder;
use serde_derive::Deserialize;
use moa_core::{System, Error, MemoryBlock, Bus, BusPort, Frequency, Address, Addressable, Steppable, wrap_transmutable};
use moa_core::{System, Error, MemoryBlock, Bus, BusPort, Frequency, Address, Addressable, Steppable, Device};
use moa_z80::{Z80, Z80Type};
use moa_z80::instructions::InterruptMode;
@ -150,10 +150,10 @@ fn init_execute_test(cputype: Z80Type, state: &TestState, ports: &[TestPort]) ->
// Insert basic initialization
let mem = MemoryBlock::new(vec![0; 0x1_0000]);
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
system.add_addressable_device(0x00000000, Device::new(mem)).unwrap();
// Set up IOREQ as memory space
let io_ram = wrap_transmutable(MemoryBlock::new(vec![0; 0x10000]));
let io_ram = Device::new(MemoryBlock::new(vec![0; 0x10000]));
let io_bus = Rc::new(RefCell::new(Bus::default()));
io_bus.borrow_mut().set_ignore_unmapped(true);
io_bus.borrow_mut().insert(0x0000, io_ram.clone());