Skip to content
Snippets Groups Projects
Commit 45db21fd authored by Geo Ster's avatar Geo Ster
Browse files

Implement reads/writes MCH_RICM/MCH_DRD

* The BIOS tries to write to 0x1000f430/0x1000f440 which contain the
registers MCH_RICM/MCH_DRD. Saldy these registers are quite undocumented.
So the writing logic has been taken from PCSX2:
https://github.com/PCSX2/pcsx2/blob/master/pcsx2/HwWrite.cpp#L237
Forgive me, for I have sinned.
parent 688bc87f
No related branches found
No related tags found
No related merge requests found
......@@ -46,8 +46,36 @@ template <typename T>
T ComponentManager::read(uint32_t addr)
{
uint32_t vaddr = addr & KUSEG_MASKS[addr >> 29];
T data = *(T*)&memory[vaddr];
return data;
switch (vaddr)
{
case 0x1000f440:
{
uint8_t SOP = (MCH_RICM >> 6) & 0xF;
uint8_t SA = (MCH_RICM >> 16) & 0xFFF;
if (!SOP)
{
switch (SA)
{
case 0x21:
if (rdram_sdevid < 2)
{
rdram_sdevid++;
return 0x1F;
}
return 0;
case 0x23:
return 0x0D0D;
case 0x24:
return 0x0090;
case 0x40:
return MCH_RICM & 0x1F;
}
}
return 0;
}
default:
return *(T*)&memory[vaddr];
}
}
/* Instanciate the templates here so we can limit their types below */
......@@ -55,10 +83,35 @@ template <typename T>
void ComponentManager::write(uint32_t addr, T data)
{
uint32_t vaddr = addr & KUSEG_MASKS[addr >> 29];
*(T*)&memory[vaddr] = data;
if (addr == 0xb000f180) /* Record any console output */
switch (vaddr)
{
/* Record any console output */
case 0x1000f180:
{
console << (char)data;
console.flush();
break;
}
case 0x1000f430:
{
uint8_t SA = (data >> 16) & 0xFFF;
uint8_t SBC = (data >> 6) & 0xF;
if (SA == 0x21 && SBC == 0x1 && ((MCH_DRD >> 7) & 1) == 0)
rdram_sdevid = 0;
MCH_RICM = data & ~0x80000000;
break;
}
case 0x1000f440:
{
MCH_DRD = data;
break;
}
default:
*(T*)&memory[vaddr] = data;
break;
};
}
/* Template definitions. */
......
......@@ -25,4 +25,7 @@ public:
/* Components */
std::unique_ptr<EmotionEngine> ee;
uint8_t* memory;
uint32_t MCH_RICM = 0, MCH_DRD = 0;
uint8_t rdram_sdevid = 0;
};
\ No newline at end of file
......@@ -116,8 +116,6 @@ void EmotionEngine::write(uint32_t addr, T data)
*(T*)&scratchpad[addr & 0x3FFF] = data;
else
manager->write<T>(addr, data);
if (scratchpad[0x70003edd & 0x3FFF] == 0x33) __debugbreak();
}
void EmotionEngine::op_cop0()
......@@ -786,11 +784,13 @@ void EmotionEngine::op_mult()
uint16_t rs = instr.r_type.rs;
uint16_t rd = instr.r_type.rd;
int64_t result = (int64_t)gpr[rs].word[0] * (int64_t)gpr[rt].word[0];
int64_t reg1 = (int64_t)gpr[rs].dword[0];
int64_t reg2 = (int64_t)gpr[rt].dword[0];
int64_t result = reg1 * reg2;
gpr[rd].dword[0] = lo0 = (int32_t)(result & 0xFFFFFFFF);
hi0 = (int32_t)(result >> 32);
log("MULT: GPR[{:d}] = LO0 = {:#x} and HI0 = {:#x}\n", rd, lo0, hi0);
log("MULT: GPR[{:d}] ({:#x}) * GPR[{:d}] ({:#x}) = {:#x} STORED IN GPR[{:d}] = LO0 = {:#x} and HI0 = {:#x}\n", rs, reg1, rt, reg2, result, rd, lo0, hi0);
}
void EmotionEngine::op_divu()
......@@ -803,7 +803,7 @@ void EmotionEngine::op_divu()
lo0 = (int64_t)(int32_t)(gpr[rs].word[0] / gpr[rt].word[0]);
hi0 = (int64_t)(int32_t)(gpr[rs].word[0] % gpr[rt].word[0]);
log("DIVU: LO0 = GPR[{:d}] ({:#x}) / GPR[{:d}] ({:#x})\n", rs, gpr[rs].word[0], rt, gpr[rt].word[0]);
log("DIVU: GPR[{:d}] ({:#x}) / GPR[{:d}] ({:#x}) OUTPUT LO0 = {:#x} and HI0 = {:#x}\n", rs, gpr[rs].word[0], rt, gpr[rt].word[0], lo0, hi0);
}
else
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment