From 467c7124d369f1d5b4c2daad1ec1020931eba460 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Tue, 11 Mar 2025 02:30:18 +0000 Subject: [PATCH] Direct CACHE0/CACHE1 Injection --- src/include/86box/nv/vid_nv3.h | 7 ++- src/video/nv/nv3/subsystems/nv3_pfifo.c | 69 ++++++++++++++++++------ src/video/nv/nv3/subsystems/nv3_pramin.c | 2 +- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 56eae4dfa..d18aa8754 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -282,7 +282,8 @@ extern const device_config_t nv3_config[]; // Current channel context - cache1 #define NV3_PFIFO_CACHE0_CTX 0x3080 -#define NV3_PFIFO_CACHE0_METHOD 0x3100 +#define NV3_PFIFO_CACHE0_METHOD_START 0x3100 +#define NV3_PFIFO_CACHE0_METHOD_END 0x3200 #define NV3_PFIFO_CACHE0_METHOD_ADDRESS 2 // 12:2 #define NV3_PFIFO_CACHE0_METHOD_SUBCHANNEL 13 // 15:13 #define NV3_PFIFO_CACHE1_DMA_PUSH0 0x3200 @@ -320,10 +321,12 @@ extern const device_config_t nv3_config[]; #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_START 0x3300 +#define NV3_PFIFO_CACHE1_METHOD_END 0x3400 #define NV3_PFIFO_CACHE1_METHOD_ADDRESS 2 // 12:2 #define NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL 13 // 15:13 + #define NV3_PFIFO_END 0x3FFF #define NV3_PRM_START 0x4000 // Real-Mode Device Support Subsystem #define NV3_PRM_INTR 0x4100 diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c index 273e0a2e3..1743750ba 100644 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c @@ -192,14 +192,6 @@ uint32_t nv3_pfifo_read(uint32_t address) if (nv3->pfifo.runout_put != nv3->pfifo.runout_get) ret |= 1 << NV3_PFIFO_CACHE1_STATUS_RANOUT; - break; - case NV3_PFIFO_CACHE0_METHOD: - ret = ((nv3->pfifo.cache0_settings.method_subchannel << 13) & 0x07) - | ((nv3->pfifo.cache0_settings.method_address << 2) & 0x7FF); - break; - case NV3_PFIFO_CACHE1_METHOD: - ret = ((nv3->pfifo.cache1_settings.method_subchannel << 13) & 0x07) - | ((nv3->pfifo.cache1_settings.method_address << 2) & 0x7FF); break; case NV3_PFIFO_CACHE0_PUT: ret = nv3->pfifo.cache0_settings.put_address; @@ -295,6 +287,30 @@ uint32_t nv3_pfifo_read(uint32_t address) nv_log("PFIFO Cache1 CTX Read Entry=%d Value=0x%04x", ctx_entry_id, ret); } + /* Direct cache read stuff */ + else if (address >= NV3_PFIFO_CACHE0_METHOD_START && address <= NV3_PFIFO_CACHE0_METHOD_END) + { + if (address & 4) + return nv3->pfifo.cache0_entry.data; + else + return nv3->pfifo.cache0_entry.method | (nv3->pfifo.cache0_entry.subchannel << NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL); + } + else if (address >= NV3_PFIFO_CACHE1_METHOD_START && address <= NV3_PFIFO_CACHE1_METHOD_END) + { + // Not sure if REV C changes this. It should... + uint32_t slot = 0; + + if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) + slot = (address >> 3) & 0x3F; + else + slot = (address >> 3) & 0x1F; + + // See if we want the object name or the channel/subchannel information. + if (address & 4) + return nv3->pfifo.cache1_entries[slot].data; + else + return nv3->pfifo.cache1_entries[slot].method | (nv3->pfifo.cache1_entries[slot].subchannel << NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL); + } else { nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); @@ -456,14 +472,6 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) nv3->pfifo.cache1_settings.channel = val; break; // CACHE0_STATUS and CACHE1_STATUS are not writable - case NV3_PFIFO_CACHE0_METHOD: - nv3->pfifo.cache0_settings.method_subchannel = (val >> 13) & 0x07; - nv3->pfifo.cache0_settings.method_address = (val >> 2) & 0x7FF; - break; - case NV3_PFIFO_CACHE1_METHOD: - nv3->pfifo.cache1_settings.method_subchannel = (val >> 13) & 0x07; - nv3->pfifo.cache1_settings.method_address = (val >> 2) & 0x7FF; - break; case NV3_PFIFO_CACHE1_DMA_CONFIG_0: nv3->pfifo.cache1_settings.dma_state = val; break; @@ -526,6 +534,33 @@ void nv3_pfifo_write(uint32_t address, uint32_t val) else nv_log("\n"); } + else if (address >= NV3_PFIFO_CACHE0_METHOD_START && address <= NV3_PFIFO_CACHE0_METHOD_END) + { + if (address & 4) + nv3->pfifo.cache0_entry.data = val; + else + nv3->pfifo.cache0_entry.method = (val & 0x1FFC); + nv3->pfifo.cache0_entry.subchannel = (val >> NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL) & 0x07; + } + else if (address >= NV3_PFIFO_CACHE1_METHOD_START && address <= NV3_PFIFO_CACHE1_METHOD_END) + { + // Not sure if REV C changes this. It should... + uint32_t slot = 0; + + if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) + slot = (address >> 3) & 0x3F; + else + slot = (address >> 3) & 0x1F; + + uint32_t real_entry = nv3_pfifo_cache1_normal2gray(slot); + + // See if we want the object name or the channel/subchannel information. + if (address & 4) + nv3->pfifo.cache1_entries[real_entry].data = val; + else + nv3->pfifo.cache1_entries[real_entry].method = (val & 0x1FFC); + nv3->pfifo.cache1_entries[real_entry].subchannel = (val >> NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL) & 0x07; + } /* Handle some special memory areas */ else if (address >= NV3_PFIFO_CACHE1_CTX_START && address <= NV3_PFIFO_CACHE1_CTX_END) { @@ -630,7 +665,7 @@ void nv3_pfifo_cache0_pull() #ifndef RELEASE_BUILD nv_log("***** SUBMITTING GRAPHICS COMMANDS CURRENTLY UNIMPLEMENTED - CACHE0 PULLED ****** Contextual information below\n"); - nv3_debug_ramin_print_context_info(current_name, *(nv3_ramin_context_t*)current_context); + nv3_debug_ramin_print_context_info(current_name, *(nv3_ramin_context_t*)¤t_context); #endif } diff --git a/src/video/nv/nv3/subsystems/nv3_pramin.c b/src/video/nv/nv3/subsystems/nv3_pramin.c index 33799c39b..e1a2a6442 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramin.c +++ b/src/video/nv/nv3/subsystems/nv3_pramin.c @@ -54,7 +54,7 @@ uint8_t nv3_ramin_read8(uint32_t addr, void* priv) addr &= (nv3->nvbase.svga.vram_max - 1); uint32_t raw_addr = addr; // saved after and - addr ^= (nv3->nvbase.svga.vram_max- 0x10); + addr ^= (nv3->nvbase.svga.vram_max - 0x10); uint32_t val = 0x00;