mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-18 00:51:49 +01:00
V23A: Speed up flashing the S29GL256N N64 repro
Writing a 32MB rom should now only take 12 minutes
This commit is contained in:
parent
339e44886e
commit
ed5dc3f573
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user