memory map viewer

This commit is contained in:
2023-05-14 22:33:44 -05:00
parent 0cc55d7b20
commit a44895645c
6 changed files with 171 additions and 20 deletions
+1 -1
View File
@@ -1098,7 +1098,7 @@ impl CPU {
self.increment_cycles_test(addressing_mode);
}
pub fn run(&mut self, bus: &mut Bus) {
pub fn tick(&mut self, bus: &mut Bus) {
let opcode = bus.read(self.registers.get_pc_address());
self.execute_opcode(opcode, bus);
}
+1 -1
View File
@@ -16,7 +16,7 @@ pub struct Registers {
impl Registers {
pub fn new() -> Self {
Self {
sp: 0,
sp: 0x01FC,
x: 0,
y: 0,
a: 0,
+2 -2
View File
@@ -20,8 +20,8 @@ impl Emulator {
}
}
pub fn run(&mut self) {
self.cpu.run(&mut self.bus);
pub fn tick(&mut self) {
self.cpu.tick(&mut self.bus);
self.bus.ppu.tick(self.cpu.cycles);
self.cpu.cycles = 0;
+1
View File
@@ -7,6 +7,7 @@ edition = "2021"
[dependencies]
snes-core = { path = "../snes-core" }
regex = "1.8.1"
winit = "0.26.1"
imgui = "0.8.2"
wgpu = "0.12.0"
+91 -13
View File
@@ -18,6 +18,9 @@ extern crate snes_core;
use snes_core::emulator::Emulator;
use snes_frontend::ppu as ppu_render;
// TODO: refactor this please
fn main() {
// Windowing state
let mut state = State::new();
@@ -78,7 +81,7 @@ fn main() {
);
imgui.set_ini_filename(None);
let font_size = (12.0 * hidpi_factor) as f32;
let font_size = (14.0 * hidpi_factor) as f32;
imgui.io_mut().font_global_scale = (1.0 / hidpi_factor) as f32;
imgui.fonts().add_font(&[FontSource::DefaultFontData {
@@ -219,7 +222,7 @@ fn main() {
{
match emulator.bus.rom.load(&String::from(path.to_str().unwrap())) {
Ok(_) => {
state.emulation.is_paused = false;
// state.emulation.is_paused = false;
},
Err(err) => {
state.error_message.show = true;
@@ -247,11 +250,27 @@ fn main() {
.size([300.0, 100.0], Condition::FirstUseEver)
.opened(&mut state.debug_options.show_debug_window)
.build(&ui, || {
ui.text("Controls:");
let pause_text = if state.emulation.is_paused {"Resume"} else {"Pause"};
if ui.button(pause_text) {
state.emulation.is_paused = !state.emulation.is_paused;
}
ui.disabled(!state.emulation.is_paused, || {
if ui.button("Tick") {
emulator.tick();
}
});
ui.separator();
ui.checkbox(
"Enable debugging",
&mut state.debug_options.is_enabled,
);
ui.separator();
ui.checkbox(
"Show Memory Map",
&mut state.debug_options.memory_map.is_enabled ,
);
ui.checkbox(
"Show PPU debugging options",
&mut state.ppudebug.is_enabled,
@@ -295,16 +314,75 @@ fn main() {
window
.size([150.0, 200.0], Condition::FirstUseEver)
.build(&ui, || {
ui.text(format!("SP: | {:#06X}", emulator.cpu.registers.sp));
ui.text(format!("X: | {:#06X}", emulator.cpu.registers.x));
ui.text(format!("Y: | {:#06X}", emulator.cpu.registers.y));
ui.text(format!("A: | {:#06X}", emulator.cpu.registers.a));
ui.text(format!("P: | {:#04X}", emulator.cpu.registers.p));
ui.text(format!("D: | {:#06X}", emulator.cpu.registers.d));
ui.text(format!("PBR: | {:#04X}", emulator.cpu.registers.pbr));
ui.text(format!("DBR: | {:#04X}", emulator.cpu.registers.dbr));
ui.text(format!("PC: | {:#06X}", emulator.cpu.registers.pc));
ui.text(format!("EMU MODE: | {}", emulator.cpu.registers.emulation_mode));
ui.text(format!("SP: | {:#06X}", emulator.cpu.registers.sp));
ui.text(format!("X: | {:#06X}", emulator.cpu.registers.x));
ui.text(format!("Y: | {:#06X}", emulator.cpu.registers.y));
ui.text(format!("A: | {:#06X}", emulator.cpu.registers.a));
ui.text(format!("P: | {:#04X}", emulator.cpu.registers.p));
ui.text(format!("D: | {:#06X}", emulator.cpu.registers.d));
ui.text(format!("PBR: | {:#04X}", emulator.cpu.registers.pbr));
ui.text(format!("DBR: | {:#04X}", emulator.cpu.registers.dbr));
ui.text(format!("PC: | {:#06X}", emulator.cpu.registers.pc));
ui.text(format!("EMU MODE: | {}", emulator.cpu.registers.emulation_mode));
});
}
if state.debug_options.memory_map.is_enabled {
let window = imgui::Window::new("Memory Map");
window
.size([400.0, 400.0], Condition::FirstUseEver)
.build(&ui, || {
let page_start_input = ui.input_text(
"Page start",
&mut state.debug_options.memory_map.page_start_input
);
page_start_input.build();
let page_end_input = ui.input_text(
"Page end",
&mut state.debug_options.memory_map.page_end_input
);
page_end_input.build();
let address_start_input = ui.input_text(
"Address start",
&mut state.debug_options.memory_map.address_start_input
);
address_start_input.build();
let address_end_input = ui.input_text(
"Address end",
&mut state.debug_options.memory_map.address_end_input,
);
address_end_input.build();
if ui.button("Apply") {
state.debug_options.memory_map.set_values_from_inputs();
}
ui.separator();
let page_start = state.debug_options.memory_map.page_start;
let page_end = state.debug_options.memory_map.page_end;
let address_start = state.debug_options.memory_map.address_start;
let address_end = state.debug_options.memory_map.address_end;
let mut header = String::from(" | ");
for page in (page_start..=page_end).rev() {
header = format!("{}{:02X} ", header, page);
}
ui.text(header);
let mut divider = String::from("-----|-");
for _page in (page_start..=page_end).rev() {
divider = format!("{}---", divider);
}
ui.text(divider);
for address in (address_start..=address_end).rev() {
let mut address_row = format!("{:04X} | ", address);
for page in (page_start..=page_end).rev() {
let bus_address = ((page as u32) << 16) | (address as u32);
address_row = format!("{}{:02X} ", address_row, emulator.bus.read(bus_address));
}
ui.text(address_row);
}
});
}
}
@@ -314,7 +392,7 @@ fn main() {
// We want to keep the emulator running
// as long as we are not at the end of the frame
while !emulator.is_frame_ending {
emulator.run()
emulator.tick()
}
// Reset the flag because otherwise the emulator will never continue running
emulator.is_frame_ending = false
+75 -3
View File
@@ -4,14 +4,86 @@ use snes_core::ppu::registers::{
MAX_BG_WIDTH,
MAX_BG_HEIGHT,
};
use regex::Regex;
pub struct MemoryMap {
pub is_enabled: bool,
pub page_start: u8,
pub page_end: u8,
pub address_start: u16,
pub address_end: u16,
pub page_start_input: String,
pub page_end_input: String,
pub address_start_input: String,
pub address_end_input: String,
}
impl MemoryMap {
pub fn new() -> Self {
Self {
is_enabled: true,
page_start: 0xF0,
page_end: 0xFF,
address_start: 0xFFF0,
address_end: 0xFFFF,
page_start_input: String::from("0xF0"),
page_end_input: String::from("0xFF"),
address_start_input: String::from("0xFFF0"),
address_end_input: String::from("0xFFFF"),
}
}
fn validate_values(&mut self) {
if self.page_start > self.page_end {
self.page_start = self.page_end;
}
if self.page_end < self.page_start {
self.page_end = self.page_start;
}
if self.address_start > self.address_end {
self.address_start = self.address_end;
}
if self.address_end < self.address_start {
self.address_end = self.address_start;
}
}
pub fn set_values_from_inputs(&mut self) {
let page_regex = Regex::new(r"^(0x)?[0-9a-fA-F]{2,2}$").unwrap();
let address_regex = Regex::new(r"^(0x)?[0-9a-fA-F]{4,4}$").unwrap();
if !page_regex.is_match(&self.page_start_input) {
println!("Page start didn't match");
self.page_start_input = String::from("0x00");
}
if !page_regex.is_match(&self.page_end_input) {
println!("Page end didn't match");
self.page_end_input = String::from("0x00");
}
if !address_regex.is_match(&self.address_start_input) {
println!("Addr start didn't match");
self.address_start_input = String::from("0x0000");
}
if !address_regex.is_match(&self.address_end_input) {
println!("Addr end didn't match");
self.address_end_input = String::from("0x0000");
}
self.page_start = u8::from_str_radix(&self.page_start_input.trim_start_matches("0x"), 16).unwrap();
self.page_end = u8::from_str_radix(&self.page_end_input.trim_start_matches("0x"), 16).unwrap();
self.address_start = u16::from_str_radix(&self.address_start_input.trim_start_matches("0x"), 16).unwrap();
self.address_end = u16::from_str_radix(&self.address_end_input.trim_start_matches("0x"), 16).unwrap();
self.validate_values()
}
}
pub struct DebugOptions {
pub is_enabled: bool,
pub show_debug_window: bool,
pub show_cpu_registers: bool,
pub show_spc700_registers: bool,
pub show_cpu_memory: bool,
pub memory_map: MemoryMap,
}
impl DebugOptions {
@@ -21,7 +93,7 @@ impl DebugOptions {
show_debug_window: true,
show_cpu_registers: true,
show_spc700_registers: true,
show_cpu_memory: true,
memory_map: MemoryMap::new(),
}
}
}
@@ -105,4 +177,4 @@ impl State {
emulation: Emulation::new(),
}
}
}
}