From d4b3046bbe127b407f010f2ae82e6eb49e840abf Mon Sep 17 00:00:00 2001 From: Melefo <42809472+Melefo@users.noreply.github.com> Date: Tue, 9 Mar 2021 10:39:54 +0100 Subject: [PATCH] Parsing header of SPC file format and stop update (for now) --- sources/Cartridge/Cartridge.cpp | 29 ++++++++++++++++++++++++++++- sources/Cartridge/Cartridge.hpp | 11 +++++++++++ sources/SNES.cpp | 3 +++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/sources/Cartridge/Cartridge.cpp b/sources/Cartridge/Cartridge.cpp index ead9363..cdbd5a5 100644 --- a/sources/Cartridge/Cartridge.cpp +++ b/sources/Cartridge/Cartridge.cpp @@ -98,13 +98,15 @@ namespace ComSquare::Cartridge uint32_t Cartridge::_getHeaderAddress() { - const std::vector address = {0x7FC0, 0xFFC0, 0x81C0, 0x101C0}; + const std::vector address = {0x7FC0, 0xFFC0}; + unsigned int smc = this->_size % 1024; int bestScore = -1; uint32_t bestAddress = 0; for (uint32_t addr : address) { int score = 0; + addr += smc; if (addr + 0x32u >= this->_size) continue; @@ -156,10 +158,30 @@ namespace ComSquare::Cartridge return bestAddress; } + bool Cartridge::_isSPCFile() + { + std::string str = std::string(reinterpret_cast(this->_data), 0x21); + + if (str != "SNES-SPC700 Sound File Data v0.30") + return false; + if (this->_data[0x21] != 0x1A || this->_data[0x22] != 0x1A) + return false; + if (this->_data[0x23] != 0x1A && this->_data[0x23] != 0x1B) + return false; + if (this->_data[0x24] != 0x1E) + return false; + return true; + } + bool Cartridge::_loadHeader() { + if (this->_isSPCFile()) { + this->_type = Audio; + return false; + } uint32_t headerAddress = this->_getHeaderAddress(); + this->_type = Game; this->header = this->_mapHeader(headerAddress); this->header.gameName = std::string(reinterpret_cast(&this->_data[headerAddress]), 21); if ((headerAddress + 0x40u) & 0x200u) { @@ -169,4 +191,9 @@ namespace ComSquare::Cartridge } return false; } + + CartridgeType Cartridge::getType() + { + return this->_type; + } } \ No newline at end of file diff --git a/sources/Cartridge/Cartridge.hpp b/sources/Cartridge/Cartridge.hpp index 90562e8..99f1639 100644 --- a/sources/Cartridge/Cartridge.hpp +++ b/sources/Cartridge/Cartridge.hpp @@ -13,6 +13,11 @@ namespace ComSquare::Cartridge { + enum CartridgeType { + Game, + Audio + }; + #define ADDMAPPINGMODE(x, flag) (x = static_cast(x | (flag))) enum MappingMode { LoRom = 1u << 0u, @@ -75,6 +80,8 @@ namespace ComSquare::Cartridge //! @brief Set the public variable header by parsing the header in the ROM. //! @return True if this cartridge has a SCM header, false otherwise. bool _loadHeader(); + //! @brief Check if the cartridge is not a game but a SPC audio dump + bool _isSPCFile(); //! @brief Get the address of the header. //! @return The address of this cartridge header. uint32_t _getHeaderAddress(); @@ -82,6 +89,8 @@ namespace ComSquare::Cartridge //! @param headerAddress The address you want to parse. //! @return A header struct representing the data at the memory address you passed. Header _mapHeader(uint32_t headerAddress); + //! @brief Current type of the cartridge + CartridgeType _type; public: //! @brief Load a rom from it's path. explicit Cartridge(const std::string &romPath); @@ -94,6 +103,8 @@ namespace ComSquare::Cartridge //! @brief The header of the cartridge. Header header; + //! @brief Return current type of the cartridge + CartridgeType getType(); //! @brief Read from the rom. //! @param addr The address to read from. The address 0x0 should refer to the first byte of the rom's memory. //! @throw InvalidAddress will be thrown if the address is more than the size of the rom's memory. diff --git a/sources/SNES.cpp b/sources/SNES.cpp index 3ad1cb4..0d2b9c3 100644 --- a/sources/SNES.cpp +++ b/sources/SNES.cpp @@ -28,6 +28,9 @@ namespace ComSquare void SNES::update() { + if (this->cartridge->getType() == Cartridge::Audio) + return; + unsigned cycleCount = this->cpu->update(); this->ppu->update(cycleCount); this->apu->update(cycleCount);