All: Factorise CRC functions.

This saves 370 bytes of program space.
This commit is contained in:
Vincent Pelletier 2022-10-23 12:26:40 +00:00
parent 84738038e1
commit 3b05046ee9
5 changed files with 55 additions and 65 deletions

View File

@ -531,32 +531,48 @@ static const uint32_t crc_32_tab[] PROGMEM = { /* CRC polynomial 0xedb88320 */
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
inline uint32_t updateCRC(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);
// Defined as a macros, as compiler disregards inlining requests and these are
// performance-critical functions.
#define UPDATE_CRC(crc, ch) do { \
uint8_t idx = ((crc) ^ (ch)) & 0xff; \
uint32_t tab_value = pgm_read_dword(crc_32_tab + idx); \
(crc) = tab_value ^ ((crc) >> 8); \
} while (0)
uint32_t updateCRC(const byte *buffer, size_t length, uint32_t crc) {
for (size_t c = 0; c < length; c++) {
UPDATE_CRC(crc, buffer[c]);
}
return crc;
}
uint32_t calculateCRC(const byte *buffer, size_t length) {
uint32_t crc = 0xFFFFFFFF;
updateCRC(buffer, length, crc);
return ~crc;
}
uint32_t calculateCRC(FsFile &infile) {
uint32_t byte_count;
uint32_t crc = 0xFFFFFFFF;
while((byte_count = infile.read(sdBuffer, sizeof(sdBuffer))) != 0) {
updateCRC(sdBuffer, byte_count, crc);
}
return ~crc;
}
// Calculate rom's CRC32 from SD
uint32_t calculateCRC(char* fileName, char* folder, int offset) {
// Open folder
FsFile infile;
uint32_t result;
sd.chdir(folder);
// Open file
if (myFile.open(fileName, O_READ)) {
uint32_t oldcrc32 = 0xFFFFFFFF;
// Skip iNES header
myFile.seek(offset);
for (unsigned long currByte = 0; currByte < ((myFile.fileSize() - offset) / 512); currByte++) {
myFile.read(sdBuffer, 512);
for (int c = 0; c < 512; c++) {
oldcrc32 = updateCRC(sdBuffer[c], oldcrc32);
}
}
// Close the file:
myFile.close();
return ~oldcrc32;
if (infile.open(fileName, O_READ)) {
infile.seek(offset);
result = calculateCRC(infile);
infile.close();
return result;
} else {
display_Clear();
print_Msg(F("File "));

View File

@ -3379,8 +3379,6 @@ redumpsamefolder:
// prepare crc32
uint32_t oldcrc32 = 0xFFFFFFFF;
uint32_t tab_value = 0;
uint8_t idx = 0;
// run combined dumper + crc32 routine for better performance, as N64 ROMs are quite large for an 8bit micro
// currently dumps + checksums a 32MB cart in 170 seconds (down from 347 seconds)
@ -3412,12 +3410,8 @@ redumpsamefolder:
PORTH |= (1 << 6);
// crc32 update
idx = ((oldcrc32) ^ (buffer[c]));
tab_value = pgm_read_dword(crc_32_tab + idx);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
idx = ((oldcrc32) ^ (buffer[c + 1]));
tab_value = pgm_read_dword(crc_32_tab + idx);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
UPDATE_CRC(oldcrc32, buffer[c]);
UPDATE_CRC(oldcrc32, buffer[c + 1]);
}
// Set the address for the next 512 bytes to dump
@ -3443,12 +3437,8 @@ redumpsamefolder:
PORTH |= (1 << 6);
// crc32 update
idx = ((oldcrc32) ^ (buffer[c])) & 0xff;
tab_value = pgm_read_dword(crc_32_tab + idx);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
idx = ((oldcrc32) ^ (buffer[c + 1])) & 0xff;
tab_value = pgm_read_dword(crc_32_tab + idx);
oldcrc32 = tab_value ^ ((oldcrc32) >> 8);
UPDATE_CRC(oldcrc32, buffer[c]);
UPDATE_CRC(oldcrc32, buffer[c + 1]);
}
processedProgressBar += 1024;

View File

@ -532,8 +532,8 @@ void getMapping() {
// Read first 512 bytes of first and last block of PRG ROM and compute CRC32
// MMC3 maps the last 8KB block of PRG ROM to 0xE000 while 0x8000 can contain random data after bootup
for (int c = 0; c < 512; c++) {
oldcrc32 = updateCRC(read_prg_byte(0x8000 + c), oldcrc32);
oldcrc32MMC3 = updateCRC(read_prg_byte(0xE000 + c), oldcrc32MMC3);
UPDATE_CRC(oldcrc32, read_prg_byte(0x8000 + c));
UPDATE_CRC(oldcrc32MMC3, read_prg_byte(0xE000 + c));
}
oldcrc32 = ~oldcrc32;
oldcrc32MMC3 = ~oldcrc32MMC3;
@ -1054,27 +1054,19 @@ int int_pow(int base, int exp) { // Power for int
CRC Functions
*****************************************/
void calcCRC(char* checkFile, uint32_t* crcCopy, unsigned long offset) {
uint32_t crc = 0xFFFFFFFF;
void printCRC(char* checkFile, uint32_t* crcCopy, unsigned long offset) {
uint32_t crc;
char tempCRC[9];
int byte_count;
FsFile crcFile = sd.open(checkFile);
crcFile.seek(offset);
while (crcFile.available()) {
byte_count = crcFile.read(sdBuffer, sizeof(sdBuffer));
for (int x = 0; x < byte_count; x++) {
uint8_t c = sdBuffer[x];
crc = updateCRC(c, crc);
}
}
crc = ~crc;
crc = calculateCRC(crcFile);
crcFile.close();
sprintf(tempCRC, "%08lX", crc);
if (crcCopy != NULL) {
*crcCopy = crc;
}
sprintf(tempCRC, "%08lX", crc);
print_Msg(F("CRC: "));
println_Msg(tempCRC);
display_Update();
@ -1324,7 +1316,7 @@ void outputNES() {
println_Msg(F(""));
display_Update();
calcCRC(outputFile, NULL, crcOffset);
printCRC(outputFile, NULL, crcOffset);
LED_RED_OFF;
LED_GREEN_OFF;
LED_BLUE_OFF;
@ -3247,7 +3239,7 @@ void readPRG(boolean readrom) {
println_Msg(F(""));
display_Update();
#ifndef nointro
calcCRC(fileName, &prg_crc32, 0);
printCRC(fileName, &prg_crc32, 0);
#endif
}
}
@ -3972,7 +3964,7 @@ void readCHR(boolean readrom) {
println_Msg(F(""));
display_Update();
#ifndef nointro
calcCRC(fileName, &chr_crc32, 0);
printCRC(fileName, &chr_crc32, 0);
#endif
}
}
@ -4161,9 +4153,9 @@ void readRAM() {
display_Update();
if ((mapper == 16) || (mapper == 159))
calcCRC(fileName, NULL, 0);
printCRC(fileName, NULL, 0);
else
calcCRC(fileName, NULL, 0);
printCRC(fileName, NULL, 0);
}
}
set_address(0);

View File

@ -807,12 +807,8 @@ boolean checkcart_SFM() {
}
// Calculate CRC32 of header
uint32_t oldcrc32 = 0xFFFFFFFF;
for (int c = 0; c < 80; c++) {
oldcrc32 = updateCRC(snesHeader[c], oldcrc32);
}
char crcStr[9];
sprintf(crcStr, "%08lX", ~oldcrc32);
sprintf(crcStr, "%08lX", calculateCRC(snesHeader, 80));
// Get Checksum as string
sprintf(checksumStr, "%02X%02X", readBank_SFM(0, 65503), readBank_SFM(0, 65502));

View File

@ -950,12 +950,8 @@ boolean checkcart_SNES() {
}
// Calculate CRC32 of header
uint32_t oldcrc32 = 0xFFFFFFFF;
for (int c = 0; c < 80; c++) {
oldcrc32 = updateCRC(snesHeader[c], oldcrc32);
}
char crcStr[9];
sprintf(crcStr, "%08lX", ~oldcrc32);
sprintf(crcStr, "%08lX", calculateCRC(snesHeader, 80));
// Get Checksum as string
sprintf(checksumStr, "%02X%02X", snesHeader[0xFFDF - headerStart], snesHeader[0xFFDE - headerStart]);