Correctly set the timers, but setting it all breaks?

This commit is contained in:
starfrost013
2024-12-20 20:14:38 +00:00
parent 60f2828aeb
commit 2f2fb2724d
5 changed files with 76 additions and 42 deletions

View File

@@ -98,7 +98,9 @@ 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
pc_timer_t pixel_clock_timer; // Pixel Clock Timer
double memory_clock_period; // Period in seconds for pixel clock
pc_timer_t memory_clock_timer; // Memory Clock Timer
} nv_base_t;
@@ -496,6 +498,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);
// NV3 PTIMER
void nv3_ptimer_init();

View File

@@ -29,6 +29,9 @@ 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 100 // 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.
// various vbioses for testing
// Coming soon: MIROmagic Premium BIOS (when I get mine dumped)
//todo: move to hash system

View File

@@ -728,19 +728,7 @@ void nv3_update_mappings()
}
}
// Polls the pixel clock.
// This updates the 2D/3D engine PGRAPH
void nv3_pixel_clock_poll(void* priv)
{
}
// Polls the memory clock.
void nv3_memory_clock_poll(void* poll)
{
// Let's hope qeeg was right here.
nv3_ptimer_tick();
}
//
// Init code
@@ -813,12 +801,13 @@ void* nv3_init(const device_t *info)
nv3_ptimer_init(); // Initialise programmable interval timer
nv3_pvideo_init(); // Initialise video overlay engine
nv_log("NV3: Starting timers...");
// Add the
timer_add(&nv3->nvbase.pixel_clock_timer, nv3_pixel_clock_poll, nv3, true);
timer_add(&nv3->nvbase.memory_clock_timer, nv3_memory_clock_poll, nv3, true);
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;
}

View File

@@ -42,15 +42,34 @@ 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();
nv_log("NV3: Initialising PRAMDAC: Done\n");
}
// Polls the pixel clock.
// This updates the 2D/3D engine PGRAPH
void nv3_pramdac_pixel_clock_poll(void* priv)
{
timer_on_auto(&nv3->nvbase.pixel_clock_timer, nv3->nvbase.pixel_clock_period);
}
// Polls the memory clock.
void nv3_pramdac_memory_clock_poll(void* poll)
{
// Let's hope qeeg was right here.
nv3_ptimer_tick();
timer_on_auto(&nv3->nvbase.memory_clock_timer, nv3->nvbase.memory_clock_period);
}
// Gets the vram clock register.
uint32_t nv3_pramdac_get_vram_clock_register()
{
// pack into 19 bits
// the clock format is packed into 19 bits
// M divisor [7-0]
// N divisor [16-8]
// P divisor [18-16]
@@ -95,39 +114,51 @@ void nv3_pramdac_set_vram_clock()
else
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
nv_log("NV3: Memory clock = %.2f MHz\n", frequency / 1000000.0f);
nv3->nvbase.memory_clock_period = time;
//Breaks everything?
//timer_set_delay_u64(&nv3->nvbase.memory_clock_timer, time * TIMER_USEC); // do we need to decrease
}
void nv3_pramdac_set_pixel_clock()
{
// frequency divider algorithm from old varcem/86box/pcbox riva driver,
// verified by reversing NT drivers v1.50e CalcMNP [symbols] function
// frequency divider algorithm from old varcem/86box/pcbox riva driver,
// verified by reversing NT drivers v1.50e CalcMNP [symbols] function
// todo: actually implement it
// todo: actually implement it
// missing section
// not really needed.
// if (nv3->pfb.boot.clock_crystal == CLOCK_CRYSTAL_13500)
// {
// freq = 13500000.0f;
// }
// else
//
// {
// freq = 14318000.0f;
// }
// missing section
// not really needed.
// if (nv3->pfb.boot.clock_crystal == CLOCK_CRYSTAL_13500)
// {
// freq = 13500000.0f;
// }
// else
//
// {
// freq = 14318000.0f;
// }
float frequency = 13500000.0f;
float frequency = 13500000.0f;
// prevent division by 0
if (nv3->pramdac.pixel_clock_m == 0)
nv3->pramdac.pixel_clock_m == 1;
else
// prevent division by 0
if (nv3->pramdac.pixel_clock_m == 0)
nv3->pramdac.pixel_clock_m == 1;
else
frequency = (frequency * nv3->pramdac.pixel_clock_n) / (nv3->pramdac.pixel_clock_m << nv3->pramdac.pixel_clock_p);
nv3->nvbase.svga.clock = cpuclock / frequency;
nv3->nvbase.svga.clock = cpuclock / frequency;
nv_log("NV3: Pixel clock = %.2f MHz\n", frequency / 1000000.0f);
double time = (1000000.0 * NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT) / (double)frequency; // needs to be a double for 86box
nv_log("NV3: Pixel clock = %.2f MHz\n", frequency / 1000000.0f);
nv3->nvbase.pixel_clock_period = time;
//Breaks everything?
//timer_set_delay_u64(&nv3->nvbase.pixel_clock_timer, time * TIMER_USEC); // do we need to decrease
}
//

View File

@@ -59,8 +59,15 @@ void nv3_ptimer_interrupt(uint32_t num)
// Ticks the timer.
void nv3_ptimer_tick()
{
// do not divide by zero
if (nv3->ptimer.clock_numerator == 0
|| nv3->ptimer.clock_denominator == 0)
return;
// get the current time
double current_time = ((double)nv3->ptimer.clock_numerator) / (double)nv3->ptimer.clock_denominator; // *10.0?
// 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?
// truncate it
nv3->ptimer.time += (uint64_t)current_time;
@@ -127,7 +134,7 @@ void nv3_ptimer_write(uint32_t address, uint32_t value)
// before doing anything, check the subsystem enablement
nv_register_t* reg = nv_get_register(address, ptimer_registers, sizeof(ptimer_registers)/sizeof(ptimer_registers[0]));
nv_log("NV3: PTIMER Write 0x%08x -> 0x%08x\n", value, address);
nv_log("NV3: PTIMER Write 0x%08x -> 0x%08x", value, address);
// if the register actually exists
if (reg)
@@ -156,7 +163,7 @@ void nv3_ptimer_write(uint32_t address, uint32_t value)
case NV3_PTIMER_INTR_EN:
nv3->ptimer.interrupt_enable = value & 0x1;
break;
//
// nUMERATOR
case NV3_PTIMER_NUMERATOR:
nv3->ptimer.clock_numerator = value & 0xFFFF; // 15:0
break;