V23A: Speed up flashing the S29GL256N N64 repro

Writing a 32MB rom should now only take 12 minutes
This commit is contained in:
sanni 2017-05-03 11:54:55 +02:00 committed by GitHub
parent 339e44886e
commit ed5dc3f573
7 changed files with 284 additions and 175 deletions

View File

@ -2,15 +2,15 @@
Cartridge Reader for Arduino Mega2560
Author: sanni
Date: 2017-03-02
Version: V23
Date: 2017-05-03
Version: V23A
SD lib: https://github.com/greiman/SdFat
LCD lib: https://github.com/adafruit/Adafruit_SSD1306
Clockgen: https://github.com/etherkit/Si5351Arduino
RGB Tools lib: https://github.com/joushx/Arduino-RGB-Tools
Compiled with Arduino 1.8.0
Compiled with Arduino 1.8.2
Thanks to:
MichlK - ROM-Reader for Super Nintendo
@ -34,12 +34,11 @@
YamaArashi - GBA flashrom bank switch command
**********************************************************************************/
char ver[5] = "V23";
char ver[5] = "V23A";
/******************************************
Define Output
******************************************/
// If you don't have an OLED screen change
// enable_OLED to 0 and enable_Serial to 1
#define enable_OLED 1
#define enable_Serial 0
@ -320,29 +319,29 @@ static const unsigned char PROGMEM sig [] = {
*****************************************/
// All menus and menu entries are stored in progmem to save on sram
// Main menu
const char modeItem1[] PROGMEM = "Nintendo 64";
const char modeItem2[] PROGMEM = "Super Nintendo";
const char modeItem3[] PROGMEM = "Nintendo Power";
const char modeItem4[] PROGMEM = "Game Boy";
const char modeItem5[] PROGMEM = "Flashrom Programmer";
const char modeItem6[] PROGMEM = "About";
const char* const modeOptions[] PROGMEM = {modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6};
static const char modeItem1[] PROGMEM = "Nintendo 64";
static const char modeItem2[] PROGMEM = "Super Nintendo";
static const char modeItem3[] PROGMEM = "Nintendo Power";
static const char modeItem4[] PROGMEM = "Game Boy";
static const char modeItem5[] PROGMEM = "Flashrom Programmer";
static const char modeItem6[] PROGMEM = "About";
static const char* const modeOptions[] PROGMEM = {modeItem1, modeItem2, modeItem3, modeItem4, modeItem5, modeItem6};
// N64 Submenu
const char n64MenuItem1[] PROGMEM = "Cart Slot";
const char n64MenuItem2[] PROGMEM = "Controller";
const char n64MenuItem3[] PROGMEM = "Flash Repro";
const char* const menuOptionsN64[] PROGMEM = {n64MenuItem1, n64MenuItem2, n64MenuItem3};
static const char n64MenuItem1[] PROGMEM = "Cart Slot";
static const char n64MenuItem2[] PROGMEM = "Controller";
static const char n64MenuItem3[] PROGMEM = "Flash Repro";
static const char* const menuOptionsN64[] PROGMEM = {n64MenuItem1, n64MenuItem2, n64MenuItem3};
// Flash Submenu
const char flashMenuItem1[] PROGMEM = "8bit slot";
const char flashMenuItem2[] PROGMEM = "16bit slot";
const char* const menuOptionsFlash[] PROGMEM = {flashMenuItem1, flashMenuItem2};
static const char flashMenuItem1[] PROGMEM = "8bit slot";
static const char flashMenuItem2[] PROGMEM = "16bit slot";
static const char* const menuOptionsFlash[] PROGMEM = {flashMenuItem1, flashMenuItem2};
// GBx Submenu
const char gbxMenuItem1[] PROGMEM = "Game Boy (Color)";
const char gbxMenuItem2[] PROGMEM = "Game Boy Advance";
const char* const menuOptionsGBx[] PROGMEM = {gbxMenuItem1, gbxMenuItem2};
static const char gbxMenuItem1[] PROGMEM = "Game Boy (Color)";
static const char gbxMenuItem2[] PROGMEM = "Game Boy Advance";
static const char* const menuOptionsGBx[] PROGMEM = {gbxMenuItem1, gbxMenuItem2};
void mainMenu() {
// create menu with title and 6 options to choose from
@ -519,6 +518,9 @@ void setup() {
//PORTD |= (1 << 7);
//PORTG |= (1 << 2);
// Initialize LED
rgb.setColor(0, 0, 0);
// Read current folder number out of eeprom
EEPROM_readAnything(0, foldern);
@ -919,12 +921,9 @@ int checkButton2() {
// Wait for user to push button
void wait_btn() {
// Change led to green
if (errorLvl == 0)
rgbLed(green_color);
else
errorLvl = 0;
while (1)
{
@ -937,12 +936,16 @@ void wait_btn() {
}
// if the cart readers input button is pressed shortly
if (b == 1) {
errorLvl = 0;
break;
}
// if the cart readers input button is pressed long
if (b == 3) {
ignoreError = 1;
if (errorLvl) {
ignoreError = 1;
errorLvl = 0;
}
break;
}
}

View File

@ -16,24 +16,24 @@ unsigned long blank;
Menu
*****************************************/
// 8bit Flash menu items
const char flash8MenuItem1[] PROGMEM = "Blankcheck";
const char flash8MenuItem2[] PROGMEM = "Erase";
const char flash8MenuItem3[] PROGMEM = "Read";
const char flash8MenuItem4[] PROGMEM = "Write";
const char flash8MenuItem5[] PROGMEM = "ID";
const char flash8MenuItem6[] PROGMEM = "Print";
const char flash8MenuItem7[] PROGMEM = "Reset";
const char* const menuOptionsFLASH8[] PROGMEM = {flash8MenuItem1, flash8MenuItem2, flash8MenuItem3, flash8MenuItem4, flash8MenuItem5, flash8MenuItem6, flash8MenuItem7};
static const char flash8MenuItem1[] PROGMEM = "Blankcheck";
static const char flash8MenuItem2[] PROGMEM = "Erase";
static const char flash8MenuItem3[] PROGMEM = "Read";
static const char flash8MenuItem4[] PROGMEM = "Write";
static const char flash8MenuItem5[] PROGMEM = "ID";
static const char flash8MenuItem6[] PROGMEM = "Print";
static const char flash8MenuItem7[] PROGMEM = "Reset";
static const char* const menuOptionsFLASH8[] PROGMEM = {flash8MenuItem1, flash8MenuItem2, flash8MenuItem3, flash8MenuItem4, flash8MenuItem5, flash8MenuItem6, flash8MenuItem7};
// 16bit Flash menu items
const char flash16MenuItem1[] PROGMEM = "Blankcheck";
const char flash16MenuItem2[] PROGMEM = "Erase";
const char flash16MenuItem3[] PROGMEM = "Read";
const char flash16MenuItem4[] PROGMEM = "Write";
const char flash16MenuItem5[] PROGMEM = "ID";
const char flash16MenuItem6[] PROGMEM = "Print";
const char flash16MenuItem7[] PROGMEM = "Reset";
const char* const menuOptionsFLASH16[] PROGMEM = {flash16MenuItem1, flash16MenuItem2, flash16MenuItem3, flash16MenuItem4, flash16MenuItem5, flash16MenuItem6, flash16MenuItem7};
static const char flash16MenuItem1[] PROGMEM = "Blankcheck";
static const char flash16MenuItem2[] PROGMEM = "Erase";
static const char flash16MenuItem3[] PROGMEM = "Read";
static const char flash16MenuItem4[] PROGMEM = "Write";
static const char flash16MenuItem5[] PROGMEM = "ID";
static const char flash16MenuItem6[] PROGMEM = "Print";
static const char flash16MenuItem7[] PROGMEM = "Reset";
static const char* const menuOptionsFLASH16[] PROGMEM = {flash16MenuItem1, flash16MenuItem2, flash16MenuItem3, flash16MenuItem4, flash16MenuItem5, flash16MenuItem6, flash16MenuItem7};
void flashromMenu8() {
// create menu with title and 7 options to choose from

View File

@ -14,12 +14,12 @@ uint16_t sramEndAddress = 0;
Menu
*****************************************/
// GB menu items
const char GBMenuItem1[] PROGMEM = "Read Rom";
const char GBMenuItem2[] PROGMEM = "Read Save";
const char GBMenuItem3[] PROGMEM = "Write Save";
const char GBMenuItem4[] PROGMEM = "Write Flashcart";
const char GBMenuItem5[] PROGMEM = "Reset";
const char* const menuOptionsGB[] PROGMEM = {GBMenuItem1, GBMenuItem2, GBMenuItem3, GBMenuItem4, GBMenuItem5};
static const char GBMenuItem1[] PROGMEM = "Read Rom";
static const char GBMenuItem2[] PROGMEM = "Read Save";
static const char GBMenuItem3[] PROGMEM = "Write Save";
static const char GBMenuItem4[] PROGMEM = "Write Flashcart";
static const char GBMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsGB[] PROGMEM = {GBMenuItem1, GBMenuItem2, GBMenuItem3, GBMenuItem4, GBMenuItem5};
void gbMenu() {
// create menu with title and 5 options to choose from

View File

@ -8,7 +8,7 @@
char calcChecksumStr[5];
boolean readType;
const int nintendoLogo[] PROGMEM = {
static const int nintendoLogo[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x24, 0xFF, 0xAE, 0x51, 0x69, 0x9A, 0xA2, 0x21, 0x3D, 0x84, 0x82, 0x0A,
0x84, 0xE4, 0x09, 0xAD, 0x11, 0x24, 0x8B, 0x98, 0xC0, 0x81, 0x7F, 0x21, 0xA3, 0x52, 0xBE, 0x19,
0x93, 0x09, 0xCE, 0x20, 0x10, 0x46, 0x4A, 0x4A, 0xF8, 0x27, 0x31, 0xEC, 0x58, 0xC7, 0xE8, 0x33,
@ -25,29 +25,29 @@ const int nintendoLogo[] PROGMEM = {
Menu
*****************************************/
// GBA menu items
const char GBAMenuItem1[] PROGMEM = "Read Rom";
const char GBAMenuItem2[] PROGMEM = "Read Save";
const char GBAMenuItem3[] PROGMEM = "Write Save";
const char GBAMenuItem4[] PROGMEM = "Reset";
const char* const menuOptionsGBA[] PROGMEM = {GBAMenuItem1, GBAMenuItem2, GBAMenuItem3, GBAMenuItem4};
static const char GBAMenuItem1[] PROGMEM = "Read Rom";
static const char GBAMenuItem2[] PROGMEM = "Read Save";
static const char GBAMenuItem3[] PROGMEM = "Write Save";
static const char GBAMenuItem4[] PROGMEM = "Reset";
static const char* const menuOptionsGBA[] PROGMEM = {GBAMenuItem1, GBAMenuItem2, GBAMenuItem3, GBAMenuItem4};
// Rom menu
const char GBARomItem1[] PROGMEM = "1MB";
const char GBARomItem2[] PROGMEM = "2MB";
const char GBARomItem3[] PROGMEM = "4MB";
const char GBARomItem4[] PROGMEM = "8MB";
const char GBARomItem5[] PROGMEM = "16MB";
const char GBARomItem6[] PROGMEM = "32MB";
const char* const romOptionsGBA[] PROGMEM = {GBARomItem1, GBARomItem2, GBARomItem3, GBARomItem4, GBARomItem5, GBARomItem6};
static const char GBARomItem1[] PROGMEM = "1MB";
static const char GBARomItem2[] PROGMEM = "2MB";
static const char GBARomItem3[] PROGMEM = "4MB";
static const char GBARomItem4[] PROGMEM = "8MB";
static const char GBARomItem5[] PROGMEM = "16MB";
static const char GBARomItem6[] PROGMEM = "32MB";
static const char* const romOptionsGBA[] PROGMEM = {GBARomItem1, GBARomItem2, GBARomItem3, GBARomItem4, GBARomItem5, GBARomItem6};
// Save menu
const char GBASaveItem1[] PROGMEM = "4K EEPROM";
const char GBASaveItem2[] PROGMEM = "64K EEPROM";
const char GBASaveItem3[] PROGMEM = "256K SRAM/FRAM";
const char GBASaveItem4[] PROGMEM = "512K SRAM/FRAM";
const char GBASaveItem5[] PROGMEM = "512K FLASHROM";
const char GBASaveItem6[] PROGMEM = "1M FLASHROM";
const char* const saveOptionsGBA[] PROGMEM = {GBASaveItem1, GBASaveItem2, GBASaveItem3, GBASaveItem4, GBASaveItem5, GBASaveItem6};
static const char GBASaveItem1[] PROGMEM = "4K EEPROM";
static const char GBASaveItem2[] PROGMEM = "64K EEPROM";
static const char GBASaveItem3[] PROGMEM = "256K SRAM/FRAM";
static const char GBASaveItem4[] PROGMEM = "512K SRAM/FRAM";
static const char GBASaveItem5[] PROGMEM = "512K FLASHROM";
static const char GBASaveItem6[] PROGMEM = "1M FLASHROM";
static const char* const saveOptionsGBA[] PROGMEM = {GBASaveItem1, GBASaveItem2, GBASaveItem3, GBASaveItem4, GBASaveItem5, GBASaveItem6};
void gbaMenu() {
// create menu with title and 4 options to choose from

View File

@ -48,25 +48,25 @@ boolean MN63F81MPN = false;
Menu
*****************************************/
// N64 controller menu items
const char N64ContMenuItem1[] PROGMEM = "Test Controller";
const char N64ContMenuItem2[] PROGMEM = "Read ControllerPak";
const char N64ContMenuItem3[] PROGMEM = "Write ControllerPak";
const char N64ContMenuItem4[] PROGMEM = "Reset";
const char* const menuOptionsN64Controller[] PROGMEM = {N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, N64ContMenuItem4};
static const char N64ContMenuItem1[] PROGMEM = "Test Controller";
static const char N64ContMenuItem2[] PROGMEM = "Read ControllerPak";
static const char N64ContMenuItem3[] PROGMEM = "Write ControllerPak";
static const char N64ContMenuItem4[] PROGMEM = "Reset";
static const char* const menuOptionsN64Controller[] PROGMEM = {N64ContMenuItem1, N64ContMenuItem2, N64ContMenuItem3, N64ContMenuItem4};
// N64 cart menu items
const char N64CartMenuItem1[] PROGMEM = "Read Rom";
const char N64CartMenuItem2[] PROGMEM = "Read Save";
const char N64CartMenuItem3[] PROGMEM = "Write Save";
const char N64CartMenuItem4[] PROGMEM = "Reset";
const char* const menuOptionsN64Cart[] PROGMEM = {N64CartMenuItem1, N64CartMenuItem2, N64CartMenuItem3, N64CartMenuItem4};
static const char N64CartMenuItem1[] PROGMEM = "Read Rom";
static const char N64CartMenuItem2[] PROGMEM = "Read Save";
static const char N64CartMenuItem3[] PROGMEM = "Write Save";
static const char N64CartMenuItem4[] PROGMEM = "Reset";
static const char* const menuOptionsN64Cart[] PROGMEM = {N64CartMenuItem1, N64CartMenuItem2, N64CartMenuItem3, N64CartMenuItem4};
// N64 CRC32 error menu items
const char N64CRCMenuItem1[] PROGMEM = "Recalc CRC";
const char N64CRCMenuItem2[] PROGMEM = "Redump";
const char N64CRCMenuItem3[] PROGMEM = "Ignore";
const char N64CRCMenuItem4[] PROGMEM = "Reset";
const char* const menuOptionsN64CRC[] PROGMEM = {N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, N64CRCMenuItem4};
static const char N64CRCMenuItem1[] PROGMEM = "Recalc CRC";
static const char N64CRCMenuItem2[] PROGMEM = "Redump";
static const char N64CRCMenuItem3[] PROGMEM = "Ignore";
static const char N64CRCMenuItem4[] PROGMEM = "Reset";
static const char* const menuOptionsN64CRC[] PROGMEM = {N64CRCMenuItem1, N64CRCMenuItem2, N64CRCMenuItem3, N64CRCMenuItem4};
// N64 Controller Menu
void n64ControllerMenu() {
@ -972,6 +972,7 @@ void printCartInfo_N64() {
wait();
}
else {
// Display error
println_Msg(F("GAMEPAK ERROR"));
println_Msg("");
print_Msg(F("Name: "));
@ -980,6 +981,9 @@ void printCartInfo_N64() {
println_Msg(cartID);
println_Msg("");
display_Update();
// Set cartSize to 1MB for test dumps
cartSize = 1;
strcpy(romName, "GPERROR");
print_Error(F("Cartridge unknown"), true);
}
}
@ -2078,26 +2082,47 @@ void flashRepro_N64() {
display_Clear();
display_Update();
// Erase flashrom
eraseFlashrom_N64();
if (blankcheckFlashrom_N64()) {
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("File size: "));
print_Msg(fileSize / 1048576);
println_Msg(F("MB"));
display_Update();
// Erase needed sectors
eraseSector_N64();
// Write flashrom
print_Msg(F("Writing "));
println_Msg(filePath);
display_Update();
writeFlashBuffer_N64();
// Close the file:
myFile.close();
// Verify
print_Msg(F("Verifying..."));
display_Update();
writeErrors = verifyFlashrom_N64();
if (writeErrors == 0) {
println_Msg(F("Verified OK"));
println_Msg(F("OK"));
display_Update();
}
else {
print_Msg(F("Error: "));
print_Msg(writeErrors);
println_Msg(F(" bytes "));
print_Msg(F(" bytes "));
print_Error(F("did not verify."), false);
}
}
else {
print_Error(F("Erase failed"), false);
print_Error(F("Can't open file"), false);
}
}
else {
print_Error(F("Unknown flashrom"), false);
@ -2160,6 +2185,45 @@ void idFlashrom_N64() {
}
}
void eraseSector_N64() {
unsigned long flashBase = romBase;
println_Msg(F("Erasing Flashrom"));
display_Update();
for (unsigned long currSector = 0; currSector < fileSize; currSector += 131072) {
// Blink led
PORTB ^= (1 << 4);
// Change to second rom chip
if (currSector == 0x2000000) {
flashBase = romBase + 0x2000000;
}
// Send Erase Command to first flashrom
setAddress_N64(flashBase + (0x555 << 1));
writeWord_N64(0xAA);
setAddress_N64(flashBase + (0x2AA << 1));
writeWord_N64(0x55);
setAddress_N64(flashBase + (0x555 << 1));
writeWord_N64(0x80);
setAddress_N64(flashBase + (0x555 << 1));
writeWord_N64(0xAA);
setAddress_N64(flashBase + (0x2AA << 1));
writeWord_N64(0x55);
setAddress_N64(romBase + currSector);
writeWord_N64(0x30);
// Read the status register
setAddress_N64(romBase + currSector);
word statusReg = readWord_N64();
while ((statusReg | 0xFF7F) != 0xFFFF) {
setAddress_N64(romBase + currSector);
statusReg = readWord_N64();
}
}
}
void eraseFlashrom_N64() {
println_Msg(F("Erasing Flashrom"));
display_Update();
@ -2178,7 +2242,7 @@ void eraseFlashrom_N64() {
setAddress_N64(romBase + (0x555 << 1));
writeWord_N64(0x10);
if (cartSize == 0x4000000) {
if ((cartSize == 0x4000000) && (fileSize > 0x2000000)) {
// Send Erase Command to second flashrom
setAddress_N64(romBase + 0x2000000 + (0x555 << 1));
writeWord_N64(0xAA);
@ -2207,7 +2271,7 @@ void eraseFlashrom_N64() {
statusReg = readWord_N64();
}
if (cartSize == 0x4000000) {
if ((cartSize == 0x4000000) && (fileSize > 0x2000000)) {
// Read the status register
setAddress_N64(romBase + 0x2000000);
word statusReg = readWord_N64();
@ -2224,7 +2288,7 @@ void eraseFlashrom_N64() {
boolean blankcheckFlashrom_N64() {
print_Msg(F("Blankcheck..."));
display_Update();
for (unsigned long currByte = romBase; currByte < romBase + cartSize; currByte += 512) {
for (unsigned long currByte = romBase; currByte < romBase + fileSize; currByte += 512) {
// Blink led
if (currByte % 131072 == 0)
PORTB ^= (1 << 4);
@ -2246,67 +2310,109 @@ boolean blankcheckFlashrom_N64() {
return 1;
}
void writeFlashrom_N64() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName);
// Write flashrom using the faster 16 word write buffer
void writeFlashBuffer_N64() {
unsigned long flashBase = romBase;
// 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();
for (unsigned long currSector = 0; currSector < fileSize; currSector += 131072) {
// Blink led
PORTB ^= (1 << 4);
unsigned long flashBase = romBase;
// Change to second rom chip
if (currSector == 0x2000000) {
flashBase = romBase + 0x2000000;
}
for (unsigned long currSector = 0; currSector < fileSize; currSector += 131072) {
// Blink led
PORTB ^= (1 << 4);
// Write to flashrom
for (unsigned long currSdBuffer = 0; currSdBuffer < 131072; currSdBuffer += 512) {
// Fill SD buffer
myFile.read(sdBuffer, 512);
// Change to second rom
if (currSector == 0x2000000) {
flashBase = romBase + 0x2000000;
}
// Write 16 words at a time
for (int currWriteBuffer = 0; currWriteBuffer < 512; currWriteBuffer += 32) {
// 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) {
// 2 unlock commands
setAddress_N64(flashBase + (0x555 << 1));
writeWord_N64(0xAA);
setAddress_N64(flashBase + (0x2AA << 1));
writeWord_N64(0x55);
// Write buffer load command at sector address
setAddress_N64(romBase + currSector + currSdBuffer + currWriteBuffer);
writeWord_N64(0x25);
// Write word count (minus 1) at sector address
setAddress_N64(romBase + currSector + currSdBuffer + currWriteBuffer);
writeWord_N64(0xF);
// Define variable before loop so we can use it later when reading the status register
word currWord;
for (byte currByte = 0; currByte < 32; 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);
currWord = ( ( sdBuffer[currWriteBuffer + currByte] & 0xFF ) << 8 ) | ( sdBuffer[currWriteBuffer + currByte + 1] & 0xFF );
// 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();
}
// Load Buffer Words
setAddress_N64(romBase + currSector + currSdBuffer + currWriteBuffer + currByte);
writeWord_N64(currWord);
}
// Write Buffer to Flash
setAddress_N64(romBase + currSector + currSdBuffer + currWriteBuffer + 30);
writeWord_N64(0x29);
// Read the status register at last written address
setAddress_N64(romBase + currSector + currSdBuffer + currWriteBuffer + 30);
word statusReg = readWord_N64();
while ((statusReg | 0xFF7F) != (currWord | 0xFF7F)) {
setAddress_N64(romBase + currSector + currSdBuffer + currWriteBuffer + 30);
statusReg = readWord_N64();
}
}
}
// Close the file:
myFile.close();
}
else {
println_Msg(F("Can't open file"));
display_Update();
}
// Write flashrom slowly
void writeFlashrom_N64() {
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();
}
}
}
}
}

View File

@ -33,27 +33,27 @@ boolean hirom[8];
Menu
*****************************************/
// NP menu items
const char NPMenuItem1[] PROGMEM = "Game Menu";
const char NPMenuItem2[] PROGMEM = "Flash Menu";
const char NPMenuItem3[] PROGMEM = "Reset";
const char* const menuOptionsNP[] PROGMEM = {NPMenuItem1, NPMenuItem2, NPMenuItem3};
static const char NPMenuItem1[] PROGMEM = "Game Menu";
static const char NPMenuItem2[] PROGMEM = "Flash Menu";
static const char NPMenuItem3[] PROGMEM = "Reset";
static const char* const menuOptionsNP[] PROGMEM = {NPMenuItem1, NPMenuItem2, NPMenuItem3};
// NP flash menu items
const char NPFlashMenuItem1[] PROGMEM = "Read Flash";
const char NPFlashMenuItem2[] PROGMEM = "Write Flash";
const char NPFlashMenuItem3[] PROGMEM = "Print Mapping";
const char NPFlashMenuItem4[] PROGMEM = "Read Mapping";
const char NPFlashMenuItem5[] PROGMEM = "Write Mapping";
const char NPFlashMenuItem6[] PROGMEM = "Back";
const char* const menuOptionsNPFlash[] PROGMEM = {NPFlashMenuItem1, NPFlashMenuItem2, NPFlashMenuItem3, NPFlashMenuItem4, NPFlashMenuItem5, NPFlashMenuItem6};
static const char NPFlashMenuItem1[] PROGMEM = "Read Flash";
static const char NPFlashMenuItem2[] PROGMEM = "Write Flash";
static const char NPFlashMenuItem3[] PROGMEM = "Print Mapping";
static const char NPFlashMenuItem4[] PROGMEM = "Read Mapping";
static const char NPFlashMenuItem5[] PROGMEM = "Write Mapping";
static const char NPFlashMenuItem6[] PROGMEM = "Back";
static const char* const menuOptionsNPFlash[] PROGMEM = {NPFlashMenuItem1, NPFlashMenuItem2, NPFlashMenuItem3, NPFlashMenuItem4, NPFlashMenuItem5, NPFlashMenuItem6};
// NP game menu items
const char NPGameMenuItem1[] PROGMEM = "Read Sram";
const char NPGameMenuItem2[] PROGMEM = "Read Game";
const char NPGameMenuItem3[] PROGMEM = "Write Sram";
const char NPGameMenuItem4[] PROGMEM = "Switch Game";
const char NPGameMenuItem5[] PROGMEM = "Reset";
const char* const menuOptionsNPGame[] PROGMEM = {NPGameMenuItem1, NPGameMenuItem2, NPGameMenuItem3, NPGameMenuItem4, NPGameMenuItem5};
static const char NPGameMenuItem1[] PROGMEM = "Read Sram";
static const char NPGameMenuItem2[] PROGMEM = "Read Game";
static const char NPGameMenuItem3[] PROGMEM = "Write Sram";
static const char NPGameMenuItem4[] PROGMEM = "Switch Game";
static const char NPGameMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsNPGame[] PROGMEM = {NPGameMenuItem1, NPGameMenuItem2, NPGameMenuItem3, NPGameMenuItem4, NPGameMenuItem5};
void npMenu() {
// create menu with title and 3 options to choose from

View File

@ -26,21 +26,21 @@ boolean NP = false;
Menu
*****************************************/
// SNES menu items
const char SnesMenuItem1[] PROGMEM = "Read Rom";
const char SnesMenuItem2[] PROGMEM = "Read Save";
const char SnesMenuItem3[] PROGMEM = "Write Save";
const char SnesMenuItem4[] PROGMEM = "Test SRAM";
const char SnesMenuItem5[] PROGMEM = "Cycle cart";
const char SnesMenuItem6[] PROGMEM = "Reset";
const char* const menuOptionsSNES[] PROGMEM = {SnesMenuItem1, SnesMenuItem2, SnesMenuItem3, SnesMenuItem4, SnesMenuItem5, SnesMenuItem6};
static const char SnesMenuItem1[] PROGMEM = "Read Rom";
static const char SnesMenuItem2[] PROGMEM = "Read Save";
static const char SnesMenuItem3[] PROGMEM = "Write Save";
static const char SnesMenuItem4[] PROGMEM = "Test SRAM";
static const char SnesMenuItem5[] PROGMEM = "Cycle cart";
static const char SnesMenuItem6[] PROGMEM = "Reset";
static const char* const menuOptionsSNES[] PROGMEM = {SnesMenuItem1, SnesMenuItem2, SnesMenuItem3, SnesMenuItem4, SnesMenuItem5, SnesMenuItem6};
// Manual config menu items
const char confMenuItem1[] PROGMEM = "Use header info";
const char confMenuItem2[] PROGMEM = "4MB LoRom 256K Sram";
const char confMenuItem3[] PROGMEM = "4MB HiRom 64K Sram";
const char confMenuItem4[] PROGMEM = "6MB ExRom 256K Sram";
const char confMenuItem5[] PROGMEM = "Reset";
const char* const menuOptionsConf[] PROGMEM = {confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, confMenuItem5};
static const char confMenuItem1[] PROGMEM = "Use header info";
static const char confMenuItem2[] PROGMEM = "4MB LoRom 256K Sram";
static const char confMenuItem3[] PROGMEM = "4MB HiRom 64K Sram";
static const char confMenuItem4[] PROGMEM = "6MB ExRom 256K Sram";
static const char confMenuItem5[] PROGMEM = "Reset";
static const char* const menuOptionsConf[] PROGMEM = {confMenuItem1, confMenuItem2, confMenuItem3, confMenuItem4, confMenuItem5};
// SNES Menu
void snesMenu() {