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::{
|
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();
|
||||||
|
@ -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) => {
|
||||||
|
37
src/m68k.rs
37
src/m68k.rs
@ -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)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user