diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index 2e3dcde..699457b 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 05aaa42..297f90f 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"; @@ -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 *****************************************/ diff --git a/Cart_Reader/GBA.ino b/Cart_Reader/GBA.ino index 1391427..75d49eb 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,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 diff --git a/Cart_Reader/N64.ino b/Cart_Reader/N64.ino index 6b28d62..39231d5 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("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; } diff --git a/Cart_Reader/SNES.ino b/Cart_Reader/SNES.ino index 0f16889..64a6c17 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; }