mirror of
https://github.com/zoriya/ComSquare.git
synced 2025-12-06 07:16:17 +00:00
Cleaning up rom data
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "Exceptions/InvalidOpcode.hpp"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace ComSquare::APU
|
||||
{
|
||||
@@ -814,17 +815,17 @@ namespace ComSquare::APU
|
||||
|
||||
void APU::loadFromSPC(Cartridge::Cartridge &cartridge)
|
||||
{
|
||||
const uint8_t *data = cartridge.getData();
|
||||
std::span<const uint8_t> data = cartridge.getData();
|
||||
uint24_t size = cartridge.getSize();
|
||||
if (size < 0x101C0)
|
||||
throw InvalidAddress("Cartridge is not the right size", size);
|
||||
|
||||
std::string song = std::string(reinterpret_cast<const char *>(data + 0x2E), 0x20);
|
||||
std::string game = std::string(reinterpret_cast<const char *>(data + 0x4E), 0x20);
|
||||
std::string dumper = std::string(reinterpret_cast<const char *>(data + 0x6E), 0x10);
|
||||
std::string comment = std::string(reinterpret_cast<const char *>(data + 0x7E), 0x20);
|
||||
std::string date = std::string(reinterpret_cast<const char *>(data + 0x9E), 0x0B);
|
||||
std::string artist = std::string(reinterpret_cast<const char *>(data + 0xB1), 0x20);
|
||||
std::string song = std::string(reinterpret_cast<const char *>(data.data() + 0x2E), 0x20);
|
||||
std::string game = std::string(reinterpret_cast<const char *>(data.data() + 0x4E), 0x20);
|
||||
std::string dumper = std::string(reinterpret_cast<const char *>(data.data() + 0x6E), 0x10);
|
||||
std::string comment = std::string(reinterpret_cast<const char *>(data.data() + 0x7E), 0x20);
|
||||
std::string date = std::string(reinterpret_cast<const char *>(data.data() + 0x9E), 0x0B);
|
||||
std::string artist = std::string(reinterpret_cast<const char *>(data.data() + 0xB1), 0x20);
|
||||
|
||||
this->_internalRegisters.pcl = cartridge.read(0x25);
|
||||
this->_internalRegisters.pch = cartridge.read(0x26);
|
||||
@@ -834,9 +835,9 @@ namespace ComSquare::APU
|
||||
this->_internalRegisters.psw = cartridge.read(0x2A);
|
||||
this->_internalRegisters.sp = cartridge.read(0x2B);
|
||||
|
||||
std::memcpy(this->_map.Page0.getData(), data + 0x100, this->_map.Page0.getSize());
|
||||
std::memcpy(this->_map.Page1.getData(), data + 0x200, this->_map.Page1.getSize());
|
||||
std::memcpy(this->_map.Memory.getData(), data + 0x300, this->_map.Memory.getSize());
|
||||
std::copy_n(data.begin() + 0x100, this->_map.Page0.getSize(), this->_map.Page0.getData().begin());
|
||||
std::copy_n(data.begin() + 0x200, this->_map.Page1.getSize(), this->_map.Page1.getData().begin());
|
||||
std::copy_n(data.begin() + 0x300, this->_map.Memory.getSize(), this->_map.Memory.getData().begin());
|
||||
|
||||
this->_registers.unknown = cartridge.read(0x100 + 0xF0);
|
||||
this->_registers.ctrlreg = cartridge.read(0x100 + 0xF1);
|
||||
|
||||
@@ -7,18 +7,19 @@
|
||||
#include "Exceptions/InvalidRom.hpp"
|
||||
#include <cstring>
|
||||
#include <sys/stat.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace ComSquare::Cartridge
|
||||
{
|
||||
constexpr unsigned HeaderSize = 0x40u;
|
||||
|
||||
Cartridge::Cartridge()
|
||||
: Ram::Ram(0, Rom, "Cartridge")
|
||||
: Ram::Ram(0, Rom, "Cartridge")
|
||||
{}
|
||||
|
||||
Cartridge::Cartridge(const std::string &romPath)
|
||||
: Ram::Ram(0, Rom, "Cartridge"),
|
||||
_romPath(romPath)
|
||||
: Ram::Ram(0, Rom, "Cartridge"),
|
||||
_romPath(romPath)
|
||||
{
|
||||
this->loadRom(romPath);
|
||||
}
|
||||
@@ -26,14 +27,12 @@ namespace ComSquare::Cartridge
|
||||
void Cartridge::loadRom(const std::string &path)
|
||||
{
|
||||
size_t size = Cartridge::getRomSize(path);
|
||||
FILE *rom = fopen(path.c_str(), "rb");
|
||||
std::ifstream rom(path, std::ios::binary);
|
||||
|
||||
if (!rom)
|
||||
throw InvalidRomException("Could not open the rom file at " + path + ". " + strerror(errno));
|
||||
this->_size = size;
|
||||
this->_data = new uint8_t[size];
|
||||
std::memset(this->_data, 0, size);
|
||||
fread(this->_data, 1, size, rom);
|
||||
this->_data.resize(size);
|
||||
rom.read(reinterpret_cast<char *>(this->_data.data()), size);
|
||||
this->_loadHeader();
|
||||
}
|
||||
|
||||
@@ -46,7 +45,6 @@ namespace ComSquare::Cartridge
|
||||
return info.st_size;
|
||||
}
|
||||
|
||||
|
||||
uint8_t Cartridge::read(uint24_t addr)
|
||||
{
|
||||
return Ram::read(addr + this->_romStart);
|
||||
@@ -113,7 +111,7 @@ namespace ComSquare::Cartridge
|
||||
uint32_t Cartridge::_getHeaderAddress()
|
||||
{
|
||||
const std::vector<uint32_t> address = {0x7FC0, 0xFFC0};
|
||||
unsigned int smc = this->_size % 1024;
|
||||
unsigned int smc = this->getSize() % 1024;
|
||||
int bestScore = -1;
|
||||
uint32_t bestAddress = 0;
|
||||
|
||||
@@ -121,7 +119,7 @@ namespace ComSquare::Cartridge
|
||||
int score = 0;
|
||||
|
||||
addr += smc;
|
||||
if (addr + 0x32u >= this->_size)
|
||||
if (addr + 0x32u >= this->getSize())
|
||||
continue;
|
||||
|
||||
Header info = this->_mapHeader(addr);
|
||||
@@ -174,9 +172,9 @@ namespace ComSquare::Cartridge
|
||||
|
||||
bool Cartridge::_isSPCFile()
|
||||
{
|
||||
if (this->_size < 0x25)
|
||||
if (this->getSize() < 0x25)
|
||||
return false;
|
||||
std::string str = std::string(reinterpret_cast<char *>(this->_data), 0x21);
|
||||
std::string str = std::string(reinterpret_cast<char *>(this->getData().data()), 0x21);
|
||||
|
||||
if (str != Cartridge::_magicSPC)
|
||||
return false;
|
||||
@@ -198,14 +196,13 @@ namespace ComSquare::Cartridge
|
||||
this->_type = Game;
|
||||
|
||||
uint32_t headerAddress = this->_getHeaderAddress();
|
||||
if (headerAddress + HeaderSize > this->_size)
|
||||
if (headerAddress + HeaderSize > this->getSize())
|
||||
return false;
|
||||
|
||||
this->header = this->_mapHeader(headerAddress);
|
||||
this->header.gameName = std::string(reinterpret_cast<char *>(&this->_data[headerAddress]), 21);
|
||||
if ((headerAddress + 0x40u) & 0x200u) {
|
||||
this->_romStart = 0x200u;
|
||||
this->_size -= 0x200u;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -216,6 +213,11 @@ namespace ComSquare::Cartridge
|
||||
return this->_type;
|
||||
}
|
||||
|
||||
uint24_t Cartridge::getSize() const
|
||||
{
|
||||
return Ram::getSize() - this->_romStart;
|
||||
}
|
||||
|
||||
MappingMode operator|(const MappingMode &self, const MappingMode &other)
|
||||
{
|
||||
return static_cast<MappingMode>(static_cast<int>(self) | static_cast<int>(other));
|
||||
|
||||
@@ -138,6 +138,9 @@ namespace ComSquare::Cartridge
|
||||
//! @return The path of the currently loaded rom file.
|
||||
[[nodiscard]] std::filesystem::path getRomPath() const;
|
||||
|
||||
//! @brief Get the size of the rom in bytes (without the smc header).
|
||||
uint24_t getSize() const override;
|
||||
|
||||
//! @brief Load the rom at the given path
|
||||
//! @param rom The path of the rom.
|
||||
//! @throws InvalidRomException If the rom is invalid, this exception is thrown.
|
||||
|
||||
@@ -30,9 +30,10 @@ namespace ComSquare::Debugger::CPU
|
||||
this->_loadLabels(snes.cartridge.getRomPath());
|
||||
this->_ui.setupUi(this->_window);
|
||||
|
||||
|
||||
//Parse the first page of the ROM (the code can't reach the second page without a jump).
|
||||
uint16_t reset = snes.cartridge.header.emulationInterrupts.reset;
|
||||
this->_updateDisassembly(reset, 0xFFFF - reset);
|
||||
uint16_t resetInter = snes.cartridge.header.emulationInterrupts.reset;
|
||||
this->_updateDisassembly(resetInter, 0xFFFF - resetInter);
|
||||
|
||||
this->_ui.disassembly->setModel(&this->_model);
|
||||
this->_ui.disassembly->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
@@ -65,7 +66,9 @@ namespace ComSquare::Debugger::CPU
|
||||
this->_cpu.isDisabled = true;
|
||||
this->_callback = this->_cpu.onReset.addCallback([this] {
|
||||
this->disassembled.clear();
|
||||
this->_updateDisassembly(0xFFFF - this->_cpu._cartridgeHeader.emulationInterrupts.reset);
|
||||
//Parse the first page of the ROM (the code can't reach the second page without a jump).
|
||||
uint16_t reset = this->_snes.cartridge.header.emulationInterrupts.reset;
|
||||
this->_updateDisassembly(reset, 0xFFFF - reset);
|
||||
this->_updateRegistersPanel();
|
||||
});
|
||||
|
||||
@@ -220,16 +223,16 @@ namespace ComSquare::Debugger::CPU
|
||||
auto end = std::find_if(this->disassembled.begin(), this->disassembled.end(), [start, refreshSize](DisassembledInstruction &i) {
|
||||
return i.address >= start + refreshSize;
|
||||
});
|
||||
this->disassembled.erase(first, end);
|
||||
auto next = this->disassembled.erase(first, end);
|
||||
|
||||
auto next = std::find_if(this->disassembled.begin(), this->disassembled.end(), [start](DisassembledInstruction &i) {
|
||||
return i.address >= start;
|
||||
});
|
||||
DisassemblyContext ctx = this->_getDisassemblyContext();
|
||||
std::vector<DisassembledInstruction> nextInstructions = this->_disassemble(start, refreshSize, ctx);
|
||||
this->disassembled.insert(next, nextInstructions.begin(), nextInstructions.end());
|
||||
auto inserted = this->disassembled.insert(next, nextInstructions.begin(), nextInstructions.end());
|
||||
|
||||
int row = static_cast<int>(next - this->disassembled.begin());
|
||||
if (this->disassembled.empty())
|
||||
return;
|
||||
|
||||
int row = static_cast<int>(inserted - this->disassembled.begin());
|
||||
if (this->_ui.disassembly->rowAt(0) > row || this->_ui.disassembly->rowAt(this->_ui.disassembly->height()) < row) {
|
||||
auto index = this->_model.index(row, 0);
|
||||
this->_ui.disassembly->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
||||
@@ -260,9 +263,12 @@ namespace ComSquare::Debugger::CPU
|
||||
std::string CPUDebug::getProceededParameters() const
|
||||
{
|
||||
uint24_t pac = this->_cpu._registers.pac;
|
||||
auto &bus = this->_cpu.getBus();
|
||||
this->_cpu.setBus(this->_snes.bus);
|
||||
const Instruction &instruction = this->_cpu.instructions[this->_cpu._readPC()];
|
||||
uint24_t valueAddr = this->_cpu._getValueAddr(instruction);
|
||||
this->_cpu._registers.pac = pac;
|
||||
this->_cpu.setBus(bus);
|
||||
if (instruction.size == 1)
|
||||
return "";
|
||||
return "[" + Utility::to_hex(valueAddr, Utility::AsmPrefix) + "]";
|
||||
|
||||
@@ -172,8 +172,7 @@ namespace ComSquare::Debugger
|
||||
if (addr > accessor->getSize()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText(
|
||||
(std::string("The ") + accessor->getName() + " is too small to contain this address.").c_str());
|
||||
msgBox.setText((std::string("The ") + accessor->getName() + " is too small to contain this address.").c_str());
|
||||
msgBox.exec();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,22 +10,10 @@
|
||||
namespace ComSquare::Ram
|
||||
{
|
||||
Ram::Ram(size_t size, Component type, std::string ramName)
|
||||
: _size(size),
|
||||
_ramType(type),
|
||||
_ramName(std::move(ramName))
|
||||
{
|
||||
if (size == 0)
|
||||
this->_data = nullptr;
|
||||
else {
|
||||
this->_data = new uint8_t[size];
|
||||
std::memset(this->_data, 0, size * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
Ram::~Ram()
|
||||
{
|
||||
delete[] this->_data;
|
||||
}
|
||||
: _data(size),
|
||||
_ramType(type),
|
||||
_ramName(std::move(ramName))
|
||||
{ }
|
||||
|
||||
uint8_t &Ram::operator[](uint24_t addr)
|
||||
{
|
||||
@@ -40,21 +28,26 @@ namespace ComSquare::Ram
|
||||
uint8_t Ram::read(uint24_t addr)
|
||||
{
|
||||
// TODO read/write after the size of the rom should noop or behave like a mirror. I don't really know.
|
||||
if (addr >= this->_size)
|
||||
if (addr >= this->_data.size())
|
||||
throw InvalidAddress(this->getName() + " read", addr);
|
||||
return this->_data[addr];
|
||||
}
|
||||
|
||||
void Ram::write(uint24_t addr, uint8_t data)
|
||||
{
|
||||
if (addr >= this->_size)
|
||||
if (addr >= this->_data.size())
|
||||
throw InvalidAddress(this->getName() + " write", addr);
|
||||
this->_data[addr] = data;
|
||||
}
|
||||
|
||||
uint24_t Ram::getSize() const
|
||||
{
|
||||
return this->_size;
|
||||
return this->_data.size();
|
||||
}
|
||||
|
||||
void Ram::setSize(uint24_t size)
|
||||
{
|
||||
this->_data.resize(size);
|
||||
}
|
||||
|
||||
std::string Ram::getName() const
|
||||
@@ -67,8 +60,13 @@ namespace ComSquare::Ram
|
||||
return this->_ramType;
|
||||
}
|
||||
|
||||
uint8_t *Ram::getData() const
|
||||
std::span<uint8_t> Ram::getData()
|
||||
{
|
||||
return this->_data;
|
||||
return std::span(this->_data);
|
||||
}
|
||||
|
||||
std::span<const uint8_t> Ram::getData() const
|
||||
{
|
||||
return std::span(this->_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include "Memory/ARectangleMemory.hpp"
|
||||
#include <string>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
namespace ComSquare::Ram
|
||||
{
|
||||
@@ -13,9 +15,7 @@ namespace ComSquare::Ram
|
||||
{
|
||||
protected:
|
||||
//! @brief The ram. (Can be used for WRam, SRam, VRam etc)
|
||||
uint8_t *_data;
|
||||
//! @brief The size of the ram (in bytes).
|
||||
uint24_t _size;
|
||||
std::vector<uint8_t> _data;
|
||||
//! @brief An id identifying the type of memory this is (for the debugger)
|
||||
Component _ramType;
|
||||
//! @brief The name of this ram.
|
||||
@@ -28,7 +28,7 @@ namespace ComSquare::Ram
|
||||
//! @brief The ram can't be assigned.
|
||||
Ram &operator=(Ram &) = delete;
|
||||
//! @brief Destructor that free the ram.
|
||||
~Ram() override;
|
||||
~Ram() override = default;
|
||||
|
||||
//! @brief Read data from the component.
|
||||
//! @param addr The local address to read from (0x0 should refer to the first byte of this component).
|
||||
@@ -59,8 +59,16 @@ namespace ComSquare::Ram
|
||||
//! @brief Get the size of the ram in bytes.
|
||||
[[nodiscard]] uint24_t getSize() const override;
|
||||
|
||||
//! @brief Change the size of this ram.
|
||||
//! @brief size The new size of this ram.
|
||||
void setSize(uint24_t size);
|
||||
|
||||
//! @brief Get the raw data of the RAM
|
||||
//! @return A raw pointer to the data.
|
||||
[[nodiscard]] uint8_t *getData() const;
|
||||
//! @return A raw accessor to the data.
|
||||
[[nodiscard]] std::span<uint8_t> getData();
|
||||
|
||||
//! @brief Get the raw data of the RAM
|
||||
//! @return A raw accessor to the data.
|
||||
[[nodiscard]] std::span<const uint8_t> getData() const;
|
||||
};
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace ComSquare
|
||||
: bus(),
|
||||
cartridge(),
|
||||
wram(16384, WRam, "WRam"),
|
||||
sram(this->cartridge.header.sramSize, SRam, "SRam"),
|
||||
sram(0, SRam, "SRam"),
|
||||
cpu(this->bus, cartridge.header),
|
||||
ppu(renderer),
|
||||
apu(renderer)
|
||||
@@ -46,6 +46,7 @@ namespace ComSquare
|
||||
void SNES::loadRom(const std::string &path)
|
||||
{
|
||||
this->cartridge.loadRom(path);
|
||||
this->sram.setSize(this->cartridge.header.sramSize);
|
||||
this->bus.mapComponents(*this);
|
||||
this->cpu.RESB();
|
||||
this->apu.reset();
|
||||
|
||||
@@ -10,9 +10,7 @@ using namespace ComSquare;
|
||||
TEST_CASE("RomToVRAM DMA", "[DMA]")
|
||||
{
|
||||
Init()
|
||||
snes.cartridge._size = 4000000;
|
||||
delete[] snes.cartridge._data;
|
||||
snes.cartridge._data = new uint8_t[snes.cartridge._size];
|
||||
snes.cartridge._data.resize(4000000);
|
||||
for (unsigned i = 0; i < 0x400; i++) {
|
||||
snes.cartridge._data[0x9be00 + i * 2] = i;
|
||||
snes.cartridge._data[0x9be00 + i * 2 + 1] = i >> 8;
|
||||
|
||||
@@ -19,13 +19,7 @@
|
||||
Renderer::NoRenderer norenderer(0, 0, 0); \
|
||||
auto snesPtr = std::make_unique<SNES>(norenderer); \
|
||||
SNES &snes = *snesPtr; \
|
||||
snes.cartridge._size = 100; \
|
||||
delete[] snes.cartridge._data; \
|
||||
snes.cartridge._data = new uint8_t[snes.cartridge._size]; \
|
||||
memset(snes.cartridge._data, 0, snes.cartridge._size); \
|
||||
snes.cartridge._data.resize(100); \
|
||||
snes.cartridge.header.mappingMode = Cartridge::LoRom; \
|
||||
snes.sram._size = 100; \
|
||||
delete[] snes.sram._data; \
|
||||
snes.sram._data = new uint8_t[snes.sram._size]; \
|
||||
memset(snes.sram._data, 0, snes.cartridge._size); \
|
||||
snes.sram._data.resize(100); \
|
||||
snes.bus.mapComponents(snes);
|
||||
|
||||
Reference in New Issue
Block a user