- the debugger was broken by recent changes in the cpu flags. To provide

a consistent way of accessing these flags that works both inside and
  outside the BX_CPU class, I added inline accessor methods for each
  flag: assert_FLAG(), clear_FLAG(), set_FLAG(value), and get_FLAG ()
  that returns its value.  I use assert to mean "set the value to one"
  to avoid confusion, since there's also a set method that takes a value.
- the eflags access macros (e.g. GetEFlagsDFLogical, ClearEFlagsTF) are
  now defined in terms of the inline accessors.  In most cases it will
  result in the same code anyway.  The major advantage of the accesors
  is that they can be used from inside or outside the BX_CPU object, while
  the macros can only be used from inside.
- since almost all eflags were stored in val32 now, I went ahead and
  removed the if_, rf, and vm fields.  Now the val32 bit is the
  "official" value for these flags, and they have accessors just like
  everything else.
- init.cc: move the registration of registers until after they have been
  initialized so that the initial value of each parameter is correct.

Modified files:
  debug/dbg_main.cc cpu/cpu.h cpu/debugstuff.cc cpu/flag_ctrl.cc
  cpu/flag_ctrl_pro.cc cpu/init.cc
This commit is contained in:
Bryce Denney 2002-09-11 03:55:22 +00:00
parent be2cdca3e0
commit 450070850b
5 changed files with 323 additions and 144 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.39 2002-09-10 00:01:01 kevinlawton Exp $
// $Id: cpu.h,v 1.40 2002-09-11 03:55:22 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -240,58 +240,77 @@ typedef struct {
Bit32u val32; // Raw 32-bit value in x86 bit position. Used to store
// some eflags which are not cached in separate fields.
// Some cached fields.
Boolean if_;
#if BX_CPU_LEVEL >= 3
Boolean rf;
Boolean vm;
#endif
// accessors for all eflags (except for lazy flags)
// The macro is used once for each flag bit.
#define IMPLEMENT_EFLAGS_ACCESSORS(name,bitnum) \
BX_CPP_INLINE void assert_##name () { val32 |= (1<<bitnum); } \
BX_CPP_INLINE void clear_##name () { val32 &= ~(1<<bitnum); } \
BX_CPP_INLINE Boolean get_##name () { return 1 & (val32 >> bitnum); } \
BX_CPP_INLINE void set_##name (Bit32u val) { \
val32 = (val32&(1<<bitnum)) | (val ? (1<<bitnum) : 0); \
}
IMPLEMENT_EFLAGS_ACCESSORS(DF, 10);
IMPLEMENT_EFLAGS_ACCESSORS(ID, 21)
IMPLEMENT_EFLAGS_ACCESSORS(VP, 20)
IMPLEMENT_EFLAGS_ACCESSORS(VF, 19)
IMPLEMENT_EFLAGS_ACCESSORS(AC, 18)
IMPLEMENT_EFLAGS_ACCESSORS(VM, 17)
IMPLEMENT_EFLAGS_ACCESSORS(RF, 16)
IMPLEMENT_EFLAGS_ACCESSORS(NT, 14)
IMPLEMENT_EFLAGS_ACCESSORS(IF, 9)
IMPLEMENT_EFLAGS_ACCESSORS(TF, 8)
#undef IMPLEMENT_EFLAGS_ACCESSORS
BX_CPP_INLINE void set_IOPL(Bit8u val) {
const Bit32u mask = (1<<12) | (1<<13);
val32 &= ~mask;
val32 |= ((3&val) << 12);
}
BX_CPP_INLINE Boolean get_IOPL() { return 3 & (val32 >> 12); }
BX_CPP_INLINE Boolean get_bit1() { return 1; }
BX_CPP_INLINE Boolean get_bit3() { return 0; }
BX_CPP_INLINE Boolean get_bit5() { return 0; }
BX_CPP_INLINE Boolean get_bit15() { return 0; }
} bx_flags_reg_t;
// EFlags.DF
#define GetEFlagsDFLogical() (BX_CPU_THIS_PTR eflags.val32 & (1<<10))
#define ClearEFlagsDF() BX_CPU_THIS_PTR eflags.val32 &= ~(1<<10)
#define SetEFlagsDF() BX_CPU_THIS_PTR eflags.val32 |= (1<<10)
#define GetEFlagsDFLogical() (BX_CPU_THIS_PTR eflags.get_DF ())
#define ClearEFlagsDF() (BX_CPU_THIS_PTR eflags.clear_DF ())
#define SetEFlagsDF() (BX_CPU_THIS_PTR eflags.assert_DF ())
// EFlags.TF
#define GetEFlagsTFLogical() (BX_CPU_THIS_PTR eflags.val32 & (1<<8))
#define ClearEFlagsTF() BX_CPU_THIS_PTR eflags.val32 &= ~(1<<8)
#define SetEFlagsTF() BX_CPU_THIS_PTR eflags.val32 |= (1<<8)
#define GetEFlagsTFLogical() (BX_CPU_THIS_PTR eflags.get_TF ())
#define ClearEFlagsTF() (BX_CPU_THIS_PTR eflags.clear_TF ())
#define SetEFlagsTF() (BX_CPU_THIS_PTR eflags.assert_TF ())
// EFlags.IF
#define GetEFlagsIFLogical() (BX_CPU_THIS_PTR eflags.if_)
#define ClearEFlagsIF() BX_CPU_THIS_PTR eflags.if_ = 0, \
BX_CPU_THIS_PTR eflags.val32 &= ~(1<<9)
#define SetEFlagsIF() BX_CPU_THIS_PTR eflags.if_ = 1, \
BX_CPU_THIS_PTR eflags.val32 |= (1<<9)
#define GetEFlagsIFLogical() (BX_CPU_THIS_PTR eflags.get_IF ())
#define ClearEFlagsIF() (BX_CPU_THIS_PTR eflags.clear_IF ())
#define SetEFlagsIF() (BX_CPU_THIS_PTR eflags.assert_IF ())
// EFlags.RF
#define GetEFlagsRFLogical() (BX_CPU_THIS_PTR eflags.rf)
#define ClearEFlagsRF() BX_CPU_THIS_PTR eflags.rf = 0, \
BX_CPU_THIS_PTR eflags.val32 &= ~(1<<16)
#define SetEFlagsRF() BX_CPU_THIS_PTR eflags.rf = 1, \
BX_CPU_THIS_PTR eflags.val32 |= (1<<16)
#define GetEFlagsRFLogical() (BX_CPU_THIS_PTR eflags.get_RF ())
#define ClearEFlagsRF() (BX_CPU_THIS_PTR eflags.clear_RF ())
#define SetEFlagsRF() (BX_CPU_THIS_PTR eflags.assert_RF ())
// EFlags.VM
#define GetEFlagsVMLogical() (BX_CPU_THIS_PTR eflags.vm)
#define ClearEFlagsVM() BX_CPU_THIS_PTR eflags.vm = 0, \
BX_CPU_THIS_PTR eflags.val32 &= ~(1<<17)
#define SetEFlagsVM() BX_CPU_THIS_PTR eflags.vm = 1, \
BX_CPU_THIS_PTR eflags.val32 |= (1<<17)
#define GetEFlagsVMLogical() (BX_CPU_THIS_PTR eflags.get_VM ())
#define ClearEFlagsVM() (BX_CPU_THIS_PTR eflags.clear_VM ())
#define SetEFlagsVM() (BX_CPU_THIS_PTR eflags.assert_VM ())
// EFlags.NT
#define GetEFlagsNTLogical() (BX_CPU_THIS_PTR eflags.val32 & (1<<14))
#define ClearEFlagsNT() BX_CPU_THIS_PTR eflags.val32 &= ~(1<<14)
#define SetEFlagsNT() BX_CPU_THIS_PTR eflags.val32 |= (1<<14)
#define GetEFlagsNTLogical() (BX_CPU_THIS_PTR eflags.get_NT ())
#define ClearEFlagsNT() (BX_CPU_THIS_PTR eflags.clear_NT ())
#define SetEFlagsNT() (BX_CPU_THIS_PTR eflags.assert_NT ())
// AC
#define ClearEFlagsAC() BX_CPU_THIS_PTR eflags.val32 &= ~(1<<18)
#define ClearEFlagsAC() (BX_CPU_THIS_PTR eflags.clear_AC ())
// IOPL
#define IOPL ((BX_CPU_THIS_PTR eflags.val32 >> 12) & 3)
#define ClearEFlagsIOPL() BX_CPU_THIS_PTR eflags.val32 &= ~(3<<12)
#define IOPL (BX_CPU_THIS_PTR eflags.get_IOPL ())
#define ClearEFlagsIOPL() (BX_CPU_THIS_PTR eflags.set_IOPL (0))
#if BX_CPU_LEVEL >= 2
@ -454,7 +473,6 @@ typedef struct {
} bx_segment_reg_t;
typedef void * (*BxVoidFPtr_t)(void);
class BX_CPU_C;
typedef struct BxInstruction_tag {
// prefix stuff here...
@ -1821,12 +1839,12 @@ BX_SMF BX_CPP_INLINE Bit32u BX_CPU_C_PREFIX get_segment_base(unsigned seg) {
# if BX_SUPPORT_V8086_MODE
BX_CPP_INLINE Boolean
BX_CPU_C::v8086_mode(void) {
return(BX_CPU_THIS_PTR eflags.vm);
return (BX_CPU_THIS_PTR eflags.get_VM ());
}
BX_CPP_INLINE Boolean
BX_CPU_C::protected_mode(void) {
return(BX_CPU_THIS_PTR cr0.pe && !BX_CPU_THIS_PTR eflags.vm);
return(BX_CPU_THIS_PTR cr0.pe && !BX_CPU_THIS_PTR eflags.get_VM ());
}
# else
BX_CPP_INLINE Boolean

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: debugstuff.cc,v 1.12 2002-09-08 04:08:14 kevinlawton Exp $
// $Id: debugstuff.cc,v 1.13 2002-09-11 03:55:22 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -41,14 +41,14 @@ BX_CPU_C::debug(Bit32u offset)
(unsigned) ESP, (unsigned) EBP, (unsigned) ESI, (unsigned) EDI));
BX_INFO(("| IOPL=%1u %s %s %s %s %s %s %s %s",
IOPL,
BX_CPU_THIS_PTR get_OF() ? "OV" : "NV",
GetEFlagsDFLogical() ? "DW" : "UP",
BX_CPU_THIS_PTR eflags.if_ ? "EI" : "DI",
BX_CPU_THIS_PTR get_SF() ? "NG" : "PL",
BX_CPU_THIS_PTR get_ZF() ? "ZR" : "NZ",
BX_CPU_THIS_PTR get_AF() ? "AC" : "NA",
BX_CPU_THIS_PTR get_PF() ? "PE" : "PO",
BX_CPU_THIS_PTR get_CF() ? "CY" : "NC"));
BX_CPU_THIS_PTR get_OF() ? "OV" : "NV",
BX_CPU_THIS_PTR eflags.get_DF() ? "DW" : "UP",
BX_CPU_THIS_PTR eflags.get_IF() ? "EI" : "DI",
BX_CPU_THIS_PTR get_SF() ? "NG" : "PL",
BX_CPU_THIS_PTR get_ZF() ? "ZR" : "NZ",
BX_CPU_THIS_PTR get_AF() ? "AC" : "NA",
BX_CPU_THIS_PTR get_PF() ? "PE" : "PO",
BX_CPU_THIS_PTR get_CF() ? "CY" : "NC"));
BX_INFO(("| SEG selector base limit G D"));
BX_INFO(("| SEG sltr(index|ti|rpl) base limit G D"));
BX_INFO(("| DS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u",
@ -210,9 +210,9 @@ BX_CPU_C::dbg_set_reg(unsigned reg, Bit32u val)
return(0);
}
// make sure none of the system bits are being changed
current_sys_bits = (BX_CPU_THIS_PTR eflags.nt << 14) |
(BX_CPU_THIS_PTR eflags.iopl << 12) |
(BX_CPU_THIS_PTR eflags.tf << 8);
current_sys_bits = (BX_CPU_THIS_PTR eflags.get_NT () << 14) |
(BX_CPU_THIS_PTR eflags.get_IOPL () << 12) |
(BX_CPU_THIS_PTR eflags.get_TF () << 8);
if ( current_sys_bits != (val & 0x0000f100) ) {
BX_INFO(("dbg_set_reg: can not modify NT, IOPL, or TF."));
return(0);
@ -222,10 +222,10 @@ BX_CPU_C::dbg_set_reg(unsigned reg, Bit32u val)
BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 2;
BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
BX_CPU_THIS_PTR eflags.df = val & 0x01; val >>= 1;
BX_CPU_THIS_PTR eflags.set_IF (val & 0x01); val >>= 1;
BX_CPU_THIS_PTR eflags.set_DF (val & 0x01); val >>= 1;
BX_CPU_THIS_PTR set_OF(val & 0x01);
if (BX_CPU_THIS_PTR eflags.if_)
if (BX_CPU_THIS_PTR eflags.get_IF ())
BX_CPU_THIS_PTR async_event = 1;
return(1);
case BX_DBG_REG_CS:
@ -287,7 +287,7 @@ BX_CPU_C::dbg_query_pending(void)
ret |= BX_DBG_PENDING_DMA;
}
if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ ) {
if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.get_IF () ) {
ret |= BX_DBG_PENDING_IRQ;
}
@ -303,27 +303,27 @@ BX_CPU_C::dbg_get_eflags(void)
val32 =
(BX_CPU_THIS_PTR get_CF()) |
(BX_CPU_THIS_PTR eflags.bit1 << 1) |
(BX_CPU_THIS_PTR eflags.get_bit1 () << 1) |
((BX_CPU_THIS_PTR get_PF()) << 2) |
(BX_CPU_THIS_PTR eflags.bit3 << 3) |
(BX_CPU_THIS_PTR eflags.get_bit3 () << 3) |
((BX_CPU_THIS_PTR get_AF()>0) << 4) |
(BX_CPU_THIS_PTR eflags.bit5 << 5) |
(BX_CPU_THIS_PTR eflags.get_bit5 () << 5) |
((BX_CPU_THIS_PTR get_ZF()>0) << 6) |
((BX_CPU_THIS_PTR get_SF()>0) << 7) |
(BX_CPU_THIS_PTR eflags.tf << 8) |
(BX_CPU_THIS_PTR eflags.if_ << 9) |
(BX_CPU_THIS_PTR eflags.df << 10) |
(BX_CPU_THIS_PTR eflags.get_TF () << 8) |
(BX_CPU_THIS_PTR eflags.get_IF () << 9) |
(BX_CPU_THIS_PTR eflags.get_DF () << 10) |
((BX_CPU_THIS_PTR get_OF()>0) << 11) |
(BX_CPU_THIS_PTR eflags.iopl << 12) |
(BX_CPU_THIS_PTR eflags.nt << 14) |
(BX_CPU_THIS_PTR eflags.bit15 << 15) |
(BX_CPU_THIS_PTR eflags.rf << 16) |
(BX_CPU_THIS_PTR eflags.vm << 17);
(BX_CPU_THIS_PTR eflags.get_IOPL () << 12) |
(BX_CPU_THIS_PTR eflags.get_NT () << 14) |
(BX_CPU_THIS_PTR eflags.get_bit15 () << 15) |
(BX_CPU_THIS_PTR eflags.get_RF () << 16) |
(BX_CPU_THIS_PTR eflags.get_VM () << 17);
#if BX_CPU_LEVEL >= 4
val32 |= (BX_CPU_THIS_PTR eflags.ac << 18);
//val32 |= (BX_CPU_THIS_PTR eflags.vif << 19);
//val32 |= (BX_CPU_THIS_PTR eflags.vip << 20);
val32 |= (BX_CPU_THIS_PTR eflags.id << 21);
val32 |= (BX_CPU_THIS_PTR eflags.get_AC () << 18);
//val32 |= (BX_CPU_THIS_PTR eflags.get_VIF () << 19);
//val32 |= (BX_CPU_THIS_PTR eflags.get_VIP () << 20);
val32 |= (BX_CPU_THIS_PTR eflags.get_ID () << 21);
#endif
return(val32);
}
@ -641,21 +641,21 @@ BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 1;
BX_CPU_THIS_PTR eflags.tf = val & 0x01; val >>= 1;
BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
BX_CPU_THIS_PTR eflags.df = val & 0x01; val >>= 1;
BX_CPU_THIS_PTR eflags.set_TF (val & 0x01); val >>= 1;
BX_CPU_THIS_PTR eflags.set_IF (val & 0x01); val >>= 1;
BX_CPU_THIS_PTR eflags.set_DF (val & 0x01); val >>= 1;
BX_CPU_THIS_PTR set_OF(val & 0x01); val >>= 1;
BX_CPU_THIS_PTR eflags.iopl = val & 0x03; val >>= 2;
BX_CPU_THIS_PTR eflags.nt = val & 0x01; val >>= 2;
BX_CPU_THIS_PTR eflags.rf = val & 0x01; val >>= 1;
BX_CPU_THIS_PTR eflags.vm = val & 0x01; val >>= 1;
BX_CPU_THIS_PTR eflags.set_IOPL (val & 0x03); val >>= 2;
BX_CPU_THIS_PTR eflags.set_NT (val & 0x01); val >>= 2;
BX_CPU_THIS_PTR eflags.set_RF (val & 0x01); val >>= 1;
BX_CPU_THIS_PTR eflags.set_VM (val & 0x01); val >>= 1;
#if BX_CPU_LEVEL >= 4
BX_CPU_THIS_PTR eflags.ac = val & 0x01; val >>= 1;
//BX_CPU_THIS_PTR eflags.vif = val & 0x01;
BX_CPU_THIS_PTR eflags.set_AC (val & 0x01); val >>= 1;
//BX_CPU_THIS_PTR eflags.set_VIF (val & 0x01);
val >>= 1;
//BX_CPU_THIS_PTR eflags.vip = val & 0x01;
//BX_CPU_THIS_PTR eflags.set_VIP (val & 0x01);
val >>= 1;
BX_CPU_THIS_PTR eflags.id = val & 0x01;
BX_CPU_THIS_PTR eflags.set_ID (val & 0x01);
#endif
BX_CPU_THIS_PTR eip = cpu->eip;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: flag_ctrl_pro.cc,v 1.7 2002-09-08 04:08:14 kevinlawton Exp $
// $Id: flag_ctrl_pro.cc,v 1.8 2002-09-11 03:55:22 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -55,7 +55,7 @@ BX_CPU_C::write_flags(Bit16u flags, Boolean change_IOPL, Boolean change_IF)
#endif
if (change_IF) {
changeMask |= (1<<9);
BX_CPU_THIS_PTR eflags.if_ = (flags >> 9) & 0x01;
BX_CPU_THIS_PTR eflags.set_IF ((flags >> 9) & 0x01);
}
@ -92,22 +92,17 @@ BX_CPU_C::write_eflags(Bit32u eflags_raw, Boolean change_IOPL, Boolean change_IF
#endif
if (change_IOPL)
changeMask |= (3<<12);
if (change_IF) {
if (change_IF)
changeMask |= (1<<9);
BX_CPU_THIS_PTR eflags.if_ = (eflags_raw >> 9) & 0x01;
}
if (change_VM) {
BX_CPU_THIS_PTR eflags.vm = (eflags_raw >> 17) & 0x01;
changeMask |= (1<<17);
#if BX_SUPPORT_V8086_MODE == 0
if ( eflags_raw & (1<<17) )
BX_PANIC(("write_eflags: VM bit set: BX_SUPPORT_V8086_MODE==0"));
#endif
}
if (change_RF) {
BX_CPU_THIS_PTR eflags.rf = (eflags_raw >> 16) & 0x01;
if (change_RF)
changeMask |= (1<<16);
}
BX_CPU_THIS_PTR eflags.val32 =
(BX_CPU_THIS_PTR eflags.val32 & ~changeMask) | (eflags_raw & changeMask);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.20 2002-09-08 04:08:14 kevinlawton Exp $
// $Id: init.cc,v 1.21 2002-09-11 03:55:22 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -49,32 +49,114 @@ BX_CPU_C::BX_CPU_C()
}
#if BX_WITH_WX
#define CASE_SEG_REG_GET(x) \
case BXP_CPU_SEG_##x: \
return BX_CPU_THIS_PTR sregs[BX_SEG_REG_##x].selector.value;
#define CASE_SEG_REG_SET(reg, val) \
case BXP_CPU_SEG_##reg: \
BX_CPU_THIS_PTR load_seg_reg (&BX_CPU_THIS_PTR sregs[BX_SEG_REG_##reg],val); \
break;
#define CASE_LAZY_EFLAG_GET(flag) \
case BXP_CPU_EFLAGS_##flag: \
return BX_CPU_THIS_PTR get_##flag ();
#define CASE_LAZY_EFLAG_SET(flag, val) \
case BXP_CPU_EFLAGS_##flag: \
BX_CPU_THIS_PTR set_##flag(val); \
break;
#define CASE_EFLAG_GET(flag) \
case BXP_CPU_EFLAGS_##flag: \
return BX_CPU_THIS_PTR eflags.get_##flag ();
#define CASE_EFLAG_SET(flag, val) \
case BXP_CPU_EFLAGS_##flag: \
BX_CPU_THIS_PTR eflags.set_##flag(val); \
break;
// implement get/set handler for parameters that need unusual set/get
static Bit32s
cpu_param_handler (bx_param_c *param, int set, Bit32s val)
{
bx_id id = param->get_id ();
if (!set) {
if (set) {
switch (id) {
case BXP_CPU_CS:
return BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
default: break;
CASE_SEG_REG_SET (CS, val);
CASE_SEG_REG_SET (DS, val);
CASE_SEG_REG_SET (SS, val);
CASE_SEG_REG_SET (ES, val);
CASE_SEG_REG_SET (FS, val);
CASE_SEG_REG_SET (GS, val);
case BXP_CPU_SEG_LDTR:
BX_PANIC(("setting LDTR not implemented"));
break;
case BXP_CPU_SEG_TR:
BX_PANIC(("setting TR not implemented"));
break;
CASE_LAZY_EFLAG_SET (OF, val);
CASE_LAZY_EFLAG_SET (SF, val);
CASE_LAZY_EFLAG_SET (ZF, val);
CASE_LAZY_EFLAG_SET (AF, val);
CASE_LAZY_EFLAG_SET (PF, val);
CASE_LAZY_EFLAG_SET (CF, val);
CASE_EFLAG_SET (ID, val);
//CASE_EFLAG_SET (VIP, val);
//CASE_EFLAG_SET (VIF, val);
CASE_EFLAG_SET (AC, val);
CASE_EFLAG_SET (VM, val);
CASE_EFLAG_SET (RF, val);
CASE_EFLAG_SET (NT, val);
CASE_EFLAG_SET (IOPL, val);
CASE_EFLAG_SET (DF, val);
CASE_EFLAG_SET (IF, val);
CASE_EFLAG_SET (TF, val);
default:
BX_PANIC (("cpu_param_handler set id %d not handled", id));
}
} else {
switch (id) {
case BXP_CPU_CS:
BX_CPU_THIS_PTR load_seg_reg (&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], val);
break;
default: break;
CASE_SEG_REG_GET (CS);
CASE_SEG_REG_GET (DS);
CASE_SEG_REG_GET (SS);
CASE_SEG_REG_GET (ES);
CASE_SEG_REG_GET (FS);
CASE_SEG_REG_GET (GS);
case BXP_CPU_SEG_LDTR:
return BX_CPU_THIS_PTR ldtr.selector.value;
break;
case BXP_CPU_SEG_TR:
return BX_CPU_THIS_PTR tr.selector.value;
break;
CASE_LAZY_EFLAG_GET (OF);
CASE_LAZY_EFLAG_GET (SF);
CASE_LAZY_EFLAG_GET (ZF);
CASE_LAZY_EFLAG_GET (AF);
CASE_LAZY_EFLAG_GET (PF);
CASE_LAZY_EFLAG_GET (CF);
CASE_EFLAG_GET (ID);
//CASE_EFLAG_GET (VIP);
//CASE_EFLAG_GET (VIF);
CASE_EFLAG_GET (AC);
CASE_EFLAG_GET (VM);
CASE_EFLAG_GET (RF);
CASE_EFLAG_GET (NT);
CASE_EFLAG_GET (IOPL);
CASE_EFLAG_GET (DF);
CASE_EFLAG_GET (IF);
CASE_EFLAG_GET (TF);
default:
BX_PANIC (("cpu_param_handler get id %d ('%s') not handled", id, param->get_name ()));
}
}
return val;
}
#undef CASE_SEG_REG_GET
#undef CASE_SEG_REG_SET
#endif
void BX_CPU_C::init(BX_MEM_C *addrspace)
{
BX_DEBUG(( "Init $Id: init.cc,v 1.20 2002-09-08 04:08:14 kevinlawton Exp $"));
BX_DEBUG(( "Init $Id: init.cc,v 1.21 2002-09-11 03:55:22 bdenney Exp $"));
// BX_CPU_C constructor
BX_CPU_THIS_PTR set_INTR (0);
#if BX_SUPPORT_APIC
@ -83,30 +165,6 @@ void BX_CPU_C::init(BX_MEM_C *addrspace)
// in SMP mode, the prefix of the CPU will be changed to [CPUn] in
// bx_local_apic_c::set_id as soon as the apic ID is assigned.
#if BX_WITH_WX
// Register some of the CPUs variables as shadow parameters so that
// they can be visible in the config interface.
// (Experimental, obviously not a complete list)
const char *fmt16 = "%04X";
const char *fmt32 = "%08X";
Bit32u oldbase = bx_param_num_c::set_default_base (16);
const char *oldfmt = bx_param_num_c::set_default_format (fmt32);
bx_list_c *list = new bx_list_c (BXP_CPU_PARAMETERS, "CPU State", "", 8);
list->add (new bx_shadow_num_c (BXP_CPU_EAX, "EAX", &EAX));
list->add (new bx_shadow_num_c (BXP_CPU_EBX, "EBX", &EBX));
list->add (new bx_shadow_num_c (BXP_CPU_ECX, "ECX", &ECX));
list->add (new bx_shadow_num_c (BXP_CPU_EDX, "EDX", &EDX));
list->add (new bx_shadow_num_c (BXP_CPU_EIP, "EIP", &EIP));
// CS has a special get/set technique, so it needs a handler function
bx_param_num_c *param;
list->add (param = new bx_param_num_c (BXP_CPU_CS, "CS", "", 0, 0xffff, 0));
param->set_handler (cpu_param_handler);
param->set_format (fmt16);
// restore defaults
bx_param_num_c::set_default_base (oldbase);
bx_param_num_c::set_default_format (oldfmt);
#endif
/* hack for the following fields. Its easier to decode mod-rm bytes if
you can assume there's always a base & index register used. For
modes which don't really use them, point to an empty (zeroed) register.
@ -238,6 +296,115 @@ void BX_CPU_C::init(BX_MEM_C *addrspace)
sprintf (name, "CPU %p", this);
BX_INSTR_INIT();
#if BX_WITH_WX
// Register some of the CPUs variables as shadow parameters so that
// they can be visible in the config interface.
// (Experimental, obviously not a complete list)
bx_param_num_c *param;
const char *fmt16 = "%04X";
const char *fmt32 = "%08X";
Bit32u oldbase = bx_param_num_c::set_default_base (16);
const char *oldfmt = bx_param_num_c::set_default_format (fmt32);
bx_list_c *list = new bx_list_c (BXP_CPU_PARAMETERS, "CPU State", "", 60);
#define DEFPARAM_NORMAL(name,field) \
list->add (new bx_shadow_num_c (BXP_CPU_##name, #name, &(field)))
DEFPARAM_NORMAL (EAX, EAX);
DEFPARAM_NORMAL (EBX, EBX);
DEFPARAM_NORMAL (ECX, ECX);
DEFPARAM_NORMAL (EDX, EDX);
DEFPARAM_NORMAL (ESP, ESP);
DEFPARAM_NORMAL (EBP, EBP);
DEFPARAM_NORMAL (ESI, ESI);
DEFPARAM_NORMAL (EDI, EDI);
DEFPARAM_NORMAL (EIP, EIP);
DEFPARAM_NORMAL (DR0, dr0);
DEFPARAM_NORMAL (DR1, dr1);
DEFPARAM_NORMAL (DR2, dr2);
DEFPARAM_NORMAL (DR3, dr3);
DEFPARAM_NORMAL (DR6, dr6);
DEFPARAM_NORMAL (DR7, dr7);
// segment registers require a handler function because they have
// special get/set requirements.
#define DEFPARAM_SEG_REG(x) \
list->add (param = new bx_param_num_c (BXP_CPU_SEG_##x, \
#x, "", 0, 0xffff, 0)); \
param->set_handler (cpu_param_handler); \
param->set_format (fmt16);
#define DEFPARAM_GLOBAL_SEG_REG(name,field) \
list->add (param = new bx_shadow_num_c (BXP_CPU_##name##_BASE, \
#name" base", \
& BX_CPU_THIS_PTR field.base)); \
list->add (param = new bx_shadow_num_c (BXP_CPU_##name##_LIMIT, \
#name" limit", \
& BX_CPU_THIS_PTR field.limit));
DEFPARAM_SEG_REG(CS);
DEFPARAM_SEG_REG(DS);
DEFPARAM_SEG_REG(SS);
DEFPARAM_SEG_REG(ES);
DEFPARAM_SEG_REG(FS);
DEFPARAM_SEG_REG(GS);
DEFPARAM_SEG_REG(LDTR);
DEFPARAM_SEG_REG(TR);
DEFPARAM_GLOBAL_SEG_REG(GDTR, gdtr);
DEFPARAM_GLOBAL_SEG_REG(IDTR, idtr);
#undef DEFPARAM_SEGREG
// flags implemented in lazy_flags.cc must be done with a handler
// that calls their get function, to force them to be computed.
#define DEFPARAM_EFLAG(name) \
list->add ( \
param = new bx_param_bool_c ( \
BXP_CPU_EFLAGS_##name, \
#name, "", eflags.get_##name())); \
param->set_handler (cpu_param_handler);
#define DEFPARAM_LAZY_EFLAG(name) \
list->add ( \
param = new bx_param_bool_c ( \
BXP_CPU_EFLAGS_##name, \
#name, "", get_##name())); \
param->set_handler (cpu_param_handler);
#if BX_CPU_LEVEL >= 4
DEFPARAM_EFLAG(ID);
//DEFPARAM_EFLAG(VIP);
//DEFPARAM_EFLAG(VIF);
DEFPARAM_EFLAG(AC);
#endif
#if BX_CPU_LEVEL >= 3
DEFPARAM_EFLAG(VM);
DEFPARAM_EFLAG(RF);
#endif
#if BX_CPU_LEVEL >= 2
DEFPARAM_EFLAG(NT);
// IOPL is a special case because it is 2 bits wide.
list->add (
param = new bx_shadow_num_c (
BXP_CPU_EFLAGS_IOPL,
"IOPL", "", 0, 3,
&eflags.val32,
12, 13));
#endif
DEFPARAM_LAZY_EFLAG(OF);
DEFPARAM_EFLAG(DF);
DEFPARAM_EFLAG(IF);
DEFPARAM_EFLAG(TF);
DEFPARAM_LAZY_EFLAG(SF);
DEFPARAM_LAZY_EFLAG(ZF);
DEFPARAM_LAZY_EFLAG(AF);
DEFPARAM_LAZY_EFLAG(PF);
DEFPARAM_LAZY_EFLAG(CF);
// restore defaults
bx_param_num_c::set_default_base (oldbase);
bx_param_num_c::set_default_format (oldfmt);
#endif
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.56 2002-09-06 19:21:55 yakovlev Exp $
// $Id: dbg_main.cc,v 1.57 2002-09-11 03:55:22 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -976,7 +976,7 @@ bx_dbg_playback_command(char* path_quoted)
void
bx_dbg_modebp_command(char* dummy)
{
BX_CPU(dbg_cpu)->debug_vm == BX_CPU(dbg_cpu)->eflags.vm;
BX_CPU(dbg_cpu)->debug_vm == BX_CPU(dbg_cpu)->eflags.get_VM ();
BX_CPU(dbg_cpu)->mode_break = !BX_CPU(dbg_cpu)->mode_break;
fprintf(stderr," mode switch break %s\n",
BX_CPU(dbg_cpu)->mode_break ? "enabled" : "disabled");
@ -1180,7 +1180,7 @@ void bx_dbg_show_command(char* arg)
BX_CPU(dbg_cpu)->show_flag = 0;
last_cr3 = BX_CPU(dbg_cpu)->cr3;
last_pe = BX_CPU(dbg_cpu)->cr0.pe;
last_vm = BX_CPU(dbg_cpu)->eflags.vm;
last_vm = BX_CPU(dbg_cpu)->eflags.get_VM ();
fprintf(stderr,"%10lld: address %04x:%08x %08x\n\n",
bx_pc_system.time_ticks(),
@ -2106,28 +2106,27 @@ void bx_dbg_disassemble_current (int which_cpu, int print_time)
if( BX_CPU(dbg_cpu)->trace_reg )
fprintf( stderr,
"eax: %08X\tecx: %08X\tedx: %08X\tebx: %08X\tesp: %08X\tebp: %08X\tesi: %08X\tedi: %08X\ncf=%u af=%u zf=%u sf=%u of=%u pf=%u tf=%u if=%u df=%u iopl=%u nt=%u rf=%u vm=%u\n",
BX_CPU(which_cpu)->gen_reg[0],
BX_CPU(which_cpu)->gen_reg[1],
BX_CPU(which_cpu)->gen_reg[2],
BX_CPU(which_cpu)->gen_reg[3],
BX_CPU(which_cpu)->gen_reg[4],
BX_CPU(which_cpu)->gen_reg[5],
BX_CPU(which_cpu)->gen_reg[6],
BX_CPU(which_cpu)->gen_reg[7],
BX_CPU(which_cpu)->gen_reg[0].erx,
BX_CPU(which_cpu)->gen_reg[1].erx,
BX_CPU(which_cpu)->gen_reg[2].erx,
BX_CPU(which_cpu)->gen_reg[3].erx,
BX_CPU(which_cpu)->gen_reg[4].erx,
BX_CPU(which_cpu)->gen_reg[5].erx,
BX_CPU(which_cpu)->gen_reg[6].erx,
BX_CPU(which_cpu)->gen_reg[7].erx,
!!BX_CPU(which_cpu)->get_CF(),
!!BX_CPU(which_cpu)->get_AF(),
!!BX_CPU(which_cpu)->get_ZF(),
!!BX_CPU(which_cpu)->get_SF(),
!!BX_CPU(which_cpu)->get_OF(),
!!BX_CPU(which_cpu)->get_PF(),
BX_CPU(which_cpu)->eflags.tf,
BX_CPU(which_cpu)->eflags.if_,
BX_CPU(which_cpu)->eflags.df,
BX_CPU(which_cpu)->eflags.iopl,
BX_CPU(which_cpu)->eflags.nt,
BX_CPU(which_cpu)->eflags.rf,
BX_CPU(which_cpu)->eflags.vm
);
BX_CPU(which_cpu)->eflags.get_TF (),
BX_CPU(which_cpu)->eflags.get_IF (),
BX_CPU(which_cpu)->eflags.get_DF (),
BX_CPU(which_cpu)->eflags.get_IOPL (),
BX_CPU(which_cpu)->eflags.get_NT (),
BX_CPU(which_cpu)->eflags.get_RF (),
BX_CPU(which_cpu)->eflags.get_VM ());
if (print_time)
fprintf (stderr, "(%u).[%lld] ", which_cpu, bx_pc_system.time_ticks());
@ -2206,7 +2205,7 @@ for (sim=0; sim<BX_SMP_PROCESSORS; sim++) {
fprintf(stderr, "(%u) Caught time breakpoint\n", sim);
} else if (BX_CPU(sim)->stop_reason == STOP_MODE_BREAK_POINT) {
fprintf(stderr, "(%u) Caught vm mode switch breakpoint to %s mode\n",
sim, BX_CPU(sim)->eflags.vm ? "virtual 86" : "protected");
sim, BX_CPU(sim)->eflags.get_VM () ? "virtual 86" : "protected");
} else if (BX_CPU(sim)->stop_reason == STOP_READ_WATCH_POINT) {
fprintf(stderr, "(%u) Caught read watch point at %08X\n", sim, BX_CPU(sim)->watchpoint);
} else if (BX_CPU(sim)->stop_reason == STOP_WRITE_WATCH_POINT) {
@ -4437,7 +4436,7 @@ bx_dbg_symbolic_output(void)
last_pe = !last_pe;
}
if(last_vm != BX_CPU(dbg_cpu)->eflags.vm) {
if(last_vm != BX_CPU(dbg_cpu)->eflags.get_VM ()) {
fprintf(stderr,"%10lld: %s V86 mode\n",
bx_pc_system.time_ticks(),
last_vm ? "Exited" : "Entered");