Merge pull request #54 from jiyunomegami/master

Merge commits by jiyunomegami
This commit is contained in:
sanni 2020-08-19 20:44:57 +02:00 committed by GitHub
commit 4e590f7114
2 changed files with 320 additions and 164 deletions

View File

@ -470,6 +470,11 @@ idtheflash:
flashSize = 4194304; flashSize = 4194304;
flashromType = 1; flashromType = 1;
} }
else if (strcmp(flashid, "04D5") == 0) {
println_Msg(F("MBM29F080C detected"));
flashSize = 1048576;
flashromType = 1;
}
else if (strcmp(flashid, "0458") == 0) { else if (strcmp(flashid, "0458") == 0) {
println_Msg(F("MBM29F800BA detected")); println_Msg(F("MBM29F800BA detected"));
flashSize = 1048576; flashSize = 1048576;
@ -928,21 +933,58 @@ void writeFlash29F032() {
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
// Retry writing, for when /RESET is not connected (floating)
int dq5failcnt = 0;
int noread = 0;
// Fill sdBuffer // Fill sdBuffer
for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) { for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) {
myFile.read(sdBuffer, 512); // if (currByte >= 0) {
// print_Msg(currByte);
// print_Msg(F(" "));
// print_Msg(dq5failcnt);
// println_Msg(F(""));
// }
if (!noread) {
myFile.read(sdBuffer, 512);
}
// Blink led // Blink led
if (currByte % 2048 == 0) if (currByte % 2048 == 0)
PORTB ^= (1 << 4); PORTB ^= (1 << 4);
noInterrupts();
int blockfailcnt = 0;
for (int c = 0; c < 512; c++) { for (int c = 0; c < 512; c++) {
uint8_t datum = sdBuffer[c];
dataIn8();
uint8_t d = readByte_Flash(currByte + c);
dataOut();
if (d == datum || datum == 0xFF) {
continue;
}
// Write command sequence // Write command sequence
writeByte_Flash(0x555, 0xaa); writeByte_Flash(0x555, 0xaa);
writeByte_Flash(0x2aa, 0x55); writeByte_Flash(0x2aa, 0x55);
writeByte_Flash(0x555, 0xa0); writeByte_Flash(0x555, 0xa0);
// Write current byte // Write current byte
writeByte_Flash(currByte + c, sdBuffer[c]); writeByte_Flash(currByte + c, datum);
busyCheck29F032(sdBuffer[c]); if (busyCheck29F032(currByte + c, datum)) {
dq5failcnt++;
blockfailcnt++;
}
}
interrupts();
if (blockfailcnt > 0) {
print_Msg(F("Failures at "));
print_Msg(currByte);
print_Msg(F(": "));
print_Msg(blockfailcnt);
println_Msg(F(""));
dq5failcnt -= blockfailcnt;
currByte -= 512;
delay(100);
noread = 1;
} else {
noread = 0;
} }
} }
// Set data pins to input again // Set data pins to input again
@ -957,7 +999,8 @@ void writeFlash29F032() {
} }
} }
void busyCheck29F032(byte c) { int busyCheck29F032(uint32_t addr, byte c) {
int ret = 0;
// Set data pins to input // Set data pins to input
dataIn8(); dataIn8();
@ -967,13 +1010,32 @@ void busyCheck29F032(byte c) {
PORTH |= (1 << 4) | (1 << 5); PORTH |= (1 << 4) | (1 << 5);
//When the Embedded Program algorithm is complete, the device outputs the datum programmed to D7 //When the Embedded Program algorithm is complete, the device outputs the datum programmed to D7
while ((PINC & 0x80) != (c & 0x80)) {} for (;;) {
uint8_t d = readByte_Flash(addr);
if ((d & 0x80) == (c & 0x80)) {
break;
}
if ((d & 0x20) == 0x20) {
// From the datasheet:
// DQ 5 will indicate if the program or erase time has exceeded the specified limits (internal pulse count).
// Under these conditions DQ 5 will produce a “1”.
// This is a failure condition which indicates that the program or erase cycle was not successfully completed.
// Note : DQ 7 is rechecked even if DQ 5 = “1” because DQ 7 may change simultaneously with DQ 5 .
if ((d & 0x80) == (c & 0x80)) {
break;
} else {
ret = 1;
break;
}
}
}
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
// Setting OE(PH1) OE_SNS(PH3) HIGH // Setting OE(PH1) OE_SNS(PH3) HIGH
PORTH |= (1 << 1) | (1 << 3); PORTH |= (1 << 1) | (1 << 3);
return ret;
} }
/****************************************** /******************************************
29F1610 flashrom functions 29F1610 flashrom functions
@ -1340,7 +1402,7 @@ void writeFlash29F800() {
writeByte_Flash(0x5555 << 1, 0xa0); writeByte_Flash(0x5555 << 1, 0xa0);
// Write current byte // Write current byte
writeByte_Flash(currByte + c, sdBuffer[c]); writeByte_Flash(currByte + c, sdBuffer[c]);
busyCheck29F032(sdBuffer[c]); busyCheck29F032(currByte + c, sdBuffer[c]);
} }
} }

View File

@ -19,6 +19,7 @@
*****************************************/ *****************************************/
#define HUCARD 0 #define HUCARD 0
#define TURBOCHIP 1 #define TURBOCHIP 1
#define HUCARD_NOSWAP 2
#define DETECTION_SIZE 64 #define DETECTION_SIZE 64
#define CHKSUM_SKIP 0 #define CHKSUM_SKIP 0
@ -36,7 +37,8 @@ void reset_cart_PCE(void);
uint8_t read_byte_PCE(uint32_t address); uint8_t read_byte_PCE(uint32_t address);
void write_byte_PCE(uint32_t address, uint8_t data); void write_byte_PCE(uint32_t address, uint8_t data);
uint32_t detect_rom_size_PCE(void); uint32_t detect_rom_size_PCE(void);
void read_bank_PCE(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size); void read_bank_PCE_ROM(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size);
void read_bank_PCE_RAM(uint32_t address_start);
void read_rom_PCE(void); void read_rom_PCE(void);
/****************************************** /******************************************
@ -44,24 +46,31 @@ void read_rom_PCE(void);
*****************************************/ *****************************************/
uint8_t pce_internal_mode; //0 - HuCARD, 1 - TurboChip uint8_t pce_internal_mode; //0 - HuCARD, 1 - TurboChip
uint16_t pce_force_rom_size = 0;
uint8_t tennokoe_bank_index = 0;
/****************************************** /******************************************
Menu Menu
*****************************************/ *****************************************/
// PCE start menu // PCE start menu
static const char pceMenuItem1[] PROGMEM = "HuCARD"; static const char pceMenuItem1[] PROGMEM = "HuCARD";
static const char pceMenuItem2[] PROGMEM = "Turbochip"; static const char pceMenuItem2[] PROGMEM = "Turbochip";
static const char pceMenuItem3[] PROGMEM = "Reset"; static const char pceMenuItem3[] PROGMEM = "HuCARD Not Swapped";
static const char* const menuOptionspce[] PROGMEM = {pceMenuItem1, pceMenuItem2, pceMenuItem3}; static const char pceMenuItem4[] PROGMEM = "Reset";
static const char* const menuOptionspce[] PROGMEM = {pceMenuItem1, pceMenuItem2, pceMenuItem3, pceMenuItem4};
// PCE card menu items // PCE card menu items
static const char pceCartMenuItem1[] PROGMEM = "Read Rom"; static const char pceCartMenuItem1[] = "Read ROM";
static const char pceCartMenuItem2[] PROGMEM = "Read Tennokoe Bank"; static char pceCartMenuItem2[20];
static const char pceCartMenuItem3[] PROGMEM = "Write Tennokoe Bank"; static char pceCartMenuItem3[20];
static const char pceCartMenuItem4[] PROGMEM = "Reset"; static const char pceCartMenuItem4[] = "Reset";
static const char* const menuOptionspceCart[] PROGMEM = {pceCartMenuItem1, pceCartMenuItem2, pceCartMenuItem3, pceCartMenuItem4}; static const char pceCartMenuItem5[] = "Inc Bank Number";
static const char pceCartMenuItem6[] = "Dec Bank Number";
static char pceCartMenuItem7[20];
static const char menuOptionspceCart[7][20];
// Turbochip menu items // Turbochip menu items
static const char pceTCMenuItem1[] PROGMEM = "Read Rom"; static const char pceTCMenuItem1[] PROGMEM = "Read ROM";
static const char pceTCMenuItem2[] PROGMEM = "Reset"; static const char pceTCMenuItem2[] PROGMEM = "Reset";
static const char* const menuOptionspceTC[] PROGMEM = {pceTCMenuItem1, pceTCMenuItem2}; static const char* const menuOptionspceTC[] PROGMEM = {pceTCMenuItem1, pceTCMenuItem2};
@ -95,6 +104,15 @@ void pcsMenu(void) {
break; break;
case 2: case 2:
//Hucard not swapped
display_Clear();
display_Update();
pce_internal_mode = HUCARD_NOSWAP;
setup_cart_PCE();
mode = mode_PCE;
break;
case 3:
resetArduino(); resetArduino();
break; break;
} }
@ -132,6 +150,8 @@ void pin_read_write_PCE(void)
// Enable Internal Pullups // Enable Internal Pullups
PORTC = 0xFF; PORTC = 0xFF;
set_cs_rd_low_PCE();
reset_cart_PCE(); reset_cart_PCE();
} }
@ -190,6 +210,13 @@ void set_address_PCE(uint32_t address)
PORTL = (PORTL & 0xF0) | ((address >> 16) & 0x0F); PORTL = (PORTL & 0xF0) | ((address >> 16) & 0x0F);
} }
void set_cs_rd_low_PCE ()
{
// Set CS(PL4) and RD(PH3) as LOW
PORTL &= ~(1 << 4);
PORTH &= ~(1 << 3);
}
uint8_t read_byte_PCE(uint32_t address) uint8_t read_byte_PCE(uint32_t address)
{ {
uint8_t ret; uint8_t ret;
@ -199,15 +226,8 @@ uint8_t read_byte_PCE(uint32_t address)
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total // Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
__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""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"); __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""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
// Set CS(PL4) and RD(PH3) as LOW
PORTL &= ~(1 << 4);
PORTH &= ~(1 << 3);
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
__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""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 byte //read byte
ret = PINC; ret = PINC;
//Swap bit order for PC Engine HuCARD //Swap bit order for PC Engine HuCARD
if (pce_internal_mode == HUCARD) if (pce_internal_mode == HUCARD)
@ -215,17 +235,27 @@ uint8_t read_byte_PCE(uint32_t address)
ret = ((ret & 0x01) << 7) | ((ret & 0x02) << 5) | ((ret & 0x04) << 3) | ((ret & 0x08) << 1) | ((ret & 0x10) >> 1) | ((ret & 0x20) >> 3) | ((ret & 0x40) >> 5) | ((ret & 0x80) >> 7); ret = ((ret & 0x01) << 7) | ((ret & 0x02) << 5) | ((ret & 0x04) << 3) | ((ret & 0x08) << 1) | ((ret & 0x10) >> 1) | ((ret & 0x20) >> 3) | ((ret & 0x40) >> 5) | ((ret & 0x80) >> 7);
} }
// Set CS(PL4) and RD(PH3) as HIGH
PORTL |= (1 << 4);
PORTH |= (1 << 3);
//return read data //return read data
return ret; return ret;
}
void data_output_PCE () {
// Set Data Pins (D0-D7) to Output
DDRC = 0xFF;
}
void data_input_PCE () {
// Set Data Pins (D0-D7) to Input
DDRC = 0x00;
// Enable Internal Pullups
PORTC = 0xFF;
set_cs_rd_low_PCE();
} }
void write_byte_PCE(uint32_t address, uint8_t data) void write_byte_PCE(uint32_t address, uint8_t data)
{ {
//PORTH |= (1 << 3); // RD HIGH
set_address_PCE(address); set_address_PCE(address);
// Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total // Arduino running at 16Mhz -> one nop = 62.5ns -> 1000ns total
@ -240,9 +270,6 @@ void write_byte_PCE(uint32_t address, uint8_t data)
//write byte //write byte
PORTC = data; PORTC = data;
// Set Data Pins (D0-D7) to Output
DDRC = 0xFF;
// Set CS(PL4) and WR(PH5) as LOW // Set CS(PL4) and WR(PH5) as LOW
PORTL &= ~(1 << 4); PORTL &= ~(1 << 4);
PORTH &= ~(1 << 5); PORTH &= ~(1 << 5);
@ -253,12 +280,6 @@ void write_byte_PCE(uint32_t address, uint8_t data)
// Set CS(PL4) and WR(PH5) as HIGH // Set CS(PL4) and WR(PH5) as HIGH
PORTL |= (1 << 4); PORTL |= (1 << 4);
PORTH |= (1 << 5); PORTH |= (1 << 5);
// Set Data Pins (D0-D7) to Input
DDRC = 0x00;
// Enable Internal Pullups
PORTC = 0xFF;
} }
//Confirm the size of ROM - 128Kb, 256Kb, 384Kb, 512Kb, 768Kb or 1024Kb //Confirm the size of ROM - 128Kb, 256Kb, 384Kb, 512Kb, 768Kb or 1024Kb
@ -344,6 +365,7 @@ uint32_t detect_rom_size_PCE(void)
} }
else else
{ {
//rom_size = 1024;
//Another confirmation for 384KB because 384KB hucard has data in 0x0--0x40000 and 0x80000--0xA0000(0x40000 is mirror of 0x00000) //Another confirmation for 384KB because 384KB hucard has data in 0x0--0x40000 and 0x80000--0xA0000(0x40000 is mirror of 0x00000)
rom_size = 384; rom_size = 384;
} }
@ -376,7 +398,7 @@ uint32_t detect_rom_size_PCE(void)
} }
/* Must be address_start and address_end should be 512 byte aligned */ /* Must be address_start and address_end should be 512 byte aligned */
void read_bank_PCE(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size) void read_bank_PCE_ROM(uint32_t address_start, uint32_t address_end, uint32_t *processed_size, uint32_t total_size, uint32_t *crcp)
{ {
uint32_t currByte; uint32_t currByte;
uint16_t c; uint16_t c;
@ -385,12 +407,23 @@ void read_bank_PCE(uint32_t address_start, uint32_t address_end, uint32_t *proce
for (c = 0; c < 512; c++) { for (c = 0; c < 512; c++) {
sdBuffer[c] = read_byte_PCE(currByte + c); sdBuffer[c] = read_byte_PCE(currByte + c);
} }
if (crcp != NULL) {
*crcp = calculate_crc32(512, sdBuffer, *crcp);
}
myFile.write(sdBuffer, 512); myFile.write(sdBuffer, 512);
*processed_size += 512; *processed_size += 512;
draw_progressbar(*processed_size, total_size); draw_progressbar(*processed_size, total_size);
} }
} }
void read_bank_PCE_RAM(uint32_t address_start, int block_index)
{
uint32_t start = address_start + block_index * 512;
for (uint16_t c = 0; c < 512; c++) {
sdBuffer[c] = read_byte_PCE(start + c);
}
}
//Get line from file and convert upper case to lower case //Get line from file and convert upper case to lower case
void skip_line(SdFile* readfile) void skip_line(SdFile* readfile)
{ {
@ -452,10 +485,10 @@ uint32_t calculate_crc32(int n, unsigned char c[], uint32_t r)
return r; return r;
} }
void crc_search(char *file_p, char *folder_p, uint32_t rom_size) void crc_search(char *file_p, char *folder_p, uint32_t rom_size, uint32_t crc)
{ {
SdFile rom, script; SdFile rom, script;
uint32_t r, crc, processedsize; uint32_t r, processedsize;
char gamename[100]; char gamename[100];
char crc_file[9], crc_search[9]; char crc_file[9], crc_search[9];
uint8_t flag; uint8_t flag;
@ -471,23 +504,7 @@ void crc_search(char *file_p, char *folder_p, uint32_t rom_size)
{ {
//Initialize flag as error //Initialize flag as error
flag = CHKSUM_ERROR; flag = CHKSUM_ERROR;
crc = 0xFFFFFFFFUL; //Initialize CRC
display_Clear();
println_Msg(F("Calculating chksum..."));
processedsize = 0;
draw_progressbar(0, rom_size * 1024UL); //Initialize progress bar
while (rom.available())
{
r = rom.read(sdBuffer, 512);
crc = calculate_crc32(r, sdBuffer, crc);
processedsize += r;
draw_progressbar(processedsize, rom_size * 1024UL);
}
crc = crc ^ 0xFFFFFFFFUL; //Finish CRC calculation and progress bar crc = crc ^ 0xFFFFFFFFUL; //Finish CRC calculation and progress bar
draw_progressbar(rom_size * 1024UL, rom_size * 1024UL);
//Display calculated CRC //Display calculated CRC
sprintf(crc_file, "%08lX", crc); sprintf(crc_file, "%08lX", crc);
@ -540,8 +557,23 @@ void crc_search(char *file_p, char *folder_p, uint32_t rom_size)
} }
void unlock_tennokoe_bank_RAM()
{
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68
write_byte_PCE(0x0F0000, 0x00); //Unlock RAM sequence 2 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 3 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
}
void read_tennokoe_bank_PCE(void) void lock_tennokoe_bank_RAM()
{
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
write_byte_PCE(0x0F0001, 0x00); //Lock RAM sequence 2 Bank 78
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
}
void read_tennokoe_bank_PCE(int bank_index)
{ {
uint32_t processed_size = 0; uint32_t processed_size = 0;
uint32_t verify_loop; uint32_t verify_loop;
@ -550,25 +582,28 @@ void read_tennokoe_bank_PCE(void)
//clear the screen //clear the screen
display_Clear(); display_Clear();
println_Msg(F("RAM size: 8KB")); println_Msg(F("RAM bank size: 2KB"));
// Get name, add extension and convert to char array for sd lib // Get name, add extension and convert to char array for sd lib
strcpy(fileName, "BANKRAM"); sprintf(fileName, "BANKRAM%d.sav", bank_index+1);
strcat(fileName, ".sav");
// create a new folder for the save file // create a new folder for the save file
EEPROM_readAnything(0, foldern); EEPROM_readAnything(0, foldern);
sprintf(folder, "PCE/ROM/%s/%d", romName, foldern); sd.chdir("/");
sprintf(folder, "PCE/ROM/%d", foldern);
sd.mkdir(folder, true); sd.mkdir(folder, true);
sd.chdir(folder); sd.chdir(folder);
println_Msg(F("Saving RAM...")); print_Msg(F("Saving RAM to "));
print_Msg(folder);
print_Msg(F("/"));
println_Msg(fileName);
display_Update(); display_Update();
// write new folder number back to eeprom // write new folder number back to eeprom
foldern = foldern + 1; foldern = foldern + 1;
EEPROM_writeAnything(0, foldern); EEPROM_writeAnything(0, foldern);
//open file on sd card //open file on sd card
if (!myFile.open(fileName, O_RDWR | O_CREAT)) { if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
print_Error(F("Can't create file on SD"), true); print_Error(F("Can't create file on SD"), true);
@ -576,49 +611,54 @@ void read_tennokoe_bank_PCE(void)
pin_read_write_PCE(); pin_read_write_PCE();
//Initialize progress bar by setting processed size as 0 for (int block_index = 0; block_index < 4; block_index++) {
draw_progressbar(0, 8 * 1024UL); //Unlock Tennokoe Bank RAM
//Disable interrupts
noInterrupts();
data_output_PCE();
unlock_tennokoe_bank_RAM();
data_input_PCE();
//Unlock Tennokoe Bank RAM //Read Tennokoe bank RAM
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68 read_bank_PCE_RAM(0x080000 + 2048UL*bank_index, block_index);
write_byte_PCE(0x0F0000, 0x0); //Unlock RAM sequence 2 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 3 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
//Read Tennokoe bank RAM //Lock Tennokoe Bank RAM
read_bank_PCE(0x080000, 0x080000 + 8 * 1024UL, &processed_size, 8 * 1024UL); data_output_PCE();
lock_tennokoe_bank_RAM();
data_input_PCE();
//Enable interrupts
interrupts();
myFile.seekSet(0); // Go back to file beginning // hexdump:
processed_size = 0; // for (int c = 0; c < 512; c += 16) {
// for (int i = 0; i < 16; i++) {
// uint8_t b = sdBuffer[c + i];
// print_Msg_PaddedHexByte(b);
// //print_Msg(F(" "));
// }
// println_Msg(F(""));
// }
//Verify Tennokoe bank RAM if (block_index == 0) {
for (verify_loop = 0; verify_loop < 8 * 1024UL; verify_loop++) print_Msg(F("header: "));
{ for (int i = 0; i < 4; i++) {
if (myFile.read() != read_byte_PCE(verify_loop + 0x080000)) uint8_t b = sdBuffer[i];
{ print_Msg_PaddedHexByte(b);
verify_flag = 0; }
draw_progressbar(8 * 1024UL, 8 * 1024UL); println_Msg(F(""));
break;
} }
draw_progressbar(verify_loop, 8 * 1024UL); if (block_index == 0 && sdBuffer[2] == 0x42 && sdBuffer[3] == 0x4D) {
if (sdBuffer[0] != 0x48 || sdBuffer[1] != 0x55) {
sdBuffer[0] = 0x48; // H
sdBuffer[1] = 0x55; // U
println_Msg(F("Corrected header"));
} else {
println_Msg(F("Header is correct"));
}
}
myFile.write(sdBuffer, 512);
} }
//If verify flag is 0, verify failed
if (verify_flag == 1)
{
println_Msg(F("Verify OK..."));
}
else
{
println_Msg(F("Verify failed..."));
}
//Lock Tennokoe Bank RAM
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
write_byte_PCE(0x0F0001, 0x0); //Lock RAM sequence 2 Bank 78
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
pin_init_PCE(); pin_init_PCE();
//Close the file: //Close the file:
@ -626,12 +666,9 @@ void read_tennokoe_bank_PCE(void)
} }
void write_tennokoe_bank_PCE(void) void write_tennokoe_bank_PCE(int bank_index)
{ {
uint32_t readwrite_loop, verify_loop; //Display file Browser and wait user to select a file. Size must be 2KB.
uint32_t verify_flag = 1;
//Display file Browser and wait user to select a file. Size must be 8KB.
filePath[0] = '\0'; filePath[0] = '\0';
sd.chdir("/"); sd.chdir("/");
fileBrowser(F("Select RAM file")); fileBrowser(F("Select RAM file"));
@ -643,8 +680,8 @@ void write_tennokoe_bank_PCE(void)
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
fileSize = myFile.fileSize(); fileSize = myFile.fileSize();
if (fileSize != 8 * 1024UL) { if (fileSize != 2 * 1024UL) {
println_Msg(F("File must be 1MB")); println_Msg(F("File must be 2KB"));
display_Update(); display_Update();
myFile.close(); myFile.close();
wait(); wait();
@ -653,48 +690,67 @@ void write_tennokoe_bank_PCE(void)
pin_read_write_PCE(); pin_read_write_PCE();
//Unlock Tennokoe Bank RAM for (int block_index = 0; block_index < 4; block_index++) {
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68 for (uint16_t c = 0; c < 512; c++) {
write_byte_PCE(0x0F0000, 0x0); //Unlock RAM sequence 2 Bank 78 sdBuffer[c] = myFile.read();
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 3 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
//Write file to Tennokoe BANK RAM
for (readwrite_loop = 0; readwrite_loop < 8 * 1024UL; readwrite_loop++)
{
write_byte_PCE(0x080000 + readwrite_loop, myFile.read());
draw_progressbar(readwrite_loop, 8 * 1024UL);
}
myFile.seekSet(0); // Go back to file beginning
for (verify_loop = 0; verify_loop < 8 * 1024UL; verify_loop++)
{
if (myFile.read() != read_byte_PCE(verify_loop + 0x080000))
{
draw_progressbar(2 * 1024UL, 8 * 1024UL);
verify_flag = 0;
break;
} }
draw_progressbar(verify_loop, 8 * 1024UL); //Unlock Tennokoe Bank RAM
//Disable interrupts
noInterrupts();
data_output_PCE();
unlock_tennokoe_bank_RAM();
data_input_PCE();
//Write file to Tennokoe BANK RAM
data_output_PCE();
uint32_t offset = 0x080000 + (bank_index * 2048UL) + (block_index * 512UL);
for (uint16_t c = 0; c < 512; c++) {
write_byte_PCE(offset + c, sdBuffer[c]);
}
//Lock Tennokoe Bank RAM
lock_tennokoe_bank_RAM();
data_input_PCE();
//Enable interrupts
interrupts();
} }
//If verify flag is 0, verify failed // verify
if (verify_flag == 1) int diffcnt = 0;
{ myFile.seekSet(0);
for (int block_index = 0; block_index < 4; block_index++) {
//Unlock Tennokoe Bank RAM
//Disable interrupts
noInterrupts();
data_output_PCE();
unlock_tennokoe_bank_RAM();
data_input_PCE();
//Read Tennokoe bank RAM
read_bank_PCE_RAM(0x080000 + 2048UL*bank_index, block_index);
//Lock Tennokoe Bank RAM
data_output_PCE();
lock_tennokoe_bank_RAM();
data_input_PCE();
//Enable interrupts
interrupts();
int diffcnt = 0;
for (int c = 0; c < 512; c += 16) {
uint8_t ram_b = sdBuffer[c];
uint8_t file_b = myFile.read();
if (ram_b != file_b) {
diffcnt++;
}
}
}
if (diffcnt == 0) {
println_Msg(F("Verify OK...")); println_Msg(F("Verify OK..."));
} } else {
else
{
println_Msg(F("Verify failed...")); println_Msg(F("Verify failed..."));
print_Msg(diffcnt);
println_Msg(F(" bytes "));
print_Error(F("did not verify."), false);
} }
//Lock Tennokoe Bank RAM
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
write_byte_PCE(0x0F0001, 0x0); //Lock RAM sequence 2 Bank 78
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
pin_init_PCE(); pin_init_PCE();
// Close the file: // Close the file:
@ -716,8 +772,12 @@ void read_rom_PCE(void)
//clear the screen //clear the screen
display_Clear(); display_Clear();
rom_size = detect_rom_size_PCE(); rom_size = detect_rom_size_PCE();
if (pce_force_rom_size > 0) {
print_Msg(F("Detected size: ")); rom_size = pce_force_rom_size;
print_Msg(F("Forced size: "));
} else {
print_Msg(F("Detected size: "));
}
print_Msg(rom_size); print_Msg(rom_size);
println_Msg(F("KB")); println_Msg(F("KB"));
@ -727,11 +787,15 @@ void read_rom_PCE(void)
// create a new folder for the save file // create a new folder for the save file
EEPROM_readAnything(0, foldern); EEPROM_readAnything(0, foldern);
sprintf(folder, "PCE/ROM/%s/%d", romName, foldern); sd.chdir("/");
sprintf(folder, "PCE/ROM/%d", foldern);
sd.mkdir(folder, true); sd.mkdir(folder, true);
sd.chdir(folder); sd.chdir(folder);
println_Msg(F("Saving ROM...")); print_Msg(F("Saving ROM to "));
print_Msg(folder);
print_Msg(F("/"));
println_Msg(fileName);
display_Update(); display_Update();
// write new folder number back to eeprom // write new folder number back to eeprom
@ -748,29 +812,38 @@ void read_rom_PCE(void)
//Initialize progress bar by setting processed size as 0 //Initialize progress bar by setting processed size as 0
draw_progressbar(0, rom_size * 1024UL); draw_progressbar(0, rom_size * 1024UL);
uint32_t crc = 0xFFFFFFFFUL; //Initialize CRC
if (rom_size == 384) if (rom_size == 384)
{ {
//Read two sections. 0x000000--0x040000 and 0x080000--0x0A0000 for 384KB //Read two sections. 0x000000--0x040000 and 0x080000--0x0A0000 for 384KB
read_bank_PCE(0, 0x40000, &processed_size, rom_size * 1024UL); read_bank_PCE_ROM(0, 0x40000, &processed_size, rom_size * 1024UL, &crc);
read_bank_PCE(0x80000, 0xA0000, &processed_size, rom_size * 1024UL); read_bank_PCE_ROM(0x80000, 0xA0000, &processed_size, rom_size * 1024UL, &crc);
} }
else if (rom_size == 2560) else if (rom_size == 2560)
{ {
//Dump Street fighter II' Champion Edition //Dump Street fighter II' Champion Edition
read_bank_PCE(0, 0x80000, &processed_size, rom_size * 1024UL); //Read first bank read_bank_PCE_ROM(0, 0x80000, &processed_size, rom_size * 1024UL, &crc); //Read first bank
data_output_PCE();
write_byte_PCE(0x1FF0, 0xFF); //Display second bank write_byte_PCE(0x1FF0, 0xFF); //Display second bank
read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read second bank data_input_PCE();
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read second bank
data_output_PCE();
write_byte_PCE(0x1FF1, 0xFF); //Display third bank write_byte_PCE(0x1FF1, 0xFF); //Display third bank
read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read third bank data_input_PCE();
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read third bank
data_output_PCE();
write_byte_PCE(0x1FF2, 0xFF); //Display forth bank write_byte_PCE(0x1FF2, 0xFF); //Display forth bank
read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read forth bank data_input_PCE();
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read forth bank
data_output_PCE();
write_byte_PCE(0x1FF3, 0xFF); //Display fifth bank write_byte_PCE(0x1FF3, 0xFF); //Display fifth bank
read_bank_PCE(0x80000, 0x100000, &processed_size, rom_size * 1024UL); //Read fifth bank data_input_PCE();
read_bank_PCE_ROM(0x80000, 0x100000, &processed_size, rom_size * 1024UL, &crc); //Read fifth bank
} }
else else
{ {
//Read start form 0x000000 and keep reading until end of ROM //Read start form 0x000000 and keep reading until end of ROM
read_bank_PCE(0, rom_size * 1024UL, &processed_size, rom_size * 1024UL); read_bank_PCE_ROM(0, rom_size * 1024UL, &processed_size, rom_size * 1024UL, &crc);
} }
pin_init_PCE(); pin_init_PCE();
@ -779,23 +852,31 @@ void read_rom_PCE(void)
myFile.close(); myFile.close();
//CRC search and rename ROM //CRC search and rename ROM
crc_search(fileName, folder, rom_size); crc_search(fileName, folder, rom_size, crc);
} }
// PC Engine Menu // PC Engine Menu
void pceMenu() { void pceMenu() {
// create menu with title and 7 options to choose from // create menu with title and 7 options to choose from
unsigned char mainMenu; unsigned char mainMenu;
if (pce_internal_mode == HUCARD) if (pce_internal_mode == HUCARD || pce_internal_mode == HUCARD_NOSWAP)
{ {
// Copy menuOptions out of progmem sprintf(pceCartMenuItem2, "Read RAM Bank %d", tennokoe_bank_index+1);
convertPgm(menuOptionspceCart, 4); sprintf(pceCartMenuItem3, "Write RAM Bank %d", tennokoe_bank_index+1);
mainMenu = question_box(F("PCE HuCARD menu"), menuOptions, 4, 0); strcpy(menuOptionspceCart[0], pceCartMenuItem1);
strcpy(menuOptionspceCart[1], pceCartMenuItem2);
strcpy(menuOptionspceCart[2], pceCartMenuItem3);
strcpy(menuOptionspceCart[3], pceCartMenuItem4);
strcpy(menuOptionspceCart[4], pceCartMenuItem5);
strcpy(menuOptionspceCart[5], pceCartMenuItem6);
if (pce_force_rom_size > 0) {
sprintf(pceCartMenuItem7, "ROM size now %dK", pce_force_rom_size);
} else {
sprintf(pceCartMenuItem7, "Force ROM size");
}
strcpy(menuOptionspceCart[6], pceCartMenuItem7);
mainMenu = question_box(F("PCE HuCARD menu"), menuOptionspceCart, 7, 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)
@ -808,15 +889,28 @@ void pceMenu() {
break; break;
case 1: case 1:
display_Clear(); display_Clear();
read_tennokoe_bank_PCE(); read_tennokoe_bank_PCE(tennokoe_bank_index);
break; break;
case 2: case 2:
display_Clear(); display_Clear();
write_tennokoe_bank_PCE(); write_tennokoe_bank_PCE(tennokoe_bank_index);
break; break;
case 3: case 3:
resetArduino(); resetArduino();
break; break;
case 4:
if (tennokoe_bank_index < 3) {
tennokoe_bank_index++;
}
break;
case 5:
if (tennokoe_bank_index > 0) {
tennokoe_bank_index--;
}
break;
case 6:
pce_force_rom_size = 1024;
break;
} }
} }
else else