NV2A : Split up in the same way as OpenXbox. This makes differences between the two easier to spot.

This commit is contained in:
patrickvl 2018-01-25 01:12:56 +01:00 committed by PatrickvL
parent 5e419e8de3
commit 21db823596
24 changed files with 1898 additions and 1438 deletions

View File

@ -355,6 +355,27 @@
<None Include="..\..\src\CxbxKrnl\HLEDataBase\XOnline.1.0.5788.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\XOnline.1.0.5849.inl" />
<None Include="..\..\src\CxbxKrnl\HLEDataBase\XOnline.OOVPA.inl" />
<None Include="..\..\src\devices\video\EmuNV2A_DEBUG.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PBUS.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PCOUNTER.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PCRTC.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PFB.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PFIFO.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PGRAPH.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PMC.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PRAMDAC.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PRAMIN.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PRMA.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PRMCIO.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PRMDIO.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PRMFB.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PRMVIO.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PSTRAPS.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PTIMER.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PTV.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PVIDEO.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_PVPE.cpp" />
<None Include="..\..\src\devices\video\EmuNV2A_USER.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\resource\Cxbx.rc">

View File

@ -728,6 +728,69 @@
<None Include="..\..\src\CxbxKrnl\HLEDataBase\XOnline.OOVPA.inl">
<Filter>HLEDatabase\XOnline</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_DEBUG.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PBUS.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PCOUNTER.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PCRTC.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PFB.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PFIFO.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PGRAPH.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PMC.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PRAMDAC.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PRAMIN.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PRMA.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PRMCIO.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PRMDIO.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PRMFB.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PRMVIO.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PSTRAPS.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PTIMER.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PTV.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PVIDEO.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_PVPE.cpp">
<Filter>Hardware</Filter>
</None>
<None Include="..\..\src\devices\video\EmuNV2A_USER.cpp">
<Filter>Hardware</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Filter Include="GUI">

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,446 @@
#define DEBUG_START(DEV) \
const char *DebugNV_##DEV##(xbaddr addr) \
{ \
switch (addr) {
#define DEBUG_CASE(a) \
case a: return #a;
#define DEBUG_CASE_EX(a, c) \
case a: return #a##c;
#define DEBUG_END(DEV) \
default: \
return "Unknown " #DEV " Address"; \
} \
}
DEBUG_START(PMC)
DEBUG_CASE(NV_PMC_BOOT_0);
DEBUG_CASE(NV_PMC_BOOT_1);
DEBUG_CASE(NV_PMC_INTR_0);
DEBUG_CASE(NV_PMC_INTR_EN_0);
DEBUG_CASE(NV_PMC_ENABLE);
DEBUG_END(PMC)
DEBUG_START(PBUS)
DEBUG_CASE(NV_PBUS_FBIO_RAM)
DEBUG_CASE_EX(NV_PBUS_PCI_NV_0, ":VENDOR_ID");
DEBUG_CASE(NV_PBUS_PCI_NV_1);
DEBUG_CASE_EX(NV_PBUS_PCI_NV_2, ":REVISION_ID");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_3, ":LATENCY_TIMER");
DEBUG_CASE(NV_PBUS_PCI_NV_4);
DEBUG_CASE(NV_PBUS_PCI_NV_5);
DEBUG_CASE(NV_PBUS_PCI_NV_6);
DEBUG_CASE(NV_PBUS_PCI_NV_7);
DEBUG_CASE_EX(NV_PBUS_PCI_NV_11, ":SUBSYSTEM");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_12, ":ROM_BASE");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_13, ":CAP_PTR");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_14, ":RESERVED");
DEBUG_CASE(NV_PBUS_PCI_NV_15);
DEBUG_CASE_EX(NV_PBUS_PCI_NV_16, ":SUBSYSTEM");
DEBUG_CASE(NV_PBUS_PCI_NV_17);
DEBUG_CASE_EX(NV_PBUS_PCI_NV_18, ":AGP_STATUS");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_19, ":AGP_COMMAND");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_20, ":ROM_SHADOW");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_21, ":VGA");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_22, ":SCRATCH");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_23, ":DT_TIMEOUT");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_24, ":PME");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_25, ":POWER_STATE");
DEBUG_CASE_EX(NV_PBUS_PCI_NV_26, ":RESERVED");
DEBUG_END(PBUS)
DEBUG_START(PFIFO)
DEBUG_CASE(NV_PFIFO_DELAY_0);
DEBUG_CASE(NV_PFIFO_DMA_TIMESLICE);
DEBUG_CASE(NV_PFIFO_TIMESLICE);
DEBUG_CASE(NV_PFIFO_INTR_0);
DEBUG_CASE(NV_PFIFO_INTR_EN_0);
DEBUG_CASE(NV_PFIFO_RAMHT);
DEBUG_CASE(NV_PFIFO_RAMFC);
DEBUG_CASE(NV_PFIFO_RAMRO);
DEBUG_CASE(NV_PFIFO_RUNOUT_STATUS);
DEBUG_CASE(NV_PFIFO_RUNOUT_PUT_ADDRESS);
DEBUG_CASE(NV_PFIFO_RUNOUT_GET_ADDRESS);
DEBUG_CASE(NV_PFIFO_CACHES);
DEBUG_CASE(NV_PFIFO_MODE);
DEBUG_CASE(NV_PFIFO_DMA);
DEBUG_CASE(NV_PFIFO_SIZE)
DEBUG_CASE(NV_PFIFO_CACHE0_PUSH0);
DEBUG_CASE(NV_PFIFO_CACHE0_PULL0);
DEBUG_CASE(NV_PFIFO_CACHE0_HASH);
DEBUG_CASE(NV_PFIFO_CACHE1_PUSH0);
DEBUG_CASE(NV_PFIFO_CACHE1_PUSH1);
DEBUG_CASE(NV_PFIFO_CACHE1_PUT);
DEBUG_CASE(NV_PFIFO_CACHE1_STATUS);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_PUSH);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_FETCH);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_STATE);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_INSTANCE);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_CTL);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_PUT);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_GET);
DEBUG_CASE(NV_PFIFO_CACHE1_REF);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_SUBROUTINE);
DEBUG_CASE(NV_PFIFO_CACHE1_PULL0);
DEBUG_CASE(NV_PFIFO_CACHE1_PULL1);
DEBUG_CASE(NV_PFIFO_CACHE1_HASH);
DEBUG_CASE(NV_PFIFO_CACHE1_ACQUIRE_0);
DEBUG_CASE(NV_PFIFO_CACHE1_ACQUIRE_1);
DEBUG_CASE(NV_PFIFO_CACHE1_ACQUIRE_2);
DEBUG_CASE(NV_PFIFO_CACHE1_SEMAPHORE);
DEBUG_CASE(NV_PFIFO_CACHE1_GET);
DEBUG_CASE(NV_PFIFO_CACHE1_ENGINE);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_DCOUNT);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_RSVD_SHADOW);
DEBUG_CASE(NV_PFIFO_CACHE1_DMA_DATA_SHADOW);
DEBUG_END(PFIFO)
DEBUG_START(PRMA)
DEBUG_END(PRMA)
DEBUG_START(PVIDEO)
DEBUG_CASE(NV_PVIDEO_DEBUG_2);
DEBUG_CASE(NV_PVIDEO_DEBUG_3);
DEBUG_CASE(NV_PVIDEO_INTR);
DEBUG_CASE(NV_PVIDEO_INTR_EN);
DEBUG_CASE(NV_PVIDEO_BUFFER);
DEBUG_CASE(NV_PVIDEO_STOP);
DEBUG_CASE(NV_PVIDEO_BASE(0));
DEBUG_CASE(NV_PVIDEO_BASE(1));
DEBUG_CASE(NV_PVIDEO_LIMIT(0));
DEBUG_CASE(NV_PVIDEO_LIMIT(1));
DEBUG_CASE(NV_PVIDEO_LUMINANCE(0));
DEBUG_CASE(NV_PVIDEO_LUMINANCE(1));
DEBUG_CASE(NV_PVIDEO_CHROMINANCE(0));
DEBUG_CASE(NV_PVIDEO_CHROMINANCE(1));
DEBUG_CASE(NV_PVIDEO_OFFSET(0));
DEBUG_CASE(NV_PVIDEO_OFFSET(1));
DEBUG_CASE(NV_PVIDEO_SIZE_IN(0));
DEBUG_CASE(NV_PVIDEO_SIZE_IN(1));
DEBUG_CASE(NV_PVIDEO_POINT_IN(0));
DEBUG_CASE(NV_PVIDEO_POINT_IN(1));
DEBUG_CASE(NV_PVIDEO_DS_DX(0));
DEBUG_CASE(NV_PVIDEO_DS_DX(1));
DEBUG_CASE(NV_PVIDEO_DT_DY(0));
DEBUG_CASE(NV_PVIDEO_DT_DY(1));
DEBUG_CASE(NV_PVIDEO_POINT_OUT(0));
DEBUG_CASE(NV_PVIDEO_POINT_OUT(1));
DEBUG_CASE(NV_PVIDEO_SIZE_OUT(0));
DEBUG_CASE(NV_PVIDEO_SIZE_OUT(1));
DEBUG_CASE(NV_PVIDEO_FORMAT(0));
DEBUG_CASE(NV_PVIDEO_FORMAT(1));
DEBUG_END(PVIDEO)
DEBUG_START(PTIMER)
DEBUG_CASE(NV_PTIMER_INTR_0);
DEBUG_CASE(NV_PTIMER_INTR_EN_0);
DEBUG_CASE(NV_PTIMER_NUMERATOR);
DEBUG_CASE(NV_PTIMER_DENOMINATOR);
DEBUG_CASE(NV_PTIMER_TIME_0);
DEBUG_CASE(NV_PTIMER_TIME_1);
DEBUG_CASE(NV_PTIMER_ALARM_0);
DEBUG_END(PTIMER)
DEBUG_START(PCOUNTER)
DEBUG_END(PCOUNTER)
DEBUG_START(PVPE)
DEBUG_END(PVPE)
DEBUG_START(PTV)
DEBUG_END(PTV)
DEBUG_START(PRMFB)
DEBUG_END(PRMFB)
DEBUG_START(PRMVIO)
DEBUG_END(PRMVIO)
DEBUG_START(PFB)
DEBUG_CASE(NV_PFB_CFG0)
DEBUG_CASE(NV_PFB_CFG1)
DEBUG_CASE(NV_PFB_CSTATUS)
DEBUG_CASE(NV_PFB_REFCTRL)
DEBUG_CASE(NV_PFB_NVM) // NV_PFB_NVM_MODE_DISABLE
DEBUG_CASE(NV_PFB_PIN)
DEBUG_CASE(NV_PFB_PAD)
DEBUG_CASE(NV_PFB_TIMING0)
DEBUG_CASE(NV_PFB_TIMING1)
DEBUG_CASE(NV_PFB_TIMING2)
DEBUG_CASE(NV_PFB_TILE(0))
DEBUG_CASE(NV_PFB_TLIMIT(0))
DEBUG_CASE(NV_PFB_TSIZE(0))
DEBUG_CASE(NV_PFB_TSTATUS(0))
DEBUG_CASE(NV_PFB_TILE(1))
DEBUG_CASE(NV_PFB_TLIMIT(1))
DEBUG_CASE(NV_PFB_TSIZE(1))
DEBUG_CASE(NV_PFB_TSTATUS(1))
DEBUG_CASE(NV_PFB_TILE(2))
DEBUG_CASE(NV_PFB_TLIMIT(2))
DEBUG_CASE(NV_PFB_TSIZE(2))
DEBUG_CASE(NV_PFB_TSTATUS(2))
DEBUG_CASE(NV_PFB_TILE(3))
DEBUG_CASE(NV_PFB_TLIMIT(3))
DEBUG_CASE(NV_PFB_TSIZE(3))
DEBUG_CASE(NV_PFB_TSTATUS(3))
DEBUG_CASE(NV_PFB_TILE(4))
DEBUG_CASE(NV_PFB_TLIMIT(4))
DEBUG_CASE(NV_PFB_TSIZE(4))
DEBUG_CASE(NV_PFB_TSTATUS(4))
DEBUG_CASE(NV_PFB_TILE(5))
DEBUG_CASE(NV_PFB_TLIMIT(5))
DEBUG_CASE(NV_PFB_TSIZE(5))
DEBUG_CASE(NV_PFB_TSTATUS(5))
DEBUG_CASE(NV_PFB_TILE(6))
DEBUG_CASE(NV_PFB_TLIMIT(6))
DEBUG_CASE(NV_PFB_TSIZE(6))
DEBUG_CASE(NV_PFB_TSTATUS(6))
DEBUG_CASE(NV_PFB_TILE(7))
DEBUG_CASE(NV_PFB_TLIMIT(7))
DEBUG_CASE(NV_PFB_TSIZE(7))
DEBUG_CASE(NV_PFB_TSTATUS(7))
DEBUG_CASE(NV_PFB_MRS)
DEBUG_CASE(NV_PFB_EMRS)
DEBUG_CASE(NV_PFB_MRS_EXT)
DEBUG_CASE(NV_PFB_EMRS_EXT)
DEBUG_CASE(NV_PFB_REF)
DEBUG_CASE(NV_PFB_PRE)
DEBUG_CASE(NV_PFB_ZCOMP(0))
DEBUG_CASE(NV_PFB_ZCOMP(1))
DEBUG_CASE(NV_PFB_ZCOMP(2))
DEBUG_CASE(NV_PFB_ZCOMP(3))
DEBUG_CASE(NV_PFB_ZCOMP(4))
DEBUG_CASE(NV_PFB_ZCOMP(5))
DEBUG_CASE(NV_PFB_ZCOMP(6))
DEBUG_CASE(NV_PFB_ZCOMP(7))
DEBUG_CASE(NV_PFB_ZCOMP_OFFSET)
DEBUG_CASE(NV_PFB_ARB_PREDIVIDER)
DEBUG_CASE(NV_PFB_ARB_TIMEOUT)
DEBUG_CASE(NV_PFB_ARB_XFER_REM)
DEBUG_CASE(NV_PFB_ARB_DIFF_BANK)
DEBUG_CASE(NV_PFB_CLOSE_PAGE0)
DEBUG_CASE(NV_PFB_CLOSE_PAGE1)
DEBUG_CASE(NV_PFB_CLOSE_PAGE2)
DEBUG_CASE(NV_PFB_BPARB)
DEBUG_CASE(NV_PFB_CMDQ0)
DEBUG_CASE(NV_PFB_CMDQ1)
DEBUG_CASE(NV_PFB_ILL_INSTR)
DEBUG_CASE(NV_PFB_RT)
DEBUG_CASE(NV_PFB_AUTOCLOSE)
DEBUG_CASE(NV_PFB_WBC)
DEBUG_CASE(NV_PFB_CMDQ_PRT)
DEBUG_CASE(NV_PFB_CPU_RRQ)
DEBUG_CASE(NV_PFB_BYPASS);
DEBUG_END(PFB)
DEBUG_START(PSTRAPS)
DEBUG_END(PSTRAPS)
DEBUG_START(PGRAPH)
DEBUG_CASE(NV_PGRAPH_DEBUG_0);
DEBUG_CASE(NV_PGRAPH_DEBUG_1);
DEBUG_CASE(NV_PGRAPH_DEBUG_3);
DEBUG_CASE(NV_PGRAPH_DEBUG_4);
DEBUG_CASE(NV_PGRAPH_DEBUG_5);
DEBUG_CASE(NV_PGRAPH_DEBUG_8);
DEBUG_CASE(NV_PGRAPH_DEBUG_9);
DEBUG_CASE(NV_PGRAPH_INTR);
DEBUG_CASE(NV_PGRAPH_NSOURCE);
DEBUG_CASE(NV_PGRAPH_INTR_EN);
DEBUG_CASE(NV_PGRAPH_CTX_CONTROL);
DEBUG_CASE(NV_PGRAPH_CTX_USER);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH1);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH2);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH3);
DEBUG_CASE(NV_PGRAPH_CTX_SWITCH4);
DEBUG_CASE(NV_PGRAPH_STATUS);
DEBUG_CASE(NV_PGRAPH_TRAPPED_ADDR);
DEBUG_CASE(NV_PGRAPH_TRAPPED_DATA_LOW);
DEBUG_CASE(NV_PGRAPH_SURFACE);
DEBUG_CASE(NV_PGRAPH_INCREMENT);
DEBUG_CASE(NV_PGRAPH_FIFO);
DEBUG_CASE(NV_PGRAPH_RDI_INDEX);
DEBUG_CASE(NV_PGRAPH_RDI_DATA);
DEBUG_CASE(NV_PGRAPH_FFINTFC_ST2);
DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_TABLE);
DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_POINTER);
DEBUG_CASE(NV_PGRAPH_CHANNEL_CTX_TRIGGER);
DEBUG_CASE(NV_PGRAPH_DEBUG_2);
DEBUG_CASE(NV_PGRAPH_TTILE(0));
DEBUG_CASE(NV_PGRAPH_TLIMIT(0));
DEBUG_CASE(NV_PGRAPH_TSIZE(0));
DEBUG_CASE(NV_PGRAPH_TSTATUS(0));
DEBUG_CASE(NV_PGRAPH_TTILE(1));
DEBUG_CASE(NV_PGRAPH_TLIMIT(1));
DEBUG_CASE(NV_PGRAPH_TSIZE(1));
DEBUG_CASE(NV_PGRAPH_TSTATUS(1));
DEBUG_CASE(NV_PGRAPH_TTILE(2));
DEBUG_CASE(NV_PGRAPH_TLIMIT(2));
DEBUG_CASE(NV_PGRAPH_TSIZE(2));
DEBUG_CASE(NV_PGRAPH_TSTATUS(2));
DEBUG_CASE(NV_PGRAPH_TTILE(3));
DEBUG_CASE(NV_PGRAPH_TLIMIT(3));
DEBUG_CASE(NV_PGRAPH_TSIZE(3));
DEBUG_CASE(NV_PGRAPH_TSTATUS(3));
DEBUG_CASE(NV_PGRAPH_TTILE(4));
DEBUG_CASE(NV_PGRAPH_TLIMIT(4));
DEBUG_CASE(NV_PGRAPH_TSIZE(4));
DEBUG_CASE(NV_PGRAPH_TSTATUS(4));
DEBUG_CASE(NV_PGRAPH_TTILE(5));
DEBUG_CASE(NV_PGRAPH_TLIMIT(5));
DEBUG_CASE(NV_PGRAPH_TSIZE(5));
DEBUG_CASE(NV_PGRAPH_TSTATUS(5));
DEBUG_CASE(NV_PGRAPH_TTILE(6));
DEBUG_CASE(NV_PGRAPH_TLIMIT(6));
DEBUG_CASE(NV_PGRAPH_TSIZE(6));
DEBUG_CASE(NV_PGRAPH_TSTATUS(6));
DEBUG_CASE(NV_PGRAPH_TTILE(7));
DEBUG_CASE(NV_PGRAPH_TLIMIT(7));
DEBUG_CASE(NV_PGRAPH_TSIZE(7));
DEBUG_CASE(NV_PGRAPH_TSTATUS(7));
DEBUG_CASE(NV_PGRAPH_ZCOMP(0));
DEBUG_CASE(NV_PGRAPH_ZCOMP(1));
DEBUG_CASE(NV_PGRAPH_ZCOMP(2));
DEBUG_CASE(NV_PGRAPH_ZCOMP(3));
DEBUG_CASE(NV_PGRAPH_ZCOMP(4));
DEBUG_CASE(NV_PGRAPH_ZCOMP(5));
DEBUG_CASE(NV_PGRAPH_ZCOMP(6));
DEBUG_CASE(NV_PGRAPH_ZCOMP(7));
DEBUG_CASE(NV_PGRAPH_ZCOMP_OFFSET);
DEBUG_CASE(NV_PGRAPH_FBCFG0);
DEBUG_CASE(NV_PGRAPH_FBCFG1);
DEBUG_CASE(NV_PGRAPH_DEBUG_6);
DEBUG_CASE(NV_PGRAPH_DEBUG_7);
DEBUG_CASE(NV_PGRAPH_DEBUG_10);
DEBUG_CASE(NV_PGRAPH_CSV0_D);
DEBUG_CASE(NV_PGRAPH_CSV0_C);
DEBUG_CASE(NV_PGRAPH_CSV1_B);
DEBUG_CASE(NV_PGRAPH_CSV1_A);
DEBUG_CASE(NV_PGRAPH_CHEOPS_OFFSET);
DEBUG_CASE(NV_PGRAPH_BLEND);
DEBUG_CASE(NV_PGRAPH_BLENDCOLOR);
DEBUG_CASE(NV_PGRAPH_BORDERCOLOR0);
DEBUG_CASE(NV_PGRAPH_BORDERCOLOR1);
DEBUG_CASE(NV_PGRAPH_BORDERCOLOR2);
DEBUG_CASE(NV_PGRAPH_BORDERCOLOR3);
DEBUG_CASE(NV_PGRAPH_BUMPOFFSET1);
DEBUG_CASE(NV_PGRAPH_BUMPSCALE1);
DEBUG_CASE(NV_PGRAPH_CLEARRECTX);
DEBUG_CASE(NV_PGRAPH_CLEARRECTY);
DEBUG_CASE(NV_PGRAPH_COLORCLEARVALUE);
DEBUG_CASE(NV_PGRAPH_COMBINEFACTOR0);
DEBUG_CASE(NV_PGRAPH_COMBINEFACTOR1);
DEBUG_CASE(NV_PGRAPH_COMBINEALPHAI0);
DEBUG_CASE(NV_PGRAPH_COMBINEALPHAO0);
DEBUG_CASE(NV_PGRAPH_COMBINECOLORI0);
DEBUG_CASE(NV_PGRAPH_COMBINECOLORO0);
DEBUG_CASE(NV_PGRAPH_COMBINECTL);
DEBUG_CASE(NV_PGRAPH_COMBINESPECFOG0);
DEBUG_CASE(NV_PGRAPH_COMBINESPECFOG1);
DEBUG_CASE(NV_PGRAPH_CONTROL_0);
DEBUG_CASE(NV_PGRAPH_CONTROL_2);
DEBUG_CASE(NV_PGRAPH_CONTROL_3);
DEBUG_CASE(NV_PGRAPH_FOGCOLOR);
DEBUG_CASE(NV_PGRAPH_FOGPARAM0);
DEBUG_CASE(NV_PGRAPH_FOGPARAM1);
DEBUG_CASE(NV_PGRAPH_SETUPRASTER);
DEBUG_CASE(NV_PGRAPH_SHADERCLIPMODE);
DEBUG_CASE(NV_PGRAPH_SHADERCTL);
DEBUG_CASE(NV_PGRAPH_SHADERPROG);
DEBUG_CASE(NV_PGRAPH_SHADOWZSLOPETHRESHOLD);
DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR0);
DEBUG_CASE(NV_PGRAPH_SPECFOGFACTOR1);
DEBUG_CASE_EX(NV_PGRAPH_TEXADDRESS0, ":_ADDRV");
DEBUG_CASE(NV_PGRAPH_TEXADDRESS1);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS2);
DEBUG_CASE(NV_PGRAPH_TEXADDRESS3);
DEBUG_CASE(NV_PGRAPH_TEXCTL0_0);
DEBUG_CASE(NV_PGRAPH_TEXCTL0_1);
DEBUG_CASE(NV_PGRAPH_TEXCTL0_2);
DEBUG_CASE(NV_PGRAPH_TEXCTL0_3);
DEBUG_CASE(NV_PGRAPH_TEXCTL1_0);
DEBUG_CASE(NV_PGRAPH_TEXCTL1_1);
DEBUG_CASE(NV_PGRAPH_TEXCTL1_2);
DEBUG_CASE(NV_PGRAPH_TEXCTL1_3);
DEBUG_CASE(NV_PGRAPH_TEXCTL2_0);
DEBUG_CASE(NV_PGRAPH_TEXCTL2_1);
DEBUG_CASE(NV_PGRAPH_TEXFILTER0);
DEBUG_CASE(NV_PGRAPH_TEXFILTER1);
DEBUG_CASE(NV_PGRAPH_TEXFILTER2);
DEBUG_CASE(NV_PGRAPH_TEXFILTER3);
DEBUG_CASE(NV_PGRAPH_TEXFMT0);
DEBUG_CASE(NV_PGRAPH_TEXFMT1);
DEBUG_CASE(NV_PGRAPH_TEXFMT2);
DEBUG_CASE(NV_PGRAPH_TEXFMT3);
DEBUG_CASE(NV_PGRAPH_TEXIMAGERECT0);
DEBUG_CASE(NV_PGRAPH_TEXIMAGERECT1);
DEBUG_CASE(NV_PGRAPH_TEXIMAGERECT2);
DEBUG_CASE(NV_PGRAPH_TEXIMAGERECT3);
DEBUG_CASE(NV_PGRAPH_TEXOFFSET0);
DEBUG_CASE(NV_PGRAPH_TEXOFFSET1);
DEBUG_CASE(NV_PGRAPH_TEXOFFSET2);
DEBUG_CASE(NV_PGRAPH_TEXOFFSET3);
DEBUG_CASE(NV_PGRAPH_TEXPALETTE0);
DEBUG_CASE(NV_PGRAPH_TEXPALETTE1);
DEBUG_CASE(NV_PGRAPH_TEXPALETTE2);
DEBUG_CASE(NV_PGRAPH_TEXPALETTE3);
DEBUG_CASE(NV_PGRAPH_ZSTENCILCLEARVALUE);
DEBUG_CASE(NV_PGRAPH_ZCLIPMIN);
DEBUG_CASE(NV_PGRAPH_ZOFFSETBIAS);
DEBUG_CASE(NV_PGRAPH_ZOFFSETFACTOR);
DEBUG_CASE(NV_PGRAPH_EYEVEC0);
DEBUG_CASE(NV_PGRAPH_EYEVEC1);
DEBUG_CASE(NV_PGRAPH_EYEVEC2);
DEBUG_CASE(NV_PGRAPH_ZCLIPMAX);
DEBUG_END(PGRAPH)
DEBUG_START(PCRTC)
DEBUG_CASE(NV_PCRTC_INTR_0);
DEBUG_CASE(NV_PCRTC_INTR_EN_0);
DEBUG_CASE(NV_PCRTC_START);
DEBUG_CASE(NV_PCRTC_CONFIG);
DEBUG_END(PCRTC)
DEBUG_START(PRMCIO)
DEBUG_CASE(VGA_CRT_DC);
DEBUG_CASE(VGA_CRT_DM);
DEBUG_CASE(VGA_ATT_R);
DEBUG_CASE(VGA_ATT_W);
DEBUG_CASE(VGA_GFX_D);
DEBUG_CASE(VGA_SEQ_D);
DEBUG_CASE(VGA_MIS_R);
DEBUG_CASE(VGA_MIS_W);
DEBUG_CASE(VGA_FTC_R);
DEBUG_CASE(VGA_IS1_RC);
DEBUG_CASE(VGA_IS1_RM);
DEBUG_CASE(VGA_PEL_D);
DEBUG_CASE(VGA_PEL_MSK);
DEBUG_CASE(VGA_CRT_IC);
DEBUG_CASE(VGA_CRT_IM);
DEBUG_CASE(VGA_GFX_I);
DEBUG_CASE(VGA_SEQ_I);
DEBUG_CASE(VGA_PEL_IW);
DEBUG_CASE(VGA_PEL_IR);
DEBUG_END(PRMCIO)
DEBUG_START(PRAMDAC)
DEBUG_CASE(NV_PRAMDAC_NVPLL_COEFF);
DEBUG_CASE(NV_PRAMDAC_MPLL_COEFF);
DEBUG_CASE(NV_PRAMDAC_VPLL_COEFF);
DEBUG_CASE(NV_PRAMDAC_PLL_TEST_COUNTER);
DEBUG_END(PRAMDAC)
DEBUG_START(PRMDIO)
DEBUG_END(PRMDIO)
DEBUG_START(PRAMIN)
DEBUG_END(PRAMIN)
DEBUG_START(USER)
DEBUG_CASE(NV_USER_DMA_PUT);
DEBUG_CASE(NV_USER_DMA_GET);
DEBUG_CASE(NV_USER_REF);
DEBUG_END(USER)

View File

@ -0,0 +1,35 @@
DEVICE_READ32(PBUS)
{
DEVICE_READ32_SWITCH() {
case NV_PBUS_PCI_NV_0:
result = 0x10de; // PCI_VENDOR_ID_NVIDIA (?where to return PCI_DEVICE_ID_NVIDIA_NV2A = 0x01b7)
break;
case NV_PBUS_PCI_NV_1:
result = 1; // NV_PBUS_PCI_NV_1_IO_SPACE_ENABLED
break;
case NV_PBUS_PCI_NV_2:
result = (0x02 << 24) | 161; // PCI_CLASS_DISPLAY_3D (0x02) Rev 161 (0xA1)
break;
default:
DEBUG_READ32_UNHANDLED(PBUS); // TODO : DEVICE_READ32_REG(pbus);
break;
}
DEVICE_READ32_END(PBUS);
}
DEVICE_WRITE32(PBUS)
{
switch(addr) {
case NV_PBUS_PCI_NV_1:
// TODO : Handle write on NV_PBUS_PCI_NV_1 with 1 (NV_PBUS_PCI_NV_1_IO_SPACE_ENABLED) + 4 (NV_PBUS_PCI_NV_1_BUS_MASTER_ENABLED)
break;
default:
DEBUG_WRITE32_UNHANDLED(PBUS); // TODO : DEVICE_WRITE32_REG(pbus);
break;
}
DEVICE_WRITE32_END(PBUS);
}

View File

@ -0,0 +1,21 @@
DEVICE_READ32(PCOUNTER)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PCOUNTER); // TODO : DEVICE_READ32_REG(pcounter);
break;
}
DEVICE_READ32_END(PCOUNTER);
}
DEVICE_WRITE32(PCOUNTER)
{
switch (addr) {
default:
DEBUG_WRITE32_UNHANDLED(PCOUNTER); // TODO : DEVICE_WRITE32_REG(pcounter);
break;
}
DEVICE_WRITE32_END(PCOUNTER);
}

View File

@ -0,0 +1,45 @@
DEVICE_READ32(PCRTC)
{
DEVICE_READ32_SWITCH() {
case NV_PCRTC_INTR_0:
result = pcrtc.pending_interrupts;
break;
case NV_PCRTC_INTR_EN_0:
result = pcrtc.enabled_interrupts;
break;
case NV_PCRTC_START:
result = pcrtc.start;
break;
default:
result = 0;
//DEVICE_READ32_REG(pcrtc); // Was : DEBUG_READ32_UNHANDLED(PCRTC);
break;
}
DEVICE_READ32_END(PCRTC);
}
DEVICE_WRITE32(PCRTC)
{
switch (addr) {
case NV_PCRTC_INTR_0:
pcrtc.pending_interrupts &= ~value;
update_irq();
break;
case NV_PCRTC_INTR_EN_0:
pcrtc.enabled_interrupts = value;
update_irq();
break;
case NV_PCRTC_START:
pcrtc.start = value &= 0x07FFFFFF;
break;
default:
DEVICE_WRITE32_REG(pcrtc); // Was : DEBUG_WRITE32_UNHANDLED(PCRTC);
break;
}
DEVICE_WRITE32_END(PCRTC);
}

View File

@ -0,0 +1,33 @@
DEVICE_READ32(PFB)
{
DEVICE_READ32_SWITCH() {
case NV_PFB_CFG0:
result = 3; // = NV_PFB_CFG0_PART_4
break;
case NV_PFB_CSTATUS:
{
if (g_bIsChihiro || g_bIsDebug) { result = CONTIGUOUS_MEMORY_CHIHIRO_SIZE; break; }
result = CONTIGUOUS_MEMORY_XBOX_SIZE;
}
break;
case NV_PFB_WBC:
result = 0; // = !NV_PFB_WBC_FLUSH
break;
default:
DEVICE_READ32_REG(pfb);
break;
}
DEVICE_READ32_END(PFB);
}
DEVICE_WRITE32(PFB)
{
switch (addr) {
default:
DEVICE_WRITE32_REG(pfb);
break;
}
DEVICE_WRITE32_END(PFB);
}

View File

@ -0,0 +1,461 @@
DEVICE_READ32(PFIFO)
{
DEVICE_READ32_SWITCH() {
case NV_PFIFO_RAMHT:
result = 0x03000100; // = NV_PFIFO_RAMHT_SIZE_4K | NV_PFIFO_RAMHT_BASE_ADDRESS(NumberOfPaddingBytes >> 12) | NV_PFIFO_RAMHT_SEARCH_128
break;
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;
case NV_PFIFO_CACHE1_PUSH0:
result = pfifo.cache1.push_enabled;
break;
case NV_PFIFO_CACHE1_PUSH1:
SET_MASK(result, NV_PFIFO_CACHE1_PUSH1_CHID, pfifo.cache1.channel_id);
SET_MASK(result, NV_PFIFO_CACHE1_PUSH1_MODE, pfifo.cache1.mode);
break;
case NV_PFIFO_CACHE1_STATUS: {
std::lock_guard<std::mutex> lk(pfifo.cache1.mutex);
if (pfifo.cache1.cache.empty()) {
result |= NV_PFIFO_CACHE1_STATUS_LOW_MARK; /* low mark empty */
}
} break;
case NV_PFIFO_CACHE1_DMA_PUSH:
SET_MASK(result, NV_PFIFO_CACHE1_DMA_PUSH_ACCESS,
pfifo.cache1.dma_push_enabled);
SET_MASK(result, NV_PFIFO_CACHE1_DMA_PUSH_STATUS,
pfifo.cache1.dma_push_suspended);
SET_MASK(result, NV_PFIFO_CACHE1_DMA_PUSH_BUFFER, 1); /* buffer emoty */
break;
case NV_PFIFO_CACHE1_DMA_STATE:
SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_METHOD_TYPE,
pfifo.cache1.method_nonincreasing);
SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_METHOD,
pfifo.cache1.method >> 2);
SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL,
pfifo.cache1.subchannel);
SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT,
pfifo.cache1.method_count);
SET_MASK(result, NV_PFIFO_CACHE1_DMA_STATE_ERROR,
pfifo.cache1.error);
break;
case NV_PFIFO_CACHE1_DMA_INSTANCE:
SET_MASK(result, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK,
pfifo.cache1.dma_instance >> 4);
break;
case NV_PFIFO_CACHE1_DMA_PUT:
result = user.channel_control[pfifo.cache1.channel_id].dma_put;
break;
case NV_PFIFO_CACHE1_DMA_GET:
result = user.channel_control[pfifo.cache1.channel_id].dma_get;
break;
case NV_PFIFO_CACHE1_DMA_SUBROUTINE:
result = pfifo.cache1.subroutine_return
| pfifo.cache1.subroutine_active;
break;
case NV_PFIFO_CACHE1_PULL0: {
std::lock_guard<std::mutex> lk(pfifo.cache1.mutex);
result = pfifo.cache1.pull_enabled;
} break;
case NV_PFIFO_CACHE1_ENGINE: {
std::lock_guard<std::mutex> lk(pfifo.cache1.mutex);
for (int i = 0; i < NV2A_NUM_SUBCHANNELS; i++) {
result |= pfifo.cache1.bound_engines[i] << (i * 2);
}
} break;
case NV_PFIFO_CACHE1_DMA_DCOUNT:
result = pfifo.cache1.dcount;
break;
case NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW:
result = pfifo.cache1.get_jmp_shadow;
break;
case NV_PFIFO_CACHE1_DMA_RSVD_SHADOW:
result = pfifo.cache1.rsvd_shadow;
break;
case NV_PFIFO_CACHE1_DMA_DATA_SHADOW:
result = pfifo.cache1.data_shadow;
break;
default:
DEVICE_READ32_REG(pfifo); // Was : DEBUG_READ32_UNHANDLED(PFIFO);
break;
}
DEVICE_READ32_END(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;
case NV_PFIFO_CACHE1_PUSH0:
pfifo.cache1.push_enabled = value & NV_PFIFO_CACHE1_PUSH0_ACCESS;
break;
case NV_PFIFO_CACHE1_PUSH1:
pfifo.cache1.channel_id = GET_MASK(value, NV_PFIFO_CACHE1_PUSH1_CHID);
pfifo.cache1.mode = (FifoMode)GET_MASK(value, NV_PFIFO_CACHE1_PUSH1_MODE);
assert(pfifo.cache1.channel_id < NV2A_NUM_CHANNELS);
break;
case NV_PFIFO_CACHE1_DMA_PUSH:
pfifo.cache1.dma_push_enabled = GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_ACCESS);
if (pfifo.cache1.dma_push_suspended && !GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_STATUS)) {
pfifo.cache1.dma_push_suspended = false;
pfifo_run_pusher();
}
pfifo.cache1.dma_push_suspended = GET_MASK(value, NV_PFIFO_CACHE1_DMA_PUSH_STATUS);
break;
case NV_PFIFO_CACHE1_DMA_STATE:
pfifo.cache1.method_nonincreasing = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD_TYPE);
pfifo.cache1.method = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD) << 2;
pfifo.cache1.subchannel = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL);
pfifo.cache1.method_count = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT);
pfifo.cache1.error = GET_MASK(value, NV_PFIFO_CACHE1_DMA_STATE_ERROR);
break;
case NV_PFIFO_CACHE1_DMA_INSTANCE:
pfifo.cache1.dma_instance = GET_MASK(value, NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS_MASK) << 4;
break;
case NV_PFIFO_CACHE1_DMA_PUT:
user.channel_control[pfifo.cache1.channel_id].dma_put = value;
break;
case NV_PFIFO_CACHE1_DMA_GET:
user.channel_control[pfifo.cache1.channel_id].dma_get = value;
break;
case NV_PFIFO_CACHE1_DMA_SUBROUTINE:
pfifo.cache1.subroutine_return = (value & NV_PFIFO_CACHE1_DMA_SUBROUTINE_RETURN_OFFSET);
pfifo.cache1.subroutine_active = (value & NV_PFIFO_CACHE1_DMA_SUBROUTINE_STATE);
break;
case NV_PFIFO_CACHE1_PULL0: {
std::lock_guard<std::mutex> lk(pfifo.cache1.mutex);
if ((value & NV_PFIFO_CACHE1_PULL0_ACCESS)
&& !pfifo.cache1.pull_enabled) {
pfifo.cache1.pull_enabled = true;
/* the puller thread should wake up */
pfifo.cache1.cache_cond.notify_all();
} else if (!(value & NV_PFIFO_CACHE1_PULL0_ACCESS)
&& pfifo.cache1.pull_enabled) {
pfifo.cache1.pull_enabled = false;
}
} break;
case NV_PFIFO_CACHE1_ENGINE: {
std::lock_guard<std::mutex> lk(pfifo.cache1.mutex);
for (int i = 0; i < NV2A_NUM_SUBCHANNELS; i++) {
pfifo.cache1.bound_engines[i] = (FIFOEngine)((value >> (i * 2)) & 3);
}
} break;
case NV_PFIFO_CACHE1_DMA_DCOUNT:
pfifo.cache1.dcount = (value & NV_PFIFO_CACHE1_DMA_DCOUNT_VALUE);
break;
case NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW:
pfifo.cache1.get_jmp_shadow = (value & NV_PFIFO_CACHE1_DMA_GET_JMP_SHADOW_OFFSET);
break;
case NV_PFIFO_CACHE1_DMA_RSVD_SHADOW:
pfifo.cache1.rsvd_shadow = value;
break;
case NV_PFIFO_CACHE1_DMA_DATA_SHADOW:
pfifo.cache1.data_shadow = value;
break;
default:
DEVICE_WRITE32_REG(pfifo); // Was : DEBUG_WRITE32_UNHANDLED(PFIFO);
break;
}
DEVICE_WRITE32_END(PFIFO);
}
/* pusher should be fine to run from a mimo handler
* whenever's it's convenient */
static void pfifo_run_pusher() {
uint8_t channel_id;
ChannelControl *control;
Cache1State *state;
CacheEntry *command;
uint8_t *dma;
xbaddr dma_len;
uint32_t word;
/* TODO: How is cache1 selected? */
state = &pfifo.cache1;
channel_id = state->channel_id;
control = &user.channel_control[channel_id];
if (!state->push_enabled) return;
/* only handling DMA for now... */
/* Channel running DMA */
uint32_t channel_modes = pfifo.regs[NV_PFIFO_MODE];
assert(channel_modes & (1 << channel_id));
assert(state->mode == FIFO_DMA);
if (!state->dma_push_enabled) return;
if (state->dma_push_suspended) return;
/* We're running so there should be no pending errors... */
assert(state->error == NV_PFIFO_CACHE1_DMA_STATE_ERROR_NONE);
dma = (uint8_t*)nv_dma_map(state->dma_instance, &dma_len);
printf("DMA pusher: max 0x%08X, 0x%08X - 0x%08X\n",
dma_len, control->dma_get, control->dma_put);
/* based on the convenient pseudocode in envytools */
while (control->dma_get != control->dma_put) {
if (control->dma_get >= dma_len) {
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION;
break;
}
word = ldl_le_p((uint32_t*)(dma + control->dma_get));
control->dma_get += 4;
if (state->method_count) {
/* data word of methods command */
state->data_shadow = word;
command = (CacheEntry*)calloc(1, sizeof(CacheEntry));
command->method = state->method;
command->subchannel = state->subchannel;
command->nonincreasing = state->method_nonincreasing;
command->parameter = word;
std::lock_guard<std::mutex> lk(state->mutex);
state->cache.push(command);
state->cache_cond.notify_all();
if (!state->method_nonincreasing) {
state->method += 4;
}
state->method_count--;
state->dcount++;
} else {
/* no command active - this is the first word of a new one */
state->rsvd_shadow = word;
/* match all forms */
if ((word & 0xe0000003) == 0x20000000) {
/* old jump */
state->get_jmp_shadow = control->dma_get;
control->dma_get = word & 0x1fffffff;
printf("pb OLD_JMP 0x%08X\n", control->dma_get);
}
else if ((word & 3) == 1) {
/* jump */
state->get_jmp_shadow = control->dma_get;
control->dma_get = word & 0xfffffffc;
printf("pb JMP 0x%08X\n", control->dma_get);
}
else if ((word & 3) == 2) {
/* call */
if (state->subroutine_active) {
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_CALL;
break;
}
state->subroutine_return = control->dma_get;
state->subroutine_active = true;
control->dma_get = word & 0xfffffffc;
printf("pb CALL 0x%08X\n", control->dma_get);
}
else if (word == 0x00020000) {
/* return */
if (!state->subroutine_active) {
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_RETURN;
break;
}
control->dma_get = state->subroutine_return;
state->subroutine_active = false;
printf("pb RET 0x%08X\n", control->dma_get);
}
else if ((word & 0xe0030003) == 0) {
/* increasing methods */
state->method = word & 0x1fff;
state->subchannel = (word >> 13) & 7;
state->method_count = (word >> 18) & 0x7ff;
state->method_nonincreasing = false;
state->dcount = 0;
}
else if ((word & 0xe0030003) == 0x40000000) {
/* non-increasing methods */
state->method = word & 0x1fff;
state->subchannel = (word >> 13) & 7;
state->method_count = (word >> 18) & 0x7ff;
state->method_nonincreasing = true;
state->dcount = 0;
}
else {
printf("pb reserved cmd 0x%08X - 0x%08X\n",
control->dma_get, word);
state->error = NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD;
break;
}
}
}
printf("DMA pusher done: max 0x%08X, 0x%08X - 0x%08X\n",
dma_len, control->dma_get, control->dma_put);
if (state->error) {
printf("pb error: %d\n", state->error);
assert(false);
state->dma_push_suspended = true;
pfifo.pending_interrupts |= NV_PFIFO_INTR_0_DMA_PUSHER;
update_irq();
}
}
static void* pfifo_puller_thread()
{
Cache1State *state = &pfifo.cache1;
while (true) {
// Scope the lock so that it automatically unlocks at tne end of this block
{
std::unique_lock<std::mutex> lk(state->mutex);
while (state->cache.empty() || !state->pull_enabled) {
state->cache_cond.wait(lk);
}
// Copy cache to working_cache
while (!state->cache.empty()) {
state->working_cache.push(state->cache.front());
state->cache.pop();
}
}
while (!state->working_cache.empty()) {
CacheEntry* command = state->working_cache.front();
state->working_cache.pop();
if (command->method == 0) {
// qemu_mutex_lock_iothread();
RAMHTEntry entry = ramht_lookup(command->parameter);
assert(entry.valid);
assert(entry.channel_id == state->channel_id);
// qemu_mutex_unlock_iothread();
switch (entry.engine) {
case ENGINE_GRAPHICS:
pgraph_context_switch(entry.channel_id);
pgraph_wait_fifo_access();
pgraph_method(command->subchannel, 0, entry.instance);
break;
default:
assert(false);
break;
}
/* the engine is bound to the subchannel */
std::lock_guard<std::mutex> lk(pfifo.cache1.mutex);
state->bound_engines[command->subchannel] = entry.engine;
state->last_engine = entry.engine;
} else if (command->method >= 0x100) {
/* method passed to engine */
uint32_t parameter = command->parameter;
/* methods that take objects.
* TODO: Check this range is correct for the nv2a */
if (command->method >= 0x180 && command->method < 0x200) {
//qemu_mutex_lock_iothread();
RAMHTEntry entry = ramht_lookup(parameter);
assert(entry.valid);
assert(entry.channel_id == state->channel_id);
parameter = entry.instance;
//qemu_mutex_unlock_iothread();
}
// qemu_mutex_lock(&state->cache_lock);
enum FIFOEngine engine = state->bound_engines[command->subchannel];
// qemu_mutex_unlock(&state->cache_lock);
switch (engine) {
case ENGINE_GRAPHICS:
pgraph_wait_fifo_access();
pgraph_method(command->subchannel, command->method, parameter);
break;
default:
assert(false);
break;
}
// qemu_mutex_lock(&state->cache_lock);
state->last_engine = state->bound_engines[command->subchannel];
// qemu_mutex_unlock(&state->cache_lock);
}
free(command);
}
}
return NULL;
}
static uint32_t ramht_hash(uint32_t handle)
{
unsigned int ramht_size = 1 << (GET_MASK(pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
/* XXX: Think this is different to what nouveau calculates... */
unsigned int bits = ffs(ramht_size) - 2;
uint32_t hash = 0;
while (handle) {
hash ^= (handle & ((1 << bits) - 1));
handle >>= bits;
}
hash ^= pfifo.cache1.channel_id << (bits - 4);
return hash;
}
static RAMHTEntry ramht_lookup(uint32_t handle)
{
unsigned int ramht_size = 1 << (GET_MASK(pfifo.regs[NV_PFIFO_RAMHT], NV_PFIFO_RAMHT_SIZE_MASK) + 12);
uint32_t hash = ramht_hash(handle);
assert(hash * 8 < ramht_size);
uint32_t ramht_address =
GET_MASK(pfifo.regs[NV_PFIFO_RAMHT],
NV_PFIFO_RAMHT_BASE_ADDRESS_MASK) << 12;
uint8_t *entry_ptr = (uint8_t*)(NV2A_ADDR + NV_PRAMIN_ADDR + ramht_address + hash * 8);
uint32_t entry_handle = ldl_le_p((uint32_t*)entry_ptr);
uint32_t entry_context = ldl_le_p((uint32_t*)(entry_ptr + 4));
RAMHTEntry entry;
entry.handle = entry_handle;
entry.instance = (entry_context & NV_RAMHT_INSTANCE) << 4;
entry.engine = (FIFOEngine)((entry_context & NV_RAMHT_ENGINE) >> 16);
entry.channel_id = (entry_context & NV_RAMHT_CHID) >> 24;
entry.valid = entry_context & NV_RAMHT_STATUS;
return entry;
}

View File

@ -0,0 +1,117 @@
DEVICE_READ32(PGRAPH)
{
std::lock_guard<std::mutex> lk(pgraph.mutex);
DEVICE_READ32_SWITCH() {
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);
}
static void pgraph_set_context_user(uint32_t value)
{
pgraph.channel_id = (value & NV_PGRAPH_CTX_USER_CHID) >> 24;
pgraph.context[pgraph.channel_id].channel_3d = GET_MASK(value, NV_PGRAPH_CTX_USER_CHANNEL_3D);
pgraph.context[pgraph.channel_id].subchannel = GET_MASK(value, NV_PGRAPH_CTX_USER_SUBCH);
}
DEVICE_WRITE32(PGRAPH)
{
std::lock_guard<std::mutex> lk(pgraph.mutex);
switch (addr) {
case NV_PGRAPH_INTR:
pgraph.pending_interrupts &= ~value;
pgraph.interrupt_cond.notify_all();
break;
case NV_PGRAPH_INTR_EN:
pgraph.enabled_interrupts = value;
break;
case NV_PGRAPH_CTX_CONTROL:
pgraph.channel_valid = (value & NV_PGRAPH_CTX_CONTROL_CHID);
break;
case NV_PGRAPH_CTX_USER:
pgraph_set_context_user(value);
break;
case NV_PGRAPH_INCREMENT:
if (value & NV_PGRAPH_INCREMENT_READ_3D) {
SET_MASK(pgraph.regs[NV_PGRAPH_SURFACE],
NV_PGRAPH_SURFACE_READ_3D,
(GET_MASK(pgraph.regs[NV_PGRAPH_SURFACE],
NV_PGRAPH_SURFACE_READ_3D) + 1)
% GET_MASK(pgraph.regs[NV_PGRAPH_SURFACE],
NV_PGRAPH_SURFACE_MODULO_3D));
pgraph.flip_3d.notify_all();
}
break;
case NV_PGRAPH_FIFO:
pgraph.fifo_access = GET_MASK(value, NV_PGRAPH_FIFO_ACCESS);
pgraph.fifo_access_cond.notify_all();
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;
case NV_PGRAPH_CHANNEL_CTX_TRIGGER:
if (value & NV_PGRAPH_CHANNEL_CTX_TRIGGER_READ_IN) {
printf("PGRAPH: read channel %d context from %0x08X\n",
pgraph.channel_id, pgraph.context_address);
uint8_t *context_ptr = (uint8_t*)(NV2A_ADDR + NV_PRAMIN_ADDR + pgraph.context_address);
uint32_t context_user = ldl_le_p((uint32_t*)context_ptr);
printf(" - CTX_USER = 0x%x\n", context_user);
pgraph_set_context_user(context_user);
}
if (value & NV_PGRAPH_CHANNEL_CTX_TRIGGER_WRITE_OUT) {
/* do stuff ... */
}
break;
default:
DEVICE_WRITE32_REG(pgraph); // Was : DEBUG_WRITE32_UNHANDLED(PGRAPH);
break;
}
DEVICE_WRITE32_END(PGRAPH);
}

View File

@ -0,0 +1,45 @@
DEVICE_READ32(PMC)
{
DEVICE_READ32_SWITCH() {
case NV_PMC_BOOT_0: // chipset and stepping: NV2A, A02, Rev 0
result = 0x02A000A2;
break;
case NV_PMC_BOOT_1: // Selects big/little endian mode for the card
result = 0; // When read, returns 0 if in little-endian mode, 0x01000001 if in big-endian mode.
break;
case NV_PMC_INTR_0: // Shows which functional units have pending IRQ
result = pmc.pending_interrupts;
break;
case NV_PMC_INTR_EN_0: // Selects which functional units can cause IRQs
result = pmc.enabled_interrupts;
break;
default:
result = 0;
//DEVICE_READ32_REG(pmc); // Was : DEBUG_READ32_UNHANDLED(PMC);
break;
}
DEVICE_READ32_END(PMC);
}
DEVICE_WRITE32(PMC)
{
switch(addr) {
case NV_PMC_INTR_0:
pmc.pending_interrupts &= ~value;
update_irq();
break;
case NV_PMC_INTR_EN_0:
pmc.enabled_interrupts = value;
update_irq();
break;
default:
//DEVICE_WRITE32_REG(pmc); // Was : DEBUG_WRITE32_UNHANDLED(PMC);
break;
}
DEVICE_WRITE32_END(PMC);
}

View File

@ -0,0 +1,64 @@
DEVICE_READ32(PRAMDAC)
{
DEVICE_READ32_SWITCH() {
case NV_PRAMDAC_NVPLL_COEFF:
result = pramdac.core_clock_coeff;
break;
case NV_PRAMDAC_MPLL_COEFF:
result = pramdac.memory_clock_coeff;
break;
case NV_PRAMDAC_VPLL_COEFF:
result = pramdac.video_clock_coeff;
break;
case NV_PRAMDAC_PLL_TEST_COUNTER:
/* emulated PLLs locked instantly? */
result = NV_PRAMDAC_PLL_TEST_COUNTER_VPLL2_LOCK
| NV_PRAMDAC_PLL_TEST_COUNTER_NVPLL_LOCK
| NV_PRAMDAC_PLL_TEST_COUNTER_MPLL_LOCK
| NV_PRAMDAC_PLL_TEST_COUNTER_VPLL_LOCK;
break;
default:
//DEVICE_READ32_REG(pramdac); // Was : DEBUG_READ32_UNHANDLED(PRAMDAC);
break;
}
DEVICE_READ32_END(PRAMDAC);
}
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;
break;
case NV_PRAMDAC_VPLL_COEFF:
pramdac.video_clock_coeff = value;
break;
default:
//DEVICE_WRITE32_REG(pramdac); // Was : DEBUG_WRITE32_UNHANDLED(PRAMDAC);
break;
}
DEVICE_WRITE32_END(PRAMDAC);
}

View File

@ -0,0 +1,21 @@
DEVICE_READ32(PRAMIN)
{
DEVICE_READ32_SWITCH() {
default:
DEVICE_READ32_REG(pramin);
break;
}
DEVICE_READ32_END(PRAMIN);
}
DEVICE_WRITE32(PRAMIN)
{
switch (addr) {
default:
DEVICE_WRITE32_REG(pramin);
break;
}
DEVICE_WRITE32_END(PRAMIN);
}

View File

@ -0,0 +1,21 @@
DEVICE_READ32(PRMA)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PRMA); // TODO : DEVICE_READ32_REG(prma);
break;
}
DEVICE_READ32_END(PRMA);
}
DEVICE_WRITE32(PRMA)
{
switch(addr) {
default:
DEBUG_WRITE32_UNHANDLED(PRMA); // TODO : DEVICE_WRITE32_REG(prma);
break;
}
DEVICE_WRITE32_END(PRMA);
}

View File

@ -0,0 +1,70 @@
DEVICE_READ32(PRMCIO)
{
DEVICE_READ32_SWITCH() {
case VGA_CRT_IM:
case VGA_CRT_IC:
result = prmcio.cr_index;
break;
case VGA_CRT_DM:
case VGA_CRT_DC:
result = prmcio.cr[prmcio.cr_index];
printf("vga: read CR%x = 0x%02x\n", prmcio.cr_index, result);
break;
default:
DEBUG_READ32_UNHANDLED(PRMCIO);
printf("vga: UNHANDLED ADDR %s\n", addr);
break;
}
DEVICE_READ32_END(PRMCIO);
}
DEVICE_WRITE32(PRMCIO)
{
switch (addr) {
case VGA_CRT_IM:
case VGA_CRT_IC:
prmcio.cr_index = value;
break;
case VGA_CRT_DM:
case VGA_CRT_DC:
printf("vga: write CR%x = 0x%02x\n", prmcio.cr_index, value);
/* handle CR0-7 protection */
if ((prmcio.cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) &&
prmcio.cr_index <= VGA_CRTC_OVERFLOW) {
/* can always write bit 4 of CR7 */
if (prmcio.cr_index == VGA_CRTC_OVERFLOW) {
prmcio.cr[VGA_CRTC_OVERFLOW] = (prmcio.cr[VGA_CRTC_OVERFLOW] & ~0x10) |
(value & 0x10);
EmuWarning("TODO: vbe_update_vgaregs");
//vbe_update_vgaregs();
}
return;
}
prmcio.cr[prmcio.cr_index] = value;
EmuWarning("TODO: vbe_update_vgaregs");
//vbe_update_vgaregs();
switch (prmcio.cr_index) {
case VGA_CRTC_H_TOTAL:
case VGA_CRTC_H_SYNC_START:
case VGA_CRTC_H_SYNC_END:
case VGA_CRTC_V_TOTAL:
case VGA_CRTC_OVERFLOW:
case VGA_CRTC_V_SYNC_END:
case VGA_CRTC_MODE:
// TODO: s->update_retrace_info(s);
EmuWarning("TODO: update_retrace_info");
break;
}
break;
default:
DEBUG_WRITE32_UNHANDLED(PRMCIO); // TODO : DEVICE_WRITE32_REG(prmcio);
break;
}
DEVICE_WRITE32_END(PRMCIO);
}

View File

@ -0,0 +1,21 @@
DEVICE_READ32(PRMDIO)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PRMDIO);
break;
}
DEVICE_READ32_END(PRMDIO);
}
DEVICE_WRITE32(PRMDIO)
{
switch (addr) {
default:
DEBUG_WRITE32_UNHANDLED(PRMDIO);
break;
}
DEVICE_WRITE32_END(PRMDIO);
}

View File

@ -0,0 +1,22 @@
DEVICE_READ32(PRMFB)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PRMFB); // TODO : DEVICE_READ32_REG(prmfb);
break;
}
DEVICE_READ32_END(PRMFB);
}
DEVICE_WRITE32(PRMFB)
{
switch (addr) {
default:
DEBUG_WRITE32_UNHANDLED(PRMFB); // TODO : DEVICE_WRITE32_REG(prmfb);
break;
}
DEVICE_WRITE32_END(PRMFB);
}

View File

@ -0,0 +1,21 @@
DEVICE_READ32(PRMVIO)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PRMVIO); // TODO : DEVICE_READ32_REG(prmvio);
break;
}
DEVICE_READ32_END(PRMVIO);
}
DEVICE_WRITE32(PRMVIO)
{
switch (addr) {
default:
DEBUG_WRITE32_UNHANDLED(PRMVIO); // TODO : DEVICE_WRITE32_REG(prmvio);
break;
}
DEVICE_WRITE32_END(PRMVIO);
}

View File

@ -0,0 +1,23 @@
DEVICE_READ32(PSTRAPS)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PSTRAPS);
break;
}
DEVICE_READ32_END(PSTRAPS);
}
DEVICE_WRITE32(PSTRAPS)
{
switch (addr) {
default:
DEBUG_WRITE32_UNHANDLED(PSTRAPS);
break;
}
DEVICE_WRITE32_END(PSTRAPS);
}

View File

@ -0,0 +1,87 @@
static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
union {
uint64_t ll;
struct {
uint32_t low, high;
} l;
} u, res;
uint64_t rl, rh;
u.ll = a;
rl = (uint64_t)u.l.low * (uint64_t)b;
rh = (uint64_t)u.l.high * (uint64_t)b;
rh += (rl >> 32);
res.l.high = rh / c;
res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
return res.ll;
}
/* PIMTER - time measurement and time-based alarms */
static uint32_t ptimer_get_clock()
{
// Get time in nanoseconds
long int time = static_cast<long int>(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
return muldiv64(time, pramdac.core_clock_freq * ptimer.numerator, CLOCKS_PER_SEC * ptimer.denominator);
}
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_NUMERATOR:
result = ptimer.numerator;
break;
case NV_PTIMER_DENOMINATOR:
result = ptimer.denominator;
break;
case NV_PTIMER_TIME_0:
result = (ptimer_get_clock() & 0x7ffffff) << 5;
break;
case NV_PTIMER_TIME_1:
result = (ptimer_get_clock() >> 27) & 0x1fffffff;
break;
default:
result = 0;
//DEVICE_READ32_REG(ptimer); // Was : DEBUG_READ32_UNHANDLED(PTIMER);
break;
}
DEVICE_READ32_END(PTIMER);
}
DEVICE_WRITE32(PTIMER)
{
switch (addr) {
case NV_PTIMER_INTR_0:
ptimer.pending_interrupts &= ~value;
update_irq();
break;
case NV_PTIMER_INTR_EN_0:
ptimer.enabled_interrupts = value;
update_irq();
break;
case NV_PTIMER_DENOMINATOR:
ptimer.denominator = value;
break;
case NV_PTIMER_NUMERATOR:
ptimer.numerator = value;
break;
case NV_PTIMER_ALARM_0:
ptimer.alarm_time = value;
break;
default:
//DEVICE_WRITE32_REG(ptimer); // Was : DEBUG_WRITE32_UNHANDLED(PTIMER);
break;
}
DEVICE_WRITE32_END(PTIMER);
}

View File

@ -0,0 +1,21 @@
DEVICE_READ32(PTV)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PTV); // TODO : DEVICE_READ32_REG(ptv);
break;
}
DEVICE_READ32_END(PTV);
}
DEVICE_WRITE32(PTV)
{
switch (addr) {
default:
DEBUG_WRITE32_UNHANDLED(PTV); // TODO : DEVICE_WRITE32_REG(ptv);
break;
}
DEVICE_WRITE32_END(PTV);
}

View File

@ -0,0 +1,48 @@
/*
static void pvideo_vga_invalidate(NV2AState *d)
{
int y1 = GET_MASK(d->pvideo.regs[NV_PVIDEO_POINT_OUT],
NV_PVIDEO_POINT_OUT_Y);
int y2 = y1 + GET_MASK(d->pvideo.regs[NV_PVIDEO_SIZE_OUT],
NV_PVIDEO_SIZE_OUT_HEIGHT);
NV2A_DPRINTF("pvideo_vga_invalidate %d %d\n", y1, y2);
vga_invalidate_scanlines(&d->vga, y1, y2);
}
*/
DEVICE_READ32(PVIDEO)
{
DEVICE_READ32_SWITCH() {
case NV_PVIDEO_STOP:
result = 0;
break;
default:
DEVICE_READ32_REG(pvideo);
break;
}
DEVICE_READ32_END(PVIDEO);
}
DEVICE_WRITE32(PVIDEO)
{
switch (addr) {
case NV_PVIDEO_BUFFER:
pvideo.regs[addr] = value;
// TODO: vga.enable_overlay = true;
// pvideo_vga_invalidate(d);
break;
case NV_PVIDEO_STOP:
pvideo.regs[NV_PVIDEO_BUFFER] = 0;
// TODO: vga.enable_overlay = false;
//pvideo_vga_invalidate(d);
break;
default:
DEVICE_WRITE32_REG(pvideo);
break;
}
DEVICE_WRITE32_END(PVIDEO);
}

View File

@ -0,0 +1,23 @@
DEVICE_READ32(PVPE)
{
DEVICE_READ32_SWITCH() {
default:
DEBUG_READ32_UNHANDLED(PVPE); // TODO : DEVICE_READ32_REG(pvpe);
break;
}
DEVICE_READ32_END(PVPE);
}
DEVICE_WRITE32(PVPE)
{
switch (addr) {
default:
DEBUG_WRITE32_UNHANDLED(PVPE); // TODO : DEVICE_WRITE32_REG(pvpe);
break;
}
DEVICE_WRITE32_END(PVPE);
}

View File

@ -0,0 +1,70 @@
DEVICE_READ32(USER)
{
unsigned int channel_id = addr >> 16;
assert(channel_id < NV2A_NUM_CHANNELS);
ChannelControl *control = &user.channel_control[channel_id];
uint32_t channel_modes = pfifo.regs[NV_PFIFO_MODE];
/* PIO Mode */
if (!channel_modes & (1 << channel_id)) {
assert(false);
}
/* DMA Mode */
addr &= 0xFFFF;
DEVICE_READ32_SWITCH() {
case NV_USER_DMA_PUT:
result = control->dma_put;
break;
case NV_USER_DMA_GET:
result = control->dma_get;
break;
case NV_USER_REF:
result = control->ref;
break;
default:
DEBUG_READ32_UNHANDLED(USER);
break;
}
DEVICE_READ32_END(USER);
}
DEVICE_WRITE32(USER)
{
unsigned int channel_id = addr >> 16;
assert(channel_id < NV2A_NUM_CHANNELS);
ChannelControl *control = &user.channel_control[channel_id];
uint32_t channel_modes = pfifo.regs[NV_PFIFO_MODE];
if (channel_modes & (1 << channel_id)) {
/* DMA Mode */
switch (addr & 0xFFFF) {
case NV_USER_DMA_PUT:
control->dma_put = value;
if (pfifo.cache1.push_enabled) {
pfifo_run_pusher();
}
break;
case NV_USER_DMA_GET:
control->dma_get = value;
break;
case NV_USER_REF:
control->ref = value;
break;
default:
DEBUG_WRITE32_UNHANDLED(USER);
break;
}
}
else {
/* PIO Mode */
assert(false);
}
DEVICE_WRITE32_END(USER);
}