V17B: Read header info even if checksum is corrupt

Some prototypes or hacked roms don't have a valid checksum in the header but still provide useful information like rom size.
This commit is contained in:
sanni 2016-07-13 09:14:28 +02:00 committed by GitHub
parent 050b499c64
commit 8cee474a3f
3 changed files with 114 additions and 99 deletions

View File

@ -2,8 +2,8 @@
Nintendo Cart Reader for Arduino Mega2560 Nintendo Cart Reader for Arduino Mega2560
Author: sanni Author: sanni
Date: 2016-07-11 Date: 2016-07-13
Version: V17A Version: V17B
SD lib: https://github.com/greiman/SdFat SD lib: https://github.com/greiman/SdFat
LCD lib: https://github.com/adafruit/Adafruit_SSD1306 LCD lib: https://github.com/adafruit/Adafruit_SSD1306
@ -29,7 +29,7 @@
Snes9x - SuperFX Sram Fix Snes9x - SuperFX Sram Fix
**********************************************************************************/ **********************************************************************************/
char ver[5] = "V17A"; char ver[5] = "V17B";
/****************************************** /******************************************
Choose Output Choose Output
@ -403,7 +403,6 @@ void mainMenu() {
// get input button // get input button
int b = checkButton(); int b = checkButton();
// Send some clock pulses to the Eeprom in case it locked up
// if the cart readers input button is pressed shortly // if the cart readers input button is pressed shortly
if (b == 1) { if (b == 1) {
asm volatile (" jmp 0"); asm volatile (" jmp 0");

View File

@ -126,7 +126,7 @@ void NPGameMenu() {
strcpy(romName, gameCode[gameSubMenu + 1]); strcpy(romName, gameCode[gameSubMenu + 1]);
// Print info // Print info
printStartPage(); getCartInfo_SNES();
mode = mode_NPGame; mode = mode_NPGame;
} }
else { else {
@ -139,7 +139,7 @@ void NPGameMenu() {
strcpy(romName, gameCode[0]); strcpy(romName, gameCode[0]);
// Print info // Print info
printStartPage(); getCartInfo_SNES();
mode = mode_NPGame; mode = mode_NPGame;
} }
} }

View File

@ -34,11 +34,12 @@ const char SnesMenuItem5[] PROGMEM = "Reset";
const char* const menuOptionsSNES[] PROGMEM = {SnesMenuItem1, SnesMenuItem2, SnesMenuItem3, SnesMenuItem4, SnesMenuItem5}; const char* const menuOptionsSNES[] PROGMEM = {SnesMenuItem1, SnesMenuItem2, SnesMenuItem3, SnesMenuItem4, SnesMenuItem5};
// Manual config menu items // Manual config menu items
const char confMenuItem1[] PROGMEM = "4MB LoRom 256K Sram"; const char confMenuItem1[] PROGMEM = "Use header info";
const char confMenuItem2[] PROGMEM = "4MB HiRom 64K Sram"; const char confMenuItem2[] PROGMEM = "4MB LoRom 256K Sram";
const char confMenuItem3[] PROGMEM = "6MB ExRom 256K Sram"; const char confMenuItem3[] PROGMEM = "4MB HiRom 64K Sram";
const char confMenuItem4[] PROGMEM = "Reset"; const char confMenuItem4[] PROGMEM = "6MB ExRom 256K Sram";
const char* const menuOptionsConf[] PROGMEM = {confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4}; const char confMenuItem5[] PROGMEM = "Reset";
const char* const menuOptionsConf[] PROGMEM = {confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, confMenuItem5};
// SNES Menu // SNES Menu
void snesMenu() { void snesMenu() {
@ -118,37 +119,40 @@ void snesMenu() {
// Menu for manual configuration // Menu for manual configuration
void confMenu() { void confMenu() {
// create menu with title and 4 options to choose from // create menu with title and 5 options to choose from
unsigned char subMenu; unsigned char subMenu;
// Copy menuOptions of of progmem // Copy menuOptions of of progmem
convertPgm(menuOptionsConf, 4); convertPgm(menuOptionsConf, 5);
subMenu = question_box("Choose mapping", menuOptions, 4, 0); subMenu = question_box("Choose mapping", menuOptions, 5, 0);
// wait for user choice to come back from the question box menu // wait for user choice to come back from the question box menu
switch (subMenu) switch (subMenu)
{ {
case 0: case 0:
break;
case 1:
romType = LO; romType = LO;
numBanks = 128; numBanks = 128;
sramSize = 256; sramSize = 256;
strcpy(romName, "LOROM"); strcpy(romName, "LOROM");
break; break;
case 1: case 2:
romType = HI; romType = HI;
numBanks = 64; numBanks = 64;
sramSize = 64; sramSize = 64;
strcpy(romName, "HIROM"); strcpy(romName, "HIROM");
break; break;
case 2: case 3:
romType = EX; romType = EX;
numBanks = 96; numBanks = 96;
sramSize = 256; sramSize = 256;
strcpy(romName, "EXROM"); strcpy(romName, "EXROM");
break; break;
case 3: case 4:
// Reset // Reset
asm volatile (" jmp 0"); asm volatile (" jmp 0");
break; break;
@ -237,7 +241,7 @@ void setup_Snes() {
delay(1000); delay(1000);
// Print all the info // Print all the info
printStartPage(); getCartInfo_SNES();
} }
/****************************************** /******************************************
@ -303,11 +307,17 @@ byte readBank_SNES(byte myBank, word myAddress) {
/****************************************** /******************************************
SNES ROM Functions SNES ROM Functions
******************************************/ ******************************************/
void printStartPage() { void getCartInfo_SNES() {
boolean manualConfig = 0;
// Print start page // Print start page
if (checkcart() == 0) { if (checkcart_SNES() == 0) {
display_Clear(); // Checksum either corrupt or 0000
manualConfig = 1;
errorLvl = 1;
rgb.setColor(255, 0, 0); rgb.setColor(255, 0, 0);
display_Clear();
println_Msg(F("ERROR")); println_Msg(F("ERROR"));
println_Msg(F("Rom header corrupt")); println_Msg(F("Rom header corrupt"));
println_Msg(F("or missing")); println_Msg(F("or missing"));
@ -318,86 +328,91 @@ void printStartPage() {
println_Msg(F("or powercycle if SA1")); println_Msg(F("or powercycle if SA1"));
display_Update(); display_Update();
wait(); wait();
confMenu(); // Wait() clears errors but in this case we still have an error
errorLvl = 1;
} }
else {
display_Clear();
print_Msg(F("Rom Name: "));
println_Msg(romName);
print_Msg(F("Type: ")); display_Clear();
if (romType == HI) print_Msg(F("Rom Name: "));
print_Msg(F("HiROM")); println_Msg(romName);
else if (romType == LO)
print_Msg(F("LoROM"));
else if (romType == EX)
print_Msg(F("ExHiRom"));
else
print_Msg(romType);
print_Msg(F(" "));
if (romSpeed == 0)
println_Msg(F("SlowROM"));
else if (romSpeed == 2)
println_Msg(F("SlowROM"));
else if (romSpeed == 3)
println_Msg(F("FastROM"));
else
println_Msg(romSpeed);
print_Msg(F("ICs: ROM ")); print_Msg(F("Type: "));
if (romChips == 0) if (romType == HI)
println_Msg(F("ONLY")); print_Msg(F("HiROM"));
else if (romChips == 1) else if (romType == LO)
println_Msg(F("RAM")); print_Msg(F("LoROM"));
else if (romChips == 2) else if (romType == EX)
println_Msg(F("SAVE")); print_Msg(F("ExHiRom"));
else if (romChips == 3) else
println_Msg(F("DSP1")); print_Msg(romType);
else if (romChips == 4) print_Msg(F(" "));
println_Msg(F("DSP1 RAM")); if (romSpeed == 0)
else if (romChips == 5) println_Msg(F("SlowROM"));
println_Msg(F("DSP1 SAVE")); else if (romSpeed == 2)
else if ((romChips == 19) || (romChips == 20) || (romChips == 21) || (romChips == 26)) println_Msg(F("SlowROM"));
println_Msg(F("SuperFX")); else if (romSpeed == 3)
else if (romChips == 52) { println_Msg(F("FastROM"));
println_Msg(F("SA1 RAM")); else
romType = SA; println_Msg(romSpeed);
}
else if (romChips == 53) {
println_Msg(F("SA1 RAM BATT"));
romType = SA;
}
else if (romChips == 227)
println_Msg(F("RAM GBoy"));
else if (romChips == 246)
println_Msg(F("DSP2"));
else
println_Msg(F(""));
print_Msg(F("Rom Size: ")); print_Msg(F("ICs: ROM "));
print_Msg(romSize); if (romChips == 0)
println_Msg(F("Mbit")); println_Msg(F("ONLY"));
else if (romChips == 1)
println_Msg(F("RAM"));
else if (romChips == 2)
println_Msg(F("SAVE"));
else if (romChips == 3)
println_Msg(F("DSP1"));
else if (romChips == 4)
println_Msg(F("DSP1 RAM"));
else if (romChips == 5)
println_Msg(F("DSP1 SAVE"));
else if ((romChips == 19) || (romChips == 20) || (romChips == 21) || (romChips == 26))
println_Msg(F("SuperFX"));
else if (romChips == 52) {
println_Msg(F("SA1 RAM"));
romType = SA;
}
else if (romChips == 53) {
println_Msg(F("SA1 RAM BATT"));
romType = SA;
}
else if (romChips == 227)
println_Msg(F("RAM GBoy"));
else if (romChips == 246)
println_Msg(F("DSP2"));
else
println_Msg(F(""));
print_Msg(F("Banks: ")); print_Msg(F("Rom Size: "));
println_Msg(numBanks); print_Msg(romSize);
println_Msg(F("Mbit"));
print_Msg(F("Sram Size: ")); print_Msg(F("Banks: "));
print_Msg(sramSize); println_Msg(numBanks);
println_Msg(F("Kbit"));
print_Msg(F("ROM Version: 1.")); print_Msg(F("Sram Size: "));
println_Msg(romVersion); print_Msg(sramSize);
println_Msg(F("Kbit"));
print_Msg(F("Checksum: ")); print_Msg(F("ROM Version: 1."));
println_Msg(checksumStr); println_Msg(romVersion);
display_Update();
// Wait for user input print_Msg(F("Checksum: "));
println_Msg(F(" ")); println_Msg(checksumStr);
println_Msg(F(" ")); display_Update();
println_Msg(F("Press Button..."));
display_Update(); // Wait for user input
wait(); println_Msg(F(" "));
println_Msg(F(" "));
println_Msg(F("Press Button..."));
display_Update();
wait();
// Start manual config
if (manualConfig == 1) {
confMenu();
} }
} }
@ -447,7 +462,7 @@ void checkAltConf() {
} }
// Read header information // Read header information
void getCartInfo_SNES() { boolean checkcart_SNES() {
// set control to read // set control to read
dataIn(); dataIn();
@ -533,17 +548,18 @@ void getCartInfo_SNES() {
// ROM Version // ROM Version
romVersion = readBank_SNES(0, 65499); romVersion = readBank_SNES(0, 65499);
}
boolean checkcart() { // Test if checksum is equal to reverse checksum
// If cart is present and checksum is equal to reverse checksum
if (((word(readBank_SNES(0, 65500)) + (word(readBank_SNES(0, 65501)) * 256)) + (word(readBank_SNES(0, 65502)) + (word(readBank_SNES(0, 65503)) * 256))) == 65535 ) { if (((word(readBank_SNES(0, 65500)) + (word(readBank_SNES(0, 65501)) * 256)) + (word(readBank_SNES(0, 65502)) + (word(readBank_SNES(0, 65503)) * 256))) == 65535 ) {
getCartInfo_SNES(); if (strcmp("0000", checksumStr) == 0) {
return 1; return 0;
}
else {
return 1;
}
} }
// Either rom checksum is wrong or no cart is inserted // Either rom checksum is wrong or no cart is inserted
else { else {
errorLvl = 1;
return 0; return 0;
} }
} }