Okay, here's the SD buffer code to speed up reads and writes. I'll post the complete dump code after I test the ExHiROM carts and a couple other enhanced chip carts.
First off we add the SDBuffer[512] in the define section.
Next, my current calc_checksum() code. Some of it is untested as I don't have all of the different sizes (missing 1.5MB, 2.5MB & "Normal" 3MB). I referred to ROMs from the GoodSets where needed.
//Define Cart Reader Variables
...
byte SDBuffer[512];
...
//*************************CALCULATE CHECKSUM**************************************
unsigned int calc_checksum (char* fileName, char* folder) {
unsigned int calcChecksum = 0;
unsigned int calcChecksumChunk = 0;
int calcFilesize = 0;
unsigned int c = 0;
unsigned long i = 0;
unsigned long j = 0;
if (strcmp(folder, "root") != 0)
sd.chdir(folder);
// If file exists
if (myFile.open(fileName, O_READ)) {
calcFilesize = myFile.fileSize() * 8 / 1024 / 1024;
if (calcFilesize == 12 || calcFilesize == 20) {
// Divide filesize by 8 to get number of 8Mbit chunks
for (i = 0; i < (calcFilesize / 8); i++ ) {
// Add all the bits in the 8Mbit chunks
for (j = 0; j < (1048576 / 512); j++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
}
calcChecksum = calcChecksumChunk;
}
calcChecksumChunk = 0;
// Add the 4Mbit rest
for (j = 0; j < (524288 / 512); j++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
}
calcChecksum += 2 * calcChecksumChunk;
}
else if (calcFilesize == 24 || calcFilesize == 28) {
// Momotarou Dentestu Happy Fix 3MB (24Mbit)
if ((calcFilesize == 24) && (romSizeExp = 0x0C)) {
for (i = 0; i < (myFile.fileSize() / 512); i++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
}
calcChecksum = 2 * calcChecksumChunk;
}
else {
for (i = 0; i < (calcFilesize / 16); i++ ) {
// Add all the bits in the 16Mbit chunks
for (j = 0; j < (2097152 / 512); j++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
}
calcChecksum = calcChecksumChunk;
}
calcChecksumChunk = 0;
// Add the 8Mbit rest
for (j = 0; j < (1048576 / 512); j++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
}
calcChecksum += 2 * calcChecksumChunk;
}
}
else if (calcFilesize == 48) {
// Star Ocean/Tales of Phantasia Fix 6MB (48Mbit)
// Add the 4MB (32Mbit) start
for (j = 0; j < (4194304 / 512); j++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
calcChecksum = calcChecksumChunk;
}
calcChecksumChunk = 0;
// Add the 2MB (16Mbit) end
for (j = 0; j < (2097152 / 512); j++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
}
calcChecksum += 2 * calcChecksumChunk;
}
else {
//calcFilesize == 2, 4, 8, 16, 32, 40, etc
for (i = 0; i < (myFile.fileSize() / 512); i++) {
myFile.read(SDBuffer, 512);
for (c = 0; c < 512; c++) {
calcChecksumChunk += SDBuffer[c];
}
calcChecksum = calcChecksumChunk;
}
}
myFile.close();
sd.chdir();
return (calcChecksum);
}
// Else show error
else {
display.println("ERROR");
display.println("DUMP ROM 1ST");
display.display();
return 0;
}
}
The checksum calculation greatly benefits from the 512 byte buffer. We read the file on the SD card in 512 byte chunks to perform our calculation. Calculations used to take minutes but now it takes only seconds to complete.
Now for the dumping code. In an effort to streamline the dumpROM() code, I created a dumpLoROM() and dumpHiROM(). These routines dump 512 bytes into the SDBuffer then writes the buffer to the file on the SD card.
long dumpLoROM() {
display.println("Dumping LoROM");
display.print("Banks: ");
display.println(numBanks);
display.display();
long dumpedBytes = 0;
// Read up to 96 banks starting at bank 0x00.
for (int currBank = 0; currBank < numBanks; currBank++) {
// give status updates via LCD
display.print(".");
display.display();
// Dump the bytes to SD
for (long currByte = 0x8000; currByte < 0x10000; currByte += 512) {
for (unsigned long c = 0; c < 512; c++) {
SDBuffer[c] = dumpByte(currBank, currByte + c, false);
dumpedBytes++;
}
myFile.write(SDBuffer, 512);
}
}
return(dumpedBytes);
}
long dumpHiROM(int currBank, int endBank, long dumpedBytes) {
for(currBank; currBank < endBank; currBank++) {
// give status updates via LCD
display.print(".");
display.display();
// Dump the bytes to SD
for(long currByte=0; currByte < 0x10000; currByte += 512) {
for (unsigned long c = 0; c < 512; c++) {
SDBuffer[c] = dumpByte(currBank, currByte + c, false);
dumpedBytes++;
}
myFile.write(SDBuffer, 512);
}
}
return(dumpedBytes);
}
So substitute dumpLoROM() and dumpHiROM() into dumpROM() where needed. Here's the calls as I have them right now.
void dumpROM() {
...
long dumpedBytes = 0;
...
if ((romChips != 67)&&(romChips != 69)&&(romChips != 245)&&(romChips != 249)) {
if (romType == 0) {
...
dumpedBytes = dumpLoROM();
...
}
else if (romType == 1) {
...
dumpedBytes = dumpHiROM(0xC0, numBanks + 0xC0, dumpedBytes);
...
}
}
else if((romChips == 67)||(romChips ==69)) {
// SDD1
// Street Fighter Alpha/Zero 2 (J, U, E): romChips = 67
// Star Ocean (J): romChips = 69
...
dumpedBytes = dumpHiROM(0xF0, 0x100, dumpedBytes);
...
}
else if((romChips == 245)||(romChips == 249)){
if (romType == 0) {
// ST018
// Hayazashi Nidan Morita Shougi 2: romChips = 245
dumpedBytes = dumpLoROM();
}
else if (romType == 1) {
// SPC7110
// Momotarou Dentetsu Happy/Super Power League 4: romChips = 245
// Far East of Eden Zero: romChips = 249
...
dumpedBytes = dumpHiROM(0xC0, 0xE0, dumpedBytes);
...
dumpedBytes = dumpHiROM(0xE0, 0xF0, dumpedBytes);
...
dumpedBytes = dumpHiROM(0xF0, 0x100, dumpedBytes);
...
dumpedBytes = dumpHiROM(0xF0, 0x100, dumpedBytes);
...
}
}
}