mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-26 04:51:52 +01:00
V23 Add writing of N64 repro (first draft, super slow)
Takes ~1 hour or so for a 64MB rom file since I have not yet implemented the roms 16 word write buffer and instead write only one word at a time. This is the repro I used: https://www.aliexpress.com/item/N64-Game-Resident-Evil-2-Nintendo-Video-Game-Cartridge-Console-Card-English-Language-US-Version/32788522464.html
This commit is contained in:
parent
4adb7c7506
commit
67a83ccab2
@ -2,8 +2,8 @@
|
|||||||
Cartridge Reader for Arduino Mega2560
|
Cartridge Reader for Arduino Mega2560
|
||||||
|
|
||||||
Author: sanni
|
Author: sanni
|
||||||
Date: 2017-02-25
|
Date: 2017-03-02
|
||||||
Version: V22B
|
Version: V23
|
||||||
|
|
||||||
SD lib: https://github.com/greiman/SdFat
|
SD lib: https://github.com/greiman/SdFat
|
||||||
LCD lib: https://github.com/adafruit/Adafruit_SSD1306
|
LCD lib: https://github.com/adafruit/Adafruit_SSD1306
|
||||||
@ -34,7 +34,7 @@
|
|||||||
YamaArashi - GBA flashrom bank switch command
|
YamaArashi - GBA flashrom bank switch command
|
||||||
|
|
||||||
**********************************************************************************/
|
**********************************************************************************/
|
||||||
char ver[5] = "V22B";
|
char ver[5] = "V23";
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
Define Output
|
Define Output
|
||||||
@ -166,6 +166,7 @@ int incomingByte;
|
|||||||
int choice = 0;
|
int choice = 0;
|
||||||
// Temporary array that holds the menu option read out of progmem
|
// Temporary array that holds the menu option read out of progmem
|
||||||
char menuOptions[7][20];
|
char menuOptions[7][20];
|
||||||
|
boolean ignoreError;
|
||||||
|
|
||||||
// File browser
|
// File browser
|
||||||
char fileName[26];
|
char fileName[26];
|
||||||
@ -330,7 +331,8 @@ const char* const modeOptions[] PROGMEM = {modeItem1, modeItem2, modeItem3, mode
|
|||||||
// N64 Submenu
|
// N64 Submenu
|
||||||
const char n64MenuItem1[] PROGMEM = "Cart Slot";
|
const char n64MenuItem1[] PROGMEM = "Cart Slot";
|
||||||
const char n64MenuItem2[] PROGMEM = "Controller";
|
const char n64MenuItem2[] PROGMEM = "Controller";
|
||||||
const char* const menuOptionsN64[] PROGMEM = {n64MenuItem1, n64MenuItem2};
|
const char n64MenuItem3[] PROGMEM = "Flash Repro";
|
||||||
|
const char* const menuOptionsN64[] PROGMEM = {n64MenuItem1, n64MenuItem2, n64MenuItem3};
|
||||||
|
|
||||||
// Flash Submenu
|
// Flash Submenu
|
||||||
const char flashMenuItem1[] PROGMEM = "8bit slot";
|
const char flashMenuItem1[] PROGMEM = "8bit slot";
|
||||||
@ -356,8 +358,8 @@ void mainMenu() {
|
|||||||
// create menu with title and 2 options to choose from
|
// create menu with title and 2 options to choose from
|
||||||
unsigned char n64Dev;
|
unsigned char n64Dev;
|
||||||
// Copy menuOptions out of progmem
|
// Copy menuOptions out of progmem
|
||||||
convertPgm(menuOptionsN64, 2);
|
convertPgm(menuOptionsN64, 3);
|
||||||
n64Dev = question_box("Select N64 device", menuOptions, 2, 0);
|
n64Dev = question_box("Select N64 device", menuOptions, 3, 0);
|
||||||
|
|
||||||
// wait for user choice to come back from the question box menu
|
// wait for user choice to come back from the question box menu
|
||||||
switch (n64Dev)
|
switch (n64Dev)
|
||||||
@ -366,6 +368,7 @@ void mainMenu() {
|
|||||||
display_Clear();
|
display_Clear();
|
||||||
display_Update();
|
display_Update();
|
||||||
setup_N64_Cart();
|
setup_N64_Cart();
|
||||||
|
printCartInfo_N64();
|
||||||
mode = mode_N64_Cart;
|
mode = mode_N64_Cart;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -375,6 +378,16 @@ void mainMenu() {
|
|||||||
setup_N64_Controller();
|
setup_N64_Controller();
|
||||||
mode = mode_N64_Controller;
|
mode = mode_N64_Controller;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
display_Clear();
|
||||||
|
display_Update();
|
||||||
|
setup_N64_Cart();
|
||||||
|
flashRepro_N64();
|
||||||
|
printCartInfo_N64();
|
||||||
|
mode = mode_N64_Cart;
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -592,8 +605,20 @@ void print_Error(const __FlashStringHelper *errorMessage, boolean forceReset) {
|
|||||||
println_Msg(F("Press Button..."));
|
println_Msg(F("Press Button..."));
|
||||||
display_Update();
|
display_Update();
|
||||||
wait();
|
wait();
|
||||||
|
if (ignoreError == 0) {
|
||||||
asm volatile (" jmp 0");
|
asm volatile (" jmp 0");
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ignoreError = 0;
|
||||||
|
display_Clear();
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F(""));
|
||||||
|
println_Msg(F(" Error Overwrite"));
|
||||||
|
display_Update();
|
||||||
|
delay(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait() {
|
void wait() {
|
||||||
@ -917,6 +942,7 @@ void wait_btn() {
|
|||||||
|
|
||||||
// if the cart readers input button is pressed long
|
// if the cart readers input button is pressed long
|
||||||
if (b == 3) {
|
if (b == 3) {
|
||||||
|
ignoreError = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ String lastbutton = "N/A";
|
|||||||
// Rom base address
|
// Rom base address
|
||||||
unsigned long romBase = 0x10000000;
|
unsigned long romBase = 0x10000000;
|
||||||
unsigned long sramBase = 0x08000000;
|
unsigned long sramBase = 0x08000000;
|
||||||
|
unsigned long fileSize;
|
||||||
|
|
||||||
// Flashram type
|
// Flashram type
|
||||||
byte flashramType = 1;
|
byte flashramType = 1;
|
||||||
@ -287,59 +288,6 @@ void setup_N64_Cart() {
|
|||||||
// Pull RESET(PH0) high
|
// Pull RESET(PH0) high
|
||||||
//PORTH |= (1 << 0);
|
//PORTH |= (1 << 0);
|
||||||
//delay(10);
|
//delay(10);
|
||||||
|
|
||||||
// Print start page
|
|
||||||
getCartInfo_N64();
|
|
||||||
if (cartSize != 0) {
|
|
||||||
println_Msg(F("N64 Cartridge Info"));
|
|
||||||
println_Msg(F(""));
|
|
||||||
print_Msg(F("Name: "));
|
|
||||||
println_Msg(romName);
|
|
||||||
print_Msg(F("ID: "));
|
|
||||||
print_Msg(cartID);
|
|
||||||
print_Msg(F(" Size: "));
|
|
||||||
print_Msg(cartSize);
|
|
||||||
println_Msg(F("MB"));
|
|
||||||
print_Msg(F("Save: "));
|
|
||||||
switch (saveType) {
|
|
||||||
case 1:
|
|
||||||
println_Msg(F("Sram"));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
println_Msg(F("Flashram"));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
println_Msg(F("4K Eeprom"));
|
|
||||||
eepPages = 64;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
println_Msg(F("16K Eeprom"));
|
|
||||||
eepPages = 256;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
println_Msg(F("unknown"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
print_Msg(F("Version: 1."));
|
|
||||||
println_Msg(romVersion);
|
|
||||||
|
|
||||||
// Wait for user input
|
|
||||||
println_Msg(F(" "));
|
|
||||||
println_Msg(F("Press Button..."));
|
|
||||||
display_Update();
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
println_Msg(F("GAMEPAK ERROR"));
|
|
||||||
println_Msg("");
|
|
||||||
print_Msg(F("Name: "));
|
|
||||||
println_Msg(romName);
|
|
||||||
print_Msg(F("ID: "));
|
|
||||||
println_Msg(cartID);
|
|
||||||
println_Msg("");
|
|
||||||
display_Update();
|
|
||||||
print_Error(F("Cartridge unknown"), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************
|
/******************************************
|
||||||
@ -979,6 +927,63 @@ void verifyMPK() {
|
|||||||
/******************************************
|
/******************************************
|
||||||
N64 Cartridge functions
|
N64 Cartridge functions
|
||||||
*****************************************/
|
*****************************************/
|
||||||
|
void printCartInfo_N64() {
|
||||||
|
// Check cart
|
||||||
|
getCartInfo_N64();
|
||||||
|
|
||||||
|
// Print start page
|
||||||
|
if (cartSize != 0) {
|
||||||
|
println_Msg(F("N64 Cartridge Info"));
|
||||||
|
println_Msg(F(""));
|
||||||
|
print_Msg(F("Name: "));
|
||||||
|
println_Msg(romName);
|
||||||
|
print_Msg(F("ID: "));
|
||||||
|
print_Msg(cartID);
|
||||||
|
print_Msg(F(" Size: "));
|
||||||
|
print_Msg(cartSize);
|
||||||
|
println_Msg(F("MB"));
|
||||||
|
print_Msg(F("Save: "));
|
||||||
|
switch (saveType) {
|
||||||
|
case 1:
|
||||||
|
println_Msg(F("Sram"));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
println_Msg(F("Flashram"));
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
println_Msg(F("4K Eeprom"));
|
||||||
|
eepPages = 64;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
println_Msg(F("16K Eeprom"));
|
||||||
|
eepPages = 256;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
println_Msg(F("unknown"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
print_Msg(F("Version: 1."));
|
||||||
|
println_Msg(romVersion);
|
||||||
|
|
||||||
|
// Wait for user input
|
||||||
|
println_Msg(F(" "));
|
||||||
|
println_Msg(F("Press Button..."));
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println_Msg(F("GAMEPAK ERROR"));
|
||||||
|
println_Msg("");
|
||||||
|
print_Msg(F("Name: "));
|
||||||
|
println_Msg(romName);
|
||||||
|
print_Msg(F("ID: "));
|
||||||
|
println_Msg(cartID);
|
||||||
|
println_Msg("");
|
||||||
|
display_Update();
|
||||||
|
print_Error(F("Cartridge unknown"), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CRC32 lookup table
|
// CRC32 lookup table
|
||||||
static const uint32_t crc_32_tab[] PROGMEM = { /* CRC polynomial 0xedb88320 */
|
static const uint32_t crc_32_tab[] PROGMEM = { /* CRC polynomial 0xedb88320 */
|
||||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||||
@ -2044,6 +2049,301 @@ calcn64crc:
|
|||||||
display_Update();
|
display_Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************
|
||||||
|
N64 Repro Flashrom Functions
|
||||||
|
*****************************************/
|
||||||
|
void flashRepro_N64() {
|
||||||
|
// Check flashrom ID's
|
||||||
|
idFlashrom_N64();
|
||||||
|
if (cartSize != 0) {
|
||||||
|
print_Msg("ID: ");
|
||||||
|
print_Msg(flashid);
|
||||||
|
print_Msg(" Size: ");
|
||||||
|
print_Msg(cartSize / 1048576);
|
||||||
|
println_Msg("MB");
|
||||||
|
println_Msg("");
|
||||||
|
println_Msg(F("This will erase your"));
|
||||||
|
println_Msg(F("Repro Cartridge."));
|
||||||
|
println_Msg(F("Attention: Use 3.3V!"));
|
||||||
|
println_Msg("");
|
||||||
|
println_Msg(F("Press Button"));
|
||||||
|
println_Msg(F("to continue"));
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
|
||||||
|
// Launch file browser
|
||||||
|
filePath[0] = '\0';
|
||||||
|
sd.chdir("/");
|
||||||
|
fileBrowser("Select z64 file");
|
||||||
|
display_Clear();
|
||||||
|
display_Update();
|
||||||
|
|
||||||
|
// Erase flashrom
|
||||||
|
eraseFlashrom_N64();
|
||||||
|
if (blankcheckFlashrom_N64()) {
|
||||||
|
writeFlashrom_N64();
|
||||||
|
writeErrors = verifyFlashrom_N64();
|
||||||
|
if (writeErrors == 0) {
|
||||||
|
println_Msg(F("Verified OK"));
|
||||||
|
display_Update();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_Msg(F("Error: "));
|
||||||
|
print_Msg(writeErrors);
|
||||||
|
println_Msg(F(" bytes "));
|
||||||
|
print_Error(F("did not verify."), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_Error(F("Erase failed"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print_Error(F("Unknown flashrom"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
println_Msg(F("Press Button..."));
|
||||||
|
display_Update();
|
||||||
|
wait();
|
||||||
|
display_Clear();
|
||||||
|
display_Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetFlashrom_N64(unsigned long flashBase) {
|
||||||
|
// Send reset Command
|
||||||
|
setAddress_N64(flashBase);
|
||||||
|
writeWord_N64(0xF0);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void idFlashrom_N64() {
|
||||||
|
// Size of repro cartridge
|
||||||
|
cartSize = 0;
|
||||||
|
|
||||||
|
// Send ID command to first flashrom
|
||||||
|
setAddress_N64(romBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0xAA);
|
||||||
|
setAddress_N64(romBase + (0x2AA << 1));
|
||||||
|
writeWord_N64(0x55);
|
||||||
|
setAddress_N64(romBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0x90);
|
||||||
|
|
||||||
|
// Read manufacturer ID
|
||||||
|
setAddress_N64(romBase);
|
||||||
|
readWord_N64();
|
||||||
|
// Read flashrom ID
|
||||||
|
sprintf(flashid, "%04X", readWord_N64());
|
||||||
|
|
||||||
|
resetFlashrom_N64(romBase);
|
||||||
|
|
||||||
|
if (strcmp(flashid, "227E") == 0) {
|
||||||
|
cartSize = 0x2000000;
|
||||||
|
|
||||||
|
// Send ID command to second flashrom
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||||
|
writeWord_N64(0xAA);
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x2AA << 1));
|
||||||
|
writeWord_N64(0x55);
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||||
|
writeWord_N64(0x90);
|
||||||
|
|
||||||
|
// Read manufacturer ID
|
||||||
|
setAddress_N64(romBase + 0x2000000);
|
||||||
|
readWord_N64();
|
||||||
|
// Read flashrom ID
|
||||||
|
sprintf(flashid, "%04X", readWord_N64());
|
||||||
|
if (strcmp(flashid, "227E") == 0) {
|
||||||
|
cartSize = 0x4000000;
|
||||||
|
}
|
||||||
|
resetFlashrom_N64(romBase + 0x2000000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eraseFlashrom_N64() {
|
||||||
|
println_Msg(F("Erasing Flashrom"));
|
||||||
|
display_Update();
|
||||||
|
|
||||||
|
// Send Erase Command to first flashrom
|
||||||
|
setAddress_N64(romBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0xAA);
|
||||||
|
setAddress_N64(romBase + (0x2AA << 1));
|
||||||
|
writeWord_N64(0x55);
|
||||||
|
setAddress_N64(romBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0x80);
|
||||||
|
setAddress_N64(romBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0xAA);
|
||||||
|
setAddress_N64(romBase + (0x2AA << 1));
|
||||||
|
writeWord_N64(0x55);
|
||||||
|
setAddress_N64(romBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0x10);
|
||||||
|
|
||||||
|
if (cartSize == 0x4000000) {
|
||||||
|
// Send Erase Command to second flashrom
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||||
|
writeWord_N64(0xAA);
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x2AA << 1));
|
||||||
|
writeWord_N64(0x55);
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||||
|
writeWord_N64(0x80);
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||||
|
writeWord_N64(0xAA);
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x2AA << 1));
|
||||||
|
writeWord_N64(0x55);
|
||||||
|
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
|
||||||
|
writeWord_N64(0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
// Read the status register
|
||||||
|
setAddress_N64(romBase);
|
||||||
|
word statusReg = readWord_N64();
|
||||||
|
while ((statusReg | 0xFF7F) != 0xFFFF) {
|
||||||
|
// Blink led
|
||||||
|
PORTB ^= (1 << 4);
|
||||||
|
delay(1000);
|
||||||
|
setAddress_N64(romBase);
|
||||||
|
statusReg = readWord_N64();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cartSize == 0x4000000) {
|
||||||
|
// Read the status register
|
||||||
|
setAddress_N64(romBase + 0x2000000);
|
||||||
|
word statusReg = readWord_N64();
|
||||||
|
while ((statusReg | 0xFF7F) != 0xFFFF) {
|
||||||
|
// Blink led
|
||||||
|
PORTB ^= (1 << 4);
|
||||||
|
delay(1000);
|
||||||
|
setAddress_N64(romBase + 0x2000000);
|
||||||
|
statusReg = readWord_N64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean blankcheckFlashrom_N64() {
|
||||||
|
print_Msg(F("Blankcheck..."));
|
||||||
|
display_Update();
|
||||||
|
for (unsigned long currByte = romBase; currByte < romBase + cartSize; currByte += 512) {
|
||||||
|
// Blink led
|
||||||
|
if (currByte % 131072 == 0)
|
||||||
|
PORTB ^= (1 << 4);
|
||||||
|
|
||||||
|
// Set the address for the next 512 bytes
|
||||||
|
setAddress_N64(currByte);
|
||||||
|
|
||||||
|
for (int c = 0; c < 512; c += 2) {
|
||||||
|
if (readWord_N64() != 0xFFFF) {
|
||||||
|
println_Msg(F("failed"));
|
||||||
|
display_Update();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
println_Msg(F("OK"));
|
||||||
|
display_Update();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeFlashrom_N64() {
|
||||||
|
// Create filepath
|
||||||
|
sprintf(filePath, "%s/%s", filePath, fileName);
|
||||||
|
|
||||||
|
// Open file on sd card
|
||||||
|
if (myFile.open(filePath, O_READ)) {
|
||||||
|
// Get rom size from file
|
||||||
|
fileSize = myFile.fileSize();
|
||||||
|
print_Msg(F("Writing "));
|
||||||
|
println_Msg(filePath);
|
||||||
|
print_Msg(F("File size: "));
|
||||||
|
print_Msg(fileSize / 1048576);
|
||||||
|
println_Msg(F("MB"));
|
||||||
|
display_Update();
|
||||||
|
|
||||||
|
unsigned long flashBase = romBase;
|
||||||
|
|
||||||
|
for (unsigned long currSector = 0; currSector < fileSize; currSector += 131072) {
|
||||||
|
// Blink led
|
||||||
|
PORTB ^= (1 << 4);
|
||||||
|
|
||||||
|
// Change to second rom
|
||||||
|
if (currSector == 0x2000000) {
|
||||||
|
flashBase = romBase + 0x2000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to flashrom
|
||||||
|
for (unsigned long currSdBuffer = 0; currSdBuffer < 131072; currSdBuffer += 512) {
|
||||||
|
// Fill SD buffer
|
||||||
|
myFile.read(sdBuffer, 512);
|
||||||
|
for (int currByte = 0; currByte < 512; currByte += 2) {
|
||||||
|
// Join two bytes into one word
|
||||||
|
word currWord = ( ( sdBuffer[currByte] & 0xFF ) << 8 ) | ( sdBuffer[currByte + 1] & 0xFF );
|
||||||
|
// 2 unlock commands
|
||||||
|
setAddress_N64(flashBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0xAA);
|
||||||
|
setAddress_N64(flashBase + (0x2AA << 1));
|
||||||
|
writeWord_N64(0x55);
|
||||||
|
// Program command
|
||||||
|
setAddress_N64(flashBase + (0x555 << 1));
|
||||||
|
writeWord_N64(0xA0);
|
||||||
|
// Write word
|
||||||
|
setAddress_N64(romBase + currSector + currSdBuffer + currByte);
|
||||||
|
writeWord_N64(currWord);
|
||||||
|
|
||||||
|
// Read the status register
|
||||||
|
setAddress_N64(romBase + currSector + currSdBuffer + currByte);
|
||||||
|
word statusReg = readWord_N64();
|
||||||
|
while ((statusReg | 0xFF7F) != (currWord | 0xFF7F)) {
|
||||||
|
setAddress_N64(romBase + currSector + currSdBuffer + currByte);
|
||||||
|
statusReg = readWord_N64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Close the file:
|
||||||
|
myFile.close();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println_Msg(F("Can't open file"));
|
||||||
|
display_Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long verifyFlashrom_N64() {
|
||||||
|
// Open file on sd card
|
||||||
|
if (myFile.open(filePath, O_READ)) {
|
||||||
|
writeErrors = 0;
|
||||||
|
|
||||||
|
for (unsigned long currSector = 0; currSector < fileSize; currSector += 131072) {
|
||||||
|
// Blink led
|
||||||
|
PORTB ^= (1 << 4);
|
||||||
|
for (unsigned long currSdBuffer = 0; currSdBuffer < 131072; currSdBuffer += 512) {
|
||||||
|
// Fill SD buffer
|
||||||
|
myFile.read(sdBuffer, 512);
|
||||||
|
for (int currByte = 0; currByte < 512; currByte += 2) {
|
||||||
|
// Join two bytes into one word
|
||||||
|
word currWord = ( ( sdBuffer[currByte] & 0xFF ) << 8 ) | ( sdBuffer[currByte + 1] & 0xFF );
|
||||||
|
// Read flash
|
||||||
|
setAddress_N64(romBase + currSector + currSdBuffer + currByte);
|
||||||
|
// Compare both
|
||||||
|
if (readWord_N64() != currWord) {
|
||||||
|
writeErrors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Close the file:
|
||||||
|
myFile.close();
|
||||||
|
return writeErrors;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println_Msg(F("Can't open file"));
|
||||||
|
display_Update();
|
||||||
|
return 9999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//******************************************
|
//******************************************
|
||||||
// End of File
|
// End of File
|
||||||
//******************************************
|
//******************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user