mirror of
https://github.com/zoriya/ComSquare.git
synced 2025-12-23 15:45:26 +00:00
Adding a scoring system for the header address
This commit is contained in:
@@ -79,7 +79,7 @@ add_executable(ComSquare
|
|||||||
sources/Renderer/SFRenderer.hpp
|
sources/Renderer/SFRenderer.hpp
|
||||||
sources/Renderer/SFRenderer.cpp
|
sources/Renderer/SFRenderer.cpp
|
||||||
sources/Exceptions/InvalidAction.hpp
|
sources/Exceptions/InvalidAction.hpp
|
||||||
)
|
sources/Cartridge/InterruptVectors.hpp)
|
||||||
|
|
||||||
target_link_libraries(ComSquare
|
target_link_libraries(ComSquare
|
||||||
sfml-graphics
|
sfml-graphics
|
||||||
|
|||||||
@@ -59,6 +59,54 @@ namespace ComSquare::Cartridge
|
|||||||
throw InvalidAction("Witting to the ROM is not allowed.");
|
throw InvalidAction("Witting to the ROM is not allowed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Header Cartridge::_mapHeader(uint32_t headerAddress)
|
||||||
|
{
|
||||||
|
Header head;
|
||||||
|
headerAddress -= 0xC0u;
|
||||||
|
|
||||||
|
ADDMAPPINGMODE(head.mappingMode, this->_data[headerAddress + 0xD5u] & 0x10u ? FastRom : SlowRom);
|
||||||
|
ADDMAPPINGMODE(head.mappingMode, this->_data[headerAddress + 0xD5u] & 0x1u ? HiRom : LoRom);
|
||||||
|
if (this->_data[headerAddress + 0xD5u] & 0x2u || this->_data[headerAddress + 0xD5u] & 0x4u)
|
||||||
|
ADDMAPPINGMODE(head.mappingMode, ExRom);
|
||||||
|
head.romType = this->_data[headerAddress + 0xD6u];
|
||||||
|
head.romSize = 0x400u << this->_data[headerAddress + 0xD7u];
|
||||||
|
head.sramSize = 0x400u << this->_data[headerAddress + 0xD8u];
|
||||||
|
head.creatorIDs[0] = this->_data[headerAddress + 0xD9u];
|
||||||
|
head.creatorIDs[1] = this->_data[headerAddress + 0xDAu];
|
||||||
|
head.version = this->_data[headerAddress + 0xDBu];
|
||||||
|
head.checksumComplements[0] = this->_data[headerAddress + 0xDCu];
|
||||||
|
head.checksumComplements[1] = this->_data[headerAddress + 0xDDu];
|
||||||
|
head.checksums[0] = this->_data[headerAddress + 0xDEu];
|
||||||
|
head.checksums[1] = this->_data[headerAddress + 0xDFu];
|
||||||
|
|
||||||
|
head.nativeInterrupts.cop8[0] = this->_data[headerAddress + 0xE4u];
|
||||||
|
head.nativeInterrupts.cop8[1] = this->_data[headerAddress + 0xE5u];
|
||||||
|
head.nativeInterrupts.brk8[0] = this->_data[headerAddress + 0xE6u];
|
||||||
|
head.nativeInterrupts.brk8[1] = this->_data[headerAddress + 0xE7u];
|
||||||
|
head.nativeInterrupts.abort8[0] = this->_data[headerAddress + 0xE8u];
|
||||||
|
head.nativeInterrupts.abort8[1] = this->_data[headerAddress + 0xE9u];
|
||||||
|
head.nativeInterrupts.nmi8[0] = this->_data[headerAddress + 0xEAu];
|
||||||
|
head.nativeInterrupts.nmi8[1] = this->_data[headerAddress + 0xEBu];
|
||||||
|
head.nativeInterrupts.reset8[0] = this->_data[headerAddress + 0xECu];
|
||||||
|
head.nativeInterrupts.reset8[1] = this->_data[headerAddress + 0xEDu];
|
||||||
|
head.nativeInterrupts.irq8[0] = this->_data[headerAddress + 0xEEu];
|
||||||
|
head.nativeInterrupts.irq8[1] = this->_data[headerAddress + 0xEFu];
|
||||||
|
|
||||||
|
head.emulationInterrupts.cop8[0] = this->_data[headerAddress + 0xF4u];
|
||||||
|
head.emulationInterrupts.cop8[1] = this->_data[headerAddress + 0xF5u];
|
||||||
|
head.emulationInterrupts.abort8[0] = this->_data[headerAddress + 0xF8u];
|
||||||
|
head.emulationInterrupts.abort8[1] = this->_data[headerAddress + 0xF9u];
|
||||||
|
head.emulationInterrupts.nmi8[0] = this->_data[headerAddress + 0xFAu];
|
||||||
|
head.emulationInterrupts.nmi8[1] = this->_data[headerAddress + 0xFBu];
|
||||||
|
head.emulationInterrupts.reset8[0] = this->_data[headerAddress + 0xFCu];
|
||||||
|
head.emulationInterrupts.reset8[1] = this->_data[headerAddress + 0xFDu];
|
||||||
|
head.emulationInterrupts.brk8[0] = this->_data[headerAddress + 0xFEu];
|
||||||
|
head.emulationInterrupts.brk8[1] = this->_data[headerAddress + 0xFFu];
|
||||||
|
head.emulationInterrupts.irq8[0] = this->_data[headerAddress + 0xFEu];
|
||||||
|
head.emulationInterrupts.irq8[1] = this->_data[headerAddress + 0xFFu];
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t Cartridge::_getHeaderAddress()
|
uint32_t Cartridge::_getHeaderAddress()
|
||||||
{
|
{
|
||||||
uint32_t address[] = {0x7FC0, 0xFFC0, 0x81C0, 0x101C0};
|
uint32_t address[] = {0x7FC0, 0xFFC0, 0x81C0, 0x101C0};
|
||||||
@@ -68,7 +116,23 @@ namespace ComSquare::Cartridge
|
|||||||
for (uint32_t addr : address) {
|
for (uint32_t addr : address) {
|
||||||
int score = 0;
|
int score = 0;
|
||||||
|
|
||||||
// TODO Implement a scoring system for the address here.
|
if (addr + 0x32u >= this->_size)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Header info = this->_mapHeader(addr);
|
||||||
|
if (info.romType <= 0x8u)
|
||||||
|
score++;
|
||||||
|
if (info.romSize < 0x400u << 0x10u)
|
||||||
|
score++;
|
||||||
|
if (info.sramSize < 0x400u << 0x08u)
|
||||||
|
score++;
|
||||||
|
if (info.checksum + info.checksumComplement == 0xFFFF && info.checksum != 0 && info.checksumComplement != 0)
|
||||||
|
score += 8;
|
||||||
|
|
||||||
|
if (info.emulationInterrupts.reset <= 0x8000u) // The reset vector is the first thing called by the SNES so It must execute the code inside the ROM (the rom starts at 0x8000).
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
if (score > bestScore) {
|
if (score > bestScore) {
|
||||||
bestScore = score;
|
bestScore = score;
|
||||||
bestAddress = addr;
|
bestAddress = addr;
|
||||||
@@ -79,23 +143,13 @@ namespace ComSquare::Cartridge
|
|||||||
|
|
||||||
bool Cartridge::_loadHeader()
|
bool Cartridge::_loadHeader()
|
||||||
{
|
{
|
||||||
unsigned headerAddress = this->_getHeaderAddress();
|
uint32_t headerAddress = this->_getHeaderAddress();
|
||||||
|
|
||||||
|
this->header = this->_mapHeader(headerAddress);
|
||||||
char name[22];
|
char name[22];
|
||||||
std::memcpy(name, &this->_data[headerAddress], 21);
|
std::memcpy(name, &this->_data[headerAddress], 21);
|
||||||
name[21] = '\0';
|
name[21] = '\0';
|
||||||
this->header.gameName = std::string(name);
|
this->header.gameName = std::string(name);
|
||||||
ADDMAPPINGMODE(this->_data[headerAddress + 21] & 0x10u ? FastRom : SlowRom);
|
|
||||||
ADDMAPPINGMODE(this->_data[headerAddress + 21] & 0x1u ? HiRom : LoRom);
|
|
||||||
if (this->_data[headerAddress + 21] & 0x2u || this->_data[headerAddress + 210] & 0x4u)
|
|
||||||
ADDMAPPINGMODE(ExRom);
|
|
||||||
this->header.romType = this->_data[headerAddress + 22];
|
|
||||||
this->header.romSize = 0x400u << this->_data[headerAddress + 23];
|
|
||||||
this->header.sramSize = 0x400u << this->_data[headerAddress + 24];
|
|
||||||
this->header.creatorID = this->_data[headerAddress + 25];
|
|
||||||
this->header.version = this->_data[headerAddress + 27];
|
|
||||||
this->header.checksumComplement = this->_data[headerAddress + 28];
|
|
||||||
this->header.checksum = this->_data[headerAddress + 29];
|
|
||||||
return headerAddress & 0x200u;
|
return headerAddress & 0x200u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,10 +9,11 @@
|
|||||||
#include "../Memory/IMemory.hpp"
|
#include "../Memory/IMemory.hpp"
|
||||||
#include "../Models/Ints.hpp"
|
#include "../Models/Ints.hpp"
|
||||||
#include "../Memory/IRectangleMemory.hpp"
|
#include "../Memory/IRectangleMemory.hpp"
|
||||||
|
#include "InterruptVectors.hpp"
|
||||||
|
|
||||||
namespace ComSquare::Cartridge
|
namespace ComSquare::Cartridge
|
||||||
{
|
{
|
||||||
#define ADDMAPPINGMODE(flag) (this->header.mappingMode = static_cast<MappingMode>(this->header.mappingMode | (flag)))
|
#define ADDMAPPINGMODE(x, flag) (x = static_cast<MappingMode>(x | (flag)))
|
||||||
enum MappingMode {
|
enum MappingMode {
|
||||||
LoRom = 1u << 0u,
|
LoRom = 1u << 0u,
|
||||||
HiRom = 1u << 1u,
|
HiRom = 1u << 1u,
|
||||||
@@ -34,13 +35,26 @@ namespace ComSquare::Cartridge
|
|||||||
//! @brief The size of the SRom inside the cartridge.
|
//! @brief The size of the SRom inside the cartridge.
|
||||||
unsigned sramSize;
|
unsigned sramSize;
|
||||||
//! @brief Creator license ID code.
|
//! @brief Creator license ID code.
|
||||||
uint8_t creatorID;
|
union {
|
||||||
|
uint8_t creatorIDs[2];
|
||||||
|
uint16_t creatorID;
|
||||||
|
};
|
||||||
//! @brief The version of the game
|
//! @brief The version of the game
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
//! @brief Checksum complement
|
//! @brief Checksum complement
|
||||||
uint8_t checksumComplement;
|
union {
|
||||||
|
uint8_t checksumComplements[2];
|
||||||
|
uint16_t checksumComplement;
|
||||||
|
};
|
||||||
//! @brief Checksum
|
//! @brief Checksum
|
||||||
uint8_t checksum;
|
union {
|
||||||
|
uint8_t checksums[2];
|
||||||
|
uint16_t checksum;
|
||||||
|
};
|
||||||
|
//! @brief The interrupt vectors used to halt the CPU in native mode
|
||||||
|
InterruptVectors nativeInterrupts;
|
||||||
|
//! @brief The interrupt vectors used to halt the CPU in emulation mode
|
||||||
|
InterruptVectors emulationInterrupts;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! @brief Contains the rom's memory/instructions.
|
//! @brief Contains the rom's memory/instructions.
|
||||||
@@ -61,6 +75,10 @@ namespace ComSquare::Cartridge
|
|||||||
//! @brief Get the address of the header.
|
//! @brief Get the address of the header.
|
||||||
//! @return The address of this cartridge header.
|
//! @return The address of this cartridge header.
|
||||||
uint32_t _getHeaderAddress();
|
uint32_t _getHeaderAddress();
|
||||||
|
//! @brief Parse the memory to get a readable header.
|
||||||
|
//! @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);
|
||||||
public:
|
public:
|
||||||
//! @brief Load a rom from it's path.
|
//! @brief Load a rom from it's path.
|
||||||
explicit Cartridge(const std::string &romPath);
|
explicit Cartridge(const std::string &romPath);
|
||||||
|
|||||||
44
sources/Cartridge/InterruptVectors.hpp
Normal file
44
sources/Cartridge/InterruptVectors.hpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Created by anonymus-raccoon on 1/31/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COMSQUARE_INTERRUPTVECTORS_HPP
|
||||||
|
#define COMSQUARE_INTERRUPTVECTORS_HPP
|
||||||
|
|
||||||
|
namespace ComSquare::Cartridge
|
||||||
|
{
|
||||||
|
struct InterruptVectors {
|
||||||
|
//! @brief The Co-Processor enable vector.
|
||||||
|
union {
|
||||||
|
uint8_t cop8[2];
|
||||||
|
uint16_t cop;
|
||||||
|
};
|
||||||
|
//! @brief The Break vector.
|
||||||
|
union {
|
||||||
|
uint8_t brk8[2];
|
||||||
|
uint16_t brk;
|
||||||
|
};
|
||||||
|
//! @brief The Abort vector.
|
||||||
|
union {
|
||||||
|
uint8_t abort8[2];
|
||||||
|
uint16_t abort;
|
||||||
|
};
|
||||||
|
//! @brief The non-maskable interrupt (The V-Blank interrupt).
|
||||||
|
union {
|
||||||
|
uint8_t nmi8[2];
|
||||||
|
uint16_t nmi;
|
||||||
|
};
|
||||||
|
//! @brief The Reset vector (execution of the SNES starts with this reset vector in emulation mode).
|
||||||
|
union {
|
||||||
|
uint8_t reset8[2];
|
||||||
|
uint16_t reset;
|
||||||
|
};
|
||||||
|
//! @brief The Interrupt Request vector.
|
||||||
|
union {
|
||||||
|
uint8_t irq8[2];
|
||||||
|
uint16_t irq;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //COMSQUARE_INTERRUPTVECTORS_HPP
|
||||||
Reference in New Issue
Block a user