Merge pull request #871 from PsyK0p4T/master

Add Sufami Turbo support
This commit is contained in:
PsyK0p4T 2023-11-25 00:40:07 +01:00 committed by GitHub
commit dece32c130
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 241 additions and 13 deletions

View File

@ -257,6 +257,7 @@ void print_STR(byte string_number, boolean newline) {
#define mode_5200 37 #define mode_5200 37
#define mode_7800 38 #define mode_7800 38
#define mode_VECTREX 39 #define mode_VECTREX 39
#define mode_ST 40
// optimization-safe nop delay // optimization-safe nop delay
#define NOP __asm__ __volatile__("nop\n\t") #define NOP __asm__ __volatile__("nop\n\t")
@ -3592,6 +3593,11 @@ void loop() {
svMenu(); svMenu();
} }
#endif #endif
#ifdef enable_ST
else if (mode == mode_ST) {
stMenu();
}
#endif
#ifdef enable_NES #ifdef enable_NES
else if (mode == mode_NES) { else if (mode == mode_NES) {
nesMenu(); nesMenu();

View File

@ -223,6 +223,13 @@
/****/ /****/
/* [ Super Famicom Sufami Turbo ----------------------------------- ]
*/
// #define enable_ST
/****/
/* [ Super Nintendo ----------------------------------------------- ] /* [ Super Nintendo ----------------------------------------------- ]
*/ */

View File

@ -32,14 +32,15 @@ boolean altconf = 0;
static const char snsMenuItem1[] PROGMEM = "SNES/SFC cartridge"; static const char snsMenuItem1[] PROGMEM = "SNES/SFC cartridge";
static const char snsMenuItem2[] PROGMEM = "SF Memory Cassette"; static const char snsMenuItem2[] PROGMEM = "SF Memory Cassette";
static const char snsMenuItem3[] PROGMEM = "Satellaview BS-X"; 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 #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 snsMenuItem6[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, string_reset2 }; 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 #endif
// SNES menu items // SNES menu items
@ -132,15 +133,15 @@ void reproMenu() {
// SNES start menu // SNES start menu
void snsMenu() { 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; unsigned char snsCart;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
#ifdef clockgen_calibration #ifdef clockgen_calibration
convertPgm(menuOptionsSNS, 7);
snsCart = question_box(F("Select Cart Type"), menuOptions, 7, 0);
#else
convertPgm(menuOptionsSNS, 6); convertPgm(menuOptionsSNS, 6);
snsCart = question_box(F("Select Cart Type"), menuOptions, 6, 0); 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 #endif
// wait for user choice to come back from the question box menu // wait for user choice to come back from the question box menu
@ -170,19 +171,28 @@ void snsMenu() {
break; break;
#endif #endif
#ifdef enable_FLASH #ifdef enable_ST
case 3: case 3:
display_Clear();
display_Update();
setup_ST();
mode = mode_ST;
break;
#endif
#ifdef enable_FLASH
case 4:
setup_FlashVoltage(); setup_FlashVoltage();
reproMenu(); reproMenu();
break; break;
#endif #endif
case 4: case 5:
#ifdef clockgen_calibration #ifdef clockgen_calibration
clkcal(); clkcal();
break; break;
case 5: case 6:
#endif #endif
resetArduino(); resetArduino();
break; break;

205
Cart_Reader/ST.ino Normal file
View File

@ -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
//******************************************

View File

@ -22,7 +22,7 @@ Happy making. 🔧🔨😊
#### Supported Systems: #### Supported Systems:
- NES/Famicom/Family Basic - 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) - Nintendo 64 (including Controller Pak, Gameshark, and Xplorer 64)
- Game Boy Color (including GB Memory, Codebreaker, and Gameshark) - Game Boy Color (including GB Memory, Codebreaker, and Gameshark)
- Game Boy Advance - Game Boy Advance