Merge pull request #557 from LukeUsher/lle

NV2A Work
This commit is contained in:
PatrickvL 2017-07-31 10:17:29 +02:00 committed by GitHub
commit c859f0d375
3 changed files with 175 additions and 29 deletions

View File

@ -299,6 +299,22 @@ void *CxbxRestoreContiguousMemory(char *szFilePath_memory_bin)
else
DbgPrintf("EmuMain: Loaded contiguous memory.bin\n");
// Map memory.bin contents into tiled memory too :
void *tiled_memory = (void *)MapViewOfFileEx(
hFileMapping,
FILE_MAP_READ | FILE_MAP_WRITE,
/* dwFileOffsetHigh */0,
/* dwFileOffsetLow */0,
CONTIGUOUS_MEMORY_SIZE,
(void *)0xF0000000);
if (tiled_memory == NULL)
{
CxbxKrnlCleanup("CxbxRestoreContiguousMemory: Couldn't map contiguous memory.bin into tiled memory!");
return nullptr;
}
DbgPrintf("EmuMain: Mapped contiguous to tiled memory\n");
return memory;
}

View File

@ -156,9 +156,32 @@ struct {
uint32_t regs[NV_PRAMIN_SIZE / sizeof(uint32_t)]; // TODO : union
} pramin;
typedef struct GraphicsContext {
bool channel_3d;
unsigned int subchannel;
} GraphicsContext;
struct {
uint32_t pending_interrupts;
uint32_t enabled_interrupts;
uint32_t context_table;
uint32_t context_address;
unsigned int trapped_method;
unsigned int trapped_subchannel;
unsigned int trapped_channel_id;
uint32_t trapped_data[2];
uint32_t notify_source;
bool fifo_access;
unsigned int channel_id;
bool channel_valid;
GraphicsContext context[NV2A_NUM_CHANNELS];
uint32_t regs[NV_PGRAPH_SIZE / sizeof(uint32_t)]; // TODO : union
} pgraph;
@ -435,6 +458,7 @@ DEBUG_START(PGRAPH)
DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR0);
DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR1);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS0);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS0_ADDRV);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS1);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS2);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS3);
@ -509,7 +533,7 @@ DEBUG_START(USER)
DEBUG_CASE(NV_USER_DMA_GET);
DEBUG_CASE(NV_USER_REF);
DEBUG_END(USER)
DEBUG_END(USER)
@ -530,6 +554,18 @@ DEBUG_END(USER)
#define DEVICE_WRITE32_END(DEV) DEBUG_WRITE32(DEV)
DWORD __index;
#define GET_MASK(v, mask) { \
(bool)(((value) & (mask)) >> (_BitScanForward(&__index, mask) - 1)) \
}
#define SET_MASK(v, mask, val) { \
const unsigned int __val = val; \
const unsigned int __mask = mask; \
(v) &= ~(__mask); \
(v) |= ((__val) << (_BitScanForward(&__index, __mask)-1)) & (__mask); \
}
DEVICE_READ32(PMC)
{
DEVICE_READ32_SWITCH() {
@ -542,9 +578,6 @@ DEVICE_READ32(PMC)
case NV_PMC_INTR_EN_0:
result = pmc.enabled_interrupts;
break;
case 0x0000020C: // What's this address? What does the xbe expect to read here? The Kernel base address perhaps?
result = NV20_REG_BASE_KERNEL;
break;
default:
DEVICE_READ32_REG(pmc); // Was : DEBUG_READ32_UNHANDLED(PMC);
break;
@ -620,6 +653,15 @@ DEVICE_READ32(PFIFO)
case NV_PFIFO_RAMFC:
result = 0x00890110; // = ? | NV_PFIFO_RAMFC_SIZE_2K | ?
break;
case NV_PFIFO_INTR_0:
result = pfifo.pending_interrupts;
break;
case NV_PFIFO_INTR_EN_0:
result = pfifo.enabled_interrupts;
break;
case NV_PFIFO_RUNOUT_STATUS:
result = NV_PFIFO_RUNOUT_STATUS_LOW_MARK; /* low mark empty */
break;
default:
DEVICE_READ32_REG(pfifo); // Was : DEBUG_READ32_UNHANDLED(PFIFO);
break;
@ -631,6 +673,14 @@ DEVICE_READ32(PFIFO)
DEVICE_WRITE32(PFIFO)
{
switch(addr) {
case NV_PFIFO_INTR_0:
pfifo.pending_interrupts &= ~value;
update_irq();
break;
case NV_PFIFO_INTR_EN_0:
pfifo.enabled_interrupts = value;
update_irq();
break;
default:
DEVICE_WRITE32_REG(pfifo); // Was : DEBUG_WRITE32_UNHANDLED(PFIFO);
break;
@ -715,7 +765,12 @@ DEVICE_WRITE32(PCOUNTER)
DEVICE_READ32(PTIMER)
{
DEVICE_READ32_SWITCH() {
case NV_PTIMER_INTR_0:
result = ptimer.pending_interrupts;
break;
case NV_PTIMER_INTR_EN_0:
result = ptimer.enabled_interrupts;
break;
case NV_PTIMER_DENOMINATOR:
result = ptimer.denominator;
break;
@ -864,6 +919,9 @@ DEVICE_READ32(PFB)
case NV_PFB_CFG0:
result = 3; // = NV_PFB_CFG0_PART_4
break;
case NV_PFB_CSTATUS:
result = CONTIGUOUS_MEMORY_SIZE;
break;
case NV_PFB_WBC:
result = 0; // = !NV_PFB_WBC_FLUSH
break;
@ -913,24 +971,69 @@ DEVICE_WRITE32(PSTRAPS)
DEVICE_READ32(PGRAPH)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PGRAPH);
case NV_PGRAPH_INTR:
result = pgraph.pending_interrupts;
break;
case NV_PGRAPH_INTR_EN:
result = pgraph.enabled_interrupts;
break;
case NV_PGRAPH_NSOURCE:
result = pgraph.notify_source;
break;
case NV_PGRAPH_CTX_USER:
SET_MASK(result, NV_PGRAPH_CTX_USER_CHANNEL_3D,
pgraph.context[pgraph.channel_id].channel_3d);
SET_MASK(result, NV_PGRAPH_CTX_USER_CHANNEL_3D_VALID, 1);
SET_MASK(result, NV_PGRAPH_CTX_USER_SUBCH,
pgraph.context[pgraph.channel_id].subchannel << 13);
SET_MASK(result, NV_PGRAPH_CTX_USER_CHID, pgraph.channel_id);
break;
case NV_PGRAPH_TRAPPED_ADDR:
SET_MASK(result, NV_PGRAPH_TRAPPED_ADDR_CHID, pgraph.trapped_channel_id);
SET_MASK(result, NV_PGRAPH_TRAPPED_ADDR_SUBCH, pgraph.trapped_subchannel);
SET_MASK(result, NV_PGRAPH_TRAPPED_ADDR_MTHD, pgraph.trapped_method);
break;
case NV_PGRAPH_TRAPPED_DATA_LOW:
result = pgraph.trapped_data[0];
break;
case NV_PGRAPH_FIFO:
SET_MASK(result, NV_PGRAPH_FIFO_ACCESS, pgraph.fifo_access);
break;
case NV_PGRAPH_CHANNEL_CTX_TABLE:
result = pgraph.context_table >> 4;
break;
case NV_PGRAPH_CHANNEL_CTX_POINTER:
result = pgraph.context_address >> 4;
break;
default:
DEVICE_READ32_REG(pgraph); // Was : DEBUG_READ32_UNHANDLED(PGRAPH);
}
DEVICE_READ32_END(PGRAPH);
}
}
DEVICE_WRITE32(PGRAPH)
{
switch (addr) {
case NV_PGRAPH_INTR:
pgraph.pending_interrupts &= ~value;
update_irq();
break;
case NV_PGRAPH_INTR_EN:
pgraph.enabled_interrupts = value;
update_irq();
break;
case NV_PGRAPH_CTX_CONTROL:
pgraph.channel_valid = (value & NV_PGRAPH_CTX_CONTROL_CHID);
break;
case NV_PGRAPH_FIFO:
pgraph.fifo_access = GET_MASK(value, NV_PGRAPH_FIFO_ACCESS);
break;
case NV_PGRAPH_CHANNEL_CTX_TABLE:
pgraph.context_table =
(value & NV_PGRAPH_CHANNEL_CTX_TABLE_INST) << 4;
break;
case NV_PGRAPH_CHANNEL_CTX_POINTER:
pgraph.context_address =
(value & NV_PGRAPH_CHANNEL_CTX_POINTER_INST) << 4;
break;
default:
DEVICE_WRITE32_REG(pgraph); // Was : DEBUG_WRITE32_UNHANDLED(PGRAPH);
@ -1043,8 +1146,22 @@ DEVICE_WRITE32(PRAMDAC)
{
switch (addr) {
uint32_t m, n, p;
case NV_PRAMDAC_NVPLL_COEFF:
pramdac.core_clock_coeff = value;
m = value & NV_PRAMDAC_NVPLL_COEFF_MDIV;
n = (value & NV_PRAMDAC_NVPLL_COEFF_NDIV) >> 8;
p = (value & NV_PRAMDAC_NVPLL_COEFF_PDIV) >> 16;
if (m == 0) {
pramdac.core_clock_freq = 0;
}
else {
pramdac.core_clock_freq = (NV2A_CRYSTAL_FREQ * n)
/ (1 << p) / m;
}
break;
case NV_PRAMDAC_MPLL_COEFF:
pramdac.memory_clock_coeff = value;
@ -1508,16 +1625,6 @@ void InitOpenGLContext()
HGLRC RC;
std::string szCode;
//glutInit();
{ // rb_init_context();
/* link in gl functions at runtime */
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (err != GLEW_OK) {
//LOG_WARNING("GLEW initialization failed: %s", glewGetErrorString(err));
return;
}
}
g_EmuWindowsDC = GetDC(g_hEmuWindow); // Actually, you can use any windowed control here
SetupPixelFormat(g_EmuWindowsDC);
@ -1537,6 +1644,18 @@ void InitOpenGLContext()
//DxbxUpdateTransformProjection();
//DxbxUpdateViewport();
//glutInit();
{ // rb_init_context();
/* link in gl functions at runtime */
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (err != GLEW_OK) {
EmuWarning("GLEW initialization failed: %s", glewGetErrorString(err));
return;
}
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Switch to left-handed coordinate space (as per http://www.opengl.org/resources/faq/technical/transformations.htm) :
@ -1613,4 +1732,12 @@ void InitOpenGLContext()
// glBindProgramARB(GL_VERTEX_PROGRAM_ARB, VertexProgramIDs[0]);
DxbxCompileShader(szCode);
// TODO: EmuNV2A_Init
pcrtc.start = 0;
pramdac.core_clock_coeff = 0x00011c01; /* 189MHz...? */
pramdac.core_clock_freq = 189000000;
pramdac.memory_clock_coeff = 0;
pramdac.video_clock_coeff = 0x0003C20D; /* 25182Khz...? */
}

View File

@ -210,15 +210,15 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
// Fix up Render state and Texture States
if (g_SymbolAddresses.find("D3DDeferredRenderState") == g_SymbolAddresses.end()) {
CxbxKrnlCleanup("EmuD3DDeferredRenderState was not found!");
EmuWarning("EmuD3DDeferredRenderState was not found!");
}
if (g_SymbolAddresses.find("D3DDeferredTextureState") == g_SymbolAddresses.end()) {
CxbxKrnlCleanup("EmuD3DDeferredTextureState was not found!");
EmuWarning("EmuD3DDeferredTextureState was not found!");
}
if (g_SymbolAddresses.find("D3DDEVICE") == g_SymbolAddresses.end()) {
CxbxKrnlCleanup("D3DDEVICE was not found!");
EmuWarning("D3DDEVICE was not found!");
}
XTL::EmuD3DDeferredRenderState = (DWORD*)g_SymbolAddresses["D3DDeferredRenderState"];
@ -226,14 +226,17 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
XRefDataBase[XREF_D3DDEVICE] = g_SymbolAddresses["D3DDEVICE"];
// TODO: Move this into a function rather than duplicating from HLE scanning code
for (int v = 0; v<44; v++) {
XTL::EmuD3DDeferredRenderState[v] = XTL::X_D3DRS_UNK;
}
if (XTL::EmuD3DDeferredRenderState != nullptr) {
for (int v = 0; v<44; v++) {
XTL::EmuD3DDeferredRenderState[v] = XTL::X_D3DRS_UNK;
}
for (int s = 0; s<4; s++) {
for (int v = 0; v<32; v++)
XTL::EmuD3DDeferredTextureState[v + s * 32] = X_D3DTSS_UNK;
for (int s = 0; s<4; s++) {
for (int v = 0; v<32; v++)
XTL::EmuD3DDeferredTextureState[v + s * 32] = X_D3DTSS_UNK;
}
}
g_HLECacheUsed = true;
}