bsnes/icarus/heuristics/famicom.cpp
Tim Allen 8f61c267c5 Update to v106r14 release.
byuu says:

Changelog:

  - game/memory/type/battery → game/memory/volatile
  - (manufacturer.)content.type → (architecture.)content.type
  - nall: Markup::find() strips spaces from values in comparisons
  - higan: updated game manifest loading/saving code for all cores
  - GBA: flash memory ID is internally selected based on the
    manufacturer and memory size
  - SFC: ST018 (ARM6) frequency can be modified via game manifest now
  - WS: EEPROM::name removed (not useful)
  - icarus, genius: battery→volatile updates

I did my best to look over the diff between r13 and r14, but it's 84KiB
excluding the game database changes. It's just too much for me. I'd
greatly appreciate if someone could look over it and check for any
errors in this update. But more than likely, I suppose we'll iron out
any issues by determining which games fail to load.

Right now, I know the Super Game Boy support doesn't seem to work. But
all non-SFC cores should work fully, and all normal + NEC DSP SFC games
should work as well. Unsure about the rest.

Also, I'm planning to change the Game Boy “MBC1M” mapper to “MBC1#A” to
indicate it's an alternate wiring configuration of the stock MBC1, and
not a new mapper type.
2018-04-15 15:49:53 +10:00

174 lines
4.4 KiB
C++

namespace Heuristics {
struct Famicom {
Famicom(vector<uint8_t>& data, string location);
explicit operator bool() const;
auto manifest() const -> string;
private:
vector<uint8_t>& data;
string location;
};
Famicom::Famicom(vector<uint8_t>& data, string location) : data(data), location(location) {
}
Famicom::operator bool() const {
if(data.size() < 16) return false;
if(data[0] != 'N') return false;
if(data[1] != 'E') return false;
if(data[2] != 'S') return false;
if(data[3] != 26) return false;
return true;
}
auto Famicom::manifest() const -> string {
if(!operator bool()) return {};
uint mapper = ((data[7] >> 4) << 4) | (data[6] >> 4);
uint mirror = ((data[6] & 0x08) >> 2) | (data[6] & 0x01);
uint prgrom = data[4] * 0x4000;
uint chrrom = data[5] * 0x2000;
uint prgram = 0u;
uint chrram = chrrom == 0u ? 8192u : 0u;
string output;
output.append("game\n");
output.append(" sha256: ", Hash::SHA256(&data[16], data.size() - 16).digest(), "\n");
output.append(" label: ", Location::prefix(location), "\n");
output.append(" name: ", Location::prefix(location), "\n");
switch(mapper) {
default:
output.append(" board: NES-NROM-256\n");
output.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
break;
case 1:
output.append(" board: NES-SXROM\n");
output.append(" chip type=MMC1B2\n");
prgram = 8192;
break;
case 2:
output.append(" board: NES-UOROM\n");
output.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
break;
case 3:
output.append(" board: NES-CNROM\n");
output.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
break;
case 4:
//MMC3
output.append(" board: NES-TLROM\n");
output.append(" chip type=MMC3B\n");
prgram = 8192;
//MMC6
//output.append(" board: NES-HKROM\n");
//output.append(" chip type=MMC6\n");
//prgram = 1024;
break;
case 5:
output.append(" board: NES-ELROM\n");
output.append(" chip type=MMC5\n");
prgram = 65536;
break;
case 7:
output.append(" board: NES-AOROM\n");
break;
case 9:
output.append(" board: NES-PNROM\n");
output.append(" chip type=MMC2\n");
prgram = 8192;
break;
case 10:
output.append(" board: NES-FKROM\n");
output.append(" chip type=MMC4\n");
prgram = 8192;
break;
case 16:
output.append(" board: BANDAI-FCG\n");
output.append(" chip type=LZ93D50\n");
break;
case 21:
case 23:
case 25:
//VRC4
output.append(" board: KONAMI-VRC-4\n");
output.append(" chip type=VRC4\n");
output.append(" pinout a0=1 a1=0\n");
prgram = 8192;
break;
case 22:
//VRC2
output.append(" board: KONAMI-VRC-2\n");
output.append(" chip type=VRC2\n");
output.append(" pinout a0=0 a1=1\n");
break;
case 24:
output.append(" board: KONAMI-VRC-6\n");
output.append(" chip type=VRC6\n");
break;
case 26:
output.append(" board: KONAMI-VRC-6\n");
output.append(" chip type=VRC6\n");
prgram = 8192;
break;
case 34:
output.append(" board: NES-BNROM\n");
output.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
break;
case 66:
output.append(" board: NES-GNROM\n");
output.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
break;
case 69:
output.append(" board: SUNSOFT-5B\n");
output.append(" chip type=5B\n");
prgram = 8192;
break;
case 73:
output.append(" board: KONAMI-VRC-3\n");
output.append(" chip type=VRC3\n");
output.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
prgram = 8192;
break;
case 75:
output.append(" board: KONAMI-VRC-1\n");
output.append(" chip type=VRC1\n");
break;
case 85:
output.append(" board: KONAMI-VRC-7\n");
output.append(" chip type=VRC7\n");
prgram = 8192;
break;
}
if(prgrom) output.append(Memory{}.type("ROM").size(prgrom).content("Program").text());
if(prgram) output.append(Memory{}.type("RAM").size(prgram).content("Save").text());
if(chrrom) output.append(Memory{}.type("ROM").size(chrrom).content("Character").text());
if(chrram) output.append(Memory{}.type("RAM").size(chrram).content("Character").isVolatile().text());
return output;
}
}