mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-27 23:14:14 +01:00
Merge pull request #47 from splash5/master
WonderSwan rom dumping and save reading/writing
This commit is contained in:
commit
f7cdce53c7
@ -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"));
|
||||
|
@ -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
|
||||
*****************************************/
|
||||
|
@ -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"));
|
||||
|
@ -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
1250
Cart_Reader/WS.ino
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user