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:
jiyunomegami, splash5, Kreeblah, ramapcsx2, PsyK0p4T, Dakkaron, majorpbx, Pickle, sdhizumi,
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.

View File

@ -23,7 +23,7 @@ static const char gbxMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsGBx[] PROGMEM = {gbxMenuItem1, gbxMenuItem2, gbxMenuItem3, gbxMenuItem4, gbxMenuItem5};
// 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 GBMenuItem3[] PROGMEM = "Write Save";
static const char GBMenuItem4[] PROGMEM = "Reset";
@ -309,10 +309,13 @@ void gbMenu() {
if (lastByte > 0) {
// Change working dir to root
sd.chdir("/");
readSRAM_GB();
if (romType == 32)
readSRAMFLASH_MBC6_GB();
else
readSRAM_GB();
}
else {
print_Error(F("Cart has no Sram"), false);
print_Error(F("No save or unsupported type"), false);
}
println_Msg(F(""));
break;
@ -325,22 +328,28 @@ void gbMenu() {
sd.chdir("/");
filePath[0] = '\0';
fileBrowser(F("Select sav file"));
writeSRAM_GB();
unsigned long wrErrors;
wrErrors = verifySRAM_GB();
if (wrErrors == 0) {
println_Msg(F("Verified OK"));
display_Update();
if (romType == 32) {
writeSRAMFLASH_MBC6_GB();
}
else {
print_Msg(F("Error: "));
print_Msg(wrErrors);
println_Msg(F(" bytes "));
print_Error(F("did not verify."), false);
writeSRAM_GB();
unsigned long wrErrors;
wrErrors = verifySRAM_GB();
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 {
print_Error(F("Cart has no Sram"), false);
print_Error(F("No save or unsupported type"), false);
}
println_Msg(F(""));
break;
@ -399,11 +408,16 @@ void setup_GB() {
void showCartInfo_GB() {
display_Clear();
if (strcmp(checksumStr, "00") != 0) {
println_Msg(F("GB Cart Info"));
print_Msg(F("Name: "));
print_Msg(F("Title: "));
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))
print_Msg(F("none"));
else if ((romType == 1) || (romType == 2) || (romType == 3))
@ -418,91 +432,121 @@ void showCartInfo_GB() {
print_Msg(F("MBC4"));
else if ((romType == 25) || (romType == 26) || (romType == 27) || (romType == 28) || (romType == 29) || (romType == 309))
print_Msg(F("MBC5"));
else if (romType == 32)
print_Msg(F("MBC6"));
else if (romType == 34)
print_Msg(F("MBC7"));
else if (romType == 252)
print_Msg(F("Camera"));
else if (romType == 253)
print_Msg(F("TAMA5"));
else if (romType == 254)
print_Msg(F("HuC-3"));
else if (romType == 255)
print_Msg(F("HuC-1"));
else if ((romType == 0x101) || (romType == 0x103))
print_Msg(F("MBC1M"));
else if (romType == 0x104)
print_Msg(F("M161"));
println_Msg(F(" "));
print_Msg(F("Rom Size: "));
println_Msg(F(""));
print_Msg(F("ROM Size: "));
switch (romSize) {
case 0:
print_Msg(F("32KB"));
print_Msg(F("32 KB"));
break;
case 1:
print_Msg(F("64KB"));
print_Msg(F("64 KB"));
break;
case 2:
print_Msg(F("128KB"));
print_Msg(F("128 KB"));
break;
case 3:
print_Msg(F("256KB"));
print_Msg(F("256 KB"));
break;
case 4:
print_Msg(F("512KB"));
print_Msg(F("512 KB"));
break;
case 5:
print_Msg(F("1MB"));
print_Msg(F("1 MB"));
break;
case 6:
print_Msg(F("2MB"));
print_Msg(F("2 MB"));
break;
case 7:
print_Msg(F("4MB"));
print_Msg(F("4 MB"));
break;
case 8:
print_Msg(F("8 MB"));
break;
}
println_Msg(F(""));
print_Msg(F("Banks: "));
println_Msg(romBanks);
//print_Msg(F("Banks: "));
//println_Msg(romBanks);
print_Msg(F("Sram Size: "));
print_Msg(F("Save Size: "));
switch (sramSize) {
case 0:
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 {
print_Msg(F("none"));
print_Msg(F("None"));
}
break;
case 1:
print_Msg(F("2KB"));
print_Msg(F("2 KB"));
break;
case 2:
print_Msg(F("8KB"));
print_Msg(F("8 KB"));
break;
case 3:
print_Msg(F("32KB"));
if (romType == 0x20) {
print_Msg(F("1.03 MB"));
} else {
print_Msg(F("32 KB"));
}
break;
case 4:
print_Msg(F("128KB"));
print_Msg(F("128 KB"));
break;
default: print_Msg(F("none"));
case 5:
print_Msg(F("64 KB"));
break;
default: print_Msg(F("None"));
}
println_Msg(F(""));
print_Msg(F("Checksum: "));
println_Msg(checksumStr);
display_Update();
//print_Msg(F("Checksum: "));
//println_Msg(checksumStr);
//display_Update();
// Wait for user input
println_Msg(F(""));
println_Msg(F("Press Button..."));
display_Update();
wait();
@ -562,7 +606,6 @@ void writeByte_GB(int myAddress, byte myData) {
// Pull WR(PH5) HIGH
PORTH |= (1 << 5);
// Leave WR high for at least 50ns
__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");
if (romType == 252) {
if (romType == 252 || romType == 253) {
// Pull CS(PH3) LOW
PORTH &= ~(1 << 3);
// 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
__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
PORTH |= (1 << 5);
// Pull CS(PH3) HIGH
@ -751,6 +794,9 @@ void getCartInfo_GB() {
case 0x07:
romBanks = 256;
break;
case 0x08:
romBanks = 512;
break;
default:
romBanks = 2;
}
@ -787,7 +833,13 @@ void getCartInfo_GB() {
else if (sramSize > 1) {
lastByte = 0xBFFF;
}
// MBC6
if (romType == 32) {
sramBanks = 8;
lastByte = 0xAFFF;
}
// Get Checksum as string
eepbit[6] = sdBuffer[0x14E];
eepbit[7] = sdBuffer[0x14F];
@ -811,6 +863,19 @@ void getCartInfo_GB() {
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
for (unsigned int i = myLength - 1; i > 0; i--) {
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)) {
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) {
startBank = 0;
romBanks >>= 1;
endAddress = 0x7FFF;
}
// MBC6 banks are half size
else if (romType == 32) {
romBanks <<= 1;
endAddress = 0x3FFF;
}
for (word currBank = startBank; currBank < romBanks; currBank++) {
// Second bank starts at 0x4000
if (currBank > 1) {
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) {
romAddress = 0;
endAddress = 0x7FFF;
PORTH &= ~(1 << 0);
delay(50);
PORTH |= (1 << 0);
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
else if (romType >= 5) {
if (romType >= 11 && romType <= 13) {
@ -919,7 +1035,10 @@ void readROM_GB() {
}
}
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
@ -992,15 +1111,15 @@ void compare_checksums_GB() {
char calcsumStr[5];
sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder));
print_Msg(F("Checksum: "));
print_Msg(calcsumStr);
if (strcmp(calcsumStr, checksumStr) == 0) {
print_Msg(F("Internal: "));
print_Msg(calcsumStr);
println_Msg(F(" -> OK"));
}
else {
print_Msg(F("Internal: "));
println_Msg(calcsumStr);
print_Error(F("Checksum Error"), false);
print_Msg(F(" != "));
println_Msg(checksumStr);
print_Error(F("Invalid Checksum"), false);
}
compareCRC("gb.txt", 0, 1, 0);
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
*****************************************/

View File

@ -13,7 +13,7 @@ boolean readType;
Menu
*****************************************/
// 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 GBAMenuItem3[] PROGMEM = "Write Save";
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};
// Rom menu
static const char GBARomItem1[] PROGMEM = "1MB";
static const char GBARomItem2[] PROGMEM = "2MB";
static const char GBARomItem3[] PROGMEM = "4MB";
static const char GBARomItem4[] PROGMEM = "8MB";
static const char GBARomItem5[] PROGMEM = "16MB";
static const char GBARomItem6[] PROGMEM = "32MB";
static const char GBARomItem1[] PROGMEM = "1 MB";
static const char GBARomItem2[] PROGMEM = "2 MB";
static const char GBARomItem3[] PROGMEM = "4 MB";
static const char GBARomItem4[] PROGMEM = "8 MB";
static const char GBARomItem5[] PROGMEM = "16 MB";
static const char GBARomItem6[] PROGMEM = "32 MB";
static const char* const romOptionsGBA[] PROGMEM = {GBARomItem1, GBARomItem2, GBARomItem3, GBARomItem4, GBARomItem5, GBARomItem6};
// Save menu
@ -35,8 +35,8 @@ static const char GBASaveItem1[] PROGMEM = "4K EEPROM";
static const char GBASaveItem2[] PROGMEM = "64K EEPROM";
static const char GBASaveItem3[] PROGMEM = "256K SRAM/FRAM";
static const char GBASaveItem4[] PROGMEM = "512K SRAM/FRAM";
static const char GBASaveItem5[] PROGMEM = "512K FLASHROM";
static const char GBASaveItem6[] PROGMEM = "1M FLASHROM";
static const char GBASaveItem5[] PROGMEM = "512K FLASH";
static const char GBASaveItem6[] PROGMEM = "1M FLASH";
static const char* const saveOptionsGBA[] PROGMEM = {GBASaveItem1, GBASaveItem2, GBASaveItem3, GBASaveItem4, GBASaveItem5, GBASaveItem6};
void gbaMenu() {
@ -175,7 +175,7 @@ void gbaMenu() {
break;
case 5:
// 1024K FLASH
// 1M FLASH
saveType = 5;
break;
}
@ -217,7 +217,7 @@ void gbaMenu() {
case 5:
display_Clear();
sd.chdir("/");
// 1024K FLASH (divided into two banks)
// 1M FLASH (divided into two banks)
switchBank_GBA(0x0);
setROM_GBA();
readFLASH_GBA(1, 65536, 0);
@ -278,7 +278,7 @@ void gbaMenu() {
break;
case 5:
// 1024K FLASH
// 1M FLASH
saveType = 5;
break;
}
@ -351,10 +351,10 @@ void gbaMenu() {
idFlash_GBA();
resetFLASH_GBA();
print_Msg(F("Flashrom ID: "));
print_Msg(F("FLASH ID: "));
println_Msg(flashid);
println_Msg(F(""));
println_Msg(F("Flashrom Type: "));
println_Msg(F("FLASH Type: "));
if (strcmp(flashid, "1F3D") == 0) {
println_Msg(F("Atmel AT29LV512"));
}
@ -508,7 +508,7 @@ void gbaMenu() {
break;
case 5:
// 1024K FLASH
// 1M FLASH
saveType = 5;
break;
}
@ -543,48 +543,48 @@ void setup_GBA() {
display_Clear();
// Print start page
print_Msg(F("Name: "));
print_Msg(F("Title: "));
println_Msg(romName);
print_Msg(F("Cart ID: "));
print_Msg(F("Serial: "));
println_Msg(cartID);
print_Msg(F("Rom Size: "));
print_Msg(F("Revision: "));
println_Msg(romVersion);
print_Msg(F("ROM Size: "));
if (cartSize == 0)
println_Msg(F("Unknown"));
else {
print_Msg(cartSize);
println_Msg(F("MB"));
println_Msg(F(" MB"));
}
print_Msg(F("Save: "));
print_Msg(F("Save Type: "));
switch (saveType)
{
case 0:
println_Msg(F("Unknown"));
println_Msg(F("None/Unknown"));
break;
case 1:
println_Msg(F("4K Eeprom"));
println_Msg(F("4K EEPROM"));
break;
case 2:
println_Msg(F("64K Eeprom"));
println_Msg(F("64K EEPROM"));
break;
case 3:
println_Msg(F("256K Sram"));
println_Msg(F("256K SRAM"));
break;
case 4:
println_Msg(F("512K Flash"));
println_Msg(F("512K FLASH"));
break;
case 5:
println_Msg(F("1024K Flash"));
println_Msg(F("1M FLASH"));
break;
}
print_Msg(F("Checksum: "));
print_Msg(F("Header Checksum: "));
println_Msg(checksumStr);
print_Msg(F("Version: 1."));
println_Msg(romVersion);
// Wait for user input
println_Msg("");
@ -921,12 +921,12 @@ void getCartInfo_GBA() {
// Print current database entry
println_Msg(gamename);
print_Msg(F("Cart ID: "));
print_Msg(F("Serial: "));
println_Msg(tempStr);
print_Msg(F("Rom Size: "));
print_Msg(F("ROM Size: "));
print_Msg(cartSize);
println_Msg(F("MB"));
print_Msg(F("Save: "));
println_Msg(F(" MB"));
print_Msg(F("Save Lib: "));
println_Msg(saveTypeStr);
#if defined(enable_OLED)
@ -1058,12 +1058,12 @@ void getCartInfo_GBA() {
Save types in Cart Reader Code
0 = Unknown or no save
1 = 4k Eeprom
2 = 64K Eeprom
3 = 256K Sram
4 = 512K Flash
5 = 1024K Flash
6 = 512K Sram
1 = 4K EEPROM
2 = 64K EEPROM
3 = 256K SRAM
4 = 512K FLASH
5 = 1M FLASH
6 = 512K SRAM
*/
if (saveTypeStr[0] == 'N') {
@ -1083,7 +1083,7 @@ void getCartInfo_GBA() {
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++) {
if (sdBuffer[currByte] != sdBuffer[currByte + 8]) {
saveType = 2;
@ -1161,7 +1161,7 @@ void readROM_GBA() {
// Calculate the checksum of the dumped rom
boolean compare_checksum_GBA () {
print_Msg(F("Internal Checksum..."));
print_Msg(F("Checksum: "));
display_Update();
strcpy(fileName, romName);
@ -1187,17 +1187,17 @@ boolean compare_checksum_GBA () {
// Turn into string
sprintf(calcChecksumStr, "%02X", calcChecksum);
print_Msg(calcChecksumStr);
if (strcmp(calcChecksumStr, checksumStr) == 0) {
println_Msg(F("OK"));
println_Msg(F(" -> OK"));
display_Update();
return 1;
}
else {
println_Msg("");
print_Msg(F("Result: "));
println_Msg(calcChecksumStr);
print_Error(F("Checksum Error"), false);
print_Msg(F(" != "));
println_Msg(checksumStr);
print_Error(F("Invalid Checksum"), false);
return 0;
}
}
@ -1963,7 +1963,7 @@ void writeEeprom_GBA(word eepSize) {
sprintf(filePath, "%s/%s", filePath, fileName);
display_Clear();
print_Msg(F("Writing eeprom..."));
print_Msg(F("Writing EEPROM..."));
display_Update();
//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};
// 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 N64CartMenuItem3[] PROGMEM = "Write Save";
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};
// Rom menu
static const char N64RomItem1[] PROGMEM = "4MB";
static const char N64RomItem2[] PROGMEM = "8MB";
static const char N64RomItem3[] PROGMEM = "12MB";
static const char N64RomItem4[] PROGMEM = "16MB";
static const char N64RomItem5[] PROGMEM = "32MB";
static const char N64RomItem6[] PROGMEM = "64MB";
static const char N64RomItem1[] PROGMEM = "4 MB";
static const char N64RomItem2[] PROGMEM = "8 MB";
static const char N64RomItem3[] PROGMEM = "12 MB";
static const char N64RomItem4[] PROGMEM = "16 MB";
static const char N64RomItem5[] PROGMEM = "32 MB";
static const char N64RomItem6[] PROGMEM = "64 MB";
static const char* const romOptionsN64[] PROGMEM = {N64RomItem1, N64RomItem2, N64RomItem3, N64RomItem4, N64RomItem5, N64RomItem6};
// Save menu
@ -98,21 +98,21 @@ static const char N64SaveItem1[] PROGMEM = "None";
static const char N64SaveItem2[] PROGMEM = "4K EEPROM";
static const char N64SaveItem3[] PROGMEM = "16K EEPROM";
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};
// 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 N64BufferItem3[] PROGMEM = "64 Byte";
static const char N64BufferItem4[] PROGMEM = "128 Byte";
static const char* const bufferOptionsN64[] PROGMEM = {N64BufferItem1, N64BufferItem2, N64BufferItem3, N64BufferItem4};
// Repro sector size menu
static const char N64SectorItem1[] PROGMEM = "8 KByte";
static const char N64SectorItem2[] PROGMEM = "32 KByte";
static const char N64SectorItem3[] PROGMEM = "64 KByte";
static const char N64SectorItem4[] PROGMEM = "128 KByte";
static const char N64SectorItem1[] PROGMEM = "8 KB";
static const char N64SectorItem2[] PROGMEM = "32 KB";
static const char N64SectorItem3[] PROGMEM = "64 KB";
static const char N64SectorItem4[] PROGMEM = "128 KB";
static const char* const sectorOptionsN64[] PROGMEM = {N64SectorItem1, N64SectorItem2, N64SectorItem3, N64SectorItem4};
// N64 start menu
@ -252,18 +252,18 @@ void n64CartMenu() {
display_Clear();
if (saveType == 1) {
println_Msg(F("Reading Sram..."));
println_Msg(F("Reading SRAM..."));
display_Update();
readSram(32768, 1);
}
else if (saveType == 4) {
getFramType();
println_Msg(F("Reading Flashram..."));
println_Msg(F("Reading FLASH..."));
display_Update();
readFram(flashramType);
}
else if ((saveType == 5) || (saveType == 6)) {
println_Msg(F("Reading Eep..."));
println_Msg(F("Reading EEPROM..."));
display_Update();
#ifdef clockgen_installed
readEeprom();
@ -291,7 +291,7 @@ void n64CartMenu() {
writeSram(32768);
writeErrors = verifySram(32768, 1);
if (writeErrors == 0) {
println_Msg(F("Sram verified OK"));
println_Msg(F("SRAM verified OK"));
display_Update();
}
else {
@ -336,7 +336,7 @@ void n64CartMenu() {
#endif
if (writeErrors == 0) {
println_Msg(F("Eeprom verified OK"));
println_Msg(F("EEPROM verified OK"));
display_Update();
}
else {
@ -348,7 +348,7 @@ void n64CartMenu() {
}
else {
display_Clear();
print_Error(F("Savetype Error"), false);
print_Error(F("Save Type Error"), false);
}
println_Msg(F("Press Button..."));
display_Update();
@ -2445,37 +2445,38 @@ void printCartInfo_N64() {
// Print start page
if (cartSize != 0) {
display_Clear();
println_Msg(F("N64 Cartridge Info"));
println_Msg(F(""));
print_Msg(F("Name: "));
print_Msg(F("Title: "));
println_Msg(romName);
print_Msg(F("ID: "));
print_Msg(cartID);
print_Msg(F(" Size: "));
print_Msg(F("Serial: "));
println_Msg(cartID);
print_Msg(F("Revision: "));
println_Msg(romVersion);
print_Msg(F("ROM Size: "));
print_Msg(cartSize);
println_Msg(F("MB"));
print_Msg(F("Save: "));
println_Msg(F(" MB"));
print_Msg(F("Save Type: "));
switch (saveType) {
case 1:
println_Msg(F("Sram"));
println_Msg(F("SRAM"));
break;
case 4:
println_Msg(F("Flashram"));
println_Msg(F("FLASH"));
break;
case 5:
println_Msg(F("4K Eeprom"));
println_Msg(F("4K EEPROM"));
eepPages = 64;
break;
case 6:
println_Msg(F("16K Eeprom"));
println_Msg(F("16K EEPROM"));
eepPages = 256;
break;
default:
println_Msg(F("unknown"));
println_Msg(F("None/Unknown"));
break;
}
print_Msg(F("Version: 1."));
println_Msg(romVersion);
print_Msg(F("CRC1: "));
println_Msg(checksumStr);
// Wait for user input
println_Msg(F(" "));
@ -2488,9 +2489,9 @@ void printCartInfo_N64() {
display_Clear();
println_Msg(F("GAMEPAK ERROR"));
println_Msg("");
print_Msg(F("Name: "));
print_Msg(F("Title: "));
println_Msg(romName);
print_Msg(F("ID: "));
print_Msg(F("Serial: "));
println_Msg(cartID);
print_Msg(F("CRC1: "));
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(cartSize);
myFile.println(F("MB"));
myFile.println(F(" MB"));
myFile.print(F("Save\t: "));
switch (saveType) {
case 1:
myFile.println(F("Sram"));
myFile.println(F("SRAM"));
break;
case 4:
myFile.println(F("Flashram"));
myFile.println(F("FLASH"));
break;
case 5:
myFile.println(F("4K Eeprom"));
myFile.println(F("4K EEPROM"));
break;
case 6:
myFile.println(F("16K Eeprom"));
myFile.println(F("16K EEPROM"));
break;
default:
myFile.println(F("unknown"));
myFile.println(F("None/Unknown"));
break;
}

View File

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