From ffc02ef10a9cc9750790834dd8ae7549ea7d0d35 Mon Sep 17 00:00:00 2001 From: Rosalie Wanders Date: Sun, 12 Jan 2025 02:38:29 +0100 Subject: [PATCH] WIP RDRAM initialization patch --- .../src/device/rcp/ri/ri_controller.c | 1 + .../src/device/rcp/ri/ri_controller.h | 12 +++++ .../mupen64plus-core/src/device/rdram/rdram.c | 47 +++++++++++++------ .../mupen64plus-core/src/main/savestates.c | 4 +- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c index d74dd66c..a1aa0323 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.c @@ -33,6 +33,7 @@ void init_ri(struct ri_controller* ri, struct rdram* rdram) void poweron_ri(struct ri_controller* ri) { memset(ri->regs, 0, RI_REGS_COUNT*sizeof(uint32_t)); + //ri->regs[RI_SELECT_REG] = 1; } diff --git a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h index 940fa80e..7f853070 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h +++ b/Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h @@ -54,6 +54,18 @@ static osal_inline uint32_t ri_reg(uint32_t address) return (address & 0xffff) >> 2; } +static osal_inline uint32_t rdram_address_to_ri_address(uint32_t address) +{ + /* https://n64brew.dev/wiki/RDRAM_Interface#Memory_addressing */ + return (((address >> 20) == 0x03f) + ? (((address & 0x3FF))) | /* Adr[10:0] */ + (((address >> 10) & 0x1FF) << 11) | /* Adr[19:11] */ + (((address >> 10) & 0x1FF) << 20) /* Adr[28:20] */ + : (((address & 0x7FF))) | /* Adr[10:0] */ + (((address >> 11) & 0x1FF) << 11) | /* Adr[19:11] */ + (((address >> 20) & 0x3F) << 20)); /* Adr[28:20] */ +} + static osal_inline uint16_t ri_address_to_id_field(uint32_t address) { /* XXX: pure guessing, need harware test */ diff --git a/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c b/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c index 28065eaf..c90491b3 100644 --- a/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c +++ b/Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c @@ -31,7 +31,7 @@ #include #define RDRAM_BCAST_ADDRESS_MASK UINT32_C(0x00080000) - +#define RDRAM_MODE_CE_MASK UINT32_C(0x80000000) /* XXX: deduce # of RDRAM modules from it's total size * Assume only 2Mo RDRAM modules. @@ -63,15 +63,25 @@ static osal_inline uint16_t idfield_value(uint32_t device_id) | (((device_id >> 7) & 0x01) << 15)); } +static osal_inline uint16_t ri_address_to_idfield(uint32_t address) +{ + const uint32_t swapfield = 0; // TODO + + return (uint16_t)((((swapfield & ((address >> 11) & 0xFF)) | ((~swapfield & (address >> 20 & 0xFF))))) | /* AdrS[28:20] */ + (((address >> 29) & 0x3F) << 9)); /* AdrS[35:29] */ +} + +#include static size_t get_module(const struct rdram* rdram, uint32_t address) { size_t module; size_t modules = get_modules_count(rdram); - uint16_t id_field = ri_address_to_id_field(address); - + uint16_t id_field = ri_address_to_idfield(rdram_address_to_ri_address(address)); for (module = 0; module < modules; ++module) { - if (id_field == idfield_value(rdram->regs[module][RDRAM_DEVICE_ID_REG])) { + // TODO: move shift to elsewhere + // TODO: figure out why using more bits than 6 will fail this check + if (((id_field >> 1) & 0x3F) == (((idfield_value(rdram->regs[module][RDRAM_DEVICE_ID_REG]) >> 1 & 0x3F)))) { return module; } } @@ -155,7 +165,7 @@ void poweron_rdram(struct rdram* rdram) } } - +#include void read_rdram_regs(void* opaque, uint32_t address, uint32_t* value) { struct rdram* rdram = (struct rdram*)opaque; @@ -191,7 +201,7 @@ void write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t m /* HACK: Detect when current Control calibration is about to start, * so we can set corrupted rdram_dram handler */ - if (address & RDRAM_BCAST_ADDRESS_MASK && reg == RDRAM_DELAY_REG) { + /*if (address & RDRAM_BCAST_ADDRESS_MASK && reg == RDRAM_DELAY_REG) { map_corrupt_rdram(rdram, 1); } @@ -200,15 +210,7 @@ void write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t m * and let dynarec have it's fast_memory enabled. */ if (address & RDRAM_BCAST_ADDRESS_MASK && reg == RDRAM_MODE_REG) { - map_corrupt_rdram(rdram, 0); - - /* HACK: In the IPL3 procedure, at this point, - * the amount of detected memory can be found in s4 */ - size_t ipl3_rdram_size = r4300_regs(rdram->r4300)[20] & UINT32_C(0x0fffffff); - if (ipl3_rdram_size != rdram->dram_size) { - DebugMessage(M64MSG_WARNING, "IPL3 detected %u MB of RDRAM != %u MB", - (uint32_t) ipl3_rdram_size / (1024*1024), (uint32_t) rdram->dram_size / (1024*1024)); - } + // map_corrupt_rdram(rdram, 0); } @@ -230,6 +232,21 @@ void read_rdram_dram(void* opaque, uint32_t address, uint32_t* value) { struct rdram* rdram = (struct rdram*)opaque; uint32_t addr = rdram_dram_address(address); + size_t module = get_module(rdram, address); + + if (module == RDRAM_MAX_MODULES_COUNT) + { + *value = 0; + return; + } + + /* corrupt read value if CC value is not calibrated */ + uint32_t mode = rdram->regs[module][RDRAM_MODE_REG] ^ UINT32_C(0xc0c0c0c0); + if ((mode & RDRAM_MODE_CE_MASK) && (cc_value(mode) == 0)) + { + *value = 0; + return; + } if (address < rdram->dram_size) { diff --git a/Source/3rdParty/mupen64plus-core/src/main/savestates.c b/Source/3rdParty/mupen64plus-core/src/main/savestates.c index 664edd1c..69217f98 100644 --- a/Source/3rdParty/mupen64plus-core/src/main/savestates.c +++ b/Source/3rdParty/mupen64plus-core/src/main/savestates.c @@ -932,7 +932,7 @@ static int savestates_load_m64p(struct device* dev, char *filepath) */ for (i = 0; i < RDRAM_MAX_MODULES_COUNT; ++i) { memcpy(dev->rdram.regs[i], dev->rdram.regs[0], RDRAM_REGS_COUNT*sizeof(dev->rdram.regs[0][0])); - dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; + //dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; } /* dd state */ @@ -1286,7 +1286,7 @@ static int savestates_load_pj64(struct device* dev, */ for (i = 0; i < (SaveRDRAMSize / 0x200000); ++i) { memcpy(dev->rdram.regs[i], dev->rdram.regs[0], RDRAM_REGS_COUNT*sizeof(dev->rdram.regs[0][0])); - dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; + //dev->rdram.regs[i][RDRAM_DEVICE_ID_REG] = ri_address_to_id_field(i * 0x200000) << 2; } /* dd state */