diff --git a/src/include/86box/nv/vid_nv.h b/src/include/86box/nv/vid_nv.h index 9a4a7c55b..0666d8f35 100644 --- a/src/include/86box/nv/vid_nv.h +++ b/src/include/86box/nv/vid_nv.h @@ -28,6 +28,7 @@ #include <86box/timer.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/nv/vid_nv_rivatimer.h> void nv_log(const char *fmt, ...); @@ -99,10 +100,12 @@ typedef struct nv_base_s 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 - pc_timer_t pixel_clock_timer; // Pixel Clock Timer + //pc_timer_t pixel_clock_timer; // Pixel Clock Timer + rivatimer_t* pixel_clock_timer; 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 - pc_timer_t memory_clock_timer; // Memory Clock Timer + //pc_timer_t memory_clock_timer; // Memory Clock Timer + rivatimer_t* memory_clock_timer; bool memory_clock_enabled; // Memory Clock Enabled - stupid crap used to prevent us eanbling the timer multiple times } nv_base_t; diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index db9474602..4a93ebddb 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -28,7 +28,7 @@ extern const device_config_t nv3_config[]; #define NV3_LFB_RAMIN_START 0xC00000 // RAMIN mapping start #define NV3_LFB_MAPPING_SIZE 0x400000 // Size of RAMIN -#define NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT 1000 // The amount by which we have to ration out the memory clock because it's not fast enough... +#define NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT 10 // The amount by which we have to ration out the memory clock because it's not fast enough... // Multiply by this value to get the real clock speed. // Default value for the boot information register. // Depends on the chip @@ -952,8 +952,8 @@ 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* priv); -void nv3_pramdac_memory_clock_poll(void* priv); +void nv3_pramdac_pixel_clock_poll(/*void* priv*/); +void nv3_pramdac_memory_clock_poll(/*void* priv*/); // NV3 PTIMER void nv3_ptimer_init(); diff --git a/src/include/86box/nv/vid_nv_rivatimer.h b/src/include/86box/nv/vid_nv_rivatimer.h index 00e94cd97..31483992e 100644 --- a/src/include/86box/nv/vid_nv_rivatimer.h +++ b/src/include/86box/nv/vid_nv_rivatimer.h @@ -80,4 +80,5 @@ 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)()); \ No newline at end of file +void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)()); +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 dde1043c4..c7a4407f2 100644 --- a/src/video/nv/nv3/nv3_core.c +++ b/src/video/nv/nv3/nv3_core.c @@ -350,6 +350,8 @@ void nv3_pci_write(int32_t func, int32_t addr, uint8_t val, void* priv) void nv3_close(void* priv) { + rivatimer_destroy(nv3->nvbase.pixel_clock_timer); + rivatimer_destroy(nv3->nvbase.memory_clock_timer); svga_close(&nv3->nvbase.svga); free(nv3); nv3 = NULL; @@ -839,12 +841,16 @@ void* nv3_init(const device_t *info) nv_log("NV3: Initialising timers...\n"); + /* // These only get turned on when the requisite registers are twiddled timer_add(&nv3->nvbase.pixel_clock_timer, nv3_pramdac_pixel_clock_poll, nv3, false); nv_log("NV3: Pixel clock OK. Will be started when the VBIOS tells us to start\n"); - + timer_add(&nv3->nvbase.memory_clock_timer, nv3_pramdac_memory_clock_poll, nv3, false); nv_log("NV3: Memory clock OK. Will be started when the VBIOS tells us to start\n"); + */ + + return nv3; } diff --git a/src/video/nv/nv3/subsystems/nv3_pramdac.c b/src/video/nv/nv3/subsystems/nv3_pramdac.c index d30900d43..4dabc0a47 100644 --- a/src/video/nv/nv3/subsystems/nv3_pramdac.c +++ b/src/video/nv/nv3/subsystems/nv3_pramdac.c @@ -42,7 +42,6 @@ void nv3_pramdac_init() nv3->pramdac.memory_clock_n = nv3->pramdac.pixel_clock_n = 0xc8; nv3->pramdac.memory_clock_p = nv3->pramdac.pixel_clock_p = 0x0c; - nv3_pramdac_set_pixel_clock(); nv3_pramdac_set_vram_clock(); @@ -51,22 +50,24 @@ void nv3_pramdac_init() // Polls the pixel clock. // This updates the 2D/3D engine PGRAPH -void nv3_pramdac_pixel_clock_poll(void* priv) +void nv3_pramdac_pixel_clock_poll(/*void* priv*/) { + /* nv3_t* nv3_poll = (nv3_t*)priv; timer_on_auto(&nv3_poll->nvbase.pixel_clock_timer, nv3_poll->nvbase.pixel_clock_period); + */ } // Polls the memory clock. -void nv3_pramdac_memory_clock_poll(void* priv) +void nv3_pramdac_memory_clock_poll(/*void* priv*/) { - nv3_t* nv3_poll = (nv3_t*)priv; + //nv3_t* nv3_poll = (nv3_t*)priv; // Let's hope qeeg was right here. nv3_ptimer_tick(); - timer_on_auto(&nv3_poll->nvbase.memory_clock_timer, nv3_poll->nvbase.memory_clock_period); + //timer_on_auto(&nv3_poll->nvbase.memory_clock_timer, nv3_poll->nvbase.memory_clock_period); } // Gets the vram clock register. @@ -118,6 +119,7 @@ void nv3_pramdac_set_vram_clock() if (nv3->pramdac.memory_clock_n == 0) nv3->pramdac.memory_clock_n = 1; + // Convert to microseconds frequency = (frequency * nv3->pramdac.memory_clock_n) / (nv3->pramdac.memory_clock_m << nv3->pramdac.memory_clock_p); double time = (1000000.0 * NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT) / (double)frequency; // needs to be a double for 86box @@ -126,8 +128,16 @@ void nv3_pramdac_set_vram_clock() nv3->nvbase.memory_clock_period = time; - timer_on_auto(&nv3->nvbase.memory_clock_timer, nv3->nvbase.memory_clock_period); + //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) + { + nv3->nvbase.memory_clock_timer = rivatimer_create(time, nv3_pramdac_pixel_clock_poll); + rivatimer_start(nv3->nvbase.memory_clock_timer); + } + + rivatimer_set_period(nv3->nvbase.memory_clock_timer, time); //Breaks everything? //timer_set_delay_u64(&nv3->nvbase.memory_clock_timer, time * TIMER_USEC); // do we need to decrease } @@ -170,7 +180,17 @@ void nv3_pramdac_set_pixel_clock() nv3->nvbase.pixel_clock_period = time; - timer_on_auto(&nv3->nvbase.pixel_clock_timer, nv3->nvbase.pixel_clock_period); + // Create and start if it it's not running. + if (!nv3->nvbase.pixel_clock_timer) + { + nv3->nvbase.pixel_clock_timer = rivatimer_create(time, nv3_pramdac_pixel_clock_poll); + rivatimer_start(nv3->nvbase.pixel_clock_timer); + } + + rivatimer_set_period(nv3->nvbase.pixel_clock_timer, time); + + + //timer_on_auto(&nv3->nvbase.pixel_clock_timer, nv3->nvbase.pixel_clock_period); //Breaks everything? //timer_set_delay_u64(&nv3->nvbase.pixel_clock_timer, time * TIMER_USEC); // do we need to decrease } diff --git a/src/video/nv/nv_rivatimer.c b/src/video/nv/nv_rivatimer.c index 1ccde5a2f..c31ee11fe 100644 --- a/src/video/nv/nv_rivatimer.c +++ b/src/video/nv/nv_rivatimer.c @@ -42,8 +42,15 @@ void rivatimer_init() if (!rivatimer_ptr) return; - while (rivatimer_ptr->next) + while (rivatimer_ptr) + { + // since we are destroing it + rivatimer_t* old_next = rivatimer_ptr->next; rivatimer_destroy(rivatimer_ptr); + + rivatimer_ptr = old_next; + } + #ifdef _WIN32 // Query the performance frequency. @@ -98,10 +105,12 @@ bool rivatimer_really_exists(rivatimer_t* rivatimer) if (!current) return false; - while (current->next != NULL) + while (current) { if (current == rivatimer) return true; + + current = current->next; } return false; @@ -160,10 +169,14 @@ void rivatimer_update_all() if (!rivatimer_ptr) return; - while (rivatimer_ptr->next) + while (rivatimer_ptr) { + // if it's not running skip it if (!rivatimer_ptr->running) + { + rivatimer_ptr = rivatimer_ptr->next; continue; + } #ifdef _WIN32 LARGE_INTEGER current_time; @@ -199,6 +212,8 @@ void rivatimer_update_all() rivatimer_ptr->callback(); } + + rivatimer_ptr = rivatimer_ptr->next; } } @@ -248,4 +263,12 @@ void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)()) fatal("rivatimer_set_callback: No callback!"); rivatimer_ptr->callback = callback; +} + +void rivatimer_set_period(rivatimer_t* rivatimer_ptr, double period) +{ + if (!rivatimer_really_exists(rivatimer_ptr)) + fatal("rivatimer_set_period: The timer has been destroyed, or never existed in the first place. Punch starfrost in the face"); + + rivatimer_ptr->period = period; } \ No newline at end of file