mad_status DIGENTRY MITraceSimulate( mad_trace_data *td, mad_disasm_data *dd, const mad_registers *in, mad_registers *out ) { address sp; word value; td = td; switch( dd->ins.type ) { case DI_X86_into: if( !( in->x86.cpu.efl & FLG_O ) ) { out->x86 = in->x86; out->x86.cpu.eip += dd->ins.size; return( MS_OK ); } /* fall through */ case DI_X86_int: /* only in real mode */ if( !( dd->characteristics & X86AC_REAL ) ) break; out->x86 = in->x86; sp = GetRegSP( out ); sp.mach.offset -= sizeof( word ); value = out->x86.cpu.efl; MCWriteMem( sp, sizeof( value ), &value ); out->x86.cpu.efl &= ~FLG_I; value = out->x86.cpu.cs; MCWriteMem( sp, sizeof( value ), &value ); value = out->x86.cpu.eip; MCWriteMem( sp, sizeof( value ), &value ); out->x86.cpu.esp = sp.mach.offset; return( MS_OK ); default: break; } return( MS_UNSUPPORTED ); }
mad_status MADIMPENTRY( CallBuildFrame )( mad_string call, address ret, address rtn, const mad_registers *in, mad_registers *out ) { unsigned dec; unsigned_32 value; address sp; dec = BIG_SEG( rtn ) ? 4 : 2; if( call == MAD_MSTR_NIL ) { call = (dec == 2) ? MAD_MSTR_FAR : MAD_MSTR_NEAR; } out->x86 = in->x86; sp = GetRegSP( out ); switch( call ) { case MAD_MSTR_INTERRUPT: sp.mach.offset -= dec; value = out->x86.cpu.efl; MCWriteMem( sp, dec, &value ); /* fall through */ case MAD_MSTR_FAR: sp.mach.offset -= dec; value = ret.mach.segment; MCWriteMem( sp, dec, &value ); /* fall through */ case MAD_MSTR_NEAR: sp.mach.offset -= dec; value = ret.mach.offset; MCWriteMem( sp, dec, &value ); break; } out->x86.cpu.esp = sp.mach.offset; out->x86.cpu.cs = rtn.mach.segment; out->x86.cpu.eip = rtn.mach.offset; return( MS_OK ); }