Add header and ToC checksum calculation for N64 Controller Pak read

This commit is contained in:
sanni 2022-08-19 11:48:43 +02:00
parent 22cb89d9f7
commit e01ce10faf
2 changed files with 119 additions and 2 deletions

View File

@ -4,7 +4,7 @@
This project represents a community-driven effort to provide
an easy to build and easy to modify cartridge dumper.
Date: 18.08.2022
Date: 19.08.2022
Version: 9.5
SD lib: https://github.com/greiman/SdFat
@ -30,7 +30,7 @@
splash5 - GBSmart, Wonderswan and NGP modules
hkz & themanbehindthecurtain - N64 flashram commands
Andrew Brown & Peter Den Hartog - N64 controller protocol
Shaun Taylor - N64 controller CRC functions
libdragon - N64 controller checksum functions
Angus Gratton - CRC32
Snes9x - SuperFX sram fix
insidegadgets - GBCartRead
@ -2008,6 +2008,51 @@ void print_Msg(byte message, int outputFormat) {
#endif
}
void print_Msg(word message, int outputFormat) {
#ifdef enable_LCD
display.print(message, outputFormat);
#endif
#ifdef enable_OLED
display.print(message, outputFormat);
#endif
#ifdef enable_serial
Serial.print(message, outputFormat);
#endif
#ifdef global_log
myLog.print(message, outputFormat);
#endif
}
void print_Msg(int message, int outputFormat) {
#ifdef enable_LCD
display.print(message, outputFormat);
#endif
#ifdef enable_OLED
display.print(message, outputFormat);
#endif
#ifdef enable_serial
Serial.print(message, outputFormat);
#endif
#ifdef global_log
myLog.print(message, outputFormat);
#endif
}
void print_Msg(long unsigned int message, int outputFormat) {
#ifdef enable_LCD
display.print(message, outputFormat);
#endif
#ifdef enable_OLED
display.print(message, outputFormat);
#endif
#ifdef enable_serial
Serial.print(message, outputFormat);
#endif
#ifdef global_log
myLog.print(message, outputFormat);
#endif
}
void print_Msg(String string) {
#ifdef enable_LCD
display.print(string);

View File

@ -195,6 +195,7 @@ void n64ControllerMenu() {
display_Clear();
display_Update();
readMPK();
checksumMPK();
println_Msg(F(""));
println_Msg(F("Press Button..."));
display_Update();
@ -2068,6 +2069,77 @@ void readMPK() {
myFile.close();
}
// Calculates the checksum of the header
boolean checkHeader(byte startAddress) {
word sum = 0;
// first 28 bytes are the header, then comes the checksum(word) followed by the reverse checksum(0xFFF2 - checksum)
for (int i = 0; i < 28; i += 2) {
word tempword = (((sdBuffer[startAddress + i] & 0xFF) << 8) | (sdBuffer[startAddress + i + 1] & 0xFF));
sum += tempword;
}
if ((((sdBuffer[startAddress + 28] & 0xFF) << 8) | (sdBuffer[startAddress + 29] & 0xFF)) != (sum & 0xFFFF)) {
return 0;
}
else {
return 1;
}
}
// verifies if read was successful
void checksumMPK() {
println_Msg(F(""));
print_Msg(F("Header..."));
display_Update();
//open file on sd card
if (!myFile.open(fileName, O_READ)) {
print_Error(F("Can't open file"), true);
}
// Read first 256 byte which contains the header including checksum and reverse checksum and three copies of it
myFile.read(sdBuffer, 256);
// At least one header copy needs to be ok
if ((checkHeader(0x20)) || (checkHeader(0x60)) || (checkHeader(0x80)) || (checkHeader(0xC0)))
println_Msg(F("OK"));
else
println_Msg(F("Error"));
display_Update();
// Check both TOC copies
writeErrors = 0;
print_Msg(F("TOC..."));
display_Update();
word sum = 0;
// Read 2nd and 3rd 256 byte page with TOC info
for (word currSdBuffer = 0x100; currSdBuffer < 0x300; currSdBuffer += 256) {
sum = 0;
// Read 256 bytes into SD buffer
myFile.read(sdBuffer, 256);
// Calculate TOC checksum
for (int i = 5; i < 128; i++ ) {
sum += sdBuffer[(i << 1) + 1];
}
if (sdBuffer[1] != (sum & 0xFF))
writeErrors++;
}
// Both TOCs damaged
if (writeErrors > 1)
println_Msg("Error");
else
println_Msg("Ok");
display_Update();
// Close the file:
myFile.close();
}
void writeMPK() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName);