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}