@@ -23,6 +23,7 @@ use log::debug;
2323use serialport:: SerialPort ;
2424use std:: thread;
2525use std:: time:: Duration ;
26+ use std:: io:: { Read , Write } ;
2627
2728/// Delay after writing to serial port
2829const DELAY_WRITE : Duration = Duration :: from_millis ( 20 ) ;
@@ -32,23 +33,23 @@ const DELAY_KEYPRESS: Duration = DELAY_WRITE;
3233pub 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\r y\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