mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 07:05:45 -04:00
Rename to DuckStation
This commit is contained in:
164
src/core/cpu_core.inl
Normal file
164
src/core/cpu_core.inl
Normal file
@ -0,0 +1,164 @@
|
||||
#pragma once
|
||||
#include "YBaseLib/Assert.h"
|
||||
#include "bus.h"
|
||||
#include "cpu_core.h"
|
||||
|
||||
namespace CPU {
|
||||
|
||||
template<MemoryAccessType type, MemoryAccessSize size>
|
||||
bool Core::DoMemoryAccess(VirtualMemoryAddress address, u32& value)
|
||||
{
|
||||
switch (address >> 29)
|
||||
{
|
||||
case 0x00: // KUSEG 0M-512M
|
||||
{
|
||||
if constexpr (type == MemoryAccessType::Write)
|
||||
{
|
||||
if (m_cop0_regs.sr.Isc)
|
||||
return true;
|
||||
}
|
||||
|
||||
const PhysicalMemoryAddress phys_addr = address & UINT32_C(0x1FFFFFFF);
|
||||
if ((phys_addr & DCACHE_LOCATION_MASK) == DCACHE_LOCATION)
|
||||
{
|
||||
DoScratchpadAccess<type, size>(phys_addr, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_bus->DispatchAccess<type, size>(phys_addr, value))
|
||||
{
|
||||
Panic("Bus error");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case 0x01: // KUSEG 512M-1024M
|
||||
case 0x02: // KUSEG 1024M-1536M
|
||||
case 0x03: // KUSEG 1536M-2048M
|
||||
{
|
||||
// Above 512mb raises an exception.
|
||||
return false;
|
||||
}
|
||||
|
||||
case 0x04: // KSEG0 - physical memory cached
|
||||
{
|
||||
if constexpr (type == MemoryAccessType::Write)
|
||||
{
|
||||
if (m_cop0_regs.sr.Isc)
|
||||
return true;
|
||||
}
|
||||
|
||||
const PhysicalMemoryAddress phys_addr = address & UINT32_C(0x1FFFFFFF);
|
||||
if ((phys_addr & DCACHE_LOCATION_MASK) == DCACHE_LOCATION)
|
||||
{
|
||||
DoScratchpadAccess<type, size>(phys_addr, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_bus->DispatchAccess<type, size>(phys_addr, value))
|
||||
{
|
||||
Panic("Bus error");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x05: // KSEG1 - physical memory uncached
|
||||
{
|
||||
const PhysicalMemoryAddress phys_addr = address & UINT32_C(0x1FFFFFFF);
|
||||
if (!m_bus->DispatchAccess<type, size>(phys_addr, value))
|
||||
{
|
||||
Panic("Bus error");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06: // KSEG2
|
||||
case 0x07: // KSEG2
|
||||
{
|
||||
if (address == 0xFFFE0130)
|
||||
{
|
||||
if constexpr (type == MemoryAccessType::Read)
|
||||
value = m_cache_control;
|
||||
else
|
||||
WriteCacheControl(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
UnreachableCode();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<MemoryAccessType type, MemoryAccessSize size>
|
||||
bool CPU::Core::DoAlignmentCheck(VirtualMemoryAddress address)
|
||||
{
|
||||
if constexpr (size == MemoryAccessSize::HalfWord)
|
||||
{
|
||||
if (Common::IsAlignedPow2(address, 2))
|
||||
return true;
|
||||
}
|
||||
else if constexpr (size == MemoryAccessSize::Word)
|
||||
{
|
||||
if (Common::IsAlignedPow2(address, 4))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
m_cop0_regs.BadVaddr = address;
|
||||
RaiseException(type == MemoryAccessType::Read ? Exception::AdEL : Exception::AdES);
|
||||
return false;
|
||||
}
|
||||
|
||||
template<MemoryAccessType type, MemoryAccessSize size>
|
||||
void CPU::Core::DoScratchpadAccess(PhysicalMemoryAddress address, u32& value)
|
||||
{
|
||||
const PhysicalMemoryAddress cache_offset = address & DCACHE_OFFSET_MASK;
|
||||
if constexpr (size == MemoryAccessSize::Byte)
|
||||
{
|
||||
if constexpr (type == MemoryAccessType::Read)
|
||||
value = ZeroExtend32(m_dcache[cache_offset]);
|
||||
else
|
||||
m_dcache[cache_offset] = Truncate8(value);
|
||||
}
|
||||
else if constexpr (size == MemoryAccessSize::HalfWord)
|
||||
{
|
||||
if constexpr (type == MemoryAccessType::Read)
|
||||
{
|
||||
u16 temp;
|
||||
std::memcpy(&temp, &m_dcache[cache_offset], sizeof(temp));
|
||||
value = ZeroExtend32(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 temp = Truncate16(value);
|
||||
std::memcpy(&m_dcache[cache_offset], &temp, sizeof(temp));
|
||||
}
|
||||
}
|
||||
else if constexpr (size == MemoryAccessSize::Word)
|
||||
{
|
||||
if constexpr (type == MemoryAccessType::Read)
|
||||
std::memcpy(&value, &m_dcache[cache_offset], sizeof(value));
|
||||
else
|
||||
std::memcpy(&m_dcache[cache_offset], &value, sizeof(value));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace CPU
|
Reference in New Issue
Block a user