- 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
This commit is contained in:
Volker Ruppert 2011-12-28 11:51:42 +00:00
parent 2b8371f2b6
commit 0b2bec6752
15 changed files with 113 additions and 57 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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]);
}
}

View File

@ -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; i<statusitem_count; i++) {
sdl_set_status_text(i+1, statusitem_text[i], statusitem_active[i+1]);
sdl_set_status_text(i+1, statusitem[i].text, statusitem_active[i+1]);
}
}

View File

@ -961,10 +961,14 @@ void bx_win32_gui_c::statusbar_setitem(int element, bx_bool active, bx_bool w)
{
if (element < 0) {
for (int i = 0; i < (int)statusitem_count; i++) {
SetStatusText(i+BX_SB_TEXT_ELEMENTS, statusitem_text[i], active, w);
SetStatusText(i+BX_SB_TEXT_ELEMENTS, statusitem[i].text, active, w);
}
} else if (element < (int)statusitem_count) {
SetStatusText(element+BX_SB_TEXT_ELEMENTS, statusitem_text[element], active, w);
SetStatusText(element+BX_SB_TEXT_ELEMENTS, statusitem[element].text, active, w);
statusitem[element].mode = w;
if (active && statusitem[element].auto_off) {
statusitem[element].counter = 10;
}
}
}

View File

@ -1086,10 +1086,10 @@ 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[i]);
strcpy(status_text+1, statusitem[i].text);
theFrame->SetStatusText(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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -96,6 +96,7 @@ typedef struct {
} eecd_state;
int tx_timer_index;
int statusbar_id;
Bit8u devfunc;
} bx_e1000_t;

View File

@ -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<BX_MAX_ATA_CHANNEL; channel++) {
for (unsigned device=0; device<2; device++) {
if (BX_HD_THIS channels[channel].drives[device].iolight_counter > 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));

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -55,6 +55,7 @@ typedef struct {
Bit8u devfunc;
int statusbar_id;
} bx_pnic_t;