Rewrite of the VGA/Cirrus code to reduce code duplication.

- Moved VGA timer handler to the VGA core and handle the non-VGA case there.
  It calls the specific update() code and finally bx_gui->flush().
- Moved the VGA update frequency parameter handler and the refresh_disply()
  method to the VGA core.
- Store the VGA extension parameter in the VGA core.
- Voodoo: Fixed graphics snapshot.
This commit is contained in:
Volker Ruppert 2017-10-08 07:55:04 +00:00
parent ebbd952d3b
commit 610cec209d
7 changed files with 74 additions and 141 deletions

View File

@ -257,7 +257,7 @@ void bx_svga_cirrus_c::init_vga_extension(void)
BX_CIRRUS_THIS put("CIRRUS");
// initialize SVGA stuffs.
BX_CIRRUS_THIS bx_vgacore_c::init_iohandlers(svga_read_handler, svga_write_handler);
BX_CIRRUS_THIS bx_vgacore_c::init_systemtimer(svga_timer_handler, svga_param_handler);
BX_CIRRUS_THIS bx_vgacore_c::init_systemtimer();
BX_CIRRUS_THIS pci_enabled = SIM->is_pci_device("cirrus");
BX_CIRRUS_THIS svga_init_members();
#if BX_SUPPORT_PCI
@ -440,7 +440,7 @@ void bx_svga_cirrus_c::after_restore_state(void)
BX_CIRRUS_THIS s.pel.data[i].blue<<2);
}
BX_CIRRUS_THIS svga_needs_update_mode = 1;
BX_CIRRUS_THIS svga_update();
BX_CIRRUS_THIS update();
}
}
@ -807,22 +807,6 @@ void bx_svga_cirrus_c::get_text_snapshot(Bit8u **text_snapshot,
BX_CIRRUS_THIS bx_vgacore_c::get_text_snapshot(text_snapshot,txHeight,txWidth);
}
Bit64s bx_svga_cirrus_c::svga_param_handler(bx_param_c *param, int set, Bit64s val)
{
if (set) {
Bit32u update_interval = (Bit32u)(1000000 / val);
BX_INFO(("Changing timer interval to %d", update_interval));
BX_CIRRUS_THIS svga_timer_handler(theSvga);
bx_virt_timer.activate_timer(BX_CIRRUS_THIS timer_id, update_interval, 1);
if (update_interval < 300000) {
BX_CIRRUS_THIS s.blink_counter = 300000 / (unsigned)update_interval;
} else {
BX_CIRRUS_THIS s.blink_counter = 1;
}
}
return val;
}
Bit32u bx_svga_cirrus_c::svga_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
{
#if !BX_USE_CIRRUS_SMF
@ -1001,37 +985,6 @@ void bx_svga_cirrus_c::svga_write(Bit32u address, Bit32u value, unsigned io_len)
VGA_WRITE(address,value,io_len);
}
void bx_svga_cirrus_c::refresh_display(void *this_ptr, bx_bool redraw)
{
#if BX_SUPPORT_PCI
if (BX_CIRRUS_THIS s.vga_override && (BX_CIRRUS_THIS s.nvgadev != NULL)) {
BX_CIRRUS_THIS s.nvgadev->refresh_display(BX_CIRRUS_THIS s.nvgadev, redraw);
return;
}
#endif
if (redraw) {
redraw_area(0, 0, BX_CIRRUS_THIS s.last_xres, BX_CIRRUS_THIS s.last_yres);
}
svga_timer_handler(this_ptr);
}
void bx_svga_cirrus_c::svga_timer_handler(void *this_ptr)
{
#if !BX_USE_CIRRUS_SMF
bx_svga_cirrus_c *class_ptr = (bx_svga_cirrus_c *) this_ptr;
class_ptr->svga_timer();
}
void bx_svga_cirrus_c::svga_timer(void)
{
#else // !BX_USE_CIRRUS_SMF
UNUSED(this_ptr);
#endif // !BX_USE_CIRRUS_SMF
BX_CIRRUS_THIS svga_update();
bx_gui->flush();
}
void bx_svga_cirrus_c::svga_modeupdate(void)
{
Bit32u iTopOffset, iWidth, iHeight;
@ -1214,16 +1167,10 @@ void bx_svga_cirrus_c::draw_hardware_cursor(unsigned xc, unsigned yc, bx_svga_ti
}
}
void bx_svga_cirrus_c::svga_update(void)
void bx_svga_cirrus_c::update(void)
{
unsigned width, height, pitch;
#if BX_SUPPORT_PCI
if (BX_CIRRUS_THIS s.vga_override && (BX_CIRRUS_THIS s.nvgadev != NULL)) {
BX_CIRRUS_THIS s.nvgadev->update();
return;
}
#endif
/* skip screen update when the sequencer is in reset mode or video is disabled */
if (! BX_CIRRUS_THIS s.sequencer.reset1 ||
! BX_CIRRUS_THIS s.sequencer.reset2 ||

View File

@ -70,7 +70,6 @@ public:
virtual void init_vga_extension(void);
virtual void reset(unsigned type);
virtual void refresh_display(void *this_ptr, bx_bool redraw);
virtual void redraw_area(unsigned x0, unsigned y0,
unsigned width, unsigned height);
virtual Bit8u mem_read(bx_phy_address addr);
@ -87,6 +86,9 @@ public:
virtual void debug_dump(int argc, char **argv);
#endif
protected:
virtual void update(void);
private:
static Bit32u svga_read_handler(void *this_ptr, Bit32u address, unsigned io_len);
static void svga_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
@ -97,11 +99,7 @@ private:
BX_CIRRUS_SMF void mem_write_mode4and5_8bpp(Bit8u mode, Bit32u offset, Bit8u value);
BX_CIRRUS_SMF void mem_write_mode4and5_16bpp(Bit8u mode, Bit32u offset, Bit8u value);
static void svga_timer_handler(void *);
static Bit64s svga_param_handler(bx_param_c *param, int set, Bit64s val);
BX_CIRRUS_SMF void svga_timer(void);
BX_CIRRUS_SMF void svga_modeupdate(void);
BX_CIRRUS_SMF void svga_update(void);
BX_CIRRUS_SMF void svga_init_members();

View File

@ -92,7 +92,7 @@ void bx_vga_c::init_vga_extension(void)
Bit16u max_xres, max_yres, max_bpp;
BX_VGA_THIS init_iohandlers(read_handler, write_handler);
BX_VGA_THIS init_systemtimer(timer_handler, vga_param_handler);
BX_VGA_THIS init_systemtimer();
BX_VGA_THIS pci_enabled = SIM->is_pci_device("pcivga");
// The following is for the VBE display extension
@ -100,7 +100,7 @@ void bx_vga_c::init_vga_extension(void)
BX_VGA_THIS vbe.enabled = 0;
BX_VGA_THIS vbe.dac_8bit = 0;
BX_VGA_THIS vbe.base_address = 0x0000;
if (!strcmp(SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr(), "vbe")) {
if (!strcmp(BX_VGA_THIS vgaext->getptr(), "vbe")) {
BX_VGA_THIS put("BXVGA");
for (addr=VBE_DISPI_IOPORT_INDEX; addr<=VBE_DISPI_IOPORT_DATA; addr++) {
DEV_register_ioread_handler(this, vbe_read_handler, addr, "vga video", 7);
@ -326,64 +326,10 @@ void bx_vga_c::write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_l
}
}
Bit64s bx_vga_c::vga_param_handler(bx_param_c *param, int set, Bit64s val)
{
// handler for runtime parameter 'vga: update_freq'
if (set) {
Bit32u update_interval = (Bit32u)(1000000 / val);
BX_INFO(("Changing timer interval to %d", update_interval));
BX_VGA_THIS timer_handler(theVga);
bx_virt_timer.activate_timer(BX_VGA_THIS timer_id, update_interval, 1);
if (update_interval < 300000) {
BX_VGA_THIS s.blink_counter = 300000 / (unsigned)update_interval;
} else {
BX_VGA_THIS s.blink_counter = 1;
}
}
return val;
}
void bx_vga_c::refresh_display(void *this_ptr, bx_bool redraw)
{
#if BX_SUPPORT_PCI
if (BX_VGA_THIS s.vga_override && (BX_VGA_THIS s.nvgadev != NULL)) {
BX_VGA_THIS s.nvgadev->refresh_display(BX_VGA_THIS s.nvgadev, redraw);
return;
}
#endif
if (redraw) {
redraw_area(0, 0, BX_VGA_THIS s.last_xres, BX_VGA_THIS s.last_yres);
}
timer_handler(this_ptr);
}
void bx_vga_c::timer_handler(void *this_ptr)
{
#if BX_USE_VGA_SMF == 0
bx_vga_c *class_ptr = (bx_vga_c *) this_ptr;
class_ptr->timer();
}
void bx_vga_c::timer(void)
{
#else
UNUSED(this_ptr);
#endif
update();
bx_gui->flush();
}
void bx_vga_c::update(void)
{
unsigned iHeight, iWidth;
#if BX_SUPPORT_PCI
if (BX_VGA_THIS s.vga_override && (BX_VGA_THIS s.nvgadev != NULL)) {
BX_VGA_THIS s.nvgadev->update();
return;
}
#endif
if (BX_VGA_THIS vbe.enabled) {
/* no screen update necessary */
if ((BX_VGA_THIS s.vga_mem_updated==0) && BX_VGA_THIS s.graphics_ctrl.graphics_alpha)

View File

@ -105,12 +105,6 @@ public:
unsigned width, unsigned height);
virtual void init_vga_extension(void);
virtual void refresh_display(void *this_ptr, bx_bool redraw);
static void timer_handler(void *);
#if BX_USE_VGA_SMF == 0
BX_VGA_SMF void timer(void);
#endif
#if BX_SUPPORT_PCI
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
@ -119,8 +113,6 @@ public:
virtual void debug_dump(int argc, char **argv);
#endif
static Bit64s vga_param_handler(bx_param_c *param, int set, Bit64s val);
protected:
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
#if BX_USE_VGA_SMF
@ -128,7 +120,7 @@ protected:
#endif
void write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
BX_VGA_SMF void update(void);
virtual void update(void);
// Bochs VBE section
#if BX_SUPPORT_PCI

View File

@ -100,6 +100,7 @@ void bx_vgacore_c::init(void)
{
unsigned x,y;
BX_VGA_THIS vgaext = SIM->get_param_string(BXPN_VGA_EXTENSION);
BX_VGA_THIS extension_init = 0;
BX_VGA_THIS pci_enabled = 0;
@ -116,10 +117,8 @@ void bx_vgacore_c::init(void)
for (x = 0; x < BX_VGA_THIS s.num_x_tiles; x++)
SET_TILE_UPDATED(x, y, 0);
char *strptr = SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr();
if (!BX_VGA_THIS extension_init &&
(strlen(strptr) > 0) && strcmp(strptr, "none")) {
BX_PANIC(("unknown display extension: %s", strptr));
if (!BX_VGA_THIS extension_init && !BX_VGA_THIS vgaext->isempty()) {
BX_PANIC(("unknown display extension: %s", BX_VGA_THIS vgaext->getptr()));
}
if (!BX_VGA_THIS pci_enabled) {
BX_MEM(0)->load_ROM(SIM->get_param_string(BXPN_VGA_ROM_PATH)->getptr(), 0xc0000, 1);
@ -128,8 +127,6 @@ void bx_vgacore_c::init(void)
void bx_vgacore_c::init_standard_vga(void)
{
char *extname;
// initialize VGA controllers and other internal stuff
BX_VGA_THIS s.vga_enabled = 1;
BX_VGA_THIS s.misc_output.color_emulation = 1;
@ -165,8 +162,7 @@ void bx_vgacore_c::init_standard_vga(void)
BX_VGA_THIS s.vga_override = 0;
// initialize memory, handlers and timer (depending on extension)
extname = SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr();
if ((strlen(extname) == 0) || (!strcmp(extname, "none"))) {
if (BX_VGA_THIS vgaext->isempty()) {
BX_VGA_THIS s.memsize = 0x40000;
if (BX_VGA_THIS s.memory == NULL)
BX_VGA_THIS s.memory = new Bit8u[BX_VGA_THIS s.memsize];
@ -257,16 +253,17 @@ void bx_vgacore_c::init_iohandlers(bx_read_handler_t f_read, bx_write_handler_t
}
}
void bx_vgacore_c::init_systemtimer(bx_timer_handler_t f_timer, param_event_handler f_param)
void bx_vgacore_c::init_systemtimer(void)
{
BX_VGA_THIS realtime = SIM->get_param_bool(BXPN_VGA_REALTIME)->get();
bx_param_num_c *vga_update_freq = SIM->get_param_num(BXPN_VGA_UPDATE_FREQUENCY);
Bit32u update_interval = (Bit32u)(1000000 / vga_update_freq->get());
BX_INFO(("interval=%u, mode=%s", update_interval, BX_VGA_THIS realtime ? "realtime":"standard"));
if (BX_VGA_THIS timer_id == BX_NULL_TIMER_HANDLE) {
BX_VGA_THIS timer_id = bx_virt_timer.register_timer(this, f_timer,
BX_VGA_THIS timer_id = bx_virt_timer.register_timer(this, vga_timer_handler,
update_interval, 1, 1, BX_VGA_THIS realtime, "vga");
vga_update_freq->set_handler(f_param);
vga_update_freq->set_handler(vga_param_handler);
vga_update_freq->set_device_param(this);
}
// VGA text mode cursor blink frequency 1.875 Hz
if (update_interval < 266666) {
@ -2377,3 +2374,52 @@ void bx_vgacore_c::redraw_area(unsigned x0, unsigned y0, unsigned width, unsigne
sizeof(BX_VGA_THIS s.text_snapshot));
}
}
void bx_vgacore_c::refresh_display(void *this_ptr, bx_bool redraw)
{
bx_vgacore_c *vgadev = (bx_vgacore_c *) this_ptr;
#if BX_SUPPORT_PCI
if (vgadev->s.vga_override && (vgadev->s.nvgadev != NULL)) {
vgadev->s.nvgadev->refresh_display(vgadev->s.nvgadev, redraw);
return;
}
#endif
if (redraw) {
redraw_area(0, 0, vgadev->s.last_xres, vgadev->s.last_yres);
}
vga_timer_handler(vgadev);
}
void bx_vgacore_c::vga_timer_handler(void *this_ptr)
{
bx_vgacore_c *vgadev = (bx_vgacore_c *) this_ptr;
#if BX_SUPPORT_PCI
if (vgadev->s.vga_override && (vgadev->s.nvgadev != NULL)) {
vgadev->s.nvgadev->update();
return;
}
#endif
vgadev->update();
bx_gui->flush();
}
#undef LOG_THIS
#define LOG_THIS vgadev->
Bit64s bx_vgacore_c::vga_param_handler(bx_param_c *param, int set, Bit64s val)
{
// handler for runtime parameter 'vga: update_freq'
if (set) {
Bit32u update_interval = (Bit32u)(1000000 / val);
bx_vgacore_c *vgadev = (bx_vgacore_c *)param->get_device_param();
BX_INFO(("Changing timer interval to %d", update_interval));
vga_timer_handler(vgadev);
bx_virt_timer.activate_timer(vgadev->timer_id, update_interval, 1);
if (update_interval < 266666) {
vgadev->s.blink_counter = 266666 / (unsigned)update_interval;
} else {
vgadev->s.blink_counter = 1;
}
}
return val;
}

View File

@ -65,7 +65,6 @@ public:
static bx_bool mem_write_handler(bx_phy_address addr, unsigned len, void *data, void *param);
virtual Bit8u mem_read(bx_phy_address addr);
virtual void mem_write(bx_phy_address addr, Bit8u value);
virtual void refresh_display(void *this_ptr, bx_bool redraw) {}
virtual void set_override(bx_bool enabled, void *dev);
virtual void register_state(bx_list_c *parent);
virtual void after_restore_state(void);
@ -75,16 +74,19 @@ public:
virtual void redraw_area(unsigned x0, unsigned y0,
unsigned width, unsigned height);
virtual void refresh_display(void *this_ptr, bx_bool redraw);
virtual void get_text_snapshot(Bit8u **text_snapshot, unsigned *txHeight,
unsigned *txWidth);
virtual void init_vga_extension(void) {}
static void vga_timer_handler(void *);
static Bit64s vga_param_handler(bx_param_c *param, int set, Bit64s val);
protected:
void init_standard_vga(void);
void init_gui(void);
void init_iohandlers(bx_read_handler_t f_read, bx_write_handler_t f_write);
void init_systemtimer(bx_timer_handler_t f_timer, param_event_handler f_param);
void init_systemtimer();
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
@ -93,7 +95,7 @@ protected:
void write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
Bit8u get_vga_pixel(Bit16u x, Bit16u y, Bit16u saddr, Bit16u lc, bx_bool bs, Bit8u **plane);
void update(void);
virtual void update(void);
void determine_screen_dimensions(unsigned *piHeight, unsigned *piWidth);
void calculate_retrace_timing(void);
bx_bool skip_update(void);
@ -238,6 +240,7 @@ protected:
int timer_id;
bx_bool realtime;
bx_param_string_c *vgaext;
bx_bool extension_init;
bx_bool pci_enabled;
};

View File

@ -633,6 +633,7 @@ void bx_voodoo_c::refresh_display(void *this_ptr, bx_bool redraw)
redraw_area(0, 0, v->fbi.width, v->fbi.height);
}
vertical_timer_handler(this_ptr);
update();
}
void bx_voodoo_c::vertical_timer_handler(void *this_ptr)