Adding a scoring system for the header address

This commit is contained in:
AnonymusRaccoon
2020-01-31 15:48:10 +01:00
parent 5d2a1e92d7
commit 53532ca44f
4 changed files with 134 additions and 18 deletions
+67 -13
View File
@@ -59,6 +59,54 @@ namespace ComSquare::Cartridge
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 address[] = {0x7FC0, 0xFFC0, 0x81C0, 0x101C0};
@@ -68,7 +116,23 @@ namespace ComSquare::Cartridge
for (uint32_t addr : address) {
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) {
bestScore = score;
bestAddress = addr;
@@ -79,23 +143,13 @@ namespace ComSquare::Cartridge
bool Cartridge::_loadHeader()
{
unsigned headerAddress = this->_getHeaderAddress();
uint32_t headerAddress = this->_getHeaderAddress();
this->header = this->_mapHeader(headerAddress);
char name[22];
std::memcpy(name, &this->_data[headerAddress], 21);
name[21] = '\0';
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;
}
}