Нет, вот, к примеру, как работает zsnes.Подозреваю что либо пофигу на заголовки, либо фиксят на лету.А как эмуляторы проблему обходят?
Берёт два адреса заголовка (Hi и Lo) и начинают там смотреть ключевые значение, у которых написаны пределы валидности (больше, меньше чего-то, равно чему-то), за каждое значение начисляется баллы, потом сравнивают, кто больше баллов набрал, так и узнает что Hi, а что Lo. Хотя не, если ищется способ определить Hi Lo, то вполне можно взять метод из zsnes'a, не очень трудоёмкий и вполне можно провести на консоли.
Code: Select all
Файл initc.c
int InfoScore(unsigned char *Buffer)
{
int score = valid_reset(Buffer);
if (validChecksum(Buffer, 0)) { score += 5; }
if (Buffer[CompanyOffset] == 0x33) { score += 3; }
if (!Buffer[ROMSizeOffset]) { score += 2; }
if ((1 << (Buffer[ROMSizeOffset] - 7)) > 48) { score -= 2; }
if ((8 << Buffer[SRAMSizeOffset]) > 1024) { score -= 2; }
if (Buffer[CountryOffset] < 14) { score += 2; }
if (!AllASCII(Buffer, 20)) { score -= 2; }
if (valid_normal_bank(Buffer[BSBankOffset])) { score += 2; }
return(score);
}
void BankCheck()
{
unsigned char *ROM = (unsigned char *)romdata;
infoloc = 0;
Interleaved = false;
if (NumofBytes < Lo)
{
romtype = 1;
infoloc = 1; //Whatever, we just need a valid location
}
if (NumofBytes < Hi)
{
romtype = 1;
infoloc = Lo;
}
if (NumofBytes >= 0x500000)
{
//Deinterleave if neccesary
CheckIntlEHi(ROM);
if (EHiHeader(ROM, EHi))
{
romtype = 2;
infoloc = EHi;
}
}
if (!infoloc)
{
static bool CommandLineForce2 = false;
int loscore, hiscore;
//Deinterleave if neccesary
CheckIntl1(ROM);
loscore = InfoScore(ROM+Lo);
hiscore = InfoScore(ROM+Hi);
switch(ROM[Lo + BankOffset])
{
case 32: case 35: case 48: case 50:
loscore += 3;
break;
}
switch(ROM[Hi + BankOffset])
{
case 33: case 49: case 53: case 58:
hiscore += 3;
break;
}
if (hiscore > loscore)
{
romtype = 2;
infoloc = Hi;
}
else
{
romtype = 1;
infoloc = Lo;
}
}
}
Ну и Масяня немного не прав по способы проверки в эмуляторах.