evolve egui interface
move more control back up to the ComputerManager
This commit is contained in:
@@ -6,3 +6,5 @@ edition = "2021"
|
||||
[dependencies]
|
||||
gemma = { path = "../gemma" }
|
||||
clap = { version = "4.5.20", features = ["derive"] }
|
||||
pest = "2.7.14"
|
||||
pest_derive = "2.7.14"
|
||||
+73
-45
@@ -1,59 +1,87 @@
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::BufRead;
|
||||
use std::path::Path;
|
||||
use clap::Parser;
|
||||
use gemma::chip8::instructions::Chip8CpuInstructions;
|
||||
|
||||
/// Ch8Asm
|
||||
/// Converts well formed CH8ASM.
|
||||
/// no variables.
|
||||
/// no labels.
|
||||
/// nothing fun.
|
||||
|
||||
pub struct Assembler {}
|
||||
|
||||
impl Assembler {
|
||||
|
||||
}
|
||||
use std::fs;
|
||||
// Ch8Asm
|
||||
// Converts well formed CH8ASM.
|
||||
// no variables.
|
||||
// no labels.
|
||||
// nothing fun.
|
||||
use pest::Parser;
|
||||
use pest_derive::Parser;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
struct AssemblerApp {
|
||||
#[arg(short)]
|
||||
input_file: Box<Path>,
|
||||
}
|
||||
#[grammar = "chip8_asm.pest"]
|
||||
pub struct Chip8AsmParser;
|
||||
|
||||
fn main() {
|
||||
println!("Taxation is Theft");
|
||||
|
||||
let result = AssemblerApp::parse();
|
||||
|
||||
let mut assembled_code: Vec<u8> = vec![];
|
||||
|
||||
// println!("Preparing to assemble {}", result.input_file.file_name());
|
||||
let unparsed = fs::read_to_string("resources/test/gemma_disassembler_1_chip_logo_ch8_asm.asc").expect("Unable to read input");
|
||||
|
||||
let path = Path::new(result.input_file);
|
||||
let file = Chip8AsmParser::parse(Rule::file, &unparsed).expect("Unable to parse. Try again.")
|
||||
.next().unwrap();
|
||||
|
||||
// Open the file in read-only mode
|
||||
let file = File::open(&path)?;
|
||||
|
||||
// Use a buffered reader for efficient reading
|
||||
let reader = io::BufReader::new(file);
|
||||
|
||||
// Read the file line by line
|
||||
for line in reader.lines() {
|
||||
// Get the line, handling possible errors
|
||||
let line = line?;
|
||||
|
||||
// Split the line by ';' and collect parts into a vector
|
||||
let parts: Vec<&str> = line.split(';').collect();
|
||||
|
||||
// Print each part or process it as needed
|
||||
for part in &parts {
|
||||
println!("{}", part);
|
||||
for record in file.into_inner() {
|
||||
match record.as_rule() {
|
||||
Rule::instruction => {
|
||||
println!("INSTRUCTION = {:?}", record.into_inner().flatten())
|
||||
}
|
||||
_ => {
|
||||
println!("UNHANDLED PART.");
|
||||
}
|
||||
}
|
||||
}
|
||||
// read the line split by a semicolon
|
||||
}
|
||||
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn bits_all_parse() {
|
||||
println!("PARSED: {:?}",
|
||||
Chip8AsmParser::parse(Rule::instruction, "CLS")
|
||||
);
|
||||
println!("PARSED: {:?}",
|
||||
Chip8AsmParser::parse(Rule::parameter, "0x01")
|
||||
);
|
||||
let parsed = Chip8AsmParser::parse(Rule::comment, "; comment").unwrap();
|
||||
for i in parsed {
|
||||
println!("PARSED COMMENT -> {:?}", i);
|
||||
}
|
||||
|
||||
let parsed =
|
||||
Chip8AsmParser::parse(Rule::record, "CLS ; comment").unwrap();
|
||||
for i in parsed {
|
||||
println!("RULE PAIR THING: {:?}", i);
|
||||
}
|
||||
|
||||
let parsed = Chip8AsmParser::parse(Rule::record, "ADDI 0x01 ; comment");
|
||||
for i in parsed {
|
||||
println!("RULE PAIR THING: {:?}", i);
|
||||
}
|
||||
|
||||
|
||||
let parsed = Chip8AsmParser::parse(Rule::record, "ADDI ; comment");
|
||||
for i in parsed {
|
||||
println!("RULE PAIR THING: {:?}", i);
|
||||
}
|
||||
|
||||
|
||||
println!("PARSED: {:?}",
|
||||
Chip8AsmParser::parse(Rule::record, "ADD 0x01 0x02 ; Comment")
|
||||
);
|
||||
|
||||
println!("PARSED: {:?}",
|
||||
Chip8AsmParser::parse(Rule::record, "ADD ADD ADD")
|
||||
);
|
||||
|
||||
println!("PARSED: {:?}",
|
||||
Chip8AsmParser::parse(Rule::record, "ADD 0x01 0x02 ; Comment")
|
||||
);
|
||||
|
||||
println!("PARSED: {:?}",
|
||||
Chip8AsmParser::parse(Rule::record, "ADD 0x01 0x02 ; Comment")
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,41 @@ struct DisassemblerApp {
|
||||
struct Disassembler {}
|
||||
impl Disassembler {
|
||||
pub fn disassemble(from_data: Vec<u8>) -> String {
|
||||
String::new()
|
||||
let mut working_instruction: u16 = 0x0000;
|
||||
|
||||
// read the input data and loop through it byte by byte.
|
||||
let mut output_string = String::new();
|
||||
|
||||
for (offset, byte) in from_data.iter().enumerate() {
|
||||
working_instruction = (working_instruction << 8) | (*byte as u16);
|
||||
if offset % 2 != 0 {
|
||||
let decoded = Chip8CpuInstructions::decode(working_instruction);
|
||||
let decoded_string = decoded.to_string();
|
||||
let mut current_parts = String::new();
|
||||
|
||||
match decoded {
|
||||
XXXXERRORINSTRUCTION => {
|
||||
current_parts = format!("DW 0x{:04x}", working_instruction);
|
||||
}
|
||||
_ => {
|
||||
current_parts = format!("{}", decoded);
|
||||
}
|
||||
};
|
||||
|
||||
let target_length: i32 = 25;
|
||||
let spacing_length = target_length.saturating_sub(current_parts.len() as i32);
|
||||
|
||||
// now add the rest after the string
|
||||
let x = spacing_length as usize;
|
||||
current_parts = format!("{}{:<x$}; Bytes [0x{:04x}] offset [0x{:04x}]\n", current_parts, " ", working_instruction, offset -1);
|
||||
// println!("SHOULD OUTPUT: [{current_parts}]");
|
||||
output_string = output_string.to_string() + &*current_parts.to_string();
|
||||
|
||||
working_instruction = 0x0000;
|
||||
}
|
||||
}
|
||||
|
||||
output_string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,51 +60,22 @@ fn main() {
|
||||
println!("Taxation is Theft");
|
||||
let result = DisassemblerApp::parse();
|
||||
println!("PREPARING TO DISASSEMBLE {:?}", result.input_file.file_name());
|
||||
// let target_file =
|
||||
|
||||
|
||||
let source_file = result.input_file.to_str().unwrap();
|
||||
let mut working_instruction: u16 = 0x0000;
|
||||
let decompiled_program = Disassembler::disassemble(
|
||||
std::fs::read(source_file).unwrap()
|
||||
);
|
||||
|
||||
// read the input file and loop through it byte by byte.
|
||||
|
||||
let mut output_string = String::new();
|
||||
|
||||
for (offset, byte) in std::fs::read(source_file).unwrap().iter().enumerate() {
|
||||
working_instruction = (working_instruction << 8) | (*byte as u16);
|
||||
if offset % 2 != 0 {
|
||||
let decoded = Chip8CpuInstructions::decode(working_instruction);
|
||||
let decoded_string = decoded.to_string();
|
||||
let mut current_parts = String::new();
|
||||
|
||||
match decoded {
|
||||
XXXXERRORINSTRUCTION => {
|
||||
current_parts = format!("DW 0x{:04x}", working_instruction);
|
||||
}
|
||||
_ => {
|
||||
current_parts = format!("{}", decoded);
|
||||
}
|
||||
};
|
||||
|
||||
let target_length: i32 = 25;
|
||||
let spacing_length = target_length.saturating_sub(current_parts.len() as i32);
|
||||
|
||||
// now add the rest after the string
|
||||
let x = spacing_length as usize;
|
||||
current_parts = format!("{}{:<x$}; Bytes [0x{:04x}] offset [0x{:04x}]\n", current_parts, " ", working_instruction, offset -1);
|
||||
// println!("SHOULD OUTPUT: [{current_parts}]");
|
||||
output_string = output_string.to_string() + &*current_parts.to_string();
|
||||
|
||||
working_instruction = 0x0000;
|
||||
}
|
||||
}
|
||||
|
||||
match result.output_file {
|
||||
None => {
|
||||
println!("Output to console.");
|
||||
println!("OS: \n\n{}", output_string);
|
||||
println!("OS: \n\n{}", decompiled_program);
|
||||
}
|
||||
Some(target) => {
|
||||
println!("Output to {:?}", target);
|
||||
std::fs::write(target, output_string).unwrap();
|
||||
std::fs::write(target, decompiled_program).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
WHITESPACE = _{ " " }
|
||||
instruction = { ASCII_ALPHA+ }
|
||||
parameter = { "0X" ~ ASCII_HEX_DIGIT+ }
|
||||
comment = { ";" ~ WHITESPACE* ~ ASCII* }
|
||||
parameters = { parameter ~ (WHITESPACE* ~ "," ~ WHITESPACE* ~ parameter)* }
|
||||
record = { instruction ~ WHITESPACE ~ parameters? ~ WHITESPACE* ~ comment? }
|
||||
file = { SOI ~ (record ~ ("\r\n" | "\n"))* ~ EOI }
|
||||
Reference in New Issue
Block a user