diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/emu/x64run.c | 74 |
1 files changed, 69 insertions, 5 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 3c6808de..397fbed1 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -447,14 +447,78 @@ x64emurun: GD->q[0] = imul32(emu, ED->dword[0], (uint32_t)tmp64s); break; case 0x6C: /* INSB DX */ + if(rex.is32bits) { + tmp32u = rep?R_ECX:1; + while(tmp32u--) { + *(int8_t*)(R_EDI+GetESBaseEmu(emu)) = 0; // faking port read, using explicit ES segment + if(ACCESS_FLAG(F_DF)) + R_EDI-=1; + else + R_EDI+=1; + } + if(rep) + R_ECX = 0; + } else { + // this is a privilege opcode in 64bits, but not in 32bits... + #ifndef TEST_INTERPRETOR + emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); + STEP; + #endif + } + break; case 0x6D: /* INSL DX */ + if(rex.is32bits) { + tmp32u = rep?R_ECX:1; + while(tmp32u--) { + *(int32_t*)(R_EDI+GetESBaseEmu(emu)) = 0; // faking port read, using explicit ES segment + if(ACCESS_FLAG(F_DF)) + R_EDI-=4; + else + R_EDI+=4; + } + if(rep) + R_ECX = 0; + } else { + // this is a privilege opcode in 64bits, but not in 32bits... + #ifndef TEST_INTERPRETOR + emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); + STEP; + #endif + } + break; case 0x6E: /* OUTSB DX */ + if(rex.is32bits) { + // faking port write, using explicit ES segment + if(ACCESS_FLAG(F_DF)) + R_ESI-=rep?R_ECX:1; + else + R_ESI+=1?R_ECX:1; + if(rep) + R_ECX = 0; + } else { + // this is a privilege opcode in 64bits, but not in 32bits... + #ifndef TEST_INTERPRETOR + emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); + STEP; + #endif + } + break; case 0x6F: /* OUTSL DX */ - // this is a privilege opcode in 64bits, but not in 32bits... - #ifndef TEST_INTERPRETOR - emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); - STEP; - #endif + if(rex.is32bits) { + // faking port write, using explicit ES segment + if(ACCESS_FLAG(F_DF)) + R_ESI-=(rep?R_ECX:1)*4; + else + R_ESI+=(rep?R_ECX:1)*4; + if(rep) + R_ECX = 0; + } else { + // this is a privilege opcode in 64bits, but not in 32bits... + #ifndef TEST_INTERPRETOR + emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); + STEP; + #endif + } break; GOCOND(0x70 |