mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-25 04:21:53 +01:00
V8.5 BETA: Add global log and GB database
Both are disabled in options.h by default since they push the RAM usage over the limit resulting in corrupted LCD output. Global log outputs all info to OSCR_LOG.txt in the root of the SD. no-intro calculates the CRC32 of a Gameboy ROM and if found in the database renames it to no-intro naming scheme.
This commit is contained in:
parent
a237f64470
commit
1c6d277e84
@ -4,8 +4,8 @@
|
|||||||
This project represents a community-driven effort to provide
|
This project represents a community-driven effort to provide
|
||||||
an easy to build and easy to modify cartridge dumper.
|
an easy to build and easy to modify cartridge dumper.
|
||||||
|
|
||||||
Date: 09.06.2022
|
Date: 11.06.2022
|
||||||
Version: 8.4
|
Version: 8.5 BETA
|
||||||
|
|
||||||
SD lib: https://github.com/greiman/SdFat
|
SD lib: https://github.com/greiman/SdFat
|
||||||
OLED lib: https://github.com/adafruit/Adafruit_SSD1306
|
OLED lib: https://github.com/adafruit/Adafruit_SSD1306
|
||||||
@ -19,7 +19,7 @@
|
|||||||
RTC lib: https://github.com/adafruit/RTClib
|
RTC lib: https://github.com/adafruit/RTClib
|
||||||
Frequency lib: https://github.com/PaulStoffregen/FreqCount
|
Frequency lib: https://github.com/PaulStoffregen/FreqCount
|
||||||
|
|
||||||
Compiled with Arduino 1.8.16
|
Compiled with Arduino 1.8.19
|
||||||
|
|
||||||
Thanks to:
|
Thanks to:
|
||||||
MichlK - ROM Reader for Super Nintendo
|
MichlK - ROM Reader for Super Nintendo
|
||||||
@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
char ver[5] = "8.4";
|
char ver[5] = "8.5B";
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
Libraries
|
Libraries
|
||||||
@ -77,6 +77,9 @@ char ver[5] = "8.4";
|
|||||||
SdFs sd;
|
SdFs sd;
|
||||||
FsFile myDir;
|
FsFile myDir;
|
||||||
FsFile myFile;
|
FsFile myFile;
|
||||||
|
#ifdef global_log
|
||||||
|
FsFile myLog;
|
||||||
|
#endif
|
||||||
|
|
||||||
// AVR Eeprom
|
// AVR Eeprom
|
||||||
#include <EEPROM.h>
|
#include <EEPROM.h>
|
||||||
@ -785,6 +788,12 @@ void setup() {
|
|||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef global_log
|
||||||
|
if (!myLog.open("OSCR_LOG.txt", O_RDWR | O_CREAT | O_APPEND)) {
|
||||||
|
print_Error(F("SD Error"), true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RTC_installed
|
#ifdef RTC_installed
|
||||||
// Start RTC
|
// Start RTC
|
||||||
RTCStart();
|
RTCStart();
|
||||||
@ -892,6 +901,9 @@ void print_Msg(const __FlashStringHelper *string) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.print(string);
|
Serial.print(string);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.print(string);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_Msg(const char myString[]) {
|
void print_Msg(const char myString[]) {
|
||||||
@ -906,8 +918,8 @@ void print_Msg(const char myString[]) {
|
|||||||
}
|
}
|
||||||
// Newline
|
// Newline
|
||||||
display.setCursor(0, display.ty + 8);
|
display.setCursor(0, display.ty + 8);
|
||||||
// Print remaining characters
|
// Print until end of display and ignore remaining characters
|
||||||
while (strPos < strlen(myString)) {
|
while ((strPos < strlen(myString)) && (display.tx < 122)) {
|
||||||
display.print(myString[strPos]);
|
display.print(myString[strPos]);
|
||||||
strPos++;
|
strPos++;
|
||||||
}
|
}
|
||||||
@ -922,6 +934,9 @@ void print_Msg(const char myString[]) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.print(myString);
|
Serial.print(myString);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.print(myString);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_Msg(long unsigned int message) {
|
void print_Msg(long unsigned int message) {
|
||||||
@ -934,6 +949,9 @@ void print_Msg(long unsigned int message) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.print(message);
|
Serial.print(message);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.print(message);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_Msg(byte message, int outputFormat) {
|
void print_Msg(byte message, int outputFormat) {
|
||||||
@ -946,6 +964,9 @@ void print_Msg(byte message, int outputFormat) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.print(message, outputFormat);
|
Serial.print(message, outputFormat);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.print(message, outputFormat);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_Msg(String string) {
|
void print_Msg(String string) {
|
||||||
@ -958,6 +979,9 @@ void print_Msg(String string) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.print(string);
|
Serial.print(string);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.print(string);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_Msg_PaddedHexByte(byte message) {
|
void print_Msg_PaddedHexByte(byte message) {
|
||||||
@ -976,10 +1000,9 @@ void print_Msg_PaddedHex32(unsigned long message) {
|
|||||||
print_Msg_PaddedHexByte((message >> 8) & 0xFF);
|
print_Msg_PaddedHexByte((message >> 8) & 0xFF);
|
||||||
print_Msg_PaddedHexByte((message >> 0) & 0xFF);
|
print_Msg_PaddedHexByte((message >> 0) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void println_Msg(String string) {
|
void println_Msg(String string) {
|
||||||
#ifdef enable_LCD
|
#ifdef enable_LCD
|
||||||
print_Msg(string);
|
display.print(string);
|
||||||
display.setCursor(0, display.ty + 8);
|
display.setCursor(0, display.ty + 8);
|
||||||
#endif
|
#endif
|
||||||
#ifdef enable_OLED
|
#ifdef enable_OLED
|
||||||
@ -988,11 +1011,14 @@ void println_Msg(String string) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.println(string);
|
Serial.println(string);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.println(string);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void println_Msg(byte message, int outputFormat) {
|
void println_Msg(byte message, int outputFormat) {
|
||||||
#ifdef enable_LCD
|
#ifdef enable_LCD
|
||||||
print_Msg(message, outputFormat);
|
display.print(message, outputFormat);
|
||||||
display.setCursor(0, display.ty + 8);
|
display.setCursor(0, display.ty + 8);
|
||||||
#endif
|
#endif
|
||||||
#ifdef enable_OLED
|
#ifdef enable_OLED
|
||||||
@ -1001,24 +1027,48 @@ void println_Msg(byte message, int outputFormat) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.println(message, outputFormat);
|
Serial.println(message, outputFormat);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.println(message, outputFormat);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void println_Msg(const char message[]) {
|
void println_Msg(const char myString[]) {
|
||||||
#ifdef enable_LCD
|
#ifdef enable_LCD
|
||||||
print_Msg(message);
|
// test for word wrap
|
||||||
|
if ((display.tx + strlen(myString) * 6) > 128) {
|
||||||
|
int strPos = 0;
|
||||||
|
// Print until end of display
|
||||||
|
while (display.tx < 122) {
|
||||||
|
display.print(myString[strPos]);
|
||||||
|
strPos++;
|
||||||
|
}
|
||||||
|
// Newline
|
||||||
|
display.setCursor(0, display.ty + 8);
|
||||||
|
// Print until end of display and ignore remaining characters
|
||||||
|
while ((strPos < strlen(myString)) && (display.tx < 122)) {
|
||||||
|
display.print(myString[strPos]);
|
||||||
|
strPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
display.print(myString);
|
||||||
|
}
|
||||||
display.setCursor(0, display.ty + 8);
|
display.setCursor(0, display.ty + 8);
|
||||||
#endif
|
#endif
|
||||||
#ifdef enable_OLED
|
#ifdef enable_OLED
|
||||||
display.println(message);
|
display.println(myString);
|
||||||
#endif
|
#endif
|
||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.println(message);
|
Serial.println(myString);
|
||||||
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.println(myString);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void println_Msg(const __FlashStringHelper *string) {
|
void println_Msg(const __FlashStringHelper *string) {
|
||||||
#ifdef enable_LCD
|
#ifdef enable_LCD
|
||||||
print_Msg(string);
|
display.print(string);
|
||||||
display.setCursor(0, display.ty + 8);
|
display.setCursor(0, display.ty + 8);
|
||||||
#endif
|
#endif
|
||||||
#ifdef enable_OLED
|
#ifdef enable_OLED
|
||||||
@ -1027,11 +1077,14 @@ void println_Msg(const __FlashStringHelper *string) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.println(string);
|
Serial.println(string);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.println(string);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void println_Msg(long unsigned int message) {
|
void println_Msg(long unsigned int message) {
|
||||||
#ifdef enable_LCD
|
#ifdef enable_LCD
|
||||||
print_Msg(message);
|
display.print(message);
|
||||||
display.setCursor(0, display.ty + 8);
|
display.setCursor(0, display.ty + 8);
|
||||||
#endif
|
#endif
|
||||||
#ifdef enable_OLED
|
#ifdef enable_OLED
|
||||||
@ -1040,6 +1093,9 @@ void println_Msg(long unsigned int message) {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
Serial.println(message);
|
Serial.println(message);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.println(message);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_Update() {
|
void display_Update() {
|
||||||
@ -1052,6 +1108,9 @@ void display_Update() {
|
|||||||
#ifdef enable_serial
|
#ifdef enable_serial
|
||||||
delay(100);
|
delay(100);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.flush();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_Clear() {
|
void display_Clear() {
|
||||||
@ -1063,6 +1122,9 @@ void display_Clear() {
|
|||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.setCursor(0, 0);
|
display.setCursor(0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef global_log
|
||||||
|
myLog.println("");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char question_box(const __FlashStringHelper* question, char answers[7][20], int num_answers, int default_choice) {
|
unsigned char question_box(const __FlashStringHelper* question, char answers[7][20], int num_answers, int default_choice) {
|
||||||
|
@ -299,7 +299,7 @@ void gbMenu() {
|
|||||||
// Change working dir to root
|
// Change working dir to root
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
readROM_GB();
|
readROM_GB();
|
||||||
compare_checksum_GB();
|
compare_checksums_GB();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@ -313,6 +313,7 @@ void gbMenu() {
|
|||||||
else {
|
else {
|
||||||
print_Error(F("Cart has no Sram"), false);
|
print_Error(F("Cart has no Sram"), false);
|
||||||
}
|
}
|
||||||
|
println_Msg(F(""));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
@ -340,13 +341,13 @@ void gbMenu() {
|
|||||||
else {
|
else {
|
||||||
print_Error(F("Cart has no Sram"), false);
|
print_Error(F("Cart has no Sram"), false);
|
||||||
}
|
}
|
||||||
|
println_Msg(F(""));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
resetArduino();
|
resetArduino();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
println_Msg(F(""));
|
|
||||||
println_Msg(F("Press Button..."));
|
println_Msg(F("Press Button..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
wait();
|
wait();
|
||||||
@ -372,8 +373,8 @@ void setup_GB() {
|
|||||||
|
|
||||||
// Set Data Pins (D0-D7) to Input
|
// Set Data Pins (D0-D7) to Input
|
||||||
DDRC = 0x00;
|
DDRC = 0x00;
|
||||||
// Disable Internal Pullups
|
// Enable Internal Pullups
|
||||||
//PORTC = 0x00;
|
PORTC = 0xFF;
|
||||||
|
|
||||||
delay(400);
|
delay(400);
|
||||||
|
|
||||||
@ -385,15 +386,12 @@ void setup_GB() {
|
|||||||
showCartInfo_GB();
|
showCartInfo_GB();
|
||||||
|
|
||||||
// MMM01 initialize
|
// MMM01 initialize
|
||||||
if (romType >= 11 && romType <= 13)
|
if (romType >= 11 && romType <= 13) {
|
||||||
{
|
|
||||||
dataOut();
|
|
||||||
writeByte_GB(0x3fff, 0x00);
|
writeByte_GB(0x3fff, 0x00);
|
||||||
writeByte_GB(0x5fff, 0x40);
|
writeByte_GB(0x5fff, 0x40);
|
||||||
writeByte_GB(0x7fff, 0x01);
|
writeByte_GB(0x7fff, 0x01);
|
||||||
writeByte_GB(0x1fff, 0x3a);
|
writeByte_GB(0x1fff, 0x3a);
|
||||||
writeByte_GB(0x1fff, 0x7a);
|
writeByte_GB(0x1fff, 0x7a);
|
||||||
dataIn_GB();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,17 +506,14 @@ void showCartInfo_GB() {
|
|||||||
/******************************************
|
/******************************************
|
||||||
Low level functions
|
Low level functions
|
||||||
*****************************************/
|
*****************************************/
|
||||||
// Switch data pins to read
|
|
||||||
void dataIn_GB() {
|
|
||||||
// Set to Input
|
|
||||||
DDRC = 0x00;
|
|
||||||
// Pullups
|
|
||||||
//PORTC = 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte readByte_GB(word myAddress) {
|
byte readByte_GB(word myAddress) {
|
||||||
|
// Set address
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 0xFF;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
// Switch data pins to input
|
||||||
|
DDRC = 0x00;
|
||||||
|
// Enable pullups
|
||||||
|
PORTC = 0xFF;
|
||||||
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
@ -539,11 +534,14 @@ byte readByte_GB(word myAddress) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeByte_GB(int myAddress, byte myData) {
|
void writeByte_GB(int myAddress, byte myData) {
|
||||||
|
// Set address
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 0xFF;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
// Set data
|
||||||
PORTC = myData;
|
PORTC = myData;
|
||||||
|
// Switch data pins to output
|
||||||
|
DDRC = 0xFF;
|
||||||
|
|
||||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
|
||||||
// Wait till output is stable
|
// Wait till output is stable
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
@ -558,12 +556,21 @@ void writeByte_GB(int myAddress, byte myData) {
|
|||||||
|
|
||||||
// Leave WR high for at least 50ns
|
// Leave WR high for at least 50ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
|
// Switch data pins to input
|
||||||
|
DDRC = 0x00;
|
||||||
|
// Enable pullups
|
||||||
|
PORTC = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triggers CS and CLK pin
|
// Triggers CS and CLK pin
|
||||||
byte readByteSRAM_GB(word myAddress) {
|
byte readByteSRAM_GB(word myAddress) {
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 0xFF;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
// Switch data pins to input
|
||||||
|
DDRC = 0x00;
|
||||||
|
// Enable pullups
|
||||||
|
PORTC = 0xFF;
|
||||||
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
@ -594,9 +601,13 @@ byte readByteSRAM_GB(word myAddress) {
|
|||||||
|
|
||||||
// Triggers CS and CLK pin
|
// Triggers CS and CLK pin
|
||||||
void writeByteSRAM_GB(int myAddress, byte myData) {
|
void writeByteSRAM_GB(int myAddress, byte myData) {
|
||||||
|
// Set address
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 0xFF;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
|
// Set data
|
||||||
PORTC = myData;
|
PORTC = myData;
|
||||||
|
// Switch data pins to output
|
||||||
|
DDRC = 0xFF;
|
||||||
|
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
@ -635,6 +646,11 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
|||||||
|
|
||||||
// Leave WR high for at least 50ns
|
// Leave WR high for at least 50ns
|
||||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||||
|
|
||||||
|
// Switch data pins to input
|
||||||
|
DDRC = 0x00;
|
||||||
|
// Enable pullups
|
||||||
|
PORTC = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
@ -642,9 +658,63 @@ void writeByteSRAM_GB(int myAddress, byte myData) {
|
|||||||
*****************************************/
|
*****************************************/
|
||||||
// Read Cartridge Header
|
// Read Cartridge Header
|
||||||
void getCartInfo_GB() {
|
void getCartInfo_GB() {
|
||||||
romType = readByte_GB(0x0147);
|
// Read Header into array
|
||||||
romSize = readByte_GB(0x0148);
|
for (int currByte = 0x100; currByte < 0x150; currByte++) {
|
||||||
sramSize = readByte_GB(0x0149);
|
sdBuffer[currByte] = readByte_GB(currByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare Nintendo logo against known checksum, 156 bytes starting at 0x04
|
||||||
|
word logoChecksum = 0;
|
||||||
|
for (int currByte = 0x104; currByte < 0x134; currByte++) {
|
||||||
|
logoChecksum += sdBuffer[currByte];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logoChecksum != 0x1546) {
|
||||||
|
print_Error(F("STARTUP LOGO ERROR"), false);
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F("Press Button to"));
|
||||||
|
println_Msg(F("ignore or powercycle"));
|
||||||
|
println_Msg(F("to try again"));
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Calculate header checksum
|
||||||
|
byte headerChecksum = 0;
|
||||||
|
for (int currByte = 0x134; currByte < 0x14D; currByte++) {
|
||||||
|
headerChecksum = headerChecksum - sdBuffer[currByte] - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerChecksum != sdBuffer[0x14D]) {
|
||||||
|
// Read Header into array a second time
|
||||||
|
for (int currByte = 0x100; currByte < 0x150; currByte++) {
|
||||||
|
sdBuffer[currByte] = readByte_GB(currByte);
|
||||||
|
}
|
||||||
|
// Calculate header checksum a second time
|
||||||
|
headerChecksum = 0;
|
||||||
|
for (int currByte = 0x134; currByte < 0x14D; currByte++) {
|
||||||
|
headerChecksum = headerChecksum - sdBuffer[currByte] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerChecksum != sdBuffer[0x14D]) {
|
||||||
|
print_Error(F("HEADER CHECKSUM ERROR"), false);
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F("Press Button to"));
|
||||||
|
println_Msg(F("ignore or clean"));
|
||||||
|
println_Msg(F("cart and try again"));
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
romType = sdBuffer[0x147];
|
||||||
|
romSize = sdBuffer[0x148];
|
||||||
|
sramSize = sdBuffer[0x149];
|
||||||
|
|
||||||
// ROM banks
|
// ROM banks
|
||||||
switch (romSize) {
|
switch (romSize) {
|
||||||
@ -710,18 +780,16 @@ void getCartInfo_GB() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get Checksum as string
|
// Get Checksum as string
|
||||||
eepbit[6] = readByte_GB(0x014E);
|
eepbit[6] = sdBuffer[0x14E];
|
||||||
eepbit[7] = readByte_GB(0x014F);
|
eepbit[7] = sdBuffer[0x14F];
|
||||||
sprintf(checksumStr, "%02X%02X", eepbit[6], eepbit[7]);
|
sprintf(checksumStr, "%02X%02X", eepbit[6], eepbit[7]);
|
||||||
|
|
||||||
// Get name
|
// Get name
|
||||||
byte myByte = 0;
|
|
||||||
byte myLength = 0;
|
byte myLength = 0;
|
||||||
|
|
||||||
for (int addr = 0x0134; addr <= 0x13C; addr++) {
|
for (int addr = 0x0134; addr <= 0x13C; addr++) {
|
||||||
myByte = readByte_GB(addr);
|
if (((char(sdBuffer[addr]) >= 48 && char(sdBuffer[addr]) <= 57) || (char(sdBuffer[addr]) >= 65 && char(sdBuffer[addr]) <= 122)) && myLength < 15) {
|
||||||
if (((char(myByte) >= 48 && char(myByte) <= 57) || (char(myByte) >= 65 && char(myByte) <= 122)) && myLength < 15) {
|
romName[myLength] = char(sdBuffer[addr]);
|
||||||
romName[myLength] = char(myByte);
|
|
||||||
myLength++;
|
myLength++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -765,9 +833,6 @@ void readROM_GB() {
|
|||||||
draw_progressbar(0, totalProgressBar);
|
draw_progressbar(0, totalProgressBar);
|
||||||
|
|
||||||
for (word currBank = 1; currBank < romBanks; currBank++) {
|
for (word currBank = 1; currBank < romBanks; currBank++) {
|
||||||
// Switch data pins to output
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Second bank starts at 0x4000
|
// Second bank starts at 0x4000
|
||||||
if (currBank > 1) {
|
if (currBank > 1) {
|
||||||
romAddress = 0x4000;
|
romAddress = 0x4000;
|
||||||
@ -808,9 +873,6 @@ void readROM_GB() {
|
|||||||
writeByte_GB(0x2000, currBank & 0x1F);
|
writeByte_GB(0x2000, currBank & 0x1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch data pins to intput
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Read banks and save to SD
|
// Read banks and save to SD
|
||||||
while (romAddress <= 0x7FFF) {
|
while (romAddress <= 0x7FFF) {
|
||||||
for (int i = 0; i < 512; i++) {
|
for (int i = 0; i < 512; i++) {
|
||||||
@ -834,9 +896,6 @@ unsigned int calc_checksum_GB (char* fileName, char* folder) {
|
|||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
if (strcmp(folder, "root") != 0)
|
|
||||||
sd.chdir(folder);
|
|
||||||
|
|
||||||
// If file exists
|
// If file exists
|
||||||
if (myFile.open(fileName, O_READ)) {
|
if (myFile.open(fileName, O_READ)) {
|
||||||
//calcFilesize = myFile.fileSize() * 8 / 1024 / 1024; // unused
|
//calcFilesize = myFile.fileSize() * 8 / 1024 / 1024; // unused
|
||||||
@ -847,7 +906,6 @@ unsigned int calc_checksum_GB (char* fileName, char* folder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
myFile.close();
|
myFile.close();
|
||||||
sd.chdir();
|
|
||||||
// Subtract checksum bytes
|
// Subtract checksum bytes
|
||||||
calcChecksum -= eepbit[6];
|
calcChecksum -= eepbit[6];
|
||||||
calcChecksum -= eepbit[7];
|
calcChecksum -= eepbit[7];
|
||||||
@ -863,8 +921,8 @@ unsigned int calc_checksum_GB (char* fileName, char* folder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compare checksum
|
// Compare checksum
|
||||||
boolean compare_checksum_GB() {
|
void compare_checksums_GB() {
|
||||||
println_Msg(F("Calculating Checksum"));
|
println_Msg(F("Calculating Checksum..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
strcpy(fileName, romName);
|
strcpy(fileName, romName);
|
||||||
@ -874,21 +932,105 @@ boolean compare_checksum_GB() {
|
|||||||
EEPROM_readAnything(0, foldern);
|
EEPROM_readAnything(0, foldern);
|
||||||
sprintf(folder, "GB/ROM/%s/%d", romName, foldern - 1);
|
sprintf(folder, "GB/ROM/%s/%d", romName, foldern - 1);
|
||||||
|
|
||||||
|
if (strcmp(folder, "root") != 0)
|
||||||
|
sd.chdir(folder);
|
||||||
|
|
||||||
|
// Internal ROM checksum
|
||||||
char calcsumStr[5];
|
char calcsumStr[5];
|
||||||
sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder));
|
sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder));
|
||||||
|
|
||||||
if (strcmp(calcsumStr, checksumStr) == 0) {
|
if (strcmp(calcsumStr, checksumStr) == 0) {
|
||||||
print_Msg(F("Result: "));
|
print_Msg(F("Internal: "));
|
||||||
println_Msg(calcsumStr);
|
print_Msg(calcsumStr);
|
||||||
println_Msg(F("Checksum matches"));
|
println_Msg(" -> OK");
|
||||||
display_Update();
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print_Msg(F("Result: "));
|
print_Msg(F("Internal: "));
|
||||||
println_Msg(calcsumStr);
|
println_Msg(calcsumStr);
|
||||||
print_Error(F("Checksum Error"), false);
|
print_Error(F("Checksum Error"), false);
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
#ifdef no-intro
|
||||||
|
//CRC32
|
||||||
|
char crcStr[9];
|
||||||
|
sprintf(crcStr, "%08lX", crcGB(fileName, folder));
|
||||||
|
// Print checksum
|
||||||
|
print_Msg("CRC32: ");
|
||||||
|
print_Msg(crcStr);
|
||||||
|
|
||||||
|
//Search for CRC32 in file
|
||||||
|
char gamename[50];
|
||||||
|
char crc_search[9];
|
||||||
|
|
||||||
|
//go to root
|
||||||
|
sd.chdir();
|
||||||
|
if (myFile.open("gb.txt", O_READ)) {
|
||||||
|
//Search for same CRC in list
|
||||||
|
while (myFile.available()) {
|
||||||
|
//Read 2 lines (game name and CRC)
|
||||||
|
get_line(gamename, &myFile, 46);
|
||||||
|
get_line(crc_search, &myFile, 9);
|
||||||
|
skip_line(&myFile); //Skip every 3rd line
|
||||||
|
|
||||||
|
//if checksum search successful, rename the file and end search
|
||||||
|
if (strcmp(crc_search, crcStr) == 0)
|
||||||
|
{
|
||||||
|
// Close the file:
|
||||||
|
myFile.close();
|
||||||
|
|
||||||
|
print_Msg(" -> ");
|
||||||
|
println_Msg(gamename);
|
||||||
|
|
||||||
|
// Rename file to no-intro
|
||||||
|
sd.chdir(folder);
|
||||||
|
if (myFile.open(fileName, O_READ)) {
|
||||||
|
myFile.rename(gamename);
|
||||||
|
// Close the file:
|
||||||
|
myFile.close();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strcmp(crc_search, crcStr) != 0)
|
||||||
|
{
|
||||||
|
println_Msg(" -> Not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println_Msg("gb.txt not found");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
println_Msg("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
display_Update();
|
||||||
|
//go to root
|
||||||
|
sd.chdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t updateCRC_GB(uint8_t ch, uint32_t crc) {
|
||||||
|
uint32_t idx = ((crc) ^ (ch)) & 0xff;
|
||||||
|
uint32_t tab_value = pgm_read_dword(crc_32_tab + idx);
|
||||||
|
return tab_value ^ ((crc) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate rom's CRC32 from SD
|
||||||
|
uint32_t crcGB(char* fileName, char* folder) {
|
||||||
|
if (myFile.open(fileName, O_READ)) {
|
||||||
|
uint32_t oldcrc32 = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
for (unsigned long currByte = 0; currByte < (myFile.fileSize() / 512); currByte++) {
|
||||||
|
myFile.read(sdBuffer, 512);
|
||||||
|
for (int c = 0; c < 512; c++) {
|
||||||
|
oldcrc32 = updateCRC_GB(sdBuffer[c], oldcrc32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Close the file:
|
||||||
|
myFile.close();
|
||||||
|
return ~oldcrc32;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_Error(F("File not found"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,12 +1061,9 @@ void readSRAM_GB() {
|
|||||||
print_Error(F("SD Error"), true);
|
print_Error(F("SD Error"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// MBC2 Fix
|
// MBC2 Fix
|
||||||
readByte_GB(0x0134);
|
readByte_GB(0x0134);
|
||||||
|
|
||||||
dataOut();
|
|
||||||
if (romType <= 4 || (romType >= 11 && romType <= 13)) {
|
if (romType <= 4 || (romType >= 11 && romType <= 13)) {
|
||||||
writeByte_GB(0x6000, 1);
|
writeByte_GB(0x6000, 1);
|
||||||
}
|
}
|
||||||
@ -934,11 +1073,9 @@ void readSRAM_GB() {
|
|||||||
|
|
||||||
// Switch SRAM banks
|
// Switch SRAM banks
|
||||||
for (byte currBank = 0; currBank < sramBanks; currBank++) {
|
for (byte currBank = 0; currBank < sramBanks; currBank++) {
|
||||||
dataOut();
|
|
||||||
writeByte_GB(0x4000, currBank);
|
writeByte_GB(0x4000, currBank);
|
||||||
|
|
||||||
// Read SRAM
|
// Read SRAM
|
||||||
dataIn_GB();
|
|
||||||
for (word sramAddress = 0xA000; sramAddress <= lastByte; sramAddress += 64) {
|
for (word sramAddress = 0xA000; sramAddress <= lastByte; sramAddress += 64) {
|
||||||
for (byte i = 0; i < 64; i++) {
|
for (byte i = 0; i < 64; i++) {
|
||||||
sdBuffer[i] = readByteSRAM_GB(sramAddress + i);
|
sdBuffer[i] = readByteSRAM_GB(sramAddress + i);
|
||||||
@ -948,9 +1085,7 @@ void readSRAM_GB() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disable SRAM
|
// Disable SRAM
|
||||||
dataOut();
|
|
||||||
writeByte_GB(0x0000, 0x00);
|
writeByte_GB(0x0000, 0x00);
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
@ -975,14 +1110,9 @@ void writeSRAM_GB() {
|
|||||||
|
|
||||||
//open file on sd card
|
//open file on sd card
|
||||||
if (myFile.open(filePath, O_READ)) {
|
if (myFile.open(filePath, O_READ)) {
|
||||||
// Set pins to input
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// MBC2 Fix
|
// MBC2 Fix
|
||||||
readByte_GB(0x0134);
|
readByte_GB(0x0134);
|
||||||
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Enable SRAM for MBC1
|
// Enable SRAM for MBC1
|
||||||
if (romType <= 4 || (romType >= 11 && romType <= 13)) {
|
if (romType <= 4 || (romType >= 11 && romType <= 13)) {
|
||||||
writeByte_GB(0x6000, 1);
|
writeByte_GB(0x6000, 1);
|
||||||
@ -1003,9 +1133,6 @@ void writeSRAM_GB() {
|
|||||||
// Disable SRAM
|
// Disable SRAM
|
||||||
writeByte_GB(0x0000, 0x00);
|
writeByte_GB(0x0000, 0x00);
|
||||||
|
|
||||||
// Set pins to input
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
display_Clear();
|
display_Clear();
|
||||||
@ -1031,14 +1158,11 @@ unsigned long verifySRAM_GB() {
|
|||||||
// Variable for errors
|
// Variable for errors
|
||||||
writeErrors = 0;
|
writeErrors = 0;
|
||||||
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// MBC2 Fix
|
// MBC2 Fix
|
||||||
readByte_GB(0x0134);
|
readByte_GB(0x0134);
|
||||||
|
|
||||||
// Check SRAM size
|
// Check SRAM size
|
||||||
if (lastByte > 0) {
|
if (lastByte > 0) {
|
||||||
dataOut();
|
|
||||||
if (romType <= 4) { // MBC1
|
if (romType <= 4) { // MBC1
|
||||||
writeByte_GB(0x6000, 1); // Set RAM Mode
|
writeByte_GB(0x6000, 1); // Set RAM Mode
|
||||||
}
|
}
|
||||||
@ -1048,11 +1172,9 @@ unsigned long verifySRAM_GB() {
|
|||||||
|
|
||||||
// Switch SRAM banks
|
// Switch SRAM banks
|
||||||
for (byte currBank = 0; currBank < sramBanks; currBank++) {
|
for (byte currBank = 0; currBank < sramBanks; currBank++) {
|
||||||
dataOut();
|
|
||||||
writeByte_GB(0x4000, currBank);
|
writeByte_GB(0x4000, currBank);
|
||||||
|
|
||||||
// Read SRAM
|
// Read SRAM
|
||||||
dataIn_GB();
|
|
||||||
for (word sramAddress = 0xA000; sramAddress <= lastByte; sramAddress += 64) {
|
for (word sramAddress = 0xA000; sramAddress <= lastByte; sramAddress += 64) {
|
||||||
//fill sdBuffer
|
//fill sdBuffer
|
||||||
myFile.read(sdBuffer, 64);
|
myFile.read(sdBuffer, 64);
|
||||||
@ -1063,10 +1185,8 @@ unsigned long verifySRAM_GB() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataOut();
|
|
||||||
// Disable RAM
|
// Disable RAM
|
||||||
writeByte_GB(0x0000, 0x00);
|
writeByte_GB(0x0000, 0x00);
|
||||||
dataIn_GB();
|
|
||||||
}
|
}
|
||||||
// Close the file:
|
// Close the file:
|
||||||
myFile.close();
|
myFile.close();
|
||||||
@ -1132,9 +1252,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
romBanks = 2;
|
romBanks = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data pins to output
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Set ROM bank hi 0
|
// Set ROM bank hi 0
|
||||||
writeByte_GB(0x3000, 0);
|
writeByte_GB(0x3000, 0);
|
||||||
// Set ROM bank low 0
|
// Set ROM bank low 0
|
||||||
@ -1150,8 +1267,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
writeByte_GB(0x2aa, 0x55);
|
writeByte_GB(0x2aa, 0x55);
|
||||||
writeByte_GB(0x555, 0x90);
|
writeByte_GB(0x555, 0x90);
|
||||||
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Read the two id bytes into a string
|
// Read the two id bytes into a string
|
||||||
sprintf(flashid, "%02X%02X", readByte_GB(0), readByte_GB(1));
|
sprintf(flashid, "%02X%02X", readByte_GB(0), readByte_GB(1));
|
||||||
|
|
||||||
@ -1196,7 +1311,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
display_Update();
|
display_Update();
|
||||||
print_Error(F("Unknown flashrom"), true);
|
print_Error(F("Unknown flashrom"), true);
|
||||||
}
|
}
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Reset flash
|
// Reset flash
|
||||||
writeByte_GB(0x555, 0xf0);
|
writeByte_GB(0x555, 0xf0);
|
||||||
@ -1215,8 +1329,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
writeByte_GB(0x2aa, 0x55);
|
writeByte_GB(0x2aa, 0x55);
|
||||||
writeByte_GB(0x555, 0x10);
|
writeByte_GB(0x555, 0x10);
|
||||||
|
|
||||||
// Set data pins to input
|
|
||||||
dataIn_GB();
|
|
||||||
// Read the status register
|
// Read the status register
|
||||||
byte statusReg = readByte_GB(0);
|
byte statusReg = readByte_GB(0);
|
||||||
// After a completed erase D7 will output 1
|
// After a completed erase D7 will output 1
|
||||||
@ -1234,11 +1346,8 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
// Blink led
|
// Blink led
|
||||||
blinkLED();
|
blinkLED();
|
||||||
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Set ROM bank
|
// Set ROM bank
|
||||||
writeByte_GB(0x2000, currBank);
|
writeByte_GB(0x2000, currBank);
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
for (unsigned int currAddr = 0x4000; currAddr < 0x7FFF; currAddr += 512) {
|
for (unsigned int currAddr = 0x4000; currAddr < 0x7FFF; currAddr += 512) {
|
||||||
for (int currByte = 0; currByte < 512; currByte++) {
|
for (int currByte = 0; currByte < 512; currByte++) {
|
||||||
@ -1259,8 +1368,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
// Write flash
|
// Write flash
|
||||||
dataOut();
|
|
||||||
|
|
||||||
word currAddr = 0;
|
word currAddr = 0;
|
||||||
word endAddr = 0x3FFF;
|
word endAddr = 0x3FFF;
|
||||||
|
|
||||||
@ -1292,9 +1399,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
// Write current byte
|
// Write current byte
|
||||||
writeByte_GB(currAddr + currByte, sdBuffer[currByte]);
|
writeByte_GB(currAddr + currByte, sdBuffer[currByte]);
|
||||||
|
|
||||||
// Set data pins to input
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Set OE/RD(PH6) LOW
|
// Set OE/RD(PH6) LOW
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
|
|
||||||
@ -1304,9 +1408,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
|
|
||||||
// Switch OE/RD(PH6) to HIGH
|
// Switch OE/RD(PH6) to HIGH
|
||||||
PORTH |= (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
|
|
||||||
// Set data pins to output
|
|
||||||
dataOut();
|
|
||||||
}
|
}
|
||||||
currAddr += 512;
|
currAddr += 512;
|
||||||
processedProgressBar += 512;
|
processedProgressBar += 512;
|
||||||
@ -1320,8 +1421,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
// Write flash
|
// Write flash
|
||||||
dataOut();
|
|
||||||
|
|
||||||
//Initialize progress bar
|
//Initialize progress bar
|
||||||
uint32_t processedProgressBar = 0;
|
uint32_t processedProgressBar = 0;
|
||||||
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
uint32_t totalProgressBar = (uint32_t)(romBanks) * 16384;
|
||||||
@ -1347,9 +1446,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
// Write current byte
|
// Write current byte
|
||||||
writeByte_GB(currAddr + currByte, sdBuffer[currByte]);
|
writeByte_GB(currAddr + currByte, sdBuffer[currByte]);
|
||||||
|
|
||||||
// Set data pins to input
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Set OE/RD(PH6) LOW
|
// Set OE/RD(PH6) LOW
|
||||||
PORTH &= ~(1 << 6);
|
PORTH &= ~(1 << 6);
|
||||||
|
|
||||||
@ -1359,9 +1455,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
|
|
||||||
// Switch OE/RD(PH6) to HIGH
|
// Switch OE/RD(PH6) to HIGH
|
||||||
PORTH |= (1 << 6);
|
PORTH |= (1 << 6);
|
||||||
|
|
||||||
// Set data pins to output
|
|
||||||
dataOut();
|
|
||||||
}
|
}
|
||||||
processedProgressBar += 512;
|
processedProgressBar += 512;
|
||||||
draw_progressbar(processedProgressBar, totalProgressBar);
|
draw_progressbar(processedProgressBar, totalProgressBar);
|
||||||
@ -1369,9 +1462,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data pins to input again
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
print_Msg(F("Verifying..."));
|
print_Msg(F("Verifying..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
@ -1385,9 +1475,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
|
|
||||||
// Read number of banks and switch banks
|
// Read number of banks and switch banks
|
||||||
for (word bank = 1; bank < romBanks; bank++) {
|
for (word bank = 1; bank < romBanks; bank++) {
|
||||||
// Switch data pins to output
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
if (romType >= 5) { // MBC2 and above
|
if (romType >= 5) { // MBC2 and above
|
||||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||||
}
|
}
|
||||||
@ -1397,9 +1484,6 @@ void writeFlash29F_GB(byte MBC, boolean flashErase) {
|
|||||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch data pins to intput
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
if (bank > 1) {
|
if (bank > 1) {
|
||||||
romAddress = 0x4000;
|
romAddress = 0x4000;
|
||||||
}
|
}
|
||||||
@ -1496,14 +1580,12 @@ void startCFIMode(boolean x16Mode) {
|
|||||||
void identifyCFI_GB() {
|
void identifyCFI_GB() {
|
||||||
// Reset flash
|
// Reset flash
|
||||||
display_Clear();
|
display_Clear();
|
||||||
dataOut();
|
|
||||||
writeByte_GB(0x6000, 0); // Set ROM Mode
|
writeByte_GB(0x6000, 0); // Set ROM Mode
|
||||||
writeByte_GB(0x2000, 0); // Set Bank to 0
|
writeByte_GB(0x2000, 0); // Set Bank to 0
|
||||||
writeByte_GB(0x3000, 0);
|
writeByte_GB(0x3000, 0);
|
||||||
|
|
||||||
startCFIMode(false); // Trying x8 mode first
|
startCFIMode(false); // Trying x8 mode first
|
||||||
|
|
||||||
dataIn_GB();
|
|
||||||
display_Clear();
|
display_Clear();
|
||||||
// Try x8 mode first
|
// Try x8 mode first
|
||||||
char cfiQRYx8[7];
|
char cfiQRYx8[7];
|
||||||
@ -1544,9 +1626,7 @@ void identifyCFI_GB() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataIn_GB();
|
|
||||||
flashBanks = 1 << (readByteCompensated(0x4E) - 14); // - flashX16Mode);
|
flashBanks = 1 << (readByteCompensated(0x4E) - 14); // - flashX16Mode);
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Reset flash
|
// Reset flash
|
||||||
writeByteCompensated(0xAAA, 0xf0);
|
writeByteCompensated(0xAAA, 0xf0);
|
||||||
@ -1621,9 +1701,6 @@ bool writeCFI_GB() {
|
|||||||
resetArduino();
|
resetArduino();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data pins to output
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Set ROM bank hi 0
|
// Set ROM bank hi 0
|
||||||
writeByte_GB(0x3000, 0);
|
writeByte_GB(0x3000, 0);
|
||||||
// Set ROM bank low 0
|
// Set ROM bank low 0
|
||||||
@ -1633,7 +1710,6 @@ bool writeCFI_GB() {
|
|||||||
// Reset flash
|
// Reset flash
|
||||||
writeByteCompensated(0xAAA, 0xf0);
|
writeByteCompensated(0xAAA, 0xf0);
|
||||||
delay(100);
|
delay(100);
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Reset flash
|
// Reset flash
|
||||||
writeByte_GB(0x555, 0xf0);
|
writeByte_GB(0x555, 0xf0);
|
||||||
@ -1650,8 +1726,6 @@ bool writeCFI_GB() {
|
|||||||
writeByteCompensated(0x555, 0x55);
|
writeByteCompensated(0x555, 0x55);
|
||||||
writeByteCompensated(0xAAA, 0x10);
|
writeByteCompensated(0xAAA, 0x10);
|
||||||
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Read the status register
|
// Read the status register
|
||||||
byte statusReg = readByte_GB(0);
|
byte statusReg = readByte_GB(0);
|
||||||
|
|
||||||
@ -1673,11 +1747,8 @@ bool writeCFI_GB() {
|
|||||||
// Blink led
|
// Blink led
|
||||||
blinkLED();
|
blinkLED();
|
||||||
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
// Set ROM bank
|
// Set ROM bank
|
||||||
writeByte_GB(0x2000, currBank);
|
writeByte_GB(0x2000, currBank);
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
for (unsigned int currAddr = 0x4000; currAddr < 0x7FFF; currAddr += 512) {
|
for (unsigned int currAddr = 0x4000; currAddr < 0x7FFF; currAddr += 512) {
|
||||||
for (int currByte = 0; currByte < 512; currByte++) {
|
for (int currByte = 0; currByte < 512; currByte++) {
|
||||||
@ -1696,8 +1767,6 @@ bool writeCFI_GB() {
|
|||||||
display_Update();
|
display_Update();
|
||||||
|
|
||||||
// Write flash
|
// Write flash
|
||||||
dataOut();
|
|
||||||
|
|
||||||
word currAddr = 0;
|
word currAddr = 0;
|
||||||
word endAddr = 0x3FFF;
|
word endAddr = 0x3FFF;
|
||||||
|
|
||||||
@ -1727,9 +1796,6 @@ bool writeCFI_GB() {
|
|||||||
// Write current byte
|
// Write current byte
|
||||||
writeByte_GB(currAddr + currByte, sdBuffer[currByte]);
|
writeByte_GB(currAddr + currByte, sdBuffer[currByte]);
|
||||||
|
|
||||||
// Set data pins to input
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
// Setting CS(PH3) and OE/RD(PH6) LOW
|
// Setting CS(PH3) and OE/RD(PH6) LOW
|
||||||
PORTH &= ~((1 << 3) | (1 << 6));
|
PORTH &= ~((1 << 3) | (1 << 6));
|
||||||
|
|
||||||
@ -1753,16 +1819,11 @@ bool writeCFI_GB() {
|
|||||||
PORTH |= (1 << 3) | (1 << 6);
|
PORTH |= (1 << 3) | (1 << 6);
|
||||||
__asm__("nop\n\tnop\n\tnop\n\t"); // Waste a few CPU cycles to remove write errors
|
__asm__("nop\n\tnop\n\tnop\n\t"); // Waste a few CPU cycles to remove write errors
|
||||||
|
|
||||||
// Set data pins to output
|
|
||||||
dataOut();
|
|
||||||
}
|
}
|
||||||
currAddr += 512;
|
currAddr += 512;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data pins to input again
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
display_Clear();
|
display_Clear();
|
||||||
println_Msg(F("Verifying"));
|
println_Msg(F("Verifying"));
|
||||||
display_Update();
|
display_Update();
|
||||||
@ -1777,9 +1838,6 @@ bool writeCFI_GB() {
|
|||||||
|
|
||||||
// Read number of banks and switch banks
|
// Read number of banks and switch banks
|
||||||
for (word bank = 1; bank < romBanks; bank++) {
|
for (word bank = 1; bank < romBanks; bank++) {
|
||||||
// Switch data pins to output
|
|
||||||
dataOut();
|
|
||||||
|
|
||||||
if (romType >= 5) { // MBC2 and above
|
if (romType >= 5) { // MBC2 and above
|
||||||
writeByte_GB(0x2100, bank); // Set ROM bank
|
writeByte_GB(0x2100, bank); // Set ROM bank
|
||||||
}
|
}
|
||||||
@ -1789,9 +1847,6 @@ bool writeCFI_GB() {
|
|||||||
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
writeByte_GB(0x2000, bank & 0x1F); // Set bits 0 & 4 (00011111) of ROM bank
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch data pins to intput
|
|
||||||
dataIn_GB();
|
|
||||||
|
|
||||||
if (bank > 1) {
|
if (bank > 1) {
|
||||||
romAddress = 0x4000;
|
romAddress = 0x4000;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,36 @@ boolean hasMenu;
|
|||||||
byte numGames;
|
byte numGames;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Compare checksum
|
||||||
|
boolean compare_checksum_GBS() {
|
||||||
|
println_Msg(F("Calculating Checksum"));
|
||||||
|
display_Update();
|
||||||
|
|
||||||
|
strcpy(fileName, romName);
|
||||||
|
strcat(fileName, ".GB");
|
||||||
|
|
||||||
|
// last used rom folder
|
||||||
|
EEPROM_readAnything(0, foldern);
|
||||||
|
sprintf(folder, "GB/ROM/%s/%d", romName, foldern - 1);
|
||||||
|
|
||||||
|
char calcsumStr[5];
|
||||||
|
sprintf(calcsumStr, "%04X", calc_checksum_GB(fileName, folder));
|
||||||
|
|
||||||
|
if (strcmp(calcsumStr, checksumStr) == 0) {
|
||||||
|
print_Msg(F("Result: "));
|
||||||
|
println_Msg(calcsumStr);
|
||||||
|
println_Msg(F("Checksum matches"));
|
||||||
|
display_Update();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_Msg(F("Result: "));
|
||||||
|
println_Msg(calcsumStr);
|
||||||
|
print_Error(F("Checksum Error"), false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
byte readByte_GBS(word myAddress) {
|
byte readByte_GBS(word myAddress) {
|
||||||
PORTF = myAddress & 0xFF;
|
PORTF = myAddress & 0xFF;
|
||||||
PORTK = (myAddress >> 8) & 0xFF;
|
PORTK = (myAddress >> 8) & 0xFF;
|
||||||
@ -166,7 +196,7 @@ void gbSmartGameOptions()
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
sd.chdir("/");
|
sd.chdir("/");
|
||||||
readROM_GB();
|
readROM_GB();
|
||||||
compare_checksum_GB();
|
compare_checksum_GBS();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: // Read SRAM
|
case 1: // Read SRAM
|
||||||
@ -329,7 +359,7 @@ void gbSmartGetGames()
|
|||||||
|
|
||||||
// check if contain menu
|
// check if contain menu
|
||||||
hasMenu = true;
|
hasMenu = true;
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
if (readByte_GBS(0x0134 + i) != menu_title[i])
|
if (readByte_GBS(0x0134 + i) != menu_title[i])
|
||||||
@ -349,7 +379,7 @@ void gbSmartGetGames()
|
|||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, i);
|
writeByte_GB(0x2100, i);
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
// read signature
|
// read signature
|
||||||
for (uint8_t j = 0x00; j < 0x30; j++)
|
for (uint8_t j = 0x00; j < 0x30; j++)
|
||||||
{
|
{
|
||||||
@ -385,7 +415,7 @@ gb_smart_get_game_loop_end:;
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (uint8_t j = 0; j < 15; j++)
|
for (uint8_t j = 0; j < 15; j++)
|
||||||
{
|
{
|
||||||
myByte = readByte_GBS(0x0134 + j);
|
myByte = readByte_GBS(0x0134 + j);
|
||||||
@ -424,7 +454,7 @@ void gbSmartReadFlash()
|
|||||||
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
||||||
|
|
||||||
// dump fixed bank 0x00
|
// dump fixed bank 0x00
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512)
|
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512)
|
||||||
{
|
{
|
||||||
for (uint16_t c = 0; c < 512; c++)
|
for (uint16_t c = 0; c < 512; c++)
|
||||||
@ -439,7 +469,7 @@ void gbSmartReadFlash()
|
|||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, bank);
|
writeByte_GB(0x2100, bank);
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512)
|
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512)
|
||||||
{
|
{
|
||||||
for (uint16_t c = 0; c < 512; c++)
|
for (uint16_t c = 0; c < 512; c++)
|
||||||
@ -558,7 +588,7 @@ void gbSmartWriteFlashFromMyFile(uint32_t addr)
|
|||||||
gbSmartWriteFlashByte(addr + i, 0x00); // BCH should be 0x00
|
gbSmartWriteFlashByte(addr + i, 0x00); // BCH should be 0x00
|
||||||
|
|
||||||
// waiting for finishing
|
// waiting for finishing
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
while ((readByte_GBS(addr + i) & 0x80) == 0x00);
|
while ((readByte_GBS(addr + i) & 0x80) == 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,7 +611,7 @@ uint32_t gbSmartVerifyFlash()
|
|||||||
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(0x00, gbSmartRomSizeGB, gbSmartSramSizeGB);
|
||||||
|
|
||||||
// verify bank 0x00
|
// verify bank 0x00
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512)
|
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr += 512)
|
||||||
{
|
{
|
||||||
myFile.read(sdBuffer, 512);
|
myFile.read(sdBuffer, 512);
|
||||||
@ -599,7 +629,7 @@ uint32_t gbSmartVerifyFlash()
|
|||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, bank);
|
writeByte_GB(0x2100, bank);
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512)
|
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr += 512)
|
||||||
{
|
{
|
||||||
myFile.read(sdBuffer, 512);
|
myFile.read(sdBuffer, 512);
|
||||||
@ -626,7 +656,7 @@ byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank)
|
|||||||
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
gbSmartRemapStartBank(flash_start_bank, gbSmartFlashSizeGB, gbSmartSramSizeGB);
|
||||||
|
|
||||||
// check first bank
|
// check first bank
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr++)
|
for (uint16_t addr = 0x0000; addr <= 0x3fff; addr++)
|
||||||
{
|
{
|
||||||
if (readByte_GBS(addr) != 0xff)
|
if (readByte_GBS(addr) != 0xff)
|
||||||
@ -639,7 +669,7 @@ byte gbSmartBlankCheckingFlash(uint8_t flash_start_bank)
|
|||||||
dataOut();
|
dataOut();
|
||||||
writeByte_GB(0x2100, bank);
|
writeByte_GB(0x2100, bank);
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr++)
|
for (uint16_t addr = 0x4000; addr <= 0x7fff; addr++)
|
||||||
{
|
{
|
||||||
if (readByte_GBS(addr) != 0xff)
|
if (readByte_GBS(addr) != 0xff)
|
||||||
@ -667,7 +697,7 @@ void gbSmartEraseFlash(uint8_t flash_start_bank)
|
|||||||
gbSmartWriteFlashByte(0x0000, 0x20);
|
gbSmartWriteFlashByte(0x0000, 0x20);
|
||||||
gbSmartWriteFlashByte(0x0000, 0xd0);
|
gbSmartWriteFlashByte(0x0000, 0xd0);
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
while ((readByte_GBS(0x0000) & 0x80) == 0x00);
|
while ((readByte_GBS(0x0000) & 0x80) == 0x00);
|
||||||
|
|
||||||
// blink LED
|
// blink LED
|
||||||
@ -682,7 +712,7 @@ void gbSmartEraseFlash(uint8_t flash_start_bank)
|
|||||||
gbSmartWriteFlashByte(0x4000, 0x20);
|
gbSmartWriteFlashByte(0x4000, 0x20);
|
||||||
gbSmartWriteFlashByte(0x4000, 0xd0);
|
gbSmartWriteFlashByte(0x4000, 0xd0);
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
while ((readByte_GBS(0x4000) & 0x80) == 0x00);
|
while ((readByte_GBS(0x4000) & 0x80) == 0x00);
|
||||||
|
|
||||||
// blink LED
|
// blink LED
|
||||||
@ -730,7 +760,7 @@ void gbSmartRemapStartBank(uint8_t rom_start_bank, uint8_t rom_size, uint8_t sra
|
|||||||
// start set new base bank
|
// start set new base bank
|
||||||
writeByte_GB(0x1000, 0xa5);
|
writeByte_GB(0x1000, 0xa5);
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
rom_start_bank = gbSmartGetResizeParam(rom_size, sram_size);
|
rom_start_bank = gbSmartGetResizeParam(rom_size, sram_size);
|
||||||
|
|
||||||
dataOut();
|
dataOut();
|
||||||
@ -740,7 +770,7 @@ void gbSmartRemapStartBank(uint8_t rom_start_bank, uint8_t rom_size, uint8_t sra
|
|||||||
writeByte_GB(0x2100, 0x01);
|
writeByte_GB(0x2100, 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
dataIn_GB();
|
dataIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get magic number for 0x7000 register.
|
// Get magic number for 0x7000 register.
|
||||||
|
@ -62,13 +62,21 @@
|
|||||||
// Use calibration data from snes_clk.txt
|
// Use calibration data from snes_clk.txt
|
||||||
// #define clockgen_calibration
|
// #define clockgen_calibration
|
||||||
|
|
||||||
|
// Write all info to log.txt in root dir
|
||||||
|
//#define global_log
|
||||||
|
|
||||||
|
// Use Adafruit Clock Generator
|
||||||
|
// #define clockgen_installed
|
||||||
|
|
||||||
|
//******************************************
|
||||||
|
// GB OPTIONS
|
||||||
|
//******************************************
|
||||||
|
// Renames ROM if found in database (slow)
|
||||||
|
//#define no-intro
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// N64 OPTIONS
|
// N64 OPTIONS
|
||||||
//******************************************
|
//******************************************
|
||||||
// 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
|
|
||||||
|
|
||||||
// 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
|
// 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
|
// #define fastcrc
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user