Merge pull request #604 from nerd73/temp

VIA Cyrix III emulation
This commit is contained in:
OBattler
2020-03-23 23:11:59 +01:00
committed by GitHub
12 changed files with 304 additions and 142 deletions

View File

@@ -43,9 +43,9 @@ extern const device_t i430vx_device;
extern const device_t i430tx_device;
#if defined(DEV_BRANCH) && defined(USE_I686)
extern const device_t i440fx_device;
#endif
extern const device_t i440bx_device;
extern const device_t i440zx_device;
#endif
/* NEAT */
extern const device_t neat_device;

View File

@@ -41,23 +41,18 @@ enum
INTEL_430FX_PB640,
INTEL_430HX,
INTEL_430VX,
INTEL_430TX
INTEL_430TX,
#if defined(DEV_BRANCH) && defined(USE_I686)
,INTEL_440FX,
INTEL_440FX,
#endif
INTEL_440BX,
INTEL_440ZX
#endif
};
typedef struct
{
#if defined(DEV_BRANCH) && defined(USE_I686)
uint8_t pm2_cntrl, max_func;
uint8_t regs[2][256], regs_locked[2][256];
#else
uint8_t pm2_cntrl;
uint8_t regs[256];
#endif
int type;
} i4x0_t;
@@ -83,7 +78,6 @@ i4x0_map(uint32_t addr, uint32_t size, int state)
}
#if defined(DEV_BRANCH) && defined(USE_I686)
static void
i4x0_mask_bar(uint8_t *regs)
{
@@ -94,7 +88,6 @@ i4x0_mask_bar(uint8_t *regs)
regs[0x12] = (bar >> 16) & 0xff;
regs[0x13] = (bar >> 24) & 0xff;
}
#endif
static uint8_t
@@ -119,20 +112,12 @@ static void
i4x0_write(int func, int addr, uint8_t val, void *priv)
{
i4x0_t *dev = (i4x0_t *) priv;
#if defined(DEV_BRANCH) && defined(USE_I686)
uint8_t *regs = (uint8_t *) dev->regs[func];
uint8_t *regs_l = (uint8_t *) dev->regs_locked[func];
int i;
#else
uint8_t *regs = (uint8_t *) dev->regs;
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
if (func > dev->max_func)
#else
if (func > 0)
#endif
return;
return;
if ((addr >= 0x10) && (addr < 0x4f))
return;
@@ -141,9 +126,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0x04: /*Command register*/
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
#endif
default:
regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42);
break;
@@ -159,8 +142,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX: case INTEL_430LX: case INTEL_430NX: case INTEL_430HX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440FX: case INTEL_440BX: case INTEL_440ZX:
case INTEL_440FX:
#endif
case INTEL_440BX: case INTEL_440ZX:
regs[0x05] = (regs[0x05] & ~0x01) | (val & 0x01);
break;
}
@@ -178,10 +162,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440FX:
regs[0x07] &= ~(val & 0xf9);
break;
case INTEL_440BX: case INTEL_440ZX:
regs[0x07] &= ~(val & 0xf0);
break;
#endif
case INTEL_440BX: case INTEL_440ZX
regs[0x07] &= ~(val & 0xf0);
break;
}
break;
case 0x0d:
@@ -201,7 +185,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case 0x12:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
@@ -228,7 +211,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#endif
case 0x4f:
switch (dev->type) {
case INTEL_430HX:
@@ -264,13 +246,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440FX:
regs[0x50] = (val & 0xf4);
break;
#endif
case INTEL_440BX:
regs[0x50] = (regs[0x50] & 0x14) | (val & 0xeb);
break;
case INTEL_440ZX:
regs[0x50] = (regs[0x50] & 0x34) | (val & 0xcb);
break;
#endif
}
break;
case 0x51:
@@ -282,10 +265,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440FX:
regs[0x51] = (val & 0xc3);
break;
#endif
case INTEL_440BX: case INTEL_440ZX:
regs[0x51] = (regs[0x50] & 0x70) | (val & 0x8f);
break;
#endif
}
break;
case 0x52: /* Cache Control Register */
@@ -303,11 +286,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
#endif
regs[0x52] = val;
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
regs[0x52] = val & 0x07;
break;
#endif
}
break;
case 0x53:
@@ -397,13 +378,13 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440FX:
regs[0x57] = val & 0x77;
break;
#endif
case INTEL_440BX:
regs[0x57] = val & 0x3f;
break;
case INTEL_440ZX:
regs[0x57] = val & 0x2f;
break;
#endif
}
break;
case 0x58:
@@ -413,9 +394,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x58] = val & 0x01;
break;
case INTEL_430NX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
#endif
regs[0x58] = val & 0x03;
break;
case INTEL_430FX: case INTEL_430FX_PB640:
@@ -494,9 +473,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430LX: case INTEL_430NX:
case INTEL_430HX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440FX: case INTEL_440BX:
case INTEL_440ZX:
case INTEL_440FX:
#endif
case INTEL_440BX: case INTEL_440ZX:
default:
regs[addr] = val;
break;
@@ -515,9 +494,9 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430LX: case INTEL_430NX:
case INTEL_430HX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440FX: case INTEL_440BX:
case INTEL_440ZX:
#endif
case INTEL_440FX:
#endif
case INTEL_440BX: case INTEL_440ZX:
regs[addr] = val;
break;
case INTEL_430VX:
@@ -532,20 +511,20 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_430NX: case INTEL_430HX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440FX: case INTEL_440BX:
case INTEL_440ZX:
case INTEL_440FX:
#endif
case INTEL_440BX: case INTEL_440ZX:
regs[addr] = val;
break;
}
break;
case 0x67:
switch (dev->type) {
case INTEL_430NX: case INTEL_430HX:
case INTEL_430NX: case INTEL_430HX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440FX: case INTEL_440BX:
case INTEL_440ZX:
case INTEL_440FX:
#endif
case INTEL_440BX: case INTEL_440ZX:
regs[addr] = val;
break;
case INTEL_430VX:
@@ -569,39 +548,33 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440FX:
regs[0x68] = val & 0xc0;
break;
#endif
case INTEL_440BX:
regs[0x68] = (regs[0x68] & 0x38) | (val & 0xc7);
break;
case INTEL_440ZX:
regs[0x68] = (regs[0x68] & 0x3f) | (val & 0xc0);
break;
#endif
}
break;
case 0x69:
switch (dev->type) {
case INTEL_430NX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX:
#endif
regs[0x69] = val;
break;
case INTEL_430VX:
regs[0x69] = val & 0x07;
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440ZX:
case INTEL_440ZX:
regs[0x69] = val & 0x3f;
break;
#endif
}
break;
case 0x6a: case 0x6b:
switch (dev->type) {
case INTEL_430NX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX:
#endif
regs[addr] = val;
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
@@ -614,7 +587,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
#endif
}
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case 0x6c: case 0x6d: case 0x6e:
switch (dev->type) {
case INTEL_440BX:
@@ -628,7 +600,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#endif
case 0x70:
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX:
@@ -680,24 +651,19 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_430VX:
regs[0x73] = val & 0x03;
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
regs[0x73] = val;
break;
#endif
}
break;
case 0x74:
switch (dev->type) {
case INTEL_430VX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
#endif
regs[0x74] = val;
break;
}
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case 0x75: case 0x76:
case 0x7b:
switch (dev->type) {
@@ -711,17 +677,14 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[0x77] = val & 0x03;
}
break;
#endif
case 0x78:
switch (dev->type) {
case INTEL_430VX:
regs[0x78] = val & 0xcf;
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
regs[0x78] = val & 0x0f;
break;
#endif
}
break;
case 0x79:
@@ -732,14 +695,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
if (val & 0x40)
io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev);
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
regs[0x79] = val;
break;
#endif
}
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case 0x7a:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
@@ -750,18 +710,15 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#endif
case 0x7c:
switch (dev->type) {
case INTEL_420TX: case INTEL_420ZX:
case INTEL_430LX: case INTEL_430NX:
regs[0x7c] = val & 0x8f;
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440BX: case INTEL_440ZX:
regs[0x7c] = val & 0x1f;
break;
#endif
}
case 0x7d:
switch (dev->type) {
@@ -777,7 +734,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
regs[addr] = val;
break;
}
#if defined(DEV_BRANCH) && defined(USE_I686)
case 0x80:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
@@ -785,7 +741,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#endif
case 0x90:
switch (dev->type) {
case INTEL_430HX:
@@ -795,24 +750,23 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case INTEL_440FX:
regs[0x80] = val & 0x1b;
break;
#endif
case INTEL_440BX: case INTEL_440ZX:
regs[0x7c] = val;
break;
#endif
}
break;
case 0x91:
switch (dev->type) {
case INTEL_430HX:
case INTEL_430HX: case INTEL_440BX:
#if defined(DEV_BRANCH) && defined(USE_I686)
case INTEL_440FX: case INTEL_440BX:
case INTEL_440FX:
#endif
/* Not applicable on 82443ZX. */
regs[0x91] &= ~(val & 0x11);
break;
}
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case 0x92:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
@@ -820,6 +774,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#if defined(DEV_BRANCH) && defined(USE_I686)
case 0x93:
switch (dev->type) {
case INTEL_440FX:
@@ -828,6 +783,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#endif
case 0xa8: case 0xa9:
switch (dev->type) {
case INTEL_440BX: case INTEL_440ZX:
@@ -999,7 +955,6 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
}
break;
#endif
}
}
@@ -1009,19 +964,11 @@ i4x0_read(int func, int addr, void *priv)
{
i4x0_t *dev = (i4x0_t *) priv;
uint8_t ret = 0xff;
#if defined(DEV_BRANCH) && defined(USE_I686)
uint8_t *regs = (uint8_t *) dev->regs[func];
#else
uint8_t *regs = (uint8_t *) dev->regs;
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
if (func > dev->max_func)
#else
if (func > 0)
#endif
ret = 0xff;
else {
if (func > dev->max_func)
ret = 0xff;
else {
ret = regs[addr];
#if defined(DEV_BRANCH) && defined(USE_I686)
/* Special behavior for 440FX register 0x93 which is basically TRC in PCI space
@@ -1054,12 +1001,10 @@ i4x0_reset(void *priv)
else
i4x0_write(0, 0x72, 0x00, priv);
#if defined(DEV_BRANCH) && defined(USE_I686)
if ((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) {
for (i = 0; i <= dev->max_func; i++)
memset(dev->regs_locked[i], 0x00, 256 * sizeof(uint8_t));
}
#endif
smbase = 0xa0000;
}
@@ -1084,11 +1029,7 @@ static void
dev->type = info->local & 0xff;
#if defined(DEV_BRANCH) && defined(USE_I686)
regs = (uint8_t *) dev->regs[0];
#else
regs = (uint8_t *) dev->regs;
#endif
// This is off by default and has to be moved to the appropriate register handling.
// io_sethandler(0x0022, 0x01, pm2_cntrl_read, NULL, NULL, pm2_cntrl_write, NULL, NULL, dev);
@@ -1234,6 +1175,7 @@ static void
regs[0x71] = 0x10;
regs[0x72] = 0x02;
break;
#endif
case INTEL_440BX: case INTEL_440ZX:
regs[0x7a] = (info->local >> 8) & 0xff;
dev->max_func = (regs[0x7a] & 0x02) ? 0 : 1;
@@ -1260,7 +1202,6 @@ static void
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
break;
#endif
}
regs[0x04] = 0x06; regs[0x07] = 0x02;
@@ -1283,7 +1224,6 @@ static void
smbase = 0xa0000;
#if defined(DEV_BRANCH) && defined(USE_I686)
if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) {
regs = (uint8_t *) dev->regs[1];
@@ -1299,7 +1239,6 @@ static void
regs[0x24] = 0xf0; regs[0x25] = 0xff;
regs[0x3e] = 0x80;
}
#endif
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev);
@@ -1457,7 +1396,7 @@ const device_t i440fx_device =
NULL
};
#endif
const device_t i440bx_device =
{
"Intel 82443BX",
@@ -1486,4 +1425,3 @@ const device_t i440zx_device =
NULL,
NULL
};
#endif

View File

@@ -226,8 +226,8 @@ extern void x386_dynarec_log(const char *fmt, ...);
#include "x86_ops_shift.h"
#ifdef USE_NEW_DYNAREC
#include "x86_ops_amd.h"
#include "x86_ops_3dnow.h"
#endif
#include "x86_ops_3dnow.h"
static int op0F_w_a16(uint32_t fetchdat)
@@ -636,7 +636,6 @@ const OpFn OP_TABLE(winchip_0f)[1024] =
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
};
#ifdef USE_NEW_DYNAREC
const OpFn OP_TABLE(winchip2_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
@@ -727,7 +726,6 @@ const OpFn OP_TABLE(winchip2_0f)[1024] =
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
};
#endif
const OpFn OP_TABLE(pentium_0f)[1024] =
{

View File

@@ -76,13 +76,11 @@ enum {
CPUID_FXSR = (1 << 24)
};
#ifdef USE_NEW_DYNAREC
/*Addition flags returned by CPUID function 0x80000001*/
enum
{
CPUID_3DNOW = (1 << 31)
};
#endif
#ifdef USE_DYNAREC
@@ -131,9 +129,7 @@ const OpFn *x86_opcodes_df_a16;
const OpFn *x86_opcodes_df_a32;
const OpFn *x86_opcodes_REPE;
const OpFn *x86_opcodes_REPNE;
#ifdef USE_NEW_DYNAREC
const OpFn *x86_opcodes_3DNOW;
#endif
int in_smm = 0, smi_line = 0, smi_latched = 0;
uint32_t smbase = 0x30000;
@@ -177,11 +173,6 @@ uint64_t pmc[2] = {0, 0};
uint16_t temp_seg_data[4] = {0, 0, 0, 0};
#if defined(DEV_BRANCH) && defined(USE_I686)
uint16_t cs_msr = 0;
uint32_t esp_msr = 0;
uint32_t eip_msr = 0;
uint64_t apic_base_msr = 0;
uint64_t mtrr_cap_msr = 0;
uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -189,8 +180,14 @@ uint64_t mtrr_fix64k_8000_msr = 0;
uint64_t mtrr_fix16k_8000_msr = 0;
uint64_t mtrr_fix16k_a000_msr = 0;
uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t pat_msr = 0;
uint64_t mtrr_deftype_msr = 0;
#if defined(DEV_BRANCH) && defined(USE_I686)
uint16_t cs_msr = 0;
uint32_t esp_msr = 0;
uint32_t eip_msr = 0;
uint64_t apic_base_msr = 0;
uint64_t pat_msr = 0;
uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t ecx17_msr = 0;
uint64_t ecx79_msr = 0;
@@ -352,9 +349,7 @@ cpu_set(void)
#endif
x86_opcodes_REPE = ops_REPE;
x86_opcodes_REPNE = ops_REPNE;
#ifdef USE_NEW_DYNAREC
x86_opcodes_3DNOW = ops_3DNOW;
#endif
#ifdef USE_DYNAREC
x86_dynarec_opcodes_REPE = dynarec_ops_REPE;
x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE;
@@ -1022,7 +1017,9 @@ cpu_set(void)
timing_jmp_pm_gate = 17;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_winchip2);
#endif
break;
#endif
@@ -1601,6 +1598,49 @@ cpu_set(void)
#endif
break;
#endif
case CPU_CYRIX3S:
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f);
#else
x86_setopcodes(ops_386, ops_winchip2_0f);
#endif
timing_rr = 1; /*register dest - register src*/
timing_rm = 2; /*register dest - memory src*/
timing_mr = 2; /*memory dest - register src*/
timing_mm = 3;
timing_rml = 2; /*register dest - memory src long*/
timing_mrl = 2; /*memory dest - register src long*/
timing_mml = 3;
timing_bt = 3-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21);
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
/*unknown*/
timing_int_rm = 26;
timing_int_v86 = 82;
timing_int_pm = 44;
timing_int_pm_outer = 71;
timing_iret_rm = 7;
timing_iret_v86 = 26;
timing_iret_pm = 10;
timing_iret_pm_outer = 26;
timing_call_rm = 4;
timing_call_pm = 15;
timing_call_pm_gate = 26;
timing_call_pm_gate_inner = 35;
timing_retf_rm = 4;
timing_retf_pm = 7;
timing_retf_pm_outer = 23;
timing_jmp_rm = 5;
timing_jmp_pm = 7;
timing_jmp_pm_gate = 17;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_winchip);
#endif
break;
default:
fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type);
@@ -1755,7 +1795,7 @@ cpu_CPUID(void)
}
break;
case 1:
EAX = 0x580;
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
if (cpu_has_feature(CPU_FEATURE_CX8))
@@ -1767,7 +1807,7 @@ cpu_CPUID(void)
EAX = 0x80000005;
break;
case 0x80000001:
EAX = 0x580;
EAX = CPUID;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
@@ -2281,7 +2321,65 @@ cpu_CPUID(void)
break;
#endif
#endif
case CPU_CYRIX3S:
switch (EAX)
{
case 0:
EAX = 1;
if (msr.fcr2 & (1 << 14))
{
EBX = msr.fcr3 >> 32;
ECX = msr.fcr3 & 0xffffffff;
EDX = msr.fcr2 >> 32;
}
else
{
EBX = 0x746e6543; /*CentaurHauls*/
ECX = 0x736c7561;
EDX = 0x48727561;
}
break;
case 1:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 9))
EDX |= CPUID_MMX;
break;
case 0x80000000:
EAX = 0x80000005;
break;
case 0x80000001:
EAX = CPUID;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
if (msr.fcr & (1 << 9))
EDX |= CPUID_MMX;
if (cpu_has_feature(CPU_FEATURE_3DNOW))
EDX |= CPUID_3DNOW;
break;
case 0x80000002: /*Processor name string*/
EAX = 0x20414956; /*VIA Samuel*/
EBX = 0x756d6153;
ECX = 0x00006c65;
EDX = 0x00000000;
break;
case 0x80000005: /*Cache information*/
EBX = 0x08800880; /*TLBs*/
ECX = 0x40040120; /*L1 data cache*/
EDX = 0x40020120; /*L1 instruction cache*/
break;
default:
EAX = EBX = ECX = EDX = 0;
break;
}
break;
}
}
@@ -2363,7 +2461,80 @@ void cpu_RDMSR()
break;
}
break;
case CPU_CYRIX3S:
EAX = EDX = 0;
switch (ECX)
{
case 0x10:
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
break;
case 0x2a:
if (cpu_dmulti == 3)
EAX = ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22));
else if (cpu_dmulti == 3.5)
EAX = ((0 << 25) | (1 << 24) | (0 << 23) | (1 << 22));
else if (cpu_dmulti == 4)
EAX = ((0 << 25) | (0 << 24) | (1 << 23) | (0 << 22));
else if (cpu_dmulti == 4.5)
EAX = ((0 << 25) | (1 << 24) | (1 << 23) | (0 << 22));
else if (cpu_dmulti == 5)
EAX = 0;
else if (cpu_dmulti == 5.5)
EAX = ((0 << 25) | (1 << 24) | (0 << 23) | (0 << 22));
else if (cpu_dmulti == 6)
EAX = ((1 << 25) | (0 << 24) | (1 << 23) | (1 << 22));
else if (cpu_dmulti == 6.5)
EAX = ((1 << 25) | (1 << 24) | (1 << 23) | (1 << 22));
else if (cpu_dmulti == 7)
EAX = ((1 << 25) | (0 << 24) | (0 << 23) | (1 << 22));
else
EAX = ((0 << 25) | (0 << 24) | (0 << 23) | (1 << 22));
break;
case 0x1107:
EAX = msr.fcr;
break;
case 0x1108:
EAX = msr.fcr2 & 0xffffffff;
EDX = msr.fcr2 >> 32;
break;
case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207:
case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F:
if (ECX & 1)
{
EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff;
EDX = mtrr_physmask_msr[(ECX - 0x200) >> 1] >> 32;
}
else
{
EAX = mtrr_physbase_msr[(ECX - 0x200) >> 1] & 0xffffffff;
EDX = mtrr_physbase_msr[(ECX - 0x200) >> 1] >> 32;
}
break;
case 0x250:
EAX = mtrr_fix64k_8000_msr & 0xffffffff;
EDX = mtrr_fix64k_8000_msr >> 32;
break;
case 0x258:
EAX = mtrr_fix16k_8000_msr & 0xffffffff;
EDX = mtrr_fix16k_8000_msr >> 32;
break;
case 0x259:
EAX = mtrr_fix16k_a000_msr & 0xffffffff;
EDX = mtrr_fix16k_a000_msr >> 32;
break;
case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F:
EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff;
EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32;
break;
case 0x2FF:
EAX = mtrr_deftype_msr & 0xffffffff;
EDX = mtrr_deftype_msr >> 32;
break;
}
break;
#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))
case CPU_K5:
case CPU_5K86:
@@ -2791,8 +2962,51 @@ void cpu_WRMSR()
msr.fcr3 = EAX | ((uint64_t)EDX << 32);
break;
}
break;
case CPU_CYRIX3S:
switch (ECX)
{
case 0x10:
tsc = EAX | ((uint64_t)EDX << 32);
break;
case 0x1107:
msr.fcr = EAX;
if (EAX & (1 << 1))
cpu_features |= CPU_FEATURE_CX8;
else
cpu_features &= ~CPU_FEATURE_CX8;
break;
case 0x1108:
msr.fcr2 = EAX | ((uint64_t)EDX << 32);
break;
case 0x1109:
msr.fcr3 = EAX | ((uint64_t)EDX << 32);
break;
case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207:
case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F:
if (ECX & 1)
mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32);
else
mtrr_physbase_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32);
break;
case 0x250:
mtrr_fix64k_8000_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x258:
mtrr_fix16k_8000_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x259:
mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F:
mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32);
break;
case 0x2FF:
mtrr_deftype_msr = EAX | ((uint64_t)EDX << 32);
break;
}
break;
#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && defined(USE_AMD_K))
case CPU_K5:
case CPU_5K86:

View File

@@ -76,6 +76,7 @@ enum {
CPU_K6_2P,
CPU_K6_3P,
#endif
CPU_CYRIX3S,
#if defined(DEV_BRANCH) && defined(USE_I686)
CPU_PENTIUMPRO, /* 686 class CPUs */
CPU_PENTIUM2,
@@ -152,6 +153,7 @@ extern CPU cpus_6x86[];
#ifdef USE_NEW_DYNAREC
extern CPU cpus_6x86SS7[];
#endif
extern CPU cpus_Cyrix3[];
#if defined(DEV_BRANCH) && defined(USE_I686)
extern CPU cpus_PentiumPro[];
extern CPU cpus_PentiumII[];
@@ -214,9 +216,7 @@ typedef union {
int16_t sw[4];
uint8_t b[8];
int8_t sb[8];
#ifdef USE_NEW_DYNAREC
float f[2];
#endif
} MMX_REG;
typedef struct {

View File

@@ -736,6 +736,7 @@ CPU cpus_PentiumII[] = {
{"Pentium II Deschutes 400", CPU_PENTIUM2D, 400000000, 4, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48},
{"Pentium II Deschutes 450", CPU_PENTIUM2D, 450000000, 9/2, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
CPU cpus_PGA370[] = {
@@ -745,3 +746,20 @@ CPU cpus_PGA370[] = {
};
#endif
#endif
CPU cpus_Cyrix3[] = {
/*VIA Cyrix III (Samuel)*/
{"Cyrix III 66", CPU_CYRIX3S, 66666666, 1, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 8}, /*66 MHz version*/
{"Cyrix III 233", CPU_CYRIX3S, 233333333, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, 28},
{"Cyrix III 266", CPU_CYRIX3S, 266666666, 4, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 32},
{"Cyrix III 300", CPU_CYRIX3S, 300000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 27, 27, 13, 13, 36},
{"Cyrix III 333", CPU_CYRIX3S, 333333333, 5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 30, 30, 15, 15, 40},
{"Cyrix III 350", CPU_CYRIX3S, 350000000, 3.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 32, 32, 11, 11, 42},
{"Cyrix III 400", CPU_CYRIX3S, 400000000, 4, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 36, 36, 12, 12, 48},
{"Cyrix III 450", CPU_CYRIX3S, 450000000, 4.5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 41, 41, 14, 14, 54}, /*^ is lower P2 speeds to allow emulation below 466 mhz*/
{"Cyrix III 500", CPU_CYRIX3S, 500000000, 5, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC, 45, 45, 15, 15, 60},
{"Cyrix III 550", CPU_CYRIX3S, 550000000, 5.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 50, 50, 17, 17, 66},
{"Cyrix III 600", CPU_CYRIX3S, 600000000, 6, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 54, 54, 18, 18, 72},
{"Cyrix III 650", CPU_CYRIX3S, 650000000, 6.5, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 58, 58, 20, 20, 78},
{"Cyrix III 700", CPU_CYRIX3S, 700000000, 7, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC, 62, 62, 21, 21, 84},
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

View File

@@ -70,9 +70,7 @@ extern const OpFn *x86_dynarec_opcodes_df_a16;
extern const OpFn *x86_dynarec_opcodes_df_a32;
extern const OpFn *x86_dynarec_opcodes_REPE;
extern const OpFn *x86_dynarec_opcodes_REPNE;
#ifdef USE_NEW_DYNAREC
extern const OpFn *x86_dynarec_opcodes_3DNOW;
#endif
extern const OpFn dynarec_ops_286[1024];
extern const OpFn dynarec_ops_286_0f[1024];
@@ -83,9 +81,7 @@ extern const OpFn dynarec_ops_386_0f[1024];
extern const OpFn dynarec_ops_486_0f[1024];
extern const OpFn dynarec_ops_winchip_0f[1024];
#ifdef USE_NEW_DYNAREC
extern const OpFn dynarec_ops_winchip2_0f[1024];
#endif
extern const OpFn dynarec_ops_pentium_0f[1024];
extern const OpFn dynarec_ops_pentiummmx_0f[1024];
@@ -175,9 +171,7 @@ extern const OpFn *x86_opcodes_df_a16;
extern const OpFn *x86_opcodes_df_a32;
extern const OpFn *x86_opcodes_REPE;
extern const OpFn *x86_opcodes_REPNE;
#ifdef USE_NEW_DYNAREC
extern const OpFn *x86_opcodes_3DNOW;
#endif
extern const OpFn ops_286[1024];
extern const OpFn ops_286_0f[1024];
@@ -188,9 +182,7 @@ extern const OpFn ops_386_0f[1024];
extern const OpFn ops_486_0f[1024];
extern const OpFn ops_winchip_0f[1024];
#ifdef USE_NEW_DYNAREC
extern const OpFn ops_winchip2_0f[1024];
#endif
extern const OpFn ops_pentium_0f[1024];
extern const OpFn ops_pentiummmx_0f[1024];
@@ -253,9 +245,7 @@ extern const OpFn ops_fpu_686_df_a32[256];
extern const OpFn ops_REPE[1024];
extern const OpFn ops_REPNE[1024];
#ifdef USE_NEW_DYNAREC
extern const OpFn ops_3DNOW[256];
#endif
#define C0 (1<<8)
#define C1 (1<<9)

View File

@@ -104,7 +104,7 @@ machine_at_s1668_init(const machine_t *model)
return ret;
}
#endif
int
machine_at_6abx3_init(const machine_t *model)
{
@@ -133,12 +133,11 @@ machine_at_6abx3_init(const machine_t *model)
// device_add(&w83977tf_device);
// device_add(&intel_flash_bxt_device);
// device_add(&sst_flash_29ee020_device);
device_add(&sst_flash_39sf020_device);
device_add(&intel_flash_bxt_device);
return ret;
}
#if defined(DEV_BRANCH) && defined(USE_I686)
int
machine_at_p2bls_init(const machine_t *model)
{

View File

@@ -304,8 +304,10 @@ extern const device_t *at_pb640_get_device(void);
#if defined(DEV_BRANCH) && defined(USE_I686)
extern int machine_at_i440fx_init(const machine_t *);
extern int machine_at_s1668_init(const machine_t *);
#endif
extern int machine_at_6abx3_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_I686) /*P2B-LS has no VIA C3 BIOS support, so further investigation may be needed*/
extern int machine_at_p2bls_init(const machine_t *);
extern int machine_at_p6bxt_init(const machine_t *);
extern int machine_at_63a_init(const machine_t *);

View File

@@ -61,7 +61,6 @@
#define MACHINE_CPUS_PENTIUM_SS7 MACHINE_CPUS_PENTIUM_S7
#endif
const machine_t machines[] = {
{ "[8088] AMI XT clone", "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL },
{ "[8088] Compaq Portable", "portable", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL },
@@ -237,8 +236,12 @@ const machine_t machines[] = {
{ "[Socket 8 FX] Tyan Titan-Pro AT", "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_i440fx_init, NULL },
{ "[Socket 8 FX] Tyan Titan-Pro ATX", "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 127, machine_at_s1668_init, NULL },
{ "[Slot 1 BX] Lucky Star 6ABX3", "6abx3", {{"Intel", cpus_PentiumII}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_6abx3_init, NULL },
{ "[Slot 1 BX] ASUS P2B-LS", "p2bls", {{"Intel", cpus_PentiumII}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p2bls_init, NULL },
{ "[Slot 1 BX] Lucky Star 6ABX3", "6abx3", {{"Intel", cpus_PentiumII}, {"VIA", cpus_Cyrix3},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_6abx3_init, NULL },
#else
{ "[Slot 1 BX] Lucky Star 6ABX3", "6abx3", {{"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_6abx3_init, NULL },
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
{ "[Slot 1 BX] ASUS P2B-LS", "p2bls", {{"Intel", cpus_PentiumII}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p2bls_init, NULL },
{ "[Socket 370 BX] ECS P6BXT-A+", "p6bxt", {{"Intel", cpus_PGA370}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p6bxt_init, NULL },
{ "[Socket 370 ZX] Soltek SL-63A1", "63a", {{"Intel", cpus_PGA370}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_63a_init, NULL },
#endif

View File

@@ -478,7 +478,6 @@ endif
ifeq ($(I686), y)
OPTS += -DUSE_I686
DEVBROBJ += m_at_socket8.o
endif
ifeq ($(LASERXT), y)
@@ -595,7 +594,8 @@ MCHOBJ := machine.o machine_table.o \
m_ps2_isa.o m_ps2_mca.o \
m_at_compaq.o \
m_at_286_386sx.o m_at_386dx_486.o \
m_at_socket4_5.o m_at_socket7_s7.o
m_at_socket4_5.o m_at_socket7_s7.o \
m_at_socket8.o
DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \
sio_acc3221.o \

View File

@@ -484,7 +484,6 @@ endif
ifeq ($(I686), y)
OPTS += -DUSE_I686
DEVBROBJ += m_at_socket8.o
endif
ifeq ($(LASERXT), y)
@@ -600,7 +599,8 @@ MCHOBJ := machine.o machine_table.o \
m_ps2_isa.o m_ps2_mca.o \
m_at_compaq.o \
m_at_286_386sx.o m_at_386dx_486.o \
m_at_socket4_5.o m_at_socket7_s7.o
m_at_socket4_5.o m_at_socket7_s7.o \
m_at_socket8.o
DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postcard.o $(SERIAL) \
sio_acc3221.o \