// TODO - verify that it is correct. Seems to work, though. void LoadIndexedXF(u32 val, int refarray) { int index = val >> 16; int address = val & 0xFFF; // check mask int size = ((val >> 12) & 0xF) + 1; //load stuff from array to address in xf mem u32* currData = (u32*)(&xfmem) + address; u32* newData = (u32*)Memory::GetPointer(arraybases[refarray] + arraystrides[refarray] * index); bool changed = false; for (int i = 0; i < size; ++i) { if (currData[i] != Common::swap32(newData[i])) { changed = true; XFMemWritten(size, address); break; } } if (changed) { for (int i = 0; i < size; ++i) currData[i] = Common::swap32(newData[i]); } }
// TODO - verify that it is correct. Seems to work, though. void LoadIndexedXF(u32 val, int refarray) { int index = val >> 16; int address = val & 0xFFF; // check mask int size = ((val >> 12) & 0xF) + 1; // load stuff from array to address in xf mem u32* currData = (u32*)(&xfmem) + address; u32* newData; if (Fifo::UseDeterministicGPUThread()) { newData = (u32*)Fifo::PopFifoAuxBuffer(size * sizeof(u32)); } else { newData = (u32*)Memory::GetPointer(g_main_cp_state.array_bases[refarray] + g_main_cp_state.array_strides[refarray] * index); } bool changed = false; for (int i = 0; i < size; ++i) { if (currData[i] != Common::swap32(newData[i])) { changed = true; XFMemWritten(size, address); break; } } if (changed) { for (int i = 0; i < size; ++i) currData[i] = Common::swap32(newData[i]); } }
void LoadXFReg(u32 transferSize, u32 baseAddress) { // do not allow writes past registers if (baseAddress + transferSize > 0x1058) { INFO_LOG(VIDEO, "XF load exceeds address space: %x %d bytes", baseAddress, transferSize); if (baseAddress >= 0x1058) transferSize = 0; else transferSize = 0x1058 - baseAddress; } // write to XF mem if (baseAddress < 0x1000 && transferSize > 0) { u32 end = baseAddress + transferSize; u32 xfMemBase = baseAddress; u32 xfMemTransferSize = transferSize; if (end >= 0x1000) { xfMemTransferSize = 0x1000 - baseAddress; baseAddress = 0x1000; transferSize = end - 0x1000; } else { transferSize = 0; } XFMemWritten(xfMemTransferSize, xfMemBase); for (u32 i = 0; i < xfMemTransferSize; i++) { ((u32*)&xfmem)[xfMemBase + i] = DataRead<u32>(); } } // write to XF regs if (transferSize > 0) { XFRegWritten(transferSize, baseAddress); for (u32 i = 0; i < transferSize; i++) { ((u32*)&xfmem)[baseAddress + i] = DataRead<u32>(); } } }
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) { // do not allow writes past registers if (baseAddress + transferSize > 0x1058) { INFO_LOG(VIDEO, "XF load exceeds address space: %x %d bytes", baseAddress, transferSize); if (baseAddress >= 0x1058) transferSize = 0; else transferSize = 0x1058 - baseAddress; } // write to XF mem if (baseAddress < 0x1000 && transferSize > 0) { u32 end = baseAddress + transferSize; u32 xfMemBase = baseAddress; u32 xfMemTransferSize = transferSize; if (end >= 0x1000) { xfMemTransferSize = 0x1000 - baseAddress; baseAddress = 0x1000; transferSize = end - 0x1000; } else { transferSize = 0; } XFMemWritten(xfMemTransferSize, xfMemBase); memcpy_gc(&xfmem[xfMemBase], pData, xfMemTransferSize * 4); pData += xfMemTransferSize; } // write to XF regs if (transferSize > 0) { XFRegWritten(transferSize, baseAddress, pData); memcpy_gc((u32*)(&xfregs) + (baseAddress - 0x1000), pData, transferSize * 4); } }