From f86a86162899e21654e542b01e676bcc156c4611 Mon Sep 17 00:00:00 2001 From: PsyK0p4T <87064902+PsyK0p4T@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:26:38 +0100 Subject: [PATCH 1/5] Add Sufami Turbo module --- Cart_Reader/ST.ino | 205 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 Cart_Reader/ST.ino diff --git a/Cart_Reader/ST.ino b/Cart_Reader/ST.ino new file mode 100644 index 00000000..c08bd454 --- /dev/null +++ b/Cart_Reader/ST.ino @@ -0,0 +1,205 @@ +/****************************************** + SUPER FAMICOM SUFAMI TURBO MODULE +******************************************/ +#ifdef enable_ST + +/****************************************** + Menu +*****************************************/ +// Sufami Turbo menu items +static const char stMenuItem1[] PROGMEM = "Read cart in Slot A"; +static const char stMenuItem2[] PROGMEM = "Read cart in Slot B"; +static const char* const menuOptionsST[] PROGMEM = { stMenuItem1, stMenuItem2, string_reset2 }; + +void stMenu() { + // Create ST menu with title and 3 options to choose from + unsigned char mainMenu; + convertPgm(menuOptionsST, 3); + mainMenu = question_box(F("Sufami Turbo"), menuOptions, 3, 0); + + // Wait for user choice to come back from the question box menu + switch (mainMenu) { + // Read cart in ST slot A + case 0: + readSlot(0); + break; + + // Read cart in ST slot B + case 1: + readSlot(1); + break; + + // Reset + case 2: + resetArduino(); + break; + } +} + +/****************************************** + Setup + *****************************************/ +void setup_ST() { + // Request 5V + setVoltage(VOLTS_SET_5V); + + // Set cicrstPin(PG1) to Output + DDRG |= (1 << 1); + // Output a high signal until we're ready to start + PORTG |= (1 << 1); + // Set cichstPin(PG0) to Input + DDRG &= ~(1 << 0); + + // Set Address Pins to Output + //A0-A7 + DDRF = 0xFF; + //A8-A15 + DDRK = 0xFF; + //BA0-BA7 + DDRL = 0xFF; + //PA0-PA7 + DDRA = 0xFF; + + // Set Control Pins to Output RST(PH0) CS(PH3) WR(PH5) RD(PH6) + DDRH |= (1 << 0) | (1 << 3) | (1 << 5) | (1 << 6); + // Switch RST(PH0) and WR(PH5) to HIGH + PORTH |= (1 << 0) | (1 << 5); + // Switch CS(PH3) and RD(PH6) to LOW + PORTH &= ~((1 << 3) | (1 << 6)); + // Set Refresh(PE5) to Output + DDRE |= (1 << 5); + // Switch Refresh(PE5) to LOW (needed for SA-1) + PORTE &= ~(1 << 5); + // Set CPU Clock(PH1) to Output + DDRH |= (1 << 1); + // Set IRQ(PH4) to Input + DDRH &= ~(1 << 4); + // Set expand(PG5) to Input + DDRG &= ~(1 << 5); + // Set Data Pins (D0-D7) to Input + DDRC = 0x00; + // Unused pins + // Set wram(PE4) to Output + DDRE |= (1 << 4); + // Set pawr(PJ1) to Output + DDRJ |= (1 << 1); + // Set pard(PJ0) to Output + DDRJ |= (1 << 0); + + //Check if Sufami Turbo adapter is inserted + if (!getHeader(0)) { + display_Clear(); + println_Msg(F("Sufami Turbo adapter")); + println_Msg(F("was not found.")); + display_Update(); + wait(); + resetArduino(); + } +} + +/****************************************** + ROM Functions +******************************************/ +// Verify if 'BANDAI' header is present in specified bank +bool getHeader(unsigned int bank) { + byte snesHeader[16]; + PORTL = bank; + + // Read first bytes + for (uint16_t c = 0, currByte = 0; c < 16; c++, currByte++) { + PORTF = (currByte & 0xFF); + PORTK = ((currByte >> 8) & 0xFF); + NOP; + NOP; + NOP; + NOP; + NOP; + NOP; + snesHeader[c] = PINC; + } + + // Format internal name + buildRomName(romName, &snesHeader[0], 14); + + // Check if 'BANDAI' header is present + if (strncmp(romName, "BANDAI SFC-ADX", 14) == 0) + return(1); + else + return(0); +} + +// Select the slot to use and detect cart size +void readSlot(bool cartSlot) { + // Set control + dataIn(); + controlIn_SNES(); + sd.chdir("/"); + display_Clear(); + + if(!cartSlot) { // Slot A was selected + if (getHeader(32)) { // Look for a cart in slot A + if (getHeader(48)) // Look for mirrored data in slot A + readRom_ST(32,48); // Dump 512KB cart + else + readRom_ST(32,64); // Dump 1MB cart + } + else { + println_Msg(F("No cart detected in Slot A")); + display_Update(); + wait(); + } + } + else { // Slot B was selected + if (getHeader(64)) { // Look for a cart in slot B + if (getHeader(80)) // Look for mirrored data in slot B + readRom_ST(64,80); // Dump 512KB cart + else + readRom_ST(64,96); // Dump 1MB cart + } + else { + println_Msg(F("No cart detected in Slot B")); + display_Update(); + wait(); + } + } +} + +// Read ST rom to SD card +void readRom_ST(unsigned int bankStart, unsigned int bankEnd) { + // create a new folder to save rom file + EEPROM_readAnything(0, foldern); + strcpy(fileName, "SUFAMI_TURBO.st"); + sprintf(folder, "ST/%s/%d", romName, foldern); + sd.mkdir(folder, true); + sd.chdir(folder); + + display_Clear(); + print_STR(saving_to_STR, 0); + print_Msg(folder); + println_Msg(F("/...")); + display_Update(); + + // write new folder number back to eeprom + foldern++; + EEPROM_writeAnything(0, foldern); + + //open file on sd card + if (!myFile.open(fileName, O_RDWR | O_CREAT)) { + print_FatalError(create_file_STR); + } + + // Read specified banks + readLoRomBanks(bankStart + 0x80, bankEnd + 0x80, &myFile); + + // Close file: + myFile.close(); + + print_STR(press_button_STR, 1); + display_Update(); + wait(); +} +#endif + +//****************************************** +// End of File +//****************************************** From 0287ea8ed2089d6d1ae11b036d7e41f9e45b7dd0 Mon Sep 17 00:00:00 2001 From: PsyK0p4T <87064902+PsyK0p4T@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:29:55 +0100 Subject: [PATCH 2/5] Update Config.h add Sufami Turbo support --- Cart_Reader/Config.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Cart_Reader/Config.h b/Cart_Reader/Config.h index a41c49cd..fb42262c 100644 --- a/Cart_Reader/Config.h +++ b/Cart_Reader/Config.h @@ -223,6 +223,13 @@ /****/ +/* [ Super Famicom Sufami Turbo ----------------------------------- ] +*/ + +// #define enable_ST + +/****/ + /* [ Super Nintendo ----------------------------------------------- ] */ From 70d52636d70f393b31aafb7ef1e7bca14fd5f048 Mon Sep 17 00:00:00 2001 From: PsyK0p4T <87064902+PsyK0p4T@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:32:51 +0100 Subject: [PATCH 3/5] Update SNES.ino Add Sufami Turbo support --- Cart_Reader/SNES.ino | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/Cart_Reader/SNES.ino b/Cart_Reader/SNES.ino index dd0571a7..5e69126c 100644 --- a/Cart_Reader/SNES.ino +++ b/Cart_Reader/SNES.ino @@ -32,14 +32,15 @@ boolean altconf = 0; static const char snsMenuItem1[] PROGMEM = "SNES/SFC cartridge"; static const char snsMenuItem2[] PROGMEM = "SF Memory Cassette"; static const char snsMenuItem3[] PROGMEM = "Satellaview BS-X"; -static const char snsMenuItem4[] PROGMEM = "Flash repro"; +static const char snsMenuItem4[] PROGMEM = "Sufami Turbo"; +static const char snsMenuItem5[] PROGMEM = "Flash repro"; #ifdef clockgen_calibration -static const char snsMenuItem5[] PROGMEM = "Calibrate Clock"; +static const char snsMenuItem6[] PROGMEM = "Calibrate Clock"; +//static const char snsMenuItem7[] PROGMEM = "Reset"; (stored in common strings array) +static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, snsMenuItem6, string_reset2 }; +#else //static const char snsMenuItem6[] PROGMEM = "Reset"; (stored in common strings array) static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, string_reset2 }; -#else -//static const char snsMenuItem5[] PROGMEM = "Reset"; (stored in common strings array) -static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, string_reset2 }; #endif // SNES menu items @@ -132,15 +133,15 @@ void reproMenu() { // SNES start menu void snsMenu() { - // create menu with title and 6 options to choose from + // create menu with title and 7 options to choose from unsigned char snsCart; // Copy menuOptions out of progmem #ifdef clockgen_calibration + convertPgm(menuOptionsSNS, 7); + snsCart = question_box(F("Select Cart Type"), menuOptions, 7, 0); +#else convertPgm(menuOptionsSNS, 6); snsCart = question_box(F("Select Cart Type"), menuOptions, 6, 0); -#else - convertPgm(menuOptionsSNS, 5); - snsCart = question_box(F("Select Cart Type"), menuOptions, 5, 0); #endif // wait for user choice to come back from the question box menu @@ -170,19 +171,28 @@ void snsMenu() { break; #endif -#ifdef enable_FLASH +#ifdef enable_ST case 3: + display_Clear(); + display_Update(); + setup_ST(); + mode = mode_ST; + break; +#endif + +#ifdef enable_FLASH + case 4: setup_FlashVoltage(); reproMenu(); break; #endif - case 4: + case 5: #ifdef clockgen_calibration clkcal(); break; - case 5: + case 6: #endif resetArduino(); break; From d0fe5c8ca14b26176caabc432c914d904d988194 Mon Sep 17 00:00:00 2001 From: PsyK0p4T <87064902+PsyK0p4T@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:34:13 +0100 Subject: [PATCH 4/5] Update Cart_Reader.ino Add Sufami Turbo support --- Cart_Reader/Cart_Reader.ino | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index 1b16f346..20dafdb4 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -257,6 +257,7 @@ void print_STR(byte string_number, boolean newline) { #define mode_5200 37 #define mode_7800 38 #define mode_VECTREX 39 +#define mode_ST 40 // optimization-safe nop delay #define NOP __asm__ __volatile__("nop\n\t") @@ -3592,6 +3593,11 @@ void loop() { svMenu(); } #endif +#ifdef enable_ST + else if (mode == mode_ST) { + stMenu(); + } +#endif #ifdef enable_NES else if (mode == mode_NES) { nesMenu(); From 3d810823e188d9d69cf469ef5645ffd12861e786 Mon Sep 17 00:00:00 2001 From: PsyK0p4T <87064902+PsyK0p4T@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:36:08 +0100 Subject: [PATCH 5/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 09be4862..09930574 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Happy making. 🔧🔨😊 #### Supported Systems: - NES/Famicom/Family Basic -- Super Nintendo/Super Famicom (including SF Memory and Satellaview) +- Super Nintendo/Super Famicom (including SF Memory, Satellaview, and Sufami Turbo) - Nintendo 64 (including Controller Pak, Gameshark, and Xplorer 64) - Game Boy Color (including GB Memory, Codebreaker, and Gameshark) - Game Boy Advance