From 0b2bec6752c740b2dc404feb81d9bbfb81281284 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Wed, 28 Dec 2011 11:51:42 +0000 Subject: [PATCH] - implemented "auto-off" timer for the status bar LEDs that replaces the existing "iolight timer" code in the hard drive code. If an LED is registered with the "auto-off" flag, the device only needs to turn on the LED to indicate data transfer. The LED timer in the gui code turns it off after 0.5 seconds if it is not actived by another transfer. Added this feature to all network devices. - TODO #1: implement this feature in the USB host controllers - TODO #2: the unused timer in the hard drive code could be used for the emulation of seek functions --- bochs/gui/gui.cc | 34 ++++++++++++++++++++++++++--- bochs/gui/gui.h | 15 +++++++++++-- bochs/gui/rfb.cc | 10 ++++++--- bochs/gui/sdl.cc | 10 ++++++--- bochs/gui/win32.cc | 8 +++++-- bochs/gui/wx.cc | 12 +++++++---- bochs/gui/x.cc | 10 ++++++--- bochs/iodev/e1000.cc | 4 ++++ bochs/iodev/e1000.h | 1 + bochs/iodev/harddrv.cc | 49 ++++++++++++++---------------------------- bochs/iodev/harddrv.h | 7 +++--- bochs/iodev/ne2k.cc | 4 ++++ bochs/iodev/ne2k.h | 1 + bochs/iodev/pcipnic.cc | 4 ++++ bochs/iodev/pcipnic.h | 1 + 15 files changed, 113 insertions(+), 57 deletions(-) diff --git a/bochs/gui/gui.cc b/bochs/gui/gui.cc index 1308ecba0..a9350047b 100644 --- a/bochs/gui/gui.cc +++ b/bochs/gui/gui.cc @@ -98,6 +98,7 @@ bx_gui_c::bx_gui_c(void) { put("GUI"); // Init in specific_init statusitem_count = 0; + led_timer_index = BX_NULL_TIMER_HANDLE; framebuffer = NULL; } @@ -244,6 +245,12 @@ void bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheig BX_GUI_THIS framebuffer = new Bit8u[BX_MAX_XRES * BX_MAX_YRES * 4]; } show_headerbar(); + + // register timer for status bar LEDs + if (BX_GUI_THIS led_timer_index == BX_NULL_TIMER_HANDLE) { + BX_GUI_THIS led_timer_index = + DEV_register_timer(this, led_timer_handler, 50000, 1, 1, "status bar LEDs"); + } } void bx_gui_c::cleanup(void) @@ -745,17 +752,38 @@ void bx_gui_c::beep_off() BX_DEBUG(("GUI Beep OFF")); } -int bx_gui_c::register_statusitem(const char *text) +int bx_gui_c::register_statusitem(const char *text, bx_bool auto_off) { if (statusitem_count < BX_MAX_STATUSITEMS) { - strncpy(statusitem_text[statusitem_count], text, 8); - statusitem_text[statusitem_count][7] = 0; + strncpy(statusitem[statusitem_count].text, text, 8); + statusitem[statusitem_count].text[7] = 0; + statusitem[statusitem_count].auto_off = auto_off; + statusitem[statusitem_count].counter = 0; return statusitem_count++; } else { return -1; } } +void bx_gui_c::led_timer_handler(void *this_ptr) +{ + bx_gui_c *class_ptr = (bx_gui_c *) this_ptr; + class_ptr->led_timer(); +} + +void bx_gui_c::led_timer() +{ + for (unsigned i = 0; i < statusitem_count; i++) { + if (statusitem[i].auto_off) { + if (statusitem[i].counter > 0) { + if (!(--statusitem[i].counter)) { + statusbar_setitem(i, 0); + } + } + } + } +} + void bx_gui_c::get_capabilities(Bit16u *xres, Bit16u *yres, Bit16u *bpp) { *xres = 1024; diff --git a/bochs/gui/gui.h b/bochs/gui/gui.h index 1cd7afe47..9bdf802f4 100644 --- a/bochs/gui/gui.h +++ b/bochs/gui/gui.h @@ -149,7 +149,7 @@ public: void cleanup(void); void update_drive_status_buttons(void); static void mouse_enabled_changed(bx_bool val); - int register_statusitem(const char *text); + int register_statusitem(const char *text, bx_bool auto_off=0); static void init_signal_handlers(); static void toggle_mouse_enable(void); bx_bool mouse_toggle_check(Bit32u key, bx_bool pressed); @@ -170,6 +170,9 @@ protected: static void userbutton_handler(void); static void save_restore_handler(void); + static void led_timer_handler(void *); + void led_timer(void); + bx_bool floppyA_status; bx_bool floppyB_status; bx_bool cdrom1_status; @@ -189,8 +192,16 @@ protected: unsigned char vga_charmap[0x2000]; bx_bool charmap_updated; bx_bool char_changed[256]; + unsigned statusitem_count; - char statusitem_text[BX_MAX_STATUSITEMS][8]; + int led_timer_index; + struct { + char text[8]; + bx_bool mode; // read/write + bx_bool auto_off; + Bit8u counter; + } statusitem[BX_MAX_STATUSITEMS]; + disp_mode_t disp_mode; bx_bool new_gfx_api; Bit16u host_xres; diff --git a/bochs/gui/rfb.cc b/bochs/gui/rfb.cc index 832f5c8d8..8fab30224 100644 --- a/bochs/gui/rfb.cc +++ b/bochs/gui/rfb.cc @@ -335,10 +335,14 @@ void bx_rfb_gui_c::statusbar_setitem(int element, bx_bool active, bx_bool w) { if (element < 0) { for (unsigned i = 0; i < statusitem_count; i++) { - rfbSetStatusText(i+1, statusitem_text[i], active, w); + rfbSetStatusText(i+1, statusitem[i].text, active, w); } } else if ((unsigned)element < statusitem_count) { - rfbSetStatusText(element+1, statusitem_text[element], active, w); + rfbSetStatusText(element+1, statusitem[element].text, active, w); + statusitem[element].mode = w; + if (active && statusitem[element].auto_off) { + statusitem[element].counter = 10; + } } } @@ -1068,7 +1072,7 @@ void bx_rfb_gui_c::show_headerbar(void) DrawBitmap(0, rfbWindowY - rfbStatusbarY, rfbWindowX, rfbStatusbarY, newBits, (char)0xf0, false); free(newBits); for (i = 1; i <= statusitem_count; i++) { - rfbSetStatusText(i, statusitem_text[i-1], rfbStatusitemActive[i]); + rfbSetStatusText(i, statusitem[i-1].text, rfbStatusitemActive[i]); } } diff --git a/bochs/gui/sdl.cc b/bochs/gui/sdl.cc index be27571b7..5a1cda830 100644 --- a/bochs/gui/sdl.cc +++ b/bochs/gui/sdl.cc @@ -431,10 +431,14 @@ void bx_sdl_gui_c::statusbar_setitem(int element, bx_bool active, bx_bool w) { if (element < 0) { for (unsigned i = 0; i < statusitem_count; i++) { - sdl_set_status_text(i+1, statusitem_text[i], active, w); + sdl_set_status_text(i+1, statusitem[i].text, active, w); } } else if ((unsigned)element < statusitem_count) { - sdl_set_status_text(element+1, statusitem_text[element], active, w); + sdl_set_status_text(element+1, statusitem[element].text, active, w); + statusitem[element].mode = w; + if (active && statusitem[element].auto_off) { + statusitem[element].counter = 10; + } } } @@ -1506,7 +1510,7 @@ void bx_sdl_gui_c::show_headerbar(void) } while(--rowsleft); SDL_UpdateRect( sdl_screen, 0,res_y+headerbar_height,res_x,statusbar_height); for (unsigned i=0; iSetStatusText(status_text, i+1); #else - theFrame->SetStatusText(wxString(statusitem_text[i], wxConvUTF8), i+1); + theFrame->SetStatusText(wxString(statusitem[i].text, wxConvUTF8), i+1); #endif } else { theFrame->SetStatusText(wxT(""), i+1); @@ -1099,12 +1099,16 @@ void bx_wx_gui_c::statusbar_setitem(int element, bx_bool active, bx_bool w) if (active) { #if defined(__WXMSW__) status_text[0] = 9; - strcpy(status_text+1, statusitem_text[element]); + strcpy(status_text+1, statusitem[element].text); theFrame->SetStatusText(status_text, element+1); #else - theFrame->SetStatusText(wxString(statusitem_text[element], wxConvUTF8), + theFrame->SetStatusText(wxString(statusitem[element].text, wxConvUTF8), element+1); #endif + statusitem[element].mode = w; + if (active && statusitem[element].auto_off) { + statusitem[element].counter = 10; + } } else { theFrame->SetStatusText(wxT(""), element+1); } diff --git a/bochs/gui/x.cc b/bochs/gui/x.cc index 61a88ccc6..d884c42de 100644 --- a/bochs/gui/x.cc +++ b/bochs/gui/x.cc @@ -712,10 +712,14 @@ void bx_x_gui_c::statusbar_setitem(int element, bx_bool active, bx_bool w) { if (element < 0) { for (unsigned i = 0; i < statusitem_count; i++) { - set_status_text(i+1, statusitem_text[i], active, w); + set_status_text(i+1, statusitem[i].text, active, w); } } else if ((unsigned)element < statusitem_count) { - set_status_text(element+1, statusitem_text[element], active, w); + set_status_text(element+1, statusitem[element].text, active, w); + statusitem[element].mode = w; + if (active && statusitem[element].auto_off) { + statusitem[element].counter = 10; + } } } @@ -1748,7 +1752,7 @@ void bx_x_gui_c::show_headerbar(void) XDrawLine(bx_x_display, win, gc_inv, xleft, sb_ypos+1, xleft, sb_ypos+bx_statusbar_y); if (i <= statusitem_count) { - set_status_text(i, statusitem_text[i-1], bx_statusitem_active[i]); + set_status_text(i, statusitem[i-1].text, bx_statusitem_active[i]); } } else { set_status_text(0, bx_status_info_text, 0); diff --git a/bochs/iodev/e1000.cc b/bochs/iodev/e1000.cc index 1f721fe94..5fcfb27c5 100644 --- a/bochs/iodev/e1000.cc +++ b/bochs/iodev/e1000.cc @@ -478,6 +478,7 @@ void bx_e1000_c::init(void) bx_pc_system.register_timer(this, tx_timer_handler, 0, 0, 0, "e1000"); // one-shot, inactive } + BX_E1000_THIS s.statusbar_id = bx_gui->register_statusitem("E1000", 1); // Attach to the selected ethernet module BX_E1000_THIS ethdev = DEV_net_init_module(base, rx_handler, rx_status_handler, this); @@ -1266,6 +1267,7 @@ void bx_e1000_c::start_xmit() } BX_E1000_THIS s.tx.int_cause = cause; bx_pc_system.activate_timer(BX_E1000_THIS s.tx_timer_index, 10, 0); // not continuous + bx_gui->statusbar_setitem(BX_E1000_THIS s.statusbar_id, 1, 1); } void bx_e1000_c::tx_timer_handler(void *this_ptr) @@ -1487,6 +1489,8 @@ void bx_e1000_c::rx_frame(const void *buf, unsigned buf_size) n |= E1000_ICS_RXDMT0; set_ics(n); + + bx_gui->statusbar_setitem(BX_E1000_THIS s.statusbar_id, 1); } diff --git a/bochs/iodev/e1000.h b/bochs/iodev/e1000.h index c3cb2d2d0..2c6286d4d 100644 --- a/bochs/iodev/e1000.h +++ b/bochs/iodev/e1000.h @@ -96,6 +96,7 @@ typedef struct { } eecd_state; int tx_timer_index; + int statusbar_id; Bit8u devfunc; } bx_e1000_t; diff --git a/bochs/iodev/harddrv.cc b/bochs/iodev/harddrv.cc index 1f6c67f40..5f3846dc2 100644 --- a/bochs/iodev/harddrv.cc +++ b/bochs/iodev/harddrv.cc @@ -134,7 +134,7 @@ bx_hard_drive_c::bx_hard_drive_c() #endif } } - iolight_timer_index = BX_NULL_TIMER_HANDLE; + seek_timer_index = BX_NULL_TIMER_HANDLE; } bx_hard_drive_c::~bx_hard_drive_c() @@ -266,7 +266,6 @@ void bx_hard_drive_c::init(void) // If not present BX_HD_THIS channels[channel].drives[device].device_type = IDE_NONE; BX_HD_THIS channels[channel].drives[device].statusbar_id = -1; - BX_HD_THIS channels[channel].drives[device].iolight_counter = 0; BX_HD_THIS channels[channel].drives[device].identify_set = 0; if (!SIM->get_param_bool("present", base)->get()) continue; @@ -283,7 +282,7 @@ void bx_hard_drive_c::init(void) BX_HD_THIS channels[channel].drives[device].device_type = IDE_DISK; sprintf(sbtext, "HD:%d-%s", channel, device?"S":"M"); BX_HD_THIS channels[channel].drives[device].statusbar_id = - bx_gui->register_statusitem(sbtext); + bx_gui->register_statusitem(sbtext, 1); int cyl = SIM->get_param_num("cylinders", base)->get(); int heads = SIM->get_param_num("heads", base)->get(); @@ -359,7 +358,7 @@ void bx_hard_drive_c::init(void) BX_HD_THIS channels[channel].drives[device].sense.ascq = 0; sprintf(sbtext, "CD:%d-%s", channel, device?"S":"M"); BX_HD_THIS channels[channel].drives[device].statusbar_id = - bx_gui->register_statusitem(sbtext); + bx_gui->register_statusitem(sbtext, 1); BX_HD_THIS cdrom_count++; BX_HD_THIS channels[channel].drives[device].device_num = BX_HD_THIS cdrom_count + 48; @@ -549,10 +548,11 @@ void bx_hard_drive_c::init(void) SIM->get_param_bool(BXPN_FLOPPYSIGCHECK)->get() ? "dis" : "en")); } - // register timer for HD/CD i/o light - if (BX_HD_THIS iolight_timer_index == BX_NULL_TIMER_HANDLE) { - BX_HD_THIS iolight_timer_index = - DEV_register_timer(this, iolight_timer_handler, 100000, 0,0, "HD/CD i/o light"); + // register timer for HD/CD seek emulation + if (BX_HD_THIS seek_timer_index == BX_NULL_TIMER_HANDLE) { + BX_HD_THIS seek_timer_index = + DEV_register_timer(this, seek_timer_handler, 100000, 0,0, "HD/CD seek"); + // TODO !!! } // register handler for correct cdrom parameter handling after runtime config @@ -623,22 +623,17 @@ void bx_hard_drive_c::register_state(void) } } -void bx_hard_drive_c::iolight_timer_handler(void *this_ptr) +void bx_hard_drive_c::seek_timer_handler(void *this_ptr) { bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr; - class_ptr->iolight_timer(); + class_ptr->seek_timer(); } -void bx_hard_drive_c::iolight_timer() +void bx_hard_drive_c::seek_timer() { for (unsigned channel=0; channel 0) { - if (--BX_HD_THIS channels[channel].drives[device].iolight_counter) - bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0); - else - bx_gui->statusbar_setitem(BX_HD_THIS channels[channel].drives[device].statusbar_id, 0); - } + // TODO: seek emulation } } } @@ -863,10 +858,7 @@ Bit32u bx_hard_drive_c::read(Bit32u address, unsigned io_len) BX_PANIC(("Read with CDROM not ready")); } /* set status bar conditions for device */ - if (!BX_SELECTED_DRIVE(channel).iolight_counter) - bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1); - BX_SELECTED_DRIVE(channel).iolight_counter = 5; - bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0); + bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1); if (!BX_SELECTED_DRIVE(channel).cdrom.cd->read_block(BX_SELECTED_CONTROLLER(channel).buffer, BX_SELECTED_DRIVE(channel).cdrom.next_lba, BX_SELECTED_CONTROLLER(channel).buffer_size)) @@ -3227,10 +3219,7 @@ bx_bool bx_hard_drive_c::bmdma_read_sector(Bit8u channel, Bit8u *buffer, Bit32u return 0; } /* set status bar conditions for device */ - if (!BX_SELECTED_DRIVE(channel).iolight_counter) - bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1); - BX_SELECTED_DRIVE(channel).iolight_counter = 5; - bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0); + bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1); #ifdef LOWLEVEL_CDROM if (!BX_SELECTED_DRIVE(channel).cdrom.cd->read_block(buffer, BX_SELECTED_DRIVE(channel).cdrom.next_lba, BX_SELECTED_CONTROLLER(channel).buffer_size)) @@ -3330,10 +3319,7 @@ bx_bool bx_hard_drive_c::ide_read_sector(Bit8u channel, Bit8u *buffer, Bit32u bu return 0; } /* set status bar conditions for device */ - if (!BX_SELECTED_DRIVE(channel).iolight_counter) - bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1); - BX_SELECTED_DRIVE(channel).iolight_counter = 5; - bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0); + bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1); ret = BX_SELECTED_DRIVE(channel).hdimage->read((bx_ptr_t)bufptr, 512); if (ret < 512) { BX_ERROR(("could not read() hard drive image file at byte %lu", (unsigned long)logical_sector*512)); @@ -3367,10 +3353,7 @@ bx_bool bx_hard_drive_c::ide_write_sector(Bit8u channel, Bit8u *buffer, Bit32u b return 0; } /* set status bar conditions for device */ - if (!BX_SELECTED_DRIVE(channel).iolight_counter) - bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1, 1 /* write */); - BX_SELECTED_DRIVE(channel).iolight_counter = 5; - bx_pc_system.activate_timer(BX_HD_THIS iolight_timer_index, 100000, 0); + bx_gui->statusbar_setitem(BX_SELECTED_DRIVE(channel).statusbar_id, 1, 1 /* write */); ret = BX_SELECTED_DRIVE(channel).hdimage->write((bx_ptr_t)bufptr, 512); if (ret < 512) { BX_ERROR(("could not write() hard drive image file at byte %lu", (unsigned long)logical_sector*512)); diff --git a/bochs/iodev/harddrv.h b/bochs/iodev/harddrv.h index 4d2760c3f..91ed6e79e 100644 --- a/bochs/iodev/harddrv.h +++ b/bochs/iodev/harddrv.h @@ -197,8 +197,8 @@ public: 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); - static void iolight_timer_handler(void *); - BX_HD_SMF void iolight_timer(void); + static void seek_timer_handler(void *); + BX_HD_SMF void seek_timer(void); static void runtime_config_handler(void *); void runtime_config(void); @@ -248,7 +248,6 @@ private: Bit8u model_no[41]; int statusbar_id; - int iolight_counter; Bit8u device_num; // for ATAPI identify & inquiry bx_bool status_changed; } drives[2]; @@ -260,7 +259,7 @@ private: } channels[BX_MAX_ATA_CHANNEL]; - int iolight_timer_index; + int seek_timer_index; Bit8u cdrom_count; }; diff --git a/bochs/iodev/ne2k.cc b/bochs/iodev/ne2k.cc index cf607ef34..b4588968a 100644 --- a/bochs/iodev/ne2k.cc +++ b/bochs/iodev/ne2k.cc @@ -343,6 +343,7 @@ void bx_ne2k_c::write_cr(Bit32u value) (64 + 96 + 4*8 + BX_NE2K_THIS s.tx_bytes*8)/10, 0); // not continuous BX_NE2K_THIS s.tx_timer_active = 1; + bx_gui->statusbar_setitem(BX_NE2K_THIS s.statusbar_id, 1, 1); } // Linux probes for an interrupt by setting up a remote-DMA read @@ -1468,6 +1469,7 @@ void bx_ne2k_c::rx_frame(const void *buf, unsigned io_len) set_irq_level(1); } + bx_gui->statusbar_setitem(BX_NE2K_THIS s.statusbar_id, 1); } void bx_ne2k_c::init(void) @@ -1587,6 +1589,8 @@ void bx_ne2k_c::init(void) for (int i = 12; i < 32; i++) BX_NE2K_THIS s.macaddr[i] = 0x57; + BX_NE2K_THIS s.statusbar_id = bx_gui->register_statusitem("NE2K", 1); + // Attach to the selected ethernet module BX_NE2K_THIS ethdev = DEV_net_init_module(base, rx_handler, rx_status_handler, this); } diff --git a/bochs/iodev/ne2k.h b/bochs/iodev/ne2k.h index 525249bd7..d5fd8a21b 100644 --- a/bochs/iodev/ne2k.h +++ b/bochs/iodev/ne2k.h @@ -188,6 +188,7 @@ typedef struct { int base_irq; int tx_timer_index; bx_bool tx_timer_active; + int statusbar_id; // pci stuff bx_bool pci_enabled; diff --git a/bochs/iodev/pcipnic.cc b/bochs/iodev/pcipnic.cc index 7455d6a4c..4f31ad59d 100644 --- a/bochs/iodev/pcipnic.cc +++ b/bochs/iodev/pcipnic.cc @@ -78,6 +78,8 @@ void bx_pcipnic_c::init(void) BX_PNIC_THIS pci_conf[i] = 0x0; } + BX_PNIC_THIS s.statusbar_id = bx_gui->register_statusitem("PNIC", 1); + // Attach to the selected ethernet module BX_PNIC_THIS ethdev = DEV_net_init_module(base, rx_handler, rx_status_handler, this); @@ -468,6 +470,7 @@ void bx_pcipnic_c::exec_command(void) case PNIC_CMD_XMIT: BX_PNIC_THIS ethdev->sendpkt(data, ilength); + bx_gui->statusbar_setitem(BX_PNIC_THIS s.statusbar_id, 1, 1); if (BX_PNIC_THIS s.irqEnabled) { set_irq_level(1); } @@ -587,6 +590,7 @@ void bx_pcipnic_c::rx_frame(const void *buf, unsigned io_len) if (BX_PNIC_THIS s.irqEnabled) { set_irq_level(1); } + bx_gui->statusbar_setitem(BX_PNIC_THIS s.statusbar_id, 1); } #endif // BX_SUPPORT_PCI && BX_SUPPORT_PCIPNIC diff --git a/bochs/iodev/pcipnic.h b/bochs/iodev/pcipnic.h index ddc93eeb4..a0956f240 100644 --- a/bochs/iodev/pcipnic.h +++ b/bochs/iodev/pcipnic.h @@ -55,6 +55,7 @@ typedef struct { Bit8u devfunc; + int statusbar_id; } bx_pnic_t;