Refactor memory management: remove unused enums and RomInfo class to simplify memory.h

This commit is contained in:
scawful
2024-11-09 20:13:08 -05:00
parent d9243b26f7
commit ef2ddaa74e
3 changed files with 39 additions and 219 deletions

View File

@@ -1,7 +1,7 @@
add_executable(
yaze_emu
app/rom.cc
app/emu/debug/emu.cc
app/emu/emu.cc
${YAZE_APP_EMU_SRC}
${YAZE_APP_CORE_SRC}
${YAZE_APP_EDITOR_SRC}

View File

@@ -1,32 +1,33 @@
#include "app/emu/memory/memory.h"
#include "imgui/imgui.h"
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include "imgui/imgui.h"
namespace yaze {
namespace app {
namespace emu {
namespace memory {
void MemoryImpl::Initialize(const std::vector<uint8_t>& romData, bool verbose) {
void MemoryImpl::Initialize(const std::vector<uint8_t>& rom_data,
bool verbose) {
verbose_ = verbose;
type_ = 1;
auto location = 0x7FC0; // GetHeaderOffset();
romSize = 0x400 << romData[location + 0x17];
sramSize = 0x400 << romData[location + 0x18];
rom_.resize(romSize);
rom_size_ = 0x400 << rom_data[location + 0x17];
sram_size_ = 0x400 << rom_data[location + 0x18];
rom_.resize(rom_size_);
// Copy memory into rom_
for (size_t i = 0; i < romSize; i++) {
rom_[i] = romData[i];
for (size_t i = 0; i < rom_size_; i++) {
rom_[i] = rom_data[i];
}
ram_.resize(sramSize);
for (size_t i = 0; i < sramSize; i++) {
ram_.resize(sram_size_);
for (size_t i = 0; i < sram_size_; i++) {
ram_[i] = 0;
}
@@ -35,71 +36,19 @@ void MemoryImpl::Initialize(const std::vector<uint8_t>& romData, bool verbose) {
std::fill(memory_.begin(), memory_.end(), 0);
// Load ROM data into memory based on LoROM mapping
size_t romSize = romData.size();
size_t romAddress = 0;
size_t rom_data_size = rom_data.size();
size_t rom_address = 0;
const size_t ROM_CHUNK_SIZE = 0x8000; // 32 KB
for (size_t bank = 0x00; bank <= 0x3F; ++bank) {
for (size_t offset = 0x8000; offset <= 0xFFFF; offset += ROM_CHUNK_SIZE) {
if (romAddress < romSize) {
std::copy(romData.begin() + romAddress,
romData.begin() + romAddress + ROM_CHUNK_SIZE,
if (rom_address < rom_data_size) {
std::copy(rom_data.begin() + rom_address,
rom_data.begin() + rom_address + ROM_CHUNK_SIZE,
memory_.begin() + (bank << 16) + offset);
romAddress += ROM_CHUNK_SIZE;
rom_address += ROM_CHUNK_SIZE;
}
}
}
}
memory::RomInfo MemoryImpl::ReadRomHeader() {
memory::RomInfo rom_info;
uint32_t offset = GetHeaderOffset();
// Read cartridge title
char title[22];
for (int i = 0; i < 21; ++i) {
title[i] = ReadByte(offset + i);
}
title[21] = '\0'; // Null-terminate the string
rom_info.title = std::string(title);
// Read ROM speed and memory map mode
uint8_t romSpeedAndMapMode = ReadByte(offset + 0x15);
rom_info.romSpeed = (memory::RomSpeed)(romSpeedAndMapMode & 0x07);
rom_info.bankSize = (memory::BankSize)((romSpeedAndMapMode >> 5) & 0x01);
// Read ROM type
rom_info.romType = (memory::RomType)ReadByte(offset + 0x16);
// Read ROM size
rom_info.romSize = (memory::RomSize)ReadByte(offset + 0x17);
// Read RAM size
rom_info.sramSize = (memory::SramSize)ReadByte(offset + 0x18);
// Read country code
rom_info.countryCode = (memory::CountryCode)ReadByte(offset + 0x19);
// Read license
rom_info.license = (memory::License)ReadByte(offset + 0x1A);
// Read ROM version
rom_info.version = ReadByte(offset + 0x1B);
// Read checksum complement
rom_info.checksumComplement = ReadWord(offset + 0x1E);
// Read checksum
rom_info.checksum = ReadWord(offset + 0x1C);
// Read NMI VBL vector
rom_info.nmiVblVector = ReadWord(offset + 0x3E);
// Read reset vector
rom_info.resetVector = ReadWord(offset + 0x3C);
return rom_info;
}
uint8_t MemoryImpl::cart_read(uint8_t bank, uint16_t adr) {
@@ -134,59 +83,59 @@ void MemoryImpl::cart_write(uint8_t bank, uint16_t adr, uint8_t val) {
uint8_t MemoryImpl::cart_readLorom(uint8_t bank, uint16_t adr) {
if (((bank >= 0x70 && bank < 0x7e) || bank >= 0xf0) && adr < 0x8000 &&
sramSize > 0) {
sram_size_ > 0) {
// banks 70-7e and f0-ff, adr 0000-7fff
return ram_[(((bank & 0xf) << 15) | adr) & (sramSize - 1)];
return ram_[(((bank & 0xf) << 15) | adr) & (sram_size_ - 1)];
}
bank &= 0x7f;
if (adr >= 0x8000 || bank >= 0x40) {
// adr 8000-ffff in all banks or all addresses in banks 40-7f and c0-ff
return rom_[((bank << 15) | (adr & 0x7fff)) & (romSize - 1)];
return rom_[((bank << 15) | (adr & 0x7fff)) & (rom_size_ - 1)];
}
return open_bus_;
}
void MemoryImpl::cart_writeLorom(uint8_t bank, uint16_t adr, uint8_t val) {
if (((bank >= 0x70 && bank < 0x7e) || bank > 0xf0) && adr < 0x8000 &&
sramSize > 0) {
sram_size_ > 0) {
// banks 70-7e and f0-ff, adr 0000-7fff
ram_[(((bank & 0xf) << 15) | adr) & (sramSize - 1)] = val;
ram_[(((bank & 0xf) << 15) | adr) & (sram_size_ - 1)] = val;
}
}
uint8_t MemoryImpl::cart_readHirom(uint8_t bank, uint16_t adr) {
bank &= 0x7f;
if (bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && sramSize > 0) {
if (bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && sram_size_ > 0) {
// banks 00-3f and 80-bf, adr 6000-7fff
return ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sramSize - 1)];
return ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sram_size_ - 1)];
}
if (adr >= 0x8000 || bank >= 0x40) {
// adr 8000-ffff in all banks or all addresses in banks 40-7f and c0-ff
return rom_[(((bank & 0x3f) << 16) | adr) & (romSize - 1)];
return rom_[(((bank & 0x3f) << 16) | adr) & (rom_size_ - 1)];
}
return open_bus_;
}
uint8_t MemoryImpl::cart_readExHirom(uint8_t bank, uint16_t adr) {
if ((bank & 0x7f) < 0x40 && adr >= 0x6000 && adr < 0x8000 && sramSize > 0) {
if ((bank & 0x7f) < 0x40 && adr >= 0x6000 && adr < 0x8000 && sram_size_ > 0) {
// banks 00-3f and 80-bf, adr 6000-7fff
return ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sramSize - 1)];
return ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sram_size_ - 1)];
}
bool secondHalf = bank < 0x80;
bank &= 0x7f;
if (adr >= 0x8000 || bank >= 0x40) {
// adr 8000-ffff in all banks or all addresses in banks 40-7f and c0-ff
return rom_[(((bank & 0x3f) << 16) | (secondHalf ? 0x400000 : 0) | adr) &
(romSize - 1)];
(rom_size_ - 1)];
}
return open_bus_;
}
void MemoryImpl::cart_writeHirom(uint8_t bank, uint16_t adr, uint8_t val) {
bank &= 0x7f;
if (bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && sramSize > 0) {
if (bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && sram_size_ > 0) {
// banks 00-3f and 80-bf, adr 6000-7fff
ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sramSize - 1)] = val;
ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sram_size_ - 1)] = val;
}
}
@@ -216,70 +165,6 @@ uint32_t MemoryImpl::GetMappedAddress(uint32_t address) const {
return address; // Return the original address if no mapping is defined
}
void DrawSnesMemoryMapping(const MemoryImpl& memory) {
// Using those as a base value to create width/height that are factor of the
// size of our font
const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
const char* column_names[] = {
"Offset", "0x00", "0x01", "0x02", "0x03", "0x04", "0x05", "0x06", "0x07",
"0x08", "0x09", "0x0A", "0x0B", "0x0C", "0x0D", "0x0E", "0x0F", "0x10",
"0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19",
"0x1A", "0x1B", "0x1C", "0x1D", "0x1E", "0x1F"};
const int columns_count = IM_ARRAYSIZE(column_names);
const int rows_count = 16;
static ImGuiTableFlags table_flags =
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX |
ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter |
ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_Hideable |
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable |
ImGuiTableFlags_HighlightHoveredColumn;
static bool bools[columns_count * rows_count] = {};
static int frozen_cols = 1;
static int frozen_rows = 2;
ImGui::CheckboxFlags("_ScrollX", &table_flags, ImGuiTableFlags_ScrollX);
ImGui::CheckboxFlags("_ScrollY", &table_flags, ImGuiTableFlags_ScrollY);
ImGui::CheckboxFlags("_NoBordersInBody", &table_flags,
ImGuiTableFlags_NoBordersInBody);
ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags,
ImGuiTableFlags_HighlightHoveredColumn);
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
ImGui::SliderInt("Frozen columns", &frozen_cols, 0, 2);
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags,
ImVec2(0.0f, TEXT_BASE_HEIGHT * 12))) {
ImGui::TableSetupColumn(
column_names[0],
ImGuiTableColumnFlags_NoHide | ImGuiTableColumnFlags_NoReorder);
for (int n = 1; n < columns_count; n++)
ImGui::TableSetupColumn(column_names[n],
ImGuiTableColumnFlags_AngledHeader |
ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupScrollFreeze(frozen_cols, frozen_rows);
ImGui::TableAngledHeadersRow();
ImGui::TableHeadersRow();
for (int row = 0; row < rows_count; row++) {
ImGui::PushID(row);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::AlignTextToFramePadding();
ImGui::Text("Offset 0x%04X", row);
for (int column = 1; column < columns_count; column++)
if (ImGui::TableSetColumnIndex(column)) {
ImGui::PushID(column);
ImGui::Checkbox("", &bools[row * columns_count + column]);
ImGui::PopID();
}
ImGui::PopID();
}
ImGui::EndTable();
}
}
} // namespace memory
} // namespace emu
} // namespace app

View File

@@ -31,67 +31,6 @@ namespace app {
namespace emu {
namespace memory {
enum RomSpeed { SLOW_ROM = 0x00, FAST_ROM = 0x07 };
enum BankSize { LOW_ROM = 0x00, HI_ROM = 0x01 };
enum RomType {
ROM_DEFAULT = 0x00,
ROM_RAM = 0x01,
ROM_SRAM = 0x02,
ROM_DSP1 = 0x03,
ROM_DSP1_RAM = 0x04,
ROM_DSP1_SRAM = 0x05,
FX = 0x06
};
enum RomSize {
SIZE_2_MBIT = 0x08,
SIZE_4_MBIT = 0x09,
SIZE_8_MBIT = 0x0A,
SIZE_16_MBIT = 0x0B,
SIZE_32_MBIT = 0x0C
};
enum SramSize {
NO_SRAM = 0x00,
SRAM_16_KBIT = 0x01,
SRAM_32_KBIT = 0x02,
SRAM_64_KBIT = 0x03
};
enum CountryCode {
JAPAN = 0x00,
USA = 0x01,
EUROPE_OCEANIA_ASIA = 0x02,
// ... and other countries
};
enum License {
INVALID = 0,
NINTENDO = 1,
ZAMUSE = 5,
CAPCOM = 8,
// ... and other licenses
};
class RomInfo {
public:
std::string title;
RomSpeed romSpeed;
BankSize bankSize;
RomType romType;
RomSize romSize;
SramSize sramSize;
CountryCode countryCode;
License license;
uint8_t version;
uint16_t checksumComplement;
uint16_t checksum;
uint16_t nmiVblVector;
uint16_t resetVector;
};
typedef struct CpuCallbacks {
std::function<uint8_t(uint32_t)> read_byte;
std::function<void(uint32_t, uint8_t)> write_byte;
@@ -162,15 +101,11 @@ class Memory {
*/
class MemoryImpl : public Memory {
public:
uint32_t romSize;
uint32_t sramSize;
void Initialize(const std::vector<uint8_t>& romData, bool verbose = false);
uint16_t GetHeaderOffset() {
uint8_t mapMode = memory_[(0x00 << 16) + 0xFFD5];
uint16_t offset;
switch (mapMode & 0x07) {
switch (memory_[(0x00 << 16) + 0xFFD5] & 0x07) {
case 0: // LoROM
offset = 0x7FC0;
break;
@@ -189,8 +124,6 @@ class MemoryImpl : public Memory {
return offset;
}
memory::RomInfo ReadRomHeader();
uint8_t cart_read(uint8_t bank, uint16_t adr);
void cart_write(uint8_t bank, uint16_t adr, uint8_t val);
@@ -347,6 +280,10 @@ class MemoryImpl : public Memory {
bool pal_timing_ = false;
// Memory regions
uint32_t rom_size_;
uint32_t sram_size_;
// Frame timing
uint16_t h_pos_ = 0;
uint16_t v_pos_ = 0;
@@ -354,9 +291,6 @@ class MemoryImpl : public Memory {
// Dma State
uint8_t dma_state_ = 0;
// Dma Channels
DmaChannel channel[8];
// Open bus
uint8_t open_bus_ = 0;
@@ -366,12 +300,13 @@ class MemoryImpl : public Memory {
// Cart Type
uint8_t type_ = 1;
// Dma Channels
DmaChannel channel[8];
// Memory (64KB)
std::vector<uint8_t> memory_;
};
void DrawSnesMemoryMapping(const MemoryImpl& memory);
} // namespace memory
} // namespace emu
} // namespace app