about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run66f0.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/emu/x64run66f0.c b/src/emu/x64run66f0.c
index da67fcbe..951edccd 100644
--- a/src/emu/x64run66f0.c
+++ b/src/emu/x64run66f0.c
@@ -32,9 +32,11 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr)
 {
     uint8_t opcode;
     uint8_t nextop;
+    uint8_t tmp8u, tmp8u2;
     int16_t tmp16s;
     uint16_t tmp16u, tmp16u2;
     int32_t tmp32s;
+    uint32_t tmp32u, tmp32u2;
     int64_t tmp64s;
     uint64_t tmp64u, tmp64u2;
     reg64_t *oped, *opgd;
@@ -89,6 +91,57 @@ uintptr_t Run66F0(x64emu_t *emu, rex_t rex, uintptr_t addr)
 #endif
                     break;
 
+                case 0xBA: /* BTS Ew, Ib */
+                    CHECK_FLAGS(emu);
+                    nextop = F8;
+                    GETEW(0);
+                    tmp8u = F8;
+#if defined(DYNAREC) && !defined(TEST_INTERPRETER)
+                    tmp8u &= 15;
+                    if ((uintptr_t)ED & 1) {
+                        do {
+                            tmp32u = native_lock_read_b(ED + (tmp8u >> 3));
+                            if (tmp32u & (1 << (tmp8u & 7))) {
+                                SET_FLAG(F_CF);
+                                tmp32s = 0;
+                            } else {
+                                tmp32u ^= (1 << (tmp8u & 7));
+                                tmp32s = native_lock_write_b(ED + (tmp8u >> 3), tmp32u);
+                                CLEAR_FLAG(F_CF);
+                            }
+                        } while (tmp32s);
+                    } else {
+                        do {
+                            tmp32u = native_lock_read_h(ED);
+                            if (tmp32u & (1 << tmp8u)) {
+                                SET_FLAG(F_CF);
+                                tmp32s = 0;
+                            } else {
+                                tmp32u ^= (1 << tmp8u);
+                                tmp32s = native_lock_write_h(ED, tmp32u);
+                                CLEAR_FLAG(F_CF);
+                            }
+                        } while (tmp32s);
+                    }
+#else
+                    pthread_mutex_lock(&my_context->mutex_lock);
+                    tmp8u &= 15;
+                    if (ED->dword[0] & (1 << tmp8u)) {
+                        SET_FLAG(F_CF);
+                    } else {
+                        ED->dword[0] ^= (1 << tmp8u);
+                        CLEAR_FLAG(F_CF);
+                    }
+                    pthread_mutex_unlock(&my_context->mutex_lock);
+#endif
+                    if (BOX64ENV(dynarec_test)) {
+                        CLEAR_FLAG(F_OF);
+                        CLEAR_FLAG(F_SF);
+                        CLEAR_FLAG(F_AF);
+                        CLEAR_FLAG(F_PF);
+                    }
+                    break;
+
                 case 0xC1:                      /* XADD Gw,Ew */
                     nextop = F8;
                     GETEW(0);