mirror of
https://github.com/sanni/cartreader.git
synced 2025-01-11 20:49:06 +01:00
V9.7: Calculate block CRC during Controller Pak read
This commit is contained in:
parent
15966b79c8
commit
07a38f30c2
@ -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: 28.08.2022
|
Date: 09.09.2022
|
||||||
Version: 9.6
|
Version: 9.7
|
||||||
|
|
||||||
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
|
||||||
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
|
|
||||||
char ver[5] = "9.6";
|
char ver[5] = "9.7";
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// !!! CHOOSE HARDWARE VERSION !!!
|
// !!! CHOOSE HARDWARE VERSION !!!
|
||||||
|
@ -22,9 +22,9 @@ bool tempBits[65];
|
|||||||
int eepPages;
|
int eepPages;
|
||||||
|
|
||||||
// N64 Controller
|
// N64 Controller
|
||||||
// 256 bits of received Controller data
|
// 256 bits of received Controller data + 8 bit CRC
|
||||||
char N64_raw_dump[257];
|
char N64_raw_dump[265];
|
||||||
// Array that holds one Controller Pak block of 32 bytes
|
// Array that holds one Controller Pak block of 32 bytes data
|
||||||
byte myBlock[33];
|
byte myBlock[33];
|
||||||
String rawStr = ""; // above char array read into a string
|
String rawStr = ""; // above char array read into a string
|
||||||
struct {
|
struct {
|
||||||
@ -192,6 +192,7 @@ void n64ControllerMenu() {
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
resetController();
|
resetController();
|
||||||
|
checkController();
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
readMPK();
|
readMPK();
|
||||||
@ -204,6 +205,7 @@ void n64ControllerMenu() {
|
|||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
resetController();
|
resetController();
|
||||||
|
checkController();
|
||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
// Change to root
|
// Change to root
|
||||||
@ -605,26 +607,25 @@ static word addrCRC(word address) {
|
|||||||
return address | crc;
|
return address | crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unused
|
static uint8_t dataCRC( uint8_t *data ) {
|
||||||
//static byte dataCRC(byte * data) {
|
uint8_t ret = 0;
|
||||||
// byte ret = 0;
|
for ( int i = 0; i <= 32; i++ ) {
|
||||||
// for (byte i = 0; i <= 32; i++) {
|
for ( int j = 7; j >= 0; j-- ) {
|
||||||
// for (byte j = 7; j >= 0; j--) {
|
int tmp = 0;
|
||||||
// int tmp = 0;
|
if ( ret & 0x80 ) {
|
||||||
// if (ret & 0x80) {
|
tmp = 0x85;
|
||||||
// tmp = 0x85;
|
}
|
||||||
// }
|
ret <<= 1;
|
||||||
// ret <<= 1;
|
if ( i < 32 ) {
|
||||||
// if ( i < 32 ) {
|
if ( data[i] & (0x01 << j) ) {
|
||||||
// if (data[i] & (0x01 << j)) {
|
ret |= 0x1;
|
||||||
// ret |= 0x1;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
ret ^= tmp;
|
||||||
// ret ^= tmp;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
return ret;
|
||||||
// return ret;
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
N64 Controller Protocol Functions
|
N64 Controller Protocol Functions
|
||||||
@ -1952,7 +1953,57 @@ void resetController() {
|
|||||||
delay(100);
|
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) {
|
void readBlock(word myAddress) {
|
||||||
// Calculate the address CRC
|
// Calculate the address CRC
|
||||||
word myAddressCRC = addrCRC(myAddress);
|
word myAddressCRC = addrCRC(myAddress);
|
||||||
@ -1970,8 +2021,8 @@ void readBlock(word myAddress) {
|
|||||||
N64_send(addressHigh, 1);
|
N64_send(addressHigh, 1);
|
||||||
N64_send(addressLow, 1);
|
N64_send(addressLow, 1);
|
||||||
N64_stop();
|
N64_stop();
|
||||||
// read in data
|
// read in 32 byte data + 1 byte crc
|
||||||
N64_get(256);
|
N64_get(264);
|
||||||
// end of time sensitive code
|
// end of time sensitive code
|
||||||
interrupts();
|
interrupts();
|
||||||
|
|
||||||
@ -1999,6 +2050,34 @@ void readBlock(word myAddress) {
|
|||||||
// Save byte into block array
|
// Save byte into block array
|
||||||
myBlock[i / 8] = myByte;
|
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
|
// reads the MPK file to the sd card
|
||||||
@ -2052,7 +2131,7 @@ void readMPK() {
|
|||||||
sdBuffer[currBlock + currByte] = myBlock[currByte];
|
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)
|
if (currBlock < 479)
|
||||||
delayMicroseconds(800);
|
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() {
|
void checksumMPK() {
|
||||||
println_Msg(F(""));
|
println_Msg(F(""));
|
||||||
print_Msg(F("Header..."));
|
print_Msg(F("Header..."));
|
||||||
|
@ -404,7 +404,7 @@ void getCartInfo_SMS() {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cartSize = 48 * 1024UL;
|
cartSize = 48 * 1024UL;
|
||||||
|
|
||||||
// LED Error
|
// LED Error
|
||||||
setColor_RGB(0, 0, 255);
|
setColor_RGB(0, 0, 255);
|
||||||
break;
|
break;
|
||||||
@ -604,7 +604,7 @@ void readROM_SMS() {
|
|||||||
|
|
||||||
// Blink led
|
// Blink led
|
||||||
blinkLED();
|
blinkLED();
|
||||||
|
|
||||||
// Read 16KB from slot 2 which starts at 0x8000
|
// Read 16KB from slot 2 which starts at 0x8000
|
||||||
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
|
for (word currBuffer = 0; currBuffer < bankSize; currBuffer += 512) {
|
||||||
// Fill SD buffer
|
// Fill SD buffer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user