Emulator housekeeping

This commit is contained in:
scawful
2023-11-26 16:48:49 -05:00
parent 23df9191ed
commit 1633955177
3 changed files with 56 additions and 42 deletions

View File

@@ -155,9 +155,9 @@ void Emulator::Run() {
if (running_) { if (running_) {
HandleEvents(); HandleEvents();
UpdateEmulator(); UpdateEmulator();
RenderEmulator();
} }
RenderEmulator();
if (debugger_) { if (debugger_) {
RenderDebugger(); RenderDebugger();
} }
@@ -166,11 +166,25 @@ void Emulator::Run() {
void Emulator::RenderEmulator() { void Emulator::RenderEmulator() {
ImVec2 size = ImVec2(320, 240); ImVec2 size = ImVec2(320, 240);
if (snes_.running()) { if (snes_.running()) {
ImGui::Image((void*)snes_.Ppu().GetScreen()->texture(), size, ImVec2(0, 0), ImGui::BeginChild(
"EmulatorOutput", ImVec2(0, 0), true,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
ImGui::SetCursorPosX((ImGui::GetWindowSize().x - size.x) * 0.5f);
ImGui::SetCursorPosY((ImGui::GetWindowSize().y - size.y) * 0.5f);
ImGui::Image((void*)snes_.ppu().GetScreen()->texture(), size, ImVec2(0, 0),
ImVec2(1, 1)); ImVec2(1, 1));
ImGui::EndChild();
ImGui::Separator(); ImGui::Separator();
} else { } else {
ImGui::BeginChild(
"EmulatorOutput", ImVec2(0, 0), true,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
ImGui::SetCursorPosX((ImGui::GetWindowSize().x - size.x) * 0.5f);
ImGui::SetCursorPosY((ImGui::GetWindowSize().y - size.y) * 0.5f);
ImGui::Dummy(size); ImGui::Dummy(size);
ImGui::EndChild();
ImGui::Separator(); ImGui::Separator();
ImGui::Text("Emulator output not available."); ImGui::Text("Emulator output not available.");
} }
@@ -242,10 +256,10 @@ void Emulator::RenderDebugger() {
"DebugTable", 3, "DebugTable", 3,
ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY)) { ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY)) {
TableNextColumn(); TableNextColumn();
RenderCpuState(snes_.Cpu()); RenderCpuState(snes_.cpu());
TableNextColumn(); TableNextColumn();
RenderCPUInstructionLog(snes_.Cpu().instruction_log_); RenderCPUInstructionLog(snes_.cpu().instruction_log_);
TableNextColumn(); TableNextColumn();
RenderBreakpointList(); RenderBreakpointList();
@@ -286,21 +300,21 @@ void Emulator::RenderBreakpointList() {
if (ImGui::InputText("##BreakpointInput", breakpoint_input, 10, if (ImGui::InputText("##BreakpointInput", breakpoint_input, 10,
ImGuiInputTextFlags_EnterReturnsTrue)) { ImGuiInputTextFlags_EnterReturnsTrue)) {
int breakpoint = std::stoi(breakpoint_input, nullptr, 16); int breakpoint = std::stoi(breakpoint_input, nullptr, 16);
snes_.Cpu().SetBreakpoint(breakpoint); snes_.cpu().SetBreakpoint(breakpoint);
memset(breakpoint_input, 0, sizeof(breakpoint_input)); memset(breakpoint_input, 0, sizeof(breakpoint_input));
} }
SameLine(); SameLine();
if (ImGui::Button("Add")) { if (ImGui::Button("Add")) {
int breakpoint = std::stoi(breakpoint_input, nullptr, 16); int breakpoint = std::stoi(breakpoint_input, nullptr, 16);
snes_.Cpu().SetBreakpoint(breakpoint); snes_.cpu().SetBreakpoint(breakpoint);
memset(breakpoint_input, 0, sizeof(breakpoint_input)); memset(breakpoint_input, 0, sizeof(breakpoint_input));
} }
SameLine(); SameLine();
if (ImGui::Button("Clear")) { if (ImGui::Button("Clear")) {
snes_.Cpu().ClearBreakpoints(); snes_.cpu().ClearBreakpoints();
} }
Separator(); Separator();
auto breakpoints = snes_.Cpu().GetBreakpoints(); auto breakpoints = snes_.cpu().GetBreakpoints();
if (!breakpoints.empty()) { if (!breakpoints.empty()) {
Text("Breakpoints:"); Text("Breakpoints:");
ImGui::BeginChild("BreakpointsList", ImVec2(0, 100), true); ImGui::BeginChild("BreakpointsList", ImVec2(0, 100), true);

View File

@@ -64,45 +64,45 @@ ROMInfo SNES::ReadRomHeader(uint32_t offset) {
// Read cartridge title // Read cartridge title
char title[22]; char title[22];
for (int i = 0; i < 21; ++i) { for (int i = 0; i < 21; ++i) {
title[i] = cpu.ReadByte(offset + i); title[i] = cpu_.ReadByte(offset + i);
} }
title[21] = '\0'; // Null-terminate the string title[21] = '\0'; // Null-terminate the string
romInfo.title = std::string(title); romInfo.title = std::string(title);
// Read ROM speed and memory map mode // Read ROM speed and memory map mode
uint8_t romSpeedAndMapMode = cpu.ReadByte(offset + 0x15); uint8_t romSpeedAndMapMode = cpu_.ReadByte(offset + 0x15);
romInfo.romSpeed = (ROMSpeed)(romSpeedAndMapMode & 0x07); romInfo.romSpeed = (ROMSpeed)(romSpeedAndMapMode & 0x07);
romInfo.bankSize = (BankSize)((romSpeedAndMapMode >> 5) & 0x01); romInfo.bankSize = (BankSize)((romSpeedAndMapMode >> 5) & 0x01);
// Read ROM type // Read ROM type
romInfo.romType = (ROMType)cpu.ReadByte(offset + 0x16); romInfo.romType = (ROMType)cpu_.ReadByte(offset + 0x16);
// Read ROM size // Read ROM size
romInfo.romSize = (ROMSize)cpu.ReadByte(offset + 0x17); romInfo.romSize = (ROMSize)cpu_.ReadByte(offset + 0x17);
// Read RAM size // Read RAM size
romInfo.sramSize = (SRAMSize)cpu.ReadByte(offset + 0x18); romInfo.sramSize = (SRAMSize)cpu_.ReadByte(offset + 0x18);
// Read country code // Read country code
romInfo.countryCode = (CountryCode)cpu.ReadByte(offset + 0x19); romInfo.countryCode = (CountryCode)cpu_.ReadByte(offset + 0x19);
// Read license // Read license
romInfo.license = (License)cpu.ReadByte(offset + 0x1A); romInfo.license = (License)cpu_.ReadByte(offset + 0x1A);
// Read ROM version // Read ROM version
romInfo.version = cpu.ReadByte(offset + 0x1B); romInfo.version = cpu_.ReadByte(offset + 0x1B);
// Read checksum complement // Read checksum complement
romInfo.checksumComplement = cpu.ReadWord(offset + 0x1E); romInfo.checksumComplement = cpu_.ReadWord(offset + 0x1E);
// Read checksum // Read checksum
romInfo.checksum = cpu.ReadWord(offset + 0x1C); romInfo.checksum = cpu_.ReadWord(offset + 0x1C);
// Read NMI VBL vector // Read NMI VBL vector
romInfo.nmiVblVector = cpu.ReadWord(offset + 0x3E); romInfo.nmiVblVector = cpu_.ReadWord(offset + 0x3E);
// Read reset vector // Read reset vector
romInfo.resetVector = cpu.ReadWord(offset + 0x3C); romInfo.resetVector = cpu_.ReadWord(offset + 0x3C);
return romInfo; return romInfo;
} }
@@ -112,18 +112,18 @@ void SNES::Init(ROM& rom) {
// Disable the emulation flag (switch to 65816 native mode) // Disable the emulation flag (switch to 65816 native mode)
// Initialize CPU // Initialize CPU
cpu.Init(); cpu_.Init();
// Read the ROM header // Read the ROM header
auto header_offset = GetHeaderOffset(memory_); auto header_offset = GetHeaderOffset(memory_);
rom_info_ = ReadRomHeader(header_offset); rom_info_ = ReadRomHeader(header_offset);
cpu.PC = rom_info_.resetVector; cpu_.PC = rom_info_.resetVector;
// Initialize PPU // Initialize PPU
ppu.Init(); ppu_.Init();
// Initialize APU // Initialize APU
apu.Init(); apu_.Init();
// Initialize SDL_Mixer to play the audio samples // Initialize SDL_Mixer to play the audio samples
// Mix_HookMusic(audio_callback, &apu); // Mix_HookMusic(audio_callback, &apu);
@@ -232,16 +232,16 @@ void SNES::Run() {
frame_accumulated_time += delta_time; frame_accumulated_time += delta_time;
// Update the CPU // Update the CPU
cpu.UpdateClock(delta_time); cpu_.UpdateClock(delta_time);
cpu.Update(GetCpuMode()); cpu_.Update(GetCpuMode());
// Update the PPU // Update the PPU
ppu.UpdateClock(delta_time); ppu_.UpdateClock(delta_time);
ppu.Update(); ppu_.Update();
// Update the APU // Update the APU
apu.UpdateClock(delta_time); apu_.UpdateClock(delta_time);
apu.Update(); apu_.Update();
if (frame_accumulated_time >= frame_time) { if (frame_accumulated_time >= frame_time) {
// renderer.Render(); // renderer.Render();
@@ -279,11 +279,11 @@ void SNES::NmiIsr() {
// ... // ...
// Push CPU registers to stack // Push CPU registers to stack
cpu.PHP(); cpu_.PHP();
// Reset DB and DP registers // Reset DB and DP registers
cpu.DB = 0x80; // Assuming bank 0x80, can be changed to 0x00 cpu_.DB = 0x80; // Assuming bank 0x80, can be changed to 0x00
cpu.D = 0; cpu_.D = 0;
if (v_blank_flag_) { if (v_blank_flag_) {
VBlankRoutine(); VBlankRoutine();
@@ -296,7 +296,7 @@ void SNES::NmiIsr() {
frame_counter_++; frame_counter_++;
// Restore CPU registers // Restore CPU registers
cpu.PHB(); cpu_.PHB();
} }
// VBlank routine // VBlank routine
@@ -307,7 +307,7 @@ void SNES::VBlankRoutine() {
void SNES::BootAPUWithIPL() { void SNES::BootAPUWithIPL() {
// 1. Waiting for the SPC700 to be ready // 1. Waiting for the SPC700 to be ready
while (!apu.IsReadySignalReceived()) { while (!apu_.IsReadySignalReceived()) {
// Active waiting (this can be optimized) // Active waiting (this can be optimized)
} }

View File

@@ -63,8 +63,8 @@ class SNES : public DMA {
bool running() const { return running_; } bool running() const { return running_; }
auto Cpu() -> CPU& { return cpu; } auto cpu() -> CPU& { return cpu_; }
auto Ppu() -> PPU& { return ppu; } auto ppu() -> Ppu& { return ppu_; }
auto Memory() -> MemoryImpl* { return &memory_; } auto Memory() -> MemoryImpl* { return &memory_; }
void SetCpuMode(int mode) { cpu_mode_ = mode; } void SetCpuMode(int mode) { cpu_mode_ = mode; }
@@ -74,8 +74,8 @@ class SNES : public DMA {
void SetupMemory(ROM& rom) { void SetupMemory(ROM& rom) {
// Setup observers for the memory space // Setup observers for the memory space
memory_.AddObserver(&apu); memory_.AddObserver(&apu_);
memory_.AddObserver(&ppu); memory_.AddObserver(&ppu_);
// Load the ROM into memory and set up the memory mapping // Load the ROM into memory and set up the memory mapping
memory_.Initialize(rom.vector()); memory_.Initialize(rom.vector());
@@ -91,9 +91,9 @@ class SNES : public DMA {
ClockImpl clock_; ClockImpl clock_;
AudioRamImpl audio_ram_; AudioRamImpl audio_ram_;
CPU cpu{memory_, clock_}; CPU cpu_{memory_, clock_};
PPU ppu{memory_, clock_}; Ppu ppu_{memory_, clock_};
APU apu{memory_, audio_ram_, clock_}; APU apu_{memory_, audio_ram_, clock_};
// Helper classes // Helper classes
ROMInfo rom_info_; ROMInfo rom_info_;