Update PCW.ino

- Added : size detection for Multi-pack cartridges
- Modified : dump function for Multi-pack cartridges
- Added : timing fixes needed for recent HW revisions
This commit is contained in:
PsyK0p4T 2023-11-02 17:21:52 +01:00 committed by GitHub
parent b11330d31b
commit 8fdd93f293
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -92,7 +92,8 @@
#define ADDR_WRITE DDRC = 0xFF // [OUTPUT] #define ADDR_WRITE DDRC = 0xFF // [OUTPUT]
#define DETECTION_SIZE 64 #define DETECTION_SIZE 64
boolean multipack = 0; // Multi-Pack Cart uint32_t rom_size;
boolean multipack;
byte bank0; byte bank0;
byte bank1; byte bank1;
@ -127,9 +128,6 @@ void setup_PCW() {
// Set Unused Pins HIGH // Set Unused Pins HIGH
PORTJ |= (1 << 0); // TIME(PJ0) PORTJ |= (1 << 0); // TIME(PJ0)
// Multi-Pack Cart Check
check_multi_PCW();
strcpy(romName, "PCW"); strcpy(romName, "PCW");
mode = mode_PCW; mode = mode_PCW;
@ -151,10 +149,11 @@ void pcwMenu() {
case 0: case 0:
// Read ROM // Read ROM
sd.chdir("/"); sd.chdir("/");
check_multi_PCW();
if (multipack) if (multipack)
readMultiROM_PCW(); readMultiROM_PCW();
else else
readROM_PCW(); readSingleROM_PCW();
sd.chdir("/"); sd.chdir("/");
break; break;
@ -370,99 +369,53 @@ void write_ram_byte_1B_PCW(unsigned long address, unsigned char data) {
NAND_1B_HIGH; NAND_1B_HIGH;
} }
//============================================================================== //******************************************
// Overload Multi-Pack Bank Switch // SINGLE-PACK FUNCTIONS
// //******************************************
// Known Multi-Pack Carts (Yellow Label Carts)
// 0BD400 [PS] (2MB Version)
// 0BD400 [PS] (4MB Version)
// 0BF400 [PL]
// 1BF400 [PZ]
// 8BD400 [CR]
// 8BF400 [LP]
// 9BF400 [SLP] (Undumped)
// Per Overload, identify multi-pack cart by reading 0x3FFA-0x3FFE uint32_t detect_rom_size_PCW(void) {
// Multi-Pack carts are non-zero uint8_t read_byte;
// 0x3FFA - Current Cartridge Bank uint8_t current_byte;
// 0x3FFC - Value to Switch to Cartridge Bank 0 uint8_t detect_1m, detect_2m;
// 0x3FFD - Value to Switch to Cartridge Bank 1
// 0x3FFE - Last Value written to 0xFFFF
// Bank Settings for 2MB //Initialize variables
// Write 0x28 to 0xFFFF to read 1st half of ROM detect_1m = 0;
// Write 0x2E to 0xFFFF to read 2nd half of ROM detect_2m = 0;
// Bank Settings for 4MB //Confirm where mirror address starts from (1MB, 2MB or 4MB)
// Write 0x20 to 0xFFFF to read 1st half of ROM for (current_byte = 0; current_byte < DETECTION_SIZE; current_byte++) {
// Write 0x31 to 0xFFFF to read 2nd half of ROM if ((current_byte != detect_1m) && (current_byte != detect_2m)) {
//If none matched, size is 4MB
break;
}
// MULTI-PACK CART CHECK read_byte = read_rom_byte_PCW(current_byte);
void check_multi_PCW() {
read_setup_PCW(); if (current_byte == detect_1m) {
byte tempbyte = read_rom_byte_PCW(0x3FFC); // Bank 0 Switch if (read_rom_byte_PCW(0x100000 + current_byte) == read_byte) {
if (tempbyte) { detect_1m++;
bank0 = tempbyte; // Store Bank 0 Switch }
tempbyte = read_rom_byte_PCW(0x3FFD); // Bank 1 Switch }
if (tempbyte) { if (current_byte == detect_2m) {
bank1 = tempbyte; // Store Bank 1 Switch if (read_rom_byte_PCW(0x200000 + current_byte) == read_byte) {
// Check for 00s detect_2m++;
tempbyte = read_rom_byte_PCW(0x3FFB); // Should be 00
if (!tempbyte) {
tempbyte = read_rom_byte_PCW(0x3FFF); // Should be 00
if (!tempbyte)
multipack = 1; // Flag Multi-Cart
else {
bank0 = 0;
bank1 = 0;
}
} }
} }
} }
}
void write_bank_byte_PCW(unsigned char data) { //ROM size detection
NAND_1A_LOW; if (detect_1m == DETECTION_SIZE) {
NAND_1A_HIGH; rom_size = 0x100000;
NAND_1B_LOW; } else if (detect_2m == DETECTION_SIZE) {
// Write to Address 0xFFFF rom_size = 0x200000;
PORTL = 0x00; } else {
PORTK = 0xFF; // A8-A15 rom_size = 0x400000;
// Latch Address on AD0-AD7
ADDR_WRITE;
LE_HIGH; // Latch Enable
PORTC = 0xFF; // A0-A7
LE_LOW; // Address Latched
// Write Data on AD0-AD7 - WE LOW ~728-736ns
WE_LOW;
PORTC = data;
__asm__("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");
WE_HIGH;
NAND_1B_HIGH;
}
void switchBank_PCW(int bank) {
if (bank == 1) { // Upper Half
write_bank_byte_PCW(bank1);
} else { // Lower Half (default)
write_bank_byte_PCW(bank0);
} }
return rom_size;
} }
//****************************************** void readSingleROM_PCW() {
// READ ROM FUNCTIONS
//******************************************
void readROM_PCW() {
// Setup read mode // Setup read mode
read_setup_PCW(); read_setup_PCW();
@ -473,7 +426,6 @@ void readROM_PCW() {
print_Msg(rom_size / 1024 / 1024); print_Msg(rom_size / 1024 / 1024);
print_Msg("MB SINGLE-PACK"); print_Msg("MB SINGLE-PACK");
println_Msg(F("")); println_Msg(F(""));
display_Update();
// Create file // Create file
strcpy(fileName, romName); strcpy(fileName, romName);
@ -516,22 +468,112 @@ void readROM_PCW() {
// Wait for user input // Wait for user input
println_Msg(F("")); println_Msg(F(""));
// Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1); print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
//******************************************
// MULTI-PACK FUNCTIONS
//******************************************
// Known Multi-Pack Carts (Yellow Label Carts)
// 0BD400 [PS] (2MB Version)
// 0BD400 [PS] (4MB Version)
// 0BF400 [PL]
// 1BF400 [PZ]
// 8BD400 [CR]
// 8BF400 [LP]
// 9BF400 [SLP] (Undumped)
// Per Overload, identify multi-pack cart by reading 0x3FFA-0x3FFE. Multi-Pack carts are non-zero.
// 0x3FFA - Current Cartridge Bank
// 0x3FFC - Value to Switch to Cartridge Bank 0
// 0x3FFD - Value to Switch to Cartridge Bank 1
// 0x3FFE - Last Value written to 0xFFFF
// Bank Settings for 2MB
// Write 0x28 to 0xFFFF to read 1st half of ROM
// Write 0x2E to 0xFFFF to read 2nd half of ROM
// Bank Settings for 4MB
// Write 0x20 to 0xFFFF to read 1st half of ROM
// Write 0x31 to 0xFFFF to read 2nd half of ROM
void check_multi_PCW() {
// init variables
read_setup_PCW();
multipack = 0;
bank0 = 0;
bank1 = 0;
byte tempbyte = read_rom_byte_PCW(0x3FFC); // Check for a bank 0 switch value
if (tempbyte) {
bank0 = tempbyte; // Store bank 0 switch value
tempbyte = read_rom_byte_PCW(0x3FFD); // Check for a bank 1 switch value
if (tempbyte) {
bank1 = tempbyte; // Store bank 1 switch value
if (!read_rom_byte_PCW(0x3FFB) && !read_rom_byte_PCW(0x3FFF)) { // Check for 00s
multipack = 1; // Flag as multi-pack
display_Clear();
if ((bank0 == 0x28) && (bank1 == 0x2E)) // 2MB multi-pack cart
rom_size = 0x200000;
else if ((bank0 == 0x20) && (bank1 == 0x31)) // 4MB multi-pack cart
rom_size = 0x400000;
else { // Warn for unknown bank switch values, size set to 4MB
println_Msg(F("Warning: Unknown cart size"));
rom_size = 0x400000;
}
}
}
}
}
void write_bank_byte_PCW(unsigned char data) {
NAND_1A_LOW;
NAND_1A_HIGH;
NAND_1B_LOW;
// Write to Address 0xFFFF
PORTL = 0x00;
PORTK = 0xFF; // A8-A15
// Latch Address on AD0-AD7
ADDR_WRITE;
LE_HIGH; // Latch Enable
PORTC = 0xFF; // A0-A7
LE_LOW; // Address Latched
// Write Data on AD0-AD7 - WE LOW ~728-736ns
WE_LOW;
PORTC = data;
for (unsigned int x = 0; x < 40; x++)
__asm__("nop\n\t");
WE_HIGH;
NAND_1B_HIGH;
}
void switchBank_PCW(int bank) {
if (bank == 1) { // Upper Half
write_bank_byte_PCW(bank1);
} else { // Lower Half (default)
write_bank_byte_PCW(bank0);
}
}
void readMultiROM_PCW() { void readMultiROM_PCW() {
print_Msg(F("READING "));
print_Msg(rom_size / 1024 / 1024);
print_Msg("MB MULTI-PACK");
println_Msg(F(""));
// Create file
strcpy(fileName, romName); strcpy(fileName, romName);
strcat(fileName, ".pcw"); strcat(fileName, ".pcw");
EEPROM_readAnything(0, foldern); EEPROM_readAnything(0, foldern);
sprintf(folder, "PCW/ROM/%d", foldern); sprintf(folder, "PCW/ROM/%d", foldern);
sd.mkdir(folder, true); sd.mkdir(folder, true);
sd.chdir(folder); sd.chdir(folder);
display_Clear();
print_STR(saving_to_STR, 0); print_STR(saving_to_STR, 0);
print_Msg(folder); print_Msg(folder);
println_Msg(F("/...")); println_Msg(F("/..."));
@ -544,41 +586,37 @@ void readMultiROM_PCW() {
print_FatalError(sd_error_STR); print_FatalError(sd_error_STR);
} }
display_Clear();
println_Msg(F("READING MULTI-PACK"));
println_Msg(F(""));
display_Update();
// Init progress bar // Init progress bar
uint32_t progress = 0; uint32_t progress = 0;
draw_progressbar(0, 0x400000); draw_progressbar(0, rom_size);
read_setup_PCW();
// Lower Half // Lower Half
read_setup_PCW();
switchBank_PCW(0); switchBank_PCW(0);
for (unsigned long address = 0; address < 0x200000; address += 512) { // 2MB for (unsigned long address = 0; address < (rom_size / 2); address += 512) {
for (unsigned int x = 0; x < 512; x++) { for (unsigned int x = 0; x < 512; x++) {
sdBuffer[x] = read_rom_byte_PCW(address + x); sdBuffer[x] = read_rom_byte_PCW(address + x);
} }
myFile.write(sdBuffer, 512); myFile.write(sdBuffer, 512);
progress += 512; progress += 512;
draw_progressbar(progress, 0x400000); draw_progressbar(progress, rom_size);
} }
read_setup_PCW();
// Upper Half // Upper Half
read_setup_PCW();
switchBank_PCW(1); switchBank_PCW(1);
for (unsigned long address = 0x200000; address < 0x400000; address += 512) { // 2MB for (unsigned long address = 0x200000; address < (0x200000 + (rom_size / 2)); address += 512) {
for (unsigned int x = 0; x < 512; x++) { for (unsigned int x = 0; x < 512; x++) {
sdBuffer[x] = read_rom_byte_PCW(address + x); sdBuffer[x] = read_rom_byte_PCW(address + x);
} }
myFile.write(sdBuffer, 512); myFile.write(sdBuffer, 512);
progress += 512; progress += 512;
draw_progressbar(progress, 0x400000); draw_progressbar(progress, rom_size);
} }
myFile.flush(); myFile.flush();
myFile.close(); myFile.close();
// Reset Bank // Reset Bank
switchBank_PCW(0); switchBank_PCW(0);
@ -588,55 +626,11 @@ void readMultiROM_PCW() {
// Wait for user input // Wait for user input
println_Msg(F("")); println_Msg(F(""));
// Prints string out of the common strings array either with or without newline
print_STR(press_button_STR, 1); print_STR(press_button_STR, 1);
display_Update(); display_Update();
wait(); wait();
} }
uint32_t detect_rom_size_PCW(void) {
uint32_t rom_size;
uint8_t read_byte;
uint8_t current_byte;
uint8_t detect_1m, detect_2m;
//Initialize variables
detect_1m = 0;
detect_2m = 0;
//Confirm where mirror address starts from (1MB, 2MB or 4MB)
for (current_byte = 0; current_byte < DETECTION_SIZE; current_byte++) {
if ((current_byte != detect_1m) && (current_byte != detect_2m)) {
//If none matched, size is 4MB
break;
}
read_byte = read_rom_byte_PCW(current_byte);
if (current_byte == detect_1m) {
if (read_rom_byte_PCW(0x100000 + current_byte) == read_byte) {
detect_1m++;
}
}
if (current_byte == detect_2m) {
if (read_rom_byte_PCW(0x200000 + current_byte) == read_byte) {
detect_2m++;
}
}
}
//ROM size detection
if (detect_1m == DETECTION_SIZE) {
rom_size = 0x100000;
} else if (detect_2m == DETECTION_SIZE) {
rom_size = 0x200000;
} else {
rom_size = 0x400000;
}
return rom_size;
}
//****************************************** //******************************************
// SRAM FUNCTIONS // SRAM FUNCTIONS
//****************************************** //******************************************