various logging/pfifo fixes, add pfifo ctx

This commit is contained in:
starfrost013
2025-02-02 00:43:27 +00:00
parent 4e001ae171
commit f568737083
12 changed files with 66 additions and 85 deletions

View File

@@ -1,57 +0,0 @@
Object classes
NOT represented by the GPU. These are the ones the drivers recognise. Most of them are faked.
Version 0.77_win95 (!!!)
object class 1 = "general" methods shared across all objects
object class 2 = DMA from memory
object class 3 = DMA to memory
object class 4 = timer
object class 5 = chip ID
object class 6 = "context ordinal"
object class 10/0Ah = patchcord (links objects together)
object class 11/0Bh = video sink
object class 12/0Ch = video switch
object class 13/0Dh = video colormap
object class 14/0Eh = patchcord...again
object class 15/0Fh = image to video
object class 16/10h = image stencil buffer
object class 17/11h = image blending methods
object class 18/12h = beta solid
object class 19/13h = image -> render operation
object class 20/14h = ROP5 (2^5 = 32bit rop)
object class 21/15h = color key
object class 22/16h = plane switch
object class 23/17h = "solid image"
object class 24/18h = pattern
object class 25/19h = black rectangle
object class 26/1Ah = solid point
object class 27/1Bh = solid line
object class 28/1Ch = solid lin (line without its ending or starting pixel)
object class 29/1Dh = triangle
object class 30/1Eh = solid rectangle
object class 31/1Fh = blit image
object class 33/21h = get image from cpu
object class 34/22h = get image from cpu, monochrome
object class 37/25h = get image from local GPU memory
object class 49/31h and 51/33h = patchcord, again
object class 54/36h = get image from cpu, stretched
object class 55/37h = get image from vram, scaled
object class 56/38h = get image from vram, scaled, YUV 420 color space (probably internal colour space used for rendering)
object class 57/39h = convert image(?) between formats in place in vram, allows you to set an in and out buffer and all that jazz
object class 61/3Dh = In-Memory DMA (vram to vram?)
object class 62/3Eh = get image from vram
object class 63/3Fh = get video from vram
object class 64/40h = video scaler
object class 65/41h = video color key (as opposed to image)
object class 66/42h = capture video to memory
object class 67/43h = Solid ROP5
object class 68/44h = zeta buffer (combined z and stencil buffer) from CPU(?)
object class 69/45h = zeta buffer in VRAM
object class 70/46h = zeta buffer patchcord
object class 71/47h = render solid point into zeta buffer (Also rectangle0
object class 72/48h = render Direct3D 5.x ("D3D0") accelerated triangle into zeta buffer
object class 73/49h = render Direct3D 5.x ("D3D0") accelerated triangle
object class 74/4Ah = video source
object class 75/4Bh = render Windows GDI accelerated rectangle and text

View File

@@ -14,7 +14,7 @@
* Also check the doc folder for some more notres
*
* vid_nv3.h: NV3 Architecture Hardware Reference (open-source)
* Last updated: 30 January 2025 (STILL WORKING ON IT!!!)
* Last updated: 2 February 2025 (STILL WORKING ON IT!!!)
*
* Authors: Connor Hyde <mario64crashed@gmail.com>
*
@@ -272,11 +272,14 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_CACHE0_PULLER_CONTROL 0x3040
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_ENABLED 0
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_HASH_FAILURE 4
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD 8
#define NV3_PFIFO_CACHE0_PULLER_CONTROL_SOFTWARE_METHOD 8
#define NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY 0x3050
#define NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY_BOOL 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 0x3100
#define NV3_PFIFO_CACHE0_METHOD_ADDRESS 2 // 12:2
#define NV3_PFIFO_CACHE0_METHOD_SUBCHANNEL 13 // 15:13
@@ -306,6 +309,11 @@ extern const device_config_t nv3_config[];
#define NV3_PFIFO_CACHE1_PULLER_CTX_IS_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 0x3300
#define NV3_PFIFO_CACHE1_METHOD_ADDRESS 2 // 12:2
#define NV3_PFIFO_CACHE1_METHOD_SUBCHANNEL 13 // 15:13
@@ -797,11 +805,11 @@ typedef struct nv3_pfifo_cache_s
bool access_enabled; // 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.
uint8_t channel; // The DMA channel ID of this cache.
uint32_t status;
uint32_t puller_control;
uint32_t control;
uint32_t context[NV3_DMA_SUBCHANNELS_PER_CHANNEL];
uint32_t context[NV3_DMA_SUBCHANNELS_PER_CHANNEL]; // Only one of these exists for cache0
/* cache1 only
do we even need to emulate this?

View File

@@ -75,7 +75,7 @@ uint32_t nv3_pbus_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}

View File

@@ -113,7 +113,7 @@ uint32_t nv3_pextdev_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}

View File

@@ -90,7 +90,7 @@ uint32_t nv3_pfb_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}

View File

@@ -41,6 +41,7 @@ nv_register_t pfifo_registers[] = {
{ 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_PULLER_CONTROL, "PFIFO - Cache0 Puller Control", NULL, NULL},
{ NV3_PFIFO_CACHE1_PULLER_CONTROL, "PFIFO - Cache1 Puller Control"},
{ NV3_PFIFO_CACHE0_PULLER_CTX_IS_DIRTY, "PFIFO - Cache0 Puller State1 (Is context clean?)", NULL, NULL},
@@ -231,21 +232,34 @@ uint32_t nv3_pfifo_read(uint32_t address)
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;
/* Cache1 is handled below */
case NV3_PFIFO_CACHE0_CTX:
ret = nv3->pfifo.cache0_settings.context[0];
break;
}
}
if (reg->friendly_name)
nv_log(": %s\n", reg->friendly_name);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\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("PFIFO Cache1 CTX Read Entry=%d Value=0x%04x", ctx_entry_id, ret);
}
else
{
nv_log(": Unknown register read (address=0x%08x), returning 0x00\n", address);
@@ -267,16 +281,11 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
nv_register_t* reg = nv_get_register(address, pfifo_registers, sizeof(pfifo_registers)/sizeof(pfifo_registers[0]));
nv_log("NV3: PFIFO Write 0x%08x -> 0x%08x\n", value, address);
nv_log("NV3: PFIFO Write 0x%08x -> 0x%08x", value, address);
// if the register actually exists
if (reg)
{
if (reg->friendly_name)
nv_log(": %s\n", reg->friendly_name);
else
nv_log("\n");
// on-read function
if (reg->on_write)
reg->on_write(value);
@@ -293,9 +302,15 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
case NV3_PFIFO_INTR:
nv3->pfifo.interrupt_status &= ~value;
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->pbus.interrupt_enable = value & 0x00001111;
nv3->pfifo.interrupt_enable = value & 0x00001111;
nv3_pmc_handle_interrupts(true);
break;
case NV3_PFIFO_DELAY_0:
nv3->pfifo.dma_delay_retry = value;
@@ -426,10 +441,26 @@ void nv3_pfifo_write(uint32_t address, uint32_t value)
else
nv3->pfifo.runout_put = ((value & 0x3FF) << 3);
break;
/* Cache1 is handled below */
case NV3_PFIFO_CACHE0_CTX:
nv3->pfifo.cache0_settings.context[0] = value;
break;
}
}
}
if (reg->friendly_name)
nv_log(": %s\n", reg->friendly_name);
else
nv_log("\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;
nv3->pfifo.cache1_settings.context[ctx_entry_id] = value;
nv_log("PFIFO Cache1 CTX Write Entry=%d value=0x%04x", ctx_entry_id, value);
}
}
/*

View File

@@ -140,9 +140,11 @@ uint32_t nv3_pgraph_read(uint32_t address)
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
@@ -243,7 +245,7 @@ uint32_t nv3_pgraph_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}
@@ -457,5 +459,5 @@ void nv3_pgraph_vblank_start(svga_t* svga)
void nv3_pgraph_submit()
{
}

View File

@@ -211,7 +211,7 @@ uint32_t nv3_pmc_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}

View File

@@ -77,7 +77,7 @@ uint32_t nv3_pme_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}

View File

@@ -285,7 +285,7 @@ uint32_t nv3_pramdac_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}

View File

@@ -76,14 +76,11 @@ void nv3_ptimer_tick(double real_time)
double current_time = freq_base * ((double)nv3->ptimer.clock_numerator * NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT) / (double)nv3->ptimer.clock_denominator; // *10.0?
// Logging is suppressed when reading this register because it is read many times
// So we only log when we update.
// truncate it
nv3->ptimer.time += (uint64_t)current_time;
nv_log("PTIMER time ticked (The value is now 0x%08x)\n", nv3->ptimer.time);
// Only log on ptimer alarm. Otherwise, it's too much spam.
//nv_log("PTIMER time ticked (The value is now 0x%08x)\n", nv3->ptimer.time);
// Check if the alarm has actually triggered...
if (nv3->ptimer.time >= nv3->ptimer.alarm)
@@ -153,7 +150,7 @@ uint32_t nv3_ptimer_read(uint32_t address)
&& reg->address != NV3_PTIMER_TIME_1_NSEC)
{
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}

View File

@@ -82,7 +82,7 @@ uint32_t nv3_pvideo_read(uint32_t address)
}
if (reg->friendly_name)
nv_log(": %s (value = 0x%08x)\n", reg->friendly_name, ret);
nv_log(": 0x%08x <- %s\n", ret, reg->friendly_name);
else
nv_log("\n");
}