diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index 29cb6d5..3503f1f 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -4,8 +4,8 @@ This project represents a community-driven effort to provide an easy to build and easy to modify cartridge dumper. - Date: 25.09.2022 - Version: 9.9 + Date: 27.09.2022 + Version: 10.0 SD lib: https://github.com/greiman/SdFat OLED lib: https://github.com/adafruit/Adafruit_SSD1306 @@ -59,7 +59,7 @@ **********************************************************************************/ -char ver[5] = "9.9"; +char ver[5] = "10.0"; //****************************************** // !!! CHOOSE HARDWARE VERSION !!! diff --git a/Cart_Reader/GBA.ino b/Cart_Reader/GBA.ino index 2f75ee3..06e61ee 100644 --- a/Cart_Reader/GBA.ino +++ b/Cart_Reader/GBA.ino @@ -581,7 +581,6 @@ void setup_GBA() { println_Msg(F("1024K Flash")); break; } - print_Msg(F("Checksum: ")); println_Msg(checksumStr); print_Msg(F("Version: 1.")); @@ -790,6 +789,8 @@ void writeByte_GBA(unsigned long myAddress, byte myData) { *****************************************/ // Read info out of rom header void getCartInfo_GBA() { + char saveTypeStr[14]; + // Read Header into array for (int currWord = 0; currWord < 192; currWord += 2) { word tempWord = readWord_GBA(currWord); @@ -835,7 +836,11 @@ void getCartInfo_GBA() { println_Msg(F("Searching database...")); display_Update(); + //go to root + sd.chdir(); if (myFile.open("gba.txt", O_READ)) { + char gamename[100]; + // Loop through file while (myFile.available()) { // Skip first line with name @@ -853,32 +858,136 @@ void getCartInfo_GBA() { // Check if string is a match if (strcmp(tempStr, cartID) == 0) { - // Skip the , in the file - myFile.seekSet(myFile.curPosition() + 1); - - // Read the next ascii character and subtract 48 to convert to decimal - cartSize = myFile.read() - 48; - // Remove leading 0 for single digit cart sizes - if (cartSize != 0) { - cartSize = cartSize * 10 + myFile.read() - 48; + // Rewind to start of entry + for (byte count_newline = 0; count_newline < 2; count_newline++) { + while (1) { + if (myFile.curPosition() == 0) { + break; + } + else if (myFile.peek() == '\n') { + myFile.seekSet(myFile.curPosition() - 1); + break; + } + else { + myFile.seekSet(myFile.curPosition() - 1); + } + } } - else { + if (myFile.curPosition() != 0) + myFile.seekSet(myFile.curPosition() + 2); + + // Display database + while (myFile.available()) { + display_Clear(); + + // Read game name +#if defined(enable_OLED) + get_line(gamename, &myFile, 42); +#else + get_line(gamename, &myFile, 96); +#endif + + // Skip over the CRC checksum + myFile.seekSet(myFile.curPosition() + 9); + + // Read 4 bytes into String, do it one at a time so byte order doesn't get mixed up + sprintf(tempStr, "%c", myFile.read()); + for (byte i = 0; i < 3; i++) { + sprintf(tempStr2, "%c", myFile.read()); + strcat(tempStr, tempStr2); + } + + // Skip the , in the file + myFile.seekSet(myFile.curPosition() + 1); + + // Read the next ascii character and subtract 48 to convert to decimal cartSize = myFile.read() - 48; + // Remove leading 0 for single digit cart sizes + if (cartSize != 0) { + cartSize = cartSize * 10 + myFile.read() - 48; + } + else { + cartSize = myFile.read() - 48; + } + + // Skip the , in the file + myFile.seekSet(myFile.curPosition() + 1); + + // Read save type into string + get_line(saveTypeStr, &myFile, 14); + + // skip third empty line + skip_line(&myFile); + + // Print current database entry + println_Msg(gamename); + print_Msg(F("Cart ID: ")); + println_Msg(tempStr); + print_Msg(F("Rom Size: ")); + print_Msg(cartSize); + println_Msg(F("MB")); + print_Msg(F("Save: ")); + println_Msg(saveTypeStr); + +#if defined(enable_OLED) + println_Msg(F("Press left to Change")); + println_Msg(F("and right to Select")); +#elif defined(enable_LCD) + println_Msg(F("")); + println_Msg(F("Rotate to Change")); + println_Msg(F("Press to Select")); +#elif defined(SERIAL_MONITOR) + println_Msg(F("")); + println_Msg(F("U/D to Change")); + println_Msg(F("Space to Select")); +#endif + display_Update(); + + int b = 0; + while (1) { + // Check button input + b = checkButton(); + + // Next + if (b == 1) { + // Break out of loop to read next entry + break; + } + + // Previous + else if (b == 2) { + for (byte count_newline = 0; count_newline < 7; count_newline++) { + while (1) { + if (myFile.curPosition() == 0) { + break; + } + else if (myFile.peek() == '\n') { + myFile.seekSet(myFile.curPosition() - 1); + break; + } + else { + myFile.seekSet(myFile.curPosition() - 1); + } + } + } + if (myFile.curPosition() != 0) + myFile.seekSet(myFile.curPosition() + 2); + break; + } + + // Selection made + else if (b == 3) { + // Close file and break to exit both loops + myFile.close(); + break; + } + } } - - // Skip the , in the file - myFile.seekSet(myFile.curPosition() + 1); - - // Read the next ascii character and subtract 48 to convert to decimal - saveType = myFile.read() - 48; - - // End loop if ID was found - break; } - // If no match, empty string, advance by 7 and try again + // If no match advance and try again else { // skip rest of line - myFile.seekSet(myFile.curPosition() + 7); + skip_line(&myFile); // skip third empty line skip_line(&myFile); } @@ -928,6 +1037,7 @@ void getCartInfo_GBA() { // Compare checksum if (strcmp(calcChecksumStr, checksumStr) != 0) { + display_Clear(); print_Msg(F("Result: ")); println_Msg(calcChecksumStr); print_Error(F("Checksum Error"), false); @@ -936,6 +1046,60 @@ void getCartInfo_GBA() { display_Update(); wait(); } + + /* Convert saveTypeStr to saveType + Save types in ROM + EEPROM_Vnnn EEPROM 512 bytes or 8 Kbytes (4Kbit or 64Kbit) + SRAM_Vnnn SRAM 32 Kbytes (256Kbit) + SRAM_F_Vnnn FRAM 32 Kbytes (256Kbit) + FLASH_Vnnn FLASH 64 Kbytes (512Kbit) (ID used in older files) + FLASH512_Vnnn FLASH 64 Kbytes (512Kbit) (ID used in newer files) + FLASH1M_Vnnn FLASH 128 Kbytes (1Mbit) + + 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 + */ + + if (saveTypeStr[0] == '0') { + saveType = 0; + } + else if (saveTypeStr[0] == 'E') { + // Test if 4kbit or 64kbit EEPROM + + // Disable interrupts for more uniform clock pulses + noInterrupts(); + // Fill sd Buffer + readBlock_EEP(0, 64); + interrupts(); + delay(1000); + // Enable ROM again + setROM_GBA(); + + saveType = 1; + + // 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; + break; + } + } + } + else if (saveTypeStr[0] == 'S') { + saveType = 3; + } + else if ((saveTypeStr[0] == 'F') && (saveTypeStr[5] == '1')) { + saveType = 5; + } + else if (saveTypeStr[0] == 'F') { + saveType = 4; + } } }