mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 17:15:32 -07:00
clang format in cpu
This commit is contained in:
@@ -209,7 +209,7 @@ exec386(int cycs)
|
||||
enter_smm_check(0);
|
||||
else if (nmi && nmi_enable && nmi_mask) {
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
oldcs = CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(2);
|
||||
|
||||
1697
src/cpu/386_common.c
1697
src/cpu/386_common.c
File diff suppressed because it is too large
Load Diff
@@ -21,308 +21,400 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) )
|
||||
#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
|
||||
#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
|
||||
#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) )
|
||||
#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
|
||||
#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
|
||||
#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a))))
|
||||
#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
#define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a))))
|
||||
#define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))))
|
||||
|
||||
#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
|
||||
#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
|
||||
#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
|
||||
#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
|
||||
#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
|
||||
#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
|
||||
#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v
|
||||
#define writememb_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememw_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememl_n(s, a, b, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll_no_mmut((s) + (a), b, v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememb(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
writemembl((s) + (a), v); \
|
||||
else \
|
||||
*(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememw(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
writememwl((s) + (a), v); \
|
||||
else \
|
||||
*(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememl(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
writememll((s) + (a), v); \
|
||||
else \
|
||||
*(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
#define writememq(s, a, v) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \
|
||||
writememql((s) + (a), v); \
|
||||
else \
|
||||
*(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v
|
||||
|
||||
#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0)
|
||||
#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0)
|
||||
#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0)
|
||||
#define do_mmut_rb2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0)
|
||||
#define do_mmut_rw2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0)
|
||||
#define do_mmut_rl2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0)
|
||||
|
||||
#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1)
|
||||
#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1)
|
||||
#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1)
|
||||
#define do_mmut_rb(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
#define do_mmut_rw(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
#define do_mmut_rl(s, a, b) \
|
||||
if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
#define do_mmut_rb2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 0)
|
||||
#define do_mmut_rw2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 0)
|
||||
#define do_mmut_rl2(s, a, b) \
|
||||
old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \
|
||||
if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 0)
|
||||
|
||||
#define do_mmut_wb(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \
|
||||
do_mmutranslate((s) + (a), b, 1, 1)
|
||||
#define do_mmut_ww(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \
|
||||
do_mmutranslate((s) + (a), b, 2, 1)
|
||||
#define do_mmut_wl(s, a, b) \
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 1)
|
||||
|
||||
int checkio(uint32_t port);
|
||||
|
||||
#define check_io_perm(port) \
|
||||
if (msw & 1 && ((CPL > IOPL) || (cpu_state.eflags & VM_FLAG))) { \
|
||||
int tempi = checkio(port); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (tempi) { \
|
||||
if (cpu_state.eflags & VM_FLAG) \
|
||||
x86gpf_expected(NULL, 0); \
|
||||
else \
|
||||
x86gpf(NULL, 0); \
|
||||
return 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \
|
||||
{ \
|
||||
int tempi = checkio(port); \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
if (tempi) \
|
||||
{ \
|
||||
if (cpu_state.eflags & VM_FLAG) \
|
||||
x86gpf_expected(NULL,0); \
|
||||
else \
|
||||
x86gpf(NULL,0); \
|
||||
return 1; \
|
||||
} \
|
||||
}
|
||||
#define SEG_CHECK_READ(seg) \
|
||||
do { \
|
||||
if ((seg)->base == 0xffffffff) { \
|
||||
x86gpf("Segment can't read", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEG_CHECK_READ(seg) \
|
||||
do \
|
||||
{ \
|
||||
if ((seg)->base == 0xffffffff) \
|
||||
{ \
|
||||
x86gpf("Segment can't read", 0);\
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
#define SEG_CHECK_WRITE(seg) \
|
||||
do { \
|
||||
if ((seg)->base == 0xffffffff) { \
|
||||
x86gpf("Segment can't write", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEG_CHECK_WRITE(seg) \
|
||||
do \
|
||||
{ \
|
||||
if ((seg)->base == 0xffffffff) \
|
||||
{ \
|
||||
x86gpf("Segment can't write", 0);\
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CHECK_READ(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) { \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL, (chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CHECK_READ(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \
|
||||
{ \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
}
|
||||
#define CHECK_READ_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL, (chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define CHECK_READ_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
}
|
||||
#define CHECK_WRITE_COMMON(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) { \
|
||||
x86gpf("Limit check (WRITE)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL, (chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE_COMMON(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \
|
||||
{ \
|
||||
x86gpf("Limit check (WRITE)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
}
|
||||
#define CHECK_WRITE(chseg, low, high) \
|
||||
CHECK_WRITE_COMMON(chseg, low, high)
|
||||
|
||||
#define CHECK_WRITE(chseg, low, high) \
|
||||
CHECK_WRITE_COMMON(chseg, low, high)
|
||||
#define CHECK_WRITE_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \
|
||||
x86gpf("Limit check (WRITE REP)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL, (chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check (WRITE REP)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
}
|
||||
#define NOTRM \
|
||||
if (!(msw & 1) || (cpu_state.eflags & VM_FLAG)) { \
|
||||
x86_int(6); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
|
||||
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
|
||||
{ \
|
||||
x86_int(6); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline uint8_t fastreadb(uint32_t a)
|
||||
static __inline uint8_t
|
||||
fastreadb(uint32_t a)
|
||||
{
|
||||
uint8_t *t;
|
||||
uint8_t *t;
|
||||
|
||||
if ((a >> 12) == pccache)
|
||||
return *((uint8_t *)&pccache2[a]);
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
return *((uint8_t *)&pccache2[a]);
|
||||
if ((a >> 12) == pccache)
|
||||
return *((uint8_t *) &pccache2[a]);
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
return *((uint8_t *) &pccache2[a]);
|
||||
}
|
||||
|
||||
static __inline uint16_t fastreadw(uint32_t a)
|
||||
static __inline uint16_t
|
||||
fastreadw(uint32_t a)
|
||||
{
|
||||
uint8_t *t;
|
||||
uint16_t val;
|
||||
if ((a&0xFFF)>0xFFE)
|
||||
{
|
||||
val = fastreadb(a);
|
||||
val |= (fastreadb(a + 1) << 8);
|
||||
return val;
|
||||
}
|
||||
if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]);
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
return *((uint16_t *)&pccache2[a]);
|
||||
}
|
||||
|
||||
static __inline uint32_t fastreadl(uint32_t a)
|
||||
{
|
||||
uint8_t *t;
|
||||
uint32_t val;
|
||||
if ((a&0xFFF)<0xFFD)
|
||||
{
|
||||
if ((a>>12)!=pccache)
|
||||
{
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
pccache2 = t;
|
||||
pccache=a>>12;
|
||||
}
|
||||
return *((uint32_t *)&pccache2[a]);
|
||||
}
|
||||
val = fastreadw(a);
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
uint8_t *t;
|
||||
uint16_t val;
|
||||
if ((a & 0xFFF) > 0xFFE) {
|
||||
val = fastreadb(a);
|
||||
val |= (fastreadb(a + 1) << 8);
|
||||
return val;
|
||||
}
|
||||
if ((a >> 12) == pccache)
|
||||
return *((uint16_t *) &pccache2[a]);
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
return *((uint16_t *) &pccache2[a]);
|
||||
}
|
||||
|
||||
static __inline void *get_ram_ptr(uint32_t a)
|
||||
static __inline uint32_t
|
||||
fastreadl(uint32_t a)
|
||||
{
|
||||
if ((a >> 12) == pccache)
|
||||
return &pccache2[a];
|
||||
else
|
||||
{
|
||||
uint8_t *t = getpccache(a);
|
||||
return &t[a];
|
||||
uint8_t *t;
|
||||
uint32_t val;
|
||||
if ((a & 0xFFF) < 0xFFD) {
|
||||
if ((a >> 12) != pccache) {
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
pccache2 = t;
|
||||
pccache = a >> 12;
|
||||
}
|
||||
return *((uint32_t *) &pccache2[a]);
|
||||
}
|
||||
val = fastreadw(a);
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
|
||||
static __inline uint8_t getbyte(void)
|
||||
static __inline void *
|
||||
get_ram_ptr(uint32_t a)
|
||||
{
|
||||
cpu_state.pc++;
|
||||
return fastreadb(cs + (cpu_state.pc - 1));
|
||||
if ((a >> 12) == pccache)
|
||||
return &pccache2[a];
|
||||
else {
|
||||
uint8_t *t = getpccache(a);
|
||||
return &t[a];
|
||||
}
|
||||
}
|
||||
|
||||
static __inline uint16_t getword(void)
|
||||
static __inline uint8_t
|
||||
getbyte(void)
|
||||
{
|
||||
cpu_state.pc+=2;
|
||||
return fastreadw(cs+(cpu_state.pc-2));
|
||||
cpu_state.pc++;
|
||||
return fastreadb(cs + (cpu_state.pc - 1));
|
||||
}
|
||||
|
||||
static __inline uint32_t getlong(void)
|
||||
static __inline uint16_t
|
||||
getword(void)
|
||||
{
|
||||
cpu_state.pc+=4;
|
||||
return fastreadl(cs+(cpu_state.pc-4));
|
||||
cpu_state.pc += 2;
|
||||
return fastreadw(cs + (cpu_state.pc - 2));
|
||||
}
|
||||
|
||||
static __inline uint64_t getquad(void)
|
||||
static __inline uint32_t
|
||||
getlong(void)
|
||||
{
|
||||
cpu_state.pc+=8;
|
||||
return fastreadl(cs+(cpu_state.pc-8)) | ((uint64_t)fastreadl(cs+(cpu_state.pc-4)) << 32);
|
||||
cpu_state.pc += 4;
|
||||
return fastreadl(cs + (cpu_state.pc - 4));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline uint8_t geteab(void)
|
||||
static __inline uint64_t
|
||||
getquad(void)
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l;
|
||||
if (eal_r)
|
||||
return *(uint8_t *)eal_r;
|
||||
return readmemb(easeg, cpu_state.eaaddr);
|
||||
cpu_state.pc += 8;
|
||||
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
|
||||
}
|
||||
|
||||
static __inline uint16_t geteaw(void)
|
||||
static __inline uint8_t
|
||||
geteab(void)
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].w;
|
||||
if (eal_r)
|
||||
return *(uint16_t *)eal_r;
|
||||
return readmemw(easeg, cpu_state.eaaddr);
|
||||
if (cpu_mod == 3)
|
||||
return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l;
|
||||
if (eal_r)
|
||||
return *(uint8_t *) eal_r;
|
||||
return readmemb(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline uint32_t geteal(void)
|
||||
static __inline uint16_t
|
||||
geteaw(void)
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].l;
|
||||
if (eal_r)
|
||||
return *eal_r;
|
||||
return readmeml(easeg, cpu_state.eaaddr);
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].w;
|
||||
if (eal_r)
|
||||
return *(uint16_t *) eal_r;
|
||||
return readmemw(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline uint64_t geteaq(void)
|
||||
static __inline uint32_t
|
||||
geteal(void)
|
||||
{
|
||||
return readmemq(easeg, cpu_state.eaaddr);
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].l;
|
||||
if (eal_r)
|
||||
return *eal_r;
|
||||
return readmeml(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline uint8_t geteab_mem(void)
|
||||
static __inline uint64_t
|
||||
geteaq(void)
|
||||
{
|
||||
if (eal_r) return *(uint8_t *)eal_r;
|
||||
return readmemb(easeg,cpu_state.eaaddr);
|
||||
return readmemq(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
static __inline uint16_t geteaw_mem(void)
|
||||
|
||||
static __inline uint8_t
|
||||
geteab_mem(void)
|
||||
{
|
||||
if (eal_r) return *(uint16_t *)eal_r;
|
||||
return readmemw(easeg,cpu_state.eaaddr);
|
||||
if (eal_r)
|
||||
return *(uint8_t *) eal_r;
|
||||
return readmemb(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
static __inline uint32_t geteal_mem(void)
|
||||
static __inline uint16_t
|
||||
geteaw_mem(void)
|
||||
{
|
||||
if (eal_r) return *eal_r;
|
||||
return readmeml(easeg,cpu_state.eaaddr);
|
||||
if (eal_r)
|
||||
return *(uint16_t *) eal_r;
|
||||
return readmemw(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline int seteaq_cwc(void)
|
||||
static __inline uint32_t
|
||||
geteal_mem(void)
|
||||
{
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
return 0;
|
||||
if (eal_r)
|
||||
return *eal_r;
|
||||
return readmeml(easeg, cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static __inline void seteaq(uint64_t v)
|
||||
static __inline int
|
||||
seteaq_cwc(void)
|
||||
{
|
||||
if (seteaq_cwc())
|
||||
return;
|
||||
writememql(easeg + cpu_state.eaaddr, v);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
|
||||
#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v
|
||||
#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v
|
||||
static __inline void
|
||||
seteaq(uint64_t v)
|
||||
{
|
||||
if (seteaq_cwc())
|
||||
return;
|
||||
writememql(easeg + cpu_state.eaaddr, v);
|
||||
}
|
||||
|
||||
#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v);
|
||||
#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v);
|
||||
#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v);
|
||||
#define seteab(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \
|
||||
if (eal_w) \
|
||||
*(uint8_t *) eal_w = v; \
|
||||
else \
|
||||
writemembl(easeg + cpu_state.eaaddr, v); \
|
||||
} else if (cpu_rm & 4) \
|
||||
cpu_state.regs[cpu_rm & 3].b.h = v; \
|
||||
else \
|
||||
cpu_state.regs[cpu_rm].b.l = v
|
||||
#define seteaw(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \
|
||||
if (eal_w) \
|
||||
*(uint16_t *) eal_w = v; \
|
||||
else \
|
||||
writememwl(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].w = v
|
||||
#define seteal(v) \
|
||||
if (cpu_mod != 3) { \
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
if (eal_w) \
|
||||
*eal_w = v; \
|
||||
else \
|
||||
writememll(easeg + cpu_state.eaaddr, v); \
|
||||
} else \
|
||||
cpu_state.regs[cpu_rm].l = v
|
||||
|
||||
#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++
|
||||
#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2
|
||||
#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++
|
||||
#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2
|
||||
#define seteab_mem(v) \
|
||||
if (eal_w) \
|
||||
*(uint8_t *) eal_w = v; \
|
||||
else \
|
||||
writemembl(easeg + cpu_state.eaaddr, v);
|
||||
#define seteaw_mem(v) \
|
||||
if (eal_w) \
|
||||
*(uint16_t *) eal_w = v; \
|
||||
else \
|
||||
writememwl(easeg + cpu_state.eaaddr, v);
|
||||
#define seteal_mem(v) \
|
||||
if (eal_w) \
|
||||
*eal_w = v; \
|
||||
else \
|
||||
writememll(easeg + cpu_state.eaaddr, v);
|
||||
|
||||
#define getbytef() \
|
||||
((uint8_t) (fetchdat)); \
|
||||
cpu_state.pc++
|
||||
#define getwordf() \
|
||||
((uint16_t) (fetchdat)); \
|
||||
cpu_state.pc += 2
|
||||
#define getbyte2f() \
|
||||
((uint8_t) (fetchdat >> 8)); \
|
||||
cpu_state.pc++
|
||||
#define getword2f() \
|
||||
((uint16_t) (fetchdat >> 8)); \
|
||||
cpu_state.pc += 2
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
# define INFINITY (__builtin_inff())
|
||||
#endif
|
||||
|
||||
#include <86box/86box.h>
|
||||
@@ -25,57 +25,61 @@
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
#ifndef IS_DYNAREC
|
||||
#define IS_DYNAREC
|
||||
# define IS_DYNAREC
|
||||
#endif
|
||||
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
static __inline void
|
||||
fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) {
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
static __inline void
|
||||
fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) {
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV)
|
||||
eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat);
|
||||
#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat);
|
||||
|
||||
#define fetch_ea_16(rmdat) \
|
||||
cpu_state.pc++; \
|
||||
if (cpu_mod != 3) \
|
||||
fetch_ea_16_long(rmdat);
|
||||
#define fetch_ea_32(rmdat) \
|
||||
cpu_state.pc++; \
|
||||
if (cpu_mod != 3) \
|
||||
fetch_ea_32_long(rmdat);
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32)
|
||||
#define PREFETCH_PREFIX()
|
||||
#define PREFETCH_FLUSH()
|
||||
|
||||
#define OP_TABLE(name) dynarec_ops_ ## name
|
||||
#define OP_TABLE(name) dynarec_ops_##name
|
||||
|
||||
#define CLOCK_CYCLES(c)
|
||||
#if 0
|
||||
#define CLOCK_CYCLES_FPU(c)
|
||||
#define CONCURRENCY_CYCLES(c) fpu_cycles = (c)
|
||||
# define CLOCK_CYCLES_FPU(c)
|
||||
# define CONCURRENCY_CYCLES(c) fpu_cycles = (c)
|
||||
#else
|
||||
#define CLOCK_CYCLES_FPU(c)
|
||||
#define CONCURRENCY_CYCLES(c)
|
||||
# define CLOCK_CYCLES_FPU(c)
|
||||
# define CONCURRENCY_CYCLES(c)
|
||||
#endif
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
|
||||
@@ -40,128 +40,137 @@
|
||||
*/
|
||||
#include "x86_ops.h"
|
||||
|
||||
#define ILLEGAL_ON(cond) \
|
||||
do { \
|
||||
if ((cond)) { \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
x86illegal(); \
|
||||
return 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ILLEGAL_ON(cond) \
|
||||
do \
|
||||
{ \
|
||||
if ((cond)) \
|
||||
{ \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
x86illegal(); \
|
||||
return 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static __inline void PUSH_W(uint16_t val)
|
||||
static __inline void
|
||||
PUSH_W(uint16_t val)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss, ESP - 2, val); if (cpu_state.abrt) return;
|
||||
ESP -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss, (SP - 2) & 0xFFFF, val); if (cpu_state.abrt) return;
|
||||
SP -= 2;
|
||||
}
|
||||
if (stack32) {
|
||||
writememw(ss, ESP - 2, val);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
ESP -= 2;
|
||||
} else {
|
||||
writememw(ss, (SP - 2) & 0xFFFF, val);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
SP -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void PUSH_L(uint32_t val)
|
||||
static __inline void
|
||||
PUSH_L(uint32_t val)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememl(ss, ESP - 4, val); if (cpu_state.abrt) return;
|
||||
ESP -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(ss, (SP - 4) & 0xFFFF, val); if (cpu_state.abrt) return;
|
||||
SP -= 4;
|
||||
}
|
||||
if (stack32) {
|
||||
writememl(ss, ESP - 4, val);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
ESP -= 4;
|
||||
} else {
|
||||
writememl(ss, (SP - 4) & 0xFFFF, val);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
SP -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline uint16_t POP_W(void)
|
||||
static __inline uint16_t
|
||||
POP_W(void)
|
||||
{
|
||||
uint16_t ret;
|
||||
if (stack32)
|
||||
{
|
||||
ret = readmemw(ss, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmemw(ss, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 2;
|
||||
}
|
||||
return ret;
|
||||
uint16_t ret;
|
||||
if (stack32) {
|
||||
ret = readmemw(ss, ESP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
ESP += 2;
|
||||
} else {
|
||||
ret = readmemw(ss, SP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
SP += 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline uint32_t POP_L(void)
|
||||
static __inline uint32_t
|
||||
POP_L(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
if (stack32)
|
||||
{
|
||||
ret = readmeml(ss, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmeml(ss, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 4;
|
||||
}
|
||||
return ret;
|
||||
uint32_t ret;
|
||||
if (stack32) {
|
||||
ret = readmeml(ss, ESP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
ESP += 4;
|
||||
} else {
|
||||
ret = readmeml(ss, SP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
SP += 4;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline uint16_t POP_W_seg(uint32_t seg)
|
||||
static __inline uint16_t
|
||||
POP_W_seg(uint32_t seg)
|
||||
{
|
||||
uint16_t ret;
|
||||
if (stack32)
|
||||
{
|
||||
ret = readmemw(seg, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmemw(seg, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 2;
|
||||
}
|
||||
return ret;
|
||||
uint16_t ret;
|
||||
if (stack32) {
|
||||
ret = readmemw(seg, ESP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
ESP += 2;
|
||||
} else {
|
||||
ret = readmemw(seg, SP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
SP += 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline uint32_t POP_L_seg(uint32_t seg)
|
||||
static __inline uint32_t
|
||||
POP_L_seg(uint32_t seg)
|
||||
{
|
||||
uint32_t ret;
|
||||
if (stack32)
|
||||
{
|
||||
ret = readmeml(seg, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmeml(seg, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 4;
|
||||
}
|
||||
return ret;
|
||||
uint32_t ret;
|
||||
if (stack32) {
|
||||
ret = readmeml(seg, ESP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
ESP += 4;
|
||||
} else {
|
||||
ret = readmeml(seg, SP);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
SP += 4;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fopcode;
|
||||
|
||||
static int ILLEGAL(uint32_t fetchdat)
|
||||
static int
|
||||
ILLEGAL(uint32_t fetchdat)
|
||||
{
|
||||
pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode);
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode);
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
|
||||
x86illegal();
|
||||
return 0;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
extern void x386_dynarec_log(const char *fmt, ...);
|
||||
extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#else
|
||||
#ifndef x386_dynarec_log
|
||||
#define x386_dynarec_log(fmt, ...)
|
||||
#endif
|
||||
# ifndef x386_dynarec_log
|
||||
# define x386_dynarec_log(fmt, ...)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "x86seg.h"
|
||||
@@ -196,9 +205,9 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#include "x86_ops_pmode.h"
|
||||
#include "x86_ops_prefix.h"
|
||||
#ifdef IS_DYNAREC
|
||||
#include "x86_ops_rep_dyn.h"
|
||||
# include "x86_ops_rep_dyn.h"
|
||||
#else
|
||||
#include "x86_ops_rep.h"
|
||||
# include "x86_ops_rep.h"
|
||||
#endif
|
||||
#include "x86_ops_ret.h"
|
||||
#include "x86_ops_set.h"
|
||||
@@ -211,157 +220,160 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#include "x86_ops_3dnow.h"
|
||||
#include <time.h>
|
||||
|
||||
|
||||
static int opVPCEXT(uint32_t fetchdat)
|
||||
static int
|
||||
opVPCEXT(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t b1, b2;
|
||||
uint16_t cent;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
uint8_t b1, b2;
|
||||
uint16_t cent;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
|
||||
if (!is_vpc) /* only emulate this on Virtual PC machines */
|
||||
return ILLEGAL(fetchdat);
|
||||
if (!is_vpc) /* only emulate this on Virtual PC machines */
|
||||
return ILLEGAL(fetchdat);
|
||||
|
||||
cpu_state.pc += 2;
|
||||
cpu_state.pc += 2;
|
||||
|
||||
b1 = fetchdat & 0xff;
|
||||
b2 = (fetchdat >> 8) & 0xff;
|
||||
b1 = fetchdat & 0xff;
|
||||
b2 = (fetchdat >> 8) & 0xff;
|
||||
|
||||
/* a lot of these opcodes (which?) return illegal instruction in user mode */
|
||||
ILLEGAL_ON(CPL > 0);
|
||||
/* a lot of these opcodes (which?) return illegal instruction in user mode */
|
||||
ILLEGAL_ON(CPL > 0);
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
CLOCK_CYCLES(1);
|
||||
|
||||
/* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */
|
||||
if (b1 == 0x03) {
|
||||
(void)time(&now);
|
||||
tm = localtime(&now);
|
||||
}
|
||||
/* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */
|
||||
if (b1 == 0x03) {
|
||||
(void) time(&now);
|
||||
tm = localtime(&now);
|
||||
}
|
||||
|
||||
if ((b1 == 0x07) && (b2 == 0x0b)) {
|
||||
/* 0f 3f 07 0b: unknown, EDX output depends on EAX input */
|
||||
switch (EAX) {
|
||||
case 0x00000000:
|
||||
EDX = 0x00000003;
|
||||
break;
|
||||
if ((b1 == 0x07) && (b2 == 0x0b)) {
|
||||
/* 0f 3f 07 0b: unknown, EDX output depends on EAX input */
|
||||
switch (EAX) {
|
||||
case 0x00000000:
|
||||
EDX = 0x00000003;
|
||||
break;
|
||||
|
||||
case 0x00000001:
|
||||
EDX = 0x00000012;
|
||||
break;
|
||||
case 0x00000001:
|
||||
EDX = 0x00000012;
|
||||
break;
|
||||
|
||||
case 0x00000002:
|
||||
case 0x00000003:
|
||||
case 0x00000004:
|
||||
case 0x00000005:
|
||||
EDX = 0x00000001;
|
||||
break;
|
||||
case 0x00000002:
|
||||
case 0x00000003:
|
||||
case 0x00000004:
|
||||
case 0x00000005:
|
||||
EDX = 0x00000001;
|
||||
break;
|
||||
|
||||
case 0x00000007:
|
||||
EDX = 0x0000009c;
|
||||
break;
|
||||
case 0x00000007:
|
||||
EDX = 0x0000009c;
|
||||
break;
|
||||
|
||||
default:
|
||||
EDX = 0x00000000;
|
||||
if (EAX > 0x00000012) /* unknown EAX values set zero flag */
|
||||
cpu_state.flags &= ~(Z_FLAG);
|
||||
}
|
||||
} else if ((b1 == 0x03) && (b2 == 0x00)) {
|
||||
/* 0f 3f 03 00: host time in BCD */
|
||||
EDX = BCD8(tm->tm_hour);
|
||||
ECX = BCD8(tm->tm_min);
|
||||
EAX = BCD8(tm->tm_sec);
|
||||
} else if ((b1 == 0x03) && (b2 == 0x01)) {
|
||||
/* 0f 3f 03 00: host date in BCD */
|
||||
EDX = BCD8(tm->tm_year % 100);
|
||||
ECX = BCD8(tm->tm_mon + 1);
|
||||
EAX = BCD8(tm->tm_mday);
|
||||
cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */
|
||||
EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7);
|
||||
} else if ((b1 == 0x03) && (b2 == 0x03)) {
|
||||
/* 0f 3f 03 03: host time in binary */
|
||||
EDX = tm->tm_hour;
|
||||
ECX = tm->tm_min;
|
||||
EAX = tm->tm_sec;
|
||||
} else if ((b1 == 0x03) && (b2 == 0x04)) {
|
||||
/* 0f 3f 03 04: host date in binary */
|
||||
EDX = 1900 + tm->tm_year;
|
||||
ECX = tm->tm_mon + 1;
|
||||
EBX = tm->tm_mday;
|
||||
} else if ((b1 == 0x03) && (b2 == 0x05)) {
|
||||
/* 0f 3f 03 05: unknown */
|
||||
EBX = 0x0000000F;
|
||||
ECX = 0x0000000A;
|
||||
} else if ((b1 == 0x03) && (b2 == 0x06)) {
|
||||
/* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */
|
||||
EBX = 0x00000000;
|
||||
ECX = 0x00000000;
|
||||
} else if ((b1 == 0x03) && (b2 >= 0x07)) {
|
||||
/* 0f 3f 03 07+: set zero flag */
|
||||
cpu_state.flags &= ~(Z_FLAG);
|
||||
} else if ((b1 == 0x0a) && (b2 == 0x00)) {
|
||||
/* 0f 3f 0a 00: memory size in KB */
|
||||
EAX = mem_size;
|
||||
} else if ((b1 == 0x11) && (b2 == 0x00)) {
|
||||
/* 0f 3f 11 00: unknown, set EAX to 0 */
|
||||
EAX = 0x00000000;
|
||||
} else if ((b1 == 0x11) && (b2 == 0x01)) {
|
||||
/* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */
|
||||
EAX = 0x00000000;
|
||||
cpu_state.flags &= ~(Z_FLAG);
|
||||
} else if ((b1 == 0x11) && (b2 == 0x02)) {
|
||||
/* 0f 3f 11 02: unknown, no-op */
|
||||
} else {
|
||||
/* other unknown opcodes: illegal instruction */
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
default:
|
||||
EDX = 0x00000000;
|
||||
if (EAX > 0x00000012) /* unknown EAX values set zero flag */
|
||||
cpu_state.flags &= ~(Z_FLAG);
|
||||
}
|
||||
} else if ((b1 == 0x03) && (b2 == 0x00)) {
|
||||
/* 0f 3f 03 00: host time in BCD */
|
||||
EDX = BCD8(tm->tm_hour);
|
||||
ECX = BCD8(tm->tm_min);
|
||||
EAX = BCD8(tm->tm_sec);
|
||||
} else if ((b1 == 0x03) && (b2 == 0x01)) {
|
||||
/* 0f 3f 03 00: host date in BCD */
|
||||
EDX = BCD8(tm->tm_year % 100);
|
||||
ECX = BCD8(tm->tm_mon + 1);
|
||||
EAX = BCD8(tm->tm_mday);
|
||||
cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */
|
||||
EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7);
|
||||
} else if ((b1 == 0x03) && (b2 == 0x03)) {
|
||||
/* 0f 3f 03 03: host time in binary */
|
||||
EDX = tm->tm_hour;
|
||||
ECX = tm->tm_min;
|
||||
EAX = tm->tm_sec;
|
||||
} else if ((b1 == 0x03) && (b2 == 0x04)) {
|
||||
/* 0f 3f 03 04: host date in binary */
|
||||
EDX = 1900 + tm->tm_year;
|
||||
ECX = tm->tm_mon + 1;
|
||||
EBX = tm->tm_mday;
|
||||
} else if ((b1 == 0x03) && (b2 == 0x05)) {
|
||||
/* 0f 3f 03 05: unknown */
|
||||
EBX = 0x0000000F;
|
||||
ECX = 0x0000000A;
|
||||
} else if ((b1 == 0x03) && (b2 == 0x06)) {
|
||||
/* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */
|
||||
EBX = 0x00000000;
|
||||
ECX = 0x00000000;
|
||||
} else if ((b1 == 0x03) && (b2 >= 0x07)) {
|
||||
/* 0f 3f 03 07+: set zero flag */
|
||||
cpu_state.flags &= ~(Z_FLAG);
|
||||
} else if ((b1 == 0x0a) && (b2 == 0x00)) {
|
||||
/* 0f 3f 0a 00: memory size in KB */
|
||||
EAX = mem_size;
|
||||
} else if ((b1 == 0x11) && (b2 == 0x00)) {
|
||||
/* 0f 3f 11 00: unknown, set EAX to 0 */
|
||||
EAX = 0x00000000;
|
||||
} else if ((b1 == 0x11) && (b2 == 0x01)) {
|
||||
/* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */
|
||||
EAX = 0x00000000;
|
||||
cpu_state.flags &= ~(Z_FLAG);
|
||||
} else if ((b1 == 0x11) && (b2 == 0x02)) {
|
||||
/* 0f 3f 11 02: unknown, no-op */
|
||||
} else {
|
||||
/* other unknown opcodes: illegal instruction */
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
|
||||
pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2);
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2);
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int op0F_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op0F_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode](fetchdat >> 8);
|
||||
return x86_opcodes_0f[opcode](fetchdat >> 8);
|
||||
}
|
||||
static int op0F_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op0F_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8);
|
||||
return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8);
|
||||
}
|
||||
static int op0F_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op0F_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8);
|
||||
return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8);
|
||||
}
|
||||
static int op0F_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op0F_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
int opcode = fetchdat & 0xff;
|
||||
fopcode = opcode;
|
||||
cpu_state.pc++;
|
||||
|
||||
PREFETCH_PREFIX();
|
||||
PREFETCH_PREFIX();
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
|
||||
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
|
||||
}
|
||||
|
||||
const OpFn OP_TABLE(186_0f)[1024] =
|
||||
|
||||
199
src/cpu/8080.c
199
src/cpu/8080.c
@@ -13,7 +13,6 @@
|
||||
* Copyright 2022 Cacodemon345
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "cpu.h"
|
||||
@@ -38,15 +37,14 @@ clock_start(void)
|
||||
cycdiff = cycles;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clock_end(void)
|
||||
{
|
||||
int diff = cycdiff - cycles;
|
||||
|
||||
/* On 808x systems, clock speed is usually crystal frequency divided by an integer. */
|
||||
tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
tsc += (uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process();
|
||||
}
|
||||
|
||||
@@ -73,7 +71,7 @@ readmemb(uint32_t a)
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
ins_fetch(i8080* cpu)
|
||||
ins_fetch(i8080 *cpu)
|
||||
{
|
||||
uint8_t ret = cpu->readmembyte(cpu->pmembase + cpu->pc);
|
||||
|
||||
@@ -83,22 +81,22 @@ ins_fetch(i8080* cpu)
|
||||
#endif
|
||||
|
||||
void
|
||||
transfer_from_808x(i8080* cpu)
|
||||
transfer_from_808x(i8080 *cpu)
|
||||
{
|
||||
cpu->hl = BX;
|
||||
cpu->bc = CX;
|
||||
cpu->de = DX;
|
||||
cpu->a = AL;
|
||||
cpu->flags = cpu_state.flags & 0xFF;
|
||||
cpu->sp = BP;
|
||||
cpu->pc = cpu_state.pc;
|
||||
cpu->oldpc = cpu_state.oldpc;
|
||||
cpu->hl = BX;
|
||||
cpu->bc = CX;
|
||||
cpu->de = DX;
|
||||
cpu->a = AL;
|
||||
cpu->flags = cpu_state.flags & 0xFF;
|
||||
cpu->sp = BP;
|
||||
cpu->pc = cpu_state.pc;
|
||||
cpu->oldpc = cpu_state.oldpc;
|
||||
cpu->pmembase = cs;
|
||||
cpu->dmembase = ds;
|
||||
}
|
||||
|
||||
void
|
||||
transfer_to_808x(i8080* cpu)
|
||||
transfer_to_808x(i8080 *cpu)
|
||||
{
|
||||
BX = cpu->hl;
|
||||
CX = cpu->bc;
|
||||
@@ -106,7 +104,7 @@ transfer_to_808x(i8080* cpu)
|
||||
AL = cpu->a;
|
||||
cpu_state.flags &= 0xFF00;
|
||||
cpu_state.flags |= cpu->flags & 0xFF;
|
||||
BP = cpu->sp;
|
||||
BP = cpu->sp;
|
||||
cpu_state.pc = cpu->pc;
|
||||
}
|
||||
|
||||
@@ -114,16 +112,31 @@ uint8_t
|
||||
getreg_i8080(i8080 *cpu, uint8_t reg)
|
||||
{
|
||||
uint8_t ret = 0xFF;
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: ret = cpu->b; break;
|
||||
case 0x1: ret = cpu->c; break;
|
||||
case 0x2: ret = cpu->d; break;
|
||||
case 0x3: ret = cpu->e; break;
|
||||
case 0x4: ret = cpu->h; break;
|
||||
case 0x5: ret = cpu->l; break;
|
||||
case 0x6: ret = cpu->readmembyte(cpu->dmembase + cpu->sp); break;
|
||||
case 0x7: ret = cpu->a; break;
|
||||
switch (reg) {
|
||||
case 0x0:
|
||||
ret = cpu->b;
|
||||
break;
|
||||
case 0x1:
|
||||
ret = cpu->c;
|
||||
break;
|
||||
case 0x2:
|
||||
ret = cpu->d;
|
||||
break;
|
||||
case 0x3:
|
||||
ret = cpu->e;
|
||||
break;
|
||||
case 0x4:
|
||||
ret = cpu->h;
|
||||
break;
|
||||
case 0x5:
|
||||
ret = cpu->l;
|
||||
break;
|
||||
case 0x6:
|
||||
ret = cpu->readmembyte(cpu->dmembase + cpu->sp);
|
||||
break;
|
||||
case 0x7:
|
||||
ret = cpu->a;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -132,16 +145,31 @@ uint8_t
|
||||
getreg_i8080_emu(i8080 *cpu, uint8_t reg)
|
||||
{
|
||||
uint8_t ret = 0xFF;
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: ret = CH; break;
|
||||
case 0x1: ret = CL; break;
|
||||
case 0x2: ret = DH; break;
|
||||
case 0x3: ret = DL; break;
|
||||
case 0x4: ret = BH; break;
|
||||
case 0x5: ret = BL; break;
|
||||
case 0x6: ret = cpu->readmembyte(cpu->dmembase + BP); break;
|
||||
case 0x7: ret = AL; break;
|
||||
switch (reg) {
|
||||
case 0x0:
|
||||
ret = CH;
|
||||
break;
|
||||
case 0x1:
|
||||
ret = CL;
|
||||
break;
|
||||
case 0x2:
|
||||
ret = DH;
|
||||
break;
|
||||
case 0x3:
|
||||
ret = DL;
|
||||
break;
|
||||
case 0x4:
|
||||
ret = BH;
|
||||
break;
|
||||
case 0x5:
|
||||
ret = BL;
|
||||
break;
|
||||
case 0x6:
|
||||
ret = cpu->readmembyte(cpu->dmembase + BP);
|
||||
break;
|
||||
case 0x7:
|
||||
ret = AL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -149,57 +177,87 @@ getreg_i8080_emu(i8080 *cpu, uint8_t reg)
|
||||
void
|
||||
setreg_i8080_emu(i8080 *cpu, uint8_t reg, uint8_t val)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: CH = val; break;
|
||||
case 0x1: CL = val; break;
|
||||
case 0x2: DH = val; break;
|
||||
case 0x3: DL = val; break;
|
||||
case 0x4: BH = val; break;
|
||||
case 0x5: BL = val; break;
|
||||
case 0x6: cpu->writemembyte(cpu->dmembase + BP, val); break;
|
||||
case 0x7: AL = val; break;
|
||||
switch (reg) {
|
||||
case 0x0:
|
||||
CH = val;
|
||||
break;
|
||||
case 0x1:
|
||||
CL = val;
|
||||
break;
|
||||
case 0x2:
|
||||
DH = val;
|
||||
break;
|
||||
case 0x3:
|
||||
DL = val;
|
||||
break;
|
||||
case 0x4:
|
||||
BH = val;
|
||||
break;
|
||||
case 0x5:
|
||||
BL = val;
|
||||
break;
|
||||
case 0x6:
|
||||
cpu->writemembyte(cpu->dmembase + BP, val);
|
||||
break;
|
||||
case 0x7:
|
||||
AL = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case 0x0: cpu->b = val; break;
|
||||
case 0x1: cpu->c = val; break;
|
||||
case 0x2: cpu->d = val; break;
|
||||
case 0x3: cpu->e = val; break;
|
||||
case 0x4: cpu->h = val; break;
|
||||
case 0x5: cpu->l = val; break;
|
||||
case 0x6: cpu->writemembyte(cpu->dmembase + cpu->sp, val); break;
|
||||
case 0x7: cpu->a = val; break;
|
||||
switch (reg) {
|
||||
case 0x0:
|
||||
cpu->b = val;
|
||||
break;
|
||||
case 0x1:
|
||||
cpu->c = val;
|
||||
break;
|
||||
case 0x2:
|
||||
cpu->d = val;
|
||||
break;
|
||||
case 0x3:
|
||||
cpu->e = val;
|
||||
break;
|
||||
case 0x4:
|
||||
cpu->h = val;
|
||||
break;
|
||||
case 0x5:
|
||||
cpu->l = val;
|
||||
break;
|
||||
case 0x6:
|
||||
cpu->writemembyte(cpu->dmembase + cpu->sp, val);
|
||||
break;
|
||||
case 0x7:
|
||||
cpu->a = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
interpret_exec8080(i8080* cpu, uint8_t opcode)
|
||||
interpret_exec8080(i8080 *cpu, uint8_t opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case 0x00:
|
||||
{
|
||||
break;
|
||||
}
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Actually implement i8080 emulation. */
|
||||
void
|
||||
exec8080(i8080* cpu, int cycs)
|
||||
exec8080(i8080 *cpu, int cycs)
|
||||
{
|
||||
#ifdef UNUSED_8080_VARS
|
||||
uint8_t temp = 0, temp2;
|
||||
uint8_t old_af;
|
||||
uint8_t handled = 0;
|
||||
uint8_t temp = 0, temp2;
|
||||
uint8_t old_af;
|
||||
uint8_t handled = 0;
|
||||
uint16_t addr, tempw;
|
||||
uint16_t new_ip;
|
||||
int bits;
|
||||
int bits;
|
||||
#endif
|
||||
|
||||
cycles += cycs;
|
||||
@@ -209,17 +267,18 @@ exec8080(i8080* cpu, int cycs)
|
||||
|
||||
if (!repeating) {
|
||||
cpu->oldpc = cpu->pc;
|
||||
opcode = cpu->fetchinstruction(cpu);
|
||||
oldc = cpu->flags & C_FLAG_I8080;
|
||||
opcode = cpu->fetchinstruction(cpu);
|
||||
oldc = cpu->flags & C_FLAG_I8080;
|
||||
i8080_wait(1, 0);
|
||||
}
|
||||
completed = 1;
|
||||
if (completed) {
|
||||
repeating = 0;
|
||||
in_rep = 0;
|
||||
repeating = 0;
|
||||
in_rep = 0;
|
||||
rep_c_flag = 0;
|
||||
cpu->endclock();
|
||||
if (cpu->checkinterrupts) cpu->checkinterrupts();
|
||||
if (cpu->checkinterrupts)
|
||||
cpu->checkinterrupts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1085,9 +1085,9 @@ rep_action(int bits)
|
||||
access(71, bits);
|
||||
pfq_clear();
|
||||
if (is_nec && (ovr_seg != NULL))
|
||||
set_ip(cpu_state.pc - 3);
|
||||
set_ip(cpu_state.pc - 3);
|
||||
else
|
||||
set_ip(cpu_state.pc - 2);
|
||||
set_ip(cpu_state.pc - 2);
|
||||
t = 0;
|
||||
}
|
||||
if (t == 0) {
|
||||
@@ -1683,7 +1683,7 @@ execx86(int cycs)
|
||||
// pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode);
|
||||
if (is186) {
|
||||
switch (opcode) {
|
||||
case 0x60: /*PUSHA/PUSH R*/
|
||||
case 0x60: /*PUSHA/PUSH R*/
|
||||
orig_sp = SP;
|
||||
wait(1, 0);
|
||||
push(&AX);
|
||||
@@ -1696,12 +1696,12 @@ execx86(int cycs)
|
||||
push(&DI);
|
||||
handled = 1;
|
||||
break;
|
||||
case 0x61: /*POPA/POP R*/
|
||||
case 0x61: /*POPA/POP R*/
|
||||
wait(9, 0);
|
||||
DI = pop();
|
||||
SI = pop();
|
||||
BP = pop();
|
||||
(void) pop(); /* former orig_sp */
|
||||
DI = pop();
|
||||
SI = pop();
|
||||
BP = pop();
|
||||
(void) pop(); /* former orig_sp */
|
||||
BX = pop();
|
||||
DX = pop();
|
||||
CX = pop();
|
||||
@@ -1710,9 +1710,9 @@ execx86(int cycs)
|
||||
break;
|
||||
|
||||
case 0x62: /* BOUND r/m */
|
||||
lowbound = 0;
|
||||
lowbound = 0;
|
||||
highbound = 0;
|
||||
regval = 0;
|
||||
regval = 0;
|
||||
do_mod_rm();
|
||||
|
||||
lowbound = readmemw(easeg, cpu_state.eaaddr);
|
||||
@@ -1733,7 +1733,7 @@ execx86(int cycs)
|
||||
in_rep = (opcode == 0x64 ? 1 : 2);
|
||||
rep_c_flag = 1;
|
||||
completed = 0;
|
||||
handled = 1;
|
||||
handled = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1746,7 +1746,7 @@ execx86(int cycs)
|
||||
|
||||
case 0x69:
|
||||
immediate = 0;
|
||||
bits = 16;
|
||||
bits = 16;
|
||||
do_mod_rm();
|
||||
read_ea(0, 16);
|
||||
immediate = pfq_fetchw();
|
||||
@@ -1764,7 +1764,7 @@ execx86(int cycs)
|
||||
|
||||
case 0x6b: /* IMUL reg16,reg16/mem16,imm8 */
|
||||
immediate = 0;
|
||||
bits = 16;
|
||||
bits = 16;
|
||||
do_mod_rm();
|
||||
read_ea(0, 16);
|
||||
immediate = pfq_fetchb();
|
||||
@@ -1805,13 +1805,13 @@ execx86(int cycs)
|
||||
case 0x6e:
|
||||
case 0x6f: /* OUTM DW, src/OUTS DX, src */
|
||||
dest_seg = ovr_seg ? *ovr_seg : ds;
|
||||
bits = 8 << (opcode & 1);
|
||||
handled = 1;
|
||||
bits = 8 << (opcode & 1);
|
||||
handled = 1;
|
||||
if (!repeating)
|
||||
wait(2, 0);
|
||||
|
||||
if (rep_action(bits))
|
||||
break;
|
||||
break;
|
||||
else if (!repeating)
|
||||
wait(7, 0);
|
||||
|
||||
@@ -1832,9 +1832,9 @@ execx86(int cycs)
|
||||
|
||||
case 0xc8: /* ENTER/PREPARE */
|
||||
tempw_int = 0;
|
||||
size = pfq_fetchw();
|
||||
nests = pfq_fetchb();
|
||||
i = 0;
|
||||
size = pfq_fetchw();
|
||||
nests = pfq_fetchb();
|
||||
i = 0;
|
||||
|
||||
push(&BP);
|
||||
tempw_int = SP;
|
||||
@@ -1984,7 +1984,7 @@ execx86(int cycs)
|
||||
handled = 1;
|
||||
break;
|
||||
|
||||
case 0x2a: /* ROR4 r/m */
|
||||
case 0x2a: /* ROR4 r/m */
|
||||
do_mod_rm();
|
||||
wait(21, 0);
|
||||
|
||||
@@ -2081,10 +2081,10 @@ execx86(int cycs)
|
||||
odd = !!(CL % 2);
|
||||
zero = 1;
|
||||
nibbles_count = CL - odd;
|
||||
i = 0;
|
||||
carry = 0;
|
||||
nibble = 0;
|
||||
srcseg = ovr_seg ? *ovr_seg : ds;
|
||||
i = 0;
|
||||
carry = 0;
|
||||
nibble = 0;
|
||||
srcseg = ovr_seg ? *ovr_seg : ds;
|
||||
|
||||
wait(5, 0);
|
||||
for (i = 0; i < ((nibbles_count / 2) + odd); i++) {
|
||||
@@ -2116,10 +2116,10 @@ execx86(int cycs)
|
||||
odd = !!(CL % 2);
|
||||
zero = 1;
|
||||
nibbles_count = CL - odd;
|
||||
i = 0;
|
||||
carry = 0;
|
||||
nibble = 0;
|
||||
srcseg = ovr_seg ? *ovr_seg : ds;
|
||||
i = 0;
|
||||
carry = 0;
|
||||
nibble = 0;
|
||||
srcseg = ovr_seg ? *ovr_seg : ds;
|
||||
|
||||
wait(5, 0);
|
||||
for (i = 0; i < ((nibbles_count / 2) + odd); i++) {
|
||||
@@ -2151,10 +2151,10 @@ execx86(int cycs)
|
||||
odd = !!(CL % 2);
|
||||
zero = 1;
|
||||
nibbles_count = CL - odd;
|
||||
i = 0;
|
||||
carry = 0;
|
||||
nibble = 0;
|
||||
srcseg = ovr_seg ? *ovr_seg : ds;
|
||||
i = 0;
|
||||
carry = 0;
|
||||
nibble = 0;
|
||||
srcseg = ovr_seg ? *ovr_seg : ds;
|
||||
|
||||
wait(5, 0);
|
||||
for (i = 0; i < ((nibbles_count / 2) + odd); i++) {
|
||||
@@ -2206,7 +2206,7 @@ execx86(int cycs)
|
||||
}
|
||||
}
|
||||
setr8(cpu_rm, bit_offset);
|
||||
|
||||
|
||||
handled = 1;
|
||||
break;
|
||||
|
||||
@@ -2501,9 +2501,9 @@ execx86(int cycs)
|
||||
wait(1, 0);
|
||||
break;
|
||||
|
||||
case 0x60: /*JO alias*/
|
||||
case 0x70: /*JO*/
|
||||
case 0x61: /*JNO alias*/
|
||||
case 0x60: /*JO alias*/
|
||||
case 0x70: /*JO*/
|
||||
case 0x61: /*JNO alias*/
|
||||
case 0x71: /*JNO*/
|
||||
jcc(opcode, cpu_state.flags & V_FLAG);
|
||||
break;
|
||||
@@ -2525,15 +2525,15 @@ execx86(int cycs)
|
||||
case 0x77: /*JNBE*/
|
||||
jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG));
|
||||
break;
|
||||
case 0x68: /*JS alias*/
|
||||
case 0x78: /*JS*/
|
||||
case 0x69: /*JNS alias*/
|
||||
case 0x68: /*JS alias*/
|
||||
case 0x78: /*JS*/
|
||||
case 0x69: /*JNS alias*/
|
||||
case 0x79: /*JNS*/
|
||||
jcc(opcode, cpu_state.flags & N_FLAG);
|
||||
break;
|
||||
case 0x6A: /*JP alias*/
|
||||
case 0x7A: /*JP*/
|
||||
case 0x6B: /*JNP alias*/
|
||||
case 0x6A: /*JP alias*/
|
||||
case 0x7A: /*JP*/
|
||||
case 0x6B: /*JNP alias*/
|
||||
case 0x7B: /*JNP*/
|
||||
jcc(opcode, cpu_state.flags & P_FLAG);
|
||||
break;
|
||||
|
||||
@@ -36,29 +36,27 @@
|
||||
#define _CODEGEN_PUBLIC_H_
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
#define PAGE_MASK_INDEX_MASK 3
|
||||
#define PAGE_MASK_INDEX_SHIFT 10
|
||||
#define PAGE_MASK_SHIFT 4
|
||||
# define PAGE_MASK_INDEX_MASK 3
|
||||
# define PAGE_MASK_INDEX_SHIFT 10
|
||||
# define PAGE_MASK_SHIFT 4
|
||||
#else
|
||||
#define PAGE_MASK_SHIFT 6
|
||||
# define PAGE_MASK_SHIFT 6
|
||||
#endif
|
||||
#define PAGE_MASK_MASK 63
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#define BLOCK_PC_INVALID 0xffffffff
|
||||
#define BLOCK_INVALID 0
|
||||
# define BLOCK_PC_INVALID 0xffffffff
|
||||
# define BLOCK_INVALID 0
|
||||
#endif
|
||||
|
||||
|
||||
extern void codegen_init(void);
|
||||
extern void codegen_init(void);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
extern void codegen_close(void);
|
||||
extern void codegen_close(void);
|
||||
#endif
|
||||
extern void codegen_flush(void);
|
||||
|
||||
extern void codegen_flush(void);
|
||||
|
||||
/*Current physical page of block being recompiled. -1 if no recompilation taking place */
|
||||
extern uint32_t recomp_page;
|
||||
extern int codegen_in_recompile;
|
||||
extern uint32_t recomp_page;
|
||||
extern int codegen_in_recompile;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
/*Instruction has input dependency on register in REG field*/
|
||||
#define SRCDEP_REG (1ull << 0)
|
||||
/*Instruction has input dependency on register in R/M field*/
|
||||
#define SRCDEP_RM (1ull << 1)
|
||||
#define SRCDEP_RM (1ull << 1)
|
||||
/*Instruction modifies register in REG field*/
|
||||
#define DSTDEP_REG (1ull << 2)
|
||||
/*Instruction modifies register in R/M field*/
|
||||
#define DSTDEP_RM (1ull << 3)
|
||||
#define DSTDEP_RM (1ull << 3)
|
||||
|
||||
#define SRCDEP_SHIFT 4
|
||||
#define DSTDEP_SHIFT 12
|
||||
@@ -40,48 +40,45 @@
|
||||
/*Instruction is MMX shift or pack/unpack instruction*/
|
||||
#define MMX_SHIFTPACK (1ull << 22)
|
||||
/*Instruction is MMX multiply instruction*/
|
||||
#define MMX_MULTIPLY (1ull << 23)
|
||||
#define MMX_MULTIPLY (1ull << 23)
|
||||
|
||||
/*Instruction pops the FPU stack*/
|
||||
#define FPU_POP (1ull << 24)
|
||||
#define FPU_POP (1ull << 24)
|
||||
/*Instruction pops the FPU stack twice*/
|
||||
#define FPU_POP2 (1ull << 25)
|
||||
#define FPU_POP2 (1ull << 25)
|
||||
/*Instruction pushes onto the FPU stack*/
|
||||
#define FPU_PUSH (1ull << 26)
|
||||
#define FPU_PUSH (1ull << 26)
|
||||
|
||||
/*Instruction writes to ST(0)*/
|
||||
#define FPU_WRITE_ST0 (1ull << 27)
|
||||
#define FPU_WRITE_ST0 (1ull << 27)
|
||||
/*Instruction reads from ST(0)*/
|
||||
#define FPU_READ_ST0 (1ull << 28)
|
||||
#define FPU_READ_ST0 (1ull << 28)
|
||||
/*Instruction reads from and writes to ST(0)*/
|
||||
#define FPU_RW_ST0 (3ull << 27)
|
||||
#define FPU_RW_ST0 (3ull << 27)
|
||||
|
||||
/*Instruction reads from ST(1)*/
|
||||
#define FPU_READ_ST1 (1ull << 29)
|
||||
#define FPU_READ_ST1 (1ull << 29)
|
||||
/*Instruction writes to ST(1)*/
|
||||
#define FPU_WRITE_ST1 (1ull << 30)
|
||||
#define FPU_WRITE_ST1 (1ull << 30)
|
||||
/*Instruction reads from and writes to ST(1)*/
|
||||
#define FPU_RW_ST1 (3ull << 29)
|
||||
#define FPU_RW_ST1 (3ull << 29)
|
||||
|
||||
/*Instruction reads from ST(reg)*/
|
||||
#define FPU_READ_STREG (1ull << 31)
|
||||
#define FPU_READ_STREG (1ull << 31)
|
||||
/*Instruction writes to ST(reg)*/
|
||||
#define FPU_WRITE_STREG (1ull << 32)
|
||||
/*Instruction reads from and writes to ST(reg)*/
|
||||
#define FPU_RW_STREG (3ull << 31)
|
||||
#define FPU_RW_STREG (3ull << 31)
|
||||
|
||||
#define FPU_FXCH (1ull << 33)
|
||||
#define FPU_FXCH (1ull << 33)
|
||||
|
||||
#define HAS_IMM8 (1ull << 34)
|
||||
#define HAS_IMM1632 (1ull << 35)
|
||||
|
||||
#define HAS_IMM8 (1ull << 34)
|
||||
#define HAS_IMM1632 (1ull << 35)
|
||||
|
||||
|
||||
#define REGMASK_IMPL_ESP (1 << 8)
|
||||
#define REGMASK_IMPL_ESP (1 << 8)
|
||||
#define REGMASK_SHIFTPACK (1 << 9)
|
||||
#define REGMASK_MULTIPLY (1 << 9)
|
||||
|
||||
|
||||
extern uint64_t opcode_deps[256];
|
||||
extern uint64_t opcode_deps_mod3[256];
|
||||
extern uint64_t opcode_deps_0f[256];
|
||||
@@ -119,114 +116,116 @@ extern uint64_t opcode_deps_81_mod3[8];
|
||||
extern uint64_t opcode_deps_8x[8];
|
||||
extern uint64_t opcode_deps_8x_mod3[8];
|
||||
|
||||
|
||||
|
||||
static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32)
|
||||
static inline uint32_t
|
||||
get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
uint32_t addr_regmask = 0;
|
||||
uint32_t addr_regmask = 0;
|
||||
|
||||
if (data & MODRM)
|
||||
{
|
||||
uint8_t modrm = fetchdat & 0xff;
|
||||
if (data & MODRM) {
|
||||
uint8_t modrm = fetchdat & 0xff;
|
||||
|
||||
if ((modrm & 0xc0) != 0xc0)
|
||||
{
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
if ((modrm & 0x7) == 4)
|
||||
{
|
||||
uint8_t sib = (fetchdat >> 8) & 0xff;
|
||||
if ((modrm & 0xc0) != 0xc0) {
|
||||
if (op_32 & 0x200) {
|
||||
if ((modrm & 0x7) == 4) {
|
||||
uint8_t sib = (fetchdat >> 8) & 0xff;
|
||||
|
||||
if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5)
|
||||
{
|
||||
addr_regmask = 1 << (sib & 7);
|
||||
if ((sib & 0x38) != 0x20)
|
||||
addr_regmask |= 1 << ((sib >> 3) & 7);
|
||||
}
|
||||
}
|
||||
else if ((modrm & 0xc7) != 5)
|
||||
{
|
||||
addr_regmask = 1 << (modrm & 7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) != 0x06)
|
||||
{
|
||||
switch (modrm & 7)
|
||||
{
|
||||
case 0: addr_regmask = REG_BX | REG_SI; break;
|
||||
case 1: addr_regmask = REG_BX | REG_DI; break;
|
||||
case 2: addr_regmask = REG_BP | REG_SI; break;
|
||||
case 3: addr_regmask = REG_BP | REG_DI; break;
|
||||
case 4: addr_regmask = REG_SI; break;
|
||||
case 5: addr_regmask = REG_DI; break;
|
||||
case 6: addr_regmask = REG_BP; break;
|
||||
case 7: addr_regmask = REG_BX; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) {
|
||||
addr_regmask = 1 << (sib & 7);
|
||||
if ((sib & 0x38) != 0x20)
|
||||
addr_regmask |= 1 << ((sib >> 3) & 7);
|
||||
}
|
||||
} else if ((modrm & 0xc7) != 5) {
|
||||
addr_regmask = 1 << (modrm & 7);
|
||||
}
|
||||
} else {
|
||||
if ((modrm & 0xc7) != 0x06) {
|
||||
switch (modrm & 7) {
|
||||
case 0:
|
||||
addr_regmask = REG_BX | REG_SI;
|
||||
break;
|
||||
case 1:
|
||||
addr_regmask = REG_BX | REG_DI;
|
||||
break;
|
||||
case 2:
|
||||
addr_regmask = REG_BP | REG_SI;
|
||||
break;
|
||||
case 3:
|
||||
addr_regmask = REG_BP | REG_DI;
|
||||
break;
|
||||
case 4:
|
||||
addr_regmask = REG_SI;
|
||||
break;
|
||||
case 5:
|
||||
addr_regmask = REG_DI;
|
||||
break;
|
||||
case 6:
|
||||
addr_regmask = REG_BP;
|
||||
break;
|
||||
case 7:
|
||||
addr_regmask = REG_BX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data & IMPL_ESP)
|
||||
addr_regmask |= REGMASK_IMPL_ESP;
|
||||
if (data & IMPL_ESP)
|
||||
addr_regmask |= REGMASK_IMPL_ESP;
|
||||
|
||||
return addr_regmask;
|
||||
return addr_regmask;
|
||||
}
|
||||
|
||||
static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32)
|
||||
static inline uint32_t
|
||||
get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & SRCDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & SRCDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> SRCDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
uint32_t mask = 0;
|
||||
if (data & SRCDEP_REG) {
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & SRCDEP_RM) {
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> SRCDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
|
||||
mask |= get_addr_regmask(data, fetchdat, op_32);
|
||||
mask |= get_addr_regmask(data, fetchdat, op_32);
|
||||
|
||||
return mask;
|
||||
return mask;
|
||||
}
|
||||
|
||||
static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8)
|
||||
static inline uint32_t
|
||||
get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & DSTDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & DSTDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> DSTDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
if (data & IMPL_ESP)
|
||||
mask |= REGMASK_IMPL_ESP | (1 << REG_ESP);
|
||||
uint32_t mask = 0;
|
||||
if (data & DSTDEP_REG) {
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & DSTDEP_RM) {
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> DSTDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
if (data & IMPL_ESP)
|
||||
mask |= REGMASK_IMPL_ESP | (1 << REG_ESP);
|
||||
|
||||
return mask;
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -1169,7 +1169,7 @@ cpu_set(void)
|
||||
#endif
|
||||
|
||||
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) {
|
||||
x86_opcodes_3DNOW = ops_3DNOWE;
|
||||
x86_opcodes_3DNOW = ops_3DNOWE;
|
||||
x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ enum {
|
||||
enum {
|
||||
CPU_8088 = 1, /* 808x class CPUs */
|
||||
CPU_8086,
|
||||
CPU_V20, /* NEC 808x class CPUs */
|
||||
CPU_V20, /* NEC 808x class CPUs */
|
||||
CPU_V30,
|
||||
CPU_188, /* 18x class CPUs */
|
||||
CPU_188, /* 18x class CPUs */
|
||||
CPU_186,
|
||||
CPU_286, /* 286 class CPUs */
|
||||
CPU_386SX, /* 386 class CPUs */
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
|
||||
|
||||
#ifdef ENABLE_FPU_LOG
|
||||
int fpu_do_log = ENABLE_FPU_LOG;
|
||||
|
||||
|
||||
void
|
||||
fpu_log(const char *fmt, ...)
|
||||
{
|
||||
@@ -42,17 +40,16 @@ fpu_log(const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define fpu_log(fmt, ...)
|
||||
# define fpu_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name)
|
||||
{
|
||||
const CPU *cpu_s = &cpu_family->cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
int fpu_type = fpus[0].type;
|
||||
int c = 0;
|
||||
const CPU *cpu_s = &cpu_family->cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
int fpu_type = fpus[0].type;
|
||||
int c = 0;
|
||||
|
||||
while (fpus[c].internal_name) {
|
||||
if (!strcmp(internal_name, fpus[c].internal_name))
|
||||
@@ -63,13 +60,12 @@ fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name)
|
||||
return fpu_type;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type)
|
||||
{
|
||||
const CPU *cpu_s = &cpu_family->cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
int c = 0;
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
int c = 0;
|
||||
|
||||
while (fpus[c].internal_name) {
|
||||
if (fpus[c].type == type)
|
||||
@@ -80,22 +76,20 @@ fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type)
|
||||
return fpus[0].internal_name;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c)
|
||||
{
|
||||
const CPU *cpu_s = &cpu_family->cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
|
||||
return fpus[c].name;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c)
|
||||
{
|
||||
const CPU *cpu_s = &cpu_family->cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
|
||||
return fpus[c].type;
|
||||
}
|
||||
|
||||
249
src/cpu/x86.c
249
src/cpu/x86.c
@@ -43,7 +43,7 @@
|
||||
uint8_t opcode;
|
||||
|
||||
/* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */
|
||||
uint8_t znptable8[256];
|
||||
uint8_t znptable8[256];
|
||||
uint16_t znptable16[65536];
|
||||
|
||||
/* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */
|
||||
@@ -52,7 +52,7 @@ uint16_t zero = 0;
|
||||
/* MOD and R/M stuff. */
|
||||
uint16_t *mod1add[2][8];
|
||||
uint32_t *mod1seg[8];
|
||||
uint32_t rmdat;
|
||||
uint32_t rmdat;
|
||||
|
||||
/* XT CPU multiplier. */
|
||||
uint64_t xt_cpu_multi;
|
||||
@@ -72,13 +72,11 @@ uint32_t easeg;
|
||||
/* This is for the OPTI 283 special reset handling mode. */
|
||||
int reset_on_hlt, hlt_reset_pending;
|
||||
|
||||
|
||||
#ifdef ENABLE_X86_LOG
|
||||
void dumpregs(int);
|
||||
void dumpregs(int);
|
||||
|
||||
int x86_do_log = ENABLE_X86_LOG;
|
||||
int indump = 0;
|
||||
|
||||
int indump = 0;
|
||||
|
||||
static void
|
||||
x808x_log(const char *fmt, ...)
|
||||
@@ -86,60 +84,58 @@ x808x_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (x808x_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dumpregs(int force)
|
||||
{
|
||||
int c;
|
||||
int c;
|
||||
char *seg_names[4] = { "ES", "CS", "SS", "DS" };
|
||||
|
||||
/* Only dump when needed, and only once.. */
|
||||
if (indump || (!force && !dump_on_exit))
|
||||
return;
|
||||
return;
|
||||
|
||||
x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",
|
||||
cpu_state.pc, CS, DS, ES, SS, cpu_state.flags);
|
||||
cpu_state.pc, CS, DS, ES, SS, cpu_state.flags);
|
||||
x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins);
|
||||
for (c = 0; c < 4; c++) {
|
||||
x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
||||
seg_names[c], _opseg[c]->base, _opseg[c]->limit,
|
||||
_opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high);
|
||||
x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
||||
seg_names[c], _opseg[c]->base, _opseg[c]->limit,
|
||||
_opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high);
|
||||
}
|
||||
if (is386) {
|
||||
x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
||||
seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high);
|
||||
x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
||||
gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high);
|
||||
x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit);
|
||||
x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit);
|
||||
x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit);
|
||||
x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
|
||||
x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n",
|
||||
(msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real",
|
||||
(use32) ? 32 : 16, (stack32) ? 32 : 16);
|
||||
x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4);
|
||||
x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",
|
||||
EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP);
|
||||
x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
||||
seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high);
|
||||
x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",
|
||||
gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high);
|
||||
x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit);
|
||||
x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit);
|
||||
x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit);
|
||||
x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
|
||||
x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n",
|
||||
(msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real",
|
||||
(use32) ? 32 : 16, (stack32) ? 32 : 16);
|
||||
x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4);
|
||||
x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",
|
||||
EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP);
|
||||
} else {
|
||||
x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real");
|
||||
x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",
|
||||
AX, BX, CX, DX, DI, SI, BP, SP);
|
||||
x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real");
|
||||
x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",
|
||||
AX, BX, CX, DX, DI, SI, BP, SP);
|
||||
}
|
||||
x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum);
|
||||
x87_dumpregs();
|
||||
indump = 0;
|
||||
}
|
||||
#else
|
||||
#define x808x_log(fmt, ...)
|
||||
# define x808x_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Preparation of the various arrays needed to speed up the MOD and R/M work. */
|
||||
static void
|
||||
makemod1table(void)
|
||||
@@ -160,143 +156,141 @@ makemod1table(void)
|
||||
mod1add[1][5] = &zero;
|
||||
mod1add[1][6] = &zero;
|
||||
mod1add[1][7] = &zero;
|
||||
mod1seg[0] = &ds;
|
||||
mod1seg[1] = &ds;
|
||||
mod1seg[2] = &ss;
|
||||
mod1seg[3] = &ss;
|
||||
mod1seg[4] = &ds;
|
||||
mod1seg[5] = &ds;
|
||||
mod1seg[6] = &ss;
|
||||
mod1seg[7] = &ds;
|
||||
mod1seg[0] = &ds;
|
||||
mod1seg[1] = &ds;
|
||||
mod1seg[2] = &ss;
|
||||
mod1seg[3] = &ss;
|
||||
mod1seg[4] = &ds;
|
||||
mod1seg[5] = &ds;
|
||||
mod1seg[6] = &ss;
|
||||
mod1seg[7] = &ds;
|
||||
}
|
||||
|
||||
|
||||
/* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */
|
||||
static void
|
||||
makeznptable(void)
|
||||
{
|
||||
int c, d, e;
|
||||
for (c = 0; c < 256; c++) {
|
||||
d = 0;
|
||||
for (e = 0; e < 8; e++) {
|
||||
if (c & (1 << e))
|
||||
d++;
|
||||
}
|
||||
if (d & 1)
|
||||
znptable8[c] = 0;
|
||||
else
|
||||
znptable8[c] = P_FLAG;
|
||||
d = 0;
|
||||
for (e = 0; e < 8; e++) {
|
||||
if (c & (1 << e))
|
||||
d++;
|
||||
}
|
||||
if (d & 1)
|
||||
znptable8[c] = 0;
|
||||
else
|
||||
znptable8[c] = P_FLAG;
|
||||
#ifdef ENABLE_808X_LOG
|
||||
if (c == 0xb1)
|
||||
x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]);
|
||||
if (c == 0xb1)
|
||||
x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]);
|
||||
#endif
|
||||
if (!c)
|
||||
znptable8[c] |= Z_FLAG;
|
||||
if (c & 0x80)
|
||||
znptable8[c] |= N_FLAG;
|
||||
if (!c)
|
||||
znptable8[c] |= Z_FLAG;
|
||||
if (c & 0x80)
|
||||
znptable8[c] |= N_FLAG;
|
||||
}
|
||||
|
||||
for (c = 0; c < 65536; c++) {
|
||||
d = 0;
|
||||
for (e = 0; e < 8; e++) {
|
||||
if (c & (1 << e))
|
||||
d++;
|
||||
}
|
||||
if (d & 1)
|
||||
znptable16[c] = 0;
|
||||
else
|
||||
znptable16[c] = P_FLAG;
|
||||
d = 0;
|
||||
for (e = 0; e < 8; e++) {
|
||||
if (c & (1 << e))
|
||||
d++;
|
||||
}
|
||||
if (d & 1)
|
||||
znptable16[c] = 0;
|
||||
else
|
||||
znptable16[c] = P_FLAG;
|
||||
#ifdef ENABLE_808X_LOG
|
||||
if (c == 0xb1)
|
||||
x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]);
|
||||
if (c == 0x65b1)
|
||||
x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]);
|
||||
if (c == 0xb1)
|
||||
x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]);
|
||||
if (c == 0x65b1)
|
||||
x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]);
|
||||
#endif
|
||||
if (!c)
|
||||
znptable16[c] |= Z_FLAG;
|
||||
if (c & 0x8000)
|
||||
znptable16[c] |= N_FLAG;
|
||||
if (!c)
|
||||
znptable16[c] |= Z_FLAG;
|
||||
if (c & 0x8000)
|
||||
znptable16[c] |= N_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Common reset function. */
|
||||
static void
|
||||
reset_common(int hard)
|
||||
{
|
||||
#ifdef ENABLE_808X_LOG
|
||||
if (hard)
|
||||
x808x_log("x86 reset\n");
|
||||
x808x_log("x86 reset\n");
|
||||
#endif
|
||||
|
||||
if (!hard && reset_on_hlt) {
|
||||
hlt_reset_pending++;
|
||||
pclog("hlt_reset_pending = %i\n", hlt_reset_pending);
|
||||
if (hlt_reset_pending == 2)
|
||||
hlt_reset_pending = 0;
|
||||
else
|
||||
return;
|
||||
hlt_reset_pending++;
|
||||
pclog("hlt_reset_pending = %i\n", hlt_reset_pending);
|
||||
if (hlt_reset_pending == 2)
|
||||
hlt_reset_pending = 0;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure to gracefully leave SMM. */
|
||||
if (in_smm)
|
||||
leave_smm();
|
||||
leave_smm();
|
||||
|
||||
/* Needed for the ALi M1533. */
|
||||
if (is486 && (hard || soft_reset_pci)) {
|
||||
pci_reset();
|
||||
if (!hard && soft_reset_pci) {
|
||||
dma_reset();
|
||||
/* TODO: Hack, but will do for time being, because all AT machines currently are 286+,
|
||||
and vice-versa. */
|
||||
dma_set_at(is286);
|
||||
device_reset_all();
|
||||
}
|
||||
pci_reset();
|
||||
if (!hard && soft_reset_pci) {
|
||||
dma_reset();
|
||||
/* TODO: Hack, but will do for time being, because all AT machines currently are 286+,
|
||||
and vice-versa. */
|
||||
dma_set_at(is286);
|
||||
device_reset_all();
|
||||
}
|
||||
}
|
||||
|
||||
use32 = 0;
|
||||
use32 = 0;
|
||||
cpu_cur_status = 0;
|
||||
stack32 = 0;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
msw = 0;
|
||||
stack32 = 0;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
msw = 0;
|
||||
if (hascache)
|
||||
cr0 = 1 << 30;
|
||||
cr0 = 1 << 30;
|
||||
else
|
||||
cr0 = 0;
|
||||
cr0 = 0;
|
||||
cpu_cache_int_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
cr4 = 0;
|
||||
cr4 = 0;
|
||||
cpu_state.eflags = 0;
|
||||
cgate32 = 0;
|
||||
cgate32 = 0;
|
||||
if (is286) {
|
||||
loadcs(0xF000);
|
||||
cpu_state.pc = 0xFFF0;
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
loadcs(0xF000);
|
||||
cpu_state.pc = 0xFFF0;
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
if (is6117)
|
||||
rammask |= 0x03000000;
|
||||
}
|
||||
idt.base = 0;
|
||||
idt.base = 0;
|
||||
cpu_state.flags = 2;
|
||||
trap = 0;
|
||||
trap = 0;
|
||||
|
||||
idt.limit = is386 ? 0x03ff : 0xffff;
|
||||
if (is386 || hard)
|
||||
EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0;
|
||||
EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0;
|
||||
|
||||
if (hard) {
|
||||
makeznptable();
|
||||
resetreadlookup();
|
||||
makemod1table();
|
||||
cpu_set_edx();
|
||||
mmu_perm = 4;
|
||||
makeznptable();
|
||||
resetreadlookup();
|
||||
makemod1table();
|
||||
cpu_set_edx();
|
||||
mmu_perm = 4;
|
||||
}
|
||||
x86seg_reset();
|
||||
#ifdef USE_DYNAREC
|
||||
if (hard)
|
||||
codegen_reset();
|
||||
codegen_reset();
|
||||
#endif
|
||||
if (!hard)
|
||||
flushmmucache();
|
||||
flushmmucache();
|
||||
x86_was_reset = 1;
|
||||
cpu_alt_reset = 0;
|
||||
|
||||
@@ -304,12 +298,12 @@ reset_common(int hard)
|
||||
|
||||
in_smm = smi_latched = 0;
|
||||
smi_line = smm_in_hlt = 0;
|
||||
smi_block = 0;
|
||||
smi_block = 0;
|
||||
|
||||
if (hard) {
|
||||
if (is486)
|
||||
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
|
||||
ppi_reset();
|
||||
if (is486)
|
||||
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
|
||||
ppi_reset();
|
||||
}
|
||||
in_sys = 0;
|
||||
|
||||
@@ -317,17 +311,16 @@ reset_common(int hard)
|
||||
alt_access = cpu_end_block_after_ins = 0;
|
||||
|
||||
if (hard) {
|
||||
reset_on_hlt = hlt_reset_pending = 0;
|
||||
cache_index = 0;
|
||||
memset(_tr, 0x00, sizeof(_tr));
|
||||
memset(_cache, 0x00, sizeof(_cache));
|
||||
reset_on_hlt = hlt_reset_pending = 0;
|
||||
cache_index = 0;
|
||||
memset(_tr, 0x00, sizeof(_tr));
|
||||
memset(_cache, 0x00, sizeof(_cache));
|
||||
}
|
||||
|
||||
if (!is286)
|
||||
reset_808x(hard);
|
||||
reset_808x(hard);
|
||||
}
|
||||
|
||||
|
||||
/* Hard reset. */
|
||||
void
|
||||
resetx86(void)
|
||||
@@ -337,13 +330,12 @@ resetx86(void)
|
||||
soft_reset_mask = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Soft reset. */
|
||||
void
|
||||
softresetx86(void)
|
||||
{
|
||||
if (soft_reset_mask)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (ibm8514_enabled || xga_enabled)
|
||||
vga_on = 1;
|
||||
@@ -351,7 +343,6 @@ softresetx86(void)
|
||||
reset_common(0);
|
||||
}
|
||||
|
||||
|
||||
/* Actual hard reset. */
|
||||
void
|
||||
hardresetx86(void)
|
||||
|
||||
113
src/cpu/x86.h
113
src/cpu/x86.h
@@ -7,77 +7,78 @@
|
||||
This distinction is used by the dynarec; a block that hits an 'expected' exception
|
||||
would be compiled, a block that hits an 'unexpected' exception would be rejected so
|
||||
that we don't end up with an unnecessarily short block*/
|
||||
#define ABRT_EXPECTED 0x80
|
||||
#define ABRT_EXPECTED 0x80
|
||||
|
||||
extern uint8_t opcode, opcode2;
|
||||
extern uint8_t flags_p;
|
||||
extern uint8_t znptable8[256];
|
||||
extern uint8_t opcode, opcode2;
|
||||
extern uint8_t flags_p;
|
||||
extern uint8_t znptable8[256];
|
||||
|
||||
extern uint16_t zero, oldcs;
|
||||
extern uint16_t lastcs, lastpc;
|
||||
extern uint16_t zero, oldcs;
|
||||
extern uint16_t lastcs, lastpc;
|
||||
extern uint16_t *mod1add[2][8];
|
||||
extern uint16_t znptable16[65536];
|
||||
extern uint16_t znptable16[65536];
|
||||
|
||||
extern int x86_was_reset, trap;
|
||||
extern int codegen_flat_ss, codegen_flat_ds;
|
||||
extern int timetolive, keyboardtimer, trap;
|
||||
extern int optype, stack32;
|
||||
extern int oldcpl, cgate32, cpl_override;
|
||||
extern int nmi_enable;
|
||||
extern int oddeven, inttype;
|
||||
extern int x86_was_reset, trap;
|
||||
extern int codegen_flat_ss, codegen_flat_ds;
|
||||
extern int timetolive, keyboardtimer, trap;
|
||||
extern int optype, stack32;
|
||||
extern int oldcpl, cgate32, cpl_override;
|
||||
extern int nmi_enable;
|
||||
extern int oddeven, inttype;
|
||||
|
||||
extern uint32_t use32;
|
||||
extern uint32_t rmdat, easeg;
|
||||
extern uint32_t oxpc, flags_zn;
|
||||
extern uint32_t abrt_error;
|
||||
extern uint32_t backupregs[16];
|
||||
extern uint32_t use32;
|
||||
extern uint32_t rmdat, easeg;
|
||||
extern uint32_t oxpc, flags_zn;
|
||||
extern uint32_t abrt_error;
|
||||
extern uint32_t backupregs[16];
|
||||
extern uint32_t *mod1seg[8];
|
||||
extern uint32_t *eal_r, *eal_w;
|
||||
|
||||
#define fetchdat rmdat
|
||||
#define fetchdat rmdat
|
||||
|
||||
#define setznp168 setznp16
|
||||
|
||||
#define getr8(r) ((r&4)?cpu_state.regs[r&3].b.h:cpu_state.regs[r&3].b.l)
|
||||
#define getr16(r) cpu_state.regs[r].w
|
||||
#define getr32(r) cpu_state.regs[r].l
|
||||
#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l)
|
||||
#define getr16(r) cpu_state.regs[r].w
|
||||
#define getr32(r) cpu_state.regs[r].l
|
||||
|
||||
#define setr8(r,v) if (r&4) cpu_state.regs[r&3].b.h=v; \
|
||||
else cpu_state.regs[r&3].b.l=v;
|
||||
#define setr16(r,v) cpu_state.regs[r].w=v
|
||||
#define setr32(r,v) cpu_state.regs[r].l=v
|
||||
#define setr8(r, v) \
|
||||
if (r & 4) \
|
||||
cpu_state.regs[r & 3].b.h = v; \
|
||||
else \
|
||||
cpu_state.regs[r & 3].b.l = v;
|
||||
#define setr16(r, v) cpu_state.regs[r].w = v
|
||||
#define setr32(r, v) cpu_state.regs[r].l = v
|
||||
|
||||
#define fetchea() { \
|
||||
rmdat = readmemb(cs + pc); \
|
||||
pc++; \
|
||||
reg = (rmdat >> 3) & 7; \
|
||||
mod = (rmdat >> 6) & 3; \
|
||||
rm = rmdat & 7; \
|
||||
if (mod!=3) \
|
||||
fetcheal(); \
|
||||
}
|
||||
#define fetchea() \
|
||||
{ \
|
||||
rmdat = readmemb(cs + pc); \
|
||||
pc++; \
|
||||
reg = (rmdat >> 3) & 7; \
|
||||
mod = (rmdat >> 6) & 3; \
|
||||
rm = rmdat & 7; \
|
||||
if (mod != 3) \
|
||||
fetcheal(); \
|
||||
}
|
||||
|
||||
#define JMP 1
|
||||
#define CALL 2
|
||||
#define IRET 3
|
||||
#define JMP 1
|
||||
#define CALL 2
|
||||
#define IRET 3
|
||||
#define OPTYPE_INT 4
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
ABRT_NONE = 0,
|
||||
ABRT_GEN,
|
||||
ABRT_TS = 0xA,
|
||||
ABRT_NP = 0xB,
|
||||
ABRT_SS = 0xC,
|
||||
ABRT_GPF = 0xD,
|
||||
ABRT_PF = 0xE,
|
||||
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
|
||||
enum {
|
||||
ABRT_NONE = 0,
|
||||
ABRT_GEN,
|
||||
ABRT_TS = 0xA,
|
||||
ABRT_NP = 0xB,
|
||||
ABRT_SS = 0xC,
|
||||
ABRT_GPF = 0xD,
|
||||
ABRT_PF = 0xE,
|
||||
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
|
||||
};
|
||||
|
||||
|
||||
extern void x86_doabrt(int x86_abrt);
|
||||
extern void x86illegal(void);
|
||||
extern void x86seg_reset(void);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
extern void x86gpf_expected(char *s, uint16_t error);
|
||||
extern void x86_doabrt(int x86_abrt);
|
||||
extern void x86illegal(void);
|
||||
extern void x86seg_reset(void);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
extern void x86gpf_expected(char *s, uint16_t error);
|
||||
|
||||
1166
src/cpu/x86_flags.h
1166
src/cpu/x86_flags.h
File diff suppressed because it is too large
Load Diff
@@ -39,16 +39,14 @@
|
||||
#ifndef _X86_OPS_H
|
||||
#define _X86_OPS_H
|
||||
|
||||
|
||||
#define UN_USED(x) (void)(x)
|
||||
|
||||
#define UN_USED(x) (void) (x)
|
||||
|
||||
typedef int (*OpFn)(uint32_t fetchdat);
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
|
||||
const OpFn *dynarec_opcodes,
|
||||
const OpFn *dynarec_opcodes_0f);
|
||||
const OpFn *dynarec_opcodes,
|
||||
const OpFn *dynarec_opcodes_0f);
|
||||
|
||||
extern const OpFn *x86_dynarec_opcodes;
|
||||
extern const OpFn *x86_dynarec_opcodes_0f;
|
||||
@@ -92,10 +90,10 @@ extern const OpFn dynarec_ops_winchip2_0f[1024];
|
||||
extern const OpFn dynarec_ops_pentium_0f[1024];
|
||||
extern const OpFn dynarec_ops_pentiummmx_0f[1024];
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
extern const OpFn dynarec_ops_c6x86_0f[1024];
|
||||
extern const OpFn dynarec_ops_c6x86mx_0f[1024];
|
||||
#endif
|
||||
# endif
|
||||
|
||||
extern const OpFn dynarec_ops_k6_0f[1024];
|
||||
extern const OpFn dynarec_ops_k62_0f[1024];
|
||||
@@ -253,9 +251,9 @@ extern const OpFn ops_REPNE[1024];
|
||||
extern const OpFn ops_3DNOW[256];
|
||||
extern const OpFn ops_3DNOWE[256];
|
||||
|
||||
#define C0 (1<<8)
|
||||
#define C1 (1<<9)
|
||||
#define C2 (1<<10)
|
||||
#define C3 (1<<14)
|
||||
#define C0 (1 << 8)
|
||||
#define C1 (1 << 9)
|
||||
#define C2 (1 << 10)
|
||||
#define C3 (1 << 14)
|
||||
|
||||
#endif /*_X86_OPS_H*/
|
||||
|
||||
@@ -1,360 +1,381 @@
|
||||
#include <math.h>
|
||||
|
||||
static int opPREFETCH_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPREFETCH_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPREFETCH_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opFEMMS(uint32_t fetchdat)
|
||||
{
|
||||
ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX));
|
||||
if (cr0 & 0xc) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
x87_emms();
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opPAVGUSB(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPF2ID(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].sl[0] = (int32_t) src.f[0];
|
||||
cpu_state.MM[cpu_reg].sl[1] = (int32_t) src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPF2IW(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].sw[0] = (int32_t) src.f[0];
|
||||
cpu_state.MM[cpu_reg].sw[1] = (int32_t) src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFNACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFPNACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPSWAPD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf, tempf2;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
/* We have to do this in case source and destination overlap. */
|
||||
tempf = src.f[0];
|
||||
tempf2 = src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = tempf;
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFADD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] += src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] += src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFCMPEQ(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFCMPGE(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFCMPGT(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFMAX(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
if (src.f[0] > cpu_state.MM[cpu_reg].f[0])
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
if (src.f[1] > cpu_state.MM[cpu_reg].f[1])
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFMIN(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
if (src.f[0] < cpu_state.MM[cpu_reg].f[0])
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
if (src.f[1] < cpu_state.MM[cpu_reg].f[1])
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFMUL(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] *= src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] *= src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFRCP(uint32_t fetchdat)
|
||||
{
|
||||
union {
|
||||
uint32_t i;
|
||||
float f;
|
||||
} src;
|
||||
|
||||
if (cpu_mod == 3) {
|
||||
src.f = cpu_state.MM[cpu_rm].f[0];
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
static int opPREFETCH_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
} else {
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.i = readmeml(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f;
|
||||
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
|
||||
|
||||
static int opFEMMS(uint32_t fetchdat)
|
||||
{
|
||||
ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX));
|
||||
if (cr0 & 0xc)
|
||||
{
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
x87_emms();
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPAVGUSB(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPF2ID(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0];
|
||||
cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPF2IW(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].sw[0] = (int32_t)src.f[0];
|
||||
cpu_state.MM[cpu_reg].sw[1] = (int32_t)src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFNACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFPNACC(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPSWAPD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
float tempf, tempf2;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
/* We have to do this in case source and destination overlap. */
|
||||
tempf = src.f[0];
|
||||
tempf2 = src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[1] = tempf;
|
||||
cpu_state.MM[cpu_reg].f[0] = tempf2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFADD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] += src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] += src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFCMPEQ(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFCMPGE(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFCMPGT(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFMAX(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
if (src.f[0] > cpu_state.MM[cpu_reg].f[0])
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
if (src.f[1] > cpu_state.MM[cpu_reg].f[1])
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFMIN(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
if (src.f[0] < cpu_state.MM[cpu_reg].f[0])
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
if (src.f[1] < cpu_state.MM[cpu_reg].f[1])
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFMUL(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] *= src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] *= src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFRCP(uint32_t fetchdat)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t i;
|
||||
float f;
|
||||
} src;
|
||||
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
src.f = cpu_state.MM[cpu_rm].f[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = 1.0/src.f;
|
||||
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
/*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/
|
||||
static int opPFRCPIT1(uint32_t fetchdat)
|
||||
static int
|
||||
opPFRCPIT1(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPFRCPIT2(uint32_t fetchdat)
|
||||
static int
|
||||
opPFRCPIT2(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPFRSQRT(uint32_t fetchdat)
|
||||
static int
|
||||
opPFRSQRT(uint32_t fetchdat)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t i;
|
||||
float f;
|
||||
} src;
|
||||
union {
|
||||
uint32_t i;
|
||||
float f;
|
||||
} src;
|
||||
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
src.f = cpu_state.MM[cpu_rm].f[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
if (cpu_mod == 3) {
|
||||
src.f = cpu_state.MM[cpu_rm].f[0];
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.i = readmeml(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = 1.0/sqrt(src.f);
|
||||
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
|
||||
cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f);
|
||||
cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
/*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/
|
||||
static int opPFRSQIT1(uint32_t fetchdat)
|
||||
static int
|
||||
opPFRSQIT1(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
UN_USED(src);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFSUB(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] -= src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] -= src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPFSUBR(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPI2FD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = (float) src.sl[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = (float) src.sl[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPI2FW(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = (float) src.sw[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = (float) src.sw[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPMULHRW(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_reg].w[0] = (((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[1] = (((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[2] = (((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[3] = (((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16;
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
UN_USED(src);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFSUB(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] -= src.f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] -= src.f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPFSUBR(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPI2FD(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPI2FW(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].f[0] = (float)src.sw[0];
|
||||
cpu_state.MM[cpu_reg].f[1] = (float)src.sw[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPMULHRW(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16;
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = ((int32_t) (cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[1] = ((int32_t) (cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[2] = ((int32_t) (cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16;
|
||||
cpu_state.MM[cpu_reg].w[3] = ((int32_t) (cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const OpFn OP_TABLE(3DNOW)[256] =
|
||||
@@ -405,29 +426,33 @@ const OpFn OP_TABLE(3DNOWE)[256] =
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
};
|
||||
|
||||
static int op3DNOW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op3DNOW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t opcode;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
opcode = fastreadb(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetch_ea_16(fetchdat);
|
||||
opcode = fastreadb(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
return x86_opcodes_3DNOW[opcode](0);
|
||||
return x86_opcodes_3DNOW[opcode](0);
|
||||
}
|
||||
static int op3DNOW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op3DNOW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t opcode;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
opcode = fastreadb(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetch_ea_32(fetchdat);
|
||||
opcode = fastreadb(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
return x86_opcodes_3DNOW[opcode](0);
|
||||
return x86_opcodes_3DNOW[opcode](0);
|
||||
}
|
||||
|
||||
@@ -23,16 +23,15 @@ opSYSCALL(uint32_t fetchdat)
|
||||
ret = syscall_op(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
opSYSRET(uint32_t fetchdat)
|
||||
{
|
||||
@@ -43,10 +42,10 @@ opSYSRET(uint32_t fetchdat)
|
||||
ret = sysret(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,227 +1,295 @@
|
||||
static int opCMPXCHG_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2 = AL;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
if (AL == temp) seteab(getr8(cpu_reg));
|
||||
else AL = temp;
|
||||
if (cpu_state.abrt) return 1;
|
||||
setsub8(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
uint8_t temp, temp2 = AL;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (AL == temp)
|
||||
seteab(getr8(cpu_reg));
|
||||
else
|
||||
AL = temp;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub8(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
}
|
||||
static int opCMPXCHG_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2 = AL;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
if (AL == temp) seteab(getr8(cpu_reg));
|
||||
else AL = temp;
|
||||
if (cpu_state.abrt) return 1;
|
||||
setsub8(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
uint8_t temp, temp2 = AL;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (AL == temp)
|
||||
seteab(getr8(cpu_reg));
|
||||
else
|
||||
AL = temp;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub8(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMPXCHG_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2 = AX;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w);
|
||||
else AX = temp;
|
||||
if (cpu_state.abrt) return 1;
|
||||
setsub16(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
uint16_t temp, temp2 = AX;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (AX == temp)
|
||||
seteaw(cpu_state.regs[cpu_reg].w);
|
||||
else
|
||||
AX = temp;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub16(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
}
|
||||
static int opCMPXCHG_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2 = AX;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w);
|
||||
else AX = temp;
|
||||
if (cpu_state.abrt) return 1;
|
||||
setsub16(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
uint16_t temp, temp2 = AX;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (AX == temp)
|
||||
seteaw(cpu_state.regs[cpu_reg].w);
|
||||
else
|
||||
AX = temp;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub16(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMPXCHG_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2 = EAX;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l);
|
||||
else EAX = temp;
|
||||
if (cpu_state.abrt) return 1;
|
||||
setsub32(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
uint32_t temp, temp2 = EAX;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (EAX == temp)
|
||||
seteal(cpu_state.regs[cpu_reg].l);
|
||||
else
|
||||
EAX = temp;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub32(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
}
|
||||
static int opCMPXCHG_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2 = EAX;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l);
|
||||
else EAX = temp;
|
||||
if (cpu_state.abrt) return 1;
|
||||
setsub32(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
uint32_t temp, temp2 = EAX;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (EAX == temp)
|
||||
seteal(cpu_state.regs[cpu_reg].l);
|
||||
else
|
||||
EAX = temp;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub32(temp2, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMPXCHG8B_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG8B_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
if (EAX == temp && EDX == temp_hi)
|
||||
{
|
||||
seteal(EBX);
|
||||
writememl(easeg, cpu_state.eaaddr+4, ECX);
|
||||
}
|
||||
else
|
||||
{
|
||||
EAX = temp;
|
||||
EDX = temp_hi;
|
||||
}
|
||||
if (cpu_state.abrt) return 0;
|
||||
flags_rebuild();
|
||||
if (temp == temp2 && temp_hi == temp2_hi)
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
if (EAX == temp && EDX == temp_hi) {
|
||||
seteal(EBX);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, ECX);
|
||||
} else {
|
||||
EAX = temp;
|
||||
EDX = temp_hi;
|
||||
}
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
flags_rebuild();
|
||||
if (temp == temp2 && temp_hi == temp2_hi)
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
return 0;
|
||||
}
|
||||
static int opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
if (EAX == temp && EDX == temp_hi)
|
||||
{
|
||||
seteal(EBX);
|
||||
writememl(easeg, cpu_state.eaaddr+4, ECX);
|
||||
}
|
||||
else
|
||||
{
|
||||
EAX = temp;
|
||||
EDX = temp_hi;
|
||||
}
|
||||
if (cpu_state.abrt) return 0;
|
||||
flags_rebuild();
|
||||
if (temp == temp2 && temp_hi == temp2_hi)
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
if (EAX == temp && EDX == temp_hi) {
|
||||
seteal(EBX);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, ECX);
|
||||
} else {
|
||||
EAX = temp;
|
||||
EDX = temp_hi;
|
||||
}
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
flags_rebuild();
|
||||
if (temp == temp2 && temp_hi == temp2_hi)
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dest = eab, src = r8 */
|
||||
static int opXADD_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opXADD_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t src, dest;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getr8(cpu_reg);
|
||||
dest = geteab(); if (cpu_state.abrt) return 1;
|
||||
temp = src + dest;
|
||||
seteab(temp); if (cpu_state.abrt) return 1;
|
||||
setadd8(src, dest);
|
||||
setr8(cpu_reg, dest);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
uint8_t temp;
|
||||
uint8_t src, dest;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getr8(cpu_reg);
|
||||
dest = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
temp = src + dest;
|
||||
seteab(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd8(src, dest);
|
||||
setr8(cpu_reg, dest);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
static int opXADD_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opXADD_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t src, dest;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getr8(cpu_reg);
|
||||
dest = geteab(); if (cpu_state.abrt) return 1;
|
||||
temp = src + dest;
|
||||
seteab(temp); if (cpu_state.abrt) return 1;
|
||||
setadd8(src, dest);
|
||||
setr8(cpu_reg, dest);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
uint8_t temp;
|
||||
uint8_t src, dest;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getr8(cpu_reg);
|
||||
dest = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
temp = src + dest;
|
||||
seteab(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd8(src, dest);
|
||||
setr8(cpu_reg, dest);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opXADD_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opXADD_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t src, dest;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].w;
|
||||
dest = geteaw(); if (cpu_state.abrt) return 1;
|
||||
temp = src + dest;
|
||||
seteaw(temp); if (cpu_state.abrt) return 1;
|
||||
setadd16(src, dest);
|
||||
cpu_state.regs[cpu_reg].w = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
uint16_t temp;
|
||||
uint16_t src, dest;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].w;
|
||||
dest = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
temp = src + dest;
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd16(src, dest);
|
||||
cpu_state.regs[cpu_reg].w = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
static int opXADD_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opXADD_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t src, dest;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].w;
|
||||
dest = geteaw(); if (cpu_state.abrt) return 1;
|
||||
temp = src + dest;
|
||||
seteaw(temp); if (cpu_state.abrt) return 1;
|
||||
setadd16(src, dest);
|
||||
cpu_state.regs[cpu_reg].w = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
uint16_t temp;
|
||||
uint16_t src, dest;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].w;
|
||||
dest = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
temp = src + dest;
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd16(src, dest);
|
||||
cpu_state.regs[cpu_reg].w = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opXADD_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opXADD_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t src, dest;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].l;
|
||||
dest = geteal(); if (cpu_state.abrt) return 1;
|
||||
temp = src + dest;
|
||||
seteal(temp); if (cpu_state.abrt) return 1;
|
||||
setadd32(src, dest);
|
||||
cpu_state.regs[cpu_reg].l = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
uint32_t temp;
|
||||
uint32_t src, dest;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].l;
|
||||
dest = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
temp = src + dest;
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd32(src, dest);
|
||||
cpu_state.regs[cpu_reg].l = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
static int opXADD_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opXADD_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t src, dest;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].l;
|
||||
dest = geteal(); if (cpu_state.abrt) return 1;
|
||||
temp = src + dest;
|
||||
seteal(temp); if (cpu_state.abrt) return 1;
|
||||
setadd32(src, dest);
|
||||
cpu_state.regs[cpu_reg].l = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
uint32_t temp;
|
||||
uint32_t src, dest;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = cpu_state.regs[cpu_reg].l;
|
||||
dest = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
temp = src + dest;
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd32(src, dest);
|
||||
cpu_state.regs[cpu_reg].l = dest;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,129 +1,130 @@
|
||||
static int opAAA(uint32_t fetchdat)
|
||||
static int
|
||||
opAAA(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
{
|
||||
/* On 286, it's indeed AX - behavior difference from 808x. */
|
||||
AX += 6;
|
||||
AH++;
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
}
|
||||
else
|
||||
cpu_state.flags &= ~(A_FLAG | C_FLAG);
|
||||
AL &= 0xF;
|
||||
CLOCK_CYCLES(is486 ? 3 : 4);
|
||||
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) {
|
||||
/* On 286, it's indeed AX - behavior difference from 808x. */
|
||||
AX += 6;
|
||||
AH++;
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
} else
|
||||
cpu_state.flags &= ~(A_FLAG | C_FLAG);
|
||||
AL &= 0xF;
|
||||
CLOCK_CYCLES(is486 ? 3 : 4);
|
||||
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opAAD(uint32_t fetchdat)
|
||||
static int
|
||||
opAAD(uint32_t fetchdat)
|
||||
{
|
||||
int base = getbytef();
|
||||
if (!cpu_isintel) base = 10;
|
||||
AL = (AH * base) + AL;
|
||||
AH = 0;
|
||||
setznp16(AX);
|
||||
CLOCK_CYCLES((is486) ? 14 : 19);
|
||||
PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
int base = getbytef();
|
||||
if (!cpu_isintel)
|
||||
base = 10;
|
||||
AL = (AH * base) + AL;
|
||||
AH = 0;
|
||||
setznp16(AX);
|
||||
CLOCK_CYCLES((is486) ? 14 : 19);
|
||||
PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opAAM(uint32_t fetchdat)
|
||||
static int
|
||||
opAAM(uint32_t fetchdat)
|
||||
{
|
||||
int base = getbytef();
|
||||
if (!base || !cpu_isintel) base = 10;
|
||||
AH = AL / base;
|
||||
AL %= base;
|
||||
setznp16(AX);
|
||||
CLOCK_CYCLES((is486) ? 15 : 17);
|
||||
PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
int base = getbytef();
|
||||
if (!base || !cpu_isintel)
|
||||
base = 10;
|
||||
AH = AL / base;
|
||||
AL %= base;
|
||||
setznp16(AX);
|
||||
CLOCK_CYCLES((is486) ? 15 : 17);
|
||||
PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opAAS(uint32_t fetchdat)
|
||||
static int
|
||||
opAAS(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
{
|
||||
/* On 286, it's indeed AX - behavior difference from 808x. */
|
||||
AX -= 6;
|
||||
AH--;
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
}
|
||||
else
|
||||
cpu_state.flags &= ~(A_FLAG | C_FLAG);
|
||||
AL &= 0xF;
|
||||
CLOCK_CYCLES(is486 ? 3 : 4);
|
||||
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) {
|
||||
/* On 286, it's indeed AX - behavior difference from 808x. */
|
||||
AX -= 6;
|
||||
AH--;
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
} else
|
||||
cpu_state.flags &= ~(A_FLAG | C_FLAG);
|
||||
AL &= 0xF;
|
||||
CLOCK_CYCLES(is486 ? 3 : 4);
|
||||
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opDAA(uint32_t fetchdat)
|
||||
static int
|
||||
opDAA(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
|
||||
flags_rebuild();
|
||||
old_AL = AL;
|
||||
old_CF = cpu_state.flags & C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
flags_rebuild();
|
||||
old_AL = AL;
|
||||
old_CF = cpu_state.flags & C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) {
|
||||
int tempi = ((uint16_t)AL) + 6;
|
||||
AL += 6;
|
||||
if (old_CF || (tempi & 0x100))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~A_FLAG;
|
||||
if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) {
|
||||
int tempi = ((uint16_t) AL) + 6;
|
||||
AL += 6;
|
||||
if (old_CF || (tempi & 0x100))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~A_FLAG;
|
||||
|
||||
if ((old_AL > 0x99) || old_CF)
|
||||
{
|
||||
AL += 0x60;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
if ((old_AL > 0x99) || old_CF) {
|
||||
AL += 0x60;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opDAS(uint32_t fetchdat)
|
||||
static int
|
||||
opDAS(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
|
||||
flags_rebuild();
|
||||
old_AL = AL;
|
||||
old_CF = cpu_state.flags & C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
flags_rebuild();
|
||||
old_AL = AL;
|
||||
old_CF = cpu_state.flags & C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG))
|
||||
{
|
||||
int tempi = ((uint16_t)AL) - 6;
|
||||
AL -= 6;
|
||||
if (old_CF || (tempi & 0x100))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~A_FLAG;
|
||||
if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) {
|
||||
int tempi = ((uint16_t) AL) - 6;
|
||||
AL -= 6;
|
||||
if (old_CF || (tempi & 0x100))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~A_FLAG;
|
||||
|
||||
if ((old_AL > 0x99) || old_CF)
|
||||
{
|
||||
AL -= 0x60;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
if ((old_AL > 0x99) || old_CF) {
|
||||
AL -= 0x60;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,328 +1,411 @@
|
||||
static int opBT_w_r_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBT_w_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2);
|
||||
eal_r = 0;
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15)))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opBT_w_r_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBT_w_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2);
|
||||
eal_r = 0;
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15)))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opBT_l_r_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBT_l_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4);
|
||||
eal_r = 0;
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31)))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opBT_l_r_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBT_l_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4);
|
||||
eal_r = 0;
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31)))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define opBT(name, operation) \
|
||||
static int opBT ## name ## _w_r_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint16_t temp; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opBT ## name ## _w_r_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint16_t temp; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opBT ## name ## _l_r_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t temp; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
|
||||
temp = geteal(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opBT ## name ## _l_r_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t temp; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
|
||||
temp = geteal(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \
|
||||
return 0; \
|
||||
}
|
||||
#define opBT(name, operation) \
|
||||
static int opBT##name##_w_r_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint16_t temp; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \
|
||||
eal_r = eal_w = 0; \
|
||||
temp = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
|
||||
temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \
|
||||
seteaw(temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) \
|
||||
cpu_state.flags |= C_FLAG; \
|
||||
else \
|
||||
cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opBT##name##_w_r_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint16_t temp; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \
|
||||
eal_r = eal_w = 0; \
|
||||
temp = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
|
||||
temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \
|
||||
seteaw(temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) \
|
||||
cpu_state.flags |= C_FLAG; \
|
||||
else \
|
||||
cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opBT##name##_l_r_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t temp; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \
|
||||
eal_r = eal_w = 0; \
|
||||
temp = geteal(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
|
||||
temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \
|
||||
seteal(temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) \
|
||||
cpu_state.flags |= C_FLAG; \
|
||||
else \
|
||||
cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opBT##name##_l_r_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int tempc; \
|
||||
uint32_t temp; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \
|
||||
eal_r = eal_w = 0; \
|
||||
temp = geteal(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
|
||||
temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \
|
||||
seteal(temp); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) \
|
||||
cpu_state.flags |= C_FLAG; \
|
||||
else \
|
||||
cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 1); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
opBT(C, ^=)
|
||||
opBT(R, &=~)
|
||||
opBT(S, |=)
|
||||
opBT(R, &= ~)
|
||||
opBT(S, |=)
|
||||
|
||||
static int opBA_w_a16(uint32_t fetchdat)
|
||||
static int opBA_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
uint16_t temp;
|
||||
int tempc, count;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteaw();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
temp = geteaw();
|
||||
count = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteaw(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return 0;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opBA_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBA_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
uint16_t temp;
|
||||
int tempc, count;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteaw();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
temp = geteaw();
|
||||
count = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteaw(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return 0;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opBA_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBA_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
uint32_t temp;
|
||||
int tempc, count;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteal();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
temp = geteal();
|
||||
count = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteal(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
return 0;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opBA_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBA_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int tempc, count;
|
||||
uint32_t temp;
|
||||
int tempc, count;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteal();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
temp = geteal();
|
||||
count = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempc = temp & (1 << count);
|
||||
flags_rebuild();
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
return 0;
|
||||
case 0x28: /*BTS w,imm*/
|
||||
temp |= (1 << count);
|
||||
break;
|
||||
case 0x30: /*BTR w,imm*/
|
||||
temp &= ~(1 << count);
|
||||
break;
|
||||
case 0x38: /*BTC w,imm*/
|
||||
temp ^= (1 << count);
|
||||
break;
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteal(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
return 0;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (tempc)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,211 +1,227 @@
|
||||
#ifdef IS_DYNAREC
|
||||
#define BS_common(start, end, dir, dest, time) \
|
||||
flags_rebuild(); \
|
||||
if (temp) \
|
||||
{ \
|
||||
int c; \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
for (c = start; c != end; c += dir) \
|
||||
{ \
|
||||
CLOCK_CYCLES(time); \
|
||||
if (temp & (1 << c)) \
|
||||
{ \
|
||||
dest = c; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
# define BS_common(start, end, dir, dest, time) \
|
||||
flags_rebuild(); \
|
||||
if (temp) { \
|
||||
int c; \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
for (c = start; c != end; c += dir) { \
|
||||
CLOCK_CYCLES(time); \
|
||||
if (temp & (1 << c)) { \
|
||||
dest = c; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} else \
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
#else
|
||||
#define BS_common(start, end, dir, dest, time) \
|
||||
flags_rebuild(); \
|
||||
instr_cycles = 0; \
|
||||
if (temp) \
|
||||
{ \
|
||||
int c; \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
for (c = start; c != end; c += dir) \
|
||||
{ \
|
||||
CLOCK_CYCLES(time); \
|
||||
instr_cycles += time; \
|
||||
if (temp & (1 << c)) \
|
||||
{ \
|
||||
dest = c; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
# define BS_common(start, end, dir, dest, time) \
|
||||
flags_rebuild(); \
|
||||
instr_cycles = 0; \
|
||||
if (temp) { \
|
||||
int c; \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
for (c = start; c != end; c += dir) { \
|
||||
CLOCK_CYCLES(time); \
|
||||
instr_cycles += time; \
|
||||
if (temp & (1 << c)) { \
|
||||
dest = c; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} else \
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
#endif
|
||||
|
||||
static int opBSF_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBSF_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
|
||||
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opBSF_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBSF_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
|
||||
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opBSF_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBSF_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
|
||||
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opBSF_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBSF_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
|
||||
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opBSR_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBSR_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
|
||||
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opBSR_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBSR_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
|
||||
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opBSR_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opBSR_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
|
||||
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opBSR_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opBSR_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
#ifndef IS_DYNAREC
|
||||
int instr_cycles = 0;
|
||||
int instr_cycles = 0;
|
||||
#endif
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
|
||||
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
|
||||
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
CLOCK_CYCLES((is486) ? 6 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
instr_cycles += ((is486) ? 6 : 10);
|
||||
PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +1,265 @@
|
||||
/*Cyrix-only instructions*/
|
||||
/*System Management Mode*/
|
||||
static void opSVDC_common(uint32_t fetchdat)
|
||||
static void
|
||||
opSVDC_common(uint32_t fetchdat)
|
||||
{
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, GS);
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
}
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, GS);
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
}
|
||||
}
|
||||
static int opSVDC_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opSVDC_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
opSVDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
opSVDC_common(fetchdat);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opSVDC_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opSVDC_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
opSVDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
opSVDC_common(fetchdat);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static void opRSDC_common(uint32_t fetchdat)
|
||||
static void
|
||||
opRSDC_common(uint32_t fetchdat)
|
||||
{
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
}
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
}
|
||||
}
|
||||
static int opRSDC_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opRSDC_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
opRSDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
opRSDC_common(fetchdat);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opRSDC_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opRSDC_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
opRSDC_common(fetchdat);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
opRSDC_common(fetchdat);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opSVLDT_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opSVLDT_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opSVLDT_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opSVLDT_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opRSLDT_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opRSLDT_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opRSLDT_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opRSLDT_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opSVTS_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opSVTS_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opSVTS_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opSVTS_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opRSTS_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opRSTS_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opRSTS_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opRSTS_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
||||
}
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm) {
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr);
|
||||
writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg);
|
||||
} else
|
||||
x86illegal();
|
||||
|
||||
return cpu_state.abrt;
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opSMINT(uint32_t fetchdat)
|
||||
static int
|
||||
opSMINT(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
fatal("opSMINT\n");
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm)
|
||||
fatal("opSMINT\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opRDSHR_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opRDSHR_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
fatal("opRDSHR_a16\n");
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm)
|
||||
fatal("opRDSHR_a16\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
static int opRDSHR_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opRDSHR_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
fatal("opRDSHR_a32\n");
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm)
|
||||
fatal("opRDSHR_a32\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opWRSHR_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opWRSHR_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
fatal("opWRSHR_a16\n");
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm)
|
||||
fatal("opWRSHR_a16\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
static int opWRSHR_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opWRSHR_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
fatal("opWRSHR_a32\n");
|
||||
else
|
||||
x86illegal();
|
||||
if (in_smm)
|
||||
fatal("opWRSHR_a32\n");
|
||||
else
|
||||
x86illegal();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,313 +1,319 @@
|
||||
static int opCMC(uint32_t fetchdat)
|
||||
static int
|
||||
opCMC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags ^= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
flags_rebuild();
|
||||
cpu_state.flags ^= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int opCLC(uint32_t fetchdat)
|
||||
static int
|
||||
opCLC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCLD(uint32_t fetchdat)
|
||||
static int
|
||||
opCLD(uint32_t fetchdat)
|
||||
{
|
||||
cpu_state.flags &= ~D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
cpu_state.flags &= ~D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCLI(uint32_t fetchdat)
|
||||
static int
|
||||
opCLI(uint32_t fetchdat)
|
||||
{
|
||||
if (!IOPLp)
|
||||
{
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||
{
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (!IOPLp) {
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opSTC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opSTD(uint32_t fetchdat)
|
||||
{
|
||||
cpu_state.flags |= D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opSTI(uint32_t fetchdat)
|
||||
{
|
||||
if (!IOPLp) {
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
|
||||
if (cpu_state.eflags & VIP_FLAG) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
} else
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
cpu_state.flags |= I_FLAG;
|
||||
|
||||
/*First instruction after STI will always execute, regardless of whether
|
||||
there is a pending interrupt*/
|
||||
cpu_end_block_after_ins = 2;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opSAHF(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opLAHF(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
AH = cpu_state.flags & 0xff;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opPUSHF(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint16_t temp;
|
||||
|
||||
flags_rebuild();
|
||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||
if (cpu_state.eflags & VIF_FLAG)
|
||||
temp |= I_FLAG;
|
||||
PUSH_W(temp);
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
flags_rebuild();
|
||||
PUSH_W(cpu_state.flags);
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int
|
||||
opPUSHFD(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (cpu_CR4_mask & CR4_VME)
|
||||
tempw = cpu_state.eflags & 0x3c;
|
||||
else if (CPUID)
|
||||
tempw = cpu_state.eflags & 0x24;
|
||||
else
|
||||
tempw = cpu_state.eflags & 4;
|
||||
flags_rebuild();
|
||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opPOPF_186(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(msw & 1))
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPOPF_286(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(msw & 1))
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPOPF(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint32_t old_esp = ESP;
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt) {
|
||||
|
||||
ESP = old_esp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
|
||||
ESP = old_esp;
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (tempw & I_FLAG)
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(CPL) || !(msw & 1))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
}
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opSTC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opSTD(uint32_t fetchdat)
|
||||
{
|
||||
cpu_state.flags |= D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opSTI(uint32_t fetchdat)
|
||||
{
|
||||
if (!IOPLp)
|
||||
{
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||
{
|
||||
if (cpu_state.eflags & VIP_FLAG)
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
cpu_state.flags |= I_FLAG;
|
||||
|
||||
/*First instruction after STI will always execute, regardless of whether
|
||||
there is a pending interrupt*/
|
||||
cpu_end_block_after_ins = 2;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opSAHF(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opLAHF(uint32_t fetchdat)
|
||||
static int
|
||||
opPOPFD(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
AH = cpu_state.flags & 0xff;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
uint32_t templ;
|
||||
|
||||
static int opPUSHF(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
uint16_t temp;
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
flags_rebuild();
|
||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||
if (cpu_state.eflags & VIF_FLAG)
|
||||
temp |= I_FLAG;
|
||||
PUSH_W(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flags_rebuild();
|
||||
PUSH_W(cpu_state.flags);
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opPUSHFD(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (cpu_CR4_mask & CR4_VME) tempw = cpu_state.eflags & 0x3c;
|
||||
else if (CPUID) tempw = cpu_state.eflags & 0x24;
|
||||
else tempw = cpu_state.eflags & 4;
|
||||
flags_rebuild();
|
||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
templ = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
static int opPOPF_186(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if (!(CPL) || !(msw & 1))
|
||||
cpu_state.flags = (templ & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
templ &= (is486 || isibm486) ? 0x3c0000 : 0;
|
||||
templ |= ((cpu_state.eflags & 3) << 16);
|
||||
if (cpu_CR4_mask & CR4_VME)
|
||||
cpu_state.eflags = (templ >> 16) & 0x3f;
|
||||
else if (CPUID)
|
||||
cpu_state.eflags = (templ >> 16) & 0x27;
|
||||
else if (is486 || isibm486)
|
||||
cpu_state.eflags = (templ >> 16) & 7;
|
||||
else
|
||||
cpu_state.eflags = (templ >> 16) & 3;
|
||||
|
||||
tempw = POP_W(); if (cpu_state.abrt) return 1;
|
||||
flags_extract();
|
||||
|
||||
if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPOPF_286(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W(); if (cpu_state.abrt) return 1;
|
||||
|
||||
if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPOPF(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
uint32_t old_esp = ESP;
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
|
||||
ESP = old_esp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG)))
|
||||
{
|
||||
ESP = old_esp;
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (tempw & I_FLAG)
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(CPL) || !(msw & 1))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
}
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPOPFD(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
templ = POP_L(); if (cpu_state.abrt) return 1;
|
||||
|
||||
if (!(CPL) || !(msw & 1)) cpu_state.flags = (templ & 0x7fd5) | 2;
|
||||
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
|
||||
else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
|
||||
|
||||
templ &= (is486 || isibm486) ? 0x3c0000 : 0;
|
||||
templ |= ((cpu_state.eflags&3) << 16);
|
||||
if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f;
|
||||
else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27;
|
||||
else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7;
|
||||
else cpu_state.eflags = (templ >> 16) & 3;
|
||||
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,85 +1,101 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
static int opESCAPE_d8_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_d8_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int opESCAPE_d8_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_d8_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int opESCAPE_d9_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_d9_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int opESCAPE_d9_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_d9_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int opESCAPE_da_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_da_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int opESCAPE_da_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_da_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int opESCAPE_db_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_db_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int opESCAPE_db_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_db_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int opESCAPE_dc_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_dc_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int opESCAPE_dc_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_dc_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int opESCAPE_dd_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_dd_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int opESCAPE_dd_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_dd_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int opESCAPE_de_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_de_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int opESCAPE_de_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_de_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int opESCAPE_df_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_df_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int opESCAPE_df_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opESCAPE_df_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat);
|
||||
return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int opWAIT(uint32_t fetchdat)
|
||||
static int
|
||||
opWAIT(uint32_t fetchdat)
|
||||
{
|
||||
if ((cr0 & 0xa) == 0xa)
|
||||
{
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
if ((cr0 & 0xa) == 0xa) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19,65 +19,63 @@ opSYSENTER(uint32_t fetchdat)
|
||||
int ret = sysenter(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
opSYSEXIT(uint32_t fetchdat)
|
||||
{
|
||||
int ret = sysexit(fetchdat);
|
||||
|
||||
if (ret <= 1) {
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
{
|
||||
uint8_t fxinst = 0;
|
||||
uint16_t twd = x87_gettag();
|
||||
uint32_t old_eaaddr = 0;
|
||||
uint8_t ftwb = 0;
|
||||
uint16_t rec_ftw = 0;
|
||||
uint16_t fpus = 0;
|
||||
uint8_t fxinst = 0;
|
||||
uint16_t twd = x87_gettag();
|
||||
uint32_t old_eaaddr = 0;
|
||||
uint8_t ftwb = 0;
|
||||
uint16_t rec_ftw = 0;
|
||||
uint16_t fpus = 0;
|
||||
uint64_t *p;
|
||||
|
||||
if (CPUID < 0x650)
|
||||
return ILLEGAL(fetchdat);
|
||||
return ILLEGAL(fetchdat);
|
||||
|
||||
FP_ENTER();
|
||||
|
||||
if (bits == 32) {
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
} else {
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
}
|
||||
|
||||
if (cpu_state.eaaddr & 0xf) {
|
||||
x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr);
|
||||
x86gpf(NULL, 0);
|
||||
return cpu_state.abrt;
|
||||
x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr);
|
||||
x86gpf(NULL, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
fxinst = (rmdat >> 3) & 7;
|
||||
|
||||
if ((fxinst > 1) || (cpu_mod == 3)) {
|
||||
x86illegal();
|
||||
return cpu_state.abrt;
|
||||
x86illegal();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
FP_ENTER();
|
||||
@@ -85,170 +83,186 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
old_eaaddr = cpu_state.eaaddr;
|
||||
|
||||
if (fxinst == 1) {
|
||||
/* FXRSTOR */
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
fpus = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040;
|
||||
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
|
||||
cpu_state.TOP = (fpus >> 11) & 7;
|
||||
cpu_state.npxs &= fpus & ~0x3800;
|
||||
/* FXRSTOR */
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
fpus = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040;
|
||||
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
|
||||
cpu_state.TOP = (fpus >> 11) & 7;
|
||||
cpu_state.npxs &= fpus & ~0x3800;
|
||||
|
||||
x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8);
|
||||
x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12);
|
||||
x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8);
|
||||
x87_pc_seg = readmemw(easeg, cpu_state.eaaddr + 12);
|
||||
|
||||
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
|
||||
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
|
||||
|
||||
if (ftwb & 0x01) rec_ftw |= 0x0003;
|
||||
if (ftwb & 0x02) rec_ftw |= 0x000C;
|
||||
if (ftwb & 0x04) rec_ftw |= 0x0030;
|
||||
if (ftwb & 0x08) rec_ftw |= 0x00C0;
|
||||
if (ftwb & 0x10) rec_ftw |= 0x0300;
|
||||
if (ftwb & 0x20) rec_ftw |= 0x0C00;
|
||||
if (ftwb & 0x40) rec_ftw |= 0x3000;
|
||||
if (ftwb & 0x80) rec_ftw |= 0xC000;
|
||||
if (ftwb & 0x01)
|
||||
rec_ftw |= 0x0003;
|
||||
if (ftwb & 0x02)
|
||||
rec_ftw |= 0x000C;
|
||||
if (ftwb & 0x04)
|
||||
rec_ftw |= 0x0030;
|
||||
if (ftwb & 0x08)
|
||||
rec_ftw |= 0x00C0;
|
||||
if (ftwb & 0x10)
|
||||
rec_ftw |= 0x0300;
|
||||
if (ftwb & 0x20)
|
||||
rec_ftw |= 0x0C00;
|
||||
if (ftwb & 0x40)
|
||||
rec_ftw |= 0x3000;
|
||||
if (ftwb & 0x80)
|
||||
rec_ftw |= 0xC000;
|
||||
|
||||
x87_op_off = readmeml(easeg, cpu_state.eaaddr+16);
|
||||
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16;
|
||||
x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20);
|
||||
x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16);
|
||||
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16;
|
||||
x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 32;
|
||||
x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0);
|
||||
cpu_state.eaaddr = old_eaaddr + 32;
|
||||
x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0]));
|
||||
x87_ld_frstor(0);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 48;
|
||||
x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1);
|
||||
cpu_state.eaaddr = old_eaaddr + 48;
|
||||
x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1]));
|
||||
x87_ld_frstor(1);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 64;
|
||||
x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2);
|
||||
cpu_state.eaaddr = old_eaaddr + 64;
|
||||
x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2]));
|
||||
x87_ld_frstor(2);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 80;
|
||||
x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3);
|
||||
cpu_state.eaaddr = old_eaaddr + 80;
|
||||
x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3]));
|
||||
x87_ld_frstor(3);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 96;
|
||||
x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4);
|
||||
cpu_state.eaaddr = old_eaaddr + 96;
|
||||
x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4]));
|
||||
x87_ld_frstor(4);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 112;
|
||||
x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5);
|
||||
cpu_state.eaaddr = old_eaaddr + 112;
|
||||
x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5]));
|
||||
x87_ld_frstor(5);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 128;
|
||||
x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6);
|
||||
cpu_state.eaaddr = old_eaaddr + 128;
|
||||
x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6]));
|
||||
x87_ld_frstor(6);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 144;
|
||||
x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7);
|
||||
cpu_state.eaaddr = old_eaaddr + 144;
|
||||
x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7]));
|
||||
x87_ld_frstor(7);
|
||||
|
||||
cpu_state.ismmx = 0;
|
||||
/*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times
|
||||
something like this is needed*/
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
cpu_state.ismmx = 0;
|
||||
/*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times
|
||||
something like this is needed*/
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
|
||||
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
|
||||
!cpu_state.TOP && (*p == 0x0101010101010101ull))
|
||||
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull))
|
||||
#else
|
||||
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
|
||||
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
|
||||
!cpu_state.TOP && !(*p))
|
||||
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p))
|
||||
#endif
|
||||
cpu_state.ismmx = 1;
|
||||
cpu_state.ismmx = 1;
|
||||
|
||||
x87_settag(rec_ftw);
|
||||
x87_settag(rec_ftw);
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
} else {
|
||||
/* FXSAVE */
|
||||
if ((twd & 0x0003) == 0x0003) ftwb |= 0x01;
|
||||
if ((twd & 0x000C) == 0x000C) ftwb |= 0x02;
|
||||
if ((twd & 0x0030) == 0x0030) ftwb |= 0x04;
|
||||
if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08;
|
||||
if ((twd & 0x0300) == 0x0300) ftwb |= 0x10;
|
||||
if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20;
|
||||
if ((twd & 0x3000) == 0x3000) ftwb |= 0x40;
|
||||
if ((twd & 0xC000) == 0xC000) ftwb |= 0x80;
|
||||
/* FXSAVE */
|
||||
if ((twd & 0x0003) == 0x0003)
|
||||
ftwb |= 0x01;
|
||||
if ((twd & 0x000C) == 0x000C)
|
||||
ftwb |= 0x02;
|
||||
if ((twd & 0x0030) == 0x0030)
|
||||
ftwb |= 0x04;
|
||||
if ((twd & 0x00C0) == 0x00C0)
|
||||
ftwb |= 0x08;
|
||||
if ((twd & 0x0300) == 0x0300)
|
||||
ftwb |= 0x10;
|
||||
if ((twd & 0x0C00) == 0x0C00)
|
||||
ftwb |= 0x20;
|
||||
if ((twd & 0x3000) == 0x3000)
|
||||
ftwb |= 0x40;
|
||||
if ((twd & 0xC000) == 0xC000)
|
||||
ftwb |= 0x80;
|
||||
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
|
||||
writememb(easeg,cpu_state.eaaddr+4,ftwb);
|
||||
writememw(easeg, cpu_state.eaaddr, cpu_state.npxc);
|
||||
writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs);
|
||||
writememb(easeg, cpu_state.eaaddr + 4, ftwb);
|
||||
|
||||
writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12);
|
||||
writememl(easeg,cpu_state.eaaddr+8,x87_pc_off);
|
||||
writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg);
|
||||
writememw(easeg, cpu_state.eaaddr + 6, (x87_op_off >> 16) << 12);
|
||||
writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off);
|
||||
writememw(easeg, cpu_state.eaaddr + 12, x87_pc_seg);
|
||||
|
||||
writememl(easeg,cpu_state.eaaddr+16,x87_op_off);
|
||||
writememw(easeg,cpu_state.eaaddr+20,x87_op_seg);
|
||||
writememl(easeg, cpu_state.eaaddr + 16, x87_op_off);
|
||||
writememw(easeg, cpu_state.eaaddr + 20, x87_op_seg);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 32;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0);
|
||||
cpu_state.eaaddr = old_eaaddr + 32;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 48;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1);
|
||||
cpu_state.eaaddr = old_eaaddr + 48;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 64;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2);
|
||||
cpu_state.eaaddr = old_eaaddr + 64;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 80;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3);
|
||||
cpu_state.eaaddr = old_eaaddr + 80;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 96;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4);
|
||||
cpu_state.eaaddr = old_eaaddr + 96;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 112;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5);
|
||||
cpu_state.eaaddr = old_eaaddr + 112;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 128;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6);
|
||||
cpu_state.eaaddr = old_eaaddr + 128;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr + 144;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7);
|
||||
cpu_state.eaaddr = old_eaaddr + 144;
|
||||
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7);
|
||||
|
||||
cpu_state.eaaddr = old_eaaddr;
|
||||
cpu_state.eaaddr = old_eaaddr;
|
||||
|
||||
cpu_state.npxc = 0x37F;
|
||||
cpu_state.npxc = 0x37F;
|
||||
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
|
||||
cpu_state.npxs = 0;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
cpu_state.npxs = 0;
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
*p = 0;
|
||||
#else
|
||||
*p = 0x0303030303030303ll;
|
||||
#endif
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
|
||||
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
|
||||
}
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
opFXSAVESTOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
return fx_save_stor_common(fetchdat, 16);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
opFXSAVESTOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
return fx_save_stor_common(fetchdat, 32);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
opHINT_NOP_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES((is486) ? 1 : 3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
opHINT_NOP_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
CLOCK_CYCLES((is486) ? 1 : 3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#define INC_DEC_OP(name, reg, inc, setflags) \
|
||||
static int op ## name (uint32_t fetchdat) \
|
||||
{ \
|
||||
setflags(reg, 1); \
|
||||
reg += inc; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
}
|
||||
#define INC_DEC_OP(name, reg, inc, setflags) \
|
||||
static int op##name(uint32_t fetchdat) \
|
||||
{ \
|
||||
setflags(reg, 1); \
|
||||
reg += inc; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
INC_DEC_OP(INC_AX, AX, 1, setadd16nc)
|
||||
INC_DEC_OP(INC_BX, BX, 1, setadd16nc)
|
||||
@@ -44,50 +44,57 @@ INC_DEC_OP(DEC_EDI, EDI, -1, setsub32nc)
|
||||
INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc)
|
||||
INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc)
|
||||
|
||||
|
||||
static int opINCDEC_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opINCDEC_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp=geteab(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (rmdat&0x38)
|
||||
{
|
||||
seteab(temp - 1); if (cpu_state.abrt) return 1;
|
||||
setsub8nc(temp, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
seteab(temp + 1); if (cpu_state.abrt) return 1;
|
||||
setadd8nc(temp, 1);
|
||||
}
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return 0;
|
||||
if (rmdat & 0x38) {
|
||||
seteab(temp - 1);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub8nc(temp, 1);
|
||||
} else {
|
||||
seteab(temp + 1);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd8nc(temp, 1);
|
||||
}
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opINCDEC_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opINCDEC_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp=geteab(); if (cpu_state.abrt) return 1;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (rmdat&0x38)
|
||||
{
|
||||
seteab(temp - 1); if (cpu_state.abrt) return 1;
|
||||
setsub8nc(temp, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
seteab(temp + 1); if (cpu_state.abrt) return 1;
|
||||
setadd8nc(temp, 1);
|
||||
}
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
return 0;
|
||||
if (rmdat & 0x38) {
|
||||
seteab(temp - 1);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setsub8nc(temp, 1);
|
||||
} else {
|
||||
seteab(temp + 1);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setadd8nc(temp, 1);
|
||||
}
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,94 +1,96 @@
|
||||
static int opINT3(uint32_t fetchdat)
|
||||
static int
|
||||
opINT3(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
#ifdef USE_GDBSTUB
|
||||
if (gdbstub_int3())
|
||||
return 1;
|
||||
if (gdbstub_int3())
|
||||
return 1;
|
||||
#endif
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
x86_int_sw(3);
|
||||
CLOCK_CYCLES((is486) ? 44 : 59);
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0);
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
x86_int_sw(3);
|
||||
CLOCK_CYCLES((is486) ? 44 : 59);
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opINT1(uint32_t fetchdat)
|
||||
static int
|
||||
opINT1(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
x86_int_sw(1);
|
||||
CLOCK_CYCLES((is486) ? 44 : 59);
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0);
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
x86_int_sw(1);
|
||||
CLOCK_CYCLES((is486) ? 44 : 59);
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opINT(uint32_t fetchdat)
|
||||
static int
|
||||
opINT(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
uint8_t temp = getbytef();
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
uint8_t temp = getbytef();
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
uint16_t t;
|
||||
uint8_t d;
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint16_t t;
|
||||
uint8_t d;
|
||||
|
||||
cpl_override = 1;
|
||||
t = readmemw(tr.base, 0x66) - 32;
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpl_override = 1;
|
||||
t = readmemw(tr.base, 0x66) - 32;
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
t += (temp >> 3);
|
||||
if (t <= tr.limit)
|
||||
{
|
||||
cpl_override = 1;
|
||||
d = readmemb(tr.base, t);// + (temp >> 3));
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt) return 1;
|
||||
t += (temp >> 3);
|
||||
if (t <= tr.limit) {
|
||||
cpl_override = 1;
|
||||
d = readmemb(tr.base, t); // + (temp >> 3));
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(d & (1 << (temp & 7))))
|
||||
{
|
||||
x86_int_sw_rm(temp);
|
||||
PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!(d & (1 << (temp & 7)))) {
|
||||
x86_int_sw_rm(temp);
|
||||
PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
x86gpf_expected(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
x86_int_sw(temp);
|
||||
PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0);
|
||||
x86gpf_expected(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
x86_int_sw(temp);
|
||||
PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opINTO(uint32_t fetchdat)
|
||||
static int
|
||||
opINTO(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (VF_SET())
|
||||
{
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int_sw(4);
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0);
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (VF_SET()) {
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int_sw(4);
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,146 +1,158 @@
|
||||
static int opIN_AL_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opIN_AL_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t)getbytef();
|
||||
check_io_perm(port);
|
||||
AL = inb(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
AL = inb(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opIN_AX_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opIN_AX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t)getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
AX = inw(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
AX = inw(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opIN_EAX_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opIN_EAX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t)getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port + 2);
|
||||
check_io_perm(port + 3);
|
||||
EAX = inl(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 0,1,0,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port + 2);
|
||||
check_io_perm(port + 3);
|
||||
EAX = inl(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opOUT_AL_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opOUT_AL_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t)getbytef();
|
||||
check_io_perm(port);
|
||||
outb(port, AL);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0);
|
||||
if (port == 0x64)
|
||||
return x86_was_reset;
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opOUT_AX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t)getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
outw(port, AX);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opOUT_EAX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t)getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port + 2);
|
||||
check_io_perm(port + 3);
|
||||
outl(port, EAX);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opIN_AL_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
AL = inb(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opIN_AX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
AX = inw(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opIN_EAX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
EAX = inl(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opOUT_AL_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
outb(DX, AL);
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
outb(port, AL);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
|
||||
if (port == 0x64)
|
||||
return x86_was_reset;
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opOUT_AX_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opOUT_AX_imm(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
outw(DX, AX);
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
outw(port, AX);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int opOUT_EAX_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opOUT_EAX_imm(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
outl(DX, EAX);
|
||||
PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port + 2);
|
||||
check_io_perm(port + 3);
|
||||
outl(port, EAX);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opIN_AL_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
AL = inb(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opIN_AX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
AX = inw(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opIN_EAX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
EAX = inl(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opOUT_AL_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
outb(DX, AL);
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return x86_was_reset;
|
||||
}
|
||||
static int
|
||||
opOUT_AX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
outw(DX, AX);
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opOUT_EAX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
outl(DX, EAX);
|
||||
PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,74 +1,73 @@
|
||||
#define cond_O ( VF_SET())
|
||||
#define cond_O (VF_SET())
|
||||
#define cond_NO (!VF_SET())
|
||||
#define cond_B ( CF_SET())
|
||||
#define cond_B (CF_SET())
|
||||
#define cond_NB (!CF_SET())
|
||||
#define cond_E ( ZF_SET())
|
||||
#define cond_E (ZF_SET())
|
||||
#define cond_NE (!ZF_SET())
|
||||
#define cond_BE ( CF_SET() || ZF_SET())
|
||||
#define cond_BE (CF_SET() || ZF_SET())
|
||||
#define cond_NBE (!CF_SET() && !ZF_SET())
|
||||
#define cond_S ( NF_SET())
|
||||
#define cond_S (NF_SET())
|
||||
#define cond_NS (!NF_SET())
|
||||
#define cond_P ( PF_SET())
|
||||
#define cond_P (PF_SET())
|
||||
#define cond_NP (!PF_SET())
|
||||
#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0))
|
||||
#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0))
|
||||
#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET()))
|
||||
#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET()))
|
||||
#define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET()))
|
||||
|
||||
#define opJ(condition) \
|
||||
static int opJ ## condition(uint32_t fetchdat) \
|
||||
{ \
|
||||
int8_t offset = (int8_t)getbytef(); \
|
||||
CLOCK_CYCLES(timing_bnt); \
|
||||
if (cond_ ## condition) \
|
||||
{ \
|
||||
cpu_state.pc += offset; \
|
||||
if (!(cpu_state.op32 & 0x100)) \
|
||||
cpu_state.pc &= 0xffff; \
|
||||
CLOCK_CYCLES_ALWAYS(timing_bt); \
|
||||
CPU_BLOCK_END(); \
|
||||
PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \
|
||||
PREFETCH_FLUSH(); \
|
||||
return 1; \
|
||||
} \
|
||||
PREFETCH_RUN(timing_bnt, 2, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opJ ## condition ## _w(uint32_t fetchdat) \
|
||||
{ \
|
||||
int16_t offset = (int16_t)getwordf(); \
|
||||
CLOCK_CYCLES(timing_bnt); \
|
||||
if (cond_ ## condition) \
|
||||
{ \
|
||||
cpu_state.pc += offset; \
|
||||
cpu_state.pc &= 0xffff; \
|
||||
CLOCK_CYCLES_ALWAYS(timing_bt); \
|
||||
CPU_BLOCK_END(); \
|
||||
PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \
|
||||
PREFETCH_FLUSH(); \
|
||||
return 1; \
|
||||
} \
|
||||
PREFETCH_RUN(timing_bnt, 3, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opJ ## condition ## _l(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t offset = getlong(); if (cpu_state.abrt) return 1; \
|
||||
CLOCK_CYCLES(timing_bnt); \
|
||||
if (cond_ ## condition) \
|
||||
{ \
|
||||
cpu_state.pc += offset; \
|
||||
CLOCK_CYCLES_ALWAYS(timing_bt); \
|
||||
CPU_BLOCK_END(); \
|
||||
PREFETCH_RUN(timing_bt+timing_bnt, 5, -1, 0,0,0,0, 0); \
|
||||
PREFETCH_FLUSH(); \
|
||||
return 1; \
|
||||
} \
|
||||
PREFETCH_RUN(timing_bnt, 5, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
#define opJ(condition) \
|
||||
static int opJ##condition(uint32_t fetchdat) \
|
||||
{ \
|
||||
int8_t offset = (int8_t) getbytef(); \
|
||||
CLOCK_CYCLES(timing_bnt); \
|
||||
if (cond_##condition) { \
|
||||
cpu_state.pc += offset; \
|
||||
if (!(cpu_state.op32 & 0x100)) \
|
||||
cpu_state.pc &= 0xffff; \
|
||||
CLOCK_CYCLES_ALWAYS(timing_bt); \
|
||||
CPU_BLOCK_END(); \
|
||||
PREFETCH_RUN(timing_bt + timing_bnt, 2, -1, 0, 0, 0, 0, 0); \
|
||||
PREFETCH_FLUSH(); \
|
||||
return 1; \
|
||||
} \
|
||||
PREFETCH_RUN(timing_bnt, 2, -1, 0, 0, 0, 0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opJ##condition##_w(uint32_t fetchdat) \
|
||||
{ \
|
||||
int16_t offset = (int16_t) getwordf(); \
|
||||
CLOCK_CYCLES(timing_bnt); \
|
||||
if (cond_##condition) { \
|
||||
cpu_state.pc += offset; \
|
||||
cpu_state.pc &= 0xffff; \
|
||||
CLOCK_CYCLES_ALWAYS(timing_bt); \
|
||||
CPU_BLOCK_END(); \
|
||||
PREFETCH_RUN(timing_bt + timing_bnt, 3, -1, 0, 0, 0, 0, 0); \
|
||||
PREFETCH_FLUSH(); \
|
||||
return 1; \
|
||||
} \
|
||||
PREFETCH_RUN(timing_bnt, 3, -1, 0, 0, 0, 0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opJ##condition##_l(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t offset = getlong(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
CLOCK_CYCLES(timing_bnt); \
|
||||
if (cond_##condition) { \
|
||||
cpu_state.pc += offset; \
|
||||
CLOCK_CYCLES_ALWAYS(timing_bt); \
|
||||
CPU_BLOCK_END(); \
|
||||
PREFETCH_RUN(timing_bt + timing_bnt, 5, -1, 0, 0, 0, 0, 0); \
|
||||
PREFETCH_FLUSH(); \
|
||||
return 1; \
|
||||
} \
|
||||
PREFETCH_RUN(timing_bnt, 5, -1, 0, 0, 0, 0, 0); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
opJ(O)
|
||||
opJ(NO)
|
||||
@@ -87,294 +86,321 @@ opJ(NL)
|
||||
opJ(LE)
|
||||
opJ(NLE)
|
||||
|
||||
|
||||
|
||||
static int opLOOPNE_w(uint32_t fetchdat)
|
||||
static int opLOOPNE_w(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
CX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0);
|
||||
if (CX && !ZF_SET())
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opLOOPNE_l(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
ECX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0);
|
||||
if (ECX && !ZF_SET())
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opLOOPE_w(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
CX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0);
|
||||
if (CX && ZF_SET())
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opLOOPE_l(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
ECX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0);
|
||||
if (ECX && ZF_SET())
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opLOOP_w(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
CX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0);
|
||||
if (CX)
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opLOOP_l(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
ECX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0);
|
||||
if (ECX)
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opJCXZ(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
CLOCK_CYCLES(5);
|
||||
if (!CX)
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CLOCK_CYCLES(4);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opJECXZ(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
CLOCK_CYCLES(5);
|
||||
if (!ECX)
|
||||
{
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CLOCK_CYCLES(4);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int opJMP_r8(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t)getbytef();
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
CX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
|
||||
if (CX && !ZF_SET()) {
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opJMP_r16(uint32_t fetchdat)
|
||||
static int
|
||||
opLOOPNE_l(uint32_t fetchdat)
|
||||
{
|
||||
int16_t offset = (int16_t)getwordf();
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
ECX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
|
||||
if (ECX && !ZF_SET()) {
|
||||
cpu_state.pc += offset;
|
||||
cpu_state.pc &= 0xffff;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opJMP_r32(uint32_t fetchdat)
|
||||
|
||||
static int
|
||||
opLOOPE_w(uint32_t fetchdat)
|
||||
{
|
||||
int32_t offset = (int32_t)getlong(); if (cpu_state.abrt) return 1;
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
CX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
|
||||
if (CX && ZF_SET()) {
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 5, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opLOOPE_l(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
ECX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
|
||||
if (ECX && ZF_SET()) {
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opJMP_far_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opLOOP_w(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint32_t old_pc;
|
||||
addr = getwordf();
|
||||
seg = getword(); if (cpu_state.abrt) return 1;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, old_pc);
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
CX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
|
||||
if (CX) {
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opJMP_far_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opLOOP_l(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t seg;
|
||||
uint32_t addr, old_pc;
|
||||
addr = getlong();
|
||||
seg = getword(); if (cpu_state.abrt) return 1;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, old_pc);
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
ECX--;
|
||||
CLOCK_CYCLES((is486) ? 7 : 11);
|
||||
PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0);
|
||||
if (ECX) {
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCALL_r16(uint32_t fetchdat)
|
||||
static int
|
||||
opJCXZ(uint32_t fetchdat)
|
||||
{
|
||||
int16_t addr = (int16_t)getwordf();
|
||||
PUSH_W(cpu_state.pc);
|
||||
cpu_state.pc += addr;
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
CLOCK_CYCLES(5);
|
||||
if (!CX) {
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CLOCK_CYCLES(4);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opJECXZ(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
CLOCK_CYCLES(5);
|
||||
if (!ECX) {
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CLOCK_CYCLES(4);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 1;
|
||||
}
|
||||
PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opJMP_r8(uint32_t fetchdat)
|
||||
{
|
||||
int8_t offset = (int8_t) getbytef();
|
||||
cpu_state.pc += offset;
|
||||
if (!(cpu_state.op32 & 0x100))
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int opCALL_r32(uint32_t fetchdat)
|
||||
static int
|
||||
opJMP_r16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t addr = getlong(); if (cpu_state.abrt) return 1;
|
||||
PUSH_L(cpu_state.pc);
|
||||
cpu_state.pc += addr;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 5, -1, 0,0,0,1, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
int16_t offset = (int16_t) getwordf();
|
||||
cpu_state.pc += offset;
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opRET_w(uint32_t fetchdat)
|
||||
static int
|
||||
opJMP_r32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
ret = POP_W(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 1, -1, 1,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
int32_t offset = (int32_t) getlong();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc += offset;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 5, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int opRET_l(uint32_t fetchdat)
|
||||
|
||||
static int
|
||||
opJMP_far_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
ret = POP_L(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 1, -1, 0,1,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
uint16_t addr, seg;
|
||||
uint32_t old_pc;
|
||||
addr = getwordf();
|
||||
seg = getword();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, old_pc);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opRET_w_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opJMP_far_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t ret;
|
||||
uint16_t offset = getwordf();
|
||||
|
||||
ret = POP_W(); if (cpu_state.abrt) return 1;
|
||||
if (stack32) ESP += offset;
|
||||
else SP += offset;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 5, -1, 1,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
uint16_t seg;
|
||||
uint32_t addr, old_pc;
|
||||
addr = getlong();
|
||||
seg = getword();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, old_pc);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int opRET_l_imm(uint32_t fetchdat)
|
||||
|
||||
static int
|
||||
opCALL_r16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint16_t offset = getwordf();
|
||||
|
||||
ret = POP_L(); if (cpu_state.abrt) return 1;
|
||||
if (stack32) ESP += offset;
|
||||
else SP += offset;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 5, -1, 0,1,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
int16_t addr = (int16_t) getwordf();
|
||||
PUSH_W(cpu_state.pc);
|
||||
cpu_state.pc += addr;
|
||||
cpu_state.pc &= 0xffff;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opCALL_r32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t addr = getlong();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
PUSH_L(cpu_state.pc);
|
||||
cpu_state.pc += addr;
|
||||
CPU_BLOCK_END();
|
||||
CLOCK_CYCLES((is486) ? 3 : 7);
|
||||
PREFETCH_RUN(7, 5, -1, 0, 0, 0, 1, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opRET_w(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
ret = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 1, -1, 1, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opRET_l(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
ret = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 1, -1, 0, 1, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opRET_w_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t ret;
|
||||
uint16_t offset = getwordf();
|
||||
|
||||
ret = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (stack32)
|
||||
ESP += offset;
|
||||
else
|
||||
SP += offset;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 5, -1, 1, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opRET_l_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint16_t offset = getwordf();
|
||||
|
||||
ret = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (stack32)
|
||||
ESP += offset;
|
||||
else
|
||||
SP += offset;
|
||||
cpu_state.pc = ret;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
CLOCK_CYCLES((is486) ? 5 : 10);
|
||||
PREFETCH_RUN(10, 5, -1, 0, 1, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,47 +3,43 @@
|
||||
#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val)))
|
||||
#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val)))
|
||||
|
||||
#define MMX_GETSRC() \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
src = cpu_state.MM[cpu_rm]; \
|
||||
CLOCK_CYCLES(1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \
|
||||
CLOCK_CYCLES(2); \
|
||||
}
|
||||
#define MMX_GETSRC() \
|
||||
if (cpu_mod == 3) { \
|
||||
src = cpu_state.MM[cpu_rm]; \
|
||||
CLOCK_CYCLES(1); \
|
||||
} else { \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
src.q = readmemq(easeg, cpu_state.eaaddr); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
CLOCK_CYCLES(2); \
|
||||
}
|
||||
|
||||
#define MMX_ENTER() \
|
||||
if (!cpu_has_feature(CPU_FEATURE_MMX)) \
|
||||
{ \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
x86illegal(); \
|
||||
return 1; \
|
||||
} \
|
||||
if (cr0 & 0xc) \
|
||||
{ \
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
x87_set_mmx()
|
||||
#define MMX_ENTER() \
|
||||
if (!cpu_has_feature(CPU_FEATURE_MMX)) { \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
x86illegal(); \
|
||||
return 1; \
|
||||
} \
|
||||
if (cr0 & 0xc) { \
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
x87_set_mmx()
|
||||
|
||||
static int opEMMS(uint32_t fetchdat)
|
||||
static int
|
||||
opEMMS(uint32_t fetchdat)
|
||||
{
|
||||
if (!cpu_has_feature(CPU_FEATURE_MMX))
|
||||
{
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
if (cr0 & 0xc)
|
||||
{
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
x87_emms();
|
||||
CLOCK_CYCLES(100); /*Guess*/
|
||||
return 0;
|
||||
if (!cpu_has_feature(CPU_FEATURE_MMX)) {
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
if (cr0 & 0xc) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
x87_emms();
|
||||
CLOCK_CYCLES(100); /*Guess*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,205 +1,217 @@
|
||||
static int opPCMPEQB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPEQB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPGTB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPGTB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0;
|
||||
cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPEQW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPEQW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPGTW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPGTW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0;
|
||||
cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPEQD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPEQD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPEQD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPGTD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPGTD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPCMPGTD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,91 +1,99 @@
|
||||
static int opPAND_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPAND_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q &= src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q &= src.q;
|
||||
return 0;
|
||||
}
|
||||
static int opPAND_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPAND_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q &= src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q &= src.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPANDN_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPANDN_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
|
||||
return 0;
|
||||
}
|
||||
static int opPANDN_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPANDN_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPOR_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q |= src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q |= src.q;
|
||||
return 0;
|
||||
}
|
||||
static int opPOR_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q |= src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q |= src.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPXOR_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPXOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q ^= src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q ^= src.q;
|
||||
return 0;
|
||||
}
|
||||
static int opPXOR_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPXOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].q ^= src.q;
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].q ^= src.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,217 +1,217 @@
|
||||
static int opMOVD_l_mm_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_l_mm_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
uint32_t dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].l[0] = dst;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmeml(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.MM[cpu_reg].l[0] = dst;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opMOVD_l_mm_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_l_mm_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
uint32_t dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].l[0] = dst;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmeml(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.MM[cpu_reg].l[0] = dst;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opMOVD_mm_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_mm_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opMOVD_mm_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_mm_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
/*Cyrix maps both MOVD and SMINT to the same opcode*/
|
||||
static int opMOVD_mm_l_a16_cx(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_mm_l_a16_cx(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
return opSMINT(fetchdat);
|
||||
if (in_smm)
|
||||
return opSMINT(fetchdat);
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opMOVD_mm_l_a32_cx(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVD_mm_l_a32_cx(uint32_t fetchdat)
|
||||
{
|
||||
if (in_smm)
|
||||
return opSMINT(fetchdat);
|
||||
if (in_smm)
|
||||
return opSMINT(fetchdat);
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opMOVQ_q_mm_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVQ_q_mm_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
uint64_t dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].q = dst;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmemq(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.MM[cpu_reg].q = dst;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opMOVQ_q_mm_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVQ_q_mm_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q;
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
uint64_t dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].q = dst;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmemq(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.MM[cpu_reg].q = dst;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opMOVQ_mm_q_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVQ_mm_q_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opMOVQ_mm_q_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVQ_mm_q_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q;
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,326 +1,342 @@
|
||||
static int opPUNPCKLDQ_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLDQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
uint32_t src;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = src;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = readmeml(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = src;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int opPUNPCKLDQ_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLDQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3)
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t src;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod == 3) {
|
||||
cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0];
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
uint32_t src;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = src;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = readmeml(easeg, cpu_state.eaaddr);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = src;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPUNPCKHDQ_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHDQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
|
||||
cpu_state.MM[cpu_reg].l[1] = src.l[1];
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
|
||||
cpu_state.MM[cpu_reg].l[1] = src.l[1];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPUNPCKHDQ_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHDQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
|
||||
cpu_state.MM[cpu_reg].l[1] = src.l[1];
|
||||
cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1];
|
||||
cpu_state.MM[cpu_reg].l[1] = src.l[1];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPUNPCKLBW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[3];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[2];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[1];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[0];
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[3];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[2];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[1];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[0];
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPUNPCKLBW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[3];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[2];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[1];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[0];
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[3];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[2];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[1];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[0];
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPUNPCKHBW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[4];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[5];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[6];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[7];
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[4];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[5];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[6];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[7];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPUNPCKHBW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[4];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[5];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[6];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[7];
|
||||
cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4];
|
||||
cpu_state.MM[cpu_reg].b[1] = src.b[4];
|
||||
cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5];
|
||||
cpu_state.MM[cpu_reg].b[3] = src.b[5];
|
||||
cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6];
|
||||
cpu_state.MM[cpu_reg].b[5] = src.b[6];
|
||||
cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7];
|
||||
cpu_state.MM[cpu_reg].b[7] = src.b[7];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPUNPCKLWD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[1];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[0];
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[1];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[0];
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPUNPCKLWD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKLWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[1];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[0];
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[1];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[0];
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPUNPCKHWD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[2];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[3];
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[2];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[3];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPUNPCKHWD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPUNPCKHWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[2];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[3];
|
||||
cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2];
|
||||
cpu_state.MM[cpu_reg].w[1] = src.w[2];
|
||||
cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3];
|
||||
cpu_state.MM[cpu_reg].w[3] = src.w[3];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPACKSSWB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSWB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
|
||||
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
|
||||
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPACKSSWB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSWB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
|
||||
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
|
||||
cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPACKUSWB_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKUSWB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
|
||||
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPACKUSWB_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKUSWB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
|
||||
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
|
||||
cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]);
|
||||
cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]);
|
||||
cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]);
|
||||
cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]);
|
||||
cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPACKSSDW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSDW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
|
||||
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
|
||||
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
|
||||
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
|
||||
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPACKSSDW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPACKSSDW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = cpu_state.MM[cpu_reg];
|
||||
|
||||
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
|
||||
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
|
||||
cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]);
|
||||
cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]);
|
||||
cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,450 +1,453 @@
|
||||
#define MMX_GETSHIFT() \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
shift = cpu_state.MM[cpu_rm].b[0]; \
|
||||
CLOCK_CYCLES(1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \
|
||||
CLOCK_CYCLES(2); \
|
||||
}
|
||||
#define MMX_GETSHIFT() \
|
||||
if (cpu_mod == 3) { \
|
||||
shift = cpu_state.MM[cpu_rm].b[0]; \
|
||||
CLOCK_CYCLES(1); \
|
||||
} else { \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
shift = readmemb(easeg, cpu_state.eaaddr); \
|
||||
if (cpu_state.abrt) \
|
||||
return 0; \
|
||||
CLOCK_CYCLES(2); \
|
||||
}
|
||||
|
||||
static int opPSxxW_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opPSxxW_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
|
||||
cpu_state.pc += 2;
|
||||
MMX_ENTER();
|
||||
cpu_state.pc += 2;
|
||||
MMX_ENTER();
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x10: /*PSRLW*/
|
||||
if (shift > 15)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[reg].w[0] >>= shift;
|
||||
cpu_state.MM[reg].w[1] >>= shift;
|
||||
cpu_state.MM[reg].w[2] >>= shift;
|
||||
cpu_state.MM[reg].w[3] >>= shift;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
cpu_state.MM[reg].sw[0] >>= shift;
|
||||
cpu_state.MM[reg].sw[1] >>= shift;
|
||||
cpu_state.MM[reg].sw[2] >>= shift;
|
||||
cpu_state.MM[reg].sw[3] >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
if (shift > 15)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[reg].w[0] <<= shift;
|
||||
cpu_state.MM[reg].w[1] <<= shift;
|
||||
cpu_state.MM[reg].w[2] <<= shift;
|
||||
cpu_state.MM[reg].w[3] <<= shift;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSLLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].w[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPSLLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].w[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSRLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].w[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPSRLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].w[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSRAW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
switch (op) {
|
||||
case 0x10: /*PSRLW*/
|
||||
if (shift > 15)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[reg].w[0] >>= shift;
|
||||
cpu_state.MM[reg].w[1] >>= shift;
|
||||
cpu_state.MM[reg].w[2] >>= shift;
|
||||
cpu_state.MM[reg].w[3] >>= shift;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
cpu_state.MM[reg].sw[0] >>= shift;
|
||||
cpu_state.MM[reg].sw[1] >>= shift;
|
||||
cpu_state.MM[reg].sw[2] >>= shift;
|
||||
cpu_state.MM[reg].sw[3] >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
if (shift > 15)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[reg].w[0] <<= shift;
|
||||
cpu_state.MM[reg].w[1] <<= shift;
|
||||
cpu_state.MM[reg].w[2] <<= shift;
|
||||
cpu_state.MM[reg].w[3] <<= shift;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpu_state.MM[cpu_reg].sw[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[3] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPSRAW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
|
||||
cpu_state.MM[cpu_reg].sw[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[3] >>= shift;
|
||||
|
||||
return 0;
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSxxD_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opPSLLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
int shift;
|
||||
|
||||
cpu_state.pc += 2;
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x10: /*PSRLD*/
|
||||
if (shift > 31)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[reg].l[0] >>= shift;
|
||||
cpu_state.MM[reg].l[1] >>= shift;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*PSRAD*/
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
cpu_state.MM[reg].sl[0] >>= shift;
|
||||
cpu_state.MM[reg].sl[1] >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLD*/
|
||||
if (shift > 31)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[reg].l[0] <<= shift;
|
||||
cpu_state.MM[reg].l[1] <<= shift;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].w[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPSLLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].w[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] <<= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSLLD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] <<= shift;
|
||||
}
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].w[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPSLLD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] <<= shift;
|
||||
}
|
||||
if (shift > 15)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].w[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].w[3] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSRLD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRAW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] >>= shift;
|
||||
}
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].sw[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[3] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPSRLD_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRAW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
{
|
||||
cpu_state.MM[cpu_reg].l[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] >>= shift;
|
||||
}
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].sw[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[1] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[2] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sw[3] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSRAD_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSxxD_imm(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
|
||||
MMX_ENTER();
|
||||
cpu_state.pc += 2;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
switch (op) {
|
||||
case 0x10: /*PSRLD*/
|
||||
if (shift > 31)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[reg].l[0] >>= shift;
|
||||
cpu_state.MM[reg].l[1] >>= shift;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*PSRAD*/
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
cpu_state.MM[reg].sl[0] >>= shift;
|
||||
cpu_state.MM[reg].sl[1] >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLD*/
|
||||
if (shift > 31)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[reg].l[0] <<= shift;
|
||||
cpu_state.MM[reg].l[1] <<= shift;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpu_state.MM[cpu_reg].sl[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sl[1] >>= shift;
|
||||
|
||||
return 0;
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
static int opPSRAD_a32(uint32_t fetchdat)
|
||||
|
||||
static int
|
||||
opPSLLD_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].l[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] <<= shift;
|
||||
}
|
||||
|
||||
cpu_state.MM[cpu_reg].sl[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sl[1] >>= shift;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSxxQ_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opPSLLD_a32(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
int shift;
|
||||
|
||||
cpu_state.pc += 2;
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x10: /*PSRLW*/
|
||||
if (shift > 63)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[reg].q >>= shift;
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
if (shift > 63)
|
||||
shift = 63;
|
||||
cpu_state.MM[reg].sq >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
if (shift > 63)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[reg].q <<= shift;
|
||||
break;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].l[0] <<= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSLLQ_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRLD_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q <<= shift;
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].l[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
static int opPSLLQ_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRLD_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q <<= shift;
|
||||
if (shift > 31)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else {
|
||||
cpu_state.MM[cpu_reg].l[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].l[1] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPSRLQ_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRAD_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q >>= shift;
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].sl[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sl[1] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPSRLQ_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPSRAD_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q >>= shift;
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
|
||||
return 0;
|
||||
cpu_state.MM[cpu_reg].sl[0] >>= shift;
|
||||
cpu_state.MM[cpu_reg].sl[1] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opPSxxQ_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
|
||||
cpu_state.pc += 2;
|
||||
MMX_ENTER();
|
||||
|
||||
switch (op) {
|
||||
case 0x10: /*PSRLW*/
|
||||
if (shift > 63)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[reg].q >>= shift;
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
if (shift > 63)
|
||||
shift = 63;
|
||||
cpu_state.MM[reg].sq >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
if (shift > 63)
|
||||
cpu_state.MM[reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[reg].q <<= shift;
|
||||
break;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opPSLLQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q <<= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPSLLQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q <<= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opPSRLQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPSRLQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
cpu_state.MM[cpu_reg].q = 0;
|
||||
else
|
||||
cpu_state.MM[cpu_reg].q >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,368 +1,362 @@
|
||||
static int opMOV_r_CRx_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_r_CRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg)
|
||||
{
|
||||
case 0:
|
||||
cpu_state.regs[cpu_rm].l = cr0;
|
||||
if (is486 || isibm486)
|
||||
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
|
||||
else {
|
||||
if (is386)
|
||||
cpu_state.regs[cpu_rm].l |=0x7fffffe0;
|
||||
else
|
||||
cpu_state.regs[cpu_rm].l |=0x7ffffff0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.regs[cpu_rm].l = cr2;
|
||||
break;
|
||||
case 3:
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_r_CRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg)
|
||||
{
|
||||
case 0:
|
||||
cpu_state.regs[cpu_rm].l = cr0;
|
||||
if (is486 || isibm486)
|
||||
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
|
||||
else {
|
||||
if (is386)
|
||||
cpu_state.regs[cpu_rm].l |=0x7fffffe0;
|
||||
else
|
||||
cpu_state.regs[cpu_rm].l |=0x7ffffff0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.regs[cpu_rm].l = cr2;
|
||||
break;
|
||||
case 3:
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_r_DRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opMOV_CRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg)
|
||||
{
|
||||
case 0:
|
||||
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
|
||||
flushmmucache();
|
||||
/* Make sure CPL = 0 when switching from real mode to protected mode. */
|
||||
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
|
||||
cpu_state.seg_cs.access &= 0x9f;
|
||||
cr0 = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_16bitbus)
|
||||
cr0 |= 0x10;
|
||||
if (!(cr0 & 0x80000000))
|
||||
mmu_perm=4;
|
||||
if (hascache && !(cr0 & (1 << 30)))
|
||||
cpu_cache_int_enabled = 1;
|
||||
else
|
||||
cpu_cache_int_enabled = 0;
|
||||
if (hascache && ((cr0 ^ old_cr0) & (1 << 30)))
|
||||
cpu_update_waitstates();
|
||||
if (cr0 & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
cpu_state.regs[cpu_rm].l = cr0;
|
||||
if (is486 || isibm486)
|
||||
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
|
||||
else {
|
||||
if (is386)
|
||||
cpu_state.regs[cpu_rm].l |= 0x7fffffe0;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
cpu_state.regs[cpu_rm].l |= 0x7ffffff0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.regs[cpu_rm].l = cr2;
|
||||
break;
|
||||
case 3:
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
case 2:
|
||||
cr2 = cpu_state.regs[cpu_rm].l;
|
||||
}
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_r_CRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
cpu_state.regs[cpu_rm].l = cr0;
|
||||
if (is486 || isibm486)
|
||||
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
|
||||
else {
|
||||
if (is386)
|
||||
cpu_state.regs[cpu_rm].l |= 0x7fffffe0;
|
||||
else
|
||||
cpu_state.regs[cpu_rm].l |= 0x7ffffff0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.regs[cpu_rm].l = cr2;
|
||||
break;
|
||||
case 3:
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
case 3:
|
||||
cr3 = cpu_state.regs[cpu_rm].l;
|
||||
}
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_r_DRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0);
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opMOV_CRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
|
||||
flushmmucache();
|
||||
/* Make sure CPL = 0 when switching from real mode to protected mode. */
|
||||
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
|
||||
cpu_state.seg_cs.access &= 0x9f;
|
||||
cr0 = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_16bitbus)
|
||||
cr0 |= 0x10;
|
||||
if (!(cr0 & 0x80000000))
|
||||
mmu_perm = 4;
|
||||
if (hascache && !(cr0 & (1 << 30)))
|
||||
cpu_cache_int_enabled = 1;
|
||||
else
|
||||
cpu_cache_int_enabled = 0;
|
||||
if (hascache && ((cr0 ^ old_cr0) & (1 << 30)))
|
||||
cpu_update_waitstates();
|
||||
if (cr0 & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
break;
|
||||
case 2:
|
||||
cr2 = cpu_state.regs[cpu_rm].l;
|
||||
break;
|
||||
case 3:
|
||||
cr3 = cpu_state.regs[cpu_rm].l;
|
||||
flushmmucache();
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE)
|
||||
flushmmucache();
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE)
|
||||
flushmmucache();
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_CRx_r_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_CRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg)
|
||||
{
|
||||
case 0:
|
||||
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
|
||||
flushmmucache();
|
||||
/* Make sure CPL = 0 when switching from real mode to protected mode. */
|
||||
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
|
||||
cpu_state.seg_cs.access &= 0x9f;
|
||||
cr0 = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_16bitbus)
|
||||
cr0 |= 0x10;
|
||||
if (!(cr0 & 0x80000000))
|
||||
mmu_perm=4;
|
||||
if (hascache && !(cr0 & (1 << 30)))
|
||||
cpu_cache_int_enabled = 1;
|
||||
else
|
||||
cpu_cache_int_enabled = 0;
|
||||
if (hascache && ((cr0 ^ old_cr0) & (1 << 30)))
|
||||
cpu_update_waitstates();
|
||||
if (cr0 & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
break;
|
||||
case 2:
|
||||
cr2 = cpu_state.regs[cpu_rm].l;
|
||||
break;
|
||||
case 3:
|
||||
cr3 = cpu_state.regs[cpu_rm].l;
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
|
||||
flushmmucache();
|
||||
/* Make sure CPL = 0 when switching from real mode to protected mode. */
|
||||
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
|
||||
cpu_state.seg_cs.access &= 0x9f;
|
||||
cr0 = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_16bitbus)
|
||||
cr0 |= 0x10;
|
||||
if (!(cr0 & 0x80000000))
|
||||
mmu_perm = 4;
|
||||
if (hascache && !(cr0 & (1 << 30)))
|
||||
cpu_cache_int_enabled = 1;
|
||||
else
|
||||
cpu_cache_int_enabled = 0;
|
||||
if (hascache && ((cr0 ^ old_cr0) & (1 << 30)))
|
||||
cpu_update_waitstates();
|
||||
if (cr0 & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
break;
|
||||
case 2:
|
||||
cr2 = cpu_state.regs[cpu_rm].l;
|
||||
break;
|
||||
case 3:
|
||||
cr3 = cpu_state.regs[cpu_rm].l;
|
||||
flushmmucache();
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE)
|
||||
flushmmucache();
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE)
|
||||
flushmmucache();
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
}
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
opMOV_r_TRx(void)
|
||||
{
|
||||
uint32_t base;
|
||||
|
||||
base = _tr[4] & 0xfffff800;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
_tr[3] = *(uint32_t *) &(_cache[cache_index]);
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
}
|
||||
cpu_state.regs[cpu_rm].l = _tr[cpu_reg];
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
static int
|
||||
opMOV_r_TRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_r_TRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
opMOV_TRx_r(void)
|
||||
{
|
||||
uint32_t base;
|
||||
int i, ctl;
|
||||
|
||||
_tr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
base = _tr[4] & 0xfffff800;
|
||||
ctl = _tr[5] & 3;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
*(uint32_t *) &(_cache[cache_index]) = _tr[3];
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
case 4:
|
||||
if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
|
||||
pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
|
||||
break;
|
||||
case 5:
|
||||
pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
|
||||
if (!(_tr[5] & (1 << 19))) {
|
||||
switch (ctl) {
|
||||
case 0:
|
||||
pclog(" Cache fill or read...\n", base);
|
||||
break;
|
||||
case 1:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
pclog(" Writing 16 bytes to %08X...\n", base);
|
||||
for (i = 0; i < 16; i += 4)
|
||||
mem_writel_phys(base + i, *(uint32_t *) &(_cache[i]));
|
||||
break;
|
||||
case 2:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
pclog(" Reading 16 bytes from %08X...\n", base);
|
||||
for (i = 0; i < 16; i += 4)
|
||||
*(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i);
|
||||
break;
|
||||
case 3:
|
||||
pclog(" Cache invalidate/flush...\n", base);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
|
||||
static int opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_TRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_TRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void opMOV_r_TRx(void)
|
||||
{
|
||||
uint32_t base;
|
||||
|
||||
base = _tr[4] & 0xfffff800;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
_tr[3] = *(uint32_t *) &(_cache[cache_index]);
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
}
|
||||
cpu_state.regs[cpu_rm].l = _tr[cpu_reg];
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
static int opMOV_r_TRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_r_TRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void opMOV_TRx_r(void)
|
||||
{
|
||||
uint32_t base;
|
||||
int i, ctl;
|
||||
|
||||
_tr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
base = _tr[4] & 0xfffff800;
|
||||
ctl = _tr[5] & 3;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
*(uint32_t *) &(_cache[cache_index]) = _tr[3];
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
case 4:
|
||||
if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
|
||||
pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
|
||||
break;
|
||||
case 5:
|
||||
pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
|
||||
if (!(_tr[5] & (1 << 19))) {
|
||||
switch(ctl) {
|
||||
case 0:
|
||||
pclog(" Cache fill or read...\n", base);
|
||||
break;
|
||||
case 1:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
pclog(" Writing 16 bytes to %08X...\n", base);
|
||||
for (i = 0; i < 16; i += 4)
|
||||
mem_writel_phys(base + i, *(uint32_t *) &(_cache[i]));
|
||||
break;
|
||||
case 2:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
pclog(" Reading 16 bytes from %08X...\n", base);
|
||||
for (i = 0; i < 16; i += 4)
|
||||
*(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i);
|
||||
break;
|
||||
case 3:
|
||||
pclog(" Cache invalidate/flush...\n", base);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
static int opMOV_TRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOV_TRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,445 +1,532 @@
|
||||
static int opMOV_w_seg_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_w_seg_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
seteaw(ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
seteaw(FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
seteaw(GS);
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int
|
||||
opMOV_w_seg_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
seteaw(ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
seteaw(FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
seteaw(GS);
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opMOV_l_seg_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = ES;
|
||||
else
|
||||
seteaw(ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = CS;
|
||||
else
|
||||
seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = DS;
|
||||
else
|
||||
seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = SS;
|
||||
else
|
||||
seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = FS;
|
||||
else
|
||||
seteaw(FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = GS;
|
||||
else
|
||||
seteaw(GS);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
return cpu_state.abrt;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opMOV_w_seg_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_l_seg_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = ES;
|
||||
else
|
||||
seteaw(ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = CS;
|
||||
else
|
||||
seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = DS;
|
||||
else
|
||||
seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = SS;
|
||||
else
|
||||
seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = FS;
|
||||
else
|
||||
seteaw(FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
if (cpu_mod == 3)
|
||||
cpu_state.regs[cpu_rm].l = GS;
|
||||
else
|
||||
seteaw(GS);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
return cpu_state.abrt;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opMOV_l_seg_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_seg_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
uint16_t new_seg;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES;
|
||||
else seteaw(ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS;
|
||||
else seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS;
|
||||
else seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS;
|
||||
else seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS;
|
||||
else seteaw(FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS;
|
||||
else seteaw(GS);
|
||||
break;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_seg = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opMOV_l_seg_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES;
|
||||
else seteaw(ES);
|
||||
break;
|
||||
case 0x08: /*CS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS;
|
||||
else seteaw(CS);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS;
|
||||
else seteaw(DS);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS;
|
||||
else seteaw(SS);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS;
|
||||
else seteaw(FS);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS;
|
||||
else seteaw(GS);
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opMOV_seg_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t new_seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_seg=geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t new_seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_seg=geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
return cpu_state.abrt;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
|
||||
static int opLDS_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint16_t new_seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opLDS_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opLDS_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opLDS_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opLSS_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0);
|
||||
new_seg = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opLSS_w_a32(uint32_t fetchdat)
|
||||
|
||||
static int
|
||||
opLDS_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint16_t addr, seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1);
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opLSS_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opLDS_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
uint16_t addr, seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0);
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opLSS_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opLDS_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1);
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opLDS_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define opLsel(name, sel) \
|
||||
static int opL ## name ## _w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t addr, seg; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
addr = readmemw(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
|
||||
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].w = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opL ## name ## _w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t addr, seg; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
addr = readmemw(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
|
||||
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].w = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opL ## name ## _l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t addr; \
|
||||
uint16_t seg; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \
|
||||
addr = readmeml(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
|
||||
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].l = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opL ## name ## _l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t addr; \
|
||||
uint16_t seg; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \
|
||||
addr = readmeml(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
|
||||
loadseg(seg, &sel); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].l = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); \
|
||||
return 0; \
|
||||
}
|
||||
static int
|
||||
opLSS_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
static int
|
||||
opLSS_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
|
||||
return 1;
|
||||
}
|
||||
static int
|
||||
opLSS_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
static int
|
||||
opLSS_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define opLsel(name, sel) \
|
||||
static int opL##name##_w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t addr, seg; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
addr = readmemw(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opL##name##_w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t addr, seg; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \
|
||||
addr = readmemw(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opL##name##_l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t addr; \
|
||||
uint16_t seg; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \
|
||||
addr = readmeml(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int opL##name##_l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t addr; \
|
||||
uint16_t seg; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \
|
||||
addr = readmeml(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = addr; \
|
||||
\
|
||||
CLOCK_CYCLES(7); \
|
||||
PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
opLsel(ES, cpu_state.seg_es)
|
||||
opLsel(FS, cpu_state.seg_fs)
|
||||
|
||||
@@ -1,209 +1,251 @@
|
||||
static int opMOVZX_w_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_w_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t) temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVZX_w_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_w_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t) temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVZX_l_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_l_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVZX_l_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_l_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVZX_w_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_w_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVZX_w_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_w_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVZX_l_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_l_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVZX_l_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVZX_l_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opMOVSX_w_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVSX_w_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].w |= 0xff00;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t) temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].w |= 0xff00;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVSX_w_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVSX_w_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].w |= 0xff00;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t) temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].w |= 0xff00;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVSX_l_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVSX_l_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffffff00;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffffff00;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVSX_l_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVSX_l_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffffff00;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
if (temp & 0x80)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffffff00;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVSX_l_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVSX_l_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x8000)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffff0000;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
if (temp & 0x8000)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffff0000;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opMOVSX_l_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opMOVSX_l_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x8000)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffff0000;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t) temp;
|
||||
if (temp & 0x8000)
|
||||
cpu_state.regs[cpu_reg].l |= 0xffff0000;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
static int opRDTSC(uint32_t fetchdat)
|
||||
static int
|
||||
opRDTSC(uint32_t fetchdat)
|
||||
{
|
||||
if (!cpu_has_feature(CPU_FEATURE_RDTSC))
|
||||
{
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
if ((cr4 & CR4_TSD) && CPL)
|
||||
{
|
||||
x86gpf("RDTSC when TSD set and CPL != 0", 0);
|
||||
return 1;
|
||||
}
|
||||
EAX = tsc & 0xffffffff;
|
||||
EDX = tsc >> 32;
|
||||
CLOCK_CYCLES(1);
|
||||
if (!cpu_has_feature(CPU_FEATURE_RDTSC)) {
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
if ((cr4 & CR4_TSD) && CPL) {
|
||||
x86gpf("RDTSC when TSD set and CPL != 0", 0);
|
||||
return 1;
|
||||
}
|
||||
EAX = tsc & 0xffffffff;
|
||||
EDX = tsc >> 32;
|
||||
CLOCK_CYCLES(1);
|
||||
#ifdef USE_DYNAREC
|
||||
if (cpu_use_dynarec)
|
||||
update_tsc();
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opRDPMC(uint32_t fetchdat)
|
||||
static int
|
||||
opRDPMC(uint32_t fetchdat)
|
||||
{
|
||||
if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL))
|
||||
{
|
||||
x86gpf("RDPMC not allowed", 0);
|
||||
return 1;
|
||||
}
|
||||
EAX = EDX = 0;
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) {
|
||||
x86gpf("RDPMC not allowed", 0);
|
||||
return 1;
|
||||
}
|
||||
EAX = EDX = 0;
|
||||
CLOCK_CYCLES(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,263 +1,337 @@
|
||||
static int opIMUL_w_iw_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_w_iw_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getword(); if (cpu_state.abrt) return 1;
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempw2 = getword();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
templ = ((int) tempw) * ((int) tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opIMUL_w_iw_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_w_iw_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getword(); if (cpu_state.abrt) return 1;
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempw2 = getword();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
templ = ((int) tempw) * ((int) tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opIMUL_l_il_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_l_il_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getlong(); if (cpu_state.abrt) return 1;
|
||||
templ = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
templ2 = getlong();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
temp64 = ((int64_t)templ) * ((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
temp64 = ((int64_t) templ) * ((int64_t) templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(25);
|
||||
PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(25);
|
||||
PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opIMUL_l_il_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_l_il_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getlong(); if (cpu_state.abrt) return 1;
|
||||
templ = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
templ2 = getlong();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
temp64 = ((int64_t)templ) * ((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
temp64 = ((int64_t) templ) * ((int64_t) templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(25);
|
||||
PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(25);
|
||||
PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opIMUL_w_ib_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_w_ib_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (tempw2 & 0x80) tempw2 |= 0xff00;
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempw2 = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (tempw2 & 0x80)
|
||||
tempw2 |= 0xff00;
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
templ = ((int) tempw) * ((int) tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opIMUL_w_ib_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_w_ib_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
int32_t templ;
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (tempw2 & 0x80) tempw2 |= 0xff00;
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tempw2 = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (tempw2 & 0x80)
|
||||
tempw2 |= 0xff00;
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
templ = ((int) tempw) * ((int) tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opIMUL_l_ib_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_l_ib_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (templ2 & 0x80) templ2 |= 0xffffff00;
|
||||
templ = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
templ2 = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (templ2 & 0x80)
|
||||
templ2 |= 0xffffff00;
|
||||
|
||||
temp64 = ((int64_t)templ)*((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
temp64 = ((int64_t) templ) * ((int64_t) templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opIMUL_l_ib_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_l_ib_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
int64_t temp64;
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (templ2 & 0x80) templ2 |= 0xffffff00;
|
||||
templ = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
templ2 = getbyte();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (templ2 & 0x80)
|
||||
templ2 |= 0xffffff00;
|
||||
|
||||
temp64 = ((int64_t)templ)*((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
temp64 = ((int64_t) templ) * ((int64_t) templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int opIMUL_w_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_w_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int32_t templ;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(18);
|
||||
PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(18);
|
||||
PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opIMUL_w_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_w_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
int32_t templ;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(18);
|
||||
PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(18);
|
||||
PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opIMUL_l_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_l_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int64_t temp64;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(30);
|
||||
PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(30);
|
||||
PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opIMUL_l_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opIMUL_l_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
int64_t temp64;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1)
|
||||
cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(30);
|
||||
PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(30);
|
||||
PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,460 +1,513 @@
|
||||
static int opARPL_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opARPL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp_seg;
|
||||
uint16_t temp_seg;
|
||||
|
||||
NOTRM
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
|
||||
NOTRM
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp_seg = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
flags_rebuild();
|
||||
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3))
|
||||
{
|
||||
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
|
||||
seteaw(temp_seg); if (cpu_state.abrt) return 1;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
}
|
||||
else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
flags_rebuild();
|
||||
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) {
|
||||
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
|
||||
seteaw(temp_seg);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
|
||||
CLOCK_CYCLES(is486 ? 9 : 20);
|
||||
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(is486 ? 9 : 20);
|
||||
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opARPL_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opARPL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp_seg;
|
||||
uint16_t temp_seg;
|
||||
|
||||
NOTRM
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
|
||||
NOTRM
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp_seg = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
flags_rebuild();
|
||||
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3))
|
||||
{
|
||||
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
|
||||
seteaw(temp_seg); if (cpu_state.abrt) return 1;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
}
|
||||
else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
flags_rebuild();
|
||||
if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) {
|
||||
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
|
||||
seteaw(temp_seg);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
} else
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
|
||||
CLOCK_CYCLES(is486 ? 9 : 20);
|
||||
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1);
|
||||
return 0;
|
||||
CLOCK_CYCLES(is486 ? 9 : 20);
|
||||
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define opLAR(name, fetch_ea, is32, ea32) \
|
||||
static int opLAR_ ## name(uint32_t fetchdat) \
|
||||
{ \
|
||||
int valid; \
|
||||
uint16_t sel, desc = 0; \
|
||||
\
|
||||
NOTRM \
|
||||
fetch_ea(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
\
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
flags_rebuild(); \
|
||||
if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
|
||||
if (valid) \
|
||||
{ \
|
||||
cpl_override = 1; \
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
|
||||
cpl_override = 0; if (cpu_state.abrt) return 1; \
|
||||
} \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
if ((desc & 0x1f00) == 0x000) valid = 0; \
|
||||
if ((desc & 0x1f00) == 0x800) valid = 0; \
|
||||
if ((desc & 0x1f00) == 0xa00) valid = 0; \
|
||||
if ((desc & 0x1f00) == 0xd00) valid = 0; \
|
||||
if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \
|
||||
{ \
|
||||
int dpl = (desc >> 13) & 3; \
|
||||
if (dpl < CPL || dpl < (sel & 3)) valid = 0; \
|
||||
} \
|
||||
if (valid) \
|
||||
{ \
|
||||
cpu_state.flags |= Z_FLAG; \
|
||||
cpl_override = 1; \
|
||||
if (is32) \
|
||||
cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \
|
||||
else \
|
||||
cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \
|
||||
cpl_override = 0; \
|
||||
} \
|
||||
CLOCK_CYCLES(11); \
|
||||
PREFETCH_RUN(11, 2, rmdat, 2,0,0,0, ea32); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
#define opLAR(name, fetch_ea, is32, ea32) \
|
||||
static int opLAR_##name(uint32_t fetchdat) \
|
||||
{ \
|
||||
int valid; \
|
||||
uint16_t sel, desc = 0; \
|
||||
\
|
||||
NOTRM \
|
||||
fetch_ea(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
\
|
||||
sel = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
\
|
||||
flags_rebuild(); \
|
||||
if (!(sel & 0xfffc)) { \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
return 0; \
|
||||
} /*Null selector*/ \
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
|
||||
if (valid) { \
|
||||
cpl_override = 1; \
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
|
||||
cpl_override = 0; \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
} \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
if ((desc & 0x1f00) == 0x000) \
|
||||
valid = 0; \
|
||||
if ((desc & 0x1f00) == 0x800) \
|
||||
valid = 0; \
|
||||
if ((desc & 0x1f00) == 0xa00) \
|
||||
valid = 0; \
|
||||
if ((desc & 0x1f00) == 0xd00) \
|
||||
valid = 0; \
|
||||
if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \
|
||||
{ \
|
||||
int dpl = (desc >> 13) & 3; \
|
||||
if (dpl < CPL || dpl < (sel & 3)) \
|
||||
valid = 0; \
|
||||
} \
|
||||
if (valid) { \
|
||||
cpu_state.flags |= Z_FLAG; \
|
||||
cpl_override = 1; \
|
||||
if (is32) \
|
||||
cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \
|
||||
else \
|
||||
cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \
|
||||
cpl_override = 0; \
|
||||
} \
|
||||
CLOCK_CYCLES(11); \
|
||||
PREFETCH_RUN(11, 2, rmdat, 2, 0, 0, 0, ea32); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
opLAR(w_a16, fetch_ea_16, 0, 0)
|
||||
opLAR(w_a32, fetch_ea_32, 0, 1)
|
||||
opLAR(l_a16, fetch_ea_16, 1, 0)
|
||||
opLAR(l_a32, fetch_ea_32, 1, 1)
|
||||
opLAR(w_a32, fetch_ea_32, 0, 1)
|
||||
opLAR(l_a16, fetch_ea_16, 1, 0)
|
||||
opLAR(l_a32, fetch_ea_32, 1, 1)
|
||||
|
||||
#define opLSL(name, fetch_ea, is32, ea32) \
|
||||
static int opLSL_ ## name(uint32_t fetchdat) \
|
||||
{ \
|
||||
int valid; \
|
||||
uint16_t sel, desc = 0; \
|
||||
\
|
||||
NOTRM \
|
||||
fetch_ea(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
\
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
if (!(sel & 0xfffc)) return 0; /*Null selector*/ \
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
|
||||
if (valid) \
|
||||
{ \
|
||||
cpl_override = 1; \
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
|
||||
cpl_override = 0; if (cpu_state.abrt) return 1; \
|
||||
} \
|
||||
if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \
|
||||
if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \
|
||||
if ((desc & 0x1f00) == 0xa00) valid = 0; /*Invalid*/ \
|
||||
if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \
|
||||
{ \
|
||||
int rpl = (desc >> 13) & 3; \
|
||||
if (rpl < CPL || rpl < (sel & 3)) valid = 0; \
|
||||
} \
|
||||
if (valid) \
|
||||
{ \
|
||||
cpu_state.flags |= Z_FLAG; \
|
||||
cpl_override = 1; \
|
||||
if (is32) \
|
||||
{ \
|
||||
cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
|
||||
cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \
|
||||
if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) \
|
||||
{ \
|
||||
cpu_state.regs[cpu_reg].l <<= 12; \
|
||||
cpu_state.regs[cpu_reg].l |= 0xFFF; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
|
||||
cpl_override = 0; \
|
||||
} \
|
||||
CLOCK_CYCLES(10); \
|
||||
PREFETCH_RUN(10, 2, rmdat, 4,0,0,0, ea32); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
#define opLSL(name, fetch_ea, is32, ea32) \
|
||||
static int opLSL_##name(uint32_t fetchdat) \
|
||||
{ \
|
||||
int valid; \
|
||||
uint16_t sel, desc = 0; \
|
||||
\
|
||||
NOTRM \
|
||||
fetch_ea(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
\
|
||||
sel = geteaw(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
flags_rebuild(); \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
if (!(sel & 0xfffc)) \
|
||||
return 0; /*Null selector*/ \
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
|
||||
if (valid) { \
|
||||
cpl_override = 1; \
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
|
||||
cpl_override = 0; \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
} \
|
||||
if ((desc & 0x1400) == 0x400) \
|
||||
valid = 0; /*Interrupt or trap or call gate*/ \
|
||||
if ((desc & 0x1f00) == 0x000) \
|
||||
valid = 0; /*Invalid*/ \
|
||||
if ((desc & 0x1f00) == 0xa00) \
|
||||
valid = 0; /*Invalid*/ \
|
||||
if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \
|
||||
{ \
|
||||
int rpl = (desc >> 13) & 3; \
|
||||
if (rpl < CPL || rpl < (sel & 3)) \
|
||||
valid = 0; \
|
||||
} \
|
||||
if (valid) { \
|
||||
cpu_state.flags |= Z_FLAG; \
|
||||
cpl_override = 1; \
|
||||
if (is32) { \
|
||||
cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
|
||||
cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \
|
||||
if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) { \
|
||||
cpu_state.regs[cpu_reg].l <<= 12; \
|
||||
cpu_state.regs[cpu_reg].l |= 0xFFF; \
|
||||
} \
|
||||
} else \
|
||||
cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \
|
||||
cpl_override = 0; \
|
||||
} \
|
||||
CLOCK_CYCLES(10); \
|
||||
PREFETCH_RUN(10, 2, rmdat, 4, 0, 0, 0, ea32); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
opLSL(w_a16, fetch_ea_16, 0, 0)
|
||||
opLSL(w_a32, fetch_ea_32, 0, 1)
|
||||
opLSL(l_a16, fetch_ea_16, 1, 0)
|
||||
opLSL(l_a32, fetch_ea_32, 1, 1)
|
||||
opLSL(w_a16, fetch_ea_16, 0, 0)
|
||||
opLSL(w_a32, fetch_ea_32, 0, 1)
|
||||
opLSL(l_a16, fetch_ea_16, 1, 0)
|
||||
opLSL(l_a32, fetch_ea_32, 1, 1)
|
||||
|
||||
|
||||
static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
{
|
||||
int dpl, valid, granularity;
|
||||
uint32_t addr, base, limit;
|
||||
uint16_t desc, sel;
|
||||
uint8_t access, ar_high;
|
||||
int dpl, valid, granularity;
|
||||
uint32_t addr, base, limit;
|
||||
uint16_t desc, sel;
|
||||
uint8_t access, ar_high;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*SLDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(ldt.seg);
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*SLDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(ldt.seg);
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
|
||||
break;
|
||||
case 0x08: /*STR*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(tr.seg);
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
|
||||
break;
|
||||
case 0x10: /*LLDT*/
|
||||
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
addr = (sel & ~7) + gdt.base;
|
||||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
|
||||
access = readmemb(0, addr + 5);
|
||||
ar_high = readmemb(0, addr + 6);
|
||||
granularity = readmemb(0, addr + 6) & 0x80;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
ldt.limit = limit;
|
||||
ldt.access = access;
|
||||
ldt.ar_high = ar_high;
|
||||
if (granularity) {
|
||||
ldt.limit <<= 12;
|
||||
ldt.limit |= 0xfff;
|
||||
}
|
||||
ldt.base = base;
|
||||
ldt.seg = sel;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32);
|
||||
break;
|
||||
case 0x18: /*LTR*/
|
||||
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
case 0x08: /*STR*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(tr.seg);
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
|
||||
break;
|
||||
case 0x10: /*LLDT*/
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
addr = (sel & ~7) + gdt.base;
|
||||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
|
||||
access = readmemb(0, addr + 5);
|
||||
ar_high = readmemb(0, addr + 6);
|
||||
granularity = readmemb(0, addr + 6) & 0x80;
|
||||
if (cpu_state.abrt) return 1;
|
||||
ldt.limit = limit;
|
||||
ldt.access = access;
|
||||
ldt.ar_high = ar_high;
|
||||
if (granularity)
|
||||
{
|
||||
ldt.limit <<= 12;
|
||||
ldt.limit |= 0xfff;
|
||||
}
|
||||
ldt.base = base;
|
||||
ldt.seg = sel;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32);
|
||||
break;
|
||||
case 0x18: /*LTR*/
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
addr = (sel & ~7) + gdt.base;
|
||||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
|
||||
access = readmemb(0, addr + 5);
|
||||
ar_high = readmemb(0, addr + 6);
|
||||
granularity = readmemb(0, addr + 6) & 0x80;
|
||||
if (cpu_state.abrt) return 1;
|
||||
access |= 2;
|
||||
writememb(0, addr + 5, access);
|
||||
if (cpu_state.abrt) return 1;
|
||||
tr.seg = sel;
|
||||
tr.limit = limit;
|
||||
tr.access = access;
|
||||
tr.ar_high = ar_high;
|
||||
if (granularity)
|
||||
{
|
||||
tr.limit <<= 12;
|
||||
tr.limit |= 0xFFF;
|
||||
}
|
||||
tr.base = base;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32);
|
||||
break;
|
||||
case 0x20: /*VERR*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
if (!(sel & 0xfffc)) return 0; /*Null selector*/
|
||||
cpl_override = 1;
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
|
||||
cpl_override = 0; if (cpu_state.abrt) return 1;
|
||||
if (!(desc & 0x1000)) valid = 0;
|
||||
if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/
|
||||
{
|
||||
dpl = (desc >> 13) & 3; /*Check permissions*/
|
||||
if (dpl < CPL || dpl < (sel & 3)) valid = 0;
|
||||
}
|
||||
if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/
|
||||
if (valid) cpu_state.flags |= Z_FLAG;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32);
|
||||
break;
|
||||
case 0x28: /*VERW*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
if (!(sel & 0xfffc)) return 0; /*Null selector*/
|
||||
cpl_override = 1;
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
|
||||
cpl_override = 0; if (cpu_state.abrt) return 1;
|
||||
if (!(desc & 0x1000)) valid = 0;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
addr = (sel & ~7) + gdt.base;
|
||||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24);
|
||||
access = readmemb(0, addr + 5);
|
||||
ar_high = readmemb(0, addr + 6);
|
||||
granularity = readmemb(0, addr + 6) & 0x80;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
access |= 2;
|
||||
writememb(0, addr + 5, access);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
tr.seg = sel;
|
||||
tr.limit = limit;
|
||||
tr.access = access;
|
||||
tr.ar_high = ar_high;
|
||||
if (granularity) {
|
||||
tr.limit <<= 12;
|
||||
tr.limit |= 0xFFF;
|
||||
}
|
||||
tr.base = base;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32);
|
||||
break;
|
||||
case 0x20: /*VERR*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
if (!(sel & 0xfffc))
|
||||
return 0; /*Null selector*/
|
||||
cpl_override = 1;
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (!(desc & 0x1000))
|
||||
valid = 0;
|
||||
if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/
|
||||
{
|
||||
dpl = (desc >> 13) & 3; /*Check permissions*/
|
||||
if (dpl < CPL || dpl < (sel & 3)) valid = 0;
|
||||
if (desc & 0x0800) valid = 0; /*Code*/
|
||||
if (!(desc & 0x0200)) valid = 0; /*Read-only data*/
|
||||
if (valid) cpu_state.flags |= Z_FLAG;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32);
|
||||
break;
|
||||
if (dpl < CPL || dpl < (sel & 3))
|
||||
valid = 0;
|
||||
}
|
||||
if ((desc & 0x0800) && !(desc & 0x0200))
|
||||
valid = 0; /*Non-readable code*/
|
||||
if (valid)
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32);
|
||||
break;
|
||||
case 0x28: /*VERW*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
if (!(sel & 0xfffc))
|
||||
return 0; /*Null selector*/
|
||||
cpl_override = 1;
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4);
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (!(desc & 0x1000))
|
||||
valid = 0;
|
||||
dpl = (desc >> 13) & 3; /*Check permissions*/
|
||||
if (dpl < CPL || dpl < (sel & 3))
|
||||
valid = 0;
|
||||
if (desc & 0x0800)
|
||||
valid = 0; /*Code*/
|
||||
if (!(desc & 0x0200))
|
||||
valid = 0; /*Read-only data*/
|
||||
if (valid)
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32);
|
||||
break;
|
||||
|
||||
default:
|
||||
cpu_state.pc -= 3;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
return cpu_state.abrt;
|
||||
default:
|
||||
cpu_state.pc -= 3;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int op0F00_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op0F00_a16(uint32_t fetchdat)
|
||||
{
|
||||
NOTRM
|
||||
NOTRM
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
return op0F00_common(fetchdat, 0);
|
||||
return op0F00_common(fetchdat, 0);
|
||||
}
|
||||
static int op0F00_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op0F00_a32(uint32_t fetchdat)
|
||||
{
|
||||
NOTRM
|
||||
NOTRM
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
return op0F00_common(fetchdat, 1);
|
||||
return op0F00_common(fetchdat, 1);
|
||||
}
|
||||
|
||||
static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
static int
|
||||
op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
{
|
||||
uint32_t base;
|
||||
uint16_t limit, tempw;
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*SGDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(gdt.limit);
|
||||
base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff);
|
||||
if (is286)
|
||||
base |= 0xff000000;
|
||||
writememl(easeg, cpu_state.eaaddr + 2, base);
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32);
|
||||
uint32_t base;
|
||||
uint16_t limit, tempw;
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*SGDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(gdt.limit);
|
||||
base = gdt.base; // is32 ? gdt.base : (gdt.base & 0xffffff);
|
||||
if (is286)
|
||||
base |= 0xff000000;
|
||||
writememl(easeg, cpu_state.eaaddr + 2, base);
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
|
||||
break;
|
||||
case 0x08: /*SIDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(idt.limit);
|
||||
base = idt.base;
|
||||
if (is286)
|
||||
base |= 0xff000000;
|
||||
writememl(easeg, cpu_state.eaaddr + 2, base);
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
|
||||
break;
|
||||
case 0x10: /*LGDT*/
|
||||
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
case 0x08: /*SIDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(idt.limit);
|
||||
base = idt.base;
|
||||
if (is286)
|
||||
base |= 0xff000000;
|
||||
writememl(easeg, cpu_state.eaaddr + 2, base);
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32);
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
limit = geteaw();
|
||||
base = readmeml(0, easeg + cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
gdt.limit = limit;
|
||||
gdt.base = base;
|
||||
if (!is32)
|
||||
gdt.base &= 0xffffff;
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32);
|
||||
break;
|
||||
case 0x18: /*LIDT*/
|
||||
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
case 0x10: /*LGDT*/
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
limit = geteaw();
|
||||
base = readmeml(0, easeg + cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
idt.limit = limit;
|
||||
idt.base = base;
|
||||
if (!is32)
|
||||
idt.base &= 0xffffff;
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32);
|
||||
break;
|
||||
|
||||
case 0x20: /*SMSW*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (is486 || isibm486)
|
||||
seteaw(msw);
|
||||
else if (is386)
|
||||
seteaw(msw | /* 0xFF00 */ 0xFFE0);
|
||||
else
|
||||
seteaw(msw | 0xFFF0);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
|
||||
break;
|
||||
case 0x30: /*LMSW*/
|
||||
if ((CPL || cpu_state.eflags & VM_FLAG) && (msw & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
if (msw & 1)
|
||||
tempw |= 1;
|
||||
if (is386) {
|
||||
tempw &= ~0x10;
|
||||
tempw |= (msw & 0x10);
|
||||
} else
|
||||
tempw &= 0xF;
|
||||
msw = tempw;
|
||||
if (msw & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
|
||||
break;
|
||||
|
||||
case 0x38: /*INVLPG*/
|
||||
if (is486 || isibm486) {
|
||||
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
limit = geteaw();
|
||||
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
gdt.limit = limit;
|
||||
gdt.base = base;
|
||||
if (!is32) gdt.base &= 0xffffff;
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32);
|
||||
break;
|
||||
case 0x18: /*LIDT*/
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
limit = geteaw();
|
||||
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
idt.limit = limit;
|
||||
idt.base = base;
|
||||
if (!is32) idt.base &= 0xffffff;
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
mmu_invalidate(ds + cpu_state.eaaddr);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x20: /*SMSW*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (is486 || isibm486) seteaw(msw);
|
||||
else if (is386) seteaw(msw | /* 0xFF00 */ 0xFFE0);
|
||||
else seteaw(msw | 0xFFF0);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
|
||||
break;
|
||||
case 0x30: /*LMSW*/
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
if (msw & 1) tempw |= 1;
|
||||
if (is386)
|
||||
{
|
||||
tempw &= ~0x10;
|
||||
tempw |= (msw & 0x10);
|
||||
}
|
||||
else tempw &= 0xF;
|
||||
msw = tempw;
|
||||
if (msw & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
|
||||
break;
|
||||
|
||||
case 0x38: /*INVLPG*/
|
||||
if (is486 || isibm486)
|
||||
{
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
mmu_invalidate(ds + cpu_state.eaaddr);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
cpu_state.pc -= 3;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
return cpu_state.abrt;
|
||||
default:
|
||||
cpu_state.pc -= 3;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int op0F01_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op0F01_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
return op0F01_common(fetchdat, 0, 0, 0);
|
||||
return op0F01_common(fetchdat, 0, 0, 0);
|
||||
}
|
||||
static int op0F01_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op0F01_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
return op0F01_common(fetchdat, 0, 0, 1);
|
||||
return op0F01_common(fetchdat, 0, 0, 1);
|
||||
}
|
||||
static int op0F01_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op0F01_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
return op0F01_common(fetchdat, 1, 0, 0);
|
||||
return op0F01_common(fetchdat, 1, 0, 0);
|
||||
}
|
||||
static int op0F01_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op0F01_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
return op0F01_common(fetchdat, 1, 0, 1);
|
||||
return op0F01_common(fetchdat, 1, 0, 1);
|
||||
}
|
||||
|
||||
static int op0F01_286(uint32_t fetchdat)
|
||||
static int
|
||||
op0F01_286(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
return op0F01_common(fetchdat, 0, 1, 0);
|
||||
return op0F01_common(fetchdat, 0, 1, 0);
|
||||
}
|
||||
|
||||
@@ -1,67 +1,71 @@
|
||||
#define op_seg(name, seg, opcode_table, normal_opcode_table) \
|
||||
static int op ## name ## _w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[fetchdat & 0xff]) \
|
||||
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
#define op_seg(name, seg, opcode_table, normal_opcode_table) \
|
||||
static int op##name##_w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[fetchdat & 0xff]) \
|
||||
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
}
|
||||
}
|
||||
|
||||
op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes)
|
||||
op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes)
|
||||
@@ -84,78 +88,89 @@ op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes)
|
||||
|
||||
static int op_66(uint32_t fetchdat) /*Data size select*/
|
||||
static int op_66(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int op_67(uint32_t fetchdat) /*Address size select*/
|
||||
static int
|
||||
op_67(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
|
||||
static int op_66_REPE(uint32_t fetchdat) /*Data size select*/
|
||||
static int
|
||||
op_66_REPE(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int op_67_REPE(uint32_t fetchdat) /*Address size select*/
|
||||
static int
|
||||
op_67_REPE(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/
|
||||
static int
|
||||
op_66_REPNE(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/
|
||||
static int
|
||||
op_67_REPNE(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,311 +1,291 @@
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#define CPU_SET_OXPC
|
||||
# define CPU_SET_OXPC
|
||||
#else
|
||||
#define CPU_SET_OXPC oxpc = cpu_state.pc;
|
||||
# define CPU_SET_OXPC oxpc = cpu_state.pc;
|
||||
#endif
|
||||
|
||||
#define RETF_a16(stack_offset) \
|
||||
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
|
||||
{ \
|
||||
pmoderetf(0, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) \
|
||||
{ \
|
||||
cpu_state.pc = readmemw(ss, ESP); \
|
||||
loadcs(readmemw(ss, ESP + 2)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
cpu_state.pc = readmemw(ss, SP); \
|
||||
loadcs(readmemw(ss, SP + 2)); \
|
||||
} \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
if (stack32) ESP += 4 + stack_offset; \
|
||||
else SP += 4 + stack_offset; \
|
||||
cycles -= timing_retf_rm;
|
||||
#define RETF_a16(stack_offset) \
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
|
||||
pmoderetf(0, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) { \
|
||||
cpu_state.pc = readmemw(ss, ESP); \
|
||||
loadcs(readmemw(ss, ESP + 2)); \
|
||||
} else { \
|
||||
cpu_state.pc = readmemw(ss, SP); \
|
||||
loadcs(readmemw(ss, SP + 2)); \
|
||||
} \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (stack32) \
|
||||
ESP += 4 + stack_offset; \
|
||||
else \
|
||||
SP += 4 + stack_offset; \
|
||||
cycles -= timing_retf_rm;
|
||||
|
||||
#define RETF_a32(stack_offset) \
|
||||
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
|
||||
{ \
|
||||
pmoderetf(1, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) \
|
||||
{ \
|
||||
cpu_state.pc = readmeml(ss, ESP); \
|
||||
loadcs(readmeml(ss, ESP + 4) & 0xffff); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
cpu_state.pc = readmeml(ss, SP); \
|
||||
loadcs(readmeml(ss, SP + 4) & 0xffff); \
|
||||
} \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
if (stack32) ESP += 8 + stack_offset; \
|
||||
else SP += 8 + stack_offset; \
|
||||
cycles -= timing_retf_rm;
|
||||
#define RETF_a32(stack_offset) \
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
|
||||
pmoderetf(1, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) { \
|
||||
cpu_state.pc = readmeml(ss, ESP); \
|
||||
loadcs(readmeml(ss, ESP + 4) & 0xffff); \
|
||||
} else { \
|
||||
cpu_state.pc = readmeml(ss, SP); \
|
||||
loadcs(readmeml(ss, SP + 4) & 0xffff); \
|
||||
} \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (stack32) \
|
||||
ESP += 8 + stack_offset; \
|
||||
else \
|
||||
SP += 8 + stack_offset; \
|
||||
cycles -= timing_retf_rm;
|
||||
|
||||
static int opRETF_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opRETF_a16(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a16(0);
|
||||
CPU_BLOCK_END();
|
||||
RETF_a16(0);
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int opRETF_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opRETF_a32(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a32(0);
|
||||
CPU_BLOCK_END();
|
||||
RETF_a32(0);
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opRETF_a16_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opRETF_a16_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset = getwordf();
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
uint16_t offset = getwordf();
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a16(offset);
|
||||
CPU_BLOCK_END();
|
||||
RETF_a16(offset);
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 3, -1, 2,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int opRETF_a32_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opRETF_a32_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset = getwordf();
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
uint16_t offset = getwordf();
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a32(offset);
|
||||
CPU_BLOCK_END();
|
||||
RETF_a32(offset);
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 3, -1, 0,2,0,0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opIRET_186(uint32_t fetchdat)
|
||||
static int
|
||||
opIRET_186(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
} else {
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opIRET_286(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
} else {
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opIRET(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint16_t new_pc, new_cs, new_flags;
|
||||
|
||||
new_pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
new_flags = readmemw(ss, ((SP + 4) & 0xffff));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
}
|
||||
if (msw&1)
|
||||
{
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
optype = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opIRET_286(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (msw&1)
|
||||
{
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
optype = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
SP += 6;
|
||||
if (new_flags & I_FLAG)
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
|
||||
loadcs(new_cs);
|
||||
cpu_state.pc = new_pc;
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
cycles -= timing_iret_rm;
|
||||
} else {
|
||||
x86gpf_expected(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
} else {
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opIRET(uint32_t fetchdat)
|
||||
static int
|
||||
opIRETD(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
uint16_t new_pc, new_cs, new_flags;
|
||||
|
||||
new_pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
new_flags = readmemw(ss, ((SP + 4) & 0xffff));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
SP += 6;
|
||||
if (new_flags & I_FLAG)
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
|
||||
loadcs(new_cs);
|
||||
cpu_state.pc = new_pc;
|
||||
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
else
|
||||
{
|
||||
x86gpf_expected(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf_expected(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(1);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmeml(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 4);
|
||||
cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, ESP + 10);
|
||||
ESP += 12;
|
||||
} else {
|
||||
cpu_state.pc = readmeml(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 4) & 0xffff));
|
||||
cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
|
||||
SP += 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msw&1)
|
||||
{
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
optype = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opIRETD(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf_expected(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1)
|
||||
{
|
||||
optype = IRET;
|
||||
pmodeiret(1);
|
||||
optype = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmeml(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 4);
|
||||
cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, ESP + 10);
|
||||
ESP += 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmeml(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 4) & 0xffff));
|
||||
cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
|
||||
SP += 12;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
#define opSET(condition) \
|
||||
static int opSET ## condition ## _a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
seteab((cond_ ## condition) ? 1 : 0); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opSET ## condition ## _a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
seteab((cond_ ## condition) ? 1 : 0); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
#define opSET(condition) \
|
||||
static int opSET##condition##_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
seteab((cond_##condition) ? 1 : 0); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opSET##condition##_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
seteab((cond_##condition) ? 1 : 0); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
opSET(O)
|
||||
opSET(NO)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,38 +1,38 @@
|
||||
#define PUSH_W_OP(reg) \
|
||||
static int opPUSH_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_W(reg); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
#define PUSH_W_OP(reg) \
|
||||
static int opPUSH_##reg(uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_W(reg); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
#define PUSH_L_OP(reg) \
|
||||
static int opPUSH_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_L(reg); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
#define PUSH_L_OP(reg) \
|
||||
static int opPUSH_##reg(uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_L(reg); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
#define POP_W_OP(reg) \
|
||||
static int opPOP_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
reg = POP_W(); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 4); \
|
||||
PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
#define POP_W_OP(reg) \
|
||||
static int opPOP_##reg(uint32_t fetchdat) \
|
||||
{ \
|
||||
reg = POP_W(); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 4); \
|
||||
PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
#define POP_L_OP(reg) \
|
||||
static int opPOP_ ## reg (uint32_t fetchdat) \
|
||||
{ \
|
||||
reg = POP_L(); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 4); \
|
||||
PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
#define POP_L_OP(reg) \
|
||||
static int opPOP_##reg(uint32_t fetchdat) \
|
||||
{ \
|
||||
reg = POP_L(); \
|
||||
CLOCK_CYCLES((is486) ? 1 : 4); \
|
||||
PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
PUSH_W_OP(AX)
|
||||
PUSH_W_OP(BX)
|
||||
@@ -70,100 +70,125 @@ POP_L_OP(EDI)
|
||||
POP_L_OP(EBP)
|
||||
POP_L_OP(ESP)
|
||||
|
||||
|
||||
static int opPUSHA_w(uint32_t fetchdat)
|
||||
static int
|
||||
opPUSHA_w(uint32_t fetchdat)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss, ESP - 2, AX);
|
||||
writememw(ss, ESP - 4, CX);
|
||||
writememw(ss, ESP - 6, DX);
|
||||
writememw(ss, ESP - 8, BX);
|
||||
writememw(ss, ESP - 10, SP);
|
||||
writememw(ss, ESP - 12, BP);
|
||||
writememw(ss, ESP - 14, SI);
|
||||
writememw(ss, ESP - 16, DI);
|
||||
if (!cpu_state.abrt) ESP -= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss, ((SP - 2) & 0xFFFF), AX);
|
||||
writememw(ss, ((SP - 4) & 0xFFFF), CX);
|
||||
writememw(ss, ((SP - 6) & 0xFFFF), DX);
|
||||
writememw(ss, ((SP - 8) & 0xFFFF), BX);
|
||||
writememw(ss, ((SP - 10) & 0xFFFF), SP);
|
||||
writememw(ss, ((SP - 12) & 0xFFFF), BP);
|
||||
writememw(ss, ((SP - 14) & 0xFFFF), SI);
|
||||
writememw(ss, ((SP - 16) & 0xFFFF), DI);
|
||||
if (!cpu_state.abrt) SP -= 16;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 11 : 18);
|
||||
PREFETCH_RUN(18, 1, -1, 0,0,8,0, 0);
|
||||
return cpu_state.abrt;
|
||||
if (stack32) {
|
||||
writememw(ss, ESP - 2, AX);
|
||||
writememw(ss, ESP - 4, CX);
|
||||
writememw(ss, ESP - 6, DX);
|
||||
writememw(ss, ESP - 8, BX);
|
||||
writememw(ss, ESP - 10, SP);
|
||||
writememw(ss, ESP - 12, BP);
|
||||
writememw(ss, ESP - 14, SI);
|
||||
writememw(ss, ESP - 16, DI);
|
||||
if (!cpu_state.abrt)
|
||||
ESP -= 16;
|
||||
} else {
|
||||
writememw(ss, ((SP - 2) & 0xFFFF), AX);
|
||||
writememw(ss, ((SP - 4) & 0xFFFF), CX);
|
||||
writememw(ss, ((SP - 6) & 0xFFFF), DX);
|
||||
writememw(ss, ((SP - 8) & 0xFFFF), BX);
|
||||
writememw(ss, ((SP - 10) & 0xFFFF), SP);
|
||||
writememw(ss, ((SP - 12) & 0xFFFF), BP);
|
||||
writememw(ss, ((SP - 14) & 0xFFFF), SI);
|
||||
writememw(ss, ((SP - 16) & 0xFFFF), DI);
|
||||
if (!cpu_state.abrt)
|
||||
SP -= 16;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 11 : 18);
|
||||
PREFETCH_RUN(18, 1, -1, 0, 0, 8, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opPUSHA_l(uint32_t fetchdat)
|
||||
static int
|
||||
opPUSHA_l(uint32_t fetchdat)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememl(ss, ESP - 4, EAX);
|
||||
writememl(ss, ESP - 8, ECX);
|
||||
writememl(ss, ESP - 12, EDX);
|
||||
writememl(ss, ESP - 16, EBX);
|
||||
writememl(ss, ESP - 20, ESP);
|
||||
writememl(ss, ESP - 24, EBP);
|
||||
writememl(ss, ESP - 28, ESI);
|
||||
writememl(ss, ESP - 32, EDI);
|
||||
if (!cpu_state.abrt) ESP -= 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(ss, ((SP - 4) & 0xFFFF), EAX);
|
||||
writememl(ss, ((SP - 8) & 0xFFFF), ECX);
|
||||
writememl(ss, ((SP - 12) & 0xFFFF), EDX);
|
||||
writememl(ss, ((SP - 16) & 0xFFFF), EBX);
|
||||
writememl(ss, ((SP - 20) & 0xFFFF), ESP);
|
||||
writememl(ss, ((SP - 24) & 0xFFFF), EBP);
|
||||
writememl(ss, ((SP - 28) & 0xFFFF), ESI);
|
||||
writememl(ss, ((SP - 32) & 0xFFFF), EDI);
|
||||
if (!cpu_state.abrt) SP -= 32;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 11 : 18);
|
||||
PREFETCH_RUN(18, 1, -1, 0,0,0,8, 0);
|
||||
return cpu_state.abrt;
|
||||
if (stack32) {
|
||||
writememl(ss, ESP - 4, EAX);
|
||||
writememl(ss, ESP - 8, ECX);
|
||||
writememl(ss, ESP - 12, EDX);
|
||||
writememl(ss, ESP - 16, EBX);
|
||||
writememl(ss, ESP - 20, ESP);
|
||||
writememl(ss, ESP - 24, EBP);
|
||||
writememl(ss, ESP - 28, ESI);
|
||||
writememl(ss, ESP - 32, EDI);
|
||||
if (!cpu_state.abrt)
|
||||
ESP -= 32;
|
||||
} else {
|
||||
writememl(ss, ((SP - 4) & 0xFFFF), EAX);
|
||||
writememl(ss, ((SP - 8) & 0xFFFF), ECX);
|
||||
writememl(ss, ((SP - 12) & 0xFFFF), EDX);
|
||||
writememl(ss, ((SP - 16) & 0xFFFF), EBX);
|
||||
writememl(ss, ((SP - 20) & 0xFFFF), ESP);
|
||||
writememl(ss, ((SP - 24) & 0xFFFF), EBP);
|
||||
writememl(ss, ((SP - 28) & 0xFFFF), ESI);
|
||||
writememl(ss, ((SP - 32) & 0xFFFF), EDI);
|
||||
if (!cpu_state.abrt)
|
||||
SP -= 32;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 11 : 18);
|
||||
PREFETCH_RUN(18, 1, -1, 0, 0, 0, 8, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opPOPA_w(uint32_t fetchdat)
|
||||
static int
|
||||
opPOPA_w(uint32_t fetchdat)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
DI = readmemw(ss, ESP); if (cpu_state.abrt) return 1;
|
||||
SI = readmemw(ss, ESP + 2); if (cpu_state.abrt) return 1;
|
||||
BP = readmemw(ss, ESP + 4); if (cpu_state.abrt) return 1;
|
||||
BX = readmemw(ss, ESP + 8); if (cpu_state.abrt) return 1;
|
||||
DX = readmemw(ss, ESP + 10); if (cpu_state.abrt) return 1;
|
||||
CX = readmemw(ss, ESP + 12); if (cpu_state.abrt) return 1;
|
||||
AX = readmemw(ss, ESP + 14); if (cpu_state.abrt) return 1;
|
||||
ESP += 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
DI = readmemw(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
SP += 16;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 9 : 24);
|
||||
PREFETCH_RUN(24, 1, -1, 7,0,0,0, 0);
|
||||
return 0;
|
||||
if (stack32) {
|
||||
DI = readmemw(ss, ESP);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
SI = readmemw(ss, ESP + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
BP = readmemw(ss, ESP + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
BX = readmemw(ss, ESP + 8);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
DX = readmemw(ss, ESP + 10);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CX = readmemw(ss, ESP + 12);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
AX = readmemw(ss, ESP + 14);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
ESP += 16;
|
||||
} else {
|
||||
DI = readmemw(ss, ((SP) &0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
SI = readmemw(ss, ((SP + 2) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
BP = readmemw(ss, ((SP + 4) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
BX = readmemw(ss, ((SP + 8) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
DX = readmemw(ss, ((SP + 10) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
CX = readmemw(ss, ((SP + 12) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
AX = readmemw(ss, ((SP + 14) & 0xFFFF));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
SP += 16;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 9 : 24);
|
||||
PREFETCH_RUN(24, 1, -1, 7, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opPOPA_l(uint32_t fetchdat)
|
||||
static int
|
||||
opPOPA_l(uint32_t fetchdat)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
if (stack32) {
|
||||
EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1;
|
||||
ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1;
|
||||
EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1;
|
||||
@@ -172,9 +197,7 @@ static int opPOPA_l(uint32_t fetchdat)
|
||||
ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1;
|
||||
EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1;
|
||||
ESP += 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1;
|
||||
@@ -189,302 +212,389 @@ static int opPOPA_l(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPUSH_imm_w(uint32_t fetchdat)
|
||||
static int
|
||||
opPUSH_imm_w(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t val = getwordf();
|
||||
PUSH_W(val);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0);
|
||||
return cpu_state.abrt;
|
||||
uint16_t val = getwordf();
|
||||
PUSH_W(val);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opPUSH_imm_l(uint32_t fetchdat)
|
||||
static int
|
||||
opPUSH_imm_l(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t val = getlong(); if (cpu_state.abrt) return 1;
|
||||
PUSH_L(val);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0);
|
||||
return cpu_state.abrt;
|
||||
uint32_t val = getlong();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
PUSH_L(val);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 3, -1, 0, 0, 0, 1, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opPUSH_imm_bw(uint32_t fetchdat)
|
||||
static int
|
||||
opPUSH_imm_bw(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw = getbytef();
|
||||
uint16_t tempw = getbytef();
|
||||
|
||||
if (tempw & 0x80) tempw |= 0xFF00;
|
||||
PUSH_W(tempw);
|
||||
if (tempw & 0x80)
|
||||
tempw |= 0xFF00;
|
||||
PUSH_W(tempw);
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 2, -1, 0,0,1,0, 0);
|
||||
return cpu_state.abrt;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 2, -1, 0, 0, 1, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opPUSH_imm_bl(uint32_t fetchdat)
|
||||
static int
|
||||
opPUSH_imm_bl(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ = getbytef();
|
||||
uint32_t templ = getbytef();
|
||||
|
||||
if (templ & 0x80) templ |= 0xFFFFFF00;
|
||||
PUSH_L(templ);
|
||||
if (templ & 0x80)
|
||||
templ |= 0xFFFFFF00;
|
||||
PUSH_L(templ);
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 2, -1, 0,0,0,1, 0);
|
||||
return cpu_state.abrt;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 2, -1, 0, 0, 0, 1, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opPOPW_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPOPW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
temp = POP_W(); if (cpu_state.abrt) return 1;
|
||||
temp = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
if (stack32) ESP -= 2;
|
||||
else SP -= 2;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt) {
|
||||
if (stack32)
|
||||
ESP -= 2;
|
||||
else
|
||||
SP -= 2;
|
||||
}
|
||||
|
||||
if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
|
||||
else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); }
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return cpu_state.abrt;
|
||||
if (is486) {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
|
||||
} else {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
|
||||
}
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opPOPW_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPOPW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
temp = POP_W(); if (cpu_state.abrt) return 1;
|
||||
temp = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
if (stack32) ESP -= 2;
|
||||
else SP -= 2;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt) {
|
||||
if (stack32)
|
||||
ESP -= 2;
|
||||
else
|
||||
SP -= 2;
|
||||
}
|
||||
|
||||
if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
|
||||
else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); }
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
return cpu_state.abrt;
|
||||
if (is486) {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
|
||||
} else {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
|
||||
}
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int opPOPL_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opPOPL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
|
||||
temp = POP_L(); if (cpu_state.abrt) return 1;
|
||||
temp = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
if (stack32) ESP -= 4;
|
||||
else SP -= 4;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt) {
|
||||
if (stack32)
|
||||
ESP -= 4;
|
||||
else
|
||||
SP -= 4;
|
||||
}
|
||||
|
||||
if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
|
||||
else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); }
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
return cpu_state.abrt;
|
||||
if (is486) {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
|
||||
} else {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
|
||||
}
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opPOPL_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opPOPL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
|
||||
temp = POP_L(); if (cpu_state.abrt) return 1;
|
||||
temp = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
if (stack32) ESP -= 4;
|
||||
else SP -= 4;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt) {
|
||||
if (stack32)
|
||||
ESP -= 4;
|
||||
else
|
||||
SP -= 4;
|
||||
}
|
||||
|
||||
if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); }
|
||||
else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); }
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
return cpu_state.abrt;
|
||||
if (is486) {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
|
||||
} else {
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
|
||||
}
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 1);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
|
||||
static int opENTER_w(uint32_t fetchdat)
|
||||
static int
|
||||
opENTER_w(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset;
|
||||
int count;
|
||||
uint32_t tempEBP, tempESP, frame_ptr;
|
||||
uint16_t offset;
|
||||
int count;
|
||||
uint32_t tempEBP, tempESP, frame_ptr;
|
||||
#ifndef IS_DYNAREC
|
||||
int reads = 0, writes = 1, instr_cycles = 0;
|
||||
int reads = 0, writes = 1, instr_cycles = 0;
|
||||
#endif
|
||||
uint16_t tempw;
|
||||
uint16_t tempw;
|
||||
|
||||
offset = getwordf();
|
||||
count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
|
||||
tempEBP = EBP;
|
||||
tempESP = ESP;
|
||||
offset = getwordf();
|
||||
count = (fetchdat >> 16) & 0xff;
|
||||
cpu_state.pc++;
|
||||
tempEBP = EBP;
|
||||
tempESP = ESP;
|
||||
|
||||
PUSH_W(BP); if (cpu_state.abrt) return 1;
|
||||
frame_ptr = ESP;
|
||||
PUSH_W(BP);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
frame_ptr = ESP;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
while (--count)
|
||||
{
|
||||
BP -= 2;
|
||||
tempw = readmemw(ss, BP);
|
||||
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
|
||||
PUSH_W(tempw);
|
||||
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
|
||||
CLOCK_CYCLES((is486) ? 3 : 4);
|
||||
if (count > 0) {
|
||||
while (--count) {
|
||||
BP -= 2;
|
||||
tempw = readmemw(ss, BP);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
EBP = tempEBP;
|
||||
return 1;
|
||||
}
|
||||
PUSH_W(tempw);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
EBP = tempEBP;
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 3 : 4);
|
||||
#ifndef IS_DYNAREC
|
||||
reads++; writes++; instr_cycles += (is486) ? 3 : 4;
|
||||
#endif
|
||||
}
|
||||
PUSH_W(frame_ptr);
|
||||
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
|
||||
CLOCK_CYCLES((is486) ? 3 : 5);
|
||||
#ifndef IS_DYNAREC
|
||||
writes++; instr_cycles += (is486) ? 3 : 5;
|
||||
reads++;
|
||||
writes++;
|
||||
instr_cycles += (is486) ? 3 : 4;
|
||||
#endif
|
||||
}
|
||||
BP = frame_ptr;
|
||||
|
||||
if (stack32) ESP -= offset;
|
||||
else SP -= offset;
|
||||
CLOCK_CYCLES((is486) ? 14 : 10);
|
||||
PUSH_W(frame_ptr);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
EBP = tempEBP;
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 3 : 5);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += (is486) ? 14 : 10;
|
||||
PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0);
|
||||
writes++;
|
||||
instr_cycles += (is486) ? 3 : 5;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
BP = frame_ptr;
|
||||
|
||||
if (stack32)
|
||||
ESP -= offset;
|
||||
else
|
||||
SP -= offset;
|
||||
CLOCK_CYCLES((is486) ? 14 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += (is486) ? 14 : 10;
|
||||
PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static int opENTER_l(uint32_t fetchdat)
|
||||
static int
|
||||
opENTER_l(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset;
|
||||
int count;
|
||||
uint32_t tempEBP, tempESP, frame_ptr;
|
||||
uint16_t offset;
|
||||
int count;
|
||||
uint32_t tempEBP, tempESP, frame_ptr;
|
||||
#ifndef IS_DYNAREC
|
||||
int reads = 0, writes = 1, instr_cycles = 0;
|
||||
int reads = 0, writes = 1, instr_cycles = 0;
|
||||
#endif
|
||||
uint32_t templ;
|
||||
uint32_t templ;
|
||||
|
||||
offset = getwordf();
|
||||
count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
|
||||
tempEBP = EBP; tempESP = ESP;
|
||||
offset = getwordf();
|
||||
count = (fetchdat >> 16) & 0xff;
|
||||
cpu_state.pc++;
|
||||
tempEBP = EBP;
|
||||
tempESP = ESP;
|
||||
|
||||
PUSH_L(EBP); if (cpu_state.abrt) return 1;
|
||||
frame_ptr = ESP;
|
||||
PUSH_L(EBP);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
frame_ptr = ESP;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
while (--count)
|
||||
{
|
||||
EBP -= 4;
|
||||
templ = readmeml(ss, EBP);
|
||||
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
|
||||
PUSH_L(templ);
|
||||
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
|
||||
CLOCK_CYCLES((is486) ? 3 : 4);
|
||||
if (count > 0) {
|
||||
while (--count) {
|
||||
EBP -= 4;
|
||||
templ = readmeml(ss, EBP);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
EBP = tempEBP;
|
||||
return 1;
|
||||
}
|
||||
PUSH_L(templ);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
EBP = tempEBP;
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 3 : 4);
|
||||
#ifndef IS_DYNAREC
|
||||
reads++; writes++; instr_cycles += (is486) ? 3 : 4;
|
||||
#endif
|
||||
}
|
||||
PUSH_L(frame_ptr);
|
||||
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
|
||||
CLOCK_CYCLES((is486) ? 3 : 5);
|
||||
#ifndef IS_DYNAREC
|
||||
writes++; instr_cycles += (is486) ? 3 : 5;
|
||||
reads++;
|
||||
writes++;
|
||||
instr_cycles += (is486) ? 3 : 4;
|
||||
#endif
|
||||
}
|
||||
EBP = frame_ptr;
|
||||
|
||||
if (stack32) ESP -= offset;
|
||||
else SP -= offset;
|
||||
CLOCK_CYCLES((is486) ? 14 : 10);
|
||||
PUSH_L(frame_ptr);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
EBP = tempEBP;
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES((is486) ? 3 : 5);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += (is486) ? 14 : 10;
|
||||
PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0);
|
||||
writes++;
|
||||
instr_cycles += (is486) ? 3 : 5;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EBP = frame_ptr;
|
||||
|
||||
if (stack32)
|
||||
ESP -= offset;
|
||||
else
|
||||
SP -= offset;
|
||||
CLOCK_CYCLES((is486) ? 14 : 10);
|
||||
#ifndef IS_DYNAREC
|
||||
instr_cycles += (is486) ? 14 : 10;
|
||||
PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int opLEAVE_w(uint32_t fetchdat)
|
||||
static int
|
||||
opLEAVE_w(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t tempESP = ESP;
|
||||
uint16_t temp;
|
||||
uint32_t tempESP = ESP;
|
||||
uint16_t temp;
|
||||
|
||||
SP = BP;
|
||||
temp = POP_W();
|
||||
if (cpu_state.abrt) { ESP = tempESP; return 1; }
|
||||
BP = temp;
|
||||
SP = BP;
|
||||
temp = POP_W();
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
return 1;
|
||||
}
|
||||
BP = temp;
|
||||
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opLEAVE_l(uint32_t fetchdat)
|
||||
static int
|
||||
opLEAVE_l(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t tempESP = ESP;
|
||||
uint32_t temp;
|
||||
uint32_t tempESP = ESP;
|
||||
uint32_t temp;
|
||||
|
||||
ESP = EBP;
|
||||
temp = POP_L();
|
||||
if (cpu_state.abrt) { ESP = tempESP; return 1; }
|
||||
EBP = temp;
|
||||
ESP = EBP;
|
||||
temp = POP_L();
|
||||
if (cpu_state.abrt) {
|
||||
ESP = tempESP;
|
||||
return 1;
|
||||
}
|
||||
EBP = temp;
|
||||
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0);
|
||||
return 0;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PUSH_SEG_OPS(seg) \
|
||||
static int opPUSH_##seg##_w(uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_W(seg); \
|
||||
CLOCK_CYCLES(2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opPUSH_##seg##_l(uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_L(seg); \
|
||||
CLOCK_CYCLES(2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
#define PUSH_SEG_OPS(seg) \
|
||||
static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_W(seg); \
|
||||
CLOCK_CYCLES(2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \
|
||||
{ \
|
||||
PUSH_L(seg); \
|
||||
CLOCK_CYCLES(2); \
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
#define POP_SEG_OPS(seg, realseg) \
|
||||
static int opPOP_ ## seg ## _w(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t temp_seg; \
|
||||
uint32_t temp_esp = ESP; \
|
||||
temp_seg = POP_W(); if (cpu_state.abrt) return 1; \
|
||||
loadseg(temp_seg, realseg); if (cpu_state.abrt) ESP = temp_esp; \
|
||||
CLOCK_CYCLES(is486 ? 3 : 7); \
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opPOP_ ## seg ## _l(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t temp_seg; \
|
||||
uint32_t temp_esp = ESP; \
|
||||
temp_seg = POP_L(); if (cpu_state.abrt) return 1; \
|
||||
loadseg(temp_seg & 0xffff, realseg); if (cpu_state.abrt) ESP = temp_esp; \
|
||||
CLOCK_CYCLES(is486 ? 3 : 7); \
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
#define POP_SEG_OPS(seg, realseg) \
|
||||
static int opPOP_##seg##_w(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t temp_seg; \
|
||||
uint32_t temp_esp = ESP; \
|
||||
temp_seg = POP_W(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(temp_seg, realseg); \
|
||||
if (cpu_state.abrt) \
|
||||
ESP = temp_esp; \
|
||||
CLOCK_CYCLES(is486 ? 3 : 7); \
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opPOP_##seg##_l(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t temp_seg; \
|
||||
uint32_t temp_esp = ESP; \
|
||||
temp_seg = POP_L(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(temp_seg & 0xffff, realseg); \
|
||||
if (cpu_state.abrt) \
|
||||
ESP = temp_esp; \
|
||||
CLOCK_CYCLES(is486 ? 3 : 7); \
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
PUSH_SEG_OPS(CS)
|
||||
PUSH_SEG_OPS(DS)
|
||||
@@ -497,44 +607,59 @@ POP_SEG_OPS(ES, &cpu_state.seg_es)
|
||||
POP_SEG_OPS(FS, &cpu_state.seg_fs)
|
||||
POP_SEG_OPS(GS, &cpu_state.seg_gs)
|
||||
|
||||
|
||||
static int opPOP_SS_w(uint32_t fetchdat)
|
||||
static int
|
||||
opPOP_SS_w(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp_seg;
|
||||
uint32_t temp_esp = ESP;
|
||||
temp_seg = POP_W(); if (cpu_state.abrt) return 1;
|
||||
loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
|
||||
CLOCK_CYCLES(is486 ? 3 : 7);
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
|
||||
uint16_t temp_seg;
|
||||
uint32_t temp_esp = ESP;
|
||||
temp_seg = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(temp_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = temp_esp;
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(is486 ? 3 : 7);
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0);
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
static int opPOP_SS_l(uint32_t fetchdat)
|
||||
static int
|
||||
opPOP_SS_l(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp_seg;
|
||||
uint32_t temp_esp = ESP;
|
||||
temp_seg = POP_L(); if (cpu_state.abrt) return 1;
|
||||
loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
|
||||
CLOCK_CYCLES(is486 ? 3 : 7);
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
|
||||
uint32_t temp_seg;
|
||||
uint32_t temp_esp = ESP;
|
||||
temp_seg = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(temp_seg & 0xffff, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = temp_esp;
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(is486 ? 3 : 7);
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0);
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,228 +1,270 @@
|
||||
static int opXCHG_b_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
seteab(getr8(cpu_reg));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_b_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
seteab(getr8(cpu_reg));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opXCHG_w_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
seteaw(cpu_state.regs[cpu_reg].w);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_w_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
seteaw(cpu_state.regs[cpu_reg].w);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opXCHG_l_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
seteal(cpu_state.regs[cpu_reg].l);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_l_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
seteal(cpu_state.regs[cpu_reg].l);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int opXCHG_AX_BX(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_AX_BX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = AX;
|
||||
AX = BX;
|
||||
BX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint16_t temp = AX;
|
||||
AX = BX;
|
||||
BX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_AX_CX(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_AX_CX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = AX;
|
||||
AX = CX;
|
||||
CX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint16_t temp = AX;
|
||||
AX = CX;
|
||||
CX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_AX_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_AX_DX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = AX;
|
||||
AX = DX;
|
||||
DX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint16_t temp = AX;
|
||||
AX = DX;
|
||||
DX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_AX_SI(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_AX_SI(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = AX;
|
||||
AX = SI;
|
||||
SI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint16_t temp = AX;
|
||||
AX = SI;
|
||||
SI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_AX_DI(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_AX_DI(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = AX;
|
||||
AX = DI;
|
||||
DI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint16_t temp = AX;
|
||||
AX = DI;
|
||||
DI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_AX_BP(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_AX_BP(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = AX;
|
||||
AX = BP;
|
||||
BP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint16_t temp = AX;
|
||||
AX = BP;
|
||||
BP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_AX_SP(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_AX_SP(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = AX;
|
||||
AX = SP;
|
||||
SP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint16_t temp = AX;
|
||||
AX = SP;
|
||||
SP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opXCHG_EAX_EBX(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_EAX_EBX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = EAX;
|
||||
EAX = EBX;
|
||||
EBX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint32_t temp = EAX;
|
||||
EAX = EBX;
|
||||
EBX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_EAX_ECX(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_EAX_ECX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = EAX;
|
||||
EAX = ECX;
|
||||
ECX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint32_t temp = EAX;
|
||||
EAX = ECX;
|
||||
ECX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_EAX_EDX(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_EAX_EDX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = EAX;
|
||||
EAX = EDX;
|
||||
EDX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint32_t temp = EAX;
|
||||
EAX = EDX;
|
||||
EDX = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_EAX_ESI(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_EAX_ESI(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = EAX;
|
||||
EAX = ESI;
|
||||
ESI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint32_t temp = EAX;
|
||||
EAX = ESI;
|
||||
ESI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_EAX_EDI(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_EAX_EDI(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = EAX;
|
||||
EAX = EDI;
|
||||
EDI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint32_t temp = EAX;
|
||||
EAX = EDI;
|
||||
EDI = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_EAX_EBP(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_EAX_EBP(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = EAX;
|
||||
EAX = EBP;
|
||||
EBP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint32_t temp = EAX;
|
||||
EAX = EBP;
|
||||
EBP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opXCHG_EAX_ESP(uint32_t fetchdat)
|
||||
static int
|
||||
opXCHG_EAX_ESP(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = EAX;
|
||||
EAX = ESP;
|
||||
ESP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
uint32_t temp = EAX;
|
||||
EAX = ESP;
|
||||
ESP = temp;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define opBSWAP(reg) \
|
||||
static int opBSWAP_ ## reg(uint32_t fetchdat) \
|
||||
{ \
|
||||
reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \
|
||||
CLOCK_CYCLES(1); \
|
||||
PREFETCH_RUN(1, 1, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
}
|
||||
#define opBSWAP(reg) \
|
||||
static int opBSWAP_##reg(uint32_t fetchdat) \
|
||||
{ \
|
||||
reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \
|
||||
CLOCK_CYCLES(1); \
|
||||
PREFETCH_RUN(1, 1, -1, 0, 0, 0, 0, 0); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
opBSWAP(EAX)
|
||||
opBSWAP(EBX)
|
||||
|
||||
3639
src/cpu/x86seg.c
3639
src/cpu/x86seg.c
File diff suppressed because it is too large
Load Diff
134
src/cpu/x87.c
134
src/cpu/x87.c
@@ -16,117 +16,111 @@
|
||||
#include "x87.h"
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
uint32_t x87_pc_off,x87_op_off;
|
||||
uint16_t x87_pc_seg,x87_op_seg;
|
||||
|
||||
uint32_t x87_pc_off, x87_op_off;
|
||||
uint16_t x87_pc_seg, x87_op_seg;
|
||||
|
||||
#ifdef ENABLE_FPU_LOG
|
||||
int fpu_do_log = ENABLE_FPU_LOG;
|
||||
|
||||
|
||||
void
|
||||
fpu_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (fpu_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define fpu_log(fmt, ...)
|
||||
# define fpu_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#define X87_TAG_VALID 0
|
||||
#define X87_TAG_ZERO 1
|
||||
#define X87_TAG_INVALID 2
|
||||
#define X87_TAG_EMPTY 3
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t x87_gettag(void)
|
||||
uint16_t
|
||||
x87_gettag(void)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
int c;
|
||||
uint16_t ret = 0;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
if (cpu_state.tag[c] == TAG_EMPTY)
|
||||
ret |= X87_TAG_EMPTY << (c * 2);
|
||||
else if (cpu_state.tag[c] & TAG_UINT64)
|
||||
ret |= 2 << (c*2);
|
||||
else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx)
|
||||
ret |= X87_TAG_ZERO << (c * 2);
|
||||
else
|
||||
ret |= X87_TAG_VALID << (c * 2);
|
||||
}
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (cpu_state.tag[c] == TAG_EMPTY)
|
||||
ret |= X87_TAG_EMPTY << (c * 2);
|
||||
else if (cpu_state.tag[c] & TAG_UINT64)
|
||||
ret |= 2 << (c * 2);
|
||||
else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx)
|
||||
ret |= X87_TAG_ZERO << (c * 2);
|
||||
else
|
||||
ret |= X87_TAG_VALID << (c * 2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void x87_settag(uint16_t new_tag)
|
||||
void
|
||||
x87_settag(uint16_t new_tag)
|
||||
{
|
||||
int c;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
int tag = (new_tag >> (c * 2)) & 3;
|
||||
for (c = 0; c < 8; c++) {
|
||||
int tag = (new_tag >> (c * 2)) & 3;
|
||||
|
||||
if (tag == X87_TAG_EMPTY)
|
||||
cpu_state.tag[c] = TAG_EMPTY;
|
||||
else if (tag == 2)
|
||||
cpu_state.tag[c] = TAG_VALID | TAG_UINT64;
|
||||
else
|
||||
cpu_state.tag[c] = TAG_VALID;
|
||||
}
|
||||
if (tag == X87_TAG_EMPTY)
|
||||
cpu_state.tag[c] = TAG_EMPTY;
|
||||
else if (tag == 2)
|
||||
cpu_state.tag[c] = TAG_VALID | TAG_UINT64;
|
||||
else
|
||||
cpu_state.tag[c] = TAG_VALID;
|
||||
}
|
||||
}
|
||||
#else
|
||||
uint16_t x87_gettag(void)
|
||||
uint16_t
|
||||
x87_gettag(void)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
int c;
|
||||
uint16_t ret = 0;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
if (cpu_state.tag[c] & TAG_UINT64)
|
||||
ret |= 2 << (c*2);
|
||||
else
|
||||
ret |= (cpu_state.tag[c] << (c*2));
|
||||
}
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (cpu_state.tag[c] & TAG_UINT64)
|
||||
ret |= 2 << (c * 2);
|
||||
else
|
||||
ret |= (cpu_state.tag[c] << (c * 2));
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void x87_settag(uint16_t new_tag)
|
||||
void
|
||||
x87_settag(uint16_t new_tag)
|
||||
{
|
||||
cpu_state.tag[0] = new_tag & 3;
|
||||
cpu_state.tag[1] = (new_tag >> 2) & 3;
|
||||
cpu_state.tag[2] = (new_tag >> 4) & 3;
|
||||
cpu_state.tag[3] = (new_tag >> 6) & 3;
|
||||
cpu_state.tag[4] = (new_tag >> 8) & 3;
|
||||
cpu_state.tag[5] = (new_tag >> 10) & 3;
|
||||
cpu_state.tag[6] = (new_tag >> 12) & 3;
|
||||
cpu_state.tag[7] = (new_tag >> 14) & 3;
|
||||
cpu_state.tag[0] = new_tag & 3;
|
||||
cpu_state.tag[1] = (new_tag >> 2) & 3;
|
||||
cpu_state.tag[2] = (new_tag >> 4) & 3;
|
||||
cpu_state.tag[3] = (new_tag >> 6) & 3;
|
||||
cpu_state.tag[4] = (new_tag >> 8) & 3;
|
||||
cpu_state.tag[5] = (new_tag >> 10) & 3;
|
||||
cpu_state.tag[6] = (new_tag >> 12) & 3;
|
||||
cpu_state.tag[7] = (new_tag >> 14) & 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_808X_LOG
|
||||
void x87_dumpregs(void)
|
||||
void
|
||||
x87_dumpregs(void)
|
||||
{
|
||||
if (cpu_state.ismmx)
|
||||
{
|
||||
fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q);
|
||||
fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q);
|
||||
}
|
||||
else
|
||||
{
|
||||
fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]);
|
||||
fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7]);
|
||||
}
|
||||
fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag());
|
||||
if (cpu_state.ismmx) {
|
||||
fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q);
|
||||
fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q);
|
||||
} else {
|
||||
fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n", cpu_state.ST[cpu_state.TOP], cpu_state.ST[(cpu_state.TOP + 1) & 7], cpu_state.ST[(cpu_state.TOP + 2) & 7], cpu_state.ST[(cpu_state.TOP + 3) & 7]);
|
||||
fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n", cpu_state.ST[(cpu_state.TOP + 4) & 7], cpu_state.ST[(cpu_state.TOP + 5) & 7], cpu_state.ST[(cpu_state.TOP + 6) & 7], cpu_state.ST[(cpu_state.TOP + 7) & 7]);
|
||||
}
|
||||
fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,43 +1,44 @@
|
||||
#define C0 (1<<8)
|
||||
#define C1 (1<<9)
|
||||
#define C2 (1<<10)
|
||||
#define C3 (1<<14)
|
||||
#define C0 (1 << 8)
|
||||
#define C1 (1 << 9)
|
||||
#define C2 (1 << 10)
|
||||
#define C3 (1 << 14)
|
||||
|
||||
extern uint32_t x87_pc_off,x87_op_off;
|
||||
extern uint16_t x87_pc_seg,x87_op_seg;
|
||||
extern uint32_t x87_pc_off, x87_op_off;
|
||||
extern uint16_t x87_pc_seg, x87_op_seg;
|
||||
|
||||
static __inline void x87_set_mmx(void)
|
||||
static __inline void
|
||||
x87_set_mmx(void)
|
||||
{
|
||||
uint64_t *p;
|
||||
cpu_state.TOP = 0;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
*p = 0x0101010101010101ull;
|
||||
cpu_state.ismmx = 1;
|
||||
uint64_t *p;
|
||||
cpu_state.TOP = 0;
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
*p = 0x0101010101010101ull;
|
||||
cpu_state.ismmx = 1;
|
||||
}
|
||||
|
||||
static __inline void x87_emms(void)
|
||||
static __inline void
|
||||
x87_emms(void)
|
||||
{
|
||||
uint64_t *p;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
*p = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
uint64_t *p;
|
||||
p = (uint64_t *) cpu_state.tag;
|
||||
*p = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
}
|
||||
|
||||
|
||||
uint16_t x87_gettag(void);
|
||||
void x87_settag(uint16_t new_tag);
|
||||
void x87_settag(uint16_t new_tag);
|
||||
|
||||
#define TAG_EMPTY 0
|
||||
#define TAG_VALID (1 << 0)
|
||||
#define TAG_EMPTY 0
|
||||
#define TAG_VALID (1 << 0)
|
||||
/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#define TAG_UINT64 (1 << 7)
|
||||
# define TAG_UINT64 (1 << 7)
|
||||
#else
|
||||
#define TAG_UINT64 (1 << 2)
|
||||
# define TAG_UINT64 (1 << 2)
|
||||
#endif
|
||||
|
||||
/*Old dynarec stuff.*/
|
||||
#define TAG_NOT_UINT64 0xfb
|
||||
#define TAG_NOT_UINT64 0xfb
|
||||
|
||||
#define X87_ROUNDING_NEAREST 0
|
||||
#define X87_ROUNDING_DOWN 1
|
||||
|
||||
@@ -24,443 +24,446 @@
|
||||
#include <fenv.h>
|
||||
#include "x87_timings.h"
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FPU_LOG
|
||||
extern void fpu_log(const char *fmt, ...);
|
||||
extern void fpu_log(const char *fmt, ...);
|
||||
#else
|
||||
#ifndef fpu_log
|
||||
#define fpu_log(fmt, ...)
|
||||
#endif
|
||||
# ifndef fpu_log
|
||||
# define fpu_log(fmt, ...)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO};
|
||||
static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO };
|
||||
|
||||
#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)]
|
||||
#define ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)]
|
||||
|
||||
#define C0 (1<<8)
|
||||
#define C1 (1<<9)
|
||||
#define C2 (1<<10)
|
||||
#define C3 (1<<14)
|
||||
#define C0 (1 << 8)
|
||||
#define C1 (1 << 9)
|
||||
#define C2 (1 << 10)
|
||||
#define C3 (1 << 14)
|
||||
|
||||
#define STATUS_ZERODIVIDE 4
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
#else
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define x87_div(dst, src1, src2) do \
|
||||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
if (!(cpu_state.npxc & 0x80)) { \
|
||||
cpu_state.npxs |= 0x80; \
|
||||
nmi = 1; \
|
||||
} \
|
||||
return 1; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
dst = src1 / (double)src2; \
|
||||
# define x87_div(dst, src1, src2) \
|
||||
do { \
|
||||
if (((double) src2) == 0.0) { \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double) src2; \
|
||||
else { \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
if (!(cpu_state.npxc & 0x80)) { \
|
||||
cpu_state.npxs |= 0x80; \
|
||||
nmi = 1; \
|
||||
} \
|
||||
return 1; \
|
||||
} \
|
||||
} else \
|
||||
dst = src1 / (double) src2; \
|
||||
} while (0)
|
||||
#else
|
||||
#define x87_div(dst, src1, src2) do \
|
||||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
dst = src1 / (double)src2; \
|
||||
# define x87_div(dst, src1, src2) \
|
||||
do { \
|
||||
if (((double) src2) == 0.0) { \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double) src2; \
|
||||
else { \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
} \
|
||||
} else \
|
||||
dst = src1 / (double) src2; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static __inline void x87_checkexceptions(void)
|
||||
static __inline void
|
||||
x87_checkexceptions(void)
|
||||
{
|
||||
}
|
||||
|
||||
static __inline void x87_push(double i)
|
||||
static __inline void
|
||||
x87_push(double i)
|
||||
{
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.TOP--;
|
||||
cpu_state.TOP--;
|
||||
#else
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
|
||||
#endif
|
||||
cpu_state.ST[cpu_state.TOP&7] = i;
|
||||
cpu_state.ST[cpu_state.TOP & 7] = i;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? TAG_VALID : 0;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = (i == 0.0) ? TAG_VALID : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void x87_push_u64(uint64_t i)
|
||||
static __inline void
|
||||
x87_push_u64(uint64_t i)
|
||||
{
|
||||
union
|
||||
{
|
||||
double d;
|
||||
uint64_t ll;
|
||||
} td;
|
||||
union {
|
||||
double d;
|
||||
uint64_t ll;
|
||||
} td;
|
||||
|
||||
td.ll = i;
|
||||
td.ll = i;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.TOP--;
|
||||
cpu_state.TOP--;
|
||||
#else
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
|
||||
#endif
|
||||
cpu_state.ST[cpu_state.TOP&7] = td.d;
|
||||
cpu_state.ST[cpu_state.TOP & 7] = td.d;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? TAG_VALID : 0;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = (td.d == 0.0) ? TAG_VALID : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline double x87_pop(void)
|
||||
static __inline double
|
||||
x87_pop(void)
|
||||
{
|
||||
double t = cpu_state.ST[cpu_state.TOP&7];
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY;
|
||||
double t = cpu_state.ST[cpu_state.TOP & 7];
|
||||
cpu_state.tag[cpu_state.TOP & 7] = TAG_EMPTY;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.TOP++;
|
||||
cpu_state.TOP++;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] |= TAG_UINT64;
|
||||
cpu_state.TOP=(cpu_state.TOP+1)&7;
|
||||
cpu_state.tag[cpu_state.TOP & 7] |= TAG_UINT64;
|
||||
cpu_state.TOP = (cpu_state.TOP + 1) & 7;
|
||||
#endif
|
||||
return t;
|
||||
return t;
|
||||
}
|
||||
|
||||
static __inline int16_t x87_fround16(double b)
|
||||
static __inline int16_t
|
||||
x87_fround16(double b)
|
||||
{
|
||||
int16_t a, c;
|
||||
int16_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int16_t)floor(b);
|
||||
c = (int16_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int16_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int16_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int16_t)b;
|
||||
}
|
||||
switch ((cpu_state.npxc >> 10) & 3) {
|
||||
case 0: /*Nearest*/
|
||||
a = (int16_t) floor(b);
|
||||
c = (int16_t) floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int16_t) floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int16_t) ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int16_t) b;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline int64_t x87_fround16_64(double b)
|
||||
static __inline int64_t
|
||||
x87_fround16_64(double b)
|
||||
{
|
||||
return (int64_t) x87_fround16(b);
|
||||
}
|
||||
|
||||
static __inline int32_t x87_fround32(double b)
|
||||
static __inline int32_t
|
||||
x87_fround32(double b)
|
||||
{
|
||||
int32_t a, c;
|
||||
int32_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int32_t)floor(b);
|
||||
c = (int32_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int32_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int32_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int32_t)b;
|
||||
}
|
||||
switch ((cpu_state.npxc >> 10) & 3) {
|
||||
case 0: /*Nearest*/
|
||||
a = (int32_t) floor(b);
|
||||
c = (int32_t) floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int32_t) floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int32_t) ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int32_t) b;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline int64_t x87_fround32_64(double b)
|
||||
static __inline int64_t
|
||||
x87_fround32_64(double b)
|
||||
{
|
||||
return (int64_t) x87_fround32(b);
|
||||
}
|
||||
|
||||
static __inline int64_t x87_fround(double b)
|
||||
static __inline int64_t
|
||||
x87_fround(double b)
|
||||
{
|
||||
int64_t a, c;
|
||||
int64_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
c = (int64_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int64_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int64_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int64_t)b;
|
||||
}
|
||||
switch ((cpu_state.npxc >> 10) & 3) {
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t) floor(b);
|
||||
c = (int64_t) floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int64_t) floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int64_t) ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int64_t) b;
|
||||
}
|
||||
|
||||
return 0LL;
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
#include "x87_ops_conv.h"
|
||||
|
||||
static __inline double x87_ld80(void)
|
||||
static __inline double
|
||||
x87_ld80(void)
|
||||
{
|
||||
x87_conv_t test;
|
||||
test.eind.ll = readmeml(easeg,cpu_state.eaaddr);
|
||||
test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32;
|
||||
test.begin = readmemw(easeg,cpu_state.eaaddr+8);
|
||||
return x87_from80(&test);
|
||||
x87_conv_t test;
|
||||
test.eind.ll = readmeml(easeg, cpu_state.eaaddr);
|
||||
test.eind.ll |= (uint64_t) readmeml(easeg, cpu_state.eaaddr + 4) << 32;
|
||||
test.begin = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
return x87_from80(&test);
|
||||
}
|
||||
|
||||
static __inline void x87_st80(double d)
|
||||
static __inline void
|
||||
x87_st80(double d)
|
||||
{
|
||||
x87_conv_t test;
|
||||
x87_to80(d, &test);
|
||||
writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff);
|
||||
writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32);
|
||||
writememw(easeg,cpu_state.eaaddr+8,test.begin);
|
||||
x87_conv_t test;
|
||||
x87_to80(d, &test);
|
||||
writememl(easeg, cpu_state.eaaddr, test.eind.ll & 0xffffffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, test.eind.ll >> 32);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, test.begin);
|
||||
}
|
||||
|
||||
static __inline void x87_st_fsave(int reg)
|
||||
static __inline void
|
||||
x87_st_fsave(int reg)
|
||||
{
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
|
||||
if (cpu_state.tag[reg] & TAG_UINT64)
|
||||
{
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0x5555);
|
||||
}
|
||||
else
|
||||
x87_st80(cpu_state.ST[reg]);
|
||||
if (cpu_state.tag[reg] & TAG_UINT64) {
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0x5555);
|
||||
} else
|
||||
x87_st80(cpu_state.ST[reg]);
|
||||
}
|
||||
|
||||
static __inline void x87_ld_frstor(int reg)
|
||||
static __inline void
|
||||
x87_ld_frstor(int reg)
|
||||
{
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
|
||||
cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr);
|
||||
cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr);
|
||||
cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64))
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64))
|
||||
#else
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2))
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2))
|
||||
#endif
|
||||
{
|
||||
{
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
cpu_state.tag[reg] = TAG_UINT64;
|
||||
cpu_state.tag[reg] = TAG_UINT64;
|
||||
#endif
|
||||
cpu_state.ST[reg] = (double)cpu_state.MM[reg].q;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.ST[reg] = (double) cpu_state.MM[reg].q;
|
||||
} else {
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[reg] &= ~TAG_UINT64;
|
||||
cpu_state.tag[reg] &= ~TAG_UINT64;
|
||||
#endif
|
||||
cpu_state.ST[reg] = x87_ld80();
|
||||
}
|
||||
cpu_state.ST[reg] = x87_ld80();
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4)
|
||||
static __inline void
|
||||
x87_ldmmx(MMX_REG *r, uint16_t *w4)
|
||||
{
|
||||
r->l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
|
||||
*w4 = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
r->l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
|
||||
*w4 = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
}
|
||||
|
||||
static __inline void x87_stmmx(MMX_REG r)
|
||||
static __inline void
|
||||
x87_stmmx(MMX_REG r)
|
||||
{
|
||||
writememl(easeg, cpu_state.eaaddr, r.l[0]);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, r.l[1]);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0xffff);
|
||||
writememl(easeg, cpu_state.eaaddr, r.l[0]);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, r.l[1]);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0xffff);
|
||||
}
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
static __inline uint16_t x87_compare(double a, double b)
|
||||
static __inline uint16_t
|
||||
x87_compare(double a, double b)
|
||||
{
|
||||
#ifdef X87_INLINE_ASM
|
||||
uint32_t result;
|
||||
double ea = a, eb = b;
|
||||
const uint64_t ia = 0x3fec1a6ff866a936ull;
|
||||
const uint64_t ib = 0x3fec1a6ff866a938ull;
|
||||
uint32_t result;
|
||||
double ea = a, eb = b;
|
||||
const uint64_t ia = 0x3fec1a6ff866a936ull;
|
||||
const uint64_t ib = 0x3fec1a6ff866a938ull;
|
||||
|
||||
/* Hack to make CHKCOP happy. */
|
||||
if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8))
|
||||
return C3;
|
||||
/* Hack to make CHKCOP happy. */
|
||||
if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8))
|
||||
return C3;
|
||||
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) &&
|
||||
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile ("" : : : "memory");
|
||||
# if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile(""
|
||||
:
|
||||
:
|
||||
: "memory");
|
||||
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fcompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m" (result)
|
||||
: "m" (ea), "m" (eb)
|
||||
);
|
||||
#else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fcompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m"(result)
|
||||
: "m"(ea), "m"(eb));
|
||||
# else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
fld eb
|
||||
fld ea
|
||||
fclex
|
||||
fcompp
|
||||
fnstsw result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
# endif
|
||||
|
||||
return result & (C0|C2|C3);
|
||||
return result & (C0 | C2 | C3);
|
||||
#else
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
double ea = a, eb = b;
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
double ea = a, eb = b;
|
||||
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) &&
|
||||
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
|
||||
if (ea == eb)
|
||||
result |= C3;
|
||||
else if (ea < eb)
|
||||
result |= C0;
|
||||
if (ea == eb)
|
||||
result |= C3;
|
||||
else if (ea < eb)
|
||||
result |= C0;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline uint16_t x87_ucompare(double a, double b)
|
||||
static __inline uint16_t
|
||||
x87_ucompare(double a, double b)
|
||||
{
|
||||
#ifdef X87_INLINE_ASM
|
||||
uint32_t result;
|
||||
uint32_t result;
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile ("" : : : "memory");
|
||||
# if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile(""
|
||||
:
|
||||
:
|
||||
: "memory");
|
||||
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fucompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m" (result)
|
||||
: "m" (a), "m" (b)
|
||||
);
|
||||
#else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fucompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m"(result)
|
||||
: "m"(a), "m"(b));
|
||||
# else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
fld b
|
||||
fld a
|
||||
fclex
|
||||
fcompp
|
||||
fnstsw result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
# endif
|
||||
|
||||
return result & (C0|C2|C3);
|
||||
return result & (C0 | C2 | C3);
|
||||
#else
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
|
||||
if (a == b)
|
||||
result |= C3;
|
||||
else if (a < b)
|
||||
result |= C0;
|
||||
if (a == b)
|
||||
result |= C3;
|
||||
else if (a < b)
|
||||
result |= C0;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef union
|
||||
{
|
||||
float s;
|
||||
uint32_t i;
|
||||
typedef union {
|
||||
float s;
|
||||
uint32_t i;
|
||||
} x87_ts;
|
||||
|
||||
typedef union
|
||||
{
|
||||
double d;
|
||||
uint64_t i;
|
||||
typedef union {
|
||||
double d;
|
||||
uint64_t i;
|
||||
} x87_td;
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define FP_ENTER() { \
|
||||
}
|
||||
# define FP_ENTER() \
|
||||
{ \
|
||||
}
|
||||
#else
|
||||
#define FP_ENTER() do \
|
||||
{ \
|
||||
if (cr0 & 0xc) \
|
||||
{ \
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
# define FP_ENTER() \
|
||||
do { \
|
||||
if (cr0 & 0xc) { \
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP&7] = TAG_VALID
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID
|
||||
#else
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64
|
||||
#endif
|
||||
|
||||
#include "x87_ops_arith.h"
|
||||
@@ -468,56 +471,55 @@ typedef union
|
||||
#include "x87_ops_loadstore.h"
|
||||
|
||||
#ifndef FPU_8087
|
||||
static int op_nofpu_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op_nofpu_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cr0 & 0xc)
|
||||
{
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
if (cr0 & 0xc) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
} else {
|
||||
fetch_ea_16(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static int op_nofpu_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op_nofpu_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cr0 & 0xc)
|
||||
{
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
if (cr0 & 0xc) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
} else {
|
||||
fetch_ea_32(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FPU_8087
|
||||
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
static int
|
||||
FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
{
|
||||
geteaw();
|
||||
wait(timing_rr, 0);
|
||||
return 0;
|
||||
geteaw();
|
||||
wait(timing_rr, 0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
static int
|
||||
FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FPU_ILLEGAL_a32(uint32_t fetchdat)
|
||||
static int
|
||||
FPU_ILLEGAL_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -774,7 +776,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] =
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
};
|
||||
#else
|
||||
#define ILLEGAL_a32 FPU_ILLEGAL_a32
|
||||
# define ILLEGAL_a32 FPU_ILLEGAL_a32
|
||||
|
||||
const OpFn OP_TABLE(fpu_d8_a16)[32] =
|
||||
{
|
||||
|
||||
@@ -1,457 +1,508 @@
|
||||
#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \
|
||||
static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
|
||||
ST(0) += use_var; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.npxs &= ~(C0|C2|C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.npxs &= ~(C0|C2|C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
x87_pop(); \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), ST(0), use_var); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), use_var, ST(0)); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv ## cycle_postfix) : ((x87_concurrency.fdiv ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) *= use_var; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul ## cycle_postfix) : ((x87_timings.fmul ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul ## cycle_postfix) : ((x87_concurrency.fmul ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) -= use_var; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) = use_var - ST(0); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \
|
||||
static int opFADD##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
|
||||
ST(0) += use_var; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFCOM##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFCOMP##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \
|
||||
x87_pop(); \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFDIV##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
x87_div(ST(0), ST(0), use_var); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFDIVR##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
x87_div(ST(0), use_var, ST(0)); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFMUL##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
ST(0) *= use_var; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul##cycle_postfix) : ((x87_timings.fmul##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFSUB##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
ST(0) -= use_var; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFSUBR##name##_a##a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_##a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
ST(0) = use_var - ST(0); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32)
|
||||
#ifndef FPU_8087
|
||||
opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32)
|
||||
opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32)
|
||||
#endif
|
||||
opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64)
|
||||
opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64)
|
||||
#ifndef FPU_8087
|
||||
opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64)
|
||||
opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64)
|
||||
#endif
|
||||
|
||||
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16)
|
||||
opFPU(iw, uint16_t, 16, t, geteaw, (double) (int16_t) t, _i16)
|
||||
#ifndef FPU_8087
|
||||
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16)
|
||||
opFPU(iw, uint16_t, 32, t, geteaw, (double) (int16_t) t, _i16)
|
||||
#endif
|
||||
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32)
|
||||
opFPU(il, uint32_t, 16, t, geteal, (double) (int32_t) t, _i32)
|
||||
#ifndef FPU_8087
|
||||
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32)
|
||||
opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32)
|
||||
#endif
|
||||
|
||||
|
||||
static int opFADD(uint32_t fetchdat)
|
||||
static int opFADD(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) + ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) + ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFADDr(uint32_t fetchdat)
|
||||
static int
|
||||
opFADDr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFADDP(uint32_t fetchdat)
|
||||
static int
|
||||
opFADDP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFCOM(uint32_t fetchdat)
|
||||
static int
|
||||
opFCOM(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3);
|
||||
if (ST(0) == ST(fetchdat & 7))
|
||||
cpu_state.npxs |= C3;
|
||||
else if (ST(0) < ST(fetchdat & 7))
|
||||
cpu_state.npxs |= C0;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFCOMP(uint32_t fetchdat)
|
||||
static int
|
||||
opFCOMP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3);
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFCOMPP(uint32_t fetchdat)
|
||||
static int
|
||||
opFCOMPP(uint32_t fetchdat)
|
||||
{
|
||||
uint64_t *p, *q;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
p = (uint64_t *)&ST(0);
|
||||
q = (uint64_t *)&ST(1);
|
||||
if ((*p == ((uint64_t)1 << 63) && *q == 0) && (fpu_type >= FPU_287XL))
|
||||
cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/
|
||||
else
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(1));
|
||||
uint64_t *p, *q;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3);
|
||||
p = (uint64_t *) &ST(0);
|
||||
q = (uint64_t *) &ST(1);
|
||||
if ((*p == ((uint64_t) 1 << 63) && *q == 0) && (fpu_type >= FPU_287XL))
|
||||
cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/
|
||||
else
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(1));
|
||||
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFUCOMPP(uint32_t fetchdat)
|
||||
static int
|
||||
opFUCOMPP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFCOMI(uint32_t fetchdat)
|
||||
static int
|
||||
opFCOMI(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7))
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFCOMIP(uint32_t fetchdat)
|
||||
static int
|
||||
opFCOMIP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7))
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFDIV(uint32_t fetchdat)
|
||||
static int
|
||||
opFDIV(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVr(uint32_t fetchdat)
|
||||
static int
|
||||
opFDIVr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVP(uint32_t fetchdat)
|
||||
static int
|
||||
opFDIVP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFDIVR(uint32_t fetchdat)
|
||||
static int
|
||||
opFDIVR(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(fetchdat&7), ST(0));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(fetchdat & 7), ST(0));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVRr(uint32_t fetchdat)
|
||||
static int
|
||||
opFDIVRr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVRP(uint32_t fetchdat)
|
||||
static int
|
||||
opFDIVRP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFMUL(uint32_t fetchdat)
|
||||
static int
|
||||
opFMUL(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFMULr(uint32_t fetchdat)
|
||||
static int
|
||||
opFMULr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFMULP(uint32_t fetchdat)
|
||||
static int
|
||||
opFMULP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFSUB(uint32_t fetchdat)
|
||||
static int
|
||||
opFSUB(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBr(uint32_t fetchdat)
|
||||
static int
|
||||
opFSUBr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBP(uint32_t fetchdat)
|
||||
static int
|
||||
opFSUBP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFSUBR(uint32_t fetchdat)
|
||||
static int
|
||||
opFSUBR(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBRr(uint32_t fetchdat)
|
||||
static int
|
||||
opFSUBRr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBRP(uint32_t fetchdat)
|
||||
static int
|
||||
opFSUBRP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FPU_8087
|
||||
static int opFUCOM(uint32_t fetchdat)
|
||||
static int
|
||||
opFUCOM(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFUCOMP(uint32_t fetchdat)
|
||||
static int
|
||||
opFUCOMP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0 | C2 | C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opFUCOMI(uint32_t fetchdat)
|
||||
static int
|
||||
opFUCOMI(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7))
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
static int opFUCOMIP(uint32_t fetchdat)
|
||||
static int
|
||||
opFUCOMIP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7))
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,65 +4,66 @@
|
||||
typedef struct {
|
||||
int16_t begin;
|
||||
union {
|
||||
double d;
|
||||
double d;
|
||||
uint64_t ll;
|
||||
} eind;
|
||||
} x87_conv_t;
|
||||
|
||||
static __inline double x87_from80(x87_conv_t *test)
|
||||
static __inline double
|
||||
x87_from80(x87_conv_t *test)
|
||||
{
|
||||
int64_t exp64;
|
||||
int64_t blah;
|
||||
int64_t exp64final;
|
||||
int64_t mant64;
|
||||
int64_t sign;
|
||||
int64_t exp64;
|
||||
int64_t blah;
|
||||
int64_t exp64final;
|
||||
int64_t mant64;
|
||||
int64_t sign;
|
||||
|
||||
exp64 = (((test->begin&0x7fff) - BIAS80));
|
||||
blah = ((exp64 >0)?exp64:-exp64)&0x3ff;
|
||||
exp64final = ((exp64 >0)?blah:-blah) +BIAS64;
|
||||
exp64 = (((test->begin & 0x7fff) - BIAS80));
|
||||
blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff;
|
||||
exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64;
|
||||
|
||||
mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll);
|
||||
sign = (test->begin&0x8000)?1:0;
|
||||
mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll);
|
||||
sign = (test->begin & 0x8000) ? 1 : 0;
|
||||
|
||||
if ((test->begin & 0x7fff) == 0x7fff)
|
||||
exp64final = 0x7ff;
|
||||
if ((test->begin & 0x7fff) == 0)
|
||||
exp64final = 0;
|
||||
if (test->eind.ll & 0x400)
|
||||
mant64++;
|
||||
if ((test->begin & 0x7fff) == 0x7fff)
|
||||
exp64final = 0x7ff;
|
||||
if ((test->begin & 0x7fff) == 0)
|
||||
exp64final = 0;
|
||||
if (test->eind.ll & 0x400)
|
||||
mant64++;
|
||||
|
||||
test->eind.ll = (sign <<63)|(exp64final << 52)| mant64;
|
||||
test->eind.ll = (sign << 63) | (exp64final << 52) | mant64;
|
||||
|
||||
return test->eind.d;
|
||||
return test->eind.d;
|
||||
}
|
||||
|
||||
static __inline void x87_to80(double d, x87_conv_t *test)
|
||||
static __inline void
|
||||
x87_to80(double d, x87_conv_t *test)
|
||||
{
|
||||
int64_t sign80;
|
||||
int64_t exp80;
|
||||
int64_t exp80final;
|
||||
int64_t mant80;
|
||||
int64_t mant80final;
|
||||
int64_t sign80;
|
||||
int64_t exp80;
|
||||
int64_t exp80final;
|
||||
int64_t mant80;
|
||||
int64_t mant80final;
|
||||
|
||||
test->eind.d=d;
|
||||
test->eind.d = d;
|
||||
|
||||
sign80 = (test->eind.ll&(0x8000000000000000ll))?1:0;
|
||||
exp80 = test->eind.ll&(0x7ff0000000000000ll);
|
||||
exp80final = (exp80>>52);
|
||||
mant80 = test->eind.ll&(0x000fffffffffffffll);
|
||||
mant80final = (mant80 << 11);
|
||||
sign80 = (test->eind.ll & (0x8000000000000000ll)) ? 1 : 0;
|
||||
exp80 = test->eind.ll & (0x7ff0000000000000ll);
|
||||
exp80final = (exp80 >> 52);
|
||||
mant80 = test->eind.ll & (0x000fffffffffffffll);
|
||||
mant80final = (mant80 << 11);
|
||||
|
||||
if (exp80final == 0x7ff) /*Infinity / Nan*/
|
||||
{
|
||||
exp80final = 0x7fff;
|
||||
mant80final |= (0x8000000000000000ll);
|
||||
}
|
||||
else if (d != 0){ /* Zero is a special case */
|
||||
/* Elvira wants the 8 and tcalc doesn't */
|
||||
mant80final |= (0x8000000000000000ll);
|
||||
/* Ca-cyber doesn't like this when result is zero. */
|
||||
exp80final += (BIAS80 - BIAS64);
|
||||
}
|
||||
test->begin = (((int16_t)sign80)<<15)| (int16_t)exp80final;
|
||||
test->eind.ll = mant80final;
|
||||
if (exp80final == 0x7ff) /*Infinity / Nan*/
|
||||
{
|
||||
exp80final = 0x7fff;
|
||||
mant80final |= (0x8000000000000000ll);
|
||||
} else if (d != 0) { /* Zero is a special case */
|
||||
/* Elvira wants the 8 and tcalc doesn't */
|
||||
mant80final |= (0x8000000000000000ll);
|
||||
/* Ca-cyber doesn't like this when result is zero. */
|
||||
exp80final += (BIAS80 - BIAS64);
|
||||
}
|
||||
test->begin = (((int16_t) sign80) << 15) | (int16_t) exp80final;
|
||||
test->eind.ll = mant80final;
|
||||
}
|
||||
|
||||
@@ -16,496 +16,582 @@
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
static int opFILDiw_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFILDiw_a16(uint32_t fetchdat)
|
||||
{
|
||||
int16_t temp;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi));
|
||||
return 0;
|
||||
int16_t temp;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) temp);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFILDiw_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFILDiw_a32(uint32_t fetchdat)
|
||||
{
|
||||
int16_t temp;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi));
|
||||
return 0;
|
||||
int16_t temp;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) temp);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTiw_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTiw_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTiw_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTiw_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTPiw_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTPiw_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0)));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTPiw_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTPiw_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(x87_fround16(ST(0)));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFILDiq_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFILDiq_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp64 = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP&7].q = temp64;
|
||||
FP_TAG_DEFAULT;
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp64 = geteaq();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) temp64);
|
||||
cpu_state.MM[cpu_state.TOP & 7].q = temp64;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFILDiq_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFILDiq_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp64 = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP&7].q = temp64;
|
||||
FP_TAG_DEFAULT;
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp64 = geteaq();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) temp64);
|
||||
cpu_state.MM[cpu_state.TOP & 7].q = temp64;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int FBSTP_a16(uint32_t fetchdat)
|
||||
static int
|
||||
FBSTP_a16(uint32_t fetchdat)
|
||||
{
|
||||
double tempd;
|
||||
int c;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
tempd = ST(0);
|
||||
if (tempd < 0.0)
|
||||
tempd = -tempd;
|
||||
for (c = 0; c < 9; c++)
|
||||
{
|
||||
uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0));
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4;
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
writememb(easeg, cpu_state.eaaddr + c, tempc);
|
||||
}
|
||||
tempc = (uint8_t)floor(fmod(tempd, 10.0));
|
||||
if (ST(0) < 0.0) tempc |= 0x80;
|
||||
writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi));
|
||||
return 0;
|
||||
double tempd;
|
||||
int c;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
tempd = ST(0);
|
||||
if (tempd < 0.0)
|
||||
tempd = -tempd;
|
||||
for (c = 0; c < 9; c++) {
|
||||
uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0));
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4;
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
writememb(easeg, cpu_state.eaaddr + c, tempc);
|
||||
}
|
||||
tempc = (uint8_t) floor(fmod(tempd, 10.0));
|
||||
if (ST(0) < 0.0)
|
||||
tempc |= 0x80;
|
||||
writememb(easeg, cpu_state.eaaddr + 9, tempc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int FBSTP_a32(uint32_t fetchdat)
|
||||
static int
|
||||
FBSTP_a32(uint32_t fetchdat)
|
||||
{
|
||||
double tempd;
|
||||
int c;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
tempd = ST(0);
|
||||
if (tempd < 0.0)
|
||||
tempd = -tempd;
|
||||
for (c = 0; c < 9; c++)
|
||||
{
|
||||
uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0));
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4;
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
writememb(easeg, cpu_state.eaaddr + c, tempc);
|
||||
}
|
||||
tempc = (uint8_t)floor(fmod(tempd, 10.0));
|
||||
if (ST(0) < 0.0) tempc |= 0x80;
|
||||
writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi));
|
||||
return 0;
|
||||
double tempd;
|
||||
int c;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
tempd = ST(0);
|
||||
if (tempd < 0.0)
|
||||
tempd = -tempd;
|
||||
for (c = 0; c < 9; c++) {
|
||||
uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0));
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4;
|
||||
tempd -= floor(fmod(tempd, 10.0));
|
||||
tempd /= 10.0;
|
||||
writememb(easeg, cpu_state.eaaddr + c, tempc);
|
||||
}
|
||||
tempc = (uint8_t) floor(fmod(tempd, 10.0));
|
||||
if (ST(0) < 0.0)
|
||||
tempc |= 0x80;
|
||||
writememb(easeg, cpu_state.eaaddr + 9, tempc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int FISTPiq_a16(uint32_t fetchdat)
|
||||
static int
|
||||
FISTPiq_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64)
|
||||
temp64 = cpu_state.MM[cpu_state.TOP&7].q;
|
||||
else
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi));
|
||||
return 0;
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64)
|
||||
temp64 = cpu_state.MM[cpu_state.TOP & 7].q;
|
||||
else
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int FISTPiq_a32(uint32_t fetchdat)
|
||||
static int
|
||||
FISTPiq_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64)
|
||||
temp64 = cpu_state.MM[cpu_state.TOP&7].q;
|
||||
else
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi));
|
||||
return 0;
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64)
|
||||
temp64 = cpu_state.MM[cpu_state.TOP & 7].q;
|
||||
else
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFILDil_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFILDil_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)templ);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi));
|
||||
return 0;
|
||||
int32_t templ;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) templ);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFILDil_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFILDil_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)templ);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi));
|
||||
return 0;
|
||||
int32_t templ;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) templ);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTil_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTil_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTil_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTil_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0)));
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTPil_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTPil_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0)));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTPil_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFISTPil_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(x87_fround32(ST(0)));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFLDe_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFLDe_a16(uint32_t fetchdat)
|
||||
{
|
||||
double t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t=x87_ld80(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
double t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t = x87_ld80();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDe_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFLDe_a32(uint32_t fetchdat)
|
||||
{
|
||||
double t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t=x87_ld80(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
double t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t = x87_ld80();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTPe_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTPe_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTPe_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTPe_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFLDd_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFLDd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi));
|
||||
return 0;
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDd_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFLDd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi));
|
||||
return 0;
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTd_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTd_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTPd_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTPd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return 0;
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTPd_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTPd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return 0;
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFLDs_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFLDs_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)ts.s);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) ts.s);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDs_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFLDs_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)ts.s);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_push((double) ts.s);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTs_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTs_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float) ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTs_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTs_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float) ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTPs_a16(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTPs_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float) ST(0);
|
||||
seteal(ts.i);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTPs_a32(uint32_t fetchdat)
|
||||
static int
|
||||
opFSTPs_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float) ST(0);
|
||||
seteal(ts.i);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -85,80 +85,79 @@ const x87_timings_t x87_timings_8087 = {
|
||||
.fyl2xp1 = (700 + 1000) / 2
|
||||
};
|
||||
|
||||
const x87_timings_t x87_timings_80187 =
|
||||
{
|
||||
.f2xm1 = (310 + 630) / 2,
|
||||
.fabs = (10 + 17) / 2,
|
||||
.fadd = (70 + 100) / 2,
|
||||
.fadd_32 = (90 + 120) / 2,
|
||||
.fadd_64 = (95 + 125) / 2,
|
||||
.fbld = (290 + 310) / 2,
|
||||
.fbstp = (520 + 540) / 2,
|
||||
.fchs = (10 + 17) / 2,
|
||||
.fclex = (2 + 8) / 2,
|
||||
.fcom = (40 + 50) / 2,
|
||||
.fcom_32 = (60 + 70) / 2,
|
||||
.fcom_64 = (65 + 75) / 2,
|
||||
.fcos = 0, /*387+*/
|
||||
.fincdecstp = (6 + 12) / 2,
|
||||
.fdisi_eni = (6 + 12) / 2,
|
||||
.fdiv = (193 + 203) / 2,
|
||||
.fdiv_32 = (215 + 225) / 2,
|
||||
.fdiv_64 = (220 + 230) / 2,
|
||||
.ffree = (9 + 16) / 2,
|
||||
.fadd_i16 = (102 + 137) / 2,
|
||||
.fadd_i32 = (108 + 143) / 2,
|
||||
.fcom_i16 = (72 + 86) / 2,
|
||||
.fcom_i32 = (78 + 91) / 2,
|
||||
.fdiv_i16 = (224 + 238) / 2,
|
||||
.fdiv_i32 = (230 + 243) / 2,
|
||||
.fild_16 = (46 + 54) / 2,
|
||||
.fild_32 = (50 + 60) / 2,
|
||||
.fild_64 = (60 + 68) / 2,
|
||||
.fmul_i16 = (124 + 138) / 2,
|
||||
.fmul_i32 = (130 + 144) / 2,
|
||||
.finit = (2 + 8) / 2,
|
||||
.fist_16 = (80 + 90) / 2,
|
||||
.fist_32 = (82 + 92) / 2,
|
||||
.fist_64 = (94 + 105) / 2,
|
||||
.fld = (17 + 22) / 2,
|
||||
.fld_32 = (38 + 56) / 2,
|
||||
.fld_64 = (40 + 60) / 2,
|
||||
.fld_80 = (53 + 65) / 2,
|
||||
.fld_z1 = (11 + 21) / 2,
|
||||
.fld_const = (15 + 24) / 2,
|
||||
.fldcw = (7 + 14) / 2,
|
||||
.fldenv = (35 + 45) / 2,
|
||||
.fmul = (90 + 145) / 2,
|
||||
.fmul_32 = (110 + 125) / 2,
|
||||
.fmul_64 = (154 + 168) / 2,
|
||||
.fnop = (10 + 16) / 2,
|
||||
.fpatan = (250 + 800) / 2,
|
||||
.fprem = (15 + 190) / 2,
|
||||
.fprem1 = 0, /*387+*/
|
||||
.fptan = (30 + 540) / 2,
|
||||
.frndint = (16 + 50) / 2,
|
||||
.frstor = (197 + 207) / 2,
|
||||
.fsave = (197 + 207) / 2,
|
||||
.fscale = (32 + 38) / 2,
|
||||
.fsetpm = 0, /*287+*/
|
||||
.fsin_cos = 0, /*387+*/
|
||||
.fsincos = 0, /*387+*/
|
||||
.fsqrt = (180 + 186) / 2,
|
||||
.fst = (15 + 22) / 2,
|
||||
.fst_32 = (84 + 90) / 2,
|
||||
.fst_64 = (96 + 104) / 2,
|
||||
.fst_80 = (52 + 58) / 2,
|
||||
.fstcw_sw = (12 + 18) / 2,
|
||||
.fstenv = (40 + 50) / 2,
|
||||
.ftst = (38 + 48) / 2,
|
||||
.fucom = 0, /*387+*/
|
||||
.fwait = 4,
|
||||
.fxam = (12 + 23) / 2,
|
||||
.fxch = (10 + 15) / 2,
|
||||
.fxtract = (27 + 55) / 2,
|
||||
.fyl2x = (900 + 1100) / 2,
|
||||
.fyl2xp1 = (700 + 1000) / 2
|
||||
const x87_timings_t x87_timings_80187 = {
|
||||
.f2xm1 = (310 + 630) / 2,
|
||||
.fabs = (10 + 17) / 2,
|
||||
.fadd = (70 + 100) / 2,
|
||||
.fadd_32 = (90 + 120) / 2,
|
||||
.fadd_64 = (95 + 125) / 2,
|
||||
.fbld = (290 + 310) / 2,
|
||||
.fbstp = (520 + 540) / 2,
|
||||
.fchs = (10 + 17) / 2,
|
||||
.fclex = (2 + 8) / 2,
|
||||
.fcom = (40 + 50) / 2,
|
||||
.fcom_32 = (60 + 70) / 2,
|
||||
.fcom_64 = (65 + 75) / 2,
|
||||
.fcos = 0, /*387+*/
|
||||
.fincdecstp = (6 + 12) / 2,
|
||||
.fdisi_eni = (6 + 12) / 2,
|
||||
.fdiv = (193 + 203) / 2,
|
||||
.fdiv_32 = (215 + 225) / 2,
|
||||
.fdiv_64 = (220 + 230) / 2,
|
||||
.ffree = (9 + 16) / 2,
|
||||
.fadd_i16 = (102 + 137) / 2,
|
||||
.fadd_i32 = (108 + 143) / 2,
|
||||
.fcom_i16 = (72 + 86) / 2,
|
||||
.fcom_i32 = (78 + 91) / 2,
|
||||
.fdiv_i16 = (224 + 238) / 2,
|
||||
.fdiv_i32 = (230 + 243) / 2,
|
||||
.fild_16 = (46 + 54) / 2,
|
||||
.fild_32 = (50 + 60) / 2,
|
||||
.fild_64 = (60 + 68) / 2,
|
||||
.fmul_i16 = (124 + 138) / 2,
|
||||
.fmul_i32 = (130 + 144) / 2,
|
||||
.finit = (2 + 8) / 2,
|
||||
.fist_16 = (80 + 90) / 2,
|
||||
.fist_32 = (82 + 92) / 2,
|
||||
.fist_64 = (94 + 105) / 2,
|
||||
.fld = (17 + 22) / 2,
|
||||
.fld_32 = (38 + 56) / 2,
|
||||
.fld_64 = (40 + 60) / 2,
|
||||
.fld_80 = (53 + 65) / 2,
|
||||
.fld_z1 = (11 + 21) / 2,
|
||||
.fld_const = (15 + 24) / 2,
|
||||
.fldcw = (7 + 14) / 2,
|
||||
.fldenv = (35 + 45) / 2,
|
||||
.fmul = (90 + 145) / 2,
|
||||
.fmul_32 = (110 + 125) / 2,
|
||||
.fmul_64 = (154 + 168) / 2,
|
||||
.fnop = (10 + 16) / 2,
|
||||
.fpatan = (250 + 800) / 2,
|
||||
.fprem = (15 + 190) / 2,
|
||||
.fprem1 = 0, /*387+*/
|
||||
.fptan = (30 + 540) / 2,
|
||||
.frndint = (16 + 50) / 2,
|
||||
.frstor = (197 + 207) / 2,
|
||||
.fsave = (197 + 207) / 2,
|
||||
.fscale = (32 + 38) / 2,
|
||||
.fsetpm = 0, /*287+*/
|
||||
.fsin_cos = 0, /*387+*/
|
||||
.fsincos = 0, /*387+*/
|
||||
.fsqrt = (180 + 186) / 2,
|
||||
.fst = (15 + 22) / 2,
|
||||
.fst_32 = (84 + 90) / 2,
|
||||
.fst_64 = (96 + 104) / 2,
|
||||
.fst_80 = (52 + 58) / 2,
|
||||
.fstcw_sw = (12 + 18) / 2,
|
||||
.fstenv = (40 + 50) / 2,
|
||||
.ftst = (38 + 48) / 2,
|
||||
.fucom = 0, /*387+*/
|
||||
.fwait = 4,
|
||||
.fxam = (12 + 23) / 2,
|
||||
.fxch = (10 + 15) / 2,
|
||||
.fxtract = (27 + 55) / 2,
|
||||
.fyl2x = (900 + 1100) / 2,
|
||||
.fyl2xp1 = (700 + 1000) / 2
|
||||
};
|
||||
|
||||
/*Mostly the same as 8087*/
|
||||
|
||||
Reference in New Issue
Block a user