From 2007e3d0e56cde208fa8cf3144a312d6e250d6d8 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 27 Apr 2025 17:04:24 +0100 Subject: [PATCH] start working on visual gpu debugging window; rename nv3_position_32 to nv3_coord_32; first pass at hardware cursor --- doc/nvidia_notes/hardware cursor.txt | 21 +++ .../86box/nv/classes/vid_nv3_classes.h | 8 +- src/include/86box/nv/render/vid_nv3_render.h | 2 +- src/include/86box/nv/vid_nv3.h | 55 +++++--- src/qt/CMakeLists.txt | 6 +- src/qt/qt_gpudebug_vram.cpp | 1 + src/qt/qt_gpudebug_vram.hpp | 18 +++ src/qt/qt_gpudebug_vram.ui | 56 ++++++++ src/qt/qt_mainwindow.ui | 18 +++ src/video/nv/nv3/nv3_core.c | 127 ++++++++++++++++-- src/video/nv/nv3/render/nv3_render_blit.c | 4 +- src/video/nv/nv3/render/nv3_render_core.c | 10 +- src/video/nv/nv3/subsystems/nv3_pramdac.c | 15 ++- 13 files changed, 294 insertions(+), 47 deletions(-) create mode 100644 doc/nvidia_notes/hardware cursor.txt create mode 100644 src/qt/qt_gpudebug_vram.cpp create mode 100644 src/qt/qt_gpudebug_vram.hpp create mode 100644 src/qt/qt_gpudebug_vram.ui diff --git a/doc/nvidia_notes/hardware cursor.txt b/doc/nvidia_notes/hardware cursor.txt new file mode 100644 index 000000000..0845778f4 --- /dev/null +++ b/doc/nvidia_notes/hardware cursor.txt @@ -0,0 +1,21 @@ +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/src/include/86box/nv/classes/vid_nv3_classes.h b/src/include/86box/nv/classes/vid_nv3_classes.h index 163b6464e..d5dc3ed43 100644 --- a/src/include/86box/nv/classes/vid_nv3_classes.h +++ b/src/include/86box/nv/classes/vid_nv3_classes.h @@ -306,11 +306,11 @@ typedef struct nv3_clip_16_s } nv3_clip_16_t; /* In case your positions weren't HIGH PRECISION enough */ -typedef struct nv3_position_32_s +typedef struct nv3_coord_32_s { uint32_t x; uint32_t y; -} nv3_position_32_t; +} nv3_coord_32_t; // COLOUR FORMATS @@ -459,7 +459,7 @@ typedef struct nv3_object_class_008 uint32_t set_notify; // Set notifier nv3_color_expanded_t color; // argb? nv3_coord_16_t point[16]; // Boring points - nv3_position_32_t point32[16]; // Allows you to have points with full 32-bit precision + 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; @@ -549,7 +549,7 @@ typedef struct nv3_object_class_00B uint32_t x2; nv3_coord_16_t mesh[32]; // Some kind of mesh format. I guess a list of vertex positions? - nv3_position_32_t mesh32[16]; + nv3_coord_32_t mesh32[16]; nv3_color_and_coord_16_t ctriangle[3]; // Triangle 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; diff --git a/src/include/86box/nv/render/vid_nv3_render.h b/src/include/86box/nv/render/vid_nv3_render.h index 795bae979..f4850b8f7 100644 --- a/src/include/86box/nv/render/vid_nv3_render.h +++ b/src/include/86box/nv/render/vid_nv3_render.h @@ -31,7 +31,7 @@ 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, nv3_grobj_t grobj, uint32_t buffer); +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.) diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 25049dbce..ebb7c0755 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -697,6 +697,11 @@ extern const device_config_t nv3t_config[]; // Confi #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 @@ -759,30 +764,30 @@ extern const device_config_t nv3t_config[]; // Confi // 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_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 +#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 +#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 -#define NV3_RAMIN_END 0x1FFFFFF +#define NV3_RAMIN_END 0x1FFFFFF // not done @@ -814,6 +819,7 @@ extern const device_config_t nv3t_config[]; // Confi #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 @@ -846,6 +852,9 @@ extern const device_config_t nv3t_config[]; // Confi #define NV3_CRTC_REGISTER_HEB 0x2D // HRS most significant bit +#define NV3_CRTC_REGISTER_CURSOR_ADDR0 0x30 // Cursor high +#define NV3_CRTC_REGISTER_CURSOR_ADDR1 0x31 // Cursor low (1:0 = enable) + #define NV3_CRTC_REGISTER_PIXELMODE_VGA 0x00 // vga textmode #define NV3_CRTC_REGISTER_PIXELMODE_8BPP 0x01 #define NV3_CRTC_REGISTER_PIXELMODE_16BPP 0x02 @@ -1084,7 +1093,10 @@ typedef struct nv3_pramdac_s 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 entriesxr,g,b = 768 bytes + 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 */ @@ -1473,6 +1485,7 @@ extern nv3_t* nv3; 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); diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 4231034d5..c2e5e4df4 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -151,7 +151,11 @@ add_library(ui STATIC qt_newfloppydialog.ui qt_harddiskdialog.cpp qt_harddiskdialog.hpp - qt_harddiskdialog.ui + qt_harddiskdialog.ui + + qt_gpudebug_vram.cpp + qt_gpudebug_vram.hpp + qt_gpudebug_vram.ui qt_harddrive_common.cpp qt_harddrive_common.hpp diff --git a/src/qt/qt_gpudebug_vram.cpp b/src/qt/qt_gpudebug_vram.cpp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/src/qt/qt_gpudebug_vram.cpp @@ -0,0 +1 @@ + diff --git a/src/qt/qt_gpudebug_vram.hpp b/src/qt/qt_gpudebug_vram.hpp new file mode 100644 index 000000000..975583f7f --- /dev/null +++ b/src/qt/qt_gpudebug_vram.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace Ui +{ + class GPUDebugVRAMDialog; +} + +class Ui::GPUDebugVRAMDialog : public QDialog +{ + public: + void Init(); + protected: + private: + + +}; \ No newline at end of file diff --git a/src/qt/qt_gpudebug_vram.ui b/src/qt/qt_gpudebug_vram.ui new file mode 100644 index 000000000..0f6c9931f --- /dev/null +++ b/src/qt/qt_gpudebug_vram.ui @@ -0,0 +1,56 @@ + + + + GPUDebugVRAMDialog + + + + 0 + 0 + 421 + 269 + + + + + 0 + 0 + + + + + 421 + 269 + + + + + 421 + 269 + + + + Dialog + + + + + + false + + + 0 + + + true + + + + + + + Sectors: + + + + diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 83a80342b..2861b65be 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -222,11 +222,19 @@ + + + &Debugging Tools + + + + + @@ -899,6 +907,16 @@ Pen + + + GPU Debug - VRAM Viewer + + + + + GPU Debug - NV3 Visual Debugger + + diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c index 031827677..d08768e3c 100644 --- a/src/video/nv/nv3/nv3_core.c +++ b/src/video/nv/nv3/nv3_core.c @@ -725,18 +725,18 @@ void nv3_svga_write(uint16_t addr, uint8_t val, void* priv) 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 + 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; + 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; @@ -769,6 +769,15 @@ void nv3_svga_write(uint16_t addr, uint8_t val, void* priv) i2c_gpio_set(nv3->nvbase.i2c, scl, sda); break; } + /* [6:0] contains cursorAddr [23:17] */ + case NV3_CRTC_REGISTER_CURSOR_ADDR0: + nv3->pramdac.cursor_address |= val << 17; //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 >> 2) << 13; // bit0 and 1 aren't part of the address + break; + } @@ -852,11 +861,109 @@ 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; // On windows, this shows up using NV_IMAGE_IN_MEMORY. // Do we need to emulate it? + uint32_t vram_cursor_base = nv3->pramdac.cursor_address; + /* let's just assume buffer 0 here...that code needs to be totally rewritten*/ + nv3_coord_16_t start_position = nv3->pramdac.cursor_start; - nv_log("nv3_draw_cursor drawline=0x%04x", drawline); + /* 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 + + 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. + */ + 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) + { + /* 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; + } + + // increment vram position + vram_cursor_base += 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); + } + + nv3_coord_16_t size = {0}; + size.x = size.y = 32; + nv3_grobj_t dummy = {0}; // need to clean it up + + /* do we need to update here? */ + nv3_render_current_bpp(&nv3->nvbase.svga, start_position, size, dummy, false, false); } // MMIO 0x110000->0x111FFF is mapped to a mirror of the VBIOS. diff --git a/src/video/nv/nv3/render/nv3_render_blit.c b/src/video/nv/nv3/render/nv3_render_blit.c index 6d29965d4..b7a45f9a8 100644 --- a/src/video/nv/nv3/render/nv3_render_blit.c +++ b/src/video/nv/nv3/render/nv3_render_blit.c @@ -161,7 +161,7 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj) { buf_position = (nv3->pgraph.blit.size.x * y); /* shouldn't matter in non-wtf mode */ - vram_position = nv3_render_get_vram_address_for_buffer(old_position, grobj, src_buffer); + vram_position = nv3_render_get_vram_address_for_buffer(old_position, src_buffer); memcpy(&nv3_s2sb_line_buffer[buf_position], &nv3->nvbase.svga.vram[vram_position], size_x); old_position.y++; @@ -172,7 +172,7 @@ void nv3_render_blit_screen2screen(nv3_grobj_t grobj) 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(new_position, grobj, dst_buffer); + vram_position = nv3_render_get_vram_address_for_buffer(new_position, dst_buffer); memcpy(&nv3->nvbase.svga.vram[vram_position], &nv3_s2sb_line_buffer[buf_position], size_x); new_position.y++; diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index acbf9fa05..6a1823883 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -260,7 +260,7 @@ uint32_t nv3_render_get_vram_address(nv3_coord_16_t position, nv3_grobj_t grobj) /* 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, nv3_grobj_t grobj, uint32_t buffer) +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; @@ -663,7 +663,7 @@ void nv3_render_8bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj, { /* re-set the vram address because we are basically "jumping" halfway across a line here */ if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, grobj, 0); // hardcode to zero for now + vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now else vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; @@ -704,7 +704,7 @@ void nv3_render_15bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj { /* re-set the vram address because we are basically "jumping" halfway across a line here */ if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, grobj, 0); // hardcode to zero for now + vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now else vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; @@ -745,7 +745,7 @@ void nv3_render_16bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj { /* re-set the vram address because we are basically "jumping" halfway across a line here */ if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, grobj, 0); // hardcode to zero for now + vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now else vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; @@ -786,7 +786,7 @@ void nv3_render_32bpp(nv3_coord_16_t pos, nv3_coord_16_t size, nv3_grobj_t grobj { /* re-set the vram address because we are basically "jumping" halfway across a line here */ if (use_destination_buffer) - vram_base = nv3_render_get_vram_address_for_buffer(pos, grobj, 0); // hardcode to zero for now + vram_base = nv3_render_get_vram_address_for_buffer(pos, 0); // hardcode to zero for now else vram_base = nv3_render_get_vram_address(pos, grobj) & nv3->nvbase.svga.vram_display_mask; diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c index 88b910b6f..b7c984f26 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ b/src/video/nv/nv3/subsystems/nv3_pramdac.c @@ -182,7 +182,7 @@ void nv3_pramdac_set_pixel_clock(void) nv3->nvbase.svga.clock = cpuclock / frequency; - double time = 1000000.0 / (double)frequency; // needs to be a double for 86box + double time = 1000000.0 / (double)frequency; // needs to be a double for 86box nv_log("Pixel clock = %.2f MHz\n", frequency / 1000000.0f); @@ -205,6 +205,7 @@ void nv3_pramdac_set_pixel_clock(void) // 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}, @@ -320,6 +321,9 @@ uint32_t nv3_pramdac_read(uint32_t address) 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; } } @@ -345,8 +349,6 @@ void nv3_pramdac_write(uint32_t address, uint32_t value) // if the register actually exists if (reg) { - - // on-read function if (reg->on_write) reg->on_write(value); @@ -434,6 +436,13 @@ void nv3_pramdac_write(uint32_t address, uint32_t 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; } }