Retrieve vertical retrace value with method get_crtc_params() (now using a

structure for the returned values calculated from CRTC regs).
This commit is contained in:
Volker Ruppert 2017-11-28 18:05:36 +00:00
parent a7e58973ce
commit bb88561a43
4 changed files with 34 additions and 21 deletions

View File

@ -410,18 +410,23 @@ void bx_vgacore_c::determine_screen_dimensions(unsigned *piHeight, unsigned *piW
}
}
void bx_vgacore_c::get_crtc_params(Bit32u *htotal, Bit32u *vtotal)
void bx_vgacore_c::get_crtc_params(bx_crtc_params_t *crtcp)
{
*htotal = BX_VGA_THIS s.CRTC.reg[0] + 5;
*vtotal = BX_VGA_THIS s.CRTC.reg[6] + ((BX_VGA_THIS s.CRTC.reg[7] & 0x01) << 8) +
((BX_VGA_THIS s.CRTC.reg[7] & 0x20) << 4) + 2;
crtcp->htotal = BX_VGA_THIS s.CRTC.reg[0] + 5;
crtcp->vtotal = BX_VGA_THIS s.CRTC.reg[6] +
((BX_VGA_THIS s.CRTC.reg[7] & 0x01) << 8) +
((BX_VGA_THIS s.CRTC.reg[7] & 0x20) << 4) + 2;
crtcp->vrstart = BX_VGA_THIS s.CRTC.reg[16] +
((BX_VGA_THIS s.CRTC.reg[7] & 0x04) << 6) +
((BX_VGA_THIS s.CRTC.reg[7] & 0x80) << 2);
}
void bx_vgacore_c::calculate_retrace_timing()
{
Bit32u htotal, hbstart, hbend, clock, cwidth, vtotal, vrstart, vrend, hfreq, vfreq;
Bit32u hbstart, hbend, clock, cwidth, hfreq, vfreq, vrend;
bx_crtc_params_t crtcp;
BX_VGA_THIS get_crtc_params(&htotal, &vtotal);
BX_VGA_THIS get_crtc_params(&crtcp);
cwidth = ((BX_VGA_THIS s.sequencer.reg1 & 0x01) == 1) ? 8 : 9;
clock = BX_VGA_THIS s.vclk[BX_VGA_THIS s.misc_output.clock_select];
if (BX_VGA_THIS s.x_dotclockdiv2) clock >>= 1;
@ -431,21 +436,19 @@ void bx_vgacore_c::calculate_retrace_timing()
} else {
BX_DEBUG(("Using video clock %.3f MHz", (double)clock / 1000000.0f));
}
hfreq = clock / (htotal * cwidth);
hfreq = clock / (crtcp.htotal * cwidth);
BX_VGA_THIS s.htotal_usec = 1000000 / hfreq;
hbstart = BX_VGA_THIS s.CRTC.reg[2];
BX_VGA_THIS s.hbstart_usec = (1000000 * hbstart * cwidth) / clock;
hbend = (BX_VGA_THIS s.CRTC.reg[3] & 0x1f) + ((BX_VGA_THIS s.CRTC.reg[5] & 0x80) >> 2);
hbend = hbstart + ((hbend - hbstart) & 0x3f);
BX_VGA_THIS s.hbend_usec = (1000000 * hbend * cwidth) / clock;
vrstart = BX_VGA_THIS s.CRTC.reg[16] + ((BX_VGA_THIS s.CRTC.reg[7] & 0x04) << 6) +
((BX_VGA_THIS s.CRTC.reg[7] & 0x80) << 2);
vrend = ((BX_VGA_THIS s.CRTC.reg[17] & 0x0f) - vrstart) & 0x0f;
vrend = vrstart + vrend + 1;
vfreq = hfreq / vtotal;
vrend = ((BX_VGA_THIS s.CRTC.reg[17] & 0x0f) - crtcp.vrstart) & 0x0f;
vrend += crtcp.vrstart;
vfreq = hfreq / crtcp.vtotal;
BX_VGA_THIS s.vtotal_usec = 1000000 / vfreq;
BX_VGA_THIS s.vblank_usec = BX_VGA_THIS s.htotal_usec * BX_VGA_THIS s.vertical_display_end;
BX_VGA_THIS s.vrstart_usec = BX_VGA_THIS s.htotal_usec * vrstart;
BX_VGA_THIS s.vrstart_usec = BX_VGA_THIS s.htotal_usec * crtcp.vrstart;
BX_VGA_THIS s.vrend_usec = BX_VGA_THIS s.htotal_usec * vrend;
BX_DEBUG(("hfreq = %.1f kHz / vfreq = %d Hz", ((double)hfreq / 1000), vfreq));
}
@ -501,7 +504,7 @@ Bit32u bx_vgacore_c::read(Bit32u address, unsigned io_len)
// bit0: Display Enable
// 0 = display is in the display mode
// 1 = display is not in the display mode; either the
// horizontal or vertical retrace period is active
// horizontal or vertical blanking period is active
retval = 0;
display_usec = bx_virt_timer.time_usec(BX_VGA_THIS realtime) % BX_VGA_THIS s.vtotal_usec;

View File

@ -60,6 +60,12 @@
s.vga_tile_updated[(xtile)+(ytile)* s.num_x_tiles] \
: 0)
typedef struct {
Bit16u htotal;
Bit16u vtotal;
Bit16u vrstart;
} bx_crtc_params_t;
#if BX_SUPPORT_PCI
class bx_nonvga_device_c : public bx_pci_device_c {
public:
@ -95,7 +101,7 @@ public:
virtual void get_text_snapshot(Bit8u **text_snapshot, unsigned *txHeight,
unsigned *txWidth);
virtual bx_bool init_vga_extension(void) {return 0;}
virtual void get_crtc_params(Bit32u *htotal, Bit32u *vtotal);
virtual void get_crtc_params(bx_crtc_params_t *crtcp);
static void vga_timer_handler(void *);
static Bit64s vga_param_handler(bx_param_c *param, int set, Bit64s val);

View File

@ -2996,12 +2996,16 @@ Bit32u bx_voodoo_vga_c::get_retrace()
return retval;
}
void bx_voodoo_vga_c::get_crtc_params(Bit32u *htotal, Bit32u *vtotal)
void bx_voodoo_vga_c::get_crtc_params(bx_crtc_params_t *crtcp)
{
*htotal = BX_VVGA_THIS s.CRTC.reg[0] + ((v->banshee.crtc[0x1a] & 0x01) << 8) + 5;
*vtotal = BX_VVGA_THIS s.CRTC.reg[6] + ((BX_VVGA_THIS s.CRTC.reg[7] & 0x01) << 8) +
((BX_VVGA_THIS s.CRTC.reg[7] & 0x20) << 4) +
((v->banshee.crtc[0x1b] & 0x01) << 10) + 2;
crtcp->htotal = BX_VVGA_THIS s.CRTC.reg[0] + ((v->banshee.crtc[0x1a] & 0x01) << 8) + 5;
crtcp->vtotal = BX_VVGA_THIS s.CRTC.reg[6] + ((BX_VVGA_THIS s.CRTC.reg[7] & 0x01) << 8) +
((BX_VVGA_THIS s.CRTC.reg[7] & 0x20) << 4) +
((v->banshee.crtc[0x1b] & 0x01) << 10) + 2;
crtcp->vrstart = BX_VVGA_THIS s.CRTC.reg[16] +
((BX_VVGA_THIS s.CRTC.reg[7] & 0x04) << 6) +
((BX_VVGA_THIS s.CRTC.reg[7] & 0x80) << 2) +
((v->banshee.crtc[0x1b] & 0x40) << 4);
}
void bx_voodoo_vga_c::update(void)

View File

@ -134,7 +134,7 @@ public:
unsigned width, unsigned height);
virtual bx_bool init_vga_extension(void);
virtual void get_crtc_params(Bit32u *htotal, Bit32u *vtotal);
virtual void get_crtc_params(bx_crtc_params_t *crtcp);
bx_bool get_retrace(void);
void banshee_update_mode(void);