- extend bx_shadow_num_c so that it can handle bit fields of variable

length.  (The first guinea pig is the 2-bit IOPL field in eflags.)
  Also it can have a pointer to a Bit8u, Bit16u, Bit32u and signed
  equivalents and do the right thing.
- add lots more CPU fields as parameters: EBP ESI EDI ESP, all segment regs,
  LDTR, GDTR, eflags, DR*, TR*, CR*.  These are all visible on a
  ridiculously tall dialog box that will one day become the debugger.
This commit is contained in:
Bryce Denney 2002-09-11 03:53:48 +00:00
parent 3ad2afe73e
commit be2cdca3e0
2 changed files with 172 additions and 34 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.cc,v 1.55 2002-09-07 14:27:50 vruppert Exp $
// $Id: siminterface.cc,v 1.56 2002-09-11 03:53:48 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// See siminterface.h for description of the siminterface concept.
@ -620,53 +620,115 @@ bx_shadow_num_c::bx_shadow_num_c (bx_id id,
char *description,
Bit32s min,
Bit32s max,
Bit32s *ptr_to_real_val)
Bit32s *ptr_to_real_val,
Bit8u highbit,
Bit8u lowbit)
: bx_param_num_c (id, name, description, min, max, *ptr_to_real_val)
{
val.pointer = ptr_to_real_val;
this->varsize = 16;
this->lowbit = lowbit;
this->mask = (1 << (highbit - lowbit)) - 1;
val.p32bit = ptr_to_real_val;
}
bx_shadow_num_c::bx_shadow_num_c (bx_id id,
char *name,
char *description,
Bit32s min, Bit32s max, Bit32u *ptr_to_real_val)
Bit32s min, Bit32s max, Bit32u *ptr_to_real_val,
Bit8u highbit,
Bit8u lowbit)
: bx_param_num_c (id, name, description, min, max, *ptr_to_real_val)
{
val.pointer = (Bit32s*) ptr_to_real_val;
this->varsize = 32;
this->lowbit = lowbit;
this->mask = (1 << (highbit - lowbit)) - 1;
val.p32bit = (Bit32s*) ptr_to_real_val;
}
bx_shadow_num_c::bx_shadow_num_c (bx_id id,
char *name,
Bit32u *ptr_to_real_val)
char *name,
Bit32u *ptr_to_real_val,
Bit8u highbit,
Bit8u lowbit)
: bx_param_num_c (id, name, "", BX_MIN_INT, BX_MAX_INT, *ptr_to_real_val)
{
val.pointer = (Bit32s*) ptr_to_real_val;
this->varsize = 32;
this->lowbit = lowbit;
this->mask = (1 << (highbit - lowbit)) - 1;
val.p32bit = (Bit32s*) ptr_to_real_val;
}
bx_shadow_num_c::bx_shadow_num_c (bx_id id,
char *name,
Bit16u *ptr_to_real_val,
Bit8u highbit,
Bit8u lowbit)
: bx_param_num_c (id, name, "", BX_MIN_INT, BX_MAX_INT, *ptr_to_real_val)
{
this->varsize = 16;
this->lowbit = lowbit;
this->mask = (1 << (highbit - lowbit)) - 1;
val.p16bit = (Bit16s*) ptr_to_real_val;
}
bx_shadow_num_c::bx_shadow_num_c (bx_id id,
char *name,
Bit16s *ptr_to_real_val,
Bit8u highbit,
Bit8u lowbit)
: bx_param_num_c (id, name, "", BX_MIN_INT, BX_MAX_INT, *ptr_to_real_val)
{
this->varsize = 16;
this->lowbit = lowbit;
this->mask = (1 << (highbit - lowbit)) - 1;
val.p16bit = ptr_to_real_val;
}
Bit32s
bx_shadow_num_c::get () {
Bit32u current;
switch (varsize) {
case 8: current = *(val.p8bit); break;
case 16: current = *(val.p16bit); break;
case 32: current = *(val.p32bit); break;
}
current = (current >> lowbit) & mask;
if (handler) {
// the handler can decide what value to return and/or do some side effect
return (*handler)(this, 0, *(val.pointer));
return (*handler)(this, 0, current) & mask;
} else {
// just return the value
return *(val.pointer);
return current;
}
}
void
bx_shadow_num_c::set (Bit32s newval)
{
Bit32u tmp;
if (newval < min || newval > max)
BX_PANIC (("numerical parameter %s was set to %d, which is out of range %d to %d", get_name (), newval, min, max));
switch (varsize) {
case 8:
tmp = (*(val.p8bit) >> lowbit) & mask;
tmp |= (newval & mask) << lowbit;
*(val.p8bit) = tmp;
break;
case 16:
tmp = (*(val.p16bit) >> lowbit) & mask;
tmp |= (newval & mask) << lowbit;
*(val.p16bit) = tmp;
break;
case 32:
tmp = (*(val.p32bit) >> lowbit) & mask;
tmp |= (newval & mask) << lowbit;
*(val.p32bit) = tmp;
break;
}
if (handler) {
// the handler can override the new value and/or perform some side effect
*(val.pointer) = newval;
(*handler)(this, 1, newval);
} else {
// just set the value.
*(val.pointer) = newval;
(*handler)(this, 1, tmp);
}
if (*(val.pointer) < min || *(val.pointer) > max)
BX_PANIC (("numerical parameter %s was set to %d, which is out of range %d to %d", get_name (), *(val.pointer), min, max));
}
bx_param_bool_c::bx_param_bool_c (bx_id id,
@ -693,33 +755,36 @@ void bx_param_bool_c::update_dependents ()
bx_shadow_bool_c::bx_shadow_bool_c (bx_id id,
char *name,
Boolean *ptr_to_real_val)
Boolean *ptr_to_real_val,
Bit8u bitnum)
: bx_param_bool_c (id, name, "", (Bit32s) *ptr_to_real_val)
{
val.pbool = ptr_to_real_val;
this->bitnum = bitnum;
}
Bit32s
bx_shadow_bool_c::get () {
if (handler) {
// the handler can decide what value to return and/or do some side effect
return (*handler)(this, 0, (Bit32s) *(val.pbool));
Bit32s ret = (*handler)(this, 0, (Bit32s) *(val.pbool));
return (ret>>bitnum) & 1;
} else {
// just return the value
return (Bit32s) *(val.pbool);
return (*(val.pbool)) & 1;
}
}
void
bx_shadow_bool_c::set (Bit32s newval)
{
// only change the bitnum bit
Bit32s tmp = (newval&1) << bitnum;
*(val.pbool) &= ~tmp;
*(val.pbool) |= tmp;
if (handler) {
// the handler can override the new value and/or perform some side effect
*(val.pbool) = (bool) newval;
(*handler)(this, 1, newval);
} else {
// just set the value. This code does not check max/min.
*(val.pbool) = (bool) newval;
(*handler)(this, 1, newval&1);
}
}
@ -914,7 +979,7 @@ void
bx_list_c::add (bx_param_c *param)
{
if (this->size >= this->maxsize)
BX_PANIC (("bx_list_c::add parameter id=%u exceeds capacity of list", param->get_id ()));
BX_PANIC (("add param %u to bx_list_c id=%u: list capacity exceeded", param->get_id (), get_id ()));
list[size] = param;
size++;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.h,v 1.59 2002-09-06 16:43:23 bdenney Exp $
// $Id: siminterface.h,v 1.60 2002-09-11 03:53:47 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Before I can describe what this file is for, I have to make the
@ -231,8 +231,56 @@ typedef enum {
BXP_CPU_EBX,
BXP_CPU_ECX,
BXP_CPU_EDX,
BXP_CPU_CS,
BXP_CPU_EBP,
BXP_CPU_ESI,
BXP_CPU_EDI,
BXP_CPU_ESP,
BXP_CPU_EIP,
BXP_CPU_SEG_CS,
BXP_CPU_SEG_DS,
BXP_CPU_SEG_SS,
BXP_CPU_SEG_ES,
BXP_CPU_SEG_FS,
BXP_CPU_SEG_GS,
BXP_CPU_SEG_LDTR,
BXP_CPU_SEG_TR,
BXP_CPU_GDTR_BASE,
BXP_CPU_GDTR_LIMIT,
BXP_CPU_IDTR_BASE,
BXP_CPU_IDTR_LIMIT,
BXP_CPU_EFLAGS_ID,
BXP_CPU_EFLAGS_VIP,
BXP_CPU_EFLAGS_VIF,
BXP_CPU_EFLAGS_AC,
BXP_CPU_EFLAGS_VM,
BXP_CPU_EFLAGS_RF,
BXP_CPU_EFLAGS_NT,
BXP_CPU_EFLAGS_IOPL,
BXP_CPU_EFLAGS_OF,
BXP_CPU_EFLAGS_DF,
BXP_CPU_EFLAGS_IF,
BXP_CPU_EFLAGS_TF,
BXP_CPU_EFLAGS_SF,
BXP_CPU_EFLAGS_ZF,
BXP_CPU_EFLAGS_AF,
BXP_CPU_EFLAGS_PF,
BXP_CPU_EFLAGS_CF,
BXP_CPU_DR0,
BXP_CPU_DR1,
BXP_CPU_DR2,
BXP_CPU_DR3,
BXP_CPU_DR6,
BXP_CPU_DR7,
BXP_CPU_TR3,
BXP_CPU_TR4,
BXP_CPU_TR5,
BXP_CPU_TR6,
BXP_CPU_TR7,
BXP_CPU_CR0,
BXP_CPU_CR1,
BXP_CPU_CR2,
BXP_CPU_CR3,
BXP_CPU_CR4,
// a few parameters for the keyboard
BXP_KBD_PARAMETERS,
BXP_KBD_PARE,
@ -610,7 +658,9 @@ protected:
Bit32s min, max, initial_val;
union _uval_ {
Bit32s number; // used by bx_param_num_c
Bit32s *pointer; // used by bx_shadow_num_c
Bit32s *p32bit; // used by bx_shadow_num_c
Bit16s *p16bit; // used by bx_shadow_num_c
Bit8s *p8bit; // used by bx_shadow_num_c
Boolean *pbool; // used by bx_shadow_bool_c
} val;
param_event_handler handler;
@ -637,23 +687,42 @@ public:
};
// a bx_shadow_num_c is like a bx_param_num_c except that it doesn't
// store the actual value with its data. Instead, it uses val.pointer
// store the actual value with its data. Instead, it uses val.p32bit
// to keep a pointer to the actual data. This is used to register
// existing variables as parameters, without have to access it via
// set/get methods.
class bx_shadow_num_c : public bx_param_num_c {
Bit8u varsize; // must be 32, 16, or 8
Bit8u lowbit; // range of bits associated with this param
Bit32u mask; // mask is ANDed with value before it is returned from get
public:
bx_shadow_num_c (bx_id id,
char *name,
char *description,
Bit32s min, Bit32s max, Bit32s *ptr_to_real_val);
Bit32s min, Bit32s max, Bit32s *ptr_to_real_val,
Bit8u highbit = 31,
Bit8u lowbit = 0);
bx_shadow_num_c (bx_id id,
char *name,
char *description,
Bit32s min, Bit32s max, Bit32u *ptr_to_real_val);
Bit32s min, Bit32s max, Bit32u *ptr_to_real_val,
Bit8u highbit = 31,
Bit8u lowbit = 0);
bx_shadow_num_c (bx_id id,
char *name,
Bit32u *ptr_to_real_val);
Bit32u *ptr_to_real_val,
Bit8u highbit = 31,
Bit8u lowbit = 0);
bx_shadow_num_c (bx_id id,
char *name,
Bit16s *ptr_to_real_val,
Bit8u highbit = 15,
Bit8u lowbit = 0);
bx_shadow_num_c (bx_id id,
char *name,
Bit16u *ptr_to_real_val,
Bit8u highbit = 15,
Bit8u lowbit = 0);
virtual Bit32s get ();
virtual void set (Bit32s val);
};
@ -687,10 +756,14 @@ public:
// a bx_shadow_bool_c is a shadow param based on bx_param_bool_c.
class bx_shadow_bool_c : public bx_param_bool_c {
// each bit of a bitfield can be a separate value. bitnum tells which
// bit is used. get/set will only modify that bit.
Bit8u bitnum;
public:
bx_shadow_bool_c (bx_id id,
char *name,
Boolean *ptr_to_real_val);
Boolean *ptr_to_real_val,
Bit8u bitnum = 0);
virtual Bit32s get ();
virtual void set (Bit32s val);
};