mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-24 05:29:17 +01:00
Retrode SMS/GG adapter support
This commit is contained in:
parent
c385323ce3
commit
bc3dd3dd13
@ -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,15 +72,30 @@ void setup_SMS() {
|
|||||||
//A15
|
//A15
|
||||||
DDRH |= (1 << 3);
|
DDRH |= (1 << 3);
|
||||||
|
|
||||||
// Set Control Pins to Output RST(PH0) WR(PH5) OE(PH6)
|
if (retrode_mode) {
|
||||||
DDRH |= (1 << 0) | (1 << 5) | (1 << 6);
|
// Set Control Pins to Output OE(PH6)
|
||||||
// CE(PL1)
|
DDRH |= (1 << 6);
|
||||||
DDRL |= (1 << 1);
|
// WR(PL5) and RD(PL6)
|
||||||
|
DDRL |= (1 << 5) | (1 << 6);
|
||||||
|
|
||||||
// Setting RST(PH0) WR(PH5) OE(PH6) HIGH
|
// Setting OE(PH6) HIGH
|
||||||
PORTH |= (1 << 0) | (1 << 5) | (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
// CE(PL1)
|
//PORTH &= ~(1 << 6); // set OE LOW
|
||||||
PORTL |= (1 << 1);
|
// 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
|
// 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) {
|
||||||
// Set Data Pins (D0-D7) to Output
|
if (retrode_mode) {
|
||||||
DDRC = 0xFF;
|
// Set Data Pins (D8-D15) to Output
|
||||||
|
DDRA = 0xFF;
|
||||||
|
} else {
|
||||||
|
// Set Data Pins (D0-D7) to Output
|
||||||
|
DDRC = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
// Set address
|
// Set address
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 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
|
// Output data
|
||||||
PORTC = myData;
|
if (retrode_mode) {
|
||||||
|
PORTA = myData;
|
||||||
|
} else {
|
||||||
|
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");
|
||||||
|
|
||||||
// Switch CE(PL1) and WR(PH5) to LOW
|
if (retrode_mode) {
|
||||||
PORTL &= ~(1 << 1);
|
// Switch WR(PL5) and OE/CE(PH6) to LOW
|
||||||
PORTH &= ~(1 << 5);
|
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");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
// Switch CE(PL1) and WR(PH5) to HIGH
|
if (retrode_mode) {
|
||||||
PORTH |= (1 << 5);
|
// Switch WR(PL5) and OE/CE(PH6) to HIGH
|
||||||
PORTL |= (1 << 1);
|
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");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
// Set Data Pins (D0-D7) to Input
|
if (retrode_mode) {
|
||||||
DDRC = 0x00;
|
// Set Data Pins (D8-D15) to Input
|
||||||
|
DDRA = 0x00;
|
||||||
|
} else {
|
||||||
|
// Set Data Pins (D0-D7) to Input
|
||||||
|
DDRC = 0x00;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte readByte_SMS(word myAddress) {
|
byte readByte_SMS(word myAddress) {
|
||||||
// Set Data Pins (D0-D7) to Input
|
if (retrode_mode) {
|
||||||
DDRC = 0x00;
|
// Set Data Pins (D8-D15) to Input
|
||||||
|
DDRA = 0x00;
|
||||||
|
} else {
|
||||||
|
// Set Data Pins (D0-D7) to Input
|
||||||
|
DDRC = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
// Set Address
|
// Set Address
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 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");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
// Switch CE(PL1) and OE(PH6) to LOW
|
if (retrode_mode) {
|
||||||
PORTL &= ~(1 << 1);
|
// Switch RD(PL6) and OE(PH6) to LOW
|
||||||
PORTH &= ~(1 << 6);
|
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");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = retrode_mode ? PINA : PINC;
|
||||||
|
|
||||||
// Switch CE(PL1) and OE(PH6) to HIGH
|
if (retrode_mode) {
|
||||||
PORTH |= (1 << 6);
|
// Switch RD(PL6) and OE(PH6) to HIGH
|
||||||
PORTL |= (1 << 1);
|
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");
|
__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:
|
||||||
cartSize = 256 * 1024UL;
|
if (retrode_mode) {
|
||||||
|
cartSize = 512 * 1024UL;
|
||||||
|
} else {
|
||||||
|
cartSize = 256 * 1024UL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
cartSize = 512 * 1024UL;
|
cartSize = 512 * 1024UL;
|
||||||
|
Loading…
Reference in New Issue
Block a user