Skip to content

Commit d3694bf

Browse files
committed
Reduce dependencies
SerialPort -> Read / Write traits
1 parent f9cab20 commit d3694bf

File tree

2 files changed

+26
-24
lines changed

2 files changed

+26
-24
lines changed

src/commands.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ use matrix65::io;
44
use matrix65::serial;
55
use parse_int::parse;
66
use serialport::SerialPort;
7+
use std::io::{Read, Write};
78

8-
pub fn reset(port: &mut Box<dyn SerialPort>, c64: bool) -> Result<(), anyhow::Error> {
9+
pub fn reset<T: Read + Write>(port: &mut T, c64: bool) -> Result<(), anyhow::Error> {
910
serial::reset(port)?;
1011
if c64 {
1112
serial::go64(port)?
1213
};
1314
Ok(())
1415
}
1516

16-
pub fn peek(
17-
port: &mut Box<dyn SerialPort>,
17+
pub fn peek<T: Read + Write>(
18+
port: &mut T,
1819
address: String,
1920
length: usize,
2021
outfile: Option<String>,
@@ -35,11 +36,11 @@ pub fn peek(
3536
Ok(())
3637
}
3738

38-
pub fn poke(
39+
pub fn poke<T: Read + Write>(
3940
file: Option<String>,
4041
value: Option<u8>,
4142
address: String,
42-
port: &mut Box<dyn SerialPort>,
43+
port: &mut T,
4344
) -> Result<(), anyhow::Error> {
4445
let bytes = match file {
4546
Some(f) => matrix65::io::load_bytes(&f)?,

src/lib/serial.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use log::debug;
2323
use serialport::SerialPort;
2424
use std::thread;
2525
use std::time::Duration;
26+
use std::io::{Read, Write};
2627

2728
/// Delay after writing to serial port
2829
const DELAY_WRITE: Duration = Duration::from_millis(20);
@@ -32,23 +33,23 @@ const DELAY_KEYPRESS: Duration = DELAY_WRITE;
3233
pub const DEFAULT_BAUD_RATE: u32 = 2000000;
3334

3435
/// Stop the MEGA65 CPU
35-
pub fn stop_cpu(port: &mut Box<dyn SerialPort>) -> Result<()> {
36+
pub fn stop_cpu(port: &mut dyn Write) -> Result<()> {
3637
port.write_all("t1\r".as_bytes())?;
3738
port.flush()?;
3839
thread::sleep(DELAY_WRITE);
3940
Ok(())
4041
}
4142

4243
/// Start the MEGA65 CPU after being halted
43-
pub fn start_cpu(port: &mut Box<dyn SerialPort>) -> Result<()> {
44+
pub fn start_cpu(port: &mut dyn Write) -> Result<()> {
4445
port.write_all("t0\r".as_bytes())?;
4546
port.flush()?;
4647
thread::sleep(DELAY_WRITE);
4748
Ok(())
4849
}
4950

5051
/// Detect if in C65 mode
51-
pub fn is_c65_mode(port: &mut Box<dyn SerialPort>) -> Result<bool> {
52+
pub fn is_c65_mode<T: Read + Write>(port: &mut T) -> Result<bool> {
5253
let byte = peek(port, 0xffd3030)?;
5354
Ok(byte == 0x64)
5455
}
@@ -80,15 +81,15 @@ pub fn open_port(name: &str, baud_rate: u32) -> Result<Box<dyn SerialPort>> {
8081
}
8182

8283
/// Reset the MEGA65
83-
pub fn reset(port: &mut Box<dyn SerialPort>) -> Result<()> {
84+
pub fn reset(port: &mut dyn Write) -> Result<()> {
8485
debug!("Sending RESET signal");
8586
port.write_all("!\n".as_bytes())?;
8687
thread::sleep(Duration::from_secs(4));
8788
Ok(())
8889
}
8990

9091
/// If not already there, go to C64 mode via key presses
91-
pub fn go64(port: &mut Box<dyn SerialPort>) -> Result<()> {
92+
pub fn go64<T: Read + Write>(port: &mut T) -> Result<()> {
9293
debug!("Sending GO64");
9394
if is_c65_mode(port)? {
9495
type_text(port, "go64\ry\r")?;
@@ -98,15 +99,15 @@ pub fn go64(port: &mut Box<dyn SerialPort>) -> Result<()> {
9899
}
99100

100101
/// If not already there, go to C65 mode via a reset
101-
pub fn go65(port: &mut Box<dyn SerialPort>) -> Result<()> {
102+
pub fn go65<T: Read + Write>(port: &mut T) -> Result<()> {
102103
if !is_c65_mode(port)? {
103104
reset(port)?;
104105
}
105106
Ok(())
106107
}
107108

108109
/// Translate and type a single letter on MEGA65
109-
fn type_key(port: &mut Box<dyn SerialPort>, mut key: char) -> Result<()> {
110+
fn type_key(port: &mut dyn Write, mut key: char) -> Result<()> {
110111
let mut c1: u8 = 0x7f;
111112
let mut c2 = match key {
112113
'!' => {
@@ -232,14 +233,14 @@ fn type_key(port: &mut Box<dyn SerialPort>, mut key: char) -> Result<()> {
232233
}
233234

234235
/// Call this when done typing
235-
fn stop_typing(port: &mut Box<dyn SerialPort>) -> Result<()> {
236+
fn stop_typing(port: &mut dyn Write) -> Result<()> {
236237
port.write_all("sffd3615 7f 7f 7f \n".as_bytes())?;
237238
thread::sleep(DELAY_WRITE);
238239
Ok(())
239240
}
240241

241242
/// Send array of key presses
242-
pub fn type_text(port: &mut Box<dyn SerialPort>, text: &str) -> Result<()> {
243+
pub fn type_text(port: &mut dyn Write, text: &str) -> Result<()> {
243244
// Manually translate user defined escape codes:
244245
// https://stackoverflow.com/questions/72583983/interpreting-escape-characters-in-a-string-read-from-user-input
245246
debug!("Typing text");
@@ -254,7 +255,7 @@ pub fn type_text(port: &mut Box<dyn SerialPort>, text: &str) -> Result<()> {
254255

255256
/// Get MEGA65 info (@todo under construction)
256257
#[allow(dead_code)]
257-
fn mega65_info(port: &mut Box<dyn SerialPort>) -> Result<()> {
258+
fn mega65_info<T: Read + Write>(port: &mut T) -> Result<()> {
258259
debug!("Requesting serial monitor info");
259260
port.write_all("h\n".as_bytes())?;
260261
thread::sleep(DELAY_WRITE);
@@ -273,7 +274,7 @@ fn mega65_info(port: &mut Box<dyn SerialPort>) -> Result<()> {
273274
}
274275

275276
/// Load memory from MEGA65 starting at given address
276-
pub fn read_memory(port: &mut Box<dyn SerialPort>, address: u32, length: usize) -> Result<Vec<u8>> {
277+
pub fn read_memory<T: Read + Write>(port: &mut T, address: u32, length: usize) -> Result<Vec<u8>> {
277278
debug!("Loading {} bytes from 0x{:x}", length, address);
278279
flush_monitor(port)?;
279280
stop_cpu(port)?;
@@ -308,15 +309,15 @@ pub fn read_memory(port: &mut Box<dyn SerialPort>, address: u32, length: usize)
308309
}
309310

310311
/// Read single byte from MEGA65
311-
pub fn peek(port: &mut Box<dyn SerialPort>, address: u32) -> Result<u8> {
312+
pub fn peek<T: Read + Write>(port: &mut T, address: u32) -> Result<u8> {
312313
let bytes = read_memory(port, address, 1)?;
313314
Ok(bytes[0])
314315
}
315316

316317
/// Try to empty the monitor by reading one byte until nothing more can be read
317318
///
318319
/// There must be more elegant ways to do this...
319-
pub fn flush_monitor(port: &mut Box<dyn SerialPort>) -> Result<()> {
320+
pub fn flush_monitor<T: Read + Write>(port: &mut T) -> Result<()> {
320321
port.write_all(&[0x15, b'#', b'\r'])?;
321322
let mut byte = [0u8];
322323
loop {
@@ -330,7 +331,7 @@ pub fn flush_monitor(port: &mut Box<dyn SerialPort>) -> Result<()> {
330331
}
331332

332333
/// Write bytes to MEGA65
333-
pub fn write_memory(port: &mut Box<dyn SerialPort>, address: u16, bytes: &[u8]) -> Result<()> {
334+
pub fn write_memory<T: Read + Write>(port: &mut T, address: u16, bytes: &[u8]) -> Result<()> {
334335
debug!("Writing {} byte(s) to address 0x{:x}", bytes.len(), address);
335336
stop_cpu(port)?;
336337
port.write_all(format!("l{:x} {:x}\r", address, address + bytes.len() as u16).as_bytes())?;
@@ -342,15 +343,15 @@ pub fn write_memory(port: &mut Box<dyn SerialPort>, address: u16, bytes: &[u8])
342343
}
343344

344345
/// Write single byte to MEGA65
345-
pub fn poke(port: &mut Box<dyn SerialPort>, destination: u16, value: u8) -> Result<()> {
346+
pub fn poke<T: Read + Write>(port: &mut T, destination: u16, value: u8) -> Result<()> {
346347
write_memory(port, destination, &[value])
347348
}
348349

349350
/// Transfer to MEGA65 and optionally run PRG
350351
///
351352
/// C64/C65 modes are selected from the load address
352-
pub fn handle_prg_from_bytes(
353-
port: &mut Box<dyn SerialPort>,
353+
pub fn handle_prg_from_bytes<T: Read + Write>(
354+
port: &mut T,
354355
bytes: &[u8],
355356
load_address: LoadAddress,
356357
reset_before_run: bool,
@@ -377,8 +378,8 @@ pub fn handle_prg_from_bytes(
377378
///
378379
/// Here `file` can be a local file or a url. CBM disk images are allowed and
379380
/// C64/C65 modes are detected from load address.
380-
pub fn handle_prg(
381-
port: &mut Box<dyn SerialPort>,
381+
pub fn handle_prg<T: Read + Write>(
382+
port: &mut T,
382383
file: &str,
383384
reset_before_run: bool,
384385
run: bool,

0 commit comments

Comments
 (0)