Add support for Super A'can flash cart

This commit is contained in:
splash5 2023-01-24 16:34:54 +08:00
parent b57470510d
commit 79f2a2b16a
2 changed files with 180 additions and 22 deletions

View File

@ -147,7 +147,7 @@ char ver[5] = "12.3";
//#define enable_WS
// Super A'can
#define enable_SUPRACAN
// #define enable_SUPRACAN
//******************************************
// HW CONFIGS
@ -1007,9 +1007,9 @@ static const char modeItem16[] PROGMEM = "Magnavox Odyssey 2";
static const char modeItem17[] PROGMEM = "Arcadia 2001";
static const char modeItem18[] PROGMEM = "Fairchild Channel F";
static const char modeItem19[] PROGMEM = "Flashrom Programmer";
static const char modeItem99[] PROGMEM = "Super A'can";
static const char modeItem20[] PROGMEM = "About";
static const char* const modeOptions[] PROGMEM = { modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6, modeItem7, modeItem8, modeItem9, modeItem10, modeItem11, modeItem12, modeItem13, modeItem14, modeItem15, modeItem16, modeItem17, modeItem18, modeItem99, modeItem19, modeItem20 };
static const char modeItem99[] PROGMEM = "Super A'can";
static const char* const modeOptions[] PROGMEM = { modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6, modeItem7, modeItem8, modeItem9, modeItem10, modeItem11, modeItem12, modeItem13, modeItem14, modeItem15, modeItem16, modeItem17, modeItem18, modeItem19, modeItem20, modeItem99 };
// All included slots
void mainMenu() {
@ -1032,7 +1032,7 @@ void mainMenu() {
num_answers = 7;
} else { // currPage == 3
option_offset = 14;
num_answers = 6;
num_answers = 7;
}
// Copy menuOptions out of progmem
convertPgm(modeOptions + option_offset, num_answers);
@ -1177,11 +1177,6 @@ void mainMenu() {
case 17:
setup_FAIRCHILD();
fairchildMenu();
#ifdef enable_SUPRACAN
case 99:
setup_SuprAcan();
mode = mode_SUPRACAN;
break;
#endif
@ -1199,6 +1194,12 @@ void mainMenu() {
aboutScreen();
break;
#ifdef enable_SUPRACAN
case 20:
setup_SuprAcan();
break;
#endif
default:
print_MissingModule(); // does not return
}
@ -1227,8 +1228,9 @@ static const char addonsItem1[] PROGMEM = "70s Consoles";
static const char addonsItem2[] PROGMEM = "80s Consoles";
static const char addonsItem3[] PROGMEM = "Handhelds";
static const char addonsItem4[] PROGMEM = "Flashrom Programmer";
static const char addonsItem5[] PROGMEM = "90s Consoles";
//static const char addonsItem5[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const addonsOptions[] PROGMEM = { addonsItem1, addonsItem2, addonsItem3, addonsItem4, string_reset2 };
static const char* const addonsOptions[] PROGMEM = { addonsItem1, addonsItem2, addonsItem3, addonsItem4, string_reset2, addonsItem5 };
// 70s Consoles submenu
static const char consoles70Item1[] PROGMEM = "Atari 2600";
@ -1316,8 +1318,8 @@ void addonMenu() {
// create menu with title and 5 options to choose from
unsigned char addonsMenu;
// Copy menuOptions out of progmem
convertPgm(addonsOptions, 5);
addonsMenu = question_box(F("Type"), menuOptions, 5, 0);
convertPgm(addonsOptions, 6);
addonsMenu = question_box(F("Type"), menuOptions, 6, 0);
// wait for user choice to come back from the question box menu
switch (addonsMenu) {
@ -1350,6 +1352,10 @@ void addonMenu() {
resetArduino();
break;
case 5:
consoles90Menu();
break;
default:
print_MissingModule(); // does not return
}
@ -1460,6 +1466,31 @@ void consoles80Menu() {
}
}
// Everything that needs an adapter
void consoles90Menu() {
unsigned char consoles90Menu;
// Copy menuOptions out of progmem
convertPgm(consoles90Options, 2);
consoles90Menu = question_box(F("Choose Adapter"), menuOptions, 2, 0);
// wait for user choice to come back from the question box menu
switch (consoles90Menu) {
#ifdef enable_SUPRACAN
case 0:
setup_SuprAcan();
break;
#endif
case 1:
resetArduino();
break;
default:
print_MissingModule(); // does not return
break;
}
}
// Everything that needs an adapter
void handheldMenu() {
// create menu with title and 6 options to choose from
@ -3524,6 +3555,11 @@ void loop() {
else if (mode == mode_FAIRCHILD) {
fairchildMenu();
}
#endif
#ifdef enable_SUPRACAN
else if (mode == mode_SUPRACAN) {
suprAcanMenu();
}
#endif
else {
display_Clear();

View File

@ -11,8 +11,9 @@ static const char acanMenuItem2[] PROGMEM = "Read Save";
static const char acanMenuItem3[] PROGMEM = "Write Save";
static const char acanMenuItem4[] PROGMEM = "Read UM6650";
static const char acanMenuItem5[] PROGMEM = "Write UM6650";
static const char acanMenuItem6[] PROGMEM = "Flash...";
static const char* const menuOptionsAcan[] PROGMEM = {acanMenuItem1, acanMenuItem2, acanMenuItem3, acanMenuItem4, acanMenuItem5, string_reset2};
static const char* const menuOptionsAcan[] PROGMEM = {acanMenuItem1, acanMenuItem2, acanMenuItem3, acanMenuItem4, acanMenuItem5, string_reset2, acanMenuItem6};
void setup_SuprAcan()
{
@ -34,11 +35,33 @@ void setup_SuprAcan()
PORTH |= ((1 << 3) | (1 << 5) | (1 << 6));
PORTH &= ~((1 << 0) | (1 << 4));
// set /CARTIN(PG5) input
DDRG &= ~(1 << 5);
// set 6619_124(PE4) input
DDRE &= ~(1 << 4);
// detect if flash chip exists
PORTG |= (1 << 5);
DDRG |= (1 << 5);
PORTG |= (1 << 5);
dataOut_MD();
writeWord_Acan(0xaaaa, 0xaaaa);
writeWord_Acan(0x5555, 0x5555);
writeWord_Acan(0xaaaa, 0x9090);
dataIn_MD();
eepbit[0] = readWord_Acan(0x2);
eepbit[1] = readWord_Acan(0x0);
dataOut_MD();
writeWord_Acan(0x0, 0xf0f0);
dataIn_MD();
// set /CARTIN(PG5) input
PORTG &= ~(1 << 5);
DDRG &= ~(1 << 5);
*((uint32_t*)(eepbit + 4)) = getFlashChipSize_Acan(*((uint16_t*)eepbit));
display_Clear();
initializeClockOffset();
@ -86,10 +109,13 @@ void setup_SuprAcan()
void suprAcanMenu()
{
uint8_t mainMenu;
uint8_t mainMenu = 6;
convertPgm(menuOptionsAcan, 6);
mainMenu = question_box(F("Super A'can Menu"), menuOptions, 6, 0);
if (*((uint32_t*)(eepbit + 4)) > 0)
mainMenu = 7;
convertPgm(menuOptionsAcan, mainMenu);
mainMenu = question_box(F("Super A'can Menu"), menuOptions, mainMenu, 0);
switch (mainMenu)
{
@ -120,6 +146,11 @@ void suprAcanMenu()
verifyUM6650();
break;
}
case 6:
{
flashCart_Acan();
break;
}
default:
{
resetCart_Acan();
@ -139,7 +170,7 @@ static void readROM_Acan()
uint32_t crc32 = 0xffffffff;
EEPROM_readAnything(0, foldern);
snprintf(folder, FILEPATH_LENGTH, "ACAN/ROM/%d", foldern);
snprintf(folder, FILEPATH_LENGTH, "/ACAN/ROM/%d", foldern);
display_Clear();
print_STR(saving_to_STR, 0);
@ -187,7 +218,7 @@ static void readSRAM_Acan()
{
// create a new folder for storing rom file
EEPROM_readAnything(0, foldern);
snprintf(folder, FILEPATH_LENGTH, "ACAN/SAVE/%d", foldern);
snprintf(folder, FILEPATH_LENGTH, "/ACAN/SAVE/%d", foldern);
display_Clear();
print_STR(saving_to_STR, 0);
@ -220,7 +251,7 @@ static void readSRAM_Acan()
static void writeSRAM_Acan()
{
filePath[0] = 0;
sd.chdir("/");
sd.chdir();
fileBrowser(F("Select a file"));
snprintf(filePath, FILEPATH_LENGTH, "%s/%s", filePath, fileName);
@ -297,7 +328,7 @@ static void readUM6650()
{
// create a new folder for storing rom file
EEPROM_readAnything(0, foldern);
snprintf(folder, sizeof(folder), "ACAN/UM6650/%d", foldern);
snprintf(folder, sizeof(folder), "/ACAN/UM6650/%d", foldern);
display_Clear();
print_STR(saving_to_STR, 0);
@ -404,6 +435,84 @@ static void writeUM6650()
print_STR(done_STR, 1);
}
static void flashCart_Acan()
{
uint32_t *flash_size = (uint32_t*)(eepbit + 4);
filePath[0] = 0;
sd.chdir();
fileBrowser(F("Select a file"));
snprintf(filePath, FILEPATH_LENGTH, "%s/%s", filePath, fileName);
display_Clear();
if (!myFile.open(filePath, O_READ))
{
print_Error(F("File doesn't exist"));
return;
}
print_Msg(F("Writing "));
print_Msg(filePath + 1);
println_Msg(F("..."));
display_Update();
uint32_t i, j, k, file_length = myFile.fileSize();
uint16_t data;
DDRG |= (1 << 5);
PORTG |= (1 << 5);
draw_progressbar(0, file_length);
for (i = 0; i < file_length; i += *flash_size)
{
// erase chip
dataOut_MD();
writeWord_Acan(i + 0xaaaa, 0xaaaa);
writeWord_Acan(i + 0x5555, 0x5555);
writeWord_Acan(i + 0xaaaa, 0x8080);
writeWord_Acan(i + 0xaaaa, 0xaaaa);
writeWord_Acan(i + 0x5555, 0x5555);
writeWord_Acan(i + 0xaaaa, 0x1010);
dataIn_MD();
while (readWord_Acan(i) != 0xffff);
for (j = 0; j < *flash_size; j += 512)
{
myFile.read(sdBuffer, 512);
for (k = 0; k < 512; k += 2)
{
data = *((uint16_t*)(sdBuffer + k));
dataOut_MD();
writeWord_Acan(i + 0xaaaa, 0xaaaa);
writeWord_Acan(i + 0x5555, 0x5555);
writeWord_Acan(i + 0xaaaa, 0xa0a0);
writeWord_Acan(i + j + k, data);
dataIn_MD();
while (readWord_Acan(i + j + k) != data);
}
draw_progressbar(i + j + k, file_length);
if ((j & 0xfff) == 0)
blinkLED();
}
}
PORTG &= ~(1 << 5);
DDRG &= ~(1 << 5);
myFile.close();
print_STR(done_STR, 1);
display_Update();
}
static uint32_t checkRomSize_Acan()
{
uint32_t addr = 0;
@ -559,4 +668,17 @@ static uint16_t readWord_Acan(uint32_t addr)
return data;
}
static uint32_t getFlashChipSize_Acan(uint16_t chip_id)
{
// 0x0458 (8M), 0x01ab (4M), 0x01d8 (16M)
switch (chip_id)
{
case 0x01ab: return 524288;
case 0x0458: return 1048576;
case 0x01d8: return 2097152;
}
return 0;
}
#endif