Merge pull request #539 from lesserkuma/master

Add support for more Game Boy mappers (MBC1M, MBC6, TAMA5, 8 MB MBC5)
This commit is contained in:
sanni 2022-09-28 22:22:58 +02:00 committed by GitHub
commit 01487b6759
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 536 additions and 175 deletions

View File

@ -40,7 +40,7 @@
And a special Thank You to all coders and contributors on Github and the Arduino forum: And a special Thank You to all coders and contributors on Github and the Arduino forum:
jiyunomegami, splash5, Kreeblah, ramapcsx2, PsyK0p4T, Dakkaron, majorpbx, Pickle, sdhizumi, jiyunomegami, splash5, Kreeblah, ramapcsx2, PsyK0p4T, Dakkaron, majorpbx, Pickle, sdhizumi,
Uzlopak, sakman55, Tombo89, scrap-a, borti4938, vogelfreiheit, CaitSith2, Modman, Uzlopak, sakman55, Tombo89, scrap-a, borti4938, vogelfreiheit, CaitSith2, Modman,
philenotfound, karimhadjsalem, nsx0r, ducky92, niklasweber, lesserkuma philenotfound, karimhadjsalem, nsx0r, ducky92, niklasweber, Lesserkuma
And to nocash for figuring out the secrets of the SFC Nintendo Power cartridge. And to nocash for figuring out the secrets of the SFC Nintendo Power cartridge.

View File

@ -23,7 +23,7 @@ static const char gbxMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsGBx[] PROGMEM = {gbxMenuItem1, gbxMenuItem2, gbxMenuItem3, gbxMenuItem4, gbxMenuItem5}; static const char* const menuOptionsGBx[] PROGMEM = {gbxMenuItem1, gbxMenuItem2, gbxMenuItem3, gbxMenuItem4, gbxMenuItem5};
// GB menu items // GB menu items
static const char GBMenuItem1[] PROGMEM = "Read Rom"; static const char GBMenuItem1[] PROGMEM = "Read ROM";
static const char GBMenuItem2[] PROGMEM = "Read Save"; static const char GBMenuItem2[] PROGMEM = "Read Save";
static const char GBMenuItem3[] PROGMEM = "Write Save"; static const char GBMenuItem3[] PROGMEM = "Write Save";
static const char GBMenuItem4[] PROGMEM = "Reset"; static const char GBMenuItem4[] PROGMEM = "Reset";
@ -309,10 +309,13 @@ void gbMenu() {
if (lastByte > 0) { if (lastByte > 0) {
// Change working dir to root // Change working dir to root
sd.chdir("/"); sd.chdir("/");
readSRAM_GB(); if (romType == 32)
readSRAMFLASH_MBC6_GB();
else
readSRAM_GB();
} }
else { else {
print_Error(F("Cart has no Sram"), false); print_Error(F("No save or unsupported type"), false);
} }
println_Msg(F("")); println_Msg(F(""));
break; break;
@ -325,22 +328,28 @@ void gbMenu() {
sd.chdir("/"); sd.chdir("/");
filePath[0] = '\0'; filePath[0] = '\0';
fileBrowser(F("Select sav file")); fileBrowser(F("Select sav file"));
writeSRAM_GB();
unsigned long wrErrors; if (romType == 32) {
wrErrors = verifySRAM_GB(); writeSRAMFLASH_MBC6_GB();
if (wrErrors == 0) {
println_Msg(F("Verified OK"));
display_Update();
} }
else { else {
print_Msg(F("Error: ")); writeSRAM_GB();
print_Msg(wrErrors); unsigned long wrErrors;
println_Msg(F(" bytes ")); wrErrors = verifySRAM_GB();
print_Error(F("did not verify."), false); if (wrErrors == 0) {
println_Msg(F("Verified OK"));
display_Update();
}
else {
print_Msg(F("Error: "));
print_Msg(wrErrors);
println_Msg(F(" bytes "));
print_Error(F("did not verify."), false);
}
} }
} }
else { else {
print_Error(F("Cart has no Sram"), false); print_Error(F("No save or unsupported type"), false);
} }
println_Msg(F("")); println_Msg(F(""));
break; break;
@ -399,11 +408,16 @@ void setup_GB() {
void showCartInfo_GB() { void showCartInfo_GB() {
display_Clear(); display_Clear();
if (strcmp(checksumStr, "00") != 0) { if (strcmp(checksumStr, "00") != 0) {
println_Msg(F("GB Cart Info")); print_Msg(F("Title: "));
print_Msg(F("Name: "));
println_Msg(romName); println_Msg(romName);
print_Msg(F("Mapper: ")); if (cartID[0] != 0) {
print_Msg(F("Serial: "));
println_Msg(cartID);
}
print_Msg(F("Revision: "));
println_Msg(romVersion);
print_Msg(F("Mapper: "));
if ((romType == 0) || (romType == 8) || (romType == 9)) if ((romType == 0) || (romType == 8) || (romType == 9))
print_Msg(F("none")); print_Msg(F("none"));
else if ((romType == 1) || (romType == 2) || (romType == 3)) else if ((romType == 1) || (romType == 2) || (romType == 3))
@ -418,91 +432,121 @@ void showCartInfo_GB() {
print_Msg(F("MBC4")); print_Msg(F("MBC4"));
else if ((romType == 25) || (romType == 26) || (romType == 27) || (romType == 28) || (romType == 29) || (romType == 309)) else if ((romType == 25) || (romType == 26) || (romType == 27) || (romType == 28) || (romType == 29) || (romType == 309))
print_Msg(F("MBC5")); print_Msg(F("MBC5"));
else if (romType == 32)
print_Msg(F("MBC6"));
else if (romType == 34) else if (romType == 34)
print_Msg(F("MBC7")); print_Msg(F("MBC7"));
else if (romType == 252) else if (romType == 252)
print_Msg(F("Camera")); print_Msg(F("Camera"));
else if (romType == 253)
print_Msg(F("TAMA5"));
else if (romType == 254) else if (romType == 254)
print_Msg(F("HuC-3")); print_Msg(F("HuC-3"));
else if (romType == 255) else if (romType == 255)
print_Msg(F("HuC-1")); print_Msg(F("HuC-1"));
else if ((romType == 0x101) || (romType == 0x103))
print_Msg(F("MBC1M"));
else if (romType == 0x104) else if (romType == 0x104)
print_Msg(F("M161")); print_Msg(F("M161"));
println_Msg(F(" ")); println_Msg(F(""));
print_Msg(F("Rom Size: ")); print_Msg(F("ROM Size: "));
switch (romSize) { switch (romSize) {
case 0: case 0:
print_Msg(F("32KB")); print_Msg(F("32 KB"));
break; break;
case 1: case 1:
print_Msg(F("64KB")); print_Msg(F("64 KB"));
break; break;
case 2: case 2:
print_Msg(F("128KB")); print_Msg(F("128 KB"));
break; break;
case 3: case 3:
print_Msg(F("256KB")); print_Msg(F("256 KB"));
break; break;
case 4: case 4:
print_Msg(F("512KB")); print_Msg(F("512 KB"));
break; break;
case 5: case 5:
print_Msg(F("1MB")); print_Msg(F("1 MB"));
break; break;
case 6: case 6:
print_Msg(F("2MB")); print_Msg(F("2 MB"));
break; break;
case 7: case 7:
print_Msg(F("4MB")); print_Msg(F("4 MB"));
break;
case 8:
print_Msg(F("8 MB"));
break; break;
} }
println_Msg(F("")); println_Msg(F(""));
print_Msg(F("Banks: ")); //print_Msg(F("Banks: "));
println_Msg(romBanks); //println_Msg(romBanks);
print_Msg(F("Sram Size: ")); print_Msg(F("Save Size: "));
switch (sramSize) { switch (sramSize) {
case 0: case 0:
if (romType == 6) { if (romType == 6) {
print_Msg(F("512B")); print_Msg(F("512 Byte"));
}
else if (romType == 0x22) {
if (strncmp(cartID, "KCEJ", 4) == 0) {
print_Msg(F("512 Byte"));
}
else {
print_Msg(F("256 Byte"));
}
}
else if (romType == 0xFD) {
print_Msg(F("32 Byte"));
} }
else { else {
print_Msg(F("none")); print_Msg(F("None"));
} }
break; break;
case 1: case 1:
print_Msg(F("2KB")); print_Msg(F("2 KB"));
break; break;
case 2: case 2:
print_Msg(F("8KB")); print_Msg(F("8 KB"));
break; break;
case 3: case 3:
print_Msg(F("32KB")); if (romType == 0x20) {
print_Msg(F("1.03 MB"));
} else {
print_Msg(F("32 KB"));
}
break; break;
case 4: case 4:
print_Msg(F("128KB")); print_Msg(F("128 KB"));
break; break;
default: print_Msg(F("none")); case 5:
print_Msg(F("64 KB"));
break;
default: print_Msg(F("None"));
} }
println_Msg(F("")); println_Msg(F(""));
print_Msg(F("Checksum: ")); //print_Msg(F("Checksum: "));
println_Msg(checksumStr); //println_Msg(checksumStr);
display_Update(); //display_Update();
// Wait for user input // Wait for user input
println_Msg(F(""));
println_Msg(F("Press Button...")); println_Msg(F("Press Button..."));
display_Update(); display_Update();
wait(); wait();
@ -562,7 +606,6 @@ void writeByte_GB(int myAddress, byte myData) {
// Pull WR(PH5) HIGH // Pull WR(PH5) HIGH
PORTH |= (1 << 5); PORTH |= (1 << 5);
// Leave WR high for at least 50ns // Leave WR high for at least 50ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
@ -620,7 +663,7 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
if (romType == 252) { if (romType == 252 || romType == 253) {
// Pull CS(PH3) LOW // Pull CS(PH3) LOW
PORTH &= ~(1 << 3); PORTH &= ~(1 << 3);
// Pull CLK(PH1)(for GB CAM) HIGH // Pull CLK(PH1)(for GB CAM) HIGH
@ -638,7 +681,7 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
// Leave WR low for at least 60ns // Leave WR low for at least 60ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
if (romType == 252) { if (romType == 252 || romType == 253) {
// Pull WR(PH5) HIGH // Pull WR(PH5) HIGH
PORTH |= (1 << 5); PORTH |= (1 << 5);
// Pull CS(PH3) HIGH // Pull CS(PH3) HIGH
@ -751,6 +794,9 @@ void getCartInfo_GB() {
case 0x07: case 0x07:
romBanks = 256; romBanks = 256;
break; break;
case 0x08:
romBanks = 512;
break;
default: default:
romBanks = 2; romBanks = 2;
} }
@ -787,7 +833,13 @@ void getCartInfo_GB() {
else if (sramSize > 1) { else if (sramSize > 1) {
lastByte = 0xBFFF; lastByte = 0xBFFF;
} }
// MBC6
if (romType == 32) {
sramBanks = 8;
lastByte = 0xAFFF;
}
// Get Checksum as string // Get Checksum as string
eepbit[6] = sdBuffer[0x14E]; eepbit[6] = sdBuffer[0x14E];
eepbit[7] = sdBuffer[0x14F]; eepbit[7] = sdBuffer[0x14F];
@ -811,6 +863,19 @@ void getCartInfo_GB() {
myLength++; myLength++;
} }
// Find Game Serial
cartID[0] = 0;
if (sdBuffer[0x143] == 0x80 || sdBuffer[0x143] == 0xC0) {
if ((romName[myLength - 4] == 'A' || romName[myLength - 4] == 'B' || romName[myLength - 4] == 'H' || romName[myLength - 4] == 'K' || romName[myLength - 4] == 'V') && (romName[myLength - 1] == 'A' || romName[myLength - 1] == 'B' || romName[myLength - 1] == 'D' || romName[myLength - 1] == 'E' || romName[myLength - 1] == 'F' || romName[myLength - 1] == 'I' || romName[myLength - 1] == 'J' || romName[myLength - 1] == 'K' || romName[myLength - 1] == 'P' || romName[myLength - 1] == 'S' || romName[myLength - 1] == 'U' || romName[myLength - 1] == 'X' || romName[myLength - 1] == 'Y')) {
cartID[0] = romName[myLength - 4];
cartID[1] = romName[myLength - 3];
cartID[2] = romName[myLength - 2];
cartID[3] = romName[myLength - 1];
myLength -= 4;
romName[myLength] = 0;
}
}
// Strip trailing white space // Strip trailing white space
for (unsigned int i = myLength - 1; i > 0; i--) { for (unsigned int i = myLength - 1; i > 0; i--) {
if ((romName[i] != 0x5F) && (romName[i] != 0x20)) break; if ((romName[i] != 0x5F) && (romName[i] != 0x20)) break;
@ -831,6 +896,20 @@ void getCartInfo_GB() {
(strncmp(romName, "RTYPE 2 SET", 11) == 0) && (sdBuffer[0x14D] == 0x32)) { (strncmp(romName, "RTYPE 2 SET", 11) == 0) && (sdBuffer[0x14D] == 0x32)) {
romType = 0x0B; romType = 0x0B;
} }
// MBC1M
if (
(strncmp(romName, "MOMOCOL", 7) == 0) && (sdBuffer[0x14D] == 0x28) ||
(strncmp(romName, "BOMCOL", 6) == 0) && (sdBuffer[0x14D] == 0x86) ||
(strncmp(romName, "GENCOL", 6) == 0) && (sdBuffer[0x14D] == 0x8A) ||
(strncmp(romName, "SUPERCHINESE 123", 16) == 0) && (sdBuffer[0x14D] == 0xE4) ||
(strncmp(romName, "MORTALKOMBATI&II", 16) == 0) && (sdBuffer[0x14D] == 0xB9) ||
(strncmp(romName, "MORTALKOMBAT DUO", 16) == 0) && (sdBuffer[0x14D] == 0xA7)) {
romType += 0x100;
}
// ROM revision
romVersion = sdBuffer[0x14C];
} }
/****************************************** /******************************************
@ -876,24 +955,61 @@ void readROM_GB() {
if (romType == 0x104) { if (romType == 0x104) {
startBank = 0; startBank = 0;
romBanks >>= 1; romBanks >>= 1;
endAddress = 0x7FFF;
}
// MBC6 banks are half size
else if (romType == 32) {
romBanks <<= 1;
endAddress = 0x3FFF;
} }
for (word currBank = startBank; currBank < romBanks; currBank++) { for (word currBank = startBank; currBank < romBanks; currBank++) {
// Second bank starts at 0x4000 // Second bank starts at 0x4000
if (currBank > 1) { if (currBank > 1) {
romAddress = 0x4000; romAddress = 0x4000;
// MBC6 banks are half size
if (romType == 32) {
endAddress = 0x5FFF;
}
} }
// M161 banks are double size and need mapper reset // Set ROM bank for M161
if (romType == 0x104) { if (romType == 0x104) {
romAddress = 0; romAddress = 0;
endAddress = 0x7FFF;
PORTH &= ~(1 << 0); PORTH &= ~(1 << 0);
delay(50); delay(50);
PORTH |= (1 << 0); PORTH |= (1 << 0);
writeByte_GB(0x4000, currBank & 0x7); writeByte_GB(0x4000, currBank & 0x7);
} }
// Set ROM bank for MBC1M
else if (romType == 0x101 || romType == 0x103) {
if (currBank < 10) {
writeByte_GB(0x4000, currBank >> 4);
writeByte_GB(0x2000, (currBank & 0x1f));
} else {
writeByte_GB(0x4000, currBank >> 4);
writeByte_GB(0x2000, 0x10 | (currBank & 0x1f));
}
}
// Set ROM bank for MBC6
else if (romType == 32) {
writeByte_GB(0x2800, 0);
writeByte_GB(0x3800, 0);
writeByte_GB(0x2000, currBank);
writeByte_GB(0x3000, currBank);
}
// Set ROM bank for TAMA5
else if (romType == 0xFD) {
writeByteSRAM_GB(0xA001, 0);
writeByteSRAM_GB(0xA000, currBank & 0x0f);
writeByteSRAM_GB(0xA001, 1);
writeByteSRAM_GB(0xA000, (currBank >> 4) & 0x0f);
}
// Set ROM bank for MBC2/3/4/5 // Set ROM bank for MBC2/3/4/5
else if (romType >= 5) { else if (romType >= 5) {
if (romType >= 11 && romType <= 13) { if (romType >= 11 && romType <= 13) {
@ -919,7 +1035,10 @@ void readROM_GB() {
} }
} }
else { else {
writeByte_GB(0x2100, currBank); if ((romType >= 0x19 && romType <= 0x1E) && (currBank == 0 || currBank == 256)) {
writeByte_GB(0x3000, (currBank >> 8) & 0xFF);
}
writeByte_GB(0x2100, currBank & 0xFF);
} }
} }
// Set ROM bank for MBC1 // Set ROM bank for MBC1
@ -992,15 +1111,15 @@ void compare_checksums_GB() {
char calcsumStr[5]; char calcsumStr[5];
sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder)); sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder));
print_Msg(F("Checksum: "));
print_Msg(calcsumStr);
if (strcmp(calcsumStr, checksumStr) == 0) { if (strcmp(calcsumStr, checksumStr) == 0) {
print_Msg(F("Internal: "));
print_Msg(calcsumStr);
println_Msg(F(" -> OK")); println_Msg(F(" -> OK"));
} }
else { else {
print_Msg(F("Internal: ")); print_Msg(F(" != "));
println_Msg(calcsumStr); println_Msg(checksumStr);
print_Error(F("Checksum Error"), false); print_Error(F("Invalid Checksum"), false);
} }
compareCRC("gb.txt", 0, 1, 0); compareCRC("gb.txt", 0, 1, 0);
display_Update(); display_Update();
@ -1171,6 +1290,243 @@ unsigned long verifySRAM_GB() {
} }
} }
// Read SRAM + FLASH save data of MBC6
void readSRAMFLASH_MBC6_GB() {
// Get name, add extension and convert to char array for sd lib
strcpy(fileName, romName);
strcat(fileName, ".sav");
// create a new folder for the save file
EEPROM_readAnything(0, foldern);
sprintf(folder, "GB/SAVE/%s/%d", romName, foldern);
sd.mkdir(folder, true);
sd.chdir(folder);
display_Clear();
print_Msg(F("Saving to "));
print_Msg(folder);
println_Msg(F("/..."));
display_Update();
// write new folder number back to eeprom
foldern = foldern + 1;
EEPROM_writeAnything(0, foldern);
//open file on sd card
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true);
}
//Initialize progress bar
uint32_t processedProgressBar = 0;
uint32_t totalProgressBar = 0x108000;
draw_progressbar(0, totalProgressBar);
// Enable Mapper and SRAM
writeByte_GB(0x0000, 0x0A);
// Switch SRAM banks
for (byte currBank = 0; currBank < sramBanks; currBank++) {
writeByte_GB(0x0400, currBank);
writeByte_GB(0x0800, currBank);
// Read SRAM
for (word sramAddress = 0xA000; sramAddress <= lastByte; sramAddress += 64) {
for (byte i = 0; i < 64; i++) {
sdBuffer[i] = readByteSRAM_GB(sramAddress + i);
}
myFile.write(sdBuffer, 64);
processedProgressBar += 64;
draw_progressbar(processedProgressBar, totalProgressBar);
}
}
// Disable SRAM
writeByte_GB(0x0000, 0x00);
// Enable flash save memory (map to ROM)
writeByte_GB(0x1000, 0x01);
writeByte_GB(0x0C00, 0x01);
writeByte_GB(0x1000, 0x00);
writeByte_GB(0x2800, 0x08);
writeByte_GB(0x3800, 0x08);
// Switch FLASH banks
for (byte currBank = 0; currBank < 128; currBank++) {
word romAddress = 0x4000;
writeByte_GB(0x2000, currBank);
writeByte_GB(0x3000, currBank);
// Read banks and save to SD
while (romAddress <= 0x5FFF) {
for (int i = 0; i < 512; i++) {
sdBuffer[i] = readByte_GB(romAddress + i);
}
myFile.write(sdBuffer, 512);
romAddress += 512;
processedProgressBar += 512;
draw_progressbar(processedProgressBar, totalProgressBar);
}
}
// Disable flash save memory
writeByte_GB(0x1000, 0x01);
writeByte_GB(0x0C00, 0x00);
writeByte_GB(0x1000, 0x00);
writeByte_GB(0x2800, 0x00);
writeByte_GB(0x3800, 0x00);
// Close the file:
myFile.close();
// Signal end of process
println_Msg(F("OK"));
display_Update();
}
// Write RAM
void writeSRAMFLASH_MBC6_GB() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName);
//open file on sd card
if (myFile.open(filePath, O_READ)) {
display_Clear();
println_Msg(F("Writing MBC6 save..."));
display_Update();
//Initialize progress bar
uint32_t processedProgressBar = 0;
uint32_t totalProgressBar = 0x108000;
draw_progressbar(0, totalProgressBar);
// Enable Mapper and SRAM
writeByte_GB(0x0000, 0x0A);
// Switch SRAM banks
for (byte currBank = 0; currBank < sramBanks; currBank++) {
writeByte_GB(0x0400, currBank);
writeByte_GB(0x0800, currBank);
// Write SRAM
for (word sramAddress = 0xA000; sramAddress <= lastByte; sramAddress++) {
writeByteSRAM_GB(sramAddress, myFile.read());
}
processedProgressBar += (lastByte + 1) - 0xA000;
draw_progressbar(processedProgressBar, totalProgressBar);
}
// Disable SRAM
writeByte_GB(0x0000, 0x00);
// Enable flash save memory (map to ROM)
writeByte_GB(0x1000, 0x01);
writeByte_GB(0x0C00, 0x01);
writeByte_GB(0x1000, 0x01);
writeByte_GB(0x2800, 0x08);
writeByte_GB(0x3800, 0x08);
for (byte currBank = 0; currBank < 128; currBank++) {
word romAddress = 0x4000;
// Erase FLASH sector
if (((processedProgressBar - 0x8000) % 0x20000) == 0) {
writeByte_GB(0x2800, 0x08);
writeByte_GB(0x3800, 0x08);
writeByte_GB(0x2000, 0x01);
writeByte_GB(0x3000, 0x02);
writeByte_GB(0x7555, 0xAA);
writeByte_GB(0x4AAA, 0x55);
writeByte_GB(0x7555, 0x80);
writeByte_GB(0x7555, 0xAA);
writeByte_GB(0x4AAA, 0x55);
writeByte_GB(0x2800, 0x08);
writeByte_GB(0x3800, 0x08);
writeByte_GB(0x2000, currBank);
writeByte_GB(0x3000, currBank);
writeByte_GB(0x4000, 0x30);
byte lives = 100;
while (1) {
byte sr = readByte_GB(0x4000);
if (sr == 0x80) break;
delay(1);
if (lives-- <= 0) {
// Disable flash save memory
writeByte_GB(0x1000, 0x01);
writeByte_GB(0x0C00, 0x00);
writeByte_GB(0x1000, 0x00);
writeByte_GB(0x2800, 0x00);
writeByte_GB(0x3800, 0x00);
myFile.close();
display_Clear();
print_Error(F("Error erasing FLASH sector."), true);
}
}
}
else {
writeByte_GB(0x2800, 0x08);
writeByte_GB(0x3800, 0x08);
writeByte_GB(0x2000, currBank);
writeByte_GB(0x3000, currBank);
}
// Write to FLASH
while (romAddress <= 0x5FFF) {
writeByte_GB(0x2000, 0x01);
writeByte_GB(0x3000, 0x02);
writeByte_GB(0x7555, 0xAA);
writeByte_GB(0x4AAA, 0x55);
writeByte_GB(0x7555, 0xA0);
writeByte_GB(0x2800, 0x08);
writeByte_GB(0x3800, 0x08);
writeByte_GB(0x2000, currBank);
writeByte_GB(0x3000, currBank);
for (int i = 0; i < 128; i++) {
writeByte_GB(romAddress++, myFile.read());
}
writeByte_GB(romAddress - 1, 0x00);
byte lives = 100;
while (1) {
byte sr = readByte_GB(romAddress - 1);
if (sr == 0x80) break;
delay(1);
if (lives-- <= 0) {
// Disable flash save memory
writeByte_GB(0x1000, 0x01);
writeByte_GB(0x0C00, 0x00);
writeByte_GB(0x1000, 0x00);
writeByte_GB(0x2800, 0x00);
writeByte_GB(0x3800, 0x00);
myFile.close();
display_Clear();
print_Error(F("Error writing to FLASH."), true);
}
}
writeByte_GB(romAddress - 1, 0xF0);
processedProgressBar += 128;
draw_progressbar(processedProgressBar, totalProgressBar);
}
}
// Disable flash save memory
writeByte_GB(0x1000, 0x01);
writeByte_GB(0x0C00, 0x00);
writeByte_GB(0x1000, 0x00);
writeByte_GB(0x2800, 0x00);
writeByte_GB(0x3800, 0x00);
// Close the file:
myFile.close();
println_Msg(F("Save writing finished"));
display_Update();
}
else {
print_Error(F("File doesnt exist"), false);
}
}
/****************************************** /******************************************
29F016/29F032/29F033 flashrom functions 29F016/29F032/29F033 flashrom functions
*****************************************/ *****************************************/

View File

@ -13,7 +13,7 @@ boolean readType;
Menu Menu
*****************************************/ *****************************************/
// GBA menu items // GBA menu items
static const char GBAMenuItem1[] PROGMEM = "Read Rom"; static const char GBAMenuItem1[] PROGMEM = "Read ROM";
static const char GBAMenuItem2[] PROGMEM = "Read Save"; static const char GBAMenuItem2[] PROGMEM = "Read Save";
static const char GBAMenuItem3[] PROGMEM = "Write Save"; static const char GBAMenuItem3[] PROGMEM = "Write Save";
static const char GBAMenuItem4[] PROGMEM = "Force Savetype"; static const char GBAMenuItem4[] PROGMEM = "Force Savetype";
@ -22,12 +22,12 @@ static const char GBAMenuItem6[] PROGMEM = "Reset";
static const char* const menuOptionsGBA[] PROGMEM = {GBAMenuItem1, GBAMenuItem2, GBAMenuItem3, GBAMenuItem4, GBAMenuItem5, GBAMenuItem6}; static const char* const menuOptionsGBA[] PROGMEM = {GBAMenuItem1, GBAMenuItem2, GBAMenuItem3, GBAMenuItem4, GBAMenuItem5, GBAMenuItem6};
// Rom menu // Rom menu
static const char GBARomItem1[] PROGMEM = "1MB"; static const char GBARomItem1[] PROGMEM = "1 MB";
static const char GBARomItem2[] PROGMEM = "2MB"; static const char GBARomItem2[] PROGMEM = "2 MB";
static const char GBARomItem3[] PROGMEM = "4MB"; static const char GBARomItem3[] PROGMEM = "4 MB";
static const char GBARomItem4[] PROGMEM = "8MB"; static const char GBARomItem4[] PROGMEM = "8 MB";
static const char GBARomItem5[] PROGMEM = "16MB"; static const char GBARomItem5[] PROGMEM = "16 MB";
static const char GBARomItem6[] PROGMEM = "32MB"; static const char GBARomItem6[] PROGMEM = "32 MB";
static const char* const romOptionsGBA[] PROGMEM = {GBARomItem1, GBARomItem2, GBARomItem3, GBARomItem4, GBARomItem5, GBARomItem6}; static const char* const romOptionsGBA[] PROGMEM = {GBARomItem1, GBARomItem2, GBARomItem3, GBARomItem4, GBARomItem5, GBARomItem6};
// Save menu // Save menu
@ -35,8 +35,8 @@ static const char GBASaveItem1[] PROGMEM = "4K EEPROM";
static const char GBASaveItem2[] PROGMEM = "64K EEPROM"; static const char GBASaveItem2[] PROGMEM = "64K EEPROM";
static const char GBASaveItem3[] PROGMEM = "256K SRAM/FRAM"; static const char GBASaveItem3[] PROGMEM = "256K SRAM/FRAM";
static const char GBASaveItem4[] PROGMEM = "512K SRAM/FRAM"; static const char GBASaveItem4[] PROGMEM = "512K SRAM/FRAM";
static const char GBASaveItem5[] PROGMEM = "512K FLASHROM"; static const char GBASaveItem5[] PROGMEM = "512K FLASH";
static const char GBASaveItem6[] PROGMEM = "1M FLASHROM"; static const char GBASaveItem6[] PROGMEM = "1M FLASH";
static const char* const saveOptionsGBA[] PROGMEM = {GBASaveItem1, GBASaveItem2, GBASaveItem3, GBASaveItem4, GBASaveItem5, GBASaveItem6}; static const char* const saveOptionsGBA[] PROGMEM = {GBASaveItem1, GBASaveItem2, GBASaveItem3, GBASaveItem4, GBASaveItem5, GBASaveItem6};
void gbaMenu() { void gbaMenu() {
@ -175,7 +175,7 @@ void gbaMenu() {
break; break;
case 5: case 5:
// 1024K FLASH // 1M FLASH
saveType = 5; saveType = 5;
break; break;
} }
@ -217,7 +217,7 @@ void gbaMenu() {
case 5: case 5:
display_Clear(); display_Clear();
sd.chdir("/"); sd.chdir("/");
// 1024K FLASH (divided into two banks) // 1M FLASH (divided into two banks)
switchBank_GBA(0x0); switchBank_GBA(0x0);
setROM_GBA(); setROM_GBA();
readFLASH_GBA(1, 65536, 0); readFLASH_GBA(1, 65536, 0);
@ -278,7 +278,7 @@ void gbaMenu() {
break; break;
case 5: case 5:
// 1024K FLASH // 1M FLASH
saveType = 5; saveType = 5;
break; break;
} }
@ -351,10 +351,10 @@ void gbaMenu() {
idFlash_GBA(); idFlash_GBA();
resetFLASH_GBA(); resetFLASH_GBA();
print_Msg(F("Flashrom ID: ")); print_Msg(F("FLASH ID: "));
println_Msg(flashid); println_Msg(flashid);
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Flashrom Type: ")); println_Msg(F("FLASH Type: "));
if (strcmp(flashid, "1F3D") == 0) { if (strcmp(flashid, "1F3D") == 0) {
println_Msg(F("Atmel AT29LV512")); println_Msg(F("Atmel AT29LV512"));
} }
@ -508,7 +508,7 @@ void gbaMenu() {
break; break;
case 5: case 5:
// 1024K FLASH // 1M FLASH
saveType = 5; saveType = 5;
break; break;
} }
@ -543,48 +543,48 @@ void setup_GBA() {
display_Clear(); display_Clear();
// Print start page // Print start page
print_Msg(F("Name: ")); print_Msg(F("Title: "));
println_Msg(romName); println_Msg(romName);
print_Msg(F("Cart ID: ")); print_Msg(F("Serial: "));
println_Msg(cartID); println_Msg(cartID);
print_Msg(F("Rom Size: ")); print_Msg(F("Revision: "));
println_Msg(romVersion);
print_Msg(F("ROM Size: "));
if (cartSize == 0) if (cartSize == 0)
println_Msg(F("Unknown")); println_Msg(F("Unknown"));
else { else {
print_Msg(cartSize); print_Msg(cartSize);
println_Msg(F("MB")); println_Msg(F(" MB"));
} }
print_Msg(F("Save: ")); print_Msg(F("Save Type: "));
switch (saveType) switch (saveType)
{ {
case 0: case 0:
println_Msg(F("Unknown")); println_Msg(F("None/Unknown"));
break; break;
case 1: case 1:
println_Msg(F("4K Eeprom")); println_Msg(F("4K EEPROM"));
break; break;
case 2: case 2:
println_Msg(F("64K Eeprom")); println_Msg(F("64K EEPROM"));
break; break;
case 3: case 3:
println_Msg(F("256K Sram")); println_Msg(F("256K SRAM"));
break; break;
case 4: case 4:
println_Msg(F("512K Flash")); println_Msg(F("512K FLASH"));
break; break;
case 5: case 5:
println_Msg(F("1024K Flash")); println_Msg(F("1M FLASH"));
break; break;
} }
print_Msg(F("Checksum: ")); print_Msg(F("Header Checksum: "));
println_Msg(checksumStr); println_Msg(checksumStr);
print_Msg(F("Version: 1."));
println_Msg(romVersion);
// Wait for user input // Wait for user input
println_Msg(""); println_Msg("");
@ -921,12 +921,12 @@ void getCartInfo_GBA() {
// Print current database entry // Print current database entry
println_Msg(gamename); println_Msg(gamename);
print_Msg(F("Cart ID: ")); print_Msg(F("Serial: "));
println_Msg(tempStr); println_Msg(tempStr);
print_Msg(F("Rom Size: ")); print_Msg(F("ROM Size: "));
print_Msg(cartSize); print_Msg(cartSize);
println_Msg(F("MB")); println_Msg(F(" MB"));
print_Msg(F("Save: ")); print_Msg(F("Save Lib: "));
println_Msg(saveTypeStr); println_Msg(saveTypeStr);
#if defined(enable_OLED) #if defined(enable_OLED)
@ -1058,12 +1058,12 @@ void getCartInfo_GBA() {
Save types in Cart Reader Code Save types in Cart Reader Code
0 = Unknown or no save 0 = Unknown or no save
1 = 4k Eeprom 1 = 4K EEPROM
2 = 64K Eeprom 2 = 64K EEPROM
3 = 256K Sram 3 = 256K SRAM
4 = 512K Flash 4 = 512K FLASH
5 = 1024K Flash 5 = 1M FLASH
6 = 512K Sram 6 = 512K SRAM
*/ */
if (saveTypeStr[0] == 'N') { if (saveTypeStr[0] == 'N') {
@ -1083,7 +1083,7 @@ void getCartInfo_GBA() {
saveType = 1; saveType = 1;
// Reading 4kbit Eeprom as 64kbit just gives the same 8 bytes repeated // Reading 4kbit EEPROM as 64kbit just gives the same 8 bytes repeated
for (int currByte = 0; currByte < 512 - 8; currByte++) { for (int currByte = 0; currByte < 512 - 8; currByte++) {
if (sdBuffer[currByte] != sdBuffer[currByte + 8]) { if (sdBuffer[currByte] != sdBuffer[currByte + 8]) {
saveType = 2; saveType = 2;
@ -1161,7 +1161,7 @@ void readROM_GBA() {
// Calculate the checksum of the dumped rom // Calculate the checksum of the dumped rom
boolean compare_checksum_GBA () { boolean compare_checksum_GBA () {
print_Msg(F("Internal Checksum...")); print_Msg(F("Checksum: "));
display_Update(); display_Update();
strcpy(fileName, romName); strcpy(fileName, romName);
@ -1187,17 +1187,17 @@ boolean compare_checksum_GBA () {
// Turn into string // Turn into string
sprintf(calcChecksumStr, "%02X", calcChecksum); sprintf(calcChecksumStr, "%02X", calcChecksum);
print_Msg(calcChecksumStr);
if (strcmp(calcChecksumStr, checksumStr) == 0) { if (strcmp(calcChecksumStr, checksumStr) == 0) {
println_Msg(F("OK")); println_Msg(F(" -> OK"));
display_Update(); display_Update();
return 1; return 1;
} }
else { else {
println_Msg(""); print_Msg(F(" != "));
print_Msg(F("Result: ")); println_Msg(checksumStr);
println_Msg(calcChecksumStr); print_Error(F("Invalid Checksum"), false);
print_Error(F("Checksum Error"), false);
return 0; return 0;
} }
} }
@ -1963,7 +1963,7 @@ void writeEeprom_GBA(word eepSize) {
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
display_Clear(); display_Clear();
print_Msg(F("Writing eeprom...")); print_Msg(F("Writing EEPROM..."));
display_Update(); display_Update();
//open file on sd card //open file on sd card

View File

@ -70,7 +70,7 @@ static const char N64ContMenuItem4[] PROGMEM = "Reset";
static const char* const menuOptionsN64Controller[] PROGMEM = {N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, N64ContMenuItem4}; static const char* const menuOptionsN64Controller[] PROGMEM = {N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, N64ContMenuItem4};
// N64 cart menu items // N64 cart menu items
static const char N64CartMenuItem1[] PROGMEM = "Read Rom"; static const char N64CartMenuItem1[] PROGMEM = "Read ROM";
static const char N64CartMenuItem2[] PROGMEM = "Read Save"; static const char N64CartMenuItem2[] PROGMEM = "Read Save";
static const char N64CartMenuItem3[] PROGMEM = "Write Save"; static const char N64CartMenuItem3[] PROGMEM = "Write Save";
static const char N64CartMenuItem4[] PROGMEM = "Force Savetype"; static const char N64CartMenuItem4[] PROGMEM = "Force Savetype";
@ -85,12 +85,12 @@ static const char N64CRCMenuItem4[] PROGMEM = "Reset";
static const char* const menuOptionsN64CRC[] PROGMEM = {N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, N64CRCMenuItem4}; static const char* const menuOptionsN64CRC[] PROGMEM = {N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, N64CRCMenuItem4};
// Rom menu // Rom menu
static const char N64RomItem1[] PROGMEM = "4MB"; static const char N64RomItem1[] PROGMEM = "4 MB";
static const char N64RomItem2[] PROGMEM = "8MB"; static const char N64RomItem2[] PROGMEM = "8 MB";
static const char N64RomItem3[] PROGMEM = "12MB"; static const char N64RomItem3[] PROGMEM = "12 MB";
static const char N64RomItem4[] PROGMEM = "16MB"; static const char N64RomItem4[] PROGMEM = "16 MB";
static const char N64RomItem5[] PROGMEM = "32MB"; static const char N64RomItem5[] PROGMEM = "32 MB";
static const char N64RomItem6[] PROGMEM = "64MB"; static const char N64RomItem6[] PROGMEM = "64 MB";
static const char* const romOptionsN64[] PROGMEM = {N64RomItem1, N64RomItem2, N64RomItem3, N64RomItem4, N64RomItem5, N64RomItem6}; static const char* const romOptionsN64[] PROGMEM = {N64RomItem1, N64RomItem2, N64RomItem3, N64RomItem4, N64RomItem5, N64RomItem6};
// Save menu // Save menu
@ -98,21 +98,21 @@ static const char N64SaveItem1[] PROGMEM = "None";
static const char N64SaveItem2[] PROGMEM = "4K EEPROM"; static const char N64SaveItem2[] PROGMEM = "4K EEPROM";
static const char N64SaveItem3[] PROGMEM = "16K EEPROM"; static const char N64SaveItem3[] PROGMEM = "16K EEPROM";
static const char N64SaveItem4[] PROGMEM = "SRAM"; static const char N64SaveItem4[] PROGMEM = "SRAM";
static const char N64SaveItem5[] PROGMEM = "FLASHRAM"; static const char N64SaveItem5[] PROGMEM = "FLASH";
static const char* const saveOptionsN64[] PROGMEM = {N64SaveItem1, N64SaveItem2, N64SaveItem3, N64SaveItem4, N64SaveItem5}; static const char* const saveOptionsN64[] PROGMEM = {N64SaveItem1, N64SaveItem2, N64SaveItem3, N64SaveItem4, N64SaveItem5};
// Repro write buffer menu // Repro write buffer menu
static const char N64BufferItem1[] PROGMEM = "no buffer"; static const char N64BufferItem1[] PROGMEM = "No buffer";
static const char N64BufferItem2[] PROGMEM = "32 Byte"; static const char N64BufferItem2[] PROGMEM = "32 Byte";
static const char N64BufferItem3[] PROGMEM = "64 Byte"; static const char N64BufferItem3[] PROGMEM = "64 Byte";
static const char N64BufferItem4[] PROGMEM = "128 Byte"; static const char N64BufferItem4[] PROGMEM = "128 Byte";
static const char* const bufferOptionsN64[] PROGMEM = {N64BufferItem1, N64BufferItem2, N64BufferItem3, N64BufferItem4}; static const char* const bufferOptionsN64[] PROGMEM = {N64BufferItem1, N64BufferItem2, N64BufferItem3, N64BufferItem4};
// Repro sector size menu // Repro sector size menu
static const char N64SectorItem1[] PROGMEM = "8 KByte"; static const char N64SectorItem1[] PROGMEM = "8 KB";
static const char N64SectorItem2[] PROGMEM = "32 KByte"; static const char N64SectorItem2[] PROGMEM = "32 KB";
static const char N64SectorItem3[] PROGMEM = "64 KByte"; static const char N64SectorItem3[] PROGMEM = "64 KB";
static const char N64SectorItem4[] PROGMEM = "128 KByte"; static const char N64SectorItem4[] PROGMEM = "128 KB";
static const char* const sectorOptionsN64[] PROGMEM = {N64SectorItem1, N64SectorItem2, N64SectorItem3, N64SectorItem4}; static const char* const sectorOptionsN64[] PROGMEM = {N64SectorItem1, N64SectorItem2, N64SectorItem3, N64SectorItem4};
// N64 start menu // N64 start menu
@ -252,18 +252,18 @@ void n64CartMenu() {
display_Clear(); display_Clear();
if (saveType == 1) { if (saveType == 1) {
println_Msg(F("Reading Sram...")); println_Msg(F("Reading SRAM..."));
display_Update(); display_Update();
readSram(32768, 1); readSram(32768, 1);
} }
else if (saveType == 4) { else if (saveType == 4) {
getFramType(); getFramType();
println_Msg(F("Reading Flashram...")); println_Msg(F("Reading FLASH..."));
display_Update(); display_Update();
readFram(flashramType); readFram(flashramType);
} }
else if ((saveType == 5) || (saveType == 6)) { else if ((saveType == 5) || (saveType == 6)) {
println_Msg(F("Reading Eep...")); println_Msg(F("Reading EEPROM..."));
display_Update(); display_Update();
#ifdef clockgen_installed #ifdef clockgen_installed
readEeprom(); readEeprom();
@ -291,7 +291,7 @@ void n64CartMenu() {
writeSram(32768); writeSram(32768);
writeErrors = verifySram(32768, 1); writeErrors = verifySram(32768, 1);
if (writeErrors == 0) { if (writeErrors == 0) {
println_Msg(F("Sram verified OK")); println_Msg(F("SRAM verified OK"));
display_Update(); display_Update();
} }
else { else {
@ -336,7 +336,7 @@ void n64CartMenu() {
#endif #endif
if (writeErrors == 0) { if (writeErrors == 0) {
println_Msg(F("Eeprom verified OK")); println_Msg(F("EEPROM verified OK"));
display_Update(); display_Update();
} }
else { else {
@ -348,7 +348,7 @@ void n64CartMenu() {
} }
else { else {
display_Clear(); display_Clear();
print_Error(F("Savetype Error"), false); print_Error(F("Save Type Error"), false);
} }
println_Msg(F("Press Button...")); println_Msg(F("Press Button..."));
display_Update(); display_Update();
@ -2445,37 +2445,38 @@ void printCartInfo_N64() {
// Print start page // Print start page
if (cartSize != 0) { if (cartSize != 0) {
display_Clear(); display_Clear();
println_Msg(F("N64 Cartridge Info")); print_Msg(F("Title: "));
println_Msg(F(""));
print_Msg(F("Name: "));
println_Msg(romName); println_Msg(romName);
print_Msg(F("ID: ")); print_Msg(F("Serial: "));
print_Msg(cartID); println_Msg(cartID);
print_Msg(F(" Size: ")); print_Msg(F("Revision: "));
println_Msg(romVersion);
print_Msg(F("ROM Size: "));
print_Msg(cartSize); print_Msg(cartSize);
println_Msg(F("MB")); println_Msg(F(" MB"));
print_Msg(F("Save: ")); print_Msg(F("Save Type: "));
switch (saveType) { switch (saveType) {
case 1: case 1:
println_Msg(F("Sram")); println_Msg(F("SRAM"));
break; break;
case 4: case 4:
println_Msg(F("Flashram")); println_Msg(F("FLASH"));
break; break;
case 5: case 5:
println_Msg(F("4K Eeprom")); println_Msg(F("4K EEPROM"));
eepPages = 64; eepPages = 64;
break; break;
case 6: case 6:
println_Msg(F("16K Eeprom")); println_Msg(F("16K EEPROM"));
eepPages = 256; eepPages = 256;
break; break;
default: default:
println_Msg(F("unknown")); println_Msg(F("None/Unknown"));
break; break;
} }
print_Msg(F("Version: 1."));
println_Msg(romVersion); print_Msg(F("CRC1: "));
println_Msg(checksumStr);
// Wait for user input // Wait for user input
println_Msg(F(" ")); println_Msg(F(" "));
@ -2488,9 +2489,9 @@ void printCartInfo_N64() {
display_Clear(); display_Clear();
println_Msg(F("GAMEPAK ERROR")); println_Msg(F("GAMEPAK ERROR"));
println_Msg(""); println_Msg("");
print_Msg(F("Name: ")); print_Msg(F("Title: "));
println_Msg(romName); println_Msg(romName);
print_Msg(F("ID: ")); print_Msg(F("Serial: "));
println_Msg(cartID); println_Msg(cartID);
print_Msg(F("CRC1: ")); print_Msg(F("CRC1: "));
println_Msg(checksumStr); println_Msg(checksumStr);
@ -3984,24 +3985,24 @@ void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElaps
myFile.print(F("Size\t: ")); myFile.print(F("Size\t: "));
myFile.print(cartSize); myFile.print(cartSize);
myFile.println(F("MB")); myFile.println(F(" MB"));
myFile.print(F("Save\t: ")); myFile.print(F("Save\t: "));
switch (saveType) { switch (saveType) {
case 1: case 1:
myFile.println(F("Sram")); myFile.println(F("SRAM"));
break; break;
case 4: case 4:
myFile.println(F("Flashram")); myFile.println(F("FLASH"));
break; break;
case 5: case 5:
myFile.println(F("4K Eeprom")); myFile.println(F("4K EEPROM"));
break; break;
case 6: case 6:
myFile.println(F("16K Eeprom")); myFile.println(F("16K EEPROM"));
break; break;
default: default:
myFile.println(F("unknown")); myFile.println(F("None/Unknown"));
break; break;
} }

View File

@ -43,7 +43,7 @@ static const char* const menuOptionsSNS[] PROGMEM = {snsMenuItem1, snsMenuItem2,
#endif #endif
// SNES menu items // SNES menu items
static const char SnesMenuItem1[] PROGMEM = "Read Rom"; static const char SnesMenuItem1[] PROGMEM = "Read ROM";
static const char SnesMenuItem2[] PROGMEM = "Read Save"; static const char SnesMenuItem2[] PROGMEM = "Read Save";
static const char SnesMenuItem3[] PROGMEM = "Write Save"; static const char SnesMenuItem3[] PROGMEM = "Write Save";
static const char SnesMenuItem4[] PROGMEM = "Test SRAM"; static const char SnesMenuItem4[] PROGMEM = "Test SRAM";
@ -54,17 +54,17 @@ static const char* const menuOptionsSNES[] PROGMEM = {SnesMenuItem1, SnesMenuIte
// Manual config menu items // Manual config menu items
static const char confMenuItem1[] PROGMEM = "Use header info"; static const char confMenuItem1[] PROGMEM = "Use header info";
static const char confMenuItem2[] PROGMEM = "4MB LoRom 256K Sram"; static const char confMenuItem2[] PROGMEM = "4MB LoROM 256K SRAM";
static const char confMenuItem3[] PROGMEM = "4MB HiRom 64K Sram"; static const char confMenuItem3[] PROGMEM = "4MB HiROM 64K SRAM";
static const char confMenuItem4[] PROGMEM = "6MB ExRom 256K Sram"; static const char confMenuItem4[] PROGMEM = "6MB ExROM 256K SRAM";
static const char confMenuItem5[] PROGMEM = "Reset"; static const char confMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsConfManual[] PROGMEM = {confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, confMenuItem5}; static const char* const menuOptionsConfManual[] PROGMEM = {confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, confMenuItem5};
// Repro menu items // Repro menu items
static const char reproMenuItem1[] PROGMEM = "LoRom (P0)"; static const char reproMenuItem1[] PROGMEM = "LoROM (P0)";
static const char reproMenuItem2[] PROGMEM = "HiRom (P0)"; static const char reproMenuItem2[] PROGMEM = "HiROM (P0)";
static const char reproMenuItem3[] PROGMEM = "ExLoRom (P1)"; static const char reproMenuItem3[] PROGMEM = "ExLoROM (P1)";
static const char reproMenuItem4[] PROGMEM = "ExHiRom (P1)"; static const char reproMenuItem4[] PROGMEM = "ExHiROM (P1)";
static const char reproMenuItem5[] PROGMEM = "Reset"; static const char reproMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsRepro[] PROGMEM = {reproMenuItem1, reproMenuItem2, reproMenuItem3, reproMenuItem4, reproMenuItem5}; static const char* const menuOptionsRepro[] PROGMEM = {reproMenuItem1, reproMenuItem2, reproMenuItem3, reproMenuItem4, reproMenuItem5};
@ -355,21 +355,21 @@ void confMenuManual() {
romType = LO; romType = LO;
numBanks = 128; numBanks = 128;
sramSize = 256; sramSize = 256;
strcpy(romName, "LOROM"); strcpy(romName, "LoROM");
break; break;
case 2: case 2:
romType = HI; romType = HI;
numBanks = 64; numBanks = 64;
sramSize = 64; sramSize = 64;
strcpy(romName, "HIROM"); strcpy(romName, "HiROM");
break; break;
case 3: case 3:
romType = EX; romType = EX;
numBanks = 96; numBanks = 96;
sramSize = 256; sramSize = 256;
strcpy(romName, "EXROM"); strcpy(romName, "ExROM");
break; break;
case 4: case 4:
@ -703,9 +703,12 @@ void getCartInfo_SNES() {
} }
display_Clear(); display_Clear();
print_Msg(F("Name: ")); print_Msg(F("Title: "));
println_Msg(romName); println_Msg(romName);
print_Msg(F("Revision: "));
println_Msg(romVersion);
print_Msg(F("Type: ")); print_Msg(F("Type: "));
if (romType == HI) if (romType == HI)
print_Msg(F("HiROM")); print_Msg(F("HiROM"));
@ -772,20 +775,23 @@ void getCartInfo_SNES() {
print_Msg(F("Rom Size: ")); print_Msg(F("Rom Size: "));
else else
print_Msg(F("ROM Size: ")); print_Msg(F("ROM Size: "));
print_Msg(romSize); if ((romSize >> 3) < 1) {
println_Msg(F("Mbit")); print_Msg(1024 * romSize >> 3);
print_Msg(F(" KB"));
print_Msg(F("Banks: ")); } else {
print_Msg(romSize >> 3);
print_Msg(F(" MB"));
}
print_Msg(F(" ("));
print_Msg(numBanks); print_Msg(numBanks);
print_Msg(F(" Chips: ")); println_Msg(F(" banks)"));
println_Msg(romChips);
//print_Msg(F("Chips: "));
//println_Msg(romChips);
print_Msg(F("Sram Size: ")); print_Msg(F("Save Size: "));
print_Msg(sramSize); print_Msg(sramSize >> 3);
println_Msg(F("Kbit")); println_Msg(F(" KB"));
print_Msg(F("ROM Version: 1."));
println_Msg(romVersion);
print_Msg(F("Checksum: ")); print_Msg(F("Checksum: "));
println_Msg(checksumStr); println_Msg(checksumStr);
@ -793,8 +799,6 @@ void getCartInfo_SNES() {
// Wait for user input // Wait for user input
#if (defined(enable_LCD) || defined(enable_OLED)) #if (defined(enable_LCD) || defined(enable_OLED))
println_Msg(F(" "));
println_Msg(F(" "));
println_Msg(F("Press Button...")); println_Msg(F("Press Button..."));
display_Update(); display_Update();
wait(); wait();
@ -1236,7 +1240,7 @@ unsigned int calc_checksum (char* fileName, char* folder) {
} }
boolean compare_checksum() { boolean compare_checksum() {
print_Msg(F("Checksum...")); print_Msg(F("Checksum... "));
display_Update(); display_Update();
strcpy(fileName, romName); strcpy(fileName, romName);
@ -1248,17 +1252,17 @@ boolean compare_checksum() {
char calcsumStr[5]; char calcsumStr[5];
sprintf(calcsumStr, "%04X", calc_checksum(fileName, folder)); sprintf(calcsumStr, "%04X", calc_checksum(fileName, folder));
print_Msg(calcsumStr);
if (strcmp(calcsumStr, checksumStr) == 0) { if (strcmp(calcsumStr, checksumStr) == 0) {
println_Msg(F("OK")); println_Msg(F(" -> OK"));
//println_Msg(calcsumStr);
display_Update(); display_Update();
return 1; return 1;
} }
else { else {
print_Msg(F("Error ")); print_Msg(F(" != "));
print_Msg(calcsumStr); println_Msg(checksumStr);
print_Error(F(" "), false); print_Error(F("Invalid Checksum"), false);
display_Update(); display_Update();
return 0; return 0;
} }