Understand better how SNES addressing works.
This commit is contained in:
parent
a161d9090e
commit
7a6689efd1
|
@ -1,33 +1,44 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read};
|
use std::io::{BufReader, BufRead};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub type Symbols = HashMap<String, u32>;
|
pub type Symbols = HashMap<String, usize>;
|
||||||
|
|
||||||
impl Symbols {
|
pub fn load_symbols(filename: &Path) -> anyhow::Result<Symbols> {
|
||||||
pub fn load(filename: Path) -> anyhow::Result<Symbols> {
|
let file = File::open(filename)?;
|
||||||
let file = File::open(filename)?;
|
let reader = BufReader::new(file);
|
||||||
let mut reader = BufReader::new(file);
|
|
||||||
|
|
||||||
reader.lines().filter_map(|l| l.ok().and_then(|line| {
|
let symbols = reader.lines().filter_map(|l| l.ok().and_then(|line| {
|
||||||
let words: Vec<String> = line.split_ascii_whitespace().collect();
|
let mut words = line.split_ascii_whitespace();
|
||||||
if words.len() == 2 {
|
match (words.next(), words.next(), words.next()) {
|
||||||
Some((words[1], words[0]))
|
// Get only two-word lines.
|
||||||
} else {
|
(Some(address), Some(symbol), None) =>
|
||||||
None
|
Some((symbol.to_owned(), address.to_owned())),
|
||||||
}
|
|
||||||
}))
|
_ => None
|
||||||
.filter_map(|(symbol, mut address)| {
|
}
|
||||||
|
})
|
||||||
|
.and_then(|(symbol, mut address)| {
|
||||||
if let Some(colon_at) = address.find(':') {
|
if let Some(colon_at) = address.find(':') {
|
||||||
address.remove(colon_at);
|
address.remove(colon_at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter out the ones that don't have a hexadecimal number as the first word.
|
||||||
let snes_address = u32::from_str_radix(&address, 16).ok()?;
|
let snes_address = u32::from_str_radix(&address, 16).ok()?;
|
||||||
|
|
||||||
let pc_address = (snes_address & 0x7FFF) + ((addr / 2) & 0xFF8000);
|
let pc_address = snes_to_pc_address(snes_address);
|
||||||
|
|
||||||
Some((symbol, pc_address))
|
Some((symbol, pc_address))
|
||||||
}).collect()
|
})).collect();
|
||||||
}
|
|
||||||
|
Ok(symbols)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn snes_to_pc_address(snes: u32) -> usize {
|
||||||
|
((snes & 0x7FFF) + ((snes / 2) & 0xFF8000)) as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pc_to_snes_address(pc: usize) -> u32 {
|
||||||
|
((pc & 0x7FFF) + ((pc & 0xFF8000) * 2)) as u32
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue