mirror of
https://github.com/86Box/86Box.git
synced 2026-02-24 20:35:32 -07:00
Initial VBLANK draft. Still fucked up
This commit is contained in:
29
doc/NV_PFB_CONFIG_0.txt
Normal file
29
doc/NV_PFB_CONFIG_0.txt
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user