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