From 258e4dc59b7635e1ca52a7283a0e20113c6057f1 Mon Sep 17 00:00:00 2001 From: Trevor Merritt Date: Wed, 9 Jul 2025 10:36:21 -0400 Subject: [PATCH] box swap --- cli/src/bin/de6502.rs | 20 ++++++---- core/src/instruction_table.rs | 68 ++++++++++++++++----------------- resources/test/instructions.asm | 17 +++++++++ 3 files changed, 64 insertions(+), 41 deletions(-) create mode 100644 resources/test/instructions.asm diff --git a/cli/src/bin/de6502.rs b/cli/src/bin/de6502.rs index fa77aef..0ee0ebd 100644 --- a/cli/src/bin/de6502.rs +++ b/cli/src/bin/de6502.rs @@ -1,11 +1,13 @@ use std::collections::HashMap; use std::fs; +use std::fs::File; use std::path::PathBuf; use std::thread::current; use core::constants::constants_system::*; use core::constants::constants_isa_op::*; use clap::{Parser, Subcommand}; use core::instruction_table::INSTRUCTION_TABLE; +use std::io::Write; #[derive(Parser)] #[command(version, about, long_about = None)] @@ -67,28 +69,29 @@ fn decompile(data: &[u8]) -> Vec<(u16, DecompiledLine)> { let target_op = INSTRUCTION_TABLE[next_byte as usize].clone(); if let Some(top) = target_op { - println!("Instruction {:?}/{:?} needs {:?} bytes.", top.operation, top.mode, top.length); + // println!("Instruction {:?}/{:?} needs {:?} bytes.", top.operation, top.mode, top.length); let num_bytes_to_load = top.length - 1; println!("Need {num_bytes_to_load} more bytes."); - let mut formatted_asm = format!("{}{}", top.format_prefix, top.format_postfix); + let mut formatted_asm = String::from(top.format_prefix); + let mut param = None; if num_bytes_to_load == 1 { bytes.push(data[current_data_position as usize + 1]); - formatted_asm = format!("{}{:02x}", formatted_asm, bytes[1]); + formatted_asm = format!("{}{:02x}{}", formatted_asm, bytes[1], top.format_postfix); }; if num_bytes_to_load == 2 { bytes.push(data[current_data_position as usize + 1]); bytes.push(data[current_data_position as usize + 2]); // 16 bit parameter. - let param = ((bytes[2] as u16) << 8) | bytes[1] as u16; - formatted_asm = format!("{} ${:04x}", formatted_asm, param); + param = Some(((bytes[2] as u16) << 8) | bytes[1] as u16); + formatted_asm = format!("{}{:04x}{}", formatted_asm, param.unwrap(), top.format_postfix); }; // figure out how long the instruction is and read that much more data lines.insert(current_data_position, DecompiledLine { offset: current_data_position, - text: formatted_asm, + text: String::from(formatted_asm), label: None, bytes, }); @@ -140,9 +143,12 @@ fn main() { println!("Loaded {}b", loaded_data.len()); // ...load the array to the WorkingProgram structure... let result = decompile(&loaded_data); + let mut output_file = File::create(opts.output).unwrap(); // ...reap the decompiled code. for (_, line) in &result { - println!("{:width$}; {:?}", line.text,line.bytes, width=30 ); + let line =format!("{:width$}; {:?}", line.text,line.bytes, width=30 ); + println!("{}", line); + writeln!(output_file, "{}", line).expect("cant write output file. you picked the red snapper."); } } diff --git a/core/src/instruction_table.rs b/core/src/instruction_table.rs index bca036f..c9754bf 100644 --- a/core/src/instruction_table.rs +++ b/core/src/instruction_table.rs @@ -112,7 +112,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::Immediate, length: 2, cycles: 2, - format_prefix: "TBD", + format_prefix: "AND #$", format_postfix: "", }); table[ISA_OP_AND_Z as usize] = Some(OpInfo { @@ -120,7 +120,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPage, length: 2, cycles: 3, - format_prefix: "TBD", + format_prefix: "AND $", format_postfix: "", }); table[ISA_OP_AND_ZX as usize] = Some(OpInfo { @@ -128,15 +128,15 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPageX, length: 2, cycles: 4, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "AND $", + format_postfix: ",X", }); table[ISA_OP_AND_ABS as usize] = Some(OpInfo { operation: AND, mode: AddressMode::Absolute, length: 3, cycles: 4, - format_prefix: "TBD", + format_prefix: "AND $", format_postfix: "", }); table[ISA_OP_AND_ABSX as usize] = Some(OpInfo { @@ -144,16 +144,16 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::AbsoluteX, length: 3, cycles: 4, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "AND $", + format_postfix: ",X", }); table[ISA_OP_AND_ABSY as usize] = Some(OpInfo { operation: AND, mode: AddressMode::AbsoluteY, length: 3, cycles: 4, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "AND $", + format_postfix: ",Y", }); table[ISA_OP_AND_INDX as usize] = Some(OpInfo { operation: AND, @@ -1122,8 +1122,8 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::IndirectY, length: 2, cycles: 5, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "SBC ($", + format_postfix: "),Y", }); table[ISA_OP_SEC as usize] = Some(OpInfo { @@ -1131,7 +1131,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::Implied, length: 1, cycles: 2, - format_prefix: "TBD", + format_prefix: "SEC", format_postfix: "", }); table[ISA_OP_SED as usize] = Some(OpInfo { @@ -1139,7 +1139,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::Implied, length: 1, cycles: 2, - format_prefix: "TBD", + format_prefix: "SED", format_postfix: "", }); table[ISA_OP_SEI as usize] = Some(OpInfo { @@ -1147,7 +1147,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::Implied, length: 1, cycles: 2, - format_prefix: "TBD", + format_prefix: "SEI", format_postfix: "", }); @@ -1156,7 +1156,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPage, length: 2, cycles: 3, - format_prefix: "TBD", + format_prefix: "STA $", format_postfix: "", }); table[ISA_OP_STA_ZPX as usize] = Some(OpInfo { @@ -1164,15 +1164,15 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPageX, length: 2, cycles: 4, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "STA $", + format_postfix: ",X", }); table[ISA_OP_STA_ABS as usize] = Some(OpInfo { operation: Operation::STA, mode: AddressMode::Absolute, length: 3, cycles: 4, - format_prefix: "TBD", + format_prefix: "STA $", format_postfix: "", }); table[ISA_OP_STA_ABSX as usize] = Some(OpInfo { @@ -1180,32 +1180,32 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::AbsoluteX, length: 3, cycles: 5, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "STA $", + format_postfix: ",X", }); table[ISA_OP_STA_ABSY as usize] = Some(OpInfo { operation: Operation::STA, mode: AddressMode::AbsoluteY, length: 3, cycles: 5, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "STA $", + format_postfix: ",Y", }); table[ISA_OP_STA_INDX as usize] = Some(OpInfo { operation: Operation::STA, mode: AddressMode::IndirectX, length: 2, cycles: 6, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "STA ($", + format_postfix: ",X)", }); table[ISA_OP_STA_INDY as usize] = Some(OpInfo { operation: Operation::STA, mode: AddressMode::IndirectY, length: 2, cycles: 6, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "STA ($", + format_postfix: "),Y", }); table[ISA_OP_STX_ZP as usize] = Some(OpInfo { @@ -1213,7 +1213,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPage, length: 2, cycles: 3, - format_prefix: "TBD", + format_prefix: "STX $", format_postfix: "", }); table[ISA_OP_STX_ZPY as usize] = Some(OpInfo { @@ -1221,7 +1221,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPageY, length: 2, cycles: 4, - format_prefix: "TBD", + format_prefix: "STX", format_postfix: "", }); table[ISA_OP_STX_ABS as usize] = Some(OpInfo { @@ -1229,7 +1229,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::Absolute, length: 3, cycles: 4, - format_prefix: "TBD", + format_prefix: "STX", format_postfix: "", }); @@ -1238,7 +1238,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPage, length: 2, cycles: 3, - format_prefix: "TBD", + format_prefix: "STY $", format_postfix: "", }); table[ISA_OP_STY_ZPX as usize] = Some(OpInfo { @@ -1246,15 +1246,15 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::ZeroPageX, length: 2, cycles: 4, - format_prefix: "TBD", - format_postfix: "", + format_prefix: "STY $", + format_postfix: ",X", }); table[ISA_OP_STY_ABS as usize] = Some(OpInfo { operation: Operation::STY, mode: AddressMode::Absolute, length: 3, cycles: 4, - format_prefix: "TBD", + format_prefix: "STY $", format_postfix: "", }); @@ -1263,7 +1263,7 @@ pub const INSTRUCTION_TABLE: [Option; 256] = { mode: AddressMode::Implied, length: 1, cycles: 2, - format_prefix: "TBD", + format_prefix: "TAX", format_postfix: "", }); table[ISA_OP_TAY as usize] = Some(OpInfo { diff --git a/resources/test/instructions.asm b/resources/test/instructions.asm new file mode 100644 index 0000000..9867705 --- /dev/null +++ b/resources/test/instructions.asm @@ -0,0 +1,17 @@ +; Test of instructions for the decompiler +; +; This file is intended to be assembled and then +; used as an input to a test that decompiles the +; binary back to the text version of the instructions + ADC #$ab ; ADC Immediate + ADC $ab ; ADC ZeroPage + ADC $ab,X ; ADC ZeroPageX + ADC $abcd ; ADC Absolute + ADC $abcd,X; ADC AbsoluteX + ADC $abcd,Y; ADC AbsoluteY + ADC ($ab,X); ADC IndirectX + ADC ($ab),Y; ADC IndirectY + + AND #$ab ; AND Immediate + AND $ab ; AND ZeroPage + AND $ab,X ; AND ZeroPageX