mirror of
https://github.com/transistorfet/moa.git
synced 2025-04-06 11:38:21 +00:00
Added formatter for Instruction to output assembly
This commit is contained in:
parent
eba1f9c9fc
commit
1732c90f5b
@ -821,7 +821,7 @@ impl M68kDecoder {
|
||||
(0..((self.end - self.start) / 2)).map(|offset|
|
||||
Ok(format!("{:04x} ", system.get_bus().read_beu16((self.start + (offset * 2)) as Address).unwrap()))
|
||||
).collect();
|
||||
println!("{:#010x}: {}\n\t{:?}\n", self.start, ins_data.unwrap(), self.instruction);
|
||||
println!("{:#010x}: {}\n\t{}\n", self.start, ins_data.unwrap(), self.instruction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -906,6 +906,66 @@ pub fn sign_extend_to_long(value: u32, from: Size) -> 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, "h"),
|
||||
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 Target {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
@ -915,11 +975,117 @@ impl fmt::Display for Target {
|
||||
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{} + #{})", reg, offset),
|
||||
Target::IndirectARegXRegOffset(reg, rtype, xreg, offset, _) => write!(f, "(%a{} + %{}{} + #{})", reg, if *rtype == RegisterType::Data { 'd' } else { 'a' }, xreg, offset),
|
||||
Target::IndirectARegOffset(reg, offset) => write!(f, "(%a{} + #{:04x})", reg, offset),
|
||||
Target::IndirectARegXRegOffset(reg, rtype, xreg, offset, _) => write!(f, "(%a{} + %{}{} + #{:04x})", reg, if *rtype == RegisterType::Data { 'd' } else { 'a' }, xreg, offset),
|
||||
Target::IndirectMemory(value) => write!(f, "(#{:08x})", value),
|
||||
Target::IndirectPCOffset(offset) => write!(f, "(%pc + #{})", offset),
|
||||
Target::IndirectPCXRegOffset(rtype, xreg, offset, _) => write!(f, "(%pc + %{}{} + #{})", if *rtype == RegisterType::Data { 'd' } else { 'a' }, xreg, offset),
|
||||
Target::IndirectPCOffset(offset) => write!(f, "(%pc + #{:04x})", offset),
|
||||
Target::IndirectPCXRegOffset(rtype, xreg, offset, _) => write!(f, "(%pc + %{}{} + #{:04x})", if *rtype == RegisterType::Data { 'd' } else { 'a' }, xreg, offset),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, size) => write!(f, "ext{}\t%d{}", 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),
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ fn main() {
|
||||
//cpu.add_breakpoint(0x10bc9c);
|
||||
//cpu.add_breakpoint(0x106a94);
|
||||
//cpu.add_breakpoint(0x10b79c);
|
||||
//cpu.decoder.dump_disassembly(&mut system, 0x100000, 0x2000);
|
||||
|
||||
system.add_interruptable_device(wrap_interruptable(cpu)).unwrap();
|
||||
loop {
|
||||
|
2
todo.txt
2
todo.txt
@ -2,7 +2,7 @@
|
||||
* add exception for privileged instructions. Should you separate them in the `match` or just put a guard into the instructions, and if the latter, can
|
||||
you use the emulator's errors to surface the execption up to the `step_internal` function but not to `System`?
|
||||
|
||||
* make functions to print assembly out
|
||||
* make it possible to break out of the current execution, into the debugger
|
||||
* how can you add 68030 support? Should it be all one module that checks maybe during decode if the instruction is supported? Should it 'inherit' from the MC68010 object
|
||||
* make tests for each instruction
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user