diff --git a/src/include/86box/nv/vid_nv.h b/src/include/86box/nv/vid_nv.h index 06c545fc7..d067c0148 100644 --- a/src/include/86box/nv/vid_nv.h +++ b/src/include/86box/nv/vid_nv.h @@ -107,10 +107,10 @@ typedef struct nv_base_s uint32_t bar1_lfb_base; // PCI Base Address Register 1 - Linear Framebuffer (NV_BASE) nv_bus_generation bus_generation; // current bus (see nv_bus_generation documentation) uint32_t gpu_revision; // GPU Stepping - double pixel_clock_period; // Period in seconds for pixel clock + double pixel_clock_frequency; // Frequency used for pixel clock rivatimer_t* pixel_clock_timer; // Timer for measuring pixel clock bool pixel_clock_enabled; // Pixel Clock Enabled - stupid crap used to prevent us enabling the timer multiple times - double memory_clock_period; // Period in seconds for pixel clock + double memory_clock_frequency; // Source Frequency for PTIMER rivatimer_t* memory_clock_timer; // Timer for measuring memory/gpu clock bool memory_clock_enabled; // Memory Clock Enabled - stupid crap used to prevent us eanbling the timer multiple times void* i2c; // I2C for monitor EDID diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index 80766be94..a404df979 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -577,7 +577,8 @@ extern const device_config_t nv3_config[]; #define NV3_CRTC_REGISTER_RL0 0x34 #define NV3_CRTC_REGISTER_RL1 0x35 #define NV3_CRTC_REGISTER_RMA 0x38 // REAL MODE ACCESS! -#define NV3_CRTC_REGISTER_I2C 0x3F +#define NV3_CRTC_REGISTER_I2C 0x3E +#define NV3_CRTC_REGISTER_I2C_GPIO 0x3F // where the fuck is GDC? #define NV3_CRTC_BANKED_128K_A0000 0x00 @@ -904,7 +905,7 @@ void nv3_speed_changed(void *priv); void nv3_force_redraw(void* priv); // Memory Mapping -void nv3_update_mappings(); +void nv3_update_mappings(); // Update memory mappings uint8_t nv3_mmio_read8(uint32_t addr, void* priv); // Read 8-bit MMIO uint16_t nv3_mmio_read16(uint32_t addr, void* priv); // Read 16-bit MMIO uint32_t nv3_mmio_read32(uint32_t addr, void* priv); // Read 32-bit MMIO @@ -917,12 +918,12 @@ void nv3_svga_out(uint16_t addr, uint8_t val, void* priv); uint8_t nv3_pci_read(int32_t func, int32_t addr, void* priv); // Read PCI configuration registers void nv3_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv); // Write PCI configuration registers -uint8_t nv3_ramin_read8(uint32_t addr, void* priv); // Read 8-bit RAMIN -uint16_t nv3_ramin_read16(uint32_t addr, void* priv); // Read 16-bit RAMIN -uint32_t nv3_ramin_read32(uint32_t addr, void* priv); // Read 32-bit RAMIN -void nv3_ramin_write8(uint32_t addr, uint8_t val, void* priv); // Write 8-bit RAMIN -void nv3_ramin_write16(uint32_t addr, uint16_t val, void* priv); // Write 16-bit RAMIN -void nv3_ramin_write32(uint32_t addr, uint32_t val, void* priv); // Write 32-bit RAMIN +uint8_t nv3_ramin_read8(uint32_t addr, void* priv); // Read 8-bit RAMIN +uint16_t nv3_ramin_read16(uint32_t addr, void* priv); // Read 16-bit RAMIN +uint32_t nv3_ramin_read32(uint32_t addr, void* priv); // Read 32-bit RAMIN +void nv3_ramin_write8(uint32_t addr, uint8_t val, void* priv); // Write 8-bit RAMIN +void nv3_ramin_write16(uint32_t addr, uint16_t val, void* priv); // Write 16-bit RAMIN +void nv3_ramin_write32(uint32_t addr, uint32_t val, void* priv); // Write 32-bit RAMIN // MMIO Arbitration // Determine where the hell in this mess our reads or writes are going @@ -1015,12 +1016,12 @@ void nv3_pbus_rma_write(uint16_t addr, uint8_t val); void nv3_pramdac_init(); void nv3_pramdac_set_vram_clock(); void nv3_pramdac_set_pixel_clock(); -void nv3_pramdac_pixel_clock_poll(); -void nv3_pramdac_memory_clock_poll(); +void nv3_pramdac_pixel_clock_poll(double real_time); +void nv3_pramdac_memory_clock_poll(double real_time); // NV3 PTIMER void nv3_ptimer_init(); -void nv3_ptimer_tick(); +void nv3_ptimer_tick(double real_time); // NV3 PVIDEO void nv3_pvideo_init(); diff --git a/src/include/86box/nv/vid_nv_rivatimer.h b/src/include/86box/nv/vid_nv_rivatimer.h index 31483992e..d5bb86b90 100644 --- a/src/include/86box/nv/vid_nv_rivatimer.h +++ b/src/include/86box/nv/vid_nv_rivatimer.h @@ -73,12 +73,12 @@ typedef struct rivatimer_s } rivatimer_t; void rivatimer_init(); // Initialise the Rivatimer. -rivatimer_t* rivatimer_create(double period, void (*callback)()); +rivatimer_t* rivatimer_create(double period, void (*callback)(double real_time)); void rivatimer_destroy(rivatimer_t* rivatimer_ptr); void rivatimer_update_all(); void rivatimer_start(rivatimer_t* rivatimer_ptr); void rivatimer_stop(rivatimer_t* rivatimer_ptr); double rivatimer_get_time(rivatimer_t* rivatimer_ptr); -void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)()); +void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)(double real_time)); void rivatimer_set_period(rivatimer_t* rivatimer_ptr, double period); diff --git a/src/video/nv/nv3/nv3_core.c b/src/video/nv/nv3/nv3_core.c index cfbb282d5..cd1614e8e 100644 --- a/src/video/nv/nv3/nv3_core.c +++ b/src/video/nv/nv3/nv3_core.c @@ -63,8 +63,8 @@ uint8_t nv3_mmio_read8(uint32_t addr, void* priv) ret = nv3_svga_in(real_address, nv3); - nv_log("NV3: Redirected MMIO read8 to SVGA: addr=0x%04x returned 0x%02x", addr, ret); - + nv_log("NV3: Redirected MMIO read8 to SVGA: addr=0x%04x returned 0x%02x\n", addr, ret); + return ret; } @@ -94,7 +94,7 @@ uint16_t nv3_mmio_read16(uint32_t addr, void* priv) ret = nv3_svga_in(real_address, nv3) | (nv3_svga_in(real_address + 1, nv3) << 8); - nv_log("NV3: Redirected MMIO read16 to SVGA: addr=0x%04x returned 0x%04x", addr, ret); + nv_log("NV3: Redirected MMIO read16 to SVGA: addr=0x%04x returned 0x%04x\n", addr, ret); return ret; } @@ -126,7 +126,7 @@ uint32_t nv3_mmio_read32(uint32_t addr, void* priv) | (nv3_svga_in(real_address + 2, nv3) << 16) | (nv3_svga_in(real_address + 3, nv3) << 24); - nv_log("NV3: Redirected MMIO read32 to SVGA: addr=0x%04x returned 0x%08x", addr, ret); + nv_log("NV3: Redirected MMIO read32 to SVGA: addr=0x%04x returned 0x%08x\n", addr, ret); return ret; } @@ -152,7 +152,7 @@ void nv3_mmio_write8(uint32_t addr, uint8_t val, void* priv) // svga writes are not logged anyway rn uint32_t real_address = addr & 0x3FF; - nv_log("NV3: Redirected MMIO write8 to SVGA: addr=0x%04x val=0x%02x", addr, val); + nv_log("NV3: Redirected MMIO write8 to SVGA: addr=0x%04x val=0x%02x\n", addr, val); nv3_svga_out(real_address, val & 0xFF, nv3); return; @@ -183,7 +183,7 @@ void nv3_mmio_write16(uint32_t addr, uint16_t val, void* priv) // svga writes are not logged anyway rn uint32_t real_address = addr & 0x3FF; - nv_log("NV3: Redirected MMIO write16 to SVGA: addr=0x%04x val=0x%04x", addr, val); + nv_log("NV3: Redirected MMIO write16 to SVGA: addr=0x%04x val=0x%04x\n", addr, val); nv3_svga_out(real_address, val & 0xFF, nv3); nv3_svga_out(real_address + 1, (val >> 8) & 0xFF, nv3); @@ -215,7 +215,7 @@ void nv3_mmio_write32(uint32_t addr, uint32_t val, void* priv) // svga writes are not logged anyway rn uint32_t real_address = addr & 0x3FF; - nv_log("NV3: Redirected MMIO write32 to SVGA: addr=0x%04x val=0x%08x", addr, val); + nv_log("NV3: Redirected MMIO write32 to SVGA: addr=0x%04x val=0x%08x\n", addr, val); nv3_svga_out(real_address, val & 0xFF, nv3); nv3_svga_out(real_address + 1, (val >> 8) & 0xFF, nv3); @@ -704,7 +704,7 @@ void nv3_svga_out(uint16_t addr, uint8_t val, void* priv) case NV3_CRTC_REGISTER_RMA: nv3->pbus.rma.mode = val & NV3_CRTC_REGISTER_RMA_MODE_MAX; break; - case NV3_CRTC_REGISTER_I2C: + case NV3_CRTC_REGISTER_I2C_GPIO: uint8_t scl = !!(val & 0x20); uint8_t sda = !!(val & 0x10); // Set an I2C GPIO register diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c index 0c57b71cb..9c44105b9 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ b/src/video/nv/nv3/subsystems/nv3_pramdac.c @@ -50,18 +50,16 @@ void nv3_pramdac_init() // Polls the pixel clock. // This updates the 2D/3D engine PGRAPH -void nv3_pramdac_pixel_clock_poll() +void nv3_pramdac_pixel_clock_poll(double real_time) { - // TODO: UPDATE PGRAPH! + // TODO: ???? } // Polls the memory clock. -void nv3_pramdac_memory_clock_poll() +void nv3_pramdac_memory_clock_poll(double real_time) { - //nv3_t* nv3_poll = (nv3_t*)priv; - - // Let's hope qeeg was right here. - nv3_ptimer_tick(); + nv3_ptimer_tick(real_time); + // TODO: UPDATE PGRAPH! } // Gets the vram clock register. @@ -120,10 +118,8 @@ void nv3_pramdac_set_vram_clock() nv_log("NV3: Memory clock = %.2f MHz\n", frequency / 1000000.0f); - nv3->nvbase.memory_clock_period = time; + nv3->nvbase.memory_clock_frequency = frequency; - //timer_on_auto(&nv3->nvbase.memory_clock_timer, nv3->nvbase.memory_clock_period); - // Create and start if it it's not running. if (!nv3->nvbase.memory_clock_timer) { @@ -170,7 +166,7 @@ void nv3_pramdac_set_pixel_clock() nv_log("NV3: Pixel clock = %.2f MHz\n", frequency / 1000000.0f); - nv3->nvbase.pixel_clock_period = time; + nv3->nvbase.pixel_clock_frequency = frequency; // Create and start if it it's not running. if (!nv3->nvbase.pixel_clock_timer) diff --git a/src/video/nv/nv3/subsystems/nv3_ptimer.c b/src/video/nv/nv3/subsystems/nv3_ptimer.c index c0d68a24c..ab19c1e61 100644 --- a/src/video/nv/nv3/subsystems/nv3_ptimer.c +++ b/src/video/nv/nv3/subsystems/nv3_ptimer.c @@ -57,7 +57,7 @@ void nv3_ptimer_interrupt(uint32_t num) } // Ticks the timer. -void nv3_ptimer_tick() +void nv3_ptimer_tick(double real_time) { // do not divide by zero if (nv3->ptimer.clock_numerator == 0 @@ -67,7 +67,14 @@ void nv3_ptimer_tick() // get the current time // Due to timer system limitations, the timer system is not capable of running at 100 megahertz. Therefore, we have to scale it down and then scale up the level of changes // to the state. - double current_time = ((double)nv3->ptimer.clock_numerator * NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT) / (double)nv3->ptimer.clock_denominator; // *10.0? + + // See Envytools. We need to use the frequency as a source. + // But we need to figure out how many cycles actually occurred because this counts up every cycle... + + // Convert to microseconds + double freq_base = (real_time / 1000000.0f) / ((double)1.0 / nv3->nvbase.memory_clock_frequency); + + 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. diff --git a/src/video/nv/nv_rivatimer.c b/src/video/nv/nv_rivatimer.c index c31ee11fe..343ec02ff 100644 --- a/src/video/nv/nv_rivatimer.c +++ b/src/video/nv/nv_rivatimer.c @@ -59,7 +59,7 @@ void rivatimer_init() } // Creates a rivatimer. -rivatimer_t* rivatimer_create(double period, void (*callback)()) +rivatimer_t* rivatimer_create(double period, void (*callback)(double real_time)) { rivatimer_t* new_rivatimer = NULL; @@ -210,7 +210,7 @@ void rivatimer_update_all() continue; } - rivatimer_ptr->callback(); + rivatimer_ptr->callback(microseconds); } rivatimer_ptr = rivatimer_ptr->next; @@ -254,7 +254,7 @@ double rivatimer_get_time(rivatimer_t* rivatimer_ptr) return rivatimer_ptr->time; } -void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)()) +void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)(double real_time)) { if (!rivatimer_really_exists(rivatimer_ptr)) fatal("rivatimer_set_callback: The timer has been destroyed, or never existed in the first place. Punch starfrost in the face");