diff --git a/Cart_Reader/COLV.ino b/Cart_Reader/COLV.ino index b833c9b..94be5de 100644 --- a/Cart_Reader/COLV.ino +++ b/Cart_Reader/COLV.ino @@ -182,7 +182,7 @@ void readROM_COL() { // open file on sdcard if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); // write new folder number back to EEPROM foldern++; @@ -515,7 +515,7 @@ void setCart_COL() { } } } else { - print_Error(F("Database file not found"), true); + print_FatalError(F("Database file not found")); } } #endif diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index 1e4e36d..6a680ec 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -298,6 +298,10 @@ bool i2c_found; #include "FreqCount.h" #endif +void _print_FatalError(void) __attribute__ ((noreturn)); +void print_FatalError(const __FlashStringHelper* errorMessage) __attribute__ ((noreturn)); +void print_FatalError(byte errorMessage) __attribute__ ((noreturn)); + /****************************************** Common Strings *****************************************/ @@ -616,7 +620,7 @@ uint32_t calculateCRC(char* fileName, char* folder, int offset) { //print_Msg(folder); //print_Msg(F("/")); //print_Msg(fileName); - print_Error(F(" not found"), true); + print_FatalError(F(" not found")); return 0; } } @@ -748,7 +752,7 @@ boolean compareCRC(const char* database, char* crcString, boolean renamerom, int // Write iNES header sd.chdir(folder); if (!myFile.open(fileName, O_RDWR)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } for (byte z = 0; z < 16; z++) { myFile.write(iNES_HEADER[z]); @@ -886,6 +890,12 @@ byte starting_letter() { #endif } +void print_MissingModule(void) { + display_Clear(); + println_Msg(F("Please enable module")); + print_FatalError(F("in Cart_Reader.ino.")); +} + /****************************************** Main menu optimized for rotary encoder *****************************************/ @@ -913,6 +923,8 @@ static const char* const modeOptions[] PROGMEM = { modeItem1, modeItem2, modeIte void mainMenu() { // create menu with title and 15 options to choose from unsigned char modeMenu; + byte num_answers; + byte option_offset; // Main menu spans across two pages currPage = 1; @@ -921,23 +933,23 @@ void mainMenu() { while (1) { if (currPage == 1) { - // Copy menuOptions out of progmem - convertPgm(modeOptions + 0, 7); - modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 7, 0); + option_offset = 0; + num_answers = 7; } if (currPage == 2) { - // Copy menuOptions out of progmem - convertPgm(modeOptions + 7, 7); - modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 7, 0); + option_offset = 7; + num_answers = 7; } if (currPage == 3) { - // Copy menuOptions out of progmem - convertPgm(modeOptions + 14, 2); - modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, 2, 0); + option_offset = 14; + num_answers = 2; } + // Copy menuOptions out of progmem + convertPgm(modeOptions + option_offset, num_answers); + modeMenu = question_box(F("OPEN SOURCE CART READER"), menuOptions, num_answers, 0); if (numPages == 0) { // Execute choice - modeMenu = (currPage - 1) * 7 + modeMenu; + modeMenu += option_offset; break; } } @@ -1062,10 +1074,7 @@ void mainMenu() { break; default: - display_Clear(); - println_Msg(F("Please enable module")); - print_Error(F("in Cart_Reader.ino."), true); - break; + print_MissingModule(); // does not return } } @@ -1081,11 +1090,7 @@ static const char modeItem2[] PROGMEM = "SNES/SFC (CLK0+1)"; static const char modeItem2[] PROGMEM = "Super Nintendo/SFC"; #endif static const char modeItem3[] PROGMEM = "Mega Drive/Genesis"; -#if defined(clockgen_installed) static const char modeItem4[] PROGMEM = "N64 (3V EEP CLK1)"; -#else -static const char modeItem4[] PROGMEM = "Nintendo 64(3V EEP)"; -#endif static const char modeItem5[] PROGMEM = "Game Boy"; static const char modeItem6[] PROGMEM = "About"; // static const char modeItem7[] PROGMEM = "Reset"; (stored in common strings array) @@ -1161,6 +1166,9 @@ void mainMenu() { case 6: resetArduino(); break; + + default: + print_MissingModule(); // does not return } } @@ -1199,10 +1207,7 @@ void addonMenu() { break; default: - display_Clear(); - println_Msg(F("Please enable module")); - print_Error(F("in Cart_Reader.ino."), true); - break; + print_MissingModule(); // does not return } } @@ -1258,10 +1263,7 @@ void consoleMenu() { break; default: - display_Clear(); - println_Msg(F("Please enable module")); - print_Error(F("in Cart_Reader.ino."), true); - break; + print_MissingModule(); // does not return } } @@ -1319,10 +1321,7 @@ void handheldMenu() { break; default: - display_Clear(); - println_Msg(F("Please enable module")); - print_Error(F("in Cart_Reader.ino."), true); - break; + print_MissingModule(); // does not return } } #endif @@ -1498,7 +1497,7 @@ void clkcal() { if (!i2c_found) { display_Clear(); - print_Error(F("Clock Generator not found"), true); + print_FatalError(F("Clock Generator not found")); } //clockgen.set_correction(cal_factor, SI5351_PLL_INPUT_XO); @@ -1654,7 +1653,7 @@ void savetofile() { delay(2000); if (!myFile.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Write calibration factor to file myFile.print(cal_factor); @@ -1841,12 +1840,12 @@ void setup() { // Init SD card if (!sd.begin(SS)) { display_Clear(); - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } #ifdef global_log if (!myLog.open("OSCR_LOG.txt", O_RDWR | O_CREAT | O_APPEND)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } println_Msg(F("")); #if defined(HW1) @@ -1955,71 +1954,38 @@ void convertPgm(const char* const pgmOptions[], byte numArrays) { } } -void print_Error(const __FlashStringHelper* errorMessage, boolean forceReset) { +void _print_Error(void) { errorLvl = 1; setColor_RGB(255, 0, 0); + display_Update(); +} + +void print_Error(const __FlashStringHelper* errorMessage) { println_Msg(errorMessage); - display_Update(); - - if (forceReset) { - println_Msg(F("")); - 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); - } - } + _print_Error(); } -void print_Error(byte errorMessage, boolean forceReset) { - errorLvl = 1; - setColor_RGB(255, 0, 0); +void print_Error(byte errorMessage) { print_STR(errorMessage, 1); + _print_Error(); +} + +void _print_FatalError(void) { + println_Msg(F("")); + print_STR(press_button_STR, 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(); - 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); - } - } + wait(); + resetArduino(); } -void print_FatalError(const __FlashStringHelper* errorMessage) __attribute__ ((noreturn)); void print_FatalError(const __FlashStringHelper* errorMessage) { - print_Error(errorMessage, true); - // Redundant as print_Error already calls it, but makes gcc understand that - // this in fact does not return. - resetArduino(); + print_Error(errorMessage); + _print_FatalError(); } -void print_FatalError(byte errorMessage) __attribute__ ((noreturn)); void print_FatalError(byte errorMessage){ - print_Error(errorMessage, true); - // Redundant as print_Error already calls it, but makes gcc understand that - // this in fact does not return. - resetArduino(); + print_Error(errorMessage); + _print_FatalError(); } void wait() { @@ -2089,7 +2055,7 @@ void save_log() { strcpy(fileName, romName); strcat(fileName, ".txt"); if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } while (myLog.available()) { @@ -2486,7 +2452,7 @@ byte questionBox_Serial(const __FlashStringHelper* question, char answers[7][20] EEPROM_readAnything(0, foldern); sprintf(fileName, "IMPORT/%d.bin", foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } // Read file from serial @@ -2753,7 +2719,7 @@ void wait_serial() { myFile.close(); } else { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } }*/ } @@ -2903,15 +2869,6 @@ void wait_btn() { // get input button int b = checkButton(); -#ifdef enable_N64 -#ifndef clockgen_installed - // Send some clock pulses to the Eeprom in case it locked up - if ((mode == mode_N64_Cart) && ((saveType == 5) || (saveType == 6))) { - pulseClock_N64(1); - } -#endif -#endif - // if the cart readers input button is pressed shortly if (b == 1) { errorLvl = 0; @@ -3005,15 +2962,6 @@ void wait_btn() { // get input button int b = checkButton(); -#ifdef enable_N64 -#ifndef clockgen_installed - // Send some clock pulses to the Eeprom in case it locked up - if ((mode == mode_N64_Cart) && ((saveType == 5) || (saveType == 6))) { - pulseClock_N64(1); - } -#endif -#endif - // if the cart readers input button is pressed shortly if (b == 1) { errorLvl = 0; @@ -3045,15 +2993,6 @@ void wait_encoder() { encoder.tick(); int newPos = encoder.getPosition(); -#ifdef enable_N64 -#ifndef clockgen_installed - // Send some clock pulses to the Eeprom in case it locked up - if ((mode == mode_N64_Cart) && ((saveType == 5) || (saveType == 6))) { - pulseClock_N64(1); - } -#endif -#endif - if (rotaryPos != newPos) { rotaryPos = newPos; errorLvl = 0; @@ -3094,7 +3033,7 @@ browserstart: // Open filepath directory if (!myDir.open(filePath)) { display_Clear(); - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Count files in directory @@ -3120,7 +3059,7 @@ page: // Open filepath directory if (!myDir.open(filePath)) { display_Clear(); - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } int countFile = 0; diff --git a/Cart_Reader/FLASH.ino b/Cart_Reader/FLASH.ino index 50b6a0b..6eb30dd 100644 --- a/Cart_Reader/FLASH.ino +++ b/Cart_Reader/FLASH.ino @@ -569,7 +569,7 @@ idtheflash: println_Msg(F("")); display_Update(); resetFlash8(); - print_Error(F("Press Button to reset"), true); + print_FatalError(F("Press Button to reset")); } println_Msg(""); // Prints string out of the common strings array either with or without newline @@ -624,7 +624,7 @@ void id_Flash16() { flashSize = 8388608; flashromType = 2; } else { - print_Error(F("Unknown flashrom"), true); + print_FatalError(F("Unknown flashrom")); println_Msg(""); } println_Msg(""); @@ -1054,7 +1054,7 @@ void writeFlash29F032() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut(); @@ -1194,7 +1194,7 @@ void writeFlash29F1610() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut(); @@ -1248,7 +1248,7 @@ void writeFlash29F1601() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut(); @@ -1393,7 +1393,7 @@ void writeFlash29LV640() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut(); @@ -1440,7 +1440,7 @@ void writeFlash29GL(unsigned long sectorSize, byte bufferSize) { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut(); @@ -1507,7 +1507,7 @@ void writeFlash29F800() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut(); @@ -1612,7 +1612,7 @@ void writeFlash28FXXX() { void writeFlashE28FXXXJ3A() { fileSize = myFile.fileSize(); if (fileSize > flashSize) { - print_Error(file_too_big_STR, false); + print_Error(file_too_big_STR); return; } @@ -1663,7 +1663,7 @@ void writeFlashE28FXXXJ3A() { void writeFlashLH28F0XX() { fileSize = myFile.fileSize(); if (fileSize > flashSize) { - print_Error(file_too_big_STR, false); + print_Error(file_too_big_STR); return; } @@ -1718,7 +1718,7 @@ void blankcheck_Flash() { println_Msg(F("Flashrom is empty")); display_Update(); } else { - print_Error(F("Error: Not blank"), false); + print_Error(F("Error: Not blank")); } } @@ -1731,7 +1731,7 @@ void verifyFlash() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); blank = 0; for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) { @@ -1750,7 +1750,7 @@ void verifyFlash() { print_STR(error_STR, 0); print_Msg(blank); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } // Close the file: myFile.close(); @@ -1782,7 +1782,7 @@ void readFlash() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } for (unsigned long currByte = 0; currByte < flashSize; currByte += 512) { for (int c = 0; c < 512; c++) { @@ -1853,7 +1853,7 @@ void writeFlash16() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut16(); @@ -1911,7 +1911,7 @@ void writeFlash16_29F1601() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut16(); @@ -2031,7 +2031,7 @@ void blankcheck16() { println_Msg(F("Flashrom is empty.")); display_Update(); } else { - print_Error(F("Error: Not blank"), false); + print_Error(F("Error: Not blank")); } } @@ -2044,7 +2044,7 @@ void verifyFlash16() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) { - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); } blank = 0; @@ -2068,7 +2068,7 @@ void verifyFlash16() { } else { println_Msg(F("Verification ERROR!")); print_Msg(blank); - print_Error(F("B did not verify."), false); + print_Error(F("B did not verify.")); display_Update(); } // Close the file: @@ -2211,7 +2211,7 @@ void writeFlash16_29LV640() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Set data pins to output dataOut16(); @@ -2374,7 +2374,7 @@ void blankcheck_Eprom() { println_Msg(F("Flashrom is empty.")); display_Update(); } else { - print_Error(F("Error: Not blank"), false); + print_Error(F("Error: Not blank")); } } @@ -2438,7 +2438,7 @@ void write_Eprom() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); // Switch VPP/OE(PH5) to HIGH PORTH |= (1 << 5); @@ -2473,7 +2473,7 @@ void write_Eprom() { print_Msg(readWord_Eprom(currWord + c), HEX); print_Msg(F(" != 0x")); println_Msg(myWord, HEX); - print_Error(F("Press button to reset"), true); + print_FatalError(F("Press button to reset")); } n++; } while (checkWord != myWord); @@ -2497,7 +2497,7 @@ void verify_Eprom() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) { - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); } blank = 0; @@ -2521,7 +2521,7 @@ void verify_Eprom() { } else { println_Msg(F("Verification ERROR!")); print_Msg(blank); - print_Error(F(" words did not verify."), false); + print_Error(F(" words did not verify.")); display_Update(); } // Close the file: diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index 11317d4..128d885 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -240,7 +240,7 @@ void gbxMenu() { print_STR(error_STR, 0); print_Msg(wrErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } break; } @@ -250,7 +250,7 @@ void gbxMenu() { println_Msg(F("Error: No save found.")); } } else { - print_Error(F("Cart has no Sram"), false); + print_Error(F("Cart has no Sram")); } // Reset wait(); @@ -316,7 +316,7 @@ void gbMenu() { else readSRAM_GB(); } else { - print_Error(F("No save or unsupported type"), false); + print_Error(F("No save or unsupported type")); } println_Msg(F("")); break; @@ -343,11 +343,11 @@ void gbMenu() { print_STR(error_STR, 0); print_Msg(wrErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } } else { - print_Error(F("No save or unsupported type"), false); + print_Error(F("No save or unsupported type")); } println_Msg(F("")); break; @@ -547,7 +547,7 @@ void showCartInfo_GB() { display_Update(); wait(); } else { - print_Error(F("GAMEPAK ERROR"), true); + print_FatalError(F("GAMEPAK ERROR")); } } @@ -750,7 +750,7 @@ void getCartInfo_GB() { } if (logoChecksum != 0x1546) { - print_Error(F("STARTUP LOGO ERROR"), false); + print_Error(F("STARTUP LOGO ERROR")); println_Msg(F("")); println_Msg(F("")); println_Msg(F("")); @@ -781,7 +781,7 @@ void getCartInfo_GB() { } if (headerChecksum != sdBuffer[0x14D]) { - print_Error(F("HEADER CHECKSUM ERROR"), false); + print_Error(F("HEADER CHECKSUM ERROR")); println_Msg(F("")); println_Msg(F("")); println_Msg(F("")); @@ -960,7 +960,7 @@ void readROM_GB() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } word endAddress = 0x7FFF; @@ -1109,7 +1109,7 @@ unsigned int calc_checksum_GB(char* fileName) { } // Else show error else { - print_Error(F("DUMP ROM 1ST"), false); + print_Error(F("DUMP ROM 1ST")); return 0; } } @@ -1137,7 +1137,7 @@ void compare_checksums_GB() { } else { print_Msg(F(" != ")); println_Msg(checksumStr); - print_Error(F("Invalid Checksum"), false); + print_Error(F("Invalid Checksum")); } compareCRC("gb.txt", 0, 1, 0); display_Update(); @@ -1169,7 +1169,7 @@ void readSRAM_GB() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // MBC2 Fix @@ -1207,7 +1207,7 @@ void readSRAM_GB() { println_Msg(F("/")); display_Update(); } else { - print_Error(F("Cart has no SRAM"), false); + print_Error(F("Cart has no SRAM")); } } @@ -1250,10 +1250,10 @@ void writeSRAM_GB() { display_Update(); } else { - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } else { - print_Error(F("Cart has no SRAM"), false); + print_Error(F("Cart has no SRAM")); } } @@ -1300,7 +1300,7 @@ unsigned long verifySRAM_GB() { myFile.close(); return writeErrors; } else { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); return 1; } } @@ -1329,7 +1329,7 @@ void readSRAMFLASH_MBC6_GB() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } //Initialize progress bar @@ -1476,7 +1476,7 @@ void writeSRAMFLASH_MBC6_GB() { writeByte_GB(0x3800, 0x00); myFile.close(); display_Clear(); - print_Error(F("Error erasing FLASH sector."), true); + print_FatalError(F("Error erasing FLASH sector.")); } } } else { @@ -1515,7 +1515,7 @@ void writeSRAMFLASH_MBC6_GB() { writeByte_GB(0x3800, 0x00); myFile.close(); display_Clear(); - print_Error(F("Error writing to FLASH."), true); + print_FatalError(F("Error writing to FLASH.")); } } writeByte_GB(romAddress - 1, 0xF0); @@ -1536,7 +1536,7 @@ void writeSRAMFLASH_MBC6_GB() { println_Msg(F("Save writing finished")); display_Update(); } else { - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } @@ -1649,7 +1649,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) { sprintf(flashid_str, "%04X", flashid); println_Msg(flashid_str); display_Update(); - print_Error(F("Unknown flashrom"), true); + print_FatalError(F("Unknown flashrom")); } // Reset flash @@ -1696,7 +1696,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) { for (int j = 0; j < 512; j++) { if (sdBuffer[j] != 0xFF) { println_Msg(F("Not empty")); - print_Error(F("Erase failed"), true); + print_FatalError(F("Erase failed")); } } } @@ -1852,7 +1852,7 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) { println_Msg(F("Error")); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, true); + print_FatalError(did_not_verify_STR); } } else { print_STR(open_file_STR, 1); @@ -2095,7 +2095,7 @@ bool writeCFI_GB() { for (int j = 0; j < 512; j++) { if (sdBuffer[j] != 0xFF) { println_Msg(F("Not empty")); - print_Error(F("Erase failed"), true); + print_FatalError(F("Erase failed")); } } } @@ -2212,7 +2212,7 @@ bool writeCFI_GB() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { print_STR(open_file_STR, 1); diff --git a/Cart_Reader/GBA.ino b/Cart_Reader/GBA.ino index 0640b4b..1feb4bb 100644 --- a/Cart_Reader/GBA.ino +++ b/Cart_Reader/GBA.ino @@ -161,7 +161,7 @@ void gbaMenu() { printFlashTypeAndWait(F("Panasonic MN63F805MNP")); } else { printFlashTypeAndWait(F("Unknown")); - //print_Error(F(""), true); + //print_FatalError(F("")); } if (flashid == 0x1F3D) { // Atmel @@ -187,7 +187,7 @@ void gbaMenu() { printFlashTypeAndWait(F("SANYO LE26FV10N1TS")); } else { printFlashTypeAndWait(F("Unknown")); - //print_Error(F(""), true); + //print_FatalError(F("")); } eraseFLASH_GBA(); @@ -593,7 +593,7 @@ void getCartInfo_GBA() { if (logoChecksum != 0x4B1B) { display_Clear(); - print_Error(F("CARTRIDGE ERROR"), false); + print_Error(F("CARTRIDGE ERROR")); strcpy(romName, "ERROR"); println_Msg(F("")); println_Msg(F("")); @@ -755,7 +755,7 @@ void getCartInfo_GBA() { dont_log = false; #endif } else { - print_Error(F("GBA.txt missing"), true); + print_FatalError(F("GBA.txt missing")); } // Get name @@ -780,7 +780,7 @@ void getCartInfo_GBA() { // Turn into string sprintf(calcChecksumStr, "%02X", calcChecksum); println_Msg(calcChecksumStr); - print_Error(F("Checksum Error"), false); + print_Error(F("Checksum Error")); println_Msg(F("")); // Prints string out of the common strings array either with or without newline print_STR(press_button_STR, 1); @@ -865,7 +865,7 @@ void readROM_GBA() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } //Initialize progress bar @@ -927,13 +927,13 @@ boolean compare_checksum_GBA() { } else { print_Msg(F(" != ")); println_Msg(checksumStr); - print_Error(F("Invalid Checksum"), false); + print_Error(F("Invalid Checksum")); return 0; } } // Else show error else { - print_Error(F("Failed to open rom"), false); + print_Error(F("Failed to open rom")); return 0; } } @@ -966,7 +966,7 @@ void readSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Seek to a new position in the file @@ -1022,7 +1022,7 @@ void writeSRAM_GBA(boolean browseFile, unsigned long sramSize, uint32_t pos) { display_Update(); } else { - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } @@ -1057,12 +1057,12 @@ unsigned long verifySRAM_GBA(unsigned long sramSize, uint32_t pos) { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } return writeErrors; } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); return 1; } } @@ -1106,7 +1106,7 @@ void readFRAM_GBA(unsigned long framSize) { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } for (unsigned long currAddress = 0; currAddress < framSize; currAddress += 512) { for (int c = 0; c < 512; c++) { @@ -1209,7 +1209,7 @@ void writeFRAM_GBA(boolean browseFile, unsigned long framSize) { display_Update(); } else { - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } @@ -1270,7 +1270,7 @@ unsigned long verifyFRAM_GBA(unsigned long framSize) { myFile.close(); return writeErrors; } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); return 1; } } @@ -1461,7 +1461,7 @@ boolean blankcheckFLASH_GBA(unsigned long flashSize) { // Check buffer for (unsigned long currByte = 0; currByte < 512; currByte++) { if (sdBuffer[currByte] != 0xFF) { - print_Error(F("Erase failed"), false); + print_Error(F("Erase failed")); currByte = 512; currAddress = flashSize; blank = 0; @@ -1539,7 +1539,7 @@ void readFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos) { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Seek to a new position in the file @@ -1657,7 +1657,7 @@ void writeFLASH_GBA(boolean browseFile, unsigned long flashSize, uint32_t pos, b } else { println_Msg(F("Error")); - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } @@ -1684,7 +1684,7 @@ unsigned long verifyFLASH_GBA(unsigned long flashSize, uint32_t pos) { //open file on sd card if (!myFile.open(filePath, O_READ)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Seek to a new position in the file @@ -1710,7 +1710,7 @@ unsigned long verifyFLASH_GBA(unsigned long flashSize, uint32_t pos) { println_Msg(F("OK")); } else { print_Msg(wrError); - print_Error(F(" Errors"), false); + print_Error(F(" Errors")); } return wrError; @@ -1753,7 +1753,7 @@ void writeEeprom_GBA(word eepSize) { display_Update(); } else { println_Msg(F("Error")); - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } @@ -1782,7 +1782,7 @@ void readEeprom_GBA(word eepSize) { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Each block contains 8 Bytes, so for a 8KB eeprom 1024 blocks need to be read @@ -2024,7 +2024,7 @@ unsigned long verifyEEP_GBA(word eepSize) { //open file on sd card if (!myFile.open(filePath, O_READ)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Fill sd Buffer @@ -2050,7 +2050,7 @@ unsigned long verifyEEP_GBA(word eepSize) { print_STR(error_STR, 0); print_Msg(wrError); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } return wrError; @@ -2134,7 +2134,7 @@ void idFlashrom_GBA() { print_Msg(F("Flash ID: ")); println_Msg(flashid_str); println_Msg(F("")); - print_Error(F("Check voltage"), true); + print_FatalError(F("Check voltage")); } } } @@ -2532,7 +2532,7 @@ boolean verifyFlashrom_GBA() { return 0; } } else { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); return 9999; } } @@ -2561,7 +2561,7 @@ void flashRepro_GBA() { } else { print_Msg(F("romType: 0x")); println_Msg(romType, HEX); - print_Error(F("Unknown manufacturer"), true); + print_FatalError(F("Unknown manufacturer")); } } // Intel 4000L0YBQ0 @@ -2614,7 +2614,7 @@ void flashRepro_GBA() { resetIntel_GBA(0x200000); } else if (flashid == 0x227E) { //if (sectorCheckMX29GL128E_GBA()) { - //print_Error(F("Sector Protected"), true); + //print_FatalError(F("Sector Protected")); //} //else { println_Msg(F("Erasing...")); @@ -2680,16 +2680,16 @@ void flashRepro_GBA() { println_Msg(F("OK")); display_Update(); } else { - print_Error(F("ERROR"), true); + print_FatalError(F("ERROR")); } /* Skipped blankcheck } else { - print_Error(F("failed"), true); + print_FatalError(F("failed")); } */ } else { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } } else { println_Msg(F("Error")); @@ -2698,7 +2698,7 @@ void flashRepro_GBA() { print_Msg(F("Flash ID: ")); println_Msg(flashid_str); println_Msg(F("")); - print_Error(F("Check voltage"), true); + print_FatalError(F("Check voltage")); } } diff --git a/Cart_Reader/GBM.ino b/Cart_Reader/GBM.ino index dc2ff50..e26fa97 100644 --- a/Cart_Reader/GBM.ino +++ b/Cart_Reader/GBM.ino @@ -165,7 +165,7 @@ void gbmMenu() { println_Msg(F("OK")); display_Update(); } else { - print_Error(F("Erasing failed"), false); + print_Error(F("Erasing failed")); break; } @@ -235,7 +235,7 @@ void setup_GBM() { timeout++; if (timeout > 10) { println_Msg(F("Error: Time Out")); - print_Error(F("Please power cycle"), true); + print_FatalError(F("Please power cycle")); } } } @@ -337,7 +337,7 @@ void readROM_GBM(word numBanks) { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } else { // Read rom word currAddress = 0; @@ -439,7 +439,7 @@ void send_GBM(byte myCommand) { break; default: - print_Error(F("Unknown Command"), true); + print_FatalError(F("Unknown Command")); break; } } @@ -459,7 +459,7 @@ void send_GBM(byte myCommand, word myAddress, byte myData) { break; default: - print_Error(F("Unknown Command"), true); + print_FatalError(F("Unknown Command")); break; } } @@ -508,7 +508,7 @@ boolean readFlashID_GBM() { } else { print_Msg(F("Flash ID: ")); println_Msg(flashid_str); - print_Error(F("Unknown Flash ID"), true); + print_FatalError(F("Unknown Flash ID")); resetFlash_GBM(); return 0; } @@ -592,7 +592,7 @@ void writeFlash_GBM() { // Get rom size from file fileSize = myFile.fileSize(); if ((fileSize / 0x4000) > 64) { - print_Error(F("File is too big."), true); + print_FatalError(F("File is too big.")); } // Enable access to ports 0120h @@ -685,7 +685,7 @@ void writeFlash_GBM() { myFile.close(); print_STR(done_STR, 1); } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); } } @@ -722,7 +722,7 @@ void readMapping_GBM() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } else { for (byte currByte = 0; currByte < 128; currByte++) { sdBuffer[currByte] = readByte_GBM(currByte); @@ -821,7 +821,7 @@ void writeMapping_GBM() { if (myFile.open(filePath, O_READ)) { // Get map file size and check if it exceeds 128KByte if (myFile.fileSize() > 0x80) { - print_Error(F("File is too big."), true); + print_FatalError(F("File is too big.")); } // Enable access to ports 0120h @@ -899,7 +899,7 @@ void writeMapping_GBM() { myFile.close(); print_STR(done_STR, 1); } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); } } diff --git a/Cart_Reader/GBS.ino b/Cart_Reader/GBS.ino index 71fb01b..403acdd 100644 --- a/Cart_Reader/GBS.ino +++ b/Cart_Reader/GBS.ino @@ -72,7 +72,7 @@ boolean compare_checksum_GBS() { } else { print_Msg(F("Result: ")); println_Msg(calcsumStr); - print_Error(F("Checksum Error"), false); + print_Error(F("Checksum Error")); return 0; } } @@ -206,7 +206,7 @@ void gbSmartGameOptions() { print_STR(error_STR, 0); print_Msg(wrErrors); println_Msg(F(" bytes")); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } break; } @@ -400,7 +400,7 @@ void gbSmartReadFlash() { display_Update(); if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); // reset flash to read array state for (uint16_t i = 0x00; i < gbSmartBanks; i += gbSmartBanksPerFlashChip) @@ -456,7 +456,7 @@ void gbSmartWriteFlash() { display_Update(); if (!gbSmartBlankCheckingFlash(bank)) - print_Error(F("Could not erase flash"), true); + print_FatalError(F("Could not erase flash")); println_Msg(F("Passed")); display_Update(); @@ -479,13 +479,13 @@ void gbSmartWriteFlash() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, true); + print_FatalError(did_not_verify_STR); } } void gbSmartWriteFlash(uint32_t start_bank) { if (!myFile.open(filePath, O_READ)) - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); // switch to flash base bank gbSmartRemapStartBank(start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB); @@ -546,7 +546,7 @@ uint32_t gbSmartVerifyFlash() { if (!myFile.open(filePath, O_READ)) { verified = 0xffffffff; - print_Error(F("Can't open file on SD"), false); + print_Error(F("Can't open file on SD")); } else { // remaps mmc to full access gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB); diff --git a/Cart_Reader/INTV.ino b/Cart_Reader/INTV.ino index 952b979..c220e47 100644 --- a/Cart_Reader/INTV.ino +++ b/Cart_Reader/INTV.ino @@ -323,7 +323,7 @@ void readROM_INTV() { // open file on sdcard if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); // write new folder number back to EEPROM foldern++; @@ -938,7 +938,7 @@ void setCart_INTV() { } } } else { - print_Error(F("Database file not found"), true); + print_FatalError(F("Database file not found")); } } #endif diff --git a/Cart_Reader/MD.ino b/Cart_Reader/MD.ino index ad58d4c..90f863a 100644 --- a/Cart_Reader/MD.ino +++ b/Cart_Reader/MD.ino @@ -255,7 +255,7 @@ void mdMenu() { println_Msg(F("MX29F1610 detected")); flashSize = 2097152; } else { - print_Error(F("Error: Unknown flashrom"), true); + print_FatalError(F("Error: Unknown flashrom")); } display_Update(); @@ -307,7 +307,7 @@ void mdCartMenu() { readROM_MD(); } } else { - print_Error(F("Cart has no ROM"), false); + print_Error(F("Cart has no ROM")); } #ifdef global_log save_log(); @@ -326,7 +326,7 @@ void mdCartMenu() { readSram_MD(); enableSram_MD(0); } else { - print_Error(F("Cart has no Sram"), false); + print_Error(F("Cart has no Sram")); } break; @@ -350,10 +350,10 @@ void mdCartMenu() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { - print_Error(F("Cart has no Sram"), false); + print_Error(F("Cart has no Sram")); } break; @@ -362,7 +362,7 @@ void mdCartMenu() { if (saveType == 4) readEEP_MD(); else { - print_Error(F("Cart has no EEPROM"), false); + print_Error(F("Cart has no EEPROM")); } break; @@ -374,7 +374,7 @@ void mdCartMenu() { display_Clear(); writeEEP_MD(); } else { - print_Error(F("Cart has no EEPROM"), false); + print_Error(F("Cart has no EEPROM")); } break; @@ -417,7 +417,7 @@ void segaCDMenu() { if (bramSize > 0) readBram_MD(); else { - print_Error(F("Not CD Backup RAM Cart"), false); + print_Error(F("Not CD Backup RAM Cart")); } break; @@ -429,7 +429,7 @@ void segaCDMenu() { display_Clear(); writeBram_MD(); } else { - print_Error(F("Not CD Backup RAM Cart"), false); + print_Error(F("Not CD Backup RAM Cart")); } break; @@ -882,7 +882,7 @@ void getCartInfo_MD() { print_Msg(("sramEnd: ")); print_Msg_PaddedHex32(sramEnd); println_Msg(F("")); - print_Error(F("Unknown Sram Base"), true); + print_FatalError(F("Unknown Sram Base")); } } else if (sramType == 0xE020) { // SRAM BOTH BYTES // Get sram start and end @@ -907,7 +907,7 @@ void getCartInfo_MD() { print_Msg(("sramEnd: ")); print_Msg_PaddedHex32(sramEnd); println_Msg(F("")); - print_Error(F("Unknown Sram Base"), true); + print_FatalError(F("Unknown Sram Base")); } } } else { @@ -1164,7 +1164,7 @@ void readROM_MD() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } byte buffer[1024] = { 0 }; @@ -1371,7 +1371,7 @@ void readROM_MD() { char calcsumStr[5]; sprintf(calcsumStr, "%04X", calcCKS); println_Msg(calcsumStr); - print_Error(F(""), false); + print_Error(F("")); display_Update(); } @@ -1392,7 +1392,7 @@ void readROM_MD() { char calcsumStr[5]; sprintf(calcsumStr, "%04X", calcCKSLockon); println_Msg(calcsumStr); - print_Error(F(""), false); + print_Error(F("")); display_Update(); } } @@ -1405,7 +1405,7 @@ void readROM_MD() { char calcsumStr[5]; sprintf(calcsumStr, "%04X", calcCKSSonic2); println_Msg(calcsumStr); - print_Error(F(""), false); + print_Error(F("")); display_Update(); } } @@ -1483,14 +1483,14 @@ void writeSram_MD() { writeWord_MD(currByte, data); } } else - print_Error(F("Unknown save type"), false); + print_Error(F("Unknown save type")); // Close the file: myFile.close(); print_STR(done_STR, 1); display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } dataIn_MD(); } @@ -1515,7 +1515,7 @@ void readSram_MD() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } for (unsigned long currBuffer = sramBase; currBuffer < sramBase + sramSize; currBuffer += 256) { @@ -1609,7 +1609,7 @@ unsigned long verifySram_MD() { // Close the file: myFile.close(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Return 0 if verified ok, or number of errors return writeErrors; @@ -1645,7 +1645,7 @@ void write29F1610_MD() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) { - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); } // Set data pins to output dataOut_MD(); @@ -1754,7 +1754,7 @@ void blankcheck_MD() { } } if (!blank) { - print_Error(F("Error: Not blank"), false); + print_Error(F("Error: Not blank")); } } @@ -1764,7 +1764,7 @@ void verifyFlash_MD() { // Get rom size from file fileSize = myFile.fileSize(); if (fileSize > flashSize) { - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); } blank = 0; @@ -1792,7 +1792,7 @@ void verifyFlash_MD() { print_STR(error_STR, 0); print_Msg(blank); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } // Close the file: myFile.close(); @@ -2382,7 +2382,7 @@ void readEEP_MD() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } if (eepSize > 0x100) { // 24C04+ for (word currByte = 0; currByte < eepSize; currByte += 256) { @@ -2451,7 +2451,7 @@ void writeEEP_MD() { print_STR(done_STR, 1); display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } dataIn_MD(); } @@ -2481,7 +2481,7 @@ void readBram_MD() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } for (unsigned long currByte = 0; currByte < bramSize; currByte += 512) { @@ -2530,7 +2530,7 @@ void writeBram_MD() { print_STR(done_STR, 1); display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } dataIn_MD(); } @@ -2579,7 +2579,7 @@ void readRealtec_MD() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Realtec Registers diff --git a/Cart_Reader/N64.ino b/Cart_Reader/N64.ino index 8d540ba..1db1afe 100644 --- a/Cart_Reader/N64.ino +++ b/Cart_Reader/N64.ino @@ -18,15 +18,9 @@ Variables *****************************************/ // Received N64 Eeprom data bits, 1 page -bool tempBits[65]; int eepPages; // N64 Controller -// 256 bits of received Controller data + 8 bit CRC -char N64_raw_dump[265]; -// Array that holds one Controller Pak block of 32 bytes data -byte myBlock[33]; -String rawStr = ""; // above char array read into a string struct { char stick_x; char stick_y; @@ -50,6 +44,9 @@ String CRC1 = ""; String CRC2 = ""; #endif +static const char N64_EEP_FILENAME_FMT[] PROGMEM = "%s.eep"; +static const char N64_SAVE_DIRNAME_FMT[] PROGMEM = "N64/SAVE/%s/%d"; + /****************************************** Menu *****************************************/ @@ -259,13 +256,9 @@ void n64CartMenu() { } else if ((saveType == 5) || (saveType == 6)) { println_Msg(F("Reading EEPROM...")); display_Update(); -#ifdef clockgen_installed readEeprom(); -#else - readEeprom_CLK(); -#endif } else { - print_Error(F("Savetype Error"), false); + print_Error(F("Savetype Error")); } println_Msg(F("")); // Prints string out of the common strings array either with or without newline @@ -291,7 +284,7 @@ void n64CartMenu() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else if (saveType == 4) { // Launch file browser @@ -310,20 +303,15 @@ void n64CartMenu() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else if ((saveType == 5) || (saveType == 6)) { // Launch file browser fileBrowser(F("Select eep file")); display_Clear(); -#ifdef clockgen_installed writeEeprom(); writeErrors = verifyEeprom(); -#else - writeEeprom_CLK(); - writeErrors = verifyEeprom_CLK(); -#endif if (writeErrors == 0) { println_Msg(F("EEPROM verified OK")); @@ -332,11 +320,11 @@ void n64CartMenu() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { display_Clear(); - print_Error(F("Save Type Error"), false); + print_Error(F("Save Type Error")); } // Prints string out of the common strings array either with or without newline print_STR(press_button_STR, 1); @@ -425,7 +413,7 @@ void setup_N64_Cart() { if (!i2c_found) { display_Clear(); - print_Error(F("Clock Generator not found"), true); + print_FatalError(F("Clock Generator not found")); } // Set Eeprom clock to 2Mhz @@ -597,35 +585,25 @@ void writeWord_N64(word myWord) { N64 Controller CRC Functions *****************************************/ static word addrCRC(word address) { - // CRC table - word xor_table[16] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x1F, 0x0B, 0x16, 0x19, 0x07, 0x0E, 0x1C, 0x0D, 0x1A, 0x01 }; - word crc = 0; - // Make sure we have a valid address - address &= ~0x1F; - // Go through each bit in the address, and if set, xor the right value into the output - for (int i = 15; i >= 5; i--) { - // Is this bit set? - if (((address >> i) & 0x1)) { - crc ^= xor_table[i]; + const char n64_address_crc_table[] = { 0x15, 0x1F, 0x0B, 0x16, 0x19, 0x07, 0x0E, 0x1C, 0x0D, 0x1A, 0x01 }; + const char *cur_xor = n64_address_crc_table; + byte crc = 0; + for (word mask = 0x0020; mask; mask <<= 1, cur_xor++) { + if (address & mask) { + crc ^= *cur_xor; } } - // Just in case - crc &= 0x1F; - // Create a new address with the CRC appended - return address | crc; + return (address & 0xFFE0) | crc; } static uint8_t dataCRC(uint8_t* data) { uint8_t ret = 0; - for (int i = 0; i <= 32; i++) { - for (int j = 7; j >= 0; j--) { - int tmp = 0; - if (ret & 0x80) { - tmp = 0x85; - } + for (uint8_t i = 0; i <= 32; i++) { + for (uint8_t mask = 0x80; mask; mask >>= 1) { + uint8_t tmp = ret & 0x80 ? 0x85 : 0; ret <<= 1; if (i < 32) { - if (data[i] & (0x01 << j)) { + if (data[i] & mask) { ret |= 0x1; } } @@ -635,157 +613,301 @@ static uint8_t dataCRC(uint8_t* data) { return ret; } +// Macro producing a delay loop waiting an number of cycles multiple of 3, with +// a range of 3 to 768 cycles (187.5ns to 48us). It takes 6 bytes to do so +// (3 instructions) making it the same size as the equivalent 3-cycles NOP +// delay. For shorter delays or non-multiple-of-3-cycle delays, add your own +// NOPs. +#define N64_DELAY_LOOP(cycle_count) do { \ + byte i; \ + __asm__ __volatile__ ("\n" \ + "\tldi %[i], %[loop_count]\n" \ + ".delay_loop_%=:\n" \ + "\tdec %[i]\n" \ + "\tbrne .delay_loop_%=\n" \ + : [i] "=r" (i) \ + : [loop_count] "i" (cycle_count / 3) \ + : "cc" \ + ); \ +} while(0) + /****************************************** N64 Controller Protocol Functions *****************************************/ -void N64_send(unsigned char* buffer, char length) { - // Send these bytes - char bits; +void sendJoyBus(const byte *buffer, char length) { + // Implemented in assembly as there is very little wiggle room, timing-wise. + // Overall structure: + // outer_loop: + // mask = 0x80 + // cur_byte = *(buffer++) + // inner_loop: + // falling edge + // if (cur_byte & mask) { + // wait 1us starting at the falling edge + // rising edge + // wait 2us starting at the rising edge + // } else { + // wait 3us starting at the falling edge + // rising edge + // } + // inner_common_codepath: + // mask >>= 1 + // if (mask == 0) + // goto outer_loop_trailer + // wait +1us from the rising edge + // goto inner_loop + // outer_loop_trailer: + // length -= 1 + // if (length == 0) + // goto stop_bit + // wait +1us from the rising edge + // goto outer_loop + // stop_bit: + // wait +1us from the rising edge + // falling edge + // wait 1us from the falling edge + // rising edge - // This routine is very carefully timed by examining the assembly output. - // Do not change any statements, it could throw the timings off - // - // We get 16 cycles per microsecond, which should be plenty, but we need to - // be conservative. Most assembly ops take 1 cycle, but a few take 2 - // - // I use manually constructed for-loops out of gotos so I have more control - // over the outputted assembly. I can insert nops where it was impossible - // with a for loop + byte mask, cur_byte, scratch; + // Note on DDRH: retrieve the current DDRH value, and pre-compute the values + // to write in order to drive the line high or low. This saves 3 cycles per + // transition: sts (2 cycles) instead of lds, or/and, sts (2 + 1 + 2 cycles). + // This means that no other code may run in parallel, but this function anyway + // requires interrupts to be disabled in order to work in the expected amount + // of time. + const byte line_low = DDRH | 0x10; + const byte line_high = line_low & 0xef; + __asm__ __volatile__("\n" + ".outer_loop_%=:\n" + // mask = 0x80 + "\tldi %[mask], 0x80\n" // 1 + // load byte to send from memory + "\tld %[cur_byte], Z+\n" // 2 + ".inner_loop_%=:\n" + // Falling edge + "\tsts %[out_byte], %[line_low]\n" // 2 + // Test cur_byte & mask, without clobbering either + "\tmov %[scratch], %[cur_byte]\n" // 1 + "\tand %[scratch], %[mask]\n" // 1 + "\tbreq .bit_is_0_%=\n" // bit is 1: 1, bit is 0: 2 - asm volatile(";Starting outer for loop"); -outer_loop: - { - asm volatile(";Starting inner for loop"); - bits = 8; -inner_loop: - { - // Starting a bit, set the line low - asm volatile(";Setting line to low"); - N64_LOW; // 1 op, 2 cycles + // bit is a 1 + // Stay low for 1us (16 cycles). + // Time before: 3 cycles (mov, and, breq-false). + // Time after: sts (2 cycles). + // So 11 to go, so 3 3-cycles iterations and 2 nop. + "\tldi %[scratch], 3\n" // 1 + ".delay_1_low_%=:\n" + "\tdec %[scratch]\n" // 1 + "\tbrne .delay_1_low_%=\n" // exit: 1, loop: 2 + "\tnop\n" // 1 + "\tnop\n" // 1 + // Rising edge + "\tsts %[out_byte], %[line_high]\n" // 2 + // Wait for 2us (32 cycles) to sync with the bot_is_0 codepath. + // Time before: 0 cycles. + // Time after: 2 cycles (rjmp). + // So 30 to go, so 10 3-cycles iterations and 0 nop. + "\tldi %[scratch], 10\n" // 1 + ".delay_1_high_%=:\n" + "\tdec %[scratch]\n" // 1 + "\tbrne .delay_1_high_%=\n" // exit: 1, loop: 2 + "\trjmp .inner_common_path_%=\n" // 2 - asm volatile(";branching"); - if (*buffer >> 7) { - asm volatile(";Bit is a 1"); - // 1 bit - // remain low for 1us, then go high for 3us - // nop block 1 - asm volatile("nop\nnop\nnop\nnop\nnop\n"); + ".bit_is_0_%=:\n" + // bit is a 0 + // Stay high for 3us (48 cycles). + // Time before: 4 cycles (mov, and, breq-true). + // Time after: 2 cycles (sts). + // So 42 to go, so 14 3-cycles iterations, and 0 nop. + "\tldi %[scratch], 14\n" // 1 + ".delay_0_low_%=:\n" + "\tdec %[scratch]\n" // 1 + "\tbrne .delay_0_low_%=\n" // exit: 1, loop: 2 + // Rising edge + "\tsts %[out_byte], %[line_high]\n" // 2 - asm volatile(";Setting line to high"); - N64_HIGH; + // codepath common to both possible values + ".inner_common_path_%=:\n" + "\tnop\n" // 1 + "\tlsr %[mask]\n" // 1 + "\tbreq .outer_loop_trailer_%=\n" // mask!=0: 1, mask==0: 2 + // Stay high for 1us (16 cycles). + // Time before: 3 cycles (nop, lsr, breq-false). + // Time after: 4 cycles (rjmp, sts) + // So 9 to go, so 3 3-cycles iterations and 0 nop. + "\tldi %[scratch], 3\n" // 1 + ".delay_common_high_%=:\n" + "\tdec %[scratch]\n" // 1 + "\tbrne .delay_common_high_%=\n" // exit: 1, loop: 2 + "\trjmp .inner_loop_%=\n" // 2 - // nop block 2 - // we'll wait only 2us to sync up with both conditions - // at the bottom of the if statement - asm volatile("nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n"); - - } else { - asm volatile(";Bit is a 0"); - // 0 bit - // remain low for 3us, then go high for 1us - // nop block 3 - asm volatile("nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\n"); - - asm volatile(";Setting line to high"); - N64_HIGH; - - // wait for 1us - asm volatile("; end of conditional branch, need to wait 1us more before next bit"); - } - // end of the if, the line is high and needs to remain - // high for exactly 16 more cycles, regardless of the previous - // branch path - - asm volatile(";finishing inner loop body"); - --bits; - if (bits != 0) { - // nop block 4 - // this block is why a for loop was impossible - asm volatile("nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\n"); - // rotate bits - asm volatile(";rotating out bits"); - *buffer <<= 1; - - goto inner_loop; - } // fall out of inner loop - } - asm volatile(";continuing outer loop"); - // In this case: the inner loop exits and the outer loop iterates, - // there are /exactly/ 16 cycles taken up by the necessary operations. - // So no nops are needed here (that was lucky!) - --length; - if (length != 0) { - ++buffer; - goto outer_loop; - } // fall out of outer loop - } + ".outer_loop_trailer_%=:\n" + "\tdec %[length]\n" // 1 + "\tbreq .stop_bit_%=\n" // length!=0: 1, length==0: 2 + // Stay high for 1us (16 cycles). + // Time before: 6 cycles (lsr, nop, breq-true, dec, breq-false). + // Time after: 7 cycles (rjmp, ldi, ld, sts). + // So 3 to go, so 3 nop (for simplicity). + "\tnop\n" // 1 + "\tnop\n" // 1 + "\tnop\n" // 1 + "\trjmp .outer_loop_%=\n" // 2 + // Done sending data, send a stop bit. + ".stop_bit_%=:\n" + // Stay high for 1us (16 cycles). + // Time before: 7 cycles (lsr, nop, breq-true, dec, breq-true). + // Time after: 2 cycles (sts). + // So 7 to go, so 2 3-cycles iterations and 1 nop. + "\tldi %[scratch], 2\n" // 1 + ".delay_stop_high_%=:\n" + "\tdec %[scratch]\n" // 1 + "\tbrne .delay_stop_high_%=\n" // exit: 1, loop: 2 + "\tnop\n" + "\tsts %[out_byte], %[line_low]\n" // 2 + // Stay low for 1us (16 cycles). + // Time before: 0 cycles. + // Time after: 2 cycles (sts). + // So 14 to go, so 4 3-cycles iterations and 2 nop. + "\tldi %[scratch], 5\n" // 1 + ".delay_stop_low_%=:\n" + "\tdec %[scratch]\n" // 1 + "\tbrne .delay_stop_low_%=\n" // exit: 1, loop: 2 + "\tnop\n" + "\tnop\n" + "\tsts %[out_byte], %[line_high]\n" // 2 + // Notes on arguments: + // - mask and scratch are used wth "ldi", which can only work on registers + // 16 to 31, so tag these with "a" rather than the generic "r" + // - mark all output-only arguments as early-clobber ("&"), as input + // registers are used throughout all iterations and both sets must be + // strictly distinct + // - tag buffer with "z", to use the "ld r?, Z+" instruction (load from + // 16bits RAM address and postincrement, in 2 cycles). + // XXX: any pointer register pair would do, but mapping to Z explicitly + // because I cannot find a way to get one of "X", "Y" or "Z" to appear + // when expanding "%[buffer]", causing the assembler to reject the + // instruction. Pick Z as it is the only call-used such register, + // avoiding the need to preserve any value a caller may have set it to. + : [buffer] "+z" (buffer), + [length] "+r" (length), + [cur_byte] "=&r" (cur_byte), + [mask] "=&a" (mask), + [scratch] "=&a" (scratch) + : [line_low] "r" (line_low), + [line_high] "r" (line_high), + [out_byte] "i" (&DDRH) + : "cc", "memory" + ); } -void N64_stop() { - // send a single stop (1) bit - // nop block 5 - asm volatile("nop\nnop\nnop\nnop\n"); - N64_LOW; - // wait 1 us, 16 cycles, then raise the line - // 16-2=14 - // nop block 6 - asm volatile("nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\n"); - N64_HIGH; -} +word recvJoyBus(byte *output, byte byte_count) { + // listen for expected byte_count bytes of data back from the controller + // return the number of bytes not (fully) received if the delay for a signal + // edge takes too long. -void N64_get(word bitcount) { - // listen for the expected bitcount/8 bytes of data back from the controller and - // blast it out to the N64_raw_dump array, one bit per byte for extra speed. - asm volatile(";Starting to listen"); - unsigned char timeout; - char* bitbin = N64_raw_dump; + // Implemented in assembly as there is very little wiggle room, timing-wise. + // Overall structure: + // mask = 0x80 + // cur_byte = 0 + // read_loop: + // wait for falling edge + // wait for a bit more than 1us + // if input: + // cur_byte |= mask + // mask >>= 1 + // if (mask == 0) + // if (--byte_count == 0) + // goto read_end + // append cur_byte to output + // mask = 0x80 + // cur_byte = 0 + // wait for data high + // goto read_loop + // read_end: + // return byte_count - // Again, using gotos here to make the assembly more predictable and - // optimization easier (please don't kill me) -read_loop: - timeout = 0x3f; - // wait for line to go low - while (N64_QUERY) { - if (!--timeout) - return; - } - // wait approx 2us and poll the line - asm volatile( - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n" - "nop\nnop\nnop\nnop\nnop\n"); - *bitbin = N64_QUERY; - ++bitbin; - --bitcount; - if (bitcount == 0) - return; + byte mask, cur_byte, timeout, scratch; + __asm__ __volatile__("\n" + "\tldi %[mask], 0x80\n" + "\tclr %[cur_byte]\n" + ".read_loop_%=:\n" + // Wait for input to be low. Time out if it takes more than ~27us (~7 bits + // worth of time) for it to go low. + // Takes 5 cycles to exit on input-low iteration (lds, sbrs-false, rjmp). + // Takes 7 cycles to loop on input-high iteration (lds, sbrs-true, dec, + // brne-true). + "\tldi %[timeout], 0x3f\n" // 1 + ".read_wait_falling_edge_%=:\n" + "\tlds %[scratch], %[in_byte]\n" // 2 + "\tsbrs %[scratch], %[in_bit]\n" // low: 1, high: 2 + "\trjmp .read_input_low_%=\n" // 2 + "\tdec %[timeout]\n" // 1 + "\tbrne .read_wait_falling_edge_%=\n" // timeout==0: 1, timeout!=0: 2 + "\trjmp .read_end_%=\n" // 2 - // wait for line to go high again - // it may already be high, so this should just drop through - timeout = 0x3f; - while (!N64_QUERY) { - if (!--timeout) - return; - } - goto read_loop; + ".read_input_low_%=:\n" + // Wait for 1500 us (24 cycles) before reading input. + // As it takes from 5 to 7 cycles for the prevous loop to exit, + // this means this loop exits from 1812.5us to 1937.5us after the falling + // edge, so at least 812.5us after a 1-bit rising edge, and at least + // 1062.5us before a 0-bit rising edge. + // This also leaves us with up to 2062.5us (33 cycles) to update cur_byte, + // possibly moving on to the next byte, waiting for a high input, and + // waiting for the next falling edge. + // Time taken until waiting for input high for non-last byte: + // - shift to current byte: + // - 1: 4 cycles (lds, sbrc-false, or) + // - 0: 4 cycles (lds, sbrc-true) + // - byte done: 8 cycles (lsr, brne-false, st, dec, brne-false, ldi, clr) + // - byte not done: 3 cycles (lsr, brne-true) + // Total: 7 to 12 cycles, so there are at least 21 cycles left until the + // next bit. + "\tldi %[timeout], 8\n" // 1 + ".read_wait_low_%=:\n" + "\tdec %[timeout]\n" // 1 + "\tbrne .read_wait_low_%=\n" // timeout=0: 1, timeout!=0: 2 + + // Sample input + "\tlds %[scratch], %[in_byte]\n" // 2 + // Add to cur_byte + "\tsbrc %[scratch], %[in_bit]\n" // high: 1, low: 2 + "\tor %[cur_byte], %[mask]\n" // 1 + // Shift mask + "\tlsr %[mask]\n" + "\tbrne .read_wait_input_high_init_%=\n" // mask==0: 1, mask!=0: 2 + // A wole byte was read, store in output + "\tst Z+, %[cur_byte]\n" // 2 + // Decrement byte count + "\tdec %[byte_count]\n" // 1 + // Are we done reading ? + "\tbreq .read_end_%=\n" // byte_count!=0: 1, byte_count==0: 2 + // No, prepare for reading another + "\tldi %[mask], 0x80\n" + "\tclr %[cur_byte]\n" + + // Wait for rising edge + ".read_wait_input_high_init_%=:" + "\tldi %[timeout], 0x3f\n" // 1 + ".read_wait_input_high_%=:\n" + "\tlds %[scratch], %[in_byte]\n" // 2 + "\tsbrc %[scratch], %[in_bit]\n" // high: 1, low: 2 + "\trjmp .read_loop_%=\n" // 2 + "\tdec %[timeout]\n" // 1 + "\tbrne .read_wait_input_high_%=\n" // timeout==0: 1, timeout!=0: 2 + "\trjmp .read_end_%=\n" // 2 + ".read_end_%=:\n" + : [output] "+z" (output), + [byte_count] "+r" (byte_count), + [mask] "=&a" (mask), + [cur_byte] "=&r" (cur_byte), + [timeout] "=&a" (timeout), + [scratch] "=&a" (scratch) + : [in_byte] "i" (&PINH), + [in_bit] "i" (4) + : "cc", "memory" + ); + return byte_count; } /****************************************** @@ -794,115 +916,54 @@ read_loop: void get_button() { // Command to send to the gamecube // The last bit is rumble, flip it to rumble - // yes this does need to be inside the loop, the - // array gets mutilated when it goes through N64_send - unsigned char command[] = { - 0x01 - }; - - // Empty buffer - for (word i = 0; i < 265; i++) { - N64_raw_dump[i] = 0xFF; - } + const byte command[] = { 0x01 }; + byte response[4]; // don't want interrupts getting in the way noInterrupts(); - // send those 3 bytes - N64_send(command, 1); - N64_stop(); - // read in 32bits of data and dump it to N64_raw_dump - N64_get(32); + sendJoyBus(command, sizeof(command)); + recvJoyBus(response, sizeof(response)); // end of time sensitive code interrupts(); - // The get_N64_status function sloppily dumps its data 1 bit per byte - // into the get_status_extended char array. It's our job to go through - // that and put each piece neatly into the struct N64_status - int i; - memset(&N64_status, 0, sizeof(N64_status)); - - // bits: joystick x value // These are 8 bit values centered at 0x80 (128) - for (i = 0; i < 8; i++) { - N64_status.stick_x |= N64_raw_dump[16 + i] ? (0x80 >> i) : 0; - } - for (i = 0; i < 8; i++) { - N64_status.stick_y |= N64_raw_dump[24 + i] ? (0x80 >> i) : 0; - } - - // read char array N64_raw_dump into string rawStr - rawStr = ""; - for (i = 0; i < 16; i++) { - rawStr = rawStr + String(N64_raw_dump[i], DEC); - } + N64_status.stick_x = response[2]; + N64_status.stick_y = response[3]; // Buttons (A,B,Z,S,DU,DD,DL,DR,0,0,L,R,CU,CD,CL,CR) - if (rawStr.substring(0, 16) == "0000000000000000") { + if (response[0] & 0x80) + button = F("A"); + else if (response[0] & 0x40) + button = F("B"); + else if (response[0] & 0x20) + button = F("Z"); + else if (response[0] & 0x10) + button = F("START"); + else if (response[0] & 0x08) + button = F("D-Up"); + else if (response[0] & 0x04) + button = F("D-Down"); + else if (response[0] & 0x02) + button = F("D-Left"); + else if (response[0] & 0x01) + button = F("D-Right"); + //else if (response[1] & 0x80) + //else if (response[1] & 0x40) + else if (response[1] & 0x20) + button = F("L"); + else if (response[1] & 0x10) + button = F("R"); + else if (response[1] & 0x08) + button = F("C-Up"); + else if (response[1] & 0x04) + button = F("C-Down"); + else if (response[1] & 0x02) + button = F("C-Left"); + else if (response[1] & 0x01) + button = F("C-Right"); + else { lastbutton = button; button = F("Press a button"); - } else { - for (int i = 0; i < 16; i++) { - // seems to be 16, 8 or 4 depending on what pin is used - if (N64_raw_dump[i] == 16) { - switch (i) { - case 7: - button = F("D-Right"); - break; - - case 6: - button = F("D-Left"); - break; - - case 5: - button = F("D-Down"); - break; - - case 4: - button = F("D-Up"); - break; - - case 3: - button = F("START"); - break; - - case 2: - button = F("Z"); - break; - - case 1: - button = F("B"); - break; - - case 0: - button = F("A"); - break; - - case 15: - button = F("C-Right"); - break; - - case 14: - button = F("C-Left"); - break; - - case 13: - button = F("C-Down"); - break; - - case 12: - button = F("C-Up"); - break; - - case 11: - button = F("R"); - break; - - case 10: - button = F("L"); - break; - } - } - } } } @@ -1435,160 +1496,72 @@ void controllerTest_Display() { *****************************************/ // Reset the controller void resetController() { - // Reset controller - unsigned char command[] = { 0xFF }; - // don't want interrupts getting in the way + const byte command[] = { 0xFF }; noInterrupts(); - // Send command - N64_send(command, 1); - // Send stop - N64_stop(); - // Enable interrupts + sendJoyBus(command, sizeof(command)); interrupts(); delay(100); } // read 3 bytes from controller void checkController() { + byte response[8]; + const byte command[] = { 0x00 }; + display_Clear(); // Check if line is HIGH if (!N64_QUERY) - print_Error(F("Data line LOW"), true); - - // Send status command - unsigned char command[] = { 0x0 }; - - // Empty buffer - for (word i = 0; i < 265; i++) { - N64_raw_dump[i] = 0xFF; - } + print_FatalError(F("Data line LOW")); // don't want interrupts getting in the way noInterrupts(); - N64_send(command, 1); - N64_stop(); - // read in data - N64_get(32); + sendJoyBus(command, sizeof(command)); + recvJoyBus(response, sizeof(response)); // end of time sensitive code interrupts(); - // Empty N64_raw_dump into myBlock - for (word i = 0; i < 32; i += 8) { - boolean byteFlipped[9]; - - // Flip byte order - byteFlipped[0] = N64_raw_dump[i + 7]; - byteFlipped[1] = N64_raw_dump[i + 6]; - byteFlipped[2] = N64_raw_dump[i + 5]; - byteFlipped[3] = N64_raw_dump[i + 4]; - byteFlipped[4] = N64_raw_dump[i + 3]; - byteFlipped[5] = N64_raw_dump[i + 2]; - byteFlipped[6] = N64_raw_dump[i + 1]; - byteFlipped[7] = N64_raw_dump[i + 0]; - - // Join bits into one byte - unsigned char myByte = 0; - for (byte j = 0; j < 8; ++j) { - if (byteFlipped[j]) { - myByte |= 1 << j; - } - } - if ((i == 0) && (myByte != 0x05)) - print_Error(F("Controller not found"), true); - if ((i == 16) && (myByte != 0x01)) - print_Error(F("Controller Pak not found"), true); - if ((i == 16) && (myByte == 0x04)) - print_Error(F("CRC Error"), true); - } + if (response[0] != 0x05) + print_FatalError(F("Controller not found")); + if (response[2] != 0x01) + print_FatalError(F("Controller Pak not found")); } // read 32bytes from controller pak and calculate CRC -byte readBlock(word myAddress) { +byte readBlock(byte *output, word myAddress) { + byte response_crc; // Calculate the address CRC word myAddressCRC = addrCRC(myAddress); - - // Read Controller Pak command - unsigned char command[] = { 0x02 }; - // Address Command - unsigned char addressHigh[] = { (unsigned char)(myAddressCRC >> 8) }; - unsigned char addressLow[] = { (unsigned char)(myAddressCRC & 0xff) }; - - // Empty buffer - for (word i = 0; i < 265; i++) { - N64_raw_dump[i] = 0xFF; - } + const byte command[] = { 0x02, (byte) (myAddressCRC >> 8), (byte) (myAddressCRC & 0xff) }; + word error; // don't want interrupts getting in the way noInterrupts(); - // send those 3 bytes - N64_send(command, 1); - N64_send(addressHigh, 1); - N64_send(addressLow, 1); - N64_stop(); - // read in 32 byte data + 1 byte crc - N64_get(264); + sendJoyBus(command, sizeof(command)); + error = recvJoyBus(output, 32); + if (error == 0) + error = recvJoyBus(&response_crc, 1); // end of time sensitive code interrupts(); - // Empty N64_raw_dump into myBlock - for (word i = 0; i < 256; i += 8) { - boolean byteFlipped[9]; - - // Flip byte order - byteFlipped[0] = N64_raw_dump[i + 7]; - byteFlipped[1] = N64_raw_dump[i + 6]; - byteFlipped[2] = N64_raw_dump[i + 5]; - byteFlipped[3] = N64_raw_dump[i + 4]; - byteFlipped[4] = N64_raw_dump[i + 3]; - byteFlipped[5] = N64_raw_dump[i + 2]; - byteFlipped[6] = N64_raw_dump[i + 1]; - byteFlipped[7] = N64_raw_dump[i + 0]; - - // Join bits into one byte - unsigned char myByte = 0; - for (byte j = 0; j < 8; ++j) { - if (byteFlipped[j]) { - myByte |= 1 << j; - } - } - // Save byte into block array - myBlock[i / 8] = myByte; + if (error) { + myFile.close(); + println_Msg(F("Controller Pak was")); + println_Msg(F("not dumped due to a")); + print_FatalError(F("read timeout")); } - // Get CRC of block send - boolean byteFlipped[9]; - // Flip byte order - byteFlipped[0] = N64_raw_dump[256 + 7]; - byteFlipped[1] = N64_raw_dump[256 + 6]; - byteFlipped[2] = N64_raw_dump[256 + 5]; - byteFlipped[3] = N64_raw_dump[256 + 4]; - byteFlipped[4] = N64_raw_dump[256 + 3]; - byteFlipped[5] = N64_raw_dump[256 + 2]; - byteFlipped[6] = N64_raw_dump[256 + 1]; - byteFlipped[7] = N64_raw_dump[256 + 0]; - - unsigned char blockCRC = 0; - for (byte k = 0; k < 8; ++k) { - if (byteFlipped[k]) { - blockCRC |= 1 << k; - } - } - - // Calculate CRC of block received - unsigned char myCRC = dataCRC(&myBlock[0]); - - // Compare - if (blockCRC != myCRC) { + // Compare with computed CRC + if (response_crc != dataCRC(output)) { display_Clear(); // Close the file: myFile.close(); println_Msg(F("Controller Pak was")); println_Msg(F("not dumped due to a")); - print_Error(F("protocol CRC error"), true); + print_FatalError(F("protocol CRC error")); } - return blockCRC; + return response_crc; } // reads the MPK file to the sd card @@ -1614,12 +1587,12 @@ void readMPK() { strcat(filePath, ".crc"); FsFile crcFile; if (!crcFile.open(filePath, O_RDWR | O_CREAT)) { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } //open mpk file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } print_Msg(F("Saving N64/MPK/")); @@ -1638,17 +1611,11 @@ void readMPK() { draw_progressbar(0, totalProgressBar); // Controller paks, which all have 32kB of space, are mapped between 0x0000 – 0x7FFF - // Read 512 byte into sdBuffer for (word currSdBuffer = 0x0000; currSdBuffer < 0x8000; currSdBuffer += 512) { - // Read 32 byte block - for (word currBlock = 0; currBlock < 512; currBlock += 32) { + // Read 32 byte block into sdBuffer + for (word currBlock = 0; currBlock < sizeof(sdBuffer); currBlock += 32) { // Read one block of the Controller Pak into array myBlock and write CRC of that block to crc file - crcFile.write(readBlock(currSdBuffer + currBlock)); - - // Copy block to SdBuffer - for (byte currByte = 0; currByte < 32; currByte++) { - sdBuffer[currBlock + currByte] = myBlock[currByte]; - } + crcFile.write(readBlock(&sdBuffer[currBlock], currSdBuffer + currBlock)); // Real N64 has about 627us pause between banks, add a bit extra delay if (currBlock < 479) @@ -1656,7 +1623,7 @@ void readMPK() { } // This will take 1300us blinkLED(); - myFile.write(sdBuffer, 512); + myFile.write(sdBuffer, sizeof(sdBuffer)); // Blink led blinkLED(); // Update progress bar @@ -1678,12 +1645,12 @@ void verifyCRC() { //open CRC file on sd card FsFile crcFile; if (!crcFile.open(filePath, O_READ)) { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } //open MPK file on sd card if (!myFile.open(fileName, O_READ)) { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } //Initialize progress bar @@ -1714,14 +1681,14 @@ void verifyCRC() { crcFile.close(); if (writeErrors == 0) { - println_Msg(F("Read successfully")); + println_Msg(F("Saved successfully")); sd.remove(filePath); display_Update(); } else { print_STR(error_STR, 0); print_Msg(writeErrors); println_Msg(F(" blocks ")); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } @@ -1740,24 +1707,31 @@ boolean checkHeader(byte* buf) { // verifies if Controller Pak holds valid header data void validateMPK() { + byte writeErrors = 0; + boolean failed = false; + SdFile mpk_file; + byte buf[256]; + //open file on sd card - if (!myFile.open(fileName, O_READ)) { - print_Error(open_file_STR, true); + if (!mpk_file.open(fileName, O_READ)) { + print_FatalError(open_file_STR); } // Read first 256 byte which contains the header including checksum and reverse checksum and three copies of it - myFile.read(sdBuffer, 256); + mpk_file.read(buf, sizeof(buf)); //Check all four header copies writeErrors = 0; - if (!checkHeader(&sdBuffer[0x20])) + if (!checkHeader(&buf[0x20])) writeErrors++; - if (!checkHeader(&sdBuffer[0x60])) + if (!checkHeader(&buf[0x60])) writeErrors++; - if (!checkHeader(&sdBuffer[0x80])) + if (!checkHeader(&buf[0x80])) writeErrors++; - if (!checkHeader(&sdBuffer[0xC0])) + if (!checkHeader(&buf[0xC0])) writeErrors++; + if (writeErrors) + failed = true; print_Msg(F("HDR: ")); print_Msg(4 - writeErrors); @@ -1766,32 +1740,46 @@ void validateMPK() { // Check both TOC copies writeErrors = 0; - word sum = 0; // Read 2nd and 3rd 256 byte page with TOC info for (word currSdBuffer = 0x100; currSdBuffer < 0x300; currSdBuffer += 256) { - sum = 0; + byte sum = 0; // Read 256 bytes into SD buffer - myFile.read(sdBuffer, 256); + mpk_file.read(buf, sizeof(buf)); // Calculate TOC checksum - for (int i = 5; i < 128; i++) { - sum += sdBuffer[(i << 1) + 1]; + for (byte i = 5; i < 128; i++) { + sum += buf[(i << 1) + 1]; } - if (sdBuffer[1] != (sum & 0xFF)) + if (buf[1] != sum) writeErrors++; } + if (writeErrors) + failed = true; print_Msg(F("ToC: ")); print_Msg(2 - writeErrors); println_Msg(F("/2")); + + print_Msg(F("Consistency check ")); + if (failed) { + errorLvl = 1; + print_Msg(F("failed")); + } else { + errorLvl = 0; + print_Msg(F("pased")); + } display_Update(); // Close the file: - myFile.close(); + mpk_file.close(); } void writeMPK() { + // 3 command bytes, 32 data bytes + byte command[3 + 32]; + command[0] = 0x03; + // Create filepath sprintf(filePath, "%s/%s", filePath, fileName); print_Msg(F("Writing ")); @@ -1803,64 +1791,42 @@ void writeMPK() { if (myFile.open(filePath, O_READ)) { //Initialize progress bar - uint32_t processedProgressBar = 0; - uint32_t totalProgressBar = (uint32_t)(0x7FFF); + uint32_t totalProgressBar = 0x7FFF; draw_progressbar(0, totalProgressBar); - for (word currSdBuffer = 0x0000; currSdBuffer < 0x8000; currSdBuffer += 512) { - // Read 512 bytes into SD buffer, takes 1500us - myFile.read(sdBuffer, 512); + for (word address = 0x0000; address < 0x8000; address += 32) { + myFile.read(command + 3, sizeof(command) - 3); - // Write 32 byte block - for (word currBlock = 0; currBlock < 512; currBlock += 32) { - // Calculate the address CRC - word myAddressCRC = addrCRC(currSdBuffer + currBlock); + word address_with_crc = addrCRC(address); + command[1] = (byte) (address_with_crc >> 8); + command[2] = (byte) (address_with_crc & 0xff); - // Copy 32 byte block from SdBuffer - for (byte currByte = 0; currByte < 32; currByte++) { - myBlock[currByte] = sdBuffer[currBlock + currByte]; - } + // don't want interrupts getting in the way + noInterrupts(); + sendJoyBus(command, sizeof(command)); + // Enable interrupts + interrupts(); - // Write Controller Pak command - unsigned char command[] = { 0x03 }; - // Address Command - unsigned char addressHigh[] = { (unsigned char)(myAddressCRC >> 8) }; - unsigned char addressLow[] = { (unsigned char)(myAddressCRC & 0xff) }; + // Real N64 has about 627us pause between banks, add a bit extra delay + delayMicroseconds(650); - // don't want interrupts getting in the way - noInterrupts(); - // Send write command - N64_send(command, 1); - // Send block number - N64_send(addressHigh, 1); - N64_send(addressLow, 1); - // Send data to write - N64_send(myBlock, 32); - // Send stop - N64_stop(); - // Enable interrupts - interrupts(); - - // Real N64 has about 627us pause between banks, add a bit extra delay - if (currBlock < 479) - delayMicroseconds(1500); + if ((address & 0x1FF) == 0) { + // Blink led + // Update progress bar + blinkLED(); + draw_progressbar(address, totalProgressBar); } - - // Blink led - blinkLED(); - // Update progress bar - processedProgressBar += 512; - draw_progressbar(processedProgressBar, totalProgressBar); } // Close the file: myFile.close(); } else { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } } // verifies if write was successful void verifyMPK() { + byte block[32]; writeErrors = 0; print_STR(verifying_STR, 1); @@ -1868,7 +1834,7 @@ void verifyMPK() { //open file on sd card if (!myFile.open(filePath, O_READ)) { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } //Initialize progress bar @@ -1877,18 +1843,18 @@ void verifyMPK() { draw_progressbar(0, totalProgressBar); // Controller paks, which all have 32kB of space, are mapped between 0x0000 – 0x7FFF - for (word currSdBuffer = 0x0000; currSdBuffer < 0x8000; currSdBuffer += 512) { + for (word currSdBuffer = 0x0000; currSdBuffer < 0x8000; currSdBuffer += sizeof(sdBuffer)) { // Read 512 bytes into SD buffer - myFile.read(sdBuffer, 512); + myFile.read(sdBuffer, sizeof(sdBuffer)); // Compare 32 byte block - for (word currBlock = 0; currBlock < 512; currBlock += 32) { - // Read one block of the Controller Pak into array myBlock - readBlock(currSdBuffer + currBlock); + for (word currBlock = 0; currBlock < sizeof(sdBuffer); currBlock += 32) { + // Read one block of the Controller Pak + readBlock(block, currSdBuffer + currBlock); // Check against file on SD card for (byte currByte = 0; currByte < 32; currByte++) { - if (sdBuffer[currBlock + currByte] != myBlock[currByte]) { + if (sdBuffer[currBlock + currByte] != block[currByte]) { writeErrors++; } } @@ -1913,7 +1879,7 @@ void verifyMPK() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } @@ -1980,7 +1946,7 @@ void printCartInfo_N64() { display_Update(); strcpy(romName, "GPERROR"); - print_Error(F("Cartridge unknown"), false); + print_Error(F("Cartridge unknown")); println_Msg(""); // Prints string out of the common strings array either with or without newline print_STR(press_button_STR, 1); @@ -2079,14 +2045,14 @@ void printCartInfo_N64() { return result; } else { - print_Error(F("n64.txt missing"), true); + print_FatalError(F("n64.txt missing")); } }*/ // look-up cart id in file n64.txt on sd card void getCartInfo_N64() { - char tempStr2[2]; char tempStr[9]; + int read_bytes; // cart not in list cartSize = 0; @@ -2108,26 +2074,18 @@ void getCartInfo_N64() { // Skip over the CRC32 checksum myFile.seekCur(9); - // Read 8 bytes into String, do it one at a time so byte order doesn't get mixed up - sprintf(tempStr, "%c", myFile.read()); - for (byte i = 0; i < 7; i++) { - sprintf(tempStr2, "%c", myFile.read()); - strcat(tempStr, tempStr2); - } + // Read 8 bytes into String + read_bytes = myFile.read(tempStr, 8); + tempStr[read_bytes == -1 ? 0 : read_bytes] = 0; // Check if string is a match if (strcmp(tempStr, checksumStr) == 0) { // Skip the , in the file myFile.seekCur(1); - // Read the next ascii character and subtract 48 to convert to decimal - cartSize = myFile.read() - 48; - // Remove leading 0 for single digit cart sizes - if (cartSize != 0) { - cartSize = cartSize * 10 + myFile.read() - 48; - } else { - cartSize = myFile.read() - 48; - } + read_bytes = myFile.read(tempStr, 2); + tempStr[read_bytes == -1 ? 0 : read_bytes] = 0; + cartSize = atoi(tempStr); // Skip the , in the file myFile.seekCur(1); @@ -2149,7 +2107,7 @@ void getCartInfo_N64() { // Close the file: myFile.close(); } else { - print_Error(F("n64.txt missing"), true); + print_FatalError(F("n64.txt missing")); } } @@ -2205,441 +2163,6 @@ void idCart() { #endif } -/****************************************** - Eeprom functions (without Adafruit clockgen) -*****************************************/ -// Send a clock pulse of 2us length, 50% duty, 500kHz -void pulseClock_N64(unsigned int times) { - for (unsigned int i = 0; i < (times * 2); i++) { - // Switch the clock pin to 0 if it's 1 and 0 if it's 1 - PORTH ^= (1 << 1); - // without the delay the clock pulse would be 1.5us and 666kHz - //__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t")); - } -} - -// Send one byte of data to eeprom -void sendData_CLK(byte data) { - for (byte i = 0; i < 8; i++) { - // pull data line low - N64_LOW; - - // if current bit is 1, pull high after ~1us, 2 cycles - if (data >> 7) { - pulseClock_N64(2); - N64_HIGH; - pulseClock_N64(6); - } - // if current bit is 0 pull high after ~3us, 6 cycles - else { - pulseClock_N64(6); - N64_HIGH; - pulseClock_N64(2); - } - - // rotate to the next bit - data <<= 1; - } -} - -// Send stop bit to eeprom -void sendStop_CLK() { - N64_LOW; - pulseClock_N64(2); - N64_HIGH; - pulseClock_N64(4); -} - -// Capture 8 bytes in 64 bits into bit array tempBits -void readData_CLK() { - for (byte i = 0; i < 64; i++) { - - // pulse clock until we get response from eeprom - while (N64_QUERY) { - pulseClock_N64(1); - } - - // Skip over the 1us low part of a high bit - pulseClock_N64(3); - - // Read bit - tempBits[i] = N64_QUERY; - - // wait for line to go high again - while (!N64_QUERY) { - pulseClock_N64(1); - } - } -} - -// Write Eeprom to cartridge -void writeEeprom_CLK() { - if ((saveType == 5) || (saveType == 6)) { - - // Create filepath - sprintf(filePath, "%s/%s", filePath, fileName); - println_Msg(F("Writing...")); - println_Msg(filePath); - display_Update(); - - // Open file on sd card - if (myFile.open(filePath, O_READ)) { - - for (byte i = 0; i < (eepPages / 64); i++) { - myFile.read(sdBuffer, 512); - // Disable interrupts for more uniform clock pulses - noInterrupts(); - - for (byte pageNumber = 0; pageNumber < 64; pageNumber++) { - // Blink led - blinkLED(); - - // Wait ~50ms between page writes or eeprom will have write errors - pulseClock_N64(26000); - - // Send write command - sendData_CLK(0x05); - // Send page number - sendData_CLK(pageNumber + (i * 64)); - // Send data to write - for (byte j = 0; j < 8; j++) { - sendData_CLK(sdBuffer[(pageNumber * 8) + j]); - } - sendStop_CLK(); - } - interrupts(); - } - - // Close the file: - myFile.close(); - print_STR(done_STR, 1); - display_Update(); - delay(600); - } else { - print_Error(sd_error_STR, true); - } - } else { - print_Error(F("Savetype Error"), true); - } -} - -// Dump Eeprom to SD -void readEeprom_CLK() { - if ((saveType == 5) || (saveType == 6)) { - - // Wait 50ms or eeprom might lock up - pulseClock_N64(26000); - - // Get name, add extension and convert to char array for sd lib - strcpy(fileName, romName); - strcat(fileName, ".eep"); - - // create a new folder for the save file - EEPROM_readAnything(0, foldern); - sprintf(folder, "N64/SAVE/%s/%d", romName, foldern); - sd.mkdir(folder, true); - sd.chdir(folder); - - // write new folder number back to eeprom - foldern = foldern + 1; - EEPROM_writeAnything(0, foldern); - - // Open file on sd card - if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); - } - - for (byte i = 0; i < (eepPages / 64); i++) { - // Disable interrupts for more uniform clock pulses - noInterrupts(); - - for (byte pageNumber = 0; pageNumber < 64; pageNumber++) { - // Blink led - blinkLED(); - - // Send read command - sendData_CLK(0x04); - // Send Page number - sendData_CLK(pageNumber + (i * 64)); - // Send stop bit - sendStop_CLK(); - - // read data - readData_CLK(); - sendStop_CLK(); - - // OR 8 bits into one byte for a total of 8 bytes - for (byte j = 0; j < 64; j += 8) { - sdBuffer[(pageNumber * 8) + (j / 8)] = tempBits[0 + j] << 7 | tempBits[1 + j] << 6 | tempBits[2 + j] << 5 | tempBits[3 + j] << 4 | tempBits[4 + j] << 3 | tempBits[5 + j] << 2 | tempBits[6 + j] << 1 | tempBits[7 + j]; - } - // Wait 50ms between pages or eeprom might lock up - pulseClock_N64(26000); - } - interrupts(); - - // Write 64 pages at once to the SD card - myFile.write(sdBuffer, 512); - } - // Close the file: - myFile.close(); - //clear the screen - display_Clear(); - print_Msg(F("Saved to ")); - print_Msg(folder); - println_Msg(F("/")); - display_Update(); - } else { - print_Error(F("Savetype Error"), true); - } -} - -// Check if a write succeeded, returns 0 if all is ok and number of errors if not -unsigned long verifyEeprom_CLK() { - if ((saveType == 5) || (saveType == 6)) { - writeErrors = 0; - - // Wait 50ms or eeprom might lock up - pulseClock_N64(26000); - - display_Clear(); - print_Msg(F("Verifying against ")); - println_Msg(filePath); - display_Update(); - - // Open file on sd card - if (myFile.open(filePath, O_READ)) { - - for (byte i = 0; i < (eepPages / 64); i++) { - // Disable interrupts for more uniform clock pulses - noInterrupts(); - - for (byte pageNumber = 0; pageNumber < 64; pageNumber++) { - // Blink led - blinkLED(); - - // Send read command - sendData_CLK(0x04); - // Send Page number - sendData_CLK(pageNumber + (i * 64)); - // Send stop bit - sendStop_CLK(); - - // read data - readData_CLK(); - sendStop_CLK(); - - // OR 8 bits into one byte for a total of 8 bytes - for (byte j = 0; j < 64; j += 8) { - sdBuffer[(pageNumber * 8) + (j / 8)] = tempBits[0 + j] << 7 | tempBits[1 + j] << 6 | tempBits[2 + j] << 5 | tempBits[3 + j] << 4 | tempBits[4 + j] << 3 | tempBits[5 + j] << 2 | tempBits[6 + j] << 1 | tempBits[7 + j]; - } - // Wait 50ms between pages or eeprom might lock up - pulseClock_N64(26000); - } - interrupts(); - - // Check sdBuffer content against file on sd card - for (int c = 0; c < 512; c++) { - if (myFile.read() != sdBuffer[c]) { - writeErrors++; - } - } - } - // Close the file: - myFile.close(); - } else { - // SD Error - writeErrors = 999999; - print_Error(sd_error_STR, true); - } - // Return 0 if verified ok, or number of errors - return writeErrors; - } else { - print_Error(F("Savetype Error"), true); - return 1; - } -} - -/****************************************** - Eeprom functions (with Adafruit clockgen) -*****************************************/ -// Send one byte of data to eeprom -void sendData(byte data) { - for (byte i = 0; i < 8; i++) { - // pull data line low - N64_LOW; - - // if current bit is 1, pull high after ~1us - if (data >> 7) { - __asm__("nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); - N64_HIGH; - __asm__("nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); - } - // if current bit is 0 pull high after ~3us - else { - __asm__("nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); - N64_HIGH; - __asm__("nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); - } - - // rotate to the next bit - data <<= 1; - } -} - -// Send stop bit to eeprom -void sendStop() { - N64_LOW; - __asm__("nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); - N64_HIGH; - __asm__("nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); -} - -// Capture 8 bytes in 64 bits into bit array tempBits -void readData() { - for (byte i = 0; i < 64; i++) { - - // wait until we get response from eeprom - while (N64_QUERY) { - } - - // Skip over the 1us low part of a high bit, Arduino running at 16Mhz -> one nop = 62.5ns - __asm__("nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); - - // Read bit - tempBits[i] = N64_QUERY; - - // wait for line to go high again - while (!N64_QUERY) { - __asm__("nop\n\t"); - } - } -} - // Write Eeprom to cartridge void writeEeprom() { if ((saveType == 5) || (saveType == 6)) { @@ -2652,31 +2175,26 @@ void writeEeprom() { // Open file on sd card if (myFile.open(filePath, O_READ)) { + // 2 command bytes and 8 data bytes + byte command[2 + 8]; + command[0] = 0x05; - for (byte i = 0; i < (eepPages / 64); i++) { - myFile.read(sdBuffer, 512); + // Note: eepPages can be 256, so page must be able to get to 256 for the + // loop to exit. So it is not possible to use command[1] directly as loop + // counter. + for (int page = 0; page < eepPages; page++) { + command[1] = page; + // TODO: read 512 bytes in a 512 + 2 bytes buffer, and move the command start 32 bytes at a time + myFile.read(command + 2, sizeof(command) - 2); // Disable interrupts for more uniform clock pulses + + // Blink led + blinkLED(); + if (page) + delay(50); // Wait 50ms between pages when writing + noInterrupts(); - - for (byte pageNumber = 0; pageNumber < 64; pageNumber++) { - // Blink led - blinkLED(); - - // Wait ~50ms between page writes or eeprom will have write errors, Arduino running at 16Mhz -> one nop = 62.5ns - for (long i = 0; i < 115000; i++) { - __asm__("nop\n\t"); - } - - // Send write command - sendData(0x05); - // Send page number - sendData(pageNumber + (i * 64)); - // Send data to write - for (byte j = 0; j < 8; j++) { - sendData(sdBuffer[(pageNumber * 8) + j]); - } - sendStop(); - } + sendJoyBus(command, sizeof(command)); interrupts(); } @@ -2686,10 +2204,32 @@ void writeEeprom() { display_Update(); delay(600); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); + } +} + +void readEepromPageList(byte *output, byte page_number, byte page_count) { + byte command[] = { 0x04, page_number }; + + // Disable interrupts for more uniform clock pulses + while (page_count--) { + // Blink led + blinkLED(); + + noInterrupts(); + sendJoyBus(command, sizeof(command)); + // XXX: is it possible to read more than 8 bytes at a time ? + recvJoyBus(output, 8); + interrupts(); + + if (page_count) + delayMicroseconds(600); // wait 600us between pages when reading + + command[1]++; + output += 8; } } @@ -2697,12 +2237,11 @@ void writeEeprom() { void readEeprom() { if ((saveType == 5) || (saveType == 6)) { // Get name, add extension and convert to char array for sd lib - strcpy(fileName, romName); - strcat(fileName, ".eep"); + snprintf_P(fileName, sizeof(fileName), N64_EEP_FILENAME_FMT, romName); // create a new folder for the save file EEPROM_readAnything(0, foldern); - sprintf(folder, "N64/SAVE/%s/%d", romName, foldern); + snprintf_P(folder, sizeof(folder), N64_SAVE_DIRNAME_FMT, romName, foldern); sd.mkdir(folder, true); sd.chdir(folder); @@ -2712,41 +2251,13 @@ void readEeprom() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } - for (byte i = 0; i < (eepPages / 64); i++) { - // Disable interrupts for more uniform clock pulses - noInterrupts(); - - for (byte pageNumber = 0; pageNumber < 64; pageNumber++) { - // Blink led - blinkLED(); - - // Send read command - sendData(0x04); - // Send Page number - sendData(pageNumber + (i * 64)); - // Send stop bit - sendStop(); - - // read data - readData(); - sendStop(); - - // OR 8 bits into one byte for a total of 8 bytes - for (byte j = 0; j < 64; j += 8) { - sdBuffer[(pageNumber * 8) + (j / 8)] = tempBits[0 + j] << 7 | tempBits[1 + j] << 6 | tempBits[2 + j] << 5 | tempBits[3 + j] << 4 | tempBits[4 + j] << 3 | tempBits[5 + j] << 2 | tempBits[6 + j] << 1 | tempBits[7 + j]; - } - // Wait ~600us between pages - for (int i = 0; i < 2000; i++) { - __asm__("nop\n\t"); - } - } - interrupts(); - + for (int i = 0; i < eepPages; i += sizeof(sdBuffer) / 8) { + readEepromPageList(sdBuffer, i, sizeof(sdBuffer) / 8); // Write 64 pages at once to the SD card - myFile.write(sdBuffer, 512); + myFile.write(sdBuffer, sizeof(sdBuffer)); } // Close the file: myFile.close(); @@ -2757,12 +2268,14 @@ void readEeprom() { println_Msg(F("/")); display_Update(); } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); } } // Check if a write succeeded, returns 0 if all is ok and number of errors if not unsigned long verifyEeprom() { + unsigned long writeErrors; + if ((saveType == 5) || (saveType == 6)) { writeErrors = 0; @@ -2773,39 +2286,10 @@ unsigned long verifyEeprom() { // Open file on sd card if (myFile.open(filePath, O_READ)) { - - for (byte i = 0; i < (eepPages / 64); i++) { - // Disable interrupts for more uniform clock pulses - noInterrupts(); - - for (byte pageNumber = 0; pageNumber < 64; pageNumber++) { - // Blink led - blinkLED(); - - // Send read command - sendData(0x04); - // Send Page number - sendData(pageNumber + (i * 64)); - // Send stop bit - sendStop(); - - // read data - readData(); - sendStop(); - - // OR 8 bits into one byte for a total of 8 bytes - for (byte j = 0; j < 64; j += 8) { - sdBuffer[(pageNumber * 8) + (j / 8)] = tempBits[0 + j] << 7 | tempBits[1 + j] << 6 | tempBits[2 + j] << 5 | tempBits[3 + j] << 4 | tempBits[4 + j] << 3 | tempBits[5 + j] << 2 | tempBits[6 + j] << 1 | tempBits[7 + j]; - } - // Wait ~600us between pages - for (int i = 0; i < 2000; i++) { - __asm__("nop\n\t"); - } - } - interrupts(); - + for (int i = 0; i < eepPages; i += sizeof(sdBuffer) / 8) { + readEepromPageList(sdBuffer, i, sizeof(sdBuffer) / 8); // Check sdBuffer content against file on sd card - for (int c = 0; c < 512; c++) { + for (size_t c = 0; c < sizeof(sdBuffer); c++) { if (myFile.read() != sdBuffer[c]) { writeErrors++; } @@ -2816,12 +2300,12 @@ unsigned long verifyEeprom() { } else { // SD Error writeErrors = 999999; - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Return 0 if verified ok, or number of errors return writeErrors; } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); return 1; } } @@ -2861,11 +2345,11 @@ void writeSram(unsigned long sramSize) { print_STR(done_STR, 1); display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); } } @@ -2886,7 +2370,7 @@ void readSram(unsigned long sramSize, byte flashramType) { } else if (saveType == 1) { strcat(fileName, ".sra"); } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); } // create a new folder for the save file @@ -2901,7 +2385,7 @@ void readSram(unsigned long sramSize, byte flashramType) { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } for (unsigned long currByte = sramBase; currByte < (sramBase + (sramSize / flashramType)); currByte += offset) { @@ -2964,7 +2448,7 @@ unsigned long verifySram(unsigned long sramSize, byte flashramType) { // Close the file: myFile.close(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Return 0 if verified ok, or number of errors return writeErrors; @@ -3070,10 +2554,10 @@ void writeFram(byte flashramType) { // Close the file: myFile.close(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); } } @@ -3101,7 +2585,7 @@ void eraseFram() { } } } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); } } @@ -3114,7 +2598,7 @@ void readFram(byte flashramType) { // Read Flashram readSram(131072, flashramType); } else { - print_Error(F("Savetype Error"), true); + print_FatalError(F("Savetype Error")); } } @@ -3276,7 +2760,7 @@ void getFramType() { print_Msg(sdBuffer[c], HEX); print_Msg(F(", ")); } - print_Error(F("Flashram unknown"), true); + print_FatalError(F("Flashram unknown")); } } @@ -3309,33 +2793,28 @@ redumpnewfolder: redumpsamefolder: // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } - // dumping rom slow -#ifndef fastcrc // get current time unsigned long startTime = millis(); +#ifndef fastcrc + // dumping rom slow for (unsigned long currByte = romBase; currByte < (romBase + (cartSize * 1024 * 1024)); currByte += 512) { // Blink led - if (currByte % 16384 == 0) + if ((currByte & 0x3FFF) == 0) blinkLED(); // Set the address for the next 512 bytes setAddress_N64(currByte); - for (int c = 0; c < 512; c += 2) { - // split word + for (word c = 0; c < sizeof(sdBuffer); c += 2) { word myWord = readWord_N64(); - byte loByte = myWord & 0xFF; - byte hiByte = myWord >> 8; - - // write to buffer - sdBuffer[c] = hiByte; - sdBuffer[c + 1] = loByte; + sdBuffer[c] = myWord >> 8; + sdBuffer[c + 1] = myWord & 0xFF; } - myFile.write(sdBuffer, 512); + myFile.write(sdBuffer, sizeof(sdBuffer)); } // Close the file: myFile.close(); @@ -3343,10 +2822,7 @@ redumpsamefolder: if (compareCRC("n64.txt", 0, 1, 0)) { #else // dumping rom fast - byte buffer[1024] = { 0 }; - - // get current time - unsigned long startTime = millis(); + byte buffer[1024]; //Initialize progress bar uint32_t processedProgressBar = 0; @@ -3490,10 +2966,10 @@ redumpsamefolder: sd.chdir(folder); // Delete old file if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } if (!myFile.remove()) { - print_Error(F("Delete Error"), true); + print_FatalError(F("Delete Error")); } // Dump again display_Clear(); @@ -3516,7 +2992,7 @@ redumpsamefolder: void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElapsed) { // Open file on sd card if (!myFile.open("N64/ROM/n64log.txt", O_RDWR | O_CREAT | O_APPEND)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } //Write the info @@ -3785,7 +3261,7 @@ void flashRepro_N64() { // Compare file size to flashrom size if ((fileSize / 1048576) > cartSize) { - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); } // Erase needed sectors @@ -3840,7 +3316,7 @@ void flashRepro_N64() { writeFlashrom_N64(sectorSize); } } else { - print_Error(F("sectorSize not set"), true); + print_FatalError(F("sectorSize not set")); } // Close the file: @@ -3856,15 +3332,15 @@ void flashRepro_N64() { } else { print_Msg(writeErrors); print_Msg(F(" bytes ")); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { // Close the file myFile.close(); - print_Error(F("failed"), false); + print_Error(F("failed")); } } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); } // Prints string out of the common strings array either with or without newline @@ -4066,7 +3542,7 @@ void idFlashrom_N64() { } } if ((flashid == 0x1240) && (strcmp(cartID, "1240") == 0)) { - print_Error(F("Please reseat cartridge"), true); + print_FatalError(F("Please reseat cartridge")); } } @@ -4625,7 +4101,7 @@ void flashGameshark_N64() { // Compare file size to flashrom size if (fileSize > 262144) { - print_Error(file_too_big_STR, true); + print_FatalError(file_too_big_STR); } // SST 29LE010, chip erase not needed as this eeprom automaticly erases during the write cycle @@ -4655,17 +4131,17 @@ void flashGameshark_N64() { } else { print_Msg(writeErrors); print_Msg(F(" bytes ")); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); } } // If the ID is unknown show error message else { print_Msg(F("ID: ")); println_Msg(flashid_str); - print_Error(F("Unknown flashrom"), false); + print_Error(F("Unknown flashrom")); } // Prints string out of the common strings array either with or without newline @@ -4730,7 +4206,7 @@ void backupGameshark_N64() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } for (unsigned long currByte = romBase + 0xC00000; currByte < (romBase + 0xC00000 + 262144); currByte += 512) { diff --git a/Cart_Reader/NES.ino b/Cart_Reader/NES.ino index 76f6012..adc83e2 100644 --- a/Cart_Reader/NES.ino +++ b/Cart_Reader/NES.ino @@ -514,7 +514,7 @@ void getMapping() { sd.chdir(); if (!database.open("nes.txt", O_READ)) { - print_Error(F("Database file not found"), true); + print_FatalError(F("Database file not found")); // never reached } @@ -766,7 +766,7 @@ void readRom_NES() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } //Initialize progress bar @@ -825,7 +825,7 @@ void readRaw_NES() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } //Initialize progress bar @@ -1203,7 +1203,7 @@ void outputNES() { display_Clear(); println_Msg(F("PRG FILE FAILED!")); display_Update(); - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } if (has_header) { @@ -1223,7 +1223,7 @@ void outputNES() { display_Clear(); println_Msg(F("NES FILE FAILED!")); display_Update(); - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } if (has_header) { @@ -4163,7 +4163,7 @@ void writeRAM() { display_Clear(); if (ramsize == 0) { - print_Error(F("RAM SIZE 0K"), false); + print_Error(F("RAM SIZE 0K")); } else { fileBrowser(F("Select RAM File")); word base = 0x6000; @@ -4379,7 +4379,7 @@ void writeRAM() { display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } } diff --git a/Cart_Reader/NGP.ino b/Cart_Reader/NGP.ino index 288800a..540e298 100644 --- a/Cart_Reader/NGP.ino +++ b/Cart_Reader/NGP.ino @@ -47,7 +47,7 @@ void setup_NGP() { if (getCartInfo_NGP()) printCartInfo_NGP(); else - print_Error(F("Cartridge read error"), true); + print_FatalError(F("Cartridge read error")); } void ngpMenu() { @@ -215,7 +215,7 @@ void readROM_NGP(char* outPathBuf, size_t bufferSize) { // open file on sdcard if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); // write new folder number back to EEPROM foldern++; @@ -265,7 +265,7 @@ void scanChip_NGP() { // open file on sdcard if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); // write new folder number back to EEPROM foldern++; diff --git a/Cart_Reader/PCE.ino b/Cart_Reader/PCE.ino index 20b17f0..69fd0df 100644 --- a/Cart_Reader/PCE.ino +++ b/Cart_Reader/PCE.ino @@ -543,7 +543,7 @@ void read_tennokoe_bank_PCE(int bank_index) { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } pin_read_write_PCE(); @@ -683,7 +683,7 @@ void write_tennokoe_bank_PCE(int bank_index) { println_Msg(F("Verify failed...")); print_Msg(diffcnt); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } pin_init_PCE(); @@ -694,7 +694,7 @@ void write_tennokoe_bank_PCE(int bank_index) { display_Update(); wait(); } else { - print_Error(F("File doesn't exist"), false); + print_Error(F("File doesn't exist")); } } @@ -737,7 +737,7 @@ void read_rom_PCE(void) { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } pin_read_write_PCE(); diff --git a/Cart_Reader/PCW.ino b/Cart_Reader/PCW.ino index 3d47830..74165fa 100644 --- a/Cart_Reader/PCW.ino +++ b/Cart_Reader/PCW.ino @@ -185,7 +185,7 @@ void pcwMenu() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } break; @@ -478,7 +478,7 @@ void readROM_PCW() { EEPROM_writeAnything(0, foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } read_setup_PCW(); for (unsigned long address = 0; address < 0x400000; address += 512) { // 4MB @@ -521,7 +521,7 @@ void readMultiROM_PCW() { EEPROM_writeAnything(0, foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } display_Clear(); println_Msg(F("READING MULTI-PACK")); @@ -579,7 +579,7 @@ void readSRAM_PCW() { // readSRAM_1A() EEPROM_writeAnything(0, foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } display_Clear(); read_setup_PCW(); @@ -626,10 +626,10 @@ void writeSRAM_PCW() { print_STR(done_STR, 1); display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } display_Clear(); } @@ -652,7 +652,7 @@ unsigned long verifySRAM_PCW() { } myFile.close(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } return writeErrors; diff --git a/Cart_Reader/SFM.ino b/Cart_Reader/SFM.ino index 86ff0ab..5d48443 100644 --- a/Cart_Reader/SFM.ino +++ b/Cart_Reader/SFM.ino @@ -109,7 +109,7 @@ void sfmGameMenu() { println_Msg(F(" Timeout")); println_Msg(readBank_SFM(0, 0x2400), HEX); println_Msg(F("")); - print_Error(F("Powercycle SFM cart"), true); + print_FatalError(F("Powercycle SFM cart")); } } // Copy gameCode to romName in case of japanese chars in romName @@ -132,7 +132,7 @@ void sfmGameMenu() { mode = mode_SFM_Game; } } else { - print_Error(F("Switch to HiRom failed"), false); + print_Error(F("Switch to HiRom failed")); } } @@ -177,7 +177,7 @@ void sfmGameOptions() { print_STR(error_STR, 0); print_Msg(wrErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } break; @@ -246,7 +246,7 @@ void sfmFlashMenu() { // Read flash readFlash_SFM(); } else { - print_Error(F("Switch to HiRom failed"), false); + print_Error(F("Switch to HiRom failed")); } break; @@ -316,13 +316,13 @@ void sfmFlashMenu() { resetFlash_SFM(0xC0); resetFlash_SFM(0xE0); } else { - print_Error(F("Error: Wrong Flash ID"), true); + print_FatalError(F("Error: Wrong Flash ID")); } } else { - print_Error(F("Error: Wrong Flash ID"), true); + print_FatalError(F("Error: Wrong Flash ID")); } } else { - print_Error(F("failed"), false); + print_Error(F("failed")); } break; @@ -353,13 +353,13 @@ void sfmFlashMenu() { resetFlash_SFM(0xC0); resetFlash_SFM(0xE0); } else { - print_Error(F("Error: Wrong Flash ID"), true); + print_FatalError(F("Error: Wrong Flash ID")); } } else { - print_Error(F("Error: Wrong Flash ID"), true); + print_FatalError(F("Error: Wrong Flash ID")); } } else { - print_Error(F("failed"), false); + print_Error(F("failed")); } break; @@ -576,7 +576,7 @@ void setup_SFM() { #ifdef clockgen_installed else { display_Clear(); - print_Error(F("Clock Generator not found"), true); + print_FatalError(F("Clock Generator not found")); } #endif @@ -598,7 +598,7 @@ void setup_SFM() { println_Msg(F("Hirom All Timeout")); println_Msg(F("")); println_Msg(F("")); - print_Error(F("Powercycle SFM cart"), true); + print_FatalError(F("Powercycle SFM cart")); } } } @@ -903,7 +903,7 @@ void readROM_SFM() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } // Check if LoROM or HiROM... @@ -1078,7 +1078,7 @@ void writeFlash_SFM(int startBank, uint32_t pos) { myFile.close(); println_Msg(""); } else { - print_Error(open_file_STR, true); + print_FatalError(open_file_STR); } } @@ -1221,7 +1221,7 @@ unsigned long verifyFlash_SFM(int startBank, uint32_t pos) { } else { // SD Error verified = 999999; - print_Error(F("Can't open file on SD"), false); + print_Error(F("Can't open file on SD")); } // Return 0 if verified ok, or number of errors return verified; @@ -1241,7 +1241,7 @@ void readFlash_SFM() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } if (romType) { for (byte currBank = 0xC0; currBank < 0xC0 + numBanks; currBank++) { @@ -1385,7 +1385,7 @@ void readMapping() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Read the mapping info out of the 1st chip @@ -1471,10 +1471,10 @@ void eraseMapping(byte startBank) { dataIn(); controlIn_SFM(); } else { - print_Error(F("Error: Wrong Flash ID"), true); + print_FatalError(F("Error: Wrong Flash ID")); } } else { - print_Error(F("Unlock failed"), true); + print_FatalError(F("Unlock failed")); } } @@ -1599,17 +1599,17 @@ void writeMapping_SFM(byte startBank, uint32_t pos) { myFile.close(); println_Msg(""); } else { - print_Error(F("Can't open file on SD"), false); + print_Error(F("Can't open file on SD")); } // Switch to read dataIn(); controlIn_SFM(); } else { - print_Error(F("Error: Wrong Flash ID"), true); + print_FatalError(F("Error: Wrong Flash ID")); } } else { - print_Error(F("Unlock failed"), true); + print_FatalError(F("Unlock failed")); } } @@ -1717,7 +1717,7 @@ void write_SFM(int startBank, uint32_t pos) { println_Msg(F("OK")); display_Update(); } else { - print_Error(F("Could not erase flash"), true); + print_FatalError(F("Could not erase flash")); } } // Write flash @@ -1737,13 +1737,13 @@ void write_SFM(int startBank, uint32_t pos) { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, true); + print_FatalError(did_not_verify_STR); } } else { - print_Error(F("Error: Wrong Flash ID"), true); + print_FatalError(F("Error: Wrong Flash ID")); } } else { - print_Error(F("Unlock failed"), true); + print_FatalError(F("Unlock failed")); } } diff --git a/Cart_Reader/SMS.ino b/Cart_Reader/SMS.ino index 1020ed0..5f499cb 100644 --- a/Cart_Reader/SMS.ino +++ b/Cart_Reader/SMS.ino @@ -593,7 +593,7 @@ void readROM_SMS() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // set default bank size to 16KB @@ -678,7 +678,7 @@ void readSRAM_SMS() { // Open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } // Write the whole 32KB // When there is only 8KB of SRAM, the contents should be duplicated @@ -705,7 +705,7 @@ void writeSRAM_SMS() { display_Clear(); if (false) { - print_Error(F("DISABLED"), false); + print_Error(F("DISABLED")); } else { fileBrowser(F("Select file")); @@ -748,7 +748,7 @@ void writeSRAM_SMS() { print_STR(done_STR, 1); display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } } diff --git a/Cart_Reader/SNES.ino b/Cart_Reader/SNES.ino index fa10693..eab1339 100644 --- a/Cart_Reader/SNES.ino +++ b/Cart_Reader/SNES.ino @@ -216,7 +216,7 @@ void snesMenu() { display_Update(); } else { display_Clear(); - print_Error(F("Does not have ROM"), false); + print_Error(F("Does not have ROM")); } } break; @@ -229,7 +229,7 @@ void snesMenu() { readSRAM(); } else { display_Clear(); - print_Error(F("Does not have SRAM"), false); + print_Error(F("Does not have SRAM")); } break; @@ -248,11 +248,11 @@ void snesMenu() { print_STR(error_STR, 0); print_Msg(wrErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { display_Clear(); - print_Error(F("Does not have SRAM"), false); + print_Error(F("Does not have SRAM")); } break; @@ -283,11 +283,11 @@ void snesMenu() { print_STR(error_STR, 0); print_Msg(wrErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { display_Clear(); - print_Error(F("Does not have SRAM"), false); + print_Error(F("Does not have SRAM")); } break; @@ -465,7 +465,7 @@ void setup_Snes() { #ifdef clockgen_installed else { display_Clear(); - print_Error(F("Clock Generator not found"), true); + print_FatalError(F("Clock Generator not found")); } #endif @@ -1213,7 +1213,7 @@ unsigned int calc_checksum(char* fileName, char* folder) { return (calcChecksum); } else { // Else show error - print_Error(F("DUMP ROM 1ST"), false); + print_Error(F("DUMP ROM 1ST")); return 0; } } @@ -1240,7 +1240,7 @@ boolean compare_checksum() { } else { print_Msg(F(" != ")); println_Msg(checksumStr); - print_Error(F("Invalid Checksum"), false); + print_Error(F("Invalid Checksum")); display_Update(); return 0; } @@ -1275,7 +1275,7 @@ void readROM_SNES() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } //Dump Derby Stallion '96 (Japan) Actual Size is 24Mb @@ -1604,7 +1604,7 @@ void writeSRAM(boolean browseFile) { display_Update(); } else { - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } @@ -1628,7 +1628,7 @@ void readSRAM() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } int sramBanks = 0; if (romType == LO) { @@ -1904,7 +1904,7 @@ unsigned long verifySRAM() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } display_Update(); wait(); @@ -1921,7 +1921,7 @@ unsigned long verifySRAM() { myFile.close(); return writeErrors; } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); return 1; } } diff --git a/Cart_Reader/SV.ino b/Cart_Reader/SV.ino index ba61252..0d4650d 100644 --- a/Cart_Reader/SV.ino +++ b/Cart_Reader/SV.ino @@ -85,7 +85,7 @@ void svMenu() { print_STR(error_STR, 0); print_Msg(wrErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } wait(); break; @@ -122,7 +122,7 @@ void setup_SV() { #ifdef clockgen_installed else { display_Clear(); - print_Error(F("Clock Generator not found"), true); + print_FatalError(F("Clock Generator not found")); } #endif @@ -300,7 +300,7 @@ void readSRAM_SV() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } readBank_SV(0x10, 0); // Preconfigure to fix corrupt 1st byte @@ -371,7 +371,7 @@ void writeSRAM_SV() { println_Msg(F("SRAM writing finished")); display_Update(); } else { - print_Error(F("File doesnt exist"), false); + print_Error(F("File doesnt exist")); } } @@ -402,7 +402,7 @@ unsigned long verifySRAM_SV() { myFile.close(); return writeErrors; } else { - print_Error(F("Can't open file"), false); + print_Error(F("Can't open file")); return 1; } } @@ -438,7 +438,7 @@ void readROM_SV() { //open file on sd card if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); } // Read Banks @@ -470,7 +470,7 @@ void writeROM_SV(void) { //if CRC is not 8B86, BS-X cart is not inserted. Display error and reset if (strcmp("8B86", checksumStr) != 0) { display_Clear(); - print_Error(F("Error: Must use BS-X cart"), true); + print_FatalError(F("Error: Must use BS-X cart")); } //Display file Browser and wait user to select a file. Size must be 1MB. @@ -575,7 +575,7 @@ void writeROM_SV(void) { wait(); } else { - print_Error(F("File doesn't exist"), false); + print_Error(F("File doesn't exist")); } } diff --git a/Cart_Reader/VBOY.ino b/Cart_Reader/VBOY.ino index 709f360..d4ba7a7 100644 --- a/Cart_Reader/VBOY.ino +++ b/Cart_Reader/VBOY.ino @@ -122,7 +122,7 @@ void vboyMenu() { readSRAM_VB(); sd.chdir("/"); } else { - print_Error(F("Cart has no SRAM"), false); + print_Error(F("Cart has no SRAM")); } #if (defined(enable_OLED) || defined(enable_LCD)) // Wait for user input @@ -149,10 +149,10 @@ void vboyMenu() { print_STR(error_STR, 0); print_Msg(writeErrors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { - print_Error(F("Cart has no SRAM"), false); + print_Error(F("Cart has no SRAM")); } #if (defined(enable_OLED) || defined(enable_LCD)) // Wait for user input @@ -429,7 +429,7 @@ void readROM_VB() { EEPROM_writeAnything(0, foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } word d = 0; @@ -500,7 +500,7 @@ void writeSRAM_VB() { print_STR(done_STR, 1); display_Update(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } dataIn_VB(); } @@ -520,7 +520,7 @@ void readSRAM_VB() { EEPROM_writeAnything(0, foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } for (unsigned long currBuffer = 0; currBuffer < sramSize; currBuffer += 512) { for (int currByte = 0; currByte < 512; currByte++) { @@ -554,7 +554,7 @@ unsigned long verifySRAM_VB() { } myFile.close(); } else { - print_Error(sd_error_STR, true); + print_FatalError(sd_error_STR); } return writeErrors; diff --git a/Cart_Reader/WS.ino b/Cart_Reader/WS.ino index 727f239..30583e8 100644 --- a/Cart_Reader/WS.ino +++ b/Cart_Reader/WS.ino @@ -77,10 +77,10 @@ void setup_WS() { // unlock MMC // if (!unlockMMC2003_WS()) - // print_Error(F("Can't initial MMC"), true); + // print_FatalError(F("Can't initial MMC")); // if (getCartInfo_WS() != 0xea) - // print_Error(F("Rom header read error"), true); + // print_FatalError(F("Rom header read error")); println_Msg(F("Initializing...")); display_Update(); @@ -496,7 +496,7 @@ void readROM_WS(char *outPathBuf, size_t bufferSize) { // open file on sdcard if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); // write new folder number back to EEPROM foldern++; @@ -563,7 +563,7 @@ void readSRAM_WS() { EEPROM_writeAnything(0, foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); uint32_t bank_size = (sramSize << 7); uint16_t end_bank = (bank_size >> 16); // 64KB per bank @@ -635,10 +635,10 @@ void verifySRAM_WS() { print_STR(error_STR, 0); print_Msg(write_errors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { - print_Error(F("File doesn't exist"), false); + print_Error(F("File doesn't exist")); } } @@ -684,7 +684,7 @@ void writeSRAM_WS() { println_Msg(F("Writing finished")); display_Update(); } else { - print_Error(F("File doesn't exist"), false); + print_Error(F("File doesn't exist")); } } @@ -708,7 +708,7 @@ void readEEPROM_WS() { EEPROM_writeAnything(0, foldern); if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); uint32_t eepromSize = (sramSize << 7); uint32_t bufSize = (eepromSize < 512 ? eepromSize : 512); @@ -789,10 +789,10 @@ void verifyEEPROM_WS() { print_STR(error_STR, 0); print_Msg(write_errors); print_STR(_bytes_STR, 1); - print_Error(did_not_verify_STR, false); + print_Error(did_not_verify_STR); } } else { - print_Error(F("File doesn't exist"), false); + print_Error(F("File doesn't exist")); } } @@ -843,7 +843,7 @@ void writeEEPROM_WS() { print_STR(done_STR, 1); } else { - print_Error(F("File doesn't exist"), false); + print_Error(F("File doesn't exist")); } } @@ -857,7 +857,7 @@ void writeWitchOS_WS() { dataIn_WS(); if (readWord_WS(0xe0004) || readWord_WS(0xe4004) || readWord_WS(0xec004) || readWord_WS(0xee004)) { display_Clear(); - print_Error(F("OS sectors are protected!"), false); + print_Error(F("OS sectors are protected!")); } else { filePath[0] = 0; sd.chdir("/"); @@ -932,7 +932,7 @@ void writeWitchOS_WS() { print_STR(done_STR, 1); } else { - print_Error(F("File doesn't exist"), false); + print_Error(F("File doesn't exist")); } } @@ -976,7 +976,7 @@ boolean compareChecksum_WS(const char *wsFilePath) { display_Update(); if (!myFile.open(wsFilePath, O_READ)) { - print_Error(F("Failed to open file"), false); + print_Error(F("Failed to open file")); return 0; } @@ -1013,7 +1013,7 @@ boolean compareChecksum_WS(const char *wsFilePath) { display_Update(); return 1; } else { - print_Error(F("Checksum Error"), false); + print_Error(F("Checksum Error")); return 0; } } diff --git a/Cart_Reader/WSV.ino b/Cart_Reader/WSV.ino index 65d56b1..1e4034d 100644 --- a/Cart_Reader/WSV.ino +++ b/Cart_Reader/WSV.ino @@ -205,7 +205,7 @@ void readROM_WSV() { // open file on sdcard if (!myFile.open(fileName, O_RDWR | O_CREAT)) - print_Error(create_file_STR, true); + print_FatalError(create_file_STR); // write new folder number back to EEPROM foldern++; @@ -516,7 +516,7 @@ void setCart_WSV() { } } } else { - print_Error(F("Database file not found"), true); + print_FatalError(F("Database file not found")); } } #endif