Krolyxon
Commit 6efefdd

Branches

Tags

Refs →

bench51cratesbench51-tuisrcmain.rs

92 lines · 2.5 KB · Rust

1mod ui;
2
3use std::path::PathBuf;
4use std::process::ExitCode;
5
6use bench51_core::asm;
7use clap::Parser;
8
9/// Intel 8051 assembler, simulator and TUI debugger.
10#[derive(Parser, Debug)]
11#[command(name = "bench51", version, about)]
12struct Args {
13 /// Assembly source (.asm) or Intel HEX (.hex) file to open.
14 file: Option<PathBuf>,
15
16 /// Assemble FILE without starting the TUI, writing the Intel HEX file.
17 #[arg(short, long, requires = "file")]
18 assemble: bool,
19
20 /// Output HEX path (default: FILE with a .hex extension).
21 #[arg(short, long, requires = "assemble")]
22 output: Option<PathBuf>,
23
24 /// Also write a listing to this path (default: FILE with a .lst extension).
25 #[arg(long, requires = "assemble")]
26 lst: Option<PathBuf>,
27
28 /// Oscillator frequency in MHz, used to show elapsed time.
29 #[arg(long, default_value_t = 11.0592)]
30 clock: f64,
31}
32
33fn assemble_file(args: &Args) -> ExitCode {
34 let path = args.file.as_ref().unwrap();
35 let source = match std::fs::read_to_string(path) {
36 Ok(s) => s,
37 Err(e) => {
38 eprintln!("error: cannot read {}: {e}", path.display());
39 return ExitCode::FAILURE;
40 }
41 };
42 let out = asm::assemble(&source);
43 let lst = args
44 .lst
45 .clone()
46 .unwrap_or_else(|| path.with_extension("lst"));
47 if let Err(e) = std::fs::write(&lst, out.listing(&source)) {
48 eprintln!("error: cannot write {}: {e}", lst.display());
49 }
50 if !out.ok() {
51 for d in &out.diagnostics {
52 eprintln!(
53 "{}:{}:{}: error: {}",
54 path.display(),
55 d.line + 1,
56 d.col + 1,
57 d.msg
58 );
59 }
60 eprintln!("{} error(s); see {}", out.diagnostics.len(), lst.display());
61 return ExitCode::FAILURE;
62 }
63 let hex = args
64 .output
65 .clone()
66 .unwrap_or_else(|| path.with_extension("hex"));
67 if let Err(e) = std::fs::write(&hex, out.intel_hex()) {
68 eprintln!("error: cannot write {}: {e}", hex.display());
69 return ExitCode::FAILURE;
70 }
71 println!(
72 "{} bytes -> {}, listing -> {}",
73 out.code_size(),
74 hex.display(),
75 lst.display()
76 );
77 ExitCode::SUCCESS
78}
79
80fn main() -> ExitCode {
81 let args = Args::parse();
82 if args.assemble {
83 return assemble_file(&args);
84 }
85 match ui::run(args.file, args.clock) {
86 Ok(()) => ExitCode::SUCCESS,
87 Err(e) => {
88 eprintln!("error: {e}");
89 ExitCode::FAILURE
90 }
91 }
92}