mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-14 00:45:07 +01:00
Add header and ToC checksum calculation for N64 Controller Pak read
This commit is contained in:
parent
22cb89d9f7
commit
e01ce10faf
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user