From f5687370831c83ae6bd8aac05c8e79102a2dff35 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 2 Feb 2025 00:43:27 +0000 Subject: [PATCH] various logging/pfifo fixes, add pfifo ctx --- .../nv3_object_classes_driver.txt | 57 ------------------- src/include/86box/nv/vid_nv3.h | 16 ++++-- src/video/nv/nv3/subsystems/nv3_pbus.c | 2 +- src/video/nv/nv3/subsystems/nv3_pextdev.c | 2 +- src/video/nv/nv3/subsystems/nv3_pfb.c | 2 +- src/video/nv/nv3/subsystems/nv3_pfifo.c | 49 +++++++++++++--- src/video/nv/nv3/subsystems/nv3_pgraph.c | 6 +- src/video/nv/nv3/subsystems/nv3_pmc.c | 2 +- src/video/nv/nv3/subsystems/nv3_pme.c | 2 +- src/video/nv/nv3/subsystems/nv3_pramdac.c | 2 +- src/video/nv/nv3/subsystems/nv3_ptimer.c | 9 +-- src/video/nv/nv3/subsystems/nv3_pvideo.c | 2 +- 12 files changed, 66 insertions(+), 85 deletions(-) delete mode 100644 doc/nvidia_notes/nv3_object_classes_driver.txt diff --git a/doc/nvidia_notes/nv3_object_classes_driver.txt b/doc/nvidia_notes/nv3_object_classes_driver.txt deleted file mode 100644 index 3e4955a80..000000000 --- a/doc/nvidia_notes/nv3_object_classes_driver.txt +++ /dev/null @@ -1,57 +0,0 @@ -Object classes - -NOT represented by the GPU. These are the ones the drivers recognise. Most of them are faked. - -Version 0.77_win95 (!!!) - -object class 1 = "general" methods shared across all objects -object class 2 = DMA from memory -object class 3 = DMA to memory -object class 4 = timer -object class 5 = chip ID -object class 6 = "context ordinal" -object class 10/0Ah = patchcord (links objects together) -object class 11/0Bh = video sink -object class 12/0Ch = video switch -object class 13/0Dh = video colormap -object class 14/0Eh = patchcord...again -object class 15/0Fh = image to video -object class 16/10h = image stencil buffer -object class 17/11h = image blending methods -object class 18/12h = beta solid -object class 19/13h = image -> render operation -object class 20/14h = ROP5 (2^5 = 32bit rop) -object class 21/15h = color key -object class 22/16h = plane switch -object class 23/17h = "solid image" -object class 24/18h = pattern -object class 25/19h = black rectangle -object class 26/1Ah = solid point -object class 27/1Bh = solid line -object class 28/1Ch = solid lin (line without its ending or starting pixel) -object class 29/1Dh = triangle -object class 30/1Eh = solid rectangle -object class 31/1Fh = blit image -object class 33/21h = get image from cpu -object class 34/22h = get image from cpu, monochrome -object class 37/25h = get image from local GPU memory -object class 49/31h and 51/33h = patchcord, again -object class 54/36h = get image from cpu, stretched -object class 55/37h = get image from vram, scaled -object class 56/38h = get image from vram, scaled, YUV 420 color space (probably internal colour space used for rendering) -object class 57/39h = convert image(?) between formats in place in vram, allows you to set an in and out buffer and all that jazz -object class 61/3Dh = In-Memory DMA (vram to vram?) -object class 62/3Eh = get image from vram -object class 63/3Fh = get video from vram -object class 64/40h = video scaler -object class 65/41h = video color key (as opposed to image) -object class 66/42h = capture video to memory -object class 67/43h = Solid ROP5 -object class 68/44h = zeta buffer (combined z and stencil buffer) from CPU(?) -object class 69/45h = zeta buffer in VRAM -object class 70/46h = zeta buffer patchcord -object class 71/47h = render solid point into zeta buffer (Also rectangle0 -object class 72/48h = render Direct3D 5.x ("D3D0") accelerated triangle into zeta buffer -object class 73/49h = render Direct3D 5.x ("D3D0") accelerated triangle -object class 74/4Ah = video source -object class 75/4Bh = render Windows GDI accelerated rectangle and text \ No newline at end of file diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 0b4813cd1..a00699a62 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -14,7 +14,7 @@ * Also check the doc folder for some more notres * * vid_nv3.h: NV3 Architecture Hardware Reference (open-source) - * Last updated: 30 January 2025 (STILL WORKING ON IT!!!) + * Last updated: 2 February 2025 (STILL WORKING ON IT!!!) * * Authors: Connor Hyde * @@ -272,11 +272,14 @@ extern const device_config_t nv3_config[]; #define NV3_PFIFO_CACHE0_PULLER_CONTROL 0x3040 #define NV3_PFIFO_CACHE0_PULLER_CONTROL_ENABLED 0 #define NV3_PFIFO_CACHE0_PULLER_CONTROL_HASH_FAILURE 4 -#define NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD 8 +#define NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD 8 #define NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY 0x3050 #define NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY_BOOL 4 // 1=dirty 0=clean #define NV3_PFIFO_CACHE0_GET 0x3070 #define NV3_PFIFO_CACHE0_GET_ADDRESS 2 // 1 bit +// Current channel context - cache1 +#define NV3_PFIFO_CACHE0_CTX 0x3080 + #define NV3_PFIFO_CACHE0_METHOD 0x3100 #define NV3_PFIFO_CACHE0_METHOD_ADDRESS 2 // 12:2 #define NV3_PFIFO_CACHE0_METHOD_SUBCHANNEL 13 // 15:13 @@ -306,6 +309,11 @@ extern const device_config_t nv3_config[]; #define NV3_PFIFO_CACHE1_PULLER_CTX_IS_DIRTY 4 #define NV3_PFIFO_CACHE1_GET 0x3270 #define NV3_PFIFO_CACHE1_GET_ADDRESS 2 // 6:2 + +// Current channel context - cache1 +#define NV3_PFIFO_CACHE1_CTX_START 0x3280 +#define NV3_PFIFO_CACHE1_CTX_END 0x32F0 + #define NV3_PFIFO_CACHE1_METHOD 0x3300 #define NV3_PFIFO_CACHE1_METHOD_ADDRESS 2 // 12:2 #define NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL 13 // 15:13 @@ -797,11 +805,11 @@ typedef struct nv3_pfifo_cache_s bool access_enabled; // Can we even access this cache? uint8_t put_address; // Trigger a DMA into the value you put here. uint8_t get_address; // Trigger a DMA from the value you put here into where you were going. - uint8_t channel; // The DMA channel ID of this cache. + uint8_t channel; // The DMA channel ID of this cache. uint32_t status; uint32_t puller_control; uint32_t control; - uint32_t context[NV3_DMA_SUBCHANNELS_PER_CHANNEL]; + uint32_t context[NV3_DMA_SUBCHANNELS_PER_CHANNEL]; // Only one of these exists for cache0 /* cache1 only do we even need to emulate this? diff --git a/src/video/nv/nv3/subsystems/nv3_pbus.c b/src/video/nv/nv3/subsystems/nv3_pbus.c index 61385b8f2..ffe2c57cf 100644 --- a/src/video/nv/nv3/subsystems/nv3_pbus.c +++ b/src/video/nv/nv3/subsystems/nv3_pbus.c @@ -75,7 +75,7 @@ uint32_t nv3_pbus_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } diff --git a/src/video/nv/nv3/subsystems/nv3_pextdev.c b/src/video/nv/nv3/subsystems/nv3_pextdev.c index 2fbbd3489..3e0d63b5e 100644 --- a/src/video/nv/nv3/subsystems/nv3_pextdev.c +++ b/src/video/nv/nv3/subsystems/nv3_pextdev.c @@ -113,7 +113,7 @@ uint32_t nv3_pextdev_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } diff --git a/src/video/nv/nv3/subsystems/nv3_pfb.c b/src/video/nv/nv3/subsystems/nv3_pfb.c index 4de4d5069..510c61e6a 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfb.c +++ b/src/video/nv/nv3/subsystems/nv3_pfb.c @@ -90,7 +90,7 @@ uint32_t nv3_pfb_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c index 6c98cf85f..1e52175c5 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c @@ -41,6 +41,7 @@ nv_register_t pfifo_registers[] = { { NV3_PFIFO_CONFIG_RAMFC, "PFIFO - RAMIN RAMFC Config", NULL, NULL }, { NV3_PFIFO_CONFIG_RAMHT, "PFIFO - RAMIN RAMHT Config", NULL, NULL }, { NV3_PFIFO_CONFIG_RAMRO, "PFIFO - RAMIN RAMRO Config", NULL, NULL }, + { NV3_PFIFO_CACHE_REASSIGNMENT, "PFIFO - Allow Cache Channel Reassignment", NULL, NULL }, { NV3_PFIFO_CACHE0_PULLER_CONTROL, "PFIFO - Cache0 Puller Control", NULL, NULL}, { NV3_PFIFO_CACHE1_PULLER_CONTROL, "PFIFO - Cache1 Puller Control"}, { NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY, "PFIFO - Cache0 Puller State1 (Is context clean?)", NULL, NULL}, @@ -231,21 +232,34 @@ uint32_t nv3_pfifo_read(uint32_t address) case NV3_PFIFO_CACHE1_DMA_TLB_TAG: ret = nv3->pfifo.cache1_settings.dma_tlb_tag; break; + // Runout case NV3_PFIFO_RUNOUT_GET: ret = nv3->pfifo.runout_get; break; case NV3_PFIFO_RUNOUT_PUT: ret = nv3->pfifo.runout_put; break; + /* Cache1 is handled below */ + case NV3_PFIFO_CACHE0_CTX: + ret = nv3->pfifo.cache0_settings.context[0]; + break; } } if (reg->friendly_name) - nv_log(": %s\n", reg->friendly_name); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } + /* Handle some special memory areas */ + else if (address >= NV3_PFIFO_CACHE1_CTX_START && address <= NV3_PFIFO_CACHE1_CTX_END) + { + uint32_t ctx_entry_id = ((address - NV3_PFIFO_CACHE1_CTX_START) / 16) % 8; + ret = nv3->pfifo.cache1_settings.context[ctx_entry_id]; + + nv_log("PFIFO Cache1 CTX Read Entry=%d Value=0x%04x", ctx_entry_id, ret); + } else { nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); @@ -267,16 +281,11 @@ void nv3_pfifo_write(uint32_t address, uint32_t value) nv_register_t* reg = nv_get_register(address, pfifo_registers, sizeof(pfifo_registers)/sizeof(pfifo_registers[0])); - nv_log("NV3: PFIFO Write 0x%08x -> 0x%08x\n", value, address); + nv_log("NV3: PFIFO Write 0x%08x -> 0x%08x", value, address); // if the register actually exists if (reg) { - if (reg->friendly_name) - nv_log(": %s\n", reg->friendly_name); - else - nv_log("\n"); - // on-read function if (reg->on_write) reg->on_write(value); @@ -293,9 +302,15 @@ void nv3_pfifo_write(uint32_t address, uint32_t value) case NV3_PFIFO_INTR: nv3->pfifo.interrupt_status &= ~value; nv3_pmc_clear_interrupts(); + + // update the internal cache error state + if (!nv3->pfifo.interrupt_status & NV3_PFIFO_INTR_CACHE_ERROR) + nv3->pfifo.debug_0 &= ~NV3_PFIFO_INTR_CACHE_ERROR; + break; case NV3_PFIFO_INTR_EN: - nv3->pbus.interrupt_enable = value & 0x00001111; + nv3->pfifo.interrupt_enable = value & 0x00001111; + nv3_pmc_handle_interrupts(true); break; case NV3_PFIFO_DELAY_0: nv3->pfifo.dma_delay_retry = value; @@ -426,10 +441,26 @@ void nv3_pfifo_write(uint32_t address, uint32_t value) else nv3->pfifo.runout_put = ((value & 0x3FF) << 3); break; + /* Cache1 is handled below */ + case NV3_PFIFO_CACHE0_CTX: + nv3->pfifo.cache0_settings.context[0] = value; + break; } } - } + if (reg->friendly_name) + nv_log(": %s\n", reg->friendly_name); + else + nv_log("\n"); + } + /* Handle some special memory areas */ + else if (address >= NV3_PFIFO_CACHE1_CTX_START && address <= NV3_PFIFO_CACHE1_CTX_END) + { + uint32_t ctx_entry_id = ((address - NV3_PFIFO_CACHE1_CTX_START) / 16) % 8; + nv3->pfifo.cache1_settings.context[ctx_entry_id] = value; + + nv_log("PFIFO Cache1 CTX Write Entry=%d value=0x%04x", ctx_entry_id, value); + } } /* diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c index 19e9f33b0..8782abd8a 100644 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ b/src/video/nv/nv3/subsystems/nv3_pgraph.c @@ -140,9 +140,11 @@ uint32_t nv3_pgraph_read(uint32_t address) break; case NV3_PGRAPH_INTR_EN_0: ret = nv3->pgraph.interrupt_enable_0; + nv3_pmc_handle_interrupts(true); break; case NV3_PGRAPH_INTR_EN_1: ret = nv3->pgraph.interrupt_enable_1; + nv3_pmc_handle_interrupts(true); break; // A lot of this is currently a temporary implementation so that we can just debug what the current state looks like // during the driver initialisation process @@ -243,7 +245,7 @@ uint32_t nv3_pgraph_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } @@ -457,5 +459,5 @@ void nv3_pgraph_vblank_start(svga_t* svga) void nv3_pgraph_submit() { - + } \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pmc.c b/src/video/nv/nv3/subsystems/nv3_pmc.c index 7313a7554..4d8ef7c4f 100644 --- a/src/video/nv/nv3/subsystems/nv3_pmc.c +++ b/src/video/nv/nv3/subsystems/nv3_pmc.c @@ -211,7 +211,7 @@ uint32_t nv3_pmc_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } diff --git a/src/video/nv/nv3/subsystems/nv3_pme.c b/src/video/nv/nv3/subsystems/nv3_pme.c index 2ba4af426..d059eb05f 100644 --- a/src/video/nv/nv3/subsystems/nv3_pme.c +++ b/src/video/nv/nv3/subsystems/nv3_pme.c @@ -77,7 +77,7 @@ uint32_t nv3_pme_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c index f913e2917..c87a7e14e 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ b/src/video/nv/nv3/subsystems/nv3_pramdac.c @@ -285,7 +285,7 @@ uint32_t nv3_pramdac_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } diff --git a/src/video/nv/nv3/subsystems/nv3_ptimer.c b/src/video/nv/nv3/subsystems/nv3_ptimer.c index 938389054..30dd96f23 100644 --- a/src/video/nv/nv3/subsystems/nv3_ptimer.c +++ b/src/video/nv/nv3/subsystems/nv3_ptimer.c @@ -76,14 +76,11 @@ void nv3_ptimer_tick(double real_time) double current_time = freq_base * ((double)nv3->ptimer.clock_numerator * NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT) / (double)nv3->ptimer.clock_denominator; // *10.0? - // Logging is suppressed when reading this register because it is read many times - // So we only log when we update. - // truncate it nv3->ptimer.time += (uint64_t)current_time; - - nv_log("PTIMER time ticked (The value is now 0x%08x)\n", nv3->ptimer.time); + // Only log on ptimer alarm. Otherwise, it's too much spam. + //nv_log("PTIMER time ticked (The value is now 0x%08x)\n", nv3->ptimer.time); // Check if the alarm has actually triggered... if (nv3->ptimer.time >= nv3->ptimer.alarm) @@ -153,7 +150,7 @@ uint32_t nv3_ptimer_read(uint32_t address) && reg->address != NV3_PTIMER_TIME_1_NSEC) { if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); } diff --git a/src/video/nv/nv3/subsystems/nv3_pvideo.c b/src/video/nv/nv3/subsystems/nv3_pvideo.c index dc8651fb8..dacf984c9 100644 --- a/src/video/nv/nv3/subsystems/nv3_pvideo.c +++ b/src/video/nv/nv3/subsystems/nv3_pvideo.c @@ -82,7 +82,7 @@ uint32_t nv3_pvideo_read(uint32_t address) } if (reg->friendly_name) - nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret); + nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name); else nv_log("\n"); }