diff --git a/Cart_Reader/SMS.ino b/Cart_Reader/SMS.ino index a8b8b3c..7c093d8 100644 --- a/Cart_Reader/SMS.ino +++ b/Cart_Reader/SMS.ino @@ -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;