Core: Improve PI Dma
This commit is contained in:
parent
ae77b8d7f5
commit
079e493728
|
@ -93,6 +93,7 @@ bool CartridgeDomain2Address2Handler::DMARead()
|
|||
{
|
||||
m_Sram.DmaToSram(m_MMU.Rdram() + m_Reg.PI_DRAM_ADDR_REG,m_Reg.PI_CART_ADDR_REG - 0x08000000, PI_RD_LEN_REG);
|
||||
m_Reg.PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
m_Reg.PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
m_Reg.MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
return true;
|
||||
|
@ -101,6 +102,7 @@ bool CartridgeDomain2Address2Handler::DMARead()
|
|||
{
|
||||
m_FlashRam.DmaToFlashram(m_MMU.Rdram() + m_Reg.PI_DRAM_ADDR_REG, m_Reg.PI_CART_ADDR_REG - 0x08000000, PI_RD_LEN_REG);
|
||||
m_Reg.PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
m_Reg.PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
m_Reg.MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
return true;
|
||||
|
@ -120,6 +122,7 @@ void CartridgeDomain2Address2Handler::DMAWrite()
|
|||
{
|
||||
m_Sram.DmaFromSram(m_MMU.Rdram() + m_Reg.PI_DRAM_ADDR_REG, m_Reg.PI_CART_ADDR_REG - 0x08000000, PI_WR_LEN_REG);
|
||||
m_Reg.PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
m_Reg.PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
m_Reg.MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
}
|
||||
|
|
|
@ -29,13 +29,15 @@ PeripheralInterfaceReg::PeripheralInterfaceReg(uint32_t * PeripheralInterface) :
|
|||
{
|
||||
}
|
||||
|
||||
PeripheralInterfaceHandler::PeripheralInterfaceHandler(CMipsMemoryVM & MMU, CRegisters & Reg, CartridgeDomain2Address2Handler & Domain2Address2Handler) :
|
||||
PeripheralInterfaceHandler::PeripheralInterfaceHandler(CN64System & System, CMipsMemoryVM & MMU, CRegisters & Reg, CartridgeDomain2Address2Handler & Domain2Address2Handler) :
|
||||
PeripheralInterfaceReg(Reg.m_Peripheral_Interface),
|
||||
MIPSInterfaceReg(Reg.m_Mips_Interface),
|
||||
m_Domain2Address2Handler(Domain2Address2Handler),
|
||||
m_MMU(MMU),
|
||||
m_Reg(Reg),
|
||||
m_PC(Reg.m_PROGRAM_COUNTER)
|
||||
{
|
||||
System.RegisterCallBack(CN64SystemCB_Reset, this, (CN64System::CallBackFunction)stSystemReset);
|
||||
}
|
||||
|
||||
bool PeripheralInterfaceHandler::Read32(uint32_t Address, uint32_t & Value)
|
||||
|
@ -119,20 +121,20 @@ bool PeripheralInterfaceHandler::Write32(uint32_t Address, uint32_t Value, uint3
|
|||
|
||||
switch (Address & 0x1FFFFFFF)
|
||||
{
|
||||
case 0x04600000: PI_DRAM_ADDR_REG = (PI_DRAM_ADDR_REG & ~Mask) | (Value & Mask); break;
|
||||
case 0x04600000: PI_DRAM_ADDR_REG = ((PI_DRAM_ADDR_REG & ~Mask) | (Value & Mask)) & 0x00FFFFFE; break;
|
||||
case 0x04600004:
|
||||
PI_CART_ADDR_REG = (PI_CART_ADDR_REG & ~Mask) | (Value & Mask);
|
||||
PI_CART_ADDR_REG = ((PI_CART_ADDR_REG & ~Mask) | (Value & Mask)) & (g_Settings->LoadBool(Game_UnalignedDMA) ? 0xFFFFFFFF : 0xFFFFFFFE);
|
||||
if (EnableDisk())
|
||||
{
|
||||
DiskDMACheck();
|
||||
}
|
||||
break;
|
||||
case 0x04600008:
|
||||
PI_RD_LEN_REG = (PI_RD_LEN_REG & ~Mask) | (Value & Mask);
|
||||
PI_RD_LEN_REG = ((PI_RD_LEN_REG & ~Mask) | (Value & Mask)) & 0x00FFFFFF;
|
||||
PI_DMA_READ();
|
||||
break;
|
||||
case 0x0460000C:
|
||||
PI_WR_LEN_REG = (PI_WR_LEN_REG & ~Mask) | (Value & Mask);
|
||||
PI_WR_LEN_REG = ((PI_WR_LEN_REG & ~Mask) | (Value & Mask)) & 0x00FFFFFF;
|
||||
PI_DMA_WRITE();
|
||||
break;
|
||||
case 0x04600010:
|
||||
|
@ -142,8 +144,9 @@ bool PeripheralInterfaceHandler::Write32(uint32_t Address, uint32_t Value, uint3
|
|||
//}
|
||||
if ((Value & PI_CLR_INTR) != 0)
|
||||
{
|
||||
g_Reg->MI_INTR_REG &= ~MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
MI_INTR_REG &= ~MI_INTR_PI;
|
||||
PI_STATUS_REG &= ~PI_STATUS_INTERRUPT;
|
||||
m_Reg.CheckInterrupts();
|
||||
}
|
||||
break;
|
||||
case 0x04600014: PI_DOMAIN1_REG = ((PI_DOMAIN1_REG & ~Mask) | (Value & Mask)) & 0xFF; break;
|
||||
|
@ -163,6 +166,12 @@ bool PeripheralInterfaceHandler::Write32(uint32_t Address, uint32_t Value, uint3
|
|||
return true;
|
||||
}
|
||||
|
||||
void PeripheralInterfaceHandler::SystemReset(void)
|
||||
{
|
||||
PI_RD_LEN_REG = 0x0000007F;
|
||||
PI_WR_LEN_REG = 0x0000007F;
|
||||
}
|
||||
|
||||
void PeripheralInterfaceHandler::OnFirstDMA()
|
||||
{
|
||||
int16_t offset;
|
||||
|
@ -180,6 +189,7 @@ void PeripheralInterfaceHandler::OnFirstDMA()
|
|||
case CIC_NUS_6103:
|
||||
case CIC_NUS_6106:
|
||||
case CIC_NUS_5101:
|
||||
case CIC_MINI_IPL3:
|
||||
offset = 0x0318;
|
||||
break;
|
||||
case CIC_NUS_6105:
|
||||
|
@ -200,34 +210,30 @@ void PeripheralInterfaceHandler::PI_DMA_READ()
|
|||
}
|
||||
|
||||
// PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
|
||||
uint32_t PI_RD_LEN = ((g_Reg->PI_RD_LEN_REG) & 0x00FFFFFFul) + 1;
|
||||
|
||||
uint32_t PI_RD_LEN = ((PI_RD_LEN_REG) & 0x00FFFFFFul) + 1;
|
||||
if ((PI_RD_LEN & 1) != 0)
|
||||
{
|
||||
PI_RD_LEN += 1;
|
||||
}
|
||||
|
||||
if (g_Reg->PI_DRAM_ADDR_REG + PI_RD_LEN > g_MMU->RdramSize())
|
||||
if (PI_DRAM_ADDR_REG + PI_RD_LEN > g_MMU->RdramSize())
|
||||
{
|
||||
if (HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("PI_DMA_READ not in Memory: %08X", g_Reg->PI_DRAM_ADDR_REG + PI_RD_LEN).c_str());
|
||||
}
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
return;
|
||||
}
|
||||
|
||||
// 64DD buffers write
|
||||
if (g_Reg->PI_CART_ADDR_REG >= 0x05000000 && g_Reg->PI_CART_ADDR_REG <= 0x050003FF)
|
||||
if (PI_CART_ADDR_REG >= 0x05000000 && PI_CART_ADDR_REG <= 0x050003FF)
|
||||
{
|
||||
// 64DD C2 sectors (don't care)
|
||||
g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_RD_LEN * 63) / 25, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Reg->PI_CART_ADDR_REG >= 0x05000400 && g_Reg->PI_CART_ADDR_REG <= 0x050004FF)
|
||||
if (PI_CART_ADDR_REG >= 0x05000400 && PI_CART_ADDR_REG <= 0x050004FF)
|
||||
{
|
||||
// 64DD user sector
|
||||
uint32_t i;
|
||||
|
@ -235,47 +241,48 @@ void PeripheralInterfaceHandler::PI_DMA_READ()
|
|||
uint8_t * DISK = g_Disk->GetDiskAddressBuffer();
|
||||
for (i = 0; i < PI_RD_LEN_REG; i++)
|
||||
{
|
||||
*(DISK + (i ^ 3)) = *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3));
|
||||
*(DISK + (i ^ 3)) = *(RDRAM + ((PI_DRAM_ADDR_REG + i) ^ 3));
|
||||
}
|
||||
g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_RD_LEN_REG * 63) / 25, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Reg->PI_CART_ADDR_REG >= 0x05000580 && g_Reg->PI_CART_ADDR_REG <= 0x050005BF)
|
||||
if (PI_CART_ADDR_REG >= 0x05000580 && PI_CART_ADDR_REG <= 0x050005BF)
|
||||
{
|
||||
// 64DD MSEQ (don't care)
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
return;
|
||||
}
|
||||
|
||||
// Write ROM area (for 64DD conversion)
|
||||
if (g_Reg->PI_CART_ADDR_REG >= 0x10000000 && g_Reg->PI_CART_ADDR_REG <= 0x1FBFFFFF && g_Settings->LoadBool(Game_AllowROMWrites))
|
||||
if (PI_CART_ADDR_REG >= 0x10000000 && PI_CART_ADDR_REG <= 0x1FBFFFFF && g_Settings->LoadBool(Game_AllowROMWrites))
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t * ROM = g_Rom->GetRomAddress();
|
||||
uint8_t * RDRAM = g_MMU->Rdram();
|
||||
|
||||
ProtectMemory(ROM, g_Rom->GetRomSize(), MEM_READWRITE);
|
||||
g_Reg->PI_CART_ADDR_REG -= 0x10000000;
|
||||
if (g_Reg->PI_CART_ADDR_REG + PI_RD_LEN_REG < g_Rom->GetRomSize())
|
||||
PI_CART_ADDR_REG -= 0x10000000;
|
||||
if (PI_CART_ADDR_REG + PI_RD_LEN_REG < g_Rom->GetRomSize())
|
||||
{
|
||||
for (i = 0; i < PI_RD_LEN_REG; i++)
|
||||
{
|
||||
*(ROM + ((g_Reg->PI_CART_ADDR_REG + i) ^ 3)) = *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3));
|
||||
*(ROM + ((PI_CART_ADDR_REG + i) ^ 3)) = *(RDRAM + ((PI_DRAM_ADDR_REG + i) ^ 3));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t Len;
|
||||
Len = g_Rom->GetRomSize() - g_Reg->PI_CART_ADDR_REG;
|
||||
Len = g_Rom->GetRomSize() - PI_CART_ADDR_REG;
|
||||
for (i = 0; i < Len; i++)
|
||||
{
|
||||
*(ROM + ((g_Reg->PI_CART_ADDR_REG + i) ^ 3)) = *(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3));
|
||||
*(ROM + ((PI_CART_ADDR_REG + i) ^ 3)) = *(RDRAM + ((PI_DRAM_ADDR_REG + i) ^ 3));
|
||||
}
|
||||
}
|
||||
g_Reg->PI_CART_ADDR_REG += 0x10000000;
|
||||
PI_CART_ADDR_REG += 0x10000000;
|
||||
|
||||
if (!g_System->DmaUsed())
|
||||
{
|
||||
|
@ -284,18 +291,19 @@ void PeripheralInterfaceHandler::PI_DMA_READ()
|
|||
}
|
||||
if (g_Recompiler && g_System->bSMM_PIDMA())
|
||||
{
|
||||
g_Recompiler->ClearRecompCode_Phys(g_Reg->PI_DRAM_ADDR_REG, g_Reg->PI_WR_LEN_REG, CRecompiler::Remove_DMA);
|
||||
g_Recompiler->ClearRecompCode_Phys(PI_DRAM_ADDR_REG, PI_WR_LEN_REG, CRecompiler::Remove_DMA);
|
||||
}
|
||||
|
||||
ProtectMemory(ROM, g_Rom->GetRomSize(), MEM_READONLY);
|
||||
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Reg->PI_CART_ADDR_REG >= 0x08000000 && g_Reg->PI_CART_ADDR_REG < 0x08088000)
|
||||
if (PI_CART_ADDR_REG >= 0x08000000 && PI_CART_ADDR_REG < 0x08088000)
|
||||
{
|
||||
if (m_Domain2Address2Handler.DMARead())
|
||||
{
|
||||
|
@ -304,275 +312,192 @@ void PeripheralInterfaceHandler::PI_DMA_READ()
|
|||
}
|
||||
if (g_System->m_SaveUsing == SaveChip_FlashRam)
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("**** FlashRAM DMA read address %08X ****", g_Reg->PI_CART_ADDR_REG).c_str());
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
g_Notify->DisplayError(stdstr_f("**** FlashRAM DMA read address %08X ****", PI_CART_ADDR_REG).c_str());
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
return;
|
||||
}
|
||||
if (HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("PI_DMA_READ where are you DMAing to? : %08X", g_Reg->PI_CART_ADDR_REG).c_str());
|
||||
g_Notify->DisplayError(stdstr_f("PI_DMA_READ where are you DMAing to? : %08X", PI_CART_ADDR_REG).c_str());
|
||||
}
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
return;
|
||||
}
|
||||
|
||||
void PeripheralInterfaceHandler::PI_DMA_WRITE()
|
||||
{
|
||||
if (g_Debugger != NULL && HaveDebugger())
|
||||
if (g_Debugger != nullptr && HaveDebugger())
|
||||
{
|
||||
g_Debugger->PIDMAWriteStarted();
|
||||
}
|
||||
|
||||
// Rounding PI_WR_LEN up to the nearest even number fixes AI Shougi 3, Doraemon 3, etc.
|
||||
uint32_t PI_WR_LEN = ((g_Reg->PI_WR_LEN_REG) & 0x00FFFFFEul) + 2;
|
||||
uint32_t PI_CART_ADDR = !g_Settings->LoadBool(Game_UnalignedDMA) ? g_Reg->PI_CART_ADDR_REG & ~1 : g_Reg->PI_CART_ADDR_REG;
|
||||
|
||||
g_Reg->PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
|
||||
if (g_Reg->PI_DRAM_ADDR_REG + PI_WR_LEN > g_MMU->RdramSize())
|
||||
if (!g_System->DmaUsed())
|
||||
{
|
||||
if (ShowUnhandledMemory()) { g_Notify->DisplayError(stdstr_f("PI_DMA_WRITE not in memory: %08X", g_Reg->PI_DRAM_ADDR_REG + PI_WR_LEN).c_str()); }
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
return;
|
||||
g_System->SetDmaUsed(true);
|
||||
OnFirstDMA();
|
||||
}
|
||||
|
||||
// 64DD buffers read
|
||||
if (PI_CART_ADDR >= 0x05000000 && PI_CART_ADDR <= 0x050003FF)
|
||||
{
|
||||
// 64DD C2 sectors (just read 0)
|
||||
uint32_t i;
|
||||
uint8_t * RDRAM = g_MMU->Rdram();
|
||||
for (i = 0; i < PI_WR_LEN; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = 0;
|
||||
}
|
||||
|
||||
// Timer is needed for track read
|
||||
g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_WR_LEN * 63) / 25, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PI_CART_ADDR >= 0x05000400 && PI_CART_ADDR <= 0x050004FF)
|
||||
{
|
||||
// 64DD user sector
|
||||
uint32_t i;
|
||||
uint8_t * RDRAM = g_MMU->Rdram();
|
||||
uint8_t * DISK = g_Disk->GetDiskAddressBuffer();
|
||||
for (i = 0; i < PI_WR_LEN; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(DISK + (i ^ 3));
|
||||
}
|
||||
|
||||
// Timer is needed for track read
|
||||
g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (PI_WR_LEN * 63) / 25, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PI_CART_ADDR >= 0x05000580 && PI_CART_ADDR <= 0x050005BF)
|
||||
uint32_t WritePos = PI_DRAM_ADDR_REG & 0x7FFFFE;
|
||||
uint32_t ReadPos = PI_CART_ADDR_REG;
|
||||
|
||||
if (ReadPos >= 0x05000580 && ReadPos <= 0x050005BF)
|
||||
{
|
||||
// 64DD MSEQ (don't care)
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
return;
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
}
|
||||
|
||||
// 64DD IPL ROM
|
||||
if (PI_CART_ADDR >= 0x06000000 && PI_CART_ADDR <= 0x063FFFFF)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
uint8_t * ROM = g_DDRom->GetRomAddress();
|
||||
uint8_t * RDRAM = g_MMU->Rdram();
|
||||
PI_CART_ADDR -= 0x06000000;
|
||||
if (PI_CART_ADDR + PI_WR_LEN < g_DDRom->GetRomSize())
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((PI_CART_ADDR + i) ^ 3));
|
||||
}
|
||||
}
|
||||
else if (PI_CART_ADDR >= g_DDRom->GetRomSize())
|
||||
{
|
||||
uint32_t cart = PI_CART_ADDR - g_DDRom->GetRomSize();
|
||||
while (cart >= g_DDRom->GetRomSize())
|
||||
{
|
||||
cart -= g_DDRom->GetRomSize();
|
||||
}
|
||||
for (i = 0; i < PI_WR_LEN; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((cart + i) ^ 3));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t Len;
|
||||
Len = g_DDRom->GetRomSize() - PI_CART_ADDR;
|
||||
for (i = 0; i < Len; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((PI_CART_ADDR + i) ^ 3));
|
||||
}
|
||||
for (i = Len; i < PI_WR_LEN - Len; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = 0;
|
||||
}
|
||||
}
|
||||
PI_CART_ADDR += 0x06000000;
|
||||
|
||||
if (!g_System->DmaUsed())
|
||||
{
|
||||
g_System->SetDmaUsed(true);
|
||||
OnFirstDMA();
|
||||
}
|
||||
if (g_Recompiler && g_System->bSMM_PIDMA())
|
||||
{
|
||||
g_Recompiler->ClearRecompCode_Phys(g_Reg->PI_DRAM_ADDR_REG, g_Reg->PI_WR_LEN_REG, CRecompiler::Remove_DMA);
|
||||
}
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN * 8.9) + 50);
|
||||
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN * 8.9));
|
||||
return;
|
||||
}
|
||||
|
||||
if (PI_CART_ADDR >= 0x08000000 && PI_CART_ADDR <= 0x08088000)
|
||||
else if (ReadPos >= 0x08000000 && ReadPos <= 0x08088000)
|
||||
{
|
||||
m_Domain2Address2Handler.DMAWrite();
|
||||
return;
|
||||
}
|
||||
|
||||
if (PI_CART_ADDR >= 0x10000000 && PI_CART_ADDR <= 0x1FFFFFFF)
|
||||
else
|
||||
{
|
||||
if (g_Recompiler && g_System->bSMM_PIDMA())
|
||||
{
|
||||
g_Recompiler->ClearRecompCode_Phys(g_Reg->PI_DRAM_ADDR_REG, g_Reg->PI_WR_LEN_REG, CRecompiler::Remove_DMA);
|
||||
}
|
||||
int32_t Length = PI_WR_LEN_REG + 1;
|
||||
PI_WR_LEN_REG = Length <= 8 ? 0x7F - (PI_DRAM_ADDR_REG & 7) : 0x7F;
|
||||
|
||||
uint32_t i;
|
||||
|
||||
uint8_t * ROM = g_Rom->GetRomAddress();
|
||||
uint8_t * RDRAM = g_MMU->Rdram();
|
||||
PI_CART_ADDR -= 0x10000000;
|
||||
if (PI_CART_ADDR + PI_WR_LEN < g_Rom->GetRomSize())
|
||||
uint8_t Block[128];
|
||||
bool FirstBlock = true;
|
||||
uint8_t * Rdram = m_MMU.Rdram();
|
||||
uint32_t TransferLen = 0;
|
||||
while (Length > 0)
|
||||
{
|
||||
size_t alignment;
|
||||
RDRAM += g_Reg->PI_DRAM_ADDR_REG;
|
||||
ROM += PI_CART_ADDR;
|
||||
alignment = PI_WR_LEN | (size_t)RDRAM | (size_t)ROM;
|
||||
if ((alignment & 0x3) == 0)
|
||||
int32_t BlockAlign = PI_DRAM_ADDR_REG & 6;
|
||||
int32_t BlockSize = 128 - BlockAlign;
|
||||
int32_t BlockLen = BlockSize;
|
||||
if (Length < BlockLen)
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN; i += 4)
|
||||
BlockLen = Length;
|
||||
}
|
||||
Length -= BlockLen;
|
||||
if (Length < 0)
|
||||
{
|
||||
Length = 0;
|
||||
}
|
||||
|
||||
int32_t ReadLen = (BlockLen + 1) & ~1;
|
||||
ReadBlock(PI_CART_ADDR_REG, Block, ReadLen);
|
||||
PI_CART_ADDR_REG += ReadLen;
|
||||
|
||||
if (FirstBlock)
|
||||
{
|
||||
if (BlockLen == BlockSize - 1)
|
||||
{
|
||||
*(uint32_t *)(RDRAM + i) = *(uint32_t *)(ROM + i);
|
||||
BlockLen += 1;
|
||||
}
|
||||
BlockLen = BlockLen - BlockAlign;
|
||||
if (BlockLen < 0)
|
||||
{
|
||||
BlockLen = 0;
|
||||
}
|
||||
}
|
||||
else if ((alignment & 1) == 0)
|
||||
|
||||
for (int32_t i = 0; i < BlockLen; i++)
|
||||
{
|
||||
if ((PI_WR_LEN & 2) == 0)
|
||||
{
|
||||
if (((size_t)RDRAM & 2) == 0)
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN; i += 4)
|
||||
{
|
||||
*(uint16_t *)(((size_t)RDRAM + i) + 2) = *(uint16_t *)(((size_t)ROM + i) - 2);
|
||||
*(uint16_t *)(((size_t)RDRAM + i) + 0) = *(uint16_t *)(((size_t)ROM + i) + 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((size_t)ROM & 2) == 0)
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN; i += 4)
|
||||
{
|
||||
*(uint16_t *)(((size_t)RDRAM + i) - 2) = *(uint16_t *)(((size_t)ROM + i) + 2);
|
||||
*(uint16_t *)(((size_t)RDRAM + i) + 4) = *(uint16_t *)(((size_t)ROM + i) + 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN; i += 4)
|
||||
{
|
||||
*(uint16_t *)(((size_t)RDRAM + i) - 2) = *(uint16_t *)(((size_t)ROM + i) - 2);
|
||||
*(uint16_t *)(((size_t)RDRAM + i) + 4) = *(uint16_t *)(((size_t)ROM + i) + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN; i += 2)
|
||||
{
|
||||
*(uint16_t *)(((size_t)RDRAM + i) ^ 2) = *(uint16_t *)(((size_t)ROM + i) ^ 2);
|
||||
}
|
||||
}
|
||||
Rdram[(PI_DRAM_ADDR_REG + i) ^ 3] = Block[i];
|
||||
}
|
||||
PI_DRAM_ADDR_REG = (PI_DRAM_ADDR_REG + BlockLen + 7) & ~7;
|
||||
TransferLen += (BlockLen + 7) & ~7;
|
||||
FirstBlock = false;
|
||||
}
|
||||
|
||||
if (ReadPos >= 0x05000000 && ReadPos <= 0x050004FF)
|
||||
{
|
||||
// 64DD buffers read and 64DD user sector
|
||||
PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
|
||||
g_SystemTimer->SetTimer(g_SystemTimer->DDPiTimer, (TransferLen * 63) / 25, false);
|
||||
}
|
||||
else if (ReadPos >= 0x06000000 && ReadPos <= 0x063FFFFF)
|
||||
{
|
||||
// 64DD IPL ROM
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
}
|
||||
else if (ReadPos >= 0x08000000 && ReadPos <= 0x08088000)
|
||||
{
|
||||
m_Domain2Address2Handler.DMAWrite();
|
||||
}
|
||||
else if (ReadPos >= 0x10000000 && ReadPos <= 0x1FFFFFFF)
|
||||
{
|
||||
if (g_System->bRandomizeSIPIInterrupts())
|
||||
{
|
||||
//ChangeTimer(PiTimer,(int32_t)(Length * 8.9) + 50);
|
||||
//ChangeTimer(PiTimer,(int32_t)(Length * 8.9));
|
||||
PI_STATUS_REG |= PI_STATUS_DMA_BUSY;
|
||||
g_SystemTimer->SetTimer(g_SystemTimer->PiTimer, TransferLen / 8 + (g_Random->next() % 0x40), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < PI_WR_LEN; i++)
|
||||
{
|
||||
*(uint8_t *)(((size_t)RDRAM + i) ^ 3) = *(uint8_t *)(((size_t)ROM + i) ^ 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PI_CART_ADDR >= g_Rom->GetRomSize())
|
||||
{
|
||||
uint32_t cart = PI_CART_ADDR - g_Rom->GetRomSize();
|
||||
while (cart >= g_Rom->GetRomSize())
|
||||
{
|
||||
cart -= g_Rom->GetRomSize();
|
||||
}
|
||||
for (i = 0; i < PI_WR_LEN; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((cart + i) ^ 3));
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t Len;
|
||||
Len = g_Rom->GetRomSize() - PI_CART_ADDR;
|
||||
for (i = 0; i < Len; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = *(ROM + ((PI_CART_ADDR + i) ^ 3));
|
||||
}
|
||||
for (i = Len; i < PI_WR_LEN - Len; i++)
|
||||
{
|
||||
*(RDRAM + ((g_Reg->PI_DRAM_ADDR_REG + i) ^ 3)) = 0;
|
||||
}
|
||||
PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
}
|
||||
PI_CART_ADDR += 0x10000000;
|
||||
|
||||
if (!g_System->DmaUsed())
|
||||
if (g_Recompiler && g_System->bSMM_PIDMA())
|
||||
{
|
||||
g_System->SetDmaUsed(true);
|
||||
OnFirstDMA();
|
||||
g_Recompiler->ClearRecompCode_Phys(WritePos, Length, CRecompiler::Remove_DMA);
|
||||
}
|
||||
|
||||
if (g_System->bRandomizeSIPIInterrupts())
|
||||
{
|
||||
g_SystemTimer->SetTimer(g_SystemTimer->PiTimer, PI_WR_LEN / 8 + (g_Random->next() % 0x40), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
}
|
||||
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN * 8.9) + 50);
|
||||
//ChangeTimer(PiTimer,(int32_t)(PI_WR_LEN * 8.9));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowUnhandledMemory())
|
||||
void PeripheralInterfaceHandler::ReadBlock(uint32_t Address, uint8_t * Block, uint32_t BlockLen)
|
||||
{
|
||||
if (Address >= 0x05000000 && Address <= 0x050003FF)
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("PI_DMA_WRITE not in ROM: %08X", PI_CART_ADDR).c_str());
|
||||
// 64DD buffers read - C2 sectors (just read 0)
|
||||
for (uint32_t i = 0, n = (BlockLen + 1) & ~1; i < n; i++)
|
||||
{
|
||||
Block[i] = 0;
|
||||
}
|
||||
}
|
||||
else if (Address >= 0x05000400 && Address <= 0x050004FF)
|
||||
{
|
||||
// 64DD user sector
|
||||
uint32_t ReadPos = Address - 0x05000400;
|
||||
uint8_t * DISK = g_Disk->GetDiskAddressBuffer();
|
||||
for (uint32_t i = 0, n = (BlockLen + 1) & ~1; i < n; i++)
|
||||
{
|
||||
Block[i] = DISK[((ReadPos + i) ^ 3)];
|
||||
}
|
||||
}
|
||||
else if (Address >= 0x06000000 && Address <= 0x063FFFFF)
|
||||
{
|
||||
uint32_t ReadPos = Address - 0x06000000;
|
||||
uint8_t * ROM = g_DDRom->GetRomAddress();
|
||||
uint32_t RomSize = g_DDRom->GetRomSize();
|
||||
for (uint32_t i = 0, n = (BlockLen + 1) & ~1; i < n; i++)
|
||||
{
|
||||
uint32_t Pos = ((ReadPos + i) ^ 3);
|
||||
Block[i] = Pos < RomSize ? ROM[Pos] : 0;
|
||||
}
|
||||
}
|
||||
else if (Address >= 0x10000000 && Address + BlockLen <= 0x1FFFFFFF)
|
||||
{
|
||||
uint32_t ReadPos = Address - 0x10000000;
|
||||
uint8_t * ROM = g_Rom->GetRomAddress();
|
||||
uint32_t RomSize = g_Rom->GetRomSize();
|
||||
for (uint32_t i = 0, n = (BlockLen + 1) & ~1; i < n; i++)
|
||||
{
|
||||
uint32_t Pos = ((ReadPos + i) ^ 3);
|
||||
Block[i] = Pos < RomSize ? ROM[Pos] : 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
g_Reg->PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->CheckInterrupts();
|
||||
}
|
|
@ -37,15 +37,28 @@ class CRegisters;
|
|||
class CMipsMemoryVM;
|
||||
class CartridgeDomain2Address2Handler;
|
||||
|
||||
// Peripheral interface flags
|
||||
enum
|
||||
{
|
||||
PI_STATUS_DMA_BUSY = 0x01,
|
||||
PI_STATUS_IO_BUSY = 0x02,
|
||||
PI_STATUS_ERROR = 0x04,
|
||||
PI_STATUS_INTERRUPT = 0x08,
|
||||
|
||||
PI_SET_RESET = 0x01,
|
||||
PI_CLR_INTR = 0x02,
|
||||
};
|
||||
|
||||
class PeripheralInterfaceHandler :
|
||||
public MemoryHandler,
|
||||
private CGameSettings,
|
||||
private CDebugSettings,
|
||||
private CLogging,
|
||||
private PeripheralInterfaceReg
|
||||
private PeripheralInterfaceReg,
|
||||
private MIPSInterfaceReg
|
||||
{
|
||||
public:
|
||||
PeripheralInterfaceHandler(CMipsMemoryVM & MMU, CRegisters & Reg, CartridgeDomain2Address2Handler & Domain2Address2Handler);
|
||||
PeripheralInterfaceHandler(CN64System & System, CMipsMemoryVM & MMU, CRegisters & Reg, CartridgeDomain2Address2Handler & Domain2Address2Handler);
|
||||
|
||||
bool Read32(uint32_t Address, uint32_t & Value);
|
||||
bool Write32(uint32_t Address, uint32_t Value, uint32_t Mask);
|
||||
|
@ -55,10 +68,13 @@ private:
|
|||
PeripheralInterfaceHandler(const PeripheralInterfaceHandler &);
|
||||
PeripheralInterfaceHandler & operator=(const PeripheralInterfaceHandler &);
|
||||
|
||||
static void stSystemReset(PeripheralInterfaceHandler * _this) { _this->SystemReset(); }
|
||||
|
||||
void PI_DMA_READ();
|
||||
void PI_DMA_WRITE();
|
||||
|
||||
void SystemReset(void);
|
||||
void OnFirstDMA();
|
||||
void ReadBlock(uint32_t Address, uint8_t * Block, uint32_t BlockLen);
|
||||
|
||||
CartridgeDomain2Address2Handler & m_Domain2Address2Handler;
|
||||
CMipsMemoryVM & m_MMU;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
RomMemoryHandler::RomMemoryHandler(CN64System & System, CRegisters & Reg, CN64Rom & Rom) :
|
||||
m_PC(Reg.m_PROGRAM_COUNTER),
|
||||
m_Reg(Reg),
|
||||
m_Rom(Rom),
|
||||
m_RomWrittenTo(false),
|
||||
m_RomWroteValue(0)
|
||||
|
@ -16,6 +17,7 @@ RomMemoryHandler::RomMemoryHandler(CN64System & System, CRegisters & Reg, CN64Ro
|
|||
|
||||
bool RomMemoryHandler::Read32(uint32_t Address, uint32_t & Value)
|
||||
{
|
||||
m_Reg.PI_CART_ADDR_REG = Address + 4;
|
||||
if (m_RomWrittenTo)
|
||||
{
|
||||
Value = m_RomWroteValue;
|
||||
|
|
|
@ -31,6 +31,7 @@ private:
|
|||
static void stLoadedGameState(RomMemoryHandler * _this) { _this->LoadedGameState(); }
|
||||
|
||||
uint32_t & m_PC;
|
||||
CRegisters & m_Reg;
|
||||
CN64Rom & m_Rom;
|
||||
bool m_RomWrittenTo;
|
||||
uint32_t m_RomWroteValue;
|
||||
|
|
|
@ -29,7 +29,7 @@ CMipsMemoryVM::CMipsMemoryVM(CN64System & System, bool SavesReadOnly) :
|
|||
m_RDRAMRegistersHandler(System.m_Reg),
|
||||
m_DPCommandRegistersHandler(System, System.GetPlugins(), System.m_Reg),
|
||||
m_MIPSInterfaceHandler(System.m_Reg),
|
||||
m_PeripheralInterfaceHandler(*this, System.m_Reg, m_CartridgeDomain2Address2Handler),
|
||||
m_PeripheralInterfaceHandler(System, *this, System.m_Reg, m_CartridgeDomain2Address2Handler),
|
||||
m_PifRamHandler(*this, System.m_Reg),
|
||||
m_RDRAMInterfaceHandler(System.m_Reg),
|
||||
m_RomMemoryHandler(System, System.m_Reg, *g_Rom),
|
||||
|
@ -598,10 +598,8 @@ bool CMipsMemoryVM::LB_NonMemory(uint32_t VAddr, uint8_t & Value)
|
|||
if (PAddr < 0x800000)
|
||||
{
|
||||
Value = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PAddr >= 0x10000000 && PAddr < 0x16000000)
|
||||
else if (PAddr >= 0x10000000 && PAddr < 0x16000000)
|
||||
{
|
||||
uint32_t Value32;
|
||||
if (!m_RomMemoryHandler.Read32(PAddr & ~0x3, Value32))
|
||||
|
@ -630,12 +628,22 @@ bool CMipsMemoryVM::LH_NonMemory(uint32_t VAddr, uint16_t & Value)
|
|||
if (PAddr < 0x800000)
|
||||
{
|
||||
Value = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
Value = 0;
|
||||
return false;
|
||||
else if (PAddr >= 0x10000000 && PAddr < 0x16000000)
|
||||
{
|
||||
uint32_t Value32;
|
||||
if (!m_RomMemoryHandler.Read32(PAddr & ~0x3, Value32))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Value = ((Value32 >> (((PAddr & 2) ^ 2) << 3)) & 0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
Value = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMipsMemoryVM::LW_NonMemory(uint32_t VAddr, uint32_t & Value)
|
||||
|
|
|
@ -212,17 +212,6 @@ enum
|
|||
SP_STATUS_SIG7 = 0x4000, // Bit 14: Signal 7 set
|
||||
};
|
||||
|
||||
// Peripheral interface flags
|
||||
enum
|
||||
{
|
||||
PI_STATUS_DMA_BUSY = 0x01,
|
||||
PI_STATUS_IO_BUSY = 0x02,
|
||||
PI_STATUS_ERROR = 0x04,
|
||||
|
||||
PI_SET_RESET = 0x01,
|
||||
PI_CLR_INTR = 0x02,
|
||||
};
|
||||
|
||||
class CRegName
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -132,6 +132,7 @@ void CSystemEvents::ExecuteEvents()
|
|||
g_Reg->DoIntrException(false);
|
||||
break;
|
||||
case SysEvent_Interrupt_PI:
|
||||
g_Reg->PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
g_Reg->MI_INTR_REG |= MI_INTR_PI;
|
||||
g_Reg->DoIntrException(false);
|
||||
break;
|
||||
|
|
|
@ -203,6 +203,7 @@ void CSystemTimer::TimerDone()
|
|||
case CSystemTimer::PiTimer:
|
||||
g_SystemTimer->StopTimer(CSystemTimer::PiTimer);
|
||||
m_Reg.PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
m_Reg.PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
m_Reg.MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.CheckInterrupts();
|
||||
break;
|
||||
|
@ -211,6 +212,7 @@ void CSystemTimer::TimerDone()
|
|||
m_Reg.PI_STATUS_REG &= ~PI_STATUS_DMA_BUSY;
|
||||
DiskBMUpdate();
|
||||
m_Reg.MI_INTR_REG |= MI_INTR_PI;
|
||||
m_Reg.PI_STATUS_REG |= PI_STATUS_INTERRUPT;
|
||||
m_Reg.CheckInterrupts();
|
||||
break;
|
||||
case CSystemTimer::DDSeekTimer:
|
||||
|
|
|
@ -284,6 +284,7 @@ CICChip CN64Rom::GetCicChipID(uint8_t * RomData, uint64_t * CRC)
|
|||
case 0x000000D2E53EF008: return CIC_NUS_8303; // 64DD IPL
|
||||
case 0x000000D2E53EF39F: return CIC_NUS_8401; // 64DD IPL tool
|
||||
case 0x000000D2E53E5DDA: return CIC_NUS_DDUS; // 64DD IPL US (different CIC)
|
||||
case 0x0000000AF3A34BC8: return CIC_MINI_IPL3;
|
||||
default:
|
||||
//Aleck64 CIC
|
||||
if (crcAleck64 == 0x000000A5F80BF620)
|
||||
|
|
|
@ -1077,6 +1077,7 @@ void CN64System::InitRegisters(bool bPostPif, CMipsMemoryVM & MMU)
|
|||
{
|
||||
case CIC_UNKNOWN:
|
||||
case CIC_NUS_6102:
|
||||
case CIC_MINI_IPL3:
|
||||
m_Reg.m_GPR[5].DW = 0xFFFFFFFFC0F1D859;
|
||||
m_Reg.m_GPR[14].DW = 0x000000002DE108EA;
|
||||
m_Reg.m_GPR[24].DW = 0x0000000000000000;
|
||||
|
@ -1108,6 +1109,7 @@ void CN64System::InitRegisters(bool bPostPif, CMipsMemoryVM & MMU)
|
|||
{
|
||||
case CIC_UNKNOWN:
|
||||
case CIC_NUS_6102:
|
||||
case CIC_MINI_IPL3:
|
||||
m_Reg.m_GPR[5].DW = 0xFFFFFFFFC95973D5;
|
||||
m_Reg.m_GPR[14].DW = 0x000000002449A366;
|
||||
break;
|
||||
|
@ -1158,6 +1160,7 @@ void CN64System::InitRegisters(bool bPostPif, CMipsMemoryVM & MMU)
|
|||
break;
|
||||
case CIC_UNKNOWN:
|
||||
case CIC_NUS_6102:
|
||||
case CIC_MINI_IPL3:
|
||||
m_Reg.m_GPR[1].DW = 0x0000000000000001;
|
||||
m_Reg.m_GPR[2].DW = 0x000000000EBDA536;
|
||||
m_Reg.m_GPR[3].DW = 0x000000000EBDA536;
|
||||
|
|
|
@ -68,7 +68,8 @@ enum CICChip
|
|||
{
|
||||
CIC_UNKNOWN = -1, CIC_NUS_6101 = 1, CIC_NUS_6102 = 2, CIC_NUS_6103 = 3,
|
||||
CIC_NUS_6104 = 4, CIC_NUS_6105 = 5, CIC_NUS_6106 = 6, CIC_NUS_5167 = 7,
|
||||
CIC_NUS_8303 = 8, CIC_NUS_DDUS = 9, CIC_NUS_8401 = 10, CIC_NUS_5101 = 11
|
||||
CIC_NUS_8303 = 8, CIC_NUS_DDUS = 9, CIC_NUS_8401 = 10, CIC_NUS_5101 = 11,
|
||||
CIC_MINI_IPL3 = 12,
|
||||
};
|
||||
|
||||
enum Country
|
||||
|
|
|
@ -2908,13 +2908,38 @@ void CX86RecompilerOps::LH_KnownAddress(x86Reg Reg, uint32_t VAddr, bool SignExt
|
|||
case 0x10000000:
|
||||
if ((PAddr - 0x10000000) < g_Rom->GetRomSize())
|
||||
{
|
||||
if (SignExtend)
|
||||
m_RegWorkingSet.BeforeCallDirect();
|
||||
PushImm32("m_TempValue32", (uint32_t)&m_TempValue32);
|
||||
PushImm32(PAddr & 0x1FFFFFFC);
|
||||
#ifdef _MSC_VER
|
||||
MoveConstToX86reg((uint32_t)(MemoryHandler *)&g_MMU->m_RomMemoryHandler, x86_ECX);
|
||||
Call_Direct((void *)((long**)(MemoryHandler *)&g_MMU->m_RomMemoryHandler)[0][0], "RomMemoryHandler::Read32");
|
||||
#else
|
||||
PushImm32((uint32_t)&g_MMU->m_RomMemoryHandler);
|
||||
Call_Direct(AddressOf(&RomMemoryHandler::Read32), "RomMemoryHandler::Read32");
|
||||
AddConstToX86Reg(x86_ESP, 16);
|
||||
#endif
|
||||
m_RegWorkingSet.AfterCallDirect();
|
||||
uint8_t ShiftValue = (((PAddr & 2) ^ 2) << 3);
|
||||
if (ShiftValue != 0)
|
||||
{
|
||||
MoveSxVariableToX86regHalf(((PAddr ^ 2) - 0x10000000) + g_Rom->GetRomAddress(), stdstr_f("Rom + (%X ^ 2)", (PAddr - 0x10000000)).c_str(), Reg);
|
||||
MoveVariableToX86reg(&m_TempValue32, "m_TempValue32", Reg);
|
||||
if (SignExtend)
|
||||
{
|
||||
ShiftRightSignImmed(Reg, ShiftValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShiftRightUnsignImmed(Reg, ShiftValue);
|
||||
}
|
||||
}
|
||||
else if (SignExtend)
|
||||
{
|
||||
MoveSxVariableToX86regHalf(&m_TempValue32, "m_TempValue32", Reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveZxVariableToX86regHalf(((PAddr ^ 2) - 0x10000000) + g_Rom->GetRomAddress(), stdstr_f("Rom + (%X ^ 2)", (PAddr - 0x10000000)).c_str(), Reg);
|
||||
MoveZxVariableToX86regHalf(&m_TempValue32, "m_TempValue32", Reg);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3312,7 +3337,19 @@ void CX86RecompilerOps::LW_KnownAddress(x86Reg Reg, uint32_t VAddr)
|
|||
default:
|
||||
if ((PAddr & 0xF0000000) == 0x10000000 && (PAddr - 0x10000000) < g_Rom->GetRomSize())
|
||||
{
|
||||
MoveVariableToX86reg((PAddr - 0x10000000) + g_Rom->GetRomAddress(), stdstr_f("Rom + %X", (PAddr - 0x10000000)).c_str(), Reg);
|
||||
m_RegWorkingSet.BeforeCallDirect();
|
||||
PushImm32("m_TempValue32", (uint32_t)&m_TempValue32);
|
||||
PushImm32(PAddr & 0x1FFFFFFF);
|
||||
#ifdef _MSC_VER
|
||||
MoveConstToX86reg((uint32_t)(MemoryHandler *)&g_MMU->m_RomMemoryHandler, x86_ECX);
|
||||
Call_Direct((void *)((long**)(MemoryHandler *)&g_MMU->m_RomMemoryHandler)[0][0], "RomMemoryHandler::Read32");
|
||||
#else
|
||||
PushImm32((uint32_t)&g_MMU->m_RomMemoryHandler);
|
||||
Call_Direct(AddressOf(&RomMemoryHandler::Read32), "RomMemoryHandler::Read32");
|
||||
AddConstToX86Reg(x86_ESP, 16);
|
||||
#endif
|
||||
m_RegWorkingSet.AfterCallDirect();
|
||||
MoveVariableToX86reg(&m_TempValue32, "m_TempValue32", Reg);
|
||||
}
|
||||
else if (g_DDRom != nullptr && ((PAddr & 0xFF000000) == 0x06000000 && (PAddr - 0x06000000) < g_DDRom->GetRomSize()))
|
||||
{
|
||||
|
@ -10609,13 +10646,15 @@ void CX86RecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)
|
|||
case 0x04600000:
|
||||
switch (PAddr)
|
||||
{
|
||||
case 0x04600000: MoveConstToVariable(Value, &g_Reg->PI_DRAM_ADDR_REG, "PI_DRAM_ADDR_REG"); break;
|
||||
case 0x04600004: MoveConstToVariable(Value, &g_Reg->PI_CART_ADDR_REG, "PI_CART_ADDR_REG"); break;
|
||||
case 0x04600000:
|
||||
case 0x04600004:
|
||||
case 0x04600008:
|
||||
case 0x0460000C:
|
||||
case 0x04600010:
|
||||
UpdateCounters(m_RegWorkingSet, false, true, false);
|
||||
|
||||
if (PAddr == 0x04600008 || PAddr == 0x0460000C)
|
||||
{
|
||||
UpdateCounters(m_RegWorkingSet, false, true, false);
|
||||
}
|
||||
m_RegWorkingSet.BeforeCallDirect();
|
||||
PushImm32(0xFFFFFFFF);
|
||||
PushImm32(Value);
|
||||
|
@ -11036,20 +11075,15 @@ void CX86RecompilerOps::SW_Register(x86Reg Reg, uint32_t VAddr)
|
|||
case 0x04600000:
|
||||
switch (PAddr)
|
||||
{
|
||||
case 0x04600000: MoveX86regToVariable(Reg, &g_Reg->PI_DRAM_ADDR_REG, "PI_DRAM_ADDR_REG"); break;
|
||||
case 0x04600000:
|
||||
case 0x04600004:
|
||||
MoveX86regToVariable(Reg, &g_Reg->PI_CART_ADDR_REG, "PI_CART_ADDR_REG");
|
||||
if (EnableDisk())
|
||||
{
|
||||
m_RegWorkingSet.BeforeCallDirect();
|
||||
Call_Direct(AddressOf(&DiskDMACheck), "DiskDMACheck");
|
||||
m_RegWorkingSet.AfterCallDirect();
|
||||
}
|
||||
break;
|
||||
case 0x04600008:
|
||||
case 0x0460000C:
|
||||
UpdateCounters(m_RegWorkingSet, false, true);
|
||||
|
||||
case 0x04600010:
|
||||
if (PAddr == 0x04600008 || PAddr == 0x0460000C)
|
||||
{
|
||||
UpdateCounters(m_RegWorkingSet, false, true);
|
||||
}
|
||||
m_RegWorkingSet.BeforeCallDirect();
|
||||
PushImm32(0xFFFFFFFF);
|
||||
Push(Reg);
|
||||
|
@ -11061,23 +11095,6 @@ void CX86RecompilerOps::SW_Register(x86Reg Reg, uint32_t VAddr)
|
|||
PushImm32((uint32_t)&g_MMU->PeripheralInterfaceHandler);
|
||||
Call_Direct(AddressOf(&PeripheralInterfaceHandler::Write32), "PeripheralInterfaceHandler::Write32");
|
||||
AddConstToX86Reg(x86_ESP, 16);
|
||||
#endif
|
||||
m_RegWorkingSet.AfterCallDirect();
|
||||
break;
|
||||
case 0x04600010:
|
||||
if (ShowUnhandledMemory())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("%s\nTrying to store in %08X?", __FUNCTION__, VAddr).c_str());
|
||||
}
|
||||
AndConstToVariable((uint32_t)~MI_INTR_PI, &g_Reg->MI_INTR_REG, "MI_INTR_REG");
|
||||
m_RegWorkingSet.BeforeCallDirect();
|
||||
#ifdef _MSC_VER
|
||||
MoveConstToX86reg((uint32_t)g_Reg, x86_ECX);
|
||||
Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts");
|
||||
#else
|
||||
PushImm32((uint32_t)g_Reg);
|
||||
Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts");
|
||||
AddConstToX86Reg(x86_ESP, 4);
|
||||
#endif
|
||||
m_RegWorkingSet.AfterCallDirect();
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue