@ -255,142 +255,6 @@ void handle_vm86_trap(CPUX86State *env, int trapno)
}
}
# define CHECK_IF_IN_TRAP() \
if ( ( ts - > vm86plus . vm86plus . flags & TARGET_vm86dbg_active ) & & \
( ts - > vm86plus . vm86plus . flags & TARGET_vm86dbg_TFpendig ) ) \
newflags | = TF_MASK
# define VM86_FAULT_RETURN \
if ( ( ts - > vm86plus . vm86plus . flags & TARGET_force_return_for_pic ) & & \
( ts - > v86flags & ( IF_MASK | VIF_MASK ) ) ) \
return_to_32bit ( env , TARGET_VM86_PICRETURN ) ; \
return
void handle_vm86_fault ( CPUX86State * env )
{
CPUState * cs = env_cpu ( env ) ;
TaskState * ts = get_task_state ( cs ) ;
uint32_t csp , ssp ;
unsigned int ip , sp , newflags , newip , newcs , opcode , intno ;
int data32 , pref_done ;
csp = env - > segs [ R_CS ] . selector < < 4 ;
ip = env - > eip & 0xffff ;
ssp = env - > segs [ R_SS ] . selector < < 4 ;
sp = env - > regs [ R_ESP ] & 0xffff ;
LOG_VM86 ( " VM86 exception %04x:%08x \n " ,
env - > segs [ R_CS ] . selector , env - > eip ) ;
data32 = 0 ;
pref_done = 0 ;
do {
opcode = vm_getb ( env , csp , ip ) ;
ADD16 ( ip , 1 ) ;
switch ( opcode ) {
case 0x66 : /* 32-bit data */ data32 = 1 ; break ;
case 0x67 : /* 32-bit address */ break ;
case 0x2e : /* CS */ break ;
case 0x3e : /* DS */ break ;
case 0x26 : /* ES */ break ;
case 0x36 : /* SS */ break ;
case 0x65 : /* GS */ break ;
case 0x64 : /* FS */ break ;
case 0xf2 : /* repnz */ break ;
case 0xf3 : /* rep */ break ;
default : pref_done = 1 ;
}
} while ( ! pref_done ) ;
/* VM86 mode */
switch ( opcode ) {
case 0x9c : /* pushf */
if ( data32 ) {
vm_putl ( env , ssp , sp - 4 , get_vflags ( env ) ) ;
ADD16 ( env - > regs [ R_ESP ] , - 4 ) ;
} else {
vm_putw ( env , ssp , sp - 2 , get_vflags ( env ) ) ;
ADD16 ( env - > regs [ R_ESP ] , - 2 ) ;
}
env - > eip = ip ;
VM86_FAULT_RETURN ;
case 0x9d : /* popf */
if ( data32 ) {
newflags = vm_getl ( env , ssp , sp ) ;
ADD16 ( env - > regs [ R_ESP ] , 4 ) ;
} else {
newflags = vm_getw ( env , ssp , sp ) ;
ADD16 ( env - > regs [ R_ESP ] , 2 ) ;
}
env - > eip = ip ;
CHECK_IF_IN_TRAP ( ) ;
if ( data32 ) {
if ( set_vflags_long ( newflags , env ) )
return ;
} else {
if ( set_vflags_short ( newflags , env ) )
return ;
}
VM86_FAULT_RETURN ;
case 0xcd : /* int */
intno = vm_getb ( env , csp , ip ) ;
ADD16 ( ip , 1 ) ;
env - > eip = ip ;
if ( ts - > vm86plus . vm86plus . flags & TARGET_vm86dbg_active ) {
if ( ( ts - > vm86plus . vm86plus . vm86dbg_intxxtab [ intno > > 3 ] > >
( intno & 7 ) ) & 1 ) {
return_to_32bit ( env , TARGET_VM86_INTx + ( intno < < 8 ) ) ;
return ;
}
}
do_int ( env , intno ) ;
break ;
case 0xcf : /* iret */
if ( data32 ) {
newip = vm_getl ( env , ssp , sp ) & 0xffff ;
newcs = vm_getl ( env , ssp , sp + 4 ) & 0xffff ;
newflags = vm_getl ( env , ssp , sp + 8 ) ;
ADD16 ( env - > regs [ R_ESP ] , 12 ) ;
} else {
newip = vm_getw ( env , ssp , sp ) ;
newcs = vm_getw ( env , ssp , sp + 2 ) ;
newflags = vm_getw ( env , ssp , sp + 4 ) ;
ADD16 ( env - > regs [ R_ESP ] , 6 ) ;
}
env - > eip = newip ;
cpu_x86_load_seg ( env , R_CS , newcs ) ;
CHECK_IF_IN_TRAP ( ) ;
if ( data32 ) {
if ( set_vflags_long ( newflags , env ) )
return ;
} else {
if ( set_vflags_short ( newflags , env ) )
return ;
}
VM86_FAULT_RETURN ;
case 0xfa : /* cli */
env - > eip = ip ;
clear_IF ( env ) ;
VM86_FAULT_RETURN ;
case 0xfb : /* sti */
env - > eip = ip ;
if ( set_IF ( env ) )
return ;
VM86_FAULT_RETURN ;
default :
/* real VM86 GPF exception */
return_to_32bit ( env , TARGET_VM86_UNKNOWN ) ;
break ;
}
}
int do_vm86 ( CPUX86State * env , long subfunction , abi_ulong vm86_addr )
{
CPUState * cs = env_cpu ( env ) ;