From 6819b2c3d0a8b3c0c0a2b27b703e06a7095d8d73 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 25 Sep 2025 01:01:09 +0200 Subject: [PATCH] Revert "Merge branch 'master' into master" This reverts commit dbafb3e8a4f9bd8a4ed387e8d72dc68b869a4764, reversing changes made to f04346bf31b2559bb08718839746b06cf6ca47e9. --- CMakeLists.txt | 13 +- CMakePresets.json | 5 +- doc/nvidia_notes/2025-01-24.txt | 1 - .../B = BUFFER. REMEMBER THESE!!!.txt | 1 - .../How to optimise riva 128 applications.txt | 6 - doc/nvidia_notes/Memory map (RIVA 128).txt | 81 - doc/nvidia_notes/NV3 DMA Engine.txt | 54 - doc/nvidia_notes/NV_PFB_CONFIG_0.txt | 29 - doc/nvidia_notes/PFIFO RAMHT RAMRO.txt | 38 - doc/nvidia_notes/RIVA fansites.txt | 26 - doc/nvidia_notes/Versions.txt | 8 - doc/nvidia_notes/gpucompanies.txt | 63 - doc/nvidia_notes/hardware cursor.txt | 21 - doc/nvidia_notes/multithreading.pdn | Bin 106011 -> 0 bytes doc/nvidia_notes/multithreading.png | Bin 117148 -> 0 bytes doc/nvidia_notes/nv3 driver init status.txt | 112 - .../nv3 driver init status_2025-02-10.txt | 90 - doc/nvidia_notes/nv3_object_classes.txt | 37 - doc/nvidia_notes/nv3d3d_t.txt | 161 - doc/nvidia_notes/old nouveau wiki.txt | 9 - doc/nvidia_notes/rivatv_riva128.txt | 2238 --------- doc/nvidia_notes/status.xlsx | Bin 15945 -> 0 bytes .../86box/nv/classes/vid_nv3_classes.h | 1179 ----- src/include/86box/nv/render/vid_nv3_render.h | 64 - src/include/86box/nv/vid_nv.h | 178 - src/include/86box/nv/vid_nv1.h | 167 - src/include/86box/nv/vid_nv3.h | 1764 ------- src/include/86box/nv/vid_nv4.h | 149 - src/include/86box/nv/vid_nv4_defines.h | 4291 ----------------- src/include/86box/utils/video_stdlib.h | 23 - src/include/86box/video.h | 7 - src/qt/CMakeLists.txt | 10 +- src/qt/qt_gpudebug_visualnv.cpp | 177 - src/qt/qt_gpudebug_visualnv.hpp | 46 - src/qt/qt_gpudebug_visualnv.ui | 213 - src/qt/qt_gpudebug_vram.cpp | 54 - src/qt/qt_gpudebug_vram.hpp | 40 - src/qt/qt_gpudebug_vram.ui | 42 - src/qt/qt_mainwindow.cpp | 98 +- src/qt/qt_mainwindow.hpp | 15 +- src/qt/qt_mainwindow.ui | 78 +- src/sound/snd_emu8k.c | 2 +- src/sound/snd_sb.c | 4 +- src/utils/CMakeLists.txt | 3 - src/utils/log.c | 19 +- src/utils/video/video_rop.c | 790 --- src/video/CMakeLists.txt | 71 +- src/video/nv/nv1/nv1_core.c | 110 - src/video/nv/nv1/nv1_core_config.c | 133 - .../nv3/classes/nv3_class_001_beta_factor.c | 50 - src/video/nv/nv3/classes/nv3_class_002_rop.c | 44 - .../nv/nv3/classes/nv3_class_003_chroma_key.c | 54 - .../nv/nv3/classes/nv3_class_004_plane_mask.c | 40 - .../nv3_class_005_clipping_rectangle.c | 49 - .../nv/nv3/classes/nv3_class_006_pattern.c | 86 - .../nv/nv3/classes/nv3_class_007_rectangle.c | 69 - .../nv/nv3/classes/nv3_class_008_point.c | 40 - src/video/nv/nv3/classes/nv3_class_009_line.c | 40 - src/video/nv/nv3/classes/nv3_class_00a_lin.c | 41 - .../nv/nv3/classes/nv3_class_00b_triangle.c | 40 - .../classes/nv3_class_00c_win95_gdi_text.c | 285 -- src/video/nv/nv3/classes/nv3_class_00d_m2mf.c | 94 - .../nv3_class_00e_scaled_image_from_mem.c | 40 - src/video/nv/nv3/classes/nv3_class_010_blit.c | 60 - .../nv/nv3/classes/nv3_class_011_image.c | 67 - .../nv/nv3/classes/nv3_class_012_bitmap.c | 41 - .../classes/nv3_class_014_transfer2memory.c | 41 - .../nv3_class_015_stretched_image_from_cpu.c | 40 - .../nv3_class_017_d3d5_tri_zeta_buffer.c | 40 - .../classes/nv3_class_018_point_zeta_buffer.c | 42 - .../classes/nv3_class_01c_image_in_memory.c | 99 - src/video/nv/nv3/classes/nv3_class_names.c | 67 - .../nv/nv3/classes/nv3_class_shared_methods.c | 67 - src/video/nv/nv3/nv3_core.c | 1567 ------ src/video/nv/nv3/nv3_core_arbiter.c | 213 - src/video/nv/nv3/nv3_core_config.c | 240 - src/video/nv/nv3/render/nv3_render_blit.c | 229 - src/video/nv/nv3/render/nv3_render_core.c | 869 ---- .../nv/nv3/render/nv3_render_primitives.c | 355 -- src/video/nv/nv3/subsystems/nv3_pbus.c | 255 - src/video/nv/nv3/subsystems/nv3_pbus_dma.c | 274 -- src/video/nv/nv3/subsystems/nv3_pextdev.c | 161 - src/video/nv/nv3/subsystems/nv3_pfb.c | 204 - src/video/nv/nv3/subsystems/nv3_pfifo.c | 985 ---- src/video/nv/nv3/subsystems/nv3_pgraph.c | 632 --- src/video/nv/nv3/subsystems/nv3_pmc.c | 274 -- src/video/nv/nv3/subsystems/nv3_pme.c | 136 - src/video/nv/nv3/subsystems/nv3_pramdac.c | 458 -- src/video/nv/nv3/subsystems/nv3_pramin.c | 515 -- .../nv/nv3/subsystems/nv3_pramin_ramfc.c | 40 - .../nv/nv3/subsystems/nv3_pramin_ramht.c | 56 - .../nv/nv3/subsystems/nv3_pramin_ramro.c | 40 - src/video/nv/nv3/subsystems/nv3_ptimer.c | 227 - src/video/nv/nv3/subsystems/nv3_pvideo.c | 159 - src/video/nv/nv3/subsystems/nv3_user.c | 70 - src/video/nv/nv4/nv4_core.c | 388 -- src/video/nv/nv4/nv4_core_config.c | 92 - src/video/nv/nv4/nv4_core_io.c | 1283 ----- src/video/nv/nv4/nv4_debug_register_list.c | 46 - src/video/nv/nv4/subsystems/nv4_pramdac.c | 84 - src/video/nv/nv4/subsystems/nv4_ptimer.c | 227 - src/video/nv/nv_base.c | 107 - src/video/vid_table.c | 7 - src/video/vid_voodoo.c | 2 +- 104 files changed, 38 insertions(+), 24413 deletions(-) delete mode 100644 doc/nvidia_notes/2025-01-24.txt delete mode 100644 doc/nvidia_notes/B = BUFFER. REMEMBER THESE!!!.txt delete mode 100644 doc/nvidia_notes/How to optimise riva 128 applications.txt delete mode 100644 doc/nvidia_notes/Memory map (RIVA 128).txt delete mode 100644 doc/nvidia_notes/NV3 DMA Engine.txt delete mode 100644 doc/nvidia_notes/NV_PFB_CONFIG_0.txt delete mode 100644 doc/nvidia_notes/PFIFO RAMHT RAMRO.txt delete mode 100644 doc/nvidia_notes/RIVA fansites.txt delete mode 100644 doc/nvidia_notes/Versions.txt delete mode 100644 doc/nvidia_notes/gpucompanies.txt delete mode 100644 doc/nvidia_notes/hardware cursor.txt delete mode 100644 doc/nvidia_notes/multithreading.pdn delete mode 100644 doc/nvidia_notes/multithreading.png delete mode 100644 doc/nvidia_notes/nv3 driver init status.txt delete mode 100644 doc/nvidia_notes/nv3 driver init status_2025-02-10.txt delete mode 100644 doc/nvidia_notes/nv3_object_classes.txt delete mode 100644 doc/nvidia_notes/nv3d3d_t.txt delete mode 100644 doc/nvidia_notes/old nouveau wiki.txt delete mode 100644 doc/nvidia_notes/rivatv_riva128.txt delete mode 100644 doc/nvidia_notes/status.xlsx delete mode 100644 src/include/86box/nv/classes/vid_nv3_classes.h delete mode 100644 src/include/86box/nv/render/vid_nv3_render.h delete mode 100644 src/include/86box/nv/vid_nv.h delete mode 100644 src/include/86box/nv/vid_nv1.h delete mode 100644 src/include/86box/nv/vid_nv3.h delete mode 100644 src/include/86box/nv/vid_nv4.h delete mode 100644 src/include/86box/nv/vid_nv4_defines.h delete mode 100644 src/include/86box/utils/video_stdlib.h delete mode 100644 src/qt/qt_gpudebug_visualnv.cpp delete mode 100644 src/qt/qt_gpudebug_visualnv.hpp delete mode 100644 src/qt/qt_gpudebug_visualnv.ui delete mode 100644 src/qt/qt_gpudebug_vram.cpp delete mode 100644 src/qt/qt_gpudebug_vram.hpp delete mode 100644 src/qt/qt_gpudebug_vram.ui delete mode 100644 src/utils/video/video_rop.c delete mode 100644 src/video/nv/nv1/nv1_core.c delete mode 100644 src/video/nv/nv1/nv1_core_config.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_001_beta_factor.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_002_rop.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_003_chroma_key.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_004_plane_mask.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_005_clipping_rectangle.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_006_pattern.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_007_rectangle.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_008_point.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_009_line.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_00a_lin.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_00b_triangle.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_00d_m2mf.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_00e_scaled_image_from_mem.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_010_blit.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_011_image.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_012_bitmap.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_014_transfer2memory.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_015_stretched_image_from_cpu.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_018_point_zeta_buffer.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_names.c delete mode 100644 src/video/nv/nv3/classes/nv3_class_shared_methods.c delete mode 100644 src/video/nv/nv3/nv3_core.c delete mode 100644 src/video/nv/nv3/nv3_core_arbiter.c delete mode 100644 src/video/nv/nv3/nv3_core_config.c delete mode 100644 src/video/nv/nv3/render/nv3_render_blit.c delete mode 100644 src/video/nv/nv3/render/nv3_render_core.c delete mode 100644 src/video/nv/nv3/render/nv3_render_primitives.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pbus.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pbus_dma.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pextdev.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pfb.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pfifo.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pgraph.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pmc.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pme.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pramdac.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pramin.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pramin_ramht.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pramin_ramro.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_ptimer.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_pvideo.c delete mode 100644 src/video/nv/nv3/subsystems/nv3_user.c delete mode 100644 src/video/nv/nv4/nv4_core.c delete mode 100644 src/video/nv/nv4/nv4_core_config.c delete mode 100644 src/video/nv/nv4/nv4_core_io.c delete mode 100644 src/video/nv/nv4/nv4_debug_register_list.c delete mode 100644 src/video/nv/nv4/subsystems/nv4_pramdac.c delete mode 100644 src/video/nv/nv4/subsystems/nv4_ptimer.c delete mode 100644 src/video/nv/nv_base.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ba7e9a75..29fedd6ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,15 +139,7 @@ option(DISCORD "Discord Rich Presence support" option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF) option(LIBASAN "Enable compilation with the addresss sanitizer" OFF) -if (NV_LOG) - add_compile_definitions(ENABLE_NV_LOG) -endif() - -if (NV_LOG_ULTRA) - add_compile_definitions(ENABLE_NV_LOG_ULTRA) -endif() - -if((ARCH STREQUAL "arm64") OR (ARCH STREQUAL "arm")) +if((ARCH STREQUAL "arm64")) set(NEW_DYNAREC ON) else() option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) @@ -192,12 +184,9 @@ cmake_dependent_option(PCL "Generic PCL5e Printer" cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(WACOM "Wacom Input Devices" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) -cmake_dependent_option(NV3 "NVidia RIVA 128/128ZX (NV3/NV3T)" ON "DEV_BRANCH" OFF) - cmake_dependent_option(NETSWITCH "Network Switch Support" ON "DEV_BRANCH" OFF) cmake_dependent_option(VFIO "Virtual Function I/O" ON "DEV_BRANCH" OFF) - # Ditto but for Qt if(QT) option(USE_QT6 "Use Qt6 instead of Qt5" OFF) diff --git a/CMakePresets.json b/CMakePresets.json index 53ddffc74..be6615088 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -35,10 +35,7 @@ { "name": "debug", "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "NV_LOG": "ON", - "NV_LOG_ULTRA": "ON" - + "CMAKE_BUILD_TYPE": "Debug" }, "inherits": "base" }, diff --git a/doc/nvidia_notes/2025-01-24.txt b/doc/nvidia_notes/2025-01-24.txt deleted file mode 100644 index e35818dc0..000000000 --- a/doc/nvidia_notes/2025-01-24.txt +++ /dev/null @@ -1 +0,0 @@ -THIS IS FIFOSERVICE!!!!!!!!!!!! \ No newline at end of file diff --git a/doc/nvidia_notes/B = BUFFER. REMEMBER THESE!!!.txt b/doc/nvidia_notes/B = BUFFER. REMEMBER THESE!!!.txt deleted file mode 100644 index e8f183240..000000000 --- a/doc/nvidia_notes/B = BUFFER. REMEMBER THESE!!!.txt +++ /dev/null @@ -1 +0,0 @@ -B = BUFFER. REMEMBER THESE!!! \ No newline at end of file diff --git a/doc/nvidia_notes/How to optimise riva 128 applications.txt b/doc/nvidia_notes/How to optimise riva 128 applications.txt deleted file mode 100644 index 004593a21..000000000 --- a/doc/nvidia_notes/How to optimise riva 128 applications.txt +++ /dev/null @@ -1,6 +0,0 @@ -How to optimise riva 128 applications: -* Ensure any set of polygons with one texture is close to a multiple of 128 polygons. -* Try to sort areas of a model with one texture to as close to 128 polygons as possible for efficient submission due to the lack of texturing. -* Try to have around (32*128) for nv3 or (64*128) for nv3t polygons -* Get coding -* Alcohol \ No newline at end of file diff --git a/doc/nvidia_notes/Memory map (RIVA 128).txt b/doc/nvidia_notes/Memory map (RIVA 128).txt deleted file mode 100644 index fbfe9074f..000000000 --- a/doc/nvidia_notes/Memory map (RIVA 128).txt +++ /dev/null @@ -1,81 +0,0 @@ -Memory map (RIVA 128) - -32 megabytes of MMIO starting at 0x0000000-0x01FFFFFF - -MC (Master Control) 0x00000000-0x00000FFF - Config/Boot 0x00000000-0x000000FF - Master Config 0x00000100-0x00000FFF - Also used to define DMA channel IDs? - -MPU-401 I/O 0x00000330-0x00000331 Probably NV1 leftover, NV1 has mpu401 emulation -- no audio in nv3 -VGA emulated ports 0x000003B0-0x000003DF Emulated I/O ports for VGA - -Bus Control (PBUS) 0x00001000-0x00001FFF -FIFO (PFIFO) 0x00002000-0x00003FFF Submit starting at 0x00800000. Used to configure RAMHT,RAMFC,RAMRO structures & cache - -PRM 0x00004000-0x00005FFF Realmode DOS device support - -PRMIO 0x00007000-0x00007FFF Realmode access to PCI BAR (Base Address Register) + PCI I/O -PTIMER 0x00009000-0x00009FFF Timer - -VGA emulation 0x0000A000-0x0000BFFF - -VGA vram emulation 0x000A0000-0x000BFFFF (PRMVGA) -VGA 0x000C0000-0x000C7FFF VGA sequencer + graph controller registers (PRMVIO) - -(All of this up to 0x0000FFFF can be traced) - -PFB (Framebuffer) 0x00100000-0x00100FFF Interface to vram -PEXTDEV 0x00101000-0x00101FFF External device interface - contains straps - Straps 0x00101000 11 bits of cfg - -ROM (VBIOS?) 0x00110000-0x0011FFFF -PALT (?) 0x00120000-0x00120FFF - -PEXTDEV 0x00101000-0x00101FFF External Devices - -Media Engine (PME) 0x00200000-0x00200FFF Allows for external video capture according to envytools? - -PGRAPH (3D rendering) 0x00400000-0x00401FFF - -PGRAPH objects (using RAMHT???) -*i assume that when you submit an object these are the registers used to actually draw the current object - -Beta blending factor 0x00410000-0x00411FFF -ROP 0x00420000-0x00421FFF Global bitwise operation (Render OPeration) for filtering the final pixel -Color Key 0x00430000-0x00431FFF -Plane Switch 0x00440000-0x00441FFF Something to do with color formats and objects? -Clipping 0x00450000-0x00451FFF -Blend Pattern 0x00460000-0x00461FFF Used for specific blending modes -Quad [OBSOLETE] 0x00470000-0x00471FFF A rectangle. NV1 LEFTOVER, OBSOLETE -Point 0x00480000-0x00481FFF A single point -Line 0x00490000-0x00491FFF A line (with an optional colour). Can also draw a polygon made out of lines - polyline -Lin 0x004A0000-0x004A1FFF A line, without starting or ending pixel (with an optional colour). Can also draw a "polylin" -Triangle [OBSOLETE] 0x004B0000-0x004B1FFF A triangle. NV1 LEFTOVER, OBSOLETE? -Win95 GDI text 0x004C0000-0x004C1FFF Win95 text acceleration -Memory to memory xfer 0x004D0000-0x004D1FFF Represents a memory to memory transfer -Scaled image from vram 0x004E0000-0x004E1FFF Scaled image from GPU VRAM -Image blit from vram 0x00500000-0x00501FFF Image from GPU VRAM -Image blit from cpu 0x00510000-0x00511FFF Image from CPU -Bitmap from cpu 0x00520000-0x00521FFF Bitmap from CPU -Image to memory 0x00540000-0x00541FFF Image to GPU VRAM -Stretch image from cpu 0x00550000-0x00551FFF Stretched image from CPU -Direct3D 5.0 triangle 0x00570000-0x00571FFF A triangle optimised explicitly for directx3/directx5 rendering - supercedes UTRI -PointZ 0x00580000-0x00581FFF A single point with "zeta factor" (not sure what this is yet) -Image in memory 0x005C0000-0x005C0FFF Image in vram(?) - -PVIDEO (Video Control) 0x00680000-0x006802FF -External DAC 0x00680000-0x006800FF - -PRMCIO 0x00601000-0x00601FFF VGA emulation - CRTC + attribute controller - -PRAMDAC 0x00680300-0x00680FFF (used for color lookup tables, hardware cursor, video overlay, PLL for clocking and pixel generation) -"USER" DAC 0x00681200-0x00681FFF - -DMA submission w/FIFO 0x00800000-0x00FFFFFF NV_USER - uses FIFO buffer - -PNVM / PDFB / VRAM 0x01000000-0x017FFFFF (actual VRAM amount depends on card, but max is 8MB) - -RAMIN 0x01C00000-0x01FFFFFF (note that this is actually mapped in the last 1mb of vram) - -contains ramht that has obj parameters for submission, configurable \ No newline at end of file diff --git a/doc/nvidia_notes/NV3 DMA Engine.txt b/doc/nvidia_notes/NV3 DMA Engine.txt deleted file mode 100644 index 380e0281e..000000000 --- a/doc/nvidia_notes/NV3 DMA Engine.txt +++ /dev/null @@ -1,54 +0,0 @@ -NV3 DMA Engine -(DirectDraw Driver) - -Initially set CACHES, CACHE1_PULL0, CACHE1_PULL1, CACHE1_DMA0 to 1 - -Same for other areas - -CACHE1_PUSH1 contains CHID - -If it's different: - -If RmFifoFlushContext failed: Do nothing - -Set PULL0, PUSH0, Caches to 1, return false - - -If it's not: -DMA TLB PTE seems to be 1 for direct programming, maybe RM does it differently -Tag=FFFFFFFF -CACHE1_DMA1 - Number of bytes to send -CACHE1_DMA2 - Get offset -CACHE1_DMA3 - Bus address space (Area BAR0 mapped to? Or bar1?) - -TO START: -To set up DMA for for Cache1 Puller: CACHE1_PULL0 -> 1, changes to 0 when done -To set up DMA Cache1 Push: CACHE1_PUsh0 -> 1, changes to 0 when done -Set CACHES to 1 - -GO: Set DMA0 to 1 - -***** Implementation in Driver ****** - -You can dma to "localvidmem:", "sysvidmem:" or "sysmem:", this is represented by a driver - -CAUSE OF FAILURE: -the pfifo is never free because it never processes the submitted objects -which means that the FIFO is never free -which means that the drivers spin forever waiting for the fifo to be free - -DMA_OBJECT STRUCTURE IN RESOURCE MANAGER: -0x328: Valid -0x34c: base address? -0x374: actually do the transfer - -some objects don't actually need to do dma, for example, video patchcord, it just creates a structure in the driver, and rop just allocate ssome memory to put the data for the patchcord/rop thing - -dma start=nv3_mini dc67 -call of mthdCreate for ***DRIVER*** CLASS ID: a7b44, check ptr - - - - - - diff --git a/doc/nvidia_notes/NV_PFB_CONFIG_0.txt b/doc/nvidia_notes/NV_PFB_CONFIG_0.txt deleted file mode 100644 index dee3b646c..000000000 --- a/doc/nvidia_notes/NV_PFB_CONFIG_0.txt +++ /dev/null @@ -1,29 +0,0 @@ -NV_PFB_CONFIG_0 - -Observed Valus: -Drivers 0x1000 -BIOS 0x1114 - -Bits -5:0 Resolution -9:8 Pixel depth -12:12 Tiling -13:13 Tiling Debug -14:14 Tiling Debug Tile Size -17:15 "Tetris" tiling -19:18 "Tetris" tiling shift -22:20 Bank Swap -23 Unused - -NV_PFB_CONFIG_1 -2:0 CAS Latency -3:3 NEC Mode (PC-98?) -7:4 RAS Default / 9 Cycles -10:8 RAS PCHG -14:12 RAS Low -18:16 MRS to RAS -22:20 Write to Read -26:24 RAS to CAS -30:28 Read to Write -31:31 Read to PCFg - diff --git a/doc/nvidia_notes/PFIFO RAMHT RAMRO.txt b/doc/nvidia_notes/PFIFO RAMHT RAMRO.txt deleted file mode 100644 index 9b4c94718..000000000 --- a/doc/nvidia_notes/PFIFO RAMHT RAMRO.txt +++ /dev/null @@ -1,38 +0,0 @@ -PIO VS dma - -driver is DIRECTLY modifying pfifo - -8X8 channel setup - -Names are 32-bit integers >4096 - -RAMFC - DMA Context object 0,0 to 8,8 - -context = channel, render object, object type, offset in instance memory - -for a rectangle (type 0x47), object render = 1, channel 0, at 0x0400 in the ramht memory - -=0x00c70400 as the context - -the ramht hash : - -xor every byte of the hash individually and then xor that with the channel number - -so obj id 01020304 in channel 0 is 1 xor 2 xor 3 xor 4 xor 0 - -Store in RAMHT at + 4*16 = name -Store in RAMHT at + 4*16 + 4 = context - -then the ramin stuff starts at *0xc04000 since c00000 is the start of ramin [PCI BAR1] which is where you put the contents of the class struct - -nv_user - -Consider the 8x8 channels as 64 subchannels. -Now you can do: - -They seem to end at 0x880000 - -(0x880000)/64 = 0x2000 for each channel - -FAILURE -> RAMRO! - diff --git a/doc/nvidia_notes/RIVA fansites.txt b/doc/nvidia_notes/RIVA fansites.txt deleted file mode 100644 index d1cfaeb90..000000000 --- a/doc/nvidia_notes/RIVA fansites.txt +++ /dev/null @@ -1,26 +0,0 @@ -RIVA fansites (?????): -RIVA User's Group http://tiger.tnstate.edu:8080/ -RIVA 128 Homepage http://pages.prodigy.net/babblin5/Main.html -> Riva3D (riva3d.com) -Zone 128 http://www.tc.umn.edu/~reda0003/zone128/ -RIVAZone https://web.archive.org/web/19981212032348/http://www.rivazone.com/ (Launched January 2, 1998) -Dimension 128 http://dimension128.smartcom.net (early domain name that was mostly not archived) -> d128.com (1999-2001) -Riva3D https://web.archive.org/web/20000525110305/http://riva3d.gxnetwork.com/s3.html -nVNews https://web.archive.org/web/20001205171202/http://www.nvnews.net/ (1999-2015) - -BluesNews has stuff https://www.bluesnews.com/archives/ -(July 1996-present!) - -https://www.bluesnews.com/archives/july97-3.html July 21, 1997 ("unreleased nvidia RIVA chipset is indeed faster than 3dfx" (carmack) - -"However, using the nvidia RIVA 128 chip it runs 1 f/s faster" - -https://web.archive.org/web/19980615024744/http://www.ogr.com/columns/techtalk/technology_talk_0611_2.shtml First mention of NV10 (June 1998) - -"RIVA 128 Turbo" early ZX name -"Riva4" early TNT name - -https://web.archive.org/web/20001002193706/http://www.rivazone.com/files/rivalog.txt - -https://web.archive.org/web/20010422044820/http://www.rivazone.com/finger/finger.cgi?nick@finger.nvidia.com nvidia .plan files - -WAVE Report - april 1997 date for tapeout \ No newline at end of file diff --git a/doc/nvidia_notes/Versions.txt b/doc/nvidia_notes/Versions.txt deleted file mode 100644 index 052de854f..000000000 --- a/doc/nvidia_notes/Versions.txt +++ /dev/null @@ -1,8 +0,0 @@ -Name Base Version Notes Date API Support Platform -0.75_nt4 Version 0.75 No Resource Manager (miniport) 1997-08-15 GDI NT4.0 -0.77_win9x Version 0.77 Symbols (COFF/VXD) 1997-09-02 GDI, D3D5 -nv3quake.zip Version 1.21 OpenGL Alpha 1 1997-11-14 GDI, D3D5, OpenGL 1.1 (alpha; Build 151) Win9x -quakea2f.zip Version 1.21 OpenGL Alpha 2 1997-12-02 GDI, D3D5, OpenGL 1.1 (alpha; Build 258) Win9x -win95_131.zip Version 1.31 OpenGL Beta 1 1998-02-04 GDI, D3D5, OpenGL 1.1 (beta; Build 661) Win9x - - diff --git a/doc/nvidia_notes/gpucompanies.txt b/doc/nvidia_notes/gpucompanies.txt deleted file mode 100644 index 08a6c61c5..000000000 --- a/doc/nvidia_notes/gpucompanies.txt +++ /dev/null @@ -1,63 +0,0 @@ -GPU companies (the period they made gpus) - -DEC 19xx-1998 -HP 19xx-2000+ (possibly until present) -IBM 19xx-2002+ (possibly until present) -E&S 1968-2006 -Intergraph 1969-2000 -Apple 1976-present (some break) -Motorola 1977-1994+ (???) -TI 1979-1988+ -Matrox 1979-2014 -Hitachi 1981-1986 -SGI 1981-2009 -Intel 1983-present -Number Nine 1983-2000 -Tseng Labs 1983-1997 -Cirrus Logic 1984-1998 -Video 7 1985-1991 -C&T 1985-1999 -Imagination 1985-present -NCR 1986-1993 -Paradise/WD 1986-1996 -Gemini 1987-1990 -Genoa Systems 1987-1991 -Trident 1987-2003 -Oak Technology 1988-1997 -Realtek 1988-1997 -Compaq 1989-1991 -Sun 1989-2002(+?) -S3 Graphics 1989-2010 -Macronix 1989-1998 -Winbond 1989-1996+ -Tamarack 198x-1991+ -UMC 198x-1993 -Sigma Designs 198x-1996 -Acer 198x-1998 (roughly) -Fujitsu 198x-1998 -AMD 1991-present (really starting in 2006) -HMC 1991-1994 -Avance Logic 1991-1995 -Weitek <1991-1996 -Bitboys 1991-2006 -IIT 1992-1994 -Weitek 1992-1996(?) -Rendition 1993-1998 -ARK Logic 1993-1999 -S-MOS/Stellar 1994-1999 -Nvidia 1993-present -Alliance 1994-1997 -iGS 1994-1999 -3dfx 1994-2000 -3dlabs 1994-2006 -Silicon Motion 1995-200? -SiS 1995-2007 -Dynamic Pictures1996-1997 -NeoMagic 1996-2000 -GigaPixel 1997-2000 -Philips 1997-199x -Tatung 199x-199x -ASPEED 2004-present -Jingjia 2006-present - - diff --git a/doc/nvidia_notes/hardware cursor.txt b/doc/nvidia_notes/hardware cursor.txt deleted file mode 100644 index 0845778f4..000000000 --- a/doc/nvidia_notes/hardware cursor.txt +++ /dev/null @@ -1,21 +0,0 @@ -NV3/NV3T/NV4 hardware cursor - -Unlock extended CRTC registers - -CIO_CRE_HCUR_ADDR0 - Bits [6:0] = Address - -CIO_CRE_HCUR_ADDR1 - Bits [7:3] = Bits [11:7] of address - Bit 1 = Cursor Doubling - Bit 0 = Enable - -PRAMDAC_CU_START_POS (MMIO 0x680300) - Bits [11:0] = X Pos - Bits [27:16] = Y Pos - -CursorAddress >> 16 written to addr0 -(((CursorAddress >> 11) & 0x1F) << 3) | 1 (for enable) written to addr1 - -Lock extended CRTC registers -Enable - write \ No newline at end of file diff --git a/doc/nvidia_notes/multithreading.pdn b/doc/nvidia_notes/multithreading.pdn deleted file mode 100644 index 427d4bab81b03e52de811f80ca4dd777b63c366d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106011 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≠JI|LU&66?u>f>oZQ43 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
  • {w;*^ab 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 Zny0BMO^5#J*nq?bT^z2uOI1S2s@< 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 diff --git a/doc/nvidia_notes/nv3 driver init status.txt b/doc/nvidia_notes/nv3 driver init status.txt deleted file mode 100644 index d0d13bacd..000000000 --- a/doc/nvidia_notes/nv3 driver init status.txt +++ /dev/null @@ -1,112 +0,0 @@ -Driver version: Windows 2000 Version 3.37 (23 March 1999) - SDK: Windows 2000 build 1996.1 -Features: - -Resource Manager Yes -DirectDraw Yes -OpenGL Yes -Direct3D No - - -get started: -MUST USE X86 WINDBG -Does older windbg support coff??? - -sxe ld nv3_mini.sys -bp nv3_mini + 0x409ac - 0x10000 (nv3_mini+0x309ac) - -offset purpose -30a1a RmInitRm call - -6be7 initClientInfo call -6878 initClientInfo -6bec Check for initClientInfo success -6bf4 initGrPatchPool call -6bf9 Check for initGrPatchPool success -6c01 initDmaListElementPool call -6c06 Check for initDmaListElementPool -6c1c initDisplayInfo call - -6c26 rmInitRm End - Success: eax=FFFFFFFFh / -1 -6c26 Fail eax=0 - -30c8b NvFindAdapter -30cb6 NvFindAdapter -> NVIsPresent call -1010 NVIsPresent function -102f NVIsPresent VideoPortGetAccessRanges call -103b NVIsPresent VideoPortGetAccessRanges call success check (only possible way to fail) -127c NVIsPresent end -30cbb NvFindAdapter -> NVIsPresent success check - Success: al=1 - Failure: al=0 -30cca NVIsPresent NVMapMemoryRanges call -e9e NVIsPresent NVMapMemoryRanges VideoPortGetDeviceBase call #1 [PCI Space] -ea4 NVIsPresent NVMapMemoryRanges VideoPortGetDeviceBase call #1 success check [PCI Space] -ebd NVIsPresent NVMapMemoryRanges VideoPortFreeDeviceBase [conditional] -ec3 NVIsPresent NVMapMemoryRanges VideoPortFreeDeviceBase [conditional] success check -ed6 NVIsPresent NVMapMemoryRanges VideoPortGetDeviceBase call #2 [MMIO] -edc NVIsPresent NVMapMemoryRanges VideoPortGetDeviceBase call #2 success check [MMIO] -f0c NVIsPresent NVMapMemoryRanges VideoPortGetDeviceBase call #3 [LFB/RAMIN?] -f12 NVIsPresent NVMapMemoryRanges VideoPortGetDeviceBase call #3 success check [LFB/RAMIN?] - -30ccf NvFindAdapter NVMapMemoryRanges success check - Success: eax=0 - Failure: eax=87 -30cf1 NvFindAdapter RmInitNvMapping call -6ce6 NvFindAdapter RmInitNvMapping -30cf6 NVIsPresent RmInitNvMapping success check - Success: eax!=0 (in practice 0xFFFFFFFF/-1) - Failure: eax=0 -30d5c NvFindAdapter -30d64 NvFindAdapter RmPostNvDevice call -6d88 RmPostNvDevice function -6d91 NvFindAdapter DevinitInitializeDevice call -6d96 NvFindAdapter DevinitInitializeDevice success check - Success: eax=0 (?) - Failure: eax=1 -e546 DevinitInitializeDevice function - [very complicated] - [several register reads] -e61d DevinitPrepDeviceForInit call -e641 DevinitPrepDeviceForInit function -e627 InitNV call -e67a InitNV function - -30d64 NVIsPresent RmPostNvDevice success check - Success: eax=0 (?) - Failure: eax=1 -30d78 NVIsPresent NVGetNVInfo call -30d7d NVIsPresent NVGetNVInfo success check - -3e9a NvFindAdapter end - Success: eax=0 - Fail eax=55 (RmInitNvMapping or NVIsPresent failed) - Fail eax=87 (NVMapMemoryRanges or NVMapFrameBuffer failed) - -30ea3 NVInitialize -30f02 NVStartIO -2aa6 NVInterrupt -30a2d NVGetChildDescriptor -30a9c NVGetPowerState -30b20 NVSetPowerState - - -Driver Init Status: -DriverEntry Success -rmInitRm -> initClientInfo Success -rmInitRm -> initGrPatchPool Success -rmInitRm -> initDmaListElementPool Success -rmInitRm -> initDisplayInfo Success -rmInitRm overall Success -NvFindAdapter Success 17:32 27/11/2024 -NvFindAdapter -> NvIsPresent Success 16:19 24/11/2024 -NvFindAdapter -> NvMapMemoryRanges Success 19:15 26/11/2024 -NvFindAdapter -> RmInitNvMapping Success 19:18 26/11/2024 -NvFindAdapter -> RmPostNvDevice Success 17:32 27/11/2024 -NvFindAdapter -> NVGetNVInfo Success 17:32 27/11/2024 -NvFindAdapter -> NVMapFrameBuffer Success 17:32 27/11/2024 - -00:00 30/12/2024: stateGr -> i2c_Write -22:31 31/12/2024: fifoService - -fix ptimer issue \ No newline at end of file diff --git a/doc/nvidia_notes/nv3 driver init status_2025-02-10.txt b/doc/nvidia_notes/nv3 driver init status_2025-02-10.txt deleted file mode 100644 index b5643a2ea..000000000 --- a/doc/nvidia_notes/nv3 driver init status_2025-02-10.txt +++ /dev/null @@ -1,90 +0,0 @@ -nv3_disp: - -0x10fe -> DrvBitBlt -0x19be -> DrvCopyBits -0x597c -> DrvCreateDeviceBitmap -0x5a6e -> DrvDeleteDeviceBitmap -0x60b8 -> DrvTextOut -0x6248 -> DrvDestroyFont -0x64b8 -> DrvRealizeBrush -0x6a46 -> DrvDitherColor -0x797a -> DrvGetDirectDrawInfo -0x7b14 -> DrvEnableDirectDraw -0x7b70 -> DrvDisableDirectDraw -0x817c -> DrvPaint -0x81c2 -> DrvResetPDEV -0x82dc -> DrvEnableDriver -0x8312 -> DrvEnablePDEV -0x83ee -> DrvDisablePDEV -0x840a -> DrvCompletePDEV -0x8418 -> DrvSynchronise -0x845a -> DrvEnableSurface -0x851a -> DrvDisableSurface -0x8554 -> DrvAssertMode -0x8690 -> DrvGetModes -0xe59a -> DrvEscape -0xf3ee -> DrvFillPath -0xf3f6 -> DrvStrokePath -0xfa08 -> DrvLineTo -0x12fee -> DrvSetPalette -0x132a4 -> DrvMovePointer -0x13d20 -> DrvSetPointerShape -0x13dea -> DrvStretchBlt -0x147f2 -> DrvSetPixelFormat -0x1483c -> DrvDescribePixelFormat -0x1495a -> DrvClipChanged -0x255b8 -> DrvSwapBuffers - -DrvEnableDriver SUCCESS -DrvEnablePDEV SUCCESS 23:28 09/02/2025 - Check for cjCaps >= 0x130 && cjDevInfo >= 0x12C SUCCESS 23:31 09/02/2025 - EngAllocMem call SUCCESS 23:38 09/02/2025 - CreateOglGlobalMemory call SUCCESS 23:40 09/02/2025 - bInitializeModeFields call SUCCESS 23:41 09/02/2025 - bInitializePalette call SUCCESS 23:42 09/02/2025 - EngDeviceIoControl IOCTL 0x232020 (CHECK mini) SUCCESS - EngDeviceIoControl IOCTL 0x232044 (CHECK mini) SUCCESS (eax=0) -DrvCompletePDEV SUCCESS 23:52 09/02/2025 -DrvEnableSurface - bEnableHardware call SUCCESS 22:36 13/02/2025 - EngCreateSemaphore call #1 csCrtc SUCCESS 00:55 10/02/2025 - EngCreateSemaphore call #2 csFifo SUCCESS 00:57 10/02/2025 - EngDeviceIoControl IOCTL 0x230460 SUCCESS 00:57 10/02/2025 - EngDeviceIoControl IOCTL 0x230458 SUCCESS 00:57 10/02/2025 - NvAllocRoot SUCCESS 01:03 10/02/2025 - NvAllocDevice SUCCESS 01:04 10/02/2025 - NV3/NV4 architecture check SUCCESS 01:14 10/02/2025 - bAssertModeHardware call (bEnable=1) SUCCESS Passing starting with build at 02:23 10/02/2025 - EngDeviceIoControl IOCTL 0x23040C] SUCCESS Passing starting with build at 02:23 10/02/2025 - nv3_mini NVStartIO ioctlcode=0x23040C - NVSetMode - NV3SetMode SUCCESS 01:53 10/02/2025 - RmUnloadState SUCCESS 01:48 10/02/2025 - VBESetModeEx SUCCESS 01:51 10/02/2025 - NV_OEMEnableExtensions SUCCESS 01:52 10/02/2025 - UpdateArbitrationSettings SUCCESS 01:52 10/02/2025 - RmLoadState SUCCESS 01:53 10/02/2025 - NV3EnableCursor SUCCESS 01:54 10/02/2025 - NV3WaitUntilFinished SUCCESS 02:23 10/02/2025 - EngDeviceIoControl IOCTL 0x230408 SUCCESS 02:26 10/02/2025 - EngDeviceIoControl IOCTL 0x232024 SUCCESS 02:26 10/02/2025 - NvAllocHardware SUCCESS 02:29 10/02/2025 - bCreateStdPatches(?) SUCCESS (EAX=1!!!) 22:24 13/02/2025 - CHECK - NV4 N/A - vDestroyStdPatches(?) N/A - NV3_WaitForOneVerticalRefresh SUCCESS - EngDeviceIoControl IOCTL 0x230410 SUCCESS - - - SET UP CORRECT FUNCTION POINTERS - Indirect call (call dword [edi]) to NV3_WaitWhileGraphicsEngineBusy HANG 22:14 16/02/2025 - _heap_init call - bEnableOffscreenHeap call - bEnablePointer call - bEnableText call - bEnablePalette call - bEnableDirectDraw call - EngCreateBitmap call - EngAssociateBitmap call - -DrvDisableSurface: ONLY IN THE CASE OF FAILURE diff --git a/doc/nvidia_notes/nv3_object_classes.txt b/doc/nvidia_notes/nv3_object_classes.txt deleted file mode 100644 index 05d1d9bf3..000000000 --- a/doc/nvidia_notes/nv3_object_classes.txt +++ /dev/null @@ -1,37 +0,0 @@ -Object classes as understood by the GPU. - -(May be represented, in RAMFC, as 0x40+ 22:16) - -0x00 = Invalid -0x01 = beta factor -0x02 = ROP5 operation -0x03 = Chroma key -0x04 = Plane mask -0x05 = Clipping rectangle -0x06 = Pattern -0x07 = Rectangle -0x08 = Point -0x09 = Line -0x0A = Lin (line without starting or ending pixel) -0x0B = Triangle -0x0C = Windows 95 GDI text acceleration -0x0D = Memory to memory format -0x0E = Scaled image from memory -0x0F = INVALID -0x10 = Blit -0x11 = Image -0x12 = Bitmap -0x13 = INVALID -0x14 = Transfer to Memory -0x15 = Stretched image from CPU -0x16 = INVALID -0x17 = Direct3D 5.0 accelerated textured triangle w/zeta buffer -0x18 = Point w/zeta buffer -0x19 = INVALID -0x1A = INVALID -0x1B = INVALID -0x1C = Image in memory -0x1D = INVALID -0x1E = INVALID -0x1F = INVALID - \ No newline at end of file diff --git a/doc/nvidia_notes/nv3d3d_t.txt b/doc/nvidia_notes/nv3d3d_t.txt deleted file mode 100644 index c8579fd6c..000000000 --- a/doc/nvidia_notes/nv3d3d_t.txt +++ /dev/null @@ -1,161 +0,0 @@ -12=unk_int12 -16=unk_short16 -22=unk_short22 (seems to determine if nv_sys_ptr is valid) -24=unk_short24 -26=unk_short26 -44=unk_int44 -56=unk_int56 -60=unk_int60 -64=unk_short64 -66=unk_short66 - -82=unk_short82 - -362..822: - big_struct - (weird alignment?) - 477 - 489 - 505 - -1140=nv_sys_ptr - - -1156=unk_int1156 [start of structure] -1160=unk_int1160 - -1168=unk_int1168 [possibly a byte array of up to 16 bytes) - -1184=unk_int1184 - -1208=unk_int1208 -1212=unk_int1212 -1216=unk_int1216 -1220=unk_int1220 -1224=unk_int1224 - -1236=unk_int1236 -1240=unk_int1240 -1244=unk_int1244 -1248=unk_int1248 - -1256=unk_int1256 -1260=fog_table_enable -1264=unk_int1264 -1270=unk_int1270 -1272=unk_byte1272 -1273=unk_byte1273 -1274=unk_byte1274 (?) -1275=unk_byte1275 - -1316=unk_int1316 -1320=unk_int1320 - -1332=unk_int1332 - -1340=unk_int1340 -1344=unk_int1344 - -1356=unk_int1356 -1360=d3d_clear_enabled -1364=texture_enabled -1368=mipmap_size_max -1372=mipmap_levels -1376=user_mipmaps -1380=zoh_mode (bool) -1384=tex_heap -1388=text_size -1392=video_texture -1396=min_video_tex_size -1400=draw_prim -1404=spread_x -1408=spread_y -1412=size_adj -1416=turbo_adj -1420=dma_min_push_count -1424=dma_push_enable - -1436=unk_int1436 -1440=unk_int1440 - -1448=unk_int1448 -1452=unk_int1452 (set to value of unk_int1908) -1456=unk_int1456 (set to value of unk_int1956) -1460=unk_int1460 (set to value of unk_int2020) - -1516=unk_int1516 -1520=unk_int1520 -1524=unk_int1524 -1528=unk_int1528 -1532=unk_int1532 - -1548=unk_int1548 -1552=unk_int1552 -1556=unk_int1556 -1560=unk_int1560 -1564=unk_int1564 - -1600=unk_int1600 - -1612=unk_int1612 -1616=unk_int1616 -1620=unk_int1620 - -1632=unk_int1632 - -1640=unk_int1640 -1644=unk_ptr1644 - -1676=unk_int1676 -1680=unk_int1680 -1684=unk_int1684 -1688=unk_int1688 -1692=unk_int1692 -1696=unk_int1696 -1700=unk_int1700 - -1716=unk_int1716 -1720=unk_int1720 -1724=unk_int1724 -1728=unk_ptr1728 - -1848=unk_int1848 -1852=unk_int1852 -1856=unk_int1856 (unk_int1552 | 0x800) -1864=unk_func_ptr1864 -1868=unk_int1868 - -1884=unk_int1884 -1888=ptr_to_start_of_structure? -1892=hInstDll -1896=unk_int1896 -1900=unk_int1900 - -1908=unk_int1908 -1912=unk_int1912 -1916=unk_func_ptr1916 -1920=unk_func_ptr1920 - -1932=unk_func_ptr1932 -1936=unk_func_ptr1936 -1944=unk_func_ptr1944 - -1956..2020: Set of function pointrs - 1956=unk_int1956 - 1960=unk_int1960 - 1960=unk_func_ptr1960 - 1964=unk_func_ptr1964 - 1968=unk_func_ptr1968 - 1976=unk_func_ptr1976 - 1980=unk_func_ptr1980 - 1988=unk_func_ptr1988 - 1996=unk_func_ptr1996 - 2000=unk_func_ptr2000 - 2004=unk_func_ptr2004 - 2008=unk_func_ptr2008 - - 2020=unk_int2020 - -2024=unk_int2024 -2028=unk_int2028 -2032=unk_int2032 diff --git a/doc/nvidia_notes/old nouveau wiki.txt b/doc/nvidia_notes/old nouveau wiki.txt deleted file mode 100644 index c875954fd..000000000 --- a/doc/nvidia_notes/old nouveau wiki.txt +++ /dev/null @@ -1,9 +0,0 @@ -old nouveau wiki: -real VRAM address = VRAM_size - (ramin_address - (ramin_address % reversal_unit_size)) - reversal_unit_size + (ramin_address % reversal_unit_size) - -nv3=16 bytes - -0x400000 - ((0x100000) - (0x100000 % 16)) - 16 + (0x100000 % 16) = 2ffff0 - - - \ No newline at end of file diff --git a/doc/nvidia_notes/rivatv_riva128.txt b/doc/nvidia_notes/rivatv_riva128.txt deleted file mode 100644 index 780ad5edd..000000000 --- a/doc/nvidia_notes/rivatv_riva128.txt +++ /dev/null @@ -1,2238 +0,0 @@ - - -Riva 128 documentation -====================== - -This document is based on kernel sources, XFree86 sources, open sources -released by nVidia and pure deduction. To make nVidia happy: - - /***************************************************************************\ -|* *| -|* Copyright (c) 1996-1998 NVIDIA, Corp. All rights reserved. *| -|* *| -|* NOTICE TO USER: The source code is copyrighted under U.S. and *| -|* international laws. NVIDIA, Corp. of Sunnyvale, California owns *| -|* the copyright and as design patents pending on the design and *| -|* interface of the NV chips. Users and possessors of this source *| -|* code are hereby granted a nonexclusive, royalty-free copyright *| -|* and design patent license to use this code in individual and *| -|* commercial software. *| -|* *| -|* Any use of this source code must include, in the user documenta- *| -|* tion and internal comments to the code, notices to the end user *| -|* as follows: *| -|* *| -|* Copyright (c) 1996-1998 NVIDIA, Corp. NVIDIA design patents *| -|* pending in the U.S. and foreign countries. *| -|* *| -|* NVIDIA, CORP. MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF *| -|* THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT *| -|* EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORP. DISCLAIMS *| -|* ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, INCLUDING ALL *| -|* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *| -|* PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORP. BE LIABLE *| -|* FOR ANY SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, *| -|* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR *| -|* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER *| -|* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR *| -|* PERFORMANCE OF THIS SOURCE CODE. *| -|* *| - \***************************************************************************/ - -Feel free to send me corrections, updates, suggestions about this document to: -fero@drama.obuda.kando.hu or rivatv-devel@lists.sourceforge.net -Any kind of info, hint or idea may be helpful. -Please visit the rivatv homepage at: -http://fero.koli.kando.hu/rivatv/ - - - -Rendering -========= - -DMA vs PIO ----------- - -Theese two methods are used to program the hardware. DMA method provides -better performance but it is harder to implement. Almost all of the released -sources uses PIO method. The rest of this document describes the PIO method. - - -Objects -------- - -The Riva rendering engine is an object-oriented hardware. (See the nVidia -docs at https://www.nvidia.com/nv/nvarch.nsf/Home?OpenView -> Documents -> -NV Programmer's Reference Manual) Do not take it serious, it's simplified -for the hardware, it is not like C++. -Each object has a name. The name is 32 bits long and should be unique. - - -FIFO Channels -------------- - -There are 8 channels for submitting graphical objects to the rendering engine. -Each channel contains 8 subchannels. The rules how channels and subchannels -are working is not clear for me yet. Channel 0 is usable without extra coding. -Other channels can not be used until the 'context switching' code is done. -FIFO channels are located in the CTRL memory at 0x00800000-0x0087FFFF. Each -channel is 64 kbytes long, each subchannel is 8 kbytes long. Registers of -subchannels are variable: their function depends on the type of the submitted -object. Registers are write only and 32 bits long except the 'Free' register. - -Offset Name(s) Valid object types ------- ----------------------------- ------------------ -0000 Object all -0010 Free (2 bytes, read only!) all -0100 Synchronize t V s3 -0100 NoOperation BKPCLTRbISMr DG -0104 StopAlarm t -0104 Notify BKPCLTRbISMr DG -0104 StopImage V -0108 StopCursor V -010c StopDac V -0180 DmaNotifies tBKPCLTRbISMrVDGs3 -0184 ClipRectangle LTR -0184 ColorKey bIS -0184 DmaImage M V -0184 DmaTexture D -0184 Pattern G -0184 DmaSource s -0184 DmaSurfaces 3 -0188 Pattern LTR SM -0188 ClipRectangle bI D -0188 Rop G -0188 DmaDestin s -018c Rop LTR SM -018c Pattern bI -018c DmaLut V -018c Surfaces3D D -018c Beta1 G -0190 Beta1 LTR SM -0190 Rop bI -0190 Surfaces G -0194 Surfaces LTR SM -0194 Beta1 bI -0194 DmaCursor V -0198 Surfaces I -019c Surfaces b -02fc Operation LTRbIS G -02fc Get V -0300 Time0 t -0300 Beta1d31 B -0300 ColorFormat KP LTR ISM G -0300 Point C -0300 ControlPointIn b -0300 Rop r -0300 Image V -0300 Format s -0300 Pitch 3 -0304 Time1 t -0304 Color K LTR -0304 MonochromeFormat P G -0304 Size C -0304 ControlPointOut b -0304 Point I -0304 SizeIn S -0304 TextureOffset D -0304 Pitch s -0304 OffsetColor 3 -0300 Operation M -0308 AlarmNotify t -0308 MonochromeShape P -0308 Size b -0308 SizeOut I -0308 DxDu S -0308 ClipPoint M -0308 TextureFormat D -0308 OffsetSource s -0308 OffsetZeta 3 -030c SizeIn I -030c DyDv S -030c ClipSize M -030c TextureFilter D -030c OffsetDestin s -0310 MonochromeColor0 P -0310 TrianglePoint0 T -0310 ClipPoint S -0310 ImageOutPoint M -0310 FogColor D -0314 MonochromeColor1 P -0314 TrianglePoint1 T -0314 ClipSize S -0314 ImageOutSize M -0314 Control0 D -0318 MonochromePattern0 P -0318 TrianglePoint2 T -0318 Point12d4 S -0318 DxDu M -0318 Control1 D -031c MonochromePattern1 P -031c DyDv M -0320 Triangle32Point0X T -0324 Triangle32Point0Y T -0328 Triangle32Point1X T -032c Triangle32Point1Y T -0330 Triangle32Point2X T -0334 Triangle32Point2Y T -0340 Cursor V -0358 CursorPointOutA V -0380 Dac V -03a0 PixelClock V -03fc Color1A G -0400 Lin L -0400 Trimesh T -0400 Rectangle R -0400 Color IS -0400 ImageInSize M -0400 UnclippedRectangle G -0404 ImageInFormat M -0408 ImageInOffset M -040c ImageInPoint M -0480 Lin32 L -0480 Trimesh32 T -0500 PolyLin L -0500 ColorTriangle T -0580 PolyLin32 L -0580 ColorTrimesh T -0600 ColorPolyLin L -07f4 ClipPoint0B G -07f8 ClipPoint0B G -07fc Color1B G -0800 ClippedRectangle G -0bec ClipPoint0C G -0bf0 ClipPoint1C G -0bf4 Color1C G -0bf8 SizeC G -0bfc PointC G -0c00 MonochromeColor1C G -0fe8 ClipPoint0D G -0fec ClipPoint1D G -0ff0 Color1D G -0ff4 SizeInD G -0ff8 SizeOutD G -0ffc PointD G -1000 Tlvertex D -1000 MonochromeColor1D G -13e4 ClipPoint0E G -13e8 ClipPoint1E G -13ec Color0E G -13f0 Color1E G -13f4 SizeInE G -13f8 SizeOutE G -13fc PointE G -1400 MonochromeColor01E G - -t=timer -B=beta1 (0x41) -K=color key (0x43) -P=pattern (0x46) -C=clip rectangle (0x45) -L=solid line (0x4a) -T=solid triangle (0x4b) -R=solid rectangle (0x47) -b=image blit (0x50) -I=image from CPU (0x51) -S=stretched image from CPU (0x55) -M=scaled image from memory (0x4e) -r=raster operation (0x42) -V=video lut cursor dac -D=DX3 textured triangle (0x57) -G=GDI rectangle text (0x4c?) -s=Surfaces 2D -3=Surfaces 3D - -Contexts --------- - -Context is a 32 bit record of channel id, object type and pointer to the -object. - -Bits 24-30: channel id -Bit 23: rendering - 0x0 other object (DMA?) - 0x1 renderable object -Bits 16-22: object type - 0x41 beta1 - 0x42 raster operation - 0x43 color key - 0x44 plane - 0x45 clipping rectangle - 0x46 pattern - 0x47 solid rectangle - 0x49 unknown line - 0x4A solid line - 0x4B solid triangle - 0x4C GDI rectangle - 0x4E scaled image from memory - 0x50 blit - 0x51 image from CPU - 0x52 bitmap - 0x55 streched image from CPU - 0x57 DX3 textured triangle - 0x?? Surfaces 2D - 0x?? Surfaces 3D - 0x?? Timer - 0x?? Video lut cursor dac - and many more... -Bits 0-15: offset in instance memory (RAMIN) / 16 - -Each graphic object has a context. Context determines the type (triangle, -raster operation, bitmap, etc) of the object. Don't ask me why this thingy -is called context: I really don't know. - - -Hash table ----------- - -The hash table (HT) is located in the instance memory area (RAMIN). -See RAMHT register in section FIFO registers. -The HT contains 8 byte length records of object names and contexts. Each -record is placed in the table by it's hash key. The key is computed as -follows: each byte of the object's name and the channel id are XOR-ed -together, and this value is multiplied by the hash depth. More explanation -on hash tables can be found in database books. -The purpose of HT is to provide connection between object names and contexts -for the graphic hardware. But it may be useful for your software driver too. - - -FIFO context table ------------------- - -The FIFO context table (FC) is located in the instance memory area (RAMIN). -See RAMFC register in section FIFO registers. -FC contains the context values for each subchannel. E.g. if FC begins -at 0x1C00: -0x1C00 Context of object in channel 0, subchannel 0 -0x1C04 Context of object in channel 0, subchannel 1 -0x1C08 Context of object in channel 0, subchannel 2 -... -0x1C1C Context of object in channel 0, subchannel 7 -0x1C20 Context of object in channel 1, subchannel 0 -0x1C24 Context of object in channel 1, subchannel 1 -... -0x1CFC Context of object in channel 7, subchannel 7 - - -Example: How to render a solid rectangle? ------------------------------------------ - -- Choose a name for your rectangle. E.g.: 0x01020304 -- Select an unused area in the instance memory. Let it be 0x00c04000 -- Calculate the context: - Channel = 0x00 - Render object = 1 - Object type = 0x47 (rectangle) - Offset in intance memory = 0x4000 / 16 = 0x0400 - Context = 0x00c70400 -- Place the name - context pair in the hash table (HT begins at 0x00c00000): - Hash key = 01 xor 02 xor 03 xor 04 xor 00 = 0x04 - (each byte of the name) (channel id) - *(0x00c00000 + 0x04 * 16) = 0x00000001; // name - *(0x00c00000 + 0x04 * 16) + 4 = 0x00c70400; // context -- Fill in the instace ram: - *(0x00c04000) = 0x00100000; // 15bpp (TODO: decode this magic) - *(0x00c04004) = 0x00000000; // not used yet - *(0x00c04008) = 0x00000000; // not used yet - *(0x00c0400c) = 0x00000000; // not used yet -- At this point the FIFO channel is ready for submitting rectangles. -- Submit the first rectangle: - write the object's name to channel 0 (subchannel 0): - *(0x00800000) = 0x00000001; -- At this point subchannel 0 becomes a rectangle. -- Submit the attributes of the rectangle: - write x,y coordinates: - (0x00800400) = 0x01000200; // x=0x100 y=0x200 - size: - (0x00800404) = 0x00100020; // width=0x10 height=0x20 -- After size is submitted, our rectangle appears on the screen. -- Subsequent rectangles may be submitted by re-sending new attributes. - - -Speculation: How to make video in working? ------------------------------------------- - -V4L stuff and hardware rendered rectangles have some similarities: -- both have color keys -- both have clipping rectangles -- both are stretchable -I suppose video in feature is implemented by rendered objects. A chroma-keyed -and clipped rectangle with 'live texture' is blitted on the screen. -Thats all. :) - - - -Memory layout -============= - -Three memory regions are accessible via the PCI (or AGP) interface: -- CTRL region (PCI base 0) -- FB region (PCI base 1) -- BIOS ROM (PCI base 2) - - -CTRL region ------------ - -The CTRL region contains memory mapped IO ports. Most of them are 32-bit -registers. The registers are grouped by functionality: - -- MC: master control (0x00000000-0x00000FFF) -- BUS: (0x00001000-0x00001FFF) -- FIFO: for DMA and PIO stuff (0x00002000-0x00003FFF) -- TIMER: built-in timer (0x00009000-0x00009FFF) -- VIO: 8 bit SVGA (MISC, GRAPH, SEQ) registers (0x000C0000-0x00C00FFF) -- FB: framebuffer properties (0x00100000-0x00100FFF) -- EXTDEV: external devices (0x00101000-0x00101FFF) -- GRAPH: (0x00400000-0x00401FFF) -- PCIO: 8 bit SVGA (CRTC, ATTR) registers (0x00601000-0x00601FFF) -- RAMDAC: RAMDAC timings (0x00680000-0x00680FFF) -- PDIO: 8 bit registers (0x00681000-0x00681FFF) -- FIFO channels: (0x00800000-0x0087FFFF) -(List in not complete.) - - -FB region ---------- - -This region contains the video memory and the instance memory. -Video memory begins at offset 0x00000000. Instance memory (RAMIN) -begins at offset 0x00C00000. (Note: Riva TNT (and higher) cards have -their instance memory in the CTRL region.) - - - -Master control -============== - -The MC registers begin at 0x00000000 in the CTRL region. They control the -master IRQ. - -Interrupt 0 register --------------------- -Name: INTR_0 -Offset: 0x00000100 -4 bytes, read-write - -Bit 0: PAUDIO (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 4: PMEDIA (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 8: PFIFO (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 12: PGRAPH0 (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 13: PGRAPH1 (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 16: PVIDEO (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 20: PTIMER (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 24: PFB (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 28: PBUS (-V, read-only) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - -Bit 31: SOFTWARE (IV, read-write) - NOT_PENDING 0x0 (default, read-write) - PENDING 0x1 (read-write) - -Interrupt 0 enable register ---------------------------- -Name: INTR_EN_0 -Offset: 0x00000140 -4 bytes, read-write - -Bits 0-1: INTA (IV, read-write) - DISABLED 0x0 (default, read-write) - HARDWARE 0x1 (read-write) - SOFTWARE 0x2 (read-write) - -Enable (what?) register ------------------------ -Name: ENABLE -Offset: 0x00000200 -4 bytes, read-write - - - -Bus -=== - -The BUS registers begin at 0x00001000 in the CTRL region. They are -undiscovered. - -Debug 0 register ----------------- -Name: DEBUG_0 -Offset: 0x00001080 -4 bytes, read-write - -Bit 0: MODE (IV, read-write) - MODE_DISABLED 0x0 (default, read-write) - MODE_ENABLED 0x1 (read-write) - -Bit 4: DESKEWER (IV, read-write) - ENABLED 0x0 (default, read-write) - -Bits 8-11: FBIO_SCLK_DELAY (IV, read-write) - 0x0 (default, read-write) - -Bits 12-15: FBIO_FBCLK_DELAY (IV, read-write) - 0x3 (default, read-write) - -Debug 1 register ----------------- -Name: DEBUG_1 -Offset: 0x00001084 -4 bytes, read-write - -Bit 0: PCIM_THROTTLE (IV, read-write) - DISABLED 0x0 (read-write) - ENABLED 0x1 (default, read-write) - -Bit 1: PCIM_CMD (IV, read-write) - SIZE_BASED 0x0 (default, read-write) - MRL_ONLY 0x1 (read-write) - -Bit 2: PCIM_AGP (IV, read-write) - IS_AGP 0x0 (default, read-write) - IS_PCI 0x1 (read-write) - -Bits 3-4: AGPM_CMD (IV, read-write) - HP_ON_1ST 0x0 (read-write) - LP_ONLY 0x1 (default, read-write) - HP_ONLY 0x2 (read-write) - -Bit 5: PCIS_WRITE (IV, read-write) - 0_CYCLE 0x0 (read-write) - 1_CYCLE 0x1 (default, read-write) - -Bit 6: PCIS_2_1 (IV, read-write) - DISABLED 0x0 (read-write) - ENABLED 0x1 (default, read-write) - -Bit 7: PCIS_RETRY (IV, read-write) - DISABLED 0x0 (read-write) - ENABLED 0x1 (default, read-write) - -Bit 8: PCIS_RD_BURST (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 9: PCIS_WR_BURST (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 10: PCIS_EARLY_RTY (IV, read-write) - DISABLED 0x0 (read-write) - ENABLED 0x1 (default, read-write) - -Bit 11: PCIS_RMAIO (IV, read-write) - DISABLED 0x0 (read-write) - ENABLED 0x1 (default, read-write) - -Bit 12: PCIS_CPUQ (IV, read-write) - DISABLED 0x0 (read-write) - ENABLED 0x1 (default, read-write) - -Bit 13: DPSH_PIPE (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 14: SPARE1 (IV, read-write) - ZERO 0x0 (default, read-write) - ONE 0x1 (read-write) - -Bit 15: SPARE2 (IV, read-write) - ZERO 0x0 (default, read-write) - ONE 0x1 (read-write) - -Bit 16: SPARE3 (IV, read-write) - ZERO 0x0 (default, read-write) - ONE 0x1 (read-write) - - - -FIFO -==== - -The BUS registers begin at 0x00002000 in the CTRL region. - -Interrupt 0 register --------------------- - -Name: INTR_0 -Offset: 0x00002100 -4 bytes, read-write - -Bit 0: CACHE_ERROR (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 4: RUNOUT (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 8: RUNOUT_OVERFLOW (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 12: DMA_PUSHER (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 16: DMA_PTE (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Interrupt 0 enable register ---------------------------- - -Name: INTR_EN_0 -Offset: 0x00002140 -4 bytes, read-write - -Bit 0: CACHE_ERROR (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 4: RUNOUT (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 8: RUNOUT_OVERFLOW (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Config 0 register ------------------ - -Name: CONFIG_0 -Offset: 0x00002200 -4 bytes, read-write - -Hash table register -------------------- - -Hardware hash table offset (in instance memory) and size. - -Name: RAMHT -Offset: 0x00002210 -4 bytes, read-write - -Bits 12-15: BASE_ADDRESS (XV, read-write) - -Bits 16-17: SIZE (XV, read-write) - 4K 0x0 (default, read-write) - 8K 0x1 (read-write) - 16K 0x2 (read-write) - 32K 0x3 (read-write) - -FIFO context table offset -------------------------- - -Name: RAMFC -Offset: 0x00002214 -4 bytes, read-write - -Bits 9-15: BASE_ADDRESS (XV, read-write) - -Runout table register ---------------------- - -FIFO runout table offset and size. - -Name: RAMRO -Offset: 0x00002218 -4 bytes, read-write - -Bits 9-15: BASE_ADDRESS (XV, read-write) - -Bit 16: SIZE (XV, read-write) - 512 0x0 (default, read-write) - 8K 0x1 (read-write) - -Runout status register ----------------------- - -Name: RUNOUT_STATUS -Offset: 0x00002400 -4 bytes, read-only - -Runout put register -------------------- - -Index in runout table. - -Name: RUNOUT_PUT -Offset: 0x00002410 -4 bytes, read-write - -Runout get register -------------------- - -Index in runout table. - -Name: RUNOUT_GET -Offset: 0x00002420 -4 bytes, read-write - -Caches register ---------------- - -Name: CACHES -Offset: 0x00002500 -4 bytes, read-write - -Bit 0: REASSIGN (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Cache 0 push 0 register ------------------------ - -Name: CACHE0_PUSH0 -Offset: 0x00003000 -4 bytes, read-write - -Bit 0: ACCESS (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Cache 0 push 1 register ------------------------ - -Name: CACHE0_PUSH1 -Offset: 0x00003004 -4 bytes, read-write - -Bits 0-6: CHID (XU, read-write) - -Cache 0 pull 0 register ------------------------ - -Name: CACHE0_PULL0 -Offset: 0x00003040 -4 bytes, read-write - -Bit 0: ACCESS (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Cache 1 push 0 register ------------------------ - -Name: CACHE1_PUSH0 -Offset: 0x00003200 -4 bytes, read-write - -Bit 0: ACCESS (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Cache 1 push 1 register ------------------------ - -Name: CACHE1_PUSH1 -Offset: 0x00003204 -4 bytes, read-write - -Bits 0-6: CHID (XU, read-write) - -Cache 1 put register --------------------- - -Name: CACHE1_PUT -Offset: 0x00003210 -4 bytes, read-write - -Bits 2-6: ADDRESS (XU, read-write) - -Cache 1 DMA 0 register ------------------------ - -Name: CACHE1_DMA0 -Offset: 0x00003220 -4 bytes, read-write - -Cache 1 DMA 1 register ------------------------ - -Name: CACHE1_DMA1 -Offset: 0x00003224 -4 bytes, read-write - -Cache 1 DMA 2 register ------------------------ - -Name: CACHE1_DMA2 -Offset: 0x00003228 -4 bytes, read-write - -Cache 1 pull 0 register ------------------------ - -Name: CACHE1_PULL0 -Offset: 0x00003240 -4 bytes, read-write - -Bit 0: ACCESS (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Cache 1 pull 1 register ------------------------ - -Name: CACHE1_PULL1 -Offset: 0x00003250 -4 bytes, read-write - -Bit 4: CTX (XV, read-write) - CLEAN 0x0 (read-write) - DIRTY 0x1 (read-write) - -Cache 1 get register --------------------- - -Name: CACHE1_GET -Offset: 0x00003270 -4 bytes, read-write - -Bits 2-6: ADDRESS (XU, read-write) - -Cache 1 context registers -------------------------- - -8 context registers for each channel (I guess). - -Name: CACHE1_CTX -Offset: 0x00003280+i*16 (0 <= i < 8) -8*16(4?) bytes, read-write - - - -Framebuffer properties -====================== - -The FB registers begin at 0x00100000 in the CTRL region. - -Boot 0 register ---------------- - -Name: BOOT_0 -Offset: 0x00100000 -4 bytes, read-write - -Bits 0-1: RAM_AMOUNT (IV, read-write) - 1MB 0x0 (read-write) - 2MB 0x1 (read-write) - 4MB 0x2 (read-write) - 8MB 0x0 (read-write) - UNDEFINED 0x3 (read-write) - DEFAULT 0x2 (default, read-write) - -Bit 2: RAM_WIDTH_128 (-V, read-write) - OFF 0x0 (read-write) - ON 0x1 (read-write) - -Bit 3: RAM_BANKS (IV, read-write) - 2BANK 0x0 (default, read-write) - 4BANK 0x1 (read-write) - -Bit 4: RAMDATA_TWIDDLE (IV, read-write) - OFF 0x0 (default, read-write) - ON 0x1 (read-write) - -Bit 5: RAM_AMOUNT_EXTENSION (IV, read-write) - OFF 0x0 (default, read-write) - 8MB 0x1 (read-write) - -Delay 1 register ----------------- - -Name: DELAY_1 -Offset: 0x00100044 -4 bytes, read-write - -Bits 0-1: WRITE_ENABLE_RISE (IU, read-write) - WRITE_ENABLE_RISE_0 0x0 (default, read-write) - -Bits 4-5: WRITE_ENABLE_FALL (IU, read-write) - WRITE_ENABLE_FALL_0 0x0 (default, read-write) - -Bits 8-9: CAS_ENABLE_RISE (IU, read-write) - CAS_ENABLE_RISE_0 0x0 (default, read-write) - -Bits 12-13: CAS_ENABLE_FALL (IU, read-write) - CAS_ENABLE_FALL_0 0x0 (default, read-write) - -Bits 16-17: OUTPUT_DATA (IU, read-write) - OUTPUT_DATA_0 0x0 (default, read-write) - -Bits 20-21: RAS_ENABLE (IU, read-write) - RAS_ENABLE_0 0x0 (default, read-write) - -Debug 0 register ----------------- - -Name: DEBUG_0 -Offset: 0x00100080 -4 bytes, read-write - -Bit 4: REFRESH (IV, read-write) - ENABLED 0x0 (default, read-write) - DISABLED 0x1 (read-write) - -Green 0 register ----------------- - -Name: GREEN_0 -Offset: 0x001000C0 -4 bytes, read-write - -Bits 0-1: LEVEL (IV, read-write) - VIDEO_ENABLED 0x0 (read-write) - VIDEO_DISABLED 0x1 (read-write) - TIMING_DISABLED 0x2 (read-write) - MEMORY_DISABLED 0x3 (default, read-write) - -Config 0 register ------------------ - -Name: CONFIG_0 -Offset: 0x00100200 -4 bytes, read-write - -Bits 0-5: RESOLUTION (IV, read-write) - 320_PIXELS 0x0a (read-write) - 400_PIXELS 0x0d (read-write) - 480_PIXELS 0x0f (read-write) - 512_PIXELS 0x10 (read-write) - 640_PIXELS 0x14 (read-write) - 800_PIXELS 0x19 (read-write) - 960_PIXELS 0x1e (read-write) - 1024_PIXELS 0x20 (read-write) - 1152_PIXELS 0x24 (read-write) - 1280_PIXELS 0x28 (read-write) - 1600_PIXELS 0x32 (read-write) - DEFAULT 0x14 (default, read-write) - -Bits 8-9: PIXEL_DEPTH (IV, read-write) - 8_BITS 0x1 (read-write) - 16_BITS 0x2 (read-write) - 32_BITS 0x3 (read-write) - DEFAULT 0x1 (default, read-write) - -Bit 12: TILING (IV, read-write) - ENABLED 0x0 (read-write) - DISABLED 0x1 (default, read-write) - - -Bits 13-23: TILING_DEBUG (IV, read-write) - DISABLED 0x0 (read-write) - -RTL(?) register ---------------- - -Name: RTL -Offset: 0x00100??? -4 bytes, read-write - -Bits 0-1: S (IU, read-write) - DEFAULT 0x2 (default, read-write) - -Bits 4-5: V (IU, read-write) - DEFAULT 0x2 (default, read-write) - -Bits 8-9: M (IU, read-write) - DEFAULT 0x2 (default, read-write) - -Bits 12-13: H (IU, read-write) - DEFAULT 0x1 (default, read-write) - -Bits 16-17: A (IU, read-write) - DEFAULT 0x1 (default, read-write) - -Bits 20-21: G (IU, read-write) - DEFAULT 0x1 (default, read-write) - -Bit 24: ARB_GR_HI_PRIOR (IU, read-write) - DEFAULT 0x0 (default, read-write) - -Bit 28: ARB_MEDIA_HI_PRIOR (IU, read-write) - DEFAULT 0x0 (default, read-write) - - - -External devices -================ - -The EXTDEV registers begin at 0x00101000 in the CTRL region. - -Boot 0 register ---------------- - -Name: BOOT_0 -Offset: 0x00101000 -4 bytes, read-write - -Bit 2: STRAP_RAM_TYPE (XV, read-write) - SGRAM_8MBIT 0x1 (read-write) - SGRAM_16MBIT 0x0 (read-write) - -Bit 11: STRAP_OVERWRITE (IV, read-write) - ENABLED 0x1 (read-write) - -Bit 4: STRAP_RAM_WIDTH (XV, read-write) - 64 0x0 (read-write) - 128 0x1 (read-write) - - - -GRAPH -===== - -The GRAPH registers begin at 0x00400000 in the CTRL region. - -Debug 0 register ----------------- - -Name: DEBUG_0 -Offset: 0x00400080 -4 bytes, read-write - -Bit 0: STATE (-V, clear(check?)-write) - NORMAL 0x0 (clear(check?)-write) - RESET 0x1 (write-only) - -Bit 4: BULK_READS (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 20: WRITE_ONLY_ROPS_2D (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 24: DRAWDIR_AUTO (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Debug 1 register ----------------- - -Name: DEBUG_1 -Offset: 0x00400084 -4 bytes, read-write - -Bit 0: VOLATILE_RESET (IV, read-write) - NOT_LAST 0x0 (default, read-write) - LAST 0x1 (read-write) - -Bit 16: INSTANCE (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 20: CTX (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Debug 2 register ----------------- - -Name: DEBUG_2 -Offset: 0x00400088 -4 bytes, read-write - -Bit 0: AVOID_RMW_BLEND (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 8: DPWR_FIFO (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Bit 28: VOLATILE_RESET (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Debug 3 register ----------------- - -Name: DEBUG_3 -Offset: 0x0040008C -4 bytes, read-write - -Bit 24: HONOR_ALPHA (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Interrupt 0 register --------------------- - -Name: INTR_0 -Offset: 0x00400100 -4 bytes, read-write - -Bit 0: RESERVED (-V, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 4: CONTEXT_SWITCH (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 8: VBLANK (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 12: RANGE (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 16: METHOD_COUNT (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 20: FORMAT (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 24: COMPLEX_CLIP (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 28: NOTIFY (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Interrupt 1 register --------------------- - -Name: INTR_1 -Offset: 0x00400104 -4 bytes, read-write - -Bit 0: METHOD (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 4: DATA (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 12: DOUBLE_NOTIFY (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 16: CTXSW_NOTIFY (IV, read-write) - NOT_PENDING 0x0 (default, read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Interrupt 0 enable register ---------------------------- - -Name: INTR_EN_0 -Offset: 0x00400140 -4 bytes, read-write - -Interrupt 1 enable register ---------------------------- - -Name: INTR_EN_1 -Offset: 0x00400144 -4 bytes, read-write - -Context switch register ------------------------ - -Name: CTX_SWITCH -Offset: 0x00400180 -4 bytes, read-write - -Context control register ------------------------- - -Name: CTX_CONTROL -Offset: 0x00400190 -4 bytes, read-write - -Bits 0-1: MINIMUM_TIME (IV, read-write) - 33US 0x0 (default, read-write) - 262US 0x1 (read-write) - 2MS 0x2 (read-write) - 17MS 0x3 (read-write) - -Bit 8: TIME (IV, read-write) - EXPIRED 0x0 (default, read-write) - NOT_EXPIRED 0x1 (read-write) - -Bit 16: CHID (IV, read-write) - INVALID 0x0 (default, read-write) - VALID 0x1 (read-write) - -Bit 20: SWITCH (-V, read-only) - UNAVAILABLE 0x0 (read-only) - AVAILABLE 0x1 (read-only) - -Bit 24: SWITCHING (IV, read-write) - IDLE 0x0 (default, read-write) - BUSY 0x1 (read-write) - -Bit 28: DEVICE (IV, read-write) - DISABLED 0x0 (default, read-write) - ENABLED 0x1 (read-write) - -Context user register ---------------------- - -Name: CTX_USER -Offset: 0x00400194 -4 bytes, read-write - -Context cache registers ------------------------ - -8 context registers for each channel (I guess). - -Name: CTX_CACHE -Offset: 0x004001a0+i*4 (0 <= i Í8) -8*4 bytes, read-write - -Absolute X RAM registers ------------------------- - -Name: ABS_X_RAM -Offset: 0x00400400+i*4 (0 <= i < 32) -32*4 bytes, read-write - -Absolute Y RAM registers ------------------------- - -Name: ABS_Y_RAM -Offset: 0x00400480+i*4 (0 <= i < 32) -32*4 bytes, read-write - -X misc register ---------------- - -Name: X_MISC -Offset: 0x00400500 -4 bytes, read-write - -Y misc register ---------------- - -Name: Y_MISC -Offset: 0x00400504 -4 bytes, read-write - -Exceptions register -------------------- - -Name: EXCEPTIONS -Offset: 0x00400508 -4 bytes, read-write - -Source color register ---------------------- - -Name: SOURCE_COLOR -Offset: 0x0040050C -4 bytes, read-write - -XY logic misc 0 register ------------------------- - -Name: XY_LOGIC_MISC0 -Offset: 0x00400514 -4 bytes, read-write - -XY logic misc 1 register ------------------------- - -Name: XY_LOGIC_MISC1 -Offset: 0x00400518 -4 bytes, read-write - - DVDY_VALUE 0x0 (default, read-write) (???) - -XY logic misc 2 register ------------------------- - -Name: XY_LOGIC_MISC2 -Offset: 0x0040051C -4 bytes, read-write - -XY logic misc 3 register ------------------------- - -Name: XY_LOGIC_MISC3 -Offset: 0x00400520 -4 bytes, read-write - -Clip X 0 register ------------------ - -Name: CLIPX_0 -Offset: 0x00400524 -4 bytes, read-write - -Clip X 1 register ------------------ - -Name: CLIPX_1 -Offset: 0x00400528 -4 bytes, read-write - -Clip Y 0 register ------------------ - -Name: CLIPY_0 -Offset: 0x0040052c -4 bytes, read-write - -Clip Y 1 register ------------------ - -Name: CLIPY_1 -Offset: 0x00400530 -4 bytes, read-write - -Absolute iclip X max. register ------------------------------- - -Name: ABS_ICLIP_XMAX -Offset: 0x00400534 -4 bytes, read-write - -Absolute iclip Y max. register ------------------------------- - -Name: ABS_ICLIP_YMAX -Offset: 0x00400538 -4 bytes, read-write - -Absolute uclip X min. register ------------------------------- - -Name: ABS_UCLIP_XMIN -Offset: 0x0040053C -4 bytes, read-write - -Absolute uclip Y min. register ------------------------------- - -Name: ABS_UCLIP_YMIN -Offset: 0x00400540 -4 bytes, read-write - -Absolute uclip X max. register ------------------------------- - -Name: ABS_UCLIP_XMAX -Offset: 0x00400544 -4 bytes, read-write - -Absolute uclip Y max. register ------------------------------- - -Name: ABS_UCLIP_YMAX -Offset: 0x00400548 -4 bytes, read-write - -Absolute uclipa X min. register ------------------------------- - -Name: ABS_UCLIPA_XMIN -Offset: 0x00400560 -4 bytes, read-write - -Absolute uclipa Y min. register ------------------------------- - -Name: ABS_UCLIPA_YMIN -Offset: 0x00400564 -4 bytes, read-write - -Absolute uclipa X max. register ------------------------------- - -Name: ABS_UCLIPA_XMAX -Offset: 0x00400568 -4 bytes, read-write - -Absolute uclipa Y max. register ------------------------------- - -Name: ABS_UCLIPA_YMAX -Offset: 0x0040056C -4 bytes, read-write - -Source canvas min. register ---------------------------- - -Name: SRC_CANVAS_MIN -Offset: 0x00400550 -4 bytes, read-write - -Source canvas max. register ---------------------------- - -Name: SRC_CANVAS_MAX -Offset: 0x00400554 -4 bytes, read-write - -Destination canvas min. register --------------------------------- - -Name: DST_CANVAS_MIN -Offset: 0x00400558 -4 bytes, read-write - -Destination canvas max. register --------------------------------- - -Name: DST_CANVAS_MAX -Offset: 0x0040055C -4 bytes, read-write - -Pattern color 0 0 register --------------------------- - -Name: PATT_COLOR0_0 -Offset: 0x00400600 -4 bytes, read-write - -Pattern color 0 1 register --------------------------- - -Name: PATT_COLOR0_1 -Offset: 0x00400604 -4 bytes, read-write - -Pattern color 1 0 register --------------------------- - -Name: PATT_COLOR1_0 -Offset: 0x00400608 -4 bytes, read-write - -Pattern color 1 1 register --------------------------- - -Name: PATT_COLOR1_1 -Offset: 0x0040060C -4 bytes, read-write - -Pattern registers ------------------ - -Name: PATTERN -Offset: 0x00400610+i*4 (0 <=i < 2) -2*4 bytes, read-write - -Pattern shape register ----------------------- - -Name: PATTERN_SHAPE -Offset: 0x00400618 -4 bytes, read-write - -Bits 0-1: VALUE (XV, read-write) - 8X8 0x0 (read-write) - 64X1 0x1 (read-write) - 1X64 0x2 (read-write) - -Monochrome color 0 register ---------------------------- - -Name: MONO_COLOR0 -Offset: 0x0040061C -4 bytes, read-write - -Raster operation register -------------------------- - -Name: ROP3 -Offset: 0x00400624 -4 bytes, read-write - -Plane mask register -------------------- - -Name: PLANE_MASK -Offset: 0x00400628 -4 bytes, read-write - -Chroma register ---------------- - -Name: CHROMA -Offset: 0x0040062C -4 bytes, read-write - -B(?) offset 0 register ----------------------- - -Name: BOFFSET0 -Offset: 0x00400630 -4 bytes, read-write - -B(?) offset 1 register ----------------------- - -Name: BOFFSET1 -Offset: 0x00400634 -4 bytes, read-write - -B(?) offset 2 register ----------------------- - -Name: BOFFSET2 -Offset: 0x00400638 -4 bytes, read-write - -B(?) offset 3 register ----------------------- - -Name: BOFFSET3 -Offset: 0x0040063C -4 bytes, read-write - -Beta register -------------- - -Name: BETA -Offset: 0x00400640 -4 bytes, read-write - -Control out register --------------------- - -Name: CONTROL_OUT -Offset: 0x00400644 -4 bytes, read-write - -B(?) pitch 0 register ---------------------- - -Name: BPITCH0 -Offset: 0x00400650 -4 bytes, read-write - -B(?) pitch 1 register ---------------------- - -Name: BPITCH1 -Offset: 0x00400654 -4 bytes, read-write - -B(?) pitch 2 register ---------------------- - -Name: BPITCH2 -Offset: 0x00400658 -4 bytes, read-write - -B(?) pitch 3 register ---------------------- - -Name: BPITCH3 -Offset: 0x0040065C -4 bytes, read-write - -DMA register ------------- - -Name: DMA -Offset: 0x00400680 -4 bytes, read-write - -Notify register ---------------- - -Name: NOTIFY -Offset: 0x00400684 -4 bytes, read-write - -Bits 0-15: INST_MEM_LOC ??? - -Instance register ------------------ - -Name: INSTANCE -Offset: 0x00400688 -4 bytes, read-write - -Memory format register ----------------------- - -Name: MEMFMT -Offset: 0x0040068C -4 bytes, read-write - -Clip 0 min. register --------------------- - -Name: CLIP0_MIN -Offset: 0x00400690 -4 bytes, read-write - -Clip 0 max. register --------------------- - -Name: CLIP0_MAX -Offset: 0x00400694 -4 bytes, read-write - -Clip 1 min. register --------------------- - -Name: CLIP1_MIN -Offset: 0x00400698 -4 bytes, read-write - -Clip 1 max. register --------------------- - -Name: CLIP1_MAX -Offset: 0x0040069C -4 bytes, read-write - -Clip misc register ------------------- - -Name: CLIP_MISC -Offset: 0x004006A0 -4 bytes, read-write - -FIFO register -------------- - -Name: FIFO -Offset: 0x004006A4 -4 bytes, read-write - -Bit 0: ACCESS (IV, read-write) - DISABLED 0x0 (read-write) - ENABLED 0x1 (default, read-write) - -B(?) pixel register -------------------- - -Name: BPIXEL -Offset: 0x004006A8 -4 bytes, read-write - -Bits 0-1: DEPTH0_FMT (XV, read-write) - Y16_BITS 0x0 (read-write) - BITS_8 0x1 (read-write) - BITS_16 0x2 (read-write) - BITS_32 0x3 (read-write) - -Bit 2: DEPTH0 (XV, read-write) - NOT_VALID 0x0 (read-write) - VALID 0x1 (read-write) - -Bits 4-5: DEPTH1_FMT (XV, read-write) - Y16_BITS 0x0 (read-write) - BITS_8 0x1 (read-write) - BITS_16 0x2 (read-write) - BITS_32 0x3 (read-write) - -Bit 6: DEPTH1 (XV, read-write) - NOT_VALID 0x0 (read-write) - VALID 0x1 (read-write) - -Bits 8-9: DEPTH2_FMT (XV, read-write) - Y16_BITS 0x0 (read-write) - BITS_8 0x1 (read-write) - BITS_16 0x2 (read-write) - BITS_32 0x3 (read-write) - -Bit 10: DEPTH2 (XV, read-write) - NOT_VALID 0x0 (read-write) - VALID 0x1 (read-write) - -Bits 12-13: DEPTH3_FMT (XV, read-write) - Y16_BITS 0x0 (read-write) - BITS_8 0x1 (read-write) - BITS_16 0x2 (read-write) - BITS_32 0x3 (read-write) - -Bit 14: DEPTH3 (XV, read-write) - NOT_VALID 0x0 (read-write) - VALID 0x1 (read-write) - -Status register ---------------- - -Name: STATUS -Offset: 0x004006B0 -4 bytes, read-only - -DMA interrupt 0 register ------------------------- - -Name: DMA_INTR_0 -Offset: 0x00401100 -4 bytes, read-write - -Bit 0: INSTANCE (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 4: PRESENT (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 8: PROTECTION (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 12: LINEAR (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -Bit 16: NOTIFY (XV, read-write) - NOT_PENDING 0x0 (read-only) - PENDING 0x1 (read-only) - RESET 0x1 (write-only) - -DMA interrupt 0 enable register -------------------------------- - -Name: DMA_INTR_EN_0 -Offset: 0x00401140 -4 bytes, read-write - -DMA control register --------------------- - -Name: DMA_CONTROL -Offset: 0x00401210 -4 bytes, read-write - - - -RAMDAC -====== - -The RAMDAC registers begin at 0x00680000 in the CTRL region. - -Graphic cursor starting position register ------------------------------------------ - -Name: GRCURSOR_START_POS -Offset: 0x00680300 -4 bytes, read-write - -Bits 0-11: X (XS, read-write) - -Bits 16-27: Y (XS, read-write) - -MPLL coeff register -------------------- - -Name: MPLL_COEFF -Offset: 0x00680504 -4 bytes, read-write - -Bits 0-7: MDIV (IU, read-write) - -Bits 8-15: NDIV (IU, read-write) - -Bits 16-18: PDIV (IV, read-write) - -VPLL coeff register -------------------- - -Name: VPLL_COEFF -Offset: 0x00680508 -4 bytes, read-write - -Bits 0-7: MDIV (IU, read-write) - -Bits 8-15: NDIV (IU, read-write) - -Bits 16-18: PDIV (IV, read-write) - -PLL coeff select register -------------------------- - -Name: PLL_COEFF_SELECT -Offset: 0x0068050C -4 bytes, read-write - -Bit 4: DLL_BYPASS (IV, read-write) - FALSE 0x0 (default, read-write) - TRUE 0x1 (read-write) - -Bit 8: MPLL_SOURCE (IV, read-write) - DEFAULT 0x0 (default, read-write) - PROG 0x1 (read-write) - -Bit 12: MPLL_BYPASS (IV, read-write) - FALSE 0x0 (default, read-write) - TRUE 0x1 (read-write) - -Bit 16: VPLL_SOURCE (IV, read-write) - DEFAULT 0x0 (default, read-write) - PROG 0x1 (read-write) - -Bit 20: VPLL_BYPASS (IV, read-write) - FALSE 0x0 (default, read-write) - TRUE 0x1 (read-write) - -Bits 24-25: PCLK_SOURCE (IV, read-write) - VPLL 0x0 (default, read-write) - VIP 0x1 (read-write) - XTALOSC 0x2 (read-write) - -Bit 28: VCLK_RATIO (IV, read-write) - DB1 0x0 (default, read-write) - DB2 0x1 (read-write) - -General control register ------------------------- - -Various flags for DAC. BPC controls the width of the palette. - -Name: GENERAL_CONTROL -Offset: 0x00680600 -4 bytes, read-write - -Bits 0-1: FF_COEFF (IV, read-write) - DEF 0x0 (default, read-write) - -Bit 4: IDC_MODE (IV, read-write) - GAMMA 0x0 (default, read-write) - INDEX 0x1 (read-write) - -Bit 8: VGA_STATE (IV, read-write) - NOTSEL 0x0 (default, read-write) - SEL 0x1 (read-write) - -Bit 12: 565_MODE (IV, read-write) - NOTSEL 0x0 (default, read-write) - SEL 0x1 (read-write) - -Bit 16: BLK_PEDSTL (IV, read-write) - OFF 0x0 (default, read-write) - ON 0x1 (read-write) - -Bit 17: TERMINATION (IV, read-write) - 37OHM 0x0 (default, read-write) - 75OHM 0x1 (read-write) - -Bit 20: BPC (IV, read-write) - 6BITS 0x0 (default, read-write) - 8BITS 0x1 (read-write) - -Bit 24: DAC_SLEEP (IV, read-write) - DIS 0x0 (default, read-write) - EN 0x1 (read-write) - -Bit 28: PALETTE_CLK (IV, read-write) - EN 0x0 (default, read-write) - DIS 0x1 (read-write) - -VSERR width register --------------------- - -Name: VSERR_WIDTH -Offset: 0x00680700 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -VEQU end register ------------------ - -Name: VEQU_END -Offset: 0x00680704 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Vertical B(?) blank end register --------------------------------- - -Name: VBBLANK_END -Offset: 0x00680708 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Vertical blank end register ---------------------------- - -Name: VBLANK_END -Offset: 0x0068070C -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Vertical blank start register ------------------------------ - -Name: VBLANK_START -Offset: 0x00680710 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Vertical (B?) blank start register ----------------------------------- - -Name: VBBLANK_START -Offset: 0x00680714 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -VEQU start register -------------------- - -Name: VEQU_START -Offset: 0x00680718 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Vertical total register ------------------------ - -Name: VTOTAL -Offset: 0x0068071C -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Horizontal sync width register ------------------------------- - -Name: HSYNC_WIDTH -Offset: 0x00680720 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Horizontal burst start register -------------------------------- - -Name: HBURST_START -Offset: 0x00680724 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Horizontal burst end register ------------------------------ - -Name: HBURST_END -Offset: 0x00680728 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Horizontal blank start register -------------------------------- - -Name: HBLANK_START -Offset: 0x0068072C -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Horizontal blank end register ------------------------------ - -Name: HBLANK_END -Offset: 0x00680730 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -Horizontal total register -------------------------- - -Name: HTOTAL -Offset: 0x00680734 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -HEQU width register -------------------- - -Name: HEQU_WIDTH -Offset: 0x00680738 -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - -HSERR width register --------------------- - -Name: HSERR_WIDTH -Offset: 0x0068073C -4 bytes, read-write - -Bits 0-10: VAL (IV, read-write) - - - -'Standard' SVGA registers -========================= - -ATTR, CTRC, GRAPH, SEQ and MISC registers are available throught MMIO too. - -Name: ATTR_REG_INDEX -Offset: 0x006013c0 -1 byte, read-write - -Name: ATTR_REG_DATA -Offset: 0x006013c1 -1 byte, read-write - -Name: CRTC_REG_INDEX -Offset: 0x006013d4 -1 byte, read-write - -Name: CRTC_REG_DATA -Offset: 0x006013d5 -1 byte, read-write - -Name: GRA_REG_INDEX -Offset: 0x000C03ce -1 byte, read-write - -Name: GRA_REG_DATA -Offset: 0x000C03cf -1 byte, read-write - -Name: SEQ_REG_INDEX -Offset: 0x000C03c4 -1 byte, read-write - -Name: SEQ_REG_DATA -Offset: 0x000C03c5 -1 byte, read-write - -Name: MISC_REG -Offset: 0x000C03c2 -1 byte, read-write - - - -Extra CRTC registers -==================== - -Repaint 0 register ------------------- - -Extended offset and start address. - -Name: REPAINT0 -Index: 0x19 -1 byte - -Bits 0-4: START_ADDR_20_16 - -Bits 5-7: OFFSET_10_8 - -Repaint 1 register ------------------- - -Various flags. - -Name: REPAINT1 -Index: 0x1a -1 byte - -Bit 1: PALETTE_WIDTH - 8BITS 0x0 - 6BITS 0x1 - -Bit 2: LARGE_SCREEN - DISABLE 0x1 - ENABLE 0x0 ( >= 1280 ) - -Bit 4: COMPATIBLE_TEXT - ENABLE 0x1 - DISABLE 0x0 - -Bit 6: VSYNC - DISABLE 0x1 - ENABLE 0x0 - -Bit 7: HSYNC - DISABLE 0x1 - ENABLE 0x0 - -FIFO control register ---------------------- - -Controls how much data the refresh fifo requests. - -Name: FIFO_CONTROL -Index: 0x1b -1 byte - -Bits 0-2: BURST_LENGTH - BURST_LENGTH_8 0x0 - BURST_LENGTH_32 0x1 - BURST_LENGTH_64 0x2 - BURST_LENGTH_128 0x3 - BURST_LENGTH_256 0x4 - -Bit 7: UNDERFLOW_WARN - -FIFO register -------------- - -When the fifo occupancy falls below *twice* the watermark, -the refresh fifo will start to be refilled. If this value is -too low, you will get junk on the screen. Too high, and performance -will suffer. Watermark in units of 8 bytes. - -Name: FIFO -Index: 0x20 -1 byte - -Bits 0-5: WATERMARK - -Bit 7: RESET - -Extra register --------------- - -Assorted extra bits. - -Name: EXTRA -Index: 0x25 -1 byte - -Bit 0: VERT_TOTAL_10 - -Bit 1: VERT_DISPLAY_END_10 - -Bit 2: VERT_RETRACE_START_10 - -Bit 3: VERT_BLANK_START_10 - -Bit 4: HORIZ_BLANK_END_6 - -Bit 5: OFFSET_11 - -Pixel register --------------- - -Controls what the format of the framebuffer is. - -Name: PIXEL -Index: 0x28 -1 byte - -Bits 0-1: FORMAT - VGA 0x0 - 8BPP 0x1 - 16BPP 0x2 - 32BPP 0x3 - -Bits 3-5: TV_HORIZ_ADJUST - -Bit 6: TV_MODE - NTSC 0x0 - PAL 0x1 - -Bit 7: MODE - TV 0x1 - VGA 0x0 - -Horizontal extra register -------------------------- - -Horizonal extended bits. - -Name: HORIZ_EXTRA -Index: 0x2d -1 byte - -Bit 0: DISPLAY_TOTAL_8 - -Bit 1: DISPLAY_END_8 - -Bit 2: HORIZ_BLANK_START_8 - -Bit 3: HORIZ_RETRACE_START_8 - -Bit 4: INTER_HALF_START_8 - -Graphic cursor 0 register -------------------------- - -Name: GRCURSOR0 -Index: 0x30 -1 byte - -Bits 0-5: START_ADDR_21_16 - -Graphic cursor 1 register -------------------------- - -Name: GRCURSOR1 -Index: 0x31 -1 byte - -Bit 0: CURSOR - DISABLE 0x0 - ENABLE 0x1 - -Bit 1: SCAN_DBL - DISABLE 0x0 - ENABLE 0x1 - -Bits 3-7: START_ADDR_15_11 - -EOF diff --git a/doc/nvidia_notes/status.xlsx b/doc/nvidia_notes/status.xlsx deleted file mode 100644 index bfeeb14528f00e6aa6a6f1d9e1f055ab1399947f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15945 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 - * - * Copyright 2024-2025 Connor Hyde - */ - -#pragma once -#include -#include -#include -#include - -// CLass names for debugging -extern const char* nv3_class_names[]; - -/* Defines valid classes. */ -typedef enum nv3_pgraph_class_e -{ - nv3_pgraph_class01_beta_factor = 0x01, - nv3_pgraph_class02_rop = 0x02, - nv3_pgraph_class03_chroma_key = 0x03, - nv3_pgraph_class04_plane_mask = 0x04, - nv3_pgraph_class05_clipping_rectangle = 0x05, - nv3_pgraph_class06_pattern = 0x06, - nv3_pgraph_class07_rectangle = 0x07, - nv3_pgraph_class08_point = 0x08, - nv3_pgraph_class09_line = 0x09, - nv3_pgraph_class0a_lin = 0x0a, - nv3_pgraph_class0b_triangle = 0x0b, - nv3_pgraph_class0c_w95txt = 0x0c, - nv3_pgraph_class0d_m2mf = 0x0d, - nv3_pgraph_class0e_scaled_image_from_memory = 0x0e, - nv3_pgraph_class10_blit = 0x10, - nv3_pgraph_class11_image = 0x11, - nv3_pgraph_class12_bitmap = 0x12, - nv3_pgraph_class14_transfer2memory = 0x14, - nv3_pgraph_class15_stretched_image_from_cpu = 0x15, - nv3_pgraph_class17_d3d5tri_zeta_buffer = 0x17, - nv3_pgraph_class18_point_zeta_buffer = 0x18, - nv3_pgraph_class1c_image_in_memory = 0x1c, -} nv3_pgraph_class; - -/* - OBJECT METHODS -*/ - -// Global stuff -#define NV3_ROOT_HI_IM_OBJECT_MCOBJECTYFACE 0x0 // I'm going insane at 00:48 14/02/2025 -#define NV3_SET_NOTIFY_CONTEXT_FOR_DMA 0x0100 // Set object ctx for dma...see nv3_dma_context_t structure -#define NV3_SET_NOTIFY 0x0104 - -// Crap e.g. "OS name", that sometimes gets submitted, for some reason. So we just suppress the warning messages for them -#define NV3_NVCLASS_CRAP_START 0x0310 -#define NV3_NVCLASS_CRAP_END 0x0324 - -// Render OPeration -#define NV3_ROP_SET_ROP 0x0300 // Set GDI standard rop - -// Beta Factor -#define NV3_BETA_FACTOR 0x0300 - -// Chroma Key -// Can't figure out what this is, used in 9x but certainly software, can't find anywhere... -#define NV3_CHROMA_UNKNOWN_0200 0x0200 -#define NV3_CHROMA_KEY 0x0304 - -// Clip -#define NV3_CLIP_POSITION 0x0300 // S16:S16, 0=topleft -#define NV3_CLIP_SIZE 0x0304 // U16:U16 - -// Blit Pattern -#define NV3_PATTERN_FORMAT 0x0304 -#define NV3_PATTERN_SHAPE 0x0308 -#define NV3_PATTERN_SHAPE_8X8 0 -#define NV3_PATTERN_SHAPE_64X1 1 -#define NV3_PATTERN_SHAPE_1X64 2 -#define NV3_PATTERN_SHAPE_LAST_VALID NV3_PATTERN_SHAPE_1X64 - -#define NV3_PATTERN_UNUSED_DRIVER_BUG 0x030C -#define NV3_PATTERN_COLOR0 0x0310 -#define NV3_PATTERN_COLOR1 0x0314 -#define NV3_PATTERN_BITMAP_HIGH 0x0318 -#define NV3_PATTERN_BITMAP_LOW 0x031C - -// Rect - -#define NV3_RECTANGLE_COLOR 0x0304 - -// 16 possible rectangles. 8 byte structure, first 4 bytes = position, second 2 = size. -#define NV3_RECTANGLE_START 0x0400 - -#define NV3_RECTANGLE_MAX 16 -#define NV3_RECTANGLE_END 0x0480 - -// M2MF -#define NV3_M2MF_IN_CTXDMA_OFFSET 0x030C -#define NV3_M2MF_OUT_CTXDMA_OFFSET 0x0310 -#define NV3_M2MF_IN_PITCH 0x0314 -#define NV3_M2MF_OUT_PITCH 0x0318 -#define NV3_M2MF_SCANLINE_LENGTH_IN_BYTES 0x031C -#define NV3_M2MF_NUM_SCANLINES 0x0320 -#define NV3_M2MF_FORMAT 0x0324 - -// M2MF formats (IN and OUT ORed together) -#define NV3_M2MF_FORMAT_INPUT 0 -#define NV3_M2MF_FORMAT_OUTPUT 8 - -#define NV3_M2MF_NOTIFY 0x0328 - -// blit -#define NV3_BLIT_POSITION_IN 0x0300 -#define NV3_BLIT_POSITION_OUT 0x0304 -#define NV3_BLIT_SIZE 0x0308 - -// image_from_cpu -#define NV3_IMAGE_START_POSITION 0x0304 // starting position of image from cpu -#define NV3_IMAGE_SIZE 0x0308 -#define NV3_IMAGE_SIZE_IN 0x030C -#define NV3_IMAGE_COLOR_START 0x0400 -#define NV3_IMAGE_COLOR_MAX 32 -#define NV3_IMAGE_COLOR_END 0x0480 - -#define NV3_IMAGE_IN_MEMORY_COLOR_FORMAT 0x0300 -#define NV3_IMAGE_IN_MEMORY_IN_MEMORY_DMA_CTX_TYPE 0x0304 -#define NV3_IMAGE_IN_MEMORY_PITCH 0x0308 -#define NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET 0x030C -#define NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET_END 22 - -/* GDI */ - -/* Type A: Unclipped Rectangle */ -#define NV3_W95TXT_A_COLOR 0x03FC // It's the colour of the text. This is used to submit a dummy object so the notifier can be used to sync in Win2000 DDraw6 drivers. -#define NV3_W95TXT_A_RECT_START 0x0400 -#define NV3_W95TXT_A_RECT_SIZE 64 // Number of rects -#define NV3_W95TXT_A_RECT_END 0x05FF - -/* Type B: Clipped Rectangle */ -#define NV3_W95TXT_B_CLIP_TOPLEFT 0x07F4 -#define NV3_W95TXT_B_CLIP_BOTTOMRIGHT 0x07F8 -#define NV3_W95TXT_B_COLOR 0x07FC -#define NV3_W95TXT_B_CLIP_CLIPRECT_START 0x0800 -#define NV3_W95TXT_B_CLIP_CLIPRECT_SIZE 128 // Number of rects -#define NV3_W95TXT_B_CLIP_CLIPRECT_END 0x09FF - -/* Type C: Unscaled Single-Colour Text (filled in from mono bitmap) */ -#define NV3_W95TXT_C_CLIP_TOPLEFT 0x0BEC -#define NV3_W95TXT_C_CLIP_BOTTOMRIGHT 0x0BF0 -#define NV3_W95TXT_C_CLIP_COLOR 0x0BF4 -#define NV3_W95TXT_C_CLIP_SIZE 0x0BF8 -#define NV3_W95TXT_C_CLIP_POSITION 0x0BFC /* TOP LEFT */ -#define NV3_W95TXT_C_CLIP_CLIPRECT_START 0x0C00 -#define NV3_W95TXT_C_CLIP_CLIPRECT_SIZE 64 // Number of rects -#define NV3_W95TXT_C_CLIP_CLIPRECT_END 0x0DFF - -/* Type D: Scaled Single-Colour Text (filled in from mono bitmap) */ -#define NV3_W95TXT_D_CLIP_TOPLEFT 0x0FE8 -#define NV3_W95TXT_D_CLIP_BOTTOMRIGHT 0x0FEC -#define NV3_W95TXT_D_CLIP_COLOR 0x0FF0 -#define NV3_W95TXT_D_CLIP_SIZE_IN 0x0FF4 -#define NV3_W95TXT_D_CLIP_SIZE_OUT 0x0FF8 -#define NV3_W95TXT_D_CLIP_POSITION 0x0FFC /* TOP LEFT */ -#define NV3_W95TXT_D_CLIP_CLIPRECT_START 0x1000 -#define NV3_W95TXT_D_CLIP_CLIPRECT_SIZE 128 // Number of rects -#define NV3_W95TXT_D_CLIP_CLIPRECT_END 0x11FF - -/* Type E: Scaled Pattern-type Bitmap Text (filled) */ -#define NV3_W95TXT_E_CLIP_TOPLEFT 0x13E4 -#define NV3_W95TXT_E_CLIP_BOTTOMRIGHT 0x13E8 -#define NV3_W95TXT_E_CLIP_COLOR_0 0x13EC -#define NV3_W95TXT_E_CLIP_COLOR_1 0x13F0 -#define NV3_W95TXT_E_CLIP_SIZE_IN 0x13F4 -#define NV3_W95TXT_E_CLIP_SIZE_OUT 0x13F8 -#define NV3_W95TXT_E_CLIP_POSITION 0x13FC /* TOP LEFT */ -#define NV3_W95TXT_E_CLIP_CLIPRECT_START 0x1400 -#define NV3_W95TXT_E_CLIP_CLIPRECT_SIZE 128 // Number of rects -#define NV3_W95TXT_E_CLIP_CLIPRECT_END 0x15FF - - -/* Class context switch method */ -typedef struct nv3_class_ctx_switch_method_s -{ - union - { - uint32_t data; - - uint16_t instance; - uint8_t channel : 6; - uint16_t reserved : 9; - bool reset_if_volatile; // ???? - } set_notify_ctx_dma; // Set notifier context for DMA (context switch) - -} nv3_class_ctx_switch_method_t; - -/* -enumerates color formats -there are some other colour formats that are only used in certain areas which are defined below -*/ -typedef enum nv3_pgraph_pixel_format_e -{ - nv3_pgraph_pixel_format_r5g5b5 = 0, - nv3_pgraph_pixel_format_r8g8b8 = 1, - nv3_pgraph_pixel_format_r10g10b10 = 2, - nv3_pgraph_pixel_format_y8 = 3, - nv3_pgraph_pixel_format_y16 = 4, - nv3_pgraph_pixel_format_v8y8u8y18 = 5, // "18"? NV wtf? - nv3_pgraph_pixel_format_y18v8y8u8 = 6, // "18"? NV wtf? - nv3_pgraph_pixel_format_y420 = 7, // YUV 420 -} nv3_pgraph_pixel_format; - -/* Main color format */ -typedef struct nv3_color_expanded_s -{ - uint8_t a; - - /* WARNING: The internal format is 10-bit RGB! */ - uint16_t r; - uint16_t g; - uint16_t b; - - // YUV stuff - float y; - float u; - float v; - - // Indexed colour - union - { - uint16_t i16; - - uint8_t i16_high; - uint8_t i8; - }; - - // the pixel format - nv3_pgraph_pixel_format pixel_format; -} nv3_color_expanded_t; - -/* A simple ARGB format colour */ -typedef struct nv3_color_argb_s -{ - uint8_t a; - uint8_t r; - uint8_t g; - uint8_t b; -} nv3_color_argb_t; - -/* Generic 16-bit coordinate*/ -typedef struct nv3_coord_16_s -{ - uint16_t x; - uint16_t y; -} nv3_coord_16_t; - -/* A big position format with 30:16 = y, 15:11 = nothing, 10:0 = x */ -typedef struct nv3_coord_16_bigy_s -{ - // WHOSE IDEA WAS THIS? - uint16_t x : 11; - uint8_t reserved : 5; - uint16_t y : 15; - bool reserved2 : 1; -} nv3_coord_16_bigy_t; - -/* Generic 32-bit colour + 16-bit position */ -typedef struct nv3_color_and_coord_16_s -{ - nv3_color_expanded_t color; - nv3_coord_16_t points; -} nv3_color_and_coord_16_t; - -/* "UTRI" type triangle */ -typedef struct nv3_utri_s -{ - uint32_t color; // use nv3_color_expanded_t but changed for alignment reasons - nv3_coord_16_t point0; - nv3_coord_16_t point1; - nv3_coord_16_t point2; -} nv3_utri_t; - -/* Generic 16-bit clip region */ -typedef struct nv3_clip_16_s -{ - // The bounds of the clipping area. - uint16_t left; - uint16_t top; - uint16_t right; - uint16_t bottom; -} nv3_clip_16_t; - -/* In case your positions weren't HIGH PRECISION enough */ -typedef struct nv3_coord_32_s -{ - uint32_t x; - uint32_t y; -} nv3_coord_32_t; - -// COLOUR FORMATS - -/* - Object Class 0x01 (real hardware, also 0x41) - 0x12 (drivers) - Beta factor -*/ -typedef struct nv3_object_class_001 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; - uint32_t set_beta_factor_1d31; // 31:31 (?) value, 30:21 fraction - // Put the rest of it here -} nv3_beta_factor_t; - -/* - Object class 0x02 (real hardware) - 0x14/0x43 (drivers) - Also 0x42 in context IDs - Render operation used for things like blending. Appears to be 8-bit i.e. a ROP3 with 256 possible operations. -*/ -typedef struct nv3_object_class_002 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint8_t rop; // ROP3 (ID = ????????) -} nv3_render_operation_t; - -/* - Object class 0x03 (real hardware) - 0x15 (drivers) - Also 0x43 in context IDs - A chroma/color key, like in video editing -*/ -typedef struct nv3_object_class_003 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint32_t color; // ROP3 (ID = ????????) -} nv3_chroma_key_t; - -/* - Object class 0x04 (real hardware) - 0x15 (drivers) - Also 0x44 in context IDs - Plane mask -*/ -typedef struct nv3_object_class_004 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint32_t color; // Plane mask -} nv3_plane_mask_t; - -/* - Object class 0x05 (real hardware) - 0x19/0x1E/0x47 (drivers) - Also 0x45 in context IDs - Clipping rectangle used for various blitting operations -*/ -typedef struct nv3_object_class_005 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - - /* 16-bit precision */ - nv3_coord_16_t position; - nv3_coord_16_t size; - -} nv3_clipping_rectangle_t; - -/* - Object Class 0x06 (real hardware) - 0x?? (drivers) - Also 0x46 in context IDs - A pattern used for blits. Wahey! -*/ -typedef struct nv3_object_class_006 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint32_t shape; // 0 = 8x8, 1 = 64x1, 2 = 1x64 - uint32_t color0; // Some 32-bit format (argb?) - uint32_t color1; // bit0=color0, bit1=color1 - uint32_t pattern[2]; // bit0=color0, bit1=color1 -} nv3_pattern_t; - -/* - Object Class 0x07 (real hardware) - 0x1E (drivers) - Also 0x47 in context IDs - A rectangle. Wahey! -*/ -typedef struct nv3_object_class_007 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint32_t color; // The colour of the object. - nv3_coord_16_t position[16]; // The positions of up to 16 rectangles. - nv3_coord_16_t size[16]; // The sizes of up to 16 rectangles -} nv3_rectangle_t; - - -/* In case your points weren't colourful enough */ -typedef struct nv3_object_class_008_cpoint_s -{ - nv3_color_expanded_t color; // argb-format 32-bit color - nv3_coord_16_t position; // position -} nv3_object_class_008_cpoint_t; - -/* - Object Class 0x08 (real hardware) - 0x1A (drivers) - Also 0x48 in context IDs - A point: the revolutionary 3d graphics technique... -*/ -typedef struct nv3_object_class_008 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - nv3_color_expanded_t color; // argb? - nv3_coord_16_t point[16]; // Boring points - nv3_coord_32_t point32[16]; // Allows you to have points with full 32-bit precision - nv3_object_class_008_cpoint_t cpoint[16]; // Allows you to have c o l o r f u l points! -} nv3_point_t; - -/* Normal line... */ -typedef struct nv3_object_class_009_line_s -{ - nv3_coord_16_t start; // presumably unless it's in reverse order...TODO: check the order - nv3_coord_16_t end; - -} nv3_object_class_009_line_t; - -/* THIRTY TWO BIT PRECISION line */ -typedef struct nv3_object_class_009_line32_s -{ - uint32_t x0; - uint32_t x1; - uint32_t y0; - uint32_t y1; -} nv3_object_class_009_line32_t; - -/* nv3_object_class_009_polyline_t not implemented because it's just a duplicate of nv3_object_class_009_line */ -/* nv3_object_class_009_polyline32_t not implemented because it's just a duplicate of nv3_object_class_009_line32 */ - - -/* - Object Class 0x09 (real hardware) - 0x1B (drivers) - Also 0x49 in context IDs - It's a line, but also a polygon... -*/ -typedef struct nv3_object_class_009 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - nv3_color_expanded_t color; // argb? - nv3_object_class_009_line_t line[16]; // List of line points (...) - nv3_object_class_009_line32_t line32[8]; - nv3_object_class_009_line_t polyline[32]; - nv3_object_class_009_line32_t polyline32[16]; - nv3_color_and_coord_16_t cpolyline[16]; // List of line points and colours. -} nv3_line_t; - -/* - Object Class 0x0A (real hardware) - 0x1c (drivers) - Also 0x4a in context IDs - - This one is where nvidia reinvents the line, but without the starting or ending pixel. - Seriously. -*/ -typedef struct nv3_object_class_00A -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - - uint32_t set_notify; // Set notifier - - nv3_color_expanded_t color; // argb? - nv3_object_class_009_line_t line[16]; // List of line points (...) - nv3_object_class_009_line32_t line32[8]; - nv3_object_class_009_line_t polyline[32]; - nv3_object_class_009_line32_t polyline32[16]; - nv3_color_and_coord_16_t cpolyline[16]; // List of line points and colours. - -} nv3_lin_t; - -/* - Object Class 0x0B (real hardware) - 0x?? (drivers) - Also 0x4b in context IDs. - - This is a triangle but seems to be obsolete. It's replaced with UD3D0Z / D3D5 Accelerated Triangle with Zeta Buffer. Does it even exist? -*/ -typedef struct nv3_object_class_00B -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - nv3_color_expanded_t color; // argb? - // The points of the triangle. - nv3_coord_16_t points[3]; - - // Another way of filling out the points of the triangle - uint32_t x0; - uint32_t y0; - uint32_t x1; - uint32_t y1; - uint32_t x2; - uint32_t y2; - - nv3_coord_16_t mesh[32]; // Some kind of mesh format. I guess a list of vertex positions? - nv3_coord_32_t mesh32[16]; // Mesh with 32-bit format - nv3_utri_t ctriangle[8]; // Triangles with colour - nv3_color_and_coord_16_t ctrimesh[16]; // Some kind of mesh format. I guess a list of vertex positions? with colours - -} nv3_triangle_t; - -/* - Object Class 0x0C (real hardware) - 0x0C (drivers) - Also 0x4C in context IDs. - - GDI text acceleration for Windows 95. -*/ -typedef struct nv3_object_class_00C -{ - /* Unclipped rect (basically class 0x07 )*/ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint32_t color_a; // Color for Clip A - nv3_coord_16_t rect_a_position[64]; - nv3_coord_16_t rect_a_size[64]; - /* Clipped rect */ - nv3_clip_16_t clip_b; - uint32_t color_b; // Color for Clip B - nv3_clip_16_t clipped_rect[64]; - /* Unclipped transparent bitmap */ - nv3_clip_16_t clip_c; - uint32_t color1_c; - nv3_coord_16_t size_c; - nv3_coord_16_t point_c; - uint32_t bitmap_c[128]; - /* Clipped transparent bitmap */ - nv3_clip_16_t clip_d; - uint32_t color1_d; - nv3_coord_16_t size_in_d; - nv3_coord_16_t size_out_d; - nv3_coord_16_t point_d; - uint32_t bitmap_d[128]; - /* Clipped 1bpp bitmap */ - nv3_clip_16_t clip_e; - uint32_t color0_e; - uint32_t color1_e; - nv3_coord_16_t size_in_e; - nv3_coord_16_t size_out_e; - nv3_coord_16_t point_e; - uint32_t bitmap_e[128]; -} nv3_win95_text_t; - - -/* - Object Class 0x0D (real hardware) - 0x?? (drivers) - Also 0x4D in context IDs. - - Represents reformatting of an image in memory. -*/ -typedef struct nv3_object_class_00D -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint32_t offset_in; - uint32_t offset_out; - uint32_t pitch_in; - uint32_t pitch_out; - uint32_t scanline_length; // Stride? - uint32_t num_scanlines; - uint8_t format; // input increment 1 2 or 4, output increment 1 2 or 4 (represented by << 8) - uint32_t buffer_notify; // Notify the Buffedr -} nv3_memory_to_memory_format_t; - -/* - Object Class 0x0E (real hardware) - 0x?? (drivers) - Also 0x4E in context IDs. - - Represents a scaled image coming from memory. -*/ -typedef struct nv3_object_class_00E -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; - uint32_t set_notify; - nv3_coord_16_t clip_0; - nv3_coord_16_t clip_1; - nv3_coord_16_t rectangle_out_0; - nv3_coord_16_t rectangle_out_1; - // Calculus in a graphics card - uint32_t delta_du_dx; - uint32_t delta_dv_dy; - nv3_coord_16_t size; // can be size_y if YUV420 - uint32_t pitch; - uint32_t offset; - uint32_t point; - // YUV420 stuff - uint32_t pitch_yuv420; - uint32_t offset_y; - uint32_t offset_u; - uint32_t offset_v; - uint32_t point_yuv420; -} nv3_scaled_image_from_memory_t; - -// (0x0F does not exist) - -/* - Object Class 0x10 (real hardware) - 0x?? (drivers) - Also 0x50 in context IDs. - - Represents a screen to screen blit. I'm still figuring it out. -*/ - -typedef struct nv3_object_class_010 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; - uint32_t set_notify; - nv3_coord_16_t point_in; - nv3_coord_16_t point_out; - nv3_coord_16_t size; -} nv3_blit_t; - -/* - Object Class 0x11 (real hardware) - 0x?? (drivers) - Also 0x51 in context IDs. - - Represents an image from the cpu (i guess from system memory) -*/ -typedef struct nv3_object_class_011 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; - uint32_t set_notify; - nv3_coord_16_t point; - nv3_coord_16_t size; - nv3_coord_16_t size_in; - nv3_color_expanded_t color[32]; // The colour to use -} nv3_image_t; - -/* - Object Class 0x12 (real hardware) - 0x?? (drivers) - Also 0x52 in context IDs. - - Bitmap from CPU. - It seems the difference is that an image is colour but a -*/ -typedef struct nv3_object_class_012 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; - uint32_t set_notify; - nv3_color_expanded_t color_0; - nv3_color_expanded_t color_1; - nv3_coord_16_t point; // Top left(?) of the bitmap - nv3_coord_16_t size; - nv3_coord_16_t size_in; - uint32_t monochrome_bitmap[32]; -} nv3_bitmap_t; - -// 0x13 doesn't exist - -/* - Object Class 0x14 (real hardware) - 0x?? (drivers) - Also 0x54 in context IDs. - - Image Transfer to Memory - It seems the difference is that an image is colour but a bitmap is b&w -*/ -typedef struct nv3_object_class_014 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; - uint32_t set_notify; - nv3_coord_16_t point; - nv3_coord_16_t size; - uint32_t image_pitch; // bytes per row - uint32_t image_start; -} nv3_image_to_memory_t; - -/* - Object Class 0x15 (real hardware) - 0x?? (drivers) - Also 0x55 in context IDs. - - Stretched Image from CPU - Seems to be, by the very large color array, the main class used in 2d acceleration. -*/ -typedef struct nv3_object_class_015 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; - uint32_t set_notify; - nv3_coord_16_t size_in; - uint32_t delta_dx_du; - uint32_t delta_dy_dv; - nv3_coord_16_t clip_0; - nv3_coord_16_t clip_1; - uint32_t point12d4; /* todo: fraction struct */ - // no reserve needed -} nv3_stretched_image_from_cpu_t; - -// 0x16 invalid - -/* - Object Class 0x17 (real hardware) - 0x?? (drivers) - Also 0x57 in context IDs. - - Direct3D 5.0 accelerated triangle with zeta buffer (combined z buffer and stencil buffer) - This is the final boss of this GPU. True horror stands below. -*/ - -// -// NV3 D3D5: TEXTURING & PIXEL FORMATS -// - -typedef enum nv3_d3d5_texture_pixel_format_e -{ - /* - 16-Bit Pixel Format - 5 bits red, 5 bits green, 5 bits alpha, "boolean" alpha - */ - nv3_d3d5_pixel_format_le_a1r5g5b5 = 0, - - /* - 15-Bit Pixel Format (represented as 16) - 1 bit irrelevant, 5 bits red, 5 bits green, 5 bits alpha - */ - nv3_d3d5_pixel_format_le_x1r5g5b5 = 1, - - /* - 16-Bit Pixel Format - 4 bits alpha, 4 bits red, 4 bits green, 4 bits blue - */ - nv3_d3d5_pixel_format_le_a4r4g4b4 = 2, - - /* - 16-Bit Pixel Format - 5 bits red, 6 bits green, 5 bits blue - (Required nv3tweak...) - */ - nv3_d3d5_pixel_format_le_r5g6b5 = 3, - -} nv3_d3d5_texture_pixel_format; - -/* Output format - - The output pixel format...I -*/ -typedef enum nv3_d3d5_output_pixel_format_e -{ - /* - 32-Bit Pixel Format - 8 bits irrelevant, 8 bits red, 8 bits green, 8 bits blue - */ - nv3_d3d5_output_pixel_format_le_x8r8g8b8 = 0, - - /* - 32-Bit Pixel Format - 8 bits irrelevant, 8 bits red, 8 bits green, 8 bits blue - Is this even used?? The riva can't even do 32 bit colour in 3d... - */ - nv3_d3d5_output_pixel_format_le_a8r8g8b8 = 1, - - -} nv3_d3d5_output_pixel_format; - - -/* Texture size - - NOTE: ONLY 256X256 OR LOWER ARE SUPPORTED! 2048X2048X16 TAKES UP ENTIRE VRAM OF RIVA 128 ZX... - I ASSUME THESE ARE INTERNALLY SCALED DOWN -*/ -typedef enum nv3_d3d5_texture_size_e -{ - nv3_d3d5_texture_size_1x1 = 0, - - nv3_d3d5_texture_size_2x2 = 1, - - nv3_d3d5_texture_size_4x4 = 2, - - nv3_d3d5_texture_size_8x8 = 3, - - nv3_d3d5_texture_size_16x16 = 4, - - nv3_d3d5_texture_size_32x32 = 5, - - nv3_d3d5_texture_size_64x64 = 6, - - nv3_d3d5_texture_size_128x128 = 7, - - nv3_d3d5_texture_size_256x256 = 8, - - nv3_d3d5_texture_size_512x512 = 9, - - nv3_d3d5_texture_size_1024x1024 = 10, - - // Kind of infeasible considering hardware VRAM size limitations - nv3_d3d5_texture_size_2048x2048 = 11, - - -} nv3_d3d5_texture_size; - -/* Texture Wrapping Mode for U/V Coordinate Overflow - -*/ -typedef enum nv3_d3d5_texture_wrap_mode_e -{ - // Map textures in a cylindrical fashion. - nv3_d3d5_texture_wrap_mode_cylindrical = 0, - - // Simply wrap back to the start. - nv3_d3d5_texture_wrap_mode_wrap = 1, - - // Mirror the texture. - nv3_d3d5_texture_wrap_mode_mirror = 2, - - // Clamp to the last border pixel. - nv3_d3d5_texture_wrap_mode_clamp = 3, -} nv3_d3d5_texture_wrap_mode; - - -/* This is blending but isn't really considered to be it in the GPU for some reason - What do we do with out input texel BEFORE processing it? - */ -typedef enum nv3_d3d5_dest_color_interpretation_e -{ - // Do nothing - nv3_d3d5_source_color_normal = 0, - - // Invert Colour - nv3_d3d5_source_color_inverse = 1, - - // Invert Alpha before Processing - nv3_d3d5_source_color_alpha_inverse = 2, - - // Take Alpha as 1 - nv3_d3d5_source_color_alpha_one = 3, - -} nv3_d3d5_dest_color_interpretation; - -// The full texture format structure -typedef struct nv3_d3d5_texture_format_s -{ - uint16_t color_key_color_mask; - bool color_key_enabled : 1; - nv3_d3d5_texture_pixel_format color_format : 2; - nv3_d3d5_texture_size size_min : 4; - nv3_d3d5_texture_size size_max : 4; -} nv3_d3d5_texture_format_t; - -// -// NV3 D3D5: INTERPOLATION -// - -/* - ?????? - Interpolating between mip levels? (or for texture blending) -*/ -typedef enum nv3_d3d5_interpolator_algorithm_e -{ - // Zero-order hold interpolation? - nv3_d3d5_interpolator_zoh = 0, - - // Zero-order hold (microsoft variant)? - nv3_d3d5_interpolator_zoh_ms = 1, - - // Full-order hold interpolation? - nv3_d3d5_interpolator_foh = 2, - -} nv3_d3d5_interpolator_algorithm; - -// -// NV3 D3D5: Z-BUFFER -// - -/* Probably the sorting algorithm */ -typedef enum nv3_d3d5_zbuffer_type_e -{ - // Sort based on linear distance - nv3_d3d5_zbuffer_linear = 0, - - // Sort based on distance from view frustum - nv3_d3d5_zbuffer_screen = 1, - -} nv3_d3d5_zbuffer_type; - -// NV3 D3D5: WRITE CONTROL (SHARED BETWEEN ZETA BUFFER AND ALPHA) -typedef enum nv3_d3d5_buffer_write_control_e -{ - // Never write. - nv3_d3d5_buffer_write_control_never = 0, - - // Only write the alpha. - nv3_d3d5_buffer_write_control_alpha = 1, - - // Write both alpha and the zeta-buffer. - nv3_d3d5_buffer_write_control_alpha_zeta = 2, - - // Write only the zeta-buffer - nv3_d3d5_buffer_write_control_zeta = 3, - - // Write everything (alpha+z+zeta?) - nv3_d3d5_buffer_write_control_always = 4, - - -} nv3_d3d5_buffer_write_control; - -// -// NV3 D3D5: BUFFER COMPARISON (SHARED BETWEEN ZETA BUFFER AND ALPHA CONTROL) -// - -// Todo: Which direction? (i.e. is less than p1 < p2 or p2 < p1!) -typedef enum nv3_d3d5_buffer_comparison_type_e -{ - // !!!ILLEGAL COMPARISON TYPE!!!! - nv3_d3d5_buffer_comparison_illegal = 0, - - // The (depth?) test always fails. - nv3_d3d5_buffer_comparison_always_false = 1, - - // True if less than fail. - nv3_d3d5_buffer_comparison_less_than = 2, - - // The test succeeds if equal. - nv3_d3d5_buffer_comparison_equal = 3, - - // The test succeeds if less or equal. - nv3_d3d5_buffer_comparison_less_or_equal = 4, - - // The test succeeds if greater. - nv3_d3d5_buffer_comparison_greater = 5, - - // The test succeeds if the two elements are equal. - nv3_d3d5_buffer_comparison_not_equal = 6, - - // The test succeeds if greater or equal - nv3_d3d5_buffer_comparison_greater_or_equal = 7, - - // The test always succeeds. - nv3_d3d5_buffer_comparison_always_true = 8, - -} nv3_d3d5_buffer_comparison_type; - -// -// NV3 D3D5: BLENDING -// - -/* Render Operation for Blending */ -typedef enum nv3_d3d5_blend_render_operation_e -{ - nv3_d3d5_blend_render_operation_and = 0, - - nv3_d3d5_blend_add_with_saturation = 1, - -} nv3_d3d5_blend_render_operation; - -typedef enum nv3_d3d5_blend_beta_factor_e -{ - nv3_d3d5_blend_beta_factor_srcalpha = 0, - - nv3_d3d5_blend_beta_factor_zero = 1, - -} nv3_d3d5_blend_beta_factor; - -typedef enum nv3_d3d5_blend_input0_e -{ - nv3_d3d5_blend_input0_srcalpha = 0, - - nv3_d3d5_blend_input0_zero = 1, - -} nv3_d3d5_blend_input0; - -typedef enum nv3_d3d5_blend_input1_e -{ - nv3_d3d5_blend_input1_destalpha = 0, - - nv3_d3d5_blend_input1_zero = 1, - -} nv3_d3d5_blend_input1; - -// -// NV3 D3D5: CULLING -// - -typedef enum nv3_d3d5_culling_algorithm_e -{ - // Don't cull - nv3_d3d5_culling_algorithm_none = 0, - - // Cull Clockwise around view frustum? - nv3_d3d5_culling_algorithm_clockwise = 1, - - // Cull counterclockwise around view frustum? - nv3_d3d5_culling_algorithm_counterclockwise = 2, - -} nv3_d3d5_culling_algorithm; - -/* Specular reflection parameters */ -typedef struct nv3_d3d5_specular_s -{ - uint8_t i0 : 4; - uint8_t i1 : 4; - uint8_t i2 : 4; - uint8_t i3 : 4; - uint8_t i4 : 4; - uint8_t i5 : 4; - uint8_t fog; //table fog emulation? -} nv3_d3d5_specular_t; - -// -// NV3 D3D5: MISC -// -typedef struct nv3_d3d5_texture_filter_s -{ - uint8_t spread_x; - uint8_t spread_y; - uint8_t mipmap; - uint8_t turbo; -} nv3_d3d5_texture_filter_t; - -// -// NV3 D3D5: OUTPUT CONTROL STRUCTURE -// - -/* Output Control for D3D5 Triangles */ -typedef struct nv3_d3d5_control_out_s -{ - nv3_d3d5_interpolator_algorithm ctrl_out_interpolator : 2; - uint8_t reserved : 2; - nv3_d3d5_texture_wrap_mode wrap_u : 2; // Controls wrapping mode of U texture coordinate - nv3_d3d5_texture_wrap_mode wrap_v : 2; // Controls wrapping move of V texture coordinate - nv3_d3d5_output_pixel_format output_pixel_format : 1; - bool reserved2 : 1; - nv3_d3d5_dest_color_interpretation dest_color_interpretation : 2; - nv3_d3d5_culling_algorithm culling_algorithm : 2; - bool reserved3 : 1; - nv3_d3d5_zbuffer_type zbuffer_type : 1; - nv3_d3d5_buffer_comparison_type zeta_buffer_compare : 4; - nv3_d3d5_buffer_write_control zeta_write : 3; - bool reserved4 : 1; - nv3_d3d5_buffer_write_control color_write : 3; - bool reserved5 : 1; - nv3_d3d5_blend_render_operation blend_rop : 1; - nv3_d3d5_blend_input0 blend_input0 : 1; - nv3_d3d5_blend_input1 blend_input1 : 1; -} nv3_d3d5_control_out_t; - -typedef struct nv3_d3d5_alpha_control_s -{ - uint8_t alpha_key; - nv3_d3d5_buffer_comparison_type zeta_buffer_compare : 4; - uint32_t reserved : 20; -} nv3_d3d5_alpha_control_t; - -// -// NV3 D3D5: Triangle Coordinates -// -typedef struct nv3_d3d5_coordinate_s -{ - nv3_d3d5_specular_t specular_reflection_parameters; - nv3_color_expanded_t color; // YOU HAVE TO FLIP THE ENDIANNESS. NVIDIA??? WHAT??? - - // Seems more plausible for these specifically to be floats. - // Also makes my life easier... - float x; // X coordinate in 3d space of the triangle - float y; // Y coordinate in 3d space of the triangle - float z; // Z coordinate in 3d space of the triangle - float m; // 1/W for projection - float u; // U coordinate within texture for the (top left?) of the triangle where sampling starts. - float v; // V coordinate within texture for the (top left?) of the triangle where sampling starts. -} nv3_d3d5_coordinate_t; - -typedef struct nv3_object_class_017 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - uint32_t texture_offset; - nv3_d3d5_texture_format_t texture_format; - nv3_d3d5_texture_filter_t texture_filter; - nv3_color_expanded_t fog_color; // Alpha is ignored here! - nv3_d3d5_control_out_t control_out; - nv3_d3d5_alpha_control_t alpha_control; - - nv3_d3d5_coordinate_t coordinate_points[128]; // The points we are rendering. - /* No placeholder needed, it really is that long. */ -} nv3_d3d5_accelerated_triangle_with_zeta_buffer_t; - - -// Color and Zeta Buffer algorithm -typedef struct nv3_zeta_buffer_s -{ - nv3_color_expanded_t color; - uint32_t zeta; // 16 bits z, 8 bits stenciul -} nv3_zeta_buffer_t; - -typedef struct nv3_object_class_018 -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; - uint32_t set_notify; - nv3_d3d5_control_out_t control_out; - nv3_d3d5_alpha_control_t alpha_control; - nv3_coord_16_t point; - nv3_zeta_buffer_t zeta[8]; -} nv3_point_with_zeta_buffer_t; - -/* 0x19, 0x1A, 0x1B don't exist */ - -/* WHY IS THE FORMAT DIFFERENT TO THE REST OF THE GPU? - They are making it look like a bitfield but it's hex? - - THEY ARE ALL LITTLE ENDIAN -*/ -typedef enum nv3_object_class_01C_pixel_format_e -{ - // Y8P4 - // 12-bits (Y8 - Planar YUV 8 bits (Y value only), 4 bits of indexed colour too? - nv3_image_in_memory_pixel_format_le_y8_p4 = 0x1010000, - - // Y16P2 - // 16-bits (Y16) - Planar YUV 16 bits (Y value only), 2 bits of indexed colour too? - nv3_image_in_memory_pixel_format_le_y16_p2 = 0x1010101, - - /* 1 unused bit, 555 15-bit format, p2(?) */ - nv3_image_in_memory_pixel_format_x1r5g5b5_p2 = 0x1000000, - - // X8G8B8R8, 24-bit colour (or 24-bit colour with alpha) - nv3_image_in_memory_pixel_format_x8g8b8r8 = 0x1, -} nv3_object_class_01C_pixel_format; - -typedef struct nv3_object_class_01C -{ - nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch) - uint32_t set_notify; // Set notifier - nv3_object_class_01C_pixel_format format; // Completely different from everything else - uint32_t pitch; // 16-bit - uint32_t linear_address; // 22-bit: Linear address in vram. -} nv3_image_in_memory_t; - -// See envytools. This is where we finally end up after this mess, it allows parameters to be passed to the methods. -typedef struct nv3_grobj_s -{ - uint32_t grobj_0; - uint32_t grobj_1; - uint32_t grobj_2; - uint32_t grobj_3; -} nv3_grobj_t; -// TODO: PATCHCORDS!!!! TO LINK ALL OF THIS TOGETHER!!! - -// PIO Subchannel info -#define NV3_SUBCHANNEL_PIO_IS_PFIFO_FREE 0x0010 -#define NV3_SUBCHANNEL_PIO_ALWAYS_ZERO_START 0x0012 -#define NV3_SUBCHANNEL_PIO_ALWAYS_ZERO_END 0x0017 \ No newline at end of file diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h deleted file mode 100644 index cca3761be..000000000 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 headers for rendering - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#pragma once - -/* Core */ -void nv3_render_current_bpp(); -void nv3_render_current_bpp_dfb_8(uint32_t address); -void nv3_render_current_bpp_dfb_16(uint32_t address); -void nv3_render_current_bpp_dfb_32(uint32_t address); - -/* Pixel */ -void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t grobj); -uint8_t nv3_render_read_pixel_8(nv3_coord_16_t position, nv3_grobj_t grobj); -uint16_t nv3_render_read_pixel_16(nv3_coord_16_t position, nv3_grobj_t grobj); -uint32_t nv3_render_read_pixel_32(nv3_coord_16_t position, nv3_grobj_t grobj); - -/* Address */ -uint32_t nv3_render_get_vram_address(nv3_coord_16_t position, nv3_grobj_t grobj); -uint32_t nv3_render_get_vram_address_for_buffer(nv3_coord_16_t position, uint32_t buffer); - -/* Colour Conversion */ -uint32_t nv3_render_get_palette_index(uint8_t index); // Get a colour for a palette index. (The colours are 24 bit RGB888 with a 0xFF alpha added for some purposes.) -uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded); // Convert a colour to A1R10G10B10 for chroma key purposes. -nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj); // Convert a colour to full RGB10 format from the current working format. -uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t color); // Convert a colour from the current working format to RGB10 format. - -/* ROP */ -uint8_t nv3_render_translate_nvrop(nv3_grobj_t grobj, uint32_t rop); - -/* Pattern */ -void nv3_render_set_pattern_color(nv3_color_expanded_t pattern_colour, bool use_color1); - -/* Primitives */ -void nv3_render_rect(nv3_coord_16_t position, nv3_coord_16_t size, uint32_t color, nv3_grobj_t grobj); // Render an A (unclipped) GDI rect -void nv3_render_rect_clipped(nv3_clip_16_t clip, uint32_t color, nv3_grobj_t grobj); // Render a B (clipped) GDI rect. - -/* Chroma */ -bool nv3_render_chroma_test(uint32_t color, nv3_grobj_t grobj); - -/* Blit */ -void nv3_render_blit_image(uint32_t color, nv3_grobj_t grobj); -void nv3_render_blit_screen2screen(nv3_grobj_t grobj); - -/* GDI */ -void nv3_render_gdi_transparent_bitmap(bool clip, uint32_t color, uint32_t bitmap_data, nv3_grobj_t grobj); -void nv3_render_gdi_1bpp_bitmap(uint32_t color0, uint32_t color1, uint32_t bitmap_data, nv3_grobj_t grobj); /* GDI Type-E: Clipped 1bpp colour-expanded bitmap */ - -/* DMA */ -void nv3_perform_dma_m2mf(nv3_grobj_t grobj); \ No newline at end of file diff --git a/src/include/86box/nv/vid_nv.h b/src/include/86box/nv/vid_nv.h deleted file mode 100644 index 83f94c167..000000000 --- a/src/include/86box/nv/vid_nv.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * The real Nvidia driver. - * Implements components shared by all variants of the Nvidia GPUs (hopefully to be) supported by 86Box. - * - * This driver draws on collaborative work by many people over many years. - * - * Credit to: - * - * - Marcelina KoÅ›cielnicka (envytools) https://envytools.readthedocs.io/en/latest/ - * - fuel (PCBox developer) https://github.com/PCBox/PCBox - * - nouveau developers https://nouveau.freedesktop.org/ - * - Utah GLX developers https://utah-glx.sourceforge.net/ - * - XFree86 developers https://www.xfree86.org/ - * - xemu developers https://github.com/xemu-project/xemu - * - RivaTV developers https://rivatv.sourceforge.net (esp. https://rivatv.sourceforge.net/stuff/riva128.txt) - * - Nvidia for leaking their driver symbols numerous times ;^) https://nvidia.com - * - Vort (Bochs GeForce fork) https://github.com/Vort/Bochs/tree/geforce - * - People who prevented me from giving up (various) - * - * Authors: Connor Hyde / starfrost - * - * Copyright 2024-2025 Connor Hyde - */ -#ifdef EMU_DEVICE_H // what - -//TODO: split this all into nv1, nv3, nv4... -#include <86box/log.h> -#include <86box/i2c.h> -#include <86box/vid_ddc.h> -#include <86box/timer.h> -#include <86box/vid_svga.h> -#include <86box/vid_svga_render.h> -#include <86box/nv/vid_nv_rivatimer.h> - -void nv_log_set_device(void* device); -void nv_log(const char *fmt, ...); - -// Verbose logging level. -void nv_log_verbose_only(const char *fmt, ...); - -// Defines common to all NV chip architectural generations - -// PCI IDs -#define PCI_VENDOR_NV 0x10DE // NVidia PCI ID -#define PCI_VENDOR_SGS 0x104A // SGS-Thompson -#define PCI_VENDOR_SGS_NV 0x12D2 // SGS-Thompson/NVidia joint venture - -#define NV_PCI_NUM_CFG_REGS 256 // number of pci config registers - -// 0x0000 was probably the NV0 'Nvidia Hardware Simulator' -#define NV_PCI_DEVICE_NV1 0x0008 // Nvidia NV1 -#define NV_PCI_DEVICE_NV1_VGA 0x0009 // Nvidia NV1 VGA core -#define NV_PCI_DEVICE_NV2 0x0010 // Nvidia NV2 / Mutara V08 (cancelled) -#define NV_PCI_DEVICE_NV3 0x0018 // Nvidia NV3 (Riva 128) -#define NV_PCI_DEVICE_NV3T 0x0019 // Nvidia NV3T (Riva 128 ZX) -#define NV_PCI_DEVICE_NV4 0x0020 // Nvidia NV4 (RIVA TNT) - -#define NV_CHIP_REVISION_NV1_A0 0x0000 // 1994 -#define NV_CHIP_REVISION_NV1_B0 0x0010 // 1995 -#define NV_CHIP_REVISION_NV1_C0 0x0020 // 1995-96? - -#define NV_CHIP_REVISION_NV3_A0 0x0000 // January 1997 -#define NV_CHIP_REVISION_NV3_B0 0x0010 // October 1997 -#define NV_CHIP_REVISION_NV3_C0 0x0020 // 1998 - -// Architecture IDs -#define NV_ARCHITECTURE_NV1 1 // NV1/STG2000 -#define NV_ARCHITECTURE_NV2 2 // Nvidia 'Mutara V08' -#define NV_ARCHITECTURE_NV3 3 // Riva 128 -#define NV_ARCHITECTURE_NV4 4 // Riva TNT and later - -#define NV_MAX_BUF_SIZE_X 1920 // Maximum buffer size, X -#define NV_MAX_BUF_SIZE_Y 1200 // Maximum buffer size, Y - -typedef enum nv_bus_generation_e -{ - // NV1 - Prototype version - nv_bus_vlb = 0, - - // NV1 - // NV3 - nv_bus_pci = 1, - - // NV3 - nv_bus_agp_1x = 2, - - // NV3T - // NV4 - nv_bus_agp_2x = 3, - -} nv_bus_generation; - -// PCI configuration -typedef struct nv_pci_config_s -{ - uint8_t pci_regs[NV_PCI_NUM_CFG_REGS]; // The actual pci register values (not really used, just so they can be stored - they aren't very good for code readability) - bool vbios_enabled; // is the vbios enabled? - uint8_t int_line; -} nv_pci_config_t; - -// NV Base -typedef struct nv_base_s -{ - rom_t vbios; // NVIDIA/OEm VBIOS - nv_pci_config_t pci_config; // PCI configuration - // move to nv3_cio_t? - svga_t svga; // SVGA core (separate to nv3) - Weitek licensed - uint32_t vram_amount; // The amount of VRAM - void* log; // new logging engine - // stuff that doesn't fit in the svga structure - uint32_t cio_read_bank; // SVGA read bank - uint32_t cio_write_bank; // SVGA write bank - - mem_mapping_t framebuffer_mapping; // Linear Framebuffer / NV_USER memory mapping - mem_mapping_t mmio_mapping; // mmio mapping (32MB unified MMIO) - mem_mapping_t framebuffer_mapping_mirror; // Mirror of LFB mapping - mem_mapping_t ramin_mapping; // RAM INput area mapping - mem_mapping_t ramin_mapping_mirror; // RAM INput area mapping (mirrored) - NV3 ONLY - uint8_t pci_slot; // pci slot number - uint8_t pci_irq_state; // current PCI irq state - uint32_t bar0_mmio_base; // PCI Base Address Register 0 - MMIO Base - uint32_t bar1_lfb_base; // PCI Base Address Register 1 - Linear Framebuffer (NV_BASE) - nv_bus_generation bus_generation; // current bus (see nv_bus_generation documentation) - uint32_t gpu_revision; // GPU Stepping - double pixel_clock_frequency; // Frequency used for pixel clock# - double refresh_time; // Rough estimation of refresh rate, for when we can present the screen - double refresh_clock; // Time since the last refresh - rivatimer_t* pixel_clock_timer; // Timer for measuring pixel clock - bool pixel_clock_enabled; // Pixel Clock Enabled - stupid crap used to prevent us enabling the timer multiple times - double memory_clock_frequency; // Source Frequency for PTIMER - rivatimer_t* memory_clock_timer; // Timer for measuring memory/gpu clock - - // VCLK / NVCLK do not have timers set here. - pc_timer_t* nv4_vclk_timer; // NV4+ MCLK (Video RAM) timer - - bool memory_clock_enabled; // Memory Clock Enabled - stupid crap used to prevent us eanbling the timer multiple times - void* i2c; // I2C for monitor EDID - void* ddc; // Display Data Channel for EDID - bool agp_enabled; // AGP Enabled (for debugging) - bool agp_sba_enabled; // AGP Sideband Addressing enabled - - // - // DEBUG UI STUFF - // - bool debug_dba_enabled; // Debug DBA override - uint32_t debug_dba; // Debug DBA -} nv_base_t; - -#define NV_REG_LIST_END 0xD15EA5E - -// The NV architectures are very complex. -// There are hundreds of registers at minimum, and implementing these in a standard way would lead to -// unbelievably large switch statements and horrifically unreadable code. -// So this is used to abstract it and allow for more readable code. -// This is mostly just used for logging and stuff. -// Optionally, you can provide a function that is run when you read to and write from the register. -// You can also implement this functionality in a traditional way such as a switch statement, for simpler registers. To do this, simply set both read and write functions to NULL. -// Typically, unless they are for a special purpose (and handled specially) e.g. vga all register reads and writes are also 32-bit aligned -typedef struct nv_register_s -{ - int32_t address; // MMIO Address - char* friendly_name; // Friendly name - // reg_ptr not needed as a parameter, because we implicitly know which register si being tiwddled - uint32_t (*on_read)(void); // Optional on-read function - void (*on_write)(uint32_t value); // Optional on-write fucntion -} nv_register_t; - -nv_register_t* nv_get_register(uint32_t address, nv_register_t* register_list, uint32_t num_regs); - - -#endif \ No newline at end of file diff --git a/src/include/86box/nv/vid_nv1.h b/src/include/86box/nv/vid_nv1.h deleted file mode 100644 index be6895c8b..000000000 --- a/src/include/86box/nv/vid_nv1.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Quadratic Heaven - * - * Authors: Connor Hyde - * - * Copyright 2024-2025 Connor Hyde - */ - -#pragma once - -#include -#include - -extern const device_config_t nv1_config[]; // Config for RIVA 128 (revision A/B) - -// -// PCI Bus Information -// - -#define NV1_PCI_BAR0_SIZE 0xFFFFFF - -// -// VRAM -// -#define NV1_VRAM_SIZE_1MB 0x100000 -#define NV1_VRAM_SIZE_2MB 0x200000 -#define NV1_VRAM_SIZE_4MB 0x400000 - -// Video BIOS -#define NV1_VBIOS_E3D_2X00 "roms/video/nvidia/nv1/Diamond_Edge_3D_2x00.BIN" -#define NV1_VBIOS_E3D_3X00 "roms/video/nvidia/nv1/Diamond_Edge_3D_3400_BIOS_M27C256.BIN" - -// -// PMC -// -#define NV1_PMC_BOOT_0 0x0 -#define NV1_PMC_BOOT_0_REVISION 0 - -#define NV1_PMC_BOOT_0_REVISION_A 0x0 // Prototype (1994) -#define NV1_PMC_BOOT_0_REVISION_B1 0x0 // Prototype (early 1995) -#define NV1_PMC_BOOT_0_REVISION_B2 0x0 // Prototype (mid 1995) -#define NV1_PMC_BOOT_0_REVISION_B3 0x0 // Final? -#define NV1_PMC_BOOT_0_REVISION_C 0x0 // Final? - -#define NV1_PMC_BOOT_0_IMPLEMENTATION 8 -#define NV1_PMC_BOOT_0_IMPLEMENTATION_NV0 0x1 // Nvidia Hardware Simulator (1993-1994) -#define NV1_PMC_BOOT_0_IMPLEMENTATION_NV1_D32 0x2 // NV1 + DRAM + SGS-Thomson STG-1732/1764 DAC -#define NV1_PMC_BOOT_0_IMPLEMENTATION_NV1_V32 0x3 // NV1 + VRAM + SGS-Thomson STG-1732/1764 DAC -#define NV1_PMC_BOOT_0_IMPLEMENTATION_PICASSO 0x4 // NV1 + VRAM + NV 128-bit DAC - - -// Defines the NV architecture version (NV1/NV2/...) -#define NV1_PMC_BOOT_0_ARCHITECTURE 16 -#define NV1_PMC_BOOT_0_ARCHITECTURE_NV0 0x0 // Nvidia Hardware Simulator (1993-1994) -#define NV1_PMC_BOOT_0_ARCHITECTURE_NV1 0x1 // NV1 (1995) -#define NV1_PMC_BOOT_0_ARCHITECTURE_NV2 0x2 // Mutara (1996, cancelled) - -#define NV1_PMC_DEBUG_0 0x80 - -#define NV1_PMC_INTR_0 0x100 -#define NV1_PMC_INTR_EN_0 0x140 - -#define NV1_PMC_INTR_EN_0_INTA 0 -#define NV1_PMC_INTR_EN_0_INTB 4 -#define NV1_PMC_INTR_EN_0_INTC 8 -#define NV1_PMC_INTR_EN_0_INTD 12 - -#define NV1_PMC_INTR_EN_0_DISABLED 0x0 -#define NV1_PMC_INTR_EN_0_HARDWARE 0x1 -#define NV1_PMC_INTR_EN_0_SOFTWARE 0x2 -#define NV1_PMC_INTR_EN_0_ALL 0x3 // (HARDWARE | SOFTWARE) - -#define NV1_PMC_INTR_READ 0x160 - -//TODO: DEFINE bits -#define NV1_PMC_ENABLE 0x200 - -// -// PRAMIN -// - -#define NV1_RAMIN_START 0x100000 - -// -// PAUTH -// Scary nvidia mode -// - -// Read only -#define NV1_PAUTH_DEBUG_0 0x605080 -#define NV1_PAUTH_DEBUG_0_BREACH_DETECTED 0 -#define NV1_PAUTH_DEBUG_0_EEPROM_INVALID 4 - -#define NV1_PAUTH_CHIP_TOKEN_0 0x605400 -#define NV1_PAUTH_CHIP_TOKEN_1 0x605404 -#define NV1_PAUTH_PASSWORD_0(i) 0x605800+(i*16) -#define NV1_PAUTH_PASSWORD_1(i) 0x605804+(i*16) -#define NV1_PAUTH_PASSWORD_2(i) 0x605808+(i*16) -#define NV1_PAUTH_PASSWORD_3(i) 0x60580C+(i*16) - -#define NV1_PAUTH_PASSWORD_SIZE 128 - -// -// PFB -// - -#define NV1_PFB_BOOT_0 0x600000 - -#define NV1_PFB_BOOT_0_RAM_AMOUNT 0 -#define NV1_PFB_BOOT_0_RAM_AMOUNT_1MB 0x0 -#define NV1_PFB_BOOT_0_RAM_AMOUNT_2MB 0x1 -#define NV1_PFB_BOOT_0_RAM_AMOUNT_4MB 0x2 - -// -// PEXTDEV -// - -#define NV1_STRAPS 0x608000 -#define NV1_STRAPS_STRAP_VENDOR 0 - -// -// PRAM+RAMIN -// - -#define NV1_PRAM_CONFIG 0x602200 -#define NV1_PRAM_CONFIG_SIZE 0 -#define NV1_PRAM_CONFIG_12KB 0 -#define NV1_PRAM_CONFIG_20KB 1 -#define NV1_PRAM_CONFIG_36KB 2 -#define NV1_PRAM_CONFIG_68KB 3 - -// Position of RAMPW in RAMIN -#define NV1_RAMPW_POSITION_CONFIG0 0x2c00 -#define NV1_RAMPW_POSITION_CONFIG1 0x4c00 -#define NV1_RAMPW_POSITION_CONFIG2 0x8c00 -#define NV1_RAMPW_POSITION_CONFIG3 0x10c00 - -// Static RAMPW mirror -#define NV1_PRAMPW 0x606000 -#define NV1_RAMPW_SIZE 0x400 - -// -// PROM -// -#define NV1_PROM 0x601000 -#define NV1_PROM_SIZE 32768 - -// Structures -typedef struct nv1_s -{ - nv_base_t nvbase; // Base Nvidia structure -} nv1_t; - -// Device Core -void nv1_init(); -void nv1_close(void* priv); -void nv1_speed_changed(void *priv); -void nv1_draw_cursor(svga_t* svga, int32_t drawline); -void nv1_recalc_timings(svga_t* svga); -void nv1_force_redraw(void* priv); \ No newline at end of file diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h deleted file mode 100644 index 3726ecc03..000000000 --- a/src/include/86box/nv/vid_nv3.h +++ /dev/null @@ -1,1764 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Welcome to what happens when a single person demands that their overly complicated "vision" of a design be implemented - * with absolutely no compromise. This is true lunacy. - * - * Explanation of what is being done here, and how this all works, hopefully posted on the 86Box blog. - * Notes specific to a subsystem in the header or c file for that subsystem - * Also check the doc folder for some more notres - * - * vid_nv3.h: NV3 Architecture Hardware Reference (open-source) - * Last updated: 12 April 2025 (STILL WORKING ON IT!!!) - * - * Authors: Connor Hyde - * - * Copyright 2024-2025 Connor Hyde - */ - -#pragma once -#include <86box/nv/classes/vid_nv3_classes.h> -#include <86box/nv/render/vid_nv3_render.h> - -// The GPU base structure -extern const device_config_t nv3_config[]; // Config for RIVA 128 (revision A/B) -extern const device_config_t nv3t_config[]; // Config for RIVA 128 ZX (revision C) - -#define NV3_MMIO_SIZE 0x1000000 // Max MMIO size - -#define NV3_LFB_RAMIN_MIRROR_START 0x400000 // Mirror of ramin (VERIFY ON HARDWARE) -#define NV3_LFB_MIRROR_START 0x800000 // The second half of LFB(?) -#define NV3_LFB_RAMIN_START 0xC00000 // RAMIN mapping start -#define NV3_LFB_MAPPING_SIZE 0x400000 // Size of RAMIN - -// THere are 64 DMA channels grouped into 8 "channels" with 8 "subchannels" each. You can only use one channel at a time. An arbitrary number of 8 objects can be submitted. -// Channel 0 is always taken up by NV drivers. - -#define NV3_DMA_CHANNELS 8 -#define NV3_DMA_SUBCHANNELS_PER_CHANNEL 8 - -#define NV3_DMA_CHANNELS_TOTAL 0x7F // This is also used somewhere despite there only being 8*8 = 64 channels - -#define NV3_LAST_VALID_GRAPHICS_OBJECT_ID 0x1F - -// The class ids are represented with 5 bits in PGRAPH, but 7 bits in PFIFO! -// What... -#define NV3_PFIFO_FIRST_VALID_GRAPHICS_OBJECT_ID 0x40 -#define NV3_PFIFO_LAST_VALID_GRAPHICS_OBJECT_ID 0x5F - -// Default value for the boot information register. -// Depends on the chip -#define NV3_BOOT_REG_REV_A00 0x00030100 // todo: format is wrong(?) for nv3a, fix it later -#define NV3_BOOT_REG_REV_B00 0x00030110 -#define NV3_BOOT_REG_REV_C00 0x00030120 - -// various vbioses for testing -// Coming soon: MIROmagic Premium BIOS (when I get mine dumped) -//todo: move to hash system - -// Oldest one of these - August 8, 1997 - -// This particular VBIOS is very early and has certain bugs -#define NV3_VBIOS_STB_V128_V160 "roms/video/nvidia/nv3/stb-velocity128-1.6.bin" // STB Velocity 128 3D (Riva 128) Ver.1.60 -#define NV3_VBIOS_ERAZOR_V14700 "roms/video/nvidia/nv3/OLD_0000.BIN" // ELSA VICTORY Erazor VBE 3.0 DDC2B DPMS Video BIOS Ver. 1.47.01 (ZZ/ A/00) -#define NV3_VBIOS_ERAZOR_V15403 "roms/video/nvidia/nv3/VCERAZOR.BIN" // ELSA VICTORY Erazor Ver. 1.54.03 [WD/VBE30/DDC2B/DPMS] -#define NV3_VBIOS_ERAZOR_V15500 "roms/video/nvidia/nv3/Ver15500.rv_" // ELSA VICTORY Erazor Ver. 1.55.00 [WD/VBE30/DDC2B/DPMS] -#define NV3_VBIOS_DIAMOND_V330_V162 "roms/video/nvidia/nv3/diamond_v330_rev-e.vbi" // Diamond Multimedia Systems, Inc. Viper V330 Version 1.62-CO -#define NV3_VBIOS_ASUS_V3000_V151 "roms/video/nvidia/nv3/riva128_asus.vbi" // ASUS AGP/3DP-V3000 BIOS 1.51B -#define NV3_VBIOS_STB_V128_V182 "roms/video/nvidia/nv3/riva128_stb.vbi" // STB Velocity 128 (RIVA 128) Ver.1.82 -#define NV3T_VBIOS_DIAMOND_V330_V182B "roms/video/nvidia/nv3/nv3t182b.rom" // Diamond Multimedia Viper V330 8M BIOS - Version 1.82B -#define NV3T_VBIOS_ASUS_V170 "roms/video/nvidia/nv3/A170D03T.rom" // ASUS AGP-V3000 ZXTV BIOS - V1.70D.03 (C) 1996-98 Nvidia Corporation -#define NV3T_VBIOS_REFERENCE_CEK_V171 "roms/video/nvidia/nv3/BIOS_49_Riva 128" // Reference BIOS: RIVA 128 ZX BIOS - V1.71B-N (C) 1996-98 NVidia Corporation -#define NV3T_VBIOS_REFERENCE_CEK_V172 "roms/video/nvidia/nv3/vgasgram.rom" // Reference(?) BIOS: RIVA 128 ZX BIOS - V1.72B (C) 1996-98 NVidia Corporation - -// The default VBIOS to use -#define NV3_VBIOS_DEFAULT NV3_VBIOS_ERAZOR_V15403 - -// Temporary, will be loaded from settings -#define NV3_VRAM_SIZE_2MB 0x200000 // 2MB -#define NV3_VRAM_SIZE_4MB 0x400000 // 4MB -#define NV3_VRAM_SIZE_8MB 0x800000 // NV3T only -// There is also 1mb supported by the card but it was never used - -// PCI config -#define NV3_PCI_CFG_VENDOR_ID 0x0 -#define NV3_PCI_CFG_DEVICE_ID 0x2 -#define NV3_PCI_CFG_CAPABILITIES 0x4 - -#define NV3_PCI_COMMAND_L_IO 1 -#define NV3_PCI_COMMAND_L_IO_ENABLED 0x1 -#define NV3_PCI_COMMAND_L_MEMORY 2 -#define NV3_PCI_COMMAND_L_MEMORY_ENABLED 0x1 - -#define NV3_PCI_COMMAND_H_FAST_BACK2BACK 0x01 - -#define NV3_PCI_STATUS_L_66MHZ_CAPABLE 0x20 -#define NV3_PCI_STATUS_H_DEVSEL_TIMING 5 -#define NV3_PCI_STATUS_H_FAST_DEVSEL_TIMING 0x00 - -#define NV3_PCI_CFG_REVISION 0x8 - -#define NV3_PCI_CFG_REVISION_A00 0x00 // nv3a January 1997 - engineering sample, had NV1 PAUDIO and other minor incompatibilities -#define NV3_PCI_CFG_REVISION_B00 0x10 // nv3b September 1997 -#define NV3_PCI_CFG_REVISION_C00 0x20 // todo: verify this - nv3c (nv3t?) / RIVA 128 ZX - -#define NV3_PCI_CFG_PROGRAMMING_INTERFACE 0x9 -#define NV3_PCI_CFG_SUBCLASS_CODE 0x0A -#define NV3_PCI_CFG_CLASS_CODE 0x0B -#define NV3_PCI_CFG_CLASS_CODE_VGA 0x03 - -#define NV3_PCI_CFG_CACHE_LINE_SIZE 0x0C -#define NV3_PCI_CFG_CACHE_LINE_SIZE_DEFAULT_FROM_VBIOS 0x40 - -#define NV3_PCI_CFG_LATENCY_TIMER 0x0D -#define NV3_PCI_CFG_HEADER_TYPE 0x0E -#define NV3_PCI_CFG_BIST 0x0F - -// PCI Bars -#define NV3_PCI_CFG_BAR_PREFETCHABLE 3 -#define NV3_PCI_CFG_BAR_PREFETCHABLE_ENABLED 0x1 - -#define NV3_PCI_CFG_BAR0_L 0x10 -#define NV3_PCI_CFG_BAR0_BYTE1 0x11 -#define NV3_PCI_CFG_BAR0_BYTE2 0x12 -#define NV3_PCI_CFG_BAR0_BASE_ADDRESS 0x13 -#define NV3_PCI_CFG_BAR1_L 0x14 -#define NV3_PCI_CFG_BAR1_BYTE1 0x15 -#define NV3_PCI_CFG_BAR1_BYTE2 0x16 -#define NV3_PCI_CFG_BAR1_BASE_ADDRESS 0x17 -#define NV3_PCI_CFG_BAR_INVALID_START 0x18 -#define NV3_PCI_CFG_BAR_INVALID_END 0x27 -#define NV3_PCI_CFG_SUBSYSTEM_ID 0x2C - -#define NV3_PCI_CFG_ENABLE_VBIOS 0x30 -#define NV3_PCI_CFG_VBIOS_BASE 0x32 ... 0x33 -#define NV3_PCI_CFG_VBIOS_BASE_L 0x32 -#define NV3_PCI_CFG_VBIOS_BASE_H 0x33 - -#define NV3_AGP_CAPABILITIES_POINTER 0x34 - -#define NV3_PCI_CFG_INT_LINE 0x3C -#define NV3_PCI_CFG_INT_PIN 0x3D - -#define NV3_PCI_CFG_SUBSYSTEM_ID_MIRROR_START 0x40 -#define NV3_PCI_CFG_SUBSYSTEM_ID_MIRROR_END 0x43 - -#define NV3_PCI_CFG_MIN_GRANT 0x3E -#define NV3_PCI_CFG_MIN_GRANT_DEFAULT 0x03 -#define NV3_PCI_CFG_MAX_LATENCY 0x3F -#define NV3_PCI_CFG_MAX_LATENCY_DEFAULT 0x01 - -// -// AGP configuration -// - -#define NV3_AGP_START 0x44 - -// stupid stupid pci system -#define NV3_AGP_CAPABILITIES_START 0x44 -#define NV3_AGP_CAPABILITIES_CAP_ID 0x44 -#define NV3_AGP_CAPABILITIES_CAP_ID_AGP 0x02 // "AGP" -#define NV3_AGP_CAPABILITIES_NEXT_PTR 0x45 -#define NV3_AGP_CAPABILITIES_AGP_VERSION 0x46 -#define NV3_AGP_CAPABILITIES_AGP_VERSION_MINOR 0 -#define NV3_AGP_CAPABILITIES_AGP_VERSION_MAJOR 4 -#define NV3_AGP_CAPABILITIES_H 0x47 - -#define NV3_AGP_STATUS_RATE 0x48 -#define NV3_AGP_STATUS_RATE_1X_SUPPORTED 0x1 -#define NV3_AGP_STATUS_RATE_2X_SUPPORTED 0x2 - -#define NV3_AGP_STATUS_BYTE1 0x49 -#define NV3_AGP_STATUS_BYTE1_SBA 1 -#define NV3_AGP_STATUS_SBA_SUPPORTED 0x0 -#define NV3_AGP_STATUS_SBA_UNSUPPORTED 0x1 -#define NV3_AGP_STATUS_MAX_REQUESTS 0x4B -#define NV3_AGP_STATUS_MAX_REQUESTS_AMOUNT 4 - -#define NV3_AGP_COMMAND 0x4C -#define NV3_AGP_COMMAND_DATA_RATE 0 -#define NV3_AGP_COMMAND_DATA_RATE_1X 0x1 -#define NV3_AGP_COMMAND_DATA_RATE_2X 0x2 -#define NV3_AGP_COMMAND_BYTE1 0x4D -#define NV3_AGP_COMMAND_BYTE1_ENABLE 0 -#define NV3_AGP_COMMAND_BYTE1_ENABLE_DISABLED 0x0 -#define NV3_AGP_COMMAND_BYTE1_ENABLE_ENABLED 0x1 -#define NV3_AGP_COMMAND_SBA_ENABLE 1 -#define NV3_AGP_COMMAND_SBA_ENABLE_DISABLED 0x0 -#define NV3_AGP_COMMAND_SBA_ENABLE_ENABLED 0x1 -#define NV3_AGP_COMMAND_REQUEST_DEPTH 0x4F - -#define NV3_AGP_END 0x4F - -// -// ACPI (NV3T only) -// TODO: IMPLEMENT THIS!!!!!! -// -#define NV3_POWER_CAP_ID 0x60 -#define NV3_POWER_NEXT_PTR 0x61 -#define NV3_POWER_VERSION 0x62 - -// "The RIVA128ZX does not physically change its power consumption when -// POWER_STATE is modified." -#define NV3_POWER_STATE 0x64 - -#define NV3_POWER_STATE_D0 0x0 -#define NV3_POWER_STATE_D3HOT 0x3 - -// GPU Subsystems -// These most likely correspond to functional blocks in the original design - -#define NV3_PMC_START 0x0 // Chip Master Control Subsystem - -#define NV3_PMC_BOOT 0x0 // Boot Configuration - -#define NV3_PMC_INTERRUPT_STATUS 0x100 // Interrupt Control -#define NV3_PMC_INTERRUPT_PAUDIO 0 // Unused, NV3A only -#define NV3_PMC_INTERRUPT_PAUDIO_PENDING 0x1 // Unused, NV3A only -#define NV3_PMC_INTERRUPT_PMEDIA 4 -#define NV3_PMC_INTERRUPT_PMEDIA_PENDING 0x1 -#define NV3_PMC_INTERRUPT_PFIFO 8 -#define NV3_PMC_INTERRUPT_PFIFO_PENDING 0x1 -#define NV3_PMC_INTERRUPT_PGRAPH0 12 -#define NV3_PMC_INTERRUPT_PGRAPH0_PENDING 0x1 -#define NV3_PMC_INTERRUPT_PGRAPH1 13 -#define NV3_PMC_INTERRUPT_PGRAPH1_PENDING 0x1 -#define NV3_PMC_INTERRUPT_PVIDEO 16 -#define NV3_PMC_INTERRUPT_PVIDEO_PENDING 0x1 -#define NV3_PMC_INTERRUPT_PTIMER 20 -#define NV3_PMC_INTERRUPT_PTIMER_PENDING 0x1 -#define NV3_PMC_INTERRUPT_PFB 24 -#define NV3_PMC_INTERRUPT_PFB_PENDING 0x1 -#define NV3_PMC_INTERRUPT_PBUS 28 -#define NV3_PMC_INTERRUPT_PBUS_PENDING 0x1 -#define NV3_PMC_INTERRUPT_SOFTWARE 31 -#define NV3_PMC_INTERRUPT_SOFTWARE_PENDING 0x1 -#define NV3_PMC_INTERRUPT_ENABLE 0x140 // Controls global interrupt enable state -#define NV3_PMC_INTERRUPT_ENABLE_HARDWARE 0x1 // Determines if hardware interrupts are enabled -#define NV3_PMC_INTERRUPT_ENABLE_SOFTWARE 0x2 // Determinse if software interrupts were enabled -#define NV3_PMC_ENABLE 0x200 // Determines which gpu subsystems were enabled -#define NV3_PMC_ENABLE_PAUDIO 0 // UNUSED - PAudio removed in NV3 Stepping B0 -#define NV3_PMC_ENABLE_PAUDIO_ENABLED 0x1 // UNUSED - PAudio removed in NV3 Stepping B0 -#define NV3_PMC_ENABLE_PMEDIA 4 -#define NV3_PMC_ENABLE_PMEDIA_ENABLED 0x1 -#define NV3_PMC_ENABLE_PFIFO 8 -#define NV3_PMC_ENABLE_PFIFO_ENABLED 0x1 -#define NV3_PMC_ENABLE_PGRAPH 12 // Determines if PGRAPH is enabled. -#define NV3_PMC_ENABLE_PGRAPH_ENABLED 0x1 -#define NV3_PMC_ENABLE_PPMI 16 -#define NV3_PMC_ENABLE_PPMI_ENABLED 0x1 -#define NV3_PMC_ENABLE_PFB 20 -#define NV3_PMC_ENABLE_PFB_ENABLED 0x1 -#define NV3_PMC_ENABLE_PCRTC 24 -#define NV3_PMC_ENABLE_PCRTC_ENABLED 0x1 -#define NV3_PMC_ENABLE_PVIDEO 28 -#define NV3_PMC_ENABLE_PVIDEO_ENABLED 0x1 - -#define NV3_PMC_END 0xfff // overlaps with CIO -#define NV3_CIO_START 0x3b0 // Legacy SVGA Emulation Subsystem -#define NV3_CIO_END 0x3df -#define NV3_PBUS_START 0x1000 // Bus Control Subsystem -#define NV3_PBUS_DEBUG_0 0x1084 // Bus Control Debug -#define NV3_PBUS_INTR 0x1100 // Bus Control - Interrupt Status - -#define NV3_PBUS_INTR_EN 0x1140 // Bus Control - Interrupt Enable -#define NV3_PBUS_PCI_START 0x1800 // PCI mirror start -#define NV3_PBUS_PCI_END 0x18FF // PCI mirror end -#define NV3_PBUS_END 0x1FFF -#define NV3_PFIFO_START 0x2000 // FIFO for DMA Object Submission (uses hashtable to store the objects) - -#define NV3_PFIFO_MINIMUM_GUARANTEED_DEPTH 0x7C - -#define NV3_PFIFO_DELAY_0 0x2040 // PFIFO Config Register -#define NV3_PFIFO_DEBUG_0 0x2080 // PFIFO Debug Register -#define NV3_PFIFO_CACHE0_ERROR_PENDING 0 -#define NV3_PFIFO_CACHE1_ERROR_PENDING 4 - -#define NV3_PFIFO_INTR 0x2100 // FIFO - Interrupt Status -#define NV3_PFIFO_INTR_EN 0x2140 // FIFO - Interrupt Enable - -// PFIFO interrupts -#define NV3_PFIFO_INTR_CACHE_ERROR 0 -#define NV3_PFIFO_INTR_RUNOUT 4 -#define NV3_PFIFO_INTR_RUNOUT_OVERFLOW 8 -#define NV3_PFIFO_INTR_DMA_PUSHER 12 -#define NV3_PFIFO_INTR_DMA_PTE 16 - -#define NV3_PFIFO_CONFIG_0 0x2200 -#define NV3_PFIFO_CONFIG_0_DMA_FETCH 8 - -#define NV3_PFIFO_CONFIG_RAMHT 0x2210 // Hashtable for graphics objects config -#define NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS 12 // 15:12 -#define NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS_DEFAULT 0x0 -#define NV3_PFIFO_CONFIG_RAMHT_SIZE 16 // 17:16 -#define NV3_PFIFO_CONFIG_RAMHT_SIZE_4K 0x0 -#define NV3_PFIFO_CONFIG_RAMHT_SIZE_8K 0x1 -#define NV3_PFIFO_CONFIG_RAMHT_SIZE_16K 0x2 -#define NV3_PFIFO_CONFIG_RAMHT_SIZE_32K 0x3 - -#define NV3_PFIFO_CONFIG_RAMFC 0x2214 -#define NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS 9 -#define NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS_DEFAULT 0x1C00 // Hardcoded in silicon? -#define NV3_PFIFO_CONFIG_RAMRO 0x2218 -#define NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS 9 -#define NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS_DEFAULT 0x1E00 // Hardcoded in silicon? -#define NV3_PFIFO_CONFIG_RAMRO_SIZE 16 -#define NV3_PFIFO_CONFIG_RAMRO_SIZE_512B 0x0 -#define NV3_PFIFO_CONFIG_RAMRO_SIZE_8K 0x1 - -#define NV3_PFIFO_RUNOUT_STATUS 0x2400 -#define NV3_PFIFO_RUNOUT_STATUS_RANOUT 0 // 1 if we fucked up -#define NV3_PFIFO_RUNOUT_STATUS_EMPTY 4 // 1 if ramro is empty -#define NV3_PFIFO_RUNOUT_STATUS_FULL 8 -#define NV3_PFIFO_RUNOUT_PUT 0x2410 -#define NV3_PFIFO_RUNOUT_PUT_ADDRESS 3 // 9:3 if small ramfc(?) otherwise 12:3 -#define NV3_PFIFO_RUNOUT_GET 0x2420 -#define NV3_PFIFO_RUNOUT_GET_ADDRESS 3 // 13:3 - -#define NV3_PFIFO_RUNOUT_RAMIN_ERR 28 // bit to or with - -#define NV3_PFIFO_CACHE0_SIZE 1 // This is for software-injected notified only! -#define NV3_PFIFO_CACHE1_SIZE_REV_AB 32 -#define NV3_PFIFO_CACHE1_SIZE_REV_C 64 -#define NV3_PFIFO_CACHE1_SIZE_MAX NV3_PFIFO_CACHE1_SIZE_REV_C -#define NV3_PFIFO_CACHE_REASSIGNMENT 0x2500 - -#define NV3_PFIFO_CACHE0_PUSH_ENABLED 0x3000 -#define NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID 0x3004 -#define NV3_PFIFO_CACHE0_PUT 0x3010 -#define NV3_PFIFO_CACHE0_STATUS 0x3014 -#define NV3_PFIFO_CACHE0_STATUS_EMPTY 4 // 1 if ramro is empty -#define NV3_PFIFO_CACHE0_STATUS_FULL 8 -#define NV3_PFIFO_CACHE0_PUT_ADDRESS 2 // 1 bit -#define NV3_PFIFO_CACHE0_PULL0 0x3040 -#define NV3_PFIFO_CACHE0_PULL0_ENABLED 0 -#define NV3_PFIFO_CACHE0_PULL0_HASH_FAILURE 4 -#define NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD 8 -#define NV3_PFIFO_CACHE0_PULLER_CTX_STATE 0x3050 -#define NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY 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_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_PUSH_ENABLED 0x3200 -#define NV3_PFIFO_CACHE1_PUSH_CHANNEL_ID 0x3204 -#define NV3_PFIFO_CACHE1_PUT 0x3210 -#define NV3_PFIFO_CACHE1_PUT_ADDRESS 2 // 6:2 -#define NV3_PFIFO_CACHE1_STATUS 0x3214 -#define NV3_PFIFO_CACHE1_STATUS_RANOUT 0 // 1 if we fucked up -#define NV3_PFIFO_CACHE1_STATUS_EMPTY 4 // 1 if ramro is empty -#define NV3_PFIFO_CACHE1_STATUS_FULL 8 -#define NV3_PFIFO_CACHE1_DMA_STATUS 0x3218 -#define NV3_PFIFO_CACHE1_DMA_STATUS_STATE 0 -#define NV3_PFIFO_CACHE1_DMA_STATUS_STATE_IDLE 0x00 -#define NV3_PFIFO_CACHE1_DMA_STATUS_STATE_RUNNING 0x01 -#define NV3_PFIFO_CACHE1_DMA_CONFIG_0 0x3220 -#define NV3_PFIFO_CACHE1_DMA_CONFIG_1 0x3224 -#define NV3_PFIFO_CACHE1_DMA_CONFIG_2 0x3228 -#define NV3_PFIFO_CACHE1_DMA_CONFIG_3 0x322C -#define NV3_PFIFO_CACHE1_DMA_CONFIG_3_TARGET_NODE 0 // The type of bus we are sending over -#define NV3_PFIFO_CACHE1_DMA_CONFIG_3_TARGET_NODE_PCI 0x02 // The type of bus we are sending over -#define NV3_PFIFO_CACHE1_DMA_CONFIG_3_TARGET_NODE_AGP 0x03 // The type of bus we are sending over - -// Why does a gpu need its own translation lookaside buffer and pagetable format. Are they crazy -// Seems to be the same format as the notifier engine -#define NV3_PFIFO_CACHE1_DMA_TLB_TAG 0x3230 -#define NV3_PFIFO_CACHE1_DMA_TLB_PTE 0x3234 // pagetable entry for dma -#define NV3_PFIFO_CACHE1_DMA_TLB_PTE_IS_PRESENT 1 -#define NV3_PFIFO_CACHE1_DMA_TLB_FRAME_ADDRESS 12 // 31:12 -#define NV3_PFIFO_CACHE1_DMA_TLB_PT_BASE 0x3238 // Base of pagetable for DMA -#define NV3_PFIFO_CACHE1_PULL0 0x3240 -//todo: merge stuff -#define NV3_PFIFO_CACHE1_PULL0_ENABLED 0 -#define NV3_PFIFO_CACHE1_PULL0_HASH_FAILURE 4 -#define NV3_PFIFO_CACHE1_PULL0_SOFTWARE_METHOD 8 // 0=software, 1=hardware -#define NV3_PFIFO_CACHE1_PULLER_CTX_STATE 0x3250 -#define NV3_PFIFO_CACHE1_PULLER_CTX_STATE_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_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 -#define NV3_PRM_INTR_EN 0x4140 -#define NV3_PRM_END 0x4FFF -#define NV3_PRAM_START 0x6000 // Local ram/cache? -#define NV3_PRAM_END 0x6FFF -#define NV3_PRMIO_START 0x7000 // Real-Mode I/O Subsystem -#define NV3_PRMIO_END 0x7FFF -#define NV3_PTIMER_START 0x9000 // Programmable Interval Timer -#define NV3_PTIMER_INTR 0x9100 -#define NV3_PTIMER_INTR_ALARM 0 // Alarm interrupt -#define NV3_PTIMER_INTR_EN 0x9140 -#define NV3_PTIMER_NUMERATOR 0x9200 -#define NV3_PTIMER_DENOMINATOR 0x9210 -#define NV3_PTIMER_TIME_0_NSEC 0x9400 // nanoseconds [31:5] -#define NV3_PTIMER_TIME_1_NSEC 0x9410 // nanoseconds [28:0] -#define NV3_PTIMER_ALARM_NSEC 0x9420 // nanoseconds [31:5] -#define NV3_PTIMER_END 0x9FFF -#define NV3_VGA_VRAM_START 0xA0000 // VGA Emulation VRAM -#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 // 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 -#define NV3_PFB_BOOT_RAM_AMOUNT_8MB 0x0 // 1mb in NV3A -#define NV3_PFB_BOOT_RAM_AMOUNT_2MB 0x1 -#define NV3_PFB_BOOT_RAM_AMOUNT_4MB 0x2 -#define NV3_PFB_BOOT_RAM_AMOUNT_UNDEFINED 0x3 // i assume this is used for debug -#define NV3_PFB_BOOT_RAM_WIDTH 2 // the bus width of the gpu's vram -#define NV3_PFB_BOOT_RAM_WIDTH_64 0x0 // 64bit -#define NV3_PFB_BOOT_RAM_WIDTH_128 0x1 // 128bit -#define NV3_PFB_BOOT_RAM_BANKS 3 // the number of banks -#define NV3_PFB_BOOT_RAM_BANKS_2 0x0 // 2 banks (seems to be used for 2mb) -#define NV3_PFB_BOOT_RAM_BANKS_4 0x1 // 4 banks (seems to be used for 4mb) -#define NV3_PFB_BOOT_RAM_DATA_TWIDDLE 4 -#define NV3_PFB_BOOT_RAM_DATA_TWIDDLE_OFF 0x0 -#define NV3_PFB_BOOT_RAM_DATA_TWIDDLE_ON 0x1 -#define NV3_PFB_BOOT_RAM_EXTENSION 5 -#define NV3_PFB_BOOT_RAM_EXTENSION_NONE 0x0 -#define NV3_PFB_BOOT_RAM_EXTENSION_8MB 0x1 - -#define NV3_PFB_DELAY 0x100044 -#define NV3_PFB_DEBUG_0 0x100080 // Debug register for pfb -#define NV3_PFB_GREEN_0 0x1000C0 - -#define NV3_PFB_CONFIG_0 0x100200 // Framebuffer interface config register 0 - -// What is this lol -// ??? Part of the memory timings -#define NV3_PFB_RTL 0x100300 -#define NV3_PFB_CONFIG_0_RESOLUTION 0 -// 1=40 horiz. resolution -// i assume it can be divided by some kind of divisor to produce the vertical resolution (e.g. 3/2 or multiply by 2/3) to get the final -// horiz is 32*value -// theoretically it should support resolutions from 40-2560 horiz - -// WHAT ARE THE TIMINGS: ARE THEY IN THE VBIOS? -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_320 0xA -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_400 0xD -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_480 0xF -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_512 0x10 -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_640 0x14 -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_800 0x19 -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_960 0x1E -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_1024 0x20 -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_1152 0x24 -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_1280 0x28 -#define NV3_PFB_CONFIG_0_HORIZ_RESOLUTION_1600 0x32 - -#define NV3_PFB_CONFIG_0_PIXEL_DEPTH 8 -#define NV3_PFB_CONFIG_0_DEPTH_8BPP 0x1 -#define NV3_PFB_CONFIG_0_DEPTH_16BPP 0x2 -#define NV3_PFB_CONFIG_0_DEPTH_32BPP 0x3 - -#define NV3_PFB_CONFIG_1 0x100204 // Framebuffer interface config register 1 -#define NV3_PFB_END 0x100FFF -#define NV3_PEXTDEV_START 0x101000 // External Devices -#define NV3_PSTRAPS 0x101000 // Straps Bits -#define NV3_PSTRAPS_BUS_SPEED 0 // Configured bus speed -#define NV3_PSTRAPS_BUS_SPEED_33MHZ 0x0 -#define NV3_PSTRAPS_BUS_SPEED_66MHZ 0x1 -#define NV3_PSTRAPS_BIOS 1 // Is a VBIOS present? -#define NV3_PSTRAPS_BIOS_NOT_PRESENT 0x0 -#define NV3_PSTRAPS_BIOS_PRESENT 1 -#define NV3_PSTRAPS_RAM_TYPE 2 // Type of RAM module -#define NV3_PSTRAPS_RAM_TYPE_16MBIT 0x0 -#define NV3_PSTRAPS_RAM_TYPE_8MBIT 0x1 -#define NV3_PSTRAPS_NEC_MODE 3 // PC98? -#define NV3_PSTRAPS_NEC_MODE_DISABLED 0x0 -#define NV3_PSTRAPS_NEC_MODE_ENABLED 0x1 -#define NV3_PSTRAPS_BUS_WIDTH 4 // Bus width -#define NV3_PSTRAPS_BUS_WIDTH_64BIT 0x0 -#define NV3_PSTRAPS_BUS_WIDTH_128BIT 0x0 -#define NV3_PSTRAPS_BUS_TYPE 5 // Determines if this is a PCI or AGP card -#define NV3_PSTRAPS_BUS_TYPE_PCI 0x0 -#define NV3_PSTRAPS_BUS_TYPE_AGP 0x1 -#define NV3_PSTRAPS_CRYSTAL 6 // type of clock crystal -#define NV3_PSTRAPS_CRYSTAL_13500K 0x0 // 13.5 Mhz -#define NV3_PSTRAPS_CRYSTAL_14318180 0x1 // 14.318180 Mhz clock crystal -#define NV3_PSTRAPS_TVMODE 7 // Type of TV signal to put out -#define NV3_PSTRAPS_TVMODE_SECAM 0x0 -#define NV3_PSTRAPS_TVMODE_NTSC 0x1 -#define NV3_PSTRAPS_TVMODE_PAL 0x2 -#define NV3_PSTRAPS_TVMODE_NONE 0x3 -#define NV3_PSTRAPS_AGP2X 9 -#define NV3_PSTRAPS_AGP2X_ENABLED 0x0 -#define NV3_PSTRAPS_AGP2X_DISABLED 0x1 -#define NV3_PSTRAPS_UNUSED 10 -#define NV3_PSTRAPS_OVERWRITE 11 -#define NV3_PSTRAPS_OVERWRITE_DISABLED 0x0 -#define NV3_PSTRAPS_OVERWRITE_ENABLED 0x1 -#define NV3_PEXTDEV_END 0x101FFF -#define NV3_PROM_START 0x110000 // VBIOS? -#define NV3_PROM_END 0x11FFFF -#define NV3_PALT_START 0x120000 // ??? but it exists -#define NV3_PALT_END 0x12FFFF -#define NV3_PME_START 0x200000 // Mediaport -#define NV3_PME_INTR 0x200100 // Mediaport: Interrupt Pending? -#define NV3_PME_INTR_EN 0x200140 // Mediaport: Interrupt Enable -#define NV3_PME_END 0x200FFF - -#define NV3_PGRAPH_START 0x400000 // Scene graph for 2d/3d rendering...the most important part -// PGRAPH Core - -#define NV3_PGRAPH_MAX_BUFFERS 4 - -// For these debug registers, 0=Disabled, 1=Enabled - -// Debug 0: General -#define NV3_PGRAPH_DEBUG_0 0x400080 -#define NV3_PGRAPH_DEBUG_0_STATE_IN_RESET 0 -#define NV3_PGRAPH_DEBUG_0_AP_PIPE_IN_RESET 1 -#define NV3_PGRAPH_DEBUG_0_CACHE_IN_RESET 2 -#define NV3_PGRAPH_DEBUG_0_3D_PIPE_IN_RESET 3 -#define NV3_PGRAPH_DEBUG_0_BULK_READS 4 -#define NV3_PGRAPH_DEBUG_0_TILING 16 -#define NV3_PGRAPH_DEBUG_0_WRITE_ONLY_ROPS_2D 20 -#define NV3_PGRAPH_DEBUG_0_WRITE_ONLY_ROPS_3D 21 -#define NV3_PGRAPH_DEBUG_0_DRAWDIR_AUT 24 -#define NV3_PGRAPH_DEBUG_0_DRAWDIR_Y 25 -#define NV3_PGRAPH_DEBUG_0_ALPHA_ABORT 28 - -// Debug 1: Registers -#define NV3_PGRAPH_DEBUG_1 0x400084 -#define NV3_PGRAPH_DEBUG_1_VOLATILE_RESET_LAST 0 -#define NV3_PGRAPH_DEBUG_1_DMA_ACTIVITY_CANCEL 4 -#define NV3_PGRAPH_DEBUG_1_TURBO3D_2X 8 -#define NV3_PGRAPH_DEBUG_1_TURBO3D_4X 9 -#define NV3_PGRAPH_DEBUG_1_TRIANGLE_OPS 12 -#define NV3_PGRAPH_DEBUG_1_TRIANGLE_CLIP_OPS 13 -#define NV3_PGRAPH_DEBUG_1_INSTANCE 16 -#define NV3_PGRAPH_DEBUG_1_CONTEXT 20 -#define NV3_PGRAPH_DEBUG_1_CACHE_FLUSH 24 -#define NV3_PGRAPH_DEBUG_1_ZCLAMP 28 - -// Debug 2: 3D Pipeline -#define NV3_PGRAPH_DEBUG_2 0x400088 -#define NV3_PGRAPH_DEBUG_2_AVOID_READMODIFYWRITE_BLEND 0 -#define NV3_PGRAPH_DEBUG_2_DPWR_FIFO 8 -#define NV3_PGRAPH_DEBUG_2_BILINEAR_FILTERING_3D 12 -#define NV3_PGRAPH_DEBUG_2_ANISOTROPIC_FILTERING_3D 13 -#define NV3_PGRAPH_DEBUG_2_FOG 14 -#define NV3_PGRAPH_DEBUG_2_LIGHTING 15 // Not sure what this does, maybe hardware t&l was planned -#define NV3_PGRAPH_DEBUG_2_BILINEAR_FILTERING_2D 16 -#define NV3_PGRAPH_DEBUG_2_ANISOTROPIC_FILTERING_2D 17 -#define NV3_PGRAPH_DEBUG_2_D3D_COALESCE 20 // coalesce reads/writes for d3d class 0x17 -#define NV3_PGRAPH_DEBUG_2_D3D_COALESCE_POINT_ZETA 22 // class 0x18 coalesce -#define NV3_PGRAPH_DEBUG_2_PREFETCH 24 -#define NV3_PGRAPH_DEBUG_2_VOLATILE_RESET 28 - -// Debug 3: Zeta & Alpha Buffer -#define NV3_PGRAPH_DEBUG_3 0x40008C -#define NV3_PGRAPH_DEBUG_3_CULLING 0 -#define NV3_PGRAPH_DEBUG_3_FAST_DATA_D3D 4 -#define NV3_PGRAPH_DEBUG_3_FAST_DATA_STRETCH 5 -#define NV3_PGRAPH_DEBUG_3_ZFLUSH 7 -#define NV3_PGRAPH_DEBUG_3_AUTOZFLUSH_POINT_ZETA 8 -#define NV3_PGRAPH_DEBUG_3_AUTOZFLUSH_D3D 9 -#define NV3_PGRAPH_DEBUG_3_SLOT_CONFLICT_POINT_ZETA 10 // Slot conflict handling for POINT_ZETA (class 0x18) -#define NV3_PGRAPH_DEBUG_3_SLOT_CONFLICT_D3D 11 // Slot conflict handling for D3D5_TRI (class 0x17) -#define NV3_PGRAPH_DEBUG_3_EARLY_ZABORT 12 -#define NV3_PGRAPH_DEBUG_3_TRIANGLE_END_FLUSH 13 -#define NV3_PGRAPH_DEBUG_3_ZFIFO_NOOP 14 // ??? -#define NV3_PGRAPH_DEBUG_3_DITHER 15 -#define NV3_PGRAPH_DEBUG_3_FORCE_COLOR_BUFFER_READ 16 -#define NV3_PGRAPH_DEBUG_3_FORCE_ZETA_BUFFER_READ 17 -#define NV3_PGRAPH_DEBUG_3_DATA_CHECK 20 -#define NV3_PGRAPH_DEBUG_3_DATA_CHECK_FAIL 21 -#define NV3_PGRAPH_DEBUG_3_FORMAT_CHECK 22 -#define NV3_PGRAPH_DEBUG_3_ALPHA_CHECK 24 - -// Interrupt stuff -#define NV3_PGRAPH_INTR_0 0x400100 -#define NV3_PGRAPH_INTR_0_VBLANK 8 // Fired every frame -#define NV3_PGRAPH_INTR_0_VBLANK_ENABLED 0x1 // Is the vblank interrupt enabled? -#define NV3_PGRAPH_INTR_0_SOFTWARE_NOTIFY 28 // Fired on software notification - -#define NV3_PGRAPH_INTR_1 0x400104 -#define NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING 0 // Software or invalid method -#define NV3_PGRAPH_INTR_1_INVALID_DATA 4 // Invalid data. Not sure when this would be triggered. -#define NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY 12 // Tried to notify while a notify was pending. -#define NV3_PGRAPH_INTR_1_CTXSW_NOTIFY 16 // Notify fired for software context - -#define NV3_PGRAPH_INTR_EN_0 0x400140 // Interrupt Control for PGRAPH #1 -//todo: add what this does -#define NV3_PGRAPH_INTR_EN_1 0x400144 // Interrupt Control for PGRAPH #2 (it can receive two at onc) -#define NV3_PGRAPH_CTX_SWITCH 0x400180 // Holds the current PGRAPH context, switched by context switching - -/* Contextual information for pgraph */ -#define NV3_PGRAPH_CTX_SWITCH_COLOR_FORMAT 0 // Holds the current color format used for drawing operations. -#define NV3_PGRAPH_CTX_SWITCH_ALPHA 3 // Holds a boolean indicating in if alpha transparency is currently enabled in drawing operations. -#define NV3_PGRAPH_CTX_SWITCH_MONO_FORMAT 8 // Holds the current color format used for monochome drawing operations. -#define NV3_PGRAPH_CTX_SWITCH_DAC_BYPASS 9 // Holds if PRAMDAC should be bypassed, and an external DAC drawn. -#define NV3_PGRAPH_CTX_SWITCH_Z_WRITE 12 // Holds if we should write back to the zbuffer. -#define NV3_PGRAPH_CTX_SWITCH_CHROMA_KEY 13 // Holds the current chroma mask used for drawing operations. -#define NV3_PGRAPH_CTX_SWITCH_PLANE_MASK 14 // Holds the current plane mask used for drawing operations. -#define NV3_PGRAPH_CTX_SWITCH_USER_CLIP 15 // Holds the user-specified clipping information used for drawing operations. -#define NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER 16 // Holds the buffer ID used for drawing operation (i.e. which bpixel/bpitch/boffset index to use) -#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER0_ENABLED 20 // Holds a boolean indicating if buffer 0 can be used as the destination for a drawing operation. -#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER1_ENABLED 21 // Holds a boolean indicating if buffer 1 can be used as the destination for a drawing operation. -#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER2_ENABLED 22 // Holds a boolean indicating if buffer 2 can be used as the destination for a drawing operation. -#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER3_ENABLED 23 // Holds a boolean indicating if buffer 3 can be used as the destination for a drawing operation. -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG 24 // ROP type - -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD0 0x0 // Reserved -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_DST_SRC 0x1 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_DST 0x2 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_SRC 0x3 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_DST 0x4 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_SRC 0x5 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_DST 0x6 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_SRC0 0x7 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_SRC1 0x8 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_PAT 0x9 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_SRC 0xA -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_PAT 0xB -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_SRC 0xC -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_PAT 0xD -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_PAT_SRC 0xE -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD1 0xF -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_DST 0x10 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_DST_SRC 0x11 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_DST 0x12 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_PAT 0x13 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_PAT_SRC 0x14 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_PAT 0x15 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD2 0x16 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_BYPASS 0x17 // Ignore -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD0 0x18 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_SRC_DST 0x19 -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_DST_SRC 0x1A -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD1 0x1B -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD2 0x1C -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_SRC 0x1D -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD3 0x1E -#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD4 0x1F - -#define NV3_PGRAPH_CTX_SWITCH_VOLATILE 31 // HUH - -#define NV3_PGRAPH_CONTEXT_CONTROL 0x400190 // DMA context control -#define NV3_PGRAPH_CONTEXT_USER 0x400194 // Current DMA context state, may rename -#define NV3_PGRAPH_CONTEXT_CACHE(i) 0x4001A0+(i*4) // Context Cache -#define NV3_PGRAPH_CONTEXT_CACHE_SIZE 8 -// TODO: CLIP0/CLIP1 (8 clips min/max in 32bits) -#define NV3_PGRAPH_ABS_UCLIP_XMIN 0x40053C // Clip X minimum -#define NV3_PGRAPH_ABS_UCLIP_XMAX 0x400540 // Clip X maximum -#define NV3_PGRAPH_ABS_UCLIP_YMIN 0x400544 // Clip Y minimum -#define NV3_PGRAPH_ABS_UCLIP_YMAX 0x400548 // Clip Y maximum -#define NV3_PGRAPH_SRC_CANVAS_MIN 0x400550 // Minimum Source Canvas for Blit, Y=30:16, X=10:0 -#define NV3_PGRAPH_SRC_CANVAS_MAX 0x400554 // Maximum Source Canvas for Blit, Y=30:16, X=10:0 -#define NV3_PGRAPH_DST_CANVAS_MIN 0x400558 // Minimum Destination Canvas for Blit, Y=30:16, X=10:0 -#define NV3_PGRAPH_DST_CANVAS_MAX 0x40055C // Maximum Destination Canvas for Blit, Y=30:16, X=10:0 -#define NV3_PGRAPH_PATTERN_COLOR_0_RGB 0x400600 -#define NV3_PGRAPH_PATTERN_COLOR_0_ALPHA 0x400604 -#define NV3_PGRAPH_PATTERN_COLOR_1_RGB 0x400608 -#define NV3_PGRAPH_PATTERN_COLOR_1_ALPHA 0x40060C // pattern color -#define NV3_PGRAPH_PATTERN_BITMAP_HIGH 0x400610 // pattern bitmap [31:0] -#define NV3_PGRAPH_PATTERN_BITMAP_LOW 0x400614 // pattern bitmap [63:32] -#define NV3_PGRAPH_PATTERN_SHAPE 0x400618 -#define NV3_PGRAPH_ROP3 0x400624 // ROP3 -#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_INSTANCE 0x400688 // Current instance (?) - -// Current notification object for pgraph -#define NV3_PGRAPH_NOTIFY 0x400684 // Notifier for PGRAPH -#define NV3_PGRAPH_NOTIFY_INSTANCE 0 -#define NV3_PGRAPH_NOTIFY_REQUEST_PENDING 16 -#define NV3_PGRAPH_NOTIFY_REQUEST_TYPE 20 -#define NV3_PGRAPH_NOTIFY_REQUEST_TYPE_HARDWARE 0x0 // anything else is software - -#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 -#define NV3_PGRAPH_CLIP_MISC 0x4006A0 // Miscellaneous clipping information -#define NV3_PGRAPH_STATUS 0x4006B0 // Current PGRAPH status -#define NV3_PGRAPH_TRAPPED_ADDRESS 0x4006B4 -#define NV3_PGRAPH_TRAPPED_DATA 0x4006B8 -#define NV3_PGRAPH_TRAPPED_INSTANCE 0x4006BC - -#define NV3_PGRAPH_DMA_INTR_0 0x401100 // PGRAPH DMA Interrupt Status -#define NV3_PGRAPH_DMA_INTR_INSTANCE 0 -#define NV3_PGRAPH_DMA_INTR_PRESENT 4 -#define NV3_PGRAPH_DMA_INTR_PROTECTION 8 -#define NV3_PGRAPH_DMA_INTR_LINEAR 12 -#define NV3_PGRAPH_DMA_INTR_NOTIFY 16 -#define NV3_PGRAPH_DMA_INTR_EN_0 0x401140 // PGRAPH DMA Interrupt Enable 0 - -#define NV3_PGRAPH_DPRAM_SIZE 12288 // Size of the internal texture cache - -// not sure about the class ids -// these are NOT what each class is, just uSed to manipulate it (there isn't a one to one class->reg mapping anyway) -#define NV3_PGRAPH_CLASS01_BETA_START 0x410000 // Beta blending factor -#define NV3_PGRAPH_CLASS01_BETA_END 0x411FFF -#define NV3_PGRAPH_CLASS02_ROP_START 0x420000 // Blending render operation used at final pixel/fragment generation stage -#define NV3_PGRAPH_CLASS02_ROP_END 0x421FFF -#define NV3_PGRAPH_CLASS03_COLORKEY_START 0x430000 // Color key for image -#define NV3_PGRAPH_CLASS03_COLORKEY_END 0x431FFF -#define NV3_PGRAPH_CLASS04_PLANEMASK_START 0x440000 // Plane mask (for clipping?) -#define NV3_PGRAPH_CLASS04_PLANEMASK_END 0x441FFF -#define NV3_PGRAPH_CLASS05_CLIP_START 0x450000 // clipping, probably class 23 -#define NV3_PGRAPH_CLASS05_CLIP_END 0x451FFF -#define NV3_PGRAPH_CLASS06_PATTERN_START 0x460000 // presumably a blend pattern -#define NV3_PGRAPH_CLASS06_PATTERN_END 0x461FFF -#define NV3_PGRAPH_CLASS07_RECTANGLE_START 0x470000 // also class 25 - that's black [NV1] -#define NV3_PGRAPH_CLASS07_RECTANGLE_END 0x471FFF // also class 25 - that's black [NV1] -#define NV3_PGRAPH_CLASS08_POINT_START 0x480000 // A single point -#define NV3_PGRAPH_CLASS08_POINT_END 0x481FFF -#define NV3_PGRAPH_CLASS09_LINE_START 0x490000 // A line -#define NV3_PGRAPH_CLASS09_LINE_END 0x491FFF -#define NV3_PGRAPH_CLASS0A_LIN_START 0x4A0000 // A lin - a line without its starting or ending pixels -#define NV3_PGRAPH_CLASS0A_LIN_END 0x4A1FFF -#define NV3_PGRAPH_CLASS0B_TRIANGLE_START 0x4B0000 // A triangle [NV1 variant] - in NV1 this was converted to a quad patch -#define NV3_PGRAPH_CLASS0B_TRIANGLE_END 0x4B1FFF -#define NV3_PGRAPH_CLASS0C_GDITEXT_START 0x4C0000 // Windows 95/NT GDI text acceleration -#define NV3_PGRAPH_CLASS0C_GDITEXT_END 0x4C1FFF - -#define NV3_PGRAPH_CLASS0D_MEM2MEM_XFER_START 0x4D0000 // memory to memory transfer (not sure about which class this is) -#define NV3_PGRAPH_CLASS0D_MEM2MEM_XFER_END 0x4D1FFF -#define NV3_PGRAPH_CLASS0E_IMAGE2MEM_XFER_SCALED_START 0x4E0000 // class 55, 56 -#define NV3_PGRAPH_CLASS0F_IMAGE2MEM_XFER_SCALED_END 0x4E1FFF - -#define NV3_PGRAPH_CLASS10_BLIT_START 0x500000 // Blit 2d image from memory -#define NV3_PGRAPH_CLASS10_BLIT_END 0x501FFF - -#define NV3_PGRAPH_CLASS11_CPU2MEM_IMAGE_START 0x510000 // Used for class 33, 34, 54 -#define NV3_PGRAPH_CLASS11_CPU2MEM_IMAGE_END 0x511FFF -#define NV3_PGRAPH_CLASS12_CPU2MEM_BITMAP_START 0x520000 // not sure, might depend on format -#define NV3_PGRAPH_CLASS12_CPU2MEM_BITMAP_END 0x521FFF - -#define NV3_PGRAPH_CLASS14_IMAGE2MEM_XFER_START 0x540000 // send image to vram, not sure what class -#define NV3_PGRAPH_CLASS14_IMAGE2MEM_XFER_END 0x541FFF -#define NV3_PGRAPH_CLASS15_CPU2MEM_STRETCHED_START 0x550000 // stretched cpu->vram transfer, 54 -#define NV3_PGRAPH_CLASS15_CPU2MEM_STRETCHED_END 0x551FFF - -#define NV3_PGRAPH_CLASS17_D3D5TRI_ZETA_START 0x570000 // [NV3] Copy a direct3d 5.0 accelerated triangle to the zeta buffer -#define NV3_PGRAPH_CLASS17_D3D5TRI_ZETA_END 0x571FFF -#define NV3_PGRAPH_CLASS18_POINTZETA_START 0x580000 // possibly class 69 -#define NV3_PGRAPH_CLASS18_POINTZETA_END 0x581FFF - -#define NV3_PGRAPH_CLASS1C_MEM2IMAGE_START 0x5C0000 // class 55, 56, 62, 63? -#define NV3_PGRAPH_CLASS1C_MEM2IMAGE_END 0x5C1FFF - - -#define NV3_PGRAPH_REGISTER_END 0x401FFF // end of pgraph registers -#define NV3_PGRAPH_REAL_END 0x5C1FFF - -// PRMCIO is redirected to SVGA subsystem -#define NV3_PRMCIO_START 0x601000 - - - -#define NV3_PRMCIO_END 0x601FFF - -#define NV3_PDAC_START 0x680000 // OPTIONAL external DAC -#define NV3_PVIDEO_START 0x680000 // Video Generation / overlay configuration -#define NV3_PVIDEO_INTR 0x680100 -#define NV3_PVIDEO_INTR_EN 0x680140 -#define NV3_PVIDEO_FIFO_THRESHOLD 0x680238 -#define NV3_PVIDEO_FIFO_BURST_LENGTH 0x68023C -#define NV3_PVIDEO_OVERLAY 0x680244 -#define NV3_PVIDEO_OVERLAY_VIDEO_IS_ON 0 -#define NV3_PVIDEO_OVERLAY_KEY_ENABLED 4 -#define NV3_PVIDEO_OVERLAY_FORMAT 8 // 0 = CCIR, 1 = YUY2 - -#define NV3_PVIDEO_END 0x6802FF -#define NV3_PRAMDAC_START 0x680300 - -#define NV3_PRAMDAC_CURSOR_START 0x680300 - -#define NV3_PRAMDAC_CURSOR_SIZE_X 32 -#define NV3_PRAMDAC_CURSOR_SIZE_Y 32 - -#define NV3_PRAMDAC_CLOCK_MEMORY 0x680504 -#define NV3_PRAMDAC_CLOCK_MEMORY_VDIV 7:0 -#define NV3_PRAMDAC_CLOCK_MEMORY_NDIV 15:8 -#define NV3_PRAMDAC_CLOCK_MEMORY_PDIV 18:16 -#define NV3_PRAMDAC_CLOCK_PIXEL 0x680508 -#define NV3_PRAMDAC_COEFF_SELECT 0x68050C - -#define NV3_PRAMDAC_GENERAL_CONTROL 0x680600 -#define NV3_PRAMDAC_GENERAL_CONTROL_565_MODE 12 - -// These are all 10-bit values, but aligned to 32bits -// so treating them as 32bit should be fine -#define NV3_PRAMDAC_VSERR_WIDTH 0x680700 -#define NV3_PRAMDAC_VEQU_END 0x680704 -#define NV3_PRAMDAC_VBBLANK_END 0x680708 -#define NV3_PRAMDAC_VBLANK_END 0x68070C -#define NV3_PRAMDAC_VBLANK_START 0x680710 -#define NV3_PRAMDAC_VBBLANK_START 0x680714 -#define NV3_PRAMDAC_VEQU_START 0x680718 -#define NV3_PRAMDAC_VTOTAL 0x68071C -#define NV3_PRAMDAC_HSYNC_WIDTH 0x680720 -#define NV3_PRAMDAC_HBURST_START 0x680724 -#define NV3_PRAMDAC_HBURST_END 0x680728 -#define NV3_PRAMDAC_HBLANK_START 0x68072C -#define NV3_PRAMDAC_HBLANK_END 0x680730 -#define NV3_PRAMDAC_HTOTAL 0x680734 -#define NV3_PRAMDAC_HEQU_WIDTH 0x680738 -#define NV3_PRAMDAC_HSERR_WIDTH 0x68073C - -#define NV3_PRAMDAC_END 0x680FFF -#define NV3_PDAC_END 0x680FFF // OPTIONAL external DAC - - -#define NV3_USER_DAC_START 0x681200 -#define NV3_USER_DAC_PALETTE_START 0x6813C6 -#define NV3_USER_DAC_PIXEL_MASK 0x6813C6 -#define NV3_USER_DAC_READ_MODE_ADDRESS 0x6813C7 //bit0=read/write mode? -#define NV3_USER_DAC_WRITE_MODE_ADDRESS 0x6813C8 -#define NV3_USER_DAC_PALETTE_DATA 0x6813C9 -#define NV3_USER_DAC_PALETTE_SIZE 768 -#define NV3_USER_DAC_PALETTE_END 0x6813C9 -#define NV3_USER_DAC_END 0x681FFF - -#define NV3_USER_START 0x800000 // Mapping for the area where objects are submitted into the FIFO (up to 0x880000?) -#define NV3_USER_END 0xFFFFFF - -// easier name -#define NV3_OBJECT_SUBMIT_START NV3_USER_START -#define NV3_OBJECT_SUBMIT_SUBCHANNEL 13 -#define NV3_OBJECT_SUBMIT_CHANNEL 16 -#define NV3_OBJECT_SUBMIT_END NV3_USER_END - -// also PDFB (Debug Framebuffer?) -#define NV3_PNVM_START 0x1000000 // VRAM access (max 8MB) -#define NV3_PNVM_END 0x17FFFFF - -// to be less confusing - NVM = "NV Memory" -#define NV3_VRAM_START NV3_PNVM_START -#define NV3_VRAM_END NV3_PNVM_END - -// control structures for dma'd in graphics objects from pfifo -// these all have configurable sizes, define them here -#define NV3_RAMIN_START 0x1C00000 - -#define NV3_RAMIN_RAMHT_START 0x1C00000 // Hashtable for storing submitted objects -#define NV3_RAMIN_RAMHT_END 0x1C00FFF -#define NV3_RAMIN_RAMHT_SIZE_0 0xFFF -#define NV3_RAMIN_RAMHT_SIZE_1 0x1FFF -#define NV3_RAMIN_RAMHT_SIZE_2 0x3FFF -#define NV3_RAMIN_RAMHT_SIZE_3 0x7FFF - -/* OBSOLETE AREA for AUDIO probably. DO NOT USE! */ -#define NV3_RAMIN_RAMAU_START 0x1C01000 -#define NV3_RAMIN_RAMAU_END 0x1C01BFF -#define NV3_RAMIN_RAMFC_START 0x1C01C00 // context for unused PFIFO DMA channels -#define NV3_RAMIN_RAMFC_END 0x1C01DFF -#define NV3_RAMIN_RAMFC_SIZE_0 0x1FF -#define NV3_RAMIN_RAMFC_SIZE_1 0xFFF -#define NV3_RAMIN_RAMRO_START 0x1C01E00 // Runout area for invalid submissions -#define NV3_RAMIN_RAMRO_SIZE_0 0x1FF -#define NV3_RAMIN_RAMRO_SIZE_1 0x1FFF -#define NV3_RAMIN_RAMRO_END 0x1C01FFF -#define NV3_RAMIN_RAMRM_START 0x1C02000 -#define NV3_RAMIN_RAMRM_END 0x1C02FFF - -// I'm not sure if this can be moved. -// 4K of "PRAM" is listed at 0x6000. -#define NV3_RAMIN_OFFSET_CURSOR 0x6000 - -#define NV3_RAMIN_END 0x1FFFFFF - -// not done - -// CRTC/CIO (0x3b0-0x3df) - -#define NV3_CRTC_REGISTER_INDEX_MONO 0x3B4 -#define NV3_CRTC_REGISTER_MONO 0x3B5 // Currently Selected CRTC Register - Monochrome - -#define NV3_CRTC_DATA_OUT 0x3C0 -#define NV3_CRTC_MISCOUT 0x3C2 - -#define NV3_RMA_REGISTER_START 0x3D0 -#define NV3_RMA_REGISTER_END 0x3D3 - -#define NV3_CRTC_REGISTER_INDEX 0x3D4 -#define NV3_CRTC_REGISTER_CURRENT 0x3D5 - -#define NV3_CRTC_REGISTER_WTF 0x3D8 - -// These are standard (0-18h) -#define NV3_CRTC_REGISTER_HTOTAL 0x00 -#define NV3_CRTC_REGISTER_HDISPEND 0x01 -#define NV3_CRTC_REGISTER_HBLANKSTART 0x02 -#define NV3_CRTC_REGISTER_HBLANKEND 0x03 -#define NV3_CRTC_REGISTER_HRETRACESTART 0x04 -#define NV3_CRTC_REGISTER_HRETRACEEND 0x05 -#define NV3_CRTC_REGISTER_VTOTAL 0x06 -#define NV3_CRTC_REGISTER_OVERFLOW 0x07 -#define NV3_CRTC_REGISTER_PRESETROWSCAN 0x08 -#define NV3_CRTC_REGISTER_MAXSCAN 0x09 -#define NV3_CRTC_REGISTER_CURSOR_START 0x0A -#define NV3_CRTC_REGISTER_CURSOR_START_DISABLED 5 -#define NV3_CRTC_REGISTER_CURSOR_END 0x0B -#define NV3_CRTC_REGISTER_STARTADDR_HIGH 0x0C -#define NV3_CRTC_REGISTER_STARTADDR_LOW 0x0D -#define NV3_CRTC_REGISTER_CURSORLOCATION_HIGH 0x0E -#define NV3_CRTC_REGISTER_CURSORLOCATION_LOW 0x0F -#define NV3_CRTC_REGISTER_VRETRACESTART 0x10 -#define NV3_CRTC_REGISTER_VRETRACEEND 0x11 -#define NV3_CRTC_REGISTER_VDISPEND 0x12 -#define NV3_CRTC_REGISTER_OFFSET 0x13 -#define NV3_CRTC_REGISTER_UNDERLINELOCATION 0x14 -#define NV3_CRTC_REGISTER_STARTVBLANK 0x15 -#define NV3_CRTC_REGISTER_ENDVBLANK 0x16 -#define NV3_CRTC_REGISTER_CRTCCONTROL 0x17 -#define NV3_CRTC_REGISTER_LINECOMP 0x18 -#define NV3_CRTC_REGISTER_STANDARDVGA_END 0x18 - - -// These are nvidia, licensed from weitek (25-63) -#define NV3_CRTC_REGISTER_RPC0 0x19 // 7:5 - [10:8] of CRTC. 4:0 - [20:16] of 21-bit display buffer address -#define NV3_CRTC_REGISTER_RPC1 0x1A // bit7=hsync enabled, bit6=vsync enabled, bit4="compatible text", bit2=large screen, bit1=6bit palette width (>1280) -#define NV3_CRTC_REGISTER_READ_BANK 0x1D -#define NV3_CRTC_REGISTER_WRITE_BANK 0x1E -#define NV3_CRTC_REGISTER_FORMAT 0x25 -#define NV3_CRTC_REGISTER_FORMAT_VDT10 0 // Use 10 bit vtotal value instead of 8 bit -#define NV3_CRTC_REGISTER_FORMAT_VDE10 1 // Use 10 bit dispend value instead of 8 bit -#define NV3_CRTC_REGISTER_FORMAT_VRS10 2 // Use 10 bit vblank start value instead of 8 bit -#define NV3_CRTC_REGISTER_FORMAT_VBS10 3 // Use 10 bit vsync start value instead of 8 bit -#define NV3_CRTC_REGISTER_FORMAT_HBE6 4 // Use 6 bit hsync start value -#define NV3_CRTC_REGISTER_PIXELMODE 0x28 - -#define NV3_CRTC_REGISTER_HEB 0x2D // HRS most significant bit - -#define NV3_CRTC_REGISTER_CURSOR_ADDR0 0x30 // Cursor high 21:16 -#define NV3_CRTC_REGISTER_CURSOR_ADDR1 0x31 // Cursor low (1:0 = enable) 15:11 - -#define NV3_CRTC_REGISTER_PIXELMODE_VGA 0x00 // vga textmode -#define NV3_CRTC_REGISTER_PIXELMODE_8BPP 0x01 -#define NV3_CRTC_REGISTER_PIXELMODE_16BPP 0x02 -#define NV3_CRTC_REGISTER_PIXELMODE_32BPP 0x03 - -#define NV3_CRTC_REGISTER_RL0 0x34 -#define NV3_CRTC_REGISTER_RL1 0x35 -#define NV3_CRTC_REGISTER_RMA 0x38 // REAL MODE ACCESS! -#define NV3_CRTC_REGISTER_I2C 0x3E -#define NV3_CRTC_REGISTER_I2C_GPIO 0x3F - -#define NV3_CRTC_BANKED_128K_A0000 0x00 -#define NV3_CRTC_BANKED_64K_A0000 0x04 -#define NV3_CRTC_BANKED_32K_B0000 0x08 -#define NV3_CRTC_BANKED_32K_B8000 0x0C - -#define NV3_CRTC_REGISTER_NVIDIA_END 0x3F - -// for 86box 8bit addressing -// get rid of this asap, replace with 32->8 macros -#define NV3_RMA_SIGNATURE_MSB 0x65 -#define NV3_RMA_SIGNATURE_BYTE2 0xD0 -#define NV3_RMA_SIGNATURE_BYTE1 0x16 -#define NV3_RMA_SIGNATURE_LSB 0x2B - -#define NV3_CRTC_REGISTER_RMA_MODE_MAX 0x0F - -/* - STRUCTURES FOR THE GPU START HERE - OBJECT CLASS & RENDERING RELATED STUFF IS IN VID_NV3_CLASSES.H -*/ - -//todo: pixel format - -// Master Control -typedef struct nv3_pmc_s -{ - /* - Holds chip manufacturing information at bootup. - Current specification (may change later): pre-packed for convenience - - Revision A: - FIB Revision 1, Mask Revision B0, Implementation 1 [NV3], Architecture 3 [NV3], Manufacturer Nvidia, Foundry SGS (seems to have been the most common?) - 31:28=0000, 27:24=0000, 23:16=0003, 15:8=0001, 7:4=0001, 3:0=0001 - little endian 00000000 00000011 00000001 00010001 = 0x00300111# - Revision B/c: - write this later - */ - int32_t boot; - int32_t interrupt_status; // Determines if interrupts are pending for specific subsystems. - int32_t interrupt_enable; // Determines if interrupts are actually enabled. - int32_t enable; // Determines which subsystems are enabled. - -} nv3_pmc_t; - -// add enums for eac -// Chip configuration -typedef struct nv3_straps_s -{ - uint32_t straps; -} nv3_straps_t; - -// Framebuffer -typedef struct nv3_pfb_s -{ - uint32_t boot; - uint32_t debug_0; // debug stuff - uint32_t config_0; // Framebuffer width, etc. - uint32_t config_1; - uint32_t green; - uint32_t delay; - uint32_t rtl; // Part of the memory timings -} nv3_pfb_t; - -// -// DMA & Notifier Engine -// All singing all dancing all happy happy bullshit to send dma transfers literally anywhere in your computer -// - -// Not a notification status, because it's a 16-bit enum -// C23 fixes this -#define NV3_NOTIFICATION_STATUS_DONE_OK 0x0 -#define NV3_NOTIFICATION_STATUS_IN_PROGRESS 0xFF -#define NV3_NOTIFICATION_STATUS_ERROR 0x100 - -#define NV3_NOTIFICATION_INFO_ADJUST 0 // Wut -#define NV3_NOTIFICATION_PT_PRESENT 16 // Determines if the pagetable exists. -#define NV3_NOTIFICATION_TARGET 24 // Determines where this notification goes -#define NV3_DMA_TARGET_NODE_VRAM 0 // VRAM target for DMA -#define NV3_DMA_TARGET_NODE_CART 1 // "Cartridge" target for dma, only mentioned in a few places, !!! NV2 LEFTOVER !!! -#define NV3_DMA_TARGET_NODE_PCI 2 // Send the data to the host system over PCI -#define NV3_DMA_TARGET_NODE_AGP 3 // Send the data to the host system over AGP - -#define NV3_NOTIFICATION_PAGE_IS_PRESENT 0 // Determines if the page really exists -#define NV3_NOTIFICATION_PAGE_ACCESS 1 // Determines the page access type -#define NV3_NOTIFICATION_PAGE_ACCESS_READ 0x0 // If this is set, the page is read only -#define NV3_NOTIFICATION_PAGE_ACCESS_READ_WRITE 0x1 // If this is set, the page is read/write -#define NV3_NOTIFICATION_PAGE_FRAME_ADDRESS 12 // The pageframe to use - - - -// Core notification structure -typedef struct nv3_notification_s -{ - uint64_t nanoseconds; - uint32_t info32; - uint16_t info16; - uint16_t status; -} nv3_notification_t; - -#define NV3_RMA_NUM_REGS 4 -// Access the GPU from real-mode -typedef struct nv3_pbus_rma_s -{ - uint32_t addr; // Address to RMA to - uint32_t data; // Data to send to MMIO - uint8_t mode; // the current state of the rma shifting engin - uint8_t rma_regs[NV3_RMA_NUM_REGS]; // The rma registers (saved) -} nv3_pbus_rma_t; - -// Bus Configuration -typedef struct nv3_pbus_s -{ - uint32_t debug_0; - uint32_t interrupt_status; // Interrupt status - uint32_t interrupt_enable; // Interrupt enable - nv3_pbus_rma_t rma; -} nv3_pbus_t; - -typedef struct nv3_pfifo_cache_s -{ - bool push0; // 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. - uint32_t status; - uint32_t pull0; - uint32_t context[NV3_DMA_SUBCHANNELS_PER_CHANNEL]; // Only one of these exists for cache0 - - /* cache1 only - do we even need to emulate this? - */ - uint32_t dma_status; // 0x3218 - bool dma_enabled; // 0x3220 bit0 - bool dma_is_busy; // 0x3220 bit4 - - uint32_t dma_state; // Corresponds to PFIFO_CACHE1_DMA0 - uint32_t dma_length; // Corresponds to PFIFO_CACHE1_DMA1 - uint32_t dma_address; // Corresponds to PFIFO_CACHE1_DMA2 - uint8_t dma_target_node; // Corresponds to PFIFO_CACHE1_DMA3 depends on card bus - uint8_t dma_tlb_tag; - uint8_t dma_tlb_pte; // DMA Engine - Translation Lookaside Buffer - uint8_t dma_tlb_pt_base; // DMA Engine - TLB Pagetable Base Addres - uint16_t method_address; // address of the method (i.e. what method it is) - uint16_t method_subchannel; // subchannel - bool context_is_dirty; - - /* TODO */ -} nv3_pfifo_cache_t; - -typedef struct nv3_pfifo_cache_entry_s -{ - uint16_t method; // method id depending on class (offset from entry channel start in ramin) - uint8_t subchannel; - uint32_t data; // is this the context - -} nv3_pfifo_cache_entry_t; - -// Command submission to PGRAPH -typedef struct nv3_pfifo_s -{ - uint32_t interrupt_status; // Interrupt status - uint32_t interrupt_enable; // Interrupt enable - uint32_t dma_delay_retry; // DMA Delay/Retry - uint32_t debug_0; // Cache Debug register - uint32_t config_0; - uint32_t ramht_config; // RAMHT config - uint32_t ramfc_config; // RAMFC config - uint32_t ramro_config; // RAMRO config - // Runout stuff - uint32_t runout_put; // 8:3 if RAMRO=512b, otherwise 12:3 - uint32_t runout_get; // 8:3 if RAMRO=512b, otherwise 12:3 - - // Cache stuff - uint32_t cache_reassignment; // Allow context switching - nv3_pfifo_cache_t cache0_settings; - nv3_pfifo_cache_t cache1_settings; - - nv3_pfifo_cache_entry_t cache0_entry; // It only has 1 entry - nv3_pfifo_cache_entry_t cache1_entries[NV3_PFIFO_CACHE1_SIZE_MAX]; // ONLY 32 USED ON REVISION A/B CARDS -} nv3_pfifo_t; - -// RAMDAC -typedef struct nv3_pramdac_s -{ - // these should be uint8_t but C math is a lot better with this - uint32_t memory_clock_m; // memory clock M-divider - uint32_t memory_clock_n; // memory clock N-divider - uint32_t memory_clock_p; // memory clock P-divider - uint32_t pixel_clock_m; // pixel clock M-divider - uint32_t pixel_clock_n; // pixel clock N-divider - uint32_t pixel_clock_p; // pixel clock P-divider - uint32_t coeff_select; // coefficient select - - uint32_t general_control; // general control register - - // this could duplicate SVGA state but I tihnk it's more readable, - // we'll just modify both - uint32_t vserr_width; // vertical sync error width - uint32_t vequ_end; // vequ end (not sure what this is) - uint32_t vbblank_end; // vbblank end (not sure what this is) - uint32_t vblank_end; // vblank end - uint32_t vblank_start; // vblank start - uint32_t vequ_start; // vequ start (not sure what this is) - uint32_t vtotal; // vertical total lines - uint32_t hsync_width; // horizontal sync width - uint32_t hburst_start; // horizontal burst signal start (in lines) - uint32_t hburst_end; // horizontal burst signal end (in lines) - uint32_t hblank_start; // horizontal blank start (in lines) - uint32_t hblank_end; // horizontal blank end (in lines) - uint32_t htotal; // horizontal total lines - uint32_t hequ_width; // horizontal equ width (not sure what this is) - uint32_t hserr_width; // horizontal sync error width - - uint8_t user_pixel_mask; // pixel mask for DAC lookup - uint32_t user_read_mode_address; // user read mode address - uint32_t user_write_mode_address; // user write mode address - uint8_t palette[NV3_USER_DAC_PALETTE_SIZE]; // Palette Info/CLUT - 256 entries, 1 byte for r,g,b = 768 bytes - - uint32_t cursor_address; // cursor address start - nv3_coord_16_t cursor_start; -} nv3_pramdac_t; - -/* Holds DMA channel context information */ -typedef struct NV3_PGRAPH_CTX_SWITCH_s -{ - /* TODO */ -} NV3_PGRAPH_CTX_SWITCH_t; - -typedef struct nv3_pgraph_context_control_s -{ - /* TODO */ -} nv3_pgraph_context_control_t; - -/* DMA object context info - Context uploaded from CACHE0/CACHE1 by DMA Puller -*/ -typedef struct nv3_pgraph_context_user_s -{ - union - { - uint32_t value; - - struct - { - bool reserved3 : 1; - uint8_t channel : 7; - uint8_t reserved2 : 3; - uint8_t class_id : 5; - uint8_t subchannel : 3; - uint16_t reserved : 13; - }; - }; -} nv3_pgraph_context_user_t; - -typedef struct nv3_pgraph_dma_settings_s -{ - /* TODO */ -} nv3_pgraph_dma_settings_t; - -typedef struct nv3_pgraph_clip_misc_settings_s -{ - /* TODO */ -} nv3_pgraph_clip_misc_settings_t; - -typedef struct nv3_pgraph_status_s -{ - bool overall_busy : 1; // Is anything busy? - uint8_t reserved : 3; - bool xy_logic_busy : 1; // Determines if the line drawing/xy/vector stuff is busy. - uint8_t reserved2 : 3; - bool port_notify_busy : 1; // Mediaport?/PIO? notifier engine busy - uint8_t reserved3 : 3; - bool port_register_busy : 1; - uint8_t reserved4 : 3; - bool port_dma_busy : 1; // Mediaport?/PIO? DMA engine busy - bool dma_engine_busy : 1; // DMA engine busy - uint8_t reserved5 : 2; - bool dma_notify_busy : 1; // Are the notifiers busy? - uint8_t reserved6 : 3; - bool engine_3d_busy : 1; // 3d engine busy? - bool engine_cache_busy : 1; // PFIFO CACHE0/CACHE1 busy? - bool engine_zfifo_busy : 1; // ZFIFO (zeta buffer? z buffer?) busy? - bool port_user_busy : 1; // User context switch? - uint8_t reserved7 : 3; - -} nv3_pgraph_status_t; - -/* All of this B* stuff is registers at 400630..40065c and 4006a8 in reality, easier to implement it like this - BPixel = Buffer Pixel Format -*/ -#define NV3_BPIXEL_FORMAT 0 -#define NV3_BPIXEL_FORMAT_IS_VALID 2 -#define NV3_BPIXEL_DEPTH 4 - -typedef enum nv3_pgraph_bpixel_format_e -{ - // Y16 - bpixel_fmt_y16 = 0, - // 8-bit colour - bpixel_fmt_8bit = 1, - // 16-bit colour - bpixel_fmt_16bit = 2, - // 32-bit colour (ARGB) - bpixel_fmt_32bit = 3, -} nv3_pgraph_bpixel_format; - -typedef enum nv3_pgraph_destination_buffer_e -{ - pgraph_dest_buffer0 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER0_ENABLED), - pgraph_dest_buffer1 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER1_ENABLED), - pgraph_dest_buffer2 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER2_ENABLED), - pgraph_dest_buffer3 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER3_ENABLED), -} nv3_pgraph_destination_buffer; - -// Graphics Subsystem -typedef struct nv3_pgraph_s -{ - uint32_t debug_0; - uint32_t debug_1; - uint32_t debug_2; - uint32_t debug_3; - uint32_t interrupt_status_0; // Interrupt status 0 - uint32_t interrupt_enable_0; // Interrupt enable 0 - uint32_t interrupt_status_1; // Interrupt status 1 - uint32_t interrupt_enable_1; // Interrupt enable 1 - uint32_t interrupt_status_dma; // Interrupt status for DMA - uint32_t interrupt_enable_dma; // Interrupt enable for DMA - - uint32_t context_switch; // TODO: Make this a struct, it's just going to be enormous lol. - nv3_pgraph_context_control_t context_control; - NV3_PGRAPH_CTX_SWITCH_t context_user_submit; - nv3_pgraph_context_user_t context_user; - uint32_t context_cache[NV3_PGRAPH_CONTEXT_CACHE_SIZE]; // DMA context cache (nv3_pgraph_context_user_t array?) - - // UCLIP stuff - uint32_t abs_uclip_xmin; - uint32_t abs_uclip_xmax; - uint32_t abs_uclip_ymin; - uint32_t abs_uclip_ymax; - // Canvas stuff - nv3_coord_16_bigy_t src_canvas_min; - nv3_coord_16_bigy_t src_canvas_max; - nv3_coord_16_bigy_t dst_canvas_min; - nv3_coord_16_bigy_t dst_canvas_max; - // Pattern stuff - nv3_color_expanded_t pattern_color_0_rgb; // ignore alpha - uint32_t pattern_color_0_alpha; // only 7:0 relevant - nv3_color_expanded_t pattern_color_1_rgb; // ignore alpha - uint32_t pattern_color_1_alpha; // only 7:0 relevant - uint64_t pattern_bitmap; // pattern bitmap for blit. it's alwaus 64 bits to simplify pixel rendering code - uint32_t pattern_shape; // may need to be an enum - 0=8x8, 1=64x1, 2=1x64 - uint32_t plane_mask; // only 7:0 relevant - uint32_t chroma_key; // color key - uint32_t beta_factor; - nv3_pgraph_dma_settings_t dma_settings; - uint8_t rop; // Current GDI Ternary Render Operation - // SURFACE STUFF - PGRAPH CAN OPERATE ON 4 SURFACES/BUFFERS AT A TIME - uint32_t boffset[NV3_PGRAPH_MAX_BUFFERS]; // 22-bit linear VRAM offset for the start of a buffer. - uint16_t bpitch[NV3_PGRAPH_MAX_BUFFERS]; // 12-bit linear VRAM offset for the pitch of a buffer - uint32_t bpixel[NV3_PGRAPH_MAX_BUFFERS]; // Pixel format for each possible surfaces. - // CLIP - nv3_pgraph_clip_misc_settings_t clip_misc_settings; - uint32_t notifier; - bool notify_pending; // Determines if a notification is pending. - /* Are these even used */ - nv3_coord_16_bigy_t clip0_min; - nv3_coord_16_bigy_t clip0_max; - nv3_coord_16_bigy_t clip1_min; - nv3_coord_16_bigy_t clip1_max; - /* idk */ - nv3_coord_16_t clip_start; // Start of the clipping region - nv3_coord_16_t clip_size; // Size of the clipping region. - bool fifo_access; // Determines if PGRAPH can access PFIFO. - nv3_pgraph_status_t status; // Current status of the 3D engine. - uint32_t trapped_address; - uint32_t trapped_data; - uint32_t instance; // no idea what this is but possibly an object context - uint32_t trapped_instance; - uint8_t dpram[NV3_PGRAPH_DPRAM_SIZE]; // Internal vertex/texturea cache. - - /* This area is used for holding universal representations of the U* registers, which are actually mapped into MMIO */ - struct nv3_object_class_001 beta_factor_class; - struct nv3_object_class_002 rop_class; - struct nv3_object_class_003 chroma_key_class; - struct nv3_object_class_004 plane_mask_class; - struct nv3_object_class_005 clipping_rectangle; - struct nv3_object_class_006 pattern; - struct nv3_object_class_007 rectangle; - struct nv3_object_class_008 point; - struct nv3_object_class_009 line; - struct nv3_object_class_00A lin; - struct nv3_object_class_00B triangle; - struct nv3_object_class_00C win95_gdi_text; - /* These are here so we can hold the current state of the image draw */ - uint32_t win95_gdi_text_bit_count; - nv3_coord_16_t win95_gdi_text_current_position; - struct nv3_object_class_00D m2mf; - struct nv3_object_class_00E scaled_image_from_memory; - struct nv3_object_class_010 blit; - struct nv3_object_class_011 image; - nv3_coord_16_t image_current_position; /* This is here so we can hold the current state of the image */ - struct nv3_object_class_012 bitmap; - struct nv3_object_class_014 transfer2memory; - struct nv3_object_class_015 stretched_image_from_cpu; - struct nv3_object_class_017 d3d5_tri; - struct nv3_object_class_018 point_zeta_buffer; - struct nv3_object_class_01C image_in_memory; -} nv3_pgraph_t; - - -// GPU Manufacturing Configuration (again) -// In the future this will be configurable -typedef struct nv3_pextdev_s -{ - /* - // Disabled 33Mhz - // Enabled 66Mhz - bool bus_speed; - - // Disabled No BIOS - // Enabled BIOS - bool bios; - - // RAM Type #1 - // Disabled 16Mbit (2MB) module size - // Enabled 8Mbit (1MB) module size - bool ram_type_1; - - // NEC Mode - bool nec_mode; - - // Disabled 64-bit - // Enabled 128-bit - bool bus_width; - - // Disabled PCI - // Enabled AGP - bool bus_type; - - // Disabled 13500 - // Enabled 14318180 - bool crystal; - - // TV Mode - // 0 - SECAM, 1 - NTSC, 2 - PAL, 3 - none - uint8_t tv_mode; - - // AGP 2X mode - // Disabled AGP 1X - // Enabled AGP 2X - bool agp_is_2x; - - bool unused; - - // Overwrite enable - bool overwrite; - - See defines in vid_nv3.h - */ - uint32_t straps; - - // more ram type stuff here but not used? -} nv3_pextdev_t; - -typedef struct nv3_ptimer_s -{ - uint32_t interrupt_status; // PTIMER Interrupt status - uint32_t interrupt_enable; // PTIMER Interrupt enable - uint32_t clock_numerator; // PTIMER (tick?) numerator - uint32_t clock_denominator; // PTIMER (tick?) denominator - uint64_t time; // time - uint32_t alarm; // The value of time when there should be an alarm -} nv3_ptimer_t; - -// Object name is just a uint32_t identifier it doesn't need a struct -// This is how the context is represented in ramin -// IN PGRAPH IT IS DIFFERENT! ONLY 5 BITS FOR THE CLASS ID! WHY? -typedef struct nv3_ramin_context_s -{ - union - { - uint32_t context; - - struct - { - uint16_t ramin_offset; - uint8_t class_id : 7; - bool is_rendering : 1; - uint8_t channel : 7; - bool reserved : 1; - }; - }; -} nv3_ramin_context_t; - -// Graphics object hashtable for specific DMA [channel, subchannel] pair -typedef struct nv3_ramin_ramht_subchannel_s -{ - uint32_t name; // must be >4096 - - // Contextual information. - // See the above union. - nv3_ramin_context_t context; -} nv3_ramin_ramht_subchannel_t; - -// Graphics object hashtable -typedef struct nv3_ramin_ramht_s -{ - nv3_ramin_ramht_subchannel_t subchannels[NV3_DMA_CHANNELS][NV3_DMA_SUBCHANNELS_PER_CHANNEL]; -} nv3_ramin_ramht_t; - - -typedef enum nv3_ramin_ramro_reason_e -{ - nv3_runout_reason_illegal_access = 0, - - // PFIFO CACHE0/CACHE1 were turned off, so the graphics object could not be processed. - nv3_runout_reason_no_cache_available = 1, - - // Ran out of CACHE0 & CACHE1 space. - nv3_runout_reason_cache_ran_out = 2, - - nv3_runout_reason_free_count_overrun = 3, - - nv3_runout_reason_caught_lying = 4, - - // Access reserved by pagetable - nv3_runout_reason_reserved_access = 5, - -} nv3_ramin_ramro_reason; - -// context for unused channels -typedef struct nv3_ramin_ramfc_s -{ - -} nv3_ramin_ramfc_t; - -// RAM for AUDIO - RevisionA ONLY -typedef struct nv_ramin_ramau_s -{ - -} nv3_ramin_ramau_t; - -typedef struct nv3_ramin_s -{ - -} nv3_ramin_t; - - -typedef struct nv3_pvideo_s -{ - uint32_t interrupt_status; // Interrupt status - uint32_t interrupt_enable; // Interrupt enable - uint32_t fifo_threshold; // FIFO threshold - uint32_t fifo_burst_size; // FIFO burst size - uint32_t overlay_settings; // Overlay settings -} nv3_pvideo_t; - -typedef struct nv3_pme_s // Mediaport -{ - uint32_t interrupt_status; - uint32_t interrupt_enable; -} nv3_pme_t; - -typedef struct nv3_s -{ - nv_base_t nvbase; // Base Nvidia structure - - // Config - nv3_straps_t straps; // OEM Configuration - - // Subsystems - nv3_pmc_t pmc; // Master Control - nv3_pfb_t pfb; // Framebuffer/VRAM - nv3_pbus_t pbus; // Bus Control - nv3_pfifo_t pfifo; // FIFO for command submission - - nv3_pramdac_t pramdac; // RAMDAC (CLUT etc) - nv3_pgraph_t pgraph; // 2D/3D Graphics - nv3_pextdev_t pextdev; // Chip configuration - nv3_ptimer_t ptimer; // programmable interval timer - nv3_ramin_ramht_t ramht; // hashtable for PGRAPH objects - // (ramro does not need a struct) - nv3_ramin_ramfc_t ramfc; // context for unused channels - nv3_ramin_ramau_t ramau; // auxillary weirdnes - nv3_ramin_t pramin; // INstance memory for graphics objects. Very important! - nv3_pvideo_t pvideo; // Video overlay - nv3_pme_t pme; // Mediaport - external MPEG decoder and video interface - //more here - -} nv3_t; - -// device object -extern nv3_t* nv3; - -/* - *FUNCTIONS* for the GPU core start here - Functions for PGRAPH objects are in vid_nv3_classes.h -*/ - -// Device Core -void* nv3_init(const device_t *info); -void nv3_close(void* priv); -void nv3_speed_changed(void *priv); -void nv3_draw_cursor(svga_t* svga, int32_t drawline); -void nv3_recalc_timings(svga_t* svga); -void nv3_force_redraw(void* priv); - -/* BAR0 GPU MMIO read */ -void nv3_update_mappings(void); // Update memory mappings -uint8_t nv3_mmio_read8(uint32_t addr, void* priv); // Read 8-bit MMIO -uint16_t nv3_mmio_read16(uint32_t addr, void* priv); // Read 16-bit MMIO -uint32_t nv3_mmio_read32(uint32_t addr, void* priv); // Read 32-bit MMIO -void nv3_mmio_write8(uint32_t addr, uint8_t val, void* priv); // Write 8-bit MMIO -void nv3_mmio_write16(uint32_t addr, uint16_t val, void* priv); // Write 16-bit MMIO -void nv3_mmio_write32(uint32_t addr, uint32_t val, void* priv); // Write 32-bit MMIO - -/* BAR1 Dumb Framebuffer Read */ -uint8_t nv3_dfb_read8(uint32_t addr, void* priv); // Write 8-bit DFB -uint16_t nv3_dfb_read16(uint32_t addr, void* priv); // Write 16-bit DFB -uint32_t nv3_dfb_read32(uint32_t addr, void* priv); // Write 32-bit DFB -void nv3_dfb_write8(uint32_t addr, uint8_t val, void* priv); // Write 8-bit DFB -void nv3_dfb_write16(uint32_t addr, uint16_t val, void* priv); // Write 16-bit DFB -void nv3_dfb_write32(uint32_t addr, uint32_t val, void* priv); // Write 32-bit DFB - -uint8_t nv3_svga_read(uint16_t addr, void* priv); // Read SVGA compatibility registers -void nv3_svga_write(uint16_t addr, uint8_t val, void* priv); // Write SVGA registers -uint8_t nv3_pci_read(int32_t func, int32_t addr, void* priv); // Read PCI configuration registers -void nv3_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv); // Write PCI configuration registers - -uint8_t nv3_ramin_read8(uint32_t addr, void* priv); // Read 8-bit RAMIN -uint16_t nv3_ramin_read16(uint32_t addr, void* priv); // Read 16-bit RAMIN -uint32_t nv3_ramin_read32(uint32_t addr, void* priv); // Read 32-bit RAMIN -void nv3_ramin_write8(uint32_t addr, uint8_t val, void* priv); // Write 8-bit RAMIN -void nv3_ramin_write16(uint32_t addr, uint16_t val, void* priv); // Write 16-bit RAMIN -void nv3_ramin_write32(uint32_t addr, uint32_t val, void* priv); // Write 32-bit RAMIN - -bool nv3_ramin_arbitrate_read(uint32_t address, uint32_t* value); // Read arbitration so we can read/write to the structures in the first 64k of ramin -bool nv3_ramin_arbitrate_write(uint32_t address, uint32_t value); // Write arbitration so we can read/write to the structures in the first 64k of ramin - -// RAMIN functions -uint32_t nv3_ramht_hash(uint32_t name, uint32_t channel); -bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel_id, uint8_t subchannel_id); -#ifndef RELEASE_BUILD -void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context); -#endif - -uint32_t nv3_ramfc_read(uint32_t address); -void nv3_ramfc_write(uint32_t address, uint32_t value); -uint32_t nv3_ramro_read(uint32_t address); -void nv3_ramro_write(uint32_t address, uint32_t value); -uint32_t nv3_ramht_read(uint32_t address); -void nv3_ramht_write(uint32_t address, uint32_t value); - -// MMIO Arbitration -// Determine where the hell in this mess our reads or writes are going -uint32_t nv3_mmio_arbitrate_read(uint32_t address); -void nv3_mmio_arbitrate_write(uint32_t address, uint32_t value); - -// Read and Write functions for GPU subsystems -// Remove the ones that aren't used here eventually, have all of htem for now -uint32_t nv3_pmc_read(uint32_t address); -void nv3_pmc_write(uint32_t address, uint32_t value); -uint32_t nv3_cio_read(uint32_t address); -void nv3_cio_write(uint32_t address, uint32_t value); -uint32_t nv3_pbus_read(uint32_t address); -void nv3_pbus_write(uint32_t address, uint32_t value); -uint32_t nv3_prm_read(uint32_t address); -void nv3_prm_write(uint32_t address, uint32_t value); -uint32_t nv3_prmio_read(uint32_t address); -void nv3_prmio_write(uint32_t address, uint32_t value); -uint32_t nv3_ptimer_read(uint32_t address); -void nv3_ptimer_write(uint32_t address, uint32_t value); -uint32_t nv3_pfb_read(uint32_t address); -void nv3_pfb_write(uint32_t address, uint32_t value); -uint32_t nv3_pextdev_read(uint32_t address); -void nv3_pextdev_write(uint32_t address, uint32_t value); - -// Special consideration for straps -#define nv3_pstraps_read nv3_pextdev_read(NV3_PSTRAPS) -#define nv3_pstraps_write(x) nv3_pextdev_write(NV3_PSTRAPS, x) - -// Reads from vbios are 8bit -uint8_t nv3_prom_read(uint32_t address); -void nv3_prom_write(uint32_t address, uint32_t value); -uint32_t nv3_palt_read(uint32_t address); -void nv3_palt_write(uint32_t address, uint32_t value); -uint32_t nv3_pme_read(uint32_t address); -void nv3_pme_write(uint32_t address, uint32_t value); - -// TODO: PGRAPH class registers - -uint32_t nv3_prmcio_read(uint32_t address); -void nv3_prmcio_write(uint32_t address, uint32_t value); -uint32_t nv3_pvideo_read(uint32_t address); -void nv3_pvideo_write(uint32_t address, uint32_t value); -uint32_t nv3_pramdac_read(uint32_t address); -void nv3_pramdac_write(uint32_t address, uint32_t value); - -uint32_t nv3_user_read(uint32_t address); -void nv3_user_write(uint32_t address, uint32_t value); -#define nv3_object_submit_start nv3_user_read -#define nv3_object_submit_end nv3_user_write -// TODO: RAMHT, RAMFC...or maybe handle it inside of nv3_ramin_* - -// GPU subsystems - -// NV3 PMC -void nv3_pmc_init(void); -void nv3_pmc_clear_interrupts(void); -uint32_t nv3_pmc_handle_interrupts(bool send_now); - -// NV3 PGRAPH -void nv3_pgraph_init(void); -uint32_t nv3_pgraph_read(uint32_t address); -void nv3_pgraph_write(uint32_t address, uint32_t value); -void nv3_pgraph_vblank_start(svga_t* svga); -void nv3_pgraph_interrupt_valid(uint32_t num); -void nv3_pgraph_interrupt_invalid(uint32_t num); -void nv3_pgraph_submit(uint32_t param, uint16_t method, uint8_t channel, uint8_t subchannel, uint8_t class_id, nv3_ramin_context_t context); - -// PGRAPH class methods -// this should be in "vid_nv3_classes.h", but before that can happen, some things need to be rejigged -void nv3_generic_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_001_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_002_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_003_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_004_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_005_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_006_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_007_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_008_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_009_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_00a_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_00b_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_00c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_00d_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_00e_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_010_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_011_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_012_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_014_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_015_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_017_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_018_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); -void nv3_class_01c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj); - -// Notification Engine -void nv3_notify_if_needed(uint32_t name, uint32_t method_id, nv3_ramin_context_t context,nv3_grobj_t grobj); - -// NV3 PFIFO -void nv3_pfifo_init(void); -uint32_t nv3_pfifo_read(uint32_t address); -void nv3_pfifo_write(uint32_t address, uint32_t value); -void nv3_pfifo_interrupt(uint32_t id, bool fire_now); - -// NV3 PFIFO - Caches -//cache0_push not a thing -void nv3_pfifo_cache0_pull(void); -void nv3_pfifo_cache1_push(uint32_t addr, uint32_t val); -void nv3_pfifo_cache1_pull(void); -uint32_t nv3_pfifo_cache1_normal2gray(uint32_t val); -uint32_t nv3_pfifo_cache1_gray2normal(uint32_t val); -uint32_t nv3_pfifo_cache1_num_free_spaces(void); - -// NV3 PFB -void nv3_pfb_init(void); - -// NV3 PEXTDEV/PSTRAPS -void nv3_pextdev_init(void); - -// NV3 PBUS -void nv3_pbus_init(void); - -// NV3 PBUS RMA - Real Mode Access for VBIOS -uint8_t nv3_pbus_rma_read(uint16_t addr); -void nv3_pbus_rma_write(uint16_t addr, uint8_t val); - -// NV3 PRAMDAC (Final presentation) -void nv3_pramdac_init(void); -void nv3_pramdac_set_vram_clock(void); -void nv3_pramdac_set_pixel_clock(void); -void nv3_pramdac_pixel_clock_poll(double real_time); -void nv3_pramdac_memory_clock_poll(double real_time); - -// NV3 PTIMER -void nv3_ptimer_init(void); -void nv3_ptimer_tick(double real_time); - -// NV3 PVIDEO -void nv3_pvideo_init(void); - -// NV3 PME (Mediaport) -void nv3_pme_init(void); \ No newline at end of file diff --git a/src/include/86box/nv/vid_nv4.h b/src/include/86box/nv/vid_nv4.h deleted file mode 100644 index 0f2aad285..000000000 --- a/src/include/86box/nv/vid_nv4.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Riva TNT hardware defines - * - * Authors: Connor Hyde - * - * Copyright 2024-2025 Connor Hyde - */ - - -#pragma once - -#include -#include -#include <86Box/nv/vid_nv4_defines.h> - -// -// Structures -// - - -// PBUS -// RMA: Access the GPU from real-mode -typedef struct nv4_pbus_rma_s -{ - uint32_t addr; // Address to RMA to - uint32_t data; // Data to send to MMIO - uint8_t mode; // the current state of the rma shifting engin - uint8_t rma_regs[NV4_RMA_NUM_REGS]; // The rma registers (saved) -} nv4_pbus_rma_t; - -// Bus Configuration -typedef struct nv4_pbus_s -{ - uint32_t debug_0; - uint32_t interrupt_status; // Interrupt status - uint32_t interrupt_enable; // Interrupt enable - nv4_pbus_rma_t rma; -} nv4_pbus_t; - - -// PTIMER -typedef struct nv4_ptimer_s -{ - uint32_t interrupt_status; // PTIMER Interrupt status - uint32_t interrupt_enable; // PTIMER Interrupt enable - uint32_t clock_numerator; // PTIMER (tick?) numerator - uint32_t clock_denominator; // PTIMER (tick?) denominator - uint64_t time; // time - uint32_t alarm; // The value of time when there should be an alarm -} nv4_ptimer_t; - -// PRAMDAC -typedef struct nv4_pramdac_s -{ - uint32_t mclk; - uint32_t vclk; - uint32_t nvclk; - uint32_t clk_coeff_select; // Clock coefficient selection - uint32_t cursor_address; -} nv4_pramdac_t; - -// Device Core -typedef struct nv4_s -{ - nv_base_t nvbase; // Base Nvidia structure - uint32_t straps; // Straps. See defines - nv4_pbus_t pbus; - nv4_ptimer_t ptimer; - nv4_pramdac_t pramdac; -} nv4_t; - -// -// Globals -// - -extern const device_config_t nv4_config[]; - -extern nv4_t* nv4; // Allocated at device startup - -#ifdef NV_LOG - -// Debug register list -extern nv_register_t nv4_registers[]; - -#endif - -// -// Functions -// - -// Device Core -bool nv4_init(); - -void* nv4_init_stb4400(const device_t* info); - -void nv4_close(void* priv); -void nv4_speed_changed(void *priv); -void nv4_draw_cursor(svga_t* svga, int32_t drawline); -void nv4_recalc_timings(svga_t* svga); -void nv4_force_redraw(void* priv); - -// I/O -uint8_t nv4_mmio_read8(uint32_t addr, void* priv); -uint16_t nv4_mmio_read16(uint32_t addr, void* priv); -uint32_t nv4_mmio_read32(uint32_t addr, void* priv); -void nv4_mmio_write8(uint32_t addr, uint8_t val, void* priv); -void nv4_mmio_write16(uint32_t addr, uint16_t val, void* priv); -void nv4_mmio_write32(uint32_t addr, uint32_t val, void* priv); -uint8_t nv4_dfb_read8(uint32_t addr, void* priv); -uint16_t nv4_dfb_read16(uint32_t addr, void* priv); -uint32_t nv4_dfb_read32(uint32_t addr, void* priv); -void nv4_dfb_write8(uint32_t addr, uint8_t val, void* priv); -void nv4_dfb_write16(uint32_t addr, uint16_t val, void* priv); -void nv4_dfb_write32(uint32_t addr, uint32_t val, void* priv); -uint8_t nv4_ramin_read8(uint32_t addr, void* priv); -uint16_t nv4_ramin_read16(uint32_t addr, void* priv); -uint32_t nv4_ramin_read32(uint32_t addr, void* priv); -void nv4_ramin_write8(uint32_t addr, uint8_t val, void* priv); -void nv4_ramin_write16(uint32_t addr, uint16_t val, void* priv); -void nv4_ramin_write32(uint32_t addr, uint32_t val, void* priv); -uint8_t nv4_pci_read(int32_t func, int32_t addr, void* priv); -void nv4_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv); - -// SVGA -uint8_t nv4_svga_read(uint16_t addr, void* priv); -void nv4_svga_write(uint16_t addr, uint8_t val, void* priv); - -// Memory -void nv4_update_mappings(); - -// PRAMDAC -uint32_t nv4_pramdac_read(uint32_t address); -void nv4_pramdac_write(uint32_t address, uint32_t data); - -// We don't implement NVCLK/VCLK because they are too fast -void nv4_pramdac_set_vclk(); - -void nv4_vclk_tick(); - -// PTIMER -uint32_t nv4_ptimer_read(uint32_t address); -void nv4_ptimer_write(uint32_t address, uint32_t data); \ No newline at end of file diff --git a/src/include/86box/nv/vid_nv4_defines.h b/src/include/86box/nv/vid_nv4_defines.h deleted file mode 100644 index 2a959670c..000000000 --- a/src/include/86box/nv/vid_nv4_defines.h +++ /dev/null @@ -1,4291 +0,0 @@ -#pragma once - -#include -#include - -// -// General -// -#define NV4_VRAM_SIZE_2MB 0x200000 // 2MB (never used; NV4 only) -#define NV4_VRAM_SIZE_4MB 0x400000 // 4MB (never used) -#define NV4_VRAM_SIZE_8MB 0x800000 // 8MB -#define NV4_VRAM_SIZE_16MB 0x1000000 // 16MB -#define NV5_VRAM_SIZE_32MB 0x2000000 // NV5 only - -#define NV4_MMIO_SIZE 0x1000000 // not sure. May be larger!!!! - -// -// VBIOS -// -#define NV4_VBIOS_STB_REVA "roms/video/nvidia/nv4/NV4_STB_velocity.rom" - -#define NV4_PRMIO_START 0x7000 -#define NV4_PRMIO_END 0x7FFF - -// NV4 Legacy I/O space -#define NV4_RMA_REGISTER_START 0x3D0 -#define NV4_RMA_REGISTER_END 0x3D3 -#define NV4_RMA_NUM_REGS 4 - -#define NV4_PRMIO_RMA_ID 0x7100 -#define NV4_PRMIO_RMA_ID_CODE 0 -#define NV4_PRMIO_RMA_ID_CODE_VALID 0x2B16D065 -#define NV4_PRMIO_RMA_PTR 0x7104 -#define NV4_PRMIO_RMA_PTR_ADDRESS 2 -#define NV4_PRMIO_RMA_DATA 0x7108 -#define NV4_PRMIO_RMA_DATA_PORT 0 -#define NV4_PRMIO_RMA_DATA32 0x710C -#define NV4_PRMIO_RMA_DATA32_BYTE2 16 -#define NV4_PRMIO_RMA_DATA32_BYTE1 8 -#define NV4_PRMIO_RMA_DATA32_BYTE0 0 -#define NV4_PRMIO_RMA_MODE_MAX 0x0F - -#define NV4_PRAMDAC_START 0x680300 -#define NV4_PRAMDAC_END 0x680FFF - -#define NV4_PRAMDAC_CU_START_POS 0x680300 -#define NV4_PRAMDAC_CU_START_POS_X 0 -#define NV4_PRAMDAC_CU_START_POS_Y 16 -#define NV4_PRAMDAC_NVPLL_COEFF 0x680500 -#define NV4_PRAMDAC_NVPLL_COEFF_MDIV 0 -#define NV4_PRAMDAC_NVPLL_COEFF_NDIV 8 -#define NV4_PRAMDAC_NVPLL_COEFF_PDIV 16 // 18:16 -#define NV4_PRAMDAC_MPLL_COEFF 0x680504 -#define NV4_PRAMDAC_MPLL_COEFF_MDIV 0 -#define NV4_PRAMDAC_MPLL_COEFF_NDIV 8 -#define NV4_PRAMDAC_MPLL_COEFF_PDIV 16 // 18:16 -#define NV4_PRAMDAC_VPLL_COEFF 0x680508 -#define NV4_PRAMDAC_VPLL_COEFF_MDIV 0 -#define NV4_PRAMDAC_VPLL_COEFF_NDIV 8 -#define NV4_PRAMDAC_VPLL_COEFF_PDIV 16 // 18:16 -#define NV4_PRAMDAC_PLL_COEFF_SELECT 0x68050C -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE 0 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_XTAL 0x0 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_VIP 0x1 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_SOURCE 8 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_SOURCE_DEFAULT 0x0 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_MPLL 0x1 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_VPLL 0x2 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_NVPLL 0x4 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_SOURCE_PROG_ALL 0x7 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VS_PCLK_TV 16 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VS_PCLK_TV_NONE 0x0 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VS_PCLK_TV_VSCLK 0x1 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VS_PCLK_TV_PCLK 0x2 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VS_PCLK_TV_BOTH 0x3 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_TVCLK_SOURCE 20 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_TVCLK_SOURCE_EXT 0x0 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_TVCLK_SOURCE_VIP 0x1 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_TVCLK_RATIO 24 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_TVCLK_RATIO_DB1 0x0 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_TVCLK_RATIO_DB2 0x1 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO 28 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB1 0x0 -#define NV4_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 0x1 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL 0x680510 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_VALUE 0 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_VAL 0x44E -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_PWRDWN 12 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_PWRDWN_ON 0x0 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_PWRDWN_MPLL 0x1 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_PWRDWN_VPLL 0x2 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_PWRDWN_NVPLL 0x4 -#define NV4_PRAMDAC_PLL_SETUP_CONTROL_PWRDWN_OFF 0x7 -#define NV4_PRAMDAC_PLL_TEST_COUNTER 0x680514 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_NOOFIPCLKS 0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_VALUE 0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_ENABLE 16 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_ENABLE_DEASSERTED 0x0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_ENABLE_ASSERTED 0x1 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_RESET 20 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_RESET_DEASSERTED 0x0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_RESET_ASSERTED 0x1 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_SOURCE 24 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_SOURCE_MCLK 0x2 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_SOURCE_VCLK 0x1 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_SOURCE_NVCLK 0x0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_PDIV_RST 28 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_PDIVRST_DEASSERTED 0x0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_PDIVRST_ASSERTED 0x1 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_NVPLL_LOCK 29 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_NVPLL_NOTLOCKED 0x0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_NVPLL_LOCKED 0x1 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_MPLL_LOCK 30 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_MPLL_NOTLOCKED 0x0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_MPLL_LOCKED 0x1 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_VPLL_LOCK 31 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_VPLL_NOTLOCKED 0x0 -#define NV4_PRAMDAC_PLL_TEST_COUNTER_VPLL_LOCKED 0x1 -#define NV4_PRAMDAC_PALETTE_TEST 0x680518 -#define NV4_PRAMDAC_PALETTE_TEST_BLUE_DATA 0 -#define NV4_PRAMDAC_PALETTE_TEST_GREEN_DATA 8 -#define NV4_PRAMDAC_PALETTE_TEST_RED_DATA 16 -#define NV4_PRAMDAC_PALETTE_TEST_MODE 24 -#define NV4_PRAMDAC_PALETTE_TEST_MODE_8BIT 0x0 -#define NV4_PRAMDAC_PALETTE_TEST_MODE_24BIT 0x1 -#define NV4_PRAMDAC_PALETTE_TEST_ADDRINC 28 -#define NV4_PRAMDAC_PALETTE_TEST_ADDRINC_READWRITE 0x0 -#define NV4_PRAMDAC_PALETTE_TEST_ADDRINC_WRITEONLY 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL 0x680600 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX32_BIT 0 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX32_BIT_24 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX32_BIT_31 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX 4 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX_OFF 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX_POS 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX_NEG 0x2 -#define NV4_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON 0x3 -#define NV4_PRAMDAC_GENERAL_CONTROL_VGA_STATE 8 -#define NV4_PRAMDAC_GENERAL_CONTROL_VGA_STATE_NOTSEL 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_ALT_MODE 12 -#define NV4_PRAMDAC_GENERAL_CONTROL_ALT_MODE_NOTSEL 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_ALT_MODE_15 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_ALT_MODE_16 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_ALT_MODE_24 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_ALT_MODE_30 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL 16 -#define NV4_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_OFF 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_ON 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_TERMINATION 17 -#define NV4_PRAMDAC_GENERAL_CONTROL_TERMINATION_37OHM 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_BPC 20 -#define NV4_PRAMDAC_GENERAL_CONTROL_BPC_6BITS 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_BPC_8BITS 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP 24 -#define NV4_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_DIS 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_EN 0x1 -#define NV4_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK 28 -#define NV4_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_EN 0x0 -#define NV4_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_DIS 0x1 -#define NV4_PRAMDAC_PALETTE_RECOVERY 0x680604 -#define NV4_PRAMDAC_PALETTE_RECOVERY_ACTIVE_ADDRESS 0 -#define NV4_PRAMDAC_PALETTE_RECOVERY_RGB_POINTER 8 -#define NV4_PRAMDAC_PALETTE_RECOVERY_RGB_POINTER_RED 0x1 -#define NV4_PRAMDAC_PALETTE_RECOVERY_RGB_POINTER_GREEN 0x2 -#define NV4_PRAMDAC_PALETTE_RECOVERY_RGB_POINTER_BLUE 0x4 -#define NV4_PRAMDAC_PALETTE_RECOVERY_DAC_STATE 12 -#define NV4_PRAMDAC_PALETTE_RECOVERY_DAC_STATE_WRITE 0x0 -#define NV4_PRAMDAC_PALETTE_RECOVERY_DAC_STATE_READ 0x3 -#define NV4_PRAMDAC_PALETTE_RECOVERY_RED_DATA 16 -#define NV4_PRAMDAC_PALETTE_RECOVERY_GREEN_DATA 24 -#define NV4_PRAMDAC_TEST_CONTROL 0x680608 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_RESET 0 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_RESET_DEASSERTED 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_RESET_ASSERTED 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_ENABLE 4 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_ENABLE_DEASSERTED 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_ENABLE_ASSERTED 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_CHANNEL 8 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_CHANNEL_BLUE 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_CHANNEL_GREEN 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_CRC_CHANNEL_RED 0x2 -#define NV4_PRAMDAC_TEST_CONTROL_TP_INS_EN 12 -#define NV4_PRAMDAC_TEST_CONTROL_TP_INS_EN_DEASSERTED 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_PWRDWN_DAC 16 -#define NV4_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_ON 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_PWRDWN_DAC_OFF 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_DACTM 20 -#define NV4_PRAMDAC_TEST_CONTROL_DACTM_NORMAL 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_DACTM_TEST 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_TPATH1 24 -#define NV4_PRAMDAC_TEST_CONTROL_TPATH1_CLEAR 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_TPATH1_SET 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_TPATH31 25 -#define NV4_PRAMDAC_TEST_CONTROL_TPATH31_CLEAR 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_TPATH31_SET 0x1 -#define NV4_PRAMDAC_TEST_CONTROL_SENSEB 28 -#define NV4_PRAMDAC_TEST_CONTROL_SENSEB_SOMELO 0x0 -#define NV4_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI 0x1 -#define NV4_PRAMDAC_CHECKSUM 0x68060C -#define NV4_PRAMDAC_CHECKSUM_VALUE 0 -#define NV4_PRAMDAC_TESTPOINT_DATA 0x680610 -#define NV4_PRAMDAC_TESTPOINT_DATA_RED 0 -#define NV4_PRAMDAC_TESTPOINT_DATA_GREEN 10 -#define NV4_PRAMDAC_TESTPOINT_DATA_BLUE 20 -#define NV4_PRAMDAC_TESTPOINT_DATA_BLACK 30 -#define NV4_PRAMDAC_TESTPOINT_DATA_NOTBLANK 31 -#define NV4_PRAMDAC_TV_SETUP 0x680700 -#define NV4_PRAMDAC_TV_SETUP_DEV_TYPE 0 -#define NV4_PRAMDAC_TV_SETUP_DEV_TYPE_SLAVE 0x0 -#define NV4_PRAMDAC_TV_SETUP_DEV_TYPE_MASTER 0x1 -#define NV4_PRAMDAC_TV_SETUP_VS_PIXFMT 4 -#define NV4_PRAMDAC_TV_SETUP_VS_PIXFMT_555 0x0 -#define NV4_PRAMDAC_TV_SETUP_VS_PIXFMT_565 0x1 -#define NV4_PRAMDAC_TV_SETUP_VS_PIXFMT_888 0x2 -#define NV4_PRAMDAC_TV_SETUP_VS_PIXFMT_101010 0x3 -#define NV4_PRAMDAC_TV_SETUP_VS_PIXFMT_YUV 0x4 -#define NV4_PRAMDAC_TV_SETUP_DATA_SRC 8 -#define NV4_PRAMDAC_TV_SETUP_DATA_SRC_COMP 0x0 -#define NV4_PRAMDAC_TV_SETUP_DATA_SRC_SCALER 0x1 -#define NV4_PRAMDAC_TV_SETUP_DATA_SRC_VIP 0x2 -#define NV4_PRAMDAC_TV_SETUP_COMP_SRC 12 -#define NV4_PRAMDAC_TV_SETUP_COMP_SRC_SCALER 0x0 -#define NV4_PRAMDAC_TV_SETUP_COMP_SRC_NO_SCALER 0x1 -#define NV4_PRAMDAC_TV_SETUP_SYNC_POL 16 -#define NV4_PRAMDAC_TV_SETUP_SYNC_POL_NEG_NONE 0x0 -#define NV4_PRAMDAC_TV_SETUP_SYNC_POL_NEG_HSYNC 0x1 -#define NV4_PRAMDAC_TV_SETUP_SYNC_POL_NEG_VSYNC 0x2 -#define NV4_PRAMDAC_TV_SETUP_SYNC_POL_NEG_BOTH 0x3 -#define NV4_PRAMDAC_TV_SETUP_VIP_VSYNC 20 -#define NV4_PRAMDAC_TV_SETUP_VIP_VSYNC_LEAD 0x0 -#define NV4_PRAMDAC_TV_SETUP_VIP_VSYNC_TRAIL 0x1 -#define NV4_PRAMDAC_TV_SETUP_VIP_DATAPOS 24 -#define NV4_PRAMDAC_TV_SETUP_VIP_DATAPOS_7_0 0x0 -#define NV4_PRAMDAC_TV_SETUP_VIP_DATAPOS_11_4 0x1 -#define NV4_PRAMDAC_TV_SETUP_VIP_FIELD 28 -#define NV4_PRAMDAC_TV_SETUP_VIP_FIELD_0 0x0 -#define NV4_PRAMDAC_TV_SETUP_VIP_FIELD_1 0x1 -#define NV4_PRAMDAC_TV_VBLANK_START 0x680704 -#define NV4_PRAMDAC_TV_VBLANK_START_VAL 0 -#define NV4_PRAMDAC_TV_VBLANK_END 0x680708 -#define NV4_PRAMDAC_TV_VBLANK_END_VAL 0 -#define NV4_PRAMDAC_TV_HBLANK_START 0x68070C -#define NV4_PRAMDAC_TV_HBLANK_START_VAL 0 -#define NV4_PRAMDAC_TV_HBLANK_END 0x680710 -#define NV4_PRAMDAC_TV_HBLANK_END_VAL 0 -#define NV4_PRAMDAC_BLANK_COLOR 0x680714 -#define NV4_PRAMDAC_BLANK_COLOR_VAL 0 -#define NV4_PRAMDAC_TV_CHECKSUM 0x680718 -#define NV4_PRAMDAC_TV_CHECKSUM_VAL 0 -#define NV4_PRAMDAC_TV_VSYNC 28 -#define NV4_PRAMDAC_TV_VSYNC_ACTIVE 0x0 -#define NV4_PRAMDAC_TV_VSYNC_INACTIVE 0x1 -#define NV4_PRAMDAC_TV_TEST_CONTROL 0x68071c -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_RESET 0 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_RESET_DEASSERTED 0x0 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_RESET_ASSERTED 0x1 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_ENABLE 4 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_ENABLE_DEASSERTED 0x0 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_ENABLE_ASSERTED 0x1 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_CHANNEL 8 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_CHANNEL_7_0 0x0 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_CHANNEL_15_8 0x1 -#define NV4_PRAMDAC_TV_TEST_CONTROL_CRC_CHANNEL_23_16 0x2 - -#define NV4_USER_DAC_START 0x681200 -#define NV4_USER_DAC_END 0x681FFF -#define NV4_USER_DAC_PALETTE_START 0x6813C6 -#define NV4_USER_DAC_PALETTE_END 0x6813C9 - -#define NV4_USER_DAC_PIXEL_MASK 0x6813C6 -#define NV4_USER_DAC_PIXEL_MASK_VALUE 0 -#define NV4_USER_DAC_PIXEL_MASK_MASK 0xFF -#define NV4_USER_DAC_READ_MODE_ADDRESS 0x6813C7 -#define NV4_USER_DAC_READ_MODE_ADDRESS_VALUE 0 -#define NV4_USER_DAC_READ_MODE_ADDRESS_WO_VALUE 0 -#define NV4_USER_DAC_READ_MODE_ADDRESS_RW_STATE 0 -#define NV4_USER_DAC_READ_MODE_ADDRESS_RW_STATE_WRITE 0x0 -#define NV4_USER_DAC_READ_MODE_ADDRESS_RW_STATE_READ 0x3 -#define NV4_USER_DAC_WRITE_MODE_ADDRESS 0x6813C8 -#define NV4_USER_DAC_WRITE_MODE_ADDRESS_VALUE 0 -#define NV4_USER_DAC_PALETTE_DATA 0x6813C9 -#define NV4_USER_DAC_PALETTE_DATA_VALUE 0 - -#define NV4_PRMDIO_START 0x681000 -#define NV4_PRMDIO_END 0x681FFF - -#define NV4_IO_MPU_401_DATA 0x330 -#define NV4_IO_MPU_401_DATA_ALIAS_1 0x300 -#define NV4_IO_MPU_401_DATA_ALIAS_2 0x230 -#define NV4_IO_MPU_401_DATA_VALUE 0 -#define NV4_IO_MPU_401_DATA_ACK 0xFE -#define NV4_IO_MPU_401_STATUS 0x331 -#define NV4_IO_MPU_401_STATUS_ALIAS_1 0x301 -#define NV4_IO_MPU_401_STATUS_ALIAS_2 0x231 -#define NV4_IO_MPU_401_STATUS_DATA 0 -#define NV4_IO_MPU_401_STATUS_WRITE 6 -#define NV4_IO_MPU_401_STATUS_WRITE_EMPTY 0x0 -#define NV4_IO_MPU_401_STATUS_WRITE_FULL 0x1 -#define NV4_IO_MPU_401_STATUS_READ 7 -#define NV4_IO_MPU_401_STATUS_READ_FULL 0x0 -#define NV4_IO_MPU_401_STATUS_READ_EMPTY 0x1 -#define NV4_IO_MPU_401_COM 0x331 -#define NV4_IO_MPU_401_COM_ALIAS_1 0x301 -#define NV4_IO_MPU_401_COM_ALIAS_2 0x231 -#define NV4_IO_MPU_401_COM_UART_MODE 0 -#define NV4_IO_MPU_401_COM_UART_MODE_COMPLEX 0xff -#define NV4_IO_MPU_401_COM_UART_MODE_SIMPLE 0x3f - -#define NV4_PMC_START 0x0 -#define NV4_PMC_END 0xFFF - -#define NV4_PMC_BOOT_0 0x0 -#define NV4_PMC_BOOT_0_MINOR_REVISION 0 -#define NV4_PMC_BOOT_0_MINOR_REVISION_0 0x0 -#define NV4_PMC_BOOT_0_MAJOR_REVISION 4 -#define NV4_PMC_BOOT_0_MAJOR_REVISION_A 0x0 -#define NV4_PMC_BOOT_0_MAJOR_REVISION_B 0x1 -#define NV4_PMC_BOOT_0_IMPLEMENTATION 8 -#define NV4_PMC_BOOT_0_IMPLEMENTATION_NV4_0 0x0 -#define NV4_PMC_BOOT_0_ARCHITECTURE 12 -#define NV4_PMC_BOOT_0_ARCHITECTURE_NV0 0x0 -#define NV4_PMC_BOOT_0_ARCHITECTURE_NV1 0x1 -#define NV4_PMC_BOOT_0_ARCHITECTURE_NV2 0x2 -#define NV4_PMC_BOOT_0_ARCHITECTURE_NV3 0x3 -#define NV4_PMC_BOOT_0_ARCHITECTURE_NV4 0x4 -#define NV4_PMC_BOOT_0_FIB_REVISION 16 -#define NV4_PMC_BOOT_0_FIB_REVISION_0 0x0 -#define NV4_PMC_BOOT_0_MASK_REVISION 20 -#define NV4_PMC_BOOT_0_MASK_REVISION_A 0x0 -#define NV4_PMC_BOOT_0_MASK_REVISION_B 0x1 -#define NV4_PMC_BOOT_0_MASK_REVISION_C 0x2 -#define NV4_PMC_BOOT_0_MANUFACTURER 24 -#define NV4_PMC_BOOT_0_MANUFACTURER_NVIDIA 0x0 -#define NV4_PMC_BOOT_0_FOUNDRY 28 -#define NV4_PMC_BOOT_0_FOUNDRY_SGS 0x0 -#define NV4_PMC_BOOT_0_FOUNDRY_HELIOS 0x1 -#define NV4_PMC_BOOT_0_FOUNDRY_TSMC 0x2 -#define NV4_PMC_INTR_0 0x100 -#define NV4_PMC_INTR_0_PMEDIA 4 -#define NV4_PMC_INTR_0_PMEDIA_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_PMEDIA_PENDING 0x1 -#define NV4_PMC_INTR_0_PFIFO 8 -#define NV4_PMC_INTR_0_PFIFO_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_PFIFO_PENDING 0x1 -#define NV4_PMC_INTR_0_PGRAPH 12 -#define NV4_PMC_INTR_0_PGRAPH_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_PGRAPH_PENDING 0x1 -#define NV4_PMC_INTR_0_PVIDEO 16 -#define NV4_PMC_INTR_0_PVIDEO_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_PVIDEO_PENDING 0x1 -#define NV4_PMC_INTR_0_PTIMER 20 -#define NV4_PMC_INTR_0_PTIMER_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_PTIMER_PENDING 0x1 -#define NV4_PMC_INTR_0_PCRTC 24 -#define NV4_PMC_INTR_0_PCRTC_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_PCRTC_PENDING 0x1 -#define NV4_PMC_INTR_0_PBUS 28 -#define NV4_PMC_INTR_0_PBUS_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_PBUS_PENDING 0x1 -#define NV4_PMC_INTR_0_SOFTWARE 31 -#define NV4_PMC_INTR_0_SOFTWARE_NOT_PENDING 0x0 -#define NV4_PMC_INTR_0_SOFTWARE_PENDING 0x1 -#define NV4_PMC_INTR_EN_0 0x140 -#define NV4_PMC_INTR_EN_0_INTA 0 -#define NV4_PMC_INTR_EN_0_INTA_DISABLED 0x0 -#define NV4_PMC_INTR_EN_0_INTA_HARDWARE 0x1 -#define NV4_PMC_INTR_EN_0_INTA_SOFTWARE 0x2 -#define NV4_PMC_INTR_READ_0 0x160 -#define NV4_PMC_INTR_READ_0_INTA 0 -#define NV4_PMC_INTR_READ_0_INTA_LOW 0x0 -#define NV4_PMC_INTR_READ_0_INTA_HIGH 0x1 -#define NV4_PMC_ENABLE 0x200 -#define NV4_PMC_ENABLE_PMEDIA 4 -#define NV4_PMC_ENABLE_PMEDIA_ENABLED 0x1 -#define NV4_PMC_ENABLE_PFIFO 8 -#define NV4_PMC_ENABLE_PFIFO_ENABLED 0x1 -#define NV4_PMC_ENABLE_PGRAPH 12 -#define NV4_PMC_ENABLE_PGRAPH_ENABLED 0x1 -#define NV4_PMC_ENABLE_PPMI 16 -#define NV4_PMC_ENABLE_PPMI_ENABLED 0x1 -#define NV4_PMC_ENABLE_PFB 20 -#define NV4_PMC_ENABLE_PFB_ENABLED 0x1 -#define NV4_PMC_ENABLE_PCRTC 24 -#define NV4_PMC_ENABLE_PCRTC_ENABLED 0x1 -#define NV4_PMC_ENABLE_PVIDEO 28 -#define NV4_PMC_ENABLE_PVIDEO_ENABLED 0x1 - -#define NV4_PBUS_START 0x1000 -#define NV4_PBUS_END 0x1FFF - -#define NV4_PBUS_DEBUG_0 0x1080 -#define NV4_PBUS_DEBUG_0_FBIO_SCLK_DELAY 0 -#define NV4_PBUS_DEBUG_0_FBIO_SCLK_DELAY_8 0x8 -#define NV4_PBUS_DEBUG_0_FBIO_SCLK_PC 4 -#define NV4_PBUS_DEBUG_0_FBIO_SCLK_PC_NORMAL 0x0 -#define NV4_PBUS_DEBUG_0_FBIO_SCLK_PC_OVERRIDE 0x1 -#define NV4_PBUS_DEBUG_0_FBIO_FBCLK_DELAY 8 -#define NV4_PBUS_DEBUG_0_FBIO_FBCLK_DELAY_8 0x8 -#define NV4_PBUS_DEBUG_0_FBIO_FBCLK_PC 12 -#define NV4_PBUS_DEBUG_0_FBIO_FBCLK_PC_NORMAL 0x0 -#define NV4_PBUS_DEBUG_0_FBIO_FBCLK_PC_OVERRIDE 0x1 -#define NV4_PBUS_DEBUG_0_FBIO_ACLK_DELAY 16 -#define NV4_PBUS_DEBUG_0_FBIO_ACLK_DELAY_8 0x8 -#define NV4_PBUS_DEBUG_0_FBIO_ACLK_PC 20 -#define NV4_PBUS_DEBUG_0_FBIO_ACLK_PC_NORMAL 0x0 -#define NV4_PBUS_DEBUG_0_FBIO_ACLK_PC_OVERRIDE 0x1 -#define NV4_PBUS_DEBUG_0_FBIO_RCLK_DELAY 24 -#define NV4_PBUS_DEBUG_0_FBIO_RCLK_DELAY_8 0x8 -#define NV4_PBUS_DEBUG_0_FBIO_RCLK_PC 28 -#define NV4_PBUS_DEBUG_0_FBIO_RCLK_PC_NORMAL 0x0 -#define NV4_PBUS_DEBUG_0_FBIO_RCLK_PC_OVERRIDE 0x1 -#define NV4_PBUS_DEBUG_1 0x1084 -#define NV4_PBUS_DEBUG_1_PCIM_THROTTLE 0 -#define NV4_PBUS_DEBUG_1_PCIM_THROTTLE_ENABLED 0x1 -#define NV4_PBUS_DEBUG_1_PCIM_CMD 1 -#define NV4_PBUS_DEBUG_1_PCIM_CMD_SIZE_BASED 0x0 -#define NV4_PBUS_DEBUG_1_PCIM_CMD_MRL_ONLY 0x1 -#define NV4_PBUS_DEBUG_1_HASH_DECODE 2 -#define NV4_PBUS_DEBUG_1_HASH_DECODE_1FF 0x0 -#define NV4_PBUS_DEBUG_1_HASH_DECODE_2FF 0x1 -#define NV4_PBUS_DEBUG_1_AGPM_CMD 3 -#define NV4_PBUS_DEBUG_1_AGPM_CMD_HP_ON_1ST 0x0 -#define NV4_PBUS_DEBUG_1_AGPM_CMD_LP_ONLY 0x1 -#define NV4_PBUS_DEBUG_1_AGPM_CMD_HP_ONLY 0x2 -#define NV4_PBUS_DEBUG_1_PCIS_WRITE 5 -#define NV4_PBUS_DEBUG_1_PCIS_WRITE_0_CYCLE 0x0 -#define NV4_PBUS_DEBUG_1_PCIS_WRITE_1_CYCLE 0x1 -#define NV4_PBUS_DEBUG_1_PCIS_2_1 6 -#define NV4_PBUS_DEBUG_1_PCIS_2_1_ENABLED 0x1 -#define NV4_PBUS_DEBUG_1_PCIS_RETRY 7 -#define NV4_PBUS_DEBUG_1_PCIS_RETRY_ENABLED 0x1 -#define NV4_PBUS_DEBUG_1_PCIS_RD_BURST 8 -#define NV4_PBUS_DEBUG_1_PCIS_RD_BURST_ENABLED 0x1 -#define NV4_PBUS_DEBUG_1_PCIS_WR_BURST 9 -#define NV4_PBUS_DEBUG_1_PCIS_WR_BURST_ENABLED 0x1 -#define NV4_PBUS_DEBUG_1_PCIS_EARLY_RTY 10 -#define NV4_PBUS_DEBUG_1_PCIS_EARLY_RTY_ENABLED 0x1 -#define NV4_PBUS_DEBUG_1_PCIS_CPUQ 12 -#define NV4_PBUS_DEBUG_1_PCIS_CPUQ_ENABLED 0x1 -#define NV4_PBUS_DEBUG_1_DPSH_DECODE 13 -#define NV4_PBUS_DEBUG_1_DPSH_DECODE_NV4 0x0 -#define NV4_PBUS_DEBUG_1_DPSH_DECODE_NV3 0x1 -#define NV4_PBUS_DEBUG_1_SPARE1 14 -#define NV4_PBUS_DEBUG_1_SPARE2 15 -#define NV4_PBUS_DEBUG_1_SPARE3 16 -#define NV4_PBUS_DEBUG_1_SPARE4 17 -#define NV4_PBUS_DEBUG_1_SPARE5 18 -#define NV4_PBUS_DEBUG_1_SPARE6 19 -#define NV4_PBUS_DEBUG_1_SPARE7 20 -#define NV4_PBUS_DEBUG_1_SPARE8 21 -#define NV4_PBUS_DEBUG_1_SPARE9 22 -#define NV4_PBUS_DEBUG_1_SPARE10 23 -#define NV4_PBUS_DEBUG_2 0x1088 -#define NV4_PBUS_DEBUG_2_AGP_DIFFERENTIAL 0 -#define NV4_PBUS_DEBUG_2_AGP_DIFFERENTIAL_ENABLED 0x1 -#define NV4_PBUS_DEBUG_2_AGP_SB_STB_DELAY 9:4 -#define NV4_PBUS_DEBUG_2_AGP_SB_STB_DELAY_34 0x22 -#define NV4_PBUS_DEBUG_2_AGP_SB_STB_PC 12 -#define NV4_PBUS_DEBUG_2_AGP_SB_STB_PC_NORMAL 0x0 -#define NV4_PBUS_DEBUG_2_AGP_SB_STB_PC_OVERRIDE 0x1 -#define NV4_PBUS_DEBUG_3 0x108C -#define NV4_PBUS_DEBUG_3_AGP_MAX_SIZE 0 -#define NV4_PBUS_DEBUG_3_AGP_MAX_SIZE_UNLIMITED 0x0 -#define NV4_PBUS_DEBUG_3_AGP_MAX_SIZE_32_BYTES 0x1 -#define NV4_PBUS_DEBUG_3_AGP_MAX_SIZE_64_BYTES 0x2 -#define NV4_PBUS_DEBUG_CTL 0x1090 -#define NV4_PBUS_DEBUG_CTL_MODE 0 -#define NV4_PBUS_DEBUG_CTL_MODE_ENABLED 0x1 -#define NV4_PBUS_DEBUG_CTL_READ_SELECT 4 -#define NV4_PBUS_DEBUG_CTL_READ_SELECT_0 0x0 -#define NV4_PBUS_DEBUG_CTL_READ_SELECT_1 0x1 -#define NV4_PBUS_DEBUG_READ 0x1094 -#define NV4_PBUS_DEBUG_READ_DATA 0 -#define NV4_PBUS_DEBUG_HOST 0x109C -#define NV4_PBUS_DEBUG_HOST_SEL 0 -#define NV4_PBUS_DEBUG_SEL_0 0x10A0 -#define NV4_PBUS_DEBUG_SEL_0_X 0 -#define NV4_PBUS_DEBUG_SEL_1 0x10A4 -#define NV4_PBUS_DEBUG_SEL_1_X 0 -#define NV4_PBUS_DEBUG_SEL_2 0x10A8 -#define NV4_PBUS_DEBUG_SEL_2_X 0 -#define NV4_PBUS_DEBUG_SEL_3 0x10AC -#define NV4_PBUS_DEBUG_SEL_3_X 0 -#define NV4_PBUS_INTR_0 0x1100 -#define NV4_PBUS_INTR_0_PCI_BUS_ERROR 0 -#define NV4_PBUS_INTR_0_PCI_BUS_ERROR_NOT_PENDING 0x0 -#define NV4_PBUS_INTR_0_PCI_BUS_ERROR_PENDING 0x1 -#define NV4_PBUS_INTR_0_PCI_BUS_ERROR_RESET 0x1 -#define NV4_PBUS_INTR_EN_0 0x1140 -#define NV4_PBUS_INTR_EN_0_PCI_BUS_ERROR 0 -#define NV4_PBUS_INTR_EN_0_PCI_BUS_ERROR_ENABLED 0x1 -#define NV4_PBUS_ROM_CONFIG 0x1200 -#define NV4_PBUS_ROM_CONFIG_TW1 0 -#define NV4_PBUS_ROM_CONFIG_TW1_DEFAULT 0xF -#define NV4_PBUS_ROM_CONFIG_TW0 4 -#define NV4_PBUS_ROM_CONFIG_TW0_DEFAULT 0x3 - -// 86Box uses 8-bit PCI registers so this section was rewritten -#define NV4_PBUS_PCI_VENDOR_ID 0x1800 -#define NV4_PBUS_PCI_DEVICE_VENDOR_NVIDIA 0x10DE -#define NV4_PBUS_PCI_DEVICE_ID 0x1802 -#define NV4_PBUS_PCI_DEVICE_ID_NV4 0x0020 // Chip (19:17)= NV4, Func = VGA -#define NV4_PBUS_PCI_COMMAND 0x1804 -#define NV4_PBUS_PCI_COMMAND_H 0x1805 -#define NV4_PBUS_PCI_COMMAND_IO_SPACE 0 -#define NV4_PBUS_PCI_COMMAND_IO_SPACE_ENABLED 0x1 -#define NV4_PBUS_PCI_COMMAND_MEMORY_SPACE 1 -#define NV4_PBUS_PCI_COMMAND_MEMORY_SPACE_ENABLED 0x1 -#define NV4_PBUS_PCI_COMMAND_BUS_MASTER 2 -#define NV4_PBUS_PCI_COMMAND_BUS_MASTER_ENABLED 0x1 -#define NV4_PBUS_PCI_COMMAND_WRITE_AND_INVAL 4 -#define NV4_PBUS_PCI_COMMAND_WRITE_AND_INVAL_ENABLED 0x1 -#define NV4_PBUS_PCI_COMMAND_PALETTE_SNOOP 5 -#define NV4_PBUS_PCI_COMMAND_PALETTE_SNOOP_ENABLED 0x1 -#define NV4_PBUS_PCI_STATUS 0x1806 -#define NV4_PBUS_PCI_STATUS_CAPLIST 4 -#define NV4_PBUS_PCI_STATUS_CAPLIST_NOT_PRESENT 0x0 -#define NV4_PBUS_PCI_STATUS_CAPLIST_PRESENT 0x1 -#define NV4_PBUS_PCI_STATUS_66MHZ 5 -#define NV4_PBUS_PCI_STATUS_66MHZ_INCAPABLE 0x0 -#define NV4_PBUS_PCI_STATUS_66MHZ_CAPABLE 0x1 -#define NV4_PBUS_PCI_STATUS_FAST_BACK2BACK 7 -#define NV4_PBUS_PCI_STATUS_FAST_BACK2BACK_INCAPABLE 0x0 -#define NV4_PBUS_PCI_STATUS_FAST_BACK2BACK_CAPABLE 0x1 -#define NV4_PBUS_PCI_STATUS_2 0x1807 -#define NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING 1 -#define NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING_FAST 0x0 -#define NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING_MEDIUM 0x1 -#define NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING_SLOW 0x2 -#define NV4_PBUS_PCI_STATUS_2_SIGNALED_TARGET 3 -#define NV4_PBUS_PCI_STATUS_2_SIGNALED_TARGET_NO_ABORT 0x0 -#define NV4_PBUS_PCI_STATUS_2_SIGNALED_TARGET_ABORT 0x1 -#define NV4_PBUS_PCI_STATUS_2_SIGNALED_TARGET_CLEAR 0x1 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_TARGET 4 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_TARGET_NO_ABORT 0x0 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_TARGET_ABORT 0x1 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_TARGET_CLEAR 0x1 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_MASTER 5 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_MASTER_NO_ABORT 0x0 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_MASTER_ABORT 0x1 -#define NV4_PBUS_PCI_STATUS_2_RECEIVED_MASTER_CLEAR 0x1 -#define NV4_PBUS_PCI_REVISION_ID 0x1808 -#define NV4_PBUS_PCI_REVISION_ID_A01 0x0 -#define NV4_PBUS_PCI_REVISION_ID_B01 0x1 -#define NV4_PBUS_PCI_CLASS_CODE 0x180B -#define NV4_PBUS_PCI_CLASS_CODE_VGA 0x30000 -#define NV4_PBUS_PCI_LATENCY_TIMER 0x180D -// Shift left by 3 to get the real value in clocks. 0x0 = 0, 0x1 = 8, 0x1E = 240, 0x1F = 248 are values used. -#define NV4_PBUS_PCI_LATENCY_TIMER_VALUE 3 -// 0x0 = single function (only value that matters) -#define NV4_PBUS_PCI_HEADER_TYPE 0x180E -#define NV4_PBUS_PCI_BAR_SPACE_TYPE 0 -#define NV4_PBUS_PCI_BAR_SPACE_TYPE_MEMORY 0x0 -#define NV4_PBUS_PCI_BAR_SPACE_TYPE_IO 0x1 -#define NV4_PBUS_PCI_BAR_ADDRESS_TYPE 1 -#define NV4_PBUS_PCI_BAR_ADDRESS_TYPE_32_BIT 0x0 -#define NV4_PBUS_PCI_BAR_ADDRESS_TYPE_20_BIT 0x1 -#define NV4_PBUS_PCI_BAR_ADDRESS_TYPE_64_BIT 0x2 -#define NV4_PBUS_PCI_BAR_PREFETCHABLE 3 -#define NV4_PBUS_PCI_BAR_PREFETCHABLE_NOT 0x0 -#define NV4_PBUS_PCI_BAR_PREFETCHABLE_MERGABLE 0x1 -// Bits 23:4 are resedrved -#define NV4_PBUS_PCI_BAR0_INFO 0x1810 -#define NV4_PBUS_PCI_BAR0_UNUSED1 0x1811 -#define NV4_PBUS_PCI_BAR0_UNUSED2 0x1812 -#define NV4_PBUS_PCI_BAR0_BASE_31_TO_24 0x1813 // Must align to 16MByte -#define NV4_PBUS_PCI_BAR1_INFO 0x1814 -#define NV4_PBUS_PCI_BAR1_UNUSED1 0x1815 -#define NV4_PBUS_PCI_BAR1_UNUSED2 0x1816 -#define NV4_PBUS_PCI_BAR1_BASE_31_TO_24 0x1817 // Must align to 16MByte -#define NV4_PBUS_PCI_BAR_RESERVED_START 0x1818 -#define NV4_PBUS_PCI_BAR_RESERVED_END 0x182B - -//BAR2-5 reserved -#define NV4_PBUS_PCI_SUBSYSTEM_VENDOR_ID 0x182C -#define NV4_PBUS_PCI_SUBSYSTEM_ID 0x182E -#define NV4_PBUS_PCI_ROM 0x1830 -#define NV4_PBUS_PCI_ROM_DECODE 0 -#define NV4_PBUS_PCI_ROM_DECODE_ENABLED 0x1 -#define NV4_PBUS_PCI_ROM_BASE 0x1832 -#define NV4_PBUS_PCI_NEXT_PTR 0x1834 -#define NV4_PBUS_PCI_CAP_PTR_AGP 0x44 -#define NV4_PBUS_PCI_CAP_PTR_POWER_MGMT 0x60 -// 0xFF = unknown, otherwise 0x0-0xF = IRQ0-15 -#define NV4_PBUS_PCI_INTR_LINE 0x183C -#define NV4_PBUS_PCI_INTR_LINE_IRQ_NUM 0 -#define NV4_PBUS_PCI_INTR_LINE_IRQ_NUM_UNKNOWN 0xFF -#define NV4_PBUS_PCI_INTR_PIN 0x183D -#define NV4_PBUS_PCI_INTR_PIN_INTA 0x1 -#define NV4_PBUS_PCI_MIN_GNT 0x183E -#define NV4_PBUS_PCI_MIN_GNT_NO_REQUIREMENTS 0x0 -#define NV4_PBUS_PCI_MIN_GNT_750NS 0x3 -#define NV4_PBUS_PCI_MIN_GNT_1250NS 0x5 -#define NV4_PBUS_PCI_MAX_LAT 0x183F -#define NV4_PBUS_PCI_MAX_LAT_NO_REQUIREMENTS 0x0 -#define NV4_PBUS_PCI_MAX_LAT_250NS 0x1 -#define NV4_PBUS_PCI_SUBSYSTEM_VENDOR_ID_WRITABLE 0x1840 -#define NV4_PBUS_PCI_SUBSYSTEM_ID_WRITABLE 0x1842 -#define NV4_PBUS_AGP 0x44 -#define NV4_PBUS_AGP_CAPABILITIES 0x1844 -#define NV4_PBUS_AGP_CAPABILITY_AGP 0x2 -// Should be null! - -#define NV4_PBUS_AGP_NEXT_PTR 0x1845 -#define NV4_PBUS_AGP_REV 0x1846 -#define NV4_PBUS_AGP_REV_MINOR 0 -#define NV4_PBUS_AGP_REV_MINOR_0 0x0 -#define NV4_PBUS_AGP_REV_MAJOR 4 -#define NV4_PBUS_AGP_REV_MAJOR_1 0x1 -#define NV4_PBUS_AGP_STATUS_RATE 0x1848 -#define NV4_PBUS_AGP_STATUS_RATE_1X 0x1 -#define NV4_PBUS_AGP_STATUS_RATE_2X 0x2 -#define NV4_PBUS_AGP_STATUS_RATE_1X_AND_2X 0x3 -#define NV4_PBUS_AGP_STATUS_RQ 0x184B -#define NV4_PBUS_AGP_STATUS_RQ_16 0xF -#define NV4_PBUS_AGP_STATUS_SBA 0x1849 -#define NV4_PBUS_AGP_STATUS_SBA_STATUS 1 -#define NV4_PBUS_AGP_STATUS_SBA_STATUS_NONE 0x0 -#define NV4_PBUS_AGP_STATUS_SBA_STATUS_CAPABLE 0x1 -#define NV4_PBUS_AGP_COMMAND 0x184C -#define NV4_PBUS_AGP_COMMAND_DATA_RATE 0 -#define NV4_PBUS_AGP_COMMAND_DATA_RATE_OFF 0x0 -#define NV4_PBUS_AGP_COMMAND_DATA_RATE_1X 0x1 -#define NV4_PBUS_AGP_COMMAND_DATA_RATE_2X 0x2 -#define NV4_PBUS_AGP_COMMAND_2 0x184D -#define NV4_PBUS_AGP_COMMAND_2_AGP_ENABLED 0 // 1 = enabled, 0 = disabled -#define NV4_PBUS_AGP_COMMAND_2_SBA_ENABLED 1 // 1 = enabled, 0 = disabled -#define NV4_PBUS_AGP_COMMAND_RQ_DEPTH 0x184F //DEFAUlt 0 -#define NV4_PBUS_PCI_ROM_SHADOW 0x1850 -#define NV4_PBUS_PCI_ROM_SHADOW_IS_ENABLED 0 // 1 = enabled, 0 = disabled -#define NV4_PBUS_PCI_VGA 0x1854 -#define NV4_PBUS_PCI_VGA_IS_ENABLED 0 // 1 = enabled, 0 = disabled -#define NV4_PBUS_PCI_SCRATCH 0x1858 -#define NV4_PBUS_PCI_SCRATCH_DEFAULT 0x23D6CE -#define NV4_PBUS_PCI_DT 0x185C -#define NV4_PBUS_PCI_DT_TIMEOUT 0 -#define NV4_PBUS_PCI_DT_TIMEOUT_16 0xF -//TODO: Implement -#define NV4_PBUS_PCIPOWER 0x1860 -#define NV4_PBUS_PCIPOWER_CAP_ID 0 -#define NV4_PBUS_PCIPOWER_CAP_ID_POWER_MGMT 0x1 -#define NV4_PBUS_PCIPOWER_NEXT_PTR 0x1861 // should be 0x44=AGP -#define NV4_PBUS_PCIPOWER_2 0x1862 -#define NV4_PBUS_PCIPOWER_2_VERSION 0 -#define NV4_PBUS_PCIPOWER_2_VERSION_1 0x1 -#define NV4_PBUS_PCIPOWER_2_CLOCK 3 -#define NV4_PBUS_PCIPOWER_2_CLOCK_NOT_REQUIRED 0x0 -#define NV4_PBUS_PCIPOWER_2_DSI 5 -#define NV4_PBUS_PCIPOWER_2_DSI_NOT_REQUIRED 0x0 -#define NV4_PBUS_PCIPOWER_SUPPORTED_STATES 0x1863 -#define NV4_PBUS_PCIPOWER_D1 1 -#define NV4_PBUS_PCIPOWER_D1_SUPPORTED 0x1 // 1 = supported -#define NV4_PBUS_PCIPOWER_D2 2 -#define NV4_PBUS_PCIPOWER_D2_SUPPORTED 0x1 // 0 = not supported -#define NV4_PBUS_PCIPOWER_PME_D0 3 -#define NV4_PBUS_PCIPOWER_PME_D0_SUPPORTED 0x1 -#define NV4_PBUS_PCIPOWER_PME_D1 4 -#define NV4_PBUS_PCIPOWER_PME_D1_SUPPORTED 0x1 -#define NV4_PBUS_PCIPOWER_PME_D2 5 -#define NV4_PBUS_PCIPOWER_PME_D2_SUPPORTED 0x1 -#define NV4_PBUS_PCIPOWER_PME_D3_HOT 6 -#define NV4_PBUS_PCIPOWER_PME_D3_HOT_SUPPORTED 0x1 -#define NV4_PBUS_PCIPOWER_PME_D3_COLD 7 -#define NV4_PBUS_PCIPOWER_PME_D3_COLD_SUPPORTED 0x1 -#define NV4_PBUS_PCIPOWER_STATE_CURRENT 0x1864 -#define NV4_PBUS_PCIPOWER_STATE 0 -#define NV4_PBUS_PCIPOWER_STATE_D3_HOT 0x3 -#define NV4_PBUS_PCIPOWER_STATE_D2 0x2 -#define NV4_PBUS_PCIPOWER_STATE_D1 0x1 -#define NV4_PBUS_PCIPOWER_STATE_D0 0x0 -#define NV4_PFIFO_START 0x2000 -#define NV4_PFIFO_END 0x3FFF -#define NV4_PFIFO_DELAY_0 0x2040 -#define NV4_PFIFO_DELAY_0_WAIT_RETRY 0 -#define NV4_PFIFO_DELAY_0_WAIT_RETRY_0 0x0 -#define NV4_PFIFO_DMA_TIMESLICE 0x2044 -#define NV4_PFIFO_DMA_TIMESLICE_SELECT 0 -#define NV4_PFIFO_DMA_TIMESLICE_SELECT_1 0x0 -#define NV4_PFIFO_DMA_TIMESLICE_SELECT_16K 0x3fff -#define NV4_PFIFO_DMA_TIMESLICE_SELECT_32K 0x7fff -#define NV4_PFIFO_DMA_TIMESLICE_SELECT_64K 0xffff -#define NV4_PFIFO_DMA_TIMESLICE_SELECT_128K 0x1ffff -#define NV4_PFIFO_DMA_TIMESLICE_TIMEOUT 24 -#define NV4_PFIFO_DMA_TIMESLICE_TIMEOUT_ENABLED 0x1 -#define NV4_PFIFO_PIO_TIMESLICE 0x2048 -#define NV4_PFIFO_PIO_TIMESLICE_SELECT 0 -#define NV4_PFIFO_PIO_TIMESLICE_SELECT_1 0x0 -#define NV4_PFIFO_PIO_TIMESLICE_SELECT_16K 0x3fff -#define NV4_PFIFO_PIO_TIMESLICE_SELECT_32K 0x7fff -#define NV4_PFIFO_PIO_TIMESLICE_SELECT_64K 0xffff -#define NV4_PFIFO_PIO_TIMESLICE_SELECT_128K 0x1ffff -#define NV4_PFIFO_PIO_TIMESLICE_TIMEOUT 24 -#define NV4_PFIFO_PIO_TIMESLICE_TIMEOUT_ENABLED 0x1 -#define NV4_PFIFO_TIMESLICE 0x204C -#define NV4_PFIFO_TIMESLICE_TIMER 0 -#define NV4_PFIFO_TIMESLICE_TIMER_EXPIRED 0x3FFFF -#define NV4_PFIFO_NEXT_CHANNEL 0x2050 -#define NV4_PFIFO_NEXT_CHANNEL_CHID 0 -#define NV4_PFIFO_NEXT_CHANNEL_MODE 8 -#define NV4_PFIFO_NEXT_CHANNEL_MODE_PIO 0x0 -#define NV4_PFIFO_NEXT_CHANNEL_MODE_DMA 0x1 -#define NV4_PFIFO_NEXT_CHANNEL_SWITCH 12 -#define NV4_PFIFO_NEXT_CHANNEL_SWITCH_NOT_PENDING 0x0 -#define NV4_PFIFO_NEXT_CHANNEL_SWITCH_PENDING 0x1 -#define NV4_PFIFO_DEBUG_0 0x2080 -#define NV4_PFIFO_DEBUG_0_CACHE_ERROR0 0 -#define NV4_PFIFO_DEBUG_0_CACHE_ERROR0_NOT_PENDING 0x0 -#define NV4_PFIFO_DEBUG_0_CACHE_ERROR0_PENDING 0x1 -#define NV4_PFIFO_DEBUG_0_CACHE_ERROR1 4 -#define NV4_PFIFO_DEBUG_0_CACHE_ERROR1_NOT_PENDING 0x0 -#define NV4_PFIFO_DEBUG_0_CACHE_ERROR1_PENDING 0x1 -#define NV4_PFIFO_INTR_0 0x2100 -#define NV4_PFIFO_INTR_0_CACHE_ERROR 0 -#define NV4_PFIFO_INTR_0_CACHE_ERROR_NOT_PENDING 0x0 -#define NV4_PFIFO_INTR_0_CACHE_ERROR_PENDING 0x1 -#define NV4_PFIFO_INTR_0_CACHE_ERROR_RESET 0x1 -#define NV4_PFIFO_INTR_0_RUNOUT 4 -#define NV4_PFIFO_INTR_0_RUNOUT_NOT_PENDING 0x0 -#define NV4_PFIFO_INTR_0_RUNOUT_PENDING 0x1 -#define NV4_PFIFO_INTR_0_RUNOUT_RESET 0x1 -#define NV4_PFIFO_INTR_0_RUNOUT_OVERFLOW 8 -#define NV4_PFIFO_INTR_0_RUNOUT_OVERFLOW_NOT_PENDING 0x0 -#define NV4_PFIFO_INTR_0_RUNOUT_OVERFLOW_PENDING 0x1 -#define NV4_PFIFO_INTR_0_RUNOUT_OVERFLOW_RESET 0x1 -#define NV4_PFIFO_INTR_0_DMA_PUSHER 12 -#define NV4_PFIFO_INTR_0_DMA_PUSHER_NOT_PENDING 0x0 -#define NV4_PFIFO_INTR_0_DMA_PUSHER_PENDING 0x1 -#define NV4_PFIFO_INTR_0_DMA_PUSHER_RESET 0x1 -#define NV4_PFIFO_INTR_0_DMA_PT 16 -#define NV4_PFIFO_INTR_0_DMA_PT_NOT_PENDING 0x0 -#define NV4_PFIFO_INTR_0_DMA_PT_PENDING 0x1 -#define NV4_PFIFO_INTR_0_DMA_PT_RESET 0x1 -#define NV4_PFIFO_INTR_EN_0 0x2140 -#define NV4_PFIFO_INTR_EN_0_CACHE_ERROR 0 -#define NV4_PFIFO_INTR_EN_0_CACHE_ERROR_ENABLED 0x1 -#define NV4_PFIFO_INTR_EN_0_RUNOUT 4 -#define NV4_PFIFO_INTR_EN_0_RUNOUT_ENABLED 0x1 -#define NV4_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW 8 -#define NV4_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_ENABLED 0x1 -#define NV4_PFIFO_INTR_EN_0_DMA_PUSHER 12 -#define NV4_PFIFO_INTR_EN_0_DMA_PUSHER_ENABLED 0x1 -#define NV4_PFIFO_INTR_EN_0_DMA_PT 16 -#define NV4_PFIFO_INTR_EN_0_DMA_PT_ENABLED 0x1 -#define NV4_PFIFO_RAMHT 0x2210 -#define NV4_PFIFO_RAMHT_BASE_ADDRESS 4 -#define NV4_PFIFO_RAMHT_BASE_ADDRESS_10000 0x10 -#define NV4_PFIFO_RAMHT_SIZE 16 -#define NV4_PFIFO_RAMHT_SIZE_4K 0x0 -#define NV4_PFIFO_RAMHT_SIZE_8K 0x1 -#define NV4_PFIFO_RAMHT_SIZE_16K 0x2 -#define NV4_PFIFO_RAMHT_SIZE_32K 0x3 -#define NV4_PFIFO_RAMHT_SEARCH 24 -#define NV4_PFIFO_RAMHT_SEARCH_16 0x0 -#define NV4_PFIFO_RAMHT_SEARCH_32 0x1 -#define NV4_PFIFO_RAMHT_SEARCH_64 0x2 -#define NV4_PFIFO_RAMHT_SEARCH_128 0x3 -#define NV4_PFIFO_RAMFC 0x2214 -#define NV4_PFIFO_RAMFC_BASE_ADDRESS 1 -#define NV4_PFIFO_RAMFC_BASE_ADDRESS_11000 0x88 -#define NV4_PFIFO_RAMRO 0x2218 -#define NV4_PFIFO_RAMRO_BASE_ADDRESS 1 -#define NV4_PFIFO_RAMRO_BASE_ADDRESS_11200 0x89 -#define NV4_PFIFO_RAMRO_BASE_ADDRESS_12000 0x90 -#define NV4_PFIFO_RAMRO_SIZE 16 -#define NV4_PFIFO_RAMRO_SIZE_512 0x0 -#define NV4_PFIFO_RAMRO_SIZE_8K 0x1 -#define NV4_PFIFO_CACHES 0x2500 -#define NV4_PFIFO_CACHES_REASSIGN 0 -#define NV4_PFIFO_CACHES_REASSIGN_ENABLED 0x1 -#define NV4_PFIFO_CACHES_DMA_SUSPEND 4 -#define NV4_PFIFO_CACHES_DMA_SUSPEND_IDLE 0x0 -#define NV4_PFIFO_CACHES_DMA_SUSPEND_BUSY 0x1 -#define NV4_PFIFO_MODE 0x2504 -// Valid for all 16 channels. Do we need thees at all? -#define NV4_PFIFO_MODE_CHANNEL_IS_PIO 0x0 -#define NV4_PFIFO_MODE_CHANNEL_IS_DMA 0x1 -#define NV4_PFIFO_MODE_CHANNEL_0 0 -#define NV4_PFIFO_MODE_CHANNEL_1 1 -#define NV4_PFIFO_MODE_CHANNEL_2 2 -#define NV4_PFIFO_MODE_CHANNEL_3 3 -#define NV4_PFIFO_MODE_CHANNEL_4 4 -#define NV4_PFIFO_MODE_CHANNEL_5 5 -#define NV4_PFIFO_MODE_CHANNEL_6 6 -#define NV4_PFIFO_MODE_CHANNEL_7 7 -#define NV4_PFIFO_MODE_CHANNEL_8 8 -#define NV4_PFIFO_MODE_CHANNEL_9 9 -#define NV4_PFIFO_MODE_CHANNEL_10 10 -#define NV4_PFIFO_MODE_CHANNEL_11 11 -#define NV4_PFIFO_MODE_CHANNEL_12 12 -#define NV4_PFIFO_MODE_CHANNEL_13 13 -#define NV4_PFIFO_MODE_CHANNEL_14 14 -#define NV4_PFIFO_MODE_CHANNEL_15 15 -#define NV4_PFIFO_DMA 0x2508 -// 0 = not pending (Valid for all channels) -#define NV4_PFIFO_DMA_CHANNEL_IS_PENDING 0x1 -#define NV4_PFIFO_DMA_CHANNEL_0 0 -#define NV4_PFIFO_DMA_CHANNEL_1 1 -#define NV4_PFIFO_DMA_CHANNEL_2 2 -#define NV4_PFIFO_DMA_CHANNEL_3 3 -#define NV4_PFIFO_DMA_CHANNEL_4 4 -#define NV4_PFIFO_DMA_CHANNEL_5 5 -#define NV4_PFIFO_DMA_CHANNEL_6 6 -#define NV4_PFIFO_DMA_CHANNEL_7 7 -#define NV4_PFIFO_DMA_CHANNEL_8 8 -#define NV4_PFIFO_DMA_CHANNEL_9 9 -#define NV4_PFIFO_DMA_CHANNEL_10 10 -#define NV4_PFIFO_DMA_CHANNEL_11 11 -#define NV4_PFIFO_DMA_CHANNEL_12 12 -#define NV4_PFIFO_DMA_CHANNEL_13 13 -#define NV4_PFIFO_DMA_CHANNEL_14 14 -#define NV4_PFIFO_DMA_CHANNEL_15 15 -#define NV4_PFIFO_SIZE 0x250C -// Valid for all channels -#define NV4_PFIFO_SIZE_CHANNEL_SIZE_IS_124_BYTES 0x0 -#define NV4_PFIFO_SIZE_CHANNEL_SIZE_IS_512_BYTES 0x1 -#define NV4_PFIFO_SIZE_CHANNEL_0 0 -#define NV4_PFIFO_SIZE_CHANNEL_1 1 -#define NV4_PFIFO_SIZE_CHANNEL_2 2 -#define NV4_PFIFO_SIZE_CHANNEL_3 3 -#define NV4_PFIFO_SIZE_CHANNEL_4 4 -#define NV4_PFIFO_SIZE_CHANNEL_5 5 -#define NV4_PFIFO_SIZE_CHANNEL_6 6 -#define NV4_PFIFO_SIZE_CHANNEL_7 7 -#define NV4_PFIFO_SIZE_CHANNEL_8 8 -#define NV4_PFIFO_SIZE_CHANNEL_9 9 -#define NV4_PFIFO_SIZE_CHANNEL_10 10 -#define NV4_PFIFO_SIZE_CHANNEL_11 11 -#define NV4_PFIFO_SIZE_CHANNEL_12 12 -#define NV4_PFIFO_SIZE_CHANNEL_13 13 -#define NV4_PFIFO_SIZE_CHANNEL_14 14 -#define NV4_PFIFO_SIZE_CHANNEL_15 15 -#define NV4_PFIFO_CACHE0_PUSH0 0x3000 -#define NV4_PFIFO_CACHE0_PUSH0_ACCESS 0 -#define NV4_PFIFO_CACHE0_PUSH0_ACCESS_ENABLED 0x1 -#define NV4_PFIFO_CACHE1_PUSH0 0x3200 -#define NV4_PFIFO_CACHE1_PUSH0_ACCESS 0 -#define NV4_PFIFO_CACHE1_PUSH0_ACCESS_ENABLED 0x1 -#define NV4_PFIFO_CACHE0_PUSH1 0x3004 -#define NV4_PFIFO_CACHE0_PUSH1_CHID 0 -#define NV4_PFIFO_CACHE1_PUSH1 0x3204 -#define NV4_PFIFO_CACHE1_PUSH1_CHID 0 -#define NV4_PFIFO_CACHE1_PUSH1_MODE 8 -#define NV4_PFIFO_CACHE1_PUSH1_MODE_PIO 0x0 -#define NV4_PFIFO_CACHE1_PUSH1_MODE_DMA 0x1 -#define NV4_PFIFO_CACHE1_DMA_PUSH 0x3220 -#define NV4_PFIFO_CACHE1_DMA_PUSH_ACCESS 0 -#define NV4_PFIFO_CACHE1_DMA_PUSH_ACCESS_ENABLED 0x1 -#define NV4_PFIFO_CACHE1_DMA_PUSH_STATE 4 -#define NV4_PFIFO_CACHE1_DMA_PUSH_STATE_IDLE 0x0 -#define NV4_PFIFO_CACHE1_DMA_PUSH_STATE_BUSY 0x1 -#define NV4_PFIFO_CACHE1_DMA_PUSH_BUFFER 8 -#define NV4_PFIFO_CACHE1_DMA_PUSH_BUFFER_NOT_EMPTY 0x0 -#define NV4_PFIFO_CACHE1_DMA_PUSH_BUFFER_EMPTY 0x1 -#define NV4_PFIFO_CACHE1_DMA_PUSH_STATUS 12 -#define NV4_PFIFO_CACHE1_DMA_PUSH_STATUS_RUNNING 0x0 -#define NV4_PFIFO_CACHE1_DMA_PUSH_STATUS_SUSPENDED 0x1 -#define NV4_PFIFO_CACHE1_DMA_FETCH 0x3224 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG 7:3 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x0 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x1 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x2 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x3 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x4 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x5 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x6 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x7 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x8 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x9 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0xA -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0xB -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0xC -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0xD -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0xE -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0xF -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x10 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x11 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x12 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x13 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x14 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x15 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x16 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x17 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x18 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x19 -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x1A -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x1B -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x1C -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x1D -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x1E -#define NV4_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x1F -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE 13 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x0 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x1 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x2 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x3 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x4 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x5 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x6 -#define NV4_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x7 -// This is a count. 0x0-0xF = number of requests -#define NV4_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 16 -#define NV4_PFIFO_CACHE1_DMA_PUT 0x3240 -#define NV4_PFIFO_CACHE1_DMA_PUT_OFFSET 2 -#define NV4_PFIFO_CACHE1_DMA_GET 0x3244 -#define NV4_PFIFO_CACHE1_DMA_GET_OFFSET 2 -#define NV4_PFIFO_CACHE1_DMA_DCOUNT 0x32A0 -#define NV4_PFIFO_CACHE1_DMA_DCOUNT_VALUE 2 -#define NV4_PFIFO_CACHE1_DMA_GET_JMP_SHADOW 0x32A4 -#define NV4_PFIFO_CACHE1_DMA_GET_JMP_SHADOW_OFFSET 2 -#define NV4_PFIFO_CACHE1_DMA_RSVD_SHADOW 0x32A8 -#define NV4_PFIFO_CACHE1_DMA_RSVD_SHADOW_CMD 0 -#define NV4_PFIFO_CACHE1_DMA_DATA_SHADOW 0x32AC -#define NV4_PFIFO_CACHE1_DMA_DATA_SHADOW_VALUE 0 -#define NV4_PFIFO_CACHE1_DMA_STATE 0x3228 -#define NV4_PFIFO_CACHE1_DMA_STATE_METHOD 2 -#define NV4_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL 13 -#define NV4_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT 18 -#define NV4_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT_0 0x0 -#define NV4_PFIFO_CACHE1_DMA_STATE_ERROR 30 -#define NV4_PFIFO_CACHE1_DMA_STATE_ERROR_NONE 0x0 -#define NV4_PFIFO_CACHE1_DMA_STATE_ERROR_NON_CACHE 0x1 -#define NV4_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD 0x2 -#define NV4_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION 0x3 -#define NV4_PFIFO_CACHE1_DMA_INSTANCE 0x322C -#define NV4_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS 0 -#define NV4_PFIFO_CACHE1_DMA_CTL 0x3230 -#define NV4_PFIFO_CACHE1_DMA_CTL_ADJUST 11:2 -#define NV4_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE 12 -#define NV4_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_NOT_PRESENT 0x0 -#define NV4_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT 0x1 -#define NV4_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY 13 -#define NV4_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_NOT_LINEAR 0x0 -#define NV4_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR 0x1 -#define NV4_PFIFO_CACHE1_DMA_CTL_TARGET_NODE 16 -#define NV4_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_PCI 0x2 -#define NV4_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_AGP 0x3 -#define NV4_PFIFO_CACHE1_DMA_CTL_AT_INFO 31 -#define NV4_PFIFO_CACHE1_DMA_CTL_AT_INFO_INVALID 0x0 -#define NV4_PFIFO_CACHE1_DMA_CTL_AT_INFO_VALID 0x1 -#define NV4_PFIFO_CACHE1_DMA_LIMIT 0x3234 -#define NV4_PFIFO_CACHE1_DMA_LIMIT_OFFSET 2 -#define NV4_PFIFO_CACHE1_DMA_TLB_TAG 0x3238 -#define NV4_PFIFO_CACHE1_DMA_TLB_TAG_ADDRESS 28:12 -#define NV4_PFIFO_CACHE1_DMA_TLB_TAG_STATE 0 -#define NV4_PFIFO_CACHE1_DMA_TLB_TAG_STATE_INVALID 0x0 -#define NV4_PFIFO_CACHE1_DMA_TLB_TAG_STATE_VALID 0x1 -#define NV4_PFIFO_CACHE1_DMA_TLB_PTE 0x323C -#define NV4_PFIFO_CACHE1_DMA_TLB_PTE_FRAME_ADDRESS 12 -#define NV4_PFIFO_CACHE0_PULL0 0x3050 -#define NV4_PFIFO_CACHE0_PULL0_ACCESS 0 -#define NV4_PFIFO_CACHE0_PULL0_ACCESS_ENABLED 0x1 -#define NV4_PFIFO_CACHE0_PULL0_HASH 4 -#define NV4_PFIFO_CACHE0_PULL0_HASH_SUCCEEDED 0x0 -#define NV4_PFIFO_CACHE0_PULL0_HASH_FAILED 0x1 -#define NV4_PFIFO_CACHE0_PULL0_DEVICE 8 -#define NV4_PFIFO_CACHE0_PULL0_DEVICE_HARDWARE 0x0 -#define NV4_PFIFO_CACHE0_PULL0_DEVICE_SOFTWARE 0x1 -#define NV4_PFIFO_CACHE0_PULL0_HASH_STATE 12 -#define NV4_PFIFO_CACHE0_PULL0_HASH_STATE_IDLE 0x0 -#define NV4_PFIFO_CACHE0_PULL0_HASH_STATE_BUSY 0x1 -#define NV4_PFIFO_CACHE1_PULL0 0x3250 -#define NV4_PFIFO_CACHE1_PULL0_ACCESS 0 -#define NV4_PFIFO_CACHE1_PULL0_ACCESS_ENABLED 0x1 -#define NV4_PFIFO_CACHE1_PULL0_HASH 4 -#define NV4_PFIFO_CACHE1_PULL0_HASH_SUCCEEDED 0x0 -#define NV4_PFIFO_CACHE1_PULL0_HASH_FAILED 0x1 -#define NV4_PFIFO_CACHE1_PULL0_DEVICE 8 -#define NV4_PFIFO_CACHE1_PULL0_DEVICE_HARDWARE 0x0 -#define NV4_PFIFO_CACHE1_PULL0_DEVICE_SOFTWARE 0x1 -#define NV4_PFIFO_CACHE1_PULL0_HASH_STATE 12 -#define NV4_PFIFO_CACHE1_PULL0_HASH_STATE_IDLE 0x0 -#define NV4_PFIFO_CACHE1_PULL0_HASH_STATE_BUSY 0x1 -#define NV4_PFIFO_CACHE0_PULL1 0x3054 -#define NV4_PFIFO_CACHE0_PULL1_ENGINE 0 -#define NV4_PFIFO_CACHE0_PULL1_ENGINE_SW 0x0 -#define NV4_PFIFO_CACHE0_PULL1_ENGINE_GRAPHICS 0x1 -#define NV4_PFIFO_CACHE0_PULL1_ENGINE_DVD 0x2 -#define NV4_PFIFO_CACHE1_PULL1 0x3254 -#define NV4_PFIFO_CACHE1_PULL1_ENGINE 0 -#define NV4_PFIFO_CACHE1_PULL1_ENGINE_SW 0x0 -#define NV4_PFIFO_CACHE1_PULL1_ENGINE_GRAPHICS 0x1 -#define NV4_PFIFO_CACHE1_PULL1_ENGINE_DVD 0x2 -#define NV4_PFIFO_CACHE0_HASH 0x3058 -#define NV4_PFIFO_CACHE0_HASH_INSTANCE 0 -#define NV4_PFIFO_CACHE0_HASH_VALID 16 -#define NV4_PFIFO_CACHE1_HASH 0x3258 -#define NV4_PFIFO_CACHE1_HASH_INSTANCE 0 -#define NV4_PFIFO_CACHE1_HASH_VALID 16 -#define NV4_PFIFO_CACHE0_STATUS 0x3014 -#define NV4_PFIFO_CACHE0_STATUS_LOW_MARK 4 -#define NV4_PFIFO_CACHE0_STATUS_LOW_MARK_NOT_EMPTY 0x0 -#define NV4_PFIFO_CACHE0_STATUS_LOW_MARK_EMPTY 0x1 -#define NV4_PFIFO_CACHE0_STATUS_HIGH_MARK 8 -#define NV4_PFIFO_CACHE0_STATUS_HIGH_MARK_NOT_FULL 0x0 -#define NV4_PFIFO_CACHE0_STATUS_HIGH_MARK_FULL 0x1 -#define NV4_PFIFO_CACHE1_STATUS 0x3214 -#define NV4_PFIFO_CACHE1_STATUS_LOW_MARK 4 -#define NV4_PFIFO_CACHE1_STATUS_LOW_MARK_NOT_EMPTY 0x0 -#define NV4_PFIFO_CACHE1_STATUS_LOW_MARK_EMPTY 0x1 -#define NV4_PFIFO_CACHE1_STATUS_HIGH_MARK 8 -#define NV4_PFIFO_CACHE1_STATUS_HIGH_MARK_NOT_FULL 0x0 -#define NV4_PFIFO_CACHE1_STATUS_HIGH_MARK_FULL 0x1 -#define NV4_PFIFO_CACHE1_STATUS1 0x3218 -#define NV4_PFIFO_CACHE1_STATUS1_RANOUT 0 -#define NV4_PFIFO_CACHE1_STATUS1_RANOUT_TRUE 0x1 -#define NV4_PFIFO_CACHE0_PUT 0x3010 -#define NV4_PFIFO_CACHE0_PUT_ADDRESS 2 -#define NV4_PFIFO_CACHE1_PUT 0x3210 -#define NV4_PFIFO_CACHE1_PUT_ADDRESS 2 -#define NV4_PFIFO_CACHE0_GET 0x3070 -#define NV4_PFIFO_CACHE0_GET_ADDRESS 2 -#define NV4_PFIFO_CACHE1_GET 0x3270 -#define NV4_PFIFO_CACHE1_GET_ADDRESS 2 -#define NV4_PFIFO_ENGINE_SW 0x0 -#define NV4_PFIFO_ENGINE_GRAPHICS 0x1 -#define NV4_PFIFO_ENGINE_DVD 0x2 -#define NV4_PFIFO_CACHE0_ENGINE 0x3080 -// For these, see above -#define NV4_PFIFO_CACHE0_SUBCHANNEL_0_ENGINE 0 -#define NV4_PFIFO_CACHE0_SUBCHANNEL_1_ENGINE 4 -#define NV4_PFIFO_CACHE0_SUBCHANNEL_2_ENGINE 8 -#define NV4_PFIFO_CACHE0_SUBCHANNEL_3_ENGINE 12 -#define NV4_PFIFO_CACHE0_SUBCHANNEL_4_ENGINE 16 -#define NV4_PFIFO_CACHE0_SUBCHANNEL_5_ENGINE 20 -#define NV4_PFIFO_CACHE0_SUBCHANNEL_6_ENGINE 24 -#define NV4_PFIFO_CACHE0_SUBCHANNEL_7_ENGINE 28 -#define NV4_PFIFO_CACHE1_ENGINE 0x3280 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_0_ENGINE 0 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_1_ENGINE 4 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_2_ENGINE 8 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_3_ENGINE 12 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_4_ENGINE 16 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_5_ENGINE 20 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_6_ENGINE 24 -#define NV4_PFIFO_CACHE1_SUBCHANNEL_7_ENGINE 28 -#define NV4_PFIFO_CACHE0_METHOD(i) (0x3100+(i)*8) -#define NV4_PFIFO_CACHE0_METHOD_SIZE_1 1 -#define NV4_PFIFO_CACHE0_METHOD_ADDRESS 2 -#define NV4_PFIFO_CACHE0_METHOD_SUBCHANNEL 13 -#define NV4_PFIFO_CACHE1_METHOD(i) (0x3800+(i)*8) -#define NV4_PFIFO_CACHE1_METHOD_SIZE_1 128 -#define NV4_PFIFO_CACHE1_METHOD_ADDRESS 2 -#define NV4_PFIFO_CACHE1_METHOD_SUBCHANNEL 13 -#define NV4_PFIFO_CACHE1_METHOD_ALIAS(i) (0x3C00+(i)*8) -#define NV4_PFIFO_CACHE1_METHOD_ALIAS_SIZE_1 128 -#define NV4_PFIFO_CACHE0_DATA(i) (0x3104+(i)*8) -#define NV4_PFIFO_CACHE0_DATA_SIZE_1 1 -#define NV4_PFIFO_CACHE0_DATA_VALUE 0 -#define NV4_PFIFO_CACHE1_DATA(i) (0x3804+(i)*8) -#define NV4_PFIFO_CACHE1_DATA_SIZE_1 128 -#define NV4_PFIFO_CACHE1_DATA_VALUE 0 -#define NV4_PFIFO_CACHE1_DATA_ALIAS(i) (0x3C04+(i)*8) -#define NV4_PFIFO_CACHE1_DATA_ALIAS_SIZE_1 128 -#define NV4_PFIFO_DEVICE(i) (0x2800+(i)*4) -#define NV4_PFIFO_DEVICE_SIZE_1 128 -#define NV4_PFIFO_DEVICE_CHID 0 -#define NV4_PFIFO_DEVICE_SWITCH 24 -#define NV4_PFIFO_DEVICE_SWITCH_AVAILABLE 0x1 -#define NV4_PFIFO_RUNOUT_STATUS 0x2400 -#define NV4_PFIFO_RUNOUT_STATUS_RANOUT 0 -#define NV4_PFIFO_RUNOUT_STATUS_RANOUT_TRUE 0x1 -#define NV4_PFIFO_RUNOUT_STATUS_LOW_MARK 4 -#define NV4_PFIFO_RUNOUT_STATUS_LOW_MARK_NOT_EMPTY 0x0 -#define NV4_PFIFO_RUNOUT_STATUS_LOW_MARK_EMPTY 0x1 -#define NV4_PFIFO_RUNOUT_STATUS_HIGH_MARK 8 -#define NV4_PFIFO_RUNOUT_STATUS_HIGH_MARK_NOT_FULL 0x0 -#define NV4_PFIFO_RUNOUT_STATUS_HIGH_MARK_FULL 0x1 -#define NV4_PFIFO_RUNOUT_PUT 0x2410 -#define NV4_PFIFO_RUNOUT_PUT_ADDRESS 3 // if size=0, 8:3, otherwise 12:3 -#define NV4_PFIFO_RUNOUT_GET 0x2420 -#define NV4_PFIFO_RUNOUT_GET_ADDRESS 3 // 13:3 - -#define NV4_PGRAPH_START 0x400000 -#define NV4_PGRAPH_END 0x401FFF - -#define NV4_PGRAPH_DEBUG_0 0x400080 -#define NV4_PGRAPH_DEBUG_0_STATE 0 -#define NV4_PGRAPH_DEBUG_0_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_FE_STATE 1 -#define NV4_PGRAPH_DEBUG_0_FE_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_FE_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_CACHE_STATE 2 -#define NV4_PGRAPH_DEBUG_0_CACHE_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_CACHE_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_D3D_PIPE_STATE 3 -#define NV4_PGRAPH_DEBUG_0_D3D_PIPE_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_D3D_PIPE_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_PREROP_STATE 4 -#define NV4_PGRAPH_DEBUG_0_PREROP_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_PREROP_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_ROP_STATE 5 -#define NV4_PGRAPH_DEBUG_0_ROP_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_ROP_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_RSTR_STATE 6 -#define NV4_PGRAPH_DEBUG_0_RSTR_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_RSTR_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_LIGHT_STATE 7 -#define NV4_PGRAPH_DEBUG_0_LIGHT_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_LIGHT_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_DMA_STATE 8 -#define NV4_PGRAPH_DEBUG_0_DMA_STATE_NORMAL 0x0 -#define NV4_PGRAPH_DEBUG_0_DMA_STATE_RESET 0x1 -#define NV4_PGRAPH_DEBUG_0_SPARE1 12 -#define NV4_PGRAPH_DEBUG_0_SPARE2 13 -#define NV4_PGRAPH_DEBUG_0_MINUSD5 14 -#define NV4_PGRAPH_DEBUG_0_MINUSD5_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_BLIT_DST_LIMIT 15 -#define NV4_PGRAPH_DEBUG_0_BLIT_DST_LIMIT_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_LIMIT_CHECK 16 -#define NV4_PGRAPH_DEBUG_0_LIMIT_CHECK_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_LIMIT_INT 17 -#define NV4_PGRAPH_DEBUG_0_LIMIT_INT_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_OVRFLW_INT 18 -#define NV4_PGRAPH_DEBUG_0_OVRFLW_INT_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_WRITE_ONLY_ROPS_2D 20 -#define NV4_PGRAPH_DEBUG_0_WRITE_ONLY_ROPS_2D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_WRITE_ONLY_ROPS_3D 21 -#define NV4_PGRAPH_DEBUG_0_WRITE_ONLY_ROPS_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_DRAWDIR_AUTO 24 -#define NV4_PGRAPH_DEBUG_0_DRAWDIR_AUTO_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_0_DRAWDIR_Y 25 -#define NV4_PGRAPH_DEBUG_0_DRAWDIR_Y_DECR 0x0 -#define NV4_PGRAPH_DEBUG_0_DRAWDIR_Y_INCR 0x1 -#define NV4_PGRAPH_DEBUG_0_ALPHA_ABORT 28 -#define NV4_PGRAPH_DEBUG_0_ALPHA_ABORT_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1 0x400084 -#define NV4_PGRAPH_DEBUG_1_VOLATILE_RESET 0 -#define NV4_PGRAPH_DEBUG_1_VOLATILE_RESET_NOT_LAST 0x0 -#define NV4_PGRAPH_DEBUG_1_VOLATILE_RESET_LAST 0x1 -#define NV4_PGRAPH_DEBUG_1_DMA_ACTIVITY 4 -#define NV4_PGRAPH_DEBUG_1_DMA_ACTIVITY_IGNORE 0x0 -#define NV4_PGRAPH_DEBUG_1_DMA_ACTIVITY_CANCEL 0x1 -#define NV4_PGRAPH_DEBUG_1_PATCH_INV 8 -#define NV4_PGRAPH_DEBUG_1_PATCH_INV_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_ALT_RW_SEQ 10 -#define NV4_PGRAPH_DEBUG_1_ALT_RW_SEQ_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_TRI_OPTS 12 -#define NV4_PGRAPH_DEBUG_1_TRI_OPTS_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_TRICLIP_OPTS 13 -#define NV4_PGRAPH_DEBUG_1_TRICLIP_OPTS_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_INSTANCE 16 -#define NV4_PGRAPH_DEBUG_1_INSTANCE_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_ALOM_BURST 17 -#define NV4_PGRAPH_DEBUG_1_ALOM_BURST_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_BIDIR_DRAIN 18 -#define NV4_PGRAPH_DEBUG_1_BIDIR_DRAIN_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_EARLY_POST 19 -#define NV4_PGRAPH_DEBUG_1_EARLY_POST_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_CTX 20 -#define NV4_PGRAPH_DEBUG_1_CTX_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_FIXED_ADRS 21 -#define NV4_PGRAPH_DEBUG_1_FIXED_ADRS_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_DITHER_RANGE_ADJ_2D 22 -#define NV4_PGRAPH_DEBUG_1_DITHER_RANGE_ADJ_2D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_DITHER_RANGE_ADJ_3D 23 -#define NV4_PGRAPH_DEBUG_1_DITHER_RANGE_ADJ_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_CACHE 24 -#define NV4_PGRAPH_DEBUG_1_CACHE_IGNORE 0x0 -#define NV4_PGRAPH_DEBUG_1_CACHE_FLUSH 0x1 -#define NV4_PGRAPH_DEBUG_1_CACHE_MODE 25 -#define NV4_PGRAPH_DEBUG_1_CACHE_MODE_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_ZCLAMP 28 -#define NV4_PGRAPH_DEBUG_1_ZCLAMP_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_UCLAMP 29 -#define NV4_PGRAPH_DEBUG_1_UCLAMP_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_RCLAMP 30 -#define NV4_PGRAPH_DEBUG_1_RCLAMP_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_1_DX6_2PIXMODE 31 -#define NV4_PGRAPH_DEBUG_1_DX6_2PIXMODE_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2 0x400088 -#define NV4_PGRAPH_DEBUG_2_HONOR_SRCFMT 0 -#define NV4_PGRAPH_DEBUG_2_HONOR_SRCFMT_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_PINGPONG 0 -#define NV4_PGRAPH_DEBUG_2_PINGPONG_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_SPARE1 4 -#define NV4_PGRAPH_DEBUG_2_SPARE2 5 -#define NV4_PGRAPH_DEBUG_2_SPARE3 6 -#define NV4_PGRAPH_DEBUG_2_SPARE4 7 -#define NV4_PGRAPH_DEBUG_2_SPARE5 8 -#define NV4_PGRAPH_DEBUG_2_SPARE6 9 -#define NV4_PGRAPH_DEBUG_2_SPARE7 10 -#define NV4_PGRAPH_DEBUG_2_MCLK_RECTS 11 -#define NV4_PGRAPH_DEBUG_2_MCLK_RECTS_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_BILINEAR_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_ANISOTROPIC_3D 13 -#define NV4_PGRAPH_DEBUG_2_ANISOTROPIC_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_FOG_3D 14 -#define NV4_PGRAPH_DEBUG_2_FOG_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_SPECULAR_3D 15 -#define NV4_PGRAPH_DEBUG_2_SPECULAR_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_ALPHA_3D 16 -#define NV4_PGRAPH_DEBUG_2_ALPHA_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_ZBUF_SEQ 17 -#define NV4_PGRAPH_DEBUG_2_ZBUF_SEQ_CRZRWCW 0x0 -#define NV4_PGRAPH_DEBUG_2_ZBUF_SEQ_ZRWCRW 0x1 -#define NV4_PGRAPH_DEBUG_2_ZBUF_SEQ_AUTO 0x2 -#define NV4_PGRAPH_DEBUG_2_COELESCE_D3D 20 -#define NV4_PGRAPH_DEBUG_2_COELESCE_D3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_COELESCE_2D 22 -#define NV4_PGRAPH_DEBUG_2_COELESCE_2D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_FAST_VERTEX_LOAD 23 -#define NV4_PGRAPH_DEBUG_2_FAST_VERTEX_LOAD_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_BLIT_MULTILINE 24 -#define NV4_PGRAPH_DEBUG_2_BLIT_MULTILINE_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_2_VOLATILE_RESET 28 -#define NV4_PGRAPH_DEBUG_2_VOLATILE_RESET_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3 0x40008C -#define NV4_PGRAPH_DEBUG_3_CULLING 0 -#define NV4_PGRAPH_DEBUG_3_CULLING_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_CULLING_TYPE 1 -#define NV4_PGRAPH_DEBUG_3_CULLING_TYPE_DX3 0x0 -#define NV4_PGRAPH_DEBUG_3_CULLING_TYPE_DX5 0x1 -#define NV4_PGRAPH_DEBUG_3_FAST_DATA_STRTCH 4 -#define NV4_PGRAPH_DEBUG_3_FAST_DATA_STRTCH_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_FAST_DATA_D3D 5 -#define NV4_PGRAPH_DEBUG_3_FAST_DATA_D3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_FAST_DATA_IMAGE 6 -#define NV4_PGRAPH_DEBUG_3_FAST_DATA_IMAGE_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_ZFLUSH 7 -#define NV4_PGRAPH_DEBUG_3_ZFLUSH_IGNORE 0x0 -#define NV4_PGRAPH_DEBUG_3_ZFLUSH_ACTIVATE 0x1 -#define NV4_PGRAPH_DEBUG_3_AUTOZFLUSH_PTZ 8 -#define NV4_PGRAPH_DEBUG_3_AUTOZFLUSH_PTZ_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_AUTOZFLUSH_D3D 9 -#define NV4_PGRAPH_DEBUG_3_AUTOZFLUSH_D3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_SLOT_CONFLICT_PTZ 10 -#define NV4_PGRAPH_DEBUG_3_SLOT_CONFLICT_PTZ_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_SLOT_CONFLICT_D3D 11 -#define NV4_PGRAPH_DEBUG_3_SLOT_CONFLICT_D3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_POSTDITHER_2D 12 -#define NV4_PGRAPH_DEBUG_3_POSTDITHER_2D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_POSTDITHER_3D 13 -#define NV4_PGRAPH_DEBUG_3_POSTDITHER_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_PREDITHER_2D 14 -#define NV4_PGRAPH_DEBUG_3_PREDITHER_2D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_PREDITHER_3D 15 -#define NV4_PGRAPH_DEBUG_3_PREDITHER_3D_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_FORCE_CREAD 16 -#define NV4_PGRAPH_DEBUG_3_FORCE_CREAD_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_FORCE_ZREAD 17 -#define NV4_PGRAPH_DEBUG_3_FORCE_ZREAD_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_EARLYZ_ABORT 18 -#define NV4_PGRAPH_DEBUG_3_EARLYZ_ABORT_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_TRIEND_FLUSH 19 -#define NV4_PGRAPH_DEBUG_3_TRIEND_FLUSH_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_DATA_CHECK 20 -#define NV4_PGRAPH_DEBUG_3_DATA_CHECK_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_DATA_CHECK_FAIL 21 -#define NV4_PGRAPH_DEBUG_3_DATA_CHECK_FAIL_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_FORMAT_CHECK 22 -#define NV4_PGRAPH_DEBUG_3_FORMAT_CHECK_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_DMA_CHECK 23 -#define NV4_PGRAPH_DEBUG_3_DMA_CHECK_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_RAMREADBACK 24 -#define NV4_PGRAPH_DEBUG_3_RAMREADBACK_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_CLIP_METHODS 25 -#define NV4_PGRAPH_DEBUG_3_CLIP_METHODS_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_EXCLUDE_ROP_IN_IDLE 27 -#define NV4_PGRAPH_DEBUG_3_EXCLUDE_ROP_IN_IDLE_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_STATE_CHECK 28 -#define NV4_PGRAPH_DEBUG_3_STATE_CHECK_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_CONTEXT_METHODS 29 -#define NV4_PGRAPH_DEBUG_3_CONTEXT_METHODS_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_OPERATION_METHOD 30 -#define NV4_PGRAPH_DEBUG_3_OPERATION_METHOD_ENABLED 0x1 -#define NV4_PGRAPH_DEBUG_3_IGNORE_PATCHVALID 31 -#define NV4_PGRAPH_DEBUG_3_IGNORE_PATCHVALID_ENABLED 0x1 -#define NV4_PGRAPH_INTR 0x400100 -#define NV4_PGRAPH_INTR_NOTIFY 0 -#define NV4_PGRAPH_INTR_NOTIFY_NOT_PENDING 0x0 -#define NV4_PGRAPH_INTR_NOTIFY_PENDING 0x1 -#define NV4_PGRAPH_INTR_NOTIFY_RESET 0x1 -#define NV4_PGRAPH_INTR_MISSING_HW 4 -#define NV4_PGRAPH_INTR_MISSING_HW_NOT_PENDING 0x0 -#define NV4_PGRAPH_INTR_MISSING_HW_PENDING 0x1 -#define NV4_PGRAPH_INTR_MISSING_HW_RESET 0x1 -#define NV4_PGRAPH_INTR_TLB_PRESENT_A 8 -#define NV4_PGRAPH_INTR_TLB_PRESENT_A_NOT_PENDING 0x0 -#define NV4_PGRAPH_INTR_TLB_PRESENT_A_PENDING 0x1 -#define NV4_PGRAPH_INTR_TLB_PRESENT_A_RESET 0x1 -#define NV4_PGRAPH_INTR_TLB_PRESENT_B 9 -#define NV4_PGRAPH_INTR_TLB_PRESENT_B_NOT_PENDING 0x0 -#define NV4_PGRAPH_INTR_TLB_PRESENT_B_PENDING 0x1 -#define NV4_PGRAPH_INTR_TLB_PRESENT_B_RESET 0x1 -#define NV4_PGRAPH_INTR_CONTEXT_SWITCH 12 -#define NV4_PGRAPH_INTR_CONTEXT_SWITCH_NOT_PENDING 0x0 -#define NV4_PGRAPH_INTR_CONTEXT_SWITCH_PENDING 0x1 -#define NV4_PGRAPH_INTR_CONTEXT_SWITCH_RESET 0x1 -#define NV4_PGRAPH_INTR_BUFFER_NOTIFY 16 -#define NV4_PGRAPH_INTR_BUFFER_NOTIFY_NOT_PENDING 0x0 -#define NV4_PGRAPH_INTR_BUFFER_NOTIFY_PENDING 0x1 -#define NV4_PGRAPH_INTR_BUFFER_NOTIFY_RESET 0x1 -#define NV4_PGRAPH_NSTATUS 0x400104 -#define NV4_PGRAPH_NSTATUS_STATE_IN_USE 11 -#define NV4_PGRAPH_NSTATUS_STATE_IN_USE_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSTATUS_STATE_IN_USE_PENDING 0x1 -#define NV4_PGRAPH_NSTATUS_INVALID_STATE 12 -#define NV4_PGRAPH_NSTATUS_INVALID_STATE_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSTATUS_INVALID_STATE_PENDING 0x1 -#define NV4_PGRAPH_NSTATUS_BAD_ARGUMENT 13 -#define NV4_PGRAPH_NSTATUS_BAD_ARGUMENT_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSTATUS_BAD_ARGUMENT_PENDING 0x1 -#define NV4_PGRAPH_NSTATUS_PROTECTION_FAULT 14 -#define NV4_PGRAPH_NSTATUS_PROTECTION_FAULT_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSTATUS_PROTECTION_FAULT_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE 0x400108 -#define NV4_PGRAPH_NSOURCE_NOTIFICATION 0 -#define NV4_PGRAPH_NSOURCE_NOTIFICATION_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_NOTIFICATION_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_DATA_ERROR 1 -#define NV4_PGRAPH_NSOURCE_DATA_ERROR_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_DATA_ERROR_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_PROTECTION_ERROR 2 -#define NV4_PGRAPH_NSOURCE_PROTECTION_ERROR_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_PROTECTION_ERROR_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_RANGE_EXCEPTION 3 -#define NV4_PGRAPH_NSOURCE_RANGE_EXCEPTION_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_RANGE_EXCEPTION_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_LIMIT_COLOR 4 -#define NV4_PGRAPH_NSOURCE_LIMIT_COLOR_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_LIMIT_COLOR_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_LIMIT_ZETA_ 5 -#define NV4_PGRAPH_NSOURCE_LIMIT_ZETA_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_LIMIT_ZETA_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_ILLEGAL_MTHD 6 -#define NV4_PGRAPH_NSOURCE_ILLEGAL_MTHD_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_ILLEGAL_MTHD_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_DMA_R_PROTECTION 7 -#define NV4_PGRAPH_NSOURCE_DMA_R_PROTECTION_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_DMA_R_PROTECTION_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_DMA_W_PROTECTION 8 -#define NV4_PGRAPH_NSOURCE_DMA_W_PROTECTION_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_DMA_W_PROTECTION_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_FORMAT_EXCEPTION 9 -#define NV4_PGRAPH_NSOURCE_FORMAT_EXCEPTION_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_FORMAT_EXCEPTION_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_PATCH_EXCEPTION 10 -#define NV4_PGRAPH_NSOURCE_PATCH_EXCEPTION_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_PATCH_EXCEPTION_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_STATE_INVALID 11 -#define NV4_PGRAPH_NSOURCE_STATE_INVALID_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_STATE_INVALID_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_DOUBLE_NOTIFY 12 -#define NV4_PGRAPH_NSOURCE_DOUBLE_NOTIFY_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_DOUBLE_NOTIFY_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_NOTIFY_IN_USE 13 -#define NV4_PGRAPH_NSOURCE_NOTIFY_IN_USE_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_NOTIFY_IN_USE_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_METHOD_CNT 14 -#define NV4_PGRAPH_NSOURCE_METHOD_CNT_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_METHOD_CNT_PENDING 0x1 -#define NV4_PGRAPH_NSOURCE_BFR_NOTIFICATION 15 -#define NV4_PGRAPH_NSOURCE_BFR_NOTIFICATION_NOT_PENDING 0x0 -#define NV4_PGRAPH_NSOURCE_BFR_NOTIFICATION_PENDING 0x1 -#define NV4_PGRAPH_INTR_EN 0x400140 -#define NV4_PGRAPH_INTR_EN_NOTIFY 0 -#define NV4_PGRAPH_INTR_EN_NOTIFY_ENABLED 0x1 -#define NV4_PGRAPH_INTR_EN_MISSING_HW 4 -#define NV4_PGRAPH_INTR_EN_MISSING_HW_ENABLED 0x1 -#define NV4_PGRAPH_INTR_EN_TLB_PRESENT_A 8 -#define NV4_PGRAPH_INTR_EN_TLB_PRESENT_A_ENABLED 0x1 -#define NV4_PGRAPH_INTR_EN_TLB_PRESENT_B 9 -#define NV4_PGRAPH_INTR_EN_TLB_PRESENT_B_ENABLED 0x1 -#define NV4_PGRAPH_INTR_EN_CONTEXT_SWITCH 12 -#define NV4_PGRAPH_INTR_EN_CONTEXT_SWITCH_ENABLED 0x1 -#define NV4_PGRAPH_INTR_EN_BUFFER_NOTIFY 16 -#define NV4_PGRAPH_INTR_EN_BUFFER_NOTIFY_ENABLED 0x1 -#define NV4_PGRAPH_CTX_SWITCH1 0x400160 -#define NV4_PGRAPH_CTX_SWITCH1_GRCLASS 0 -#define NV4_PGRAPH_CTX_SWITCH1_CHROMA_KEY 12 -#define NV4_PGRAPH_CTX_SWITCH1_CHROMA_KEY_DISABLE 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_CHROMA_KEY_ENABLE 0x1 -#define NV4_PGRAPH_CTX_SWITCH1_USER_CLIP 13 -#define NV4_PGRAPH_CTX_SWITCH1_USER_CLIP_DISABLE 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_USER_CLIP_ENABLE 0x1 -#define NV4_PGRAPH_CTX_SWITCH1_SWIZZLE 14 -#define NV4_PGRAPH_CTX_SWITCH1_SWIZZLE_DISABLE 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_SWIZZLE_ENABLE 0x1 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_CONFIG 17:15 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_AND 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_ROP_AND 0x1 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_AND 0x2 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY 0x3 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_PRE 0x4 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_PRE 0x5 -#define NV4_PGRAPH_CTX_SWITCH1_DITHER_MODE 20 -#define NV4_PGRAPH_CTX_SWITCH1_DITHER_MODE_COMPATIBILITY 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_DITHER_MODE_DITHER 0x1 -#define NV4_PGRAPH_CTX_SWITCH1_DITHER_MODE_TRUNCATE 0x2 -#define NV4_PGRAPH_CTX_SWITCH1_DITHER_MODE_MS 0x3 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_STATUS 24 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_STATUS_INVALID 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_PATCH_STATUS_VALID 0x1 -#define NV4_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE 25 -#define NV4_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_INVALID 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_VALID 0x1 -#define NV4_PGRAPH_CTX_SWITCH1_VOLATILE_RESET 31 -#define NV4_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_IGNORE 0x0 -#define NV4_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_ENABLED 0x1 -#define NV4_PGRAPH_CTX_SWITCH2 0x400164 -#define NV4_PGRAPH_CTX_SWITCH2_MONO_FORMAT 0 -#define NV4_PGRAPH_CTX_SWITCH2_MONO_FORMAT_INVALID 0x00 -#define NV4_PGRAPH_CTX_SWITCH2_MONO_FORMAT_CGA6_M1 0x01 -#define NV4_PGRAPH_CTX_SWITCH2_MONO_FORMAT_LE_M1 0x02 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT 13:8 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_INVALID 0x00 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y8 0x01 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A8Y8 0x02 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X24Y8 0x03 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A1R5G5B5 0x06 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X1R5G5B5 0x07 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A1R5G5B5 0x08 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X17R5G5B5 0x09 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_R5G6B5 0x0A -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16R5G6B5 0x0B -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16R5G6B5 0x0C -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A8R8G8B8 0x0D -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X8R8G8B8 0x0E -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y16 0x0F -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16Y16 0x10 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16Y16 0x11 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_V8YB8U8YA8 0x12 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_YB8V8YA8U8 0x13 -#define NV4_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y32 0x14 -#define NV4_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE 16 -#define NV4_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE_INVALID 0x00 -#define NV4_PGRAPH_CTX_SWITCH3 0x400168 -#define NV4_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0 0 -#define NV4_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0_INVALID 0x00 -#define NV4_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1 16 -#define NV4_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1_INVALID 0x00 -#define NV4_PGRAPH_CTX_SWITCH4 0x40016C -#define NV4_PGRAPH_CTX_SWITCH4_USER_INSTANCE 0 -#define NV4_PGRAPH_CTX_SWITCH4_USER_INSTANCE_INVALID 0x00 -#define NV4_PGRAPH_CTX_CACHE1(i) (0x400180+(i)*4) -#define NV4_PGRAPH_CTX_CACHE1_SIZE_1 8 -#define NV4_PGRAPH_CTX_CACHE1_GRCLASS 0 -#define NV4_PGRAPH_CTX_CACHE1_CHROMA_KEY 12 -#define NV4_PGRAPH_CTX_CACHE1_USER_CLIP 13 -#define NV4_PGRAPH_CTX_CACHE1_SWIZZLE 14 -#define NV4_PGRAPH_CTX_CACHE1_PATCH_CONFIG 19:15 -#define NV4_PGRAPH_CTX_CACHE1_SPARE1 20 -#define NV4_PGRAPH_CTX_CACHE1_PATCH_STATUS 24 -#define NV4_PGRAPH_CTX_CACHE1_CONTEXT_SURFACE 25 -#define NV4_PGRAPH_CTX_CACHE2(i) (0x4001a0+(i)*4) -#define NV4_PGRAPH_CTX_CACHE2_SIZE_1 8 -#define NV4_PGRAPH_CTX_CACHE2_MONO_FORMAT 0 -#define NV4_PGRAPH_CTX_CACHE2_COLOR_FORMAT 13:8 -#define NV4_PGRAPH_CTX_CACHE2_NOTIFY_INSTANCE 16 -#define NV4_PGRAPH_CTX_CACHE3(i) (0x4001c0+(i)*4) -#define NV4_PGRAPH_CTX_CACHE3_SIZE_1 8 -#define NV4_PGRAPH_CTX_CACHE3_DMA_INSTANCE_0 0 -#define NV4_PGRAPH_CTX_CACHE3_DMA_INSTANCE_1 16 -#define NV4_PGRAPH_CTX_CACHE4(i) (0x4001e0+(i)*4) -#define NV4_PGRAPH_CTX_CACHE4_SIZE_1 8 -#define NV4_PGRAPH_CTX_CACHE4_USER_INSTANCE 0 -#define NV4_PGRAPH_CTX_CONTROL 0x400170 -#define NV4_PGRAPH_CTX_CONTROL_MINIMUM_TIME 0 -#define NV4_PGRAPH_CTX_CONTROL_MINIMUM_TIME_33US 0x0 -#define NV4_PGRAPH_CTX_CONTROL_MINIMUM_TIME_262US 0x1 -#define NV4_PGRAPH_CTX_CONTROL_MINIMUM_TIME_2MS 0x2 -#define NV4_PGRAPH_CTX_CONTROL_MINIMUM_TIME_17MS 0x3 -#define NV4_PGRAPH_CTX_CONTROL_TIME 8 -#define NV4_PGRAPH_CTX_CONTROL_TIME_EXPIRED 0x0 -#define NV4_PGRAPH_CTX_CONTROL_TIME_NOT_EXPIRED 0x1 -#define NV4_PGRAPH_CTX_CONTROL_CHID 16 -#define NV4_PGRAPH_CTX_CONTROL_CHID_INVALID 0x0 -#define NV4_PGRAPH_CTX_CONTROL_CHID_VALID 0x1 -#define NV4_PGRAPH_CTX_CONTROL_CHANGE 20 -#define NV4_PGRAPH_CTX_CONTROL_CHANGE_UNAVAILABLE 0x0 -#define NV4_PGRAPH_CTX_CONTROL_CHANGE_AVAILABLE 0x1 -#define NV4_PGRAPH_CTX_CONTROL_SWITCHING 24 -#define NV4_PGRAPH_CTX_CONTROL_SWITCHING_IDLE 0x0 -#define NV4_PGRAPH_CTX_CONTROL_SWITCHING_BUSY 0x1 -#define NV4_PGRAPH_CTX_CONTROL_DEVICE 28 -#define NV4_PGRAPH_CTX_CONTROL_DEVICE_DISABLED 0x0 -#define NV4_PGRAPH_CTX_CONTROL_DEVICE_ENABLED 0x1 -#define NV4_PGRAPH_CTX_USER 0x400174 -#define NV4_PGRAPH_CTX_USER_SUBCH 13 -#define NV4_PGRAPH_CTX_USER_SUBCH_0 0x0 -#define NV4_PGRAPH_CTX_USER_CHID 24 -#define NV4_PGRAPH_CTX_USER_CHID_0 0x0 -#define NV4_PGRAPH_FIFO 0x400720 -#define NV4_PGRAPH_FIFO_ACCESS 0 -#define NV4_PGRAPH_FIFO_ACCESS_DISABLED 0x0 -#define NV4_PGRAPH_FIFO_ACCESS_ENABLED 0x1 -#define NV4_PGRAPH_FFINTFC_FIFO_0(i) (0x400730+(i)*4) -#define NV4_PGRAPH_FFINTFC_FIFO_0_SIZE_1 4 -#define NV4_PGRAPH_FFINTFC_FIFO_0_TAG 0 -#define NV4_PGRAPH_FFINTFC_FIFO_0_TAG_MTHD 0x0 -#define NV4_PGRAPH_FFINTFC_FIFO_0_TAG_CHSW 0x1 -// Note: shift left by 1 (3:1). Subch number = 0-7 -#define NV4_PGRAPH_FFINTFC_FIFO_0_SUBCH 1 -#define NV4_PGRAPH_FFINTFC_FIFO_0_MTHD 4 -#define NV4_PGRAPH_FFINTFC_FIFO_0_MTHD_CTX_SWITCH 0x0 -#define NV4_PGRAPH_FFINTFC_FIFO_1(i) (0x400740+(i)*4) -#define NV4_PGRAPH_FFINTFC_FIFO_1_SIZE_1 4 -#define NV4_PGRAPH_FFINTFC_FIFO_1_ARGUMENT 0 -#define NV4_PGRAPH_FFINTFC_FIFO_PTR 0x400750 -#define NV4_PGRAPH_FFINTFC_FIFO_PTR_WRITE 0 -#define NV4_PGRAPH_FFINTFC_FIFO_PTR_WRITE_0 0x0 -#define NV4_PGRAPH_FFINTFC_FIFO_PTR_READ 4 -#define NV4_PGRAPH_FFINTFC_FIFO_PTR_READ_0 0x0 -#define NV4_PGRAPH_FFINTFC_ST2 0x400754 -#define NV4_PGRAPH_FFINTFC_ST2_STATUS 0 -#define NV4_PGRAPH_FFINTFC_ST2_STATUS_INVALID 0x0 -#define NV4_PGRAPH_FFINTFC_ST2_STATUS_VALID 0x1 -#define NV4_PGRAPH_FFINTFC_ST2_MTHD 1 -#define NV4_PGRAPH_FFINTFC_ST2_MTHD_CTX_SWITCH 0x0 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH 12 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_0 0x0 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_1 0x1 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_2 0x2 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_3 0x3 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_4 0x4 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_5 0x5 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_6 0x6 -#define NV4_PGRAPH_FFINTFC_ST2_SUBCH_7 0x7 -#define NV4_PGRAPH_FFINTFC_ST2_CHID 15 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_0 0x0 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_1 0x1 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_2 0x2 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_3 0x3 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_4 0x4 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_5 0x5 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_6 0x6 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_7 0x7 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_8 0x8 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_9 0x9 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_10 0xA -#define NV4_PGRAPH_FFINTFC_ST2_CHID_11 0xB -#define NV4_PGRAPH_FFINTFC_ST2_CHID_12 0xC -#define NV4_PGRAPH_FFINTFC_ST2_CHID_13 0xD -#define NV4_PGRAPH_FFINTFC_ST2_CHID_14 0xE -#define NV4_PGRAPH_FFINTFC_ST2_CHID_15 0xF -#define NV4_PGRAPH_FFINTFC_ST2_CHID_STATUS 19 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_STATUS_INVALID 0x0 -#define NV4_PGRAPH_FFINTFC_ST2_CHID_STATUS_VALID 0x1 -#define NV4_PGRAPH_FFINTFC_ST2_CH_SWITCH_DETECT 20 -#define NV4_PGRAPH_FFINTFC_ST2_CH_SWITCH_DETECT_CLEAR 0x0 -#define NV4_PGRAPH_FFINTFC_ST2_CH_SWITCH_DETECT_SET 0x1 -#define NV4_PGRAPH_FFINTFC_ST2_FIFO_HOLD 21 -#define NV4_PGRAPH_FFINTFC_ST2_FIFO_HOLD_CLEAR 0x0 -#define NV4_PGRAPH_FFINTFC_ST2_FIFO_HOLD_SET 0x1 -#define NV4_PGRAPH_FFINTFC_ST2_D 0x400758 -#define NV4_PGRAPH_FFINTFC_ST2_D_ARGUMENT 0 -#define NV4_PGRAPH_FFINTFC_ST2_D_ARGUMENT_0 0x0 -#define NV4_PGRAPH_STATUS 0x400700 -#define NV4_PGRAPH_STATUS_STATE 0 -#define NV4_PGRAPH_STATUS_STATE_IDLE 0x0 -#define NV4_PGRAPH_STATUS_STATE_BUSY 0x1 -#define NV4_PGRAPH_STATUS_XY_LOGIC 4 -#define NV4_PGRAPH_STATUS_XY_LOGIC_IDLE 0x0 -#define NV4_PGRAPH_STATUS_XY_LOGIC_BUSY 0x1 -#define NV4_PGRAPH_STATUS_FE 5 -#define NV4_PGRAPH_STATUS_FE_IDLE 0x0 -#define NV4_PGRAPH_STATUS_FE_BUSY 0x1 -#define NV4_PGRAPH_STATUS_RASTERIZER 6 -#define NV4_PGRAPH_STATUS_RASTERIZER_IDLE 0x0 -#define NV4_PGRAPH_STATUS_RASTERIZER_BUSY 0x1 -#define NV4_PGRAPH_STATUS_PORT_NOTIFY 8 -#define NV4_PGRAPH_STATUS_PORT_NOTIFY_IDLE 0x0 -#define NV4_PGRAPH_STATUS_PORT_NOTIFY_BUSY 0x1 -#define NV4_PGRAPH_STATUS_PORT_REGISTER 12 -#define NV4_PGRAPH_STATUS_PORT_REGISTER_IDLE 0x0 -#define NV4_PGRAPH_STATUS_PORT_REGISTER_BUSY 0x1 -#define NV4_PGRAPH_STATUS_PORT_DMA 16 -#define NV4_PGRAPH_STATUS_PORT_DMA_IDLE 0x0 -#define NV4_PGRAPH_STATUS_PORT_DMA_BUSY 0x1 -#define NV4_PGRAPH_STATUS_DMA_ENGINE 17 -#define NV4_PGRAPH_STATUS_DMA_ENGINE_IDLE 0x0 -#define NV4_PGRAPH_STATUS_DMA_ENGINE_BUSY 0x1 -#define NV4_PGRAPH_STATUS_DMA_NOTIFY 20 -#define NV4_PGRAPH_STATUS_DMA_NOTIFY_IDLE 0x0 -#define NV4_PGRAPH_STATUS_DMA_NOTIFY_BUSY 0x1 -#define NV4_PGRAPH_STATUS_DMA_BUFFER_NOTIFY 21 -#define NV4_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_IDLE 0x0 -#define NV4_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_BUSY 0x1 -#define NV4_PGRAPH_STATUS_D3D 24 -#define NV4_PGRAPH_STATUS_D3D_IDLE 0x0 -#define NV4_PGRAPH_STATUS_D3D_BUSY 0x1 -#define NV4_PGRAPH_STATUS_CACHE 25 -#define NV4_PGRAPH_STATUS_CACHE_IDLE 0x0 -#define NV4_PGRAPH_STATUS_CACHE_BUSY 0x1 -#define NV4_PGRAPH_STATUS_LIGHTING 26 -#define NV4_PGRAPH_STATUS_LIGHTING_IDLE 0x0 -#define NV4_PGRAPH_STATUS_LIGHTING_BUSY 0x1 -#define NV4_PGRAPH_STATUS_PREROP 27 -#define NV4_PGRAPH_STATUS_PREROP_IDLE 0x0 -#define NV4_PGRAPH_STATUS_PREROP_BUSY 0x1 -#define NV4_PGRAPH_STATUS_ROP 28 -#define NV4_PGRAPH_STATUS_ROP_IDLE 0x0 -#define NV4_PGRAPH_STATUS_ROP_BUSY 0x1 -#define NV4_PGRAPH_STATUS_PORT_USER 29 -#define NV4_PGRAPH_STATUS_PORT_USER_IDLE 0x0 -#define NV4_PGRAPH_STATUS_PORT_USER_BUSY 0x1 -#define NV4_PGRAPH_TRAPPED_ADDR 0x400704 -#define NV4_PGRAPH_TRAPPED_ADDR_MTHD 2 -#define NV4_PGRAPH_TRAPPED_ADDR_SUBCH 13 -#define NV4_PGRAPH_TRAPPED_ADDR_CHID 24 -#define NV4_PGRAPH_TRAPPED_DATA 0x400708 -#define NV4_PGRAPH_TRAPPED_DATA_VALUE 0 -#define NV4_PGRAPH_SURFACE 0x40070C -#define NV4_PGRAPH_SURFACE_TYPE 0 -#define NV4_PGRAPH_SURFACE_TYPE_INVALID 0x0 -#define NV4_PGRAPH_SURFACE_TYPE_NON_SWIZZLE 0x1 -#define NV4_PGRAPH_SURFACE_TYPE_SWIZZLE 0x2 -#define NV4_PGRAPH_NOTIFY 0x400714 -#define NV4_PGRAPH_NOTIFY_BUFFER_REQ 0 -#define NV4_PGRAPH_NOTIFY_BUFFER_REQ_NOT_PENDING 0x0 -#define NV4_PGRAPH_NOTIFY_BUFFER_REQ_PENDING 0x1 -#define NV4_PGRAPH_NOTIFY_BUFFER_STYLE 8 -#define NV4_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_ONLY 0x0 -#define NV4_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_THEN_AWAKEN 0x1 -#define NV4_PGRAPH_NOTIFY_REQ 16 -#define NV4_PGRAPH_NOTIFY_REQ_NOT_PENDING 0x0 -#define NV4_PGRAPH_NOTIFY_REQ_PENDING 0x1 -#define NV4_PGRAPH_NOTIFY_STYLE 20 -#define NV4_PGRAPH_NOTIFY_STYLE_WRITE_ONLY 0x0 -#define NV4_PGRAPH_NOTIFY_STYLE_WRITE_THEN_AWAKEN 0x1 -#define NV4_PGRAPH_BOFFSET(i) (0x400640+(i)*4) -//used for all -#define NV4_PGRAPH_BOFFSET_LINADRS_DEFAULT 0x0 -#define NV4_PGRAPH_BOFFSET_SIZE_1 6 -#define NV4_PGRAPH_BOFFSET_LINADRS 0 -#define NV4_PGRAPH_BOFFSET_LINADRS_0 0x0 -#define NV4_PGRAPH_BOFFSET0 0x400640 -#define NV4_PGRAPH_BOFFSET0_ALIAS_1 NV_PGRAPH_BOFFSET(0) -#define NV4_PGRAPH_BOFFSET0_LINADRS 0 -#define NV4_PGRAPH_BOFFSET1 0x400644 -#define NV4_PGRAPH_BOFFSET1_ALIAS_1 NV_PGRAPH_BOFFSET(1) -#define NV4_PGRAPH_BOFFSET1_LINADRS 0 -#define NV4_PGRAPH_BOFFSET2 0x400648 -#define NV4_PGRAPH_BOFFSET2_ALIAS_1 NV_PGRAPH_BOFFSET(2) -#define NV4_PGRAPH_BOFFSET2_LINADRS 0 -#define NV4_PGRAPH_BOFFSET3 0x40064C -#define NV4_PGRAPH_BOFFSET3_ALIAS_1 NV_PGRAPH_BOFFSET(3) -#define NV4_PGRAPH_BOFFSET3_LINADRS 0 -#define NV4_PGRAPH_BOFFSET4 0x400650 -#define NV4_PGRAPH_BOFFSET4_ALIAS_1 NV_PGRAPH_BOFFSET(4) -#define NV4_PGRAPH_BOFFSET4_LINADRS 0 -#define NV4_PGRAPH_BOFFSET5 0x400654 -#define NV4_PGRAPH_BOFFSET5_ALIAS_1 NV_PGRAPH_BOFFSET(5) -#define NV4_PGRAPH_BOFFSET5_LINADRS 0 -#define NV4_PGRAPH_BBASE(i) (0x400658+(i)*4) -//used for all -#define NV4_PGRAPH_BBASE_LINADRS_DEFAULT 0x0 -#define NV4_PGRAPH_BBASE_SIZE_1 6 -#define NV4_PGRAPH_BBASE_LINADRS 0 -#define NV4_PGRAPH_BBASE0 0x400658 -#define NV4_PGRAPH_BBASE0_ALIAS_1 NV_PGRAPH_BBASE(0) -#define NV4_PGRAPH_BBASE0_LINADRS 0 -#define NV4_PGRAPH_BBASE1 0x40065c -#define NV4_PGRAPH_BBASE1_ALIAS_1 NV_PGRAPH_BBASE(1) -#define NV4_PGRAPH_BBASE1_LINADRS 0 -#define NV4_PGRAPH_BBASE2 0x400660 -#define NV4_PGRAPH_BBASE2_ALIAS_1 NV_PGRAPH_BBASE(2) -#define NV4_PGRAPH_BBASE2_LINADRS 0 -#define NV4_PGRAPH_BBASE3 0x400664 -#define NV4_PGRAPH_BBASE3_ALIAS_1 NV_PGRAPH_BBASE(3) -#define NV4_PGRAPH_BBASE3_LINADRS 0 -#define NV4_PGRAPH_BBASE4 0x400668 -#define NV4_PGRAPH_BBASE4_ALIAS_1 NV_PGRAPH_BBASE(4) -#define NV4_PGRAPH_BBASE4_LINADRS 0 -#define NV4_PGRAPH_BBASE5 0x40066C -#define NV4_PGRAPH_BBASE5_ALIAS_1 NV_PGRAPH_BBASE(5) -#define NV4_PGRAPH_BBASE5_LINADRS 0 -#define NV4_PGRAPH_BPITCH(i) (0x400670+(i)*4) -//used for all -#define NV4_PGRAPH_BPITCH_LINADRS_DEFAULT 0x0 -#define NV4_PGRAPH_BPITCH_SIZE_1 5 -#define NV4_PGRAPH_BPITCH_VALUE 0 // use bit 0 for all -#define NV4_PGRAPH_BPITCH_VALUE_0 0x0 -#define NV4_PGRAPH_BPITCH0 0x400670 -#define NV4_PGRAPH_BPITCH0_ALIAS_1 NV_PGRAPH_BPITCH(0) -#define NV4_PGRAPH_BPITCH1 0x400674 -#define NV4_PGRAPH_BPITCH1_ALIAS_1 NV_PGRAPH_BPITCH(1) -#define NV4_PGRAPH_BPITCH2 0x400678 -#define NV4_PGRAPH_BPITCH2_ALIAS_1 NV_PGRAPH_BPITCH(2) -#define NV4_PGRAPH_BPITCH3 0x40067C -#define NV4_PGRAPH_BPITCH3_ALIAS_1 NV_PGRAPH_BPITCH(3) -#define NV4_PGRAPH_BPITCH4 0x400680 -#define NV4_PGRAPH_BPITCH4_ALIAS_1 NV_PGRAPH_BPITCH(4) -#define NV4_PGRAPH_BLIMIT(i) (0x400684+(i)*4) -//following two used for all -#define NV4_PGRAPH_BLIMIT_SIZE_1 6 -#define NV4_PGRAPH_BLIMIT_VALUE 0 -#define NV4_PGRAPH_BLIMIT_TYPE 31 -#define NV4_PGRAPH_BLIMIT_TYPE_IN_MEMORY 0x0 -#define NV4_PGRAPH_BLIMIT_TYPE_NULL 0x1 -#define NV4_PGRAPH_BLIMIT0 0x400684 -#define NV4_PGRAPH_BLIMIT0_ALIAS_1 NV_PGRAPH_BLIMIT(0) -#define NV4_PGRAPH_BLIMIT1 0x400688 -#define NV4_PGRAPH_BLIMIT1_ALIAS_1 NV_PGRAPH_BLIMIT(1) -#define NV4_PGRAPH_BLIMIT2 0x40068c -#define NV4_PGRAPH_BLIMIT2_ALIAS_1 NV_PGRAPH_BLIMIT(2) -#define NV4_PGRAPH_BLIMIT3 0x400690 -#define NV4_PGRAPH_BLIMIT3_ALIAS_1 NV_PGRAPH_BLIMIT(3) -#define NV4_PGRAPH_BLIMIT4 0x400694 -#define NV4_PGRAPH_BLIMIT4_ALIAS_1 NV_PGRAPH_BLIMIT(4) -#define NV4_PGRAPH_BLIMIT5 0x400698 -#define NV4_PGRAPH_BLIMIT5_ALIAS_1 NV_PGRAPH_BLIMIT(5) -#define NV4_PGRAPH_BSWIZZLE2 0x40069c -#define NV4_PGRAPH_BSWIZZLE2_WIDTH 16 -#define NV4_PGRAPH_BSWIZZLE2_WIDTH_0 0x0 -#define NV4_PGRAPH_BSWIZZLE2_HEIGHT 24 -#define NV4_PGRAPH_BSWIZZLE2_HEIGHT_0 0x0 -#define NV4_PGRAPH_BSWIZZLE5 0x4006a0 -#define NV4_PGRAPH_BSWIZZLE5_WIDTH 16 -#define NV4_PGRAPH_BSWIZZLE5_WIDTH_0 0x0 -#define NV4_PGRAPH_BSWIZZLE5_HEIGHT 24 -#define NV4_PGRAPH_BSWIZZLE5_HEIGHT_0 0x0 -#define NV4_PGRAPH_BPIXEL 0x400724 -#define NV4_PGRAPH_BPIXEL_DEPTH0 0 -#define NV4_PGRAPH_BPIXEL_DEPTH1 4 -#define NV4_PGRAPH_BPIXEL_DEPTH2 8 -#define NV4_PGRAPH_BPIXEL_DEPTH3 12 -#define NV4_PGRAPH_BPIXEL_DEPTH4 16 -#define NV4_PGRAPH_BPIXEL_DEPTH5 20 - -// valid for depth0-depth5 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_INVALID 0x0 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_Y8 0x1 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_X1R5G5B5_Z1R5G5B5 0x2 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_X1R5G5B5_O1R5G5B5 0x3 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_A1R5G5B5 0x4 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_R5G6B5 0x5 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_Y16 0x6 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_X8R8G8B8_Z8R8G8B8 0x7 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_X8R8G8B8_O1Z7R8G8B8 0x8 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_X1A7R8G8B8_Z1A7R8G8B8 0x9 -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_X1A7R8G8B8_O1A7R8G8B8 0xA -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_X8R8G8B8_O8R8G8B8 0xB -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_A8R8G8B8 0xC -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_Y32 0xD -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_V8YB8U8YA8 0xE -#define NV4_PGRAPH_BPIXEL_DEPTH_FORMAT_YB8V8YA8U8 0xF - -#define NV4_PGRAPH_LIMIT_VIOL_PIX 0x400610 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_ADRS 0 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_ADRS_0 0x0 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_BLIT 29 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_BLIT_NO_VIOL 0x0 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_BLIT_VIOL 0x1 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_LIMIT 30 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_LIMIT_NO_VIOL 0x0 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_LIMIT_VIOL 0x1 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_OVRFLW 31 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_NO_VIOL 0x0 -#define NV4_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_VIOL 0x1 -#define NV4_PGRAPH_LIMIT_VIOL_Z 0x400614 -#define NV4_PGRAPH_LIMIT_VIOL_Z_ADRS 0 -#define NV4_PGRAPH_LIMIT_VIOL_Z_ADRS_0 0x0 -#define NV4_PGRAPH_LIMIT_VIOL_Z_LIMIT 30 -#define NV4_PGRAPH_LIMIT_VIOL_Z_LIMIT_NO_VIOL 0x0 -#define NV4_PGRAPH_LIMIT_VIOL_Z_LIMIT_VIOL 0x1 -#define NV4_PGRAPH_LIMIT_VIOL_Z_OVRFLW 31 -#define NV4_PGRAPH_LIMIT_VIOL_Z_OVRFLW_NO_VIOL 0x0 -#define NV4_PGRAPH_LIMIT_VIOL_Z_OVRFLW_VIOL 0x1 -#define NV4_PGRAPH_STATE 0x400710 -#define NV4_PGRAPH_STATE_BUFFER_0 0 -#define NV4_PGRAPH_STATE_BUFFER_0_INVALID 0x0 -#define NV4_PGRAPH_STATE_BUFFER_0_VALID 0x1 -#define NV4_PGRAPH_STATE_BUFFER_1 1 -#define NV4_PGRAPH_STATE_BUFFER_1_INVALID 0x0 -#define NV4_PGRAPH_STATE_BUFFER_1_VALID 0x1 -#define NV4_PGRAPH_STATE_BUFFER_2 2 -#define NV4_PGRAPH_STATE_BUFFER_2_INVALID 0x0 -#define NV4_PGRAPH_STATE_BUFFER_2_VALID 0x1 -#define NV4_PGRAPH_STATE_BUFFER_3 3 -#define NV4_PGRAPH_STATE_BUFFER_3_INVALID 0x0 -#define NV4_PGRAPH_STATE_BUFFER_3_VALID 0x1 -#define NV4_PGRAPH_STATE_BUFFER_4 4 -#define NV4_PGRAPH_STATE_BUFFER_4_INVALID 0x0 -#define NV4_PGRAPH_STATE_BUFFER_4_VALID 0x1 -#define NV4_PGRAPH_STATE_BUFFER_5 5 -#define NV4_PGRAPH_STATE_BUFFER_5_INVALID 0x0 -#define NV4_PGRAPH_STATE_BUFFER_5_VALID 0x1 -#define NV4_PGRAPH_STATE_PITCH_0 8 -#define NV4_PGRAPH_STATE_PITCH_0_INVALID 0x0 -#define NV4_PGRAPH_STATE_PITCH_0_VALID 0x1 -#define NV4_PGRAPH_STATE_PITCH_1 9 -#define NV4_PGRAPH_STATE_PITCH_1_INVALID 0x0 -#define NV4_PGRAPH_STATE_PITCH_1_VALID 0x1 -#define NV4_PGRAPH_STATE_PITCH_2 10 -#define NV4_PGRAPH_STATE_PITCH_2_INVALID 0x0 -#define NV4_PGRAPH_STATE_PITCH_2_VALID 0x1 -#define NV4_PGRAPH_STATE_PITCH_3 11 -#define NV4_PGRAPH_STATE_PITCH_3_INVALID 0x0 -#define NV4_PGRAPH_STATE_PITCH_3_VALID 0x1 -#define NV4_PGRAPH_STATE_PITCH_4 12 -#define NV4_PGRAPH_STATE_PITCH_4_INVALID 0x0 -#define NV4_PGRAPH_STATE_PITCH_4_VALID 0x1 -#define NV4_PGRAPH_STATE_CHROMA_COLOR 16 -#define NV4_PGRAPH_STATE_CHROMA_COLOR_INVALID 0x0 -#define NV4_PGRAPH_STATE_CHROMA_COLOR_VALID 0x1 -#define NV4_PGRAPH_STATE_CHROMA_COLORFMT 17 -#define NV4_PGRAPH_STATE_CHROMA_COLORFMT_INVALID 0x0 -#define NV4_PGRAPH_STATE_CHROMA_COLORFMT_VALID 0x1 -#define NV4_PGRAPH_STATE_CPATTERN_COLORFMT 20 -#define NV4_PGRAPH_STATE_CPATTERN_COLORFMT_INVALID 0x0 -#define NV4_PGRAPH_STATE_CPATTERN_COLORFMT_VALID 0x1 -#define NV4_PGRAPH_STATE_CPATTERN_MONOFMT 21 -#define NV4_PGRAPH_STATE_CPATTERN_MONOFMT_INVALID 0x0 -#define NV4_PGRAPH_STATE_CPATTERN_MONOFMT_VALID 0x1 -#define NV4_PGRAPH_STATE_CPATTERN_SELECT 22 -#define NV4_PGRAPH_STATE_CPATTERN_SELECT_INVALID 0x0 -#define NV4_PGRAPH_STATE_CPATTERN_SELECT_VALID 0x1 -#define NV4_PGRAPH_STATE_PATTERN_COLOR0 24 -#define NV4_PGRAPH_STATE_PATTERN_COLOR0_INVALID 0x0 -#define NV4_PGRAPH_STATE_PATTERN_COLOR0_VALID 0x1 -#define NV4_PGRAPH_STATE_PATTERN_COLOR1 25 -#define NV4_PGRAPH_STATE_PATTERN_COLOR1_INVALID 0x0 -#define NV4_PGRAPH_STATE_PATTERN_COLOR1_VALID 0x1 -#define NV4_PGRAPH_STATE_PATTERN_PATT0 26 -#define NV4_PGRAPH_STATE_PATTERN_PATT0_INVALID 0x0 -#define NV4_PGRAPH_STATE_PATTERN_PATT0_VALID 0x1 -#define NV4_PGRAPH_STATE_PATTERN_PATT1 27 -#define NV4_PGRAPH_STATE_PATTERN_PATT1_INVALID 0x0 -#define NV4_PGRAPH_STATE_PATTERN_PATT1_VALID 0x1 -#define NV4_PGRAPH_CACHE_INDEX 0x400728 -#define NV4_PGRAPH_CACHE_INDEX_BANK 2 -#define NV4_PGRAPH_CACHE_INDEX_BANK_10 0x0 -#define NV4_PGRAPH_CACHE_INDEX_BANK_32 0x1 -#define NV4_PGRAPH_CACHE_INDEX_ADRS 3 -#define NV4_PGRAPH_CACHE_INDEX_ADRS_0 0x0 -#define NV4_PGRAPH_CACHE_INDEX_ADRS_1024 0x400 -#define NV4_PGRAPH_CACHE_INDEX_OP 13 -#define NV4_PGRAPH_CACHE_INDEX_OP_WR_CACHE 0x0 -#define NV4_PGRAPH_CACHE_INDEX_OP_RD_CACHE 0x1 -#define NV4_PGRAPH_CACHE_INDEX_OP_RD_INDEX 0x2 -#define NV4_PGRAPH_CACHE_RAM 0x40072c -#define NV4_PGRAPH_CACHE_RAM_VALUE 0 -#define NV4_PGRAPH_DMA_PITCH 0x400760 -#define NV4_PGRAPH_DMA_PITCH_S0 0 -#define NV4_PGRAPH_DMA_PITCH_S1 16 -#define NV4_PGRAPH_DVD_COLORFMT 0x400764 -#define NV4_PGRAPH_DVD_COLORFMT_IMAGE 0 -#define NV4_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_INVALID 0x00 -#define NV4_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_V8YB8U8YA8 0x12 -#define NV4_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_YB8V8YA8U8 0x13 -#define NV4_PGRAPH_DVD_COLORFMT_OVLY 8 -#define NV4_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_INVALID 0x00 -#define NV4_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A8Y8U8V8 0x01 -#define NV4_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A4V6YB6A4U6YA6 0x02 -#define NV4_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_TRANSPARENT 0x03 -#define NV4_PGRAPH_SCALED_FORMAT 0x400768 -#define NV4_PGRAPH_SCALED_FORMAT_ORIGIN 16 -#define NV4_PGRAPH_SCALED_FORMAT_ORIGIN_INVALID 0x0 -#define NV4_PGRAPH_SCALED_FORMAT_ORIGIN_CENTER 0x1 -#define NV4_PGRAPH_SCALED_FORMAT_ORIGIN_CORNER 0x2 -#define NV4_PGRAPH_SCALED_FORMAT_INTERPOLATOR 24 -#define NV4_PGRAPH_SCALED_FORMAT_INTERPOLATOR_ZOH 0x0 -#define NV4_PGRAPH_SCALED_FORMAT_INTERPOLATOR_FOH 0x1 -#define NV4_PGRAPH_PATT_COLOR0 0x400800 -#define NV4_PGRAPH_PATT_COLOR0_VALUE 0 -#define NV4_PGRAPH_PATT_COLOR1 0x400804 -#define NV4_PGRAPH_PATT_COLOR1_VALUE 0 -#define NV4_PGRAPH_PATT_COLORRAM(i) (0x400900+(i)*4) -#define NV4_PGRAPH_PATT_COLORRAM_SIZE_1 64 -#define NV4_PGRAPH_PATT_COLORRAM_VALUE 0 -#define NV4_PGRAPH_PATTERN(i) (0x400808+(i)*4) -#define NV4_PGRAPH_PATTERN_SIZE_1 2 -#define NV4_PGRAPH_PATTERN_BITMAP 0 -#define NV4_PGRAPH_PATTERN_SHAPE 0x400810 -#define NV4_PGRAPH_PATTERN_SHAPE_VALUE 0 -#define NV4_PGRAPH_PATTERN_SHAPE_VALUE_8X_8Y 0x0 -#define NV4_PGRAPH_PATTERN_SHAPE_VALUE_64X_1Y 0x1 -#define NV4_PGRAPH_PATTERN_SHAPE_VALUE_1X_64Y 0x2 -#define NV4_PGRAPH_PATTERN_SHAPE_SELECT 4 -#define NV4_PGRAPH_PATTERN_SHAPE_SELECT_2COLOR 0x0 -#define NV4_PGRAPH_PATTERN_SHAPE_SELECT_FULLCOLOR 0x1 -#define NV4_PGRAPH_MONO_COLOR0 0x400600 -#define NV4_PGRAPH_MONO_COLOR0_VALUE 0 -#define NV4_PGRAPH_ROP3 0x400604 -#define NV4_PGRAPH_ROP3_VALUE 0 -#define NV4_PGRAPH_CHROMA 0x400814 -#define NV4_PGRAPH_CHROMA_VALUE 0 -#define NV4_PGRAPH_BETA_AND 0x400608 -#define NV4_PGRAPH_BETA_AND_VALUE_FRACTION 23 -#define NV4_PGRAPH_BETA_PREMULT 0x40060c -#define NV4_PGRAPH_BETA_PREMULT_VALUE 0 -#define NV4_PGRAPH_CONTROL0 0x400818 -#define NV4_PGRAPH_CONTROL0_ALPHAREF 0 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC 8 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_NEVER 0x1 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_LESS 0x2 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_EQUAL 0x3 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_LESSEQUAL 0x4 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_GREATER 0x5 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_NOTEQUAL 0x6 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_GREATEREQUAL 0x7 -#define NV4_PGRAPH_CONTROL0_ALPHAFUNC_ALWAYS 0x8 -#define NV4_PGRAPH_CONTROL0_ALPHATESTENABLE 12 -#define NV4_PGRAPH_CONTROL0_ALPHATESTENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_ZENABLE 14 -#define NV4_PGRAPH_CONTROL0_ZENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_ZENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_ZFUNC 16 -#define NV4_PGRAPH_CONTROL0_ZFUNC_NEVER 0x1 -#define NV4_PGRAPH_CONTROL0_ZFUNC_LESS 0x2 -#define NV4_PGRAPH_CONTROL0_ZFUNC_EQUAL 0x3 -#define NV4_PGRAPH_CONTROL0_ZFUNC_LESSEQUAL 0x4 -#define NV4_PGRAPH_CONTROL0_ZFUNC_GREATER 0x5 -#define NV4_PGRAPH_CONTROL0_ZFUNC_NOTEQUAL 0x6 -#define NV4_PGRAPH_CONTROL0_ZFUNC_GREATEREQUAL 0x7 -#define NV4_PGRAPH_CONTROL0_ZFUNC_ALWAYS 0x8 -#define NV4_PGRAPH_CONTROL0_CULLMODE 20 -#define NV4_PGRAPH_CONTROL0_CULLMODE_NONE 0x1 -#define NV4_PGRAPH_CONTROL0_CULLMODE_CW 0x2 -#define NV4_PGRAPH_CONTROL0_CULLMODE_CCW 0x3 -#define NV4_PGRAPH_CONTROL0_DITHERENABLE 22 -#define NV4_PGRAPH_CONTROL0_DITHERENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_DITHERENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_Z_PERSPECTIVE_ENABLE 23 -#define NV4_PGRAPH_CONTROL0_Z_PERSPECTIVE_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_Z_PERSPECTIVE_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_ZWRITEENABLE 24 -#define NV4_PGRAPH_CONTROL0_ZWRITEENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_ZWRITEENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_STENCIL_WRITE_ENABLE 25 -#define NV4_PGRAPH_CONTROL0_STENCIL_WRITE_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_STENCIL_WRITE_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_ALPHA_WRITE_ENABLE 26 -#define NV4_PGRAPH_CONTROL0_ALPHA_WRITE_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_ALPHA_WRITE_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_RED_WRITE_ENABLE 27 -#define NV4_PGRAPH_CONTROL0_RED_WRITE_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_RED_WRITE_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_GREEN_WRITE_ENABLE 28 -#define NV4_PGRAPH_CONTROL0_GREEN_WRITE_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_GREEN_WRITE_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_BLUE_WRITE_ENABLE 29 -#define NV4_PGRAPH_CONTROL0_BLUE_WRITE_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL0_BLUE_WRITE_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL0_Z_FORMAT 30 -#define NV4_PGRAPH_CONTROL0_Z_FORMAT_FIXED 0x1 -#define NV4_PGRAPH_CONTROL0_Z_FORMAT_FLOAT 0x2 -#define NV4_PGRAPH_CONTROL1 0x40081c -#define NV4_PGRAPH_CONTROL1_STENCIL_TEST_ENABLE 0 -#define NV4_PGRAPH_CONTROL1_STENCIL_TEST_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_CONTROL1_STENCIL_TEST_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC 4 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_NEVER 0x1 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_LESS 0x2 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_EQUAL 0x3 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_LESSEQUAL 0x4 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_GREATER 0x5 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_NOTEQUAL 0x6 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_GREATEREQUAL 0x7 -#define NV4_PGRAPH_CONTROL1_STENCIL_FUNC_ALWAYS 0x8 -#define NV4_PGRAPH_CONTROL1_STENCIL_REF 8 -#define NV4_PGRAPH_CONTROL1_STENCIL_MASK_READ 16 -#define NV4_PGRAPH_CONTROL1_STENCIL_MASK_WRITE 24 -#define NV4_PGRAPH_CONTROL2 0x400820 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL 0 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_KEEP 0x1 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_ZERO 0x2 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_REPLACE 0x3 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_INCRSAT 0x4 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_DECRSAT 0x5 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_INVERT 0x6 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_INCR 0x7 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_FAIL_DECR 0x8 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL 4 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_KEEP 0x1 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_ZERO 0x2 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_REPLACE 0x3 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_INCRSAT 0x4 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_DECRSAT 0x5 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_INVERT 0x6 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_INCR 0x7 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZFAIL_DECR 0x8 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS 8 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_KEEP 0x1 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_ZERO 0x2 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_REPLACE 0x3 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_INCRSAT 0x4 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_DECRSAT 0x5 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_INVERT 0x6 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_INCR 0x7 -#define NV4_PGRAPH_CONTROL2_STENCIL_OP_ZPASS_DECR 0x8 -#define NV4_PGRAPH_BLEND 0x400824 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND 0 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_DECAL 0x1 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_MODULATE 0x2 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_DECALALPHA 0x3 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_MODULATEALPHA 0x4 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_DECALMASK 0x5 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_MODULATEMASK 0x6 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_COPY 0x7 -#define NV4_PGRAPH_BLEND_TEXTUREMAPBLEND_ADD 0x8 -#define NV4_PGRAPH_BLEND_MASK_BIT 4 -#define NV4_PGRAPH_BLEND_MASK_BIT_LSB 0x1 -#define NV4_PGRAPH_BLEND_MASK_BIT_MSB 0x2 -#define NV4_PGRAPH_BLEND_SHADEMODE 6 -#define NV4_PGRAPH_BLEND_SHADEMODE_FLAT 0x1 -#define NV4_PGRAPH_BLEND_SHADEMODE_GOURAUD 0x2 -#define NV4_PGRAPH_BLEND_SHADEMODE_PHONG 0x3 -#define NV4_PGRAPH_BLEND_TEXTUREPERSPECTIVE 8 -#define NV4_PGRAPH_BLEND_TEXTUREPERSPECTIVE_TRUE 0x1 -#define NV4_PGRAPH_BLEND_SPECULARENABLE 12 -#define NV4_PGRAPH_BLEND_SPECULARENABLE_TRUE 0x1 -#define NV4_PGRAPH_BLEND_FOGENABLE 16 -#define NV4_PGRAPH_BLEND_FOGENABLE_TRUE 0x1 -#define NV4_PGRAPH_BLEND_ALPHABLENDENABLE 20 -#define NV4_PGRAPH_BLEND_ALPHABLENDENABLE_TRUE 0x1 -#define NV4_PGRAPH_BLEND_SRCBLEND 24 -#define NV4_PGRAPH_BLEND_SRCBLEND_ZERO 0x1 -#define NV4_PGRAPH_BLEND_SRCBLEND_ONE 0x2 -#define NV4_PGRAPH_BLEND_SRCBLEND_SRCCOLOR 0x3 -#define NV4_PGRAPH_BLEND_SRCBLEND_INVSRCCOLOR 0x4 -#define NV4_PGRAPH_BLEND_SRCBLEND_SRCALPHA 0x5 -#define NV4_PGRAPH_BLEND_SRCBLEND_INVSRCALPHA 0x6 -#define NV4_PGRAPH_BLEND_SRCBLEND_DESTALPHA 0x7 -#define NV4_PGRAPH_BLEND_SRCBLEND_INVDESTALPHA 0x8 -#define NV4_PGRAPH_BLEND_SRCBLEND_DESTCOLOR 0x9 -#define NV4_PGRAPH_BLEND_SRCBLEND_INVDESTCOLOR 0xA -#define NV4_PGRAPH_BLEND_SRCBLEND_SRCALPHASAT 0xB -#define NV4_PGRAPH_BLEND_SRCBLEND_INVSRCALPHASAT 0xC -#define NV4_PGRAPH_BLEND_SRCBLEND_BETA 0xD -#define NV4_PGRAPH_BLEND_DESTBLEND 28 -#define NV4_PGRAPH_BLEND_DESTBLEND_ZERO 0x1 -#define NV4_PGRAPH_BLEND_DESTBLEND_ONE 0x2 -#define NV4_PGRAPH_BLEND_DESTBLEND_SRCCOLOR 0x3 -#define NV4_PGRAPH_BLEND_DESTBLEND_INVSRCCOLOR 0x4 -#define NV4_PGRAPH_BLEND_DESTBLEND_SRCALPHA 0x5 -#define NV4_PGRAPH_BLEND_DESTBLEND_INVSRCALPHA 0x6 -#define NV4_PGRAPH_BLEND_DESTBLEND_DESTALPHA 0x7 -#define NV4_PGRAPH_BLEND_DESTBLEND_INVDESTALPHA 0x8 -#define NV4_PGRAPH_BLEND_DESTBLEND_DESTCOLOR 0x9 -#define NV4_PGRAPH_BLEND_DESTBLEND_INVDESTCOLOR 0xA -#define NV4_PGRAPH_BLEND_DESTBLEND_SRCALPHASAT 0xB -#define NV4_PGRAPH_DPRAM_INDEX 0x400828 -#define NV4_PGRAPH_DPRAM_INDEX_ADRS 0 -#define NV4_PGRAPH_DPRAM_INDEX_ADRS_0 0x0 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT 8 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_ADRS_0 0x0 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_ADRS_1 0x1 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_DATA_0 0x2 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_DATA_1 0x3 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_WE_0 0x4 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_WE_1 0x5 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_0 0x6 -#define NV4_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_1 0x7 -#define NV4_PGRAPH_DPRAM_DATA 0x40082c -#define NV4_PGRAPH_DPRAM_DATA_VALUE 0 -#define NV4_PGRAPH_DPRAM_ADRS_0 0x40082c -#define NV4_PGRAPH_DPRAM_ADRS_0_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_ADRS_0_VALUE 0 -#define NV4_PGRAPH_DPRAM_ADRS_1 0x40082c -#define NV4_PGRAPH_DPRAM_ADRS_1_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_ADRS_1_VALUE 0 -#define NV4_PGRAPH_DPRAM_DATA_0 0x40082c -#define NV4_PGRAPH_DPRAM_DATA_0_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_DATA_0_VALUE 0 -#define NV4_PGRAPH_DPRAM_DATA_1 0x40082c -#define NV4_PGRAPH_DPRAM_DATA_1_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_DATA_1_VALUE 0 -#define NV4_PGRAPH_DPRAM_WE_0 0x40082c -#define NV4_PGRAPH_DPRAM_WE_0_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_WE_0_VALUE 0 -#define NV4_PGRAPH_DPRAM_WE_1 0x40082c -#define NV4_PGRAPH_DPRAM_WE_1_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_WE_1_VALUE 0 -#define NV4_PGRAPH_DPRAM_ALPHA_0 0x40082c -#define NV4_PGRAPH_DPRAM_ALPHA_0_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_ALPHA_0_VALUE 0 -#define NV4_PGRAPH_DPRAM_ALPHA_1 0x40082c -#define NV4_PGRAPH_DPRAM_ALPHA_1_ALIAS_1 NV_PGRAPH_DPRAM_DATA -#define NV4_PGRAPH_DPRAM_ALPHA_1_VALUE 0 -#define NV4_PGRAPH_STORED_FMT 0x400830 -#define NV4_PGRAPH_STORED_FMT_MONO0 0 -#define NV4_PGRAPH_STORED_FMT_PATT0 8 -#define NV4_PGRAPH_STORED_FMT_PATT1 16 -#define NV4_PGRAPH_STORED_FMT_CHROMA 24 -#define NV4_PGRAPH_FORMATS 0x400618 -#define NV4_PGRAPH_FORMATS_ROP 0 -#define NV4_PGRAPH_FORMATS_ROP_Y8 0x0 -#define NV4_PGRAPH_FORMATS_ROP_RGB15 0x1 -#define NV4_PGRAPH_FORMATS_ROP_RGB16 0x2 -#define NV4_PGRAPH_FORMATS_ROP_Y16 0x3 -#define NV4_PGRAPH_FORMATS_ROP_INVALID 0x4 -#define NV4_PGRAPH_FORMATS_ROP_RGB24 0x5 -#define NV4_PGRAPH_FORMATS_ROP_RGB30 0x6 -#define NV4_PGRAPH_FORMATS_ROP_Y32 0x7 -#define NV4_PGRAPH_FORMATS_SRC 4 -#define NV4_PGRAPH_FORMATS_SRC_INVALID 0x0 -#define NV4_PGRAPH_FORMATS_SRC_LE_Y8 0x1 -#define NV4_PGRAPH_FORMATS_SRC_LE_X16A8Y8 0x2 -#define NV4_PGRAPH_FORMATS_SRC_LE_X24Y8 0x3 -#define NV4_PGRAPH_FORMATS_SRC_LE_A1R5G5B5 0x6 -#define NV4_PGRAPH_FORMATS_SRC_LE_X1R5G5B5 0x7 -#define NV4_PGRAPH_FORMATS_SRC_LE_X16A1R5G5B5 0x8 -#define NV4_PGRAPH_FORMATS_SRC_LE_X17R5G5B5 0x9 -#define NV4_PGRAPH_FORMATS_SRC_LE_R5G6B5 0xA -#define NV4_PGRAPH_FORMATS_SRC_LE_A16R5G6B5 0xB -#define NV4_PGRAPH_FORMATS_SRC_LE_X16R5G6B5 0xC -#define NV4_PGRAPH_FORMATS_SRC_LE_A8R8G8B8 0xD -#define NV4_PGRAPH_FORMATS_SRC_LE_X8R8G8B8 0xE -#define NV4_PGRAPH_FORMATS_SRC_LE_Y16 0xF -#define NV4_PGRAPH_FORMATS_SRC_LE_A16Y16 0x10 -#define NV4_PGRAPH_FORMATS_SRC_LE_X16Y16 0x11 -#define NV4_PGRAPH_FORMATS_SRC_LE_V8YB8U8YA8 0x12 -#define NV4_PGRAPH_FORMATS_SRC_LE_YB8V8YA8U8 0x13 -#define NV4_PGRAPH_FORMATS_SRC_LE_Y32 0x14 -#define NV4_PGRAPH_FORMATS_FB 12 -#define NV4_PGRAPH_FORMATS_FB_INVALID 0x0 -#define NV4_PGRAPH_FORMATS_FB_Y8 0x1 -#define NV4_PGRAPH_FORMATS_FB_X1R5G5B5_Z1R5G5B5 0x2 -#define NV4_PGRAPH_FORMATS_FB_X1R5G5B5_O1R5G5B5 0x3 -#define NV4_PGRAPH_FORMATS_FB_A1R5G5B5 0x4 -#define NV4_PGRAPH_FORMATS_FB_R5G6B5 0x5 -#define NV4_PGRAPH_FORMATS_FB_Y16 0x6 -#define NV4_PGRAPH_FORMATS_FB_X8R8G8B8_Z8R8G8B8 0x7 -#define NV4_PGRAPH_FORMATS_FB_X8R8G8B8_O1Z7R8G8B8 0x8 -#define NV4_PGRAPH_FORMATS_FB_X1A7R8G8B8_Z1A7R8G8B8 0x9 -#define NV4_PGRAPH_FORMATS_FB_X1A7R8G8B8_O1A7R8G8B8 0xA -#define NV4_PGRAPH_FORMATS_FB_X8R8G8B8_O8R8G8B8 0xB -#define NV4_PGRAPH_FORMATS_FB_A8R8G8B8 0xC -#define NV4_PGRAPH_FORMATS_FB_Y32 0xD -#define NV4_PGRAPH_FORMATS_FB_V8YB8U8YA8 0xE -#define NV4_PGRAPH_FORMATS_FB_YB8V8YA8U8 0xF -#define NV4_PGRAPH_ABS_X_RAM(i) (0x400400+(i)*4) -#define NV4_PGRAPH_ABS_X_RAM_SIZE_1 32 -#define NV4_PGRAPH_ABS_X_RAM_VALUE 0 -#define NV4_PGRAPH_X_RAM_BPORT(i) (0x400c00+(i)*4) -#define NV4_PGRAPH_X_RAM_BPORT_SIZE_1 32 -#define NV4_PGRAPH_X_RAM_BPORT_VALUE 0 -#define NV4_PGRAPH_ABS_Y_RAM(i) (0x400480+(i)*4) -#define NV4_PGRAPH_ABS_Y_RAM_SIZE_1 32 -#define NV4_PGRAPH_ABS_Y_RAM_VALUE 0 -#define NV4_PGRAPH_Y_RAM_BPORT(i) (0x400c80+(i)*4) -#define NV4_PGRAPH_Y_RAM_BPORT_SIZE_1 32 -#define NV4_PGRAPH_Y_RAM_BPORT_VALUE 0 -#define NV4_PGRAPH_XY_LOGIC_MISC0 0x400514 -#define NV4_PGRAPH_XY_LOGIC_MISC0_COUNTER 0 -#define NV4_PGRAPH_XY_LOGIC_MISC0_COUNTER_0 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC0_DIMENSION 20 -#define NV4_PGRAPH_XY_LOGIC_MISC0_DIMENSION_NONZERO 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC0_DIMENSION_ZERO 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC0_INDEX 28 -#define NV4_PGRAPH_XY_LOGIC_MISC0_INDEX_0 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC1 0x400518 -#define NV4_PGRAPH_XY_LOGIC_MISC1_INITIAL 0 -#define NV4_PGRAPH_XY_LOGIC_MISC1_INITIAL_NEEDED 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC1_INITIAL_DONE 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX 4 -#define NV4_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NOTNULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NULL 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY 5 -#define NV4_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NOTNULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NULL 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX 12 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_UUMAX 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_IMAGEMAX 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX 16 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_UUMAX 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_IMAGEMAX 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA 20 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_CLIPMAX 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_IMAGEMAX 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC2 0x40051C -#define NV4_PGRAPH_XY_LOGIC_MISC2_HANDOFF 0 -#define NV4_PGRAPH_XY_LOGIC_MISC2_HANDOFF_DISABLE 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC2_HANDOFF_ENABLE 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX 4 -#define NV4_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NOTNULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NULL 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY 5 -#define NV4_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NOTNULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NULL 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX 12 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_UCMAX 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_IMAGEMAX 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX 16 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_UCMAX 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_IMAGEMAX 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA 20 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_CLIPMAX 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_IMAGEMAX 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC3 0x400520 -#define NV4_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0 0 -#define NV4_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_NULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_TRUE 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY 4 -#define NV4_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_NULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_TRUE 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX 8 -#define NV4_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_NULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_TRUE 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG 12 -#define NV4_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_NULL 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_TRUE 0x1 -#define NV4_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX 16 -#define NV4_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX_0 0x0 -#define NV4_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX 24 -#define NV4_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX_0 0x0 -#define NV4_PGRAPH_X_MISC 0x400500 -#define NV4_PGRAPH_X_MISC_BIT33_0 0 -#define NV4_PGRAPH_X_MISC_BIT33_0_0 0x0 -#define NV4_PGRAPH_X_MISC_BIT33_1 1 -#define NV4_PGRAPH_X_MISC_BIT33_1_0 0x0 -#define NV4_PGRAPH_X_MISC_BIT33_2 2 -#define NV4_PGRAPH_X_MISC_BIT33_2_0 0x0 -#define NV4_PGRAPH_X_MISC_BIT33_3 3 -#define NV4_PGRAPH_X_MISC_BIT33_3_0 0x0 -#define NV4_PGRAPH_X_MISC_RANGE_0 4 -#define NV4_PGRAPH_X_MISC_RANGE_0_0 0x0 -#define NV4_PGRAPH_X_MISC_RANGE_1 5 -#define NV4_PGRAPH_X_MISC_RANGE_1_0 0x0 -#define NV4_PGRAPH_X_MISC_RANGE_2 6 -#define NV4_PGRAPH_X_MISC_RANGE_2_0 0x0 -#define NV4_PGRAPH_X_MISC_RANGE_3 7 -#define NV4_PGRAPH_X_MISC_RANGE_3_0 0x0 -#define NV4_PGRAPH_X_MISC_ADDER_OUTPUT 28 -#define NV4_PGRAPH_X_MISC_ADDER_OUTPUT_EQ_0 0x0 -#define NV4_PGRAPH_X_MISC_ADDER_OUTPUT_LT_0 0x1 -#define NV4_PGRAPH_X_MISC_ADDER_OUTPUT_GT_0 0x2 -#define NV4_PGRAPH_Y_MISC 0x400504 -#define NV4_PGRAPH_Y_MISC_BIT33_0 0 -#define NV4_PGRAPH_Y_MISC_BIT33_0_0 0x0 -#define NV4_PGRAPH_Y_MISC_BIT33_1 1 -#define NV4_PGRAPH_Y_MISC_BIT33_1_0 0x0 -#define NV4_PGRAPH_Y_MISC_BIT33_2 2 -#define NV4_PGRAPH_Y_MISC_BIT33_2_0 0x0 -#define NV4_PGRAPH_Y_MISC_BIT33_3 3 -#define NV4_PGRAPH_Y_MISC_BIT33_3_0 0x0 -#define NV4_PGRAPH_Y_MISC_RANGE_0 4 -#define NV4_PGRAPH_Y_MISC_RANGE_0_0 0x0 -#define NV4_PGRAPH_Y_MISC_RANGE_1 5 -#define NV4_PGRAPH_Y_MISC_RANGE_1_0 0x0 -#define NV4_PGRAPH_Y_MISC_RANGE_2 6 -#define NV4_PGRAPH_Y_MISC_RANGE_2_0 0x0 -#define NV4_PGRAPH_Y_MISC_RANGE_3 7 -#define NV4_PGRAPH_Y_MISC_RANGE_3_0 0x0 -#define NV4_PGRAPH_Y_MISC_ADDER_OUTPUT 28 -#define NV4_PGRAPH_Y_MISC_ADDER_OUTPUT_EQ_0 0x0 -#define NV4_PGRAPH_Y_MISC_ADDER_OUTPUT_LT_0 0x1 -#define NV4_PGRAPH_Y_MISC_ADDER_OUTPUT_GT_0 0x2 -#define NV4_PGRAPH_ABS_UCLIP_XMIN 0x40053C -#define NV4_PGRAPH_ABS_UCLIP_XMIN_VALUE 0 -#define NV4_PGRAPH_ABS_UCLIP_XMAX 0x400544 -#define NV4_PGRAPH_ABS_UCLIP_XMAX_VALUE 0 -#define NV4_PGRAPH_ABS_UCLIP_YMIN 0x400540 -#define NV4_PGRAPH_ABS_UCLIP_YMIN_VALUE 0 -#define NV4_PGRAPH_ABS_UCLIP_YMAX 0x400548 -#define NV4_PGRAPH_ABS_UCLIP_YMAX_VALUE 0 -#define NV4_PGRAPH_ABS_UCLIPA_XMIN 0x400560 -#define NV4_PGRAPH_ABS_UCLIPA_XMIN_VALUE 0 -#define NV4_PGRAPH_ABS_UCLIPA_XMAX 0x400568 -#define NV4_PGRAPH_ABS_UCLIPA_XMAX_VALUE 0 -#define NV4_PGRAPH_ABS_UCLIPA_YMIN 0x400564 -#define NV4_PGRAPH_ABS_UCLIPA_YMIN_VALUE 0 -#define NV4_PGRAPH_ABS_UCLIPA_YMAX 0x40056C -#define NV4_PGRAPH_ABS_UCLIPA_YMAX_VALUE 0 -#define NV4_PGRAPH_SOURCE_COLOR 0x40050C -#define NV4_PGRAPH_SOURCE_COLOR_VALUE 0 -#define NV4_PGRAPH_SOURCE_COLOR_VALUE_0 0x0 -#define NV4_PGRAPH_VALID1 0x400508 -#define NV4_PGRAPH_VALID1_VLD 0 -#define NV4_PGRAPH_VALID1_VLD_0 0x0 -#define NV4_PGRAPH_VALID1_VLD_NOCLIP (0x1<<19) -#define NV4_PGRAPH_VALID1_VLD_SRCCOLOR (0x1<<16) -#define NV4_PGRAPH_VALID1_VLD_GOTMOVE (0x1<<21) -#define NV4_PGRAPH_VALID1_VLD_GOTX01 (0x3<<0) -#define NV4_PGRAPH_VALID1_VLD_GOTX02 (0x7<<0) -#define NV4_PGRAPH_VALID1_VLD_GOTX03 (0xF<<0) -#define NV4_PGRAPH_VALID1_VLD_GOTXCHAIN01 (0x3<<4) -#define NV4_PGRAPH_VALID1_VLD_GOTXCHAIN02 (0x7<<4) -#define NV4_PGRAPH_VALID1_VLD_GOTXCHAIN03 (0xF<<4) -#define NV4_PGRAPH_VALID1_VLD_GOTY01 (0x3<<8) -#define NV4_PGRAPH_VALID1_VLD_GOTY02 (0x7<<8) -#define NV4_PGRAPH_VALID1_VLD_GOTY03 (0xF<<8) -#define NV4_PGRAPH_VALID1_VLD_GOTYCHAIN01 (0x3<<12) -#define NV4_PGRAPH_VALID1_VLD_GOTYCHAIN02 (0x7<<12) -#define NV4_PGRAPH_VALID1_VLD_GOTYCHAIN03 (0xF<<12) -#define NV4_PGRAPH_VALID1_VLD_X_OFFSET (0x1<<0) -#define NV4_PGRAPH_VALID1_VLD_XCHAIN_OFFSET (0x1<<4) -#define NV4_PGRAPH_VALID1_VLD_Y_OFFSET (0x1<<8) -#define NV4_PGRAPH_VALID1_VLD_YCHAIN_OFFSET (0x1<<12) -#define NV4_PGRAPH_VALID1_VLD_GOTCOLOR0 (0x1<<17) -#define NV4_PGRAPH_VALID1_VLD_GOTCOLOR1 (0x1<<18) -#define NV4_PGRAPH_VALID1_VLD_GOTCLIP (0x1<<20) -#define NV4_PGRAPH_VALID1_VLD_GOTFONT (0x1<<22) -#define NV4_PGRAPH_VALID1_VLD_GOTOFFSET (0x1<<22) -#define NV4_PGRAPH_VALID1_VLD_GOTBPITCH (0x1<<2) -#define NV4_PGRAPH_VALID1_VLD_GOTBOFFSET (0x1<<3) -#define NV4_PGRAPH_VALID1_VLD_GOTDUDX (0x1<<4) -#define NV4_PGRAPH_VALID1_VLD_GOTDVDY (0x1<<5) -#define NV4_PGRAPH_VALID1_VLD_GOTPOINT (0x1<<8) -#define NV4_PGRAPH_VALID1_VLD_GOTSIZE (0x1<<9) -#define NV4_PGRAPH_VALID1_VLD_GOTPITCH (0x1<<10) -#define NV4_PGRAPH_VALID1_VLD_GOTSTART (0x1<<11) -#define NV4_PGRAPH_VALID1_VLD_GOTDUDX2 (0x1<<12) -#define NV4_PGRAPH_VALID1_VLD_GOTDVDY2 (0x1<<13) -#define NV4_PGRAPH_VALID1_VLD_GOTPOINT2 (0x1<<14) -#define NV4_PGRAPH_VALID1_VLD_GOTSIZE2 (0x1<<15) -#define NV4_PGRAPH_VALID1_VLD_GOTPITCH2 (0x1<<16) -#define NV4_PGRAPH_VALID1_VLD_GOTSTART2 (0x1<<17) -#define NV4_PGRAPH_VALID1_VLD_GOTOFFSIN (0x1<<0) -#define NV4_PGRAPH_VALID1_VLD_GOTOFFSOUT (0x1<<1) -#define NV4_PGRAPH_VALID1_VLD_GOTPITCHIN (0x1<<2) -#define NV4_PGRAPH_VALID1_VLD_GOTPITCHOUT (0x1<<3) -#define NV4_PGRAPH_VALID1_VLD_GOTLENGTH (0x1<<4) -#define NV4_PGRAPH_VALID1_VLD_GOTCOUNT (0x1<<5) -#define NV4_PGRAPH_VALID1_VLD_GOTFORMAT (0x1<<6) -#define NV4_PGRAPH_VALID1_VLD_GOTNOTIFY (0x1<<7) -#define NV4_PGRAPH_VALID1_CLIP_MIN 28 -#define NV4_PGRAPH_VALID1_CLIP_MIN_NO_ERROR 0x0 -#define NV4_PGRAPH_VALID1_CLIP_MIN_ONLY 0x1 -#define NV4_PGRAPH_VALID1_CLIPA_MIN 29 -#define NV4_PGRAPH_VALID1_CLIPA_MIN_NO_ERROR 0x0 -#define NV4_PGRAPH_VALID1_CLIPA_MIN_ONLY 0x1 -#define NV4_PGRAPH_VALID1_CLIP_MAX 30 -#define NV4_PGRAPH_VALID1_CLIP_MAX_NO_ERROR 0x0 -#define NV4_PGRAPH_VALID1_CLIP_MAX_ONLY 0x1 -#define NV4_PGRAPH_VALID1_CLIPA_MAX 31 -#define NV4_PGRAPH_VALID1_CLIPA_MAX_NO_ERROR 0x0 -#define NV4_PGRAPH_VALID1_CLIPA_MAX_ONLY 0x1 -#define NV4_PGRAPH_VALID2 0x400578 -#define NV4_PGRAPH_VALID2_VLD2 0 -#define NV4_PGRAPH_VALID2_VLD2_0 0x0 -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_COMBINE0A (1<<28) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_COMBINE0C (1<<27) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_COMBINE1A (1<<26) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_COMBINE1C (1<<25) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_COMBFACTOR (1<<24) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_FILTER1 (1<<23) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_OFFSET1 (1<<22) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_FORMAT1 (1<<21) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_BLEND (1<<20) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_CONTROL2 (1<<19) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_CONTROL1 (1<<18) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_CONTROL0 (1<<17) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_FILTER0 (1<<16) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_FORMAT0 (1<<15) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_OFFSET0 (1<<14) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_FOGCOLOR (1<<13) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_COLORKEY (1<<12) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_V1 (1<<9) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_U1 (1<<8) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_V0 (1<<7) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_U0 (1<<6) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_X (1<<5) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_Y (1<<4) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_ZETA (1<<3) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_M (1<<2) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_COLOR (1<<1) -#define NV4_PGRAPH_VALID2_VLD2_GOT3D_SPECULAR (1<<0) -#define NV4_PGRAPH_VALID2_VLD2_DX3FULLVERTEX (0x7f<<0) -#define NV4_PGRAPH_VALID2_VLD2_DX5FULLVERTEX (0x7f<<0) -#define NV4_PGRAPH_VALID2_VLD2_DX6FULLVERTEX (0x1ff<<0) -#define NV4_PGRAPH_VALID2_VLD2_DX3FULLSTATE (0x3f<<13) -#define NV4_PGRAPH_VALID2_VLD2_DX5FULLSTATE (0x1ff<<12) -#define NV4_PGRAPH_VALID2_VLD2_DX6FULLSTATE (0xFfff<<13) -#define NV4_PGRAPH_ABS_ICLIP_XMAX 0x400534 -#define NV4_PGRAPH_ABS_ICLIP_XMAX_VALUE 0 -#define NV4_PGRAPH_ABS_ICLIP_YMAX 0x400538 -#define NV4_PGRAPH_ABS_ICLIP_YMAX_VALUE 0 -#define NV4_PGRAPH_CLIPX_0 0x400524 -// Valid for all clips! -#define NV4_PGRAPH_CLIP_CONDITION_IS_GT 0x0 -#define NV4_PGRAPH_CLIP_CONDITION_IS_LT 0x1 -#define NV4_PGRAPH_CLIP_CONDITION_IS_EQ 0x2 -#define NV4_PGRAPH_CLIPX_0_CLIP0_MIN 0 -#define NV4_PGRAPH_CLIPX_0_CLIP0_MAX 2 -#define NV4_PGRAPH_CLIPX_0_CLIP1_MIN 4 -#define NV4_PGRAPH_CLIPX_0_CLIP1_MAX 6 -#define NV4_PGRAPH_CLIPX_0_CLIP2_MIN 8 -#define NV4_PGRAPH_CLIPX_0_CLIP2_MAX 10 -#define NV4_PGRAPH_CLIPX_0_CLIP3_MIN 12 -#define NV4_PGRAPH_CLIPX_0_CLIP3_MAX 14 -#define NV4_PGRAPH_CLIPX_0_CLIP4_MIN 16 -#define NV4_PGRAPH_CLIPX_0_CLIP4_MAX 18 -#define NV4_PGRAPH_CLIPX_0_CLIP5_MIN 20 -#define NV4_PGRAPH_CLIPX_0_CLIP5_MAX 22 -#define NV4_PGRAPH_CLIPX_0_CLIP6_MIN 24 -#define NV4_PGRAPH_CLIPX_0_CLIP6_MAX 26 -#define NV4_PGRAPH_CLIPX_0_CLIP7_MIN 28 -#define NV4_PGRAPH_CLIPX_0_CLIP7_MAX 30 -#define NV4_PGRAPH_CLIPX_1 0x400528 -#define NV4_PGRAPH_CLIPX_1_CLIP8_MIN 0 -#define NV4_PGRAPH_CLIPX_1_CLIP8_MAX 2 -#define NV4_PGRAPH_CLIPX_1_CLIP9_MIN 4 -#define NV4_PGRAPH_CLIPX_1_CLIP9_MAX 6 -#define NV4_PGRAPH_CLIPX_1_CLIP10_MIN 8 -#define NV4_PGRAPH_CLIPX_1_CLIP10_MAX 10 -#define NV4_PGRAPH_CLIPX_1_CLIP11_MIN 12 -#define NV4_PGRAPH_CLIPX_1_CLIP11_MAX 14 -#define NV4_PGRAPH_CLIPX_1_CLIP12_MIN 16 -#define NV4_PGRAPH_CLIPX_1_CLIP12_MAX 18 -#define NV4_PGRAPH_CLIPX_1_CLIP13_MIN 20 -#define NV4_PGRAPH_CLIPX_1_CLIP13_MAX 22 -#define NV4_PGRAPH_CLIPX_1_CLIP14_MIN 24 -#define NV4_PGRAPH_CLIPX_1_CLIP14_MAX 26 -#define NV4_PGRAPH_CLIPX_1_CLIP15_MIN 28 -#define NV4_PGRAPH_CLIPX_1_CLIP15_MAX 30 -#define NV4_PGRAPH_CLIPY_0 0x40052c -#define NV4_PGRAPH_CLIPY_0_CLIP0_MIN 0 -#define NV4_PGRAPH_CLIPY_0_CLIP0_MAX 2 -#define NV4_PGRAPH_CLIPY_0_CLIP1_MIN 4 -#define NV4_PGRAPH_CLIPY_0_CLIP1_MAX 6 -#define NV4_PGRAPH_CLIPY_0_CLIP2_MIN 8 -#define NV4_PGRAPH_CLIPY_0_CLIP2_MAX 10 -#define NV4_PGRAPH_CLIPY_0_CLIP3_MIN 12 -#define NV4_PGRAPH_CLIPY_0_CLIP3_MAX 14 -#define NV4_PGRAPH_CLIPY_0_CLIP4_MIN 16 -#define NV4_PGRAPH_CLIPY_0_CLIP4_MAX 18 -#define NV4_PGRAPH_CLIPY_0_CLIP5_MIN 20 -#define NV4_PGRAPH_CLIPY_0_CLIP5_MAX 22 -#define NV4_PGRAPH_CLIPY_0_CLIP6_MIN 24 -#define NV4_PGRAPH_CLIPY_0_CLIP6_MAX 26 -#define NV4_PGRAPH_CLIPY_0_CLIP7_MIN 28 -#define NV4_PGRAPH_CLIPY_0_CLIP7_MAX 30 -#define NV4_PGRAPH_CLIPY_1 0x400530 -#define NV4_PGRAPH_CLIPY_1_CLIP8_MIN 0 -#define NV4_PGRAPH_CLIPY_1_CLIP8_MAX 2 -#define NV4_PGRAPH_CLIPY_1_CLIP9_MIN 4 -#define NV4_PGRAPH_CLIPY_1_CLIP9_MAX 6 -#define NV4_PGRAPH_CLIPY_1_CLIP10_MIN 8 -#define NV4_PGRAPH_CLIPY_1_CLIP10_MAX 10 -#define NV4_PGRAPH_CLIPY_1_CLIP11_MIN 12 -#define NV4_PGRAPH_CLIPY_1_CLIP11_MAX 14 -#define NV4_PGRAPH_CLIPY_1_CLIP12_MIN 16 -#define NV4_PGRAPH_CLIPY_1_CLIP12_MAX 18 -#define NV4_PGRAPH_CLIPY_1_CLIP13_MIN 20 -#define NV4_PGRAPH_CLIPY_1_CLIP13_MAX 22 -#define NV4_PGRAPH_CLIPY_1_CLIP14_MIN 24 -#define NV4_PGRAPH_CLIPY_1_CLIP14_MAX 26 -#define NV4_PGRAPH_CLIPY_1_CLIP15_MIN 28 -#define NV4_PGRAPH_CLIPY_1_CLIP15_MAX 30 -#define NV4_PGRAPH_MISC24_0 0x400510 -#define NV4_PGRAPH_MISC24_0_VALUE 0 -#define NV4_PGRAPH_MISC24_1 0x400570 -#define NV4_PGRAPH_MISC24_1_VALUE 0 -#define NV4_PGRAPH_MISC24_2 0x400574 -#define NV4_PGRAPH_MISC24_2_VALUE 0 -#define NV4_PGRAPH_PASSTHRU_0 0x40057C -#define NV4_PGRAPH_PASSTHRU_0_VALUE 0 -#define NV4_PGRAPH_PASSTHRU_1 0x400580 -#define NV4_PGRAPH_PASSTHRU_1_VALUE 0 -#define NV4_PGRAPH_PASSTHRU_2 0x400584 -#define NV4_PGRAPH_PASSTHRU_2_VALUE 0 -#define NV4_PGRAPH_U_RAM(i) (0x400d00+(i)*4) -#define NV4_PGRAPH_U_RAM_SIZE_1 16 -#define NV4_PGRAPH_U_RAM_VALUE 6 -#define NV4_PGRAPH_V_RAM(i) (0x400d40+(i)*4) -#define NV4_PGRAPH_V_RAM_SIZE_1 16 -#define NV4_PGRAPH_V_RAM_VALUE 6 -#define NV4_PGRAPH_M_RAM(i) (0x400d80+(i)*4) -#define NV4_PGRAPH_M_RAM_SIZE_1 16 -#define NV4_PGRAPH_M_RAM_VALUE 6 -#define NV4_PGRAPH_D3D_XY 0x4005c0 -#define NV4_PGRAPH_D3D_XY_X_VALUE 0 -#define NV4_PGRAPH_D3D_XY_Y_VALUE 16 -#define NV4_PGRAPH_D3D_U0 0x4005c4 -#define NV4_PGRAPH_D3D_U0_VALUE 6 -#define NV4_PGRAPH_D3D_V0 0x4005c8 -#define NV4_PGRAPH_D3D_V0_VALUE 6 -#define NV4_PGRAPH_D3D_U1 0x4005cc -#define NV4_PGRAPH_D3D_U1_VALUE 6 -#define NV4_PGRAPH_D3D_V1 0x4005d0 -#define NV4_PGRAPH_D3D_V1_VALUE 6 -#define NV4_PGRAPH_D3D_ZETA 0x4005d4 -#define NV4_PGRAPH_D3D_ZETA_VALUE 0 -#define NV4_PGRAPH_D3D_RGB 0x4005d8 -#define NV4_PGRAPH_D3D_RGB_VALUE 0 -#define NV4_PGRAPH_D3D_S 0x4005dc -#define NV4_PGRAPH_D3D_S_VALUE 0 -#define NV4_PGRAPH_D3D_M 0x4005e0 -#define NV4_PGRAPH_D3D_M_VALUE 6 -#define NV4_PGRAPH_FORMAT0 0x4005A8 -#define NV4_PGRAPH_FORMAT0_CONTEXT_DMA 1 -#define NV4_PGRAPH_FORMAT0_CONTEXT_DMA_A 0x0 -#define NV4_PGRAPH_FORMAT0_CONTEXT_DMA_B 0x1 -#define NV4_PGRAPH_FORMAT0_COLORKEYENABLE 2 -#define NV4_PGRAPH_FORMAT0_COLORKEYENABLE_FALSE 0x0 -#define NV4_PGRAPH_FORMAT0_COLORKEYENABLE_TRUE 0x1 -#define NV4_PGRAPH_FORMAT0_ORIGIN_ZOH 5 -#define NV4_PGRAPH_FORMAT0_ORIGIN_ZOH_CENTER 0x0 -#define NV4_PGRAPH_FORMAT0_ORIGIN_ZOH_CORNER 0x1 -#define NV4_PGRAPH_FORMAT0_ORIGIN_FOH 7 -#define NV4_PGRAPH_FORMAT0_ORIGIN_FOH_CENTER 0x0 -#define NV4_PGRAPH_FORMAT0_ORIGIN_FOH_CORNER 0x1 -#define NV4_PGRAPH_FORMAT0_COLOR 8 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_Y8 0x0 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_AY8 0x1 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_A1R5G5B5 0x2 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_X1R5G5B5 0x3 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_A4R4G4B4 0x4 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_R5G6B5 0x5 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_A8R8G8B8 0x6 -#define NV4_PGRAPH_FORMAT0_COLOR_LE_X8R8G8B8 0x7 -// 0x1-0Xf used for 1-16 mipmap levels -#define NV4_PGRAPH_FORMAT0_MIPMAP_LEVELS 12 -#define NV4_PGRAPH_FORMAT0_MIPMAP_LEVELS_INVALID 0x0 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U 16 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_1 0x0 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_2 0x1 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_4 0x2 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_8 0x3 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_16 0x4 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_32 0x5 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_64 0x6 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_128 0x7 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_256 0x8 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_512 0x9 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_1024 0xA -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_U_2048 0xB -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V 20 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_1 0x0 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_2 0x1 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_4 0x2 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_8 0x3 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_16 0x4 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_32 0x5 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_64 0x6 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_128 0x7 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_256 0x8 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_512 0x9 -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_1024 0xA -#define NV4_PGRAPH_FORMAT0_BASE_SIZE_V_2048 0xB -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSU 24 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSU_WRAP 0x1 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSU_MIRROR 0x2 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSU_CLAMP 0x3 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSU_BORDER 0x4 -#define NV4_PGRAPH_FORMAT0_WRAPU 27 -#define NV4_PGRAPH_FORMAT0_WRAPU_FALSE 0x0 -#define NV4_PGRAPH_FORMAT0_WRAPU_TRUE 0x1 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSV 28 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSV_WRAP 0x1 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSV_MIRROR 0x2 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSV_CLAMP 0x3 -#define NV4_PGRAPH_FORMAT0_TEXTUREADDRESSV_BORDER 0x4 -#define NV4_PGRAPH_FORMAT0_WRAPV 31 -#define NV4_PGRAPH_FORMAT0_WRAPV_FALSE 0x0 -#define NV4_PGRAPH_FORMAT0_WRAPV_TRUE 0x1 -#define NV4_PGRAPH_FORMAT1 0x4005AC -#define NV4_PGRAPH_FORMAT1_CONTEXT_DMA 1 -#define NV4_PGRAPH_FORMAT1_CONTEXT_DMA_A 0x0 -#define NV4_PGRAPH_FORMAT1_CONTEXT_DMA_B 0x1 -#define NV4_PGRAPH_FORMAT1_COLORKEYENABLE 2 -#define NV4_PGRAPH_FORMAT1_COLORKEYENABLE_FALSE 0x0 -#define NV4_PGRAPH_FORMAT1_COLORKEYENABLE_TRUE 0x1 -#define NV4_PGRAPH_FORMAT1_ORIGIN_ZOH 5 -#define NV4_PGRAPH_FORMAT1_ORIGIN_ZOH_CENTER 0x0 -#define NV4_PGRAPH_FORMAT1_ORIGIN_ZOH_CORNER 0x1 -#define NV4_PGRAPH_FORMAT1_ORIGIN_FOH 7 -#define NV4_PGRAPH_FORMAT1_ORIGIN_FOH_CENTER 0x0 -#define NV4_PGRAPH_FORMAT1_ORIGIN_FOH_CORNER 0x1 -#define NV4_PGRAPH_FORMAT1_COLOR 8 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_Y8 0x0 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_AY8 0x1 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_A1R5G5B5 0x2 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_X1R5G5B5 0x3 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_A4R4G4B4 0x4 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_R5G6B5 0x5 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_A8R8G8B8 0x6 -#define NV4_PGRAPH_FORMAT1_COLOR_LE_X8R8G8B8 0x7 -// 15:12 = number of mipmap levels (1-15. 0 = invalid). Stupid defines removed here -#define NV4_PGRAPH_FORMAT1_MIPMAP_LEVELS 12 -#define NV4_PGRAPH_FORMAT1_MIPMAP_LEVELS_INVALID 0x0 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U 16 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_1 0x0 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_2 0x1 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_4 0x2 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_8 0x3 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_16 0x4 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_32 0x5 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_64 0x6 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_128 0x7 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_256 0x8 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_512 0x9 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_1024 0xA -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_U_2048 0xB -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V 20 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_1 0x0 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_2 0x1 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_4 0x2 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_8 0x3 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_16 0x4 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_32 0x5 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_64 0x6 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_128 0x7 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_256 0x8 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_512 0x9 -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_1024 0xA -#define NV4_PGRAPH_FORMAT1_BASE_SIZE_V_2048 0xB -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSU 24 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSU_WRAP 0x1 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSU_MIRROR 0x2 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSU_CLAMP 0x3 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSU_BORDER 0x4 -#define NV4_PGRAPH_FORMAT1_WRAPU 27 -#define NV4_PGRAPH_FORMAT1_WRAPU_TRUE 0x1 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSV 28 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSV_WRAP 0x1 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSV_MIRROR 0x2 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSV_CLAMP 0x3 -#define NV4_PGRAPH_FORMAT1_TEXTUREADDRESSV_BORDER 0x4 -#define NV4_PGRAPH_FORMAT1_WRAPV 31 -#define NV4_PGRAPH_FORMAT1_WRAPV_TRUE 0x1 -#define NV4_PGRAPH_FILTER0 0x4005B0 -#define NV4_PGRAPH_FILTER0_KERNEL_SIZE_X 1 -#define NV4_PGRAPH_FILTER0_KERNEL_SIZE_Y 9 -#define NV4_PGRAPH_FILTER0_MIPMAP_DITHER_ENABLE 15 -#define NV4_PGRAPH_FILTER0_MIPMAP_DITHER_ENABLE_FALSE 0x0 -#define NV4_PGRAPH_FILTER0_MIPMAP_DITHER_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_FILTER0_MIPMAPLODBIAS 16 -#define NV4_PGRAPH_FILTER0_TEXTUREMIN 24 -#define NV4_PGRAPH_FILTER0_TEXTUREMIN_NEAREST 0x1 -#define NV4_PGRAPH_FILTER0_TEXTUREMIN_LINEAR 0x2 -#define NV4_PGRAPH_FILTER0_TEXTUREMIN_MIPNEAREST 0x3 -#define NV4_PGRAPH_FILTER0_TEXTUREMIN_MIPLINEAR 0x4 -#define NV4_PGRAPH_FILTER0_TEXTUREMIN_LINEARMIPNEAREST 0x5 -#define NV4_PGRAPH_FILTER0_TEXTUREMIN_LINEARMIPLINEAR 0x6 -#define NV4_PGRAPH_FILTER0_ANISOTROPIC_MIN_ENABLE 27 -#define NV4_PGRAPH_FILTER0_ANISOTROPIC_MIN_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_FILTER0_TEXTUREMAG 28 -#define NV4_PGRAPH_FILTER0_TEXTUREMAG_NEAREST 0x1 -#define NV4_PGRAPH_FILTER0_TEXTUREMAG_LINEAR 0x2 -#define NV4_PGRAPH_FILTER0_TEXTUREMAG_MIPNEAREST 0x3 -#define NV4_PGRAPH_FILTER0_TEXTUREMAG_MIPLINEAR 0x4 -#define NV4_PGRAPH_FILTER0_TEXTUREMAG_LINEARMIPNEAREST 0x5 -#define NV4_PGRAPH_FILTER0_TEXTUREMAG_LINEARMIPLINEAR 0x6 -#define NV4_PGRAPH_FILTER0_ANISOTROPIC_MAG_ENABLE 31 -#define NV4_PGRAPH_FILTER0_ANISOTROPIC_MAG_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_FILTER1 0x4005B4 -#define NV4_PGRAPH_FILTER1_KERNEL_SIZE_X 1 -#define NV4_PGRAPH_FILTER1_KERNEL_SIZE_Y 9 -#define NV4_PGRAPH_FILTER1_MIPMAP_DITHER_ENABLE 15 -#define NV4_PGRAPH_FILTER1_MIPMAP_DITHER_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_FILTER1_MIPMAPLODBIAS 16 -#define NV4_PGRAPH_FILTER1_TEXTUREMIN 24 -#define NV4_PGRAPH_FILTER1_TEXTUREMIN_NEAREST 0x1 -#define NV4_PGRAPH_FILTER1_TEXTUREMIN_LINEAR 0x2 -#define NV4_PGRAPH_FILTER1_TEXTUREMIN_MIPNEAREST 0x3 -#define NV4_PGRAPH_FILTER1_TEXTUREMIN_MIPLINEAR 0x4 -#define NV4_PGRAPH_FILTER1_TEXTUREMIN_LINEARMIPNEAREST 0x5 -#define NV4_PGRAPH_FILTER1_TEXTUREMIN_LINEARMIPLINEAR 0x6 -#define NV4_PGRAPH_FILTER1_ANISOTROPIC_MIN_ENABLE 27 -#define NV4_PGRAPH_FILTER1_ANISOTROPIC_MIN_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_FILTER1_TEXTUREMAG 28 -#define NV4_PGRAPH_FILTER1_TEXTUREMAG_NEAREST 0x1 -#define NV4_PGRAPH_FILTER1_TEXTUREMAG_LINEAR 0x2 -#define NV4_PGRAPH_FILTER1_TEXTUREMAG_MIPNEAREST 0x3 -#define NV4_PGRAPH_FILTER1_TEXTUREMAG_MIPLINEAR 0x4 -#define NV4_PGRAPH_FILTER1_TEXTUREMAG_LINEARMIPNEAREST 0x5 -#define NV4_PGRAPH_FILTER1_TEXTUREMAG_LINEARMIPLINEAR 0x6 -#define NV4_PGRAPH_FILTER1_ANISOTROPIC_MAG_ENABLE 31 -#define NV4_PGRAPH_FILTER1_ANISOTROPIC_MAG_ENABLE_TRUE 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA 0x400590 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_0 0 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_0_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_0_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0 4:2 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_0_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_1 8 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_1_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_1_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1 10 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_1_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_2 16 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_2_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_2_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2 18 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_2_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_3 24 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_3_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0ALPHA_INVERSE_3_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3 26 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0ALPHA_ARGUMENT_3_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION 29 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION_ADD 0x1 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION_ADD2 0x2 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION_ADD4 0x3 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION_ADDSIGNED 0x4 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION_MUX 0x5 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION_ADDCOMPLEMENT 0x6 -#define NV4_PGRAPH_COMBINE0ALPHA_OPERATION_ADDSIGNED2 0x7 -#define NV4_PGRAPH_COMBINE0COLOR 0x400594 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_0 0 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_0_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_0_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_0 1 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_0_COLOR 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_0_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0 2 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_0_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_1 8 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_1_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_1_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_1 9 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_1_COLOR 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_1_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1 10 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_1_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_2 16 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_2_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_2_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_2 17 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_2_COLOR 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_2_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2 18 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_2_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_3 24 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_3_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_INVERSE_3_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_3 25 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_3_COLOR 0x0 -#define NV4_PGRAPH_COMBINE0COLOR_ALPHA_3_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3 26 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3_ZERO 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3_INPUT 0x4 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE0COLOR_ARGUMENT_3_TEXTURELOD 0x7 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION 29 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION_ADD 0x1 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION_ADD2 0x2 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION_ADD4 0x3 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION_ADDSIGNED 0x4 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION_MUX 0x5 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION_ADDCOMPLEMENT 0x6 -#define NV4_PGRAPH_COMBINE0COLOR_OPERATION_ADDSIGNED2 0x7 -#define NV4_PGRAPH_COMBINE1ALPHA 0x400598 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_0 0 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_0_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_0_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_0 2 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_0_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_0_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_0_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_0_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_0_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_0_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_1 8 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_1_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_1_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_1 10 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_1_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_1_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_1_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_1_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_1_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_1_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_2 16 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_2_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_2_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_2 18 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_2_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_2_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_2_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_2_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_2_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_2_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_3 24 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_3_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1ALPHA_INVERSE_3_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_3 26 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_3_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_3_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_3_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_3_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_3_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1ALPHA_ARGUMENT_3_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION 29 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION_ADD 0x1 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION_ADD2 0x2 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION_ADD4 0x3 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION_ADDSIGNED 0x4 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION_MUX 0x5 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION_ADDCOMPLEMENT 0x6 -#define NV4_PGRAPH_COMBINE1ALPHA_OPERATION_ADDSIGNED2 0x7 -#define NV4_PGRAPH_COMBINE1COLOR 0x40059C -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_0 0 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_0_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_0_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_0 1 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_0_COLOR 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_0_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_0 4:2 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_0_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_0_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_0_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_0_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_0_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_0_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_1 8 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_1_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_1_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_1 9 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_1_COLOR 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_1_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_1 10 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_1_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_1_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_1_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_1_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_1_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_1_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_2 16 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_2_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_2_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_2 17 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_2_COLOR 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_2_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_2 18 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_2_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_2_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_2_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_2_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_2_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_2_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_3 24 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_3_NORMAL 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_INVERSE_3_INVERSE 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_3 25 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_3_COLOR 0x0 -#define NV4_PGRAPH_COMBINE1COLOR_ALPHA_3_ALPHA 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_3 26 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_3_ZERO 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_3_FACTOR 0x2 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_3_DIFFUSE 0x3 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_3_INPUT 0x4 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_3_TEXTURE0 0x5 -#define NV4_PGRAPH_COMBINE1COLOR_ARGUMENT_3_TEXTURE1 0x6 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION 29 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION_ADD 0x1 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION_ADD2 0x2 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION_ADD4 0x3 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION_ADDSIGNED 0x4 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION_MUX 0x5 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION_ADDCOMPLEMENT 0x6 -#define NV4_PGRAPH_COMBINE1COLOR_OPERATION_ADDSIGNED2 0x7 -#define NV4_PGRAPH_DMA_START_0 0x401000 -#define NV4_PGRAPH_DMA_START_0_VALUE 0 -#define NV4_PGRAPH_DMA_START_1 0x401004 -#define NV4_PGRAPH_DMA_START_1_VALUE 0 -#define NV4_PGRAPH_DMA_LENGTH 0x401008 -#define NV4_PGRAPH_DMA_LENGTH_VALUE 0 -#define NV4_PGRAPH_DMA_MISC 0x40100C -#define NV4_PGRAPH_DMA_MISC_COUNT 0 -#define NV4_PGRAPH_DMA_MISC_FMT_SRC 16 -#define NV4_PGRAPH_DMA_MISC_FMT_DST 20 -#define NV4_PGRAPH_DMA_DATA_0 0x401020 -#define NV4_PGRAPH_DMA_DATA_0_VALUE 0 -#define NV4_PGRAPH_DMA_DATA_1 0x401024 -#define NV4_PGRAPH_DMA_DATA_1_VALUE 0 -#define NV4_PGRAPH_DMA_RM 0x401030 -#define NV4_PGRAPH_DMA_RM_ASSIST_A 0 -#define NV4_PGRAPH_DMA_RM_ASSIST_A_NOT_PENDING 0x0 -#define NV4_PGRAPH_DMA_RM_ASSIST_A_PENDING 0x1 -#define NV4_PGRAPH_DMA_RM_ASSIST_A_RESET 0x1 -#define NV4_PGRAPH_DMA_RM_ASSIST_B 1 -#define NV4_PGRAPH_DMA_RM_ASSIST_B_NOT_PENDING 0x0 -#define NV4_PGRAPH_DMA_RM_ASSIST_B_PENDING 0x1 -#define NV4_PGRAPH_DMA_RM_ASSIST_B_RESET 0x1 -#define NV4_PGRAPH_DMA_RM_WRITE_REQ 4 -#define NV4_PGRAPH_DMA_RM_WRITE_REQ_NOT_PENDING 0x0 -#define NV4_PGRAPH_DMA_RM_WRITE_REQ_PENDING 0x1 -#define NV4_PGRAPH_DMA_A_XLATE_INST 0x401040 -#define NV4_PGRAPH_DMA_A_XLATE_INST_VALUE 0 -#define NV4_PGRAPH_DMA_A_CONTROL 0x401044 -#define NV4_PGRAPH_DMA_A_CONTROL_PAGE_TABLE 12 -#define NV4_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_NOT_PRESENT 0x0 -#define NV4_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_PRESENT 0x1 -#define NV4_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY 13 -#define NV4_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x0 -#define NV4_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_LINEAR 0x1 -#define NV4_PGRAPH_DMA_A_CONTROL_TARGET_NODE 16 -#define NV4_PGRAPH_DMA_A_CONTROL_TARGET_NODE_NVM 0x0 -#define NV4_PGRAPH_DMA_A_CONTROL_TARGET_NODE_PCI 0x2 -#define NV4_PGRAPH_DMA_A_CONTROL_TARGET_NODE_AGP 0x3 -#define NV4_PGRAPH_DMA_A_CONTROL_ADJUST 20 -#define NV4_PGRAPH_DMA_A_LIMIT 0x401048 -#define NV4_PGRAPH_DMA_A_LIMIT_OFFSET 0 -#define NV4_PGRAPH_DMA_A_TLB_PTE 0x40104C -#define NV4_PGRAPH_DMA_A_TLB_PTE_ACCESS 1 -#define NV4_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_ONLY 0x0 -#define NV4_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_WRITE 0x1 -#define NV4_PGRAPH_DMA_A_TLB_PTE_FRAME_ADDRESS 12 -#define NV4_PGRAPH_DMA_A_TLB_TAG 0x401050 -#define NV4_PGRAPH_DMA_A_TLB_TAG_ADDRESS 12 -#define NV4_PGRAPH_DMA_A_ADJ_OFFSET 0x401054 -#define NV4_PGRAPH_DMA_A_ADJ_OFFSET_VALUE 0 -#define NV4_PGRAPH_DMA_A_OFFSET 0x401058 -#define NV4_PGRAPH_DMA_A_OFFSET_VALUE 0 -#define NV4_PGRAPH_DMA_A_SIZE 0x40105C -#define NV4_PGRAPH_DMA_A_SIZE_VALUE 0 -#define NV4_PGRAPH_DMA_A_Y_SIZE 0x401060 -#define NV4_PGRAPH_DMA_A_Y_SIZE_VALUE 0 -#define NV4_PGRAPH_DMA_B_XLATE_INST 0x401080 -#define NV4_PGRAPH_DMA_B_XLATE_INST_VALUE 0 -#define NV4_PGRAPH_DMA_B_CONTROL 0x401084 -#define NV4_PGRAPH_DMA_B_CONTROL_PAGE_TABLE 12 -#define NV4_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_NOT_PRESENT 0x0 -#define NV4_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_PRESENT 0x1 -#define NV4_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY 13 -#define NV4_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x0 -#define NV4_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_LINEAR 0x1 -#define NV4_PGRAPH_DMA_B_CONTROL_TARGET_NODE 16 -#define NV4_PGRAPH_DMA_B_CONTROL_TARGET_NODE_NVM 0x0 -#define NV4_PGRAPH_DMA_B_CONTROL_TARGET_NODE_PCI 0x2 -#define NV4_PGRAPH_DMA_B_CONTROL_TARGET_NODE_AGP 0x3 -#define NV4_PGRAPH_DMA_B_CONTROL_ADJUST 20 -#define NV4_PGRAPH_DMA_B_LIMIT 0x401088 -#define NV4_PGRAPH_DMA_B_LIMIT_OFFSET 0 -#define NV4_PGRAPH_DMA_B_TLB_PTE 0x40108C -#define NV4_PGRAPH_DMA_B_TLB_PTE_ACCESS 1 -#define NV4_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_ONLY 0x0 -#define NV4_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_WRITE 0x1 -#define NV4_PGRAPH_DMA_B_TLB_PTE_FRAME_ADDRESS 12 -#define NV4_PGRAPH_DMA_B_TLB_TAG 0x401090 -#define NV4_PGRAPH_DMA_B_TLB_TAG_ADDRESS 12 -#define NV4_PGRAPH_DMA_B_ADJ_OFFSET 0x401094 -#define NV4_PGRAPH_DMA_B_ADJ_OFFSET_VALUE 0 -#define NV4_PGRAPH_DMA_B_OFFSET 0x401098 -#define NV4_PGRAPH_DMA_B_OFFSET_VALUE 0 -#define NV4_PGRAPH_DMA_B_SIZE 0x40109C -#define NV4_PGRAPH_DMA_B_SIZE_VALUE 0 -#define NV4_PGRAPH_DMA_B_Y_SIZE 0x4010A0 -#define NV4_PGRAPH_DMA_B_Y_SIZE_VALUE 0 -#define NV4_PGRAPH_CONTROL_OUT_INTERPOLATOR 0 -#define NV4_PGRAPH_CONTROL_OUT_INTERPOLATOR_ZOH_MS 0x0 -#define NV4_PGRAPH_CONTROL_OUT_INTERPOLATOR_ZOH 0x1 -#define NV4_PGRAPH_CONTROL_OUT_INTERPOLATOR_FOH 0x2 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_U 4 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_U_CYLINDRICAL 0x0 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_U_WRAP 0x1 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_U_MIRROR 0x2 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_U_CLAMP 0x3 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_V 6 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_V_CYLINDRICAL 0x0 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_V_WRAP 0x1 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_V_MIRROR 0x2 -#define NV4_PGRAPH_CONTROL_OUT_WRAP_V_CLAMP 0x3 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_FORMAT 8 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_FORMAT_LE_X8R8G8B8 0x0 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_FORMAT_LE_A8R8G8B8 0x1 -#define NV4_PGRAPH_CONTROL_OUT_SRCCOLOR 10 -#define NV4_PGRAPH_CONTROL_OUT_SRCCOLOR_NORMAL 0x0 -#define NV4_PGRAPH_CONTROL_OUT_SRCCOLOR_COLOR_INVERSE 0x1 -#define NV4_PGRAPH_CONTROL_OUT_SRCCOLOR_ALPHA_INVERSE 0x2 -#define NV4_PGRAPH_CONTROL_OUT_SRCCOLOR_ALPHA_ONE 0x3 -#define NV4_PGRAPH_CONTROL_OUT_CULLING 12 -#define NV4_PGRAPH_CONTROL_OUT_CULLING_ILLEGAL 0x0 -#define NV4_PGRAPH_CONTROL_OUT_CULLING_NONE 0x1 -#define NV4_PGRAPH_CONTROL_OUT_CULLING_COUNTERCLOCKWISE 0x2 -#define NV4_PGRAPH_CONTROL_OUT_CULLING_CLOCKWISE 0x3 -#define NV4_PGRAPH_CONTROL_OUT_ZBUFFER 15 -#define NV4_PGRAPH_CONTROL_OUT_ZBUFFER_SCREEN 0x0 -#define NV4_PGRAPH_CONTROL_OUT_ZBUFFER_LINEAR 0x1 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE 16 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_ILLEGAL 0x0 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_FALSE 0x1 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_LT 0x2 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_EQ 0x3 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_LE 0x4 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_GT 0x5 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_NE 0x6 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_GE 0x7 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_COMPARE_TRUE 0x8 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_WRITE 20 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_WRITE_NEVER 0x0 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_WRITE_ALPHA 0x1 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_WRITE_ALPHA_ZETA 0x2 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_WRITE_ZETA 0x3 -#define NV4_PGRAPH_CONTROL_OUT_ZETA_WRITE_ALWAYS 0x4 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_WRITE 24 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_WRITE_NEVER 0x0 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_WRITE_ALPHA 0x1 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_WRITE_ALPHA_ZETA 0x2 -#define NV4_PGRAPH_CONTROL_OUT_COLOR_WRITE_ZETA 0x3 -#define NV4_PGRAPH_CONTROL_OUT_ROP 28 -#define NV4_PGRAPH_CONTROL_OUT_ROP_BLEND_AND 0x0 -#define NV4_PGRAPH_CONTROL_OUT_ROP_ADD_WITH_SATURATION 0x1 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_BETA 29 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_BETA_SRCALPHA 0x0 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_BETA_DESTCOLOR 0x1 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_INPUT0 30 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_INPUT0_DESTCOLOR 0x0 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_INPUT0_ZERO 0x1 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_INPUT1 31 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_INPUT1_SRCCOLOR 0x0 -#define NV4_PGRAPH_CONTROL_OUT_BLEND_INPUT1_ZERO 0x1 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_KEY 0 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE 8 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_ILLEGAL 0x0 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_FALSE 0x1 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_LT 0x2 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_EQ 0x3 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_LE 0x4 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_GT 0x5 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_NE 0x6 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_GE 0x7 -#define NV4_PGRAPH_ALPHACNTRL_ALPHA_COMPARE_TRUE 0x8 - -#define NV4_PVIDEO_START 0x680000 -#define NV4_PVIDEO_END 0x6802FF - -#define NV4_PVIDEO_INTR_0 0x680100 -#define NV4_PVIDEO_INTR_0_NOTIFY 0 -#define NV4_PVIDEO_INTR_0_NOTIFY_NOT_PENDING 0x0 -#define NV4_PVIDEO_INTR_0_NOTIFY_PENDING 0x1 -#define NV4_PVIDEO_INTR_0_NOTIFY_RESET 0x1 -#define NV4_PVIDEO_INTR_EN_0 0x680140 -#define NV4_PVIDEO_INTR_EN_0_NOTIFY 0 -#define NV4_PVIDEO_INTR_EN_0_NOTIFY_ENABLED 0x1 -#define NV4_PVIDEO_STEP_SIZE 0x680200 -#define NV4_PVIDEO_STEP_SIZE_X 0 -#define NV4_PVIDEO_STEP_SIZE_Y 16 -#define NV4_PVIDEO_CONTROL_Y 0x680204 -#define NV4_PVIDEO_CONTROL_Y_BLUR 0 -#define NV4_PVIDEO_CONTROL_Y_BLUR_OFF 0x0 -#define NV4_PVIDEO_CONTROL_Y_BLUR_ON 0x1 -#define NV4_PVIDEO_CONTROL_Y_LINE 4 -#define NV4_PVIDEO_CONTROL_Y_LINE_HALF 0x0 -#define NV4_PVIDEO_CONTROL_Y_LINE_FULL 0x1 -#define NV4_PVIDEO_CONTROL_X 0x680208 -#define NV4_PVIDEO_CONTROL_X_WEIGHT 0 -#define NV4_PVIDEO_CONTROL_X_WEIGHT_LIGHT 0x0 -#define NV4_PVIDEO_CONTROL_X_WEIGHT_HEAVY 0x1 -#define NV4_PVIDEO_CONTROL_X_SHARPENING 4 -#define NV4_PVIDEO_CONTROL_X_SHARPENING_OFF 0x0 -#define NV4_PVIDEO_CONTROL_X_SHARPENING_ON 0x1 -#define NV4_PVIDEO_CONTROL_X_SMOOTHING 8 -#define NV4_PVIDEO_CONTROL_X_SMOOTHING_OFF 0x0 -#define NV4_PVIDEO_CONTROL_X_SMOOTHING_ON 0x1 -#define NV4_PVIDEO_BUFF0_START 0x68020c -#define NV4_PVIDEO_BUFF0_START_ADDRESS 2 -#define NV4_PVIDEO_BUFF1_START 0x680210 -#define NV4_PVIDEO_BUFF1_START_ADDRESS 2 -#define NV4_PVIDEO_BUFF0_PITCH 0x680214 -#define NV4_PVIDEO_BUFF0_PITCH_LENGTH 4 -#define NV4_PVIDEO_BUFF1_PITCH 0x680218 -#define NV4_PVIDEO_BUFF1_PITCH_LENGTH 4 -#define NV4_PVIDEO_BUFF0_OFFSET 0x68021c -#define NV4_PVIDEO_BUFF0_OFFSET_X 0 -#define NV4_PVIDEO_BUFF0_OFFSET_Y 4 -#define NV4_PVIDEO_BUFF0_OFFSET_Y_OFF 0x0 -#define NV4_PVIDEO_BUFF0_OFFSET_Y_QUARTER 0x1 -#define NV4_PVIDEO_BUFF0_OFFSET_Y_HALF 0x2 -#define NV4_PVIDEO_BUFF1_OFFSET 0x680220 -#define NV4_PVIDEO_BUFF1_OFFSET_X 0 -#define NV4_PVIDEO_BUFF1_OFFSET_Y 4 -#define NV4_PVIDEO_BUFF1_OFFSET_Y_OFF 0x0 -#define NV4_PVIDEO_BUFF1_OFFSET_Y_QUARTER 0x1 -#define NV4_PVIDEO_BUFF1_OFFSET_Y_HALF 0x2 -#define NV4_PVIDEO_OE_STATE 0x680224 -#define NV4_PVIDEO_OE_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PVIDEO_OE_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PVIDEO_OE_STATE_BUFF0_ERROR 8 -#define NV4_PVIDEO_OE_STATE_BUFF1_ERROR 12 -#define NV4_PVIDEO_OE_STATE_BUFF0_IN_USE 16 -#define NV4_PVIDEO_OE_STATE_BUFF1_IN_USE 20 -#define NV4_PVIDEO_OE_STATE_CURRENT_BUFFER 24 -#define NV4_PVIDEO_OE_STATE_CURRENT_BUFFER_0 0x0 -#define NV4_PVIDEO_OE_STATE_CURRENT_BUFFER_1 0x1 -#define NV4_PVIDEO_SU_STATE 0x680228 -#define NV4_PVIDEO_SU_STATE_BUFF0_IN_USE 16 -#define NV4_PVIDEO_SU_STATE_BUFF1_IN_USE 20 -#define NV4_PVIDEO_RM_STATE 0x68022c -#define NV4_PVIDEO_RM_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PVIDEO_RM_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PVIDEO_WINDOW_START 0x680230 -#define NV4_PVIDEO_WINDOW_START_X 0 -#define NV4_PVIDEO_WINDOW_START_Y 16 -#define NV4_PVIDEO_WINDOW_SIZE 0x680234 -#define NV4_PVIDEO_WINDOW_SIZE_X 0 -#define NV4_PVIDEO_WINDOW_SIZE_Y 16 -#define NV4_PVIDEO_FIFO_THRES 0x680238 -#define NV4_PVIDEO_FIFO_THRES_SIZE 3 -#define NV4_PVIDEO_FIFO_BURST 0x68023c -#define NV4_PVIDEO_FIFO_BURST_LENGTH 0 -#define NV4_PVIDEO_FIFO_BURST_LENGTH_32 0x1 -#define NV4_PVIDEO_FIFO_BURST_LENGTH_64 0x2 -#define NV4_PVIDEO_FIFO_BURST_LENGTH_128 0x3 -#define NV4_PVIDEO_KEY 0x680240 -#define NV4_PVIDEO_KEY_INDEX 0 -#define NV4_PVIDEO_KEY_565 0 -#define NV4_PVIDEO_KEY_555 0 -#define NV4_PVIDEO_KEY_888 0 -#define NV4_PVIDEO_KEY_PACK 24 -#define NV4_PVIDEO_OVERLAY 0x680244 -#define NV4_PVIDEO_OVERLAY_VIDEO 0 -#define NV4_PVIDEO_OVERLAY_VIDEO_OFF 0x0 -#define NV4_PVIDEO_OVERLAY_VIDEO_ON 0x1 -#define NV4_PVIDEO_OVERLAY_KEY 4 -#define NV4_PVIDEO_OVERLAY_KEY_OFF 0x0 -#define NV4_PVIDEO_OVERLAY_KEY_ON 0x1 -#define NV4_PVIDEO_OVERLAY_FORMAT 8 -#define NV4_PVIDEO_OVERLAY_FORMAT_CCIR 0x0 -#define NV4_PVIDEO_OVERLAY_FORMAT_YUY2 0x1 -#define NV4_PVIDEO_RED_CSC 0x680280 -#define NV4_PVIDEO_RED_CSC_OFFSET 0 -#define NV4_PVIDEO_GREEN_CSC 0x680284 -#define NV4_PVIDEO_GREEN_CSC_OFFSET 0 -#define NV4_PVIDEO_BLUE_CSC 0x680288 -#define NV4_PVIDEO_BLUE_CSC_OFFSET 0 -#define NV4_PVIDEO_CSC_ADJUST 0x68028c -#define NV4_PVIDEO_CSC_ADJUST_B_FLAG 0 -#define NV4_PVIDEO_CSC_ADJUST_B_FLAG_OFF 0x0 -#define NV4_PVIDEO_CSC_ADJUST_B_FLAG_ON 0x1 -#define NV4_PVIDEO_CSC_ADJUST_G_FLAG 4 -#define NV4_PVIDEO_CSC_ADJUST_G_FLAG_OFF 0x0 -#define NV4_PVIDEO_CSC_ADJUST_G_FLAG_ON 0x1 -#define NV4_PVIDEO_CSC_ADJUST_R_FLAG 8 -#define NV4_PVIDEO_CSC_ADJUST_R_FLAG_OFF 0x0 -#define NV4_PVIDEO_CSC_ADJUST_R_FLAG_ON 0x1 -#define NV4_PVIDEO_CSC_ADJUST_L_FLAG 12 -#define NV4_PVIDEO_CSC_ADJUST_L_FLAG_OFF 0x0 -#define NV4_PVIDEO_CSC_ADJUST_L_FLAG_ON 0x1 -#define NV4_PVIDEO_CSC_ADJUST_CHROMA 16 -#define NV4_PVIDEO_CSC_ADJUST_CHROMA_OFF 0x0 -#define NV4_PVIDEO_CSC_ADJUST_CHROMA_ON 0x1 - -#define NV4_PRMCIO_START 0x601000 -#define NV4_PRMCIO_END 0x601FFF - -#define NV4_PRMCIO_INP0 0x6013c2 -#define NV4_PRMCIO_INP0_MONO 0x6013ba -#define NV4_PRMCIO_INP0_COLOR 0x6013da -#define NV4_PRMCIO_INP0_READ_MONO 0x6013ca -#define NV4_PRMCIO_INP0_WRITE_MONO 0x6013ba -#define NV4_PRMCIO_INP0_WRITE_COLOR 0x6013da -// DEFAULT = Palette -#define NV4_PRMCIO_ARX 0x6013c0 -#define NV4_PRMCIO_AR_WRITE 0x6013c0 // After ARX -#define NV4_PRMCIO_AR_READ 0x6013c1 -#define NV4_PRMCIO_AR_PALETTE_WRITE 0x6013c0 -#define NV4_PRMCIO_AR_PALETTE_READ 0x6013c1 -#define NV4_PRMCIO_AR_MODE_INDEX 0x10 -#define NV4_PRMCIO_AR_OSCAN_INDEX 0x11 -#define NV4_PRMCIO_AR_PLANE_INDEX 0x12 -#define NV4_PRMCIO_AR_HPP_INDEX 0x13 -#define NV4_PRMCIO_AR_CSEL_INDEX 0x14 -#define NV4_PRMCIO_CRX_MONO 0x6013b4 -#define NV4_PRMCIO_CRX_COLOR 0x6013d4 -#define NV4_PRMCIO_CR_MONO 0x6013b5 -#define NV4_PRMCIO_CR_COLOR 0x6013d5 -#define NV4_PRMCIO_CRE_MONO 0x6013b5 -#define NV4_PRMCIO_CRE_COLOR 0x6013d5 - -#define NV4_PCRTC_INTR_0 0x600100 -#define NV4_PCRTC_INTR_0_VBLANK 0 -#define NV4_PCRTC_INTR_0_VBLANK_NOT_PENDING 0x0 -#define NV4_PCRTC_INTR_0_VBLANK_PENDING 0x1 -#define NV4_PCRTC_INTR_0_VBLANK_RESET 0x1 -#define NV4_PCRTC_INTR_EN_0 0x600140 -#define NV4_PCRTC_INTR_EN_0_VBLANK 0 -#define NV4_PCRTC_INTR_EN_0_VBLANK_ENABLED 0x1 -#define NV4_PCRTC_START 0x600800 -#define NV4_PCRTC_START_ADDRESS 2 -#define NV4_PCRTC_CONFIG 0x600804 -#define NV4_PCRTC_CONFIG_START_ADDRESS 0 -#define NV4_PCRTC_CONFIG_START_ADDRESS_VGA 0x0 -#define NV4_PCRTC_CONFIG_START_ADDRESS_NON_VGA 0x1 -#define NV4_PCRTC_CONFIG_START_ADDRESS_HSYNC 0x2 -#define NV4_PCRTC_RASTER 0x600808 -#define NV4_PCRTC_RASTER_POSITION 0 -#define NV4_PCRTC_RASTER_SA_LOAD 12 -#define NV4_PCRTC_RASTER_SA_LOAD_DISPLAY 0x0 -#define NV4_PCRTC_RASTER_SA_LOAD_BEFORE 0x1 -#define NV4_PCRTC_RASTER_SA_LOAD_AFTER 0x2 -#define NV4_PCRTC_RASTER_VERT_BLANK 16 -#define NV4_PCRTC_RASTER_VERT_BLANK_ACTIVE 0x1 -#define NV4_PCRTC_RASTER_VERT_BLANK_INACTIVE 0x0 - -#define NV4_CIO_START 0x3B0 -#define NV4_CIO_END 0x3DF -#define NV4_CIO_SIZE NV4_CIO_END - NV4_CIO_START - - -#define NV4_CIO_INP0 0x3c2 -#define NV4_CIO_INP0_MONO 0x3ba -#define NV4_CIO_INP0_COLOR 0x3da -#define NV4_CIO_INP0_READ_MONO 0x3ca -#define NV4_CIO_INP0_WRITE_MONO 0x3ba -#define NV4_CIO_INP0_WRITE_COLOR 0x3da -#define NV4_CIO_ARX 0x3c0 // if index is not 0x10-0x13 write palette -#define NV4_CIO_AR_PALETTE_WRITE 0x3c0 -#define NV4_CIO_AR_PALETTE_READ 0x3c1 -#define NV4_CIO_AR_MODE_WRITE 0x3c0 -#define NV4_CIO_AR_MODE_READ 0x3c1 -#define NV4_CIO_AR_MODE_INDEX 0x10 -#define NV4_CIO_AR_OSCAN_WRITE 0x3c0 -#define NV4_CIO_AR_OSCAN_READ 0x3c1 -#define NV4_CIO_AR_OSCAN_INDEX 0x11 -#define NV4_CIO_AR_PLANE_WRITE 0x3c0 -#define NV4_CIO_AR_PLANE_READ 0x3c1 -#define NV4_CIO_AR_PLANE_INDEX 0x12 -#define NV4_CIO_AR_HPP_WRITE 0x3c0 -#define NV4_CIO_AR_HPP_READ 0x3c1 -#define NV4_CIO_AR_HPP_INDEX 0x13 -#define NV4_CIO_AR_CSEL_WRITE 0x3c0 -#define NV4_CIO_AR_CSEL_READ 0x3c1 -#define NV4_CIO_AR_CSEL_INDEX 0x14 -#define NV4_CIO_CRX_MONO 0x3b4 -#define NV4_CIO_CRX_COLOR 0x3d4 -#define NV4_CIO_CR_MONO 0x3b5 -#define NV4_CIO_CR_COLOR 0x3d5 -#define NV4_CIO_CR_HDT_INDEX 0x0 -#define NV4_CIO_CR_HDE_INDEX 0x1 -#define NV4_CIO_CR_HBS_INDEX 0x2 -#define NV4_CIO_CR_HBE_INDEX 0x3 -#define NV4_CIO_CR_HBE_4_0 0 -#define NV4_CIO_CR_HRS_INDEX 0x4 -#define NV4_CIO_CR_HRE_INDEX 0x5 -#define NV4_CIO_CR_HRE_HBE_5 7 -#define NV4_CIO_CR_HRE_4_0 0 -#define NV4_CIO_CR_VDT_INDEX 0x6 -#define NV4_CIO_CR_OVL_INDEX 0x7 -#define NV4_CIO_CR_OVL_VDE_8 1 -#define NV4_CIO_CR_OVL_VDE_9 6 -#define NV4_CIO_CR_OVL_VDT_8 0 -#define NV4_CIO_CR_OVL_VDT_9 5 -#define NV4_CIO_CR_OVL_VBS_8 3 -#define NV4_CIO_CR_OVL_VRS_8 2 -#define NV4_CIO_CR_OVL_VRS_9 7 -#define NV4_CIO_CR_RSAL_INDEX 0x8 -#define NV4_CIO_CR_RSAL_PANNING 5 -#define NV4_CIO_CR_CELL_HT_INDEX 0x9 -#define NV4_CIO_CR_CELL_HT_SCANDBL 7 -#define NV4_CIO_CR_CELL_HT_VBS_9 5 -#define NV4_CIO_CR_CURS_ST_INDEX 0xA -#define NV4_CIO_CR_CURS_END_INDEX 0xB -#define NV4_CIO_CR_SA_HI_INDEX 0xC -#define NV4_CIO_CR_SA_LO_INDEX 0xD -#define NV4_CIO_CR_TCOFF_HI_INDEX 0xE -#define NV4_CIO_CR_TCOFF_LO_INDEX 0xF -#define NV4_CIO_CR_VRS_INDEX 0x10 -#define NV4_CIO_CR_VRE_INDEX 0x11 -#define NV4_CIO_CR_VRE_3_0 0 -#define NV4_CIO_CR_VDE_INDEX 0x12 -#define NV4_CIO_CR_OFFSET_INDEX 0x13 -#define NV4_CIO_CR_ULINE_INDEX 0x14 -#define NV4_CIO_CR_VBS_INDEX 0x15 -#define NV4_CIO_CR_VBE_INDEX 0x16 -#define NV4_CIO_CR_MODE_INDEX 0x17 -#define NV4_CIO_CR_LCOMP_INDEX 0x18 -#define NV4_CIO_CR_GDATA_INDEX 0x22 -#define NV4_CIO_CR_ARFF_INDEX 0x24 -#define NV4_CIO_CR_ARX_INDEX 0x26 -#define NV4_CIO_CRE_MONO 0x3b5 -#define NV4_CIO_CRE_COLOR 0x3d5 -#define NV4_CIO_CRE_RPC0_INDEX 0x19 -#define NV4_CIO_CRE_RPC0_START 0 -#define NV4_CIO_CRE_RPC0_OFFSET_10_8 5 -#define NV4_CIO_CRE_RPC1_INDEX 0x1A -#define NV4_CIO_CRE_RPC1_LARGE 2 -#define NV4_CIO_CRE_FF_INDEX 0x1B -#define NV4_CIO_CRE_FF_BURST 0 -#define NV4_CIO_CRE_FF_BURST_8 0x0 -#define NV4_CIO_CRE_FF_BURST_32 0x1 -#define NV4_CIO_CRE_FF_BURST_64 0x2 -#define NV4_CIO_CRE_FF_BURST_128 0x3 -#define NV4_CIO_CRE_FF_BURST_256 0x4 -#define NV4_CIO_CRE_ENH_INDEX 0x1C -#define NV4_CIO_CRE_PAGE0_INDEX 0x1D -#define NV4_CIO_CRE_PAGE1_INDEX 0x1E -#define NV4_CIO_SR_LOCK_INDEX 0x1F -#define NV4_CIO_SR_UNLOCK_RW_VALUE 0x57 -#define NV4_CIO_SR_UNLOCK_RO_VALUE 0x75 -#define NV4_CIO_SR_LOCK_VALUE 0x99 -#define NV4_SR_UNLOCK_RW_VALUE 0x57 -#define NV4_SR_UNLOCK_RO_VALUE 0x75 -#define NV4_SR_LOCK_VALUE 0x99 -#define NV4_CIO_CRE_FFLWM_INDEX 0x20 -#define NV4_CIO_CRE_FFLWM_LWM 0 -#define NV4_CIO_CRE_FABID_INDEX 0x25 -#define NV4_CIO_CRE_LSR_INDEX 0x25 -#define NV4_CIO_CRE_LSR_VDE_10 1 -#define NV4_CIO_CRE_LSR_VDT_10 0 -#define NV4_CIO_CRE_LSR_HBE_6 4 -#define NV4_CIO_CRE_LSR_VBS_10 3 -#define NV4_CIO_CRE_LSR_VRS_10 2 -#define NV4_CIO_CRE_CHIP_ID_INDEX 0x27 -#define NV4_CIO_CRE_PIXEL_INDEX 0x28 -#define NV4_CIO_CRE_PIXEL_TV_ADJ 3 -#define NV4_CIO_CRE_PIXEL_FORMAT 0 -#define NV4_CIO_CRE_PIXEL_FORMAT_VGA 0x0 -#define NV4_CIO_CRE_PIXEL_FORMAT_8BPP 0x1 -#define NV4_CIO_CRE_PIXEL_FORMAT_16BPP 0x2 -#define NV4_CIO_CRE_PIXEL_FORMAT_32BPP 0x3 -#define NV4_CIO_CRE_PAGE_OVFL_INDEX 0x29 -#define NV4_CIO_CRE_OSCOL_INDEX 0x2A -#define NV4_CIO_CRE_SCRATCH0_INDEX 0x2B -#define NV4_CIO_CRE_SCRATCH1_INDEX 0x2C -#define NV4_CIO_CRE_HEB_INDEX 0x2D -#define NV4_CIO_CRE_HEB_SA_23 5 -#define NV4_CIO_CRE_HEB_ILC_8 4 -#define NV4_CIO_CRE_HEB_HRS_8 3 -#define NV4_CIO_CRE_HEB_HBS_8 2 -#define NV4_CIO_CRE_HEB_HDE_8 1 -#define NV4_CIO_CRE_HEB_HDT_8 0 -#define NV4_CIO_CRE_HCUR_ADDR2_INDEX 0x2f -#define NV4_CIO_CRE_HCUR_ADDR0_INDEX 0x30 -#define NV4_CIO_CRE_HCUR_ASI 7 -#define NV4_CIO_CRE_HCUR_ASI_FRAMEBUFFER 0x1 -#define NV4_CIO_CRE_HCUR_ASI_INSTMEM 0x0 -#define NV4_CIO_CRE_HCUR_ADDR0_ADR 0 -#define NV4_CIO_CRE_HCUR_ADDR1_INDEX 0x31 -#define NV4_CIO_CRE_HCUR_ADDR1_ADR 2 -#define NV4_CIO_CRE_HCUR_ADDR1_CUR_DBL 1 -#define NV4_CIO_CRE_HCUR_ADDR1_ENABLE 0 -#define NV4_CIO_CRE_VID_END0_INDEX 0x32 -#define NV4_CIO_CRE_VID_END_7_0 0 -#define NV4_CIO_CRE_VID_END1_INDEX 0x33 -#define NV4_CIO_CRE_VID_END_ENABLE 4 -#define NV4_CIO_CRE_VID_END_10_8 0 -#define NV4_CIO_CRE_RL0_INDEX 0x34 -#define NV4_CIO_CRE_RL1_INDEX 0x35 -#define NV4_CIO_CRE_RMA_INDEX 0x38 -#define NV4_CIO_CRE_ILACE_INDEX 0x39 -#define NV4_CIO_CRE_SCRATCH2_INDEX 0x3A -#define NV4_CIO_CRE_SCRATCH3_INDEX 0x3B -#define NV4_CIO_CRE_SCRATCH4_INDEX 0x3C -#define NV4_CIO_CRE_TREG_INDEX 0x3D -#define NV4_CIO_CRE_TREG_HCNT 6 -#define NV4_CIO_CRE_TREG_VCNT 4 -#define NV4_CIO_CRE_TREG_SHADOW 0 -#define NV4_CIO_CRE_TREG_HCNT_INDEX 0x0 -#define NV4_CIO_CRE_TREG_VCNTA_INDEX 0x6 -#define NV4_CIO_CRE_TREG_VCNTB_INDEX 0x7 -#define NV4_CIO_CRE_DDC_STATUS_INDEX 0x3E -#define NV4_CIO_CRE_DDC_WR_INDEX 0x3F // Write to i2c for EDID/DDC -#define NV4_CIO_CRE_PCI_TO_INDEX 0x40 -#define NV4_CIO_CRE_PCI_TO_DELAY 0 - -#define NV4_VIO_MBEN 0x94 -#define NV4_VIO_ADDEN 0x46e8 -#define NV4_VIO_VSE1 0x102 -#define NV4_VIO_VSE2 0x3c3 -#define NV4_VIO_MISC_READ 0x3cc -#define NV4_VIO_MISC_WRITE 0x3c2 -#define NV4_VIO_SRX 0x3c4 -#define NV4_VIO_SR 0x3c5 -#define NV4_VIO_SR_RESET_INDEX 0x0 -#define NV4_VIO_SR_CLOCK_INDEX 0x1 -#define NV4_VIO_SR_PLANE_MASK_INDEX 0x2 -#define NV4_VIO_SR_CHAR_MAP_INDEX 0x3 -#define NV4_VIO_SR_MEM_MODE_INDEX 0x4 -#define NV4_VIO_GRX 0x3ce -#define NV4_VIO_GX_SR 0x3cf -#define NV4_VIO_GX_SR_INDEX 0x0 -#define NV4_VIO_GX_SREN_INDEX 0x1 -#define NV4_VIO_GX_CCOMP_INDEX 0x2 -#define NV4_VIO_GX_ROP_INDEX 0x3 -#define NV4_VIO_GX_READ_MAP_INDEX 0x4 -#define NV4_VIO_GX_MODE_INDEX 0x5 -#define NV4_VIO_GX_MISC_INDEX 0x6 -#define NV4_VIO_GX_DONT_CARE_INDEX 0x7 -#define NV4_VIO_GX_BIT_MASK_INDEX 0x8 - -#define NV4_PRMVIO_START 0xC0000 -#define NV4_PRMVIO_END 0xC7FFF - -#define NV4_PRMVIO_MBEN 0xC0094 -#define NV4_PRMVIO_ADDEN 0xC46e8 -#define NV4_PRMVIO_VSE1 0xC0102 -#define NV4_PRMVIO_VSE2 0xC03c3 -#define NV4_PRMVIO_MISC_READ 0xC03cc -#define NV4_PRMVIO_MISC_WRITE 0xC03c2 -#define NV4_PRMVIO_SRX 0xC03c4 -#define NV4_PRMVIO_SR_RESET 0xC03c5 -#define NV4_PRMVIO_SR_RESET_INDEX 0x0 -#define NV4_PRMVIO_SR_CLOCK_INDEX 0x1 -#define NV4_PRMVIO_SR_PLANE_MASK_INDEX 0x2 -#define NV4_PRMVIO_SR_CHAR_MAP_INDEX 0x3 -#define NV4_PRMVIO_SR_MEM_MODE_INDEX 0x4 -#define NV4_PRMVIO_GX_SR 0xC03cf -#define NV4_PRMVIO_GX_SR_INDEX 0x0 -#define NV4_PRMVIO_GX_SREN_INDEX 0x1 -#define NV4_PRMVIO_GX_CCOMP_INDEX 0x2 -#define NV4_PRMVIO_GX_ROP_INDEX 0x3 -#define NV4_PRMVIO_GX_READ_MAP_INDEX 0x4 -#define NV4_PRMVIO_GX_MODE_INDEX 0x5 -#define NV4_PRMVIO_GX_MISC_INDEX 0x6 -#define NV4_PRMVIO_GX_MISC_BANKED_128K_A0000 0x00 -#define NV4_PRMVIO_GX_MISC_BANKED_64K_A0000 0x04 -#define NV4_PRMVIO_GX_MISC_BANKED_32K_B0000 0x08 -#define NV4_PRMVIO_GX_MISC_BANKED_32K_B8000 0x0C -#define NV4_PRMVIO_GX_DONT_CARE_INDEX 0x7 -#define NV4_PRMVIO_GX_BIT_MASK_INDEX 0x8 - -#define NV4_PRMVGA 0xA0000 -#define NV4_PRMVGA_END 0xBFFFF - -#define NV4_PME 0x200FFF:0x200000 -#define NV4_PME_DEBUG_0 0x200080 -#define NV4_PME_DEBUG_0_DET_FIELD_SWITCH 0 -#define NV4_PME_DEBUG_0_DET_FIELD_SWITCH_ENABLED 0x1 -#define NV4_PME_DEBUG_0_CAPTURE_00_FF 4 -#define NV4_PME_DEBUG_0_CAPTURE_00_FF_ENABLED 0x1 -#define NV4_PME_DEBUG_1 0x200084 -#define NV4_PME_DEBUG_1_SEL 0 -#define NV4_PME_DEBUG_1_SEL_VIPCLK 0x0 -#define NV4_PME_DEBUG_1_SEL_MCLK 0x1 -#define NV4_PME_DEBUG_1_SEL_GLOB 0x2 -#define NV4_PME_DEBUG_1_VIPCLK_SEL 4 -#define NV4_PME_DEBUG_1_VIPCLK_SEL_DEFAULT 0x0 -#define NV4_PME_DEBUG_1_MCLK_SEL 8 -#define NV4_PME_DEBUG_1_MCLK_SEL_DEFAULT 0x0 -#define NV4_PME_INTR_0 0x200100 -#define NV4_PME_INTR_0_IMAGE_NOTIFY 0 -#define NV4_PME_INTR_0_IMAGE_NOTIFY_NOT_PENDING 0x0 -#define NV4_PME_INTR_0_IMAGE_NOTIFY_PENDING 0x1 -#define NV4_PME_INTR_0_IMAGE_NOTIFY_RESET 0x1 -#define NV4_PME_INTR_0_VBI_NOTIFY 4 -#define NV4_PME_INTR_0_VBI_NOTIFY_NOT_PENDING 0x0 -#define NV4_PME_INTR_0_VBI_NOTIFY_PENDING 0x1 -#define NV4_PME_INTR_0_VBI_NOTIFY_RESET 0x1 -#define NV4_PME_INTR_0_VID_NOTIFY 8 -#define NV4_PME_INTR_0_VID_NOTIFY_NOT_PENDING 0x0 -#define NV4_PME_INTR_0_VID_NOTIFY_PENDING 0x1 -#define NV4_PME_INTR_0_VID_NOTIFY_RESET 0x1 -#define NV4_PME_INTR_0_AUD_NOTIFY 12 -#define NV4_PME_INTR_0_AUD_NOTIFY_NOT_PENDING 0x0 -#define NV4_PME_INTR_0_AUD_NOTIFY_PENDING 0x1 -#define NV4_PME_INTR_0_AUD_NOTIFY_RESET 0x1 -#define NV4_PME_INTR_0_VMI 16 -#define NV4_PME_INTR_0_VMI_NOT_PENDING 0x0 -#define NV4_PME_INTR_0_VMI_PENDING 0x1 -#define NV4_PME_INTR_0_VMI_RESET 0x1 -#define NV4_PME_INTR_EN_0 0x200140 -#define NV4_PME_INTR_EN_0_IMAGE_NOTIFY 0 -#define NV4_PME_INTR_EN_0_IMAGE_NOTIFY_ENABLED 0x1 -#define NV4_PME_INTR_EN_0_VBI_NOTIFY 4 -#define NV4_PME_INTR_EN_0_VBI_NOTIFY_ENABLED 0x1 -#define NV4_PME_INTR_EN_0_VID_NOTIFY 8 -#define NV4_PME_INTR_EN_0_VID_NOTIFY_ENABLED 0x1 -#define NV4_PME_INTR_EN_0_AUD_NOTIFY 12 -#define NV4_PME_INTR_EN_0_AUD_NOTIFY_ENABLED 0x1 -#define NV4_PME_INTR_EN_0_VMI 16 -#define NV4_PME_INTR_EN_0_VMI_ENABLED 0x1 -#define NV4_PME_CONFIG_0 0x200200 -#define NV4_PME_CONFIG_0_BUS_MODE 0 -#define NV4_PME_CONFIG_0_BUS_MODE_DISABLED 0x0 -#define NV4_PME_CONFIG_0_BUS_MODE_VMI 0x1 -#define NV4_PME_CONFIG_0_BUS_MODE_CCIR656 0x2 -#define NV4_PME_CONFIG_0_IMAGE 4 -#define NV4_PME_CONFIG_0_IMAGE_ENABLED 0x1 -#define NV4_PME_CONFIG_0_VBI_MODE 8 -#define NV4_PME_CONFIG_0_VBI_MODE_DISABLED 0x0 -#define NV4_PME_CONFIG_0_VBI_MODE_1 0x1 -#define NV4_PME_CONFIG_0_VBI_MODE_2 0x2 -#define NV4_PME_CONFIG_0_VID_CD 12 -#define NV4_PME_CONFIG_0_VID_CD_ENABLED 0x1 -#define NV4_PME_CONFIG_0_AUD_CD 16 -#define NV4_PME_CONFIG_0_AUD_CD_ENABLED 0x1 -#define NV4_PME_CONFIG_1 0x200204 -#define NV4_PME_CONFIG_1_BUFFS 0 -#define NV4_PME_CONFIG_1_BUFFS_PNVM 0x0 -#define NV4_PME_CONFIG_1_BUFFS_SYS 0x1 -#define NV4_PME_CONFIG_1_HOST 4 -#define NV4_PME_CONFIG_1_HOST_PCI 0x0 -#define NV4_PME_CONFIG_1_HOST_AGP 0x1 -#define NV4_PME_NULL_DATA 0x200208 -#define NV4_PME_NULL_DATA_COMPARE 0 -#define NV4_PME_NULL_DATA_COMPARE_ENABLED 0x1 -#define NV4_PME_NULL_DATA_LINE_DETECT 4 -#define NV4_PME_NULL_DATA_LINE_DETECT_ENABLED 0x1 -#define NV4_PME_NULL_DATA_BYTE 24 -#define NV4_PME_VID_BUFF0_START_SYS 0x200300 -#define NV4_PME_VID_BUFF0_START_SYS_ADDRESS 4 -#define NV4_PME_VID_BUFF1_START_SYS 0x200304 -#define NV4_PME_VID_BUFF1_START_SYS_ADDRESS 4 -#define NV4_PME_VID_BUFF0_START_PNVM 0x200308 -#define NV4_PME_VID_BUFF0_START_PNVM_ADDRESS 4 -#define NV4_PME_VID_BUFF1_START_PNVM 0x20030c -#define NV4_PME_VID_BUFF1_START_PNVM_ADDRESS 4 -#define NV4_PME_VID_BUFF0_LENGTH 0x200310 -#define NV4_PME_VID_BUFF0_LENGTH_BITS 12 -#define NV4_PME_VID_BUFF1_LENGTH 0x200314 -#define NV4_PME_VID_BUFF1_LENGTH_BITS 12 -#define NV4_PME_VID_ME_STATE 0x200318 -#define NV4_PME_VID_ME_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_VID_ME_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_VID_ME_STATE_BUFF0_INTR_CHAINGAP 8 -#define NV4_PME_VID_ME_STATE_BUFF1_INTR_CHAINGAP 12 -#define NV4_PME_VID_ME_STATE_BUFF0_IN_USE 16 -#define NV4_PME_VID_ME_STATE_BUFF1_IN_USE 20 -#define NV4_PME_VID_ME_STATE_CURRENT_BUFFER 24 -#define NV4_PME_VID_ME_STATE_CURRENT_BUFFER_0 0x0 -#define NV4_PME_VID_ME_STATE_CURRENT_BUFFER_1 0x1 -#define NV4_PME_VID_SU_STATE 0x20031c -#define NV4_PME_VID_SU_STATE_BUFF0_IN_USE 16 -#define NV4_PME_VID_SU_STATE_BUFF1_IN_USE 20 -#define NV4_PME_VID_RM_STATE 0x200320 -#define NV4_PME_VID_RM_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_VID_RM_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_VID_RM_STATE_BUFF0_INTR_CHAINGAP 8 -#define NV4_PME_VID_RM_STATE_BUFF1_INTR_CHAINGAP 12 -#define NV4_PME_VID_CURRENT 0x200324 -#define NV4_PME_VID_CURRENT_POS 2 -#define NV4_PME_AUD_BUFF0_START_SYS 0x200340 -#define NV4_PME_AUD_BUFF0_START_SYS_ADDRESS 4 -#define NV4_PME_AUD_BUFF1_START_SYS 0x200344 -#define NV4_PME_AUD_BUFF1_START_SYS_ADDRESS 4 -#define NV4_PME_AUD_BUFF0_START_PNVM 0x200348 -#define NV4_PME_AUD_BUFF0_START_PNVM_ADDRESS 4 -#define NV4_PME_AUD_BUFF1_START_PNVM 0x20034c -#define NV4_PME_AUD_BUFF1_START_PNVM_ADDRESS 4 -#define NV4_PME_AUD_BUFF0_LENGTH 0x200350 -#define NV4_PME_AUD_BUFF0_LENGTH_BITS 10 -#define NV4_PME_AUD_BUFF1_LENGTH 0x200354 -#define NV4_PME_AUD_BUFF1_LENGTH_BITS 10 -#define NV4_PME_AUD_ME_STATE 0x200358 -#define NV4_PME_AUD_ME_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_AUD_ME_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_AUD_ME_STATE_BUFF0_INTR_CHAINGAP 8 -#define NV4_PME_AUD_ME_STATE_BUFF1_INTR_CHAINGAP 12 -#define NV4_PME_AUD_ME_STATE_BUFF0_IN_USE 16 -#define NV4_PME_AUD_ME_STATE_BUFF1_IN_USE 20 -#define NV4_PME_AUD_ME_STATE_CURRENT_BUFFER 24 -#define NV4_PME_AUD_ME_STATE_CURRENT_BUFFER_0 0x0 -#define NV4_PME_AUD_ME_STATE_CURRENT_BUFFER_1 0x1 -#define NV4_PME_AUD_SU_STATE 0x20035c -#define NV4_PME_AUD_SU_STATE_BUFF0_IN_USE 16 -#define NV4_PME_AUD_SU_STATE_BUFF1_IN_USE 20 -#define NV4_PME_AUD_RM_STATE 0x200360 -#define NV4_PME_AUD_RM_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_AUD_RM_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_AUD_RM_STATE_BUFF0_INTR_CHAINGAP 8 -#define NV4_PME_AUD_RM_STATE_BUFF1_INTR_CHAINGAP 12 -#define NV4_PME_AUD_CURRENT 0x200364 -#define NV4_PME_AUD_CURRENT_POS 2 -#define NV4_PME_VBI_BUFF0_START 0x200380 -#define NV4_PME_VBI_BUFF0_START_ADDRESS 4 -#define NV4_PME_VBI_BUFF1_START 0x200384 -#define NV4_PME_VBI_BUFF1_START_ADDRESS 4 -#define NV4_PME_VBI_BUFF0_PITCH 0x200388 -#define NV4_PME_VBI_BUFF0_PITCH_VALUE 4 -#define NV4_PME_VBI_BUFF1_PITCH 0x20038c -#define NV4_PME_VBI_BUFF1_PITCH_VALUE 4 -#define NV4_PME_VBI_BUFF0_LENGTH 0x200390 -#define NV4_PME_VBI_BUFF0_LENGTH_BITS 4 -#define NV4_PME_VBI_BUFF1_LENGTH 0x200394 -#define NV4_PME_VBI_BUFF1_LENGTH_BITS 4 -#define NV4_PME_VBI_ME_STATE 0x200398 -#define NV4_PME_VBI_ME_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_VBI_ME_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_VBI_ME_STATE_BUFF0_ERROR_CODE 8 -#define NV4_PME_VBI_ME_STATE_BUFF1_ERROR_CODE 12 -#define NV4_PME_VBI_ME_STATE_BUFF0_IN_USE 16 -#define NV4_PME_VBI_ME_STATE_BUFF1_IN_USE 20 -#define NV4_PME_VBI_ME_STATE_CURRENT_BUFFER 24 -#define NV4_PME_VBI_ME_STATE_CURRENT_BUFFER_0 0x0 -#define NV4_PME_VBI_ME_STATE_CURRENT_BUFFER_1 0x1 -#define NV4_PME_VBI_SU_STATE 0x20039c -#define NV4_PME_VBI_SU_STATE_BUFF0_FIELD 8 -#define NV4_PME_VBI_SU_STATE_BUFF1_FIELD 12 -#define NV4_PME_VBI_SU_STATE_BUFF0_IN_USE 16 -#define NV4_PME_VBI_SU_STATE_BUFF1_IN_USE 20 -#define NV4_PME_VBI_RM_STATE 0x2003a0 -#define NV4_PME_VBI_RM_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_VBI_RM_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_VBI 0x2003a4 -#define NV4_PME_VBI_START_LINE 0 -#define NV4_PME_VBI_NUM_LINES 16 -#define NV4_PME_IMAGE_BUFF0_START 0x200400 -#define NV4_PME_IMAGE_BUFF0_START_ADDRESS 4 -#define NV4_PME_IMAGE_BUFF1_START 0x200404 -#define NV4_PME_IMAGE_BUFF1_START_ADDRESS 4 -#define NV4_PME_IMAGE_BUFF0_PITCH 0x200408 -#define NV4_PME_IMAGE_BUFF0_PITCH_VALUE 4 -#define NV4_PME_IMAGE_BUFF1_PITCH 0x20040c -#define NV4_PME_IMAGE_BUFF1_PITCH_VALUE 4 -#define NV4_PME_IMAGE_BUFF0_LENGTH 0x200410 -#define NV4_PME_IMAGE_BUFF0_LENGTH_BITS 4 -#define NV4_PME_IMAGE_BUFF1_LENGTH 0x200414 -#define NV4_PME_IMAGE_BUFF1_LENGTH_BITS 4 -#define NV4_PME_IMAGE_ME_STATE 0x200418 -#define NV4_PME_IMAGE_ME_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_IMAGE_ME_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_IMAGE_ME_STATE_BUFF0_ERROR_CODE 8 -#define NV4_PME_IMAGE_ME_STATE_BUFF1_ERROR_CODE 12 -#define NV4_PME_IMAGE_ME_STATE_BUFF0_IN_USE 16 -#define NV4_PME_IMAGE_ME_STATE_BUFF1_IN_USE 20 -#define NV4_PME_IMAGE_ME_STATE_CURRENT_BUFFER 24 -#define NV4_PME_IMAGE_ME_STATE_CURRENT_BUFFER_0 0x0 -#define NV4_PME_IMAGE_ME_STATE_CURRENT_BUFFER_1 0x1 -#define NV4_PME_IMAGE_SU_STATE 0x20041c -#define NV4_PME_IMAGE_SU_STATE_BUFF0_FIELD 8 -#define NV4_PME_IMAGE_SU_STATE_BUFF1_FIELD 12 -#define NV4_PME_IMAGE_SU_STATE_BUFF0_IN_USE 16 -#define NV4_PME_IMAGE_SU_STATE_BUFF1_IN_USE 20 -#define NV4_PME_IMAGE_RM_STATE 0x200420 -#define NV4_PME_IMAGE_RM_STATE_BUFF0_INTR_NOTIFY 0 -#define NV4_PME_IMAGE_RM_STATE_BUFF1_INTR_NOTIFY 4 -#define NV4_PME_IMAGE_BUFF0_SCALE_INCR 0x200424 -#define NV4_PME_IMAGE_BUFF0_SCALE_INCR_Y 16 -#define NV4_PME_IMAGE_BUFF0_SCALE_INCR_X 0 -#define NV4_PME_IMAGE_BUFF1_SCALE_INCR 0x200428 -#define NV4_PME_IMAGE_BUFF1_SCALE_INCR_Y 16 -#define NV4_PME_IMAGE_BUFF1_SCALE_INCR_X 0 -#define NV4_PME_IMAGE_Y_CROP 0x20042c -#define NV4_PME_IMAGE_Y_CROP_STARTLINE 0 -#define NV4_PME_FIFO_LINE_START 0x200480 -#define NV4_PME_FIFO_LINE_START_ADDRESS 4 -#define NV4_PME_FIFO_CURRENT 0x200484 -#define NV4_PME_FIFO_CURRENT_ADDRESS 2 -#define NV4_PME_VMI_POLL 0x200488 -#define NV4_PME_VMI_POLL_UNCD 0 -#define NV4_PME_VMI_POLL_UNCD_NOT_PENDING 0x0 -#define NV4_PME_VMI_POLL_UNCD_PENDING 0x1 -#define NV4_PME_VMI_POLL_VIDCD 1 -#define NV4_PME_VMI_POLL_VIDCD_NOT_PENDING 0x0 -#define NV4_PME_VMI_POLL_VIDCD_PENDING 0x1 -#define NV4_PME_VMI_POLL_AUDCD 2 -#define NV4_PME_VMI_POLL_AUDCD_NOT_PENDING 0x0 -#define NV4_PME_VMI_POLL_AUDCD_PENDING 0x1 -#define NV4_PME_VMI_POLL_INT 3 -#define NV4_PME_VMI_POLL_INT_NOT_PENDING 0x0 -#define NV4_PME_VMI_POLL_INT_PENDING 0x1 -#define NV4_PME_VMI_POLL_CPURDREC 4 -#define NV4_PME_VMI_POLL_CPURDREC_NOT_PENDING 0x0 -#define NV4_PME_VMI_POLL_CPURDREC_PENDING 0x1 -#define NV4_PME_EXTERNAL(i) (0x200600+(i)*4) -#define NV4_PME_EXTERNAL_SIZE_1 256 -#define NV4_PME_EXTERNAL_DATA 0 - -#define NV4_PFB_START 0x100000 -#define NV4_PFB_END 0x100FFF - -#define NV4_PFB_BOOT_0 0x100000 -#define NV4_PFB_BOOT_0_RAM_AMOUNT 0 -#define NV4_PFB_BOOT_0_RAM_AMOUNT_2MB 0x0 -#define NV4_PFB_BOOT_0_RAM_AMOUNT_4MB 0x1 -#define NV4_PFB_BOOT_0_RAM_AMOUNT_8MB 0x2 -#define NV4_PFB_BOOT_0_RAM_AMOUNT_16MB 0x3 -#define NV4_PFB_BOOT_0_RAM_WIDTH_128 2 -#define NV4_PFB_BOOT_0_RAM_WIDTH_128_OFF 0x0 -#define NV4_PFB_BOOT_0_RAM_WIDTH_128_ON 0x1 -#define NV4_PFB_BOOT_0_RAM_TYPE 3 -#define NV4_PFB_BOOT_0_RAM_TYPE_256K 0x0 -#define NV4_PFB_BOOT_0_RAM_TYPE_512K_2BANK 0x1 -#define NV4_PFB_BOOT_0_RAM_TYPE_512K_4BANK 0x2 -#define NV4_PFB_BOOT_0_RAM_TYPE_1024K_2BANK 0x3 -#define NV4_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT 0x0 -#define NV4_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT 0x1 -#define NV4_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK 0x2 -#define NV4_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT 0x3 -#define NV4_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT 0x4 -#define NV4_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16 0x5 -#define NV4_PFB_BOOT_0_UMA 8 -#define NV4_PFB_BOOT_0_UMA_DISABLE 0x0 -#define NV4_PFB_BOOT_0_UMA_ENABLE 0x1 -#define NV4_PFB_BOOT_0_UMA_SIZE 12 -#define NV4_PFB_BOOT_0_UMA_SIZE_DEFAULT 0x7 -#define NV4_PFB_BOOT_0_UMA_SIZE_2M 0x0 -#define NV4_PFB_BOOT_0_UMA_SIZE_4M 0x1 -#define NV4_PFB_BOOT_0_UMA_SIZE_6M 0x2 -#define NV4_PFB_BOOT_0_UMA_SIZE_8M 0x3 -#define NV4_PFB_BOOT_0_UMA_SIZE_10M 0x4 -#define NV4_PFB_BOOT_0_UMA_SIZE_12M 0x5 -#define NV4_PFB_BOOT_0_UMA_SIZE_14M 0x6 -#define NV4_PFB_BOOT_0_UMA_SIZE_16M 0x7 -#define NV4_PFB_BOOT_0_UMA_SIZE_18M 0x8 -#define NV4_PFB_BOOT_0_UMA_SIZE_20M 0x9 -#define NV4_PFB_BOOT_0_UMA_SIZE_22M 0xA -#define NV4_PFB_BOOT_0_UMA_SIZE_24M 0xB -#define NV4_PFB_BOOT_0_UMA_SIZE_26M 0xC -#define NV4_PFB_BOOT_0_UMA_SIZE_28M 0xD -#define NV4_PFB_BOOT_0_UMA_SIZE_30M 0xE -#define NV4_PFB_BOOT_0_UMA_SIZE_32M 0xF -#define NV4_PFB_DEBUG_0 0x100080 -#define NV4_PFB_DEBUG_0_PAGE_MODE 0 -#define NV4_PFB_DEBUG_0_PAGE_MODE_ENABLED 0x0 -#define NV4_PFB_DEBUG_0_PAGE_MODE_DISABLED 0x1 -#define NV4_PFB_DEBUG_0_REFRESH 4 -#define NV4_PFB_DEBUG_0_REFRESH_ENABLED 0x0 -#define NV4_PFB_DEBUG_0_REFRESH_DISABLED 0x1 -#define NV4_PFB_DEBUG_0_REFRESH_COUNTX64 8 -#define NV4_PFB_DEBUG_0_REFRESH_COUNTX64_DEFAULT 0x10 -#define NV4_PFB_DEBUG_0_REFRESH_SLOW_CLK 14 -#define NV4_PFB_DEBUG_0_REFRESH_SLOW_CLK_ENABLED 0x1 -#define NV4_PFB_DEBUG_0_CASOE 20 -#define NV4_PFB_DEBUG_0_CASOE_ENABLED 0x0 -#define NV4_PFB_DEBUG_0_CASOE_DISABLED 0x1 -#define NV4_PFB_DEBUG_0_CKE_INVERT 28 -#define NV4_PFB_DEBUG_0_CKE_INVERT_OFF 0x0 -#define NV4_PFB_DEBUG_0_CKE_INVERT_ON 0x1 -#define NV4_PFB_DEBUG_0_REFINC 29 -#define NV4_PFB_DEBUG_0_REFINC_DISABLED 0x0 -#define NV4_PFB_DEBUG_0_REFINC_ENABLED 0x1 -#define NV4_PFB_DEBUG_0_SAVE_POWER 30 -#define NV4_PFB_DEBUG_0_SAVE_POWER_ON 0x0 -#define NV4_PFB_DEBUG_0_SAVE_POWER_OFF 0x1 -#define NV4_PFB_GREEN_0 0x1000C0 -#define NV4_PFB_GREEN_0_LEVEL 0 -#define NV4_PFB_GREEN_0_LEVEL_VIDEO_ENABLED 0x0 -#define NV4_PFB_GREEN_0_LEVEL_VIDEO_DISABLED 0x1 -#define NV4_PFB_GREEN_0_LEVEL_TIMING_DISABLED 0x2 -#define NV4_PFB_GREEN_0_LEVEL_MEMORY_DISABLED 0x3 -#define NV4_PFB_CONFIG_0 0x100200 -#define NV4_PFB_CONFIG_0_TYPE 0 -#define NV4_PFB_CONFIG_0_TYPE_OLD1024_FIXED_8BPP 0x120 -#define NV4_PFB_CONFIG_0_TYPE_OLD1024_FIXED_16BPP 0x220 -#define NV4_PFB_CONFIG_0_TYPE_OLD1024_FIXED_32BPP 0x320 -#define NV4_PFB_CONFIG_0_TYPE_OLD1024_VAR_8BPP 0x4120 -#define NV4_PFB_CONFIG_0_TYPE_OLD1024_VAR_16BPP 0x4220 -#define NV4_PFB_CONFIG_0_TYPE_OLD1024_VAR_32BPP 0x4320 -#define NV4_PFB_CONFIG_0_TYPE_TETRIS 0x2000 -#define NV4_PFB_CONFIG_0_TYPE_NOTILING 0x1114 -#define NV4_PFB_CONFIG_0_TETRIS_MODE 15 -// 18:15 = tetris mode # -#define NV4_PFB_CONFIG_0_TETRIS_MODE_PASS 0x0 -// 18 = shift # -#define NV4_PFB_CONFIG_0_TETRIS_SHIFT 18 -#define NV4_PFB_CONFIG_0_BANK_SWAP 20 -#define NV4_PFB_CONFIG_0_BANK_SWAP_OFF 0x0 -#define NV4_PFB_CONFIG_0_BANK_SWAP_1M 0x1 -#define NV4_PFB_CONFIG_0_BANK_SWAP_2M 0x5 -#define NV4_PFB_CONFIG_0_BANK_SWAP_4M 0x7 -#define NV4_PFB_CONFIG_0_UNUSED 23 -#define NV4_PFB_CONFIG_0_SCRAMBLE_EN 29 -#define NV4_PFB_CONFIG_0_SCRAMBLE_EN_INIT 0x0 -#define NV4_PFB_CONFIG_0_SCRAMBLE_ACTIVE 0x1 -#define NV4_PFB_CONFIG_0_PRAMIN_WR 28 -#define NV4_PFB_CONFIG_0_PRAMIN_WR_INIT 0x0 -#define NV4_PFB_CONFIG_0_PRAMIN_WR_DISABLED 0x1 -#define NV4_PFB_CONFIG_0_PRAMIN_WR_MASK 24 -#define NV4_PFB_CONFIG_0_PRAMIN_WR_MASK_INIT 0x0 -#define NV4_PFB_CONFIG_0_PRAMIN_WR_MASK_CLEAR 0xF -#define NV4_PFB_CONFIG_1 0x100204 -#define NV4_PFB_CONFIG_1_CAS_LATENCY 0 -#define NV4_PFB_CONFIG_1_CAS_LATENCY_3 0x3 -#define NV4_PFB_CONFIG_1_CAS_LATENCY_2 0x2 -#define NV4_PFB_CONFIG_1_CAS_LATENCY_4 0x4 -#define NV4_PFB_CONFIG_1_RAS_RAS 4 -#define NV4_PFB_CONFIG_1_RAS_RAS_DEFAULT 0x9 -#define NV4_PFB_CONFIG_1_RAS_RAS_9CYCLES 0x8 -#define NV4_PFB_CONFIG_1_RAS_RAS_8CYCLES 0x7 -#define NV4_PFB_CONFIG_1_RAS_RAS_7CYCLES 0x6 -#define NV4_PFB_CONFIG_1_RAS_PCHG 8 -#define NV4_PFB_CONFIG_1_RAS_PCHG_DEFAULT 0x2 -#define NV4_PFB_CONFIG_1_RAS_PCHG_2CYCLES 0x1 -#define NV4_PFB_CONFIG_1_RAS_LOW 12 -#define NV4_PFB_CONFIG_1_RAS_LOW_DEFAULT 0x6 -#define NV4_PFB_CONFIG_1_RAS_LOW_7CYCLES 0x7 -#define NV4_PFB_CONFIG_1_RAS_LOW_5CYCLES 0x5 -#define NV4_PFB_CONFIG_1_RAS_LOW_4CYCLES 0x4 -#define NV4_PFB_CONFIG_1_MRS_TO_RAS 16 -#define NV4_PFB_CONFIG_1_MRS_TO_RAS_DEFAULT 0x1 -#define NV4_PFB_CONFIG_1_MRS_TO_RAS_2CYCLES 0x2 -#define NV4_PFB_CONFIG_1_MRS_TO_RAS_0CYCLES 0x0 -#define NV4_PFB_CONFIG_1_WRITE_TO_READ 20 -#define NV4_PFB_CONFIG_1_WRITE_TO_READ_DEFAULT 0x0 -#define NV4_PFB_CONFIG_1_RAS_TO_CAS_M1 24 -#define NV4_PFB_CONFIG_1_RAS_TO_CAS_M1_DEFAULT 0x1 -#define NV4_PFB_CONFIG_1_RAS_TO_CAS_M1_2CYCLES 0x2 -#define NV4_PFB_CONFIG_1_RAS_TO_CAS_M1_0CYCLES 0x0 -#define NV4_PFB_CONFIG_1_READ_TO_WRITE 28 -#define NV4_PFB_CONFIG_1_READ_TO_WRITE_DEFAULT 0x4 -#define NV4_PFB_CONFIG_1_READ_TO_WRITE_5CYCLES 0x5 -#define NV4_PFB_CONFIG_1_READ_TO_WRITE_3CYCLES 0x3 -#define NV4_PFB_CONFIG_1_READ_TO_WRITE_2CYCLES 0x2 -#define NV4_PFB_CONFIG_1_READ_TO_PCHG 31 -#define NV4_PFB_CONFIG_1_READ_TO_PCHG_ON 0x1 -#define NV4_PFB_CONFIG_1_READ_TO_PCHG_OFF 0x0 -#define NV4_PFB_RTL 0x100300 -#define NV4_PFB_RTL_H 0 -#define NV4_PFB_RTL_H_DEFAULT 0x0 -#define NV4_PFB_RTL_MC 1 -#define NV4_PFB_RTL_MC_DEFAULT 0x0 -#define NV4_PFB_RTL_V 2 -#define NV4_PFB_RTL_V_DEFAULT 0x0 -#define NV4_PFB_RTL_G 3 -#define NV4_PFB_RTL_G_DEFAULT 0x0 -#define NV4_PFB_RTL_GB 4 -#define NV4_PFB_RTL_GB_DEFAULT 0x0 -#define NV4_PFB_SCRAMBLE(i) (0x100400+((i)*4)) -#define NV4_PFB_SCRAMBLE_SIZE_1 8 -#define NV4_PFB_SCRAMBLE_w0 0 -#define NV4_PFB_SCRAMBLE_w1 8 -#define NV4_PFB_SCRAMBLE_w2 16 -#define NV4_PFB_SCRAMBLE_w3 24 -#define NV4_PFB_SCRAMBLE_EN 0x100420 -#define NV4_PFB_SCRAMBLE_VALUE_0 0x03020100 -#define NV4_PFB_SCRAMBLE_VALUE_1 0x07060504 -#define NV4_PFB_SCRAMBLE_VALUE_2 0x0b0a0908 -#define NV4_PFB_SCRAMBLE_VALUE_3 0x0f0e0d0c -#define NV4_PFB_SCRAMBLE_VALUE_4 0x13121110 -#define NV4_PFB_SCRAMBLE_VALUE_5 0x17161514 -#define NV4_PFB_SCRAMBLE_VALUE_6 0x1b1a1918 -#define NV4_PFB_SCRAMBLE_VALUE_7 0x1f1e1d1c -#define NV4_PFB_CONFIG_0_RESOLUTION 0 -#define NV4_PFB_CONFIG_0_RESOLUTION_320_PIXELS 0xA -#define NV4_PFB_CONFIG_0_RESOLUTION_400_PIXELS 0xD -#define NV4_PFB_CONFIG_0_RESOLUTION_480_PIXELS 0xF -#define NV4_PFB_CONFIG_0_RESOLUTION_512_PIXELS 0x10 -#define NV4_PFB_CONFIG_0_RESOLUTION_640_PIXELS 0x14 -#define NV4_PFB_CONFIG_0_RESOLUTION_800_PIXELS 0x19 -#define NV4_PFB_CONFIG_0_RESOLUTION_960_PIXELS 0x1e -#define NV4_PFB_CONFIG_0_RESOLUTION_1024_PIXELS 0x20 -#define NV4_PFB_CONFIG_0_RESOLUTION_1152_PIXELS 0x24 -#define NV4_PFB_CONFIG_0_RESOLUTION_1280_PIXELS 0x28 -#define NV4_PFB_CONFIG_0_RESOLUTION_1600_PIXELS 0x32 -#define NV4_PFB_CONFIG_0_RESOLUTION_DEFAULT 0x14 -#define NV4_PFB_CONFIG_0_PIXEL_DEPTH 8 -#define NV4_PFB_CONFIG_0_PIXEL_DEPTH_8_BITS 0x1 -#define NV4_PFB_CONFIG_0_PIXEL_DEPTH_16_BITS 0x2 -#define NV4_PFB_CONFIG_0_PIXEL_DEPTH_32_BITS 0x3 -#define NV4_PFB_CONFIG_0_PIXEL_DEPTH_DEFAULT 0x1 -#define NV4_PFB_CONFIG_0_TILING 12 -#define NV4_PFB_CONFIG_0_TILING_ENABLED 0x0 -#define NV4_PFB_CONFIG_0_TILING_DISABLED 0x1 -#define NV4_PFB_CONFIG_0_TILING_DEBUG 13 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_DISABLED 0x0 -#define NV4_PFB_CONFIG_0_TILE 12 -#define NV4_PFB_CONFIG_0_TILE_OLD1024_FIXED 0x0 -#define NV4_PFB_CONFIG_0_TILE_OLD1024_VARIABLE 0x4 -#define NV4_PFB_CONFIG_0_TILE_TETRIS_ALLOW 0x1 -#define NV4_PFB_CONFIG_0_TILE_TETRIS_REDUNDANT 0x2 -#define NV4_PFB_CONFIG_0_TILE_TETRIS_REDUNDANT2 0x3 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_ON 13 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_ON_ENABLED 0x0 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_ON_DISABLED 0x1 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_TILESIZE 14 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_TILESIZE_FIXED 0x0 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_TILESIZE_VARIABLE 0x1 -// tetris mode # = 17:15 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_TETRIS_MODE 15 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_TETRIS_MODE_PASS 0x0 -// tetris shift # = 18 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_TETRIS_SHIFT 18 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_BANK_SWAP 20 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_BANK_SWAP_OFF 0x0 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_BANK_SWAP_ON 0x1 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_BANK_SWAP_MSB 21 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_BANK_SWAP_MSB_1M 0x0 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_BANK_SWAP_MSB_2M 0x2 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_BANK_SWAP_MSB_4M 0x3 -#define NV4_PFB_CONFIG_0_TILING_DEBUG_UNUSED 23 -#define NV4_PFB_CONFIG_1_SGRAM100 3 -#define NV4_PFB_CONFIG_1_SGRAM100_ENABLED 0x0 -#define NV4_PFB_CONFIG_1_SGRAM100_DISABLED 0x1 -#define NV4_PFB_DEBUG_0_CKE_ALWAYSON 29 -#define NV4_PFB_DEBUG_0_CKE_ALWAYSON_OFF 0x0 -#define NV4_PFB_DEBUG_0_CKE_ALWAYSON_ON 0x1 - -// WARNING! WARNING! WARNING! -// STB V4400 has shown PROM at 0x700000 instead of 0x300000 (errata), clashing with first 0x10000 of instance memory -// Nvidia never ran into this issue because they never used that area -// But this part may not work -#define NV4_PRAMIN_START 0x700000 -#define NV4_PRAMIN_END 0x7FFFFF -#define NV4_PRAMIN_SIZE 0xFFFFF - -#define NV4_PRAMIN_CONTEXT_0 ( 0*32+31):( 0*32+ 0) -#define NV4_PRAMIN_CONTEXT_1 ( 1*32+31):( 1*32+ 0) -#define NV4_PRAMIN_CONTEXT_2 ( 2*32+31):( 2*32+ 0) -#define NV4_PRAMIN_CONTEXT_3 ( 3*32+31):( 3*32+ 0) -#define NV4_PRAMIN_RAMHT_START 0x710000 -#define NV4_PRAMIN_RAMHT_END 0x710FFF -#define NV4_PRAMIN_RAMFC_START 0x711000 -#define NV4_PRAMIN_RAMFC_END 0x7111FF -#define NV4_PRAMIN_RAMRO_START 0x711200 -#define NV4_PRAMIN_RAMRO_END 0x7113FF -#define NV4_PRAMIN_CTX_0(i) (0x700000 + (i)*16) -// This is the same format as PGRAPH_CTX_SWITCH -#define NV4_PRAMIN_CTX_0_SIZE_1 0x10000 -#define NV4_PRAMIN_CTX_0_NVCLASS 0 -#define NV4_PRAMIN_CTX_0_CHROMA_KEY 12 -#define NV4_PRAMIN_CTX_0_CHROMA_KEY_ENABLE 0x1 -#define NV4_PRAMIN_CTX_0_USER_CLIP 13 -#define NV4_PRAMIN_CTX_0_USER_CLIP_ENABLE 0x1 -#define NV4_PRAMIN_CTX_0_SWIZZLE 14 -#define NV4_PRAMIN_CTX_0_SWIZZLE_ENABLE 0x1 -#define NV4_PRAMIN_CTX_0_PATCH_CONFIG 17:15 -#define NV4_PRAMIN_CTX_0_PATCH_CONFIG_SRCCOPY_AND 0x0 -#define NV4_PRAMIN_CTX_0_PATCH_CONFIG_ROP_AND 0x1 -#define NV4_PRAMIN_CTX_0_PATCH_CONFIG_BLEND_AND 0x2 -#define NV4_PRAMIN_CTX_0_PATCH_CONFIG_SRCCOPY 0x3 -#define NV4_PRAMIN_CTX_0_PATCH_CONFIG_SRCCOPY_PRE 0x4 -#define NV4_PRAMIN_CTX_0_PATCH_CONFIG_BLEND_PRE 0x5 -#define NV4_PRAMIN_CTX_0_PATCH_STATUS 24 -#define NV4_PRAMIN_CTX_0_PATCH_STATUS_INVALID 0x0 -#define NV4_PRAMIN_CTX_0_PATCH_STATUS_VALID 0x1 -#define NV4_PRAMIN_CTX_0_CONTEXT_SURFACE 25 -#define NV4_PRAMIN_CTX_0_CONTEXT_SURFACE_INVALID 0x0 -#define NV4_PRAMIN_CTX_0_CONTEXT_SURFACE_VALID 0x1 -#define NV4_PRAMIN_CTX_1(i) (0x700004 + (i)*16) -#define NV4_PRAMIN_CTX_1_SIZE_1 0x10000 -#define NV4_PRAMIN_CTX_1_MONO_FORMAT 0 -#define NV4_PRAMIN_CTX_1_MONO_FORMAT_INVALID 0x00 -#define NV4_PRAMIN_CTX_1_MONO_FORMAT_CGA6_M1 0x01 -#define NV4_PRAMIN_CTX_1_MONO_FORMAT_LE_M1 0x02 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT 8 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_INVALID 0x00 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_Y8 0x01 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X16A8Y8 0x02 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X24Y8 0x03 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_A1R5G5B5 0x06 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X1R5G5B5 0x07 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X16A1R5G5B5 0x08 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X17R5G5B5 0x09 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_R5G6B5 0x0A -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_A16R5G6B5 0x0B -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X16R5G6B5 0x0C -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_A8R8G8B8 0x0D -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X8R8G8B8 0x0E -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_Y16 0x0F -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_A16Y16 0x10 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_X16Y16 0x11 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_V8YB8U8YA8 0x12 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_YB8V8YA8U8 0x13 -#define NV4_PRAMIN_CTX_1_COLOR_FORMAT_LE_Y32 0x14 -#define NV4_PRAMIN_CTX_1_NOTIFY_INSTANCE 16 -#define NV4_PRAMIN_CTX_1_NOTIFY_INSTANCE_INVALID 0x00 -#define NV4_PRAMIN_CTX_2(i) (0x700008 + (i)*16) -#define NV4_PRAMIN_CTX_2_SIZE_1 0x10000 -#define NV4_PRAMIN_CTX_2_DMA_0_INSTANCE 0 -#define NV4_PRAMIN_CTX_2_DMA_0_INSTANCE_INVALID 0x00 -#define NV4_PRAMIN_CTX_2_DMA_1_INSTANCE 16 -#define NV4_PRAMIN_CTX_2_DMA_1_INSTANCE_INVALID 0x00 - -#define NV4_FIFO_DMA_OPCODE ( 0*32+31):( 0*32+29) -#define NV4_FIFO_DMA_OPCODE_METHOD 0x0 -#define NV4_FIFO_DMA_OPCODE_JUMP 0x1 -#define NV4_FIFO_DMA_METHOD_COUNT ( 0*32+28):( 0*32+18) -#define NV4_FIFO_DMA_METHOD_SUBCHANNEL ( 0*32+15):( 0*32+13) -#define NV4_FIFO_DMA_METHOD_ADDRESS ( 0*32+12):( 0*32+ 2) -#define NV4_FIFO_DMA_DATA ( 1*32+31):( 1*32+ 0) -#define NV4_FIFO_DMA_JUMP_OFFSET 2 - -// DFB is in BAR1. Access it as VRAM - -#define NV4_PEXTDEV_BOOT_0 0x101000 -#define NV4_STRAP_BUS_SPEED 0 -#define NV4_STRAP_BUS_SPEED_33MHZ 0x0 -#define NV4_STRAP_BUS_SPEED_66MHZ 0x1 -#define NV4_STRAP_SUB_VENDOR 1 -#define NV4_STRAP_SUB_VENDOR_NO_BIOS 0x0 -#define NV4_STRAP_SUB_VENDOR_BIOS 0x1 -#define NV4_STRAP_RAM_TYPE 2 -#define NV4_STRAP_RAM_TYPE_SGRAM_256K 0x0 -#define NV4_STRAP_RAM_TYPE_SGRAM_512K_2BANK 0x1 -#define NV4_STRAP_RAM_TYPE_SGRAM_512K_4BANK 0x2 -#define NV4_STRAP_RAM_TYPE_1024K_2BANK 0x3 -#define NV4_STRAP_RAM_WIDTH 4 -#define NV4_STRAP_RAM_WIDTH_64 0x0 -#define NV4_STRAP_RAM_WIDTH_128 0x1 -#define NV4_STRAP_BUS_TYPE 5 -#define NV4_STRAP_BUS_TYPE_PCI 0x0 -#define NV4_STRAP_BUS_TYPE_AGP 0x1 -#define NV4_STRAP_CRYSTAL 6 -#define NV4_STRAP_CRYSTAL_13500K 0x0 -#define NV4_STRAP_CRYSTAL_14318180 0x1 -#define NV4_STRAP_TVMODE 7 -#define NV4_STRAP_TVMODE_SECAM 0x0 -#define NV4_STRAP_TVMODE_NTSC 0x1 -#define NV4_STRAP_TVMODE_PAL 0x2 -#define NV4_STRAP_TVMODE_DISABLED 0x3 -#define NV4_STRAP_OVERWRITE 11 -#define NV4_STRAP_OVERWRITE_DISABLED 0x0 -#define NV4_STRAP_OVERWRITE_ENABLED 0x1 - -#define NV4_PDAC_START 0x680000 -#define NV4_PDAC_END 0x680FFF - -#define NV4_PDAC_DATA(i) (0x680000+(i)*4) -#define NV4_PDAC_DATA_SIZE_1 16 -#define NV4_PDAC_DATA_VALUE 0 - -// WARNING! -// This has shown up at 0x700000 on real NV4 -#define NV4_PROM_START 0x300000 -#define NV4_PROM_END 0x30FFFF -#define NV4_PROM_DATA(i) (NV4_PROM_START+(i)) -#define NV4_PROM_SIZE 65536 - -#define NV4_PROM_ERRATA_START 0x700000 -#define NV4_PROM_ERRATA_END 0x70FFFF -#define NV4_PROM_ERRATA_DATA(i) (NV4_PROM_ERRATA_START+(i)) - -#define NV4_PRM 0x5FFF:0x4000 -#define NV4_PRM_INTR_0 0x4100 -#define NV4_PRM_INTR_0_TRACE_MPU401 0 -#define NV4_PRM_INTR_0_TRACE_MPU401_NOT_PENDING 0x0 -#define NV4_PRM_INTR_0_TRACE_MPU401_PENDING 0x1 -#define NV4_PRM_INTR_0_TRACE_MPU401_RESET 0x1 -#define NV4_PRM_INTR_0_TRACE_FM 4 -#define NV4_PRM_INTR_0_TRACE_FM_NOT_PENDING 0x0 -#define NV4_PRM_INTR_0_TRACE_FM_PENDING 0x1 -#define NV4_PRM_INTR_0_TRACE_FM_RESET 0x1 -#define NV4_PRM_INTR_0_TRACE_SB_DIGITAL 8 -#define NV4_PRM_INTR_0_TRACE_SB_DIGITAL_NOT_PENDING 0x0 -#define NV4_PRM_INTR_0_TRACE_SB_DIGITAL_PENDING 0x1 -#define NV4_PRM_INTR_0_TRACE_SB_DIGITAL_RESET 0x1 -#define NV4_PRM_INTR_0_TRACE_SB_MIXER 12 -#define NV4_PRM_INTR_0_TRACE_SB_MIXER_NOT_PENDING 0x0 -#define NV4_PRM_INTR_0_TRACE_SB_MIXER_PENDING 0x1 -#define NV4_PRM_INTR_0_TRACE_SB_MIXER_RESET 0x1 -#define NV4_PRM_INTR_0_TRACE_OVERFLOW 16 -#define NV4_PRM_INTR_0_TRACE_OVERFLOW_NOT_PENDING 0x0 -#define NV4_PRM_INTR_0_TRACE_OVERFLOW_PENDING 0x1 -#define NV4_PRM_INTR_0_TRACE_OVERFLOW_RESET 0x1 -#define NV4_PRM_INTR_EN_0 0x4140 -#define NV4_PRM_INTR_EN_0_TRACE_MPU401 0 -#define NV4_PRM_INTR_EN_0_TRACE_MPU401_ENABLED 0x1 -#define NV4_PRM_INTR_EN_0_TRACE_FM 4 -#define NV4_PRM_INTR_EN_0_TRACE_FM_ENABLED 0x1 -#define NV4_PRM_INTR_EN_0_TRACE_SB_DIGITAL 8 -#define NV4_PRM_INTR_EN_0_TRACE_SB_DIGITAL_ENABLED 0x1 -#define NV4_PRM_INTR_EN_0_TRACE_SB_MIXER 12 -#define NV4_PRM_INTR_EN_0_TRACE_SB_MIXER_ENABLED 0x1 -#define NV4_PRM_INTR_EN_0_TRACE_OVERFLOW 16 -#define NV4_PRM_INTR_EN_0_TRACE_OVERFLOW_ENABLED 0x1 -#define NV4_PRM_RAMRM 0x4200 -#define NV4_PRM_RAMRM_BASE_ADDRESS 12 -#define NV4_PRM_RAMRM_BASE_ADDRESS_2000 0x2000 -#define NV4_PRM_TRACE 0x4300 -#define NV4_PRM_TRACE_IO_CAPTURE 0 -#define NV4_PRM_TRACE_IO_CAPTURE_DISABLED 0x0 -#define NV4_PRM_TRACE_IO_CAPTURE_WRITES 0x1 -#define NV4_PRM_TRACE_IO_CAPTURE_READS 0x2 -#define NV4_PRM_TRACE_IO_CAPTURE_READS_WRITES 0x3 -#define NV4_PRM_TRACE_IO_WRITE 4 -#define NV4_PRM_TRACE_IO_WRITE_NONE 0x0 -#define NV4_PRM_TRACE_IO_WRITE_OCCURED 0x1 -#define NV4_PRM_TRACE_IO_WRITE_RESET 0x1 -#define NV4_PRM_TRACE_IO_READ 5 -#define NV4_PRM_TRACE_IO_READ_NONE 0x0 -#define NV4_PRM_TRACE_IO_READ_OCCURED 0x1 -#define NV4_PRM_TRACE_IO_READ_RESET 0x1 -#define NV4_PRM_TRACE_INDEX 0x4310 -#define NV4_PRM_TRACE_INDEX_ADDRESS 0 -#define NV4_PRM_TRACE_INDEX_ADDRESS_0 0x0 -#define NV4_PRM_IGNORE_0 0x4320 -#define NV4_PRM_IGNORE_0_MPU401 0 -#define NV4_PRM_IGNORE_0_MPU401_DISABLED 0x0 -#define NV4_PRM_IGNORE_0_MPU401_WRITES 0x1 -#define NV4_PRM_IGNORE_0_MPU401_READS 0x2 -#define NV4_PRM_IGNORE_0_MPU401_READS_WRITES 0x3 -#define NV4_PRM_IGNORE_0_FM 4 -#define NV4_PRM_IGNORE_0_FM_DISABLED 0x0 -#define NV4_PRM_IGNORE_0_FM_WRITES 0x1 -#define NV4_PRM_IGNORE_0_FM_READS 0x2 -#define NV4_PRM_IGNORE_0_FM_READS_WRITES 0x3 -#define NV4_PRM_IGNORE_0_SB_DIGITAL 8 -#define NV4_PRM_IGNORE_0_SB_DIGITAL_DISABLED 0x0 -#define NV4_PRM_IGNORE_0_SB_DIGITAL_WRITES 0x1 -#define NV4_PRM_IGNORE_0_SB_DIGITAL_READS 0x2 -#define NV4_PRM_IGNORE_0_SB_DIGITAL_READS_WRITES 0x3 -#define NV4_PRM_IGNORE_0_SB_MIXER 12 -#define NV4_PRM_IGNORE_0_SB_MIXER_DISABLED 0x0 -#define NV4_PRM_IGNORE_0_SB_MIXER_WRITES 0x1 -#define NV4_PRM_IGNORE_0_SB_MIXER_READS 0x2 -#define NV4_PRM_IGNORE_0_SB_MIXER_READS_WRITES 0x3 - -// -// PIO submission -// - -#define NV4_USER_START 0x800000 -#define NV4_USER_END 0xFFFFFF - -#define NV4_USER_OBJECT(i,j) (0x800000+(i)*0x10000+(j)*0x2000) -#define NV4_USER_OBJECT_SIZE_1 16 -#define NV4_USER_OBJECT_SIZE_2 8 -#define NV4_USER_OBJECT_HANDLE 0 -#define NV4_USER_FREE016(i,j) (0x800010+(i)*65536+(j)*8192) -#define NV4_USER_FREE016_SIZE_1 16 -#define NV4_USER_FREE016_SIZE_2 8 -#define NV4_USER_FREE016_COUNT_LO 0 -#define NV4_USER_FREE016_COUNT_LO_0 0x0 -#define NV4_USER_FREE016_COUNT 2 -#define NV4_USER_FREE016_COUNT_HI 10 -#define NV4_USER_FREE016_COUNT_HI_0 0x0 -#define NV4_USER_FREE032(i,j) (0x800010+(i)*65536+(j)*8192) -#define NV4_USER_FREE032_SIZE_1 16 -#define NV4_USER_FREE032_SIZE_2 8 -#define NV4_USER_FREE032_COUNT_LO 0 -#define NV4_USER_FREE032_COUNT_LO_0 0x0 -#define NV4_USER_FREE032_COUNT 2 -#define NV4_USER_FREE032_COUNT_HI 10 -#define NV4_USER_FREE032_COUNT_HI_0 0x0 -#define NV4_USER_ZERO016(i,j,k) (0x0800012+(i)*65536+(j)*8192+(k)*2) -#define NV4_USER_ZERO016_SIZE_1 16 -#define NV4_USER_ZERO016_SIZE_2 8 -#define NV4_USER_ZERO016_SIZE_3 7 -#define NV4_USER_ZERO016_COUNT 0 -#define NV4_USER_ZERO016_COUNT_0 0x0 -#define NV4_USER_ZERO032(i,j,k) (0x0800014+(i)*65536+(j)*8192+(k)*4) -#define NV4_USER_ZERO032_SIZE_1 16 -#define NV4_USER_ZERO032_SIZE_2 8 -#define NV4_USER_ZERO032_SIZE_3 3 -#define NV4_USER_ZERO032_COUNT 0 -#define NV4_USER_ZERO032_COUNT_0 0x0 -#define NV4_USER_DMA_PUT(i,j) (0x800040+(i)*0x10000+(j)*0x2000) -#define NV4_USER_DMA_PUT_OFFSET 2 -#define NV4_USER_DMA_GET(i,j) (0x800044+(i)*0x10000+(j)*0x2000) -#define NV4_USER_DMA_GET_OFFSET 2 - -#define NV4_USER_ADR_CHID 16 -#define NV4_USER_ADR_SUBCHID 13 -#define NV4_USER_ADR_METHOD 0 -#define NV4_USER_DEVICE 16 - -#define NV4_PTIMER_START 0x9000 -#define NV4_PTIMER_END 0x9FFF - -#define NV4_PTIMER_INTR 0x9100 -#define NV4_PTIMER_INTR_ALARM 0 -#define NV4_PTIMER_INTR_ALARM_NOT_PENDING 0x0 -#define NV4_PTIMER_INTR_ALARM_PENDING 0x1 -#define NV4_PTIMER_INTR_ALARM_RESET 0x1 -#define NV4_PTIMER_INTR_EN 0x9140 -#define NV4_PTIMER_INTR_EN_ALARM 0 -#define NV4_PTIMER_INTR_EN_ALARM_ENABLED 0x1 // 0 = disabled -#define NV4_PTIMER_NUMERATOR 0x9200 -#define NV4_PTIMER_NUMERATOR_VALUE 0 -#define NV4_PTIMER_NUMERATOR_VALUE_0 0x0 -#define NV4_PTIMER_DENOMINATOR 0x9210 -#define NV4_PTIMER_DENOMINATOR_VALUE 0 -#define NV4_PTIMER_DENOMINATOR_VALUE_0 0x0 -#define NV4_PTIMER_TIME_0 0x9400 -#define NV4_PTIMER_TIME_0_NSEC 5 -#define NV4_PTIMER_TIME_1 0x9410 -#define NV4_PTIMER_TIME_1_NSEC 0 -#define NV4_PTIMER_ALARM 0x9420 -#define NV4_PTIMER_ALARM_NSEC 5 - -#define NV4_TRACE 0xFFFF: 0x0 -#define NV4_TRACE_DATA ( 0*32+ 7):( 0*32+ 0) -#define NV4_TRACE_ACCESS ( 0*32+14):( 0*32+14) -#define NV4_TRACE_ACCESS_WRITE 0x0 -#define NV4_TRACE_ACCESS_READ 0x1 -#define NV4_TRACE_TYPE ( 0*32+15):( 0*32+15) -#define NV4_TRACE_TYPE_IO 0x0 -#define NV4_TRACE_TYPE_MEMORY 0x1 -#define NV4_TRACE_ADDRESS ( 0*32+31):( 0*32+16) - -#define NV4_RAMHT_SIZE_0 0xFFF -#define NV4_RAMHT_SIZE_1 0x1FFF -#define NV4_RAMHT_SIZE_2 0x3FFF -#define NV4_RAMHT_SIZE_3 0x7FFF -#define NV4_RAMHT_HANDLE ( 0*32+31):( 0*32+ 0) -#define NV4_RAMHT_INSTANCE ( 1*32+15):( 1*32+ 0) -#define NV4_RAMHT_ENGINE ( 1*32+17):( 1*32+16) -#define NV4_RAMHT_ENGINE_SW 0x0 -#define NV4_RAMHT_ENGINE_GRAPHICS 0x1 -#define NV4_RAMHT_ENGINE_DVD 0x2 -#define NV4_RAMHT_CHID ( 1*32+27):( 1*32+24) -#define NV4_RAMHT_STATUS ( 1*32+31):( 1*32+31) -#define NV4_RAMHT_STATUS_INVALID 0x0 -#define NV4_RAMHT_STATUS_VALID 0x1 - -#define NV4_RAMRO_SIZE_0 0x1FF -#define NV4_RAMRO_SIZE_1 0x1FFF -#define NV4_RAMRO_METHOD ( 0*32+12):( 0*32+ 0) -#define NV4_RAMRO_SUBCHANNEL ( 0*32+15):( 0*32+13) -#define NV4_RAMRO_CHID ( 0*32+22):( 0*32+16) -#define NV4_RAMRO_TYPE ( 0*32+23):( 0*32+23) -#define NV4_RAMRO_TYPE_WRITE 0x0 -#define NV4_RAMRO_TYPE_READ 0x1 -#define NV4_RAMRO_BYTE_ENABLES ( 0*32+27):( 0*32+24) -#define NV4_RAMRO_REASON ( 0*32+31):( 0*32+28) -#define NV4_RAMRO_REASON_ILLEGAL_ACCESS 0x0 -#define NV4_RAMRO_REASON_NO_CACHE_AVAILABLE 0x1 -#define NV4_RAMRO_REASON_CACHE_RAN_OUT 0x2 -#define NV4_RAMRO_REASON_FREE_COUNT_OVERRUN 0x3 -#define NV4_RAMRO_REASON_CAUGHT_LYING 0x4 -#define NV4_RAMRO_REASON_RESERVED_ACCESS 0x5 -#define NV4_RAMRO_DATA ( 1*32+31):( 1*32+ 0) - -#define NV4_RAMFC_SIZE_0 0x1FF -#define NV4_RAMFC_DMA_PUT ( 0*32+28):( 0*32+ 2) -#define NV4_RAMFC_DMA_GET ( 1*32+28):( 1*32+ 2) -#define NV4_RAMFC_DMA_INST ( 2*32+15):( 2*32+ 0) -#define NV4_RAMFC_DMA_METHOD ( 3*32+12):( 3*32+ 2) -#define NV4_RAMFC_DMA_SUBCHANNEL ( 3*32+15):( 3*32+13) -#define NV4_RAMFC_DMA_METHOD_COUNT ( 3*32+28):( 3*32+18) -#define NV4_RAMFC_DMA_FETCH_TRIG ( 4*32+ 7):( 4*32+ 3) -#define NV4_RAMFC_DMA_FETCH_SIZE ( 4*32+15):( 4*32+13) -#define NV4_RAMFC_DMA_FETCH_MAX_REQS ( 4*32+19):( 4*32+16) -#define NV4_RAMFC_ENGINE_SUB_0 ( 5*32+ 1):( 5*32+ 0) -#define NV4_RAMFC_ENGINE_SUB_1 ( 5*32+ 5):( 5*32+ 4) -#define NV4_RAMFC_ENGINE_SUB_2 ( 5*32+ 9):( 5*32+ 8) -#define NV4_RAMFC_ENGINE_SUB_3 ( 5*32+13):( 5*32+12) -#define NV4_RAMFC_ENGINE_SUB_4 ( 5*32+17):( 5*32+16) -#define NV4_RAMFC_ENGINE_SUB_5 ( 5*32+21):( 5*32+20) -#define NV4_RAMFC_ENGINE_SUB_6 ( 5*32+25):( 5*32+24) -#define NV4_RAMFC_ENGINE_SUB_7 ( 5*32+29):( 5*32+28) -#define NV4_RAMFC_ENGINE_SW 0x0 -#define NV4_RAMFC_ENGINE_GRAPHICS 0x1 -#define NV4_RAMFC_ENGINE_DVD 0x2 -#define NV4_RAMFC_PULL1_ENGINE ( 6*32+ 1):( 6*32+ 0) -#define NV4_RAMFC_PULL1_ENGINE_SW 0x0 -#define NV4_RAMFC_PULL1_ENGINE_GRAPHICS 0x1 -#define NV4_RAMFC_PULL1_ENGINE_DVD 0x2 - - -#define NV4_RAMDVD_CTX_TABLE (63*32+31):( 0*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT(c,s) (((c)*4+((s)/2))*32+((s)%2)*16+15):(((c)*4+((s)/2))*32+((s)%2)*16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_0 ( 0*32+15):( 0*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_1 ( 0*32+31):( 0*32+16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_2 ( 1*32+15):( 1*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_3 ( 1*32+31):( 1*32+16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_4 ( 2*32+15):( 2*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_5 ( 2*32+31):( 2*32+16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_6 ( 3*32+15):( 3*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_0_7 ( 3*32+31):( 3*32+16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_0 (60*32+15):(60*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_1 (60*32+31):(60*32+16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_2 (61*32+15):(61*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_3 (61*32+31):(61*32+16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_4 (62*32+15):(62*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_5 (62*32+31):(62*32+16) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_6 (63*32+15):(63*32+ 0) -#define NV4_RAMDVD_CTX_TABLE_OBJECT_15_7 (63*32+31):(63*32+16) - -#define NV4_DMA_CLASS ( 0*32+11):( 0*32+ 0) -#define NV4_DMA_PAGE_TABLE ( 0*32+12):( 0*32+12) -#define NV4_DMA_PAGE_TABLE_NOT_PRESENT 0x0 -#define NV4_DMA_PAGE_TABLE_PRESENT 0x1 -#define NV4_DMA_PAGE_ENTRY ( 0*32+13):( 0*32+13) -#define NV4_DMA_PAGE_ENTRY_NOT_LINEAR 0x0 -#define NV4_DMA_PAGE_ENTRY_LINEAR 0x1 -#define NV4_DMA_TARGET_NODE ( 0*32+17):( 0*32+16) -#define NV4_DMA_TARGET_NODE_NVM 0x0 -#define NV4_DMA_TARGET_NODE_PCI 0x2 -#define NV4_DMA_TARGET_NODE_AGP 0x3 -#define NV4_DMA_ADJUST ( 0*32+31):( 0*32+20) -#define NV4_DMA_LIMIT ( 1*32+31):( 1*32+ 0) -#define NV4_DMA_ACCESS ( 2*32+ 1):( 2*32+ 1) -#define NV4_DMA_ACCESS_READ_ONLY 0x0 -#define NV4_DMA_ACCESS_READ_AND_WRITE 0x1 -#define NV4_DMA_FRAME_ADDRESS ( 2*32+31):( 2*32+12) - -#define NV4_SUBCHAN_CTX_SWITCH ( 0*32+31):( 0*32+ 0) -#define NV4_SUBCHAN_DMA_INSTANCE ( 1*32+15):( 1*32+ 0) -#define NV4_SUBCHAN_NOTIFY_INSTANCE ( 1*32+31):( 1*32+16) -#define NV4_SUBCHAN_MEMFMT_INSTANCE ( 2*32+15):( 2*32+ 0) -#define NV4_SUBCHAN_MEMFMT_LINEAR ( 2*32+16):( 2*32+16) -#define NV4_SUBCHAN_MEMFMT_LINEAR_OUT 0x0 -#define NV4_SUBCHAN_MEMFMT_LINEAR_IN 0x1 \ No newline at end of file diff --git a/src/include/86box/utils/video_stdlib.h b/src/include/86box/utils/video_stdlib.h deleted file mode 100644 index 0d4b148d6..000000000 --- a/src/include/86box/utils/video_stdlib.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Standard library for implementation of video functionality that is duplicated across multiple cards. - * - * - * - * Authors: Connor Hyde - * - * Copyright 2025 Connor Hyde - */ - - -/* ROP */ - -#define VIDEO_ROP_SRC_COPY 0xCC - -int32_t video_rop_gdi_ternary(int32_t rop, int32_t src, int32_t dst, int32_t pattern); \ No newline at end of file diff --git a/src/include/86box/video.h b/src/include/86box/video.h index c87ef4f77..81424dbcb 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -630,13 +630,6 @@ extern const device_t voodoo_3_3500_se_agp_device; extern const device_t voodoo_3_3500_si_agp_device; extern const device_t velocity_100_agp_device; extern const device_t velocity_200_agp_device; -extern const device_t nv1_device_edge2k; -extern const device_t nv1_device_edge3k; -extern const device_t nv3_device_pci; -extern const device_t nv3_device_agp; -extern const device_t nv3t_device_pci; -extern const device_t nv3t_device_agp; -extern const device_t nv4_device_agp; /* Wyse 700 */ extern const device_t wy700_device; diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 87ff7293a..1a004d958 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -171,15 +171,7 @@ add_library(ui STATIC qt_newfloppydialog.ui qt_harddiskdialog.cpp qt_harddiskdialog.hpp - qt_harddiskdialog.ui - - qt_gpudebug_vram.cpp - qt_gpudebug_vram.hpp - qt_gpudebug_vram.ui - - qt_gpudebug_visualnv.cpp - qt_gpudebug_visualnv.hpp - qt_gpudebug_visualnv.ui + qt_harddiskdialog.ui qt_harddrive_common.cpp qt_harddrive_common.hpp diff --git a/src/qt/qt_gpudebug_visualnv.cpp b/src/qt/qt_gpudebug_visualnv.cpp deleted file mode 100644 index 3b2ba8472..000000000 --- a/src/qt/qt_gpudebug_visualnv.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * GPU Debugging Tools - Visual NV Debugger implementation - * - * - * - * Authors: starfrost - * - * Copyright 2025 starfrost - */ - -/* C++ includes */ -#include -#include - - -/* Qt includes*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ui_qt_gpudebug_visualnv.h" - -/* 86Box core includes */ -extern "C" -{ - /* NOTE: DO NOT REMOVE */ - #include <86box/86box.h> - #include <86box/device.h> - #include <86box/mem.h> - #include <86box/pci.h> - #include <86box/rom.h> - #include <86box/video.h> - #include <86box/nv/vid_nv.h> - #include <86box/nv/vid_nv3.h> -} - -VisualNVDialog::VisualNVDialog(QWidget *parent) - : QDialog(parent) - , ui(new Ui::VisualNVDialog) -{ - ui->setupUi(this); - - connect(ui->btnLoadSavestate, &QPushButton::clicked, this, &VisualNVDialog::on_btnLoadSavestate_clicked); - connect(ui->fbStartAddress, &QPlainTextEdit::textChanged, this, &VisualNVDialog::on_fbStartAddress_changed); - connect(ui->bPitch0Value, &QPlainTextEdit::textChanged, this, &VisualNVDialog::on_bPitch0Value_changed); - connect(ui->bPitch1Value, &QPlainTextEdit::textChanged, this, &VisualNVDialog::on_bPitch1Value_changed); -} - -// VisualNV dialog destructor -VisualNVDialog::~VisualNVDialog() -{ - -} - -void VisualNVDialog::on_btnLoadSavestate_clicked() -{ - if (!nv3) - return; - - QString bar0_file_name = QFileDialog::getOpenFileName - ( - this, - tr("Please provide NVPlay 0.3.0.7+ NV3BAR0.BIN file"), - ".", - tr("NVPlay MMIO Dump Files (*.bin)") - ); - - QString bar1_file_name = QFileDialog::getOpenFileName - ( - this, - tr("Please provide NVPlay 0.3.0.7+ NV3BAR1.BIN file"), - ".", - tr("NVPlay VRAM/RAMIN Dump Files (*.bin)") - ); - - // - // Open both dump files - // - - QFile bar0(bar0_file_name); - QFile bar1(bar1_file_name); - - if (!bar0.open(QIODevice::ReadOnly)) - { - warning("Failed to open NV3BAR0.bin!"); - return; - } - - if (!bar1.open(QIODevice::ReadOnly)) - { - warning("Failed to open NV3BAR1.bin!"); - return; - } - - if (bar0.size() != NV3_MMIO_SIZE - || bar1.size() != NV3_MMIO_SIZE) - { - warning("NV3BAR0.bin and NV3BAR1.bin must be 16MB!"); - bar0.close(); - bar1.close(); - return; - } - - // Load VRAM contents only for now. Todo: MMIO+RAMIN - QString oldTitle = this->windowTitle(); - - this->setWindowTitle(tr("RIVA 128 Realtime Debugger: Savestate Loading...")); - - bar1.read((char*)nv3->nvbase.svga.vram, nv3->nvbase.vram_amount); - - this->setWindowTitle(oldTitle); - -} - -void VisualNVDialog::on_fbStartAddress_changed() -{ - if (nv3) - { - nv3->nvbase.debug_dba_enabled = true; - - bool ok = true; - - nv3->nvbase.debug_dba = ui->fbStartAddress->toPlainText().toInt(&ok); - - if (!ok) - nv3->nvbase.debug_dba_enabled = false; - } -} - -void VisualNVDialog::on_bPitch0Value_changed() -{ - if (nv3) - { - bool ok = true; - - uint32_t old_bpitch = nv3->pgraph.bpitch[0]; - - nv3->pgraph.bpitch[0] = ui->bPitch0Value->toPlainText().toInt(&ok); - - if (!ok) - nv3->pgraph.bpitch[0] = old_bpitch; - } - -} - -void VisualNVDialog::on_bPitch1Value_changed() -{ - if (nv3) - { - bool ok = true; - - uint32_t old_bpitch = nv3->pgraph.bpitch[1]; - - nv3->pgraph.bpitch[1] = ui->bPitch0Value->toPlainText().toInt(&ok); - - if (!ok) - nv3->pgraph.bpitch[1] = old_bpitch; - } - -} \ No newline at end of file diff --git a/src/qt/qt_gpudebug_visualnv.hpp b/src/qt/qt_gpudebug_visualnv.hpp deleted file mode 100644 index ee87dc0b3..000000000 --- a/src/qt/qt_gpudebug_visualnv.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * GPU Debugging Tools - VRAM Viewer headers - * - * - * - * Authors: starfrost - * - * Copyright 2025 starfrost - */ - - -#pragma once - -#include - -namespace Ui -{ - class VisualNVDialog; -} - -class VisualNVDialog : public QDialog -{ - Q_OBJECT - - public: - explicit VisualNVDialog(QWidget *parent = nullptr); - ~VisualNVDialog(); - - void on_btnLoadSavestate_clicked(); - void on_fbStartAddress_changed(); - void on_bPitch0Value_changed(); - void on_bPitch1Value_changed(); - - protected: - private: - Ui::VisualNVDialog* ui; - - -}; \ No newline at end of file diff --git a/src/qt/qt_gpudebug_visualnv.ui b/src/qt/qt_gpudebug_visualnv.ui deleted file mode 100644 index ce45c4e44..000000000 --- a/src/qt/qt_gpudebug_visualnv.ui +++ /dev/null @@ -1,213 +0,0 @@ - - - VisualNVDialog - - - - 0 - 0 - 620 - 350 - - - - - 0 - 0 - - - - - 620 - 350 - - - - - 620 - 350 - - - - RIVA 128 Realtime Debugger - - - - - - - - 10 - 0 - 201 - 171 - - - - PFIFO State - - - - - - 220 - 0 - 361 - 171 - - - - PGRAPH State - - - - - - 10 - 180 - 571 - 141 - - - - VRAM Control - - - - - 160 - 30 - 104 - 21 - - - - - - - 10 - 30 - 151 - 21 - - - - <html><head/><body><p>VRAM Visual Aperture Start</p></body></html> - - - - - - 390 - 30 - 91 - 16 - - - - <html><head/><body><p>FB Start Address:</p></body></html> - - - - - - 480 - 30 - 81 - 16 - - - - <html><head/><body><p><span style=" font-weight:700;">PLACEHOLDER</span></p></body></html> - - - - - - 160 - 60 - 104 - 21 - - - - - - - 10 - 60 - 151 - 21 - - - - <html><head/><body><p>Pixel Depth</p></body></html> - - - - - - 10 - 110 - 231 - 24 - - - - Load nvplay savestate from real hardware - - - - - - 390 - 60 - 61 - 16 - - - - <html><head/><body><p>BPITCH[0]:</p></body></html> - - - - - - 460 - 60 - 104 - 21 - - - - - - - 460 - 90 - 104 - 21 - - - - - - - 390 - 90 - 61 - 16 - - - - <html><head/><body><p>BPITCH[1]:</p></body></html> - - - - - - - - - - diff --git a/src/qt/qt_gpudebug_vram.cpp b/src/qt/qt_gpudebug_vram.cpp deleted file mode 100644 index 000f41263..000000000 --- a/src/qt/qt_gpudebug_vram.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * GPU Debugging Tools - VRAM Viewer implementation - * - * - * - * Authors: starfrost - * - * Copyright 2025 starfrost - */ - -/* C++ includes */ -#include -#include - - -/* Qt includes*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ui_qt_gpudebug_vram.h" - -/* 86Box core includes */ -extern "C" -{ - -} - -GPUDebugVRAMDialog::GPUDebugVRAMDialog(QWidget *parent) - : QDialog(parent) - , ui(new Ui::GPUDebugVRAMDialog) -{ - ui->setupUi(this); -} - -GPUDebugVRAMDialog::~GPUDebugVRAMDialog() -{ - -} \ No newline at end of file diff --git a/src/qt/qt_gpudebug_vram.hpp b/src/qt/qt_gpudebug_vram.hpp deleted file mode 100644 index 18b2e8c96..000000000 --- a/src/qt/qt_gpudebug_vram.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * GPU Debugging Tools - VRAM Viewer headers - * - * - * - * Authors: starfrost - * - * Copyright 2025 starfrost - */ - - -#pragma once - -#include - -namespace Ui -{ - class GPUDebugVRAMDialog; -} - -class GPUDebugVRAMDialog : public QDialog -{ - Q_OBJECT - - public: - explicit GPUDebugVRAMDialog(QWidget *parent = nullptr); - ~GPUDebugVRAMDialog(); - protected: - private: - Ui::GPUDebugVRAMDialog* ui; - - -}; \ No newline at end of file diff --git a/src/qt/qt_gpudebug_vram.ui b/src/qt/qt_gpudebug_vram.ui deleted file mode 100644 index a92a60306..000000000 --- a/src/qt/qt_gpudebug_vram.ui +++ /dev/null @@ -1,42 +0,0 @@ - - - GPUDebugVRAMDialog - - - - 0 - 0 - 600 - 400 - - - - - 0 - 0 - - - - - 600 - 400 - - - - - 600 - 400 - - - - VRAM Viewer - - - - - - - - - - diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e0900d1ef..954547078 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -24,8 +24,6 @@ #include "qt_mainwindow.hpp" #include "ui_qt_mainwindow.h" -#include "ui_qt_gpudebug_vram.h" -#include "ui_qt_gpudebug_visualnv.h" #include "qt_specifydimensions.h" #include "qt_soundgain.hpp" @@ -108,8 +106,6 @@ void qt_set_sequence_auto_mnemonic(bool b); #include "qt_mediamenu.hpp" #include "qt_util.hpp" -#include "qt_gpudebug_vram.hpp" - #if defined __unix__ && !defined __HAIKU__ # ifndef Q_OS_MACOS # include "evdev_keyboard.hpp" @@ -289,7 +285,29 @@ MainWindow::MainWindow(QWidget *parent) this->setWindowTitle(QString("%1 - %2 %3").arg(vmname, EMU_NAME, EMU_VERSION_FULL)); connect(this, &MainWindow::hardResetCompleted, this, [this]() { - onHardResetCompleted(); + ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); + num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && + (keyboard_type == KEYBOARD_TYPE_AX); + int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && + !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); + kana_label->setVisible(ext_ax_kbd || int_ax_kbd); + while (QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); +#ifdef USE_WACOM + ui->menuTablet_tool->menuAction()->setVisible(mouse_input_mode >= 1); +#else + ui->menuTablet_tool->menuAction()->setVisible(false); +#endif + + bool enable_comp_option = false; + for (int i = 0; i < MONITORS_NUM; i++) { + if (monitors[i].mon_composite) { enable_comp_option = true; break; } + } + + ui->actionCGA_composite_settings->setEnabled(enable_comp_option); }); connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::QueuedConnection); @@ -890,50 +908,6 @@ MainWindow::MainWindow(QWidget *parent) updateShortcuts(); } -void MainWindow::onHardResetCompleted() -{ - ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); - num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); - scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); - caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); - int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && - (keyboard_type == KEYBOARD_TYPE_AX); - int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && - !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); - kana_label->setVisible(ext_ax_kbd || int_ax_kbd); - while (QApplication::overrideCursor()) - QApplication::restoreOverrideCursor(); -#ifdef USE_WACOM - ui->menuTablet_tool->menuAction()->setVisible(mouse_input_mode >= 1); -#else - ui->menuTablet_tool->menuAction()->setVisible(false); -#endif - - bool enable_comp_option = false; - for (int i = 0; i < MONITORS_NUM; i++) { - if (monitors[i].mon_composite) { enable_comp_option = true; break; } - } - - ui->actionCGA_composite_settings->setEnabled(enable_comp_option); - -#ifdef ENABLE_NV_LOG - /* - THIS CODE SUCKS AND THIS DESIGN IS TERRIBLE - EVERYTHING ABOUT IT IS BAD AND WRONG. - ENTIRE DEVICE SUBSYSTEM IDEALLY WOULD BE DECOUPLED FROM UI BUT MEH - */ - - const device_t* vid_device = video_card_getdevice(gfxcard[0]); - - bool is_nv3 = (vid_device == &nv3_device_agp - || vid_device == &nv3_device_pci - || vid_device == &nv3t_device_agp - || vid_device == &nv3t_device_pci); - - ui->actionDebug_GPUDebug_VisualNv->setVisible(is_nv3); -#endif -} - - void MainWindow::closeEvent(QCloseEvent *event) { @@ -2551,29 +2525,3 @@ void MainWindow::on_actionCGA_composite_settings_triggered() config_save(); } - -void MainWindow::on_actionDebug_GPUDebug_VRAM_triggered() -{ - debugVramDialog = new GPUDebugVRAMDialog(this); - debugVramDialog->setWindowFlag(Qt::CustomizeWindowHint, true); - debugVramDialog->setWindowFlag(Qt::WindowTitleHint, true); - debugVramDialog->setWindowFlag(Qt::WindowSystemMenuHint, false); - // If I have this as a NON-MODAL dialog, input is just eaten without doing anything - // WTF?!?!?!?!? - //debugVramDialog->show(); - debugVramDialog->exec(); - -} - - -void MainWindow::on_actionDebug_GPUDebug_VisualNv_triggered() -{ - visualNvDialog = new VisualNVDialog(this); - visualNvDialog->setWindowFlag(Qt::CustomizeWindowHint, true); - visualNvDialog->setWindowFlag(Qt::WindowTitleHint, true); - visualNvDialog->setWindowFlag(Qt::WindowSystemMenuHint, false); - // If I have this as a NON-MODAL dialog, input is just eaten without doing anything - // WTF?!?!?!?!? - //visualNvDialog->show(); - visualNvDialog->exec(); -} \ No newline at end of file diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 6ae838896..f562c2ea9 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -17,11 +17,6 @@ extern QTimer discordupdate; -// NON-modal dialogs -#include "qt_gpudebug_vram.hpp" -#include "qt_gpudebug_visualnv.hpp" - - class MediaMenu; class RendererStack; @@ -79,8 +74,6 @@ signals: public slots: void showSettings(); void hardReset(); - void onHardResetCompleted(); - void togglePause(); void initRendererMonitorSlot(int monitor_index); void destroyRendererMonitorSlot(int monitor_index); @@ -143,9 +136,7 @@ private slots: void on_actionPreferences_triggered(); void on_actionEnable_Discord_integration_triggered(bool checked); void on_actionRenderer_options_triggered(); - void on_actionDebug_GPUDebug_VRAM_triggered(); - void on_actionDebug_GPUDebug_VisualNv_triggered(); - + void refreshMediaMenu(); void showMessage_(int flags, const QString &header, const QString &message, bool richText, std::atomic_bool* done = nullptr); void getTitle_(wchar_t *title); @@ -184,10 +175,6 @@ private slots: private: Ui::MainWindow *ui; - - // NON-modal dialogs - these use ::show() and therefore have to be maintained as objects - GPUDebugVRAMDialog *debugVramDialog; - VisualNVDialog *visualNvDialog; std::unique_ptr status; std::shared_ptr mm; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index bebef8c88..ca7aca2ca 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -251,19 +251,11 @@ - - - &Debugging Tools - - - - - @@ -927,27 +919,7 @@ &CGA composite settings... - - - - - GPU Debug - VRAM Viewer - - - - - RIVA 128 Realtime Debugger - - - - - GPU Debug - VRAM Viewer - - - - - RIVA 128 Realtime Debugger - + @@ -1077,54 +1049,6 @@ &8x - - - true - - - &Full screen stretch - - - - - true - - - &4:3 - - - - - true - - - &Square pixels (Keep ratio) - - - - - true - - - &Integer scale - - - - - true - - - 4:&3 Integer scale - - - - - true - - - &1x - - diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index b806f3ccb..c3efdaaff 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -1525,7 +1525,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) default: break; } - emu8k_log("EMU8K WRITE: : Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, + emu8k_log("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice, val); } diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fe9be9c2d..f041ebb8c 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -798,7 +798,7 @@ sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *priv) break; default: - sb_log("sb_ct1335: : Unknown register write: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("sb_ct1335: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } @@ -899,7 +899,7 @@ sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv) break; default: - sb_log("sb_ct1345: : Unknown register write: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("sb_ct1345: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); break; } } diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index fab669d28..bcbc7aafd 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -24,7 +24,4 @@ add_library(utils OBJECT ini.c log.c random.c - - # VIDEO - video/video_rop.c ) diff --git a/src/utils/log.c b/src/utils/log.c index b8c28afab..f0eb6aa3c 100644 --- a/src/utils/log.c +++ b/src/utils/log.c @@ -44,7 +44,6 @@ typedef struct log_t { char **cyclic_buff; int32_t cyclic_last_line; int32_t log_cycles; - int32_t last_repeat_order; } log_t; /* File to log output to. */ @@ -220,18 +219,9 @@ log_out_cyclic(void* priv, const char* fmt, va_list ap) } - if (is_cycle) - { - if (log->cyclic_last_line % repeat_order == 0) - { - log->log_cycles++; - - // If the order of the log repeat changes - if (log->last_repeat_order != repeat_order - && log->last_repeat_order > 0) - { - log->log_cycles = 1; - } + if (is_cycle) { + if (log->cyclic_last_line % repeat_order == 0) { + log->log_cycles++; if (log->log_cycles == 1) { /* @@ -275,13 +265,10 @@ log_out_cyclic(void* priv, const char* fmt, va_list ap) } log->cyclic_last_line++; - - log->last_repeat_order = repeat_order; } } #endif - void log_fatal(void *priv, const char *fmt, ...) { diff --git a/src/utils/video/video_rop.c b/src/utils/video/video_rop.c deleted file mode 100644 index 146822201..000000000 --- a/src/utils/video/video_rop.c +++ /dev/null @@ -1,790 +0,0 @@ -#include -#include <86box/utils/video_stdlib.h> - -/* - Implements a standard GDI ternary rop for e.g. bitblit acceleration. - For further information on this function, refer to the documentation on Win32 GDI: - - https://learn.microsoft.com/en-us/windows/win32/gdi/binary-raster-operations - - This is currently used in the following graphics cards: Tseng Labs ET4000/32p, Cirrus Logic CL-GD54xx, 3dfx Voodoo Banshee/Voodoo 3, Trident TGUI9440, - S3 ViRGE, C&T 69000, ATI Mach64, and NVidia RIVA 128 -*/ -int32_t video_rop_gdi_ternary(int32_t rop, int32_t src, int32_t dst, int32_t pattern) -{ - uint32_t out = 0x00; - - switch (rop) - { - case 0x00: - out = 0; - break; - case 0x01: - out = ~(dst | (pattern | src)); - break; - case 0x02: - out = dst & ~(pattern | src); - break; - case 0x03: - out = ~(pattern | src); - break; - case 0x04: - out = src & ~(dst | pattern); - break; - case 0x05: - out = ~(dst | pattern); - break; - case 0x06: - out = ~(pattern | ~(dst ^ src)); - break; - case 0x07: - out = ~(pattern | (dst & src)); - break; - case 0x08: - out = src & (dst & ~pattern); - break; - case 0x09: - out = ~(pattern | (dst ^ src)); - break; - case 0x0a: - out = dst & ~pattern; - break; - case 0x0b: - out = ~(pattern | (src & ~dst)); - break; - case 0x0c: - out = src & ~pattern; - break; - case 0x0d: - out = ~(pattern | (dst & ~src)); - break; - case 0x0e: - out = ~(pattern | ~(dst | src)); - break; - case 0x0f: - out = ~pattern; - break; - case 0x10: - out = pattern & ~(dst | src); - break; - case 0x11: - out = ~(dst | src); - break; - case 0x12: - out = ~(src | ~(dst ^ pattern)); - break; - case 0x13: - out = ~(src | (dst & pattern)); - break; - case 0x14: - out = ~(dst | ~(pattern ^ src)); - break; - case 0x15: - out = ~(dst | (pattern & src)); - break; - case 0x16: - out = pattern ^ (src ^ (dst & ~(pattern & src))); - break; - case 0x17: - out = ~(src ^ ((src ^ pattern) & (dst ^ src))); - break; - case 0x18: - out = (src ^ pattern) & (pattern ^ dst); - break; - case 0x19: - out = ~(src ^ (dst & ~(pattern & src))); - break; - case 0x1a: - out = pattern ^ (dst | (src & pattern)); - break; - case 0x1b: - out = ~(src ^ (dst & (pattern ^ src))); - break; - case 0x1c: - out = pattern ^ (src | (dst & pattern)); - break; - case 0x1d: - out = ~(dst ^ (src & (pattern ^ dst))); - break; - case 0x1e: - out = pattern ^ (dst | src); - break; - case 0x1f: - out = ~(pattern & (dst | src)); - break; - case 0x20: - out = dst & (pattern & ~src); - break; - case 0x21: - out = ~(src | (dst ^ pattern)); - break; - case 0x22: - out = dst & ~src; - break; - case 0x23: - out = ~(src | (pattern & ~dst)); - break; - case 0x24: - out = (src ^ pattern) & (dst ^ src); - break; - case 0x25: - out = ~(pattern ^ (dst & ~(src & pattern))); - break; - case 0x26: - out = src ^ (dst | (pattern & src)); - break; - case 0x27: - out = src ^ (dst | ~(pattern ^ src)); - break; - case 0x28: - out = dst & (pattern ^ src); - break; - case 0x29: - out = ~(pattern ^ (src ^ (dst | (pattern & src)))); - break; - case 0x2a: - out = dst & ~(pattern & src); - break; - case 0x2b: - out = ~(src ^ ((src ^ pattern) & (pattern ^ dst))); - break; - case 0x2c: - out = src ^ (pattern & (dst | src)); - break; - case 0x2d: - out = pattern ^ (src | ~dst); - break; - case 0x2e: - out = pattern ^ (src | (dst ^ pattern)); - break; - case 0x2f: - out = ~(pattern & (src | ~dst)); - break; - case 0x30: - out = pattern & ~src; - break; - case 0x31: - out = ~(src | (dst & ~pattern)); - break; - case 0x32: - out = src ^ (dst | (pattern | src)); - break; - case 0x33: - out = ~src; - break; - case 0x34: - out = src ^ (pattern | (dst & src)); - break; - case 0x35: - out = src ^ (pattern | ~(dst ^ src)); - break; - case 0x36: - out = src ^ (dst | pattern); - break; - case 0x37: - out = ~(src & (dst | pattern)); - break; - case 0x38: - out = pattern ^ (src & (dst | pattern)); - break; - case 0x39: - out = src ^ (pattern | ~dst); - break; - case 0x3a: - out = src ^ (pattern | (dst ^ src)); - break; - case 0x3b: - out = ~(src & (pattern | ~dst)); - break; - case 0x3c: - out = pattern ^ src; - break; - case 0x3d: - out = src ^ (pattern | ~(dst | src)); - break; - case 0x3e: - out = src ^ (pattern | (dst & ~src)); - break; - case 0x3f: - out = ~(pattern & src); - break; - case 0x40: - out = pattern & (src & ~dst); - break; - case 0x41: - out = ~(dst | (pattern ^ src)); - break; - case 0x42: - out = (src ^ dst) & (pattern ^ dst); - break; - case 0x43: - out = ~(src ^ (pattern & ~(dst & src))); - break; - case 0x44: - out = src & ~dst; - break; - case 0x45: - out = ~(dst | (pattern & ~src)); - break; - case 0x46: - out = dst ^ (src | (pattern & dst)); - break; - case 0x47: - out = ~(pattern ^ (src & (dst ^ pattern))); - break; - case 0x48: - out = src & (dst ^ pattern); - break; - case 0x49: - out = ~(pattern ^ (dst ^ (src | (pattern & dst)))); - break; - case 0x4a: - out = dst ^ (pattern & (src | dst)); - break; - case 0x4b: - out = pattern ^ (dst | ~src); - break; - case 0x4c: - out = src & ~(dst & pattern); - break; - case 0x4d: - out = ~(src ^ ((src ^ pattern) | (dst ^ src))); - break; - case 0x4e: - out = pattern ^ (dst | (src ^ pattern)); - break; - case 0x4f: - out = ~(pattern & (dst | ~src)); - break; - case 0x50: - out = pattern & ~dst; - break; - case 0x51: - out = ~(dst | (src & ~pattern)); - break; - case 0x52: - out = dst ^ (pattern | (src & dst)); - break; - case 0x53: - out = ~(src ^ (pattern & (dst ^ src))); - break; - case 0x54: - out = ~(dst | ~(pattern | src)); - break; - case 0x55: - out = ~dst; - break; - case 0x56: - out = dst ^ (pattern | src); - break; - case 0x57: - out = ~(dst & (pattern | src)); - break; - case 0x58: - out = pattern ^ (dst & (src | pattern)); - break; - case 0x59: - out = dst ^ (pattern | ~src); - break; - case 0x5a: - out = dst ^ pattern; - break; - case 0x5b: - out = dst ^ (pattern | ~(src | dst)); - break; - case 0x5c: - out = dst ^ (pattern | (src ^ dst)); - break; - case 0x5d: - out = ~(dst & (pattern | ~src)); - break; - case 0x5e: - out = dst ^ (pattern | (src & ~dst)); - break; - case 0x5f: - out = ~(dst & pattern); - break; - case 0x60: - out = pattern & (dst ^ src); - break; - case 0x61: - out = ~(dst ^ (src ^ (pattern | (dst & src)))); - break; - case 0x62: - out = dst ^ (src & (pattern | dst)); - break; - case 0x63: - out = src ^ (dst | ~pattern); - break; - case 0x64: - out = src ^ (dst & (pattern | src)); - break; - case 0x65: - out = dst ^ (src | ~pattern); - break; - case 0x66: - out = dst ^ src; - break; - case 0x67: - out = src ^ (dst | ~(pattern | src)); - break; - case 0x68: - out = ~(dst ^ (src ^ (pattern | ~(dst | src)))); - break; - case 0x69: - out = ~(pattern ^ (dst ^ src)); - break; - case 0x6a: - out = dst ^ (pattern & src); - break; - case 0x6b: - out = ~(pattern ^ (src ^ (dst & (pattern | src)))); - break; - case 0x6c: - out = src ^ (dst & pattern); - break; - case 0x6d: - out = ~(pattern ^ (dst ^ (src & (pattern | dst)))); - break; - case 0x6e: - out = src ^ (dst & (pattern | ~src)); - break; - case 0x6f: - out = ~(pattern & ~(dst ^ src)); - break; - case 0x70: - out = pattern & ~(dst & src); - break; - case 0x71: - out = ~(src ^ ((src ^ dst) & (pattern ^ dst))); - break; - case 0x72: - out = src ^ (dst | (pattern ^ src)); - break; - case 0x73: - out = ~(src & (dst | ~pattern)); - break; - case 0x74: - out = dst ^ (src | (pattern ^ dst)); - break; - case 0x75: - out = ~(dst & (src | ~pattern)); - break; - case 0x76: - out = src ^ (dst | (pattern & ~src)); - break; - case 0x77: - out = ~(dst & src); - break; - case 0x78: - out = pattern ^ (dst & src); - break; - case 0x79: - out = ~(dst ^ (src ^ (pattern & (dst | src)))); - break; - case 0x7a: - out = dst ^ (pattern & (src | ~dst)); - break; - case 0x7b: - out = ~(src & ~(dst ^ pattern)); - break; - case 0x7c: - out = src ^ (pattern & (dst | ~src)); - break; - case 0x7d: - out = ~(dst & ~(pattern ^ src)); - break; - case 0x7e: - out = (src ^ pattern) | (dst ^ src); - break; - case 0x7f: - out = ~(dst & (pattern & src)); - break; - case 0x80: - out = dst & (pattern & src); - break; - case 0x81: - out = ~((src ^ pattern) | (dst ^ src)); - break; - case 0x82: - out = dst & ~(pattern ^ src); - break; - case 0x83: - out = ~(src ^ (pattern & (dst | ~src))); - break; - case 0x84: - out = src & ~(dst ^ pattern); - break; - case 0x85: - out = ~(pattern ^ (dst & (src | ~pattern))); - break; - case 0x86: - out = dst ^ (src ^ (pattern & (dst | src))); - break; - case 0x87: - out = ~(pattern ^ (dst & src)); - break; - case 0x88: - out = dst & src; - break; - case 0x89: - out = ~(src ^ (dst | (pattern & ~src))); - break; - case 0x8a: - out = dst & (src | ~pattern); - break; - case 0x8b: - out = ~(dst ^ (src | (pattern ^ dst))); - break; - case 0x8c: - out = src & (dst | ~pattern); - break; - case 0x8d: - out = ~(src ^ (dst | (pattern ^ src))); - break; - case 0x8e: - out = src ^ ((src ^ dst) & (pattern ^ dst)); - break; - case 0x8f: - out = ~(pattern & ~(dst & src)); - break; - case 0x90: - out = pattern & ~(dst ^ src); - break; - case 0x91: - out = ~(src ^ (dst & (pattern | ~src))); - break; - case 0x92: - out = dst ^ (pattern ^ (src & (dst | pattern))); - break; - case 0x93: - out = ~(src ^ (pattern & dst)); - break; - case 0x94: - out = pattern ^ (src ^ (dst & (pattern | src))); - break; - case 0x95: - out = ~(dst ^ (pattern & src)); - break; - case 0x96: - out = dst ^ (pattern ^ src); - break; - case 0x97: - out = pattern ^ (src ^ (dst | ~(pattern | src))); - break; - case 0x98: - out = ~(src ^ (dst | ~(pattern | src))); - break; - case 0x99: - out = ~(dst ^ src); - break; - case 0x9a: - out = dst ^ (pattern & ~src); - break; - case 0x9b: - out = ~(src ^ (dst & (pattern | src))); - break; - case 0x9c: - out = src ^ (pattern & ~dst); - break; - case 0x9d: - out = ~(dst ^ (src & (pattern | dst))); - break; - case 0x9e: - out = dst ^ (src ^ (pattern | (dst & src))); - break; - case 0x9f: - out = ~(pattern & (dst ^ src)); - break; - case 0xa0: - out = dst & pattern; - break; - case 0xa1: - out = ~(pattern ^ (dst | (src & ~pattern))); - break; - case 0xa2: - out = dst & (pattern | ~src); - break; - case 0xa3: - out = ~(dst ^ (pattern | (src ^ dst))); - break; - case 0xa4: - out = ~(pattern ^ (dst | ~(src | pattern))); - break; - case 0xa5: - out = ~(pattern ^ dst); - break; - case 0xa6: - out = dst ^ (src & ~pattern); - break; - case 0xa7: - out = ~(pattern ^ (dst & (src | pattern))); - break; - case 0xa8: - out = dst & (pattern | src); - break; - case 0xa9: - out = ~(dst ^ (pattern | src)); - break; - case 0xaa: - out = dst; - break; - case 0xab: - out = dst | ~(pattern | src); - break; - case 0xac: - out = src ^ (pattern & (dst ^ src)); - break; - case 0xad: - out = ~(dst ^ (pattern | (src & dst))); - break; - case 0xae: - out = dst | (src & ~pattern); - break; - case 0xaf: - out = dst | ~pattern; - break; - case 0xb0: - out = pattern & (dst | ~src); - break; - case 0xb1: - out = ~(pattern ^ (dst | (src ^ pattern))); - break; - case 0xb2: - out = src ^ ((src ^ pattern) | (dst ^ src)); - break; - case 0xb3: - out = ~(src & ~(dst & pattern)); - break; - case 0xb4: - out = pattern ^ (src & ~dst); - break; - case 0xb5: - out = ~(dst ^ (pattern & (src | dst))); - break; - case 0xb6: - out = dst ^ (pattern ^ (src | (dst & pattern))); - break; - case 0xb7: - out = ~(src & (dst ^ pattern)); - break; - case 0xb8: - out = pattern ^ (src & (dst ^ pattern)); - break; - case 0xb9: - out = ~(dst ^ (src | (pattern & dst))); - break; - case 0xba: - out = dst | (pattern & ~src); - break; - case 0xbb: - out = dst | ~src; - break; - case 0xbc: - out = src ^ (pattern & ~(dst & src)); - break; - case 0xbd: - out = ~((src ^ dst) & (pattern ^ dst)); - break; - case 0xbe: - out = dst | (pattern ^ src); - break; - case 0xbf: - out = dst | ~(pattern & src); - break; - case 0xc0: - out = pattern & src; - break; - case 0xc1: - out = ~(src ^ (pattern | (dst & ~src))); - break; - case 0xc2: - out = ~(src ^ (pattern | ~(dst | src))); - break; - case 0xc3: - out = ~(pattern ^ src); - break; - case 0xc4: - out = src & (pattern | ~dst); - break; - case 0xc5: - out = ~(src ^ (pattern | (dst ^ src))); - break; - case 0xc6: - out = src ^ (dst & ~pattern); - break; - case 0xc7: - out = ~(pattern ^ (src & (dst | pattern))); - break; - case 0xc8: - out = src & (dst | pattern); - break; - case 0xc9: - out = ~(src ^ (pattern | dst)); - break; - case 0xca: - out = dst ^ (pattern & (src ^ dst)); - break; - case 0xcb: - out = ~(src ^ (pattern | (dst & src))); - break; - case 0xcc: - out = src; - break; - case 0xcd: - out = src | ~(dst | pattern); - break; - case 0xce: - out = src | (dst & ~pattern); - break; - case 0xcf: - out = src | ~pattern; - break; - case 0xd0: - out = pattern & (src | ~dst); - break; - case 0xd1: - out = ~(pattern ^ (src | (dst ^ pattern))); - break; - case 0xd2: - out = pattern ^ (dst & ~src); - break; - case 0xd3: - out = ~(src ^ (pattern & (dst | src))); - break; - case 0xd4: - out = src ^ ((src ^ pattern) & (pattern ^ dst)); - break; - case 0xd5: - out = ~(dst & ~(pattern & src)); - break; - case 0xd6: - out = pattern ^ (src ^ (dst | (pattern & src))); - break; - case 0xd7: - out = ~(dst & (pattern ^ src)); - break; - case 0xd8: - out = pattern ^ (dst & (src ^ pattern)); - break; - case 0xd9: - out = ~(src ^ (dst | (pattern & src))); - break; - case 0xda: - out = dst ^ (pattern & ~(src & dst)); - break; - case 0xdb: - out = ~((src ^ pattern) & (dst ^ src)); - break; - case 0xdc: - out = src | (pattern & ~dst); - break; - case 0xdd: - out = src | ~dst; - break; - case 0xde: - out = src | (dst ^ pattern); - break; - case 0xdf: - out = src | ~(dst & pattern); - break; - case 0xe0: - out = pattern & (dst | src); - break; - case 0xe1: - out = ~(pattern ^ (dst | src)); - break; - case 0xe2: - out = dst ^ (src & (pattern ^ dst)); - break; - case 0xe3: - out = ~(pattern ^ (src | (dst & pattern))); - break; - case 0xe4: - out = src ^ (dst & (pattern ^ src)); - break; - case 0xe5: - out = ~(pattern ^ (dst | (src & pattern))); - break; - case 0xe6: - out = src ^ (dst & ~(pattern & src)); - break; - case 0xe7: - out = ~((src ^ pattern) & (pattern ^ dst)); - break; - case 0xe8: - out = src ^ ((src ^ pattern) & (dst ^ src)); - break; - case 0xe9: - out = ~(dst ^ (src ^ (pattern & ~(dst & src)))); - break; - case 0xea: - out = dst | (pattern & src); - break; - case 0xeb: - out = dst | ~(pattern ^ src); - break; - case 0xec: - out = src | (dst & pattern); - break; - case 0xed: - out = src | ~(dst ^ pattern); - break; - case 0xee: - out = dst | src; - break; - case 0xef: - out = src | (dst | ~pattern); - break; - case 0xf0: - out = pattern; - break; - case 0xf1: - out = pattern | ~(dst | src); - break; - case 0xf2: - out = pattern | (dst & ~src); - break; - case 0xf3: - out = pattern | ~src; - break; - case 0xf4: - out = pattern | (src & ~dst); - break; - case 0xf5: - out = pattern | ~dst; - break; - case 0xf6: - out = pattern | (dst ^ src); - break; - case 0xf7: - out = pattern | ~(dst & src); - break; - case 0xf8: - out = pattern | (dst & src); - break; - case 0xf9: - out = pattern | ~(dst ^ src); - break; - case 0xfa: - out = dst | pattern; - break; - case 0xfb: - out = dst | (pattern | ~src); - break; - case 0xfc: - out = pattern | src; - break; - case 0xfd: - out = pattern | (src | ~dst); - break; - case 0xfe: - out = dst | (pattern | src); - break; - case 0xff: - out = ~0; - break; - } - - return out; -} \ No newline at end of file diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index f1d755dba..98a9cb385 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -11,7 +11,7 @@ # Authors: David HrdliÄka, # # Copyright 2020-2021 David HrdliÄka. -# Copyright 2025 Connor Hyde / starfrost +# Copyright 2025 starfrost # add_library(vid OBJECT @@ -136,77 +136,12 @@ add_library(vid OBJECT # Matrox vid_mga.c - # NVidia - Core - nv/nv_base.c + # NVidia (pending) nv/nv_rivatimer.c - # NVidia NV1 - nv/nv1/nv1_core.c - nv/nv1/nv1_core_config.c - - # NVidia RIVA 128 - Subsystems - nv/nv3/nv3_core.c - nv/nv3/nv3_core_config.c - nv/nv3/nv3_core_arbiter.c - - nv/nv3/subsystems/nv3_pramdac.c - nv/nv3/subsystems/nv3_pfifo.c - nv/nv3/subsystems/nv3_pgraph.c - nv/nv3/subsystems/nv3_pmc.c - nv/nv3/subsystems/nv3_pme.c - nv/nv3/subsystems/nv3_pextdev.c - nv/nv3/subsystems/nv3_pfb.c - nv/nv3/subsystems/nv3_pbus.c - nv/nv3/subsystems/nv3_pbus_dma.c - nv/nv3/subsystems/nv3_ptimer.c - nv/nv3/subsystems/nv3_pramin.c - nv/nv3/subsystems/nv3_pramin_ramht.c - nv/nv3/subsystems/nv3_pramin_ramfc.c - nv/nv3/subsystems/nv3_pramin_ramro.c - nv/nv3/subsystems/nv3_pvideo.c - nv/nv3/subsystems/nv3_user.c - - # NVidia RIVA 128 - Object Classes - nv/nv3/classes/nv3_class_names.c - nv/nv3/classes/nv3_class_shared_methods.c - nv/nv3/classes/nv3_class_001_beta_factor.c - nv/nv3/classes/nv3_class_002_rop.c - nv/nv3/classes/nv3_class_003_chroma_key.c - nv/nv3/classes/nv3_class_004_plane_mask.c - nv/nv3/classes/nv3_class_005_clipping_rectangle.c - nv/nv3/classes/nv3_class_006_pattern.c - nv/nv3/classes/nv3_class_007_rectangle.c - nv/nv3/classes/nv3_class_008_point.c - nv/nv3/classes/nv3_class_009_line.c - nv/nv3/classes/nv3_class_00a_lin.c - nv/nv3/classes/nv3_class_00b_triangle.c - nv/nv3/classes/nv3_class_00c_win95_gdi_text.c - nv/nv3/classes/nv3_class_00d_m2mf.c - nv/nv3/classes/nv3_class_00e_scaled_image_from_mem.c - nv/nv3/classes/nv3_class_010_blit.c - nv/nv3/classes/nv3_class_011_image.c - nv/nv3/classes/nv3_class_012_bitmap.c - nv/nv3/classes/nv3_class_014_transfer2memory.c - nv/nv3/classes/nv3_class_015_stretched_image_from_cpu.c - nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c - nv/nv3/classes/nv3_class_018_point_zeta_buffer.c - nv/nv3/classes/nv3_class_01c_image_in_memory.c - - # NVidia RIVA 128 - Render - nv/nv3/render/nv3_render_core.c - nv/nv3/render/nv3_render_primitives.c - nv/nv3/render/nv3_render_blit.c - - # NVidia RIVA TNT/TNT2 - Core - nv/nv4/nv4_core.c - nv/nv4/nv4_core_io.c - nv/nv4/nv4_core_config.c - nv/nv4/nv4_debug_register_list.c - nv/nv4/subsystems/nv4_pramdac.c - nv/nv4/subsystems/nv4_ptimer.c - # Generic vid_bochs_vbe.c + ) if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") diff --git a/src/video/nv/nv1/nv1_core.c b/src/video/nv/nv1/nv1_core.c deleted file mode 100644 index 3de528b26..000000000 --- a/src/video/nv/nv1/nv1_core.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 bringup and device emulation. - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv1.h> - - -void nv1_init() -{ - -} - -void* nv1_init_edge2k(const device_t *info) -{ - -} - -void* nv1_init_edge3k(const device_t *info) -{ - -} - -void nv1_close(void* priv) -{ - -} - -void nv1_speed_changed(void *priv) -{ - -} - -void nv1_draw_cursor(svga_t* svga, int32_t drawline) -{ - -} - -void nv1_recalc_timings(svga_t* svga) -{ - -} - -void nv1_force_redraw(void* priv) -{ - -} - -// See if the bios rom is available. -int32_t nv1_available(void) -{ - return (rom_present(NV1_VBIOS_E3D_2X00) - || rom_present(NV1_VBIOS_E3D_3X00)); -} - -// NV3 (RIVA 128) -// PCI -// 2MB or 4MB VRAM -const device_t nv1_device_edge2k = -{ - .name = "nVIDIA NV1 [Diamond Edge 3D 2x00] [Not Direct3D Compatible]", - .internal_name = "nv1_edge2k", - .flags = DEVICE_PCI, - .local = 0, - .init = nv1_init_edge2k, - .close = nv1_close, - .speed_changed = nv1_speed_changed, - .force_redraw = nv1_force_redraw, - .available = nv1_available, - .config = nv1_config, -}; - -// NV3 (RIVA 128) -// AGP -// 2MB or 4MB VRAM -const device_t nv1_device_edge3k = -{ - .name = "nVIDIA NV1 [Diamond Edge 3D 3x00] [Not Direct3D Compatible]", - .internal_name = "nv1_edge3k", - .flags = DEVICE_PCI, - .local = 0, - .init = nv1_init_edge3k, - .close = nv1_close, - .speed_changed = nv1_speed_changed, - .force_redraw = nv1_force_redraw, - .available = nv1_available, - .config = nv1_config, -}; diff --git a/src/video/nv/nv1/nv1_core_config.c b/src/video/nv/nv1/nv1_core_config.c deleted file mode 100644 index 460067f6f..000000000 --- a/src/video/nv/nv1/nv1_core_config.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Provides NV4 configuration - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv1.h> - -const device_config_t nv1_config[] = -{ - // Memory configuration - { - .name = "vram_size", - .description = "VRAM Size", - .type = CONFIG_SELECTION, - .default_int = NV1_VRAM_SIZE_4MB, - .selection = - { - // I thought this was never released, but it seems that at least one was released: - // The card was called the "NEC G7AGK" - { - .description = "1 MB", - .value = NV1_VRAM_SIZE_1MB, - }, - { - .description = "2 MB", - .value = NV1_VRAM_SIZE_2MB, - }, - { - .description = "4 MB", - .value = NV1_VRAM_SIZE_4MB, - }, - } - - }, - // Multithreading configuration - { - - .name = "pgraph_threads", -#ifndef RELEASE_BUILD - .description = "PFIFO/PGRAPH - Number of threads to split large object method execution into", -#else - .description = "Render threads", -#endif - .type = CONFIG_SELECTION, - .default_int = 1, // todo: change later - .selection = - { - { - .description = "1 thread (Only use if issues appear with more threads)", - .value = 1, - }, - { - .description = "2 threads", - .value = 2, - }, - { - .description = "4 threads", - .value = 4, - }, - { - .description = "8 threads", - .value = 8, - }, - }, - }, - { - .name = "RAMDAC Type", - .description = "SGS-Thomson RAMDAC type", - .default_int = 0x1764, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "SGS-Thomson STG-1732X", - .value = 0x1732, - }, - { - .description = "SGS-Thomson STG-1764X/NVDAC64", - .value = 0x1764, - }, - } - }, - { - .name = "Chip type", - .description = "Chip type", - .default_int = 0x1, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "SGS-Thomson STG-2000", - .value = 0x2000, - }, - { - .description = "Nvidia NV1", - .value = 0x1, - }, - } - }, -#ifndef RELEASE_BUILD - { - .name = "nv_debug_fulllog", - .description = "Disable Cyclical Lines Detection for nv_log (Use for getting full context at cost of VERY large log files)", - .type = CONFIG_BINARY, - .default_int = 0, - }, -#endif - { - .type = CONFIG_END - } -}; \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_001_beta_factor.c b/src/video/nv/nv3/classes/nv3_class_001_beta_factor.c deleted file mode 100644 index 4520a941f..000000000 --- a/src/video/nv/nv3/classes/nv3_class_001_beta_factor.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x01 (Beta factor) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_001_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - /* even if we don't do anything with this yet... */ - case NV3_BETA_FACTOR: - if (param & 0x80000000) /* bit0 */ - nv3->pgraph.beta_factor = 0; - else - nv3->pgraph.beta_factor = param & 0x7F800000; - - nv_log("Method Execution: Beta Factor = %02x", nv3->pgraph.beta_factor); - - break; - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_002_rop.c b/src/video/nv/nv3/classes/nv3_class_002_rop.c deleted file mode 100644 index 56b135888..000000000 --- a/src/video/nv/nv3/classes/nv3_class_002_rop.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x02 (Render operation) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_002_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - case NV3_ROP_SET_ROP: - nv3->pgraph.rop = param & 0xFF; - nv_log("Method Execution: ROP = %02x\n", nv3->pgraph.rop); - break; - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_003_chroma_key.c b/src/video/nv/nv3/classes/nv3_class_003_chroma_key.c deleted file mode 100644 index f19a06932..000000000 --- a/src/video/nv/nv3/classes/nv3_class_003_chroma_key.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x02 (Chroma/color key) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_003_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - case NV3_CHROMA_UNKNOWN_0200: - nv_log("Method Execution: Chroma Unknown 0x0200 0x%08x", param); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - - break; - case NV3_CHROMA_KEY: - { - nv3_color_expanded_t expanded_color = nv3_render_expand_color(param, grobj); - - nv3->pgraph.chroma_key = nv3_render_to_chroma(expanded_color); - - nv_log("Method Execution: Chroma = 0x%08x", nv3->pgraph.chroma_key); - break; - } - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_004_plane_mask.c b/src/video/nv/nv3/classes/nv3_class_004_plane_mask.c deleted file mode 100644 index d93de9bc1..000000000 --- a/src/video/nv/nv3/classes/nv3_class_004_plane_mask.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x02 (Plane mask) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_004_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_005_clipping_rectangle.c b/src/video/nv/nv3/classes/nv3_class_005_clipping_rectangle.c deleted file mode 100644 index c7ec3ae98..000000000 --- a/src/video/nv/nv3/classes/nv3_class_005_clipping_rectangle.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x05 (Clipping rectangle) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_005_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - case NV3_CLIP_POSITION: - nv3->pgraph.clip_start.x = (param >> 16) & 0xFFFF; - nv3->pgraph.clip_start.y = (param) & 0xFFFF; - nv_log("Method Execution: Clip Position: %d,%d\n", nv3->pgraph.clip_start.x, nv3->pgraph.clip_start.y); - break; - case NV3_CLIP_SIZE: - nv3->pgraph.clip_size.x = (param >> 16) & 0xFFFF; - nv3->pgraph.clip_size.y = (param) & 0xFFFF; - nv_log("Method Execution: Clip Size: %d,%d\n", nv3->pgraph.clip_start.x, nv3->pgraph.clip_start.y); - break; - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_006_pattern.c b/src/video/nv/nv3/classes/nv3_class_006_pattern.c deleted file mode 100644 index 5aa5bf0fc..000000000 --- a/src/video/nv/nv3/classes/nv3_class_006_pattern.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x06 (Pattern) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_006_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - /* Valid software method, suppress logging */ - case NV3_PATTERN_FORMAT: - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - case NV3_PATTERN_SHAPE: - /* If the shape is not valid, tell the software that it's invalid */ - - /* - Technically you are meant to do this: - - But in practice, I don't know, because it always submits 0x20 or 0x40, which are valid when param & 0x03, - and appear to be deliberate behaviour in the drivers rather than bugs. What - if (param > NV3_PATTERN_SHAPE_LAST_VALID) - { - warning("NV3 class 0x06 (Pattern) invalid shape %d (This is a bug)", param); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_INVALID_DATA); - return; - } - - */ - nv3->pgraph.pattern_shape = param & 0x03; - - break; - /* Seems to be "SetPatternSelect" on Riva TNT and later, but possibly called by accident on Riva 128. There is no hardware equivalent for this. So let's just suppress - the warnings. */ - case NV3_PATTERN_UNUSED_DRIVER_BUG: - break; - case NV3_PATTERN_COLOR0: - { - nv3_color_expanded_t expanded_colour0 = nv3_render_expand_color(param, grobj); - nv3_render_set_pattern_color(expanded_colour0, false); - break; - } - case NV3_PATTERN_COLOR1: - { - nv3_color_expanded_t expanded_colour1 = nv3_render_expand_color(param, grobj); - nv3_render_set_pattern_color(expanded_colour1, true); - break; - } - case NV3_PATTERN_BITMAP_HIGH: - nv3->pgraph.pattern_bitmap = 0; //reset - nv3->pgraph.pattern_bitmap |= ((uint64_t)param << 32); - break; - case NV3_PATTERN_BITMAP_LOW: - nv3->pgraph.pattern_bitmap |= param; - break; - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_007_rectangle.c b/src/video/nv/nv3/classes/nv3_class_007_rectangle.c deleted file mode 100644 index d1273a84a..000000000 --- a/src/video/nv/nv3/classes/nv3_class_007_rectangle.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x07 (Rectangle) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_007_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - case NV3_RECTANGLE_COLOR: - nv3->pgraph.rectangle.color = param; - break; - default: - /* Check for any rectangle point or size method. */ - if (method_id >= NV3_RECTANGLE_START && method_id <= NV3_RECTANGLE_END) - { - uint32_t index = (method_id - NV3_RECTANGLE_START) >> 3; - - // If the size is submitted, render it. - if (method_id & 0x04) - { - nv3->pgraph.rectangle.size[index].x = param & 0xFFFF; - nv3->pgraph.rectangle.size[index].y = (param >> 16) & 0xFFFF; - - nv_log("Method Execution: Rect%d Size=%d,%d Color=0x%08x\n", index, nv3->pgraph.rectangle.size[index].x, nv3->pgraph.rectangle.size[index].y, nv3->pgraph.rectangle.color); - - nv3_render_rect(nv3->pgraph.rectangle.position[index], nv3->pgraph.rectangle.size[index], nv3->pgraph.rectangle.color, grobj); - } - else // position - { - nv3->pgraph.rectangle.position[index].x = param & 0xFFFF; - nv3->pgraph.rectangle.position[index].y = (param >> 16) & 0xFFFF; - - nv_log("Method Execution: Rect%d Position=%d,%d\n", index, nv3->pgraph.rectangle.position[index].x, nv3->pgraph.rectangle.position[index].y); - } - - return; - } - - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_008_point.c b/src/video/nv/nv3/classes/nv3_class_008_point.c deleted file mode 100644 index 41002f745..000000000 --- a/src/video/nv/nv3/classes/nv3_class_008_point.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x08 (Point) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_008_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_009_line.c b/src/video/nv/nv3/classes/nv3_class_009_line.c deleted file mode 100644 index f149bb8b3..000000000 --- a/src/video/nv/nv3/classes/nv3_class_009_line.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x09 (Line) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_009_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_00a_lin.c b/src/video/nv/nv3/classes/nv3_class_00a_lin.c deleted file mode 100644 index 473aaa214..000000000 --- a/src/video/nv/nv3/classes/nv3_class_00a_lin.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x0A (Lin - a line without starting or ending pixels) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_00a_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_00b_triangle.c b/src/video/nv/nv3/classes/nv3_class_00b_triangle.c deleted file mode 100644 index d08b7a72e..000000000 --- a/src/video/nv/nv3/classes/nv3_class_00b_triangle.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x0B (Basic triangle) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_00b_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c b/src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c deleted file mode 100644 index 64d76c278..000000000 --- a/src/video/nv/nv3/classes/nv3_class_00c_win95_gdi_text.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x0C (Windows 95 GDI text acceleration) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_00c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - /* Type A: Unclipped Rectangle */ - - /* NOTE: This method is used by the GDI driver as part of the notification engine. */ - case NV3_W95TXT_A_COLOR: - nv3->pgraph.win95_gdi_text.color_a = param; - nv_log("Method Execution: GDI-A Color 0x%08x\n", nv3->pgraph.win95_gdi_text.color_a); - break; - /* Type B: Clipped Rectangle */ - case NV3_W95TXT_B_COLOR: - nv3->pgraph.win95_gdi_text.color_b = param; - nv_log("Method Execution: GDI-B Color 0x%08x\n", nv3->pgraph.win95_gdi_text.color_b); - break; - case NV3_W95TXT_B_CLIP_TOPLEFT: - nv3->pgraph.win95_gdi_text.clip_b.left = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_b.top = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-B Clip Left,Top %04x,%04x", nv3->pgraph.win95_gdi_text.clip_b.left, nv3->pgraph.win95_gdi_text.clip_b.top); - break; - case NV3_W95TXT_B_CLIP_BOTTOMRIGHT: - nv3->pgraph.win95_gdi_text.clip_b.bottom = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_b.right = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-B Clip Bottom,Right %04x,%04x", nv3->pgraph.win95_gdi_text.clip_b.right, nv3->pgraph.win95_gdi_text.clip_b.bottom); - break; - /* Type C: Unclipped Bitmap */ - case NV3_W95TXT_C_CLIP_COLOR: - nv3->pgraph.win95_gdi_text.color1_c = param; - nv_log("Method Execution: GDI-C Color 0x%08x\n", nv3->pgraph.win95_gdi_text.color1_c); - break; - case NV3_W95TXT_C_CLIP_SIZE: - nv3->pgraph.win95_gdi_text.size_c.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.size_c.y = ((param >> 16) & 0xFFFF); - - nv3->pgraph.win95_gdi_text_bit_count = 0; - nv_log("Method Execution: GDI-C Size In %04x,%04x\n", nv3->pgraph.win95_gdi_text.size_c.x, nv3->pgraph.win95_gdi_text.size_c.y); - break; - case NV3_W95TXT_C_CLIP_POSITION: - nv3->pgraph.win95_gdi_text.point_c.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.point_c.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-C Point %04x,%04x\n", nv3->pgraph.win95_gdi_text.point_c.x, nv3->pgraph.win95_gdi_text.point_c.y); - - nv3->pgraph.win95_gdi_text_current_position.x = nv3->pgraph.win95_gdi_text.point_c.x ; - nv3->pgraph.win95_gdi_text_current_position.y = nv3->pgraph.win95_gdi_text.point_c.y; - - break; - case NV3_W95TXT_C_CLIP_TOPLEFT: - nv3->pgraph.win95_gdi_text.clip_c.left = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_c.top = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-C Clip Left,Top %04x,%04x\n", nv3->pgraph.win95_gdi_text.clip_c.left, nv3->pgraph.win95_gdi_text.clip_c.top); - break; - case NV3_W95TXT_C_CLIP_BOTTOMRIGHT: - nv3->pgraph.win95_gdi_text.clip_c.right = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_c.bottom = ((param >> 16) & 0xFFFF); - /* is it "only if we are out of the top left or the bottom right or is it "all of them"*/ - nv_log("Method Execution: GDI-C Clip Right,Bottom %04x,%04x\n", nv3->pgraph.win95_gdi_text.clip_c.left, nv3->pgraph.win95_gdi_text.clip_c.top); - break; - /* Type B and C not implemented YET, as they are not used by NT GDI driver */ - case NV3_W95TXT_D_CLIP_TOPLEFT: - nv3->pgraph.win95_gdi_text.clip_d.left = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_d.top = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-D Clip Left,Top %04x,%04x\n", nv3->pgraph.win95_gdi_text.clip_d.left, nv3->pgraph.win95_gdi_text.clip_d.top); - break; - case NV3_W95TXT_D_CLIP_BOTTOMRIGHT: - nv3->pgraph.win95_gdi_text.clip_d.right = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_d.bottom = ((param >> 16) & 0xFFFF); - /* is it "only if we are out of the top left or the bottom right or is it "all of them"*/ - nv_log("Method Execution: GDI-D Clip Right,Bottom %04x,%04x\n", nv3->pgraph.win95_gdi_text.clip_d.left, nv3->pgraph.win95_gdi_text.clip_d.top); - break; - - case NV3_W95TXT_D_CLIP_COLOR: - nv3->pgraph.win95_gdi_text.color1_d = param; - nv_log("Method Execution: GDI-D Color 0x%08x\n", nv3->pgraph.win95_gdi_text.color_a); - break; - case NV3_W95TXT_D_CLIP_SIZE_IN: - nv3->pgraph.win95_gdi_text.size_in_d.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.size_in_d.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-D Size In %04x,%04x\n", nv3->pgraph.win95_gdi_text.size_in_d.x, nv3->pgraph.win95_gdi_text.size_in_d.y); - break; - case NV3_W95TXT_D_CLIP_SIZE_OUT: - nv3->pgraph.win95_gdi_text.size_out_d.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.size_out_d.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-D Size Out %04x,%04x\n", nv3->pgraph.win95_gdi_text.size_out_d.x, nv3->pgraph.win95_gdi_text.size_out_d.y); - break; - case NV3_W95TXT_D_CLIP_POSITION: - nv3->pgraph.win95_gdi_text.point_d.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.point_d.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-D Point %04x,%04x\n", nv3->pgraph.win95_gdi_text.point_d.x, nv3->pgraph.win95_gdi_text.point_d.y); - - nv3->pgraph.win95_gdi_text_current_position.x = nv3->pgraph.win95_gdi_text.point_d.x; - nv3->pgraph.win95_gdi_text_current_position.y = nv3->pgraph.win95_gdi_text.point_d.y; - nv3->pgraph.win95_gdi_text_bit_count = 0; - - break; - /* Type E: Two-colour 1bpp */ - case NV3_W95TXT_E_CLIP_TOPLEFT: - nv3->pgraph.win95_gdi_text.clip_e.left = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_e.top = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-E Clip Left,Top 0x%08x\n", nv3->pgraph.win95_gdi_text.clip_e.left, nv3->pgraph.win95_gdi_text.clip_e.top); - break; - case NV3_W95TXT_E_CLIP_BOTTOMRIGHT: - nv3->pgraph.win95_gdi_text.clip_e.right = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clip_e.bottom = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-E Clip Bottom,Right 0x%08x\n", nv3->pgraph.win95_gdi_text.clip_e.right, nv3->pgraph.win95_gdi_text.clip_e.bottom); - /* is it "only if we are out of the top left or the bottom right or is it "all of them"*/ - break; - case NV3_W95TXT_E_CLIP_COLOR_0: - nv3->pgraph.win95_gdi_text.color0_e = param; - nv_log("Method Execution: GDI-E Color0 0x%08x\n", nv3->pgraph.win95_gdi_text.color_a); - break; - case NV3_W95TXT_E_CLIP_COLOR_1: - nv3->pgraph.win95_gdi_text.color1_e = param; - nv_log("Method Execution: GDI-E Color1 0x%08x\n", nv3->pgraph.win95_gdi_text.color_a); - break; - case NV3_W95TXT_E_CLIP_SIZE_IN: - nv3->pgraph.win95_gdi_text.size_in_e.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.size_in_e.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-E Size In %04x,%04x\n", nv3->pgraph.win95_gdi_text.size_in_e.x, nv3->pgraph.win95_gdi_text.size_in_e.y); - break; - case NV3_W95TXT_E_CLIP_SIZE_OUT: - nv3->pgraph.win95_gdi_text.size_out_e.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.size_out_e.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: GDI-E Size Out %04x,%04x\n", nv3->pgraph.win95_gdi_text.size_out_e.x, nv3->pgraph.win95_gdi_text.size_out_e.y); - break; - case NV3_W95TXT_E_CLIP_POSITION: - nv3->pgraph.win95_gdi_text.point_e.x = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.point_e.y = ((param >> 16) & 0xFFFF); - - nv3->pgraph.win95_gdi_text_current_position.x = nv3->pgraph.win95_gdi_text.point_e.x; - nv3->pgraph.win95_gdi_text_current_position.y = nv3->pgraph.win95_gdi_text.point_e.y; - nv3->pgraph.win95_gdi_text_bit_count = 0; - - nv_log("Method Execution: GDI-E Point %04x,%04x\n", nv3->pgraph.win95_gdi_text.point_e.x, nv3->pgraph.win95_gdi_text.point_e.y); - break; - default: - /* Type A submission: these are the same things as rectangles */ - if (method_id >= NV3_W95TXT_A_RECT_START && method_id <= NV3_W95TXT_A_RECT_END) - { - uint32_t index = (method_id - NV3_W95TXT_A_RECT_START) >> 3; - - // IN THIS ONE SPECIFIC PLACE, ****AND ONLY THIS ONE SPECIFIC PLACE****, X AND Y ARE SWAPPED???? */ - // If the size is submitted, render it. - if (method_id & 0x04) - { - nv3->pgraph.win95_gdi_text.rect_a_size[index].x = (param >> 16) & 0xFFFF; - nv3->pgraph.win95_gdi_text.rect_a_size[index].y = param & 0xFFFF; - - nv_log("Method Execution: Rect GDI-A%d Size=%d,%d", index, nv3->pgraph.win95_gdi_text.rect_a_size[index].x, - nv3->pgraph.win95_gdi_text.rect_a_size[index].y); - - nv3_render_rect(nv3->pgraph.win95_gdi_text.rect_a_position[index], - nv3->pgraph.win95_gdi_text.rect_a_size[index], nv3->pgraph.win95_gdi_text.color_a, grobj); - } - else // position - { - nv3->pgraph.win95_gdi_text.rect_a_position[index].x = (param >> 16) & 0xFFFF; - nv3->pgraph.win95_gdi_text.rect_a_position[index].y = param & 0xFFFF; - - nv_log("Method Execution: Rect GDI-A%d Position=%d,%d\n", index, - nv3->pgraph.win95_gdi_text.rect_a_position[index].x, nv3->pgraph.win95_gdi_text.rect_a_position[index].y); - } - - return; - } - /* Type B: Clipped Rectangle */ - else if (method_id >= NV3_W95TXT_B_CLIP_CLIPRECT_START && method_id <= NV3_W95TXT_B_CLIP_CLIPRECT_END) - { - uint32_t index = (method_id - NV3_W95TXT_B_CLIP_CLIPRECT_START) >> 3; - - /* Works slightly differently, we define the bounds of the rectangle instead. */ - if (method_id & 0x04) - { - nv3->pgraph.win95_gdi_text.clipped_rect[index].right = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clipped_rect[index].bottom = ((param >> 16) & 0xFFFF); - - nv_log("Method Execution: Rect GDI-B%d Right,Bottom=%d,%d\n", index, nv3->pgraph.win95_gdi_text.clipped_rect[index].right, - nv3->pgraph.win95_gdi_text.clipped_rect[index].bottom); - - nv3_render_rect_clipped(nv3->pgraph.win95_gdi_text.clipped_rect[index], - nv3->pgraph.win95_gdi_text.color_b, grobj); - } - else // left,top - { - nv3->pgraph.win95_gdi_text.clipped_rect[index].left = (param & 0xFFFF); - nv3->pgraph.win95_gdi_text.clipped_rect[index].top = ((param >> 16) & 0xFFFF); - - nv_log("Method Execution: Rect GDI-B%d Left,Top=%d,%d\n", index, - nv3->pgraph.win95_gdi_text.clipped_rect[index].left, nv3->pgraph.win95_gdi_text.clipped_rect[index].top); - } - - return; - } - /* Type C */ - else if (method_id >= NV3_W95TXT_C_CLIP_CLIPRECT_START && method_id <= NV3_W95TXT_C_CLIP_CLIPRECT_END) - { - /* lol */ - uint32_t index = (method_id - NV3_W95TXT_C_CLIP_CLIPRECT_START) >> 3; - - nv3->pgraph.win95_gdi_text.bitmap_c[index] = param; - - /* Mammoth logger! */ - nv_log("Method Execution: Rect GDI-C%d Data=%08x Size%04x,%04x Point%04x,%04x Color=%08x Clip Left=0x%04x Right=0x%04x Top=0x%04x Bottom=0x%04x", - index, param, nv3->pgraph.win95_gdi_text.size_c.x, nv3->pgraph.win95_gdi_text.size_c.y, - nv3->pgraph.win95_gdi_text.point_c.x, nv3->pgraph.win95_gdi_text.point_c.y, - nv3->pgraph.win95_gdi_text.color1_c, - nv3->pgraph.win95_gdi_text.clip_c.left, nv3->pgraph.win95_gdi_text.clip_c.right, - nv3->pgraph.win95_gdi_text.clip_c.top, nv3->pgraph.win95_gdi_text.clip_c.bottom); - - nv3_render_gdi_transparent_bitmap(false, nv3->pgraph.win95_gdi_text.color1_c, nv3->pgraph.win95_gdi_text.bitmap_c[index], grobj); - return; - } - else if (method_id >= NV3_W95TXT_D_CLIP_CLIPRECT_START && method_id <= NV3_W95TXT_D_CLIP_CLIPRECT_END) - { - /* lol */ - uint32_t index = (method_id - NV3_W95TXT_D_CLIP_CLIPRECT_START) >> 3; - - nv3->pgraph.win95_gdi_text.bitmap_d[index] = param; - - /* Mammoth logger! */ - nv_log("Method Execution: Rect GDI-D%d Data=%08x SizeIn%04x,%04x SizeOut%04x,%04x Point%04x,%04x Color=%08x Clip Left=0x%04x Right=0x%04x Top=0x%04x Bottom=0x%04x", - index, param, nv3->pgraph.win95_gdi_text.size_in_d.x, nv3->pgraph.win95_gdi_text.size_in_d.y, - nv3->pgraph.win95_gdi_text.size_out_d.x, nv3->pgraph.win95_gdi_text.size_out_d.y, - nv3->pgraph.win95_gdi_text.point_d.x, nv3->pgraph.win95_gdi_text.point_d.y, - nv3->pgraph.win95_gdi_text.color1_d, - nv3->pgraph.win95_gdi_text.clip_d.left, nv3->pgraph.win95_gdi_text.clip_d.right, - nv3->pgraph.win95_gdi_text.clip_d.top, nv3->pgraph.win95_gdi_text.clip_d.bottom); - - nv3_render_gdi_transparent_bitmap(true, nv3->pgraph.win95_gdi_text.color1_d, nv3->pgraph.win95_gdi_text.bitmap_d[index], grobj); - return; - } - else if (method_id >= NV3_W95TXT_E_CLIP_CLIPRECT_START && method_id <= NV3_W95TXT_E_CLIP_CLIPRECT_END) - { - /* lol */ - uint32_t index = (method_id - NV3_W95TXT_E_CLIP_CLIPRECT_START) >> 3; - - nv3->pgraph.win95_gdi_text.bitmap_e[index] = param; - - /* Mammoth logger! */ - nv_log("Method Execution: Rect GDI-E%d Data=%08x SizeIn%04x,%04x SizeOut%04x,%04x Point%04x,%04x Color=%08x Clip Left=0x%04x Right=0x%04x Top=0x%04x Bottom=0x%04x", - index, param, nv3->pgraph.win95_gdi_text.size_in_e.x, nv3->pgraph.win95_gdi_text.size_in_e.y, - nv3->pgraph.win95_gdi_text.size_out_e.x, nv3->pgraph.win95_gdi_text.size_out_e.y, - nv3->pgraph.win95_gdi_text.point_e.x, nv3->pgraph.win95_gdi_text.point_e.y, - nv3->pgraph.win95_gdi_text.color1_e, - nv3->pgraph.win95_gdi_text.clip_e.left, nv3->pgraph.win95_gdi_text.clip_e.right, nv3->pgraph.win95_gdi_text.clip_e.top, nv3->pgraph.win95_gdi_text.clip_e.bottom); - - nv3_render_gdi_1bpp_bitmap(nv3->pgraph.win95_gdi_text.color0_e, nv3->pgraph.win95_gdi_text.color1_e, nv3->pgraph.win95_gdi_text.bitmap_e[index], grobj); - return; - } - - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_00d_m2mf.c b/src/video/nv/nv3/classes/nv3_class_00d_m2mf.c deleted file mode 100644 index f07aab737..000000000 --- a/src/video/nv/nv3/classes/nv3_class_00d_m2mf.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x0D (Reformat image in memory) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_00d_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - case NV3_M2MF_IN_CTXDMA_OFFSET: - nv3->pgraph.m2mf.offset_in = param; - nv_log("Method Execution: M2MF Offset In = 0x%08x", param); - break; - case NV3_M2MF_OUT_CTXDMA_OFFSET: - nv3->pgraph.m2mf.offset_out = param; - nv_log("Method Execution: M2MF Offset Out = 0x%08x", param); - break; - case NV3_M2MF_IN_PITCH: - nv3->pgraph.m2mf.pitch_in = param; - nv_log("Method Execution: M2MF Pitch In = 0x%08x", param); - break; - case NV3_M2MF_OUT_PITCH: - nv3->pgraph.m2mf.pitch_out = param; - nv_log("Method Execution: M2MF Pitch Out = 0x%08x", param); - break; - case NV3_M2MF_SCANLINE_LENGTH_IN_BYTES: - nv3->pgraph.m2mf.scanline_length = param; - nv_log("Method Execution: M2MF Scanline Length in Bytes = 0x%08x", param); - break; - case NV3_M2MF_NUM_SCANLINES: - nv3->pgraph.m2mf.num_scanlines = param; - nv_log("Method Execution: M2MF Num Scanlines = 0x%08x", param); - break; - case NV3_M2MF_FORMAT: - nv3->pgraph.m2mf.format = param; - nv_log("Method Execution: M2MF Format = 0x%08x", param); - - // Format Done - start m2mf - - nv3_perform_dma_m2mf(grobj); - - break; - case NV3_M2MF_NOTIFY: - /* This is technically its own thing, but I don't know if it's ever a problem with how we've designed it */ - if (nv3->pgraph.notify_pending) - { - nv_log("WARNING: M2MF notification with notify_pending already set. param=0x%08x, method=0x%04x, grobj=0x%08x 0x%08x 0x%08x 0x%08x\n"); - nv_log("IF THIS BUILD WAS COMPILED WITH NV_LOG_ENABLE_ULTRA, YOU SHOULD SEE A CONTEXT BELOW"); - nv3_debug_ramin_print_context_info(param, context); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY); - - // disable - nv3->pgraph.notify_pending = false; - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY); - /* may need to disable fifo in this state */ - return; - } - - nv_log("Method Execution: TODO: ACTUALLY IMPLEMENT M2MF!!!!"); - // set a notify as pending. - nv3->pgraph.notifier = param; - nv3->pgraph.notify_pending = true; - break; - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break;; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_00e_scaled_image_from_mem.c b/src/video/nv/nv3/classes/nv3_class_00e_scaled_image_from_mem.c deleted file mode 100644 index 457c8ade1..000000000 --- a/src/video/nv/nv3/classes/nv3_class_00e_scaled_image_from_mem.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x0E (Get image from vram and scale it) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_00e_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_010_blit.c b/src/video/nv/nv3/classes/nv3_class_010_blit.c deleted file mode 100644 index ed1ac465b..000000000 --- a/src/video/nv/nv3/classes/nv3_class_010_blit.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x10 (Blit something) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_010_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - case NV3_BLIT_POSITION_IN: - nv3->pgraph.blit.point_in.x = (param & 0xFFFF); - nv3->pgraph.blit.point_in.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: S2SB POINT_IN %d,%d\n", nv3->pgraph.blit.point_in.x, nv3->pgraph.blit.point_in.y); - break; - case NV3_BLIT_POSITION_OUT: - nv3->pgraph.blit.point_out.x = (param & 0xFFFF); - nv3->pgraph.blit.point_out.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: S2SB POINT_OUT %d,%d\n", nv3->pgraph.blit.point_out.x, nv3->pgraph.blit.point_out.y); - - break; - case NV3_BLIT_SIZE: - /* This is the last one*/ - nv3->pgraph.blit.size.x = (param & 0xFFFF); - nv3->pgraph.blit.size.y = ((param >> 16) & 0xFFFF); - nv_log("Method Execution: S2SB Size %d,%d grobj_0=0x%08x\n", nv3->pgraph.blit.size.x, nv3->pgraph.blit.size.y, grobj.grobj_0); - - nv3_render_blit_screen2screen(grobj); - - break; - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_011_image.c b/src/video/nv/nv3/classes/nv3_class_011_image.c deleted file mode 100644 index 1eda15df7..000000000 --- a/src/video/nv/nv3/classes/nv3_class_011_image.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x11 (Color image) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_011_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - case NV3_IMAGE_START_POSITION: - nv3->pgraph.image.point.x = (param & 0xFFFF); - nv3->pgraph.image.point.y = (param >> 16); - nv_log("Method Execution: Image Point=%d,%d\n", nv3->pgraph.image.point.x, nv3->pgraph.image.point.y); - break; - /* Seems to allow scaling of the bitblt. */ - case NV3_IMAGE_SIZE: - nv3->pgraph.image.size.x = (param & 0xFFFF); - nv3->pgraph.image.size.y = (param >> 16); - nv_log("Method Execution: Image Size (Clip)=%d,%d\n", nv3->pgraph.image.size.x, nv3->pgraph.image.size.y); - break; - case NV3_IMAGE_SIZE_IN: - nv3->pgraph.image.size_in.x = (param & 0xFFFF); - nv3->pgraph.image.size_in.y = (param >> 16); - nv3->pgraph.image_current_position = nv3->pgraph.image.point; - nv_log("Method Execution: Image SizeIn=%d,%d\n", nv3->pgraph.image.size_in.x, nv3->pgraph.image.size_in.y); - break; - default: - if (method_id >= NV3_IMAGE_COLOR_START && method_id <= NV3_IMAGE_COLOR_END) - { - uint32_t pixel_slot = (method_id - NV3_IMAGE_COLOR_START) >> 2; - nv_log("Method Execution: Image Pixel%d Colour%08x Format%x\n", pixel_slot, param, (grobj.grobj_0) & 0x07); - nv3_render_blit_image(param, grobj); - } - else - { - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - - } - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_012_bitmap.c b/src/video/nv/nv3/classes/nv3_class_012_bitmap.c deleted file mode 100644 index 2ac47f0de..000000000 --- a/src/video/nv/nv3/classes/nv3_class_012_bitmap.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x12 (Monochrome bitmap) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_012_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_014_transfer2memory.c b/src/video/nv/nv3/classes/nv3_class_014_transfer2memory.c deleted file mode 100644 index b49b1fc89..000000000 --- a/src/video/nv/nv3/classes/nv3_class_014_transfer2memory.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x14 (Transfer to Memory) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_014_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_015_stretched_image_from_cpu.c b/src/video/nv/nv3/classes/nv3_class_015_stretched_image_from_cpu.c deleted file mode 100644 index 3fa88ba39..000000000 --- a/src/video/nv/nv3/classes/nv3_class_015_stretched_image_from_cpu.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x15 (stretched image from cpu to memory) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_015_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c b/src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c deleted file mode 100644 index 3bb8f66d7..000000000 --- a/src/video/nv/nv3/classes/nv3_class_017_d3d5_tri_zeta_buffer.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* NV3: Methods for class 0x17 (Direct3D 5.0 accelerated triangle with zeta buffer) -* -* -* -* Authors: Connor Hyde, I need a better email address ;^) -* -* Copyright 2024-2025 Connor Hyde -*/ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_017_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_018_point_zeta_buffer.c b/src/video/nv/nv3/classes/nv3_class_018_point_zeta_buffer.c deleted file mode 100644 index 87111b70c..000000000 --- a/src/video/nv/nv3/classes/nv3_class_018_point_zeta_buffer.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x18 (Point with zeta buffer) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -struct nv3_object_class_018 nv3_d3d5_point_zeta_buffer; - -void nv3_class_018_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c b/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c deleted file mode 100644 index 12ac3fe6b..000000000 --- a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods for class 0x1C (Image in memory) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_class_01c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - /* We need this for a lot of methods, so may as well store it here. */ - uint32_t src_buffer_id = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER) & 0x03; - - - switch (method_id) - { - /* Color format of the image */ - case NV3_IMAGE_IN_MEMORY_COLOR_FORMAT: - { - // convert to how the bpixel registers represent surface - uint32_t real_format = 1; - - /* TODO: THIS CODE MIGHT BE NONSENSE - Convert between different internal representations of the pixel format, because Nvidia says: I WANT TO MAKE YOUR LIFE PAIN. - */ - switch (param) - { - case nv3_image_in_memory_pixel_format_x8g8b8r8: - real_format = 3; //32bit - // no change - break; - case nv3_image_in_memory_pixel_format_x1r5g5b5_p2: - real_format = 2; - break; - case nv3_image_in_memory_pixel_format_le_y16_p2: - real_format = 0; - break; - } - - /* Set the format */ - - nv3->pgraph.bpixel[src_buffer_id] = (real_format | NV3_BPIXEL_FORMAT_IS_VALID); - - nv_log("Method Execution: Image in Memory BUF%d COLOR_FORMAT=0x%04x\n", src_buffer_id, param); - - break; - } - /* DOn't log invalid */ - case NV3_IMAGE_IN_MEMORY_IN_MEMORY_DMA_CTX_TYPE: - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - /* Pitch - length between scanlines */ - case NV3_IMAGE_IN_MEMORY_PITCH: - nv3->pgraph.image_in_memory.pitch = param & 0x1FF0; - nv3->pgraph.bpitch[src_buffer_id] = param & 0x1FF0; // 12:0 - - nv_log("Method Execution: Image in Memory BUF%d PITCH=0x%04x\n", src_buffer_id, nv3->pgraph.bpitch[src_buffer_id]); - break; - /* Byte offset in GPU VRAM of top left pixel (22:0) */ - case NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET: - if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) // RIVA 128ZX - nv3->pgraph.boffset[src_buffer_id] = param & 0x7FFFFF; - else - nv3->pgraph.boffset[src_buffer_id] = param & 0x3FFFFF; - - nv_log("Method Execution: Image in Memory BUF%d TOP_LEFT_OFFSET=0x%08x\n", src_buffer_id, nv3->pgraph.boffset[src_buffer_id]); - break; - case NV3_NVCLASS_CRAP_START ... NV3_NVCLASS_CRAP_END: - /* Suppress but don't do anything */ - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - default: - warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_names.c b/src/video/nv/nv3/classes/nv3_class_names.c deleted file mode 100644 index 64e35d9b3..000000000 --- a/src/video/nv/nv3/classes/nv3_class_names.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Defines core class names for debugging purposes - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -/* These are the object classes AS RECOGNISED BY THE GRAPHICS HARDWARE. */ -/* The drivers implement a COMPLETELY DIFFERENT SET OF CLASSES. */ - -/* THERE CAN ONLY BE 32 CLASSES IN NV3 BECAUSE THE CLASS ID PART OF THE CONTEXT OF A GRAPHICS OBJECT IN PFIFO RAM HASH TABLE IS ONLY 5 BITS LONG! */ - -const char* nv3_class_names[] = -{ - "NV3 INVALID class 0x00", - "NV3 class 0x01: Beta factor", - "NV3 class 0x02: Render operation", - "NV3 class 0x03: Chroma key", - "NV3 class 0x04: Plane mask", - "NV3 class 0x05: Clipping rectangle", - "NV3 class 0x06: Pattern", - "NV3 class 0x07: Rectangle", - "NV3 class 0x08: Point", - "NV3 class 0x09: Line", - "NV3 class 0x0A: Lin (line without starting or ending pixel)", - "NV3 class 0x0B: Triangle", - "NV3 class 0x0C: Windows 95 GDI text acceleration", - "NV3 class 0x0D: Memory to memory format", - "NV3 class 0x0E: Scaled image from memory", - "NV3 INVALID class 0x0F", - "NV3 class 0x10: Blit", - "NV3 class 0x11: Image", - "NV3 class 0x12: Bitmap", - "NV3 INVALID class 0x13", - "NV3 class 0x14: Transfer to Memory", - "NV3 class 0x15: Stretched image from CPU", - "NV3 INVALID class 0x16", - "NV3 class 0x17: Direct3D 5.0 accelerated textured triangle w/zeta buffer", - "NV3 class 0x18: Point with zeta buffer", - "NV3 INVALID class 0x19", - "NV3 INVALID class 0x1A", - "NV3 INVALID class 0x1B", - "NV3 class 0x1C: Image in Memory", - "NV3 INVALID class 0x1D", - "NV3 INVALID class 0x1E", - "NV3 INVALID class 0x1F", -}; \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_shared_methods.c b/src/video/nv/nv3/classes/nv3_class_shared_methods.c deleted file mode 100644 index 89473d829..000000000 --- a/src/video/nv/nv3/classes/nv3_class_shared_methods.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3: Methods shared across multiple classes - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 Connor Hyde - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/dma.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_generic_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - switch (method_id) - { - /* mthdCreate in software(?)*/ - case NV3_ROOT_HI_IM_OBJECT_MCOBJECTYFACE: - //nv_log("mthdCreate obj_name=0x%08x\n", param); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - break; - // set up the current notification request/object - // and check for double notifiers. - case NV3_SET_NOTIFY: - if (nv3->pgraph.notify_pending) - { - nv_log("Executed method NV3_SET_NOTIFY with nv3->pgraph.notify_pending already set. param=0x%08x, method=0x%04x, grobj=0x%08x 0x%08x 0x%08x 0x%08x\n"); - nv_log("IF THIS IS A DEBUG BUILD, YOU SHOULD SEE A CONTEXT BELOW"); - nv3_debug_ramin_print_context_info(param, context); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY); - - // disable - nv3->pgraph.notify_pending = false; - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY); - /* may need to disable fifo in this state */ - return; - } - - // set a notify as pending. - nv3->pgraph.notifier = param; - nv3->pgraph.notify_pending = true; - break; - default: - nv_log("Shared Generic Methods: Invalid or Unimplemented method 0x%04x", method_id); - nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING); - return; - } -} diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c deleted file mode 100644 index 01af9100d..000000000 --- a/src/video/nv/nv3/nv3_core.c +++ /dev/null @@ -1,1567 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 bringup and device emulation. - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -/* Main device object pointer */ -nv3_t* nv3; - -/* These are a ****PLACEHOLDER**** and are copied from 3dfx VoodooBanshee/Voodoo3*/ -static video_timings_t timing_nv3_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; -static video_timings_t timing_nv3_agp = { .type = VIDEO_AGP, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; -// Revision C -static video_timings_t timing_nv3t_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; -static video_timings_t timing_nv3t_agp = { .type = VIDEO_AGP, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; - -// Prototypes for functions only used in this translation unit -void nv3_init_mappings_mmio(void); -void nv3_init_mappings_svga(void); -bool nv3_is_svga_redirect_address(uint32_t addr); - -uint8_t nv3_svga_read(uint16_t addr, void* priv); -void nv3_svga_write(uint16_t addr, uint8_t val, void* priv); - -// Determine if this address needs to be redirected to the SVGA subsystem. - -bool nv3_is_svga_redirect_address(uint32_t addr) -{ - return (addr >= NV3_PRMVIO_START && addr <= NV3_PRMVIO_END) // VGA - || (addr >= NV3_PRMCIO_START && addr <= NV3_PRMCIO_END) // CRTC - || (addr >= NV3_USER_DAC_START && addr <= NV3_USER_DAC_END); // Note: 6813c6-6813c9 are ignored somewhere else -} - -// All MMIO regs are 32-bit i believe internally -// so we have to do some munging to get this to read - -// 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; - - // We need to specifically exclude this particular set of registers - // so we can write the 4/8bpp CLUT - if (addr >= NV3_USER_DAC_PALETTE_START && addr <= NV3_USER_DAC_PALETTE_END) - { - // Throw directly into PRAMDAC - return nv3_mmio_arbitrate_read(addr); - } - - if (nv3_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - ret = nv3_svga_read(real_address, nv3); - - nv_log_verbose_only("Redirected MMIO read8 to SVGA: addr=0x%04x returned 0x%04x\n", addr, ret); - - return ret; - } - - // see if unaligned reads are a problem - 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 = 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 (nv3_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - ret = nv3_svga_read(real_address, nv3) - | (nv3_svga_read(real_address + 1, nv3) << 8); - - nv_log_verbose_only("Redirected MMIO read16 to SVGA: addr=0x%04x returned 0x%04x\n", addr, ret); - - 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 (nv3_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - ret = nv3_svga_read(real_address, nv3) - | (nv3_svga_read(real_address + 1, nv3) << 8) - | (nv3_svga_read(real_address + 2, nv3) << 16) - | (nv3_svga_read(real_address + 3, nv3) << 24); - - nv_log_verbose_only("Redirected MMIO read32 to SVGA: addr=0x%04x returned 0x%04x\n", addr, ret); - - return ret; - } - ret = nv3_mmio_arbitrate_read(addr); - return ret; - -} - -// Write 8-bit MMIO -void nv3_mmio_write8(uint32_t addr, uint8_t val, void* priv) -{ - addr &= 0xFFFFFF; - - // We need to specifically exclude this particular set of registers - // so we can write the 4/8bpp CLUT - if (addr >= NV3_USER_DAC_PALETTE_START && addr <= NV3_USER_DAC_PALETTE_END) - { - // Throw directly into PRAMDAC - nv3_mmio_arbitrate_write(addr, val); - return; - } - - // This is weitek vga stuff - // If we need to add more of these we can convert these to a switch statement - if (nv3_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - nv_log_verbose_only("Redirected MMIO write8 to SVGA: addr=0x%04x val=0x%02x\n", addr, val); - - nv3_svga_write(real_address, val & 0xFF, nv3); - - return; - } - - // overwrite first 8bits of a 32 bit value - uint32_t new_val = nv3_mmio_read32(addr, NULL); - - new_val &= (~0xFF << (addr & 3) << 3); - new_val |= (val << ((addr & 3) << 3)); - - nv3_mmio_write32(addr, new_val, priv); -} - -// Write 16-bit MMIO -void nv3_mmio_write16(uint32_t addr, uint16_t val, void* priv) -{ - addr &= 0xFFFFFF; - - // This is weitek vga stuff - if (nv3_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - nv_log_verbose_only("Redirected MMIO write16 to SVGA: addr=0x%04x val=0x%02x\n", addr, val); - - nv3_svga_write(real_address, val & 0xFF, nv3); - nv3_svga_write(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); - - new_val &= (~0xFFFF << (addr & 3) << 3); - new_val |= (val << ((addr & 3) << 3)); - - nv3_mmio_write32(addr, new_val, priv); -} - -// Write 32-bit MMIO -void nv3_mmio_write32(uint32_t addr, uint32_t val, void* priv) -{ - addr &= 0xFFFFFF; - - // This is weitek vga stuff - if (nv3_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - nv_log_verbose_only("Redirected MMIO write32 to SVGA: addr=0x%04x val=0x%02x\n", addr, val); - - nv3_svga_write(real_address, val & 0xFF, nv3); - nv3_svga_write(real_address + 1, (val >> 8) & 0xFF, nv3); - nv3_svga_write(real_address + 2, (val >> 16) & 0xFF, nv3); - nv3_svga_write(real_address + 3, (val >> 24) & 0xFF, nv3); - - return; - } - - nv3_mmio_arbitrate_write(addr, val); -} - -// AGP read function -uint8_t nv3_agp_read(int32_t func, int32_t addr) -{ - uint8_t ret = 0x00; - - switch (addr) - { - case NV3_AGP_CAPABILITIES_CAP_ID: - ret = NV3_AGP_CAPABILITIES_CAP_ID_AGP; // AGP capable device - break; - case NV3_AGP_CAPABILITIES_NEXT_PTR: // Always off - ret = 0x00; - case NV3_AGP_CAPABILITIES_AGP_VERSION: - ret = (0x1 << NV3_AGP_CAPABILITIES_AGP_VERSION_MAJOR) | NV3_AGP_CAPABILITIES_AGP_VERSION_MINOR; - break; - case NV3_AGP_STATUS_RATE: - // NV3T = AGP 2X, NV3 = AGP 1X - if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) - ret = NV3_AGP_STATUS_RATE_1X_SUPPORTED | NV3_AGP_STATUS_RATE_2X_SUPPORTED; - else - ret = NV3_AGP_STATUS_RATE_1X_SUPPORTED; - break; - case NV3_AGP_STATUS_BYTE1: - ret = 0x00; // SBA not supported - break; - case NV3_AGP_STATUS_MAX_REQUESTS: - ret = NV3_AGP_STATUS_MAX_REQUESTS_AMOUNT; - break; - // This is also used for SBA but SBA is always off so we can use a bool - case NV3_AGP_COMMAND_BYTE1: - ret = nv3->nvbase.agp_enabled; - break; - default: - ret = nv3->nvbase.pci_config.pci_regs[addr]; - break; - } - - return ret; -} - -// PCI stuff -// BAR0 Pointer to MMIO space -// BAR1 Pointer to Linear Framebuffer (NV_USER) - -uint8_t nv3_pci_read(int32_t func, int32_t addr, void* priv) -{ - uint8_t ret = 0x00; - - // sanity check - if (!nv3) - return ret; - - // figure out what size this gets read as first - // seems func does not matter at least here? - switch (addr) - { - // Get the pci vendor id.. - - case NV3_PCI_CFG_VENDOR_ID: - ret = (PCI_VENDOR_SGS_NV & 0xFF); - break; - - case NV3_PCI_CFG_VENDOR_ID + 1: // all access 8bit - ret = (PCI_VENDOR_SGS_NV >> 8); - break; - - // device id - - case NV3_PCI_CFG_DEVICE_ID: - ret = (NV_PCI_DEVICE_NV3 & 0xFF); - break; - - case NV3_PCI_CFG_DEVICE_ID + 1: - ret = (NV_PCI_DEVICE_NV3 >> 8); - break; - - // various capabilities enabled by default - // IO space enabled - // Memory space enabled - // Bus master enabled - // Write/inval enabled - // Pal snoop enabled - // Capabiliies list enabled - // 66Mhz FSB capable - - case PCI_REG_COMMAND_L: - ret = nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND_L]; - break; - - case PCI_REG_COMMAND_H: - ret = nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND_H] & NV3_PCI_COMMAND_H_FAST_BACK2BACK; // always enable fast back2back - break; - - // pci status register - case PCI_REG_STATUS_L: - if (nv3->pextdev.straps - & NV3_PSTRAPS_BUS_SPEED_66MHZ) - ret = (nv3->nvbase.pci_config.pci_regs[PCI_REG_STATUS_L] | NV3_PCI_STATUS_L_66MHZ_CAPABLE); - else - ret = nv3->nvbase.pci_config.pci_regs[PCI_REG_STATUS_L]; - - break; - - case PCI_REG_STATUS_H: - ret = (nv3->nvbase.pci_config.pci_regs[PCI_REG_STATUS_H]) & (NV3_PCI_STATUS_H_FAST_DEVSEL_TIMING << NV3_PCI_STATUS_H_DEVSEL_TIMING); - break; - - case NV3_PCI_CFG_REVISION: - ret = nv3->nvbase.gpu_revision; // Commercial release - break; - - case PCI_REG_PROG_IF: - ret = 0x00; - break; - - case NV3_PCI_CFG_SUBCLASS_CODE: - ret = 0x00; // nothing - break; - - case NV3_PCI_CFG_CLASS_CODE: - ret = NV3_PCI_CFG_CLASS_CODE_VGA; // CLASS_CODE_VGA - break; - - case NV3_PCI_CFG_CACHE_LINE_SIZE: - ret = NV3_PCI_CFG_CACHE_LINE_SIZE_DEFAULT_FROM_VBIOS; - break; - - case NV3_PCI_CFG_LATENCY_TIMER: - case NV3_PCI_CFG_HEADER_TYPE: - case NV3_PCI_CFG_BIST: - ret = 0x00; - break; - - // BARs are marked as prefetchable per the datasheet - case NV3_PCI_CFG_BAR0_L: - case NV3_PCI_CFG_BAR1_L: - // only bit that matters is bit 3 (prefetch bit) - ret = (NV3_PCI_CFG_BAR_PREFETCHABLE_ENABLED << NV3_PCI_CFG_BAR_PREFETCHABLE); - break; - - // These registers are hardwired to zero per the datasheet - // Writes have no effect, we can just handle it here though - case NV3_PCI_CFG_BAR0_BYTE1 ... NV3_PCI_CFG_BAR0_BYTE2: - case NV3_PCI_CFG_BAR1_BYTE1 ... NV3_PCI_CFG_BAR1_BYTE2: - ret = 0x00; - break; - - // MMIO base address - case NV3_PCI_CFG_BAR0_BASE_ADDRESS: - ret = nv3->nvbase.bar0_mmio_base >> 24;//8bit value - break; - - case NV3_PCI_CFG_BAR1_BASE_ADDRESS: - ret = nv3->nvbase.bar1_lfb_base >> 24; //8bit value - break; - - case NV3_PCI_CFG_ENABLE_VBIOS: - ret = nv3->nvbase.pci_config.vbios_enabled; - break; - - case NV3_AGP_CAPABILITIES_POINTER: - if (nv3->nvbase.bus_generation >= nv_bus_agp_1x) - ret = NV3_AGP_CAPABILITIES_START; - else - ret = 0x00; - break; - - case NV3_PCI_CFG_INT_LINE: - ret = nv3->nvbase.pci_config.int_line; - break; - - case NV3_PCI_CFG_INT_PIN: - ret = PCI_INTA; - break; - - case NV3_PCI_CFG_MIN_GRANT: - ret = NV3_PCI_CFG_MIN_GRANT_DEFAULT; - break; - - case NV3_PCI_CFG_MAX_LATENCY: - ret = NV3_PCI_CFG_MAX_LATENCY_DEFAULT; - break; - - //bar2-5 are not used and hardwired to 0 - case NV3_PCI_CFG_BAR_INVALID_START ... NV3_PCI_CFG_BAR_INVALID_END: - ret = 0x00; - break; - - case NV3_PCI_CFG_SUBSYSTEM_ID_MIRROR_START: - case NV3_PCI_CFG_SUBSYSTEM_ID_MIRROR_END: - ret = nv3->nvbase.pci_config.pci_regs[NV3_PCI_CFG_SUBSYSTEM_ID + (addr & 0x03)]; - break; - - case NV3_AGP_START ... NV3_AGP_END: - if (nv3->nvbase.bus_generation < nv_bus_agp_1x) - break; - - ret = nv3_agp_read(func, addr); - - break; - - - default: // by default just return pci_config.pci_regs - ret = nv3->nvbase.pci_config.pci_regs[addr]; - break; - - } - - nv_log("nv3_pci_read func=0x%04x addr=0x%04x ret=0x%04x\n", func, addr, ret); - return ret; -} - -void nv3_agp_write(int32_t func, int32_t addr, uint8_t val) -{ - nv3->nvbase.pci_config.pci_regs[addr] = val; - - switch (addr) - { - case NV3_AGP_COMMAND_BYTE1: - nv3->nvbase.agp_enabled = val; - break; - default: - break; - } -} - -void nv3_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv) -{ - // sanity check - if (!nv3) - return; - - // some addresses are not writable so can't have any effect and can't be allowed to be modified using this code - // as an example, only the most significant byte of the PCI BARs can be modified - if (addr >= NV3_PCI_CFG_BAR0_L && addr <= NV3_PCI_CFG_BAR0_BYTE2 - && addr >= NV3_PCI_CFG_BAR1_L && addr <= NV3_PCI_CFG_BAR1_BYTE2) - return; - - nv_log("nv3_pci_write func=0x%04x addr=0x%04x val=0x%04x\n", func, addr, val); - - nv3->nvbase.pci_config.pci_regs[addr] = val; - - switch (addr) - { - // standard pci command stuff - case PCI_REG_COMMAND_L: - nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND_L] = val; - // actually update the mappings - nv3_update_mappings(); - break; - case PCI_REG_COMMAND_H: - nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND_H] = val; - // actually update the mappings - nv3_update_mappings(); - break; - // pci status register - case PCI_REG_STATUS_L: - nv3->nvbase.pci_config.pci_regs[PCI_REG_STATUS_L] = val | (NV3_PCI_STATUS_L_66MHZ_CAPABLE); - break; - case PCI_REG_STATUS_H: - nv3->nvbase.pci_config.pci_regs[PCI_REG_STATUS_H] = val | (NV3_PCI_STATUS_H_FAST_DEVSEL_TIMING << NV3_PCI_STATUS_H_DEVSEL_TIMING); - break; - case NV3_PCI_CFG_BAR0_BASE_ADDRESS: - nv3->nvbase.bar0_mmio_base = val << 24; - nv3_update_mappings(); - break; - case NV3_PCI_CFG_BAR1_BASE_ADDRESS: - nv3->nvbase.bar1_lfb_base = val << 24; - nv3_update_mappings(); - break; - case NV3_PCI_CFG_ENABLE_VBIOS: - case NV3_PCI_CFG_VBIOS_BASE: - - // make sure we are actually toggling the vbios, not the rom base - if (addr == NV3_PCI_CFG_ENABLE_VBIOS) - nv3->nvbase.pci_config.vbios_enabled = (val & 0x01); - - if (nv3->nvbase.pci_config.vbios_enabled) - { - // First see if we simply wanted to change the VBIOS location - - // Enable it in case it was disabled before - mem_mapping_enable(&nv3->nvbase.vbios.mapping); - - if (addr != NV3_PCI_CFG_ENABLE_VBIOS) - { - uint32_t old_addr = nv3->nvbase.vbios.mapping.base; - // 9bit register - uint32_t new_addr = nv3->nvbase.pci_config.pci_regs[NV3_PCI_CFG_VBIOS_BASE_H] << 24 | - nv3->nvbase.pci_config.pci_regs[NV3_PCI_CFG_VBIOS_BASE_L] << 16; - - // move it - mem_mapping_set_addr(&nv3->nvbase.vbios.mapping, new_addr, 0x8000); - - nv_log("...i like to move it move it (VBIOS Relocation) 0x%04x -> 0x%04x\n", old_addr, new_addr); - - } - else - { - nv_log("...VBIOS Enable\n"); - } - } - else - { - nv_log("...VBIOS Disable\n"); - mem_mapping_disable(&nv3->nvbase.vbios.mapping); - - } - break; - case NV3_PCI_CFG_INT_LINE: - nv3->nvbase.pci_config.int_line = val; - break; - //bar2-5 are not used and can't be written to - case NV3_PCI_CFG_BAR_INVALID_START ... NV3_PCI_CFG_BAR_INVALID_END: - break; - - // these are mirrored to the subsystem id and also stored in the ROMBIOS - case NV3_PCI_CFG_SUBSYSTEM_ID_MIRROR_START: - case NV3_PCI_CFG_SUBSYSTEM_ID_MIRROR_END: - nv3->nvbase.pci_config.pci_regs[NV3_PCI_CFG_SUBSYSTEM_ID + (addr & 0x03)] = val; - break; - - case NV3_AGP_START ... NV3_AGP_END: - if (nv3->nvbase.bus_generation < nv_bus_agp_1x) - break; - - nv3_agp_write(func, addr, val); - - break; - - default: - break; - } -} - - -// -// SVGA functions -// -void nv3_recalc_timings(svga_t* svga) -{ - // sanity check - if (!nv3) - return; - - nv3_t* nv3 = (nv3_t*)svga->priv; - uint32_t pixel_mode = svga->crtc[NV3_CRTC_REGISTER_PIXELMODE] & 0x03; - - svga->memaddr_latch += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0x1F) << 16; - - /* Turn off override if we are in VGA mode */ - svga->override = !(pixel_mode == NV3_CRTC_REGISTER_PIXELMODE_VGA); - - /* NOTE: The RIVA 128 draws in a way almost completely separate to any other 86Box GPU. - - Basically, we only blit to buffer32 when something changes and we don't even bother using a timer. We only render when there is something to actually render. - - This is because there is no linear relationship between the contents of VRAM and the contents of the display which 86box's SVGA subsystem cannot tolerate. - In fact, the position in VRAM and pitch can be changed at any time via an NV_IMAGE_IN_MEMORY object. - - Therefore, we need to completely bypass it using svga->override and draw our own rendering functions. This allows us to use a neat optimisation trick - to only ever actually draw when we need to do something. This shouldn't be a problem in games, because the drivers will read the current refresh rate from - the Windows settings, and then, just submit objects at that pace for anything that changes on the screen. - */ - - // Set the pixel mode - switch (pixel_mode) - { - case NV3_CRTC_REGISTER_PIXELMODE_8BPP: - svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 1; // ????? - svga->bpp = 8; - svga->lowres = 0; - svga->map8 = svga->pallook; - break; - case NV3_CRTC_REGISTER_PIXELMODE_16BPP: - /* This is some sketchy shit that is an attempt at an educated guess - at pixel clock differences between 9x and NT only in 16bpp. If there is ever an error on 9x with "interlaced" looking graphics, - this is what's causing it. Possibly fucking up the drivers under *ReactOS* of all things */ - if ((svga->crtc[NV3_CRTC_REGISTER_VRETRACESTART] >> 1) & 0x01) - svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 2; - else - svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 3; - - /* sometimes it really renders in 15bpp, so you need to do this */ - if ((nv3->pramdac.general_control >> NV3_PRAMDAC_GENERAL_CONTROL_565_MODE) & 0x01) - { - svga->bpp = 16; - svga->lowres = 0; - } - else - { - svga->bpp = 15; - svga->lowres = 0; - - } - - break; - case NV3_CRTC_REGISTER_PIXELMODE_32BPP: - svga->rowoffset += (svga->crtc[NV3_CRTC_REGISTER_RPC0] & 0xE0) << 3; - - svga->bpp = 32; - svga->lowres = 0; - //svga->render = nv3_render_32bpp; - break; - } - - // from nv_riva128 - if (((svga->miscout >> 2) & 2) == 2) - { - // set clocks - nv3_pramdac_set_pixel_clock(); - nv3_pramdac_set_vram_clock(); - } -} - -void nv3_speed_changed(void* priv) -{ - // sanity check - if (!nv3) - return; - - nv3_recalc_timings(&nv3->nvbase.svga); -} - -// Force Redraw -// Reset etc. -void nv3_force_redraw(void* priv) -{ - // sanity check - if (!nv3) - return; - - nv3->nvbase.svga.fullchange = changeframecount; -} - -// Read from SVGA core memory -uint8_t nv3_svga_read(uint16_t addr, void* priv) -{ - - nv3_t* nv3 = (nv3_t*)priv; - - uint8_t ret = 0x00; - - // sanity check - if (!nv3) - return ret; - - // If we need to RMA from GPU MMIO, go do that - if (addr >= NV3_RMA_REGISTER_START - && addr <= NV3_RMA_REGISTER_END) - { - if (!(nv3->pbus.rma.mode & 0x01)) - return ret; - - // must be dword aligned - uint32_t real_rma_read_addr = (((nv3->pbus.rma.mode & NV3_CRTC_REGISTER_RMA_MODE_MAX) - 1) << 1) + (addr & 0x03); - ret = nv3_pbus_rma_read(real_rma_read_addr); - return ret; - } - - // mask off b0/d0 registers - if ((((addr & 0xFFF0) == 0x3D0 - || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) - && !(nv3->nvbase.svga.miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - // Alias for "get current SVGA CRTC register ID" - case NV3_CRTC_REGISTER_INDEX: - ret = nv3->nvbase.svga.crtcreg; - break; - case NV3_CRTC_REGISTER_WTF: - ret = 0x08; // Required to not freeze in certain situations on v3.xx drivers. Even though this register doesn't actually exist lol - break; - case NV3_CRTC_REGISTER_CURRENT: - // Support the extended NVIDIA CRTC register range - switch (nv3->nvbase.svga.crtcreg) - { - case NV3_CRTC_REGISTER_RL0: - ret = nv3->nvbase.svga.displine & 0xFF; - break; - /* Is rl1?*/ - case NV3_CRTC_REGISTER_RL1: - ret = (nv3->nvbase.svga.displine >> 8) & 7; - break; - case NV3_CRTC_REGISTER_I2C: - ret = i2c_gpio_get_sda(nv3->nvbase.i2c) << 3 - | i2c_gpio_get_scl(nv3->nvbase.i2c) << 2; - - break; - default: - ret = nv3->nvbase.svga.crtc[nv3->nvbase.svga.crtcreg]; - } - break; - default: - ret = svga_in(addr, &nv3->nvbase.svga); - break; - } - - return ret; //TEMP -} - -// Write to SVGA core memory -void nv3_svga_write(uint16_t addr, uint8_t val, void* priv) -{ - // sanity check - if (!nv3) - return; - - // If we need to RMA to GPU MMIO, go do that - if (addr >= NV3_RMA_REGISTER_START - && addr <= NV3_RMA_REGISTER_END) - { - // we don't need to store these registers... - nv3->pbus.rma.rma_regs[addr & 3] = val; - - if (!(nv3->pbus.rma.mode & 0x01)) // we are halfway through sending something - return; - - uint32_t real_rma_write_addr = ((nv3->pbus.rma.mode & (NV3_CRTC_REGISTER_RMA_MODE_MAX - 1)) << 1) + (addr & 0x03); - - nv3_pbus_rma_write(real_rma_write_addr, nv3->pbus.rma.rma_regs[addr & 3]); - return; - } - - // mask off b0/d0 registers - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) - && addr < 0x3de) - && !(nv3->nvbase.svga.miscout & 1))//miscout bit 7 controls mappping - addr ^= 0x60; - - uint8_t crtcreg = nv3->nvbase.svga.crtcreg; - uint8_t old_value = 0x00; - - // todo: - // Pixel formats (8bit vs 555 vs 565) - // VBE 3.0? - - switch (addr) - { - case NV3_CRTC_REGISTER_INDEX: - // real mode access to GPU MMIO space... - nv3->nvbase.svga.crtcreg = val; - break; - // support the extended crtc regs and debug this out - case NV3_CRTC_REGISTER_CURRENT: - - // Implements the VGA Protect register - if ((nv3->nvbase.svga.crtcreg < NV3_CRTC_REGISTER_OVERFLOW) && (nv3->nvbase.svga.crtc[0x11] & 0x80)) - return; - - // Ignore certain bits when VGA Protect register set and we are writing to CRTC register=07h - if ((nv3->nvbase.svga.crtcreg == NV3_CRTC_REGISTER_OVERFLOW) && (nv3->nvbase.svga.crtc[0x11] & 0x80)) - val = (nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_OVERFLOW] & ~0x10) | (val & 0x10); - - // set the register value... - old_value = nv3->nvbase.svga.crtc[crtcreg]; - - nv3->nvbase.svga.crtc[crtcreg] = val; - // ...now act on it - - // Handle nvidia extended Bank0/Bank1 IDs - switch (crtcreg) - { - case NV3_CRTC_REGISTER_READ_BANK: - nv3->nvbase.cio_read_bank = val; - if (nv3->nvbase.svga.chain4) // chain4 addressing (planar?) - nv3->nvbase.svga.read_bank = nv3->nvbase.cio_read_bank << 15; - else - nv3->nvbase.svga.read_bank = nv3->nvbase.cio_read_bank << 13; // extended bank numbers - break; - case NV3_CRTC_REGISTER_WRITE_BANK: - nv3->nvbase.cio_write_bank = val; - if (nv3->nvbase.svga.chain4) - nv3->nvbase.svga.write_bank = nv3->nvbase.cio_write_bank << 15; - else - nv3->nvbase.svga.write_bank = nv3->nvbase.cio_write_bank << 13; - break; - case NV3_CRTC_REGISTER_RMA: - nv3->pbus.rma.mode = val & NV3_CRTC_REGISTER_RMA_MODE_MAX; - break; - /* Handle some large screen stuff */ - case NV3_CRTC_REGISTER_PIXELMODE: - if (val & 1 << (NV3_CRTC_REGISTER_FORMAT_VDT10)) - nv3->nvbase.svga.vtotal += 0x400; - if (val & 1 << (NV3_CRTC_REGISTER_FORMAT_VRS10)) - nv3->nvbase.svga.vblankstart += 0x400; - if (val & 1 << (NV3_CRTC_REGISTER_FORMAT_VBS10)) - nv3->nvbase.svga.vsyncstart += 0x400; - if (val & 1 << (NV3_CRTC_REGISTER_FORMAT_HBE6)) - nv3->nvbase.svga.hdisp += 0x400; - - /* Make sure dispend and vblankstart are right if we are displaying above 1024 vert */ - if (nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_PIXELMODE] & 1 << (NV3_CRTC_REGISTER_FORMAT_VDE10)) - nv3->nvbase.svga.dispend += 0x400; - - break; - case NV3_CRTC_REGISTER_HEB: - if (val & 0x01) - nv3->nvbase.svga.hdisp += 0x100; - break; - case NV3_CRTC_REGISTER_I2C_GPIO: - { - uint8_t scl = !!(val & 0x20); - uint8_t sda = !!(val & 0x10); - // Set an I2C GPIO register - i2c_gpio_set(nv3->nvbase.i2c, scl, sda); - break; - } - /* [6:0] contains cursorAddr [22:16] */ - case NV3_CRTC_REGISTER_CURSOR_ADDR0: - nv3->pramdac.cursor_address |= ((val & 0x7F) << 12); //bit7 technically ignored, but nv don't care, so neither do we - break; - /* [7:2] contains cursorAddr [16:11] */ - case NV3_CRTC_REGISTER_CURSOR_ADDR1: - nv3->pramdac.cursor_address |= ((val & 0xF8) << 4); // bit0 and 1 aren't part of the address - break; - } - - /* Recalculate the timings if we actually changed them - Additionally only do it if the value actually changed*/ - if (old_value != val) - { - // Thx to Fuel who basically wrote most of the SVGA compatibility code already (although I fixed some issues), because VGA is boring - // and in the words of an ex-Rendition/3dfx/NVIDIA engineer, "VGA was basically an undocumented bundle of steaming you-know-what. - // And it was essential that any cores the PC 3D startups acquired had to work with all the undocumented modes and timing tweaks (mode X, etc.)" - if (nv3->nvbase.svga.crtcreg < 0xE - || nv3->nvbase.svga.crtcreg > 0x10) - { - nv3->nvbase.svga.fullchange = changeframecount; - nv3_recalc_timings(&nv3->nvbase.svga); - } - } - - break; - default: - svga_out(addr, val, &nv3->nvbase.svga); - break; - } - -} - -/* DFB, sets up a dumb framebuffer */ -uint8_t nv3_dfb_read8(uint32_t addr, void* priv) -{ - addr &= (nv3->nvbase.svga.vram_mask); - return nv3->nvbase.svga.vram[addr]; -} - -uint16_t nv3_dfb_read16(uint32_t addr, void* priv) -{ - addr &= (nv3->nvbase.svga.vram_mask); - return (nv3->nvbase.svga.vram[addr + 1] << 8) | nv3->nvbase.svga.vram[addr]; -} - -uint32_t nv3_dfb_read32(uint32_t addr, void* priv) -{ - addr &= (nv3->nvbase.svga.vram_mask); - return (nv3->nvbase.svga.vram[addr + 3] << 24) | (nv3->nvbase.svga.vram[addr + 2] << 16) + - (nv3->nvbase.svga.vram[addr + 1] << 8) | nv3->nvbase.svga.vram[addr]; -} - -void nv3_dfb_write8(uint32_t addr, uint8_t val, void* priv) -{ - addr &= (nv3->nvbase.svga.vram_mask); - nv3->nvbase.svga.vram[addr] = val; - nv3->nvbase.svga.changedvram[addr >> 12] = val; - nv3_render_current_bpp_dfb_8(addr); -} - -void nv3_dfb_write16(uint32_t addr, uint16_t val, void* priv) -{ - addr &= (nv3->nvbase.svga.vram_mask); - nv3->nvbase.svga.vram[addr + 1] = (val >> 8) & 0xFF; - nv3->nvbase.svga.vram[addr] = (val) & 0xFF; - nv3->nvbase.svga.changedvram[addr >> 12] = val; - nv3_render_current_bpp_dfb_16(addr); - -} - -void nv3_dfb_write32(uint32_t addr, uint32_t val, void* priv) -{ - addr &= (nv3->nvbase.svga.vram_mask); - nv3->nvbase.svga.vram[addr + 3] = (val >> 24) & 0xFF; - nv3->nvbase.svga.vram[addr + 2] = (val >> 16) & 0xFF; - nv3->nvbase.svga.vram[addr + 1] = (val >> 8) & 0xFF; - nv3->nvbase.svga.vram[addr] = (val) & 0xFF; - nv3->nvbase.svga.changedvram[addr >> 12] = val; - - nv3_render_current_bpp_dfb_32(addr); - -} - -/* Cursor shit */ -void nv3_draw_cursor(svga_t* svga, int32_t drawline) -{ - // sanity check - if (!nv3) - return; - - // if cursor disabled is set, return - if ((nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_CURSOR_START] >> NV3_CRTC_REGISTER_CURSOR_START_DISABLED) & 0x01) - return; - - // NT GDI drivers: Load cursor using NV_IMAGE_FROM_MEMORY ("NV3LCD") - // 9x GDI drivers: Use H/W cursor in RAMIN - - // Do we need to emulate it? - - // THIS IS CORRECT. BUT HOW DO WE FIND IT? - uint32_t ramin_cursor_position = NV3_RAMIN_OFFSET_CURSOR; - - /* let's just assume buffer 0 here...that code needs to be totally rewritten*/ - nv3_coord_16_t start_position = nv3->pramdac.cursor_start; - - /* refuse to draw if thge cursor is offscreen */ - if (start_position.x >= nv3->nvbase.svga.hdisp - || start_position.y >= nv3->nvbase.svga.dispend) - { - return; - } - - nv_log("nv3_draw_cursor start=0x%04x,0x%04x", start_position.x, start_position.y); - - uint32_t final_position = nv3_render_get_vram_address_for_buffer(start_position, 0); - - uint16_t* vram_16 = (uint16_t*)nv3->nvbase.svga.vram; - uint32_t* vram_32 = (uint32_t*)nv3->nvbase.svga.vram; - - /* - We have to get a 32x32, "A"1R5G5B5-format cursor - out of video memory. The alpha bit actually means - XOR with display pixel if 0, replace if 1 - - These are expanded to RGB10 only if they are XORed. We don't do this (we don't really need to + there is no grobj specified here so special casing - would be needed) so we just xor it with the current pixel format - */ - for (int32_t y = 0; y < NV3_PRAMDAC_CURSOR_SIZE_Y; y++) - { - for (int32_t x = 0; x < NV3_PRAMDAC_CURSOR_SIZE_X; x++) - { - uint16_t current_pixel = nv3_ramin_read16(ramin_cursor_position, nv3); - - // 0000 = transparent, so skip drawing - if (current_pixel) - { - bool replace_bit = (current_pixel & 0x8000); - - // use buffer 0 BPIXEL - uint32_t bpixel_format = (nv3->pgraph.bpixel[0]) & 0x03; - - switch (bpixel_format) - { - case bpixel_fmt_8bit: - if (replace_bit) - nv3->nvbase.svga.vram[final_position] = current_pixel; - else //xor - { - // not sure what to do here. we'd have to search through the palette to find the closest possible colour. - uint8_t final = current_pixel ^ nv3->nvbase.svga.vram[final_position]; - nv3->nvbase.svga.vram[final_position] = final; - } - case bpixel_fmt_16bit: // easy case (our cursor is 15bpp format) - uint32_t index_16 = final_position >> 1; - - if (replace_bit) // just replace - vram_16[index_16] = current_pixel; - else // xor - { - current_pixel &= ~0x8000; // mask off the xor bit - uint16_t final = current_pixel ^ vram_16[index_16]; - vram_16[index_16] = final; - } - case bpixel_fmt_32bit: - uint32_t index_32 = final_position >> 2; - - if (replace_bit) // just replace - vram_32[index_32] = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here - else //xor - { - current_pixel &= ~0x8000; // mask off the xor bit - uint32_t current_pixel_32 = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here - - uint32_t final = current_pixel_32 ^ vram_32[index_32]; - vram_32[index_32] = final; - } - break; - } - } - - // increment vram position - ramin_cursor_position += 2; - - // go - switch (nv3->nvbase.svga.bpp) - { - case 8: - final_position++; - case 15 ... 16: - final_position += 2; - break; - case 32: - final_position += 4; - break; - } - - start_position.x++; - } - - - start_position.y++; - start_position.x = nv3->pramdac.cursor_start.x; - - // reset at the end of each line so we "jump" to the start x - final_position = nv3_render_get_vram_address_for_buffer(start_position, 0); - } -} - -// MMIO 0x110000->0x111FFF is mapped to a mirror of the VBIOS. -// Note this area is 64kb and the vbios is only 32kb. See below.. - -uint8_t nv3_prom_read(uint32_t address) -{ - // prom area is 64k, so... - // first see if we even have a rom of 64kb in size - uint32_t max_rom_size = NV3_PROM_END - NV3_PROM_START; - uint32_t real_rom_size = max_rom_size; - - // set it - if (nv3->nvbase.vbios.sz < max_rom_size) - real_rom_size = nv3->nvbase.vbios.sz; - - //get our real address - uint8_t rom_address = address & max_rom_size; - - // Does this mirror on real hardware? - if (rom_address >= real_rom_size) - { - nv_log("PROM VBIOS Read to INVALID address 0x%05x, returning 0xFF", rom_address); - return 0xFF; - } - else - { - uint8_t val = nv3->nvbase.vbios.rom[rom_address]; - nv_log("PROM VBIOS Read 0x%05x <- 0x%05x", val, rom_address); - return val; - } -} - -void nv3_prom_write(uint32_t address, uint32_t value) -{ - uint32_t real_addr = address & 0x1FFFF; - nv_log("What's going on here? Tried to write to the Video BIOS ROM? (Address=0x%05x, value=0x%02x)", real_addr, value); -} - -// Initialise the MMIO mappings -void nv3_init_mappings_mmio(void) -{ - nv_log("Initialising MMIO mapping\n"); - - // 0x0 - 1000000: regs - // 0x1000000-2000000 - - // initialize the mmio mapping - mem_mapping_add(&nv3->nvbase.mmio_mapping, 0, 0, - nv3_mmio_read8, - nv3_mmio_read16, - nv3_mmio_read32, - nv3_mmio_write8, - nv3_mmio_write16, - nv3_mmio_write32, - NULL, MEM_MAPPING_EXTERNAL, nv3); - - // initialize the mmio mapping - mem_mapping_add(&nv3->nvbase.ramin_mapping, 0, 0, - nv3_ramin_read8, - nv3_ramin_read16, - nv3_ramin_read32, - nv3_ramin_write8, - nv3_ramin_write16, - nv3_ramin_write32, - NULL, MEM_MAPPING_EXTERNAL, nv3); - - mem_mapping_add(&nv3->nvbase.ramin_mapping_mirror, 0, 0, - nv3_ramin_read8, - nv3_ramin_read16, - nv3_ramin_read32, - nv3_ramin_write8, - nv3_ramin_write16, - nv3_ramin_write32, - NULL, MEM_MAPPING_EXTERNAL, nv3); - -} - -void nv3_init_mappings_svga(void) -{ - nv_log("Initialising SVGA core memory mapping\n"); - // setup the svga mappings - mem_mapping_add(&nv3->nvbase.framebuffer_mapping, 0, 0, - nv3_dfb_read8, - nv3_dfb_read16, - nv3_dfb_read32, - nv3_dfb_write8, - nv3_dfb_write16, - nv3_dfb_write32, - nv3->nvbase.svga.vram, 0, &nv3->nvbase.svga); - - // the SVGA/LFB mapping is also mirrored - mem_mapping_add(&nv3->nvbase.framebuffer_mapping_mirror, 0, 0, - nv3_dfb_read8, - nv3_dfb_read16, - nv3_dfb_read32, - nv3_dfb_write8, - nv3_dfb_write16, - nv3_dfb_write32, - nv3->nvbase.svga.vram, 0, &nv3->nvbase.svga); - - io_sethandler(0x03c0, 0x0020, - nv3_svga_read, NULL, NULL, - nv3_svga_write, NULL, NULL, - nv3); -} - -void nv3_init_mappings(void) -{ - nv3_init_mappings_mmio(); - nv3_init_mappings_svga(); -} - -// Updates the mappings after initialisation. -void nv3_update_mappings(void) -{ - // sanity check - if (!nv3) - return; - - // setting this to 0 doesn't seem to disable it, based on the datasheet - - nv_log("\nMemory Mapping Config Change:\n"); - - (nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) ? nv_log("Enable I/O\n") : nv_log("Disable I/O\n"); - - io_removehandler(0x03c0, 0x0020, - nv3_svga_read, NULL, NULL, - nv3_svga_write, NULL, NULL, - nv3); - - if (nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - io_sethandler(0x03c0, 0x0020, - nv3_svga_read, NULL, NULL, - nv3_svga_write, NULL, NULL, - nv3); - - if (!(nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - nv_log("The memory was turned off, not much is going to happen.\n"); - return; - } - - // turn off bar0 and bar1 by defualt - mem_mapping_disable(&nv3->nvbase.mmio_mapping); - mem_mapping_disable(&nv3->nvbase.framebuffer_mapping); - mem_mapping_disable(&nv3->nvbase.framebuffer_mapping_mirror); - mem_mapping_disable(&nv3->nvbase.ramin_mapping); - mem_mapping_disable(&nv3->nvbase.ramin_mapping_mirror); - - // Setup BAR0 (MMIO) - - nv_log("BAR0 (MMIO Base) = 0x%08x\n", nv3->nvbase.bar0_mmio_base); - - - if (nv3->nvbase.bar0_mmio_base) - mem_mapping_set_addr(&nv3->nvbase.mmio_mapping, nv3->nvbase.bar0_mmio_base, NV3_MMIO_SIZE); - - // if this breaks anything, remove it - nv_log("BAR1 (Linear Framebuffer / NV_USER Base & RAMIN) = 0x%08x\n", nv3->nvbase.bar1_lfb_base); - - // this is likely mirrored - // 4x on 2mb cards - // 2x on 4mb cards - // and not at all on 8mb - - /* TODO: 2MB */ - - // 4MB VRAM memory map: - // LFB_BASE+VRAM_SIZE=RAMIN Mirror(?) 0x1400000 (VERIFY PCBOX) - // LFB_BASE+VRAM_SIZE*2=LFB Mirror(?) 0x1800000 - // LFB_BASE+VRAM_SIZE*3=Definitely RAMIN (then it ends, the total ram space is 16mb) 0x1C00000 - - // 8MB VRAM memory map: - // LFB_BASE->LFB_BASE+VRAM_SIZE=LFB - // What is in 800000-c00000? - // LFB_BASE+0xC00000 = RAMIN - - if (nv3->nvbase.bar1_lfb_base) - { - if (nv3->nvbase.vram_amount == NV3_VRAM_SIZE_4MB) - { - mem_mapping_set_addr(&nv3->nvbase.framebuffer_mapping, nv3->nvbase.bar1_lfb_base, NV3_VRAM_SIZE_4MB); - mem_mapping_set_addr(&nv3->nvbase.ramin_mapping_mirror, nv3->nvbase.bar1_lfb_base + NV3_LFB_RAMIN_MIRROR_START, NV3_LFB_MAPPING_SIZE); - mem_mapping_set_addr(&nv3->nvbase.framebuffer_mapping_mirror, nv3->nvbase.bar1_lfb_base + NV3_LFB_MIRROR_START, NV3_VRAM_SIZE_4MB); - mem_mapping_set_addr(&nv3->nvbase.ramin_mapping, nv3->nvbase.bar1_lfb_base + NV3_LFB_RAMIN_START, NV3_LFB_MAPPING_SIZE); - } - else if (nv3->nvbase.vram_amount == NV3_VRAM_SIZE_8MB) - { - // we don't need this one in the case of 8mb, because regular mapping is 8mb - mem_mapping_disable(&nv3->nvbase.ramin_mapping_mirror); - mem_mapping_set_addr(&nv3->nvbase.framebuffer_mapping, nv3->nvbase.bar1_lfb_base, NV3_VRAM_SIZE_8MB); - mem_mapping_set_addr(&nv3->nvbase.framebuffer_mapping_mirror, nv3->nvbase.bar1_lfb_base + NV3_LFB_MIRROR_START, NV3_LFB_MAPPING_SIZE); - mem_mapping_set_addr(&nv3->nvbase.ramin_mapping, nv3->nvbase.bar1_lfb_base + NV3_LFB_RAMIN_START, NV3_LFB_MAPPING_SIZE); - } - else - { - fatal("NV3 2MB not implemented yet"); - } - } - - // Did we change the banked SVGA mode? - switch (nv3->nvbase.svga.gdcreg[0x06] & 0x0c) - { - case NV3_CRTC_BANKED_128K_A0000: - nv_log("SVGA Banked Mode = 128K @ A0000h\n"); - mem_mapping_set_addr(&nv3->nvbase.svga.mapping, 0xA0000, 0x20000); // 128kb @ 0xA0000 - nv3->nvbase.svga.banked_mask = 0x1FFFF; - break; - case NV3_CRTC_BANKED_64K_A0000: - nv_log("SVGA Banked Mode = 64K @ A0000h\n"); - mem_mapping_set_addr(&nv3->nvbase.svga.mapping, 0xA0000, 0x10000); // 64kb @ 0xA0000 - nv3->nvbase.svga.banked_mask = 0xFFFF; - break; - case NV3_CRTC_BANKED_32K_B0000: - nv_log("SVGA Banked Mode = 32K @ B0000h\n"); - mem_mapping_set_addr(&nv3->nvbase.svga.mapping, 0xB0000, 0x8000); // 32kb @ 0xB0000 - nv3->nvbase.svga.banked_mask = 0x7FFF; - break; - case NV3_CRTC_BANKED_32K_B8000: - nv_log("SVGA Banked Mode = 32K @ B8000h\n"); - mem_mapping_set_addr(&nv3->nvbase.svga.mapping, 0xB8000, 0x8000); // 32kb @ 0xB8000 - nv3->nvbase.svga.banked_mask = 0x7FFF; - break; - } -} - -// -// Init code -// -void* nv3_init(const device_t *info) -{ - // set the vram amount and gpu revision - - /* We don't bother looking these up if they are nonzero. On Riva 128 ZX, they are already set by the init function (always 8 MB VRAM + Revision C0) */ - if (!nv3->nvbase.vram_amount) - nv3->nvbase.vram_amount = device_get_config_int("vram_size"); - - if (!nv3->nvbase.gpu_revision) - nv3->nvbase.gpu_revision = device_get_config_int("chip_revision"); - - /* Set log device name based on card model */ - const char* log_device_name = (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) ? "NV3T" : "NV3"; - - if (device_get_config_int("nv_debug_fulllog")) - nv3->nvbase.log = log_open(log_device_name); - else - nv3->nvbase.log = log_open_cyclic(log_device_name); - -#ifdef ENABLE_NV_LOG - // Allows nv_log to be used for multiple nvidia devices - nv_log_set_device(nv3->nvbase.log); -#endif - nv_log("Initialising core\n"); - - // this will only be logged if ENABLE_NV_LOG_ULTRA is defined - nv_log_verbose_only("ULTRA LOGGING enabled"); - - // Figure out which vbios the user selected - // This depends on the bus we are using and if the gpu is rev a/b or rev c - const char* vbios_id = device_get_config_bios("vbios"); - const char* vbios_file = ""; - - if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) - { - if (nv3->nvbase.bus_generation == nv_bus_pci) - vbios_file = device_get_bios_file(&nv3t_device_pci, vbios_id, 0); - else - vbios_file = device_get_bios_file(&nv3t_device_agp, vbios_id, 0); - } - else - { - if (nv3->nvbase.bus_generation == nv_bus_pci) - vbios_file = device_get_bios_file(&nv3_device_pci, vbios_id, 0); - else - vbios_file = device_get_bios_file(&nv3_device_agp, vbios_id, 0); - } - - - int32_t err = rom_init(&nv3->nvbase.vbios, vbios_file, 0xC0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - if (err) - { - nv_log("NV3 FATAL: failed to load VBIOS err=%d\n", err); - fatal("Nvidia NV3 init failed: Somehow selected a nonexistent VBIOS? err=%d\n", err); - return NULL; - } - else - nv_log("Successfully loaded VBIOS %s located at %s\n", vbios_id, vbios_file); - - // set up the bus and start setting up SVGA core - if (nv3->nvbase.bus_generation == nv_bus_pci) - { - nv_log("Using PCI bus\n"); - - pci_add_card(PCI_ADD_NORMAL, nv3_pci_read, nv3_pci_write, NULL, &nv3->nvbase.pci_slot); - - /* Initialise the right revision of the card */ - if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) - { - svga_init(&nv3t_device_pci, &nv3->nvbase.svga, nv3, nv3->nvbase.vram_amount, - nv3_recalc_timings, nv3_svga_read, nv3_svga_write, nv3_draw_cursor, NULL); - - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_nv3t_pci); - } - else - { - svga_init(&nv3_device_pci, &nv3->nvbase.svga, nv3, nv3->nvbase.vram_amount, - nv3_recalc_timings, nv3_svga_read, nv3_svga_write, nv3_draw_cursor, NULL); - - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_nv3_pci); - } - - } - else if (nv3->nvbase.bus_generation == nv_bus_agp_1x - || nv3->nvbase.bus_generation == nv_bus_agp_2x) - { - nv_log("Using AGP 1X/2X bus\n"); - - pci_add_card(PCI_ADD_AGP, nv3_pci_read, nv3_pci_write, NULL, &nv3->nvbase.pci_slot); - - /* Initialise the right revision of the card */ - if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) - { - svga_init(&nv3t_device_agp, &nv3->nvbase.svga, nv3, nv3->nvbase.vram_amount, - nv3_recalc_timings, nv3_svga_read, nv3_svga_write, nv3_draw_cursor, NULL); - - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_nv3t_agp); - } - else - { - svga_init(&nv3_device_agp, &nv3->nvbase.svga, nv3, nv3->nvbase.vram_amount, - nv3_recalc_timings, nv3_svga_read, nv3_svga_write, nv3_draw_cursor, NULL); - - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_nv3_agp); - } - } - - // set vram - nv_log("VRAM=%d bytes\n", nv3->nvbase.svga.vram_max); - - // init memory mappings - nv3_init_mappings(); - - // make us actually exist - nv3->nvbase.pci_config.int_line = 0xFF; // per datasheet - nv3->nvbase.pci_config.pci_regs[PCI_REG_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEM; - - // svga is done, so now initialise the real gpu - - nv_log("Initialising GPU core...\n"); - - nv3_pextdev_init(); // Initialise Straps - nv3_pmc_init(); // Initialise Master Control - nv3_pbus_init(); // Initialise Bus (the 128 part of riva) - nv3_pfb_init(); // Initialise Framebuffer Interface - nv3_pramdac_init(); // Initialise RAMDAC (CLUT, final pixel presentation etc) - nv3_pfifo_init(); // Initialise FIFO for graphics object submission - nv3_pgraph_init(); // Initialise accelerated graphics engine - nv3_ptimer_init(); // Initialise programmable interval timer - nv3_pvideo_init(); // Initialise video overlay engine - - nv_log("Initialising I2C..."); - nv3->nvbase.i2c = i2c_gpio_init("nv3_i2c"); - nv3->nvbase.ddc = ddc_init(i2c_gpio_get_bus(nv3->nvbase.i2c)); - - return nv3; -} - -// RIVA 128 PCI initialisation function: This function simply allocates the device struct, and sets the bus to PCI before initialising. -void* nv3_init_pci(const device_t* info) -{ - nv3 = (nv3_t*)calloc(1, sizeof(nv3_t)); - nv3->nvbase.bus_generation = nv_bus_pci; - nv3_init(info); - return nv3; -} - -// RIVA 128 AGP initialisation function: This function simply allocates the device struct, and sets the bus to AGP before initialising. -void* nv3_init_agp(const device_t* info) -{ - nv3 = (nv3_t*)calloc(1, sizeof(nv3_t)); - nv3->nvbase.bus_generation = nv_bus_agp_1x; - nv3_init(info); - return nv3; -} - -// RIVA 128 ZX PCI initialisation function: This function simply allocates the device struct, and sets the bus to PCI before initialising. -// It also sets the GPU revision to C0 because NV3T config doesn't let you configure the rev (there were multiple steppings, but it's basically irrelevant), -// and sets RAM to 8 MB (the only supported config on ZX cards) -void* nv3t_init_pci(const device_t* info) -{ - nv3 = (nv3_t*)calloc(1, sizeof(nv3_t)); - nv3->nvbase.bus_generation = nv_bus_pci; - nv3->nvbase.gpu_revision = NV3_PCI_CFG_REVISION_C00; - nv3->nvbase.vram_amount = NV3_VRAM_SIZE_8MB; - nv3_init(info); - return nv3; -} - -// RIVA 128 ZX AGP initialisation function: This function simply allocates the device struct, and sets the bus to AGP before initialising. -// It also sets the GPU revision to C0 because NV3T config doesn't let you configure the rev (there were multiple steppings, but it's basically irrelevant) -// and sets RAM to 8 MB (the only supported config on ZX cards) -void* nv3t_init_agp(const device_t* info) -{ - nv3 = (nv3_t*)calloc(1, sizeof(nv3_t)); - nv3->nvbase.bus_generation = nv_bus_agp_2x; // Riva 128 ZX is AGP2X - nv3->nvbase.gpu_revision = NV3_PCI_CFG_REVISION_C00; - nv3->nvbase.vram_amount = NV3_VRAM_SIZE_8MB; - nv3_init(info); - return nv3; -} - -void nv3_close(void* priv) -{ - // Shut down logging - log_close(nv3->nvbase.log); -#ifdef ENABLE_NV_LOG - nv_log_set_device(NULL); -#endif - - // Shut down I2C and the DDC - ddc_close(nv3->nvbase.ddc); - i2c_gpio_close(nv3->nvbase.i2c); - - // Destroy the Rivatimers. (It doesn't matter if they are running.) - rivatimer_destroy(nv3->nvbase.pixel_clock_timer); - rivatimer_destroy(nv3->nvbase.memory_clock_timer); - - // Shut down SVGA - svga_close(&nv3->nvbase.svga); - free(nv3); - nv3 = NULL; -} - -// See if the bios rom is available. -int32_t nv3_available(void) -{ - return rom_present(NV3_VBIOS_ASUS_V3000_V151) - || rom_present(NV3_VBIOS_DIAMOND_V330_V162) - || rom_present(NV3_VBIOS_ERAZOR_V14700) - || rom_present(NV3_VBIOS_ERAZOR_V15403) - || rom_present(NV3_VBIOS_ERAZOR_V15500) - || rom_present(NV3_VBIOS_STB_V128_V182) - || rom_present(NV3_VBIOS_STB_V128_V182) - || rom_present(NV3T_VBIOS_ASUS_V170) - || rom_present(NV3T_VBIOS_DIAMOND_V330_V182B) - || rom_present(NV3T_VBIOS_REFERENCE_CEK_V171) - || rom_present(NV3T_VBIOS_REFERENCE_CEK_V172); -} - -// NV3 (RIVA 128) -// PCI -// 2MB or 4MB VRAM -const device_t nv3_device_pci = -{ - .name = "nVIDIA RIVA 128 (NV3) PCI", - .internal_name = "nv3_pci", - .flags = DEVICE_PCI, - .local = 0, - .init = nv3_init_pci, - .close = nv3_close, - .speed_changed = nv3_speed_changed, - .force_redraw = nv3_force_redraw, - .available = nv3_available, - .config = nv3_config, -}; - -// NV3 (RIVA 128) -// AGP -// 2MB or 4MB VRAM -const device_t nv3_device_agp = -{ - .name = "nVIDIA RIVA 128 (NV3) AGP", - .internal_name = "nv3_agp", - .flags = DEVICE_AGP, - .local = 0, - .init = nv3_init_agp, - .close = nv3_close, - .speed_changed = nv3_speed_changed, - .force_redraw = nv3_force_redraw, - .available = nv3_available, - .config = nv3_config, -}; - -// NV3T (RIVA 128 ZX) -// PCI -// 8MB VRAM -const device_t nv3t_device_pci = -{ - .name = "nVIDIA RIVA 128 ZX (NV3T) PCI", - .internal_name = "nv3t_pci", - .flags = DEVICE_PCI, - .local = 0, - .init = nv3t_init_pci, - .close = nv3_close, - .speed_changed = nv3_speed_changed, - .force_redraw = nv3_force_redraw, - .available = nv3_available, - .config = nv3t_config, -}; - -// NV3T (RIVA 128) -// AGP -// 2MB or 4MB VRAM -const device_t nv3t_device_agp = -{ - .name = "nVIDIA RIVA 128 ZX (NV3T) AGP", - .internal_name = "nv3t_agp", - .flags = DEVICE_AGP, - .local = 0, - .init = nv3t_init_agp, - .close = nv3_close, - .speed_changed = nv3_speed_changed, - .force_redraw = nv3_force_redraw, - .available = nv3_available, - .config = nv3t_config, -}; \ No newline at end of file diff --git a/src/video/nv/nv3/nv3_core_arbiter.c b/src/video/nv/nv3/nv3_core_arbiter.c deleted file mode 100644 index 3399ca9fe..000000000 --- a/src/video/nv/nv3/nv3_core_arbiter.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * The insane NV3 MMIO arbiter. - * Writes to ALL sections of the GPU based on the write position - * All writes are internally considered to be 32-bit! Be careful... - * - * Also handles interrupt dispatch - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -// STANDARD NV3 includes -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -// Gets a register... -// move this somewhere else when we have more models -nv_register_t* nv_get_register(uint32_t address, nv_register_t* register_list, uint32_t num_regs) -{ - for (int32_t reg_num = 0; reg_num < num_regs; reg_num++) - { - if (register_list[reg_num].address == NV_REG_LIST_END) - break; //unimplemented - - if (register_list[reg_num].address == address) - return ®ister_list[reg_num]; - } - - return NULL; -} - -// Arbitrates an MMIO read -uint32_t nv3_mmio_arbitrate_read(uint32_t address) -{ - // sanity check - if (!nv3) - return 0x00; - - uint32_t ret = 0x00; - - // Ensure the addresses are dword aligned. - // I don't know why this is needed because writepriv32 is always to dword align, but it crashes if you don't do this. - if (!(address >= NV3_USER_DAC_PALETTE_START && address <= NV3_USER_DAC_PALETTE_END)) - address &= 0xFFFFFC; - - // gigantic set of if statements to send the write to the right subsystem - if (address >= NV3_PMC_START && address <= NV3_PMC_END) - ret = nv3_pmc_read(address); - else if (address >= NV3_CIO_START && address <= NV3_CIO_END) - ret = nv3_cio_read(address); - else if (address >= NV3_PBUS_PCI_START && address <= NV3_PBUS_PCI_END) - ret = nv3_pci_read(0x00, address & 0xFF, NULL); - else if (address >= NV3_PBUS_START && address <= NV3_PBUS_END) - ret = nv3_pbus_read(address); - else if (address >= NV3_PFIFO_START && address <= NV3_PFIFO_END) - ret = nv3_pfifo_read(address); - else if (address >= NV3_PFB_START && address <= NV3_PFB_END) - ret = nv3_pfb_read(address); - else if (address >= NV3_PRM_START && address <= NV3_PRM_END) - ret = nv3_prm_read(address); - else if (address >= NV3_PRMIO_START && address <= NV3_PRMIO_END) - ret = nv3_prmio_read(address); - else if (address >= NV3_PTIMER_START && address <= NV3_PTIMER_END) - ret = nv3_ptimer_read(address); - else if (address >= NV3_PFB_START && address <= NV3_PFB_END) - ret = nv3_pfb_read(address); - else if (address >= NV3_PEXTDEV_START && address <= NV3_PEXTDEV_END) - ret = nv3_pextdev_read(address); - else if (address >= NV3_PROM_START && address <= NV3_PROM_END) - ret = nv3_prom_read(address); - else if (address >= NV3_PALT_START && address <= NV3_PALT_END) - ret = nv3_palt_read(address); - else if (address >= NV3_PME_START && address <= NV3_PME_END) - ret = nv3_pme_read(address); - else if (address >= NV3_PGRAPH_START && address <= NV3_PGRAPH_REAL_END) // what we're actually doing here determined by nv3_pgraph_* func - ret = nv3_pgraph_read(address); - else if (address >= NV3_PRMCIO_START && address <= NV3_PRMCIO_END) - ret = nv3_prmcio_read(address); - else if (address >= NV3_PVIDEO_START && address <= NV3_PVIDEO_END) - ret = nv3_pvideo_read(address); - else if ((address >= NV3_PRAMDAC_START && address <= NV3_PRAMDAC_END) - || (address >= NV3_USER_DAC_PALETTE_START && address <= NV3_USER_DAC_PALETTE_END)) //clut - ret = nv3_pramdac_read(address); - else if (address >= NV3_VRAM_START && address <= NV3_VRAM_END) - ret = nv3_dfb_read32(address & nv3->nvbase.svga.vram_mask, &nv3->nvbase.svga); - else if (address >= NV3_USER_START && address <= NV3_USER_END) - ret = nv3_user_read(address); - else - { - //nvplay stuff - //#ifdef ENABLE_NV_LOG_ULTRA - //warning("MMIO read arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning unmapped pattern]\n", address); - //#else - nv_log("MMIO read arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning unmapped pattern]\n", address); - //#endif - - // The real hardware returns a garbage pattern - return 0x00; - } - - return ret; -} - -void nv3_mmio_arbitrate_write(uint32_t address, uint32_t value) -{ - // sanity check - 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; - - - // Ensure the addresses are dword aligned. - // I don't know why this is needed because writepriv32 is always dword aligned in Nvidia's drivers, but it crashes if you don't do this. - // Exclude the 4bpp/8bpp CLUT for this purpose - if (!(address >= NV3_USER_DAC_PALETTE_START && address <= NV3_USER_DAC_PALETTE_END)) - address &= 0xFFFFFC; - - // gigantic set of if statements to send the write to the right subsystem - if (address >= NV3_PMC_START && address <= NV3_PMC_END) - nv3_pmc_write(address, value); - else if (address >= NV3_CIO_START && address <= NV3_CIO_END) - nv3_cio_write(address, value); - else if (address >= NV3_PBUS_PCI_START && address <= NV3_PBUS_PCI_END) // PCI mirrored at 0x1800 in MMIO - nv3_pci_write(0x00, address & 0xFF, value, NULL); // priv does not matter - else if (address >= NV3_PBUS_START && address <= NV3_PBUS_END) - nv3_pbus_write(address, value); - else if (address >= NV3_PFIFO_START && address <= NV3_PFIFO_END) - nv3_pfifo_write(address, value); - else if (address >= NV3_PRM_START && address <= NV3_PRM_END) - nv3_prm_write(address, value); - else if (address >= NV3_PRMIO_START && address <= NV3_PRMIO_END) - nv3_prmio_write(address, value); - else if (address >= NV3_PTIMER_START && address <= NV3_PTIMER_END) - nv3_ptimer_write(address, value); - else if (address >= NV3_PFB_START && address <= NV3_PFB_END) - nv3_pfb_write(address, value); - else if (address >= NV3_PEXTDEV_START && address <= NV3_PEXTDEV_END) - nv3_pextdev_write(address, value); - else if (address >= NV3_PROM_START && address <= NV3_PROM_END) - nv3_prom_write(address, value); - else if (address >= NV3_PALT_START && address <= NV3_PALT_END) - nv3_palt_write(address, value); - else if (address >= NV3_PME_START && address <= NV3_PME_END) - nv3_pme_write(address, value); - else if (address >= NV3_PGRAPH_START && address <= NV3_PGRAPH_REAL_END) // what we're actually doing here is determined by the nv3_pgraph_* functions - nv3_pgraph_write(address, value); - else if (address >= NV3_PRMCIO_START && address <= NV3_PRMCIO_END) - nv3_prmcio_write(address, value); - else if (address >= NV3_PVIDEO_START && address <= NV3_PVIDEO_END) - nv3_pvideo_write(address, value); - else if ((address >= NV3_PRAMDAC_START && address <= NV3_PRAMDAC_END) - || (address >= NV3_USER_DAC_PALETTE_START && address <= NV3_USER_DAC_PALETTE_END)) //clut - nv3_pramdac_write(address, value); - else if (address >= NV3_VRAM_START && address <= NV3_VRAM_END) - nv3_dfb_write32(address, value, &nv3->nvbase.svga); - else if (address >= NV3_USER_START && address <= NV3_USER_END) - nv3_user_write(address, value); - //RAMIN is its own thing - else - { - //nvplay stuff - //#ifdef ENABLE_NV_LOG_ULTRA - //warning("MMIO write arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning 0x00]\n", address); - //#else - nv_log("MMIO write arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning 0x00]\n", address); - //#endif - - return; - } -} - - -// // -// ******* DUMMY FUNCTIONS FOR UNIMPLEMENTED SUBSYSTEMS ******* // -// // - -// Read and Write functions for GPU subsystems -// Remove the ones that aren't used here eventually, have all of htem for now -uint32_t nv3_cio_read(uint32_t address) { return 0; }; -void nv3_cio_write(uint32_t address, uint32_t value) {}; -uint32_t nv3_prm_read(uint32_t address) { return 0; }; -void nv3_prm_write(uint32_t address, uint32_t value) {}; -uint32_t nv3_prmio_read(uint32_t address) { return 0; }; -void nv3_prmio_write(uint32_t address, uint32_t value) {}; - -uint32_t nv3_palt_read(uint32_t address) { return 0; }; -void nv3_palt_write(uint32_t address, uint32_t value) {}; - -// TODO: PGRAPH class registers -uint32_t nv3_prmcio_read(uint32_t address) { return 0; }; -void nv3_prmcio_write(uint32_t address, uint32_t value) {}; diff --git a/src/video/nv/nv3/nv3_core_config.c b/src/video/nv/nv3/nv3_core_config.c deleted file mode 100644 index b039ff82b..000000000 --- a/src/video/nv/nv3/nv3_core_config.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Provides NV3 configuration - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -const device_config_t nv3_config[] = -{ - // VBIOS type configuration - { - .name = "vbios", - .description = "Model", - .type = CONFIG_BIOS, - .default_string = "NV3_VBIOS_ERAZOR_V15403", - .default_int = 0, - .bios = - { - - { - .name = "ELSA VICTORY Erazor - Version 1.47.00", .files_no = 1, - .internal_name = "NV3_VBIOS_ERAZOR_V14700", - .files = {NV3_VBIOS_ERAZOR_V14700, ""} - }, - { - .name = "ELSA VICTORY Erazor - Version 1.54.03", .files_no = 1, - .internal_name = "NV3_VBIOS_ERAZOR_V15403", - .files = {NV3_VBIOS_ERAZOR_V15403, ""} - }, - { - .name = "ELSA VICTORY Erazor - Version 1.55.00", .files_no = 1, - .internal_name = "NV3_VBIOS_ERAZOR_V15500", - .files = {NV3_VBIOS_ERAZOR_V15500, ""} - }, - { - .name = "Diamond Viper V330 - Version 1.62-CO", .files_no = 1, - .internal_name = "NV3_VBIOS_DIAMOND_V330_V162", - .files = {NV3_VBIOS_DIAMOND_V330_V162, ""}, - }, - { - .name = "ASUS AGP/3DP-V3000 - Version 1.51B", .files_no = 1, - .internal_name = "NV3_VBIOS_ASUS_V3000_V151", - .files = {NV3_VBIOS_ASUS_V3000_V151, ""}, - }, - { - .name = "STB Velocity 128 - Version 1.60 [BUGGY]", .files_no = 1, - .internal_name = "NV3_VBIOS_STB_V128_V160", - .files = {NV3_VBIOS_STB_V128_V160, ""}, - }, - { - .name = "STB Velocity 128 - Version 1.82", .files_no = 1, - .internal_name = "NV3_VBIOS_STB_V128_V182", - .files = {NV3_VBIOS_STB_V128_V182, ""}, - }, - } - }, - // Memory configuration - { - .name = "vram_size", - .description = "VRAM Size", - .type = CONFIG_SELECTION, - .default_int = NV3_VRAM_SIZE_4MB, - .selection = - { - // I thought this was never released, but it seems that at least one was released: - // The card was called the "NEC G7AGK" - { - .description = "2 MB", - .value = NV3_VRAM_SIZE_2MB, - }, - - { - .description = "4 MB", - .value = NV3_VRAM_SIZE_4MB, - }, - } - - }, - { - .name = "chip_revision", - .description = "Chip Revision", - .type = CONFIG_SELECTION, - .default_int = NV3_PCI_CFG_REVISION_B00, - .selection = - { - { - .description = "RIVA 128 Prototype (Revision A; January 1997)", - .value = NV3_PCI_CFG_REVISION_A00, - }, - { - .description = "RIVA 128 (Revision B)", - .value = NV3_PCI_CFG_REVISION_B00, - }, - } - }, - // Multithreading configuration - { - - .name = "pgraph_threads", -#ifndef RELEASE_BUILD - .description = "PFIFO/PGRAPH - Number of threads to split large object method execution into", -#else - .description = "Render threads", -#endif - .type = CONFIG_SELECTION, - .default_int = 1, // todo: change later - .selection = - { - { - .description = "1 thread (Only use if issues appear with more threads)", - .value = 1, - }, - { - .description = "2 threads", - .value = 2, - }, - { - .description = "4 threads", - .value = 4, - }, - { - .description = "8 threads", - .value = 8, - }, - }, - }, -#ifndef RELEASE_BUILD - { - .name = "nv_debug_fulllog", - .description = "Disable Cyclical Lines Detection for nv_log (Use for getting full context at cost of VERY large log files)", - .type = CONFIG_BINARY, - .default_int = 0, - }, -#endif - { - .type = CONFIG_END - } -}; - -const device_config_t nv3t_config[] = -{ - // VBIOS type configuration - { - .name = "vbios", - .description = "Model", - .type = CONFIG_BIOS, - .default_string = "NV3T_VBIOS_DIAMOND_V330_V182B", - .default_int = 0, - .bios = - { - { - - .name = "Diamond Multimedia Viper V330 8M BIOS - Version 1.82B", .files_no = 1, - .internal_name = "NV3T_VBIOS_DIAMOND_V330_V182B", - .files = {NV3T_VBIOS_DIAMOND_V330_V182B, ""}, - }, - { - .name = "ASUS AGP-V3000 ZXTV BIOS - V1.70D.03", .files_no = 1, - .internal_name = "NV3T_VBIOS_ASUS_V170", - .files = {NV3T_VBIOS_ASUS_V170, ""}, - }, - { - .name = "NVidia Reference BIOS - V1.71B-N", .files_no = 1, - - .internal_name = "NV3T_VBIOS_REFERENCE_CEK_V171", - .files = {NV3T_VBIOS_REFERENCE_CEK_V171, ""}, - }, - - { - .name = "NVidia Reference BIOS - V1.72B", .files_no = 1, - .internal_name = "NV3T_VBIOS_REFERENCE_CEK_V172", - .files = {NV3T_VBIOS_REFERENCE_CEK_V172, ""}, - }, - } - }, - // Multithreading configuration - { - - .name = "pgraph_threads", -#ifndef RELEASE_BUILD - .description = "PFIFO/PGRAPH - Number of threads to split large object method execution into", -#else - .description = "Render threads", -#endif - .type = CONFIG_SELECTION, - .default_int = 1, // todo: change later - .selection = - { - { - .description = "1 thread (Only use if issues appear with more threads)", - .value = 1, - }, - { - .description = "2 threads", - .value = 2, - }, - { - .description = "4 threads", - .value = 4, - }, - { - .description = "8 threads", - .value = 8, - }, - }, - }, -#ifndef RELEASE_BUILD - { - .name = "nv_debug_fulllog", - .description = "Disable Cyclical Lines Detection for nv_log (Use for getting full context at cost of VERY large log files)", - .type = CONFIG_BINARY, - .default_int = 0, - }, -#endif - { - .type = CONFIG_END - } -}; \ No newline at end of file diff --git a/src/video/nv/nv3/render/nv3_render_blit.c b/src/video/nv/nv3/render/nv3_render_blit.c deleted file mode 100644 index 92b657cd0..000000000 --- a/src/video/nv/nv3/render/nv3_render_blit.c +++ /dev/null @@ -1,229 +0,0 @@ -/* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* NV3 Core rendering code (Software version) -* -* -* -* Authors: Connor Hyde, I need a better email address ;^) -* -* Copyright 2024-2025 Connor Hyde -*/ - -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/plat.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -/* Check the line bounds */ -void nv3_class_011_check_line_bounds(void) -{ - uint32_t relative_x = nv3->pgraph.image_current_position.x - nv3->pgraph.image.point.x; - - /* In the case of class 0x11 there is no requirement to check for relative_y because we have exceeded the size of the image */ - if (relative_x >= nv3->pgraph.image.size_in.x) - { - nv3->pgraph.image_current_position.y++; - nv3->pgraph.image_current_position.x = nv3->pgraph.image.point.x; - } -} - -/* Renders an image from cpu */ -void nv3_render_blit_image(uint32_t color, nv3_grobj_t grobj) -{ - /* todo: a lot of stuff */ - - uint32_t pixel0 = 0, pixel1 = 0, pixel2 = 0, pixel3 = 0; - - /* Some extra data is sent as padding, we need to clip it off using size_out */ - - uint16_t clip_x = nv3->pgraph.image.point.x + nv3->pgraph.image.size.x; - /* we need to unpack them - IF THIS IS USED SOMEWHERE ELSE, DO SOMETHING ELSE WITH IT */ - /* the reverse order is due to the endianness */ - switch (nv3->nvbase.svga.bpp) - { - // 4 pixels packed into one color in 8bpp - case 8: - - //pixel3 - pixel3 = color & 0xFF; - if (nv3->pgraph.image_current_position.x < clip_x) nv3_render_write_pixel(nv3->pgraph.image_current_position, pixel3, grobj); - nv3->pgraph.image_current_position.x++; - nv3_class_011_check_line_bounds(); - - pixel2 = (color >> 8) & 0xFF; - if (nv3->pgraph.image_current_position.x < clip_x) nv3_render_write_pixel(nv3->pgraph.image_current_position, pixel2, grobj); - nv3->pgraph.image_current_position.x++; - nv3_class_011_check_line_bounds(); - - pixel1 = (color >> 16) & 0xFF; - if (nv3->pgraph.image_current_position.x < clip_x) nv3_render_write_pixel(nv3->pgraph.image_current_position, pixel1, grobj); - nv3->pgraph.image_current_position.x++; - nv3_class_011_check_line_bounds(); - - pixel0 = (color >> 24) & 0xFF; - if (nv3->pgraph.image_current_position.x < clip_x) nv3_render_write_pixel(nv3->pgraph.image_current_position, pixel0, grobj); - nv3->pgraph.image_current_position.x++; - nv3_class_011_check_line_bounds(); - - break; - // 2 pixels packed into one color in 15/16bpp - case 15: - case 16: - pixel1 = (color) & 0xFFFF; - if (nv3->pgraph.image_current_position.x < (clip_x)) nv3_render_write_pixel(nv3->pgraph.image_current_position, pixel1, grobj); - nv3->pgraph.image_current_position.x++; - nv3_class_011_check_line_bounds(); - - pixel0 = (color >> 16) & 0xFFFF; - if (nv3->pgraph.image_current_position.x < (clip_x)) nv3_render_write_pixel(nv3->pgraph.image_current_position, pixel0, grobj); - nv3->pgraph.image_current_position.x++; - nv3_class_011_check_line_bounds(); - - break; - // just one pixel in 32bpp - case 32: - if (nv3->pgraph.image_current_position.x < clip_x) nv3_render_write_pixel(nv3->pgraph.image_current_position, color, grobj); - nv3->pgraph.image_current_position.x++; - nv3_class_011_check_line_bounds(); - - break; - } -} - - -#define NV3_MAX_HORIZONTAL_SIZE 1920 -#define NV3_MAX_VERTICAL_SIZE 1200 - -/* 1920 for margin. Holds a buffer of the old screen we want to hold so we don't overwrite things we already overwtote -We only need to clear it once per blit, because the blits are always the same size, and then only for the size of our new blit - -Extremely not crazy about this...Surely a better way to do it without buffering the ENTIRE SCREEN. I only update the parts that are needed, but still... - -This is LUDICROUSLY INEFFICIENT (2*O(n^2)) and COMPLETELY TERRIBLE code, but it's currently 2:48am so I can't think of a better approach... -*/ -uint32_t nv3_s2sb_line_buffer[NV3_MAX_HORIZONTAL_SIZE*NV3_MAX_VERTICAL_SIZE] = {0}; - -void nv3_render_blit_screen2screen_for_buffer(nv3_grobj_t grobj, uint32_t dst_buffer) -{ - if (nv3->pgraph.blit.size.x < NV3_MAX_HORIZONTAL_SIZE - && nv3->pgraph.blit.size.y < NV3_MAX_VERTICAL_SIZE) - memset(&nv3_s2sb_line_buffer, 0x00, (sizeof(uint32_t) * nv3->pgraph.blit.size.y) * (sizeof(uint32_t) * nv3->pgraph.blit.size.x)); - - /* First calculate our source and destination buffer */ - uint32_t src_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER) & 0x03; - - nv3_coord_16_t in_position = nv3->pgraph.blit.point_in; - nv3_coord_16_t out_position = nv3->pgraph.blit.point_out; - - /* Coordinates for copying an entire line at a time */ - uint32_t buf_position = 0, vram_position = 0, size_x = nv3->pgraph.blit.size.x; - - /* - Read the old pixel into the line buffer - Assumption: All data is sent in an unpacked format. In the case of an NVIDIA GPU this means that all data is sent 32 bits at a time regardless of if - the actual source data is 32 bits in size or not. For pixel data, the upper bits are left as 0 in 8bpp/16bpp mode. For 86box purposes, the data is written - 8/16 bits at a time. - - TODO: CHECK FOR PACKED FORMAT!!!!! - */ - - if (nv3->nvbase.svga.bpp == 15 - || nv3->nvbase.svga.bpp == 16) - size_x <<= 1; - else if (nv3->nvbase.svga.bpp == 32) - size_x <<= 2; - - for (int32_t y = 0; y < nv3->pgraph.blit.size.y; y++) - { - buf_position = (nv3->pgraph.blit.size.x * y); - /* shouldn't matter in non-wtf mode */ - vram_position = nv3_render_get_vram_address_for_buffer(in_position, src_buffer); - - memcpy(&nv3_s2sb_line_buffer[buf_position], &nv3->nvbase.svga.vram[vram_position], size_x); - in_position.y++; - /* 32bit buffer */ - } - - /* simply write it all back to vram */ - for (int32_t y = 0; y < nv3->pgraph.blit.size.y; y++) - { - buf_position = (nv3->pgraph.blit.size.x * y); - vram_position = nv3_render_get_vram_address_for_buffer(out_position, dst_buffer); - - memcpy(&nv3->nvbase.svga.vram[vram_position], &nv3_s2sb_line_buffer[buf_position], size_x); - out_position.y++; - } - - /* - //32bit only as a test - uint32_t* vram_32 = (uint32_t*)nv3->nvbase.svga.vram; - - if (nv3->pgraph.boffset[src_buffer] != nv3->pgraph.boffset[dst_buffer]) - { - // stretch out the position to the new one - - nv3_coord_16_t current_pos_in; - nv3_coord_16_t current_pos_out; - - current_pos_in.x = nv3->pgraph.blit.point_in.x; - current_pos_in.y = nv3->pgraph.blit.point_in.y; - current_pos_out.x = nv3->pgraph.blit.point_out.x; - current_pos_out.y = nv3->pgraph.blit.point_out.y; - - for (uint32_t y = 0; y < nv3->pgraph.blit.size.y; y++) - { - current_pos_in.y = nv3->pgraph.blit.point_in.y + y; - current_pos_out.y = nv3->pgraph.blit.point_out.y + y; - - for (uint32_t x = 0; x < nv3->pgraph.blit.size.x; x++) - { - current_pos_in.x = nv3->pgraph.blit.point_in.x + x; - current_pos_out.x = nv3->pgraph.blit.point_out.x + x; - - uint32_t index = nv3_render_get_vram_address_for_buffer(current_pos_in, dst_buffer) >> 2; - uint32_t index_dst = nv3_render_get_vram_address_for_buffer(current_pos_out, src_buffer) >> 2; - - vram_32[index_dst] = vram_32[index]; - - //nv3_render_write_pixel(current_pos, vram_32[index], grobj); - } - - current_pos_in.x = nv3->pgraph.blit.point_in.x; - current_pos_out.x = nv3->pgraph.blit.point_out.x; - - } - } - */ -} - -void nv3_render_blit_screen2screen(nv3_grobj_t grobj) -{ - uint32_t dst_buffer = (nv3_pgraph_destination_buffer)grobj.grobj_0; // 5 = just use the source buffer - - if (dst_buffer & pgraph_dest_buffer0) - nv3_render_blit_screen2screen_for_buffer(grobj, 0); - if (dst_buffer & pgraph_dest_buffer1) - nv3_render_blit_screen2screen_for_buffer(grobj, 1); - if (dst_buffer & pgraph_dest_buffer2) - nv3_render_blit_screen2screen_for_buffer(grobj, 2); - if (dst_buffer & pgraph_dest_buffer3) - nv3_render_blit_screen2screen_for_buffer(grobj, 3); - - -} \ No newline at end of file diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c deleted file mode 100644 index c40fa84a9..000000000 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ /dev/null @@ -1,869 +0,0 @@ -/* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* NV3 Core rendering code (Software version) -* -* -* -* Authors: Connor Hyde, I need a better email address ;^) -* -* Copyright 2024-2025 Connor Hyde -*/ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/plat.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> -#include <86box/utils/video_stdlib.h> - -/* Functions only used in this translation unit */ -void nv3_render_8bpp(uint32_t vram_start, nv3_coord_16_t screen_size); -void nv3_render_15bpp(uint32_t vram_start, nv3_coord_16_t screen_size); -void nv3_render_16bpp(uint32_t vram_start, nv3_coord_16_t screen_size); -void nv3_render_32bpp(uint32_t vram_start, nv3_coord_16_t screen_size); - -/* Expand a colour. - NOTE: THE GPU INTERNALLY OPERATES ON RGB10!!!!!!!!!!! -*/ -nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj) -{ - // grobj0 = seems to share the format of PGRAPH_CONTEXT_SWITCH register. - - uint8_t format = (grobj.grobj_0 & 0x07); - bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_ALPHA) & 0x01; - - nv3_color_expanded_t color_final; - // set the pixel format - color_final.pixel_format = format; - - nv_log_verbose_only("Expanding Colour 0x%08x using pgraph_pixel_format 0x%x alpha enabled=%d\n", color, format, alpha_enabled); - - - // default to fully opaque in case alpha is disabled - color_final.a = 0xFF; - - switch (format) - { - // ALL OF THESE TYPES ARE 32 BITS IN SIZE - - // 555 - case nv3_pgraph_pixel_format_r5g5b5: - // "stretch out" the colour - - color_final.a = (color >> 15) & 0x01; // will be ignored if alpha_enabled isn't used - color_final.r = ((color >> 10) & 0x1F) << 5; - color_final.g = ((color >> 5) & 0x1F) << 5; - color_final.b = (color & 0x1F) << 5; - - break; - // 888 (standard colour + 8-bit alpha) - case nv3_pgraph_pixel_format_r8g8b8: - if (alpha_enabled) - color_final.a = ((color >> 24) & 0xFF) * 4; - - color_final.r = ((color >> 16) & 0xFF) * 4; - color_final.g = ((color >> 8) & 0xFF) * 4; - color_final.b = (color & 0xFF) * 4; - - break; - case nv3_pgraph_pixel_format_r10g10b10: - color_final.a = (color >> 31) & 0x01; - color_final.r = (color >> 30) & 0x3FF; - color_final.g = (color >> 20) & 0x1FF; - color_final.b = (color >> 10); - - break; - case nv3_pgraph_pixel_format_y8: - /* Indexed mode */ - color_final.a = (color >> 8) & 0xFF; - - // yuv - color_final.r = color_final.g = color_final.b = (color & 0xFF) * 4; // convert to rgb10 - break; - case nv3_pgraph_pixel_format_y16: - color_final.a = (color >> 16) & 0xFFFF; - - // yuv - color_final.r = color_final.g = color_final.b = (color & 0xFFFF) * 4; // convert to rgb10 - break; - case nv3_pgraph_pixel_format_y420: - warning("nv3_render_expand_color: YUV420 not implemented\n"); - break; - default: - warning("nv3_render_expand_color unknown format %d", format); - break; - - } - - // i8 is a union under i16 - color_final.i16 = (color & 0xFFFF); - - return color_final; -} - -/* Used for chroma test */ -uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t color) -{ - uint8_t format = (grobj.grobj_0 & 0x07); - bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_ALPHA) & 0x01; - - nv_log_verbose_only("Downconverting Colour 0x%08x using pgraph_pixel_format 0x%x alpha enabled=%d\n", color, format, alpha_enabled); - - uint32_t packed_color = 0x00; - - switch (format) - { - case nv3_pgraph_pixel_format_r5g5b5: - packed_color = (color.r >> 5) << 10 | - (color.g >> 5) << 5 | - (color.b >> 5); - - break; - case nv3_pgraph_pixel_format_r8g8b8: - packed_color = (color.a) << 24 | // is this a thing? - (color.r >> 2) << 16 | - (color.g >> 2) << 8 | - color.b; - break; - case nv3_pgraph_pixel_format_r10g10b10: - /* sometimes alpha isn't used but we should incorporate it anyway */ - if (color.a > 0x00) packed_color |= (1 << 31); - - packed_color |= (color.r << 30); - packed_color |= (color.g << 20); - packed_color |= (color.b << 10); - break; - case nv3_pgraph_pixel_format_y8: /* i think this is just indexed mode. since r=g=b we can just take the indexed from the r */ - packed_color = nv3_render_get_palette_index((color.r >> 2) & 0xFF); - break; - case nv3_pgraph_pixel_format_y16: - warning("nv3_render_downconvert_color: Y16 not implemented"); - break; - case nv3_pgraph_pixel_format_y420: - warning("nv3_render_downconvert_color: YUV420 not implemented\n"); - break; - default: - warning("nv3_render_downconvert_color unknown format %d", format); - break; - - } - - return packed_color; -} - -/* Runs the chroma key/color key test */ -bool nv3_render_chroma_test(uint32_t color, nv3_grobj_t grobj) -{ - bool chroma_enabled = ((grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_CHROMA_KEY) & 0x01); - - if (!chroma_enabled) - return true; - - bool alpha = ((nv3->pgraph.chroma_key >> 31) & 0x01); - - if (!alpha) - return true; - - /* this is dumb but i'm lazy, if it kills perf, fix it later - we need to do some format shuffling */ - nv3_grobj_t grobj_fake = {0}; - grobj_fake.grobj_0 = 0x02; /* we don't care about any other bits */ - - nv3_color_expanded_t chroma_expanded = nv3_render_expand_color(nv3->pgraph.chroma_key, grobj_fake); - - uint32_t chroma_downconverted = nv3_render_downconvert_color(grobj, chroma_expanded); - - return !(chroma_downconverted == color); -} - -/* Convert expanded colour format to chroma key format */ -uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded) -{ - // convert the alpha to 1 bit. then return packed rgb10 - return !!expanded.a | (expanded.r << 30) | (expanded.g << 20) | (expanded.b << 10); -} - -/* Get a colour for a palette index. (The colours are 24 bit RGB888 with a 0xFF alpha added for some purposes.) */ -uint32_t nv3_render_get_palette_index(uint8_t index) -{ - uint32_t red_index = index * 3; - uint32_t green_index = red_index + 1; - uint32_t blue_index = red_index + 2; - - uint8_t red_colour = nv3->pramdac.palette[red_index]; - uint8_t green_colour = nv3->pramdac.palette[green_index]; - uint8_t blue_colour = nv3->pramdac.palette[blue_index]; - - /* Alpha is always 0xFF */ - return (0xFF << 24) | ((red_colour) << 16) | ((green_colour) << 8) | blue_colour; -} - -/* Convert a rgb10 colour to a pattern colour */ -void nv3_render_set_pattern_color(nv3_color_expanded_t pattern_colour, bool use_color1) -{ - /* select the right pattern colour, _rgb is already in RGB10 format, so we don't need to do any conversion */ - - if (!use_color1) - { - nv3->pgraph.pattern_color_0_alpha = (pattern_colour.a) & 0xFF; - nv3->pgraph.pattern_color_0_rgb.r = pattern_colour.r; - nv3->pgraph.pattern_color_0_rgb.g = pattern_colour.g; - nv3->pgraph.pattern_color_0_rgb.b = pattern_colour.b; - - } - else - { - nv3->pgraph.pattern_color_1_alpha = (pattern_colour.a) & 0xFF; - nv3->pgraph.pattern_color_1_rgb.r = pattern_colour.r; - nv3->pgraph.pattern_color_1_rgb.g = pattern_colour.g; - nv3->pgraph.pattern_color_1_rgb.b = pattern_colour.b; - } - -} - -/* Combine the current buffer with the pitch to get the address in the framebuffer to draw from for a given position. */ -uint32_t nv3_render_get_vram_address(nv3_coord_16_t position, nv3_grobj_t grobj) -{ - uint32_t vram_x = position.x; - uint32_t vram_y = position.y; - uint32_t current_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER) & 0x03; - - uint32_t framebuffer_bpp = nv3->nvbase.svga.bpp; - - // we have to multiply the x position by the number of bytes per pixel - switch (framebuffer_bpp) - { - case 8: - break; - case 15: - case 16: - vram_x = position.x << 1; - break; - case 32: - vram_x = position.x << 2; - break; - } - - uint32_t pixel_addr_vram = vram_x + (nv3->pgraph.bpitch[current_buffer] * vram_y) + nv3->pgraph.boffset[current_buffer]; - - pixel_addr_vram &= nv3->nvbase.svga.vram_mask; - - return pixel_addr_vram; -} - - -/* Combine the current buffer with the pitch to get the address in the video ram for a specific position relative to a specific framebuffer */ -uint32_t nv3_render_get_vram_address_for_buffer(nv3_coord_16_t position, uint32_t buffer) -{ - uint32_t vram_x = position.x; - uint32_t vram_y = position.y; - - uint32_t framebuffer_bpp = nv3->nvbase.svga.bpp; - - // we have to multiply the x position by the number of bytes per pixel - switch (framebuffer_bpp) - { - case 8: - break; - case 15: - case 16: - vram_x = position.x << 1; - break; - case 32: - vram_x = position.x << 2; - break; - } - - uint32_t pixel_addr_vram = vram_x + (nv3->pgraph.bpitch[buffer] * vram_y) + nv3->pgraph.boffset[buffer]; - - pixel_addr_vram &= nv3->nvbase.svga.vram_mask; - - return pixel_addr_vram; -} - -/* Convert a dumb framebuffer address to a position. No buffer setup or anything, but just start at 0,0 for address 0. */ -nv3_coord_16_t nv3_render_get_dfb_position(uint32_t vram_address) -{ - nv3_coord_16_t pos = {0}; - - uint32_t pitch = nv3->nvbase.svga.hdisp; - - if (nv3->nvbase.svga.bpp == 15 - || nv3->nvbase.svga.bpp == 16) - pitch <<= 1; - else if (nv3->nvbase.svga.bpp == 32) - pitch <<= 2; - - pos.y = (vram_address / pitch); - pos.x = (vram_address % pitch); - - /* Fixup our x position */ - if (nv3->nvbase.svga.bpp == 15 - || nv3->nvbase.svga.bpp == 16) - pos.x >>= 1; - else if (nv3->nvbase.svga.bpp == 32) - pos.x >>= 2; - - - /* there is some strange behaviour where it writes long past the end of the fb */ - if (pos.y >= nv3->nvbase.svga.monitor->target_buffer->h) pos.y = nv3->nvbase.svga.monitor->target_buffer->h - 1; - - return pos; -} - -/* Read an 8bpp pixel from the framebuffer. */ -uint8_t nv3_render_read_pixel_8(nv3_coord_16_t position, nv3_grobj_t grobj) -{ - // hope you call it with the right bit - uint32_t vram_address = nv3_render_get_vram_address(position, grobj); - - return nv3->nvbase.svga.vram[vram_address]; -} - -/* Read an 16bpp pixel from the framebuffer. */ -uint16_t nv3_render_read_pixel_16(nv3_coord_16_t position, nv3_grobj_t grobj) -{ - // hope you call it with the right bit - uint32_t vram_address = nv3_render_get_vram_address(position, grobj); - - uint16_t* vram_16 = (uint16_t*)(nv3->nvbase.svga.vram); - vram_address >>= 1; //convert to 16bit pointer - - return vram_16[vram_address]; -} - -/* Read an 16bpp pixel from the framebuffer. */ -uint32_t nv3_render_read_pixel_32(nv3_coord_16_t position, nv3_grobj_t grobj) -{ - // hope you call it with the right bit - uint32_t vram_address = nv3_render_get_vram_address(position, grobj); - - uint32_t* vram_32 = (uint32_t*)(nv3->nvbase.svga.vram); - vram_address >>= 2; //convert to 32bit pointer - - return vram_32[vram_address]; -} - -void nv3_render_write_pixel_to_buffer(nv3_coord_16_t position, uint32_t color, nv3_grobj_t grobj, uint32_t buffer) -{ - bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_ALPHA) & 0x01; - - int32_t clip_end_x = nv3->pgraph.clip_start.x + nv3->pgraph.clip_size.x; - int32_t clip_end_y = nv3->pgraph.clip_start.y + nv3->pgraph.clip_size.y; - - /* First, check our current buffer. */ - /* Then do the clip. */ - if (position.x < nv3->pgraph.clip_start.x - || position.y < nv3->pgraph.clip_start.y - || position.x > clip_end_x - || position.y > clip_end_y) - { - // DO NOT DRAW THE PIXEL - return; - } - - /* TODO: Plane Mask...*/ - if (!nv3_render_chroma_test(color, grobj)) - return; - - uint32_t pixel_addr_vram = nv3_render_get_vram_address_for_buffer(position, buffer); - - uint32_t rop_src = 0, rop_dst = 0, rop_pattern = 0; - uint8_t bit = 0x00; - - /* Get our pattern data, may move to another function */ - switch (nv3->pgraph.pattern.shape) - { - - /* This logic is from NV1 envytoos docs, but seems to be same on NV3*/ - case NV3_PATTERN_SHAPE_8X8: - bit = (position.x & 7) | (position.y & 7) << 3; - break; - case NV3_PATTERN_SHAPE_1X64: - bit = (position.x & 0x3f); - break; - case NV3_PATTERN_SHAPE_64X1: - bit = (position.y & 0x3f); - break; - } - - // pull out the actual bit and see which colour we need to use - - bool use_color1 = (nv3->pgraph.pattern_bitmap >> bit) & 0x01; - - if (!use_color1) - { - if (!nv3->pgraph.pattern_color_0_alpha) - return; - - /* This is stupid */ - rop_pattern = nv3_render_downconvert_color(grobj, nv3->pgraph.pattern_color_0_rgb); - } - else - { - if (!nv3->pgraph.pattern_color_1_alpha) - return; - - rop_pattern = nv3_render_downconvert_color(grobj, nv3->pgraph.pattern_color_1_rgb); - } - - - /* Go to vram and do the final ROP for a basic bitblit. - It seems we can skip the downconversion step *for now*, since (framebuffer bits per pixel) == (object bits per pixel) - I'm not sure how games will react. But it depends on how the D3D drivers operate, we may need ro convert texture formats to the current bpp internally. - - We use the pixel format of the destination buffer to achieve this (thanks frostbite2000) - */ - - // translate the patch config to GDI rop - uint32_t final_rop = nv3_render_translate_nvrop(grobj, nv3->pgraph.rop); - - uint32_t destination_format = (nv3->pgraph.bpixel[buffer]) & 0x03; - - switch (destination_format) - { - case bpixel_fmt_8bit: - rop_src = color & 0xFF; - rop_dst = nv3->nvbase.svga.vram[pixel_addr_vram]; - nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(final_rop, rop_src, rop_dst, rop_pattern) & 0xFF; - - nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount; - - break; - case bpixel_fmt_16bit: - { - uint16_t* vram_16 = (uint16_t*)(nv3->nvbase.svga.vram); - pixel_addr_vram >>= 1; - - // mask to 16bit - - rop_src = color & 0xFFFF; - - /* if alpha is turned on and we aren't in 565 mode, reject transparent pixels */ - bool is_16bpp = (nv3->pramdac.general_control >> NV3_PRAMDAC_GENERAL_CONTROL_565_MODE) & 0x01; - - // a1r5g5b5 - if (!is_16bpp) - { - if (alpha_enabled && - !(color & 0x8000)) - return; - } - - // convert to 15bpp or 16bpp based on if we are in 16bpp mode - - rop_dst = vram_16[pixel_addr_vram]; - - vram_16[pixel_addr_vram] = video_rop_gdi_ternary(final_rop, rop_src, rop_dst, rop_pattern) & 0xFFFF; - - nv3->nvbase.svga.changedvram[pixel_addr_vram >> 11] = changeframecount; - - break; - } - case bpixel_fmt_32bit: - { - uint32_t* vram_32 = (uint32_t*)(nv3->nvbase.svga.vram); - pixel_addr_vram >>= 2; - - rop_src = color; - rop_dst = vram_32[pixel_addr_vram]; - vram_32[pixel_addr_vram] = video_rop_gdi_ternary(final_rop, rop_src, rop_dst, rop_pattern); - - nv3->nvbase.svga.changedvram[pixel_addr_vram >> 10] = changeframecount; - - break; - } - } -} - -/* Plots a pixel. */ -void nv3_render_write_pixel(nv3_coord_16_t position, uint32_t color, nv3_grobj_t grobj) -{ - // PFB_0 is always set to hardcoded "NO_TILING" value of 0x1114. - // It seems, you are meant to use the CRTC - - nv3_pgraph_destination_buffer dst_buffer = (nv3_pgraph_destination_buffer)grobj.grobj_0; - - if (dst_buffer & (pgraph_dest_buffer0)) - nv3_render_write_pixel_to_buffer(position, color, grobj, 0); - if (dst_buffer & (pgraph_dest_buffer1)) - nv3_render_write_pixel_to_buffer(position, color, grobj, 1); - if (dst_buffer & (pgraph_dest_buffer2)) - nv3_render_write_pixel_to_buffer(position, color, grobj, 2); - if (dst_buffer & (pgraph_dest_buffer3)) - nv3_render_write_pixel_to_buffer(position, color, grobj, 3); -} - -/* Ensure the correct monitor size */ -void nv3_render_ensure_screen_size(void) -{ - /* First check if hdisp == xsize and dispend == ysize. */ - bool changed = false; - - if (nv3->nvbase.svga.hdisp != nv3->nvbase.svga.monitor->mon_xsize) - { - changed = true; - nv3->nvbase.svga.monitor->mon_xsize = nv3->nvbase.svga.hdisp; - } - - if (nv3->nvbase.svga.dispend != nv3->nvbase.svga.monitor->mon_ysize) - { - changed = true; - nv3->nvbase.svga.monitor->mon_ysize = nv3->nvbase.svga.dispend; - } - - /* - if either changed: - -> set resolution - -> set refresh rate - this is just a rough estimation right now. we need it as we only blit what changes - */ - if (changed) - { - nv3->nvbase.refresh_time = 1 / (nv3->nvbase.pixel_clock_frequency / (double)ysize / (double)xsize); // rivatimers count in microseconds - set_screen_size(xsize, ysize); - } - -} - - -/* Blit to the monitor from DFB, 8bpp */ -void nv3_render_current_bpp_dfb_8(uint32_t address) -{ - /* Broken as fuck early vbios does this. Wtf? */ - if (!nv3->nvbase.svga.hdisp) - return; - - nv3_coord_16_t size = {0}; - size.x = size.y = 1; - - nv3_coord_16_t pos = nv3_render_get_dfb_position(address); - - uint32_t* p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - uint32_t data = *(uint32_t*)&(nv3->nvbase.svga.vram[address]); - - *p = nv3_render_get_palette_index(data & 0xFF); -} - -/* Blit to the monitor from DFB, 15/16bpp */ -void nv3_render_current_bpp_dfb_16(uint32_t address) -{ - /* Broken as fuck early vbios does this. Wtf? */ - if (!nv3->nvbase.svga.hdisp) - return; - - nv3_coord_16_t size = {0}; - size.x = size.y = 1; - - nv3_coord_16_t pos = nv3_render_get_dfb_position(address); - - uint32_t* p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - uint32_t data = *(uint32_t*)&(nv3->nvbase.svga.vram[address]); - - if ((nv3->pramdac.general_control >> NV3_PRAMDAC_GENERAL_CONTROL_565_MODE) & 0x01) - /* should just "tip over" to the next line */ - *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, 16); - else - /* should just "tip over" to the next line */ - *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, 15); - - /*does 8bpp packed into 16 occur/ i would be surprised*/ -} - -/* Blit to the monitor from DFB, 32bpp */ -void nv3_render_current_bpp_dfb_32(uint32_t address) -{ - /* Broken as fuck early vbios does this. Wtf? */ - if (!nv3->nvbase.svga.hdisp) - return; - - nv3_coord_16_t size = {0}; - size.x = size.y = 1; - - nv3_coord_16_t pos = nv3_render_get_dfb_position(address); - - uint32_t data = *(uint32_t*)&(nv3->nvbase.svga.vram[address]); - - uint32_t* p = &nv3->nvbase.svga.monitor->target_buffer->line[pos.y][pos.x]; - - if (nv3->nvbase.svga.bpp == 32) - { - *p = data; - } - /* Packed format */ - else if (nv3->nvbase.svga.bpp == 15 - || nv3->nvbase.svga.bpp == 16) - { - *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, nv3->nvbase.svga.bpp); - *p++; - *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, (data >> 16) & 0xFFFF, nv3->nvbase.svga.bpp); - } -} - - -/* Blit to the monitor from GPU, current bpp */ -void nv3_render_current_bpp() -{ - /* Figure out the Display Buffer Address from the CRTC */ - - uint32_t dba = ((nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_RPC0] & 0x1F) << 16) - + (nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_STARTADDR_HIGH] << 8) - + nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_STARTADDR_LOW]; - - if (nv3->nvbase.debug_dba_enabled - && nv3->nvbase.debug_dba > 0) - dba = nv3->nvbase.debug_dba; - - nv3_coord_16_t screen_size = {0}; - screen_size.x = nv3->nvbase.svga.hdisp; - screen_size.y = nv3->nvbase.svga.dispend; - - /* Ensure that we are - in the correct mode. Modified SVGA core code */ - nv3_render_ensure_screen_size(); - - /* Don't try and draw stuff that is past the buffer, but, leave it in Video RAM, so it can be used for s2sb's etc */ - - switch (nv3->nvbase.svga.bpp) - { - case 4: - /* Uh we should never be here because we're in the SVGA mode(?) */ - fatal("NV3 - 4bpp not implemented (not even sure if it's SVGA only)"); - break; - case 8: - nv3_render_8bpp(dba, screen_size); - break; - case 15: - nv3_render_15bpp(dba, screen_size); - break; - case 16: - nv3_render_16bpp(dba, screen_size); - break; - case 32: - nv3_render_32bpp(dba, screen_size); - break; - } - -} - -/* - Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, indexed 8 bits per pixel format -*/ - -void nv3_render_8bpp(uint32_t vram_start, nv3_coord_16_t screen_size) -{ - if (!nv3) - return; - - uint32_t vram_current_position = vram_start; - uint32_t* p; - uint32_t data = 0; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - - for (uint32_t y = 0; y < screen_size.y; y++) - { - for (uint32_t x = 0; x < screen_size.x; x++) - { - if (vram_current_position >= nv3->nvbase.vram_amount) - return; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; - - /* should just "tip over" to the next line */ - *p = nv3_render_get_palette_index(data & 0xFF); - - vram_current_position++; - } - } -} - -/* - Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, 15 bits per pixel format -*/ - -void nv3_render_15bpp(uint32_t vram_start, nv3_coord_16_t screen_size) -{ - if (!nv3) - return; - - uint32_t vram_current_position = vram_start; - uint32_t* p; - uint32_t data = 0; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - - for (uint32_t y = 0; y < screen_size.y; y++) - { - for (uint32_t x = 0; x < screen_size.x; x++) - { - if (vram_current_position >= nv3->nvbase.vram_amount) - return; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; - - /* should just "tip over" to the next line */ - *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, 15); - - vram_current_position += 2; - } - - } -} - -/* - Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, 16 bits per pixel format -*/ - -void nv3_render_16bpp(uint32_t vram_start, nv3_coord_16_t screen_size) -{ - if (!nv3) - return; - - uint32_t vram_current_position = vram_start; - uint32_t* p; - uint32_t data = 0; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - - for (uint32_t y = 0; y < screen_size.y; y++) - { - for (uint32_t x = 0; x < screen_size.x; x++) - { - if (vram_current_position >= nv3->nvbase.vram_amount) - return; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; - - /* should just "tip over" to the next line */ - *p = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, data & 0xFFFF, 15); - - vram_current_position += 2; - - } - - } -} - -/* - Blit a certain region from the (destination buffer base + (position in vram)) to the 86Box monitor, 32 bits per pixel format -*/ - -void nv3_render_32bpp(uint32_t vram_start, nv3_coord_16_t screen_size) -{ - if (!nv3) - return; - - uint32_t vram_current_position = vram_start; - uint32_t* p; - uint32_t data = 0; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[0][0]; - - for (uint32_t y = 0; y < screen_size.y; y++) - { - for (uint32_t x = 0; x < screen_size.x; x++) - { - if (vram_current_position >= nv3->nvbase.vram_amount) - return; - - p = &nv3->nvbase.svga.monitor->target_buffer->line[y][x]; - data = *(uint32_t*)&nv3->nvbase.svga.vram[vram_current_position]; - - /* should just "tip over" to the next line */ - *p = data; - - vram_current_position += 4; - } - } -} - -// Translate an "NV-ROP" into a GDI Ternary ROP -uint8_t nv3_render_translate_nvrop(nv3_grobj_t grobj, uint32_t rop) -{ - // Credit to envytools for this function: - // https://github.com/envytools/envytools/blob/f102b82381f3f11cee113d16374c87091db039d9/nvhw/pgraph.c - // How does one even go about reverse engineering this (I'm sure the behaviour is simpler when you don't have to translate this but...) Marcelina is a legend. - - uint32_t patch_config_rop = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG) & 0x1F; - - /* || patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD0*/ - - // TODO: Blending - if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_BYPASS) // 0x00 is used for "nothing here" it seems. - return VIDEO_ROP_SRC_COPY; - - uint8_t res = 0; - - int32_t swizzle[3]; - - if (patch_config_rop < 8) { - swizzle[0] = patch_config_rop >> 0 & 1; - swizzle[1] = patch_config_rop >> 1 & 1; - swizzle[2] = patch_config_rop >> 2 & 1; - } else if (patch_config_rop < 0x10) { - swizzle[0] = (patch_config_rop >> 0 & 1) + 1; - swizzle[1] = (patch_config_rop >> 1 & 1) + 1; - swizzle[2] = (patch_config_rop >> 2 & 1) + 1; - } else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_DST) { - swizzle[0] = 0, swizzle[1] = 1, swizzle[2] = 2; - } else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_DST_SRC) { - swizzle[0] = 1, swizzle[1] = 0, swizzle[2] = 2; - } else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_DST) { - swizzle[0] = 0, swizzle[1] = 2, swizzle[2] = 1; - } else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_PAT) { - swizzle[0] = 2, swizzle[1] = 0, swizzle[2] = 1; - } else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_PAT_SRC) { - swizzle[0] = 1, swizzle[1] = 2, swizzle[2] = 0; - } else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_PAT) { - swizzle[0] = 2, swizzle[1] = 1, swizzle[2] = 0; - } else { - warning("NV3 ROP: Invalid patch configuration %02x!", rop); - } - if (patch_config_rop == 0) { - if (rop & 0x01) - res |= 0x11; - if (rop & 0x16) - res |= 0x44; - if (rop & 0x68) - res |= 0x22; - if (rop & 0x80) - res |= 0x88; - } else if (patch_config_rop == 0xf) { - if (rop & 0x01) - res |= 0x03; - if (rop & 0x16) - res |= 0x0c; - if (rop & 0x68) - res |= 0x30; - if (rop & 0x80) - res |= 0xc0; - } else { - int32_t i; - for (i = 0; i < 8; i++) { - int32_t s0 = i >> swizzle[0] & 1; - int32_t s1 = i >> swizzle[1] & 1; - int32_t s2 = i >> swizzle[2] & 1; - int32_t s = s2 << 2 | s1 << 1 | s0; - if (rop >> s & 1) - res |= 1 << i; - } - } - - return res; -} \ No newline at end of file diff --git a/src/video/nv/nv3/render/nv3_render_primitives.c b/src/video/nv/nv3/render/nv3_render_primitives.c deleted file mode 100644 index e2d088c3f..000000000 --- a/src/video/nv/nv3/render/nv3_render_primitives.c +++ /dev/null @@ -1,355 +0,0 @@ -/* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* NV3 code to render basic objects. -* -* -* -* Authors: Connor Hyde, I need a better email address ;^) -* -* Copyright 2024-2025 Connor Hyde -*/ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> -#include <86box/utils/video_stdlib.h> - -void nv3_render_rect(nv3_coord_16_t position, nv3_coord_16_t size, uint32_t color, nv3_grobj_t grobj) -{ - nv3_coord_16_t current_pos = {0}; - - for (int32_t y = position.y; y < (position.y + size.y); y++) - { - current_pos.y = y; - - for (int32_t x = position.x; x < (position.x + size.x); x++) - { - current_pos.x = x; - - nv3_render_write_pixel(current_pos, color, grobj); - } - } -} - -/* Render GDI-B clipped rectangle */ -void nv3_render_rect_clipped(nv3_clip_16_t clip, uint32_t color, nv3_grobj_t grobj) -{ - nv3_coord_16_t current_pos = {0}; - - for (int32_t y = clip.top; y < clip.bottom; y++) - { - current_pos.y = y; - - for (int32_t x = clip.left; x < clip.right; x++) - { - current_pos.x = x; - - /* compare against the global clip too */ - if (current_pos.x >= nv3->pgraph.win95_gdi_text.clip_b.left - && current_pos.x <= nv3->pgraph.win95_gdi_text.clip_b.right - && current_pos.y >= nv3->pgraph.win95_gdi_text.clip_b.top - && current_pos.y <= nv3->pgraph.win95_gdi_text.clip_b.bottom) - { - nv3_render_write_pixel(current_pos, color, grobj); - } - } - } -} - -void nv3_render_gdi_transparent_bitmap_blit(bool bit, bool clip, uint32_t color, nv3_grobj_t grobj) -{ - /* If the bit is set, and cliping is enabled (Type D) tru and lcip */ - if (bit && clip) - { - /* Turn the bit off if we need to clip (Type D ) */ - if (nv3->pgraph.win95_gdi_text_current_position.x < nv3->pgraph.win95_gdi_text.clip_d.left - || nv3->pgraph.win95_gdi_text_current_position.x > nv3->pgraph.win95_gdi_text.clip_d.right - || nv3->pgraph.win95_gdi_text_current_position.y < nv3->pgraph.win95_gdi_text.clip_d.top - || nv3->pgraph.win95_gdi_text_current_position.y > nv3->pgraph.win95_gdi_text.clip_d.bottom) - { - bit = false; - } - - /* - Also clip if we are outside of the SIZE_OUT range - We only need to do this in one direction just to get rid of the crud sent by NV - */ - uint32_t clip_x = nv3->pgraph.win95_gdi_text.point_d.x + (nv3->pgraph.win95_gdi_text.size_out_d.x); - uint32_t clip_y = nv3->pgraph.win95_gdi_text.point_d.y + (nv3->pgraph.win95_gdi_text.size_out_d.y); - - if (nv3->pgraph.win95_gdi_text_current_position.x >= clip_x - || nv3->pgraph.win95_gdi_text_current_position.y >= clip_y) - bit = false; - } - - /* We don't need to and it, because it seems the Riva only uses non-packed bpp formats for this class */ - if (bit) - nv3_render_write_pixel(nv3->pgraph.win95_gdi_text_current_position, color, grobj); - - /* - Check if we've reached the bottom - Because we check the bits in reverse, we go forward (bits 7,6,5 were set for a 1x3 bitmap) - */ - - uint32_t end_x = (clip) ? nv3->pgraph.win95_gdi_text.point_d.x + nv3->pgraph.win95_gdi_text.size_in_d.x : nv3->pgraph.win95_gdi_text.point_c.x + nv3->pgraph.win95_gdi_text.size_c.x; - - nv3->pgraph.win95_gdi_text_current_position.x++; - - if (nv3->pgraph.win95_gdi_text_current_position.x >= end_x) - { - nv3->pgraph.win95_gdi_text_current_position.y++; - - if (!clip) - nv3->pgraph.win95_gdi_text_current_position.x = nv3->pgraph.win95_gdi_text.point_c.x; - else - nv3->pgraph.win95_gdi_text_current_position.x = nv3->pgraph.win95_gdi_text.point_d.x; - } - -} - -/* Originally written 23 March 2025, but then, redone, properly, on 30 March 2025 */ -void nv3_render_gdi_transparent_bitmap(bool clip, uint32_t color, uint32_t bitmap_data, nv3_grobj_t grobj) -{ - /* - First, we need to figure out how many bits we have left. - If we have less than 32, don't process all of the bits. - - Bits are processed in the following order: [7-0] [15-8] [23-16] [31-24] - TODO: Store this somewhere, so it doesn't need to be recalculated. - - We store a global bit count for this purpose. - */ - - uint32_t bitmap_size = (clip) ? nv3->pgraph.win95_gdi_text.size_in_d.x * nv3->pgraph.win95_gdi_text.size_in_d.y : nv3->pgraph.win95_gdi_text.size_c.x * nv3->pgraph.win95_gdi_text.size_c.y; - uint32_t bits_remaining_in_bitmap = bitmap_size - nv3->pgraph.win95_gdi_text_bit_count; - - /* we have to interpret every bit in reverse bit order but in the right byte order */ - - bool current_bit = false; - - /* Start by rendering bits 7 through 0 */ - for (int32_t bit = 7; bit >= 0; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_transparent_bitmap_blit(current_bit, clip, color, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; - - /* Now for 15 through 8 */ - for (int32_t bit = 15; bit >= 8; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_transparent_bitmap_blit(current_bit, clip, color, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; - - /* Now for 23 through 16 */ - for (int32_t bit = 23; bit >= 16; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_transparent_bitmap_blit(current_bit, clip, color, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; - - /* Now for 31 through 24 */ - for (int32_t bit = 31; bit >= 24; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_transparent_bitmap_blit(current_bit, clip, color, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; - -} - -void nv3_render_gdi_1bpp_bitmap_blit(bool bit, uint32_t color0, uint32_t color1, nv3_grobj_t grobj) -{ - /* We can't force the bit off because this is a 1bpp bitmap */ - bool skip = false; - - /* For Type E, always clip */ - /* Turn the bit off if we need to clip (Type D ) */ - if (nv3->pgraph.win95_gdi_text_current_position.x < nv3->pgraph.win95_gdi_text.clip_e.left - || nv3->pgraph.win95_gdi_text_current_position.x > nv3->pgraph.win95_gdi_text.clip_e.right - || nv3->pgraph.win95_gdi_text_current_position.y < nv3->pgraph.win95_gdi_text.clip_e.top - || nv3->pgraph.win95_gdi_text_current_position.y > nv3->pgraph.win95_gdi_text.clip_e.bottom) - { - skip = true; - } - - /* - Also clip if we are outside of the SIZE_OUT range - We only need to do this in one direction just to get rid of the crud sent by NV - */ - uint32_t clip_x = nv3->pgraph.win95_gdi_text.point_e.x + (nv3->pgraph.win95_gdi_text.size_out_e.x); - uint32_t clip_y = nv3->pgraph.win95_gdi_text.point_e.y + (nv3->pgraph.win95_gdi_text.size_out_e.y); - - if (nv3->pgraph.win95_gdi_text_current_position.x >= clip_x - || nv3->pgraph.win95_gdi_text_current_position.y >= clip_y) - skip = true; - - /* We don't need to and it, because it seems the Riva only uses non-packed bpp formats for this class */ - if (!skip) - { - if (bit) - nv3_render_write_pixel(nv3->pgraph.win95_gdi_text_current_position, nv3->pgraph.win95_gdi_text.color1_e, grobj); - else - nv3_render_write_pixel(nv3->pgraph.win95_gdi_text_current_position, nv3->pgraph.win95_gdi_text.color0_e, grobj); - } - - - /* - Check if we've reached the bottom, if so, advance to the next horizontal lin - Because we check the bits in reverse, we go forward (bits 7,6,5 were set for a 1x3 bitmap) - */ - - uint32_t end_x = nv3->pgraph.win95_gdi_text.point_e.x + nv3->pgraph.win95_gdi_text.size_in_e.x; - - nv3->pgraph.win95_gdi_text_current_position.x++; - - if (nv3->pgraph.win95_gdi_text_current_position.x >= end_x) - { - nv3->pgraph.win95_gdi_text_current_position.y++; - nv3->pgraph.win95_gdi_text_current_position.x = nv3->pgraph.win95_gdi_text.point_e.x; - } -} - - -/* Originally written 23 March 2025, but then, redone, properly, on 30 March 2025 */ -void nv3_render_gdi_1bpp_bitmap(uint32_t color0, uint32_t color1, uint32_t bitmap_data, nv3_grobj_t grobj) -{ - /* - First, we need to figure out how many bits we have left. - If we have less than 32, don't process all of the bits. - - Bits are processed in the following order: [7-0] [15-8] [23-16] [31-24] - TODO: Store this somewhere, so it doesn't need to be recalculated. - - We store a global bit count for this purpose. - */ - - uint32_t bitmap_size = nv3->pgraph.win95_gdi_text.size_in_e.x * nv3->pgraph.win95_gdi_text.size_in_e.y; - uint32_t bits_remaining_in_bitmap = bitmap_size - nv3->pgraph.win95_gdi_text_bit_count; - - /* we have to interpret every bit in reverse bit order but in the right byte order */ - - bool current_bit = false; - - /* Start by rendering bits 7 through 0 */ - for (int32_t bit = 7; bit >= 0; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_1bpp_bitmap_blit(current_bit, color0, color1, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; - - /* Now for 15 through 8 */ - for (int32_t bit = 15; bit >= 8; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_1bpp_bitmap_blit(current_bit, color0, color1, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; - - /* Now for 23 through 16 */ - for (int32_t bit = 23; bit >= 16; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_1bpp_bitmap_blit(current_bit, color0, color1, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; - - /* Now for 31 through 24 */ - for (int32_t bit = 31; bit >= 24; bit--) - { - current_bit = (bitmap_data >> bit) & 0x01; - - nv3_render_gdi_1bpp_bitmap_blit(current_bit, color0, color1, grobj); - nv3->pgraph.win95_gdi_text_bit_count++; - bits_remaining_in_bitmap--; - - if (!bits_remaining_in_bitmap) - break; - } - - /* IF we're done, let's return */ - if (!bits_remaining_in_bitmap) - return; -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pbus.c b/src/video/nv/nv3/subsystems/nv3_pbus.c deleted file mode 100644 index a2e340e85..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pbus.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PBUS: 128-bit unified bus - * - * - * - * Authors: Connor Hyde, I need a better email dataess ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -// NV3 PBUS RMA - Real Mode Access for VBIOS -// This basically works like a shifter, you write one byte at a time from [0x3d0...0x3d3] and it shifts it in to build a 32-bit MMIO address... -// Putting this in pbus because imo it makes the most sense (related to memory access/memory interface) - -nv_register_t pbus_registers[] = { - { NV3_PBUS_DEBUG_0, "PBUS - Debug Register", NULL, NULL}, - { NV3_PBUS_INTR, "PBUS - Interrupt Status", NULL, NULL}, - { NV3_PBUS_INTR_EN, "PBUS - Interrupt Enable", NULL, NULL,}, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -void nv3_pbus_init(void) -{ - nv_log("Initialising PBUS..."); - - nv_log("Done\n"); -} - -uint32_t nv3_pbus_read(uint32_t address) -{ - nv_register_t* reg = nv_get_register(address, pbus_registers, sizeof(pbus_registers)/sizeof(pbus_registers[0])); - - uint32_t ret = 0x00; - - // todo: friendly logging - - nv_log_verbose_only("PBUS Read from 0x%08x", address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - switch (reg->address) - { - case NV3_PBUS_DEBUG_0: - ret = nv3->pbus.debug_0; - break; - case NV3_PBUS_INTR: - ret = nv3->pbus.interrupt_status; - break; - case NV3_PBUS_INTR_EN: - ret = nv3->pbus.interrupt_enable; - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pbus_write(uint32_t address, uint32_t value) -{ - nv_register_t* reg = nv_get_register(address, pbus_registers, sizeof(pbus_registers)/sizeof(pbus_registers[0])); - - nv_log_verbose_only("PBUS Write 0x%08x -> 0x%08x\n", value, address); - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - switch (reg->address) - { - case NV3_PBUS_DEBUG_0: - nv3->pbus.debug_0 = value; - break; - // Interrupt registers - // Interrupt state: - // Bit 0 - PCI Bus Error - case NV3_PBUS_INTR: - nv3->pbus.interrupt_status &= ~value; - nv3_pmc_clear_interrupts(); - break; - case NV3_PBUS_INTR_EN: - nv3->pbus.interrupt_enable = value & 0x00000001; - break; - } - - } - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} - -uint8_t nv3_pbus_rma_read(uint16_t addr) -{ - addr &= 0xFF; - uint32_t real_final_address = 0x0; - uint8_t ret = 0x0; - - switch (addr) - { - // signature so you know reads work - case 0x00: - ret = NV3_RMA_SIGNATURE_MSB; - break; - case 0x01: - ret = NV3_RMA_SIGNATURE_BYTE2; - break; - case 0x02: - ret = NV3_RMA_SIGNATURE_BYTE1; - break; - case 0x03: - ret = NV3_RMA_SIGNATURE_LSB; - break; - case 0x08 ... 0x0B: - // reads must be dword aligned - real_final_address = (nv3->pbus.rma.addr + (addr & 0x03)); - - if (nv3->pbus.rma.addr < NV3_MMIO_SIZE) - ret = nv3_mmio_read8(real_final_address, NULL); - else - { - /* Do we need to read RAMIN here? */ - ret = nv3->nvbase.svga.vram[real_final_address - NV3_MMIO_SIZE] & (nv3->nvbase.svga.vram_max - 1); - } - - // log current location for vbios RE - nv_log_verbose_only("MMIO Real Mode Access read, initial address=0x%04x final RMA MMIO address=0x%08x data=0x%08x\n", - addr, real_final_address, ret); - - break; - } - - return ret; -} - -// Implements a 32-bit write using 16 bit port number -void nv3_pbus_rma_write(uint16_t addr, uint8_t val) -{ - // addresses are in reality 8bit so just mask it to be safe - addr &= 0xFF; - - // format: - // 0x00 ID - // 0x04 Pointer to data - // 0x08 Data port(?) - // 0x0B Data - 32bit. SENT IN THE RIGHT ORDER FOR ONCE WAHOO! - // 0x10 Increment (?) data - implemented the same as data for now - - if (addr < 0x08) - { - switch (addr % 0x04) - { - case 0x00: // lowest byte - nv3->pbus.rma.addr &= ~0xff; - nv3->pbus.rma.addr |= val; - break; - case 0x01: // 2nd highest byte - nv3->pbus.rma.addr &= ~0xff00; - nv3->pbus.rma.addr |= (val << 8); - break; - case 0x02: // 3rd highest byte - nv3->pbus.rma.addr &= ~0xff0000; - nv3->pbus.rma.addr |= (val << 16); - break; - case 0x03: // 4th highest byte - nv3->pbus.rma.addr &= ~0xff000000; - nv3->pbus.rma.addr |= (val << 24); - break; - } - } - // Data to send to MMIO - else - { - switch (addr % 0x04) - { - case 0x00: // lowest byte - nv3->pbus.rma.data &= ~0xff; - nv3->pbus.rma.data |= val; - break; - case 0x01: // 2nd highest byte - nv3->pbus.rma.data &= ~0xff00; - nv3->pbus.rma.data |= (val << 8); - break; - case 0x02: // 3rd highest byte - nv3->pbus.rma.data &= ~0xff0000; - nv3->pbus.rma.data |= (val << 16); - break; - case 0x03: // 4th highest byte - nv3->pbus.rma.data &= ~0xff000000; - nv3->pbus.rma.data |= (val << 24); - - nv_log_verbose_only("MMIO Real Mode Access write transaction complete, initial address=0x%04x final RMA MMIO address=0x%08x data=0x%08x\n", - addr, nv3->pbus.rma.addr, nv3->pbus.rma.data); - - if (nv3->pbus.rma.addr < NV3_MMIO_SIZE) - nv3_mmio_write32(nv3->pbus.rma.addr, nv3->pbus.rma.data, NULL); - else // failsafe code, i don't think you will ever write outside of VRAM? - { - uint32_t* vram_32 = (uint32_t*)nv3->nvbase.svga.vram; - vram_32[(nv3->pbus.rma.addr - NV3_MMIO_SIZE) >> 2] = nv3->pbus.rma.data; - } - - - break; - } - } - - if (addr & 0x10) - nv3->pbus.rma.addr += 0x04; // Alignment -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pbus_dma.c b/src/video/nv/nv3/subsystems/nv3_pbus_dma.c deleted file mode 100644 index 3359e9079..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pbus_dma.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PBUS DMA: DMA & Notifier Engine - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/dma.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -/* Nvidia DMA Engine */ - -void nv3_perform_dma_m2mf(nv3_grobj_t grobj) -{ - // notify object base=grobj_1 >> 12 - uint32_t notify_obj_base = grobj.grobj_1 >> 12; - - uint32_t notify_obj_info = nv3_ramin_read32(notify_obj_base, nv3); - uint32_t notify_obj_limit = nv3_ramin_read32(notify_obj_base + 0x04, nv3); - uint32_t notify_obj_page = nv3_ramin_read32(notify_obj_base + 0x08, nv3); - - /* extract some important information*/ - uint32_t info_adjust = notify_obj_info & 0xFFF; - bool info_pt_present = (notify_obj_info >> NV3_NOTIFICATION_PT_PRESENT) & 0x01; - uint8_t info_dma_target = (notify_obj_info >> NV3_NOTIFICATION_TARGET) & 0x03; - - /* paging information */ - bool page_is_present = notify_obj_page & 0x01; - bool page_is_readwrite = (notify_obj_page >> NV3_NOTIFICATION_PAGE_ACCESS); - uint32_t frame_base = notify_obj_page & 0xFFFFF000; - - // This code is temporary and will probably be moved somewhere else - // Print torns of debug info - #ifdef DEBUG - nv_log_verbose_only("******* WARNING: IF THIS OPERATION FUCKS UP, RANDOM MEMORY WILL BE CORRUPTED, YOUR ENTIRE SYSTEM MAY BE HOSED *******\n"); - - nv_log_verbose_only("M2MF DMA Information:\n"); - nv_log_verbose_only("Adjust Value: 0x%08x\n", info_adjust); - (info_pt_present) ? nv_log_verbose_only("Pagetable Present: True\n") : nv_log_verbose_only("Pagetable Present: False\n"); - - switch (info_dma_target) - { - case NV3_DMA_TARGET_NODE_VRAM: - nv_log_verbose_only("Notification Target: VRAM\n"); - break; - case NV3_DMA_TARGET_NODE_CART: - nv_log_verbose_only("VERY BAD WARNING: Notification detected with Notification Target: Cartridge. THIS SHOULD NEVER HAPPEN!!!!!\n"); - break; - case NV3_DMA_TARGET_NODE_PCI: - (nv3->nvbase.bus_generation == nv_bus_pci) ? nv_log_verbose_only("Notification Target: PCI Bus\n") : nv_log_verbose_only("Notification Target: PCI Bus (On AGP card?)\n"); - break; - case NV3_DMA_TARGET_NODE_AGP: - (nv3->nvbase.bus_generation == nv_bus_agp_1x - || nv3->nvbase.bus_generation == nv_bus_agp_2x) ? nv_log_verbose_only("Notification Target: AGP Bus\n") : nv_log_verbose_only("Notification Target: AGP Bus (On PCI card?)\n"); - break; - } - - nv_log_verbose_only("Limit: 0x%08x\n", notify_obj_limit); - (page_is_present) ? nv_log_verbose_only("Page is present\n") : nv_log_verbose_only("Page is not present\n"); - (page_is_readwrite) ? nv_log_verbose_only("Page is read-write\n") : nv_log_verbose_only("Page is read-only\n"); - nv_log_verbose_only("Pageframe Address: 0x%08x\n", frame_base); - #endif - - // set up the dma transfer. we need to translate to a physical address. - - uint32_t final_address = 0; - - /* M2MF DMA only uses HW type */ - - final_address = frame_base + info_adjust; - - /* send the notification off */ - nv_log("About to send M2MF DMA to 0x%08x (Check target)\n", final_address); - - uint32_t offset_in = (nv3->pgraph.m2mf.offset_in); - uint32_t offset_out = (nv3->pgraph.m2mf.offset_out); - - uint32_t pitch_in = nv3->pgraph.m2mf.pitch_in; - uint32_t pitch_out = nv3->pgraph.m2mf.pitch_out; - - // pitch out surely can't be 0 - if (pitch_out == 0) - pitch_out = pitch_in; - - uint32_t bytes_per_scanline = nv3->pgraph.m2mf.scanline_length; - - uint8_t increment_in = (nv3->pgraph.m2mf.format) & 0x07; - uint8_t increment_out = (nv3->pgraph.m2mf.format >> NV3_M2MF_FORMAT_INPUT) & 0x07; - - for (uint32_t scanline = 0; scanline < nv3->pgraph.m2mf.num_scanlines; scanline++) - { - for (uint32_t pixel = offset_in; pixel < (offset_in + bytes_per_scanline); pixel += increment_in) - { - nv3->nvbase.svga.vram[offset_out] = nv3->nvbase.svga.vram[offset_in]; - offset_out += increment_out; - } - - offset_in += pitch_in; - offset_out += pitch_out; - } - - /* - switch (info_dma_target) - { - // for M2MF only NVM target node is used. - - case NV3_DMA_TARGET_NODE_VRAM: - - - uint32_t* vram_32 = (uint32_t*)nv3->nvbase.svga.vram; - - break; - case NV3_DMA_TARGET_NODE_PCI: - case NV3_DMA_TARGET_NODE_AGP: - // Idk how to implement increments of more than 1 but only 1 increments seem to be used with these. - uint32_t size_in = nv3->pgraph.m2mf.num_scanlines * nv3->pgraph.m2mf.pitch_in; - uint32_t size_out = nv3->pgraph.m2mf.num_scanlines * nv3->pgraph.m2mf.pitch_out; - - uint8_t* page_in = calloc(1, size_in); - - for (uint32_t scanline = 0; scanline < nv3->pgraph.m2mf.num_scanlines; scanline++) - { - - } - - dma_bm_read(offset_in, page_in, size_in, size_in); - dma_bm_write(offset_out, page_in, size_out, size_out); - - break; - } -*/ - // we're done - nv3->pgraph.notify_pending = false; -} - - -/* Sees if any notification is required after an object method is executed. If so, executes it... */ -void nv3_notify_if_needed(uint32_t name, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj) -{ - if (!nv3->pgraph.notify_pending) - return; - - uint32_t current_notification_object = nv3->pgraph.notifier; - uint32_t notification_type = ((current_notification_object >> NV3_PGRAPH_NOTIFY_REQUEST_TYPE) & 0x07); - - // check for a software method (0 = hardware, 1 = software) - if (notification_type != 0) - { - nv_log("Software Notification, firing interrupt"); - nv3_pgraph_interrupt_valid(NV3_PGRAPH_INTR_0_SOFTWARE_NOTIFY); - //return; - } - - // set up the NvNotification structure - nv3_notification_t notify = {0}; - notify.nanoseconds = nv3->ptimer.time; - notify.status = NV3_NOTIFICATION_STATUS_DONE_OK; // it should be fine to just signal that it's ok - - // these are only nonzero when there is an error - notify.info32 = notify.info16 = 0; - - // notify object base=grobj_1 >> 12 - uint32_t notify_obj_base = grobj.grobj_1 >> 12; - - uint32_t notify_obj_info = nv3_ramin_read32(notify_obj_base, nv3); - uint32_t notify_obj_limit = nv3_ramin_read32(notify_obj_base + 0x04, nv3); - uint32_t notify_obj_page = nv3_ramin_read32(notify_obj_base + 0x08, nv3); - - /* extract some important information*/ - uint32_t info_adjust = notify_obj_info & 0xFFF; - bool info_pt_present = (notify_obj_info >> NV3_NOTIFICATION_PT_PRESENT) & 0x01; - uint8_t info_notification_target = (notify_obj_info >> NV3_NOTIFICATION_TARGET) & 0x03; - - /* paging information */ - bool page_is_present = notify_obj_page & 0x01; - bool page_is_readwrite = (notify_obj_page >> NV3_NOTIFICATION_PAGE_ACCESS); - uint32_t frame_base = notify_obj_page & 0xFFFFF000; - - // This code is temporary and will probably be moved somewhere else - // Print torns of debug info - #ifdef DEBUG - nv_log_verbose_only("******* WARNING: IF THIS OPERATION FUCKS UP, RANDOM MEMORY WILL BE CORRUPTED, YOUR ENTIRE SYSTEM MAY BE HOSED *******\n"); - - nv_log_verbose_only("Notification Information:\n"); - nv_log_verbose_only("Adjust Value: 0x%08x\n", info_adjust); - (info_pt_present) ? nv_log_verbose_only("Pagetable Present: True\n") : nv_log_verbose_only("Pagetable Present: False\n"); - - switch (info_notification_target) - { - case NV3_DMA_TARGET_NODE_VRAM: - nv_log_verbose_only("Notification Target: VRAM\n"); - break; - case NV3_DMA_TARGET_NODE_CART: - nv_log_verbose_only("VERY BAD WARNING: Notification detected with Notification Target: Cartridge. THIS SHOULD NEVER HAPPEN!!!!!\n"); - break; - case NV3_DMA_TARGET_NODE_PCI: - (nv3->nvbase.bus_generation == nv_bus_pci) ? nv_log_verbose_only("Notification Target: PCI Bus\n") : nv_log_verbose_only("Notification Target: PCI Bus (On AGP card?)\n"); - break; - case NV3_DMA_TARGET_NODE_AGP: - (nv3->nvbase.bus_generation == nv_bus_agp_1x - || nv3->nvbase.bus_generation == nv_bus_agp_2x) ? nv_log_verbose_only("Notification Target: AGP Bus\n") : nv_log_verbose_only("Notification Target: AGP Bus (On PCI card?)\n"); - break; - } - - nv_log_verbose_only("Limit: 0x%08x\n", notify_obj_limit); - (page_is_present) ? nv_log_verbose_only("Page is present\n") : nv_log_verbose_only("Page is not present\n"); - (page_is_readwrite) ? nv_log_verbose_only("Page is read-write\n") : nv_log_verbose_only("Page is read-only\n"); - nv_log_verbose_only("Pageframe Address: 0x%08x\n", frame_base); - #endif - - // set up the dma transfer. we need to translate to a physical address. - - uint32_t final_address = 0; - - /* Simple case: hardware notification, we can just take the pte since it's based on the type */ - if (notification_type == 0) - { - final_address = frame_base + info_adjust; - } - else - { - // for software we have to calculate the pte index - uint32_t pte_num = ((notification_type << 4) + info_adjust) >> 12; - - /* ramin entries are sorted - 1 object for each pte entry...*/ - final_address = nv3_ramin_read32(notify_obj_base + (0x10 * pte_num) + 8, nv3); - final_address += (info_adjust & 0xFFF); - } - - /* send the notification off */ - nv_log("About to send hardware notification to 0x%08x (Check target)\n", final_address); - - switch (info_notification_target) - { - case NV3_DMA_TARGET_NODE_VRAM: - - uint32_t* vram_32 = (uint32_t*)nv3->nvbase.svga.vram; - - // increment by 1 because each index increments by 4 - vram_32[final_address] = (notify.nanoseconds & 0xFFFFFFFF); - vram_32[final_address + 1] = (notify.nanoseconds >> 32); - vram_32[final_address + 2] = notify.info32; - vram_32[final_address + 3] = (notify.info16 | notify.status); - break; - case NV3_DMA_TARGET_NODE_PCI: - case NV3_DMA_TARGET_NODE_AGP: - dma_bm_write(final_address, (uint8_t*)¬ify, sizeof(nv3_notification_t), 4); - break; - } - - // we're done - nv3->pgraph.notify_pending = false; -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pextdev.c b/src/video/nv/nv3/subsystems/nv3_pextdev.c deleted file mode 100644 index c89d540c3..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pextdev.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PEXTDEV - External Devices - * Including straps - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_pextdev_init(void) -{ - nv_log("Initialising PEXTDEV....\n"); - - // Set the chip straps - // Make these configurable in the future... - - // Current settings - // AGP2X Disabled - // TV Mode NTSC - // Crystal 13.5 Mhz - // Bus width 128-Bit (some gpus were sold as 64bit for cost reduction) - // - - nv_log("Initialising straps...\n"); - - nv3->pextdev.straps = - (NV3_PSTRAPS_AGP2X_DISABLED << NV3_PSTRAPS_AGP2X) | - (NV3_PSTRAPS_TVMODE_NTSC << NV3_PSTRAPS_TVMODE) | - (NV3_PSTRAPS_CRYSTAL_13500K << NV3_PSTRAPS_CRYSTAL); - - // figure out the bus - if (nv3->nvbase.bus_generation == nv_bus_pci) - nv3->pextdev.straps |= (NV3_PSTRAPS_BUS_TYPE_PCI << NV3_PSTRAPS_BUS_TYPE); - else - nv3->pextdev.straps |= (NV3_PSTRAPS_BUS_TYPE_AGP << NV3_PSTRAPS_BUS_TYPE); - - // now the lower bits - nv3->pextdev.straps |= - (NV3_PSTRAPS_BUS_WIDTH_128BIT << NV3_PSTRAPS_BUS_WIDTH) | - (NV3_PSTRAPS_BIOS_PRESENT << NV3_PSTRAPS_BIOS) | - (NV3_PSTRAPS_BUS_SPEED_66MHZ << NV3_PSTRAPS_BUS_SPEED); - - nv_log("Straps = 0x%04x\n", nv3->pextdev.straps); - nv_log("Initialising PEXTDEV: Done\n"); -} - -// -// ****** PEXTDEV register list START ****** -// - -nv_register_t pextdev_registers[] = { - { NV3_PSTRAPS, "Straps - Chip Configuration", NULL, NULL }, - { NV_REG_LIST_END, NULL, NULL, NULL }, // sentinel value -}; - - -// -// ****** Read/Write functions start ****** -// - -uint32_t nv3_pextdev_read(uint32_t address) -{ - nv_register_t* reg = nv_get_register(address, pextdev_registers, sizeof(pextdev_registers)/sizeof(pextdev_registers[0])); - - uint32_t ret = 0x00; - - // special consideration for straps - if (address == NV3_PSTRAPS) - { - nv_log_verbose_only("Straps Read (current value=0x%08x)\n", nv3->pextdev.straps); - } - else - { - nv_log_verbose_only("PEXTDEV Read from 0x%08x", address); - } - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - switch (reg->address) - { - case NV3_PSTRAPS: - ret = nv3->pextdev.straps; - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pextdev_write(uint32_t address, uint32_t value) -{ - nv_register_t* reg = nv_get_register(address, pextdev_registers, sizeof(pextdev_registers)/sizeof(pextdev_registers[0])); - - nv_log_verbose_only("PEXTDEV Write 0x%08x -> 0x%08x\n", value, address); - - // special consideration for straps - if (address == NV3_PSTRAPS) - { - /* For some reason, all RIVA 128 ZX VBIOSes try to write to the straps. So only indicate this as a problem and return on Rev A/B */ - if (nv3->nvbase.gpu_revision != NV3_PCI_CFG_REVISION_C00) - { - warning("Huh? Tried to write to the straps (value=%d). Something is wrong...\n", nv3->pextdev.straps); - return; - } - } - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_write) - reg->on_write(value); - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pfb.c b/src/video/nv/nv3/subsystems/nv3_pfb.c deleted file mode 100644 index 7360a2c9a..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pfb.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PFB: Framebuffer - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -// Functions only used in this translation unit -uint32_t nv3_pfb_config0_read(void); -void nv3_pfb_config0_write(uint32_t val); - -nv_register_t pfb_registers[] = { - { NV3_PFB_BOOT, "PFB Boot Config", NULL, NULL}, - { NV3_PFB_DELAY, "PFB Delay", NULL, NULL}, - { NV3_PFB_DEBUG_0, "PFB Debug", NULL, NULL }, - { NV3_PFB_GREEN_0, "PFB Green / Power Saving", NULL, NULL,}, - { NV3_PFB_CONFIG_0, "PFB Framebuffer Config 0", nv3_pfb_config0_read, nv3_pfb_config0_write }, - { NV3_PFB_CONFIG_1, "PFB Framebuffer Config 1", NULL, NULL }, - { NV3_PFB_RTL, "PFB RTL (Part of memory timings)", NULL, NULL }, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -void nv3_pfb_init(void) -{ - nv_log("Initialising PFB..."); - - // initial configuration: - // ram 4mb - // bus width 128bit - // extension ram none (was this ever used?) - // ram banks 4 (based on observation of physical RIVA 128 with 4mb, does 1 bank = 1chip?) - // twiddle off (check this on a real card once it's actually installed) - nv3->pfb.boot = (NV3_PFB_BOOT_RAM_EXTENSION_NONE << (NV3_PFB_BOOT_RAM_EXTENSION) - | (NV3_PFB_BOOT_RAM_DATA_TWIDDLE_OFF << NV3_PFB_BOOT_RAM_DATA_TWIDDLE) - | (NV3_PFB_BOOT_RAM_BANKS_4 << NV3_PFB_BOOT_RAM_BANKS) - | (NV3_PFB_BOOT_RAM_WIDTH_128 << NV3_PFB_BOOT_RAM_WIDTH) - ); - - if (nv3->nvbase.vram_amount == NV3_VRAM_SIZE_4MB) - nv3->pfb.boot |= (NV3_PFB_BOOT_RAM_AMOUNT_4MB << NV3_PFB_BOOT_RAM_AMOUNT); - else - nv3->pfb.boot |= (NV3_PFB_BOOT_RAM_AMOUNT_8MB << NV3_PFB_BOOT_RAM_AMOUNT); - - nv_log("Done\n"); -} - -uint32_t nv3_pfb_read(uint32_t address) -{ - nv_register_t* reg = nv_get_register(address, pfb_registers, sizeof(pfb_registers)/sizeof(pfb_registers[0])); - - uint32_t ret = 0x00; - - // todo: friendly logging - - nv_log_verbose_only("PFB Read from 0x%08x", address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - switch (reg->address) - { - case NV3_PFB_BOOT: - ret = nv3->pfb.boot; - break; - case NV3_PFB_DEBUG_0: - ret = nv3->pfb.debug_0; - break; - // Config 0 has a read/write function - case NV3_PFB_CONFIG_1: - ret = nv3->pfb.config_1; - break; - case NV3_PFB_GREEN_0: - ret = nv3->pfb.green; - break; - case NV3_PFB_DELAY: - ret = nv3->pfb.delay; - break; - case NV3_PFB_RTL: - ret = nv3->pfb.rtl; - break; - - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pfb_write(uint32_t address, uint32_t value) -{ - nv_register_t* reg = nv_get_register(address, pfb_registers, sizeof(pfb_registers)/sizeof(pfb_registers[0])); - - nv_log_verbose_only("PFB Write 0x%08x -> 0x%08x", value, address); - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - switch (reg->address) - { - // Boot is read only - case NV3_PFB_DEBUG_0: - nv3->pfb.debug_0 = value; - break; - // Config 0 has a read/write function - case NV3_PFB_CONFIG_1: // Config Register 1 - nv3->pfb.config_1 = value; - break; - case NV3_PFB_GREEN_0: - nv3->pfb.green = value; - break; - case NV3_PFB_DELAY: - nv3->pfb.delay = value; - break; - case NV3_PFB_RTL: - nv3->pfb.rtl = value; - break; - } - } - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} - -uint32_t nv3_pfb_config0_read(void) -{ - return nv3->pfb.config_0; -} - -void nv3_pfb_config0_write(uint32_t val) -{ - nv3->pfb.config_0 = val; - - // i think the actual size and pixel depth are set in PRAMDAC - // so we don't update things here for now - - uint32_t new_pfb_htotal = (nv3->pfb.config_0 & 0x3F) << 5; - // i don't think 16:9 is supported - uint32_t new_pfb_vtotal = new_pfb_htotal * (3.0/4.0); - uint32_t new_bit_depth = (nv3->pfb.config_0 >> 8) & 0x03; - - - // This doesn't actually seem very useful - - nv_log_verbose_only("Framebuffer Config Change\n"); - nv_log_verbose_only("Horizontal Size=%d pixels\n", new_pfb_htotal); - nv_log_verbose_only("Vertical Size @ 4:3=%d pixels\n", new_pfb_vtotal); - - if (new_bit_depth == NV3_PFB_CONFIG_0_DEPTH_8BPP) - nv_log_verbose_only("Bit Depth=8bpp\n"); - else if (new_bit_depth == NV3_PFB_CONFIG_0_DEPTH_16BPP) - nv_log_verbose_only("Bit Depth=16bpp\n"); - else if (new_bit_depth == NV3_PFB_CONFIG_0_DEPTH_32BPP) - nv_log_verbose_only("Bit Depth=32bpp\n"); - -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c deleted file mode 100644 index 9ddcda0d3..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pfifo.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PFIFO (FIFO for graphics object submission) - * PIO object submission - * Gray code conversion routines - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/dma.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -// -// ****** PFIFO register list START ****** -// - -nv_register_t pfifo_registers[] = { - { NV3_PFIFO_INTR, "PFIFO - Interrupt Status", NULL, NULL}, - { NV3_PFIFO_INTR_EN, "PFIFO - Interrupt Enable", NULL, NULL,}, - { NV3_PFIFO_DELAY_0, "PFIFO - DMA Delay/Retry Register", NULL, NULL}, - { NV3_PFIFO_DEBUG_0, "PFIFO - Debug 0", NULL, NULL, }, - { NV3_PFIFO_CONFIG_0, "PFIFO - Config 0", NULL, NULL, }, - { 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_PULL0, "PFIFO - Cache0 Puller Control", NULL, NULL}, - { NV3_PFIFO_CACHE1_PULL0, "PFIFO - Cache1 Puller Control"}, - { NV3_PFIFO_CACHE0_PULLER_CTX_STATE, "PFIFO - Cache0 Puller State1 (Is context clean?)", NULL, NULL}, - { NV3_PFIFO_CACHE1_PULL0, "PFIFO - Cache1 Puller State0", NULL, NULL}, - { NV3_PFIFO_CACHE1_PULLER_CTX_STATE, "PFIFO - Cache1 Puller State1 (Is context clean?)", NULL, NULL}, - { NV3_PFIFO_CACHE0_PUSH_ENABLED, "PFIFO - Cache0 Access", NULL, NULL, }, - { NV3_PFIFO_CACHE1_PUSH_ENABLED, "PFIFO - Cache1 Access", NULL, NULL, }, - { NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID, "PFIFO - Cache0 Push Channel ID", NULL, NULL, }, - { NV3_PFIFO_CACHE1_PUSH_CHANNEL_ID, "PFIFO - Cache1 Push Channel ID", NULL, NULL, }, - { NV3_PFIFO_CACHE0_ERROR_PENDING, "PFIFO - Cache0 DMA Error Pending?", NULL, NULL, }, - { NV3_PFIFO_CACHE0_STATUS, "PFIFO - Cache0 Status", NULL, NULL}, - { NV3_PFIFO_CACHE1_STATUS, "PFIFO - Cache1 Status", NULL, NULL}, - { NV3_PFIFO_CACHE0_GET, "PFIFO - Cache0 Get", NULL, NULL }, - { NV3_PFIFO_CACHE0_CTX, "PFIFO - Cache0 Context", NULL, NULL }, - { NV3_PFIFO_CACHE1_GET, "PFIFO - Cache1 Get", NULL, NULL }, - { NV3_PFIFO_CACHE0_PUT, "PFIFO - Cache0 Put", NULL, NULL }, - { NV3_PFIFO_CACHE1_PUT, "PFIFO - Cache1 Put", NULL, NULL }, - //Cache1 exclusive stuff - { NV3_PFIFO_CACHE1_DMA_CONFIG_0, "PFIFO - Cache1 DMA Access (bit 0: is running, bit 4: is busy)"}, - { NV3_PFIFO_CACHE1_DMA_CONFIG_1, "PFIFO - Cache1 DMA Length"}, - { NV3_PFIFO_CACHE1_DMA_CONFIG_2, "PFIFO - Cache1 DMA Address"}, - { NV3_PFIFO_CACHE1_DMA_CONFIG_3, "PFIFO - Cache1 DMA Target Node"}, - { NV3_PFIFO_CACHE1_DMA_STATUS, "PFIFO - Cache1 DMA Status"}, - { NV3_PFIFO_CACHE1_DMA_TLB_PT_BASE, "PFIFO - Cache1 DMA TLB - Pagetable Base"}, - { NV3_PFIFO_CACHE1_DMA_TLB_PTE, "PFIFO - Cache1 DMA TLB - Pagetable Entry (31:12 - Frame Address; bit 0 - Is Present)"}, - { NV3_PFIFO_CACHE1_DMA_TLB_TAG, "PFIFO - Cache1 DMA TLB - Tag"}, - //Runout - { NV3_PFIFO_RUNOUT_GET, "PFIFO Runout Get Address [8:3 if 512b, otherwise 12:3]"}, - { NV3_PFIFO_RUNOUT_PUT, "PFIFO Runout Put Address [8:3 if 512b, otherwise 12:3]"}, - { NV3_PFIFO_RUNOUT_STATUS, "PFIFO Runout Status"}, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -// PFIFO init code -void nv3_pfifo_init(void) -{ - nv_log("Initialising PFIFO..."); - - nv_log("Done!\n"); -} - -uint32_t nv3_pfifo_read(uint32_t address) -{ - // before doing anything, check the subsystem enablement state - - if (!(nv3->pmc.enable >> NV3_PMC_ENABLE_PFIFO) - & NV3_PMC_ENABLE_PFIFO_ENABLED) - { - nv_log("Repressing PFIFO read. The subsystem is disabled according to pmc_enable, returning 0\n"); - return 0x00; - } - - uint32_t ret = 0x00; - - nv_register_t* reg = nv_get_register(address, pfifo_registers, sizeof(pfifo_registers)/sizeof(pfifo_registers[0])); - - // todo: friendly logging - - nv_log_verbose_only("PFIFO Read from 0x%08x", address); - - // if the register actually exists - if (reg) - { - - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - // Interrupt state: - // Bit 0 - Cache Error - // Bit 4 - RAMRO Triggered - // Bit 8 - RAMRO Overflow (too many invalid dma objects) - // Bit 12 - DMA Pusher - // Bit 16 - DMA Page Table Entry (pagefault?) - switch (reg->address) - { - case NV3_PFIFO_INTR: - ret = nv3->pfifo.interrupt_status; - break; - case NV3_PFIFO_INTR_EN: - ret = nv3->pfifo.interrupt_enable; - break; - case NV3_PFIFO_DELAY_0: - ret = nv3->pfifo.dma_delay_retry; - break; - // Debug - case NV3_PFIFO_DEBUG_0: - ret = nv3->pfifo.debug_0; - break; - case NV3_PFIFO_CONFIG_0: - ret = nv3->pfifo.config_0; - break; - // Some of these may need to become functions. - case NV3_PFIFO_CONFIG_RAMFC: - ret = nv3->pfifo.ramfc_config; - break; - case NV3_PFIFO_CONFIG_RAMHT: - ret = nv3->pfifo.ramht_config; - break; - case NV3_PFIFO_CONFIG_RAMRO: - ret = nv3->pfifo.ramro_config; - break; - /* These automatically trigger pulls when 1 is written */ - case NV3_PFIFO_CACHE0_PULL0: - ret = nv3->pfifo.cache0_settings.pull0; - break; - case NV3_PFIFO_CACHE1_PULL0: - ret = nv3->pfifo.cache1_settings.pull0; - break; - case NV3_PFIFO_CACHE0_PULLER_CTX_STATE: - ret = (nv3->pfifo.cache0_settings.context_is_dirty) ? (1 << NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) : 0; - break; - case NV3_PFIFO_CACHE1_PULLER_CTX_STATE: - ret = (nv3->pfifo.cache0_settings.context_is_dirty) ? (1 << NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) : 0; - break; - /* Does this automatically push? */ - case NV3_PFIFO_CACHE0_PUSH_ENABLED: - ret = nv3->pfifo.cache0_settings.push0; - break; - case NV3_PFIFO_CACHE1_PUSH_ENABLED: - ret = nv3->pfifo.cache1_settings.push0; - break; - case NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID: - ret = nv3->pfifo.cache0_settings.channel; - break; - case NV3_PFIFO_CACHE1_PUSH_CHANNEL_ID: - ret = nv3->pfifo.cache1_settings.channel; - break; - case NV3_PFIFO_CACHE0_STATUS: - // CACHE0 has only one entry so it can only ever be empty or full - - if (nv3->pfifo.cache0_settings.put_address == nv3->pfifo.cache0_settings.get_address) - ret |= 1 << NV3_PFIFO_CACHE0_STATUS_EMPTY; - else - ret |= 1 << NV3_PFIFO_CACHE0_STATUS_FULL; - - break; - case NV3_PFIFO_CACHE1_STATUS: - // CACHE1 doesn't... - - if (nv3->pfifo.cache1_settings.put_address == nv3->pfifo.cache1_settings.get_address) - ret |= 1 << NV3_PFIFO_CACHE1_STATUS_EMPTY; - - // Check if Cache1 (0x7C bytes in size depending on gpu?) is full - // Based on how the drivers do it - if (!nv3_pfifo_cache1_num_free_spaces()) - ret |= 1 << NV3_PFIFO_CACHE1_STATUS_FULL; - - if (nv3->pfifo.runout_put != nv3->pfifo.runout_get) - ret |= 1 << NV3_PFIFO_CACHE1_STATUS_RANOUT; - - break; - case NV3_PFIFO_CACHE0_PUT: - ret = nv3->pfifo.cache0_settings.put_address; - break; - case NV3_PFIFO_CACHE0_GET: - ret = nv3->pfifo.cache0_settings.get_address; - break; - case NV3_PFIFO_CACHE1_PUT: - ret = nv3->pfifo.cache1_settings.put_address; - break; - case NV3_PFIFO_CACHE1_GET: - ret = nv3->pfifo.cache1_settings.get_address; - break; - // Reassignment - case NV3_PFIFO_CACHE_REASSIGNMENT: - ret = nv3->pfifo.cache_reassignment & 0x01; //1bit meaningful - break; - // Cache1 exclusive stuff - // Control - case NV3_PFIFO_CACHE1_DMA_CONFIG_0: - ret = nv3->pfifo.cache1_settings.dma_state; - break; - case NV3_PFIFO_CACHE1_DMA_CONFIG_1: - ret = nv3->pfifo.cache1_settings.dma_length & (NV3_VRAM_SIZE_8MB) - 4; //MAX vram size - break; - case NV3_PFIFO_CACHE1_DMA_CONFIG_2: - ret = nv3->pfifo.cache1_settings.dma_address; - break; - case NV3_PFIFO_CACHE1_DMA_CONFIG_3: - if (nv3->nvbase.bus_generation == nv_bus_pci) - return NV3_PFIFO_CACHE1_DMA_CONFIG_3_TARGET_NODE_PCI; - else - return NV3_PFIFO_CACHE1_DMA_CONFIG_3_TARGET_NODE_AGP; - break; - case NV3_PFIFO_CACHE1_DMA_STATUS: - ret = nv3->pfifo.cache1_settings.dma_status; - break; - case NV3_PFIFO_CACHE1_DMA_TLB_PT_BASE: - ret = nv3->pfifo.cache1_settings.dma_tlb_pt_base; - break; - case NV3_PFIFO_CACHE1_DMA_TLB_PTE: - ret = nv3->pfifo.cache1_settings.dma_tlb_pte; - break; - 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; - case NV3_PFIFO_RUNOUT_STATUS: - if (nv3->pfifo.runout_put == nv3->pfifo.runout_get) - ret |= 1 << NV3_PFIFO_RUNOUT_STATUS_EMPTY; /* good news */ - else - ret |= 1 << NV3_PFIFO_RUNOUT_STATUS_RANOUT; /* bad news */ - - /* TODO: the following code sucks (move to a functio?) */ - - uint32_t new_size_ramro = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); - - if (new_size_ramro == 0) - new_size_ramro = 0x200; - else if (new_size_ramro == 1) - new_size_ramro = 0x2000; - - // WTF? - if (nv3->pfifo.runout_put + 0x08 & (new_size_ramro - 0x08) == nv3->pfifo.runout_get) - ret |= 1 << NV3_PFIFO_RUNOUT_STATUS_FULL; /* VERY BAD news */ - - break; - - /* Cache1 is handled below - cache0 only has one entry */ - case NV3_PFIFO_CACHE0_CTX: - ret = nv3->pfifo.cache0_settings.context[0]; - break; - - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\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_verbose_only("PFIFO Cache1 CTX Read Entry=%d Value=0x%04x\n", ctx_entry_id, ret); - } - /* Direct cache read stuff */ - else if (address >= NV3_PFIFO_CACHE0_METHOD_START && address <= NV3_PFIFO_CACHE0_METHOD_END) - { - nv_log_verbose_only("PFIFO Cache0 Read\n"); - - // See if we want the object name or the channel/subchannel information. - if (address & 4) - { - nv_log_verbose_only("Data=0x%08x\n", nv3->pfifo.cache0_entry.data); - - return nv3->pfifo.cache0_entry.data; - } - else - { - uint32_t final = nv3->pfifo.cache0_entry.method | (nv3->pfifo.cache0_entry.subchannel << NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL); - - nv_log_verbose_only("Param (subchannel=15:13, method=12:2)=0x%08x\n", final); - - - return final; - } - } - 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; - - // shift right by 3, convert from address, to slot. - if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_C00) - slot = (address >> 3) & 0x3F; - else - slot = (address >> 3) & 0x1F; - - nv_log_verbose_only("PFIFO Cache1 Read slot=%d", slot); - - // See if we want the object name or the channel/subchannel information. - if (address & 4) - { - nv_log_verbose_only("Data=0x%08x\n", nv3->pfifo.cache1_entries[slot].data); - return nv3->pfifo.cache1_entries[slot].data; - } - else - { - uint32_t final = nv3->pfifo.cache1_entries[slot].method | (nv3->pfifo.cache1_entries[slot].subchannel << NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL); - nv_log_verbose_only("Param (subchannel=15:13, method=12:2)=0x%08x\n", final); - return final; - } - - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pfifo_trigger_dma_if_required(void) -{ - // Not a thing for cache0 - - bool cache1_dma = false; - - /* Check that DMA is enabled */ - if ((nv3->pfifo.cache1_settings.dma_state & NV3_PFIFO_CACHE1_DMA_STATUS_STATE_RUNNING) - && nv3->pfifo.cache1_settings.dma_enabled) - { - uint32_t bytes_to_send = nv3->pfifo.cache1_settings.dma_length; - uint32_t where_to_send = nv3->pfifo.cache1_settings.dma_address; - uint32_t target_node = nv3->pfifo.cache1_settings.dma_target_node; //2=pci, 3=agp. - - /* Pagetable information */ - uint32_t tlb_pt_base = nv3->pfifo.cache1_settings.dma_tlb_pt_base; - uint32_t tlb_pt_entry = nv3->pfifo.cache1_settings.dma_tlb_pte; // notify_obj_page - uint32_t tlb_pt_tag = nv3->pfifo.cache1_settings.dma_tlb_tag; // 0xFFFFFFFF usually? - - /* - going to treat the format the same as notifiers - */ - if (!(tlb_pt_entry & NV3_PFIFO_CACHE1_DMA_TLB_PTE_IS_PRESENT)) - { - warning("NV3: Tried to DMA to a non-existent page! Big Problem!"); - return; - } - - uint32_t final_page_base = tlb_pt_entry & 0xFFFFF000; /* pull out 31:12 */ - - /* - page size is 0x1000 - */ - uint32_t final_address = final_page_base + (tlb_pt_entry << 10) + where_to_send; //x86 page size is 0x1000 (maybe rsh where_to_send by 2) - - nv_log_verbose_only("DMA Engine: DMA to %08x length=%08x", final_address, bytes_to_send); - - //-dma_bm_write() - } - - //we're done - nv3->pfifo.cache1_settings.dma_state &= ~NV3_PFIFO_CACHE1_DMA_STATUS_STATE_RUNNING; -} - -void nv3_pfifo_write(uint32_t address, uint32_t val) -{ - // before doing anything, check the subsystem enablement - - if (!(nv3->pmc.enable >> NV3_PMC_ENABLE_PFIFO) - & NV3_PMC_ENABLE_PFIFO_ENABLED) - { - nv_log("Repressing PFIFO write. The subsystem is disabled according to pmc_enable\n"); - return; - } - - nv_register_t* reg = nv_get_register(address, pfifo_registers, sizeof(pfifo_registers)/sizeof(pfifo_registers[0])); - - nv_log_verbose_only("PFIFO Write 0x%08x -> 0x%08x", val, address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_write) - reg->on_write(val); - else - { - switch (reg->address) - { - // Interrupt state: - // Bit 0 - Cache Error - // Bit 4 - RAMRO Triggered - // Bit 8 - RAMRO Overflow (too many invalid dma objects) - // Bit 12 - DMA Pusher - // Bit 16 - DMA Page Table Entry (pagefault?) - case NV3_PFIFO_INTR: - nv3->pfifo.interrupt_status &= ~val; - 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->pfifo.interrupt_enable = val & 0x00011111; - nv3_pmc_handle_interrupts(true); - break; - case NV3_PFIFO_DELAY_0: - nv3->pfifo.dma_delay_retry = val; - break; - case NV3_PFIFO_CONFIG_0: - nv3->pfifo.config_0 = val; - break; - - case NV3_PFIFO_CONFIG_RAMHT: - nv3->pfifo.ramht_config = val; -// This code sucks a bit fix it later -#ifdef ENABLE_NV_LOG - uint32_t new_size_ramht = ((val >> 16) & 0x03); - - if (new_size_ramht == 0) - new_size_ramht = 0x1000; - else if (new_size_ramht == 1) - new_size_ramht = 0x2000; - else if (new_size_ramht == 2) - new_size_ramht = 0x4000; - else if (new_size_ramht == 3) - new_size_ramht = 0x8000; - - nv_log("RAMHT Reconfiguration\n" - "Base Address in RAMIN: %d\n" - "Size: 0x%08x bytes\n", ((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS) & 0x0F) << 12, new_size_ramht); -#endif - break; - case NV3_PFIFO_CONFIG_RAMFC: - nv3->pfifo.ramfc_config = val; - - nv_log("RAMFC Reconfiguration\n" - "Base Address in RAMIN: %d\n", ((nv3->pfifo.ramfc_config >> NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS) & 0x7F) << 9); - break; - case NV3_PFIFO_CONFIG_RAMRO: - nv3->pfifo.ramro_config = val; - - uint32_t new_size_ramro = ((val >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); - - if (new_size_ramro == 0) - new_size_ramro = 0x200; - else if (new_size_ramro == 1) - new_size_ramro = 0x2000; - - nv_log("RAMRO Reconfiguration\n" - "Base Address in RAMIN: %d\n" - "Size: 0x%08x bytes\n", ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS) & 0x7F) << 9, new_size_ramro); - break; - case NV3_PFIFO_DEBUG_0: - nv3->pfifo.debug_0 = val; - break; - // Reassignment - case NV3_PFIFO_CACHE_REASSIGNMENT: - nv3->pfifo.cache_reassignment = val & 0x01; //1bit meaningful - break; - // Control - these can trigger pulls - case NV3_PFIFO_CACHE0_PULL0: - nv3->pfifo.cache0_settings.pull0 = val; // 8bits meaningful - - if (nv3->pfifo.cache0_settings.pull0 & (1 >> NV3_PFIFO_CACHE0_PULL0_ENABLED)) - nv3_pfifo_cache0_pull(); - - break; - case NV3_PFIFO_CACHE1_PULL0: - nv3->pfifo.cache1_settings.pull0 = val; // 8bits meaningful - - if (nv3->pfifo.cache1_settings.pull0 & (1 >> NV3_PFIFO_CACHE1_PULL0_ENABLED)) - nv3_pfifo_cache1_pull(); - - break; - case NV3_PFIFO_CACHE0_PULLER_CTX_STATE: - nv3->pfifo.cache0_settings.context_is_dirty = (val >> NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) & 0x01; - break; - case NV3_PFIFO_CACHE1_PULLER_CTX_STATE: - nv3->pfifo.cache1_settings.context_is_dirty = (val >> NV3_PFIFO_CACHE0_PULLER_CTX_STATE_DIRTY) & 0x01; - break; - case NV3_PFIFO_CACHE0_PUSH_ENABLED: - nv3->pfifo.cache0_settings.push0 = val; - break; - case NV3_PFIFO_CACHE1_PUSH_ENABLED: - nv3->pfifo.cache1_settings.push0 = val; - break; - case NV3_PFIFO_CACHE0_PUSH_CHANNEL_ID: - nv3->pfifo.cache0_settings.channel = val; - break; - case NV3_PFIFO_CACHE1_PUSH_CHANNEL_ID: - nv3->pfifo.cache1_settings.channel = val; - break; - // CACHE0_STATUS and CACHE1_STATUS are not writable - // DMA configuration - case NV3_PFIFO_CACHE1_DMA_CONFIG_0: - nv3->pfifo.cache1_settings.dma_state = val; - break; - case NV3_PFIFO_CACHE1_DMA_CONFIG_1: - nv3->pfifo.cache1_settings.dma_length = val; - break; - case NV3_PFIFO_CACHE1_DMA_CONFIG_2: - nv3->pfifo.cache1_settings.dma_address = val; - break; - case NV3_PFIFO_CACHE1_DMA_STATUS: - nv3->pfifo.cache1_settings.dma_status = val; - break; - case NV3_PFIFO_CACHE1_DMA_TLB_PT_BASE: - nv3->pfifo.cache1_settings.dma_tlb_pt_base = val; - break; - case NV3_PFIFO_CACHE1_DMA_TLB_PTE: - nv3->pfifo.cache1_settings.dma_tlb_pte = val; - break; - case NV3_PFIFO_CACHE1_DMA_TLB_TAG: - nv3->pfifo.cache1_settings.dma_tlb_tag = val; - break; - /* Put and Get addresses */ - case NV3_PFIFO_CACHE0_PUT: - nv3->pfifo.cache0_settings.put_address = val; - break; - case NV3_PFIFO_CACHE0_GET: - nv3->pfifo.cache0_settings.get_address = val; - break; - case NV3_PFIFO_CACHE1_PUT: - nv3->pfifo.cache1_settings.put_address = val; - break; - case NV3_PFIFO_CACHE1_GET: - nv3->pfifo.cache1_settings.get_address = val; - break; - case NV3_PFIFO_RUNOUT_GET: - { - uint32_t size_get = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); - - if (size_get == 0) //512b - nv3->pfifo.runout_get = val & (NV3_RAMIN_RAMRO_SIZE_0 - 0x07); - else - nv3->pfifo.runout_get = val & (NV3_RAMIN_RAMRO_SIZE_1 - 0x07); - break; - } - case NV3_PFIFO_RUNOUT_PUT: - { - uint32_t size_put = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); - - if (size_put == 0) //512b - nv3->pfifo.runout_put = val & (NV3_RAMIN_RAMRO_SIZE_0 - 0x07); - else - nv3->pfifo.runout_put = val & (NV3_RAMIN_RAMRO_SIZE_1 - 0x07); - - break; - } - /* Cache1 Context is handled below */ - case NV3_PFIFO_CACHE0_CTX: - nv3->pfifo.cache0_settings.context[0] = val; - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else if (address >= NV3_PFIFO_CACHE0_METHOD_START && address <= NV3_PFIFO_CACHE0_METHOD_END) - { - nv_log_verbose_only("PFIFO Cache0 Write\n"); - - // 3104 always written after 3100 - if (address & 4) - { - nv_log_verbose_only("Name = 0x%08x\n", val); - nv3->pfifo.cache0_entry.data = val; - nv3_pfifo_cache0_pull(); // immediately pull out - } - else - { - nv3->pfifo.cache0_entry.method = (val & 0x1FFC); - nv3->pfifo.cache0_entry.subchannel = (val >> NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL) & 0x07; - nv_log_verbose_only("Subchannel = 0x%08x, method = 0x%04x\n", nv3->pfifo.cache0_entry.subchannel, nv3->pfifo.cache0_entry.method); - } - - } - 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); - - nv_log_verbose_only("Cache1 Write Slot %d (Gray code)", real_entry); - - // See if we want the object name or the channel/subchannel information. - if (address & 4) - { - nv_log_verbose_only("Name = 0x%08x\n", val); - 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; - nv_log_verbose_only("Subchannel = 0x%08x, method = 0x%04x\n", nv3->pfifo.cache1_entries[real_entry].subchannel, nv3->pfifo.cache1_entries[real_entry].method); - } - } - /* 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] = val; - - nv_log_verbose_only("PFIFO Cache1 CTX Write Entry=%d value=0x%04x\n", ctx_entry_id, val); - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } - - /* Trigger DMA for notifications if we need to */ - nv3_pfifo_trigger_dma_if_required(); -} - - -/* -https://en.wikipedia.org/wiki/Gray_code -WHY?????? IT'S NOT A TELEGRAPH IT'S A GPU????? - -Convert from a normal number to a total insanity number which is only used in PFIFO CACHE1 for ungodly and totally unknowable reasons -(Possibly it just makes it easier to implement in logic) - -I decided to use a lookup table to save everyone's time, also the numbers generated from the function -that existed here before didn't make any sense -*/ - -#define NV3_GRAY_TABLE_NUM_ENTRIES 64 - -uint8_t nv3_pfifo_cache1_gray_code_table[NV3_GRAY_TABLE_NUM_ENTRIES] = { - 0b000000, 0b000001, 0b000011, 0b000010, 0b000110, 0b000111, 0b000101, 0b000100, //0x07 - 0b001100, 0b001101, 0b001111, 0b001110, 0b001010, 0b001011, 0b001001, 0b001000, //0x0F - 0b011000, 0b011001, 0b011011, 0b011010, 0b011110, 0b011111, 0b011101, 0b011100, //0x17 - 0b010100, 0b010101, 0b010111, 0b010110, 0b010010, 0b010011, 0b010001, 0b010000, //0x1F - 0b110000, 0b110001, 0b110011, 0b110010, 0b110110, 0b110111, 0b110101, 0b110100, //0x27 - 0b111100, 0b111101, 0b111111, 0b111110, 0b111010, 0b111011, 0b111001, 0b111000, //0x2F - 0b101000, 0b101001, 0b101011, 0b101010, 0b101110, 0b101111, 0b101101, 0b101100, //0x37 - 0b100100, 0b100101, 0b100111, 0b100110, 0b100010, 0b100011, 0b100001, 0b100000 //0x3F -}; - -/* The function is called up to hundreds of thousands of times per second, it's too slow to do anything else */ -uint8_t nv3_pfifo_cache1_binary_code_table[NV3_GRAY_TABLE_NUM_ENTRIES] = -{ - 0x00, 0x01, 0x03, 0x02, 0x07, 0x06, 0x04, 0x05, // 0x07 (0) - 0x0F, 0x0E, 0x0C, 0x0D, 0x08, 0x09, 0x0B, 0x0A, // 0x0F (1000) - 0x1F, 0x1E, 0x1C, 0x1D, 0x18, 0x19, 0x1B, 0x1A, // 0x17 (10000) - 0x10, 0x11, 0x13, 0x12, 0x17, 0x16, 0x14, 0x15, // 0x1F (11000) - 0x3F, 0x3E, 0x3C, 0x3D, 0x38, 0x39, 0x3B, 0x3A, // 0x27 (100000) - 0x30, 0x31, 0x33, 0x32, 0x37, 0x36, 0x34, 0x35, // 0x2F (101000) - 0x20, 0x21, 0x23, 0x22, 0x27, 0x26, 0x24, 0x25, // 0x37 (110000) - 0x2F, 0x2E, 0x2C, 0x2D, 0x28, 0x29, 0x2B, 0x2A, // 0X3f (111000) -}; - -uint32_t nv3_pfifo_cache1_normal2gray(uint32_t val) -{ - return nv3_pfifo_cache1_gray_code_table[val]; -} - -/* -Back to sanity -*/ -uint32_t nv3_pfifo_cache1_gray2normal(uint32_t val) -{ - return nv3_pfifo_cache1_binary_code_table[val]; -} - -/* -You can't push into cache0 on the real hardware, but it's not practically done because Cache0 is meant to be reserved for software objects, -NV_USER writes always go to CACHE1 -*/ - -// Pulls graphics objects OUT of cache0 -void nv3_pfifo_cache0_pull(void) -{ - // Do nothing if PFIFO CACHE0 is disabled - if (!nv3->pfifo.cache0_settings.pull0 & (1 >> NV3_PFIFO_CACHE0_PULL0_ENABLED)) - return; - - // Do nothing if there is nothing in cache0 to pull - if (nv3->pfifo.cache0_settings.put_address == nv3->pfifo.cache0_settings.get_address) - return; - - // There is only one entry for cache0 - uint8_t current_channel = nv3->pfifo.cache0_settings.channel; - uint8_t current_subchannel = nv3->pfifo.cache0_entry.subchannel; - uint32_t current_param = nv3->pfifo.cache0_entry.data; - uint16_t current_method = nv3->pfifo.cache0_entry.method; - - // i.e. there is no method in cache0, so we have to find the object. - if (!current_method) - { - // flip the get address over - nv3->pfifo.cache0_settings.get_address ^= 0x04; - - if (!nv3_ramin_find_object(current_param, 0, current_channel, current_subchannel)) - return; // interrupt was fired, and we went to ramro - } - - uint32_t current_context = nv3->pfifo.cache0_settings.context[0]; // only 1 entry for CACHE0 so basically ignore the other context entries? - uint8_t class_id = ((nv3_ramin_context_t*)¤t_context)->class_id; - - // Tell the CPU if we found a software method and turn off cache pulling - if (!(current_context & 0x800000)) - { - nv_log_verbose_only("The object in CACHE0 is a software object\n"); - - nv3->pfifo.cache0_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; - nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true); - return; - } - - // Is this needed? - nv3->pfifo.cache0_settings.get_address ^= 0x04; - - #ifndef RELEASE_BUILD - - nv_log_verbose_only("***** DEBUG: CACHE0 PULLED ****** Contextual information below\n"); - - - nv3_ramin_context_t context_structure = *(nv3_ramin_context_t*)¤t_context; - - nv3_debug_ramin_print_context_info(current_param, context_structure); - - nv3_pgraph_submit(current_param, current_method, current_channel, current_subchannel, class_id & 0x1F, context_structure); - #endif - -} - -void nv3_pfifo_context_switch(uint32_t new_channel) -{ - /* Send our contexts to RAMFC. Load the new ones from RAMFC. */ - if (new_channel >= NV3_DMA_CHANNELS) - fatal("nv3_pfifo_context_switch: Tried to switch to invalid dma channel"); - - //uint16_t ramfc_base = nv3->pfifo.ramfc_config >> NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS & 0xF; -} - -// NV_USER writes go here! -// Pushes graphics objects into cache1 -void nv3_pfifo_cache1_push(uint32_t addr, uint32_t param) -{ - bool oh_shit = false; // RAMRO needed - nv3_ramin_ramro_reason oh_shit_reason = 0x00; // It's all good for now - - // bit 23 of a ramin dword means it's a write... - uint32_t new_address = 0; - - uint32_t method_offset = (addr & 0x1FFC); // size of dma object is 0x2000 and some universal methods are implemented at this point, like free - - // Up to 128 per envytools? - uint32_t channel = (addr >> NV3_OBJECT_SUBMIT_CHANNEL) & 0x7F; - uint32_t subchannel = (addr >> NV3_OBJECT_SUBMIT_SUBCHANNEL) & (NV3_DMA_CHANNELS - 1); - - // first make sure there is even any cache available - if (!nv3->pfifo.cache1_settings.push0) - { - oh_shit = true; - oh_shit_reason = nv3_runout_reason_no_cache_available; - new_address |= (nv3_runout_reason_no_cache_available << NV3_PFIFO_RUNOUT_RAMIN_ERR); - - } - - // Check if runout is full - if (nv3->pfifo.runout_get != nv3->pfifo.runout_put) - { - oh_shit = true; - oh_shit_reason = nv3_runout_reason_cache_ran_out; // ? really ? I guess this means we already ran out.. - new_address |= (nv3_runout_reason_cache_ran_out << NV3_PFIFO_RUNOUT_RAMIN_ERR); - } - - if (!nv3_pfifo_cache1_num_free_spaces()) - { - oh_shit = true; - oh_shit_reason = nv3_runout_reason_free_count_overrun; - new_address |= (nv3_runout_reason_free_count_overrun << NV3_PFIFO_RUNOUT_RAMIN_ERR); - } - - // 0x0 is used for creating the object. - if (method_offset > 0 && method_offset < 0x100) - { - // Reserved nvidia methods - oh_shit = true; - oh_shit_reason = nv3_runout_reason_reserved_access; - new_address |= (nv3_runout_reason_reserved_access << NV3_PFIFO_RUNOUT_RAMIN_ERR); - - } - - // Now check for context switching - - if (channel != nv3->pfifo.cache1_settings.channel) - { - // Cache reassignment required - if (!nv3->pfifo.cache_reassignment - || (nv3->pfifo.cache1_settings.get_address != nv3->pfifo.cache1_settings.put_address)) - { - oh_shit = true; - oh_shit_reason = nv3_runout_reason_no_cache_available; - new_address |= (nv3_runout_reason_no_cache_available << NV3_PFIFO_RUNOUT_RAMIN_ERR); - } - - nv3_pfifo_context_switch(channel); - } - - // Did we fuck up? - if (oh_shit) - { - nv_log("OH CRAP: Runout Error=%d Channel=%d Subchannel=%d Method=0x%04x", - oh_shit_reason, channel, subchannel, method_offset); - - nv3_ramro_write(nv3->pfifo.runout_put, new_address); - nv3_ramro_write(nv3->pfifo.runout_put + 4, param); - - nv3->pfifo.runout_put += 0x08; - - uint32_t ramro_size = (nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01; - - /* Make sure it's valid */ - switch (ramro_size) - { - case 0: - nv3->pfifo.runout_put &= (NV3_RAMIN_RAMRO_SIZE_0 - 0x07); - break; - case 1: - nv3->pfifo.runout_put &= (NV3_RAMIN_RAMRO_SIZE_1 - 0x07); - break; - } - - //Fire the interrupt. Also the very bad interrupt... - if (nv3->pfifo.runout_get == nv3->pfifo.runout_put) - nv3_pfifo_interrupt(NV3_PFIFO_INTR_RUNOUT_OVERFLOW, true); - else - nv3_pfifo_interrupt(NV3_PFIFO_INTR_RUNOUT, true); - - return; - } - - // We didn't. Let's put it in CACHE1 - uint32_t current_put_index = nv3->pfifo.cache1_settings.put_address >> 2; - nv3->pfifo.cache1_entries[current_put_index].subchannel = subchannel; - nv3->pfifo.cache1_entries[current_put_index].method = method_offset; - nv3->pfifo.cache1_entries[current_put_index].data = param; - - // now we have to recalculate the cache1 put address - uint32_t next_put_address = nv3_pfifo_cache1_gray2normal(current_put_index); - next_put_address++; - - if (nv3->nvbase.gpu_revision >= NV3_PCI_CFG_REVISION_C00) // RIVA 128ZX# - next_put_address &= (NV3_PFIFO_CACHE1_SIZE_REV_C - 1); - else - next_put_address &= (NV3_PFIFO_CACHE1_SIZE_REV_AB - 1); - - nv3->pfifo.cache1_settings.put_address = nv3_pfifo_cache1_normal2gray(next_put_address) << 2; - - nv_log_verbose_only("Submitted object [PIO]: Channel %d.%d, Parameter 0x%08x, Method ID 0x%04x (Put Address is now %d)\n", - channel, subchannel, param, method_offset, nv3->pfifo.cache1_settings.put_address); - - // Now we're done. Phew! -} - -// Pulls graphics objects OUT of cache1 -void nv3_pfifo_cache1_pull(void) -{ - // Do nothing if PFIFO CACHE1 is disabled - if (!nv3->pfifo.cache1_settings.pull0 & (1 >> NV3_PFIFO_CACHE1_PULL0_ENABLED)) - return; - - // Do nothing if there is nothing in cache1 to pull - if (nv3->pfifo.cache1_settings.put_address == nv3->pfifo.cache1_settings.get_address) - return; - - uint32_t get_index = nv3->pfifo.cache1_settings.get_address >> 2; // 32 bit aligned probably - - uint8_t current_channel = nv3->pfifo.cache1_settings.channel; - uint8_t current_subchannel = nv3->pfifo.cache1_entries[get_index].subchannel; - uint32_t current_param = nv3->pfifo.cache1_entries[get_index].data; - uint16_t current_method = nv3->pfifo.cache1_entries[get_index].method; - - // NV_ROOT - if (!current_method) - { - if (!nv3_ramin_find_object(current_param, 1, current_channel, current_subchannel)) - return; // interrupt was fired, and we went to ramro - } - - // should this be obtained from the grobj? Test on real nv3 h/w after drawrect.nvp works - uint32_t current_context = nv3->pfifo.cache1_settings.context[current_subchannel]; // get the current subchannel - - uint8_t class_id = ((nv3_ramin_context_t*)¤t_context)->class_id; - - - - // start by incrementing - uint32_t next_get_address = nv3_pfifo_cache1_gray2normal(get_index) + 1; - - if (nv3->nvbase.gpu_revision >= NV3_PCI_CFG_REVISION_C00) // RIVA 128ZX - next_get_address &= (NV3_PFIFO_CACHE1_SIZE_REV_C - 1); - else - next_get_address &= (NV3_PFIFO_CACHE1_SIZE_REV_AB - 1); - - // Tell the CPU if we found a software method - //bit23 unset=software - //bit23 set=hardware - if (!(current_context & 0x800000)) - { - nv_log_verbose_only("The object in CACHE1 is a software object\n"); - - nv3->pfifo.cache1_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; - nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true); - return; - } - - // Is this needed? - nv3->pfifo.cache1_settings.get_address = nv3_pfifo_cache1_normal2gray(next_get_address) << 2; - - #ifndef RELEASE_BUILD - - nv_log_verbose_only("***** DEBUG: CACHE1 PULLED ****** Contextual information below\n"); - - nv3_ramin_context_t context_structure = *(nv3_ramin_context_t*)¤t_context; - - nv3_debug_ramin_print_context_info(current_param, context_structure); - #endif - - nv3_pgraph_submit(current_param, current_method, current_channel, current_subchannel, class_id & 0x1F, context_structure); - - - //Todo: finish it -} - -// THIS IS PER SUBCHANNEL! -uint32_t nv3_pfifo_cache1_num_free_spaces(void) -{ - // get the index - - uint32_t get_index = nv3->pfifo.cache1_settings.get_address >> 2; - uint32_t put_index = nv3->pfifo.cache1_settings.put_address >> 2; - - uint32_t real_get_address = nv3_pfifo_cache1_gray2normal(get_index) << 2; - uint32_t real_put_address = nv3_pfifo_cache1_gray2normal(put_index) << 2; - - // There is no hope of being able to understand it. Nobody can understand - return (real_get_address - real_put_address - 4) & 0x7C; // there are 64 entries what -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pgraph.c b/src/video/nv/nv3/subsystems/nv3_pgraph.c deleted file mode 100644 index 3ad9fa2a1..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pgraph.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PGRAPH (Scene Graph for 2D/3D Accelerated Graphics) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> -#include <86box/nv/classes/vid_nv3_classes.h> - -// Initialise the PGRAPH subsystem. -void nv3_pgraph_init(void) -{ - nv_log("Initialising PGRAPH..."); - // Set up the vblank interrupt - nv3->nvbase.svga.vblank_start = nv3_pgraph_vblank_start; - nv_log("Done!\n"); -} - -// -// ****** PGRAPH register list START ****** -// - -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 }, - { NV3_PGRAPH_INTR_EN_1, "PGRAPH Interrupt Enable 1", NULL, NULL }, - { NV3_PGRAPH_CTX_SWITCH, "PGRAPH DMA Context Switch", NULL, NULL }, - { NV3_PGRAPH_CONTEXT_CONTROL, "PGRAPH DMA Context Control", NULL, NULL }, - { NV3_PGRAPH_CONTEXT_USER, "PGRAPH DMA Context User", NULL, NULL }, - //{ NV3_PGRAPH_CONTEXT_CACHE(0), "PGRAPH DMA Context Cache", NULL, NULL }, - { NV3_PGRAPH_ABS_UCLIP_XMIN, "PGRAPH Absolute Clip Minimum X [17:0]", NULL, NULL }, - { NV3_PGRAPH_ABS_UCLIP_XMAX, "PGRAPH Absolute Clip Maximum X [17:0]", NULL, NULL }, - { NV3_PGRAPH_ABS_UCLIP_YMIN, "PGRAPH Absolute Clip Minimum Y [17:0]", NULL, NULL }, - { NV3_PGRAPH_ABS_UCLIP_YMAX, "PGRAPH Absolute Clip Maximum Y [17:0]", NULL, NULL }, - { NV3_PGRAPH_SRC_CANVAS_MIN, "PGRAPH Source Canvas Minimum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, - { NV3_PGRAPH_SRC_CANVAS_MAX, "PGRAPH Source Canvas Maximum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, - { NV3_PGRAPH_DST_CANVAS_MIN, "PGRAPH Destination Canvas Minimum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, - { NV3_PGRAPH_DST_CANVAS_MAX, "PGRAPH Destination Canvas Maximum Coordinates (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, - { NV3_PGRAPH_PATTERN_COLOR_0_RGB, "PGRAPH Pattern Color 0_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_0_ALPHA, "PGRAPH Pattern Color 0_1 (Bits 7:0 = Alpha)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_1_RGB, "PGRAPH Pattern Color 1_0 (Bits 29:20 = Red, Bits 19:10 = Green, Bits 9:0 = Blue)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_COLOR_1_ALPHA, "PGRAPH Pattern Color 1_1 (Bits 7:0 = Alpha)", NULL, NULL, }, - { NV3_PGRAPH_PATTERN_BITMAP_HIGH, "PGRAPH Pattern Bitmap (High 32bits)", NULL, NULL}, - { NV3_PGRAPH_PATTERN_BITMAP_LOW, "PGRAPH Pattern Bitmap (Low 32bits)", NULL, NULL}, - { NV3_PGRAPH_PATTERN_SHAPE, "PGRAPH Pattern Shape (1:0 - 0=8x8, 1=64x1, 2=1x64)", NULL, NULL}, - { NV3_PGRAPH_ROP3, "PGRAPH GDI Ternary 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_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}, - { NV3_PGRAPH_CLIP1_MAX, "PGRAPH Clip1 Max (Bits 30:16 = Y, Bits 10:0 = X)", NULL, NULL}, - { NV3_PGRAPH_FIFO_ACCESS, "PGRAPH - Can we access PFIFO?", NULL, NULL, }, - { NV3_PGRAPH_STATUS, "PGRAPH Status", NULL, NULL }, - { NV3_PGRAPH_TRAPPED_ADDRESS, "PGRAPH Trapped Address", NULL, NULL }, - { NV3_PGRAPH_TRAPPED_DATA, "PGRAPH Trapped Data", NULL, NULL }, - { NV3_PGRAPH_INSTANCE, "PGRAPH Object Instance", NULL, NULL}, - { NV3_PGRAPH_TRAPPED_INSTANCE, "PGRAPH Trapped Object Instance", NULL, NULL }, - { NV3_PGRAPH_DMA_INTR_0, "PGRAPH DMA Interrupt Status (unimplemented)", NULL, NULL }, - { NV3_PGRAPH_DMA_INTR_EN_0, "PGRAPH DMA Interrupt Enable (unimplemented)", NULL, NULL }, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -uint32_t nv3_pgraph_read(uint32_t address) -{ - // before doing anything, check that this is even enabled.. - - if (!(nv3->pmc.enable >> NV3_PMC_ENABLE_PGRAPH) - & NV3_PMC_ENABLE_PGRAPH_ENABLED) - { - nv_log("Repressing PGRAPH read. The subsystem is disabled according to pmc_enable, returning 0\n"); - return 0x00; - } - - uint32_t ret = 0x00; - - nv_register_t* reg = nv_get_register(address, pgraph_registers, sizeof(pgraph_registers)/sizeof(pgraph_registers[0])); - - // todo: friendly logging - - nv_log_verbose_only("PGRAPH Read from 0x%08x", address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - switch (reg->address) - { - case NV3_PGRAPH_DEBUG_0: - ret = nv3->pgraph.debug_0; - break; - case NV3_PGRAPH_DEBUG_1: - ret = nv3->pgraph.debug_1; - break; - case NV3_PGRAPH_DEBUG_2: - ret = nv3->pgraph.debug_2; - break; - case NV3_PGRAPH_DEBUG_3: - ret = nv3->pgraph.debug_3; - break; - //interrupt status and enable regs - case NV3_PGRAPH_INTR_0: - ret = nv3->pgraph.interrupt_status_0; - nv3_pmc_clear_interrupts(); - break; - case NV3_PGRAPH_INTR_1: - ret = nv3->pgraph.interrupt_status_1; - nv3_pmc_clear_interrupts(); - 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 - - // In the future, these will most likely have their own functions... - - // Context Swithcing (THIS IS CONTROLLED BY PFIFO!) - case NV3_PGRAPH_CTX_SWITCH: - ret = nv3->pgraph.context_switch; - break; - case NV3_PGRAPH_CONTEXT_CONTROL: - ret = *(uint32_t*)&nv3->pgraph.context_control; - break; - case NV3_PGRAPH_CONTEXT_USER: - ret = *(uint32_t*)&nv3->pgraph.context_user; - break; - // Clip - case NV3_PGRAPH_ABS_UCLIP_XMIN: - ret = nv3->pgraph.abs_uclip_xmin; - break; - case NV3_PGRAPH_ABS_UCLIP_XMAX: - ret = nv3->pgraph.abs_uclip_xmax; - break; - case NV3_PGRAPH_ABS_UCLIP_YMIN: - ret = nv3->pgraph.abs_uclip_ymin; - break; - case NV3_PGRAPH_ABS_UCLIP_YMAX: - ret = nv3->pgraph.abs_uclip_ymax; - break; - // Canvas - case NV3_PGRAPH_SRC_CANVAS_MIN: - ret = *(uint32_t*)&nv3->pgraph.src_canvas_min; - break; - case NV3_PGRAPH_SRC_CANVAS_MAX: - ret = *(uint32_t*)&nv3->pgraph.src_canvas_max; - break; - // Pattern - case NV3_PGRAPH_PATTERN_COLOR_0_RGB: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_rgb; - break; - case NV3_PGRAPH_PATTERN_COLOR_0_ALPHA: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_0_alpha; - break; - case NV3_PGRAPH_PATTERN_COLOR_1_RGB: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_rgb; - break; - case NV3_PGRAPH_PATTERN_COLOR_1_ALPHA: - ret = *(uint32_t*)&nv3->pgraph.pattern_color_1_alpha; - break; - case NV3_PGRAPH_PATTERN_BITMAP_HIGH: - ret = (nv3->pgraph.pattern_bitmap >> 32) & 0xFFFFFFFF; - break; - case NV3_PGRAPH_PATTERN_BITMAP_LOW: - ret = (nv3->pgraph.pattern_bitmap & 0xFFFFFFFF); - break; - // Beta factor - case NV3_PGRAPH_BETA: - ret = nv3->pgraph.beta_factor; - break; - // Todo: Massive table of ROP IDs or at least known ones? - case NV3_PGRAPH_ROP3: - ret = nv3->pgraph.rop; - break; - case NV3_PGRAPH_CHROMA_KEY: - ret = *(uint32_t*)&nv3->pgraph.chroma_key; - break; - case NV3_PGRAPH_PLANE_MASK: - ret = nv3->pgraph.plane_mask; - break; - // DMA - case NV3_PGRAPH_DMA: - ret = *(uint32_t*)&nv3->pgraph.dma_settings; - break; - case NV3_PGRAPH_NOTIFY: - ret = *(uint32_t*)&nv3->pgraph.notifier; - break; - // More clip - case NV3_PGRAPH_CLIP0_MIN: - ret = *(uint32_t*)&nv3->pgraph.clip0_min; - break; - case NV3_PGRAPH_CLIP0_MAX: - ret = *(uint32_t*)&nv3->pgraph.clip0_max; - break; - case NV3_PGRAPH_CLIP1_MIN: - ret = *(uint32_t*)&nv3->pgraph.clip1_min; - break; - case NV3_PGRAPH_CLIP1_MAX: - ret = *(uint32_t*)&nv3->pgraph.clip1_max; - break; - case NV3_PGRAPH_CLIP_MISC: - ret = *(uint32_t*)&nv3->pgraph.clip_misc_settings; - break; - - // Overall Status - case NV3_PGRAPH_STATUS: - ret = *(uint32_t*)&nv3->pgraph.status; - break; - // Trapped Address - case NV3_PGRAPH_TRAPPED_ADDRESS: - ret = nv3->pgraph.trapped_address; - break; - case NV3_PGRAPH_TRAPPED_DATA: - ret = nv3->pgraph.trapped_data; - break; - case NV3_PGRAPH_INSTANCE: - ret = nv3->pgraph.instance; - break; - case NV3_PGRAPH_TRAPPED_INSTANCE: - ret = nv3->pgraph.trapped_instance; - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - /* Special exception for memory areas */ - if (address >= NV3_PGRAPH_CONTEXT_CACHE(0) - && address <= NV3_PGRAPH_CONTEXT_CACHE(NV3_PGRAPH_CONTEXT_CACHE_SIZE)) - { - // Addresses should be aligned to 4 bytes. - uint32_t entry = (address - NV3_PGRAPH_CONTEXT_CACHE(0)); - - nv_log_verbose_only("PGRAPH Context Cache Read (Entry=%04x Value=%04x)\n", entry, nv3->pgraph.context_cache[entry]); - } - else /* Completely unknown */ - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - } - - return ret; -} - -void nv3_pgraph_write(uint32_t address, uint32_t value) -{ - if (!(nv3->pmc.enable >> NV3_PMC_ENABLE_PGRAPH) - & NV3_PMC_ENABLE_PGRAPH_ENABLED) - { - nv_log("Repressing PGRAPH write. The subsystem is disabled according to pmc_enable\n"); - return; - } - - nv_register_t* reg = nv_get_register(address, pgraph_registers, sizeof(pgraph_registers)/sizeof(pgraph_registers[0])); - - nv_log_verbose_only("PGRAPH Write 0x%08x -> 0x%08x\n", value, address); - - // if the register actually exists - if (reg) - { - - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - switch (reg->address) - { - case NV3_PGRAPH_DEBUG_0: - nv3->pgraph.debug_0 = value; - break; - case NV3_PGRAPH_DEBUG_1: - nv3->pgraph.debug_1 = value; - break; - case NV3_PGRAPH_DEBUG_2: - nv3->pgraph.debug_2 = value; - break; - case NV3_PGRAPH_DEBUG_3: - nv3->pgraph.debug_3 = value; - break; - //interrupt status and enable regs - case NV3_PGRAPH_INTR_0: - nv3->pgraph.interrupt_status_0 &= ~value; - //we changed interrupt state - nv3_pmc_clear_interrupts(); - break; - case NV3_PGRAPH_INTR_1: - nv3->pgraph.interrupt_status_1 &= ~value; - //we changed interrupt state - nv3_pmc_clear_interrupts(); - break; - // Only bits divisible by 4 matter - // and only bit0-16 is defined in intr_1 - case NV3_PGRAPH_INTR_EN_0: - nv3->pgraph.interrupt_enable_0 = value & 0x11111111; - nv3_pmc_handle_interrupts(true); - break; - case NV3_PGRAPH_INTR_EN_1: - nv3->pgraph.interrupt_enable_1 = value & 0x00011111; - nv3_pmc_handle_interrupts(true); - break; - case NV3_PGRAPH_DMA_INTR_0: - nv3->pgraph.interrupt_status_dma &= ~value; - nv3_pmc_clear_interrupts(); - break; - case NV3_PGRAPH_DMA_INTR_EN_0: - nv3->pgraph.interrupt_enable_dma = value & 0x000111111; - nv_log("Handling PGRAPH_DMA interrupts not implemented"); - 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 - - // In the future, these will most likely have their own functions... - - // Context Swithcing (THIS IS CONTROLLED BY PFIFO!) - case NV3_PGRAPH_CTX_SWITCH: - nv3->pgraph.context_switch = value; - break; - case NV3_PGRAPH_CONTEXT_CONTROL: - *(uint32_t*)&nv3->pgraph.context_control = value; - break; - case NV3_PGRAPH_CONTEXT_USER: - *(uint32_t*)&nv3->pgraph.context_user = value; - break; - // Clip - case NV3_PGRAPH_ABS_UCLIP_XMIN: - nv3->pgraph.abs_uclip_xmin = value; - break; - case NV3_PGRAPH_ABS_UCLIP_XMAX: - nv3->pgraph.abs_uclip_xmax = value; - break; - case NV3_PGRAPH_ABS_UCLIP_YMIN: - nv3->pgraph.abs_uclip_ymin = value; - break; - case NV3_PGRAPH_ABS_UCLIP_YMAX: - nv3->pgraph.abs_uclip_ymax = value; - break; - // Canvas - case NV3_PGRAPH_SRC_CANVAS_MIN: - *(uint32_t*)&nv3->pgraph.src_canvas_min = value; - break; - case NV3_PGRAPH_SRC_CANVAS_MAX: - *(uint32_t*)&nv3->pgraph.src_canvas_max = value; - break; - // Pattern - case NV3_PGRAPH_PATTERN_COLOR_0_RGB: - *(uint32_t*)&nv3->pgraph.pattern_color_0_rgb = value; - break; - case NV3_PGRAPH_PATTERN_COLOR_0_ALPHA: - *(uint32_t*)&nv3->pgraph.pattern_color_0_alpha = value; - break; - case NV3_PGRAPH_PATTERN_COLOR_1_RGB: - *(uint32_t*)&nv3->pgraph.pattern_color_1_rgb = value; - break; - case NV3_PGRAPH_PATTERN_COLOR_1_ALPHA: - *(uint32_t*)&nv3->pgraph.pattern_color_1_alpha = value; - break; - case NV3_PGRAPH_PATTERN_BITMAP_HIGH: - nv3->pgraph.pattern_bitmap |= ((uint64_t)value << 32); - break; - case NV3_PGRAPH_PATTERN_BITMAP_LOW: - nv3->pgraph.pattern_bitmap |= value; - break; - // Beta factor - case NV3_PGRAPH_BETA: - nv3->pgraph.beta_factor = value; - break; - // Todo: Massive table of ROP IDs or at least known ones? - case NV3_PGRAPH_ROP3: - nv3->pgraph.rop = value & 0xFF; - break; - case NV3_PGRAPH_CHROMA_KEY: - nv3->pgraph.chroma_key = value; - break; - case NV3_PGRAPH_PLANE_MASK: - nv3->pgraph.plane_mask = value; - break; - // DMA - case NV3_PGRAPH_DMA: - *(uint32_t*)&nv3->pgraph.dma_settings = value; - break; - case NV3_PGRAPH_NOTIFY: - *(uint32_t*)&nv3->pgraph.notifier = value; - break; - // More clip - case NV3_PGRAPH_CLIP0_MIN: - *(uint32_t*)&nv3->pgraph.clip0_min = value; - break; - case NV3_PGRAPH_CLIP0_MAX: - *(uint32_t*)&nv3->pgraph.clip0_max = value; - break; - case NV3_PGRAPH_CLIP1_MIN: - *(uint32_t*)&nv3->pgraph.clip1_min = value; - break; - case NV3_PGRAPH_CLIP1_MAX: - *(uint32_t*)&nv3->pgraph.clip1_max = value; - break; - case NV3_PGRAPH_CLIP_MISC: - *(uint32_t*)&nv3->pgraph.clip_misc_settings = value; - break; - // Overall Status - case NV3_PGRAPH_STATUS: - *(uint32_t*)&nv3->pgraph.status = value; - break; - // Trapped Address - case NV3_PGRAPH_TRAPPED_ADDRESS: - nv3->pgraph.trapped_address = value; - break; - case NV3_PGRAPH_TRAPPED_DATA: - nv3->pgraph.trapped_data = value; - break; - case NV3_PGRAPH_INSTANCE: - nv3->pgraph.instance = value; - break; - case NV3_PGRAPH_TRAPPED_INSTANCE: - nv3->pgraph.trapped_instance = value; - break; - - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - } - else - { - /* Special exception for memory areas */ - if (address >= NV3_PGRAPH_CONTEXT_CACHE(0) - && address <= NV3_PGRAPH_CONTEXT_CACHE(NV3_PGRAPH_CONTEXT_CACHE_SIZE)) - { - // Addresses should be aligned to 4 bytes. - uint32_t entry = (address - NV3_PGRAPH_CONTEXT_CACHE(0)) >> 2; - - nv_log_verbose_only("PGRAPH Context Cache Write (Entry=%04x Value=0x%08x)\n", entry, value); - nv3->pgraph.context_cache[entry] = value; - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } - } -} - -// Fire a VALID Pgraph interrupt: num is the bit# of the interrupt in the GPU subsystem INTR_EN register. -void nv3_pgraph_interrupt_valid(uint32_t num) -{ - nv3->pgraph.interrupt_status_0 |= (1 << num); - nv3_pmc_handle_interrupts(true); -} - -// Fire an INVALID pgraph interrupt -void nv3_pgraph_interrupt_invalid(uint32_t num) -{ - nv3->pgraph.interrupt_status_1 |= (1 << num); - - // Some code in pcbox hat enables the "reserved" bit HERE if it's set in intr 0. What??? - nv3_pmc_handle_interrupts(true); -} - -// VBlank. Fired every single frame. -void nv3_pgraph_vblank_start(svga_t* svga) -{ - nv3_pgraph_interrupt_valid(NV3_PGRAPH_INTR_0_VBLANK); -} - -/* Sends off method execution to the right class */ -void nv3_pgraph_arbitrate_method(uint32_t param, uint16_t method, uint8_t channel, uint8_t subchannel, uint8_t class_id, nv3_ramin_context_t context) -{ - /* Obtain the grobj information from the context in ramin */ - nv3_grobj_t grobj = {0}; - - // we need to shift left by 4 to get the real address, something to do with the 16 byte unit of reversal - uint32_t real_ramin_base = context.ramin_offset << 4; - - // readin our grobj - grobj.grobj_0 = nv3_ramin_read32(real_ramin_base, nv3); - grobj.grobj_1 = nv3_ramin_read32(real_ramin_base + 4, nv3); - grobj.grobj_2 = nv3_ramin_read32(real_ramin_base + 8, nv3); - grobj.grobj_3 = nv3_ramin_read32(real_ramin_base + 12, nv3); - - nv_log_verbose_only("**** About to execute method **** method=0x%04x param=0x%08x, channel=%d.%d, class=%s, grobj=0x%08x 0x%08x 0x%08x 0x%08x\n", - method, param, channel, subchannel, nv3_class_names[class_id], grobj.grobj_0, grobj.grobj_1, grobj.grobj_2, grobj.grobj_3); - - /* Methods below 0x104 are shared across all classids, so call generic_method for that*/ - if (method <= NV3_SET_NOTIFY) - { - nv3_generic_method(param, method, context, grobj); - } - else - { - // By this point, we already ANDed the class ID to 0x1F. - // Send the grobj, the context, the method and the name off to actually be acted upon. - switch (class_id) - { - case nv3_pgraph_class01_beta_factor: - nv3_class_001_method(param, method, context, grobj); - break; - case nv3_pgraph_class02_rop: - nv3_class_002_method(param, method, context, grobj); - break; - case nv3_pgraph_class03_chroma_key: - nv3_class_003_method(param, method, context, grobj); - break; - case nv3_pgraph_class04_plane_mask: - nv3_class_004_method(param, method, context, grobj); - break; - case nv3_pgraph_class05_clipping_rectangle: - nv3_class_005_method(param, method, context, grobj); - break; - case nv3_pgraph_class06_pattern: - nv3_class_006_method(param, method, context, grobj); - break; - case nv3_pgraph_class07_rectangle: - nv3_class_007_method(param, method, context, grobj); - break; - case nv3_pgraph_class08_point: - nv3_class_008_method(param, method, context, grobj); - break; - case nv3_pgraph_class09_line: - nv3_class_009_method(param, method, context, grobj); - break; - case nv3_pgraph_class0a_lin: - nv3_class_00a_method(param, method, context, grobj); - break; - case nv3_pgraph_class0b_triangle: - nv3_class_00b_method(param, method, context, grobj); - break; - case nv3_pgraph_class0c_w95txt: - nv3_class_00c_method(param, method, context, grobj); - break; - case nv3_pgraph_class0d_m2mf: - nv3_class_00d_method(param, method, context, grobj); - break; - case nv3_pgraph_class0e_scaled_image_from_memory: - nv3_class_00e_method(param, method, context, grobj); - break; - case nv3_pgraph_class10_blit: - nv3_class_010_method(param, method, context, grobj); - break; - case nv3_pgraph_class11_image: - nv3_class_011_method(param, method, context, grobj); - break; - case nv3_pgraph_class12_bitmap: - nv3_class_012_method(param, method, context, grobj); - break; - case nv3_pgraph_class14_transfer2memory: - nv3_class_014_method(param, method, context, grobj); - break; - case nv3_pgraph_class15_stretched_image_from_cpu: - nv3_class_015_method(param, method, context, grobj); - break; - case nv3_pgraph_class17_d3d5tri_zeta_buffer: - nv3_class_017_method(param, method, context, grobj); - break; - case nv3_pgraph_class18_point_zeta_buffer: - nv3_class_018_method(param, method, context, grobj); - break; - case nv3_pgraph_class1c_image_in_memory: - nv3_class_01c_method(param, method, context, grobj); - break; - default: - fatal("NV3 (nv3_pgraph_arbitrate_method): Attempted to execute method on invalid, or unimplemented, class ID %s", nv3_class_names[class_id]); - return; - } - } - - nv3_notify_if_needed(param, method, context, grobj); -} - -/* Arbitrates graphics object submission to the right object types */ -void nv3_pgraph_submit(uint32_t param, uint16_t method, uint8_t channel, uint8_t subchannel, uint8_t class_id, nv3_ramin_context_t context) -{ - // class id can be derived from the context but we debug log it before we get here - // Do we need to read grobj here? - - switch (method) - { - default: - // Object Method arbitration - nv3_pgraph_arbitrate_method(param, method, channel, subchannel, class_id, context); - break; - } -} \ 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 deleted file mode 100644 index b6528fe0a..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pmc.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PMC - Master control for the chip - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_pmc_init(void) -{ - nv_log("Initialising PMC....\n"); - - if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_A00) - nv3->pmc.boot = NV3_BOOT_REG_REV_A00; - else if (nv3->nvbase.gpu_revision == NV3_PCI_CFG_REVISION_B00) - nv3->pmc.boot = NV3_BOOT_REG_REV_B00; - else - nv3->pmc.boot = NV3_BOOT_REG_REV_C00; - - nv3->pmc.interrupt_enable = NV3_PMC_INTERRUPT_ENABLE_HARDWARE | NV3_PMC_INTERRUPT_ENABLE_SOFTWARE; - - nv_log("Initialising PMC: Done\n"); -} - -// -// ****** PMC register list START ****** -// - -nv_register_t pmc_registers[] = { - { NV3_PMC_BOOT, "PMC: Boot Manufacturing Information", NULL, NULL }, - { NV3_PMC_INTERRUPT_STATUS, "PMC: Current Pending Subsystem Interrupts", NULL, NULL}, - { NV3_PMC_INTERRUPT_ENABLE, "PMC: Global Interrupt Enable", NULL, NULL,}, - { NV3_PMC_ENABLE, "PMC: Global Subsystem Enable", NULL, NULL }, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -void nv3_pmc_clear_interrupts(void) -{ - nv_log_verbose_only("Clearing IRQs\n"); - pci_clear_irq(nv3->nvbase.pci_slot, PCI_INTA, &nv3->nvbase.pci_irq_state); -} - -// Handle hardware interrupts -// We only clear when we need to, in other functions... -uint32_t nv3_pmc_handle_interrupts(bool send_now) -{ - // TODO: - // PGRAPH DMA INTR_EN (there is no DMA engine yet) - // PRM Real-Mode Compatibility Interrupts - - uint32_t new_intr_value = 0x00; - - // set the new interrupt value - // PAUDIO not used - // IF NV3 REV A EMULATION IS ADDED, ADD THIS COMPONENT! - - // the registers are designed to line up so you can enable specific interrupts - - // Check Mediaport interrupts - if (nv3->pme.interrupt_status & nv3->pme.interrupt_enable) - new_intr_value |= (NV3_PMC_INTERRUPT_PMEDIA_PENDING << NV3_PMC_INTERRUPT_PMEDIA); - - // Check FIFO interrupts - if (nv3->pfifo.interrupt_status & nv3->pfifo.interrupt_enable) - new_intr_value |= (NV3_PMC_INTERRUPT_PFIFO_PENDING << NV3_PMC_INTERRUPT_PFIFO); - - // PFB interrupt is VBLANK PGRAPH interrupt...what nvidia... - if (nv3->pgraph.interrupt_status_0 & (1 << 8) - && nv3->pgraph.interrupt_enable_0 & (1 << 8)) - new_intr_value |= (NV3_PMC_INTERRUPT_PFB_PENDING << NV3_PMC_INTERRUPT_PFB); - - if (nv3->pgraph.interrupt_status_0 & ~(1 << 8) - && nv3->pgraph.interrupt_enable_0 & ~(1 << 8)) // otherwise PGRAPH-0 interurpt - new_intr_value |= (NV3_PMC_INTERRUPT_PGRAPH0_PENDING << NV3_PMC_INTERRUPT_PGRAPH0); - - // Check second pgraph interrupt register - if (nv3->pgraph.interrupt_status_1 & nv3->pgraph.interrupt_enable_1) - new_intr_value |= (NV3_PMC_INTERRUPT_PGRAPH1_PENDING << NV3_PMC_INTERRUPT_PGRAPH1); - - // check video overlay interrupts - if (nv3->pvideo.interrupt_status & nv3->pvideo.interrupt_enable) - new_intr_value |= (NV3_PMC_INTERRUPT_PVIDEO_PENDING << NV3_PMC_INTERRUPT_PVIDEO); - - // check PIT interrupts - if (nv3->ptimer.interrupt_status & nv3->ptimer.interrupt_enable) - new_intr_value |= (NV3_PMC_INTERRUPT_PTIMER_PENDING << NV3_PMC_INTERRUPT_PTIMER); - - // check bus interrupts - if (nv3->pbus.interrupt_status & nv3->pbus.interrupt_enable) - new_intr_value |= (NV3_PMC_INTERRUPT_PBUS_PENDING << NV3_PMC_INTERRUPT_PBUS); - - // check SW interrupts - if (nv3->pmc.interrupt_status & (1 << NV3_PMC_INTERRUPT_SOFTWARE)) - new_intr_value |= (NV3_PMC_INTERRUPT_SOFTWARE_PENDING << NV3_PMC_INTERRUPT_SOFTWARE); - - nv3->pmc.interrupt_status = new_intr_value; - - // ***TODO: DOes INTR still change if INTR_EN=0???*** - // If interrupts are disabled don't bother - - if (!nv3->pmc.interrupt_enable) - { - nv3_pmc_clear_interrupts(); - return nv3->pmc.interrupt_status; - } - - - // if we actually need to send the interrupt (i.e. this is a write) send it now - if (send_now) - { - // no interrupts to send - if (!(nv3->pmc.interrupt_status) - || !(nv3->pmc.interrupt_status - 0x80000000)) - { - nv3_pmc_clear_interrupts(); - return nv3->pmc.interrupt_status; - } - - if ((nv3->pmc.interrupt_status & 0x7FFFFFFF)) - { - if (nv3->pmc.interrupt_enable & NV3_PMC_INTERRUPT_ENABLE_HARDWARE) - { - nv_log_verbose_only("Firing hardware-originated interrupt NV3_PMC_INTR_0=0x%08x\n", nv3->pmc.interrupt_status); - pci_set_irq(nv3->nvbase.pci_slot, PCI_INTA, &nv3->nvbase.pci_irq_state); - } - else - nv_log_verbose_only("NOT firing hardware-originated interrupt NV3_PMC_INTR_0=0x%08x, BECAUSE HARDWARE INTERRUPTS ARE DISABLED\n", nv3->pmc.interrupt_status); - } - else - { - if (nv3->pmc.interrupt_enable & NV3_PMC_INTERRUPT_ENABLE_SOFTWARE) - { - nv_log_verbose_only("Firing software-originated interrupt NV3_PMC_INTR_0=0x%08x\n", nv3->pmc.interrupt_status); - pci_set_irq(nv3->nvbase.pci_slot, PCI_INTA, &nv3->nvbase.pci_irq_state); - } - else - nv_log_verbose_only("NOT firing software-originated interrupt NV3_PMC_INTR_0=0x%08x, BECAUSE SOFTWARE INTERRUPTS ARE DISABLED\n", nv3->pmc.interrupt_status); - } - } - - return nv3->pmc.interrupt_status; -} - - - -// -// ****** Read/Write functions start ****** -// - -uint32_t nv3_pmc_read(uint32_t address) -{ - nv_register_t* reg = nv_get_register(address, pmc_registers, sizeof(pmc_registers)/sizeof(pmc_registers[0])); - - uint32_t ret = 0x00; - - // todo: friendly logging - nv_log_verbose_only("PMC Read from 0x%08x", address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - switch (reg->address) - { - case NV3_PMC_BOOT: - ret = nv3->pmc.boot; - break; - case NV3_PMC_INTERRUPT_STATUS: - nv_log_verbose_only("\n"); // clear_interrupts logs - nv3_pmc_clear_interrupts(); - - ret = nv3_pmc_handle_interrupts(false); - break; - case NV3_PMC_INTERRUPT_ENABLE: - //TODO: ACTUALLY CHANGE THE INTERRUPT STATE - ret = nv3->pmc.interrupt_enable; - break; - case NV3_PMC_ENABLE: - ret = nv3->pmc.enable; - break; - - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pmc_write(uint32_t address, uint32_t value) -{ - nv_register_t* reg = nv_get_register(address, pmc_registers, sizeof(pmc_registers)/sizeof(pmc_registers[0])); - - nv_log_verbose_only("PMC Write 0x%08x -> 0x%08x", value, address); - - // if the register actually exists... - if (reg) - { - - // ... call its on-write function - if (reg->on_write) - reg->on_write(value); - else - { - // if it doesn't have one fallback to a switch statement - switch (reg->address) - { - case NV3_PMC_INTERRUPT_STATUS: - // This can only be done by software interrupts... - if (!(nv3->pmc.interrupt_status & 0x7FFFFFFF)) - { - warning("Huh? This is a hardware interrupt...Please use the INTR_EN registers of the GPU subsystem you want to trigger " - " an interrupt on, rather than writing to NV3_PMC_INTERRUPT_STATUS (Or this is a bug)...NV3_PMC_INTERRUPT_STATUS=0x%08x)\n", nv3->pmc.interrupt_enable); - return; - } - - nv3_pmc_handle_interrupts(true); - nv3->pmc.interrupt_status = value; - break; - case NV3_PMC_INTERRUPT_ENABLE: - nv3->pmc.interrupt_enable = value & 0x03; - nv3_pmc_handle_interrupts(value != 0); - break; - case NV3_PMC_ENABLE: - nv3->pmc.enable = value; - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pme.c b/src/video/nv/nv3/subsystems/nv3_pme.c deleted file mode 100644 index 1f0da2aac..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pme.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 pme: Nvidia Mediaport - External MPEG Decode Interface - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -nv_register_t pme_registers[] = { - { NV3_PME_INTR, "PME - Interrupt Status", NULL, NULL}, - { NV3_PME_INTR_EN, "PME - Interrupt Enable", NULL, NULL,}, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -void nv3_pme_init(void) -{ - nv_log("Initialising PME..."); - - nv_log("Done\n"); -} - -uint32_t nv3_pme_read(uint32_t address) -{ - nv_register_t* reg = nv_get_register(address, pme_registers, sizeof(pme_registers)/sizeof(pme_registers[0])); - - uint32_t ret = 0x00; - - // todo: friendly logging - - nv_log_verbose_only("PME Read from 0x%08x", address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - // Interrupt state: - // Bit 0 - Image Notifier - // Bit 4 - Vertical Blank Interval Notifier - // Bit 8 - Video Notifier - // Bit 12 - Audio Notifier - // Bit 16 - VMI Notifer - switch (reg->address) - { - case NV3_PME_INTR: - ret = nv3->pme.interrupt_status; - break; - case NV3_PME_INTR_EN: - ret = nv3->pme.interrupt_enable; - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pme_write(uint32_t address, uint32_t value) -{ - nv_register_t* reg = nv_get_register(address, pme_registers, sizeof(pme_registers)/sizeof(pme_registers[0])); - - nv_log_verbose_only("PME Write 0x%08x -> 0x%08x\n", value, address); - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - switch (reg->address) - { - // Interrupt state: - // Bit 0 - Image Notifier - // Bit 4 - Vertical Blank Interfal Notifier - // Bit 8 - Video Notifier - // Bit 12 - Audio Notifier - // Bit 16 - VMI Notifer - - case NV3_PME_INTR: - nv3->pme.interrupt_status &= ~value; - nv3_pmc_clear_interrupts(); - break; - case NV3_PME_INTR_EN: - nv3->pme.interrupt_enable = value & 0x00001111; - break; - } - } - - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } - -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c deleted file mode 100644 index 9ce5a189a..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 bringup and device emulation. - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -// nv3_pramdac.c: NV3 RAMDAC -// Todo: Allow overridability using 68050C register... - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -void nv3_pramdac_init(void) -{ - nv_log("Initialising PRAMDAC\n"); - - // defaults, these come from vbios in reality - // driver defaults are nonsensical(?), or the algorithm is wrong - // munged this to 100mhz for now - nv3->pramdac.memory_clock_m = nv3->pramdac.pixel_clock_m = 0x07; - nv3->pramdac.memory_clock_n = nv3->pramdac.pixel_clock_n = 0xc8; - nv3->pramdac.memory_clock_p = nv3->pramdac.pixel_clock_p = 0x0c; - - nv3_pramdac_set_pixel_clock(); - nv3_pramdac_set_vram_clock(); - - nv_log("Initialising PRAMDAC: Done\n"); -} - -// Polls the pixel clock. -void nv3_pramdac_pixel_clock_poll(double real_time) -{ - /* Ignore in VGA mode */ - if (!nv3->nvbase.svga.override) - return; - - /* Figure out our refresh time. */ - if (!nv3->nvbase.refresh_time) - nv3->nvbase.refresh_time = (1/60.0); // rivatimers count in microseconds but present the info as seconds - - nv3->nvbase.refresh_clock += real_time; - - if (nv3->nvbase.refresh_clock > nv3->nvbase.refresh_time) - { - /* Update the screen because something changed */ - nv3_render_current_bpp(); - video_blit_memtoscreen(0, 0, xsize, ysize); - nv3->nvbase.refresh_clock = 0; - } - - // TODO: ???? -} - -// Polls the memory clock. -// This updates the 2D/3D engine PGRAPH, PTIMER and more -void nv3_pramdac_memory_clock_poll(double real_time) -{ - nv3_ptimer_tick(real_time); - - nv3_pfifo_cache0_pull(); - nv3_pfifo_cache1_pull(); - // TODO: UPDATE PGRAPH! -} - -// Gets the vram clock register. -uint32_t nv3_pramdac_get_vram_clock_register(void) -{ - // the clock format is packed into 19 bits - // M divisor [7-0] - // N divisor [16-8] - // P divisor [18-16] - return (nv3->pramdac.memory_clock_m) - + (nv3->pramdac.memory_clock_n << 8) - + (nv3->pramdac.memory_clock_p << 16); // 0-3 -} - -uint32_t nv3_pramdac_get_pixel_clock_register(void) -{ - return (nv3->pramdac.pixel_clock_m) - + (nv3->pramdac.pixel_clock_n << 8) - + (nv3->pramdac.pixel_clock_p << 16); // 0-3 -} - -void nv3_pramdac_set_vram_clock_register(uint32_t value) -{ - nv3->pramdac.memory_clock_m = value & 0xFF; - nv3->pramdac.memory_clock_n = (value >> 8) & 0xFF; - nv3->pramdac.memory_clock_p = (value >> 16) & 0x07; - - nv3_pramdac_set_vram_clock(); -} - -void nv3_pramdac_set_pixel_clock_register(uint32_t value) -{ - nv3->pramdac.pixel_clock_m = value & 0xFF; - nv3->pramdac.pixel_clock_n = (value >> 8) & 0xFF; - nv3->pramdac.pixel_clock_p = (value >> 16) & 0x07; - - nv3_pramdac_set_pixel_clock(); -} - -void nv3_pramdac_set_vram_clock(void) -{ - // from driver and vbios source - float frequency = 13500000.0f; - - // prevent division by 0 - if (nv3->pramdac.memory_clock_m == 0) - nv3->pramdac.memory_clock_m = 1; - - if (nv3->pramdac.memory_clock_n == 0) - nv3->pramdac.memory_clock_n = 1; - - // Convert to microseconds - frequency = (frequency * nv3->pramdac.memory_clock_n) / (nv3->pramdac.memory_clock_m << nv3->pramdac.memory_clock_p); - - double time = 1000000.0 / (double)frequency; // needs to be a double for 86box - - nv_log("Memory clock = %.2f MHz\n", frequency / 1000000.0f); - - nv3->nvbase.memory_clock_frequency = frequency; - - // Create and start if it it's not running. - if (!nv3->nvbase.memory_clock_timer) - { - nv3->nvbase.memory_clock_timer = rivatimer_create(time, nv3_pramdac_memory_clock_poll); - rivatimer_start(nv3->nvbase.memory_clock_timer); - } - - rivatimer_set_period(nv3->nvbase.memory_clock_timer, time); -} - -void nv3_pramdac_set_pixel_clock(void) -{ - // frequency divider algorithm from old varcem/86box/pcbox riva driver, - // verified by reversing NT drivers v1.50e CalcMNP [symbols] function - - // missing section - // not really needed. - // if (nv3->pfb.boot.clock_crystal == CLOCK_CRYSTAL_13500) - // { - // freq = 13500000.0f; - // } - // else - // - // { - // freq = 14318000.0f; - // } - - float frequency = 13500000.0f; - - // prevent division by 0 - if (nv3->pramdac.pixel_clock_m == 0) - nv3->pramdac.pixel_clock_m = 1; - - if (nv3->pramdac.memory_clock_n == 0) - nv3->pramdac.memory_clock_n = 1; - - frequency = (frequency * nv3->pramdac.pixel_clock_n) / (nv3->pramdac.pixel_clock_m << nv3->pramdac.pixel_clock_p); - - nv3->nvbase.svga.clock = cpuclock / frequency; - - double time = 1000000.0 / (double)frequency; // needs to be a double for 86box - - nv_log("Pixel clock = %.2f MHz\n", frequency / 1000000.0f); - - nv3->nvbase.pixel_clock_frequency = frequency; - - // Create and start if it it's not running. - if (!nv3->nvbase.pixel_clock_timer) - { - nv3->nvbase.pixel_clock_timer = rivatimer_create(time, nv3_pramdac_pixel_clock_poll); - rivatimer_start(nv3->nvbase.pixel_clock_timer); - } - - rivatimer_set_period(nv3->nvbase.pixel_clock_timer, time); -} - -// -// ****** PRAMDAC register list START ****** -// - -// NULL means handle in read functions -nv_register_t pramdac_registers[] = -{ - { NV3_PRAMDAC_CURSOR_START, "PRAMDAC - Cursor Start Position"}, - { NV3_PRAMDAC_CLOCK_PIXEL, "PRAMDAC - NV3 GPU Core - Pixel clock", nv3_pramdac_get_pixel_clock_register, nv3_pramdac_set_pixel_clock_register }, - { NV3_PRAMDAC_CLOCK_MEMORY, "PRAMDAC - NV3 GPU Core - Memory clock", nv3_pramdac_get_vram_clock_register, nv3_pramdac_set_vram_clock_register }, - { NV3_PRAMDAC_COEFF_SELECT, "PRAMDAC - PLL Clock Coefficient Select", NULL, NULL}, - { NV3_PRAMDAC_GENERAL_CONTROL, "PRAMDAC - General Control", NULL, NULL }, - { NV3_PRAMDAC_VSERR_WIDTH, "PRAMDAC - Vertical Sync Error Width", NULL, NULL}, - { NV3_PRAMDAC_VEQU_END, "PRAMDAC - VEqu End", NULL, NULL}, - { NV3_PRAMDAC_VBBLANK_START, "PRAMDAC - VBBlank Start", NULL, NULL}, - { NV3_PRAMDAC_VBBLANK_END, "PRAMDAC - VBBlank End", NULL, NULL}, - { NV3_PRAMDAC_HBLANK_END, "PRAMDAC - Horizontal Blanking Interval End", NULL, NULL}, - { NV3_PRAMDAC_HBLANK_START, "PRAMDAC - Horizontal Blanking Interval Start", NULL, NULL}, - { NV3_PRAMDAC_VBLANK_END, "PRAMDAC - Vertical Blanking Interval End", NULL, NULL}, - { NV3_PRAMDAC_VBLANK_START, "PRAMDAC - Vertical Blanking Interval Start", NULL, NULL}, - { NV3_PRAMDAC_VEQU_START, "PRAMDAC - VEqu Start", NULL, NULL}, - { NV3_PRAMDAC_VTOTAL, "PRAMDAC - Total Vertical Lines", NULL, NULL}, - { NV3_PRAMDAC_HSYNC_WIDTH, "PRAMDAC - Horizontal Sync Pulse Width", NULL, NULL}, - { NV3_PRAMDAC_HBURST_START, "PRAMDAC - Horizontal Burst Signal Start", NULL, NULL}, - { NV3_PRAMDAC_HBURST_END, "PRAMDAC - Horizontal Burst Signal Start", NULL, NULL}, - { NV3_PRAMDAC_HTOTAL, "PRAMDAC - Total Horizontal Lines", NULL, NULL}, - { NV3_PRAMDAC_HEQU_WIDTH, "PRAMDAC - HEqu End", NULL, NULL}, - { NV3_PRAMDAC_HSERR_WIDTH, "PRAMDAC - Horizontal Sync Error", NULL, NULL}, - { NV3_USER_DAC_PIXEL_MASK, "PRAMDAC - User DAC Pixel Mask", NULL, NULL}, - { NV3_USER_DAC_READ_MODE_ADDRESS, "PRAMDAC - User DAC Read Mode Address", NULL, NULL}, - { NV3_USER_DAC_WRITE_MODE_ADDRESS, "PRAMDAC - User DAC Write Mode Address", NULL, NULL}, - { NV3_USER_DAC_PALETTE_DATA, "PRAMDAC - User DAC Palette Data", NULL, NULL}, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -// -// ****** Read/Write functions start ****** -// - -uint32_t nv3_pramdac_read(uint32_t address) -{ - nv_register_t* reg = nv_get_register(address, pramdac_registers, sizeof(pramdac_registers)/sizeof(pramdac_registers[0])); - - uint32_t ret = 0x00; - - // todo: friendly logging - - nv_log_verbose_only("PRAMDAC Read from 0x%08x\n", address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - //s hould be pretty easy to understand - switch (reg->address) - { - case NV3_PRAMDAC_COEFF_SELECT: - ret = nv3->pramdac.coeff_select; - break; - case NV3_PRAMDAC_GENERAL_CONTROL: - ret = nv3->pramdac.general_control; - break; - case NV3_PRAMDAC_VSERR_WIDTH: - ret = nv3->pramdac.vserr_width; - break; - case NV3_PRAMDAC_VBBLANK_END: - ret = nv3->pramdac.vbblank_end; - break; - case NV3_PRAMDAC_VBLANK_END: - ret = nv3->pramdac.vblank_end; - break; - case NV3_PRAMDAC_VBLANK_START: - ret = nv3->pramdac.vblank_start; - break; - case NV3_PRAMDAC_VEQU_START: - ret = nv3->pramdac.vequ_start; - break; - case NV3_PRAMDAC_VTOTAL: - ret = nv3->pramdac.vtotal; - break; - case NV3_PRAMDAC_HSYNC_WIDTH: - ret = nv3->pramdac.hsync_width; - break; - case NV3_PRAMDAC_HBURST_START: - ret = nv3->pramdac.hburst_start; - break; - case NV3_PRAMDAC_HBURST_END: - ret = nv3->pramdac.hburst_end; - break; - case NV3_PRAMDAC_HBLANK_START: - ret = nv3->pramdac.hblank_start; - break; - case NV3_PRAMDAC_HBLANK_END: - ret = nv3->pramdac.hblank_end; - break; - case NV3_PRAMDAC_HTOTAL: - ret = nv3->pramdac.htotal; - break; - case NV3_PRAMDAC_HEQU_WIDTH: - ret = nv3->pramdac.hequ_width; - break; - case NV3_PRAMDAC_HSERR_WIDTH: - ret = nv3->pramdac.hserr_width; - break; - case NV3_USER_DAC_PIXEL_MASK: - ret = nv3->pramdac.user_pixel_mask; - break; - case NV3_USER_DAC_READ_MODE_ADDRESS: - ret = nv3->pramdac.user_read_mode_address; - break; - case NV3_USER_DAC_WRITE_MODE_ADDRESS: - ret = nv3->pramdac.user_write_mode_address; - break; - case NV3_USER_DAC_PALETTE_DATA: - /* I doubt NV actually read this in their drivers, but it's worth doing anyway */ - /* Bit 1 is listed as "read or write mode" and 7:0 as "Write-only address", but NV only ever set this to 0 too, so i think this should be fine for now */ - ret = nv3->pramdac.palette[nv3->pramdac.user_read_mode_address]; - nv3->pramdac.user_read_mode_address++; - break; - case NV3_PRAMDAC_CURSOR_START: - ret = (nv3->pramdac.cursor_start.y << 16) | nv3->pramdac.cursor_start.x; - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pramdac_write(uint32_t address, uint32_t value) -{ - nv_register_t* reg = nv_get_register(address, pramdac_registers, sizeof(pramdac_registers)/sizeof(pramdac_registers[0])); - - nv_log_verbose_only("PRAMDAC Write 0x%08x -> 0x%08x\n", value, address); - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - //s hould be pretty easy to understand - // we also update the SVGA state here - switch (reg->address) - { - case NV3_PRAMDAC_COEFF_SELECT: - nv3->pramdac.coeff_select = value; - break; - case NV3_PRAMDAC_GENERAL_CONTROL: - nv3->pramdac.general_control = value; - nv3_recalc_timings(&nv3->nvbase.svga); - break; - case NV3_PRAMDAC_VSERR_WIDTH: - //vslines? - nv3->pramdac.vserr_width = value; - break; - case NV3_PRAMDAC_VBBLANK_END: - nv3->pramdac.vbblank_end = value; - break; - case NV3_PRAMDAC_VBLANK_END: - nv3->pramdac.vblank_end = value; - break; - case NV3_PRAMDAC_VBLANK_START: - //nv3->nvbase.svga.vblankstart = value; - nv3->pramdac.vblank_start = value; - break; - case NV3_PRAMDAC_VEQU_START: - nv3->pramdac.vequ_start = value; - break; - case NV3_PRAMDAC_VTOTAL: - //nv3->pramdac.vtotal = value; - nv3->nvbase.svga.vtotal = value; - break; - case NV3_PRAMDAC_HSYNC_WIDTH: - nv3->pramdac.hsync_width = value; - break; - case NV3_PRAMDAC_HBURST_START: - nv3->pramdac.hburst_start = value; - break; - case NV3_PRAMDAC_HBURST_END: - nv3->pramdac.hburst_end = value; - break; - case NV3_PRAMDAC_HBLANK_START: - //nv3->nvbase.svga.hblankstart = value; - nv3->pramdac.hblank_start = value; - break; - case NV3_PRAMDAC_HBLANK_END: - //nv3->nvbase.svga.hblank_end_val = value; - nv3->pramdac.hblank_end = value; - break; - case NV3_PRAMDAC_HTOTAL: - nv3->pramdac.htotal = value; - //nv3->nvbase.svga.htotal = value; - break; - case NV3_PRAMDAC_HEQU_WIDTH: - nv3->pramdac.hequ_width = value; - break; - case NV3_PRAMDAC_HSERR_WIDTH: - nv3->pramdac.hserr_width = value; - break; - case NV3_USER_DAC_PIXEL_MASK: - nv3->pramdac.user_pixel_mask = value; - break; - case NV3_USER_DAC_READ_MODE_ADDRESS: - nv3->pramdac.user_read_mode_address = value; - break; - case NV3_USER_DAC_WRITE_MODE_ADDRESS: - /* - This seems to get reset to 0 after 256 writes, but, the palette is 768 bytes in size. - Clearly there's some mechanism here, but I'm not sure what it is. So let's just reset if we reach 768. - */ - if (nv3->pramdac.user_write_mode_address >= NV3_USER_DAC_PALETTE_SIZE) - nv3->pramdac.user_write_mode_address = value; - - break; - case NV3_USER_DAC_PALETTE_DATA: - /* I doubt NV actually read this in their drivers, but it's worth doing anyway */ - /* Bit 1 is listed as "read or write mode" and 7:0 as "Write-only address", but NV only ever set this to 0 too, so i think this should be fine for now */ - nv3->pramdac.palette[nv3->pramdac.user_write_mode_address] = value; - - nv3->pramdac.user_write_mode_address++; - - break; - /* cursor start location */ - case NV3_PRAMDAC_CURSOR_START: - // only 12 bits are used here instead of 16 for some stupid reason - nv3->pramdac.cursor_start.y = (value >> 16) & 0xFFF; - nv3->pramdac.cursor_start.x = (value) & 0xFFF; - nv3_draw_cursor(&nv3->nvbase.svga, 0);//drawline doesn't matter here - break; - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} - diff --git a/src/video/nv/nv3/subsystems/nv3_pramin.c b/src/video/nv/nv3/subsystems/nv3_pramin.c deleted file mode 100644 index 77e2d1a6a..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pramin.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PRAMIN - Basically, this is how we know what to render. - * Has a giant hashtable of all the submitted DMA objects using a pseudo-C++ class system - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> -#include <86box/nv/classes/vid_nv3_classes.h> - -// Functions only used in this translation unit -#ifndef RELEASE_BUILD -void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context); -#endif - -// i believe the main loop is to walk the hashtable in RAMIN (last 0.5 MB of VRAM), -// find the objects that were submitted from DMA -// (going from software -> nvidia d3d / ogl implementation -> resource manager client -> nvapi -> nvrm -> GPU PFIFO -> GPU PBUS -> GPU PFB RAMIN -> PGRAPH) -// and then rendering each of those using PGRAPH - -// Notes for all of these functions: -// Structures in RAMIN are stored from the bottom of vram up in reverse order -// this can be explained without bitwise math like so: -// real VRAM address = VRAM_size - (ramin_address - (ramin_address % reversal_unit_size)) - reversal_unit_size + (ramin_address % reversal_unit_size) -// reversal unit size in this case is 16 bytes, vram size is 2-8mb (but 8mb is zx/nv3t only and 2mb...i haven't found a 22mb card) - -// Read 8-bit ramin -uint8_t nv3_ramin_read8(uint32_t addr, void* priv) -{ - if (!nv3) return 0x00; - - addr &= (nv3->nvbase.svga.vram_max - 1); - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv3->nvbase.svga.vram_max - 0x10); - - uint32_t val = 0x00; - - if (!nv3_ramin_arbitrate_read(addr, &val)) // Oh well - { - val = (uint8_t)nv3->nvbase.svga.vram[addr]; - nv_log_verbose_only("Read byte from PRAMIN addr=0x%08x (raw address=0x%08x)\n", addr, raw_addr); - } - - return (uint8_t)val; -} - -// Read 16-bit ramin -uint16_t nv3_ramin_read16(uint32_t addr, void* priv) -{ - if (!nv3) return 0x00; - - addr &= (nv3->nvbase.svga.vram_max - 1); - - // why does this not work in one line - svga_t* svga = &nv3->nvbase.svga; - uint16_t* vram_16bit = (uint16_t*)svga->vram; - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv3->nvbase.svga.vram_max - 0x10); - addr >>= 1; // what - - uint32_t val = 0x00; - - if (!nv3_ramin_arbitrate_read(addr, &val)) - { - val = (uint16_t)vram_16bit[addr]; - nv_log_verbose_only("Read word from PRAMIN addr=0x%08x (raw address=0x%08x)\n", addr, raw_addr); - } - - return val; -} - -// Read 32-bit ramin -uint32_t nv3_ramin_read32(uint32_t addr, void* priv) -{ - if (!nv3) - return 0x00; - - addr &= (nv3->nvbase.svga.vram_max - 1); - - // why does this not work in one line - uint32_t* vram_32bit = (uint32_t*)nv3->nvbase.svga.vram; - uint32_t raw_addr = addr; // saved after and logged - - addr ^= (nv3->nvbase.svga.vram_max - 0x10); - addr >>= 2; // what - - uint32_t val = 0x00; - - if (!nv3_ramin_arbitrate_read(addr, &val)) - { - val = vram_32bit[addr]; - - nv_log_verbose_only("Read dword from PRAMIN 0x%08x <- 0x%08x (raw address=0x%08x)\n", val, addr, raw_addr); - } - - return val; -} - -// Write 8-bit ramin -void nv3_ramin_write8(uint32_t addr, uint8_t val, void* priv) -{ - if (!nv3) return; - - addr &= (nv3->nvbase.svga.vram_max - 1); - uint32_t raw_addr = addr; // saved after and - - // Structures in RAMIN are stored from the bottom of vram up in reverse order - // this can be explained without bitwise math like so: - // real VRAM address = VRAM_size - (ramin_address - (ramin_address % reversal_unit_size)) - reversal_unit_size + (ramin_address % reversal_unit_size) - // reversal unit size in this case is 16 bytes, vram size is 2-8mb (but 8mb is zx/nv3t only and 2mb...i haven't found a 22mb card) - addr ^= (nv3->nvbase.svga.vram_max - 0x10); - - uint32_t val32 = (uint32_t)val; - - if (!nv3_ramin_arbitrate_write(addr, val32)) - { - nv3->nvbase.svga.vram[addr] = val; - nv_log_verbose_only("Write byte to PRAMIN addr=0x%08x val=0x%02x (raw address=0x%08x)\n", addr, val, raw_addr); - } - - -} - -// Write 16-bit ramin -void nv3_ramin_write16(uint32_t addr, uint16_t val, void* priv) -{ - if (!nv3) return; - - addr &= (nv3->nvbase.svga.vram_max - 1); - - // why does this not work in one line - svga_t* svga = &nv3->nvbase.svga; - uint16_t* vram_16bit = (uint16_t*)svga->vram; - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv3->nvbase.svga.vram_max - 0x10); - addr >>= 1; // what - - uint32_t val32 = (uint32_t)val; - - if (!nv3_ramin_arbitrate_write(addr, val32)) - { - vram_16bit[addr] = val; - nv_log_verbose_only("Write word to PRAMIN addr=0x%08x val=0x%04x (raw address=0x%08x)\n", addr, val, raw_addr); - } - - -} - -// Write 32-bit ramin -void nv3_ramin_write32(uint32_t addr, uint32_t val, void* priv) -{ - if (!nv3) return; - - addr &= (nv3->nvbase.svga.vram_max - 1); - - // why does this not work in one line - svga_t* svga = &nv3->nvbase.svga; - uint32_t* vram_32bit = (uint32_t*)svga->vram; - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv3->nvbase.svga.vram_max - 0x10); - addr >>= 2; // what - - if (!nv3_ramin_arbitrate_write(addr, val)) - { - vram_32bit[addr] = val; - nv_log_verbose_only("Write dword to PRAMIN addr=0x%08x val=0x%08x (raw address=0x%08x)\n", addr, val, raw_addr); - } - -} - -void nv3_pfifo_interrupt(uint32_t id, bool fire_now) -{ - nv3->pfifo.interrupt_status |= (1 << id); - nv3_pmc_handle_interrupts(fire_now); -} - -/* -RAMIN access arbitration functions -Arbitrates reads and writes to RAMFC (unused dma context storage), RAMRO (invalid object submission location), RAMHT (hashtable for graphics objectstorage) unused audio memory (RAMAU?) -and generic RAMIN - -Takes a pointer to a result integer. This is because we need to check its result in our normal write function. -Returns true if a valid "non-generic" address was found (e.g. RAMFC/RAMRO/RAMHT). False if the specified address is a generic RAMIN address -*/ -bool nv3_ramin_arbitrate_read(uint32_t address, uint32_t* value) -{ - if (!nv3) return 0x00; - - uint32_t ramht_size = ((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_SIZE) & 0x03); - uint32_t ramro_size = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); - - // Get the addresses of RAMHT, RAMFC, RAMRO - // They must be within first 64KB of PRAMIN! - uint32_t ramht_start = ((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS) & 0x0F) << 12; // Must be 0x1000 aligned - uint32_t ramfc_start = ((nv3->pfifo.ramfc_config >> NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS) & 0x7F) << 9; // Must be 0x200 aligned - uint32_t ramro_start = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS) & 0x7F) << 9; // Must be 0x200 aligned - - // Calculate the RAMHT and RAMRO end points. - // (RAMFC is always 0x1000 bytes on NV3.) - uint32_t ramht_end = ramht_start; - uint32_t ramfc_end = ramfc_start + 0x1000; - uint32_t ramro_end = ramro_start; - - switch (ramht_size) - { - case NV3_PFIFO_CONFIG_RAMHT_SIZE_4K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_0; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_8K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_1; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_16K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_2; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_32K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_3; - break; - } - - switch (ramro_size) - { - case NV3_PFIFO_CONFIG_RAMRO_SIZE_512B: - ramro_end = ramro_start + NV3_RAMIN_RAMRO_SIZE_0; - break; - case NV3_PFIFO_CONFIG_RAMRO_SIZE_8K: - ramro_end = ramro_start + NV3_RAMIN_RAMRO_SIZE_1; - break; - } - - if (address >= ramht_start - && address <= ramht_end) - { - *value = nv3_ramht_read(address); - return true; - } - else if (address >= ramfc_start - && address <= ramfc_end) - { - *value = nv3_ramfc_read(address); - return true; - } - else if (address >= ramro_start - && address <= ramro_end) - { - *value = nv3_ramro_read(address); - return true; - } - - /* temp */ - return false; -} - -bool nv3_ramin_arbitrate_write(uint32_t address, uint32_t value) -{ - if (!nv3) return 0x00; - - uint32_t ramht_size = ((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_SIZE) & 0x03); - uint32_t ramro_size = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_SIZE) & 0x01); - - // Get the addresses of RAMHT, RAMFC, RAMRO - // They must be within first 64KB of PRAMIN! - uint32_t ramht_start = ((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS) & 0x0F) << 12; // Must be 0x1000 aligned - uint32_t ramfc_start = ((nv3->pfifo.ramfc_config >> NV3_PFIFO_CONFIG_RAMFC_BASE_ADDRESS) & 0x7F) << 9; // Must be 0x200 aligned - uint32_t ramro_start = ((nv3->pfifo.ramro_config >> NV3_PFIFO_CONFIG_RAMRO_BASE_ADDRESS) & 0x7F) << 9; // Must be 0x200 aligned - - // Calculate the RAMHT and RAMRO end points. - // (RAMFC is always 0x1000 bytes on NV3.) - uint32_t ramht_end = ramht_start; - uint32_t ramfc_end = ramfc_start + 0x1000; - uint32_t ramro_end = ramro_start; - - switch (ramht_size) - { - case NV3_PFIFO_CONFIG_RAMHT_SIZE_4K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_0; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_8K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_1; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_16K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_2; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_32K: - ramht_end = ramht_start + NV3_RAMIN_RAMHT_SIZE_3; - break; - } - - switch (ramro_size) - { - case NV3_PFIFO_CONFIG_RAMRO_SIZE_512B: - ramro_end = ramro_start + NV3_RAMIN_RAMRO_SIZE_0; - break; - case NV3_PFIFO_CONFIG_RAMRO_SIZE_8K: - ramro_end = ramro_start + NV3_RAMIN_RAMRO_SIZE_1; - break; - } - - // send the addresses to the right part - if (address >= ramht_start - && address <= ramht_end) - { - nv3_ramht_write(address, value); - return true; - } - else if (address >= ramfc_start - && address <= ramfc_end) - { - nv3_ramfc_write(address, value); - return true; - } - else if (address >= ramro_start - && address <= ramro_end) - { - nv3_ramro_write(address, value); - return true; - } - - return false; -} - -// THIS IS THE MOST IMPORTANT FUNCTION! -bool nv3_ramin_find_object(uint32_t name, uint32_t cache_num, uint8_t channel, uint8_t subchannel) -{ - // TODO: WRITE IT!!! - // Set the number of entries to search based on the ramht size (2*(size+1)) - // Not a switch statement in case newer gpus have larger ramins - - uint32_t bucket_entries = 2; - uint8_t ramht_size = (nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_SIZE) & 0x03; - - switch (ramht_size) - { - case NV3_PFIFO_CONFIG_RAMHT_SIZE_4K: - // stays as is - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_8K: - bucket_entries = 4; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_16K: - bucket_entries = 8; - break; - case NV3_PFIFO_CONFIG_RAMHT_SIZE_32K: - bucket_entries = 16; - break; - - } - - // Calculate the address in the hashtable - uint32_t ramht_base = ((nv3->pfifo.ramht_config >> NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS) & 0x0F) << NV3_PFIFO_CONFIG_RAMHT_BASE_ADDRESS; - - // This is certainly wrong. But the objects seem to be written to 4600? So I just multiply it by 80 to multiply the final address by 10. - // Why does this work? - uint32_t ramht_cur_address = ramht_base + (nv3_ramht_hash(name, channel) * bucket_entries * 8); - - nv_log_verbose_only("Beginning search for graphics object at RAMHT base=0x%04x, name=0x%08x, Cache%d, channel=%d.%d)\n", - ramht_cur_address, name, cache_num, channel, subchannel); - - bool found_object = false; - - // set up some variables - uint32_t found_obj_name = 0x00; - nv3_ramin_context_t obj_context_struct = {0}; - - for (uint32_t bucket_entry = 0; bucket_entry < bucket_entries; bucket_entry++) - { - found_obj_name = nv3_ramin_read32(ramht_cur_address, NULL); - ramht_cur_address += 0x04; - uint32_t obj_context = nv3_ramin_read32(ramht_cur_address, NULL); - ramht_cur_address += 0x04; - obj_context_struct = *(nv3_ramin_context_t*)&obj_context; - - // see if the object is in the right channel - if (found_obj_name == name - && obj_context_struct.channel == channel) - { - found_object = true; - break; - } - } - - if (!found_object) - { - if (!cache_num) - { - nv3->pfifo.debug_0 |= NV3_PFIFO_CACHE0_ERROR_PENDING; - nv3->pfifo.cache0_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_HASH_FAILURE; - //It turns itself off on failure, the drivers turn it back on - nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; - } - else - { - nv3->pfifo.debug_0 |= NV3_PFIFO_CACHE1_ERROR_PENDING; - nv3->pfifo.cache1_settings.pull0 |= NV3_PFIFO_CACHE1_PULL0_HASH_FAILURE; - //It turns itself off on failure, the drivers turn it back on - nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_ENABLED; - } - - nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true); - - return false; - } - - // So we did find an object. - // Now try to read some of this... - - // Class ID is 5 bits in all other parts of the gpu but 7 bits here. A move in a direction that didn't pan out? - // Represented as 0x40-0x5f? Some other meaning - - // Perform more validation - - if (obj_context_struct.class_id < NV3_PFIFO_FIRST_VALID_GRAPHICS_OBJECT_ID - || obj_context_struct.class_id > NV3_PFIFO_LAST_VALID_GRAPHICS_OBJECT_ID) - { - fatal("NV3: Invalid graphics object class ID name=0x%04x type=%04x, interpreted by pgraph as: %04x (Contact starfrost)", - name, obj_context_struct.class_id, obj_context_struct.class_id & 0x1F); - } - else if (obj_context_struct.channel > (NV3_DMA_CHANNELS - 1)) - fatal("NV3: Super fucked up graphics object. Contact starfrost with the error string: DMA Channel ID=%d, it should be 0-7", obj_context_struct.channel); - - // Illegal accesses sent to RAMRO, so ignore here - // TODO: SEND THESE TO RAMRO!!!!! - - #ifndef RELEASE_BUILD - nv3_debug_ramin_print_context_info(name, obj_context_struct); - #endif - - // By definition we can't have a cache error by here so take it off - if (!cache_num) - nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_HASH_FAILURE; - else - nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_HASH_FAILURE; - - // Caches store all the subchannels for our current dma channel and basically get stale every context switch - // Also we have to check that a osftware object didn't end up in here... - - bool is_software = false; - if (!cache_num) - is_software = (nv3->pfifo.cache0_settings.context[subchannel] & 0x800000); - else - is_software = (nv3->pfifo.cache1_settings.context[subchannel] & 0x800000); - - // This isn't an error but it's sent as an interrupt so the drivers can sync - if (is_software) - { - // handle it as an error - if (!cache_num) - { - nv3->pfifo.cache0_settings.pull0 |= NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_ENABLED; - } - else - { - nv3->pfifo.cache1_settings.pull0 |= NV3_PFIFO_CACHE1_PULL0_SOFTWARE_METHOD; - nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_ENABLED; - } - - // It's an error but it isn't lol - nv3_pfifo_interrupt(NV3_PFIFO_INTR_CACHE_ERROR, true); - - } - else - { - // obviously turn off the "is software" if it's not - if (!cache_num) - nv3->pfifo.cache0_settings.pull0 &= ~NV3_PFIFO_CACHE0_PULL0_SOFTWARE_METHOD; - else - nv3->pfifo.cache1_settings.pull0 &= ~NV3_PFIFO_CACHE1_PULL0_SOFTWARE_METHOD; - } - - // Ok we found it. Lol - return true; - -} - - -// Prints out some informaiton about the object -void nv3_debug_ramin_print_context_info(uint32_t name, nv3_ramin_context_t context) -{ - #ifndef RELEASE_BUILD - nv_log_verbose_only("Found object:\n"); - nv_log_verbose_only("Param: 0x%04x\n", name); - - nv_log_verbose_only("Context:\n"); - nv_log_verbose_only("DMA Channel %d (0-7 valid)\n", context.channel); - nv_log_verbose_only("Class ID: 0x%04x (%s)\n", context.class_id & 0x1F, nv3_class_names[context.class_id & 0x1F]); - nv_log_verbose_only("Render Engine %d (0=Software, also DMA? 1=Accelerated Renderer)\n", context.is_rendering); - nv_log_verbose_only("PRAMIN Offset 0x%08x\n", context.ramin_offset << 4); - #endif -} diff --git a/src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c b/src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c deleted file mode 100644 index 59fa41e8d..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pramin_ramfc.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PFIFO RAMFC area: Stores context for unused DMA channels - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -uint32_t nv3_ramfc_read(uint32_t address) -{ - nv_log_verbose_only("RAMFC (Unused DMA channel context) Read (0x%04x) (UNIMPLEMENTED returning 0x00)\n", address); - return 0x00; //temp -} - -void nv3_ramfc_write(uint32_t address, uint32_t value) -{ - nv_log_verbose_only("RAMFC (Unused DMA channel context) Write (0x%04x -> 0x%04x)\n", value, address); -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pramin_ramht.c b/src/video/nv/nv3/subsystems/nv3_pramin_ramht.c deleted file mode 100644 index 9f90b3434..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pramin_ramht.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PFIFO hashtable (Quickly access submitted DMA objects) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -/* This implements the hash that all the objects are stored within. -It is used to get the offset within RAMHT of a graphics object. - */ - -uint32_t nv3_ramht_hash(uint32_t name, uint32_t channel) -{ - // the official nvidia hash algorithm, tweaked for readability - uint32_t hash = ((name ^ (name >> 8) ^ (name >> 16) ^ (name >> 24)) & 0xFF) ^ (channel & NV3_DMA_CHANNELS_TOTAL); - - - // is this the right endianness? - nv_log_verbose_only("Generated RAMHT hash 0x%04x (RAMHT slot=0x%04x (from name 0x%08x for DMA channel 0x%04x)\n)\n", hash, (hash/8), name, channel); - return hash; -} - - -uint32_t nv3_ramht_read(uint32_t address) -{ - nv_log_verbose_only("RAMHT (Graphics object storage hashtable) Read (0x%04x), I DON'T BELIEVE THIS SHOULD EVER HAPPEN - RETURNING 0x00\n", address); - return 0x00; -} - -void nv3_ramht_write(uint32_t address, uint32_t value) -{ - nv_log_verbose_only("RAMHT (Graphics object storage hashtable) Write (0x%04x -> 0x%04x), I DON'T BELIEVE THIS SHOULD EVER HAPPEN - UNIMPLEMENTED\n", value, address); -} diff --git a/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c b/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c deleted file mode 100644 index 142d746d2..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pramin_ramro.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PFIFO ram runout area (you fucked up) - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - -uint32_t nv3_ramro_read(uint32_t address) -{ - nv_log("BIG Problem: RAM Runout (invalid dma object submission) Read (0x%04x)\n", address); - return 0x00; -} - -void nv3_ramro_write(uint32_t address, uint32_t value) -{ - nv_log("BIG Problem: RAM Runout WRITE, OH CRAP!!!! (0x%04x -> 0x%04x)", value, address); -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_ptimer.c b/src/video/nv/nv3/subsystems/nv3_ptimer.c deleted file mode 100644 index ab14be4f9..000000000 --- a/src/video/nv/nv3/subsystems/nv3_ptimer.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PTIMER - PIT emulation - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - - -nv_register_t ptimer_registers[] = { - { NV3_PTIMER_INTR, "PTIMER - Interrupt Status", NULL, NULL}, - { NV3_PTIMER_INTR_EN, "PTIMER - Interrupt Enable", NULL, NULL,}, - { NV3_PTIMER_NUMERATOR, "PTIMER - Numerator", NULL, NULL, }, - { NV3_PTIMER_DENOMINATOR, "PTIMER - Denominator", NULL, NULL, }, - { NV3_PTIMER_TIME_0_NSEC, "PTIMER - Time0", NULL, NULL, }, - { NV3_PTIMER_TIME_1_NSEC, "PTIMER - Time1", NULL, NULL, }, - { NV3_PTIMER_ALARM_NSEC, "PTIMER - Alarm", NULL, NULL, }, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -// ptimer init code -void nv3_ptimer_init(void) -{ - nv_log("Initialising PTIMER..."); - - nv_log("Done!\n"); -} - -// Handles the PTIMER alarm interrupt -void nv3_ptimer_interrupt(uint32_t num) -{ - nv3->ptimer.interrupt_status |= (1 << num); - - nv3_pmc_handle_interrupts(true); -} - -// Ticks the timer. -void nv3_ptimer_tick(double real_time) -{ - // prevent a divide by zero - if (nv3->ptimer.clock_numerator == 0 - || nv3->ptimer.clock_denominator == 0) - return; - - // get the current time - - // See Envytools. We need to use the frequency as a source. - // We need to figure out how many cycles actually occurred because this counts up every cycle... - // However it seems that their formula is wrong. I can't be bothered to figure out what's going on and, based on documentation from NVIDIA, - // timer_0 is meant to roll over every 4 seconds. Multiplying by 10 basically does the job. - - // Convert to microseconds - double freq_base = (real_time / 1000000.0f) / ((double)1.0 / nv3->nvbase.memory_clock_frequency) * 10.0f; - double current_time = freq_base * ((double)nv3->ptimer.clock_numerator) / (double)nv3->ptimer.clock_denominator; // *10.0? - - // truncate it - nv3->ptimer.time += (uint64_t)current_time; - - // Check if the alarm has actually triggered.. - // Only log on ptimer alarm. Otherwise, it's too much spam. - if (nv3->ptimer.time >= nv3->ptimer.alarm) - { - nv_log_verbose_only("PTIMER alarm interrupt fired (if interrupts enabled) because we reached TIME value 0x%08x\n", nv3->ptimer.alarm); - nv3_ptimer_interrupt(NV3_PTIMER_INTR_ALARM); - } -} - -uint32_t nv3_ptimer_read(uint32_t address) -{ - // always enabled - - nv_register_t* reg = nv_get_register(address, ptimer_registers, sizeof(ptimer_registers)/sizeof(ptimer_registers[0])); - - // Only log these when tehy actually tick - if (address != NV3_PTIMER_TIME_0_NSEC - && address != NV3_PTIMER_TIME_1_NSEC) - { - nv_log_verbose_only("PTIMER Read from 0x%08x", address); - } - - uint32_t ret = 0x00; - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - // Interrupt state: - // Bit 0: Alarm - - switch (reg->address) - { - case NV3_PTIMER_INTR: - ret = nv3->ptimer.interrupt_status; - break; - case NV3_PTIMER_INTR_EN: - ret = nv3->ptimer.interrupt_enable; - break; - case NV3_PTIMER_NUMERATOR: - ret = nv3->ptimer.clock_numerator; // 15:0 - break; - case NV3_PTIMER_DENOMINATOR: - ret = nv3->ptimer.clock_denominator ; //15:0 - break; - // 64-bit value - // High part - case NV3_PTIMER_TIME_0_NSEC: - ret = nv3->ptimer.time & 0xFFFFFFFF; //28:0 - break; - // Low part - case NV3_PTIMER_TIME_1_NSEC: - ret = nv3->ptimer.time >> 32; // 31:5 - break; - case NV3_PTIMER_ALARM_NSEC: - ret = nv3->ptimer.alarm; // 31:5 - break; - } - - } - //TIME0 and TIME1 produce too much log spam that slows everything down - if (reg->address != NV3_PTIMER_TIME_0_NSEC - && reg->address != NV3_PTIMER_TIME_1_NSEC) - { - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_ptimer_write(uint32_t address, uint32_t value) -{ - // before doing anything, check the subsystem enablement - nv_register_t* reg = nv_get_register(address, ptimer_registers, sizeof(ptimer_registers)/sizeof(ptimer_registers[0])); - - nv_log_verbose_only("PTIMER Write 0x%08x -> 0x%08x", value, address); - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - switch (reg->address) - { - // Interrupt state: - // Bit 0 - Alarm - - case NV3_PTIMER_INTR: - nv3->ptimer.interrupt_status &= ~value; - nv3_pmc_clear_interrupts(); - break; - - // Interrupt enablement state - case NV3_PTIMER_INTR_EN: - nv3->ptimer.interrupt_enable = value & 0x1; - break; - // nUMERATOR - case NV3_PTIMER_NUMERATOR: - nv3->ptimer.clock_numerator = value & 0xFFFF; // 15:0 - break; - case NV3_PTIMER_DENOMINATOR: - // prevent Div0 - if (!value) - value = 1; - - nv3->ptimer.clock_denominator = value & 0xFFFF; //15:0 - break; - // 64-bit value - // High part - case NV3_PTIMER_TIME_0_NSEC: - nv3->ptimer.time |= (value) & 0xFFFFFFE0; //28:0 - break; - // Low part - case NV3_PTIMER_TIME_1_NSEC: - nv3->ptimer.time |= ((uint64_t)(value & 0xFFFFFFE0) << 32); // 31:5 - break; - case NV3_PTIMER_ALARM_NSEC: - nv3->ptimer.alarm = value & 0xFFFFFFE0; // 31:5 - break; - } - } - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_pvideo.c b/src/video/nv/nv3/subsystems/nv3_pvideo.c deleted file mode 100644 index 60019b9c6..000000000 --- a/src/video/nv/nv3/subsystems/nv3_pvideo.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 PVIDEO - Video Overlay - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - - -nv_register_t pvideo_registers[] = { - { NV3_PVIDEO_INTR, "PVIDEO - Interrupt Status", NULL, NULL}, - { NV3_PVIDEO_INTR_EN, "PVIDEO - Interrupt Enable", NULL, NULL,}, - { NV3_PVIDEO_FIFO_THRESHOLD, "PVIDEO - FIFO Fill Threshold", NULL, NULL}, - { NV3_PVIDEO_FIFO_BURST_LENGTH, "PVIDEO - FIFO Burst Length (1=32, 2=64, 3=128)", NULL, NULL}, - { NV3_PVIDEO_OVERLAY, "PVIDEO - Overlay Info (Bit0 = Video On, Bit4 = Key On, Bit8 = Format, 0=CCIR, 1=YUV2)", NULL, NULL }, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -// ptimer init code -void nv3_pvideo_init(void) -{ - nv_log("Initialising PVIDEO..."); - - nv_log("Done!\n"); -} - -uint32_t nv3_pvideo_read(uint32_t address) -{ - // before doing anything, check the subsystem enablement - - nv_register_t* reg = nv_get_register(address, pvideo_registers, sizeof(pvideo_registers)/sizeof(pvideo_registers[0])); - uint32_t ret = 0x00; - - // todo: friendly logging - - nv_log_verbose_only("PVIDEO Read from 0x%08x", address); - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - // Interrupt state: - // Bit 0 - Notifier - - switch (reg->address) - { - case NV3_PVIDEO_INTR: - ret = nv3->pvideo.interrupt_status; - break; - case NV3_PVIDEO_INTR_EN: - ret = nv3->pvideo.interrupt_enable; - break; - case NV3_PVIDEO_FIFO_THRESHOLD: - ret = nv3->pvideo.fifo_threshold; - break; - case NV3_PVIDEO_FIFO_BURST_LENGTH: - ret = nv3->pvideo.fifo_burst_size & 0x03; - break; - case NV3_PVIDEO_OVERLAY: - ret = nv3->pvideo.overlay_settings & 0xFF; - break; - - } - } - - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv3_pvideo_write(uint32_t address, uint32_t value) -{ - // before doing anything, check the subsystem enablement - nv_register_t* reg = nv_get_register(address, pvideo_registers, sizeof(pvideo_registers)/sizeof(pvideo_registers[0])); - - nv_log_verbose_only("PVIDEO Write 0x%08x -> 0x%08x\n", value, address); - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - switch (reg->address) - { - // Interrupt state: - // Bit 0 - Notifier - - case NV3_PVIDEO_INTR: - nv3->pvideo.interrupt_status &= ~value; - nv3_pmc_clear_interrupts(); - break; - case NV3_PVIDEO_INTR_EN: - nv3->pvideo.interrupt_enable = value & 0x00000001; - break; - case NV3_PVIDEO_FIFO_THRESHOLD: - // only bits 6:3 matter - nv3->pvideo.fifo_threshold = ((value >> 3) & 0x0F) << 3; - break; - case NV3_PVIDEO_FIFO_BURST_LENGTH: - nv3->pvideo.fifo_burst_size = value & 0x03; - break; - case NV3_PVIDEO_OVERLAY: - nv3->pvideo.overlay_settings = value & 0xFF; - break; - } - } - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} \ No newline at end of file diff --git a/src/video/nv/nv3/subsystems/nv3_user.c b/src/video/nv/nv3/subsystems/nv3_user.c deleted file mode 100644 index f10e28793..000000000 --- a/src/video/nv/nv3/subsystems/nv3_user.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV3 User Submission Area (NV_USER, conceptually considered "Cache1 Pusher") - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv3.h> - - -// PIO Method Submission -// 128 channels conceptually supported - a hangover from nv1 where multiple windows all directly programming the gpu were supported? total lunacy. -uint32_t nv3_user_read(uint32_t address) -{ - // Get the address within the subchannel - //todo: print out the subchannel - uint8_t method_offset = (address & 0x1FFC); - - uint8_t channel = (address - NV3_USER_START) / 0x10000; - uint8_t subchannel = ((address - NV3_USER_START)) / 0x2000 % NV3_DMA_SUBCHANNELS_PER_CHANNEL; - - nv_log_verbose_only("User Submission Area PIO Channel %d.%d method_offset=0x%04x\n", channel, subchannel, method_offset); - - // 0x10 is free CACHE1 object - // TODO: THERE ARE OTHER STUFF! - switch (method_offset) - { - case NV3_SUBCHANNEL_PIO_IS_PFIFO_FREE: - return nv3_pfifo_cache1_num_free_spaces(); - case NV3_SUBCHANNEL_PIO_ALWAYS_ZERO_START ... NV3_SUBCHANNEL_PIO_ALWAYS_ZERO_END: - return 0x00; - - } - - nv_log("NV_USER READ: Channel FIELD NOT IMPLEMENTED!!!! offset=0x%04x\n", method_offset); - - return 0x00; -}; - -// Although NV3 doesn't have DMA mode unlike NV4 and later, it's conceptually similar to a "pusher" that pushes graphics commands that you write into CACHE1 that are then pulled out. -// So we send the writes here. This might do other stuff, so we keep this function -void nv3_user_write(uint32_t address, uint32_t value) -{ - nv3_pfifo_cache1_push(address, value); - - // This isn't ideal, but otherwise, the dynarec causes the GPU to write so many objects into CACHE1, it starts overwriting the old objects - // This basically makes the fifo not a fifo, but oh well - nv3_pfifo_cache1_pull(); -} \ No newline at end of file diff --git a/src/video/nv/nv4/nv4_core.c b/src/video/nv/nv4/nv4_core.c deleted file mode 100644 index 5712cf7d1..000000000 --- a/src/video/nv/nv4/nv4_core.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV4 bringup and device emulation. - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv4.h> - -nv4_t* nv4; - -// Stolen from Voodoo 3 -static video_timings_t timing_nv4_agp = { .type = VIDEO_AGP, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; - -// Initialise the MMIO mappings -void nv4_init_mappings_mmio(void) -{ - nv_log("Initialising MMIO mapping\n"); - - // 0x0 - 1000000: regs - // 0x1000000-2000000 - - // initialize the mmio mapping - mem_mapping_add(&nv4->nvbase.mmio_mapping, 0, 0, - nv4_mmio_read8, - nv4_mmio_read16, - nv4_mmio_read32, - nv4_mmio_write8, - nv4_mmio_write16, - nv4_mmio_write32, - NULL, MEM_MAPPING_EXTERNAL, nv4); - - // initialize the mmio mapping - mem_mapping_add(&nv4->nvbase.ramin_mapping, 0, 0, - nv4_ramin_read8, - nv4_ramin_read16, - nv4_ramin_read32, - nv4_ramin_write8, - nv4_ramin_write16, - nv4_ramin_write32, - NULL, MEM_MAPPING_EXTERNAL, nv4); - -} - -void nv4_init_mappings_svga(void) -{ - nv_log("Initialising SVGA core memory mapping\n"); - // setup the svga mappings - - mem_mapping_add(&nv4->nvbase.framebuffer_mapping, 0, 0, - nv4_dfb_read8, - nv4_dfb_read16, - nv4_dfb_read32, - nv4_dfb_write8, - nv4_dfb_write16, - nv4_dfb_write32, - nv4->nvbase.svga.vram, 0, &nv4->nvbase.svga); - - // the SVGA/LFB mapping is also mirrored - mem_mapping_add(&nv4->nvbase.framebuffer_mapping_mirror, 0, 0, - nv4_dfb_read8, - nv4_dfb_read16, - nv4_dfb_read32, - nv4_dfb_write8, - nv4_dfb_write16, - nv4_dfb_write32, - nv4->nvbase.svga.vram, 0, &nv4->nvbase.svga); - - io_sethandler(NV4_CIO_START, NV4_CIO_SIZE, - nv4_svga_read, NULL, NULL, - nv4_svga_write, NULL, NULL, - nv4); -} - -void nv4_init_mappings(void) -{ - nv4_init_mappings_mmio(); - nv4_init_mappings_svga(); -} - -// Updates the mappings after initialisation. -void nv4_update_mappings(void) -{ - // sanity check - if (!nv4) - return; - - // setting this to 0 doesn't seem to disable it, based on the datasheet - - nv_log("\nMemory Mapping Config Change:\n"); - - (nv4->nvbase.pci_config.pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) ? nv_log("Enable I/O\n") : nv_log("Disable I/O\n"); - - io_removehandler(NV4_CIO_START, NV4_CIO_SIZE, - nv4_svga_read, NULL, NULL, - nv4_svga_write, NULL, NULL, - nv4); - - if (nv4->nvbase.pci_config.pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - io_sethandler(NV4_CIO_START, NV4_CIO_SIZE, - nv4_svga_read, NULL, NULL, - nv4_svga_write, NULL, NULL, - nv4); - - if (!(nv4->nvbase.pci_config.pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - nv_log("The memory was turned off, not much is going to happen.\n"); - return; - } - - // turn off bar0 and bar1 by defualt - mem_mapping_disable(&nv4->nvbase.mmio_mapping); - mem_mapping_disable(&nv4->nvbase.framebuffer_mapping); - mem_mapping_disable(&nv4->nvbase.framebuffer_mapping_mirror); - mem_mapping_disable(&nv4->nvbase.ramin_mapping); - - // Setup BAR0 (MMIO) - - nv_log("BAR0 (MMIO Base) = 0x%08x\n", nv4->nvbase.bar0_mmio_base); - - if (nv4->nvbase.bar0_mmio_base) - { - mem_mapping_set_addr(&nv4->nvbase.mmio_mapping, nv4->nvbase.bar0_mmio_base, NV4_MMIO_SIZE); - mem_mapping_set_addr(&nv4->nvbase.ramin_mapping, nv4->nvbase.bar0_mmio_base + NV4_PRAMIN_START, NV4_PRAMIN_SIZE); - } - - // if this breaks anything, remove it - nv_log("BAR1 (Linear Framebuffer & VRAM) = 0x%08x\n", nv4->nvbase.bar1_lfb_base); - - if (nv4->nvbase.bar1_lfb_base) - { - if (nv4->nvbase.vram_amount == NV4_VRAM_SIZE_16MB) - { - // we don't need this one in the case of 16mb, - mem_mapping_disable(&nv4->nvbase.framebuffer_mapping_mirror); - mem_mapping_set_addr(&nv4->nvbase.framebuffer_mapping, nv4->nvbase.bar1_lfb_base, NV4_VRAM_SIZE_16MB); - } - else if (nv4->nvbase.vram_amount == NV4_VRAM_SIZE_8MB) - { - mem_mapping_set_addr(&nv4->nvbase.framebuffer_mapping, nv4->nvbase.bar1_lfb_base, NV4_VRAM_SIZE_8MB); - mem_mapping_set_addr(&nv4->nvbase.framebuffer_mapping_mirror, nv4->nvbase.bar1_lfb_base + NV4_VRAM_SIZE_8MB, NV4_VRAM_SIZE_8MB); - } - } - - // Did we change the banked SVGA mode? - switch (nv4->nvbase.svga.gdcreg[NV4_PRMVIO_GX_MISC_INDEX] & 0x0c) - { - case NV4_PRMVIO_GX_MISC_BANKED_128K_A0000: - nv_log("SVGA Banked Mode = 128K @ A0000h\n"); - mem_mapping_set_addr(&nv4->nvbase.svga.mapping, 0xA0000, 0x20000); // 128kb @ 0xA0000 - nv4->nvbase.svga.banked_mask = 0x1FFFF; - break; - case NV4_PRMVIO_GX_MISC_BANKED_64K_A0000: - nv_log("SVGA Banked Mode = 64K @ A0000h\n"); - mem_mapping_set_addr(&nv4->nvbase.svga.mapping, 0xA0000, 0x10000); // 64kb @ 0xA0000 - nv4->nvbase.svga.banked_mask = 0xFFFF; - break; - case NV4_PRMVIO_GX_MISC_BANKED_32K_B0000: - nv_log("SVGA Banked Mode = 32K @ B0000h\n"); - mem_mapping_set_addr(&nv4->nvbase.svga.mapping, 0xB0000, 0x8000); // 32kb @ 0xB0000 - nv4->nvbase.svga.banked_mask = 0x7FFF; - break; - case NV4_PRMVIO_GX_MISC_BANKED_32K_B8000: - nv_log("SVGA Banked Mode = 32K @ B8000h\n"); - mem_mapping_set_addr(&nv4->nvbase.svga.mapping, 0xB8000, 0x8000); // 32kb @ 0xB8000 - nv4->nvbase.svga.banked_mask = 0x7FFF; - break; - } -} - - -bool nv4_init() -{ - nv4 = calloc(1, sizeof(nv4_t)); - - if (!nv4->nvbase.vram_amount) - nv4->nvbase.vram_amount = device_get_config_int("vram_size"); - - /* Set log device name based on card model */ - const char* log_device_name = "NV4"; - - /* Just hardcode full logging */ - - if (device_get_config_int("nv_debug_fulllog")) - nv4->nvbase.log = log_open(log_device_name); - else - nv4->nvbase.log = log_open_cyclic(log_device_name); - - nv_log_set_device(nv4->nvbase.log); - - nv4->nvbase.bus_generation = nv_bus_agp_2x; - - // Figure out which vbios the user selected - // This depends on the bus we are using and if the gpu is rev a/b or rev c - - const char* vbios_file = NV4_VBIOS_STB_REVA; - - int32_t err = rom_init(&nv4->nvbase.vbios, vbios_file, 0xC0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - if (err) - { - nv_log("NV4 FATAL: failed to load VBIOS err=%d\n", err); - fatal("Nvidia NV4 init failed: Somehow selected a nonexistent VBIOS? err=%d\n", err); - return false; - } - else - nv_log("Successfully loaded VBIOS located at %s\n", vbios_file); - - pci_add_card(PCI_ADD_AGP, nv4_pci_read, nv4_pci_write, NULL, &nv4->nvbase.pci_slot); - - svga_init(&nv4_device_agp, &nv4->nvbase.svga, nv4, nv4->nvbase.vram_amount, - nv4_recalc_timings, nv4_svga_read, nv4_svga_write, nv4_draw_cursor, NULL); - - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_nv4_agp); - - // Setup clock information. These values don't matter, I pulled them out of an STB BIOS, we don't need to macro them - nv4->pramdac.nvclk = 0x17809; - nv4->pramdac.mclk = 0x1a30a; - nv4->pramdac.vclk = 0x1400c; - - //timer_add(nv4->pramdac.nvclk, ) - - - - nv4_init_mappings(); - //nv4_update_mappings(); - - return true; -} - -void* nv4_init_stb4400(const device_t *info) -{ - bool successful = nv4_init(); - - if (successful) - return nv4; - else - return NULL; -} - -void nv4_nvclk_tick() -{ - -} - -void nv4_mclk_tick() -{ - -} - -void nv4_vclk_tick() -{ - -} - -void nv4_close(void* priv) -{ - free(nv4); -} - -void nv4_speed_changed(void *priv) -{ - -} - -void nv4_draw_cursor(svga_t* svga, int32_t drawline) -{ - -} - - -// -// SVGA functions -// -void nv4_recalc_timings(svga_t* svga) -{ - // sanity check - if (!nv4) - return; - - - nv4_t* nv4 = (nv4_t*)svga->priv; - - // TODO: Everything, this code sucks, incl. NV4_PRAMDAC_GENERAL_CONTROL_BPC and the offset register - uint32_t pixel_mode = svga->crtc[NV4_CIO_CRE_PIXEL_INDEX] & 0x03; - - svga->memaddr_latch += (svga->crtc[NV4_CIO_CRE_RPC0_INDEX] & 0x1F) << 16; - - /* Turn off override if we are in VGA mode */ - svga->override = !(pixel_mode == NV4_CIO_CRE_PIXEL_FORMAT_VGA); - - /* NOTE: The RIVA 128 draws in a way almost completely separate to any other 86Box GPU. - - Basically, we only blit to buffer32 when something changes and we don't even bother using a timer. We only render when there is something to actually render. - - This is because there is no linear relationship between the contents of VRAM and the contents of the display which 86box's SVGA subsystem cannot tolerate. - In fact, the position in VRAM and pitch can be changed at any time via an NV_IMAGE_IN_MEMORY object. - - Therefore, we need to completely bypass it using svga->override and draw our own rendering functions. This allows us to use a neat optimisation trick - to only ever actually draw when we need to do something. This shouldn't be a problem in games, because the drivers will read the current refresh rate from - the Windows settings, and then, just submit objects at that pace for anything that changes on the screen. - */ - - // Set the pixel mode - switch (pixel_mode) - { - case NV4_CIO_CRE_PIXEL_FORMAT_8BPP: - svga->rowoffset += (svga->crtc[NV4_CIO_CRE_RPC0_INDEX] & 0xE0) << 1; // ????? - svga->bpp = 8; - svga->lowres = 0; - svga->map8 = svga->pallook; - break; - case NV4_CIO_CRE_PIXEL_FORMAT_16BPP: - /* This is some sketchy shit that is an attempt at an educated guess - at pixel clock differences between 9x and NT only in 16bpp. If there is ever an error on 9x with "interlaced" looking graphics, - this is what's causing it. Possibly fucking up the drivers under *ReactOS* of all things */ - if ((svga->crtc[NV4_CIO_CR_VRS_INDEX] >> 1) & 0x01) - svga->rowoffset += (svga->crtc[NV4_CIO_CRE_RPC0_INDEX] & 0xE0) << 2; - else - svga->rowoffset += (svga->crtc[NV4_CIO_CRE_RPC0_INDEX] & 0xE0) << 3; - - // 15bpp mode is removed on NV4 - // TODO: Not svga - svga->bpp = 16; - svga->lowres = 0; - - break; - case NV4_CIO_CRE_PIXEL_FORMAT_32BPP: - svga->rowoffset += (svga->crtc[NV4_CIO_CRE_RPC0_INDEX] & 0xE0) << 3; - - svga->bpp = 32; - svga->lowres = 0; - //svga->render = nv4_render_32bpp; - break; - } - - - if (((svga->miscout >> 2) & 2) == 2) - { - // set clocks - //nv4_pramdac_set_pixel_clock(); - //nv4_pramdac_set_vram_clock(); - } -} - - -// See if the bios rom is available. -int32_t nv4_available(void) -{ - return (rom_present(NV4_VBIOS_STB_REVA)); -} - -// NV4 (RIVA 128) -// AGP -// 8MB or 16MB VRAM -const device_t nv4_device_agp = -{ - .name = "nVIDIA RIVA TNT (STB Velocity 4400)", - .internal_name = "nv4_stb4400", - .flags = DEVICE_AGP, - .local = 0, - .init = nv4_init_stb4400, - .close = nv4_close, - .speed_changed = nv4_speed_changed, - .force_redraw = nv4_force_redraw, - .available = nv4_available, - .config = nv4_config, -}; diff --git a/src/video/nv/nv4/nv4_core_config.c b/src/video/nv/nv4/nv4_core_config.c deleted file mode 100644 index 2dd88eed6..000000000 --- a/src/video/nv/nv4/nv4_core_config.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Provides NV4 configuration - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv4.h> - -const device_config_t nv4_config[] = -{ - // Memory configuration - { - .name = "vram_size", - .description = "VRAM Size", - .type = CONFIG_SELECTION, - .default_int = NV4_VRAM_SIZE_16MB, - .selection = - { - // I thought this was never released, but it seems that at least one was released: - // The card was called the "NEC G7AGK" - { - .description = "8 MB", - .value = NV4_VRAM_SIZE_8MB, - }, - - { - .description = "16 MB", - .value = NV4_VRAM_SIZE_16MB, - }, - } - - }, - // Multithreading configuration - { - - .name = "pgraph_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .default_int = 1, // todo: change later - .selection = - { - { - .description = "1 thread (Only use if issues appear with more threads)", - .value = 1, - }, - { - .description = "2 threads", - .value = 2, - }, - { - .description = "4 threads", - .value = 4, - }, - { - .description = "8 threads", - .value = 8, - }, - }, - }, -#ifndef RELEASE_BUILD - { - .name = "nv_debug_fulllog", - .description = "Disable Cyclical Lines Detection for nv_log (Use for getting full context at cost of VERY large log files)", - .type = CONFIG_BINARY, - .default_int = 0, - }, -#endif - { - .type = CONFIG_END - } -}; \ No newline at end of file diff --git a/src/video/nv/nv4/nv4_core_io.c b/src/video/nv/nv4/nv4_core_io.c deleted file mode 100644 index 4c5aa5a40..000000000 --- a/src/video/nv/nv4/nv4_core_io.c +++ /dev/null @@ -1,1283 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV4 I/O, including Real-Mode Access (RMA), memory mapping, PCI, AGP, SVGA and MMIO via PCI BARs - * - * MMIO dumps are available at: https://nvwiki.org/misc/NVDumps/ - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - - -// Prototypes for functions only used in this translation unit - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv4.h> - - -void nv4_init_mappings_mmio(void); -void nv4_init_mappings_svga(void); -bool nv4_is_svga_redirect_address(uint32_t addr); - -uint8_t nv4_svga_read(uint16_t addr, void* priv); -void nv4_svga_write(uint16_t addr, uint8_t val, void* priv); - - -uint32_t nv4_mmio_arbitrate_read(uint32_t addr) -{ - uint32_t ret = 0x00; - - if (addr >= NV4_PTIMER_START && addr <= NV4_PTIMER_END) - ret = nv4_ptimer_read(addr); - else if (addr >= NV4_PRAMDAC_START && addr <= NV4_PRAMDAC_END) - ret = nv4_pramdac_read(addr); - - #ifdef NV_LOG - nv_register_t reg = nv_get_register(addr, &nv4_registers, sizeof(nv4_registers)/sizeof(nv4_registers[0])); - - if (reg) - { - if (reg->on_read) - ret = reg->on_read(); - - nv_log_verbose_only("Register read from 0x%08x value=%08x", addr, ret); - - } - #endif - -} - -void nv4_mmio_arbitrate_write(uint32_t addr, uint32_t val) -{ - if (addr >= NV4_PTIMER_START && addr <= NV4_PTIMER_END) - nv4_ptimer_write(addr, val); - else if (addr >= NV4_PRAMDAC_START && addr <= NV4_PRAMDAC_END) - nv4_pramdac_write(addr, val); - - #ifdef NV_LOG - nv_register_t reg = nv_get_register(addr, &nv4_registers, sizeof(nv4_registers)/sizeof(nv4_registers[0])); - - if (reg) - { - if (reg->on_write) - reg->on_write(val); - - nv_log_verbose_only("Register write from 0x%08x value=%08x", addr, val); - - } - #endif -} - -// Determine if this address needs to be redirected to the SVGA subsystem. - -bool nv4_is_svga_redirect_address(uint32_t addr) -{ - return (addr >= NV4_PRMVIO_START && addr <= NV4_PRMVIO_END) // VGA - || (addr >= NV4_PRMCIO_START && addr <= NV4_PRMCIO_END) // CRTC - || (addr >= NV4_USER_DAC_START && addr <= NV4_USER_DAC_END); // Note: 6813c6-6813c9 are ignored somewhere else -} - -uint8_t nv4_rma_read(uint16_t addr) -{ - addr &= 0xFF; - uint32_t real_final_address = 0x0; - uint8_t ret = 0x0; - - switch (addr) - { - // signature so you know reads work - case 0x00: - ret = NV4_PRMIO_RMA_ID_CODE_VALID & 0xFF; - break; - case 0x01: - ret = (NV4_PRMIO_RMA_ID_CODE_VALID >> 8) & 0xFF; - break; - case 0x02: - ret = (NV4_PRMIO_RMA_ID_CODE_VALID >> 16) & 0xFF; - break; - case 0x03: - ret = (NV4_PRMIO_RMA_ID_CODE_VALID >> 24) & 0xFF; - break; - case 0x08 ... 0x0B: - // reads must be dword aligned - real_final_address = (nv4->pbus.rma.addr + (addr & 0x03)); - - if (nv4->pbus.rma.addr < NV4_MMIO_SIZE) - ret = nv4_mmio_read8(real_final_address, NULL); - else - { - /* Do we need to read RAMIN here? */ - ret = nv4->nvbase.svga.vram[real_final_address - NV4_MMIO_SIZE] & (nv4->nvbase.svga.vram_max - 1); - } - - // log current location for vbios RE - nv_log_verbose_only("MMIO Real Mode Access read, initial address=0x%08x final RMA MMIO address=0x%08x data=0x%08x\n", - addr, real_final_address, ret); - - break; - } - - return ret; -} - -// Implements a 32-bit write using 16 bit port number -void nv4_rma_write(uint16_t addr, uint8_t val) -{ - // addresses are in reality 8bit so just mask it to be safe - addr &= 0xFF; - - // format: - // 0x00 ID - // 0x04 Pointer to data - // 0x08 Data port(?) - // 0x0B Data - 32bit. SENT IN THE RIGHT ORDER FOR ONCE WAHOO! - // 0x10 Increment (?) data - implemented the same as data for now - - if (addr < 0x08) - { - switch (addr % 0x04) - { - case 0x00: // lowest byte - nv4->pbus.rma.addr &= ~0xff; - nv4->pbus.rma.addr |= val; - break; - case 0x01: // 2nd highest byte - nv4->pbus.rma.addr &= ~0xff00; - nv4->pbus.rma.addr |= (val << 8); - break; - case 0x02: // 3rd highest byte - nv4->pbus.rma.addr &= ~0xff0000; - nv4->pbus.rma.addr |= (val << 16); - break; - case 0x03: // 4th highest byte - nv4->pbus.rma.addr &= ~0xff000000; - nv4->pbus.rma.addr |= (val << 24); - break; - } - } - // Data to send to MMIO - else - { - switch (addr % 0x04) - { - case 0x00: // lowest byte - nv4->pbus.rma.data &= ~0xff; - nv4->pbus.rma.data |= val; - break; - case 0x01: // 2nd highest byte - nv4->pbus.rma.data &= ~0xff00; - nv4->pbus.rma.data |= (val << 8); - break; - case 0x02: // 3rd highest byte - nv4->pbus.rma.data &= ~0xff0000; - nv4->pbus.rma.data |= (val << 16); - break; - case 0x03: // 4th highest byte - nv4->pbus.rma.data &= ~0xff000000; - nv4->pbus.rma.data |= (val << 24); - - nv_log_verbose_only("MMIO Real Mode Access write transaction complete, initial address=0x%04x final RMA MMIO address=0x%08x data=0x%08x\n", - addr, nv4->pbus.rma.addr, nv4->pbus.rma.data); - - if (nv4->pbus.rma.addr < NV4_MMIO_SIZE) - nv4_mmio_write32(nv4->pbus.rma.addr, nv4->pbus.rma.data, NULL); - else // failsafe code, i don't think you will ever write outside of VRAM? - { - uint32_t* vram_32 = (uint32_t*)nv4->nvbase.svga.vram; - vram_32[(nv4->pbus.rma.addr - NV4_MMIO_SIZE) >> 2] = nv4->pbus.rma.data; - } - - - break; - } - } - - if (addr & 0x10) - nv4->pbus.rma.addr += 0x04; // Alignment -} - - - -// All MMIO regs are 32-bit i believe internally -// so we have to do some munging to get this to read - -// Read 8-bit MMIO -uint8_t nv4_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; - - // We need to specifically exclude this particular set of registers - // so we can write the 4/8bpp CLUT - if (addr >= NV4_USER_DAC_PALETTE_START && addr <= NV4_USER_DAC_PALETTE_END) - { - // Throw directly into PRAMDAC - return nv4_mmio_arbitrate_read(addr); - } - - if (nv4_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - ret = nv4_svga_read(real_address, nv4); - - nv_log_verbose_only("Redirected MMIO read8 to SVGA: addr=0x%04x returned 0x%04x\n", addr, ret); - - return ret; - } - - // see if unaligned reads are a problem - ret = nv4_mmio_read32(addr, priv); - return (uint8_t)(ret >> ((addr & 3) << 3) & 0xFF); -} - -// Read 16-bit MMIO -uint16_t nv4_mmio_read16(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 (nv4_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - ret = nv4_svga_read(real_address, nv4) - | (nv4_svga_read(real_address + 1, nv4) << 8); - - nv_log_verbose_only("Redirected MMIO read16 to SVGA: addr=0x%04x returned 0x%04x\n", addr, ret); - - return ret; - } - - ret = nv4_mmio_read32(addr, priv); - return (uint8_t)(ret >> ((addr & 3) << 3) & 0xFFFF); -} - -// Read 32-bit MMIO -uint32_t nv4_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 (nv4_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - ret = nv4_svga_read(real_address, nv4) - | (nv4_svga_read(real_address + 1, nv4) << 8) - | (nv4_svga_read(real_address + 2, nv4) << 16) - | (nv4_svga_read(real_address + 3, nv4) << 24); - - nv_log_verbose_only("Redirected MMIO read32 to SVGA: addr=0x%04x returned 0x%04x\n", addr, ret); - - return ret; - } - - ret = nv4_mmio_arbitrate_read(addr); - - return ret; -} - -// Write 8-bit MMIO -void nv4_mmio_write8(uint32_t addr, uint8_t val, void* priv) -{ - addr &= 0xFFFFFF; - - // We need to specifically exclude this particular set of registers - // so we can write the 4/8bpp CLUT - if (addr >= NV4_USER_DAC_PALETTE_START && addr <= NV4_USER_DAC_PALETTE_END) - { - // Throw directly into PRAMDAC - nv4_mmio_arbitrate_write(addr, val); - return; - } - - // This is weitek vga stuff - // If we need to add more of these we can convert these to a switch statement - if (nv4_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - nv_log_verbose_only("Redirected MMIO write8 to SVGA: addr=0x%04x val=0x%02x\n", addr, val); - - nv4_svga_write(real_address, val & 0xFF, nv4); - - return; - } - - // overwrite first 8bits of a 32 bit value - uint32_t new_val = nv4_mmio_read32(addr, NULL); - - new_val &= (~0xFF << (addr & 3) << 3); - new_val |= (val << ((addr & 3) << 3)); - - nv4_mmio_write32(addr, new_val, priv); -} - -// Write 16-bit MMIO -void nv4_mmio_write16(uint32_t addr, uint16_t val, void* priv) -{ - addr &= 0xFFFFFF; - - // This is weitek vga stuff - if (nv4_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - nv_log_verbose_only("Redirected MMIO write16 to SVGA: addr=0x%04x val=0x%02x\n", addr, val); - - nv4_svga_write(real_address, val & 0xFF, nv4); - nv4_svga_write(real_address + 1, (val >> 8) & 0xFF, nv4); - - return; - } - - // overwrite first 16bits of a 32 bit value - uint32_t new_val = nv4_mmio_read32(addr, NULL); - - new_val &= (~0xFFFF << (addr & 3) << 3); - new_val |= (val << ((addr & 3) << 3)); - - nv4_mmio_write32(addr, new_val, priv); -} - -// Write 32-bit MMIO -void nv4_mmio_write32(uint32_t addr, uint32_t val, void* priv) -{ - addr &= 0xFFFFFF; - - // This is weitek vga stuff - if (nv4_is_svga_redirect_address(addr)) - { - // svga writes are not logged anyway rn - uint32_t real_address = addr & 0x3FF; - - nv_log_verbose_only("Redirected MMIO write32 to SVGA: addr=0x%04x val=0x%02x\n", addr, val); - - nv4_svga_write(real_address, val & 0xFF, nv4); - nv4_svga_write(real_address + 1, (val >> 8) & 0xFF, nv4); - nv4_svga_write(real_address + 2, (val >> 16) & 0xFF, nv4); - nv4_svga_write(real_address + 3, (val >> 24) & 0xFF, nv4); - - return; - } - - nv4_mmio_arbitrate_write(addr, val); -} - -// PCI stuff -// BAR0 Pointer to MMIO space & RAMIN -// BAR1 Pointer to Linear Framebuffer -uint8_t nv4_pci_read(int32_t func, int32_t addr, void* priv) -{ - uint8_t ret = 0x00; - - // sanity check - if (!nv4) - return ret; - - // Convert to the MMIO addresses - if (addr <= 0xFF) - addr += 0x1800; - - // Anything not listed is 0x00 - // PCI values extracted from https://nvwiki.org/misc/NVDumps/RivaMobileNV4/Nv4win_HL/nv4bar0.bin - // STB V4400 (running Half-Life) - switch (addr) - { - // Get the pci vendor id.. - - case NV4_PBUS_PCI_VENDOR_ID: - ret = (NV4_PBUS_PCI_DEVICE_VENDOR_NVIDIA & 0xFF); - break; - - case NV4_PBUS_PCI_VENDOR_ID + 1: // all access 8bit - ret = (NV4_PBUS_PCI_DEVICE_VENDOR_NVIDIA >> 8); - break; - - // device id - - case NV4_PBUS_PCI_DEVICE_ID: - ret = (NV_PCI_DEVICE_NV4 & 0xFF); - break; - - case NV4_PBUS_PCI_DEVICE_ID + 1: - ret = (NV_PCI_DEVICE_NV4 >> 8); - break; - - // various capabilities enabled by default - // IO space enabled - // Memory space enabled - // Bus master enabled - // Write/inval enabled - // Pal snoop enabled - // Capabiliies list enabled - // 66Mhz FSB capable - - case NV4_PBUS_PCI_COMMAND: - ret = nv4->nvbase.pci_config.pci_regs[PCI_REG_COMMAND_L]; - break; - // COMMAND_L not used - - // pci status register - case NV4_PBUS_PCI_STATUS: - if (nv4->straps - & NV4_STRAP_BUS_SPEED_66MHZ) - ret = (nv4->nvbase.pci_config.pci_regs[PCI_REG_STATUS_L] | NV4_PBUS_PCI_STATUS_66MHZ_CAPABLE); - else - ret = nv4->nvbase.pci_config.pci_regs[PCI_REG_STATUS_L]; - - break; - - case NV4_PBUS_PCI_STATUS_2: - ret = (nv4->nvbase.pci_config.pci_regs[PCI_REG_STATUS_H]) & (NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING_FAST << NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING); - break; - - case NV4_PBUS_PCI_REVISION_ID: - ret = nv4->nvbase.gpu_revision; // Commercial release - break; - - case PCI_REG_PROG_IF: - ret = 0x00; - break; - - // We only need to return 0x30 since the VGA class code is 0x30000 - case NV4_PBUS_PCI_CLASS_CODE: - ret = (NV4_PBUS_PCI_CLASS_CODE_VGA) >> 16; // CLASS_CODE_VGA - break; - - - case NV4_PBUS_PCI_LATENCY_TIMER: - case NV4_PBUS_PCI_HEADER_TYPE: - ret = 0x00; - break; - - // BARs are marked as prefetchable per the datasheet - case NV4_PBUS_PCI_BAR0_INFO: - case NV4_PBUS_PCI_BAR1_INFO: - // only bit that matters is bit 3 (prefetch bit) - ret = (NV4_PBUS_PCI_BAR_PREFETCHABLE_MERGABLE << NV4_PBUS_PCI_BAR_PREFETCHABLE); - break; - - // MMIO base address - case NV4_PBUS_PCI_BAR0_BASE_31_TO_24: - ret = nv4->nvbase.bar0_mmio_base >> 24;//8bit value - break; - - case NV4_PBUS_PCI_BAR1_BASE_31_TO_24: - ret = nv4->nvbase.bar1_lfb_base >> 24; //8bit value - break; - - case NV4_PBUS_PCI_BAR_RESERVED_START ... NV4_PBUS_PCI_BAR_RESERVED_END: - case NV4_PBUS_PCI_BAR0_UNUSED1: - case NV4_PBUS_PCI_BAR0_UNUSED2: - case NV4_PBUS_PCI_BAR1_UNUSED1: - case NV4_PBUS_PCI_BAR1_UNUSED2: - - ret = 0x00; // hard lock - break; - - case NV4_PBUS_PCI_ROM: - ret = nv4->nvbase.pci_config.vbios_enabled; - break; - - case NV4_PBUS_PCI_INTR_LINE: - ret = nv4->nvbase.pci_config.int_line; - break; - - case NV4_PBUS_PCI_INTR_PIN: - ret = PCI_INTA; - break; - - // - // Capabilities pointers - // - - case NV4_PBUS_PCI_NEXT_PTR: - ret = NV4_PBUS_PCI_CAP_PTR_POWER_MGMT; - break; - - case NV4_PBUS_PCIPOWER_NEXT_PTR: - ret = NV4_PBUS_PCI_CAP_PTR_AGP; - break; - - // AGP is the end of the chain - case NV4_PBUS_AGP_NEXT_PTR: - ret = 0x00; - break; - - case NV4_PBUS_PCI_MAX_LAT: - ret = NV4_PBUS_PCI_MAX_LAT_250NS; - break; - - // these map to the subsystem - // todo: port this bugfix to NV4 - case NV4_PBUS_PCI_SUBSYSTEM_VENDOR_ID_WRITABLE: - case NV4_PBUS_PCI_SUBSYSTEM_VENDOR_ID_WRITABLE + 1: - case NV4_PBUS_PCI_SUBSYSTEM_ID_WRITABLE: - case NV4_PBUS_PCI_SUBSYSTEM_ID_WRITABLE + 1: - ret = nv4->nvbase.pci_config.pci_regs[NV4_PBUS_PCI_SUBSYSTEM_ID + (addr & 0x03)]; - break; - - case NV4_PBUS_AGP_CAPABILITIES: - ret = NV4_PBUS_AGP_CAPABILITY_AGP; // AGP capable device - break; - case NV4_PBUS_AGP_REV: - ret = (NV4_PBUS_AGP_REV_MAJOR_1 << NV4_PBUS_AGP_REV_MAJOR) | NV4_PBUS_AGP_REV_MINOR; - break; - case NV4_PBUS_AGP_STATUS_RATE: - ret = NV4_PBUS_AGP_STATUS_RATE_1X_AND_2X; - break; - case NV4_PBUS_AGP_STATUS_SBA: - ret = (NV4_PBUS_AGP_STATUS_SBA_STATUS_CAPABLE) << NV4_PBUS_AGP_STATUS_SBA_STATUS; // Sideband is supported on NV4 - break; - case NV4_PBUS_AGP_STATUS_RQ: - ret = NV4_PBUS_AGP_STATUS_RQ_16; - break; - case NV4_PBUS_AGP_COMMAND_2: - ret = (nv4->nvbase.agp_enabled) << NV4_PBUS_AGP_COMMAND_2_AGP_ENABLED - | (nv4->nvbase.agp_sba_enabled) << NV4_PBUS_AGP_COMMAND_2_SBA_ENABLED; - break; - default: // by default just return pci_config.pci_regs (default value for nonwritten registers is 0x00) - ret = nv4->nvbase.pci_config.pci_regs[addr]; - break; - - } - - nv_log("nv4_pci_read func=0x%04x addr=0x%04x ret=0x%04x\n", func, addr & 0xFF, ret); - return ret; -} - - -// nv4 pci/agp write -void nv4_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv) -{ - // sanity check - if (!nv4) - return; - - // Convert to the MMIO addresses - if (addr <= 0xFF) - addr += 0x1800; - // some addresses are not writable so can't have any effect and can't be allowed to be modified using this code - // as an example, only the most significant byte of the PCI BARs can be modified - if (addr == NV4_PBUS_PCI_BAR0_UNUSED1 || addr == NV4_PBUS_PCI_BAR0_UNUSED2 - && addr == NV4_PBUS_PCI_BAR1_UNUSED1 || addr == NV4_PBUS_PCI_BAR1_UNUSED2) - return; - - nv_log("nv4_pci_write func=0x%04x addr=0x%04x val=0x%04x\n", func, addr & 0xFF, val); - - nv4->nvbase.pci_config.pci_regs[addr] = val; - - switch (addr) - { - // standard pci command stuff - case NV4_PBUS_PCI_COMMAND: - nv4->nvbase.pci_config.pci_regs[PCI_REG_COMMAND_L] = val; - // actually update the mappings - nv4_update_mappings(); - break; - case NV4_PBUS_PCI_COMMAND_H: - nv4->nvbase.pci_config.pci_regs[PCI_REG_COMMAND_H] = val; - // actually update the mappings - nv4_update_mappings(); - break; - // pci status register - case NV4_PBUS_PCI_STATUS: - nv4->nvbase.pci_config.pci_regs[PCI_REG_STATUS_L] = val | (NV4_PBUS_PCI_STATUS_66MHZ_CAPABLE << NV4_PBUS_PCI_STATUS_66MHZ); - break; - case NV4_PBUS_PCI_STATUS_2: - nv4->nvbase.pci_config.pci_regs[PCI_REG_STATUS_H] = val | (NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING_FAST << NV4_PBUS_PCI_STATUS_2_DEVSEL_TIMING); - break; - //TODO: ACTUALLY REMAP THE MMIO AND NV_USER - case NV4_PBUS_PCI_BAR0_BASE_31_TO_24: - nv4->nvbase.bar0_mmio_base = val << 24; - nv4_update_mappings(); - break; - case NV4_PBUS_PCI_BAR1_BASE_31_TO_24: - nv4->nvbase.bar1_lfb_base = val << 24; - nv4_update_mappings(); - break; - - case NV4_PBUS_PCI_ROM: - case NV4_PBUS_PCI_ROM_BASE: - - // make sure we are actually toggling the vbios, not the rom base - if (addr == NV4_PBUS_PCI_ROM) - nv4->nvbase.pci_config.vbios_enabled = (val & 0x01); - - if (nv4->nvbase.pci_config.vbios_enabled) - { - // First see if we simply wanted to change the VBIOS location - - // Enable it in case it was disabled before - mem_mapping_enable(&nv4->nvbase.vbios.mapping); - - if (addr != NV4_PBUS_PCI_ROM) - { - uint32_t old_addr = nv4->nvbase.vbios.mapping.base; - // 9bit register - uint32_t new_addr = nv4->nvbase.pci_config.pci_regs[NV4_PBUS_PCI_ROM + 3] << 24 | - nv4->nvbase.pci_config.pci_regs[NV4_PBUS_PCI_ROM + 2] << 16; - - // only bits 31;22 matter - //new_addr &= 0xFFC00000; - - // move it - mem_mapping_set_addr(&nv4->nvbase.vbios.mapping, new_addr, 0x8000); - - nv_log("...i like to move it move it (VBIOS Relocation) 0x%x -> 0x%x\n", old_addr, new_addr); - - } - else - { - nv_log("...VBIOS Enable\n"); - } - } - else - { - nv_log("...VBIOS Disable\n"); - mem_mapping_disable(&nv4->nvbase.vbios.mapping); - - } - break; - case NV4_PBUS_PCI_INTR_LINE: - nv4->nvbase.pci_config.int_line = val; - break; - // these are mirrored to the subsystem id and also stored in the ROMBIOS - //todo: port to pci - case NV4_PBUS_PCI_SUBSYSTEM_ID_WRITABLE: - case NV4_PBUS_PCI_SUBSYSTEM_ID_WRITABLE + 1: - case NV4_PBUS_PCI_SUBSYSTEM_VENDOR_ID_WRITABLE: - case NV4_PBUS_PCI_SUBSYSTEM_VENDOR_ID_WRITABLE + 1: - nv4->nvbase.pci_config.pci_regs[NV4_PBUS_PCI_SUBSYSTEM_ID + (addr & 0x03)] = val; - break; - case NV4_PBUS_AGP_COMMAND_2: - nv4->nvbase.agp_enabled = (val >> NV4_PBUS_AGP_COMMAND_2_AGP_ENABLED) & 0x01; - nv4->nvbase.agp_sba_enabled = (val >> NV4_PBUS_AGP_COMMAND_2_SBA_ENABLED) & 0x01; - break; - default: - break; - } -} - - -void nv4_speed_changed(void* priv) -{ - // sanity check - if (!nv4) - return; - - nv4_recalc_timings(&nv4->nvbase.svga); -} - -// Force Redraw -// Reset etc. -void nv4_force_redraw(void* priv) -{ - // sanity check - if (!nv4) - return; - - nv4->nvbase.svga.fullchange = changeframecount; -} - -// CHECK that ramin is the smae as nv4 - -// Read 8-bit ramin -uint8_t nv4_ramin_read8(uint32_t addr, void* priv) -{ - if (!nv4) return 0x00; - - addr &= (nv4->nvbase.svga.vram_max - 1); - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv4->nvbase.svga.vram_max - 0x10); - - uint32_t val = 0x00; - - //if (!nv4_ramin_arbitrate_read(addr, &val)) // Oh well - //{ - val = (uint8_t)nv4->nvbase.svga.vram[addr]; - nv_log_verbose_only("Read byte from PRAMIN addr=0x%08x (raw address=0x%08x)\n", addr, raw_addr); - //} - - return (uint8_t)val; -} - -// Read 16-bit ramin -uint16_t nv4_ramin_read16(uint32_t addr, void* priv) -{ - if (!nv4) return 0x00; - - addr &= (nv4->nvbase.svga.vram_max - 1); - - // why does this not work in one line - svga_t* svga = &nv4->nvbase.svga; - uint16_t* vram_16bit = (uint16_t*)svga->vram; - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv4->nvbase.svga.vram_max - 0x10); - addr >>= 1; // what - - uint32_t val = 0x00; - - //if (!nv4_ramin_arbitrate_read(addr, &val)) - //{ - val = (uint16_t)vram_16bit[addr]; - nv_log_verbose_only("Read word from PRAMIN addr=0x%08x (raw address=0x%08x)\n", addr, raw_addr); - //} - - return val; -} - -// Read 32-bit ramin -uint32_t nv4_ramin_read32(uint32_t addr, void* priv) -{ - if (!nv4) - return 0x00; - - addr &= (nv4->nvbase.svga.vram_max - 1); - - // why does this not work in one line - uint32_t* vram_32bit = (uint32_t*)nv4->nvbase.svga.vram; - uint32_t raw_addr = addr; // saved after and logged - - addr ^= (nv4->nvbase.svga.vram_max - 0x10); - addr >>= 2; // what - - uint32_t val = 0x00; - - //if (!nv4_ramin_arbitrate_read(addr, &val)) - //{ - val = vram_32bit[addr]; - nv_log_verbose_only("Read dword from PRAMIN 0x%08x <- 0x%08x (raw address=0x%08x)\n", val, addr, raw_addr); - //} - - return val; -} - -// Write 8-bit ramin -void nv4_ramin_write8(uint32_t addr, uint8_t val, void* priv) -{ - if (!nv4) return; - - addr &= (nv4->nvbase.svga.vram_max - 1); - uint32_t raw_addr = addr; // saved after and - - // Structures in RAMIN are stored from the bottom of vram up in reverse order - // this can be explained without bitwise math like so: - // real VRAM address = VRAM_size - (ramin_address - (ramin_address % reversal_unit_size)) - reversal_unit_size + (ramin_address % reversal_unit_size) - // reversal unit size in this case is 16 bytes, vram size is 2-8mb (but 8mb is zx/nv4t only and 2mb...i haven't found a 22mb card) - addr ^= (nv4->nvbase.svga.vram_max - 0x10); - - uint32_t val32 = (uint32_t)val; - - //if (!nv4_ramin_arbitrate_write(addr, val32)) - //{ - nv4->nvbase.svga.vram[addr] = val; - nv_log_verbose_only("Write byte to PRAMIN addr=0x%08x val=0x%02x (raw address=0x%08x)\n", addr, val, raw_addr); - //} -} - -// Write 16-bit ramin -void nv4_ramin_write16(uint32_t addr, uint16_t val, void* priv) -{ - if (!nv4) return; - - addr &= (nv4->nvbase.svga.vram_max - 1); - - // why does this not work in one line - svga_t* svga = &nv4->nvbase.svga; - uint16_t* vram_16bit = (uint16_t*)svga->vram; - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv4->nvbase.svga.vram_max - 0x10); - addr >>= 1; // what - - uint32_t val32 = (uint32_t)val; - - //if (!nv4_ramin_arbitrate_write(addr, val32)) - //{ - vram_16bit[addr] = val; - nv_log_verbose_only("Write word to PRAMIN addr=0x%08x val=0x%04x (raw address=0x%08x)\n", addr, val, raw_addr); - //} - - -} - -// Write 32-bit ramin -void nv4_ramin_write32(uint32_t addr, uint32_t val, void* priv) -{ - if (!nv4) return; - - addr &= (nv4->nvbase.svga.vram_max - 1); - - // why does this not work in one line - svga_t* svga = &nv4->nvbase.svga; - uint32_t* vram_32bit = (uint32_t*)svga->vram; - uint32_t raw_addr = addr; // saved after and - - addr ^= (nv4->nvbase.svga.vram_max - 0x10); - addr >>= 2; // what - - //if (!nv4_ramin_arbitrate_write(addr, val)) - //{ - vram_32bit[addr] = val; - nv_log_verbose_only("Write dword to PRAMIN addr=0x%08x val=0x%08x (raw address=0x%08x)\n", addr, val, raw_addr); - //} -} - -// Read from SVGA core memory -uint8_t nv4_svga_read(uint16_t addr, void* priv) -{ - // CR = CRTC Controller - // CRE = CRTC Controller Extended (weitek) - uint8_t ret = 0x00; - - // sanity check - if (!nv4) - return ret; - - // If we need to RMA from GPU MMIO, go do that - if (addr >= NV4_RMA_REGISTER_START - && addr <= NV4_RMA_REGISTER_END) - { - if (!(nv4->pbus.rma.mode & 0x01)) - return ret; - - // must be dword aligned - uint32_t real_rma_read_addr = ((nv4->pbus.rma.mode & 0x0E) << 1) + (addr & 0x03); - ret = nv4_rma_read(real_rma_read_addr); - return ret; - } - - // mask off b0/d0 registers - if ((((addr & 0xFFF0) == 0x3D0 - || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) - && !(nv4->nvbase.svga.miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - // Alias for "get current SVGA CRTC register ID" - case NV4_CIO_CRX_COLOR: - ret = nv4->nvbase.svga.crtcreg; - break; - case NV4_CIO_CR_COLOR: - // Support the extended NVIDIA CRTC register range - switch (nv4->nvbase.svga.crtcreg) - { - case NV4_CIO_CRE_RL0_INDEX: - ret = nv4->nvbase.svga.displine & 0xFF; - break; - /* Is rl1?*/ - case NV4_CIO_CRE_RL1_INDEX: - ret = (nv4->nvbase.svga.displine >> 8) & 7; - break; - case NV4_CIO_CRE_DDC_STATUS_INDEX: - ret = i2c_gpio_get_sda(nv4->nvbase.i2c) << 3 - | i2c_gpio_get_scl(nv4->nvbase.i2c) << 2; - - break; - default: - ret = nv4->nvbase.svga.crtc[nv4->nvbase.svga.crtcreg]; - } - break; - default: - ret = svga_in(addr, &nv4->nvbase.svga); - break; - } - - - return ret; //TEMP -} - -// Write to SVGA core memory -void nv4_svga_write(uint16_t addr, uint8_t val, void* priv) -{ - // sanity check - if (!nv4) - return; - - // If we need to RMA to GPU MMIO, go do that - if (addr >= NV4_RMA_REGISTER_START - && addr <= NV4_RMA_REGISTER_END) - { - // we don't need to store these registers... - nv4->pbus.rma.rma_regs[addr & 3] = val; - - if (!(nv4->pbus.rma.mode & 0x01)) // we are halfway through sending something - return; - - uint32_t real_rma_write_addr = ((nv4->pbus.rma.mode & (0x0E)) << 1) + (addr & 0x03); - - nv4_rma_write(real_rma_write_addr, nv4->pbus.rma.rma_regs[addr & 0x03]); - return; - } - - // mask off b0/d0 registers - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) - && addr < 0x3de) - && !(nv4->nvbase.svga.miscout & 1))//miscout bit 7 controls mappping - addr ^= 0x60; - - uint8_t crtcreg = nv4->nvbase.svga.crtcreg; - uint8_t old_val = 0x00; - - // todo: - // Pixel formats (8bit vs 555 vs 565) - // VBE 3.0? - - switch (addr) - { - case NV4_CIO_CRX_COLOR: - // real mode access to GPU MMIO space... - nv4->nvbase.svga.crtcreg = val; - break; - // support the extended crtc regs and debug this out - case NV4_CIO_CR_COLOR: - - // Implements the VGA Protect register - if ((nv4->nvbase.svga.crtcreg < NV4_CIO_CR_OVL_INDEX) && (nv4->nvbase.svga.crtc[NV4_CIO_CR_VRE_INDEX] & 0x80)) - return; - - // Ignore certain bits when VGA Protect register set and we are writing to CRTC register=07h - if ((nv4->nvbase.svga.crtcreg == NV4_CIO_CR_OVL_INDEX) && (nv4->nvbase.svga.crtc[NV4_CIO_CR_VRE_INDEX] & 0x80)) - val = (nv4->nvbase.svga.crtc[NV4_CIO_CR_OVL_INDEX] & ~0x10) | (val & 0x10); - - // set the register value... - old_val = nv4->nvbase.svga.crtc[crtcreg]; - - nv4->nvbase.svga.crtc[crtcreg] = val; - // ...now act on it - - // Handle nvidia extended Bank0/Bank1 IDs - switch (crtcreg) - { - case NV4_CIO_CRE_PAGE0_INDEX: - nv4->nvbase.cio_read_bank = val; - if (nv4->nvbase.svga.chain4) // chain4 addressing (planar?) - nv4->nvbase.svga.read_bank = nv4->nvbase.cio_read_bank << 15; - else - nv4->nvbase.svga.read_bank = nv4->nvbase.cio_read_bank << 13; // extended bank numbers - break; - case NV4_CIO_CRE_PAGE1_INDEX: - nv4->nvbase.cio_write_bank = val; - if (nv4->nvbase.svga.chain4) - nv4->nvbase.svga.write_bank = nv4->nvbase.cio_write_bank << 15; - else - nv4->nvbase.svga.write_bank = nv4->nvbase.cio_write_bank << 13; - break; - case NV4_CIO_CRE_RMA_INDEX: - nv4->pbus.rma.mode = val & NV4_PRMIO_RMA_MODE_MAX; - break; - /* Handle some large screen stuff */ - case NV4_CIO_CRE_PIXEL_INDEX: - if (val & 1 << (NV4_CIO_CRE_LSR_VDT_10)) - nv4->nvbase.svga.vtotal += 0x400; - if (val & 1 << (NV4_CIO_CRE_LSR_VRS_10)) - nv4->nvbase.svga.vblankstart += 0x400; - if (val & 1 << (NV4_CIO_CRE_LSR_VBS_10)) - nv4->nvbase.svga.vsyncstart += 0x400; - if (val & 1 << (NV4_CIO_CRE_LSR_HBE_6)) - nv4->nvbase.svga.hdisp += 0x400; - - /* Make sure dispend and vblankstart are right if we are displaying above 1024 vert */ - if (nv4->nvbase.svga.crtc[NV4_CIO_CRE_PIXEL_INDEX] & 1 << (NV4_CIO_CRE_LSR_VDE_10)) - nv4->nvbase.svga.dispend += 0x400; - - break; - case NV4_CIO_CRE_HEB_INDEX: // large screen bit - if (val & 0x01) - nv4->nvbase.svga.hdisp += 0x100; - break; - case NV4_CIO_CRE_DDC_WR_INDEX: - { - uint8_t scl = !!(val & 0x20); - uint8_t sda = !!(val & 0x10); - // Set an I2C GPIO register - i2c_gpio_set(nv4->nvbase.i2c, scl, sda); - break; - } - /* [6:0] contains cursorAddr [23:17] */ - case NV4_CIO_CRE_HCUR_ADDR0_INDEX: - nv4->pramdac.cursor_address |= (val & 0x7F) << 13; //bit7 technically ignored, but nv don't care, so neither do we - break; - /* [7:2] contains cursorAddr [16:11] */ - case NV4_CIO_CRE_HCUR_ADDR1_INDEX: - nv4->pramdac.cursor_address |= (val & 0xFC) << 5; // bit0 and 1 aren't part of the address - break; - - - } - - /* Recalculate the timings if we actually changed them - Additionally only do it if the value actually changed*/ - if (old_val != val) - { - // Thx to Fuel who basically wrote most of the SVGA compatibility code already (although I fixed some issues), because VGA is boring - // and in the words of an ex-Rendition/3dfx/NVIDIA engineer, "VGA was basically an undocumented bundle of steaming you-know-what. - // And it was essential that any cores the PC 3D startups acquired had to work with all the undocumented modes and timing tweaks (mode X, etc.)" - if (nv4->nvbase.svga.crtcreg < 0xE - || nv4->nvbase.svga.crtcreg > 0x10) - { - nv4->nvbase.svga.fullchange = changeframecount; - nv4_recalc_timings(&nv4->nvbase.svga); - } - } - - break; - default: - svga_out(addr, val, &nv4->nvbase.svga); - break; - } - -} - -/* DFB, sets up a dumb framebuffer */ -uint8_t nv4_dfb_read8(uint32_t addr, void* priv) -{ - addr &= (nv4->nvbase.svga.vram_mask); - return nv4->nvbase.svga.vram[addr]; -} - -uint16_t nv4_dfb_read16(uint32_t addr, void* priv) -{ - addr &= (nv4->nvbase.svga.vram_mask); - return (nv4->nvbase.svga.vram[addr + 1] << 8) | nv4->nvbase.svga.vram[addr]; -} - -uint32_t nv4_dfb_read32(uint32_t addr, void* priv) -{ - addr &= (nv4->nvbase.svga.vram_mask); - return (nv4->nvbase.svga.vram[addr + 3] << 24) | (nv4->nvbase.svga.vram[addr + 2] << 16) + - (nv4->nvbase.svga.vram[addr + 1] << 8) | nv4->nvbase.svga.vram[addr]; -} - -void nv4_dfb_write8(uint32_t addr, uint8_t val, void* priv) -{ - addr &= (nv4->nvbase.svga.vram_mask); - nv4->nvbase.svga.vram[addr] = val; - nv4->nvbase.svga.changedvram[addr >> 12] = val; - //nv4_render_current_bpp_dfb_8(addr); -} - -void nv4_dfb_write16(uint32_t addr, uint16_t val, void* priv) -{ - addr &= (nv4->nvbase.svga.vram_mask); - nv4->nvbase.svga.vram[addr + 1] = (val >> 8) & 0xFF; - nv4->nvbase.svga.vram[addr] = (val) & 0xFF; - nv4->nvbase.svga.changedvram[addr >> 12] = val; - - //nv4_render_current_bpp_dfb_16(addr); - -} - -void nv4_dfb_write32(uint32_t addr, uint32_t val, void* priv) -{ - addr &= (nv4->nvbase.svga.vram_mask); - nv4->nvbase.svga.vram[addr + 3] = (val >> 24) & 0xFF; - nv4->nvbase.svga.vram[addr + 2] = (val >> 16) & 0xFF; - nv4->nvbase.svga.vram[addr + 1] = (val >> 8) & 0xFF; - nv4->nvbase.svga.vram[addr] = (val) & 0xFF; - nv4->nvbase.svga.changedvram[addr >> 12] = val; - - //removed until there is a render pipeline - //nv4_render_current_bpp_dfb_32(addr); - -} - -/* Cursor shit */ -void nv4_draw_cursor(svga_t* svga, int32_t drawline) -{ - // sanity check - if (!nv4) - return; - - /* - Commented out until we have a real graphics pipeline going here - - // if cursor disabled is set, return - if ((nv4->nvbase.svga.crtc[NV4_CRTC_REGISTER_CURSOR_START] >> NV4_CRTC_REGISTER_CURSOR_START_DISABLED) & 0x01) - return; - - // NT GDI drivers: Load cursor using NV_IMAGE_FROM_MEMORY ("NV4LCD") - // 9x GDI drivers: Use H/W cursor in RAMIN - - // Do we need to emulate it? - - // THIS IS CORRECT. BUT HOW DO WE FIND IT? - uint32_t ramin_cursor_position = NV4_RAMIN_OFFSET_CURSOR; - - /* let's just assume buffer 0 here...that code needs to be totally rewritten - nv4_coord_16_t start_position = nv4->pramdac.cursor_start; - - /* refuse to draw if thge cursor is offscreen - if (start_position.x >= nv4->nvbase.svga.hdisp - || start_position.y >= nv4->nvbase.svga.dispend) - { - return; - } - - nv_log("nv4_draw_cursor start=0x%04x,0x%04x", start_position.x, start_position.y); - - uint32_t final_position = nv4_render_get_vram_address_for_buffer(start_position, 0); - - uint16_t* vram_16 = (uint16_t*)nv4->nvbase.svga.vram; - uint32_t* vram_32 = (uint32_t*)nv4->nvbase.svga.vram; - - /* - We have to get a 32x32, "A"1R5G5B5-format cursor - out of video memory. The alpha bit actually means - XOR with display pixel if 0, replace if 1 - - These are expanded to RGB10 only if they are XORed. We don't do this (we don't really need to + there is no grobj specified here so special casing - would be needed) so we just xor it with the current pixel format - - for (int32_t y = 0; y < NV4_PRAMDAC_CURSOR_SIZE_Y; y++) - { - for (int32_t x = 0; x < NV4_PRAMDAC_CURSOR_SIZE_X; x++) - { - uint16_t current_pixel = nv4_ramin_read16(ramin_cursor_position, nv4); - - // 0000 = transparent, so skip drawing - if (current_pixel) - { - bool replace_bit = (current_pixel & 0x8000); - - // use buffer 0 BPIXEL - uint32_t bpixel_format = (nv4->pgraph.bpixel[0]) & 0x03; - - switch (bpixel_format) - { - case bpixel_fmt_8bit: - if (replace_bit) - nv4->nvbase.svga.vram[final_position] = current_pixel; - else //xor - { - // not sure what to do here. we'd have to search through the palette to find the closest possible colour. - uint8_t final = current_pixel ^ nv4->nvbase.svga.vram[final_position]; - nv4->nvbase.svga.vram[final_position] = final; - } - case bpixel_fmt_16bit: // easy case (our cursor is 15bpp format) - uint32_t index_16 = final_position >> 1; - - if (replace_bit) // just replace - vram_16[index_16] = current_pixel; - else // xor - { - current_pixel &= ~0x8000; // mask off the xor bit - uint16_t final = current_pixel ^ vram_16[index_16]; - vram_16[index_16] = final; - } - case bpixel_fmt_32bit: - uint32_t index_32 = final_position >> 2; - - if (replace_bit) // just replace - vram_32[index_32] = nv4->nvbase.svga.conv_16to32(&nv4->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here - else //xor - { - current_pixel &= ~0x8000; // mask off the xor bit - uint32_t current_pixel_32 = nv4->nvbase.svga.conv_16to32(&nv4->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here - - uint32_t final = current_pixel_32 ^ vram_32[index_32]; - vram_32[index_32] = final; - } - break; - } - } - - // increment vram position - ramin_cursor_position += 2; - - // go - switch (nv4->nvbase.svga.bpp) - { - case 8: - final_position++; - case 15 ... 16: - final_position += 2; - break; - case 32: - final_position += 4; - break; - } - - start_position.x++; - } - - - start_position.y++; - start_position.x = nv4->pramdac.cursor_start.x; - - // reset at the end of each line so we "jump" to the start x - final_position = nv4_render_get_vram_address_for_buffer(start_position, 0); - }*/ -} - -// MMIO 0x110000->0x111FFF is mapped to a mirror of the VBIOS. -// Note this area is 64kb and the vbios is only 32kb. See below.. - -uint8_t nv4_prom_read(uint32_t address) -{ - // prom area is 64k, so... - // first see if we even have a rom of 64kb in size - uint32_t max_rom_size = NV4_PROM_END - NV4_PROM_START; - uint32_t real_rom_size = max_rom_size; - - // set it - if (nv4->nvbase.vbios.sz < max_rom_size) - real_rom_size = nv4->nvbase.vbios.sz; - - //get our real address - uint8_t rom_address = address & max_rom_size; - - // Does this mirror on real hardware? - if (rom_address >= real_rom_size) - { - nv_log("PROM VBIOS Read to INVALID address 0x%05x, returning 0xFF", rom_address); - return 0xFF; - } - else - { - uint8_t val = nv4->nvbase.vbios.rom[rom_address]; - nv_log("PROM VBIOS Read 0x%05x <- 0x%05x", val, rom_address); - return val; - } -} - -void nv4_prom_write(uint32_t address, uint32_t value) -{ - uint32_t real_addr = address & 0x1FFFF; - nv_log("What's going on here? Tried to write to the Video BIOS ROM? (Address=0x%05x, value=0x%02x)", real_addr, value); -} diff --git a/src/video/nv/nv4/nv4_debug_register_list.c b/src/video/nv/nv4/nv4_debug_register_list.c deleted file mode 100644 index 32516be0c..000000000 --- a/src/video/nv/nv4/nv4_debug_register_list.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * NV4 debug register list - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/io.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv4.h> - -#ifdef NV_LOG - -nv_register_t nv4_registers[] = { - { NV4_PTIMER_INTR, "NV4 PTIMER - Interrupt Status", NULL, NULL}, - { NV4_PTIMER_INTR_EN, "NV4 PTIMER - Interrupt Enable", NULL, NULL,}, - { NV4_PTIMER_NUMERATOR, "NV4 PTIMER - Numerator", NULL, NULL, }, - { NV4_PTIMER_DENOMINATOR, "NV4 PTIMER - Denominator", NULL, NULL, }, - { NV4_PTIMER_TIME_0_NSEC, "NV4 PTIMER - Time0", NULL, NULL, }, - { NV4_PTIMER_TIME_1_NSEC, "NV4 PTIMER - Time1", NULL, NULL, }, - { NV4_PTIMER_ALARM_NSEC, "NV4 PTIMER - Alarm", NULL, NULL, }, - { NV4_PRAMDAC_VPLL_COEFF, "NV4 PRAMDAC - Pixel Clock Coefficient", NULL, NULL, }, - { NV4_PRAMDAC_NVPLL_COEFF, "NV4 PRAMDAC - GPU Core Clock Coefficient", NULL, NULL, }, - { NV4_PRAMDAC_MPLL_COEFF, "NV4 PRAMDAC - VRAM Clock Coefficient", NULL, NULL, }, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -#endif \ No newline at end of file diff --git a/src/video/nv/nv4/subsystems/nv4_pramdac.c b/src/video/nv/nv4/subsystems/nv4_pramdac.c deleted file mode 100644 index 0b8292796..000000000 --- a/src/video/nv/nv4/subsystems/nv4_pramdac.c +++ /dev/null @@ -1,84 +0,0 @@ -/* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* NV4/Riva TNT - RAMDAC -* -* -* Authors: Connor Hyde, I need a better email address ;^) -* -* Copyright 2024-2025 starfrost -*/ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv4.h> - - -uint64_t nv4_pramdac_get_hz(uint32_t coeff, bool apply_divider) -{ - uint32_t m = coeff & 0xFF; - uint32_t n = (coeff >> 8) & 0xFF; - uint32_t p = (coeff >> 16) & 0x07; - - // Check clock base - uint32_t hz_base = (nv4->straps & (1 << NV4_STRAP_CRYSTAL)) ? 14318180 : 13500000; - uint32_t final_hz = (hz_base * n) / (m << p); - - // Check VCLK divider - - if (apply_divider) - { - if (nv4->pramdac.clk_coeff_select & (1 << NV4_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO)) - final_hz >>= 1; - } - - return final_hz; -} - -void nv4_pramdac_set_vclk() -{ - uint64_t final_hz = nv4_pramdac_get_hz(nv4->pramdac.nvclk, false); - - //TODO: Everything - if (nv4->nvbase.nv4_vclk_timer) - timer_set_delay_u64(nv4->nvbase.nv4_vclk_timer, final_hz / TIMER_USEC); - -} - -uint32_t nv4_pramdac_read(uint32_t address) -{ - uint32_t ret = 0x00; - - switch (address) - { - case NV4_PRAMDAC_VPLL_COEFF: // Pixel clock - ret = nv4->pramdac.vclk; - break; - case NV4_PRAMDAC_NVPLL_COEFF: // System clock - ret = nv4->pramdac.nvclk; - break; - case NV4_PRAMDAC_MPLL_COEFF: // Memory clock - ret = nv4->pramdac.mclk; - break; - - } -} - -void nv4_pramdac_write(uint32_t address, uint32_t data) -{ - -} diff --git a/src/video/nv/nv4/subsystems/nv4_ptimer.c b/src/video/nv/nv4/subsystems/nv4_ptimer.c deleted file mode 100644 index 29df0168b..000000000 --- a/src/video/nv/nv4/subsystems/nv4_ptimer.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Nvidia RIVA TNT (NV4 architecture) - Timer emulation - * - * - * - * Authors: Connor Hyde, - * - * Copyright 2024-2025 starfrost - */ - -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/pci.h> -#include <86box/rom.h> // DEPENDENT!!! -#include <86box/video.h> -#include <86box/nv/vid_nv.h> -#include <86box/nv/vid_nv4.h> - -nv_register_t ptimer_registers[] = { - { NV4_PTIMER_INTR, "NV4 PTIMER - Interrupt Status", NULL, NULL}, - { NV4_PTIMER_INTR_EN, "NV4 PTIMER - Interrupt Enable", NULL, NULL,}, - { NV4_PTIMER_NUMERATOR, "NV4 PTIMER - Numerator", NULL, NULL, }, - { NV4_PTIMER_DENOMINATOR, "NV4 PTIMER - Denominator", NULL, NULL, }, - { NV4_PTIMER_TIME_0_NSEC, "NV4 PTIMER - Time0", NULL, NULL, }, - { NV4_PTIMER_TIME_1_NSEC, "NV4 PTIMER - Time1", NULL, NULL, }, - { NV4_PTIMER_ALARM_NSEC, "NV4 PTIMER - Alarm", NULL, NULL, }, - { NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value -}; - -// ptimer init code -void nv4_ptimer_init(void) -{ - nv_log("Initialising PTIMER..."); - - nv_log("Done!\n"); -} - -// Handles the PTIMER alarm interrupt -void nv4_ptimer_interrupt(uint32_t num) -{ - nv4->ptimer.interrupt_status |= (1 << num); - - //todo - //nv4_pmc_handle_interrupts(true); -} - -// Ticks the timer. -void nv4_ptimer_tick(double real_time) -{ - // prevent a divide by zero - if (nv4->ptimer.clock_numerator == 0 - || nv4->ptimer.clock_denominator == 0) - return; - - // get the current time - - // See Envytools. We need to use the frequency as a source. - // We need to figure out how many cycles actually occurred because this counts up every cycle... - // However it seems that their formula is wrong. I can't be bothered to figure out what's going on and, based on documentation from NVIDIA, - // timer_0 is meant to roll over every 4 seconds. Multiplying by 10 basically does the job. - - // Convert to microseconds - double freq_base = (real_time / 1000000.0f) / ((double)1.0 / nv4->nvbase.memory_clock_frequency) * 10.0f; - double current_time = freq_base * ((double)nv4->ptimer.clock_numerator) / (double)nv4->ptimer.clock_denominator; // *10.0? - - // truncate it - nv4->ptimer.time += (uint64_t)current_time; - - // Check if the alarm has actually triggered.. - // Only log on ptimer alarm. Otherwise, it's too much spam. - if (nv4->ptimer.time >= nv4->ptimer.alarm) - { - nv_log_verbose_only("PTIMER alarm interrupt fired (if interrupts enabled) because we reached TIME value 0x%08x\n", nv4->ptimer.alarm); - nv4_ptimer_interrupt(NV4_PTIMER_INTR_ALARM); - } -} - -uint32_t nv4_ptimer_read(uint32_t address) -{ - // always enabled - - nv_register_t* reg = nv_get_register(address, ptimer_registers, sizeof(ptimer_registers)/sizeof(ptimer_registers[0])); - - // Only log these when tehy actually tick - if (address != NV4_PTIMER_TIME_0_NSEC - && address != NV4_PTIMER_TIME_1_NSEC) - { - nv_log_verbose_only("PTIMER Read from 0x%08x", address); - } - - uint32_t ret = 0x00; - - // if the register actually exists - if (reg) - { - // on-read function - if (reg->on_read) - ret = reg->on_read(); - else - { - // Interrupt state: - // Bit 0: Alarm - - switch (reg->address) - { - case NV4_PTIMER_INTR: - ret = nv4->ptimer.interrupt_status; - break; - case NV4_PTIMER_INTR_EN: - ret = nv4->ptimer.interrupt_enable; - break; - case NV4_PTIMER_NUMERATOR: - ret = nv4->ptimer.clock_numerator; // 15:0 - break; - case NV4_PTIMER_DENOMINATOR: - ret = nv4->ptimer.clock_denominator ; //15:0 - break; - // 64-bit value - // High part - case NV4_PTIMER_TIME_0: - ret = nv4->ptimer.time & 0xFFFFFFFF; //28:0 - break; - // Low part - case NV4_PTIMER_TIME_1: - ret = nv4->ptimer.time >> 32; // 31:5 - break; - case NV4_PTIMER_ALARM: - ret = nv4->ptimer.alarm; // 31:5 - break; - } - - } - //TIME0 and TIME1 produce too much log spam that slows everything down - if (reg->address != NV4_PTIMER_TIME_0_NSEC - && reg->address != NV4_PTIMER_TIME_1_NSEC) - { - if (reg->friendly_name) - nv_log_verbose_only(": 0x%08x <- %s\n", ret, reg->friendly_name); - else - nv_log_verbose_only("\n"); - } - } - else - { - nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address); - } - - return ret; -} - -void nv4_ptimer_write(uint32_t address, uint32_t value) -{ - // before doing anything, check the subsystem enablement - nv_register_t* reg = nv_get_register(address, ptimer_registers, sizeof(ptimer_registers)/sizeof(ptimer_registers[0])); - - nv_log_verbose_only("PTIMER Write 0x%08x -> 0x%08x", value, address); - - // if the register actually exists - if (reg) - { - if (reg->friendly_name) - nv_log_verbose_only(": %s\n", reg->friendly_name); - else - nv_log_verbose_only("\n"); - - // on-read function - if (reg->on_write) - reg->on_write(value); - else - { - switch (reg->address) - { - // Interrupt state: - // Bit 0 - Alarm - - case NV4_PTIMER_INTR: - nv4->ptimer.interrupt_status &= ~value; - //TODO nv4_pmc_clear_interrupts(); - break; - - // Interrupt enablement state - case NV4_PTIMER_INTR_EN: - nv4->ptimer.interrupt_enable = value & 0x1; - break; - // nUMERATOR - case NV4_PTIMER_NUMERATOR: - nv4->ptimer.clock_numerator = value & 0xFFFF; // 15:0 - break; - case NV4_PTIMER_DENOMINATOR: - // prevent Div0 - if (!value) - value = 1; - - nv4->ptimer.clock_denominator = value & 0xFFFF; //15:0 - break; - // 64-bit value - // High part - case NV4_PTIMER_TIME_0: - nv4->ptimer.time |= (value) & 0xFFFFFFE0; //28:0 - break; - // Low part - case NV4_PTIMER_TIME_1: - nv4->ptimer.time |= ((uint64_t)(value & 0xFFFFFFE0) << 32); // 31:5 - break; - case NV4_PTIMER_ALARM: - nv4->ptimer.alarm = value & 0xFFFFFFE0; // 31:5 - break; - } - } - } - else /* Completely unknown */ - { - nv_log(": Unknown register write (address=0x%08x)\n", address); - } -} \ No newline at end of file diff --git a/src/video/nv/nv_base.c b/src/video/nv/nv_base.c deleted file mode 100644 index c7a83d5ad..000000000 --- a/src/video/nv/nv_base.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Base file for emulation of NVidia video cards. - * - * - * - * Authors: Connor Hyde, I need a better email address ;^) - * - * Copyright 2024-2025 starfrost - */ - -// Common NV1/3/4... init -#define HAVE_STDARG_H // wtf is this crap -#include -#include -#include -#include -#include <86box/86box.h> -#ifndef RELEASE_BUILD -#include <86box/device.h> -#endif -#include <86box/log.h> - - -// Common logging -#ifdef ENABLE_NV_LOG -int nv_do_log = ENABLE_NV_LOG; - -// A bit of kludge so that in the future we can abstract this function acorss multiple generations of Nvidia GPUs -void* nv_log_device; -bool nv_log_full = false; - -void nv_log_set_device(void* device) -{ - // in case the cyclical logger doesn't show you the full context of what went on, you can enable this debug feature - #ifndef RELEASE_BUILD - if (device - && device_get_config_int("nv_debug_fulllog")) - { - nv_log_full = true; - } - #endif - - nv_log_device = device; -} - -void nv_log_internal(const char* fmt, va_list arg) -{ - if (!nv_log_device) - return; - - // If our debug config option is configured, full log. Otherwise log with cyclical detection. - if (nv_log_full) - log_out(nv_log_device, fmt, arg); - else - log_out_cyclic(nv_log_device, fmt, arg); - -} - -void nv_log(const char *fmt, ...) -{ - va_list arg; - - if (!nv_do_log) - return; - - va_start(arg, fmt); - nv_log_internal(fmt, arg); - va_end(arg); -} - -void nv_log_verbose_only(const char *fmt, ...) -{ - #ifdef ENABLE_NV_LOG_ULTRA - va_list arg; - - if (!nv_do_log) - return; - - va_start(arg, fmt); - nv_log_internal(fmt, arg); - va_end(arg); - #endif -} - -#else -void nv_log(const char *fmt, ...) -{ - -} - -void nv_log_verbose_only(const char *fmt, ...) -{ - -} - -void nv_log_set_device(void* device) -{ - -} -#endif \ No newline at end of file diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 3ea8a0358..4e76e150d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -262,13 +262,6 @@ video_cards[] = { { .device = &compaq_voodoo_3_3500_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &voodoo_3_3500_se_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &voodoo_3_3500_si_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nv1_device_edge2k, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nv1_device_edge3k, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nv3_device_agp, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nv3_device_pci, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nv3t_device_agp, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nv3t_device_pci, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nv4_device_agp, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = NULL, .flags = VIDEO_FLAG_TYPE_NONE } // clang-format on }; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 7ee3d9ae7..fe02b7811 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -675,7 +675,7 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) default: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) { - voodoo_log(": Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); + voodoo_log("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); } else { voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); }