Bus: Adjust memory access and MMIO timing

Hasn't broken anything yet, but needs more thorough testing.
This commit is contained in:
Connor McLaughlin 2020-05-30 02:19:10 +10:00
parent 07e8ab4446
commit 69a00a64e6
2 changed files with 55 additions and 27 deletions

View file

@ -140,13 +140,6 @@ private:
MEMCTRL_REG_COUNT = 9 MEMCTRL_REG_COUNT = 9
}; };
enum : TickCount
{
RAM_READ_ACCESS_DELAY = 5, // Nocash docs say RAM takes 6 cycles to access. Subtract one because we already add a
// tick for the instruction.
RAM_WRITE_ACCESS_DELAY = 0, // Writes are free unless we're executing more than 4 stores in a row.
};
union MEMDELAY union MEMDELAY
{ {
u32 bits; u32 bits;

View file

@ -44,8 +44,7 @@ TickCount Bus::DoRAMAccess(u32 offset, u32& value)
} }
} }
// Nocash docs say RAM takes 6 cycles to access. return (type == MemoryAccessType::Read) ? 3 : 0;
return (type == MemoryAccessType::Read) ? RAM_READ_ACCESS_DELAY : RAM_WRITE_ACCESS_DELAY;
} }
template<MemoryAccessType type, MemoryAccessSize size> template<MemoryAccessType type, MemoryAccessSize size>
@ -109,66 +108,94 @@ TickCount Bus::DispatchAccess(PhysicalMemoryAddress address, u32& value)
else if (address < (MEMCTRL_BASE + MEMCTRL_SIZE)) else if (address < (MEMCTRL_BASE + MEMCTRL_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadMemoryControl(size, address & PAD_MASK); value = DoReadMemoryControl(size, address & PAD_MASK);
return 1;
}
else else
{
DoWriteMemoryControl(size, address & PAD_MASK, value); DoWriteMemoryControl(size, address & PAD_MASK, value);
return 0; return 0;
} }
}
else if (address < (PAD_BASE + PAD_SIZE)) else if (address < (PAD_BASE + PAD_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadPad(size, address & PAD_MASK); value = DoReadPad(size, address & PAD_MASK);
return 1;
}
else else
{
DoWritePad(size, address & PAD_MASK, value); DoWritePad(size, address & PAD_MASK, value);
return 0; return 0;
} }
}
else if (address < (SIO_BASE + SIO_SIZE)) else if (address < (SIO_BASE + SIO_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadSIO(size, address & SIO_MASK); value = DoReadSIO(size, address & SIO_MASK);
return 1;
}
else else
{
DoWriteSIO(size, address & SIO_MASK, value); DoWriteSIO(size, address & SIO_MASK, value);
return 0; return 0;
} }
}
else if (address < (MEMCTRL2_BASE + MEMCTRL2_SIZE)) else if (address < (MEMCTRL2_BASE + MEMCTRL2_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadMemoryControl2(size, address & PAD_MASK); value = DoReadMemoryControl2(size, address & PAD_MASK);
return 1;
}
else else
{
DoWriteMemoryControl2(size, address & PAD_MASK, value); DoWriteMemoryControl2(size, address & PAD_MASK, value);
return 0; return 0;
} }
}
else if (address < (INTERRUPT_CONTROLLER_BASE + INTERRUPT_CONTROLLER_SIZE)) else if (address < (INTERRUPT_CONTROLLER_BASE + INTERRUPT_CONTROLLER_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadInterruptController(size, address & INTERRUPT_CONTROLLER_MASK); value = DoReadInterruptController(size, address & INTERRUPT_CONTROLLER_MASK);
return 1;
}
else else
{
DoWriteInterruptController(size, address & INTERRUPT_CONTROLLER_MASK, value); DoWriteInterruptController(size, address & INTERRUPT_CONTROLLER_MASK, value);
return 0; return 0;
} }
}
else if (address < (DMA_BASE + DMA_SIZE)) else if (address < (DMA_BASE + DMA_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadDMA(size, address & DMA_MASK); value = DoReadDMA(size, address & DMA_MASK);
return 1;
}
else else
{
DoWriteDMA(size, address & DMA_MASK, value); DoWriteDMA(size, address & DMA_MASK, value);
return 0; return 0;
} }
}
else if (address < (TIMERS_BASE + TIMERS_SIZE)) else if (address < (TIMERS_BASE + TIMERS_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadTimers(size, address & TIMERS_MASK); value = DoReadTimers(size, address & TIMERS_MASK);
return 1;
}
else else
{
DoWriteTimers(size, address & TIMERS_MASK, value); DoWriteTimers(size, address & TIMERS_MASK, value);
return 0; return 0;
} }
}
else if (address < CDROM_BASE) else if (address < CDROM_BASE)
{ {
return DoInvalidAccess(type, size, address, value); return DoInvalidAccess(type, size, address, value);
@ -189,21 +216,29 @@ TickCount Bus::DispatchAccess(PhysicalMemoryAddress address, u32& value)
else if (address < (GPU_BASE + GPU_SIZE)) else if (address < (GPU_BASE + GPU_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadGPU(size, address & GPU_MASK); value = DoReadGPU(size, address & GPU_MASK);
return 1;
}
else else
{
DoWriteGPU(size, address & GPU_MASK, value); DoWriteGPU(size, address & GPU_MASK, value);
return 0; return 0;
} }
}
else if (address < (MDEC_BASE + MDEC_SIZE)) else if (address < (MDEC_BASE + MDEC_SIZE))
{ {
if constexpr (type == MemoryAccessType::Read) if constexpr (type == MemoryAccessType::Read)
{
value = DoReadMDEC(size, address & MDEC_MASK); value = DoReadMDEC(size, address & MDEC_MASK);
return 1;
}
else else
{
DoWriteMDEC(size, address & MDEC_MASK, value); DoWriteMDEC(size, address & MDEC_MASK, value);
return 0; return 0;
} }
}
else if (address < SPU_BASE) else if (address < SPU_BASE)
{ {
return DoInvalidAccess(type, size, address, value); return DoInvalidAccess(type, size, address, value);