diff --git a/README.md b/README.md index a3d758d..db80eae 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,29 @@ A small assembler I wrote for use with the microprocessor from the Book "Grundla W. Hoffmann. ## How does it work? -You run the binary with a path to an assembler file like this `cargo run path/to/file.asm`. +You can generate the data and program memory for a program like this: +``` +$ cargo run -- generate examples/add_endless.asm +Data Memory: +0 1 1 0 +0 0 0 0 +0 0 0 0 +0 0 0 0 +Program Memory: +1 4 8 0 +0 0 0 0 +0 0 0 0 +0 0 0 0 +And that's your program! + +``` +Alternatively you can simulate an asm program for n clock cycles like this: +``` +$ cargo run -- simulate examples/add_endless.asm 4 +``` ## Syntax? -You can find some syntax examples in `examples/` +You can find some syntax examples for the assembler in `examples/` ## Limitations Note that since this microprocessor is only a 4 bit microporcessor we cannot possibly have programs with more than 16 diff --git a/src/html.rs b/src/html.rs new file mode 100644 index 0000000..056032c --- /dev/null +++ b/src/html.rs @@ -0,0 +1,31 @@ +use crate::simulate::State; +use std::fmt::Write; + +static TABLE_HEADER: &str = " + + + + + + + + + + + + + + +\n"; + +pub fn html_state_table(states: Vec) -> String { + let mut result = String::from(TABLE_HEADER); + result.push_str("\n"); + for state in states.iter() { + write!(result, "{}", state).unwrap(); + } + + result.push_str("\n
SchrittclkPC
AddressbusDatenbusIRDRASRBei Befehlen, die aus dem Speicher laden
bzw. in Speicher schreiben (LDA n, ADD n, STA n)
"); + + result +} diff --git a/src/main.rs b/src/main.rs index 86bd97a..fb7035e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,9 +10,12 @@ mod asm; mod generate; mod parse; mod simulate; +mod html; use generate::generate_binary; use parse::{parse_asm, AsmParser}; +use html::html_state_table; + fn main() { let sub_cmd = env::args().nth(1); @@ -41,7 +44,8 @@ fn main() { else if sub_cmd == "simulate" { if let Some(steps) = steps { let states = simulate::simulate(instructions, steps.parse::().unwrap()); - println!("{:#?}", states); + //println!("{:#?}", states); + println!("{}", html_state_table(states)); } } } diff --git a/src/simulate.rs b/src/simulate.rs index 979dad7..14aa28d 100644 --- a/src/simulate.rs +++ b/src/simulate.rs @@ -3,6 +3,7 @@ use crate::asm::*; use crate::generate::generate_binary; use std::collections::HashMap; +use std::fmt; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct StateRegister { @@ -31,6 +32,29 @@ pub struct State { opcode_info: Option } + +impl fmt::Display for State { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "")?; + writeln!(f, "{}", self.step)?; + writeln!(f, "{}", self.clk as u8)?; + writeln!(f, "{}", self.pc)?; + writeln!(f, "{}", self.addr_bus)?; + writeln!(f, "{}", self.data_bus)?; + writeln!(f, "{}", self.ir)?; + writeln!(f, "{}", self.dr)?; + writeln!(f, "{}", self.akku)?; + writeln!(f, "C: {}, Z: {}, N: {}", self.sr.carry as u8, self.sr.zero as u8, self.sr.negative as u8)?; + if let Some(opcode_info) = self.opcode_info { + writeln!(f, "addr: {}, val: {}", opcode_info.addr, opcode_info.content)?; + } else { + writeln!(f, "")?; + } + writeln!(f, "") + } +} + + pub fn simulate<'a>(instructions: Vec>, max_steps: usize) -> Vec { let mut data_memory = generate_binary(instructions.clone()).data_memory; @@ -38,13 +62,13 @@ pub fn simulate<'a>(instructions: Vec>, max_steps: usize) -> Vec let mut states: Vec = Vec::new(); let mut step: usize = 0; - let mut clk: bool = false; - let mut pc: u8 = 0; - let mut addr_bus: u8 = 0; - let mut data_bus: u8 = 0; + let mut clk: bool; + let mut pc: u8; + let mut addr_bus: u8; + let mut data_bus: u8; let mut ir : u8 = 0; let mut dr : u8 = 0; - let mut akku : u8 = 0; + let mut akku : u8; let mut sr: StateRegister = StateRegister { carry: false, zero: false, diff --git a/state.html b/state.html new file mode 100644 index 0000000..c1c2897 --- /dev/null +++ b/state.html @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SchrittclkPC
AddressbusDatenbusIRDRASRBei Befehlen, die aus dem Speicher laden
bzw. in Speicher schreiben (LDA n, ADD n, STA n)
00000000C: 0, Z: 0, N: 0
01000100C: 0, Z: 0, N: 0
10111100C: 0, Z: 1, N: 0
11111410C: 0, Z: 1, N: 0
20221411C: 0, Z: 1, N: 0
21211811C: 0, Z: 1, N: 0
30111811C: 0, Z: 0, N: 0
31111411C: 0, Z: 0, N: 0