about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/emu/x64run.c74
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