cartreader/Cart_Reader/ST.ino

198 lines
5.0 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, FSTRING_RESET };
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
createFolder("ST", "ROM", "SUFAMI_TURBO", "st");
printAndIncrementFolder(true);
//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();
// Compare dump CRC with db values
compareCRC("st.txt", 0, 1, 0);
println_Msg(FS(FSTRING_EMPTY));
print_STR(press_button_STR, 1);
display_Update();
wait();
}
#endif
//******************************************
// End of File
//******************************************