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

View File

@ -158,7 +158,8 @@ void flashromMenu8() {
// sector size, write buffer size
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();
break;
@ -466,11 +467,21 @@ idtheflash:
flashSize = 1048576;
flashromType = 2;
}
else if (strcmp(flashid, "01AB") == 0) {
println_Msg(F("AM29F400AB detected"));
flashSize = 131072 * 4;
flashromType = 2;
}
else if (strcmp(flashid, "0158") == 0) {
println_Msg(F("AM29F800BB detected"));
flashSize = 1048576;
flashromType = 2;
}
else if (strcmp(flashid, "01A3") == 0) {
println_Msg(F("AM29LV033C detected"));
flashSize = 131072 * 32;
flashromType = 1;
}
else if (strcmp(flashid, "017E") == 0) {
// S29GL032M
if (readByte_Flash(28) == 0x1A) {
@ -498,6 +509,32 @@ idtheflash:
bufferSize = 256;
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) {
// Backup first ID read-out
strncpy(vendorID, flashid, 5);
@ -1345,7 +1382,7 @@ void eraseFlash28FXXX() {
for (uint32_t ba = 0; ba < flashSize; ba += sectorSize)
{
dataOut();
writeByte_Flash(0x0, 0x20);
writeByte_Flash(ba, 0x20);
writeByte_Flash(ba, 0xd0);
dataIn8();
@ -1357,55 +1394,21 @@ void eraseFlash28FXXX() {
}
void writeFlash28FXXX() {
if ((strcmp(flashid, "B088") == 0))
writeFlashLH28F0XX();
}
void writeFlashLH28F0XX() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file "));
print_Msg(F("Flashing file "));
println_Msg(filePath);
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);
// Fill sdBuffer
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);
}
if ((strcmp(flashid, "B088") == 0))
writeFlashLH28F0XX();
else if ((strcmp(flashid, "8916") == 0) ||
(strcmp(flashid, "8917") == 0) ||
(strcmp(flashid, "8918") == 0)) {
writeFlashE28FXXXJ3A();
}
dataIn8();
// Close the file:
myFile.close();
}
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
*****************************************/

View File

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

View File

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

1250
Cart_Reader/WS.ino Normal file

File diff suppressed because it is too large Load Diff