Retrode SMS/GG adapter support

This commit is contained in:
jiyunomegami 2020-07-04 19:16:14 +09:00
parent c385323ce3
commit bc3dd3dd13

View File

@ -11,20 +11,25 @@
*****************************************/ *****************************************/
// MD menu items // MD menu items
static const char SMSMenuItem1[] PROGMEM = "Read Rom"; static const char SMSMenuItem1[] PROGMEM = "Read Rom";
static const char SMSMenuItem2[] PROGMEM = "Reset"; static const char SMSMenuItem2[] PROGMEM = "Read Rom Retrode";
static const char* const menuOptionsSMS[] PROGMEM = {SMSMenuItem1, SMSMenuItem2}; static const char SMSMenuItem3[] PROGMEM = "Reset";
static const char* const menuOptionsSMS[] PROGMEM = {SMSMenuItem1, SMSMenuItem2, SMSMenuItem3};
// Set retrode_mode to true when using a retrode SMS/GG adapter
static bool retrode_mode = false;
void smsMenu() { void smsMenu() {
// create menu with title and 2 options to choose from // create menu with title and 2 options to choose from
unsigned char mainMenu; unsigned char mainMenu;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(menuOptionsSMS, 2); convertPgm(menuOptionsSMS, 3);
mainMenu = question_box(F("Sega Master System"), menuOptions, 2, 0); mainMenu = question_box(F("Sega Master System"), menuOptions, 3, 0);
// wait for user choice to come back from the question box menu // wait for user choice to come back from the question box menu
switch (mainMenu) switch (mainMenu)
{ {
case 0: case 0:
retrode_mode = false;
display_Clear(); display_Clear();
mode = mode_SMS; mode = mode_SMS;
setup_SMS(); setup_SMS();
@ -34,10 +39,21 @@ void smsMenu() {
break; break;
case 1: case 1:
retrode_mode = true;
display_Clear();
mode = mode_SMS;
setup_SMS();
// Change working dir to root
sd.chdir("/");
readROM_SMS();
break;
case 2:
// Reset // Reset
resetArduino(); resetArduino();
break; break;
} }
println_Msg(retrode_mode ? F("Retrode Mode On") : F("Retrode Mode Off"));
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); println_Msg(F("Press Button..."));
display_Update(); display_Update();
@ -56,6 +72,20 @@ void setup_SMS() {
//A15 //A15
DDRH |= (1 << 3); DDRH |= (1 << 3);
if (retrode_mode) {
// Set Control Pins to Output OE(PH6)
DDRH |= (1 << 6);
// WR(PL5) and RD(PL6)
DDRL |= (1 << 5) | (1 << 6);
// Setting OE(PH6) HIGH
PORTH |= (1 << 6);
//PORTH &= ~(1 << 6); // set OE LOW
// Setting WR(PL5) and RD(PL6) HIGH
PORTL |= (1 << 5) | (1 << 6);
// RD(PL6)
//PORTL &= ~(1 << 6); // set RE LOW
} else {
// Set Control Pins to Output RST(PH0) WR(PH5) OE(PH6) // Set Control Pins to Output RST(PH0) WR(PH5) OE(PH6)
DDRH |= (1 << 0) | (1 << 5) | (1 << 6); DDRH |= (1 << 0) | (1 << 5) | (1 << 6);
// CE(PL1) // CE(PL1)
@ -65,6 +95,7 @@ void setup_SMS() {
PORTH |= (1 << 0) | (1 << 5) | (1 << 6); PORTH |= (1 << 0) | (1 << 5) | (1 << 6);
// CE(PL1) // CE(PL1)
PORTL |= (1 << 1); PORTL |= (1 << 1);
}
// ROM has 16KB banks which can be mapped to one of three slots via register writes // ROM has 16KB banks which can be mapped to one of three slots via register writes
// Register Slot Address space // Register Slot Address space
@ -88,61 +119,111 @@ void setup_SMS() {
Low level functions Low level functions
*****************************************/ *****************************************/
void writeByte_SMS(word myAddress, byte myData) { void writeByte_SMS(word myAddress, byte myData) {
if (retrode_mode) {
// Set Data Pins (D8-D15) to Output
DDRA = 0xFF;
} else {
// Set Data Pins (D0-D7) to Output // Set Data Pins (D0-D7) to Output
DDRC = 0xFF; DDRC = 0xFF;
}
// Set address // Set address
PORTF = myAddress & 0xFF; PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF; PORTK = (myAddress >> 8) & 0xFF;
if (!retrode_mode) {
// CE(PH3) and OE(PH6) are connected
PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000); PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000);
}
// Output data // Output data
if (retrode_mode) {
PORTA = myData;
} else {
PORTC = myData; PORTC = myData;
}
// Arduino running at 16Mhz -> one nop = 62.5ns // Arduino running at 16Mhz -> one nop = 62.5ns
// Wait till output is stable // Wait till output is stable
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
if (retrode_mode) {
// Switch WR(PL5) and OE/CE(PH6) to LOW
PORTL &= ~(1 << 5);
PORTH &= ~(1 << 6);
} else {
// Switch CE(PL1) and WR(PH5) to LOW // Switch CE(PL1) and WR(PH5) to LOW
PORTL &= ~(1 << 1); PORTL &= ~(1 << 1);
PORTH &= ~(1 << 5); PORTH &= ~(1 << 5);
}
// Leave WE low for at least 60ns // Leave WR low for at least 60ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
if (retrode_mode) {
// Switch WR(PL5) and OE/CE(PH6) to HIGH
PORTH |= (1 << 6);
PORTL |= (1 << 5);
} else {
// Switch CE(PL1) and WR(PH5) to HIGH // Switch CE(PL1) and WR(PH5) to HIGH
PORTH |= (1 << 5); PORTH |= (1 << 5);
PORTL |= (1 << 1); PORTL |= (1 << 1);
}
// Leave WE high for at least 50ns // Leave WR high for at least 50ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
if (retrode_mode) {
// Set Data Pins (D8-D15) to Input
DDRA = 0x00;
} else {
// Set Data Pins (D0-D7) to Input // Set Data Pins (D0-D7) to Input
DDRC = 0x00; DDRC = 0x00;
}
} }
byte readByte_SMS(word myAddress) { byte readByte_SMS(word myAddress) {
if (retrode_mode) {
// Set Data Pins (D8-D15) to Input
DDRA = 0x00;
} else {
// Set Data Pins (D0-D7) to Input // Set Data Pins (D0-D7) to Input
DDRC = 0x00; DDRC = 0x00;
}
// Set Address // Set Address
PORTF = myAddress & 0xFF; PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF; PORTK = (myAddress >> 8) & 0xFF;
if (!retrode_mode) {
// CE(PH3) and OE(PH6) are connected
PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000); PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000);
}
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
if (retrode_mode) {
// Switch RD(PL6) and OE(PH6) to LOW
PORTL &= ~(1 << 6);
PORTH &= ~(1 << 6);
} else {
// Switch CE(PL1) and OE(PH6) to LOW // Switch CE(PL1) and OE(PH6) to LOW
PORTL &= ~(1 << 1); PORTL &= ~(1 << 1);
PORTH &= ~(1 << 6); PORTH &= ~(1 << 6);
}
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Read // Read
byte tempByte = PINC; byte tempByte = retrode_mode ? PINA : PINC;
if (retrode_mode) {
// Switch RD(PL6) and OE(PH6) to HIGH
PORTH |= (1 << 6);
PORTL |= (1 << 6);
} else {
// Switch CE(PL1) and OE(PH6) to HIGH // Switch CE(PL1) and OE(PH6) to HIGH
PORTH |= (1 << 6); PORTH |= (1 << 6);
PORTL |= (1 << 1); PORTL |= (1 << 1);
}
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
@ -186,7 +267,11 @@ void getCartInfo_SMS() {
cartSize = 128 * 1024UL; cartSize = 128 * 1024UL;
break; break;
case 0x0: case 0x0:
if (retrode_mode) {
cartSize = 512 * 1024UL;
} else {
cartSize = 256 * 1024UL; cartSize = 256 * 1024UL;
}
break; break;
case 0x1: case 0x1:
cartSize = 512 * 1024UL; cartSize = 512 * 1024UL;