From a981bb0c3e9143cb1268e77311eadaa620eff621 Mon Sep 17 00:00:00 2001 From: sanni Date: Thu, 14 Oct 2021 09:53:07 +0200 Subject: [PATCH] Make clockgen calibration optional --- Cart_Reader/Cart_Reader.ino | 10 +++--- Cart_Reader/MD.ino | 70 ++++++++++++++++++------------------- Cart_Reader/N64.ino | 43 +++++++++++++---------- Cart_Reader/NGP.ino | 52 +++++++++++++-------------- Cart_Reader/NP.ino | 5 +++ Cart_Reader/RTC.cpp | 6 ++-- Cart_Reader/SNES.ino | 6 +++- Cart_Reader/options.h | 22 +++++++----- Cart_Reader/snes_clk.h | 2 -- 9 files changed, 116 insertions(+), 100 deletions(-) diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index 7c2e76d..5015a1f 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -4,8 +4,8 @@ This project represents a community-driven effort to provide an easy to build and easy to modify cartridge dumper. - Date: 02.10.2021 - Version: 6.7 + Date: 14.10.2021 + Version: 6.8 SD lib: https://github.com/greiman/SdFat LCD lib: https://github.com/adafruit/Adafruit_SSD1306 @@ -33,14 +33,14 @@ Gens-gs - Megadrive checksum And a special Thank You to all coders and contributors on Github and the Arduino forum: - jiyunomegami, splash5, Kreeblah, ramapcsx2, PsyK0p4T, Dakkaron, Pickle, sdhizumi, + jiyunomegami, splash5, Kreeblah, ramapcsx2, PsyK0p4T, Dakkaron, Pickle, sdhizumi, sakman55, Uzlopak, scrap-a, majorpbx, borti4938, Modman, philenotfound, vogelfreiheit - + And to nocash for figuring out the secrets of the SFC Nintendo Power cartridge. **********************************************************************************/ -char ver[5] = "6.7"; +char ver[5] = "6.8"; /****************************************** Libraries diff --git a/Cart_Reader/MD.ino b/Cart_Reader/MD.ino index 3607e46..b966ea5 100644 --- a/Cart_Reader/MD.ino +++ b/Cart_Reader/MD.ino @@ -91,7 +91,7 @@ int segaSram16bit = DEFAULT_VALUE_segaSram16bit; //***************************************** // SONIC & KNUCKLES LOCK-ON MODE VARIABLES -// SnKmode : +// SnKmode : // 0 = Not Sonic & Knuckles // 1 = Only Sonic & Knucles // 2 = Sonic & Knucles + Sonic1 @@ -663,7 +663,7 @@ void getCartInfo_MD() { sdBuffer[c] = hiByte; sdBuffer[c + 1] = loByte; } - for(int i=0; i<14; i++){ + for (int i = 0; i < 14; i++) { id[i] = char(sdBuffer[i]); } @@ -681,7 +681,7 @@ void getCartInfo_MD() { sdBuffer[c] = hiByte; sdBuffer[c + 1] = loByte; } - for(int i=0; i<16; i++){ + for (int i = 0; i < 16; i++) { labelLockon[i] = char(sdBuffer[i]); } @@ -704,29 +704,29 @@ void getCartInfo_MD() { sdBuffer[c] = hiByte; sdBuffer[c + 1] = loByte; } - for(int i=0; i<14; i++){ + for (int i = 0; i < 14; i++) { idLockon[i] = char(sdBuffer[i]); } - if (!(strncmp("GM 00001009-0", idLockon,13) & strncmp("GM 00004049-0", idLockon,13) )) { + if (!(strncmp("GM 00001009-0", idLockon, 13) & strncmp("GM 00004049-0", idLockon, 13) )) { //Sonic1 ID:GM 00001009-0? or GM 00004049-0? SnKmode = 2; - }else if (!(strcmp("GM 00001051-00", idLockon) & strcmp("GM 00001051-01", idLockon) & strcmp("GM 00001051-02", idLockon))) { + } else if (!(strcmp("GM 00001051-00", idLockon) & strcmp("GM 00001051-01", idLockon) & strcmp("GM 00001051-02", idLockon))) { //Sonic2 ID:GM 00001051-00 or GM 00001051-01 or GM 00001051-02 SnKmode = 3; // Prepare Sonic2 Banks writeSSF2Map(0x509878, 1); // 0xA130F1 - }else if (!strcmp("GM MK-1079 -00", idLockon)) { + } else if (!strcmp("GM MK-1079 -00", idLockon)) { //Sonic3 ID:GM MK-1079 -00 SnKmode = 4; - }else{ + } else { //Other game SnKmode = 5; } - }else{ + } else { SnKmode = 1; } } @@ -926,20 +926,20 @@ void getCartInfo_MD() { } //Get Lock-on cart name - if(SnKmode>=2){ + if (SnKmode >= 2) { //Change romName - strcpy(romName,"SnK_"); + strcpy(romName, "SnK_"); - for (byte c = 0; c < 48; c += 2) { - // split word - word myWord = readWord_MD((0x200150 + c) / 2); - byte loByte = myWord & 0xFF; - byte hiByte = myWord >> 8; + for (byte c = 0; c < 48; c += 2) { + // split word + word myWord = readWord_MD((0x200150 + c) / 2); + byte loByte = myWord & 0xFF; + byte hiByte = myWord >> 8; - // write to buffer - sdBuffer[c] = hiByte; - sdBuffer[c + 1] = loByte; + // write to buffer + sdBuffer[c] = hiByte; + sdBuffer[c + 1] = loByte; } byte myLength = 0; for (unsigned int i = 0; i < 48; i++) { @@ -949,11 +949,11 @@ void getCartInfo_MD() { } } - switch(SnKmode){ - case 2: strcat(romName,"SONIC1"); break; - case 3: strcat(romName,"SONIC2"); break; - case 4: strcat(romName,"SONIC3"); break; - case 5: strcat(romName,romNameLockon); break; + switch (SnKmode) { + case 2: strcat(romName, "SONIC1"); break; + case 3: strcat(romName, "SONIC2"); break; + case 4: strcat(romName, "SONIC3"); break; + case 5: strcat(romName, romNameLockon); break; } } @@ -983,25 +983,25 @@ void getCartInfo_MD() { } print_Msg(F("Size: ")); print_Msg(cartSize * 8 / 1024 / 1024 ); - switch(SnKmode){ + switch (SnKmode) { case 2: case 4: case 5: print_Msg(F("+")); print_Msg(cartSizeLockon * 8 / 1024 / 1024 ); break; - case 3: + case 3: print_Msg(F("+")); print_Msg(cartSizeLockon * 8 / 1024 / 1024 ); print_Msg(F("+")); print_Msg(cartSizeSonic2 * 8 / 1024 / 1024 ); - break; + break; } println_Msg(F(" MBit")); print_Msg(F("ChkS: ")); print_Msg_PaddedHexByte((chksum >> 8)); print_Msg_PaddedHexByte((chksum & 0x00ff)); - switch(SnKmode){ + switch (SnKmode) { case 2: case 4: case 5: @@ -1128,8 +1128,8 @@ void readROM_MD() { //Initialize progress bar uint32_t processedProgressBar = 0; uint32_t totalProgressBar = (uint32_t)(cartSize); - if(SnKmode>=2) totalProgressBar += (uint32_t) cartSizeLockon; - if(SnKmode==3) totalProgressBar += (uint32_t) cartSizeSonic2; + if (SnKmode >= 2) totalProgressBar += (uint32_t) cartSizeLockon; + if (SnKmode == 3) totalProgressBar += (uint32_t) cartSizeSonic2; draw_progressbar(0, totalProgressBar); for (unsigned long currBuffer = 0; currBuffer < cartSize / 2; currBuffer += 512) { @@ -1184,7 +1184,7 @@ void readROM_MD() { processedProgressBar += 1024; draw_progressbar(processedProgressBar, totalProgressBar); } - if(SnKmode >= 2){ + if (SnKmode >= 2) { for (unsigned long currBuffer = 0; currBuffer < cartSizeLockon / 2; currBuffer += 512) { // Blink led if (currBuffer % 16384 == 0) @@ -1229,7 +1229,7 @@ void readROM_MD() { draw_progressbar(processedProgressBar, totalProgressBar); } } - if(SnKmode == 3){ + if (SnKmode == 3) { for (unsigned long currBuffer = 0; currBuffer < cartSizeSonic2 / 2; currBuffer += 512) { // Blink led if (currBuffer % 16384 == 0) @@ -1238,7 +1238,7 @@ void readROM_MD() { d = 0; for (int currWord = 0; currWord < 512; currWord++) { - unsigned long myAddress = currBuffer + currWord + (cartSize+cartSizeLockon) / 2; + unsigned long myAddress = currBuffer + currWord + (cartSize + cartSizeLockon) / 2; PORTF = myAddress & 0xFF; PORTK = (myAddress >> 8) & 0xFF; PORTL = (myAddress >> 16) & 0xFF; @@ -1299,7 +1299,7 @@ void readROM_MD() { print_Error(F(""), false); display_Update(); } - if(SnKmode >= 2){ + if (SnKmode >= 2) { if (chksumLockon == calcCKSLockon) { println_Msg(F("Checksum2 OK")); display_Update(); @@ -1313,7 +1313,7 @@ void readROM_MD() { display_Update(); } } - if(SnKmode == 3){ + if (SnKmode == 3) { if (chksumSonic2 == calcCKSSonic2) { println_Msg(F("Checksum3 OK")); display_Update(); diff --git a/Cart_Reader/N64.ino b/Cart_Reader/N64.ino index 0bf5a17..4782e47 100644 --- a/Cart_Reader/N64.ino +++ b/Cart_Reader/N64.ino @@ -421,13 +421,18 @@ void setup_N64_Cart() { #ifdef clockgen_installed // Adafruit Clock Generator - // last number is the clock correction factor which is custom for each clock generator + +#ifdef clockgen_calibration int32_t clock_offset = readClockOffset(); if (clock_offset > INT32_MIN) { clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, clock_offset); } else { clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); } +#else + // last number is the clock correction factor which is custom for each clock generator + clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); +#endif // Set Eeprom clock to 2Mhz clockgen.set_freq(200000000ULL, SI5351_CLK1); @@ -1713,7 +1718,7 @@ int strcicmp(char const * a, char const * b) } } -#ifdef slowcrc +#ifndef fastcrc // Calculate dumped rom's CRC32 inline uint32_t updateCRC64(uint8_t ch, uint32_t crc) { uint32_t idx = ((crc) ^ (ch)) & 0xff; @@ -1889,21 +1894,21 @@ void idCart() { } } -// Get CRC1 -for (int i = 0; i < 4; i++) { - if (sdBuffer[0x10 + i] < 0x10) { - CRC1 += '0'; + // Get CRC1 + for (int i = 0; i < 4; i++) { + if (sdBuffer[0x10 + i] < 0x10) { + CRC1 += '0'; + } + CRC1 += String(sdBuffer[0x10 + i], HEX); } - CRC1 += String(sdBuffer[0x10 + i], HEX); -} -// Get CRC2 -for (int i = 0; i < 4; i++) { - if (sdBuffer[0x14 + i] < 0x10) { - CRC2 += '0'; + // Get CRC2 + for (int i = 0; i < 4; i++) { + if (sdBuffer[0x14 + i] < 0x10) { + CRC2 += '0'; + } + CRC2 += String(sdBuffer[0x14 + i], HEX); } - CRC2 += String(sdBuffer[0x14 + i], HEX); -} } /****************************************** @@ -2908,7 +2913,7 @@ redumpsamefolder: } // dumping rom slow -#ifdef slowcrc +#ifndef fastcrc // get current time unsigned long startTime = millis(); @@ -3175,14 +3180,14 @@ void savesummary_N64(boolean checkfound, char crcStr[9], unsigned long timeElaps myFile.print(F("Saved To: ")); myFile.println(folder); - #ifdef RTC_installed +#ifdef RTC_installed myFile.print(F("Dumped\t: ")); myFile.println(RTCStamp()); - #endif - +#endif + myFile.print(F("CRC\t: ")); myFile.print(crcStr); - + if (checkfound) { // Dump was a known good rom // myFile.println(F("Checksum matches")); diff --git a/Cart_Reader/NGP.ino b/Cart_Reader/NGP.ino index 44c946c..76ea0d3 100644 --- a/Cart_Reader/NGP.ino +++ b/Cart_Reader/NGP.ino @@ -45,7 +45,7 @@ void setup_NGP() { println_Msg(F("Initializing...")); display_Update(); - + if (getCartInfo_NGP()) printCartInfo_NGP(); else @@ -91,8 +91,8 @@ bool getCartInfo_NGP() { dataIn(); cartSize = 0; - - // get chip manufacturer and device IDs + + // get chip manufacturer and device IDs manufacturerID = readByte_NGP(0); deviceID = readByte_NGP(1); tmp = (uint8_t*)&romSize; @@ -123,14 +123,14 @@ bool getCartInfo_NGP() { // get app ID snprintf(cartID, 5, "%02X%02X", readByte_NGP(0x21), readByte_NGP(0x20)); - + // force rom size to 32 Mbits for few titles - if (strcmp(cartID,"0060") == 0 || strcmp(cartID,"0061") == 0 || strcmp(cartID,"0069") == 0 ) + if (strcmp(cartID, "0060") == 0 || strcmp(cartID, "0061") == 0 || strcmp(cartID, "0069") == 0 ) cartSize = 4194304; - - // get app version + + // get app version snprintf(ngpRomVersion, 3, "%02X", readByte_NGP(0x22)); - + // get app system compatibility ngpSystemType = readByte_NGP(0x23); @@ -181,7 +181,7 @@ void readROM_NGP(char *outPathBuf, size_t bufferSize) { // Set cartsize manually if chip ID is unknown if (cartSize == 0) { unsigned char ngpRomMenu; - + // Copy menuOptions out of progmem convertPgm(ngpRomOptions, 4); ngpRomMenu = question_box(F("Select ROM size"), menuOptions, 4, 0); @@ -194,7 +194,7 @@ void readROM_NGP(char *outPathBuf, size_t bufferSize) { case 3: cartSize = 4194304; break; } } - + // generate fullname of rom file snprintf(fileName, FILENAME_LENGTH, "%s.ngp", romName); @@ -249,7 +249,7 @@ void scanChip_NGP() { uint32_t block_addr = 0; // generate name of report file - snprintf(fileName, FILENAME_LENGTH, "%s.txt",romName); + snprintf(fileName, FILENAME_LENGTH, "%s.txt", romName); // create a new folder to save report file EEPROM_readAnything(0, foldern); @@ -277,11 +277,11 @@ void scanChip_NGP() { myFile.println(""); // write chip info to report file - myFile.println("Chip manufacturer ID : 0x" + String(manufacturerID,HEX)); - myFile.println("Chip device ID : 0x" + String(deviceID,HEX)); + myFile.println("Chip manufacturer ID : 0x" + String(manufacturerID, HEX)); + myFile.println("Chip device ID : 0x" + String(deviceID, HEX)); myFile.println(""); - if(cartSize == 0) + if (cartSize == 0) myFile.println("Cart size unknown"); else { // enter autoselect mode @@ -295,29 +295,29 @@ void scanChip_NGP() { uint8_t sectorID = 0; // skip the 2nd 16Mbits chip - if (cartSize == 4194304){ + if (cartSize == 4194304) { myFile.println("Warning: this cart is 32Mbits. Only the first 16Mbits chip will be scanned."); myFile.println(""); addrMax = 2097152; } else addrMax = cartSize; - - myFile.println("Sector | Start address | Status"); - - // browse sectors - for(uint32_t addr = 0; addr < addrMax; addr+= 0x1000) { - if( (addr%0x10000 == 0) || (addr == addrMax-0x8000) || (addr == addrMax-0x6000) || (addr == addrMax-0x4000)){ - - myFile.print("#" + String(sectorID) + " | 0x" + String(addr,HEX) + " | "); - + myFile.println("Sector | Start address | Status"); + + // browse sectors + for (uint32_t addr = 0; addr < addrMax; addr += 0x1000) { + + if ( (addr % 0x10000 == 0) || (addr == addrMax - 0x8000) || (addr == addrMax - 0x6000) || (addr == addrMax - 0x4000)) { + + myFile.print("#" + String(sectorID) + " | 0x" + String(addr, HEX) + " | "); + // check the protection status - if(readByte_NGP(addr + 0x2) == 0) + if (readByte_NGP(addr + 0x2) == 0) myFile.println("unprotected"); else myFile.println("protected"); - + sectorID += 1; } } diff --git a/Cart_Reader/NP.ino b/Cart_Reader/NP.ino index 26d7b76..56392f8 100644 --- a/Cart_Reader/NP.ino +++ b/Cart_Reader/NP.ino @@ -606,12 +606,17 @@ void setup_SFM() { //PORTH &= ~(1 << 1); // Adafruit Clock Generator +#ifdef clockgen_calibration int32_t clock_offset = readClockOffset(); if (clock_offset > INT32_MIN) { clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, clock_offset); } else { clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); } +#else + clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); +#endif + clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA); clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB); clockgen.set_freq(2147727200ULL, SI5351_CLK0); diff --git a/Cart_Reader/RTC.cpp b/Cart_Reader/RTC.cpp index 18debec..da4aee2 100644 --- a/Cart_Reader/RTC.cpp +++ b/Cart_Reader/RTC.cpp @@ -13,7 +13,7 @@ void RTCStart() { // Set RTC Date/Time of Sketch Build if it lost battery power // After initial setup it would have lost battery power ;) if (rtc.lostPower()) { - rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); + rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } } @@ -38,14 +38,14 @@ void dateTime(uint16_t* date, uint16_t* time) { String RTCStamp() { // Set a format char dtstamp[] = "DDMMMYYYY hh:mm:ssAP"; - + // Get current Date/Time DateTime now = rtc.now(); // Convert it to a string and caps lock it String dts = now.toString(dtstamp); dts.toUpperCase(); - + // Print results return dts; } diff --git a/Cart_Reader/SNES.ino b/Cart_Reader/SNES.ino index 2f9c75a..b4c17bd 100644 --- a/Cart_Reader/SNES.ino +++ b/Cart_Reader/SNES.ino @@ -436,13 +436,17 @@ void setup_Snes() { //PORTJ &= ~(1 << 0); // Adafruit Clock Generator - // last number is the clock correction factor which is custom for each clock generator +#ifdef clockgen_calibration int32_t clock_offset = readClockOffset(); if (clock_offset > INT32_MIN) { clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, clock_offset); } else { clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); } +#else + // last number is the clock correction factor which is custom for each clock generator + clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0); +#endif // Set clocks to 4Mhz/1Mhz for better SA-1 unlocking clockgen.set_freq(100000000ULL, SI5351_CLK1); // CPU diff --git a/Cart_Reader/options.h b/Cart_Reader/options.h index 7d020c0..c793396 100644 --- a/Cart_Reader/options.h +++ b/Cart_Reader/options.h @@ -9,10 +9,18 @@ // be sure to change the Arduino Serial Monitor to no line ending #define enable_OLED // Skip OLED start-up animation -//#define fast_start +// #define fast_start + // Enable the second button #define enable_Button2 +// Setup RTC if installed. +// remove // if you have an RTC installed +// #define RTC_installed + +// Use calibration data from snes_clk.txt +// #define clockgen_calibration + //****************************************** // ENABLED MODULES //****************************************** @@ -35,14 +43,10 @@ //****************************************** // Read N64 Eeprom with Adadruit clockgen, CLK1 switch needs to be switch to ON // add // and disable CLK1 switch if you don't have the clockgen installed or if you want to read a repros save -#define clockgen_installed +// #define clockgen_installed -// Define CRC method for dumping N64 ROMs, slow seems to be more compatible with some SD cards -#define slowcrc // crc will be calculated after dumping from SD card instead of during dumping from memory +// The CRC for N64 Roms will be calculated during dumping from memory instead of after dumping from SD card, not compatible to all Cart Readers +// #define fastcrc // saves a n64log.txt file with rom info in /N64/ROM -#define savesummarytotxt - -// Setup RTC if installed. -// remove // if you have an RTC installed -// #define RTC_installed +// #define savesummarytotxt diff --git a/Cart_Reader/snes_clk.h b/Cart_Reader/snes_clk.h index a9a3bfe..bab38f7 100644 --- a/Cart_Reader/snes_clk.h +++ b/Cart_Reader/snes_clk.h @@ -3,7 +3,5 @@ #include "SdFat.h" #include "atoi32.h" - int32_t readClockOffset(); - #endif