From fd82faca2ddd11e178cf14d6078bc3f90a8bb84d Mon Sep 17 00:00:00 2001 From: sanni Date: Wed, 26 Jun 2024 09:24:12 +0200 Subject: [PATCH] SNES: Add 2x2MB flash to CFI (thx to MouseBiteLabs) --- Cart_Reader/FLASH.ino | 87 +++++++++++++++++++++++++++++---- Cart_Reader/SNES.ino | 109 ++++++++++++++++++++++++++++++++---------- 2 files changed, 162 insertions(+), 34 deletions(-) diff --git a/Cart_Reader/FLASH.ino b/Cart_Reader/FLASH.ino index 6cdcb7c..f0351dd 100644 --- a/Cart_Reader/FLASH.ino +++ b/Cart_Reader/FLASH.ino @@ -830,7 +830,7 @@ void writeByte_Flash(unsigned long myAddress, byte myData) { // A15-A22 PORTL = (myAddress >> 15) & 0xFF; } - // for SNES ExLoRom repro + // for SNES ExLoRom repro with 2x 4MB else if (mapping == 2) { // A8-A14 PORTK = (myAddress >> 8) & 0x7F; @@ -858,6 +858,26 @@ void writeByte_Flash(unsigned long myAddress, byte myData) { // Switch SNES BA6(PL6) to HIGH to disable SRAM PORTL |= (1 << 6); } + // for SNES LoRom repro with 2x 2MB + else if (mapping == 4) { + // A8-A14 + PORTK = (myAddress >> 8) & 0x7F; + // Set SNES A15(PK7) HIGH to disable SRAM + PORTK |= (1 << 7); + // A15-A22 + PORTL = (myAddress >> 15) & 0xFF; + // Flip BA6(PL6) to address second rom chip + PORTL ^= (1 << PL6); + } + // for SNES HiRom repro with 2x 2MB + else if (mapping == 5) { + // A8-A15 + PORTK = (myAddress >> 8) & 0xFF; + // A16-A23 + PORTL = (myAddress >> 16) & 0xFF; + // Flip BA5(PL5) to address second rom chip + PORTL ^= (1 << PL5); + } // Data PORTC = myData; @@ -942,6 +962,26 @@ byte readByte_Flash(unsigned long myAddress) { // Switch SNES BA6(PL6) to HIGH to disable SRAM PORTL |= (1 << 6); } + // for SNES LoRom repro with 2x 2MB + else if (mapping == 4) { + // A8-A14 + PORTK = (myAddress >> 8) & 0x7F; + // Set SNES A15(PK7) HIGH to disable SRAM + PORTK |= (1 << 7); + // A15-A22 + PORTL = (myAddress >> 15) & 0xFF; + // Flip BA6(PL6) to address second rom chip + PORTL ^= (1 << PL6); + } + // for SNES HiRom repro with 2x 2MB + else if (mapping == 5) { + // A8-A15 + PORTK = (myAddress >> 8) & 0xFF; + // A16-A23 + PORTL = (myAddress >> 16) & 0xFF; + // Flip BA5(PL5) to address second rom chip + PORTL ^= (1 << PL5); + } // Arduino running at 16Mhz -> one nop = 62.5ns __asm__("nop\n\t" @@ -1711,8 +1751,18 @@ void blankcheck_Flash() { } void verifyFlash() { + verifyFlash(0, 0); +} + +void verifyFlash(unsigned long verifyStart, unsigned long verifyEnd) { if (openVerifyFlashFile()) { blank = 0; + + if (verifyStart != 0) + myFile.seekCur(verifyStart); + if (verifyEnd != 0) + fileSize = verifyEnd; + for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) { //fill sdBuffer myFile.read(sdBuffer, 512); @@ -2367,7 +2417,7 @@ void print_Eprom(int numBytes) { #endif /****************************************** -CFI flashrom functions (copy&paste from GB.ino) +CFI flashrom functions (modified from GB.ino) *****************************************/ void sendCFICommand_Flash(byte cmd) { writeByteCompensated_Flash(0xAAA, 0xaa); @@ -2453,8 +2503,10 @@ void identifyCFI_Flash() { flashSwitchLastBits = true; } else { println_Msg(F("CFI Query failed!")); + print_STR(press_button_STR, 0); display_Update(); wait(); + resetArduino(); return; } } @@ -2469,13 +2521,13 @@ void identifyCFI_Flash() { } // Write flashrom -void writeCFI_Flash() { - filePath[0] = '\0'; - sd.chdir("/"); - fileBrowser(FS(FSTRING_SELECT_FILE)); - display_Clear(); - - if (openFlashFile()) { +void writeCFI_Flash(byte romChips) { + if (openFileOnSD()) { + // Print filepath + print_STR(flashing_file_STR, 0); + print_Msg(filePath); + println_Msg(F("...")); + display_Update(); // Reset flash dataOut(); @@ -2510,7 +2562,22 @@ void writeCFI_Flash() { statusReg = readByte_Flash(0); } - println_Msg(F("Writing flash")); + print_Msg(F("Writing flash")); + // If we have two ROM chips only write half the ROM file here and skip to second half of file on second write + if (romChips == 0) { + println_Msg(F("")); + } else if (romChips == 1) { + println_Msg(F(" 1/2")); + myFile.seekCur(0); + // Truncate file to size of 1st flash chip + if (fileSize > flashSize / 2) { + fileSize = flashSize / 2; + } + } else if (romChips == 2) { + println_Msg(F(" 2/2")); + myFile.seekCur(flashSize / 2); + fileSize = fileSize - flashSize / 2; + } display_Update(); //Initialize progress bar diff --git a/Cart_Reader/SNES.ino b/Cart_Reader/SNES.ino index f7bdce2..a6067ac 100644 --- a/Cart_Reader/SNES.ino +++ b/Cart_Reader/SNES.ino @@ -63,6 +63,89 @@ static const char reproMenuItem5[] PROGMEM = "ExLoROM (P1)"; static const char reproMenuItem6[] PROGMEM = "ExHiROM (P1)"; static const char* const menuOptionsRepro[] PROGMEM = { reproMenuItem1, reproMenuItem2, reproMenuItem3, reproMenuItem4, reproMenuItem5, reproMenuItem6, FSTRING_RESET }; +// CFI ROM config +static const char reproCFIItem1[] PROGMEM = "1x 2MB"; +static const char reproCFIItem2[] PROGMEM = "2x 2MB"; +static const char reproCFIItem3[] PROGMEM = "1x 4MB"; +static const char* const menuOptionsReproCFI[] PROGMEM = { reproCFIItem1, reproCFIItem2, reproCFIItem3, FSTRING_RESET }; + +void setupCFI() { +#ifdef ENABLE_FLASH + display_Clear(); + display_Update(); + filePath[0] = '\0'; + sd.chdir("/"); + fileBrowser(F("Select file")); + display_Clear(); + setup_Flash8(); + identifyCFI_Flash(); + sprintf(filePath, "%s/%s", filePath, fileName); + display_Clear(); +#endif +} + +// Setup number of flashroms +void reproCFIMenu() { + // create menu with title and 4 options to choose from + unsigned char snsReproCFI; + // Copy menuOptions out of progmem + convertPgm(menuOptionsReproCFI, 4); + snsReproCFI = question_box(F("Select Flash Config"), menuOptions, 4, 0); + + // wait for user choice to come back from the question box menu + switch (snsReproCFI) { +#ifdef ENABLE_FLASH + case 0: + setupCFI(); + flashSize = 2097152; + writeCFI_Flash(0); + verifyFlash(); + break; + + case 1: + setupCFI(); + flashSize = 4194304; + // Write first rom chip + writeCFI_Flash(1); + verifyFlash(0, 2097152); + delay(300); + + // Switch to second ROM chip, see flash.ino low level functions line 811 + // LoROM + if (mapping == 0) + mapping = 4; + // HiROM + else if (mapping == 1) + mapping = 5; + + // Write second rom chip + display_Clear(); + writeCFI_Flash(2); + verifyFlash(2097152, 2097152); + break; + + case 2: + setupCFI(); + flashSize = 4194304; + writeCFI_Flash(0); + verifyFlash(); + break; +#endif + + case 3: + resetArduino(); + break; + } + +#ifdef ENABLE_FLASH + // Prints string out of the common strings array either with or without newline + print_STR(press_button_STR, 0); + display_Update(); + wait(); + resetArduino(); +#endif +} + // SNES repro menu void reproMenu() { // create menu with title and 7 options to choose from @@ -76,36 +159,14 @@ void reproMenu() { #ifdef ENABLE_FLASH case 0: // CFI LoROM - display_Clear(); - display_Update(); mapping = 0; - flashSize = 4194304; - setup_Flash8(); - identifyCFI_Flash(); - writeCFI_Flash(); - verifyFlash(); - // Prints string out of the common strings array either with or without newline - print_STR(press_button_STR, 0); - display_Update(); - wait(); - resetArduino(); + reproCFIMenu(); break; case 1: // CFI HiROM - display_Clear(); - display_Update(); mapping = 1; - flashSize = 4194304; - setup_Flash8(); - identifyCFI_Flash(); - writeCFI_Flash(); - verifyFlash(); - // Prints string out of the common strings array either with or without newline - print_STR(press_button_STR, 0); - display_Update(); - wait(); - resetArduino(); + reproCFIMenu(); break; case 2: