diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h
index c89f2e9b2..632ee01fa 100644
--- a/src/include/86box/nv/vid_nv3.h
+++ b/src/include/86box/nv/vid_nv3.h
@@ -463,13 +463,6 @@ extern const device_config_t nv3t_config[]; // Confi
#define NV3_PME_INTR_EN 0x200140 // Mediaport: Interrupt Enable
#define NV3_PME_END 0x200FFF
-// THIS IS NOT A REAL REGISTER.
-// This is so my software e.g. nvplayground can determine if the software is being run in an emulator on a real RIVA 128.
-// This register should have some sort of open bus, garbage or 00/FF on a real NV3/NV3T but have a string.
-#define NV3_EMULATED_MARKER_START 0x269420
-
-#define NV3_EMULATED_MARKER 0x0D15EA5E
-
#define NV3_PGRAPH_START 0x400000 // Scene graph for 2d/3d rendering...the most important part
// PGRAPH Core
@@ -800,6 +793,10 @@ extern const device_config_t nv3t_config[]; // Confi
#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
diff --git a/src/qt/qt_gpudebug_visualnv.ui b/src/qt/qt_gpudebug_visualnv.ui
index e103ff03e..313df859d 100644
--- a/src/qt/qt_gpudebug_visualnv.ui
+++ b/src/qt/qt_gpudebug_visualnv.ui
@@ -6,7 +6,7 @@
0
0
- 600
+ 620
350
@@ -18,13 +18,13 @@
- 600
+ 620
350
- 600
+ 620
350
@@ -88,7 +88,7 @@
10
30
151
- 16
+ 21
@@ -98,7 +98,7 @@
- 420
+ 390
30
91
16
@@ -111,14 +111,14 @@
- 510
+ 480
30
- 49
+ 81
16
- <html><head/><body><p><span style=" font-weight:700;">PLACEHOLDER 9000</span></p></body></html>
+ <html><head/><body><p><span style=" font-weight:700;">PLACEHOLDER</span></p></body></html>
@@ -137,13 +137,26 @@
10
60
151
- 16
+ 21
<html><head/><body><p>Pixel Depth</p></body></html>
+
+
+
+ 10
+ 110
+ 231
+ 24
+
+
+
+ Load nvplay savestate from real hardware
+
+
diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c
index 21810386e..39aa0178d 100644
--- a/src/video/nv/nv3/nv3_core.c
+++ b/src/video/nv/nv3/nv3_core.c
@@ -866,9 +866,14 @@ void nv3_draw_cursor(svga_t* svga, int32_t drawline)
if ((nv3->nvbase.svga.crtc[NV3_CRTC_REGISTER_CURSOR_START] >> NV3_CRTC_REGISTER_CURSOR_START_DISABLED) & 0x01)
return;
- // On windows, this shows up using NV_IMAGE_IN_MEMORY.
+ // 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?
- uint32_t vram_cursor_base = nv3->pramdac.cursor_address;
+
+ // 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;
@@ -890,49 +895,64 @@ void nv3_draw_cursor(svga_t* svga, int32_t drawline)
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
- Technically these are expanded to RGB10, but I don't see why this needs to happen. And our pipeline isn't set up for it anyway.
+ 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 = vram_16[vram_cursor_base << 1];
- bool replace_bit = (current_pixel & 0x8000);
-
- switch (nv3->nvbase.svga.bpp)
+ uint16_t current_pixel = nv3_ramin_read16(ramin_cursor_position, nv3);
+
+ // 0000 = transparent, so skip drawing
+ if (current_pixel)
{
- /* this is indexed colour but... lol */
- case 8:
- if (replace_bit)
- {
- uint8_t final = current_pixel ^ nv3->nvbase.svga.vram[final_position];
- nv3->nvbase.svga.vram[final_position] = final;
- }
- else // just override
- nv3->nvbase.svga.vram[final_position] = current_pixel;
- case 15 ... 16: // easy case (our cursor is 15bpp format)
- uint32_t index_16 = final_position >> 1;
- if (replace_bit)
- {
- uint16_t final = current_pixel ^ vram_16[index_16];
- vram_16[index_16] = final;
- }
- else // just override
- vram_16[index_16] = current_pixel;
- case 32:
- uint32_t index_32 = final_position >> 2;
- if (replace_bit)
- {
- uint16_t final = current_pixel ^ vram_32[index_32];
- vram_32[index_32] = final;
- }
- else // just override
- vram_32[index_32] = nv3->nvbase.svga.conv_16to32(&nv3->nvbase.svga, current_pixel, 15); // 565_MODE doesn't seem to matter here
- break;
+ 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
- vram_cursor_base += 2;
+ ramin_cursor_position += 2;
// go
switch (nv3->nvbase.svga.bpp)
diff --git a/src/video/nv/nv3/subsystems/nv3_pfifo.c b/src/video/nv/nv3/subsystems/nv3_pfifo.c
index 7cd7f71a9..542aa26fa 100644
--- a/src/video/nv/nv3/subsystems/nv3_pfifo.c
+++ b/src/video/nv/nv3/subsystems/nv3_pfifo.c
@@ -739,7 +739,7 @@ void nv3_pfifo_cache0_pull(void)
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
+ // Tell the CPU if we found a software method and turn off cache pulling
if (!(current_context & 0x800000))
{
nv_log("The object in CACHE0 is a software object\n");