Add support for 768Kbit SRAM save type

Fixes a Segfault when loading Dezaemon 3D.

  * Unfortunately, Dezaemon 3D does not actually work yet. It appears to
    fail the SRAM test, which still needs further investigation.

Adds an option alias for sram256k to disambiguate with new sram768k option.
This commit is contained in:
Christopher Bonhage 2021-11-29 13:05:55 -05:00 committed by Simon Eriksson
parent 87ebca00b5
commit 6b7c2af8d4
6 changed files with 66 additions and 21 deletions

14
cen64.c
View file

@ -140,8 +140,18 @@ int cen64_main(int argc, const char **argv) {
break; break;
case CART_DB_SAVE_TYPE_SRAM_256KBIT: case CART_DB_SAVE_TYPE_SRAM_256KBIT:
if (options.sram_path == NULL) { if (options.sram_path == NULL) {
printf("Warning: cart saves to SRAM, but none specified (see -sram)\n"); printf("Warning: cart saves to 256kbit SRAM, but none specified (see -sram256k)\n");
open_save_file(NULL, 0x8000, &sram, NULL); open_save_file(NULL, 0x8000, &sram, NULL);
} else if (options.sram_size != 0x8000) {
printf("Warning: cart saves to 256kbit SRAM, but different size specified (see -sram256k)\n");
}
break;
case CART_DB_SAVE_TYPE_SRAM_768KBIT:
if (options.sram_path == NULL) {
printf("Warning: cart saves to 768kbit SRAM, but none specified (see -sram768k)\n");
open_save_file(NULL, 0x18000, &sram, NULL);
} else if (options.sram_size != 0x18000) {
printf("Warning: cart saves to 768kbit SRAM, but different size specified (see -sram768k)\n");
} }
break; break;
} }
@ -159,7 +169,7 @@ int cen64_main(int argc, const char **argv) {
} }
if (options.sram_path != NULL && if (options.sram_path != NULL &&
open_save_file(options.sram_path, 0x8000, &sram, NULL)) { open_save_file(options.sram_path, options.sram_size, &sram, NULL)) {
cen64_alloc_cleanup(); cen64_alloc_cleanup();
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View file

@ -18,6 +18,7 @@
static const struct cart_db_entry cart_db_table[] = { static const struct cart_db_entry cart_db_table[] = {
{"CDZ", "J", CART_DB_SAVE_TYPE_SRAM_768KBIT, "Dezaemon 3D"},
{"CFZ", "EJ", CART_DB_SAVE_TYPE_SRAM_256KBIT, "F-Zero X (NTSC)"}, {"CFZ", "EJ", CART_DB_SAVE_TYPE_SRAM_256KBIT, "F-Zero X (NTSC)"},
{"CLB", "EJ", CART_DB_SAVE_TYPE_EEPROM_4KBIT, "Mario Party (NTSC)"}, {"CLB", "EJ", CART_DB_SAVE_TYPE_EEPROM_4KBIT, "Mario Party (NTSC)"},
{"CP2", "J", CART_DB_SAVE_TYPE_FLASH_1MBIT, "Pokemon Stadium 2 (Japan)"}, {"CP2", "J", CART_DB_SAVE_TYPE_FLASH_1MBIT, "Pokemon Stadium 2 (Japan)"},

View file

@ -16,6 +16,7 @@ enum cart_db_save_type {
CART_DB_SAVE_TYPE_EEPROM_16KBIT, CART_DB_SAVE_TYPE_EEPROM_16KBIT,
CART_DB_SAVE_TYPE_FLASH_1MBIT, CART_DB_SAVE_TYPE_FLASH_1MBIT,
CART_DB_SAVE_TYPE_SRAM_256KBIT, CART_DB_SAVE_TYPE_SRAM_256KBIT,
CART_DB_SAVE_TYPE_SRAM_768KBIT,
}; };
struct cart_db_entry { struct cart_db_entry {

View file

@ -23,6 +23,7 @@ const struct cen64_options default_cen64_options = {
NULL, // eeprom_path NULL, // eeprom_path
0, // eeprom_size 0, // eeprom_size
NULL, // sram_path NULL, // sram_path
0, // sram_size
NULL, // flashram_path NULL, // flashram_path
0, // is_viewer_present 0, // is_viewer_present
NULL, // controller NULL, // controller
@ -122,6 +123,27 @@ int parse_options(struct cen64_options *options, int argc, const char *argv[]) {
} }
options->sram_path = argv[++i]; options->sram_path = argv[++i];
options->sram_size = 0x8000;
}
else if (!strcmp(argv[i], "-sram256k")) {
if ((i + 1) >= (argc - 1)) {
printf("-sram256k requires a path to the save file.\n\n");
return 1;
}
options->sram_path = argv[++i];
options->sram_size = 0x8000;
}
else if (!strcmp(argv[i], "-sram768k")) {
if ((i + 1) >= (argc - 1)) {
printf("-sram768k requires a path to the save file.\n\n");
return 1;
}
options->sram_path = argv[++i];
options->sram_size = 0x18000;
} }
else if (!strcmp(argv[i], "-flash")) { else if (!strcmp(argv[i], "-flash")) {
@ -279,7 +301,9 @@ void print_command_line_usage(const char *invokation_string) {
"Save Options:\n" "Save Options:\n"
" -eep4k <path> : Path to 4 kbit EEPROM save.\n" " -eep4k <path> : Path to 4 kbit EEPROM save.\n"
" -eep16k <path> : Path to 16 kbit EEPROM save.\n" " -eep16k <path> : Path to 16 kbit EEPROM save.\n"
" -sram <path> : Path to SRAM save.\n" " -sram <path> : Path to 256 kbit SRAM save (alias of -sram256k).\n"
" -sram256k <path> : Path to 256 kbit SRAM save.\n"
" -sram768k <path> : Path to 768 kbit SRAM save.\n"
" -flash <path> : Path to FlashRAM save.\n" " -flash <path> : Path to FlashRAM save.\n"
" For mempak see controller options.\n" " For mempak see controller options.\n"

View file

@ -22,6 +22,7 @@ struct cen64_options {
const char *eeprom_path; const char *eeprom_path;
size_t eeprom_size; size_t eeprom_size;
const char *sram_path; const char *sram_path;
size_t sram_size;
const char *flashram_path; const char *flashram_path;
int is_viewer_present; int is_viewer_present;

View file

@ -57,14 +57,17 @@ static int pi_dma_read(struct pi_controller *pi) {
if (source & 0x7) if (source & 0x7)
length -= source & 0x7; length -= source & 0x7;
// SRAM and FlashRAM // Cartridge Domain 2 Address 2
if (dest >= 0x08000000 && dest < 0x08010000) { if (dest >= 0x08000000 && dest < 0x10000000) {
uint32_t addr = dest & 0x00FFFFF;
// SRAM // SRAM
if (pi->sram->ptr != NULL && addr + length <= 0x8000) if (pi->sram->ptr != NULL) {
memcpy((uint8_t *) (pi->sram->ptr) + addr, pi->bus->ri->ram + source, length); // SRAM bank selection bits are [19:18]
uint32_t sram_bank = (dest >> 18) & 3;
// SRAM bank capacity is 256Kbits (0x8000 bytes)
uint32_t sram_offset = (sram_bank * 0x8000) + (dest & 0x7FFF);
if (sram_offset + length <= pi->sram->size)
memcpy((uint8_t *) (pi->sram->ptr) + sram_offset, pi->bus->ri->ram + source, length);
}
// FlashRAM: Save the RDRAM destination address. Writing happens // FlashRAM: Save the RDRAM destination address. Writing happens
// after the system sends the flash write command (handled in // after the system sends the flash write command (handled in
// write_flashram) // write_flashram)
@ -111,23 +114,28 @@ static int pi_dma_write(struct pi_controller *pi) {
else if ((source & 0x05000000) == 0x05000000) else if ((source & 0x05000000) == 0x05000000)
dd_dma_write(pi->bus->dd, source, dest, length); dd_dma_write(pi->bus->dd, source, dest, length);
// SRAM and FlashRAM // Cartridge Domain 2 Address 2
else if (source >= 0x08000000 && source < 0x08010000) { else if (source >= 0x08000000 && source < 0x10000000) {
uint32_t addr = source & 0x00FFFFF; // SRAM
if (pi->sram->ptr != NULL) {
if (pi->sram->ptr != NULL && addr + length <= 0x8000) // SRAM bank selection bits are [19:18]
memcpy(pi->bus->ri->ram + dest, (const uint8_t *) (pi->sram->ptr) + addr, length); uint32_t sram_bank = (source >> 18) & 3;
// SRAM bank capacity is 256Kbits (0x8000 bytes)
uint32_t sram_offset = (sram_bank * 0x8000) + (source & 0x7FFF);
if (sram_offset + length <= pi->sram->size)
memcpy(pi->bus->ri->ram + dest, (const uint8_t *) (pi->sram->ptr) + sram_offset, length);
}
// FlashRAM
else if (pi->flashram.data != NULL) { else if (pi->flashram.data != NULL) {
// SRAM uint32_t flashram_offset = source & 0x1FFFF;
// FlashRAM status
if (pi->flashram.mode == FLASHRAM_STATUS) { if (pi->flashram.mode == FLASHRAM_STATUS) {
uint64_t status = htonll(pi->flashram.status); uint64_t status = htonll(pi->flashram.status);
memcpy(pi->bus->ri->ram + dest, &status, 8); memcpy(pi->bus->ri->ram + dest, &status, 8);
} }
// FlashRAM read
// FlashRAM
else if (pi->flashram.mode == FLASHRAM_READ) else if (pi->flashram.mode == FLASHRAM_READ)
memcpy(pi->bus->ri->ram + dest, pi->flashram.data + addr * 2, length); memcpy(pi->bus->ri->ram + dest, pi->flashram.data + flashram_offset * 2, length);
} }
} }