void handle_vm86_fault(CPUX86State *env)

{

    TaskState *ts = env->opaque;

    uint8_t *csp, *pc, *ssp;

    unsigned int ip, sp, newflags, newip, newcs, opcode, intno;

    int data32, pref_done;



    csp = (uint8_t *)(env->segs[R_CS] << 4);

    ip = env->eip & 0xffff;

    pc = csp + ip;

    

    ssp = (uint8_t *)(env->segs[R_SS] << 4);

    sp = env->regs[R_ESP] & 0xffff;



#if defined(DEBUG_VM86)

    fprintf(logfile, "VM86 exception %04x:%08x %02x %02x\n",

            env->segs[R_CS], env->eip, pc[0], pc[1]);

#endif



    data32 = 0;

    pref_done = 0;

    do {

        opcode = 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 */

        ADD16(env->eip, 2);

        if (data32) {

            vm_putl(ssp, sp - 4, get_vflags(env));

            ADD16(env->regs[R_ESP], -4);

        } else {

            vm_putw(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(ssp, sp);

            ADD16(env->regs[R_ESP], 4);

        } else {

            newflags = vm_getw(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 = 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(ssp, sp) & 0xffff;

            newcs = vm_getl(ssp, sp + 4) & 0xffff;

            newflags = vm_getl(ssp, sp + 8);

            ADD16(env->regs[R_ESP], 12);

        } else {

            newip = vm_getw(ssp, sp);

            newcs = vm_getw(ssp, sp + 2);

            newflags = vm_getw(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;

    }

}

void handle_vm86_fault(CPUX86State *env)

{

    TaskState *ts = env->opaque;

    uint8_t *csp, *pc, *ssp;

    unsigned int ip, sp, newflags, newip, newcs, opcode, intno;

    int data32, pref_done;



    csp = (uint8_t *)(env->segs[R_CS] << 4);

    ip = env->eip & 0xffff;

    pc = csp + ip;

    

    ssp = (uint8_t *)(env->segs[R_SS] << 4);

    sp = env->regs[R_ESP] & 0xffff;



#if defined(DEBUG_VM86)

    fprintf(logfile, "VM86 exception %04x:%08x %02x %02x\n",

            env->segs[R_CS], env->eip, pc[0], pc[1]);

#endif



    data32 = 0;

    pref_done = 0;

    do {

        opcode = csp[ip];

        ADD16(ip, 1);

        switch (opcode) {

        case 0x66:           data32=1; break;

        case 0x67:        break;

        case 0x2e:                    break;

        case 0x3e:                    break;

        case 0x26:                    break;

        case 0x36:                    break;

        case 0x65:                    break;

        case 0x64:                    break;

        case 0xf2:      	      break;

        case 0xf3:                   break;

        default: pref_done = 1;

        }

    } while (!pref_done);



    

    switch(opcode) {

    case 0x9c: 

        ADD16(env->eip, 2);

        if (data32) {

            vm_putl(ssp, sp - 4, get_vflags(env));

            ADD16(env->regs[R_ESP], -4);

        } else {

            vm_putw(ssp, sp - 2, get_vflags(env));

            ADD16(env->regs[R_ESP], -2);

        }

        env->eip = ip;

        VM86_FAULT_RETURN;



    case 0x9d: 

        if (data32) {

            newflags = vm_getl(ssp, sp);

            ADD16(env->regs[R_ESP], 4);

        } else {

            newflags = vm_getw(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: 

        intno = 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: 

        if (data32) {

            newip = vm_getl(ssp, sp) & 0xffff;

            newcs = vm_getl(ssp, sp + 4) & 0xffff;

            newflags = vm_getl(ssp, sp + 8);

            ADD16(env->regs[R_ESP], 12);

        } else {

            newip = vm_getw(ssp, sp);

            newcs = vm_getw(ssp, sp + 2);

            newflags = vm_getw(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: 

        env->eip = ip;

        clear_IF(env);

        VM86_FAULT_RETURN;

        

    case 0xfb: 

        env->eip = ip;

        if (set_IF(env))

            return;

        VM86_FAULT_RETURN;



    default:

        

        return_to_32bit(env, TARGET_VM86_UNKNOWN);

        break;

    }

}

void FUNC_0(CPUX86State *VAR_0)

{

    TaskState *ts = VAR_0->opaque;

    uint8_t *csp, *pc, *ssp;

    unsigned int VAR_1, VAR_2, VAR_3, VAR_4, VAR_5, VAR_6, VAR_7;

    int VAR_8, VAR_9;



    csp = (uint8_t *)(VAR_0->segs[R_CS] << 4);

    VAR_1 = VAR_0->eip & 0xffff;

    pc = csp + VAR_1;

    

    ssp = (uint8_t *)(VAR_0->segs[R_SS] << 4);

    VAR_2 = VAR_0->regs[R_ESP] & 0xffff;



#if defined(DEBUG_VM86)

    fprintf(logfile, "VM86 exception %04x:%08x %02x %02x\n",

            VAR_0->segs[R_CS], VAR_0->eip, pc[0], pc[1]);

#endif



    VAR_8 = 0;

    VAR_9 = 0;

    do {

        VAR_6 = csp[VAR_1];

        ADD16(VAR_1, 1);

        switch (VAR_6) {

        case 0x66:           VAR_8=1; break;

        case 0x67:        break;

        case 0x2e:                    break;

        case 0x3e:                    break;

        case 0x26:                    break;

        case 0x36:                    break;

        case 0x65:                    break;

        case 0x64:                    break;

        case 0xf2:      	      break;

        case 0xf3:                   break;

        default: VAR_9 = 1;

        }

    } while (!VAR_9);



    

    switch(VAR_6) {

    case 0x9c: 

        ADD16(VAR_0->eip, 2);

        if (VAR_8) {

            vm_putl(ssp, VAR_2 - 4, get_vflags(VAR_0));

            ADD16(VAR_0->regs[R_ESP], -4);

        } else {

            vm_putw(ssp, VAR_2 - 2, get_vflags(VAR_0));

            ADD16(VAR_0->regs[R_ESP], -2);

        }

        VAR_0->eip = VAR_1;

        VM86_FAULT_RETURN;



    case 0x9d: 

        if (VAR_8) {

            VAR_3 = vm_getl(ssp, VAR_2);

            ADD16(VAR_0->regs[R_ESP], 4);

        } else {

            VAR_3 = vm_getw(ssp, VAR_2);

            ADD16(VAR_0->regs[R_ESP], 2);

        }

        VAR_0->eip = VAR_1;

        CHECK_IF_IN_TRAP();

        if (VAR_8) {

            if (set_vflags_long(VAR_3, VAR_0))

                return;

        } else {

            if (set_vflags_short(VAR_3, VAR_0))

                return;

        }

        VM86_FAULT_RETURN;



    case 0xcd: 

        VAR_7 = csp[VAR_1];

        ADD16(VAR_1, 1);

        VAR_0->eip = VAR_1;

        if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) {

            if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[VAR_7 >> 3] >> 

                  (VAR_7 &7)) & 1) {

                return_to_32bit(VAR_0, TARGET_VM86_INTx + (VAR_7 << 8));

                return;

            }

        }

        do_int(VAR_0, VAR_7);

        break;



    case 0xcf: 

        if (VAR_8) {

            VAR_4 = vm_getl(ssp, VAR_2) & 0xffff;

            VAR_5 = vm_getl(ssp, VAR_2 + 4) & 0xffff;

            VAR_3 = vm_getl(ssp, VAR_2 + 8);

            ADD16(VAR_0->regs[R_ESP], 12);

        } else {

            VAR_4 = vm_getw(ssp, VAR_2);

            VAR_5 = vm_getw(ssp, VAR_2 + 2);

            VAR_3 = vm_getw(ssp, VAR_2 + 4);

            ADD16(VAR_0->regs[R_ESP], 6);

        }

        VAR_0->eip = VAR_4;

        cpu_x86_load_seg(VAR_0, R_CS, VAR_5);

        CHECK_IF_IN_TRAP();

        if (VAR_8) {

            if (set_vflags_long(VAR_3, VAR_0))

                return;

        } else {

            if (set_vflags_short(VAR_3, VAR_0))

                return;

        }

        VM86_FAULT_RETURN;

        

    case 0xfa: 

        VAR_0->eip = VAR_1;

        clear_IF(VAR_0);

        VM86_FAULT_RETURN;

        

    case 0xfb: 

        VAR_0->eip = VAR_1;

        if (set_IF(VAR_0))

            return;

        VM86_FAULT_RETURN;



    default:

        

        return_to_32bit(VAR_0, TARGET_VM86_UNKNOWN);

        break;

    }

}

void FUNC_0(CPUX86State *VAR_0)
{ TaskState *ts = VAR_0->opaque; uint8_t *csp, *pc, *ssp; unsigned int VAR_1, VAR_2, VAR_3, VAR_4, VAR_5, VAR_6, VAR_7; int VAR_8, VAR_9; csp = (uint8_t *)(VAR_0->segs[R_CS] << 4); VAR_1 = VAR_0->eip & 0xffff; pc = csp + VAR_1; ssp = (uint8_t *)(VAR_0->segs[R_SS] << 4); VAR_2 = VAR_0->regs[R_ESP] & 0xffff; #if defined(DEBUG_VM86)
fprintf(logfile, "VM86 exception %04x:%08x %02x %02x\n",
VAR_0->segs[R_CS], VAR_0->eip, pc[0], pc[1]); #endif
VAR_8 = 0; VAR_9 = 0; do { VAR_6 = csp[VAR_1]; ADD16(VAR_1, 1); switch (VAR_6) { case 0x66:           VAR_8=1; break; case 0x67:        break; case 0x2e:                    break; case 0x3e:                    break; case 0x26:                    break; case 0x36:                    break; case 0x65:                    break; case 0x64:                    break; case 0xf2:      	      break; case 0xf3:                   break; default: VAR_9 = 1; } } while (!VAR_9); switch(VAR_6) { case 0x9c:
ADD16(VAR_0->eip, 2); if (VAR_8) { vm_putl(ssp, VAR_2 - 4, get_vflags(VAR_0)); ADD16(VAR_0->regs[R_ESP], -4); } else { vm_putw(ssp, VAR_2 - 2, get_vflags(VAR_0)); ADD16(VAR_0->regs[R_ESP], -2); } VAR_0->eip = VAR_1; VM86_FAULT_RETURN; case 0x9d:
if (VAR_8) { VAR_3 = vm_getl(ssp, VAR_2); ADD16(VAR_0->regs[R_ESP], 4); } else { VAR_3 = vm_getw(ssp, VAR_2); ADD16(VAR_0->regs[R_ESP], 2); } VAR_0->eip = VAR_1; CHECK_IF_IN_TRAP(); if (VAR_8) { if (set_vflags_long(VAR_3, VAR_0))
return; } else { if (set_vflags_short(VAR_3, VAR_0))
return; } VM86_FAULT_RETURN; case 0xcd:
VAR_7 = csp[VAR_1]; ADD16(VAR_1, 1); VAR_0->eip = VAR_1; if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) { if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[VAR_7 >> 3] >>
(VAR_7 &7)) & 1) { return_to_32bit(VAR_0, TARGET_VM86_INTx + (VAR_7 << 8)); return; } } do_int(VAR_0, VAR_7); break; case 0xcf:
if (VAR_8) { VAR_4 = vm_getl(ssp, VAR_2) & 0xffff; VAR_5 = vm_getl(ssp, VAR_2 + 4) & 0xffff; VAR_3 = vm_getl(ssp, VAR_2 + 8); ADD16(VAR_0->regs[R_ESP], 12); } else { VAR_4 = vm_getw(ssp, VAR_2); VAR_5 = vm_getw(ssp, VAR_2 + 2); VAR_3 = vm_getw(ssp, VAR_2 + 4); ADD16(VAR_0->regs[R_ESP], 6); } VAR_0->eip = VAR_4; cpu_x86_load_seg(VAR_0, R_CS, VAR_5); CHECK_IF_IN_TRAP(); if (VAR_8) { if (set_vflags_long(VAR_3, VAR_0))
return; } else { if (set_vflags_short(VAR_3, VAR_0))
return; } VM86_FAULT_RETURN; case 0xfa:
VAR_0->eip = VAR_1; clear_IF(VAR_0); VM86_FAULT_RETURN; case 0xfb:
VAR_0->eip = VAR_1; if (set_IF(VAR_0))
return; VM86_FAULT_RETURN; default:
return_to_32bit(VAR_0, TARGET_VM86_UNKNOWN); break; } }