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::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::io::{BufReader, BufRead};
|
||||
use std::path::Path;
|
||||
|
||||
pub type Symbols = HashMap<String, u32>;
|
||||
pub type Symbols = HashMap<String, usize>;
|
||||
|
||||
impl Symbols {
|
||||
pub fn load(filename: Path) -> anyhow::Result<Symbols> {
|
||||
pub fn load_symbols(filename: &Path) -> anyhow::Result<Symbols> {
|
||||
let file = File::open(filename)?;
|
||||
let mut reader = BufReader::new(file);
|
||||
let reader = BufReader::new(file);
|
||||
|
||||
reader.lines().filter_map(|l| l.ok().and_then(|line| {
|
||||
let words: Vec<String> = line.split_ascii_whitespace().collect();
|
||||
if words.len() == 2 {
|
||||
Some((words[1], words[0]))
|
||||
} else {
|
||||
None
|
||||
let symbols = reader.lines().filter_map(|l| l.ok().and_then(|line| {
|
||||
let mut words = line.split_ascii_whitespace();
|
||||
match (words.next(), words.next(), words.next()) {
|
||||
// Get only two-word lines.
|
||||
(Some(address), Some(symbol), 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(':') {
|
||||
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 pc_address = (snes_address & 0x7FFF) + ((addr / 2) & 0xFF8000);
|
||||
let pc_address = snes_to_pc_address(snes_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