Skip to main content

working_roms/
working_roms.rs

1use std::fs;
2use std::path::Path;
3use std::process::Command;
4use uxn_tal::{Assembler, AssemblerError};
5fn enumerate_tal_files(dir: &str) -> Vec<String> {
6    let mut files = Vec::new();
7    if let Ok(entries) = fs::read_dir(dir) {
8        for entry in entries.flatten() {
9            let path = entry.path();
10            if path.extension().is_some_and(|ext| ext == "tal") {
11                if let Some(path_str) = path.to_str() {
12                    files.push(path_str.to_owned());
13                }
14            }
15        }
16    }
17    files
18}
19fn main() -> Result<(), AssemblerError> {
20    std::env::set_current_dir("tal")?;
21    let tal_files = enumerate_tal_files(".");
22    for tal_file in tal_files {
23        println!("Processing TAL file: {}", tal_file);
24        let tal_file_name = Path::new(&tal_file)
25            .file_name()
26            .unwrap()
27            .to_str()
28            .unwrap()
29            .to_owned();
30        let tal_source = std::fs::read_to_string(&tal_file)?;
31
32        let mut assembler = Assembler::new();
33        match assembler.assemble(&tal_source, Some(tal_file.clone())) {
34            Ok(rom) => {
35                let rom_path = format!("{}.rom", tal_file_name);
36                std::fs::write(&rom_path, &rom)?;
37                println!("Successfully assembled {} bytes to {}", rom.len(), rom_path);
38
39                // Run WSL uxnasm on the TAL source file
40                let wsl_rom_path = format!("{}_wsl.rom", tal_file);
41                let wsl_file_name = Path::new(&wsl_rom_path)
42                    .file_name()
43                    .unwrap()
44                    .to_str()
45                    .unwrap()
46                    .to_owned();
47                println!(
48                    "Running command: wsl uxnasm {} {}",
49                    tal_file_name, wsl_file_name
50                );
51                let status = Command::new("wsl")
52                    .arg("uxnasm")
53                    .arg(&tal_file_name)
54                    .arg(&wsl_file_name)
55                    .status()?;
56
57                if status.success() {
58                    println!("WSL uxnasm succeeded, output at {:?}", wsl_rom_path);
59                } else {
60                    eprintln!("WSL uxnasm failed with status: {}", status);
61                }
62
63                // Compare the two ROM files byte-by-byte
64                // let rom_path = format!("tal\\{}.rom", tal_file_name);
65
66                let rust_rom = std::fs::read(&rom_path).unwrap_or_default();
67                let wsl_rom = std::fs::read(&wsl_rom_path).unwrap_or_default();
68
69                if rust_rom == wsl_rom {
70                    println!("ROM outputs are identical for {}", tal_file);
71                } else {
72                    println!("ROM outputs differ for {}", tal_file);
73                }
74
75                // Run both ROMs using uxncli via WSL and compare their outputs
76                let run_rom = |rom_path: &str| -> Result<String, std::io::Error> {
77                    let output = Command::new("wsl").arg("uxncli").arg(rom_path).output()?;
78                    Ok(String::from_utf8_lossy(&output.stdout).to_string())
79                };
80
81                let rust_output = run_rom(&rom_path)?;
82                let wsl_output = run_rom(&wsl_rom_path)?;
83
84                println!("--- Rust ROM output {}---\n{}", rust_output, rom_path);
85                println!("--- WSL ROM output {}---\n{}", wsl_output, wsl_rom_path);
86
87                if rust_output == wsl_output {
88                    println!("ROM runtime outputs are identical for {}", tal_file);
89                } else {
90                    println!("ROM runtime outputs differ for {}", tal_file);
91                }
92
93                // Run both ROMs using uxndis via WSL and compare their outputs
94                let run_dis = |rom_path: &str| -> Result<String, std::io::Error> {
95                    let output = Command::new("wsl")
96                        .arg("uxncli")
97                        .arg("uxndis.rom")
98                        .arg("--")
99                        .arg(rom_path)
100                        .output()?;
101                    println!("Running command: wsl uxncli uxndis.rom -- {}", rom_path);
102                    Ok(String::from_utf8_lossy(&output.stdout).to_string())
103                };
104
105                let rust_dis_output = run_dis(&rom_path)?;
106                let wsl_dis_output = run_dis(&wsl_rom_path)?;
107
108                println!("--- Rust ROM disassembly ---\n{}", rust_dis_output);
109                println!("--- WSL ROM disassembly ---\n{}", wsl_dis_output);
110
111                if rust_dis_output == wsl_dis_output {
112                    println!("ROM disassembly outputs are identical for {}", tal_file);
113                } else {
114                    println!("ROM disassembly outputs differ for {}", tal_file);
115                }
116            }
117            Err(e) => {
118                eprintln!("Assembly failed for {}: {}", tal_file, e);
119            }
120        }
121    }
122    let cwd = std::env::current_dir()?;
123    let parent_cwd = cwd.parent().unwrap_or(&cwd);
124    println!("Changing back to parent directory: {:?}", parent_cwd);
125    std::env::set_current_dir(parent_cwd)?;
126    //     ( Simple working hello world )
127    //     #48 #18 DEO  ( H )
128    //     #65 #18 DEO  ( e )
129    //     #6c #18 DEO  ( l )
130    //     #6c #18 DEO  ( l )
131    //     #6f #18 DEO  ( o )
132    //     #20 #18 DEO  ( space )
133    //     #57 #18 DEO  ( W )
134    //     #6f #18 DEO  ( o )
135    //     #72 #18 DEO  ( r )
136    //     #6c #18 DEO  ( l )
137    //     #64 #18 DEO  ( d )
138    //     #21 #18 DEO  ( ! )
139    //     #0a #18 DEO  ( newline )
140    //     BRK
141    // "#;
142
143    // let mut assembler = Assembler::new();
144    // match assembler.assemble(tal_source, Some("working_hello.rs".to_owned())) {
145    //     Ok(rom) => {
146    //         println!("Successfully assembled {} bytes", rom.len());
147
148    //         // Save to file
149    //         std::fs::write("working_hello.rom", &rom)?;
150    //         println!("ROM saved to working_hello.rom");
151    //     }
152    //     Err(e) => {
153    //         eprintln!("Assembly failed: {}", e);
154    //     }
155    // }
156    // // Write the TAL source to a temporary file
157    // let temp_path = "working_hello.tal";
158    // std::fs::write(&temp_path, tal_source)?;
159    // println!("TAL source written to {:?}", temp_path);
160
161    // // Run WSL uxnasm on the TAL source file
162    // let output_path = "working_hello_wsl.rom";
163    // let status = Command::new("wsl")
164    //     .arg("uxnasm")
165    //     .arg(&temp_path)
166    //     .arg(&output_path)
167    //     .status()?;
168
169    // if status.success() {
170    //     println!("WSL uxnasm succeeded, output at {:?}", output_path);
171    // } else {
172    //     eprintln!("WSL uxnasm failed with status: {}", status);
173    // }
174
175    // // Compare the two ROM files byte-by-byte
176    // let rust_rom = std::fs::read("working_hello.rom")?;
177    // let wsl_rom = std::fs::read(&output_path)?;
178
179    // if rust_rom == wsl_rom {
180    //     println!("ROM outputs are identical.");
181    // } else {
182    //     println!("ROM outputs differ:");
183    //     let min_len = rust_rom.len().min(wsl_rom.len());
184    //     for i in 0..min_len {
185    //         if rust_rom[i] == wsl_rom[i] {
186    //         println!("Byte {}: equal ({:02x})", i, rust_rom[i]);
187    //         } else {
188    //         println!(
189    //             "Byte {}: Rust = {:02x}, WSL = {:02x}",
190    //             i, rust_rom[i], wsl_rom[i]
191    //         );
192    //         }
193    //     }
194    //     let min_len = rust_rom.len().min(wsl_rom.len());
195    //     for i in 0..min_len {
196    //         if rust_rom[i] != wsl_rom[i] {
197    //             println!(
198    //                 "Byte {}: Rust = {:02x}, WSL = {:02x}",
199    //                 i, rust_rom[i], wsl_rom[i]
200    //             );
201    //         }
202    //     }
203    //     if rust_rom.len() != wsl_rom.len() {
204    //         println!(
205    //         "ROM sizes differ: Rust = {}, WSL = {}",
206    //         rust_rom.len(),
207    //         wsl_rom.len()
208    //         );
209    //         if rust_rom.len() > wsl_rom.len() {
210    //         println!("Extra bytes in Rust ROM:");
211    //         for i in wsl_rom.len()..rust_rom.len() {
212    //             println!("Byte {}: {:02x}", i, rust_rom[i]);
213    //         }
214    //         } else {
215    //         println!("Extra bytes in WSL ROM:");
216    //         for i in rust_rom.len()..wsl_rom.len() {
217    //             println!("Byte {}: {:02x}", i, wsl_rom[i]);
218    //         }
219    //         }
220    //     }
221    // }
222
223    // // Run both ROMs using uxncli via WSL and compare their outputs
224    // let run_rom = |rom_path: &str| -> Result<String, std::io::Error> {
225    //     let output = Command::new("wsl")
226    //         .arg("uxncli")
227    //         .arg(rom_path)
228    //         .output()?;
229    //     Ok(String::from_utf8_lossy(&output.stdout).to_string())
230    // };
231
232    // let rust_output = run_rom("working_hello.rom")?;
233    // let wsl_output = run_rom(&output_path)?;
234
235    // println!("--- Rust ROM output ---\n{}", rust_output);
236    // println!("--- WSL ROM output ---\n{}", wsl_output);
237
238    // if rust_output == wsl_output {
239    //     println!("ROM runtime outputs are identical.");
240    // } else {
241    //     println!("ROM runtime outputs differ.");
242    // }
243    Ok(())
244}