Fixed Voodoo pixel clock calculation.

- Now using float type for the 'clk0_freq' variable.
- DAC register 6 can switch to half pixel clock (ported from PCem).
- Writing value 0xf8 to PLL register 0x0e completes clock #0 setup.
This commit is contained in:
Volker Ruppert 2017-08-21 19:33:29 +00:00
parent 4e80e2fbfc
commit 680189a548
3 changed files with 10 additions and 6 deletions

View File

@ -324,7 +324,7 @@ void bx_voodoo_c::register_state(void)
new bx_shadow_num_c(dac, name, &v->dac.reg[i], BASE_HEX);
}
new bx_shadow_num_c(dac, "read_result", &v->dac.read_result, BASE_HEX);
new bx_shadow_num_c(dac, "clk0_freq", &v->dac.clk0_freq, BASE_DEC);
new bx_shadow_num_c(dac, "clk0_freq", &v->dac.clk0_freq);
bx_list_c *fbi = new bx_list_c(vstate, "fbi", "framebuffer");
new bx_shadow_data_c(fbi, "ram", v->fbi.ram, (4 << 20));
new bx_shadow_num_c(fbi, "rgboffs0", &v->fbi.rgboffs[0], BASE_HEX);
@ -568,11 +568,11 @@ bx_bool bx_voodoo_c::update_timing(void)
hsync = ((v->reg[hSync].u >> 16) & 0x3ff);
vsync = ((v->reg[vSync].u >> 16) & 0xfff);
}
double hfreq = (double)(v->dac.clk0_freq * 1000) / htotal;
float hfreq = v->dac.clk0_freq / (float)htotal;
if (((v->reg[fbiInit1].u >> 20) & 3) == 1) { // VCLK div 2
hfreq /= 2;
}
double vfreq = hfreq / (double)vtotal;
float vfreq = hfreq / (float)vtotal;
BX_VOODOO_THIS s.vdraw.htotal_usec = (unsigned)(1000000.0 / hfreq);
BX_VOODOO_THIS s.vdraw.vtotal_usec = (unsigned)(1000000.0 / vfreq);
BX_VOODOO_THIS s.vdraw.htime_to_pixel = (double)htotal / (1000000.0 / hfreq);

View File

@ -1621,7 +1621,7 @@ struct _dac_state
Bit8u clk0_m;
Bit8u clk0_n;
Bit8u clk0_p;
Bit32u clk0_freq;
float clk0_freq;
};

View File

@ -1396,8 +1396,12 @@ void dacdata_w(dac_state *d, Bit8u regnum, Bit8u data)
}
break;
case 0x0e:
if ((d->data_size == 1) && ((data & 0x21) == 0x21)) {
d->clk0_freq = (Bit32u)((14318.0 * (d->clk0_m + 2)) / ((1 << d->clk0_p) * (d->clk0_n + 2)));
if ((d->data_size == 1) && (data == 0xf8)) {
d->clk0_freq = 14318184.0 * ((float)(d->clk0_m + 2) / (float)(d->clk0_n + 2)) / (float)(1 << d->clk0_p);
Bit8u dacr6 = d->reg[6] & 0xf0;
if ((dacr6 == 0x20) || (dacr6 == 0x60) || (dacr6 == 0x70)) {
d->clk0_freq /= 2.0f;
}
Voodoo_update_timing();
}
break;