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-17 03:30:50 +00:00
|
|
|
use crate::memory::MemoryBlock;
|
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-18 23:34:55 +00:00
|
|
|
let mut cpu = M68k::new(cputype);
|
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);
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
|
|
|
|
(cpu, system)
|
|
|
|
}
|
|
|
|
|
2021-10-18 19:05:10 +00:00
|
|
|
fn get_decode_memory(cpu: &mut M68k, system: &System) -> TransmutableBox {
|
2021-10-11 22:04:39 +00:00
|
|
|
let (memory, relative_addr) = system.get_bus().get_device_at(INIT_ADDR, 12).unwrap();
|
|
|
|
cpu.decoder.init((INIT_ADDR - relative_addr) as u32, INIT_ADDR as u32);
|
|
|
|
memory
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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;
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 23:34:55 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b110, 0b010, Some(size)).unwrap();
|
|
|
|
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
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 23:34:55 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b110, 0b010, Some(size)).unwrap();
|
|
|
|
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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b110, 0b010, Some(size)).unwrap();
|
|
|
|
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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b011, Some(size)).unwrap();
|
|
|
|
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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b000, Some(size)).unwrap();
|
|
|
|
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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b001, Some(size)).unwrap();
|
|
|
|
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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
2021-10-18 19:05:10 +00:00
|
|
|
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 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();
|
|
|
|
|
|
|
|
let memory = get_decode_memory(&mut cpu, &system);
|
|
|
|
let result = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b110, 0b010, Some(Size::Long));
|
|
|
|
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-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0x4e71).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-02 15:47:20 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::NOP);
|
2021-10-02 02:27:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_ori() {
|
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-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0x0008).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, 0x00FF).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
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
|
|
|
|
|
|
|
#[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-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0x7020).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, 0x0C00).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 4, 0x0020).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.step(&system).unwrap();
|
|
|
|
cpu.decode_next(&system).unwrap();
|
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-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0x7020).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, 0x0C00).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 4, 0x0030).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.step(&system).unwrap();
|
|
|
|
cpu.decode_next(&system).unwrap();
|
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-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0x7020).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, 0x0C00).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 4, 0x0010).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.step(&system).unwrap();
|
|
|
|
cpu.decode_next(&system).unwrap();
|
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-03 16:55:20 +00:00
|
|
|
fn instruction_andi_sr() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
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-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0x027C).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, 0xF8FF).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-03 16:55:20 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::ANDtoSR(0xF8FF));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_muls() {
|
2021-10-18 23:34:55 +00:00
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
2021-10-03 16:55:20 +00:00
|
|
|
|
2021-10-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0xC1FC).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, 0x0276).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
2021-10-03 16:55:20 +00:00
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::MUL(Target::Immediate(0x276), Target::DirectDReg(0), Size::Word, 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-19 04:22:57 +00:00
|
|
|
#[test]
|
|
|
|
fn instruction_mulsl() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68010);
|
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0x4c3c).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 2, 0x0800).unwrap();
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR + 4, 0x0000).unwrap();
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
assert_eq!(cpu.decoder.instruction, Instruction::MUL(Target::Immediate(0x276), Target::DirectDReg(0), Size::Word, Sign::Signed));
|
|
|
|
}
|
|
|
|
|
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-07 16:41:01 +00:00
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0xE300).unwrap();
|
2021-10-06 23:14:56 +00:00
|
|
|
cpu.decode_next(&system).unwrap();
|
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
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0xE200).unwrap();
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
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
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0xE318).unwrap();
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
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
|
|
|
|
|
|
|
system.get_bus().write_beu16(INIT_ADDR, 0xE218).unwrap();
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
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
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_movel_full_extension() {
|
|
|
|
let (mut cpu, system) = init_decode_test(M68kType::MC68030);
|
|
|
|
|
|
|
|
let mut addr = INIT_ADDR;
|
|
|
|
let data = [0x21bc, 0x0010, 0x14c4, 0x09b0, 0x0010, 0xdf40];
|
|
|
|
for word in data {
|
|
|
|
system.get_bus().write_beu16(addr, word).unwrap();
|
|
|
|
addr += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu.decode_next(&system).unwrap();
|
|
|
|
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-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod execute_tests {
|
|
|
|
use crate::system::System;
|
2021-10-17 03:30:50 +00:00
|
|
|
use crate::memory::MemoryBlock;
|
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-10-18 19:05:10 +00:00
|
|
|
use crate::cpus::m68k::instructions::{Instruction, Target, Size, Sign, ShiftDirection};
|
2021-10-11 22:04:39 +00:00
|
|
|
|
|
|
|
const INIT_STACK: Address = 0x00002000;
|
|
|
|
const INIT_ADDR: Address = 0x00000010;
|
|
|
|
|
|
|
|
fn init_test() -> (M68k, System) {
|
|
|
|
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();
|
|
|
|
|
|
|
|
let mut cpu = M68k::new(M68kType::MC68010);
|
|
|
|
cpu.step(&system).unwrap();
|
|
|
|
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() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
|
|
|
cpu.decoder.instruction = Instruction::NOP;
|
|
|
|
|
|
|
|
let previous = cpu.state.clone();
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state, previous);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_ori() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
|
|
|
cpu.decoder.instruction = Instruction::OR(Target::Immediate(0xFF), Target::DirectAReg(0), Size::Byte);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state.a_reg[0], 0x000000FF);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmpi_equal() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
|
|
|
let value = 0x20;
|
|
|
|
cpu.state.d_reg[0] = value;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(value), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state.sr & 0x0F, 0x04);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmpi_greater() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x20;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x30), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state.sr & 0x0F, 0x09);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_cmpi_less() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
|
|
|
cpu.state.d_reg[0] = 0x20;
|
|
|
|
cpu.decoder.instruction = Instruction::CMP(Target::Immediate(0x10), Target::DirectDReg(0), Size::Byte);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state.sr & 0x0F, 0x00);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_andi_sr() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-17 03:30:50 +00:00
|
|
|
assert_eq!(cpu.state.sr, 0xA0AA);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_ori_sr() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-17 03:30:50 +00:00
|
|
|
assert_eq!(cpu.state.sr, 0xA7FF);
|
2021-10-11 22:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_muls() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
|
|
|
let value = 0x0276;
|
|
|
|
cpu.state.d_reg[0] = 0x0200;
|
|
|
|
cpu.decoder.instruction = Instruction::MUL(Target::Immediate(value), Target::DirectDReg(0), Size::Word, Sign::Signed);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state.d_reg[0], 0x4ec00);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_divu() {
|
|
|
|
let (mut cpu, system) = init_test();
|
|
|
|
|
|
|
|
let value = 0x0245;
|
|
|
|
cpu.state.d_reg[0] = 0x40000;
|
|
|
|
cpu.decoder.instruction = Instruction::DIV(Target::Immediate(value), Target::DirectDReg(0), Size::Word, Sign::Unsigned);
|
|
|
|
|
|
|
|
cpu.execute_current(&system).unwrap();
|
|
|
|
assert_eq!(cpu.state.d_reg[0], 0x007101C3);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_asli() {
|
|
|
|
let (mut cpu, system) = init_test();
|
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-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(cpu.state.d_reg[0], 0x00000002);
|
|
|
|
assert_eq!(cpu.state.sr & 0x1F, 0x00);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_asri() {
|
2021-10-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(cpu.state.d_reg[0], 0x000000C0);
|
|
|
|
assert_eq!(cpu.state.sr & 0x1F, 0x19);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_roli() {
|
2021-10-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(cpu.state.d_reg[0], 0x00000001);
|
|
|
|
assert_eq!(cpu.state.sr & 0x1F, 0x01);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn instruction_rori() {
|
2021-10-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-06 23:14:56 +00:00
|
|
|
cpu.execute_current(&system).unwrap();
|
2021-10-05 23:22:21 +00:00
|
|
|
assert_eq!(cpu.state.d_reg[0], 0x00000080);
|
|
|
|
assert_eq!(cpu.state.sr & 0x1F, 0x09);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn target_value_direct_d() {
|
2021-10-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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-11 22:04:39 +00:00
|
|
|
let (mut cpu, system) = init_test();
|
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
|
|
|
|