Understand better how SNES addressing works.

This commit is contained in:
Lyle Mantooth 2022-05-29 19:16:49 -04:00
parent a161d9090e
commit 7a6689efd1
Signed by: IslandUsurper
GPG key ID: 6DB52EAE123A5789

View file

@ -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
}