Fixed tests failing due to wrapping into past the end of memory

This commit is contained in:
transistor 2023-05-14 21:12:38 -07:00
parent aaa7952dd0
commit f205e231b6
7 changed files with 86 additions and 140 deletions

View File

@ -2,11 +2,18 @@
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ErrorType {
Assertion,
Emulator,
Emulator(EmulatorErrorKind),
Processor,
Breakpoint,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EmulatorErrorKind {
Misc,
MemoryAlignment,
}
#[derive(Debug)]
pub struct Error {
pub err: ErrorType,
@ -15,11 +22,25 @@ pub struct Error {
}
impl Error {
pub fn new(msg: &str) -> Error {
pub fn new<S>(msg: S) -> Error
where
S: Into<String>,
{
Error {
err: ErrorType::Emulator,
err: ErrorType::Emulator(EmulatorErrorKind::Misc),
native: 0,
msg: msg.to_string(),
msg: msg.into(),
}
}
pub fn emulator<S>(kind: EmulatorErrorKind, msg: S) -> Error
where
S: Into<String>,
{
Error {
err: ErrorType::Emulator(kind),
native: 0,
msg: msg.into(),
}
}
@ -31,19 +52,25 @@ impl Error {
}
}
pub fn breakpoint(msg: &str) -> Error {
pub fn breakpoint<S>(msg: S) -> Error
where
S: Into<String>,
{
Error {
err: ErrorType::Breakpoint,
native: 0,
msg: msg.to_string(),
msg: msg.into(),
}
}
pub fn assertion(msg: &str) -> Error {
pub fn assertion<S>(msg: S) -> Error
where
S: Into<String>,
{
Error {
err: ErrorType::Assertion,
native: 0,
msg: msg.to_string(),
msg: msg.into(),
}
}
}

View File

@ -1,11 +1,12 @@
use std::fs;
use std::cmp;
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt::Write;
use crate::info;
use crate::error::Error;
use crate::error::{Error, EmulatorErrorKind};
use crate::clock::ClockTime;
use crate::devices::{Address, Addressable, Transmutable, TransmutableBox, read_beu16};
@ -274,20 +275,17 @@ pub struct BusPort {
offset: Address,
address_mask: Address,
data_width: u8,
error_on_alignment: bool,
subdevice: Rc<RefCell<Bus>>,
}
impl BusPort {
pub fn new(offset: Address, address_bits: u8, data_bits: u8, bus: Rc<RefCell<Bus>>) -> Self {
let mut address_mask = 0;
for _ in 0..address_bits {
address_mask = (address_mask << 1) | 0x01;
}
Self {
offset,
address_mask,
address_mask: (1 << address_bits) - 1,
data_width: data_bits / 8,
error_on_alignment: false,
subdevice: bus,
}
}
@ -311,21 +309,31 @@ impl Addressable for BusPort {
}
fn read(&mut self, clock: ClockTime, addr: Address, data: &mut [u8]) -> Result<(), Error> {
if self.error_on_alignment && addr % self.data_width as Address != 0 {
return Err(Error::emulator(EmulatorErrorKind::MemoryAlignment, format!("misaligned memory access at {:x}", addr)));
}
let addr = self.offset + (addr & self.address_mask);
let mut subdevice = self.subdevice.borrow_mut();
for i in (0..data.len()).step_by(self.data_width as usize) {
let end = std::cmp::min(i + self.data_width as usize, data.len());
subdevice.read(clock, addr + i as Address, &mut data[i..end])?;
let addr_index = (addr + i as Address) & self.address_mask;
let end = cmp::min(i + self.data_width as usize, data.len());
subdevice.read(clock, addr_index, &mut data[i..end])?;
}
Ok(())
}
fn write(&mut self, clock: ClockTime, addr: Address, data: &[u8]) -> Result<(), Error> {
if self.error_on_alignment && addr % self.data_width as Address != 0 {
return Err(Error::emulator(EmulatorErrorKind::MemoryAlignment, format!("misaligned memory access at {:x}", addr)));
}
let addr = self.offset + (addr & self.address_mask);
let mut subdevice = self.subdevice.borrow_mut();
for i in (0..data.len()).step_by(self.data_width as usize) {
let addr_index = (addr + i as Address) & self.address_mask;
let end = std::cmp::min(i + self.data_width as usize, data.len());
subdevice.write(clock, addr + i as Address, &data[i..end])?;
subdevice.write(clock, addr_index, &data[i..end])?;
}
Ok(())
}

View File

@ -305,7 +305,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_abcd(&mut self, src: Target, dest: Target) -> Result<(), Error> {
let src_val = self.get_target_value(src, Size::Byte, Used::Once)?;
let dest_val = self.get_target_value(dest, Size::Byte, Used::Twice)?;
@ -330,7 +329,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_add(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
@ -342,7 +340,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_adda(&mut self, src: Target, dest: Register, size: Size) -> Result<(), Error> {
let src_val = sign_extend_to_long(self.get_target_value(src, size, Used::Once)?, size) as u32;
let dest_val = *self.get_a_reg_mut(dest);
@ -351,7 +348,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_addx(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
@ -373,7 +369,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_and(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
@ -383,20 +378,17 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_and_to_ccr(&mut self, value: u8) -> Result<(), Error> {
self.state.sr = (self.state.sr & 0xFF00) | ((self.state.sr & 0x00FF) & (value as u16));
Ok(())
}
#[inline]
fn execute_and_to_sr(&mut self, value: u16) -> Result<(), Error> {
self.require_supervisor()?;
self.set_sr(self.state.sr & value);
Ok(())
}
#[inline]
fn execute_asd(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
let count = self.get_target_value(count, size, Used::Once)? % 64;
let value = self.get_target_value(target, size, Used::Twice)?;
@ -430,7 +422,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bcc(&mut self, cond: Condition, offset: i32) -> Result<(), Error> {
let should_branch = self.get_current_condition(cond);
if should_branch {
@ -442,7 +433,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bra(&mut self, offset: i32) -> Result<(), Error> {
if let Err(err) = self.set_pc(self.decoder.start.wrapping_add(2).wrapping_add(offset as u32)) {
self.state.pc -= 2;
@ -451,7 +441,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bsr(&mut self, offset: i32) -> Result<(), Error> {
self.push_long(self.state.pc)?;
let sp = *self.get_stack_pointer_mut();
@ -463,7 +452,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bchg(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> {
let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?;
let mut src_val = self.get_target_value(target, size, Used::Twice)?;
@ -473,7 +461,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bclr(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> {
let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?;
let mut src_val = self.get_target_value(target, size, Used::Twice)?;
@ -483,7 +470,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bset(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> {
let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?;
let mut value = self.get_target_value(target, size, Used::Twice)?;
@ -493,7 +479,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_btst(&mut self, bitnum: Target, target: Target, size: Size) -> Result<(), Error> {
let bitnum = self.get_target_value(bitnum, Size::Byte, Used::Once)?;
let value = self.get_target_value(target, size, Used::Once)?;
@ -501,7 +486,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bfchg(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
@ -512,7 +496,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bfclr(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
@ -523,7 +506,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bfexts(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate, reg: Register) -> Result<(), Error> {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
@ -540,7 +522,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bfextu(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate, reg: Register) -> Result<(), Error> {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
@ -551,7 +532,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bfset(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
@ -562,7 +542,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_bftst(&mut self, target: Target, offset: RegOrImmediate, width: RegOrImmediate) -> Result<(), Error> {
let (offset, width) = self.get_bit_field_args(offset, width);
let mask = get_bit_field_mask(offset, width);
@ -572,7 +551,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_chk(&mut self, target: Target, reg: Register, size: Size) -> Result<(), Error> {
let upper_bound = sign_extend_to_long(self.get_target_value(target, size, Used::Once)?, size);
let dreg = sign_extend_to_long(self.state.d_reg[reg as usize], size);
@ -589,7 +567,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_clr(&mut self, target: Target, size: Size) -> Result<(), Error> {
if self.cputype == M68kType::MC68000 {
self.get_target_value(target, size, Used::Twice)?;
@ -602,7 +579,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_cmp(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Once)?;
@ -612,7 +588,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_cmpa(&mut self, src: Target, reg: Register, size: Size) -> Result<(), Error> {
let src_val = sign_extend_to_long(self.get_target_value(src, size, Used::Once)?, size) as u32;
let dest_val = *self.get_a_reg_mut(reg);
@ -622,7 +597,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_dbcc(&mut self, cond: Condition, reg: Register, offset: i16) -> Result<(), Error> {
let condition_true = self.get_current_condition(cond);
if !condition_true {
@ -638,7 +612,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_divw(&mut self, src: Target, dest: Register, sign: Sign) -> Result<(), Error> {
let src_val = self.get_target_value(src, Size::Word, Used::Once)?;
if src_val == 0 {
@ -679,7 +652,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_divl(&mut self, src: Target, dest_h: Option<Register>, dest_l: Register, sign: Sign) -> Result<(), Error> {
let src_val = self.get_target_value(src, Size::Long, Used::Once)?;
if src_val == 0 {
@ -713,7 +685,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_eor(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
@ -723,20 +694,17 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_eor_to_ccr(&mut self, value: u8) -> Result<(), Error> {
self.set_sr((self.state.sr & 0xFF00) | ((self.state.sr & 0x00FF) ^ (value as u16)));
Ok(())
}
#[inline]
fn execute_eor_to_sr(&mut self, value: u16) -> Result<(), Error> {
self.require_supervisor()?;
self.set_sr(self.state.sr ^ value);
Ok(())
}
#[inline]
fn execute_exg(&mut self, target1: Target, target2: Target) -> Result<(), Error> {
let value1 = self.get_target_value(target1, Size::Long, Used::Twice)?;
let value2 = self.get_target_value(target2, Size::Long, Used::Twice)?;
@ -745,7 +713,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_ext(&mut self, reg: Register, from_size: Size, to_size: Size) -> Result<(), Error> {
let input = get_value_sized(self.state.d_reg[reg as usize], from_size);
let result = match (from_size, to_size) {
@ -759,13 +726,11 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_illegal(&mut self) -> Result<(), Error> {
self.exception(Exceptions::IllegalInstruction as u8, false)?;
Ok(())
}
#[inline]
fn execute_jmp(&mut self, target: Target) -> Result<(), Error> {
let addr = self.get_target_address(target)?;
if let Err(err) = self.set_pc(addr) {
@ -775,7 +740,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_jsr(&mut self, target: Target) -> Result<(), Error> {
let previous_pc = self.state.pc;
let addr = self.get_target_address(target)?;
@ -791,7 +755,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_lea(&mut self, target: Target, reg: Register) -> Result<(), Error> {
let value = self.get_target_address(target)?;
let addr = self.get_a_reg_mut(reg);
@ -799,7 +762,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_link(&mut self, reg: Register, offset: i32) -> Result<(), Error> {
*self.get_stack_pointer_mut() -= 4;
let sp = *self.get_stack_pointer_mut();
@ -810,7 +772,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_lsd(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
let count = self.get_target_value(count, size, Used::Once)? % 64;
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
@ -831,7 +792,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_move(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
self.set_logic_flags(src_val, size);
@ -839,7 +799,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_movea(&mut self, src: Target, reg: Register, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let src_val = sign_extend_to_long(src_val, size) as u32;
@ -848,14 +807,12 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_move_from_sr(&mut self, target: Target) -> Result<(), Error> {
self.require_supervisor()?;
self.set_target_value(target, self.state.sr as u32, Size::Word, Used::Once)?;
Ok(())
}
#[inline]
fn execute_move_to_sr(&mut self, target: Target) -> Result<(), Error> {
self.require_supervisor()?;
let value = self.get_target_value(target, Size::Word, Used::Once)? as u16;
@ -863,14 +820,12 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_move_to_ccr(&mut self, target: Target) -> Result<(), Error> {
let value = self.get_target_value(target, Size::Word, Used::Once)? as u16;
self.set_sr((self.state.sr & 0xFF00) | (value & 0x00FF));
Ok(())
}
#[inline]
fn execute_movec(&mut self, target: Target, control_reg: ControlRegister, dir: Direction) -> Result<(), Error> {
self.require_supervisor()?;
match dir {
@ -888,7 +843,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_movem(&mut self, target: Target, size: Size, dir: Direction, mask: u16) -> Result<(), Error> {
let addr = self.get_target_address(target)?;
@ -936,7 +890,6 @@ impl M68k {
Ok(())
}
#[inline]
fn move_memory_to_registers(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result<u32, Error> {
for i in 0..8 {
if (mask & 0x01) != 0 {
@ -955,7 +908,6 @@ impl M68k {
Ok(addr)
}
#[inline]
fn move_registers_to_memory(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result<u32, Error> {
for i in 0..8 {
if (mask & 0x01) != 0 {
@ -975,7 +927,6 @@ impl M68k {
Ok(addr)
}
#[inline]
fn move_registers_to_memory_reverse(&mut self, mut addr: u32, size: Size, mut mask: u16) -> Result<u32, Error> {
for i in (0..8).rev() {
if (mask & 0x01) != 0 {
@ -995,7 +946,6 @@ impl M68k {
Ok(addr)
}
#[inline]
fn execute_movep(&mut self, dreg: Register, areg: Register, offset: i16, size: Size, dir: Direction) -> Result<(), Error> {
match dir {
Direction::ToTarget => {
@ -1022,7 +972,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_moveq(&mut self, data: u8, reg: Register) -> Result<(), Error> {
let value = sign_extend_to_long(data as u32, Size::Byte) as u32;
self.state.d_reg[reg as usize] = value;
@ -1030,7 +979,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_moveusp(&mut self, target: Target, dir: Direction) -> Result<(), Error> {
self.require_supervisor()?;
match dir {
@ -1040,7 +988,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_mulw(&mut self, src: Target, dest: Register, sign: Sign) -> Result<(), Error> {
let src_val = self.get_target_value(src, Size::Word, Used::Once)?;
let dest_val = get_value_sized(self.state.d_reg[dest as usize], Size::Word);
@ -1054,7 +1001,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_mull(&mut self, src: Target, dest_h: Option<Register>, dest_l: Register, sign: Sign) -> Result<(), Error> {
let src_val = self.get_target_value(src, Size::Long, Used::Once)?;
let dest_val = get_value_sized(self.state.d_reg[dest_l as usize], Size::Long);
@ -1071,7 +1017,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_nbcd(&mut self, dest: Target) -> Result<(), Error> {
let dest_val = self.get_target_value(dest, Size::Byte, Used::Twice)?;
let result = self.execute_sbcd_val(dest_val, 0)?;
@ -1079,7 +1024,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_neg(&mut self, target: Target, size: Size) -> Result<(), Error> {
let original = self.get_target_value(target, size, Used::Twice)?;
let (result, overflow) = overflowing_sub_signed_sized(0, original, size);
@ -1090,7 +1034,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_negx(&mut self, dest: Target, size: Size) -> Result<(), Error> {
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
let extend = self.get_flag(Flags::Extend) as u32;
@ -1111,7 +1054,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_not(&mut self, target: Target, size: Size) -> Result<(), Error> {
let mut value = self.get_target_value(target, size, Used::Twice)?;
value = get_value_sized(!value, size);
@ -1120,7 +1062,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_or(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
@ -1130,34 +1071,29 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_or_to_ccr(&mut self, value: u8) -> Result<(), Error> {
self.set_sr((self.state.sr & 0xFF00) | ((self.state.sr & 0x00FF) | (value as u16)));
Ok(())
}
#[inline]
fn execute_or_to_sr(&mut self, value: u16) -> Result<(), Error> {
self.require_supervisor()?;
self.set_sr(self.state.sr | value);
Ok(())
}
#[inline]
fn execute_pea(&mut self, target: Target) -> Result<(), Error> {
let value = self.get_target_address(target)?;
self.push_long(value)?;
Ok(())
}
#[inline]
fn execute_reset(&mut self) -> Result<(), Error> {
self.require_supervisor()?;
// TODO this only resets external devices and not internal ones
Ok(())
}
#[inline]
fn execute_rod(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
let count = self.get_target_value(count, size, Used::Once)? % 64;
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
@ -1174,7 +1110,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_roxd(&mut self, count: Target, target: Target, size: Size, shift_dir: ShiftDirection) -> Result<(), Error> {
let count = self.get_target_value(count, size, Used::Once)? % 64;
let mut pair = (self.get_target_value(target, size, Used::Twice)?, false);
@ -1192,7 +1127,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_rte(&mut self) -> Result<(), Error> {
self.require_supervisor()?;
let sr = self.pop_word()?;
@ -1210,7 +1144,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_rtr(&mut self) -> Result<(), Error> {
let ccr = self.pop_word()?;
let addr = self.pop_long()?;
@ -1222,7 +1155,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_rts(&mut self) -> Result<(), Error> {
self.debugger.stack_tracer.pop_return();
let addr = self.pop_long()?;
@ -1233,7 +1165,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_scc(&mut self, cond: Condition, target: Target) -> Result<(), Error> {
let condition_true = self.get_current_condition(cond);
if condition_true {
@ -1244,7 +1175,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_stop(&mut self, flags: u16) -> Result<(), Error> {
self.require_supervisor()?;
self.set_sr(flags);
@ -1252,7 +1182,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_sbcd(&mut self, src: Target, dest: Target) -> Result<(), Error> {
let src_val = self.get_target_value(src, Size::Byte, Used::Once)?;
let dest_val = self.get_target_value(dest, Size::Byte, Used::Twice)?;
@ -1261,7 +1190,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_sbcd_val(&mut self, src_val: u32, dest_val: u32) -> Result<u32, Error> {
let extend_flag = self.get_flag(Flags::Extend) as u32;
let src_parts = get_nibbles_from_byte(src_val);
@ -1283,7 +1211,6 @@ impl M68k {
Ok(result)
}
#[inline]
fn execute_sub(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
@ -1295,7 +1222,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_suba(&mut self, src: Target, dest: Register, size: Size) -> Result<(), Error> {
let src_val = sign_extend_to_long(self.get_target_value(src, size, Used::Once)?, size) as u32;
let dest_val = *self.get_a_reg_mut(dest);
@ -1304,7 +1230,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_subx(&mut self, src: Target, dest: Target, size: Size) -> Result<(), Error> {
let src_val = self.get_target_value(src, size, Used::Once)?;
let dest_val = self.get_target_value(dest, size, Used::Twice)?;
@ -1326,7 +1251,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_swap(&mut self, reg: Register) -> Result<(), Error> {
let value = self.state.d_reg[reg as usize];
self.state.d_reg[reg as usize] = ((value & 0x0000FFFF) << 16) | ((value & 0xFFFF0000) >> 16);
@ -1334,7 +1258,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_tas(&mut self, target: Target) -> Result<(), Error> {
let value = self.get_target_value(target, Size::Byte, Used::Twice)?;
self.set_flag(Flags::Negative, (value & 0x80) != 0);
@ -1345,20 +1268,17 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_tst(&mut self, target: Target, size: Size) -> Result<(), Error> {
let value = self.get_target_value(target, size, Used::Once)?;
self.set_logic_flags(value, size);
Ok(())
}
#[inline]
fn execute_trap(&mut self, number: u8) -> Result<(), Error> {
self.exception(32 + number, false)?;
Ok(())
}
#[inline]
fn execute_trapv(&mut self) -> Result<(), Error> {
if self.get_flag(Flags::Overflow) {
self.exception(Exceptions::TrapvInstruction as u8, false)?;
@ -1366,7 +1286,6 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_unlk(&mut self, reg: Register) -> Result<(), Error> {
let value = *self.get_a_reg_mut(reg);
*self.get_stack_pointer_mut() = value;
@ -1376,14 +1295,12 @@ impl M68k {
Ok(())
}
#[inline]
fn execute_unimplemented_a(&mut self, _: u16) -> Result<(), Error> {
self.state.pc -= 2;
self.exception(Exceptions::LineAEmulator as u8, false)?;
Ok(())
}
#[inline]
fn execute_unimplemented_f(&mut self, _: u16) -> Result<(), Error> {
self.state.pc -= 2;
self.exception(Exceptions::LineFEmulator as u8, false)?;
@ -1658,12 +1575,10 @@ impl M68k {
}
}
#[inline(always)]
fn get_stack_pointer_mut(&mut self) -> &mut u32 {
if self.is_supervisor() { &mut self.state.ssp } else { &mut self.state.usp }
}
#[inline(always)]
fn get_a_reg(&self, reg: Register) -> u32 {
if reg == 7 {
if self.is_supervisor() { self.state.ssp } else { self.state.usp }
@ -1672,7 +1587,6 @@ impl M68k {
}
}
#[inline(always)]
fn get_a_reg_mut(&mut self, reg: Register) -> &mut u32 {
if reg == 7 {
if self.is_supervisor() { &mut self.state.ssp } else { &mut self.state.usp }
@ -1681,12 +1595,10 @@ impl M68k {
}
}
#[inline(always)]
fn is_supervisor(&self) -> bool {
self.state.sr & (Flags:: Supervisor as u16) != 0
}
#[inline(always)]
fn require_supervisor(&self) -> Result<(), Error> {
if self.is_supervisor() {
Ok(())
@ -1700,12 +1612,10 @@ impl M68k {
self.state.sr = value & mask;
}
#[inline(always)]
fn get_flag(&self, flag: Flags) -> bool {
(self.state.sr & (flag as u16)) != 0
}
#[inline(always)]
fn set_flag(&mut self, flag: Flags, value: bool) {
self.state.sr = (self.state.sr & !(flag as u16)) | (if value { flag as u16 } else { 0 });
}
@ -1909,7 +1819,6 @@ fn get_sub_overflow(operand1: u32, operand2: u32, result: u32, size: Size) -> bo
(msb1 && msb2 && !msb_res) || (!msb1 && !msb2 && msb_res)
}
#[inline(always)]
fn get_msb(value: u32, size: Size) -> bool {
match size {
Size::Byte => (value & 0x00000080) != 0,
@ -1918,7 +1827,6 @@ fn get_msb(value: u32, size: Size) -> bool {
}
}
#[inline(always)]
fn get_msb_mask(value: u32, size: Size) -> u32 {
match size {
Size::Byte => value & 0x00000080,

View File

@ -479,7 +479,7 @@ impl Z80 {
fn execute_ini(&mut self) -> Result<(), Error> {
let b = self.get_register_value(Register::B);
let c = self.get_register_value(Register::C);
let value = self.get_ioport_value(b, c)?;
let value = self.read_ioport_value(b, c)?;
self.set_load_target_value(LoadTarget::IndirectRegByte(RegisterPair::HL), value as u16)?;
let hl = self.get_register_pair_value(RegisterPair::HL).wrapping_add(1);
@ -495,7 +495,7 @@ impl Z80 {
fn execute_inic(&mut self, reg: Register) -> Result<(), Error> {
let b = self.get_register_value(Register::B);
let c = self.get_register_value(Register::C);
let value = self.get_ioport_value(b, c)?;
let value = self.read_ioport_value(b, c)?;
self.set_register_value(reg, value);
self.set_numeric_flags(value as u16, Size::Byte);
@ -510,7 +510,7 @@ impl Z80 {
fn execute_inx(&mut self, n: u8) -> Result<(), Error> {
let a = self.get_register_value(Register::A);
let value = self.get_ioport_value(a, n)?;
let value = self.read_ioport_value(a, n)?;
self.set_register_value(Register::A, value);
Ok(())
}
@ -630,7 +630,7 @@ impl Z80 {
let b = self.get_register_value(Register::B);
let c = self.get_register_value(Register::C);
let value = self.get_register_value(reg);
self.set_ioport_value(b, c, value)?;
self.write_ioport_value(b, c, value)?;
Ok(())
}
@ -640,7 +640,7 @@ impl Z80 {
fn execute_outx(&mut self, n: u8) -> Result<(), Error> {
let a = self.get_register_value(Register::A);
let value = self.get_register_value(Register::A);
self.set_ioport_value(a, n, value)?;
self.write_ioport_value(a, n, value)?;
Ok(())
}
@ -1101,7 +1101,7 @@ impl Z80 {
self.port.write_leu16(self.current_clock, addr as Address, value)
}
fn get_ioport_value(&mut self, upper: u8, lower: u8) -> Result<u8, Error> {
fn read_ioport_value(&mut self, upper: u8, lower: u8) -> Result<u8, Error> {
let addr = ((upper as Address) << 8) | (lower as Address);
if let Some(io) = self.ioport.as_mut() {
Ok(io.read_u8(self.current_clock, addr)?)
@ -1110,7 +1110,7 @@ impl Z80 {
}
}
fn set_ioport_value(&mut self, upper: u8, lower: u8, value: u8) -> Result<(), Error> {
fn write_ioport_value(&mut self, upper: u8, lower: u8, value: u8) -> Result<(), Error> {
let addr = ((upper as Address) << 8) | (lower as Address);
if let Some(io) = self.ioport.as_mut() {
io.write_u8(self.current_clock, addr, value)?
@ -1221,12 +1221,10 @@ impl Z80 {
self.set_flags(FLAGS_CARRY_HALF_CARRY, carry_flag | half_carry_flag);
}
#[inline(always)]
fn get_flag(&self, flag: Flags) -> bool {
self.get_flags() & (flag as u8) != 0
}
#[inline(always)]
fn set_flag(&mut self, flag: Flags, value: bool) {
self.state.reg[Register::F as usize] &= !(flag as u8);
if value {
@ -1234,12 +1232,10 @@ impl Z80 {
}
}
#[inline(always)]
fn get_flags(&self) -> u8 {
self.state.reg[Register::F as usize]
}
#[inline(always)]
fn set_flags(&mut self, mask: u8, values: u8) {
self.state.reg[Register::F as usize] = (self.state.reg[Register::F as usize] & !mask) | values;
}
@ -1273,7 +1269,6 @@ fn sub_words(operand1: u16, operand2: u16) -> (u16, bool, bool, bool) {
(result, carry, overflow, half_carry)
}
#[inline(always)]
fn get_msb(value: u16, size: Size) -> bool {
match size {
Size::Byte => (value & 0x0080) != 0,

View File

@ -1,4 +1,4 @@
Last run on 2023-05-14 at commit 7e62a2691c552f3a628ac18b3eaba2a45265abde
Last run on 2023-05-14 at commit aaa7952dd0cf0ab6e33946ce0ae1aa91920e5405
00.json completed, all passed!
01.json completed, all passed!
@ -36,7 +36,7 @@ Last run on 2023-05-14 at commit 7e62a2691c552f3a628ac18b3eaba2a45265abde
1f.json completed, all passed!
20.json completed, all passed!
21.json completed, all passed!
22.json completed: 999 passed, 1 FAILED
22.json completed, all passed!
23.json completed, all passed!
24.json completed, all passed!
25.json completed, all passed!
@ -636,12 +636,12 @@ fd ae.json completed, all passed!
fd b6.json completed, all passed!
fd be.json completed, all passed!
fd e1.json completed, all passed!
fd e3.json completed: 999 passed, 1 FAILED
fd e3.json completed, all passed!
fd e5.json completed, all passed!
fd e9.json completed, all passed!
fd f9.json completed, all passed!
fe.json completed, all passed!
ff.json completed, all passed!
passed: 629558, failed: 12442, total 98%
passed: 629560, failed: 12440, total 98%
completed in 0m 32s

View File

@ -9,7 +9,7 @@ use std::path::PathBuf;
use std::time::SystemTime;
use std::fs::{self, File};
use clap::{Parser, ArgEnum};
use clap::Parser;
use flate2::read::GzDecoder;
use serde_derive::Deserialize;
@ -20,13 +20,6 @@ use moa_z80::instructions::InterruptMode;
use moa_z80::state::Flags;
use moa_z80::state::Status;
#[derive(Copy, Clone, PartialEq, Eq, ArgEnum)]
enum Selection {
Include,
Exclude,
ExcludeAddr,
Only,
}
#[derive(Parser)]
struct Args {
@ -47,11 +40,12 @@ struct Args {
/// Check undocumented instructions
#[clap(short = 'u', long)]
check_undocumented: bool,
/// Check instruction timings
#[clap(short = 't', long)]
check_timings: bool,
/// Directory to the test suite to run
#[clap(long, default_value = DEFAULT_RAD_TESTS)]
testsuite: String,
#[clap(long, short, arg_enum, default_value_t = Selection::Include)]
exceptions: Selection,
}
fn main() {
@ -90,6 +84,9 @@ struct TestState {
ram: Vec<(u16, u8)>,
}
#[derive(Debug, Deserialize)]
struct TestCycle(u16, Option<u8>, String);
#[derive(Debug, Deserialize)]
struct TestPort {
addr: u16,
@ -105,6 +102,8 @@ struct TestCase {
#[serde(rename(deserialize = "final"))]
final_state: TestState,
#[serde(default)]
cycles: Vec<TestCycle>,
#[serde(default)]
ports: Vec<TestPort>,
}
@ -279,10 +278,16 @@ fn assert_state(cpu: &Z80, system: &System, io_bus: Rc<RefCell<Bus>>, expected:
Ok(())
}
fn step_cpu_and_assert(cpu: &mut Z80, system: &System, io_bus: Rc<RefCell<Bus>>, case: &TestCase, check_extra_flags: bool) -> Result<(), Error> {
let _clock_elapsed = cpu.step(&system)?;
fn step_cpu_and_assert(cpu: &mut Z80, system: &System, io_bus: Rc<RefCell<Bus>>, case: &TestCase, args: &Args) -> Result<(), Error> {
let clock_elapsed = cpu.step(&system)?;
assert_state(&cpu, &system, io_bus, &case.final_state, check_extra_flags, &case.ports)?;
assert_state(&cpu, &system, io_bus, &case.final_state, args.check_extra_flags, &case.ports)?;
if args.check_timings {
let cycles = clock_elapsed / cpu.frequency.period_duration();
if cycles != case.cycles.len() as Address {
return Err(Error::assertion(&format!("expected instruction to take {} cycles, but took {}", case.cycles.len(), cycles)));
}
}
Ok(())
}
@ -291,7 +296,7 @@ fn run_test(case: &TestCase, args: &Args) -> Result<(), Error> {
let (mut cpu, system, io_bus) = init_execute_test(Z80Type::Z80, &case.initial_state, &case.ports).unwrap();
let mut initial_cpu = cpu.clone();
let result = step_cpu_and_assert(&mut cpu, &system, io_bus, case, args.check_extra_flags);
let result = step_cpu_and_assert(&mut cpu, &system, io_bus, case, args);
match result {
Ok(()) => Ok(()),

View File

@ -7,10 +7,13 @@
* go through flags on m68k and see if you can fix the remaining ones and/or clean up the implementation
* you could possibly make a Z80MemoryPort type that wraps the BusPort type and which impls Addressable, which can be passed into the decoder
to auto-insert things like the refresh counter, as well as the record all bus timings whenever any mem access is performed
* should you make Address a newtype and add From impls for each type of numeric, and add utils to wrap address at certain boundaries and such
* should you make a means of storing different kinds of buses?
* should you make buses hide their RcRefCell?
* address repeater on ym2612 doesn't seem to work the same, when it's on the 68000 device. The Z80 device doesn't have an affect, but maybe it's not being used
* sound doesn't work on a lot of games... is it a problem with the Z80 accessing the YM2612, or the lack of YM timers? or something else?
* make the ym generate audio in sync so the DAC timings can be more accurate