ACPI, SMM, and PIIX fixes, fixes quite a few boards, also fixed the Via Apollo series northbridge ID's, some CPU instructions on both 808x and 286+, and added SMM to 486's (Intel and AMD), WinChip and WinChip 2, and VIA Cyrix III, also removed the TC430HX and the Toshiba machine from the Dev branch.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <86box/pit.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/machine.h>
|
||||
#include "386_common.h"
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#include "codegen.h"
|
||||
@@ -303,6 +304,9 @@ exec386(int cycs)
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
}
|
||||
} else if (nmi && nmi_enable && nmi_mask) {
|
||||
if (AT && (cpu_fast_off_flags & 0x20000000))
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
|
||||
@@ -147,6 +147,11 @@ enum SMMRAM_Fields_386_To_P5 {
|
||||
SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */
|
||||
SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */
|
||||
SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */
|
||||
SMRAM_FIELD_AM486_CR2, /* 0F4 */
|
||||
SMRAM_FIELD_AM486_DR0, /* 0F0 */
|
||||
SMRAM_FIELD_AM486_DR1, /* 0EC */
|
||||
SMRAM_FIELD_AM486_DR2, /* 0E8 */
|
||||
SMRAM_FIELD_AM486_DR3, /* 0E4 */
|
||||
SMRAM_FIELD_P5_LAST
|
||||
};
|
||||
|
||||
@@ -459,6 +464,15 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt)
|
||||
saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base;
|
||||
saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit;
|
||||
saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8);
|
||||
|
||||
/* Am486/5x86 stuff */
|
||||
if (!is_pentium) {
|
||||
saved_state[SMRAM_FIELD_AM486_CR2] = cr2;
|
||||
saved_state[SMRAM_FIELD_AM486_DR0] = dr[0];
|
||||
saved_state[SMRAM_FIELD_AM486_DR1] = dr[1];
|
||||
saved_state[SMRAM_FIELD_AM486_DR2] = dr[2];
|
||||
saved_state[SMRAM_FIELD_AM486_DR3] = dr[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -564,6 +578,15 @@ smram_restore_state_p5(uint32_t *saved_state)
|
||||
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
|
||||
smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET];
|
||||
|
||||
/* Am486/5x86 stuff */
|
||||
if (!is_pentium) {
|
||||
cr2 = saved_state[SMRAM_FIELD_AM486_CR2];
|
||||
dr[0] = saved_state[SMRAM_FIELD_AM486_DR0];
|
||||
dr[1] = saved_state[SMRAM_FIELD_AM486_DR1];
|
||||
dr[2] = saved_state[SMRAM_FIELD_AM486_DR2];
|
||||
dr[3] = saved_state[SMRAM_FIELD_AM486_DR3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1014,7 +1037,7 @@ enter_smm(int in_hlt)
|
||||
|
||||
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
|
||||
|
||||
if (is_pentium) /* Intel P5 (Pentium) */
|
||||
if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */
|
||||
smram_save_state_p5(saved_state, in_hlt);
|
||||
else if (is_k5 || is_k6) /* AMD K5 and K6 */
|
||||
smram_save_state_amd_k(saved_state, in_hlt);
|
||||
@@ -1086,6 +1109,9 @@ enter_smm(int in_hlt)
|
||||
void
|
||||
enter_smm_check(int in_hlt)
|
||||
{
|
||||
if (smi_line && (cpu_fast_off_flags & 0x80000000))
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
|
||||
if ((in_smm == 0) && smi_line) {
|
||||
#ifdef ENABLE_386_COMMON_LOG
|
||||
x386_common_log("SMI while not in SMM\n");
|
||||
@@ -1136,8 +1162,8 @@ leave_smm(void)
|
||||
smram_restore_state_p6(saved_state);
|
||||
|
||||
/* Maybe we need this? */
|
||||
if (smbase == 0x00030000)
|
||||
smbase = 0x000a0000;
|
||||
// if (smbase == 0x00030000)
|
||||
// smbase = 0x000a0000;
|
||||
|
||||
in_smm = 0;
|
||||
mem_mapping_recalc(0x00030000, 0x00020000);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/machine.h>
|
||||
#ifdef USE_DYNAREC
|
||||
#include "codegen.h"
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
@@ -39,8 +40,6 @@ 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;
|
||||
|
||||
|
||||
#define SYSENTER_LOG 1
|
||||
#define ENABLE_386_DYNAREC_LOG 1
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
|
||||
|
||||
@@ -324,6 +323,10 @@ void exec386_dynarec(int cycs)
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
if (in_smm)
|
||||
x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat);
|
||||
#endif
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
@@ -539,6 +542,10 @@ void exec386_dynarec(int cycs)
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
if (in_smm)
|
||||
x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat);
|
||||
#endif
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
@@ -627,6 +634,10 @@ void exec386_dynarec(int cycs)
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
if (in_smm)
|
||||
x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat);
|
||||
#endif
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
@@ -744,6 +755,9 @@ void exec386_dynarec(int cycs)
|
||||
}
|
||||
else if (nmi && nmi_enable && nmi_mask)
|
||||
{
|
||||
if (AT && (cpu_fast_off_flags & 0x20000000))
|
||||
cpu_fast_off_count = cpu_fast_off_val + 1;
|
||||
|
||||
CPU_BLOCK_END();
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
#define SYSENTER_LOG 1
|
||||
|
||||
static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
|
||||
@@ -899,6 +899,10 @@ makeznptable(void)
|
||||
static void
|
||||
reset_common(int hard)
|
||||
{
|
||||
/* Make sure to gracefully leave SMM. */
|
||||
if (in_smm)
|
||||
leave_smm();
|
||||
|
||||
biu_cycles = 0;
|
||||
in_rep = 0;
|
||||
in_lock = 0;
|
||||
@@ -1681,14 +1685,6 @@ stos(int bits)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
da(void)
|
||||
{
|
||||
set_pzs(8);
|
||||
wait(2, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
aa(void)
|
||||
{
|
||||
@@ -1875,58 +1871,81 @@ execx86(int cycs)
|
||||
break;
|
||||
|
||||
case 0x27: /*DAA*/
|
||||
wait(1, 0);
|
||||
cpu_dest = AL;
|
||||
set_of(0);
|
||||
temp = !!(cpu_state.flags & A_FLAG);
|
||||
if ((cpu_state.flags & A_FLAG) || (AL & 0x0f) > 9) {
|
||||
cpu_data = AL + 6;
|
||||
AL = (uint8_t) cpu_data;
|
||||
cpu_src = 6;
|
||||
cpu_data = cpu_dest + cpu_src;
|
||||
set_of_add(8);
|
||||
cpu_dest = cpu_data;
|
||||
set_af(1);
|
||||
if ((cpu_data & 0x100) != 0)
|
||||
set_cf(1);
|
||||
}
|
||||
if ((cpu_state.flags & C_FLAG) || AL > 0x9f) {
|
||||
AL += 0x60;
|
||||
if ((cpu_state.flags & C_FLAG) || AL > (temp ? 0x9f : 0x99)) {
|
||||
cpu_src = 0x60;
|
||||
cpu_data = cpu_dest + cpu_src;
|
||||
set_of_add(8);
|
||||
cpu_dest = cpu_data;
|
||||
set_cf(1);
|
||||
}
|
||||
da();
|
||||
AL = cpu_dest;
|
||||
set_pzs(8);
|
||||
wait(3, 0);
|
||||
break;
|
||||
case 0x2F: /*DAS*/
|
||||
wait(1, 0);
|
||||
temp = AL;
|
||||
cpu_dest = AL;
|
||||
set_of(0);
|
||||
temp = !!(cpu_state.flags & A_FLAG);
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) {
|
||||
cpu_data = AL - 6;
|
||||
AL = (uint8_t) cpu_data;
|
||||
cpu_src = 6;
|
||||
cpu_data = cpu_dest + cpu_src;
|
||||
set_of_sub(8);
|
||||
cpu_dest = cpu_data;
|
||||
set_af(1);
|
||||
if ((cpu_data & 0x100) != 0)
|
||||
set_cf(1);
|
||||
}
|
||||
if ((cpu_state.flags & C_FLAG) || temp > 0x9f) {
|
||||
AL -= 0x60;
|
||||
if ((cpu_state.flags & C_FLAG) || AL > (temp ? 0x9f : 0x99)) {
|
||||
cpu_src = 0x60;
|
||||
cpu_data = cpu_dest - cpu_src;
|
||||
set_of_sub(8);
|
||||
cpu_dest = cpu_data;
|
||||
set_cf(1);
|
||||
}
|
||||
da();
|
||||
AL = cpu_dest;
|
||||
set_pzs(8);
|
||||
wait(3, 0);
|
||||
break;
|
||||
case 0x37: /*AAA*/
|
||||
wait(1, 0);
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) {
|
||||
AL += 6;
|
||||
cpu_src = 6;
|
||||
++AH;
|
||||
set_ca();
|
||||
} else {
|
||||
cpu_src = 0;
|
||||
clear_ca();
|
||||
wait(1, 0);
|
||||
}
|
||||
cpu_dest = AL;
|
||||
cpu_data = cpu_dest + cpu_src;
|
||||
AL = cpu_data;
|
||||
set_of_add(8);
|
||||
aa();
|
||||
break;
|
||||
case 0x3F: /*AAS*/
|
||||
wait(1, 0);
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) {
|
||||
AL -= 6;
|
||||
cpu_src = 6;
|
||||
--AH;
|
||||
set_ca();
|
||||
} else {
|
||||
cpu_src = 0;
|
||||
clear_ca();
|
||||
wait(1, 0);
|
||||
}
|
||||
cpu_dest = AL;
|
||||
cpu_data = cpu_dest - cpu_src;
|
||||
AL = cpu_data;
|
||||
set_of_sub(8);
|
||||
aa();
|
||||
break;
|
||||
|
||||
|
||||
@@ -154,6 +154,8 @@ int cpu_prefetch_cycles, cpu_prefetch_width,
|
||||
int cpu_waitstates;
|
||||
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
|
||||
int cpu_pci_speed, cpu_alt_reset;
|
||||
uint16_t cpu_fast_off_count, cpu_fast_off_val;
|
||||
uint32_t cpu_fast_off_flags;
|
||||
|
||||
uint32_t cpu_features;
|
||||
|
||||
@@ -165,7 +167,7 @@ int is286,
|
||||
hascache,
|
||||
isibm486,
|
||||
israpidcad,
|
||||
is_pentium, is_k5, is_k6, is_p6;
|
||||
is_am486, is_pentium, is_k5, is_k6, is_p6;
|
||||
|
||||
int hasfpu;
|
||||
|
||||
@@ -298,14 +300,20 @@ cpu_set(void)
|
||||
is286 = (cpu_s->cpu_type >= CPU_286);
|
||||
is386 = (cpu_s->cpu_type >= CPU_386SX);
|
||||
israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
isibm486 = (cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL);
|
||||
isibm486 = (cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL);
|
||||
is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
is486sx = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type < CPU_i486SX2);
|
||||
is486sx2 = (cpu_s->cpu_type >= CPU_i486SX2) && (cpu_s->cpu_type < CPU_i486DX);
|
||||
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_am486 = (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486SX2) || (cpu_s->cpu_type == CPU_Am486DX) ||
|
||||
(cpu_s->cpu_type == CPU_Am486DX2) || (cpu_s->cpu_type == CPU_Am486DX4) || (cpu_s->cpu_type == CPU_Am5x86);
|
||||
is_pentium = (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX);
|
||||
/* Not Pentiums, but they share the same SMM save state table layout. */
|
||||
is_pentium |= (cpu_s->cpu_type == CPU_i486DX2) || (cpu_s->cpu_type == CPU_iDX4);
|
||||
/* The WinChip datasheet claims these are Pentium-compatible. */
|
||||
is_pentium |= (cpu_s->cpu_type == CPU_WINCHIP) || (cpu_s->cpu_type == CPU_WINCHIP2);
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
|
||||
is_k5 = (cpu_s->cpu_type == CPU_K5) || (cpu_s->cpu_type == CPU_5K86);
|
||||
#else
|
||||
@@ -317,6 +325,8 @@ cpu_set(void)
|
||||
(cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P);
|
||||
is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) ||
|
||||
(cpu_s->cpu_type == CPU_PENTIUM2D);
|
||||
/* The Samuel 2 datasheet claims it's Celeron-compatible. */
|
||||
is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S);
|
||||
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(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
|
||||
@@ -376,7 +376,7 @@ 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 is_pentium, is_k5, is_k6, is_p6;
|
||||
extern int is_am486, is_pentium, is_k5, is_k6, is_p6;
|
||||
extern int hascache;
|
||||
extern int isibm486;
|
||||
extern int is_rapidcad;
|
||||
@@ -479,6 +479,9 @@ extern int timing_misaligned;
|
||||
|
||||
extern int in_sys;
|
||||
|
||||
extern uint16_t cpu_fast_off_count, cpu_fast_off_val;
|
||||
extern uint32_t cpu_fast_off_flags;
|
||||
|
||||
extern CPU cpus_pcjr[]; // FIXME: should be in machine file!
|
||||
extern CPU cpus_europc[]; // FIXME: should be in machine file!
|
||||
extern CPU cpus_pc1512[]; // FIXME: should be in machine file!
|
||||
|
||||
@@ -232,14 +232,14 @@ CPU cpus_i486S1[] = {
|
||||
{"i486SX/20", CPU_i486SX, 20000000, 1, 0x420, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/25", CPU_i486SX, 25000000, 1, 0x422, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/33", CPU_i486SX, 33333333, 1, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486SX2/50", CPU_i486SX, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
|
||||
{"i486SX2/50", CPU_i486SX2, 50000000, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
|
||||
{"i486DX/25", CPU_i486DX, 25000000, 1, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486DX/33", CPU_i486DX, 33333333, 1, 0x414, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486DX/50", CPU_i486DX, 50000000, 1, 0x411, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
|
||||
{"i486DX2/40", CPU_i486DX, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},
|
||||
{"i486DX2/50", CPU_i486DX, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486DX2/66", CPU_i486DX, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"i486DX2/40", CPU_i486DX2, 40000000, 2, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},
|
||||
{"i486DX2/50", CPU_i486DX2, 50000000, 2, 0x433, 0x433, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486DX2/66", CPU_i486DX2, 66666666, 2, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3, 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, 0x1480, 0x1480, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
@@ -276,14 +276,14 @@ CPU cpus_i486[] = {
|
||||
{"i486SX/20", CPU_i486SX, 20000000, 1.0, 0x420, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486SX/25", CPU_i486SX, 25000000, 1.0, 0x422, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486SX/33", CPU_i486SX, 33333333, 1.0, 0x42a, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"i486SX2/50", CPU_i486SX, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8},
|
||||
{"i486SX2/50", CPU_i486SX2, 50000000, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX2, 66666666, 2.0, 0x45b, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 8},
|
||||
{"i486DX/25", CPU_i486DX, 25000000, 1.0, 0x404, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"i486DX/33", CPU_i486DX, 33333333, 1.0, 0x414, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"i486DX/50", CPU_i486DX, 50000000, 1.0, 0x411, 0, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6},
|
||||
{"i486DX2/40", CPU_i486DX, 40000000, 2.0, 0x430, 0x430, 0x0000, CPU_SUPPORTS_DYNAREC, 7, 7, 6, 6, 5},
|
||||
{"i486DX2/50", CPU_i486DX, 50000000, 2.0, 0x433, 0x433, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"i486DX2/66", CPU_i486DX, 66666666, 2.0, 0x435, 0x435, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"i486DX2/40", CPU_i486DX2, 40000000, 2.0, 0x430, 0x430, 0x0000, CPU_SUPPORTS_DYNAREC, 7, 7, 6, 6, 5},
|
||||
{"i486DX2/50", CPU_i486DX2, 50000000, 2.0, 0x433, 0x433, 0x0000, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"i486DX2/66", CPU_i486DX2, 66666666, 2.0, 0x435, 0x435, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"iDX4/75", CPU_iDX4, 75000000, 3.0, 0x480, 0x480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, /*CPUID available on DX4, >= 75 MHz*/
|
||||
{"iDX4/100", CPU_iDX4, 100000000, 3.0, 0x483, 0x483, 0x0000, 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.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
|
||||
|
||||
@@ -134,75 +134,81 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
|
||||
static int opXADD_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setadd8(temp, getr8(cpu_reg));
|
||||
temp2 = getr8(cpu_reg);
|
||||
setr8(cpu_reg, temp);
|
||||
seteab(temp + temp2); if (cpu_state.abrt) return 1;
|
||||
setadd8(temp, temp2);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
static int opXADD_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint8_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setadd8(temp, getr8(cpu_reg));
|
||||
temp2 = getr8(cpu_reg);
|
||||
setr8(cpu_reg, temp);
|
||||
seteab(temp + temp2); if (cpu_state.abrt) return 1;
|
||||
setadd8(temp, temp2);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opXADD_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
setadd16(temp, cpu_state.regs[cpu_reg].w);
|
||||
temp2 = cpu_state.regs[cpu_reg].w;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
seteaw(temp + temp2); if (cpu_state.abrt) return 1;
|
||||
setadd16(temp, temp2);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
static int opXADD_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
setadd16(temp, cpu_state.regs[cpu_reg].w);
|
||||
temp2 = cpu_state.regs[cpu_reg].w;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
seteaw(temp + temp2); if (cpu_state.abrt) return 1;
|
||||
setadd16(temp, temp2);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opXADD_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
setadd32(temp, cpu_state.regs[cpu_reg].l);
|
||||
temp2 = cpu_state.regs[cpu_reg].l;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
seteal(temp + temp2); if (cpu_state.abrt) return 1;
|
||||
setadd32(temp, temp2);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
static int opXADD_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
setadd32(temp, cpu_state.regs[cpu_reg].l);
|
||||
temp2 = cpu_state.regs[cpu_reg].l;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
seteal(temp + temp2); if (cpu_state.abrt) return 1;
|
||||
setadd32(temp, temp2);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ static int opAAA(uint32_t fetchdat)
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
{
|
||||
AL += 6;
|
||||
/* On 286, it's indeed AX - behavior difference from 808x. */
|
||||
AX += 6;
|
||||
AH++;
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
}
|
||||
@@ -44,7 +45,8 @@ static int opAAS(uint32_t fetchdat)
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
{
|
||||
AL -= 6;
|
||||
/* On 286, it's indeed AX - behavior difference from 808x. */
|
||||
AX -= 6;
|
||||
AH--;
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
}
|
||||
@@ -58,26 +60,33 @@ static int opAAS(uint32_t fetchdat)
|
||||
|
||||
static int opDAA(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9))
|
||||
{
|
||||
old_AL = AL;
|
||||
old_CF = cpu_state.flags & C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) {
|
||||
int tempi = ((uint16_t)AL) + 6;
|
||||
AL += 6;
|
||||
if (old_CF || (tempi & 0x100))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
if (tempi & 0x100) cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f))
|
||||
} else
|
||||
cpu_state.flags &= ~A_FLAG;
|
||||
|
||||
if ((old_AL > 0x99) || old_CF)
|
||||
{
|
||||
AL += 0x60;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
} else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= tempw;
|
||||
cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);
|
||||
|
||||
@@ -86,17 +95,24 @@ static int opDAA(uint32_t fetchdat)
|
||||
|
||||
static int opDAS(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
uint16_t tempw, old_AL, old_CF;
|
||||
|
||||
flags_rebuild();
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9))
|
||||
old_AL = AL;
|
||||
old_CF = cpu_state.flags & C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG))
|
||||
{
|
||||
int tempi = ((uint16_t)AL) - 6;
|
||||
AL -= 6;
|
||||
if (old_CF || (tempi & 0x100))
|
||||
cpu_state.flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
if (tempi & 0x100) cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f))
|
||||
} else
|
||||
cpu_state.flags &= ~A_FLAG;
|
||||
|
||||
if ((old_AL > 0x99) || old_CF)
|
||||
{
|
||||
AL -= 0x60;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
@@ -105,7 +121,7 @@ static int opDAS(uint32_t fetchdat)
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= tempw;
|
||||
cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user