Merge pull request #596 from vpelletier/trim

Free some program and global ram space
This commit is contained in:
sanni 2022-10-28 09:48:25 +02:00 committed by GitHub
commit 202e5ff25e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1622 additions and 2334 deletions

View File

@ -51,8 +51,8 @@ byte newcolsize;
static const char colMenuItem1[] PROGMEM = "Select Cart"; 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"; (stored in common strings array)
static const char* const menuOptionsCOL[] PROGMEM = { colMenuItem1, colMenuItem2, colMenuItem3, colMenuItem4 }; static const char* const menuOptionsCOL[] PROGMEM = { colMenuItem1, colMenuItem2, colMenuItem3, string_reset2 };
void setup_COL() { void setup_COL() {
// Set Address Pins to Output // Set Address Pins to Output
@ -175,14 +175,14 @@ void readROM_COL() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
// open file on sdcard // open file on sdcard
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(create_file_STR, true);
// write new folder number back to EEPROM // write new folder number back to EEPROM
foldern++; foldern++;
@ -216,7 +216,8 @@ void readROM_COL() {
compareCRC("colv.txt", 0, 1, 0); compareCRC("colv.txt", 0, 1, 0);
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -239,11 +240,11 @@ void setROMSize_COL() {
println_Msg(COL[i]); println_Msg(COL[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
@ -261,11 +262,11 @@ void setROMSize_COL() {
println_Msg(COL[i]); println_Msg(COL[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -281,11 +282,11 @@ void setROMSize_COL() {
println_Msg(COL[i]); println_Msg(COL[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -349,7 +350,8 @@ void checkStatus_COL() {
print_Msg(COL[colsize]); print_Msg(COL[colsize]);
println_Msg(F("K")); println_Msg(F("K"));
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#else #else
@ -392,20 +394,7 @@ void setCart_COL() {
} }
// Rewind one line // Rewind one line
for (byte count_newline = 0; count_newline < 2; count_newline++) { rewind_line(myFile);
while (1) {
if (myFile.curPosition() == 0) {
break;
} else if (myFile.peek() == '\n') {
myFile.seekSet(myFile.curPosition() - 1);
break;
} else {
myFile.seekSet(myFile.curPosition() - 1);
}
}
}
if (myFile.curPosition() != 0)
myFile.seekSet(myFile.curPosition() + 2);
} }
// Display database // Display database
@ -423,7 +412,7 @@ void setCart_COL() {
} }
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read CRC32 of first 512 bytes // Read CRC32 of first 512 bytes
sprintf(crc_search, "%c", myFile.read()); sprintf(crc_search, "%c", myFile.read());
@ -433,7 +422,7 @@ void setCart_COL() {
} }
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read rom size // Read rom size
// Read the next ascii character and subtract 48 to convert to decimal // Read the next ascii character and subtract 48 to convert to decimal
@ -447,7 +436,7 @@ void setCart_COL() {
} }
// Skip rest of line // Skip rest of line
myFile.seekSet(myFile.curPosition() + 2); myFile.seekCur(2);
// Skip every 3rd line // Skip every 3rd line
skip_line(&myFile); skip_line(&myFile);
@ -460,11 +449,11 @@ void setCart_COL() {
println_Msg(F("KB")); println_Msg(F("KB"));
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#elif defined(SERIAL_MONITOR) #elif defined(SERIAL_MONITOR)
println_Msg(F("U/D to Change")); println_Msg(F("U/D to Change"));
println_Msg(F("Space to Select")); println_Msg(F("Space to Select"));
@ -483,20 +472,7 @@ void setCart_COL() {
// Previous // Previous
else if (b == 2) { else if (b == 2) {
for (byte count_newline = 0; count_newline < 7; count_newline++) { rewind_line(myFile, 6);
while (1) {
if (myFile.curPosition() == 0) {
break;
} else if (myFile.peek() == '\n') {
myFile.seekSet(myFile.curPosition() - 1);
break;
} else {
myFile.seekSet(myFile.curPosition() - 1);
}
}
}
if (myFile.curPosition() != 0)
myFile.seekSet(myFile.curPosition() + 2);
break; break;
} }

View File

@ -56,7 +56,7 @@
**********************************************************************************/ **********************************************************************************/
char ver[5] = "10.3"; char ver[5] = "10.4";
//****************************************** //******************************************
// !!! CHOOSE HARDWARE VERSION !!! // !!! CHOOSE HARDWARE VERSION !!!
@ -176,7 +176,6 @@ char ver[5] = "10.3";
// SD Card // SD Card
#include "SdFat.h" #include "SdFat.h"
SdFs sd; SdFs sd;
FsFile myDir;
FsFile myFile; FsFile myFile;
#ifdef global_log #ifdef global_log
FsFile myLog; FsFile myLog;
@ -263,6 +262,57 @@ bool i2c_found;
#include "FreqCount.h" #include "FreqCount.h"
#endif #endif
/******************************************
Common Strings
*****************************************/
#define press_button_STR 0
#define sd_error_STR 1
#define reset_STR 2
#define did_not_verify_STR 3
#define _bytes_STR 4
#define error_STR 5
#define create_file_STR 6
#define open_file_STR 7
#define file_too_big_STR 8
#define done_STR 9
#define saving_to_STR 10
#define verifying_STR 11
#define flashing_file_STR 12
#define press_to_change_STR 13
#define right_to_select_STR 14
#define rotate_to_change_STR 15
#define press_to_select_STR 16
// This arrays holds the most often uses strings
static const char string_press_button0[] PROGMEM = "Press Button...";
static const char string_sd_error1[] PROGMEM = "SD Error";
static const char string_reset2[] PROGMEM = "Reset";
static const char string_did_not_verify3[] PROGMEM = "did not verify";
static const char string_bytes4[] PROGMEM = " bytes ";
static const char string_error5[] PROGMEM = "Error: ";
static const char string_create_file6[] PROGMEM = "Can't create file";
static const char string_open_file7[] PROGMEM = "Can't open file";
static const char string_file_too_big8[] PROGMEM = "File too big";
static const char string_done9[] PROGMEM = "Done";
static const char string_saving_to10[] PROGMEM = "Saving to ";
static const char string_verifying11[] PROGMEM = "Verifying...";
static const char string_flashing_file12[] PROGMEM = "Flashing file ";
static const char string_press_to_change13[] PROGMEM = "Press left to Change";
static const char string_right_to_select14[] PROGMEM = "and right to Select";
static const char string_rotate_to_change15[] PROGMEM = "Rotate to Change";
static const char string_press_to_select16[] PROGMEM = "Press to Select";
static const char* const string_table[] PROGMEM = { string_press_button0, string_sd_error1, string_reset2, string_did_not_verify3, string_bytes4, string_error5, string_create_file6, string_open_file7, string_file_too_big8, string_done9, string_saving_to10, string_verifying11, string_flashing_file12, string_press_to_change13, string_right_to_select14, string_rotate_to_change15, string_press_to_select16 };
void print_STR(byte string_number, boolean newline) {
char string_buffer[22];
strcpy_P(string_buffer, (char*)pgm_read_word(&(string_table[string_number])));
if (newline)
println_Msg(string_buffer);
else
print_Msg(string_buffer);
}
/****************************************** /******************************************
Defines Defines
*****************************************/ *****************************************/
@ -380,7 +430,8 @@ bool errorLvl = 0;
byte romVersion = 0; byte romVersion = 0;
char cartID[5]; char cartID[5];
unsigned long cartSize; unsigned long cartSize;
char flashid[5]; unsigned int flashid;
char flashid_str[5];
char vendorID[5]; char vendorID[5];
unsigned long fileSize; unsigned long fileSize;
unsigned long sramBase; unsigned long sramBase;
@ -480,32 +531,48 @@ static const uint32_t crc_32_tab[] PROGMEM = { /* CRC polynomial 0xedb88320 */
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
}; };
inline uint32_t updateCRC(uint8_t ch, uint32_t crc) { // Defined as a macros, as compiler disregards inlining requests and these are
uint32_t idx = ((crc) ^ (ch)) & 0xff; // performance-critical functions.
uint32_t tab_value = pgm_read_dword(crc_32_tab + idx); #define UPDATE_CRC(crc, ch) do { \
return tab_value ^ ((crc) >> 8); uint8_t idx = ((crc) ^ (ch)) & 0xff; \
uint32_t tab_value = pgm_read_dword(crc_32_tab + idx); \
(crc) = tab_value ^ ((crc) >> 8); \
} while (0)
uint32_t updateCRC(const byte *buffer, size_t length, uint32_t crc) {
for (size_t c = 0; c < length; c++) {
UPDATE_CRC(crc, buffer[c]);
}
return crc;
}
uint32_t calculateCRC(const byte *buffer, size_t length) {
uint32_t crc = 0xFFFFFFFF;
updateCRC(buffer, length, crc);
return ~crc;
}
uint32_t calculateCRC(FsFile &infile) {
uint32_t byte_count;
uint32_t crc = 0xFFFFFFFF;
while((byte_count = infile.read(sdBuffer, sizeof(sdBuffer))) != 0) {
updateCRC(sdBuffer, byte_count, crc);
}
return ~crc;
} }
// Calculate rom's CRC32 from SD // Calculate rom's CRC32 from SD
uint32_t calculateCRC(char* fileName, char* folder, int offset) { uint32_t calculateCRC(char* fileName, char* folder, int offset) {
// Open folder FsFile infile;
uint32_t result;
sd.chdir(folder); sd.chdir(folder);
// Open file if (infile.open(fileName, O_READ)) {
if (myFile.open(fileName, O_READ)) { infile.seek(offset);
uint32_t oldcrc32 = 0xFFFFFFFF; result = calculateCRC(infile);
infile.close();
// Skip iNES header return result;
myFile.seek(offset);
for (unsigned long currByte = 0; currByte < ((myFile.fileSize() - offset) / 512); currByte++) {
myFile.read(sdBuffer, 512);
for (int c = 0; c < 512; c++) {
oldcrc32 = updateCRC(sdBuffer[c], oldcrc32);
}
}
// Close the file:
myFile.close();
return ~oldcrc32;
} else { } else {
display_Clear(); display_Clear();
print_Msg(F("File ")); print_Msg(F("File "));
@ -513,6 +580,7 @@ uint32_t calculateCRC(char* fileName, char* folder, int offset) {
//print_Msg(F("/")); //print_Msg(F("/"));
//print_Msg(fileName); //print_Msg(fileName);
print_Error(F(" not found"), true); print_Error(F(" not found"), true);
return 0;
} }
} }
@ -539,32 +607,47 @@ void skip_line(FsFile* readfile) {
//Get line from file //Get line from file
void get_line(char* str_buf, FsFile* readfile, uint8_t maxi) { void get_line(char* str_buf, FsFile* readfile, uint8_t maxi) {
int read_len;
// Status LED on // Status LED on
statusLED(true); statusLED(true);
int i = 0; read_len = readfile->read(str_buf, maxi - 1);
while (readfile->available()) {
//If line size is more than maximum array, limit it.
if (i >= maxi) {
i = maxi - 1;
}
//Read 1 byte from file
str_buf[i] = readfile->read();
for (int i = 0; i < read_len; i++) {
//if end of file or newline found, execute command //if end of file or newline found, execute command
if (str_buf[i] == '\r') { if (str_buf[i] == '\r') {
str_buf[i] = '\0'; str_buf[i] = 0;
readfile->read(); //dispose \n because \r\n readfile->seekCur(i - read_len + 2); // +2 to skip over \n because \r\n
return;
}
}
str_buf[maxi - 1] = 0;
// EOL was not found, keep looking (slower)
while (readfile->available()) {
if (readfile->read() == '\r') {
readfile->read(); // read \n because \r\n
break; break;
} }
i++; }
} //End while }
void rewind_line(FsFile &readfile, byte count=1) {
uint32_t position = readfile.curPosition();
count++;
for (byte count_newline = 0; count_newline < count; count_newline++) {
while (position--) {
readfile.seekCur(-1);
if (readfile.peek() == '\n')
break;
}
}
if (position)
readfile.seekCur(1);
} }
// Calculate CRC32 if needed and compare it to CRC read from database // Calculate CRC32 if needed and compare it to CRC read from database
boolean compareCRC(char* database, char* crcString, boolean renamerom, int offset) { boolean compareCRC(const char* database, char* crcString, boolean renamerom, int offset) {
#ifdef nointro #ifdef nointro
char crcStr[9]; char crcStr[9];
if (crcString == 0) { if (crcString == 0) {
@ -577,7 +660,6 @@ boolean compareCRC(char* database, char* crcString, boolean renamerom, int offse
} else { } else {
// Use precalculated crc // Use precalculated crc
print_Msg(F("CRC32... ")); print_Msg(F("CRC32... "));
display_Update();
strcpy(crcStr, crcString); strcpy(crcStr, crcString);
} }
// Print checksum // Print checksum
@ -585,7 +667,7 @@ boolean compareCRC(char* database, char* crcString, boolean renamerom, int offse
display_Update(); display_Update();
//Search for CRC32 in file //Search for CRC32 in file
char gamename[100]; char gamename[96];
char crc_search[9]; char crc_search[9];
//go to root //go to root
@ -594,8 +676,8 @@ boolean compareCRC(char* database, char* crcString, boolean renamerom, int offse
//Search for same CRC in list //Search for same CRC in list
while (myFile.available()) { while (myFile.available()) {
//Read 2 lines (game name and CRC) //Read 2 lines (game name and CRC)
get_line(gamename, &myFile, 96); get_line(gamename, &myFile, sizeof(gamename));
get_line(crc_search, &myFile, 9); get_line(crc_search, &myFile, sizeof(crc_search));
skip_line(&myFile); //Skip every 3rd line skip_line(&myFile); //Skip every 3rd line
//if checksum search successful, rename the file and end search //if checksum search successful, rename the file and end search
@ -603,22 +685,22 @@ boolean compareCRC(char* database, char* crcString, boolean renamerom, int offse
#ifdef enable_NES #ifdef enable_NES
if ((mode == mode_NES) && (offset != 0)) { if ((mode == mode_NES) && (offset != 0)) {
// Rewind to iNES Header // Rewind to iNES Header
myFile.seekSet(myFile.curPosition() - 36); myFile.seekCur(-36);
char iNES_STR[33]; char iNES_STR[33];
// Read iNES header // Read iNES header
get_line(iNES_STR, &myFile, 33); get_line(iNES_STR, &myFile, 33);
// Convert "4E4553" to (0x4E, 0x45, 0x53) // Convert "4E4553" to (0x4E, 0x45, 0x53)
byte iNES_BUF[2]; unsigned int iNES_BUF;
for (byte j = 0; j < 16; j++) { for (byte j = 0; j < 16; j++) {
sscanf(iNES_STR + j * 2, "%2X", iNES_BUF); sscanf(iNES_STR + j * 2, "%2X", &iNES_BUF);
iNES_HEADER[j] = iNES_BUF[0]; iNES_HEADER[j] = iNES_BUF;
} }
//Skip CRLF //Skip CRLF
myFile.seekSet(myFile.curPosition() + 4); myFile.seekCur(4);
} }
#endif #endif // enable_NES
// Close the file: // Close the file:
myFile.close(); myFile.close();
@ -629,14 +711,14 @@ boolean compareCRC(char* database, char* crcString, boolean renamerom, int offse
// Write iNES header // Write iNES header
sd.chdir(folder); sd.chdir(folder);
if (!myFile.open(fileName, O_RDWR)) { if (!myFile.open(fileName, O_RDWR)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
for (byte z = 0; z < 16; z++) { for (byte z = 0; z < 16; z++) {
myFile.write(iNES_HEADER[z]); myFile.write(iNES_HEADER[z]);
} }
myFile.close(); myFile.close();
} }
#endif #endif // enable_NES
print_Msg(F(" -> ")); print_Msg(F(" -> "));
display_Update(); display_Update();
@ -667,9 +749,10 @@ boolean compareCRC(char* database, char* crcString, boolean renamerom, int offse
println_Msg(F("Database missing")); println_Msg(F("Database missing"));
return 0; return 0;
} }
#else #else // nointro
println_Msg(""); println_Msg("");
#endif #endif // !nointro
return 0;
} }
byte starting_letter() { byte starting_letter() {
@ -802,17 +885,17 @@ void mainMenu() {
while (1) { while (1) {
if (currPage == 1) { if (currPage == 1) {
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(modeOptions, 0, 7); convertPgm(modeOptions + 0, 7);
modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 7, 0); modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 7, 0);
} }
if (currPage == 2) { if (currPage == 2) {
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(modeOptions, 7, 7); convertPgm(modeOptions + 7, 7);
modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 7, 0); modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 7, 0);
} }
if (currPage == 3) { if (currPage == 3) {
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(modeOptions, 14, 2); convertPgm(modeOptions + 14, 2);
modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 2, 0); modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 2, 0);
} }
if (numPages == 0) { if (numPages == 0) {
@ -839,11 +922,6 @@ void mainMenu() {
display_Clear(); display_Clear();
display_Update(); display_Update();
setup_NES(); setup_NES();
#ifdef nointro
if (getMapping() == 0) {
selectMapping();
}
#endif
checkStatus_NES(); checkStatus_NES();
nesMenu(); nesMenu();
break; break;
@ -973,15 +1051,15 @@ static const char modeItem4[] PROGMEM = "Nintendo 64(3V EEP)";
#endif #endif
static const char modeItem5[] PROGMEM = "Game Boy"; static const char modeItem5[] PROGMEM = "Game Boy";
static const char modeItem6[] PROGMEM = "About"; static const char modeItem6[] PROGMEM = "About";
static const char modeItem7[] PROGMEM = "Reset"; // static const char modeItem7[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const modeOptions[] PROGMEM = { modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6, modeItem7 }; static const char* const modeOptions[] PROGMEM = { modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6, string_reset2 };
// Add-ons submenu // Add-ons submenu
static const char addonsItem1[] PROGMEM = "Consoles"; static const char addonsItem1[] PROGMEM = "Consoles";
static const char addonsItem2[] PROGMEM = "Handhelds"; static const char addonsItem2[] PROGMEM = "Handhelds";
static const char addonsItem3[] PROGMEM = "Flashrom Programmer"; static const char addonsItem3[] PROGMEM = "Flashrom Programmer";
static const char addonsItem4[] PROGMEM = "Reset"; //static const char addonsItem4[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const addonsOptions[] PROGMEM = { addonsItem1, addonsItem2, addonsItem3, addonsItem4 }; static const char* const addonsOptions[] PROGMEM = { addonsItem1, addonsItem2, addonsItem3, string_reset2 };
// Consoles submenu // Consoles submenu
static const char consolesItem1[] PROGMEM = "NES/Famicom"; static const char consolesItem1[] PROGMEM = "NES/Famicom";
@ -989,8 +1067,8 @@ static const char consolesItem2[] PROGMEM = "PC Engine/TG16";
static const char consolesItem3[] PROGMEM = "SMS/GG/MIII/SG-1000"; static const char consolesItem3[] PROGMEM = "SMS/GG/MIII/SG-1000";
static const char consolesItem4[] PROGMEM = "Intellivision"; static const char consolesItem4[] PROGMEM = "Intellivision";
static const char consolesItem5[] PROGMEM = "Colecovision"; static const char consolesItem5[] PROGMEM = "Colecovision";
static const char consolesItem6[] PROGMEM = "Reset"; //static const char consolesItem6[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const consolesOptions[] PROGMEM = { consolesItem1, consolesItem2, consolesItem3, consolesItem4, consolesItem5, consolesItem6 }; static const char* const consolesOptions[] PROGMEM = { consolesItem1, consolesItem2, consolesItem3, consolesItem4, consolesItem5, string_reset2 };
// Handhelds submenu // Handhelds submenu
static const char handheldsItem1[] PROGMEM = "Virtual Boy"; static const char handheldsItem1[] PROGMEM = "Virtual Boy";
@ -998,8 +1076,8 @@ static const char handheldsItem2[] PROGMEM = "WonderSwan";
static const char handheldsItem3[] PROGMEM = "NeoGeo Pocket"; static const char handheldsItem3[] PROGMEM = "NeoGeo Pocket";
static const char handheldsItem4[] PROGMEM = "Watara Supervision"; static const char handheldsItem4[] PROGMEM = "Watara Supervision";
static const char handheldsItem5[] PROGMEM = "Pocket Challenge W"; static const char handheldsItem5[] PROGMEM = "Pocket Challenge W";
static const char handheldsItem6[] PROGMEM = "Reset"; //static const char handheldsItem6[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const handheldsOptions[] PROGMEM = { handheldsItem1, handheldsItem2, handheldsItem3, handheldsItem4, handheldsItem5, handheldsItem6 }; static const char* const handheldsOptions[] PROGMEM = { handheldsItem1, handheldsItem2, handheldsItem3, handheldsItem4, handheldsItem5, string_reset2 };
// All included slots // All included slots
void mainMenu() { void mainMenu() {
@ -1103,11 +1181,6 @@ void consoleMenu() {
display_Clear(); display_Clear();
display_Update(); display_Update();
setup_NES(); setup_NES();
#ifdef nointro
if (getMapping() == 0) {
selectMapping();
}
#endif
checkStatus_NES(); checkStatus_NES();
nesMenu(); nesMenu();
break; break;
@ -1227,7 +1300,8 @@ void aboutScreen() {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
while (1) { while (1) {
@ -1539,14 +1613,14 @@ void savetofile() {
delay(2000); delay(2000);
if (!myFile.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) { if (!myFile.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Write calibration factor to file // Write calibration factor to file
myFile.print(cal_factor); myFile.print(cal_factor);
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
delay(1000); delay(1000);
resetArduino(); resetArduino();
@ -1726,12 +1800,12 @@ void setup() {
// Init SD card // Init SD card
if (!sd.begin(SS)) { if (!sd.begin(SS)) {
display_Clear(); display_Clear();
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
#ifdef global_log #ifdef global_log
if (!myLog.open("OSCR_LOG.txt", O_RDWR | O_CREAT | O_APPEND)) { if (!myLog.open("OSCR_LOG.txt", O_RDWR | O_CREAT | O_APPEND)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
println_Msg(F("")); println_Msg(F(""));
#if defined(HW1) #if defined(HW1)
@ -1810,12 +1884,31 @@ void setColor_RGB(byte r, byte g, byte b) {
#endif #endif
} }
// Converts a progmem array into a ram array // Extract ASCII printable characters from input, collapsing underscores and spaces.
void convertPgm(const char* const pgmOptions[], byte startArray, byte numArrays) { // Use when extracting titles from cartridges, to build a rom title.
for (int i = 0; i < numArrays; i++) { byte buildRomName(char *output, const byte *input, byte length) {
strlcpy_P(menuOptions[i], (char*)pgm_read_word(&(pgmOptions[i + startArray])), 20); byte input_char;
byte output_len = 0;
for (unsigned int i = 0; i < length; i++) {
input_char = input[i];
if (isprint(input_char) && input_char != '<' && input_char != '>' && input_char != ':' && input_char != '"' && input_char != '/' && input_char != '\\' && input_char != '|' && input_char != '?' && input_char != '*') {
output[output_len++] = input_char;
} else {
if (output_len == 0 || output[output_len - 1] != '_') {
output[output_len++] = '_';
} }
} }
}
while (
output_len && (
output[output_len - 1] == '_' || output[output_len - 1] == ' '
)
) {
output_len--;
}
output[output_len] = 0;
return output_len;
}
// Converts a progmem array into a ram array // Converts a progmem array into a ram array
void convertPgm(const char* const pgmOptions[], byte numArrays) { void convertPgm(const char* const pgmOptions[], byte numArrays) {
@ -1832,7 +1925,33 @@ void print_Error(const __FlashStringHelper* errorMessage, boolean forceReset) {
if (forceReset) { if (forceReset) {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); print_STR(press_button_STR, 1);
display_Update();
wait();
if (ignoreError == 0) {
resetArduino();
} else {
ignoreError = 0;
display_Clear();
println_Msg(F(""));
println_Msg(F("Error Overwrite"));
println_Msg(F(""));
display_Update();
delay(2000);
}
}
}
void print_Error(byte errorMessage, boolean forceReset) {
errorLvl = 1;
setColor_RGB(255, 0, 0);
print_STR(errorMessage, 1);
display_Update();
if (forceReset) {
println_Msg(F(""));
// Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
if (ignoreError == 0) { if (ignoreError == 0) {
@ -1916,7 +2035,7 @@ void save_log() {
strcpy(fileName, romName); strcpy(fileName, romName);
strcat(fileName, ".txt"); strcat(fileName, ".txt");
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
while (myLog.available()) { while (myLog.available()) {
@ -1926,8 +2045,8 @@ void save_log() {
} }
myFile.write(sdBuffer, 512); myFile.write(sdBuffer, 512);
} else { } else {
word i = 0; int i = 0;
for (i = 0; i < myLog.available(); i++) { for (; i < myLog.available(); i++) {
sdBuffer[i] = myLog.read(); sdBuffer[i] = myLog.read();
} }
myFile.write(sdBuffer, i); myFile.write(sdBuffer, i);
@ -1960,7 +2079,7 @@ void print_Msg(const char myString[]) {
#if (defined(enable_LCD) || defined(enable_OLED)) #if (defined(enable_LCD) || defined(enable_OLED))
// test for word wrap // test for word wrap
if ((display.tx + strlen(myString) * 6) > 128) { if ((display.tx + strlen(myString) * 6) > 128) {
int strPos = 0; unsigned int strPos = 0;
// Print until end of display // Print until end of display
while (display.tx < 122) { while (display.tx < 122) {
display.print(myString[strPos]); display.print(myString[strPos]);
@ -2103,7 +2222,7 @@ void println_Msg(const char myString[]) {
#if (defined(enable_LCD) || defined(enable_OLED)) #if (defined(enable_LCD) || defined(enable_OLED))
// test for word wrap // test for word wrap
if ((display.tx + strlen(myString) * 6) > 128) { if ((display.tx + strlen(myString) * 6) > 128) {
int strPos = 0; unsigned int strPos = 0;
// Print until end of display // Print until end of display
while ((display.tx < 122) && (myString[strPos] != '\0')) { while ((display.tx < 122) && (myString[strPos] != '\0')) {
display.print(myString[strPos]); display.print(myString[strPos]);
@ -2234,8 +2353,8 @@ void blinkLED() {
#endif #endif
} }
void statusLED(boolean on) {
#if defined(HW5) #if defined(HW5)
void statusLED(boolean on) {
if (!on) if (!on)
PORTD |= (1 << 7); PORTD |= (1 << 7);
else else
@ -2263,8 +2382,11 @@ void statusLED(boolean on) {
PORTB &= ~(1 << 7); PORTB &= ~(1 << 7);
} }
*/ */
#endif
} }
#else
void statusLED(boolean on __attribute__ ((unused))) {
}
#endif
/****************************************** /******************************************
Menu system Menu system
@ -2310,7 +2432,7 @@ byte questionBox_Serial(const __FlashStringHelper* question, char answers[7][20]
EEPROM_readAnything(0, foldern); EEPROM_readAnything(0, foldern);
sprintf(fileName, "IMPORT/%d.bin", foldern); sprintf(fileName, "IMPORT/%d.bin", foldern);
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(create_file_STR, true);
} }
// Read file from serial // Read file from serial
@ -2577,7 +2699,7 @@ void wait_serial() {
myFile.close(); myFile.close();
} }
else { else {
print_Error(F("Can't open file"), true); print_Error(open_file_STR, true);
} }
}*/ }*/
} }
@ -2893,6 +3015,9 @@ void wait_encoder() {
void fileBrowser(const __FlashStringHelper* browserTitle) { void fileBrowser(const __FlashStringHelper* browserTitle) {
char fileNames[7][FILENAME_LENGTH]; char fileNames[7][FILENAME_LENGTH];
int currFile; int currFile;
FsFile myDir;
div_t page_layout;
filebrowse = 1; filebrowse = 1;
// Root // Root
@ -2915,37 +3040,20 @@ browserstart:
// Open filepath directory // Open filepath directory
if (!myDir.open(filePath)) { if (!myDir.open(filePath)) {
display_Clear(); display_Clear();
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Count files in directory // Count files in directory
while (myFile.openNext(&myDir, O_READ)) { while (myFile.openNext(&myDir, O_READ)) {
// Ignore if hidden if (!myFile.isHidden() && (myFile.isDir() || myFile.isFile())) {
if (myFile.isHidden()) {
}
// Indicate a directory.
else if (myFile.isDir()) {
currFile++;
}
// It's just a file
else if (myFile.isFile()) {
currFile++; currFile++;
} }
myFile.close(); myFile.close();
} }
myDir.close(); myDir.close();
// "Calculate number of needed pages" page_layout = div(currFile, 7);
if (currFile < 8) numPages = page_layout.quot + 1;
numPages = 1;
else if (currFile < 15)
numPages = 2;
else if (currFile < 22)
numPages = 3;
else if (currFile < 29)
numPages = 4;
else if (currFile < 36)
numPages = 5;
// Fill the array "answers" with 7 options to choose from in the file browser // Fill the array "answers" with 7 options to choose from in the file browser
char answers[7][20]; char answers[7][20];
@ -2953,35 +3061,12 @@ browserstart:
page: page:
// If there are less than 7 entries, set count to that number so no empty options appear // If there are less than 7 entries, set count to that number so no empty options appear
byte count; byte count = currPage == numPages ? page_layout.rem : 7;
if (currFile < 8)
count = currFile;
else if (currPage == 1)
count = 7;
else if (currFile < 15)
count = currFile - 7;
else if (currPage == 2)
count = 7;
else if (currFile < 22)
count = currFile - 14;
else if (currPage == 3)
count = 7;
else if (currFile < 29)
count = currFile - 21;
else {
display_Clear();
println_Msg(F("Too many files"));
display_Update();
println_Msg(F(""));
println_Msg(F("Press Button..."));
display_Update();
wait();
}
// Open filepath directory // Open filepath directory
if (!myDir.open(filePath)) { if (!myDir.open(filePath)) {
display_Clear(); display_Clear();
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
int countFile = 0; int countFile = 0;
@ -3231,7 +3316,8 @@ void loop() {
print_Msg(F("Mode = ")); print_Msg(F("Mode = "));
print_Msg(mode); print_Msg(mode);
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
resetArduino(); resetArduino();

View File

@ -27,16 +27,16 @@ static const char flash8MenuItem3[] PROGMEM = "Read";
static const char flash8MenuItem4[] PROGMEM = "Write"; 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"; (stored in common strings array)
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, string_reset2 };
#ifdef enable_FLASH16 #ifdef enable_FLASH16
// Flash start menu // Flash start menu
static const char flashMenuItem1[] PROGMEM = "8bit Flash adapter"; 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"; (stored in common strings array)
static const char* const menuOptionsFlash[] PROGMEM = { flashMenuItem1, flashMenuItem2, flashMenuItem3, flashMenuItem4 }; static const char* const menuOptionsFlash[] PROGMEM = { flashMenuItem1, flashMenuItem2, flashMenuItem3, string_reset2 };
// 16bit Flash menu items // 16bit Flash menu items
static const char flash16MenuItem1[] PROGMEM = "Blankcheck"; static const char flash16MenuItem1[] PROGMEM = "Blankcheck";
@ -45,8 +45,8 @@ static const char flash16MenuItem3[] PROGMEM = "Read";
static const char flash16MenuItem4[] PROGMEM = "Write"; 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"; (stored in common strings array)
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, string_reset2 };
// Eprom menu items // Eprom menu items
static const char epromMenuItem1[] PROGMEM = "Blankcheck"; static const char epromMenuItem1[] PROGMEM = "Blankcheck";
@ -54,8 +54,8 @@ static const char epromMenuItem2[] PROGMEM = "Read";
static const char epromMenuItem3[] PROGMEM = "Write"; 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"; (stored in common strings array)
static const char* const menuOptionsEprom[] PROGMEM = { epromMenuItem1, epromMenuItem2, epromMenuItem3, epromMenuItem4, epromMenuItem5, epromMenuItem6 }; static const char* const menuOptionsEprom[] PROGMEM = { epromMenuItem1, epromMenuItem2, epromMenuItem3, epromMenuItem4, epromMenuItem5, string_reset2 };
void flashMenu() { void flashMenu() {
// create menu with title and 3 options to choose from // create menu with title and 3 options to choose from
@ -153,16 +153,16 @@ void flashromMenu8() {
writeFlash29F032(); writeFlash29F032();
break; break;
case 2: case 2:
if (strcmp(flashid, "C2F3") == 0) if (flashid == 0xC2F3)
writeFlash29F1601(); writeFlash29F1601();
else if ((strcmp(flashid, "C2F1") == 0) || (strcmp(flashid, "C2F9") == 0)) else if ((flashid == 0xC2F1) || (flashid == 0xC2F9))
writeFlash29F1610(); writeFlash29F1610();
else if ((strcmp(flashid, "C2C4") == 0) || (strcmp(flashid, "C249") == 0) || (strcmp(flashid, "C2A7") == 0) || (strcmp(flashid, "C2A8") == 0) || (strcmp(flashid, "C2C9") == 0) || (strcmp(flashid, "C2CB") == 0)) else if ((flashid == 0xC2C4) || (flashid == 0xC249) || (flashid == 0xC2A7) || (flashid == 0xC2A8) || (flashid == 0xC2C9) || (flashid == 0xC2CB))
writeFlash29LV640(); writeFlash29LV640();
else if (strcmp(flashid, "017E") == 0) { else if (flashid == 0x017E) {
// 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 ((flashid == 0x0458) || (flashid == 0x0158) || (flashid == 0x01AB))
writeFlash29F800(); writeFlash29F800();
break; break;
@ -222,7 +222,8 @@ void flashromMenu8() {
println_Msg(F("s")); println_Msg(F("s"));
display_Update(); display_Update();
} }
print_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 0);
display_Update(); display_Update();
wait(); wait();
} }
@ -270,9 +271,9 @@ void flashromMenu16() {
fileBrowser(F("Select file")); fileBrowser(F("Select file"));
display_Clear(); display_Clear();
time = millis(); time = millis();
if (strcmp(flashid, "C2F3") == 0) { if (flashid == 0xC2F3) {
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 ((flashid == 0xC2C4) || (flashid == 0xC249) || (flashid == 0xC2A7) || (flashid == 0xC2A8) || (flashid == 0xC2C9) || (flashid == 0xC2CB) || (flashid == 0xC2FC)) {
writeFlash16_29LV640(); writeFlash16_29LV640();
} else { } else {
writeFlash16(); writeFlash16();
@ -403,77 +404,77 @@ idtheflash:
println_Msg(""); println_Msg("");
println_Msg(""); println_Msg("");
print_Msg(F("Flash ID: ")); print_Msg(F("Flash ID: "));
println_Msg(flashid); println_Msg(flashid_str);
if (strcmp(flashid, "C2F1") == 0) { if (flashid == 0xC2F1) {
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 (flashid == 0xC2F3) {
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 (flashid == 0xC2F9) {
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 ((flashid == 0xC2C4) || (flashid == 0xC249)) {
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 ((flashid == 0xC2A7) || (flashid == 0xC2A8)) {
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 ((flashid == 0xC2C9) || (flashid == 0xC2CB)) {
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 (flashid == 0x0141) {
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 (flashid == 0x01AD) {
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 (flashid == 0x20AD) {
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 (flashid == 0x04AD) {
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 (flashid == 0x04D4) {
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 (flashid == 0x04D5) {
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 (flashid == 0x0458) {
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 (flashid == 0x01AB) {
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 (flashid == 0x0158) {
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 (flashid == 0x01A3) {
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 (flashid == 0x017E) {
// S29GL032M // S29GL032M
if (readByte_Flash(28) == 0x1A) { if (readByte_Flash(28) == 0x1A) {
println_Msg(F("S29GL032M detected")); println_Msg(F("S29GL032M detected"));
@ -497,7 +498,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 (flashid == 0xB088) {
// 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"));
@ -505,20 +506,20 @@ 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 ((flashid == 0x8916) || (flashid == 0x8917) || (flashid == 0x8918)) {
// E28FXXXJ3A // E28FXXXJ3A
print_Msg(F("E28F")); print_Msg(F("E28F"));
switch (flashid[3]) { switch (flashid & 0x00f0) {
case '6': case 0x60:
flashSize = 131072 * 32; flashSize = 131072 * 32;
print_Msg(F("320")); print_Msg(F("320"));
break; break;
case '7': case 0x70:
flashSize = 131072 * 64; flashSize = 131072 * 64;
print_Msg(F("640")); print_Msg(F("640"));
break; break;
case '8': case 0x80:
flashSize = 131072 * 128; flashSize = 131072 * 128;
print_Msg(F("128")); print_Msg(F("128"));
break; break;
@ -536,7 +537,7 @@ idtheflash:
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_str, 5);
// Read ID a third time using a different command (type 2 flashrom) // Read ID a third time using a different command (type 2 flashrom)
resetFlash8(); resetFlash8();
@ -551,11 +552,12 @@ idtheflash:
print_Msg(F("ID Type 1: ")); print_Msg(F("ID Type 1: "));
println_Msg(vendorID); println_Msg(vendorID);
print_Msg(F("ID Type 2: ")); print_Msg(F("ID Type 2: "));
println_Msg(flashid); println_Msg(flashid_str);
println_Msg(""); println_Msg("");
println_Msg(F("UNKNOWN FLASHROM")); println_Msg(F("UNKNOWN FLASHROM"));
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -570,7 +572,8 @@ idtheflash:
print_Error(F("Press Button to reset"), true); print_Error(F("Press Button to reset"), true);
} }
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
resetFlash8(); resetFlash8();
@ -585,37 +588,37 @@ void id_Flash16() {
println_Msg(F("Flashrom Writer 16bit")); println_Msg(F("Flashrom Writer 16bit"));
println_Msg(""); println_Msg("");
print_Msg(F("Flash ID: ")); print_Msg(F("Flash ID: "));
println_Msg(flashid); println_Msg(flashid_str);
if (strcmp(flashid, "C2F1") == 0) { if (flashid == 0xC2F1) {
println_Msg(F("MX29F1610 detected")); println_Msg(F("MX29F1610 detected"));
println_Msg(""); println_Msg("");
flashSize = 2097152; flashSize = 2097152;
flashromType = 2; flashromType = 2;
} else if (strcmp(flashid, "C2F3") == 0) { } else if (flashid == 0xC2F3) {
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 (flashid == 0xC2F9) {
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 ((flashid == 0xC2C4) || (flashid == 0xC249)) {
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 ((flashid == 0xC2A7) || (flashid == 0xC2A8)) {
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 ((flashid == 0xC2C9) || (flashid == 0xC2CB)) {
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 (flashid == 0xC2FC) {
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;
@ -625,7 +628,8 @@ void id_Flash16() {
println_Msg(""); println_Msg("");
} }
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
} }
#endif #endif
@ -1004,7 +1008,9 @@ void idFlash29F032() {
dataIn8(); dataIn8();
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readByte_Flash(0), readByte_Flash(1)); flashid = readByte_Flash(0) << 8;
flashid |= readByte_Flash(1);
sprintf(flashid_str, "%04X", flashid);
} }
void eraseFlash29F032() { void eraseFlash29F032() {
@ -1038,7 +1044,7 @@ void eraseFlash29F032() {
void writeFlash29F032() { void writeFlash29F032() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
print_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 0);
print_Msg(filePath); print_Msg(filePath);
println_Msg(F("...")); println_Msg(F("..."));
display_Update(); display_Update();
@ -1048,7 +1054,7 @@ void writeFlash29F032() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
@ -1113,7 +1119,7 @@ void writeFlash29F032() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1179,7 +1185,7 @@ void resetFlash29F1610() {
void writeFlash29F1610() { void writeFlash29F1610() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -1188,7 +1194,7 @@ void writeFlash29F1610() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
@ -1225,7 +1231,7 @@ void writeFlash29F1610() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file on SD")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1233,7 +1239,7 @@ void writeFlash29F1610() {
void writeFlash29F1601() { void writeFlash29F1601() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -1242,7 +1248,7 @@ void writeFlash29F1601() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
@ -1284,7 +1290,7 @@ void writeFlash29F1601() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file on SD")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1302,7 +1308,9 @@ void idFlash29F1610() {
dataIn8(); dataIn8();
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readByte_Flash(0), readByte_Flash(2)); flashid = readByte_Flash(0) << 8;
flashid |= readByte_Flash(2);
sprintf(flashid_str, "%04X", flashid);
} }
byte readStatusReg() { byte readStatusReg() {
@ -1376,7 +1384,7 @@ void busyCheck29LV640(unsigned long myAddress, byte myData) {
void writeFlash29LV640() { void writeFlash29LV640() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -1385,7 +1393,7 @@ void writeFlash29LV640() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
@ -1412,7 +1420,7 @@ void writeFlash29LV640() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file on SD")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1423,7 +1431,7 @@ void writeFlash29LV640() {
void writeFlash29GL(unsigned long sectorSize, byte bufferSize) { void writeFlash29GL(unsigned long sectorSize, byte bufferSize) {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -1432,7 +1440,7 @@ void writeFlash29GL(unsigned long sectorSize, byte bufferSize) {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
@ -1479,7 +1487,7 @@ void writeFlash29GL(unsigned long sectorSize, byte bufferSize) {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file on SD")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1490,7 +1498,7 @@ void writeFlash29GL(unsigned long sectorSize, byte bufferSize) {
void writeFlash29F800() { void writeFlash29F800() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -1499,7 +1507,7 @@ void writeFlash29F800() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
@ -1528,7 +1536,7 @@ void writeFlash29F800() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file on SD")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1543,7 +1551,9 @@ void idFlash28FXXX() {
dataIn8(); dataIn8();
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readByte_Flash(0), readByte_Flash(1)); flashid = readByte_Flash(0) << 8;
flashid |= readByte_Flash(1);
sprintf(flashid_str, "%04X", flashid);
} }
void resetFlash28FXXX() { void resetFlash28FXXX() {
@ -1580,21 +1590,21 @@ void eraseFlash28FXXX() {
void writeFlash28FXXX() { void writeFlash28FXXX() {
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
print_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 0);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
if ((strcmp(flashid, "B088") == 0)) if ((flashid == 0xB088))
writeFlashLH28F0XX(); writeFlashLH28F0XX();
else if ((strcmp(flashid, "8916") == 0) || (strcmp(flashid, "8917") == 0) || (strcmp(flashid, "8918") == 0)) { else if ((flashid == 0x8916) || (flashid == 0x8917) || (flashid == 0x8918)) {
writeFlashE28FXXXJ3A(); writeFlashE28FXXXJ3A();
} }
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file on SD")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1602,7 +1612,7 @@ void writeFlash28FXXX() {
void writeFlashE28FXXXJ3A() { void writeFlashE28FXXXJ3A() {
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) { if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), false); print_Error(file_too_big_STR, false);
return; return;
} }
@ -1653,7 +1663,7 @@ void writeFlashE28FXXXJ3A() {
void writeFlashLH28F0XX() { void writeFlashLH28F0XX() {
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) { if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), false); print_Error(file_too_big_STR, false);
return; return;
} }
@ -1713,7 +1723,7 @@ void blankcheck_Flash() {
} }
void verifyFlash() { void verifyFlash() {
println_Msg(F("Verifying...")); print_STR(verifying_STR, 1);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
@ -1721,7 +1731,7 @@ void verifyFlash() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
blank = 0; blank = 0;
for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) { for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) {
@ -1737,15 +1747,15 @@ void verifyFlash() {
println_Msg(F("Flashrom verified OK")); println_Msg(F("Flashrom verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(blank); print_Msg(blank);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file on SD")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1772,7 +1782,7 @@ void readFlash() {
// 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(create_file_STR, true);
} }
for (unsigned long currByte = 0; currByte < flashSize; currByte += 512) { for (unsigned long currByte = 0; currByte < flashSize; currByte += 512) {
for (int c = 0; c < 512; c++) { for (int c = 0; c < 512; c++) {
@ -1793,7 +1803,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 (size_t i = 0; i < 2 - strlen(myBuffer); i++) {
print_Msg(F("0")); print_Msg(F("0"));
} }
// Now print the significant bits // Now print the significant bits
@ -1834,7 +1844,7 @@ void resetFlash16() {
void writeFlash16() { void writeFlash16() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -1843,7 +1853,7 @@ void writeFlash16() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut16(); dataOut16();
@ -1892,7 +1902,7 @@ void writeFlash16() {
void writeFlash16_29F1601() { void writeFlash16_29F1601() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -1901,7 +1911,7 @@ void writeFlash16_29F1601() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut16(); dataOut16();
@ -1965,7 +1975,9 @@ void idFlash16() {
dataIn16(); dataIn16();
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readWord_Flash(0) & 0xFF, readWord_Flash(1) & 0xFF); flashid = (readWord_Flash(0) & 0xFF) << 8;
flashid |= readWord_Flash(1) & 0xFF;
sprintf(flashid_str, "%04X", flashid);
} }
byte readStatusReg16() { byte readStatusReg16() {
@ -2024,7 +2036,7 @@ void blankcheck16() {
} }
void verifyFlash16() { void verifyFlash16() {
println_Msg(F("Verifying...")); print_STR(verifying_STR, 1);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
@ -2032,7 +2044,7 @@ void verifyFlash16() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) { if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
} }
blank = 0; blank = 0;
@ -2135,14 +2147,14 @@ void printFlash16(int numBytes) {
sprintf(buf, "%x", left_byte); sprintf(buf, "%x", left_byte);
for (int i = 0; i < 2 - strlen(buf); i++) { for (size_t 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 (size_t 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
@ -2190,7 +2202,7 @@ void busyCheck16_29LV640(unsigned long myAddress, word myData) {
void writeFlash16_29LV640() { void writeFlash16_29LV640() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -2199,7 +2211,7 @@ void writeFlash16_29LV640() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Set data pins to output // Set data pins to output
dataOut16(); dataOut16();
@ -2417,7 +2429,7 @@ void read_Eprom() {
void write_Eprom() { void write_Eprom() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 1);
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
@ -2426,7 +2438,7 @@ void write_Eprom() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
// Switch VPP/OE(PH5) to HIGH // Switch VPP/OE(PH5) to HIGH
PORTH |= (1 << 5); PORTH |= (1 << 5);
@ -2477,7 +2489,7 @@ void write_Eprom() {
} }
void verify_Eprom() { void verify_Eprom() {
println_Msg(F("Verifying...")); print_STR(verifying_STR, 1);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
@ -2485,7 +2497,7 @@ void verify_Eprom() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) { if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
} }
blank = 0; blank = 0;
@ -2534,14 +2546,14 @@ void print_Eprom(int numBytes) {
sprintf(buf, "%x", left_byte); sprintf(buf, "%x", left_byte);
for (int i = 0; i < 2 - strlen(buf); i++) { for (size_t 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 (size_t 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

View File

@ -7,8 +7,8 @@
Variables Variables
*****************************************/ *****************************************/
// Game Boy // Game Boy
int sramBanks; word sramBanks;
int romBanks; word romBanks;
word lastByte = 0; word lastByte = 0;
/****************************************** /******************************************
@ -19,15 +19,15 @@ static const char gbxMenuItem1[] PROGMEM = "Game Boy (Color)";
static const char gbxMenuItem2[] PROGMEM = "GB Advance (3V)"; 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"; (stored in common strings array)
static const char* const menuOptionsGBx[] PROGMEM = { gbxMenuItem1, gbxMenuItem2, gbxMenuItem3, gbxMenuItem4, gbxMenuItem5 }; static const char* const menuOptionsGBx[] PROGMEM = { gbxMenuItem1, gbxMenuItem2, gbxMenuItem3, gbxMenuItem4, string_reset2 };
// 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"; (stored in common strings array)
static const char* const menuOptionsGB[] PROGMEM = { GBMenuItem1, GBMenuItem2, GBMenuItem3, GBMenuItem4 }; static const char* const menuOptionsGB[] PROGMEM = { GBMenuItem1, GBMenuItem2, GBMenuItem3, string_reset2 };
// GB Flash items // GB Flash items
static const char GBFlashItem1[] PROGMEM = "29F Cart (MBC3)"; static const char GBFlashItem1[] PROGMEM = "29F Cart (MBC3)";
@ -36,8 +36,8 @@ static const char GBFlashItem3[] PROGMEM = "29F Cart (CAM)";
static const char GBFlashItem4[] PROGMEM = "CFI Cart"; 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"; (stored in common strings array)
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, string_reset2 };
// Start menu for both GB and GBA // Start menu for both GB and GBA
void gbxMenu() { void gbxMenu() {
@ -84,7 +84,8 @@ void gbxMenu() {
//MBC3 //MBC3
writeFlash29F_GB(3, 1); writeFlash29F_GB(3, 1);
// Reset // Reset
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
resetArduino(); resetArduino();
@ -102,7 +103,8 @@ void gbxMenu() {
//MBC5 //MBC5
writeFlash29F_GB(5, 1); writeFlash29F_GB(5, 1);
// Reset // Reset
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
resetArduino(); resetArduino();
@ -120,7 +122,8 @@ void gbxMenu() {
sd.chdir("/"); sd.chdir("/");
//MBC3 //MBC3
writeFlash29F_GB(3, 1); writeFlash29F_GB(3, 1);
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -131,7 +134,8 @@ void gbxMenu() {
println_Msg(F("if you want to flash")); println_Msg(F("if you want to flash"));
println_Msg(F("a second game")); println_Msg(F("a second game"));
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -143,7 +147,8 @@ void gbxMenu() {
// Reset // Reset
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
resetArduino(); resetArduino();
@ -167,7 +172,8 @@ void gbxMenu() {
if (!writeCFI_GB()) { if (!writeCFI_GB()) {
display_Clear(); display_Clear();
println_Msg(F("Flashing failed, time out!")); println_Msg(F("Flashing failed, time out!"));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -194,7 +200,8 @@ void gbxMenu() {
if (!writeCFI_GB()) { if (!writeCFI_GB()) {
display_Clear(); display_Clear();
println_Msg(F("Flashing failed, time out!")); println_Msg(F("Flashing failed, time out!"));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
resetArduino(); resetArduino();
@ -230,10 +237,10 @@ void gbxMenu() {
println_Msg(F("Verified OK")); println_Msg(F("Verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(wrErrors); print_Msg(wrErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
break; break;
} }
@ -333,10 +340,10 @@ void gbMenu() {
println_Msg(F("Verified OK")); println_Msg(F("Verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(wrErrors); print_Msg(wrErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} }
} else { } else {
@ -349,7 +356,8 @@ void gbMenu() {
resetArduino(); resetArduino();
break; break;
} }
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -534,7 +542,8 @@ void showCartInfo_GB() {
// Wait for user input // Wait for user input
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} else { } else {
@ -873,12 +882,10 @@ void getCartInfo_GB() {
for (int addr = 0x0134; addr <= 0x0143 - x; addr++) { for (int addr = 0x0134; addr <= 0x0143 - x; addr++) {
myByte = sdBuffer[addr]; myByte = sdBuffer[addr];
if (isprint(myByte) && myByte != '<' && myByte != '>' && myByte != ':' && myByte != '"' && myByte != '/' && myByte != '\\' && myByte != '|' && myByte != '?' && myByte != '*') { if (isprint(myByte) && myByte != '<' && myByte != '>' && myByte != ':' && myByte != '"' && myByte != '/' && myByte != '\\' && myByte != '|' && myByte != '?' && myByte != '*') {
romName[myLength] = char(myByte); romName[myLength++] = char(myByte);
} else { } else if (myLength == 0 || romName[myLength - 1] != '_') {
if (romName[myLength - 1] == 0x5F) myLength--; romName[myLength++] = '_';
romName[myLength] = 0x5F;
} }
myLength++;
} }
// Find Game Serial // Find Game Serial
@ -895,26 +902,50 @@ void getCartInfo_GB() {
} }
// Strip trailing white space // Strip trailing white space
for (unsigned int i = myLength - 1; i > 0; i--) { while (
if ((romName[i] != 0x5F) && (romName[i] != 0x20)) break; myLength &&
romName[i] = 0x00; (romName[myLength - 1] == '_' || romName[myLength - 1] == ' ')
) {
myLength--; myLength--;
} }
romName[myLength] = 0;
// M161 (Mani 4 in 1) // M161 (Mani 4 in 1)
if ((strncmp(romName, "TETRIS SET", 10) == 0) && (sdBuffer[0x14D] == 0x3F)) { if (strncmp(romName, "TETRIS SET", 10) == 0 && sdBuffer[0x14D] == 0x3F) {
romType = 0x104; romType = 0x104;
} }
// MMM01 (Mani 4 in 1) // MMM01 (Mani 4 in 1)
if ( if (
(strncmp(romName, "BOUKENJIMA2 SET", 15) == 0) && (sdBuffer[0x14D] == 0) || (strncmp(romName, "BUBBLEBOBBLE SET", 16) == 0) && (sdBuffer[0x14D] == 0xC6) || (strncmp(romName, "GANBARUGA SET", 13) == 0) && (sdBuffer[0x14D] == 0x90) || (strncmp(romName, "RTYPE 2 SET", 11) == 0) && (sdBuffer[0x14D] == 0x32)) { (
strncmp(romName, "BOUKENJIMA2 SET", 15) == 0 && sdBuffer[0x14D] == 0
) || (
strncmp(romName, "BUBBLEBOBBLE SET", 16) == 0 && sdBuffer[0x14D] == 0xC6
) || (
strncmp(romName, "GANBARUGA SET", 13) == 0 && sdBuffer[0x14D] == 0x90
) || (
strncmp(romName, "RTYPE 2 SET", 11) == 0 && sdBuffer[0x14D] == 0x32
)
) {
romType = 0x0B; romType = 0x0B;
} }
// MBC1M // MBC1M
if ( if (
(strncmp(romName, "MOMOCOL", 7) == 0) && (sdBuffer[0x14D] == 0x28) || (strncmp(romName, "BOMCOL", 6) == 0) && (sdBuffer[0x14D] == 0x86) || (strncmp(romName, "GENCOL", 6) == 0) && (sdBuffer[0x14D] == 0x8A) || (strncmp(romName, "SUPERCHINESE 123", 16) == 0) && (sdBuffer[0x14D] == 0xE4) || (strncmp(romName, "MORTALKOMBATI&II", 16) == 0) && (sdBuffer[0x14D] == 0xB9) || (strncmp(romName, "MORTALKOMBAT DUO", 16) == 0) && (sdBuffer[0x14D] == 0xA7)) { (
strncmp(romName, "MOMOCOL", 7) == 0 && sdBuffer[0x14D] == 0x28
) || (
strncmp(romName, "BOMCOL", 6) == 0 && sdBuffer[0x14D] == 0x86
) || (
strncmp(romName, "GENCOL", 6) == 0 && sdBuffer[0x14D] == 0x8A
) || (
strncmp(romName, "SUPERCHINESE 123", 16) == 0 && sdBuffer[0x14D] == 0xE4
) || (
strncmp(romName, "MORTALKOMBATI&II", 16) == 0 && sdBuffer[0x14D] == 0xB9
) || (
strncmp(romName, "MORTALKOMBAT DUO", 16) == 0 && sdBuffer[0x14D] == 0xA7
)
) {
romType += 0x100; romType += 0x100;
} }
@ -938,7 +969,7 @@ void readROM_GB() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -949,10 +980,10 @@ void readROM_GB() {
//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(create_file_STR, true);
} }
int endAddress = 0x7FFF; word endAddress = 0x7FFF;
word romAddress = 0; word romAddress = 0;
word startBank = 1; word startBank = 1;
@ -1073,7 +1104,7 @@ void readROM_GB() {
} }
// Calculate checksum // Calculate checksum
unsigned int calc_checksum_GB(char* fileName, char* folder) { unsigned int calc_checksum_GB(char* fileName) {
unsigned int calcChecksum = 0; unsigned int calcChecksum = 0;
// int calcFilesize = 0; // unused // int calcFilesize = 0; // unused
unsigned long i = 0; unsigned long i = 0;
@ -1117,7 +1148,7 @@ void compare_checksums_GB() {
// Internal ROM checksum // Internal ROM checksum
char calcsumStr[5]; char calcsumStr[5];
sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder)); sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName));
print_Msg(F("Checksum: ")); print_Msg(F("Checksum: "));
print_Msg(calcsumStr); print_Msg(calcsumStr);
@ -1158,7 +1189,7 @@ void readSRAM_GB() {
//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("SD Error"), true); print_Error(sd_error_STR, true);
} }
// MBC2 Fix // MBC2 Fix
@ -1289,7 +1320,8 @@ unsigned long verifySRAM_GB() {
myFile.close(); myFile.close();
return writeErrors; return writeErrors;
} else { } else {
print_Error(F("Can't open file"), true); print_Error(open_file_STR, true);
return 1;
} }
} }
@ -1306,7 +1338,7 @@ void readSRAMFLASH_MBC6_GB() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -1317,7 +1349,7 @@ void readSRAMFLASH_MBC6_GB() {
//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("SD Error"), true); print_Error(sd_error_STR, true);
} }
//Initialize progress bar //Initialize progress bar
@ -1599,33 +1631,34 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
writeByte_GB(0x555, 0x90); writeByte_GB(0x555, 0x90);
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readByte_GB(0), readByte_GB(1)); flashid = readByte_GB(0) << 8;
flashid |= readByte_GB(1);
if (strcmp(flashid, "04D4") == 0) { if (flashid == 0x04D4) {
println_Msg(F("MBM29F033C")); println_Msg(F("MBM29F033C"));
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, "0141") == 0) { } else if (flashid == 0x0141) {
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 (flashid == 0x01AD) {
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 (flashid == 0x04AD) {
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 (flashid == 0x01D5) {
println_Msg(F("AM29F080B")); println_Msg(F("AM29F080B"));
print_Msg(F("Banks: ")); print_Msg(F("Banks: "));
print_Msg(romBanks); print_Msg(romBanks);
@ -1633,7 +1666,8 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
display_Update(); display_Update();
} else { } else {
print_Msg(F("Flash ID: ")); print_Msg(F("Flash ID: "));
println_Msg(flashid); sprintf(flashid_str, "%04X", flashid);
println_Msg(flashid_str);
display_Update(); display_Update();
print_Error(F("Unknown flashrom"), true); print_Error(F("Unknown flashrom"), true);
} }
@ -1668,7 +1702,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
display_Update(); display_Update();
// Read x number of banks // Read x number of banks
for (int currBank = 0; currBank < romBanks; currBank++) { for (word currBank = 0; currBank < romBanks; currBank++) {
// Blink led // Blink led
blinkLED(); blinkLED();
@ -1702,7 +1736,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
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 (word currBank = 0; currBank < romBanks; currBank++) {
// Blink led // Blink led
blinkLED(); blinkLED();
@ -1752,7 +1786,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
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 (word currBank = 0; currBank < romBanks; currBank++) {
// Blink led // Blink led
blinkLED(); blinkLED();
@ -1788,7 +1822,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
} }
} }
print_Msg(F("Verifying...")); print_STR(verifying_STR, 0);
display_Update(); display_Update();
// Go back to file beginning // Go back to file beginning
@ -1837,11 +1871,11 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
} else { } else {
println_Msg(F("Error")); println_Msg(F("Error"));
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), true); print_Error(did_not_verify_STR, true);
} }
} else { } else {
println_Msg(F("Can't open file")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1874,7 +1908,7 @@ byte readByteCompensated(int address) {
. .
address needs to be the x8 mode address of the flash register that should be read. address needs to be the x8 mode address of the flash register that should be read.
*/ */
byte writeByteCompensated(int address, byte data) { void writeByteCompensated(int address, byte data) {
if (flashSwitchLastBits) { if (flashSwitchLastBits) {
data = (data & 0b11111100) | ((data << 1) & 0b10) | ((data >> 1) & 0b01); data = (data & 0b11111100) | ((data << 1) & 0b10) | ((data >> 1) & 0b01);
} }
@ -2018,7 +2052,8 @@ bool writeCFI_GB() {
print_Msg(F("but needs ")); print_Msg(F("but needs "));
print_Msg(romBanks); print_Msg(romBanks);
println_Msg(F(".")); println_Msg(F("."));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
resetArduino(); resetArduino();
@ -2066,7 +2101,7 @@ bool writeCFI_GB() {
display_Update(); display_Update();
// Read x number of banks // Read x number of banks
for (int currBank = 0; currBank < romBanks; currBank++) { for (word currBank = 0; currBank < romBanks; currBank++) {
// Blink led // Blink led
blinkLED(); blinkLED();
@ -2093,7 +2128,7 @@ bool writeCFI_GB() {
word currAddr = 0; word currAddr = 0;
word endAddr = 0x3FFF; word endAddr = 0x3FFF;
for (int currBank = 0; currBank < romBanks; currBank++) { for (word currBank = 0; currBank < romBanks; currBank++) {
// Blink led // Blink led
blinkLED(); blinkLED();
@ -2194,13 +2229,13 @@ bool writeCFI_GB() {
println_Msg(F("OK")); println_Msg(F("OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
println_Msg(F("Can't open file")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
return true; return true;

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,8 @@ void gbmMenu() {
println_Msg(F("cartreader directly")); println_Msg(F("cartreader directly"));
println_Msg(F("before reading")); println_Msg(F("before reading"));
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
// Clear screen // Clear screen
@ -71,7 +72,8 @@ void gbmMenu() {
println_Msg(F("NP Cartridge.")); println_Msg(F("NP Cartridge."));
println_Msg(""); println_Msg("");
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
// Clear screen // Clear screen
@ -131,7 +133,8 @@ void gbmMenu() {
println_Msg(F("NP Cartridge's")); println_Msg(F("NP Cartridge's"));
println_Msg(F("mapping data")); println_Msg(F("mapping data"));
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -171,7 +174,8 @@ void gbmMenu() {
break; break;
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -304,7 +308,7 @@ void writeByte_GBM(word myAddress, byte myData) {
HELPER FUNCTIONS HELPER FUNCTIONS
**********************/ **********************/
void printSdBuffer(word startByte, word numBytes) { void printSdBuffer(word startByte, word numBytes) {
for (int currByte = 0; currByte < numBytes; currByte += 10) { for (word currByte = 0; currByte < numBytes; currByte += 10) {
for (byte c = 0; c < 10; c++) { for (byte c = 0; c < 10; c++) {
// Convert to char array so we don't lose leading zeros // Convert to char array so we don't lose leading zeros
char currByteStr[2]; char currByteStr[2];
@ -333,7 +337,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(create_file_STR, true);
} else { } else {
// Read rom // Read rom
word currAddress = 0; word currAddress = 0;
@ -492,16 +496,18 @@ boolean readFlashID_GBM() {
send_GBM(0x0F, 0x5555, 0x90); send_GBM(0x0F, 0x5555, 0x90);
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readByte_GBM(0), readByte_GBM(1)); flashid = readByte_GBM(0) << 8;
if (strcmp(flashid, "C289") == 0) { flashid |= readByte_GBM(1);
sprintf(flashid_str, "%04X", flashid);
if (flashid == 0xC289) {
print_Msg(F("Flash ID: ")); print_Msg(F("Flash ID: "));
println_Msg(flashid); println_Msg(flashid_str);
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_str);
print_Error(F("Unknown Flash ID"), true); print_Error(F("Unknown Flash ID"), true);
resetFlash_GBM(); resetFlash_GBM();
return 0; return 0;
@ -677,7 +683,7 @@ void writeFlash_GBM() {
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
} else { } else {
print_Error(F("Can't open file"), false); print_Error(F("Can't open file"), false);
} }
@ -716,7 +722,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(create_file_STR, 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);
@ -891,7 +897,7 @@ void writeMapping_GBM() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
} else { } else {
print_Error(F("Can't open file"), false); print_Error(F("Can't open file"), false);
} }

View File

@ -11,8 +11,8 @@
// GB Smart menu items // GB Smart menu items
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"; (stored in common strings array)
static const char* const menuOptionsGBSmart[] PROGMEM = { gbSmartMenuItem1, gbSmartMenuItem2, gbSmartMenuItem3 }; static const char* const menuOptionsGBSmart[] PROGMEM = { gbSmartMenuItem1, gbSmartMenuItem2, string_reset2 };
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";
@ -23,17 +23,17 @@ 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"; (stored in common strings array)
static const char* const menuOptionsGBSmartGame[] PROGMEM = { gbSmartGameMenuItem1, gbSmartGameMenuItem2, gbSmartGameMenuItem3, gbSmartGameMenuItem4, gbSmartGameMenuItem5 }; static const char* const menuOptionsGBSmartGame[] PROGMEM = { gbSmartGameMenuItem1, gbSmartGameMenuItem2, gbSmartGameMenuItem3, gbSmartGameMenuItem4, string_reset2 };
typedef struct struct GBSmartGameInfo
{ {
uint8_t start_bank; uint8_t start_bank;
uint8_t rom_type; uint8_t rom_type;
uint8_t rom_size; uint8_t rom_size;
uint8_t sram_size; uint8_t sram_size;
char title[16]; char title[16];
} GBSmartGameInfo; };
uint32_t gbSmartSize = 32 * 131072; uint32_t gbSmartSize = 32 * 131072;
uint16_t gbSmartBanks = 256; uint16_t gbSmartBanks = 256;
@ -46,19 +46,9 @@ uint8_t gbSmartRomSizeGB = 0x07;
uint8_t gbSmartSramSizeGB = 0x04; uint8_t gbSmartSramSizeGB = 0x04;
uint8_t gbSmartFlashSizeGB = 0x06; uint8_t gbSmartFlashSizeGB = 0x06;
GBSmartGameInfo gbSmartGames[GB_SMART_GAMES_PER_PAGE];
byte signature[48]; byte signature[48];
uint16_t gameMenuStartBank; uint16_t gameMenuStartBank;
#ifdef enable_SFM
extern boolean hasMenu;
extern byte numGames;
#else
boolean hasMenu;
byte numGames;
#endif
// Compare checksum // Compare checksum
boolean compare_checksum_GBS() { boolean compare_checksum_GBS() {
println_Msg(F("Calculating Checksum")); println_Msg(F("Calculating Checksum"));
@ -72,7 +62,7 @@ boolean compare_checksum_GBS() {
sprintf(folder, "GB/ROM/%s/%d", romName, foldern - 1); sprintf(folder, "GB/ROM/%s/%d", romName, foldern - 1);
char calcsumStr[5]; char calcsumStr[5];
sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder)); sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName));
if (strcmp(calcsumStr, checksumStr) == 0) { if (strcmp(calcsumStr, checksumStr) == 0) {
print_Msg(F("Result: ")); print_Msg(F("Result: "));
@ -150,8 +140,6 @@ void setup_GBSmart() {
signature[i] = readByte_GBS(0x0104 + i); signature[i] = readByte_GBS(0x0104 + i);
gameMenuStartBank = 0x02; gameMenuStartBank = 0x02;
hasMenu = true;
numGames = 0;
display_Clear(); display_Clear();
display_Update(); display_Update();
@ -216,10 +204,10 @@ void gbSmartGameOptions() {
println_Msg(F("Verified OK")); println_Msg(F("Verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(wrErrors); print_Msg(wrErrors);
println_Msg(F(" bytes")); println_Msg(F(" bytes"));
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
break; break;
} }
@ -238,19 +226,23 @@ void gbSmartGameOptions() {
if (gameSubMenu != 3) { if (gameSubMenu != 3) {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
} }
void gbSmartGameMenu() { void gbSmartGameMenu() {
boolean hasMenu;
byte numGames;
struct GBSmartGameInfo gbSmartGames[GB_SMART_GAMES_PER_PAGE];
uint8_t gameSubMenu = 0; uint8_t gameSubMenu = 0;
gb_smart_load_more_games: gb_smart_load_more_games:
if (gameMenuStartBank > 0xfe) if (gameMenuStartBank > 0xfe)
gameMenuStartBank = 0x02; gameMenuStartBank = 0x02;
gbSmartGetGames(); gbSmartGetGames(gbSmartGames, &hasMenu, &numGames);
if (hasMenu) { if (hasMenu) {
char menuOptionsGBSmartGames[7][20]; char menuOptionsGBSmartGames[7][20];
@ -310,7 +302,8 @@ void gbSmartFlashMenu() {
println_Msg(F("This will erase your")); println_Msg(F("This will erase your"));
println_Msg(F("GB Smart Cartridge.")); println_Msg(F("GB Smart Cartridge."));
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -331,34 +324,50 @@ void gbSmartFlashMenu() {
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
void gbSmartGetGames() { void gbSmartGetOneGame(struct GBSmartGameInfo *gbSmartGames, byte bank, word base) {
uint8_t myByte, myLength = 0;
word title_address = base + 0x0134;
for (uint8_t j = 0; j < 15; j++) {
myByte = readByte_GBS(title_address++);
if (((myByte >= '0' && myByte <= '9') || (myByte >= 'A' && myByte <= 'z')))
gbSmartGames->title[myLength++] = myByte;
}
gbSmartGames->title[myLength] = 0x00;
gbSmartGames->start_bank = bank;
gbSmartGames->rom_type = readByte_GBS(base + 0x0147);
gbSmartGames->rom_size = readByte_GBS(base + 0x0148);
gbSmartGames->sram_size = readByte_GBS(base + 0x0149);
}
void gbSmartGetGames(struct GBSmartGameInfo *gbSmartGames, boolean *hasMenu, byte *numGames) {
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);
uint16_t i; uint16_t i;
uint8_t myByte, myLength;
// 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;
// switch bank // switch bank
dataOut(); dataOut();
writeByte_GB(0x2100, i); writeByte_GB(0x2100, i);
@ -368,46 +377,19 @@ void gbSmartGetGames() {
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; continue;
} }
} }
gbSmartGetOneGame(&gbSmartGames[*numGames], i, 0x4000);
for (uint8_t j = 0; j < 15; j++) { i += (2 << gbSmartGames[(*numGames)++].rom_size);
myByte = readByte_GBS(0x4134 + j);
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) || (char(myByte) >= 0x41 && char(myByte) <= 0x7a)))
gbSmartGames[numGames].title[myLength++] = char(myByte);
}
gbSmartGames[numGames].title[myLength] = 0x00;
gbSmartGames[numGames].start_bank = i;
gbSmartGames[numGames].rom_type = readByte_GBS(0x4147);
gbSmartGames[numGames].rom_size = readByte_GBS(0x4148);
gbSmartGames[numGames].sram_size = readByte_GBS(0x4149);
myByte = (2 << gbSmartGames[numGames].rom_size);
i += myByte;
numGames++;
gb_smart_get_game_loop_end:;
} }
gameMenuStartBank = i; gameMenuStartBank = i;
} else { } else {
dataIn(); dataIn();
for (uint8_t j = 0; j < 15; j++) { gbSmartGetOneGame(&gbSmartGames[0], 0, 0);
myByte = readByte_GBS(0x0134 + j);
if (((char(myByte) >= 0x30 && char(myByte) <= 0x39) || (char(myByte) >= 0x41 && char(myByte) <= 0x7a))) *numGames = 1;
gbSmartGames[0].title[myLength++] = char(myByte);
}
gbSmartGames[0].title[myLength] = 0x00;
gbSmartGames[0].start_bank = 0x00;
gbSmartGames[0].rom_type = readByte_GBS(0x0147);
gbSmartGames[0].rom_size = readByte_GBS(0x0148);
gbSmartGames[0].sram_size = readByte_GBS(0x0149);
numGames = 1;
gameMenuStartBank = 0xfe; gameMenuStartBank = 0xfe;
} }
} }
@ -419,10 +401,10 @@ void gbSmartReadFlash() {
display_Update(); display_Update();
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(create_file_STR, true);
// reset flash to read array state // reset flash to read array state
for (int i = 0x00; i < gbSmartBanks; i += gbSmartBanksPerFlashChip) for (uint16_t i = 0x00; i < gbSmartBanks; i += gbSmartBanksPerFlashChip)
gbSmartResetFlash(i); gbSmartResetFlash(i);
// remaps mmc to full access // remaps mmc to full access
@ -461,7 +443,7 @@ void gbSmartReadFlash() {
} }
void gbSmartWriteFlash() { void gbSmartWriteFlash() {
for (int bank = 0x00; bank < gbSmartBanks; bank += gbSmartBanksPerFlashChip) { for (uint16_t bank = 0x00; bank < gbSmartBanks; bank += gbSmartBanksPerFlashChip) {
display_Clear(); display_Clear();
print_Msg(F("Erasing...")); print_Msg(F("Erasing..."));
@ -470,7 +452,7 @@ void gbSmartWriteFlash() {
gbSmartEraseFlash(bank); gbSmartEraseFlash(bank);
gbSmartResetFlash(bank); gbSmartResetFlash(bank);
println_Msg(F("Done")); print_STR(done_STR, 1);
print_Msg(F("Blankcheck...")); print_Msg(F("Blankcheck..."));
display_Update(); display_Update();
@ -487,7 +469,7 @@ void gbSmartWriteFlash() {
gbSmartWriteFlashByte(0x0000, 0xff); gbSmartWriteFlashByte(0x0000, 0xff);
} }
print_Msg(F("Verifying...")); print_STR(verifying_STR, 0);
display_Update(); display_Update();
writeErrors = gbSmartVerifyFlash(); writeErrors = gbSmartVerifyFlash();
@ -495,16 +477,16 @@ void gbSmartWriteFlash() {
println_Msg(F("OK")); println_Msg(F("OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), true); print_Error(did_not_verify_STR, true);
} }
} }
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(open_file_STR, true);
// switch to flash base bank // switch to flash base bank
gbSmartRemapStartBank(start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB); gbSmartRemapStartBank(start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);

View File

@ -95,8 +95,8 @@ byte newintvsize;
static const char intvMenuItem1[] PROGMEM = "Select Cart"; 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"; (stored in common strings array)
static const char* const menuOptionsINTV[] PROGMEM = { intvMenuItem1, intvMenuItem2, intvMenuItem3, intvMenuItem4 }; static const char* const menuOptionsINTV[] PROGMEM = { intvMenuItem1, intvMenuItem2, intvMenuItem3, string_reset2 };
void setup_INTV() { void setup_INTV() {
// Set Address Pins to Output (UNUSED) // Set Address Pins to Output (UNUSED)
@ -316,14 +316,14 @@ void readROM_INTV() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
// open file on sdcard // open file on sdcard
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(create_file_STR, true);
// write new folder number back to EEPROM // write new folder number back to EEPROM
foldern++; foldern++;
@ -423,7 +423,8 @@ void readROM_INTV() {
compareCRC("intv.txt", 0, 1, 0); compareCRC("intv.txt", 0, 1, 0);
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -528,11 +529,11 @@ void setMapper_INTV() {
println_Msg(intvmapselect); println_Msg(intvmapselect);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
@ -553,11 +554,11 @@ void setMapper_INTV() {
println_Msg(intvmapselect); println_Msg(intvmapselect);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -575,11 +576,11 @@ void setMapper_INTV() {
println_Msg(intvmapselect); println_Msg(intvmapselect);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -647,11 +648,11 @@ void setROMSize_INTV() {
println_Msg(INTV[i]); println_Msg(INTV[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
@ -669,11 +670,11 @@ void setROMSize_INTV() {
println_Msg(INTV[i]); println_Msg(INTV[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -688,11 +689,11 @@ void setROMSize_INTV() {
println_Msg(INTV[i]); println_Msg(INTV[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -806,20 +807,7 @@ void setCart_INTV() {
} }
// Rewind one line // Rewind one line
for (byte count_newline = 0; count_newline < 2; count_newline++) { rewind_line(myFile);
while (1) {
if (myFile.curPosition() == 0) {
break;
} else if (myFile.peek() == '\n') {
myFile.seekSet(myFile.curPosition() - 1);
break;
} else {
myFile.seekSet(myFile.curPosition() - 1);
}
}
}
if (myFile.curPosition() != 0)
myFile.seekSet(myFile.curPosition() + 2);
} }
// Display database // Display database
@ -837,7 +825,7 @@ void setCart_INTV() {
} }
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read CRC32 of first 512 bytes // Read CRC32 of first 512 bytes
sprintf(crc_search, "%c", myFile.read()); sprintf(crc_search, "%c", myFile.read());
@ -847,13 +835,13 @@ void setCart_INTV() {
} }
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read mapper // Read mapper
intvmapper = myFile.read() - 48; intvmapper = myFile.read() - 48;
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read rom size // Read rom size
// Read the next ascii character and subtract 48 to convert to decimal // Read the next ascii character and subtract 48 to convert to decimal
@ -867,13 +855,13 @@ void setCart_INTV() {
} }
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read SRAM size // Read SRAM size
byte sramSize = myFile.read() - 48; byte sramSize __attribute__ ((unused)) = myFile.read() - 48;
// Skip rest of line // Skip rest of line
myFile.seekSet(myFile.curPosition() + 2); myFile.seekCur(2);
// Skip every 3rd line // Skip every 3rd line
skip_line(&myFile); skip_line(&myFile);
@ -887,11 +875,11 @@ void setCart_INTV() {
print_Msg(F("Mapper: ")); print_Msg(F("Mapper: "));
println_Msg(intvmapper); println_Msg(intvmapper);
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#elif defined(SERIAL_MONITOR) #elif defined(SERIAL_MONITOR)
println_Msg(F("U/D to Change")); println_Msg(F("U/D to Change"));
println_Msg(F("Space to Select")); println_Msg(F("Space to Select"));
@ -910,20 +898,7 @@ void setCart_INTV() {
// Previous // Previous
else if (b == 2) { else if (b == 2) {
for (byte count_newline = 0; count_newline < 7; count_newline++) { rewind_line(myFile, 6);
while (1) {
if (myFile.curPosition() == 0) {
break;
} else if (myFile.peek() == '\n') {
myFile.seekSet(myFile.curPosition() - 1);
break;
} else {
myFile.seekSet(myFile.curPosition() - 1);
}
}
}
if (myFile.curPosition() != 0)
myFile.seekSet(myFile.curPosition() + 2);
break; break;
} }

View File

@ -8,7 +8,7 @@
Variables Variables
*****************************************/ *****************************************/
unsigned long sramEnd; unsigned long sramEnd;
int eepSize; word eepSize;
word addrhi; word addrhi;
word addrlo; word addrlo;
word chksum; word chksum;
@ -103,10 +103,6 @@ static unsigned long cartSizeLockon;
static unsigned long cartSizeSonic2 = 262144; static unsigned long cartSizeSonic2 = 262144;
static word chksumLockon; static word chksumLockon;
static word chksumSonic2 = 0x0635; static word chksumSonic2 = 0x0635;
static char romNameLockon[12];
static char id[15];
static char idLockon[15];
static char labelLockon[17];
/****************************************** /******************************************
Configuration Configuration
@ -192,8 +188,8 @@ void mdLoadConf() {
static const char MDMenuItem1[] PROGMEM = "Game Cartridge"; static const char MDMenuItem1[] PROGMEM = "Game Cartridge";
static const char MDMenuItem2[] PROGMEM = "SegaCD RamCart"; static const char MDMenuItem2[] PROGMEM = "SegaCD RamCart";
static const char MDMenuItem3[] PROGMEM = "Flash Repro"; static const char MDMenuItem3[] PROGMEM = "Flash Repro";
static const char MDMenuItem4[] PROGMEM = "Reset"; //static const char MDMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsMD[] PROGMEM = { MDMenuItem1, MDMenuItem2, MDMenuItem3, MDMenuItem4 }; static const char* const menuOptionsMD[] PROGMEM = { MDMenuItem1, MDMenuItem2, MDMenuItem3, string_reset2 };
// Cart menu items // Cart menu items
static const char MDCartMenuItem1[] PROGMEM = "Read Rom"; static const char MDCartMenuItem1[] PROGMEM = "Read Rom";
@ -202,14 +198,14 @@ static const char MDCartMenuItem3[] PROGMEM = "Write Sram";
static const char MDCartMenuItem4[] PROGMEM = "Read EEPROM"; static const char MDCartMenuItem4[] PROGMEM = "Read EEPROM";
static const char MDCartMenuItem5[] PROGMEM = "Write EEPROM"; static const char MDCartMenuItem5[] PROGMEM = "Write EEPROM";
static const char MDCartMenuItem6[] PROGMEM = "Cycle cart"; static const char MDCartMenuItem6[] PROGMEM = "Cycle cart";
static const char MDCartMenuItem7[] PROGMEM = "Reset"; //static const char MDCartMenuItem7[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsMDCart[] PROGMEM = { MDCartMenuItem1, MDCartMenuItem2, MDCartMenuItem3, MDCartMenuItem4, MDCartMenuItem5, MDCartMenuItem6, MDCartMenuItem7 }; static const char* const menuOptionsMDCart[] PROGMEM = { MDCartMenuItem1, MDCartMenuItem2, MDCartMenuItem3, MDCartMenuItem4, MDCartMenuItem5, MDCartMenuItem6, string_reset2 };
// Sega CD Ram Backup Cartridge menu items // Sega CD Ram Backup Cartridge menu items
static const char SCDMenuItem1[] PROGMEM = "Read Backup RAM"; static const char SCDMenuItem1[] PROGMEM = "Read Backup RAM";
static const char SCDMenuItem2[] PROGMEM = "Write Backup RAM"; static const char SCDMenuItem2[] PROGMEM = "Write Backup RAM";
static const char SCDMenuItem3[] PROGMEM = "Reset"; //static const char SCDMenuItem3[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsSCD[] PROGMEM = { SCDMenuItem1, SCDMenuItem2, SCDMenuItem3 }; static const char* const menuOptionsSCD[] PROGMEM = { SCDMenuItem1, SCDMenuItem2, string_reset2 };
// Sega start menu // Sega start menu
void mdMenu() { void mdMenu() {
@ -254,8 +250,8 @@ void mdMenu() {
idFlash_MD(); idFlash_MD();
resetFlash_MD(); resetFlash_MD();
print_Msg(F("Flash ID: ")); print_Msg(F("Flash ID: "));
println_Msg(flashid); println_Msg(flashid_str);
if (strcmp(flashid, "C2F1") == 0) { if (flashid == 0xC2F1) {
println_Msg(F("MX29F1610 detected")); println_Msg(F("MX29F1610 detected"));
flashSize = 2097152; flashSize = 2097152;
} else { } else {
@ -275,7 +271,8 @@ void mdMenu() {
// Set CS(PH3) HIGH // Set CS(PH3) HIGH
PORTH |= (1 << 3); PORTH |= (1 << 3);
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
break; break;
@ -350,10 +347,10 @@ void mdCartMenu() {
println_Msg(F("Sram verified OK")); println_Msg(F("Sram verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
print_Error(F("Cart has no Sram"), false); print_Error(F("Cart has no Sram"), false);
@ -400,7 +397,8 @@ void mdCartMenu() {
resetArduino(); resetArduino();
break; break;
} }
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -441,7 +439,8 @@ void segaCDMenu() {
break; break;
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -668,6 +667,23 @@ void dataIn_MD() {
/****************************************** /******************************************
MEGA DRIVE functions MEGA DRIVE functions
*****************************************/ *****************************************/
byte copyToRomName_MD(char *output, const byte *input, byte length) {
byte myLength = 0;
for (byte i = 0; i < 48; i++) {
if (
(
(input[i] >= '0' && input[i] <= '9') ||
(input[i] >= 'A' && input[i] <= 'z')
) && myLength < length
) {
output[myLength++] = input[i];
}
}
return myLength;
}
void getCartInfo_MD() { void getCartInfo_MD() {
// Set control // Set control
dataIn_MD(); dataIn_MD();
@ -706,6 +722,7 @@ void getCartInfo_MD() {
// Sonic & Knuckles Check // Sonic & Knuckles Check
SnKmode = 0; SnKmode = 0;
if (chksum == 0xDFB3) { if (chksum == 0xDFB3) {
char id[15];
// Get ID // Get ID
for (byte c = 0; c < 14; c += 2) { for (byte c = 0; c < 14; c += 2) {
@ -715,15 +732,13 @@ void getCartInfo_MD() {
byte hiByte = myWord >> 8; byte hiByte = myWord >> 8;
// write to buffer // write to buffer
sdBuffer[c] = hiByte; id[c] = hiByte;
sdBuffer[c + 1] = loByte; id[c + 1] = loByte;
}
for (int i = 0; i < 14; i++) {
id[i] = char(sdBuffer[i]);
} }
//Sonic & Knuckles ID:GM MK-1563 -00 //Sonic & Knuckles ID:GM MK-1563 -00
if (!strcmp("GM MK-1563 -00", id)) { if (!strcmp("GM MK-1563 -00", id)) {
char labelLockon[17];
// Get labelLockon // Get labelLockon
for (byte c = 0; c < 16; c += 2) { for (byte c = 0; c < 16; c += 2) {
@ -733,15 +748,13 @@ void getCartInfo_MD() {
byte hiByte = myWord >> 8; byte hiByte = myWord >> 8;
// write to buffer // write to buffer
sdBuffer[c] = hiByte; labelLockon[c] = hiByte;
sdBuffer[c + 1] = loByte; labelLockon[c + 1] = loByte;
}
for (int i = 0; i < 16; i++) {
labelLockon[i] = char(sdBuffer[i]);
} }
// check Lock-on game presence // check Lock-on game presence
if (!(strcmp("SEGA MEGA DRIVE ", labelLockon) & strcmp("SEGA GENESIS ", labelLockon))) { if (!(strcmp("SEGA MEGA DRIVE ", labelLockon) & strcmp("SEGA GENESIS ", labelLockon))) {
char idLockon[15];
// Lock-on cart checksum // Lock-on cart checksum
chksumLockon = readWord_MD(0x1000C7); chksumLockon = readWord_MD(0x1000C7);
@ -756,11 +769,8 @@ void getCartInfo_MD() {
byte hiByte = myWord >> 8; byte hiByte = myWord >> 8;
// write to buffer // write to buffer
sdBuffer[c] = hiByte; idLockon[c] = hiByte;
sdBuffer[c + 1] = loByte; idLockon[c + 1] = loByte;
}
for (int i = 0; i < 14; i++) {
idLockon[i] = char(sdBuffer[i]);
} }
if (!(strncmp("GM 00001009-0", idLockon, 13) & strncmp("GM 00004049-0", idLockon, 13))) { if (!(strncmp("GM 00001009-0", idLockon, 13) & strncmp("GM 00004049-0", idLockon, 13))) {
@ -965,16 +975,11 @@ void getCartInfo_MD() {
sdBuffer[c] = hiByte; sdBuffer[c] = hiByte;
sdBuffer[c + 1] = loByte; sdBuffer[c + 1] = loByte;
} }
byte myLength = 0; romName[copyToRomName_MD(romName, sdBuffer, sizeof(romName) - 1)] = 0;
for (unsigned int i = 0; i < 48; i++) {
if (((char(sdBuffer[i]) >= 48 && char(sdBuffer[i]) <= 57) || (char(sdBuffer[i]) >= 65 && char(sdBuffer[i]) <= 122)) && myLength < 15) {
romName[myLength] = char(sdBuffer[i]);
myLength++;
}
}
//Get Lock-on cart name //Get Lock-on cart name
if (SnKmode >= 2) { if (SnKmode >= 2) {
char romNameLockon[12];
//Change romName //Change romName
strcpy(romName, "SnK_"); strcpy(romName, "SnK_");
@ -989,13 +994,7 @@ void getCartInfo_MD() {
sdBuffer[c] = hiByte; sdBuffer[c] = hiByte;
sdBuffer[c + 1] = loByte; sdBuffer[c + 1] = loByte;
} }
byte myLength = 0; romNameLockon[copyToRomName_MD(romNameLockon, sdBuffer, sizeof(romNameLockon) - 1)] = 0;
for (unsigned int i = 0; i < 48; i++) {
if (((char(sdBuffer[i]) >= 48 && char(sdBuffer[i]) <= 57) || (char(sdBuffer[i]) >= 65 && char(sdBuffer[i]) <= 122)) && myLength < 11) {
romNameLockon[myLength] = char(sdBuffer[i]);
myLength++;
}
}
switch (SnKmode) { switch (SnKmode) {
case 2: strcat(romName, "SONIC1"); break; case 2: strcat(romName, "SONIC1"); break;
@ -1082,7 +1081,8 @@ void getCartInfo_MD() {
// Wait for user input // Wait for user input
#if (defined(enable_LCD) || defined(enable_OLED)) #if (defined(enable_LCD) || defined(enable_OLED))
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#endif #endif
@ -1155,7 +1155,7 @@ void readROM_MD() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -1166,16 +1166,16 @@ void readROM_MD() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
byte buffer[1024] = { 0 }; byte buffer[1024] = { 0 };
// get current time // get current time
unsigned long startTime = millis(); // unsigned long startTime = millis();
// Phantasy Star/Beyond Oasis with 74HC74 and 74HC139 switch ROM/SRAM at address 0x200000 // Phantasy Star/Beyond Oasis with 74HC74 and 74HC139 switch ROM/SRAM at address 0x200000
if (0x200000 < cartSize < 0x400000) { if (0x200000 < cartSize && cartSize < 0x400000) {
enableSram_MD(0); enableSram_MD(0);
} }
@ -1489,10 +1489,10 @@ void writeSram_MD() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
dataIn_MD(); dataIn_MD();
} }
@ -1517,7 +1517,7 @@ void readSram_MD() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
for (unsigned long currBuffer = sramBase; currBuffer < sramBase + sramSize; currBuffer += 256) { for (unsigned long currBuffer = sramBase; currBuffer < sramBase + sramSize; currBuffer += 256) {
@ -1557,7 +1557,7 @@ void readSram_MD() {
} }
unsigned long padsize = (1UL << 16) - (sramSize << 1); unsigned long padsize = (1UL << 16) - (sramSize << 1);
unsigned long padblockcount = padsize >> 9; // number of 512 byte blocks unsigned long padblockcount = padsize >> 9; // number of 512 byte blocks
for (int i = 0; i < padblockcount; i++) { for (unsigned long i = 0; i < padblockcount; i++) {
myFile.write(sdBuffer, 512); myFile.write(sdBuffer, 512);
} }
} }
@ -1611,7 +1611,7 @@ unsigned long verifySram_MD() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Return 0 if verified ok, or number of errors // Return 0 if verified ok, or number of errors
return writeErrors; return writeErrors;
@ -1637,7 +1637,7 @@ void resetFlash_MD() {
void write29F1610_MD() { void write29F1610_MD() {
// Create filepath // Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
print_Msg(F("Flashing file ")); print_STR(flashing_file_STR, 0);
print_Msg(filePath); print_Msg(filePath);
println_Msg(F("...")); println_Msg(F("..."));
display_Update(); display_Update();
@ -1647,7 +1647,7 @@ void write29F1610_MD() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) { if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
} }
// Set data pins to output // Set data pins to output
dataOut_MD(); dataOut_MD();
@ -1686,7 +1686,7 @@ void write29F1610_MD() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -1704,7 +1704,9 @@ void idFlash_MD() {
dataIn_MD(); dataIn_MD();
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readFlash_MD(0) & 0xFF, readFlash_MD(1) & 0xFF); flashid = (readFlash_MD(0) & 0xFF) << 8;
flashid |= readFlash_MD(1) & 0xFF;
sprintf(flashid_str, "%04X", flashid);
} }
byte readStatusReg_MD() { byte readStatusReg_MD() {
@ -1764,7 +1766,7 @@ void verifyFlash_MD() {
// Get rom size from file // Get rom size from file
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize > flashSize) { if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), true); print_Error(file_too_big_STR, true);
} }
blank = 0; blank = 0;
@ -1789,15 +1791,15 @@ void verifyFlash_MD() {
println_Msg(F("Flashrom verified OK")); println_Msg(F("Flashrom verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(blank); print_Msg(blank);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
println_Msg(F("Can't open file")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
} }
} }
@ -2382,7 +2384,7 @@ void readEEP_MD() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
if (eepSize > 0x100) { // 24C04+ if (eepSize > 0x100) { // 24C04+
for (word currByte = 0; currByte < eepSize; currByte += 256) { for (word currByte = 0; currByte < eepSize; currByte += 256) {
@ -2448,10 +2450,10 @@ void writeEEP_MD() {
myFile.close(); myFile.close();
println_Msg(F("")); println_Msg(F(""));
display_Clear(); display_Clear();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
dataIn_MD(); dataIn_MD();
} }
@ -2481,7 +2483,7 @@ void readBram_MD() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
for (unsigned long currByte = 0; currByte < bramSize; currByte += 512) { for (unsigned long currByte = 0; currByte < bramSize; currByte += 512) {
@ -2527,10 +2529,10 @@ void writeBram_MD() {
myFile.close(); myFile.close();
println_Msg(F("")); println_Msg(F(""));
display_Clear(); display_Clear();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
dataIn_MD(); dataIn_MD();
} }
@ -2568,7 +2570,7 @@ void readRealtec_MD() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -2579,7 +2581,7 @@ void readRealtec_MD() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Realtec Registers // Realtec Registers

View File

@ -58,30 +58,30 @@ static const char n64MenuItem1[] PROGMEM = "Game Cartridge";
static const char n64MenuItem2[] PROGMEM = "Controller"; static const char n64MenuItem2[] PROGMEM = "Controller";
static const char n64MenuItem3[] PROGMEM = "Flash Repro"; static const char n64MenuItem3[] PROGMEM = "Flash Repro";
static const char n64MenuItem4[] PROGMEM = "Flash Gameshark"; static const char n64MenuItem4[] PROGMEM = "Flash Gameshark";
static const char n64MenuItem5[] PROGMEM = "Reset"; //static const char n64MenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsN64[] PROGMEM = { n64MenuItem1, n64MenuItem2, n64MenuItem3, n64MenuItem4, n64MenuItem5 }; static const char* const menuOptionsN64[] PROGMEM = { n64MenuItem1, n64MenuItem2, n64MenuItem3, n64MenuItem4, string_reset2 };
// N64 controller menu items // N64 controller menu items
static const char N64ContMenuItem1[] PROGMEM = "Test Controller"; static const char N64ContMenuItem1[] PROGMEM = "Test Controller";
static const char N64ContMenuItem2[] PROGMEM = "Read ControllerPak"; static const char N64ContMenuItem2[] PROGMEM = "Read ControllerPak";
static const char N64ContMenuItem3[] PROGMEM = "Write ControllerPak"; static const char N64ContMenuItem3[] PROGMEM = "Write ControllerPak";
static const char N64ContMenuItem4[] PROGMEM = "Reset"; //static const char N64ContMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsN64Controller[] PROGMEM = { N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, N64ContMenuItem4 }; static const char* const menuOptionsN64Controller[] PROGMEM = { N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, string_reset2 };
// N64 cart menu items // N64 cart menu items
static const char N64CartMenuItem1[] PROGMEM = "Read ROM"; static const char N64CartMenuItem1[] PROGMEM = "Read ROM";
static const char N64CartMenuItem2[] PROGMEM = "Read Save"; static const char N64CartMenuItem2[] PROGMEM = "Read Save";
static const char N64CartMenuItem3[] PROGMEM = "Write Save"; static const char N64CartMenuItem3[] PROGMEM = "Write Save";
static const char N64CartMenuItem4[] PROGMEM = "Force Savetype"; static const char N64CartMenuItem4[] PROGMEM = "Force Savetype";
static const char N64CartMenuItem5[] PROGMEM = "Reset"; //static const char N64CartMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsN64Cart[] PROGMEM = { N64CartMenuItem1, N64CartMenuItem2, N64CartMenuItem3, N64CartMenuItem4, N64CartMenuItem5 }; static const char* const menuOptionsN64Cart[] PROGMEM = { N64CartMenuItem1, N64CartMenuItem2, N64CartMenuItem3, N64CartMenuItem4, string_reset2 };
// N64 CRC32 error menu items // N64 CRC32 error menu items
static const char N64CRCMenuItem1[] PROGMEM = "No"; static const char N64CRCMenuItem1[] PROGMEM = "No";
static const char N64CRCMenuItem2[] PROGMEM = "Yes and keep old"; static const char N64CRCMenuItem2[] PROGMEM = "Yes and keep old";
static const char N64CRCMenuItem3[] PROGMEM = "Yes and delete old"; static const char N64CRCMenuItem3[] PROGMEM = "Yes and delete old";
static const char N64CRCMenuItem4[] PROGMEM = "Reset"; //static const char N64CRCMenuItem4[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsN64CRC[] PROGMEM = { N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, N64CRCMenuItem4 }; static const char* const menuOptionsN64CRC[] PROGMEM = { N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, string_reset2 };
// Rom menu // Rom menu
static const char N64RomItem1[] PROGMEM = "4 MB"; static const char N64RomItem1[] PROGMEM = "4 MB";
@ -194,7 +194,8 @@ void n64ControllerMenu() {
verifyCRC(); verifyCRC();
validateMPK(); validateMPK();
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
break; break;
@ -215,7 +216,8 @@ void n64ControllerMenu() {
delay(500); delay(500);
verifyMPK(); verifyMPK();
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
break; break;
@ -266,7 +268,8 @@ void n64CartMenu() {
print_Error(F("Savetype Error"), false); print_Error(F("Savetype Error"), false);
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
break; break;
@ -285,10 +288,10 @@ void n64CartMenu() {
println_Msg(F("SRAM verified OK")); println_Msg(F("SRAM verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else if (saveType == 4) { } else if (saveType == 4) {
// Launch file browser // Launch file browser
@ -296,7 +299,7 @@ void n64CartMenu() {
display_Clear(); display_Clear();
getFramType(); getFramType();
writeFram(flashramType); writeFram(flashramType);
print_Msg(F("Verifying...")); print_STR(verifying_STR, 0);
display_Update(); display_Update();
writeErrors = verifyFram(flashramType); writeErrors = verifyFram(flashramType);
if (writeErrors == 0) { if (writeErrors == 0) {
@ -304,10 +307,10 @@ void n64CartMenu() {
display_Update(); display_Update();
} else { } else {
println_Msg(""); println_Msg("");
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else if ((saveType == 5) || (saveType == 6)) { } else if ((saveType == 5) || (saveType == 6)) {
// Launch file browser // Launch file browser
@ -326,16 +329,17 @@ void n64CartMenu() {
println_Msg(F("EEPROM verified OK")); println_Msg(F("EEPROM verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
display_Clear(); display_Clear();
print_Error(F("Save Type Error"), false); print_Error(F("Save Type Error"), false);
} }
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
break; break;
@ -977,7 +981,6 @@ void controllerTest_Display() {
// Graph // Graph
int xax = 24; // midpoint x int xax = 24; // midpoint x
int yax = 24; // midpoint y int yax = 24; // midpoint y
int zax = 24; // size
// variables to display test data of different sticks // variables to display test data of different sticks
int upx = 0; int upx = 0;
@ -1611,12 +1614,12 @@ void readMPK() {
strcat(filePath, ".crc"); strcat(filePath, ".crc");
FsFile crcFile; FsFile crcFile;
if (!crcFile.open(filePath, O_RDWR | O_CREAT)) { if (!crcFile.open(filePath, O_RDWR | O_CREAT)) {
print_Error(F("Can't open file on SD"), true); print_Error(open_file_STR, true);
} }
//open mpk file on sd card //open mpk 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 open file on SD"), true); print_Error(open_file_STR, true);
} }
print_Msg(F("Saving N64/MPK/")); print_Msg(F("Saving N64/MPK/"));
@ -1669,18 +1672,18 @@ void readMPK() {
void verifyCRC() { void verifyCRC() {
writeErrors = 0; writeErrors = 0;
println_Msg(F("Verifying...")); print_STR(verifying_STR, 1);
display_Update(); display_Update();
//open CRC file on sd card //open CRC file on sd card
FsFile crcFile; FsFile crcFile;
if (!crcFile.open(filePath, O_READ)) { if (!crcFile.open(filePath, O_READ)) {
print_Error(F("Can't open file on SD"), true); print_Error(open_file_STR, true);
} }
//open MPK file on sd card //open MPK file on sd card
if (!myFile.open(fileName, O_READ)) { if (!myFile.open(fileName, O_READ)) {
print_Error(F("Can't open file on SD"), true); print_Error(open_file_STR, true);
} }
//Initialize progress bar //Initialize progress bar
@ -1715,35 +1718,31 @@ void verifyCRC() {
sd.remove(filePath); sd.remove(filePath);
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" blocks ")); println_Msg(F(" blocks "));
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} }
// Calculates the checksum of the header // Calculates the checksum of the header
boolean checkHeader(byte startAddress) { boolean checkHeader(byte *buf) {
word sum = 0; word sum = 0;
word buf_sum = (buf[28] << 8) + buf[29];
// first 28 bytes are the header, then comes the checksum(word) followed by the reverse checksum(0xFFF2 - checksum) // first 28 bytes are the header, then comes the checksum(word) followed by the reverse checksum(0xFFF2 - checksum)
for (int i = 0; i < 28; i += 2) { for (byte i = 0; i < 28; i += 2) {
word tempword = (((sdBuffer[startAddress + i] & 0xFF) << 8) | (sdBuffer[startAddress + i + 1] & 0xFF)); sum += (buf[i] << 8) + buf[i + 1];
sum += tempword;
} }
if ((((sdBuffer[startAddress + 28] & 0xFF) << 8) | (sdBuffer[startAddress + 29] & 0xFF)) != (sum & 0xFFFF)) { return sum == buf_sum;
return 0;
} else {
return 1;
}
} }
// verifies if Controller Pak holds valid header data // verifies if Controller Pak holds valid header data
void validateMPK() { void validateMPK() {
//open file on sd card //open file on sd card
if (!myFile.open(fileName, O_READ)) { if (!myFile.open(fileName, O_READ)) {
print_Error(F("Can't open file"), true); print_Error(open_file_STR, true);
} }
// Read first 256 byte which contains the header including checksum and reverse checksum and three copies of it // Read first 256 byte which contains the header including checksum and reverse checksum and three copies of it
@ -1751,13 +1750,13 @@ void validateMPK() {
//Check all four header copies //Check all four header copies
writeErrors = 0; writeErrors = 0;
if (!checkHeader(0x20)) if (!checkHeader(&sdBuffer[0x20]))
writeErrors++; writeErrors++;
if (!checkHeader(0x60)) if (!checkHeader(&sdBuffer[0x60]))
writeErrors++; writeErrors++;
if (!checkHeader(0x80)) if (!checkHeader(&sdBuffer[0x80]))
writeErrors++; writeErrors++;
if (!checkHeader(0xC0)) if (!checkHeader(&sdBuffer[0xC0]))
writeErrors++; writeErrors++;
print_Msg(F("HDR: ")); print_Msg(F("HDR: "));
@ -1856,7 +1855,7 @@ void writeMPK() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
print_Error(F("Can't open file on SD"), true); print_Error(open_file_STR, true);
} }
} }
@ -1864,12 +1863,12 @@ void writeMPK() {
void verifyMPK() { void verifyMPK() {
writeErrors = 0; writeErrors = 0;
println_Msg(F("Verifying...")); print_STR(verifying_STR, 1);
display_Update(); display_Update();
//open file on sd card //open file on sd card
if (!myFile.open(filePath, O_READ)) { if (!myFile.open(filePath, O_READ)) {
print_Error(F("Can't open file on SD"), true); print_Error(open_file_STR, true);
} }
//Initialize progress bar //Initialize progress bar
@ -1911,10 +1910,10 @@ void verifyMPK() {
println_Msg(F("Written successfully")); println_Msg(F("Written successfully"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} }
@ -1963,7 +1962,8 @@ void printCartInfo_N64() {
// Wait for user input // Wait for user input
println_Msg(F(" ")); println_Msg(F(" "));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} else { } else {
@ -1982,7 +1982,8 @@ void printCartInfo_N64() {
strcpy(romName, "GPERROR"); strcpy(romName, "GPERROR");
print_Error(F("Cartridge unknown"), false); print_Error(F("Cartridge unknown"), false);
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -2027,15 +2028,6 @@ void printCartInfo_N64() {
} }
} }
// improved strcmp function that ignores case to prevent checksum comparison issues
int strcicmp(char const* a, char const* b) {
for (;; a++, b++) {
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b);
if (d != 0 || !*a)
return d;
}
}
/* look-up the calculated crc in the file n64.txt on sd card /* look-up the calculated crc in the file n64.txt on sd card
boolean searchCRC(char crcStr[9]) { boolean searchCRC(char crcStr[9]) {
boolean result = 0; boolean result = 0;
@ -2057,9 +2049,9 @@ int strcicmp(char const* a, char const* b) {
} }
// Check if string is a match // Check if string is a match
if (strcicmp(tempStr1, crcStr) == 0) { if (strcasecmp(tempStr1, crcStr) == 0) {
// Skip the , in the file // Skip the , in the file
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read 4 bytes into String, do it one at a time so byte order doesn't get mixed up // Read 4 bytes into String, do it one at a time so byte order doesn't get mixed up
sprintf(tempStr, "%c", myFile.read()); sprintf(tempStr, "%c", myFile.read());
@ -2079,7 +2071,7 @@ int strcicmp(char const* a, char const* b) {
} }
// If no match, empty string, advance by 12 and try again // If no match, empty string, advance by 12 and try again
else { else {
myFile.seekSet(myFile.curPosition() + 12); myFile.seekCur(12);
} }
} }
// Close the file: // Close the file:
@ -2114,7 +2106,7 @@ void getCartInfo_N64() {
skip_line(&myFile); skip_line(&myFile);
// Skip over the CRC32 checksum // Skip over the CRC32 checksum
myFile.seekSet(myFile.curPosition() + 9); myFile.seekCur(9);
// Read 8 bytes into String, do it one at a time so byte order doesn't get mixed up // Read 8 bytes into String, do it one at a time so byte order doesn't get mixed up
sprintf(tempStr, "%c", myFile.read()); sprintf(tempStr, "%c", myFile.read());
@ -2126,7 +2118,7 @@ void getCartInfo_N64() {
// Check if string is a match // Check if string is a match
if (strcmp(tempStr, checksumStr) == 0) { if (strcmp(tempStr, checksumStr) == 0) {
// Skip the , in the file // Skip the , in the file
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read the next ascii character and subtract 48 to convert to decimal // Read the next ascii character and subtract 48 to convert to decimal
cartSize = myFile.read() - 48; cartSize = myFile.read() - 48;
@ -2138,7 +2130,7 @@ void getCartInfo_N64() {
} }
// Skip the , in the file // Skip the , in the file
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read the next ascii character and subtract 48 to convert to decimal // Read the next ascii character and subtract 48 to convert to decimal
saveType = myFile.read() - 48; saveType = myFile.read() - 48;
@ -2149,7 +2141,7 @@ void getCartInfo_N64() {
// If no match skip to next entry // If no match skip to next entry
else { else {
// skip rest of line // skip rest of line
myFile.seekSet(myFile.curPosition() + 7); myFile.seekCur(7);
// skip third empty line // skip third empty line
skip_line(&myFile); skip_line(&myFile);
} }
@ -2189,33 +2181,9 @@ void idCart() {
// Get rom version // Get rom version
romVersion = sdBuffer[0x3F]; romVersion = sdBuffer[0x3F];
// Get name
byte myByte = 0;
byte myLength = 0;
for (unsigned int i = 0; i < 20; i++) {
myByte = sdBuffer[0x20 + i];
if (isprint(myByte) && myByte != '<' && myByte != '>' && myByte != ':' && myByte != '"' && myByte != '/' && myByte != '\\' && myByte != '|' && myByte != '?' && myByte != '*') {
romName[myLength] = char(myByte);
} else {
if (romName[myLength - 1] == 0x5F) myLength--;
romName[myLength] = 0x5F;
}
myLength++;
}
// Strip trailing white space
for (unsigned int i = myLength - 1; i > 0; i--) {
if ((romName[i] != 0x5F) && (romName[i] != 0x20)) break;
romName[i] = 0x00;
myLength--;
}
// If name consists out of all japanese characters use cart id // If name consists out of all japanese characters use cart id
if (myLength == 0) { if (buildRomName(romName, &sdBuffer[0x20], 20) == 0) {
romName[0] = sdBuffer[0x3B]; strcpy(romName, cartID);
romName[1] = sdBuffer[0x3C];
romName[2] = sdBuffer[0x3D];
romName[3] = sdBuffer[0x3E];
} }
#ifdef savesummarytotxt #ifdef savesummarytotxt
@ -2344,11 +2312,11 @@ void writeEeprom_CLK() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
delay(600); delay(600);
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
} else { } else {
print_Error(F("Savetype Error"), true); print_Error(F("Savetype Error"), true);
@ -2378,7 +2346,7 @@ void readEeprom_CLK() {
// 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(create_file_STR, true);
} }
for (byte i = 0; i < (eepPages / 64); i++) { for (byte i = 0; i < (eepPages / 64); i++) {
@ -2481,12 +2449,13 @@ unsigned long verifyEeprom_CLK() {
} else { } else {
// SD Error // SD Error
writeErrors = 999999; writeErrors = 999999;
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Return 0 if verified ok, or number of errors // Return 0 if verified ok, or number of errors
return writeErrors; return writeErrors;
} else { } else {
print_Error(F("Savetype Error"), true); print_Error(F("Savetype Error"), true);
return 1;
} }
} }
@ -2713,11 +2682,11 @@ void writeEeprom() {
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
delay(600); delay(600);
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
} else { } else {
print_Error(F("Savetype Error"), true); print_Error(F("Savetype Error"), true);
@ -2743,7 +2712,7 @@ void readEeprom() {
// 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(create_file_STR, true);
} }
for (byte i = 0; i < (eepPages / 64); i++) { for (byte i = 0; i < (eepPages / 64); i++) {
@ -2847,12 +2816,13 @@ unsigned long verifyEeprom() {
} else { } else {
// SD Error // SD Error
writeErrors = 999999; writeErrors = 999999;
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Return 0 if verified ok, or number of errors // Return 0 if verified ok, or number of errors
return writeErrors; return writeErrors;
} else { } else {
print_Error(F("Savetype Error"), true); print_Error(F("Savetype Error"), true);
return 1;
} }
} }
@ -2888,10 +2858,10 @@ void writeSram(unsigned long sramSize) {
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
} else { } else {
@ -2931,7 +2901,7 @@ void readSram(unsigned long sramSize, byte flashramType) {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
for (unsigned long currByte = sramBase; currByte < (sramBase + (sramSize / flashramType)); currByte += offset) { for (unsigned long currByte = sramBase; currByte < (sramBase + (sramSize / flashramType)); currByte += offset) {
@ -2994,7 +2964,7 @@ unsigned long verifySram(unsigned long sramSize, byte flashramType) {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Return 0 if verified ok, or number of errors // Return 0 if verified ok, or number of errors
return writeErrors; return writeErrors;
@ -3100,7 +3070,7 @@ void writeFram(byte flashramType) {
// Close the file: // Close the file:
myFile.close(); myFile.close();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
} else { } else {
print_Error(F("Savetype Error"), true); print_Error(F("Savetype Error"), true);
@ -3327,7 +3297,7 @@ redumpnewfolder:
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -3339,7 +3309,7 @@ redumpnewfolder:
redumpsamefolder: redumpsamefolder:
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
// dumping rom slow // dumping rom slow
@ -3385,8 +3355,6 @@ redumpsamefolder:
// prepare crc32 // prepare crc32
uint32_t oldcrc32 = 0xFFFFFFFF; uint32_t oldcrc32 = 0xFFFFFFFF;
uint32_t tab_value = 0;
uint8_t idx = 0;
// run combined dumper + crc32 routine for better performance, as N64 ROMs are quite large for an 8bit micro // run combined dumper + crc32 routine for better performance, as N64 ROMs are quite large for an 8bit micro
// currently dumps + checksums a 32MB cart in 170 seconds (down from 347 seconds) // currently dumps + checksums a 32MB cart in 170 seconds (down from 347 seconds)
@ -3418,12 +3386,8 @@ redumpsamefolder:
PORTH |= (1 << 6); PORTH |= (1 << 6);
// crc32 update // crc32 update
idx = ((oldcrc32) ^ (buffer[c])); UPDATE_CRC(oldcrc32, buffer[c]);
tab_value = pgm_read_dword(crc_32_tab + idx); UPDATE_CRC(oldcrc32, buffer[c + 1]);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
idx = ((oldcrc32) ^ (buffer[c + 1]));
tab_value = pgm_read_dword(crc_32_tab + idx);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
} }
// Set the address for the next 512 bytes to dump // Set the address for the next 512 bytes to dump
@ -3449,12 +3413,8 @@ redumpsamefolder:
PORTH |= (1 << 6); PORTH |= (1 << 6);
// crc32 update // crc32 update
idx = ((oldcrc32) ^ (buffer[c])) & 0xff; UPDATE_CRC(oldcrc32, buffer[c]);
tab_value = pgm_read_dword(crc_32_tab + idx); UPDATE_CRC(oldcrc32, buffer[c + 1]);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
idx = ((oldcrc32) ^ (buffer[c + 1])) & 0xff;
tab_value = pgm_read_dword(crc_32_tab + idx);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
} }
processedProgressBar += 1024; processedProgressBar += 1024;
@ -3478,7 +3438,8 @@ redumpsamefolder:
print_Msg(timeElapsed); // include elapsed time print_Msg(timeElapsed); // include elapsed time
println_Msg(F("s)")); println_Msg(F("s)"));
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
// This saves a tt file with rom info next to the dumped rom // This saves a tt file with rom info next to the dumped rom
#ifdef savesummarytotxt #ifdef savesummarytotxt
@ -3493,7 +3454,8 @@ redumpsamefolder:
errorLvl = 1; errorLvl = 1;
setColor_RGB(255, 0, 0); setColor_RGB(255, 0, 0);
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
// This saves a tt file with rom info next to the dumped rom // This saves a tt file with rom info next to the dumped rom
#ifdef savesummarytotxt #ifdef savesummarytotxt
@ -3528,7 +3490,7 @@ redumpsamefolder:
sd.chdir(folder); sd.chdir(folder);
// Delete old file // Delete old file
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
if (!myFile.remove()) { if (!myFile.remove()) {
print_Error(F("Delete Error"), true); print_Error(F("Delete Error"), true);
@ -3554,7 +3516,7 @@ redumpsamefolder:
void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElapsed) { void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElapsed) {
// Open file on sd card // Open file on sd card
if (!myFile.open("N64/ROM/n64log.txt", O_RDWR | O_CREAT | O_APPEND)) { if (!myFile.open("N64/ROM/n64log.txt", O_RDWR | O_CREAT | O_APPEND)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
//Write the info //Write the info
@ -3631,42 +3593,42 @@ void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElaps
N64 Repro Flashrom Functions N64 Repro Flashrom Functions
*****************************************/ *****************************************/
void flashRepro_N64() { void flashRepro_N64() {
unsigned long sectorSize; unsigned long sectorSize = 0;
byte bufferSize; byte bufferSize = 0;
// Check flashrom ID's // Check flashrom ID's
idFlashrom_N64(); idFlashrom_N64();
// If the ID is known continue // If the ID is known continue
if (cartSize != 0) { if (cartSize != 0) {
// Print flashrom name // Print flashrom name
if ((strcmp(flashid, "227E") == 0) && (strcmp(cartID, "2201") == 0)) { if ((flashid == 0x227E) && (strcmp(cartID, "2201") == 0)) {
print_Msg(F("Spansion S29GL256N")); print_Msg(F("Spansion S29GL256N"));
if (cartSize == 64) if (cartSize == 64)
println_Msg(F(" x2")); println_Msg(F(" x2"));
else else
println_Msg(""); println_Msg("");
} else if ((strcmp(flashid, "227E") == 0) && (strcmp(cartID, "2101") == 0)) { } else if ((flashid == 0x227E) && (strcmp(cartID, "2101") == 0)) {
print_Msg(F("Spansion S29GL128N")); print_Msg(F("Spansion S29GL128N"));
} else if ((strcmp(flashid, "227E") == 0) && (strcmp(cartID, "2100") == 0)) { } else if ((flashid == 0x227E) && (strcmp(cartID, "2100") == 0)) {
print_Msg(F("ST M29W128GL")); print_Msg(F("ST M29W128GL"));
} else if ((strcmp(flashid, "22C9") == 0) || (strcmp(flashid, "22CB") == 0)) { } else if ((flashid == 0x22C9) || (flashid == 0x22CB)) {
print_Msg(F("Macronix MX29LV640")); print_Msg(F("Macronix MX29LV640"));
if (cartSize == 16) if (cartSize == 16)
println_Msg(F(" x2")); println_Msg(F(" x2"));
else else
println_Msg(""); println_Msg("");
} else if (strcmp(flashid, "8816") == 0) } else if (flashid == 0x8816)
println_Msg(F("Intel 4400L0ZDQ0")); println_Msg(F("Intel 4400L0ZDQ0"));
else if (strcmp(flashid, "7E7E") == 0) else if (flashid == 0x7E7E)
println_Msg(F("Fujitsu MSP55LV100S")); println_Msg(F("Fujitsu MSP55LV100S"));
else if ((strcmp(flashid, "227E") == 0) && (strcmp(cartID, "2301") == 0)) else if ((flashid == 0x227E) && (strcmp(cartID, "2301") == 0))
println_Msg(F("Fujitsu MSP55LV512")); println_Msg(F("Fujitsu MSP55LV512"));
else if ((strcmp(flashid, "227E") == 0) && (strcmp(cartID, "3901") == 0)) else if ((flashid == 0x227E) && (strcmp(cartID, "3901") == 0))
println_Msg(F("Intel 512M29EW")); println_Msg(F("Intel 512M29EW"));
// Print info // Print info
print_Msg(F("ID: ")); print_Msg(F("ID: "));
print_Msg(flashid); print_Msg(flashid_str);
print_Msg(F(" Size: ")); print_Msg(F(" Size: "));
print_Msg(cartSize); print_Msg(cartSize);
println_Msg(F("MB")); println_Msg(F("MB"));
@ -3675,7 +3637,8 @@ void flashRepro_N64() {
println_Msg(F("Repro Cartridge.")); println_Msg(F("Repro Cartridge."));
println_Msg(F("Attention: Use 3.3V!")); println_Msg(F("Attention: Use 3.3V!"));
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} else { } else {
@ -3683,7 +3646,7 @@ void flashRepro_N64() {
print_Msg(F("ID: ")); print_Msg(F("ID: "));
print_Msg(vendorID); print_Msg(vendorID);
print_Msg(F(" ")); print_Msg(F(" "));
print_Msg(flashid); print_Msg(flashid_str);
print_Msg(F(" ")); print_Msg(F(" "));
println_Msg(cartID); println_Msg(cartID);
println_Msg(F(" ")); println_Msg(F(" "));
@ -3697,7 +3660,8 @@ void flashRepro_N64() {
// clear IDs // clear IDs
sprintf(vendorID, "%s", "CONF"); sprintf(vendorID, "%s", "CONF");
sprintf(flashid, "%s", "CONF"); flashid = 0;
sprintf(flashid_str, "%s", "CONF");
sprintf(cartID, "%s", "CONF"); sprintf(cartID, "%s", "CONF");
@ -3821,21 +3785,21 @@ void flashRepro_N64() {
// Compare file size to flashrom size // Compare file size to flashrom size
if ((fileSize / 1048576) > cartSize) { if ((fileSize / 1048576) > cartSize) {
print_Error(F("File too big"), true); print_Error(file_too_big_STR, true);
} }
// Erase needed sectors // Erase needed sectors
if (strcmp(flashid, "227E") == 0) { if (flashid == 0x227E) {
// Spansion S29GL256N or Fujitsu MSP55LV512 with 0x20000 sector size and 32 byte buffer // Spansion S29GL256N or Fujitsu MSP55LV512 with 0x20000 sector size and 32 byte buffer
eraseSector_N64(0x20000); eraseSector_N64(0x20000);
} else if (strcmp(flashid, "7E7E") == 0) { } else if (flashid == 0x7E7E) {
// Fujitsu MSP55LV100S // Fujitsu MSP55LV100S
eraseMSP55LV100_N64(); eraseMSP55LV100_N64();
} else if ((strcmp(flashid, "8813") == 0) || (strcmp(flashid, "8816") == 0)) { } else if ((flashid == 0x8813) || (flashid == 0x8816)) {
// Intel 4400L0ZDQ0 // Intel 4400L0ZDQ0
eraseIntel4400_N64(); eraseIntel4400_N64();
resetIntel4400_N64(); resetIntel4400_N64();
} else if ((strcmp(flashid, "22C9") == 0) || (strcmp(flashid, "22CB") == 0)) { } else if ((flashid == 0x22C9) || (flashid == 0x22CB)) {
// Macronix MX29LV640, C9 is top boot and CB is bottom boot block // Macronix MX29LV640, C9 is top boot and CB is bottom boot block
eraseSector_N64(0x8000); eraseSector_N64(0x8000);
} else { } else {
@ -3850,36 +3814,40 @@ void flashRepro_N64() {
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
if ((strcmp(cartID, "3901") == 0) && (strcmp(flashid, "227E") == 0)) { if ((strcmp(cartID, "3901") == 0) && (flashid == 0x227E)) {
// Intel 512M29EW(64MB) with 0x20000 sector size and 128 byte buffer // Intel 512M29EW(64MB) with 0x20000 sector size and 128 byte buffer
writeFlashBuffer_N64(0x20000, 128); writeFlashBuffer_N64(0x20000, 128);
} else if ((strcmp(cartID, "2100") == 0) && (strcmp(flashid, "227E") == 0)) { } else if ((strcmp(cartID, "2100") == 0) && (flashid == 0x227E)) {
// ST M29W128GH(16MB) with 0x20000 sector size and 64 byte buffer // ST M29W128GH(16MB) with 0x20000 sector size and 64 byte buffer
writeFlashBuffer_N64(0x20000, 64); writeFlashBuffer_N64(0x20000, 64);
} else if (strcmp(flashid, "227E") == 0) { } else if (flashid == 0x227E) {
// Spansion S29GL128N/S29GL256N or Fujitsu MSP55LV512 with 0x20000 sector size and 32 byte buffer // Spansion S29GL128N/S29GL256N or Fujitsu MSP55LV512 with 0x20000 sector size and 32 byte buffer
writeFlashBuffer_N64(0x20000, 32); writeFlashBuffer_N64(0x20000, 32);
} else if (strcmp(flashid, "7E7E") == 0) { } else if (flashid == 0x7E7E) {
//Fujitsu MSP55LV100S //Fujitsu MSP55LV100S
writeMSP55LV100_N64(0x20000); writeMSP55LV100_N64(0x20000);
} else if ((strcmp(flashid, "22C9") == 0) || (strcmp(flashid, "22CB") == 0)) { } else if ((flashid == 0x22C9) || (flashid == 0x22CB)) {
// Macronix MX29LV640 without buffer and 0x8000 sector size // Macronix MX29LV640 without buffer and 0x8000 sector size
writeFlashrom_N64(0x8000); writeFlashrom_N64(0x8000);
} else if ((strcmp(flashid, "8813") == 0) || (strcmp(flashid, "8816") == 0)) { } else if ((flashid == 0x8813) || (flashid == 0x8816)) {
// Intel 4400L0ZDQ0 // Intel 4400L0ZDQ0
writeIntel4400_N64(); writeIntel4400_N64();
resetIntel4400_N64(); resetIntel4400_N64();
} else if (bufferSize == 0) { } else if (sectorSize) {
writeFlashrom_N64(sectorSize); if (bufferSize) {
} else {
writeFlashBuffer_N64(sectorSize, bufferSize); writeFlashBuffer_N64(sectorSize, bufferSize);
} else {
writeFlashrom_N64(sectorSize);
}
} else {
print_Error(F("sectorSize not set"), true);
} }
// Close the file: // Close the file:
myFile.close(); myFile.close();
// Verify // Verify
print_Msg(F("Verifying...")); print_STR(verifying_STR, 0);
display_Update(); display_Update();
writeErrors = verifyFlashrom_N64(); writeErrors = verifyFlashrom_N64();
if (writeErrors == 0) { if (writeErrors == 0) {
@ -3888,7 +3856,7 @@ void flashRepro_N64() {
} else { } else {
print_Msg(writeErrors); print_Msg(writeErrors);
print_Msg(F(" bytes ")); print_Msg(F(" bytes "));
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
// Close the file // Close the file
@ -3899,7 +3867,8 @@ void flashRepro_N64() {
print_Error(F("Can't open file"), false); print_Error(F("Can't open file"), false);
} }
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
display_Clear(); display_Clear();
@ -3946,13 +3915,14 @@ void idFlashrom_N64() {
setAddress_N64(romBase); setAddress_N64(romBase);
sprintf(vendorID, "%02X", readWord_N64()); sprintf(vendorID, "%02X", readWord_N64());
// Read 2 bytes flashrom ID // Read 2 bytes flashrom ID
sprintf(flashid, "%04X", readWord_N64()); flashid = readWord_N64();
sprintf(flashid_str, "%04X", flashid);
// Read 2 bytes secondary flashrom ID // Read 2 bytes secondary flashrom ID
setAddress_N64(romBase + 0x1C); setAddress_N64(romBase + 0x1C);
sprintf(cartID, "%04X", ((readWord_N64() << 8) | (readWord_N64() & 0xFF))); sprintf(cartID, "%04X", ((readWord_N64() << 8) | (readWord_N64() & 0xFF)));
// Spansion S29GL256N(32MB/64MB) with either one or two flashrom chips // Spansion S29GL256N(32MB/64MB) with either one or two flashrom chips
if ((strcmp(cartID, "2201") == 0) && (strcmp(flashid, "227E") == 0)) { if ((strcmp(cartID, "2201") == 0) && (flashid == 0x227E)) {
cartSize = 32; cartSize = 32;
// Reset flashrom // Reset flashrom
@ -3981,7 +3951,7 @@ void idFlashrom_N64() {
} }
// Macronix MX29LV640(8MB/16MB) with either one or two flashrom chips // Macronix MX29LV640(8MB/16MB) with either one or two flashrom chips
else if ((strcmp(flashid, "22C9") == 0) || (strcmp(flashid, "22CB") == 0)) { else if ((flashid == 0x22C9) || (flashid == 0x22CB)) {
cartSize = 8; cartSize = 8;
resetFlashrom_N64(romBase + 0x800000); resetFlashrom_N64(romBase + 0x800000);
@ -4009,7 +3979,7 @@ void idFlashrom_N64() {
} }
// Intel 4400L0ZDQ0 (64MB) // Intel 4400L0ZDQ0 (64MB)
else if (strcmp(flashid, "8816") == 0) { else if (flashid == 0x8816) {
// Found first flashrom chip, set to 32MB // Found first flashrom chip, set to 32MB
cartSize = 32; cartSize = 32;
resetIntel4400_N64(); resetIntel4400_N64();
@ -4029,7 +3999,8 @@ void idFlashrom_N64() {
sprintf(cartID, "%04X", readWord_N64()); sprintf(cartID, "%04X", readWord_N64());
if (strcmp(cartID, "8813") == 0) { if (strcmp(cartID, "8813") == 0) {
cartSize = 64; cartSize = 64;
strncpy(flashid, cartID, 5); flashid = 0x8813;
strncpy(flashid_str, cartID, 5);
} }
resetIntel4400_N64(); resetIntel4400_N64();
// Empty cartID string // Empty cartID string
@ -4037,35 +4008,35 @@ void idFlashrom_N64() {
} }
//Fujitsu MSP55LV512/Spansion S29GL512N (64MB) //Fujitsu MSP55LV512/Spansion S29GL512N (64MB)
else if ((strcmp(cartID, "2301") == 0) && (strcmp(flashid, "227E") == 0)) { else if ((strcmp(cartID, "2301") == 0) && (flashid == 0x227E)) {
cartSize = 64; cartSize = 64;
// Reset flashrom // Reset flashrom
resetFlashrom_N64(romBase); resetFlashrom_N64(romBase);
} }
// Spansion S29GL128N(16MB) with one flashrom chip // Spansion S29GL128N(16MB) with one flashrom chip
else if ((strcmp(cartID, "2101") == 0) && (strcmp(flashid, "227E") == 0)) { else if ((strcmp(cartID, "2101") == 0) && (flashid == 0x227E)) {
cartSize = 16; cartSize = 16;
// Reset flashrom // Reset flashrom
resetFlashrom_N64(romBase); resetFlashrom_N64(romBase);
} }
// ST M29W128GL(16MB) with one flashrom chip // ST M29W128GL(16MB) with one flashrom chip
else if ((strcmp(cartID, "2100") == 0) && (strcmp(flashid, "227E") == 0)) { else if ((strcmp(cartID, "2100") == 0) && (flashid == 0x227E)) {
cartSize = 16; cartSize = 16;
// Reset flashrom // Reset flashrom
resetFlashrom_N64(romBase); resetFlashrom_N64(romBase);
} }
// Intel 512M29EW(64MB) with one flashrom chip // Intel 512M29EW(64MB) with one flashrom chip
else if ((strcmp(cartID, "3901") == 0) && (strcmp(flashid, "227E") == 0)) { else if ((strcmp(cartID, "3901") == 0) && (flashid == 0x227E)) {
cartSize = 64; cartSize = 64;
// Reset flashrom // Reset flashrom
resetFlashrom_N64(romBase); resetFlashrom_N64(romBase);
} }
// Unknown 227E type // Unknown 227E type
else if (strcmp(flashid, "227E") == 0) { else if (flashid == 0x227E) {
cartSize = 0; cartSize = 0;
// Reset flashrom // Reset flashrom
resetFlashrom_N64(romBase); resetFlashrom_N64(romBase);
@ -4090,10 +4061,11 @@ void idFlashrom_N64() {
if (strcmp(cartID, "7E7E") == 0) { if (strcmp(cartID, "7E7E") == 0) {
resetMSP55LV100_N64(romBase); resetMSP55LV100_N64(romBase);
cartSize = 64; cartSize = 64;
strncpy(flashid, cartID, 5); flashid = 0x7E7E;
strncpy(flashid_str, cartID, 5);
} }
} }
if ((strcmp(flashid, "1240") == 0) && (strcmp(cartID, "1240") == 0)) { if ((flashid == 0x1240) && (strcmp(cartID, "1240") == 0)) {
print_Error(F("Please reseat cartridge"), true); print_Error(F("Please reseat cartridge"), true);
} }
} }
@ -4298,12 +4270,12 @@ void eraseSector_N64(unsigned long sectorSize) {
blinkLED(); blinkLED();
// Spansion S29GL256N(32MB/64MB) with two flashrom chips // Spansion S29GL256N(32MB/64MB) with two flashrom chips
if ((currSector == 0x2000000) && (strcmp(cartID, "2201") == 0) && (strcmp(flashid, "227E") == 0)) { if ((currSector == 0x2000000) && (strcmp(cartID, "2201") == 0) && (flashid == 0x227E)) {
// Change to second chip // Change to second chip
flashBase = romBase + 0x2000000; flashBase = romBase + 0x2000000;
} }
// Macronix MX29LV640(8MB/16MB) with two flashrom chips // Macronix MX29LV640(8MB/16MB) with two flashrom chips
else if ((currSector == 0x800000) && ((strcmp(flashid, "22C9") == 0) || (strcmp(flashid, "22CB") == 0))) { else if ((currSector == 0x800000) && ((flashid == 0x22C9) || (flashid == 0x22CB))) {
flashBase = romBase + 0x800000; flashBase = romBase + 0x800000;
} }
@ -4493,7 +4465,7 @@ void writeFlashBuffer_N64(unsigned long sectorSize, byte bufferSize) {
writeWord_N64((bufferSize / 2) - 1); writeWord_N64((bufferSize / 2) - 1);
// Define variable before loop so we can use it later when reading the status register // Define variable before loop so we can use it later when reading the status register
word currWord; word currWord = 0;
for (byte currByte = 0; currByte < bufferSize; currByte += 2) { for (byte currByte = 0; currByte < bufferSize; currByte += 2) {
// Join two bytes into one word // Join two bytes into one word
@ -4598,7 +4570,7 @@ unsigned long verifyFlashrom_N64() {
myFile.close(); myFile.close();
return writeErrors; return writeErrors;
} else { } else {
println_Msg(F("Can't open file")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
return 9999; return 9999;
} }
@ -4620,14 +4592,15 @@ void flashGameshark_N64() {
// !!!! SST 29EE010 may have a 5V requirement for writing however dumping works at 3V. As such it is not !!!! // !!!! SST 29EE010 may have a 5V requirement for writing however dumping works at 3V. As such it is not !!!!
// !!!! advised to write to a cart with this chip until further testing can be completed. !!!! // !!!! advised to write to a cart with this chip until further testing can be completed. !!!!
if (strcmp(flashid, "0808") == 0 || strcmp(flashid, "0404") == 0 || strcmp(flashid, "3535") == 0 || strcmp(flashid, "0707") == 0) { if (flashid == 0x0808 || flashid == 0x0404 || flashid == 0x3535 || flashid == 0x0707) {
backupGameshark_N64(); backupGameshark_N64();
println_Msg(""); println_Msg("");
println_Msg(F("This will erase your")); println_Msg(F("This will erase your"));
println_Msg(F("Gameshark cartridge")); println_Msg(F("Gameshark cartridge"));
println_Msg(F("Attention: Use 3.3V!")); println_Msg(F("Attention: Use 3.3V!"));
println_Msg(F("Power OFF if Unsure!")); println_Msg(F("Power OFF if Unsure!"));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -4652,7 +4625,7 @@ void flashGameshark_N64() {
// Compare file size to flashrom size // Compare file size to flashrom size
if (fileSize > 262144) { if (fileSize > 262144) {
print_Error(F("File too big"), true); print_Error(file_too_big_STR, true);
} }
// SST 29LE010, chip erase not needed as this eeprom automaticly erases during the write cycle // SST 29LE010, chip erase not needed as this eeprom automaticly erases during the write cycle
@ -4668,7 +4641,7 @@ void flashGameshark_N64() {
myFile.close(); myFile.close();
// Verify // Verify
print_Msg(F("Verifying...")); print_STR(verifying_STR, 0);
display_Update(); display_Update();
writeErrors = verifyGameshark_N64(); writeErrors = verifyGameshark_N64();
@ -4682,7 +4655,7 @@ void flashGameshark_N64() {
} else { } else {
print_Msg(writeErrors); print_Msg(writeErrors);
print_Msg(F(" bytes ")); print_Msg(F(" bytes "));
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
print_Error(F("Can't open file"), false); print_Error(F("Can't open file"), false);
@ -4691,11 +4664,12 @@ void flashGameshark_N64() {
// If the ID is unknown show error message // If the ID is unknown show error message
else { else {
print_Msg(F("ID: ")); print_Msg(F("ID: "));
println_Msg(flashid); println_Msg(flashid_str);
print_Error(F("Unknown flashrom"), false); print_Error(F("Unknown flashrom"), false);
} }
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
display_Clear(); display_Clear();
@ -4717,7 +4691,8 @@ void idGameshark_N64() {
// Read 1 byte vendor ID // Read 1 byte vendor ID
readWord_N64(); readWord_N64();
// Read 2 bytes flashrom ID // Read 2 bytes flashrom ID
sprintf(flashid, "%04X", readWord_N64()); flashid = readWord_N64();
sprintf(flashid_str, "%04X", flashid);
// Reset flashrom // Reset flashrom
resetGameshark_N64(); resetGameshark_N64();
} }
@ -4755,7 +4730,7 @@ void backupGameshark_N64() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
for (unsigned long currByte = romBase + 0xC00000; currByte < (romBase + 0xC00000 + 262144); currByte += 512) { for (unsigned long currByte = romBase + 0xC00000; currByte < (romBase + 0xC00000 + 262144); currByte += 512) {
@ -4852,7 +4827,7 @@ unsigned long verifyGameshark_N64() {
setAddress_N64(romBase + 0xC00000 + currSector + currSdBuffer + currByte); setAddress_N64(romBase + 0xC00000 + currSector + currSdBuffer + currByte);
// Compare both // Compare both
if (readWord_N64() != currWord) { if (readWord_N64() != currWord) {
if ((strcmp(flashid, "0808") == 0) && (currSector + currSdBuffer + currByte > 0x3F) && (currSector + currSdBuffer + currByte < 0x1080)) { if ((flashid == 0x0808) && (currSector + currSdBuffer + currByte > 0x3F) && (currSector + currSdBuffer + currByte < 0x1080)) {
// Gameshark maps this area to the bootcode of the plugged in cartridge // Gameshark maps this area to the bootcode of the plugged in cartridge
} else { } else {
writeErrors++; writeErrors++;
@ -4865,7 +4840,7 @@ unsigned long verifyGameshark_N64() {
myFile.close(); myFile.close();
return writeErrors; return writeErrors;
} else { } else {
println_Msg(F("Can't open file")); print_STR(open_file_STR, 1);
display_Update(); display_Update();
return 9999; return 9999;
} }

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@
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"; (stored in common strings array)
static const char* const menuOptionsNGP[] PROGMEM = { ngpMenuItem1, ngpMenuItem2, ngpMenuItemReset }; static const char* const menuOptionsNGP[] PROGMEM = { ngpMenuItem1, ngpMenuItem2, string_reset2 };
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";
@ -73,7 +73,8 @@ void ngpMenu() {
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -169,7 +170,8 @@ void printCartInfo_NGP() {
println_Msg(F(" Mbits")); println_Msg(F(" Mbits"));
} }
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -206,14 +208,14 @@ void readROM_NGP(char* outPathBuf, size_t bufferSize) {
snprintf(outPathBuf, bufferSize, "%s/%s", folder, fileName); snprintf(outPathBuf, bufferSize, "%s/%s", folder, fileName);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
// open file on sdcard // open file on sdcard
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(create_file_STR, true);
// write new folder number back to EEPROM // write new folder number back to EEPROM
foldern++; foldern++;
@ -246,7 +248,6 @@ void readROM_NGP(char* outPathBuf, size_t bufferSize) {
void scanChip_NGP() { void scanChip_NGP() {
display_Clear(); display_Clear();
uint32_t block_addr = 0;
// generate name of report file // generate name of report file
snprintf(fileName, FILENAME_LENGTH, "%s.txt", romName); snprintf(fileName, FILENAME_LENGTH, "%s.txt", romName);
@ -264,7 +265,7 @@ void scanChip_NGP() {
// open file on sdcard // open file on sdcard
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(create_file_STR, true);
// write new folder number back to EEPROM // write new folder number back to EEPROM
foldern++; foldern++;

View File

@ -54,23 +54,24 @@ uint8_t tennokoe_bank_index = 0;
static const char pceMenuItem1[] PROGMEM = "HuCARD (swapped)"; 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"; (stored in common strings array)
static const char *const menuOptionspce[] PROGMEM = { pceMenuItem1, pceMenuItem2, pceMenuItem3, pceMenuItem4 }; static const char *const menuOptionspce[] PROGMEM = { pceMenuItem1, pceMenuItem2, pceMenuItem3, string_reset2 };
// PCE card menu items // PCE card menu items
static const char pceCartMenuItem1[] = "Read ROM"; static char menuOptionspceCart[7][20] = {
static char pceCartMenuItem2[20]; "Read ROM",
static char pceCartMenuItem3[20]; "", // Read RAM Bank %d
static const char pceCartMenuItem4[] = "Reset"; "", //Write RAM Bank %d
static const char pceCartMenuItem5[] = "Inc Bank Number"; "Reset",
static const char pceCartMenuItem6[] = "Dec Bank Number"; "Inc Bank Number",
static char pceCartMenuItem7[20]; "Dec Bank Number",
static char menuOptionspceCart[7][20]; "" // ROM size now %dK / Force ROM size
};
// 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"; (stored in common strings array)
static const char *const menuOptionspceTC[] PROGMEM = { pceTCMenuItem1, pceTCMenuItem2 }; static const char *const menuOptionspceTC[] PROGMEM = { pceTCMenuItem1, string_reset2 };
// PCE start menu // PCE start menu
void pcsMenu(void) { void pcsMenu(void) {
@ -439,9 +440,8 @@ uint32_t calculate_crc32(int n, unsigned char c[], uint32_t r) {
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 __attribute__ ((unused)), uint32_t crc) {
FsFile rom, script; FsFile rom, script;
uint32_t r, processedsize;
char gamename[100]; char gamename[100];
char crc_file[9], crc_search[9]; char crc_file[9], crc_search[9];
uint8_t flag; uint8_t flag;
@ -518,10 +518,6 @@ void lock_tennokoe_bank_RAM() {
} }
void read_tennokoe_bank_PCE(int bank_index) { void read_tennokoe_bank_PCE(int bank_index) {
uint32_t processed_size = 0;
uint32_t verify_loop;
uint8_t verify_flag = 1;
//clear the screen //clear the screen
display_Clear(); display_Clear();
@ -549,7 +545,7 @@ void read_tennokoe_bank_PCE(int bank_index) {
//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(create_file_STR, true);
} }
pin_read_write_PCE(); pin_read_write_PCE();
@ -688,8 +684,8 @@ void write_tennokoe_bank_PCE(int bank_index) {
} else { } else {
println_Msg(F("Verify failed...")); println_Msg(F("Verify failed..."));
print_Msg(diffcnt); print_Msg(diffcnt);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
pin_init_PCE(); pin_init_PCE();
@ -743,7 +739,7 @@ void read_rom_PCE(void) {
//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(create_file_STR, true);
} }
pin_read_write_PCE(); pin_read_write_PCE();
@ -795,20 +791,13 @@ void pceMenu() {
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(menuOptionspceCart[1], "Read RAM Bank %d", tennokoe_bank_index + 1);
sprintf(pceCartMenuItem3, "Write RAM Bank %d", tennokoe_bank_index + 1); sprintf(menuOptionspceCart[2], "Write RAM Bank %d", tennokoe_bank_index + 1);
strcpy(menuOptionspceCart[0], pceCartMenuItem1);
strcpy(menuOptionspceCart[1], pceCartMenuItem2);
strcpy(menuOptionspceCart[2], pceCartMenuItem3);
strcpy(menuOptionspceCart[3], pceCartMenuItem4);
strcpy(menuOptionspceCart[4], pceCartMenuItem5);
strcpy(menuOptionspceCart[5], pceCartMenuItem6);
if (pce_force_rom_size > 0) { if (pce_force_rom_size > 0) {
sprintf(pceCartMenuItem7, "ROM size now %dK", pce_force_rom_size); sprintf(menuOptionspceCart[6], "ROM size now %dK", pce_force_rom_size);
} else { } else {
sprintf(pceCartMenuItem7, "Force ROM size"); sprintf(menuOptionspceCart[6], "Force ROM size");
} }
strcpy(menuOptionspceCart[6], pceCartMenuItem7);
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
@ -865,7 +854,8 @@ void pceMenu() {
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }

View File

@ -137,8 +137,8 @@ void setup_PCW() {
static const char pcwmenuItem1[] PROGMEM = "Read ROM"; 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"; (stored in common strings array)
static const char* const menuOptionsPCW[] PROGMEM = { pcwmenuItem1, pcwmenuItem2, pcwmenuItem3, pcwmenuItem4 }; static const char* const menuOptionsPCW[] PROGMEM = { pcwmenuItem1, pcwmenuItem2, pcwmenuItem3, string_reset2 };
void pcwMenu() { void pcwMenu() {
convertPgm(menuOptionsPCW, 4); convertPgm(menuOptionsPCW, 4);
@ -164,7 +164,8 @@ void pcwMenu() {
readSRAM_PCW(); readSRAM_PCW();
sd.chdir("/"); sd.chdir("/");
// Wait for user input // Wait for user input
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
break; break;
@ -181,10 +182,10 @@ void pcwMenu() {
println_Msg(F("SRAM verified OK")); println_Msg(F("SRAM verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
break; break;
@ -468,7 +469,7 @@ void readROM_PCW() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -477,7 +478,7 @@ void readROM_PCW() {
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, 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
@ -495,7 +496,8 @@ void readROM_PCW() {
// Wait for user input // Wait for user input
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -510,7 +512,7 @@ void readMultiROM_PCW() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -519,7 +521,7 @@ void readMultiROM_PCW() {
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
display_Clear(); display_Clear();
println_Msg(F("READING MULTI-PACK")); println_Msg(F("READING MULTI-PACK"));
@ -554,7 +556,8 @@ void readMultiROM_PCW() {
// Wait for user input // Wait for user input
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -576,7 +579,7 @@ void readSRAM_PCW() { // readSRAM_1A()
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
display_Clear(); display_Clear();
read_setup_PCW(); read_setup_PCW();
@ -620,13 +623,13 @@ void writeSRAM_PCW() {
} }
} }
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
display_Clear(); display_Clear();
} }
@ -649,11 +652,16 @@ unsigned long verifySRAM_PCW() {
} }
myFile.close(); myFile.close();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
return writeErrors; return writeErrors;
} }
// avoid warnings
#undef MODE_READ
#undef MODE_WRITE
#endif #endif
//****************************************** //******************************************
// End of File // End of File

View File

@ -16,16 +16,11 @@
// SF Memory status // SF Memory status
byte sfmReady = 0; byte sfmReady = 0;
// SF Memory Menu
boolean hasMenu = true;
byte numGames = 0;
// Arrays that hold game info // Arrays that hold game info
int gameSize[8]; int gameSize[8];
int saveSize[8]; int saveSize[8];
byte gameAddress[8]; byte gameAddress[8];
byte gameVersion[8]; byte gameVersion[8];
char gameCode[8][10];
boolean hirom[8]; boolean hirom[8];
/****************************************** /******************************************
@ -34,8 +29,8 @@ boolean hirom[8];
// SFM menu items // SFM menu items
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"; (stored in common strings array)
static const char* const menuOptionsSFM[] PROGMEM = { sfmMenuItem1, sfmMenuItem2, sfmMenuItem3 }; static const char* const menuOptionsSFM[] PROGMEM = { sfmMenuItem1, sfmMenuItem2, string_reset2 };
// SFM flash menu items // SFM flash menu items
static const char sfmFlashMenuItem1[] PROGMEM = "Read Flash"; static const char sfmFlashMenuItem1[] PROGMEM = "Read Flash";
@ -51,8 +46,8 @@ static const char sfmGameMenuItem1[] PROGMEM = "Read Sram";
static const char sfmGameMenuItem2[] PROGMEM = "Read Game"; 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"; (stored in common strings array)
static const char* const menuOptionsSFMGame[] PROGMEM = { sfmGameMenuItem1, sfmGameMenuItem2, sfmGameMenuItem3, sfmGameMenuItem4, sfmGameMenuItem5 }; static const char* const menuOptionsSFMGame[] PROGMEM = { sfmGameMenuItem1, sfmGameMenuItem2, sfmGameMenuItem3, sfmGameMenuItem4, string_reset2 };
void sfmMenu() { void sfmMenu() {
// create menu with title and 3 options to choose from // create menu with title and 3 options to choose from
@ -79,20 +74,17 @@ void sfmMenu() {
} }
void sfmGameMenu() { void sfmGameMenu() {
char menuOptionsSFMGames[8][20];
byte numGames;
boolean hasMenu;
// Switch to hirom all // Switch to hirom all
if (send_SFM(0x04) == 0x2A) { if (send_SFM(0x04) == 0x2A) {
delay(300); delay(300);
// Fill arrays with data // Fill arrays with data
getGames(); getGames(menuOptionsSFMGames, &hasMenu, &numGames);
if (hasMenu) { if (hasMenu) {
// Create submenu options
char menuOptionsSFMGames[8][20];
for (int i = 0; i < (numGames); i++) {
strncpy(menuOptionsSFMGames[i], gameCode[i], 10);
}
// Create menu with title and numGames options to choose from // Create menu with title and numGames options to choose from
unsigned char gameSubMenu; unsigned char gameSubMenu;
// wait for user choice to come back from the question box menu // wait for user choice to come back from the question box menu
@ -121,7 +113,7 @@ void sfmGameMenu() {
} }
} }
// Copy gameCode to romName in case of japanese chars in romName // Copy gameCode to romName in case of japanese chars in romName
strcpy(romName, gameCode[gameSubMenu + 1]); strcpy(romName, menuOptionsSFMGames[gameSubMenu + 1]);
// Print info // Print info
getCartInfo_SFM(); getCartInfo_SFM();
@ -133,7 +125,7 @@ void sfmGameMenu() {
delay(200); delay(200);
// Copy gameCode to romName in case of japanese chars in romName // Copy gameCode to romName in case of japanese chars in romName
strcpy(romName, gameCode[0]); strcpy(romName, menuOptionsSFMGames[0]);
// Print info // Print info
getCartInfo_SFM(); getCartInfo_SFM();
@ -182,10 +174,10 @@ void sfmGameOptions() {
println_Msg(F("Verified OK")); println_Msg(F("Verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(wrErrors); print_Msg(wrErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
break; break;
@ -201,7 +193,8 @@ void sfmGameOptions() {
} }
if (gameSubMenu != 3) { if (gameSubMenu != 3) {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -267,7 +260,8 @@ void sfmFlashMenu() {
println_Msg(F("This will erase your")); println_Msg(F("This will erase your"));
println_Msg(F("NP Cartridge.")); println_Msg(F("NP Cartridge."));
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -309,9 +303,9 @@ void sfmFlashMenu() {
println_Msg(F("OK")); println_Msg(F("OK"));
display_Update(); display_Update();
idFlash_SFM(0xC0); idFlash_SFM(0xC0);
if (strcmp(flashid, "c2f3") == 0) { if (flashid == 0xc2f3) {
idFlash_SFM(0xE0); idFlash_SFM(0xE0);
if (strcmp(flashid, "c2f3") == 0) { if (flashid == 0xc2f3) {
// Reset flash // Reset flash
resetFlash_SFM(0xC0); resetFlash_SFM(0xC0);
resetFlash_SFM(0xE0); resetFlash_SFM(0xE0);
@ -348,9 +342,9 @@ void sfmFlashMenu() {
println_Msg(F("OK")); println_Msg(F("OK"));
display_Update(); display_Update();
idFlash_SFM(0xC0); idFlash_SFM(0xC0);
if (strcmp(flashid, "c2f3") == 0) { if (flashid == 0xc2f3) {
idFlash_SFM(0xE0); idFlash_SFM(0xE0);
if (strcmp(flashid, "c2f3") == 0) { if (flashid == 0xc2f3) {
// Reset flash // Reset flash
resetFlash_SFM(0xC0); resetFlash_SFM(0xC0);
resetFlash_SFM(0xE0); resetFlash_SFM(0xE0);
@ -379,7 +373,8 @@ void sfmFlashMenu() {
println_Msg(F("This will erase your")); println_Msg(F("This will erase your"));
println_Msg(F("NP Cartridge.")); println_Msg(F("NP Cartridge."));
println_Msg(""); println_Msg("");
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -429,7 +424,8 @@ void sfmFlashMenu() {
} }
if (flashSubMenu != 5) { if (flashSubMenu != 5) {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -437,29 +433,31 @@ void sfmFlashMenu() {
#endif #endif
// Read the games from the menu area // Read the games from the menu area
void getGames() { void getGames(char gameCode[8][20], boolean *hasMenu, byte *numGames) {
// Set data pins to input // Set data pins to input
dataIn(); dataIn();
// Set control pins to input // Set control pins to input
controlIn_SFM(); controlIn_SFM();
// Check if menu is present // Check if menu is present
*hasMenu = true;
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;
} }
} }
if (hasMenu) { if (*hasMenu) {
*numGames = 0;
// 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)++;
} }
// Get game info // Get game info
for (int i = 0; i < numGames; i++) { for (int i = 0; i < *numGames; i++) {
// Read starting address and size // Read starting address and size
gameAddress[i] = 0xC0 + readBank_SFM(0xC6, i * 0x2000 + 0x01) * 0x8; gameAddress[i] = 0xC0 + readBank_SFM(0xC6, i * 0x2000 + 0x01) * 0x8;
gameSize[i] = readBank_SFM(0xC6, i * 0x2000 + 0x03) * 128; gameSize[i] = readBank_SFM(0xC6, i * 0x2000 + 0x03) * 128;
@ -486,8 +484,8 @@ void getGames() {
for (int j = 0; j < 9; j++) { for (int j = 0; j < 9; j++) {
myByte = readBank_SFM(0xC6, i * 0x2000 + 0x07 + j); myByte = readBank_SFM(0xC6, i * 0x2000 + 0x07 + j);
// Remove funny characters // Remove funny characters
if (((char(myByte) >= 44 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 9) { if (((myByte >= ',' && myByte <= '9') || (myByte >= 'A' && myByte <= 'z')) && myLength < 9) {
gameCode[i][myLength] = char(myByte); gameCode[i][myLength] = myByte;
myLength++; myLength++;
} }
} }
@ -495,48 +493,29 @@ void getGames() {
gameCode[i][myLength] = '\0'; gameCode[i][myLength] = '\0';
} }
} else { } else {
word base;
*numGames = 1;
//check if hirom //check if hirom
if (readBank_SFM(0xC0, 0xFFD5) == 0x31) { if (readBank_SFM(0xC0, 0xFFD5) == 0x31) {
hirom[0] = true; hirom[0] = true;
base = 0xFF00;
} else { } else {
hirom[0] = false; hirom[0] = false;
base = 0x7F00;
} }
if (hirom[0]) { gameVersion[0] = readBank_SFM(0xC0, base + 0xDB);
gameVersion[0] = readBank_SFM(0xC0, 0xFFDB);
gameCode[0][0] = 'G'; gameCode[0][0] = 'G';
gameCode[0][1] = 'A'; gameCode[0][1] = 'A';
gameCode[0][2] = 'M'; gameCode[0][2] = 'M';
gameCode[0][3] = 'E'; gameCode[0][3] = 'E';
gameCode[0][4] = '-'; gameCode[0][4] = '-';
gameCode[0][5] = char(readBank_SFM(0xC0, 0xFFB2)); gameCode[0][5] = readBank_SFM(0xC0, base + 0xB2);
gameCode[0][6] = char(readBank_SFM(0xC0, 0xFFB3)); gameCode[0][6] = readBank_SFM(0xC0, base + 0xB3);
gameCode[0][7] = char(readBank_SFM(0xC0, 0xFFB4)); gameCode[0][7] = readBank_SFM(0xC0, base + 0xB4);
gameCode[0][8] = char(readBank_SFM(0xC0, 0xFFB5)); gameCode[0][8] = readBank_SFM(0xC0, base + 0xB5);
gameCode[0][9] = '\0'; gameCode[0][9] = '\0';
gameSize[0] = 1 << (readBank_SFM(0xC0, base + 0xD7) - 7);
byte romSizeExp = readBank_SFM(0xC0, 0xFFD7) - 7;
gameSize[0] = 1;
while (romSizeExp--)
gameSize[0] *= 2;
} else {
gameVersion[0] = readBank_SFM(0xC0, 0x7FDB);
gameCode[0][0] = 'G';
gameCode[0][1] = 'A';
gameCode[0][2] = 'M';
gameCode[0][3] = 'E';
gameCode[0][4] = '-';
gameCode[0][5] = char(readBank_SFM(0xC0, 0x7FB2));
gameCode[0][6] = char(readBank_SFM(0xC0, 0x7FB3));
gameCode[0][7] = char(readBank_SFM(0xC0, 0x7FB4));
gameCode[0][8] = char(readBank_SFM(0xC0, 0x7FB5));
gameCode[0][9] = '\0';
byte romSizeExp = readBank_SFM(0xC0, 0x7FD7) - 7;
gameSize[0] = 1;
while (romSizeExp--)
gameSize[0] *= 2;
}
} }
} }
@ -784,7 +763,8 @@ void getCartInfo_SFM() {
print_Msg(F("Sram: ")); print_Msg(F("Sram: "));
print_Msg(sramSize); print_Msg(sramSize);
println_Msg(F("Kbit")); println_Msg(F("Kbit"));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
// Wait for user input // Wait for user input
wait(); wait();
@ -802,12 +782,8 @@ boolean checkcart_SFM() {
} }
// Calculate CRC32 of header // Calculate CRC32 of header
uint32_t oldcrc32 = 0xFFFFFFFF;
for (int c = 0; c < 80; c++) {
oldcrc32 = updateCRC(snesHeader[c], oldcrc32);
}
char crcStr[9]; char crcStr[9];
sprintf(crcStr, "%08lX", ~oldcrc32); sprintf(crcStr, "%08lX", calculateCRC(snesHeader, 80));
// Get Checksum as string // Get Checksum as string
sprintf(checksumStr, "%02X%02X", readBank_SFM(0, 65503), readBank_SFM(0, 65502)); sprintf(checksumStr, "%02X%02X", readBank_SFM(0, 65503), readBank_SFM(0, 65502));
@ -927,7 +903,7 @@ void readROM_SFM() {
//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(create_file_STR, true);
} }
// Check if LoROM or HiROM... // Check if LoROM or HiROM...
@ -936,7 +912,7 @@ void readROM_SFM() {
display_Update(); display_Update();
// Read up to 96 banks starting at bank 0×00. // Read up to 96 banks starting at bank 0×00.
for (int currBank = 0; currBank < numBanks; currBank++) { for (byte currBank = 0; currBank < numBanks; currBank++) {
// Dump the bytes to SD 512B at a time // Dump the bytes to SD 512B at a time
for (long currByte = 32768; currByte < 65536; currByte += 512) { for (long currByte = 32768; currByte < 65536; currByte += 512) {
for (int c = 0; c < 512; c++) { for (int c = 0; c < 512; c++) {
@ -951,7 +927,7 @@ void readROM_SFM() {
println_Msg(F("Dumping HiRom...")); println_Msg(F("Dumping HiRom..."));
display_Update(); display_Update();
for (int currBank = 192; currBank < (numBanks + 192); currBank++) { for (byte currBank = 192; currBank < (numBanks + 192); currBank++) {
for (long currByte = 0; currByte < 65536; currByte += 512) { for (long currByte = 0; currByte < 65536; currByte += 512) {
for (int c = 0; c < 512; c++) { for (int c = 0; c < 512; c++) {
sdBuffer[c] = readBank_SFM(currBank, currByte + c); sdBuffer[c] = readBank_SFM(currBank, currByte + c);
@ -1009,7 +985,9 @@ void idFlash_SFM(int startBank) {
controlIn_SFM(); controlIn_SFM();
// 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)); flashid = readBank_SFM(startBank, 0x00) << 8;
flashid |= readBank_SFM(startBank, 0x02);
sprintf(flashid_str, "%04x", flashid);
} 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);
@ -1021,7 +999,9 @@ void idFlash_SFM(int startBank) {
controlIn_SFM(); controlIn_SFM();
// Read the two id bytes into a string // Read the two id bytes into a string
sprintf(flashid, "%x%x", readBank_SFM(0, 0x8000), readBank_SFM(0, 0x8000 + 0x02)); flashid = readBank_SFM(0, 0x8000) << 8;
flashid |= readBank_SFM(0, 0x8000 + 0x02);
sprintf(flashid_str, "%04x", flashid);
} }
} }
@ -1047,7 +1027,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) {
if (romType) { if (romType) {
// Write hirom // Write hirom
for (int currBank = startBank; currBank < startBank + numBanks; currBank++) { for (byte currBank = startBank; currBank < startBank + numBanks; currBank++) {
// Fill SDBuffer with 1 page at a time then write it repeat until all bytes are written // Fill SDBuffer with 1 page at a time then write it repeat until all bytes are written
for (unsigned long currByte = 0; currByte < 0x10000; currByte += 128) { for (unsigned long currByte = 0; currByte < 0x10000; currByte += 128) {
myFile.read(sdBuffer, 128); myFile.read(sdBuffer, 128);
@ -1072,7 +1052,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) {
} }
} else { } else {
// Write lorom // Write lorom
for (int currBank = 0; currBank < numBanks; currBank++) { for (byte currBank = 0; currBank < numBanks; currBank++) {
for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 128) { for (unsigned long currByte = 0x8000; currByte < 0x10000; currByte += 128) {
myFile.read(sdBuffer, 128); myFile.read(sdBuffer, 128);
// Write command sequence // Write command sequence
@ -1098,7 +1078,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) {
myFile.close(); myFile.close();
println_Msg(""); println_Msg("");
} else { } else {
print_Error(F("Can't open file on SD"), true); print_Error(open_file_STR, true);
} }
} }
@ -1175,7 +1155,7 @@ byte blankcheck_SFM(int startBank) {
byte blank = 1; byte blank = 1;
if (romType) { if (romType) {
for (int currBank = startBank; currBank < startBank + numBanks; currBank++) { for (byte 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;
@ -1184,7 +1164,7 @@ byte blankcheck_SFM(int startBank) {
} }
} }
} else { } else {
for (int currBank = 0; currBank < numBanks; currBank++) { for (byte 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) {
currBank = numBanks; currBank = numBanks;
@ -1212,7 +1192,7 @@ unsigned long verifyFlash_SFM(int startBank, uint32_t pos) {
controlIn_SFM(); controlIn_SFM();
if (romType) { if (romType) {
for (int currBank = startBank; currBank < startBank + numBanks; currBank++) { for (byte currBank = startBank; currBank < startBank + numBanks; currBank++) {
for (unsigned long currByte = 0; currByte < 0x10000; currByte += 512) { for (unsigned long currByte = 0; currByte < 0x10000; currByte += 512) {
// Fill SDBuffer // Fill SDBuffer
myFile.read(sdBuffer, 512); myFile.read(sdBuffer, 512);
@ -1224,7 +1204,7 @@ unsigned long verifyFlash_SFM(int startBank, uint32_t pos) {
} }
} }
} else { } else {
for (int currBank = 0; currBank < numBanks; currBank++) { for (byte 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
myFile.read(sdBuffer, 512); myFile.read(sdBuffer, 512);
@ -1261,10 +1241,10 @@ void readFlash_SFM() {
// 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(create_file_STR, true);
} }
if (romType) { if (romType) {
for (int currBank = 0xC0; currBank < 0xC0 + numBanks; currBank++) { for (byte currBank = 0xC0; currBank < 0xC0 + numBanks; currBank++) {
for (unsigned long currByte = 0; currByte < 0x10000; currByte += 512) { for (unsigned long currByte = 0; currByte < 0x10000; currByte += 512) {
for (int c = 0; c < 512; c++) { for (int c = 0; c < 512; c++) {
sdBuffer[c] = readBank_SFM(currBank, currByte + c); sdBuffer[c] = readBank_SFM(currBank, currByte + c);
@ -1273,7 +1253,7 @@ void readFlash_SFM() {
} }
} }
} else { } else {
for (int currBank = 0; currBank < numBanks; currBank++) { for (byte 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++) {
sdBuffer[c] = readBank_SFM(currBank, currByte + c); sdBuffer[c] = readBank_SFM(currBank, currByte + c);
@ -1339,10 +1319,10 @@ void printMapping() {
// Read the mapping out of the first chip // Read the mapping out of the first chip
char buffer[3]; char buffer[3];
for (int currByte = 0xFF00; currByte < 0xFF50; currByte += 10) { for (unsigned 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 (size_t i = 0; i < 2 - strlen(buffer); i++) {
print_Msg(F("0")); print_Msg(F("0"));
} }
// Now print the significant bits // Now print the significant bits
@ -1405,7 +1385,7 @@ void readMapping() {
//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("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Read the mapping info out of the 1st chip // Read the mapping info out of the 1st chip
@ -1468,7 +1448,7 @@ void eraseMapping(byte startBank) {
if (unlockHirom()) { if (unlockHirom()) {
// Get ID // Get ID
idFlash_SFM(startBank); idFlash_SFM(startBank);
if (strcmp(flashid, "c2f3") == 0) { if (flashid == 0xc2f3) {
resetFlash_SFM(startBank); resetFlash_SFM(startBank);
// Switch to write // Switch to write
@ -1578,7 +1558,7 @@ void writeMapping_SFM(byte startBank, uint32_t pos) {
if (unlockHirom()) { if (unlockHirom()) {
// Get ID // Get ID
idFlash_SFM(startBank); idFlash_SFM(startBank);
if (strcmp(flashid, "c2f3") == 0) { if (flashid == 0xc2f3) {
resetFlash_SFM(startBank); resetFlash_SFM(startBank);
// Switch to write // Switch to write
@ -1711,9 +1691,9 @@ void write_SFM(int startBank, uint32_t pos) {
if (unlockHirom()) { if (unlockHirom()) {
// Get ID // Get ID
idFlash_SFM(startBank); idFlash_SFM(startBank);
if (strcmp(flashid, "c2f3") == 0) { if (flashid == 0xc2f3) {
print_Msg(F("Flash ID: ")); print_Msg(F("Flash ID: "));
println_Msg(flashid); println_Msg(flashid_str);
display_Update(); display_Update();
resetFlash_SFM(startBank); resetFlash_SFM(startBank);
delay(1000); delay(1000);
@ -1730,7 +1710,7 @@ void write_SFM(int startBank, uint32_t pos) {
display_Update(); display_Update();
eraseFlash_SFM(startBank); eraseFlash_SFM(startBank);
resetFlash_SFM(startBank); resetFlash_SFM(startBank);
println_Msg(F("Done")); print_STR(done_STR, 1);
print_Msg(F("Blankcheck...")); print_Msg(F("Blankcheck..."));
display_Update(); display_Update();
if (blankcheck_SFM(startBank)) { if (blankcheck_SFM(startBank)) {
@ -1747,17 +1727,17 @@ void write_SFM(int startBank, uint32_t pos) {
resetFlash_SFM(startBank); resetFlash_SFM(startBank);
// Checking for errors // Checking for errors
print_Msg(F("Verifying...")); print_STR(verifying_STR, 0);
display_Update(); display_Update();
writeErrors = verifyFlash_SFM(startBank, pos); writeErrors = verifyFlash_SFM(startBank, 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_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), true); print_Error(did_not_verify_STR, true);
} }
} else { } else {
print_Error(F("Error: Wrong Flash ID"), true); print_Error(F("Error: Wrong Flash ID"), true);

View File

@ -18,9 +18,9 @@ static const char* const menuAdapterSMS[] PROGMEM = { SMSAdapterItem1, SMSAdapte
static const char SMSMenuItem1[] PROGMEM = "Read Rom"; static const char SMSMenuItem1[] PROGMEM = "Read Rom";
static const char SMSMenuItem2[] PROGMEM = "Read from SRAM"; 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"; (stored in common strings array)
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, string_reset2, SMSMenuItem5 };
// Rom Size menu // Rom Size menu
static const char SMSRomItem1[] PROGMEM = "8KB"; static const char SMSRomItem1[] PROGMEM = "8KB";
@ -114,10 +114,12 @@ 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...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
} else { } else {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
} }
display_Update(); display_Update();
wait(); wait();
@ -550,7 +552,8 @@ void getCartInfo_SMS() {
// Wait for user input // Wait for user input
#if (defined(enable_LCD) || defined(enable_OLED)) #if (defined(enable_LCD) || defined(enable_OLED))
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#endif #endif
@ -579,7 +582,7 @@ void readROM_SMS() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -590,7 +593,7 @@ void readROM_SMS() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
// set default bank size to 16KB // set default bank size to 16KB
@ -664,7 +667,7 @@ void readSRAM_SMS() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -675,7 +678,7 @@ void readSRAM_SMS() {
// 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("SD Error"), true); print_Error(sd_error_STR, true);
} }
// Write the whole 32KB // Write the whole 32KB
// When there is only 8KB of SRAM, the contents should be duplicated // When there is only 8KB of SRAM, the contents should be duplicated
@ -742,10 +745,10 @@ void writeSRAM_SMS() {
blinkLED(); blinkLED();
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("DONE")); print_STR(done_STR, 1);
display_Update(); display_Update();
} else { } else {
print_Error(F("SD ERROR"), true); print_Error(sd_error_STR, true);
} }
} }

View File

@ -35,11 +35,11 @@ static const char snsMenuItem3[] PROGMEM = "Satellaview BS-X";
static const char snsMenuItem4[] PROGMEM = "Flash repro"; static const char snsMenuItem4[] PROGMEM = "Flash repro";
#ifdef clockgen_calibration #ifdef clockgen_calibration
static const char snsMenuItem5[] PROGMEM = "Calibrate Clock"; static const char snsMenuItem5[] PROGMEM = "Calibrate Clock";
static const char snsMenuItem6[] PROGMEM = "Reset"; //static const char snsMenuItem6[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, snsMenuItem6 }; static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, string_reset2 };
#else #else
static const char snsMenuItem5[] PROGMEM = "Reset"; //static const char snsMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5 }; static const char* const menuOptionsSNS[] PROGMEM = { snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, string_reset2 };
#endif #endif
// SNES menu items // SNES menu items
@ -49,24 +49,24 @@ static const char SnesMenuItem3[] PROGMEM = "Write Save";
static const char SnesMenuItem4[] PROGMEM = "Test SRAM"; static const char SnesMenuItem4[] PROGMEM = "Test SRAM";
static const char SnesMenuItem5[] PROGMEM = "Cycle cart"; static const char SnesMenuItem5[] PROGMEM = "Cycle cart";
static const char SnesMenuItem6[] PROGMEM = "Force cart type"; static const char SnesMenuItem6[] PROGMEM = "Force cart type";
static const char SnesMenuItem7[] PROGMEM = "Reset"; //static const char SnesMenuItem7[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsSNES[] PROGMEM = { SnesMenuItem1, SnesMenuItem2, SnesMenuItem3, SnesMenuItem4, SnesMenuItem5, SnesMenuItem6, SnesMenuItem7 }; static const char* const menuOptionsSNES[] PROGMEM = { SnesMenuItem1, SnesMenuItem2, SnesMenuItem3, SnesMenuItem4, SnesMenuItem5, SnesMenuItem6, string_reset2 };
// Manual config menu items // Manual config menu items
static const char confMenuItem1[] PROGMEM = "Use header info"; static const char confMenuItem1[] PROGMEM = "Use header info";
static const char confMenuItem2[] PROGMEM = "4MB LoROM 256K SRAM"; static const char confMenuItem2[] PROGMEM = "4MB LoROM 256K SRAM";
static const char confMenuItem3[] PROGMEM = "4MB HiROM 64K SRAM"; static const char confMenuItem3[] PROGMEM = "4MB HiROM 64K SRAM";
static const char confMenuItem4[] PROGMEM = "6MB ExROM 256K SRAM"; static const char confMenuItem4[] PROGMEM = "6MB ExROM 256K SRAM";
static const char confMenuItem5[] PROGMEM = "Reset"; //static const char confMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsConfManual[] PROGMEM = { confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, confMenuItem5 }; static const char* const menuOptionsConfManual[] PROGMEM = { confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, string_reset2 };
// Repro menu items // Repro menu items
static const char reproMenuItem1[] PROGMEM = "LoROM (P0)"; static const char reproMenuItem1[] PROGMEM = "LoROM (P0)";
static const char reproMenuItem2[] PROGMEM = "HiROM (P0)"; static const char reproMenuItem2[] PROGMEM = "HiROM (P0)";
static const char reproMenuItem3[] PROGMEM = "ExLoROM (P1)"; static const char reproMenuItem3[] PROGMEM = "ExLoROM (P1)";
static const char reproMenuItem4[] PROGMEM = "ExHiROM (P1)"; static const char reproMenuItem4[] PROGMEM = "ExHiROM (P1)";
static const char reproMenuItem5[] PROGMEM = "Reset"; //static const char reproMenuItem5[] PROGMEM = "Reset"; (stored in common strings array)
static const char* const menuOptionsRepro[] PROGMEM = { reproMenuItem1, reproMenuItem2, reproMenuItem3, reproMenuItem4, reproMenuItem5 }; static const char* const menuOptionsRepro[] PROGMEM = { reproMenuItem1, reproMenuItem2, reproMenuItem3, reproMenuItem4, string_reset2 };
// SNES repro menu // SNES repro menu
void reproMenu() { void reproMenu() {
@ -204,8 +204,6 @@ void snesMenu() {
display_Clear(); display_Clear();
// Change working dir to root // Change working dir to root
sd.chdir("/"); sd.chdir("/");
// get current time
unsigned long startTime = millis();
// start reading from cart // start reading from cart
readROM_SNES(); readROM_SNES();
// Internal Checksum // Internal Checksum
@ -247,10 +245,10 @@ void snesMenu() {
println_Msg(F("Verified OK")); println_Msg(F("Verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(wrErrors); print_Msg(wrErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
display_Clear(); display_Clear();
@ -282,10 +280,10 @@ void snesMenu() {
println_Msg(F("Restored OK")); println_Msg(F("Restored OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(wrErrors); print_Msg(wrErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
display_Clear(); display_Clear();
@ -323,7 +321,8 @@ void snesMenu() {
break; break;
} }
//println_Msg(F("")); //println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -603,7 +602,7 @@ void readLoRomBanks(unsigned int start, unsigned int total, FsFile* file) {
uint32_t totalProgressBar = (uint32_t)(total - start) * 1024; uint32_t totalProgressBar = (uint32_t)(total - start) * 1024;
draw_progressbar(0, totalProgressBar); draw_progressbar(0, totalProgressBar);
for (int currBank = start; currBank < total; currBank++) { for (byte currBank = start; currBank < total; currBank++) {
PORTL = currBank; PORTL = currBank;
// Blink led // Blink led
@ -654,7 +653,7 @@ void readHiRomBanks(unsigned int start, unsigned int total, FsFile* file) {
uint32_t totalProgressBar = (uint32_t)(total - start) * 1024; uint32_t totalProgressBar = (uint32_t)(total - start) * 1024;
draw_progressbar(0, totalProgressBar); draw_progressbar(0, totalProgressBar);
for (int currBank = start; currBank < total; currBank++) { for (byte currBank = start; currBank < total; currBank++) {
PORTL = currBank; PORTL = currBank;
// Blink led // Blink led
@ -700,31 +699,6 @@ void readHiRomBanks(unsigned int start, unsigned int total, FsFile* file) {
void getCartInfo_SNES() { void getCartInfo_SNES() {
boolean manualConfig = 0; boolean manualConfig = 0;
//Prime SA1 cartridge
uint16_t c = 0;
uint16_t currByte = 0;
byte buffer[1024] = { 0 };
PORTL = 192;
while (c < 1024) {
PORTF = (currByte & 0xFF);
PORTK = ((currByte >> 8) & 0xFF);
// Wait for the Byte to appear on the data bus
// Arduino running at 16Mhz -> one nop = 62.5ns
// slowRom is good for 200ns, fastRom is <= 120ns; S-CPU best case read speed: 3.57MHz / 280ns
// let's be conservative and use 6 x 62.5 = 375ns
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
buffer[c] = PINC;
c++;
currByte++;
}
// Print start page // Print start page
if (checkcart_SNES() == 0) { if (checkcart_SNES() == 0) {
// Checksum either corrupt or 0000 // Checksum either corrupt or 0000
@ -840,7 +814,8 @@ void getCartInfo_SNES() {
// Wait for user input // Wait for user input
#if (defined(enable_LCD) || defined(enable_OLED)) #if (defined(enable_LCD) || defined(enable_OLED))
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#endif #endif
@ -872,7 +847,7 @@ void checkAltConf(char crcStr[9]) {
skip_line(&myFile); skip_line(&myFile);
// Skip over the CRC checksum // Skip over the CRC checksum
myFile.seekSet(myFile.curPosition() + 9); myFile.seekCur(9);
// Get internal ROM checksum as string // Get internal ROM checksum as string
for (byte j = 0; j < 4; j++) { for (byte j = 0; j < 4; j++) {
@ -887,7 +862,7 @@ void checkAltConf(char crcStr[9]) {
display_Update(); display_Update();
// Skip the , in the file // Skip the , in the file
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read the CRC32 of the SNES header out of database // Read the CRC32 of the SNES header out of database
for (byte k = 0; k < 8; k++) { for (byte k = 0; k < 8; k++) {
@ -896,13 +871,13 @@ void checkAltConf(char crcStr[9]) {
tempStr3[8] = '\0'; tempStr3[8] = '\0';
// Skip the , in the file // Skip the , in the file
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read file size // Read file size
byte romSize2 = (myFile.read() - 48) * 10 + (myFile.read() - 48); byte romSize2 = (myFile.read() - 48) * 10 + (myFile.read() - 48);
// Skip the , in the file // Skip the , in the file
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read number of banks // Read number of banks
byte numBanks2 = (myFile.read() - 48) * 100 + (myFile.read() - 48) * 10 + (myFile.read() - 48); byte numBanks2 = (myFile.read() - 48) * 100 + (myFile.read() - 48) * 10 + (myFile.read() - 48);
@ -936,7 +911,7 @@ void checkAltConf(char crcStr[9]) {
// If no match go to next entry // If no match go to next entry
else { else {
// skip rest of line // skip rest of line
myFile.seekSet(myFile.curPosition() + 18); myFile.seekCur(18);
// skip third empty line // skip third empty line
skip_line(&myFile); skip_line(&myFile);
} }
@ -951,12 +926,10 @@ boolean checkcart_SNES() {
// set control to read // set control to read
dataIn(); dataIn();
uint16_t c = 0;
uint16_t headerStart = 0xFFB0; uint16_t headerStart = 0xFFB0;
uint16_t currByte = headerStart; byte snesHeader[80];
byte snesHeader[80] = { 0 };
PORTL = 0; PORTL = 0;
while (c < 80) { for (uint16_t c = 0, currByte = headerStart; c < 80; c++, currByte++) {
PORTF = (currByte & 0xFF); PORTF = (currByte & 0xFF);
PORTK = ((currByte >> 8) & 0xFF); PORTK = ((currByte >> 8) & 0xFF);
@ -974,17 +947,11 @@ boolean checkcart_SNES() {
NOP; NOP;
snesHeader[c] = PINC; snesHeader[c] = PINC;
c++;
currByte++;
} }
// Calculate CRC32 of header // Calculate CRC32 of header
uint32_t oldcrc32 = 0xFFFFFFFF;
for (int c = 0; c < 80; c++) {
oldcrc32 = updateCRC(snesHeader[c], oldcrc32);
}
char crcStr[9]; char crcStr[9];
sprintf(crcStr, "%08lX", ~oldcrc32); sprintf(crcStr, "%08lX", calculateCRC(snesHeader, 80));
// Get Checksum as string // Get Checksum as string
sprintf(checksumStr, "%02X%02X", snesHeader[0xFFDF - headerStart], snesHeader[0xFFDE - headerStart]); sprintf(checksumStr, "%02X%02X", snesHeader[0xFFDF - headerStart], snesHeader[0xFFDE - headerStart]);
@ -1049,25 +1016,7 @@ boolean checkcart_SNES() {
} }
// Get name // Get name
byte myByte = 0; byte myLength = buildRomName(romName, &snesHeader[headerStart], 21);
byte myLength = 0;
for (unsigned int i = 0xFFC0; i < 0xFFD5; i++) {
myByte = snesHeader[i - headerStart];
if (isprint(myByte) && myByte != '<' && myByte != '>' && myByte != ':' && myByte != '"' && myByte != '/' && myByte != '\\' && myByte != '|' && myByte != '?' && myByte != '*') {
romName[myLength] = char(myByte);
} else {
if (romName[myLength - 1] == 0x5F) myLength--;
romName[myLength] = 0x5F;
}
myLength++;
}
// Strip trailing white space
for (unsigned int i = myLength - 1; i > 0; i--) {
if ((romName[i] != 0x5F) && (romName[i] != 0x20)) break;
romName[i] = 0x00;
myLength--;
}
// If name consists out of all japanese characters use game code // If name consists out of all japanese characters use game code
if (myLength == 0) { if (myLength == 0) {
@ -1078,9 +1027,10 @@ boolean checkcart_SNES() {
romName[3] = 'C'; romName[3] = 'C';
romName[4] = '-'; romName[4] = '-';
for (unsigned int i = 0; i < 4; i++) { for (unsigned int i = 0; i < 4; i++) {
byte myByte;
myByte = snesHeader[0xFFB2 + i - headerStart]; myByte = snesHeader[0xFFB2 + i - headerStart];
if (((char(myByte) >= 48 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 4) { if (((myByte >= '0' && myByte <= '9') || (myByte >= 'A' && myByte <= 'z')) && myLength < 4) {
romName[myLength + 5] = char(myByte); romName[myLength + 5] = myByte;
myLength++; myLength++;
} }
} }
@ -1314,7 +1264,7 @@ void readROM_SNES() {
//clear the screen //clear the screen
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -1325,7 +1275,7 @@ void readROM_SNES() {
//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(create_file_STR, true);
} }
//Dump Derby Stallion '96 (Japan) Actual Size is 24Mb //Dump Derby Stallion '96 (Japan) Actual Size is 24Mb
@ -1394,7 +1344,7 @@ void readROM_SNES() {
controlIn_SNES(); controlIn_SNES();
byte initialSOMap = readBank_SNES(0, 18439); byte initialSOMap = readBank_SNES(0, 18439);
for (int currMemmap = 0; currMemmap < (numBanks / 16); currMemmap++) { for (byte currMemmap = 0; currMemmap < (numBanks / 16); currMemmap++) {
dataOut(); dataOut();
controlOut_SNES(); controlOut_SNES();
@ -1678,7 +1628,7 @@ void readSRAM() {
//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("SD Error"), true); print_Error(sd_error_STR, true);
} }
int sramBanks = 0; int sramBanks = 0;
if (romType == LO) { if (romType == LO) {
@ -1951,10 +1901,10 @@ unsigned long verifySRAM() {
if (writeErrors == 0) { if (writeErrors == 0) {
println_Msg(F("Verified OK")); println_Msg(F("Verified OK"));
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
display_Update(); display_Update();
wait(); wait();
@ -1972,6 +1922,7 @@ unsigned long verifySRAM() {
return writeErrors; return writeErrors;
} else { } else {
print_Error(F("Can't open file"), false); print_Error(F("Can't open file"), false);
return 1;
} }
} }

View File

@ -82,10 +82,10 @@ void svMenu() {
println_Msg(F("Verified OK")); println_Msg(F("Verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(wrErrors); print_Msg(wrErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
wait(); wait();
break; break;
@ -300,13 +300,10 @@ void readSRAM_SV() {
//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("SD Error"), true); print_Error(sd_error_STR, true);
} }
int sramBanks = 0;
readBank_SV(0x10, 0); // Preconfigure to fix corrupt 1st byte readBank_SV(0x10, 0); // Preconfigure to fix corrupt 1st byte
// Sram size
long lastByte = (long(sramSize) * 0x80);
//startBank = 0x10; endBank = 0x17; CS low //startBank = 0x10; endBank = 0x17; CS low
for (byte BSBank = 0x10; BSBank < 0x18; BSBank++) { for (byte BSBank = 0x10; BSBank < 0x18; BSBank++) {
@ -347,8 +344,6 @@ void writeSRAM_SV() {
// Set RST RD WR to High and CS to Low // Set RST RD WR to High and CS to Low
controlOut_SNES(); controlOut_SNES();
long lastByte = (long(sramSize) * 0x80);
println_Msg(F("Writing sram...")); println_Msg(F("Writing sram..."));
display_Update(); display_Update();
@ -390,10 +385,6 @@ unsigned long verifySRAM_SV() {
// Set control // Set control
controlIn_SNES(); controlIn_SNES();
int sramBanks = 0;
// Sram size
long lastByte = (long(sramSize) * 0x80);
//startBank = 0x10; endBank = 0x17; CS low //startBank = 0x10; endBank = 0x17; CS low
for (byte BSBank = 0x10; BSBank < 0x18; BSBank++) { for (byte BSBank = 0x10; BSBank < 0x18; BSBank++) {
//startAddr = 0x5000 //startAddr = 0x5000
@ -412,6 +403,7 @@ unsigned long verifySRAM_SV() {
return writeErrors; return writeErrors;
} else { } else {
print_Error(F("Can't open file"), false); print_Error(F("Can't open file"), false);
return 1;
} }
} }
@ -435,7 +427,7 @@ void readROM_SV() {
//clear the screen //clear the screen
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -446,7 +438,7 @@ void readROM_SV() {
//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(create_file_STR, true);
} }
// Read Banks // Read Banks
@ -559,7 +551,7 @@ void writeROM_SV(void) {
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...")); print_STR(verifying_STR, 1);
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);

View File

@ -97,8 +97,8 @@ void setup_VBOY() {
static const char vboyMenuItem1[] PROGMEM = "Read ROM"; 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"; (stored in common strings array)
static const char* const menuOptionsVBOY[] PROGMEM = { vboyMenuItem1, vboyMenuItem2, vboyMenuItem3, vboyMenuItem4 }; static const char* const menuOptionsVBOY[] PROGMEM = { vboyMenuItem1, vboyMenuItem2, vboyMenuItem3, string_reset2 };
void vboyMenu() { void vboyMenu() {
convertPgm(menuOptionsVBOY, 4); convertPgm(menuOptionsVBOY, 4);
@ -126,7 +126,8 @@ void vboyMenu() {
} }
#if (defined(enable_OLED) || defined(enable_LCD)) #if (defined(enable_OLED) || defined(enable_LCD))
// Wait for user input // Wait for user input
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#endif #endif
@ -145,17 +146,18 @@ void vboyMenu() {
println_Msg(F("SRAM verified OK")); println_Msg(F("SRAM verified OK"));
display_Update(); display_Update();
} else { } else {
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(writeErrors); print_Msg(writeErrors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, 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))
// Wait for user input // Wait for user input
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#endif #endif
@ -395,7 +397,8 @@ void getCartInfo_VB() {
#if (defined(enable_OLED) || defined(enable_LCD)) #if (defined(enable_OLED) || defined(enable_LCD))
// Wait for user input // Wait for user input
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#endif #endif
@ -417,7 +420,7 @@ void readROM_VB() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
@ -426,7 +429,7 @@ void readROM_VB() {
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
word d = 0; word d = 0;
@ -469,7 +472,8 @@ void readROM_VB() {
#if (defined(enable_OLED) || defined(enable_LCD)) #if (defined(enable_OLED) || defined(enable_LCD))
// Wait for user input // Wait for user input
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
#endif #endif
@ -493,10 +497,10 @@ void writeSRAM_VB() {
writeByte_VB(currByte, (myFile.read())); writeByte_VB(currByte, (myFile.read()));
} }
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
dataIn_VB(); dataIn_VB();
} }
@ -516,7 +520,7 @@ void readSRAM_VB() {
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
for (unsigned long currBuffer = 0; currBuffer < sramSize; currBuffer += 512) { for (unsigned long currBuffer = 0; currBuffer < sramSize; currBuffer += 512) {
for (int currByte = 0; currByte < 512; currByte++) { for (int currByte = 0; currByte < 512; currByte++) {
@ -550,7 +554,7 @@ unsigned long verifySRAM_VB() {
} }
myFile.close(); myFile.close();
} else { } else {
print_Error(F("SD Error"), true); print_Error(sd_error_STR, true);
} }
return writeErrors; return writeErrors;

View File

@ -35,9 +35,9 @@
static const char wsMenuItem1[] PROGMEM = "Read Rom"; static const char wsMenuItem1[] PROGMEM = "Read Rom";
static const char wsMenuItem2[] PROGMEM = "Read Save"; 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"; (stored in common strings array)
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, string_reset2, 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 };
@ -184,7 +184,8 @@ void wsMenu() {
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
@ -404,7 +405,8 @@ void showCartInfo_WS() {
print_Msg(F("Checksum: ")); print_Msg(F("Checksum: "));
println_Msg(checksumStr); println_Msg(checksumStr);
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -487,14 +489,14 @@ void readROM_WS(char *outPathBuf, size_t bufferSize) {
snprintf(outPathBuf, bufferSize, "%s/%s", folder, fileName); snprintf(outPathBuf, bufferSize, "%s/%s", folder, fileName);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
// open file on sdcard // open file on sdcard
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(create_file_STR, true);
// write new folder number back to EEPROM // write new folder number back to EEPROM
foldern++; foldern++;
@ -561,7 +563,7 @@ void readSRAM_WS() {
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
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(create_file_STR, true);
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
@ -591,7 +593,7 @@ void readSRAM_WS() {
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
display_Update(); display_Update();
} }
@ -630,10 +632,10 @@ void verifySRAM_WS() {
println_Msg(F("passed")); println_Msg(F("passed"));
} else { } else {
println_Msg(F("failed")); println_Msg(F("failed"));
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(write_errors); print_Msg(write_errors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
print_Error(F("File doesn't exist"), false); print_Error(F("File doesn't exist"), false);
@ -706,7 +708,7 @@ void readEEPROM_WS() {
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
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(create_file_STR, true);
uint32_t eepromSize = (sramSize << 7); uint32_t eepromSize = (sramSize << 7);
uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512); uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512);
@ -738,7 +740,7 @@ void readEEPROM_WS() {
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
} }
void verifyEEPROM_WS() { void verifyEEPROM_WS() {
@ -784,10 +786,10 @@ void verifyEEPROM_WS() {
println_Msg(F("passed")); println_Msg(F("passed"));
} else { } else {
println_Msg(F("failed")); println_Msg(F("failed"));
print_Msg(F("Error: ")); print_STR(error_STR, 0);
print_Msg(write_errors); print_Msg(write_errors);
println_Msg(F(" bytes ")); print_STR(_bytes_STR, 1);
print_Error(F("did not verify."), false); print_Error(did_not_verify_STR, false);
} }
} else { } else {
print_Error(F("File doesn't exist"), false); print_Error(F("File doesn't exist"), false);
@ -839,7 +841,7 @@ void writeEEPROM_WS() {
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
} else { } else {
print_Error(F("File doesn't exist"), false); print_Error(F("File doesn't exist"), false);
} }
@ -928,7 +930,7 @@ void writeWitchOS_WS() {
myFile.close(); myFile.close();
println_Msg(F("Done")); print_STR(done_STR, 1);
} else { } else {
print_Error(F("File doesn't exist"), false); print_Error(F("File doesn't exist"), false);
} }
@ -979,7 +981,7 @@ boolean compareChecksum_WS(const char *wsFilePath) {
} }
uint32_t calLength = myFile.fileSize() - 512; uint32_t calLength = myFile.fileSize() - 512;
uint32_t checksum = 0; uint16_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)
@ -1001,18 +1003,12 @@ boolean compareChecksum_WS(const char *wsFilePath) {
myFile.close(); myFile.close();
checksum &= 0x0000ffff;
calLength = wsGameChecksum;
// don't know why formating string "%04X(%04X)" always output "xxxx(0000)"
// so split into two snprintf
char result[11]; char result[11];
snprintf(result, 5, "%04X", calLength); snprintf(result, 11, "%04X(%04X)", wsGameChecksum, checksum);
snprintf(result + 4, 11 - 4, "(%04X)", checksum);
print_Msg(F("Result: ")); print_Msg(F("Result: "));
println_Msg(result); println_Msg(result);
if (checksum == calLength) { if (checksum == wsGameChecksum) {
println_Msg(F("Checksum matches")); println_Msg(F("Checksum matches"));
display_Update(); display_Update();
return 1; return 1;

View File

@ -102,8 +102,8 @@ void setup_WSV() {
static const char wsvMenuItem1[] PROGMEM = "Select Cart"; 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"; (stored in common strings array)
static const char* const menuOptionsSV[] PROGMEM = { wsvMenuItem1, wsvMenuItem2, wsvMenuItem3, wsvMenuItem4 }; static const char* const menuOptionsSV[] PROGMEM = { wsvMenuItem1, wsvMenuItem2, wsvMenuItem3, string_reset2 };
void wsvMenu() { void wsvMenu() {
convertPgm(menuOptionsSV, 4); convertPgm(menuOptionsSV, 4);
@ -198,14 +198,14 @@ void readROM_WSV() {
sd.chdir(folder); sd.chdir(folder);
display_Clear(); display_Clear();
print_Msg(F("Saving to ")); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
display_Update(); display_Update();
// open file on sdcard // open file on sdcard
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(create_file_STR, true);
// write new folder number back to EEPROM // write new folder number back to EEPROM
foldern++; foldern++;
@ -233,7 +233,8 @@ void readROM_WSV() {
compareCRC("wsv.txt", 0, 1, 0); compareCRC("wsv.txt", 0, 1, 0);
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); // Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
@ -256,11 +257,11 @@ void setROMSize_WSV() {
println_Msg(WSV[i]); println_Msg(WSV[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
@ -278,11 +279,11 @@ void setROMSize_WSV() {
println_Msg(WSV[i]); println_Msg(WSV[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -298,11 +299,11 @@ void setROMSize_WSV() {
println_Msg(WSV[i]); println_Msg(WSV[i]);
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#endif #endif
display_Update(); display_Update();
} }
@ -407,20 +408,7 @@ void setCart_WSV() {
} }
// Rewind one line // Rewind one line
for (byte count_newline = 0; count_newline < 2; count_newline++) { rewind_line(myFile);
while (1) {
if (myFile.curPosition() == 0) {
break;
} else if (myFile.peek() == '\n') {
myFile.seekSet(myFile.curPosition() - 1);
break;
} else {
myFile.seekSet(myFile.curPosition() - 1);
}
}
}
if (myFile.curPosition() != 0)
myFile.seekSet(myFile.curPosition() + 2);
} }
// Display database // Display database
@ -438,7 +426,7 @@ void setCart_WSV() {
} }
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read CRC32 of first 512 bytes // Read CRC32 of first 512 bytes
sprintf(crc_search, "%c", myFile.read()); sprintf(crc_search, "%c", myFile.read());
@ -448,7 +436,7 @@ void setCart_WSV() {
} }
// Skip over semicolon // Skip over semicolon
myFile.seekSet(myFile.curPosition() + 1); myFile.seekCur(1);
// Read rom size // Read rom size
// Read the next ascii character and subtract 48 to convert to decimal // Read the next ascii character and subtract 48 to convert to decimal
@ -462,7 +450,7 @@ void setCart_WSV() {
} }
// Skip rest of line // Skip rest of line
myFile.seekSet(myFile.curPosition() + 2); myFile.seekCur(2);
// Skip every 3rd line // Skip every 3rd line
skip_line(&myFile); skip_line(&myFile);
@ -478,11 +466,11 @@ void setCart_WSV() {
println_Msg(F("KB")); println_Msg(F("KB"));
println_Msg(F("")); println_Msg(F(""));
#if defined(enable_OLED) #if defined(enable_OLED)
println_Msg(F("Press left to Change")); print_STR(press_to_change_STR, 1);
println_Msg(F("and right to Select")); print_STR(right_to_select_STR, 1);
#elif defined(enable_LCD) #elif defined(enable_LCD)
println_Msg(F("Rotate to Change")); print_STR(rotate_to_change_STR, 1);
println_Msg(F("Press to Select")); print_STR(press_to_select_STR, 1);
#elif defined(SERIAL_MONITOR) #elif defined(SERIAL_MONITOR)
println_Msg(F("U/D to Change")); println_Msg(F("U/D to Change"));
println_Msg(F("Space to Select")); println_Msg(F("Space to Select"));
@ -501,20 +489,7 @@ void setCart_WSV() {
// Previous // Previous
else if (b == 2) { else if (b == 2) {
for (byte count_newline = 0; count_newline < 7; count_newline++) { rewind_line(myFile, 6);
while (1) {
if (myFile.curPosition() == 0) {
break;
} else if (myFile.peek() == '\n') {
myFile.seekSet(myFile.curPosition() - 1);
break;
} else {
myFile.seekSet(myFile.curPosition() - 1);
}
}
}
if (myFile.curPosition() != 0)
myFile.seekSet(myFile.curPosition() + 2);
break; break;
} }