mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-23 21:19:16 +01:00
Move to Arduino IDE 2.0.0 (different auto formatting, no code changes)
This commit is contained in:
parent
6ddb206a63
commit
4badfff458
@ -34,9 +34,9 @@
|
||||
// /C000(PH5) - CHIP 2 - SNES /WR
|
||||
// /E000(PH6) - CHIP 3 - SNES /RD
|
||||
|
||||
byte COL[] = {8, 12, 16, 20, 24, 32};
|
||||
byte collo = 0; // Lowest Entry
|
||||
byte colhi = 5; // Highest Entry
|
||||
byte COL[] = { 8, 12, 16, 20, 24, 32 };
|
||||
byte collo = 0; // Lowest Entry
|
||||
byte colhi = 5; // Highest Entry
|
||||
|
||||
byte colsize;
|
||||
byte newcolsize;
|
||||
@ -52,10 +52,9 @@ static const char colMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char colMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char colMenuItem3[] PROGMEM = "Set Size";
|
||||
static const char colMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsCOL[] PROGMEM = {colMenuItem1, colMenuItem2, colMenuItem3, colMenuItem4};
|
||||
static const char* const menuOptionsCOL[] PROGMEM = { colMenuItem1, colMenuItem2, colMenuItem3, colMenuItem4 };
|
||||
|
||||
void setup_COL()
|
||||
{
|
||||
void setup_COL() {
|
||||
// Set Address Pins to Output
|
||||
// Colecovision uses A0-A14 [A15-A23 UNUSED]
|
||||
//A0-A7
|
||||
@ -67,10 +66,10 @@ void setup_COL()
|
||||
|
||||
// Set Control Pins to Output
|
||||
// ---(PH0) ---(PH1) /8000(PH3) /A000(PH4) /C000(PH5) /E000(PH6)
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set TIME(PJ0) to Output (UNUSED)
|
||||
DDRJ |= (1 << 0);
|
||||
DDRJ |= (1 << 0);
|
||||
|
||||
// Set Pins (D0-D7) to Input
|
||||
DDRC = 0x00;
|
||||
@ -84,8 +83,8 @@ void setup_COL()
|
||||
|
||||
// Set Unused Pins HIGH
|
||||
PORTA = 0xFF;
|
||||
PORTL = 0xFF; // A16-A23
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
PORTL = 0xFF; // A16-A23
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
|
||||
checkStatus_COL();
|
||||
strcpy(romName, "COLECO");
|
||||
@ -93,13 +92,11 @@ void setup_COL()
|
||||
mode = mode_COL;
|
||||
}
|
||||
|
||||
void colMenu()
|
||||
{
|
||||
void colMenu() {
|
||||
convertPgm(menuOptionsCOL, 4);
|
||||
uint8_t mainMenu = question_box(F("COLECOVISION MENU"), menuOptions, 4, 0);
|
||||
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
// Select Cart
|
||||
setCart_COL();
|
||||
@ -134,31 +131,29 @@ void colMenu()
|
||||
// /C000(PH5) - CHIP 2
|
||||
// /E000(PH6) - CHIP 3
|
||||
|
||||
uint8_t readData_COL(uint32_t addr)
|
||||
{
|
||||
uint8_t readData_COL(uint32_t addr) {
|
||||
// SELECT ROM CHIP - PULL /CE LOW
|
||||
uint8_t chipdecode = ((addr >> 13) & 0x3);
|
||||
if (chipdecode == 3) // CHIP 3
|
||||
PORTH &= ~(1 << 6); // /E000 LOW (ENABLE)
|
||||
else if (chipdecode == 2) // CHIP 2
|
||||
PORTH &= ~(1 << 5); // /C000 LOW (ENABLE)
|
||||
else if (chipdecode == 1) // CHIP 1
|
||||
PORTH &= ~(1 << 4); // /A000 LOW (ENABLE)
|
||||
else // CHIP 0
|
||||
PORTH &= ~(1 << 3); // /8000 LOW (ENABLE)
|
||||
if (chipdecode == 3) // CHIP 3
|
||||
PORTH &= ~(1 << 6); // /E000 LOW (ENABLE)
|
||||
else if (chipdecode == 2) // CHIP 2
|
||||
PORTH &= ~(1 << 5); // /C000 LOW (ENABLE)
|
||||
else if (chipdecode == 1) // CHIP 1
|
||||
PORTH &= ~(1 << 4); // /A000 LOW (ENABLE)
|
||||
else // CHIP 0
|
||||
PORTH &= ~(1 << 3); // /8000 LOW (ENABLE)
|
||||
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A15
|
||||
PORTF = addr & 0xFF; // A0-A7
|
||||
PORTK = (addr >> 8) & 0xFF; // A8-A15
|
||||
|
||||
// LATCH ADDRESS - PULL /CE HIGH
|
||||
PORTH |= (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6); // ALL /CE HIGH (DISABLE)
|
||||
PORTH |= (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6); // ALL /CE HIGH (DISABLE)
|
||||
|
||||
uint8_t ret = PINC;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void readSegment_COL(uint32_t startaddr, uint32_t endaddr)
|
||||
{
|
||||
void readSegment_COL(uint32_t startaddr, uint32_t endaddr) {
|
||||
for (uint32_t addr = startaddr; addr < endaddr; addr += 512) {
|
||||
for (int w = 0; w < 512; w++) {
|
||||
uint8_t temp = readData_COL(addr + w);
|
||||
@ -168,8 +163,7 @@ void readSegment_COL(uint32_t startaddr, uint32_t endaddr)
|
||||
}
|
||||
}
|
||||
|
||||
void readROM_COL()
|
||||
{
|
||||
void readROM_COL() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".col");
|
||||
|
||||
@ -197,17 +191,17 @@ void readROM_COL()
|
||||
// RESET ALL CS PINS HIGH (DISABLE)
|
||||
PORTH |= (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
readSegment_COL(0x8000, 0xA000); // 8K
|
||||
readSegment_COL(0x8000, 0xA000); // 8K
|
||||
if (colsize > 0) {
|
||||
readSegment_COL(0xA000, 0xB000); // +4K = 12K
|
||||
readSegment_COL(0xA000, 0xB000); // +4K = 12K
|
||||
if (colsize > 1) {
|
||||
readSegment_COL(0xB000, 0xC000); // +4K = 16K
|
||||
readSegment_COL(0xB000, 0xC000); // +4K = 16K
|
||||
if (colsize > 2) {
|
||||
readSegment_COL(0xC000, 0xD000); // +4K = 20K
|
||||
readSegment_COL(0xC000, 0xD000); // +4K = 20K
|
||||
if (colsize > 3) {
|
||||
readSegment_COL(0xD000, 0xE000); // +4K = 24K
|
||||
readSegment_COL(0xD000, 0xE000); // +4K = 24K
|
||||
if (colsize > 4) {
|
||||
readSegment_COL(0xE000, 0x10000); // +8K = 32K
|
||||
readSegment_COL(0xE000, 0x10000); // +8K = 32K
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -231,8 +225,7 @@ void readROM_COL()
|
||||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
void setROMSize_COL()
|
||||
{
|
||||
void setROMSize_COL() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
if (collo == colhi)
|
||||
@ -256,7 +249,7 @@ void setROMSize_COL()
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == collo)
|
||||
i = colhi;
|
||||
else
|
||||
@ -276,7 +269,7 @@ void setROMSize_COL()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == colhi)
|
||||
i = collo;
|
||||
else
|
||||
@ -296,12 +289,12 @@ void setROMSize_COL()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newcolsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(COL[newcolsize]);
|
||||
@ -340,8 +333,7 @@ setrom:
|
||||
colsize = newcolsize;
|
||||
}
|
||||
|
||||
void checkStatus_COL()
|
||||
{
|
||||
void checkStatus_COL() {
|
||||
EEPROM_readAnything(8, colsize);
|
||||
if (colsize > 5) {
|
||||
colsize = 0;
|
||||
@ -404,12 +396,10 @@ void setCart_COL() {
|
||||
while (1) {
|
||||
if (myFile.curPosition() == 0) {
|
||||
break;
|
||||
}
|
||||
else if (myFile.peek() == '\n') {
|
||||
} else if (myFile.peek() == '\n') {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
}
|
||||
}
|
||||
@ -451,9 +441,8 @@ void setCart_COL() {
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
}
|
||||
else {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
@ -498,12 +487,10 @@ void setCart_COL() {
|
||||
while (1) {
|
||||
if (myFile.curPosition() == 0) {
|
||||
break;
|
||||
}
|
||||
else if (myFile.peek() == '\n') {
|
||||
} else if (myFile.peek() == '\n') {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
}
|
||||
}
|
||||
@ -551,8 +538,7 @@ void setCart_COL() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Database file not found"), true);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,7 +28,7 @@ static const char flash8MenuItem4[] PROGMEM = "Write";
|
||||
static const char flash8MenuItem5[] PROGMEM = "ID";
|
||||
static const char flash8MenuItem6[] PROGMEM = "Print";
|
||||
static const char flash8MenuItem7[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsFLASH8[] PROGMEM = {flash8MenuItem1, flash8MenuItem2, flash8MenuItem3, flash8MenuItem4, flash8MenuItem5, flash8MenuItem6, flash8MenuItem7};
|
||||
static const char* const menuOptionsFLASH8[] PROGMEM = { flash8MenuItem1, flash8MenuItem2, flash8MenuItem3, flash8MenuItem4, flash8MenuItem5, flash8MenuItem6, flash8MenuItem7 };
|
||||
|
||||
#ifdef enable_FLASH16
|
||||
// Flash start menu
|
||||
@ -36,7 +36,7 @@ static const char flashMenuItem1[] PROGMEM = "8bit Flash adapter";
|
||||
static const char flashMenuItem2[] PROGMEM = "Eprom adapter";
|
||||
static const char flashMenuItem3[] PROGMEM = "MX26L6420 adapter";
|
||||
static const char flashMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsFlash[] PROGMEM = {flashMenuItem1, flashMenuItem2, flashMenuItem3, flashMenuItem4};
|
||||
static const char* const menuOptionsFlash[] PROGMEM = { flashMenuItem1, flashMenuItem2, flashMenuItem3, flashMenuItem4 };
|
||||
|
||||
// 16bit Flash menu items
|
||||
static const char flash16MenuItem1[] PROGMEM = "Blankcheck";
|
||||
@ -46,7 +46,7 @@ static const char flash16MenuItem4[] PROGMEM = "Write";
|
||||
static const char flash16MenuItem5[] PROGMEM = "ID";
|
||||
static const char flash16MenuItem6[] PROGMEM = "Print";
|
||||
static const char flash16MenuItem7[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsFLASH16[] PROGMEM = {flash16MenuItem1, flash16MenuItem2, flash16MenuItem3, flash16MenuItem4, flash16MenuItem5, flash16MenuItem6, flash16MenuItem7};
|
||||
static const char* const menuOptionsFLASH16[] PROGMEM = { flash16MenuItem1, flash16MenuItem2, flash16MenuItem3, flash16MenuItem4, flash16MenuItem5, flash16MenuItem6, flash16MenuItem7 };
|
||||
|
||||
// Eprom menu items
|
||||
static const char epromMenuItem1[] PROGMEM = "Blankcheck";
|
||||
@ -55,7 +55,7 @@ static const char epromMenuItem3[] PROGMEM = "Write";
|
||||
static const char epromMenuItem4[] PROGMEM = "Verify";
|
||||
static const char epromMenuItem5[] PROGMEM = "Print";
|
||||
static const char epromMenuItem6[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsEprom[] PROGMEM = {epromMenuItem1, epromMenuItem2, epromMenuItem3, epromMenuItem4, epromMenuItem5, epromMenuItem6};
|
||||
static const char* const menuOptionsEprom[] PROGMEM = { epromMenuItem1, epromMenuItem2, epromMenuItem3, epromMenuItem4, epromMenuItem5, epromMenuItem6 };
|
||||
|
||||
void flashMenu() {
|
||||
// create menu with title and 3 options to choose from
|
||||
@ -65,8 +65,7 @@ void flashMenu() {
|
||||
flashSlot = question_box(F("Select adapter PCB"), menuOptions, 4, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (flashSlot)
|
||||
{
|
||||
switch (flashSlot) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
@ -74,14 +73,14 @@ void flashMenu() {
|
||||
setup_Flash8();
|
||||
id_Flash8();
|
||||
wait();
|
||||
mode = mode_FLASH8;
|
||||
mode = mode_FLASH8;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_Eprom();
|
||||
mode = mode_EPROM;
|
||||
mode = mode_EPROM;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@ -90,7 +89,7 @@ void flashMenu() {
|
||||
setup_Flash16();
|
||||
id_Flash16();
|
||||
wait();
|
||||
mode = mode_FLASH16;
|
||||
mode = mode_FLASH16;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -108,8 +107,7 @@ void flashromMenu8() {
|
||||
mainMenu = question_box(F("Flashrom Writer 8"), menuOptions, 7, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
println_Msg(F("Blankcheck"));
|
||||
@ -159,16 +157,12 @@ void flashromMenu8() {
|
||||
writeFlash29F1601();
|
||||
else if ((strcmp(flashid, "C2F1") == 0) || (strcmp(flashid, "C2F9") == 0))
|
||||
writeFlash29F1610();
|
||||
else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0) ||
|
||||
(strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0) ||
|
||||
(strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0))
|
||||
else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0) || (strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0) || (strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0))
|
||||
writeFlash29LV640();
|
||||
else if (strcmp(flashid, "017E") == 0) {
|
||||
// sector size, write buffer size
|
||||
writeFlash29GL(sectorSize, bufferSize);
|
||||
}
|
||||
else if ((strcmp(flashid, "0458") == 0) || (strcmp(flashid, "0158") == 0) ||
|
||||
(strcmp(flashid, "01AB") == 0))
|
||||
} else if ((strcmp(flashid, "0458") == 0) || (strcmp(flashid, "0158") == 0) || (strcmp(flashid, "01AB") == 0))
|
||||
writeFlash29F800();
|
||||
|
||||
break;
|
||||
@ -242,8 +236,7 @@ void flashromMenu16() {
|
||||
mainMenu = question_box(F("Flashrom Writer 16"), menuOptions, 7, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
println_Msg(F("Blankcheck"));
|
||||
@ -279,11 +272,9 @@ void flashromMenu16() {
|
||||
time = millis();
|
||||
if (strcmp(flashid, "C2F3") == 0) {
|
||||
writeFlash16_29F1601();
|
||||
}
|
||||
else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0) || (strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0) || (strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0) || (strcmp(flashid, "C2FC") == 0)) {
|
||||
} else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0) || (strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0) || (strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0) || (strcmp(flashid, "C2FC") == 0)) {
|
||||
writeFlash16_29LV640();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writeFlash16();
|
||||
}
|
||||
delay(100);
|
||||
@ -338,8 +329,7 @@ void epromMenu() {
|
||||
mainMenu = question_box(F("Eprom Writer"), menuOptions, 6, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
println_Msg(F("Blankcheck"));
|
||||
@ -419,87 +409,71 @@ idtheflash:
|
||||
println_Msg(F("MX29F1610 detected"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "C2F3") == 0) {
|
||||
} else if (strcmp(flashid, "C2F3") == 0) {
|
||||
println_Msg(F("MX29F1601 detected"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "C2F9") == 0) {
|
||||
} else if (strcmp(flashid, "C2F9") == 0) {
|
||||
println_Msg(F("MX29L3211 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 4194304;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0)) {
|
||||
} else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0)) {
|
||||
println_Msg(F("MX29LV160 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if ((strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0)) {
|
||||
} else if ((strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0)) {
|
||||
println_Msg(F("MX29LV320 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 4194304;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if ((strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0)) {
|
||||
} else if ((strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0)) {
|
||||
println_Msg(F("MX29LV640 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 8388608;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "0141") == 0) {
|
||||
} else if (strcmp(flashid, "0141") == 0) {
|
||||
println_Msg(F("AM29F032B detected"));
|
||||
flashSize = 4194304;
|
||||
flashromType = 1;
|
||||
}
|
||||
else if (strcmp(flashid, "01AD") == 0) {
|
||||
} else if (strcmp(flashid, "01AD") == 0) {
|
||||
println_Msg(F("AM29F016B detected"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 1;
|
||||
}
|
||||
else if (strcmp(flashid, "20AD") == 0) {
|
||||
} else if (strcmp(flashid, "20AD") == 0) {
|
||||
println_Msg(F("AM29F016D detected"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 1;
|
||||
}
|
||||
else if (strcmp(flashid, "04AD") == 0) {
|
||||
} else if (strcmp(flashid, "04AD") == 0) {
|
||||
println_Msg(F("AM29F016D detected"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 1;
|
||||
}
|
||||
else if (strcmp(flashid, "04D4") == 0) {
|
||||
} else if (strcmp(flashid, "04D4") == 0) {
|
||||
println_Msg(F("MBM29F033C detected"));
|
||||
flashSize = 4194304;
|
||||
flashromType = 1;
|
||||
}
|
||||
else if (strcmp(flashid, "04D5") == 0) {
|
||||
} else if (strcmp(flashid, "04D5") == 0) {
|
||||
println_Msg(F("MBM29F080C detected"));
|
||||
flashSize = 1048576;
|
||||
flashromType = 1;
|
||||
}
|
||||
else if (strcmp(flashid, "0458") == 0) {
|
||||
} else if (strcmp(flashid, "0458") == 0) {
|
||||
println_Msg(F("MBM29F800BA detected"));
|
||||
flashSize = 1048576;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "01AB") == 0) {
|
||||
} else if (strcmp(flashid, "01AB") == 0) {
|
||||
println_Msg(F("AM29F400AB detected"));
|
||||
flashSize = 131072 * 4;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "0158") == 0) {
|
||||
} else if (strcmp(flashid, "0158") == 0) {
|
||||
println_Msg(F("AM29F800BB detected"));
|
||||
flashSize = 1048576;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "01A3") == 0) {
|
||||
} else if (strcmp(flashid, "01A3") == 0) {
|
||||
println_Msg(F("AM29LV033C detected"));
|
||||
flashSize = 131072 * 32;
|
||||
flashromType = 1;
|
||||
}
|
||||
else if (strcmp(flashid, "017E") == 0) {
|
||||
} else if (strcmp(flashid, "017E") == 0) {
|
||||
// S29GL032M
|
||||
if (readByte_Flash(28) == 0x1A) {
|
||||
println_Msg(F("S29GL032M detected"));
|
||||
@ -523,8 +497,7 @@ idtheflash:
|
||||
}
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "B088") == 0) {
|
||||
} else if (strcmp(flashid, "B088") == 0) {
|
||||
// LH28F016SUT
|
||||
println_Msg(F("LH28F016SUT detected"));
|
||||
println_Msg(F("ATTENTION 3/5 setting"));
|
||||
@ -532,10 +505,7 @@ idtheflash:
|
||||
sectorSize = 65536;
|
||||
bufferSize = 256;
|
||||
flashromType = 3;
|
||||
}
|
||||
else if ((strcmp(flashid, "8916") == 0) ||
|
||||
(strcmp(flashid, "8917") == 0) ||
|
||||
(strcmp(flashid, "8918") == 0)) {
|
||||
} else if ((strcmp(flashid, "8916") == 0) || (strcmp(flashid, "8917") == 0) || (strcmp(flashid, "8918") == 0)) {
|
||||
// E28FXXXJ3A
|
||||
print_Msg(F("E28F"));
|
||||
|
||||
@ -558,15 +528,13 @@ idtheflash:
|
||||
sectorSize = 131072;
|
||||
bufferSize = 32;
|
||||
flashromType = 3;
|
||||
}
|
||||
else if (secondID == 1) {
|
||||
} else if (secondID == 1) {
|
||||
// Read ID a second time using a different command (type 1 flashrom)
|
||||
resetFlash8();
|
||||
idFlash29F032();
|
||||
secondID = 2;
|
||||
goto idtheflash;
|
||||
}
|
||||
else if (secondID == 2) {
|
||||
} else if (secondID == 2) {
|
||||
// Backup first ID read-out
|
||||
strncpy(vendorID, flashid, 5);
|
||||
|
||||
@ -575,8 +543,7 @@ idtheflash:
|
||||
idFlash29F1610();
|
||||
secondID = 0;
|
||||
goto idtheflash;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// ID not found
|
||||
display_Clear();
|
||||
println_Msg(F("Flashrom Writer 8bit"));
|
||||
@ -624,43 +591,36 @@ void id_Flash16() {
|
||||
println_Msg("");
|
||||
flashSize = 2097152;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "C2F3") == 0) {
|
||||
} else if (strcmp(flashid, "C2F3") == 0) {
|
||||
println_Msg(F("MX29F1601 detected"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "C2F9") == 0) {
|
||||
} else if (strcmp(flashid, "C2F9") == 0) {
|
||||
println_Msg(F("MX29L3211 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 4194304;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0)) {
|
||||
} else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0)) {
|
||||
println_Msg(F("MX29LV160 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 2097152;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if ((strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0)) {
|
||||
} else if ((strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0)) {
|
||||
println_Msg(F("MX29LV320 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 4194304;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if ((strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0)) {
|
||||
} else if ((strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0)) {
|
||||
println_Msg(F("MX29LV640 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 8388608;
|
||||
flashromType = 2;
|
||||
}
|
||||
else if (strcmp(flashid, "C2FC") == 0) {
|
||||
} else if (strcmp(flashid, "C2FC") == 0) {
|
||||
println_Msg(F("MX26L6420 detected"));
|
||||
println_Msg(F("ATTENTION 3.3V"));
|
||||
flashSize = 8388608;
|
||||
flashromType = 2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Unknown flashrom"), true);
|
||||
println_Msg("");
|
||||
}
|
||||
@ -683,7 +643,7 @@ void setup_Flash8() {
|
||||
DDRL = 0xFF;
|
||||
|
||||
// Set Control Pins to Output RST(PH0) OE(PH1) OE_SNS(PH3) WE(PH4) WE_SNS(PH5) CE(PH6)
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
// Setting RST(PH0) OE(PH1) OE_SNS(PH3) WE(PH4) WE_SNS(PH5) HIGH
|
||||
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5);
|
||||
// Setting CE(PH6) LOW
|
||||
@ -819,10 +779,9 @@ void writeByte_Flash(unsigned long myAddress, byte myData) {
|
||||
if (!(((myAddress >> 16) & 0xFF) & 0x40)) {
|
||||
// if PL6 is 0 set PL7 to 1
|
||||
PORTL |= (1 << 7);
|
||||
}
|
||||
else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
||||
} else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
||||
// if PL6 is 1 set PL7 to 0
|
||||
PORTL &= ~ (1 << 7);
|
||||
PORTL &= ~(1 << 7);
|
||||
}
|
||||
// Switch SNES BA6(PL6) to HIGH to disable SRAM
|
||||
PORTL |= (1 << 6);
|
||||
@ -833,19 +792,34 @@ void writeByte_Flash(unsigned long myAddress, byte 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""nop\n\t""nop\n\t");
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WE(PH4) WE_SNS(PH5) to LOW
|
||||
PORTH &= ~((1 << 4) | (1 << 5));
|
||||
|
||||
// Leave WE low for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WE(PH4) WE_SNS(PH5) to HIGH
|
||||
PORTH |= (1 << 4) | (1 << 5);
|
||||
|
||||
// Leave WE high for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
}
|
||||
|
||||
byte readByte_Flash(unsigned long myAddress) {
|
||||
@ -889,29 +863,43 @@ byte readByte_Flash(unsigned long myAddress) {
|
||||
if (!(((myAddress >> 16) & 0xFF) & 0x40)) {
|
||||
// if PL6 is 0 set PL7 to 1
|
||||
PORTL |= (1 << 7);
|
||||
}
|
||||
else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
||||
} else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
||||
// if PL6 is 1 set PL7 to 0
|
||||
PORTL &= ~ (1 << 7);
|
||||
PORTL &= ~(1 << 7);
|
||||
}
|
||||
// Switch SNES BA6(PL6) to HIGH to disable SRAM
|
||||
PORTL |= (1 << 6);
|
||||
}
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Setting OE(PH1) OE_SNS(PH3) LOW
|
||||
PORTH &= ~((1 << 1) | (1 << 3));
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Read
|
||||
byte tempByte = PINC;
|
||||
|
||||
// Setting OE(PH1) OE_SNS(PH3) HIGH
|
||||
PORTH |= (1 << 1) | (1 << 3);
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
return tempByte;
|
||||
}
|
||||
@ -932,13 +920,23 @@ void writeWord_Flash(unsigned long myAddress, word myData) {
|
||||
PORTH &= ~(1 << 4);
|
||||
|
||||
// Leave WE low for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WE(PH4) to HIGH
|
||||
PORTH |= (1 << 4);
|
||||
|
||||
// Leave WE high for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
}
|
||||
|
||||
word readWord_Flash(unsigned long myAddress) {
|
||||
@ -952,16 +950,26 @@ word readWord_Flash(unsigned long myAddress) {
|
||||
// Setting OE(PH1) LOW
|
||||
PORTH &= ~(1 << 1);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Read
|
||||
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
|
||||
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF);
|
||||
|
||||
__asm__("nop\n\t");
|
||||
|
||||
// Setting OE(PH1) HIGH
|
||||
PORTH |= (1 << 1);
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
return tempWord;
|
||||
}
|
||||
@ -1104,8 +1112,7 @@ void writeFlash29F032() {
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1119,7 +1126,7 @@ int busyCheck29F032(uint32_t addr, byte c) {
|
||||
// Setting OE(PH1) OE_SNS(PH3) CE(PH6)LOW
|
||||
PORTH &= ~((1 << 1) | (1 << 3) | (1 << 6));
|
||||
// Setting WE(PH4) WE_SNES(PH5) HIGH
|
||||
PORTH |= (1 << 4) | (1 << 5);
|
||||
PORTH |= (1 << 4) | (1 << 5);
|
||||
|
||||
//When the Embedded Program algorithm is complete, the device outputs the datum programmed to D7
|
||||
for (;;) {
|
||||
@ -1217,8 +1224,7 @@ void writeFlash29F1610() {
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1277,8 +1283,7 @@ void writeFlash29F1601() {
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1406,8 +1411,7 @@ void writeFlash29LV640() {
|
||||
dataIn8();
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1474,8 +1478,7 @@ void writeFlash29GL(unsigned long sectorSize, byte bufferSize) {
|
||||
dataIn8();
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1524,8 +1527,7 @@ void writeFlash29F800() {
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1562,14 +1564,14 @@ uint8_t statusFlash28FXXX() {
|
||||
|
||||
void eraseFlash28FXXX() {
|
||||
// only can erase block by block
|
||||
for (uint32_t ba = 0; ba < flashSize; ba += sectorSize)
|
||||
{
|
||||
for (uint32_t ba = 0; ba < flashSize; ba += sectorSize) {
|
||||
dataOut();
|
||||
writeByte_Flash(ba, 0x20);
|
||||
writeByte_Flash(ba, 0xd0);
|
||||
|
||||
dataIn8();
|
||||
while ((readByte_Flash(ba) & 0x80) == 0x00);
|
||||
while ((readByte_Flash(ba) & 0x80) == 0x00)
|
||||
;
|
||||
|
||||
// blink LED
|
||||
blinkLED();
|
||||
@ -1586,15 +1588,12 @@ void writeFlash28FXXX() {
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
if ((strcmp(flashid, "B088") == 0))
|
||||
writeFlashLH28F0XX();
|
||||
else if ((strcmp(flashid, "8916") == 0) ||
|
||||
(strcmp(flashid, "8917") == 0) ||
|
||||
(strcmp(flashid, "8918") == 0)) {
|
||||
else if ((strcmp(flashid, "8916") == 0) || (strcmp(flashid, "8917") == 0) || (strcmp(flashid, "8918") == 0)) {
|
||||
writeFlashE28FXXXJ3A();
|
||||
}
|
||||
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1627,7 +1626,8 @@ void writeFlashE28FXXXJ3A() {
|
||||
|
||||
// waiting for buffer available
|
||||
dataIn8();
|
||||
while ((readByte_Flash(block_addr) & 0x80) == 0x00);
|
||||
while ((readByte_Flash(block_addr) & 0x80) == 0x00)
|
||||
;
|
||||
dataOut();
|
||||
|
||||
// set write byte count
|
||||
@ -1642,7 +1642,8 @@ void writeFlashE28FXXXJ3A() {
|
||||
|
||||
// waiting for finishing
|
||||
dataIn8();
|
||||
while ((readByte_Flash(block_addr) & 0x80) == 0x00);
|
||||
while ((readByte_Flash(block_addr) & 0x80) == 0x00)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1667,20 +1668,21 @@ void writeFlashLH28F0XX() {
|
||||
// sequence load to page
|
||||
dataOut();
|
||||
writeByte_Flash(0x0, 0xe0);
|
||||
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
||||
writeByte_Flash(0x0, 0x00); // BCH should be 0x00
|
||||
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
||||
writeByte_Flash(0x0, 0x00); // BCH should be 0x00
|
||||
|
||||
for (uint32_t d = 0; d < bufferSize; d++)
|
||||
writeByte_Flash(d, sdBuffer[c + d]);
|
||||
|
||||
// start flashing page
|
||||
writeByte_Flash(0x0, 0x0c);
|
||||
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
||||
writeByte_Flash(currByte + c, 0x00); // BCH should be 0x00
|
||||
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
||||
writeByte_Flash(currByte + c, 0x00); // BCH should be 0x00
|
||||
|
||||
// waiting for finishing
|
||||
dataIn8();
|
||||
while ((readByte_Flash(currByte + c) & 0x80) == 0x00);
|
||||
while ((readByte_Flash(currByte + c) & 0x80) == 0x00)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1705,8 +1707,7 @@ void blankcheck_Flash() {
|
||||
if (blank) {
|
||||
println_Msg(F("Flashrom is empty"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Not blank"), false);
|
||||
}
|
||||
}
|
||||
@ -1735,8 +1736,7 @@ void verifyFlash() {
|
||||
if (blank == 0) {
|
||||
println_Msg(F("Flashrom verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(blank);
|
||||
println_Msg(F(" bytes "));
|
||||
@ -1744,8 +1744,7 @@ void verifyFlash() {
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1793,7 +1792,7 @@ void printFlash(int numBytes) {
|
||||
|
||||
for (int currByte = 0; currByte < numBytes; currByte += 10) {
|
||||
for (int c = 0; c < 10; c++) {
|
||||
itoa (readByte_Flash(currByte + c), myBuffer, 16);
|
||||
itoa(readByte_Flash(currByte + c), myBuffer, 16);
|
||||
for (int i = 0; i < 2 - strlen(myBuffer); i++) {
|
||||
print_Msg(F("0"));
|
||||
}
|
||||
@ -1869,7 +1868,7 @@ void writeFlash16() {
|
||||
|
||||
// Write one full page at a time
|
||||
for (byte c = 0; c < 64; c++) {
|
||||
word currWord = ( ( sdBuffer[d + 1] & 0xFF ) << 8 ) | ( sdBuffer[d] & 0xFF );
|
||||
word currWord = ((sdBuffer[d + 1] & 0xFF) << 8) | (sdBuffer[d] & 0xFF);
|
||||
writeWord_Flash(currByte + c, currWord);
|
||||
d += 2;
|
||||
}
|
||||
@ -1884,8 +1883,7 @@ void writeFlash16() {
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD."));
|
||||
display_Update();
|
||||
}
|
||||
@ -1928,7 +1926,7 @@ void writeFlash16_29F1601() {
|
||||
|
||||
// Write one full page at a time
|
||||
for (byte c = 0; c < 64; c++) {
|
||||
word currWord = ( ( sdBuffer[d + 1] & 0xFF ) << 8 ) | ( sdBuffer[d] & 0xFF );
|
||||
word currWord = ((sdBuffer[d + 1] & 0xFF) << 8) | (sdBuffer[d] & 0xFF);
|
||||
writeWord_Flash(currByte + c, currWord);
|
||||
|
||||
if (c == 63) {
|
||||
@ -1948,8 +1946,7 @@ void writeFlash16_29F1601() {
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD."));
|
||||
display_Update();
|
||||
}
|
||||
@ -2021,8 +2018,7 @@ void blankcheck16() {
|
||||
if (blank) {
|
||||
println_Msg(F("Flashrom is empty."));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Not blank"), false);
|
||||
}
|
||||
}
|
||||
@ -2057,8 +2053,7 @@ void verifyFlash16() {
|
||||
if (blank == 0) {
|
||||
println_Msg(F("Flashrom verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Verification ERROR!"));
|
||||
print_Msg(blank);
|
||||
print_Error(F("B did not verify."), false);
|
||||
@ -2066,8 +2061,7 @@ void verifyFlash16() {
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD."));
|
||||
display_Update();
|
||||
}
|
||||
@ -2097,7 +2091,8 @@ void readFlash16() {
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
println_Msg(F("Can't create file on SD."));
|
||||
display_Update();
|
||||
while (1);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
word d = 0;
|
||||
for (unsigned long currByte = 0; currByte < flashSize / 2; currByte += 256) {
|
||||
@ -2105,7 +2100,7 @@ void readFlash16() {
|
||||
word currWord = readWord_Flash(currByte + c);
|
||||
// Split word into two bytes
|
||||
// Right
|
||||
sdBuffer[d + 1] = (( currWord >> 8 ) & 0xFF);
|
||||
sdBuffer[d + 1] = ((currWord >> 8) & 0xFF);
|
||||
// Left
|
||||
sdBuffer[d] = (currWord & 0xFF);
|
||||
d += 2;
|
||||
@ -2136,17 +2131,17 @@ void printFlash16(int numBytes) {
|
||||
|
||||
// Split word into two bytes
|
||||
byte left_byte = currWord & 0xFF;
|
||||
byte right_byte = ( currWord >> 8 ) & 0xFF;
|
||||
byte right_byte = (currWord >> 8) & 0xFF;
|
||||
|
||||
|
||||
sprintf (buf, "%x", left_byte);
|
||||
sprintf(buf, "%x", left_byte);
|
||||
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||
print_Msg(F("0"));
|
||||
}
|
||||
// Now print the significant bits
|
||||
print_Msg(buf);
|
||||
|
||||
sprintf (buf, "%x", right_byte);
|
||||
sprintf(buf, "%x", right_byte);
|
||||
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||
print_Msg(F("0"));
|
||||
}
|
||||
@ -2225,7 +2220,7 @@ void writeFlash16_29LV640() {
|
||||
writeWord_Flash(0x5555, 0xa0);
|
||||
|
||||
// Write current word
|
||||
word myWord = ( ( sdBuffer[d + 1] & 0xFF ) << 8 ) | ( sdBuffer[d] & 0xFF );
|
||||
word myWord = ((sdBuffer[d + 1] & 0xFF) << 8) | (sdBuffer[d] & 0xFF);
|
||||
writeWord_Flash(currWord + c, myWord);
|
||||
d += 2;
|
||||
// Check if write is complete
|
||||
@ -2238,8 +2233,7 @@ void writeFlash16_29LV640() {
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD."));
|
||||
display_Update();
|
||||
}
|
||||
@ -2291,7 +2285,10 @@ word writeWord_Eprom(unsigned long myAddress, word myData) {
|
||||
DDRA = 0x00;
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||
__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");
|
||||
|
||||
// Setting CE(PH6) LOW
|
||||
PORTH &= ~(1 << 6);
|
||||
@ -2300,15 +2297,20 @@ word writeWord_Eprom(unsigned long myAddress, word myData) {
|
||||
delayMicroseconds(3);
|
||||
|
||||
// Read
|
||||
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
|
||||
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF);
|
||||
|
||||
__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");
|
||||
|
||||
// Setting CE(PH6) HIGH
|
||||
PORTH |= (1 << 6);
|
||||
|
||||
// Delay 130ns for Chip Enable High to Output Hi-Z
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t");
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
return tempWord;
|
||||
}
|
||||
@ -2329,10 +2331,15 @@ word readWord_Eprom(unsigned long myAddress) {
|
||||
PORTH &= ~(1 << 6);
|
||||
|
||||
// Delay for 100ns for Address Valid/Chip Enable Low to Output Valid
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Read
|
||||
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
|
||||
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF);
|
||||
|
||||
// Setting CE(PH6) HIGH
|
||||
PORTH |= (1 << 6);
|
||||
@ -2354,8 +2361,7 @@ void blankcheck_Eprom() {
|
||||
if (blank) {
|
||||
println_Msg(F("Flashrom is empty."));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Not blank"), false);
|
||||
}
|
||||
}
|
||||
@ -2384,7 +2390,8 @@ void read_Eprom() {
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
println_Msg(F("Can't create file on SD."));
|
||||
display_Update();
|
||||
while (1);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
word d = 0;
|
||||
for (unsigned long currWord = 0; currWord < flashSize / 2; currWord += 256) {
|
||||
@ -2392,7 +2399,7 @@ void read_Eprom() {
|
||||
word myWord = readWord_Eprom(currWord + c);
|
||||
// Split word into two bytes
|
||||
// Right
|
||||
sdBuffer[d + 1] = ((myWord >> 8 ) & 0xFF);
|
||||
sdBuffer[d + 1] = ((myWord >> 8) & 0xFF);
|
||||
// Left
|
||||
sdBuffer[d] = (myWord & 0xFF);
|
||||
d += 2;
|
||||
@ -2437,7 +2444,7 @@ void write_Eprom() {
|
||||
// Work through SD buffer
|
||||
for (int c = 0; c < 256; c++) {
|
||||
word checkWord;
|
||||
word myWord = ( ( sdBuffer[d + 1] & 0xFF ) << 8 ) | ( sdBuffer[d] & 0xFF );
|
||||
word myWord = ((sdBuffer[d + 1] & 0xFF) << 8) | (sdBuffer[d] & 0xFF);
|
||||
|
||||
// Error counter
|
||||
byte n = 0;
|
||||
@ -2457,15 +2464,13 @@ void write_Eprom() {
|
||||
print_Error(F("Press button to reset"), true);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
while (checkWord != myWord);
|
||||
} while (checkWord != myWord);
|
||||
d += 2;
|
||||
}
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD."));
|
||||
display_Update();
|
||||
}
|
||||
@ -2501,8 +2506,7 @@ void verify_Eprom() {
|
||||
if (blank == 0) {
|
||||
println_Msg(F("Eprom verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Verification ERROR!"));
|
||||
print_Msg(blank);
|
||||
print_Error(F(" words did not verify."), false);
|
||||
@ -2510,8 +2514,7 @@ void verify_Eprom() {
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file on SD."));
|
||||
display_Update();
|
||||
}
|
||||
@ -2527,17 +2530,17 @@ void print_Eprom(int numBytes) {
|
||||
|
||||
// Split word into two bytes
|
||||
byte left_byte = currWord & 0xFF;
|
||||
byte right_byte = ( currWord >> 8 ) & 0xFF;
|
||||
byte right_byte = (currWord >> 8) & 0xFF;
|
||||
|
||||
|
||||
sprintf (buf, "%x", left_byte);
|
||||
sprintf(buf, "%x", left_byte);
|
||||
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||
print_Msg(F("0"));
|
||||
}
|
||||
// Now print the significant bits
|
||||
print_Msg(buf);
|
||||
|
||||
sprintf (buf, "%x", right_byte);
|
||||
sprintf(buf, "%x", right_byte);
|
||||
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||
print_Msg(F("0"));
|
||||
}
|
||||
|
@ -20,14 +20,14 @@ static const char gbxMenuItem2[] PROGMEM = "GB Advance (3V)";
|
||||
static const char gbxMenuItem3[] PROGMEM = "Flash GBC Cart";
|
||||
static const char gbxMenuItem4[] PROGMEM = "NPower GB Memory";
|
||||
static const char gbxMenuItem5[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsGBx[] PROGMEM = {gbxMenuItem1, gbxMenuItem2, gbxMenuItem3, gbxMenuItem4, gbxMenuItem5};
|
||||
static const char* const menuOptionsGBx[] PROGMEM = { gbxMenuItem1, gbxMenuItem2, gbxMenuItem3, gbxMenuItem4, gbxMenuItem5 };
|
||||
|
||||
// GB menu items
|
||||
static const char GBMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char GBMenuItem2[] PROGMEM = "Read Save";
|
||||
static const char GBMenuItem3[] PROGMEM = "Write Save";
|
||||
static const char GBMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsGB[] PROGMEM = {GBMenuItem1, GBMenuItem2, GBMenuItem3, GBMenuItem4};
|
||||
static const char* const menuOptionsGB[] PROGMEM = { GBMenuItem1, GBMenuItem2, GBMenuItem3, GBMenuItem4 };
|
||||
|
||||
// GB Flash items
|
||||
static const char GBFlashItem1[] PROGMEM = "29F Cart (MBC3)";
|
||||
@ -37,7 +37,7 @@ static const char GBFlashItem4[] PROGMEM = "CFI Cart";
|
||||
static const char GBFlashItem5[] PROGMEM = "CFI Cart and Save";
|
||||
static const char GBFlashItem6[] PROGMEM = "GB Smart";
|
||||
static const char GBFlashItem7[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsGBFlash[] PROGMEM = {GBFlashItem1, GBFlashItem2, GBFlashItem3, GBFlashItem4, GBFlashItem5, GBFlashItem6, GBFlashItem7};
|
||||
static const char* const menuOptionsGBFlash[] PROGMEM = { GBFlashItem1, GBFlashItem2, GBFlashItem3, GBFlashItem4, GBFlashItem5, GBFlashItem6, GBFlashItem7 };
|
||||
|
||||
// Start menu for both GB and GBA
|
||||
void gbxMenu() {
|
||||
@ -48,20 +48,19 @@ void gbxMenu() {
|
||||
gbType = question_box(F("Select Game Boy"), menuOptions, 5, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (gbType)
|
||||
{
|
||||
switch (gbType) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
mode = mode_GB;
|
||||
mode = mode_GB;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GBA();
|
||||
mode = mode_GBA;
|
||||
mode = mode_GBA;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@ -72,14 +71,13 @@ void gbxMenu() {
|
||||
gbFlash = question_box(F("Select type"), menuOptions, 7, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (gbFlash)
|
||||
{
|
||||
switch (gbFlash) {
|
||||
case 0:
|
||||
//Flash MBC3
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
mode = mode_GB;
|
||||
mode = mode_GB;
|
||||
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
@ -97,7 +95,7 @@ void gbxMenu() {
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
mode = mode_GB;
|
||||
mode = mode_GB;
|
||||
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
@ -115,7 +113,7 @@ void gbxMenu() {
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
mode = mode_GB;
|
||||
mode = mode_GB;
|
||||
|
||||
//Flash first bank with erase
|
||||
// Change working dir to root
|
||||
@ -156,7 +154,7 @@ void gbxMenu() {
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
mode = mode_GB;
|
||||
mode = mode_GB;
|
||||
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
@ -183,7 +181,7 @@ void gbxMenu() {
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GB();
|
||||
mode = mode_GB;
|
||||
mode = mode_GB;
|
||||
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
@ -231,8 +229,7 @@ void gbxMenu() {
|
||||
if (wrErrors == 0) {
|
||||
println_Msg(F("Verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(wrErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
@ -245,8 +242,7 @@ void gbxMenu() {
|
||||
if (!saveFound) {
|
||||
println_Msg(F("Error: No save found."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Cart has no Sram"), false);
|
||||
}
|
||||
// Reset
|
||||
@ -273,7 +269,7 @@ void gbxMenu() {
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_GBM();
|
||||
mode = mode_GBM;
|
||||
mode = mode_GBM;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
@ -290,8 +286,7 @@ void gbMenu() {
|
||||
mainMenu = question_box(F("GB Cart Reader"), menuOptions, 4, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
// Change working dir to root
|
||||
@ -313,8 +308,7 @@ void gbMenu() {
|
||||
readSRAMFLASH_MBC6_GB();
|
||||
else
|
||||
readSRAM_GB();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("No save or unsupported type"), false);
|
||||
}
|
||||
println_Msg(F(""));
|
||||
@ -331,24 +325,21 @@ void gbMenu() {
|
||||
|
||||
if (romType == 32) {
|
||||
writeSRAMFLASH_MBC6_GB();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writeSRAM_GB();
|
||||
unsigned long wrErrors;
|
||||
wrErrors = verifySRAM_GB();
|
||||
if (wrErrors == 0) {
|
||||
println_Msg(F("Verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(wrErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
print_Error(F("did not verify."), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("No save or unsupported type"), false);
|
||||
}
|
||||
println_Msg(F(""));
|
||||
@ -498,19 +489,15 @@ void showCartInfo_GB() {
|
||||
case 0:
|
||||
if (romType == 6) {
|
||||
print_Msg(F("512 Byte"));
|
||||
}
|
||||
else if (romType == 0x22) {
|
||||
} else if (romType == 0x22) {
|
||||
if (strncmp(cartID, "KCEJ", 4) == 0) {
|
||||
print_Msg(F("512 Byte"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("256 Byte"));
|
||||
}
|
||||
}
|
||||
else if (romType == 0xFD) {
|
||||
} else if (romType == 0xFD) {
|
||||
print_Msg(F("32 Byte"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("None"));
|
||||
}
|
||||
break;
|
||||
@ -550,8 +537,7 @@ void showCartInfo_GB() {
|
||||
println_Msg(F("Press Button..."));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("GAMEPAK ERROR"), true);
|
||||
}
|
||||
}
|
||||
@ -568,12 +554,18 @@ byte readByte_GB(word myAddress) {
|
||||
// Enable pullups
|
||||
PORTC = 0xFF;
|
||||
|
||||
__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 RD(PH6) to LOW
|
||||
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
|
||||
byte tempByte = PINC;
|
||||
@ -581,7 +573,10 @@ byte readByte_GB(word myAddress) {
|
||||
// Switch and RD(PH6) to HIGH
|
||||
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");
|
||||
|
||||
return tempByte;
|
||||
}
|
||||
@ -596,18 +591,27 @@ void writeByte_GB(int myAddress, byte myData) {
|
||||
DDRC = 0xFF;
|
||||
|
||||
// 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");
|
||||
|
||||
// Pull WR(PH5) low
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
// 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");
|
||||
|
||||
// Pull WR(PH5) HIGH
|
||||
PORTH |= (1 << 5);
|
||||
// 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");
|
||||
|
||||
// Switch data pins to input
|
||||
DDRC = 0x00;
|
||||
@ -624,29 +628,37 @@ byte readByteSRAM_GB(word myAddress) {
|
||||
// Enable pullups
|
||||
PORTC = 0xFF;
|
||||
|
||||
__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");
|
||||
|
||||
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) LOW
|
||||
PORTH &= ~((1 << 3) | (1 << 1));
|
||||
// Pull RD(PH6) LOW
|
||||
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
|
||||
byte tempByte = PINC;
|
||||
|
||||
// Pull RD(PH6) HIGH
|
||||
PORTH |= (1 << 6);
|
||||
PORTH |= (1 << 6);
|
||||
if (romType == 252) {
|
||||
// Pull CS(PH3) HIGH
|
||||
PORTH |= (1 << 3);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) HIGH
|
||||
PORTH |= (1 << 3) | (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");
|
||||
|
||||
return tempByte;
|
||||
}
|
||||
@ -661,7 +673,10 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
||||
// Switch data pins to output
|
||||
DDRC = 0xFF;
|
||||
|
||||
__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");
|
||||
|
||||
if (romType == 252 || romType == 253) {
|
||||
// Pull CS(PH3) LOW
|
||||
@ -670,8 +685,7 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
||||
PORTH |= (1 << 1);
|
||||
// Pull WR(PH5) low
|
||||
PORTH &= ~(1 << 5);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) LOW
|
||||
PORTH &= ~((1 << 3) | (1 << 1));
|
||||
// Pull WR(PH5) low
|
||||
@ -679,7 +693,10 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
if (romType == 252 || romType == 253) {
|
||||
// Pull WR(PH5) HIGH
|
||||
@ -688,8 +705,7 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
||||
PORTH |= (1 << 3);
|
||||
// Pull CLK(PH1) LOW (for GB CAM)
|
||||
PORTH &= ~(1 << 1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Pull WR(PH5) HIGH
|
||||
PORTH |= (1 << 5);
|
||||
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) HIGH
|
||||
@ -697,7 +713,10 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
// Switch data pins to input
|
||||
DDRC = 0x00;
|
||||
@ -829,8 +848,7 @@ void getCartInfo_GB() {
|
||||
}
|
||||
if (sramSize == 1) {
|
||||
lastByte = 0xA7FF;
|
||||
}
|
||||
else if (sramSize > 1) {
|
||||
} else if (sramSize > 1) {
|
||||
lastByte = 0xBFFF;
|
||||
}
|
||||
|
||||
@ -890,21 +908,13 @@ void getCartInfo_GB() {
|
||||
|
||||
// MMM01 (Mani 4 in 1)
|
||||
if (
|
||||
(strncmp(romName, "BOUKENJIMA2 SET", 15) == 0) && (sdBuffer[0x14D] == 0) ||
|
||||
(strncmp(romName, "BUBBLEBOBBLE SET", 16) == 0) && (sdBuffer[0x14D] == 0xC6) ||
|
||||
(strncmp(romName, "GANBARUGA SET", 13) == 0) && (sdBuffer[0x14D] == 0x90) ||
|
||||
(strncmp(romName, "RTYPE 2 SET", 11) == 0) && (sdBuffer[0x14D] == 0x32)) {
|
||||
(strncmp(romName, "BOUKENJIMA2 SET", 15) == 0) && (sdBuffer[0x14D] == 0) || (strncmp(romName, "BUBBLEBOBBLE SET", 16) == 0) && (sdBuffer[0x14D] == 0xC6) || (strncmp(romName, "GANBARUGA SET", 13) == 0) && (sdBuffer[0x14D] == 0x90) || (strncmp(romName, "RTYPE 2 SET", 11) == 0) && (sdBuffer[0x14D] == 0x32)) {
|
||||
romType = 0x0B;
|
||||
}
|
||||
|
||||
// MBC1M
|
||||
if (
|
||||
(strncmp(romName, "MOMOCOL", 7) == 0) && (sdBuffer[0x14D] == 0x28) ||
|
||||
(strncmp(romName, "BOMCOL", 6) == 0) && (sdBuffer[0x14D] == 0x86) ||
|
||||
(strncmp(romName, "GENCOL", 6) == 0) && (sdBuffer[0x14D] == 0x8A) ||
|
||||
(strncmp(romName, "SUPERCHINESE 123", 16) == 0) && (sdBuffer[0x14D] == 0xE4) ||
|
||||
(strncmp(romName, "MORTALKOMBATI&II", 16) == 0) && (sdBuffer[0x14D] == 0xB9) ||
|
||||
(strncmp(romName, "MORTALKOMBAT DUO", 16) == 0) && (sdBuffer[0x14D] == 0xA7)) {
|
||||
(strncmp(romName, "MOMOCOL", 7) == 0) && (sdBuffer[0x14D] == 0x28) || (strncmp(romName, "BOMCOL", 6) == 0) && (sdBuffer[0x14D] == 0x86) || (strncmp(romName, "GENCOL", 6) == 0) && (sdBuffer[0x14D] == 0x8A) || (strncmp(romName, "SUPERCHINESE 123", 16) == 0) && (sdBuffer[0x14D] == 0xE4) || (strncmp(romName, "MORTALKOMBATI&II", 16) == 0) && (sdBuffer[0x14D] == 0xB9) || (strncmp(romName, "MORTALKOMBAT DUO", 16) == 0) && (sdBuffer[0x14D] == 0xA7)) {
|
||||
romType += 0x100;
|
||||
}
|
||||
|
||||
@ -948,7 +958,7 @@ void readROM_GB() {
|
||||
|
||||
//Initialize progress bar
|
||||
uint32_t processedProgressBar = 0;
|
||||
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
||||
uint32_t totalProgressBar = (uint32_t)(romBanks)*16384;
|
||||
draw_progressbar(0, totalProgressBar);
|
||||
|
||||
// M161 banks are double size and start with 0
|
||||
@ -1028,13 +1038,11 @@ void readROM_GB() {
|
||||
// for every 4Mbits ROM, restart from 0x0000
|
||||
romAddress = 0x0000;
|
||||
currBank++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writeByte_GB(0x6000, 0);
|
||||
writeByte_GB(0x2000, (currBank & 0x1f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if ((romType >= 0x19 && romType <= 0x1E) && (currBank == 0 || currBank == 256)) {
|
||||
writeByte_GB(0x3000, (currBank >> 8) & 0xFF);
|
||||
}
|
||||
@ -1065,7 +1073,7 @@ void readROM_GB() {
|
||||
}
|
||||
|
||||
// Calculate checksum
|
||||
unsigned int calc_checksum_GB (char* fileName, char* folder) {
|
||||
unsigned int calc_checksum_GB(char* fileName, char* folder) {
|
||||
unsigned int calcChecksum = 0;
|
||||
// int calcFilesize = 0; // unused
|
||||
unsigned long i = 0;
|
||||
@ -1115,8 +1123,7 @@ void compare_checksums_GB() {
|
||||
print_Msg(calcsumStr);
|
||||
if (strcmp(calcsumStr, checksumStr) == 0) {
|
||||
println_Msg(F(" -> OK"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F(" != "));
|
||||
println_Msg(checksumStr);
|
||||
print_Error(F("Invalid Checksum"), false);
|
||||
@ -1188,8 +1195,7 @@ void readSRAM_GB() {
|
||||
print_Msg(folder);
|
||||
println_Msg(F("/"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Cart has no SRAM"), false);
|
||||
}
|
||||
}
|
||||
@ -1232,12 +1238,10 @@ void writeSRAM_GB() {
|
||||
println_Msg(F("SRAM writing finished"));
|
||||
display_Update();
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("File doesnt exist"), false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Cart has no SRAM"), false);
|
||||
}
|
||||
}
|
||||
@ -1256,8 +1260,8 @@ unsigned long verifySRAM_GB() {
|
||||
|
||||
// Check SRAM size
|
||||
if (lastByte > 0) {
|
||||
if (romType <= 4) { // MBC1
|
||||
writeByte_GB(0x6000, 1); // Set RAM Mode
|
||||
if (romType <= 4) { // MBC1
|
||||
writeByte_GB(0x6000, 1); // Set RAM Mode
|
||||
}
|
||||
|
||||
// Initialise MBC
|
||||
@ -1284,8 +1288,7 @@ unsigned long verifySRAM_GB() {
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
return writeErrors;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Can't open file"), true);
|
||||
}
|
||||
}
|
||||
@ -1464,8 +1467,7 @@ void writeSRAMFLASH_MBC6_GB() {
|
||||
print_Error(F("Error erasing FLASH sector."), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writeByte_GB(0x2800, 0x08);
|
||||
writeByte_GB(0x3800, 0x08);
|
||||
writeByte_GB(0x2000, currBank);
|
||||
@ -1521,8 +1523,7 @@ void writeSRAMFLASH_MBC6_GB() {
|
||||
myFile.close();
|
||||
println_Msg(F("Save writing finished"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("File doesnt exist"), false);
|
||||
}
|
||||
}
|
||||
@ -1606,36 +1607,31 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
print_Msg(romBanks);
|
||||
println_Msg(F("/256"));
|
||||
display_Update();
|
||||
}
|
||||
else if (strcmp(flashid, "0141") == 0) {
|
||||
} else if (strcmp(flashid, "0141") == 0) {
|
||||
println_Msg(F("AM29F032B"));
|
||||
print_Msg(F("Banks: "));
|
||||
print_Msg(romBanks);
|
||||
println_Msg(F("/256"));
|
||||
display_Update();
|
||||
}
|
||||
else if (strcmp(flashid, "01AD") == 0) {
|
||||
} else if (strcmp(flashid, "01AD") == 0) {
|
||||
println_Msg(F("AM29F016B"));
|
||||
print_Msg(F("Banks: "));
|
||||
print_Msg(romBanks);
|
||||
println_Msg(F("/128"));
|
||||
display_Update();
|
||||
}
|
||||
else if (strcmp(flashid, "04AD") == 0) {
|
||||
} else if (strcmp(flashid, "04AD") == 0) {
|
||||
println_Msg(F("AM29F016D"));
|
||||
print_Msg(F("Banks: "));
|
||||
print_Msg(romBanks);
|
||||
println_Msg(F("/128"));
|
||||
display_Update();
|
||||
}
|
||||
else if (strcmp(flashid, "01D5") == 0) {
|
||||
} else if (strcmp(flashid, "01D5") == 0) {
|
||||
println_Msg(F("AM29F080B"));
|
||||
print_Msg(F("Banks: "));
|
||||
print_Msg(romBanks);
|
||||
println_Msg(F("/64"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Flash ID: "));
|
||||
println_Msg(flashid);
|
||||
display_Update();
|
||||
@ -1703,7 +1699,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
|
||||
//Initialize progress bar
|
||||
uint32_t processedProgressBar = 0;
|
||||
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
||||
uint32_t totalProgressBar = (uint32_t)(romBanks)*16384;
|
||||
draw_progressbar(0, totalProgressBar);
|
||||
|
||||
for (int currBank = 0; currBank < romBanks; currBank++) {
|
||||
@ -1753,7 +1749,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
// Write flash
|
||||
//Initialize progress bar
|
||||
uint32_t processedProgressBar = 0;
|
||||
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
||||
uint32_t totalProgressBar = (uint32_t)(romBanks)*16384;
|
||||
draw_progressbar(0, totalProgressBar);
|
||||
|
||||
for (int currBank = 0; currBank < romBanks; currBank++) {
|
||||
@ -1805,13 +1801,12 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
|
||||
// Read number of banks and switch banks
|
||||
for (word bank = 1; bank < romBanks; bank++) {
|
||||
if (romType >= 5) { // MBC2 and above
|
||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||
}
|
||||
else { // MBC1
|
||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||
writeByte_GB(0x4000, bank >> 5); // Set bits 5 & 6 (01100000) of ROM bank
|
||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
||||
if (romType >= 5) { // MBC2 and above
|
||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||
} else { // MBC1
|
||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||
writeByte_GB(0x4000, bank >> 5); // Set bits 5 & 6 (01100000) of ROM bank
|
||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
||||
}
|
||||
|
||||
if (bank > 1) {
|
||||
@ -1839,15 +1834,13 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Error"));
|
||||
print_Msg(writeErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
print_Error(F("did not verify."), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file"));
|
||||
display_Update();
|
||||
}
|
||||
@ -1890,15 +1883,15 @@ byte writeByteCompensated(int address, byte data) {
|
||||
|
||||
void startCFIMode(boolean x16Mode) {
|
||||
if (x16Mode) {
|
||||
writeByte_GB(0x555, 0xf0); //x16 mode reset command
|
||||
writeByte_GB(0x555, 0xf0); //x16 mode reset command
|
||||
delay(500);
|
||||
writeByte_GB(0x555, 0xf0); //Double reset to get out of possible Autoselect + CFI mode
|
||||
writeByte_GB(0x555, 0xf0); //Double reset to get out of possible Autoselect + CFI mode
|
||||
delay(500);
|
||||
writeByte_GB(0x55, 0x98); //x16 CFI Query command
|
||||
} else {
|
||||
writeByte_GB(0xAAA, 0xf0); //x8 mode reset command
|
||||
writeByte_GB(0xAAA, 0xf0); //x8 mode reset command
|
||||
delay(100);
|
||||
writeByte_GB(0xAAA, 0xf0); //Double reset to get out of possible Autoselect + CFI mode
|
||||
writeByte_GB(0xAAA, 0xf0); //Double reset to get out of possible Autoselect + CFI mode
|
||||
delay(100);
|
||||
writeByte_GB(0xAA, 0x98); //x8 CFI Query command
|
||||
}
|
||||
@ -1910,42 +1903,42 @@ void startCFIMode(boolean x16Mode) {
|
||||
void identifyCFI_GB() {
|
||||
// Reset flash
|
||||
display_Clear();
|
||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||
writeByte_GB(0x2000, 0); // Set Bank to 0
|
||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||
writeByte_GB(0x2000, 0); // Set Bank to 0
|
||||
writeByte_GB(0x3000, 0);
|
||||
|
||||
startCFIMode(false); // Trying x8 mode first
|
||||
startCFIMode(false); // Trying x8 mode first
|
||||
|
||||
display_Clear();
|
||||
// Try x8 mode first
|
||||
char cfiQRYx8[7];
|
||||
char cfiQRYx16[7];
|
||||
sprintf(cfiQRYx8, "%02X%02X%02X", readByte_GB(0x20), readByte_GB(0x22), readByte_GB(0x24));
|
||||
sprintf(cfiQRYx16, "%02X%02X%02X", readByte_GB(0x10), readByte_GB(0x11), readByte_GB(0x12)); // some devices use x8-style CFI Query command even though they are in x16 command mode
|
||||
if (strcmp(cfiQRYx8, "515259") == 0) { // QRY in x8 mode
|
||||
sprintf(cfiQRYx16, "%02X%02X%02X", readByte_GB(0x10), readByte_GB(0x11), readByte_GB(0x12)); // some devices use x8-style CFI Query command even though they are in x16 command mode
|
||||
if (strcmp(cfiQRYx8, "515259") == 0) { // QRY in x8 mode
|
||||
println_Msg(F("Normal CFI x8 Mode"));
|
||||
flashX16Mode = false;
|
||||
flashSwitchLastBits = false;
|
||||
} else if (strcmp(cfiQRYx8, "52515A") == 0) { // QRY in x8 mode with switched last bit
|
||||
} else if (strcmp(cfiQRYx8, "52515A") == 0) { // QRY in x8 mode with switched last bit
|
||||
println_Msg(F("Switched CFI x8 Mode"));
|
||||
flashX16Mode = false;
|
||||
flashSwitchLastBits = true;
|
||||
} else if (strcmp(cfiQRYx16, "515259") == 0) { // QRY in x16 mode
|
||||
} else if (strcmp(cfiQRYx16, "515259") == 0) { // QRY in x16 mode
|
||||
println_Msg(F("Normal CFI x16 Mode"));
|
||||
flashX16Mode = true;
|
||||
flashSwitchLastBits = false;
|
||||
} else if (strcmp(cfiQRYx16, "52515A") == 0) { // QRY in x16 mode with switched last bit
|
||||
} else if (strcmp(cfiQRYx16, "52515A") == 0) { // QRY in x16 mode with switched last bit
|
||||
println_Msg(F("Switched CFI x16 Mode"));
|
||||
flashX16Mode = true;
|
||||
flashSwitchLastBits = true;
|
||||
} else {
|
||||
startCFIMode(true); // Try x16 mode next
|
||||
startCFIMode(true); // Try x16 mode next
|
||||
sprintf(cfiQRYx16, "%02X%02X%02X", readByte_GB(0x10), readByte_GB(0x11), readByte_GB(0x12));
|
||||
if (strcmp(cfiQRYx16, "515259") == 0) { // QRY in x16 mode
|
||||
if (strcmp(cfiQRYx16, "515259") == 0) { // QRY in x16 mode
|
||||
println_Msg(F("Normal CFI x16 Mode"));
|
||||
flashX16Mode = true;
|
||||
flashSwitchLastBits = false;
|
||||
} else if (strcmp(cfiQRYx16, "52515A") == 0) { // QRY in x16 mode with switched last bit
|
||||
} else if (strcmp(cfiQRYx16, "52515A") == 0) { // QRY in x16 mode with switched last bit
|
||||
println_Msg(F("Switched CFI x16 Mode"));
|
||||
flashX16Mode = true;
|
||||
flashSwitchLastBits = true;
|
||||
@ -1956,7 +1949,7 @@ void identifyCFI_GB() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
flashBanks = 1 << (readByteCompensated(0x4E) - 14); // - flashX16Mode);
|
||||
flashBanks = 1 << (readByteCompensated(0x4E) - 14); // - flashX16Mode);
|
||||
|
||||
// Reset flash
|
||||
writeByteCompensated(0xAAA, 0xf0);
|
||||
@ -2134,12 +2127,12 @@ bool writeCFI_GB() {
|
||||
while ((PINC & 0x80) != (sdBuffer[currByte] & 0x80)) {
|
||||
i++;
|
||||
if (i > 500) {
|
||||
if (currAddr < 0x4000) { // This happens when trying to flash an MBC5 as if it was an MBC3. Retry to flash as MBC5, starting from last successfull byte.
|
||||
if (currAddr < 0x4000) { // This happens when trying to flash an MBC5 as if it was an MBC3. Retry to flash as MBC5, starting from last successfull byte.
|
||||
currByte--;
|
||||
currAddr += 0x4000;
|
||||
endAddr = 0x7FFF;
|
||||
break;
|
||||
} else { // If a timeout happens while trying to flash MBC5-style, flashing failed.
|
||||
} else { // If a timeout happens while trying to flash MBC5-style, flashing failed.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2147,8 +2140,7 @@ bool writeCFI_GB() {
|
||||
|
||||
// Switch CS(PH3) and OE/RD(PH6) to HIGH
|
||||
PORTH |= (1 << 3) | (1 << 6);
|
||||
__asm__("nop\n\tnop\n\tnop\n\t"); // Waste a few CPU cycles to remove write errors
|
||||
|
||||
__asm__("nop\n\tnop\n\tnop\n\t"); // Waste a few CPU cycles to remove write errors
|
||||
}
|
||||
currAddr += 512;
|
||||
}
|
||||
@ -2168,13 +2160,12 @@ bool writeCFI_GB() {
|
||||
|
||||
// Read number of banks and switch banks
|
||||
for (word bank = 1; bank < romBanks; bank++) {
|
||||
if (romType >= 5) { // MBC2 and above
|
||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||
}
|
||||
else { // MBC1
|
||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||
writeByte_GB(0x4000, bank >> 5); // Set bits 5 & 6 (01100000) of ROM bank
|
||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
||||
if (romType >= 5) { // MBC2 and above
|
||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||
} else { // MBC1
|
||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||
writeByte_GB(0x4000, bank >> 5); // Set bits 5 & 6 (01100000) of ROM bank
|
||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
||||
}
|
||||
|
||||
if (bank > 1) {
|
||||
@ -2202,15 +2193,13 @@ bool writeCFI_GB() {
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(writeErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
print_Error(F("did not verify."), false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Can't open file"));
|
||||
display_Update();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,7 @@ static const char gbmMenuItem4[] PROGMEM = "Blankcheck";
|
||||
static const char gbmMenuItem5[] PROGMEM = "Write Flash";
|
||||
static const char gbmMenuItem6[] PROGMEM = "Read Mapping";
|
||||
static const char gbmMenuItem7[] PROGMEM = "Write Mapping";
|
||||
static const char* const menuOptionsGBM[] PROGMEM = {gbmMenuItem1, gbmMenuItem2, gbmMenuItem3, gbmMenuItem4, gbmMenuItem5, gbmMenuItem6, gbmMenuItem7};
|
||||
static const char* const menuOptionsGBM[] PROGMEM = { gbmMenuItem1, gbmMenuItem2, gbmMenuItem3, gbmMenuItem4, gbmMenuItem5, gbmMenuItem6, gbmMenuItem7 };
|
||||
|
||||
void gbmMenu() {
|
||||
// create menu with title and 7 options to choose from
|
||||
@ -24,8 +24,7 @@ void gbmMenu() {
|
||||
mainMenu = question_box(F("GB Memory Menu"), menuOptions, 7, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
// Read Flash ID
|
||||
case 0:
|
||||
// Clear screen
|
||||
@ -87,8 +86,7 @@ void gbmMenu() {
|
||||
if (blankcheckFlash_GBM()) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("ERROR"));
|
||||
display_Update();
|
||||
}
|
||||
@ -163,8 +161,7 @@ void gbmMenu() {
|
||||
if (blankcheckMapping_GBM()) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Erasing failed"), false);
|
||||
break;
|
||||
}
|
||||
@ -211,7 +208,26 @@ void setup_GBM() {
|
||||
while (readByte_GBM(0x120) != 0x21) {
|
||||
// Enable ports 0x120h (F2)
|
||||
send_GBM(0x09);
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
timeout++;
|
||||
if (timeout > 10) {
|
||||
println_Msg(F("Error: Time Out"));
|
||||
@ -230,13 +246,19 @@ byte readByte_GBM(word myAddress) {
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
|
||||
__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 CS(PH3) and RD(PH6) to LOW
|
||||
PORTH &= ~(1 << 3);
|
||||
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
|
||||
byte tempByte = PINC;
|
||||
@ -260,13 +282,19 @@ void writeByte_GBM(word myAddress, byte myData) {
|
||||
PORTH &= ~(1 << 3);
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
__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");
|
||||
|
||||
// Pull CS(PH3) and write(PH5) high
|
||||
PORTH |= (1 << 5);
|
||||
PORTH |= (1 << 3);
|
||||
|
||||
__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 to Input (or read errors??!)
|
||||
DDRC = 0x0;
|
||||
@ -306,8 +334,7 @@ void readROM_GBM(word numBanks) {
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_Error(F("Can't create file on SD"), true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Read rom
|
||||
word currAddress = 0;
|
||||
|
||||
@ -472,8 +499,7 @@ boolean readFlashID_GBM() {
|
||||
display_Update();
|
||||
resetFlash_GBM();
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Flash ID: "));
|
||||
println_Msg(flashid);
|
||||
print_Error(F("Unknown Flash ID"), true);
|
||||
@ -652,8 +678,7 @@ void writeFlash_GBM() {
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F("Done"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Can't open file"), false);
|
||||
}
|
||||
}
|
||||
@ -692,8 +717,7 @@ void readMapping_GBM() {
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
print_Error(F("Can't create file on SD"), true);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (byte currByte = 0; currByte < 128; currByte++) {
|
||||
sdBuffer[currByte] = readByte_GBM(currByte);
|
||||
}
|
||||
@ -868,8 +892,7 @@ void writeMapping_GBM() {
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F("Done"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Can't open file"), false);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// Supports 32M cart with LH28F016SUT flash
|
||||
//******************************************
|
||||
#ifdef enable_GBX
|
||||
#define GB_SMART_GAMES_PER_PAGE 6
|
||||
#define GB_SMART_GAMES_PER_PAGE 6
|
||||
|
||||
/******************************************
|
||||
Menu
|
||||
@ -12,19 +12,19 @@
|
||||
static const char gbSmartMenuItem1[] PROGMEM = "Game Menu";
|
||||
static const char gbSmartMenuItem2[] PROGMEM = "Flash Menu";
|
||||
static const char gbSmartMenuItem3[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsGBSmart[] PROGMEM = {gbSmartMenuItem1, gbSmartMenuItem2, gbSmartMenuItem3};
|
||||
static const char* const menuOptionsGBSmart[] PROGMEM = { gbSmartMenuItem1, gbSmartMenuItem2, gbSmartMenuItem3 };
|
||||
|
||||
static const char gbSmartFlashMenuItem1[] PROGMEM = "Read Flash";
|
||||
static const char gbSmartFlashMenuItem2[] PROGMEM = "Write Flash";
|
||||
static const char gbSmartFlashMenuItem3[] PROGMEM = "Back";
|
||||
static const char* const menuOptionsGBSmartFlash[] PROGMEM = {gbSmartFlashMenuItem1, gbSmartFlashMenuItem2, gbSmartFlashMenuItem3};
|
||||
static const char* const menuOptionsGBSmartFlash[] PROGMEM = { gbSmartFlashMenuItem1, gbSmartFlashMenuItem2, gbSmartFlashMenuItem3 };
|
||||
|
||||
static const char gbSmartGameMenuItem1[] PROGMEM = "Read Game";
|
||||
static const char gbSmartGameMenuItem2[] PROGMEM = "Read SRAM";
|
||||
static const char gbSmartGameMenuItem3[] PROGMEM = "Write SRAM";
|
||||
static const char gbSmartGameMenuItem4[] PROGMEM = "Switch Game";
|
||||
static const char gbSmartGameMenuItem5[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsGBSmartGame[] PROGMEM = {gbSmartGameMenuItem1, gbSmartGameMenuItem2, gbSmartGameMenuItem3, gbSmartGameMenuItem4, gbSmartGameMenuItem5};
|
||||
static const char* const menuOptionsGBSmartGame[] PROGMEM = { gbSmartGameMenuItem1, gbSmartGameMenuItem2, gbSmartGameMenuItem3, gbSmartGameMenuItem4, gbSmartGameMenuItem5 };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -80,8 +80,7 @@ boolean compare_checksum_GBS() {
|
||||
println_Msg(F("Checksum matches"));
|
||||
display_Update();
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Result: "));
|
||||
println_Msg(calcsumStr);
|
||||
print_Error(F("Checksum Error"), false);
|
||||
@ -93,12 +92,18 @@ byte readByte_GBS(word myAddress) {
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
|
||||
__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 CS(PH3) and RD(PH6) to LOW
|
||||
PORTH &= ~((1 << 3) | (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
|
||||
byte tempByte = PINC;
|
||||
@ -106,13 +111,15 @@ byte readByte_GBS(word myAddress) {
|
||||
// Switch CS(PH3) and RD(PH6) to HIGH
|
||||
PORTH |= (1 << 3) | (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");
|
||||
|
||||
return tempByte;
|
||||
}
|
||||
|
||||
void setup_GBSmart()
|
||||
{
|
||||
void setup_GBSmart() {
|
||||
// take from setup_GB
|
||||
// Set RST(PH0) to Input
|
||||
DDRH &= ~(1 << 0);
|
||||
@ -150,8 +157,7 @@ void setup_GBSmart()
|
||||
display_Update();
|
||||
}
|
||||
|
||||
void gbSmartMenu()
|
||||
{
|
||||
void gbSmartMenu() {
|
||||
uint8_t mainMenu;
|
||||
|
||||
// Copy menuOptions out of progmem
|
||||
@ -159,8 +165,7 @@ void gbSmartMenu()
|
||||
mainMenu = question_box(F("GB Smart"), menuOptions, 3, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
{
|
||||
gbSmartGameMenu();
|
||||
@ -173,22 +178,20 @@ void gbSmartMenu()
|
||||
}
|
||||
default:
|
||||
{
|
||||
asm volatile (" jmp 0");
|
||||
asm volatile(" jmp 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gbSmartGameOptions()
|
||||
{
|
||||
void gbSmartGameOptions() {
|
||||
uint8_t gameSubMenu;
|
||||
|
||||
convertPgm(menuOptionsGBSmartGame, 5);
|
||||
gameSubMenu = question_box(F("GB Smart Game Menu"), menuOptions, 5, 0);
|
||||
|
||||
switch (gameSubMenu)
|
||||
{
|
||||
case 0: // Read Game
|
||||
switch (gameSubMenu) {
|
||||
case 0: // Read Game
|
||||
{
|
||||
display_Clear();
|
||||
sd.chdir("/");
|
||||
@ -196,26 +199,23 @@ void gbSmartGameOptions()
|
||||
compare_checksum_GBS();
|
||||
break;
|
||||
}
|
||||
case 1: // Read SRAM
|
||||
case 1: // Read SRAM
|
||||
{
|
||||
display_Clear();
|
||||
sd.chdir("/");
|
||||
readSRAM_GB();
|
||||
break;
|
||||
}
|
||||
case 2: // Write SRAM
|
||||
case 2: // Write SRAM
|
||||
{
|
||||
display_Clear();
|
||||
sd.chdir("/");
|
||||
writeSRAM_GB();
|
||||
uint32_t wrErrors = verifySRAM_GB();
|
||||
if (wrErrors == 0)
|
||||
{
|
||||
if (wrErrors == 0) {
|
||||
println_Msg(F("Verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(wrErrors);
|
||||
println_Msg(F(" bytes"));
|
||||
@ -223,7 +223,7 @@ void gbSmartGameOptions()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: // Switch Game
|
||||
case 3: // Switch Game
|
||||
{
|
||||
gameMenuStartBank = 0x02;
|
||||
gbSmartGameMenu();
|
||||
@ -231,13 +231,12 @@ void gbSmartGameOptions()
|
||||
}
|
||||
default:
|
||||
{
|
||||
asm volatile (" jmp 0");
|
||||
asm volatile(" jmp 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gameSubMenu != 3)
|
||||
{
|
||||
if (gameSubMenu != 3) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Press Button..."));
|
||||
display_Update();
|
||||
@ -245,8 +244,7 @@ void gbSmartGameOptions()
|
||||
}
|
||||
}
|
||||
|
||||
void gbSmartGameMenu()
|
||||
{
|
||||
void gbSmartGameMenu() {
|
||||
uint8_t gameSubMenu = 0;
|
||||
gb_smart_load_more_games:
|
||||
if (gameMenuStartBank > 0xfe)
|
||||
@ -254,8 +252,7 @@ gb_smart_load_more_games:
|
||||
|
||||
gbSmartGetGames();
|
||||
|
||||
if (hasMenu)
|
||||
{
|
||||
if (hasMenu) {
|
||||
char menuOptionsGBSmartGames[7][20];
|
||||
int i = 0;
|
||||
for (; i < numGames; i++)
|
||||
@ -266,9 +263,7 @@ gb_smart_load_more_games:
|
||||
|
||||
if (gameSubMenu >= i)
|
||||
goto gb_smart_load_more_games;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
gameSubMenu = 0;
|
||||
}
|
||||
|
||||
@ -283,15 +278,13 @@ gb_smart_load_more_games:
|
||||
mode = mode_GB_GBSmart_Game;
|
||||
}
|
||||
|
||||
void gbSmartFlashMenu()
|
||||
{
|
||||
void gbSmartFlashMenu() {
|
||||
uint8_t flashSubMenu;
|
||||
|
||||
convertPgm(menuOptionsGBSmartFlash, 3);
|
||||
flashSubMenu = question_box(F("GB Smart Flash Menu"), menuOptions, 3, 0);
|
||||
|
||||
switch (flashSubMenu)
|
||||
{
|
||||
switch (flashSubMenu) {
|
||||
case 0:
|
||||
{
|
||||
// read flash
|
||||
@ -343,9 +336,8 @@ void gbSmartFlashMenu()
|
||||
wait();
|
||||
}
|
||||
|
||||
void gbSmartGetGames()
|
||||
{
|
||||
static const byte menu_title[] = {0x47, 0x42, 0x31, 0x36, 0x4d};
|
||||
void gbSmartGetGames() {
|
||||
static const byte menu_title[] = { 0x47, 0x42, 0x31, 0x36, 0x4d };
|
||||
|
||||
// reset remap setting
|
||||
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
||||
@ -356,19 +348,15 @@ void gbSmartGetGames()
|
||||
// check if contain menu
|
||||
hasMenu = true;
|
||||
dataIn();
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (readByte_GBS(0x0134 + i) != menu_title[i])
|
||||
{
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (readByte_GBS(0x0134 + i) != menu_title[i]) {
|
||||
hasMenu = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMenu)
|
||||
{
|
||||
for (i = gameMenuStartBank, numGames = 0; i < gbSmartBanks && numGames < GB_SMART_GAMES_PER_PAGE; )
|
||||
{
|
||||
if (hasMenu) {
|
||||
for (i = gameMenuStartBank, numGames = 0; i < gbSmartBanks && numGames < GB_SMART_GAMES_PER_PAGE;) {
|
||||
myLength = 0;
|
||||
|
||||
// switch bank
|
||||
@ -377,21 +365,17 @@ void gbSmartGetGames()
|
||||
|
||||
dataIn();
|
||||
// read signature
|
||||
for (uint8_t j = 0x00; j < 0x30; j++)
|
||||
{
|
||||
if (readByte_GBS(0x4104 + j) != signature[j])
|
||||
{
|
||||
for (uint8_t j = 0x00; j < 0x30; j++) {
|
||||
if (readByte_GBS(0x4104 + j) != signature[j]) {
|
||||
i += 0x02;
|
||||
goto gb_smart_get_game_loop_end;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t j = 0; j < 15; j++)
|
||||
{
|
||||
for (uint8_t j = 0; j < 15; j++) {
|
||||
myByte = readByte_GBS(0x4134 + j);
|
||||
|
||||
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) ||
|
||||
(char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
||||
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) || (char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
||||
gbSmartGames[numGames].title[myLength++] = char(myByte);
|
||||
}
|
||||
|
||||
@ -408,16 +392,12 @@ gb_smart_get_game_loop_end:;
|
||||
}
|
||||
|
||||
gameMenuStartBank = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
dataIn();
|
||||
for (uint8_t j = 0; j < 15; j++)
|
||||
{
|
||||
for (uint8_t j = 0; j < 15; j++) {
|
||||
myByte = readByte_GBS(0x0134 + j);
|
||||
|
||||
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) ||
|
||||
(char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
||||
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) || (char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
||||
gbSmartGames[0].title[myLength++] = char(myByte);
|
||||
}
|
||||
|
||||
@ -432,8 +412,7 @@ gb_smart_get_game_loop_end:;
|
||||
}
|
||||
}
|
||||
|
||||
void gbSmartReadFlash()
|
||||
{
|
||||
void gbSmartReadFlash() {
|
||||
print_Msg(F("Saving as GB/GBS/"));
|
||||
print_Msg(fileName);
|
||||
println_Msg(F("..."));
|
||||
@ -451,8 +430,7 @@ void gbSmartReadFlash()
|
||||
|
||||
// dump fixed bank 0x00
|
||||
dataIn();
|
||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512)
|
||||
{
|
||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512) {
|
||||
for (uint16_t c = 0; c < 512; c++)
|
||||
sdBuffer[c] = readByte_GBS(addr + c);
|
||||
|
||||
@ -460,14 +438,12 @@ void gbSmartReadFlash()
|
||||
}
|
||||
|
||||
// read rest banks
|
||||
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++)
|
||||
{
|
||||
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++) {
|
||||
dataOut();
|
||||
writeByte_GB(0x2100, bank);
|
||||
|
||||
dataIn();
|
||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512)
|
||||
{
|
||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512) {
|
||||
for (uint16_t c = 0; c < 512; c++)
|
||||
sdBuffer[c] = readByte_GBS(addr + c);
|
||||
|
||||
@ -484,10 +460,8 @@ void gbSmartReadFlash()
|
||||
display_Update();
|
||||
}
|
||||
|
||||
void gbSmartWriteFlash()
|
||||
{
|
||||
for (int bank = 0x00; bank < gbSmartBanks; bank += gbSmartBanksPerFlashChip)
|
||||
{
|
||||
void gbSmartWriteFlash() {
|
||||
for (int bank = 0x00; bank < gbSmartBanks; bank += gbSmartBanksPerFlashChip) {
|
||||
display_Clear();
|
||||
|
||||
print_Msg(F("Erasing..."));
|
||||
@ -517,13 +491,10 @@ void gbSmartWriteFlash()
|
||||
display_Update();
|
||||
|
||||
writeErrors = gbSmartVerifyFlash();
|
||||
if (writeErrors == 0)
|
||||
{
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(writeErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
@ -531,8 +502,7 @@ void gbSmartWriteFlash()
|
||||
}
|
||||
}
|
||||
|
||||
void gbSmartWriteFlash(uint32_t start_bank)
|
||||
{
|
||||
void gbSmartWriteFlash(uint32_t start_bank) {
|
||||
if (!myFile.open(filePath, O_READ))
|
||||
print_Error(F("Can't open file on SD"), true);
|
||||
|
||||
@ -550,8 +520,7 @@ void gbSmartWriteFlash(uint32_t start_bank)
|
||||
gbSmartWriteFlashFromMyFile(0x0000);
|
||||
|
||||
// handle rest banks on 0x4000
|
||||
for (uint8_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++)
|
||||
{
|
||||
for (uint8_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++) {
|
||||
dataOut();
|
||||
writeByte_GB(0x2100, bank);
|
||||
|
||||
@ -562,17 +531,15 @@ void gbSmartWriteFlash(uint32_t start_bank)
|
||||
println_Msg("");
|
||||
}
|
||||
|
||||
void gbSmartWriteFlashFromMyFile(uint32_t addr)
|
||||
{
|
||||
for (uint16_t i = 0; i < 16384; i += 256)
|
||||
{
|
||||
void gbSmartWriteFlashFromMyFile(uint32_t addr) {
|
||||
for (uint16_t i = 0; i < 16384; i += 256) {
|
||||
myFile.read(sdBuffer, 256);
|
||||
|
||||
// sequence load to page
|
||||
dataOut();
|
||||
gbSmartWriteFlashByte(addr, 0xe0);
|
||||
gbSmartWriteFlashByte(addr, 0xff);
|
||||
gbSmartWriteFlashByte(addr, 0x00); // BCH should be 0x00
|
||||
gbSmartWriteFlashByte(addr, 0x00); // BCH should be 0x00
|
||||
|
||||
// fill page buffer
|
||||
for (int d = 0; d < 256; d++)
|
||||
@ -585,53 +552,45 @@ void gbSmartWriteFlashFromMyFile(uint32_t addr)
|
||||
|
||||
// waiting for finishing
|
||||
dataIn();
|
||||
while ((readByte_GBS(addr + i) & 0x80) == 0x00);
|
||||
while ((readByte_GBS(addr + i) & 0x80) == 0x00)
|
||||
;
|
||||
}
|
||||
|
||||
// blink LED
|
||||
blinkLED();
|
||||
}
|
||||
|
||||
uint32_t gbSmartVerifyFlash()
|
||||
{
|
||||
uint32_t gbSmartVerifyFlash() {
|
||||
uint32_t verified = 0;
|
||||
|
||||
if (!myFile.open(filePath, O_READ))
|
||||
{
|
||||
if (!myFile.open(filePath, O_READ)) {
|
||||
verified = 0xffffffff;
|
||||
print_Error(F("Can't open file on SD"), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// remaps mmc to full access
|
||||
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
||||
|
||||
// verify bank 0x00
|
||||
dataIn();
|
||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512)
|
||||
{
|
||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512) {
|
||||
myFile.read(sdBuffer, 512);
|
||||
|
||||
for (uint16_t c = 0; c < 512; c++)
|
||||
{
|
||||
for (uint16_t c = 0; c < 512; c++) {
|
||||
if (readByte_GBS(addr + c) != sdBuffer[c])
|
||||
verified++;
|
||||
}
|
||||
}
|
||||
|
||||
// verify rest banks
|
||||
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++)
|
||||
{
|
||||
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++) {
|
||||
dataOut();
|
||||
writeByte_GB(0x2100, bank);
|
||||
|
||||
dataIn();
|
||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512)
|
||||
{
|
||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512) {
|
||||
myFile.read(sdBuffer, 512);
|
||||
|
||||
for (uint16_t c = 0; c < 512; c++)
|
||||
{
|
||||
for (uint16_t c = 0; c < 512; c++) {
|
||||
if (readByte_GBS(addr + c) != sdBuffer[c])
|
||||
verified++;
|
||||
}
|
||||
@ -647,27 +606,23 @@ uint32_t gbSmartVerifyFlash()
|
||||
return verified;
|
||||
}
|
||||
|
||||
byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank)
|
||||
{
|
||||
byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank) {
|
||||
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
||||
|
||||
// check first bank
|
||||
dataIn();
|
||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr++)
|
||||
{
|
||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr++) {
|
||||
if (readByte_GBS(addr) != 0xff)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check rest banks
|
||||
for (uint16_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++)
|
||||
{
|
||||
for (uint16_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++) {
|
||||
dataOut();
|
||||
writeByte_GB(0x2100, bank);
|
||||
|
||||
dataIn();
|
||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr++)
|
||||
{
|
||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr++) {
|
||||
if (readByte_GBS(addr) != 0xff)
|
||||
return 0;
|
||||
}
|
||||
@ -676,16 +631,14 @@ byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void gbSmartResetFlash(uint8_t flash_start_bank)
|
||||
{
|
||||
void gbSmartResetFlash(uint8_t flash_start_bank) {
|
||||
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
||||
|
||||
dataOut();
|
||||
gbSmartWriteFlashByte(0x0, 0xff);
|
||||
}
|
||||
|
||||
void gbSmartEraseFlash(uint8_t flash_start_bank)
|
||||
{
|
||||
void gbSmartEraseFlash(uint8_t flash_start_bank) {
|
||||
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
||||
|
||||
// handling first flash block
|
||||
@ -694,14 +647,14 @@ void gbSmartEraseFlash(uint8_t flash_start_bank)
|
||||
gbSmartWriteFlashByte(0x0000, 0xd0);
|
||||
|
||||
dataIn();
|
||||
while ((readByte_GBS(0x0000) & 0x80) == 0x00);
|
||||
while ((readByte_GBS(0x0000) & 0x80) == 0x00)
|
||||
;
|
||||
|
||||
// blink LED
|
||||
blinkLED();
|
||||
|
||||
// rest of flash block
|
||||
for (uint32_t ba = gbSmartBanksPerFlashBlock; ba < gbSmartBanksPerFlashChip; ba += gbSmartBanksPerFlashBlock)
|
||||
{
|
||||
for (uint32_t ba = gbSmartBanksPerFlashBlock; ba < gbSmartBanksPerFlashChip; ba += gbSmartBanksPerFlashBlock) {
|
||||
dataOut();
|
||||
writeByte_GB(0x2100, ba);
|
||||
|
||||
@ -709,15 +662,15 @@ void gbSmartEraseFlash(uint8_t flash_start_bank)
|
||||
gbSmartWriteFlashByte(0x4000, 0xd0);
|
||||
|
||||
dataIn();
|
||||
while ((readByte_GBS(0x4000) & 0x80) == 0x00);
|
||||
while ((readByte_GBS(0x4000) & 0x80) == 0x00)
|
||||
;
|
||||
|
||||
// blink LED
|
||||
blinkLED();
|
||||
}
|
||||
}
|
||||
|
||||
void gbSmartWriteFlashByte(uint32_t myAddress, uint8_t myData)
|
||||
{
|
||||
void gbSmartWriteFlashByte(uint32_t myAddress, uint8_t myData) {
|
||||
PORTF = myAddress & 0xff;
|
||||
PORTK = (myAddress >> 8) & 0xff;
|
||||
PORTC = myData;
|
||||
@ -739,8 +692,7 @@ void gbSmartWriteFlashByte(uint32_t myAddress, uint8_t myData)
|
||||
}
|
||||
|
||||
// rom_start_bank = 0x00 means back to original state
|
||||
void gbSmartRemapStartBank(uint8_t rom_start_bank, uint8_t rom_size, uint8_t sram_size)
|
||||
{
|
||||
void gbSmartRemapStartBank(uint8_t rom_start_bank, uint8_t rom_size, uint8_t sram_size) {
|
||||
rom_start_bank &= 0xfe;
|
||||
|
||||
dataOut();
|
||||
@ -751,8 +703,7 @@ void gbSmartRemapStartBank(uint8_t rom_start_bank, uint8_t rom_size, uint8_t sra
|
||||
writeByte_GB(0x1000, 0x98);
|
||||
writeByte_GB(0x2000, rom_start_bank);
|
||||
|
||||
if (rom_start_bank > 1)
|
||||
{
|
||||
if (rom_start_bank > 1) {
|
||||
// start set new base bank
|
||||
writeByte_GB(0x1000, 0xa5);
|
||||
|
||||
@ -773,35 +724,25 @@ void gbSmartRemapStartBank(uint8_t rom_start_bank, uint8_t rom_size, uint8_t sra
|
||||
// Use for setting correct rom and sram size
|
||||
// Code logic is take from SmartCard32M V1.3 menu code,
|
||||
// see 0x2db2 to 0x2e51 (0xa0 bytes)
|
||||
uint8_t gbSmartGetResizeParam(uint8_t rom_size, uint8_t sram_size)
|
||||
{
|
||||
if (rom_size < 0x0f)
|
||||
{
|
||||
uint8_t gbSmartGetResizeParam(uint8_t rom_size, uint8_t sram_size) {
|
||||
if (rom_size < 0x0f) {
|
||||
rom_size &= 0x07;
|
||||
rom_size ^= 0x07;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
rom_size = 0x01;
|
||||
}
|
||||
|
||||
if (sram_size > 0)
|
||||
{
|
||||
if (sram_size > 1)
|
||||
{
|
||||
if (sram_size > 0) {
|
||||
if (sram_size > 1) {
|
||||
sram_size--;
|
||||
sram_size ^= 0x03;
|
||||
sram_size <<= 4;
|
||||
sram_size &= 0x30;
|
||||
} else {
|
||||
sram_size = 0x20; // 2KiB treat as 8KiB
|
||||
}
|
||||
else
|
||||
{
|
||||
sram_size = 0x20; // 2KiB treat as 8KiB
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sram_size = 0x30; // no sram
|
||||
} else {
|
||||
sram_size = 0x30; // no sram
|
||||
}
|
||||
|
||||
return (sram_size | rom_size);
|
||||
|
@ -57,27 +57,27 @@
|
||||
|
||||
// Cart Configurations
|
||||
// Format = {mapper,romlo,romhi,ramsize}
|
||||
static const byte PROGMEM intvmapsize [] = {
|
||||
0, 0, 2, 0, // default mattel up to 32K (8K/16K/24K/32K)
|
||||
1, 1, 3, 0, // demo cart 16K, championship tennis 32K, wsml baseball 48K
|
||||
2, 1, 3, 0, // up to 48K (16K/32K/48K)
|
||||
3, 4, 4, 0, // tower of doom 48K
|
||||
4, 0, 1, 1, // uscf chess 16K + RAM 1K
|
||||
5, 2, 3, 0, // congo bongo/defender/pac-man 24K, dig dug 32K
|
||||
6, 1, 1, 0, // centipede 16K
|
||||
7, 1, 1, 0, // imagic carts 16K
|
||||
8, 1, 1, 0, // mte-201 test cart 16K
|
||||
9, 3, 3, 2, // triple challenge 32K + RAM 2K
|
||||
static const byte PROGMEM intvmapsize[] = {
|
||||
0, 0, 2, 0, // default mattel up to 32K (8K/16K/24K/32K)
|
||||
1, 1, 3, 0, // demo cart 16K, championship tennis 32K, wsml baseball 48K
|
||||
2, 1, 3, 0, // up to 48K (16K/32K/48K)
|
||||
3, 4, 4, 0, // tower of doom 48K
|
||||
4, 0, 1, 1, // uscf chess 16K + RAM 1K
|
||||
5, 2, 3, 0, // congo bongo/defender/pac-man 24K, dig dug 32K
|
||||
6, 1, 1, 0, // centipede 16K
|
||||
7, 1, 1, 0, // imagic carts 16K
|
||||
8, 1, 1, 0, // mte-201 test cart 16K
|
||||
9, 3, 3, 2, // triple challenge 32K + RAM 2K
|
||||
};
|
||||
|
||||
byte intvmapcount = 10; // (sizeof(mapsize)/sizeof(mapsize[0])) / 4;
|
||||
byte intvmapcount = 10; // (sizeof(mapsize)/sizeof(mapsize[0])) / 4;
|
||||
boolean intvmapfound = false;
|
||||
byte intvmapselect;
|
||||
int intvindex;
|
||||
|
||||
byte INTV[] = {8, 16, 24, 32, 48};
|
||||
byte intvlo = 0; // Lowest Entry
|
||||
byte intvhi = 4; // Highest Entry
|
||||
byte INTV[] = { 8, 16, 24, 32, 48 };
|
||||
byte intvlo = 0; // Lowest Entry
|
||||
byte intvhi = 4; // Highest Entry
|
||||
|
||||
byte intvmapper;
|
||||
byte newintvmapper;
|
||||
@ -96,10 +96,9 @@ static const char intvMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char intvMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char intvMenuItem3[] PROGMEM = "Set Mapper + Size";
|
||||
static const char intvMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsINTV[] PROGMEM = {intvMenuItem1, intvMenuItem2, intvMenuItem3, intvMenuItem4};
|
||||
static const char* const menuOptionsINTV[] PROGMEM = { intvMenuItem1, intvMenuItem2, intvMenuItem3, intvMenuItem4 };
|
||||
|
||||
void setup_INTV()
|
||||
{
|
||||
void setup_INTV() {
|
||||
// Set Address Pins to Output (UNUSED)
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
@ -113,7 +112,7 @@ void setup_INTV()
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set TIME(PJ0) to Output (UNUSED)
|
||||
DDRJ |= (1 << 0);
|
||||
DDRJ |= (1 << 0);
|
||||
|
||||
// Set Pins (DB0-DB15) to Input
|
||||
DDRC = 0x00;
|
||||
@ -124,10 +123,10 @@ void setup_INTV()
|
||||
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set Unused Pins HIGH
|
||||
PORTF = 0xFF; // A0-A7
|
||||
PORTK = 0xFF; // A8-A15
|
||||
PORTL = 0xFF; // A16-A23
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
PORTF = 0xFF; // A0-A7
|
||||
PORTK = 0xFF; // A8-A15
|
||||
PORTL = 0xFF; // A16-A23
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
|
||||
checkStatus_INTV();
|
||||
strcpy(romName, "INTV");
|
||||
@ -135,13 +134,11 @@ void setup_INTV()
|
||||
mode = mode_INTV;
|
||||
}
|
||||
|
||||
void intvMenu()
|
||||
{
|
||||
void intvMenu() {
|
||||
convertPgm(menuOptionsINTV, 4);
|
||||
uint8_t mainMenu = question_box(F("INTELLIVISION MENU"), menuOptions, 4, 0);
|
||||
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
// Select Cart
|
||||
setCart_INTV();
|
||||
@ -185,8 +182,7 @@ void intvMenu()
|
||||
// DIRECT ADDRESSING MODE READ SEQUENCE: BAR-NACT-ADAR-NACT-DTB-NACT
|
||||
|
||||
// NO ACTION (NACT) - 0/0/0
|
||||
void NACT_INT()
|
||||
{
|
||||
void NACT_INT() {
|
||||
// Switch BC1(PH4) + BC2(PH5) + BDIR(PH6) to LOW
|
||||
PORTH &= ~(1 << 4) & ~(1 << 5) & ~(1 << 6);
|
||||
// DB0..DB15 INPUT
|
||||
@ -195,8 +191,7 @@ void NACT_INT()
|
||||
}
|
||||
|
||||
// SET ADDRESS - BUS TO ADDR (BAR) - 1/0/0
|
||||
void BAR_INT()
|
||||
{
|
||||
void BAR_INT() {
|
||||
// Switch BDIR(PH6) to HIGH
|
||||
PORTH |= (1 << 6);
|
||||
// Switch BC1(PH4) + BC2(PH5) to LOW
|
||||
@ -207,8 +202,7 @@ void BAR_INT()
|
||||
}
|
||||
|
||||
// READ DATA - DATA TO BUS (DTB) - 0/1/1
|
||||
void DTB_INT()
|
||||
{
|
||||
void DTB_INT() {
|
||||
// Switch BDIR(PH6) to LOW
|
||||
PORTH &= ~(1 << 6);
|
||||
// Switch BC1(PH4) + BC2(PH5) to HIGH
|
||||
@ -219,8 +213,7 @@ void DTB_INT()
|
||||
}
|
||||
|
||||
// ADDRESS DATA TO ADDRESS REGISTER (ADAR) - 0/1/0
|
||||
void ADAR_INT()
|
||||
{
|
||||
void ADAR_INT() {
|
||||
// Switch BC2(PH5) + BDIR(PH6) to LOW
|
||||
PORTH &= ~(1 << 5) & ~(1 << 6);
|
||||
// Switch BC1(PH4) to HIGH
|
||||
@ -231,8 +224,7 @@ void ADAR_INT()
|
||||
// DATA SHOULD BE STABLE ACROSS BOTH
|
||||
|
||||
// DATA WRITE (DW) - 1/1/0
|
||||
void DW_INT()
|
||||
{
|
||||
void DW_INT() {
|
||||
// Switch BC1(PH4) + BDIR(PH6) to HIGH
|
||||
PORTH |= (1 << 4) | (1 << 6);
|
||||
// Switch BC2(PH5) to LOW
|
||||
@ -240,8 +232,7 @@ void DW_INT()
|
||||
}
|
||||
|
||||
// DATA WRITE STROBE (DWS) - 1/0/1
|
||||
void DWS_INT()
|
||||
{
|
||||
void DWS_INT() {
|
||||
// Switch BC2(PH5) + BDIR(PH6) to HIGH
|
||||
PORTH |= (1 << 5) | (1 << 6);
|
||||
// Switch BC1(PH4) to LOW
|
||||
@ -252,25 +243,40 @@ void DWS_INT()
|
||||
// READ CODE
|
||||
//******************************************
|
||||
|
||||
uint16_t readData_INTV(uint32_t addr)
|
||||
{
|
||||
uint16_t readData_INTV(uint32_t addr) {
|
||||
PORTC = addr & 0xFF;
|
||||
PORTA = (addr >> 8) & 0xFF;
|
||||
|
||||
BAR_INT();
|
||||
// Wait for bus
|
||||
// 5 x 62.5ns = 312.5ns
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
NACT_INT();
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
DTB_INT();
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
uint16_t ret = (((PINA & 0xFF) << 8) | (PINC & 0xFF));
|
||||
|
||||
NACT_INT();
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -287,8 +293,7 @@ uint16_t readData_INTV(uint32_t addr)
|
||||
// 8: 0x50-0x60,0x70-0x80, // mte-201 test cart 16K
|
||||
// 9: 0x50-0x70,0x90-0xB0,[0xC0-0xC8,0xD0-0xD8] // triple challenge 32K + RAM 2K [0xC0 + 0xD0 segments are not needed]
|
||||
|
||||
void readSegment_INTV(uint32_t startaddr, uint32_t endaddr)
|
||||
{
|
||||
void readSegment_INTV(uint32_t startaddr, uint32_t endaddr) {
|
||||
for (uint32_t addr = startaddr; addr < endaddr; addr += 256) {
|
||||
for (uint16_t w = 0; w < 256; w++) {
|
||||
uint16_t temp = readData_INTV(addr + w);
|
||||
@ -300,8 +305,7 @@ void readSegment_INTV(uint32_t startaddr, uint32_t endaddr)
|
||||
}
|
||||
|
||||
// MODIFIED READ ROUTINE FOR ALL 10 MAPPERS
|
||||
void readROM_INTV()
|
||||
{
|
||||
void readROM_INTV() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".int");
|
||||
|
||||
@ -326,88 +330,88 @@ void readROM_INTV()
|
||||
EEPROM_writeAnything(0, foldern);
|
||||
|
||||
switch (intvmapper) {
|
||||
case 0: //default mattel up to 32K (8K/16K/24K/32K)
|
||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||
case 0: //default mattel up to 32K (8K/16K/24K/32K)
|
||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||
if (intvsize > 0) {
|
||||
readSegment_INTV(0x6000, 0x7000); // +8K = 16K
|
||||
readSegment_INTV(0x6000, 0x7000); // +8K = 16K
|
||||
if (intvsize > 1) {
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 24K
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 24K
|
||||
if (intvsize > 2)
|
||||
readSegment_INTV(0xF000, 0x10000); // +8K = 32K
|
||||
readSegment_INTV(0xF000, 0x10000); // +8K = 32K
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // demo cart/championship tennis/wsml baseball
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K Demo Cart
|
||||
case 1: // demo cart/championship tennis/wsml baseball
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K Demo Cart
|
||||
if (intvsize > 1) {
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 24K [NONE]
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 24K [NONE]
|
||||
if (intvsize > 2) {
|
||||
readSegment_INTV(0xE000, 0xF000); // +8K = 32K Championship Tennis
|
||||
readSegment_INTV(0xE000, 0xF000); // +8K = 32K Championship Tennis
|
||||
if (intvsize > 3) {
|
||||
readSegment_INTV(0xF000, 0x10000); // +8K = 40K WSML Baseball [MISSING 8K ECS BANK]
|
||||
readSegment_INTV(0xF000, 0x10000); // +8K = 40K WSML Baseball [MISSING 8K ECS BANK]
|
||||
// ecs bank switch
|
||||
ecsBank(0xFFFF, 0x1); // switch ecs page 1 to 0xF000
|
||||
readSegment_INTV(0xF000, 0x10000); // + 8K = 48K WSML Baseball
|
||||
ecsBank(0xFFFF, 0x0); // reset ecs page 0 to 0xF000
|
||||
ecsBank(0xFFFF, 0x1); // switch ecs page 1 to 0xF000
|
||||
readSegment_INTV(0xF000, 0x10000); // + 8K = 48K WSML Baseball
|
||||
ecsBank(0xFFFF, 0x0); // reset ecs page 0 to 0xF000
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // up to 48K (16K/32K/48K)
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
case 2: // up to 48K (16K/32K/48K)
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
if (intvsize > 1) {
|
||||
readSegment_INTV(0x9000, 0xA000); // +8K = 24K [NONE]
|
||||
readSegment_INTV(0x9000, 0xA000); // +8K = 24K [NONE]
|
||||
if (intvsize > 2) {
|
||||
readSegment_INTV(0xA000, 0xB000); // +8K = 32K
|
||||
readSegment_INTV(0xA000, 0xB000); // +8K = 32K
|
||||
if (intvsize > 3) {
|
||||
readSegment_INTV(0xB000, 0xC000); // +8K = 40K
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 48K
|
||||
readSegment_INTV(0xB000, 0xC000); // +8K = 40K
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 48K
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // tower of doom 48K
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 40K
|
||||
readSegment_INTV(0xF000, 0x10000); // +8K = 48K
|
||||
case 3: // tower of doom 48K
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
||||
readSegment_INTV(0xD000, 0xE000); // +8K = 40K
|
||||
readSegment_INTV(0xF000, 0x10000); // +8K = 48K
|
||||
break;
|
||||
|
||||
case 4: // chess 16K
|
||||
PORTH &= ~(1 << 3); // /MSYNC to LOW
|
||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||
PORTH |= (1 << 3); // /MSYNC to HIGH
|
||||
readSegment_INTV(0x6000, 0x7000); // 8K
|
||||
case 4: // chess 16K
|
||||
PORTH &= ~(1 << 3); // /MSYNC to LOW
|
||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||
PORTH |= (1 << 3); // /MSYNC to HIGH
|
||||
readSegment_INTV(0x6000, 0x7000); // 8K
|
||||
break;
|
||||
|
||||
case 5:// congo bongo/defender/pac-man/dig dug
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
readSegment_INTV(0x7000, 0x8000); // +8K = 24K Congo Bongo/Defender/Pac-Man
|
||||
case 5: // congo bongo/defender/pac-man/dig dug
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
readSegment_INTV(0x7000, 0x8000); // +8K = 24K Congo Bongo/Defender/Pac-Man
|
||||
if (intvsize > 2) {
|
||||
readSegment_INTV(0x9000, 0xA000); // +8K = 32K Dig Dug
|
||||
readSegment_INTV(0x9000, 0xA000); // +8K = 32K Dig Dug
|
||||
//readSegment_INTV(0xA000,0xC000); // +16K = 48K [UNUSED]
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: // centipede 16K
|
||||
readSegment_INTV(0x6000, 0x8000); // 16K
|
||||
case 6: // centipede 16K
|
||||
readSegment_INTV(0x6000, 0x8000); // 16K
|
||||
break;
|
||||
|
||||
case 7: // imagic carts 16K
|
||||
readSegment_INTV(0x4800, 0x6800); // 16K
|
||||
case 7: // imagic carts 16K
|
||||
readSegment_INTV(0x4800, 0x6800); // 16K
|
||||
break;
|
||||
|
||||
case 8: //mte-201 test cart 16K
|
||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||
readSegment_INTV(0x7000, 0x8000); // +8K = 16K
|
||||
case 8: //mte-201 test cart 16K
|
||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||
readSegment_INTV(0x7000, 0x8000); // +8K = 16K
|
||||
break;
|
||||
|
||||
case 9: // triple challenge 32K [KNOWN ROM 44K BAD!]
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
||||
case 9: // triple challenge 32K [KNOWN ROM 44K BAD!]
|
||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
||||
// 0xC000 + 0xD000 SEGMENTS ARE NOT NEEDED (PER INTVNUT POST)
|
||||
// readSegment_INTV(0xC000,0xC800); // +4K = 36K
|
||||
// readSegment_INTV(0xD000,0xE000); // +8K = 44K
|
||||
@ -429,7 +433,7 @@ void readROM_INTV()
|
||||
// x = rom location ($x000 - $xFFF)
|
||||
// y = page (up to 16 - WSML Baseball only uses 0/1)
|
||||
void ecsBank(uint32_t addr, uint8_t bank) {
|
||||
uint16_t ecsdata = (addr & 0xF000) + 0x0A50 + bank; // $xA5y
|
||||
uint16_t ecsdata = (addr & 0xF000) + 0x0A50 + bank; // $xA5y
|
||||
|
||||
// Data OUT
|
||||
DDRA = 0xFF;
|
||||
@ -440,47 +444,62 @@ void ecsBank(uint32_t addr, uint8_t bank) {
|
||||
PORTC = addr & 0xFF;
|
||||
|
||||
BAR_INT();
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NACT_INT();
|
||||
NOP;
|
||||
|
||||
// Data OUT
|
||||
DDRA = 0xFF;
|
||||
DDRC = 0xFF;
|
||||
PORTA = (ecsdata >> 8) & 0xFF; // $xA
|
||||
PORTC = ecsdata & 0xFF; // $5y
|
||||
PORTA = (ecsdata >> 8) & 0xFF; // $xA
|
||||
PORTC = ecsdata & 0xFF; // $5y
|
||||
|
||||
DW_INT();
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
DWS_INT();
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NACT_INT();
|
||||
NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// MAPPER CODE
|
||||
//******************************************
|
||||
|
||||
void setMapper_INTV()
|
||||
{
|
||||
void setMapper_INTV() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
int b = 0;
|
||||
int i = 0;
|
||||
// Check Button Status
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||
#endif
|
||||
if (buttonVal1 == LOW) { // Button Pressed
|
||||
while (1) { // Scroll Mapper List
|
||||
if (buttonVal1 == LOW) { // Button Pressed
|
||||
while (1) { // Scroll Mapper List
|
||||
#if defined(enable_OLED)
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||
#elif defined(enable_LCD)
|
||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||
#endif
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
if (buttonVal1 == HIGH) { // Button Released
|
||||
// Correct Overshoot
|
||||
if (i == 0)
|
||||
i = intvmapcount - 1;
|
||||
@ -520,7 +539,7 @@ void setMapper_INTV()
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
|
||||
if (b == 2) { // Previous Mapper (doubleclick)
|
||||
if (b == 2) { // Previous Mapper (doubleclick)
|
||||
if (i == 0)
|
||||
i = intvmapcount - 1;
|
||||
else
|
||||
@ -542,7 +561,7 @@ void setMapper_INTV()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next Mapper (press)
|
||||
if (b == 1) { // Next Mapper (press)
|
||||
if (i == (intvmapcount - 1))
|
||||
i = 0;
|
||||
else
|
||||
@ -564,7 +583,7 @@ void setMapper_INTV()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newintvmapper = intvmapselect;
|
||||
break;
|
||||
}
|
||||
@ -613,8 +632,7 @@ void checkMapperSize_INTV() {
|
||||
}
|
||||
}
|
||||
|
||||
void setROMSize_INTV()
|
||||
{
|
||||
void setROMSize_INTV() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
if (intvlo == intvhi)
|
||||
@ -639,7 +657,7 @@ void setROMSize_INTV()
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == intvlo)
|
||||
i = intvhi;
|
||||
else
|
||||
@ -659,7 +677,7 @@ void setROMSize_INTV()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == intvhi)
|
||||
i = intvlo;
|
||||
else
|
||||
@ -678,12 +696,12 @@ void setROMSize_INTV()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newintvsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(INTV[newintvsize]);
|
||||
@ -722,8 +740,7 @@ setrom:
|
||||
intvsize = newintvsize;
|
||||
}
|
||||
|
||||
void checkStatus_INTV()
|
||||
{
|
||||
void checkStatus_INTV() {
|
||||
EEPROM_readAnything(7, intvmapper);
|
||||
EEPROM_readAnything(8, intvsize);
|
||||
if (intvmapper > 9) {
|
||||
@ -793,12 +810,10 @@ void setCart_INTV() {
|
||||
while (1) {
|
||||
if (myFile.curPosition() == 0) {
|
||||
break;
|
||||
}
|
||||
else if (myFile.peek() == '\n') {
|
||||
} else if (myFile.peek() == '\n') {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
}
|
||||
}
|
||||
@ -846,9 +861,8 @@ void setCart_INTV() {
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
}
|
||||
else {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
@ -900,12 +914,10 @@ void setCart_INTV() {
|
||||
while (1) {
|
||||
if (myFile.curPosition() == 0) {
|
||||
break;
|
||||
}
|
||||
else if (myFile.peek() == '\n') {
|
||||
} else if (myFile.peek() == '\n') {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
}
|
||||
}
|
||||
@ -950,8 +962,7 @@ void setCart_INTV() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Database file not found"), true);
|
||||
}
|
||||
}
|
||||
|
1112
Cart_Reader/MD.ino
1112
Cart_Reader/MD.ino
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1857
Cart_Reader/NES.ino
1857
Cart_Reader/NES.ino
File diff suppressed because it is too large
Load Diff
@ -6,13 +6,13 @@
|
||||
static const char ngpMenuItem1[] PROGMEM = "Read Rom";
|
||||
static const char ngpMenuItem2[] PROGMEM = "Read chip info";
|
||||
static const char ngpMenuItemReset[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsNGP[] PROGMEM = {ngpMenuItem1, ngpMenuItem2, ngpMenuItemReset};
|
||||
static const char* const menuOptionsNGP[] PROGMEM = { ngpMenuItem1, ngpMenuItem2, ngpMenuItemReset };
|
||||
|
||||
static const char ngpRomItem1[] PROGMEM = "4 Mbits / 512 KB";
|
||||
static const char ngpRomItem2[] PROGMEM = "8 Mbits / 1 MB";
|
||||
static const char ngpRomItem3[] PROGMEM = "16 Mbits / 2 MB";
|
||||
static const char ngpRomItem4[] PROGMEM = "32 Mbits / 4 MB";
|
||||
static const char* const ngpRomOptions[] PROGMEM = {ngpRomItem1, ngpRomItem2, ngpRomItem3, ngpRomItem4};
|
||||
static const char* const ngpRomOptions[] PROGMEM = { ngpRomItem1, ngpRomItem2, ngpRomItem3, ngpRomItem4 };
|
||||
|
||||
char ngpRomVersion[3];
|
||||
uint8_t ngpSystemType;
|
||||
@ -79,7 +79,7 @@ void ngpMenu() {
|
||||
}
|
||||
|
||||
bool getCartInfo_NGP() {
|
||||
uint8_t *tmp;
|
||||
uint8_t* tmp;
|
||||
|
||||
// enter autoselect mode
|
||||
dataOut();
|
||||
@ -99,13 +99,13 @@ bool getCartInfo_NGP() {
|
||||
|
||||
|
||||
switch (romSize) {
|
||||
case 0xffff: return false; break; // detection error (no cart inserted or hw problem)
|
||||
case 0x98ab: cartSize = 524288; break; // 4 Mbits - Toshiba
|
||||
case 0x204c: cartSize = 524288; break; // 4 Mbits - STMicroelectronics ?
|
||||
case 0x982c: cartSize = 1048576; break; // 8 Mbits - Toshiba
|
||||
case 0xec2c: cartSize = 1048576; break; // 8 Mbits - Samsung
|
||||
case 0x982f: cartSize = 2097152; break; // 16 Mbits - Toshiba
|
||||
case 0xec2f: cartSize = 2097152; break; // 16 Mbits - Samsung
|
||||
case 0xffff: return false; break; // detection error (no cart inserted or hw problem)
|
||||
case 0x98ab: cartSize = 524288; break; // 4 Mbits - Toshiba
|
||||
case 0x204c: cartSize = 524288; break; // 4 Mbits - STMicroelectronics ?
|
||||
case 0x982c: cartSize = 1048576; break; // 8 Mbits - Toshiba
|
||||
case 0xec2c: cartSize = 1048576; break; // 8 Mbits - Samsung
|
||||
case 0x982f: cartSize = 2097152; break; // 16 Mbits - Toshiba
|
||||
case 0xec2f: cartSize = 2097152; break; // 16 Mbits - Samsung
|
||||
}
|
||||
|
||||
// reset to read mode
|
||||
@ -123,7 +123,7 @@ bool getCartInfo_NGP() {
|
||||
snprintf(cartID, 5, "%02X%02X", readByte_NGP(0x21), readByte_NGP(0x20));
|
||||
|
||||
// force rom size to 32 Mbits for few titles
|
||||
if (strcmp(cartID, "0060") == 0 || strcmp(cartID, "0061") == 0 || strcmp(cartID, "0069") == 0 )
|
||||
if (strcmp(cartID, "0060") == 0 || strcmp(cartID, "0061") == 0 || strcmp(cartID, "0069") == 0)
|
||||
cartSize = 4194304;
|
||||
|
||||
// get app version
|
||||
@ -164,8 +164,7 @@ void printCartInfo_NGP() {
|
||||
print_Msg(F("ROM Size: "));
|
||||
if (cartSize == 0) {
|
||||
println_Msg(F("Unknown"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg((cartSize >> 17));
|
||||
println_Msg(F(" Mbits"));
|
||||
}
|
||||
@ -175,7 +174,7 @@ void printCartInfo_NGP() {
|
||||
wait();
|
||||
}
|
||||
|
||||
void readROM_NGP(char *outPathBuf, size_t bufferSize) {
|
||||
void readROM_NGP(char* outPathBuf, size_t bufferSize) {
|
||||
// Set cartsize manually if chip ID is unknown
|
||||
if (cartSize == 0) {
|
||||
unsigned char ngpRomMenu;
|
||||
@ -300,8 +299,7 @@ void scanChip_NGP() {
|
||||
myFile.println("Warning: this cart is 32Mbits. Only the first 16Mbits chip will be scanned.");
|
||||
myFile.println("");
|
||||
addrMax = 2097152;
|
||||
}
|
||||
else
|
||||
} else
|
||||
addrMax = cartSize;
|
||||
|
||||
myFile.println("Sector | Start address | Status");
|
||||
@ -309,7 +307,7 @@ void scanChip_NGP() {
|
||||
// browse sectors
|
||||
for (uint32_t addr = 0; addr < addrMax; addr += 0x1000) {
|
||||
|
||||
if ( (addr % 0x10000 == 0) || (addr == addrMax - 0x8000) || (addr == addrMax - 0x6000) || (addr == addrMax - 0x4000)) {
|
||||
if ((addr % 0x10000 == 0) || (addr == addrMax - 0x8000) || (addr == addrMax - 0x6000) || (addr == addrMax - 0x4000)) {
|
||||
|
||||
myFile.print("#" + String(sectorID) + " | 0x" + String(addr, HEX) + " | ");
|
||||
|
||||
@ -344,7 +342,8 @@ void writeByte_NGP(uint32_t addr, uint8_t data) {
|
||||
|
||||
PORTH |= data;
|
||||
PORTH |= (1 << 5);
|
||||
NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
}
|
||||
|
||||
uint8_t readByte_NGP(uint32_t addr) {
|
||||
@ -361,7 +360,9 @@ uint8_t readByte_NGP(uint32_t addr) {
|
||||
|
||||
PORTH &= ~data;
|
||||
PORTH &= ~(1 << 6);
|
||||
NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
data = PINC;
|
||||
|
||||
|
@ -42,7 +42,7 @@ void read_rom_PCE(void);
|
||||
/******************************************
|
||||
Variables
|
||||
*****************************************/
|
||||
uint8_t pce_internal_mode; //0 - HuCARD, 1 - TurboChip
|
||||
uint8_t pce_internal_mode; //0 - HuCARD, 1 - TurboChip
|
||||
|
||||
uint16_t pce_force_rom_size = 0;
|
||||
uint8_t tennokoe_bank_index = 0;
|
||||
@ -55,7 +55,7 @@ static const char pceMenuItem1[] PROGMEM = "HuCARD (swapped)";
|
||||
static const char pceMenuItem2[] PROGMEM = "HuCARD(not swapped)";
|
||||
static const char pceMenuItem3[] PROGMEM = "Turbochip";
|
||||
static const char pceMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionspce[] PROGMEM = {pceMenuItem1, pceMenuItem2, pceMenuItem3, pceMenuItem4};
|
||||
static const char *const menuOptionspce[] PROGMEM = { pceMenuItem1, pceMenuItem2, pceMenuItem3, pceMenuItem4 };
|
||||
|
||||
// PCE card menu items
|
||||
static const char pceCartMenuItem1[] = "Read ROM";
|
||||
@ -70,7 +70,7 @@ static char menuOptionspceCart[7][20];
|
||||
// Turbochip menu items
|
||||
static const char pceTCMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char pceTCMenuItem2[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionspceTC[] PROGMEM = {pceTCMenuItem1, pceTCMenuItem2};
|
||||
static const char *const menuOptionspceTC[] PROGMEM = { pceTCMenuItem1, pceTCMenuItem2 };
|
||||
|
||||
// PCE start menu
|
||||
void pcsMenu(void) {
|
||||
@ -81,8 +81,7 @@ void pcsMenu(void) {
|
||||
pceDev = question_box(F("Select device"), menuOptions, 3, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (pceDev)
|
||||
{
|
||||
switch (pceDev) {
|
||||
case 0:
|
||||
//Hucard
|
||||
display_Clear();
|
||||
@ -116,8 +115,7 @@ void pcsMenu(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void pin_read_write_PCE(void)
|
||||
{
|
||||
void pin_read_write_PCE(void) {
|
||||
// Set Address Pins to Output
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
@ -153,8 +151,7 @@ void pin_read_write_PCE(void)
|
||||
reset_cart_PCE();
|
||||
}
|
||||
|
||||
void pin_init_PCE(void)
|
||||
{
|
||||
void pin_init_PCE(void) {
|
||||
|
||||
//Set Address Pins to input and pull up
|
||||
DDRF = 0x00;
|
||||
@ -175,61 +172,67 @@ void pin_init_PCE(void)
|
||||
DDRC = 0x00;
|
||||
// Enable Internal Pullups
|
||||
PORTC = 0xFF;
|
||||
|
||||
}
|
||||
|
||||
void setup_cart_PCE(void)
|
||||
{
|
||||
void setup_cart_PCE(void) {
|
||||
// Set cicrstPin(PG1) to Output
|
||||
DDRG |= (1 << 1);
|
||||
// Output a high to disable CIC
|
||||
PORTG |= (1 << 1);
|
||||
|
||||
pin_init_PCE();
|
||||
|
||||
}
|
||||
|
||||
void reset_cart_PCE(void)
|
||||
{
|
||||
void reset_cart_PCE(void) {
|
||||
//Set RESET as Low
|
||||
PORTH &= ~(1 << 0);
|
||||
delay(200);
|
||||
//Set RESET as High
|
||||
PORTH |= (1 << 0);
|
||||
delay(200);
|
||||
|
||||
}
|
||||
|
||||
void set_address_PCE(uint32_t address)
|
||||
{
|
||||
void set_address_PCE(uint32_t address) {
|
||||
//Set address
|
||||
PORTF = address & 0xFF;
|
||||
PORTK = (address >> 8) & 0xFF;
|
||||
PORTL = (PORTL & 0xF0) | ((address >> 16) & 0x0F);
|
||||
}
|
||||
|
||||
void set_cs_rd_low_PCE ()
|
||||
{
|
||||
void set_cs_rd_low_PCE() {
|
||||
// Set CS(PL4) and RD(PH3) as LOW
|
||||
PORTL &= ~(1 << 4);
|
||||
PORTH &= ~(1 << 3);
|
||||
}
|
||||
|
||||
uint8_t read_byte_PCE(uint32_t address)
|
||||
{
|
||||
uint8_t read_byte_PCE(uint32_t address) {
|
||||
uint8_t ret;
|
||||
|
||||
set_address_PCE(address);
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
//read byte
|
||||
ret = PINC;
|
||||
|
||||
//Swap bit order for PC Engine HuCARD
|
||||
if (pce_internal_mode == HUCARD)
|
||||
{
|
||||
if (pce_internal_mode == HUCARD) {
|
||||
ret = ((ret & 0x01) << 7) | ((ret & 0x02) << 5) | ((ret & 0x04) << 3) | ((ret & 0x08) << 1) | ((ret & 0x10) >> 1) | ((ret & 0x20) >> 3) | ((ret & 0x40) >> 5) | ((ret & 0x80) >> 7);
|
||||
}
|
||||
|
||||
@ -237,12 +240,12 @@ uint8_t read_byte_PCE(uint32_t address)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void data_output_PCE () {
|
||||
void data_output_PCE() {
|
||||
// Set Data Pins (D0-D7) to Output
|
||||
DDRC = 0xFF;
|
||||
}
|
||||
|
||||
void data_input_PCE () {
|
||||
void data_input_PCE() {
|
||||
// Set Data Pins (D0-D7) to Input
|
||||
DDRC = 0x00;
|
||||
// Enable Internal Pullups
|
||||
@ -251,17 +254,30 @@ void data_input_PCE () {
|
||||
set_cs_rd_low_PCE();
|
||||
}
|
||||
|
||||
void write_byte_PCE(uint32_t address, uint8_t data)
|
||||
{
|
||||
void write_byte_PCE(uint32_t address, uint8_t data) {
|
||||
//PORTH |= (1 << 3); // RD HIGH
|
||||
set_address_PCE(address);
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
//Swap bit order for PC Engine HuCARD
|
||||
if (pce_internal_mode == HUCARD)
|
||||
{
|
||||
if (pce_internal_mode == HUCARD) {
|
||||
data = ((data & 0x01) << 7) | ((data & 0x02) << 5) | ((data & 0x04) << 3) | ((data & 0x08) << 1) | ((data & 0x10) >> 1) | ((data & 0x20) >> 3) | ((data & 0x40) >> 5) | ((data & 0x80) >> 7);
|
||||
}
|
||||
|
||||
@ -273,7 +289,22 @@ void write_byte_PCE(uint32_t address, uint8_t data)
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Set CS(PL4) and WR(PH5) as HIGH
|
||||
PORTL |= (1 << 4);
|
||||
@ -281,8 +312,7 @@ void write_byte_PCE(uint32_t address, uint8_t data)
|
||||
}
|
||||
|
||||
//Confirm the size of ROM - 128Kb, 256Kb, 384Kb, 512Kb, 768Kb or 1024Kb
|
||||
uint32_t detect_rom_size_PCE(void)
|
||||
{
|
||||
uint32_t detect_rom_size_PCE(void) {
|
||||
uint32_t rom_size;
|
||||
uint8_t read_byte;
|
||||
uint8_t current_byte;
|
||||
@ -299,8 +329,7 @@ uint32_t detect_rom_size_PCE(void)
|
||||
|
||||
//Confirm where mirror address start from(128KB, 256KB, 512KB, 768, or 1024KB)
|
||||
for (current_byte = 0; current_byte < DETECTION_SIZE; current_byte++) {
|
||||
if ((current_byte != detect_128) && (current_byte != detect_256) && (current_byte != detect_512) && (current_byte != detect_768))
|
||||
{
|
||||
if ((current_byte != detect_128) && (current_byte != detect_256) && (current_byte != detect_512) && (current_byte != detect_768)) {
|
||||
//If none matched, it is 1024KB
|
||||
break;
|
||||
}
|
||||
@ -309,38 +338,30 @@ uint32_t detect_rom_size_PCE(void)
|
||||
read_byte = read_byte_PCE(current_byte);
|
||||
|
||||
//128KB detection
|
||||
if (current_byte == detect_128)
|
||||
{
|
||||
if (read_byte_PCE(current_byte + 128UL * 1024UL) == read_byte)
|
||||
{
|
||||
if (current_byte == detect_128) {
|
||||
if (read_byte_PCE(current_byte + 128UL * 1024UL) == read_byte) {
|
||||
detect_128++;
|
||||
}
|
||||
}
|
||||
|
||||
//256KB detection
|
||||
if (current_byte == detect_256)
|
||||
{
|
||||
if (read_byte_PCE(current_byte + 256UL * 1024UL) == read_byte)
|
||||
{
|
||||
if (current_byte == detect_256) {
|
||||
if (read_byte_PCE(current_byte + 256UL * 1024UL) == read_byte) {
|
||||
detect_256++;
|
||||
}
|
||||
}
|
||||
|
||||
//512KB detection
|
||||
if (current_byte == detect_512)
|
||||
{
|
||||
if (read_byte_PCE(current_byte + 512UL * 1024UL) == read_byte)
|
||||
{
|
||||
if (current_byte == detect_512) {
|
||||
if (read_byte_PCE(current_byte + 512UL * 1024UL) == read_byte) {
|
||||
detect_512++;
|
||||
}
|
||||
}
|
||||
|
||||
//768KB detection
|
||||
read_byte = read_byte_PCE(current_byte + 512UL * 1024UL);
|
||||
if (current_byte == detect_768)
|
||||
{
|
||||
if (read_byte_PCE(current_byte + 768UL * 1024UL) == read_byte)
|
||||
{
|
||||
if (current_byte == detect_768) {
|
||||
if (read_byte_PCE(current_byte + 768UL * 1024UL) == read_byte) {
|
||||
detect_768++;
|
||||
}
|
||||
}
|
||||
@ -351,43 +372,29 @@ uint32_t detect_rom_size_PCE(void)
|
||||
//println_Msg(fileName);
|
||||
|
||||
//ROM size detection by result
|
||||
if (detect_128 == DETECTION_SIZE)
|
||||
{
|
||||
if (detect_128 == DETECTION_SIZE) {
|
||||
rom_size = 128;
|
||||
}
|
||||
else if (detect_256 == DETECTION_SIZE)
|
||||
{
|
||||
if (detect_512 == DETECTION_SIZE)
|
||||
{
|
||||
} else if (detect_256 == DETECTION_SIZE) {
|
||||
if (detect_512 == DETECTION_SIZE) {
|
||||
rom_size = 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
//rom_size = 1024;
|
||||
//Another confirmation for 384KB because 384KB hucard has data in 0x0--0x40000 and 0x80000--0xA0000(0x40000 is mirror of 0x00000)
|
||||
rom_size = 384;
|
||||
}
|
||||
}
|
||||
else if (detect_512 == DETECTION_SIZE)
|
||||
{
|
||||
} else if (detect_512 == DETECTION_SIZE) {
|
||||
rom_size = 512;
|
||||
}
|
||||
else if (detect_768 == DETECTION_SIZE)
|
||||
{
|
||||
} else if (detect_768 == DETECTION_SIZE) {
|
||||
rom_size = 768;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
rom_size = 1024;
|
||||
}
|
||||
|
||||
//If rom size is more than or equal to 512KB, detect Street fighter II'
|
||||
if (rom_size >= 512)
|
||||
{
|
||||
if (rom_size >= 512) {
|
||||
//Look for "NEC HE "
|
||||
if (read_byte_PCE(0x7FFF9) == 'N' && read_byte_PCE(0x7FFFA) == 'E' && read_byte_PCE(0x7FFFB) == 'C'
|
||||
&& read_byte_PCE(0x7FFFC) == ' ' && read_byte_PCE(0x7FFFD) == 'H' && read_byte_PCE(0x7FFFE) == 'E')
|
||||
{
|
||||
if (read_byte_PCE(0x7FFF9) == 'N' && read_byte_PCE(0x7FFFA) == 'E' && read_byte_PCE(0x7FFFB) == 'C'
|
||||
&& read_byte_PCE(0x7FFFC) == ' ' && read_byte_PCE(0x7FFFD) == 'H' && read_byte_PCE(0x7FFFE) == 'E') {
|
||||
rom_size = 2560;
|
||||
}
|
||||
}
|
||||
@ -396,8 +403,7 @@ uint32_t detect_rom_size_PCE(void)
|
||||
}
|
||||
|
||||
/* Must be address_start and address_end should be 512 byte aligned */
|
||||
void read_bank_PCE_ROM(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size, uint32_t *crcp)
|
||||
{
|
||||
void read_bank_PCE_ROM(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size, uint32_t *crcp) {
|
||||
uint32_t currByte;
|
||||
uint16_t c;
|
||||
|
||||
@ -414,29 +420,26 @@ void read_bank_PCE_ROM(uint32_t address_start, uint32_t address_end, uint32_t *p
|
||||
}
|
||||
}
|
||||
|
||||
void read_bank_PCE_RAM(uint32_t address_start, int block_index)
|
||||
{
|
||||
void read_bank_PCE_RAM(uint32_t address_start, int block_index) {
|
||||
uint32_t start = address_start + block_index * 512;
|
||||
for (uint16_t c = 0; c < 512; c++) {
|
||||
sdBuffer[c] = read_byte_PCE(start + c);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t calculate_crc32(int n, unsigned char c[], uint32_t r)
|
||||
{
|
||||
uint32_t calculate_crc32(int n, unsigned char c[], uint32_t r) {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
r ^= c[i];
|
||||
for (j = 0; j < 8; j++)
|
||||
if (r & 1) r = (r >> 1) ^ 0xEDB88320UL;
|
||||
else r >>= 1;
|
||||
else r >>= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void crc_search(char *file_p, char *folder_p, uint32_t rom_size, uint32_t crc)
|
||||
{
|
||||
void crc_search(char *file_p, char *folder_p, uint32_t rom_size, uint32_t crc) {
|
||||
FsFile rom, script;
|
||||
uint32_t r, processedsize;
|
||||
char gamename[100];
|
||||
@ -445,16 +448,14 @@ void crc_search(char *file_p, char *folder_p, uint32_t rom_size, uint32_t crc)
|
||||
flag = CHKSUM_SKIP;
|
||||
|
||||
//Open list file. If no list file found, just skip
|
||||
sd.chdir("/"); //Set read directry to root
|
||||
if (script.open("pce.txt", O_READ))
|
||||
{
|
||||
sd.chdir("/"); //Set read directry to root
|
||||
if (script.open("pce.txt", O_READ)) {
|
||||
//Calculate CRC of ROM file
|
||||
sd.chdir(folder_p);
|
||||
if (rom.open(file_p, O_READ))
|
||||
{
|
||||
if (rom.open(file_p, O_READ)) {
|
||||
//Initialize flag as error
|
||||
flag = CHKSUM_ERROR;
|
||||
crc = crc ^ 0xFFFFFFFFUL; //Finish CRC calculation and progress bar
|
||||
crc = crc ^ 0xFFFFFFFFUL; //Finish CRC calculation and progress bar
|
||||
//Display calculated CRC
|
||||
sprintf(crc_file, "%08lX", crc);
|
||||
|
||||
@ -463,11 +464,10 @@ void crc_search(char *file_p, char *folder_p, uint32_t rom_size, uint32_t crc)
|
||||
//Read 2 lines (game name and CRC)
|
||||
get_line(gamename, &script, 96);
|
||||
get_line(crc_search, &script, 9);
|
||||
skip_line(&script); //Skip every 3rd line
|
||||
skip_line(&script); //Skip every 3rd line
|
||||
|
||||
//if checksum search successful, rename the file and end search
|
||||
if (strcmp(crc_search, crc_file) == 0)
|
||||
{
|
||||
if (strcmp(crc_search, crc_file) == 0) {
|
||||
print_Msg(F("Chksum OK "));
|
||||
println_Msg(crc_file);
|
||||
print_Msg(F("Saved to "));
|
||||
@ -486,15 +486,12 @@ void crc_search(char *file_p, char *folder_p, uint32_t rom_size, uint32_t crc)
|
||||
}
|
||||
|
||||
|
||||
if (flag == CHKSUM_SKIP)
|
||||
{
|
||||
if (flag == CHKSUM_SKIP) {
|
||||
print_Msg(F("Saved to "));
|
||||
print_Msg(folder_p);
|
||||
print_Msg(F("/"));
|
||||
print_Msg(file_p);
|
||||
}
|
||||
else if (flag == CHKSUM_ERROR)
|
||||
{
|
||||
} else if (flag == CHKSUM_ERROR) {
|
||||
print_Msg(F("Chksum Error "));
|
||||
println_Msg(crc_file);
|
||||
print_Msg(F("Saved to "));
|
||||
@ -504,27 +501,23 @@ void crc_search(char *file_p, char *folder_p, uint32_t rom_size, uint32_t crc)
|
||||
}
|
||||
|
||||
script.close();
|
||||
|
||||
}
|
||||
|
||||
void unlock_tennokoe_bank_RAM()
|
||||
{
|
||||
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68
|
||||
write_byte_PCE(0x0F0000, 0x00); //Unlock RAM sequence 2 Bank 78
|
||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 3 Bank 78
|
||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
|
||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
|
||||
void unlock_tennokoe_bank_RAM() {
|
||||
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68
|
||||
write_byte_PCE(0x0F0000, 0x00); //Unlock RAM sequence 2 Bank 78
|
||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 3 Bank 78
|
||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
|
||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
|
||||
}
|
||||
|
||||
void lock_tennokoe_bank_RAM()
|
||||
{
|
||||
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
|
||||
write_byte_PCE(0x0F0001, 0x00); //Lock RAM sequence 2 Bank 78
|
||||
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
|
||||
void lock_tennokoe_bank_RAM() {
|
||||
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
|
||||
write_byte_PCE(0x0F0001, 0x00); //Lock RAM sequence 2 Bank 78
|
||||
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
|
||||
}
|
||||
|
||||
void read_tennokoe_bank_PCE(int bank_index)
|
||||
{
|
||||
void read_tennokoe_bank_PCE(int bank_index) {
|
||||
uint32_t processed_size = 0;
|
||||
uint32_t verify_loop;
|
||||
uint8_t verify_flag = 1;
|
||||
@ -599,8 +592,8 @@ void read_tennokoe_bank_PCE(int bank_index)
|
||||
}
|
||||
if (block_index == 0 && sdBuffer[2] == 0x42 && sdBuffer[3] == 0x4D) {
|
||||
if (sdBuffer[0] != 0x48 || sdBuffer[1] != 0x55) {
|
||||
sdBuffer[0] = 0x48; // H
|
||||
sdBuffer[1] = 0x55; // U
|
||||
sdBuffer[0] = 0x48; // H
|
||||
sdBuffer[1] = 0x55; // U
|
||||
println_Msg(F("Corrected header"));
|
||||
} else {
|
||||
println_Msg(F("Header is correct"));
|
||||
@ -613,11 +606,9 @@ void read_tennokoe_bank_PCE(int bank_index)
|
||||
|
||||
//Close the file:
|
||||
myFile.close();
|
||||
|
||||
}
|
||||
|
||||
void write_tennokoe_bank_PCE(int bank_index)
|
||||
{
|
||||
void write_tennokoe_bank_PCE(int bank_index) {
|
||||
//Display file Browser and wait user to select a file. Size must be 2KB.
|
||||
filePath[0] = '\0';
|
||||
sd.chdir("/");
|
||||
@ -708,14 +699,12 @@ void write_tennokoe_bank_PCE(int bank_index)
|
||||
println_Msg(F("Finished"));
|
||||
display_Update();
|
||||
wait();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"), false);
|
||||
}
|
||||
}
|
||||
|
||||
void read_rom_PCE(void)
|
||||
{
|
||||
void read_rom_PCE(void) {
|
||||
uint32_t rom_size;
|
||||
uint32_t processed_size = 0;
|
||||
|
||||
@ -762,36 +751,31 @@ void read_rom_PCE(void)
|
||||
//Initialize progress bar by setting processed size as 0
|
||||
draw_progressbar(0, rom_size * 1024UL);
|
||||
|
||||
uint32_t crc = 0xFFFFFFFFUL; //Initialize CRC
|
||||
if (rom_size == 384)
|
||||
{
|
||||
uint32_t crc = 0xFFFFFFFFUL; //Initialize CRC
|
||||
if (rom_size == 384) {
|
||||
//Read two sections. 0x000000--0x040000 and 0x080000--0x0A0000 for 384KB
|
||||
read_bank_PCE_ROM(0, 0x40000, &processed_size, rom_size * 1024UL, &crc);
|
||||
read_bank_PCE_ROM(0x80000, 0xA0000, &processed_size, rom_size * 1024UL, &crc);
|
||||
}
|
||||
else if (rom_size == 2560)
|
||||
{
|
||||
} else if (rom_size == 2560) {
|
||||
//Dump Street fighter II' Champion Edition
|
||||
read_bank_PCE_ROM(0, 0x80000, &processed_size, rom_size * 1024UL, &crc); //Read first bank
|
||||
data_output_PCE();
|
||||
write_byte_PCE(0x1FF0, 0xFF); //Display second bank
|
||||
write_byte_PCE(0x1FF0, 0xFF); //Display second bank
|
||||
data_input_PCE();
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read second bank
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read second bank
|
||||
data_output_PCE();
|
||||
write_byte_PCE(0x1FF1, 0xFF); //Display third bank
|
||||
write_byte_PCE(0x1FF1, 0xFF); //Display third bank
|
||||
data_input_PCE();
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read third bank
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read third bank
|
||||
data_output_PCE();
|
||||
write_byte_PCE(0x1FF2, 0xFF); //Display forth bank
|
||||
write_byte_PCE(0x1FF2, 0xFF); //Display forth bank
|
||||
data_input_PCE();
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read forth bank
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read forth bank
|
||||
data_output_PCE();
|
||||
write_byte_PCE(0x1FF3, 0xFF); //Display fifth bank
|
||||
write_byte_PCE(0x1FF3, 0xFF); //Display fifth bank
|
||||
data_input_PCE();
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read fifth bank
|
||||
}
|
||||
else
|
||||
{
|
||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read fifth bank
|
||||
} else {
|
||||
//Read start form 0x000000 and keep reading until end of ROM
|
||||
read_bank_PCE_ROM(0, rom_size * 1024UL, &processed_size, rom_size * 1024UL, &crc);
|
||||
}
|
||||
@ -810,8 +794,7 @@ void pceMenu() {
|
||||
// create menu with title and 7 options to choose from
|
||||
unsigned char mainMenu;
|
||||
|
||||
if (pce_internal_mode == HUCARD || pce_internal_mode == HUCARD_NOSWAP)
|
||||
{
|
||||
if (pce_internal_mode == HUCARD || pce_internal_mode == HUCARD_NOSWAP) {
|
||||
sprintf(pceCartMenuItem2, "Read RAM Bank %d", tennokoe_bank_index + 1);
|
||||
sprintf(pceCartMenuItem3, "Write RAM Bank %d", tennokoe_bank_index + 1);
|
||||
strcpy(menuOptionspceCart[0], pceCartMenuItem1);
|
||||
@ -829,8 +812,7 @@ void pceMenu() {
|
||||
mainMenu = question_box(F("PCE HuCARD menu"), menuOptionspceCart, 7, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
// Change working dir to root
|
||||
@ -862,16 +844,13 @@ void pceMenu() {
|
||||
pce_force_rom_size = 1024;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionspceTC, 2);
|
||||
mainMenu = question_box(F("TG TurboChip menu"), menuOptions, 2, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
// Change working dir to root
|
||||
|
@ -75,19 +75,23 @@
|
||||
#define NAND_1A_HIGH PORTH |= (1 << 3)
|
||||
#define NAND_1A_LOW PORTH &= ~(1 << 3)
|
||||
#define NAND_1B_HIGH PORTH |= (1 << 4)
|
||||
#define NAND_1B_LOW PORTH &= ~(1 << 4) // Built-in RAM + I/O
|
||||
#define NAND_1B_LOW PORTH &= ~(1 << 4) // Built-in RAM + I/O
|
||||
#define WE_HIGH PORTH |= (1 << 5)
|
||||
#define WE_LOW PORTH &= ~(1 << 5)
|
||||
#define OE_HIGH PORTH |= (1 << 6)
|
||||
#define OE_LOW PORTH &= ~(1 << 6)
|
||||
|
||||
#define MODE_READ DDRC = 0 // [INPUT]
|
||||
#define MODE_WRITE DDRC = 0xFF //[OUTPUT]
|
||||
#define MODE_READ DDRC = 0 // [INPUT]
|
||||
#define MODE_WRITE DDRC = 0xFF //[OUTPUT]
|
||||
|
||||
#define DATA_READ { DDRC = 0; PORTC = 0xFF; } // [INPUT PULLUP]
|
||||
#define ADDR_WRITE DDRC = 0xFF // [OUTPUT]
|
||||
#define DATA_READ \
|
||||
{ \
|
||||
DDRC = 0; \
|
||||
PORTC = 0xFF; \
|
||||
} // [INPUT PULLUP]
|
||||
#define ADDR_WRITE DDRC = 0xFF // [OUTPUT]
|
||||
|
||||
boolean multipack = 0; // Multi-Pack Cart
|
||||
boolean multipack = 0; // Multi-Pack Cart
|
||||
byte bank0;
|
||||
byte bank1;
|
||||
|
||||
@ -107,17 +111,17 @@ void setup_PCW() {
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set TIME(PJ0) to Output (UNUSED)
|
||||
DDRJ |= (1 << 0);
|
||||
DDRJ |= (1 << 0);
|
||||
|
||||
// Set Address/Data Pins AD0-AD7 (PC0-PC7) to Input
|
||||
MODE_READ; // DDRC = 0
|
||||
MODE_READ; // DDRC = 0
|
||||
|
||||
// Setting Control Pins to HIGH
|
||||
// LE(PH0) ---(PH1) 1A(PH3) 1B(PH4) WE(PH5) OE(PH6)
|
||||
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set Unused Pins HIGH
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
|
||||
// Multi-Pack Cart Check
|
||||
check_multi_PCW();
|
||||
@ -134,15 +138,13 @@ static const char pcwmenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char pcwmenuItem2[] PROGMEM = "Read SRAM";
|
||||
static const char pcwmenuItem3[] PROGMEM = "Write SRAM";
|
||||
static const char pcwmenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsPCW[] PROGMEM = {pcwmenuItem1, pcwmenuItem2, pcwmenuItem3, pcwmenuItem4};
|
||||
static const char* const menuOptionsPCW[] PROGMEM = { pcwmenuItem1, pcwmenuItem2, pcwmenuItem3, pcwmenuItem4 };
|
||||
|
||||
void pcwMenu()
|
||||
{
|
||||
void pcwMenu() {
|
||||
convertPgm(menuOptionsPCW, 4);
|
||||
uint8_t mainMenu = question_box(F(" POCKET CHALLENGE W"), menuOptions, 4, 0);
|
||||
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
// Read ROM
|
||||
sd.chdir("/");
|
||||
@ -178,8 +180,7 @@ void pcwMenu()
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("SRAM verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(writeErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
@ -215,14 +216,15 @@ unsigned char read_rom_byte_PCW(unsigned long address) {
|
||||
PORTK = (address >> 8) & 0xFF;
|
||||
// Latch Address on AD0-AD7
|
||||
ADDR_WRITE;
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
__asm__("nop\n\t""nop\n\t");
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t");
|
||||
// Read Data on AD0-AD7
|
||||
OE_LOW;
|
||||
DATA_READ;
|
||||
delayMicroseconds(5); // 3+ Microseconds for Problem Carts
|
||||
delayMicroseconds(5); // 3+ Microseconds for Problem Carts
|
||||
unsigned char data = PINC;
|
||||
OE_HIGH;
|
||||
|
||||
@ -237,18 +239,33 @@ unsigned char read_ram_byte_1A_PCW(unsigned long address) {
|
||||
PORTK = (address >> 8) & 0xFF;
|
||||
// Latch Address on AD0-AD7
|
||||
ADDR_WRITE;
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
// Read Data on AD0-AD7
|
||||
OE_LOW;
|
||||
DATA_READ;
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
unsigned char data = PINC;
|
||||
OE_HIGH;
|
||||
NAND_1A_HIGH;
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -267,18 +284,33 @@ unsigned char read_ram_byte_1B_PCW(unsigned long address) {
|
||||
PORTK = (address >> 8) & 0xFF;
|
||||
// Latch Address on AD0-AD7
|
||||
ADDR_WRITE;
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
// Read Data on AD0-AD7
|
||||
OE_LOW;
|
||||
DATA_READ;
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
unsigned char data = PINC;
|
||||
OE_HIGH;
|
||||
NAND_1B_HIGH;
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -290,13 +322,16 @@ void write_ram_byte_1A_PCW(unsigned long address, unsigned char data) {
|
||||
PORTK = (address >> 8) & 0xFF;
|
||||
// Latch Address on AD0-AD7
|
||||
ADDR_WRITE;
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
// Write Data on AD0-AD7 - WE LOW ~240-248ns
|
||||
WE_LOW;
|
||||
PORTC = data;
|
||||
__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");
|
||||
WE_HIGH;
|
||||
NAND_1A_HIGH;
|
||||
}
|
||||
@ -311,14 +346,22 @@ void write_ram_byte_1B_PCW(unsigned long address, unsigned char data) {
|
||||
PORTK = (address >> 8) & 0xFF;
|
||||
// Latch Address on AD0-AD7
|
||||
ADDR_WRITE;
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = address & 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
// Write Data on AD0-AD7 - WE LOW ~740ns
|
||||
WE_LOW;
|
||||
PORTC = data;
|
||||
__asm__("nop\n\t""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""nop\n\t");
|
||||
__asm__("nop\n\t"
|
||||
"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"
|
||||
"nop\n\t");
|
||||
WE_HIGH;
|
||||
NAND_1B_HIGH;
|
||||
}
|
||||
@ -353,18 +396,18 @@ void write_ram_byte_1B_PCW(unsigned long address, unsigned char data) {
|
||||
// MULTI-PACK CART CHECK
|
||||
void check_multi_PCW() {
|
||||
read_setup_PCW();
|
||||
byte tempbyte = read_rom_byte_PCW(0x3FFC); // Bank 0 Switch
|
||||
byte tempbyte = read_rom_byte_PCW(0x3FFC); // Bank 0 Switch
|
||||
if (tempbyte) {
|
||||
bank0 = tempbyte; // Store Bank 0 Switch
|
||||
tempbyte = read_rom_byte_PCW(0x3FFD); // Bank 1 Switch
|
||||
bank0 = tempbyte; // Store Bank 0 Switch
|
||||
tempbyte = read_rom_byte_PCW(0x3FFD); // Bank 1 Switch
|
||||
if (tempbyte) {
|
||||
bank1 = tempbyte; // Store Bank 1 Switch
|
||||
bank1 = tempbyte; // Store Bank 1 Switch
|
||||
// Check for 00s
|
||||
tempbyte = read_rom_byte_PCW(0x3FFB); // Should be 00
|
||||
tempbyte = read_rom_byte_PCW(0x3FFB); // Should be 00
|
||||
if (!tempbyte) {
|
||||
tempbyte = read_rom_byte_PCW(0x3FFF); // Should be 00
|
||||
tempbyte = read_rom_byte_PCW(0x3FFF); // Should be 00
|
||||
if (!tempbyte)
|
||||
multipack = 1; // Flag Multi-Cart
|
||||
multipack = 1; // Flag Multi-Cart
|
||||
else {
|
||||
bank0 = 0;
|
||||
bank1 = 0;
|
||||
@ -380,26 +423,33 @@ void write_bank_byte_PCW(unsigned char data) {
|
||||
NAND_1B_LOW;
|
||||
// Write to Address 0xFFFF
|
||||
PORTL = 0x00;
|
||||
PORTK = 0xFF; // A8-A15
|
||||
PORTK = 0xFF; // A8-A15
|
||||
// Latch Address on AD0-AD7
|
||||
ADDR_WRITE;
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
LE_HIGH; // Latch Enable
|
||||
PORTC = 0xFF; // A0-A7
|
||||
LE_LOW; // Address Latched
|
||||
// Write Data on AD0-AD7 - WE LOW ~728-736ns
|
||||
WE_LOW;
|
||||
PORTC = data;
|
||||
__asm__("nop\n\t""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""nop\n\t");
|
||||
__asm__("nop\n\t"
|
||||
"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"
|
||||
"nop\n\t");
|
||||
WE_HIGH;
|
||||
NAND_1B_HIGH;
|
||||
}
|
||||
|
||||
void switchBank_PCW(int bank) {
|
||||
if (bank == 1) { // Upper Half
|
||||
if (bank == 1) { // Upper Half
|
||||
write_bank_byte_PCW(bank1);
|
||||
}
|
||||
else { // Lower Half (default)
|
||||
} else { // Lower Half (default)
|
||||
write_bank_byte_PCW(bank0);
|
||||
}
|
||||
}
|
||||
@ -430,7 +480,7 @@ void readROM_PCW() {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
read_setup_PCW();
|
||||
for (unsigned long address = 0; address < 0x400000; address += 512) { // 4MB
|
||||
for (unsigned long address = 0; address < 0x400000; address += 512) { // 4MB
|
||||
for (unsigned int x = 0; x < 512; x++) {
|
||||
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
||||
}
|
||||
@ -478,7 +528,7 @@ void readMultiROM_PCW() {
|
||||
read_setup_PCW();
|
||||
// Lower Half
|
||||
switchBank_PCW(0);
|
||||
for (unsigned long address = 0; address < 0x200000; address += 512) { // 2MB
|
||||
for (unsigned long address = 0; address < 0x200000; address += 512) { // 2MB
|
||||
for (unsigned int x = 0; x < 512; x++) {
|
||||
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
||||
}
|
||||
@ -487,7 +537,7 @@ void readMultiROM_PCW() {
|
||||
read_setup_PCW();
|
||||
// Upper Half
|
||||
switchBank_PCW(1);
|
||||
for (unsigned long address = 0x200000; address < 0x400000; address += 512) { // 2MB
|
||||
for (unsigned long address = 0x200000; address < 0x400000; address += 512) { // 2MB
|
||||
for (unsigned int x = 0; x < 512; x++) {
|
||||
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
||||
}
|
||||
@ -513,7 +563,7 @@ void readMultiROM_PCW() {
|
||||
// SRAM
|
||||
//******************************************
|
||||
|
||||
void readSRAM_PCW() { // readSRAM_1A()
|
||||
void readSRAM_PCW() { // readSRAM_1A()
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".srm");
|
||||
|
||||
@ -530,7 +580,7 @@ void readSRAM_PCW() { // readSRAM_1A()
|
||||
}
|
||||
display_Clear();
|
||||
read_setup_PCW();
|
||||
for (unsigned long address = 0x0; address < 0x8000; address += 512) { // 32K
|
||||
for (unsigned long address = 0x0; address < 0x8000; address += 512) { // 32K
|
||||
for (unsigned int x = 0; x < 512; x++) {
|
||||
sdBuffer[x] = read_ram_byte_1A_PCW(address + x);
|
||||
}
|
||||
@ -563,7 +613,7 @@ void writeSRAM_PCW() {
|
||||
//open file on sd card
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
read_setup_PCW();
|
||||
for (unsigned int address = 0x0; address < 0x8000; address += 512) { // 32K
|
||||
for (unsigned int address = 0x0; address < 0x8000; address += 512) { // 32K
|
||||
myFile.read(sdBuffer, 512);
|
||||
for (unsigned int x = 0; x < 512; x++) {
|
||||
write_ram_byte_1A_PCW(address + x, sdBuffer[x]);
|
||||
@ -572,12 +622,10 @@ void writeSRAM_PCW() {
|
||||
myFile.close();
|
||||
println_Msg(F("Done"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
display_Clear();
|
||||
@ -588,7 +636,7 @@ unsigned long verifySRAM_PCW() {
|
||||
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
read_setup_PCW();
|
||||
for (unsigned int address = 0x0; address < 0x8000; address += 512) { // 32K
|
||||
for (unsigned int address = 0x0; address < 0x8000; address += 512) { // 32K
|
||||
for (unsigned int x = 0; x < 512; x++) {
|
||||
byte myByte = read_ram_byte_1A_PCW(address + x);
|
||||
sdBuffer[x] = myByte;
|
||||
@ -600,8 +648,7 @@ unsigned long verifySRAM_PCW() {
|
||||
}
|
||||
}
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ boolean hirom[8];
|
||||
static const char sfmMenuItem1[] PROGMEM = "Game Menu";
|
||||
static const char sfmMenuItem2[] PROGMEM = "Flash Menu";
|
||||
static const char sfmMenuItem3[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsSFM[] PROGMEM = {sfmMenuItem1, sfmMenuItem2, sfmMenuItem3};
|
||||
static const char* const menuOptionsSFM[] PROGMEM = { sfmMenuItem1, sfmMenuItem2, sfmMenuItem3 };
|
||||
|
||||
// SFM flash menu items
|
||||
static const char sfmFlashMenuItem1[] PROGMEM = "Read Flash";
|
||||
@ -44,7 +44,7 @@ static const char sfmFlashMenuItem3[] PROGMEM = "Print Mapping";
|
||||
static const char sfmFlashMenuItem4[] PROGMEM = "Read Mapping";
|
||||
static const char sfmFlashMenuItem5[] PROGMEM = "Write Mapping";
|
||||
static const char sfmFlashMenuItem6[] PROGMEM = "Back";
|
||||
static const char* const menuOptionsSFMFlash[] PROGMEM = {sfmFlashMenuItem1, sfmFlashMenuItem2, sfmFlashMenuItem3, sfmFlashMenuItem4, sfmFlashMenuItem5, sfmFlashMenuItem6};
|
||||
static const char* const menuOptionsSFMFlash[] PROGMEM = { sfmFlashMenuItem1, sfmFlashMenuItem2, sfmFlashMenuItem3, sfmFlashMenuItem4, sfmFlashMenuItem5, sfmFlashMenuItem6 };
|
||||
|
||||
// SFM game menu items
|
||||
static const char sfmGameMenuItem1[] PROGMEM = "Read Sram";
|
||||
@ -52,7 +52,7 @@ static const char sfmGameMenuItem2[] PROGMEM = "Read Game";
|
||||
static const char sfmGameMenuItem3[] PROGMEM = "Write Sram";
|
||||
static const char sfmGameMenuItem4[] PROGMEM = "Switch Game";
|
||||
static const char sfmGameMenuItem5[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsSFMGame[] PROGMEM = {sfmGameMenuItem1, sfmGameMenuItem2, sfmGameMenuItem3, sfmGameMenuItem4, sfmGameMenuItem5};
|
||||
static const char* const menuOptionsSFMGame[] PROGMEM = { sfmGameMenuItem1, sfmGameMenuItem2, sfmGameMenuItem3, sfmGameMenuItem4, sfmGameMenuItem5 };
|
||||
|
||||
void sfmMenu() {
|
||||
// create menu with title and 3 options to choose from
|
||||
@ -62,8 +62,7 @@ void sfmMenu() {
|
||||
mainMenu = question_box(F("SF Memory"), menuOptions, 3, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
// Game menu
|
||||
case 0:
|
||||
sfmGameMenu();
|
||||
@ -127,8 +126,7 @@ void sfmGameMenu() {
|
||||
// Print info
|
||||
getCartInfo_SFM();
|
||||
mode = mode_SFM_Game;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// No menu so switch to only game
|
||||
// Switch to game
|
||||
send_SFM(0x80);
|
||||
@ -141,8 +139,7 @@ void sfmGameMenu() {
|
||||
getCartInfo_SFM();
|
||||
mode = mode_SFM_Game;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Switch to HiRom failed"), false);
|
||||
}
|
||||
}
|
||||
@ -155,8 +152,7 @@ void sfmGameOptions() {
|
||||
gameSubMenu = question_box(F("SFM Game Menu"), menuOptions, 5, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (gameSubMenu)
|
||||
{
|
||||
switch (gameSubMenu) {
|
||||
// Read sram
|
||||
case 0:
|
||||
display_Clear();
|
||||
@ -185,8 +181,7 @@ void sfmGameOptions() {
|
||||
if (wrErrors == 0) {
|
||||
println_Msg(F("Verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(wrErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
@ -221,8 +216,7 @@ void sfmFlashMenu() {
|
||||
flashSubMenu = question_box(F("SFM Flash Menu"), menuOptions, 6, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (flashSubMenu)
|
||||
{
|
||||
switch (flashSubMenu) {
|
||||
// Read Flash
|
||||
case 0:
|
||||
// Clear screen
|
||||
@ -258,8 +252,7 @@ void sfmFlashMenu() {
|
||||
|
||||
// Read flash
|
||||
readFlash_SFM();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Switch to HiRom failed"), false);
|
||||
}
|
||||
break;
|
||||
@ -328,16 +321,13 @@ void sfmFlashMenu() {
|
||||
printMapping();
|
||||
resetFlash_SFM(0xC0);
|
||||
resetFlash_SFM(0xE0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Wrong Flash ID"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Wrong Flash ID"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("failed"), false);
|
||||
}
|
||||
break;
|
||||
@ -368,16 +358,13 @@ void sfmFlashMenu() {
|
||||
readMapping();
|
||||
resetFlash_SFM(0xC0);
|
||||
resetFlash_SFM(0xE0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Wrong Flash ID"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Wrong Flash ID"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("failed"), false);
|
||||
}
|
||||
break;
|
||||
@ -410,8 +397,7 @@ void sfmFlashMenu() {
|
||||
if (blankcheckMapping_SFM()) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Nope"));
|
||||
break;
|
||||
}
|
||||
@ -458,7 +444,7 @@ void getGames() {
|
||||
controlIn_SFM();
|
||||
|
||||
// Check if menu is present
|
||||
byte menuString[] = {0x4D, 0x45, 0x4E, 0x55, 0x20, 0x50, 0x52, 0x4F, 0x47, 0x52, 0x41, 0x4D};
|
||||
byte menuString[] = { 0x4D, 0x45, 0x4E, 0x55, 0x20, 0x50, 0x52, 0x4F, 0x47, 0x52, 0x41, 0x4D };
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (menuString[i] != readBank_SFM(0xC0, 0x7FC0 + i)) {
|
||||
hasMenu = false;
|
||||
@ -468,7 +454,7 @@ void getGames() {
|
||||
if (hasMenu) {
|
||||
// Count number of games
|
||||
for (word i = 0x0000; i < 0xE000; i += 0x2000) {
|
||||
if (readBank_SFM(0xC6, i) == numGames )
|
||||
if (readBank_SFM(0xC6, i) == numGames)
|
||||
numGames++;
|
||||
}
|
||||
|
||||
@ -482,11 +468,9 @@ void getGames() {
|
||||
//check if hirom
|
||||
if (readBank_SFM(gameAddress[i], 0xFFD5) == 0x31) {
|
||||
hirom[i] = true;
|
||||
}
|
||||
else if (readBank_SFM(gameAddress[i], 0xFFD5) == 0x21) {
|
||||
} else if (readBank_SFM(gameAddress[i], 0xFFD5) == 0x21) {
|
||||
hirom[i] = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
hirom[i] = false;
|
||||
}
|
||||
|
||||
@ -510,13 +494,11 @@ void getGames() {
|
||||
// End char array in case game code is less than 9 chars
|
||||
gameCode[i][myLength] = '\0';
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//check if hirom
|
||||
if (readBank_SFM(0xC0, 0xFFD5) == 0x31) {
|
||||
hirom[0] = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
hirom[0] = false;
|
||||
}
|
||||
|
||||
@ -537,8 +519,7 @@ void getGames() {
|
||||
gameSize[0] = 1;
|
||||
while (romSizeExp--)
|
||||
gameSize[0] *= 2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gameVersion[0] = readBank_SFM(0xC0, 0x7FDB);
|
||||
gameCode[0][0] = 'G';
|
||||
gameCode[0][1] = 'A';
|
||||
@ -674,19 +655,56 @@ void writeBank_SFM(byte myBank, word myAddress, byte 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""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WR(PH5) to LOW
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
// Leave WR low for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WR(PH5) to HIGH
|
||||
PORTH |= (1 << 5);
|
||||
|
||||
// Leave WR high for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
}
|
||||
|
||||
// Read one byte of data from a location specified by bank and address, 00:0000
|
||||
@ -696,7 +714,22 @@ byte readBank_SFM(byte myBank, word myAddress) {
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Read
|
||||
byte tempByte = PINC;
|
||||
@ -781,10 +814,9 @@ boolean checkcart_SFM() {
|
||||
|
||||
romType = readBank_SFM(0, 0xFFD5);
|
||||
if ((romType >> 5) != 1) { // Detect invalid romType byte due to too long ROM name (22 chars)
|
||||
romType = 0; // LoROM // Krusty's Super Fun House (U) 1.0 & Contra 3 (U)
|
||||
}
|
||||
else {
|
||||
romType &= 1; // Must be LoROM or HiROM
|
||||
romType = 0; // LoROM // Krusty's Super Fun House (U) 1.0 & Contra 3 (U)
|
||||
} else {
|
||||
romType &= 1; // Must be LoROM or HiROM
|
||||
}
|
||||
|
||||
// Check RomSize
|
||||
@ -846,8 +878,7 @@ boolean checkcart_SFM() {
|
||||
sramSize = 1;
|
||||
while (sramSizeExp--)
|
||||
sramSize *= 2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sramSize = 0;
|
||||
}
|
||||
|
||||
@ -855,11 +886,10 @@ boolean checkcart_SFM() {
|
||||
romVersion = readBank_SFM(0, 65499);
|
||||
|
||||
// Test if checksum is equal to reverse checksum
|
||||
if (((word(readBank_SFM(0, 65500)) + (word(readBank_SFM(0, 65501)) * 256)) + (word(readBank_SFM(0, 65502)) + (word(readBank_SFM(0, 65503)) * 256))) == 65535 ) {
|
||||
if (((word(readBank_SFM(0, 65500)) + (word(readBank_SFM(0, 65501)) * 256)) + (word(readBank_SFM(0, 65502)) + (word(readBank_SFM(0, 65503)) * 256))) == 65535) {
|
||||
if (strcmp("0000", checksumStr) == 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -953,8 +983,7 @@ void resetFlash_SFM(int startBank) {
|
||||
writeBank_SFM(startBank, 0x5555L * 2, 0xaa);
|
||||
writeBank_SFM(startBank, 0x2AAAL * 2, 0x55);
|
||||
writeBank_SFM(startBank, 0x5555L * 2, 0xf0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
||||
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xf0);
|
||||
@ -981,8 +1010,7 @@ void idFlash_SFM(int startBank) {
|
||||
|
||||
// Read the two id bytes into a string
|
||||
sprintf(flashid, "%x%x", readBank_SFM(startBank, 0x00), readBank_SFM(startBank, 0x02));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
||||
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0x90);
|
||||
@ -1042,8 +1070,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) {
|
||||
busyCheck_SFM(startBank);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Write lorom
|
||||
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 128) {
|
||||
@ -1070,8 +1097,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) {
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg("");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Can't open file on SD"), true);
|
||||
}
|
||||
}
|
||||
@ -1126,8 +1152,7 @@ void eraseFlash_SFM(int startBank) {
|
||||
writeBank_SFM(startBank, 0x5555L * 2, 0xaa);
|
||||
writeBank_SFM(startBank, 0x2AAAL * 2, 0x55);
|
||||
writeBank_SFM(startBank, 0x5555L * 2, 0x10);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
||||
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0x80);
|
||||
@ -1153,13 +1178,12 @@ byte blankcheck_SFM(int startBank) {
|
||||
for (int currBank = startBank; currBank < startBank + numBanks; currBank++) {
|
||||
for (unsigned long currByte = 0; currByte < 0x10000; currByte++) {
|
||||
if (readBank_SFM(currBank, currByte) != 0xFF) {
|
||||
currBank = startBank + numBanks;
|
||||
currBank = startBank + numBanks;
|
||||
blank = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte++) {
|
||||
if (readBank_SFM(currBank, currByte) != 0xFF) {
|
||||
@ -1174,7 +1198,7 @@ byte blankcheck_SFM(int startBank) {
|
||||
|
||||
// Check if a write succeeded, returns 0 if all is ok and number of errors if not
|
||||
unsigned long verifyFlash_SFM(int startBank, uint32_t pos) {
|
||||
unsigned long verified = 0;
|
||||
unsigned long verified = 0;
|
||||
|
||||
// Open file on sd card
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
@ -1199,8 +1223,7 @@ unsigned long verifyFlash_SFM(int startBank, uint32_t pos) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 512) {
|
||||
// Fill SDBuffer
|
||||
@ -1215,8 +1238,7 @@ unsigned long verifyFlash_SFM(int startBank, uint32_t pos) {
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// SD Error
|
||||
verified = 999999;
|
||||
print_Error(F("Can't open file on SD"), false);
|
||||
@ -1250,8 +1272,7 @@ void readFlash_SFM() {
|
||||
myFile.write(sdBuffer, 512);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 512) {
|
||||
for (int c = 0; c < 512; c++) {
|
||||
@ -1320,7 +1341,7 @@ void printMapping() {
|
||||
|
||||
for (int currByte = 0xFF00; currByte < 0xFF50; currByte += 10) {
|
||||
for (int c = 0; c < 10; c++) {
|
||||
itoa (readBank_SFM(0xC0, currByte + c), buffer, 16);
|
||||
itoa(readBank_SFM(0xC0, currByte + c), buffer, 16);
|
||||
for (int i = 0; i < 2 - strlen(buffer); i++) {
|
||||
print_Msg(F("0"));
|
||||
}
|
||||
@ -1469,12 +1490,10 @@ void eraseMapping(byte startBank) {
|
||||
// Switch to read
|
||||
dataIn();
|
||||
controlIn_SFM();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Wrong Flash ID"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Unlock failed"), true);
|
||||
}
|
||||
}
|
||||
@ -1599,20 +1618,17 @@ void writeMapping_SFM(byte startBank, uint32_t pos) {
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg("");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Can't open file on SD"), false);
|
||||
}
|
||||
|
||||
// Switch to read
|
||||
dataIn();
|
||||
controlIn_SFM();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Wrong Flash ID"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Unlock failed"), true);
|
||||
}
|
||||
}
|
||||
@ -1636,14 +1652,12 @@ boolean unlockHirom() {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("failed"));
|
||||
display_Update();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("failed"));
|
||||
display_Update();
|
||||
return 0;
|
||||
@ -1709,8 +1723,7 @@ void write_SFM(int startBank, uint32_t pos) {
|
||||
if (blankcheck_SFM(startBank)) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("Nope"));
|
||||
display_Clear();
|
||||
print_Msg(F("Erasing..."));
|
||||
@ -1723,8 +1736,7 @@ void write_SFM(int startBank, uint32_t pos) {
|
||||
if (blankcheck_SFM(startBank)) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Could not erase flash"), true);
|
||||
}
|
||||
}
|
||||
@ -1741,19 +1753,16 @@ void write_SFM(int startBank, uint32_t pos) {
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(writeErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
print_Error(F("did not verify."), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Error: Wrong Flash ID"), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Unlock failed"), true);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ static const char SMSAdapterItem2[] PROGMEM = "SG-1000 raphnet";
|
||||
static const char SMSAdapterItem3[] PROGMEM = "SMS Retrode";
|
||||
static const char SMSAdapterItem4[] PROGMEM = "GG Retrode";
|
||||
static const char SMSAdapterItem5[] PROGMEM = "GG Retron 3in1";
|
||||
static const char* const menuAdapterSMS[] PROGMEM = {SMSAdapterItem1, SMSAdapterItem2, SMSAdapterItem3, SMSAdapterItem4, SMSAdapterItem5};
|
||||
static const char* const menuAdapterSMS[] PROGMEM = { SMSAdapterItem1, SMSAdapterItem2, SMSAdapterItem3, SMSAdapterItem4, SMSAdapterItem5 };
|
||||
|
||||
// MD menu items
|
||||
static const char SMSMenuItem1[] PROGMEM = "Read Rom";
|
||||
@ -20,7 +20,7 @@ static const char SMSMenuItem2[] PROGMEM = "Read from SRAM";
|
||||
static const char SMSMenuItem3[] PROGMEM = "Write to SRAM";
|
||||
static const char SMSMenuItem4[] PROGMEM = "Reset";
|
||||
static const char SMSMenuItem5[] PROGMEM = "Change Retrode Mode";
|
||||
static const char* const menuOptionsSMS[] PROGMEM = {SMSMenuItem1, SMSMenuItem2, SMSMenuItem3, SMSMenuItem4, SMSMenuItem5};
|
||||
static const char* const menuOptionsSMS[] PROGMEM = { SMSMenuItem1, SMSMenuItem2, SMSMenuItem3, SMSMenuItem4, SMSMenuItem5 };
|
||||
|
||||
// Rom Size menu
|
||||
static const char SMSRomItem1[] PROGMEM = "8KB";
|
||||
@ -30,12 +30,12 @@ static const char SMSRomItem4[] PROGMEM = "32KB";
|
||||
static const char SMSRomItem5[] PROGMEM = "40KB";
|
||||
static const char SMSRomItem6[] PROGMEM = "48KB";
|
||||
static const char SMSRomItem7[] PROGMEM = "512KB";
|
||||
static const char* const romOptionsSMS[] PROGMEM = {SMSRomItem1, SMSRomItem2, SMSRomItem3, SMSRomItem4, SMSRomItem5, SMSRomItem6, SMSRomItem7};
|
||||
static const char* const romOptionsSMS[] PROGMEM = { SMSRomItem1, SMSRomItem2, SMSRomItem3, SMSRomItem4, SMSRomItem5, SMSRomItem6, SMSRomItem7 };
|
||||
|
||||
// Set retrode_mode to true when using a retrode SMS/GG adapter
|
||||
static bool retrode_mode = false;
|
||||
static bool retrode_mode_sms = false; // true: SMS/Mark3 false: GG
|
||||
static bool raphnet_mode_sg1000 = false; // true: SG-1000 false: SMS/Mark3
|
||||
static bool retrode_mode_sms = false; // true: SMS/Mark3 false: GG
|
||||
static bool raphnet_mode_sg1000 = false; // true: SG-1000 false: SMS/Mark3
|
||||
static bool retron_mode = false;
|
||||
|
||||
|
||||
@ -48,21 +48,18 @@ void _smsMenu() {
|
||||
int noptions = sizeof(menuOptionsSMS) / sizeof(menuOptionsSMS[0]);
|
||||
convertPgm(menuOptionsSMS, noptions);
|
||||
mainMenu = question_box(retrode_mode ? (retrode_mode_sms ? F("Retrode:SMS") : F("Retrode:GG")) : F("SMS/GG Retrode:NO"), menuOptions, noptions, 0);
|
||||
}
|
||||
else if (retron_mode) {
|
||||
} else if (retron_mode) {
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsSMS, 4);
|
||||
mainMenu = question_box(F("Game Gear"), menuOptions, 4, 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsSMS, (raphnet_mode_sg1000 ? 1 : 4));
|
||||
mainMenu = question_box((raphnet_mode_sg1000 ? F("SG-1000") : F("SMS/Mark III") ), menuOptions, (raphnet_mode_sg1000 ? 1 : 4), 0);
|
||||
convertPgm(menuOptionsSMS, (raphnet_mode_sg1000 ? 1 : 4));
|
||||
mainMenu = question_box((raphnet_mode_sg1000 ? F("SG-1000") : F("SMS/Mark III")), menuOptions, (raphnet_mode_sg1000 ? 1 : 4), 0);
|
||||
}
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
display_Clear();
|
||||
mode = mode_SMS;
|
||||
@ -72,8 +69,7 @@ void _smsMenu() {
|
||||
readROM_SMS();
|
||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||
compareCRC("gg.txt", 0, 1, 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
compareCRC("sms.txt", 0, 1, 0);
|
||||
}
|
||||
#ifdef global_log
|
||||
@ -117,8 +113,7 @@ void _smsMenu() {
|
||||
if (retrode_mode) {
|
||||
println_Msg(retrode_mode ? (retrode_mode_sms ? F("Retrode Mode SMS") : F("Retrode Mode GG")) : F("Retrode Mode Off"));
|
||||
println_Msg(F("Press Button..."));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Press Button..."));
|
||||
}
|
||||
@ -134,8 +129,7 @@ void smsMenu() {
|
||||
SMSAdapterMenu = question_box(F("Select System/Adapter"), menuOptions, 5, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (SMSAdapterMenu)
|
||||
{
|
||||
switch (SMSAdapterMenu) {
|
||||
case 0:
|
||||
// raphnet SMS/Mark3
|
||||
retrode_mode = false;
|
||||
@ -267,7 +261,10 @@ void writeByte_SMS(word myAddress, byte 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");
|
||||
__asm__("nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
if (retrode_mode) {
|
||||
// Switch WR(PL5) and OE/CE(PH6) to LOW
|
||||
@ -280,7 +277,10 @@ void writeByte_SMS(word myAddress, byte myData) {
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
if (retrode_mode) {
|
||||
// Switch WR(PL5) and OE/CE(PH6) to HIGH
|
||||
@ -293,7 +293,10 @@ void writeByte_SMS(word myAddress, byte myData) {
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
if (retrode_mode && !retrode_mode_sms) {
|
||||
// Set Data Pins (D8-D15) to Input
|
||||
@ -321,7 +324,10 @@ byte readByte_SMS(word myAddress) {
|
||||
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");
|
||||
|
||||
if (retrode_mode) {
|
||||
// Switch RD(PL6) and OE(PH6) to LOW
|
||||
@ -333,7 +339,10 @@ byte readByte_SMS(word myAddress) {
|
||||
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
|
||||
byte tempByte = (retrode_mode && !retrode_mode_sms) ? PINA : PINC;
|
||||
@ -348,7 +357,10 @@ byte readByte_SMS(word myAddress) {
|
||||
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");
|
||||
|
||||
return tempByte;
|
||||
}
|
||||
@ -372,38 +384,38 @@ void getCartInfo_SMS() {
|
||||
switch (readNibble(readByte_SMS(0x7fff), 0)) {
|
||||
case 0xa:
|
||||
// Adding UL gets rid of integer overflow compiler warning
|
||||
cartSize = 8 * 1024UL;
|
||||
cartSize = 8 * 1024UL;
|
||||
break;
|
||||
case 0xb:
|
||||
cartSize = 16 * 1024UL;
|
||||
cartSize = 16 * 1024UL;
|
||||
break;
|
||||
case 0xc:
|
||||
cartSize = 32 * 1024UL;
|
||||
cartSize = 32 * 1024UL;
|
||||
break;
|
||||
case 0xd:
|
||||
cartSize = 48 * 1024UL;
|
||||
cartSize = 48 * 1024UL;
|
||||
break;
|
||||
case 0xe:
|
||||
cartSize = 64 * 1024UL;
|
||||
cartSize = 64 * 1024UL;
|
||||
break;
|
||||
case 0xf:
|
||||
cartSize = 128 * 1024UL;
|
||||
cartSize = 128 * 1024UL;
|
||||
break;
|
||||
case 0x0:
|
||||
cartSize = 256 * 1024UL;
|
||||
cartSize = 256 * 1024UL;
|
||||
break;
|
||||
case 0x1:
|
||||
cartSize = 512 * 1024UL;
|
||||
cartSize = 512 * 1024UL;
|
||||
break;
|
||||
case 0x2:
|
||||
cartSize = 512 * 1024UL;
|
||||
cartSize = 512 * 1024UL;
|
||||
break;
|
||||
case 0x3:
|
||||
// 0x3 is (only?) used in The Pro Yakyuu '91 (Game Gear)
|
||||
cartSize = 128 * 1024UL;
|
||||
cartSize = 128 * 1024UL;
|
||||
break;
|
||||
default:
|
||||
cartSize = 48 * 1024UL;
|
||||
cartSize = 48 * 1024UL;
|
||||
|
||||
// LED Error
|
||||
setColor_RGB(0, 0, 255);
|
||||
@ -455,7 +467,7 @@ void getCartInfo_SMS() {
|
||||
|
||||
if (strcmp(headerFZ, "COPYRIGHT SEGAPRG. BY T.ASAI") == 0) {
|
||||
strcpy(romName, "TMR SEGA");
|
||||
cartSize = 128 * 1024UL;
|
||||
cartSize = 128 * 1024UL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -464,45 +476,44 @@ void getCartInfo_SMS() {
|
||||
// Set cartsize manually
|
||||
unsigned char SMSRomMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(romOptionsSMS, (raphnet_mode_sg1000 ? 4 : 7));
|
||||
SMSRomMenu = question_box(F("Select ROM size"), menuOptions, (raphnet_mode_sg1000 ? 4 : 7), 0);
|
||||
convertPgm(romOptionsSMS, (raphnet_mode_sg1000 ? 4 : 7));
|
||||
SMSRomMenu = question_box(F("Select ROM size"), menuOptions, (raphnet_mode_sg1000 ? 4 : 7), 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (SMSRomMenu)
|
||||
{
|
||||
switch (SMSRomMenu) {
|
||||
case 0:
|
||||
// 8KB
|
||||
cartSize = 8 * 1024UL;
|
||||
cartSize = 8 * 1024UL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// 16KB
|
||||
cartSize = 16 * 1024UL;
|
||||
cartSize = 16 * 1024UL;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// 24KB
|
||||
cartSize = 24 * 1024UL;
|
||||
cartSize = 24 * 1024UL;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// 32KB
|
||||
cartSize = 32 * 1024UL;
|
||||
cartSize = 32 * 1024UL;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// 40KB
|
||||
cartSize = 40 * 1024UL;
|
||||
cartSize = 40 * 1024UL;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// 48KB
|
||||
cartSize = 48 * 1024UL;
|
||||
cartSize = 48 * 1024UL;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// 512KB
|
||||
cartSize = 512 * 1024UL;
|
||||
cartSize = 512 * 1024UL;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -523,8 +534,7 @@ void getCartInfo_SMS() {
|
||||
display_Clear();
|
||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||
println_Msg(F("GG Header Info"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
println_Msg(F("SMS Header Info"));
|
||||
}
|
||||
println_Msg(F(" "));
|
||||
@ -552,8 +562,7 @@ void readROM_SMS() {
|
||||
strcpy(fileName, romName);
|
||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||
strcat(fileName, ".gg");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
strcat(fileName, ".sms");
|
||||
}
|
||||
|
||||
@ -561,8 +570,7 @@ void readROM_SMS() {
|
||||
EEPROM_readAnything(0, foldern);
|
||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||
sprintf(folder, "GG/ROM/%s/%d", romName, foldern);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sprintf(folder, "SMS/ROM/%s/%d", romName, foldern);
|
||||
}
|
||||
sd.mkdir(folder, true);
|
||||
@ -609,7 +617,7 @@ void readROM_SMS() {
|
||||
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
|
||||
// Fill SD buffer
|
||||
for (int currByte = 0; currByte < 512; currByte++) {
|
||||
sdBuffer[currByte] = readByte_SMS((raphnet_mode_sg1000 || (cartSize == 32 * 1024UL) ? 0 : 0x8000) + currBuffer + currByte);
|
||||
sdBuffer[currByte] = readByte_SMS((raphnet_mode_sg1000 || (cartSize == 32 * 1024UL) ? 0 : 0x8000) + currBuffer + currByte);
|
||||
}
|
||||
// hexdump for debugging:
|
||||
// if (currBank == 0 && currBuffer == 0) {
|
||||
@ -647,8 +655,7 @@ void readSRAM_SMS() {
|
||||
EEPROM_readAnything(0, foldern);
|
||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||
sprintf(folder, "GG/SAVE/%s/%d", romName, foldern);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sprintf(folder, "SMS/SAVE/%s/%d", romName, foldern);
|
||||
}
|
||||
sd.mkdir(folder, true);
|
||||
@ -694,8 +701,7 @@ void writeSRAM_SMS() {
|
||||
|
||||
if (false) {
|
||||
print_Error(F("DISABLED"), false);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fileBrowser(F("Select file"));
|
||||
|
||||
sd.chdir();
|
||||
@ -736,16 +742,15 @@ void writeSRAM_SMS() {
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("DONE"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("SD ERROR"), true);
|
||||
}
|
||||
}
|
||||
|
||||
display_Clear();
|
||||
|
||||
sd.chdir(); // root
|
||||
filePath[0] = '\0'; // Reset filePath
|
||||
sd.chdir(); // root
|
||||
filePath[0] = '\0'; // Reset filePath
|
||||
}
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ extern void draw_progressbar(uint32_t processedsize, uint32_t totalsize);
|
||||
//void svMenu();
|
||||
void readROM_SV();
|
||||
//void setup_SV();
|
||||
void writeROM_SV (void);
|
||||
void writeROM_SV(void);
|
||||
void eraseCheck_SV(void);
|
||||
void supplyCheck_SV(void);
|
||||
void writeCheck_SV(void);
|
||||
@ -38,7 +38,7 @@ static const char svFlashMenuItem2[] PROGMEM = "Write Memory Pack";
|
||||
static const char svFlashMenuItem3[] PROGMEM = "Read BS-X Sram";
|
||||
static const char svFlashMenuItem4[] PROGMEM = "Write BS-X Sram";
|
||||
static const char svFlashMenuItem5[] PROGMEM = "Back";
|
||||
static const char* const menuOptionsSVFlash[] PROGMEM = {svFlashMenuItem1, svFlashMenuItem2, svFlashMenuItem3, svFlashMenuItem4, svFlashMenuItem5};
|
||||
static const char* const menuOptionsSVFlash[] PROGMEM = { svFlashMenuItem1, svFlashMenuItem2, svFlashMenuItem3, svFlashMenuItem4, svFlashMenuItem5 };
|
||||
|
||||
|
||||
void svMenu() {
|
||||
@ -49,8 +49,7 @@ void svMenu() {
|
||||
mainMenu = question_box(F("Satellaview 8M Memory"), menuOptions, 5, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
// Read memory pack
|
||||
case 0:
|
||||
// Change working dir to root
|
||||
@ -82,8 +81,7 @@ void svMenu() {
|
||||
if (wrErrors == 0) {
|
||||
println_Msg(F("Verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(wrErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
@ -181,7 +179,7 @@ void setup_SV() {
|
||||
//PORTJ &= ~(1 << 0);
|
||||
|
||||
// Start CIC by outputting a low signal to cicrstPin(PG1)
|
||||
PORTG &= ~(1 << 1);
|
||||
PORTG &= ~(1 << 1);
|
||||
|
||||
// Wait for CIC reset
|
||||
delay(1000);
|
||||
@ -199,19 +197,56 @@ void writeBank_SV(byte myBank, word myAddress, byte 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""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WR(PH5) to LOW
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
// Leave WR low for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Switch WR(PH5) to HIGH
|
||||
PORTH |= (1 << 5);
|
||||
|
||||
// Leave WR high for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
}
|
||||
|
||||
// Read one byte of data from a location specified by bank and address, 00:0000
|
||||
@ -221,7 +256,22 @@ byte readBank_SV(byte myBank, word myAddress) {
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Read
|
||||
byte tempByte = PINC;
|
||||
@ -231,7 +281,7 @@ byte readBank_SV(byte myBank, word myAddress) {
|
||||
/******************************************
|
||||
SatellaView BS-X Sram functions
|
||||
*****************************************/
|
||||
void readSRAM_SV () {
|
||||
void readSRAM_SV() {
|
||||
// set control
|
||||
controlIn_SNES();
|
||||
|
||||
@ -254,7 +304,7 @@ void readSRAM_SV () {
|
||||
}
|
||||
int sramBanks = 0;
|
||||
|
||||
readBank_SV(0x10, 0); // Preconfigure to fix corrupt 1st byte
|
||||
readBank_SV(0x10, 0); // Preconfigure to fix corrupt 1st byte
|
||||
// Sram size
|
||||
long lastByte = (long(sramSize) * 0x80);
|
||||
|
||||
@ -325,8 +375,7 @@ void writeSRAM_SV() {
|
||||
println_Msg("");
|
||||
println_Msg(F("SRAM writing finished"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("File doesnt exist"), false);
|
||||
}
|
||||
}
|
||||
@ -361,8 +410,7 @@ unsigned long verifySRAM_SV() {
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
return writeErrors;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Can't open file"), false);
|
||||
}
|
||||
}
|
||||
@ -412,7 +460,7 @@ void readROM_SV() {
|
||||
myFile.write(sdBuffer, 512);
|
||||
}
|
||||
}
|
||||
draw_progressbar(0x100000, 0x100000); //Finish drawing progress bar
|
||||
draw_progressbar(0x100000, 0x100000); //Finish drawing progress bar
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
@ -421,15 +469,14 @@ void readROM_SV() {
|
||||
wait();
|
||||
}
|
||||
|
||||
void writeROM_SV (void) {
|
||||
void writeROM_SV(void) {
|
||||
// Get Checksum as string to make sure that BS-X cart is inserted
|
||||
dataIn();
|
||||
controlIn_SNES();
|
||||
sprintf(checksumStr, "%02X%02X", readBank_SV(0, 65503), readBank_SV(0, 65502));
|
||||
|
||||
//if CRC is not 8B86, BS-X cart is not inserted. Display error and reset
|
||||
if (strcmp("8B86", checksumStr) != 0)
|
||||
{
|
||||
if (strcmp("8B86", checksumStr) != 0) {
|
||||
display_Clear();
|
||||
print_Error(F("Error: Must use BS-X cart"), true);
|
||||
}
|
||||
@ -457,8 +504,8 @@ void writeROM_SV (void) {
|
||||
//Disable 8M memory pack write protection
|
||||
dataOut();
|
||||
controlOut_SNES();
|
||||
writeBank_SV(0x0C, 0x5000, 0x80); //Modify write enable register
|
||||
writeBank_SV(0x0E, 0x5000, 0x80); //Commit register modification
|
||||
writeBank_SV(0x0C, 0x5000, 0x80); //Modify write enable register
|
||||
writeBank_SV(0x0E, 0x5000, 0x80); //Commit register modification
|
||||
|
||||
//Erase memory pack
|
||||
println_Msg(F("Erasing pack..."));
|
||||
@ -474,8 +521,7 @@ void writeROM_SV (void) {
|
||||
for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
|
||||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
||||
if (0xFF != readBank_SV(currBank, currByte))
|
||||
{
|
||||
if (0xFF != readBank_SV(currBank, currByte)) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Erase failed"));
|
||||
display_Update();
|
||||
@ -496,30 +542,29 @@ void writeROM_SV (void) {
|
||||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
||||
|
||||
writeBank_SV(0xC0, 0x0000, 0x10); //Program Byte
|
||||
writeBank_SV(0xC0, 0x0000, 0x10); //Program Byte
|
||||
writeBank_SV(currBank, currByte, myFile.read());
|
||||
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
||||
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
||||
writeCheck_SV();
|
||||
}
|
||||
}
|
||||
|
||||
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
||||
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
||||
writeCheck_SV();
|
||||
writeBank_SV(0xC0, 0x0000, 0xFF); //Terminate write
|
||||
writeBank_SV(0xC0, 0x0000, 0xFF); //Terminate write
|
||||
draw_progressbar(0x100000, 0x100000);
|
||||
|
||||
|
||||
//Verify
|
||||
dataIn(); //Set pins to input
|
||||
dataIn(); //Set pins to input
|
||||
controlIn_SNES();
|
||||
myFile.seekSet(0); // Go back to file beginning
|
||||
myFile.seekSet(0); // Go back to file beginning
|
||||
println_Msg(F("Verifying..."));
|
||||
display_Update();
|
||||
for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
|
||||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
||||
if (myFile.read() != readBank_SV(currBank, currByte))
|
||||
{
|
||||
if (myFile.read() != readBank_SV(currBank, currByte)) {
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Verify failed"));
|
||||
display_Update();
|
||||
@ -537,8 +582,7 @@ void writeROM_SV (void) {
|
||||
display_Update();
|
||||
wait();
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"), false);
|
||||
}
|
||||
}
|
||||
@ -553,15 +597,25 @@ void eraseCheck_SV(void) {
|
||||
|
||||
// CE or OE must be toggled with each subsequent status read or the
|
||||
// completion of a program or erase operation will not be evident.
|
||||
while ((ret & 0x80) == 0x00) { //Wait until X.bit7 = 1
|
||||
while ((ret & 0x80) == 0x00) { //Wait until X.bit7 = 1
|
||||
controlOut_SNES();
|
||||
// Switch CS(PH3) High
|
||||
PORTH |= (1 << 3);
|
||||
// Leave CE high for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
controlIn_SNES();
|
||||
// Leave CE low for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
// Read register
|
||||
ret = readBank_SV(0xC0, 0x0004);
|
||||
}
|
||||
@ -580,15 +634,25 @@ void supplyCheck_SV(void) {
|
||||
|
||||
// CE or OE must be toggled with each subsequent status read or the
|
||||
// completion of a program or erase operation will not be evident.
|
||||
while ((ret & 0x08) == 0x08) { //Wait until X.bit3 = 0
|
||||
while ((ret & 0x08) == 0x08) { //Wait until X.bit3 = 0
|
||||
controlOut_SNES();
|
||||
// Switch CS(PH3) High
|
||||
PORTH |= (1 << 3);
|
||||
// Leave CE high for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
controlIn_SNES();
|
||||
// Leave CE low for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
// Read register
|
||||
ret = readBank_SV(0xC0, 0x0004);
|
||||
}
|
||||
@ -612,10 +676,20 @@ void writeCheck_SV(void) {
|
||||
// Switch CS(PH3) High
|
||||
PORTH |= (1 << 3);
|
||||
// Leave CE high for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
controlIn_SNES();
|
||||
// Leave CE low for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
// Read register
|
||||
ret = readBank_SV(0xC0, 0x0000);
|
||||
}
|
||||
@ -638,8 +712,7 @@ void detectCheck_SV(void) {
|
||||
// completion of a program or erase operation will not be evident.
|
||||
while ((ret & 0x80) == 0x00) {
|
||||
i++;
|
||||
if ( i > 10000)
|
||||
{
|
||||
if (i > 10000) {
|
||||
//timeout
|
||||
break;
|
||||
}
|
||||
@ -647,10 +720,20 @@ void detectCheck_SV(void) {
|
||||
// Switch CS(PH3) High
|
||||
PORTH |= (1 << 3);
|
||||
// Leave CE high for at least 60ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
controlIn_SNES();
|
||||
// Leave CE low for at least 50ns
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
// Read register
|
||||
ret = readBank_SV(0xC0, 0x0002);
|
||||
}
|
||||
@ -660,18 +743,17 @@ void detectCheck_SV(void) {
|
||||
}
|
||||
|
||||
|
||||
void eraseAll_SV(void)
|
||||
{
|
||||
void eraseAll_SV(void) {
|
||||
dataOut();
|
||||
controlOut_SNES();
|
||||
writeBank_SV(0xC0, 0x0000, 0x50); //Clear Status Registers
|
||||
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
||||
writeBank_SV(0xC0, 0x0000, 0x50); //Clear Status Registers
|
||||
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
||||
supplyCheck_SV();
|
||||
writeBank_SV(0xC0, 0x0000, 0xA7); //Chip Erase
|
||||
writeBank_SV(0xC0, 0x0000, 0xD0); //Confirm
|
||||
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
||||
writeBank_SV(0xC0, 0x0000, 0xA7); //Chip Erase
|
||||
writeBank_SV(0xC0, 0x0000, 0xD0); //Confirm
|
||||
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
||||
eraseCheck_SV();
|
||||
writeBank_SV(0xC0, 0x0000, 0xFF); //Teriminate
|
||||
writeBank_SV(0xC0, 0x0000, 0xFF); //Teriminate
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -55,8 +55,7 @@
|
||||
// SETUP
|
||||
//******************************************
|
||||
|
||||
void setup_VBOY()
|
||||
{
|
||||
void setup_VBOY() {
|
||||
// Set Address Pins to Output
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
@ -70,7 +69,7 @@ void setup_VBOY()
|
||||
DDRH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||
|
||||
// Set TIME(PJ0) to Output (UNUSED)
|
||||
DDRJ |= (1 << 0);
|
||||
DDRJ |= (1 << 0);
|
||||
|
||||
// Set Pins (D0-D15) to Input
|
||||
DDRC = 0x00;
|
||||
@ -83,7 +82,7 @@ void setup_VBOY()
|
||||
PORTH &= ~(1 << 0);
|
||||
|
||||
// Set Unused Pins HIGH
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
|
||||
getCartInfo_VB();
|
||||
|
||||
@ -99,15 +98,13 @@ static const char vboyMenuItem1[] PROGMEM = "Read ROM";
|
||||
static const char vboyMenuItem2[] PROGMEM = "Read SRAM";
|
||||
static const char vboyMenuItem3[] PROGMEM = "Write SRAM";
|
||||
static const char vboyMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsVBOY[] PROGMEM = {vboyMenuItem1, vboyMenuItem2, vboyMenuItem3, vboyMenuItem4};
|
||||
static const char* const menuOptionsVBOY[] PROGMEM = { vboyMenuItem1, vboyMenuItem2, vboyMenuItem3, vboyMenuItem4 };
|
||||
|
||||
void vboyMenu()
|
||||
{
|
||||
void vboyMenu() {
|
||||
convertPgm(menuOptionsVBOY, 4);
|
||||
uint8_t mainMenu = question_box(F("VIRTUALBOY MENU"), menuOptions, 4, 0);
|
||||
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
// Read ROM
|
||||
sd.chdir("/");
|
||||
@ -124,8 +121,7 @@ void vboyMenu()
|
||||
display_Update();
|
||||
readSRAM_VB();
|
||||
sd.chdir("/");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Cart has no SRAM"), false);
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
@ -148,15 +144,13 @@ void vboyMenu()
|
||||
if (writeErrors == 0) {
|
||||
println_Msg(F("SRAM verified OK"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(writeErrors);
|
||||
println_Msg(F(" bytes "));
|
||||
print_Error(F("did not verify."), false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Cart has no SRAM"), false);
|
||||
}
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
@ -192,12 +186,22 @@ void writeByte_VB(unsigned long myAddress, byte myData) {
|
||||
// Set /CS1(PH4), /WE0(PH5) to LOW
|
||||
PORTH &= ~(1 << 4) & ~(1 << 5);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Set CS2(PH0), /CS1(PH4), /WE0(PH5) to HIGH
|
||||
PORTH |= (1 << 0) | (1 << 4) | (1 << 5);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
}
|
||||
|
||||
word readWord_VB(unsigned long myAddress) {
|
||||
@ -212,21 +216,31 @@ word readWord_VB(unsigned long myAddress) {
|
||||
// Set /CE(PH3), /OE(PH6) to LOW
|
||||
PORTH &= ~(1 << 3) & ~(1 << 6);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
|
||||
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF);
|
||||
|
||||
// Set /CE(PH3), /OE(PH6) to HIGH
|
||||
PORTH |= (1 << 3) | (1 << 6);
|
||||
// Setting CS2(PH0) LOW
|
||||
PORTH &= ~(1 << 0);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
return tempWord;
|
||||
}
|
||||
|
||||
byte readByte_VB(unsigned long myAddress) { // SRAM BYTE
|
||||
byte readByte_VB(unsigned long myAddress) { // SRAM BYTE
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
PORTL = (myAddress >> 16) & 0xFF;
|
||||
@ -238,18 +252,33 @@ byte readByte_VB(unsigned long myAddress) { // SRAM BYTE
|
||||
// Set /CS1(PH4), /OE(PH6) to LOW
|
||||
PORTH &= ~(1 << 4) & ~(1 << 6);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
byte tempByte = PINA;
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
// Set /CS1(PH4), /OE(PH6) to HIGH
|
||||
PORTH |= (1 << 3) | (1 << 6);
|
||||
// Setting CS2(PH0) LOW
|
||||
PORTH &= ~(1 << 0);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""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"
|
||||
"nop\n\t"
|
||||
"nop\n\t");
|
||||
|
||||
return tempByte;
|
||||
}
|
||||
@ -277,52 +306,51 @@ void getCartInfo_VB() {
|
||||
cartSize = 0;
|
||||
for (unsigned long address = 0x80000; address <= 0x400000; address *= 2) {
|
||||
// Get Serial
|
||||
word vbSerial = readWord_VB((address - 0x204) / 2); // Cart Serial
|
||||
word vbSerial = readWord_VB((address - 0x204) / 2); // Cart Serial
|
||||
|
||||
switch (vbSerial)
|
||||
{
|
||||
case 0x4D54: // MT = Mario's Tennis
|
||||
case 0x4832: // H2 = Panic Bomber/Tobidase! Panibomb
|
||||
case 0x5350: // SP = Space Invaders
|
||||
case 0x5353: // SS = Space Squash
|
||||
case 0x5452: // TR = V-Tetris
|
||||
cartSize = 0x80000; // 512KB
|
||||
switch (vbSerial) {
|
||||
case 0x4D54: // MT = Mario's Tennis
|
||||
case 0x4832: // H2 = Panic Bomber/Tobidase! Panibomb
|
||||
case 0x5350: // SP = Space Invaders
|
||||
case 0x5353: // SS = Space Squash
|
||||
case 0x5452: // TR = V-Tetris
|
||||
cartSize = 0x80000; // 512KB
|
||||
break;
|
||||
|
||||
case 0x494D: // IM = Insmouse no Yakata
|
||||
case 0x4A42: // JB = Jack Bros.
|
||||
case 0x4D43: // MC = Mario Clash
|
||||
case 0x5245: // RE = Red Alarm
|
||||
case 0x4833: // H3 = Vertical Force
|
||||
case 0x5642: // VB = Virtual Bowling
|
||||
case 0x5646: // VF = Virtual Fishing
|
||||
case 0x4A56: // JV = Virtual Lab
|
||||
case 0x5650: // VP = Virtual League Baseball/Virtual Pro Yakyuu '95
|
||||
cartSize = 0x100000; // 1MB
|
||||
case 0x494D: // IM = Insmouse no Yakata
|
||||
case 0x4A42: // JB = Jack Bros.
|
||||
case 0x4D43: // MC = Mario Clash
|
||||
case 0x5245: // RE = Red Alarm
|
||||
case 0x4833: // H3 = Vertical Force
|
||||
case 0x5642: // VB = Virtual Bowling
|
||||
case 0x5646: // VF = Virtual Fishing
|
||||
case 0x4A56: // JV = Virtual Lab
|
||||
case 0x5650: // VP = Virtual League Baseball/Virtual Pro Yakyuu '95
|
||||
cartSize = 0x100000; // 1MB
|
||||
break;
|
||||
|
||||
case 0x5042: // PB = 3-D Tetris
|
||||
case 0x4750: // GP = Galactic Pinball
|
||||
case 0x5344: // SD = SD Gundam Dimension War
|
||||
case 0x5442: // TB = Teleroboxer
|
||||
cartSize = 0x100000; // 1MB
|
||||
sramSize = 0x2000; // 8KB
|
||||
case 0x5042: // PB = 3-D Tetris
|
||||
case 0x4750: // GP = Galactic Pinball
|
||||
case 0x5344: // SD = SD Gundam Dimension War
|
||||
case 0x5442: // TB = Teleroboxer
|
||||
cartSize = 0x100000; // 1MB
|
||||
sramSize = 0x2000; // 8KB
|
||||
break;
|
||||
|
||||
case 0x5647: // VG = Golf/T&E Virtual Golf
|
||||
case 0x4E46: // NF = Nester's Funky Bowling
|
||||
case 0x5745: // WE = Waterworld
|
||||
cartSize = 0x200000; // 2MB
|
||||
case 0x5647: // VG = Golf/T&E Virtual Golf
|
||||
case 0x4E46: // NF = Nester's Funky Bowling
|
||||
case 0x5745: // WE = Waterworld
|
||||
cartSize = 0x200000; // 2MB
|
||||
break;
|
||||
|
||||
case 0x5743: // WC = Virtual Boy Wario Land
|
||||
cartSize = 0x200000; // 2MB
|
||||
sramSize = 0x2000; // 8KB
|
||||
case 0x5743: // WC = Virtual Boy Wario Land
|
||||
cartSize = 0x200000; // 2MB
|
||||
sramSize = 0x2000; // 8KB
|
||||
break;
|
||||
|
||||
case 0x4644: // FD = Hyper Fighting
|
||||
cartSize = 0x400000; // 4MB
|
||||
sramSize = 0x2000; // 8KB
|
||||
case 0x4644: // FD = Hyper Fighting
|
||||
cartSize = 0x400000; // 4MB
|
||||
sramSize = 0x2000; // 8KB
|
||||
break;
|
||||
}
|
||||
|
||||
@ -355,14 +383,13 @@ void getCartInfo_VB() {
|
||||
print_Msg(F("Name: "));
|
||||
println_Msg(romName);
|
||||
print_Msg(F("Size: "));
|
||||
print_Msg(cartSize * 8 / 1024 / 1024 );
|
||||
print_Msg(cartSize * 8 / 1024 / 1024);
|
||||
println_Msg(F(" MBit"));
|
||||
print_Msg(F("Sram: "));
|
||||
if (sramSize > 0) {
|
||||
print_Msg(sramSize * 8 / 1024);
|
||||
println_Msg(F(" KBit"));
|
||||
}
|
||||
else
|
||||
} else
|
||||
println_Msg(F("None"));
|
||||
println_Msg(F(" "));
|
||||
|
||||
@ -413,20 +440,19 @@ void readROM_VB() {
|
||||
for (int currWord = 0; currWord < 256; currWord++) {
|
||||
word myWord = readWord_VB(currBuffer + currWord);
|
||||
// Split word into two bytes
|
||||
sdBuffer[d] = (( myWord >> 8 ) & 0xFF);
|
||||
sdBuffer[d] = ((myWord >> 8) & 0xFF);
|
||||
sdBuffer[d + 1] = (myWord & 0xFF);
|
||||
d += 2;
|
||||
}
|
||||
myFile.write(sdBuffer, 512);
|
||||
d = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 256) {
|
||||
for (int currWord = 0; currWord < 256; currWord++) {
|
||||
word myWord = readWord_VB(currBuffer + currWord);
|
||||
// Split word into two bytes
|
||||
sdBuffer[d] = (( myWord >> 8 ) & 0xFF);
|
||||
sdBuffer[d] = ((myWord >> 8) & 0xFF);
|
||||
sdBuffer[d + 1] = (myWord & 0xFF);
|
||||
d += 2;
|
||||
}
|
||||
@ -469,8 +495,7 @@ void writeSRAM_VB() {
|
||||
myFile.close();
|
||||
println_Msg(F("Done"));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
dataIn_VB();
|
||||
@ -524,8 +549,7 @@ unsigned long verifySRAM_VB() {
|
||||
}
|
||||
}
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ static const char wsMenuItem2[] PROGMEM = "Read Save";
|
||||
static const char wsMenuItem3[] PROGMEM = "Write Save";
|
||||
static const char wsMenuItem4[] PROGMEM = "Reset";
|
||||
static const char wsMenuItem5[] PROGMEM = "Write WitchOS";
|
||||
static const char* const menuOptionsWS[] PROGMEM = {wsMenuItem1, wsMenuItem2, wsMenuItem3, wsMenuItem4, wsMenuItem5};
|
||||
static const char *const menuOptionsWS[] PROGMEM = { wsMenuItem1, wsMenuItem2, wsMenuItem3, wsMenuItem4, wsMenuItem5 };
|
||||
|
||||
static const uint8_t wwLaunchCode[] PROGMEM = { 0xea, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xff, 0xff };
|
||||
|
||||
@ -47,8 +47,7 @@ static uint16_t wsGameChecksum = 0;
|
||||
static uint8_t wsEepromShiftReg[2];
|
||||
static boolean wsWitch = false;
|
||||
|
||||
void setup_WS()
|
||||
{
|
||||
void setup_WS() {
|
||||
// A-1 - A6
|
||||
DDRF = 0xff;
|
||||
// A7 - A14
|
||||
@ -88,8 +87,7 @@ void setup_WS()
|
||||
|
||||
do {
|
||||
unlockMMC2003_WS();
|
||||
}
|
||||
while (!headerCheck());
|
||||
} while (!headerCheck());
|
||||
|
||||
getCartInfo_WS();
|
||||
|
||||
@ -100,18 +98,18 @@ boolean headerCheck() {
|
||||
dataIn_WS();
|
||||
|
||||
for (uint32_t i = 0; i < 16; i += 2)
|
||||
* ((uint16_t*)(sdBuffer + i)) = readWord_WS(0xffff0 + i);
|
||||
*((uint16_t *)(sdBuffer + i)) = readWord_WS(0xffff0 + i);
|
||||
|
||||
uint8_t startByte = sdBuffer[0];
|
||||
if (startByte == 0xEA) { // Start should be 0xEA
|
||||
if (startByte == 0xEA) { // Start should be 0xEA
|
||||
uint8_t zeroByte = sdBuffer[5];
|
||||
if (zeroByte == 0) { // Zero Byte
|
||||
if (zeroByte == 0) { // Zero Byte
|
||||
uint8_t systemByte = sdBuffer[7];
|
||||
if (systemByte < 2) { // System < 2
|
||||
if (systemByte < 2) { // System < 2
|
||||
uint8_t revisionByte = sdBuffer[9];
|
||||
if ((revisionByte < 7) || (revisionByte == 0x80)) { // Known Revisions: 0 to 6 and 0x80
|
||||
if ((revisionByte < 7) || (revisionByte == 0x80)) { // Known Revisions: 0 to 6 and 0x80
|
||||
uint8_t sizeByte = sdBuffer[10];
|
||||
if (sizeByte < 10) // Rom Size < 10
|
||||
if (sizeByte < 10) // Rom Size < 10
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -120,15 +118,13 @@ boolean headerCheck() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void wsMenu()
|
||||
{
|
||||
void wsMenu() {
|
||||
uint8_t mainMenu = (wsWitch ? 5 : 4);
|
||||
|
||||
convertPgm(menuOptionsWS, mainMenu);
|
||||
mainMenu = question_box(F("WS Menu"), menuOptions, mainMenu, 0);
|
||||
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
{
|
||||
// Read Rom
|
||||
@ -142,8 +138,7 @@ void wsMenu()
|
||||
{
|
||||
// Read Save
|
||||
sd.chdir("/");
|
||||
switch (saveType)
|
||||
{
|
||||
switch (saveType) {
|
||||
case 0: println_Msg(F("No save for this game")); break;
|
||||
case 1: readSRAM_WS(); break;
|
||||
case 2: readEEPROM_WS(); break;
|
||||
@ -156,8 +151,7 @@ void wsMenu()
|
||||
{
|
||||
// Write Save
|
||||
sd.chdir("/");
|
||||
switch (saveType)
|
||||
{
|
||||
switch (saveType) {
|
||||
case 0: println_Msg(F("No save for this game")); break;
|
||||
case 1:
|
||||
{
|
||||
@ -184,7 +178,7 @@ void wsMenu()
|
||||
default:
|
||||
{
|
||||
// reset
|
||||
asm volatile (" jmp 0");
|
||||
asm volatile(" jmp 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -196,20 +190,18 @@ void wsMenu()
|
||||
wait();
|
||||
}
|
||||
|
||||
uint8_t getCartInfo_WS()
|
||||
{
|
||||
uint8_t getCartInfo_WS() {
|
||||
dataIn_WS();
|
||||
|
||||
// for (uint32_t i = 0; i < 16; i += 2)
|
||||
// *((uint16_t*)(sdBuffer + i)) = readWord_WS(0xffff0 + i);
|
||||
|
||||
wsGameChecksum = *(uint16_t*)(sdBuffer + 14);
|
||||
wsGameChecksum = *(uint16_t *)(sdBuffer + 14);
|
||||
wsWitch = false;
|
||||
|
||||
// some game has wrong info in header
|
||||
// patch here
|
||||
switch (wsGameChecksum)
|
||||
{
|
||||
switch (wsGameChecksum) {
|
||||
// games with wrong save type/size
|
||||
// 256kbits sram
|
||||
case 0xe600: // BAN007
|
||||
@ -247,11 +239,9 @@ uint8_t getCartInfo_WS()
|
||||
{
|
||||
// developerId/cartId/checksum are all filled with 0x00 in witch based games
|
||||
dataIn_WS();
|
||||
if (readWord_WS(0xf0000) == 0x4c45 && readWord_WS(0xf0002) == 0x5349 && readWord_WS(0xf0004) == 0x0041)
|
||||
{
|
||||
if (readWord_WS(0xf0000) == 0x4c45 && readWord_WS(0xf0002) == 0x5349 && readWord_WS(0xf0004) == 0x0041) {
|
||||
// check witch BIOS
|
||||
if (readWord_WS(0xfff5e) == 0x006c && readWord_WS(0xfff60) == 0x5b1b)
|
||||
{
|
||||
if (readWord_WS(0xfff5e) == 0x006c && readWord_WS(0xfff60) == 0x5b1b) {
|
||||
// check flashchip
|
||||
// should be a MBM29DL400TC
|
||||
dataOut_WS();
|
||||
@ -272,39 +262,30 @@ uint8_t getCartInfo_WS()
|
||||
sdBuffer[8] = 0x03;
|
||||
}
|
||||
// check service menu
|
||||
else if (readWord_WS(0xfff22) == 0x006c && readWord_WS(0xfff24) == 0x5b1b)
|
||||
{
|
||||
if (readWord_WS(0x93246) == 0x4a2f && readWord_WS(0x93248) == 0x5353 && readWord_WS(0x9324a) == 0x2e32)
|
||||
{
|
||||
else if (readWord_WS(0xfff22) == 0x006c && readWord_WS(0xfff24) == 0x5b1b) {
|
||||
if (readWord_WS(0x93246) == 0x4a2f && readWord_WS(0x93248) == 0x5353 && readWord_WS(0x9324a) == 0x2e32) {
|
||||
// jss2
|
||||
sdBuffer[6] = 0xff; // WWGP
|
||||
sdBuffer[8] = 0x1a; // 2001A
|
||||
sdBuffer[7] = 0x01; // color only
|
||||
sdBuffer[6] = 0xff; // WWGP
|
||||
sdBuffer[8] = 0x1a; // 2001A
|
||||
sdBuffer[7] = 0x01; // color only
|
||||
|
||||
if (readWord_WS(0x93e9c) == 0x4648 && readWord_WS(0x93e9e) == 0x0050)
|
||||
{
|
||||
if (readWord_WS(0x93e9c) == 0x4648 && readWord_WS(0x93e9e) == 0x0050) {
|
||||
// WWGP2001A3 -> HFP Version
|
||||
sdBuffer[9] = 0x03;
|
||||
wsGameChecksum = 0x4870;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// TODO check other jss2 version
|
||||
}
|
||||
}
|
||||
else if (readWord_WS(0xe4260) == 0x6b64 && readWord_WS(0xe4262) == 0x696e)
|
||||
{
|
||||
} else if (readWord_WS(0xe4260) == 0x6b64 && readWord_WS(0xe4262) == 0x696e) {
|
||||
// dknight
|
||||
sdBuffer[6] = 0xff; // WWGP
|
||||
sdBuffer[8] = 0x2b; // 2002B
|
||||
sdBuffer[7] = 0x01; // color only
|
||||
sdBuffer[6] = 0xff; // WWGP
|
||||
sdBuffer[8] = 0x2b; // 2002B
|
||||
sdBuffer[7] = 0x01; // color only
|
||||
sdBuffer[9] = 0x00;
|
||||
wsGameChecksum = 0x8b1c;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sdBuffer[6] == 0x2a && sdBuffer[8] == 0x01 && sdBuffer[9] == 0x01)
|
||||
{
|
||||
} else if (sdBuffer[6] == 0x2a && sdBuffer[8] == 0x01 && sdBuffer[9] == 0x01) {
|
||||
// Mobile WonderGate v1.1, checksum is filled with 0x0000
|
||||
wsGameChecksum = 0x1da0;
|
||||
}
|
||||
@ -313,7 +294,7 @@ uint8_t getCartInfo_WS()
|
||||
}
|
||||
}
|
||||
|
||||
romType = (sdBuffer[7] & 0x01); // wsc only = 1
|
||||
romType = (sdBuffer[7] & 0x01); // wsc only = 1
|
||||
romVersion = sdBuffer[9];
|
||||
romSize = sdBuffer[10];
|
||||
sramSize = sdBuffer[11];
|
||||
@ -325,8 +306,7 @@ uint8_t getCartInfo_WS()
|
||||
snprintf(checksumStr, 5, "%04X", wsGameChecksum);
|
||||
snprintf(romName, 17, "%s%s", vendorID, cartID);
|
||||
|
||||
switch (romSize)
|
||||
{
|
||||
switch (romSize) {
|
||||
case 0x01: cartSize = 131072 * 2; break;
|
||||
case 0x02: cartSize = 131072 * 4; break;
|
||||
case 0x03: cartSize = 131072 * 8; break;
|
||||
@ -339,17 +319,43 @@ uint8_t getCartInfo_WS()
|
||||
default: cartSize = 0; break;
|
||||
}
|
||||
|
||||
switch (sramSize)
|
||||
{
|
||||
case 0x00: saveType = 0; sramSize = 0; break;
|
||||
case 0x01: saveType = 1; sramSize = 64; break;
|
||||
case 0x02: saveType = 1; sramSize = 256; break;
|
||||
case 0x03: saveType = 1; sramSize = 1024; break;
|
||||
case 0x04: saveType = 1; sramSize = 2048; break;
|
||||
case 0x05: saveType = 1; sramSize = 4096; break;
|
||||
case 0x10: saveType = 2; sramSize = 1; break;
|
||||
case 0x20: saveType = 2; sramSize = 16; break;
|
||||
case 0x50: saveType = 2; sramSize = 8; break;
|
||||
switch (sramSize) {
|
||||
case 0x00:
|
||||
saveType = 0;
|
||||
sramSize = 0;
|
||||
break;
|
||||
case 0x01:
|
||||
saveType = 1;
|
||||
sramSize = 64;
|
||||
break;
|
||||
case 0x02:
|
||||
saveType = 1;
|
||||
sramSize = 256;
|
||||
break;
|
||||
case 0x03:
|
||||
saveType = 1;
|
||||
sramSize = 1024;
|
||||
break;
|
||||
case 0x04:
|
||||
saveType = 1;
|
||||
sramSize = 2048;
|
||||
break;
|
||||
case 0x05:
|
||||
saveType = 1;
|
||||
sramSize = 4096;
|
||||
break;
|
||||
case 0x10:
|
||||
saveType = 2;
|
||||
sramSize = 1;
|
||||
break;
|
||||
case 0x20:
|
||||
saveType = 2;
|
||||
sramSize = 16;
|
||||
break;
|
||||
case 0x50:
|
||||
saveType = 2;
|
||||
sramSize = 8;
|
||||
break;
|
||||
default: saveType = 0xff; break;
|
||||
}
|
||||
|
||||
@ -360,8 +366,7 @@ uint8_t getCartInfo_WS()
|
||||
return sdBuffer[0];
|
||||
}
|
||||
|
||||
void showCartInfo_WS()
|
||||
{
|
||||
void showCartInfo_WS() {
|
||||
display_Clear();
|
||||
|
||||
println_Msg(F("WS Cart Info"));
|
||||
@ -372,18 +377,24 @@ void showCartInfo_WS()
|
||||
print_Msg(F("Rom Size: "));
|
||||
if (cartSize == 0x00)
|
||||
println_Msg(romSize, HEX);
|
||||
else
|
||||
{
|
||||
else {
|
||||
print_Msg((cartSize >> 17));
|
||||
println_Msg(F(" Mb"));
|
||||
}
|
||||
|
||||
print_Msg(F("Save: "));
|
||||
switch (saveType)
|
||||
{
|
||||
switch (saveType) {
|
||||
case 0: println_Msg(F("None")); break;
|
||||
case 1: print_Msg(F("Sram ")); print_Msg(sramSize); println_Msg(F(" Kb")); break;
|
||||
case 2: print_Msg(F("Eeprom ")); print_Msg(sramSize); println_Msg(F(" Kb")); break;
|
||||
case 1:
|
||||
print_Msg(F("Sram "));
|
||||
print_Msg(sramSize);
|
||||
println_Msg(F(" Kb"));
|
||||
break;
|
||||
case 2:
|
||||
print_Msg(F("Eeprom "));
|
||||
print_Msg(sramSize);
|
||||
println_Msg(F(" Kb"));
|
||||
break;
|
||||
default: println_Msg(sramSize, HEX); break;
|
||||
}
|
||||
|
||||
@ -398,15 +409,13 @@ void showCartInfo_WS()
|
||||
wait();
|
||||
}
|
||||
|
||||
void getDeveloperName(uint8_t id, char *buf, size_t length)
|
||||
{
|
||||
void getDeveloperName(uint8_t id, char *buf, size_t length) {
|
||||
if (buf == NULL)
|
||||
return;
|
||||
|
||||
char *devName = NULL;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
switch (id) {
|
||||
case 0x01: devName = PSTR("BAN"); break;
|
||||
case 0x02: devName = PSTR("TAT"); break;
|
||||
case 0x03: devName = PSTR("TMY"); break;
|
||||
@ -433,7 +442,7 @@ void getDeveloperName(uint8_t id, char *buf, size_t length)
|
||||
case 0x1e: devName = PSTR("NAP"); break;
|
||||
case 0x1f: devName = PSTR("BVL"); break;
|
||||
case 0x20: devName = PSTR("ATN"); break;
|
||||
case 0x21: devName = PSTR("KDX"); break; // KDK for Memories of Festa?
|
||||
case 0x21: devName = PSTR("KDX"); break; // KDK for Memories of Festa?
|
||||
case 0x22: devName = PSTR("HAL"); break;
|
||||
case 0x23: devName = PSTR("YKE"); break;
|
||||
case 0x24: devName = PSTR("OMM"); break;
|
||||
@ -452,17 +461,18 @@ void getDeveloperName(uint8_t id, char *buf, size_t length)
|
||||
|
||||
// custom developerId
|
||||
case 0x7a: devName = PSTR("7AC"); break; // witch
|
||||
case 0xff: devName = PSTR("WWGP"); break; // WWGP series (jss2, dknight)
|
||||
case 0xff:
|
||||
devName = PSTR("WWGP");
|
||||
break; // WWGP series (jss2, dknight)
|
||||
|
||||
// if not found, use id
|
||||
default: snprintf(buf, length, "%02X", id); return;
|
||||
default: snprintf(buf, length, "%02X", id); return;
|
||||
}
|
||||
|
||||
strlcpy_P(buf, devName, length);
|
||||
}
|
||||
|
||||
void readROM_WS(char *outPathBuf, size_t bufferSize)
|
||||
{
|
||||
void readROM_WS(char *outPathBuf, size_t bufferSize) {
|
||||
// generate fullname of rom file
|
||||
snprintf(fileName, FILENAME_LENGTH, "%s.ws%c", romName, ((romType & 1) ? 'c' : '\0'));
|
||||
|
||||
@ -497,8 +507,7 @@ void readROM_WS(char *outPathBuf, size_t bufferSize)
|
||||
draw_progressbar(0, cartSize);
|
||||
|
||||
// start reading rom
|
||||
for (; bank <= 0xff; bank++)
|
||||
{
|
||||
for (; bank <= 0xff; bank++) {
|
||||
// switch bank on segment 0x2
|
||||
dataOut_WS();
|
||||
writeByte_WSPort(0xc2, bank);
|
||||
@ -508,14 +517,13 @@ void readROM_WS(char *outPathBuf, size_t bufferSize)
|
||||
writeByte_WSPort(0xcd, (bank & 0x03));
|
||||
|
||||
dataIn_WS();
|
||||
for (uint32_t addr = 0; addr < 0x10000; addr += 512)
|
||||
{
|
||||
for (uint32_t addr = 0; addr < 0x10000; addr += 512) {
|
||||
// blink LED
|
||||
if ((addr & ((1 << 14) - 1)) == 0)
|
||||
blinkLED();
|
||||
|
||||
for (uint32_t w = 0; w < 512; w += 2)
|
||||
* ((uint16_t*)(sdBuffer + w)) = readWord_WS(0x20000 + addr + w);
|
||||
*((uint16_t *)(sdBuffer + w)) = readWord_WS(0x20000 + addr + w);
|
||||
|
||||
myFile.write(sdBuffer, 512);
|
||||
progress += 512;
|
||||
@ -525,8 +533,7 @@ void readROM_WS(char *outPathBuf, size_t bufferSize)
|
||||
}
|
||||
|
||||
// turn off LEDs (only for BANC33)
|
||||
if (wsGameChecksum == 0xeafd)
|
||||
{
|
||||
if (wsGameChecksum == 0xeafd) {
|
||||
dataOut_WS();
|
||||
writeByte_WSPort(0xcd, 0x00);
|
||||
}
|
||||
@ -534,8 +541,7 @@ void readROM_WS(char *outPathBuf, size_t bufferSize)
|
||||
myFile.close();
|
||||
}
|
||||
|
||||
void readSRAM_WS()
|
||||
{
|
||||
void readSRAM_WS() {
|
||||
// generate fullname of rom file
|
||||
snprintf(fileName, FILENAME_LENGTH, "%s.sav", romName);
|
||||
|
||||
@ -565,14 +571,12 @@ void readSRAM_WS()
|
||||
|
||||
uint16_t bank = 0;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
dataOut_WS();
|
||||
writeByte_WSPort(0xc1, bank);
|
||||
|
||||
dataIn_WS();
|
||||
for (uint32_t addr = 0; addr < bank_size; addr += 512)
|
||||
{
|
||||
for (uint32_t addr = 0; addr < bank_size; addr += 512) {
|
||||
// blink LED
|
||||
if ((addr & ((1 << 14) - 1)) == 0)
|
||||
blinkLED();
|
||||
@ -591,13 +595,11 @@ void readSRAM_WS()
|
||||
display_Update();
|
||||
}
|
||||
|
||||
void verifySRAM_WS()
|
||||
{
|
||||
void verifySRAM_WS() {
|
||||
print_Msg(F("Verifying... "));
|
||||
display_Update();
|
||||
|
||||
if (myFile.open(filePath, O_READ))
|
||||
{
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
uint32_t bank_size = (sramSize << 7);
|
||||
uint16_t end_bank = (bank_size >> 16); // 64KB per bank
|
||||
uint16_t bank = 0;
|
||||
@ -606,19 +608,16 @@ void verifySRAM_WS()
|
||||
if (bank_size > 0x10000)
|
||||
bank_size = 0x10000;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
dataOut_WS();
|
||||
writeByte_WSPort(0xc1, bank);
|
||||
|
||||
dataIn_WS();
|
||||
for (uint32_t addr = 0; addr < bank_size && myFile.available(); addr += 512)
|
||||
{
|
||||
for (uint32_t addr = 0; addr < bank_size && myFile.available(); addr += 512) {
|
||||
myFile.read(sdBuffer, 512);
|
||||
|
||||
// SRAM data on D0-D7, with A-1 to select high/low byte
|
||||
for (uint32_t w = 0; w < 512; w++)
|
||||
{
|
||||
for (uint32_t w = 0; w < 512; w++) {
|
||||
if (readByte_WS(0x10000 + addr + w) != sdBuffer[w])
|
||||
write_errors++;
|
||||
}
|
||||
@ -627,27 +626,21 @@ void verifySRAM_WS()
|
||||
|
||||
myFile.close();
|
||||
|
||||
if (write_errors == 0)
|
||||
{
|
||||
if (write_errors == 0) {
|
||||
println_Msg(F("passed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
println_Msg(F("failed"));
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(write_errors);
|
||||
println_Msg(F(" bytes "));
|
||||
print_Error(F("did not verify."), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"), false);
|
||||
}
|
||||
}
|
||||
|
||||
void writeSRAM_WS()
|
||||
{
|
||||
void writeSRAM_WS() {
|
||||
filePath[0] = 0;
|
||||
sd.chdir("/");
|
||||
fileBrowser(F("Select sav file"));
|
||||
@ -659,8 +652,7 @@ void writeSRAM_WS()
|
||||
println_Msg(F("..."));
|
||||
display_Update();
|
||||
|
||||
if (myFile.open(filePath, O_READ))
|
||||
{
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
uint32_t bank_size = (sramSize << 7);
|
||||
uint16_t end_bank = (bank_size >> 16); // 64KB per bank
|
||||
|
||||
@ -669,12 +661,10 @@ void writeSRAM_WS()
|
||||
|
||||
uint16_t bank = 0;
|
||||
dataOut_WS();
|
||||
do
|
||||
{
|
||||
do {
|
||||
writeByte_WSPort(0xc1, bank);
|
||||
|
||||
for (uint32_t addr = 0; addr < bank_size && myFile.available(); addr += 512)
|
||||
{
|
||||
for (uint32_t addr = 0; addr < bank_size && myFile.available(); addr += 512) {
|
||||
// blink LED
|
||||
if ((addr & ((1 << 14) - 1)) == 0)
|
||||
blinkLED();
|
||||
@ -691,15 +681,12 @@ void writeSRAM_WS()
|
||||
|
||||
println_Msg(F("Writing finished"));
|
||||
display_Update();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"), false);
|
||||
}
|
||||
}
|
||||
|
||||
void readEEPROM_WS()
|
||||
{
|
||||
void readEEPROM_WS() {
|
||||
// generate fullname of eep file
|
||||
snprintf(fileName, FILENAME_LENGTH, "%s.eep", romName);
|
||||
|
||||
@ -724,10 +711,8 @@ void readEEPROM_WS()
|
||||
uint32_t eepromSize = (sramSize << 7);
|
||||
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
|
||||
|
||||
for (uint32_t i = 0; i < eepromSize; i += bufSize)
|
||||
{
|
||||
for (uint32_t j = 0; j < bufSize; j += 2)
|
||||
{
|
||||
for (uint32_t i = 0; i < eepromSize; i += bufSize) {
|
||||
for (uint32_t j = 0; j < bufSize; j += 2) {
|
||||
// blink LED
|
||||
if ((j & 0x1f) == 0x00)
|
||||
blinkLED();
|
||||
@ -756,23 +741,19 @@ void readEEPROM_WS()
|
||||
println_Msg(F("Done"));
|
||||
}
|
||||
|
||||
void verifyEEPROM_WS()
|
||||
{
|
||||
void verifyEEPROM_WS() {
|
||||
print_Msg(F("Verifying... "));
|
||||
display_Update();
|
||||
|
||||
if (myFile.open(filePath, O_READ))
|
||||
{
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
uint32_t write_errors = 0;
|
||||
uint32_t eepromSize = (sramSize << 7);
|
||||
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
|
||||
|
||||
for (uint32_t i = 0; i < eepromSize; i += bufSize)
|
||||
{
|
||||
for (uint32_t i = 0; i < eepromSize; i += bufSize) {
|
||||
myFile.read(sdBuffer, bufSize);
|
||||
|
||||
for (uint32_t j = 0; j < bufSize; j += 2)
|
||||
{
|
||||
for (uint32_t j = 0; j < bufSize; j += 2) {
|
||||
// blink LED
|
||||
if ((j & 0x1f) == 0x00)
|
||||
blinkLED();
|
||||
@ -799,27 +780,21 @@ void verifyEEPROM_WS()
|
||||
|
||||
myFile.close();
|
||||
|
||||
if (write_errors == 0)
|
||||
{
|
||||
if (write_errors == 0) {
|
||||
println_Msg(F("passed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
println_Msg(F("failed"));
|
||||
print_Msg(F("Error: "));
|
||||
print_Msg(write_errors);
|
||||
println_Msg(F(" bytes "));
|
||||
print_Error(F("did not verify."), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"), false);
|
||||
}
|
||||
}
|
||||
|
||||
void writeEEPROM_WS()
|
||||
{
|
||||
void writeEEPROM_WS() {
|
||||
filePath[0] = 0;
|
||||
sd.chdir("/");
|
||||
fileBrowser(F("Select eep file"));
|
||||
@ -831,17 +806,14 @@ void writeEEPROM_WS()
|
||||
println_Msg(F("..."));
|
||||
display_Update();
|
||||
|
||||
if (myFile.open(filePath, O_READ))
|
||||
{
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
uint32_t eepromSize = (sramSize << 7);
|
||||
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
|
||||
|
||||
for (uint32_t i = 0; i < eepromSize; i += bufSize)
|
||||
{
|
||||
for (uint32_t i = 0; i < eepromSize; i += bufSize) {
|
||||
myFile.read(sdBuffer, bufSize);
|
||||
|
||||
for (uint32_t j = 0; j < bufSize; j += 2)
|
||||
{
|
||||
for (uint32_t j = 0; j < bufSize; j += 2) {
|
||||
// blink LED
|
||||
if ((j & 0x1f) == 0x00)
|
||||
blinkLED();
|
||||
@ -861,23 +833,19 @@ void writeEEPROM_WS()
|
||||
dataIn_WS();
|
||||
do {
|
||||
pulseCLK_WS(128);
|
||||
}
|
||||
while ((readByte_WSPort(0xc8) & 0x02) == 0x00);
|
||||
} while ((readByte_WSPort(0xc8) & 0x02) == 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
myFile.close();
|
||||
|
||||
println_Msg(F("Done"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"), false);
|
||||
}
|
||||
}
|
||||
|
||||
void writeWitchOS_WS()
|
||||
{
|
||||
void writeWitchOS_WS() {
|
||||
// make sure that OS sectors not protected
|
||||
dataOut_WS();
|
||||
writeWord_WS(0x80aaa, 0xaaaa);
|
||||
@ -885,13 +853,10 @@ void writeWitchOS_WS()
|
||||
writeWord_WS(0xe0aaa, 0x9090);
|
||||
|
||||
dataIn_WS();
|
||||
if (readWord_WS(0xe0004) || readWord_WS(0xe4004) || readWord_WS(0xec004) || readWord_WS(0xee004))
|
||||
{
|
||||
if (readWord_WS(0xe0004) || readWord_WS(0xe4004) || readWord_WS(0xec004) || readWord_WS(0xee004)) {
|
||||
display_Clear();
|
||||
print_Error(F("OS sectors are protected!"), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
filePath[0] = 0;
|
||||
sd.chdir("/");
|
||||
fileBrowser(F("Select fbin file"));
|
||||
@ -899,8 +864,7 @@ void writeWitchOS_WS()
|
||||
|
||||
display_Clear();
|
||||
|
||||
if (myFile.open(filePath, O_READ))
|
||||
{
|
||||
if (myFile.open(filePath, O_READ)) {
|
||||
println_Msg(F("Erasing OS..."));
|
||||
display_Update();
|
||||
eraseWitchFlashSector_WS(0xe0000);
|
||||
@ -930,8 +894,7 @@ void writeWitchOS_WS()
|
||||
writeWord_WS(0x80aaa, 0x2020);
|
||||
|
||||
// 128bytes per block
|
||||
for (i = 0; i < fbin_length; i += 128)
|
||||
{
|
||||
for (i = 0; i < fbin_length; i += 128) {
|
||||
// blink LED
|
||||
if ((i & 0x3ff) == 0)
|
||||
blinkLED();
|
||||
@ -940,8 +903,7 @@ void writeWitchOS_WS()
|
||||
key = 0xff;
|
||||
bytes_read = myFile.read(sdBuffer, 128);
|
||||
|
||||
for (uint32_t j = 0; j < bytes_read; j += 2)
|
||||
{
|
||||
for (uint32_t j = 0; j < bytes_read; j += 2) {
|
||||
// for each decoded[n] = encoded[n] ^ key
|
||||
// where key = encoded[n - 1]
|
||||
// key = 0xff when n = 0, 0 <= n < 128
|
||||
@ -954,10 +916,10 @@ void writeWitchOS_WS()
|
||||
|
||||
// write jmpf instruction and block counts at 0xe0000
|
||||
memcpy_P(sdBuffer, wwLaunchCode, 8);
|
||||
*((uint16_t*)(sdBuffer + 6)) = ((i >> 7) & 0xffff);
|
||||
*((uint16_t *)(sdBuffer + 6)) = ((i >> 7) & 0xffff);
|
||||
|
||||
for (uint32_t i = 0; i < 8; i += 2)
|
||||
fastProgramWitchFlash_WS(0xefff0 + i, *((uint16_t*)(sdBuffer + i)));
|
||||
fastProgramWitchFlash_WS(0xefff0 + i, *((uint16_t *)(sdBuffer + i)));
|
||||
|
||||
// leave fast program mode
|
||||
dataOut_WS();
|
||||
@ -967,9 +929,7 @@ void writeWitchOS_WS()
|
||||
myFile.close();
|
||||
|
||||
println_Msg(F("Done"));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Error(F("File doesn't exist"), false);
|
||||
}
|
||||
}
|
||||
@ -978,19 +938,18 @@ void writeWitchOS_WS()
|
||||
writeWord_WS(0x80000, 0xf0f0);
|
||||
}
|
||||
|
||||
void fastProgramWitchFlash_WS(uint32_t addr, uint16_t data)
|
||||
{
|
||||
void fastProgramWitchFlash_WS(uint32_t addr, uint16_t data) {
|
||||
dataOut_WS();
|
||||
|
||||
writeWord_WS(addr, 0xa0a0);
|
||||
writeWord_WS(addr, data);
|
||||
|
||||
dataIn_WS();
|
||||
while (readWord_WS(addr) != data);
|
||||
while (readWord_WS(addr) != data)
|
||||
;
|
||||
}
|
||||
|
||||
void eraseWitchFlashSector_WS(uint32_t sector_addr)
|
||||
{
|
||||
void eraseWitchFlashSector_WS(uint32_t sector_addr) {
|
||||
// blink LED
|
||||
blinkLED();
|
||||
|
||||
@ -1003,19 +962,18 @@ void eraseWitchFlashSector_WS(uint32_t sector_addr)
|
||||
writeWord_WS(sector_addr, 0x3030);
|
||||
|
||||
dataIn_WS();
|
||||
while ((readWord_WS(sector_addr) & 0x0080) == 0x0000);
|
||||
while ((readWord_WS(sector_addr) & 0x0080) == 0x0000)
|
||||
;
|
||||
}
|
||||
|
||||
boolean compareChecksum_WS(const char *wsFilePath)
|
||||
{
|
||||
boolean compareChecksum_WS(const char *wsFilePath) {
|
||||
if (wsFilePath == NULL)
|
||||
return 0;
|
||||
|
||||
println_Msg(F("Calculating Checksum"));
|
||||
display_Update();
|
||||
|
||||
if (!myFile.open(wsFilePath, O_READ))
|
||||
{
|
||||
if (!myFile.open(wsFilePath, O_READ)) {
|
||||
print_Error(F("Failed to open file"), false);
|
||||
return 0;
|
||||
}
|
||||
@ -1023,15 +981,13 @@ boolean compareChecksum_WS(const char *wsFilePath)
|
||||
uint32_t calLength = myFile.fileSize() - 512;
|
||||
uint32_t checksum = 0;
|
||||
|
||||
if (wsWitch)
|
||||
{
|
||||
if (wsWitch) {
|
||||
// only calcuate last 128Kbytes for wonderwitch (OS and BIOS region)
|
||||
myFile.seekCur(myFile.fileSize() - 131072);
|
||||
calLength = 131072 - 512;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < calLength; i += 512)
|
||||
{
|
||||
for (uint32_t i = 0; i < calLength; i += 512) {
|
||||
myFile.read(sdBuffer, 512);
|
||||
for (uint32_t j = 0; j < 512; j++)
|
||||
checksum += sdBuffer[j];
|
||||
@ -1056,21 +1012,17 @@ boolean compareChecksum_WS(const char *wsFilePath)
|
||||
print_Msg(F("Result: "));
|
||||
println_Msg(result);
|
||||
|
||||
if (checksum == calLength)
|
||||
{
|
||||
if (checksum == calLength) {
|
||||
println_Msg(F("Checksum matches"));
|
||||
display_Update();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
print_Error(F("Checksum Error"), false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void writeByte_WSPort(uint8_t port, uint8_t data)
|
||||
{
|
||||
void writeByte_WSPort(uint8_t port, uint8_t data) {
|
||||
PORTF = (port & 0x0f);
|
||||
PORTL = (port >> 4);
|
||||
|
||||
@ -1086,14 +1038,14 @@ void writeByte_WSPort(uint8_t port, uint8_t data)
|
||||
|
||||
// switch WE(PH5) to HIGH
|
||||
PORTH |= (1 << 5);
|
||||
NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
// switch CART(PH3), MMC(PH4) to HIGH
|
||||
PORTH |= ((1 << 3) | (1 << 4));
|
||||
}
|
||||
|
||||
uint8_t readByte_WSPort(uint8_t port)
|
||||
{
|
||||
uint8_t readByte_WSPort(uint8_t port) {
|
||||
PORTF = (port & 0x0f);
|
||||
PORTL = (port >> 4);
|
||||
|
||||
@ -1102,7 +1054,9 @@ uint8_t readByte_WSPort(uint8_t port)
|
||||
|
||||
// switch OE(PH6) to LOW
|
||||
PORTH &= ~(1 << 6);
|
||||
NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
uint8_t ret = PINC;
|
||||
|
||||
@ -1115,8 +1069,7 @@ uint8_t readByte_WSPort(uint8_t port)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void writeWord_WS(uint32_t addr, uint16_t data)
|
||||
{
|
||||
void writeWord_WS(uint32_t addr, uint16_t data) {
|
||||
PORTF = addr & 0xff;
|
||||
PORTK = (addr >> 8) & 0xff;
|
||||
PORTL = (addr >> 16) & 0x0f;
|
||||
@ -1130,18 +1083,20 @@ void writeWord_WS(uint32_t addr, uint16_t data)
|
||||
|
||||
// switch CART(PH3) and WE(PH5) to HIGH
|
||||
PORTH |= (1 << 3) | (1 << 5);
|
||||
NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
}
|
||||
|
||||
uint16_t readWord_WS(uint32_t addr)
|
||||
{
|
||||
uint16_t readWord_WS(uint32_t addr) {
|
||||
PORTF = addr & 0xff;
|
||||
PORTK = (addr >> 8) & 0xff;
|
||||
PORTL = (addr >> 16) & 0x0f;
|
||||
|
||||
// switch CART(PH3) and OE(PH6) to LOW
|
||||
PORTH &= ~((1 << 3) | (1 << 6));
|
||||
NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
uint16_t ret = ((PINA << 8) | PINC);
|
||||
|
||||
@ -1151,8 +1106,7 @@ uint16_t readWord_WS(uint32_t addr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void writeByte_WS(uint32_t addr, uint8_t data)
|
||||
{
|
||||
void writeByte_WS(uint32_t addr, uint8_t data) {
|
||||
PORTF = addr & 0xff;
|
||||
PORTK = (addr >> 8) & 0xff;
|
||||
PORTL = (addr >> 16) & 0x0f;
|
||||
@ -1165,18 +1119,20 @@ void writeByte_WS(uint32_t addr, uint8_t data)
|
||||
|
||||
// switch CART(PH3) and WE(PH5) to HIGH
|
||||
PORTH |= (1 << 3) | (1 << 5);
|
||||
NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
}
|
||||
|
||||
uint8_t readByte_WS(uint32_t addr)
|
||||
{
|
||||
uint8_t readByte_WS(uint32_t addr) {
|
||||
PORTF = addr & 0xff;
|
||||
PORTK = (addr >> 8) & 0xff;
|
||||
PORTL = (addr >> 16) & 0x0f;
|
||||
|
||||
// switch CART(PH3) and OE(PH6) to LOW
|
||||
PORTH &= ~((1 << 3) | (1 << 6));
|
||||
NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
uint8_t ret = PINC;
|
||||
|
||||
@ -1186,8 +1142,7 @@ uint8_t readByte_WS(uint32_t addr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void unprotectEEPROM()
|
||||
{
|
||||
void unprotectEEPROM() {
|
||||
generateEepromInstruction_WS(wsEepromShiftReg, 0x0, 0x3);
|
||||
|
||||
dataOut_WS();
|
||||
@ -1201,23 +1156,19 @@ void unprotectEEPROM()
|
||||
|
||||
// generate data for port 0xc6 to 0xc7
|
||||
// number of CLK pulses needed for each instruction is 1 + (16 or 32) + 3
|
||||
void generateEepromInstruction_WS(uint8_t *instruction, uint8_t opcode, uint16_t addr)
|
||||
{
|
||||
void generateEepromInstruction_WS(uint8_t *instruction, uint8_t opcode, uint16_t addr) {
|
||||
uint8_t addr_bits = (sramSize > 1 ? 10 : 6);
|
||||
uint16_t *ptr = (uint16_t*)instruction;
|
||||
*ptr = 0x0001; // initial with a start bit
|
||||
uint16_t *ptr = (uint16_t *)instruction;
|
||||
*ptr = 0x0001; // initial with a start bit
|
||||
|
||||
if (opcode == 0)
|
||||
{
|
||||
if (opcode == 0) {
|
||||
// 2bits opcode = 0x00
|
||||
*ptr <<= 2;
|
||||
// 2bits ext cmd (from addr)
|
||||
*ptr <<= 2;
|
||||
*ptr |= (addr & 0x0003);
|
||||
*ptr <<= (addr_bits - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// 2bits opcode
|
||||
*ptr <<= 2;
|
||||
*ptr |= (opcode & 0x03);
|
||||
@ -1230,8 +1181,7 @@ void generateEepromInstruction_WS(uint8_t *instruction, uint8_t opcode, uint16_t
|
||||
// 2003 MMC need to be unlock,
|
||||
// or it will reject all reading and bank switching
|
||||
// All signals' timing are analyzed by using LogicAnalyzer
|
||||
boolean unlockMMC2003_WS()
|
||||
{
|
||||
boolean unlockMMC2003_WS() {
|
||||
// initialize all control pin state
|
||||
// RST(PH0) and CLK(PE3or5) to LOW
|
||||
// CART(PH3) MMC(PH4) WE(PH5) OE(PH6) to HIGH
|
||||
@ -1261,8 +1211,7 @@ boolean unlockMMC2003_WS()
|
||||
writeByte_WSPort(0xc3, 0x55);
|
||||
|
||||
dataIn_WS();
|
||||
if (readByte_WSPort(0xc2) == 0xaa && readByte_WSPort(0xc3) == 0x55)
|
||||
{
|
||||
if (readByte_WSPort(0xc2) == 0xaa && readByte_WSPort(0xc3) == 0x55) {
|
||||
// now set initial bank number to MMC
|
||||
dataOut_WS();
|
||||
writeByte_WSPort(0xc0, 0x2f);
|
||||
@ -1276,35 +1225,31 @@ boolean unlockMMC2003_WS()
|
||||
}
|
||||
|
||||
// doing a L->H on CLK pin
|
||||
void pulseCLK_WS(uint8_t count)
|
||||
{
|
||||
void pulseCLK_WS(uint8_t count) {
|
||||
register uint8_t tic;
|
||||
|
||||
// about 384KHz, 50% duty cycle
|
||||
asm volatile
|
||||
("L0_%=:\n\t"
|
||||
"cpi %[count], 0\n\t"
|
||||
"breq L3_%=\n\t"
|
||||
"dec %[count]\n\t"
|
||||
"cbi %[porte], %[ws_clk_bit]\n\t"
|
||||
"ldi %[tic], 6\n\t"
|
||||
"L1_%=:\n\t"
|
||||
"dec %[tic]\n\t"
|
||||
"brne L1_%=\n\t"
|
||||
"sbi %[porte], %[ws_clk_bit]\n\t"
|
||||
"ldi %[tic], 5\n\t"
|
||||
"L2_%=:\n\t"
|
||||
"dec %[tic]\n\t"
|
||||
"brne L2_%=\n\t"
|
||||
"rjmp L0_%=\n\t"
|
||||
"L3_%=:\n\t"
|
||||
: [tic] "=a" (tic)
|
||||
: [count] "a" (count), [porte] "I" (_SFR_IO_ADDR(PORTE)), [ws_clk_bit] "I" (WS_CLK_BIT)
|
||||
);
|
||||
asm volatile("L0_%=:\n\t"
|
||||
"cpi %[count], 0\n\t"
|
||||
"breq L3_%=\n\t"
|
||||
"dec %[count]\n\t"
|
||||
"cbi %[porte], %[ws_clk_bit]\n\t"
|
||||
"ldi %[tic], 6\n\t"
|
||||
"L1_%=:\n\t"
|
||||
"dec %[tic]\n\t"
|
||||
"brne L1_%=\n\t"
|
||||
"sbi %[porte], %[ws_clk_bit]\n\t"
|
||||
"ldi %[tic], 5\n\t"
|
||||
"L2_%=:\n\t"
|
||||
"dec %[tic]\n\t"
|
||||
"brne L2_%=\n\t"
|
||||
"rjmp L0_%=\n\t"
|
||||
"L3_%=:\n\t"
|
||||
: [tic] "=a"(tic)
|
||||
: [count] "a"(count), [porte] "I"(_SFR_IO_ADDR(PORTE)), [ws_clk_bit] "I"(WS_CLK_BIT));
|
||||
}
|
||||
|
||||
void dataIn_WS()
|
||||
{
|
||||
void dataIn_WS() {
|
||||
DDRC = 0x00;
|
||||
DDRA = 0x00;
|
||||
|
||||
@ -1314,8 +1259,7 @@ void dataIn_WS()
|
||||
PORTA = 0x00;
|
||||
}
|
||||
|
||||
void dataOut_WS()
|
||||
{
|
||||
void dataOut_WS() {
|
||||
DDRC = 0xff;
|
||||
DDRA = 0xff;
|
||||
}
|
||||
|
@ -38,9 +38,9 @@
|
||||
// /WR - (PH5)
|
||||
// /RD - (PH6)
|
||||
|
||||
word WSV[] = {32, 64, 512};
|
||||
byte wsvlo = 0; // Lowest Entry
|
||||
byte wsvhi = 2; // Highest Entry
|
||||
word WSV[] = { 32, 64, 512 };
|
||||
byte wsvlo = 0; // Lowest Entry
|
||||
byte wsvhi = 2; // Highest Entry
|
||||
|
||||
byte wsvsize;
|
||||
byte newwsvsize;
|
||||
@ -52,8 +52,7 @@ byte newwsvsize;
|
||||
// SETUP
|
||||
//******************************************
|
||||
|
||||
void setup_WSV()
|
||||
{
|
||||
void setup_WSV() {
|
||||
// Set Address Pins to Output
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
@ -87,7 +86,7 @@ void setup_WSV()
|
||||
// Set Unused Pins HIGH
|
||||
PORTL = 0xE0;
|
||||
PORTA = 0xFF;
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||
|
||||
checkStatus_WSV();
|
||||
strcpy(romName, "SUPERVISION");
|
||||
@ -104,15 +103,13 @@ static const char wsvMenuItem1[] PROGMEM = "Select Cart";
|
||||
static const char wsvMenuItem2[] PROGMEM = "Read ROM";
|
||||
static const char wsvMenuItem3[] PROGMEM = "Set Size";
|
||||
static const char wsvMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsSV[] PROGMEM = {wsvMenuItem1, wsvMenuItem2, wsvMenuItem3, wsvMenuItem4};
|
||||
static const char* const menuOptionsSV[] PROGMEM = { wsvMenuItem1, wsvMenuItem2, wsvMenuItem3, wsvMenuItem4 };
|
||||
|
||||
void wsvMenu()
|
||||
{
|
||||
void wsvMenu() {
|
||||
convertPgm(menuOptionsSV, 4);
|
||||
uint8_t mainMenu = question_box(F("SUPERVISION MENU"), menuOptions, 4, 0);
|
||||
|
||||
switch (mainMenu)
|
||||
{
|
||||
switch (mainMenu) {
|
||||
case 0:
|
||||
// Select Cart
|
||||
setCart_WSV();
|
||||
@ -157,25 +154,27 @@ void controlIn_WSV() {
|
||||
PORTH &= ~(1 << 6);
|
||||
}
|
||||
|
||||
void dataIn_WSV()
|
||||
{
|
||||
void dataIn_WSV() {
|
||||
DDRC = 0x00;
|
||||
}
|
||||
|
||||
void dataOut_WSV()
|
||||
{
|
||||
void dataOut_WSV() {
|
||||
DDRC = 0xFF;
|
||||
}
|
||||
|
||||
uint8_t readByte_WSV(uint32_t addr)
|
||||
{
|
||||
uint8_t readByte_WSV(uint32_t addr) {
|
||||
PORTF = addr & 0xFF;
|
||||
PORTK = (addr >> 8) & 0xFF;
|
||||
PORTL = (addr >> 16) & 0xFF;
|
||||
|
||||
// Wait for data bus
|
||||
// 6 x 62.5ns = 375ns
|
||||
NOP; NOP; NOP; NOP; NOP; NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
NOP;
|
||||
|
||||
uint8_t ret = PINC;
|
||||
NOP;
|
||||
@ -187,8 +186,7 @@ uint8_t readByte_WSV(uint32_t addr)
|
||||
// READ CODE
|
||||
//******************************************
|
||||
|
||||
void readROM_WSV()
|
||||
{
|
||||
void readROM_WSV() {
|
||||
strcpy(fileName, romName);
|
||||
strcat(fileName, ".sv");
|
||||
|
||||
@ -223,8 +221,7 @@ void readROM_WSV()
|
||||
if (romSize < 64)
|
||||
romStart = 0x8000;
|
||||
uint32_t romEnd = (uint32_t)romSize * 0x400;
|
||||
for (uint32_t addr = 0; addr < romEnd; addr += 512)
|
||||
{
|
||||
for (uint32_t addr = 0; addr < romEnd; addr += 512) {
|
||||
for (uint16_t w = 0; w < 512; w++)
|
||||
sdBuffer[w] = readByte_WSV(romStart + addr + w);
|
||||
myFile.write(sdBuffer, 512);
|
||||
@ -245,8 +242,7 @@ void readROM_WSV()
|
||||
// ROM SIZE
|
||||
//******************************************
|
||||
|
||||
void setROMSize_WSV()
|
||||
{
|
||||
void setROMSize_WSV() {
|
||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||
display_Clear();
|
||||
if (wsvlo == wsvhi)
|
||||
@ -270,7 +266,7 @@ void setROMSize_WSV()
|
||||
|
||||
while (1) {
|
||||
b = checkButton();
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (b == 2) { // Previous (doubleclick)
|
||||
if (i == wsvlo)
|
||||
i = wsvhi;
|
||||
else
|
||||
@ -290,7 +286,7 @@ void setROMSize_WSV()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 1) { // Next (press)
|
||||
if (b == 1) { // Next (press)
|
||||
if (i == wsvhi)
|
||||
i = wsvlo;
|
||||
else
|
||||
@ -310,12 +306,12 @@ void setROMSize_WSV()
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
if (b == 3) { // Long Press - Execute (hold)
|
||||
newwsvsize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
display.setCursor(0, 56); // Display selection at bottom
|
||||
}
|
||||
print_Msg(F("ROM SIZE "));
|
||||
print_Msg(WSV[newwsvsize]);
|
||||
@ -354,11 +350,10 @@ setrom:
|
||||
wsvsize = newwsvsize;
|
||||
}
|
||||
|
||||
void checkStatus_WSV()
|
||||
{
|
||||
void checkStatus_WSV() {
|
||||
EEPROM_readAnything(8, wsvsize);
|
||||
if (wsvsize > 2) {
|
||||
wsvsize = 1; // default 64K
|
||||
wsvsize = 1; // default 64K
|
||||
EEPROM_writeAnything(8, wsvsize);
|
||||
}
|
||||
|
||||
@ -416,12 +411,10 @@ void setCart_WSV() {
|
||||
while (1) {
|
||||
if (myFile.curPosition() == 0) {
|
||||
break;
|
||||
}
|
||||
else if (myFile.peek() == '\n') {
|
||||
} else if (myFile.peek() == '\n') {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
}
|
||||
}
|
||||
@ -463,9 +456,8 @@ void setCart_WSV() {
|
||||
|
||||
// Remove leading 0 for single digit cart sizes
|
||||
if (cartSize != 0) {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
}
|
||||
else {
|
||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||
} else {
|
||||
cartSize = myFile.read() - 48;
|
||||
}
|
||||
|
||||
@ -513,12 +505,10 @@ void setCart_WSV() {
|
||||
while (1) {
|
||||
if (myFile.curPosition() == 0) {
|
||||
break;
|
||||
}
|
||||
else if (myFile.peek() == '\n') {
|
||||
} else if (myFile.peek() == '\n') {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
myFile.seekSet(myFile.curPosition() - 1);
|
||||
}
|
||||
}
|
||||
@ -550,8 +540,7 @@ void setCart_WSV() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print_Error(F("Database file not found"), true);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user