mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-26 16:59:35 -04:00
feat: added PS2 stubs and change runtime a bit
This commit is contained in:
+209
-12
@@ -258,7 +258,7 @@ __m128i PS2Memory::read128(uint32_t address)
|
||||
// Return zeroes for unsupported areas
|
||||
return _mm_setzero_si128();
|
||||
}
|
||||
|
||||
|
||||
void PS2Memory::write8(uint32_t address, uint8_t value)
|
||||
{
|
||||
uint32_t physAddr = translateAddress(address);
|
||||
@@ -280,7 +280,7 @@ void PS2Memory::write8(uint32_t address, uint8_t value)
|
||||
uint32_t newValue = (m_ioRegisters[regAddr] & mask) | ((uint32_t)value << shift);
|
||||
m_ioRegisters[regAddr] = newValue;
|
||||
|
||||
// Handle potential side effects of IO register writes
|
||||
// Handle potential side effects of IO register writes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,20 +327,19 @@ void PS2Memory::write32(uint32_t address, uint32_t value)
|
||||
|
||||
if (physAddr < PS2_RAM_SIZE)
|
||||
{
|
||||
// Check if this might be code modification
|
||||
markModified(address, 4);
|
||||
|
||||
*reinterpret_cast<uint32_t *>(&m_rdram[physAddr]) = value;
|
||||
}
|
||||
else if (physAddr >= PS2_SCRATCHPAD_BASE && physAddr < PS2_SCRATCHPAD_BASE + PS2_SCRATCHPAD_SIZE)
|
||||
{
|
||||
*reinterpret_cast<uint32_t *>(&m_scratchpad[physAddr - PS2_SCRATCHPAD_BASE]) = value;
|
||||
else if (physAddr >= 0x70000000 && physAddr < 0x70004000)
|
||||
{ // Scratchpad
|
||||
*reinterpret_cast<uint32_t *>(&m_scratchpad[physAddr - 0x70000000]) = value;
|
||||
}
|
||||
else if (physAddr >= PS2_IO_BASE && physAddr < PS2_IO_BASE + PS2_IO_SIZE)
|
||||
else if (physAddr >= 0x10000000 && physAddr < 0x10010000)
|
||||
{
|
||||
// IO registers
|
||||
m_ioRegisters[physAddr] = value;
|
||||
|
||||
// Handle potential side effects of IO register writes
|
||||
// This would be where we handle the various hardware effects
|
||||
// For example, writing to a DMA control register might trigger a transfer
|
||||
// Handle IO register writes with potential side effects
|
||||
writeIORegister(physAddr, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,4 +397,202 @@ void PS2Memory::write128(uint32_t address, __m128i value)
|
||||
write64(address, lo);
|
||||
write64(address + 8, hi);
|
||||
}
|
||||
}
|
||||
|
||||
bool PS2Memory::writeIORegister(uint32_t address, uint32_t value)
|
||||
{
|
||||
m_ioRegisters[address] = value;
|
||||
|
||||
// Now check if this is a special hardware register
|
||||
if (address >= 0x10000000 && address < 0x10010000)
|
||||
{
|
||||
// Timer/counter registers
|
||||
if (address >= 0x10000000 && address < 0x10000100)
|
||||
{
|
||||
std::cout << "Timer register write: " << std::hex << address << " = " << value << std::dec << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// DMA registers
|
||||
if (address >= 0x10008000 && address < 0x1000F000)
|
||||
{
|
||||
std::cout << "DMA register write: " << std::hex << address << " = " << value << std::dec << std::endl;
|
||||
|
||||
// Check if we need to start a DMA transfer
|
||||
if ((address & 0xFF) == 0x00)
|
||||
{ // CHCR registers
|
||||
if (value & 0x100)
|
||||
{
|
||||
uint32_t channelBase = address & 0xFFFFFF00;
|
||||
uint32_t madr = m_ioRegisters[channelBase + 0x10]; // Memory address
|
||||
uint32_t qwc = m_ioRegisters[channelBase + 0x20]; // Quadword count
|
||||
|
||||
std::cout << "Starting DMA transfer on channel " << ((address >> 8) & 0xF)
|
||||
<< ", MADR: " << std::hex << madr
|
||||
<< ", QWC: " << qwc << std::dec << std::endl;
|
||||
|
||||
// Would actually start DMA here
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Interrupt control registers
|
||||
if (address >= 0x10000200 && address < 0x10000300)
|
||||
{
|
||||
std::cout << "Interrupt register write: " << std::hex << address << " = " << value << std::dec << std::endl;
|
||||
// Handle interrupt register side effects
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (address >= 0x12000000 && address < 0x12001000)
|
||||
{
|
||||
// GS registers
|
||||
std::cout << "GS register write: " << std::hex << address << " = " << value << std::dec << std::endl;
|
||||
// Handle GS register side effects
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t PS2Memory::readIORegister(uint32_t address)
|
||||
{
|
||||
auto it = m_ioRegisters.find(address);
|
||||
if (it != m_ioRegisters.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Special cases for reads from hardware registers that have side effects
|
||||
if (address >= 0x10000000 && address < 0x10010000)
|
||||
{
|
||||
// Timer registers
|
||||
if (address >= 0x10000000 && address < 0x10000100)
|
||||
{
|
||||
if ((address & 0xF) == 0x00)
|
||||
{ // COUNT registers
|
||||
uint32_t timerCount = 0; // Should calculate based on elapsed time
|
||||
std::cout << "Timer COUNT read: " << std::hex << address << " = " << timerCount << std::dec << std::endl;
|
||||
return timerCount;
|
||||
}
|
||||
}
|
||||
|
||||
// DMA status registers
|
||||
if (address >= 0x10008000 && address < 0x1000F000)
|
||||
{
|
||||
if ((address & 0xFF) == 0x00)
|
||||
{ // CHCR registers
|
||||
uint32_t channelStatus = m_ioRegisters[address] & ~0x100; // Clear busy bit
|
||||
std::cout << "DMA status read: " << std::hex << address << " = " << channelStatus << std::dec << std::endl;
|
||||
return channelStatus;
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt status registers
|
||||
if (address >= 0x10000200 && address < 0x10000300)
|
||||
{
|
||||
std::cout << "Interrupt status read: " << std::hex << address << std::dec << std::endl;
|
||||
// Should calculate based on pending interrupts
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PS2Memory::registerCodeRegion(uint32_t start, uint32_t end)
|
||||
{
|
||||
CodeRegion region;
|
||||
region.start = start;
|
||||
region.end = end;
|
||||
|
||||
// Initialize the modified bitmap (one bit per 4-byte word)
|
||||
size_t sizeInWords = (end - start) / 4;
|
||||
region.modified.resize(sizeInWords, false);
|
||||
|
||||
m_codeRegions.push_back(region);
|
||||
std::cout << "Registered code region: " << std::hex << start << " - " << end << std::dec << std::endl;
|
||||
}
|
||||
|
||||
bool PS2Memory::isAddressInRegion(uint32_t address, const CodeRegion ®ion)
|
||||
{
|
||||
return (address >= region.start && address < region.end);
|
||||
}
|
||||
|
||||
void PS2Memory::markModified(uint32_t address, uint32_t size)
|
||||
{
|
||||
for (auto ®ion : m_codeRegions)
|
||||
{
|
||||
if (address + size <= region.start || address >= region.end)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t overlapStart = std::max(address, region.start);
|
||||
uint32_t overlapEnd = std::min(address + size, region.end);
|
||||
|
||||
// Mark each 4-byte word in the overlap as modified
|
||||
for (uint32_t addr = overlapStart; addr < overlapEnd; addr += 4)
|
||||
{
|
||||
size_t bitIndex = (addr - region.start) / 4;
|
||||
if (bitIndex < region.modified.size())
|
||||
{
|
||||
region.modified[bitIndex] = true;
|
||||
std::cout << "Marked code at " << std::hex << addr << std::dec << " as modified" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PS2Memory::isCodeModified(uint32_t address, uint32_t size)
|
||||
{
|
||||
for (const auto ®ion : m_codeRegions)
|
||||
{
|
||||
if (address + size <= region.start || address >= region.end)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate overlap
|
||||
uint32_t overlapStart = std::max(address, region.start);
|
||||
uint32_t overlapEnd = std::min(address + size, region.end);
|
||||
|
||||
// Check each 4-byte word in the overlap
|
||||
for (uint32_t addr = overlapStart; addr < overlapEnd; addr += 4)
|
||||
{
|
||||
size_t bitIndex = (addr - region.start) / 4;
|
||||
if (bitIndex < region.modified.size() && region.modified[bitIndex])
|
||||
{
|
||||
return true; // Found modified code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false; // No modifications found
|
||||
}
|
||||
|
||||
void PS2Memory::clearModifiedFlag(uint32_t address, uint32_t size)
|
||||
{
|
||||
for (auto ®ion : m_codeRegions)
|
||||
{
|
||||
if (address + size <= region.start || address >= region.end)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate overlap
|
||||
uint32_t overlapStart = std::max(address, region.start);
|
||||
uint32_t overlapEnd = std::min(address + size, region.end);
|
||||
|
||||
// Clear flags for each 4-byte word in the overlap
|
||||
for (uint32_t addr = overlapStart; addr < overlapEnd; addr += 4)
|
||||
{
|
||||
size_t bitIndex = (addr - region.start) / 4;
|
||||
if (bitIndex < region.modified.size())
|
||||
{
|
||||
region.modified[bitIndex] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user