Skip to content

Commit

Permalink
When writing a value to IO 0 to force emulator exit, the exit status …
Browse files Browse the repository at this point in the history
…code will be taken from the value written
  • Loading branch information
tomm committed Dec 1, 2024
1 parent 959f695 commit 8f3c84b
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 13 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
members = ["agon-light-emulator-debugger"]

[workspace.package]
version = "0.9.74"
version = "0.9.75"
edition = "2021"
authors = ["Tom Morton <[email protected]>"]
license = "GPL-3.0"
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ emulator from), type `help` for instructions on the use of the debugger.
Some IO addresses unused by the EZ80F92 are used by the emulator for debugging
purposes:

| IO addresses | Function |
| ------------- | ------------------------------------- |
| 0x00 | Terminate emulator |
| 0x10-0x1f | Breakpoint (requires --debugger) |
| 0x20-0x2f | Print CPU state (requires --debugger) |
| IO addresses | Function |
| ------------- | ------------------------------------------------------------------ |
| 0x00 | Terminate emulator (exit code will be the value written to IO 0x0) |
| 0x10-0x1f | Breakpoint (requires --debugger) |
| 0x20-0x2f | Print CPU state (requires --debugger) |

These functions are activated by write (not read), and the upper 8-bits of the
IO address are ignored. ie:
Expand Down
11 changes: 10 additions & 1 deletion agon-ez80-emulator/src/agon_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct AgonMachine {
paused: Arc<std::sync::atomic::AtomicBool>,
soft_reset: Arc<std::sync::atomic::AtomicBool>,
emulator_shutdown: Arc<std::sync::atomic::AtomicBool>,
exit_status: Arc<std::sync::atomic::AtomicI32>,
clockspeed_hz: u64,
prt_timers: [prt_timer::PrtTimer; 6],
gpios: Arc<Mutex<gpio::GpioSet>>,
Expand Down Expand Up @@ -464,10 +465,16 @@ impl Machine for AgonMachine {
// Discard high byte of address, so we can use `out (n),a`
// for debugging
if address & 0xff == 0 {
println!("Emulator shutdown triggered by write to IO 0x0");
println!(
"Emulator shutdown triggered by writing 0x{:x} IO 0x0",
value
);
self.exit_status
.store(value as i32, std::sync::atomic::Ordering::Relaxed);
self.emulator_shutdown
.store(true, std::sync::atomic::Ordering::Relaxed);
} else {
// the debugger will handle some of these
self.io_unhandled.set(Some(address));
}
}
Expand All @@ -480,6 +487,7 @@ pub struct AgonMachineConfig {
pub uart1_link: Box<dyn uart::SerialLink>,
pub soft_reset: Arc<std::sync::atomic::AtomicBool>,
pub emulator_shutdown: Arc<std::sync::atomic::AtomicBool>,
pub exit_status: Arc<std::sync::atomic::AtomicI32>,
pub paused: Arc<std::sync::atomic::AtomicBool>,
pub clockspeed_hz: u64,
pub ram_init: RamInit,
Expand All @@ -505,6 +513,7 @@ impl AgonMachine {
mos_current_dir: MosPath(std::path::PathBuf::new()),
soft_reset: config.soft_reset,
emulator_shutdown: config.emulator_shutdown,
exit_status: config.exit_status,
clockspeed_hz: config.clockspeed_hz,
prt_timers: [
prt_timer::PrtTimer::new(),
Expand Down
15 changes: 12 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@ pub fn firmware_paths(
paths
}

pub fn main() -> Result<(), pico_args::Error> {
let args = parse_args()?;
pub fn main() -> () {
let args = match parse_args() {
Ok(a) => a,
Err(e) => {
eprintln!("Error parsing arguments: {}", e);
std::process::exit(-1);
}
};
let vdp_interface = vdp_interface::init(
firmware_paths(args.firmware, args.vdp_dll, false),
args.verbose,
Expand All @@ -71,6 +77,7 @@ pub fn main() -> Result<(), pico_args::Error> {
let ez80_paused = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let emulator_shutdown = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let soft_reset = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let exit_status = std::sync::Arc::new(std::sync::atomic::AtomicI32::new(0));

for breakpoint in &args.breakpoints {
let trigger = Trigger {
Expand Down Expand Up @@ -124,6 +131,7 @@ pub fn main() -> Result<(), pico_args::Error> {
});

let _cpu_thread = {
let _exit_status = exit_status.clone();
let _ez80_paused = ez80_paused.clone();
let _emulator_shutdown = emulator_shutdown.clone();
let soft_reset_ez80 = soft_reset.clone();
Expand Down Expand Up @@ -181,6 +189,7 @@ pub fn main() -> Result<(), pico_args::Error> {
gpios: gpios_,
soft_reset: soft_reset_ez80,
emulator_shutdown: _emulator_shutdown,
exit_status: _exit_status,
paused: _ez80_paused,
clockspeed_hz: if args.unlimited_cpu {
1000_000_000
Expand Down Expand Up @@ -617,7 +626,7 @@ pub fn main() -> Result<(), pico_args::Error> {
}
std::thread::sleep(std::time::Duration::from_millis(200));

Ok(())
std::process::exit(exit_status.load(std::sync::atomic::Ordering::Relaxed))
}

fn calc_int_scale(canvas_size: (u32, u32), agon_size: (u32, u32)) -> (u32, u32) {
Expand Down

0 comments on commit 8f3c84b

Please sign in to comment.