mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-25 12:31:54 +01:00
Non swapped HuCARD adapter support. Changed Tennokoe Bank support to read/write files for each 2KB bank, one at a time.
This commit is contained in:
parent
2096ec7597
commit
a3417eeb23
@ -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,13 +226,6 @@ 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;
|
||||||
|
|
||||||
@ -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,19 +582,22 @@ 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
|
||||||
@ -576,48 +611,53 @@ 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
|
//Unlock Tennokoe Bank RAM
|
||||||
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68
|
//Disable interrupts
|
||||||
write_byte_PCE(0x0F0000, 0x0); //Unlock RAM sequence 2 Bank 78
|
noInterrupts();
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 3 Bank 78
|
data_output_PCE();
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
|
unlock_tennokoe_bank_RAM();
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
|
data_input_PCE();
|
||||||
|
|
||||||
//Read Tennokoe bank RAM
|
//Read Tennokoe bank RAM
|
||||||
read_bank_PCE(0x080000, 0x080000 + 8 * 1024UL, &processed_size, 8 * 1024UL);
|
read_bank_PCE_RAM(0x080000 + 2048UL*bank_index, block_index);
|
||||||
|
|
||||||
myFile.seekSet(0); // Go back to file beginning
|
|
||||||
processed_size = 0;
|
|
||||||
|
|
||||||
//Verify Tennokoe bank RAM
|
|
||||||
for (verify_loop = 0; verify_loop < 8 * 1024UL; verify_loop++)
|
|
||||||
{
|
|
||||||
if (myFile.read() != read_byte_PCE(verify_loop + 0x080000))
|
|
||||||
{
|
|
||||||
verify_flag = 0;
|
|
||||||
draw_progressbar(8 * 1024UL, 8 * 1024UL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
draw_progressbar(verify_loop, 8 * 1024UL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//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
|
//Lock Tennokoe Bank RAM
|
||||||
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
|
data_output_PCE();
|
||||||
write_byte_PCE(0x0F0001, 0x0); //Lock RAM sequence 2 Bank 78
|
lock_tennokoe_bank_RAM();
|
||||||
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
|
data_input_PCE();
|
||||||
|
//Enable interrupts
|
||||||
|
interrupts();
|
||||||
|
|
||||||
|
// hexdump:
|
||||||
|
// 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(""));
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (block_index == 0) {
|
||||||
|
print_Msg(F("header: "));
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
uint8_t b = sdBuffer[i];
|
||||||
|
print_Msg_PaddedHexByte(b);
|
||||||
|
}
|
||||||
|
println_Msg(F(""));
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
pin_init_PCE();
|
pin_init_PCE();
|
||||||
|
|
||||||
@ -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,47 +690,66 @@ void write_tennokoe_bank_PCE(void)
|
|||||||
|
|
||||||
pin_read_write_PCE();
|
pin_read_write_PCE();
|
||||||
|
|
||||||
|
for (int block_index = 0; block_index < 4; block_index++) {
|
||||||
|
for (uint16_t c = 0; c < 512; c++) {
|
||||||
|
sdBuffer[c] = myFile.read();
|
||||||
|
}
|
||||||
//Unlock Tennokoe Bank RAM
|
//Unlock Tennokoe Bank RAM
|
||||||
write_byte_PCE(0x0D0000, 0x68); //Unlock RAM sequence 1 Bank 68
|
//Disable interrupts
|
||||||
write_byte_PCE(0x0F0000, 0x0); //Unlock RAM sequence 2 Bank 78
|
noInterrupts();
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 3 Bank 78
|
data_output_PCE();
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 4 Bank 78
|
unlock_tennokoe_bank_RAM();
|
||||||
write_byte_PCE(0x0F0000, 0x73); //Unlock RAM sequence 5 Bank 78
|
data_input_PCE();
|
||||||
|
|
||||||
//Write file to Tennokoe BANK RAM
|
//Write file to Tennokoe BANK RAM
|
||||||
for (readwrite_loop = 0; readwrite_loop < 8 * 1024UL; readwrite_loop++)
|
data_output_PCE();
|
||||||
{
|
uint32_t offset = 0x080000 + (bank_index * 2048UL) + (block_index * 512UL);
|
||||||
write_byte_PCE(0x080000 + readwrite_loop, myFile.read());
|
for (uint16_t c = 0; c < 512; c++) {
|
||||||
draw_progressbar(readwrite_loop, 8 * 1024UL);
|
write_byte_PCE(offset + c, sdBuffer[c]);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//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
|
//Lock Tennokoe Bank RAM
|
||||||
write_byte_PCE(0x0D0000, 0x68); //Lock RAM sequence 1 Bank 68
|
lock_tennokoe_bank_RAM();
|
||||||
write_byte_PCE(0x0F0001, 0x0); //Lock RAM sequence 2 Bank 78
|
data_input_PCE();
|
||||||
write_byte_PCE(0x0C0001, 0x60); //Lock RAM sequence 3 Bank 60
|
//Enable interrupts
|
||||||
|
interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify
|
||||||
|
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..."));
|
||||||
|
} else {
|
||||||
|
println_Msg(F("Verify failed..."));
|
||||||
|
print_Msg(diffcnt);
|
||||||
|
println_Msg(F(" bytes "));
|
||||||
|
print_Error(F("did not verify."), false);
|
||||||
|
}
|
||||||
|
|
||||||
pin_init_PCE();
|
pin_init_PCE();
|
||||||
|
|
||||||
@ -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) {
|
||||||
|
rom_size = pce_force_rom_size;
|
||||||
|
print_Msg(F("Forced size: "));
|
||||||
|
} else {
|
||||||
print_Msg(F("Detected size: "));
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user