2021-10-02 02:27:05 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
2021-10-11 22:04:39 +00:00
|
|
|
mod decode_tests {
|
2021-10-18 23:34:55 +00:00
|
|
|
use crate::error::{Error, ErrorType};
|
2021-10-11 22:04:39 +00:00
|
|
|
use crate::system::System;
|
2021-10-27 04:32:25 +00:00
|
|
|
use crate::memory::{MemoryBlock, BusPort};
|
2021-10-18 19:05:10 +00:00
|
|
|
use crate::devices::{Address, Addressable, Steppable, TransmutableBox, wrap_transmutable, MAX_READ};
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
use crate::cpus::m68k::{M68k, M68kType};
|
2021-10-18 23:34:55 +00:00
|
|
|
use crate::cpus::m68k::state::Exceptions;
|
|
|
|
use crate::cpus::m68k::instructions::{Instruction, Target, Size, Sign, XRegister, BaseRegister, IndexRegister, ShiftDirection};
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
const INIT_STACK: Address = 0x00002000;
|
|
|
|
const INIT_ADDR: Address = 0x00000010;
|
|
|
|
|
2021-10-18 23:34:55 +00:00
|
|
|
fn init_decode_test(cputype: M68kType) -> (M68k, System) {
|
2021-10-11 22:04:39 +00:00
|
|
|
let mut system = System::new();
|
|
|
|
|
|
|
|
// Insert basic initialization
|
|
|
|
let data = vec![0; 0x00100000];
|
|
|
|
let mem = MemoryBlock::new(data);
|
2021-10-18 19:05:10 +00:00
|
|
|
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
system.get_bus().write_beu32(0, INIT_STACK as u32).unwrap();
|
|
|
|
system.get_bus().write_beu32(4, INIT_ADDR as u32).unwrap();
|
|
|
|
|
|
|
|
// Initialize the CPU and make sure it's in the expected state
|
2021-10-27 04:32:25 +00:00
|
|
|
let port = if cputype <= M68kType::MC68010 {
|
|
|
|
BusPort::new(0, 24, 16, system.bus.clone())
|
|
|
|
} else {
|
|
|
|
BusPort::new(0, 24, 16, system.bus.clone())
|
|
|
|
};
|
|
|
|
let mut cpu = M68k::new(cputype, 10_000_000, port);
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.init(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state.pc, INIT_ADDR as u32);
|
|
|
|
assert_eq!(cpu.state.msp, INIT_STACK as u32);
|
2021-10-27 04:32:25 +00:00
|
|
|
|
|
|
|
cpu.decoder.init(INIT_ADDR as u32);
|
|
|
|
assert_eq!(cpu.decoder.start, INIT_ADDR as u32);
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
|
|
|
|
(cpu, system)
|
|
|
|
}
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
fn load_memory(system: &System, data: &[u16]) {
|
|
|
|
let mut addr = INIT_ADDR;
|
|
|
|
for word in data {
|
|
|
|
system.get_bus().write_beu16(addr, *word).unwrap();
|
|
|
|
addr += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
//
|
|
|
|
// Addressing Mode Target Tests
|
|
|
|
//
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_direct_d() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x1234;
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b000, 0b001, Some(size)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(target, Target::DirectDReg(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_direct_a() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x1234;
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b001, 0b010, Some(size)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(target, Target::DirectAReg(2));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_a() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let expected_addr = INIT_ADDR;
|
|
|
|
let expected = 0x12345678;
|
|
|
|
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b010, 0b010, Some(size)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(target, Target::IndirectAReg(2));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_a_inc() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let expected_addr = INIT_ADDR;
|
|
|
|
let expected = 0x12345678;
|
|
|
|
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b011, 0b010, Some(size)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(target, Target::IndirectARegInc(2));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_a_dec() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let expected_addr = INIT_ADDR + 4;
|
|
|
|
let expected = 0x12345678;
|
|
|
|
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b100, 0b010, Some(size)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(target, Target::IndirectARegDec(2));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_a_reg_offset() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let offset = -8;
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, (offset as i16) as u16).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b101, 0b100, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(4), None, offset));
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-10-18 23:34:55 +00:00
|
|
|
fn target_indirect_a_reg_brief_extension_word() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let offset = -8;
|
|
|
|
let brief_extension = 0x3800 | (((offset as i8) as u8) as u16);
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, brief_extension).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, (offset as i16) as u16).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b110, 0b010, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(2), Some(IndexRegister { xreg: XRegister::DReg(3), scale: 0, size: size }), offset));
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-10-18 23:34:55 +00:00
|
|
|
fn target_indirect_a_reg_full_extension_word() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68020);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
2021-10-18 23:34:55 +00:00
|
|
|
let offset = -1843235 as i32;
|
|
|
|
let brief_extension = 0xF330;
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-18 23:34:55 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, brief_extension).unwrap();
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR + 2, offset as u32).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b110, 0b010, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(2), Some(IndexRegister { xreg: XRegister::AReg(7), scale: 1, size: size }), offset));
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-10-18 23:34:55 +00:00
|
|
|
fn target_indirect_a_reg_full_extension_word_no_base() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68020);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
2021-10-18 23:34:55 +00:00
|
|
|
let offset = -1843235 as i32;
|
|
|
|
let brief_extension = 0xF3B0;
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-18 23:34:55 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, brief_extension).unwrap();
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR + 2, offset as u32).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b110, 0b010, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::None, Some(IndexRegister { xreg: XRegister::AReg(7), scale: 1, size: size }), offset));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_a_reg_full_extension_word_no_index() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68020);
|
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let offset = -1843235 as i32;
|
|
|
|
let brief_extension = 0xF370;
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, brief_extension).unwrap();
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR + 2, offset as u32).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b110, 0b010, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::AReg(2), None, offset));
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_pc_offset() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let offset = -8;
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, (offset as i16) as u16).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b111, 0b010, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::PC, None, offset));
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-10-18 23:34:55 +00:00
|
|
|
fn target_indirect_pc_brief_extension_word() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 03:47:51 +00:00
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
let size = Size::Word;
|
|
|
|
let offset = -8;
|
|
|
|
let brief_extension = 0x3000 | (((offset as i8) as u8) as u16);
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, brief_extension).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, (offset as i16) as u16).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b111, 0b011, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::PC, Some(IndexRegister { xreg: XRegister::DReg(3), scale: 0, size: size }), offset));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_pc_full_extension_word() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68020);
|
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let offset = -1843235 as i32;
|
|
|
|
let brief_extension = 0xF330;
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, brief_extension).unwrap();
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR + 2, offset as u32).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b111, 0b011, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectRegOffset(BaseRegister::PC, Some(IndexRegister { xreg: XRegister::AReg(7), scale: 1, size: size }), offset));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_immediate_word() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x1234;
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, expected as u16).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b111, 0b000, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectMemory(expected));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_indirect_immediate_long() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x12345678;
|
|
|
|
|
|
|
|
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b111, 0b001, Some(size)).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
assert_eq!(target, Target::IndirectMemory(expected));
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_immediate() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x1234;
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, expected as u16).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b111, 0b100, Some(size)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(target, Target::Immediate(expected));
|
|
|
|
}
|
|
|
|
|
2021-10-18 23:34:55 +00:00
|
|
|
#[test]
|
|
|
|
fn target_full_extension_word_unsupported_on_mc68010() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
let brief_extension = 0x0100;
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, brief_extension).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let result = cpu.decoder.get_mode_as_target(&mut cpu.port, 0b110, 0b010, Some(Size::Long));
|
2021-10-18 23:34:55 +00:00
|
|
|
match result {
|
|
|
|
Err(Error { err: ErrorType::Processor, native, .. }) if native == Exceptions::IllegalInstruction as u32 => { },
|
|
|
|
result => panic!("Expected illegal instruction but found: {:?}", result),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
//
|
|
|
|
// Instruction Decode Tests
|
|
|
|
//
|
2021-10-02 02:27:05 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_nop() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-02 02:27:05 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x4e71]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-02 15:47:20 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
|
2021-10-02 02:27:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-10-26 19:17:59 +00:00
|
|
|
fn instruction_ori_byte() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-02 02:27:05 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x0008, 0x00FF]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-02 15:47:20 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::OR(Target::Immediate(0xFF), Target::DirectAReg(0), Size::Byte));
|
2021-10-02 02:27:05 +00:00
|
|
|
}
|
2021-10-02 22:35:08 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_ori_to_ccr() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x003C, 0x00FF]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ORtoCCR(0xFF));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_ori_to_sr() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x007C, 0x1234]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ORtoSR(0x1234));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_andi_word() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x0263, 0x1234]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::AND(Target::Immediate(0x1234), Target::IndirectARegDec(3), Size::Word));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_andi_to_ccr() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x023C, 0x1234]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ANDtoCCR(0x34));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_andi_to_sr() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x027C, 0xF8FF]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ANDtoSR(0xF8FF));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_subi() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x0487, 0x1234, 0x5678]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::SUB(Target::Immediate(0x12345678), Target::DirectDReg(7), Size::Long));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_addi() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x063A, 0x1234, 0x0055]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ADD(Target::Immediate(0x34), Target::IndirectRegOffset(BaseRegister::PC, None, 0x55), Size::Byte));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_eori_byte() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x0A23, 0x1234]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::EOR(Target::Immediate(0x34), Target::IndirectARegDec(3), Size::Byte));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_eori_to_ccr() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x0A3C, 0x1234]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::EORtoCCR(0x34));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_eori_to_sr() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
load_memory(&system, &[0x0A7C, 0xF8FF]);
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::EORtoSR(0xF8FF));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-02 22:35:08 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_cmpi_equal() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-02 22:35:08 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x0C00, 0x0020]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-02 22:35:08 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::CMP(Target::Immediate(0x20), Target::DirectDReg(0), Size::Byte));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmpi_greater() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-02 22:35:08 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x0C00, 0x0030]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-02 22:35:08 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::CMP(Target::Immediate(0x30), Target::DirectDReg(0), Size::Byte));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmpi_less() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-02 22:35:08 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x0C00, 0x0010]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-02 22:35:08 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::CMP(Target::Immediate(0x10), Target::DirectDReg(0), Size::Byte));
|
|
|
|
}
|
Added MUL, DIV, NEG, DBcc, and Scc instructions, and fixed issue with ADD/SUB flags
With ADDA, SUBA, and ADDQ/SUBQ when the target is an address register, the condition
flags should not be changed, but the code was changing them, which caused problems.
I've fixed it by making the ADD/SUB executions check for an address target and
will not update flags in that case. This should only occur when the actual instruction
was an ADDA or ADDQ with an address register target
2021-10-03 04:59:28 +00:00
|
|
|
|
|
|
|
#[test]
|
2021-10-26 19:17:59 +00:00
|
|
|
fn instruction_movel_full_extension() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68030);
|
Added MUL, DIV, NEG, DBcc, and Scc instructions, and fixed issue with ADD/SUB flags
With ADDA, SUBA, and ADDQ/SUBQ when the target is an address register, the condition
flags should not be changed, but the code was changing them, which caused problems.
I've fixed it by making the ADD/SUB executions check for an address target and
will not update flags in that case. This should only occur when the actual instruction
was an ADDA or ADDQ with an address register target
2021-10-03 04:59:28 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x21bc, 0x0010, 0x14c4, 0x09b0, 0x0010, 0xdf40]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::MOVE(Target::Immediate(1053892), Target::IndirectRegOffset(BaseRegister::None, Some(IndexRegister { xreg: XRegister::DReg(0), scale: 0, size: Size::Long }), 0x10df40), Size::Long));
|
2021-10-03 16:55:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-10-26 19:17:59 +00:00
|
|
|
fn instruction_mulsl() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68030);
|
2021-10-03 16:55:20 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x4c3c, 0x0800, 0x0000, 0x0097]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::MULL(Target::Immediate(0x97), None, 0, Sign::Signed));
|
Added MUL, DIV, NEG, DBcc, and Scc instructions, and fixed issue with ADD/SUB flags
With ADDA, SUBA, and ADDQ/SUBQ when the target is an address register, the condition
flags should not be changed, but the code was changing them, which caused problems.
I've fixed it by making the ADD/SUB executions check for an address target and
will not update flags in that case. This should only occur when the actual instruction
was an ADDA or ADDQ with an address register target
2021-10-03 04:59:28 +00:00
|
|
|
}
|
2021-10-05 23:22:21 +00:00
|
|
|
|
2021-10-22 20:02:48 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_divs() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0x81FC, 0x0003]);
|
2021-10-22 20:02:48 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-22 20:02:48 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::DIVW(Target::Immediate(3), 0, Sign::Signed));
|
|
|
|
}
|
|
|
|
|
2021-10-19 04:22:57 +00:00
|
|
|
#[test]
|
2021-10-26 19:17:59 +00:00
|
|
|
fn instruction_muls() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-19 04:22:57 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0xC1FC, 0x0276]);
|
2021-10-19 04:22:57 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::MULW(Target::Immediate(0x276), 0, Sign::Signed));
|
2021-10-19 04:22:57 +00:00
|
|
|
}
|
|
|
|
|
2021-10-05 23:22:21 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_asli() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0xE300]);
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ASd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left));
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_asri() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0xE200]);
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ASd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_roli() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0xE318]);
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ROd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_rori() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
load_memory(&system, &[0xE218]);
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-18 23:34:55 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ROd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right));
|
2021-10-18 23:34:55 +00:00
|
|
|
}
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod execute_tests {
|
|
|
|
use crate::system::System;
|
2021-10-27 04:32:25 +00:00
|
|
|
use crate::memory::{MemoryBlock, BusPort};
|
2021-10-18 19:05:10 +00:00
|
|
|
use crate::devices::{Address, Addressable, Steppable, wrap_transmutable};
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
use crate::cpus::m68k::{M68k, M68kType};
|
2021-11-04 06:55:50 +00:00
|
|
|
use crate::cpus::m68k::instructions::{Instruction, Target, Size, Sign, ShiftDirection, Condition};
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
const INIT_STACK: Address = 0x00002000;
|
|
|
|
const INIT_ADDR: Address = 0x00000010;
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
fn init_test(cputype: M68kType) -> (M68k, System) {
|
2021-10-11 22:04:39 +00:00
|
|
|
let mut system = System::new();
|
|
|
|
|
|
|
|
// Insert basic initialization
|
|
|
|
let data = vec![0; 0x00100000];
|
|
|
|
let mem = MemoryBlock::new(data);
|
2021-10-18 19:05:10 +00:00
|
|
|
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
|
2021-10-11 22:04:39 +00:00
|
|
|
system.get_bus().write_beu32(0, INIT_STACK as u32).unwrap();
|
|
|
|
system.get_bus().write_beu32(4, INIT_ADDR as u32).unwrap();
|
|
|
|
|
2021-10-27 04:32:25 +00:00
|
|
|
let port = if cputype <= M68kType::MC68010 {
|
|
|
|
BusPort::new(0, 24, 16, system.bus.clone())
|
|
|
|
} else {
|
|
|
|
BusPort::new(0, 24, 16, system.bus.clone())
|
|
|
|
};
|
|
|
|
let mut cpu = M68k::new(cputype, 10_000_000, port);
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.step(&system).unwrap();
|
2021-11-04 06:55:50 +00:00
|
|
|
cpu.decoder.init(cpu.state.pc);
|
2021-10-11 22:04:39 +00:00
|
|
|
assert_eq!(cpu.state.pc, INIT_ADDR as u32);
|
|
|
|
assert_eq!(cpu.state.msp, INIT_STACK as u32);
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
|
|
|
|
(cpu, system)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_nop() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
cpu.decoder.instruction = Instruction::NOP;
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let expected_state = cpu.state.clone();
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_ori() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
cpu.decoder.instruction = Instruction::OR(Target::Immediate(0xFF), Target::DirectAReg(0), Size::Byte);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2708;
|
|
|
|
expected_state.a_reg[0] = 0x000000FF;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-11-05 04:29:52 +00:00
|
|
|
fn instruction_add_no_overflow() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x00;
|
|
|
|
cpu.decoder.instruction = Instruction::ADD(Target::Immediate(0x7f), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.d_reg[0] = 0x7f;
|
|
|
|
expected_state.sr = 0x2700;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_add_no_overflow_negative() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
|
|
|
cpu.decoder.instruction = Instruction::ADD(Target::Immediate(0x80), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.d_reg[0] = 0x81;
|
|
|
|
expected_state.sr = 0x2708;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_add_overflow() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
|
|
|
cpu.decoder.instruction = Instruction::ADD(Target::Immediate(0x7f), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.d_reg[0] = 0x80;
|
|
|
|
expected_state.sr = 0x270A;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_add_carry() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x80;
|
|
|
|
cpu.decoder.instruction = Instruction::ADD(Target::Immediate(0x80), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.d_reg[0] = 0x00;
|
|
|
|
expected_state.sr = 0x2717;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmp_equal() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let value = 0x20;
|
|
|
|
cpu.state.d_reg[0] = value;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(value), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2704;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-11-05 04:29:52 +00:00
|
|
|
fn instruction_cmp_greater_than() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x20;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x30), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2709;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
2021-11-04 06:55:50 +00:00
|
|
|
#[test]
|
2021-11-05 04:29:52 +00:00
|
|
|
fn instruction_cmp_less_than() {
|
2021-11-04 06:55:50 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x20;
|
2021-11-05 04:29:52 +00:00
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x10), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2700;
|
|
|
|
|
2021-11-04 06:55:50 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-11-05 04:29:52 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmp_no_overflow() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x00;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x7f), Target::DirectDReg(0), Size::Byte);
|
2021-11-04 06:55:50 +00:00
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
2021-11-05 04:29:52 +00:00
|
|
|
expected_state.sr = 0x2709;
|
2021-11-04 06:55:50 +00:00
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-11-05 04:29:52 +00:00
|
|
|
fn instruction_cmp_no_overflow_2() {
|
2021-11-04 06:55:50 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
2021-11-05 04:29:52 +00:00
|
|
|
cpu.state.d_reg[0] = 0x00;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x8001), Target::DirectDReg(0), Size::Word);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2701;
|
|
|
|
|
2021-11-04 06:55:50 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-11-05 04:29:52 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmp_overflow() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x00;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x80), Target::DirectDReg(0), Size::Byte);
|
2021-11-04 06:55:50 +00:00
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
2021-11-05 04:29:52 +00:00
|
|
|
expected_state.sr = 0x270B;
|
2021-11-04 06:55:50 +00:00
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-11-05 04:29:52 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmp_overflow_2() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x8001), Target::DirectDReg(0), Size::Word);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x270B;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-11-04 06:55:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
#[test]
|
2021-11-05 04:29:52 +00:00
|
|
|
fn instruction_cmp_no_carry() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0xFF;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x01), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2708;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmp_carry() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0xFF), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2701;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_blt() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x20;
|
2021-11-05 04:29:52 +00:00
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x30), Target::DirectDReg(0), Size::Byte);
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
cpu.decoder.instruction = Instruction::Bcc(Condition::LessThan, 8);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
2021-11-05 04:29:52 +00:00
|
|
|
expected_state.pc = expected_state.pc + 8 + 2;
|
2021-10-26 19:17:59 +00:00
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
2021-11-05 04:29:52 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_blt_not() {
|
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x30;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x20), Target::DirectDReg(0), Size::Byte);
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
cpu.decoder.instruction = Instruction::Bcc(Condition::LessThan, 8);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.pc = expected_state.pc + 8 + 2;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_ne!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_andi_sr() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-17 03:30:50 +00:00
|
|
|
cpu.state.sr = 0xA7AA;
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decoder.instruction = Instruction::ANDtoSR(0xF8FF);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0xA0AA;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_ori_sr() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-17 03:30:50 +00:00
|
|
|
cpu.state.sr = 0xA755;
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decoder.instruction = Instruction::ORtoSR(0x00AA);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0xA7FF;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_muls() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let value = 0x0276;
|
|
|
|
cpu.state.d_reg[0] = 0x0200;
|
2021-10-20 02:50:42 +00:00
|
|
|
cpu.decoder.instruction = Instruction::MULW(Target::Immediate(value), 0, Sign::Signed);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.d_reg[0] = 0x4ec00;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_divu() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
let value = 0x0245;
|
|
|
|
cpu.state.d_reg[0] = 0x40000;
|
2021-10-20 02:50:42 +00:00
|
|
|
cpu.decoder.instruction = Instruction::DIVW(Target::Immediate(value), 0, Sign::Unsigned);
|
2021-10-11 22:04:39 +00:00
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.d_reg[0] = 0x007101C3;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_asli() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decoder.instruction = Instruction::ASd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2700;
|
|
|
|
expected_state.d_reg[0] = 0x00000002;
|
|
|
|
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-05 23:22:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_asri() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x81;
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decoder.instruction = Instruction::ASd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2719;
|
|
|
|
expected_state.d_reg[0] = 0x000000C0;
|
|
|
|
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-05 23:22:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_roli() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x80;
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decoder.instruction = Instruction::ROd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2701;
|
|
|
|
expected_state.d_reg[0] = 0x00000001;
|
|
|
|
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-05 23:22:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_rori() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
2021-10-11 22:04:39 +00:00
|
|
|
cpu.decoder.instruction = Instruction::ROd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2709;
|
|
|
|
expected_state.d_reg[0] = 0x00000080;
|
|
|
|
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-05 23:22:21 +00:00
|
|
|
}
|
|
|
|
|
2021-10-20 02:50:42 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_roxl() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-20 02:50:42 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x80;
|
|
|
|
cpu.state.sr = 0x2700;
|
|
|
|
cpu.decoder.instruction = Instruction::ROXd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2715;
|
|
|
|
expected_state.d_reg[0] = 0x00000000;
|
|
|
|
|
2021-10-20 02:50:42 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-20 02:50:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_roxr() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-20 02:50:42 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
|
|
|
cpu.state.sr = 0x2700;
|
|
|
|
cpu.decoder.instruction = Instruction::ROXd(Target::Immediate(1), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2715;
|
|
|
|
expected_state.d_reg[0] = 0x00000000;
|
|
|
|
|
2021-10-20 02:50:42 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-20 02:50:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_roxl_2() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-20 02:50:42 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x80;
|
|
|
|
cpu.state.sr = 0x2700;
|
|
|
|
cpu.decoder.instruction = Instruction::ROXd(Target::Immediate(2), Target::DirectDReg(0), Size::Byte, ShiftDirection::Left);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2700;
|
|
|
|
expected_state.d_reg[0] = 0x00000001;
|
|
|
|
|
2021-10-20 02:50:42 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-20 02:50:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_roxr_2() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-20 02:50:42 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x01;
|
|
|
|
cpu.state.sr = 0x2700;
|
|
|
|
cpu.decoder.instruction = Instruction::ROXd(Target::Immediate(2), Target::DirectDReg(0), Size::Byte, ShiftDirection::Right);
|
|
|
|
|
2021-10-26 19:17:59 +00:00
|
|
|
let mut expected_state = cpu.state.clone();
|
|
|
|
expected_state.sr = 0x2708;
|
|
|
|
expected_state.d_reg[0] = 0x00000080;
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, expected_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_neg_word() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-26 19:17:59 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x80;
|
|
|
|
cpu.state.sr = 0x2700;
|
|
|
|
cpu.decoder.instruction = Instruction::NEG(Target::DirectDReg(0), Size::Word);
|
|
|
|
|
|
|
|
let mut expected_state = cpu.state.clone();
|
2021-11-05 04:29:52 +00:00
|
|
|
expected_state.sr = 0x2719;
|
2021-10-26 19:17:59 +00:00
|
|
|
expected_state.d_reg[0] = 0x0000FF80;
|
|
|
|
|
2021-10-20 02:50:42 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-26 19:17:59 +00:00
|
|
|
assert_eq!(cpu.state, expected_state);
|
2021-10-20 02:50:42 +00:00
|
|
|
}
|
|
|
|
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_value_direct_d() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x1234;
|
2021-10-11 22:04:39 +00:00
|
|
|
let target = Target::DirectDReg(1);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.d_reg[1] = expected;
|
2021-10-06 23:14:56 +00:00
|
|
|
let result = cpu.get_target_value(&system, target, size).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(result, expected);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_value_direct_a() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x1234;
|
2021-10-11 22:04:39 +00:00
|
|
|
let target = Target::DirectAReg(2);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.a_reg[2] = expected;
|
2021-10-06 23:14:56 +00:00
|
|
|
let result = cpu.get_target_value(&system, target, size).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(result, expected);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_value_indirect_a() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let expected_addr = INIT_ADDR;
|
|
|
|
let expected = 0x12345678;
|
2021-10-11 22:04:39 +00:00
|
|
|
let target = Target::IndirectAReg(2);
|
2021-10-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.a_reg[2] = INIT_ADDR as u32;
|
2021-10-06 23:14:56 +00:00
|
|
|
let result = cpu.get_target_value(&system, target, size).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(result, expected);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_value_indirect_a_inc() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let expected_addr = INIT_ADDR;
|
|
|
|
let expected = 0x12345678;
|
2021-10-11 22:04:39 +00:00
|
|
|
let target = Target::IndirectARegInc(2);
|
2021-10-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.a_reg[2] = INIT_ADDR as u32;
|
2021-10-06 23:14:56 +00:00
|
|
|
let result = cpu.get_target_value(&system, target, size).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(result, expected);
|
|
|
|
assert_eq!(cpu.state.a_reg[2], (INIT_ADDR as u32) + 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_value_indirect_a_dec() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
let size = Size::Long;
|
|
|
|
let expected_addr = INIT_ADDR + 4;
|
|
|
|
let expected = 0x12345678;
|
2021-10-11 22:04:39 +00:00
|
|
|
let target = Target::IndirectARegDec(2);
|
2021-10-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
cpu.state.a_reg[2] = (INIT_ADDR as u32) + 4;
|
2021-10-06 23:14:56 +00:00
|
|
|
let result = cpu.get_target_value(&system, target, size).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(result, expected);
|
|
|
|
assert_eq!(cpu.state.a_reg[2], INIT_ADDR as u32);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_value_immediate() {
|
2021-10-27 04:32:25 +00:00
|
|
|
let (mut cpu, system) = init_test(M68kType::MC68010);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
|
|
|
let size = Size::Word;
|
|
|
|
let expected = 0x1234;
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
let target = Target::Immediate(expected);
|
2021-10-05 23:22:21 +00:00
|
|
|
|
2021-10-06 23:14:56 +00:00
|
|
|
let result = cpu.get_target_value(&system, target, size).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(result, expected);
|
|
|
|
}
|
2021-10-02 02:27:05 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 22:04:39 +00:00
|
|
|
|