Fixed SMM, overhauled the emulation of the VIA northbridges, and added the Via Apollo VP3.
This commit is contained in:
@@ -234,6 +234,10 @@ exec386(int cycs)
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
#ifdef ENABLE_386_LOG
|
||||
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;
|
||||
@@ -242,7 +246,11 @@ exec386(int cycs)
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
} else
|
||||
#ifdef ENABLE_386_LOG
|
||||
if (in_smm)
|
||||
x386_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
|
||||
#endif
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
@@ -272,12 +280,25 @@ exec386(int cycs)
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_smm && smi_line/* && is_pentium*/) {
|
||||
if ((in_smm == 0) && smi_line) {
|
||||
#ifdef ENABLE_386_LOG
|
||||
x386_log("SMI while not in SMM\n");
|
||||
#endif
|
||||
enter_smm();
|
||||
smi_line = 0;
|
||||
} else if (in_smm && smi_line/* && is_pentium*/) {
|
||||
} else if ((in_smm == 1) && smi_line) {
|
||||
/* Mark this so that we don't latch more than one SMI. */
|
||||
#ifdef ENABLE_386_LOG
|
||||
x386_log("SMI while in unlatched SMM\n");
|
||||
#endif
|
||||
smi_latched = 1;
|
||||
smi_line = 0;
|
||||
} else if ((in_smm == 2) && smi_line) {
|
||||
/* Mark this so that we don't latch more than one SMI. */
|
||||
#ifdef ENABLE_386_LOG
|
||||
x386_log("SMI while in latched SMM\n");
|
||||
#endif
|
||||
smi_line = 0;
|
||||
}
|
||||
|
||||
ins_cycles -= cycles;
|
||||
|
||||
@@ -1,910 +0,0 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
#endif
|
||||
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#ifdef USE_DYNAREC
|
||||
#include "codegen.h"
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#include "codegen_backend.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
|
||||
int inrecomp = 0, cpu_block_end = 0;
|
||||
int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
|
||||
|
||||
|
||||
void
|
||||
x386_dynarec_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (x386_dynarec_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define x386_dynarec_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (cpu_rm == 4)
|
||||
{
|
||||
uint8_t sib = rmdat >> 8;
|
||||
|
||||
switch (cpu_mod)
|
||||
{
|
||||
case 0:
|
||||
cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
|
||||
cpu_state.pc++;
|
||||
break;
|
||||
case 1:
|
||||
cpu_state.pc++;
|
||||
cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
|
||||
cpu_state.pc += 5;
|
||||
break;
|
||||
}
|
||||
/*SIB byte present*/
|
||||
if ((sib & 7) == 5 && !cpu_mod)
|
||||
cpu_state.eaaddr = getlong();
|
||||
else if ((sib & 6) == 4 && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_mod)
|
||||
{
|
||||
if (cpu_rm == 5 && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (cpu_mod == 1)
|
||||
{
|
||||
cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
|
||||
cpu_state.pc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.eaaddr += getlong();
|
||||
}
|
||||
}
|
||||
else if (cpu_rm == 5)
|
||||
{
|
||||
cpu_state.eaaddr = getlong();
|
||||
}
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if ( readlookup2[addr >> 12] != -1)
|
||||
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (!cpu_mod && cpu_rm == 6)
|
||||
{
|
||||
cpu_state.eaaddr = getword();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cpu_mod)
|
||||
{
|
||||
case 0:
|
||||
cpu_state.eaaddr = 0;
|
||||
break;
|
||||
case 1:
|
||||
cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.eaaddr = getword();
|
||||
break;
|
||||
}
|
||||
cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
|
||||
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
cpu_state.eaaddr &= 0xFFFF;
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if ( readlookup2[addr >> 12] != -1)
|
||||
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
|
||||
#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1
|
||||
|
||||
#include "x86_flags.h"
|
||||
|
||||
|
||||
/*Prefetch emulation is a fairly simplistic model:
|
||||
- All instruction bytes must be fetched before it starts.
|
||||
- Cycles used for non-instruction memory accesses are counted and subtracted
|
||||
from the total cycles taken
|
||||
- Any remaining cycles are used to refill the prefetch queue.
|
||||
|
||||
Note that this is only used for 286 / 386 systems. It is disabled when the
|
||||
internal cache on 486+ CPUs is enabled.
|
||||
*/
|
||||
static int prefetch_bytes = 0;
|
||||
static int prefetch_prefixes = 0;
|
||||
|
||||
static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
|
||||
{
|
||||
int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l;
|
||||
|
||||
if (instr_cycles < mem_cycles)
|
||||
instr_cycles = mem_cycles;
|
||||
|
||||
prefetch_bytes -= prefetch_prefixes;
|
||||
prefetch_bytes -= bytes;
|
||||
if (modrm != -1)
|
||||
{
|
||||
if (ea32)
|
||||
{
|
||||
if ((modrm & 7) == 4)
|
||||
{
|
||||
if ((modrm & 0x700) == 0x500)
|
||||
prefetch_bytes -= 5;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x05)
|
||||
prefetch_bytes -= 4;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes--;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x06)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) != 0xc0)
|
||||
prefetch_bytes -= ((modrm & 0xc0) >> 6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill up prefetch queue */
|
||||
while (prefetch_bytes < 0)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
/* Subtract cycles used for memory access by instruction */
|
||||
instr_cycles -= mem_cycles;
|
||||
|
||||
while (instr_cycles >= cpu_prefetch_cycles)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
instr_cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
prefetch_prefixes = 0;
|
||||
if (prefetch_bytes > 16)
|
||||
prefetch_bytes = 16;
|
||||
}
|
||||
|
||||
static void prefetch_flush()
|
||||
{
|
||||
prefetch_bytes = 0;
|
||||
}
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
|
||||
do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0)
|
||||
|
||||
#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0)
|
||||
#define PREFETCH_FLUSH() prefetch_flush()
|
||||
|
||||
|
||||
void enter_smm()
|
||||
{
|
||||
uint32_t smram_state = smbase + 0xfe00;
|
||||
uint32_t old_cr0 = cr0;
|
||||
uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16);
|
||||
|
||||
cr0 &= ~0x8000000d;
|
||||
cpu_state.flags = 2;
|
||||
cpu_state.eflags = 0;
|
||||
|
||||
in_smm = 1;
|
||||
mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
smi_latched = 1;
|
||||
|
||||
mem_writel_phys(smram_state + 0xf8, smbase);
|
||||
mem_writel_phys(smram_state + 0x128, cr4);
|
||||
mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit);
|
||||
mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base);
|
||||
mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access);
|
||||
mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit);
|
||||
mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base);
|
||||
mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access);
|
||||
mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit);
|
||||
mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base);
|
||||
mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access);
|
||||
mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit);
|
||||
mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base);
|
||||
mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access);
|
||||
mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit);
|
||||
mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base);
|
||||
mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access);
|
||||
mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit);
|
||||
mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base);
|
||||
mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access);
|
||||
mem_writel_phys(smram_state + 0x178, ldt.limit);
|
||||
mem_writel_phys(smram_state + 0x17c, ldt.base);
|
||||
mem_writel_phys(smram_state + 0x180, ldt.access);
|
||||
mem_writel_phys(smram_state + 0x184, gdt.limit);
|
||||
mem_writel_phys(smram_state + 0x188, gdt.base);
|
||||
mem_writel_phys(smram_state + 0x18c, gdt.access);
|
||||
mem_writel_phys(smram_state + 0x190, idt.limit);
|
||||
mem_writel_phys(smram_state + 0x194, idt.base);
|
||||
mem_writel_phys(smram_state + 0x198, idt.access);
|
||||
mem_writel_phys(smram_state + 0x19c, tr.limit);
|
||||
mem_writel_phys(smram_state + 0x1a0, tr.base);
|
||||
mem_writel_phys(smram_state + 0x1a4, tr.access);
|
||||
|
||||
mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg);
|
||||
mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg);
|
||||
mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg);
|
||||
mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg);
|
||||
mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg);
|
||||
mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg);
|
||||
mem_writel_phys(smram_state + 0x1c0, ldt.seg);
|
||||
mem_writel_phys(smram_state + 0x1c4, tr.seg);
|
||||
|
||||
mem_writel_phys(smram_state + 0x1c8, dr[7]);
|
||||
mem_writel_phys(smram_state + 0x1cc, dr[6]);
|
||||
mem_writel_phys(smram_state + 0x1d0, EAX);
|
||||
mem_writel_phys(smram_state + 0x1d4, ECX);
|
||||
mem_writel_phys(smram_state + 0x1d8, EDX);
|
||||
mem_writel_phys(smram_state + 0x1dc, EBX);
|
||||
mem_writel_phys(smram_state + 0x1e0, ESP);
|
||||
mem_writel_phys(smram_state + 0x1e4, EBP);
|
||||
mem_writel_phys(smram_state + 0x1e8, ESI);
|
||||
mem_writel_phys(smram_state + 0x1ec, EDI);
|
||||
mem_writel_phys(smram_state + 0x1f0, cpu_state.pc);
|
||||
mem_writel_phys(smram_state + 0x1d0, old_flags);
|
||||
mem_writel_phys(smram_state + 0x1f8, cr3);
|
||||
mem_writel_phys(smram_state + 0x1fc, old_cr0);
|
||||
|
||||
ds = es = fs_seg = gs = ss = 0;
|
||||
|
||||
DS = ES = FS = GS = SS = 0;
|
||||
|
||||
cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit
|
||||
= cpu_state.seg_ss.limit = 0xffffffff;
|
||||
|
||||
cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high
|
||||
= cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff;
|
||||
|
||||
cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low
|
||||
= cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0;
|
||||
|
||||
cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access
|
||||
= cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93;
|
||||
|
||||
cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked
|
||||
= cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
|
||||
|
||||
CS = 0x3000;
|
||||
cs = smbase;
|
||||
cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.access = 0x93;
|
||||
cpu_state.seg_cs.checked = 1;
|
||||
|
||||
cr4 = 0;
|
||||
dr[7] = 0x400;
|
||||
cpu_state.pc = 0x8000;
|
||||
|
||||
nmi_mask = 0;
|
||||
}
|
||||
|
||||
void leave_smm()
|
||||
{
|
||||
uint32_t smram_state = smbase + 0xfe00;
|
||||
|
||||
smbase = mem_readl_phys(smram_state + 0xf8);
|
||||
cr4 = mem_readl_phys(smram_state + 0x128);
|
||||
|
||||
cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130);
|
||||
cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134);
|
||||
cpu_state.seg_es.limit_low = cpu_state.seg_es.base;
|
||||
cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138);
|
||||
|
||||
cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c);
|
||||
cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140);
|
||||
cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base;
|
||||
cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144);
|
||||
|
||||
cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148);
|
||||
cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c);
|
||||
cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base;
|
||||
cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150);
|
||||
|
||||
cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154);
|
||||
cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158);
|
||||
cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base;
|
||||
cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c);
|
||||
|
||||
cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160);
|
||||
cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164);
|
||||
cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base;
|
||||
cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168);
|
||||
|
||||
cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c);
|
||||
cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170);
|
||||
cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base;
|
||||
cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174);
|
||||
|
||||
ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178);
|
||||
ldt.base = mem_readl_phys(smram_state + 0x17c);
|
||||
ldt.limit_low = ldt.base;
|
||||
ldt.access = mem_readl_phys(smram_state + 0x180);
|
||||
|
||||
gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184);
|
||||
gdt.base = mem_readl_phys(smram_state + 0x188);
|
||||
gdt.limit_low = gdt.base;
|
||||
gdt.access = mem_readl_phys(smram_state + 0x18c);
|
||||
|
||||
idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190);
|
||||
idt.base = mem_readl_phys(smram_state + 0x194);
|
||||
idt.limit_low = idt.base;
|
||||
idt.access = mem_readl_phys(smram_state + 0x198);
|
||||
|
||||
tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c);
|
||||
tr.base = mem_readl_phys(smram_state + 0x1a0);
|
||||
tr.limit_low = tr.base;
|
||||
tr.access = mem_readl_phys(smram_state + 0x1a4);
|
||||
|
||||
ES = mem_readl_phys(smram_state + 0x1a8);
|
||||
CS = mem_readl_phys(smram_state + 0x1ac);
|
||||
SS = mem_readl_phys(smram_state + 0x1b0);
|
||||
DS = mem_readl_phys(smram_state + 0x1b4);
|
||||
FS = mem_readl_phys(smram_state + 0x1b8);
|
||||
GS = mem_readl_phys(smram_state + 0x1bc);
|
||||
ldt.seg = mem_readl_phys(smram_state + 0x1c0);
|
||||
tr.seg = mem_readl_phys(smram_state + 0x1c4);
|
||||
|
||||
dr[7] = mem_readl_phys(smram_state + 0x1c8);
|
||||
dr[6] = mem_readl_phys(smram_state + 0x1cc);
|
||||
EAX = mem_readl_phys(smram_state + 0x1d0);
|
||||
ECX = mem_readl_phys(smram_state + 0x1d4);
|
||||
EDX = mem_readl_phys(smram_state + 0x1d8);
|
||||
EBX = mem_readl_phys(smram_state + 0x1dc);
|
||||
ESP = mem_readl_phys(smram_state + 0x1e0);
|
||||
EBP = mem_readl_phys(smram_state + 0x1e4);
|
||||
ESI = mem_readl_phys(smram_state + 0x1e8);
|
||||
EDI = mem_readl_phys(smram_state + 0x1ec);
|
||||
|
||||
cpu_state.pc = mem_readl_phys(smram_state + 0x1f0);
|
||||
uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4);
|
||||
cpu_state.flags = new_flags & 0xffff;
|
||||
cpu_state.eflags = new_flags >> 16;
|
||||
cr3 = mem_readl_phys(smram_state + 0x1f8);
|
||||
cr0 = mem_readl_phys(smram_state + 0x1fc);
|
||||
|
||||
cpu_state.seg_cs.access &= ~0x60;
|
||||
cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss
|
||||
|
||||
if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
cpu_state.seg_cs.checked = CS ? 1 : 0;
|
||||
cpu_state.seg_ds.checked = DS ? 1 : 0;
|
||||
cpu_state.seg_es.checked = ES ? 1 : 0;
|
||||
cpu_state.seg_fs.checked = FS ? 1 : 0;
|
||||
cpu_state.seg_gs.checked = GS ? 1 : 0;
|
||||
cpu_state.seg_ss.checked = SS ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked
|
||||
= cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
|
||||
}
|
||||
|
||||
mem_restore_mem_state(smbase, 131072);
|
||||
in_smm = 0;
|
||||
|
||||
nmi_mask = 1;
|
||||
}
|
||||
|
||||
#define OP_TABLE(name) ops_ ## name
|
||||
#define CLOCK_CYCLES(c) cycles -= (c)
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
#include "386_ops.h"
|
||||
|
||||
|
||||
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
static int cycles_main = 0;
|
||||
|
||||
|
||||
void exec386_dynarec(int cycs)
|
||||
{
|
||||
int vector;
|
||||
uint32_t addr;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
int oldcyc;
|
||||
uint32_t start_pc = 0;
|
||||
|
||||
int cyc_period = cycs / 2000; /*5us*/
|
||||
|
||||
cycles_main += cycs;
|
||||
while (cycles_main > 0)
|
||||
{
|
||||
int cycles_start;
|
||||
|
||||
cycles += cyc_period;
|
||||
cycles_start = cycles;
|
||||
|
||||
while (cycles>0)
|
||||
{
|
||||
oldcs = CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
|
||||
cycdiff=0;
|
||||
oldcyc=cycles;
|
||||
if (!CACHE_ON()) /*Interpret block*/
|
||||
{
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
oldcs=CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
}
|
||||
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
|
||||
if (((cs + cpu_state.pc) >> 12) != pccache)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
/* if (ssegs)
|
||||
{
|
||||
ds=oldds;
|
||||
ss=oldss;
|
||||
ssegs=0;
|
||||
}*/
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
CPU_BLOCK_END();
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
ins++;
|
||||
|
||||
/* if ((cs + pc) == 4)
|
||||
fatal("4\n");*/
|
||||
/* if (ins >= 141400000)
|
||||
output = 3;*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t phys_addr = get_phys(cs+cpu_state.pc);
|
||||
int hash = HASH(phys_addr);
|
||||
codeblock_t *block = codeblock_hash[hash];
|
||||
int valid_block = 0;
|
||||
trap = 0;
|
||||
|
||||
if (block && !cpu_state.abrt)
|
||||
{
|
||||
page_t *page = &pages[phys_addr >> 12];
|
||||
|
||||
/*Block must match current CS, PC, code segment size,
|
||||
and physical address. The physical address check will
|
||||
also catch any page faults at this stage*/
|
||||
valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
|
||||
(block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
|
||||
if (!valid_block)
|
||||
{
|
||||
uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
|
||||
if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask)
|
||||
{
|
||||
/*Walk page tree to see if we find the correct block*/
|
||||
codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
|
||||
if (new_block)
|
||||
{
|
||||
valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
|
||||
(new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
|
||||
if (valid_block)
|
||||
block = new_block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_block && (block->page_mask & *block->dirty_mask))
|
||||
{
|
||||
codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr);
|
||||
page->dirty_mask[(phys_addr >> 10) & 3] = 0;
|
||||
if (!block->valid)
|
||||
valid_block = 0;
|
||||
}
|
||||
if (valid_block && block->page_mask2)
|
||||
{
|
||||
/*We don't want the second page to cause a page
|
||||
fault at this stage - that would break any
|
||||
code crossing a page boundary where the first
|
||||
page is present but the second isn't. Instead
|
||||
allow the first page to be interpreted and for
|
||||
the page fault to occur when the page boundary
|
||||
is actually crossed.*/
|
||||
uint32_t phys_addr_2 = get_phys_noabrt(block->endpc);
|
||||
page_t *page_2 = &pages[phys_addr_2 >> 12];
|
||||
|
||||
if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
|
||||
valid_block = 0;
|
||||
else if (block->page_mask2 & *block->dirty_mask2)
|
||||
{
|
||||
codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2);
|
||||
page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0;
|
||||
if (!block->valid)
|
||||
valid_block = 0;
|
||||
}
|
||||
}
|
||||
if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP)
|
||||
{
|
||||
/*FPU top-of-stack does not match the value this block was compiled
|
||||
with, re-compile using dynamic top-of-stack*/
|
||||
block->flags &= ~CODEBLOCK_STATIC_TOP;
|
||||
block->was_recompiled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_block && block->was_recompiled)
|
||||
{
|
||||
void (*code)() = (void *)&block->data[BLOCK_START];
|
||||
|
||||
codeblock_hash[hash] = block;
|
||||
|
||||
inrecomp=1;
|
||||
code();
|
||||
inrecomp=0;
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
cpu_recomp_blocks++;
|
||||
}
|
||||
else if (valid_block && !cpu_state.abrt)
|
||||
{
|
||||
start_pc = cpu_state.pc;
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
cpu_new_blocks++;
|
||||
|
||||
codegen_block_start_recompile(block);
|
||||
codegen_in_recompile = 1;
|
||||
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
oldcs=CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
|
||||
codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
|
||||
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
|
||||
/*Cap source code at 4000 bytes per block; this
|
||||
will prevent any block from spanning more than
|
||||
2 pages. In practice this limit will never be
|
||||
hit, as host block size is only 2kB*/
|
||||
if ((cpu_state.pc - start_pc) > 1000)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
codegen_block_end_recompile(block);
|
||||
|
||||
if (x86_was_reset)
|
||||
codegen_reset();
|
||||
|
||||
codegen_in_recompile = 0;
|
||||
}
|
||||
else if (!cpu_state.abrt)
|
||||
{
|
||||
/*Mark block but do not recompile*/
|
||||
start_pc = cpu_state.pc;
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
codegen_block_init(phys_addr);
|
||||
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
oldcs=CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
|
||||
/*Cap source code at 4000 bytes per block; this
|
||||
will prevent any block from spanning more than
|
||||
2 pages. In practice this limit will never be
|
||||
hit, as host block size is only 2kB*/
|
||||
if ((cpu_state.pc - start_pc) > 1000)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
codegen_block_end();
|
||||
|
||||
if (x86_was_reset)
|
||||
codegen_reset();
|
||||
}
|
||||
}
|
||||
|
||||
cycdiff=oldcyc-cycles;
|
||||
tsc += cycdiff;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
CS = oldcs;
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
x386_dynarec_log("Double fault %i\n", ins);
|
||||
#endif
|
||||
pmodeint(8, 0);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
x386_dynarec_log("Triple fault - reset\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
{
|
||||
enter_smm();
|
||||
}
|
||||
|
||||
if (trap)
|
||||
{
|
||||
flags_rebuild();
|
||||
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;
|
||||
oldcs = CS;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
if (nmi_auto_clear)
|
||||
{
|
||||
nmi_auto_clear = 0;
|
||||
nmi = 0;
|
||||
}
|
||||
}
|
||||
else if ((cpu_state.flags&I_FLAG) && pic_intpending)
|
||||
{
|
||||
vector=picinterrupt();
|
||||
if (vector!=-1)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
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;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
|
||||
cycles_main -= (cycles_start - cycles);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,900 +0,0 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
#endif
|
||||
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#ifdef USE_DYNAREC
|
||||
#include "codegen.h"
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#include "codegen_backend.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
|
||||
int inrecomp = 0, cpu_block_end = 0;
|
||||
int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
|
||||
|
||||
|
||||
void
|
||||
x386_dynarec_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (x386_dynarec_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define x386_dynarec_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (cpu_rm == 4)
|
||||
{
|
||||
uint8_t sib = rmdat >> 8;
|
||||
|
||||
switch (cpu_mod)
|
||||
{
|
||||
case 0:
|
||||
cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
|
||||
cpu_state.pc++;
|
||||
break;
|
||||
case 1:
|
||||
cpu_state.pc++;
|
||||
cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
|
||||
cpu_state.pc += 5;
|
||||
break;
|
||||
}
|
||||
/*SIB byte present*/
|
||||
if ((sib & 7) == 5 && !cpu_mod)
|
||||
cpu_state.eaaddr = getlong();
|
||||
else if ((sib & 6) == 4 && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_mod)
|
||||
{
|
||||
if (cpu_rm == 5 && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (cpu_mod == 1)
|
||||
{
|
||||
cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
|
||||
cpu_state.pc++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.eaaddr += getlong();
|
||||
}
|
||||
}
|
||||
else if (cpu_rm == 5)
|
||||
{
|
||||
cpu_state.eaaddr = getlong();
|
||||
}
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if ( readlookup2[addr >> 12] != -1)
|
||||
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (!cpu_mod && cpu_rm == 6)
|
||||
{
|
||||
cpu_state.eaaddr = getword();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (cpu_mod)
|
||||
{
|
||||
case 0:
|
||||
cpu_state.eaaddr = 0;
|
||||
break;
|
||||
case 1:
|
||||
cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.eaaddr = getword();
|
||||
break;
|
||||
}
|
||||
cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
|
||||
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
cpu_state.eaaddr &= 0xFFFF;
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if ( readlookup2[addr >> 12] != -1)
|
||||
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
|
||||
#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1
|
||||
|
||||
#include "x86_flags.h"
|
||||
|
||||
|
||||
/*Prefetch emulation is a fairly simplistic model:
|
||||
- All instruction bytes must be fetched before it starts.
|
||||
- Cycles used for non-instruction memory accesses are counted and subtracted
|
||||
from the total cycles taken
|
||||
- Any remaining cycles are used to refill the prefetch queue.
|
||||
|
||||
Note that this is only used for 286 / 386 systems. It is disabled when the
|
||||
internal cache on 486+ CPUs is enabled.
|
||||
*/
|
||||
static int prefetch_bytes = 0;
|
||||
static int prefetch_prefixes = 0;
|
||||
|
||||
static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
|
||||
{
|
||||
int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l;
|
||||
|
||||
if (instr_cycles < mem_cycles)
|
||||
instr_cycles = mem_cycles;
|
||||
|
||||
prefetch_bytes -= prefetch_prefixes;
|
||||
prefetch_bytes -= bytes;
|
||||
if (modrm != -1)
|
||||
{
|
||||
if (ea32)
|
||||
{
|
||||
if ((modrm & 7) == 4)
|
||||
{
|
||||
if ((modrm & 0x700) == 0x500)
|
||||
prefetch_bytes -= 5;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x05)
|
||||
prefetch_bytes -= 4;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes--;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x06)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) != 0xc0)
|
||||
prefetch_bytes -= ((modrm & 0xc0) >> 6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill up prefetch queue */
|
||||
while (prefetch_bytes < 0)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
/* Subtract cycles used for memory access by instruction */
|
||||
instr_cycles -= mem_cycles;
|
||||
|
||||
while (instr_cycles >= cpu_prefetch_cycles)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
instr_cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
prefetch_prefixes = 0;
|
||||
if (prefetch_bytes > 16)
|
||||
prefetch_bytes = 16;
|
||||
}
|
||||
|
||||
static void prefetch_flush()
|
||||
{
|
||||
prefetch_bytes = 0;
|
||||
}
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
|
||||
do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0)
|
||||
|
||||
#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0)
|
||||
#define PREFETCH_FLUSH() prefetch_flush()
|
||||
|
||||
|
||||
void enter_smm()
|
||||
{
|
||||
uint32_t smram_state = smbase + 0xfe00;
|
||||
uint32_t old_cr0 = cr0;
|
||||
uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16);
|
||||
|
||||
cr0 &= ~0x8000000d;
|
||||
cpu_state.flags = 2;
|
||||
cpu_state.eflags = 0;
|
||||
|
||||
in_smm = 1;
|
||||
mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
smi_latched = 1;
|
||||
|
||||
mem_writel_phys(smram_state + 0xf8, smbase);
|
||||
mem_writel_phys(smram_state + 0x128, cr4);
|
||||
mem_writel_phys(smram_state + 0x130, cpu_state.seg_es.limit);
|
||||
mem_writel_phys(smram_state + 0x134, cpu_state.seg_es.base);
|
||||
mem_writel_phys(smram_state + 0x138, cpu_state.seg_es.access);
|
||||
mem_writel_phys(smram_state + 0x13c, cpu_state.seg_cs.limit);
|
||||
mem_writel_phys(smram_state + 0x140, cpu_state.seg_cs.base);
|
||||
mem_writel_phys(smram_state + 0x144, cpu_state.seg_cs.access);
|
||||
mem_writel_phys(smram_state + 0x148, cpu_state.seg_ss.limit);
|
||||
mem_writel_phys(smram_state + 0x14c, cpu_state.seg_ss.base);
|
||||
mem_writel_phys(smram_state + 0x150, cpu_state.seg_ss.access);
|
||||
mem_writel_phys(smram_state + 0x154, cpu_state.seg_ds.limit);
|
||||
mem_writel_phys(smram_state + 0x158, cpu_state.seg_ds.base);
|
||||
mem_writel_phys(smram_state + 0x15c, cpu_state.seg_ds.access);
|
||||
mem_writel_phys(smram_state + 0x160, cpu_state.seg_fs.limit);
|
||||
mem_writel_phys(smram_state + 0x164, cpu_state.seg_fs.base);
|
||||
mem_writel_phys(smram_state + 0x168, cpu_state.seg_fs.access);
|
||||
mem_writel_phys(smram_state + 0x16c, cpu_state.seg_gs.limit);
|
||||
mem_writel_phys(smram_state + 0x170, cpu_state.seg_gs.base);
|
||||
mem_writel_phys(smram_state + 0x174, cpu_state.seg_gs.access);
|
||||
mem_writel_phys(smram_state + 0x178, ldt.limit);
|
||||
mem_writel_phys(smram_state + 0x17c, ldt.base);
|
||||
mem_writel_phys(smram_state + 0x180, ldt.access);
|
||||
mem_writel_phys(smram_state + 0x184, gdt.limit);
|
||||
mem_writel_phys(smram_state + 0x188, gdt.base);
|
||||
mem_writel_phys(smram_state + 0x18c, gdt.access);
|
||||
mem_writel_phys(smram_state + 0x190, idt.limit);
|
||||
mem_writel_phys(smram_state + 0x194, idt.base);
|
||||
mem_writel_phys(smram_state + 0x198, idt.access);
|
||||
mem_writel_phys(smram_state + 0x19c, tr.limit);
|
||||
mem_writel_phys(smram_state + 0x1a0, tr.base);
|
||||
mem_writel_phys(smram_state + 0x1a4, tr.access);
|
||||
|
||||
mem_writel_phys(smram_state + 0x1a8, cpu_state.seg_es.seg);
|
||||
mem_writel_phys(smram_state + 0x1ac, cpu_state.seg_cs.seg);
|
||||
mem_writel_phys(smram_state + 0x1b0, cpu_state.seg_ss.seg);
|
||||
mem_writel_phys(smram_state + 0x1b4, cpu_state.seg_ds.seg);
|
||||
mem_writel_phys(smram_state + 0x1b8, cpu_state.seg_fs.seg);
|
||||
mem_writel_phys(smram_state + 0x1bc, cpu_state.seg_gs.seg);
|
||||
mem_writel_phys(smram_state + 0x1c0, ldt.seg);
|
||||
mem_writel_phys(smram_state + 0x1c4, tr.seg);
|
||||
|
||||
mem_writel_phys(smram_state + 0x1c8, dr[7]);
|
||||
mem_writel_phys(smram_state + 0x1cc, dr[6]);
|
||||
mem_writel_phys(smram_state + 0x1d0, EAX);
|
||||
mem_writel_phys(smram_state + 0x1d4, ECX);
|
||||
mem_writel_phys(smram_state + 0x1d8, EDX);
|
||||
mem_writel_phys(smram_state + 0x1dc, EBX);
|
||||
mem_writel_phys(smram_state + 0x1e0, ESP);
|
||||
mem_writel_phys(smram_state + 0x1e4, EBP);
|
||||
mem_writel_phys(smram_state + 0x1e8, ESI);
|
||||
mem_writel_phys(smram_state + 0x1ec, EDI);
|
||||
mem_writel_phys(smram_state + 0x1f0, cpu_state.pc);
|
||||
mem_writel_phys(smram_state + 0x1d0, old_flags);
|
||||
mem_writel_phys(smram_state + 0x1f8, cr3);
|
||||
mem_writel_phys(smram_state + 0x1fc, old_cr0);
|
||||
|
||||
ds = es = fs_seg = gs = ss = 0;
|
||||
|
||||
DS = ES = FS = GS = SS = 0;
|
||||
|
||||
cpu_state.seg_ds.limit = cpu_state.seg_es.limit = cpu_state.seg_fs.limit = cpu_state.seg_gs.limit
|
||||
= cpu_state.seg_ss.limit = 0xffffffff;
|
||||
|
||||
cpu_state.seg_ds.limit_high = cpu_state.seg_es.limit_high = cpu_state.seg_fs.limit_high
|
||||
= cpu_state.seg_gs.limit_high = cpu_state.seg_ss.limit_high = 0xffffffff;
|
||||
|
||||
cpu_state.seg_ds.limit_low = cpu_state.seg_es.limit_low = cpu_state.seg_fs.limit_low
|
||||
= cpu_state.seg_gs.limit_low = cpu_state.seg_ss.limit_low = 0;
|
||||
|
||||
cpu_state.seg_ds.access = cpu_state.seg_es.access = cpu_state.seg_fs.access
|
||||
= cpu_state.seg_gs.access = cpu_state.seg_ss.access = 0x93;
|
||||
|
||||
cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked
|
||||
= cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
|
||||
|
||||
CS = 0x3000;
|
||||
cs = smbase;
|
||||
cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = 0xffffffff;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.access = 0x93;
|
||||
cpu_state.seg_cs.checked = 1;
|
||||
|
||||
cr4 = 0;
|
||||
dr[7] = 0x400;
|
||||
cpu_state.pc = 0x8000;
|
||||
|
||||
nmi_mask = 0;
|
||||
}
|
||||
|
||||
void leave_smm()
|
||||
{
|
||||
uint32_t smram_state = smbase + 0xfe00;
|
||||
|
||||
smbase = mem_readl_phys(smram_state + 0xf8);
|
||||
cr4 = mem_readl_phys(smram_state + 0x128);
|
||||
|
||||
cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130);
|
||||
cpu_state.seg_es.base = mem_readl_phys(smram_state + 0x134);
|
||||
cpu_state.seg_es.limit_low = cpu_state.seg_es.base;
|
||||
cpu_state.seg_es.access = mem_readl_phys(smram_state + 0x138);
|
||||
|
||||
cpu_state.seg_cs.limit = cpu_state.seg_cs.limit_high = mem_readl_phys(smram_state + 0x13c);
|
||||
cpu_state.seg_cs.base = mem_readl_phys(smram_state + 0x140);
|
||||
cpu_state.seg_cs.limit_low = cpu_state.seg_cs.base;
|
||||
cpu_state.seg_cs.access = mem_readl_phys(smram_state + 0x144);
|
||||
|
||||
cpu_state.seg_ss.limit = cpu_state.seg_ss.limit_high = mem_readl_phys(smram_state + 0x148);
|
||||
cpu_state.seg_ss.base = mem_readl_phys(smram_state + 0x14c);
|
||||
cpu_state.seg_ss.limit_low = cpu_state.seg_ss.base;
|
||||
cpu_state.seg_ss.access = mem_readl_phys(smram_state + 0x150);
|
||||
|
||||
cpu_state.seg_ds.limit = cpu_state.seg_ds.limit_high = mem_readl_phys(smram_state + 0x154);
|
||||
cpu_state.seg_ds.base = mem_readl_phys(smram_state + 0x158);
|
||||
cpu_state.seg_ds.limit_low = cpu_state.seg_ds.base;
|
||||
cpu_state.seg_ds.access = mem_readl_phys(smram_state + 0x15c);
|
||||
|
||||
cpu_state.seg_fs.limit = cpu_state.seg_fs.limit_high = mem_readl_phys(smram_state + 0x160);
|
||||
cpu_state.seg_fs.base = mem_readl_phys(smram_state + 0x164);
|
||||
cpu_state.seg_fs.limit_low = cpu_state.seg_fs.base;
|
||||
cpu_state.seg_fs.access = mem_readl_phys(smram_state + 0x168);
|
||||
|
||||
cpu_state.seg_gs.limit = cpu_state.seg_gs.limit_high = mem_readl_phys(smram_state + 0x16c);
|
||||
cpu_state.seg_gs.base = mem_readl_phys(smram_state + 0x170);
|
||||
cpu_state.seg_gs.limit_low = cpu_state.seg_gs.base;
|
||||
cpu_state.seg_gs.access = mem_readl_phys(smram_state + 0x174);
|
||||
|
||||
ldt.limit = ldt.limit_high = mem_readl_phys(smram_state + 0x178);
|
||||
ldt.base = mem_readl_phys(smram_state + 0x17c);
|
||||
ldt.limit_low = ldt.base;
|
||||
ldt.access = mem_readl_phys(smram_state + 0x180);
|
||||
|
||||
gdt.limit = gdt.limit_high = mem_readl_phys(smram_state + 0x184);
|
||||
gdt.base = mem_readl_phys(smram_state + 0x188);
|
||||
gdt.limit_low = gdt.base;
|
||||
gdt.access = mem_readl_phys(smram_state + 0x18c);
|
||||
|
||||
idt.limit = idt.limit_high = mem_readl_phys(smram_state + 0x190);
|
||||
idt.base = mem_readl_phys(smram_state + 0x194);
|
||||
idt.limit_low = idt.base;
|
||||
idt.access = mem_readl_phys(smram_state + 0x198);
|
||||
|
||||
tr.limit = tr.limit_high = mem_readl_phys(smram_state + 0x19c);
|
||||
tr.base = mem_readl_phys(smram_state + 0x1a0);
|
||||
tr.limit_low = tr.base;
|
||||
tr.access = mem_readl_phys(smram_state + 0x1a4);
|
||||
|
||||
ES = mem_readl_phys(smram_state + 0x1a8);
|
||||
CS = mem_readl_phys(smram_state + 0x1ac);
|
||||
SS = mem_readl_phys(smram_state + 0x1b0);
|
||||
DS = mem_readl_phys(smram_state + 0x1b4);
|
||||
FS = mem_readl_phys(smram_state + 0x1b8);
|
||||
GS = mem_readl_phys(smram_state + 0x1bc);
|
||||
ldt.seg = mem_readl_phys(smram_state + 0x1c0);
|
||||
tr.seg = mem_readl_phys(smram_state + 0x1c4);
|
||||
|
||||
dr[7] = mem_readl_phys(smram_state + 0x1c8);
|
||||
dr[6] = mem_readl_phys(smram_state + 0x1cc);
|
||||
EAX = mem_readl_phys(smram_state + 0x1d0);
|
||||
ECX = mem_readl_phys(smram_state + 0x1d4);
|
||||
EDX = mem_readl_phys(smram_state + 0x1d8);
|
||||
EBX = mem_readl_phys(smram_state + 0x1dc);
|
||||
ESP = mem_readl_phys(smram_state + 0x1e0);
|
||||
EBP = mem_readl_phys(smram_state + 0x1e4);
|
||||
ESI = mem_readl_phys(smram_state + 0x1e8);
|
||||
EDI = mem_readl_phys(smram_state + 0x1ec);
|
||||
|
||||
cpu_state.pc = mem_readl_phys(smram_state + 0x1f0);
|
||||
uint32_t new_flags = mem_readl_phys(smram_state + 0x1f4);
|
||||
cpu_state.flags = new_flags & 0xffff;
|
||||
cpu_state.eflags = new_flags >> 16;
|
||||
cr3 = mem_readl_phys(smram_state + 0x1f8);
|
||||
cr0 = mem_readl_phys(smram_state + 0x1fc);
|
||||
|
||||
cpu_state.seg_cs.access &= ~0x60;
|
||||
cpu_state.seg_cs.access |= cpu_state.seg_ss.access & 0x60; //cpl is dpl of ss
|
||||
|
||||
if((cr0 & 1) && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
cpu_state.seg_cs.checked = CS ? 1 : 0;
|
||||
cpu_state.seg_ds.checked = DS ? 1 : 0;
|
||||
cpu_state.seg_es.checked = ES ? 1 : 0;
|
||||
cpu_state.seg_fs.checked = FS ? 1 : 0;
|
||||
cpu_state.seg_gs.checked = GS ? 1 : 0;
|
||||
cpu_state.seg_ss.checked = SS ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.seg_cs.checked = cpu_state.seg_ds.checked = cpu_state.seg_es.checked
|
||||
= cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = cpu_state.seg_ss.checked = 1;
|
||||
}
|
||||
|
||||
mem_restore_mem_state(smbase, 131072);
|
||||
in_smm = 0;
|
||||
|
||||
nmi_mask = 1;
|
||||
}
|
||||
|
||||
#define OP_TABLE(name) ops_ ## name
|
||||
#define CLOCK_CYCLES(c) cycles -= (c)
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
#include "386_ops.h"
|
||||
|
||||
|
||||
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
static int cycles_main = 0;
|
||||
|
||||
|
||||
void exec386_dynarec(int cycs)
|
||||
{
|
||||
int vector;
|
||||
uint32_t addr;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
int oldcyc;
|
||||
uint32_t start_pc = 0;
|
||||
|
||||
int cyc_period = cycs / 2000; /*5us*/
|
||||
|
||||
cycles_main += cycs;
|
||||
while (cycles_main > 0)
|
||||
{
|
||||
int cycles_start;
|
||||
|
||||
cycles += cyc_period;
|
||||
cycles_start = cycles;
|
||||
|
||||
while (cycles>0)
|
||||
{
|
||||
oldcs = CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cycdiff=0;
|
||||
oldcyc=cycles;
|
||||
if (!CACHE_ON()) /*Interpret block*/
|
||||
{
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
oldcs = CS;
|
||||
oldcpl = CPL;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
}
|
||||
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
|
||||
if (((cs + cpu_state.pc) >> 12) != pccache)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
CPU_BLOCK_END();
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
ins++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t phys_addr = get_phys(cs+cpu_state.pc);
|
||||
int hash = HASH(phys_addr);
|
||||
codeblock_t *block = codeblock_hash[hash];
|
||||
int valid_block = 0;
|
||||
trap = 0;
|
||||
|
||||
if (block && !cpu_state.abrt)
|
||||
{
|
||||
page_t *page = &pages[phys_addr >> 12];
|
||||
|
||||
/*Block must match current CS, PC, code segment size,
|
||||
and physical address. The physical address check will
|
||||
also catch any page faults at this stage*/
|
||||
valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
|
||||
(block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
|
||||
if (!valid_block)
|
||||
{
|
||||
uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
|
||||
if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask)
|
||||
{
|
||||
/*Walk page tree to see if we find the correct block*/
|
||||
codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
|
||||
if (new_block)
|
||||
{
|
||||
valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
|
||||
(new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
|
||||
if (valid_block)
|
||||
block = new_block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_block && (block->page_mask & *block->dirty_mask))
|
||||
{
|
||||
codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr);
|
||||
page->dirty_mask[(phys_addr >> 10) & 3] = 0;
|
||||
if (!block->valid)
|
||||
valid_block = 0;
|
||||
}
|
||||
if (valid_block && block->page_mask2)
|
||||
{
|
||||
/*We don't want the second page to cause a page
|
||||
fault at this stage - that would break any
|
||||
code crossing a page boundary where the first
|
||||
page is present but the second isn't. Instead
|
||||
allow the first page to be interpreted and for
|
||||
the page fault to occur when the page boundary
|
||||
is actually crossed.*/
|
||||
uint32_t phys_addr_2 = get_phys_noabrt(block->endpc);
|
||||
page_t *page_2 = &pages[phys_addr_2 >> 12];
|
||||
|
||||
if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
|
||||
valid_block = 0;
|
||||
else if (block->page_mask2 & *block->dirty_mask2)
|
||||
{
|
||||
codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2);
|
||||
page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0;
|
||||
if (!block->valid)
|
||||
valid_block = 0;
|
||||
}
|
||||
}
|
||||
if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP)
|
||||
{
|
||||
/*FPU top-of-stack does not match the value this block was compiled
|
||||
with, re-compile using dynamic top-of-stack*/
|
||||
block->flags &= ~CODEBLOCK_STATIC_TOP;
|
||||
block->was_recompiled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_block && block->was_recompiled)
|
||||
{
|
||||
void (*code)() = (void *)&block->data[BLOCK_START];
|
||||
|
||||
codeblock_hash[hash] = block;
|
||||
|
||||
inrecomp=1;
|
||||
code();
|
||||
inrecomp=0;
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
cpu_recomp_blocks++;
|
||||
}
|
||||
else if (valid_block && !cpu_state.abrt)
|
||||
{
|
||||
start_pc = cpu_state.pc;
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
cpu_new_blocks++;
|
||||
|
||||
codegen_block_start_recompile(block);
|
||||
codegen_in_recompile = 1;
|
||||
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
oldcs = CS;
|
||||
oldcpl = CPL;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
|
||||
codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
|
||||
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
|
||||
/*Cap source code at 4000 bytes per block; this
|
||||
will prevent any block from spanning more than
|
||||
2 pages. In practice this limit will never be
|
||||
hit, as host block size is only 2kB*/
|
||||
if ((cpu_state.pc - start_pc) > 1000)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
codegen_block_end_recompile(block);
|
||||
|
||||
if (x86_was_reset)
|
||||
codegen_reset();
|
||||
|
||||
codegen_in_recompile = 0;
|
||||
}
|
||||
else if (!cpu_state.abrt)
|
||||
{
|
||||
/*Mark block but do not recompile*/
|
||||
start_pc = cpu_state.pc;
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
codegen_block_init(phys_addr);
|
||||
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
oldcs=CS;
|
||||
oldcpl = CPL;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
|
||||
/*Cap source code at 4000 bytes per block; this
|
||||
will prevent any block from spanning more than
|
||||
2 pages. In practice this limit will never be
|
||||
hit, as host block size is only 2kB*/
|
||||
if ((cpu_state.pc - start_pc) > 1000)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
codegen_block_end();
|
||||
|
||||
if (x86_was_reset)
|
||||
codegen_reset();
|
||||
}
|
||||
}
|
||||
|
||||
cycdiff=oldcyc-cycles;
|
||||
tsc += cycdiff;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
CS = oldcs;
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
x386_dynarec_log("Double fault %i\n", ins);
|
||||
#endif
|
||||
pmodeint(8, 0);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
x386_dynarec_log("Triple fault - reset\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in_smm && smi_line && is_pentium)
|
||||
{
|
||||
enter_smm();
|
||||
}
|
||||
|
||||
else if (trap)
|
||||
{
|
||||
flags_rebuild();
|
||||
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;
|
||||
oldcs = CS;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
if (nmi_auto_clear)
|
||||
{
|
||||
nmi_auto_clear = 0;
|
||||
nmi = 0;
|
||||
}
|
||||
}
|
||||
else if ((cpu_state.flags&I_FLAG) && pic_intpending)
|
||||
{
|
||||
vector = picinterrupt();
|
||||
if (vector != -1)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
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;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
|
||||
cycles_main -= (cycles_start - cycles);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -66,7 +66,7 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
|
||||
#define OP_TABLE(name) dynarec_ops_ ## name
|
||||
|
||||
#define CLOCK_CYCLES(c)
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
#define CLOCK_CYCLES(c) in_hlt = 0
|
||||
#define CLOCK_CYCLES_ALWAYS(c) do { cycles -= (c); in_hlt = 0; } while(0)
|
||||
|
||||
#include "386_ops.h"
|
||||
|
||||
@@ -972,7 +972,10 @@ reset_common(int hard)
|
||||
cpu_alu_op = 0;
|
||||
|
||||
in_smm = smi_latched = 0;
|
||||
smi_line = 0;
|
||||
smi_line = in_hlt = 0;
|
||||
|
||||
if (hard)
|
||||
smbase = 0x00030000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,10 +39,13 @@
|
||||
* USA.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/device.h>
|
||||
@@ -132,7 +135,7 @@ const OpFn *x86_opcodes_REPE;
|
||||
const OpFn *x86_opcodes_REPNE;
|
||||
const OpFn *x86_opcodes_3DNOW;
|
||||
|
||||
int in_smm = 0, smi_line = 0, smi_latched = 0;
|
||||
int in_smm = 0, smi_line = 0, smi_latched = 0, in_hlt = 0;
|
||||
uint32_t smbase = 0x30000;
|
||||
|
||||
CPU *cpu_s;
|
||||
@@ -163,7 +166,7 @@ int is286,
|
||||
hascache,
|
||||
isibm486,
|
||||
israpidcad,
|
||||
is_pentium;
|
||||
is_pentium, is_k5, is_k6, is_p6;
|
||||
|
||||
int hasfpu;
|
||||
|
||||
@@ -237,7 +240,29 @@ int timing_misaligned;
|
||||
|
||||
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
|
||||
|
||||
int cpu_has_feature(int feature)
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define cpu_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
cpu_has_feature(int feature)
|
||||
{
|
||||
return cpu_features & feature;
|
||||
}
|
||||
@@ -291,7 +316,28 @@ cpu_set(void)
|
||||
is486dx = (cpu_s->cpu_type >= CPU_i486DX) && (cpu_s->cpu_type < CPU_i486DX2);
|
||||
is486dx2 = (cpu_s->cpu_type >= CPU_i486DX2) && (cpu_s->cpu_type < CPU_iDX4);
|
||||
isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP);
|
||||
is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP);
|
||||
is_pentium = (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX);
|
||||
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)))
|
||||
is_k5 = (cpu_s->cpu_type == CPU_K5) || (cpu_s->cpu_type == CPU_5K86);
|
||||
#else
|
||||
is_k5 = 0;
|
||||
#endif
|
||||
#if (defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K)))
|
||||
is_k6 = (cpu_s->cpu_type == CPU_K6);
|
||||
#else
|
||||
is_k6 = 0;
|
||||
#endif
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
is_k6 = is_k6 || (cpu_s->cpu_type == CPU_K6_2) || (cpu_s->cpu_type == CPU_K6_2C) ||
|
||||
(cpu_s->cpu_type == CPU_K6_3) || (cpu_s->cpu_type == CPU_K6_2P) ||
|
||||
(cpu_s->cpu_type == CPU_K6_3P);
|
||||
#endif
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) ||
|
||||
(cpu_s->cpu_type == CPU_PENTIUM2D);
|
||||
#else
|
||||
is_p6 = 0;
|
||||
#endif
|
||||
hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
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);
|
||||
#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))
|
||||
@@ -2362,6 +2408,7 @@ void cpu_ven_reset(void)
|
||||
|
||||
void cpu_RDMSR()
|
||||
{
|
||||
cpu_log("RDMSR %08X\n", ECX);
|
||||
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
|
||||
{
|
||||
case CPU_WINCHIP:
|
||||
@@ -2833,7 +2880,7 @@ void cpu_RDMSR()
|
||||
break;
|
||||
default:
|
||||
i686_invalid_rdmsr:
|
||||
// pclog("RDMSR: Invalid MSR: %08X\n", ECX);
|
||||
cpu_log("RDMSR: Invalid MSR: %08X\n", ECX);
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
@@ -2849,6 +2896,7 @@ void cpu_WRMSR()
|
||||
uint64_t temp;
|
||||
#endif
|
||||
|
||||
cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX);
|
||||
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
|
||||
{
|
||||
case CPU_WINCHIP:
|
||||
@@ -3249,7 +3297,7 @@ void cpu_WRMSR()
|
||||
break;
|
||||
default:
|
||||
i686_invalid_wrmsr:
|
||||
// pclog("WRMSR: Invalid MSR: %08X\n", ECX);
|
||||
cpu_log("WRMSR: Invalid MSR: %08X\n", ECX);
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -382,11 +382,12 @@ extern double cpu_dmulti;
|
||||
extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
|
||||
penalties when crossing 8-byte boundaries*/
|
||||
|
||||
extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4;
|
||||
extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4;
|
||||
extern int is_pentium, is_k5, is_k6, is_p6;
|
||||
extern int hascache;
|
||||
extern int isibm486;
|
||||
extern int is_rapidcad;
|
||||
extern int hasfpu;
|
||||
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)
|
||||
@@ -397,7 +398,7 @@ extern int hasfpu;
|
||||
|
||||
extern uint32_t cpu_features;
|
||||
|
||||
extern int in_smm, smi_line, smi_latched;
|
||||
extern int in_smm, smi_line, smi_latched, in_hlt;
|
||||
extern uint32_t smbase;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
|
||||
@@ -1,695 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Define all known processor types.
|
||||
*
|
||||
* Available cpuspeeds:
|
||||
*
|
||||
* 0 = 16 MHz
|
||||
* 1 = 20 MHz
|
||||
* 2 = 25 MHz
|
||||
* 3 = 33 MHz
|
||||
* 4 = 40 MHz
|
||||
* 5 = 50 MHz
|
||||
* 6 = 66 MHz
|
||||
* 7 = 75 MHz
|
||||
* 8 = 80 MHz
|
||||
* 9 = 90 MHz
|
||||
* 10 = 100 MHz
|
||||
* 11 = 120 MHz
|
||||
* 12 = 133 MHz
|
||||
* 13 = 150 MHz
|
||||
* 14 = 160 MHz
|
||||
* 15 = 166 MHz
|
||||
* 16 = 180 MHz
|
||||
* 17 = 200 MHz
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 leilei.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/machine.h>
|
||||
|
||||
|
||||
CPU cpus_8088[] = {
|
||||
/*8088 standard*/
|
||||
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_pcjr[] = {
|
||||
/*8088 PCjr*/
|
||||
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_europc[] = {
|
||||
/*8088 EuroPC*/
|
||||
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8088/9.54", CPU_8088, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_8086[] = {
|
||||
/*8086 standard*/
|
||||
{"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8086/10", CPU_8086, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8086/12", CPU_8086, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8086/16", CPU_8086, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_pc1512[] = {
|
||||
/*8086 Amstrad*/
|
||||
{"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_286[] = {
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ibmat[] = {
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
|
||||
{"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ibmxt286[] = {
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ps1_m2011[] = {
|
||||
/*286*/
|
||||
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9}
|
||||
};
|
||||
|
||||
CPU cpus_ps2_m30_286[] = {
|
||||
/*286*/
|
||||
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/12", CPU_286, 12500000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i386SX[] = {
|
||||
/*i386SX*/
|
||||
{"i386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"i386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"i386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i386DX[] = {
|
||||
/*i386DX/RapidCAD*/
|
||||
{"i386DX/16", CPU_386DX, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"i386DX/20", CPU_386DX, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"i386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
|
||||
{"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
|
||||
{"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am386SX[] = {
|
||||
/*Am386SX*/
|
||||
{"Am386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"Am386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"Am386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am386DX[] = {
|
||||
/*Am386DX*/
|
||||
{"Am386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"Am386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_486SLC[] = {
|
||||
/*Cx486SLC*/
|
||||
{"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
|
||||
{"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
|
||||
{"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
|
||||
{"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4},
|
||||
{"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
|
||||
{"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_IBM386SLC[] = {
|
||||
/*IBM 386SLC*/
|
||||
{"386SLC/16", CPU_IBM386SLC, 16000000, 1, 0, 0x300, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"386SLC/20", CPU_IBM386SLC, 20000000, 1, 0, 0x300, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"386SLC/25", CPU_IBM386SLC, 25000000, 1, 0, 0x300, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_IBM486SLC[] = {
|
||||
/*IBM 486SLC*/
|
||||
{"486SLC/33", CPU_IBM486SLC, 33333333, 1, 0, 0x400, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"486SLC2/40", CPU_IBM486SLC, 40000000, 2, 0, 0x400, 0, 0, 0, 7,7,6,6, 5},
|
||||
{"486SLC2/50", CPU_IBM486SLC, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6},
|
||||
{"486SLC2/66", CPU_IBM486SLC, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8},
|
||||
{"486SLC3/60", CPU_IBM486SLC, 60000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 7},
|
||||
{"486SLC3/75", CPU_IBM486SLC, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9},
|
||||
{"486SLC3/100", CPU_IBM486SLC, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_IBM486BL[] = {
|
||||
/*IBM Blue Lightning*/
|
||||
{"486BL2/50", CPU_IBM486BL, 50000000, 2, 0, 0x400, 0, 0, 0, 8,8,6,6, 6},
|
||||
{"486BL2/66", CPU_IBM486BL, 66666666, 2, 0, 0x400, 0, 0, 0, 12,12,6,6, 8},
|
||||
{"486BL3/75", CPU_IBM486BL, 75000000, 3, 0, 0x400, 0, 0, 0, 12,12,9,9, 9},
|
||||
{"486BL3/100", CPU_IBM486BL, 100000000, 3, 0, 0x400, 0, 0, 0, 18,18,9,9, 12},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_486DLC[] = {
|
||||
/*Cx486DLC*/
|
||||
{"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3},
|
||||
{"Cx486DLC/33", CPU_486DLC, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4},
|
||||
{"Cx486DLC/40", CPU_486DLC, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5},
|
||||
{"Cx486DRx2/32", CPU_486DLC, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4},
|
||||
{"Cx486DRx2/40", CPU_486DLC, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
|
||||
{"Cx486DRx2/50", CPU_486DLC, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
|
||||
{"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i486S1[] = {
|
||||
/*i486*/
|
||||
{"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
|
||||
{"i486SX/20", CPU_i486SX, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/25", CPU_i486SX, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/33", CPU_i486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486SX2/50", CPU_i486SX, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
|
||||
{"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
|
||||
{"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},
|
||||
{"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*Only added the DX4 OverDrive as the others would be redundant*/
|
||||
{"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
CPU cpus_Am486S1[] = {
|
||||
/*Am486*/
|
||||
{"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, 40000000, 1, 40000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
|
||||
{"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486DX/40", CPU_Am486DX, 40000000, 1, 40000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"Am486DX2/66", CPU_Am486DX, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Am486DX2/80", CPU_Am486DX, 80000000, 2, 40000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
CPU cpus_Cx486S1[] = {
|
||||
/*Cyrix 486*/
|
||||
{"Cx486S/25", CPU_Cx486S, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, 40000000, 1, 40000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 40000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX2/50", CPU_Cx486DX, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"Cx486DX2/66", CPU_Cx486DX, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Cx486DX2/80", CPU_Cx486DX, 80000000, 2, 40000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i486[] = {
|
||||
/*i486/P24T*/
|
||||
{"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
|
||||
{"i486SX/20", CPU_i486SX, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/25", CPU_i486SX, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/33", CPU_i486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486SX2/50", CPU_i486SX, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
|
||||
{"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
|
||||
{"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5}, /*CPUID available on DX2, DX4, P24T, >= 40 MHz*/
|
||||
{"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/
|
||||
{"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
|
||||
{"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 25000000, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9},
|
||||
{"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3, 33333333, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12},
|
||||
{"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 5/2, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
|
||||
{"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 5/2, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am486[] = {
|
||||
/*Am486/5x86*/
|
||||
{"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, 40000000, 1, 40000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486DX/40", CPU_Am486DX, 40000000, 1, 40000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"Am486DX2/66", CPU_Am486DX, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Am486DX2/80", CPU_Am486DX, 80000000, 2, 40000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
|
||||
{"Am486DX4/75", CPU_Am486DX, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
|
||||
{"Am486DX4/90", CPU_Am486DX, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
{"Am486DX4/100", CPU_Am486DX, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
{"Am486DX4/120", CPU_Am486DX, 120000000, 3, 40000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
|
||||
{"Am5x86/P75", CPU_Am486DX, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
|
||||
{"Am5x86/P75+", CPU_Am486DX, 150000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*The rare P75+ was indeed a triple-clocked 150 MHz according to research*/
|
||||
{"Am5x86/P90", CPU_Am486DX, 160000000, 4, 40000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},/*160 MHz on a 40 MHz bus was a common overclock and "5x86/P90" was used by a number of BIOSes to refer to that configuration*/
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Cx486[] = {
|
||||
/*Cyrix 486*/
|
||||
{"Cx486S/25", CPU_Cx486S, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, 40000000, 1, 40000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 40000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX2/50", CPU_Cx486DX, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"Cx486DX2/66", CPU_Cx486DX, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Cx486DX2/80", CPU_Cx486DX, 80000000, 2, 40000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
|
||||
{"Cx486DX4/75", CPU_Cx486DX, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
|
||||
{"Cx486DX4/100", CPU_Cx486DX, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
|
||||
/*Cyrix 5x86*/
|
||||
{"Cx5x86/80", CPU_Cx5x86, 80000000, 2, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10}, /*If we're including the Pentium 50, might as well include this*/
|
||||
{"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
{"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 40000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
|
||||
{"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_CYRIX_6X86))
|
||||
CPU cpus_6x863V[] = {
|
||||
/*Cyrix 6x86*/
|
||||
{"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
|
||||
{"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
|
||||
{"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
|
||||
{"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_6x86[] = {
|
||||
/*Cyrix 6x86*/
|
||||
{"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
|
||||
{"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
|
||||
{"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
|
||||
{"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
|
||||
|
||||
/*Cyrix 6x86L*/
|
||||
{"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
|
||||
{"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
|
||||
|
||||
/*Cyrix 6x86MX/MII*/
|
||||
{"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2},
|
||||
{"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 41666666, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
|
||||
{"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28},
|
||||
{"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CPU cpus_6x86SS7[] = {
|
||||
/*Cyrix 6x86*/
|
||||
{"Cx6x86/P90", CPU_Cx6x86, 80000000, 2, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
|
||||
{"Cx6x86/PR120+", CPU_Cx6x86, 100000000, 2, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
|
||||
{"Cx6x86/PR133+", CPU_Cx6x86, 110000000, 2, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
|
||||
{"Cx6x86/PR150+", CPU_Cx6x86, 120000000, 2, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Cx6x86/PR166+", CPU_Cx6x86, 133333333, 2, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Cx6x86/PR200+", CPU_Cx6x86, 150000000, 2, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
|
||||
|
||||
/*Cyrix 6x86L*/
|
||||
{"Cx6x86L/PR133+", CPU_Cx6x86L, 110000000, 2, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
|
||||
{"Cx6x86L/PR150+", CPU_Cx6x86L, 120000000, 2, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Cx6x86L/PR166+", CPU_Cx6x86L, 133333333, 2, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Cx6x86L/PR200+", CPU_Cx6x86L, 150000000, 2, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
|
||||
|
||||
/*Cyrix 6x86MX/MII*/
|
||||
{"Cx6x86MX/PR166", CPU_Cx6x86MX, 133333333, 2, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Cx6x86MX/PR200", CPU_Cx6x86MX, 166666666, 5/2, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Cx6x86MX/PR233", CPU_Cx6x86MX, 187500000, 5/2, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2},
|
||||
{"Cx6x86MX/PR266", CPU_Cx6x86MX, 208333333, 5/2, 41666666, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
|
||||
{"MII/PR300", CPU_Cx6x86MX, 233333333, 7/2, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28},
|
||||
{"MII/PR333", CPU_Cx6x86MX, 250000000, 3, 41666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 9, 9, 30},
|
||||
{"MII/PR366", CPU_Cx6x86MX, 250000000, 5/2, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 23,23, 7, 7, 30},
|
||||
{"MII/PR400", CPU_Cx6x86MX, 285000000, 3, 31666666, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 34},
|
||||
{"MII/PR433", CPU_Cx6x86MX, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
CPU cpus_WinChip[] = {
|
||||
/*IDT WinChip*/
|
||||
{"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9},
|
||||
{"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14},
|
||||
{"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16},
|
||||
{"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2},
|
||||
{"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40},
|
||||
{"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21},
|
||||
{"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
|
||||
{"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27},
|
||||
{"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28},
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
{"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
|
||||
{"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27},
|
||||
{"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
|
||||
{"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
|
||||
{"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
|
||||
{"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7*8)/2},
|
||||
#endif
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CPU cpus_WinChip_SS7[] = {
|
||||
/*IDT WinChip*/
|
||||
{"WinChip 75", CPU_WINCHIP, 75000000, 3/2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9},
|
||||
{"WinChip 90", CPU_WINCHIP, 90000000, 3/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"WinChip 100", CPU_WINCHIP, 100000000, 3/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 14},
|
||||
{"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 16},
|
||||
{"WinChip 150", CPU_WINCHIP, 150000000, 5/2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 35/2},
|
||||
{"WinChip 166", CPU_WINCHIP, 166666666, 5/2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, 40},
|
||||
{"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 21},
|
||||
{"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24},
|
||||
{"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 27},
|
||||
{"WinChip 240", CPU_WINCHIP, 240000000, 4, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28},
|
||||
{"WinChip 2/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8},
|
||||
{"WinChip 2/225", CPU_WINCHIP2, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*9},
|
||||
{"WinChip 2/240", CPU_WINCHIP2, 240000000, 4, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
|
||||
{"WinChip 2/250", CPU_WINCHIP2, 250000000, 3, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30},
|
||||
{"WinChip 2A/200", CPU_WINCHIP2, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3*8},
|
||||
{"WinChip 2A/233", CPU_WINCHIP2, 233333333, 7/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, (7*8)/2},
|
||||
{"WinChip 2A/266", CPU_WINCHIP2, 233333333, 7/3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 7, 7, 28},
|
||||
{"WinChip 2A/300", CPU_WINCHIP2, 250000000, 5/2, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 8, 8, 30},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
CPU cpus_Pentium5V[] = {
|
||||
/*Intel Pentium (5V, socket 4)*/
|
||||
{"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
|
||||
{"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
|
||||
{"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium5V50[] = {
|
||||
/*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/
|
||||
{"Pentium 50 (Q0399)", CPU_PENTIUM, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6},
|
||||
{"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
|
||||
{"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x517, 0x517, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
|
||||
{"Pentium OverDrive 100", CPU_PENTIUM, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12},
|
||||
{"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_PentiumS5[] = {
|
||||
/*Intel Pentium (Socket 5)*/
|
||||
{"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 25000000, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
|
||||
{"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
|
||||
/*Intel Pentium OverDrive*/
|
||||
{"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16},
|
||||
{"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium3V[] = {
|
||||
/*Intel Pentium*/
|
||||
{"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Pentium 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
|
||||
/*Intel Pentium OverDrive*/
|
||||
{"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
|
||||
{"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium[] = {
|
||||
/*Intel Pentium*/
|
||||
{"Pentium 75", CPU_PENTIUM, 75000000, 3/2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 3/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium 90", CPU_PENTIUM, 90000000, 3/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 100000000, 3/2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Pentium 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Pentium 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
|
||||
/*Intel Pentium MMX*/
|
||||
{"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
|
||||
/*Mobile Pentium*/
|
||||
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 5/2, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 7/2, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 300000000, 9/2, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
|
||||
/*Intel Pentium OverDrive*/
|
||||
{"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 5/2, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
|
||||
{"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 5/2, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 5/2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 5/2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 5/2, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 5/2, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))
|
||||
CPU cpus_K5[] = {
|
||||
/*AMD K5 (Socket 5)*/
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
|
||||
{"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_K56[] = {
|
||||
/*AMD K5 (Socket 7)*/
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
|
||||
/*AMD K6 (Socket 7*/
|
||||
{"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28},
|
||||
{"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28},
|
||||
{"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32},
|
||||
{"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36},
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
{"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 10, 10, 28},
|
||||
{"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24, 12, 12, 32},
|
||||
{"K6-2/300 AFR-66", CPU_K6_2, 300000000, 9/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 13, 13, 36},
|
||||
{"K6-2/366", CPU_K6_2, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33,33, 17, 17, 44},
|
||||
#endif
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
CPU cpus_K56_SS7[] = {
|
||||
/*AMD K5 (Socket 7)*/
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 3/2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 3/2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 3/2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 3/2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 3/2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 3/2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 5/2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 5/2, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
|
||||
/*AMD K6 (Socket 7)*/
|
||||
{"K6 (Model 6) 166", CPU_K6, 166666666, 5/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"K6 (Model 6) 233", CPU_K6, 233333333, 7/2, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"K6 (Model 7) 233", CPU_K6, 233333333, 7/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"K6 (Model 7) 300", CPU_K6, 300000000, 9/2, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
|
||||
/*AMD K6-2 (Socket 7/Super Socket 7)*/
|
||||
{"K6-2/233", CPU_K6_2, 233333333, 7/2, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28},
|
||||
{"K6-2/266", CPU_K6_2, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32},
|
||||
{"K6-2/300", CPU_K6_2, 300000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 9, 9, 36},
|
||||
{"K6-2/333", CPU_K6_2, 332500000, 7/2, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 30, 30, 11, 11, 40},
|
||||
{"K6-2/350", CPU_K6_2C, 350000000, 7/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32, 32, 11, 11, 42},
|
||||
{"K6-2/366", CPU_K6_2C, 366666666, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 33, 33, 17, 17, 44},
|
||||
{"K6-2/380", CPU_K6_2C, 380000000, 4, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 34, 34, 12, 12, 46},
|
||||
{"K6-2/400", CPU_K6_2C, 400000000, 4, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
|
||||
{"K6-2/450", CPU_K6_2C, 450000000, 9/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
|
||||
{"K6-2/475", CPU_K6_2C, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
|
||||
{"K6-2/500", CPU_K6_2C, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
|
||||
{"K6-2/533", CPU_K6_2C, 533333333, 11/2, 32323232, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64},
|
||||
{"K6-2/550", CPU_K6_2C, 550000000, 11/2, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66},
|
||||
|
||||
/*AMD K6-2+/K6-3/K6-3+ (Super Socket 7)*/
|
||||
{"K6-2+/450", CPU_K6_2P, 450000000, 9/2, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
|
||||
{"K6-2+/475", CPU_K6_2P, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
|
||||
{"K6-2+/500", CPU_K6_2P, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
|
||||
{"K6-2+/533", CPU_K6_2P, 533333333, 11/2, 32323232, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 48, 48, 17, 17, 64},
|
||||
{"K6-2+/550", CPU_K6_2P, 550000000, 11/2, 32333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 50, 50, 17, 17, 66},
|
||||
{"K6-III/400", CPU_K6_3, 400000000, 4, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
|
||||
{"K6-III/450", CPU_K6_3, 450000000, 9/2, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
|
||||
{"K6-III+/400", CPU_K6_3P, 400000000, 4, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36, 36, 12, 12, 48},
|
||||
{"K6-III+/450", CPU_K6_3P, 450000000, 9/2, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41, 41, 14, 14, 54},
|
||||
{"K6-III+/475", CPU_K6_3P, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 43, 43, 15, 15, 57},
|
||||
{"K6-III+/500", CPU_K6_3P, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 45, 45, 15, 15, 60},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DEV_BRANCH
|
||||
#ifdef USE_I686
|
||||
CPU cpus_PentiumPro[] = {
|
||||
/*Intel Pentium Pro*/
|
||||
{"Pentium Pro 50", CPU_PENTIUMPRO, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
|
||||
{"Pentium Pro 60" , CPU_PENTIUMPRO, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
|
||||
{"Pentium Pro 66" , CPU_PENTIUMPRO, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
|
||||
{"Pentium Pro 75", CPU_PENTIUMPRO, 75000000, 3/2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium Pro 150", CPU_PENTIUMPRO, 150000000, 5/2, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium Pro 166", CPU_PENTIUMPRO, 166666666, 5/2, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium Pro 180", CPU_PENTIUMPRO, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
|
||||
{"Pentium Pro 200", CPU_PENTIUMPRO, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
|
||||
/*Intel Pentium II OverDrive*/
|
||||
{"Pentium II Overdrive 50", CPU_PENTIUM2D, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
|
||||
{"Pentium II Overdrive 60", CPU_PENTIUM2D, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
|
||||
{"Pentium II Overdrive 66", CPU_PENTIUM2D, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
|
||||
{"Pentium II Overdrive 75", CPU_PENTIUM2D, 75000000, 3/2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium II Overdrive 210", CPU_PENTIUM2D, 210000000, 7/2, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
|
||||
{"Pentium II Overdrive 233", CPU_PENTIUM2D, 233333333, 7/2, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"Pentium II Overdrive 240", CPU_PENTIUM2D, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29},
|
||||
{"Pentium II Overdrive 266", CPU_PENTIUM2D, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"Pentium II Overdrive 270", CPU_PENTIUM2D, 270000000, 9/2, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33},
|
||||
{"Pentium II Overdrive 300/66", CPU_PENTIUM2D, 300000000, 9/2, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
|
||||
{"Pentium II Overdrive 300/60", CPU_PENTIUM2D, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
{"Pentium II Overdrive 333", CPU_PENTIUM2D, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
@@ -132,7 +132,7 @@ static int opSYSEXIT(uint32_t fetchdat)
|
||||
do_seg_load(&cpu_state.seg_ss, sysexit_ss_seg_data);
|
||||
stack32 = 1;
|
||||
|
||||
flushmmucache_cr3();
|
||||
flushmmucache();
|
||||
|
||||
cycles -= timing_call_pm;
|
||||
|
||||
|
||||
@@ -607,6 +607,8 @@ static int opF7_l_a32(uint32_t fetchdat)
|
||||
|
||||
static int opHLT(uint32_t fetchdat)
|
||||
{
|
||||
in_hlt = 0;
|
||||
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
@@ -615,8 +617,10 @@ static int opHLT(uint32_t fetchdat)
|
||||
if (!((cpu_state.flags & I_FLAG) && pic_intpending))
|
||||
{
|
||||
CLOCK_CYCLES_ALWAYS(100);
|
||||
if (!((cpu_state.flags & I_FLAG) && pic_intpending))
|
||||
if (!((cpu_state.flags & I_FLAG) && pic_intpending)) {
|
||||
in_hlt = 1;
|
||||
cpu_state.pc--;
|
||||
}
|
||||
}
|
||||
else
|
||||
CLOCK_CYCLES(5);
|
||||
@@ -831,6 +835,7 @@ static void loadall_load_segment(uint32_t addr, x86seg *s)
|
||||
uint32_t attrib = readmeml(0, addr);
|
||||
uint32_t segdat3 = (attrib >> 16) & 0xff;
|
||||
s->access = (attrib >> 8) & 0xff;
|
||||
s->ar_high = segdat3;
|
||||
s->base = readmeml(0, addr + 4);
|
||||
s->limit = readmeml(0, addr + 8);
|
||||
|
||||
@@ -953,10 +958,8 @@ static int opRSM(uint32_t fetchdat)
|
||||
if (in_smm)
|
||||
{
|
||||
leave_smm();
|
||||
if (smi_latched) {
|
||||
smi_latched = 0;
|
||||
if (smi_latched)
|
||||
enter_smm();
|
||||
}
|
||||
CPU_BLOCK_END();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user