mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-24 12:01:53 +01:00
Add support for Super A'can flash cart
This commit is contained in:
parent
b57470510d
commit
79f2a2b16a
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user