Merge branch 'master' of pterpstra.com:m68k-backplane-computer/emu

This commit is contained in:
pjht 2023-12-20 13:11:29 -06:00
commit f3cec9c9a3
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
10 changed files with 178 additions and 207 deletions

View File

@ -95,7 +95,7 @@ impl Backplane {
}
let cards: Vec<_> = card_configs
.into_iter()
.map(|cfg| cfg.into_card())
.map(card::Config::into_card)
.try_collect()?;
let mmu = cards
@ -328,7 +328,7 @@ impl Backplane {
fn read_byte_io(&self, address: u8) -> NullableResult<u8, BusError> {
#[allow(clippy::single_match)]
match address {
0x1 => NullableResult::Ok(self.io_at_top_16mb.load(Ordering::Relaxed) as u8),
0x1 => NullableResult::Ok(u8::from(self.io_at_top_16mb.load(Ordering::Relaxed))),
_ => NullableResult::Ok(0),
}
}

View File

@ -3,8 +3,8 @@ use std::fmt::Display;
use bitvec::prelude::*;
use crate::instruction::{
BitInsType, Condition, EffectiveAddress, Instruction, MoveDirection, RegisterEffective,
Rotation, ShiftDirection, ShiftType, Size, ControlRegister,
BitInsType, Condition, ControlRegister, EffectiveAddress, Instruction, MoveDirection,
RegisterEffective, Rotation, ShiftDirection, ShiftType, Size,
};
use derive_try_from_primitive::TryFromPrimitive;
@ -461,7 +461,7 @@ impl<T> Disasm<'_, T> {
} else if ins_word[4..13].load_be::<u16>() == 0b1_1100_1010 {
let areg = ins_word[13..16].load_be::<u8>();
let displacement = self.read_immediate(Size::Word)? as i16;
Ok(Instruction::Link {areg, displacement})
Ok(Instruction::Link { areg, displacement })
} else if ins_word[4..13].load_be::<u16>() == 0b1_1100_1011 {
let dst = ins_word[13..16].load_be::<u8>();
Ok(Instruction::Unlk(dst))
@ -502,7 +502,8 @@ impl<T> Disasm<'_, T> {
} else {
EffectiveAddress::DataReg(reg_num)
};
let ctrl = ControlRegister::try_from(word2[4..16].load_be::<u16>()).map_err(|_| DisassemblyError::InvalidInstruction)?;
let ctrl = ControlRegister::try_from(word2[4..16].load_be::<u16>())
.map_err(|_| DisassemblyError::InvalidInstruction)?;
Ok(Instruction::Movec(dir, ea, ctrl))
} else if ins_word[4..10].load_be::<u8>() == 0b11_1010 {
let dst_mode =
@ -616,9 +617,9 @@ impl<T> Disasm<'_, T> {
Size::Long => unreachable!(),
};
let new_pc = if displacement >= 0 {
pc.wrapping_add(displacement as u16 as u32)
pc.wrapping_add(u32::from(displacement as u16))
} else {
pc.wrapping_sub(-displacement as u16 as u32)
pc.wrapping_sub(u32::from(-displacement as u16))
};
if condition == Condition::False {
Ok(Instruction::Bsr(size, displacement, new_pc))

View File

@ -265,23 +265,22 @@ impl Display for ShiftDirection {
}
}
#[derive(Debug, Clone, TryFromPrimitive)]
#[repr(u16)]
pub enum ControlRegister {
SFC = 0x0,
DFC = 0x1,
USP = 0x800,
VBR = 0x801,
Sfc = 0x0,
Dfc = 0x1,
Usp = 0x800,
Vbr = 0x801,
}
impl Display for ControlRegister {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::SFC => f.write_str("SFC"),
Self::DFC => f.write_str("DFC"),
Self::USP => f.write_str("USP"),
Self::VBR => f.write_str("VBR"),
Self::Sfc => f.write_str("SFC"),
Self::Dfc => f.write_str("DFC"),
Self::Usp => f.write_str("USP"),
Self::Vbr => f.write_str("VBR"),
}
}
}
@ -488,12 +487,10 @@ impl Display for Instruction {
Self::Rts => write!(f, "RTS"),
Self::Trapv => write!(f, "TRAPV"),
Self::Rtr => write!(f, "RTR"),
Self::Movec(dir, ea, ctrl) => {
match dir {
Self::Movec(dir, ea, ctrl) => match dir {
MoveDirection::MemToReg => write!(f, "MOVEC {ctrl}, {ea}"),
MoveDirection::RegToMem => write!(f, "MOVEC {ea}, {ctrl}"),
}
}
},
Self::Jsr(ea) => write!(f, "JSR {ea}"),
Self::Jmp(ea) => write!(f, "JMP {ea}"),
Self::Movem(dir, size, dst, regs) => {

View File

@ -8,8 +8,8 @@ use crate::{
backplane::Backplane,
disas::{self, DisassemblyError},
instruction::{
ArithType, BitInsType, EffectiveAddress, Instruction, MoveDirection, ShiftDirection,
ShiftType, Size, ControlRegister, Rotation,
ArithType, BitInsType, ControlRegister, EffectiveAddress, Instruction, MoveDirection,
Rotation, ShiftDirection, ShiftType, Size,
},
};
@ -87,37 +87,37 @@ enum MemCycleInfo {
impl MemCycleInfo {
fn is_err(&self) -> bool {
match self {
MemCycleInfo::ReadByte { result, .. } => result.is_err(),
MemCycleInfo::ReadWord { result, .. } => result.is_err(),
MemCycleInfo::WriteByte { result, .. } => result.is_err(),
MemCycleInfo::WriteWord { result, .. } => result.is_err(),
Self::ReadByte { result, .. } => result.is_err(),
Self::ReadWord { result, .. } => result.is_err(),
Self::WriteByte { result, .. } => result.is_err(),
Self::WriteWord { result, .. } => result.is_err(),
}
}
fn unwrap_err(&self) -> DetailedBusError {
match self {
MemCycleInfo::ReadByte { result, .. } => result.unwrap_err(),
MemCycleInfo::ReadWord { result, .. } => result.unwrap_err(),
MemCycleInfo::WriteByte { result, .. } => result.unwrap_err(),
MemCycleInfo::WriteWord { result, .. } => result.unwrap_err(),
Self::ReadByte { result, .. } => result.unwrap_err(),
Self::ReadWord { result, .. } => result.unwrap_err(),
Self::WriteByte { result, .. } => result.unwrap_err(),
Self::WriteWord { result, .. } => result.unwrap_err(),
}
}
fn address(&self) -> u32 {
*(match self {
MemCycleInfo::ReadByte { address, .. } => address,
MemCycleInfo::ReadWord { address, .. } => address,
MemCycleInfo::WriteByte { address, .. } => address,
MemCycleInfo::WriteWord { address, .. } => address,
Self::ReadByte { address, .. } => address,
Self::ReadWord { address, .. } => address,
Self::WriteByte { address, .. } => address,
Self::WriteWord { address, .. } => address,
})
}
fn try_get_write_data(&self) -> Option<u16> {
match self {
MemCycleInfo::ReadByte { .. } => None,
MemCycleInfo::ReadWord { .. } => None,
MemCycleInfo::WriteByte { data, .. } => Some(*data as u16),
MemCycleInfo::WriteWord { data, .. } => Some(*data),
Self::ReadByte { .. } => None,
Self::ReadWord { .. } => None,
Self::WriteByte { data, .. } => Some(u16::from(*data)),
Self::WriteWord { data, .. } => Some(*data),
}
}
}
@ -144,8 +144,14 @@ impl From<DetailedBusError> for InsExecError {
}
}
impl Display for InsExecError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BusError(err) => f.write_fmt(format_args!("{err}")),
Self::AbnormalTrap => f.write_str("Abnormal trap"),
}
}
}
#[derive(Debug)]
pub struct M68K {
@ -225,7 +231,7 @@ impl M68K {
self.read_word(4),
self.read_word(6),
) {
self.ssp = ((ssp_high as u32) << 16) | (ssp_low as u32);
self.ssp = (u32::from(ssp_high) << 16) | u32::from(ssp_low);
self.vbr = 0;
self.pc = (u32::from(pc_high) << 16) | u32::from(pc_low);
self.sr = 0x2700 | self.sr & 0xFF;
@ -243,33 +249,34 @@ impl M68K {
pub fn disassemble(
&mut self,
loc: u32,
) -> Result<(Instruction, u32), DisassemblyError<DetailedBusError>> {
) -> Result<(Instruction, u32), DisassemblyError<InsExecError>> {
disas::disasm(loc, &mut |addr| {
self.read_word(addr).map_err(|err| DetailedBusError {
self.read_word(addr).map_err(|err| match err {
InsExecError::AbnormalTrap => InsExecError::AbnormalTrap,
InsExecError::BusError(err) => InsExecError::BusError(DetailedBusError {
cause: BusErrorCause::ReadingInstruction,
..err.try_into_bus_error().unwrap()
..err
}),
})
})
}
pub fn step(&mut self) {
let bus_error = match self.step_ret_berr() {
Ok(_) => {
Ok(()) => {
self.stored_mem_cycles.clear();
return;
},
Err(e) => {
match e {
}
Err(e) => match e {
InsExecError::BusError(e) => e,
InsExecError::AbnormalTrap => {
self.stored_mem_cycles.clear();
return;
},
}
},
};
if self.handling_bus_error {
println!("{} while handling bus error, halting", bus_error);
println!("{bus_error} while handling bus error, halting");
self.stopped = true;
self.stored_mem_cycles.clear();
self.use_stored_mem_cycles = false;
@ -288,22 +295,23 @@ impl M68K {
};
let stored_mem_cycles_len = self.stored_mem_cycles.len();
let last_cycle = &self.stored_mem_cycles[stored_mem_cycles_len - 1];
if let Err(snd_bus_error) = self
.berr_trap(
if let Err(snd_bus_error) = self.berr_trap(
write,
ins,
byte_access,
bus_error.address,
last_cycle.try_get_write_data().unwrap_or(0),
)
{
println!("{} while trapping to bus error handler for {}, halting", snd_bus_error.try_into_bus_error().unwrap(), bus_error);
) {
println!(
"{} while trapping to bus error handler for {}, halting",
snd_bus_error.try_into_bus_error().unwrap(),
bus_error
);
self.stopped = true;
self.stored_mem_cycles.clear();
self.use_stored_mem_cycles = false;
self.handling_bus_error = false;
self.store_mem_cycles = true;
return;
}
}
@ -316,13 +324,16 @@ impl M68K {
}
let (ins, new_pc) = match self.disassemble(self.pc) {
Ok(ins) => ins,
Err(DisassemblyError::InvalidInstruction) => panic!("Invalid instruction"),
Err(DisassemblyError::ReadError(e)) => return Err(e.into()),
Err(DisassemblyError::InvalidInstruction) => {
self.trap(4)?;
return self.step_ret_berr();
}
Err(DisassemblyError::ReadError(e)) => return Err(e),
};
self.pc = new_pc;
match ins {
Instruction::OriCcr(val) => {
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) | val as u16);
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) | u16::from(val));
}
Instruction::OriSr(val) => self.sr |= val,
Instruction::Ori(size, dst, val) => {
@ -340,7 +351,7 @@ impl M68K {
self.sr = (self.sr & 0xFFE0) | new_flags;
}
Instruction::AndiCcr(val) => {
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) & val as u16);
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) & u16::from(val));
}
Instruction::AndiSr(val) => self.sr &= val,
Instruction::Andi(size, dst, val) => {
@ -364,7 +375,7 @@ impl M68K {
self.add(dst, EffectiveAddress::Immediate(val), size, ArithType::Reg)?;
}
Instruction::EoriCcr(val) => {
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) ^ val as u16);
self.sr = (self.sr & 0xFF00) | ((self.sr & 0xFF) ^ u16::from(val));
}
Instruction::EoriSr(val) => self.sr ^= val,
Instruction::Eori(size, dst, val) => {
@ -423,7 +434,7 @@ impl M68K {
)? as u8;
self.write_effective(
EffectiveAddress::DataReg(dreg),
((high as u32) << 8) | (low as u32),
(u32::from(high) << 8) | u32::from(low),
Size::Word,
)?;
}
@ -446,10 +457,10 @@ impl M68K {
)? as u8;
self.write_effective(
EffectiveAddress::DataReg(dreg),
((high as u32) << 24)
| ((mid_high as u32) << 16)
| ((mid_low as u32) << 8)
| (low as u32),
(u32::from(high) << 24)
| (u32::from(mid_high) << 16)
| (u32::from(mid_low) << 8)
| u32::from(low),
Size::Word,
)?;
}
@ -600,11 +611,7 @@ impl M68K {
} else {
sp.wrapping_sub(-displacement as u32)
};
self.write_effective(
EffectiveAddress::AddressReg(7),
new_sp,
Size::Long,
)?;
self.write_effective(EffectiveAddress::AddressReg(7), new_sp, Size::Long)?;
}
Instruction::Unlk(areg) => {
let dst = EffectiveAddress::AddressReg(areg);
@ -657,14 +664,11 @@ impl M68K {
let ssw_rerrun = (special_status_word >> 15) > 1;
let stored_mem_cycles_len = self.stored_mem_cycles.len();
let last_cycle = &mut self.stored_mem_cycles[stored_mem_cycles_len - 1];
if !ssw_rerrun {
if last_cycle.is_err() {
self.stored_mem_cycles.pop();
}
} else {
if fault_address != last_cycle.address() {
panic!("Recorded fault address did not match cycle address");
};
if ssw_rerrun {
assert!(
fault_address == last_cycle.address(),
"Recorded fault address did not match cycle address"
);
let (expected_write, expected_ins, expected_byte_access) =
match last_cycle.unwrap_err().cause {
BusErrorCause::ReadingByte => (false, false, true),
@ -673,15 +677,9 @@ impl M68K {
BusErrorCause::WritingWord => (true, false, false),
BusErrorCause::ReadingInstruction => (false, true, false),
};
if ssw_write != expected_write {
panic!("Write flag in the SSW did not match kind of cycle when returning from handling bus error (got {}, expected {})", ssw_write, expected_write);
};
if ssw_ins != expected_ins {
panic!("Instruction flag in the SSW did not match kind of cycle when returning from handling bus error (got {}, expected {})", ssw_ins, expected_ins);
};
if ssw_byte_access != expected_byte_access {
panic!("Byte access flag in the SSW did not match kind of cycle when returning from handling bus error (got {}, expected {})", ssw_byte_access, expected_byte_access);
};
assert!(ssw_write == expected_write, "Write flag in the SSW did not match kind of cycle when returning from handling bus error (got {ssw_write}, expected {expected_write})");
assert!(ssw_ins == expected_ins, "Instruction flag in the SSW did not match kind of cycle when returning from handling bus error (got {ssw_ins}, expected {expected_ins})");
assert!(ssw_byte_access == expected_byte_access, "Byte access flag in the SSW did not match kind of cycle when returning from handling bus error (got {ssw_byte_access}, expected {expected_byte_access})");
let input_buf = if ssw_ins {
instruction_input_buf
} else {
@ -705,6 +703,8 @@ impl M68K {
*result = Ok(());
}
}
} else if last_cycle.is_err() {
self.stored_mem_cycles.pop();
}
}
}
@ -719,34 +719,28 @@ impl M68K {
self.sr = (self.sr & 0xFF00) | u16::from(self.pop(Size::Word)? as u8);
self.pc = self.pop(Size::Long)?;
}
Instruction::Movec(dir, ea, ctrl) => {
match dir {
MoveDirection::MemToReg => {
match ctrl {
ControlRegister::SFC => todo!(),
ControlRegister::DFC => todo!(),
ControlRegister::USP => {
Instruction::Movec(dir, ea, ctrl) => match dir {
MoveDirection::MemToReg => match ctrl {
ControlRegister::Sfc => todo!(),
ControlRegister::Dfc => todo!(),
ControlRegister::Usp => {
self.write_effective(ea, self.usp, Size::Long)?;
},
ControlRegister::VBR => {
}
ControlRegister::Vbr => {
self.write_effective(ea, self.vbr, Size::Long)?;
},
}
},
MoveDirection::RegToMem => {
match ctrl {
ControlRegister::SFC => todo!(),
ControlRegister::DFC => todo!(),
ControlRegister::USP => {
MoveDirection::RegToMem => match ctrl {
ControlRegister::Sfc => todo!(),
ControlRegister::Dfc => todo!(),
ControlRegister::Usp => {
self.usp = self.read_effective(ea, Size::Long)?;
},
ControlRegister::VBR => {
self.vbr = self.read_effective(ea, Size::Long)? &!(0x3FF);
},
}
ControlRegister::Vbr => {
self.vbr = self.read_effective(ea, Size::Long)? & !(0x3FF);
}
},
}
}
},
Instruction::Jsr(ea) => {
self.push(self.pc, Size::Long)?;
self.pc = self.effective_address(ea)?;
@ -780,7 +774,7 @@ impl M68K {
}
Instruction::Addq(size, val, dst) => self.add(
dst,
EffectiveAddress::Immediate(val as i32 as u32),
EffectiveAddress::Immediate(i32::from(val) as u32),
size,
if matches!(dst, EffectiveAddress::AddressReg(_)) {
ArithType::Addr
@ -790,7 +784,7 @@ impl M68K {
)?,
Instruction::Subq(size, val, dst) => self.sub(
dst,
EffectiveAddress::Immediate(val as i32 as u32),
EffectiveAddress::Immediate(i32::from(val) as u32),
size,
if matches!(dst, EffectiveAddress::AddressReg(_)) {
ArithType::Addr
@ -827,7 +821,7 @@ impl M68K {
}
}
Instruction::Moveq { dreg, imm } => {
let imm = imm as i32 as u32;
let imm = i32::from(imm) as u32;
let neg = (imm & 0x8000_0000) > 0;
let zero = imm == 0;
let old_flags = self.sr & 0xFFE0;
@ -1361,7 +1355,7 @@ impl M68K {
.wrapping_add(self.read_effective(EffectiveAddress::from(idx), idx_size)?);
self.read_address(address, size)
}
EffectiveAddress::AbsoluteShort(x) => self.read_address(x as u32, size),
EffectiveAddress::AbsoluteShort(x) => self.read_address(u32::from(x), size),
EffectiveAddress::AbsoluteLong(x) => self.read_address(x, size),
}
}
@ -1440,7 +1434,7 @@ impl M68K {
.wrapping_add(self.read_effective(EffectiveAddress::from(idx), idx_size)?);
self.write_address(address, data, size)?;
}
EffectiveAddress::AbsoluteShort(x) => self.write_address(x as u32, data, size)?,
EffectiveAddress::AbsoluteShort(x) => self.write_address(u32::from(x), data, size)?,
EffectiveAddress::AbsoluteLong(x) => self.write_address(x, data, size)?,
EffectiveAddress::PcDisplacement(..)
| EffectiveAddress::PcIndex(..)
@ -1450,7 +1444,6 @@ impl M68K {
}
fn read_address(&mut self, address: u32, size: Size) -> Result<u32, InsExecError> {
// println!("READ {:x}, {:?}", address, size);
let address = address & 0xFF_FFFF;
match size {
Size::Byte => Ok(u32::from(self.read_byte(address)?)),
@ -1462,13 +1455,7 @@ impl M68K {
}
}
fn write_address(
&mut self,
address: u32,
data: u32,
size: Size,
) -> Result<(), InsExecError> {
// println!("WRITE {:x}, {:?}, data {:x}", address, size, data);
fn write_address(&mut self, address: u32, data: u32, size: Size) -> Result<(), InsExecError> {
match size {
Size::Byte => self.write_byte(address, data as u8)?,
Size::Word => self.write_word(address, data as u16)?,
@ -1489,11 +1476,8 @@ impl M68K {
result,
} = cycle
{
if stored_address == address {
assert!(stored_address == address, "Stored bus cycle has wrong address when reading byte (reading {address:#x}, stored {stored_address:#x})");
return Ok(result?);
} else {
panic!("Stored bus cycle has wrong address when reading byte (reading {:#x}, stored {:#x})", address, stored_address);
}
}
if self.stored_mem_cycles.is_empty() {
self.store_mem_cycles = true;
@ -1504,10 +1488,8 @@ impl M68K {
cause: BusErrorCause::ReadingByte,
});
if self.store_mem_cycles {
self.stored_mem_cycles.push(MemCycleInfo::ReadByte {
address,
result: result.clone(),
});
self.stored_mem_cycles
.push(MemCycleInfo::ReadByte { address, result });
};
Ok(result?)
}
@ -1525,9 +1507,9 @@ impl M68K {
if stored_address == address && stored_data == data {
return Ok(result?);
} else if stored_address != address {
panic!("Stored bus cycle has wrong address when writing byte (reading {:#x}, stored {:#x})", address, stored_address);
panic!("Stored bus cycle has wrong address when writing byte (reading {address:#x}, stored {stored_address:#x})");
} else if stored_data != data {
panic!("Stored bus cycle has wrong data when writing byte (writing {:#x}, stored {:#x})", data, stored_data);
panic!("Stored bus cycle has wrong data when writing byte (writing {data:#x}, stored {stored_data:#x})");
}
}
if self.stored_mem_cycles.is_empty() {
@ -1545,7 +1527,7 @@ impl M68K {
self.stored_mem_cycles.push(MemCycleInfo::WriteByte {
address,
data,
result: result.clone(),
result,
});
};
Ok(result?)
@ -1564,11 +1546,8 @@ impl M68K {
result,
} = cycle
{
if stored_address == address {
assert!(stored_address == address, "Stored bus cycle has wrong address when reading word (reading {address:#x}, stored {stored_address:#x})");
return Ok(result?);
} else {
panic!("Stored bus cycle has wrong address when reading word (reading {:#x}, stored {:#x})", address, stored_address);
}
}
if self.stored_mem_cycles.is_empty() {
self.store_mem_cycles = true;
@ -1579,10 +1558,8 @@ impl M68K {
cause: BusErrorCause::ReadingWord,
});
if self.store_mem_cycles {
self.stored_mem_cycles.push(MemCycleInfo::ReadWord {
address,
result: result.clone(),
});
self.stored_mem_cycles
.push(MemCycleInfo::ReadWord { address, result });
};
Ok(result?)
}
@ -1604,9 +1581,9 @@ impl M68K {
if stored_address == address && stored_data == data {
return Ok(result?);
} else if stored_address != address {
panic!("Stored bus cycle has wrong address when writing word (reading {:#x}, stored {:#x})", address, stored_address);
panic!("Stored bus cycle has wrong address when writing word (reading {address:#x}, stored {stored_address:#x})");
} else if stored_data != data {
panic!("Stored bus cycle has wrong data when writing word (writing {:#x}, stored {:#x})", data, stored_data);
panic!("Stored bus cycle has wrong data when writing word (writing {data:#x}, stored {stored_data:#x})");
}
}
if self.stored_mem_cycles.is_empty() {
@ -1624,7 +1601,7 @@ impl M68K {
self.stored_mem_cycles.push(MemCycleInfo::WriteWord {
address,
data,
result: result.clone(),
result,
});
};
Ok(result?)
@ -1663,7 +1640,7 @@ impl M68K {
}
}
EffectiveAddress::PcDisplacement(pc, d) => Ok(pc.wrapping_add(d.into())),
EffectiveAddress::AbsoluteShort(x) => Ok(x as u32),
EffectiveAddress::AbsoluteShort(x) => Ok(u32::from(x)),
EffectiveAddress::AbsoluteLong(x) => Ok(x),
EffectiveAddress::DataReg(_)
| EffectiveAddress::AddressReg(_)
@ -1735,17 +1712,17 @@ impl M68K {
// Unused
self.push(0, Size::Word)?;
// Data output buffer
self.push(write_data as u32, Size::Word)?;
self.push(u32::from(write_data), Size::Word)?;
// Unused
self.push(0, Size::Word)?;
// Fault address
self.push(fault_addr, Size::Long)?;
// Special status word
let special_status_word = ((write as u16) << 8)
| ((byte_access as u16) << 9)
let special_status_word = (u16::from(write) << 8)
| (u16::from(byte_access) << 9)
| (((fault_addr & 0x1) as u16) << 10)
| (!ins as u16)
| (ins as u16);
| u16::from(!ins)
| u16::from(ins);
self.push(u32::from(special_status_word), Size::Word)?;
// Format & vector
self.push(0x8002, Size::Word)?;

View File

@ -15,16 +15,13 @@ mod symbol;
mod symbol_table;
mod symbol_tables;
mod term;
use crate::{
backplane::Backplane,
location::Location,
m68k::{DetailedBusError, M68K},
};
use crate::{backplane::Backplane, location::Location, m68k::M68K};
use anyhow::anyhow;
use clap::Parser;
use disas::DisassemblyError;
use indexmap::IndexSet;
use itertools::Itertools;
use m68k::InsExecError;
use parse_int::parse;
use reedline_repl_rs::{
clap::{builder::BoolishValueParser, Arg, ArgAction, Command},
@ -286,22 +283,22 @@ fn main() -> Result<(), anyhow::Error> {
if args.get_flag("phys") {
for i in 0..count {
match size {
peek::Size::Byte => data.push(bus.read_byte_phys(addr + i)? as u32),
peek::Size::Word => data.push(bus.read_word_phys(addr + (i * 2))? as u32),
peek::Size::Byte => data.push(u32::from(bus.read_byte_phys(addr + i)?)),
peek::Size::Word => data.push(u32::from(bus.read_word_phys(addr + (i * 2))?)),
peek::Size::LongWord => data.push(
(bus.read_word_phys(addr + (i * 4))? as u32) << 16
| (bus.read_word_phys(addr + (i * 4) + 2)? as u32),
u32::from(bus.read_word_phys(addr + (i * 4))?) << 16
| u32::from(bus.read_word_phys(addr + (i * 4) + 2)?),
),
}
}
} else {
for i in 0..count {
match size {
peek::Size::Byte => data.push(bus.read_byte(addr + i)? as u32),
peek::Size::Word => data.push(bus.read_word(addr + (i * 2))? as u32),
peek::Size::Byte => data.push(u32::from(bus.read_byte(addr + i)?)),
peek::Size::Word => data.push(u32::from(bus.read_word(addr + (i * 2))?)),
peek::Size::LongWord => data.push(
(bus.read_word(addr + (i * 4))? as u32) << 16
| (bus.read_word(addr + (i * 4) + 2)? as u32),
u32::from(bus.read_word(addr + (i * 4))?) << 16
| u32::from(bus.read_word(addr + (i * 4) + 2)?),
),
}
}
@ -527,7 +524,7 @@ fn disas_fmt(
cpu: &mut M68K,
addr: u32,
symbol_tables: &SymbolTables,
) -> (String, Result<u32, DisassemblyError<DetailedBusError>>) {
) -> (String, Result<u32, DisassemblyError<InsExecError>>) {
let addr_fmt = if let Some((table, symbol, offset)) = symbol_tables.address_to_symbol(addr) {
format!("{table}:{symbol} + {offset} (0x{addr:x})")
} else {

View File

@ -49,7 +49,7 @@ impl Card for MmuCard {
let offset = address % 4;
match offset {
(0..=2) => NullableResult::Ok(u32_get_be_byte(self.map_frames[map_no], offset)),
3 => NullableResult::Ok(self.map_frames_enabled[map_no] as u8),
3 => NullableResult::Ok(u8::from(self.map_frames_enabled[map_no])),
_ => unreachable!(),
}
}
@ -86,18 +86,19 @@ impl Card for MmuCard {
match offset {
0 => (),
1 => {
self.tlb_clear_entry = (self.tlb_clear_entry & 0xF) | ((data as u16) << 4);
self.tlb_clear_entry =
(self.tlb_clear_entry & 0xF) | (u16::from(data) << 4);
}
2 => {
self.tlb_clear_entry =
(self.tlb_clear_entry & 0xFF0) | (((data as u16) & 0xF0) >> 4);
(self.tlb_clear_entry & 0xFF0) | ((u16::from(data) & 0xF0) >> 4);
}
3 => {
if self.print_debug {
println!(
"Clearing TLB entry {:#x} ( page start {:#x} )",
self.tlb_clear_entry,
(self.tlb_clear_entry as u32) << 12
u32::from(self.tlb_clear_entry) << 12
);
}
self.tlb[self.tlb_clear_entry as usize] = 0x0;
@ -164,7 +165,7 @@ impl Mmu for MmuCard {
let print_debug = self.print_debug;
if self.enabled {
if print_debug {
println!("Translating {:#x}", address);
println!("Translating {address:#x}");
}
let page = address >> 12;
let offset = address & 0xFFF;
@ -192,7 +193,7 @@ impl Mmu for MmuCard {
let mapping_hi = backplane.read_word_phys(mapping_address)?;
let mapping_lo = backplane.read_word_phys(mapping_address + 2)?;
let mapping =
((mapping_hi as u32) << 16 | mapping_lo as u32) | TLB_MAPPING_FLAG_VALID;
(u32::from(mapping_hi) << 16 | u32::from(mapping_lo)) | TLB_MAPPING_FLAG_VALID;
self.tlb[page as usize] = mapping;
mapping
};

View File

@ -16,8 +16,8 @@ impl Format {
Self::Hex => format!("0x{:0>width$x}", num, width = size.byte_count() * 2),
Self::Decimal => {
let num = match size {
Size::Byte => num as u8 as i8 as i32,
Size::Word => num as u16 as i16 as i32,
Size::Byte => i32::from(num as u8 as i8),
Size::Word => i32::from(num as u16 as i16),
Size::LongWord => num as i32,
};
format!("{num}")

View File

@ -77,7 +77,7 @@ impl Card for Rom {
match address {
(0..=0xEF) => NullableResult::Ok(self.ram[address as usize]),
(0xF0..=0xF1) => NullableResult::Ok(u16_get_be_byte(self.start, address - 0xF0)),
0xF3 => NullableResult::Ok(self.enabled as u8),
0xF3 => NullableResult::Ok(u8::from(self.enabled)),
(0xFE..=0xFF) => NullableResult::Ok(u16_get_be_byte(ID, address - 0xFE)),
_ => NullableResult::Null,
}
@ -144,7 +144,7 @@ impl Display for Rom {
if self.enabled {
f.write_fmt(format_args!(
", enabled at base address {:#x}",
(self.start as u32) << 16
u32::from(self.start) << 16
))?;
};
Ok(())

View File

@ -102,14 +102,13 @@ impl Card for Storage {
0x9 => match data {
0x0 => {
if let Some((file, _)) = &mut self.file {
file.seek(SeekFrom::Start(self.sector as u64 * SECTOR_SIZE))
file.seek(SeekFrom::Start(u64::from(self.sector) * SECTOR_SIZE))
.unwrap();
let mut buf = Vec::new();
buf.resize(self.count as usize * SECTOR_SIZE as usize, 0);
let mut buf = vec![0; self.count as usize * SECTOR_SIZE as usize];
match file.read_exact(&mut buf) {
Ok(_) => (),
Ok(()) => (),
Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => (),
Err(e) => Err(e).unwrap(),
Err(e) => panic!("{e:?}"),
}
self.read_data.extend(buf);
self.status.set(Status::DATA_READY, true);
@ -117,14 +116,13 @@ impl Card for Storage {
}
0x1 => {
if let Some((file, _)) = &mut self.file {
file.seek(SeekFrom::Start(self.sector as u64 * SECTOR_SIZE))
file.seek(SeekFrom::Start(u64::from(self.sector) * SECTOR_SIZE))
.unwrap();
let mut buf = Vec::new();
buf.resize(self.count as usize * SECTOR_SIZE as usize, 0);
let mut buf = vec![0; self.count as usize * SECTOR_SIZE as usize];
match file.read_exact(&mut buf) {
Ok(_) => (),
Ok(()) => (),
Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => (),
Err(e) => Err(e).unwrap(),
Err(e) => panic!("{e:?}"),
}
self.read_data.extend(buf);
self.status.set(Status::BUSY, true);

View File

@ -84,8 +84,8 @@ impl SymbolTable {
self.breakpoints = self
.breakpoints
.iter()
.filter(|&sym| table.symbols.contains_key(sym))
.cloned()
.filter(|sym| table.symbols.contains_key(sym))
.collect::<IndexSet<_>>();
self.symbols = table.symbols;
}