Ad suport for the VBR and MOVEC

This commit is contained in:
pjht 2023-11-04 09:02:44 -05:00
parent 601e29b634
commit 26837a6750
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
3 changed files with 79 additions and 4 deletions

View File

@ -4,7 +4,7 @@ use bitvec::prelude::*;
use crate::instruction::{ use crate::instruction::{
BitInsType, Condition, EffectiveAddress, Instruction, MoveDirection, RegisterEffective, BitInsType, Condition, EffectiveAddress, Instruction, MoveDirection, RegisterEffective,
Rotation, ShiftDirection, ShiftType, Size, Rotation, ShiftDirection, ShiftType, Size, ControlRegister,
}; };
use derive_try_from_primitive::TryFromPrimitive; use derive_try_from_primitive::TryFromPrimitive;
@ -488,6 +488,22 @@ impl<T> Disasm<'_, T> {
Ok(Instruction::Trapv) Ok(Instruction::Trapv)
} else if ins_word[4..16].load_be::<u16>() == 0b1110_0111_0111 { } else if ins_word[4..16].load_be::<u16>() == 0b1110_0111_0111 {
Ok(Instruction::Rtr) 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 { } else if ins_word[4..10].load_be::<u8>() == 0b11_1010 {
let dst_mode = let dst_mode =
AddressingMode::try_from(ins_word[10..13].load_be::<u8>()).unwrap(); AddressingMode::try_from(ins_word[10..13].load_be::<u8>()).unwrap();

View File

@ -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)] #[derive(Debug, Clone)]
pub enum Instruction { pub enum Instruction {
OriCcr(u8), OriCcr(u8),
@ -324,6 +345,7 @@ pub enum Instruction {
Rts, Rts,
Trapv, Trapv,
Rtr, Rtr,
Movec(MoveDirection, EffectiveAddress, ControlRegister),
Jsr(EffectiveAddress), Jsr(EffectiveAddress),
Jmp(EffectiveAddress), Jmp(EffectiveAddress),
Movem(MoveDirection, Size, EffectiveAddress, Vec<EffectiveAddress>), Movem(MoveDirection, Size, EffectiveAddress, Vec<EffectiveAddress>),
@ -466,6 +488,12 @@ impl Display for Instruction {
Self::Rts => write!(f, "RTS"), Self::Rts => write!(f, "RTS"),
Self::Trapv => write!(f, "TRAPV"), Self::Trapv => write!(f, "TRAPV"),
Self::Rtr => write!(f, "RTR"), 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::Jsr(ea) => write!(f, "JSR {ea}"),
Self::Jmp(ea) => write!(f, "JMP {ea}"), Self::Jmp(ea) => write!(f, "JMP {ea}"),
Self::Movem(dir, size, dst, regs) => { Self::Movem(dir, size, dst, regs) => {

View File

@ -9,7 +9,7 @@ use crate::{
disas::{self, DisassemblyError}, disas::{self, DisassemblyError},
instruction::{ instruction::{
ArithType, BitInsType, EffectiveAddress, Instruction, MoveDirection, ShiftDirection, ArithType, BitInsType, EffectiveAddress, Instruction, MoveDirection, ShiftDirection,
ShiftType, Size, ShiftType, Size, ControlRegister,
}, },
}; };
@ -128,6 +128,7 @@ pub struct M68K {
aregs: [u32; 7], aregs: [u32; 7],
usp: u32, usp: u32,
ssp: u32, ssp: u32,
vbr: u32,
pc: u32, pc: u32,
sr: u16, sr: u16,
bus: Backplane, bus: Backplane,
@ -179,6 +180,7 @@ impl M68K {
aregs: [0; 7], aregs: [0; 7],
usp: 0, usp: 0,
ssp: 0, ssp: 0,
vbr: 0,
pc: 0, pc: 0,
sr: 0, sr: 0,
bus, bus,
@ -199,6 +201,7 @@ impl M68K {
self.read_word(6), self.read_word(6),
) { ) {
self.ssp = ((ssp_high as u32) << 16) | (ssp_low as u32); 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.pc = (u32::from(pc_high) << 16) | u32::from(pc_low);
self.sr = 0x2700 | self.sr & 0xFF; self.sr = 0x2700 | self.sr & 0xFF;
self.stopped = false; self.stopped = false;
@ -675,6 +678,34 @@ impl M68K {
self.sr = (self.sr & 0xFF00) | u16::from(self.pop(Size::Word)? as u8); self.sr = (self.sr & 0xFF00) | u16::from(self.pop(Size::Word)? as u8);
self.pc = self.pop(Size::Long)?; 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) => { Instruction::Jsr(ea) => {
self.push(self.pc, Size::Long)?; self.push(self.pc, Size::Long)?;
self.pc = self.effective_address(ea)?; self.pc = self.effective_address(ea)?;
@ -1621,7 +1652,7 @@ impl M68K {
} }
fn trap(&mut self, vector: u8) -> Result<(), DetailedBusError> { 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(u32::from(vector), Size::Word)?;
self.push(self.pc, Size::Long)?; self.push(self.pc, Size::Long)?;
self.push(u32::from(self.sr), Size::Word)?; self.push(u32::from(self.sr), Size::Word)?;
@ -1638,7 +1669,7 @@ impl M68K {
fault_addr: u32, fault_addr: u32,
write_data: u16, write_data: u16,
) -> Result<(), DetailedBusError> { ) -> 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 // Version & internal information
self.push(0, Size::Long)?; self.push(0, Size::Long)?;
self.push(0, Size::Long)?; self.push(0, Size::Long)?;