mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-26 14:34:15 +01:00
2cf7f5dbe7
The `setVoltage()` function should be called even when `ENABLE_VSELECT` is disabled because `ENABLE_3V3FIX` also uses it. There is no resource cost to do this as when both options are disabled the compiler will optimize this function out. This just "future proofs" the code so if that function ever does more it doesn't need updated everywhere. This applies to `setup_FlashVoltage()` as well. The changes to OSCR.cpp are just for code formatting and additional comments to clarify this.
678 lines
17 KiB
C++
678 lines
17 KiB
C++
//******************************************
|
|
// MAGNAVOX ODYSSEY 2 MODULE
|
|
//******************************************
|
|
#if defined(enable_ODY2)
|
|
// Magnavox Odyssey 2
|
|
// Philips Videopac/Videopac+
|
|
// Cartridge Pinout
|
|
// 30P 3.96mm pitch connector
|
|
//
|
|
// FRONT BACK
|
|
// SIDE SIDE
|
|
// +------+
|
|
// T0 -| 1 A |- /WR
|
|
// D0 -| 2 B |- GND
|
|
// D1 -| 3 C |- GND
|
|
// D2 -| 4 D |- VCC (+5V)
|
|
// D3 -| 5 E |- CS3
|
|
// D4 -| 6 F |- /PSEN (/CE)
|
|
// D5 -| 7 G |- A0
|
|
// D6 -| 8 H |- A1
|
|
// D7 -| 9 J |- A2
|
|
// A10 (P22) -| 10 K |- A3
|
|
// /CS1 (P14) -| 11 L |- A4
|
|
// P11 -| 12 M |- A5
|
|
// P10 -| 13 N |- A7
|
|
// A11 (P23) -| 14 P |- A6
|
|
// A9 (P21) -| 15 R |- A8 (P20)
|
|
// +------+
|
|
//
|
|
// NOTE: ADDRESS A7/A6 PIN ORDER ON PINS N & P.
|
|
// NOTE: MOST CARTS DO NOT CONNECT A10 ON PIN 10.
|
|
//
|
|
// BACK
|
|
// +---------------------------------------------+
|
|
// | A B C D E F G H J K L M N P R |
|
|
// LEFT | | RIGHT
|
|
// | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
|
// +---------------------------------------------+
|
|
// FRONT
|
|
//
|
|
// CONTROL PINS:
|
|
// T0(PH0) - SNES RESET
|
|
// CS3(PH3) - SNES /CS
|
|
// /CS1(PH4) - SNES /IRQ
|
|
// /WR(PH5) - SNES /WR
|
|
// /PSEN(PH6) - SNES /RD
|
|
|
|
byte ODY2[] = { 2, 4, 8, 12, 16 };
|
|
byte ody2lo = 0; // Lowest Entry
|
|
byte ody2hi = 4; // Highest Entry
|
|
|
|
byte ody2mapper;
|
|
byte newody2mapper;
|
|
byte ody2size;
|
|
byte newody2size;
|
|
|
|
// EEPROM MAPPING
|
|
// 07 MAPPER
|
|
// 08 ROM SIZE
|
|
|
|
//******************************************
|
|
// Menu
|
|
//******************************************
|
|
// Base Menu
|
|
static const char ody2MenuItem1[] PROGMEM = "Select Cart";
|
|
static const char ody2MenuItem2[] PROGMEM = "Read ROM";
|
|
static const char ody2MenuItem3[] PROGMEM = "Set Size";
|
|
static const char ody2MenuItem4[] PROGMEM = "Reset";
|
|
static const char* const menuOptionsODY2[] PROGMEM = { ody2MenuItem1, ody2MenuItem2, ody2MenuItem3, ody2MenuItem4 };
|
|
|
|
void setup_ODY2() {
|
|
// Request 5V
|
|
setVoltage(VOLTS_SET_5V);
|
|
|
|
// Set Address Pins to Output
|
|
// Odyssey 2 uses A0-A13 [A14-A23 UNUSED]
|
|
//A0-A7
|
|
DDRF = 0xFF;
|
|
//A8-A15
|
|
DDRK = 0xFF;
|
|
//A16-A23
|
|
DDRL = 0xFF;
|
|
|
|
// Set Control Pins to Output
|
|
// T0(PH0) ---(PH1) CS3(PH3) /CS1(PH4) /WR(PH5) /RD(PH6)
|
|
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
|
|
|
// Set TIME(PJ0) to Output (UNUSED)
|
|
DDRJ |= (1 << 0);
|
|
|
|
// Set Pins (D0-D7) to Input
|
|
DDRC = 0x00;
|
|
|
|
// Setting Control Pins to HIGH
|
|
// T0(PH0) ---(PH1) /CS1(PH4) /WR(PH5) /RD(PH6)
|
|
PORTH |= (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6);
|
|
|
|
// Set CS3(PH3) to LOW
|
|
PORTH &= ~(1 << 3);
|
|
|
|
// Set Unused Data Pins (PA0-PA7) to Output
|
|
DDRA = 0xFF;
|
|
|
|
// Set Unused Pins HIGH
|
|
PORTA = 0xFF;
|
|
PORTL = 0xFF; // A16-A23
|
|
PORTJ |= (1 << 0); // TIME(PJ0)
|
|
|
|
checkStatus_ODY2();
|
|
strcpy(romName, "ODYSSEY2");
|
|
|
|
mode = mode_ODY2;
|
|
}
|
|
|
|
void ody2Menu() {
|
|
convertPgm(menuOptionsODY2, 4);
|
|
uint8_t mainMenu = question_box(F("ODYSSEY 2 MENU"), menuOptions, 4, 0);
|
|
|
|
switch (mainMenu) {
|
|
case 0:
|
|
// Select Cart
|
|
setCart_ODY2();
|
|
wait();
|
|
setup_ODY2();
|
|
break;
|
|
|
|
case 1:
|
|
// Read ROM
|
|
sd.chdir("/");
|
|
readROM_ODY2();
|
|
sd.chdir("/");
|
|
break;
|
|
|
|
case 2:
|
|
// Set Size
|
|
setROMSize_ODY2();
|
|
break;
|
|
|
|
case 3:
|
|
// reset
|
|
resetArduino();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//******************************************
|
|
// READ CODE
|
|
//******************************************
|
|
|
|
uint8_t readData_ODY2(uint16_t addr) {
|
|
PORTF = addr & 0xFF; // A0-A7
|
|
PORTK = (addr >> 8) & 0xFF; // A8-A13
|
|
|
|
// Set /PSEN (/CE) to LOW
|
|
PORTH &= ~(1 << 6); // /PSEN LOW (ENABLE)
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
|
|
uint8_t ret = PINC;
|
|
|
|
// Pull /PSEN (/CE) to HIGH
|
|
PORTH |= (1 << 6); // /PSEN HIGH (DISABLE)
|
|
|
|
return ret;
|
|
}
|
|
|
|
void readSegment_ODY2(uint16_t startaddr, uint16_t endaddr) {
|
|
for (uint16_t addr = startaddr; addr < endaddr; addr += 512) {
|
|
for (int w = 0; w < 512; w++) {
|
|
uint8_t temp = readData_ODY2(addr + w);
|
|
sdBuffer[w] = temp;
|
|
}
|
|
myFile.write(sdBuffer, 512);
|
|
}
|
|
}
|
|
|
|
void bankSwitch_ODY2(uint16_t addr, uint8_t data) {
|
|
PORTF = addr & 0xFF; // A0-A7
|
|
PORTK = (addr >> 8) & 0xFF; // A8-A13
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
|
|
// Set /CS1(PH4) to LOW
|
|
PORTH &= ~(1 << 4);
|
|
// Set /WR(PH5) to LOW
|
|
PORTH &= ~(1 << 5);
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
|
|
DDRC = 0xFF; // Set to Output
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
|
|
PORTC = data;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
NOP;
|
|
|
|
// Set /WR(PH5) to HIGH
|
|
PORTH |= (1 << 5);
|
|
// Set /CS1(PH4) to HIGH
|
|
PORTH |= (1 << 4);
|
|
|
|
DDRC = 0x00; // Reset to Input
|
|
}
|
|
|
|
void readROM_ODY2() {
|
|
strcpy(fileName, romName);
|
|
strcat(fileName, ".bin");
|
|
|
|
// create a new folder for storing rom file
|
|
EEPROM_readAnything(0, foldern);
|
|
sprintf(folder, "ODY2/ROM/%d", foldern);
|
|
sd.mkdir(folder, true);
|
|
sd.chdir(folder);
|
|
|
|
display_Clear();
|
|
print_Msg(F("Saving to "));
|
|
print_Msg(folder);
|
|
println_Msg(F("/..."));
|
|
display_Update();
|
|
|
|
// open file on sdcard
|
|
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
|
print_FatalError(create_file_STR);
|
|
}
|
|
|
|
// write new folder number back to EEPROM
|
|
foldern++;
|
|
EEPROM_writeAnything(0, foldern);
|
|
|
|
if (ody2mapper == 1) { // A10 CONNECTED
|
|
// Videopac 31: Musician
|
|
// Videopac 40: 4 in 1 Row/4 en 1 Ligne
|
|
readSegment_ODY2(0x0000, 0x1000); // 4K
|
|
}
|
|
// A10 NOT CONNECTED
|
|
else if (ody2size > 2) { // 12K/16K (BANKSWITCH)
|
|
// Videopac+ 55: Neutron Star 12K = 2K x 6 Banks
|
|
// Videopac+ 58: Norseman 12K = 2K x 6 Banks
|
|
// Videopac+ 59: Helicopter Rescue 16K = 2K x 8 Banks
|
|
// Videopac+ 60: Trans American Rally 16K = 2K x 8 Banks
|
|
uint8_t ody2banks = (ody2size * 4) / 2;
|
|
for (int x = (ody2banks - 1); x >= 0; x--) {
|
|
bankSwitch_ODY2(0x80, ~x);
|
|
readSegment_ODY2(0x0400, 0x0C00); // 2K x 6/8 = 12K/16K
|
|
}
|
|
} else { // STANDARD SIZES
|
|
readSegment_ODY2(0x0400, 0x0C00); // 2K
|
|
if (ody2size > 0) {
|
|
readSegment_ODY2(0x1400, 0x1C00); // +2K = 4K
|
|
if (ody2size > 1) {
|
|
readSegment_ODY2(0x2400, 0x2C00); // +2K = 6K
|
|
readSegment_ODY2(0x3400, 0x3C00); // +2K = 8K
|
|
}
|
|
}
|
|
}
|
|
myFile.close();
|
|
|
|
unsigned long crcsize = ODY2[ody2size] * 0x400;
|
|
calcCRC(fileName, crcsize, NULL, 0);
|
|
|
|
println_Msg(F(""));
|
|
print_STR(press_button_STR, 1);
|
|
display_Update();
|
|
wait();
|
|
}
|
|
|
|
//******************************************
|
|
// ROM SIZE
|
|
//******************************************
|
|
|
|
void setROMSize_ODY2() {
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
if (ody2lo == ody2hi)
|
|
newody2size = ody2lo;
|
|
else {
|
|
int b = 0;
|
|
int i = ody2lo;
|
|
|
|
display_Clear();
|
|
print_Msg(F("ROM Size: "));
|
|
println_Msg(ODY2[i]);
|
|
println_Msg(F(""));
|
|
#if defined(enable_OLED)
|
|
print_STR(press_to_change_STR, 1);
|
|
print_STR(right_to_select_STR, 1);
|
|
#elif defined(enable_LCD)
|
|
print_STR(rotate_to_change_STR, 1);
|
|
print_STR(press_to_select_STR, 1);
|
|
#endif
|
|
display_Update();
|
|
|
|
while (1) {
|
|
b = checkButton();
|
|
if (b == 2) { // Previous (doubleclick)
|
|
if (i == ody2lo)
|
|
i = ody2hi;
|
|
else
|
|
i--;
|
|
|
|
// Only update display after input because of slow LCD library
|
|
display_Clear();
|
|
print_Msg(F("ROM Size: "));
|
|
println_Msg(ODY2[i]);
|
|
println_Msg(F(""));
|
|
#if defined(enable_OLED)
|
|
print_STR(press_to_change_STR, 1);
|
|
print_STR(right_to_select_STR, 1);
|
|
#elif defined(enable_LCD)
|
|
print_STR(rotate_to_change_STR, 1);
|
|
print_STR(press_to_select_STR, 1);
|
|
#endif
|
|
display_Update();
|
|
}
|
|
if (b == 1) { // Next (press)
|
|
if (i == ody2hi)
|
|
i = ody2lo;
|
|
else
|
|
i++;
|
|
|
|
// Only update display after input because of slow LCD library
|
|
display_Clear();
|
|
print_Msg(F("ROM Size: "));
|
|
println_Msg(ODY2[i]);
|
|
println_Msg(F(""));
|
|
#if defined(enable_OLED)
|
|
print_STR(press_to_change_STR, 1);
|
|
print_STR(right_to_select_STR, 1);
|
|
#elif defined(enable_LCD)
|
|
print_STR(rotate_to_change_STR, 1);
|
|
print_STR(press_to_select_STR, 1);
|
|
#endif
|
|
display_Update();
|
|
}
|
|
if (b == 3) { // Long Press - Execute (hold)
|
|
newody2size = i;
|
|
break;
|
|
}
|
|
}
|
|
display.setCursor(0, 56); // Display selection at bottom
|
|
}
|
|
print_Msg(F("ROM SIZE "));
|
|
print_Msg(ODY2[newody2size]);
|
|
println_Msg(F("K"));
|
|
display_Update();
|
|
delay(1000);
|
|
#else
|
|
if (ody2lo == ody2hi)
|
|
newody2size = ody2lo;
|
|
else {
|
|
setrom:
|
|
String sizeROM;
|
|
for (int i = 0; i < (ody2hi - ody2lo + 1); i++) {
|
|
Serial.print(F("Select ROM Size: "));
|
|
Serial.print(i);
|
|
Serial.print(F(" = "));
|
|
Serial.print(ODY2[i + ody2lo]);
|
|
Serial.println(F("K"));
|
|
}
|
|
Serial.print(F("Enter ROM Size: "));
|
|
while (Serial.available() == 0) {}
|
|
sizeROM = Serial.readStringUntil('\n');
|
|
Serial.println(sizeROM);
|
|
newody2size = sizeROM.toInt() + ody2lo;
|
|
if (newody2size > ody2hi) {
|
|
Serial.println(F("SIZE NOT SUPPORTED"));
|
|
Serial.println(F(""));
|
|
goto setrom;
|
|
}
|
|
}
|
|
Serial.print(F("ROM Size = "));
|
|
Serial.print(ODY2[newody2size]);
|
|
Serial.println(F("K"));
|
|
#endif
|
|
EEPROM_writeAnything(8, newody2size);
|
|
ody2size = newody2size;
|
|
}
|
|
|
|
void checkStatus_ODY2() {
|
|
EEPROM_readAnything(7, ody2mapper);
|
|
EEPROM_readAnything(8, ody2size);
|
|
if (ody2mapper > 1) {
|
|
ody2mapper = 0;
|
|
EEPROM_writeAnything(7, ody2mapper);
|
|
}
|
|
if (ody2size > 4) {
|
|
ody2size = 0;
|
|
EEPROM_writeAnything(8, ody2size);
|
|
}
|
|
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
println_Msg(F("ODYSSEY 2 READER"));
|
|
println_Msg(F("CURRENT SETTINGS"));
|
|
println_Msg(F(""));
|
|
print_Msg(F("MAPPER: "));
|
|
println_Msg(ody2mapper);
|
|
print_Msg(F("ROM SIZE: "));
|
|
print_Msg(ODY2[ody2size]);
|
|
println_Msg(F("K"));
|
|
display_Update();
|
|
wait();
|
|
#else
|
|
Serial.print(F("CURRENT MAPPER: "));
|
|
Serial.println(ody2mapper);
|
|
Serial.print(F("CURRENT ROM SIZE: "));
|
|
Serial.print(ODY2[ody2size]);
|
|
Serial.println(F("K"));
|
|
Serial.println(F(""));
|
|
#endif
|
|
}
|
|
|
|
//******************************************
|
|
// CART SELECT CODE
|
|
//******************************************
|
|
|
|
FsFile ody2csvFile;
|
|
char ody2game[51]; // title
|
|
char ody2mm[3]; // mapper (A10)
|
|
char ody2rr[3]; // romsize
|
|
char ody2ll[4]; // linelength (previous line)
|
|
unsigned long ody2csvpos; // CSV File Position
|
|
char ody2cartCSV[] = "ody2cart.txt"; // CSV List
|
|
char ody2csvEND[] = "EOF"; // CSV End Marker for scrolling
|
|
|
|
bool readLine_ODY2(FsFile& f, char* line, size_t maxLen) {
|
|
for (size_t n = 0; n < maxLen; n++) {
|
|
int c = f.read();
|
|
if (c < 0 && n == 0) return false; // EOF
|
|
if (c < 0 || c == '\n') {
|
|
line[n] = 0;
|
|
return true;
|
|
}
|
|
line[n] = c;
|
|
}
|
|
return false; // line too long
|
|
}
|
|
|
|
bool readVals_ODY2(char* ody2game, char* ody2mm, char* ody2rr, char* ody2ll) {
|
|
char line[59];
|
|
ody2csvpos = ody2csvFile.position();
|
|
if (!readLine_ODY2(ody2csvFile, line, sizeof(line))) {
|
|
return false; // EOF or too long
|
|
}
|
|
char* comma = strtok(line, ",");
|
|
int x = 0;
|
|
while (comma != NULL) {
|
|
if (x == 0)
|
|
strcpy(ody2game, comma);
|
|
else if (x == 1)
|
|
strcpy(ody2mm, comma);
|
|
else if (x == 2)
|
|
strcpy(ody2rr, comma);
|
|
else if (x == 3)
|
|
strcpy(ody2ll, comma);
|
|
comma = strtok(NULL, ",");
|
|
x += 1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool getCartListInfo_ODY2() {
|
|
bool buttonreleased = 0;
|
|
bool cartselected = 0;
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
println_Msg(F(" HOLD TO FAST CYCLE"));
|
|
display_Update();
|
|
#else
|
|
Serial.println(F("HOLD BUTTON TO FAST CYCLE"));
|
|
#endif
|
|
delay(2000);
|
|
#if defined(enable_OLED)
|
|
buttonVal1 = (PIND & (1 << 7)); // PD7
|
|
#elif defined(enable_LCD)
|
|
boolean buttonVal1 = (PING & (1 << 2)); //PG2
|
|
#endif
|
|
if (buttonVal1 == LOW) { // Button Held - Fast Cycle
|
|
while (1) { // Scroll Game List
|
|
while (readVals_ODY2(ody2game, ody2mm, ody2rr, ody2ll)) {
|
|
if (strcmp(ody2csvEND, ody2game) == 0) {
|
|
ody2csvFile.seek(0); // Restart
|
|
} else {
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
println_Msg(F("CART TITLE:"));
|
|
println_Msg(F(""));
|
|
println_Msg(ody2game);
|
|
display_Update();
|
|
#else
|
|
Serial.print(F("CART TITLE:"));
|
|
Serial.println(ody2game);
|
|
#endif
|
|
#if defined(enable_OLED)
|
|
buttonVal1 = (PIND & (1 << 7)); // PD7
|
|
#elif defined(enable_LCD)
|
|
buttonVal1 = (PING & (1 << 2)); //PG2
|
|
#endif
|
|
if (buttonVal1 == HIGH) { // Button Released
|
|
buttonreleased = 1;
|
|
break;
|
|
}
|
|
if (buttonreleased) {
|
|
buttonreleased = 0; // Reset Flag
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#if defined(enable_OLED)
|
|
buttonVal1 = (PIND & (1 << 7)); // PD7
|
|
#elif defined(enable_LCD)
|
|
buttonVal1 = (PING & (1 << 2)); //PG2
|
|
#endif
|
|
if (buttonVal1 == HIGH) // Button Released
|
|
break;
|
|
}
|
|
}
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display.setCursor(0, 56);
|
|
println_Msg(F("FAST CYCLE OFF"));
|
|
display_Update();
|
|
#else
|
|
Serial.println(F(""));
|
|
Serial.println(F("FAST CYCLE OFF"));
|
|
Serial.println(F("PRESS BUTTON TO STEP FORWARD"));
|
|
Serial.println(F("DOUBLE CLICK TO STEP BACK"));
|
|
Serial.println(F("HOLD TO SELECT"));
|
|
Serial.println(F(""));
|
|
#endif
|
|
while (readVals_ODY2(ody2game, ody2mm, ody2rr, ody2ll)) {
|
|
if (strcmp(ody2csvEND, ody2game) == 0) {
|
|
ody2csvFile.seek(0); // Restart
|
|
} else {
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
println_Msg(F("CART TITLE:"));
|
|
println_Msg(F(""));
|
|
println_Msg(ody2game);
|
|
display.setCursor(0, 48);
|
|
#if defined(enable_OLED)
|
|
print_STR(press_to_change_STR, 1);
|
|
print_STR(right_to_select_STR, 1);
|
|
#elif defined(enable_LCD)
|
|
print_STR(rotate_to_change_STR, 1);
|
|
print_STR(press_to_select_STR, 1);
|
|
#endif
|
|
display_Update();
|
|
#else
|
|
Serial.print(F("CART TITLE:"));
|
|
Serial.println(ody2game);
|
|
#endif
|
|
while (1) { // Single Step
|
|
int b = checkButton();
|
|
if (b == 1) { // Continue (press)
|
|
break;
|
|
}
|
|
if (b == 2) { // Reset to Start of List (doubleclick)
|
|
byte prevline = strtol(ody2ll, NULL, 10);
|
|
ody2csvpos -= prevline;
|
|
ody2csvFile.seek(ody2csvpos);
|
|
break;
|
|
}
|
|
if (b == 3) { // Long Press - Select Cart (hold)
|
|
newody2mapper = strtol(ody2mm, NULL, 10);
|
|
newody2size = strtol(ody2rr, NULL, 10);
|
|
EEPROM_writeAnything(7, newody2mapper);
|
|
EEPROM_writeAnything(8, newody2size);
|
|
cartselected = 1; // SELECTION MADE
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
println_Msg(F("SELECTION MADE"));
|
|
display_Update();
|
|
#else
|
|
Serial.println(F("SELECTION MADE"));
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
if (cartselected) {
|
|
cartselected = 0; // Reset Flag
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
println_Msg(F(""));
|
|
println_Msg(F("END OF FILE"));
|
|
display_Update();
|
|
#else
|
|
Serial.println(F("END OF FILE"));
|
|
#endif
|
|
|
|
return false;
|
|
}
|
|
|
|
void checkCSV_ODY2() {
|
|
if (getCartListInfo_ODY2()) {
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
println_Msg(F("CART SELECTED"));
|
|
println_Msg(F(""));
|
|
println_Msg(ody2game);
|
|
display_Update();
|
|
// Display Settings
|
|
display.setCursor(0, 56);
|
|
print_Msg(F("CODE: M"));
|
|
print_Msg(newody2mapper);
|
|
print_Msg(F("/R"));
|
|
println_Msg(newody2size);
|
|
display_Update();
|
|
#else
|
|
Serial.println(F(""));
|
|
Serial.println(F("CART SELECTED"));
|
|
Serial.println(ody2game);
|
|
// Display Settings
|
|
Serial.print(F("CODE: M"));
|
|
Serial.print(newody2mapper);
|
|
Serial.print(F("/R"));
|
|
Serial.println(newody2size);
|
|
Serial.println(F(""));
|
|
#endif
|
|
} else {
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display.setCursor(0, 56);
|
|
println_Msg(F("NO SELECTION"));
|
|
display_Update();
|
|
#else
|
|
Serial.println(F("NO SELECTION"));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void setCart_ODY2() {
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
println_Msg(ody2cartCSV);
|
|
display_Update();
|
|
#endif
|
|
sd.chdir();
|
|
sprintf(folder, "ODY2/CSV");
|
|
sd.chdir(folder); // Switch Folder
|
|
ody2csvFile = sd.open(ody2cartCSV, O_READ);
|
|
if (!ody2csvFile) {
|
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
|
display_Clear();
|
|
println_Msg(F("CSV FILE NOT FOUND!"));
|
|
display_Update();
|
|
#else
|
|
Serial.println(F("CSV FILE NOT FOUND!"));
|
|
#endif
|
|
while (1) {
|
|
if (checkButton() != 0)
|
|
setup_ODY2();
|
|
}
|
|
}
|
|
checkCSV_ODY2();
|
|
|
|
ody2csvFile.close();
|
|
}
|
|
#endif
|
|
//******************************************
|
|
// End of File
|
|
//******************************************
|