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;
case CART_DB_SAVE_TYPE_SRAM_256KBIT:
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);
} 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;
}
@ -159,7 +169,7 @@ int cen64_main(int argc, const char **argv) {
}
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();
return EXIT_FAILURE;
}

View file

@ -18,6 +18,7 @@
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)"},
{"CLB", "EJ", CART_DB_SAVE_TYPE_EEPROM_4KBIT, "Mario Party (NTSC)"},
{"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_FLASH_1MBIT,
CART_DB_SAVE_TYPE_SRAM_256KBIT,
CART_DB_SAVE_TYPE_SRAM_768KBIT,
};
struct cart_db_entry {

View file

@ -23,6 +23,7 @@ const struct cen64_options default_cen64_options = {
NULL, // eeprom_path
0, // eeprom_size
NULL, // sram_path
0, // sram_size
NULL, // flashram_path
0, // is_viewer_present
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_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")) {
@ -279,7 +301,9 @@ void print_command_line_usage(const char *invokation_string) {
"Save Options:\n"
" -eep4k <path> : Path to 4 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"
" For mempak see controller options.\n"

View file

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

View file

@ -57,14 +57,17 @@ static int pi_dma_read(struct pi_controller *pi) {
if (source & 0x7)
length -= source & 0x7;
// SRAM and FlashRAM
if (dest >= 0x08000000 && dest < 0x08010000) {
uint32_t addr = dest & 0x00FFFFF;
// Cartridge Domain 2 Address 2
if (dest >= 0x08000000 && dest < 0x10000000) {
// SRAM
if (pi->sram->ptr != NULL && addr + length <= 0x8000)
memcpy((uint8_t *) (pi->sram->ptr) + addr, pi->bus->ri->ram + source, length);
if (pi->sram->ptr != NULL) {
// 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
// after the system sends the flash write command (handled in
// write_flashram)
@ -111,23 +114,28 @@ static int pi_dma_write(struct pi_controller *pi) {
else if ((source & 0x05000000) == 0x05000000)
dd_dma_write(pi->bus->dd, source, dest, length);
// SRAM and FlashRAM
else if (source >= 0x08000000 && source < 0x08010000) {
uint32_t addr = source & 0x00FFFFF;
if (pi->sram->ptr != NULL && addr + length <= 0x8000)
memcpy(pi->bus->ri->ram + dest, (const uint8_t *) (pi->sram->ptr) + addr, length);
// Cartridge Domain 2 Address 2
else if (source >= 0x08000000 && source < 0x10000000) {
// SRAM
if (pi->sram->ptr != NULL) {
// SRAM bank selection bits are [19:18]
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) {
// SRAM
uint32_t flashram_offset = source & 0x1FFFF;
// FlashRAM status
if (pi->flashram.mode == FLASHRAM_STATUS) {
uint64_t status = htonll(pi->flashram.status);
memcpy(pi->bus->ri->ram + dest, &status, 8);
}
// FlashRAM
// 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);
}
}