mirror of
https://github.com/transistorfet/moa.git
synced 2024-12-23 03:29:24 +00:00
Moved m68k instruction types to their own file
This commit is contained in:
parent
32d2d591ce
commit
3fc76335d0
@ -1,11 +1,22 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
use crate::devices::{Address, Addressable};
|
||||
|
||||
use super::state::{M68kType, Exceptions};
|
||||
use super::instructions::{
|
||||
Size,
|
||||
Sign,
|
||||
Direction,
|
||||
ShiftDirection,
|
||||
XRegister,
|
||||
RegOrImmediate,
|
||||
ControlRegister,
|
||||
Condition,
|
||||
Target,
|
||||
Instruction,
|
||||
sign_extend_to_long,
|
||||
};
|
||||
|
||||
|
||||
const OPCG_BIT_OPS: u8 = 0x0;
|
||||
@ -29,184 +40,6 @@ const OPCG_RESERVED1: u8 = 0xA;
|
||||
const OPCG_RESERVED2: u8 = 0xF;
|
||||
|
||||
|
||||
pub type Register = u8;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Sign {
|
||||
Signed,
|
||||
Unsigned,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Direction {
|
||||
FromTarget,
|
||||
ToTarget,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum ShiftDirection {
|
||||
Right,
|
||||
Left,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum XRegister {
|
||||
Data(u8),
|
||||
Address(u8),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum RegOrImmediate {
|
||||
DReg(u8),
|
||||
Immediate(u8),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum ControlRegister {
|
||||
VBR,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Size {
|
||||
Byte,
|
||||
Word,
|
||||
Long,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Condition {
|
||||
True,
|
||||
False,
|
||||
High,
|
||||
LowOrSame,
|
||||
CarryClear,
|
||||
CarrySet,
|
||||
NotEqual,
|
||||
Equal,
|
||||
OverflowClear,
|
||||
OverflowSet,
|
||||
Plus,
|
||||
Minus,
|
||||
GreaterThanOrEqual,
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
LessThanOrEqual,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Target {
|
||||
Immediate(u32),
|
||||
DirectDReg(Register),
|
||||
DirectAReg(Register),
|
||||
IndirectAReg(Register),
|
||||
IndirectARegInc(Register),
|
||||
IndirectARegDec(Register),
|
||||
IndirectARegOffset(Register, i32),
|
||||
IndirectARegXRegOffset(Register, XRegister, i32, u8, Size),
|
||||
IndirectMemory(u32),
|
||||
IndirectPCOffset(i32),
|
||||
IndirectPCXRegOffset(XRegister, i32, u8, Size),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Instruction {
|
||||
ABCD(Target, Target),
|
||||
ADD(Target, Target, Size),
|
||||
AND(Target, Target, Size),
|
||||
ANDtoCCR(u8),
|
||||
ANDtoSR(u16),
|
||||
ASd(Target, Target, Size, ShiftDirection),
|
||||
|
||||
Bcc(Condition, i32),
|
||||
BRA(i32),
|
||||
BSR(i32),
|
||||
BCHG(Target, Target, Size),
|
||||
BCLR(Target, Target, Size),
|
||||
BSET(Target, Target, Size),
|
||||
BTST(Target, Target, Size),
|
||||
BFCHG(Target, RegOrImmediate, RegOrImmediate),
|
||||
BFCLR(Target, RegOrImmediate, RegOrImmediate),
|
||||
BFEXTS(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||
BFEXTU(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||
BFFFO(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||
BFINS(Register, Target, RegOrImmediate, RegOrImmediate),
|
||||
BFSET(Target, RegOrImmediate, RegOrImmediate),
|
||||
BFTST(Target, RegOrImmediate, RegOrImmediate),
|
||||
BKPT(u8),
|
||||
|
||||
CHK(Target, Register, Size),
|
||||
CLR(Target, Size),
|
||||
CMP(Target, Target, Size),
|
||||
CMPA(Target, Register, Size),
|
||||
|
||||
DBcc(Condition, Register, i16),
|
||||
DIV(Target, Target, Size, Sign),
|
||||
|
||||
EOR(Target, Target, Size),
|
||||
EORtoCCR(u8),
|
||||
EORtoSR(u16),
|
||||
EXG(Target, Target),
|
||||
EXT(Register, Size, Size),
|
||||
|
||||
ILLEGAL,
|
||||
|
||||
JMP(Target),
|
||||
JSR(Target),
|
||||
|
||||
LEA(Target, Register),
|
||||
LINK(Register, i16),
|
||||
LSd(Target, Target, Size, ShiftDirection),
|
||||
|
||||
MOVE(Target, Target, Size),
|
||||
MOVEA(Target, Register, Size),
|
||||
MOVEfromSR(Target),
|
||||
MOVEtoSR(Target),
|
||||
MOVEfromCCR(Target),
|
||||
MOVEtoCCR(Target),
|
||||
MOVEC(Target, ControlRegister, Direction),
|
||||
MOVEM(Target, Size, Direction, u16),
|
||||
MOVEP(Register, Target, Size, Direction),
|
||||
MOVEQ(u8, Register),
|
||||
MOVEUSP(Target, Direction),
|
||||
MUL(Target, Target, Size, Sign),
|
||||
|
||||
NBCD(Target),
|
||||
NEG(Target, Size),
|
||||
NEGX(Target, Size),
|
||||
|
||||
NOP,
|
||||
NOT(Target, Size),
|
||||
|
||||
OR(Target, Target, Size),
|
||||
ORtoCCR(u8),
|
||||
ORtoSR(u16),
|
||||
|
||||
PEA(Target),
|
||||
|
||||
RESET,
|
||||
ROd(Target, Target, Size, ShiftDirection),
|
||||
ROXd(Target, Target, Size, ShiftDirection),
|
||||
RTE,
|
||||
RTR,
|
||||
RTS,
|
||||
RTD(i16),
|
||||
|
||||
SBCD(Target, Target),
|
||||
Scc(Condition, Target),
|
||||
STOP(u16),
|
||||
SUB(Target, Target, Size),
|
||||
SWAP(Register),
|
||||
|
||||
TAS(Target),
|
||||
TST(Target, Size),
|
||||
TRAP(u8),
|
||||
TRAPV,
|
||||
|
||||
UNLK(Register),
|
||||
}
|
||||
|
||||
|
||||
pub struct M68kDecoder {
|
||||
pub cputype: M68kType,
|
||||
pub base: u32,
|
||||
@ -929,232 +762,3 @@ fn get_condition(ins: u16) -> Condition {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Size {
|
||||
pub fn in_bytes(&self) -> u32 {
|
||||
match self {
|
||||
Size::Byte => 1,
|
||||
Size::Word => 2,
|
||||
Size::Long => 4,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn in_bits(&self) -> u32 {
|
||||
match self {
|
||||
Size::Byte => 8,
|
||||
Size::Word => 16,
|
||||
Size::Long => 32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign_extend_to_long(value: u32, from: Size) -> i32 {
|
||||
match from {
|
||||
Size::Byte => ((value as u8) as i8) as i32,
|
||||
Size::Word => ((value as u16) as i16) as i32,
|
||||
Size::Long => value as i32,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Sign {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Sign::Signed => write!(f, "s"),
|
||||
Sign::Unsigned => write!(f, "u"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ShiftDirection {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ShiftDirection::Right => write!(f, "r"),
|
||||
ShiftDirection::Left => write!(f, "l"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Size {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Size::Byte => write!(f, "b"),
|
||||
Size::Word => write!(f, "w"),
|
||||
Size::Long => write!(f, "l"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Condition {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Condition::True => write!(f, "t"),
|
||||
Condition::False => write!(f, "f"),
|
||||
Condition::High => write!(f, "hi"),
|
||||
Condition::LowOrSame => write!(f, "ls"),
|
||||
Condition::CarryClear => write!(f, "cc"),
|
||||
Condition::CarrySet => write!(f, "cs"),
|
||||
Condition::NotEqual => write!(f, "ne"),
|
||||
Condition::Equal => write!(f, "eq"),
|
||||
Condition::OverflowClear => write!(f, "oc"),
|
||||
Condition::OverflowSet => write!(f, "os"),
|
||||
Condition::Plus => write!(f, "p"),
|
||||
Condition::Minus => write!(f, "m"),
|
||||
Condition::GreaterThanOrEqual => write!(f, "ge"),
|
||||
Condition::LessThan => write!(f, "lt"),
|
||||
Condition::GreaterThan => write!(f, "gt"),
|
||||
Condition::LessThanOrEqual => write!(f, "le"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ControlRegister {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ControlRegister::VBR => write!(f, "%vbr"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for XRegister {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
XRegister::Data(reg) => write!(f, "d{}", reg),
|
||||
XRegister::Address(reg) => write!(f, "a{}", reg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Target {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Target::Immediate(value) => write!(f, "#{:08x}", value),
|
||||
Target::DirectDReg(reg) => write!(f, "%d{}", reg),
|
||||
Target::DirectAReg(reg) => write!(f, "%a{}", reg),
|
||||
Target::IndirectAReg(reg) => write!(f, "(%a{})", reg),
|
||||
Target::IndirectARegInc(reg) => write!(f, "(%a{})+", reg),
|
||||
Target::IndirectARegDec(reg) => write!(f, "-(%a{})", reg),
|
||||
Target::IndirectARegOffset(reg, offset) => write!(f, "(%a{} + #{:04x})", reg, offset),
|
||||
Target::IndirectARegXRegOffset(reg, xreg, offset, scale, _) => {
|
||||
let scale_str = if *scale != 0 { format!("<< {}", scale) } else { "".to_string() };
|
||||
write!(f, "(%a{} + %{} + #{:04x}{})", reg, xreg, offset, scale_str)
|
||||
},
|
||||
Target::IndirectMemory(value) => write!(f, "(#{:08x})", value),
|
||||
Target::IndirectPCOffset(offset) => write!(f, "(%pc + #{:04x})", offset),
|
||||
Target::IndirectPCXRegOffset(xreg, offset, scale, _) => {
|
||||
let scale_str = if *scale != 0 { format!("<< {}", scale) } else { "".to_string() };
|
||||
write!(f, "(%pc + %{} + #{:04x}{})", xreg, offset, scale_str)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_movem_mask(mask: u16) -> String {
|
||||
format!("something")
|
||||
}
|
||||
|
||||
impl fmt::Display for Instruction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Instruction::ABCD(src, dest) => write!(f, "abcd\t{}, {}", src, dest),
|
||||
Instruction::ADD(src, dest, size) => write!(f, "add{}\t{}, {}", size, src, dest),
|
||||
Instruction::AND(src, dest, size) => write!(f, "and{}\t{}, {}", size, src, dest),
|
||||
Instruction::ANDtoCCR(value) => write!(f, "andb\t{:02x}, %ccr", value),
|
||||
Instruction::ANDtoSR(value) => write!(f, "andw\t{:04x}, %sr", value),
|
||||
Instruction::ASd(src, dest, size, dir) => write!(f, "as{}{}\t{}, {}", dir, size, src, dest),
|
||||
|
||||
Instruction::Bcc(cond, offset) => write!(f, "b{}\t{}", cond, offset),
|
||||
Instruction::BRA(offset) => write!(f, "bra\t{}", offset),
|
||||
Instruction::BSR(offset) => write!(f, "bra\t{}", offset),
|
||||
Instruction::BCHG(src, dest, size) => write!(f, "bchg{}\t{}, {}", size, src, dest),
|
||||
Instruction::BCLR(src, dest, size) => write!(f, "bclr{}\t{}, {}", size, src, dest),
|
||||
Instruction::BSET(src, dest, size) => write!(f, "bset{}\t{}, {}", size, src, dest),
|
||||
Instruction::BTST(src, dest, size) => write!(f, "btst{}\t{}, {}", size, src, dest),
|
||||
//Instruction::BKPT(value),
|
||||
|
||||
Instruction::CHK(target, reg, size) => write!(f, "chk{}\t{}, %d{}", size, target, reg),
|
||||
Instruction::CLR(target, size) => write!(f, "clr{}\t{}", size, target),
|
||||
Instruction::CMP(src, dest, size) => write!(f, "cmp{}\t{}, {}", size, src, dest),
|
||||
Instruction::CMPA(target, reg, size) => write!(f, "cmpa{}\t{}, %a{}", size, target, reg),
|
||||
|
||||
Instruction::DBcc(cond, reg, offset) => write!(f, "db{}\t%d{}, {}", cond, reg, offset),
|
||||
Instruction::DIV(src, dest, size, sign) => write!(f, "div{}{}\t{}, {}", sign, size, src, dest),
|
||||
|
||||
Instruction::EOR(src, dest, size) => write!(f, "eor{}\t{}, {}", size, src, dest),
|
||||
Instruction::EORtoCCR(value) => write!(f, "eorb\t{:02x}, %ccr", value),
|
||||
Instruction::EORtoSR(value) => write!(f, "eorw\t{:04x}, %sr", value),
|
||||
Instruction::EXG(src, dest) => write!(f, "exg\t{}, {}", src, dest),
|
||||
Instruction::EXT(reg, from_size, to_size) => write!(f, "ext{}{}\t%d{}", from_size, to_size, reg),
|
||||
|
||||
Instruction::ILLEGAL => write!(f, "illegal"),
|
||||
|
||||
Instruction::JMP(target) => write!(f, "jmp\t{}", target),
|
||||
Instruction::JSR(target) => write!(f, "jsr\t{}", target),
|
||||
|
||||
Instruction::LEA(target, reg) => write!(f, "lea\t{}, %a{}", target, reg),
|
||||
Instruction::LINK(reg, offset) => write!(f, "link\t%a{}, {}", reg, offset),
|
||||
Instruction::LSd(src, dest, size, dir) => write!(f, "ls{}{}\t{}, {}", dir, size, src, dest),
|
||||
|
||||
Instruction::MOVE(src, dest, size) => write!(f, "move{}\t{}, {}", size, src, dest),
|
||||
Instruction::MOVEA(target, reg, size) => write!(f, "movea{}\t{}, %a{}", size, target, reg),
|
||||
Instruction::MOVEfromSR(target) => write!(f, "movew\t%sr, {}", target),
|
||||
Instruction::MOVEtoSR(target) => write!(f, "movew\t{}, %sr", target),
|
||||
Instruction::MOVEfromCCR(target) => write!(f, "moveb\t%ccr, {}", target),
|
||||
Instruction::MOVEtoCCR(target) => write!(f, "moveb\t{}, %ccr", target),
|
||||
Instruction::MOVEC(target, reg, dir) => match dir {
|
||||
Direction::ToTarget => write!(f, "movec\t{}, {}", reg, target),
|
||||
Direction::FromTarget => write!(f, "movec\t{}, {}", target, reg),
|
||||
},
|
||||
Instruction::MOVEM(target, size, dir, mask) => match dir {
|
||||
Direction::ToTarget => write!(f, "movem{}\t{}, {}", size, fmt_movem_mask(*mask), target),
|
||||
Direction::FromTarget => write!(f, "movem{}\t{}, {}", size, target, fmt_movem_mask(*mask)),
|
||||
},
|
||||
Instruction::MOVEP(reg, target, size, dir) => match dir {
|
||||
Direction::ToTarget => write!(f, "movep{}\t%d{}, {}", size, reg, target),
|
||||
Direction::FromTarget => write!(f, "movep{}\t{}, %d{}", size, target, reg),
|
||||
},
|
||||
Instruction::MOVEQ(value, reg) => write!(f, "moveq\t#{:02x}, %d{}", value, reg),
|
||||
Instruction::MOVEUSP(target, dir) => match dir {
|
||||
Direction::ToTarget => write!(f, "movel\t%usp, {}", target),
|
||||
Direction::FromTarget => write!(f, "movel\t{}, %usp", target),
|
||||
},
|
||||
Instruction::MUL(src, dest, size, sign) => write!(f, "mul{}{}\t{}, {}", sign, size, src, dest),
|
||||
|
||||
Instruction::NBCD(target) => write!(f, "nbcd\t{}", target),
|
||||
Instruction::NEG(target, size) => write!(f, "neg{}\t{}", size, target),
|
||||
Instruction::NEGX(target, size) => write!(f, "negx{}\t{}", size, target),
|
||||
|
||||
Instruction::NOP => write!(f, "nop"),
|
||||
Instruction::NOT(target, size) => write!(f, "not{}\t{}", size, target),
|
||||
|
||||
Instruction::OR(src, dest, size) => write!(f, "or{}\t{}, {}", size, src, dest),
|
||||
Instruction::ORtoCCR(value) => write!(f, "orb\t{:02x}, %ccr", value),
|
||||
Instruction::ORtoSR(value) => write!(f, "orw\t{:04x}, %sr", value),
|
||||
|
||||
Instruction::PEA(target) => write!(f, "pea\t{}", target),
|
||||
|
||||
Instruction::RESET => write!(f, "reset"),
|
||||
Instruction::ROd(src, dest, size, dir) => write!(f, "ro{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::ROXd(src, dest, size, dir) => write!(f, "rox{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::RTE => write!(f, "rte"),
|
||||
Instruction::RTR => write!(f, "rtr"),
|
||||
Instruction::RTS => write!(f, "rts"),
|
||||
Instruction::RTD(offset) => write!(f, "rtd\t{}", offset),
|
||||
|
||||
Instruction::SBCD(src, dest) => write!(f, "sbcd\t{}, {}", src, dest),
|
||||
Instruction::Scc(cond, target) => write!(f, "s{}\t{}", cond, target),
|
||||
Instruction::STOP(value) => write!(f, "stop\t#{:04x}", value),
|
||||
Instruction::SUB(src, dest, size) => write!(f, "sub{}\t{}, {}", size, src, dest),
|
||||
Instruction::SWAP(reg) => write!(f, "swap\t%d{}", reg),
|
||||
|
||||
Instruction::TAS(target) => write!(f, "tas\t{}", target),
|
||||
Instruction::TST(target, size) => write!(f, "tst{}\t{}", size, target),
|
||||
Instruction::TRAP(num) => write!(f, "trap\t{}", num),
|
||||
Instruction::TRAPV => write!(f, "trapv"),
|
||||
|
||||
Instruction::UNLK(reg) => write!(f, "unlk\t%a{}", reg),
|
||||
_ => write!(f, "UNIMPL"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,21 +3,22 @@ use crate::system::System;
|
||||
use crate::error::{ErrorType, Error};
|
||||
use crate::devices::{Clock, Address, Steppable, Interruptable, Addressable, Transmutable};
|
||||
|
||||
use super::decode::{
|
||||
Instruction,
|
||||
Target,
|
||||
use super::instructions::{
|
||||
Register,
|
||||
Size,
|
||||
Sign,
|
||||
Direction,
|
||||
Condition,
|
||||
ShiftDirection,
|
||||
ControlRegister,
|
||||
Register,
|
||||
XRegister,
|
||||
RegOrImmediate,
|
||||
sign_extend_to_long
|
||||
ControlRegister,
|
||||
Condition,
|
||||
Target,
|
||||
Instruction,
|
||||
sign_extend_to_long,
|
||||
};
|
||||
|
||||
|
||||
const DEV_NAME: &'static str = "m68k-cpu";
|
||||
|
||||
use super::state::{M68k, Status, Flags, Exceptions, InterruptPriority};
|
||||
|
408
src/cpus/m68k/instructions.rs
Normal file
408
src/cpus/m68k/instructions.rs
Normal file
@ -0,0 +1,408 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
||||
pub type Register = u8;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Size {
|
||||
Byte,
|
||||
Word,
|
||||
Long,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Sign {
|
||||
Signed,
|
||||
Unsigned,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Direction {
|
||||
FromTarget,
|
||||
ToTarget,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum ShiftDirection {
|
||||
Right,
|
||||
Left,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum XRegister {
|
||||
Data(u8),
|
||||
Address(u8),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum RegOrImmediate {
|
||||
DReg(u8),
|
||||
Immediate(u8),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum ControlRegister {
|
||||
VBR,
|
||||
}
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Condition {
|
||||
True,
|
||||
False,
|
||||
High,
|
||||
LowOrSame,
|
||||
CarryClear,
|
||||
CarrySet,
|
||||
NotEqual,
|
||||
Equal,
|
||||
OverflowClear,
|
||||
OverflowSet,
|
||||
Plus,
|
||||
Minus,
|
||||
GreaterThanOrEqual,
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
LessThanOrEqual,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Target {
|
||||
Immediate(u32),
|
||||
DirectDReg(Register),
|
||||
DirectAReg(Register),
|
||||
IndirectAReg(Register),
|
||||
IndirectARegInc(Register),
|
||||
IndirectARegDec(Register),
|
||||
IndirectARegOffset(Register, i32),
|
||||
IndirectARegXRegOffset(Register, XRegister, i32, u8, Size),
|
||||
IndirectMemory(u32),
|
||||
IndirectPCOffset(i32),
|
||||
IndirectPCXRegOffset(XRegister, i32, u8, Size),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum Instruction {
|
||||
ABCD(Target, Target),
|
||||
ADD(Target, Target, Size),
|
||||
AND(Target, Target, Size),
|
||||
ANDtoCCR(u8),
|
||||
ANDtoSR(u16),
|
||||
ASd(Target, Target, Size, ShiftDirection),
|
||||
|
||||
Bcc(Condition, i32),
|
||||
BRA(i32),
|
||||
BSR(i32),
|
||||
BCHG(Target, Target, Size),
|
||||
BCLR(Target, Target, Size),
|
||||
BSET(Target, Target, Size),
|
||||
BTST(Target, Target, Size),
|
||||
BFCHG(Target, RegOrImmediate, RegOrImmediate),
|
||||
BFCLR(Target, RegOrImmediate, RegOrImmediate),
|
||||
BFEXTS(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||
BFEXTU(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||
BFFFO(Target, RegOrImmediate, RegOrImmediate, Register),
|
||||
BFINS(Register, Target, RegOrImmediate, RegOrImmediate),
|
||||
BFSET(Target, RegOrImmediate, RegOrImmediate),
|
||||
BFTST(Target, RegOrImmediate, RegOrImmediate),
|
||||
BKPT(u8),
|
||||
|
||||
CHK(Target, Register, Size),
|
||||
CLR(Target, Size),
|
||||
CMP(Target, Target, Size),
|
||||
CMPA(Target, Register, Size),
|
||||
|
||||
DBcc(Condition, Register, i16),
|
||||
DIV(Target, Target, Size, Sign),
|
||||
|
||||
EOR(Target, Target, Size),
|
||||
EORtoCCR(u8),
|
||||
EORtoSR(u16),
|
||||
EXG(Target, Target),
|
||||
EXT(Register, Size, Size),
|
||||
|
||||
ILLEGAL,
|
||||
|
||||
JMP(Target),
|
||||
JSR(Target),
|
||||
|
||||
LEA(Target, Register),
|
||||
LINK(Register, i16),
|
||||
LSd(Target, Target, Size, ShiftDirection),
|
||||
|
||||
MOVE(Target, Target, Size),
|
||||
MOVEA(Target, Register, Size),
|
||||
MOVEfromSR(Target),
|
||||
MOVEtoSR(Target),
|
||||
MOVEfromCCR(Target),
|
||||
MOVEtoCCR(Target),
|
||||
MOVEC(Target, ControlRegister, Direction),
|
||||
MOVEM(Target, Size, Direction, u16),
|
||||
MOVEP(Register, Target, Size, Direction),
|
||||
MOVEQ(u8, Register),
|
||||
MOVEUSP(Target, Direction),
|
||||
MUL(Target, Target, Size, Sign),
|
||||
|
||||
NBCD(Target),
|
||||
NEG(Target, Size),
|
||||
NEGX(Target, Size),
|
||||
|
||||
NOP,
|
||||
NOT(Target, Size),
|
||||
|
||||
OR(Target, Target, Size),
|
||||
ORtoCCR(u8),
|
||||
ORtoSR(u16),
|
||||
|
||||
PEA(Target),
|
||||
|
||||
RESET,
|
||||
ROd(Target, Target, Size, ShiftDirection),
|
||||
ROXd(Target, Target, Size, ShiftDirection),
|
||||
RTE,
|
||||
RTR,
|
||||
RTS,
|
||||
RTD(i16),
|
||||
|
||||
SBCD(Target, Target),
|
||||
Scc(Condition, Target),
|
||||
STOP(u16),
|
||||
SUB(Target, Target, Size),
|
||||
SWAP(Register),
|
||||
|
||||
TAS(Target),
|
||||
TST(Target, Size),
|
||||
TRAP(u8),
|
||||
TRAPV,
|
||||
|
||||
UNLK(Register),
|
||||
}
|
||||
|
||||
pub fn sign_extend_to_long(value: u32, from: Size) -> i32 {
|
||||
match from {
|
||||
Size::Byte => ((value as u8) as i8) as i32,
|
||||
Size::Word => ((value as u16) as i16) as i32,
|
||||
Size::Long => value as i32,
|
||||
}
|
||||
}
|
||||
|
||||
impl Size {
|
||||
pub fn in_bytes(&self) -> u32 {
|
||||
match self {
|
||||
Size::Byte => 1,
|
||||
Size::Word => 2,
|
||||
Size::Long => 4,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn in_bits(&self) -> u32 {
|
||||
match self {
|
||||
Size::Byte => 8,
|
||||
Size::Word => 16,
|
||||
Size::Long => 32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Sign {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Sign::Signed => write!(f, "s"),
|
||||
Sign::Unsigned => write!(f, "u"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ShiftDirection {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ShiftDirection::Right => write!(f, "r"),
|
||||
ShiftDirection::Left => write!(f, "l"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Size {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Size::Byte => write!(f, "b"),
|
||||
Size::Word => write!(f, "w"),
|
||||
Size::Long => write!(f, "l"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Condition {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Condition::True => write!(f, "t"),
|
||||
Condition::False => write!(f, "f"),
|
||||
Condition::High => write!(f, "hi"),
|
||||
Condition::LowOrSame => write!(f, "ls"),
|
||||
Condition::CarryClear => write!(f, "cc"),
|
||||
Condition::CarrySet => write!(f, "cs"),
|
||||
Condition::NotEqual => write!(f, "ne"),
|
||||
Condition::Equal => write!(f, "eq"),
|
||||
Condition::OverflowClear => write!(f, "oc"),
|
||||
Condition::OverflowSet => write!(f, "os"),
|
||||
Condition::Plus => write!(f, "p"),
|
||||
Condition::Minus => write!(f, "m"),
|
||||
Condition::GreaterThanOrEqual => write!(f, "ge"),
|
||||
Condition::LessThan => write!(f, "lt"),
|
||||
Condition::GreaterThan => write!(f, "gt"),
|
||||
Condition::LessThanOrEqual => write!(f, "le"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ControlRegister {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ControlRegister::VBR => write!(f, "%vbr"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for XRegister {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
XRegister::Data(reg) => write!(f, "d{}", reg),
|
||||
XRegister::Address(reg) => write!(f, "a{}", reg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Target {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Target::Immediate(value) => write!(f, "#{:08x}", value),
|
||||
Target::DirectDReg(reg) => write!(f, "%d{}", reg),
|
||||
Target::DirectAReg(reg) => write!(f, "%a{}", reg),
|
||||
Target::IndirectAReg(reg) => write!(f, "(%a{})", reg),
|
||||
Target::IndirectARegInc(reg) => write!(f, "(%a{})+", reg),
|
||||
Target::IndirectARegDec(reg) => write!(f, "-(%a{})", reg),
|
||||
Target::IndirectARegOffset(reg, offset) => write!(f, "(%a{} + #{:04x})", reg, offset),
|
||||
Target::IndirectARegXRegOffset(reg, xreg, offset, scale, _) => {
|
||||
let scale_str = if *scale != 0 { format!("<< {}", scale) } else { "".to_string() };
|
||||
write!(f, "(%a{} + %{} + #{:04x}{})", reg, xreg, offset, scale_str)
|
||||
},
|
||||
Target::IndirectMemory(value) => write!(f, "(#{:08x})", value),
|
||||
Target::IndirectPCOffset(offset) => write!(f, "(%pc + #{:04x})", offset),
|
||||
Target::IndirectPCXRegOffset(xreg, offset, scale, _) => {
|
||||
let scale_str = if *scale != 0 { format!("<< {}", scale) } else { "".to_string() };
|
||||
write!(f, "(%pc + %{} + #{:04x}{})", xreg, offset, scale_str)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_movem_mask(mask: u16) -> String {
|
||||
format!("something")
|
||||
}
|
||||
|
||||
impl fmt::Display for Instruction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Instruction::ABCD(src, dest) => write!(f, "abcd\t{}, {}", src, dest),
|
||||
Instruction::ADD(src, dest, size) => write!(f, "add{}\t{}, {}", size, src, dest),
|
||||
Instruction::AND(src, dest, size) => write!(f, "and{}\t{}, {}", size, src, dest),
|
||||
Instruction::ANDtoCCR(value) => write!(f, "andb\t{:02x}, %ccr", value),
|
||||
Instruction::ANDtoSR(value) => write!(f, "andw\t{:04x}, %sr", value),
|
||||
Instruction::ASd(src, dest, size, dir) => write!(f, "as{}{}\t{}, {}", dir, size, src, dest),
|
||||
|
||||
Instruction::Bcc(cond, offset) => write!(f, "b{}\t{}", cond, offset),
|
||||
Instruction::BRA(offset) => write!(f, "bra\t{}", offset),
|
||||
Instruction::BSR(offset) => write!(f, "bra\t{}", offset),
|
||||
Instruction::BCHG(src, dest, size) => write!(f, "bchg{}\t{}, {}", size, src, dest),
|
||||
Instruction::BCLR(src, dest, size) => write!(f, "bclr{}\t{}, {}", size, src, dest),
|
||||
Instruction::BSET(src, dest, size) => write!(f, "bset{}\t{}, {}", size, src, dest),
|
||||
Instruction::BTST(src, dest, size) => write!(f, "btst{}\t{}, {}", size, src, dest),
|
||||
//Instruction::BKPT(value),
|
||||
|
||||
Instruction::CHK(target, reg, size) => write!(f, "chk{}\t{}, %d{}", size, target, reg),
|
||||
Instruction::CLR(target, size) => write!(f, "clr{}\t{}", size, target),
|
||||
Instruction::CMP(src, dest, size) => write!(f, "cmp{}\t{}, {}", size, src, dest),
|
||||
Instruction::CMPA(target, reg, size) => write!(f, "cmpa{}\t{}, %a{}", size, target, reg),
|
||||
|
||||
Instruction::DBcc(cond, reg, offset) => write!(f, "db{}\t%d{}, {}", cond, reg, offset),
|
||||
Instruction::DIV(src, dest, size, sign) => write!(f, "div{}{}\t{}, {}", sign, size, src, dest),
|
||||
|
||||
Instruction::EOR(src, dest, size) => write!(f, "eor{}\t{}, {}", size, src, dest),
|
||||
Instruction::EORtoCCR(value) => write!(f, "eorb\t{:02x}, %ccr", value),
|
||||
Instruction::EORtoSR(value) => write!(f, "eorw\t{:04x}, %sr", value),
|
||||
Instruction::EXG(src, dest) => write!(f, "exg\t{}, {}", src, dest),
|
||||
Instruction::EXT(reg, from_size, to_size) => write!(f, "ext{}{}\t%d{}", from_size, to_size, reg),
|
||||
|
||||
Instruction::ILLEGAL => write!(f, "illegal"),
|
||||
|
||||
Instruction::JMP(target) => write!(f, "jmp\t{}", target),
|
||||
Instruction::JSR(target) => write!(f, "jsr\t{}", target),
|
||||
|
||||
Instruction::LEA(target, reg) => write!(f, "lea\t{}, %a{}", target, reg),
|
||||
Instruction::LINK(reg, offset) => write!(f, "link\t%a{}, {}", reg, offset),
|
||||
Instruction::LSd(src, dest, size, dir) => write!(f, "ls{}{}\t{}, {}", dir, size, src, dest),
|
||||
|
||||
Instruction::MOVE(src, dest, size) => write!(f, "move{}\t{}, {}", size, src, dest),
|
||||
Instruction::MOVEA(target, reg, size) => write!(f, "movea{}\t{}, %a{}", size, target, reg),
|
||||
Instruction::MOVEfromSR(target) => write!(f, "movew\t%sr, {}", target),
|
||||
Instruction::MOVEtoSR(target) => write!(f, "movew\t{}, %sr", target),
|
||||
Instruction::MOVEfromCCR(target) => write!(f, "moveb\t%ccr, {}", target),
|
||||
Instruction::MOVEtoCCR(target) => write!(f, "moveb\t{}, %ccr", target),
|
||||
Instruction::MOVEC(target, reg, dir) => match dir {
|
||||
Direction::ToTarget => write!(f, "movec\t{}, {}", reg, target),
|
||||
Direction::FromTarget => write!(f, "movec\t{}, {}", target, reg),
|
||||
},
|
||||
Instruction::MOVEM(target, size, dir, mask) => match dir {
|
||||
Direction::ToTarget => write!(f, "movem{}\t{}, {}", size, fmt_movem_mask(*mask), target),
|
||||
Direction::FromTarget => write!(f, "movem{}\t{}, {}", size, target, fmt_movem_mask(*mask)),
|
||||
},
|
||||
Instruction::MOVEP(reg, target, size, dir) => match dir {
|
||||
Direction::ToTarget => write!(f, "movep{}\t%d{}, {}", size, reg, target),
|
||||
Direction::FromTarget => write!(f, "movep{}\t{}, %d{}", size, target, reg),
|
||||
},
|
||||
Instruction::MOVEQ(value, reg) => write!(f, "moveq\t#{:02x}, %d{}", value, reg),
|
||||
Instruction::MOVEUSP(target, dir) => match dir {
|
||||
Direction::ToTarget => write!(f, "movel\t%usp, {}", target),
|
||||
Direction::FromTarget => write!(f, "movel\t{}, %usp", target),
|
||||
},
|
||||
Instruction::MUL(src, dest, size, sign) => write!(f, "mul{}{}\t{}, {}", sign, size, src, dest),
|
||||
|
||||
Instruction::NBCD(target) => write!(f, "nbcd\t{}", target),
|
||||
Instruction::NEG(target, size) => write!(f, "neg{}\t{}", size, target),
|
||||
Instruction::NEGX(target, size) => write!(f, "negx{}\t{}", size, target),
|
||||
|
||||
Instruction::NOP => write!(f, "nop"),
|
||||
Instruction::NOT(target, size) => write!(f, "not{}\t{}", size, target),
|
||||
|
||||
Instruction::OR(src, dest, size) => write!(f, "or{}\t{}, {}", size, src, dest),
|
||||
Instruction::ORtoCCR(value) => write!(f, "orb\t{:02x}, %ccr", value),
|
||||
Instruction::ORtoSR(value) => write!(f, "orw\t{:04x}, %sr", value),
|
||||
|
||||
Instruction::PEA(target) => write!(f, "pea\t{}", target),
|
||||
|
||||
Instruction::RESET => write!(f, "reset"),
|
||||
Instruction::ROd(src, dest, size, dir) => write!(f, "ro{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::ROXd(src, dest, size, dir) => write!(f, "rox{}{}\t{}, {}", dir, size, src, dest),
|
||||
Instruction::RTE => write!(f, "rte"),
|
||||
Instruction::RTR => write!(f, "rtr"),
|
||||
Instruction::RTS => write!(f, "rts"),
|
||||
Instruction::RTD(offset) => write!(f, "rtd\t{}", offset),
|
||||
|
||||
Instruction::SBCD(src, dest) => write!(f, "sbcd\t{}, {}", src, dest),
|
||||
Instruction::Scc(cond, target) => write!(f, "s{}\t{}", cond, target),
|
||||
Instruction::STOP(value) => write!(f, "stop\t#{:04x}", value),
|
||||
Instruction::SUB(src, dest, size) => write!(f, "sub{}\t{}, {}", size, src, dest),
|
||||
Instruction::SWAP(reg) => write!(f, "swap\t%d{}", reg),
|
||||
|
||||
Instruction::TAS(target) => write!(f, "tas\t{}", target),
|
||||
Instruction::TST(target, size) => write!(f, "tst{}\t{}", size, target),
|
||||
Instruction::TRAP(num) => write!(f, "trap\t{}", num),
|
||||
Instruction::TRAPV => write!(f, "trapv"),
|
||||
|
||||
Instruction::UNLK(reg) => write!(f, "unlk\t%a{}", reg),
|
||||
_ => write!(f, "UNIMPL"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ pub mod state;
|
||||
pub mod decode;
|
||||
pub mod execute;
|
||||
pub mod debugger;
|
||||
pub mod instructions;
|
||||
pub mod tests;
|
||||
|
||||
pub use self::state::{M68k, M68kType};
|
||||
|
@ -3,10 +3,10 @@
|
||||
mod decode_tests {
|
||||
use crate::system::System;
|
||||
use crate::memory::MemoryBlock;
|
||||
use crate::devices::{Address, Addressable, Steppable, AddressableDeviceBox, wrap_addressable, MAX_READ};
|
||||
use crate::devices::{Address, Addressable, Steppable, TransmutableBox, wrap_transmutable, MAX_READ};
|
||||
|
||||
use crate::cpus::m68k::{M68k, M68kType};
|
||||
use crate::cpus::m68k::decode::{Instruction, Target, Size, Sign, XRegister, ShiftDirection};
|
||||
use crate::cpus::m68k::instructions::{Instruction, Target, Size, Sign, XRegister, ShiftDirection};
|
||||
|
||||
const INIT_STACK: Address = 0x00002000;
|
||||
const INIT_ADDR: Address = 0x00000010;
|
||||
@ -17,7 +17,7 @@ mod decode_tests {
|
||||
// Insert basic initialization
|
||||
let data = vec![0; 0x00100000];
|
||||
let mem = MemoryBlock::new(data);
|
||||
system.add_addressable_device(0x00000000, wrap_addressable(mem)).unwrap();
|
||||
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
|
||||
system.get_bus().write_beu32(0, INIT_STACK as u32).unwrap();
|
||||
system.get_bus().write_beu32(4, INIT_ADDR as u32).unwrap();
|
||||
|
||||
@ -30,7 +30,7 @@ mod decode_tests {
|
||||
(cpu, system)
|
||||
}
|
||||
|
||||
fn get_decode_memory(cpu: &mut M68k, system: &System) -> AddressableDeviceBox {
|
||||
fn get_decode_memory(cpu: &mut M68k, system: &System) -> TransmutableBox {
|
||||
let (memory, relative_addr) = system.get_bus().get_device_at(INIT_ADDR, 12).unwrap();
|
||||
cpu.decoder.init((INIT_ADDR - relative_addr) as u32, INIT_ADDR as u32);
|
||||
memory
|
||||
@ -48,7 +48,7 @@ mod decode_tests {
|
||||
let expected = 0x1234;
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b000, 0b001, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b000, 0b001, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::DirectDReg(1));
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ mod decode_tests {
|
||||
let expected = 0x1234;
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b001, 0b010, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b001, 0b010, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::DirectAReg(2));
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b010, 0b010, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b010, 0b010, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectAReg(2));
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b011, 0b010, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b011, 0b010, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectARegInc(2));
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b100, 0b010, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b100, 0b010, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectARegDec(2));
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu16(INIT_ADDR, (offset as i16) as u16).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b101, 0b100, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b101, 0b100, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectARegOffset(4, offset));
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu16(INIT_ADDR + 2, (offset as i16) as u16).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b110, 0b010, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b110, 0b010, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectARegXRegOffset(2, XRegister::Data(3), offset, 0, size));
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu16(INIT_ADDR, expected as u16).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b111, 0b000, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b000, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectMemory(expected));
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu32(INIT_ADDR, expected).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b111, 0b001, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b001, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectMemory(expected));
|
||||
}
|
||||
|
||||
@ -177,7 +177,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu16(INIT_ADDR, (offset as i16) as u16).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b111, 0b010, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b010, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectPCOffset(offset));
|
||||
}
|
||||
|
||||
@ -193,7 +193,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu16(INIT_ADDR + 2, (offset as i16) as u16).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b111, 0b011, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b011, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::IndirectPCXRegOffset(XRegister::Data(3), offset, 0, size));
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ mod decode_tests {
|
||||
system.get_bus().write_beu16(INIT_ADDR, expected as u16).unwrap();
|
||||
|
||||
let memory = get_decode_memory(&mut cpu, &system);
|
||||
let target = cpu.decoder.get_mode_as_target(&mut memory.borrow_mut(), 0b111, 0b100, Some(size)).unwrap();
|
||||
let target = cpu.decoder.get_mode_as_target(memory.borrow_mut().as_addressable().unwrap(), 0b111, 0b100, Some(size)).unwrap();
|
||||
assert_eq!(target, Target::Immediate(expected));
|
||||
}
|
||||
|
||||
@ -332,10 +332,10 @@ mod decode_tests {
|
||||
mod execute_tests {
|
||||
use crate::system::System;
|
||||
use crate::memory::MemoryBlock;
|
||||
use crate::devices::{Address, Addressable, Steppable, wrap_addressable};
|
||||
use crate::devices::{Address, Addressable, Steppable, wrap_transmutable};
|
||||
|
||||
use crate::cpus::m68k::{M68k, M68kType};
|
||||
use crate::cpus::m68k::decode::{Instruction, Target, Size, Sign, ShiftDirection};
|
||||
use crate::cpus::m68k::instructions::{Instruction, Target, Size, Sign, ShiftDirection};
|
||||
|
||||
const INIT_STACK: Address = 0x00002000;
|
||||
const INIT_ADDR: Address = 0x00000010;
|
||||
@ -346,7 +346,7 @@ mod execute_tests {
|
||||
// Insert basic initialization
|
||||
let data = vec![0; 0x00100000];
|
||||
let mem = MemoryBlock::new(data);
|
||||
system.add_addressable_device(0x00000000, wrap_addressable(mem)).unwrap();
|
||||
system.add_addressable_device(0x00000000, wrap_transmutable(mem)).unwrap();
|
||||
system.get_bus().write_beu32(0, INIT_STACK as u32).unwrap();
|
||||
system.get_bus().write_beu32(4, INIT_ADDR as u32).unwrap();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
|
@ -2,8 +2,7 @@
|
||||
use std::fs;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
use crate::devices::{Clock, Address, Steppable, Addressable, Transmutable, TransmutableBox, MAX_READ};
|
||||
use crate::devices::{Address, Addressable, Transmutable, TransmutableBox, MAX_READ};
|
||||
|
||||
|
||||
pub struct MemoryBlock {
|
||||
|
@ -2,8 +2,7 @@
|
||||
use std::fs;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::system::System;
|
||||
use crate::devices::{Clock, Address, Addressable, Transmutable, MAX_READ};
|
||||
use crate::devices::{Address, Addressable, Transmutable, MAX_READ};
|
||||
|
||||
|
||||
const ATA_REG_DATA_WORD: Address = 0x20;
|
||||
|
@ -4,7 +4,7 @@ use std::cell::{RefCell, RefMut};
|
||||
use crate::error::Error;
|
||||
use crate::memory::Bus;
|
||||
use crate::interrupts::InterruptController;
|
||||
use crate::devices::{Clock, Address, Transmutable, TransmutableBox};
|
||||
use crate::devices::{Clock, Address, TransmutableBox};
|
||||
|
||||
|
||||
pub struct System {
|
||||
|
Loading…
Reference in New Issue
Block a user