From caa33123c698110b7614275d4e91a8c95f5e9f5d Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 29 Dec 2024 19:29:27 +0000 Subject: [PATCH] add prmvio --- src/include/86box/nv/vid_nv3.h | 6 +- src/video/nv/nv3/nv3_core.c | 97 +++++++++++++++++++++++- src/video/nv/nv3/nv3_core_arbiter.c | 5 +- src/video/nv/nv3/subsystems/nv3_pgraph.c | 11 ++- 4 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 328d8335e..d185cd408 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -212,8 +212,8 @@ extern const device_config_t nv3_config[]; #define NV3_VGA_VRAM_END 0xBFFFF #define NV3_VGA_START 0xC0000 // VGA Emulation Registers #define NV3_VGA_END 0xC7FFF -#define NV3_PRMVIO_START NV3_VGA_START -#define NV3_PRMVIO_END NV3_VGA_END +#define NV3_PRMVIO_START NV3_VGA_START // VGA stuff written from main GPU +#define NV3_PRMVIO_END 0xC0400 #define NV3_PFB_START 0x100000 // GPU Interface to VRAM #define NV3_PFB_BOOT 0x100000 // Boot registration #define NV3_PFB_BOOT_RAM_AMOUNT 0 // The amount of ram @@ -342,11 +342,13 @@ extern const device_config_t nv3_config[]; #define NV3_PGRAPH_PLANE_MASK 0x400628 #define NV3_PGRAPH_CHROMA_KEY 0x40062C #define NV3_PGRAPH_BETA 0x400640 // Beta factor (30:23 fractional, 22:0 before fraction) +#define NV3_PGRAPH_DMA 0x400680 #define NV3_PGRAPH_NOTIFY 0x400684 // Notifier for PGRAPH #define NV3_PGRAPH_CLIP0_MIN 0x400690 // Clip for Blitting 0 Min #define NV3_PGRAPH_CLIP0_MAX 0x400694 // Clip for Blitting 0 Max #define NV3_PGRAPH_CLIP1_MIN 0x400698 // Clip for Blitting 1 Min #define NV3_PGRAPH_CLIP1_MAX 0x40069C // Clip for Blitting 1 Max +#define NV3_PGRAPH_CLIP_MISC 0x4006A0 // Regions/Render/Complex mode #define NV3_PGRAPH_FIFO_ACCESS 0x4006A4 // Is PGRAPH enabled? #define NV3_PGRAPH_FIFO_ACCESS_DISABLED 0x0 #define NV3_PGRAPH_FIFO_ACCESS_ENABLED 0x1 diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c index c7a4407f2..77abd7a00 100644 --- a/src/video/nv/nv3/nv3_core.c +++ b/src/video/nv/nv3/nv3_core.c @@ -46,27 +46,92 @@ void nv3_svga_out(uint16_t addr, uint8_t val, void* priv); // Read 8-bit MMIO uint8_t nv3_mmio_read8(uint32_t addr, void* priv) { + uint32_t ret = 0x00; + + // Some of these addresses are Weitek VGA stuff and we need to mask it to this first because the weitek addresses are 8-bit aligned. + addr &= 0xFFFFFF; + + if (addr >= NV3_PRMVIO_START + && addr <= NV3_PRMVIO_END) + { + // svga writes are not logged anyway rn + uint32_t real_address = addr & 0x3FF; + + ret = nv3_svga_in(real_address, nv3); + + return ret; + } + // see if unaligned reads are a problem - uint32_t ret = nv3_mmio_read32(addr, priv); + ret = nv3_mmio_read32(addr, priv); return (uint8_t)(ret >> ((addr & 3) << 3) & 0xFF); } // Read 16-bit MMIO uint16_t nv3_mmio_read16(uint32_t addr, void* priv) { - uint32_t ret = nv3_mmio_read32(addr, priv); + uint32_t ret = 0x00; + + // Some of these addresses are Weitek VGA stuff and we need to mask it to this first because the weitek addresses are 8-bit aligned. + addr &= 0xFFFFFF; + + if (addr >= NV3_PRMVIO_START + && addr <= NV3_PRMVIO_END) + { + // svga writes are not logged anyway rn + uint32_t real_address = addr & 0x3FF; + + ret = nv3_svga_in(real_address, nv3) + | (nv3_svga_in(real_address + 1, nv3) << 8); + + return ret; + } + + ret = nv3_mmio_read32(addr, priv); return (uint8_t)(ret >> ((addr & 3) << 3) & 0xFFFF); } // Read 32-bit MMIO uint32_t nv3_mmio_read32(uint32_t addr, void* priv) { + uint32_t ret = 0x00; + + // Some of these addresses are Weitek VGA stuff and we need to mask it to this first because the weitek addresses are 8-bit aligned. + addr &= 0xFFFFFF; + + if (addr >= NV3_PRMVIO_START + && addr <= NV3_PRMVIO_END) + { + // svga writes are not logged anyway rn + uint32_t real_address = addr & 0x3FF; + + ret = nv3_svga_in(real_address, nv3) + | (nv3_svga_in(real_address + 1, nv3) << 8) + | (nv3_svga_in(real_address + 2, nv3) << 16) + | (nv3_svga_in(real_address + 3, nv3) << 24); + + return ret; + } + + return nv3_mmio_arbitrate_read(addr); } // Write 8-bit MMIO void nv3_mmio_write8(uint32_t addr, uint8_t val, void* priv) { + // This is weitek vga stuff + if (addr >= NV3_PRMVIO_START + && addr <= NV3_PRMVIO_END) + { + // svga writes are not logged anyway rn + uint32_t real_address = addr & 0x3FF; + + nv3_svga_out(real_address, val & 0xFF, nv3); + + return; + } + // overwrite first 8bits of a 32 bit value uint32_t new_val = nv3_mmio_read32(addr, NULL); @@ -79,6 +144,19 @@ void nv3_mmio_write8(uint32_t addr, uint8_t val, void* priv) // Write 16-bit MMIO void nv3_mmio_write16(uint32_t addr, uint16_t val, void* priv) { + // This is weitek vga stuff + if (addr >= NV3_PRMVIO_START + && addr <= NV3_PRMVIO_END) + { + // svga writes are not logged anyway rn + uint32_t real_address = addr & 0x3FF; + + nv3_svga_out(real_address, val & 0xFF, nv3); + nv3_svga_out(real_address + 1, (val >> 8) & 0xFF, nv3); + + return; + } + // overwrite first 16bits of a 32 bit value uint32_t new_val = nv3_mmio_read32(addr, NULL); @@ -91,6 +169,21 @@ void nv3_mmio_write16(uint32_t addr, uint16_t val, void* priv) // Write 32-bit MMIO void nv3_mmio_write32(uint32_t addr, uint32_t val, void* priv) { + // This is weitek vga stuff + if (addr >= NV3_PRMVIO_START + && addr <= NV3_PRMVIO_END) + { + // svga writes are not logged anyway rn + uint32_t real_address = addr & 0x3FF; + + nv3_svga_out(real_address, val & 0xFF, nv3); + nv3_svga_out(real_address + 1, (val >> 8) & 0xFF, nv3); + nv3_svga_out(real_address + 2, (val >> 16) & 0xFF, nv3); + nv3_svga_out(real_address + 3, (val >> 24) & 0xFF, nv3); + + return; + } + nv3_mmio_arbitrate_write(addr, val); } diff --git a/src/video/nv/nv3/nv3_core_arbiter.c b/src/video/nv/nv3/nv3_core_arbiter.c index e74e6a93d..ee8fe048d 100644 --- a/src/video/nv/nv3/nv3_core_arbiter.c +++ b/src/video/nv/nv3/nv3_core_arbiter.c @@ -57,7 +57,7 @@ uint32_t nv3_mmio_arbitrate_read(uint32_t address) return 0x00; uint32_t ret = 0x00; - + // note: some registers are byte aligned not dword aligned // only very few are though, so they can be handled specially, using the register list most likely address &= 0xFFFFFC; @@ -120,6 +120,9 @@ void nv3_mmio_arbitrate_write(uint32_t address, uint32_t value) if (!nv3) return; + // Some of these addresses are Weitek VGA stuff and we need to mask it to this first because the weitek addresses are 8-bit aligned. + address &= 0xFFFFFF; + // note: some registers are byte aligned not dword aligned // only very few are though, so they can be handled specially, using the register list most likely address &= 0xFFFFFC; diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c index d7b7bfb01..9dfca4f00 100644 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ b/src/video/nv/nv3/subsystems/nv3_pgraph.c @@ -43,6 +43,10 @@ void nv3_pgraph_init() // nv_register_t pgraph_registers[] = { + { NV3_PGRAPH_DEBUG_0, "PGRAPH Debug 0", NULL, NULL }, + { NV3_PGRAPH_DEBUG_1, "PGRAPH Debug 1", NULL, NULL }, + { NV3_PGRAPH_DEBUG_2, "PGRAPH Debug 2", NULL, NULL }, + { NV3_PGRAPH_DEBUG_3, "PGRAPH Debug 3", NULL, NULL }, { NV3_PGRAPH_INTR_0, "PGRAPH Interrupt Status 0", NULL, NULL }, { NV3_PGRAPH_INTR_EN_0, "PGRAPH Interrupt Enable 0", NULL, NULL }, { NV3_PGRAPH_INTR_1, "PGRAPH Interrupt Status 1", NULL, NULL }, @@ -69,7 +73,10 @@ nv_register_t pgraph_registers[] = { { NV3_PGRAPH_ROP3, "PGRAPH Render Operation ROP3 (2^3 bits = 256 possible operations)", NULL, NULL}, { NV3_PGRAPH_PLANE_MASK, "PGRAPH Current Plane Mask (7:0)", NULL, NULL}, { NV3_PGRAPH_CHROMA_KEY, "PGRAPH Chroma Key (17:0) (Bit 30 = Alpha, 29:20 = Red, 19:10 = Green, 9:0 = Blue)", NULL, NULL}, - { NV3_PGRAPH_NOTIFY, "PGRAPH Notifier (Wip...)", NULL, NULL}, + { NV3_PGRAPH_BETA, "PGRAPH Beta factor", NULL, NULL }, + { NV3_PGRAPH_DMA, "PGRAPH DMA", NULL, NULL }, + { NV3_PGRAPH_CLIP_MISC, "PGRAPH Clipping Miscellaneous Settings", NULL, NULL }, + { NV3_PGRAPH_NOTIFY, "PGRAPH Notifier (Wip...)", NULL, NULL }, { NV3_PGRAPH_CLIP0_MIN, "PGRAPH Clip0 Min (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, { NV3_PGRAPH_CLIP0_MAX, "PGRAPH Clip0 Max (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, { NV3_PGRAPH_CLIP1_MIN, "PGRAPH Clip1 Min (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, @@ -164,7 +171,7 @@ void nv3_pgraph_write(uint32_t address, uint32_t value) nv_register_t* reg = nv_get_register(address, pgraph_registers, sizeof(pgraph_registers)/sizeof(pgraph_registers[0])); - nv_log("NV3: pgraph Write 0x%08x -> 0x%08x\n", value, address); + nv_log("NV3: PGRAPH Write 0x%08x -> 0x%08x\n", value, address); // if the register actually exists if (reg)