From 05c1965a9aa336661c33f317cf0609f956585c77 Mon Sep 17 00:00:00 2001 From: sanni Date: Thu, 12 Jan 2017 00:47:38 +0100 Subject: [PATCH] Reset SA-1 cart after SRAM write --- Cart_Reader/Cart_Reader.ino | 10 +- Cart_Reader/FLASH.ino | 4 +- Cart_Reader/GB.ino | 262 +++++++++++++++++++++++++++++++++++- Cart_Reader/N64.ino | 6 +- Cart_Reader/NP.ino | 6 +- Cart_Reader/SNES.ino | 33 ++++- 6 files changed, 300 insertions(+), 21 deletions(-) diff --git a/Cart_Reader/Cart_Reader.ino b/Cart_Reader/Cart_Reader.ino index a2fcd64..6c720bf 100644 --- a/Cart_Reader/Cart_Reader.ino +++ b/Cart_Reader/Cart_Reader.ino @@ -2,8 +2,8 @@ Cartridge Reader for Arduino Mega2560 Author: sanni - Date: 2016-10-15 - Version: V19J + Date: 2017-01-12 + Version: V19L SD lib: https://github.com/greiman/SdFat LCD lib: https://github.com/adafruit/Adafruit_SSD1306 @@ -34,7 +34,7 @@ YamaArashi - GBA flashrom bank switch command **********************************************************************************/ -char ver[5] = "V19J"; +char ver[5] = "V19L"; /****************************************** Define Output @@ -449,7 +449,7 @@ void mainMenu() { display.drawBitmap(0, 0, sig, 128, 64, 1); println_Msg(F("Cartridge Reader")); println_Msg(F("github.com/sanni")); - print_Msg(F("2016 ")); + print_Msg(F("2017 ")); println_Msg(ver); println_Msg(F("")); println_Msg(F("")); @@ -529,7 +529,7 @@ void setup() { // Serial Begin Serial.begin(9600); Serial.println(F("Cartridge Reader")); - Serial.println(F("2016 sanni")); + Serial.println(F("2017 sanni")); Serial.println(""); // Print available RAM diff --git a/Cart_Reader/FLASH.ino b/Cart_Reader/FLASH.ino index 0d29f83..e732549 100644 --- a/Cart_Reader/FLASH.ino +++ b/Cart_Reader/FLASH.ino @@ -38,7 +38,7 @@ const char* const menuOptionsFLASH16[] PROGMEM = {flash16MenuItem1, flash16MenuI void flashromMenu8() { // create menu with title and 7 options to choose from unsigned char mainMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsFLASH8, 7); mainMenu = question_box("Flashrom Writer 8", menuOptions, 7, 0); @@ -168,7 +168,7 @@ void flashromMenu8() { void flashromMenu16() { // create menu with title "Flashrom Writer 16" and 7 options to choose from unsigned char mainMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsFLASH16, 7); mainMenu = question_box("Flashrom Writer 16", menuOptions, 7, 0); diff --git a/Cart_Reader/GB.ino b/Cart_Reader/GB.ino index ab291f8..30a5f89 100644 --- a/Cart_Reader/GB.ino +++ b/Cart_Reader/GB.ino @@ -15,18 +15,19 @@ int sramBanks; const char GBMenuItem1[] PROGMEM = "Read Rom"; const char GBMenuItem2[] PROGMEM = "Read Save"; const char GBMenuItem3[] PROGMEM = "Write Save"; -const char GBMenuItem4[] PROGMEM = "Reset"; -const char* const menuOptionsGB[] PROGMEM = {GBMenuItem1, GBMenuItem2, GBMenuItem3, GBMenuItem4}; +const char GBMenuItem4[] PROGMEM = "Write Flash"; +const char GBMenuItem5[] PROGMEM = "Reset"; +const char* const menuOptionsGB[] PROGMEM = {GBMenuItem1, GBMenuItem2, GBMenuItem3, GBMenuItem4, GBMenuItem5}; void gbMenu() { // Output a high signal on CS(PH3) WR(PH5) RD(PH6) PORTH |= (1 << 3) | (1 << 5) | (1 << 6); - // create menu with title and 4 options to choose from + // create menu with title and 5 options to choose from unsigned char mainMenu; - // Copy menuOptions of of progmem - convertPgm(menuOptionsGB, 4); - mainMenu = question_box("GB Cart Reader", menuOptions, 4, 0); + // Copy menuOptions out of progmem + convertPgm(menuOptionsGB, 5); + mainMenu = question_box("GB Cart Reader", menuOptions, 5, 0); // wait for user choice to come back from the question box menu switch (mainMenu) @@ -66,6 +67,12 @@ void gbMenu() { break; case 3: + // Change working dir to root + sd.chdir("/"); + writeFlash_GB(); + break; + + case 4: asm volatile (" jmp 0"); break; } @@ -683,6 +690,249 @@ unsigned long verifySRAM_GB() { } } +/* Switch rom bank + void switchRomBank(word romBank) { + writeByte_GB(0x3000, romBank >> 8); + writeByte_GB(0x2000, romBank & 0xFFu); + }*/ + +// Write 29F032 flashrom +// A0-A13 directly connected to cart edge -> 16384(0x0-0x3FFF) bytes per bank -> 256(0x0-0xFF) banks +// A14-A21 connected to MBC5 +void writeFlash_GB() { + // Launch filebrowser + filePath[0] = '\0'; + sd.chdir("/"); + fileBrowser("Select file"); + display_Clear(); + + // Create filepath + sprintf(filePath, "%s/%s", filePath, fileName); + + // Open file on sd card + if (myFile.open(filePath, O_READ)) { + // Get rom size from file + myFile.seekCur(0x147); + romType = myFile.read(); + romSize = myFile.read(); + // Go back to file beginning + myFile.seekCur(0); + + numBanks = 2; // Default 32K + if (romSize == 1) { + numBanks = 4; + } + if (romSize == 2) { + numBanks = 8; + } + if (romSize == 3) { + numBanks = 16; + } + if (romSize == 4) { + numBanks = 32; + } + if (romSize == 5 && (romType == 1 || romType == 2 || romType == 3)) { + numBanks = 63; + } + else if (romSize == 5) { + numBanks = 64; + } + if (romSize == 6 && (romType == 1 || romType == 2 || romType == 3)) { + numBanks = 125; + } + else if (romSize == 6) { + numBanks = 128; + } + if (romSize == 7) { + numBanks = 255; + } + if (romSize == 82) { + numBanks = 72; + } + if (romSize == 83) { + numBanks = 80; + } + if (romSize == 84) { + numBanks = 96; + } + + // Set data pins to output + dataOut(); + + // Set ROM bank 1 + writeByte_GB(0x2100, 1); + delay(100); + + // Reset flash + writeByte_GB(0x555, 0xf0); + delay(100); + + // ID command sequence + writeByte_GB(0x555, 0xaa); + writeByte_GB(0x2aa, 0x55); + writeByte_GB(0x555, 0x90); + + dataIn(); + + // Read the two id bytes into a string + sprintf(flashid, "%02X%02X", readByte_GB(0), readByte_GB(1)); + + if (strcmp(flashid, "04D4") == 0) { + println_Msg(F("MBM29F033C")); + print_Msg(F("Banks: ")); + print_Msg(numBanks); + println_Msg(F("/256")); + display_Update(); + } + else if (strcmp(flashid, "0141") == 0) { + println_Msg(F("AM29F032B")); + print_Msg(F("Banks: ")); + print_Msg(numBanks); + println_Msg(F("/256")); + display_Update(); + } + else if (strcmp(flashid, "01AD") == 0) { + println_Msg(F("AM29F016B")); + print_Msg(F("Banks: ")); + print_Msg(numBanks); + println_Msg(F("/128")); + display_Update(); + } + else { + print_Msg(F("Flash ID: ")); + println_Msg(flashid); + display_Update(); + print_Error(F("Unknown flashrom"), true); + } + dataOut(); + + // Reset flash + writeByte_GB(0x555, 0xf0); + + delay(100); + println_Msg(F("Erasing flash")); + display_Update(); + + // Erase flash + writeByte_GB(0x555, 0xaa); + writeByte_GB(0x2aa, 0x55); + writeByte_GB(0x555, 0x80); + writeByte_GB(0x555, 0xaa); + writeByte_GB(0x2aa, 0x55); + writeByte_GB(0x555, 0x10); + + dataIn(); + + // Read the status register + byte statusReg = readByte_GB(0); + + // After a completed erase D7 will output 1 + while ((statusReg & 0x80) != 0x80) { + // Blink led + PORTB ^= (1 << 4); + delay(100); + // Update Status + statusReg = readByte_GB(0); + } + + // Blankcheck + println_Msg(F("Blankcheck")); + display_Update(); + + unsigned int addr = 0; + + // Read x number of banks + for (int y = 1; y < numBanks; y++) { + // Blink led + PORTB ^= (1 << 4); + + dataOut(); + + // Set ROM bank + writeByte_GB(0x2100, y); + dataIn(); + + if (y > 1) { + addr = 0x4000; + } + + for (; addr <= 0x7FFF; addr += 512) { + uint8_t readData[512]; + for (int i = 0; i < 512; i++) { + readData[i] = readByte_GB(addr + i); + } + for (int j = 0; j < 512; j++) { + if (readData[j] != 0xFF) { + println_Msg(F("Not empty")); + display_Update(); + print_Error(F("Erase failed"), true); + } + } + } + } + + println_Msg(F("Writing flash")); + display_Update(); + + // Write flash + addr = 0; + dataOut(); + + for (int y = 1; y < numBanks; y++) { + // Blink led + PORTB ^= (1 << 4); + + // Set ROM bank + writeByte_GB(0x2100, y); + + if (y > 1) { + addr = 0x4000; + } + + for (; addr <= 0x7FFF; addr += 512) { + myFile.read(sdBuffer, 512); + + for (int c = 0; c < 512; c++) { + // Write command sequence + writeByte_GB(0x555, 0xaa); + writeByte_GB(0x2aa, 0x55); + writeByte_GB(0x555, 0xa0); + // Write current byte + writeByte_GB(addr + c, sdBuffer[c]); + + // Set data pins to input + dataIn(); + + // Switch CS(PH3) and RD(PH6) to LOW + PORTH &= ~((1 << 3) | (1 << 6)); + __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t"); + + // Busycheck + while ((PINC & 0x80) != (sdBuffer[c] & 0x80)) { + } + // Switch CS(PH3) and RD(PH6) to HIGH + PORTH |= (1 << 3) | (1 << 6); + + // Set data pins to output + dataOut(); + } + } + } + // Set data pins to input again + dataIn(); + + // Close the file: + myFile.close(); + + println_Msg(F("Done")); + display_Update(); + } + else { + println_Msg(F("Can't open file")); + display_Update(); + } +} + //****************************************** // End of File //****************************************** diff --git a/Cart_Reader/N64.ino b/Cart_Reader/N64.ino index ba275a9..51c78fa 100644 --- a/Cart_Reader/N64.ino +++ b/Cart_Reader/N64.ino @@ -73,7 +73,7 @@ const char* const menuOptionsN64CRC[] PROGMEM = {N64CRCMenuItem1, N64CRCMenuItem void n64ControllerMenu() { // create menu with title and 4 options to choose from unsigned char mainMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsN64Controller, 4); mainMenu = question_box("N64 Controller", menuOptions, 4, 0); @@ -124,7 +124,7 @@ void n64ControllerMenu() { void n64CartMenu() { // create menu with title and 4 options to choose from unsigned char mainMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsN64Cart, 4); mainMenu = question_box("N64 Cart Reader", menuOptions, 4, 0); @@ -2007,7 +2007,7 @@ calcn64crc: rgb.setColor(255, 0, 0); // N64 CRC32 error Menu unsigned char CRCMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsN64CRC, 4); char tempStr3[20]; diff --git a/Cart_Reader/NP.ino b/Cart_Reader/NP.ino index 8515d02..410b25e 100644 --- a/Cart_Reader/NP.ino +++ b/Cart_Reader/NP.ino @@ -58,7 +58,7 @@ const char* const menuOptionsNPGame[] PROGMEM = {NPGameMenuItem1, NPGameMenuItem void npMenu() { // create menu with title and 3 options to choose from unsigned char mainMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsNP, 3); mainMenu = question_box("Nintendo Power", menuOptions, 3, 0); @@ -151,7 +151,7 @@ void NPGameMenu() { void NPGameOptions() { // create menu with title and 3 options to choose from unsigned char gameSubMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsNPGame, 5); gameSubMenu = question_box("NP Game Menu", menuOptions, 5, 0); @@ -216,7 +216,7 @@ void NPGameOptions() { void NPFlashMenu() { // create menu with title and 6 options to choose from unsigned char flashSubMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsNPFlash, 6); flashSubMenu = question_box("NP Flash Menu", menuOptions, 6, 0); diff --git a/Cart_Reader/SNES.ino b/Cart_Reader/SNES.ino index 167ba04..7ef6b75 100644 --- a/Cart_Reader/SNES.ino +++ b/Cart_Reader/SNES.ino @@ -46,7 +46,7 @@ const char* const menuOptionsConf[] PROGMEM = {confMenuItem1, confMenuItem2, con void snesMenu() { // create menu with title and 7 options to choose from unsigned char mainMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsSNES, 6); mainMenu = question_box("SNES Cart Reader", menuOptions, 6, 0); @@ -101,6 +101,16 @@ void snesMenu() { case 3: if (sramSize > 0) { + display_Clear(); + println_Msg(F("Warning:")); + println_Msg(F("This can erase")); + println_Msg(F("your save games")); + println_Msg(F("")); + println_Msg(F("")); + println_Msg(F("Press any button to")); + println_Msg(F("start sram testing")); + display_Update(); + wait(); display_Clear(); // Change working dir to root sd.chdir("/"); @@ -153,7 +163,7 @@ void snesMenu() { void confMenu() { // create menu with title and 5 options to choose from unsigned char subMenu; - // Copy menuOptions of of progmem + // Copy menuOptions out of progmem convertPgm(menuOptionsConf, 5); subMenu = question_box("Choose mapping", menuOptions, 5, 0); @@ -990,6 +1000,25 @@ void writeSRAM (boolean browseFile) { writeBank_SNES(0, 0x2227, 0x00); // Disable CPU clock clockgen.output_enable(SI5351_CLK1, 0); + + // Reset SA1 + // Set pins to input + dataIn(); + // Close the file: + myFile.close(); + println_Msg(F("SRAM writing finished")); + println_Msg(F("Press Button to reset")); + display_Update(); + wait(); + // Set reset pin to output (PH0) + DDRH |= (1 << 0); + // Switch RST(PH0) to LOW + PORTH &= ~(1 << 0); + display_Clear(); + print_Msg("Resetting..."); + display_Update(); + delay(3000); // wait 3 secs to switch to next game + asm volatile (" jmp 0"); } // Set pins to input