mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-10 23:15:08 +01:00
206 lines
5.2 KiB
C++
206 lines
5.2 KiB
C++
/******************************************
|
|
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
|
|
//******************************************
|