Ad suport for the VBR and MOVEC
This commit is contained in:
parent
601e29b634
commit
26837a6750
18
src/disas.rs
18
src/disas.rs
@ -4,7 +4,7 @@ use bitvec::prelude::*;
|
||||
|
||||
use crate::instruction::{
|
||||
BitInsType, Condition, EffectiveAddress, Instruction, MoveDirection, RegisterEffective,
|
||||
Rotation, ShiftDirection, ShiftType, Size,
|
||||
Rotation, ShiftDirection, ShiftType, Size, ControlRegister,
|
||||
};
|
||||
|
||||
use derive_try_from_primitive::TryFromPrimitive;
|
||||
@ -488,6 +488,22 @@ impl<T> Disasm<'_, T> {
|
||||
Ok(Instruction::Trapv)
|
||||
} else if ins_word[4..16].load_be::<u16>() == 0b1110_0111_0111 {
|
||||
Ok(Instruction::Rtr)
|
||||
} else if ins_word[4..15].load_be::<u16>() == 0b111_0011_1101 {
|
||||
let dir = if ins_word[15] {
|
||||
MoveDirection::RegToMem
|
||||
} else {
|
||||
MoveDirection::MemToReg
|
||||
};
|
||||
let word2 = self.read_prog_word()?;
|
||||
let word2 = word2.view_bits::<Msb0>();
|
||||
let reg_num = word2[1..4].load_be::<u8>();
|
||||
let ea = if word2[0] {
|
||||
EffectiveAddress::AddressReg(reg_num)
|
||||
} else {
|
||||
EffectiveAddress::DataReg(reg_num)
|
||||
};
|
||||
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 =
|
||||
AddressingMode::try_from(ins_word[10..13].load_be::<u8>()).unwrap();
|
||||
|
@ -265,6 +265,27 @@ impl Display for ShiftDirection {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, TryFromPrimitive)]
|
||||
#[repr(u16)]
|
||||
pub enum ControlRegister {
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Instruction {
|
||||
OriCcr(u8),
|
||||
@ -324,6 +345,7 @@ pub enum Instruction {
|
||||
Rts,
|
||||
Trapv,
|
||||
Rtr,
|
||||
Movec(MoveDirection, EffectiveAddress, ControlRegister),
|
||||
Jsr(EffectiveAddress),
|
||||
Jmp(EffectiveAddress),
|
||||
Movem(MoveDirection, Size, EffectiveAddress, Vec<EffectiveAddress>),
|
||||
@ -466,6 +488,12 @@ 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 {
|
||||
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) => {
|
||||
|
37
src/m68k.rs
37
src/m68k.rs
@ -9,7 +9,7 @@ use crate::{
|
||||
disas::{self, DisassemblyError},
|
||||
instruction::{
|
||||
ArithType, BitInsType, EffectiveAddress, Instruction, MoveDirection, ShiftDirection,
|
||||
ShiftType, Size,
|
||||
ShiftType, Size, ControlRegister,
|
||||
},
|
||||
};
|
||||
|
||||
@ -128,6 +128,7 @@ pub struct M68K {
|
||||
aregs: [u32; 7],
|
||||
usp: u32,
|
||||
ssp: u32,
|
||||
vbr: u32,
|
||||
pc: u32,
|
||||
sr: u16,
|
||||
bus: Backplane,
|
||||
@ -179,6 +180,7 @@ impl M68K {
|
||||
aregs: [0; 7],
|
||||
usp: 0,
|
||||
ssp: 0,
|
||||
vbr: 0,
|
||||
pc: 0,
|
||||
sr: 0,
|
||||
bus,
|
||||
@ -199,6 +201,7 @@ impl M68K {
|
||||
self.read_word(6),
|
||||
) {
|
||||
self.ssp = ((ssp_high as u32) << 16) | (ssp_low as u32);
|
||||
self.vbr = 0;
|
||||
self.pc = (u32::from(pc_high) << 16) | u32::from(pc_low);
|
||||
self.sr = 0x2700 | self.sr & 0xFF;
|
||||
self.stopped = false;
|
||||
@ -675,6 +678,34 @@ 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 => {
|
||||
self.write_effective(ea, self.usp, Size::Long)?;
|
||||
},
|
||||
ControlRegister::VBR => {
|
||||
self.write_effective(ea, self.vbr, Size::Long)?;
|
||||
},
|
||||
}
|
||||
},
|
||||
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);
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Instruction::Jsr(ea) => {
|
||||
self.push(self.pc, Size::Long)?;
|
||||
self.pc = self.effective_address(ea)?;
|
||||
@ -1621,7 +1652,7 @@ impl M68K {
|
||||
}
|
||||
|
||||
fn trap(&mut self, vector: u8) -> Result<(), DetailedBusError> {
|
||||
let new_pc = self.read_address(u32::from(vector) * 4, Size::Long)?;
|
||||
let new_pc = self.read_address((u32::from(vector) * 4) + self.vbr, Size::Long)?;
|
||||
self.push(u32::from(vector), Size::Word)?;
|
||||
self.push(self.pc, Size::Long)?;
|
||||
self.push(u32::from(self.sr), Size::Word)?;
|
||||
@ -1638,7 +1669,7 @@ impl M68K {
|
||||
fault_addr: u32,
|
||||
write_data: u16,
|
||||
) -> Result<(), DetailedBusError> {
|
||||
let new_pc = self.read_address(2 * 4, Size::Long)?;
|
||||
let new_pc = self.read_address(2 * 4 + self.vbr, Size::Long)?;
|
||||
// Version & internal information
|
||||
self.push(0, Size::Long)?;
|
||||
self.push(0, Size::Long)?;
|
||||
|
Loading…
Reference in New Issue
Block a user