Skip to content

Commit

Permalink
WIP RDRAM initialization patch
Browse files Browse the repository at this point in the history
  • Loading branch information
Rosalie241 committed Jan 12, 2025
1 parent 817ef45 commit ffc02ef
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


Expand Down
12 changes: 12 additions & 0 deletions Source/3rdParty/mupen64plus-core/src/device/rcp/ri/ri_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
47 changes: 32 additions & 15 deletions Source/3rdParty/mupen64plus-core/src/device/rdram/rdram.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include <string.h>

#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.
Expand Down Expand Up @@ -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 <stdio.h>
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;
}
}
Expand Down Expand Up @@ -155,7 +165,7 @@ void poweron_rdram(struct rdram* rdram)
}
}


#include <stdio.h>
void read_rdram_regs(void* opaque, uint32_t address, uint32_t* value)
{
struct rdram* rdram = (struct rdram*)opaque;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}


Expand All @@ -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)
{
Expand Down
4 changes: 2 additions & 2 deletions Source/3rdParty/mupen64plus-core/src/main/savestates.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit ffc02ef

Please sign in to comment.