mirror of
https://github.com/sanni/cartreader.git
synced 2025-02-17 13:36:19 +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
|
// /C000(PH5) - CHIP 2 - SNES /WR
|
||||||
// /E000(PH6) - CHIP 3 - SNES /RD
|
// /E000(PH6) - CHIP 3 - SNES /RD
|
||||||
|
|
||||||
byte COL[] = {8, 12, 16, 20, 24, 32};
|
byte COL[] = { 8, 12, 16, 20, 24, 32 };
|
||||||
byte collo = 0; // Lowest Entry
|
byte collo = 0; // Lowest Entry
|
||||||
byte colhi = 5; // Highest Entry
|
byte colhi = 5; // Highest Entry
|
||||||
|
|
||||||
byte colsize;
|
byte colsize;
|
||||||
byte newcolsize;
|
byte newcolsize;
|
||||||
@ -52,10 +52,9 @@ static const char colMenuItem1[] PROGMEM = "Select Cart";
|
|||||||
static const char colMenuItem2[] PROGMEM = "Read ROM";
|
static const char colMenuItem2[] PROGMEM = "Read ROM";
|
||||||
static const char colMenuItem3[] PROGMEM = "Set Size";
|
static const char colMenuItem3[] PROGMEM = "Set Size";
|
||||||
static const char colMenuItem4[] PROGMEM = "Reset";
|
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
|
// Set Address Pins to Output
|
||||||
// Colecovision uses A0-A14 [A15-A23 UNUSED]
|
// Colecovision uses A0-A14 [A15-A23 UNUSED]
|
||||||
//A0-A7
|
//A0-A7
|
||||||
@ -67,10 +66,10 @@ void setup_COL()
|
|||||||
|
|
||||||
// Set Control Pins to Output
|
// Set Control Pins to Output
|
||||||
// ---(PH0) ---(PH1) /8000(PH3) /A000(PH4) /C000(PH5) /E000(PH6)
|
// ---(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)
|
// Set TIME(PJ0) to Output (UNUSED)
|
||||||
DDRJ |= (1 << 0);
|
DDRJ |= (1 << 0);
|
||||||
|
|
||||||
// Set Pins (D0-D7) to Input
|
// Set Pins (D0-D7) to Input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
@ -84,8 +83,8 @@ void setup_COL()
|
|||||||
|
|
||||||
// Set Unused Pins HIGH
|
// Set Unused Pins HIGH
|
||||||
PORTA = 0xFF;
|
PORTA = 0xFF;
|
||||||
PORTL = 0xFF; // A16-A23
|
PORTL = 0xFF; // A16-A23
|
||||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||||
|
|
||||||
checkStatus_COL();
|
checkStatus_COL();
|
||||||
strcpy(romName, "COLECO");
|
strcpy(romName, "COLECO");
|
||||||
@ -93,13 +92,11 @@ void setup_COL()
|
|||||||
mode = mode_COL;
|
mode = mode_COL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void colMenu()
|
void colMenu() {
|
||||||
{
|
|
||||||
convertPgm(menuOptionsCOL, 4);
|
convertPgm(menuOptionsCOL, 4);
|
||||||
uint8_t mainMenu = question_box(F("COLECOVISION MENU"), menuOptions, 4, 0);
|
uint8_t mainMenu = question_box(F("COLECOVISION MENU"), menuOptions, 4, 0);
|
||||||
|
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
// Select Cart
|
// Select Cart
|
||||||
setCart_COL();
|
setCart_COL();
|
||||||
@ -134,31 +131,29 @@ void colMenu()
|
|||||||
// /C000(PH5) - CHIP 2
|
// /C000(PH5) - CHIP 2
|
||||||
// /E000(PH6) - CHIP 3
|
// /E000(PH6) - CHIP 3
|
||||||
|
|
||||||
uint8_t readData_COL(uint32_t addr)
|
uint8_t readData_COL(uint32_t addr) {
|
||||||
{
|
|
||||||
// SELECT ROM CHIP - PULL /CE LOW
|
// SELECT ROM CHIP - PULL /CE LOW
|
||||||
uint8_t chipdecode = ((addr >> 13) & 0x3);
|
uint8_t chipdecode = ((addr >> 13) & 0x3);
|
||||||
if (chipdecode == 3) // CHIP 3
|
if (chipdecode == 3) // CHIP 3
|
||||||
PORTH &= ~(1 << 6); // /E000 LOW (ENABLE)
|
PORTH &= ~(1 << 6); // /E000 LOW (ENABLE)
|
||||||
else if (chipdecode == 2) // CHIP 2
|
else if (chipdecode == 2) // CHIP 2
|
||||||
PORTH &= ~(1 << 5); // /C000 LOW (ENABLE)
|
PORTH &= ~(1 << 5); // /C000 LOW (ENABLE)
|
||||||
else if (chipdecode == 1) // CHIP 1
|
else if (chipdecode == 1) // CHIP 1
|
||||||
PORTH &= ~(1 << 4); // /A000 LOW (ENABLE)
|
PORTH &= ~(1 << 4); // /A000 LOW (ENABLE)
|
||||||
else // CHIP 0
|
else // CHIP 0
|
||||||
PORTH &= ~(1 << 3); // /8000 LOW (ENABLE)
|
PORTH &= ~(1 << 3); // /8000 LOW (ENABLE)
|
||||||
|
|
||||||
PORTF = addr & 0xFF; // A0-A7
|
PORTF = addr & 0xFF; // A0-A7
|
||||||
PORTK = (addr >> 8) & 0xFF; // A8-A15
|
PORTK = (addr >> 8) & 0xFF; // A8-A15
|
||||||
|
|
||||||
// LATCH ADDRESS - PULL /CE HIGH
|
// 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;
|
uint8_t ret = PINC;
|
||||||
return ret;
|
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 (uint32_t addr = startaddr; addr < endaddr; addr += 512) {
|
||||||
for (int w = 0; w < 512; w++) {
|
for (int w = 0; w < 512; w++) {
|
||||||
uint8_t temp = readData_COL(addr + 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);
|
strcpy(fileName, romName);
|
||||||
strcat(fileName, ".col");
|
strcat(fileName, ".col");
|
||||||
|
|
||||||
@ -197,17 +191,17 @@ void readROM_COL()
|
|||||||
// RESET ALL CS PINS HIGH (DISABLE)
|
// RESET ALL CS PINS HIGH (DISABLE)
|
||||||
PORTH |= (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
PORTH |= (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||||
|
|
||||||
readSegment_COL(0x8000, 0xA000); // 8K
|
readSegment_COL(0x8000, 0xA000); // 8K
|
||||||
if (colsize > 0) {
|
if (colsize > 0) {
|
||||||
readSegment_COL(0xA000, 0xB000); // +4K = 12K
|
readSegment_COL(0xA000, 0xB000); // +4K = 12K
|
||||||
if (colsize > 1) {
|
if (colsize > 1) {
|
||||||
readSegment_COL(0xB000, 0xC000); // +4K = 16K
|
readSegment_COL(0xB000, 0xC000); // +4K = 16K
|
||||||
if (colsize > 2) {
|
if (colsize > 2) {
|
||||||
readSegment_COL(0xC000, 0xD000); // +4K = 20K
|
readSegment_COL(0xC000, 0xD000); // +4K = 20K
|
||||||
if (colsize > 3) {
|
if (colsize > 3) {
|
||||||
readSegment_COL(0xD000, 0xE000); // +4K = 24K
|
readSegment_COL(0xD000, 0xE000); // +4K = 24K
|
||||||
if (colsize > 4) {
|
if (colsize > 4) {
|
||||||
readSegment_COL(0xE000, 0x10000); // +8K = 32K
|
readSegment_COL(0xE000, 0x10000); // +8K = 32K
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,8 +225,7 @@ void readROM_COL()
|
|||||||
// ROM SIZE
|
// ROM SIZE
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
void setROMSize_COL()
|
void setROMSize_COL() {
|
||||||
{
|
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
display_Clear();
|
display_Clear();
|
||||||
if (collo == colhi)
|
if (collo == colhi)
|
||||||
@ -256,7 +249,7 @@ void setROMSize_COL()
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
b = checkButton();
|
b = checkButton();
|
||||||
if (b == 2) { // Previous (doubleclick)
|
if (b == 2) { // Previous (doubleclick)
|
||||||
if (i == collo)
|
if (i == collo)
|
||||||
i = colhi;
|
i = colhi;
|
||||||
else
|
else
|
||||||
@ -276,7 +269,7 @@ void setROMSize_COL()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 1) { // Next (press)
|
if (b == 1) { // Next (press)
|
||||||
if (i == colhi)
|
if (i == colhi)
|
||||||
i = collo;
|
i = collo;
|
||||||
else
|
else
|
||||||
@ -296,12 +289,12 @@ void setROMSize_COL()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 3) { // Long Press - Execute (hold)
|
if (b == 3) { // Long Press - Execute (hold)
|
||||||
newcolsize = i;
|
newcolsize = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
display.setCursor(0, 56); // Display selection at bottom
|
display.setCursor(0, 56); // Display selection at bottom
|
||||||
}
|
}
|
||||||
print_Msg(F("ROM SIZE "));
|
print_Msg(F("ROM SIZE "));
|
||||||
print_Msg(COL[newcolsize]);
|
print_Msg(COL[newcolsize]);
|
||||||
@ -340,8 +333,7 @@ setrom:
|
|||||||
colsize = newcolsize;
|
colsize = newcolsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkStatus_COL()
|
void checkStatus_COL() {
|
||||||
{
|
|
||||||
EEPROM_readAnything(8, colsize);
|
EEPROM_readAnything(8, colsize);
|
||||||
if (colsize > 5) {
|
if (colsize > 5) {
|
||||||
colsize = 0;
|
colsize = 0;
|
||||||
@ -404,12 +396,10 @@ void setCart_COL() {
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (myFile.curPosition() == 0) {
|
if (myFile.curPosition() == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (myFile.peek() == '\n') {
|
||||||
else if (myFile.peek() == '\n') {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,9 +441,8 @@ void setCart_COL() {
|
|||||||
|
|
||||||
// Remove leading 0 for single digit cart sizes
|
// Remove leading 0 for single digit cart sizes
|
||||||
if (cartSize != 0) {
|
if (cartSize != 0) {
|
||||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cartSize = myFile.read() - 48;
|
cartSize = myFile.read() - 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,12 +487,10 @@ void setCart_COL() {
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (myFile.curPosition() == 0) {
|
if (myFile.curPosition() == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (myFile.peek() == '\n') {
|
||||||
else if (myFile.peek() == '\n') {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,12 +538,11 @@ void setCart_COL() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Database file not found"), true);
|
print_Error(F("Database file not found"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
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 flash8MenuItem5[] PROGMEM = "ID";
|
||||||
static const char flash8MenuItem6[] PROGMEM = "Print";
|
static const char flash8MenuItem6[] PROGMEM = "Print";
|
||||||
static const char flash8MenuItem7[] PROGMEM = "Reset";
|
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
|
#ifdef enable_FLASH16
|
||||||
// Flash start menu
|
// 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 flashMenuItem2[] PROGMEM = "Eprom adapter";
|
||||||
static const char flashMenuItem3[] PROGMEM = "MX26L6420 adapter";
|
static const char flashMenuItem3[] PROGMEM = "MX26L6420 adapter";
|
||||||
static const char flashMenuItem4[] PROGMEM = "Reset";
|
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
|
// 16bit Flash menu items
|
||||||
static const char flash16MenuItem1[] PROGMEM = "Blankcheck";
|
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 flash16MenuItem5[] PROGMEM = "ID";
|
||||||
static const char flash16MenuItem6[] PROGMEM = "Print";
|
static const char flash16MenuItem6[] PROGMEM = "Print";
|
||||||
static const char flash16MenuItem7[] PROGMEM = "Reset";
|
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
|
// Eprom menu items
|
||||||
static const char epromMenuItem1[] PROGMEM = "Blankcheck";
|
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 epromMenuItem4[] PROGMEM = "Verify";
|
||||||
static const char epromMenuItem5[] PROGMEM = "Print";
|
static const char epromMenuItem5[] PROGMEM = "Print";
|
||||||
static const char epromMenuItem6[] PROGMEM = "Reset";
|
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() {
|
void flashMenu() {
|
||||||
// create menu with title and 3 options to choose from
|
// 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);
|
flashSlot = question_box(F("Select adapter PCB"), menuOptions, 4, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (flashSlot)
|
switch (flashSlot) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
@ -74,14 +73,14 @@ void flashMenu() {
|
|||||||
setup_Flash8();
|
setup_Flash8();
|
||||||
id_Flash8();
|
id_Flash8();
|
||||||
wait();
|
wait();
|
||||||
mode = mode_FLASH8;
|
mode = mode_FLASH8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_Eprom();
|
setup_Eprom();
|
||||||
mode = mode_EPROM;
|
mode = mode_EPROM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -90,7 +89,7 @@ void flashMenu() {
|
|||||||
setup_Flash16();
|
setup_Flash16();
|
||||||
id_Flash16();
|
id_Flash16();
|
||||||
wait();
|
wait();
|
||||||
mode = mode_FLASH16;
|
mode = mode_FLASH16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
@ -108,8 +107,7 @@ void flashromMenu8() {
|
|||||||
mainMenu = question_box(F("Flashrom Writer 8"), menuOptions, 7, 0);
|
mainMenu = question_box(F("Flashrom Writer 8"), menuOptions, 7, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
println_Msg(F("Blankcheck"));
|
println_Msg(F("Blankcheck"));
|
||||||
@ -159,16 +157,12 @@ void flashromMenu8() {
|
|||||||
writeFlash29F1601();
|
writeFlash29F1601();
|
||||||
else if ((strcmp(flashid, "C2F1") == 0) || (strcmp(flashid, "C2F9") == 0))
|
else if ((strcmp(flashid, "C2F1") == 0) || (strcmp(flashid, "C2F9") == 0))
|
||||||
writeFlash29F1610();
|
writeFlash29F1610();
|
||||||
else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 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, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0) ||
|
|
||||||
(strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0))
|
|
||||||
writeFlash29LV640();
|
writeFlash29LV640();
|
||||||
else if (strcmp(flashid, "017E") == 0) {
|
else if (strcmp(flashid, "017E") == 0) {
|
||||||
// sector size, write buffer size
|
// sector size, write buffer size
|
||||||
writeFlash29GL(sectorSize, bufferSize);
|
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();
|
writeFlash29F800();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -242,8 +236,7 @@ void flashromMenu16() {
|
|||||||
mainMenu = question_box(F("Flashrom Writer 16"), menuOptions, 7, 0);
|
mainMenu = question_box(F("Flashrom Writer 16"), menuOptions, 7, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
println_Msg(F("Blankcheck"));
|
println_Msg(F("Blankcheck"));
|
||||||
@ -279,11 +272,9 @@ void flashromMenu16() {
|
|||||||
time = millis();
|
time = millis();
|
||||||
if (strcmp(flashid, "C2F3") == 0) {
|
if (strcmp(flashid, "C2F3") == 0) {
|
||||||
writeFlash16_29F1601();
|
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();
|
writeFlash16_29LV640();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writeFlash16();
|
writeFlash16();
|
||||||
}
|
}
|
||||||
delay(100);
|
delay(100);
|
||||||
@ -338,8 +329,7 @@ void epromMenu() {
|
|||||||
mainMenu = question_box(F("Eprom Writer"), menuOptions, 6, 0);
|
mainMenu = question_box(F("Eprom Writer"), menuOptions, 6, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
println_Msg(F("Blankcheck"));
|
println_Msg(F("Blankcheck"));
|
||||||
@ -419,87 +409,71 @@ idtheflash:
|
|||||||
println_Msg(F("MX29F1610 detected"));
|
println_Msg(F("MX29F1610 detected"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "C2F3") == 0) {
|
||||||
else if (strcmp(flashid, "C2F3") == 0) {
|
|
||||||
println_Msg(F("MX29F1601 detected"));
|
println_Msg(F("MX29F1601 detected"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "C2F9") == 0) {
|
||||||
else if (strcmp(flashid, "C2F9") == 0) {
|
|
||||||
println_Msg(F("MX29L3211 detected"));
|
println_Msg(F("MX29L3211 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 4194304;
|
flashSize = 4194304;
|
||||||
flashromType = 2;
|
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("MX29LV160 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 2;
|
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("MX29LV320 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 4194304;
|
flashSize = 4194304;
|
||||||
flashromType = 2;
|
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("MX29LV640 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 8388608;
|
flashSize = 8388608;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "0141") == 0) {
|
||||||
else if (strcmp(flashid, "0141") == 0) {
|
|
||||||
println_Msg(F("AM29F032B detected"));
|
println_Msg(F("AM29F032B detected"));
|
||||||
flashSize = 4194304;
|
flashSize = 4194304;
|
||||||
flashromType = 1;
|
flashromType = 1;
|
||||||
}
|
} else if (strcmp(flashid, "01AD") == 0) {
|
||||||
else if (strcmp(flashid, "01AD") == 0) {
|
|
||||||
println_Msg(F("AM29F016B detected"));
|
println_Msg(F("AM29F016B detected"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 1;
|
flashromType = 1;
|
||||||
}
|
} else if (strcmp(flashid, "20AD") == 0) {
|
||||||
else if (strcmp(flashid, "20AD") == 0) {
|
|
||||||
println_Msg(F("AM29F016D detected"));
|
println_Msg(F("AM29F016D detected"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 1;
|
flashromType = 1;
|
||||||
}
|
} else if (strcmp(flashid, "04AD") == 0) {
|
||||||
else if (strcmp(flashid, "04AD") == 0) {
|
|
||||||
println_Msg(F("AM29F016D detected"));
|
println_Msg(F("AM29F016D detected"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 1;
|
flashromType = 1;
|
||||||
}
|
} else if (strcmp(flashid, "04D4") == 0) {
|
||||||
else if (strcmp(flashid, "04D4") == 0) {
|
|
||||||
println_Msg(F("MBM29F033C detected"));
|
println_Msg(F("MBM29F033C detected"));
|
||||||
flashSize = 4194304;
|
flashSize = 4194304;
|
||||||
flashromType = 1;
|
flashromType = 1;
|
||||||
}
|
} else if (strcmp(flashid, "04D5") == 0) {
|
||||||
else if (strcmp(flashid, "04D5") == 0) {
|
|
||||||
println_Msg(F("MBM29F080C detected"));
|
println_Msg(F("MBM29F080C detected"));
|
||||||
flashSize = 1048576;
|
flashSize = 1048576;
|
||||||
flashromType = 1;
|
flashromType = 1;
|
||||||
}
|
} else if (strcmp(flashid, "0458") == 0) {
|
||||||
else if (strcmp(flashid, "0458") == 0) {
|
|
||||||
println_Msg(F("MBM29F800BA detected"));
|
println_Msg(F("MBM29F800BA detected"));
|
||||||
flashSize = 1048576;
|
flashSize = 1048576;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "01AB") == 0) {
|
||||||
else if (strcmp(flashid, "01AB") == 0) {
|
|
||||||
println_Msg(F("AM29F400AB detected"));
|
println_Msg(F("AM29F400AB detected"));
|
||||||
flashSize = 131072 * 4;
|
flashSize = 131072 * 4;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "0158") == 0) {
|
||||||
else if (strcmp(flashid, "0158") == 0) {
|
|
||||||
println_Msg(F("AM29F800BB detected"));
|
println_Msg(F("AM29F800BB detected"));
|
||||||
flashSize = 1048576;
|
flashSize = 1048576;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "01A3") == 0) {
|
||||||
else if (strcmp(flashid, "01A3") == 0) {
|
|
||||||
println_Msg(F("AM29LV033C detected"));
|
println_Msg(F("AM29LV033C detected"));
|
||||||
flashSize = 131072 * 32;
|
flashSize = 131072 * 32;
|
||||||
flashromType = 1;
|
flashromType = 1;
|
||||||
}
|
} else if (strcmp(flashid, "017E") == 0) {
|
||||||
else if (strcmp(flashid, "017E") == 0) {
|
|
||||||
// S29GL032M
|
// S29GL032M
|
||||||
if (readByte_Flash(28) == 0x1A) {
|
if (readByte_Flash(28) == 0x1A) {
|
||||||
println_Msg(F("S29GL032M detected"));
|
println_Msg(F("S29GL032M detected"));
|
||||||
@ -523,8 +497,7 @@ idtheflash:
|
|||||||
}
|
}
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "B088") == 0) {
|
||||||
else if (strcmp(flashid, "B088") == 0) {
|
|
||||||
// LH28F016SUT
|
// LH28F016SUT
|
||||||
println_Msg(F("LH28F016SUT detected"));
|
println_Msg(F("LH28F016SUT detected"));
|
||||||
println_Msg(F("ATTENTION 3/5 setting"));
|
println_Msg(F("ATTENTION 3/5 setting"));
|
||||||
@ -532,10 +505,7 @@ idtheflash:
|
|||||||
sectorSize = 65536;
|
sectorSize = 65536;
|
||||||
bufferSize = 256;
|
bufferSize = 256;
|
||||||
flashromType = 3;
|
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
|
// E28FXXXJ3A
|
||||||
print_Msg(F("E28F"));
|
print_Msg(F("E28F"));
|
||||||
|
|
||||||
@ -558,15 +528,13 @@ idtheflash:
|
|||||||
sectorSize = 131072;
|
sectorSize = 131072;
|
||||||
bufferSize = 32;
|
bufferSize = 32;
|
||||||
flashromType = 3;
|
flashromType = 3;
|
||||||
}
|
} else if (secondID == 1) {
|
||||||
else if (secondID == 1) {
|
|
||||||
// Read ID a second time using a different command (type 1 flashrom)
|
// Read ID a second time using a different command (type 1 flashrom)
|
||||||
resetFlash8();
|
resetFlash8();
|
||||||
idFlash29F032();
|
idFlash29F032();
|
||||||
secondID = 2;
|
secondID = 2;
|
||||||
goto idtheflash;
|
goto idtheflash;
|
||||||
}
|
} else if (secondID == 2) {
|
||||||
else if (secondID == 2) {
|
|
||||||
// Backup first ID read-out
|
// Backup first ID read-out
|
||||||
strncpy(vendorID, flashid, 5);
|
strncpy(vendorID, flashid, 5);
|
||||||
|
|
||||||
@ -575,8 +543,7 @@ idtheflash:
|
|||||||
idFlash29F1610();
|
idFlash29F1610();
|
||||||
secondID = 0;
|
secondID = 0;
|
||||||
goto idtheflash;
|
goto idtheflash;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// ID not found
|
// ID not found
|
||||||
display_Clear();
|
display_Clear();
|
||||||
println_Msg(F("Flashrom Writer 8bit"));
|
println_Msg(F("Flashrom Writer 8bit"));
|
||||||
@ -624,43 +591,36 @@ void id_Flash16() {
|
|||||||
println_Msg("");
|
println_Msg("");
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "C2F3") == 0) {
|
||||||
else if (strcmp(flashid, "C2F3") == 0) {
|
|
||||||
println_Msg(F("MX29F1601 detected"));
|
println_Msg(F("MX29F1601 detected"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "C2F9") == 0) {
|
||||||
else if (strcmp(flashid, "C2F9") == 0) {
|
|
||||||
println_Msg(F("MX29L3211 detected"));
|
println_Msg(F("MX29L3211 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 4194304;
|
flashSize = 4194304;
|
||||||
flashromType = 2;
|
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("MX29LV160 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 2097152;
|
flashSize = 2097152;
|
||||||
flashromType = 2;
|
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("MX29LV320 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 4194304;
|
flashSize = 4194304;
|
||||||
flashromType = 2;
|
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("MX29LV640 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 8388608;
|
flashSize = 8388608;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else if (strcmp(flashid, "C2FC") == 0) {
|
||||||
else if (strcmp(flashid, "C2FC") == 0) {
|
|
||||||
println_Msg(F("MX26L6420 detected"));
|
println_Msg(F("MX26L6420 detected"));
|
||||||
println_Msg(F("ATTENTION 3.3V"));
|
println_Msg(F("ATTENTION 3.3V"));
|
||||||
flashSize = 8388608;
|
flashSize = 8388608;
|
||||||
flashromType = 2;
|
flashromType = 2;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Unknown flashrom"), true);
|
print_Error(F("Unknown flashrom"), true);
|
||||||
println_Msg("");
|
println_Msg("");
|
||||||
}
|
}
|
||||||
@ -683,7 +643,7 @@ void setup_Flash8() {
|
|||||||
DDRL = 0xFF;
|
DDRL = 0xFF;
|
||||||
|
|
||||||
// Set Control Pins to Output RST(PH0) OE(PH1) OE_SNS(PH3) WE(PH4) WE_SNS(PH5) CE(PH6)
|
// 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
|
// 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);
|
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5);
|
||||||
// Setting CE(PH6) LOW
|
// Setting CE(PH6) LOW
|
||||||
@ -819,10 +779,9 @@ void writeByte_Flash(unsigned long myAddress, byte myData) {
|
|||||||
if (!(((myAddress >> 16) & 0xFF) & 0x40)) {
|
if (!(((myAddress >> 16) & 0xFF) & 0x40)) {
|
||||||
// if PL6 is 0 set PL7 to 1
|
// if PL6 is 0 set PL7 to 1
|
||||||
PORTL |= (1 << 7);
|
PORTL |= (1 << 7);
|
||||||
}
|
} else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
||||||
else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
|
||||||
// if PL6 is 1 set PL7 to 0
|
// if PL6 is 1 set PL7 to 0
|
||||||
PORTL &= ~ (1 << 7);
|
PORTL &= ~(1 << 7);
|
||||||
}
|
}
|
||||||
// Switch SNES BA6(PL6) to HIGH to disable SRAM
|
// Switch SNES BA6(PL6) to HIGH to disable SRAM
|
||||||
PORTL |= (1 << 6);
|
PORTL |= (1 << 6);
|
||||||
@ -833,19 +792,34 @@ void writeByte_Flash(unsigned long myAddress, byte myData) {
|
|||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||||
// Wait till output is stable
|
// Wait till output is stable
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""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
|
// Switch WE(PH4) WE_SNS(PH5) to LOW
|
||||||
PORTH &= ~((1 << 4) | (1 << 5));
|
PORTH &= ~((1 << 4) | (1 << 5));
|
||||||
|
|
||||||
// Leave WE low for at least 60ns
|
// 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
|
// Switch WE(PH4) WE_SNS(PH5) to HIGH
|
||||||
PORTH |= (1 << 4) | (1 << 5);
|
PORTH |= (1 << 4) | (1 << 5);
|
||||||
|
|
||||||
// Leave WE high for at least 50ns
|
// 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) {
|
byte readByte_Flash(unsigned long myAddress) {
|
||||||
@ -889,29 +863,43 @@ byte readByte_Flash(unsigned long myAddress) {
|
|||||||
if (!(((myAddress >> 16) & 0xFF) & 0x40)) {
|
if (!(((myAddress >> 16) & 0xFF) & 0x40)) {
|
||||||
// if PL6 is 0 set PL7 to 1
|
// if PL6 is 0 set PL7 to 1
|
||||||
PORTL |= (1 << 7);
|
PORTL |= (1 << 7);
|
||||||
}
|
} else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
||||||
else if (((myAddress >> 16) & 0xFF) & 0x40) {
|
|
||||||
// if PL6 is 1 set PL7 to 0
|
// if PL6 is 1 set PL7 to 0
|
||||||
PORTL &= ~ (1 << 7);
|
PORTL &= ~(1 << 7);
|
||||||
}
|
}
|
||||||
// Switch SNES BA6(PL6) to HIGH to disable SRAM
|
// Switch SNES BA6(PL6) to HIGH to disable SRAM
|
||||||
PORTL |= (1 << 6);
|
PORTL |= (1 << 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
// 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
|
// Setting OE(PH1) OE_SNS(PH3) LOW
|
||||||
PORTH &= ~((1 << 1) | (1 << 3));
|
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
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = PINC;
|
||||||
|
|
||||||
// Setting OE(PH1) OE_SNS(PH3) HIGH
|
// Setting OE(PH1) OE_SNS(PH3) HIGH
|
||||||
PORTH |= (1 << 1) | (1 << 3);
|
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;
|
return tempByte;
|
||||||
}
|
}
|
||||||
@ -932,13 +920,23 @@ void writeWord_Flash(unsigned long myAddress, word myData) {
|
|||||||
PORTH &= ~(1 << 4);
|
PORTH &= ~(1 << 4);
|
||||||
|
|
||||||
// Leave WE low for at least 60ns
|
// 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
|
// Switch WE(PH4) to HIGH
|
||||||
PORTH |= (1 << 4);
|
PORTH |= (1 << 4);
|
||||||
|
|
||||||
// Leave WE high for at least 50ns
|
// 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) {
|
word readWord_Flash(unsigned long myAddress) {
|
||||||
@ -952,16 +950,26 @@ word readWord_Flash(unsigned long myAddress) {
|
|||||||
// Setting OE(PH1) LOW
|
// Setting OE(PH1) LOW
|
||||||
PORTH &= ~(1 << 1);
|
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
|
// Read
|
||||||
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
|
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF);
|
||||||
|
|
||||||
__asm__("nop\n\t");
|
__asm__("nop\n\t");
|
||||||
|
|
||||||
// Setting OE(PH1) HIGH
|
// Setting OE(PH1) HIGH
|
||||||
PORTH |= (1 << 1);
|
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;
|
return tempWord;
|
||||||
}
|
}
|
||||||
@ -1104,8 +1112,7 @@ void writeFlash29F032() {
|
|||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file"));
|
println_Msg(F("Can't open file"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1119,7 +1126,7 @@ int busyCheck29F032(uint32_t addr, byte c) {
|
|||||||
// Setting OE(PH1) OE_SNS(PH3) CE(PH6)LOW
|
// Setting OE(PH1) OE_SNS(PH3) CE(PH6)LOW
|
||||||
PORTH &= ~((1 << 1) | (1 << 3) | (1 << 6));
|
PORTH &= ~((1 << 1) | (1 << 3) | (1 << 6));
|
||||||
// Setting WE(PH4) WE_SNES(PH5) HIGH
|
// 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
|
//When the Embedded Program algorithm is complete, the device outputs the datum programmed to D7
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -1217,8 +1224,7 @@ void writeFlash29F1610() {
|
|||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD"));
|
println_Msg(F("Can't open file on SD"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1277,8 +1283,7 @@ void writeFlash29F1601() {
|
|||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD"));
|
println_Msg(F("Can't open file on SD"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1406,8 +1411,7 @@ void writeFlash29LV640() {
|
|||||||
dataIn8();
|
dataIn8();
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD"));
|
println_Msg(F("Can't open file on SD"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1474,8 +1478,7 @@ void writeFlash29GL(unsigned long sectorSize, byte bufferSize) {
|
|||||||
dataIn8();
|
dataIn8();
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD"));
|
println_Msg(F("Can't open file on SD"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1524,8 +1527,7 @@ void writeFlash29F800() {
|
|||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD"));
|
println_Msg(F("Can't open file on SD"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1562,14 +1564,14 @@ uint8_t statusFlash28FXXX() {
|
|||||||
|
|
||||||
void eraseFlash28FXXX() {
|
void eraseFlash28FXXX() {
|
||||||
// only can erase block by block
|
// 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();
|
dataOut();
|
||||||
writeByte_Flash(ba, 0x20);
|
writeByte_Flash(ba, 0x20);
|
||||||
writeByte_Flash(ba, 0xd0);
|
writeByte_Flash(ba, 0xd0);
|
||||||
|
|
||||||
dataIn8();
|
dataIn8();
|
||||||
while ((readByte_Flash(ba) & 0x80) == 0x00);
|
while ((readByte_Flash(ba) & 0x80) == 0x00)
|
||||||
|
;
|
||||||
|
|
||||||
// blink LED
|
// blink LED
|
||||||
blinkLED();
|
blinkLED();
|
||||||
@ -1586,15 +1588,12 @@ void writeFlash28FXXX() {
|
|||||||
if (myFile.open(filePath, O_READ)) {
|
if (myFile.open(filePath, O_READ)) {
|
||||||
if ((strcmp(flashid, "B088") == 0))
|
if ((strcmp(flashid, "B088") == 0))
|
||||||
writeFlashLH28F0XX();
|
writeFlashLH28F0XX();
|
||||||
else if ((strcmp(flashid, "8916") == 0) ||
|
else if ((strcmp(flashid, "8916") == 0) || (strcmp(flashid, "8917") == 0) || (strcmp(flashid, "8918") == 0)) {
|
||||||
(strcmp(flashid, "8917") == 0) ||
|
|
||||||
(strcmp(flashid, "8918") == 0)) {
|
|
||||||
writeFlashE28FXXXJ3A();
|
writeFlashE28FXXXJ3A();
|
||||||
}
|
}
|
||||||
|
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD"));
|
println_Msg(F("Can't open file on SD"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1627,7 +1626,8 @@ void writeFlashE28FXXXJ3A() {
|
|||||||
|
|
||||||
// waiting for buffer available
|
// waiting for buffer available
|
||||||
dataIn8();
|
dataIn8();
|
||||||
while ((readByte_Flash(block_addr) & 0x80) == 0x00);
|
while ((readByte_Flash(block_addr) & 0x80) == 0x00)
|
||||||
|
;
|
||||||
dataOut();
|
dataOut();
|
||||||
|
|
||||||
// set write byte count
|
// set write byte count
|
||||||
@ -1642,7 +1642,8 @@ void writeFlashE28FXXXJ3A() {
|
|||||||
|
|
||||||
// waiting for finishing
|
// waiting for finishing
|
||||||
dataIn8();
|
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
|
// sequence load to page
|
||||||
dataOut();
|
dataOut();
|
||||||
writeByte_Flash(0x0, 0xe0);
|
writeByte_Flash(0x0, 0xe0);
|
||||||
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
||||||
writeByte_Flash(0x0, 0x00); // BCH should be 0x00
|
writeByte_Flash(0x0, 0x00); // BCH should be 0x00
|
||||||
|
|
||||||
for (uint32_t d = 0; d < bufferSize; d++)
|
for (uint32_t d = 0; d < bufferSize; d++)
|
||||||
writeByte_Flash(d, sdBuffer[c + d]);
|
writeByte_Flash(d, sdBuffer[c + d]);
|
||||||
|
|
||||||
// start flashing page
|
// start flashing page
|
||||||
writeByte_Flash(0x0, 0x0c);
|
writeByte_Flash(0x0, 0x0c);
|
||||||
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
writeByte_Flash(0x0, bufferSize - 1); // BCL
|
||||||
writeByte_Flash(currByte + c, 0x00); // BCH should be 0x00
|
writeByte_Flash(currByte + c, 0x00); // BCH should be 0x00
|
||||||
|
|
||||||
// waiting for finishing
|
// waiting for finishing
|
||||||
dataIn8();
|
dataIn8();
|
||||||
while ((readByte_Flash(currByte + c) & 0x80) == 0x00);
|
while ((readByte_Flash(currByte + c) & 0x80) == 0x00)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1705,8 +1707,7 @@ void blankcheck_Flash() {
|
|||||||
if (blank) {
|
if (blank) {
|
||||||
println_Msg(F("Flashrom is empty"));
|
println_Msg(F("Flashrom is empty"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Not blank"), false);
|
print_Error(F("Error: Not blank"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1735,8 +1736,7 @@ void verifyFlash() {
|
|||||||
if (blank == 0) {
|
if (blank == 0) {
|
||||||
println_Msg(F("Flashrom verified OK"));
|
println_Msg(F("Flashrom verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(blank);
|
print_Msg(blank);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
@ -1744,8 +1744,7 @@ void verifyFlash() {
|
|||||||
}
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD"));
|
println_Msg(F("Can't open file on SD"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1793,7 +1792,7 @@ void printFlash(int numBytes) {
|
|||||||
|
|
||||||
for (int currByte = 0; currByte < numBytes; currByte += 10) {
|
for (int currByte = 0; currByte < numBytes; currByte += 10) {
|
||||||
for (int c = 0; c < 10; c++) {
|
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++) {
|
for (int i = 0; i < 2 - strlen(myBuffer); i++) {
|
||||||
print_Msg(F("0"));
|
print_Msg(F("0"));
|
||||||
}
|
}
|
||||||
@ -1869,7 +1868,7 @@ void writeFlash16() {
|
|||||||
|
|
||||||
// Write one full page at a time
|
// Write one full page at a time
|
||||||
for (byte c = 0; c < 64; c++) {
|
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);
|
writeWord_Flash(currByte + c, currWord);
|
||||||
d += 2;
|
d += 2;
|
||||||
}
|
}
|
||||||
@ -1884,8 +1883,7 @@ void writeFlash16() {
|
|||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD."));
|
println_Msg(F("Can't open file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1928,7 +1926,7 @@ void writeFlash16_29F1601() {
|
|||||||
|
|
||||||
// Write one full page at a time
|
// Write one full page at a time
|
||||||
for (byte c = 0; c < 64; c++) {
|
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);
|
writeWord_Flash(currByte + c, currWord);
|
||||||
|
|
||||||
if (c == 63) {
|
if (c == 63) {
|
||||||
@ -1948,8 +1946,7 @@ void writeFlash16_29F1601() {
|
|||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD."));
|
println_Msg(F("Can't open file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -2021,8 +2018,7 @@ void blankcheck16() {
|
|||||||
if (blank) {
|
if (blank) {
|
||||||
println_Msg(F("Flashrom is empty."));
|
println_Msg(F("Flashrom is empty."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Not blank"), false);
|
print_Error(F("Error: Not blank"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2057,8 +2053,7 @@ void verifyFlash16() {
|
|||||||
if (blank == 0) {
|
if (blank == 0) {
|
||||||
println_Msg(F("Flashrom verified OK"));
|
println_Msg(F("Flashrom verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Verification ERROR!"));
|
println_Msg(F("Verification ERROR!"));
|
||||||
print_Msg(blank);
|
print_Msg(blank);
|
||||||
print_Error(F("B did not verify."), false);
|
print_Error(F("B did not verify."), false);
|
||||||
@ -2066,8 +2061,7 @@ void verifyFlash16() {
|
|||||||
}
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD."));
|
println_Msg(F("Can't open file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -2097,7 +2091,8 @@ void readFlash16() {
|
|||||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||||
println_Msg(F("Can't create file on SD."));
|
println_Msg(F("Can't create file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
while (1);
|
while (1)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
word d = 0;
|
word d = 0;
|
||||||
for (unsigned long currByte = 0; currByte < flashSize / 2; currByte += 256) {
|
for (unsigned long currByte = 0; currByte < flashSize / 2; currByte += 256) {
|
||||||
@ -2105,7 +2100,7 @@ void readFlash16() {
|
|||||||
word currWord = readWord_Flash(currByte + c);
|
word currWord = readWord_Flash(currByte + c);
|
||||||
// Split word into two bytes
|
// Split word into two bytes
|
||||||
// Right
|
// Right
|
||||||
sdBuffer[d + 1] = (( currWord >> 8 ) & 0xFF);
|
sdBuffer[d + 1] = ((currWord >> 8) & 0xFF);
|
||||||
// Left
|
// Left
|
||||||
sdBuffer[d] = (currWord & 0xFF);
|
sdBuffer[d] = (currWord & 0xFF);
|
||||||
d += 2;
|
d += 2;
|
||||||
@ -2136,17 +2131,17 @@ void printFlash16(int numBytes) {
|
|||||||
|
|
||||||
// Split word into two bytes
|
// Split word into two bytes
|
||||||
byte left_byte = currWord & 0xFF;
|
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++) {
|
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||||
print_Msg(F("0"));
|
print_Msg(F("0"));
|
||||||
}
|
}
|
||||||
// Now print the significant bits
|
// Now print the significant bits
|
||||||
print_Msg(buf);
|
print_Msg(buf);
|
||||||
|
|
||||||
sprintf (buf, "%x", right_byte);
|
sprintf(buf, "%x", right_byte);
|
||||||
for (int i = 0; i < 2 - strlen(buf); i++) {
|
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||||
print_Msg(F("0"));
|
print_Msg(F("0"));
|
||||||
}
|
}
|
||||||
@ -2225,7 +2220,7 @@ void writeFlash16_29LV640() {
|
|||||||
writeWord_Flash(0x5555, 0xa0);
|
writeWord_Flash(0x5555, 0xa0);
|
||||||
|
|
||||||
// Write current word
|
// 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);
|
writeWord_Flash(currWord + c, myWord);
|
||||||
d += 2;
|
d += 2;
|
||||||
// Check if write is complete
|
// Check if write is complete
|
||||||
@ -2238,8 +2233,7 @@ void writeFlash16_29LV640() {
|
|||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD."));
|
println_Msg(F("Can't open file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -2291,7 +2285,10 @@ word writeWord_Eprom(unsigned long myAddress, word myData) {
|
|||||||
DDRA = 0x00;
|
DDRA = 0x00;
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
// 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
|
// Setting CE(PH6) LOW
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
@ -2300,15 +2297,20 @@ word writeWord_Eprom(unsigned long myAddress, word myData) {
|
|||||||
delayMicroseconds(3);
|
delayMicroseconds(3);
|
||||||
|
|
||||||
// Read
|
// 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
|
// Setting CE(PH6) HIGH
|
||||||
PORTH |= (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
|
|
||||||
// Delay 130ns for Chip Enable High to Output Hi-Z
|
// 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;
|
return tempWord;
|
||||||
}
|
}
|
||||||
@ -2329,10 +2331,15 @@ word readWord_Eprom(unsigned long myAddress) {
|
|||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
|
|
||||||
// Delay for 100ns for Address Valid/Chip Enable Low to Output Valid
|
// 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
|
// Read
|
||||||
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
|
word tempWord = ((PINA & 0xFF) << 8) | (PINC & 0xFF);
|
||||||
|
|
||||||
// Setting CE(PH6) HIGH
|
// Setting CE(PH6) HIGH
|
||||||
PORTH |= (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
@ -2354,8 +2361,7 @@ void blankcheck_Eprom() {
|
|||||||
if (blank) {
|
if (blank) {
|
||||||
println_Msg(F("Flashrom is empty."));
|
println_Msg(F("Flashrom is empty."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Not blank"), false);
|
print_Error(F("Error: Not blank"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2384,7 +2390,8 @@ void read_Eprom() {
|
|||||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||||
println_Msg(F("Can't create file on SD."));
|
println_Msg(F("Can't create file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
while (1);
|
while (1)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
word d = 0;
|
word d = 0;
|
||||||
for (unsigned long currWord = 0; currWord < flashSize / 2; currWord += 256) {
|
for (unsigned long currWord = 0; currWord < flashSize / 2; currWord += 256) {
|
||||||
@ -2392,7 +2399,7 @@ void read_Eprom() {
|
|||||||
word myWord = readWord_Eprom(currWord + c);
|
word myWord = readWord_Eprom(currWord + c);
|
||||||
// Split word into two bytes
|
// Split word into two bytes
|
||||||
// Right
|
// Right
|
||||||
sdBuffer[d + 1] = ((myWord >> 8 ) & 0xFF);
|
sdBuffer[d + 1] = ((myWord >> 8) & 0xFF);
|
||||||
// Left
|
// Left
|
||||||
sdBuffer[d] = (myWord & 0xFF);
|
sdBuffer[d] = (myWord & 0xFF);
|
||||||
d += 2;
|
d += 2;
|
||||||
@ -2437,7 +2444,7 @@ void write_Eprom() {
|
|||||||
// Work through SD buffer
|
// Work through SD buffer
|
||||||
for (int c = 0; c < 256; c++) {
|
for (int c = 0; c < 256; c++) {
|
||||||
word checkWord;
|
word checkWord;
|
||||||
word myWord = ( ( sdBuffer[d + 1] & 0xFF ) << 8 ) | ( sdBuffer[d] & 0xFF );
|
word myWord = ((sdBuffer[d + 1] & 0xFF) << 8) | (sdBuffer[d] & 0xFF);
|
||||||
|
|
||||||
// Error counter
|
// Error counter
|
||||||
byte n = 0;
|
byte n = 0;
|
||||||
@ -2457,15 +2464,13 @@ void write_Eprom() {
|
|||||||
print_Error(F("Press button to reset"), true);
|
print_Error(F("Press button to reset"), true);
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
}
|
} while (checkWord != myWord);
|
||||||
while (checkWord != myWord);
|
|
||||||
d += 2;
|
d += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD."));
|
println_Msg(F("Can't open file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -2501,8 +2506,7 @@ void verify_Eprom() {
|
|||||||
if (blank == 0) {
|
if (blank == 0) {
|
||||||
println_Msg(F("Eprom verified OK"));
|
println_Msg(F("Eprom verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Verification ERROR!"));
|
println_Msg(F("Verification ERROR!"));
|
||||||
print_Msg(blank);
|
print_Msg(blank);
|
||||||
print_Error(F(" words did not verify."), false);
|
print_Error(F(" words did not verify."), false);
|
||||||
@ -2510,8 +2514,7 @@ void verify_Eprom() {
|
|||||||
}
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file on SD."));
|
println_Msg(F("Can't open file on SD."));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -2527,17 +2530,17 @@ void print_Eprom(int numBytes) {
|
|||||||
|
|
||||||
// Split word into two bytes
|
// Split word into two bytes
|
||||||
byte left_byte = currWord & 0xFF;
|
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++) {
|
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||||
print_Msg(F("0"));
|
print_Msg(F("0"));
|
||||||
}
|
}
|
||||||
// Now print the significant bits
|
// Now print the significant bits
|
||||||
print_Msg(buf);
|
print_Msg(buf);
|
||||||
|
|
||||||
sprintf (buf, "%x", right_byte);
|
sprintf(buf, "%x", right_byte);
|
||||||
for (int i = 0; i < 2 - strlen(buf); i++) {
|
for (int i = 0; i < 2 - strlen(buf); i++) {
|
||||||
print_Msg(F("0"));
|
print_Msg(F("0"));
|
||||||
}
|
}
|
||||||
@ -2553,4 +2556,4 @@ void print_Eprom(int numBytes) {
|
|||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -20,14 +20,14 @@ static const char gbxMenuItem2[] PROGMEM = "GB Advance (3V)";
|
|||||||
static const char gbxMenuItem3[] PROGMEM = "Flash GBC Cart";
|
static const char gbxMenuItem3[] PROGMEM = "Flash GBC Cart";
|
||||||
static const char gbxMenuItem4[] PROGMEM = "NPower GB Memory";
|
static const char gbxMenuItem4[] PROGMEM = "NPower GB Memory";
|
||||||
static const char gbxMenuItem5[] PROGMEM = "Reset";
|
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
|
// GB menu items
|
||||||
static const char GBMenuItem1[] PROGMEM = "Read ROM";
|
static const char GBMenuItem1[] PROGMEM = "Read ROM";
|
||||||
static const char GBMenuItem2[] PROGMEM = "Read Save";
|
static const char GBMenuItem2[] PROGMEM = "Read Save";
|
||||||
static const char GBMenuItem3[] PROGMEM = "Write Save";
|
static const char GBMenuItem3[] PROGMEM = "Write Save";
|
||||||
static const char GBMenuItem4[] PROGMEM = "Reset";
|
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
|
// GB Flash items
|
||||||
static const char GBFlashItem1[] PROGMEM = "29F Cart (MBC3)";
|
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 GBFlashItem5[] PROGMEM = "CFI Cart and Save";
|
||||||
static const char GBFlashItem6[] PROGMEM = "GB Smart";
|
static const char GBFlashItem6[] PROGMEM = "GB Smart";
|
||||||
static const char GBFlashItem7[] PROGMEM = "Reset";
|
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
|
// Start menu for both GB and GBA
|
||||||
void gbxMenu() {
|
void gbxMenu() {
|
||||||
@ -48,20 +48,19 @@ void gbxMenu() {
|
|||||||
gbType = question_box(F("Select Game Boy"), menuOptions, 5, 0);
|
gbType = question_box(F("Select Game Boy"), menuOptions, 5, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (gbType)
|
switch (gbType) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GB();
|
setup_GB();
|
||||||
mode = mode_GB;
|
mode = mode_GB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GBA();
|
setup_GBA();
|
||||||
mode = mode_GBA;
|
mode = mode_GBA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -72,14 +71,13 @@ void gbxMenu() {
|
|||||||
gbFlash = question_box(F("Select type"), menuOptions, 7, 0);
|
gbFlash = question_box(F("Select type"), menuOptions, 7, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (gbFlash)
|
switch (gbFlash) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
//Flash MBC3
|
//Flash MBC3
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GB();
|
setup_GB();
|
||||||
mode = mode_GB;
|
mode = mode_GB;
|
||||||
|
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -97,7 +95,7 @@ void gbxMenu() {
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GB();
|
setup_GB();
|
||||||
mode = mode_GB;
|
mode = mode_GB;
|
||||||
|
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -115,7 +113,7 @@ void gbxMenu() {
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GB();
|
setup_GB();
|
||||||
mode = mode_GB;
|
mode = mode_GB;
|
||||||
|
|
||||||
//Flash first bank with erase
|
//Flash first bank with erase
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
@ -156,7 +154,7 @@ void gbxMenu() {
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GB();
|
setup_GB();
|
||||||
mode = mode_GB;
|
mode = mode_GB;
|
||||||
|
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -183,7 +181,7 @@ void gbxMenu() {
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GB();
|
setup_GB();
|
||||||
mode = mode_GB;
|
mode = mode_GB;
|
||||||
|
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -231,8 +229,7 @@ void gbxMenu() {
|
|||||||
if (wrErrors == 0) {
|
if (wrErrors == 0) {
|
||||||
println_Msg(F("Verified OK"));
|
println_Msg(F("Verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(wrErrors);
|
print_Msg(wrErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
@ -245,8 +242,7 @@ void gbxMenu() {
|
|||||||
if (!saveFound) {
|
if (!saveFound) {
|
||||||
println_Msg(F("Error: No save found."));
|
println_Msg(F("Error: No save found."));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Cart has no Sram"), false);
|
print_Error(F("Cart has no Sram"), false);
|
||||||
}
|
}
|
||||||
// Reset
|
// Reset
|
||||||
@ -273,7 +269,7 @@ void gbxMenu() {
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_GBM();
|
setup_GBM();
|
||||||
mode = mode_GBM;
|
mode = mode_GBM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
@ -290,8 +286,7 @@ void gbMenu() {
|
|||||||
mainMenu = question_box(F("GB Cart Reader"), menuOptions, 4, 0);
|
mainMenu = question_box(F("GB Cart Reader"), menuOptions, 4, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
@ -313,8 +308,7 @@ void gbMenu() {
|
|||||||
readSRAMFLASH_MBC6_GB();
|
readSRAMFLASH_MBC6_GB();
|
||||||
else
|
else
|
||||||
readSRAM_GB();
|
readSRAM_GB();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("No save or unsupported type"), false);
|
print_Error(F("No save or unsupported type"), false);
|
||||||
}
|
}
|
||||||
println_Msg(F(""));
|
println_Msg(F(""));
|
||||||
@ -331,24 +325,21 @@ void gbMenu() {
|
|||||||
|
|
||||||
if (romType == 32) {
|
if (romType == 32) {
|
||||||
writeSRAMFLASH_MBC6_GB();
|
writeSRAMFLASH_MBC6_GB();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writeSRAM_GB();
|
writeSRAM_GB();
|
||||||
unsigned long wrErrors;
|
unsigned long wrErrors;
|
||||||
wrErrors = verifySRAM_GB();
|
wrErrors = verifySRAM_GB();
|
||||||
if (wrErrors == 0) {
|
if (wrErrors == 0) {
|
||||||
println_Msg(F("Verified OK"));
|
println_Msg(F("Verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(wrErrors);
|
print_Msg(wrErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
print_Error(F("did not verify."), false);
|
print_Error(F("did not verify."), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("No save or unsupported type"), false);
|
print_Error(F("No save or unsupported type"), false);
|
||||||
}
|
}
|
||||||
println_Msg(F(""));
|
println_Msg(F(""));
|
||||||
@ -498,19 +489,15 @@ void showCartInfo_GB() {
|
|||||||
case 0:
|
case 0:
|
||||||
if (romType == 6) {
|
if (romType == 6) {
|
||||||
print_Msg(F("512 Byte"));
|
print_Msg(F("512 Byte"));
|
||||||
}
|
} else if (romType == 0x22) {
|
||||||
else if (romType == 0x22) {
|
|
||||||
if (strncmp(cartID, "KCEJ", 4) == 0) {
|
if (strncmp(cartID, "KCEJ", 4) == 0) {
|
||||||
print_Msg(F("512 Byte"));
|
print_Msg(F("512 Byte"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("256 Byte"));
|
print_Msg(F("256 Byte"));
|
||||||
}
|
}
|
||||||
}
|
} else if (romType == 0xFD) {
|
||||||
else if (romType == 0xFD) {
|
|
||||||
print_Msg(F("32 Byte"));
|
print_Msg(F("32 Byte"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("None"));
|
print_Msg(F("None"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -550,8 +537,7 @@ void showCartInfo_GB() {
|
|||||||
println_Msg(F("Press Button..."));
|
println_Msg(F("Press Button..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
wait();
|
wait();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("GAMEPAK ERROR"), true);
|
print_Error(F("GAMEPAK ERROR"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -568,12 +554,18 @@ byte readByte_GB(word myAddress) {
|
|||||||
// Enable pullups
|
// Enable pullups
|
||||||
PORTC = 0xFF;
|
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
|
// Switch RD(PH6) to LOW
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = PINC;
|
||||||
@ -581,7 +573,10 @@ byte readByte_GB(word myAddress) {
|
|||||||
// Switch and RD(PH6) to HIGH
|
// Switch and RD(PH6) to HIGH
|
||||||
PORTH |= (1 << 6);
|
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;
|
return tempByte;
|
||||||
}
|
}
|
||||||
@ -596,18 +591,27 @@ void writeByte_GB(int myAddress, byte myData) {
|
|||||||
DDRC = 0xFF;
|
DDRC = 0xFF;
|
||||||
|
|
||||||
// Wait till output is stable
|
// Wait till output is stable
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
// Pull WR(PH5) low
|
// Pull WR(PH5) low
|
||||||
PORTH &= ~(1 << 5);
|
PORTH &= ~(1 << 5);
|
||||||
|
|
||||||
// Leave WR low for at least 60ns
|
// Leave WR low for at least 60ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
// Pull WR(PH5) HIGH
|
// Pull WR(PH5) HIGH
|
||||||
PORTH |= (1 << 5);
|
PORTH |= (1 << 5);
|
||||||
// Leave WR high for at least 50ns
|
// Leave WR high for at least 50ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
// Switch data pins to input
|
// Switch data pins to input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
@ -624,29 +628,37 @@ byte readByteSRAM_GB(word myAddress) {
|
|||||||
// Enable pullups
|
// Enable pullups
|
||||||
PORTC = 0xFF;
|
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
|
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) LOW
|
||||||
PORTH &= ~((1 << 3) | (1 << 1));
|
PORTH &= ~((1 << 3) | (1 << 1));
|
||||||
// Pull RD(PH6) LOW
|
// Pull RD(PH6) LOW
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = PINC;
|
||||||
|
|
||||||
// Pull RD(PH6) HIGH
|
// Pull RD(PH6) HIGH
|
||||||
PORTH |= (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
if (romType == 252) {
|
if (romType == 252) {
|
||||||
// Pull CS(PH3) HIGH
|
// Pull CS(PH3) HIGH
|
||||||
PORTH |= (1 << 3);
|
PORTH |= (1 << 3);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) HIGH
|
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 1);
|
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;
|
return tempByte;
|
||||||
}
|
}
|
||||||
@ -661,7 +673,10 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
|||||||
// Switch data pins to output
|
// Switch data pins to output
|
||||||
DDRC = 0xFF;
|
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) {
|
if (romType == 252 || romType == 253) {
|
||||||
// Pull CS(PH3) LOW
|
// Pull CS(PH3) LOW
|
||||||
@ -670,8 +685,7 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
|||||||
PORTH |= (1 << 1);
|
PORTH |= (1 << 1);
|
||||||
// Pull WR(PH5) low
|
// Pull WR(PH5) low
|
||||||
PORTH &= ~(1 << 5);
|
PORTH &= ~(1 << 5);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) LOW
|
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) LOW
|
||||||
PORTH &= ~((1 << 3) | (1 << 1));
|
PORTH &= ~((1 << 3) | (1 << 1));
|
||||||
// Pull WR(PH5) low
|
// Pull WR(PH5) low
|
||||||
@ -679,7 +693,10 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Leave WR low for at least 60ns
|
// Leave WR low for at least 60ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
if (romType == 252 || romType == 253) {
|
if (romType == 252 || romType == 253) {
|
||||||
// Pull WR(PH5) HIGH
|
// Pull WR(PH5) HIGH
|
||||||
@ -688,8 +705,7 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
|||||||
PORTH |= (1 << 3);
|
PORTH |= (1 << 3);
|
||||||
// Pull CLK(PH1) LOW (for GB CAM)
|
// Pull CLK(PH1) LOW (for GB CAM)
|
||||||
PORTH &= ~(1 << 1);
|
PORTH &= ~(1 << 1);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Pull WR(PH5) HIGH
|
// Pull WR(PH5) HIGH
|
||||||
PORTH |= (1 << 5);
|
PORTH |= (1 << 5);
|
||||||
// Pull CS(PH3) CLK(PH1)(for FRAM MOD) HIGH
|
// 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
|
// 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
|
// Switch data pins to input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
@ -829,8 +848,7 @@ void getCartInfo_GB() {
|
|||||||
}
|
}
|
||||||
if (sramSize == 1) {
|
if (sramSize == 1) {
|
||||||
lastByte = 0xA7FF;
|
lastByte = 0xA7FF;
|
||||||
}
|
} else if (sramSize > 1) {
|
||||||
else if (sramSize > 1) {
|
|
||||||
lastByte = 0xBFFF;
|
lastByte = 0xBFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,21 +908,13 @@ void getCartInfo_GB() {
|
|||||||
|
|
||||||
// MMM01 (Mani 4 in 1)
|
// MMM01 (Mani 4 in 1)
|
||||||
if (
|
if (
|
||||||
(strncmp(romName, "BOUKENJIMA2 SET", 15) == 0) && (sdBuffer[0x14D] == 0) ||
|
(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, "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;
|
romType = 0x0B;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MBC1M
|
// MBC1M
|
||||||
if (
|
if (
|
||||||
(strncmp(romName, "MOMOCOL", 7) == 0) && (sdBuffer[0x14D] == 0x28) ||
|
(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, "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;
|
romType += 0x100;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,7 +958,7 @@ void readROM_GB() {
|
|||||||
|
|
||||||
//Initialize progress bar
|
//Initialize progress bar
|
||||||
uint32_t processedProgressBar = 0;
|
uint32_t processedProgressBar = 0;
|
||||||
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
uint32_t totalProgressBar = (uint32_t)(romBanks)*16384;
|
||||||
draw_progressbar(0, totalProgressBar);
|
draw_progressbar(0, totalProgressBar);
|
||||||
|
|
||||||
// M161 banks are double size and start with 0
|
// M161 banks are double size and start with 0
|
||||||
@ -1028,13 +1038,11 @@ void readROM_GB() {
|
|||||||
// for every 4Mbits ROM, restart from 0x0000
|
// for every 4Mbits ROM, restart from 0x0000
|
||||||
romAddress = 0x0000;
|
romAddress = 0x0000;
|
||||||
currBank++;
|
currBank++;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writeByte_GB(0x6000, 0);
|
writeByte_GB(0x6000, 0);
|
||||||
writeByte_GB(0x2000, (currBank & 0x1f));
|
writeByte_GB(0x2000, (currBank & 0x1f));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if ((romType >= 0x19 && romType <= 0x1E) && (currBank == 0 || currBank == 256)) {
|
if ((romType >= 0x19 && romType <= 0x1E) && (currBank == 0 || currBank == 256)) {
|
||||||
writeByte_GB(0x3000, (currBank >> 8) & 0xFF);
|
writeByte_GB(0x3000, (currBank >> 8) & 0xFF);
|
||||||
}
|
}
|
||||||
@ -1065,7 +1073,7 @@ void readROM_GB() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate checksum
|
// Calculate checksum
|
||||||
unsigned int calc_checksum_GB (char* fileName, char* folder) {
|
unsigned int calc_checksum_GB(char* fileName, char* folder) {
|
||||||
unsigned int calcChecksum = 0;
|
unsigned int calcChecksum = 0;
|
||||||
// int calcFilesize = 0; // unused
|
// int calcFilesize = 0; // unused
|
||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
@ -1115,8 +1123,7 @@ void compare_checksums_GB() {
|
|||||||
print_Msg(calcsumStr);
|
print_Msg(calcsumStr);
|
||||||
if (strcmp(calcsumStr, checksumStr) == 0) {
|
if (strcmp(calcsumStr, checksumStr) == 0) {
|
||||||
println_Msg(F(" -> OK"));
|
println_Msg(F(" -> OK"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F(" != "));
|
print_Msg(F(" != "));
|
||||||
println_Msg(checksumStr);
|
println_Msg(checksumStr);
|
||||||
print_Error(F("Invalid Checksum"), false);
|
print_Error(F("Invalid Checksum"), false);
|
||||||
@ -1188,8 +1195,7 @@ void readSRAM_GB() {
|
|||||||
print_Msg(folder);
|
print_Msg(folder);
|
||||||
println_Msg(F("/"));
|
println_Msg(F("/"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Cart has no SRAM"), false);
|
print_Error(F("Cart has no SRAM"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1232,12 +1238,10 @@ void writeSRAM_GB() {
|
|||||||
println_Msg(F("SRAM writing finished"));
|
println_Msg(F("SRAM writing finished"));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("File doesnt exist"), false);
|
print_Error(F("File doesnt exist"), false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Cart has no SRAM"), false);
|
print_Error(F("Cart has no SRAM"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1256,8 +1260,8 @@ unsigned long verifySRAM_GB() {
|
|||||||
|
|
||||||
// Check SRAM size
|
// Check SRAM size
|
||||||
if (lastByte > 0) {
|
if (lastByte > 0) {
|
||||||
if (romType <= 4) { // MBC1
|
if (romType <= 4) { // MBC1
|
||||||
writeByte_GB(0x6000, 1); // Set RAM Mode
|
writeByte_GB(0x6000, 1); // Set RAM Mode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise MBC
|
// Initialise MBC
|
||||||
@ -1284,8 +1288,7 @@ unsigned long verifySRAM_GB() {
|
|||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
return writeErrors;
|
return writeErrors;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Can't open file"), true);
|
print_Error(F("Can't open file"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1464,8 +1467,7 @@ void writeSRAMFLASH_MBC6_GB() {
|
|||||||
print_Error(F("Error erasing FLASH sector."), true);
|
print_Error(F("Error erasing FLASH sector."), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writeByte_GB(0x2800, 0x08);
|
writeByte_GB(0x2800, 0x08);
|
||||||
writeByte_GB(0x3800, 0x08);
|
writeByte_GB(0x3800, 0x08);
|
||||||
writeByte_GB(0x2000, currBank);
|
writeByte_GB(0x2000, currBank);
|
||||||
@ -1521,8 +1523,7 @@ void writeSRAMFLASH_MBC6_GB() {
|
|||||||
myFile.close();
|
myFile.close();
|
||||||
println_Msg(F("Save writing finished"));
|
println_Msg(F("Save writing finished"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("File doesnt exist"), false);
|
print_Error(F("File doesnt exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1606,36 +1607,31 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
print_Msg(romBanks);
|
print_Msg(romBanks);
|
||||||
println_Msg(F("/256"));
|
println_Msg(F("/256"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else if (strcmp(flashid, "0141") == 0) {
|
||||||
else if (strcmp(flashid, "0141") == 0) {
|
|
||||||
println_Msg(F("AM29F032B"));
|
println_Msg(F("AM29F032B"));
|
||||||
print_Msg(F("Banks: "));
|
print_Msg(F("Banks: "));
|
||||||
print_Msg(romBanks);
|
print_Msg(romBanks);
|
||||||
println_Msg(F("/256"));
|
println_Msg(F("/256"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else if (strcmp(flashid, "01AD") == 0) {
|
||||||
else if (strcmp(flashid, "01AD") == 0) {
|
|
||||||
println_Msg(F("AM29F016B"));
|
println_Msg(F("AM29F016B"));
|
||||||
print_Msg(F("Banks: "));
|
print_Msg(F("Banks: "));
|
||||||
print_Msg(romBanks);
|
print_Msg(romBanks);
|
||||||
println_Msg(F("/128"));
|
println_Msg(F("/128"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else if (strcmp(flashid, "04AD") == 0) {
|
||||||
else if (strcmp(flashid, "04AD") == 0) {
|
|
||||||
println_Msg(F("AM29F016D"));
|
println_Msg(F("AM29F016D"));
|
||||||
print_Msg(F("Banks: "));
|
print_Msg(F("Banks: "));
|
||||||
print_Msg(romBanks);
|
print_Msg(romBanks);
|
||||||
println_Msg(F("/128"));
|
println_Msg(F("/128"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else if (strcmp(flashid, "01D5") == 0) {
|
||||||
else if (strcmp(flashid, "01D5") == 0) {
|
|
||||||
println_Msg(F("AM29F080B"));
|
println_Msg(F("AM29F080B"));
|
||||||
print_Msg(F("Banks: "));
|
print_Msg(F("Banks: "));
|
||||||
print_Msg(romBanks);
|
print_Msg(romBanks);
|
||||||
println_Msg(F("/64"));
|
println_Msg(F("/64"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Flash ID: "));
|
print_Msg(F("Flash ID: "));
|
||||||
println_Msg(flashid);
|
println_Msg(flashid);
|
||||||
display_Update();
|
display_Update();
|
||||||
@ -1703,7 +1699,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
|
|
||||||
//Initialize progress bar
|
//Initialize progress bar
|
||||||
uint32_t processedProgressBar = 0;
|
uint32_t processedProgressBar = 0;
|
||||||
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
uint32_t totalProgressBar = (uint32_t)(romBanks)*16384;
|
||||||
draw_progressbar(0, totalProgressBar);
|
draw_progressbar(0, totalProgressBar);
|
||||||
|
|
||||||
for (int currBank = 0; currBank < romBanks; currBank++) {
|
for (int currBank = 0; currBank < romBanks; currBank++) {
|
||||||
@ -1753,7 +1749,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
// Write flash
|
// Write flash
|
||||||
//Initialize progress bar
|
//Initialize progress bar
|
||||||
uint32_t processedProgressBar = 0;
|
uint32_t processedProgressBar = 0;
|
||||||
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
uint32_t totalProgressBar = (uint32_t)(romBanks)*16384;
|
||||||
draw_progressbar(0, totalProgressBar);
|
draw_progressbar(0, totalProgressBar);
|
||||||
|
|
||||||
for (int currBank = 0; currBank < romBanks; currBank++) {
|
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
|
// Read number of banks and switch banks
|
||||||
for (word bank = 1; bank < romBanks; bank++) {
|
for (word bank = 1; bank < romBanks; bank++) {
|
||||||
if (romType >= 5) { // MBC2 and above
|
if (romType >= 5) { // MBC2 and above
|
||||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||||
}
|
} else { // MBC1
|
||||||
else { // MBC1
|
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
writeByte_GB(0x4000, bank >> 5); // Set bits 5 & 6 (01100000) of ROM bank
|
||||||
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
|
||||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bank > 1) {
|
if (bank > 1) {
|
||||||
@ -1839,15 +1834,13 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
if (writeErrors == 0) {
|
if (writeErrors == 0) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Error"));
|
println_Msg(F("Error"));
|
||||||
print_Msg(writeErrors);
|
print_Msg(writeErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
print_Error(F("did not verify."), true);
|
print_Error(F("did not verify."), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file"));
|
println_Msg(F("Can't open file"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -1890,15 +1883,15 @@ byte writeByteCompensated(int address, byte data) {
|
|||||||
|
|
||||||
void startCFIMode(boolean x16Mode) {
|
void startCFIMode(boolean x16Mode) {
|
||||||
if (x16Mode) {
|
if (x16Mode) {
|
||||||
writeByte_GB(0x555, 0xf0); //x16 mode reset command
|
writeByte_GB(0x555, 0xf0); //x16 mode reset command
|
||||||
delay(500);
|
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);
|
delay(500);
|
||||||
writeByte_GB(0x55, 0x98); //x16 CFI Query command
|
writeByte_GB(0x55, 0x98); //x16 CFI Query command
|
||||||
} else {
|
} else {
|
||||||
writeByte_GB(0xAAA, 0xf0); //x8 mode reset command
|
writeByte_GB(0xAAA, 0xf0); //x8 mode reset command
|
||||||
delay(100);
|
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);
|
delay(100);
|
||||||
writeByte_GB(0xAA, 0x98); //x8 CFI Query command
|
writeByte_GB(0xAA, 0x98); //x8 CFI Query command
|
||||||
}
|
}
|
||||||
@ -1910,42 +1903,42 @@ void startCFIMode(boolean x16Mode) {
|
|||||||
void identifyCFI_GB() {
|
void identifyCFI_GB() {
|
||||||
// Reset flash
|
// Reset flash
|
||||||
display_Clear();
|
display_Clear();
|
||||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||||
writeByte_GB(0x2000, 0); // Set Bank to 0
|
writeByte_GB(0x2000, 0); // Set Bank to 0
|
||||||
writeByte_GB(0x3000, 0);
|
writeByte_GB(0x3000, 0);
|
||||||
|
|
||||||
startCFIMode(false); // Trying x8 mode first
|
startCFIMode(false); // Trying x8 mode first
|
||||||
|
|
||||||
display_Clear();
|
display_Clear();
|
||||||
// Try x8 mode first
|
// Try x8 mode first
|
||||||
char cfiQRYx8[7];
|
char cfiQRYx8[7];
|
||||||
char cfiQRYx16[7];
|
char cfiQRYx16[7];
|
||||||
sprintf(cfiQRYx8, "%02X%02X%02X", readByte_GB(0x20), readByte_GB(0x22), readByte_GB(0x24));
|
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
|
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
|
if (strcmp(cfiQRYx8, "515259") == 0) { // QRY in x8 mode
|
||||||
println_Msg(F("Normal CFI x8 Mode"));
|
println_Msg(F("Normal CFI x8 Mode"));
|
||||||
flashX16Mode = false;
|
flashX16Mode = false;
|
||||||
flashSwitchLastBits = 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"));
|
println_Msg(F("Switched CFI x8 Mode"));
|
||||||
flashX16Mode = false;
|
flashX16Mode = false;
|
||||||
flashSwitchLastBits = true;
|
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"));
|
println_Msg(F("Normal CFI x16 Mode"));
|
||||||
flashX16Mode = true;
|
flashX16Mode = true;
|
||||||
flashSwitchLastBits = false;
|
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"));
|
println_Msg(F("Switched CFI x16 Mode"));
|
||||||
flashX16Mode = true;
|
flashX16Mode = true;
|
||||||
flashSwitchLastBits = true;
|
flashSwitchLastBits = true;
|
||||||
} else {
|
} 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));
|
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"));
|
println_Msg(F("Normal CFI x16 Mode"));
|
||||||
flashX16Mode = true;
|
flashX16Mode = true;
|
||||||
flashSwitchLastBits = false;
|
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"));
|
println_Msg(F("Switched CFI x16 Mode"));
|
||||||
flashX16Mode = true;
|
flashX16Mode = true;
|
||||||
flashSwitchLastBits = true;
|
flashSwitchLastBits = true;
|
||||||
@ -1956,7 +1949,7 @@ void identifyCFI_GB() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flashBanks = 1 << (readByteCompensated(0x4E) - 14); // - flashX16Mode);
|
flashBanks = 1 << (readByteCompensated(0x4E) - 14); // - flashX16Mode);
|
||||||
|
|
||||||
// Reset flash
|
// Reset flash
|
||||||
writeByteCompensated(0xAAA, 0xf0);
|
writeByteCompensated(0xAAA, 0xf0);
|
||||||
@ -2134,12 +2127,12 @@ bool writeCFI_GB() {
|
|||||||
while ((PINC & 0x80) != (sdBuffer[currByte] & 0x80)) {
|
while ((PINC & 0x80) != (sdBuffer[currByte] & 0x80)) {
|
||||||
i++;
|
i++;
|
||||||
if (i > 500) {
|
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--;
|
currByte--;
|
||||||
currAddr += 0x4000;
|
currAddr += 0x4000;
|
||||||
endAddr = 0x7FFF;
|
endAddr = 0x7FFF;
|
||||||
break;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2147,8 +2140,7 @@ bool writeCFI_GB() {
|
|||||||
|
|
||||||
// Switch CS(PH3) and OE/RD(PH6) to HIGH
|
// Switch CS(PH3) and OE/RD(PH6) to HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 6);
|
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;
|
currAddr += 512;
|
||||||
}
|
}
|
||||||
@ -2168,13 +2160,12 @@ bool writeCFI_GB() {
|
|||||||
|
|
||||||
// Read number of banks and switch banks
|
// Read number of banks and switch banks
|
||||||
for (word bank = 1; bank < romBanks; bank++) {
|
for (word bank = 1; bank < romBanks; bank++) {
|
||||||
if (romType >= 5) { // MBC2 and above
|
if (romType >= 5) { // MBC2 and above
|
||||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||||
}
|
} else { // MBC1
|
||||||
else { // MBC1
|
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
writeByte_GB(0x4000, bank >> 5); // Set bits 5 & 6 (01100000) of ROM bank
|
||||||
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
|
||||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bank > 1) {
|
if (bank > 1) {
|
||||||
@ -2202,15 +2193,13 @@ bool writeCFI_GB() {
|
|||||||
if (writeErrors == 0) {
|
if (writeErrors == 0) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(writeErrors);
|
print_Msg(writeErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
print_Error(F("did not verify."), false);
|
print_Error(F("did not verify."), false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Can't open file"));
|
println_Msg(F("Can't open file"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -2221,4 +2210,4 @@ bool writeCFI_GB() {
|
|||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
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 gbmMenuItem5[] PROGMEM = "Write Flash";
|
||||||
static const char gbmMenuItem6[] PROGMEM = "Read Mapping";
|
static const char gbmMenuItem6[] PROGMEM = "Read Mapping";
|
||||||
static const char gbmMenuItem7[] PROGMEM = "Write 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() {
|
void gbmMenu() {
|
||||||
// create menu with title and 7 options to choose from
|
// 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);
|
mainMenu = question_box(F("GB Memory Menu"), menuOptions, 7, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
// Read Flash ID
|
// Read Flash ID
|
||||||
case 0:
|
case 0:
|
||||||
// Clear screen
|
// Clear screen
|
||||||
@ -87,8 +86,7 @@ void gbmMenu() {
|
|||||||
if (blankcheckFlash_GBM()) {
|
if (blankcheckFlash_GBM()) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("ERROR"));
|
println_Msg(F("ERROR"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
@ -163,8 +161,7 @@ void gbmMenu() {
|
|||||||
if (blankcheckMapping_GBM()) {
|
if (blankcheckMapping_GBM()) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Erasing failed"), false);
|
print_Error(F("Erasing failed"), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -211,7 +208,26 @@ void setup_GBM() {
|
|||||||
while (readByte_GBM(0x120) != 0x21) {
|
while (readByte_GBM(0x120) != 0x21) {
|
||||||
// Enable ports 0x120h (F2)
|
// Enable ports 0x120h (F2)
|
||||||
send_GBM(0x09);
|
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++;
|
timeout++;
|
||||||
if (timeout > 10) {
|
if (timeout > 10) {
|
||||||
println_Msg(F("Error: Time Out"));
|
println_Msg(F("Error: Time Out"));
|
||||||
@ -230,13 +246,19 @@ byte readByte_GBM(word myAddress) {
|
|||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 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
|
// Switch CS(PH3) and RD(PH6) to LOW
|
||||||
PORTH &= ~(1 << 3);
|
PORTH &= ~(1 << 3);
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = PINC;
|
||||||
@ -260,13 +282,19 @@ void writeByte_GBM(word myAddress, byte myData) {
|
|||||||
PORTH &= ~(1 << 3);
|
PORTH &= ~(1 << 3);
|
||||||
PORTH &= ~(1 << 5);
|
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
|
// Pull CS(PH3) and write(PH5) high
|
||||||
PORTH |= (1 << 5);
|
PORTH |= (1 << 5);
|
||||||
PORTH |= (1 << 3);
|
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??!)
|
// Set data pins to Input (or read errors??!)
|
||||||
DDRC = 0x0;
|
DDRC = 0x0;
|
||||||
@ -306,8 +334,7 @@ void readROM_GBM(word numBanks) {
|
|||||||
// Open file on sd card
|
// Open file on sd card
|
||||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||||
print_Error(F("Can't create file on SD"), true);
|
print_Error(F("Can't create file on SD"), true);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Read rom
|
// Read rom
|
||||||
word currAddress = 0;
|
word currAddress = 0;
|
||||||
|
|
||||||
@ -472,8 +499,7 @@ boolean readFlashID_GBM() {
|
|||||||
display_Update();
|
display_Update();
|
||||||
resetFlash_GBM();
|
resetFlash_GBM();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Flash ID: "));
|
print_Msg(F("Flash ID: "));
|
||||||
println_Msg(flashid);
|
println_Msg(flashid);
|
||||||
print_Error(F("Unknown Flash ID"), true);
|
print_Error(F("Unknown Flash ID"), true);
|
||||||
@ -652,8 +678,7 @@ void writeFlash_GBM() {
|
|||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
println_Msg(F("Done"));
|
println_Msg(F("Done"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Can't open file"), false);
|
print_Error(F("Can't open file"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,8 +717,7 @@ void readMapping_GBM() {
|
|||||||
// Open file on sd card
|
// Open file on sd card
|
||||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||||
print_Error(F("Can't create file on SD"), true);
|
print_Error(F("Can't create file on SD"), true);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (byte currByte = 0; currByte < 128; currByte++) {
|
for (byte currByte = 0; currByte < 128; currByte++) {
|
||||||
sdBuffer[currByte] = readByte_GBM(currByte);
|
sdBuffer[currByte] = readByte_GBM(currByte);
|
||||||
}
|
}
|
||||||
@ -868,8 +892,7 @@ void writeMapping_GBM() {
|
|||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
println_Msg(F("Done"));
|
println_Msg(F("Done"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Can't open file"), false);
|
print_Error(F("Can't open file"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -878,4 +901,4 @@ void writeMapping_GBM() {
|
|||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -3,7 +3,7 @@
|
|||||||
// Supports 32M cart with LH28F016SUT flash
|
// Supports 32M cart with LH28F016SUT flash
|
||||||
//******************************************
|
//******************************************
|
||||||
#ifdef enable_GBX
|
#ifdef enable_GBX
|
||||||
#define GB_SMART_GAMES_PER_PAGE 6
|
#define GB_SMART_GAMES_PER_PAGE 6
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
Menu
|
Menu
|
||||||
@ -12,19 +12,19 @@
|
|||||||
static const char gbSmartMenuItem1[] PROGMEM = "Game Menu";
|
static const char gbSmartMenuItem1[] PROGMEM = "Game Menu";
|
||||||
static const char gbSmartMenuItem2[] PROGMEM = "Flash Menu";
|
static const char gbSmartMenuItem2[] PROGMEM = "Flash Menu";
|
||||||
static const char gbSmartMenuItem3[] PROGMEM = "Reset";
|
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 gbSmartFlashMenuItem1[] PROGMEM = "Read Flash";
|
||||||
static const char gbSmartFlashMenuItem2[] PROGMEM = "Write Flash";
|
static const char gbSmartFlashMenuItem2[] PROGMEM = "Write Flash";
|
||||||
static const char gbSmartFlashMenuItem3[] PROGMEM = "Back";
|
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 gbSmartGameMenuItem1[] PROGMEM = "Read Game";
|
||||||
static const char gbSmartGameMenuItem2[] PROGMEM = "Read SRAM";
|
static const char gbSmartGameMenuItem2[] PROGMEM = "Read SRAM";
|
||||||
static const char gbSmartGameMenuItem3[] PROGMEM = "Write SRAM";
|
static const char gbSmartGameMenuItem3[] PROGMEM = "Write SRAM";
|
||||||
static const char gbSmartGameMenuItem4[] PROGMEM = "Switch Game";
|
static const char gbSmartGameMenuItem4[] PROGMEM = "Switch Game";
|
||||||
static const char gbSmartGameMenuItem5[] PROGMEM = "Reset";
|
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
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -80,8 +80,7 @@ boolean compare_checksum_GBS() {
|
|||||||
println_Msg(F("Checksum matches"));
|
println_Msg(F("Checksum matches"));
|
||||||
display_Update();
|
display_Update();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Result: "));
|
print_Msg(F("Result: "));
|
||||||
println_Msg(calcsumStr);
|
println_Msg(calcsumStr);
|
||||||
print_Error(F("Checksum Error"), false);
|
print_Error(F("Checksum Error"), false);
|
||||||
@ -93,12 +92,18 @@ byte readByte_GBS(word myAddress) {
|
|||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 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
|
// Switch CS(PH3) and RD(PH6) to LOW
|
||||||
PORTH &= ~((1 << 3) | (1 << 6));
|
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
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = PINC;
|
||||||
@ -106,13 +111,15 @@ byte readByte_GBS(word myAddress) {
|
|||||||
// Switch CS(PH3) and RD(PH6) to HIGH
|
// Switch CS(PH3) and RD(PH6) to HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 6);
|
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;
|
return tempByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_GBSmart()
|
void setup_GBSmart() {
|
||||||
{
|
|
||||||
// take from setup_GB
|
// take from setup_GB
|
||||||
// Set RST(PH0) to Input
|
// Set RST(PH0) to Input
|
||||||
DDRH &= ~(1 << 0);
|
DDRH &= ~(1 << 0);
|
||||||
@ -150,8 +157,7 @@ void setup_GBSmart()
|
|||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartMenu()
|
void gbSmartMenu() {
|
||||||
{
|
|
||||||
uint8_t mainMenu;
|
uint8_t mainMenu;
|
||||||
|
|
||||||
// Copy menuOptions out of progmem
|
// Copy menuOptions out of progmem
|
||||||
@ -159,8 +165,7 @@ void gbSmartMenu()
|
|||||||
mainMenu = question_box(F("GB Smart"), menuOptions, 3, 0);
|
mainMenu = question_box(F("GB Smart"), menuOptions, 3, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
gbSmartGameMenu();
|
gbSmartGameMenu();
|
||||||
@ -173,22 +178,20 @@ void gbSmartMenu()
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
asm volatile (" jmp 0");
|
asm volatile(" jmp 0");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartGameOptions()
|
void gbSmartGameOptions() {
|
||||||
{
|
|
||||||
uint8_t gameSubMenu;
|
uint8_t gameSubMenu;
|
||||||
|
|
||||||
convertPgm(menuOptionsGBSmartGame, 5);
|
convertPgm(menuOptionsGBSmartGame, 5);
|
||||||
gameSubMenu = question_box(F("GB Smart Game Menu"), menuOptions, 5, 0);
|
gameSubMenu = question_box(F("GB Smart Game Menu"), menuOptions, 5, 0);
|
||||||
|
|
||||||
switch (gameSubMenu)
|
switch (gameSubMenu) {
|
||||||
{
|
case 0: // Read Game
|
||||||
case 0: // Read Game
|
|
||||||
{
|
{
|
||||||
display_Clear();
|
display_Clear();
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -196,26 +199,23 @@ void gbSmartGameOptions()
|
|||||||
compare_checksum_GBS();
|
compare_checksum_GBS();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: // Read SRAM
|
case 1: // Read SRAM
|
||||||
{
|
{
|
||||||
display_Clear();
|
display_Clear();
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
readSRAM_GB();
|
readSRAM_GB();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: // Write SRAM
|
case 2: // Write SRAM
|
||||||
{
|
{
|
||||||
display_Clear();
|
display_Clear();
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
writeSRAM_GB();
|
writeSRAM_GB();
|
||||||
uint32_t wrErrors = verifySRAM_GB();
|
uint32_t wrErrors = verifySRAM_GB();
|
||||||
if (wrErrors == 0)
|
if (wrErrors == 0) {
|
||||||
{
|
|
||||||
println_Msg(F("Verified OK"));
|
println_Msg(F("Verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(wrErrors);
|
print_Msg(wrErrors);
|
||||||
println_Msg(F(" bytes"));
|
println_Msg(F(" bytes"));
|
||||||
@ -223,7 +223,7 @@ void gbSmartGameOptions()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: // Switch Game
|
case 3: // Switch Game
|
||||||
{
|
{
|
||||||
gameMenuStartBank = 0x02;
|
gameMenuStartBank = 0x02;
|
||||||
gbSmartGameMenu();
|
gbSmartGameMenu();
|
||||||
@ -231,13 +231,12 @@ void gbSmartGameOptions()
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
asm volatile (" jmp 0");
|
asm volatile(" jmp 0");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameSubMenu != 3)
|
if (gameSubMenu != 3) {
|
||||||
{
|
|
||||||
println_Msg(F(""));
|
println_Msg(F(""));
|
||||||
println_Msg(F("Press Button..."));
|
println_Msg(F("Press Button..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
@ -245,8 +244,7 @@ void gbSmartGameOptions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartGameMenu()
|
void gbSmartGameMenu() {
|
||||||
{
|
|
||||||
uint8_t gameSubMenu = 0;
|
uint8_t gameSubMenu = 0;
|
||||||
gb_smart_load_more_games:
|
gb_smart_load_more_games:
|
||||||
if (gameMenuStartBank > 0xfe)
|
if (gameMenuStartBank > 0xfe)
|
||||||
@ -254,8 +252,7 @@ gb_smart_load_more_games:
|
|||||||
|
|
||||||
gbSmartGetGames();
|
gbSmartGetGames();
|
||||||
|
|
||||||
if (hasMenu)
|
if (hasMenu) {
|
||||||
{
|
|
||||||
char menuOptionsGBSmartGames[7][20];
|
char menuOptionsGBSmartGames[7][20];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < numGames; i++)
|
for (; i < numGames; i++)
|
||||||
@ -266,9 +263,7 @@ gb_smart_load_more_games:
|
|||||||
|
|
||||||
if (gameSubMenu >= i)
|
if (gameSubMenu >= i)
|
||||||
goto gb_smart_load_more_games;
|
goto gb_smart_load_more_games;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
gameSubMenu = 0;
|
gameSubMenu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,15 +278,13 @@ gb_smart_load_more_games:
|
|||||||
mode = mode_GB_GBSmart_Game;
|
mode = mode_GB_GBSmart_Game;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartFlashMenu()
|
void gbSmartFlashMenu() {
|
||||||
{
|
|
||||||
uint8_t flashSubMenu;
|
uint8_t flashSubMenu;
|
||||||
|
|
||||||
convertPgm(menuOptionsGBSmartFlash, 3);
|
convertPgm(menuOptionsGBSmartFlash, 3);
|
||||||
flashSubMenu = question_box(F("GB Smart Flash Menu"), menuOptions, 3, 0);
|
flashSubMenu = question_box(F("GB Smart Flash Menu"), menuOptions, 3, 0);
|
||||||
|
|
||||||
switch (flashSubMenu)
|
switch (flashSubMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
// read flash
|
// read flash
|
||||||
@ -343,9 +336,8 @@ void gbSmartFlashMenu()
|
|||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartGetGames()
|
void gbSmartGetGames() {
|
||||||
{
|
static const byte menu_title[] = { 0x47, 0x42, 0x31, 0x36, 0x4d };
|
||||||
static const byte menu_title[] = {0x47, 0x42, 0x31, 0x36, 0x4d};
|
|
||||||
|
|
||||||
// reset remap setting
|
// reset remap setting
|
||||||
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
||||||
@ -356,19 +348,15 @@ void gbSmartGetGames()
|
|||||||
// check if contain menu
|
// check if contain menu
|
||||||
hasMenu = true;
|
hasMenu = true;
|
||||||
dataIn();
|
dataIn();
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++) {
|
||||||
{
|
if (readByte_GBS(0x0134 + i) != menu_title[i]) {
|
||||||
if (readByte_GBS(0x0134 + i) != menu_title[i])
|
|
||||||
{
|
|
||||||
hasMenu = false;
|
hasMenu = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasMenu)
|
if (hasMenu) {
|
||||||
{
|
for (i = gameMenuStartBank, numGames = 0; i < gbSmartBanks && numGames < GB_SMART_GAMES_PER_PAGE;) {
|
||||||
for (i = gameMenuStartBank, numGames = 0; i < gbSmartBanks && numGames < GB_SMART_GAMES_PER_PAGE; )
|
|
||||||
{
|
|
||||||
myLength = 0;
|
myLength = 0;
|
||||||
|
|
||||||
// switch bank
|
// switch bank
|
||||||
@ -377,21 +365,17 @@ void gbSmartGetGames()
|
|||||||
|
|
||||||
dataIn();
|
dataIn();
|
||||||
// read signature
|
// read signature
|
||||||
for (uint8_t j = 0x00; j < 0x30; j++)
|
for (uint8_t j = 0x00; j < 0x30; j++) {
|
||||||
{
|
if (readByte_GBS(0x4104 + j) != signature[j]) {
|
||||||
if (readByte_GBS(0x4104 + j) != signature[j])
|
|
||||||
{
|
|
||||||
i += 0x02;
|
i += 0x02;
|
||||||
goto gb_smart_get_game_loop_end;
|
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);
|
myByte = readByte_GBS(0x4134 + j);
|
||||||
|
|
||||||
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) ||
|
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) || (char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
||||||
(char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
|
||||||
gbSmartGames[numGames].title[myLength++] = char(myByte);
|
gbSmartGames[numGames].title[myLength++] = char(myByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,16 +392,12 @@ gb_smart_get_game_loop_end:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
gameMenuStartBank = i;
|
gameMenuStartBank = i;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
dataIn();
|
dataIn();
|
||||||
for (uint8_t j = 0; j < 15; j++)
|
for (uint8_t j = 0; j < 15; j++) {
|
||||||
{
|
|
||||||
myByte = readByte_GBS(0x0134 + j);
|
myByte = readByte_GBS(0x0134 + j);
|
||||||
|
|
||||||
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) ||
|
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) || (char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
||||||
(char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
|
|
||||||
gbSmartGames[0].title[myLength++] = char(myByte);
|
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(F("Saving as GB/GBS/"));
|
||||||
print_Msg(fileName);
|
print_Msg(fileName);
|
||||||
println_Msg(F("..."));
|
println_Msg(F("..."));
|
||||||
@ -451,8 +430,7 @@ void gbSmartReadFlash()
|
|||||||
|
|
||||||
// dump fixed bank 0x00
|
// dump fixed bank 0x00
|
||||||
dataIn();
|
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++)
|
for (uint16_t c = 0; c < 512; c++)
|
||||||
sdBuffer[c] = readByte_GBS(addr + c);
|
sdBuffer[c] = readByte_GBS(addr + c);
|
||||||
|
|
||||||
@ -460,14 +438,12 @@ void gbSmartReadFlash()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read rest banks
|
// read rest banks
|
||||||
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++)
|
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++) {
|
||||||
{
|
|
||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, bank);
|
writeByte_GB(0x2100, bank);
|
||||||
|
|
||||||
dataIn();
|
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++)
|
for (uint16_t c = 0; c < 512; c++)
|
||||||
sdBuffer[c] = readByte_GBS(addr + c);
|
sdBuffer[c] = readByte_GBS(addr + c);
|
||||||
|
|
||||||
@ -484,10 +460,8 @@ void gbSmartReadFlash()
|
|||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartWriteFlash()
|
void gbSmartWriteFlash() {
|
||||||
{
|
for (int bank = 0x00; bank < gbSmartBanks; bank += gbSmartBanksPerFlashChip) {
|
||||||
for (int bank = 0x00; bank < gbSmartBanks; bank += gbSmartBanksPerFlashChip)
|
|
||||||
{
|
|
||||||
display_Clear();
|
display_Clear();
|
||||||
|
|
||||||
print_Msg(F("Erasing..."));
|
print_Msg(F("Erasing..."));
|
||||||
@ -517,13 +491,10 @@ void gbSmartWriteFlash()
|
|||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
writeErrors = gbSmartVerifyFlash();
|
writeErrors = gbSmartVerifyFlash();
|
||||||
if (writeErrors == 0)
|
if (writeErrors == 0) {
|
||||||
{
|
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(writeErrors);
|
print_Msg(writeErrors);
|
||||||
println_Msg(F(" bytes "));
|
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))
|
if (!myFile.open(filePath, O_READ))
|
||||||
print_Error(F("Can't open file on SD"), true);
|
print_Error(F("Can't open file on SD"), true);
|
||||||
|
|
||||||
@ -550,8 +520,7 @@ void gbSmartWriteFlash(uint32_t start_bank)
|
|||||||
gbSmartWriteFlashFromMyFile(0x0000);
|
gbSmartWriteFlashFromMyFile(0x0000);
|
||||||
|
|
||||||
// handle rest banks on 0x4000
|
// handle rest banks on 0x4000
|
||||||
for (uint8_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++)
|
for (uint8_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++) {
|
||||||
{
|
|
||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, bank);
|
writeByte_GB(0x2100, bank);
|
||||||
|
|
||||||
@ -562,17 +531,15 @@ void gbSmartWriteFlash(uint32_t start_bank)
|
|||||||
println_Msg("");
|
println_Msg("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartWriteFlashFromMyFile(uint32_t addr)
|
void gbSmartWriteFlashFromMyFile(uint32_t addr) {
|
||||||
{
|
for (uint16_t i = 0; i < 16384; i += 256) {
|
||||||
for (uint16_t i = 0; i < 16384; i += 256)
|
|
||||||
{
|
|
||||||
myFile.read(sdBuffer, 256);
|
myFile.read(sdBuffer, 256);
|
||||||
|
|
||||||
// sequence load to page
|
// sequence load to page
|
||||||
dataOut();
|
dataOut();
|
||||||
gbSmartWriteFlashByte(addr, 0xe0);
|
gbSmartWriteFlashByte(addr, 0xe0);
|
||||||
gbSmartWriteFlashByte(addr, 0xff);
|
gbSmartWriteFlashByte(addr, 0xff);
|
||||||
gbSmartWriteFlashByte(addr, 0x00); // BCH should be 0x00
|
gbSmartWriteFlashByte(addr, 0x00); // BCH should be 0x00
|
||||||
|
|
||||||
// fill page buffer
|
// fill page buffer
|
||||||
for (int d = 0; d < 256; d++)
|
for (int d = 0; d < 256; d++)
|
||||||
@ -585,53 +552,45 @@ void gbSmartWriteFlashFromMyFile(uint32_t addr)
|
|||||||
|
|
||||||
// waiting for finishing
|
// waiting for finishing
|
||||||
dataIn();
|
dataIn();
|
||||||
while ((readByte_GBS(addr + i) & 0x80) == 0x00);
|
while ((readByte_GBS(addr + i) & 0x80) == 0x00)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// blink LED
|
// blink LED
|
||||||
blinkLED();
|
blinkLED();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gbSmartVerifyFlash()
|
uint32_t gbSmartVerifyFlash() {
|
||||||
{
|
|
||||||
uint32_t verified = 0;
|
uint32_t verified = 0;
|
||||||
|
|
||||||
if (!myFile.open(filePath, O_READ))
|
if (!myFile.open(filePath, O_READ)) {
|
||||||
{
|
|
||||||
verified = 0xffffffff;
|
verified = 0xffffffff;
|
||||||
print_Error(F("Can't open file on SD"), false);
|
print_Error(F("Can't open file on SD"), false);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// remaps mmc to full access
|
// remaps mmc to full access
|
||||||
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
||||||
|
|
||||||
// verify bank 0x00
|
// verify bank 0x00
|
||||||
dataIn();
|
dataIn();
|
||||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512)
|
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512) {
|
||||||
{
|
|
||||||
myFile.read(sdBuffer, 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])
|
if (readByte_GBS(addr + c) != sdBuffer[c])
|
||||||
verified++;
|
verified++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify rest banks
|
// verify rest banks
|
||||||
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++)
|
for (uint16_t bank = 0x01; bank < gbSmartBanks; bank++) {
|
||||||
{
|
|
||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, bank);
|
writeByte_GB(0x2100, bank);
|
||||||
|
|
||||||
dataIn();
|
dataIn();
|
||||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512)
|
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512) {
|
||||||
{
|
|
||||||
myFile.read(sdBuffer, 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])
|
if (readByte_GBS(addr + c) != sdBuffer[c])
|
||||||
verified++;
|
verified++;
|
||||||
}
|
}
|
||||||
@ -647,27 +606,23 @@ uint32_t gbSmartVerifyFlash()
|
|||||||
return verified;
|
return verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank)
|
byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank) {
|
||||||
{
|
|
||||||
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
||||||
|
|
||||||
// check first bank
|
// check first bank
|
||||||
dataIn();
|
dataIn();
|
||||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr++)
|
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr++) {
|
||||||
{
|
|
||||||
if (readByte_GBS(addr) != 0xff)
|
if (readByte_GBS(addr) != 0xff)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check rest banks
|
// check rest banks
|
||||||
for (uint16_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++)
|
for (uint16_t bank = 0x01; bank < gbSmartBanksPerFlashChip; bank++) {
|
||||||
{
|
|
||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, bank);
|
writeByte_GB(0x2100, bank);
|
||||||
|
|
||||||
dataIn();
|
dataIn();
|
||||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr++)
|
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr++) {
|
||||||
{
|
|
||||||
if (readByte_GBS(addr) != 0xff)
|
if (readByte_GBS(addr) != 0xff)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -676,16 +631,14 @@ byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartResetFlash(uint8_t flash_start_bank)
|
void gbSmartResetFlash(uint8_t flash_start_bank) {
|
||||||
{
|
|
||||||
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
||||||
|
|
||||||
dataOut();
|
dataOut();
|
||||||
gbSmartWriteFlashByte(0x0, 0xff);
|
gbSmartWriteFlashByte(0x0, 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartEraseFlash(uint8_t flash_start_bank)
|
void gbSmartEraseFlash(uint8_t flash_start_bank) {
|
||||||
{
|
|
||||||
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
||||||
|
|
||||||
// handling first flash block
|
// handling first flash block
|
||||||
@ -694,14 +647,14 @@ void gbSmartEraseFlash(uint8_t flash_start_bank)
|
|||||||
gbSmartWriteFlashByte(0x0000, 0xd0);
|
gbSmartWriteFlashByte(0x0000, 0xd0);
|
||||||
|
|
||||||
dataIn();
|
dataIn();
|
||||||
while ((readByte_GBS(0x0000) & 0x80) == 0x00);
|
while ((readByte_GBS(0x0000) & 0x80) == 0x00)
|
||||||
|
;
|
||||||
|
|
||||||
// blink LED
|
// blink LED
|
||||||
blinkLED();
|
blinkLED();
|
||||||
|
|
||||||
// rest of flash block
|
// rest of flash block
|
||||||
for (uint32_t ba = gbSmartBanksPerFlashBlock; ba < gbSmartBanksPerFlashChip; ba += gbSmartBanksPerFlashBlock)
|
for (uint32_t ba = gbSmartBanksPerFlashBlock; ba < gbSmartBanksPerFlashChip; ba += gbSmartBanksPerFlashBlock) {
|
||||||
{
|
|
||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, ba);
|
writeByte_GB(0x2100, ba);
|
||||||
|
|
||||||
@ -709,15 +662,15 @@ void gbSmartEraseFlash(uint8_t flash_start_bank)
|
|||||||
gbSmartWriteFlashByte(0x4000, 0xd0);
|
gbSmartWriteFlashByte(0x4000, 0xd0);
|
||||||
|
|
||||||
dataIn();
|
dataIn();
|
||||||
while ((readByte_GBS(0x4000) & 0x80) == 0x00);
|
while ((readByte_GBS(0x4000) & 0x80) == 0x00)
|
||||||
|
;
|
||||||
|
|
||||||
// blink LED
|
// blink LED
|
||||||
blinkLED();
|
blinkLED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSmartWriteFlashByte(uint32_t myAddress, uint8_t myData)
|
void gbSmartWriteFlashByte(uint32_t myAddress, uint8_t myData) {
|
||||||
{
|
|
||||||
PORTF = myAddress & 0xff;
|
PORTF = myAddress & 0xff;
|
||||||
PORTK = (myAddress >> 8) & 0xff;
|
PORTK = (myAddress >> 8) & 0xff;
|
||||||
PORTC = myData;
|
PORTC = myData;
|
||||||
@ -739,8 +692,7 @@ void gbSmartWriteFlashByte(uint32_t myAddress, uint8_t myData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rom_start_bank = 0x00 means back to original state
|
// 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;
|
rom_start_bank &= 0xfe;
|
||||||
|
|
||||||
dataOut();
|
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(0x1000, 0x98);
|
||||||
writeByte_GB(0x2000, rom_start_bank);
|
writeByte_GB(0x2000, rom_start_bank);
|
||||||
|
|
||||||
if (rom_start_bank > 1)
|
if (rom_start_bank > 1) {
|
||||||
{
|
|
||||||
// start set new base bank
|
// start set new base bank
|
||||||
writeByte_GB(0x1000, 0xa5);
|
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
|
// Use for setting correct rom and sram size
|
||||||
// Code logic is take from SmartCard32M V1.3 menu code,
|
// Code logic is take from SmartCard32M V1.3 menu code,
|
||||||
// see 0x2db2 to 0x2e51 (0xa0 bytes)
|
// see 0x2db2 to 0x2e51 (0xa0 bytes)
|
||||||
uint8_t gbSmartGetResizeParam(uint8_t rom_size, uint8_t sram_size)
|
uint8_t gbSmartGetResizeParam(uint8_t rom_size, uint8_t sram_size) {
|
||||||
{
|
if (rom_size < 0x0f) {
|
||||||
if (rom_size < 0x0f)
|
|
||||||
{
|
|
||||||
rom_size &= 0x07;
|
rom_size &= 0x07;
|
||||||
rom_size ^= 0x07;
|
rom_size ^= 0x07;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
rom_size = 0x01;
|
rom_size = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sram_size > 0)
|
if (sram_size > 0) {
|
||||||
{
|
if (sram_size > 1) {
|
||||||
if (sram_size > 1)
|
|
||||||
{
|
|
||||||
sram_size--;
|
sram_size--;
|
||||||
sram_size ^= 0x03;
|
sram_size ^= 0x03;
|
||||||
sram_size <<= 4;
|
sram_size <<= 4;
|
||||||
sram_size &= 0x30;
|
sram_size &= 0x30;
|
||||||
|
} else {
|
||||||
|
sram_size = 0x20; // 2KiB treat as 8KiB
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
sram_size = 0x30; // no sram
|
||||||
sram_size = 0x20; // 2KiB treat as 8KiB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sram_size = 0x30; // no sram
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (sram_size | rom_size);
|
return (sram_size | rom_size);
|
||||||
@ -810,4 +751,4 @@ uint8_t gbSmartGetResizeParam(uint8_t rom_size, uint8_t sram_size)
|
|||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -57,27 +57,27 @@
|
|||||||
|
|
||||||
// Cart Configurations
|
// Cart Configurations
|
||||||
// Format = {mapper,romlo,romhi,ramsize}
|
// Format = {mapper,romlo,romhi,ramsize}
|
||||||
static const byte PROGMEM intvmapsize [] = {
|
static const byte PROGMEM intvmapsize[] = {
|
||||||
0, 0, 2, 0, // default mattel up to 32K (8K/16K/24K/32K)
|
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
|
1, 1, 3, 0, // demo cart 16K, championship tennis 32K, wsml baseball 48K
|
||||||
2, 1, 3, 0, // up to 48K (16K/32K/48K)
|
2, 1, 3, 0, // up to 48K (16K/32K/48K)
|
||||||
3, 4, 4, 0, // tower of doom 48K
|
3, 4, 4, 0, // tower of doom 48K
|
||||||
4, 0, 1, 1, // uscf chess 16K + RAM 1K
|
4, 0, 1, 1, // uscf chess 16K + RAM 1K
|
||||||
5, 2, 3, 0, // congo bongo/defender/pac-man 24K, dig dug 32K
|
5, 2, 3, 0, // congo bongo/defender/pac-man 24K, dig dug 32K
|
||||||
6, 1, 1, 0, // centipede 16K
|
6, 1, 1, 0, // centipede 16K
|
||||||
7, 1, 1, 0, // imagic carts 16K
|
7, 1, 1, 0, // imagic carts 16K
|
||||||
8, 1, 1, 0, // mte-201 test cart 16K
|
8, 1, 1, 0, // mte-201 test cart 16K
|
||||||
9, 3, 3, 2, // triple challenge 32K + RAM 2K
|
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;
|
boolean intvmapfound = false;
|
||||||
byte intvmapselect;
|
byte intvmapselect;
|
||||||
int intvindex;
|
int intvindex;
|
||||||
|
|
||||||
byte INTV[] = {8, 16, 24, 32, 48};
|
byte INTV[] = { 8, 16, 24, 32, 48 };
|
||||||
byte intvlo = 0; // Lowest Entry
|
byte intvlo = 0; // Lowest Entry
|
||||||
byte intvhi = 4; // Highest Entry
|
byte intvhi = 4; // Highest Entry
|
||||||
|
|
||||||
byte intvmapper;
|
byte intvmapper;
|
||||||
byte newintvmapper;
|
byte newintvmapper;
|
||||||
@ -96,10 +96,9 @@ static const char intvMenuItem1[] PROGMEM = "Select Cart";
|
|||||||
static const char intvMenuItem2[] PROGMEM = "Read ROM";
|
static const char intvMenuItem2[] PROGMEM = "Read ROM";
|
||||||
static const char intvMenuItem3[] PROGMEM = "Set Mapper + Size";
|
static const char intvMenuItem3[] PROGMEM = "Set Mapper + Size";
|
||||||
static const char intvMenuItem4[] PROGMEM = "Reset";
|
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)
|
// Set Address Pins to Output (UNUSED)
|
||||||
//A0-A7
|
//A0-A7
|
||||||
DDRF = 0xFF;
|
DDRF = 0xFF;
|
||||||
@ -113,7 +112,7 @@ void setup_INTV()
|
|||||||
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)
|
// Set TIME(PJ0) to Output (UNUSED)
|
||||||
DDRJ |= (1 << 0);
|
DDRJ |= (1 << 0);
|
||||||
|
|
||||||
// Set Pins (DB0-DB15) to Input
|
// Set Pins (DB0-DB15) to Input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
@ -124,10 +123,10 @@ void setup_INTV()
|
|||||||
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||||
|
|
||||||
// Set Unused Pins HIGH
|
// Set Unused Pins HIGH
|
||||||
PORTF = 0xFF; // A0-A7
|
PORTF = 0xFF; // A0-A7
|
||||||
PORTK = 0xFF; // A8-A15
|
PORTK = 0xFF; // A8-A15
|
||||||
PORTL = 0xFF; // A16-A23
|
PORTL = 0xFF; // A16-A23
|
||||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||||
|
|
||||||
checkStatus_INTV();
|
checkStatus_INTV();
|
||||||
strcpy(romName, "INTV");
|
strcpy(romName, "INTV");
|
||||||
@ -135,13 +134,11 @@ void setup_INTV()
|
|||||||
mode = mode_INTV;
|
mode = mode_INTV;
|
||||||
}
|
}
|
||||||
|
|
||||||
void intvMenu()
|
void intvMenu() {
|
||||||
{
|
|
||||||
convertPgm(menuOptionsINTV, 4);
|
convertPgm(menuOptionsINTV, 4);
|
||||||
uint8_t mainMenu = question_box(F("INTELLIVISION MENU"), menuOptions, 4, 0);
|
uint8_t mainMenu = question_box(F("INTELLIVISION MENU"), menuOptions, 4, 0);
|
||||||
|
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
// Select Cart
|
// Select Cart
|
||||||
setCart_INTV();
|
setCart_INTV();
|
||||||
@ -185,8 +182,7 @@ void intvMenu()
|
|||||||
// DIRECT ADDRESSING MODE READ SEQUENCE: BAR-NACT-ADAR-NACT-DTB-NACT
|
// DIRECT ADDRESSING MODE READ SEQUENCE: BAR-NACT-ADAR-NACT-DTB-NACT
|
||||||
|
|
||||||
// NO ACTION (NACT) - 0/0/0
|
// NO ACTION (NACT) - 0/0/0
|
||||||
void NACT_INT()
|
void NACT_INT() {
|
||||||
{
|
|
||||||
// Switch BC1(PH4) + BC2(PH5) + BDIR(PH6) to LOW
|
// Switch BC1(PH4) + BC2(PH5) + BDIR(PH6) to LOW
|
||||||
PORTH &= ~(1 << 4) & ~(1 << 5) & ~(1 << 6);
|
PORTH &= ~(1 << 4) & ~(1 << 5) & ~(1 << 6);
|
||||||
// DB0..DB15 INPUT
|
// DB0..DB15 INPUT
|
||||||
@ -195,8 +191,7 @@ void NACT_INT()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SET ADDRESS - BUS TO ADDR (BAR) - 1/0/0
|
// SET ADDRESS - BUS TO ADDR (BAR) - 1/0/0
|
||||||
void BAR_INT()
|
void BAR_INT() {
|
||||||
{
|
|
||||||
// Switch BDIR(PH6) to HIGH
|
// Switch BDIR(PH6) to HIGH
|
||||||
PORTH |= (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
// Switch BC1(PH4) + BC2(PH5) to LOW
|
// Switch BC1(PH4) + BC2(PH5) to LOW
|
||||||
@ -207,8 +202,7 @@ void BAR_INT()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// READ DATA - DATA TO BUS (DTB) - 0/1/1
|
// READ DATA - DATA TO BUS (DTB) - 0/1/1
|
||||||
void DTB_INT()
|
void DTB_INT() {
|
||||||
{
|
|
||||||
// Switch BDIR(PH6) to LOW
|
// Switch BDIR(PH6) to LOW
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
// Switch BC1(PH4) + BC2(PH5) to HIGH
|
// Switch BC1(PH4) + BC2(PH5) to HIGH
|
||||||
@ -219,8 +213,7 @@ void DTB_INT()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ADDRESS DATA TO ADDRESS REGISTER (ADAR) - 0/1/0
|
// ADDRESS DATA TO ADDRESS REGISTER (ADAR) - 0/1/0
|
||||||
void ADAR_INT()
|
void ADAR_INT() {
|
||||||
{
|
|
||||||
// Switch BC2(PH5) + BDIR(PH6) to LOW
|
// Switch BC2(PH5) + BDIR(PH6) to LOW
|
||||||
PORTH &= ~(1 << 5) & ~(1 << 6);
|
PORTH &= ~(1 << 5) & ~(1 << 6);
|
||||||
// Switch BC1(PH4) to HIGH
|
// Switch BC1(PH4) to HIGH
|
||||||
@ -231,8 +224,7 @@ void ADAR_INT()
|
|||||||
// DATA SHOULD BE STABLE ACROSS BOTH
|
// DATA SHOULD BE STABLE ACROSS BOTH
|
||||||
|
|
||||||
// DATA WRITE (DW) - 1/1/0
|
// DATA WRITE (DW) - 1/1/0
|
||||||
void DW_INT()
|
void DW_INT() {
|
||||||
{
|
|
||||||
// Switch BC1(PH4) + BDIR(PH6) to HIGH
|
// Switch BC1(PH4) + BDIR(PH6) to HIGH
|
||||||
PORTH |= (1 << 4) | (1 << 6);
|
PORTH |= (1 << 4) | (1 << 6);
|
||||||
// Switch BC2(PH5) to LOW
|
// Switch BC2(PH5) to LOW
|
||||||
@ -240,8 +232,7 @@ void DW_INT()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DATA WRITE STROBE (DWS) - 1/0/1
|
// DATA WRITE STROBE (DWS) - 1/0/1
|
||||||
void DWS_INT()
|
void DWS_INT() {
|
||||||
{
|
|
||||||
// Switch BC2(PH5) + BDIR(PH6) to HIGH
|
// Switch BC2(PH5) + BDIR(PH6) to HIGH
|
||||||
PORTH |= (1 << 5) | (1 << 6);
|
PORTH |= (1 << 5) | (1 << 6);
|
||||||
// Switch BC1(PH4) to LOW
|
// Switch BC1(PH4) to LOW
|
||||||
@ -252,25 +243,40 @@ void DWS_INT()
|
|||||||
// READ CODE
|
// READ CODE
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
uint16_t readData_INTV(uint32_t addr)
|
uint16_t readData_INTV(uint32_t addr) {
|
||||||
{
|
|
||||||
PORTC = addr & 0xFF;
|
PORTC = addr & 0xFF;
|
||||||
PORTA = (addr >> 8) & 0xFF;
|
PORTA = (addr >> 8) & 0xFF;
|
||||||
|
|
||||||
BAR_INT();
|
BAR_INT();
|
||||||
// Wait for bus
|
// Wait for bus
|
||||||
// 5 x 62.5ns = 312.5ns
|
// 5 x 62.5ns = 312.5ns
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
NACT_INT();
|
NACT_INT();
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
DTB_INT();
|
DTB_INT();
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
uint16_t ret = (((PINA & 0xFF) << 8) | (PINC & 0xFF));
|
uint16_t ret = (((PINA & 0xFF) << 8) | (PINC & 0xFF));
|
||||||
|
|
||||||
NACT_INT();
|
NACT_INT();
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -287,8 +293,7 @@ uint16_t readData_INTV(uint32_t addr)
|
|||||||
// 8: 0x50-0x60,0x70-0x80, // mte-201 test cart 16K
|
// 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]
|
// 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 (uint32_t addr = startaddr; addr < endaddr; addr += 256) {
|
||||||
for (uint16_t w = 0; w < 256; w++) {
|
for (uint16_t w = 0; w < 256; w++) {
|
||||||
uint16_t temp = readData_INTV(addr + 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
|
// MODIFIED READ ROUTINE FOR ALL 10 MAPPERS
|
||||||
void readROM_INTV()
|
void readROM_INTV() {
|
||||||
{
|
|
||||||
strcpy(fileName, romName);
|
strcpy(fileName, romName);
|
||||||
strcat(fileName, ".int");
|
strcat(fileName, ".int");
|
||||||
|
|
||||||
@ -326,88 +330,88 @@ void readROM_INTV()
|
|||||||
EEPROM_writeAnything(0, foldern);
|
EEPROM_writeAnything(0, foldern);
|
||||||
|
|
||||||
switch (intvmapper) {
|
switch (intvmapper) {
|
||||||
case 0: //default mattel up to 32K (8K/16K/24K/32K)
|
case 0: //default mattel up to 32K (8K/16K/24K/32K)
|
||||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||||
if (intvsize > 0) {
|
if (intvsize > 0) {
|
||||||
readSegment_INTV(0x6000, 0x7000); // +8K = 16K
|
readSegment_INTV(0x6000, 0x7000); // +8K = 16K
|
||||||
if (intvsize > 1) {
|
if (intvsize > 1) {
|
||||||
readSegment_INTV(0xD000, 0xE000); // +8K = 24K
|
readSegment_INTV(0xD000, 0xE000); // +8K = 24K
|
||||||
if (intvsize > 2)
|
if (intvsize > 2)
|
||||||
readSegment_INTV(0xF000, 0x10000); // +8K = 32K
|
readSegment_INTV(0xF000, 0x10000); // +8K = 32K
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // demo cart/championship tennis/wsml baseball
|
case 1: // demo cart/championship tennis/wsml baseball
|
||||||
readSegment_INTV(0x5000, 0x7000); // 16K Demo Cart
|
readSegment_INTV(0x5000, 0x7000); // 16K Demo Cart
|
||||||
if (intvsize > 1) {
|
if (intvsize > 1) {
|
||||||
readSegment_INTV(0xD000, 0xE000); // +8K = 24K [NONE]
|
readSegment_INTV(0xD000, 0xE000); // +8K = 24K [NONE]
|
||||||
if (intvsize > 2) {
|
if (intvsize > 2) {
|
||||||
readSegment_INTV(0xE000, 0xF000); // +8K = 32K Championship Tennis
|
readSegment_INTV(0xE000, 0xF000); // +8K = 32K Championship Tennis
|
||||||
if (intvsize > 3) {
|
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
|
// ecs bank switch
|
||||||
ecsBank(0xFFFF, 0x1); // switch ecs page 1 to 0xF000
|
ecsBank(0xFFFF, 0x1); // switch ecs page 1 to 0xF000
|
||||||
readSegment_INTV(0xF000, 0x10000); // + 8K = 48K WSML Baseball
|
readSegment_INTV(0xF000, 0x10000); // + 8K = 48K WSML Baseball
|
||||||
ecsBank(0xFFFF, 0x0); // reset ecs page 0 to 0xF000
|
ecsBank(0xFFFF, 0x0); // reset ecs page 0 to 0xF000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // up to 48K (16K/32K/48K)
|
case 2: // up to 48K (16K/32K/48K)
|
||||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||||
if (intvsize > 1) {
|
if (intvsize > 1) {
|
||||||
readSegment_INTV(0x9000, 0xA000); // +8K = 24K [NONE]
|
readSegment_INTV(0x9000, 0xA000); // +8K = 24K [NONE]
|
||||||
if (intvsize > 2) {
|
if (intvsize > 2) {
|
||||||
readSegment_INTV(0xA000, 0xB000); // +8K = 32K
|
readSegment_INTV(0xA000, 0xB000); // +8K = 32K
|
||||||
if (intvsize > 3) {
|
if (intvsize > 3) {
|
||||||
readSegment_INTV(0xB000, 0xC000); // +8K = 40K
|
readSegment_INTV(0xB000, 0xC000); // +8K = 40K
|
||||||
readSegment_INTV(0xD000, 0xE000); // +8K = 48K
|
readSegment_INTV(0xD000, 0xE000); // +8K = 48K
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // tower of doom 48K
|
case 3: // tower of doom 48K
|
||||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||||
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
||||||
readSegment_INTV(0xD000, 0xE000); // +8K = 40K
|
readSegment_INTV(0xD000, 0xE000); // +8K = 40K
|
||||||
readSegment_INTV(0xF000, 0x10000); // +8K = 48K
|
readSegment_INTV(0xF000, 0x10000); // +8K = 48K
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // chess 16K
|
case 4: // chess 16K
|
||||||
PORTH &= ~(1 << 3); // /MSYNC to LOW
|
PORTH &= ~(1 << 3); // /MSYNC to LOW
|
||||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||||
PORTH |= (1 << 3); // /MSYNC to HIGH
|
PORTH |= (1 << 3); // /MSYNC to HIGH
|
||||||
readSegment_INTV(0x6000, 0x7000); // 8K
|
readSegment_INTV(0x6000, 0x7000); // 8K
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:// congo bongo/defender/pac-man/dig dug
|
case 5: // congo bongo/defender/pac-man/dig dug
|
||||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||||
readSegment_INTV(0x7000, 0x8000); // +8K = 24K Congo Bongo/Defender/Pac-Man
|
readSegment_INTV(0x7000, 0x8000); // +8K = 24K Congo Bongo/Defender/Pac-Man
|
||||||
if (intvsize > 2) {
|
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]
|
//readSegment_INTV(0xA000,0xC000); // +16K = 48K [UNUSED]
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // centipede 16K
|
case 6: // centipede 16K
|
||||||
readSegment_INTV(0x6000, 0x8000); // 16K
|
readSegment_INTV(0x6000, 0x8000); // 16K
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // imagic carts 16K
|
case 7: // imagic carts 16K
|
||||||
readSegment_INTV(0x4800, 0x6800); // 16K
|
readSegment_INTV(0x4800, 0x6800); // 16K
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: //mte-201 test cart 16K
|
case 8: //mte-201 test cart 16K
|
||||||
readSegment_INTV(0x5000, 0x6000); // 8K
|
readSegment_INTV(0x5000, 0x6000); // 8K
|
||||||
readSegment_INTV(0x7000, 0x8000); // +8K = 16K
|
readSegment_INTV(0x7000, 0x8000); // +8K = 16K
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9: // triple challenge 32K [KNOWN ROM 44K BAD!]
|
case 9: // triple challenge 32K [KNOWN ROM 44K BAD!]
|
||||||
readSegment_INTV(0x5000, 0x7000); // 16K
|
readSegment_INTV(0x5000, 0x7000); // 16K
|
||||||
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
readSegment_INTV(0x9000, 0xB000); // +16K = 32K
|
||||||
// 0xC000 + 0xD000 SEGMENTS ARE NOT NEEDED (PER INTVNUT POST)
|
// 0xC000 + 0xD000 SEGMENTS ARE NOT NEEDED (PER INTVNUT POST)
|
||||||
// readSegment_INTV(0xC000,0xC800); // +4K = 36K
|
// readSegment_INTV(0xC000,0xC800); // +4K = 36K
|
||||||
// readSegment_INTV(0xD000,0xE000); // +8K = 44K
|
// readSegment_INTV(0xD000,0xE000); // +8K = 44K
|
||||||
@ -429,7 +433,7 @@ void readROM_INTV()
|
|||||||
// x = rom location ($x000 - $xFFF)
|
// x = rom location ($x000 - $xFFF)
|
||||||
// y = page (up to 16 - WSML Baseball only uses 0/1)
|
// y = page (up to 16 - WSML Baseball only uses 0/1)
|
||||||
void ecsBank(uint32_t addr, uint8_t bank) {
|
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
|
// Data OUT
|
||||||
DDRA = 0xFF;
|
DDRA = 0xFF;
|
||||||
@ -440,47 +444,62 @@ void ecsBank(uint32_t addr, uint8_t bank) {
|
|||||||
PORTC = addr & 0xFF;
|
PORTC = addr & 0xFF;
|
||||||
|
|
||||||
BAR_INT();
|
BAR_INT();
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
NACT_INT();
|
NACT_INT();
|
||||||
NOP;
|
NOP;
|
||||||
|
|
||||||
// Data OUT
|
// Data OUT
|
||||||
DDRA = 0xFF;
|
DDRA = 0xFF;
|
||||||
DDRC = 0xFF;
|
DDRC = 0xFF;
|
||||||
PORTA = (ecsdata >> 8) & 0xFF; // $xA
|
PORTA = (ecsdata >> 8) & 0xFF; // $xA
|
||||||
PORTC = ecsdata & 0xFF; // $5y
|
PORTC = ecsdata & 0xFF; // $5y
|
||||||
|
|
||||||
DW_INT();
|
DW_INT();
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
DWS_INT();
|
DWS_INT();
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
NACT_INT();
|
NACT_INT();
|
||||||
NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// MAPPER CODE
|
// MAPPER CODE
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
void setMapper_INTV()
|
void setMapper_INTV() {
|
||||||
{
|
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
int b = 0;
|
int b = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// Check Button Status
|
// Check Button Status
|
||||||
#if defined(enable_OLED)
|
#if defined(enable_OLED)
|
||||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||||
#elif defined(enable_LCD)
|
#elif defined(enable_LCD)
|
||||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||||
#endif
|
#endif
|
||||||
if (buttonVal1 == LOW) { // Button Pressed
|
if (buttonVal1 == LOW) { // Button Pressed
|
||||||
while (1) { // Scroll Mapper List
|
while (1) { // Scroll Mapper List
|
||||||
#if defined(enable_OLED)
|
#if defined(enable_OLED)
|
||||||
buttonVal1 = (PIND & (1 << 7)); // PD7
|
buttonVal1 = (PIND & (1 << 7)); // PD7
|
||||||
#elif defined(enable_LCD)
|
#elif defined(enable_LCD)
|
||||||
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
boolean buttonVal1 = (PING & (1 << 2)); // PG2
|
||||||
#endif
|
#endif
|
||||||
if (buttonVal1 == HIGH) { // Button Released
|
if (buttonVal1 == HIGH) { // Button Released
|
||||||
// Correct Overshoot
|
// Correct Overshoot
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
i = intvmapcount - 1;
|
i = intvmapcount - 1;
|
||||||
@ -520,7 +539,7 @@ void setMapper_INTV()
|
|||||||
while (1) {
|
while (1) {
|
||||||
b = checkButton();
|
b = checkButton();
|
||||||
|
|
||||||
if (b == 2) { // Previous Mapper (doubleclick)
|
if (b == 2) { // Previous Mapper (doubleclick)
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
i = intvmapcount - 1;
|
i = intvmapcount - 1;
|
||||||
else
|
else
|
||||||
@ -542,7 +561,7 @@ void setMapper_INTV()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 1) { // Next Mapper (press)
|
if (b == 1) { // Next Mapper (press)
|
||||||
if (i == (intvmapcount - 1))
|
if (i == (intvmapcount - 1))
|
||||||
i = 0;
|
i = 0;
|
||||||
else
|
else
|
||||||
@ -564,7 +583,7 @@ void setMapper_INTV()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 3) { // Long Press - Execute (hold)
|
if (b == 3) { // Long Press - Execute (hold)
|
||||||
newintvmapper = intvmapselect;
|
newintvmapper = intvmapselect;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -613,8 +632,7 @@ void checkMapperSize_INTV() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setROMSize_INTV()
|
void setROMSize_INTV() {
|
||||||
{
|
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
display_Clear();
|
display_Clear();
|
||||||
if (intvlo == intvhi)
|
if (intvlo == intvhi)
|
||||||
@ -639,7 +657,7 @@ void setROMSize_INTV()
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
b = checkButton();
|
b = checkButton();
|
||||||
if (b == 2) { // Previous (doubleclick)
|
if (b == 2) { // Previous (doubleclick)
|
||||||
if (i == intvlo)
|
if (i == intvlo)
|
||||||
i = intvhi;
|
i = intvhi;
|
||||||
else
|
else
|
||||||
@ -659,7 +677,7 @@ void setROMSize_INTV()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 1) { // Next (press)
|
if (b == 1) { // Next (press)
|
||||||
if (i == intvhi)
|
if (i == intvhi)
|
||||||
i = intvlo;
|
i = intvlo;
|
||||||
else
|
else
|
||||||
@ -678,12 +696,12 @@ void setROMSize_INTV()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 3) { // Long Press - Execute (hold)
|
if (b == 3) { // Long Press - Execute (hold)
|
||||||
newintvsize = i;
|
newintvsize = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
display.setCursor(0, 56); // Display selection at bottom
|
display.setCursor(0, 56); // Display selection at bottom
|
||||||
}
|
}
|
||||||
print_Msg(F("ROM SIZE "));
|
print_Msg(F("ROM SIZE "));
|
||||||
print_Msg(INTV[newintvsize]);
|
print_Msg(INTV[newintvsize]);
|
||||||
@ -722,8 +740,7 @@ setrom:
|
|||||||
intvsize = newintvsize;
|
intvsize = newintvsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkStatus_INTV()
|
void checkStatus_INTV() {
|
||||||
{
|
|
||||||
EEPROM_readAnything(7, intvmapper);
|
EEPROM_readAnything(7, intvmapper);
|
||||||
EEPROM_readAnything(8, intvsize);
|
EEPROM_readAnything(8, intvsize);
|
||||||
if (intvmapper > 9) {
|
if (intvmapper > 9) {
|
||||||
@ -793,12 +810,10 @@ void setCart_INTV() {
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (myFile.curPosition() == 0) {
|
if (myFile.curPosition() == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (myFile.peek() == '\n') {
|
||||||
else if (myFile.peek() == '\n') {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -846,9 +861,8 @@ void setCart_INTV() {
|
|||||||
|
|
||||||
// Remove leading 0 for single digit cart sizes
|
// Remove leading 0 for single digit cart sizes
|
||||||
if (cartSize != 0) {
|
if (cartSize != 0) {
|
||||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cartSize = myFile.read() - 48;
|
cartSize = myFile.read() - 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,12 +914,10 @@ void setCart_INTV() {
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (myFile.curPosition() == 0) {
|
if (myFile.curPosition() == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (myFile.peek() == '\n') {
|
||||||
else if (myFile.peek() == '\n') {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -950,12 +962,11 @@ void setCart_INTV() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Database file not found"), true);
|
print_Error(F("Database file not found"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
1114
Cart_Reader/MD.ino
1114
Cart_Reader/MD.ino
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1871
Cart_Reader/NES.ino
1871
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 ngpMenuItem1[] PROGMEM = "Read Rom";
|
||||||
static const char ngpMenuItem2[] PROGMEM = "Read chip info";
|
static const char ngpMenuItem2[] PROGMEM = "Read chip info";
|
||||||
static const char ngpMenuItemReset[] PROGMEM = "Reset";
|
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 ngpRomItem1[] PROGMEM = "4 Mbits / 512 KB";
|
||||||
static const char ngpRomItem2[] PROGMEM = "8 Mbits / 1 MB";
|
static const char ngpRomItem2[] PROGMEM = "8 Mbits / 1 MB";
|
||||||
static const char ngpRomItem3[] PROGMEM = "16 Mbits / 2 MB";
|
static const char ngpRomItem3[] PROGMEM = "16 Mbits / 2 MB";
|
||||||
static const char ngpRomItem4[] PROGMEM = "32 Mbits / 4 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];
|
char ngpRomVersion[3];
|
||||||
uint8_t ngpSystemType;
|
uint8_t ngpSystemType;
|
||||||
@ -79,7 +79,7 @@ void ngpMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool getCartInfo_NGP() {
|
bool getCartInfo_NGP() {
|
||||||
uint8_t *tmp;
|
uint8_t* tmp;
|
||||||
|
|
||||||
// enter autoselect mode
|
// enter autoselect mode
|
||||||
dataOut();
|
dataOut();
|
||||||
@ -99,13 +99,13 @@ bool getCartInfo_NGP() {
|
|||||||
|
|
||||||
|
|
||||||
switch (romSize) {
|
switch (romSize) {
|
||||||
case 0xffff: return false; break; // detection error (no cart inserted or hw problem)
|
case 0xffff: return false; break; // detection error (no cart inserted or hw problem)
|
||||||
case 0x98ab: cartSize = 524288; break; // 4 Mbits - Toshiba
|
case 0x98ab: cartSize = 524288; break; // 4 Mbits - Toshiba
|
||||||
case 0x204c: cartSize = 524288; break; // 4 Mbits - STMicroelectronics ?
|
case 0x204c: cartSize = 524288; break; // 4 Mbits - STMicroelectronics ?
|
||||||
case 0x982c: cartSize = 1048576; break; // 8 Mbits - Toshiba
|
case 0x982c: cartSize = 1048576; break; // 8 Mbits - Toshiba
|
||||||
case 0xec2c: cartSize = 1048576; break; // 8 Mbits - Samsung
|
case 0xec2c: cartSize = 1048576; break; // 8 Mbits - Samsung
|
||||||
case 0x982f: cartSize = 2097152; break; // 16 Mbits - Toshiba
|
case 0x982f: cartSize = 2097152; break; // 16 Mbits - Toshiba
|
||||||
case 0xec2f: cartSize = 2097152; break; // 16 Mbits - Samsung
|
case 0xec2f: cartSize = 2097152; break; // 16 Mbits - Samsung
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset to read mode
|
// reset to read mode
|
||||||
@ -123,7 +123,7 @@ bool getCartInfo_NGP() {
|
|||||||
snprintf(cartID, 5, "%02X%02X", readByte_NGP(0x21), readByte_NGP(0x20));
|
snprintf(cartID, 5, "%02X%02X", readByte_NGP(0x21), readByte_NGP(0x20));
|
||||||
|
|
||||||
// force rom size to 32 Mbits for few titles
|
// 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;
|
cartSize = 4194304;
|
||||||
|
|
||||||
// get app version
|
// get app version
|
||||||
@ -164,8 +164,7 @@ void printCartInfo_NGP() {
|
|||||||
print_Msg(F("ROM Size: "));
|
print_Msg(F("ROM Size: "));
|
||||||
if (cartSize == 0) {
|
if (cartSize == 0) {
|
||||||
println_Msg(F("Unknown"));
|
println_Msg(F("Unknown"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg((cartSize >> 17));
|
print_Msg((cartSize >> 17));
|
||||||
println_Msg(F(" Mbits"));
|
println_Msg(F(" Mbits"));
|
||||||
}
|
}
|
||||||
@ -175,7 +174,7 @@ void printCartInfo_NGP() {
|
|||||||
wait();
|
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
|
// Set cartsize manually if chip ID is unknown
|
||||||
if (cartSize == 0) {
|
if (cartSize == 0) {
|
||||||
unsigned char ngpRomMenu;
|
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("Warning: this cart is 32Mbits. Only the first 16Mbits chip will be scanned.");
|
||||||
myFile.println("");
|
myFile.println("");
|
||||||
addrMax = 2097152;
|
addrMax = 2097152;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
addrMax = cartSize;
|
addrMax = cartSize;
|
||||||
|
|
||||||
myFile.println("Sector | Start address | Status");
|
myFile.println("Sector | Start address | Status");
|
||||||
@ -309,7 +307,7 @@ void scanChip_NGP() {
|
|||||||
// browse sectors
|
// browse sectors
|
||||||
for (uint32_t addr = 0; addr < addrMax; addr += 0x1000) {
|
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) + " | ");
|
myFile.print("#" + String(sectorID) + " | 0x" + String(addr, HEX) + " | ");
|
||||||
|
|
||||||
@ -344,7 +342,8 @@ void writeByte_NGP(uint32_t addr, uint8_t data) {
|
|||||||
|
|
||||||
PORTH |= data;
|
PORTH |= data;
|
||||||
PORTH |= (1 << 5);
|
PORTH |= (1 << 5);
|
||||||
NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t readByte_NGP(uint32_t addr) {
|
uint8_t readByte_NGP(uint32_t addr) {
|
||||||
@ -361,7 +360,9 @@ uint8_t readByte_NGP(uint32_t addr) {
|
|||||||
|
|
||||||
PORTH &= ~data;
|
PORTH &= ~data;
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
data = PINC;
|
data = PINC;
|
||||||
|
|
||||||
@ -374,4 +375,4 @@ uint8_t readByte_NGP(uint32_t addr) {
|
|||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -42,7 +42,7 @@ void read_rom_PCE(void);
|
|||||||
/******************************************
|
/******************************************
|
||||||
Variables
|
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;
|
uint16_t pce_force_rom_size = 0;
|
||||||
uint8_t tennokoe_bank_index = 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 pceMenuItem2[] PROGMEM = "HuCARD(not swapped)";
|
||||||
static const char pceMenuItem3[] PROGMEM = "Turbochip";
|
static const char pceMenuItem3[] PROGMEM = "Turbochip";
|
||||||
static const char pceMenuItem4[] PROGMEM = "Reset";
|
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
|
// PCE card menu items
|
||||||
static const char pceCartMenuItem1[] = "Read ROM";
|
static const char pceCartMenuItem1[] = "Read ROM";
|
||||||
@ -70,7 +70,7 @@ static char menuOptionspceCart[7][20];
|
|||||||
// Turbochip menu items
|
// Turbochip menu items
|
||||||
static const char pceTCMenuItem1[] PROGMEM = "Read ROM";
|
static const char pceTCMenuItem1[] PROGMEM = "Read ROM";
|
||||||
static const char pceTCMenuItem2[] PROGMEM = "Reset";
|
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
|
// PCE start menu
|
||||||
void pcsMenu(void) {
|
void pcsMenu(void) {
|
||||||
@ -81,8 +81,7 @@ void pcsMenu(void) {
|
|||||||
pceDev = question_box(F("Select device"), menuOptions, 3, 0);
|
pceDev = question_box(F("Select device"), menuOptions, 3, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (pceDev)
|
switch (pceDev) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
//Hucard
|
//Hucard
|
||||||
display_Clear();
|
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
|
// Set Address Pins to Output
|
||||||
//A0-A7
|
//A0-A7
|
||||||
DDRF = 0xFF;
|
DDRF = 0xFF;
|
||||||
@ -153,8 +151,7 @@ void pin_read_write_PCE(void)
|
|||||||
reset_cart_PCE();
|
reset_cart_PCE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pin_init_PCE(void)
|
void pin_init_PCE(void) {
|
||||||
{
|
|
||||||
|
|
||||||
//Set Address Pins to input and pull up
|
//Set Address Pins to input and pull up
|
||||||
DDRF = 0x00;
|
DDRF = 0x00;
|
||||||
@ -175,61 +172,67 @@ void pin_init_PCE(void)
|
|||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
// Enable Internal Pullups
|
// Enable Internal Pullups
|
||||||
PORTC = 0xFF;
|
PORTC = 0xFF;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_cart_PCE(void)
|
void setup_cart_PCE(void) {
|
||||||
{
|
|
||||||
// Set cicrstPin(PG1) to Output
|
// Set cicrstPin(PG1) to Output
|
||||||
DDRG |= (1 << 1);
|
DDRG |= (1 << 1);
|
||||||
// Output a high to disable CIC
|
// Output a high to disable CIC
|
||||||
PORTG |= (1 << 1);
|
PORTG |= (1 << 1);
|
||||||
|
|
||||||
pin_init_PCE();
|
pin_init_PCE();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_cart_PCE(void)
|
void reset_cart_PCE(void) {
|
||||||
{
|
|
||||||
//Set RESET as Low
|
//Set RESET as Low
|
||||||
PORTH &= ~(1 << 0);
|
PORTH &= ~(1 << 0);
|
||||||
delay(200);
|
delay(200);
|
||||||
//Set RESET as High
|
//Set RESET as High
|
||||||
PORTH |= (1 << 0);
|
PORTH |= (1 << 0);
|
||||||
delay(200);
|
delay(200);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_address_PCE(uint32_t address)
|
void set_address_PCE(uint32_t address) {
|
||||||
{
|
|
||||||
//Set address
|
//Set address
|
||||||
PORTF = address & 0xFF;
|
PORTF = address & 0xFF;
|
||||||
PORTK = (address >> 8) & 0xFF;
|
PORTK = (address >> 8) & 0xFF;
|
||||||
PORTL = (PORTL & 0xF0) | ((address >> 16) & 0x0F);
|
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
|
// Set CS(PL4) and RD(PH3) as LOW
|
||||||
PORTL &= ~(1 << 4);
|
PORTL &= ~(1 << 4);
|
||||||
PORTH &= ~(1 << 3);
|
PORTH &= ~(1 << 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t read_byte_PCE(uint32_t address)
|
uint8_t read_byte_PCE(uint32_t address) {
|
||||||
{
|
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
|
|
||||||
set_address_PCE(address);
|
set_address_PCE(address);
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
// 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
|
//read byte
|
||||||
ret = PINC;
|
ret = PINC;
|
||||||
|
|
||||||
//Swap bit order for PC Engine HuCARD
|
//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);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void data_output_PCE () {
|
void data_output_PCE() {
|
||||||
// Set Data Pins (D0-D7) to Output
|
// Set Data Pins (D0-D7) to Output
|
||||||
DDRC = 0xFF;
|
DDRC = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void data_input_PCE () {
|
void data_input_PCE() {
|
||||||
// Set Data Pins (D0-D7) to Input
|
// Set Data Pins (D0-D7) to Input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
// Enable Internal Pullups
|
// Enable Internal Pullups
|
||||||
@ -251,17 +254,30 @@ void data_input_PCE () {
|
|||||||
set_cs_rd_low_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
|
//PORTH |= (1 << 3); // RD HIGH
|
||||||
set_address_PCE(address);
|
set_address_PCE(address);
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
// 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
|
//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);
|
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);
|
PORTH &= ~(1 << 5);
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
// 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
|
// Set CS(PL4) and WR(PH5) as HIGH
|
||||||
PORTL |= (1 << 4);
|
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
|
//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;
|
uint32_t rom_size;
|
||||||
uint8_t read_byte;
|
uint8_t read_byte;
|
||||||
uint8_t current_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)
|
//Confirm where mirror address start from(128KB, 256KB, 512KB, 768, or 1024KB)
|
||||||
for (current_byte = 0; current_byte < DETECTION_SIZE; current_byte++) {
|
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
|
//If none matched, it is 1024KB
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -309,38 +338,30 @@ uint32_t detect_rom_size_PCE(void)
|
|||||||
read_byte = read_byte_PCE(current_byte);
|
read_byte = read_byte_PCE(current_byte);
|
||||||
|
|
||||||
//128KB detection
|
//128KB detection
|
||||||
if (current_byte == detect_128)
|
if (current_byte == detect_128) {
|
||||||
{
|
if (read_byte_PCE(current_byte + 128UL * 1024UL) == read_byte) {
|
||||||
if (read_byte_PCE(current_byte + 128UL * 1024UL) == read_byte)
|
|
||||||
{
|
|
||||||
detect_128++;
|
detect_128++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//256KB detection
|
//256KB detection
|
||||||
if (current_byte == detect_256)
|
if (current_byte == detect_256) {
|
||||||
{
|
if (read_byte_PCE(current_byte + 256UL * 1024UL) == read_byte) {
|
||||||
if (read_byte_PCE(current_byte + 256UL * 1024UL) == read_byte)
|
|
||||||
{
|
|
||||||
detect_256++;
|
detect_256++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//512KB detection
|
//512KB detection
|
||||||
if (current_byte == detect_512)
|
if (current_byte == detect_512) {
|
||||||
{
|
if (read_byte_PCE(current_byte + 512UL * 1024UL) == read_byte) {
|
||||||
if (read_byte_PCE(current_byte + 512UL * 1024UL) == read_byte)
|
|
||||||
{
|
|
||||||
detect_512++;
|
detect_512++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//768KB detection
|
//768KB detection
|
||||||
read_byte = read_byte_PCE(current_byte + 512UL * 1024UL);
|
read_byte = read_byte_PCE(current_byte + 512UL * 1024UL);
|
||||||
if (current_byte == detect_768)
|
if (current_byte == detect_768) {
|
||||||
{
|
if (read_byte_PCE(current_byte + 768UL * 1024UL) == read_byte) {
|
||||||
if (read_byte_PCE(current_byte + 768UL * 1024UL) == read_byte)
|
|
||||||
{
|
|
||||||
detect_768++;
|
detect_768++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,43 +372,29 @@ uint32_t detect_rom_size_PCE(void)
|
|||||||
//println_Msg(fileName);
|
//println_Msg(fileName);
|
||||||
|
|
||||||
//ROM size detection by result
|
//ROM size detection by result
|
||||||
if (detect_128 == DETECTION_SIZE)
|
if (detect_128 == DETECTION_SIZE) {
|
||||||
{
|
|
||||||
rom_size = 128;
|
rom_size = 128;
|
||||||
}
|
} else if (detect_256 == DETECTION_SIZE) {
|
||||||
else if (detect_256 == DETECTION_SIZE)
|
if (detect_512 == DETECTION_SIZE) {
|
||||||
{
|
|
||||||
if (detect_512 == DETECTION_SIZE)
|
|
||||||
{
|
|
||||||
rom_size = 256;
|
rom_size = 256;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//rom_size = 1024;
|
//rom_size = 1024;
|
||||||
//Another confirmation for 384KB because 384KB hucard has data in 0x0--0x40000 and 0x80000--0xA0000(0x40000 is mirror of 0x00000)
|
//Another confirmation for 384KB because 384KB hucard has data in 0x0--0x40000 and 0x80000--0xA0000(0x40000 is mirror of 0x00000)
|
||||||
rom_size = 384;
|
rom_size = 384;
|
||||||
}
|
}
|
||||||
}
|
} else if (detect_512 == DETECTION_SIZE) {
|
||||||
else if (detect_512 == DETECTION_SIZE)
|
|
||||||
{
|
|
||||||
rom_size = 512;
|
rom_size = 512;
|
||||||
}
|
} else if (detect_768 == DETECTION_SIZE) {
|
||||||
else if (detect_768 == DETECTION_SIZE)
|
|
||||||
{
|
|
||||||
rom_size = 768;
|
rom_size = 768;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
rom_size = 1024;
|
rom_size = 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If rom size is more than or equal to 512KB, detect Street fighter II'
|
//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 "
|
//Look for "NEC HE "
|
||||||
if (read_byte_PCE(0x7FFF9) == 'N' && read_byte_PCE(0x7FFFA) == 'E' && read_byte_PCE(0x7FFFB) == 'C'
|
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')
|
&& read_byte_PCE(0x7FFFC) == ' ' && read_byte_PCE(0x7FFFD) == 'H' && read_byte_PCE(0x7FFFE) == 'E') {
|
||||||
{
|
|
||||||
rom_size = 2560;
|
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 */
|
/* 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;
|
uint32_t currByte;
|
||||||
uint16_t c;
|
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;
|
uint32_t start = address_start + block_index * 512;
|
||||||
for (uint16_t c = 0; c < 512; c++) {
|
for (uint16_t c = 0; c < 512; c++) {
|
||||||
sdBuffer[c] = read_byte_PCE(start + 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;
|
int i, j;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
r ^= c[i];
|
r ^= c[i];
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
if (r & 1) r = (r >> 1) ^ 0xEDB88320UL;
|
if (r & 1) r = (r >> 1) ^ 0xEDB88320UL;
|
||||||
else r >>= 1;
|
else r >>= 1;
|
||||||
}
|
}
|
||||||
return r;
|
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;
|
FsFile rom, script;
|
||||||
uint32_t r, processedsize;
|
uint32_t r, processedsize;
|
||||||
char gamename[100];
|
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;
|
flag = CHKSUM_SKIP;
|
||||||
|
|
||||||
//Open list file. If no list file found, just skip
|
//Open list file. If no list file found, just skip
|
||||||
sd.chdir("/"); //Set read directry to root
|
sd.chdir("/"); //Set read directry to root
|
||||||
if (script.open("pce.txt", O_READ))
|
if (script.open("pce.txt", O_READ)) {
|
||||||
{
|
|
||||||
//Calculate CRC of ROM file
|
//Calculate CRC of ROM file
|
||||||
sd.chdir(folder_p);
|
sd.chdir(folder_p);
|
||||||
if (rom.open(file_p, O_READ))
|
if (rom.open(file_p, O_READ)) {
|
||||||
{
|
|
||||||
//Initialize flag as error
|
//Initialize flag as error
|
||||||
flag = CHKSUM_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
|
//Display calculated CRC
|
||||||
sprintf(crc_file, "%08lX", 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)
|
//Read 2 lines (game name and CRC)
|
||||||
get_line(gamename, &script, 96);
|
get_line(gamename, &script, 96);
|
||||||
get_line(crc_search, &script, 9);
|
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 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 "));
|
print_Msg(F("Chksum OK "));
|
||||||
println_Msg(crc_file);
|
println_Msg(crc_file);
|
||||||
print_Msg(F("Saved to "));
|
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(F("Saved to "));
|
||||||
print_Msg(folder_p);
|
print_Msg(folder_p);
|
||||||
print_Msg(F("/"));
|
print_Msg(F("/"));
|
||||||
print_Msg(file_p);
|
print_Msg(file_p);
|
||||||
}
|
} else if (flag == CHKSUM_ERROR) {
|
||||||
else if (flag == CHKSUM_ERROR)
|
|
||||||
{
|
|
||||||
print_Msg(F("Chksum Error "));
|
print_Msg(F("Chksum Error "));
|
||||||
println_Msg(crc_file);
|
println_Msg(crc_file);
|
||||||
print_Msg(F("Saved to "));
|
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();
|
script.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlock_tennokoe_bank_RAM()
|
void unlock_tennokoe_bank_RAM() {
|
||||||
{
|
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68
|
||||||
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, 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 3 Bank 78
|
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
|
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lock_tennokoe_bank_RAM()
|
void lock_tennokoe_bank_RAM() {
|
||||||
{
|
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
|
||||||
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(0x0F0001, 0x00); //Lock RAM sequence 2 Bank 78
|
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
|
||||||
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 processed_size = 0;
|
||||||
uint32_t verify_loop;
|
uint32_t verify_loop;
|
||||||
uint8_t verify_flag = 1;
|
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 (block_index == 0 && sdBuffer[2] == 0x42 && sdBuffer[3] == 0x4D) {
|
||||||
if (sdBuffer[0] != 0x48 || sdBuffer[1] != 0x55) {
|
if (sdBuffer[0] != 0x48 || sdBuffer[1] != 0x55) {
|
||||||
sdBuffer[0] = 0x48; // H
|
sdBuffer[0] = 0x48; // H
|
||||||
sdBuffer[1] = 0x55; // U
|
sdBuffer[1] = 0x55; // U
|
||||||
println_Msg(F("Corrected header"));
|
println_Msg(F("Corrected header"));
|
||||||
} else {
|
} else {
|
||||||
println_Msg(F("Header is correct"));
|
println_Msg(F("Header is correct"));
|
||||||
@ -613,11 +606,9 @@ void read_tennokoe_bank_PCE(int bank_index)
|
|||||||
|
|
||||||
//Close the file:
|
//Close the file:
|
||||||
myFile.close();
|
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.
|
//Display file Browser and wait user to select a file. Size must be 2KB.
|
||||||
filePath[0] = '\0';
|
filePath[0] = '\0';
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -708,14 +699,12 @@ void write_tennokoe_bank_PCE(int bank_index)
|
|||||||
println_Msg(F("Finished"));
|
println_Msg(F("Finished"));
|
||||||
display_Update();
|
display_Update();
|
||||||
wait();
|
wait();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("File doesn't exist"), false);
|
print_Error(F("File doesn't exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_rom_PCE(void)
|
void read_rom_PCE(void) {
|
||||||
{
|
|
||||||
uint32_t rom_size;
|
uint32_t rom_size;
|
||||||
uint32_t processed_size = 0;
|
uint32_t processed_size = 0;
|
||||||
|
|
||||||
@ -762,36 +751,31 @@ void read_rom_PCE(void)
|
|||||||
//Initialize progress bar by setting processed size as 0
|
//Initialize progress bar by setting processed size as 0
|
||||||
draw_progressbar(0, rom_size * 1024UL);
|
draw_progressbar(0, rom_size * 1024UL);
|
||||||
|
|
||||||
uint32_t crc = 0xFFFFFFFFUL; //Initialize CRC
|
uint32_t crc = 0xFFFFFFFFUL; //Initialize CRC
|
||||||
if (rom_size == 384)
|
if (rom_size == 384) {
|
||||||
{
|
|
||||||
//Read two sections. 0x000000--0x040000 and 0x080000--0x0A0000 for 384KB
|
//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(0, 0x40000, &processed_size, rom_size * 1024UL, &crc);
|
||||||
read_bank_PCE_ROM(0x80000, 0xA0000, &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
|
//Dump Street fighter II' Champion Edition
|
||||||
read_bank_PCE_ROM(0, 0x80000, &processed_size, rom_size * 1024UL, &crc); //Read first bank
|
read_bank_PCE_ROM(0, 0x80000, &processed_size, rom_size * 1024UL, &crc); //Read first bank
|
||||||
data_output_PCE();
|
data_output_PCE();
|
||||||
write_byte_PCE(0x1FF0, 0xFF); //Display second bank
|
write_byte_PCE(0x1FF0, 0xFF); //Display second bank
|
||||||
data_input_PCE();
|
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();
|
data_output_PCE();
|
||||||
write_byte_PCE(0x1FF1, 0xFF); //Display third bank
|
write_byte_PCE(0x1FF1, 0xFF); //Display third bank
|
||||||
data_input_PCE();
|
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();
|
data_output_PCE();
|
||||||
write_byte_PCE(0x1FF2, 0xFF); //Display forth bank
|
write_byte_PCE(0x1FF2, 0xFF); //Display forth bank
|
||||||
data_input_PCE();
|
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();
|
data_output_PCE();
|
||||||
write_byte_PCE(0x1FF3, 0xFF); //Display fifth bank
|
write_byte_PCE(0x1FF3, 0xFF); //Display fifth bank
|
||||||
data_input_PCE();
|
data_input_PCE();
|
||||||
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read fifth bank
|
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read fifth bank
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//Read start form 0x000000 and keep reading until end of ROM
|
//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);
|
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
|
// create menu with title and 7 options to choose from
|
||||||
unsigned char mainMenu;
|
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(pceCartMenuItem2, "Read RAM Bank %d", tennokoe_bank_index + 1);
|
||||||
sprintf(pceCartMenuItem3, "Write RAM Bank %d", tennokoe_bank_index + 1);
|
sprintf(pceCartMenuItem3, "Write RAM Bank %d", tennokoe_bank_index + 1);
|
||||||
strcpy(menuOptionspceCart[0], pceCartMenuItem1);
|
strcpy(menuOptionspceCart[0], pceCartMenuItem1);
|
||||||
@ -829,8 +812,7 @@ void pceMenu() {
|
|||||||
mainMenu = question_box(F("PCE HuCARD menu"), menuOptionspceCart, 7, 0);
|
mainMenu = question_box(F("PCE HuCARD menu"), menuOptionspceCart, 7, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
@ -862,16 +844,13 @@ void pceMenu() {
|
|||||||
pce_force_rom_size = 1024;
|
pce_force_rom_size = 1024;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Copy menuOptions out of progmem
|
// Copy menuOptions out of progmem
|
||||||
convertPgm(menuOptionspceTC, 2);
|
convertPgm(menuOptionspceTC, 2);
|
||||||
mainMenu = question_box(F("TG TurboChip menu"), menuOptions, 2, 0);
|
mainMenu = question_box(F("TG TurboChip menu"), menuOptions, 2, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
@ -895,4 +874,4 @@ void pceMenu() {
|
|||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -75,19 +75,23 @@
|
|||||||
#define NAND_1A_HIGH PORTH |= (1 << 3)
|
#define NAND_1A_HIGH PORTH |= (1 << 3)
|
||||||
#define NAND_1A_LOW PORTH &= ~(1 << 3)
|
#define NAND_1A_LOW PORTH &= ~(1 << 3)
|
||||||
#define NAND_1B_HIGH PORTH |= (1 << 4)
|
#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_HIGH PORTH |= (1 << 5)
|
||||||
#define WE_LOW PORTH &= ~(1 << 5)
|
#define WE_LOW PORTH &= ~(1 << 5)
|
||||||
#define OE_HIGH PORTH |= (1 << 6)
|
#define OE_HIGH PORTH |= (1 << 6)
|
||||||
#define OE_LOW PORTH &= ~(1 << 6)
|
#define OE_LOW PORTH &= ~(1 << 6)
|
||||||
|
|
||||||
#define MODE_READ DDRC = 0 // [INPUT]
|
#define MODE_READ DDRC = 0 // [INPUT]
|
||||||
#define MODE_WRITE DDRC = 0xFF //[OUTPUT]
|
#define MODE_WRITE DDRC = 0xFF //[OUTPUT]
|
||||||
|
|
||||||
#define DATA_READ { DDRC = 0; PORTC = 0xFF; } // [INPUT PULLUP]
|
#define DATA_READ \
|
||||||
#define ADDR_WRITE DDRC = 0xFF // [OUTPUT]
|
{ \
|
||||||
|
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 bank0;
|
||||||
byte bank1;
|
byte bank1;
|
||||||
|
|
||||||
@ -107,17 +111,17 @@ void setup_PCW() {
|
|||||||
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)
|
// Set TIME(PJ0) to Output (UNUSED)
|
||||||
DDRJ |= (1 << 0);
|
DDRJ |= (1 << 0);
|
||||||
|
|
||||||
// Set Address/Data Pins AD0-AD7 (PC0-PC7) to Input
|
// Set Address/Data Pins AD0-AD7 (PC0-PC7) to Input
|
||||||
MODE_READ; // DDRC = 0
|
MODE_READ; // DDRC = 0
|
||||||
|
|
||||||
// Setting Control Pins to HIGH
|
// Setting Control Pins to HIGH
|
||||||
// LE(PH0) ---(PH1) 1A(PH3) 1B(PH4) WE(PH5) OE(PH6)
|
// LE(PH0) ---(PH1) 1A(PH3) 1B(PH4) WE(PH5) OE(PH6)
|
||||||
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
PORTH |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
|
||||||
|
|
||||||
// Set Unused Pins HIGH
|
// Set Unused Pins HIGH
|
||||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||||
|
|
||||||
// Multi-Pack Cart Check
|
// Multi-Pack Cart Check
|
||||||
check_multi_PCW();
|
check_multi_PCW();
|
||||||
@ -134,15 +138,13 @@ static const char pcwmenuItem1[] PROGMEM = "Read ROM";
|
|||||||
static const char pcwmenuItem2[] PROGMEM = "Read SRAM";
|
static const char pcwmenuItem2[] PROGMEM = "Read SRAM";
|
||||||
static const char pcwmenuItem3[] PROGMEM = "Write SRAM";
|
static const char pcwmenuItem3[] PROGMEM = "Write SRAM";
|
||||||
static const char pcwmenuItem4[] PROGMEM = "Reset";
|
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);
|
convertPgm(menuOptionsPCW, 4);
|
||||||
uint8_t mainMenu = question_box(F(" POCKET CHALLENGE W"), menuOptions, 4, 0);
|
uint8_t mainMenu = question_box(F(" POCKET CHALLENGE W"), menuOptions, 4, 0);
|
||||||
|
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
// Read ROM
|
// Read ROM
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -178,8 +180,7 @@ void pcwMenu()
|
|||||||
if (writeErrors == 0) {
|
if (writeErrors == 0) {
|
||||||
println_Msg(F("SRAM verified OK"));
|
println_Msg(F("SRAM verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(writeErrors);
|
print_Msg(writeErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
@ -215,14 +216,15 @@ unsigned char read_rom_byte_PCW(unsigned long address) {
|
|||||||
PORTK = (address >> 8) & 0xFF;
|
PORTK = (address >> 8) & 0xFF;
|
||||||
// Latch Address on AD0-AD7
|
// Latch Address on AD0-AD7
|
||||||
ADDR_WRITE;
|
ADDR_WRITE;
|
||||||
LE_HIGH; // Latch Enable
|
LE_HIGH; // Latch Enable
|
||||||
PORTC = address & 0xFF; // A0-A7
|
PORTC = address & 0xFF; // A0-A7
|
||||||
LE_LOW; // Address Latched
|
LE_LOW; // Address Latched
|
||||||
__asm__("nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
// Read Data on AD0-AD7
|
// Read Data on AD0-AD7
|
||||||
OE_LOW;
|
OE_LOW;
|
||||||
DATA_READ;
|
DATA_READ;
|
||||||
delayMicroseconds(5); // 3+ Microseconds for Problem Carts
|
delayMicroseconds(5); // 3+ Microseconds for Problem Carts
|
||||||
unsigned char data = PINC;
|
unsigned char data = PINC;
|
||||||
OE_HIGH;
|
OE_HIGH;
|
||||||
|
|
||||||
@ -237,18 +239,33 @@ unsigned char read_ram_byte_1A_PCW(unsigned long address) {
|
|||||||
PORTK = (address >> 8) & 0xFF;
|
PORTK = (address >> 8) & 0xFF;
|
||||||
// Latch Address on AD0-AD7
|
// Latch Address on AD0-AD7
|
||||||
ADDR_WRITE;
|
ADDR_WRITE;
|
||||||
LE_HIGH; // Latch Enable
|
LE_HIGH; // Latch Enable
|
||||||
PORTC = address & 0xFF; // A0-A7
|
PORTC = address & 0xFF; // A0-A7
|
||||||
LE_LOW; // Address Latched
|
LE_LOW; // Address Latched
|
||||||
__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 Data on AD0-AD7
|
// Read Data on AD0-AD7
|
||||||
OE_LOW;
|
OE_LOW;
|
||||||
DATA_READ;
|
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;
|
unsigned char data = PINC;
|
||||||
OE_HIGH;
|
OE_HIGH;
|
||||||
NAND_1A_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;
|
return data;
|
||||||
}
|
}
|
||||||
@ -267,18 +284,33 @@ unsigned char read_ram_byte_1B_PCW(unsigned long address) {
|
|||||||
PORTK = (address >> 8) & 0xFF;
|
PORTK = (address >> 8) & 0xFF;
|
||||||
// Latch Address on AD0-AD7
|
// Latch Address on AD0-AD7
|
||||||
ADDR_WRITE;
|
ADDR_WRITE;
|
||||||
LE_HIGH; // Latch Enable
|
LE_HIGH; // Latch Enable
|
||||||
PORTC = address & 0xFF; // A0-A7
|
PORTC = address & 0xFF; // A0-A7
|
||||||
LE_LOW; // Address Latched
|
LE_LOW; // Address Latched
|
||||||
__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 Data on AD0-AD7
|
// Read Data on AD0-AD7
|
||||||
OE_LOW;
|
OE_LOW;
|
||||||
DATA_READ;
|
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;
|
unsigned char data = PINC;
|
||||||
OE_HIGH;
|
OE_HIGH;
|
||||||
NAND_1B_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;
|
return data;
|
||||||
}
|
}
|
||||||
@ -290,13 +322,16 @@ void write_ram_byte_1A_PCW(unsigned long address, unsigned char data) {
|
|||||||
PORTK = (address >> 8) & 0xFF;
|
PORTK = (address >> 8) & 0xFF;
|
||||||
// Latch Address on AD0-AD7
|
// Latch Address on AD0-AD7
|
||||||
ADDR_WRITE;
|
ADDR_WRITE;
|
||||||
LE_HIGH; // Latch Enable
|
LE_HIGH; // Latch Enable
|
||||||
PORTC = address & 0xFF; // A0-A7
|
PORTC = address & 0xFF; // A0-A7
|
||||||
LE_LOW; // Address Latched
|
LE_LOW; // Address Latched
|
||||||
// Write Data on AD0-AD7 - WE LOW ~240-248ns
|
// Write Data on AD0-AD7 - WE LOW ~240-248ns
|
||||||
WE_LOW;
|
WE_LOW;
|
||||||
PORTC = data;
|
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;
|
WE_HIGH;
|
||||||
NAND_1A_HIGH;
|
NAND_1A_HIGH;
|
||||||
}
|
}
|
||||||
@ -311,14 +346,22 @@ void write_ram_byte_1B_PCW(unsigned long address, unsigned char data) {
|
|||||||
PORTK = (address >> 8) & 0xFF;
|
PORTK = (address >> 8) & 0xFF;
|
||||||
// Latch Address on AD0-AD7
|
// Latch Address on AD0-AD7
|
||||||
ADDR_WRITE;
|
ADDR_WRITE;
|
||||||
LE_HIGH; // Latch Enable
|
LE_HIGH; // Latch Enable
|
||||||
PORTC = address & 0xFF; // A0-A7
|
PORTC = address & 0xFF; // A0-A7
|
||||||
LE_LOW; // Address Latched
|
LE_LOW; // Address Latched
|
||||||
// Write Data on AD0-AD7 - WE LOW ~740ns
|
// Write Data on AD0-AD7 - WE LOW ~740ns
|
||||||
WE_LOW;
|
WE_LOW;
|
||||||
PORTC = data;
|
PORTC = data;
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("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");
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
WE_HIGH;
|
WE_HIGH;
|
||||||
NAND_1B_HIGH;
|
NAND_1B_HIGH;
|
||||||
}
|
}
|
||||||
@ -353,18 +396,18 @@ void write_ram_byte_1B_PCW(unsigned long address, unsigned char data) {
|
|||||||
// MULTI-PACK CART CHECK
|
// MULTI-PACK CART CHECK
|
||||||
void check_multi_PCW() {
|
void check_multi_PCW() {
|
||||||
read_setup_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) {
|
if (tempbyte) {
|
||||||
bank0 = tempbyte; // Store Bank 0 Switch
|
bank0 = tempbyte; // Store Bank 0 Switch
|
||||||
tempbyte = read_rom_byte_PCW(0x3FFD); // Bank 1 Switch
|
tempbyte = read_rom_byte_PCW(0x3FFD); // Bank 1 Switch
|
||||||
if (tempbyte) {
|
if (tempbyte) {
|
||||||
bank1 = tempbyte; // Store Bank 1 Switch
|
bank1 = tempbyte; // Store Bank 1 Switch
|
||||||
// Check for 00s
|
// Check for 00s
|
||||||
tempbyte = read_rom_byte_PCW(0x3FFB); // Should be 00
|
tempbyte = read_rom_byte_PCW(0x3FFB); // Should be 00
|
||||||
if (!tempbyte) {
|
if (!tempbyte) {
|
||||||
tempbyte = read_rom_byte_PCW(0x3FFF); // Should be 00
|
tempbyte = read_rom_byte_PCW(0x3FFF); // Should be 00
|
||||||
if (!tempbyte)
|
if (!tempbyte)
|
||||||
multipack = 1; // Flag Multi-Cart
|
multipack = 1; // Flag Multi-Cart
|
||||||
else {
|
else {
|
||||||
bank0 = 0;
|
bank0 = 0;
|
||||||
bank1 = 0;
|
bank1 = 0;
|
||||||
@ -380,26 +423,33 @@ void write_bank_byte_PCW(unsigned char data) {
|
|||||||
NAND_1B_LOW;
|
NAND_1B_LOW;
|
||||||
// Write to Address 0xFFFF
|
// Write to Address 0xFFFF
|
||||||
PORTL = 0x00;
|
PORTL = 0x00;
|
||||||
PORTK = 0xFF; // A8-A15
|
PORTK = 0xFF; // A8-A15
|
||||||
// Latch Address on AD0-AD7
|
// Latch Address on AD0-AD7
|
||||||
ADDR_WRITE;
|
ADDR_WRITE;
|
||||||
LE_HIGH; // Latch Enable
|
LE_HIGH; // Latch Enable
|
||||||
PORTC = 0xFF; // A0-A7
|
PORTC = 0xFF; // A0-A7
|
||||||
LE_LOW; // Address Latched
|
LE_LOW; // Address Latched
|
||||||
// Write Data on AD0-AD7 - WE LOW ~728-736ns
|
// Write Data on AD0-AD7 - WE LOW ~728-736ns
|
||||||
WE_LOW;
|
WE_LOW;
|
||||||
PORTC = data;
|
PORTC = data;
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("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");
|
||||||
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
WE_HIGH;
|
WE_HIGH;
|
||||||
NAND_1B_HIGH;
|
NAND_1B_HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchBank_PCW(int bank) {
|
void switchBank_PCW(int bank) {
|
||||||
if (bank == 1) { // Upper Half
|
if (bank == 1) { // Upper Half
|
||||||
write_bank_byte_PCW(bank1);
|
write_bank_byte_PCW(bank1);
|
||||||
}
|
} else { // Lower Half (default)
|
||||||
else { // Lower Half (default)
|
|
||||||
write_bank_byte_PCW(bank0);
|
write_bank_byte_PCW(bank0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -430,7 +480,7 @@ void readROM_PCW() {
|
|||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
read_setup_PCW();
|
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++) {
|
for (unsigned int x = 0; x < 512; x++) {
|
||||||
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
||||||
}
|
}
|
||||||
@ -478,7 +528,7 @@ void readMultiROM_PCW() {
|
|||||||
read_setup_PCW();
|
read_setup_PCW();
|
||||||
// Lower Half
|
// Lower Half
|
||||||
switchBank_PCW(0);
|
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++) {
|
for (unsigned int x = 0; x < 512; x++) {
|
||||||
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
||||||
}
|
}
|
||||||
@ -487,7 +537,7 @@ void readMultiROM_PCW() {
|
|||||||
read_setup_PCW();
|
read_setup_PCW();
|
||||||
// Upper Half
|
// Upper Half
|
||||||
switchBank_PCW(1);
|
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++) {
|
for (unsigned int x = 0; x < 512; x++) {
|
||||||
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
sdBuffer[x] = read_rom_byte_PCW(address + x);
|
||||||
}
|
}
|
||||||
@ -513,7 +563,7 @@ void readMultiROM_PCW() {
|
|||||||
// SRAM
|
// SRAM
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
void readSRAM_PCW() { // readSRAM_1A()
|
void readSRAM_PCW() { // readSRAM_1A()
|
||||||
strcpy(fileName, romName);
|
strcpy(fileName, romName);
|
||||||
strcat(fileName, ".srm");
|
strcat(fileName, ".srm");
|
||||||
|
|
||||||
@ -530,7 +580,7 @@ void readSRAM_PCW() { // readSRAM_1A()
|
|||||||
}
|
}
|
||||||
display_Clear();
|
display_Clear();
|
||||||
read_setup_PCW();
|
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++) {
|
for (unsigned int x = 0; x < 512; x++) {
|
||||||
sdBuffer[x] = read_ram_byte_1A_PCW(address + x);
|
sdBuffer[x] = read_ram_byte_1A_PCW(address + x);
|
||||||
}
|
}
|
||||||
@ -563,7 +613,7 @@ void writeSRAM_PCW() {
|
|||||||
//open file on sd card
|
//open file on sd card
|
||||||
if (myFile.open(filePath, O_READ)) {
|
if (myFile.open(filePath, O_READ)) {
|
||||||
read_setup_PCW();
|
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);
|
myFile.read(sdBuffer, 512);
|
||||||
for (unsigned int x = 0; x < 512; x++) {
|
for (unsigned int x = 0; x < 512; x++) {
|
||||||
write_ram_byte_1A_PCW(address + x, sdBuffer[x]);
|
write_ram_byte_1A_PCW(address + x, sdBuffer[x]);
|
||||||
@ -572,12 +622,10 @@ void writeSRAM_PCW() {
|
|||||||
myFile.close();
|
myFile.close();
|
||||||
println_Msg(F("Done"));
|
println_Msg(F("Done"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
display_Clear();
|
display_Clear();
|
||||||
@ -588,7 +636,7 @@ unsigned long verifySRAM_PCW() {
|
|||||||
|
|
||||||
if (myFile.open(filePath, O_READ)) {
|
if (myFile.open(filePath, O_READ)) {
|
||||||
read_setup_PCW();
|
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++) {
|
for (unsigned int x = 0; x < 512; x++) {
|
||||||
byte myByte = read_ram_byte_1A_PCW(address + x);
|
byte myByte = read_ram_byte_1A_PCW(address + x);
|
||||||
sdBuffer[x] = myByte;
|
sdBuffer[x] = myByte;
|
||||||
@ -600,8 +648,7 @@ unsigned long verifySRAM_PCW() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,4 +657,4 @@ unsigned long verifySRAM_PCW() {
|
|||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -35,7 +35,7 @@ boolean hirom[8];
|
|||||||
static const char sfmMenuItem1[] PROGMEM = "Game Menu";
|
static const char sfmMenuItem1[] PROGMEM = "Game Menu";
|
||||||
static const char sfmMenuItem2[] PROGMEM = "Flash Menu";
|
static const char sfmMenuItem2[] PROGMEM = "Flash Menu";
|
||||||
static const char sfmMenuItem3[] PROGMEM = "Reset";
|
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
|
// SFM flash menu items
|
||||||
static const char sfmFlashMenuItem1[] PROGMEM = "Read Flash";
|
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 sfmFlashMenuItem4[] PROGMEM = "Read Mapping";
|
||||||
static const char sfmFlashMenuItem5[] PROGMEM = "Write Mapping";
|
static const char sfmFlashMenuItem5[] PROGMEM = "Write Mapping";
|
||||||
static const char sfmFlashMenuItem6[] PROGMEM = "Back";
|
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
|
// SFM game menu items
|
||||||
static const char sfmGameMenuItem1[] PROGMEM = "Read Sram";
|
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 sfmGameMenuItem3[] PROGMEM = "Write Sram";
|
||||||
static const char sfmGameMenuItem4[] PROGMEM = "Switch Game";
|
static const char sfmGameMenuItem4[] PROGMEM = "Switch Game";
|
||||||
static const char sfmGameMenuItem5[] PROGMEM = "Reset";
|
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() {
|
void sfmMenu() {
|
||||||
// create menu with title and 3 options to choose from
|
// 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);
|
mainMenu = question_box(F("SF Memory"), menuOptions, 3, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
// Game menu
|
// Game menu
|
||||||
case 0:
|
case 0:
|
||||||
sfmGameMenu();
|
sfmGameMenu();
|
||||||
@ -127,8 +126,7 @@ void sfmGameMenu() {
|
|||||||
// Print info
|
// Print info
|
||||||
getCartInfo_SFM();
|
getCartInfo_SFM();
|
||||||
mode = mode_SFM_Game;
|
mode = mode_SFM_Game;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// No menu so switch to only game
|
// No menu so switch to only game
|
||||||
// Switch to game
|
// Switch to game
|
||||||
send_SFM(0x80);
|
send_SFM(0x80);
|
||||||
@ -141,8 +139,7 @@ void sfmGameMenu() {
|
|||||||
getCartInfo_SFM();
|
getCartInfo_SFM();
|
||||||
mode = mode_SFM_Game;
|
mode = mode_SFM_Game;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Switch to HiRom failed"), false);
|
print_Error(F("Switch to HiRom failed"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,8 +152,7 @@ void sfmGameOptions() {
|
|||||||
gameSubMenu = question_box(F("SFM Game Menu"), menuOptions, 5, 0);
|
gameSubMenu = question_box(F("SFM Game Menu"), menuOptions, 5, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (gameSubMenu)
|
switch (gameSubMenu) {
|
||||||
{
|
|
||||||
// Read sram
|
// Read sram
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
@ -185,8 +181,7 @@ void sfmGameOptions() {
|
|||||||
if (wrErrors == 0) {
|
if (wrErrors == 0) {
|
||||||
println_Msg(F("Verified OK"));
|
println_Msg(F("Verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(wrErrors);
|
print_Msg(wrErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
@ -221,8 +216,7 @@ void sfmFlashMenu() {
|
|||||||
flashSubMenu = question_box(F("SFM Flash Menu"), menuOptions, 6, 0);
|
flashSubMenu = question_box(F("SFM Flash Menu"), menuOptions, 6, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (flashSubMenu)
|
switch (flashSubMenu) {
|
||||||
{
|
|
||||||
// Read Flash
|
// Read Flash
|
||||||
case 0:
|
case 0:
|
||||||
// Clear screen
|
// Clear screen
|
||||||
@ -258,8 +252,7 @@ void sfmFlashMenu() {
|
|||||||
|
|
||||||
// Read flash
|
// Read flash
|
||||||
readFlash_SFM();
|
readFlash_SFM();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Switch to HiRom failed"), false);
|
print_Error(F("Switch to HiRom failed"), false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -328,16 +321,13 @@ void sfmFlashMenu() {
|
|||||||
printMapping();
|
printMapping();
|
||||||
resetFlash_SFM(0xC0);
|
resetFlash_SFM(0xC0);
|
||||||
resetFlash_SFM(0xE0);
|
resetFlash_SFM(0xE0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Wrong Flash ID"), true);
|
print_Error(F("Error: Wrong Flash ID"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Wrong Flash ID"), true);
|
print_Error(F("Error: Wrong Flash ID"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("failed"), false);
|
print_Error(F("failed"), false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -368,16 +358,13 @@ void sfmFlashMenu() {
|
|||||||
readMapping();
|
readMapping();
|
||||||
resetFlash_SFM(0xC0);
|
resetFlash_SFM(0xC0);
|
||||||
resetFlash_SFM(0xE0);
|
resetFlash_SFM(0xE0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Wrong Flash ID"), true);
|
print_Error(F("Error: Wrong Flash ID"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Wrong Flash ID"), true);
|
print_Error(F("Error: Wrong Flash ID"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("failed"), false);
|
print_Error(F("failed"), false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -410,8 +397,7 @@ void sfmFlashMenu() {
|
|||||||
if (blankcheckMapping_SFM()) {
|
if (blankcheckMapping_SFM()) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Nope"));
|
println_Msg(F("Nope"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -458,7 +444,7 @@ void getGames() {
|
|||||||
controlIn_SFM();
|
controlIn_SFM();
|
||||||
|
|
||||||
// Check if menu is present
|
// 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++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
if (menuString[i] != readBank_SFM(0xC0, 0x7FC0 + i)) {
|
if (menuString[i] != readBank_SFM(0xC0, 0x7FC0 + i)) {
|
||||||
hasMenu = false;
|
hasMenu = false;
|
||||||
@ -468,7 +454,7 @@ void getGames() {
|
|||||||
if (hasMenu) {
|
if (hasMenu) {
|
||||||
// Count number of games
|
// Count number of games
|
||||||
for (word i = 0x0000; i < 0xE000; i += 0x2000) {
|
for (word i = 0x0000; i < 0xE000; i += 0x2000) {
|
||||||
if (readBank_SFM(0xC6, i) == numGames )
|
if (readBank_SFM(0xC6, i) == numGames)
|
||||||
numGames++;
|
numGames++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,11 +468,9 @@ void getGames() {
|
|||||||
//check if hirom
|
//check if hirom
|
||||||
if (readBank_SFM(gameAddress[i], 0xFFD5) == 0x31) {
|
if (readBank_SFM(gameAddress[i], 0xFFD5) == 0x31) {
|
||||||
hirom[i] = true;
|
hirom[i] = true;
|
||||||
}
|
} else if (readBank_SFM(gameAddress[i], 0xFFD5) == 0x21) {
|
||||||
else if (readBank_SFM(gameAddress[i], 0xFFD5) == 0x21) {
|
|
||||||
hirom[i] = true;
|
hirom[i] = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
hirom[i] = false;
|
hirom[i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,13 +494,11 @@ void getGames() {
|
|||||||
// End char array in case game code is less than 9 chars
|
// End char array in case game code is less than 9 chars
|
||||||
gameCode[i][myLength] = '\0';
|
gameCode[i][myLength] = '\0';
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//check if hirom
|
//check if hirom
|
||||||
if (readBank_SFM(0xC0, 0xFFD5) == 0x31) {
|
if (readBank_SFM(0xC0, 0xFFD5) == 0x31) {
|
||||||
hirom[0] = true;
|
hirom[0] = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
hirom[0] = false;
|
hirom[0] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,8 +519,7 @@ void getGames() {
|
|||||||
gameSize[0] = 1;
|
gameSize[0] = 1;
|
||||||
while (romSizeExp--)
|
while (romSizeExp--)
|
||||||
gameSize[0] *= 2;
|
gameSize[0] *= 2;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
gameVersion[0] = readBank_SFM(0xC0, 0x7FDB);
|
gameVersion[0] = readBank_SFM(0xC0, 0x7FDB);
|
||||||
gameCode[0][0] = 'G';
|
gameCode[0][0] = 'G';
|
||||||
gameCode[0][1] = 'A';
|
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
|
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||||
// Wait till output is stable
|
// Wait till output is stable
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""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
|
// Switch WR(PH5) to LOW
|
||||||
PORTH &= ~(1 << 5);
|
PORTH &= ~(1 << 5);
|
||||||
|
|
||||||
// Leave WR low for at least 60ns
|
// Leave WR low for at least 60ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""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
|
// Switch WR(PH5) to HIGH
|
||||||
PORTH |= (1 << 5);
|
PORTH |= (1 << 5);
|
||||||
|
|
||||||
// Leave WR high for at least 50ns
|
// Leave WR high for at least 50ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""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
|
// 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;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
// 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
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = PINC;
|
||||||
@ -781,10 +814,9 @@ boolean checkcart_SFM() {
|
|||||||
|
|
||||||
romType = readBank_SFM(0, 0xFFD5);
|
romType = readBank_SFM(0, 0xFFD5);
|
||||||
if ((romType >> 5) != 1) { // Detect invalid romType byte due to too long ROM name (22 chars)
|
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)
|
romType = 0; // LoROM // Krusty's Super Fun House (U) 1.0 & Contra 3 (U)
|
||||||
}
|
} else {
|
||||||
else {
|
romType &= 1; // Must be LoROM or HiROM
|
||||||
romType &= 1; // Must be LoROM or HiROM
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check RomSize
|
// Check RomSize
|
||||||
@ -846,8 +878,7 @@ boolean checkcart_SFM() {
|
|||||||
sramSize = 1;
|
sramSize = 1;
|
||||||
while (sramSizeExp--)
|
while (sramSizeExp--)
|
||||||
sramSize *= 2;
|
sramSize *= 2;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
sramSize = 0;
|
sramSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,11 +886,10 @@ boolean checkcart_SFM() {
|
|||||||
romVersion = readBank_SFM(0, 65499);
|
romVersion = readBank_SFM(0, 65499);
|
||||||
|
|
||||||
// Test if checksum is equal to reverse checksum
|
// 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) {
|
if (strcmp("0000", checksumStr) == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -953,8 +983,7 @@ void resetFlash_SFM(int startBank) {
|
|||||||
writeBank_SFM(startBank, 0x5555L * 2, 0xaa);
|
writeBank_SFM(startBank, 0x5555L * 2, 0xaa);
|
||||||
writeBank_SFM(startBank, 0x2AAAL * 2, 0x55);
|
writeBank_SFM(startBank, 0x2AAAL * 2, 0x55);
|
||||||
writeBank_SFM(startBank, 0x5555L * 2, 0xf0);
|
writeBank_SFM(startBank, 0x5555L * 2, 0xf0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
||||||
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
||||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xf0);
|
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xf0);
|
||||||
@ -981,8 +1010,7 @@ void idFlash_SFM(int startBank) {
|
|||||||
|
|
||||||
// Read the two id bytes into a string
|
// Read the two id bytes into a string
|
||||||
sprintf(flashid, "%x%x", readBank_SFM(startBank, 0x00), readBank_SFM(startBank, 0x02));
|
sprintf(flashid, "%x%x", readBank_SFM(startBank, 0x00), readBank_SFM(startBank, 0x02));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
||||||
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
||||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0x90);
|
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0x90);
|
||||||
@ -1042,8 +1070,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) {
|
|||||||
busyCheck_SFM(startBank);
|
busyCheck_SFM(startBank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Write lorom
|
// Write lorom
|
||||||
for (int currBank = 0; currBank < numBanks; currBank++) {
|
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 128) {
|
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 128) {
|
||||||
@ -1070,8 +1097,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) {
|
|||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
println_Msg("");
|
println_Msg("");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Can't open file on SD"), true);
|
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, 0x5555L * 2, 0xaa);
|
||||||
writeBank_SFM(startBank, 0x2AAAL * 2, 0x55);
|
writeBank_SFM(startBank, 0x2AAAL * 2, 0x55);
|
||||||
writeBank_SFM(startBank, 0x5555L * 2, 0x10);
|
writeBank_SFM(startBank, 0x5555L * 2, 0x10);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0xaa);
|
||||||
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
writeBank_SFM(0, 0x8000 + 0x2AAAL * 2, 0x55);
|
||||||
writeBank_SFM(1, 0x8000 + 0x1555L * 2, 0x80);
|
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 (int currBank = startBank; currBank < startBank + numBanks; currBank++) {
|
||||||
for (unsigned long currByte = 0; currByte < 0x10000; currByte++) {
|
for (unsigned long currByte = 0; currByte < 0x10000; currByte++) {
|
||||||
if (readBank_SFM(currBank, currByte) != 0xFF) {
|
if (readBank_SFM(currBank, currByte) != 0xFF) {
|
||||||
currBank = startBank + numBanks;
|
currBank = startBank + numBanks;
|
||||||
blank = 0;
|
blank = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (int currBank = 0; currBank < numBanks; currBank++) {
|
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte++) {
|
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte++) {
|
||||||
if (readBank_SFM(currBank, currByte) != 0xFF) {
|
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
|
// 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 verifyFlash_SFM(int startBank, uint32_t pos) {
|
||||||
unsigned long verified = 0;
|
unsigned long verified = 0;
|
||||||
|
|
||||||
// Open file on sd card
|
// Open file on sd card
|
||||||
if (myFile.open(filePath, O_READ)) {
|
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 (int currBank = 0; currBank < numBanks; currBank++) {
|
||||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 512) {
|
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 512) {
|
||||||
// Fill SDBuffer
|
// Fill SDBuffer
|
||||||
@ -1215,8 +1238,7 @@ unsigned long verifyFlash_SFM(int startBank, uint32_t pos) {
|
|||||||
}
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// SD Error
|
// SD Error
|
||||||
verified = 999999;
|
verified = 999999;
|
||||||
print_Error(F("Can't open file on SD"), false);
|
print_Error(F("Can't open file on SD"), false);
|
||||||
@ -1250,8 +1272,7 @@ void readFlash_SFM() {
|
|||||||
myFile.write(sdBuffer, 512);
|
myFile.write(sdBuffer, 512);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (int currBank = 0; currBank < numBanks; currBank++) {
|
for (int currBank = 0; currBank < numBanks; currBank++) {
|
||||||
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 512) {
|
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 512) {
|
||||||
for (int c = 0; c < 512; c++) {
|
for (int c = 0; c < 512; c++) {
|
||||||
@ -1320,7 +1341,7 @@ void printMapping() {
|
|||||||
|
|
||||||
for (int currByte = 0xFF00; currByte < 0xFF50; currByte += 10) {
|
for (int currByte = 0xFF00; currByte < 0xFF50; currByte += 10) {
|
||||||
for (int c = 0; c < 10; c++) {
|
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++) {
|
for (int i = 0; i < 2 - strlen(buffer); i++) {
|
||||||
print_Msg(F("0"));
|
print_Msg(F("0"));
|
||||||
}
|
}
|
||||||
@ -1469,12 +1490,10 @@ void eraseMapping(byte startBank) {
|
|||||||
// Switch to read
|
// Switch to read
|
||||||
dataIn();
|
dataIn();
|
||||||
controlIn_SFM();
|
controlIn_SFM();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Wrong Flash ID"), true);
|
print_Error(F("Error: Wrong Flash ID"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Unlock failed"), true);
|
print_Error(F("Unlock failed"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1599,20 +1618,17 @@ void writeMapping_SFM(byte startBank, uint32_t pos) {
|
|||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
println_Msg("");
|
println_Msg("");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Can't open file on SD"), false);
|
print_Error(F("Can't open file on SD"), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch to read
|
// Switch to read
|
||||||
dataIn();
|
dataIn();
|
||||||
controlIn_SFM();
|
controlIn_SFM();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Wrong Flash ID"), true);
|
print_Error(F("Error: Wrong Flash ID"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Unlock failed"), true);
|
print_Error(F("Unlock failed"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1636,14 +1652,12 @@ boolean unlockHirom() {
|
|||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("failed"));
|
println_Msg(F("failed"));
|
||||||
display_Update();
|
display_Update();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("failed"));
|
println_Msg(F("failed"));
|
||||||
display_Update();
|
display_Update();
|
||||||
return 0;
|
return 0;
|
||||||
@ -1709,8 +1723,7 @@ void write_SFM(int startBank, uint32_t pos) {
|
|||||||
if (blankcheck_SFM(startBank)) {
|
if (blankcheck_SFM(startBank)) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("Nope"));
|
println_Msg(F("Nope"));
|
||||||
display_Clear();
|
display_Clear();
|
||||||
print_Msg(F("Erasing..."));
|
print_Msg(F("Erasing..."));
|
||||||
@ -1723,8 +1736,7 @@ void write_SFM(int startBank, uint32_t pos) {
|
|||||||
if (blankcheck_SFM(startBank)) {
|
if (blankcheck_SFM(startBank)) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Could not erase flash"), true);
|
print_Error(F("Could not erase flash"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1741,19 +1753,16 @@ void write_SFM(int startBank, uint32_t pos) {
|
|||||||
if (writeErrors == 0) {
|
if (writeErrors == 0) {
|
||||||
println_Msg(F("OK"));
|
println_Msg(F("OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(writeErrors);
|
print_Msg(writeErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
print_Error(F("did not verify."), true);
|
print_Error(F("did not verify."), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Error: Wrong Flash ID"), true);
|
print_Error(F("Error: Wrong Flash ID"), true);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Unlock failed"), true);
|
print_Error(F("Unlock failed"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1762,4 +1771,4 @@ void write_SFM(int startBank, uint32_t pos) {
|
|||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -12,7 +12,7 @@ static const char SMSAdapterItem2[] PROGMEM = "SG-1000 raphnet";
|
|||||||
static const char SMSAdapterItem3[] PROGMEM = "SMS Retrode";
|
static const char SMSAdapterItem3[] PROGMEM = "SMS Retrode";
|
||||||
static const char SMSAdapterItem4[] PROGMEM = "GG Retrode";
|
static const char SMSAdapterItem4[] PROGMEM = "GG Retrode";
|
||||||
static const char SMSAdapterItem5[] PROGMEM = "GG Retron 3in1";
|
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
|
// MD menu items
|
||||||
static const char SMSMenuItem1[] PROGMEM = "Read Rom";
|
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 SMSMenuItem3[] PROGMEM = "Write to SRAM";
|
||||||
static const char SMSMenuItem4[] PROGMEM = "Reset";
|
static const char SMSMenuItem4[] PROGMEM = "Reset";
|
||||||
static const char SMSMenuItem5[] PROGMEM = "Change Retrode Mode";
|
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
|
// Rom Size menu
|
||||||
static const char SMSRomItem1[] PROGMEM = "8KB";
|
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 SMSRomItem5[] PROGMEM = "40KB";
|
||||||
static const char SMSRomItem6[] PROGMEM = "48KB";
|
static const char SMSRomItem6[] PROGMEM = "48KB";
|
||||||
static const char SMSRomItem7[] PROGMEM = "512KB";
|
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
|
// Set retrode_mode to true when using a retrode SMS/GG adapter
|
||||||
static bool retrode_mode = false;
|
static bool retrode_mode = false;
|
||||||
static bool retrode_mode_sms = false; // true: SMS/Mark3 false: GG
|
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 raphnet_mode_sg1000 = false; // true: SG-1000 false: SMS/Mark3
|
||||||
static bool retron_mode = false;
|
static bool retron_mode = false;
|
||||||
|
|
||||||
|
|
||||||
@ -48,21 +48,18 @@ void _smsMenu() {
|
|||||||
int noptions = sizeof(menuOptionsSMS) / sizeof(menuOptionsSMS[0]);
|
int noptions = sizeof(menuOptionsSMS) / sizeof(menuOptionsSMS[0]);
|
||||||
convertPgm(menuOptionsSMS, noptions);
|
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);
|
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
|
// Copy menuOptions out of progmem
|
||||||
convertPgm(menuOptionsSMS, 4);
|
convertPgm(menuOptionsSMS, 4);
|
||||||
mainMenu = question_box(F("Game Gear"), menuOptions, 4, 0);
|
mainMenu = question_box(F("Game Gear"), menuOptions, 4, 0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Copy menuOptions out of progmem
|
// Copy menuOptions out of progmem
|
||||||
convertPgm(menuOptionsSMS, (raphnet_mode_sg1000 ? 1 : 4));
|
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);
|
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
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
display_Clear();
|
display_Clear();
|
||||||
mode = mode_SMS;
|
mode = mode_SMS;
|
||||||
@ -72,8 +69,7 @@ void _smsMenu() {
|
|||||||
readROM_SMS();
|
readROM_SMS();
|
||||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||||
compareCRC("gg.txt", 0, 1, 0);
|
compareCRC("gg.txt", 0, 1, 0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
compareCRC("sms.txt", 0, 1, 0);
|
compareCRC("sms.txt", 0, 1, 0);
|
||||||
}
|
}
|
||||||
#ifdef global_log
|
#ifdef global_log
|
||||||
@ -117,8 +113,7 @@ void _smsMenu() {
|
|||||||
if (retrode_mode) {
|
if (retrode_mode) {
|
||||||
println_Msg(retrode_mode ? (retrode_mode_sms ? F("Retrode Mode SMS") : F("Retrode Mode GG")) : F("Retrode Mode Off"));
|
println_Msg(retrode_mode ? (retrode_mode_sms ? F("Retrode Mode SMS") : F("Retrode Mode GG")) : F("Retrode Mode Off"));
|
||||||
println_Msg(F("Press Button..."));
|
println_Msg(F("Press Button..."));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F(""));
|
println_Msg(F(""));
|
||||||
println_Msg(F("Press Button..."));
|
println_Msg(F("Press Button..."));
|
||||||
}
|
}
|
||||||
@ -134,8 +129,7 @@ void smsMenu() {
|
|||||||
SMSAdapterMenu = question_box(F("Select System/Adapter"), menuOptions, 5, 0);
|
SMSAdapterMenu = question_box(F("Select System/Adapter"), menuOptions, 5, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (SMSAdapterMenu)
|
switch (SMSAdapterMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
// raphnet SMS/Mark3
|
// raphnet SMS/Mark3
|
||||||
retrode_mode = false;
|
retrode_mode = false;
|
||||||
@ -267,7 +261,10 @@ void writeByte_SMS(word myAddress, byte myData) {
|
|||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||||
// Wait till output is stable
|
// Wait till output is stable
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
if (retrode_mode) {
|
if (retrode_mode) {
|
||||||
// Switch WR(PL5) and OE/CE(PH6) to LOW
|
// 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
|
// 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) {
|
if (retrode_mode) {
|
||||||
// Switch WR(PL5) and OE/CE(PH6) to HIGH
|
// 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
|
// 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) {
|
if (retrode_mode && !retrode_mode_sms) {
|
||||||
// Set Data Pins (D8-D15) to Input
|
// Set Data Pins (D8-D15) to Input
|
||||||
@ -321,7 +324,10 @@ byte readByte_SMS(word myAddress) {
|
|||||||
PORTH = (PORTH & 0b11110111) | ((myAddress >> 12) & 0b00001000);
|
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) {
|
if (retrode_mode) {
|
||||||
// Switch RD(PL6) and OE(PH6) to LOW
|
// Switch RD(PL6) and OE(PH6) to LOW
|
||||||
@ -333,7 +339,10 @@ byte readByte_SMS(word myAddress) {
|
|||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t"
|
||||||
|
"nop\n\t");
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
byte tempByte = (retrode_mode && !retrode_mode_sms) ? PINA : PINC;
|
byte tempByte = (retrode_mode && !retrode_mode_sms) ? PINA : PINC;
|
||||||
@ -348,7 +357,10 @@ byte readByte_SMS(word myAddress) {
|
|||||||
PORTL |= (1 << 1);
|
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;
|
return tempByte;
|
||||||
}
|
}
|
||||||
@ -372,38 +384,38 @@ void getCartInfo_SMS() {
|
|||||||
switch (readNibble(readByte_SMS(0x7fff), 0)) {
|
switch (readNibble(readByte_SMS(0x7fff), 0)) {
|
||||||
case 0xa:
|
case 0xa:
|
||||||
// Adding UL gets rid of integer overflow compiler warning
|
// Adding UL gets rid of integer overflow compiler warning
|
||||||
cartSize = 8 * 1024UL;
|
cartSize = 8 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0xb:
|
case 0xb:
|
||||||
cartSize = 16 * 1024UL;
|
cartSize = 16 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0xc:
|
case 0xc:
|
||||||
cartSize = 32 * 1024UL;
|
cartSize = 32 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0xd:
|
case 0xd:
|
||||||
cartSize = 48 * 1024UL;
|
cartSize = 48 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0xe:
|
case 0xe:
|
||||||
cartSize = 64 * 1024UL;
|
cartSize = 64 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0xf:
|
case 0xf:
|
||||||
cartSize = 128 * 1024UL;
|
cartSize = 128 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0x0:
|
case 0x0:
|
||||||
cartSize = 256 * 1024UL;
|
cartSize = 256 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
cartSize = 512 * 1024UL;
|
cartSize = 512 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
cartSize = 512 * 1024UL;
|
cartSize = 512 * 1024UL;
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
// 0x3 is (only?) used in The Pro Yakyuu '91 (Game Gear)
|
// 0x3 is (only?) used in The Pro Yakyuu '91 (Game Gear)
|
||||||
cartSize = 128 * 1024UL;
|
cartSize = 128 * 1024UL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cartSize = 48 * 1024UL;
|
cartSize = 48 * 1024UL;
|
||||||
|
|
||||||
// LED Error
|
// LED Error
|
||||||
setColor_RGB(0, 0, 255);
|
setColor_RGB(0, 0, 255);
|
||||||
@ -455,7 +467,7 @@ void getCartInfo_SMS() {
|
|||||||
|
|
||||||
if (strcmp(headerFZ, "COPYRIGHT SEGAPRG. BY T.ASAI") == 0) {
|
if (strcmp(headerFZ, "COPYRIGHT SEGAPRG. BY T.ASAI") == 0) {
|
||||||
strcpy(romName, "TMR SEGA");
|
strcpy(romName, "TMR SEGA");
|
||||||
cartSize = 128 * 1024UL;
|
cartSize = 128 * 1024UL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,45 +476,44 @@ void getCartInfo_SMS() {
|
|||||||
// Set cartsize manually
|
// Set cartsize manually
|
||||||
unsigned char SMSRomMenu;
|
unsigned char SMSRomMenu;
|
||||||
// Copy menuOptions out of progmem
|
// Copy menuOptions out of progmem
|
||||||
convertPgm(romOptionsSMS, (raphnet_mode_sg1000 ? 4 : 7));
|
convertPgm(romOptionsSMS, (raphnet_mode_sg1000 ? 4 : 7));
|
||||||
SMSRomMenu = question_box(F("Select ROM size"), menuOptions, (raphnet_mode_sg1000 ? 4 : 7), 0);
|
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
|
// wait for user choice to come back from the question box menu
|
||||||
switch (SMSRomMenu)
|
switch (SMSRomMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
// 8KB
|
// 8KB
|
||||||
cartSize = 8 * 1024UL;
|
cartSize = 8 * 1024UL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// 16KB
|
// 16KB
|
||||||
cartSize = 16 * 1024UL;
|
cartSize = 16 * 1024UL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// 24KB
|
// 24KB
|
||||||
cartSize = 24 * 1024UL;
|
cartSize = 24 * 1024UL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
// 32KB
|
// 32KB
|
||||||
cartSize = 32 * 1024UL;
|
cartSize = 32 * 1024UL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
// 40KB
|
// 40KB
|
||||||
cartSize = 40 * 1024UL;
|
cartSize = 40 * 1024UL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
// 48KB
|
// 48KB
|
||||||
cartSize = 48 * 1024UL;
|
cartSize = 48 * 1024UL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
// 512KB
|
// 512KB
|
||||||
cartSize = 512 * 1024UL;
|
cartSize = 512 * 1024UL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -523,8 +534,7 @@ void getCartInfo_SMS() {
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||||
println_Msg(F("GG Header Info"));
|
println_Msg(F("GG Header Info"));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
println_Msg(F("SMS Header Info"));
|
println_Msg(F("SMS Header Info"));
|
||||||
}
|
}
|
||||||
println_Msg(F(" "));
|
println_Msg(F(" "));
|
||||||
@ -552,8 +562,7 @@ void readROM_SMS() {
|
|||||||
strcpy(fileName, romName);
|
strcpy(fileName, romName);
|
||||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||||
strcat(fileName, ".gg");
|
strcat(fileName, ".gg");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
strcat(fileName, ".sms");
|
strcat(fileName, ".sms");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,8 +570,7 @@ void readROM_SMS() {
|
|||||||
EEPROM_readAnything(0, foldern);
|
EEPROM_readAnything(0, foldern);
|
||||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||||
sprintf(folder, "GG/ROM/%s/%d", romName, foldern);
|
sprintf(folder, "GG/ROM/%s/%d", romName, foldern);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
sprintf(folder, "SMS/ROM/%s/%d", romName, foldern);
|
sprintf(folder, "SMS/ROM/%s/%d", romName, foldern);
|
||||||
}
|
}
|
||||||
sd.mkdir(folder, true);
|
sd.mkdir(folder, true);
|
||||||
@ -609,7 +617,7 @@ void readROM_SMS() {
|
|||||||
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
|
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
|
||||||
// Fill SD buffer
|
// Fill SD buffer
|
||||||
for (int currByte = 0; currByte < 512; currByte++) {
|
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:
|
// hexdump for debugging:
|
||||||
// if (currBank == 0 && currBuffer == 0) {
|
// if (currBank == 0 && currBuffer == 0) {
|
||||||
@ -647,8 +655,7 @@ void readSRAM_SMS() {
|
|||||||
EEPROM_readAnything(0, foldern);
|
EEPROM_readAnything(0, foldern);
|
||||||
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
if ((retrode_mode && !retrode_mode_sms) || retron_mode) {
|
||||||
sprintf(folder, "GG/SAVE/%s/%d", romName, foldern);
|
sprintf(folder, "GG/SAVE/%s/%d", romName, foldern);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
sprintf(folder, "SMS/SAVE/%s/%d", romName, foldern);
|
sprintf(folder, "SMS/SAVE/%s/%d", romName, foldern);
|
||||||
}
|
}
|
||||||
sd.mkdir(folder, true);
|
sd.mkdir(folder, true);
|
||||||
@ -694,8 +701,7 @@ void writeSRAM_SMS() {
|
|||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
print_Error(F("DISABLED"), false);
|
print_Error(F("DISABLED"), false);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fileBrowser(F("Select file"));
|
fileBrowser(F("Select file"));
|
||||||
|
|
||||||
sd.chdir();
|
sd.chdir();
|
||||||
@ -736,19 +742,18 @@ void writeSRAM_SMS() {
|
|||||||
println_Msg(F(""));
|
println_Msg(F(""));
|
||||||
println_Msg(F("DONE"));
|
println_Msg(F("DONE"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("SD ERROR"), true);
|
print_Error(F("SD ERROR"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
display_Clear();
|
display_Clear();
|
||||||
|
|
||||||
sd.chdir(); // root
|
sd.chdir(); // root
|
||||||
filePath[0] = '\0'; // Reset filePath
|
filePath[0] = '\0'; // Reset filePath
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
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 svMenu();
|
||||||
void readROM_SV();
|
void readROM_SV();
|
||||||
//void setup_SV();
|
//void setup_SV();
|
||||||
void writeROM_SV (void);
|
void writeROM_SV(void);
|
||||||
void eraseCheck_SV(void);
|
void eraseCheck_SV(void);
|
||||||
void supplyCheck_SV(void);
|
void supplyCheck_SV(void);
|
||||||
void writeCheck_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 svFlashMenuItem3[] PROGMEM = "Read BS-X Sram";
|
||||||
static const char svFlashMenuItem4[] PROGMEM = "Write BS-X Sram";
|
static const char svFlashMenuItem4[] PROGMEM = "Write BS-X Sram";
|
||||||
static const char svFlashMenuItem5[] PROGMEM = "Back";
|
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() {
|
void svMenu() {
|
||||||
@ -49,8 +49,7 @@ void svMenu() {
|
|||||||
mainMenu = question_box(F("Satellaview 8M Memory"), menuOptions, 5, 0);
|
mainMenu = question_box(F("Satellaview 8M Memory"), menuOptions, 5, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
// Read memory pack
|
// Read memory pack
|
||||||
case 0:
|
case 0:
|
||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
@ -82,8 +81,7 @@ void svMenu() {
|
|||||||
if (wrErrors == 0) {
|
if (wrErrors == 0) {
|
||||||
println_Msg(F("Verified OK"));
|
println_Msg(F("Verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(wrErrors);
|
print_Msg(wrErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
@ -181,7 +179,7 @@ void setup_SV() {
|
|||||||
//PORTJ &= ~(1 << 0);
|
//PORTJ &= ~(1 << 0);
|
||||||
|
|
||||||
// Start CIC by outputting a low signal to cicrstPin(PG1)
|
// Start CIC by outputting a low signal to cicrstPin(PG1)
|
||||||
PORTG &= ~(1 << 1);
|
PORTG &= ~(1 << 1);
|
||||||
|
|
||||||
// Wait for CIC reset
|
// Wait for CIC reset
|
||||||
delay(1000);
|
delay(1000);
|
||||||
@ -199,19 +197,56 @@ void writeBank_SV(byte myBank, word myAddress, byte myData) {
|
|||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||||
// Wait till output is stable
|
// Wait till output is stable
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""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
|
// Switch WR(PH5) to LOW
|
||||||
PORTH &= ~(1 << 5);
|
PORTH &= ~(1 << 5);
|
||||||
|
|
||||||
// Leave WR low for at least 60ns
|
// Leave WR low for at least 60ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""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
|
// Switch WR(PH5) to HIGH
|
||||||
PORTH |= (1 << 5);
|
PORTH |= (1 << 5);
|
||||||
|
|
||||||
// Leave WR high for at least 50ns
|
// Leave WR high for at least 50ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""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
|
// 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;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
|
// 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
|
// Read
|
||||||
byte tempByte = PINC;
|
byte tempByte = PINC;
|
||||||
@ -231,7 +281,7 @@ byte readBank_SV(byte myBank, word myAddress) {
|
|||||||
/******************************************
|
/******************************************
|
||||||
SatellaView BS-X Sram functions
|
SatellaView BS-X Sram functions
|
||||||
*****************************************/
|
*****************************************/
|
||||||
void readSRAM_SV () {
|
void readSRAM_SV() {
|
||||||
// set control
|
// set control
|
||||||
controlIn_SNES();
|
controlIn_SNES();
|
||||||
|
|
||||||
@ -254,7 +304,7 @@ void readSRAM_SV () {
|
|||||||
}
|
}
|
||||||
int sramBanks = 0;
|
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
|
// Sram size
|
||||||
long lastByte = (long(sramSize) * 0x80);
|
long lastByte = (long(sramSize) * 0x80);
|
||||||
|
|
||||||
@ -325,8 +375,7 @@ void writeSRAM_SV() {
|
|||||||
println_Msg("");
|
println_Msg("");
|
||||||
println_Msg(F("SRAM writing finished"));
|
println_Msg(F("SRAM writing finished"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("File doesnt exist"), false);
|
print_Error(F("File doesnt exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,8 +410,7 @@ unsigned long verifySRAM_SV() {
|
|||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
return writeErrors;
|
return writeErrors;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Can't open file"), false);
|
print_Error(F("Can't open file"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,7 +460,7 @@ void readROM_SV() {
|
|||||||
myFile.write(sdBuffer, 512);
|
myFile.write(sdBuffer, 512);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
draw_progressbar(0x100000, 0x100000); //Finish drawing progress bar
|
draw_progressbar(0x100000, 0x100000); //Finish drawing progress bar
|
||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
@ -421,15 +469,14 @@ void readROM_SV() {
|
|||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeROM_SV (void) {
|
void writeROM_SV(void) {
|
||||||
// Get Checksum as string to make sure that BS-X cart is inserted
|
// Get Checksum as string to make sure that BS-X cart is inserted
|
||||||
dataIn();
|
dataIn();
|
||||||
controlIn_SNES();
|
controlIn_SNES();
|
||||||
sprintf(checksumStr, "%02X%02X", readBank_SV(0, 65503), readBank_SV(0, 65502));
|
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 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();
|
display_Clear();
|
||||||
print_Error(F("Error: Must use BS-X cart"), true);
|
print_Error(F("Error: Must use BS-X cart"), true);
|
||||||
}
|
}
|
||||||
@ -457,8 +504,8 @@ void writeROM_SV (void) {
|
|||||||
//Disable 8M memory pack write protection
|
//Disable 8M memory pack write protection
|
||||||
dataOut();
|
dataOut();
|
||||||
controlOut_SNES();
|
controlOut_SNES();
|
||||||
writeBank_SV(0x0C, 0x5000, 0x80); //Modify write enable register
|
writeBank_SV(0x0C, 0x5000, 0x80); //Modify write enable register
|
||||||
writeBank_SV(0x0E, 0x5000, 0x80); //Commit register modification
|
writeBank_SV(0x0E, 0x5000, 0x80); //Commit register modification
|
||||||
|
|
||||||
//Erase memory pack
|
//Erase memory pack
|
||||||
println_Msg(F("Erasing pack..."));
|
println_Msg(F("Erasing pack..."));
|
||||||
@ -474,8 +521,7 @@ void writeROM_SV (void) {
|
|||||||
for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
|
for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
|
||||||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
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(""));
|
||||||
println_Msg(F("Erase failed"));
|
println_Msg(F("Erase failed"));
|
||||||
display_Update();
|
display_Update();
|
||||||
@ -496,30 +542,29 @@ void writeROM_SV (void) {
|
|||||||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
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(currBank, currByte, myFile.read());
|
||||||
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
||||||
writeCheck_SV();
|
writeCheck_SV();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
writeBank_SV(0xC0, 0x0000, 0x70); //Status Mode
|
||||||
writeCheck_SV();
|
writeCheck_SV();
|
||||||
writeBank_SV(0xC0, 0x0000, 0xFF); //Terminate write
|
writeBank_SV(0xC0, 0x0000, 0xFF); //Terminate write
|
||||||
draw_progressbar(0x100000, 0x100000);
|
draw_progressbar(0x100000, 0x100000);
|
||||||
|
|
||||||
|
|
||||||
//Verify
|
//Verify
|
||||||
dataIn(); //Set pins to input
|
dataIn(); //Set pins to input
|
||||||
controlIn_SNES();
|
controlIn_SNES();
|
||||||
myFile.seekSet(0); // Go back to file beginning
|
myFile.seekSet(0); // Go back to file beginning
|
||||||
println_Msg(F("Verifying..."));
|
println_Msg(F("Verifying..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
|
for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
|
||||||
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
|
||||||
for (long currByte = 0; currByte < 65536; currByte++) {
|
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(""));
|
||||||
println_Msg(F("Verify failed"));
|
println_Msg(F("Verify failed"));
|
||||||
display_Update();
|
display_Update();
|
||||||
@ -537,8 +582,7 @@ void writeROM_SV (void) {
|
|||||||
display_Update();
|
display_Update();
|
||||||
wait();
|
wait();
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("File doesn't exist"), false);
|
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
|
// CE or OE must be toggled with each subsequent status read or the
|
||||||
// completion of a program or erase operation will not be evident.
|
// 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();
|
controlOut_SNES();
|
||||||
// Switch CS(PH3) High
|
// Switch CS(PH3) High
|
||||||
PORTH |= (1 << 3);
|
PORTH |= (1 << 3);
|
||||||
// Leave CE high for at least 60ns
|
// 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();
|
controlIn_SNES();
|
||||||
// Leave CE low for at least 50ns
|
// 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
|
// Read register
|
||||||
ret = readBank_SV(0xC0, 0x0004);
|
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
|
// CE or OE must be toggled with each subsequent status read or the
|
||||||
// completion of a program or erase operation will not be evident.
|
// 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();
|
controlOut_SNES();
|
||||||
// Switch CS(PH3) High
|
// Switch CS(PH3) High
|
||||||
PORTH |= (1 << 3);
|
PORTH |= (1 << 3);
|
||||||
// Leave CE high for at least 60ns
|
// 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();
|
controlIn_SNES();
|
||||||
// Leave CE low for at least 50ns
|
// 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
|
// Read register
|
||||||
ret = readBank_SV(0xC0, 0x0004);
|
ret = readBank_SV(0xC0, 0x0004);
|
||||||
}
|
}
|
||||||
@ -612,10 +676,20 @@ void writeCheck_SV(void) {
|
|||||||
// Switch CS(PH3) High
|
// Switch CS(PH3) High
|
||||||
PORTH |= (1 << 3);
|
PORTH |= (1 << 3);
|
||||||
// Leave CE high for at least 60ns
|
// 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();
|
controlIn_SNES();
|
||||||
// Leave CE low for at least 50ns
|
// 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
|
// Read register
|
||||||
ret = readBank_SV(0xC0, 0x0000);
|
ret = readBank_SV(0xC0, 0x0000);
|
||||||
}
|
}
|
||||||
@ -638,8 +712,7 @@ void detectCheck_SV(void) {
|
|||||||
// completion of a program or erase operation will not be evident.
|
// completion of a program or erase operation will not be evident.
|
||||||
while ((ret & 0x80) == 0x00) {
|
while ((ret & 0x80) == 0x00) {
|
||||||
i++;
|
i++;
|
||||||
if ( i > 10000)
|
if (i > 10000) {
|
||||||
{
|
|
||||||
//timeout
|
//timeout
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -647,10 +720,20 @@ void detectCheck_SV(void) {
|
|||||||
// Switch CS(PH3) High
|
// Switch CS(PH3) High
|
||||||
PORTH |= (1 << 3);
|
PORTH |= (1 << 3);
|
||||||
// Leave CE high for at least 60ns
|
// 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();
|
controlIn_SNES();
|
||||||
// Leave CE low for at least 50ns
|
// 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
|
// Read register
|
||||||
ret = readBank_SV(0xC0, 0x0002);
|
ret = readBank_SV(0xC0, 0x0002);
|
||||||
}
|
}
|
||||||
@ -660,22 +743,21 @@ void detectCheck_SV(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void eraseAll_SV(void)
|
void eraseAll_SV(void) {
|
||||||
{
|
|
||||||
dataOut();
|
dataOut();
|
||||||
controlOut_SNES();
|
controlOut_SNES();
|
||||||
writeBank_SV(0xC0, 0x0000, 0x50); //Clear Status Registers
|
writeBank_SV(0xC0, 0x0000, 0x50); //Clear Status Registers
|
||||||
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
||||||
supplyCheck_SV();
|
supplyCheck_SV();
|
||||||
writeBank_SV(0xC0, 0x0000, 0xA7); //Chip Erase
|
writeBank_SV(0xC0, 0x0000, 0xA7); //Chip Erase
|
||||||
writeBank_SV(0xC0, 0x0000, 0xD0); //Confirm
|
writeBank_SV(0xC0, 0x0000, 0xD0); //Confirm
|
||||||
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
writeBank_SV(0xC0, 0x0000, 0x71); //Status Mode
|
||||||
eraseCheck_SV();
|
eraseCheck_SV();
|
||||||
writeBank_SV(0xC0, 0x0000, 0xFF); //Teriminate
|
writeBank_SV(0xC0, 0x0000, 0xFF); //Teriminate
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -55,8 +55,7 @@
|
|||||||
// SETUP
|
// SETUP
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
void setup_VBOY()
|
void setup_VBOY() {
|
||||||
{
|
|
||||||
// Set Address Pins to Output
|
// Set Address Pins to Output
|
||||||
//A0-A7
|
//A0-A7
|
||||||
DDRF = 0xFF;
|
DDRF = 0xFF;
|
||||||
@ -70,7 +69,7 @@ void setup_VBOY()
|
|||||||
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)
|
// Set TIME(PJ0) to Output (UNUSED)
|
||||||
DDRJ |= (1 << 0);
|
DDRJ |= (1 << 0);
|
||||||
|
|
||||||
// Set Pins (D0-D15) to Input
|
// Set Pins (D0-D15) to Input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
@ -83,7 +82,7 @@ void setup_VBOY()
|
|||||||
PORTH &= ~(1 << 0);
|
PORTH &= ~(1 << 0);
|
||||||
|
|
||||||
// Set Unused Pins HIGH
|
// Set Unused Pins HIGH
|
||||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||||
|
|
||||||
getCartInfo_VB();
|
getCartInfo_VB();
|
||||||
|
|
||||||
@ -99,15 +98,13 @@ static const char vboyMenuItem1[] PROGMEM = "Read ROM";
|
|||||||
static const char vboyMenuItem2[] PROGMEM = "Read SRAM";
|
static const char vboyMenuItem2[] PROGMEM = "Read SRAM";
|
||||||
static const char vboyMenuItem3[] PROGMEM = "Write SRAM";
|
static const char vboyMenuItem3[] PROGMEM = "Write SRAM";
|
||||||
static const char vboyMenuItem4[] PROGMEM = "Reset";
|
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);
|
convertPgm(menuOptionsVBOY, 4);
|
||||||
uint8_t mainMenu = question_box(F("VIRTUALBOY MENU"), menuOptions, 4, 0);
|
uint8_t mainMenu = question_box(F("VIRTUALBOY MENU"), menuOptions, 4, 0);
|
||||||
|
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
// Read ROM
|
// Read ROM
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
@ -124,8 +121,7 @@ void vboyMenu()
|
|||||||
display_Update();
|
display_Update();
|
||||||
readSRAM_VB();
|
readSRAM_VB();
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Cart has no SRAM"), false);
|
print_Error(F("Cart has no SRAM"), false);
|
||||||
}
|
}
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
@ -148,15 +144,13 @@ void vboyMenu()
|
|||||||
if (writeErrors == 0) {
|
if (writeErrors == 0) {
|
||||||
println_Msg(F("SRAM verified OK"));
|
println_Msg(F("SRAM verified OK"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(writeErrors);
|
print_Msg(writeErrors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
print_Error(F("did not verify."), false);
|
print_Error(F("did not verify."), false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Cart has no SRAM"), false);
|
print_Error(F("Cart has no SRAM"), false);
|
||||||
}
|
}
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
#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
|
// Set /CS1(PH4), /WE0(PH5) to LOW
|
||||||
PORTH &= ~(1 << 4) & ~(1 << 5);
|
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
|
// Set CS2(PH0), /CS1(PH4), /WE0(PH5) to HIGH
|
||||||
PORTH |= (1 << 0) | (1 << 4) | (1 << 5);
|
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) {
|
word readWord_VB(unsigned long myAddress) {
|
||||||
@ -212,21 +216,31 @@ word readWord_VB(unsigned long myAddress) {
|
|||||||
// Set /CE(PH3), /OE(PH6) to LOW
|
// Set /CE(PH3), /OE(PH6) to LOW
|
||||||
PORTH &= ~(1 << 3) & ~(1 << 6);
|
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
|
// Set /CE(PH3), /OE(PH6) to HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 6);
|
PORTH |= (1 << 3) | (1 << 6);
|
||||||
// Setting CS2(PH0) LOW
|
// Setting CS2(PH0) LOW
|
||||||
PORTH &= ~(1 << 0);
|
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;
|
return tempWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte readByte_VB(unsigned long myAddress) { // SRAM BYTE
|
byte readByte_VB(unsigned long myAddress) { // SRAM BYTE
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 0xFF;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
PORTL = (myAddress >> 16) & 0xFF;
|
PORTL = (myAddress >> 16) & 0xFF;
|
||||||
@ -238,18 +252,33 @@ byte readByte_VB(unsigned long myAddress) { // SRAM BYTE
|
|||||||
// Set /CS1(PH4), /OE(PH6) to LOW
|
// Set /CS1(PH4), /OE(PH6) to LOW
|
||||||
PORTH &= ~(1 << 4) & ~(1 << 6);
|
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;
|
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
|
// Set /CS1(PH4), /OE(PH6) to HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 6);
|
PORTH |= (1 << 3) | (1 << 6);
|
||||||
// Setting CS2(PH0) LOW
|
// Setting CS2(PH0) LOW
|
||||||
PORTH &= ~(1 << 0);
|
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;
|
return tempByte;
|
||||||
}
|
}
|
||||||
@ -277,52 +306,51 @@ void getCartInfo_VB() {
|
|||||||
cartSize = 0;
|
cartSize = 0;
|
||||||
for (unsigned long address = 0x80000; address <= 0x400000; address *= 2) {
|
for (unsigned long address = 0x80000; address <= 0x400000; address *= 2) {
|
||||||
// Get Serial
|
// Get Serial
|
||||||
word vbSerial = readWord_VB((address - 0x204) / 2); // Cart Serial
|
word vbSerial = readWord_VB((address - 0x204) / 2); // Cart Serial
|
||||||
|
|
||||||
switch (vbSerial)
|
switch (vbSerial) {
|
||||||
{
|
case 0x4D54: // MT = Mario's Tennis
|
||||||
case 0x4D54: // MT = Mario's Tennis
|
case 0x4832: // H2 = Panic Bomber/Tobidase! Panibomb
|
||||||
case 0x4832: // H2 = Panic Bomber/Tobidase! Panibomb
|
case 0x5350: // SP = Space Invaders
|
||||||
case 0x5350: // SP = Space Invaders
|
case 0x5353: // SS = Space Squash
|
||||||
case 0x5353: // SS = Space Squash
|
case 0x5452: // TR = V-Tetris
|
||||||
case 0x5452: // TR = V-Tetris
|
cartSize = 0x80000; // 512KB
|
||||||
cartSize = 0x80000; // 512KB
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x494D: // IM = Insmouse no Yakata
|
case 0x494D: // IM = Insmouse no Yakata
|
||||||
case 0x4A42: // JB = Jack Bros.
|
case 0x4A42: // JB = Jack Bros.
|
||||||
case 0x4D43: // MC = Mario Clash
|
case 0x4D43: // MC = Mario Clash
|
||||||
case 0x5245: // RE = Red Alarm
|
case 0x5245: // RE = Red Alarm
|
||||||
case 0x4833: // H3 = Vertical Force
|
case 0x4833: // H3 = Vertical Force
|
||||||
case 0x5642: // VB = Virtual Bowling
|
case 0x5642: // VB = Virtual Bowling
|
||||||
case 0x5646: // VF = Virtual Fishing
|
case 0x5646: // VF = Virtual Fishing
|
||||||
case 0x4A56: // JV = Virtual Lab
|
case 0x4A56: // JV = Virtual Lab
|
||||||
case 0x5650: // VP = Virtual League Baseball/Virtual Pro Yakyuu '95
|
case 0x5650: // VP = Virtual League Baseball/Virtual Pro Yakyuu '95
|
||||||
cartSize = 0x100000; // 1MB
|
cartSize = 0x100000; // 1MB
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x5042: // PB = 3-D Tetris
|
case 0x5042: // PB = 3-D Tetris
|
||||||
case 0x4750: // GP = Galactic Pinball
|
case 0x4750: // GP = Galactic Pinball
|
||||||
case 0x5344: // SD = SD Gundam Dimension War
|
case 0x5344: // SD = SD Gundam Dimension War
|
||||||
case 0x5442: // TB = Teleroboxer
|
case 0x5442: // TB = Teleroboxer
|
||||||
cartSize = 0x100000; // 1MB
|
cartSize = 0x100000; // 1MB
|
||||||
sramSize = 0x2000; // 8KB
|
sramSize = 0x2000; // 8KB
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x5647: // VG = Golf/T&E Virtual Golf
|
case 0x5647: // VG = Golf/T&E Virtual Golf
|
||||||
case 0x4E46: // NF = Nester's Funky Bowling
|
case 0x4E46: // NF = Nester's Funky Bowling
|
||||||
case 0x5745: // WE = Waterworld
|
case 0x5745: // WE = Waterworld
|
||||||
cartSize = 0x200000; // 2MB
|
cartSize = 0x200000; // 2MB
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x5743: // WC = Virtual Boy Wario Land
|
case 0x5743: // WC = Virtual Boy Wario Land
|
||||||
cartSize = 0x200000; // 2MB
|
cartSize = 0x200000; // 2MB
|
||||||
sramSize = 0x2000; // 8KB
|
sramSize = 0x2000; // 8KB
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x4644: // FD = Hyper Fighting
|
case 0x4644: // FD = Hyper Fighting
|
||||||
cartSize = 0x400000; // 4MB
|
cartSize = 0x400000; // 4MB
|
||||||
sramSize = 0x2000; // 8KB
|
sramSize = 0x2000; // 8KB
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,14 +383,13 @@ void getCartInfo_VB() {
|
|||||||
print_Msg(F("Name: "));
|
print_Msg(F("Name: "));
|
||||||
println_Msg(romName);
|
println_Msg(romName);
|
||||||
print_Msg(F("Size: "));
|
print_Msg(F("Size: "));
|
||||||
print_Msg(cartSize * 8 / 1024 / 1024 );
|
print_Msg(cartSize * 8 / 1024 / 1024);
|
||||||
println_Msg(F(" MBit"));
|
println_Msg(F(" MBit"));
|
||||||
print_Msg(F("Sram: "));
|
print_Msg(F("Sram: "));
|
||||||
if (sramSize > 0) {
|
if (sramSize > 0) {
|
||||||
print_Msg(sramSize * 8 / 1024);
|
print_Msg(sramSize * 8 / 1024);
|
||||||
println_Msg(F(" KBit"));
|
println_Msg(F(" KBit"));
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
println_Msg(F("None"));
|
println_Msg(F("None"));
|
||||||
println_Msg(F(" "));
|
println_Msg(F(" "));
|
||||||
|
|
||||||
@ -413,20 +440,19 @@ void readROM_VB() {
|
|||||||
for (int currWord = 0; currWord < 256; currWord++) {
|
for (int currWord = 0; currWord < 256; currWord++) {
|
||||||
word myWord = readWord_VB(currBuffer + currWord);
|
word myWord = readWord_VB(currBuffer + currWord);
|
||||||
// Split word into two bytes
|
// Split word into two bytes
|
||||||
sdBuffer[d] = (( myWord >> 8 ) & 0xFF);
|
sdBuffer[d] = ((myWord >> 8) & 0xFF);
|
||||||
sdBuffer[d + 1] = (myWord & 0xFF);
|
sdBuffer[d + 1] = (myWord & 0xFF);
|
||||||
d += 2;
|
d += 2;
|
||||||
}
|
}
|
||||||
myFile.write(sdBuffer, 512);
|
myFile.write(sdBuffer, 512);
|
||||||
d = 0;
|
d = 0;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 256) {
|
for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 256) {
|
||||||
for (int currWord = 0; currWord < 256; currWord++) {
|
for (int currWord = 0; currWord < 256; currWord++) {
|
||||||
word myWord = readWord_VB(currBuffer + currWord);
|
word myWord = readWord_VB(currBuffer + currWord);
|
||||||
// Split word into two bytes
|
// Split word into two bytes
|
||||||
sdBuffer[d] = (( myWord >> 8 ) & 0xFF);
|
sdBuffer[d] = ((myWord >> 8) & 0xFF);
|
||||||
sdBuffer[d + 1] = (myWord & 0xFF);
|
sdBuffer[d + 1] = (myWord & 0xFF);
|
||||||
d += 2;
|
d += 2;
|
||||||
}
|
}
|
||||||
@ -469,8 +495,7 @@ void writeSRAM_VB() {
|
|||||||
myFile.close();
|
myFile.close();
|
||||||
println_Msg(F("Done"));
|
println_Msg(F("Done"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
dataIn_VB();
|
dataIn_VB();
|
||||||
@ -524,8 +549,7 @@ unsigned long verifySRAM_VB() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,4 +558,4 @@ unsigned long verifySRAM_VB() {
|
|||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -37,7 +37,7 @@ static const char wsMenuItem2[] PROGMEM = "Read Save";
|
|||||||
static const char wsMenuItem3[] PROGMEM = "Write Save";
|
static const char wsMenuItem3[] PROGMEM = "Write Save";
|
||||||
static const char wsMenuItem4[] PROGMEM = "Reset";
|
static const char wsMenuItem4[] PROGMEM = "Reset";
|
||||||
static const char wsMenuItem5[] PROGMEM = "Write WitchOS";
|
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 };
|
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 uint8_t wsEepromShiftReg[2];
|
||||||
static boolean wsWitch = false;
|
static boolean wsWitch = false;
|
||||||
|
|
||||||
void setup_WS()
|
void setup_WS() {
|
||||||
{
|
|
||||||
// A-1 - A6
|
// A-1 - A6
|
||||||
DDRF = 0xff;
|
DDRF = 0xff;
|
||||||
// A7 - A14
|
// A7 - A14
|
||||||
@ -88,8 +87,7 @@ void setup_WS()
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
unlockMMC2003_WS();
|
unlockMMC2003_WS();
|
||||||
}
|
} while (!headerCheck());
|
||||||
while (!headerCheck());
|
|
||||||
|
|
||||||
getCartInfo_WS();
|
getCartInfo_WS();
|
||||||
|
|
||||||
@ -100,18 +98,18 @@ boolean headerCheck() {
|
|||||||
dataIn_WS();
|
dataIn_WS();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < 16; i += 2)
|
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];
|
uint8_t startByte = sdBuffer[0];
|
||||||
if (startByte == 0xEA) { // Start should be 0xEA
|
if (startByte == 0xEA) { // Start should be 0xEA
|
||||||
uint8_t zeroByte = sdBuffer[5];
|
uint8_t zeroByte = sdBuffer[5];
|
||||||
if (zeroByte == 0) { // Zero Byte
|
if (zeroByte == 0) { // Zero Byte
|
||||||
uint8_t systemByte = sdBuffer[7];
|
uint8_t systemByte = sdBuffer[7];
|
||||||
if (systemByte < 2) { // System < 2
|
if (systemByte < 2) { // System < 2
|
||||||
uint8_t revisionByte = sdBuffer[9];
|
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];
|
uint8_t sizeByte = sdBuffer[10];
|
||||||
if (sizeByte < 10) // Rom Size < 10
|
if (sizeByte < 10) // Rom Size < 10
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,15 +118,13 @@ boolean headerCheck() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsMenu()
|
void wsMenu() {
|
||||||
{
|
|
||||||
uint8_t mainMenu = (wsWitch ? 5 : 4);
|
uint8_t mainMenu = (wsWitch ? 5 : 4);
|
||||||
|
|
||||||
convertPgm(menuOptionsWS, mainMenu);
|
convertPgm(menuOptionsWS, mainMenu);
|
||||||
mainMenu = question_box(F("WS Menu"), menuOptions, mainMenu, 0);
|
mainMenu = question_box(F("WS Menu"), menuOptions, mainMenu, 0);
|
||||||
|
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
// Read Rom
|
// Read Rom
|
||||||
@ -142,8 +138,7 @@ void wsMenu()
|
|||||||
{
|
{
|
||||||
// Read Save
|
// Read Save
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
switch (saveType)
|
switch (saveType) {
|
||||||
{
|
|
||||||
case 0: println_Msg(F("No save for this game")); break;
|
case 0: println_Msg(F("No save for this game")); break;
|
||||||
case 1: readSRAM_WS(); break;
|
case 1: readSRAM_WS(); break;
|
||||||
case 2: readEEPROM_WS(); break;
|
case 2: readEEPROM_WS(); break;
|
||||||
@ -156,8 +151,7 @@ void wsMenu()
|
|||||||
{
|
{
|
||||||
// Write Save
|
// Write Save
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
switch (saveType)
|
switch (saveType) {
|
||||||
{
|
|
||||||
case 0: println_Msg(F("No save for this game")); break;
|
case 0: println_Msg(F("No save for this game")); break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
@ -184,7 +178,7 @@ void wsMenu()
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// reset
|
// reset
|
||||||
asm volatile (" jmp 0");
|
asm volatile(" jmp 0");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,20 +190,18 @@ void wsMenu()
|
|||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getCartInfo_WS()
|
uint8_t getCartInfo_WS() {
|
||||||
{
|
|
||||||
dataIn_WS();
|
dataIn_WS();
|
||||||
|
|
||||||
// for (uint32_t i = 0; i < 16; i += 2)
|
// 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);
|
||||||
|
|
||||||
wsGameChecksum = *(uint16_t*)(sdBuffer + 14);
|
wsGameChecksum = *(uint16_t *)(sdBuffer + 14);
|
||||||
wsWitch = false;
|
wsWitch = false;
|
||||||
|
|
||||||
// some game has wrong info in header
|
// some game has wrong info in header
|
||||||
// patch here
|
// patch here
|
||||||
switch (wsGameChecksum)
|
switch (wsGameChecksum) {
|
||||||
{
|
|
||||||
// games with wrong save type/size
|
// games with wrong save type/size
|
||||||
// 256kbits sram
|
// 256kbits sram
|
||||||
case 0xe600: // BAN007
|
case 0xe600: // BAN007
|
||||||
@ -247,11 +239,9 @@ uint8_t getCartInfo_WS()
|
|||||||
{
|
{
|
||||||
// developerId/cartId/checksum are all filled with 0x00 in witch based games
|
// developerId/cartId/checksum are all filled with 0x00 in witch based games
|
||||||
dataIn_WS();
|
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
|
// check witch BIOS
|
||||||
if (readWord_WS(0xfff5e) == 0x006c && readWord_WS(0xfff60) == 0x5b1b)
|
if (readWord_WS(0xfff5e) == 0x006c && readWord_WS(0xfff60) == 0x5b1b) {
|
||||||
{
|
|
||||||
// check flashchip
|
// check flashchip
|
||||||
// should be a MBM29DL400TC
|
// should be a MBM29DL400TC
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
@ -272,39 +262,30 @@ uint8_t getCartInfo_WS()
|
|||||||
sdBuffer[8] = 0x03;
|
sdBuffer[8] = 0x03;
|
||||||
}
|
}
|
||||||
// check service menu
|
// check service menu
|
||||||
else if (readWord_WS(0xfff22) == 0x006c && readWord_WS(0xfff24) == 0x5b1b)
|
else if (readWord_WS(0xfff22) == 0x006c && readWord_WS(0xfff24) == 0x5b1b) {
|
||||||
{
|
if (readWord_WS(0x93246) == 0x4a2f && readWord_WS(0x93248) == 0x5353 && readWord_WS(0x9324a) == 0x2e32) {
|
||||||
if (readWord_WS(0x93246) == 0x4a2f && readWord_WS(0x93248) == 0x5353 && readWord_WS(0x9324a) == 0x2e32)
|
|
||||||
{
|
|
||||||
// jss2
|
// jss2
|
||||||
sdBuffer[6] = 0xff; // WWGP
|
sdBuffer[6] = 0xff; // WWGP
|
||||||
sdBuffer[8] = 0x1a; // 2001A
|
sdBuffer[8] = 0x1a; // 2001A
|
||||||
sdBuffer[7] = 0x01; // color only
|
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
|
// WWGP2001A3 -> HFP Version
|
||||||
sdBuffer[9] = 0x03;
|
sdBuffer[9] = 0x03;
|
||||||
wsGameChecksum = 0x4870;
|
wsGameChecksum = 0x4870;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO check other jss2 version
|
// 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
|
// dknight
|
||||||
sdBuffer[6] = 0xff; // WWGP
|
sdBuffer[6] = 0xff; // WWGP
|
||||||
sdBuffer[8] = 0x2b; // 2002B
|
sdBuffer[8] = 0x2b; // 2002B
|
||||||
sdBuffer[7] = 0x01; // color only
|
sdBuffer[7] = 0x01; // color only
|
||||||
sdBuffer[9] = 0x00;
|
sdBuffer[9] = 0x00;
|
||||||
wsGameChecksum = 0x8b1c;
|
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
|
// Mobile WonderGate v1.1, checksum is filled with 0x0000
|
||||||
wsGameChecksum = 0x1da0;
|
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];
|
romVersion = sdBuffer[9];
|
||||||
romSize = sdBuffer[10];
|
romSize = sdBuffer[10];
|
||||||
sramSize = sdBuffer[11];
|
sramSize = sdBuffer[11];
|
||||||
@ -325,8 +306,7 @@ uint8_t getCartInfo_WS()
|
|||||||
snprintf(checksumStr, 5, "%04X", wsGameChecksum);
|
snprintf(checksumStr, 5, "%04X", wsGameChecksum);
|
||||||
snprintf(romName, 17, "%s%s", vendorID, cartID);
|
snprintf(romName, 17, "%s%s", vendorID, cartID);
|
||||||
|
|
||||||
switch (romSize)
|
switch (romSize) {
|
||||||
{
|
|
||||||
case 0x01: cartSize = 131072 * 2; break;
|
case 0x01: cartSize = 131072 * 2; break;
|
||||||
case 0x02: cartSize = 131072 * 4; break;
|
case 0x02: cartSize = 131072 * 4; break;
|
||||||
case 0x03: cartSize = 131072 * 8; break;
|
case 0x03: cartSize = 131072 * 8; break;
|
||||||
@ -339,17 +319,43 @@ uint8_t getCartInfo_WS()
|
|||||||
default: cartSize = 0; break;
|
default: cartSize = 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sramSize)
|
switch (sramSize) {
|
||||||
{
|
case 0x00:
|
||||||
case 0x00: saveType = 0; sramSize = 0; break;
|
saveType = 0;
|
||||||
case 0x01: saveType = 1; sramSize = 64; break;
|
sramSize = 0;
|
||||||
case 0x02: saveType = 1; sramSize = 256; break;
|
break;
|
||||||
case 0x03: saveType = 1; sramSize = 1024; break;
|
case 0x01:
|
||||||
case 0x04: saveType = 1; sramSize = 2048; break;
|
saveType = 1;
|
||||||
case 0x05: saveType = 1; sramSize = 4096; break;
|
sramSize = 64;
|
||||||
case 0x10: saveType = 2; sramSize = 1; break;
|
break;
|
||||||
case 0x20: saveType = 2; sramSize = 16; break;
|
case 0x02:
|
||||||
case 0x50: saveType = 2; sramSize = 8; break;
|
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;
|
default: saveType = 0xff; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,8 +366,7 @@ uint8_t getCartInfo_WS()
|
|||||||
return sdBuffer[0];
|
return sdBuffer[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void showCartInfo_WS()
|
void showCartInfo_WS() {
|
||||||
{
|
|
||||||
display_Clear();
|
display_Clear();
|
||||||
|
|
||||||
println_Msg(F("WS Cart Info"));
|
println_Msg(F("WS Cart Info"));
|
||||||
@ -372,18 +377,24 @@ void showCartInfo_WS()
|
|||||||
print_Msg(F("Rom Size: "));
|
print_Msg(F("Rom Size: "));
|
||||||
if (cartSize == 0x00)
|
if (cartSize == 0x00)
|
||||||
println_Msg(romSize, HEX);
|
println_Msg(romSize, HEX);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
print_Msg((cartSize >> 17));
|
print_Msg((cartSize >> 17));
|
||||||
println_Msg(F(" Mb"));
|
println_Msg(F(" Mb"));
|
||||||
}
|
}
|
||||||
|
|
||||||
print_Msg(F("Save: "));
|
print_Msg(F("Save: "));
|
||||||
switch (saveType)
|
switch (saveType) {
|
||||||
{
|
|
||||||
case 0: println_Msg(F("None")); break;
|
case 0: println_Msg(F("None")); break;
|
||||||
case 1: print_Msg(F("Sram ")); print_Msg(sramSize); println_Msg(F(" Kb")); break;
|
case 1:
|
||||||
case 2: print_Msg(F("Eeprom ")); print_Msg(sramSize); println_Msg(F(" Kb")); break;
|
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;
|
default: println_Msg(sramSize, HEX); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,15 +409,13 @@ void showCartInfo_WS()
|
|||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getDeveloperName(uint8_t id, char *buf, size_t length)
|
void getDeveloperName(uint8_t id, char *buf, size_t length) {
|
||||||
{
|
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char *devName = NULL;
|
char *devName = NULL;
|
||||||
|
|
||||||
switch (id)
|
switch (id) {
|
||||||
{
|
|
||||||
case 0x01: devName = PSTR("BAN"); break;
|
case 0x01: devName = PSTR("BAN"); break;
|
||||||
case 0x02: devName = PSTR("TAT"); break;
|
case 0x02: devName = PSTR("TAT"); break;
|
||||||
case 0x03: devName = PSTR("TMY"); 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 0x1e: devName = PSTR("NAP"); break;
|
||||||
case 0x1f: devName = PSTR("BVL"); break;
|
case 0x1f: devName = PSTR("BVL"); break;
|
||||||
case 0x20: devName = PSTR("ATN"); 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 0x22: devName = PSTR("HAL"); break;
|
||||||
case 0x23: devName = PSTR("YKE"); break;
|
case 0x23: devName = PSTR("YKE"); break;
|
||||||
case 0x24: devName = PSTR("OMM"); break;
|
case 0x24: devName = PSTR("OMM"); break;
|
||||||
@ -452,17 +461,18 @@ void getDeveloperName(uint8_t id, char *buf, size_t length)
|
|||||||
|
|
||||||
// custom developerId
|
// custom developerId
|
||||||
case 0x7a: devName = PSTR("7AC"); break; // witch
|
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
|
// if not found, use id
|
||||||
default: snprintf(buf, length, "%02X", id); return;
|
default: snprintf(buf, length, "%02X", id); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy_P(buf, devName, length);
|
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
|
// generate fullname of rom file
|
||||||
snprintf(fileName, FILENAME_LENGTH, "%s.ws%c", romName, ((romType & 1) ? 'c' : '\0'));
|
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);
|
draw_progressbar(0, cartSize);
|
||||||
|
|
||||||
// start reading rom
|
// start reading rom
|
||||||
for (; bank <= 0xff; bank++)
|
for (; bank <= 0xff; bank++) {
|
||||||
{
|
|
||||||
// switch bank on segment 0x2
|
// switch bank on segment 0x2
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
writeByte_WSPort(0xc2, bank);
|
writeByte_WSPort(0xc2, bank);
|
||||||
@ -508,14 +517,13 @@ void readROM_WS(char *outPathBuf, size_t bufferSize)
|
|||||||
writeByte_WSPort(0xcd, (bank & 0x03));
|
writeByte_WSPort(0xcd, (bank & 0x03));
|
||||||
|
|
||||||
dataIn_WS();
|
dataIn_WS();
|
||||||
for (uint32_t addr = 0; addr < 0x10000; addr += 512)
|
for (uint32_t addr = 0; addr < 0x10000; addr += 512) {
|
||||||
{
|
|
||||||
// blink LED
|
// blink LED
|
||||||
if ((addr & ((1 << 14) - 1)) == 0)
|
if ((addr & ((1 << 14) - 1)) == 0)
|
||||||
blinkLED();
|
blinkLED();
|
||||||
|
|
||||||
for (uint32_t w = 0; w < 512; w += 2)
|
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);
|
myFile.write(sdBuffer, 512);
|
||||||
progress += 512;
|
progress += 512;
|
||||||
@ -525,8 +533,7 @@ void readROM_WS(char *outPathBuf, size_t bufferSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// turn off LEDs (only for BANC33)
|
// turn off LEDs (only for BANC33)
|
||||||
if (wsGameChecksum == 0xeafd)
|
if (wsGameChecksum == 0xeafd) {
|
||||||
{
|
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
writeByte_WSPort(0xcd, 0x00);
|
writeByte_WSPort(0xcd, 0x00);
|
||||||
}
|
}
|
||||||
@ -534,8 +541,7 @@ void readROM_WS(char *outPathBuf, size_t bufferSize)
|
|||||||
myFile.close();
|
myFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void readSRAM_WS()
|
void readSRAM_WS() {
|
||||||
{
|
|
||||||
// generate fullname of rom file
|
// generate fullname of rom file
|
||||||
snprintf(fileName, FILENAME_LENGTH, "%s.sav", romName);
|
snprintf(fileName, FILENAME_LENGTH, "%s.sav", romName);
|
||||||
|
|
||||||
@ -565,14 +571,12 @@ void readSRAM_WS()
|
|||||||
|
|
||||||
uint16_t bank = 0;
|
uint16_t bank = 0;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
writeByte_WSPort(0xc1, bank);
|
writeByte_WSPort(0xc1, bank);
|
||||||
|
|
||||||
dataIn_WS();
|
dataIn_WS();
|
||||||
for (uint32_t addr = 0; addr < bank_size; addr += 512)
|
for (uint32_t addr = 0; addr < bank_size; addr += 512) {
|
||||||
{
|
|
||||||
// blink LED
|
// blink LED
|
||||||
if ((addr & ((1 << 14) - 1)) == 0)
|
if ((addr & ((1 << 14) - 1)) == 0)
|
||||||
blinkLED();
|
blinkLED();
|
||||||
@ -591,13 +595,11 @@ void readSRAM_WS()
|
|||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void verifySRAM_WS()
|
void verifySRAM_WS() {
|
||||||
{
|
|
||||||
print_Msg(F("Verifying... "));
|
print_Msg(F("Verifying... "));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
if (myFile.open(filePath, O_READ))
|
if (myFile.open(filePath, O_READ)) {
|
||||||
{
|
|
||||||
uint32_t bank_size = (sramSize << 7);
|
uint32_t bank_size = (sramSize << 7);
|
||||||
uint16_t end_bank = (bank_size >> 16); // 64KB per bank
|
uint16_t end_bank = (bank_size >> 16); // 64KB per bank
|
||||||
uint16_t bank = 0;
|
uint16_t bank = 0;
|
||||||
@ -606,19 +608,16 @@ void verifySRAM_WS()
|
|||||||
if (bank_size > 0x10000)
|
if (bank_size > 0x10000)
|
||||||
bank_size = 0x10000;
|
bank_size = 0x10000;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
writeByte_WSPort(0xc1, bank);
|
writeByte_WSPort(0xc1, bank);
|
||||||
|
|
||||||
dataIn_WS();
|
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);
|
myFile.read(sdBuffer, 512);
|
||||||
|
|
||||||
// SRAM data on D0-D7, with A-1 to select high/low byte
|
// 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])
|
if (readByte_WS(0x10000 + addr + w) != sdBuffer[w])
|
||||||
write_errors++;
|
write_errors++;
|
||||||
}
|
}
|
||||||
@ -627,27 +626,21 @@ void verifySRAM_WS()
|
|||||||
|
|
||||||
myFile.close();
|
myFile.close();
|
||||||
|
|
||||||
if (write_errors == 0)
|
if (write_errors == 0) {
|
||||||
{
|
|
||||||
println_Msg(F("passed"));
|
println_Msg(F("passed"));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
println_Msg(F("failed"));
|
println_Msg(F("failed"));
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(write_errors);
|
print_Msg(write_errors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
print_Error(F("did not verify."), false);
|
print_Error(F("did not verify."), false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Error(F("File doesn't exist"), false);
|
print_Error(F("File doesn't exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeSRAM_WS()
|
void writeSRAM_WS() {
|
||||||
{
|
|
||||||
filePath[0] = 0;
|
filePath[0] = 0;
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
fileBrowser(F("Select sav file"));
|
fileBrowser(F("Select sav file"));
|
||||||
@ -659,8 +652,7 @@ void writeSRAM_WS()
|
|||||||
println_Msg(F("..."));
|
println_Msg(F("..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
if (myFile.open(filePath, O_READ))
|
if (myFile.open(filePath, O_READ)) {
|
||||||
{
|
|
||||||
uint32_t bank_size = (sramSize << 7);
|
uint32_t bank_size = (sramSize << 7);
|
||||||
uint16_t end_bank = (bank_size >> 16); // 64KB per bank
|
uint16_t end_bank = (bank_size >> 16); // 64KB per bank
|
||||||
|
|
||||||
@ -669,12 +661,10 @@ void writeSRAM_WS()
|
|||||||
|
|
||||||
uint16_t bank = 0;
|
uint16_t bank = 0;
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
writeByte_WSPort(0xc1, bank);
|
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
|
// blink LED
|
||||||
if ((addr & ((1 << 14) - 1)) == 0)
|
if ((addr & ((1 << 14) - 1)) == 0)
|
||||||
blinkLED();
|
blinkLED();
|
||||||
@ -691,15 +681,12 @@ void writeSRAM_WS()
|
|||||||
|
|
||||||
println_Msg(F("Writing finished"));
|
println_Msg(F("Writing finished"));
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Error(F("File doesn't exist"), false);
|
print_Error(F("File doesn't exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void readEEPROM_WS()
|
void readEEPROM_WS() {
|
||||||
{
|
|
||||||
// generate fullname of eep file
|
// generate fullname of eep file
|
||||||
snprintf(fileName, FILENAME_LENGTH, "%s.eep", romName);
|
snprintf(fileName, FILENAME_LENGTH, "%s.eep", romName);
|
||||||
|
|
||||||
@ -724,10 +711,8 @@ void readEEPROM_WS()
|
|||||||
uint32_t eepromSize = (sramSize << 7);
|
uint32_t eepromSize = (sramSize << 7);
|
||||||
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
|
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) {
|
||||||
{
|
for (uint32_t j = 0; j < bufSize; j += 2) {
|
||||||
for (uint32_t j = 0; j < bufSize; j += 2)
|
|
||||||
{
|
|
||||||
// blink LED
|
// blink LED
|
||||||
if ((j & 0x1f) == 0x00)
|
if ((j & 0x1f) == 0x00)
|
||||||
blinkLED();
|
blinkLED();
|
||||||
@ -756,23 +741,19 @@ void readEEPROM_WS()
|
|||||||
println_Msg(F("Done"));
|
println_Msg(F("Done"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void verifyEEPROM_WS()
|
void verifyEEPROM_WS() {
|
||||||
{
|
|
||||||
print_Msg(F("Verifying... "));
|
print_Msg(F("Verifying... "));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
if (myFile.open(filePath, O_READ))
|
if (myFile.open(filePath, O_READ)) {
|
||||||
{
|
|
||||||
uint32_t write_errors = 0;
|
uint32_t write_errors = 0;
|
||||||
uint32_t eepromSize = (sramSize << 7);
|
uint32_t eepromSize = (sramSize << 7);
|
||||||
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
|
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);
|
myFile.read(sdBuffer, bufSize);
|
||||||
|
|
||||||
for (uint32_t j = 0; j < bufSize; j += 2)
|
for (uint32_t j = 0; j < bufSize; j += 2) {
|
||||||
{
|
|
||||||
// blink LED
|
// blink LED
|
||||||
if ((j & 0x1f) == 0x00)
|
if ((j & 0x1f) == 0x00)
|
||||||
blinkLED();
|
blinkLED();
|
||||||
@ -799,27 +780,21 @@ void verifyEEPROM_WS()
|
|||||||
|
|
||||||
myFile.close();
|
myFile.close();
|
||||||
|
|
||||||
if (write_errors == 0)
|
if (write_errors == 0) {
|
||||||
{
|
|
||||||
println_Msg(F("passed"));
|
println_Msg(F("passed"));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
println_Msg(F("failed"));
|
println_Msg(F("failed"));
|
||||||
print_Msg(F("Error: "));
|
print_Msg(F("Error: "));
|
||||||
print_Msg(write_errors);
|
print_Msg(write_errors);
|
||||||
println_Msg(F(" bytes "));
|
println_Msg(F(" bytes "));
|
||||||
print_Error(F("did not verify."), false);
|
print_Error(F("did not verify."), false);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Error(F("File doesn't exist"), false);
|
print_Error(F("File doesn't exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeEEPROM_WS()
|
void writeEEPROM_WS() {
|
||||||
{
|
|
||||||
filePath[0] = 0;
|
filePath[0] = 0;
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
fileBrowser(F("Select eep file"));
|
fileBrowser(F("Select eep file"));
|
||||||
@ -831,17 +806,14 @@ void writeEEPROM_WS()
|
|||||||
println_Msg(F("..."));
|
println_Msg(F("..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
if (myFile.open(filePath, O_READ))
|
if (myFile.open(filePath, O_READ)) {
|
||||||
{
|
|
||||||
uint32_t eepromSize = (sramSize << 7);
|
uint32_t eepromSize = (sramSize << 7);
|
||||||
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
|
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);
|
myFile.read(sdBuffer, bufSize);
|
||||||
|
|
||||||
for (uint32_t j = 0; j < bufSize; j += 2)
|
for (uint32_t j = 0; j < bufSize; j += 2) {
|
||||||
{
|
|
||||||
// blink LED
|
// blink LED
|
||||||
if ((j & 0x1f) == 0x00)
|
if ((j & 0x1f) == 0x00)
|
||||||
blinkLED();
|
blinkLED();
|
||||||
@ -861,23 +833,19 @@ void writeEEPROM_WS()
|
|||||||
dataIn_WS();
|
dataIn_WS();
|
||||||
do {
|
do {
|
||||||
pulseCLK_WS(128);
|
pulseCLK_WS(128);
|
||||||
}
|
} while ((readByte_WSPort(0xc8) & 0x02) == 0x00);
|
||||||
while ((readByte_WSPort(0xc8) & 0x02) == 0x00);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
myFile.close();
|
myFile.close();
|
||||||
|
|
||||||
println_Msg(F("Done"));
|
println_Msg(F("Done"));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Error(F("File doesn't exist"), false);
|
print_Error(F("File doesn't exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeWitchOS_WS()
|
void writeWitchOS_WS() {
|
||||||
{
|
|
||||||
// make sure that OS sectors not protected
|
// make sure that OS sectors not protected
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
writeWord_WS(0x80aaa, 0xaaaa);
|
writeWord_WS(0x80aaa, 0xaaaa);
|
||||||
@ -885,13 +853,10 @@ void writeWitchOS_WS()
|
|||||||
writeWord_WS(0xe0aaa, 0x9090);
|
writeWord_WS(0xe0aaa, 0x9090);
|
||||||
|
|
||||||
dataIn_WS();
|
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();
|
display_Clear();
|
||||||
print_Error(F("OS sectors are protected!"), false);
|
print_Error(F("OS sectors are protected!"), false);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
filePath[0] = 0;
|
filePath[0] = 0;
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
fileBrowser(F("Select fbin file"));
|
fileBrowser(F("Select fbin file"));
|
||||||
@ -899,8 +864,7 @@ void writeWitchOS_WS()
|
|||||||
|
|
||||||
display_Clear();
|
display_Clear();
|
||||||
|
|
||||||
if (myFile.open(filePath, O_READ))
|
if (myFile.open(filePath, O_READ)) {
|
||||||
{
|
|
||||||
println_Msg(F("Erasing OS..."));
|
println_Msg(F("Erasing OS..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
eraseWitchFlashSector_WS(0xe0000);
|
eraseWitchFlashSector_WS(0xe0000);
|
||||||
@ -930,8 +894,7 @@ void writeWitchOS_WS()
|
|||||||
writeWord_WS(0x80aaa, 0x2020);
|
writeWord_WS(0x80aaa, 0x2020);
|
||||||
|
|
||||||
// 128bytes per block
|
// 128bytes per block
|
||||||
for (i = 0; i < fbin_length; i += 128)
|
for (i = 0; i < fbin_length; i += 128) {
|
||||||
{
|
|
||||||
// blink LED
|
// blink LED
|
||||||
if ((i & 0x3ff) == 0)
|
if ((i & 0x3ff) == 0)
|
||||||
blinkLED();
|
blinkLED();
|
||||||
@ -940,8 +903,7 @@ void writeWitchOS_WS()
|
|||||||
key = 0xff;
|
key = 0xff;
|
||||||
bytes_read = myFile.read(sdBuffer, 128);
|
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
|
// for each decoded[n] = encoded[n] ^ key
|
||||||
// where key = encoded[n - 1]
|
// where key = encoded[n - 1]
|
||||||
// key = 0xff when n = 0, 0 <= n < 128
|
// key = 0xff when n = 0, 0 <= n < 128
|
||||||
@ -954,10 +916,10 @@ void writeWitchOS_WS()
|
|||||||
|
|
||||||
// write jmpf instruction and block counts at 0xe0000
|
// write jmpf instruction and block counts at 0xe0000
|
||||||
memcpy_P(sdBuffer, wwLaunchCode, 8);
|
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)
|
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
|
// leave fast program mode
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
@ -967,9 +929,7 @@ void writeWitchOS_WS()
|
|||||||
myFile.close();
|
myFile.close();
|
||||||
|
|
||||||
println_Msg(F("Done"));
|
println_Msg(F("Done"));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Error(F("File doesn't exist"), false);
|
print_Error(F("File doesn't exist"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -978,19 +938,18 @@ void writeWitchOS_WS()
|
|||||||
writeWord_WS(0x80000, 0xf0f0);
|
writeWord_WS(0x80000, 0xf0f0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fastProgramWitchFlash_WS(uint32_t addr, uint16_t data)
|
void fastProgramWitchFlash_WS(uint32_t addr, uint16_t data) {
|
||||||
{
|
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
|
|
||||||
writeWord_WS(addr, 0xa0a0);
|
writeWord_WS(addr, 0xa0a0);
|
||||||
writeWord_WS(addr, data);
|
writeWord_WS(addr, data);
|
||||||
|
|
||||||
dataIn_WS();
|
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
|
// blink LED
|
||||||
blinkLED();
|
blinkLED();
|
||||||
|
|
||||||
@ -1003,19 +962,18 @@ void eraseWitchFlashSector_WS(uint32_t sector_addr)
|
|||||||
writeWord_WS(sector_addr, 0x3030);
|
writeWord_WS(sector_addr, 0x3030);
|
||||||
|
|
||||||
dataIn_WS();
|
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)
|
if (wsFilePath == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
println_Msg(F("Calculating Checksum"));
|
println_Msg(F("Calculating Checksum"));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
if (!myFile.open(wsFilePath, O_READ))
|
if (!myFile.open(wsFilePath, O_READ)) {
|
||||||
{
|
|
||||||
print_Error(F("Failed to open file"), false);
|
print_Error(F("Failed to open file"), false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1023,15 +981,13 @@ boolean compareChecksum_WS(const char *wsFilePath)
|
|||||||
uint32_t calLength = myFile.fileSize() - 512;
|
uint32_t calLength = myFile.fileSize() - 512;
|
||||||
uint32_t checksum = 0;
|
uint32_t checksum = 0;
|
||||||
|
|
||||||
if (wsWitch)
|
if (wsWitch) {
|
||||||
{
|
|
||||||
// only calcuate last 128Kbytes for wonderwitch (OS and BIOS region)
|
// only calcuate last 128Kbytes for wonderwitch (OS and BIOS region)
|
||||||
myFile.seekCur(myFile.fileSize() - 131072);
|
myFile.seekCur(myFile.fileSize() - 131072);
|
||||||
calLength = 131072 - 512;
|
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);
|
myFile.read(sdBuffer, 512);
|
||||||
for (uint32_t j = 0; j < 512; j++)
|
for (uint32_t j = 0; j < 512; j++)
|
||||||
checksum += sdBuffer[j];
|
checksum += sdBuffer[j];
|
||||||
@ -1056,21 +1012,17 @@ boolean compareChecksum_WS(const char *wsFilePath)
|
|||||||
print_Msg(F("Result: "));
|
print_Msg(F("Result: "));
|
||||||
println_Msg(result);
|
println_Msg(result);
|
||||||
|
|
||||||
if (checksum == calLength)
|
if (checksum == calLength) {
|
||||||
{
|
|
||||||
println_Msg(F("Checksum matches"));
|
println_Msg(F("Checksum matches"));
|
||||||
display_Update();
|
display_Update();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
print_Error(F("Checksum Error"), false);
|
print_Error(F("Checksum Error"), false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeByte_WSPort(uint8_t port, uint8_t data)
|
void writeByte_WSPort(uint8_t port, uint8_t data) {
|
||||||
{
|
|
||||||
PORTF = (port & 0x0f);
|
PORTF = (port & 0x0f);
|
||||||
PORTL = (port >> 4);
|
PORTL = (port >> 4);
|
||||||
|
|
||||||
@ -1086,14 +1038,14 @@ void writeByte_WSPort(uint8_t port, uint8_t data)
|
|||||||
|
|
||||||
// switch WE(PH5) to HIGH
|
// switch WE(PH5) to HIGH
|
||||||
PORTH |= (1 << 5);
|
PORTH |= (1 << 5);
|
||||||
NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
// switch CART(PH3), MMC(PH4) to HIGH
|
// switch CART(PH3), MMC(PH4) to HIGH
|
||||||
PORTH |= ((1 << 3) | (1 << 4));
|
PORTH |= ((1 << 3) | (1 << 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t readByte_WSPort(uint8_t port)
|
uint8_t readByte_WSPort(uint8_t port) {
|
||||||
{
|
|
||||||
PORTF = (port & 0x0f);
|
PORTF = (port & 0x0f);
|
||||||
PORTL = (port >> 4);
|
PORTL = (port >> 4);
|
||||||
|
|
||||||
@ -1102,7 +1054,9 @@ uint8_t readByte_WSPort(uint8_t port)
|
|||||||
|
|
||||||
// switch OE(PH6) to LOW
|
// switch OE(PH6) to LOW
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
uint8_t ret = PINC;
|
uint8_t ret = PINC;
|
||||||
|
|
||||||
@ -1115,8 +1069,7 @@ uint8_t readByte_WSPort(uint8_t port)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeWord_WS(uint32_t addr, uint16_t data)
|
void writeWord_WS(uint32_t addr, uint16_t data) {
|
||||||
{
|
|
||||||
PORTF = addr & 0xff;
|
PORTF = addr & 0xff;
|
||||||
PORTK = (addr >> 8) & 0xff;
|
PORTK = (addr >> 8) & 0xff;
|
||||||
PORTL = (addr >> 16) & 0x0f;
|
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
|
// switch CART(PH3) and WE(PH5) to HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 5);
|
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;
|
PORTF = addr & 0xff;
|
||||||
PORTK = (addr >> 8) & 0xff;
|
PORTK = (addr >> 8) & 0xff;
|
||||||
PORTL = (addr >> 16) & 0x0f;
|
PORTL = (addr >> 16) & 0x0f;
|
||||||
|
|
||||||
// switch CART(PH3) and OE(PH6) to LOW
|
// switch CART(PH3) and OE(PH6) to LOW
|
||||||
PORTH &= ~((1 << 3) | (1 << 6));
|
PORTH &= ~((1 << 3) | (1 << 6));
|
||||||
NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
uint16_t ret = ((PINA << 8) | PINC);
|
uint16_t ret = ((PINA << 8) | PINC);
|
||||||
|
|
||||||
@ -1151,8 +1106,7 @@ uint16_t readWord_WS(uint32_t addr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeByte_WS(uint32_t addr, uint8_t data)
|
void writeByte_WS(uint32_t addr, uint8_t data) {
|
||||||
{
|
|
||||||
PORTF = addr & 0xff;
|
PORTF = addr & 0xff;
|
||||||
PORTK = (addr >> 8) & 0xff;
|
PORTK = (addr >> 8) & 0xff;
|
||||||
PORTL = (addr >> 16) & 0x0f;
|
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
|
// switch CART(PH3) and WE(PH5) to HIGH
|
||||||
PORTH |= (1 << 3) | (1 << 5);
|
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;
|
PORTF = addr & 0xff;
|
||||||
PORTK = (addr >> 8) & 0xff;
|
PORTK = (addr >> 8) & 0xff;
|
||||||
PORTL = (addr >> 16) & 0x0f;
|
PORTL = (addr >> 16) & 0x0f;
|
||||||
|
|
||||||
// switch CART(PH3) and OE(PH6) to LOW
|
// switch CART(PH3) and OE(PH6) to LOW
|
||||||
PORTH &= ~((1 << 3) | (1 << 6));
|
PORTH &= ~((1 << 3) | (1 << 6));
|
||||||
NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
uint8_t ret = PINC;
|
uint8_t ret = PINC;
|
||||||
|
|
||||||
@ -1186,8 +1142,7 @@ uint8_t readByte_WS(uint32_t addr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unprotectEEPROM()
|
void unprotectEEPROM() {
|
||||||
{
|
|
||||||
generateEepromInstruction_WS(wsEepromShiftReg, 0x0, 0x3);
|
generateEepromInstruction_WS(wsEepromShiftReg, 0x0, 0x3);
|
||||||
|
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
@ -1201,23 +1156,19 @@ void unprotectEEPROM()
|
|||||||
|
|
||||||
// generate data for port 0xc6 to 0xc7
|
// generate data for port 0xc6 to 0xc7
|
||||||
// number of CLK pulses needed for each instruction is 1 + (16 or 32) + 3
|
// 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);
|
uint8_t addr_bits = (sramSize > 1 ? 10 : 6);
|
||||||
uint16_t *ptr = (uint16_t*)instruction;
|
uint16_t *ptr = (uint16_t *)instruction;
|
||||||
*ptr = 0x0001; // initial with a start bit
|
*ptr = 0x0001; // initial with a start bit
|
||||||
|
|
||||||
if (opcode == 0)
|
if (opcode == 0) {
|
||||||
{
|
|
||||||
// 2bits opcode = 0x00
|
// 2bits opcode = 0x00
|
||||||
*ptr <<= 2;
|
*ptr <<= 2;
|
||||||
// 2bits ext cmd (from addr)
|
// 2bits ext cmd (from addr)
|
||||||
*ptr <<= 2;
|
*ptr <<= 2;
|
||||||
*ptr |= (addr & 0x0003);
|
*ptr |= (addr & 0x0003);
|
||||||
*ptr <<= (addr_bits - 2);
|
*ptr <<= (addr_bits - 2);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// 2bits opcode
|
// 2bits opcode
|
||||||
*ptr <<= 2;
|
*ptr <<= 2;
|
||||||
*ptr |= (opcode & 0x03);
|
*ptr |= (opcode & 0x03);
|
||||||
@ -1230,8 +1181,7 @@ void generateEepromInstruction_WS(uint8_t *instruction, uint8_t opcode, uint16_t
|
|||||||
// 2003 MMC need to be unlock,
|
// 2003 MMC need to be unlock,
|
||||||
// or it will reject all reading and bank switching
|
// or it will reject all reading and bank switching
|
||||||
// All signals' timing are analyzed by using LogicAnalyzer
|
// All signals' timing are analyzed by using LogicAnalyzer
|
||||||
boolean unlockMMC2003_WS()
|
boolean unlockMMC2003_WS() {
|
||||||
{
|
|
||||||
// initialize all control pin state
|
// initialize all control pin state
|
||||||
// RST(PH0) and CLK(PE3or5) to LOW
|
// RST(PH0) and CLK(PE3or5) to LOW
|
||||||
// CART(PH3) MMC(PH4) WE(PH5) OE(PH6) to HIGH
|
// CART(PH3) MMC(PH4) WE(PH5) OE(PH6) to HIGH
|
||||||
@ -1261,8 +1211,7 @@ boolean unlockMMC2003_WS()
|
|||||||
writeByte_WSPort(0xc3, 0x55);
|
writeByte_WSPort(0xc3, 0x55);
|
||||||
|
|
||||||
dataIn_WS();
|
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
|
// now set initial bank number to MMC
|
||||||
dataOut_WS();
|
dataOut_WS();
|
||||||
writeByte_WSPort(0xc0, 0x2f);
|
writeByte_WSPort(0xc0, 0x2f);
|
||||||
@ -1276,35 +1225,31 @@ boolean unlockMMC2003_WS()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// doing a L->H on CLK pin
|
// doing a L->H on CLK pin
|
||||||
void pulseCLK_WS(uint8_t count)
|
void pulseCLK_WS(uint8_t count) {
|
||||||
{
|
|
||||||
register uint8_t tic;
|
register uint8_t tic;
|
||||||
|
|
||||||
// about 384KHz, 50% duty cycle
|
// about 384KHz, 50% duty cycle
|
||||||
asm volatile
|
asm volatile("L0_%=:\n\t"
|
||||||
("L0_%=:\n\t"
|
"cpi %[count], 0\n\t"
|
||||||
"cpi %[count], 0\n\t"
|
"breq L3_%=\n\t"
|
||||||
"breq L3_%=\n\t"
|
"dec %[count]\n\t"
|
||||||
"dec %[count]\n\t"
|
"cbi %[porte], %[ws_clk_bit]\n\t"
|
||||||
"cbi %[porte], %[ws_clk_bit]\n\t"
|
"ldi %[tic], 6\n\t"
|
||||||
"ldi %[tic], 6\n\t"
|
"L1_%=:\n\t"
|
||||||
"L1_%=:\n\t"
|
"dec %[tic]\n\t"
|
||||||
"dec %[tic]\n\t"
|
"brne L1_%=\n\t"
|
||||||
"brne L1_%=\n\t"
|
"sbi %[porte], %[ws_clk_bit]\n\t"
|
||||||
"sbi %[porte], %[ws_clk_bit]\n\t"
|
"ldi %[tic], 5\n\t"
|
||||||
"ldi %[tic], 5\n\t"
|
"L2_%=:\n\t"
|
||||||
"L2_%=:\n\t"
|
"dec %[tic]\n\t"
|
||||||
"dec %[tic]\n\t"
|
"brne L2_%=\n\t"
|
||||||
"brne L2_%=\n\t"
|
"rjmp L0_%=\n\t"
|
||||||
"rjmp L0_%=\n\t"
|
"L3_%=:\n\t"
|
||||||
"L3_%=:\n\t"
|
: [tic] "=a"(tic)
|
||||||
: [tic] "=a" (tic)
|
: [count] "a"(count), [porte] "I"(_SFR_IO_ADDR(PORTE)), [ws_clk_bit] "I"(WS_CLK_BIT));
|
||||||
: [count] "a" (count), [porte] "I" (_SFR_IO_ADDR(PORTE)), [ws_clk_bit] "I" (WS_CLK_BIT)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataIn_WS()
|
void dataIn_WS() {
|
||||||
{
|
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
DDRA = 0x00;
|
DDRA = 0x00;
|
||||||
|
|
||||||
@ -1314,8 +1259,7 @@ void dataIn_WS()
|
|||||||
PORTA = 0x00;
|
PORTA = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataOut_WS()
|
void dataOut_WS() {
|
||||||
{
|
|
||||||
DDRC = 0xff;
|
DDRC = 0xff;
|
||||||
DDRA = 0xff;
|
DDRA = 0xff;
|
||||||
}
|
}
|
||||||
@ -1323,4 +1267,4 @@ void dataOut_WS()
|
|||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
@ -38,9 +38,9 @@
|
|||||||
// /WR - (PH5)
|
// /WR - (PH5)
|
||||||
// /RD - (PH6)
|
// /RD - (PH6)
|
||||||
|
|
||||||
word WSV[] = {32, 64, 512};
|
word WSV[] = { 32, 64, 512 };
|
||||||
byte wsvlo = 0; // Lowest Entry
|
byte wsvlo = 0; // Lowest Entry
|
||||||
byte wsvhi = 2; // Highest Entry
|
byte wsvhi = 2; // Highest Entry
|
||||||
|
|
||||||
byte wsvsize;
|
byte wsvsize;
|
||||||
byte newwsvsize;
|
byte newwsvsize;
|
||||||
@ -52,8 +52,7 @@ byte newwsvsize;
|
|||||||
// SETUP
|
// SETUP
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
void setup_WSV()
|
void setup_WSV() {
|
||||||
{
|
|
||||||
// Set Address Pins to Output
|
// Set Address Pins to Output
|
||||||
//A0-A7
|
//A0-A7
|
||||||
DDRF = 0xFF;
|
DDRF = 0xFF;
|
||||||
@ -87,7 +86,7 @@ void setup_WSV()
|
|||||||
// Set Unused Pins HIGH
|
// Set Unused Pins HIGH
|
||||||
PORTL = 0xE0;
|
PORTL = 0xE0;
|
||||||
PORTA = 0xFF;
|
PORTA = 0xFF;
|
||||||
PORTJ |= (1 << 0); // TIME(PJ0)
|
PORTJ |= (1 << 0); // TIME(PJ0)
|
||||||
|
|
||||||
checkStatus_WSV();
|
checkStatus_WSV();
|
||||||
strcpy(romName, "SUPERVISION");
|
strcpy(romName, "SUPERVISION");
|
||||||
@ -104,15 +103,13 @@ static const char wsvMenuItem1[] PROGMEM = "Select Cart";
|
|||||||
static const char wsvMenuItem2[] PROGMEM = "Read ROM";
|
static const char wsvMenuItem2[] PROGMEM = "Read ROM";
|
||||||
static const char wsvMenuItem3[] PROGMEM = "Set Size";
|
static const char wsvMenuItem3[] PROGMEM = "Set Size";
|
||||||
static const char wsvMenuItem4[] PROGMEM = "Reset";
|
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);
|
convertPgm(menuOptionsSV, 4);
|
||||||
uint8_t mainMenu = question_box(F("SUPERVISION MENU"), menuOptions, 4, 0);
|
uint8_t mainMenu = question_box(F("SUPERVISION MENU"), menuOptions, 4, 0);
|
||||||
|
|
||||||
switch (mainMenu)
|
switch (mainMenu) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
// Select Cart
|
// Select Cart
|
||||||
setCart_WSV();
|
setCart_WSV();
|
||||||
@ -157,25 +154,27 @@ void controlIn_WSV() {
|
|||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataIn_WSV()
|
void dataIn_WSV() {
|
||||||
{
|
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataOut_WSV()
|
void dataOut_WSV() {
|
||||||
{
|
|
||||||
DDRC = 0xFF;
|
DDRC = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t readByte_WSV(uint32_t addr)
|
uint8_t readByte_WSV(uint32_t addr) {
|
||||||
{
|
|
||||||
PORTF = addr & 0xFF;
|
PORTF = addr & 0xFF;
|
||||||
PORTK = (addr >> 8) & 0xFF;
|
PORTK = (addr >> 8) & 0xFF;
|
||||||
PORTL = (addr >> 16) & 0xFF;
|
PORTL = (addr >> 16) & 0xFF;
|
||||||
|
|
||||||
// Wait for data bus
|
// Wait for data bus
|
||||||
// 6 x 62.5ns = 375ns
|
// 6 x 62.5ns = 375ns
|
||||||
NOP; NOP; NOP; NOP; NOP; NOP;
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
NOP;
|
||||||
|
|
||||||
uint8_t ret = PINC;
|
uint8_t ret = PINC;
|
||||||
NOP;
|
NOP;
|
||||||
@ -187,8 +186,7 @@ uint8_t readByte_WSV(uint32_t addr)
|
|||||||
// READ CODE
|
// READ CODE
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
void readROM_WSV()
|
void readROM_WSV() {
|
||||||
{
|
|
||||||
strcpy(fileName, romName);
|
strcpy(fileName, romName);
|
||||||
strcat(fileName, ".sv");
|
strcat(fileName, ".sv");
|
||||||
|
|
||||||
@ -223,8 +221,7 @@ void readROM_WSV()
|
|||||||
if (romSize < 64)
|
if (romSize < 64)
|
||||||
romStart = 0x8000;
|
romStart = 0x8000;
|
||||||
uint32_t romEnd = (uint32_t)romSize * 0x400;
|
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++)
|
for (uint16_t w = 0; w < 512; w++)
|
||||||
sdBuffer[w] = readByte_WSV(romStart + addr + w);
|
sdBuffer[w] = readByte_WSV(romStart + addr + w);
|
||||||
myFile.write(sdBuffer, 512);
|
myFile.write(sdBuffer, 512);
|
||||||
@ -245,8 +242,7 @@ void readROM_WSV()
|
|||||||
// ROM SIZE
|
// ROM SIZE
|
||||||
//******************************************
|
//******************************************
|
||||||
|
|
||||||
void setROMSize_WSV()
|
void setROMSize_WSV() {
|
||||||
{
|
|
||||||
#if (defined(enable_OLED) || defined(enable_LCD))
|
#if (defined(enable_OLED) || defined(enable_LCD))
|
||||||
display_Clear();
|
display_Clear();
|
||||||
if (wsvlo == wsvhi)
|
if (wsvlo == wsvhi)
|
||||||
@ -270,7 +266,7 @@ void setROMSize_WSV()
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
b = checkButton();
|
b = checkButton();
|
||||||
if (b == 2) { // Previous (doubleclick)
|
if (b == 2) { // Previous (doubleclick)
|
||||||
if (i == wsvlo)
|
if (i == wsvlo)
|
||||||
i = wsvhi;
|
i = wsvhi;
|
||||||
else
|
else
|
||||||
@ -290,7 +286,7 @@ void setROMSize_WSV()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 1) { // Next (press)
|
if (b == 1) { // Next (press)
|
||||||
if (i == wsvhi)
|
if (i == wsvhi)
|
||||||
i = wsvlo;
|
i = wsvlo;
|
||||||
else
|
else
|
||||||
@ -310,12 +306,12 @@ void setROMSize_WSV()
|
|||||||
#endif
|
#endif
|
||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
if (b == 3) { // Long Press - Execute (hold)
|
if (b == 3) { // Long Press - Execute (hold)
|
||||||
newwsvsize = i;
|
newwsvsize = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
display.setCursor(0, 56); // Display selection at bottom
|
display.setCursor(0, 56); // Display selection at bottom
|
||||||
}
|
}
|
||||||
print_Msg(F("ROM SIZE "));
|
print_Msg(F("ROM SIZE "));
|
||||||
print_Msg(WSV[newwsvsize]);
|
print_Msg(WSV[newwsvsize]);
|
||||||
@ -354,11 +350,10 @@ setrom:
|
|||||||
wsvsize = newwsvsize;
|
wsvsize = newwsvsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkStatus_WSV()
|
void checkStatus_WSV() {
|
||||||
{
|
|
||||||
EEPROM_readAnything(8, wsvsize);
|
EEPROM_readAnything(8, wsvsize);
|
||||||
if (wsvsize > 2) {
|
if (wsvsize > 2) {
|
||||||
wsvsize = 1; // default 64K
|
wsvsize = 1; // default 64K
|
||||||
EEPROM_writeAnything(8, wsvsize);
|
EEPROM_writeAnything(8, wsvsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,12 +411,10 @@ void setCart_WSV() {
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (myFile.curPosition() == 0) {
|
if (myFile.curPosition() == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (myFile.peek() == '\n') {
|
||||||
else if (myFile.peek() == '\n') {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,9 +456,8 @@ void setCart_WSV() {
|
|||||||
|
|
||||||
// Remove leading 0 for single digit cart sizes
|
// Remove leading 0 for single digit cart sizes
|
||||||
if (cartSize != 0) {
|
if (cartSize != 0) {
|
||||||
cartSize = cartSize * 10 + myFile.read() - 48;
|
cartSize = cartSize * 10 + myFile.read() - 48;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cartSize = myFile.read() - 48;
|
cartSize = myFile.read() - 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,12 +505,10 @@ void setCart_WSV() {
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (myFile.curPosition() == 0) {
|
if (myFile.curPosition() == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (myFile.peek() == '\n') {
|
||||||
else if (myFile.peek() == '\n') {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
myFile.seekSet(myFile.curPosition() - 1);
|
myFile.seekSet(myFile.curPosition() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,12 +540,11 @@ void setCart_WSV() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
print_Error(F("Database file not found"), true);
|
print_Error(F("Database file not found"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
Loading…
x
Reference in New Issue
Block a user