1use std::{env, fs, process};
4
5use romulan::amd::{
6 Rom,
7 directory::Directory,
8};
9
10fn print_directory(data: &[u8], address: u64, indent: usize) {
11 let mut padding = String::with_capacity(indent);
13 for i in 0..indent {
14 padding.push(' ');
15 }
16 let offset = (address & 0xFFFFFF) as usize;
17 match Directory::new(&data[offset..]) {
18 Ok(Directory::Bios(directory)) => {
19 println!("{}* {:#X}: BIOS Directory", padding, address);
20 for entry in directory.entries() {
21 println!("{} * Type {:02X} Region {:02X} Flags {:02X} SubProg {:02X} Size {:08X} Source {:08X} Dest {:016X}: {}", padding, entry.kind, entry.region_kind, entry.flags, entry.sub_program, entry.size, entry.source, entry.destination, entry.description());
22 if entry.kind == 0x70 {
23 print_directory(data, entry.source, indent + 4);
24 }
25 }
26 },
27 Ok(Directory::BiosCombo(combo)) => {
28 println!("{}* {:#X}: BIOS Combo Directory", padding, address);
29 for entry in combo.entries() {
30 println!("{} * {:X?}", padding, entry);
31 print_directory(data, entry.directory, indent + 4);
32 }
33 },
34 Ok(Directory::BiosLevel2(directory)) => {
35 println!("{}* {:#X}: BIOS Level 2 Directory", padding, address);
36 for entry in directory.entries() {
37 println!("{} * Type {:02X} Region {:02X} Flags {:02X} SubProg {:02X} Size {:08X} Source {:08X} Dest {:016X}: {}", padding, entry.kind, entry.region_kind, entry.flags, entry.sub_program, entry.size, entry.source, entry.destination, entry.description());
38 }
39 },
40 Ok(Directory::Psp(directory)) => {
41 println!("{}* {:#X}: PSP Directory", padding, address);
42 for entry in directory.entries() {
43 println!("{} * Type {:02X} SubProg {:02X} Size {:08X} Value {:08X}: {}", padding, entry.kind, entry.sub_program, entry.size, entry.value, entry.description());
44 if entry.kind == 0x40 {
45 print_directory(data, entry.value, indent + 4);
46 }
47 }
48 },
49 Ok(Directory::PspCombo(combo)) => {
50 println!("{}* {:#X}: PSP Combo Directory", padding, address);
51 for entry in combo.entries() {
52 println!("{} * {:X?}", padding, entry);
53 print_directory(data, entry.directory, indent + 4);
54 }
55 },
56 Ok(Directory::PspLevel2(directory)) => {
57 println!("{}* {:#X}: PSP Level 2 Directory", padding, address);
58 for entry in directory.entries() {
59 println!("{} * Type {:02X} SubProg {:02X} Size {:08X} Value {:08X}: {}", padding, entry.kind, entry.sub_program, entry.size, entry.value, entry.description());
60 }
61 },
62 Err(err) => {
63 println!("{}* {:#X}: failed to load directory: {}", padding, address, err);
64 }
65 }
66}
67
68fn main() {
69 let file = if let Some(file) = env::args().nth(1) {
70 file
71 } else {
72 eprintln!("used_regions <file>");
73 process::exit(1);
74 };
75
76 let data = fs::read(file).unwrap();
77
78 let rom = Rom::new(&data).unwrap();
79
80 let signature = rom.signature();
81 println!("{:#X?}", signature);
82
83 print_directory(&data, signature.psp as u64, 0);
84 print_directory(&data, signature.bios as u64, 0);
85}