diff --git a/src/cpu/386.c b/src/cpu/386.c index d6d4ded16..662850318 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -6,7 +6,7 @@ #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H @@ -25,14 +25,12 @@ #include <86box/gdbstub.h> #include "386_common.h" #ifdef USE_NEW_DYNAREC -#include "codegen.h" +# include "codegen.h" #endif - #undef CPU_BLOCK_END #define CPU_BLOCK_END() - extern int codegen_flags_changed; int tempc, oldcpl, optype, inttype, oddeven = 0; @@ -41,225 +39,229 @@ int timetolive; uint16_t oldcs; uint32_t oldds, oldss, olddslimit, oldsslimit, - olddslimitw, oldsslimitw; + olddslimitw, oldsslimitw; uint32_t oxpc; uint32_t rmdat32; uint32_t backupregs[16]; x86seg _oldds; - #ifdef ENABLE_386_LOG int x386_do_log = ENABLE_386_LOG; - void x386_log(const char *fmt, ...) { va_list ap; if (x386_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 x386_log(fmt, ...) +# define x386_log(fmt, ...) #endif - #undef CPU_BLOCK_END #define CPU_BLOCK_END() #include "x86_flags.h" -#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 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 OP_TABLE(name) ops_ ## name +#define OP_TABLE(name) ops_##name #if 0 -#define CLOCK_CYCLES(c) \ - {\ - if (fpu_cycles > 0) {\ - fpu_cycles -= (c);\ - if (fpu_cycles < 0) {\ - cycles += fpu_cycles;\ - }\ - } else {\ - cycles -= (c);\ - }\ - } +# define CLOCK_CYCLES(c) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (c); \ + if (fpu_cycles < 0) { \ + cycles += fpu_cycles; \ + } \ + } else { \ + cycles -= (c); \ + } \ + } -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) +# define CLOCK_CYCLES(c) cycles -= (c) +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) #endif #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) #include "x86_ops.h" - void exec386(int cycs) { - int vector, tempi, cycdiff, oldcyc; - int cycle_period, ins_cycles; + int vector, tempi, cycdiff, oldcyc; + int cycle_period, ins_cycles; uint32_t addr; cycles += cycs; while (cycles > 0) { - cycle_period = (timer_target - (uint32_t)tsc) + 1; + cycle_period = (timer_target - (uint32_t) tsc) + 1; - x86_was_reset = 0; - cycdiff = 0; - oldcyc = cycles; - while (cycdiff < cycle_period) { - ins_cycles = cycles; + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + while (cycdiff < cycle_period) { + ins_cycles = cycles; #ifndef USE_NEW_DYNAREC - oldcs=CS; - oldcpl=CPL; + oldcs = CS; + oldcpl = CPL; #endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; #ifndef USE_NEW_DYNAREC - x86_was_reset = 0; + x86_was_reset = 0; #endif - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl(cs + cpu_state.pc); - if (!cpu_state.abrt) { + if (!cpu_state.abrt) { #ifdef ENABLE_386_LOG - if (in_smm) - x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); + if (in_smm) + x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat); #endif - opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } #ifdef ENABLE_386_LOG - else if (in_smm) - x386_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc); + else if (in_smm) + x386_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc); #endif #ifndef USE_NEW_DYNAREC - if (!use32) cpu_state.pc &= 0xffff; + if (!use32) + cpu_state.pc &= 0xffff; #endif - if (cpu_end_block_after_ins) - cpu_end_block_after_ins--; + if (cpu_end_block_after_ins) + cpu_end_block_after_ins--; - if (cpu_state.abrt) { - flags_rebuild(); - tempi = cpu_state.abrt & ABRT_MASK; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; #ifndef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - cpu_state.pc = cpu_state.oldpc; - x386_log("Double fault\n"); - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); + cpu_state.pc = cpu_state.oldpc; + x386_log("Double fault\n"); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); #ifdef ENABLE_386_LOG - x386_log("Triple fault - reset\n"); + x386_log("Triple fault - reset\n"); #endif - } - } - } + } + } + } - if (smi_line) - enter_smm_check(0); - else if (trap) { - flags_rebuild(); - dr[6] |= 0x4000; - if (msw&1) - pmodeint(1,0); - else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (1 << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } else if (nmi && nmi_enable && nmi_mask) { - cpu_state.oldpc = cpu_state.pc; - x86_int(2); - nmi_enable = 0; + if (smi_line) + enter_smm_check(0); + else if (trap) { + flags_rebuild(); + dr[6] |= 0x4000; + if (msw & 1) + pmodeint(1, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } else if (nmi && nmi_enable && nmi_mask) { + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; #ifdef OLD_NMI_BEHAVIOR - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } #else - nmi = 0; + nmi = 0; #endif - } else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) { - vector = picinterrupt(); - if (vector != -1) { - flags_rebuild(); - if (msw & 1) - pmodeint(vector, 0); - else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (vector << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } - } + } else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) { + vector = picinterrupt(); + if (vector != -1) { + flags_rebuild(); + if (msw & 1) + pmodeint(vector, 0); + else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (vector << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } + } - ins_cycles -= cycles; - tsc += ins_cycles; + ins_cycles -= cycles; + tsc += ins_cycles; - cycdiff = oldcyc - cycles; + cycdiff = oldcyc - cycles; - if (timetolive) { - timetolive--; - if (!timetolive) - fatal("Life expired\n"); - } + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); #ifdef USE_GDBSTUB - if (gdbstub_instruction()) - return; + if (gdbstub_instruction()) + return; #endif - } + } } } diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 219bb4b67..01bfba24b 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -39,9 +39,8 @@ /* Is the CPU 8088 or 8086. */ int is8086 = 0; -uint8_t use_custom_nmi_vector = 0; -uint32_t custom_nmi_vector = 0x00000000; - +uint8_t use_custom_nmi_vector = 0; +uint32_t custom_nmi_vector = 0x00000000; /* The prefetch queue (4 bytes for 8088, 6 bytes for 8086). */ static uint8_t pfq[6]; @@ -54,9 +53,9 @@ static uint16_t pfq_ip; /* Pointer tables needed for segment overrides. */ static uint32_t *opseg[4]; -static x86seg *_opseg[4]; +static x86seg *_opseg[4]; -static int noint = 0; +static int noint = 0; static int in_lock = 0; static int cpu_alu_op, pfq_size; @@ -65,83 +64,77 @@ static uint32_t cpu_data = 0; static uint16_t last_addr = 0x0000; -static uint32_t *ovr_seg = NULL; -static int prefetching = 1, completed = 1; -static int in_rep = 0, repeating = 0; -static int oldc, clear_lock = 0; -static int refresh = 0, cycdiff; - +static uint32_t *ovr_seg = NULL; +static int prefetching = 1, completed = 1; +static int in_rep = 0, repeating = 0; +static int oldc, clear_lock = 0; +static int refresh = 0, cycdiff; /* Various things needed for 8087. */ -#define OP_TABLE(name) ops_ ## name +#define OP_TABLE(name) ops_##name #define CPU_BLOCK_END() -#define SEG_CHECK_READ(seg) -#define SEG_CHECK_WRITE(seg) -#define CHECK_READ(a, b, c) -#define CHECK_WRITE(a, b, c) -#define UN_USED(x) (void)(x) -#define fetch_ea_16(val) -#define fetch_ea_32(val) -#define PREFETCH_RUN(a, b, c, d, e, f, g, h) +#define SEG_CHECK_READ(seg) +#define SEG_CHECK_WRITE(seg) +#define CHECK_READ(a, b, c) +#define CHECK_WRITE(a, b, c) +#define UN_USED(x) (void) (x) +#define fetch_ea_16(val) +#define fetch_ea_32(val) +#define PREFETCH_RUN(a, b, c, d, e, f, g, h) -#define CYCLES(val) \ - { \ - wait(val, 0); \ - } +#define CYCLES(val) \ + { \ + wait(val, 0); \ + } -#define CLOCK_CYCLES_ALWAYS(val) \ - { \ - wait(val, 0); \ - } +#define CLOCK_CYCLES_ALWAYS(val) \ + { \ + wait(val, 0); \ + } #if 0 -#define CLOCK_CYCLES_FPU(val) \ - { \ - wait(val, 0); \ - } +# define CLOCK_CYCLES_FPU(val) \ + { \ + wait(val, 0); \ + } +# define CLOCK_CYCLES(val) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (val); \ + if (fpu_cycles < 0) { \ + wait(val, 0); \ + } \ + } else { \ + wait(val, 0); \ + } \ + } -#define CLOCK_CYCLES(val) \ - { \ - if (fpu_cycles > 0) { \ - fpu_cycles -= (val); \ - if (fpu_cycles < 0) { \ - wait(val, 0); \ - } \ - } else { \ - wait(val, 0); \ - } \ - } - -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES(val) \ - { \ - wait(val, 0); \ - } +# define CLOCK_CYCLES(val) \ + { \ + wait(val, 0); \ + } -#define CLOCK_CYCLES_FPU(val) \ - { \ - wait(val, 0); \ - } +# define CLOCK_CYCLES_FPU(val) \ + { \ + wait(val, 0); \ + } -#define CONCURRENCY_CYCLES(c) +# define CONCURRENCY_CYCLES(c) #endif +typedef int (*OpFn)(uint32_t fetchdat); -typedef int (*OpFn)(uint32_t fetchdat); - - -static int tempc_fpu = 0; - +static int tempc_fpu = 0; #ifdef ENABLE_808X_LOG -void dumpregs(int); +void dumpregs(int); int x808x_do_log = ENABLE_808X_LOG; -int indump = 0; - +int indump = 0; static void x808x_log(const char *fmt, ...) @@ -149,19 +142,17 @@ 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); } } #else -#define x808x_log(fmt, ...) +# define x808x_log(fmt, ...) #endif - -static void pfq_add(int c, int add); -static void set_pzs(int bits); - +static void pfq_add(int c, int add); +static void set_pzs(int bits); uint16_t get_last_addr(void) @@ -169,48 +160,44 @@ get_last_addr(void) return last_addr; } - static void 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)) - timer_process(); + 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(); } - static void fetch_and_bus(int c, int bus) { if (refresh > 0) { - /* Finish the current fetch, if any. */ - cycles -= ((4 - (biu_cycles & 3)) & 3); - pfq_add((4 - (biu_cycles & 3)) & 3, 1); - /* Add 4 memory access cycles. */ - cycles -= 4; - pfq_add(4, 0); + /* Finish the current fetch, if any. */ + cycles -= ((4 - (biu_cycles & 3)) & 3); + pfq_add((4 - (biu_cycles & 3)) & 3, 1); + /* Add 4 memory access cycles. */ + cycles -= 4; + pfq_add(4, 0); - refresh--; + refresh--; } pfq_add(c, !bus); if (bus < 2) { - clock_end(); - clock_start(); + clock_end(); + clock_start(); } } - static void wait(int c, int bus) { @@ -218,83 +205,78 @@ wait(int c, int bus) fetch_and_bus(c, bus); } - /* This is for external subtraction of cycles. */ void sub_cycles(int c) { if (c <= 0) - return; + return; cycles -= c; if (!is286) - fetch_and_bus(c, 2); + fetch_and_bus(c, 2); } - void resub_cycles(int old_cycles) { int cyc_diff = 0; if (old_cycles > cycles) { - cyc_diff = old_cycles - cycles; - cycles = old_cycles; - sub_cycles(cyc_diff); + cyc_diff = old_cycles - cycles; + cycles = old_cycles; + sub_cycles(cyc_diff); } } - #undef readmemb #undef readmemw #undef readmeml #undef readmemq - static void cpu_io(int bits, int out, uint16_t port) { int old_cycles = cycles; if (out) { - wait(4, 1); - if (bits == 16) { - if (is8086 && !(port & 1)) { - old_cycles = cycles; - outw(port, AX); - } else { - wait(4, 1); - old_cycles = cycles; - outb(port++, AL); - outb(port, AH); - } - } else { - old_cycles = cycles; - outb(port, AL); - } + wait(4, 1); + if (bits == 16) { + if (is8086 && !(port & 1)) { + old_cycles = cycles; + outw(port, AX); + } else { + wait(4, 1); + old_cycles = cycles; + outb(port++, AL); + outb(port, AH); + } + } else { + old_cycles = cycles; + outb(port, AL); + } } else { - wait(4, 1); - if (bits == 16) { - if (is8086 && !(port & 1)) { - old_cycles = cycles; - AX = inw(port); - } else { - wait(4, 1); - old_cycles = cycles; - AL = inb(port++); - AH = inb(port); - } - } else { - old_cycles = cycles; - AL = inb(port); - } + wait(4, 1); + if (bits == 16) { + if (is8086 && !(port & 1)) { + old_cycles = cycles; + AX = inw(port); + } else { + wait(4, 1); + old_cycles = cycles; + AL = inb(port++); + AH = inb(port); + } + } else { + old_cycles = cycles; + AL = inb(port); + } } resub_cycles(old_cycles); } - /* Reads a byte from the memory and advances the BIU. */ static uint8_t readmemb(uint32_t a) @@ -307,20 +289,18 @@ readmemb(uint32_t a) return ret; } - /* Reads a byte from the memory but does not advance the BIU. */ static uint8_t readmembf(uint32_t a) { uint8_t ret; - a = cs + (a & 0xffff); + a = cs + (a & 0xffff); ret = read_mem_b(a); return ret; } - /* Reads a word from the memory and advances the BIU. */ static uint16_t readmemw(uint32_t s, uint16_t a) @@ -329,17 +309,16 @@ readmemw(uint32_t s, uint16_t a) wait(4, 1); if (is8086 && !(a & 1)) - ret = read_mem_w(s + a); + ret = read_mem_w(s + a); else { - wait(4, 1); - ret = read_mem_b(s + a); - ret |= read_mem_b(s + ((a + 1) & 0xffff)) << 8; + wait(4, 1); + ret = read_mem_b(s + a); + ret |= read_mem_b(s + ((a + 1) & 0xffff)) << 8; } return ret; } - static uint16_t readmemwf(uint16_t a) { @@ -350,17 +329,15 @@ readmemwf(uint16_t a) return ret; } - static uint16_t readmem(uint32_t s) { if (opcode & 1) - return readmemw(s, cpu_state.eaaddr); + return readmemw(s, cpu_state.eaaddr); else - return (uint16_t) readmemb(s + cpu_state.eaaddr); + return (uint16_t) readmemb(s + cpu_state.eaaddr); } - static uint32_t readmeml(uint32_t s, uint16_t a) { @@ -372,7 +349,6 @@ readmeml(uint32_t s, uint16_t a) return temp; } - static uint64_t readmemq(uint32_t s, uint16_t a) { @@ -384,7 +360,6 @@ readmemq(uint32_t s, uint16_t a) return temp; } - /* Writes a byte to the memory and advances the BIU. */ static void writememb(uint32_t s, uint32_t a, uint8_t v) @@ -395,10 +370,9 @@ writememb(uint32_t s, uint32_t a, uint8_t v) write_mem_b(addr, v); if ((addr >= 0xf0000) && (addr <= 0xfffff)) - last_addr = addr & 0xffff; + last_addr = addr & 0xffff; } - /* Writes a word to the memory and advances the BIU. */ static void writememw(uint32_t s, uint32_t a, uint16_t v) @@ -407,29 +381,27 @@ writememw(uint32_t s, uint32_t a, uint16_t v) wait(4, 1); if (is8086 && !(a & 1)) - write_mem_w(addr, v); + write_mem_w(addr, v); else { - write_mem_b(addr, v & 0xff); - wait(4, 1); - addr = s + ((a + 1) & 0xffff); - write_mem_b(addr, v >> 8); + write_mem_b(addr, v & 0xff); + wait(4, 1); + addr = s + ((a + 1) & 0xffff); + write_mem_b(addr, v >> 8); } if ((addr >= 0xf0000) && (addr <= 0xfffff)) - last_addr = addr & 0xffff; + last_addr = addr & 0xffff; } - static void writemem(uint32_t s, uint16_t v) { if (opcode & 1) - writememw(s, cpu_state.eaaddr, v); + writememw(s, cpu_state.eaaddr, v); else - writememb(s, cpu_state.eaaddr, (uint8_t) (v & 0xff)); + writememb(s, cpu_state.eaaddr, (uint8_t) (v & 0xff)); } - static void writememl(uint32_t s, uint32_t a, uint32_t v) { @@ -437,7 +409,6 @@ writememl(uint32_t s, uint32_t a, uint32_t v) writememw(s, a + 2, v >> 16); } - static void writememq(uint32_t s, uint32_t a, uint64_t v) { @@ -445,29 +416,27 @@ writememq(uint32_t s, uint32_t a, uint64_t v) writememl(s, a + 4, v >> 32); } - static void pfq_write(void) { uint16_t tempw; if (is8086 && (pfq_pos < (pfq_size - 1))) { - /* The 8086 fetches 2 bytes at a time, and only if there's at least 2 bytes - free in the queue. */ - tempw = readmemwf(pfq_ip); - *(uint16_t *) &(pfq[pfq_pos]) = tempw; - pfq_ip += 2; - pfq_pos += 2; + /* The 8086 fetches 2 bytes at a time, and only if there's at least 2 bytes + free in the queue. */ + tempw = readmemwf(pfq_ip); + *(uint16_t *) &(pfq[pfq_pos]) = tempw; + pfq_ip += 2; + pfq_pos += 2; } else if (!is8086 && (pfq_pos < pfq_size)) { - /* The 8088 fetches 1 byte at a time, and only if there's at least 1 byte - free in the queue. */ - pfq[pfq_pos] = readmembf(pfq_ip); - pfq_ip++; - pfq_pos++; + /* The 8088 fetches 1 byte at a time, and only if there's at least 1 byte + free in the queue. */ + pfq[pfq_pos] = readmembf(pfq_ip); + pfq_ip++; + pfq_pos++; } } - static uint8_t pfq_read(void) { @@ -475,13 +444,12 @@ pfq_read(void) temp = pfq[0]; for (i = 0; i < (pfq_size - 1); i++) - pfq[i] = pfq[i + 1]; + pfq[i] = pfq[i + 1]; pfq_pos--; cpu_state.pc = (cpu_state.pc + 1) & 0xffff; return temp; } - /* Fetches a byte from the prefetch queue, or from memory if the queue has been drained. */ static uint8_t @@ -490,10 +458,10 @@ pfq_fetchb_common(void) uint8_t temp; if (pfq_pos == 0) { - /* Reset prefetch queue internal position. */ - pfq_ip = cpu_state.pc; - /* Fill the queue. */ - wait(4 - (biu_cycles & 3), 0); + /* Reset prefetch queue internal position. */ + pfq_ip = cpu_state.pc; + /* Fill the queue. */ + wait(4 - (biu_cycles & 3), 0); } /* Fetch. */ @@ -501,7 +469,6 @@ pfq_fetchb_common(void) return temp; } - static uint8_t pfq_fetchb(void) { @@ -512,7 +479,6 @@ pfq_fetchb(void) return ret; } - /* Fetches a word from the prefetch queue, or from memory if the queue has been drained. */ static uint16_t @@ -527,17 +493,15 @@ pfq_fetchw(void) return temp; } - static uint16_t pfq_fetch() { if (opcode & 1) - return pfq_fetchw(); + return pfq_fetchw(); else - return (uint16_t) pfq_fetchb(); + return (uint16_t) pfq_fetchb(); } - /* Adds bytes to the prefetch queue based on the instruction's cycle count. */ static void pfq_add(int c, int add) @@ -545,293 +509,277 @@ pfq_add(int c, int add) int d; if ((c <= 0) || (pfq_pos >= pfq_size)) - return; + return; for (d = 0; d < c; d++) { - biu_cycles = (biu_cycles + 1) & 0x03; - if (prefetching && add && (biu_cycles == 0x00)) - pfq_write(); + biu_cycles = (biu_cycles + 1) & 0x03; + if (prefetching && add && (biu_cycles == 0x00)) + pfq_write(); } } - /* Clear the prefetch queue - called on reset and on anything that affects either CS or IP. */ static void pfq_clear() { - pfq_pos = 0; + pfq_pos = 0; prefetching = 0; } - static void load_cs(uint16_t seg) { cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.seg = seg & 0xffff; + cpu_state.seg_cs.seg = seg & 0xffff; } - static void load_seg(uint16_t seg, x86seg *s) { s->base = seg << 4; - s->seg = seg & 0xffff; + s->seg = seg & 0xffff; } - void reset_808x(int hard) { biu_cycles = 0; - in_rep = 0; - in_lock = 0; - completed = 1; - repeating = 0; + in_rep = 0; + in_lock = 0; + completed = 1; + repeating = 0; clear_lock = 0; - refresh = 0; - ovr_seg = NULL; + refresh = 0; + ovr_seg = NULL; if (hard) { - opseg[0] = &es; - opseg[1] = &cs; - opseg[2] = &ss; - opseg[3] = &ds; - _opseg[0] = &cpu_state.seg_es; - _opseg[1] = &cpu_state.seg_cs; - _opseg[2] = &cpu_state.seg_ss; - _opseg[3] = &cpu_state.seg_ds; + opseg[0] = &es; + opseg[1] = &cs; + opseg[2] = &ss; + opseg[3] = &ds; + _opseg[0] = &cpu_state.seg_es; + _opseg[1] = &cpu_state.seg_cs; + _opseg[2] = &cpu_state.seg_ss; + _opseg[3] = &cpu_state.seg_ds; - pfq_size = (is8086) ? 6 : 4; - pfq_clear(); + pfq_size = (is8086) ? 6 : 4; + pfq_clear(); } load_cs(0xFFFF); cpu_state.pc = 0; - rammask = 0xfffff; + rammask = 0xfffff; prefetching = 1; - cpu_alu_op = 0; + cpu_alu_op = 0; use_custom_nmi_vector = 0x00; - custom_nmi_vector = 0x00000000; + custom_nmi_vector = 0x00000000; } - static void -set_ip(uint16_t new_ip) { +set_ip(uint16_t new_ip) +{ pfq_ip = cpu_state.pc = new_ip; - prefetching = 1; + prefetching = 1; } - /* Memory refresh read - called by reads and writes on DMA channel 0. */ void -refreshread(void) { +refreshread(void) +{ refresh++; } - static uint16_t get_accum(int bits) { return (bits == 16) ? AX : AL; } - static void set_accum(int bits, uint16_t val) { if (bits == 16) - AX = val; + AX = val; else - AL = val; + AL = val; } - static uint16_t sign_extend(uint8_t data) { return data + (data < 0x80 ? 0 : 0xff00); } - /* Fetches the effective address from the prefetch queue according to MOD and R/M. */ static void do_mod_rm(void) { - rmdat = pfq_fetchb(); + rmdat = pfq_fetchb(); cpu_reg = (rmdat >> 3) & 7; cpu_mod = (rmdat >> 6) & 3; - cpu_rm = rmdat & 7; + cpu_rm = rmdat & 7; if (cpu_mod == 3) - return; + return; wait(1, 0); if ((rmdat & 0xc7) == 0x06) { - wait(1, 0); - cpu_state.eaaddr = pfq_fetchw(); - easeg = ovr_seg ? *ovr_seg : ds; - wait(1, 0); - return; - } else switch (cpu_rm) { - case 0: - case 3: - wait(2, 0); - break; - case 1: - case 2: - wait(3, 0); - break; - } + wait(1, 0); + cpu_state.eaaddr = pfq_fetchw(); + easeg = ovr_seg ? *ovr_seg : ds; + wait(1, 0); + return; + } else + switch (cpu_rm) { + case 0: + case 3: + wait(2, 0); + break; + case 1: + case 2: + wait(3, 0); + break; + } cpu_state.eaaddr = (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - easeg = ovr_seg ? *ovr_seg : *mod1seg[cpu_rm]; + easeg = ovr_seg ? *ovr_seg : *mod1seg[cpu_rm]; switch (rmdat & 0xc0) { - case 0x40: - wait(3, 0); - cpu_state.eaaddr += sign_extend(pfq_fetchb()); - break; - case 0x80: - wait(3, 0); - cpu_state.eaaddr += pfq_fetchw(); - break; + case 0x40: + wait(3, 0); + cpu_state.eaaddr += sign_extend(pfq_fetchb()); + break; + case 0x80: + wait(3, 0); + cpu_state.eaaddr += pfq_fetchw(); + break; } cpu_state.eaaddr &= 0xffff; wait(2, 0); } - #undef getr8 -#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) +#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) #undef setr8 -#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 setr8(r, v) \ + if (r & 4) \ + cpu_state.regs[r & 3].b.h = v; \ + else \ + cpu_state.regs[r & 3].b.l = v; /* Reads a byte from the effective address. */ static uint8_t geteab(void) { if (cpu_mod == 3) - return (getr8(cpu_rm)); + return (getr8(cpu_rm)); return readmemb(easeg + cpu_state.eaaddr); } - /* Reads a word from the effective address. */ static uint16_t geteaw(void) { if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; + return cpu_state.regs[cpu_rm].w; return readmemw(easeg, cpu_state.eaaddr); } - /* Neede for 8087 - memory only. */ static uint32_t geteal(void) { if (cpu_mod == 3) { - fatal("808x register geteal()\n"); - return 0xffffffff; + fatal("808x register geteal()\n"); + return 0xffffffff; } return readmeml(easeg, cpu_state.eaaddr); } - /* Neede for 8087 - memory only. */ static uint64_t geteaq(void) { if (cpu_mod == 3) { - fatal("808x register geteaq()\n"); - return 0xffffffff; + fatal("808x register geteaq()\n"); + return 0xffffffff; } return readmemq(easeg, cpu_state.eaaddr); } - static void read_ea(int memory_only, int bits) { if (cpu_mod != 3) { - if (bits == 16) - cpu_data = readmemw(easeg, cpu_state.eaaddr); - else - cpu_data = readmemb(easeg + cpu_state.eaaddr); - return; + if (bits == 16) + cpu_data = readmemw(easeg, cpu_state.eaaddr); + else + cpu_data = readmemb(easeg + cpu_state.eaaddr); + return; } if (!memory_only) { - if (bits == 8) { - cpu_data = getr8(cpu_rm); - } else - cpu_data = cpu_state.regs[cpu_rm].w; + if (bits == 8) { + cpu_data = getr8(cpu_rm); + } else + cpu_data = cpu_state.regs[cpu_rm].w; } } - static void read_ea2(int bits) { cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; if (bits == 16) - cpu_data = readmemw(easeg, cpu_state.eaaddr); + cpu_data = readmemw(easeg, cpu_state.eaaddr); else - cpu_data = readmemb(easeg + cpu_state.eaaddr); + cpu_data = readmemb(easeg + cpu_state.eaaddr); } - /* Writes a byte to the effective address. */ static void seteab(uint8_t val) { if (cpu_mod == 3) { - setr8(cpu_rm, val); + setr8(cpu_rm, val); } else - writememb(easeg, cpu_state.eaaddr, val); + writememb(easeg, cpu_state.eaaddr, val); } - /* Writes a word to the effective address. */ static void seteaw(uint16_t val) { if (cpu_mod == 3) - cpu_state.regs[cpu_rm].w = val; + cpu_state.regs[cpu_rm].w = val; else - writememw(easeg, cpu_state.eaaddr, val); + writememw(easeg, cpu_state.eaaddr, val); } - static void seteal(uint32_t val) { if (cpu_mod == 3) { - fatal("808x register seteal()\n"); - return; + fatal("808x register seteal()\n"); + return; } else - writememl(easeg, cpu_state.eaaddr, val); + writememl(easeg, cpu_state.eaaddr, val); } - static void seteaq(uint64_t val) { if (cpu_mod == 3) { - fatal("808x register seteaq()\n"); - return; + fatal("808x register seteaq()\n"); + return; } else - writememq(easeg, cpu_state.eaaddr, val); + writememq(easeg, cpu_state.eaaddr, val); } - /* Leave out the 686 stuff as it's not needed and complicates compiling. */ #define FPU_8087 @@ -841,7 +789,6 @@ seteaq(uint64_t val) #undef tempc #undef FPU_8087 - /* Pushes a word to the stack. */ static void push(uint16_t *val) @@ -851,7 +798,6 @@ push(uint16_t *val) writememw(ss, cpu_state.eaaddr, *val); } - /* Pops a word from the stack. */ static uint16_t pop(void) @@ -861,90 +807,135 @@ pop(void) return readmemw(ss, cpu_state.eaaddr); } - static void access(int num, int bits) { switch (num) { - case 0: case 61: case 63: case 64: - case 67: case 69: case 71: case 72: - default: - break; - case 1: case 6: case 7: case 8: - case 9: case 17: case 20: case 21: - case 24: case 28: case 47: case 48: - case 49: case 50: case 51: case 55: - case 56: case 62: case 66: case 68: - wait(1, 0); - break; - case 3: case 11: case 15: case 22: - case 23: case 25: case 26: case 35: - case 44: case 45: case 46: case 52: - case 53: case 54: - wait(2, 0); - break; - case 16: case 18: case 19: case 27: - case 32: case 37: case 42: - wait(3, 0); - break; - case 10: case 12: case 13: case 14: - case 29: case 30: case 33: case 34: - case 39: case 41: case 60: - wait(4, 0); - break; - case 4: case 70: - wait(5, 0); - break; - case 31: case 38: case 40: - wait(6, 0); - break; - case 5: - if (opcode == 0xcc) - wait(7, 0); - else - wait(4, 0); - break; - case 36: - wait(1, 0); - pfq_clear(); - wait (1, 0); - if (cpu_mod != 3) - wait(1, 0); - wait(3, 0); - break; - case 43: - wait(2, 0); - pfq_clear(); - wait(1, 0); - break; - case 57: - if (cpu_mod != 3) - wait(2, 0); - wait(4, 0); - break; - case 58: - if (cpu_mod != 3) - wait(1, 0); - wait(4, 0); - break; - case 59: - wait(2, 0); - pfq_clear(); - if (cpu_mod != 3) - wait(1, 0); - wait(3, 0); - break; - case 65: - wait(1, 0); - pfq_clear(); - wait(2, 0); - if (cpu_mod != 3) - wait(1, 0); - break; + case 0: + case 61: + case 63: + case 64: + case 67: + case 69: + case 71: + case 72: + default: + break; + case 1: + case 6: + case 7: + case 8: + case 9: + case 17: + case 20: + case 21: + case 24: + case 28: + case 47: + case 48: + case 49: + case 50: + case 51: + case 55: + case 56: + case 62: + case 66: + case 68: + wait(1, 0); + break; + case 3: + case 11: + case 15: + case 22: + case 23: + case 25: + case 26: + case 35: + case 44: + case 45: + case 46: + case 52: + case 53: + case 54: + wait(2, 0); + break; + case 16: + case 18: + case 19: + case 27: + case 32: + case 37: + case 42: + wait(3, 0); + break; + case 10: + case 12: + case 13: + case 14: + case 29: + case 30: + case 33: + case 34: + case 39: + case 41: + case 60: + wait(4, 0); + break; + case 4: + case 70: + wait(5, 0); + break; + case 31: + case 38: + case 40: + wait(6, 0); + break; + case 5: + if (opcode == 0xcc) + wait(7, 0); + else + wait(4, 0); + break; + case 36: + wait(1, 0); + pfq_clear(); + wait(1, 0); + if (cpu_mod != 3) + wait(1, 0); + wait(3, 0); + break; + case 43: + wait(2, 0); + pfq_clear(); + wait(1, 0); + break; + case 57: + if (cpu_mod != 3) + wait(2, 0); + wait(4, 0); + break; + case 58: + if (cpu_mod != 3) + wait(1, 0); + wait(4, 0); + break; + case 59: + wait(2, 0); + pfq_clear(); + if (cpu_mod != 3) + wait(1, 0); + wait(3, 0); + break; + case 65: + wait(1, 0); + pfq_clear(); + wait(2, 0); + if (cpu_mod != 3) + wait(1, 0); + break; } } - /* Calls an interrupt. */ static void interrupt(uint16_t addr) @@ -955,13 +946,13 @@ interrupt(uint16_t addr) addr <<= 2; cpu_state.eaaddr = addr; - old_cs = CS; + old_cs = CS; access(5, 16); new_ip = readmemw(0, cpu_state.eaaddr); wait(1, 0); cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; access(6, 16); - new_cs = readmemw(0, cpu_state.eaaddr); + new_cs = readmemw(0, cpu_state.eaaddr); prefetching = 0; pfq_clear(); ovr_seg = NULL; @@ -979,7 +970,6 @@ interrupt(uint16_t addr) push(&old_ip); } - static void custom_nmi(void) { @@ -988,7 +978,7 @@ custom_nmi(void) uint16_t tempf; cpu_state.eaaddr = 0x0002; - old_cs = CS; + old_cs = CS; access(5, 16); (void) readmemw(0, cpu_state.eaaddr); new_ip = custom_nmi_vector & 0xffff; @@ -996,7 +986,7 @@ custom_nmi(void) cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; access(6, 16); (void) readmemw(0, cpu_state.eaaddr); - new_cs = custom_nmi_vector >> 16; + new_cs = custom_nmi_vector >> 16; prefetching = 0; pfq_clear(); ovr_seg = NULL; @@ -1014,95 +1004,90 @@ custom_nmi(void) push(&old_ip); } - static int irq_pending(void) { uint8_t temp; - temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || - ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint); + temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint); return temp; } - static void check_interrupts(void) { int temp; if (irq_pending()) { - if ((cpu_state.flags & T_FLAG) && !noint) { - interrupt(1); - return; - } - if (nmi && nmi_enable && nmi_mask) { - nmi_enable = 0; - if (use_custom_nmi_vector) - custom_nmi(); - else - interrupt(2); + if ((cpu_state.flags & T_FLAG) && !noint) { + interrupt(1); + return; + } + if (nmi && nmi_enable && nmi_mask) { + nmi_enable = 0; + if (use_custom_nmi_vector) + custom_nmi(); + else + interrupt(2); #ifndef OLD_NMI_BEHAVIOR - nmi = 0; + nmi = 0; #endif - return; - } - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) { - repeating = 0; - completed = 1; - ovr_seg = NULL; - wait(3, 0); - /* ACK to PIC */ - temp = pic_irq_ack(); - wait(4, 1); - wait(1, 0); - /* ACK to PIC */ - temp = pic_irq_ack(); - wait(4, 1); - wait(1, 0); - in_lock = 0; - clear_lock = 0; - wait(1, 0); - /* Here is where temp should be filled, but we cheat. */ - wait(3, 0); - opcode = 0x00; - interrupt(temp); - } + return; + } + if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) { + repeating = 0; + completed = 1; + ovr_seg = NULL; + wait(3, 0); + /* ACK to PIC */ + temp = pic_irq_ack(); + wait(4, 1); + wait(1, 0); + /* ACK to PIC */ + temp = pic_irq_ack(); + wait(4, 1); + wait(1, 0); + in_lock = 0; + clear_lock = 0; + wait(1, 0); + /* Here is where temp should be filled, but we cheat. */ + wait(3, 0); + opcode = 0x00; + interrupt(temp); + } } } - static int rep_action(int bits) { uint16_t t; if (in_rep == 0) - return 0; + return 0; wait(2, 0); t = CX; if (irq_pending() && (repeating != 0)) { - access(71, bits); - pfq_clear(); - set_ip(cpu_state.pc - 2); - t = 0; + access(71, bits); + pfq_clear(); + set_ip(cpu_state.pc - 2); + t = 0; } if (t == 0) { - wait(1, 0); - completed = 1; - repeating = 0; - return 1; + wait(1, 0); + completed = 1; + repeating = 0; + return 1; } --CX; completed = 0; wait(2, 0); if (!repeating) - wait(2, 0); + wait(2, 0); return 0; } - static uint16_t jump(uint16_t delta) { @@ -1115,21 +1100,18 @@ jump(uint16_t delta) return old_ip; } - static void jump_short(void) { jump(sign_extend((uint8_t) cpu_data)); } - static uint16_t jump_near(void) { return jump(pfq_fetchw()); } - /* Performs a conditional jump. */ static void jcc(uint8_t opcode, int cond) @@ -1140,31 +1122,27 @@ jcc(uint8_t opcode, int cond) cpu_data = pfq_fetchb(); wait(1, 0); if ((!cond) == !!(opcode & 0x01)) - jump_short(); + jump_short(); } - static void set_cf(int cond) { cpu_state.flags = (cpu_state.flags & ~C_FLAG) | (cond ? C_FLAG : 0); } - static void set_if(int cond) { cpu_state.flags = (cpu_state.flags & ~I_FLAG) | (cond ? I_FLAG : 0); } - static void set_df(int cond) { cpu_state.flags = (cpu_state.flags & ~D_FLAG) | (cond ? D_FLAG : 0); } - static void bitwise(int bits, uint16_t data) { @@ -1173,58 +1151,50 @@ bitwise(int bits, uint16_t data) set_pzs(bits); } - static void test(int bits, uint16_t dest, uint16_t src) { cpu_dest = dest; - cpu_src = src; + cpu_src = src; bitwise(bits, (cpu_dest & cpu_src)); } - static void set_of(int of) { cpu_state.flags = (cpu_state.flags & ~0x800) | (of ? 0x800 : 0); } - static int top_bit(uint16_t w, int bits) { return (w & (1 << (bits - 1))); } - static void set_of_add(int bits) { set_of(top_bit((cpu_data ^ cpu_src) & (cpu_data ^ cpu_dest), bits)); } - static void set_of_sub(int bits) { set_of(top_bit((cpu_dest ^ cpu_src) & (cpu_data ^ cpu_dest), bits)); } - static void set_af(int af) { cpu_state.flags = (cpu_state.flags & ~0x10) | (af ? 0x10 : 0); } - static void do_af(void) { set_af(((cpu_data ^ cpu_src ^ cpu_dest) & 0x10) != 0); } - static void set_apzs(int bits) { @@ -1232,7 +1202,6 @@ set_apzs(int bits) do_af(); } - static void add(int bits) { @@ -1245,12 +1214,11 @@ add(int bits) /* Anything - FF with carry on is basically anything + 0x100: value stays unchanged but carry goes on. */ if ((cpu_alu_op == 2) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) - cpu_state.flags |= C_FLAG; + cpu_state.flags |= C_FLAG; else - set_cf((cpu_src & size_mask) > (cpu_data & size_mask)); + set_cf((cpu_src & size_mask) > (cpu_data & size_mask)); } - static void sub(int bits) { @@ -1263,63 +1231,60 @@ sub(int bits) /* Anything - FF with carry on is basically anything - 0x100: value stays unchanged but carry goes on. */ if ((cpu_alu_op == 3) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) - cpu_state.flags |= C_FLAG; + cpu_state.flags |= C_FLAG; else - set_cf((cpu_src & size_mask) > (cpu_dest & size_mask)); + set_cf((cpu_src & size_mask) > (cpu_dest & size_mask)); } - static void alu_op(int bits) { - switch(cpu_alu_op) { - case 1: - bitwise(bits, (cpu_dest | cpu_src)); - break; - case 2: - if (cpu_state.flags & C_FLAG) - cpu_src++; - /* Fall through. */ - case 0: - add(bits); - break; - case 3: - if (cpu_state.flags & C_FLAG) - cpu_src++; - /* Fall through. */ - case 5: case 7: - sub(bits); - break; - case 4: - test(bits, cpu_dest, cpu_src); - break; - case 6: - bitwise(bits, (cpu_dest ^ cpu_src)); - break; + switch (cpu_alu_op) { + case 1: + bitwise(bits, (cpu_dest | cpu_src)); + break; + case 2: + if (cpu_state.flags & C_FLAG) + cpu_src++; + /* Fall through. */ + case 0: + add(bits); + break; + case 3: + if (cpu_state.flags & C_FLAG) + cpu_src++; + /* Fall through. */ + case 5: + case 7: + sub(bits); + break; + case 4: + test(bits, cpu_dest, cpu_src); + break; + case 6: + bitwise(bits, (cpu_dest ^ cpu_src)); + break; } } - static void set_sf(int bits) { cpu_state.flags = (cpu_state.flags & ~0x80) | (top_bit(cpu_data, bits) ? 0x80 : 0); } - static void set_pf(void) { - cpu_state.flags = (cpu_state.flags & ~4) | (!__builtin_parity(cpu_data & 0xFF) << 2); + cpu_state.flags = (cpu_state.flags & ~4) | (!__builtin_parity(cpu_data & 0xFF) << 2); } - static void mul(uint16_t a, uint16_t b) { - int negate = 0; - int bit_count = 8; - int carry, i; + int negate = 0; + int bit_count = 8; + int carry, i; uint16_t high_bit = 0x80; uint16_t size_mask; uint16_t c, r; @@ -1327,36 +1292,36 @@ mul(uint16_t a, uint16_t b) size_mask = (1 << bit_count) - 1; if (opcode != 0xd5) { - if (opcode & 1) { - bit_count = 16; - high_bit = 0x8000; - } else - wait(8, 0); + if (opcode & 1) { + bit_count = 16; + high_bit = 0x8000; + } else + wait(8, 0); - size_mask = (1 << bit_count) - 1; + size_mask = (1 << bit_count) - 1; - if ((rmdat & 0x38) == 0x28) { - if (!top_bit(a, bit_count)) { - if (top_bit(b, bit_count)) { - wait(1, 0); - if ((b & size_mask) != ((opcode & 1) ? 0x8000 : 0x80)) - wait(1, 0); - b = ~b + 1; - negate = 1; - } - } else { - wait(1, 0); - a = ~a + 1; - negate = 1; - if (top_bit(b, bit_count)) { - b = ~b + 1; - negate = 0; - } else - wait(4, 0); - } - wait(10, 0); - } - wait(3, 0); + if ((rmdat & 0x38) == 0x28) { + if (!top_bit(a, bit_count)) { + if (top_bit(b, bit_count)) { + wait(1, 0); + if ((b & size_mask) != ((opcode & 1) ? 0x8000 : 0x80)) + wait(1, 0); + b = ~b + 1; + negate = 1; + } + } else { + wait(1, 0); + a = ~a + 1; + negate = 1; + if (top_bit(b, bit_count)) { + b = ~b + 1; + negate = 0; + } else + wait(4, 0); + } + wait(10, 0); + } + wait(3, 0); } c = 0; @@ -1364,28 +1329,28 @@ mul(uint16_t a, uint16_t b) carry = (a & 1) != 0; a >>= 1; for (i = 0; i < bit_count; ++i) { - wait(7, 0); - if (carry) { - cpu_src = c; - cpu_dest = b; - add(bit_count); - c = cpu_data & size_mask; - wait(1, 0); - carry = !!(cpu_state.flags & C_FLAG); - } - r = (c >> 1) + (carry ? high_bit : 0); - carry = (c & 1) != 0; - c = r; - r = (a >> 1) + (carry ? high_bit : 0); - carry = (a & 1) != 0; - a = r; + wait(7, 0); + if (carry) { + cpu_src = c; + cpu_dest = b; + add(bit_count); + c = cpu_data & size_mask; + wait(1, 0); + carry = !!(cpu_state.flags & C_FLAG); + } + r = (c >> 1) + (carry ? high_bit : 0); + carry = (c & 1) != 0; + c = r; + r = (a >> 1) + (carry ? high_bit : 0); + carry = (a & 1) != 0; + a = r; } if (negate) { - c = ~c; - a = (~a + 1) & size_mask; - if (a == 0) - ++c; - wait(9, 0); + c = ~c; + a = (~a + 1) & size_mask; + if (a == 0) + ++c; + wait(9, 0); } cpu_data = a; cpu_dest = c; @@ -1395,21 +1360,18 @@ mul(uint16_t a, uint16_t b) set_af(0); } - static void set_of_rotate(int bits) { set_of(top_bit(cpu_data ^ cpu_dest, bits)); } - static void set_zf_ex(int zf) { cpu_state.flags = (cpu_state.flags & ~0x40) | (zf ? 0x40 : 0); } - static void set_zf(int bits) { @@ -1418,7 +1380,6 @@ set_zf(int bits) set_zf_ex((cpu_data & size_mask) == 0); } - static void set_pzs(int bits) { @@ -1427,161 +1388,155 @@ set_pzs(int bits) set_sf(bits); } - static void set_co_mul(int bits, int carry) { set_cf(carry); set_of(carry); /* NOTE: When implementing the V20, care should be taken to not change - the zero flag. */ + the zero flag. */ set_zf_ex(!carry); if (!carry) - wait(1, 0); + wait(1, 0); } - /* Was div(), renamed to avoid conflicts with stdlib div(). */ static int x86_div(uint16_t l, uint16_t h) { - int b, bit_count = 8; - int negative = 0; - int dividend_negative = 0; - int size_mask, carry; + int b, bit_count = 8; + int negative = 0; + int dividend_negative = 0; + int size_mask, carry; uint16_t r; if (opcode & 1) { - l = AX; - h = DX; - bit_count = 16; + l = AX; + h = DX; + bit_count = 16; } size_mask = (1 << bit_count) - 1; if (opcode != 0xd4) { - if ((rmdat & 0x38) == 0x38) { - if (top_bit(h, bit_count)) { - h = ~h; - l = (~l + 1) & size_mask; - if (l == 0) - ++h; - h &= size_mask; - negative = 1; - dividend_negative = 1; - wait(4, 0); - } - if (top_bit(cpu_src, bit_count)) { - cpu_src = ~cpu_src + 1; - negative = !negative; - } else - wait(1, 0); - wait(9, 0); - } - wait(3, 0); + if ((rmdat & 0x38) == 0x38) { + if (top_bit(h, bit_count)) { + h = ~h; + l = (~l + 1) & size_mask; + if (l == 0) + ++h; + h &= size_mask; + negative = 1; + dividend_negative = 1; + wait(4, 0); + } + if (top_bit(cpu_src, bit_count)) { + cpu_src = ~cpu_src + 1; + negative = !negative; + } else + wait(1, 0); + wait(9, 0); + } + wait(3, 0); } wait(8, 0); cpu_src &= size_mask; if (h >= cpu_src) { - if (opcode != 0xd4) - wait(1, 0); - interrupt(0); - return 0; + if (opcode != 0xd4) + wait(1, 0); + interrupt(0); + return 0; } if (opcode != 0xd4) - wait(1, 0); + wait(1, 0); wait(2, 0); carry = 1; for (b = 0; b < bit_count; ++b) { - r = (l << 1) + (carry ? 1 : 0); - carry = top_bit(l, bit_count); - l = r; - r = (h << 1) + (carry ? 1 : 0); - carry = top_bit(h, bit_count); - h = r; - wait(8, 0); - if (carry) { - carry = 0; - h -= cpu_src; - if (b == bit_count - 1) - wait(2, 0); - } else { - carry = cpu_src > h; - if (!carry) { - h -= cpu_src; - wait(1, 0); - if (b == bit_count - 1) - wait(2, 0); - } - } + r = (l << 1) + (carry ? 1 : 0); + carry = top_bit(l, bit_count); + l = r; + r = (h << 1) + (carry ? 1 : 0); + carry = top_bit(h, bit_count); + h = r; + wait(8, 0); + if (carry) { + carry = 0; + h -= cpu_src; + if (b == bit_count - 1) + wait(2, 0); + } else { + carry = cpu_src > h; + if (!carry) { + h -= cpu_src; + wait(1, 0); + if (b == bit_count - 1) + wait(2, 0); + } + } } l = ~((l << 1) + (carry ? 1 : 0)); if (opcode != 0xd4 && (rmdat & 0x38) == 0x38) { - wait(4, 0); - if (top_bit(l, bit_count)) { - if (cpu_mod == 3) - wait(1, 0); - interrupt(0); - return 0; - } - wait(7, 0); - if (negative) - l = ~l + 1; - if (dividend_negative) - h = ~h + 1; + wait(4, 0); + if (top_bit(l, bit_count)) { + if (cpu_mod == 3) + wait(1, 0); + interrupt(0); + return 0; + } + wait(7, 0); + if (negative) + l = ~l + 1; + if (dividend_negative) + h = ~h + 1; } if (opcode == 0xd4) { - AL = h & 0xff; - AH = l & 0xff; + AL = h & 0xff; + AH = l & 0xff; } else { - AH = h & 0xff; - AL = l & 0xff; - if (opcode & 1) { - DX = h; - AX = l; - } + AH = h & 0xff; + AL = l & 0xff; + if (opcode & 1) { + DX = h; + AX = l; + } } return 1; } - static uint16_t string_increment(int bits) { int d = bits >> 3; if (cpu_state.flags & D_FLAG) - cpu_state.eaaddr -= d; + cpu_state.eaaddr -= d; else - cpu_state.eaaddr += d; + cpu_state.eaaddr += d; cpu_state.eaaddr &= 0xffff; return cpu_state.eaaddr; } - static void lods(int bits) { cpu_state.eaaddr = SI; if (bits == 16) - cpu_data = readmemw((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + cpu_data = readmemw((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); else - cpu_data = readmemb((ovr_seg ? *ovr_seg : ds) + cpu_state.eaaddr); + cpu_data = readmemb((ovr_seg ? *ovr_seg : ds) + cpu_state.eaaddr); SI = string_increment(bits); } - static void stos(int bits) { cpu_state.eaaddr = DI; if (bits == 16) - writememw(es, cpu_state.eaaddr, cpu_data); + writememw(es, cpu_state.eaaddr, cpu_data); else - writememb(es, cpu_state.eaaddr, (uint8_t) (cpu_data & 0xff)); + writememb(es, cpu_state.eaaddr, (uint8_t) (cpu_data & 0xff)); DI = string_increment(bits); } - static void aa(void) { @@ -1590,7 +1545,6 @@ aa(void) wait(6, 0); } - static void set_ca(void) { @@ -1598,7 +1552,6 @@ set_ca(void) set_af(1); } - static void clear_ca(void) { @@ -1606,1219 +1559,1347 @@ clear_ca(void) set_af(0); } - static uint16_t get_ea(void) { if (opcode & 1) - return geteaw(); + return geteaw(); else - return (uint16_t) geteab(); + return (uint16_t) geteab(); } - static uint16_t get_reg(uint8_t reg) { if (opcode & 1) - return cpu_state.regs[reg].w; + return cpu_state.regs[reg].w; else - return (uint16_t) getr8(reg); + return (uint16_t) getr8(reg); } - static void set_ea(uint16_t val) { if (opcode & 1) - seteaw(val); + seteaw(val); else - seteab((uint8_t) (val & 0xff)); + seteab((uint8_t) (val & 0xff)); } - static void set_reg(uint8_t reg, uint16_t val) { if (opcode & 1) - cpu_state.regs[reg].w = val; + cpu_state.regs[reg].w = val; else - setr8(reg, (uint8_t) (val & 0xff)); + setr8(reg, (uint8_t) (val & 0xff)); } - static void -cpu_data_opff_rm(void) { +cpu_data_opff_rm(void) +{ if (!(opcode & 1)) { - if (cpu_mod != 3) - cpu_data |= 0xff00; - else - cpu_data = cpu_state.regs[cpu_rm].w; + if (cpu_mod != 3) + cpu_data |= 0xff00; + else + cpu_data = cpu_state.regs[cpu_rm].w; } } - /* Executes instructions up to the specified number of cycles. */ void execx86(int cycs) { - uint8_t temp = 0, temp2; - uint8_t old_af; + uint8_t temp = 0, temp2; + uint8_t old_af; uint16_t addr, tempw; uint16_t new_cs, new_ip; - int bits; + int bits; cycles += cycs; while (cycles > 0) { - clock_start(); + clock_start(); - if (!repeating) { - cpu_state.oldpc = cpu_state.pc; - opcode = pfq_fetchb(); - oldc = cpu_state.flags & C_FLAG; - if (clear_lock) { - in_lock = 0; - clear_lock = 0; - } - wait(1, 0); - } + if (!repeating) { + cpu_state.oldpc = cpu_state.pc; + opcode = pfq_fetchb(); + oldc = cpu_state.flags & C_FLAG; + if (clear_lock) { + in_lock = 0; + clear_lock = 0; + } + wait(1, 0); + } - completed = 1; - // pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); - switch (opcode) { - case 0x06: case 0x0E: case 0x16: case 0x1E: /* PUSH seg */ - access(29, 16); - push(&(_opseg[(opcode >> 3) & 0x03]->seg)); - break; - case 0x07: case 0x0F: case 0x17: case 0x1F: /* POP seg */ - access(22, 16); - if (opcode == 0x0F) { - load_cs(pop()); - pfq_pos = 0; - } else - load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); - wait(1, 0); - /* All POP segment instructions suppress interrupts for one instruction. */ - noint = 1; - break; + completed = 1; + // pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); + switch (opcode) { + case 0x06: + case 0x0E: + case 0x16: + case 0x1E: /* PUSH seg */ + access(29, 16); + push(&(_opseg[(opcode >> 3) & 0x03]->seg)); + break; + case 0x07: + case 0x0F: + case 0x17: + case 0x1F: /* POP seg */ + access(22, 16); + if (opcode == 0x0F) { + load_cs(pop()); + pfq_pos = 0; + } else + load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); + wait(1, 0); + /* All POP segment instructions suppress interrupts for one instruction. */ + noint = 1; + break; - case 0x26: /*ES:*/ - case 0x2E: /*CS:*/ - case 0x36: /*SS:*/ - case 0x3E: /*DS:*/ - wait(1, 0); - ovr_seg = opseg[(opcode >> 3) & 0x03]; - completed = 0; - break; + case 0x26: /*ES:*/ + case 0x2E: /*CS:*/ + case 0x36: /*SS:*/ + case 0x3E: /*DS:*/ + wait(1, 0); + ovr_seg = opseg[(opcode >> 3) & 0x03]; + completed = 0; + break; - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x20: case 0x21: case 0x22: case 0x23: - case 0x28: case 0x29: case 0x2a: case 0x2b: - case 0x30: case 0x31: case 0x32: case 0x33: - case 0x38: case 0x39: case 0x3a: case 0x3b: - /* alu rm, r / r, rm */ - bits = 8 << (opcode & 1); - do_mod_rm(); - access(46, bits); - tempw = get_ea(); - cpu_alu_op = (opcode >> 3) & 7; - if ((opcode & 2) == 0) { - cpu_dest = tempw; - cpu_src = get_reg(cpu_reg); - } else { - cpu_dest = get_reg(cpu_reg); - cpu_src = tempw; - } - if (cpu_mod != 3) - wait(2, 0); - wait(1, 0); - alu_op(bits); - if (cpu_alu_op != 7) { - if ((opcode & 2) == 0) { - access(10, bits); - set_ea(cpu_data); - if (cpu_mod == 3) - wait(1, 0); - } else { - set_reg(cpu_reg, cpu_data); - wait(1, 0); - } - } else - wait(1, 0); - break; + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + /* alu rm, r / r, rm */ + bits = 8 << (opcode & 1); + do_mod_rm(); + access(46, bits); + tempw = get_ea(); + cpu_alu_op = (opcode >> 3) & 7; + if ((opcode & 2) == 0) { + cpu_dest = tempw; + cpu_src = get_reg(cpu_reg); + } else { + cpu_dest = get_reg(cpu_reg); + cpu_src = tempw; + } + if (cpu_mod != 3) + wait(2, 0); + wait(1, 0); + alu_op(bits); + if (cpu_alu_op != 7) { + if ((opcode & 2) == 0) { + access(10, bits); + set_ea(cpu_data); + if (cpu_mod == 3) + wait(1, 0); + } else { + set_reg(cpu_reg, cpu_data); + wait(1, 0); + } + } else + wait(1, 0); + break; - case 0x04: case 0x05: case 0x0c: case 0x0d: - case 0x14: case 0x15: case 0x1c: case 0x1d: - case 0x24: case 0x25: case 0x2c: case 0x2d: - case 0x34: case 0x35: case 0x3c: case 0x3d: - /* alu A, imm */ - bits = 8 << (opcode & 1); - wait(1, 0); - cpu_data = pfq_fetch(); - cpu_dest = get_accum(bits); /* AX/AL */ - cpu_src = cpu_data; - cpu_alu_op = (opcode >> 3) & 7; - alu_op(bits); - if (cpu_alu_op != 7) - set_accum(bits, cpu_data); - wait(1, 0); - break; + case 0x04: + case 0x05: + case 0x0c: + case 0x0d: + case 0x14: + case 0x15: + case 0x1c: + case 0x1d: + case 0x24: + case 0x25: + case 0x2c: + case 0x2d: + case 0x34: + case 0x35: + case 0x3c: + case 0x3d: + /* alu A, imm */ + bits = 8 << (opcode & 1); + wait(1, 0); + cpu_data = pfq_fetch(); + cpu_dest = get_accum(bits); /* AX/AL */ + cpu_src = cpu_data; + cpu_alu_op = (opcode >> 3) & 7; + alu_op(bits); + if (cpu_alu_op != 7) + set_accum(bits, cpu_data); + wait(1, 0); + break; - case 0x27: /*DAA*/ - cpu_dest = AL; - set_of(0); - old_af = !!(cpu_state.flags & A_FLAG); - if ((cpu_state.flags & A_FLAG) || (AL & 0x0f) > 9) { - cpu_src = 6; - cpu_data = cpu_dest + cpu_src; - set_of_add(8); - cpu_dest = cpu_data; - set_af(1); - } - if ((cpu_state.flags & C_FLAG) || AL > (old_af ? 0x9f : 0x99)) { - cpu_src = 0x60; - cpu_data = cpu_dest + cpu_src; - set_of_add(8); - cpu_dest = cpu_data; - set_cf(1); - } - AL = cpu_dest; - set_pzs(8); - wait(3, 0); - break; - case 0x2F: /*DAS*/ - cpu_dest = AL; - set_of(0); - old_af = !!(cpu_state.flags & A_FLAG); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - cpu_src = 6; - cpu_data = cpu_dest - cpu_src; - set_of_sub(8); - cpu_dest = cpu_data; - set_af(1); - } - if ((cpu_state.flags & C_FLAG) || AL > (old_af ? 0x9f : 0x99)) { - cpu_src = 0x60; - cpu_data = cpu_dest - cpu_src; - set_of_sub(8); - cpu_dest = cpu_data; - set_cf(1); - } - AL = cpu_dest; - set_pzs(8); - wait(3, 0); - break; - case 0x37: /*AAA*/ - wait(1, 0); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - cpu_src = 6; - ++AH; - set_ca(); - } else { - cpu_src = 0; - clear_ca(); - wait(1, 0); - } - cpu_dest = AL; - cpu_data = cpu_dest + cpu_src; - set_of_add(8); - aa(); - break; - case 0x3F: /*AAS*/ - wait(1, 0); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - cpu_src = 6; - --AH; - set_ca(); - } else { - cpu_src = 0; - clear_ca(); - wait(1, 0); - } - cpu_dest = AL; - cpu_data = cpu_dest - cpu_src; - set_of_sub(8); - aa(); - break; + case 0x27: /*DAA*/ + cpu_dest = AL; + set_of(0); + old_af = !!(cpu_state.flags & A_FLAG); + if ((cpu_state.flags & A_FLAG) || (AL & 0x0f) > 9) { + cpu_src = 6; + cpu_data = cpu_dest + cpu_src; + set_of_add(8); + cpu_dest = cpu_data; + set_af(1); + } + if ((cpu_state.flags & C_FLAG) || AL > (old_af ? 0x9f : 0x99)) { + cpu_src = 0x60; + cpu_data = cpu_dest + cpu_src; + set_of_add(8); + cpu_dest = cpu_data; + set_cf(1); + } + AL = cpu_dest; + set_pzs(8); + wait(3, 0); + break; + case 0x2F: /*DAS*/ + cpu_dest = AL; + set_of(0); + old_af = !!(cpu_state.flags & A_FLAG); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { + cpu_src = 6; + cpu_data = cpu_dest - cpu_src; + set_of_sub(8); + cpu_dest = cpu_data; + set_af(1); + } + if ((cpu_state.flags & C_FLAG) || AL > (old_af ? 0x9f : 0x99)) { + cpu_src = 0x60; + cpu_data = cpu_dest - cpu_src; + set_of_sub(8); + cpu_dest = cpu_data; + set_cf(1); + } + AL = cpu_dest; + set_pzs(8); + wait(3, 0); + break; + case 0x37: /*AAA*/ + wait(1, 0); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { + cpu_src = 6; + ++AH; + set_ca(); + } else { + cpu_src = 0; + clear_ca(); + wait(1, 0); + } + cpu_dest = AL; + cpu_data = cpu_dest + cpu_src; + set_of_add(8); + aa(); + break; + case 0x3F: /*AAS*/ + wait(1, 0); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { + cpu_src = 6; + --AH; + set_ca(); + } else { + cpu_src = 0; + clear_ca(); + wait(1, 0); + } + cpu_dest = AL; + cpu_data = cpu_dest - cpu_src; + set_of_sub(8); + aa(); + break; - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4A: case 0x4B: - case 0x4C: case 0x4D: case 0x4E: case 0x4F: - /* INCDEC rw */ - wait(1, 0); - cpu_dest = cpu_state.regs[opcode & 7].w; - cpu_src = 1; - bits = 16; - if ((opcode & 8) == 0) { - cpu_data = cpu_dest + cpu_src; - set_of_add(bits); - } else { - cpu_data = cpu_dest - cpu_src; - set_of_sub(bits); - } - do_af(); - set_pzs(16); - cpu_state.regs[opcode & 7].w = cpu_data; - break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + /* INCDEC rw */ + wait(1, 0); + cpu_dest = cpu_state.regs[opcode & 7].w; + cpu_src = 1; + bits = 16; + if ((opcode & 8) == 0) { + cpu_data = cpu_dest + cpu_src; + set_of_add(bits); + } else { + cpu_data = cpu_dest - cpu_src; + set_of_sub(bits); + } + do_af(); + set_pzs(16); + cpu_state.regs[opcode & 7].w = cpu_data; + break; - case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ - case 0x54: case 0x55: case 0x56: case 0x57: - access(30, 16); - push(&(cpu_state.regs[opcode & 0x07].w)); - break; - case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/ - case 0x5C: case 0x5D: case 0x5E: case 0x5F: - access(23, 16); - cpu_state.regs[opcode & 0x07].w = pop(); - wait(1, 0); - break; + case 0x50: + case 0x51: + case 0x52: + case 0x53: /*PUSH r16*/ + case 0x54: + case 0x55: + case 0x56: + case 0x57: + access(30, 16); + push(&(cpu_state.regs[opcode & 0x07].w)); + break; + case 0x58: + case 0x59: + case 0x5A: + case 0x5B: /*POP r16*/ + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + access(23, 16); + cpu_state.regs[opcode & 0x07].w = pop(); + wait(1, 0); + break; - case 0x60: /*JO alias*/ - case 0x70: /*JO*/ - case 0x61: /*JNO alias*/ - case 0x71: /*JNO*/ - jcc(opcode, cpu_state.flags & V_FLAG); - break; - case 0x62: /*JB alias*/ - case 0x72: /*JB*/ - case 0x63: /*JNB alias*/ - case 0x73: /*JNB*/ - jcc(opcode, cpu_state.flags & C_FLAG); - break; - case 0x64: /*JE alias*/ - case 0x74: /*JE*/ - case 0x65: /*JNE alias*/ - case 0x75: /*JNE*/ - jcc(opcode, cpu_state.flags & Z_FLAG); - break; - case 0x66: /*JBE alias*/ - case 0x76: /*JBE*/ - case 0x67: /*JNBE alias*/ - 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 0x79: /*JNS*/ - jcc(opcode, cpu_state.flags & N_FLAG); - break; - case 0x6A: /*JP alias*/ - case 0x7A: /*JP*/ - case 0x6B: /*JNP alias*/ - case 0x7B: /*JNP*/ - jcc(opcode, cpu_state.flags & P_FLAG); - break; - case 0x6C: /*JL alias*/ - case 0x7C: /*JL*/ - case 0x6D: /*JNL alias*/ - case 0x7D: /*JNL*/ - temp = (cpu_state.flags & N_FLAG) ? 1 : 0; - temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; - jcc(opcode, temp ^ temp2); - break; - case 0x6E: /*JLE alias*/ - case 0x7E: /*JLE*/ - case 0x6F: /*JNLE alias*/ - case 0x7F: /*JNLE*/ - temp = (cpu_state.flags & N_FLAG) ? 1 : 0; - temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; - jcc(opcode, (cpu_state.flags & Z_FLAG) || (temp != temp2)); - break; + case 0x60: /*JO alias*/ + case 0x70: /*JO*/ + case 0x61: /*JNO alias*/ + case 0x71: /*JNO*/ + jcc(opcode, cpu_state.flags & V_FLAG); + break; + case 0x62: /*JB alias*/ + case 0x72: /*JB*/ + case 0x63: /*JNB alias*/ + case 0x73: /*JNB*/ + jcc(opcode, cpu_state.flags & C_FLAG); + break; + case 0x64: /*JE alias*/ + case 0x74: /*JE*/ + case 0x65: /*JNE alias*/ + case 0x75: /*JNE*/ + jcc(opcode, cpu_state.flags & Z_FLAG); + break; + case 0x66: /*JBE alias*/ + case 0x76: /*JBE*/ + case 0x67: /*JNBE alias*/ + 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 0x79: /*JNS*/ + jcc(opcode, cpu_state.flags & N_FLAG); + break; + case 0x6A: /*JP alias*/ + case 0x7A: /*JP*/ + case 0x6B: /*JNP alias*/ + case 0x7B: /*JNP*/ + jcc(opcode, cpu_state.flags & P_FLAG); + break; + case 0x6C: /*JL alias*/ + case 0x7C: /*JL*/ + case 0x6D: /*JNL alias*/ + case 0x7D: /*JNL*/ + temp = (cpu_state.flags & N_FLAG) ? 1 : 0; + temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; + jcc(opcode, temp ^ temp2); + break; + case 0x6E: /*JLE alias*/ + case 0x7E: /*JLE*/ + case 0x6F: /*JNLE alias*/ + case 0x7F: /*JNLE*/ + temp = (cpu_state.flags & N_FLAG) ? 1 : 0; + temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; + jcc(opcode, (cpu_state.flags & Z_FLAG) || (temp != temp2)); + break; - case 0x80: case 0x81: case 0x82: case 0x83: - /* alu rm, imm */ - bits = 8 << (opcode & 1); - do_mod_rm(); - access(47, bits); - cpu_data = get_ea(); - cpu_dest = cpu_data; - if (cpu_mod != 3) - wait(3, 0); - if (opcode == 0x81) { - if (cpu_mod == 3) - wait(1, 0); - cpu_src = pfq_fetchw(); - } else { - if (cpu_mod == 3) - wait(1, 0); - if (opcode == 0x83) - cpu_src = sign_extend(pfq_fetchb()); - else - cpu_src = pfq_fetchb() | 0xff00; - } - wait(1, 0); - cpu_alu_op = (rmdat & 0x38) >> 3; - alu_op(bits); - if (cpu_alu_op != 7) { - access(11, bits); - set_ea(cpu_data); - } else { - if (cpu_mod != 3) - wait(1, 0); - } - break; + case 0x80: + case 0x81: + case 0x82: + case 0x83: + /* alu rm, imm */ + bits = 8 << (opcode & 1); + do_mod_rm(); + access(47, bits); + cpu_data = get_ea(); + cpu_dest = cpu_data; + if (cpu_mod != 3) + wait(3, 0); + if (opcode == 0x81) { + if (cpu_mod == 3) + wait(1, 0); + cpu_src = pfq_fetchw(); + } else { + if (cpu_mod == 3) + wait(1, 0); + if (opcode == 0x83) + cpu_src = sign_extend(pfq_fetchb()); + else + cpu_src = pfq_fetchb() | 0xff00; + } + wait(1, 0); + cpu_alu_op = (rmdat & 0x38) >> 3; + alu_op(bits); + if (cpu_alu_op != 7) { + access(11, bits); + set_ea(cpu_data); + } else { + if (cpu_mod != 3) + wait(1, 0); + } + break; - case 0x84: case 0x85: - /* TEST rm, reg */ - bits = 8 << (opcode & 1); - do_mod_rm(); - access(48, bits); - cpu_data = get_ea(); - test(bits, cpu_data, get_reg(cpu_reg)); - if (cpu_mod == 3) - wait(2, 0); - wait(2, 0); - break; - case 0x86: case 0x87: - /* XCHG rm, reg */ - bits = 8 << (opcode & 1); - do_mod_rm(); - access(49, bits); - cpu_data = get_ea(); - cpu_src = get_reg(cpu_reg); - set_reg(cpu_reg, cpu_data); - wait(3, 0); - access(12, bits); - set_ea(cpu_src); - break; + case 0x84: + case 0x85: + /* TEST rm, reg */ + bits = 8 << (opcode & 1); + do_mod_rm(); + access(48, bits); + cpu_data = get_ea(); + test(bits, cpu_data, get_reg(cpu_reg)); + if (cpu_mod == 3) + wait(2, 0); + wait(2, 0); + break; + case 0x86: + case 0x87: + /* XCHG rm, reg */ + bits = 8 << (opcode & 1); + do_mod_rm(); + access(49, bits); + cpu_data = get_ea(); + cpu_src = get_reg(cpu_reg); + set_reg(cpu_reg, cpu_data); + wait(3, 0); + access(12, bits); + set_ea(cpu_src); + break; - case 0x88: case 0x89: - /* MOV rm, reg */ - bits = 8 << (opcode & 1); - do_mod_rm(); - wait(1, 0); - access(13, bits); - set_ea(get_reg(cpu_reg)); - break; - case 0x8A: case 0x8B: - /* MOV reg, rm */ - bits = 8 << (opcode & 1); - do_mod_rm(); - access(50, bits); - set_reg(cpu_reg, get_ea()); - wait(1, 0); - if (cpu_mod != 3) - wait(2, 0); - break; + case 0x88: + case 0x89: + /* MOV rm, reg */ + bits = 8 << (opcode & 1); + do_mod_rm(); + wait(1, 0); + access(13, bits); + set_ea(get_reg(cpu_reg)); + break; + case 0x8A: + case 0x8B: + /* MOV reg, rm */ + bits = 8 << (opcode & 1); + do_mod_rm(); + access(50, bits); + set_reg(cpu_reg, get_ea()); + wait(1, 0); + if (cpu_mod != 3) + wait(2, 0); + break; - case 0x8C: /*MOV w,sreg*/ - do_mod_rm(); - if (cpu_mod == 3) - wait(1, 0); - access(14, 16); - seteaw(_opseg[(rmdat & 0x18) >> 3]->seg); - break; + case 0x8C: /*MOV w,sreg*/ + do_mod_rm(); + if (cpu_mod == 3) + wait(1, 0); + access(14, 16); + seteaw(_opseg[(rmdat & 0x18) >> 3]->seg); + break; - case 0x8D: /*LEA*/ - do_mod_rm(); - cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - wait(1, 0); - if (cpu_mod != 3) - wait(2, 0); - break; + case 0x8D: /*LEA*/ + do_mod_rm(); + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + wait(1, 0); + if (cpu_mod != 3) + wait(2, 0); + break; - case 0x8E: /*MOV sreg,w*/ - do_mod_rm(); - access(51, 16); - tempw = geteaw(); - if ((rmdat & 0x18) == 0x08) { - load_cs(tempw); - pfq_pos = 0; - } else - load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]); - wait(1, 0); - if (cpu_mod != 3) - wait(2, 0); - if (((rmdat & 0x18) >> 3) == 2) - noint = 1; - break; + case 0x8E: /*MOV sreg,w*/ + do_mod_rm(); + access(51, 16); + tempw = geteaw(); + if ((rmdat & 0x18) == 0x08) { + load_cs(tempw); + pfq_pos = 0; + } else + load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]); + wait(1, 0); + if (cpu_mod != 3) + wait(2, 0); + if (((rmdat & 0x18) >> 3) == 2) + noint = 1; + break; - case 0x8F: /*POPW*/ - do_mod_rm(); - wait(1, 0); - cpu_src = cpu_state.eaaddr; - access(24, 16); - if (cpu_mod != 3) - wait(2, 0); - cpu_data = pop(); - cpu_state.eaaddr = cpu_src; - wait(2, 0); - access(15, 16); - seteaw(cpu_data); - break; + case 0x8F: /*POPW*/ + do_mod_rm(); + wait(1, 0); + cpu_src = cpu_state.eaaddr; + access(24, 16); + if (cpu_mod != 3) + wait(2, 0); + cpu_data = pop(); + cpu_state.eaaddr = cpu_src; + wait(2, 0); + access(15, 16); + seteaw(cpu_data); + break; - case 0x90: case 0x91: case 0x92: case 0x93: - case 0x94: case 0x95: case 0x96: case 0x97: - /* XCHG AX, rw */ - wait(1, 0); - cpu_data = cpu_state.regs[opcode & 7].w; - cpu_state.regs[opcode & 7].w = AX; - AX = cpu_data; - wait(1, 0); - break; + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + /* XCHG AX, rw */ + wait(1, 0); + cpu_data = cpu_state.regs[opcode & 7].w; + cpu_state.regs[opcode & 7].w = AX; + AX = cpu_data; + wait(1, 0); + break; - case 0x98: /*CBW*/ - wait(1, 0); - AX = sign_extend(AL); - break; - case 0x99: /*CWD*/ - wait(4, 0); - if (!top_bit(AX, 16)) - DX = 0; - else { - wait(1, 0); - DX = 0xffff; - } - break; - case 0x9A: /*CALL FAR*/ - wait(1, 0); - new_ip = pfq_fetchw(); - wait(1, 0); - new_cs = pfq_fetchw(); - pfq_clear(); - access(31, 16); - push(&(CS)); - access(60, 16); - cpu_state.oldpc = cpu_state.pc; - load_cs(new_cs); - set_ip(new_ip); - access(32, 16); - push((uint16_t *) &(cpu_state.oldpc)); - break; - case 0x9B: /*WAIT*/ - if (!repeating) - wait(2, 0); - wait(5, 0); + case 0x98: /*CBW*/ + wait(1, 0); + AX = sign_extend(AL); + break; + case 0x99: /*CWD*/ + wait(4, 0); + if (!top_bit(AX, 16)) + DX = 0; + else { + wait(1, 0); + DX = 0xffff; + } + break; + case 0x9A: /*CALL FAR*/ + wait(1, 0); + new_ip = pfq_fetchw(); + wait(1, 0); + new_cs = pfq_fetchw(); + pfq_clear(); + access(31, 16); + push(&(CS)); + access(60, 16); + cpu_state.oldpc = cpu_state.pc; + load_cs(new_cs); + set_ip(new_ip); + access(32, 16); + push((uint16_t *) &(cpu_state.oldpc)); + break; + case 0x9B: /*WAIT*/ + if (!repeating) + wait(2, 0); + wait(5, 0); #ifdef NO_HACK - if (irq_pending()) { - wait(7, 0); - check_interrupts(); - } else { - repeating = 1; - completed = 0; - clock_end(); - } + if (irq_pending()) { + wait(7, 0); + check_interrupts(); + } else { + repeating = 1; + completed = 0; + clock_end(); + } #else - wait(7, 0); - check_interrupts(); + wait(7, 0); + check_interrupts(); #endif - break; - case 0x9C: /*PUSHF*/ - access(33, 16); - tempw = (cpu_state.flags & 0x0fd7) | 0xf000; - push(&tempw); - break; - case 0x9D: /*POPF*/ - access(25, 16); - cpu_state.flags = pop() | 2; - wait(1, 0); - break; - case 0x9E: /*SAHF*/ - wait(1, 0); - cpu_state.flags = (cpu_state.flags & 0xff02) | AH; - wait(2, 0); - break; - case 0x9F: /*LAHF*/ - wait(1, 0); - AH = cpu_state.flags & 0xd7; - break; + break; + case 0x9C: /*PUSHF*/ + access(33, 16); + tempw = (cpu_state.flags & 0x0fd7) | 0xf000; + push(&tempw); + break; + case 0x9D: /*POPF*/ + access(25, 16); + cpu_state.flags = pop() | 2; + wait(1, 0); + break; + case 0x9E: /*SAHF*/ + wait(1, 0); + cpu_state.flags = (cpu_state.flags & 0xff02) | AH; + wait(2, 0); + break; + case 0x9F: /*LAHF*/ + wait(1, 0); + AH = cpu_state.flags & 0xd7; + break; - case 0xA0: case 0xA1: - /* MOV A, [iw] */ - bits = 8 << (opcode & 1); - wait(1, 0); - cpu_state.eaaddr = pfq_fetchw(); - access(1, bits); - set_accum(bits, readmem((ovr_seg ? *ovr_seg : ds))); - wait(1, 0); - break; - case 0xA2: case 0xA3: - /* MOV [iw], A */ - bits = 8 << (opcode & 1); - wait(1, 0); - cpu_state.eaaddr = pfq_fetchw(); - access(7, bits); - writemem((ovr_seg ? *ovr_seg : ds), get_accum(bits)); - break; + case 0xA0: + case 0xA1: + /* MOV A, [iw] */ + bits = 8 << (opcode & 1); + wait(1, 0); + cpu_state.eaaddr = pfq_fetchw(); + access(1, bits); + set_accum(bits, readmem((ovr_seg ? *ovr_seg : ds))); + wait(1, 0); + break; + case 0xA2: + case 0xA3: + /* MOV [iw], A */ + bits = 8 << (opcode & 1); + wait(1, 0); + cpu_state.eaaddr = pfq_fetchw(); + access(7, bits); + writemem((ovr_seg ? *ovr_seg : ds), get_accum(bits)); + break; - case 0xA4: case 0xA5: /* MOVS */ - case 0xAC: case 0xAD: /* LODS */ - bits = 8 << (opcode & 1); - if (!repeating) { - wait(1, 0); - if ((opcode & 8) == 0 && in_rep != 0) - wait(1, 0); - } - if (rep_action(bits)) { - wait(1, 0); - if ((opcode & 8) != 0) - wait(1, 0); - break; - } - if (in_rep != 0 && (opcode & 8) != 0) - wait(1, 0); - access(20, bits); - lods(bits); - if ((opcode & 8) == 0) { - access(27, bits); - stos(bits); - } else { - set_accum(bits, cpu_data); - if (in_rep != 0) - wait(2, 0); - } - if (in_rep == 0) { - wait(3, 0); - if ((opcode & 8) != 0) - wait(1, 0); - break; - } - repeating = 1; - clock_end(); - break; + case 0xA4: + case 0xA5: /* MOVS */ + case 0xAC: + case 0xAD: /* LODS */ + bits = 8 << (opcode & 1); + if (!repeating) { + wait(1, 0); + if ((opcode & 8) == 0 && in_rep != 0) + wait(1, 0); + } + if (rep_action(bits)) { + wait(1, 0); + if ((opcode & 8) != 0) + wait(1, 0); + break; + } + if (in_rep != 0 && (opcode & 8) != 0) + wait(1, 0); + access(20, bits); + lods(bits); + if ((opcode & 8) == 0) { + access(27, bits); + stos(bits); + } else { + set_accum(bits, cpu_data); + if (in_rep != 0) + wait(2, 0); + } + if (in_rep == 0) { + wait(3, 0); + if ((opcode & 8) != 0) + wait(1, 0); + break; + } + repeating = 1; + clock_end(); + break; - case 0xA6: case 0xA7: /* CMPS */ - case 0xAE: case 0xAF: /* SCAS */ - bits = 8 << (opcode & 1); - if (!repeating) - wait(1, 0); - if (rep_action(bits)) { - wait(2, 0); - break; - } - if (in_rep != 0) - wait(1, 0); - wait(1, 0); - cpu_dest = get_accum(bits); - if ((opcode & 8) == 0) { - access(21, bits); - lods(bits); - wait(1, 0); - cpu_dest = cpu_data; - } - access(2, bits); - cpu_state.eaaddr = DI; - cpu_data = readmem(es); - DI = string_increment(bits); - cpu_src = cpu_data; - sub(bits); - wait(2, 0); - if (in_rep == 0) { - wait(3, 0); - break; - } - if ((!!(cpu_state.flags & Z_FLAG)) == (in_rep == 1)) { - completed = 1; - wait(4, 0); - break; - } - repeating = 1; - clock_end(); - break; + case 0xA6: + case 0xA7: /* CMPS */ + case 0xAE: + case 0xAF: /* SCAS */ + bits = 8 << (opcode & 1); + if (!repeating) + wait(1, 0); + if (rep_action(bits)) { + wait(2, 0); + break; + } + if (in_rep != 0) + wait(1, 0); + wait(1, 0); + cpu_dest = get_accum(bits); + if ((opcode & 8) == 0) { + access(21, bits); + lods(bits); + wait(1, 0); + cpu_dest = cpu_data; + } + access(2, bits); + cpu_state.eaaddr = DI; + cpu_data = readmem(es); + DI = string_increment(bits); + cpu_src = cpu_data; + sub(bits); + wait(2, 0); + if (in_rep == 0) { + wait(3, 0); + break; + } + if ((!!(cpu_state.flags & Z_FLAG)) == (in_rep == 1)) { + completed = 1; + wait(4, 0); + break; + } + repeating = 1; + clock_end(); + break; - case 0xA8: case 0xA9: - /* TEST A, imm */ - bits = 8 << (opcode & 1); - wait(1, 0); - cpu_data = pfq_fetch(); - test(bits, get_accum(bits), cpu_data); - wait(1, 0); - break; + case 0xA8: + case 0xA9: + /* TEST A, imm */ + bits = 8 << (opcode & 1); + wait(1, 0); + cpu_data = pfq_fetch(); + test(bits, get_accum(bits), cpu_data); + wait(1, 0); + break; - case 0xAA: case 0xAB: /* STOS */ - bits = 8 << (opcode & 1); - if (!repeating) { - wait(1, 0); - if (in_rep != 0) - wait(1, 0); - } - if (rep_action(bits)) { - wait(1, 0); - break; - } - cpu_data = AX; - access(28, bits); - stos(bits); - if (in_rep == 0) { - wait(3, 0); - break; - } - repeating = 1; - clock_end(); - break; + case 0xAA: + case 0xAB: /* STOS */ + bits = 8 << (opcode & 1); + if (!repeating) { + wait(1, 0); + if (in_rep != 0) + wait(1, 0); + } + if (rep_action(bits)) { + wait(1, 0); + break; + } + cpu_data = AX; + access(28, bits); + stos(bits); + if (in_rep == 0) { + wait(3, 0); + break; + } + repeating = 1; + clock_end(); + break; - case 0xB0: case 0xB1: case 0xB2: case 0xB3: /*MOV cpu_reg,#8*/ - case 0xB4: case 0xB5: case 0xB6: case 0xB7: - wait(1, 0); - if (opcode & 0x04) - cpu_state.regs[opcode & 0x03].b.h = pfq_fetchb(); - else - cpu_state.regs[opcode & 0x03].b.l = pfq_fetchb(); - wait(1, 0); - break; + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: /*MOV cpu_reg,#8*/ + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + wait(1, 0); + if (opcode & 0x04) + cpu_state.regs[opcode & 0x03].b.h = pfq_fetchb(); + else + cpu_state.regs[opcode & 0x03].b.l = pfq_fetchb(); + wait(1, 0); + break; - case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV cpu_reg,#16*/ - case 0xBC: case 0xBD: case 0xBE: case 0xBF: - wait(1, 0); - cpu_state.regs[opcode & 0x07].w = pfq_fetchw(); - wait(1, 0); - break; + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: /*MOV cpu_reg,#16*/ + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + wait(1, 0); + cpu_state.regs[opcode & 0x07].w = pfq_fetchw(); + wait(1, 0); + break; - case 0xC0: case 0xC1: case 0xC2: case 0xC3: - case 0xC8: case 0xC9: case 0xCA: case 0xCB: - /* RET */ - bits = 8 + (opcode & 0x08); - if ((opcode & 9) != 1) - wait(1, 0); - if (!(opcode & 1)) { - cpu_src = pfq_fetchw(); - wait(1, 0); - } - if ((opcode & 9) == 9) - wait(1, 0); - pfq_clear(); - access(26, bits); - new_ip = pop(); - wait(2, 0); - if ((opcode & 8) == 0) - new_cs = CS; - else { - access(42, bits); - new_cs = pop(); - if (opcode & 1) - wait(1, 0); - } - if (!(opcode & 1)) { - SP += cpu_src; - wait(1, 0); - } - load_cs(new_cs); - access(72, bits); - set_ip(new_ip); - break; + case 0xC0: + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + /* RET */ + bits = 8 + (opcode & 0x08); + if ((opcode & 9) != 1) + wait(1, 0); + if (!(opcode & 1)) { + cpu_src = pfq_fetchw(); + wait(1, 0); + } + if ((opcode & 9) == 9) + wait(1, 0); + pfq_clear(); + access(26, bits); + new_ip = pop(); + wait(2, 0); + if ((opcode & 8) == 0) + new_cs = CS; + else { + access(42, bits); + new_cs = pop(); + if (opcode & 1) + wait(1, 0); + } + if (!(opcode & 1)) { + SP += cpu_src; + wait(1, 0); + } + load_cs(new_cs); + access(72, bits); + set_ip(new_ip); + break; - case 0xC4: case 0xC5: - /* LsS rw, rmd */ - do_mod_rm(); - bits = 16; - access(52, bits); - read_ea(1, bits); - cpu_state.regs[cpu_reg].w = cpu_data; - access(57, bits); - read_ea2(bits); - load_seg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); - wait(1, 0); - break; + case 0xC4: + case 0xC5: + /* LsS rw, rmd */ + do_mod_rm(); + bits = 16; + access(52, bits); + read_ea(1, bits); + cpu_state.regs[cpu_reg].w = cpu_data; + access(57, bits); + read_ea2(bits); + load_seg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); + wait(1, 0); + break; - case 0xC6: case 0xC7: - /* MOV rm, imm */ - bits = 8 << (opcode & 1); - do_mod_rm(); - wait(1, 0); - if (cpu_mod != 3) - wait(2, 0); - cpu_data = pfq_fetch(); - if (cpu_mod == 3) - wait(1, 0); - access(16, bits); - set_ea(cpu_data); - break; + case 0xC6: + case 0xC7: + /* MOV rm, imm */ + bits = 8 << (opcode & 1); + do_mod_rm(); + wait(1, 0); + if (cpu_mod != 3) + wait(2, 0); + cpu_data = pfq_fetch(); + if (cpu_mod == 3) + wait(1, 0); + access(16, bits); + set_ea(cpu_data); + break; - case 0xCC: /*INT 3*/ - interrupt(3); - break; - case 0xCD: /*INT*/ - wait(1, 0); - interrupt(pfq_fetchb()); - break; - case 0xCE: /*INTO*/ - wait(3, 0); - if (cpu_state.flags & V_FLAG) { - wait(2, 0); - interrupt(4); - } - break; + case 0xCC: /*INT 3*/ + interrupt(3); + break; + case 0xCD: /*INT*/ + wait(1, 0); + interrupt(pfq_fetchb()); + break; + case 0xCE: /*INTO*/ + wait(3, 0); + if (cpu_state.flags & V_FLAG) { + wait(2, 0); + interrupt(4); + } + break; - case 0xCF: /*IRET*/ - access(43, 8); - new_ip = pop(); - wait(3, 0); - access(44, 8); - new_cs = pop(); - load_cs(new_cs); - access(62, 8); - set_ip(new_ip); - access(45, 8); - cpu_state.flags = pop() | 2; - wait(5, 0); - noint = 1; - nmi_enable = 1; - break; + case 0xCF: /*IRET*/ + access(43, 8); + new_ip = pop(); + wait(3, 0); + access(44, 8); + new_cs = pop(); + load_cs(new_cs); + access(62, 8); + set_ip(new_ip); + access(45, 8); + cpu_state.flags = pop() | 2; + wait(5, 0); + noint = 1; + nmi_enable = 1; + break; - case 0xD0: case 0xD1: case 0xD2: case 0xD3: - /* rot rm */ - bits = 8 << (opcode & 1); - do_mod_rm(); - if (cpu_mod == 3) - wait(1, 0); - access(53, bits); - cpu_data = get_ea(); - if ((opcode & 2) == 0) { - cpu_src = 1; - wait((cpu_mod != 3) ? 4 : 0, 0); - } else { - cpu_src = CL; - wait((cpu_mod != 3) ? 9 : 6, 0); - } - while (cpu_src != 0) { - cpu_dest = cpu_data; - oldc = cpu_state.flags & C_FLAG; - switch (rmdat & 0x38) { - case 0x00: /* ROL */ - set_cf(top_bit(cpu_data, bits)); - cpu_data <<= 1; - cpu_data |= ((cpu_state.flags & C_FLAG) ? 1 : 0); - set_of_rotate(bits); - set_af(0); - break; - case 0x08: /* ROR */ - set_cf((cpu_data & 1) != 0); - cpu_data >>= 1; - if (cpu_state.flags & C_FLAG) - cpu_data |= (!(opcode & 1) ? 0x80 : 0x8000); - set_of_rotate(bits); - set_af(0); - break; - case 0x10: /* RCL */ - set_cf(top_bit(cpu_data, bits)); - cpu_data = (cpu_data << 1) | (oldc ? 1 : 0); - set_of_rotate(bits); - set_af(0); - break; - case 0x18: /* RCR */ - set_cf((cpu_data & 1) != 0); - cpu_data >>= 1; - if (oldc) - cpu_data |= (!(opcode & 0x01) ? 0x80 : 0x8000); - set_cf((cpu_dest & 1) != 0); - set_of_rotate(bits); - set_af(0); - break; - case 0x20: /* SHL */ - set_cf(top_bit(cpu_data, bits)); - cpu_data <<= 1; - set_of_rotate(bits); - set_af((cpu_data & 0x10) != 0); - set_pzs(bits); - break; - case 0x28: /* SHR */ - set_cf((cpu_data & 1) != 0); - cpu_data >>= 1; - set_of_rotate(bits); - set_af(0); - set_pzs(bits); - break; - case 0x30: /* SETMO - undocumented? */ - bitwise(bits, 0xffff); - set_cf(0); - set_of_rotate(bits); - set_af(0); - set_pzs(bits); - break; - case 0x38: /* SAR */ - set_cf((cpu_data & 1) != 0); - cpu_data >>= 1; - if (!(opcode & 1)) - cpu_data |= (cpu_dest & 0x80); - else - cpu_data |= (cpu_dest & 0x8000); - set_of_rotate(bits); - set_af(0); - set_pzs(bits); - break; - } - if ((opcode & 2) != 0) - wait(4, 0); - --cpu_src; - } - access(17, bits); - set_ea(cpu_data); - break; + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + /* rot rm */ + bits = 8 << (opcode & 1); + do_mod_rm(); + if (cpu_mod == 3) + wait(1, 0); + access(53, bits); + cpu_data = get_ea(); + if ((opcode & 2) == 0) { + cpu_src = 1; + wait((cpu_mod != 3) ? 4 : 0, 0); + } else { + cpu_src = CL; + wait((cpu_mod != 3) ? 9 : 6, 0); + } + while (cpu_src != 0) { + cpu_dest = cpu_data; + oldc = cpu_state.flags & C_FLAG; + switch (rmdat & 0x38) { + case 0x00: /* ROL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data <<= 1; + cpu_data |= ((cpu_state.flags & C_FLAG) ? 1 : 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x08: /* ROR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (cpu_state.flags & C_FLAG) + cpu_data |= (!(opcode & 1) ? 0x80 : 0x8000); + set_of_rotate(bits); + set_af(0); + break; + case 0x10: /* RCL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data = (cpu_data << 1) | (oldc ? 1 : 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x18: /* RCR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (oldc) + cpu_data |= (!(opcode & 0x01) ? 0x80 : 0x8000); + set_cf((cpu_dest & 1) != 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x20: /* SHL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data <<= 1; + set_of_rotate(bits); + set_af((cpu_data & 0x10) != 0); + set_pzs(bits); + break; + case 0x28: /* SHR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + case 0x30: /* SETMO - undocumented? */ + bitwise(bits, 0xffff); + set_cf(0); + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + case 0x38: /* SAR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (!(opcode & 1)) + cpu_data |= (cpu_dest & 0x80); + else + cpu_data |= (cpu_dest & 0x8000); + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + } + if ((opcode & 2) != 0) + wait(4, 0); + --cpu_src; + } + access(17, bits); + set_ea(cpu_data); + break; - case 0xD4: /*AAM*/ - wait(1, 0); - cpu_src = pfq_fetchb(); - if (x86_div(AL, 0)) - set_pzs(16); - break; - case 0xD5: /*AAD*/ - wait(1, 0); - mul(pfq_fetchb(), AH); - cpu_dest = AL; - cpu_src = cpu_data; - add(8); - AL = cpu_data; - AH = 0x00; - break; - case 0xD6: /*SALC*/ - wait(1, 0); - AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00; - wait(1, 0); - break; - case 0xD7: /*XLATB*/ - cpu_state.eaaddr = (BX + AL) & 0xffff; - access(4, 8); - AL = readmemb((ovr_seg ? *ovr_seg : ds) + cpu_state.eaaddr); - wait(1, 0); - break; + case 0xD4: /*AAM*/ + wait(1, 0); + cpu_src = pfq_fetchb(); + if (x86_div(AL, 0)) + set_pzs(16); + break; + case 0xD5: /*AAD*/ + wait(1, 0); + mul(pfq_fetchb(), AH); + cpu_dest = AL; + cpu_src = cpu_data; + add(8); + AL = cpu_data; + AH = 0x00; + break; + case 0xD6: /*SALC*/ + wait(1, 0); + AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00; + wait(1, 0); + break; + case 0xD7: /*XLATB*/ + cpu_state.eaaddr = (BX + AL) & 0xffff; + access(4, 8); + AL = readmemb((ovr_seg ? *ovr_seg : ds) + cpu_state.eaaddr); + wait(1, 0); + break; - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - case 0xDD: case 0xDC: case 0xDE: case 0xDF: - /* esc i, r, rm */ - do_mod_rm(); - access(54, 16); - tempw = cpu_state.pc; - if (!hasfpu) - geteaw(); - else switch(opcode) { - case 0xD8: - ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xD9: - ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDA: - ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDB: - ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDC: - ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); - break; - case 0xDD: - ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDE: - ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); - break; - case 0xDF: - ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); - break; - } - cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on - the 286+ core, but not here. */ - wait(1, 0); - if (cpu_mod != 3) - wait(2, 0); - break; + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDD: + case 0xDC: + case 0xDE: + case 0xDF: + /* esc i, r, rm */ + do_mod_rm(); + access(54, 16); + tempw = cpu_state.pc; + if (!hasfpu) + geteaw(); + else + switch (opcode) { + case 0xD8: + ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + break; + case 0xD9: + ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDA: + ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDB: + ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDC: + ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat); + break; + case 0xDD: + ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDE: + ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat); + break; + case 0xDF: + ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat); + break; + } + cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on + the 286+ core, but not here. */ + wait(1, 0); + if (cpu_mod != 3) + wait(2, 0); + break; - case 0xE0: case 0xE1: case 0xE2: case 0xE3: - /* LOOP */ - wait(3, 0); - cpu_data = pfq_fetchb(); - if (opcode != 0xe2) - wait(1, 0); - if (opcode != 0xe3) { - --CX; - oldc = (CX != 0); - switch (opcode) { - case 0xE0: - if (cpu_state.flags & Z_FLAG) - oldc = 0; - break; - case 0xE1: - if (!(cpu_state.flags & Z_FLAG)) - oldc = 0; - break; - } - } else - oldc = (CX == 0); - if (oldc) - jump_short(); - break; + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + /* LOOP */ + wait(3, 0); + cpu_data = pfq_fetchb(); + if (opcode != 0xe2) + wait(1, 0); + if (opcode != 0xe3) { + --CX; + oldc = (CX != 0); + switch (opcode) { + case 0xE0: + if (cpu_state.flags & Z_FLAG) + oldc = 0; + break; + case 0xE1: + if (!(cpu_state.flags & Z_FLAG)) + oldc = 0; + break; + } + } else + oldc = (CX == 0); + if (oldc) + jump_short(); + break; - case 0xE4: case 0xE5: case 0xE6: case 0xE7: - case 0xEC: case 0xED: case 0xEE: case 0xEF: - bits = 8 << (opcode & 1); - if ((opcode & 0x0e) != 0x0c) - wait(1, 0); - if ((opcode & 8) == 0) - cpu_data = pfq_fetchb(); - else - cpu_data = DX; - cpu_state.eaaddr = cpu_data; - if ((opcode & 2) == 0) { - access(3, bits); - if (opcode & 1) - cpu_io(16, 0, cpu_data); - else - cpu_io(8, 0, cpu_data); - wait(1, 0); - } else { - if ((opcode & 8) == 0) - access(8, bits); - else - access(9, bits); - if (opcode & 1) - cpu_io(16, 1, cpu_data); - else - cpu_io(8, 1, cpu_data); - } - break; + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + case 0xEC: + case 0xED: + case 0xEE: + case 0xEF: + bits = 8 << (opcode & 1); + if ((opcode & 0x0e) != 0x0c) + wait(1, 0); + if ((opcode & 8) == 0) + cpu_data = pfq_fetchb(); + else + cpu_data = DX; + cpu_state.eaaddr = cpu_data; + if ((opcode & 2) == 0) { + access(3, bits); + if (opcode & 1) + cpu_io(16, 0, cpu_data); + else + cpu_io(8, 0, cpu_data); + wait(1, 0); + } else { + if ((opcode & 8) == 0) + access(8, bits); + else + access(9, bits); + if (opcode & 1) + cpu_io(16, 1, cpu_data); + else + cpu_io(8, 1, cpu_data); + } + break; - case 0xE8: /*CALL rel 16*/ - wait(1, 0); - cpu_state.oldpc = jump_near(); - access(34, 8); - push((uint16_t *) &(cpu_state.oldpc)); - break; - case 0xE9: /*JMP rel 16*/ - wait(1, 0); - jump_near(); - break; - case 0xEA: /*JMP far*/ - wait(1, 0); - addr = pfq_fetchw(); - wait(1, 0); - tempw = pfq_fetchw(); - load_cs(tempw); - access(70, 8); - pfq_clear(); - set_ip(addr); - break; - case 0xEB: /*JMP rel*/ - wait(1, 0); - cpu_data = (int8_t) pfq_fetchb(); - jump_short(); - wait(1, 0); - break; + case 0xE8: /*CALL rel 16*/ + wait(1, 0); + cpu_state.oldpc = jump_near(); + access(34, 8); + push((uint16_t *) &(cpu_state.oldpc)); + break; + case 0xE9: /*JMP rel 16*/ + wait(1, 0); + jump_near(); + break; + case 0xEA: /*JMP far*/ + wait(1, 0); + addr = pfq_fetchw(); + wait(1, 0); + tempw = pfq_fetchw(); + load_cs(tempw); + access(70, 8); + pfq_clear(); + set_ip(addr); + break; + case 0xEB: /*JMP rel*/ + wait(1, 0); + cpu_data = (int8_t) pfq_fetchb(); + jump_short(); + wait(1, 0); + break; - case 0xF0: case 0xF1: /*LOCK - F1 is alias*/ - in_lock = 1; - wait(1, 0); - completed = 0; - break; + case 0xF0: + case 0xF1: /*LOCK - F1 is alias*/ + in_lock = 1; + wait(1, 0); + completed = 0; + break; - case 0xF2: /*REPNE*/ - case 0xF3: /*REPE*/ - wait(1, 0); - in_rep = (opcode == 0xf2 ? 1 : 2); - completed = 0; - break; + case 0xF2: /*REPNE*/ + case 0xF3: /*REPE*/ + wait(1, 0); + in_rep = (opcode == 0xf2 ? 1 : 2); + completed = 0; + break; - case 0xF4: /*HLT*/ - if (!repeating) { - wait(1, 0); - pfq_clear(); - } - wait(1, 0); - if (irq_pending()) { - wait(cycles & 1, 0); - check_interrupts(); - } else { - repeating = 1; - completed = 0; - clock_end(); - } - break; - case 0xF5: /*CMC*/ - wait(1, 0); - cpu_state.flags ^= C_FLAG; - break; + case 0xF4: /*HLT*/ + if (!repeating) { + wait(1, 0); + pfq_clear(); + } + wait(1, 0); + if (irq_pending()) { + wait(cycles & 1, 0); + check_interrupts(); + } else { + repeating = 1; + completed = 0; + clock_end(); + } + break; + case 0xF5: /*CMC*/ + wait(1, 0); + cpu_state.flags ^= C_FLAG; + break; - case 0xF6: case 0xF7: - bits = 8 << (opcode & 1); - do_mod_rm(); - access(55, bits); - cpu_data = get_ea(); - switch (rmdat & 0x38) { - case 0x00: case 0x08: - /* TEST */ - wait(2, 0); - if (cpu_mod != 3) - wait(1, 0); - cpu_src = pfq_fetch(); - wait(1, 0); - test(bits, cpu_data, cpu_src); - if (cpu_mod != 3) - wait(1, 0); - break; - case 0x10: /* NOT */ - case 0x18: /* NEG */ - wait(2, 0); - if ((rmdat & 0x38) == 0x10) - cpu_data = ~cpu_data; - else { - cpu_src = cpu_data; - cpu_dest = 0; - sub(bits); - } - access(18, bits); - set_ea(cpu_data); - break; - case 0x20: /* MUL */ - case 0x28: /* IMUL */ - wait(1, 0); - mul(get_accum(bits), cpu_data); - if (opcode & 1) { - AX = cpu_data; - DX = cpu_dest; - set_co_mul(bits, DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); - cpu_data = DX; - } else { - AL = (uint8_t) cpu_data; - AH = (uint8_t) cpu_dest; - set_co_mul(bits, AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); - cpu_data = AH; - } - /* NOTE: When implementing the V20, care should be taken to not change - the zero flag. */ - set_sf(bits); - set_pf(); - if (cpu_mod != 3) - wait(1, 0); - break; - case 0x30: /* DIV */ - case 0x38: /* IDIV */ - if (cpu_mod != 3) - wait(1, 0); - cpu_src = cpu_data; - if (x86_div(AL, AH)) - wait(1, 0); - break; - } - break; + case 0xF6: + case 0xF7: + bits = 8 << (opcode & 1); + do_mod_rm(); + access(55, bits); + cpu_data = get_ea(); + switch (rmdat & 0x38) { + case 0x00: + case 0x08: + /* TEST */ + wait(2, 0); + if (cpu_mod != 3) + wait(1, 0); + cpu_src = pfq_fetch(); + wait(1, 0); + test(bits, cpu_data, cpu_src); + if (cpu_mod != 3) + wait(1, 0); + break; + case 0x10: /* NOT */ + case 0x18: /* NEG */ + wait(2, 0); + if ((rmdat & 0x38) == 0x10) + cpu_data = ~cpu_data; + else { + cpu_src = cpu_data; + cpu_dest = 0; + sub(bits); + } + access(18, bits); + set_ea(cpu_data); + break; + case 0x20: /* MUL */ + case 0x28: /* IMUL */ + wait(1, 0); + mul(get_accum(bits), cpu_data); + if (opcode & 1) { + AX = cpu_data; + DX = cpu_dest; + set_co_mul(bits, DX != ((AX & 0x8000) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + cpu_data = DX; + } else { + AL = (uint8_t) cpu_data; + AH = (uint8_t) cpu_dest; + set_co_mul(bits, AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + cpu_data = AH; + } + /* NOTE: When implementing the V20, care should be taken to not change + the zero flag. */ + set_sf(bits); + set_pf(); + if (cpu_mod != 3) + wait(1, 0); + break; + case 0x30: /* DIV */ + case 0x38: /* IDIV */ + if (cpu_mod != 3) + wait(1, 0); + cpu_src = cpu_data; + if (x86_div(AL, AH)) + wait(1, 0); + break; + } + break; - case 0xF8: case 0xF9: - /* CLCSTC */ - wait(1, 0); - set_cf(opcode & 1); - break; - case 0xFA: case 0xFB: - /* CLISTI */ - wait(1, 0); - set_if(opcode & 1); - break; - case 0xFC: case 0xFD: - /* CLDSTD */ - wait(1, 0); - set_df(opcode & 1); - break; + case 0xF8: + case 0xF9: + /* CLCSTC */ + wait(1, 0); + set_cf(opcode & 1); + break; + case 0xFA: + case 0xFB: + /* CLISTI */ + wait(1, 0); + set_if(opcode & 1); + break; + case 0xFC: + case 0xFD: + /* CLDSTD */ + wait(1, 0); + set_df(opcode & 1); + break; - case 0xFE: case 0xFF: - /* misc */ - bits = 8 << (opcode & 1); - do_mod_rm(); - access(56, bits); - read_ea(((rmdat & 0x38) == 0x18) || ((rmdat & 0x38) == 0x28), bits); - switch (rmdat & 0x38) { - case 0x00: /* INC rm */ - case 0x08: /* DEC rm */ - cpu_dest = cpu_data; - cpu_src = 1; - if ((rmdat & 0x38) == 0x00) { - cpu_data = cpu_dest + cpu_src; - set_of_add(bits); - } else { - cpu_data = cpu_dest - cpu_src; - set_of_sub(bits); - } - do_af(); - set_pzs(bits); - wait(2, 0); - access(19, bits); - set_ea(cpu_data); - break; - case 0x10: /* CALL rm */ - cpu_data_opff_rm(); - access(63, bits); - wait(1, 0); - pfq_clear(); - wait(4, 0); - if (cpu_mod != 3) - wait(1, 0); - wait(1, 0); /* Wait. */ - cpu_state.oldpc = cpu_state.pc; - set_ip(cpu_data); - wait(2, 0); - access(35, bits); - push((uint16_t *) &(cpu_state.oldpc)); - break; - case 0x18: /* CALL rmd */ - new_ip = cpu_data; - access(58, bits); - read_ea2(bits); - if (!(opcode & 1)) - cpu_data |= 0xff00; - new_cs = cpu_data; - access(36, bits); - push(&(CS)); - access(64, bits); - wait(4, 0); - cpu_state.oldpc = cpu_state.pc; - load_cs(new_cs); - set_ip(new_ip); - access(37, bits); - push((uint16_t *) &(cpu_state.oldpc)); - break; - case 0x20: /* JMP rm */ - cpu_data_opff_rm(); - access(65, bits); - set_ip(cpu_data); - break; - case 0x28: /* JMP rmd */ - new_ip = cpu_data; - access(59, bits); - read_ea2(bits); - if (!(opcode & 1)) - cpu_data |= 0xff00; - new_cs = cpu_data; - load_cs(new_cs); - access(66, bits); - set_ip(new_ip); - break; - case 0x30: /* PUSH rm */ - case 0x38: - if (cpu_mod != 3) - wait(1, 0); - access(38, bits); - push((uint16_t *) &(cpu_data)); - break; - } - break; + case 0xFE: + case 0xFF: + /* misc */ + bits = 8 << (opcode & 1); + do_mod_rm(); + access(56, bits); + read_ea(((rmdat & 0x38) == 0x18) || ((rmdat & 0x38) == 0x28), bits); + switch (rmdat & 0x38) { + case 0x00: /* INC rm */ + case 0x08: /* DEC rm */ + cpu_dest = cpu_data; + cpu_src = 1; + if ((rmdat & 0x38) == 0x00) { + cpu_data = cpu_dest + cpu_src; + set_of_add(bits); + } else { + cpu_data = cpu_dest - cpu_src; + set_of_sub(bits); + } + do_af(); + set_pzs(bits); + wait(2, 0); + access(19, bits); + set_ea(cpu_data); + break; + case 0x10: /* CALL rm */ + cpu_data_opff_rm(); + access(63, bits); + wait(1, 0); + pfq_clear(); + wait(4, 0); + if (cpu_mod != 3) + wait(1, 0); + wait(1, 0); /* Wait. */ + cpu_state.oldpc = cpu_state.pc; + set_ip(cpu_data); + wait(2, 0); + access(35, bits); + push((uint16_t *) &(cpu_state.oldpc)); + break; + case 0x18: /* CALL rmd */ + new_ip = cpu_data; + access(58, bits); + read_ea2(bits); + if (!(opcode & 1)) + cpu_data |= 0xff00; + new_cs = cpu_data; + access(36, bits); + push(&(CS)); + access(64, bits); + wait(4, 0); + cpu_state.oldpc = cpu_state.pc; + load_cs(new_cs); + set_ip(new_ip); + access(37, bits); + push((uint16_t *) &(cpu_state.oldpc)); + break; + case 0x20: /* JMP rm */ + cpu_data_opff_rm(); + access(65, bits); + set_ip(cpu_data); + break; + case 0x28: /* JMP rmd */ + new_ip = cpu_data; + access(59, bits); + read_ea2(bits); + if (!(opcode & 1)) + cpu_data |= 0xff00; + new_cs = cpu_data; + load_cs(new_cs); + access(66, bits); + set_ip(new_ip); + break; + case 0x30: /* PUSH rm */ + case 0x38: + if (cpu_mod != 3) + wait(1, 0); + access(38, bits); + push((uint16_t *) &(cpu_data)); + break; + } + break; - default: - x808x_log("Illegal opcode: %02X\n", opcode); - pfq_fetchb(); - wait(8, 0); - break; - } + default: + x808x_log("Illegal opcode: %02X\n", opcode); + pfq_fetchb(); + wait(8, 0); + break; + } - if (completed) { - repeating = 0; - ovr_seg = NULL; - in_rep = 0; - if (in_lock) - clear_lock = 1; - clock_end(); - check_interrupts(); + if (completed) { + repeating = 0; + ovr_seg = NULL; + in_rep = 0; + if (in_lock) + clear_lock = 1; + clock_end(); + check_interrupts(); - if (noint) - noint = 0; + if (noint) + noint = 0; - cpu_alu_op = 0; - } + cpu_alu_op = 0; + } #ifdef USE_GDBSTUB - if (gdbstub_instruction()) - return; + if (gdbstub_instruction()) + return; #endif } } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 7ff81607f..7a35e2589 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -38,7 +38,7 @@ #include <86box/pci.h> #include <86box/gdbstub.h> #ifdef USE_DYNAREC -# include "codegen.h" +# include "codegen.h" #endif #include "x87_timings.h" @@ -49,318 +49,302 @@ #define CCR3_SMI_LOCK (1 << 0) #define CCR3_NMI_EN (1 << 1) - enum { - CPUID_FPU = (1 << 0), - CPUID_VME = (1 << 1), - CPUID_PSE = (1 << 3), - CPUID_TSC = (1 << 4), - CPUID_MSR = (1 << 5), - CPUID_PAE = (1 << 6), - CPUID_MCE = (1 << 7), + CPUID_FPU = (1 << 0), + CPUID_VME = (1 << 1), + CPUID_PSE = (1 << 3), + CPUID_TSC = (1 << 4), + CPUID_MSR = (1 << 5), + CPUID_PAE = (1 << 6), + CPUID_MCE = (1 << 7), CPUID_CMPXCHG8B = (1 << 8), - CPUID_AMDSEP = (1 << 10), - CPUID_SEP = (1 << 11), - CPUID_MTRR = (1 << 12), - CPUID_MCA = (1 << 14), - CPUID_CMOV = (1 << 15), - CPUID_MMX = (1 << 23), - CPUID_FXSR = (1 << 24) + CPUID_AMDSEP = (1 << 10), + CPUID_SEP = (1 << 11), + CPUID_MTRR = (1 << 12), + CPUID_MCA = (1 << 14), + CPUID_CMOV = (1 << 15), + CPUID_MMX = (1 << 23), + CPUID_FXSR = (1 << 24) }; /*Addition flags returned by CPUID function 0x80000001*/ -#define CPUID_3DNOW (1UL << 31UL) - +#define CPUID_3DNOW (1UL << 31UL) /* Make sure this is as low as possible. */ -cpu_state_t cpu_state; +cpu_state_t cpu_state; #ifdef USE_DYNAREC -const OpFn *x86_dynarec_opcodes, *x86_dynarec_opcodes_0f, - *x86_dynarec_opcodes_d8_a16, *x86_dynarec_opcodes_d8_a32, - *x86_dynarec_opcodes_d9_a16, *x86_dynarec_opcodes_d9_a32, - *x86_dynarec_opcodes_da_a16, *x86_dynarec_opcodes_da_a32, - *x86_dynarec_opcodes_db_a16, *x86_dynarec_opcodes_db_a32, - *x86_dynarec_opcodes_dc_a16, *x86_dynarec_opcodes_dc_a32, - *x86_dynarec_opcodes_dd_a16, *x86_dynarec_opcodes_dd_a32, - *x86_dynarec_opcodes_de_a16, *x86_dynarec_opcodes_de_a32, - *x86_dynarec_opcodes_df_a16, *x86_dynarec_opcodes_df_a32, - *x86_dynarec_opcodes_REPE, *x86_dynarec_opcodes_REPNE, - *x86_dynarec_opcodes_3DNOW; +const OpFn *x86_dynarec_opcodes, *x86_dynarec_opcodes_0f, + *x86_dynarec_opcodes_d8_a16, *x86_dynarec_opcodes_d8_a32, + *x86_dynarec_opcodes_d9_a16, *x86_dynarec_opcodes_d9_a32, + *x86_dynarec_opcodes_da_a16, *x86_dynarec_opcodes_da_a32, + *x86_dynarec_opcodes_db_a16, *x86_dynarec_opcodes_db_a32, + *x86_dynarec_opcodes_dc_a16, *x86_dynarec_opcodes_dc_a32, + *x86_dynarec_opcodes_dd_a16, *x86_dynarec_opcodes_dd_a32, + *x86_dynarec_opcodes_de_a16, *x86_dynarec_opcodes_de_a32, + *x86_dynarec_opcodes_df_a16, *x86_dynarec_opcodes_df_a32, + *x86_dynarec_opcodes_REPE, *x86_dynarec_opcodes_REPNE, + *x86_dynarec_opcodes_3DNOW; #endif -const OpFn *x86_opcodes, *x86_opcodes_0f, - *x86_opcodes_d8_a16, *x86_opcodes_d8_a32, - *x86_opcodes_d9_a16, *x86_opcodes_d9_a32, - *x86_opcodes_da_a16, *x86_opcodes_da_a32, - *x86_opcodes_db_a16, *x86_opcodes_db_a32, - *x86_opcodes_dc_a16, *x86_opcodes_dc_a32, - *x86_opcodes_dd_a16, *x86_opcodes_dd_a32, - *x86_opcodes_de_a16, *x86_opcodes_de_a32, - *x86_opcodes_df_a16, *x86_opcodes_df_a32, - *x86_opcodes_REPE, *x86_opcodes_REPNE, - *x86_opcodes_3DNOW; +const OpFn *x86_opcodes, *x86_opcodes_0f, + *x86_opcodes_d8_a16, *x86_opcodes_d8_a32, + *x86_opcodes_d9_a16, *x86_opcodes_d9_a32, + *x86_opcodes_da_a16, *x86_opcodes_da_a32, + *x86_opcodes_db_a16, *x86_opcodes_db_a32, + *x86_opcodes_dc_a16, *x86_opcodes_dc_a32, + *x86_opcodes_dd_a16, *x86_opcodes_dd_a32, + *x86_opcodes_de_a16, *x86_opcodes_de_a32, + *x86_opcodes_df_a16, *x86_opcodes_df_a32, + *x86_opcodes_REPE, *x86_opcodes_REPNE, + *x86_opcodes_3DNOW; -uint16_t cpu_fast_off_count, cpu_fast_off_val; -uint16_t temp_seg_data[4] = {0, 0, 0, 0}; +uint16_t cpu_fast_off_count, cpu_fast_off_val; +uint16_t temp_seg_data[4] = { 0, 0, 0, 0 }; -int isa_cycles, cpu_inited, +int isa_cycles, cpu_inited, - cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l, - cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles, - cpu_waitstates, cpu_cache_int_enabled, cpu_cache_ext_enabled, - cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset, + cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l, + cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles, + cpu_waitstates, cpu_cache_int_enabled, cpu_cache_ext_enabled, + cpu_isa_speed, cpu_pci_speed, cpu_isa_pci_div, cpu_agp_speed, cpu_alt_reset, - cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_busspeed, - cpu_cyrix_alignment, CPUID, + cpu_override, cpu_effective, cpu_multi, cpu_16bitbus, cpu_64bitbus, cpu_busspeed, + cpu_cyrix_alignment, CPUID, - is286, is386, is6117, is486 = 1, - cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc, - is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm, hasfpu, + is286, is386, is6117, is486 = 1, + cpu_isintel, cpu_iscyrix, hascache, isibm486, israpidcad, is_vpc, + is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm, hasfpu, - timing_rr, timing_mr, timing_mrl, timing_rm, timing_rml, - timing_mm, timing_mml, timing_bt, timing_bnt, - timing_int, timing_int_rm, timing_int_v86, timing_int_pm, - timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm, - timing_iret_pm_outer, timing_call_rm, timing_call_pm, timing_call_pm_gate, - timing_call_pm_gate_inner, timing_retf_rm, timing_retf_pm, timing_retf_pm_outer, - timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned; -uint32_t cpu_features, cpu_fast_off_flags; + timing_rr, timing_mr, timing_mrl, timing_rm, timing_rml, + timing_mm, timing_mml, timing_bt, timing_bnt, + timing_int, timing_int_rm, timing_int_v86, timing_int_pm, + timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm, + timing_iret_pm_outer, timing_call_rm, timing_call_pm, timing_call_pm_gate, + timing_call_pm_gate_inner, timing_retf_rm, timing_retf_pm, timing_retf_pm_outer, + timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned; +uint32_t cpu_features, cpu_fast_off_flags; -uint32_t _tr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint32_t cache_index = 0; -uint8_t _cache[2048]; +uint32_t _tr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +uint32_t cache_index = 0; +uint8_t _cache[2048]; -uint64_t cpu_CR4_mask, tsc = 0; -uint64_t pmc[2] = {0, 0}; +uint64_t cpu_CR4_mask, tsc = 0; +uint64_t pmc[2] = { 0, 0 }; -double cpu_dmulti; +double cpu_dmulti; -msr_t msr; +msr_t msr; -cyrix_t cyrix; +cyrix_t cyrix; -cpu_family_t *cpu_f; -CPU *cpu_s; +cpu_family_t *cpu_f; +CPU *cpu_s; -uint8_t do_translate = 0, do_translate2 = 0; +uint8_t do_translate = 0, do_translate2 = 0; -void (*cpu_exec)(int cycs); +void (*cpu_exec)(int cycs); +static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; -static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; - -static int cyrix_addr; - - -static void cpu_write(uint16_t addr, uint8_t val, void *priv); -static uint8_t cpu_read(uint16_t addr, void *priv); +static int cyrix_addr; +static void cpu_write(uint16_t addr, uint8_t val, void *priv); +static uint8_t cpu_read(uint16_t addr, void *priv); #ifdef ENABLE_CPU_LOG int cpu_do_log = ENABLE_CPU_LOG; - void cpu_log(const char *fmt, ...) { va_list ap; if (cpu_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 cpu_log(fmt, ...) +# define cpu_log(fmt, ...) #endif - int cpu_has_feature(int feature) { return cpu_features & feature; } - void cpu_dynamic_switch(int new_cpu) { int c; if (cpu_effective == new_cpu) - return; + return; - c = cpu; + c = cpu; cpu = new_cpu; cpu_set(); pc_speed_changed(); cpu = c; } - void cpu_set_edx(void) { EDX = cpu_s->edx_reset; } - cpu_family_t * cpu_get_family(const char *internal_name) { int c = 0; while (cpu_families[c].package) { - if (!strcmp(internal_name, cpu_families[c].internal_name)) - return (cpu_family_t *) &cpu_families[c]; - c++; + if (!strcmp(internal_name, cpu_families[c].internal_name)) + return (cpu_family_t *) &cpu_families[c]; + c++; } return NULL; } - uint8_t cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine) { const machine_t *machine_s = &machines[machine]; - const CPU *cpu_s = &cpu_family->cpus[cpu]; - uint32_t packages, bus_speed; - uint8_t i; - double multi; + const CPU *cpu_s = &cpu_family->cpus[cpu]; + uint32_t packages, bus_speed; + uint8_t i; + double multi; /* Full override. */ if (cpu_override > 1) - return 1; + return 1; /* Add implicit CPU package compatibility. */ packages = machine_s->cpu.package; if (packages & CPU_PKG_SOCKET3) - packages |= CPU_PKG_SOCKET1; + packages |= CPU_PKG_SOCKET1; else if (packages & CPU_PKG_SLOT1) - packages |= CPU_PKG_SOCKET370; + packages |= CPU_PKG_SOCKET370; /* Package type. */ if (!(cpu_family->package & packages)) - return 0; + return 0; /* Partial override. */ if (cpu_override) - return 1; + return 1; /* Check CPU blocklist. */ if (machine_s->cpu.block) { - i = 0; + i = 0; - while (machine_s->cpu.block[i]) { - if (machine_s->cpu.block[i++] == cpu_s->cpu_type) - return 0; - } + while (machine_s->cpu.block[i]) { + if (machine_s->cpu.block[i++] == cpu_s->cpu_type) + return 0; + } } bus_speed = cpu_s->rspeed / cpu_s->multi; /* Minimum bus speed with ~0.84 MHz (for 8086) tolerance. */ if (machine_s->cpu.min_bus && (bus_speed < (machine_s->cpu.min_bus - 840907))) - return 0; + return 0; /* Maximum bus speed with ~0.84 MHz (for 8086) tolerance. */ if (machine_s->cpu.max_bus && (bus_speed > (machine_s->cpu.max_bus + 840907))) - return 0; + return 0; /* Minimum voltage with 0.1V tolerance. */ if (machine_s->cpu.min_voltage && (cpu_s->voltage < (machine_s->cpu.min_voltage - 100))) - return 0; + return 0; /* Maximum voltage with 0.1V tolerance. */ if (machine_s->cpu.max_voltage && (cpu_s->voltage > (machine_s->cpu.max_voltage + 100))) - return 0; + return 0; /* Account for CPUs which use a different internal multiplier than specified by jumpers. */ multi = cpu_s->multi; /* Don't care about multiplier compatibility on fixed multiplier CPUs. */ if (cpu_s->cpu_flags & CPU_FIXED_MULTIPLIER) - return 1; + return 1; else if (cpu_family->package & CPU_PKG_SOCKET5_7) { - if ((multi == 1.5) && (cpu_s->cpu_type == CPU_5K86) && (machine_s->cpu.min_multi > 1.5)) /* K5 5k86 */ - multi = 2.0; - else if (multi == 1.75) /* K5 5k86 */ - multi = 2.5; - else if (multi == 2.0) { - if (cpu_s->cpu_type == CPU_5K86) /* K5 5k86 */ - multi = 3.0; - /* K6-2+ / K6-3+ */ - else if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) - multi = 2.5; - else if (((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && - (machine_s->cpu.min_multi > 2.0)) /* WinChip (2) */ - multi = 2.5; - } - else if (multi == (7.0 / 3.0)) /* WinChip 2A - 2.33x */ - multi = 5.0; - else if (multi == (8.0 / 3.0)) /* WinChip 2A - 2.66x */ - multi = 5.5; - else if ((multi == 3.0) && (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ - multi = 1.5; - else if (multi == (10.0 / 3.0)) /* WinChip 2A - 3.33x */ - multi = 2.0; - else if (multi == 3.5) /* standard set by the Pentium MMX */ - multi = 1.5; - else if (multi == 4.0) { - /* WinChip (2) */ - if ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) { - if (machine_s->cpu.min_multi >= 1.5) - multi = 1.5; - else if (machine_s->cpu.min_multi >= 3.5) - multi = 3.5; - else if (machine_s->cpu.min_multi >= 4.5) - multi = 4.5; - } else if ((cpu_s->cpu_type == CPU_Cx6x86) || (cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ - multi = 3.0; - } else if ((multi == 5.0) && ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && - (machine_s->cpu.min_multi > 5.0)) /* WinChip (2) */ - multi = 5.5; - else if (multi == 6.0) /* K6-2(+) / K6-3(+) */ - multi = 2.0; + if ((multi == 1.5) && (cpu_s->cpu_type == CPU_5K86) && (machine_s->cpu.min_multi > 1.5)) /* K5 5k86 */ + multi = 2.0; + else if (multi == 1.75) /* K5 5k86 */ + multi = 2.5; + else if (multi == 2.0) { + if (cpu_s->cpu_type == CPU_5K86) /* K5 5k86 */ + multi = 3.0; + /* K6-2+ / K6-3+ */ + else if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) + multi = 2.5; + else if (((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && (machine_s->cpu.min_multi > 2.0)) /* WinChip (2) */ + multi = 2.5; + } else if (multi == (7.0 / 3.0)) /* WinChip 2A - 2.33x */ + multi = 5.0; + else if (multi == (8.0 / 3.0)) /* WinChip 2A - 2.66x */ + multi = 5.5; + else if ((multi == 3.0) && (cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ + multi = 1.5; + else if (multi == (10.0 / 3.0)) /* WinChip 2A - 3.33x */ + multi = 2.0; + else if (multi == 3.5) /* standard set by the Pentium MMX */ + multi = 1.5; + else if (multi == 4.0) { + /* WinChip (2) */ + if ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) { + if (machine_s->cpu.min_multi >= 1.5) + multi = 1.5; + else if (machine_s->cpu.min_multi >= 3.5) + multi = 3.5; + else if (machine_s->cpu.min_multi >= 4.5) + multi = 4.5; + } else if ((cpu_s->cpu_type == CPU_Cx6x86) || (cpu_s->cpu_type == CPU_Cx6x86L)) /* 6x86(L) */ + multi = 3.0; + } else if ((multi == 5.0) && ((cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2)) && (machine_s->cpu.min_multi > 5.0)) /* WinChip (2) */ + multi = 5.5; + else if (multi == 6.0) /* K6-2(+) / K6-3(+) */ + multi = 2.0; } /* Minimum multiplier, */ if (multi < machine_s->cpu.min_multi) - return 0; + return 0; /* Maximum multiplier. */ if (machine_s->cpu.max_multi && (multi > machine_s->cpu.max_multi)) - return 0; + return 0; return 1; } - uint8_t cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine) { int c = 0; while (cpu_family->cpus[c].cpu_type) { - if (cpu_is_eligible(cpu_family, c, machine)) - return 1; - c++; + if (cpu_is_eligible(cpu_family, c, machine)) + return 1; + c++; } return 0; } - void cpu_set(void) { cpu_inited = 1; cpu_effective = cpu; - cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; + cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; #ifdef USE_ACYCS acycs = 0; @@ -368,52 +352,46 @@ cpu_set(void) soft_reset_pci = 0; - cpu_alt_reset = 0; + cpu_alt_reset = 0; unmask_a20_in_smm = 0; - CPUID = cpu_s->cpuid_model; - is8086 = (cpu_s->cpu_type > CPU_8088); - is286 = (cpu_s->cpu_type >= CPU_286); - is386 = (cpu_s->cpu_type >= CPU_386SX); - israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); - isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || - (cpu_s->cpu_type == CPU_IBM486BL); - is486 = (cpu_s->cpu_type >= CPU_RAPIDCAD); - is_am486 = (cpu_s->cpu_type == CPU_ENH_Am486DX); - is_am486dxl = (cpu_s->cpu_type == CPU_Am486DXL); + CPUID = cpu_s->cpuid_model; + is8086 = (cpu_s->cpu_type > CPU_8088); + is286 = (cpu_s->cpu_type >= CPU_286); + is386 = (cpu_s->cpu_type >= CPU_386SX); + israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD); + isibm486 = (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); + is486 = (cpu_s->cpu_type >= CPU_RAPIDCAD); + is_am486 = (cpu_s->cpu_type == CPU_ENH_Am486DX); + is_am486dxl = (cpu_s->cpu_type == CPU_Am486DXL); - is6117 = !strcmp(cpu_f->manufacturer, "ALi"); + is6117 = !strcmp(cpu_f->manufacturer, "ALi"); - cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); - cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST"); + cpu_isintel = !strcmp(cpu_f->manufacturer, "Intel"); + cpu_iscyrix = !strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST"); /* SL-Enhanced Intel 486s have the same SMM save state table layout as Pentiums, and the WinChip datasheet claims those are Pentium-compatible as well. AMD Am486DXL/DXL2 also has compatible SMM, or would if not for it's different SMBase*/ - is_pentium = (cpu_isintel && (cpu_s->cpu_type >= CPU_i486SX_SLENH) && (cpu_s->cpu_type < CPU_PENTIUMPRO)) || - !strcmp(cpu_f->manufacturer, "IDT") || (cpu_s->cpu_type == CPU_Am486DXL); - is_k5 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type > CPU_ENH_Am486DX) && (cpu_s->cpu_type < CPU_K6); - is_k6 = (cpu_s->cpu_type >= CPU_K6) && !strcmp(cpu_f->manufacturer, "AMD"); + is_pentium = (cpu_isintel && (cpu_s->cpu_type >= CPU_i486SX_SLENH) && (cpu_s->cpu_type < CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "IDT") || (cpu_s->cpu_type == CPU_Am486DXL); + is_k5 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type > CPU_ENH_Am486DX) && (cpu_s->cpu_type < CPU_K6); + is_k6 = (cpu_s->cpu_type >= CPU_K6) && !strcmp(cpu_f->manufacturer, "AMD"); /* The Samuel 2 datasheet claims it's Celeron-compatible. */ - is_p6 = (cpu_isintel && (cpu_s->cpu_type >= CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "VIA"); - is_cxsmm = (!strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST")) && - (cpu_s->cpu_type >= CPU_Cx486S); + is_p6 = (cpu_isintel && (cpu_s->cpu_type >= CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "VIA"); + is_cxsmm = (!strcmp(cpu_f->manufacturer, "Cyrix") || !strcmp(cpu_f->manufacturer, "ST")) && (cpu_s->cpu_type >= CPU_Cx486S); - cpu_isintel = cpu_isintel || !strcmp(cpu_f->manufacturer, "AMD"); + cpu_isintel = cpu_isintel || !strcmp(cpu_f->manufacturer, "AMD"); - hasfpu = (fpu_type != FPU_NONE); - hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || - (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); + hasfpu = (fpu_type != FPU_NONE); + hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL); - cpu_16bitbus = (cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || - (cpu_s->cpu_type == CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || - (cpu_s->cpu_type == CPU_IBM486SLC); + cpu_16bitbus = (cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || (cpu_s->cpu_type == CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC) || (cpu_s->cpu_type == CPU_IBM486SLC); cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP); if (cpu_s->multi) - cpu_busspeed = cpu_s->rspeed / cpu_s->multi; + cpu_busspeed = cpu_s->rspeed / cpu_s->multi; else - cpu_busspeed = cpu_s->rspeed; - cpu_multi = (int) ceil(cpu_s->multi); + cpu_busspeed = cpu_s->rspeed; + cpu_multi = (int) ceil(cpu_s->multi); cpu_dmulti = cpu_s->multi; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; @@ -422,9 +400,9 @@ cpu_set(void) isa_cycles = cpu_s->atclk_div; if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; else - cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; + cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; cpu_set_isa_pci_div(0); cpu_set_pci_speed(0); @@ -440,85 +418,85 @@ cpu_set(void) #else x86_setopcodes(ops_386, ops_386_0f); #endif - x86_opcodes_REPE = ops_REPE; + x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; x86_opcodes_3DNOW = ops_3DNOW; #ifdef USE_DYNAREC - x86_dynarec_opcodes_REPE = dynarec_ops_REPE; + x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; #endif if (hasfpu) { #ifdef USE_DYNAREC - x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; + x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16; + x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; #endif - x86_opcodes_d8_a16 = ops_fpu_d8_a16; - x86_opcodes_d8_a32 = ops_fpu_d8_a32; - x86_opcodes_d9_a16 = ops_fpu_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_d9_a32; - x86_opcodes_da_a16 = ops_fpu_da_a16; - x86_opcodes_da_a32 = ops_fpu_da_a32; - x86_opcodes_db_a16 = ops_fpu_db_a16; - x86_opcodes_db_a32 = ops_fpu_db_a32; - x86_opcodes_dc_a16 = ops_fpu_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_dd_a32; - x86_opcodes_de_a16 = ops_fpu_de_a16; - x86_opcodes_de_a32 = ops_fpu_de_a32; - x86_opcodes_df_a16 = ops_fpu_df_a16; - x86_opcodes_df_a32 = ops_fpu_df_a32; + x86_opcodes_d8_a16 = ops_fpu_d8_a16; + x86_opcodes_d8_a32 = ops_fpu_d8_a32; + x86_opcodes_d9_a16 = ops_fpu_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_d9_a32; + x86_opcodes_da_a16 = ops_fpu_da_a16; + x86_opcodes_da_a32 = ops_fpu_da_a32; + x86_opcodes_db_a16 = ops_fpu_db_a16; + x86_opcodes_db_a32 = ops_fpu_db_a32; + x86_opcodes_dc_a16 = ops_fpu_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_dd_a32; + x86_opcodes_de_a16 = ops_fpu_de_a16; + x86_opcodes_de_a32 = ops_fpu_de_a32; + x86_opcodes_df_a16 = ops_fpu_df_a16; + x86_opcodes_df_a32 = ops_fpu_df_a32; } else { #ifdef USE_DYNAREC - x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_d8_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; #endif - x86_opcodes_d8_a16 = ops_nofpu_a16; - x86_opcodes_d8_a32 = ops_nofpu_a32; - x86_opcodes_d9_a16 = ops_nofpu_a16; - x86_opcodes_d9_a32 = ops_nofpu_a32; - x86_opcodes_da_a16 = ops_nofpu_a16; - x86_opcodes_da_a32 = ops_nofpu_a32; - x86_opcodes_db_a16 = ops_nofpu_a16; - x86_opcodes_db_a32 = ops_nofpu_a32; - x86_opcodes_dc_a16 = ops_nofpu_a16; - x86_opcodes_dc_a32 = ops_nofpu_a32; - x86_opcodes_dd_a16 = ops_nofpu_a16; - x86_opcodes_dd_a32 = ops_nofpu_a32; - x86_opcodes_de_a16 = ops_nofpu_a16; - x86_opcodes_de_a32 = ops_nofpu_a32; - x86_opcodes_df_a16 = ops_nofpu_a16; - x86_opcodes_df_a32 = ops_nofpu_a32; + x86_opcodes_d8_a16 = ops_nofpu_a16; + x86_opcodes_d8_a32 = ops_nofpu_a32; + x86_opcodes_d9_a16 = ops_nofpu_a16; + x86_opcodes_d9_a32 = ops_nofpu_a32; + x86_opcodes_da_a16 = ops_nofpu_a16; + x86_opcodes_da_a32 = ops_nofpu_a32; + x86_opcodes_db_a16 = ops_nofpu_a16; + x86_opcodes_db_a32 = ops_nofpu_a32; + x86_opcodes_dc_a16 = ops_nofpu_a16; + x86_opcodes_dc_a32 = ops_nofpu_a32; + x86_opcodes_dd_a16 = ops_nofpu_a16; + x86_opcodes_dd_a32 = ops_nofpu_a32; + x86_opcodes_de_a16 = ops_nofpu_a16; + x86_opcodes_de_a32 = ops_nofpu_a32; + x86_opcodes_df_a16 = ops_nofpu_a16; + x86_opcodes_df_a32 = ops_nofpu_a32; } #ifdef USE_DYNAREC @@ -527,919 +505,915 @@ cpu_set(void) memset(&msr, 0, sizeof(msr)); - timing_misaligned = 0; + timing_misaligned = 0; cpu_cyrix_alignment = 0; - cpu_CR4_mask = 0; + cpu_CR4_mask = 0; switch (cpu_s->cpu_type) { - case CPU_8088: - case CPU_8086: - break; + case CPU_8088: + case CPU_8086: + break; - case CPU_286: + case CPU_286: #ifdef USE_DYNAREC - x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); + x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); #else - x86_setopcodes(ops_286, ops_286_0f); + x86_setopcodes(ops_286, ops_286_0f); #endif - if (fpu_type == FPU_287) { + if (fpu_type == FPU_287) { #ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; #endif - x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; - x86_opcodes_da_a16 = ops_fpu_287_da_a16; - x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; - x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; - x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; - x86_opcodes_df_a32 = ops_fpu_287_df_a32; - } + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a32 = ops_fpu_287_de_a32; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a32 = ops_fpu_287_df_a32; + } - timing_rr = 2; /* register dest - register src */ - timing_rm = 7; /* register dest - memory src */ - timing_mr = 7; /* memory dest - register src */ - timing_mm = 7; /* memory dest - memory src */ - timing_rml = 9; /* register dest - memory src long */ - timing_mrl = 11; /* memory dest - register src long */ - timing_mml = 11; /* memory dest - memory src */ - timing_bt = 4; /* branch taken */ - timing_bnt = 3; /* branch not taken */ + timing_rr = 2; /* register dest - register src */ + timing_rm = 7; /* register dest - memory src */ + timing_mr = 7; /* memory dest - register src */ + timing_mm = 7; /* memory dest - memory src */ + timing_rml = 9; /* register dest - memory src long */ + timing_mrl = 11; /* memory dest - register src long */ + timing_mml = 11; /* memory dest - memory src */ + timing_bt = 4; /* branch taken */ + timing_bnt = 3; /* branch not taken */ - timing_int = 0; - timing_int_rm = 23; - timing_int_v86 = 0; - timing_int_pm = 40; - timing_int_pm_outer = 78; - timing_iret_rm = 17; - timing_iret_v86 = 0; - timing_iret_pm = 31; - timing_iret_pm_outer = 55; - timing_call_rm = 13; - timing_call_pm = 26; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 82; - timing_retf_rm = 15; - timing_retf_pm = 25; - timing_retf_pm_outer = 55; - timing_jmp_rm = 11; - timing_jmp_pm = 23; - timing_jmp_pm_gate = 38; - break; + timing_int = 0; + timing_int_rm = 23; + timing_int_v86 = 0; + timing_int_pm = 40; + timing_int_pm_outer = 78; + timing_iret_rm = 17; + timing_iret_v86 = 0; + timing_iret_pm = 31; + timing_iret_pm_outer = 55; + timing_call_rm = 13; + timing_call_pm = 26; + timing_call_pm_gate = 52; + timing_call_pm_gate_inner = 82; + timing_retf_rm = 15; + timing_retf_pm = 25; + timing_retf_pm_outer = 55; + timing_jmp_rm = 11; + timing_jmp_pm = 23; + timing_jmp_pm_gate = 38; + break; - case CPU_IBM486SLC: - case CPU_IBM386SLC: - case CPU_IBM486BL: + case CPU_IBM486SLC: + case CPU_IBM386SLC: + case CPU_IBM486BL: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); #else - x86_setopcodes(ops_386, ops_ibm486_0f); + x86_setopcodes(ops_386, ops_ibm486_0f); #endif - cpu_features = CPU_FEATURE_MSR; - /* FALLTHROUGH */ - case CPU_386SX: - case CPU_386DX: - if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */ + cpu_features = CPU_FEATURE_MSR; + /* FALLTHROUGH */ + case CPU_386SX: + case CPU_386DX: + if (fpu_type == FPU_287) { /* In case we get Deskpro 386 emulation */ #ifdef USE_DYNAREC - x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; - x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; - x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; - x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; - x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; - x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; - x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; - x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; #endif - x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; - x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; - x86_opcodes_da_a16 = ops_fpu_287_da_a16; - x86_opcodes_da_a32 = ops_fpu_287_da_a32; - x86_opcodes_db_a16 = ops_fpu_287_db_a16; - x86_opcodes_db_a32 = ops_fpu_287_db_a32; - x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; - x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; - x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; - x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; - x86_opcodes_de_a16 = ops_fpu_287_de_a16; - x86_opcodes_de_a32 = ops_fpu_287_de_a32; - x86_opcodes_df_a16 = ops_fpu_287_df_a16; - x86_opcodes_df_a32 = ops_fpu_287_df_a32; - } + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a32 = ops_fpu_287_de_a32; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a32 = ops_fpu_287_df_a32; + } - timing_rr = 2; /* register dest - register src */ - timing_rm = 6; /* register dest - memory src */ - timing_mr = 7; /* memory dest - register src */ - timing_mm = 6; /* memory dest - memory src */ - if (cpu_s->cpu_type >= CPU_386DX) { - timing_rml = 6; /* register dest - memory src long */ - timing_mrl = 7; /* memory dest - register src long */ - timing_mml = 6; /* memory dest - memory src */ - } else { - timing_rml = 8; /* register dest - memory src long */ - timing_mrl = 11; /* memory dest - register src long */ - timing_mml = 10; /* memory dest - memory src */ - } - timing_bt = 4; /* branch taken */ - timing_bnt = 3; /* branch not taken */ + timing_rr = 2; /* register dest - register src */ + timing_rm = 6; /* register dest - memory src */ + timing_mr = 7; /* memory dest - register src */ + timing_mm = 6; /* memory dest - memory src */ + if (cpu_s->cpu_type >= CPU_386DX) { + timing_rml = 6; /* register dest - memory src long */ + timing_mrl = 7; /* memory dest - register src long */ + timing_mml = 6; /* memory dest - memory src */ + } else { + timing_rml = 8; /* register dest - memory src long */ + timing_mrl = 11; /* memory dest - register src long */ + timing_mml = 10; /* memory dest - memory src */ + } + timing_bt = 4; /* branch taken */ + timing_bnt = 3; /* branch not taken */ - timing_int = 0; - timing_int_rm = 37; - timing_int_v86 = 59; - timing_int_pm = 99; - timing_int_pm_outer = 119; - timing_iret_rm = 22; - timing_iret_v86 = 60; - timing_iret_pm = 38; - timing_iret_pm_outer = 82; - timing_call_rm = 17; - timing_call_pm = 34; - timing_call_pm_gate = 52; - timing_call_pm_gate_inner = 86; - timing_retf_rm = 18; - timing_retf_pm = 32; - timing_retf_pm_outer = 68; - timing_jmp_rm = 12; - timing_jmp_pm = 27; - timing_jmp_pm_gate = 45; - break; + timing_int = 0; + timing_int_rm = 37; + timing_int_v86 = 59; + timing_int_pm = 99; + timing_int_pm_outer = 119; + timing_iret_rm = 22; + timing_iret_v86 = 60; + timing_iret_pm = 38; + timing_iret_pm_outer = 82; + timing_call_rm = 17; + timing_call_pm = 34; + timing_call_pm_gate = 52; + timing_call_pm_gate_inner = 86; + timing_retf_rm = 18; + timing_retf_pm = 32; + timing_retf_pm_outer = 68; + timing_jmp_rm = 12; + timing_jmp_pm = 27; + timing_jmp_pm_gate = 45; + break; - case CPU_486SLC: + case CPU_486SLC: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 3; /* register dest - memory src */ - timing_mr = 5; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 5; /* register dest - memory src long */ - timing_mrl = 7; /* memory dest - register src long */ - timing_mml = 7; - timing_bt = 5; /* branch taken */ - timing_bnt = 1; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 5; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 5; /* register dest - memory src long */ + timing_mrl = 7; /* memory dest - register src long */ + timing_mml = 7; + timing_bt = 5; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - timing_int = 4; /* unknown */ - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; + timing_int = 4; /* unknown */ + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; + timing_misaligned = 3; + break; - case CPU_486DLC: + case CPU_486DLC: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 3; /* register dest - memory src */ - timing_mr = 3; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 3; /* register dest - memory src long */ - timing_mrl = 3; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 5; /* branch taken */ - timing_bnt = 1; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 3; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 5; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - timing_int = 4; /* unknown */ - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; + timing_int = 4; /* unknown */ + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; - timing_misaligned = 3; - break; + timing_misaligned = 3; + break; - case CPU_i486SX_SLENH: - case CPU_i486DX_SLENH: - cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; - /* FALLTHROUGH */ - case CPU_RAPIDCAD: - case CPU_i486SX: - case CPU_i486DX: - case CPU_Am486SX: - case CPU_Am486DX: - case CPU_Am486DXL: - case CPU_ENH_Am486DX: - /*AMD timing identical to Intel*/ + case CPU_i486SX_SLENH: + case CPU_i486DX_SLENH: + cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; + /* FALLTHROUGH */ + case CPU_RAPIDCAD: + case CPU_i486SX: + case CPU_i486DX: + case CPU_Am486SX: + case CPU_Am486DX: + case CPU_Am486DXL: + case CPU_ENH_Am486DX: + /*AMD timing identical to Intel*/ #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else - x86_setopcodes(ops_386, ops_486_0f); + x86_setopcodes(ops_386, ops_486_0f); #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 2; /* register dest - memory src */ - timing_mr = 3; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 2; /* register dest - memory src long */ - timing_mrl = 3; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 2; /* branch taken */ - timing_bnt = 1; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - timing_int = 4; - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 15; - timing_iret_v86 = 36; /* unknown */ - timing_iret_pm = 20; - timing_iret_pm_outer = 36; - timing_call_rm = 18; - timing_call_pm = 20; - timing_call_pm_gate = 35; - timing_call_pm_gate_inner = 69; - timing_retf_rm = 13; - timing_retf_pm = 17; - timing_retf_pm_outer = 35; - timing_jmp_rm = 17; - timing_jmp_pm = 19; - timing_jmp_pm_gate = 32; + timing_int = 4; + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 15; + timing_iret_v86 = 36; /* unknown */ + timing_iret_pm = 20; + timing_iret_pm_outer = 36; + timing_call_rm = 18; + timing_call_pm = 20; + timing_call_pm_gate = 35; + timing_call_pm_gate_inner = 69; + timing_retf_rm = 13; + timing_retf_pm = 17; + timing_retf_pm_outer = 35; + timing_jmp_rm = 17; + timing_jmp_pm = 19; + timing_jmp_pm_gate = 32; - timing_misaligned = 3; - break; + timing_misaligned = 3; + break; - case CPU_Cx486S: - case CPU_Cx486DX: - case CPU_STPC: + case CPU_Cx486S: + case CPU_Cx486DX: + case CPU_STPC: #ifdef USE_DYNAREC - if (cpu_s->cpu_type == CPU_STPC) - x86_setopcodes(ops_386, ops_stpc_0f, dynarec_ops_386, dynarec_ops_stpc_0f); - else - x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f); + if (cpu_s->cpu_type == CPU_STPC) + x86_setopcodes(ops_386, ops_stpc_0f, dynarec_ops_386, dynarec_ops_stpc_0f); + else + x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f); #else - if (cpu_s->cpu_type == CPU_STPC) - x86_setopcodes(ops_386, ops_stpc_0f); - else - x86_setopcodes(ops_386, ops_c486_0f); + if (cpu_s->cpu_type == CPU_STPC) + x86_setopcodes(ops_386, ops_stpc_0f); + else + x86_setopcodes(ops_386, ops_c486_0f); #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 3; /* register dest - memory src */ - timing_mr = 3; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 3; /* register dest - memory src long */ - timing_mrl = 3; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 3; /* branch taken */ - timing_bnt = 1; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 3; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 3; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 3; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - timing_int = 4; - timing_int_rm = 14; - timing_int_v86 = 82; - timing_int_pm = 49; - timing_int_pm_outer = 77; - timing_iret_rm = 14; - timing_iret_v86 = 66; /* unknown */ - timing_iret_pm = 31; - timing_iret_pm_outer = 66; - timing_call_rm = 12; - timing_call_pm = 30; - timing_call_pm_gate = 41; - timing_call_pm_gate_inner = 83; - timing_retf_rm = 13; - timing_retf_pm = 26; - timing_retf_pm_outer = 61; - timing_jmp_rm = 9; - timing_jmp_pm = 26; - timing_jmp_pm_gate = 37; + timing_int = 4; + timing_int_rm = 14; + timing_int_v86 = 82; + timing_int_pm = 49; + timing_int_pm_outer = 77; + timing_iret_rm = 14; + timing_iret_v86 = 66; /* unknown */ + timing_iret_pm = 31; + timing_iret_pm_outer = 66; + timing_call_rm = 12; + timing_call_pm = 30; + timing_call_pm_gate = 41; + timing_call_pm_gate_inner = 83; + timing_retf_rm = 13; + timing_retf_pm = 26; + timing_retf_pm_outer = 61; + timing_jmp_rm = 9; + timing_jmp_pm = 26; + timing_jmp_pm_gate = 37; - timing_misaligned = 3; + timing_misaligned = 3; - if (cpu_s->cpu_type == CPU_STPC) - cpu_features = CPU_FEATURE_RDTSC; - break; + if (cpu_s->cpu_type == CPU_STPC) + cpu_features = CPU_FEATURE_RDTSC; + break; - case CPU_Cx5x86: + case CPU_Cx5x86: #ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f); + x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f); #else - x86_setopcodes(ops_386, ops_c486_0f); + x86_setopcodes(ops_386, ops_c486_0f); #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 1; /* register dest - memory src */ - timing_mr = 2; /* memory dest - register src */ - timing_mm = 2; - timing_rml = 1; /* register dest - memory src long */ - timing_mrl = 2; /* memory dest - register src long */ - timing_mml = 2; - timing_bt = 4; /* branch taken */ - timing_bnt = 1; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 1; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 2; + timing_rml = 1; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 2; + timing_bt = 4; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - timing_int = 0; - timing_int_rm = 9; - timing_int_v86 = 82; /* unknown */ - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; /* unknown */ - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; + timing_int = 0; + timing_int_rm = 9; + timing_int_v86 = 82; /* unknown */ + timing_int_pm = 21; + timing_int_pm_outer = 32; + timing_iret_rm = 7; + timing_iret_v86 = 26; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; - timing_misaligned = 2; + timing_misaligned = 2; - cpu_cyrix_alignment = 1; - break; + cpu_cyrix_alignment = 1; + break; - case CPU_WINCHIP: - case CPU_WINCHIP2: + case CPU_WINCHIP: + case CPU_WINCHIP2: #ifdef USE_DYNAREC - if (cpu_s->cpu_type == CPU_WINCHIP2) - x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); - else - x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); + if (cpu_s->cpu_type == CPU_WINCHIP2) + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + else + x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); #else - if (cpu_s->cpu_type == CPU_WINCHIP2) - x86_setopcodes(ops_386, ops_winchip2_0f); - else - x86_setopcodes(ops_386, ops_winchip_0f); + if (cpu_s->cpu_type == CPU_WINCHIP2) + x86_setopcodes(ops_386, ops_winchip2_0f); + else + x86_setopcodes(ops_386, ops_winchip_0f); #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 2; /* register dest - memory src */ - timing_mr = 2; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 2; /* register dest - memory src long */ - timing_mrl = 2; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 2; /* branch taken */ - timing_bnt = 1; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; - timing_misaligned = 2; + timing_misaligned = 2; - cpu_cyrix_alignment = 1; + cpu_cyrix_alignment = 1; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; - if (cpu_s->cpu_type == CPU_WINCHIP2) - cpu_features |= CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - if (cpu_s->cpu_type == CPU_WINCHIP2) - msr.fcr |= (1 << 18) | (1 << 20); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; + if (cpu_s->cpu_type == CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + if (cpu_s->cpu_type == CPU_WINCHIP2) + msr.fcr |= (1 << 18) | (1 << 20); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC - if (cpu_s->cpu_type == CPU_WINCHIP2) - codegen_timing_set(&codegen_timing_winchip2); - else - codegen_timing_set(&codegen_timing_winchip); + if (cpu_s->cpu_type == CPU_WINCHIP2) + codegen_timing_set(&codegen_timing_winchip2); + else + codegen_timing_set(&codegen_timing_winchip); #endif - break; + break; - case CPU_P24T: - case CPU_PENTIUM: - case CPU_PENTIUMMMX: + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: #ifdef USE_DYNAREC - if (cpu_s->cpu_type == CPU_PENTIUMMMX) - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); - else - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); + else + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); #else - if (cpu_s->cpu_type == CPU_PENTIUMMMX) - x86_setopcodes(ops_386, ops_pentiummmx_0f); - else - x86_setopcodes(ops_386, ops_pentium_0f); + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + x86_setopcodes(ops_386, ops_pentiummmx_0f); + else + x86_setopcodes(ops_386, ops_pentium_0f); #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 2; /* register dest - memory src */ - timing_mr = 3; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 2; /* register dest - memory src long */ - timing_mrl = 3; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 0; /* branch taken */ - if (cpu_s->cpu_type == CPU_PENTIUMMMX) - timing_bnt = 1; /* branch not taken */ - else - timing_bnt = 2; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + timing_bnt = 1; /* branch not taken */ + else + timing_bnt = 2; /* branch not taken */ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /* unknown */ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; - timing_misaligned = 3; + timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; - if (cpu_s->cpu_type == CPU_PENTIUMMMX) - cpu_features |= CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; + if (cpu_s->cpu_type == CPU_PENTIUMMMX) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_pentium); + codegen_timing_set(&codegen_timing_pentium); #endif - break; + break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - if (cpu_s->cpu_type == CPU_Cx6x86MX) { -#ifdef USE_DYNAREC - x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; - x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; - x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; - x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; - x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; - x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; -#endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - } - -#ifdef USE_DYNAREC - if (cpu_s->cpu_type == CPU_Cx6x86MX) - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); - else if (cpu_s->cpu_type == CPU_Cx6x86L) - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); - else - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); - // x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); -#else - if (cpu_s->cpu_type == CPU_Cx6x86MX) - x86_setopcodes(ops_386, ops_c6x86mx_0f); - else if (cpu_s->cpu_type == CPU_Cx6x86L) - x86_setopcodes(ops_386, ops_pentium_0f); - else - x86_setopcodes(ops_386, ops_c6x86_0f); -#endif - - timing_rr = 1; /* register dest - register src */ - timing_rm = 1; /* register dest - memory src */ - timing_mr = 2; /* memory dest - register src */ - timing_mm = 2; - timing_rml = 1; /* register dest - memory src long */ - timing_mrl = 2; /* memory dest - register src long */ - timing_mml = 2; - if (cpu_s->cpu_type == CPU_CxGX1) { - timing_bt = 4; /* branch taken */ - timing_bnt = 1; /* branch not taken */ - } else { - timing_bt = 0; /* branch taken */ - timing_bnt = 2; /* branch not taken */ - } - - /* Make the CxGX1 share the timings with most other Cyrix C6x86's due to the real - ones still being unknown. */ - timing_int_rm = 9; - timing_int_v86 = 46; - timing_int_pm = 21; - timing_int_pm_outer = 32; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 3; - timing_call_pm = 4; - timing_call_pm_gate = 15; - timing_call_pm_gate_inner = 26; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 1; - timing_jmp_pm = 4; - timing_jmp_pm_gate = 14; - - timing_misaligned = 2; - - cpu_cyrix_alignment = 1; - - cpu_features = CPU_FEATURE_RDTSC; - if (cpu_s->cpu_type >= CPU_CxGX1) - cpu_features |= CPU_FEATURE_MSR | CPU_FEATURE_CR4; - if (cpu_s->cpu_type == CPU_Cx6x86MX) - cpu_features |= CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - if (cpu_s->cpu_type >= CPU_CxGX1) - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; - -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_686); -#endif - - if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX)) - ccr4 = 0x80; - else if (CPU_Cx6x86) - CPUID = 0; /* Disabled on powerup by default */ - break; -#endif - -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: -#endif - case CPU_K6: - case CPU_K6_2: - case CPU_K6_2C: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P: -#ifdef USE_DYNAREC - if (cpu_s->cpu_type >= CPU_K6_2) - x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - else if (cpu_s->cpu_type == CPU_K6) - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); - else - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); -#else - else - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); -#endif -#else - if (cpu_s->cpu_type >= CPU_K6_2) - x86_setopcodes(ops_386, ops_k62_0f); -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - else if (cpu_s->cpu_type = CPU_K6) - x86_setopcodes(ops_386, ops_k6_0f); - else - x86_setopcodes(ops_386, ops_pentiummmx_0f); -#else - else - x86_setopcodes(ops_386, ops_k6_0f); -#endif -#endif - - timing_rr = 1; /* register dest - register src */ - timing_rm = 2; /* register dest - memory src */ - timing_mr = 3; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 2; /* register dest - memory src long */ - timing_mrl = 3; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 0; /* branch taken */ - timing_bnt = 1; /* branch not taken */ - - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /* unknown */ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - - timing_misaligned = 3; - - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - if (cpu_s->cpu_type >= CPU_K6_2) - cpu_features |= CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE; - if (cpu_s->cpu_type >= CPU_K6) { - cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); - if (cpu_s->cpu_type <= CPU_K6) - cpu_CR4_mask |= CR4_PCE; - } -#else - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; - if (cpu_s->cpu_type == CPU_K6) - cpu_CR4_mask |= CR4_PCE; -#endif - -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_k6); -#endif - break; - - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: -#ifdef USE_DYNAREC - /* TODO: Perhaps merge the three opcode tables with some instructions UD#'ing depending on - CPU type. */ - if (cpu_s->cpu_type == CPU_PENTIUM2D) - x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); - else if (cpu_s->cpu_type == CPU_PENTIUM2) - x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); - else - x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + if (cpu_s->cpu_type == CPU_Cx6x86MX) { +# ifdef USE_DYNAREC x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; +# endif + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + } + +# ifdef USE_DYNAREC + if (cpu_s->cpu_type == CPU_Cx6x86MX) + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + else if (cpu_s->cpu_type == CPU_Cx6x86L) + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + else + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + // x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); +# else + if (cpu_s->cpu_type == CPU_Cx6x86MX) + x86_setopcodes(ops_386, ops_c6x86mx_0f); + else if (cpu_s->cpu_type == CPU_Cx6x86L) + x86_setopcodes(ops_386, ops_pentium_0f); + else + x86_setopcodes(ops_386, ops_c6x86_0f); +# endif + + timing_rr = 1; /* register dest - register src */ + timing_rm = 1; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 2; + timing_rml = 1; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 2; + if (cpu_s->cpu_type == CPU_CxGX1) { + timing_bt = 4; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + } else { + timing_bt = 0; /* branch taken */ + timing_bnt = 2; /* branch not taken */ + } + + /* Make the CxGX1 share the timings with most other Cyrix C6x86's due to the real + ones still being unknown. */ + timing_int_rm = 9; + timing_int_v86 = 46; + timing_int_pm = 21; + timing_int_pm_outer = 32; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 3; + timing_call_pm = 4; + timing_call_pm_gate = 15; + timing_call_pm_gate_inner = 26; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 1; + timing_jmp_pm = 4; + timing_jmp_pm_gate = 14; + + timing_misaligned = 2; + + cpu_cyrix_alignment = 1; + + cpu_features = CPU_FEATURE_RDTSC; + if (cpu_s->cpu_type >= CPU_CxGX1) + cpu_features |= CPU_FEATURE_MSR | CPU_FEATURE_CR4; + if (cpu_s->cpu_type == CPU_Cx6x86MX) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + if (cpu_s->cpu_type >= CPU_CxGX1) + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; + +# ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_686); +# endif + + if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX)) + ccr4 = 0x80; + else if (CPU_Cx6x86) + CPUID = 0; /* Disabled on powerup by default */ + break; +#endif + +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + case CPU_K5: + case CPU_5K86: +#endif + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: +#ifdef USE_DYNAREC + if (cpu_s->cpu_type >= CPU_K6_2) + x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); +# if defined(DEV_BRANCH) && defined(USE_AMD_K5) + else if (cpu_s->cpu_type == CPU_K6) + x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); + else + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); +# else + else + x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); +# endif #else - if (cpu_s->cpu_type == CPU_PENTIUM2D) - x86_setopcodes(ops_386, ops_pentium2d_0f); - else - x86_setopcodes(ops_386, ops_pentium2_0f); + if (cpu_s->cpu_type >= CPU_K6_2) + x86_setopcodes(ops_386, ops_k62_0f); +# if defined(DEV_BRANCH) && defined(USE_AMD_K5) + else if (cpu_s->cpu_type = CPU_K6) + x86_setopcodes(ops_386, ops_k6_0f); + else + x86_setopcodes(ops_386, ops_pentiummmx_0f); +# else + else + x86_setopcodes(ops_386, ops_k6_0f); +# endif #endif - x86_opcodes_da_a16 = ops_fpu_686_da_a16; - x86_opcodes_da_a32 = ops_fpu_686_da_a32; - x86_opcodes_db_a16 = ops_fpu_686_db_a16; - x86_opcodes_db_a32 = ops_fpu_686_db_a32; - x86_opcodes_df_a16 = ops_fpu_686_df_a16; - x86_opcodes_df_a32 = ops_fpu_686_df_a32; - timing_rr = 1; /* register dest - register src */ - timing_rm = 2; /* register dest - memory src */ - timing_mr = 3; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 2; /* register dest - memory src long */ - timing_mrl = 3; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 0; /* branch taken */ - timing_bnt = 1; /* branch not taken */ + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + timing_bnt = 1; /* branch not taken */ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /* unknown */ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; - timing_misaligned = 3; + timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; - if (cpu_s->cpu_type >= CPU_PENTIUM2) - cpu_features |= CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE; - if (cpu_s->cpu_type == CPU_PENTIUM2D) - cpu_CR4_mask |= CR4_OSFXSR; - -#ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_p6); -#endif - break; - - case CPU_CYRIX3S: -#ifdef USE_DYNAREC - x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; + if (cpu_s->cpu_type >= CPU_K6_2) + cpu_features |= CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); +#if defined(DEV_BRANCH) && defined(USE_AMD_K5) + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE; + if (cpu_s->cpu_type >= CPU_K6) { + cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); + if (cpu_s->cpu_type <= CPU_K6) + cpu_CR4_mask |= CR4_PCE; + } #else - x86_setopcodes(ops_386, ops_winchip2_0f); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + if (cpu_s->cpu_type == CPU_K6) + cpu_CR4_mask |= CR4_PCE; #endif - timing_rr = 1; /* register dest - register src */ - timing_rm = 2; /* register dest - memory src */ - timing_mr = 2; /* memory dest - register src */ - timing_mm = 3; - timing_rml = 2; /* register dest - memory src long */ - timing_mrl = 2; /* memory dest - register src long */ - timing_mml = 3; - timing_bt = 2; /* branch taken */ - timing_bnt = 1; /* branch not taken */ - - timing_int_rm = 26; /* unknown */ - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - - timing_misaligned = 2; - - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - - cpu_cyrix_alignment = 1; #ifdef USE_DYNAREC - codegen_timing_set(&codegen_timing_winchip); + codegen_timing_set(&codegen_timing_k6); #endif - break; + break; - default: - fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: +#ifdef USE_DYNAREC + /* TODO: Perhaps merge the three opcode tables with some instructions UD#'ing depending on + CPU type. */ + if (cpu_s->cpu_type == CPU_PENTIUM2D) + x86_setopcodes(ops_386, ops_pentium2d_0f, dynarec_ops_386, dynarec_ops_pentium2d_0f); + else if (cpu_s->cpu_type == CPU_PENTIUM2) + x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); + else + x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; +#else + if (cpu_s->cpu_type == CPU_PENTIUM2D) + x86_setopcodes(ops_386, ops_pentium2d_0f); + else + x86_setopcodes(ops_386, ops_pentium2_0f); +#endif + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; + if (cpu_s->cpu_type >= CPU_PENTIUM2) + cpu_features |= CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE; + if (cpu_s->cpu_type == CPU_PENTIUM2D) + cpu_CR4_mask |= CR4_OSFXSR; + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_p6); +#endif + break; + + case CPU_CYRIX3S: +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); +#else + x86_setopcodes(ops_386, ops_winchip2_0f); +#endif + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 2; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 2; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 2; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int_rm = 26; /* unknown */ + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + + timing_misaligned = 2; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + + cpu_cyrix_alignment = 1; + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_winchip); +#endif + break; + + default: + fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } switch (fpu_type) { - case FPU_NONE: - break; + case FPU_NONE: + break; - case FPU_8087: - x87_timings = x87_timings_8087; - break; + case FPU_8087: + x87_timings = x87_timings_8087; + break; - case FPU_287: - x87_timings = x87_timings_287; - break; + case FPU_287: + x87_timings = x87_timings_287; + break; - case FPU_287XL: - case FPU_387: - x87_timings = x87_timings_387; - break; + case FPU_287XL: + case FPU_387: + x87_timings = x87_timings_387; + break; - case FPU_487SX: - default: - x87_timings = x87_timings_486; - x87_concurrency = x87_concurrency_486; + case FPU_487SX: + default: + x87_timings = x87_timings_486; + x87_concurrency = x87_concurrency_486; } if (is386) { #if defined(USE_DYNAREC) && !defined(USE_GDBSTUB) - if (cpu_use_dynarec) - cpu_exec = exec386_dynarec; - else + if (cpu_use_dynarec) + cpu_exec = exec386_dynarec; + else #endif - cpu_exec = exec386; + cpu_exec = exec386; } else if (cpu_s->cpu_type >= CPU_286) - cpu_exec = exec386; + cpu_exec = exec386; else - cpu_exec = execx86; + cpu_exec = execx86; gdbstub_cpu_init(); } - void cpu_close(void) { cpu_inited = 0; } - void cpu_set_isa_speed(int speed) { if (speed) { - cpu_isa_speed = speed; - pc_speed_changed(); + cpu_isa_speed = speed; + pc_speed_changed(); } else if (cpu_busspeed >= 8000000) - cpu_isa_speed = 8000000; + cpu_isa_speed = 8000000; else - cpu_isa_speed = cpu_busspeed; + cpu_isa_speed = cpu_busspeed; cpu_log("cpu_set_isa_speed(%d) = %d\n", speed, cpu_isa_speed); } - void cpu_set_pci_speed(int speed) { if (speed) - cpu_pci_speed = speed; + cpu_pci_speed = speed; else if (cpu_busspeed < 42500000) - cpu_pci_speed = cpu_busspeed; + cpu_pci_speed = cpu_busspeed; else if (cpu_busspeed < 84000000) - cpu_pci_speed = cpu_busspeed / 2; + cpu_pci_speed = cpu_busspeed / 2; else if (cpu_busspeed < 120000000) - cpu_pci_speed = cpu_busspeed / 3; + cpu_pci_speed = cpu_busspeed / 3; else - cpu_pci_speed = cpu_busspeed / 4; + cpu_pci_speed = cpu_busspeed / 4; if (cpu_isa_pci_div) - cpu_set_isa_pci_div(cpu_isa_pci_div); + cpu_set_isa_pci_div(cpu_isa_pci_div); else if (speed) - pc_speed_changed(); + pc_speed_changed(); - pci_burst_time = cpu_s->rspeed / cpu_pci_speed; + pci_burst_time = cpu_s->rspeed / cpu_pci_speed; pci_nonburst_time = 4 * pci_burst_time; cpu_log("cpu_set_pci_speed(%d) = %d\n", speed, cpu_pci_speed); } - void cpu_set_isa_pci_div(int div) { @@ -1448,1094 +1422,1148 @@ cpu_set_isa_pci_div(int div) cpu_log("cpu_set_isa_pci_div(%d)\n", cpu_isa_pci_div); if (cpu_isa_pci_div) - cpu_set_isa_speed(cpu_pci_speed / cpu_isa_pci_div); + cpu_set_isa_speed(cpu_pci_speed / cpu_isa_pci_div); else - cpu_set_isa_speed(0); + cpu_set_isa_speed(0); } - void cpu_set_agp_speed(int speed) { if (speed) { - cpu_agp_speed = speed; - pc_speed_changed(); - } - else if (cpu_busspeed < 84000000) - cpu_agp_speed = cpu_busspeed; + cpu_agp_speed = speed; + pc_speed_changed(); + } else if (cpu_busspeed < 84000000) + cpu_agp_speed = cpu_busspeed; else if (cpu_busspeed < 120000000) - cpu_agp_speed = cpu_busspeed / 1.5; + cpu_agp_speed = cpu_busspeed / 1.5; else - cpu_agp_speed = cpu_busspeed / 2; + cpu_agp_speed = cpu_busspeed / 2; - agp_burst_time = cpu_s->rspeed / cpu_agp_speed; + agp_burst_time = cpu_s->rspeed / cpu_agp_speed; agp_nonburst_time = 4 * agp_burst_time; cpu_log("cpu_set_agp_speed(%d) = %d\n", speed, cpu_agp_speed); } - char * cpu_current_pc(char *bufp) { static char buff[10]; if (bufp == NULL) - bufp = buff; + bufp = buff; sprintf(bufp, "%04X:%04X", CS, cpu_state.pc); - return(bufp); + return (bufp); } - void cpu_CPUID(void) { switch (cpu_s->cpu_type) { - case CPU_i486SX_SLENH: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_VME; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_i486SX_SLENH: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_VME; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_i486DX_SLENH: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_i486DX_SLENH: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_ENH_Am486DX: - if (!EAX) { - EAX = 1; - EBX = 0x68747541; - ECX = 0x444D4163; - EDX = 0x69746E65; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; /*FPU*/ - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_ENH_Am486DX: + if (!EAX) { + EAX = 1; + EBX = 0x68747541; + ECX = 0x444D4163; + EDX = 0x69746E65; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; /*FPU*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_WINCHIP: - if (!EAX) { - EAX = 1; - if (msr.fcr2 & (1 << 14)) { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } else { - EBX = 0x746e6543; /* CentaurHauls */ - ECX = 0x736c7561; - EDX = 0x48727561; - } - } else if (EAX == 1) { - EAX = 0x540; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_WINCHIP: + if (!EAX) { + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + } else if (EAX == 1) { + EAX = 0x540; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_WINCHIP2: - switch (EAX) { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } else { - EBX = 0x746e6543; /* CentaurHauls */ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - if (cpu_has_feature(CPU_FEATURE_3DNOW)) - EDX |= CPUID_3DNOW; - break; + case CPU_WINCHIP2: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; - case 0x80000002: /* Processor name string */ - EAX = 0x20544449; /* IDT WinChip 2-3D */ - EBX = 0x436e6957; - ECX = 0x20706968; - EDX = 0x44332d32; - break; + case 0x80000002: /* Processor name string */ + EAX = 0x20544449; /* IDT WinChip 2-3D */ + EBX = 0x436e6957; + ECX = 0x20706968; + EDX = 0x44332d32; + break; - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x20040120; /*L1 data cache*/ - EDX = 0x20020120; /*L1 instruction cache*/ - break; + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x20040120; /*L1 data cache*/ + EDX = 0x20020120; /*L1 instruction cache*/ + break; - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case CPU_P24T: - case CPU_PENTIUM: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_P24T: + case CPU_PENTIUM: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_K5: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_5K86: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x7428354B; - ECX = 0x5020296D; - EDX = 0x65636F72; - } else if (EAX == 0x80000003) { - EAX = 0x726F7373; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000004) - EAX = EBX = ECX = EDX = 0; - else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x04800000; - ECX = 0x08040120; - EDX = 0x10040120; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_5K86: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + } else if (EAX == 0x80000000) { + EAX = 0x80000005; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000001) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; + } else if (EAX == 0x80000002) { + EAX = 0x2D444D41; + EBX = 0x7428354B; + ECX = 0x5020296D; + EDX = 0x65636F72; + } else if (EAX == 0x80000003) { + EAX = 0x726F7373; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000004) + EAX = EBX = ECX = EDX = 0; + else if (EAX == 0x80000005) { + EAX = 0; + EBX = 0x04800000; + ECX = 0x08040120; + EDX = 0x10040120; + } else + EAX = EBX = ECX = EDX = 0; + break; #endif - case CPU_K6: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x68747541; - EDX = 0x69746E65; - ECX = 0x444D4163; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - } else if (EAX == 0x80000000) { - EAX = 0x80000005; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000001) { - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; - } else if (EAX == 0x80000002) { - EAX = 0x2D444D41; - EBX = 0x6D74364B; - ECX = 0x202F7720; - EDX = 0x746C756D; - } else if (EAX == 0x80000003) { - EAX = 0x64656D69; - EBX = 0x65206169; - ECX = 0x6E657478; - EDX = 0x6E6F6973; - } else if (EAX == 0x80000004) { - EAX = 0x73; - EBX = ECX = EDX = 0; - } else if (EAX == 0x80000005) { - EAX = 0; - EBX = 0x02800140; - ECX = 0x20020220; - EDX = 0x20020220; - } else if (EAX == 0x8FFFFFFF) { - EAX = 0x4778654E; - EBX = 0x72656E65; - ECX = 0x6F697461; - EDX = 0x444D416E; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_K6: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x68747541; + EDX = 0x69746E65; + ECX = 0x444D4163; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + } else if (EAX == 0x80000000) { + EAX = 0x80000005; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000001) { + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + } else if (EAX == 0x80000002) { + EAX = 0x2D444D41; + EBX = 0x6D74364B; + ECX = 0x202F7720; + EDX = 0x746C756D; + } else if (EAX == 0x80000003) { + EAX = 0x64656D69; + EBX = 0x65206169; + ECX = 0x6E657478; + EDX = 0x6E6F6973; + } else if (EAX == 0x80000004) { + EAX = 0x73; + EBX = ECX = EDX = 0; + } else if (EAX == 0x80000005) { + EAX = 0; + EBX = 0x02800140; + ECX = 0x20020220; + EDX = 0x20020220; + } else if (EAX == 0x8FFFFFFF) { + EAX = 0x4778654E; + EBX = 0x72656E65; + ECX = 0x6F697461; + EDX = 0x444D416E; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_K6_2: - case CPU_K6_2C: - switch (EAX) { - case 0: - EAX = 1; - EBX = 0x68747541; /* AuthenticAMD */ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000005; - EBX = ECX = EDX = 0; - break; - case 0x80000001: - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; - case 0x80000002: /* Processor name string */ - EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x72702044; - break; - case 0x80000003: /* Processor name string */ - EAX = 0x7365636f; /* ocessor */ - EBX = 0x00726f73; - ECX = 0x00000000; - EDX = 0x00000000; - break; - case 0x80000005: /*Cache information*/ - EAX = 0; - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; + case CPU_K6_2: + case CPU_K6_2C: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x72702044; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x7365636f; /* ocessor */ + EBX = 0x00726f73; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /*Cache information*/ + EAX = 0; + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case CPU_K6_3: - switch (EAX) { - case 0: - EAX = 1; - EBX = 0x68747541; /* AuthenticAMD */ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000006; - EBX = ECX = EDX = 0; - break; - case 0x80000001: - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; - case 0x80000002: /* Processor name string */ - EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x50202b44; - break; - case 0x80000003: /* Processor name string */ - EAX = 0x65636f72; /* rocessor */ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; - case 0x80000005: /* Cache information */ - EAX = 0; - EBX = 0x02800140; /* TLBs */ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; - case 0x80000006: /* L2 Cache information */ - EAX = EBX = EDX = 0; - ECX = 0x01004220; - break; - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; + case CPU_K6_3: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x50202b44; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x65636f72; /* rocessor */ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + case 0x80000006: /* L2 Cache information */ + EAX = EBX = EDX = 0; + ECX = 0x01004220; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case CPU_K6_2P: - case CPU_K6_3P: - switch (EAX) { - case 0: - EAX = 1; - EBX = 0x68747541; /* AuthenticAMD */ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000: - EAX = 0x80000007; - EBX = ECX = EDX = 0; - break; - case 0x80000001: - EAX = CPUID + 0x100; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; - break; - case 0x80000002: /* Processor name string */ - EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ - EBX = 0x7428364b; - ECX = 0x492d296d; - EDX = 0x50204949; - break; - case 0x80000003: /* Processor name string */ - EAX = 0x65636f72; /* rocessor */ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; - case 0x80000005: /* Cache information */ - EAX = 0; - EBX = 0x02800140; /* TLBs */ - ECX = 0x20020220; /* L1 data cache */ - EDX = 0x20020220; /* L1 instruction cache */ - break; - case 0x80000006: /* L2 Cache information */ - EAX = EBX = EDX = 0; - if (cpu_s->cpu_type == CPU_K6_3P) - ECX = 0x01004220; - else - ECX = 0x00804220; - break; - case 0x80000007: /* PowerNow information */ - EAX = EBX = ECX = 0; - EDX = 7; - break; - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; + case CPU_K6_2P: + case CPU_K6_3P: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /* AuthenticAMD */ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000007; + EBX = ECX = EDX = 0; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ + EBX = 0x7428364b; + ECX = 0x492d296d; + EDX = 0x50204949; + break; + case 0x80000003: /* Processor name string */ + EAX = 0x65636f72; /* rocessor */ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EAX = 0; + EBX = 0x02800140; /* TLBs */ + ECX = 0x20020220; /* L1 data cache */ + EDX = 0x20020220; /* L1 instruction cache */ + break; + case 0x80000006: /* L2 Cache information */ + EAX = EBX = EDX = 0; + if (cpu_s->cpu_type == CPU_K6_3P) + ECX = 0x01004220; + else + ECX = 0x00804220; + break; + case 0x80000007: /* PowerNow information */ + EAX = EBX = ECX = 0; + EDX = 7; + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case CPU_PENTIUMMMX: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_PENTIUMMMX: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Cx6x86: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Cx6x86L: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_CMPXCHG8B; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Cx6x86L: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_CxGX1: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_CxGX1: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_Cx6x86MX: - if (!EAX) { - EAX = 0x00000001; - EBX = 0x69727943; - EDX = 0x736e4978; - ECX = 0x64616574; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_Cx6x86MX: + if (!EAX) { + EAX = 0x00000001; + EBX = 0x69727943; + EDX = 0x736e4978; + ECX = 0x64616574; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; #endif - case CPU_PENTIUMPRO: - if (!EAX) { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; - } else if (EAX == 2) { - EAX = 0x00000001; - EBX = ECX = 0; - EDX = 0x00000000; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_PENTIUMPRO: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; + } else if (EAX == 2) { + EAX = 0x00000001; + EBX = ECX = 0; + EDX = 0x00000000; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_PENTIUM2: - if (!EAX) { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; - } else if (EAX == 2) { - EAX = 0x00000001; - EBX = ECX = 0; - EDX = 0x00000000; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_PENTIUM2: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; + } else if (EAX == 2) { + EAX = 0x00000001; + EBX = ECX = 0; + EDX = 0x00000000; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_PENTIUM2D: - if (!EAX) { - EAX = 0x00000002; - EBX = 0x756e6547; - EDX = 0x49656e69; - ECX = 0x6c65746e; - } else if (EAX == 1) { - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; - } else if (EAX == 2) { - EAX = 0x00000001; - EBX = ECX = 0; - EDX = 0x00000000; - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_PENTIUM2D: + if (!EAX) { + EAX = 0x00000002; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } else if (EAX == 1) { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + } else if (EAX == 2) { + EAX = 0x00000001; + EBX = ECX = 0; + EDX = 0x00000000; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_CYRIX3S: - switch (EAX) { - case 0: - EAX = 1; - if (msr.fcr2 & (1 << 14)) { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } else { - EBX = 0x746e6543; /* CentaurHauls */ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1: - EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000000: - EAX = 0x80000005; - break; - case 0x80000001: - EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - break; - case 0x80000002: /* Processor name string */ - EAX = 0x20414956; /* VIA Samuel */ - EBX = 0x756d6153; - ECX = 0x00006c65; - EDX = 0x00000000; - break; - case 0x80000005: /* Cache information */ - EBX = 0x08800880; /* TLBs */ - ECX = 0x40040120; /* L1 data cache */ - EDX = 0x40020120; /* L1 instruction cache */ - break; - default: - EAX = EBX = ECX = EDX = 0; - break; - } - break; + case CPU_CYRIX3S: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /* CentaurHauls */ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + break; + case 0x80000002: /* Processor name string */ + EAX = 0x20414956; /* VIA Samuel */ + EBX = 0x756d6153; + ECX = 0x00006c65; + EDX = 0x00000000; + break; + case 0x80000005: /* Cache information */ + EBX = 0x08800880; /* TLBs */ + ECX = 0x40040120; /* L1 data cache */ + EDX = 0x40020120; /* L1 instruction cache */ + break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; } } - void cpu_ven_reset(void) { memset(&msr, 0, sizeof(msr)); switch (cpu_s->cpu_type) { - case CPU_K6_2P: - case CPU_K6_3P: - case CPU_K6_3: - case CPU_K6_2C: - msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL; - /* FALLTHROUGH */ - case CPU_K6_2: + case CPU_K6_2P: + case CPU_K6_3P: + case CPU_K6_3: + case CPU_K6_2C: + msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL; + /* FALLTHROUGH */ + case CPU_K6_2: #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: + case CPU_K5: + case CPU_5K86: #endif - case CPU_K6: - msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL; - break; + case CPU_K6: + msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL; + break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: - msr.mtrr_cap = 0x00000508ULL; - /* FALLTHROUGH */ - break; + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + msr.mtrr_cap = 0x00000508ULL; + /* FALLTHROUGH */ + break; } } - void cpu_RDMSR(void) { switch (cpu_s->cpu_type) { - case CPU_IBM386SLC: - case CPU_IBM486SLC: - case CPU_IBM486BL: - EAX = EDX = 0; - switch (ECX) { - case 0x1000: - EAX = msr.ibm_por & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); - break; + case CPU_IBM386SLC: + case CPU_IBM486SLC: + case CPU_IBM486BL: + EAX = EDX = 0; + switch (ECX) { + case 0x1000: + EAX = msr.ibm_por & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); + break; - case 0x1001: - EAX = msr.ibm_crcr & 0xffffffffff; - break; + case 0x1001: + EAX = msr.ibm_crcr & 0xffffffffff; + break; - case 0x1002: - if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) - EAX = msr.ibm_por2 & 0x3f000000; - break; - } - break; + case 0x1002: + if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) + EAX = msr.ibm_por2 & 0x3f000000; + break; + } + break; - case CPU_WINCHIP: - case CPU_WINCHIP2: - EAX = EDX = 0; - switch (ECX) { - case 0x02: - EAX = msr.tr1; - break; - case 0x0e: - EAX = msr.tr12; - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x11: - EAX = msr.cesr; - break; - case 0x107: - EAX = msr.fcr; - break; - case 0x108: - EAX = msr.fcr2 & 0xffffffff; - EDX = msr.fcr2 >> 32; - break; - case 0x10a: - EAX = cpu_multi & 3; - break; - } - break; + case CPU_WINCHIP: + case CPU_WINCHIP2: + EAX = EDX = 0; + switch (ECX) { + case 0x02: + EAX = msr.tr1; + break; + case 0x0e: + EAX = msr.tr12; + break; + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x11: + EAX = msr.cesr; + break; + case 0x107: + EAX = msr.fcr; + break; + case 0x108: + EAX = msr.fcr2 & 0xffffffff; + EDX = msr.fcr2 >> 32; + break; + case 0x10a: + EAX = cpu_multi & 3; + break; + } + break; - case CPU_CYRIX3S: - EAX = EDX = 0; - switch (ECX) { - case 0x00: case 0x01: - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x2a: - EAX = 0xc4000000; - EDX = 0; - if (cpu_dmulti == 3) - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 3.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 4) - EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 4.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 5) - EAX |= 0; - else if (cpu_dmulti == 5.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); - else if (cpu_dmulti == 6) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 6.5) - EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 7) - EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - if (cpu_busspeed >= 84000000) - EAX |= (1 << 19); - break; - case 0x1107: - EAX = msr.fcr; - break; - case 0x1108: - EAX = msr.fcr2 & 0xffffffff; - EDX = msr.fcr2 >> 32; - break; - case 0x200: case 0x201: case 0x202: case 0x203: - case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20a: case 0x20b: - case 0x20c: case 0x20d: case 0x20e: case 0x20f: - if (ECX & 1) { - EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; - } else { - EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; - } - break; - case 0x250: - EAX = msr.mtrr_fix64k_8000 & 0xffffffff; - EDX = msr.mtrr_fix64k_8000 >> 32; - break; - case 0x258: - EAX = msr.mtrr_fix16k_8000 & 0xffffffff; - EDX = msr.mtrr_fix16k_8000 >> 32; - break; - case 0x259: - EAX = msr.mtrr_fix16k_a000 & 0xffffffff; - EDX = msr.mtrr_fix16k_a000 >> 32; - break; - case 0x268: case 0x269: case 0x26a: case 0x26b: - case 0x26c: case 0x26d: case 0x26e: case 0x26f: - EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; - EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; - break; - case 0x2ff: - EAX = msr.mtrr_deftype & 0xffffffff; - EDX = msr.mtrr_deftype >> 32; - break; - } - break; + case CPU_CYRIX3S: + EAX = EDX = 0; + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x2a: + EAX = 0xc4000000; + EDX = 0; + if (cpu_dmulti == 3) + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 3.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 4) + EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 4.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 5) + EAX |= 0; + else if (cpu_dmulti == 5.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); + else if (cpu_dmulti == 6) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 6.5) + EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 7) + EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + if (cpu_busspeed >= 84000000) + EAX |= (1 << 19); + break; + case 0x1107: + EAX = msr.fcr; + break; + case 0x1108: + EAX = msr.fcr2 & 0xffffffff; + EDX = msr.fcr2 >> 32; + break; + case 0x200: + case 0x201: + case 0x202: + case 0x203: + case 0x204: + case 0x205: + case 0x206: + case 0x207: + case 0x208: + case 0x209: + case 0x20a: + case 0x20b: + case 0x20c: + case 0x20d: + case 0x20e: + case 0x20f: + if (ECX & 1) { + EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; + } else { + EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; + } + break; + case 0x250: + EAX = msr.mtrr_fix64k_8000 & 0xffffffff; + EDX = msr.mtrr_fix64k_8000 >> 32; + break; + case 0x258: + EAX = msr.mtrr_fix16k_8000 & 0xffffffff; + EDX = msr.mtrr_fix16k_8000 >> 32; + break; + case 0x259: + EAX = msr.mtrr_fix16k_a000 & 0xffffffff; + EDX = msr.mtrr_fix16k_a000 >> 32; + break; + case 0x268: + case 0x269: + case 0x26a: + case 0x26b: + case 0x26c: + case 0x26d: + case 0x26e: + case 0x26f: + EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; + EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; + break; + case 0x2ff: + EAX = msr.mtrr_deftype & 0xffffffff; + EDX = msr.mtrr_deftype >> 32; + break; + } + break; #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: + case CPU_K5: + case CPU_5K86: #endif - case CPU_K6: - case CPU_K6_2: - case CPU_K6_2C: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P: - EAX = EDX = 0; - switch (ECX) { - case 0x00000000: - case 0x00000001: - break; - case 0x0000000e: - EAX = msr.tr12; - break; - case 0x00000010: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x00000083: - EAX = msr.ecx83 & 0xffffffff; - EDX = msr.ecx83 >> 32; - break; - case 0xc0000080: - EAX = msr.amd_efer & 0xffffffff; - EDX = msr.amd_efer >> 32; - break; - case 0xc0000081: - if (cpu_s->cpu_type < CPU_K6_2) - goto amd_k_invalid_rdmsr; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + EAX = EDX = 0; + switch (ECX) { + case 0x00000000: + case 0x00000001: + break; + case 0x0000000e: + EAX = msr.tr12; + break; + case 0x00000010: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x00000083: + EAX = msr.ecx83 & 0xffffffff; + EDX = msr.ecx83 >> 32; + break; + case 0xc0000080: + EAX = msr.amd_efer & 0xffffffff; + EDX = msr.amd_efer >> 32; + break; + case 0xc0000081: + if (cpu_s->cpu_type < CPU_K6_2) + goto amd_k_invalid_rdmsr; - EAX = msr.star & 0xffffffff; - EDX = msr.star >> 32; - break; - case 0xc0000082: - EAX = msr.amd_whcr & 0xffffffff; - EDX = msr.amd_whcr >> 32; - break; - case 0xc0000085: - if (cpu_s->cpu_type < CPU_K6_2C) - goto amd_k_invalid_rdmsr; + EAX = msr.star & 0xffffffff; + EDX = msr.star >> 32; + break; + case 0xc0000082: + EAX = msr.amd_whcr & 0xffffffff; + EDX = msr.amd_whcr >> 32; + break; + case 0xc0000085: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; - EAX = msr.amd_uwccr & 0xffffffff; - EDX = msr.amd_uwccr >> 32; - break; - case 0xc0000086: - if (cpu_s->cpu_type < CPU_K6_2P) - goto amd_k_invalid_rdmsr; + EAX = msr.amd_uwccr & 0xffffffff; + EDX = msr.amd_uwccr >> 32; + break; + case 0xc0000086: + if (cpu_s->cpu_type < CPU_K6_2P) + goto amd_k_invalid_rdmsr; - EAX = msr.amd_epmr & 0xffffffff; - EDX = msr.amd_epmr >> 32; - break; - case 0xc0000087: - if (cpu_s->cpu_type < CPU_K6_2C) - goto amd_k_invalid_rdmsr; + EAX = msr.amd_epmr & 0xffffffff; + EDX = msr.amd_epmr >> 32; + break; + case 0xc0000087: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; - EAX = msr.amd_psor & 0xffffffff; - EDX = msr.amd_psor >> 32; - break; - case 0xc0000088: - if (cpu_s->cpu_type < CPU_K6_2C) - goto amd_k_invalid_rdmsr; + EAX = msr.amd_psor & 0xffffffff; + EDX = msr.amd_psor >> 32; + break; + case 0xc0000088: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_rdmsr; - EAX = msr.amd_pfir & 0xffffffff; - EDX = msr.amd_pfir >> 32; - break; - case 0xc0000089: - if (cpu_s->cpu_type < CPU_K6_3) - goto amd_k_invalid_rdmsr; + EAX = msr.amd_pfir & 0xffffffff; + EDX = msr.amd_pfir >> 32; + break; + case 0xc0000089: + if (cpu_s->cpu_type < CPU_K6_3) + goto amd_k_invalid_rdmsr; - EAX = msr.amd_l2aar & 0xffffffff; - EDX = msr.amd_l2aar >> 32; - break; - default: + EAX = msr.amd_l2aar & 0xffffffff; + EDX = msr.amd_l2aar >> 32; + break; + default: amd_k_invalid_rdmsr: - x86gpf(NULL, 0); - break; - } - break; + x86gpf(NULL, 0); + break; + } + break; - case CPU_P24T: - case CPU_PENTIUM: - case CPU_PENTIUMMMX: + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: - if (cpu_s->cpu_type < CPU_Cx6x86) + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: + if (cpu_s->cpu_type < CPU_Cx6x86) #endif - EAX = EDX = 0; - switch (ECX) { - case 0x00: case 0x01: - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - } - cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); - break; + EAX = EDX = 0; + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: - EAX = EDX = 0; - switch (ECX) { - case 0x00: case 0x01: - break; - case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) - goto i686_invalid_rdmsr; + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + EAX = EDX = 0; + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + case 0x17: + if (cpu_s->cpu_type != CPU_PENTIUM2D) + goto i686_invalid_rdmsr; - if (cpu_f->package == CPU_PKG_SLOT2) - EDX |= 0x80000; - else if (cpu_f->package == CPU_PKG_SOCKET370) - EDX |= 0x100000; - break; - case 0x1B: - EAX = msr.apic_base & 0xffffffff; - EDX = msr.apic_base >> 32; - cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); - break; - case 0x2a: - EAX = 0xc4000000; - EDX = 0; - if (cpu_dmulti == 2.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 3) - EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 3.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 4) - EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 4.5) - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); - else if (cpu_dmulti == 5) - EAX |= 0; - else if (cpu_dmulti == 5.5) - EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); - else if (cpu_dmulti == 6) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 6.5) - EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - else if (cpu_dmulti == 7) - EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 7.5) - EAX |= ((1 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); - else if (cpu_dmulti == 8) - EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); - else - EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); - if (cpu_s->cpu_type != CPU_PENTIUMPRO) { - if (cpu_busspeed >= 84000000) - EAX |= (1 << 19); - } - break; - case 0x79: - EAX = msr.ecx79 & 0xffffffff; - EDX = msr.ecx79 >> 32; - break; - case 0x88: case 0x89: case 0x8a: case 0x8b: - EAX = msr.ecx8x[ECX - 0x88] & 0xffffffff; - EDX = msr.ecx8x[ECX - 0x88] >> 32; - break; - case 0xc1: case 0xc2: case 0xc3: case 0xc4: - case 0xc5: case 0xc6: case 0xc7: case 0xc8: - EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; - EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; - break; - case 0xfe: - EAX = msr.mtrr_cap & 0xffffffff; - EDX = msr.mtrr_cap >> 32; - break; - case 0x116: - EAX = msr.ecx116 & 0xffffffff; - EDX = msr.ecx116 >> 32; - break; - case 0x118: case 0x119: case 0x11a: case 0x11b: - EAX = msr.ecx11x[ECX - 0x118] & 0xffffffff; - EDX = msr.ecx11x[ECX - 0x118] >> 32; - break; - case 0x11e: - EAX = msr.ecx11e & 0xffffffff; - EDX = msr.ecx11e >> 32; - break; - case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_rdmsr; + if (cpu_f->package == CPU_PKG_SLOT2) + EDX |= 0x80000; + else if (cpu_f->package == CPU_PKG_SOCKET370) + EDX |= 0x100000; + break; + case 0x1B: + EAX = msr.apic_base & 0xffffffff; + EDX = msr.apic_base >> 32; + cpu_log("APIC_BASE read : %08X%08X\n", EDX, EAX); + break; + case 0x2a: + EAX = 0xc4000000; + EDX = 0; + if (cpu_dmulti == 2.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 3) + EAX |= ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 3.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 4) + EAX |= ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 4.5) + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22)); + else if (cpu_dmulti == 5) + EAX |= 0; + else if (cpu_dmulti == 5.5) + EAX |= ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22)); + else if (cpu_dmulti == 6) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 6.5) + EAX |= ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + else if (cpu_dmulti == 7) + EAX |= ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 7.5) + EAX |= ((1 << 25) | (1 << 24) | (0 << 23) | (1 << 22)); + else if (cpu_dmulti == 8) + EAX |= ((1 << 25) | (0 << 24) | (1 << 23) | (0 << 22)); + else + EAX |= ((0 << 25) | (1 << 24) | (1 << 23) | (1 << 22)); + if (cpu_s->cpu_type != CPU_PENTIUMPRO) { + if (cpu_busspeed >= 84000000) + EAX |= (1 << 19); + } + break; + case 0x79: + EAX = msr.ecx79 & 0xffffffff; + EDX = msr.ecx79 >> 32; + break; + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + EAX = msr.ecx8x[ECX - 0x88] & 0xffffffff; + EDX = msr.ecx8x[ECX - 0x88] >> 32; + break; + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + EAX = msr.ia32_pmc[ECX - 0xC1] & 0xffffffff; + EDX = msr.ia32_pmc[ECX - 0xC1] >> 32; + break; + case 0xfe: + EAX = msr.mtrr_cap & 0xffffffff; + EDX = msr.mtrr_cap >> 32; + break; + case 0x116: + EAX = msr.ecx116 & 0xffffffff; + EDX = msr.ecx116 >> 32; + break; + case 0x118: + case 0x119: + case 0x11a: + case 0x11b: + EAX = msr.ecx11x[ECX - 0x118] & 0xffffffff; + EDX = msr.ecx11x[ECX - 0x118] >> 32; + break; + case 0x11e: + EAX = msr.ecx11e & 0xffffffff; + EDX = msr.ecx11e >> 32; + break; + case 0x174: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; - EAX &= 0xffff0000; - EAX |= msr.sysenter_cs; - EDX = 0x00000000; - break; - case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_rdmsr; + EAX &= 0xffff0000; + EAX |= msr.sysenter_cs; + EDX = 0x00000000; + break; + case 0x175: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; - EAX = msr.sysenter_esp; - EDX = 0x00000000; - break; - case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_rdmsr; + EAX = msr.sysenter_esp; + EDX = 0x00000000; + break; + case 0x176: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_rdmsr; - EAX = msr.sysenter_eip; - EDX = 0x00000000; - break; - case 0x179: - EAX = 0x00000105; - EDX = 0x00000000; - break; - case 0x17a: - break; - case 0x17b: - EAX = msr.mcg_ctl & 0xffffffff; - EDX = msr.mcg_ctl >> 32; - break; - case 0x186: - EAX = msr.ecx186 & 0xffffffff; - EDX = msr.ecx186 >> 32; - break; - case 0x187: - EAX = msr.ecx187 & 0xffffffff; - EDX = msr.ecx187 >> 32; - break; - case 0x1e0: - EAX = msr.ecx1e0 & 0xffffffff; - EDX = msr.ecx1e0 >> 32; - break; - case 0x200: case 0x201: case 0x202: case 0x203: - case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20a: case 0x20b: - case 0x20c: case 0x20d: case 0x20e: case 0x20f: - if (ECX & 1) { - EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; - } else { - EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; - EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; - } - break; - case 0x250: - EAX = msr.mtrr_fix64k_8000 & 0xffffffff; - EDX = msr.mtrr_fix64k_8000 >> 32; - break; - case 0x258: - EAX = msr.mtrr_fix16k_8000 & 0xffffffff; - EDX = msr.mtrr_fix16k_8000 >> 32; - break; - case 0x259: - EAX = msr.mtrr_fix16k_a000 & 0xffffffff; - EDX = msr.mtrr_fix16k_a000 >> 32; - break; - case 0x268: case 0x269: case 0x26a: case 0x26b: - case 0x26c: case 0x26d: case 0x26e: case 0x26f: - EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; - EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; - break; - case 0x277: - EAX = msr.pat & 0xffffffff; - EDX = msr.pat >> 32; - break; - case 0x2ff: - EAX = msr.mtrr_deftype & 0xffffffff; - EDX = msr.mtrr_deftype >> 32; - break; - case 0x400: case 0x404: case 0x408: case 0x40c: - case 0x410: - EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff; - EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32; - break; - case 0x401: case 0x402: case 0x405: case 0x406: - case 0x407: case 0x409: case 0x40d: case 0x40e: - case 0x411: case 0x412: - break; - case 0x570: - EAX = msr.ecx570 & 0xffffffff; - EDX = msr.ecx570 >> 32; - break; - case 0x1002ff: - EAX = msr.ecx1002ff & 0xffffffff; - EDX = msr.ecx1002ff >> 32; - break; - case 0xf0f00250: - EAX = msr.ecxf0f00250 & 0xffffffff; - EDX = msr.ecxf0f00250 >> 32; - break; - case 0xf0f00258: - EAX = msr.ecxf0f00258 & 0xffffffff; - EDX = msr.ecxf0f00258 >> 32; - break; - case 0xf0f00259: - EAX = msr.ecxf0f00259 & 0xffffffff; - EDX = msr.ecxf0f00259 >> 32; - break; - default: + EAX = msr.sysenter_eip; + EDX = 0x00000000; + break; + case 0x179: + EAX = 0x00000105; + EDX = 0x00000000; + break; + case 0x17a: + break; + case 0x17b: + EAX = msr.mcg_ctl & 0xffffffff; + EDX = msr.mcg_ctl >> 32; + break; + case 0x186: + EAX = msr.ecx186 & 0xffffffff; + EDX = msr.ecx186 >> 32; + break; + case 0x187: + EAX = msr.ecx187 & 0xffffffff; + EDX = msr.ecx187 >> 32; + break; + case 0x1e0: + EAX = msr.ecx1e0 & 0xffffffff; + EDX = msr.ecx1e0 >> 32; + break; + case 0x200: + case 0x201: + case 0x202: + case 0x203: + case 0x204: + case 0x205: + case 0x206: + case 0x207: + case 0x208: + case 0x209: + case 0x20a: + case 0x20b: + case 0x20c: + case 0x20d: + case 0x20e: + case 0x20f: + if (ECX & 1) { + EAX = msr.mtrr_physmask[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physmask[(ECX - 0x200) >> 1] >> 32; + } else { + EAX = msr.mtrr_physbase[(ECX - 0x200) >> 1] & 0xffffffff; + EDX = msr.mtrr_physbase[(ECX - 0x200) >> 1] >> 32; + } + break; + case 0x250: + EAX = msr.mtrr_fix64k_8000 & 0xffffffff; + EDX = msr.mtrr_fix64k_8000 >> 32; + break; + case 0x258: + EAX = msr.mtrr_fix16k_8000 & 0xffffffff; + EDX = msr.mtrr_fix16k_8000 >> 32; + break; + case 0x259: + EAX = msr.mtrr_fix16k_a000 & 0xffffffff; + EDX = msr.mtrr_fix16k_a000 >> 32; + break; + case 0x268: + case 0x269: + case 0x26a: + case 0x26b: + case 0x26c: + case 0x26d: + case 0x26e: + case 0x26f: + EAX = msr.mtrr_fix4k[ECX - 0x268] & 0xffffffff; + EDX = msr.mtrr_fix4k[ECX - 0x268] >> 32; + break; + case 0x277: + EAX = msr.pat & 0xffffffff; + EDX = msr.pat >> 32; + break; + case 0x2ff: + EAX = msr.mtrr_deftype & 0xffffffff; + EDX = msr.mtrr_deftype >> 32; + break; + case 0x400: + case 0x404: + case 0x408: + case 0x40c: + case 0x410: + EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff; + EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32; + break; + case 0x401: + case 0x402: + case 0x405: + case 0x406: + case 0x407: + case 0x409: + case 0x40d: + case 0x40e: + case 0x411: + case 0x412: + break; + case 0x570: + EAX = msr.ecx570 & 0xffffffff; + EDX = msr.ecx570 >> 32; + break; + case 0x1002ff: + EAX = msr.ecx1002ff & 0xffffffff; + EDX = msr.ecx1002ff >> 32; + break; + case 0xf0f00250: + EAX = msr.ecxf0f00250 & 0xffffffff; + EDX = msr.ecxf0f00250 >> 32; + break; + case 0xf0f00258: + EAX = msr.ecxf0f00258 & 0xffffffff; + EDX = msr.ecxf0f00258 >> 32; + break; + case 0xf0f00259: + EAX = msr.ecxf0f00259 & 0xffffffff; + EDX = msr.ecxf0f00259 >> 32; + break; + default: i686_invalid_rdmsr: - cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); - x86gpf(NULL, 0); - break; - } - break; + cpu_log("RDMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + break; } cpu_log("RDMSR %08X %08X%08X\n", ECX, EDX, EAX); } - void cpu_WRMSR(void) { @@ -2544,489 +2572,550 @@ cpu_WRMSR(void) cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX); switch (cpu_s->cpu_type) { - case CPU_IBM386SLC: - case CPU_IBM486BL: - case CPU_IBM486SLC: - switch (ECX) { - case 0x1000: - msr.ibm_por = EAX & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); - cpu_cache_int_enabled = (EAX & (1 << 7)); - break; - case 0x1001: - msr.ibm_crcr = EAX & 0xffffffffff; - break; - case 0x1002: - if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) - msr.ibm_por2 = EAX & 0x3f000000; - break; - } - break; + case CPU_IBM386SLC: + case CPU_IBM486BL: + case CPU_IBM486SLC: + switch (ECX) { + case 0x1000: + msr.ibm_por = EAX & ((cpu_s->cpu_type > CPU_IBM386SLC) ? 0xffeff : 0xfeff); + cpu_cache_int_enabled = (EAX & (1 << 7)); + break; + case 0x1001: + msr.ibm_crcr = EAX & 0xffffffffff; + break; + case 0x1002: + if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi) + msr.ibm_por2 = EAX & 0x3f000000; + break; + } + break; - case CPU_WINCHIP: - case CPU_WINCHIP2: - switch (ECX) { - case 0x02: - msr.tr1 = EAX & 2; - break; - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x11: - msr.cesr = EAX & 0xff00ff; - break; - case 0x107: - msr.fcr = EAX; - if (EAX & (1 << 9)) - cpu_features |= CPU_FEATURE_MMX; - else - cpu_features &= ~CPU_FEATURE_MMX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; - if ((EAX & (1 << 20)) && cpu_s->cpu_type >= CPU_WINCHIP2) - cpu_features |= CPU_FEATURE_3DNOW; - else - cpu_features &= ~CPU_FEATURE_3DNOW; - if (EAX & (1 << 29)) - CPUID = 0; - else - CPUID = cpu_s->cpuid_model; - break; - case 0x108: - msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x109: - msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - } - break; + case CPU_WINCHIP: + case CPU_WINCHIP2: + switch (ECX) { + case 0x02: + msr.tr1 = EAX & 2; + break; + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t) EDX << 32); + break; + case 0x11: + msr.cesr = EAX & 0xff00ff; + break; + case 0x107: + msr.fcr = EAX; + if (EAX & (1 << 9)) + cpu_features |= CPU_FEATURE_MMX; + else + cpu_features &= ~CPU_FEATURE_MMX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + if ((EAX & (1 << 20)) && cpu_s->cpu_type >= CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + else + cpu_features &= ~CPU_FEATURE_3DNOW; + if (EAX & (1 << 29)) + CPUID = 0; + else + CPUID = cpu_s->cpuid_model; + break; + case 0x108: + msr.fcr2 = EAX | ((uint64_t) EDX << 32); + break; + case 0x109: + msr.fcr3 = EAX | ((uint64_t) EDX << 32); + break; + } + break; - case CPU_CYRIX3S: - switch (ECX) { - case 0x00: case 0x01: - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x1107: - msr.fcr = EAX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; - break; - case 0x1108: - msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x1109: - msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - case 0x200: case 0x201: case 0x202: case 0x203: - case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20a: case 0x20b: - case 0x20c: case 0x20d: case 0x20e: case 0x20f: - if (ECX & 1) - msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - else - msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - break; - case 0x250: - msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32); - break; - case 0x258: - msr.mtrr_fix16k_8000 = EAX | ((uint64_t)EDX << 32); - break; - case 0x259: - msr.mtrr_fix16k_a000 = EAX | ((uint64_t)EDX << 32); - break; - case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: - msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); - break; - case 0x2ff: - msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); - break; - } - break; + case CPU_CYRIX3S: + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + tsc = EAX | ((uint64_t) EDX << 32); + break; + case 0x1107: + msr.fcr = EAX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + break; + case 0x1108: + msr.fcr2 = EAX | ((uint64_t) EDX << 32); + break; + case 0x1109: + msr.fcr3 = EAX | ((uint64_t) EDX << 32); + break; + case 0x200: + case 0x201: + case 0x202: + case 0x203: + case 0x204: + case 0x205: + case 0x206: + case 0x207: + case 0x208: + case 0x209: + case 0x20a: + case 0x20b: + case 0x20c: + case 0x20d: + case 0x20e: + case 0x20f: + if (ECX & 1) + msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); + else + msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); + break; + case 0x250: + msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); + break; + case 0x258: + msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); + break; + case 0x259: + msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); + break; + case 0x268: + case 0x269: + case 0x26A: + case 0x26B: + case 0x26C: + case 0x26D: + case 0x26E: + case 0x26F: + msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); + break; + case 0x2ff: + msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); + break; + } + break; #if defined(DEV_BRANCH) && defined(USE_AMD_K5) - case CPU_K5: - case CPU_5K86: + case CPU_K5: + case CPU_5K86: #endif - case CPU_K6: - case CPU_K6_2: - case CPU_K6_2C: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P: - switch (ECX) { - case 0x00: case 0x01: - break; - case 0x0e: - msr.tr12 = EAX & 0x228; - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x83: - msr.ecx83 = EAX | ((uint64_t)EDX << 32); - break; - case 0xc0000080: - temp = EAX | ((uint64_t)EDX << 32); - if (temp & ~1ULL) - x86gpf(NULL, 0); - else - msr.amd_efer = temp; - break; - case 0xc0000081: - if (cpu_s->cpu_type < CPU_K6_2) - goto amd_k_invalid_wrmsr; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_2C: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x0e: + msr.tr12 = EAX & 0x228; + break; + case 0x10: + tsc = EAX | ((uint64_t) EDX << 32); + break; + case 0x83: + msr.ecx83 = EAX | ((uint64_t) EDX << 32); + break; + case 0xc0000080: + temp = EAX | ((uint64_t) EDX << 32); + if (temp & ~1ULL) + x86gpf(NULL, 0); + else + msr.amd_efer = temp; + break; + case 0xc0000081: + if (cpu_s->cpu_type < CPU_K6_2) + goto amd_k_invalid_wrmsr; - msr.star = EAX | ((uint64_t)EDX << 32); - break; - case 0xc0000082: - msr.amd_whcr = EAX | ((uint64_t)EDX << 32); - break; - case 0xc0000085: - if (cpu_s->cpu_type < CPU_K6_2C) - goto amd_k_invalid_wrmsr; + msr.star = EAX | ((uint64_t) EDX << 32); + break; + case 0xc0000082: + msr.amd_whcr = EAX | ((uint64_t) EDX << 32); + break; + case 0xc0000085: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; - msr.amd_uwccr = EAX | ((uint64_t)EDX << 32); - break; - case 0xc0000086: - if (cpu_s->cpu_type < CPU_K6_2P) - goto amd_k_invalid_wrmsr; + msr.amd_uwccr = EAX | ((uint64_t) EDX << 32); + break; + case 0xc0000086: + if (cpu_s->cpu_type < CPU_K6_2P) + goto amd_k_invalid_wrmsr; - msr.amd_epmr = EAX | ((uint64_t)EDX << 32); - break; - case 0xc0000087: - if (cpu_s->cpu_type < CPU_K6_2C) - goto amd_k_invalid_wrmsr; + msr.amd_epmr = EAX | ((uint64_t) EDX << 32); + break; + case 0xc0000087: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; - msr.amd_psor = EAX | ((uint64_t)EDX << 32); - break; - case 0xc0000088: - if (cpu_s->cpu_type < CPU_K6_2C) - goto amd_k_invalid_wrmsr; + msr.amd_psor = EAX | ((uint64_t) EDX << 32); + break; + case 0xc0000088: + if (cpu_s->cpu_type < CPU_K6_2C) + goto amd_k_invalid_wrmsr; - msr.amd_pfir = EAX | ((uint64_t)EDX << 32); - break; - case 0xc0000089: - if (cpu_s->cpu_type < CPU_K6_3) - goto amd_k_invalid_wrmsr; + msr.amd_pfir = EAX | ((uint64_t) EDX << 32); + break; + case 0xc0000089: + if (cpu_s->cpu_type < CPU_K6_3) + goto amd_k_invalid_wrmsr; - msr.amd_l2aar = EAX | ((uint64_t)EDX << 32); - break; - default: + msr.amd_l2aar = EAX | ((uint64_t) EDX << 32); + break; + default: amd_k_invalid_wrmsr: - x86gpf(NULL, 0); - break; - } - break; + x86gpf(NULL, 0); + break; + } + break; - case CPU_P24T: - case CPU_PENTIUM: - case CPU_PENTIUMMMX: + case CPU_P24T: + case CPU_PENTIUM: + case CPU_PENTIUMMMX: #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - case CPU_Cx6x86: - case CPU_Cx6x86L: - case CPU_CxGX1: - case CPU_Cx6x86MX: + case CPU_Cx6x86: + case CPU_Cx6x86L: + case CPU_CxGX1: + case CPU_Cx6x86MX: #endif - cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); - switch (ECX) { - case 0x00: case 0x01: - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x8b: + cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); + switch (ECX) { + case 0x00: + case 0x01: + break; + case 0x10: + tsc = EAX | ((uint64_t) EDX << 32); + break; + case 0x8b: #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - if (cpu_s->cpu_type < CPU_Cx6x86) { + if (cpu_s->cpu_type < CPU_Cx6x86) { #endif - cpu_log("WRMSR: Invalid MSR: 0x8B\n"); - x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ + cpu_log("WRMSR: Invalid MSR: 0x8B\n"); + x86gpf(NULL, 0); /* Needed for Vista to correctly break on Pentium */ #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - } + } #endif - break; - } - break; + break; + } + break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM2: - case CPU_PENTIUM2D: - switch (ECX) { - case 0x00: case 0x01: - if (EAX || EDX) - x86gpf(NULL, 0); - break; - case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; - case 0x1b: - cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); - // msr.apic_base = EAX | ((uint64_t)EDX << 32); - break; - case 0x2a: - break; - case 0x79: - msr.ecx79 = EAX | ((uint64_t)EDX << 32); - break; - case 0x88: case 0x89: case 0x8a: case 0x8b: - msr.ecx8x[ECX - 0x88] = EAX | ((uint64_t)EDX << 32); - break; - case 0xc1: case 0xc2: case 0xc3: case 0xc4: - case 0xc5: case 0xc6: case 0xc7: case 0xc8: - msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32); - break; - case 0xfe: - msr.mtrr_cap = EAX | ((uint64_t)EDX << 32); - break; - case 0x116: - msr.ecx116 = EAX | ((uint64_t)EDX << 32); - break; - case 0x118: case 0x119: case 0x11a: case 0x11b: - msr.ecx11x[ECX - 0x118] = EAX | ((uint64_t)EDX << 32); - break; - case 0x11e: - msr.ecx11e = EAX | ((uint64_t)EDX << 32); - break; - case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_wrmsr; + case CPU_PENTIUMPRO: + case CPU_PENTIUM2: + case CPU_PENTIUM2D: + switch (ECX) { + case 0x00: + case 0x01: + if (EAX || EDX) + x86gpf(NULL, 0); + break; + case 0x10: + tsc = EAX | ((uint64_t) EDX << 32); + break; + case 0x1b: + cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); + // msr.apic_base = EAX | ((uint64_t)EDX << 32); + break; + case 0x2a: + break; + case 0x79: + msr.ecx79 = EAX | ((uint64_t) EDX << 32); + break; + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + msr.ecx8x[ECX - 0x88] = EAX | ((uint64_t) EDX << 32); + break; + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + msr.ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t) EDX << 32); + break; + case 0xfe: + msr.mtrr_cap = EAX | ((uint64_t) EDX << 32); + break; + case 0x116: + msr.ecx116 = EAX | ((uint64_t) EDX << 32); + break; + case 0x118: + case 0x119: + case 0x11a: + case 0x11b: + msr.ecx11x[ECX - 0x118] = EAX | ((uint64_t) EDX << 32); + break; + case 0x11e: + msr.ecx11e = EAX | ((uint64_t) EDX << 32); + break; + case 0x174: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; - msr.sysenter_cs = EAX & 0xFFFF; - break; - case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_wrmsr; + msr.sysenter_cs = EAX & 0xFFFF; + break; + case 0x175: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; - msr.sysenter_esp = EAX; - break; - case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_wrmsr; + msr.sysenter_esp = EAX; + break; + case 0x176: + if (cpu_s->cpu_type == CPU_PENTIUMPRO) + goto i686_invalid_wrmsr; - msr.sysenter_eip = EAX; - break; - case 0x179: - break; - case 0x17a: - if (EAX || EDX) - x86gpf(NULL, 0); - break; - case 0x17b: - msr.mcg_ctl = EAX | ((uint64_t)EDX << 32); - break; - case 0x186: - msr.ecx186 = EAX | ((uint64_t)EDX << 32); - break; - case 0x187: - msr.ecx187 = EAX | ((uint64_t)EDX << 32); - break; - case 0x1e0: - msr.ecx1e0 = EAX | ((uint64_t)EDX << 32); - break; - case 0x200: case 0x201: case 0x202: case 0x203: - case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20a: case 0x20b: - case 0x20c: case 0x20d: case 0x20e: case 0x20f: - if (ECX & 1) - msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - else - msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); - break; - case 0x250: - msr.mtrr_fix64k_8000 = EAX | ((uint64_t)EDX << 32); - break; - case 0x258: - msr.mtrr_fix16k_8000 = EAX | ((uint64_t)EDX << 32); - break; - case 0x259: - msr.mtrr_fix16k_a000 = EAX | ((uint64_t)EDX << 32); - break; - case 0x268: case 0x269: case 0x26a: case 0x26b: - case 0x26c: case 0x26d: case 0x26e: case 0x26f: - msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); - break; - case 0x277: - msr.pat = EAX | ((uint64_t)EDX << 32); - break; - case 0x2ff: - msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); - break; - case 0x400: case 0x404: case 0x408: case 0x40c: - case 0x410: - msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t)EDX << 32); - break; - case 0x401: case 0x402: case 0x405: case 0x406: - case 0x407: case 0x409: case 0x40d: case 0x40e: - case 0x411: case 0x412: - if (EAX || EDX) - x86gpf(NULL, 0); - break; - case 0x570: - msr.ecx570 = EAX | ((uint64_t)EDX << 32); - break; - case 0x1002ff: - msr.ecx1002ff = EAX | ((uint64_t)EDX << 32); - break; - case 0xf0f00250: - msr.ecxf0f00250 = EAX | ((uint64_t)EDX << 32); - break; - case 0xf0f00258: - msr.ecxf0f00258 = EAX | ((uint64_t)EDX << 32); - break; - case 0xf0f00259: - msr.ecxf0f00259 = EAX | ((uint64_t)EDX << 32); - break; - default: + msr.sysenter_eip = EAX; + break; + case 0x179: + break; + case 0x17a: + if (EAX || EDX) + x86gpf(NULL, 0); + break; + case 0x17b: + msr.mcg_ctl = EAX | ((uint64_t) EDX << 32); + break; + case 0x186: + msr.ecx186 = EAX | ((uint64_t) EDX << 32); + break; + case 0x187: + msr.ecx187 = EAX | ((uint64_t) EDX << 32); + break; + case 0x1e0: + msr.ecx1e0 = EAX | ((uint64_t) EDX << 32); + break; + case 0x200: + case 0x201: + case 0x202: + case 0x203: + case 0x204: + case 0x205: + case 0x206: + case 0x207: + case 0x208: + case 0x209: + case 0x20a: + case 0x20b: + case 0x20c: + case 0x20d: + case 0x20e: + case 0x20f: + if (ECX & 1) + msr.mtrr_physmask[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); + else + msr.mtrr_physbase[(ECX - 0x200) >> 1] = EAX | ((uint64_t) EDX << 32); + break; + case 0x250: + msr.mtrr_fix64k_8000 = EAX | ((uint64_t) EDX << 32); + break; + case 0x258: + msr.mtrr_fix16k_8000 = EAX | ((uint64_t) EDX << 32); + break; + case 0x259: + msr.mtrr_fix16k_a000 = EAX | ((uint64_t) EDX << 32); + break; + case 0x268: + case 0x269: + case 0x26a: + case 0x26b: + case 0x26c: + case 0x26d: + case 0x26e: + case 0x26f: + msr.mtrr_fix4k[ECX - 0x268] = EAX | ((uint64_t) EDX << 32); + break; + case 0x277: + msr.pat = EAX | ((uint64_t) EDX << 32); + break; + case 0x2ff: + msr.mtrr_deftype = EAX | ((uint64_t) EDX << 32); + break; + case 0x400: + case 0x404: + case 0x408: + case 0x40c: + case 0x410: + msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t) EDX << 32); + break; + case 0x401: + case 0x402: + case 0x405: + case 0x406: + case 0x407: + case 0x409: + case 0x40d: + case 0x40e: + case 0x411: + case 0x412: + if (EAX || EDX) + x86gpf(NULL, 0); + break; + case 0x570: + msr.ecx570 = EAX | ((uint64_t) EDX << 32); + break; + case 0x1002ff: + msr.ecx1002ff = EAX | ((uint64_t) EDX << 32); + break; + case 0xf0f00250: + msr.ecxf0f00250 = EAX | ((uint64_t) EDX << 32); + break; + case 0xf0f00258: + msr.ecxf0f00258 = EAX | ((uint64_t) EDX << 32); + break; + case 0xf0f00259: + msr.ecxf0f00259 = EAX | ((uint64_t) EDX << 32); + break; + default: i686_invalid_wrmsr: - cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); - x86gpf(NULL, 0); - break; - } - break; + cpu_log("WRMSR: Invalid MSR: %08X\n", ECX); + x86gpf(NULL, 0); + break; + } + break; } } - static void cpu_write(uint16_t addr, uint8_t val, void *priv) { if (addr == 0xf0) { - /* Writes to F0 clear FPU error and deassert the interrupt. */ - if (is286) - picintc(1 << 13); - else - nmi = 0; - return; + /* Writes to F0 clear FPU error and deassert the interrupt. */ + if (is286) + picintc(1 << 13); + else + nmi = 0; + return; } else if (addr >= 0xf1) - return; /* FPU stuff */ + return; /* FPU stuff */ if (!(addr & 1)) - cyrix_addr = val; - else switch (cyrix_addr) { - case 0xc0: /* CCR0 */ - ccr0 = val; - break; - case 0xc1: /* CCR1 */ - if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) - val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); - ccr1 = val; - break; - case 0xc2: /* CCR2 */ - ccr2 = val; - break; - case 0xc3: /* CCR3 */ - if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) - val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; - ccr3 = val; - break; - case 0xcd: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xce: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xcf: - if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); - if ((val & 0xf) == 0xf) - cyrix.arr[3].size = 1ull << 32; /* 4 GB */ - else if (val & 0xf) - cyrix.arr[3].size = 2048 << (val & 0xf); - else - cyrix.arr[3].size = 0; /* Disabled */ - cyrix.smhr &= ~SMHR_VALID; - } - break; + cyrix_addr = val; + else + switch (cyrix_addr) { + case 0xc0: /* CCR0 */ + ccr0 = val; + break; + case 0xc1: /* CCR1 */ + if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) + val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); + ccr1 = val; + break; + case 0xc2: /* CCR2 */ + ccr2 = val; + break; + case 0xc3: /* CCR3 */ + if ((ccr3 & CCR3_SMI_LOCK) && !in_smm) + val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; + ccr3 = val; + break; + case 0xcd: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xce: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xcf: + if (!(ccr3 & CCR3_SMI_LOCK) || in_smm) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); + if ((val & 0xf) == 0xf) + cyrix.arr[3].size = 1ull << 32; /* 4 GB */ + else if (val & 0xf) + cyrix.arr[3].size = 2048 << (val & 0xf); + else + cyrix.arr[3].size = 0; /* Disabled */ + cyrix.smhr &= ~SMHR_VALID; + } + break; - case 0xe8: /* CCR4 */ - if ((ccr3 & 0xf0) == 0x10) { - ccr4 = val; + case 0xe8: /* CCR4 */ + if ((ccr3 & 0xf0) == 0x10) { + ccr4 = val; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) - if (cpu_s->cpu_type >= CPU_Cx6x86) { - if (val & 0x80) - CPUID = cpu_s->cpuid_model; - else - CPUID = 0; - } + if (cpu_s->cpu_type >= CPU_Cx6x86) { + if (val & 0x80) + CPUID = cpu_s->cpuid_model; + else + CPUID = 0; + } #endif - } - break; - case 0xe9: /* CCR5 */ - if ((ccr3 & 0xf0) == 0x10) - ccr5 = val; - break; - case 0xea: /* CCR6 */ - if ((ccr3 & 0xf0) == 0x10) - ccr6 = val; - break; - } + } + break; + case 0xe9: /* CCR5 */ + if ((ccr3 & 0xf0) == 0x10) + ccr5 = val; + break; + case 0xea: /* CCR6 */ + if ((ccr3 & 0xf0) == 0x10) + ccr6 = val; + break; + } } - static uint8_t cpu_read(uint16_t addr, void *priv) { if (addr == 0xf007) - return 0x7f; + return 0x7f; if (addr >= 0xf0) - return 0xff; /* FPU stuff */ + return 0xff; /* FPU stuff */ if (addr & 1) { - switch (cyrix_addr) { - case 0xc0: - return ccr0; - case 0xc1: - return ccr1; - case 0xc2: - return ccr2; - case 0xc3: - return ccr3; - case 0xe8: - return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; - case 0xe9: - return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; - case 0xea: - return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; - case 0xfe: - return cpu_s->cyrix_id & 0xff; - case 0xff: - return cpu_s->cyrix_id >> 8; - } + switch (cyrix_addr) { + case 0xc0: + return ccr0; + case 0xc1: + return ccr1; + case 0xc2: + return ccr2; + case 0xc3: + return ccr3; + case 0xe8: + return ((ccr3 & 0xf0) == 0x10) ? ccr4 : 0xff; + case 0xe9: + return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff; + case 0xea: + return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff; + case 0xfe: + return cpu_s->cyrix_id & 0xff; + case 0xff: + return cpu_s->cyrix_id >> 8; + } - if ((cyrix_addr & 0xf0) == 0xc0) - return 0xff; + if ((cyrix_addr & 0xf0) == 0xc0) + return 0xff; - if (cyrix_addr == 0x20 && (cpu_s->cpu_type == CPU_Cx5x86)) - return 0xff; + if (cyrix_addr == 0x20 && (cpu_s->cpu_type == CPU_Cx5x86)) + return 0xff; } return 0xff; } - void #ifdef USE_DYNAREC 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) { - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; - x86_dynarec_opcodes = dynarec_opcodes; + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; + x86_dynarec_opcodes = dynarec_opcodes; x86_dynarec_opcodes_0f = dynarec_opcodes_0f; } #else @@ -3037,48 +3126,47 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) } #endif - void cpu_update_waitstates(void) { cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; if (is486) - cpu_prefetch_width = 16; + cpu_prefetch_width = 16; else - cpu_prefetch_width = cpu_16bitbus ? 2 : 4; + cpu_prefetch_width = cpu_16bitbus ? 2 : 4; if (cpu_cache_int_enabled) { - /* Disable prefetch emulation */ - cpu_prefetch_cycles = 0; + /* Disable prefetch emulation */ + cpu_prefetch_cycles = 0; } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { - /* Waitstates override */ - cpu_prefetch_cycles = cpu_waitstates+1; - cpu_cycles_read = cpu_waitstates+1; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); - cpu_cycles_write = cpu_waitstates+1; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates+1); + /* Waitstates override */ + cpu_prefetch_cycles = cpu_waitstates + 1; + cpu_cycles_read = cpu_waitstates + 1; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); + cpu_cycles_write = cpu_waitstates + 1; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); } else if (cpu_cache_ext_enabled) { - /* Use cache timings */ - cpu_prefetch_cycles = cpu_s->cache_read_cycles; - cpu_cycles_read = cpu_s->cache_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; - cpu_cycles_write = cpu_s->cache_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; + /* Use cache timings */ + cpu_prefetch_cycles = cpu_s->cache_read_cycles; + cpu_cycles_read = cpu_s->cache_read_cycles; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; + cpu_cycles_write = cpu_s->cache_write_cycles; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; } else { - /* Use memory timings */ - cpu_prefetch_cycles = cpu_s->mem_read_cycles; - cpu_cycles_read = cpu_s->mem_read_cycles; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles; - cpu_cycles_write = cpu_s->mem_write_cycles; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; + /* Use memory timings */ + cpu_prefetch_cycles = cpu_s->mem_read_cycles; + cpu_cycles_read = cpu_s->mem_read_cycles; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_read_cycles; + cpu_cycles_write = cpu_s->mem_write_cycles; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; } if (is486) - cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; + cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; cpu_mem_prefetch_cycles = cpu_prefetch_cycles; if (cpu_s->rspeed <= 8000000) - cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 964c456eb..04b379127 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -19,27 +19,27 @@ * Copyright 2016,2018 Miran Grca. */ #ifndef EMU_CPU_H -# define EMU_CPU_H +#define EMU_CPU_H enum { - FPU_NONE, - FPU_8087, - FPU_287, - FPU_287XL, - FPU_387, - FPU_487SX, - FPU_INTERNAL + FPU_NONE, + FPU_8087, + FPU_287, + FPU_287XL, + FPU_387, + FPU_487SX, + FPU_INTERNAL }; enum { - CPU_8088 = 1, /* 808x class CPUs */ + CPU_8088 = 1, /* 808x class CPUs */ CPU_8086, #ifdef USE_NEC_808X - CPU_V20, /* NEC 808x class CPUs - future proofing */ + CPU_V20, /* NEC 808x class CPUs - future proofing */ CPU_V30, #endif - CPU_286, /* 286 class CPUs */ - CPU_386SX, /* 386 class CPUs */ + CPU_286, /* 286 class CPUs */ + CPU_386SX, /* 386 class CPUs */ CPU_IBM386SLC, CPU_IBM486SLC, CPU_386DX, @@ -47,7 +47,7 @@ enum { CPU_RAPIDCAD, CPU_486SLC, CPU_486DLC, - CPU_i486SX, /* 486 class CPUs */ + CPU_i486SX, /* 486 class CPUs */ CPU_Am486SX, CPU_Cx486S, CPU_i486DX, @@ -60,7 +60,7 @@ enum { CPU_ENH_Am486DX, CPU_Cx5x86, CPU_P24T, - CPU_WINCHIP, /* 586 class CPUs */ + CPU_WINCHIP, /* 586 class CPUs */ CPU_WINCHIP2, CPU_PENTIUM, CPU_PENTIUMMMX, @@ -77,43 +77,42 @@ enum { CPU_K6_2P, CPU_K6_3P, CPU_CYRIX3S, - CPU_PENTIUMPRO, /* 686 class CPUs */ + CPU_PENTIUMPRO, /* 686 class CPUs */ CPU_PENTIUM2, CPU_PENTIUM2D }; enum { - CPU_PKG_8088 = (1 << 0), - CPU_PKG_8088_EUROPC = (1 << 1), - CPU_PKG_8086 = (1 << 2), - CPU_PKG_286 = (1 << 3), - CPU_PKG_386SX = (1 << 4), - CPU_PKG_386DX = (1 << 5), - CPU_PKG_M6117 = (1 << 6), - CPU_PKG_386SLC_IBM = (1 << 7), - CPU_PKG_486SLC = (1 << 8), - CPU_PKG_486SLC_IBM = (1 << 9), - CPU_PKG_486BL = (1 << 10), - CPU_PKG_486DLC = (1 << 11), - CPU_PKG_SOCKET1 = (1 << 12), - CPU_PKG_SOCKET3 = (1 << 13), + CPU_PKG_8088 = (1 << 0), + CPU_PKG_8088_EUROPC = (1 << 1), + CPU_PKG_8086 = (1 << 2), + CPU_PKG_286 = (1 << 3), + CPU_PKG_386SX = (1 << 4), + CPU_PKG_386DX = (1 << 5), + CPU_PKG_M6117 = (1 << 6), + CPU_PKG_386SLC_IBM = (1 << 7), + CPU_PKG_486SLC = (1 << 8), + CPU_PKG_486SLC_IBM = (1 << 9), + CPU_PKG_486BL = (1 << 10), + CPU_PKG_486DLC = (1 << 11), + CPU_PKG_SOCKET1 = (1 << 12), + CPU_PKG_SOCKET3 = (1 << 13), CPU_PKG_SOCKET3_PC330 = (1 << 14), - CPU_PKG_STPC = (1 << 15), - CPU_PKG_SOCKET4 = (1 << 16), - CPU_PKG_SOCKET5_7 = (1 << 17), - CPU_PKG_SOCKET8 = (1 << 18), - CPU_PKG_SLOT1 = (1 << 19), - CPU_PKG_SLOT2 = (1 << 20), - CPU_PKG_SOCKET370 = (1 << 21), - CPU_PKG_EBGA368 = (1 << 22) + CPU_PKG_STPC = (1 << 15), + CPU_PKG_SOCKET4 = (1 << 16), + CPU_PKG_SOCKET5_7 = (1 << 17), + CPU_PKG_SOCKET8 = (1 << 18), + CPU_PKG_SLOT1 = (1 << 19), + CPU_PKG_SLOT2 = (1 << 20), + CPU_PKG_SOCKET370 = (1 << 21), + CPU_PKG_EBGA368 = (1 << 22) }; - -#define MANU_INTEL 0 -#define MANU_AMD 1 -#define MANU_CYRIX 2 -#define MANU_IDT 3 -#define MANU_NEC 4 +#define MANU_INTEL 0 +#define MANU_AMD 1 +#define MANU_CYRIX 2 +#define MANU_IDT 3 +#define MANU_NEC 4 #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 @@ -121,284 +120,278 @@ enum { #define CPU_FIXED_MULTIPLIER 8 #if (defined __amd64__ || defined _M_X64) -#define LOOKUP_INV -1LL +# define LOOKUP_INV -1LL #else -#define LOOKUP_INV -1 +# define LOOKUP_INV -1 #endif - typedef struct { - const char *name; - const char *internal_name; - const int type; + const char *name; + const char *internal_name; + const int type; } FPU; typedef struct { const char *name; - uint64_t cpu_type; + uint64_t cpu_type; const FPU *fpus; - int rspeed; - double multi; - uint16_t voltage; - uint32_t edx_reset; - uint32_t cpuid_model; - uint16_t cyrix_id; - uint8_t cpu_flags; - int8_t mem_read_cycles, mem_write_cycles; - int8_t cache_read_cycles, cache_write_cycles; - int8_t atclk_div; + int rspeed; + double multi; + uint16_t voltage; + uint32_t edx_reset; + uint32_t cpuid_model; + uint16_t cyrix_id; + uint8_t cpu_flags; + int8_t mem_read_cycles, mem_write_cycles; + int8_t cache_read_cycles, cache_write_cycles; + int8_t atclk_div; } CPU; typedef struct { - const uint32_t package; - const char *manufacturer; - const char *name; - const char *internal_name; - const CPU *cpus; + const uint32_t package; + const char *manufacturer; + const char *name; + const char *internal_name; + const CPU *cpus; } cpu_family_t; typedef struct { - const char *family; - const int rspeed; + const char *family; + const int rspeed; const double multi; } cpu_legacy_table_t; typedef struct { - const char *machine; + const char *machine; const cpu_legacy_table_t **tables; } cpu_legacy_machine_t; +#define C_FLAG 0x0001 +#define P_FLAG 0x0004 +#define A_FLAG 0x0010 +#define Z_FLAG 0x0040 +#define N_FLAG 0x0080 +#define T_FLAG 0x0100 +#define I_FLAG 0x0200 +#define D_FLAG 0x0400 +#define V_FLAG 0x0800 +#define NT_FLAG 0x4000 +#define RF_FLAG 0x0001 /* in EFLAGS */ +#define VM_FLAG 0x0002 /* in EFLAGS */ +#define VIF_FLAG 0x0008 /* in EFLAGS */ +#define VIP_FLAG 0x0010 /* in EFLAGS */ +#define VID_FLAG 0x0020 /* in EFLAGS */ -#define C_FLAG 0x0001 -#define P_FLAG 0x0004 -#define A_FLAG 0x0010 -#define Z_FLAG 0x0040 -#define N_FLAG 0x0080 -#define T_FLAG 0x0100 -#define I_FLAG 0x0200 -#define D_FLAG 0x0400 -#define V_FLAG 0x0800 -#define NT_FLAG 0x4000 +#define WP_FLAG 0x10000 /* in CR0 */ +#define CR4_VME (1 << 0) +#define CR4_PVI (1 << 1) +#define CR4_PSE (1 << 4) +#define CR4_PAE (1 << 5) -#define RF_FLAG 0x0001 /* in EFLAGS */ -#define VM_FLAG 0x0002 /* in EFLAGS */ -#define VIF_FLAG 0x0008 /* in EFLAGS */ -#define VIP_FLAG 0x0010 /* in EFLAGS */ -#define VID_FLAG 0x0020 /* in EFLAGS */ +#define CPL ((cpu_state.seg_cs.access >> 5) & 3) -#define WP_FLAG 0x10000 /* in CR0 */ -#define CR4_VME (1 << 0) -#define CR4_PVI (1 << 1) -#define CR4_PSE (1 << 4) -#define CR4_PAE (1 << 5) - -#define CPL ((cpu_state.seg_cs.access>>5)&3) - -#define IOPL ((cpu_state.flags>>12)&3) - -#define IOPLp ((!(msw&1)) || (CPL<=IOPL)) +#define IOPL ((cpu_state.flags >> 12) & 3) +#define IOPLp ((!(msw & 1)) || (CPL <= IOPL)) typedef union { - uint32_t l; - uint16_t w; + uint32_t l; + uint16_t w; struct { - uint8_t l, - h; - } b; + uint8_t l, + h; + } b; } x86reg; typedef struct { - uint32_t base; - uint32_t limit; - uint8_t access, ar_high; - uint16_t seg; - uint32_t limit_low, limit_high; - int checked; /*Non-zero if selector is known to be valid*/ + uint32_t base; + uint32_t limit; + uint8_t access, ar_high; + uint16_t seg; + uint32_t limit_low, limit_high; + int checked; /*Non-zero if selector is known to be valid*/ } x86seg; typedef union { - uint64_t q; - int64_t sq; - uint32_t l[2]; - int32_t sl[2]; - uint16_t w[4]; - int16_t sw[4]; - uint8_t b[8]; - int8_t sb[8]; - float f[2]; + uint64_t q; + int64_t sq; + uint32_t l[2]; + int32_t sl[2]; + uint16_t w[4]; + int16_t sw[4]; + uint8_t b[8]; + int8_t sb[8]; + float f[2]; } MMX_REG; typedef struct { /* IDT WinChip and WinChip 2 MSR's */ - uint32_t tr1, tr12; /* 0x00000002, 0x0000000e */ - uint32_t cesr; /* 0x00000011 */ + uint32_t tr1, tr12; /* 0x00000002, 0x0000000e */ + uint32_t cesr; /* 0x00000011 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ - uint64_t ecx79; /* 0x00000079 */ + uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ + uint64_t ecx79; /* 0x00000079 */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */ + uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */ - uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ - uint64_t mtrr_cap; /* 0x000000fe */ + uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */ + uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */ + uint64_t mtrr_cap; /* 0x000000fe */ /* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */ - uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ - uint64_t fcr2, fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ + uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */ + uint64_t fcr2, fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx116; /* 0x00000116 */ - uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */ - uint64_t ecx11e; /* 0x0000011e */ + uint64_t ecx116; /* 0x00000116 */ + uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */ + uint64_t ecx11e; /* 0x0000011e */ /* Pentium II Klamath and Pentium II Deschutes MSR's */ - uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ - uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ + uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */ + uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ + uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ + uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */ - uint64_t ecx1e0; /* 0x000001e0 */ + uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */ + uint64_t ecx1e0; /* 0x000001e0 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also on the VIA Cyrix III */ - uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */ - uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */ - uint64_t mtrr_fix64k_8000; /* 0x00000250 */ - uint64_t mtrr_fix16k_8000; /* 0x00000258 */ - uint64_t mtrr_fix16k_a000; /* 0x00000259 */ - uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */ + uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */ + uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */ + uint64_t mtrr_fix64k_8000; /* 0x00000250 */ + uint64_t mtrr_fix16k_8000; /* 0x00000258 */ + uint64_t mtrr_fix16k_a000; /* 0x00000259 */ + uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t pat; /* 0x00000277 */ + uint64_t pat; /* 0x00000277 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also on the VIA Cyrix III */ - uint64_t mtrr_deftype; /* 0x000002ff */ + uint64_t mtrr_deftype; /* 0x000002ff */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */ - uint64_t ecx570; /* 0x00000570 */ + uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */ + uint64_t ecx570; /* 0x00000570 */ /* IBM 386SLC, 486SLC, and 486BL MSR's */ - uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */ - uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */ + uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */ + uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */ /* IBM 486SLC and 486BL MSR's */ - uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ + uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ + uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_efer; /* 0xc0000080 */ + uint64_t amd_efer; /* 0xc0000080 */ /* AMD K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t star; /* 0xc0000081 */ + uint64_t star; /* 0xc0000081 */ /* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_whcr; /* 0xc0000082 */ + uint64_t amd_whcr; /* 0xc0000082 */ /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_uwccr; /* 0xc0000085 */ + uint64_t amd_uwccr; /* 0xc0000085 */ /* AMD K6-2P and K6-3P MSR's */ - uint64_t amd_epmr; /* 0xc0000086 */ + uint64_t amd_epmr; /* 0xc0000086 */ /* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_psor, amd_pfir; /* 0xc0000087, 0xc0000088 */ + uint64_t amd_psor, amd_pfir; /* 0xc0000087, 0xc0000088 */ /* K6-3, K6-2P, and K6-3P MSR's */ - uint64_t amd_l2aar; /* 0xc0000089 */ + uint64_t amd_l2aar; /* 0xc0000089 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ - uint64_t ecxf0f00258; /* 0xf0f00258 */ - uint64_t ecxf0f00259; /* 0xf0f00259 */ + uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */ + uint64_t ecxf0f00258; /* 0xf0f00258 */ + uint64_t ecxf0f00259; /* 0xf0f00259 */ } msr_t; typedef struct { - x86reg regs[8]; + x86reg regs[8]; - uint8_t tag[8]; + uint8_t tag[8]; - x86seg *ea_seg; - uint32_t eaaddr; + x86seg *ea_seg; + uint32_t eaaddr; - int flags_op; - uint32_t flags_res, - flags_op1, flags_op2; + int flags_op; + uint32_t flags_res, + flags_op1, flags_op2; - uint32_t pc, - oldpc, op32; + uint32_t pc, + oldpc, op32; - int TOP; + int TOP; union { - struct { - int8_t rm, - mod, - reg; - } rm_mod_reg; - int32_t rm_mod_reg_data; - } rm_data; + struct { + int8_t rm, + mod, + reg; + } rm_mod_reg; + int32_t rm_mod_reg_data; + } rm_data; - uint8_t ssegs, ismmx, - abrt, _smi_line; + uint8_t ssegs, ismmx, + abrt, _smi_line; #ifdef FPU_CYCLES - int _cycles, _fpu_cycles, _in_smm; + int _cycles, _fpu_cycles, _in_smm; #else - int _cycles, _in_smm; + int _cycles, _in_smm; #endif - uint16_t npxs, npxc; + uint16_t npxs, npxc; - double ST[8]; + double ST[8]; - uint16_t MM_w4[8]; + uint16_t MM_w4[8]; - MMX_REG MM[8]; + MMX_REG MM[8]; #ifdef USE_NEW_DYNAREC - uint32_t old_fp_control, new_fp_control; -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 - uint16_t old_fp_control2, new_fp_control2; -#endif -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined __amd64__ || defined _M_X64 - uint32_t trunc_fp_control; -#endif + uint32_t old_fp_control, new_fp_control; +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 + uint16_t old_fp_control2, new_fp_control2; +# endif +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined __amd64__ || defined _M_X64 + uint32_t trunc_fp_control; +# endif #else - uint16_t old_npxc, new_npxc; + uint16_t old_npxc, new_npxc; #endif - x86seg seg_cs, seg_ds, seg_es, seg_ss, - seg_fs, seg_gs; + x86seg seg_cs, seg_ds, seg_es, seg_ss, + seg_fs, seg_gs; union { - uint32_t l; - uint16_t w; - } CR0; + uint32_t l; + uint16_t w; + } CR0; - uint16_t flags, eflags; + uint16_t flags, eflags; - uint32_t _smbase; + uint32_t _smbase; } cpu_state_t; +#define in_smm cpu_state._in_smm +#define smi_line cpu_state._smi_line -#define in_smm cpu_state._in_smm -#define smi_line cpu_state._smi_line - -#define smbase cpu_state._smbase - +#define smbase cpu_state._smbase /*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block to be valid*/ @@ -407,100 +400,99 @@ typedef struct { #define CPU_STATUS_PMODE (1 << 2) #define CPU_STATUS_V86 (1 << 3) #define CPU_STATUS_SMM (1 << 4) -#define CPU_STATUS_FLAGS 0xffff +#define CPU_STATUS_FLAGS 0xffff /*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ #ifdef USE_NEW_DYNAREC -#define CPU_STATUS_NOTFLATDS (1 << 8) -#define CPU_STATUS_NOTFLATSS (1 << 9) -#define CPU_STATUS_MASK 0xff00 +# define CPU_STATUS_NOTFLATDS (1 << 8) +# define CPU_STATUS_NOTFLATSS (1 << 9) +# define CPU_STATUS_MASK 0xff00 #else -#define CPU_STATUS_NOTFLATDS (1 << 16) -#define CPU_STATUS_NOTFLATSS (1 << 17) -#define CPU_STATUS_MASK 0xffff0000 +# define CPU_STATUS_NOTFLATDS (1 << 16) +# define CPU_STATUS_NOTFLATSS (1 << 17) +# define CPU_STATUS_MASK 0xffff0000 #endif #ifdef _MSC_VER -# define COMPILE_TIME_ASSERT(expr) /*nada*/ +# define COMPILE_TIME_ASSERT(expr) /*nada*/ #else -# ifdef EXTREME_DEBUG -# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; -# else -# define COMPILE_TIME_ASSERT(expr) /*nada*/ -# endif +# ifdef EXTREME_DEBUG +# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; +# else +# define COMPILE_TIME_ASSERT(expr) /*nada*/ +# endif #endif COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128) -#define cpu_state_offset(MEMBER) ((uint8_t)((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128)) +#define cpu_state_offset(MEMBER) ((uint8_t) ((uintptr_t) &cpu_state.MEMBER - (uintptr_t) &cpu_state - 128)) -#define EAX cpu_state.regs[0].l -#define AX cpu_state.regs[0].w -#define AL cpu_state.regs[0].b.l -#define AH cpu_state.regs[0].b.h -#define ECX cpu_state.regs[1].l -#define CX cpu_state.regs[1].w -#define CL cpu_state.regs[1].b.l -#define CH cpu_state.regs[1].b.h -#define EDX cpu_state.regs[2].l -#define DX cpu_state.regs[2].w -#define DL cpu_state.regs[2].b.l -#define DH cpu_state.regs[2].b.h -#define EBX cpu_state.regs[3].l -#define BX cpu_state.regs[3].w -#define BL cpu_state.regs[3].b.l -#define BH cpu_state.regs[3].b.h -#define ESP cpu_state.regs[4].l -#define EBP cpu_state.regs[5].l -#define ESI cpu_state.regs[6].l -#define EDI cpu_state.regs[7].l -#define SP cpu_state.regs[4].w -#define BP cpu_state.regs[5].w -#define SI cpu_state.regs[6].w -#define DI cpu_state.regs[7].w +#define EAX cpu_state.regs[0].l +#define AX cpu_state.regs[0].w +#define AL cpu_state.regs[0].b.l +#define AH cpu_state.regs[0].b.h +#define ECX cpu_state.regs[1].l +#define CX cpu_state.regs[1].w +#define CL cpu_state.regs[1].b.l +#define CH cpu_state.regs[1].b.h +#define EDX cpu_state.regs[2].l +#define DX cpu_state.regs[2].w +#define DL cpu_state.regs[2].b.l +#define DH cpu_state.regs[2].b.h +#define EBX cpu_state.regs[3].l +#define BX cpu_state.regs[3].w +#define BL cpu_state.regs[3].b.l +#define BH cpu_state.regs[3].b.h +#define ESP cpu_state.regs[4].l +#define EBP cpu_state.regs[5].l +#define ESI cpu_state.regs[6].l +#define EDI cpu_state.regs[7].l +#define SP cpu_state.regs[4].w +#define BP cpu_state.regs[5].w +#define SI cpu_state.regs[6].w +#define DI cpu_state.regs[7].w -#define cycles cpu_state._cycles +#define cycles cpu_state._cycles #ifdef FPU_CYCLES -#define fpu_cycles cpu_state._fpu_cycles +# define fpu_cycles cpu_state._fpu_cycles #endif -#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm -#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod -#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg - -#define CR4_TSD (1 << 2) -#define CR4_DE (1 << 3) -#define CR4_MCE (1 << 6) -#define CR4_PCE (1 << 8) -#define CR4_OSFXSR (1 << 9) +#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm +#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod +#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg +#define CR4_TSD (1 << 2) +#define CR4_DE (1 << 3) +#define CR4_MCE (1 << 6) +#define CR4_PCE (1 << 8) +#define CR4_OSFXSR (1 << 9) /* Global variables. */ -extern cpu_state_t cpu_state; +extern cpu_state_t cpu_state; -extern const cpu_family_t cpu_families[]; +extern const cpu_family_t cpu_families[]; extern const cpu_legacy_machine_t cpu_legacy_table[]; -extern cpu_family_t *cpu_f; -extern CPU *cpu_s; -extern int cpu_override; +extern cpu_family_t *cpu_f; +extern CPU *cpu_s; +extern int cpu_override; -extern int cpu_isintel; -extern int cpu_iscyrix; -extern int cpu_16bitbus, cpu_64bitbus; -extern int cpu_busspeed, cpu_pci_speed; -extern int cpu_multi; -extern double cpu_dmulti; -extern double fpu_multi; -extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment - penalties when crossing 8-byte boundaries*/ +extern int cpu_isintel; +extern int cpu_iscyrix; +extern int cpu_16bitbus, cpu_64bitbus; +extern int cpu_busspeed, cpu_pci_speed; +extern int cpu_multi; +extern double cpu_dmulti; +extern double fpu_multi; +extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment + penalties when crossing 8-byte boundaries*/ -extern int is8086, is286, is386, is6117, is486; -extern int is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm; -extern int hascache; -extern int isibm486; -extern int is_rapidcad; -extern int hasfpu; +extern int is8086, is286, is386, is6117, is486; +extern int is_am486, is_am486dxl, is_pentium, is_k5, is_k6, is_p6, is_cxsmm; +extern int hascache; +extern int isibm486; +extern int is_rapidcad; +extern int hasfpu; #define CPU_FEATURE_RDTSC (1 << 0) #define CPU_FEATURE_MSR (1 << 1) #define CPU_FEATURE_MMX (1 << 2) @@ -509,237 +501,233 @@ extern int hasfpu; #define CPU_FEATURE_CX8 (1 << 5) #define CPU_FEATURE_3DNOW (1 << 6) -extern uint32_t cpu_features; +extern uint32_t cpu_features; -extern int smi_latched, smm_in_hlt; -extern int smi_block; +extern int smi_latched, smm_in_hlt; +extern int smi_block; #ifdef USE_NEW_DYNAREC -extern uint16_t cpu_cur_status; +extern uint16_t cpu_cur_status; #else -extern uint32_t cpu_cur_status; +extern uint32_t cpu_cur_status; #endif -extern uint64_t cpu_CR4_mask; -extern uint64_t tsc; -extern msr_t msr; -extern uint8_t opcode; -extern int cgate16; -extern int cpl_override; -extern int CPUID; -extern uint64_t xt_cpu_multi; -extern int isa_cycles, cpu_inited; -extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; -extern uint32_t pccache; -extern uint8_t *pccache2; +extern uint64_t cpu_CR4_mask; +extern uint64_t tsc; +extern msr_t msr; +extern uint8_t opcode; +extern int cgate16; +extern int cpl_override; +extern int CPUID; +extern uint64_t xt_cpu_multi; +extern int isa_cycles, cpu_inited; +extern uint32_t oldds, oldss, olddslimit, oldsslimit, olddslimitw, oldsslimitw; +extern uint32_t pccache; +extern uint8_t *pccache2; -extern double bus_timing, isa_timing, pci_timing, agp_timing; -extern uint64_t pmc[2]; -extern uint16_t temp_seg_data[4]; -extern uint16_t cs_msr; -extern uint32_t esp_msr; -extern uint32_t eip_msr; +extern double bus_timing, isa_timing, pci_timing, agp_timing; +extern uint64_t pmc[2]; +extern uint16_t temp_seg_data[4]; +extern uint16_t cs_msr; +extern uint32_t esp_msr; +extern uint32_t eip_msr; /* For the AMD K6. */ -extern uint64_t amd_efer, star; +extern uint64_t amd_efer, star; #define FPU_CW_Reserved_Bits (0xe0c0) -#define cr0 cpu_state.CR0.l -#define msw cpu_state.CR0.w -extern uint32_t cr2, cr3, cr4; -extern uint32_t dr[8]; -extern uint32_t _tr[8]; -extern uint32_t cache_index; -extern uint8_t _cache[2048]; - +#define cr0 cpu_state.CR0.l +#define msw cpu_state.CR0.w +extern uint32_t cr2, cr3, cr4; +extern uint32_t dr[8]; +extern uint32_t _tr[8]; +extern uint32_t cache_index; +extern uint8_t _cache[2048]; /*Segments - _cs,_ds,_es,_ss are the segment structures CS,DS,ES,SS is the 16-bit data cs,ds,es,ss are defines to the bases*/ -extern x86seg gdt,ldt,idt,tr; -extern x86seg _oldds; -#define CS cpu_state.seg_cs.seg -#define DS cpu_state.seg_ds.seg -#define ES cpu_state.seg_es.seg -#define SS cpu_state.seg_ss.seg -#define FS cpu_state.seg_fs.seg -#define GS cpu_state.seg_gs.seg -#define cs cpu_state.seg_cs.base -#define ds cpu_state.seg_ds.base -#define es cpu_state.seg_es.base -#define ss cpu_state.seg_ss.base -#define fs_seg cpu_state.seg_fs.base -#define gs cpu_state.seg_gs.base +extern x86seg gdt, ldt, idt, tr; +extern x86seg _oldds; +#define CS cpu_state.seg_cs.seg +#define DS cpu_state.seg_ds.seg +#define ES cpu_state.seg_es.seg +#define SS cpu_state.seg_ss.seg +#define FS cpu_state.seg_fs.seg +#define GS cpu_state.seg_gs.seg +#define cs cpu_state.seg_cs.base +#define ds cpu_state.seg_ds.base +#define es cpu_state.seg_es.base +#define ss cpu_state.seg_ss.base +#define fs_seg cpu_state.seg_fs.base +#define gs cpu_state.seg_gs.base +#define ISA_CYCLES(x) (x * isa_cycles) -#define ISA_CYCLES(x) (x * isa_cycles) +extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; +extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; +extern int cpu_waitstates; +extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; +extern int cpu_isa_speed, cpu_pci_speed, cpu_agp_speed; -extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; -extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; -extern int cpu_waitstates; -extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; -extern int cpu_isa_speed, cpu_pci_speed, cpu_agp_speed; +extern int timing_rr; +extern int timing_mr, timing_mrl; +extern int timing_rm, timing_rml; +extern int timing_mm, timing_mml; +extern int timing_bt, timing_bnt; +extern int timing_int, timing_int_rm, timing_int_v86, timing_int_pm; +extern int timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm; +extern int timing_iret_pm_outer, timing_call_rm, timing_call_pm; +extern int timing_call_pm_gate, timing_call_pm_gate_inner; +extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; +extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; +extern int timing_misaligned; -extern int timing_rr; -extern int timing_mr, timing_mrl; -extern int timing_rm, timing_rml; -extern int timing_mm, timing_mml; -extern int timing_bt, timing_bnt; -extern int timing_int, timing_int_rm, timing_int_v86, timing_int_pm; -extern int timing_int_pm_outer, timing_iret_rm, timing_iret_v86, timing_iret_pm; -extern int timing_iret_pm_outer, timing_call_rm, timing_call_pm; -extern int timing_call_pm_gate, timing_call_pm_gate_inner; -extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; -extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; -extern int timing_misaligned; - -extern int in_sys, unmask_a20_in_smm; -extern int cycles_main; -extern uint32_t old_rammask; +extern int in_sys, unmask_a20_in_smm; +extern int cycles_main; +extern uint32_t old_rammask; #ifdef USE_ACYCS -extern int acycs; +extern int acycs; #endif -extern int pic_pending, is_vpc; -extern int soft_reset_mask, alt_access; -extern int cpu_end_block_after_ins; - -extern uint16_t cpu_fast_off_count, cpu_fast_off_val; -extern uint32_t cpu_fast_off_flags; +extern int pic_pending, is_vpc; +extern int soft_reset_mask, alt_access; +extern int cpu_end_block_after_ins; +extern uint16_t cpu_fast_off_count, cpu_fast_off_val; +extern uint32_t cpu_fast_off_flags; /* Functions. */ extern int cpu_has_feature(int feature); #ifdef USE_NEW_DYNAREC -extern void loadseg_dynarec(uint16_t seg, x86seg *s); -extern int loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); +extern void loadseg_dynarec(uint16_t seg, x86seg *s); +extern int loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); #else -extern void loadseg(uint16_t seg, x86seg *s); -extern void loadcs(uint16_t seg); +extern void loadseg(uint16_t seg, x86seg *s); +extern void loadcs(uint16_t seg); #endif -extern char *cpu_current_pc(char *bufp); +extern char *cpu_current_pc(char *bufp); -extern void cpu_update_waitstates(void); -extern void cpu_set(void); -extern void cpu_close(void); -extern void cpu_set_isa_speed(int speed); -extern void cpu_set_pci_speed(int speed); -extern void cpu_set_isa_pci_div(int div); -extern void cpu_set_agp_speed(int speed); +extern void cpu_update_waitstates(void); +extern void cpu_set(void); +extern void cpu_close(void); +extern void cpu_set_isa_speed(int speed); +extern void cpu_set_pci_speed(int speed); +extern void cpu_set_isa_pci_div(int div); +extern void cpu_set_agp_speed(int speed); -extern void cpu_CPUID(void); -extern void cpu_RDMSR(void); -extern void cpu_WRMSR(void); +extern void cpu_CPUID(void); +extern void cpu_RDMSR(void); +extern void cpu_WRMSR(void); -extern int checkio(uint32_t port); -extern void codegen_block_end(void); -extern void codegen_reset(void); -extern void cpu_set_edx(void); -extern int divl(uint32_t val); -extern void execx86(int cycs); -extern void enter_smm(int in_hlt); -extern void enter_smm_check(int in_hlt); -extern void leave_smm(void); -extern void exec386(int cycs); -extern void exec386_dynarec(int cycs); -extern int idivl(int32_t val); +extern int checkio(uint32_t port); +extern void codegen_block_end(void); +extern void codegen_reset(void); +extern void cpu_set_edx(void); +extern int divl(uint32_t val); +extern void execx86(int cycs); +extern void enter_smm(int in_hlt); +extern void enter_smm_check(int in_hlt); +extern void leave_smm(void); +extern void exec386(int cycs); +extern void exec386_dynarec(int cycs); +extern int idivl(int32_t val); #ifdef USE_NEW_DYNAREC -extern void loadcscall(uint16_t seg, uint32_t old_pc); -extern void loadcsjmp(uint16_t seg, uint32_t old_pc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); +extern void loadcscall(uint16_t seg, uint32_t old_pc); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); #else -extern void loadcscall(uint16_t seg); -extern void loadcsjmp(uint16_t seg, uint32_t old_pc); -extern void pmodeint(int num, int soft); -extern void pmoderetf(int is32, uint16_t off); -extern void pmodeiret(int is32); +extern void loadcscall(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t old_pc); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); #endif -extern void resetmcr(void); -extern void resetx86(void); -extern void refreshread(void); -extern void resetreadlookup(void); -extern void softresetx86(void); -extern void hardresetx86(void); -extern void x86_int(int num); -extern void x86_int_sw(int num); -extern int x86_int_sw_rm(int num); -extern void x86de(char *s, uint16_t error); -extern void x86gpf(char *s, uint16_t error); -extern void x86np(char *s, uint16_t error); -extern void x86ss(char *s, uint16_t error); -extern void x86ts(char *s, uint16_t error); +extern void resetmcr(void); +extern void resetx86(void); +extern void refreshread(void); +extern void resetreadlookup(void); +extern void softresetx86(void); +extern void hardresetx86(void); +extern void x86_int(int num); +extern void x86_int_sw(int num); +extern int x86_int_sw_rm(int num); +extern void x86de(char *s, uint16_t error); +extern void x86gpf(char *s, uint16_t error); +extern void x86np(char *s, uint16_t error); +extern void x86ss(char *s, uint16_t error); +extern void x86ts(char *s, uint16_t error); #ifdef ENABLE_808X_LOG -extern void dumpregs(int __force); -extern void x87_dumpregs(void); -extern void x87_reset(void); +extern void dumpregs(int __force); +extern void x87_dumpregs(void); +extern void x87_reset(void); #endif -extern int cpu_effective, cpu_alt_reset; -extern void cpu_dynamic_switch(int new_cpu); +extern int cpu_effective, cpu_alt_reset; +extern void cpu_dynamic_switch(int new_cpu); -extern void cpu_ven_reset(void); -extern void update_tsc(void); +extern void cpu_ven_reset(void); +extern void update_tsc(void); -extern int sysenter(uint32_t fetchdat); -extern int sysexit(uint32_t fetchdat); -extern int syscall_op(uint32_t fetchdat); -extern int sysret(uint32_t fetchdat); +extern int sysenter(uint32_t fetchdat); +extern int sysexit(uint32_t fetchdat); +extern int syscall_op(uint32_t fetchdat); +extern int sysret(uint32_t fetchdat); extern cpu_family_t *cpu_get_family(const char *internal_name); -extern uint8_t cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine); -extern uint8_t cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine); -extern int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name); -extern const char *fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type); -extern const char *fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c); -extern int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c); +extern uint8_t cpu_is_eligible(const cpu_family_t *cpu_family, int cpu, int machine); +extern uint8_t cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine); +extern int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name); +extern const char *fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type); +extern const char *fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c); +extern int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c); void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg); void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); -#define SMHR_VALID (1 << 0) +#define SMHR_VALID (1 << 0) #define SMHR_ADDR_MASK (0xfffffffc) typedef struct { - struct - { - uint32_t base; - uint64_t size; - } arr[8]; - uint32_t smhr; + struct + { + uint32_t base; + uint64_t size; + } arr[8]; + uint32_t smhr; } cyrix_t; +extern uint32_t addr64, addr64_2; +extern uint32_t addr64a[8], addr64a_2[8]; -extern uint32_t addr64, addr64_2; -extern uint32_t addr64a[8], addr64a_2[8]; +extern int soft_reset_pci; -extern int soft_reset_pci; +extern int reset_on_hlt, hlt_reset_pending; -extern int reset_on_hlt, hlt_reset_pending; +extern cyrix_t cyrix; -extern cyrix_t cyrix; +extern uint8_t use_custom_nmi_vector; +extern uint32_t custom_nmi_vector; -extern uint8_t use_custom_nmi_vector; -extern uint32_t custom_nmi_vector; +extern void (*cpu_exec)(int cycs); +extern uint8_t do_translate, do_translate2; -extern void (*cpu_exec)(int cycs); -extern uint8_t do_translate, do_translate2; +extern void reset_808x(int hard); -extern void reset_808x(int hard); +extern void cpu_register_fast_off_handler(void *timer); +extern void cpu_fast_off_advance(void); +extern void cpu_fast_off_period_set(uint16_t vla, double period); +extern void cpu_fast_off_reset(void); -extern void cpu_register_fast_off_handler(void *timer); -extern void cpu_fast_off_advance(void); -extern void cpu_fast_off_period_set(uint16_t vla, double period); -extern void cpu_fast_off_reset(void); +extern void smi_raise(); +extern void nmi_raise(); -extern void smi_raise(); -extern void nmi_raise(); - -#endif /*EMU_CPU_H*/ +#endif /*EMU_CPU_H*/ diff --git a/src/cpu/x87_timings.c b/src/cpu/x87_timings.c index ca207cc17..d769affaf 100644 --- a/src/cpu/x87_timings.c +++ b/src/cpu/x87_timings.c @@ -10,461 +10,455 @@ x87_timings_t x87_timings; x87_timings_t x87_concurrency; -const x87_timings_t x87_timings_8087 = -{ - .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_8087 = { + .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*/ -const x87_timings_t x87_timings_287 = -{ - .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 = 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 = (2 + 8) / 2, /*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 = 3, - .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_287 = { + .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 = 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 = (2 + 8) / 2, /*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 = 3, + .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_387 = -{ - .f2xm1 = (211 + 476) / 2, - .fabs = 22, - .fadd = (23 + 34) / 2, - .fadd_32 = (24 + 32) / 2, - .fadd_64 = (29 + 37) / 2, - .fbld = (266 + 275) / 2, - .fbstp = (512 + 534) / 2, - .fchs = (24 + 25) / 2, - .fclex = 11, - .fcom = 24, - .fcom_32 = 26, - .fcom_64 = 31, - .fcos = (122 + 772) / 2, - .fincdecstp = 22, - .fdisi_eni = 2, - .fdiv = (88 + 91) / 2, - .fdiv_32 = 89, - .fdiv_64 = 94, - .ffree = 18, - .fadd_i16 = (71 + 85) / 2, - .fadd_i32 = (57 + 72) / 2, - .fcom_i16 = (71 + 75) / 2, - .fcom_i32 = (56 + 63) / 2, - .fdiv_i16 = (136 + 140) / 2, - .fdiv_i32 = (120 + 127) / 2, - .fild_16 = (61 + 65) / 2, - .fild_32 = (45 + 52) / 2, - .fild_64 = (56 + 67) / 2, - .fmul_i16 = (76 + 87) / 2, - .fmul_i32 = (61 + 82) / 2, - .finit = 33, - .fist_16 = (82 + 95) / 2, - .fist_32 = (79 + 93) / 2, - .fist_64 = (80 + 97) / 2, - .fld = 14, - .fld_32 = 20, - .fld_64 = 25, - .fld_80 = 44, - .fld_z1 = (20 + 24) / 2, - .fld_const = 40, - .fldcw = 19, - .fldenv = 71, - .fmul = (29 + 57) / 2, - .fmul_32 = (27 + 35) / 2, - .fmul_64 = (32 + 57) / 2, - .fnop = 12, - .fpatan = (314 + 487) / 2, - .fprem = (74 + 155) / 2, - .fprem1 = (95 + 185) / 2, - .fptan = (191 + 497) / 2, - .frndint = (66 + 80) / 2, - .frstor = 308, - .fsave = 375, - .fscale = (67 + 86) / 2, - .fsetpm = 12, - .fsin_cos = (122 + 771) / 2, - .fsincos = (194 + 809) / 2, - .fsqrt = (122 + 129) / 2, - .fst = 11, - .fst_32 = 44, - .fst_64 = 45, - .fst_80 = 53, - .fstcw_sw = 15, - .fstenv = 103, - .ftst = 28, - .fucom = 24, - .fwait = 6, - .fxam = (30 + 38) / 2, - .fxch = 18, - .fxtract = (70 + 76) / 2, - .fyl2x = (120 + 538) / 2, - .fyl2xp1 = (257 + 547) / 2 +const x87_timings_t x87_timings_387 = { + .f2xm1 = (211 + 476) / 2, + .fabs = 22, + .fadd = (23 + 34) / 2, + .fadd_32 = (24 + 32) / 2, + .fadd_64 = (29 + 37) / 2, + .fbld = (266 + 275) / 2, + .fbstp = (512 + 534) / 2, + .fchs = (24 + 25) / 2, + .fclex = 11, + .fcom = 24, + .fcom_32 = 26, + .fcom_64 = 31, + .fcos = (122 + 772) / 2, + .fincdecstp = 22, + .fdisi_eni = 2, + .fdiv = (88 + 91) / 2, + .fdiv_32 = 89, + .fdiv_64 = 94, + .ffree = 18, + .fadd_i16 = (71 + 85) / 2, + .fadd_i32 = (57 + 72) / 2, + .fcom_i16 = (71 + 75) / 2, + .fcom_i32 = (56 + 63) / 2, + .fdiv_i16 = (136 + 140) / 2, + .fdiv_i32 = (120 + 127) / 2, + .fild_16 = (61 + 65) / 2, + .fild_32 = (45 + 52) / 2, + .fild_64 = (56 + 67) / 2, + .fmul_i16 = (76 + 87) / 2, + .fmul_i32 = (61 + 82) / 2, + .finit = 33, + .fist_16 = (82 + 95) / 2, + .fist_32 = (79 + 93) / 2, + .fist_64 = (80 + 97) / 2, + .fld = 14, + .fld_32 = 20, + .fld_64 = 25, + .fld_80 = 44, + .fld_z1 = (20 + 24) / 2, + .fld_const = 40, + .fldcw = 19, + .fldenv = 71, + .fmul = (29 + 57) / 2, + .fmul_32 = (27 + 35) / 2, + .fmul_64 = (32 + 57) / 2, + .fnop = 12, + .fpatan = (314 + 487) / 2, + .fprem = (74 + 155) / 2, + .fprem1 = (95 + 185) / 2, + .fptan = (191 + 497) / 2, + .frndint = (66 + 80) / 2, + .frstor = 308, + .fsave = 375, + .fscale = (67 + 86) / 2, + .fsetpm = 12, + .fsin_cos = (122 + 771) / 2, + .fsincos = (194 + 809) / 2, + .fsqrt = (122 + 129) / 2, + .fst = 11, + .fst_32 = 44, + .fst_64 = 45, + .fst_80 = 53, + .fstcw_sw = 15, + .fstenv = 103, + .ftst = 28, + .fucom = 24, + .fwait = 6, + .fxam = (30 + 38) / 2, + .fxch = 18, + .fxtract = (70 + 76) / 2, + .fyl2x = (120 + 538) / 2, + .fyl2xp1 = (257 + 547) / 2 }; -const x87_timings_t x87_timings_486 = -{ - .f2xm1 = (140 + 270) / 2, - .fabs = 3, - .fadd = (8 + 20) / 2, - .fadd_32 = (8 + 20) / 2, - .fadd_64 = (8 + 20) / 2, - .fbld = (70 + 103) / 2, - .fbstp = (172 + 176) / 2, - .fchs = 6, - .fclex = 7, - .fcom = 4, - .fcom_32 = 4, - .fcom_64 = 4, - .fcos = (257 + 354) / 2, - .fincdecstp = 3, - .fdisi_eni = 3, - .fdiv = 73, - .fdiv_32 = 73, - .fdiv_64 = 73, - .ffree = 3, - .fadd_i16 = (20 + 35) / 2, - .fadd_i32 = (19 + 32) / 2, - .fcom_i16 = (16 + 20) / 2, - .fcom_i32 = (15 + 17) / 2, - .fdiv_i16 = (85 + 89) / 2, - .fdiv_i32 = (84 + 86) / 2, - .fild_16 = (13 + 16) / 2, - .fild_32 = (9 + 12) / 2, - .fild_64 = (10 + 18) / 2, - .fmul_i16 = (23 + 27) / 2, - .fmul_i32 = (22 + 24) / 2, - .finit = 17, - .fist_16 = (29 + 34) / 2, - .fist_32 = (28 + 34) / 2, - .fist_64 = (29 + 34) / 2, - .fld = 4, - .fld_32 = 3, - .fld_64 = 3, - .fld_80 = 6, - .fld_z1 = 4, - .fld_const = 8, - .fldcw = 4, - .fldenv = 34, - .fmul = 16, - .fmul_32 = 11, - .fmul_64 = 14, - .fnop = 3, - .fpatan = (218 + 303) / 2, - .fprem = (70 + 138) / 2, - .fprem1 = (72 + 167) / 2, - .fptan = (200 + 273) / 2, - .frndint = (21 + 30) / 2, - .frstor = 120, - .fsave = 143, - .fscale = (30 + 32) / 2, - .fsetpm = 3, - .fsin_cos = (257 + 354) / 2, - .fsincos = (292 + 365) / 2, - .fsqrt = (83 + 87) / 2, - .fst = 3, - .fst_32 = 7, - .fst_64 = 8, - .fst_80 = 6, - .fstcw_sw = 3, - .fstenv = 56, - .ftst = 4, - .fucom = 4, - .fwait = (1 + 3) / 2, - .fxam = 8, - .fxch = 4, - .fxtract = (16 + 20) / 2, - .fyl2x = (196 + 329) / 2, - .fyl2xp1 = (171 + 326) / 2 +const x87_timings_t x87_timings_486 = { + .f2xm1 = (140 + 270) / 2, + .fabs = 3, + .fadd = (8 + 20) / 2, + .fadd_32 = (8 + 20) / 2, + .fadd_64 = (8 + 20) / 2, + .fbld = (70 + 103) / 2, + .fbstp = (172 + 176) / 2, + .fchs = 6, + .fclex = 7, + .fcom = 4, + .fcom_32 = 4, + .fcom_64 = 4, + .fcos = (257 + 354) / 2, + .fincdecstp = 3, + .fdisi_eni = 3, + .fdiv = 73, + .fdiv_32 = 73, + .fdiv_64 = 73, + .ffree = 3, + .fadd_i16 = (20 + 35) / 2, + .fadd_i32 = (19 + 32) / 2, + .fcom_i16 = (16 + 20) / 2, + .fcom_i32 = (15 + 17) / 2, + .fdiv_i16 = (85 + 89) / 2, + .fdiv_i32 = (84 + 86) / 2, + .fild_16 = (13 + 16) / 2, + .fild_32 = (9 + 12) / 2, + .fild_64 = (10 + 18) / 2, + .fmul_i16 = (23 + 27) / 2, + .fmul_i32 = (22 + 24) / 2, + .finit = 17, + .fist_16 = (29 + 34) / 2, + .fist_32 = (28 + 34) / 2, + .fist_64 = (29 + 34) / 2, + .fld = 4, + .fld_32 = 3, + .fld_64 = 3, + .fld_80 = 6, + .fld_z1 = 4, + .fld_const = 8, + .fldcw = 4, + .fldenv = 34, + .fmul = 16, + .fmul_32 = 11, + .fmul_64 = 14, + .fnop = 3, + .fpatan = (218 + 303) / 2, + .fprem = (70 + 138) / 2, + .fprem1 = (72 + 167) / 2, + .fptan = (200 + 273) / 2, + .frndint = (21 + 30) / 2, + .frstor = 120, + .fsave = 143, + .fscale = (30 + 32) / 2, + .fsetpm = 3, + .fsin_cos = (257 + 354) / 2, + .fsincos = (292 + 365) / 2, + .fsqrt = (83 + 87) / 2, + .fst = 3, + .fst_32 = 7, + .fst_64 = 8, + .fst_80 = 6, + .fstcw_sw = 3, + .fstenv = 56, + .ftst = 4, + .fucom = 4, + .fwait = (1 + 3) / 2, + .fxam = 8, + .fxch = 4, + .fxtract = (16 + 20) / 2, + .fyl2x = (196 + 329) / 2, + .fyl2xp1 = (171 + 326) / 2 }; /* this should be used for FPUs with no concurrency. some pre-486DX Cyrix FPUs reportedly are like this. */ -const x87_timings_t x87_concurrency_none = -{ - .f2xm1 = 0, - .fabs = 0, - .fadd = 0, - .fadd_32 = 0, - .fadd_64 = 0, - .fbld = 0, - .fbstp = 0, - .fchs = 0, - .fclex = 0, - .fcom = 0, - .fcom_32 = 0, - .fcom_64 = 0, - .fcos = 0, - .fincdecstp = 0, - .fdisi_eni = 0, - .fdiv = 0, - .fdiv_32 = 0, - .fdiv_64 = 0, - .ffree = 0, - .fadd_i16 = 0, - .fadd_i32 = 0, - .fcom_i16 = 0, - .fcom_i32 = 0, - .fdiv_i16 = 0, - .fdiv_i32 = 0, - .fild_16 = 0, - .fild_32 = 0, - .fild_64 = 0, - .fmul_i16 = 0, - .fmul_i32 = 0, - .finit = 0, - .fist_16 = 0, - .fist_32 = 0, - .fist_64 = 0, - .fld = 0, - .fld_32 = 0, - .fld_64 = 0, - .fld_80 = 0, - .fld_z1 = 0, - .fld_const = 0, - .fldcw = 0, - .fldenv = 0, - .fmul = 0, - .fmul_32 = 0, - .fmul_64 = 0, - .fnop = 0, - .fpatan = 0, - .fprem = 0, - .fprem1 = 0, - .fptan = 0, - .frndint = 0, - .frstor = 0, - .fsave = 0, - .fscale = 0, - .fsetpm = 0, - .fsin_cos = 0, - .fsincos = 0, - .fsqrt = 0, - .fst = 0, - .fst_32 = 0, - .fst_64 = 0, - .fst_80 = 0, - .fstcw_sw = 0, - .fstenv = 0, - .ftst = 0, - .fucom = 0, - .fwait = 0, - .fxam = 0, - .fxch = 0, - .fxtract = 0, - .fyl2x = 0, - .fyl2xp1 = 0, +const x87_timings_t x87_concurrency_none = { + .f2xm1 = 0, + .fabs = 0, + .fadd = 0, + .fadd_32 = 0, + .fadd_64 = 0, + .fbld = 0, + .fbstp = 0, + .fchs = 0, + .fclex = 0, + .fcom = 0, + .fcom_32 = 0, + .fcom_64 = 0, + .fcos = 0, + .fincdecstp = 0, + .fdisi_eni = 0, + .fdiv = 0, + .fdiv_32 = 0, + .fdiv_64 = 0, + .ffree = 0, + .fadd_i16 = 0, + .fadd_i32 = 0, + .fcom_i16 = 0, + .fcom_i32 = 0, + .fdiv_i16 = 0, + .fdiv_i32 = 0, + .fild_16 = 0, + .fild_32 = 0, + .fild_64 = 0, + .fmul_i16 = 0, + .fmul_i32 = 0, + .finit = 0, + .fist_16 = 0, + .fist_32 = 0, + .fist_64 = 0, + .fld = 0, + .fld_32 = 0, + .fld_64 = 0, + .fld_80 = 0, + .fld_z1 = 0, + .fld_const = 0, + .fldcw = 0, + .fldenv = 0, + .fmul = 0, + .fmul_32 = 0, + .fmul_64 = 0, + .fnop = 0, + .fpatan = 0, + .fprem = 0, + .fprem1 = 0, + .fptan = 0, + .frndint = 0, + .frstor = 0, + .fsave = 0, + .fscale = 0, + .fsetpm = 0, + .fsin_cos = 0, + .fsincos = 0, + .fsqrt = 0, + .fst = 0, + .fst_32 = 0, + .fst_64 = 0, + .fst_80 = 0, + .fstcw_sw = 0, + .fstenv = 0, + .ftst = 0, + .fucom = 0, + .fwait = 0, + .fxam = 0, + .fxch = 0, + .fxtract = 0, + .fyl2x = 0, + .fyl2xp1 = 0, }; -const x87_timings_t x87_concurrency_486 = -{ - .f2xm1 = 2, - .fabs = 0, - .fadd = 7, - .fadd_32 = 7, - .fadd_64 = 7, - .fbld = 8, - .fbstp = 0, - .fchs = 0, - .fclex = 0, - .fcom = 1, - .fcom_32 = 1, - .fcom_64 = 1, - .fcos = 2, - .fincdecstp = 0, - .fdisi_eni = 0, - .fdiv = 70, - .fdiv_32 = 70, - .fdiv_64 = 70, - .ffree = 0, - .fadd_i16 = 7, - .fadd_i32 = 7, - .fcom_i16 = 1, - .fcom_i32 = 1, - .fdiv_i16 = 70, - .fdiv_i32 = 70, - .fild_16 = 4, - .fild_32 = 4, - .fild_64 = 8, - .fmul_i16 = 8, - .fmul_i32 = 8, - .finit = 0, - .fist_16 = 0, - .fist_32 = 0, - .fist_64 = 0, - .fld = 0, - .fld_32 = 0, - .fld_64 = 0, - .fld_80 = 0, - .fld_z1 = 0, - .fld_const = 2, - .fldcw = 0, - .fldenv = 0, - .fmul = 13, - .fmul_32 = 8, - .fmul_64 = 11, - .fnop = 0, - .fpatan = 5, - .fprem = 2, - .fprem1 = 6, - .fptan = 70, - .frndint = 0, - .frstor = 0, - .fsave = 0, - .fscale = 2, - .fsetpm = 0, - .fsin_cos = 2, - .fsincos = 2, - .fsqrt = 70, - .fst = 0, - .fst_32 = 0, - .fst_64 = 0, - .fst_80 = 0, - .fstcw_sw = 0, - .fstenv = 0, - .ftst = 1, - .fucom = 1, - .fwait = 0, - .fxam = 0, - .fxch = 0, - .fxtract = 4, - .fyl2x = 13, - .fyl2xp1 = 13, +const x87_timings_t x87_concurrency_486 = { + .f2xm1 = 2, + .fabs = 0, + .fadd = 7, + .fadd_32 = 7, + .fadd_64 = 7, + .fbld = 8, + .fbstp = 0, + .fchs = 0, + .fclex = 0, + .fcom = 1, + .fcom_32 = 1, + .fcom_64 = 1, + .fcos = 2, + .fincdecstp = 0, + .fdisi_eni = 0, + .fdiv = 70, + .fdiv_32 = 70, + .fdiv_64 = 70, + .ffree = 0, + .fadd_i16 = 7, + .fadd_i32 = 7, + .fcom_i16 = 1, + .fcom_i32 = 1, + .fdiv_i16 = 70, + .fdiv_i32 = 70, + .fild_16 = 4, + .fild_32 = 4, + .fild_64 = 8, + .fmul_i16 = 8, + .fmul_i32 = 8, + .finit = 0, + .fist_16 = 0, + .fist_32 = 0, + .fist_64 = 0, + .fld = 0, + .fld_32 = 0, + .fld_64 = 0, + .fld_80 = 0, + .fld_z1 = 0, + .fld_const = 2, + .fldcw = 0, + .fldenv = 0, + .fmul = 13, + .fmul_32 = 8, + .fmul_64 = 11, + .fnop = 0, + .fpatan = 5, + .fprem = 2, + .fprem1 = 6, + .fptan = 70, + .frndint = 0, + .frstor = 0, + .fsave = 0, + .fscale = 2, + .fsetpm = 0, + .fsin_cos = 2, + .fsincos = 2, + .fsqrt = 70, + .fst = 0, + .fst_32 = 0, + .fst_64 = 0, + .fst_80 = 0, + .fstcw_sw = 0, + .fstenv = 0, + .ftst = 1, + .fucom = 1, + .fwait = 0, + .fxam = 0, + .fxch = 0, + .fxtract = 4, + .fyl2x = 13, + .fyl2xp1 = 13, }; diff --git a/src/cpu/x87_timings.h b/src/cpu/x87_timings.h index 6396fcb06..ad16231db 100644 --- a/src/cpu/x87_timings.h +++ b/src/cpu/x87_timings.h @@ -1,51 +1,51 @@ typedef struct { - int f2xm1; - int fabs; - int fadd, fadd_32, fadd_64; - int fbld; - int fbstp; - int fchs; - int fclex; - int fcom, fcom_32, fcom_64; - int fcos; - int fincdecstp; - int fdisi_eni; - int fdiv, fdiv_32, fdiv_64; - int ffree; - int fadd_i16, fadd_i32; - int fcom_i16, fcom_i32; - int fdiv_i16, fdiv_i32; - int fild_16, fild_32, fild_64; - int fmul_i16, fmul_i32; - int finit; - int fist_16, fist_32, fist_64; - int fld, fld_32, fld_64, fld_80; - int fld_z1, fld_const; - int fldcw; - int fldenv; - int fmul, fmul_32, fmul_64; - int fnop; - int fpatan; - int fprem, fprem1; - int fptan; - int frndint; - int frstor; - int fsave; - int fscale; - int fsetpm; - int fsin_cos, fsincos; - int fsqrt; - int fst, fst_32, fst_64, fst_80; - int fstcw_sw; - int fstenv; - int ftst; - int fucom; - int fwait; - int fxam; - int fxch; - int fxtract; - int fyl2x, fyl2xp1; + int f2xm1; + int fabs; + int fadd, fadd_32, fadd_64; + int fbld; + int fbstp; + int fchs; + int fclex; + int fcom, fcom_32, fcom_64; + int fcos; + int fincdecstp; + int fdisi_eni; + int fdiv, fdiv_32, fdiv_64; + int ffree; + int fadd_i16, fadd_i32; + int fcom_i16, fcom_i32; + int fdiv_i16, fdiv_i32; + int fild_16, fild_32, fild_64; + int fmul_i16, fmul_i32; + int finit; + int fist_16, fist_32, fist_64; + int fld, fld_32, fld_64, fld_80; + int fld_z1, fld_const; + int fldcw; + int fldenv; + int fmul, fmul_32, fmul_64; + int fnop; + int fpatan; + int fprem, fprem1; + int fptan; + int frndint; + int frstor; + int fsave; + int fscale; + int fsetpm; + int fsin_cos, fsincos; + int fsqrt; + int fst, fst_32, fst_64, fst_80; + int fstcw_sw; + int fstenv; + int ftst; + int fucom; + int fwait; + int fxam; + int fxch; + int fxtract; + int fyl2x, fyl2xp1; } x87_timings_t; extern const x87_timings_t x87_timings_8087;