mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-10 23:15:08 +01:00
Add no-intro database to NES
This is just a beta release, stuff might be broken.
This commit is contained in:
parent
9ef81c2912
commit
0a4a4d0039
@ -4,7 +4,7 @@
|
||||
This project represents a community-driven effort to provide
|
||||
an easy to build and easy to modify cartridge dumper.
|
||||
|
||||
Date: 03.07.2022
|
||||
Date: 07.07.2022
|
||||
Version: 9.0 BETA
|
||||
|
||||
SD lib: https://github.com/greiman/SdFat
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
And a special Thank You to all coders and contributors on Github and the Arduino forum:
|
||||
jiyunomegami, splash5, Kreeblah, ramapcsx2, PsyK0p4T, Dakkaron, majorpbx, Pickle, sdhizumi,
|
||||
Uzlopak, sakman55, scrap-a, Tombo89, borti4938, vogelfreiheit, CaitSith2, Modman, philenotfound
|
||||
Uzlopak, sakman55, Tombo89, scrap-a, Tombo89, borti4938, vogelfreiheit, CaitSith2, Modman, philenotfound
|
||||
|
||||
And to nocash for figuring out the secrets of the SFC Nintendo Power cartridge.
|
||||
|
||||
@ -60,12 +60,108 @@
|
||||
|
||||
char ver[5] = "9.0B";
|
||||
|
||||
//******************************************
|
||||
// !!! CHOOSE HARDWARE VERSION !!!
|
||||
//******************************************
|
||||
// Remove // in front of the line with your hardware version
|
||||
// #define HW5
|
||||
// #define HW4
|
||||
// #define HW3
|
||||
// #define HW2
|
||||
// #define HW1
|
||||
// #define SERIAL_MONITOR
|
||||
|
||||
#if !(defined(HW1) || defined(HW2) || defined(HW3) || defined(HW4) || defined(HW5) || defined(SERIAL_MONITOR))
|
||||
# error !!! PLEASE CHOOSE HARDWARE VERSION !!!
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// HW CONFIGS
|
||||
//******************************************
|
||||
#if (defined(HW4) || defined(HW5))
|
||||
#define enable_LCD
|
||||
#define enable_neopixel
|
||||
#define background_color 100,0,0 //Green, Red, Blue
|
||||
#define enable_rotary
|
||||
// #define rotate_counter_clockwise
|
||||
#define clockgen_installed
|
||||
#define fastcrc
|
||||
#define ws_adapter_v2
|
||||
#endif
|
||||
|
||||
#if (defined(HW2) || defined(HW3))
|
||||
#define enable_OLED
|
||||
#define enable_Button2
|
||||
// #define clockgen_installed
|
||||
// #define fastcrc
|
||||
#endif
|
||||
|
||||
#if defined(HW1)
|
||||
#define enable_OLED
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_MONITOR)
|
||||
#define enable_serial
|
||||
#define clockgen_installed
|
||||
#define fastcrc
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// OPTIONS
|
||||
//******************************************
|
||||
// Change mainMenu to snsMenu, mdMenu, n64Menu, gbxMenu, pcsMenu,
|
||||
// flashMenu, nesMenu or smsMenu for single slot Cart Readers
|
||||
#define startMenu mainMenu
|
||||
|
||||
// Write all info to OSCR_LOG.txt in root dir
|
||||
#define global_log
|
||||
|
||||
// Renames ROM if found in database
|
||||
#define no-intro
|
||||
|
||||
// Ignores errors that normally force a reset if button 2 is pressed
|
||||
// #define debug_mode
|
||||
|
||||
// Setup RTC if installed.
|
||||
// #define RTC_installed
|
||||
|
||||
// Use calibration data from snes_clk.txt
|
||||
// #define clockgen_calibration
|
||||
|
||||
// Use Adafruit Clock Generator
|
||||
// #define clockgen_installed
|
||||
|
||||
// I don't know
|
||||
//#define use_md_conf
|
||||
|
||||
// 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
|
||||
|
||||
//******************************************
|
||||
// DISABLE MODULES
|
||||
//******************************************
|
||||
// add // before #define to disable a module
|
||||
#define enable_SNES
|
||||
#define enable_NP
|
||||
#define enable_SV
|
||||
|
||||
#define enable_MD
|
||||
#define enable_SMS
|
||||
|
||||
#define enable_N64
|
||||
#define enable_GBX
|
||||
#define enable_NES
|
||||
#define enable_FLASH
|
||||
#define enable_PCE
|
||||
#define enable_WS
|
||||
#define enable_NGP
|
||||
|
||||
/******************************************
|
||||
Libraries
|
||||
*****************************************/
|
||||
// Options
|
||||
#include "options.h"
|
||||
|
||||
// Basic Libs
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
@ -367,14 +463,17 @@ inline uint32_t updateCRC(uint8_t ch, uint32_t crc) {
|
||||
}
|
||||
|
||||
// Calculate rom's CRC32 from SD
|
||||
uint32_t calculateCRC(char* fileName, char* folder) {
|
||||
uint32_t calculateCRC(char* fileName, char* folder, int offset) {
|
||||
// Open folder
|
||||
sd.chdir(folder);
|
||||
// Open file
|
||||
if (myFile.open(fileName, O_READ)) {
|
||||
uint32_t oldcrc32 = 0xFFFFFFFF;
|
||||
|
||||
for (unsigned long currByte = 0; currByte < (myFile.fileSize() / 512); currByte++) {
|
||||
// Skip iNES header
|
||||
myFile.seek(offset);
|
||||
|
||||
for (unsigned long currByte = 0; currByte < ((myFile.fileSize() - offset) / 512); currByte++) {
|
||||
myFile.read(sdBuffer, 512);
|
||||
for (int c = 0; c < 512; c++) {
|
||||
oldcrc32 = updateCRC(sdBuffer[c], oldcrc32);
|
||||
@ -446,7 +545,7 @@ void get_line(char* str_buf, FsFile* readfile, uint8_t maxi)
|
||||
}
|
||||
|
||||
// Calculate CRC32 if needed and compare it to CRC read from database
|
||||
boolean compareCRC(char* database, char* crcString) {
|
||||
boolean compareCRC(char* database, char* crcString, int offset) {
|
||||
#ifdef no-intro
|
||||
char crcStr[9];
|
||||
if (crcString == 0) {
|
||||
@ -455,7 +554,7 @@ boolean compareCRC(char* database, char* crcString) {
|
||||
// Calculate CRC32
|
||||
print_Msg(F("CRC32... "));
|
||||
display_Update();
|
||||
sprintf(crcStr, "%08lX", calculateCRC(fileName, folder));
|
||||
sprintf(crcStr, "%08lX", calculateCRC(fileName, folder, offset));
|
||||
}
|
||||
else {
|
||||
// Use precalculated crc
|
||||
@ -579,7 +678,11 @@ void mainMenu() {
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_NES();
|
||||
checkStatus_NES();
|
||||
#ifdef no-intro
|
||||
checkStatus_NES(getMapping());
|
||||
#else
|
||||
checkStatus_NES(0);
|
||||
#endif
|
||||
nesMenu();
|
||||
mode = mode_NES;
|
||||
break;
|
||||
@ -734,7 +837,11 @@ void addonsMenu() {
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_NES();
|
||||
checkStatus_NES();
|
||||
#ifdef no-intro
|
||||
checkStatus_NES(getMapping());
|
||||
#else
|
||||
checkStatus_NES(0);
|
||||
#endif
|
||||
nesMenu();
|
||||
mode = mode_NES;
|
||||
break;
|
||||
@ -871,6 +978,341 @@ void draw_progressbar(uint32_t processed, uint32_t total) {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************
|
||||
RTC Module
|
||||
*****************************************/
|
||||
#ifdef RTC_installed
|
||||
|
||||
#include "RTC.h"
|
||||
#include "SdFat.h"
|
||||
|
||||
RTC_DS3231 rtc;
|
||||
|
||||
// Start Time
|
||||
void RTCStart() {
|
||||
// Start RTC
|
||||
if (! rtc.begin()) {
|
||||
abort();
|
||||
}
|
||||
|
||||
// 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__)));
|
||||
}
|
||||
}
|
||||
|
||||
// Set Date/Time Callback Funtion
|
||||
// Callback for file timestamps
|
||||
void dateTime(uint16_t* date, uint16_t* time) {
|
||||
DateTime now = rtc.now();
|
||||
|
||||
// Return date using FAT_DATE macro to format fields
|
||||
*date = FAT_DATE(now.year(), now.month(), now.day());
|
||||
|
||||
// Return time using FAT_TIME macro to format fields
|
||||
*time = FAT_TIME(now.hour(), now.minute(), now.second());
|
||||
}
|
||||
|
||||
|
||||
/******************************************
|
||||
RTC Time Stamp Setup
|
||||
Call in any other script
|
||||
*****************************************/
|
||||
// Format a Date/Time stamp
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************
|
||||
Clockgen Calibration
|
||||
*****************************************/
|
||||
#ifdef clockgen_calibration
|
||||
#include <FreqCount.h>
|
||||
#include "snes_clk.h"
|
||||
#include "SdFat.h"
|
||||
|
||||
int32_t cal_factor = 0;
|
||||
int32_t old_cal = 0;
|
||||
int32_t cal_offset = 100;
|
||||
|
||||
void clkcal() {
|
||||
// Adafruit Clock Generator
|
||||
// last number is the clock correction factor which is custom for each clock generator
|
||||
cal_factor = readClockOffset();
|
||||
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
display.print("Read correction: ");
|
||||
display.println(cal_factor);
|
||||
display.display();
|
||||
delay(500);
|
||||
|
||||
if (cal_factor > INT32_MIN) {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, cal_factor);
|
||||
} else {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
cal_factor = 0;
|
||||
}
|
||||
|
||||
if (!i2c_found) {
|
||||
display_Clear();
|
||||
print_Error(F("Clock Generator not found"), true);
|
||||
}
|
||||
|
||||
//clockgen.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
||||
//clockgen.pll_reset(SI5351_PLLA);
|
||||
//clockgen.pll_reset(SI5351_PLLB);
|
||||
clockgen.set_freq(400000000ULL, SI5351_CLK0);
|
||||
clockgen.set_freq(100000000ULL, SI5351_CLK1);
|
||||
clockgen.set_freq(307200000ULL, SI5351_CLK2);
|
||||
clockgen.output_enable(SI5351_CLK1, 1);
|
||||
clockgen.output_enable(SI5351_CLK2, 1);
|
||||
clockgen.output_enable(SI5351_CLK0, 1);
|
||||
|
||||
// Frequency Counter
|
||||
delay(500);
|
||||
FreqCount.begin(1000);
|
||||
while (1)
|
||||
{
|
||||
if (old_cal != cal_factor) {
|
||||
display_Clear();
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(" Adjusting"));
|
||||
display_Update();
|
||||
clockgen.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
||||
clockgen.pll_reset(SI5351_PLLA);
|
||||
clockgen.pll_reset(SI5351_PLLB);
|
||||
clockgen.set_freq(400000000ULL, SI5351_CLK0);
|
||||
clockgen.set_freq(100000000ULL, SI5351_CLK1);
|
||||
clockgen.set_freq(307200000ULL, SI5351_CLK2);
|
||||
old_cal = cal_factor;
|
||||
delay(500);
|
||||
}
|
||||
else {
|
||||
clockgen.update_status();
|
||||
while (clockgen.dev_status.SYS_INIT == 1) {
|
||||
}
|
||||
|
||||
if (FreqCount.available()) {
|
||||
float count = FreqCount.read();
|
||||
display_Clear();
|
||||
println_Msg(F("Clock Calibration"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("Freq: "));
|
||||
print_Msg(count);
|
||||
println_Msg(F("Hz"));
|
||||
print_Msg(F("Correction:"));
|
||||
print_right(cal_factor);
|
||||
print_Msg(F("Adjustment:"));
|
||||
print_right(cal_offset);
|
||||
#ifdef enable_Button2
|
||||
println_Msg(F("(Hold button to save)"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Decrease Increase"));
|
||||
#else
|
||||
#ifdef enable_rotary
|
||||
println_Msg(F("Rotate to adjust"));
|
||||
#else
|
||||
println_Msg(F("Click/dbl to adjust"));
|
||||
#endif
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
#ifdef enable_Button2
|
||||
// get input button
|
||||
int a = checkButton1();
|
||||
int b = checkButton2();
|
||||
|
||||
// if the cart readers input button is pressed shortly
|
||||
if (a == 1) {
|
||||
old_cal = cal_factor;
|
||||
cal_factor -= cal_offset;
|
||||
}
|
||||
if (b == 1) {
|
||||
old_cal = cal_factor;
|
||||
cal_factor += cal_offset;
|
||||
}
|
||||
|
||||
// if the cart readers input buttons is double clicked
|
||||
if (a == 2) {
|
||||
cal_offset /= 10ULL;
|
||||
if (cal_offset < 1)
|
||||
{
|
||||
cal_offset = 100000000ULL;
|
||||
}
|
||||
}
|
||||
if (b == 2) {
|
||||
cal_offset *= 10ULL;
|
||||
if (cal_offset > 100000000ULL)
|
||||
{
|
||||
cal_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if the cart readers input button is pressed long
|
||||
if (a == 3) {
|
||||
savetofile();
|
||||
}
|
||||
if (b == 3) {
|
||||
savetofile();
|
||||
}
|
||||
#else
|
||||
//Handle inputs for either rotary encoder or single button interface.
|
||||
int a = checkButton();
|
||||
|
||||
if (a == 1) { //clockwise rotation or single click
|
||||
old_cal = cal_factor;
|
||||
cal_factor += cal_offset;
|
||||
}
|
||||
|
||||
if (a == 2) { //counterclockwise rotation or double click
|
||||
old_cal = cal_factor;
|
||||
cal_factor -= cal_offset;
|
||||
}
|
||||
|
||||
if (a == 3) { //button short hold
|
||||
cal_offset *= 10ULL;
|
||||
if (cal_offset > 100000000ULL)
|
||||
{
|
||||
cal_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (a == 4) { //button long hold
|
||||
savetofile();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_right(int32_t number)
|
||||
{
|
||||
int32_t abs_number = number;
|
||||
if (abs_number < 0)
|
||||
abs_number *= -1;
|
||||
else
|
||||
print_Msg(F(" "));
|
||||
|
||||
if (abs_number == 0)
|
||||
abs_number = 1;
|
||||
while (abs_number < 100000000ULL)
|
||||
{
|
||||
print_Msg(F(" "));
|
||||
abs_number *= 10ULL;
|
||||
}
|
||||
println_Msg(number);
|
||||
}
|
||||
|
||||
void savetofile() {
|
||||
display_Clear();
|
||||
println_Msg(F("Saving..."));
|
||||
println_Msg(cal_factor);
|
||||
display_Update();
|
||||
delay(2000);
|
||||
|
||||
if (!myFile.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
// Write calibration factor to file
|
||||
myFile.print(cal_factor);
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F("Done"));
|
||||
display_Update();
|
||||
delay(1000);
|
||||
resetArduino();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef clockgen_calibration
|
||||
int32_t readClockOffset() {
|
||||
FsFile clock_file;
|
||||
char* clock_buf;
|
||||
int16_t i;
|
||||
int32_t clock_offset;
|
||||
|
||||
if (!clock_file.open("/snes_clk.txt", O_READ)) {
|
||||
return INT32_MIN;
|
||||
}
|
||||
|
||||
clock_buf = (char*)malloc(12 * sizeof(char));
|
||||
i = clock_file.read(clock_buf, 11);
|
||||
clock_file.close();
|
||||
if (i == -1) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else if ((i == 11) && (clock_buf[0] != '-')) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
clock_buf[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (clock_buf[i] != '-' && clock_buf[i] < '0' && clock_buf[i] > '9') {
|
||||
if (i == 0) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else if ((i == 1) && (clock_buf[0] == '-')) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
clock_buf[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clock_offset = atoi32_signed(clock_buf);
|
||||
free(clock_buf);
|
||||
|
||||
return clock_offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t initializeClockOffset() {
|
||||
#ifdef clockgen_calibration
|
||||
FsFile clock_file;
|
||||
const char zero_char_arr[] = {'0'};
|
||||
int32_t clock_offset = readClockOffset();
|
||||
if (clock_offset > INT32_MIN) {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, clock_offset);
|
||||
} else {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
if (clock_file.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) {
|
||||
clock_file.write(zero_char_arr, 1);
|
||||
clock_file.close();
|
||||
}
|
||||
}
|
||||
return clock_offset;
|
||||
#else
|
||||
// last number is the clock correction factor which is custom for each clock generator
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Setup
|
||||
*****************************************/
|
||||
|
@ -2,8 +2,6 @@
|
||||
// FLASHROM MODULE
|
||||
// (also includes SNES repro functions)
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_FLASH
|
||||
|
||||
/******************************************
|
||||
|
@ -1,8 +1,6 @@
|
||||
//******************************************
|
||||
// GAME BOY MODULE
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_GBX
|
||||
|
||||
/******************************************
|
||||
@ -949,7 +947,7 @@ void compare_checksums_GB() {
|
||||
println_Msg(calcsumStr);
|
||||
print_Error(F("Checksum Error"), false);
|
||||
}
|
||||
compareCRC("gb.txt", 0);
|
||||
compareCRC("gb.txt", 0, 0);
|
||||
display_Update();
|
||||
//go to root
|
||||
sd.chdir();
|
||||
|
@ -1,8 +1,6 @@
|
||||
//******************************************
|
||||
// GAME BOY ADVANCE MODULE
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_GBX
|
||||
|
||||
/******************************************
|
||||
@ -130,7 +128,7 @@ void gbaMenu() {
|
||||
// Internal Checksum
|
||||
compare_checksum_GBA();
|
||||
// CRC32
|
||||
compareCRC("gba.txt", 0);
|
||||
compareCRC("gba.txt", 0, 0);
|
||||
#ifdef global_log
|
||||
save_log();
|
||||
#endif
|
||||
|
@ -1,8 +1,6 @@
|
||||
//******************************************
|
||||
// GB MEMORY MODULE
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_GBX
|
||||
|
||||
/******************************************
|
||||
|
@ -2,10 +2,7 @@
|
||||
// GB SMART MODULE
|
||||
// Supports 32M cart with LH28F016SUT flash
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_GBX
|
||||
|
||||
#define GB_SMART_GAMES_PER_PAGE 6
|
||||
|
||||
/******************************************
|
||||
|
@ -2,8 +2,6 @@
|
||||
// SEGA MEGA DRIVE MODULE
|
||||
//******************************************
|
||||
// Writes to Sega CD Backup RAM Cart require an extra wire from MRES (B02) to VRES (B27)
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_MD
|
||||
|
||||
/******************************************
|
||||
@ -1310,7 +1308,7 @@ void readROM_MD() {
|
||||
}
|
||||
|
||||
// Calculate and compare CRC32 with no-intro
|
||||
compareCRC("md.txt", 0);
|
||||
compareCRC("md.txt", 0, 0);
|
||||
|
||||
// More checksums
|
||||
if (SnKmode >= 2) {
|
||||
|
@ -1,15 +1,7 @@
|
||||
//******************************************
|
||||
// NINTENDO 64 MODULE
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_N64
|
||||
#include "snes_clk.h"
|
||||
|
||||
// Include Cart_Reader.ino to allow for calling istablished functions
|
||||
#ifdef RTC_installed
|
||||
#include "RTC.h"
|
||||
#endif
|
||||
|
||||
/******************************************
|
||||
Defines
|
||||
@ -3445,7 +3437,7 @@ redumpsamefolder:
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
|
||||
if (compareCRC("n64.txt", 0)) {
|
||||
if (compareCRC("n64.txt", 0, 0)) {
|
||||
#else
|
||||
// dumping rom fast
|
||||
byte buffer[1024] = { 0 };
|
||||
@ -3538,7 +3530,7 @@ redumpsamefolder:
|
||||
sprintf(crcStr, "%08lX", ~oldcrc32);
|
||||
|
||||
// Search n64.txt for crc
|
||||
if (compareCRC("n64.txt", crcStr)) {
|
||||
if (compareCRC("n64.txt", crcStr, 0)) {
|
||||
#endif
|
||||
unsigned long timeElapsed = (millis() - startTime) / 1000; // seconds
|
||||
print_Msg(F("Done ("));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,6 @@
|
||||
//******************************************
|
||||
// NGP MODULE
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_NGP
|
||||
|
||||
static const char ngpMenuItem1[] PROGMEM = "Read Rom";
|
||||
|
@ -1,10 +1,7 @@
|
||||
//******************************************
|
||||
// NINTENDO POWER SF MEMORY MODULE
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_NP
|
||||
#include "snes_clk.h"
|
||||
|
||||
/******************************************
|
||||
SF Memory Clock Source
|
||||
|
@ -10,8 +10,6 @@
|
||||
// Chris Covell - Tennokoe bank support
|
||||
//
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_PCE
|
||||
|
||||
/******************************************
|
||||
|
@ -1,56 +0,0 @@
|
||||
#include "options.h"
|
||||
#ifdef RTC_installed
|
||||
|
||||
#include "RTC.h"
|
||||
#include "SdFat.h"
|
||||
|
||||
RTC_DS3231 rtc;
|
||||
|
||||
// Start Time
|
||||
void RTCStart() {
|
||||
// Start RTC
|
||||
if (! rtc.begin()) {
|
||||
abort();
|
||||
}
|
||||
|
||||
// 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__)));
|
||||
}
|
||||
}
|
||||
|
||||
// Set Date/Time Callback Funtion
|
||||
// Callback for file timestamps
|
||||
void dateTime(uint16_t* date, uint16_t* time) {
|
||||
DateTime now = rtc.now();
|
||||
|
||||
// Return date using FAT_DATE macro to format fields
|
||||
*date = FAT_DATE(now.year(), now.month(), now.day());
|
||||
|
||||
// Return time using FAT_TIME macro to format fields
|
||||
*time = FAT_TIME(now.hour(), now.minute(), now.second());
|
||||
}
|
||||
|
||||
|
||||
/******************************************
|
||||
RTC Time Stamp Setup
|
||||
Call in any other script
|
||||
*****************************************/
|
||||
// Format a Date/Time stamp
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,17 +0,0 @@
|
||||
#include "options.h"
|
||||
#ifdef RTC_installed
|
||||
|
||||
// RTC Library
|
||||
#ifndef _RTC_H
|
||||
#define _RTC_H
|
||||
|
||||
#include "RTClib.h"
|
||||
|
||||
void RTCStart();
|
||||
|
||||
void dateTime(uint16_t* date, uint16_t* time);
|
||||
|
||||
String RTCStamp();
|
||||
|
||||
#endif
|
||||
#endif
|
@ -1,8 +1,6 @@
|
||||
//********************************************************
|
||||
// SEGA MASTER SYSTEM/Mark III/SG-1000/GAME GEAR MODULE
|
||||
//********************************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_MD
|
||||
|
||||
/******************************************
|
||||
@ -68,7 +66,7 @@ void _smsMenu() {
|
||||
// Change working dir to root
|
||||
sd.chdir("/");
|
||||
readROM_SMS();
|
||||
compareCRC("sms.txt", 0);
|
||||
compareCRC("sms.txt", 0, 0);
|
||||
#ifdef global_log
|
||||
save_log();
|
||||
#endif
|
||||
|
@ -1,10 +1,7 @@
|
||||
//******************************************
|
||||
// SUPER NINTENDO MODULE
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_SNES
|
||||
#include "snes_clk.h"
|
||||
|
||||
/******************************************
|
||||
Defines
|
||||
@ -147,7 +144,6 @@ void snsMenu() {
|
||||
snsCart = question_box(F("Select Cart Type"), menuOptions, 5, 0);
|
||||
#endif
|
||||
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (snsCart)
|
||||
{
|
||||
@ -218,7 +214,7 @@ void snesMenu() {
|
||||
// Internal Checksum
|
||||
compare_checksum();
|
||||
// CRC32
|
||||
compareCRC("snes.txt", 0);
|
||||
compareCRC("snes.txt", 0, 0);
|
||||
#ifdef global_log
|
||||
save_log();
|
||||
#endif
|
||||
|
@ -3,8 +3,6 @@
|
||||
// Revision 1.0.0 October 22nd 2018
|
||||
// Added BSX Sram, copied from skamans enhanced sketch //sanni
|
||||
//******************************************
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_SV
|
||||
|
||||
/******************************************
|
||||
|
@ -22,7 +22,6 @@
|
||||
// C46 : INT (for RTC alarm interrupt)
|
||||
// C47 : CLK (384KHz on WS)
|
||||
|
||||
#include "options.h"
|
||||
#ifdef enable_WS
|
||||
|
||||
#ifdef ws_adapter_v2
|
||||
|
@ -1,55 +0,0 @@
|
||||
#include "atoi32.h"
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int32_t atoi32_signed(const char* input_string) {
|
||||
if (input_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int int_sign = 1;
|
||||
int i = 0;
|
||||
|
||||
if (input_string[0] == '-') {
|
||||
int_sign = -1;
|
||||
i = 1;
|
||||
}
|
||||
|
||||
int32_t return_val = 0;
|
||||
|
||||
while (input_string[i] != '\0') {
|
||||
if (input_string[i] >= '0' && input_string[i] <= '9') {
|
||||
return_val = (return_val * 10) + (input_string[i] - '0');
|
||||
} else if (input_string[i] != '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return_val = return_val * int_sign;
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
uint32_t atoi32_unsigned(const char* input_string) {
|
||||
if (input_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
uint32_t return_val = 0;
|
||||
|
||||
while (input_string[i] != '\0') {
|
||||
if (input_string[i] >= '0' && input_string[i] <= '9') {
|
||||
return_val = (return_val * 10) + (input_string[i] - '0');
|
||||
} else if (input_string[i] != '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
#ifndef _ATOI32_H
|
||||
#define _ATOI32_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int32_t atoi32_signed(const char* input_string);
|
||||
uint32_t atoi32_unsigned(const char* input_string);
|
||||
|
||||
#endif
|
@ -1,221 +0,0 @@
|
||||
//******************************************
|
||||
// Clock Calibration Module
|
||||
//******************************************
|
||||
|
||||
#ifdef clockgen_calibration
|
||||
#include <FreqCount.h>
|
||||
#include "snes_clk.h"
|
||||
#include "SdFat.h"
|
||||
|
||||
/******************************************
|
||||
Variables
|
||||
*****************************************/
|
||||
int32_t cal_factor = 0;
|
||||
int32_t old_cal = 0;
|
||||
int32_t cal_offset = 100;
|
||||
|
||||
|
||||
/******************************************
|
||||
Clock Calibration
|
||||
*****************************************/
|
||||
void clkcal() {
|
||||
// Adafruit Clock Generator
|
||||
// last number is the clock correction factor which is custom for each clock generator
|
||||
cal_factor = readClockOffset();
|
||||
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
display.print("Read correction: ");
|
||||
display.println(cal_factor);
|
||||
display.display();
|
||||
delay(500);
|
||||
|
||||
if (cal_factor > INT32_MIN) {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, cal_factor);
|
||||
} else {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
cal_factor = 0;
|
||||
}
|
||||
|
||||
if (!i2c_found) {
|
||||
display_Clear();
|
||||
print_Error(F("Clock Generator not found"), true);
|
||||
}
|
||||
|
||||
//clockgen.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
||||
//clockgen.pll_reset(SI5351_PLLA);
|
||||
//clockgen.pll_reset(SI5351_PLLB);
|
||||
clockgen.set_freq(400000000ULL, SI5351_CLK0);
|
||||
clockgen.set_freq(100000000ULL, SI5351_CLK1);
|
||||
clockgen.set_freq(307200000ULL, SI5351_CLK2);
|
||||
clockgen.output_enable(SI5351_CLK1, 1);
|
||||
clockgen.output_enable(SI5351_CLK2, 1);
|
||||
clockgen.output_enable(SI5351_CLK0, 1);
|
||||
|
||||
// Frequency Counter
|
||||
delay(500);
|
||||
FreqCount.begin(1000);
|
||||
while (1)
|
||||
{
|
||||
if (old_cal != cal_factor) {
|
||||
display_Clear();
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(" Adjusting"));
|
||||
display_Update();
|
||||
clockgen.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
||||
clockgen.pll_reset(SI5351_PLLA);
|
||||
clockgen.pll_reset(SI5351_PLLB);
|
||||
clockgen.set_freq(400000000ULL, SI5351_CLK0);
|
||||
clockgen.set_freq(100000000ULL, SI5351_CLK1);
|
||||
clockgen.set_freq(307200000ULL, SI5351_CLK2);
|
||||
old_cal = cal_factor;
|
||||
delay(500);
|
||||
}
|
||||
else {
|
||||
clockgen.update_status();
|
||||
while (clockgen.dev_status.SYS_INIT == 1) {
|
||||
}
|
||||
|
||||
if (FreqCount.available()) {
|
||||
float count = FreqCount.read();
|
||||
display_Clear();
|
||||
println_Msg(F("Clock Calibration"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("Freq: "));
|
||||
print_Msg(count);
|
||||
println_Msg(F("Hz"));
|
||||
print_Msg(F("Correction:"));
|
||||
print_right(cal_factor);
|
||||
print_Msg(F("Adjustment:"));
|
||||
print_right(cal_offset);
|
||||
#ifdef enable_Button2
|
||||
println_Msg(F("(Hold button to save)"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Decrease Increase"));
|
||||
#else
|
||||
#ifdef enable_rotary
|
||||
println_Msg(F("Rotate to adjust"));
|
||||
#else
|
||||
println_Msg(F("Click/dbl to adjust"));
|
||||
#endif
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
#ifdef enable_Button2
|
||||
// get input button
|
||||
int a = checkButton1();
|
||||
int b = checkButton2();
|
||||
|
||||
// if the cart readers input button is pressed shortly
|
||||
if (a == 1) {
|
||||
old_cal = cal_factor;
|
||||
cal_factor -= cal_offset;
|
||||
}
|
||||
if (b == 1) {
|
||||
old_cal = cal_factor;
|
||||
cal_factor += cal_offset;
|
||||
}
|
||||
|
||||
// if the cart readers input buttons is double clicked
|
||||
if (a == 2) {
|
||||
cal_offset /= 10ULL;
|
||||
if (cal_offset < 1)
|
||||
{
|
||||
cal_offset = 100000000ULL;
|
||||
}
|
||||
}
|
||||
if (b == 2) {
|
||||
cal_offset *= 10ULL;
|
||||
if (cal_offset > 100000000ULL)
|
||||
{
|
||||
cal_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if the cart readers input button is pressed long
|
||||
if (a == 3) {
|
||||
savetofile();
|
||||
}
|
||||
if (b == 3) {
|
||||
savetofile();
|
||||
}
|
||||
#else
|
||||
//Handle inputs for either rotary encoder or single button interface.
|
||||
int a = checkButton();
|
||||
|
||||
if (a == 1) { //clockwise rotation or single click
|
||||
old_cal = cal_factor;
|
||||
cal_factor += cal_offset;
|
||||
}
|
||||
|
||||
if (a == 2) { //counterclockwise rotation or double click
|
||||
old_cal = cal_factor;
|
||||
cal_factor -= cal_offset;
|
||||
}
|
||||
|
||||
if (a == 3) { //button short hold
|
||||
cal_offset *= 10ULL;
|
||||
if (cal_offset > 100000000ULL)
|
||||
{
|
||||
cal_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (a == 4) { //button long hold
|
||||
savetofile();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_right(int32_t number)
|
||||
{
|
||||
int32_t abs_number = number;
|
||||
if (abs_number < 0)
|
||||
abs_number *= -1;
|
||||
else
|
||||
print_Msg(F(" "));
|
||||
|
||||
if (abs_number == 0)
|
||||
abs_number = 1;
|
||||
while (abs_number < 100000000ULL)
|
||||
{
|
||||
print_Msg(F(" "));
|
||||
abs_number *= 10ULL;
|
||||
}
|
||||
println_Msg(number);
|
||||
}
|
||||
|
||||
void savetofile() {
|
||||
display_Clear();
|
||||
println_Msg(F("Saving..."));
|
||||
println_Msg(cal_factor);
|
||||
display_Update();
|
||||
delay(2000);
|
||||
|
||||
if (!myFile.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
// Write calibration factor to file
|
||||
myFile.print(cal_factor);
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F("Done"));
|
||||
display_Update();
|
||||
delay(1000);
|
||||
resetArduino();
|
||||
}
|
||||
|
||||
#endif
|
||||
//******************************************
|
||||
// End of File
|
||||
//******************************************
|
@ -1,112 +0,0 @@
|
||||
//******************************************
|
||||
// !!! CHOOSE HARDWARE VERSION !!!
|
||||
//******************************************
|
||||
// Remove // in front of the line with your hardware version
|
||||
// #define HW5
|
||||
// #define HW4
|
||||
// #define HW3
|
||||
// #define HW2
|
||||
// #define HW1
|
||||
// #define SERIAL_MONITOR
|
||||
|
||||
#if !(defined(HW1) || defined(HW2) || defined(HW3) || defined(HW4) || defined(HW5) || defined(SERIAL_MONITOR))
|
||||
# error !!! PLEASE CHOOSE HARDWARE VERSION IN OPTIONS.H !!!
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// Advanced Options
|
||||
//******************************************
|
||||
|
||||
//******************************************
|
||||
// Hardware Configurations
|
||||
//******************************************
|
||||
#if (defined(HW4) || defined(HW5))
|
||||
#define enable_LCD
|
||||
#define enable_neopixel
|
||||
#define background_color 100,0,0 //Green, Red, Blue
|
||||
#define enable_rotary
|
||||
// #define rotate_counter_clockwise
|
||||
#define clockgen_installed
|
||||
#define fastcrc
|
||||
#define ws_adapter_v2
|
||||
#endif
|
||||
|
||||
#if (defined(HW2) || defined(HW3))
|
||||
#define enable_OLED
|
||||
#define enable_Button2
|
||||
// #define clockgen_installed
|
||||
// #define fastcrc
|
||||
#endif
|
||||
|
||||
#if defined(HW1)
|
||||
#define enable_OLED
|
||||
#endif
|
||||
|
||||
#if defined(SERIAL_MONITOR)
|
||||
#define enable_serial
|
||||
#define clockgen_installed
|
||||
#define fastcrc
|
||||
#endif
|
||||
|
||||
//******************************************
|
||||
// GLOBAL OPTIONS
|
||||
//******************************************
|
||||
// Change mainMenu to snsMenu, mdMenu, n64Menu, gbxMenu, pcsMenu,
|
||||
// flashMenu, nesMenu or smsMenu for single slot Cart Readers
|
||||
#define startMenu mainMenu
|
||||
|
||||
// Ignores errors that normally force a reset if button 2 is pressed
|
||||
// #define debug_mode
|
||||
|
||||
// Setup RTC if installed.
|
||||
// remove // if you have an RTC installed
|
||||
// #define RTC_installed
|
||||
|
||||
// Use calibration data from snes_clk.txt
|
||||
// #define clockgen_calibration
|
||||
|
||||
// Write all info to OSCR_LOG.txt in root dir
|
||||
#define global_log
|
||||
|
||||
// Use Adafruit Clock Generator
|
||||
// #define clockgen_installed
|
||||
|
||||
//******************************************
|
||||
// GB, SMS, MD, N64 database lookup
|
||||
//******************************************
|
||||
// Renames ROM if found in database
|
||||
#define no-intro
|
||||
|
||||
//******************************************
|
||||
// MD OPTIONS
|
||||
//******************************************
|
||||
// I don't know
|
||||
//#define use_md_conf
|
||||
|
||||
//******************************************
|
||||
// N64 OPTIONS
|
||||
//******************************************
|
||||
// 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
|
||||
|
||||
//******************************************
|
||||
// DISABLE MODULES
|
||||
//******************************************
|
||||
// add // before #define to disable a module
|
||||
#define enable_SNES
|
||||
#define enable_NP
|
||||
#define enable_SV
|
||||
|
||||
#define enable_MD
|
||||
#define enable_SMS
|
||||
|
||||
#define enable_N64
|
||||
#define enable_GBX
|
||||
#define enable_NES
|
||||
#define enable_FLASH
|
||||
#define enable_PCE
|
||||
#define enable_WS
|
||||
#define enable_NGP
|
@ -1,70 +0,0 @@
|
||||
#include "snes_clk.h"
|
||||
#include <si5351.h>
|
||||
#include "SdFat.h"
|
||||
#include "atoi32.h"
|
||||
#include "options.h"
|
||||
|
||||
int32_t readClockOffset() {
|
||||
FsFile clock_file;
|
||||
char* clock_buf;
|
||||
int16_t i;
|
||||
int32_t clock_offset;
|
||||
|
||||
if (!clock_file.open("/snes_clk.txt", O_READ)) {
|
||||
return INT32_MIN;
|
||||
}
|
||||
|
||||
clock_buf = (char*)malloc(12 * sizeof(char));
|
||||
i = clock_file.read(clock_buf, 11);
|
||||
clock_file.close();
|
||||
if (i == -1) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else if ((i == 11) && (clock_buf[0] != '-')) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
clock_buf[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (clock_buf[i] != '-' && clock_buf[i] < '0' && clock_buf[i] > '9') {
|
||||
if (i == 0) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else if ((i == 1) && (clock_buf[0] == '-')) {
|
||||
free(clock_buf);
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
clock_buf[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clock_offset = atoi32_signed(clock_buf);
|
||||
free(clock_buf);
|
||||
|
||||
return clock_offset;
|
||||
}
|
||||
|
||||
int32_t initializeClockOffset() {
|
||||
#ifdef clockgen_calibration
|
||||
FsFile clock_file;
|
||||
const char zero_char_arr[] = {'0'};
|
||||
int32_t clock_offset = readClockOffset();
|
||||
if (clock_offset > INT32_MIN) {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, clock_offset);
|
||||
} else {
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
if (clock_file.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) {
|
||||
clock_file.write(zero_char_arr, 1);
|
||||
clock_file.close();
|
||||
}
|
||||
}
|
||||
return clock_offset;
|
||||
#else
|
||||
// last number is the clock correction factor which is custom for each clock generator
|
||||
i2c_found = clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#ifndef _SNES_CLK_H
|
||||
#define _SNES_CLK_H
|
||||
|
||||
#include <si5351.h>
|
||||
#include "SdFat.h"
|
||||
#include "atoi32.h"
|
||||
#include "options.h"
|
||||
|
||||
extern Si5351 clockgen;
|
||||
extern bool i2c_found;
|
||||
|
||||
int32_t readClockOffset();
|
||||
int32_t initializeClockOffset();
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user