V2.3: Remove 16bit flash adapter menu

If you're still using the old 16bit adapter(the one with the additional pins left and right on the snes cart edge) you can enable the menu again by changing one line in Cart_Reader.ino:  
// Enable 16bit flash adapter menu
#define enable_flash16
This commit is contained in:
sanni 2018-10-30 21:08:59 +01:00 committed by GitHub
parent 9c3e5e9d38
commit a27ee157e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 327 additions and 40 deletions

View File

@ -2,8 +2,8 @@
Cartridge Reader for Arduino Mega2560 Cartridge Reader for Arduino Mega2560
Author: sanni Author: sanni
Date: 22-10-2018 Date: 30-10-2018
Version: 2.2 Version: 2.3
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
@ -37,7 +37,7 @@
vogelfreiheit - N64 flashram fix vogelfreiheit - N64 flashram fix
**********************************************************************************/ **********************************************************************************/
char ver[5] = "2.2"; char ver[5] = "2.3";
/****************************************** /******************************************
Define Starting Point Define Starting Point
@ -71,6 +71,8 @@ char ver[5] = "2.2";
******************************************/ ******************************************/
// If set to 1 then the crc32 checksum will be calculated after reading a N64 rom // If set to 1 then the crc32 checksum will be calculated after reading a N64 rom
boolean n64crc = 1; boolean n64crc = 1;
// Enable 16bit flash adapter menu
//#define enable_flash16
/****************************************** /******************************************
Libraries Libraries

View File

@ -19,9 +19,9 @@ boolean hiROM = 1;
Menu Menu
*****************************************/ *****************************************/
// Flash start menu // Flash start menu
static const char flashMenuItem1[] PROGMEM = "8bit adapter"; static const char flashMenuItem1[] PROGMEM = "8bit Flash adapter";
static const char flashMenuItem2[] PROGMEM = "16bit adapter(old)"; static const char flashMenuItem2[] PROGMEM = "Eprom adapter(beta)";
static const char flashMenuItem3[] PROGMEM = "Eprom adapter(beta)"; static const char flashMenuItem3[] PROGMEM = "16bit Flash adapter";
static const char* const menuOptionsFlash[] PROGMEM = {flashMenuItem1, flashMenuItem2, flashMenuItem3}; static const char* const menuOptionsFlash[] PROGMEM = {flashMenuItem1, flashMenuItem2, flashMenuItem3};
// 8bit Flash menu items // 8bit Flash menu items
@ -57,8 +57,13 @@ void flashMenu() {
// create menu with title and 3 options to choose from // create menu with title and 3 options to choose from
unsigned char flashSlot; unsigned char flashSlot;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
#ifdef enable_flash16
convertPgm(menuOptionsFlash, 3); convertPgm(menuOptionsFlash, 3);
flashSlot = question_box("Select adapter PCB", menuOptions, 3, 0); flashSlot = question_box("Select adapter PCB", menuOptions, 3, 0);
#else
convertPgm(menuOptionsFlash, 2);
flashSlot = question_box("Select adapter PCB", menuOptions, 2, 0);
#endif
// 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 (flashSlot) switch (flashSlot)
@ -76,17 +81,17 @@ void flashMenu() {
case 1: case 1:
display_Clear(); display_Clear();
display_Update(); display_Update();
setup_Flash16(); setup_Eprom();
id_Flash16(); mode = mode_EPROM;
wait();
mode = mode_FLASH16;
break; break;
case 2: case 2:
display_Clear(); display_Clear();
display_Update(); display_Update();
setup_Eprom(); setup_Flash16();
mode = mode_EPROM; id_Flash16();
wait();
mode = mode_FLASH16;
break; break;
} }
} }

View File

@ -31,7 +31,7 @@ void mdMenu() {
unsigned char mainMenu; unsigned char mainMenu;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(menuOptionsMD, 5); convertPgm(menuOptionsMD, 5);
mainMenu = question_box("MEGA DRIVE Reader", menuOptions, 3, 0); mainMenu = question_box("MEGA DRIVE Reader", menuOptions, 5, 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 (mainMenu) switch (mainMenu)
@ -90,18 +90,47 @@ void mdMenu() {
} }
break; break;
/*case 3: case 3:
// Change working dir to root // Change working dir to root
filePath[0] = '\0';
sd.chdir("/"); sd.chdir("/");
writeFlash_MD(); fileBrowser("Select file");
// Reset display_Clear();
wait(); // Setting CS(PH3) LOW
asm volatile (" jmp 0"); PORTH &= ~(1 << 3);
// ID flash
resetFlash_MD();
idFlash_MD();
resetFlash_MD();
print_Msg("Flash ID: ");
println_Msg(flashid);
if (strcmp(flashid, "C2F1") == 0) {
println_Msg("MX29F1610 detected");
flashSize = 2097152;
}
else {
print_Error(F("Error: Unknown flashrom"), true);
}
display_Update();
eraseFlash_MD();
resetFlash_MD();
blankcheck_MD();
write29F1610_MD();
resetFlash_MD();
delay(1000);
resetFlash_MD();
delay(1000);
verifyFlash_MD();
// Set CS(PH3) HIGH
PORTH |= (1 << 3);
break; break;
case 4: case 4:
// Reset
asm volatile (" jmp 0"); asm volatile (" jmp 0");
break;*/ break;
} }
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Press Button...")); println_Msg(F("Press Button..."));
@ -206,6 +235,55 @@ word readWord_MD(unsigned long myAddress) {
return tempWord; return tempWord;
} }
void writeFlash_MD(unsigned long myAddress, word myData) {
PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF;
PORTL = (myAddress >> 16) & 0xFF;
PORTC = myData;
PORTA = (myData >> 8) & 0xFF;
// Arduino running at 16Mhz -> one nop = 62.5ns
// Wait till output is stable
__asm__("nop\n\t");
// Switch WE(PH5) to LOW
PORTH &= ~(1 << 5);
// Leave WE low for at least 60ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Switch WE(PH5)to HIGH
PORTH |= (1 << 5);
// Leave WE high for at least 50ns
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
}
word readFlash_MD(unsigned long myAddress) {
PORTF = myAddress & 0xFF;
PORTK = (myAddress >> 8) & 0xFF;
PORTL = (myAddress >> 16) & 0xFF;
// Arduino running at 16Mhz -> one nop = 62.5ns
__asm__("nop\n\t");
// Setting OE(PH6) LOW
PORTH &= ~(1 << 6);
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Read
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
__asm__("nop\n\t");
// Setting OE(PH6) HIGH
PORTH |= (1 << 6);
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
return tempWord;
}
// Switch data pins to write // Switch data pins to write
void dataOut_MD() { void dataOut_MD() {
DDRC = 0xFF; DDRC = 0xFF;
@ -494,6 +572,209 @@ unsigned long verifySram_MD() {
return writeErrors; return writeErrors;
} }
//******************************************
// Flashrom Functions
//******************************************
void resetFlash_MD() {
// Set data pins to output
dataOut_MD();
// Reset command sequence
writeFlash_MD(0x5555, 0xaa);
writeFlash_MD(0x2aaa, 0x55);
writeFlash_MD(0x5555, 0xf0);
// Set data pins to input again
dataIn_MD();
}
void write29F1610_MD() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName);
print_Msg(F("Flashing file "));
print_Msg(filePath);
println_Msg(F("..."));
display_Update();
// Open file on sd card
if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), true);
}
// Set data pins to output
dataOut_MD();
// Fill sdBuffer with 1 page at a time then write it repeat until all bytes are written
int d = 0;
for (unsigned long currByte = 0; currByte < fileSize / 2; currByte += 64) {
myFile.read(sdBuffer, 128);
// Blink led
if (currByte % 4096 == 0) {
PORTB ^= (1 << 4);
}
// Write command sequence
writeFlash_MD(0x5555, 0xaa);
writeFlash_MD(0x2aaa, 0x55);
writeFlash_MD(0x5555, 0xa0);
// Write one full page at a time
for (byte c = 0; c < 64; c++) {
word currWord = ( ( sdBuffer[d] & 0xFF ) << 8 ) | ( sdBuffer[d + 1] & 0xFF );
writeFlash_MD(currByte + c, currWord);
d += 2;
}
d = 0;
// Check if write is complete
delayMicroseconds(100);
busyCheck_MD();
}
// Set data pins to input again
dataIn_MD();
// Close the file:
myFile.close();
}
else {
println_Msg(F("Can't open file"));
display_Update();
}
}
void idFlash_MD() {
// Set data pins to output
dataOut_MD();
// ID command sequence
writeFlash_MD(0x5555, 0xaa);
writeFlash_MD(0x2aaa, 0x55);
writeFlash_MD(0x5555, 0x90);
// Set data pins to input again
dataIn_MD();
// Read the two id bytes into a string
sprintf(flashid, "%02X%02X", readFlash_MD(0) & 0xFF, readFlash_MD(1) & 0xFF);
}
byte readStatusReg_MD() {
// Set data pins to output
dataOut_MD();
// Status reg command sequence
writeFlash_MD(0x5555, 0xaa);
writeFlash_MD(0x2aaa, 0x55);
writeFlash_MD(0x5555, 0x70);
// Set data pins to input again
dataIn_MD();
// Read the status register
byte statusReg = readFlash_MD(0);
return statusReg;
}
void eraseFlash_MD() {
// Set data pins to output
dataOut_MD();
// Erase command sequence
writeFlash_MD(0x5555, 0xaa);
writeFlash_MD(0x2aaa, 0x55);
writeFlash_MD(0x5555, 0x80);
writeFlash_MD(0x5555, 0xaa);
writeFlash_MD(0x2aaa, 0x55);
writeFlash_MD(0x5555, 0x10);
// Set data pins to input again
dataIn_MD();
busyCheck_MD();
}
void blankcheck_MD() {
blank = 1;
for (unsigned long currByte = 0; currByte < flashSize / 2; currByte++) {
if (readFlash_MD(currByte) != 0xFFFF) {
currByte = flashSize / 2;
blank = 0;
}
if (currByte % 4096 == 0) {
PORTB ^= (1 << 4);
}
}
if (!blank) {
print_Error(F("Error: Not blank"), false);
}
}
void verifyFlash_MD() {
// Open file on sd card
if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), true);
}
blank = 0;
word d = 0;
for (unsigned long currByte = 0; currByte < fileSize / 2; currByte += 256) {
if (currByte % 4096 == 0) {
PORTB ^= (1 << 4);
}
//fill sdBuffer
myFile.read(sdBuffer, 512);
for (int c = 0; c < 256; c++) {
word currWord = ((sdBuffer[d] << 8) | sdBuffer[d + 1]);
if (readFlash_MD(currByte + c) != currWord) {
blank++;
}
d += 2;
}
d = 0;
}
if (blank == 0) {
println_Msg(F("Flashrom verified OK"));
display_Update();
}
else {
print_Msg(F("Error: "));
print_Msg(blank);
println_Msg(F(" bytes "));
print_Error(F("did not verify."), false);
}
// Close the file:
myFile.close();
}
else {
println_Msg(F("Can't open file"));
display_Update();
}
}
// Delay between write operations based on status register
void busyCheck_MD() {
// Set data pins to input
dataIn_MD();
// Read the status register
word statusReg = readFlash_MD(0);
while ((statusReg | 0xFF7F) != 0xFFFF) {
statusReg = readFlash_MD(0);
}
// Set data pins to output
dataOut_MD();
}
//****************************************** //******************************************
// End of File // End of File
//****************************************** //******************************************

View File

@ -205,7 +205,7 @@ void writeROM_SV (void) {
sprintf(checksumStr, "%02X%02X", readBank_SNES(0, 65503), readBank_SNES(0, 65502)); sprintf(checksumStr, "%02X%02X", readBank_SNES(0, 65503), readBank_SNES(0, 65502));
//if CRC is not 8B86, BS-X cart is not inserted. Display error and reset //if CRC is not 8B86, BS-X cart is not inserted. Display error and reset
if(strcmp("8B86", checksumStr) != 0) if (strcmp("8B86", checksumStr) != 0)
{ {
display_Clear(); display_Clear();
print_Error(F("Error: Must use BS-X cart"), true); print_Error(F("Error: Must use BS-X cart"), true);
@ -251,7 +251,7 @@ void writeROM_SV (void) {
for (int currBank = 0xC0; currBank < 0xD0; currBank++) { for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000); draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
for (long currByte = 0; currByte < 65536; currByte++) { for (long currByte = 0; currByte < 65536; currByte++) {
if(0xFF != readBank_SNES(currBank, currByte)) if (0xFF != readBank_SNES(currBank, currByte))
{ {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Erase failed")); println_Msg(F("Erase failed"));
@ -295,7 +295,7 @@ void writeROM_SV (void) {
for (int currBank = 0xC0; currBank < 0xD0; currBank++) { for (int currBank = 0xC0; currBank < 0xD0; currBank++) {
draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000); draw_progressbar(((currBank - 0xC0) * 0x10000), 0x100000);
for (long currByte = 0; currByte < 65536; currByte++) { for (long currByte = 0; currByte < 65536; currByte++) {
if(myFile.read() != readBank_SNES(currBank, currByte)) if (myFile.read() != readBank_SNES(currBank, currByte))
{ {
println_Msg(F("")); println_Msg(F(""));
println_Msg(F("Verify failed")); println_Msg(F("Verify failed"));
@ -415,7 +415,7 @@ void detectCheck_SV(void) {
// completion of a program or erase operation will not be evident. // completion of a program or erase operation will not be evident.
while ((ret & 0x80) == 0x00) { while ((ret & 0x80) == 0x00) {
i++; i++;
if( i > 10000) if ( i > 10000)
{ {
//timeout //timeout
break; break;
@ -454,4 +454,3 @@ void eraseAll_SV(void)
//****************************************** //******************************************
// End of File // End of File
//****************************************** //******************************************