mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
Bus: Adjust memory access and MMIO timing
Hasn't broken anything yet, but needs more thorough testing.
This commit is contained in:
parent
07e8ab4446
commit
69a00a64e6
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue