V9.7: Calculate block CRC during Controller Pak read

This commit is contained in:
sanni 2022-09-09 00:21:16 +02:00
parent 15966b79c8
commit 07a38f30c2
3 changed files with 112 additions and 33 deletions

View File

@ -4,8 +4,8 @@
This project represents a community-driven effort to provide
an easy to build and easy to modify cartridge dumper.
Date: 28.08.2022
Version: 9.6
Date: 09.09.2022
Version: 9.7
SD lib: https://github.com/greiman/SdFat
OLED lib: https://github.com/adafruit/Adafruit_SSD1306
@ -59,7 +59,7 @@
**********************************************************************************/
char ver[5] = "9.6";
char ver[5] = "9.7";
//******************************************
// !!! CHOOSE HARDWARE VERSION !!!

View File

@ -22,9 +22,9 @@ bool tempBits[65];
int eepPages;
// N64 Controller
// 256 bits of received Controller data
char N64_raw_dump[257];
// Array that holds one Controller Pak block of 32 bytes
// 256 bits of received Controller data + 8 bit CRC
char N64_raw_dump[265];
// Array that holds one Controller Pak block of 32 bytes data
byte myBlock[33];
String rawStr = ""; // above char array read into a string
struct {
@ -192,6 +192,7 @@ void n64ControllerMenu() {
case 1:
resetController();
checkController();
display_Clear();
display_Update();
readMPK();
@ -204,6 +205,7 @@ void n64ControllerMenu() {
case 2:
resetController();
checkController();
display_Clear();
display_Update();
// Change to root
@ -605,26 +607,25 @@ static word addrCRC(word address) {
return address | crc;
}
// unused
//static byte dataCRC(byte * data) {
// byte ret = 0;
// for (byte i = 0; i <= 32; i++) {
// for (byte j = 7; j >= 0; j--) {
// int tmp = 0;
// if (ret & 0x80) {
// tmp = 0x85;
// }
// ret <<= 1;
// if ( i < 32 ) {
// if (data[i] & (0x01 << j)) {
// ret |= 0x1;
// }
// }
// ret ^= tmp;
// }
// }
// return ret;
//}
static uint8_t dataCRC( uint8_t *data ) {
uint8_t ret = 0;
for ( int i = 0; i <= 32; i++ ) {
for ( int j = 7; j >= 0; j-- ) {
int tmp = 0;
if ( ret & 0x80 ) {
tmp = 0x85;
}
ret <<= 1;
if ( i < 32 ) {
if ( data[i] & (0x01 << j) ) {
ret |= 0x1;
}
}
ret ^= tmp;
}
}
return ret;
}
/******************************************
N64 Controller Protocol Functions
@ -1952,7 +1953,57 @@ void resetController() {
delay(100);
}
// read 32bytes from controller pak
// read 3 bytes from controller
void checkController() {
display_Clear();
// Check if line is HIGH
if (!N64_QUERY)
print_Error(F("Data line LOW"), true);
// Send status command
unsigned char command[] = {0x0};
// don't want interrupts getting in the way
noInterrupts();
N64_send(command, 1);
N64_stop();
// read in data
N64_get(32);
// end of time sensitive code
interrupts();
// Empty N64_raw_dump into myBlock
for (word i = 0; i < 32; i += 8) {
boolean byteFlipped[9];
// Flip byte order
byteFlipped[0] = N64_raw_dump[i + 7];
byteFlipped[1] = N64_raw_dump[i + 6];
byteFlipped[2] = N64_raw_dump[i + 5];
byteFlipped[3] = N64_raw_dump[i + 4];
byteFlipped[4] = N64_raw_dump[i + 3];
byteFlipped[5] = N64_raw_dump[i + 2];
byteFlipped[6] = N64_raw_dump[i + 1];
byteFlipped[7] = N64_raw_dump[i + 0];
// Join bits into one byte
unsigned char myByte = 0;
for (byte j = 0; j < 8; ++j) {
if (byteFlipped[j]) {
myByte |= 1 << j;
}
}
if ((i == 0) && (myByte != 0x05))
print_Error(F("Controller not found"), true);
if ((i == 16) && (myByte != 0x01))
print_Error(F("Controller Pak not found"), true);
if ((i == 16) && (myByte == 0x04))
print_Error(F("CRC Error"), true);
}
}
// read 32bytes from controller pak and calculate CRC
void readBlock(word myAddress) {
// Calculate the address CRC
word myAddressCRC = addrCRC(myAddress);
@ -1970,8 +2021,8 @@ void readBlock(word myAddress) {
N64_send(addressHigh, 1);
N64_send(addressLow, 1);
N64_stop();
// read in data
N64_get(256);
// read in 32 byte data + 1 byte crc
N64_get(264);
// end of time sensitive code
interrupts();
@ -1999,6 +2050,34 @@ void readBlock(word myAddress) {
// Save byte into block array
myBlock[i / 8] = myByte;
}
// Get CRC of block send
boolean byteFlipped[9];
// Flip byte order
byteFlipped[0] = N64_raw_dump[256 + 7];
byteFlipped[1] = N64_raw_dump[256 + 6];
byteFlipped[2] = N64_raw_dump[256 + 5];
byteFlipped[3] = N64_raw_dump[256 + 4];
byteFlipped[4] = N64_raw_dump[256 + 3];
byteFlipped[5] = N64_raw_dump[256 + 2];
byteFlipped[6] = N64_raw_dump[256 + 1];
byteFlipped[7] = N64_raw_dump[256 + 0];
unsigned char blockCRC = 0;
for (byte k = 0; k < 8; ++k) {
if (byteFlipped[k]) {
blockCRC |= 1 << k;
}
}
// Calculate CRC of block received
unsigned char myCRC = dataCRC(&myBlock[0]);
// Compare
if (blockCRC != myCRC) {
display_Clear();
print_Error(F("CRC ERROR"), true);
}
}
// reads the MPK file to the sd card
@ -2052,7 +2131,7 @@ void readMPK() {
sdBuffer[currBlock + currByte] = myBlock[currByte];
}
// Real N64 has about 627us pause between banks, loop takes 500us, add a bit extra delay
// Real N64 has about 627us pause between banks, add a bit extra delay
if (currBlock < 479)
delayMicroseconds(800);
}
@ -2087,7 +2166,7 @@ boolean checkHeader(byte startAddress) {
}
}
// verifies if read was successful
// verifies if Controller Pak holds valid header data
void checksumMPK() {
println_Msg(F(""));
print_Msg(F("Header..."));

View File

@ -404,7 +404,7 @@ void getCartInfo_SMS() {
break;
default:
cartSize = 48 * 1024UL;
// LED Error
setColor_RGB(0, 0, 255);
break;
@ -604,7 +604,7 @@ void readROM_SMS() {
// Blink led
blinkLED();
// Read 16KB from slot 2 which starts at 0x8000
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
// Fill SD buffer