From 6fbde0d537e9b96287c59c0c2485759272cb24c7 Mon Sep 17 00:00:00 2001 From: "Andrew C. Young" Date: Sun, 27 Sep 2026 15:44:38 +0900 Subject: [PATCH] Save serial bridge settings in the workspace and re-enable them on workspace load; command line bridges take precedence. --- docs/src/manual/network/ltoudp.md | 1 + docs/src/manual/ports.md | 6 ++++++ frontend_egui/src/app.rs | 15 ++++++++++++++- frontend_egui/src/workspace.rs | 5 +++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/src/manual/network/ltoudp.md b/docs/src/manual/network/ltoudp.md index 1c6a0254..e3f4d621 100644 --- a/docs/src/manual/network/ltoudp.md +++ b/docs/src/manual/network/ltoudp.md @@ -5,6 +5,7 @@ real Mac hardware through an adapter such as the [TashTalk](https://github.com/l By default, MacOS will use serial port B for LocalTalk. To enable LToUDP, enable the bridge through the 'Ports' -> 'Channel B (printer)' -> 'Enable LocalTalk bridge'. +The bridge setting is saved in the workspace, so it is re-enabled the next time the workspace is loaded. ![LToUDP menu](../../images/ltoudp_menu.png) diff --git a/docs/src/manual/ports.md b/docs/src/manual/ports.md index 2e702a27..33eec2e3 100644 --- a/docs/src/manual/ports.md +++ b/docs/src/manual/ports.md @@ -23,6 +23,12 @@ filename of the virtual serial port for use in your host operating system. On Li and on MacOS `/dev/ttys`. +## Saving bridges in the workspace + +Enabled bridges are saved in the workspace and re-enabled when the workspace is loaded. A PTY bridge gets a new device +filename every time it is enabled. Bridges specified on the command line (`--serial-bridge-a`, `--serial-bridge-b`) +take precedence over those saved in the workspace. + ## Using the built-in terminal ![Terminal](../images/ports_terminal.png) diff --git a/frontend_egui/src/app.rs b/frontend_egui/src/app.rs index 6d0e248a..bc6738b7 100644 --- a/frontend_egui/src/app.rs +++ b/frontend_egui/src/app.rs @@ -1877,7 +1877,7 @@ impl SnowGui { } } - fn draw_serial_bridge_menu(&self, ui: &mut egui::Ui, ch: SccCh) { + fn draw_serial_bridge_menu(&mut self, ui: &mut egui::Ui, ch: SccCh) { let is_enabled = self.emu.is_serial_bridge_enabled(ch); let emu_ready = self.emu.is_initialized(); @@ -1891,6 +1891,7 @@ impl SnowGui { .clicked() { let _ = self.emu.disable_serial_bridge(ch); + self.workspace.serial_bridges[ch as usize] = None; } } else { // Bridge is inactive - show enable options @@ -1902,6 +1903,7 @@ impl SnowGui { .clicked() { let _ = self.emu.enable_serial_bridge(ch, SerialBridgeConfig::Pty); + self.workspace.serial_bridges[ch as usize] = Some(SerialBridgeConfig::Pty); } let port = match ch { @@ -1918,6 +1920,7 @@ impl SnowGui { let _ = self .emu .enable_serial_bridge(ch, SerialBridgeConfig::Tcp(port)); + self.workspace.serial_bridges[ch as usize] = Some(SerialBridgeConfig::Tcp(port)); } if ui @@ -1927,6 +1930,7 @@ impl SnowGui { let _ = self .emu .enable_serial_bridge(ch, SerialBridgeConfig::LocalTalk); + self.workspace.serial_bridges[ch as usize] = Some(SerialBridgeConfig::LocalTalk); } } } @@ -2730,6 +2734,15 @@ impl SnowGui { self.emu .set_eth_link(id, self.workspace.get_ethernet_link_type()); } + + // Bridges given on the command line take precedence over the workspace + for (idx, ch) in [SccCh::A, SccCh::B].into_iter().enumerate() { + if self.pending_serial_bridges[idx].is_none() + && let Some(config) = self.workspace.serial_bridges[idx].clone() + { + let _ = self.emu.enable_serial_bridge(ch, config); + } + } } else { self.emu.deinit(); self.ff_on = false; diff --git a/frontend_egui/src/workspace.rs b/frontend_egui/src/workspace.rs index 98584814..b6935557 100644 --- a/frontend_egui/src/workspace.rs +++ b/frontend_egui/src/workspace.rs @@ -14,6 +14,7 @@ use snow_core::mac::MacModel; #[cfg(feature = "ethernet")] use snow_core::mac::scsi::ethernet::EthernetLinkType; use snow_core::mac::scsi::target::ScsiTargetType; +use snow_core::mac::serial_bridge::SerialBridgeConfig; /// Custom deserializer that skips invalid shader configs instead of failing entirely fn deserialize_shader_configs_lenient<'de, D>( @@ -302,6 +303,9 @@ pub struct Workspace { /// Ethernet link type pub ethernet_link_type: WorkspaceEthernetLinkType, + + /// Serial bridges per SCC channel (index 0 = Channel A, index 1 = Channel B) + pub serial_bridges: [Option; 2], } impl Default for Workspace { @@ -338,6 +342,7 @@ impl Default for Workspace { shader_enabled: false, shader_configs: Vec::new(), ethernet_link_type: WorkspaceEthernetLinkType::default(), + serial_bridges: [None, None], } } }