Initial VBLANK draft. Still fucked up

This commit is contained in:
starfrost013
2024-12-01 20:56:42 +00:00
parent 1c14718677
commit b816a7d379
8 changed files with 171 additions and 37 deletions

29
doc/NV_PFB_CONFIG_0.txt Normal file
View File

@@ -0,0 +1,29 @@
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

View File

@@ -98,8 +98,10 @@ rmInitRm -> initGrPatchPool Success
rmInitRm -> initDmaListElementPool Success
rmInitRm -> initDisplayInfo Success
rmInitRm overall Success
NvFindAdapter Failing (EAX=87)
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
NvFindAdapter -> RmPostNvDevice Success 17:32 27/11/2024
NvFindAdapter -> NVGetNVInfo Success 17:32 27/11/2024
NvFindAdapter -> NVMapFrameBuffer Success 17:32 27/11/2024

View File

@@ -158,6 +158,8 @@ typedef struct nv3_straps_s
typedef struct nv3_pfb_s
{
uint32_t boot;
uint32_t config_0;
uint32_t config_1;
} nv3_pfb_t;
#define NV3_RMA_NUM_REGS 4
@@ -460,6 +462,7 @@ uint32_t nv3_pmc_handle_interrupts(bool send_now);
// NV3 PGRAPH
void nv3_pgraph_init();
void nv3_pgraph_vblank_start(svga_t* svga);
// NV3 PFIFO
void nv3_pfifo_init();

View File

@@ -34,6 +34,8 @@ extern nv3_t* nv3;
#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_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_DIAMOND_V330_V182B "roms/video/nvidia/nv3/nv3t182b.rom" // Diamond Multimedia Viper V330 8M BIOS - Version 1.82B
// Temporary, will be loaded from settings
#define VRAM_SIZE_2MB 0x200000 // 2MB
@@ -113,6 +115,7 @@ extern nv3_t* nv3;
#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
@@ -138,6 +141,23 @@ extern nv3_t* nv3;
#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
@@ -189,6 +209,32 @@ extern nv3_t* nv3;
#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_CONFIG_0 0x100200 // Framebuffer interface config register 0
#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
@@ -238,6 +284,7 @@ extern nv3_t* nv3;
#define NV3_PGRAPH_INTR_0 0x400100
#define NV3_PGRAPH_INTR_1 0x400104
#define NV3_PGRAPH_INTR_EN_0 0x400140 // Interrupt Control for PGRAPH #1
#define NV3_PGRAPH_INTR_EN_0_VBLANK 8 // Fired every frame
//todo: add what this does
#define NV3_PGRAPH_INTR_EN_1 0x400180 // Interrupt Control for PGRAPH #2 (it can receive two at onc)
@@ -384,26 +431,6 @@ extern nv3_t* nv3;
// Master Control
#define NV3_PMC_BOOT 0x0
#define NV3_PMC_INTERRUPT 0x100
#define NV3_PMC_INTERRUPT_ENABLE 0x140
#define NV3_PMC_ENABLE 0x200
#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
#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
// CRTC/CIO (0x3b0-0x3df)

View File

@@ -67,6 +67,8 @@ uint32_t nv3_mmio_arbitrate_read(uint32_t address)
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)

View File

@@ -28,8 +28,14 @@
#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 nv3_pfb_config0_write(uint32_t val);
nv_register_t pfb_registers[] = {
{ NV3_PFB_BOOT, "PFB Boot Config", 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 },
{ NV_REG_LIST_END, NULL, NULL, NULL}, // sentinel value
};
@@ -78,7 +84,8 @@ uint32_t nv3_pfb_read(uint32_t address)
{
case NV3_PFB_BOOT:
return nv3->pfb.boot;
break;
case NV3_PFB_CONFIG_1:
return nv3->pfb.config_1;
}
}
}
@@ -90,7 +97,7 @@ 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("NV3: PFB Write 0x%08x -> 0x%08x\n", value, address);
nv_log("NV3: PFB Write 0x%08x -> 0x%08x", value, address);
// if the register actually exists
if (reg)
@@ -103,7 +110,40 @@ void nv3_pfb_write(uint32_t address, uint32_t value)
// on-read function
if (reg->on_write)
reg->on_write(value);
else
{
switch (reg->address)
{
case NV3_PFB_CONFIG_1: // Config Register 1
nv3->pfb.config_1 = value;
}
}
}
}
uint32_t nv3_pfb_config0_read()
{
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;
uint32_t new_bit_depth = (nv3->pfb.config_0 >> 8) & 0x03;
nv_log("NV3: Framebuffer Config Change\n");
nv_log("NV3: Horizontal Size=%d pixels\n", new_pfb_htotal);
if (new_bit_depth == NV3_PFB_CONFIG_0_DEPTH_8BPP)
nv_log("NV3: Bit Depth=8bpp\n");
else if (new_bit_depth == NV3_PFB_CONFIG_0_DEPTH_16BPP)
nv_log("NV3: Bit Depth=16bpp\n");
else if (new_bit_depth == NV3_PFB_CONFIG_0_DEPTH_32BPP)
nv_log("NV3: Bit Depth=32bpp\n");
}

View File

@@ -28,19 +28,20 @@
#include <86Box/nv/vid_nv.h>
#include <86Box/nv/vid_nv3.h>
// Single unified write function...
// Initialise the PGRAPH subsystem.
void nv3_pgraph_init()
{
nv_log("NV3: Initialising PGRAPH...");
// Set up the vblank interrupt
nv3->nvbase.svga.vblank_start = nv3_pgraph_vblank_start;
nv_log("Done!\n");
}
//
// ****** PGRAPH register list START ******
//
void nv3_pgraph_init()
{
nv_log("NV3: Initialising PGRAPH...");
nv_log("Done!\n");
}
nv_register_t pgraph_registers[] = {
{ NV3_PGRAPH_INTR_0, "PGRAPH Interrupt Status 0", NULL, NULL },
{ NV3_PGRAPH_INTR_EN_0, "PGRAPH Interrupt Enable 0", NULL, NULL },
@@ -141,11 +142,27 @@ void nv3_pgraph_write(uint32_t address, uint32_t value)
// 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;
}
}
}
}
// 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_enable_0 |= (1 << num);
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_EN_0_VBLANK);
}

View File

@@ -35,6 +35,7 @@ void nv3_pmc_init()
nv_log("NV3: Initialising PMC....\n");
nv3->pmc.boot = NV3_BOOT_REG_DEFAULT;
nv3->pmc.interrupt_enable = NV3_PMC_INTERRUPT_ENABLE_HARDWARE | NV3_PMC_INTERRUPT_ENABLE_HARDWARE;
nv_log("NV3: Initialising PMC: Done\n");
}
@@ -113,11 +114,23 @@ uint32_t nv3_pmc_handle_interrupts(bool send_now)
// 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)
@@ -213,8 +226,8 @@ void nv3_pmc_write(uint32_t address, uint32_t value)
switch (reg->address)
{
case NV3_PMC_INTERRUPT_STATUS:
// this
if (!(nv3->pmc.interrupt_status & (NV3_PMC_INTERRUPT_SOFTWARE - 1)))
// This can only be done by software interrupts...
if (!(nv3->pmc.interrupt_status & 0x7FFFFFFF))
{
nv_log("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);
@@ -225,7 +238,8 @@ void nv3_pmc_write(uint32_t address, uint32_t value)
nv3->pmc.interrupt_status = value;
break;
case NV3_PMC_INTERRUPT_ENABLE:
nv3->pmc.interrupt_enable = value;
nv3->pmc.interrupt_enable = value & 0x03;
nv3_pmc_handle_interrupts(value != 0);
break;
case NV3_PMC_ENABLE:
nv3->pmc.enable = value;