machine_check_avr/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod system;
4mod util;
5
6use clap::Args;
7use machine_check::{Bitvector, BitvectorArray, ExecArgs, ExecError, ExecResult, ExecStats};
8pub use system::machine_module::{ATmega328P, Input, Param, State};
9
10pub use util::read_hex_into_progmem;
11
12/// Execute machine-check-avr as if called from the command line.
13///
14/// The arguments are supplied as if they were entered from the command line.
15pub fn execute(args: impl Iterator<Item = String>) -> ExecResult {
16    let (exec_args, system_args) = machine_check::parse_args::<SystemArgs>(args);
17    execute_with_args(exec_args, system_args)
18}
19
20/// Execute machine-check-avr with given argument structures.
21pub fn execute_with_args(exec_args: ExecArgs, system_args: SystemArgs) -> ExecResult {
22    let hex = match std::fs::read_to_string(system_args.hex_file) {
23        Ok(ok) => ok,
24        Err(err) => {
25            eprintln!("Could not read hex file: {}", err);
26            return ExecResult {
27                result: Err(ExecError::OtherError(String::from(
28                    "Could not read hex file",
29                ))),
30                stats: ExecStats::default(),
31            };
32        }
33    };
34
35    // fill with ones which is a reserved instruction
36    // TODO: keep track of which progmem locations are filled instead
37    let all_ones = Bitvector::new(0xFFFF);
38    let mut progmem = BitvectorArray::new_filled(all_ones);
39
40    read_hex_into_progmem(&mut progmem, &hex);
41
42    let system = ATmega328P { PROGMEM: progmem };
43    machine_check::execute(system, exec_args)
44}
45
46// Arguments for system construction.
47#[derive(Args)]
48pub struct SystemArgs {
49    /// The machine-code program in an Intel Hex file.
50    #[arg(short = 'H', long = "system-hex-file")]
51    pub hex_file: String,
52}