Merge pull request #47 from splash5/master

WonderSwan rom dumping and save reading/writing
This commit is contained in:
sanni 2019-10-18 07:42:12 +02:00 committed by GitHub
commit f7cdce53c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1423 additions and 69 deletions

View File

@ -154,6 +154,7 @@ typedef enum COLOR_T {
#define mode_GB_GBSmart 18 #define mode_GB_GBSmart 18
#define mode_GB_GBSmart_Flash 19 #define mode_GB_GBSmart_Flash 19
#define mode_GB_GBSmart_Game 20 #define mode_GB_GBSmart_Game 20
#define mode_WS 21
// optimization-safe nop delay // optimization-safe nop delay
#define NOP __asm__ __volatile__ ("nop\n\t") #define NOP __asm__ __volatile__ ("nop\n\t")
@ -204,14 +205,18 @@ char menuOptions[7][20];
boolean ignoreError = 0; boolean ignoreError = 0;
// File browser // File browser
char fileName[26]; #define FILENAME_LENGTH 32
char filePath[50]; #define FILEPATH_LENGTH 64
#define FILEOPTS_LENGTH 20
char fileName[FILENAME_LENGTH];
char filePath[FILEPATH_LENGTH];
byte currPage; byte currPage;
byte lastPage; byte lastPage;
byte numPages; byte numPages;
boolean root = 0; boolean root = 0;
boolean filebrowse = 0; boolean filebrowse = 0;
char fileOptions[30][20]; char fileOptions[30][FILEOPTS_LENGTH];
// Common // Common
char romName[17]; char romName[17];
@ -377,8 +382,9 @@ static const char addonsItem1[] PROGMEM = "NES/Famicom";
static const char addonsItem2[] PROGMEM = "Flashrom Programmer"; static const char addonsItem2[] PROGMEM = "Flashrom Programmer";
static const char addonsItem3[] PROGMEM = "PC Engine/TG16"; static const char addonsItem3[] PROGMEM = "PC Engine/TG16";
static const char addonsItem4[] PROGMEM = "Sega Master System"; static const char addonsItem4[] PROGMEM = "Sega Master System";
static const char addonsItem6[] PROGMEM = "WonderSwan";
static const char addonsItem5[] PROGMEM = "Reset"; static const char addonsItem5[] PROGMEM = "Reset";
static const char* const addonsOptions[] PROGMEM = {addonsItem1, addonsItem2, addonsItem3, addonsItem4, addonsItem5}; static const char* const addonsOptions[] PROGMEM = {addonsItem1, addonsItem2, addonsItem3, addonsItem4, addonsItem6, addonsItem5};
// Info Screen // Info Screen
void aboutScreen() { void aboutScreen() {
@ -476,8 +482,8 @@ void addonsMenu() {
// create menu with title and 5 options to choose from // create menu with title and 5 options to choose from
unsigned char addonsMenu; unsigned char addonsMenu;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(addonsOptions, 5); convertPgm(addonsOptions, 6);
addonsMenu = question_box(F("Choose Adapter"), menuOptions, 5, 0); addonsMenu = question_box(F("Choose Adapter"), menuOptions, 6, 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 (addonsMenu) switch (addonsMenu)
@ -499,6 +505,10 @@ void addonsMenu() {
break; break;
case 4: case 4:
setup_WS();
break;
default:
resetArduino(); resetArduino();
break; break;
} }
@ -656,7 +666,7 @@ void dataIn() {
// Converts a progmem array into a ram array // Converts a progmem array into a ram array
void convertPgm(const char* const pgmOptions[], byte numArrays) { void convertPgm(const char* const pgmOptions[], byte numArrays) {
for (int i = 0; i < numArrays; i++) { for (int i = 0; i < numArrays; i++) {
strcpy_P(menuOptions[i], (char*)pgm_read_word(&(pgmOptions[i]))); strlcpy_P(menuOptions[i], (char*)pgm_read_word(&(pgmOptions[i])), 20);
} }
} }
@ -1256,7 +1266,7 @@ unsigned char questionBox_OLED(const __FlashStringHelper* question, char answers
Filebrowser Module Filebrowser Module
*****************************************/ *****************************************/
void fileBrowser(const __FlashStringHelper* browserTitle) { void fileBrowser(const __FlashStringHelper* browserTitle) {
char fileNames[30][26]; char fileNames[30][FILENAME_LENGTH];
int currFile; int currFile;
filebrowse = 1; filebrowse = 1;
@ -1264,7 +1274,7 @@ void fileBrowser(const __FlashStringHelper* browserTitle) {
filePath[0] = '\0'; filePath[0] = '\0';
// Temporary char array for filename // Temporary char array for filename
char nameStr[26]; char nameStr[FILENAME_LENGTH];
browserstart: browserstart:
@ -1280,7 +1290,7 @@ browserstart:
while (myFile.openNext(sd.vwd(), O_READ)) { while (myFile.openNext(sd.vwd(), O_READ)) {
// Get name of file // Get name of file
myFile.getName(nameStr, 27); myFile.getName(nameStr, FILENAME_LENGTH);
// Ignore if hidden // Ignore if hidden
if (myFile.isHidden()) { if (myFile.isHidden()) {
@ -1288,21 +1298,17 @@ browserstart:
// Indicate a directory. // Indicate a directory.
else if (myFile.isDir()) { else if (myFile.isDir()) {
// Copy full dirname into fileNames // Copy full dirname into fileNames
sprintf(fileNames[currFile], "%s%s", "/", nameStr); snprintf(fileNames[currFile], FILENAME_LENGTH, "%s%s", "/", nameStr);
// Truncate to 19 letters for LCD
nameStr[19] = '\0';
// Copy short string into fileOptions // Copy short string into fileOptions
sprintf(fileOptions[currFile], "%s%s", "/", nameStr); snprintf(fileOptions[currFile], FILEOPTS_LENGTH, "%s%s", "/", nameStr);
currFile++; currFile++;
} }
// It's just a file // It's just a file
else if (myFile.isFile()) { else if (myFile.isFile()) {
// Copy full filename into fileNames // Copy full filename into fileNames
sprintf(fileNames[currFile], "%s", nameStr); snprintf(fileNames[currFile], FILENAME_LENGTH, "%s", nameStr);
// Truncate to 19 letters for LCD
nameStr[19] = '\0';
// Copy short string into fileOptions // Copy short string into fileOptions
sprintf(fileOptions[currFile], "%s", nameStr); snprintf(fileOptions[currFile], FILEOPTS_LENGTH, "%s", nameStr);
currFile++; currFile++;
} }
myFile.close(); myFile.close();
@ -1354,7 +1360,7 @@ page:
for (byte i = 0; i < 8; i++ ) { for (byte i = 0; i < 8; i++ ) {
// Copy short string into fileOptions // Copy short string into fileOptions
sprintf( answers[i], "%s", fileOptions[ ((currPage - 1) * 7 + i)] ); snprintf( answers[i], FILEOPTS_LENGTH, "%s", fileOptions[ ((currPage - 1) * 7 + i)] );
} }
// Create menu with title and 1-7 options to choose from // Create menu with title and 1-7 options to choose from
@ -1383,31 +1389,31 @@ page:
switch (answer) switch (answer)
{ {
case 0: case 0:
strcpy(fileName, fileNames[0 + ((currPage - 1) * 7)]); strncpy(fileName, fileNames[0 + ((currPage - 1) * 7)], FILENAME_LENGTH - 1);
break; break;
case 1: case 1:
strcpy(fileName, fileNames[1 + ((currPage - 1) * 7)]); strncpy(fileName, fileNames[1 + ((currPage - 1) * 7)], FILENAME_LENGTH - 1);
break; break;
case 2: case 2:
strcpy(fileName, fileNames[2 + ((currPage - 1) * 7)]); strncpy(fileName, fileNames[2 + ((currPage - 1) * 7)], FILENAME_LENGTH - 1);
break; break;
case 3: case 3:
strcpy(fileName, fileNames[3 + ((currPage - 1) * 7)]); strncpy(fileName, fileNames[3 + ((currPage - 1) * 7)], FILENAME_LENGTH - 1);
break; break;
case 4: case 4:
strcpy(fileName, fileNames[4 + ((currPage - 1) * 7)]); strncpy(fileName, fileNames[4 + ((currPage - 1) * 7)], FILENAME_LENGTH - 1);
break; break;
case 5: case 5:
strcpy(fileName, fileNames[5 + ((currPage - 1) * 7)]); strncpy(fileName, fileNames[5 + ((currPage - 1) * 7)], FILENAME_LENGTH - 1);
break; break;
case 6: case 6:
strcpy(fileName, fileNames[6 + ((currPage - 1) * 7)]); strncpy(fileName, fileNames[6 + ((currPage - 1) * 7)], FILENAME_LENGTH - 1);
break; break;
case 7: case 7:
@ -1500,6 +1506,9 @@ void loop() {
else if (mode == mode_GB_GBSmart_Game) { else if (mode == mode_GB_GBSmart_Game) {
gbSmartGameOptions(); gbSmartGameOptions();
} }
else if (mode == mode_WS) {
wsMenu();
}
else { else {
display_Clear(); display_Clear();
println_Msg(F("Menu Error")); println_Msg(F("Menu Error"));

View File

@ -158,7 +158,8 @@ void flashromMenu8() {
// sector size, write buffer size // sector size, write buffer size
writeFlash29GL(sectorSize, bufferSize); writeFlash29GL(sectorSize, bufferSize);
} }
else if ((strcmp(flashid, "0458") == 0) || (strcmp(flashid, "0158") == 0)) else if ((strcmp(flashid, "0458") == 0) || (strcmp(flashid, "0158") == 0) ||
(strcmp(flashid, "01AB") == 0))
writeFlash29F800(); writeFlash29F800();
break; break;
@ -466,11 +467,21 @@ idtheflash:
flashSize = 1048576; flashSize = 1048576;
flashromType = 2; flashromType = 2;
} }
else if (strcmp(flashid, "01AB") == 0) {
println_Msg(F("AM29F400AB detected"));
flashSize = 131072 * 4;
flashromType = 2;
}
else if (strcmp(flashid, "0158") == 0) { else if (strcmp(flashid, "0158") == 0) {
println_Msg(F("AM29F800BB detected")); println_Msg(F("AM29F800BB detected"));
flashSize = 1048576; flashSize = 1048576;
flashromType = 2; flashromType = 2;
} }
else if (strcmp(flashid, "01A3") == 0) {
println_Msg(F("AM29LV033C detected"));
flashSize = 131072 * 32;
flashromType = 1;
}
else if (strcmp(flashid, "017E") == 0) { else if (strcmp(flashid, "017E") == 0) {
// S29GL032M // S29GL032M
if (readByte_Flash(28) == 0x1A) { if (readByte_Flash(28) == 0x1A) {
@ -498,6 +509,32 @@ idtheflash:
bufferSize = 256; bufferSize = 256;
flashromType = 3; flashromType = 3;
} }
else if ((strcmp(flashid, "8916") == 0) ||
(strcmp(flashid, "8917") == 0) ||
(strcmp(flashid, "8918") == 0)) {
// E28FXXXJ3A
print_Msg(F("E28F"));
switch (flashid[3]) {
case '6':
flashSize = 131072 * 32;
print_Msg(F("320"));
break;
case '7':
flashSize = 131072 * 64;
print_Msg(F("640"));
break;
case '8':
flashSize = 131072 * 128;
print_Msg(F("128"));
break;
}
println_Msg(F("J3A detected"));
sectorSize = 131072;
bufferSize = 32;
flashromType = 3;
}
else if (secondID == 1) { else if (secondID == 1) {
// Backup first ID read-out // Backup first ID read-out
strncpy(vendorID, flashid, 5); strncpy(vendorID, flashid, 5);
@ -1345,7 +1382,7 @@ void eraseFlash28FXXX() {
for (uint32_t ba = 0; ba < flashSize; ba += sectorSize) for (uint32_t ba = 0; ba < flashSize; ba += sectorSize)
{ {
dataOut(); dataOut();
writeByte_Flash(0x0, 0x20); writeByte_Flash(ba, 0x20);
writeByte_Flash(ba, 0xd0); writeByte_Flash(ba, 0xd0);
dataIn8(); dataIn8();
@ -1357,55 +1394,21 @@ void eraseFlash28FXXX() {
} }
void writeFlash28FXXX() { void writeFlash28FXXX() {
if ((strcmp(flashid, "B088") == 0))
writeFlashLH28F0XX();
}
void writeFlashLH28F0XX() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName); sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file ")); print_Msg(F("Flashing file "));
println_Msg(filePath); println_Msg(filePath);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
// Get rom size from file if ((strcmp(flashid, "B088") == 0))
fileSize = myFile.fileSize(); writeFlashLH28F0XX();
if (fileSize > flashSize) else if ((strcmp(flashid, "8916") == 0) ||
print_Error(F("File size exceeds flash size."), true); (strcmp(flashid, "8917") == 0) ||
(strcmp(flashid, "8918") == 0)) {
// Fill sdBuffer writeFlashE28FXXXJ3A();
for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) {
myFile.read(sdBuffer, 512);
// Blink led
if (currByte % 2048 == 0)
PORTB ^= (1 << 4);
for (int c = 0; c < 512; c += bufferSize) {
// sequence load to page
dataOut();
writeByte_Flash(0x0, 0xe0);
writeByte_Flash(0x0, bufferSize - 1); // BCL
writeByte_Flash(0x0, 0x00); // BCH should be 0x00
for (int d = 0; d < bufferSize; d++)
writeByte_Flash(d, sdBuffer[c + d]);
// start flashing page
writeByte_Flash(0x0, 0x0c);
writeByte_Flash(0x0, bufferSize - 1); // BCL
writeByte_Flash(currByte + c, 0x00); // BCH should be 0x00
// waiting for finishing
dataIn8();
while ((readByte_Flash(currByte + c) & 0x80) == 0x00);
}
} }
dataIn8();
// Close the file:
myFile.close(); myFile.close();
} }
else { else {
@ -1414,6 +1417,93 @@ void writeFlashLH28F0XX() {
} }
} }
void writeFlashE28FXXXJ3A() {
fileSize = myFile.fileSize();
if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), false);
return;
}
uint32_t block_addr;
uint32_t block_addr_mask = ~(sectorSize - 1);
// Fill sdBuffer
for (uint32_t currByte = 0; currByte < fileSize; currByte += 512) {
myFile.read(sdBuffer, 512);
// Blink led
if (currByte % 2048 == 0)
PORTB ^= (1 << 4);
block_addr = currByte & block_addr_mask;
for (uint32_t c = 0; c < 512; c += bufferSize) {
// write to buffer start
dataOut();
writeByte_Flash(block_addr, 0xe8);
// waiting for buffer available
dataIn8();
while ((readByte_Flash(block_addr) & 0x80) == 0x00);
dataOut();
// set write byte count
writeByte_Flash(block_addr, bufferSize - 1);
// filling buffer
for (uint32_t d = 0; d < bufferSize; d++)
writeByte_Flash(currByte + c + d, sdBuffer[c + d]);
// start flashing page
writeByte_Flash(block_addr, 0xd0);
// waiting for finishing
dataIn8();
while ((readByte_Flash(block_addr) & 0x80) == 0x00);
}
}
dataIn8();
}
void writeFlashLH28F0XX() {
fileSize = myFile.fileSize();
if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), false);
return;
}
// Fill sdBuffer
for (uint32_t currByte = 0; currByte < fileSize; currByte += 512) {
myFile.read(sdBuffer, 512);
// Blink led
if (currByte % 2048 == 0)
PORTB ^= (1 << 4);
for (uint32_t c = 0; c < 512; c += bufferSize) {
// sequence load to page
dataOut();
writeByte_Flash(0x0, 0xe0);
writeByte_Flash(0x0, bufferSize - 1); // BCL
writeByte_Flash(0x0, 0x00); // BCH should be 0x00
for (uint32_t d = 0; d < bufferSize; d++)
writeByte_Flash(d, sdBuffer[c + d]);
// start flashing page
writeByte_Flash(0x0, 0x0c);
writeByte_Flash(0x0, bufferSize - 1); // BCL
writeByte_Flash(currByte + c, 0x00); // BCH should be 0x00
// waiting for finishing
dataIn8();
while ((readByte_Flash(currByte + c) & 0x80) == 0x00);
}
}
dataIn8();
}
/****************************************** /******************************************
Common flashrom functions Common flashrom functions
*****************************************/ *****************************************/

View File

@ -185,6 +185,10 @@ void setup_GB() {
// Print start page // Print start page
getCartInfo_GB(); getCartInfo_GB();
showCartInfo_GB();
}
void showCartInfo_GB() {
display_Clear(); display_Clear();
if (strcmp(checksumStr, "00") != 0) { if (strcmp(checksumStr, "00") != 0) {
println_Msg(F("GB Cart Info")); println_Msg(F("GB Cart Info"));

View File

@ -220,6 +220,7 @@ gb_smart_load_more_games:
// select a game // select a game
gbSmartRemapStartBank(gbSmartGames[gameSubMenu].start_bank, gbSmartGames[gameSubMenu].rom_size, gbSmartGames[gameSubMenu].sram_size); gbSmartRemapStartBank(gbSmartGames[gameSubMenu].start_bank, gbSmartGames[gameSubMenu].rom_size, gbSmartGames[gameSubMenu].sram_size);
getCartInfo_GB(); getCartInfo_GB();
showCartInfo_GB();
mode = mode_GB_GBSmart_Game; mode = mode_GB_GBSmart_Game;
} }

1250
Cart_Reader/WS.ino Normal file

File diff suppressed because it is too large Load Diff