From ff758768df56559639e2fb07adcdb8dbe09b247b Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Sun, 25 Sep 2022 01:46:46 +0200 Subject: [PATCH 01/10] Add support for GB MBC5 8 MiB cartridges --- Cart_Reader/Cart_Reader.ino | 2 +- Cart_Reader/GB.ino | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index 61820a9..6e42ec0 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -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. diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index 072346f..3033bd4 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -463,6 +463,10 @@ void showCartInfo_GB() { case 7: print_Msg(F("4MB")); break; + + case 8: + print_Msg(F("8MB")); + break; } println_Msg(F("")); @@ -751,6 +755,9 @@ void getCartInfo_GB() { case 0x07: romBanks = 256; break; + case 0x08: + romBanks = 512; + break; default: romBanks = 2; } @@ -919,7 +926,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 From 140401161bc3d3ab50bd054a07e0d09a1eb855e7 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Sun, 25 Sep 2022 16:40:21 +0200 Subject: [PATCH 02/10] UI improvements for GB, GBA, N64, SNES --- Cart_Reader/GB.ino | 93 +++++++++++++++++++++++++++++--------------- Cart_Reader/GBA.ino | 72 +++++++++++++++++----------------- Cart_Reader/N64.ino | 85 ++++++++++++++++++++-------------------- Cart_Reader/SNES.ino | 70 +++++++++++++++++---------------- 4 files changed, 177 insertions(+), 143 deletions(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index 3033bd4..686e62b 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -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"; @@ -312,7 +312,7 @@ void gbMenu() { readSRAM_GB(); } else { - print_Error(F("Cart has no Sram"), false); + print_Error(F("No save or unsupported type"), false); } println_Msg(F("")); break; @@ -340,7 +340,7 @@ void gbMenu() { } } else { - print_Error(F("Cart has no Sram"), false); + print_Error(F("No save or unsupported type"), false); } println_Msg(F("")); break; @@ -399,11 +399,13 @@ 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: ")); + + 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,10 +420,14 @@ 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 (no support)")); else if (romType == 34) print_Msg(F("MBC7")); else if (romType == 252) print_Msg(F("Camera")); + else if (romType == 253) + print_Msg(F("TAMA5 (no support)")); else if (romType == 254) print_Msg(F("HuC-3")); else if (romType == 255) @@ -429,77 +435,96 @@ void showCartInfo_GB() { 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("8MB")); + 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(romName, "CMASTER_KCEJ", 12) == 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: ")); @@ -507,6 +532,7 @@ void showCartInfo_GB() { display_Update(); // Wait for user input + println_Msg(F("")); println_Msg(F("Press Button...")); display_Update(); wait(); @@ -838,6 +864,9 @@ void getCartInfo_GB() { (strncmp(romName, "RTYPE 2 SET", 11) == 0) && (sdBuffer[0x14D] == 0x32)) { romType = 0x0B; } + + // ROM revision + romVersion = sdBuffer[0x14C]; } /****************************************** @@ -1002,15 +1031,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(); diff --git a/Cart_Reader/GBA.ino b/Cart_Reader/GBA.ino index 2cacd24..02338c9 100644 --- a/Cart_Reader/GBA.ino +++ b/Cart_Reader/GBA.ino @@ -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,49 +543,49 @@ 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("Code: ")); 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(""); @@ -997,7 +997,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); @@ -1023,17 +1023,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; } } @@ -1799,7 +1799,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 diff --git a/Cart_Reader/N64.ino b/Cart_Reader/N64.ino index f0fa9e4..a4e6ead 100644 --- a/Cart_Reader/N64.ino +++ b/Cart_Reader/N64.ino @@ -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("Code: ")); + 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("Code: ")); 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; } diff --git a/Cart_Reader/SNES.ino b/Cart_Reader/SNES.ino index a535aee..8b1f46a 100644 --- a/Cart_Reader/SNES.ino +++ b/Cart_Reader/SNES.ino @@ -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; } From 866f0ce2b561b893c43618249cf5e11f7cb6e8b8 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Sun, 25 Sep 2022 16:51:05 +0200 Subject: [PATCH 03/10] Add support for the Game Boy MBC1M mapper --- Cart_Reader/GB.ino | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index 686e62b..90e36ea 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -432,6 +432,8 @@ void showCartInfo_GB() { 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")); @@ -865,6 +867,17 @@ void getCartInfo_GB() { 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]; } @@ -929,7 +942,18 @@ void readROM_GB() { 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 MBC2/3/4/5 else if (romType >= 5) { if (romType >= 11 && romType <= 13) { From 282f5bc1081984024bddbe3c3d3eb8e25d8e6ce5 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Sun, 25 Sep 2022 23:35:29 +0200 Subject: [PATCH 04/10] Add support for the Game Boy TAMA5 mapper (ROM read) --- Cart_Reader/GB.ino | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index b2cd4dd..eeb2293 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -427,7 +427,7 @@ void showCartInfo_GB() { else if (romType == 252) print_Msg(F("Camera")); else if (romType == 253) - print_Msg(F("TAMA5 (no support)")); + print_Msg(F("TAMA5")); else if (romType == 254) print_Msg(F("HuC-3")); else if (romType == 255) @@ -594,7 +594,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"); @@ -652,7 +651,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 @@ -670,7 +669,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 @@ -954,6 +953,14 @@ void readROM_GB() { } } + // 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) { From 38c2262f1c398677dd28ced1c2cae65f8b56bad1 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Wed, 28 Sep 2022 15:15:04 +0200 Subject: [PATCH 05/10] Add support for the Game Boy MBC6 mapper (ROM read) --- Cart_Reader/GB.ino | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index eeb2293..c0671d3 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -421,7 +421,7 @@ void showCartInfo_GB() { 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 (no support)")); + print_Msg(F("MBC6")); else if (romType == 34) print_Msg(F("MBC7")); else if (romType == 252) @@ -924,18 +924,28 @@ 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); @@ -953,6 +963,14 @@ void readROM_GB() { } } + // 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); From f7d9051b953f68ba5802a496f16d5cffcf9fcf9c Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Wed, 28 Sep 2022 18:00:16 +0200 Subject: [PATCH 06/10] Add support for the Game Boy MBC6 mapper (save read) --- Cart_Reader/GB.ino | 205 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 203 insertions(+), 2 deletions(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index c0671d3..a710cbc 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -309,7 +309,10 @@ void gbMenu() { if (lastByte > 0) { // Change working dir to root sd.chdir("/"); - readSRAM_GB(); + if (romType == 32) + readSRAMFLASH_GB_MBC6(); + else + readSRAM_GB(); } else { print_Error(F("No save or unsupported type"), false); @@ -821,7 +824,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]; @@ -1259,6 +1268,198 @@ unsigned long verifySRAM_GB() { } } +// Read SRAM + FLASH save data of MBC6 +void readSRAMFLASH_GB_MBC6() { + // 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); + + word romAddress = 0x4000; + for (byte currBank = 0; currBank < 128; currBank++) { + writeByte_GB(0x2800, 8); + writeByte_GB(0x3800, 8); + writeByte_GB(0x2000, currBank); + writeByte_GB(0x3000, currBank); + + romAddress = 0x4000; + // 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(); +} + +// Read SRAM + FLASH save data of MBC6 +void readSRAMFLASH_GB_MBC6() { + // 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); + + word romAddress = 0x4000; + for (byte currBank = 0; currBank < 128; currBank++) { + writeByte_GB(0x2800, 8); + writeByte_GB(0x3800, 8); + writeByte_GB(0x2000, currBank); + writeByte_GB(0x3000, currBank); + + romAddress = 0x4000; + // 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(); +} + /****************************************** 29F016/29F032/29F033 flashrom functions *****************************************/ From 9d42ce0964b89f3e9ac66b693ac6afe6ff401da4 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Wed, 28 Sep 2022 18:52:52 +0200 Subject: [PATCH 07/10] Add support for the Game Boy MBC6 mapper (save write) --- Cart_Reader/GB.ino | 251 +++++++++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 100 deletions(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index a710cbc..7bce920 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -310,7 +310,7 @@ void gbMenu() { // Change working dir to root sd.chdir("/"); if (romType == 32) - readSRAMFLASH_GB_MBC6(); + readSRAMFLASH_MBC6_GB(); else readSRAM_GB(); } @@ -328,18 +328,24 @@ 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 { @@ -1268,8 +1274,8 @@ unsigned long verifySRAM_GB() { } } -// Read SRAM + FLASH save data of MBC6 -void readSRAMFLASH_GB_MBC6() { +// Read MBC6 (SRAM + FLASH) save data +void readSRAMFLASH_MBC6_GB() { // Get name, add extension and convert to char array for sd lib strcpy(fileName, romName); strcat(fileName, ".sav"); @@ -1328,15 +1334,14 @@ void readSRAMFLASH_GB_MBC6() { writeByte_GB(0x1000, 0x00); writeByte_GB(0x2800, 0x08); writeByte_GB(0x3800, 0x08); - - word romAddress = 0x4000; + + // Switch FLASH banks for (byte currBank = 0; currBank < 128; currBank++) { - writeByte_GB(0x2800, 8); - writeByte_GB(0x3800, 8); + word romAddress = 0x4000; + writeByte_GB(0x2000, currBank); writeByte_GB(0x3000, currBank); - romAddress = 0x4000; // Read banks and save to SD while (romAddress <= 0x5FFF) { for (int i = 0; i < 512; i++) { @@ -1364,100 +1369,146 @@ void readSRAMFLASH_GB_MBC6() { display_Update(); } -// Read SRAM + FLASH save data of MBC6 -void readSRAMFLASH_GB_MBC6() { - // 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); +// Write MBC6 (SRAM + FLASH) save data +void writeSRAMFLASH_MBC6_GB() { + // Create filepath + sprintf(filePath, "%s/%s", filePath, fileName); //open file on sd card - if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(F("SD Error"), true); - } + 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); - //Initialize progress bar - uint32_t processedProgressBar = 0; - uint32_t totalProgressBar = 0x108000; - draw_progressbar(0, totalProgressBar); + // Enable Mapper and SRAM + writeByte_GB(0x0000, 0x0A); - // 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); - // 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); + // Write SRAM + for (word sramAddress = 0xA000; sramAddress <= lastByte; sramAddress++) { + writeByteSRAM_GB(sramAddress, myFile.read()); } - myFile.write(sdBuffer, 64); - processedProgressBar += 64; + + 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, 0x00); - writeByte_GB(0x2800, 0x08); - writeByte_GB(0x3800, 0x08); + + // Disable SRAM + writeByte_GB(0x0000, 0x00); - word romAddress = 0x4000; - for (byte currBank = 0; currBank < 128; currBank++) { - writeByte_GB(0x2800, 8); - writeByte_GB(0x3800, 8); - writeByte_GB(0x2000, currBank); - writeByte_GB(0x3000, currBank); - - romAddress = 0x4000; - // Read banks and save to SD - while (romAddress <= 0x5FFF) { - for (int i = 0; i < 512; i++) { - sdBuffer[i] = readByte_GB(romAddress + i); + // 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); } - 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(); + println_Msg(F("Save writing finished")); + display_Update(); + } + else { + print_Error(F("File doesnt exist"), false); } - - // 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(); } /****************************************** From dab124def7a198872a8d956d331a128381103c18 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Wed, 28 Sep 2022 21:31:49 +0200 Subject: [PATCH 08/10] Find Game Serial for Game Boy --- Cart_Reader/GB.ino | 31 ++++++++++++++++++++++++------- Cart_Reader/GBA.ino | 6 +++--- Cart_Reader/N64.ino | 2 +- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index 7bce920..3f60d33 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -410,7 +410,10 @@ void showCartInfo_GB() { if (strcmp(checksumStr, "00") != 0) { print_Msg(F("Title: ")); println_Msg(romName); - + if (cartID[0] != 0) { + print_Msg(F("Serial: ")); + println_Msg(cartID); + } print_Msg(F("Revision: ")); println_Msg(romVersion); @@ -497,7 +500,7 @@ void showCartInfo_GB() { print_Msg(F("512 Byte")); } else if (romType == 0x22) { - if (strncmp(romName, "CMASTER_KCEJ", 12) == 0) { + if (strncmp(cartID, "KCEJ", 4) == 0) { print_Msg(F("512 Byte")); } else { @@ -538,9 +541,9 @@ void showCartInfo_GB() { 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("")); @@ -860,6 +863,20 @@ void getCartInfo_GB() { myLength++; } + // Find Game Serial + cartID[0] = 0; + if (sdBuffer[0x143] == 0x80 || sdBuffer[0x143] == 0xC0) { + Serial.println(romName[myLength - 4]); + 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; @@ -1274,7 +1291,7 @@ unsigned long verifySRAM_GB() { } } -// Read MBC6 (SRAM + FLASH) save data +// 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); @@ -1369,7 +1386,7 @@ void readSRAMFLASH_MBC6_GB() { display_Update(); } -// Write MBC6 (SRAM + FLASH) save data +// Write RAM void writeSRAMFLASH_MBC6_GB() { // Create filepath sprintf(filePath, "%s/%s", filePath, fileName); diff --git a/Cart_Reader/GBA.ino b/Cart_Reader/GBA.ino index 6eb3cf2..75d49eb 100644 --- a/Cart_Reader/GBA.ino +++ b/Cart_Reader/GBA.ino @@ -545,7 +545,7 @@ void setup_GBA() { // Print start page print_Msg(F("Title: ")); println_Msg(romName); - print_Msg(F("Code: ")); + print_Msg(F("Serial: ")); println_Msg(cartID); print_Msg(F("Revision: ")); println_Msg(romVersion); @@ -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(cartSize); println_Msg(F(" MB")); - print_Msg(F("Save: ")); + print_Msg(F("Save Lib: ")); println_Msg(saveTypeStr); #if defined(enable_OLED) diff --git a/Cart_Reader/N64.ino b/Cart_Reader/N64.ino index a77da71..07dfc8a 100644 --- a/Cart_Reader/N64.ino +++ b/Cart_Reader/N64.ino @@ -2447,7 +2447,7 @@ void printCartInfo_N64() { display_Clear(); print_Msg(F("Title: ")); println_Msg(romName); - print_Msg(F("Code: ")); + print_Msg(F("Serial: ")); println_Msg(cartID); print_Msg(F("Revision: ")); println_Msg(romVersion); From e892a8e9f1709d50be94d662bae805453991d9d1 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Wed, 28 Sep 2022 21:42:05 +0200 Subject: [PATCH 09/10] Fixed wording --- Cart_Reader/N64.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cart_Reader/N64.ino b/Cart_Reader/N64.ino index 07dfc8a..39231d5 100644 --- a/Cart_Reader/N64.ino +++ b/Cart_Reader/N64.ino @@ -2491,7 +2491,7 @@ void printCartInfo_N64() { println_Msg(""); print_Msg(F("Title: ")); println_Msg(romName); - print_Msg(F("Code: ")); + print_Msg(F("Serial: ")); println_Msg(cartID); print_Msg(F("CRC1: ")); println_Msg(checksumStr); From 4cac40e0112183ba8ba2e329acb0ac908c323760 Mon Sep 17 00:00:00 2001 From: Lesserkuma Date: Wed, 28 Sep 2022 21:46:21 +0200 Subject: [PATCH 10/10] Remove debug output --- Cart_Reader/GB.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index 3f60d33..297f90f 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -866,7 +866,6 @@ void getCartInfo_GB() { // Find Game Serial cartID[0] = 0; if (sdBuffer[0x143] == 0x80 || sdBuffer[0x143] == 0xC0) { - Serial.println(romName[myLength - 4]); 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];