Assorted Cyrix (and Codegen opcode Mod R/M passing table) fixes - fixes Windows 98 SE on Cyrix 6x86's with power management enabled.
This commit is contained in:
@@ -499,14 +499,14 @@ static int opcode_modrm[256] = {
|
||||
|
||||
int opcode_0f_modrm[256] = {
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
|
||||
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
|
||||
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
|
||||
1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, /*50*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/
|
||||
|
||||
@@ -1643,14 +1643,14 @@ static int opcode_modrm[256] = {
|
||||
|
||||
int opcode_0f_modrm[256] = {
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
|
||||
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
|
||||
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
|
||||
1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, /*50*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/
|
||||
|
||||
@@ -359,14 +359,14 @@ static uint8_t opcode_modrm[256] = {
|
||||
|
||||
static uint8_t opcode_0f_modrm[256] = {
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
|
||||
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/
|
||||
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
|
||||
1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, /*50*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/
|
||||
0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/
|
||||
|
||||
@@ -107,6 +107,12 @@ uint32_t backupregs[16];
|
||||
|
||||
x86seg _oldds;
|
||||
|
||||
uint8_t rep_op = 0x00;
|
||||
uint8_t is_smint = 0;
|
||||
|
||||
uint16_t io_port = 0x0000;
|
||||
uint32_t io_val = 0x00000000;
|
||||
|
||||
int opcode_has_modrm[256] = {
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/
|
||||
@@ -1215,7 +1221,7 @@ smram_restore_state_amd_k(uint32_t *saved_state)
|
||||
}
|
||||
|
||||
static void
|
||||
smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt))
|
||||
smram_save_state_cyrix(uint32_t *saved_state, int in_hlt)
|
||||
{
|
||||
saved_state[0] = dr[7];
|
||||
saved_state[1] = cpu_state.flags | (cpu_state.eflags << 16);
|
||||
@@ -1224,6 +1230,35 @@ smram_save_state_cyrix(uint32_t *saved_state, UNUSED(int in_hlt))
|
||||
saved_state[4] = cpu_state.pc;
|
||||
saved_state[5] = CS | (CPL << 21);
|
||||
saved_state[6] = 0x00000000;
|
||||
saved_state[7] = 0x00010000;
|
||||
|
||||
if (((opcode >= 0x6e) && (opcode <= 0x6f)) || ((opcode >= 0xe6) && (opcode <= 0xe7)) ||
|
||||
((opcode >= 0xee) && (opcode <= 0xef))) {
|
||||
saved_state[6] |= 0x00000002;
|
||||
saved_state[7] = (opcode & 0x01) ? (cpu_state.op32 ? 0x000f0000 : 0x00030000) : 0x00010000;
|
||||
} else if (((opcode == 0xf2) || (opcode == 0xf3)) && (rep_op >= 0x6e) && (rep_op <= 0x6f)) {
|
||||
saved_state[6] |= 0x00000006;
|
||||
saved_state[7] = (rep_op & 0x01) ? (cpu_state.op32 ? 0x000f0000 : 0x00030000) : 0x00010000;
|
||||
} else if (((opcode == 0xf2) || (opcode == 0xf3)) && (rep_op >= 0x6e) && (rep_op <= 0x6f)) {
|
||||
saved_state[6] |= 0x00000004;
|
||||
saved_state[7] = (rep_op & 0x01) ? (cpu_state.op32 ? 0x000f0000 : 0x00030000) : 0x00010000;
|
||||
}
|
||||
|
||||
if (is_smint) {
|
||||
saved_state[6] |= 0x00000008;
|
||||
is_smint = 0;
|
||||
}
|
||||
|
||||
if (in_hlt)
|
||||
saved_state[6] |= 0x00000010;
|
||||
|
||||
saved_state[7] |= io_port;
|
||||
saved_state[8] = io_val;
|
||||
|
||||
if (saved_state[6] & 0x00000002)
|
||||
saved_state[9] = ESI;
|
||||
else
|
||||
saved_state[9] = EDI;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1234,6 +1269,13 @@ smram_restore_state_cyrix(uint32_t *saved_state)
|
||||
cpu_state.eflags = saved_state[1] >> 16;
|
||||
cr0 = saved_state[2];
|
||||
cpu_state.pc = saved_state[4];
|
||||
/* Restore CPL. */
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x9f) | (((saved_state[5] >> 21) & 0x03) << 5);
|
||||
|
||||
if (saved_state[6] & 0x00000002)
|
||||
ESI = saved_state[9];
|
||||
else
|
||||
EDI = saved_state[9];
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1368,6 +1410,9 @@ enter_smm(int in_hlt)
|
||||
writememl(0, smram_state - 0x14, saved_state[4]);
|
||||
writememl(0, smram_state - 0x18, saved_state[5]);
|
||||
writememl(0, smram_state - 0x24, saved_state[6]);
|
||||
writememl(0, smram_state - 0x28, saved_state[7]);
|
||||
writememl(0, smram_state - 0x2c, saved_state[8]);
|
||||
writememl(0, smram_state - 0x30, saved_state[9]);
|
||||
} else {
|
||||
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||
smram_state -= 4;
|
||||
@@ -1452,6 +1497,9 @@ leave_smm(void)
|
||||
else
|
||||
cyrix_load_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
saved_state[6] = readmeml(0, smram_state - 0x24);
|
||||
saved_state[7] = readmeml(0, smram_state - 0x28);
|
||||
saved_state[8] = readmeml(0, smram_state - 0x2c);
|
||||
saved_state[9] = readmeml(0, smram_state - 0x30);
|
||||
} else {
|
||||
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||
smram_state -= 4;
|
||||
|
||||
@@ -103,4 +103,10 @@ extern int fpu_cycles;
|
||||
|
||||
extern void x86illegal(void);
|
||||
|
||||
extern uint8_t rep_op;
|
||||
extern uint8_t is_smint;
|
||||
|
||||
extern uint16_t io_port;
|
||||
extern uint32_t io_val;
|
||||
|
||||
#endif /*EMU_X86_H*/
|
||||
|
||||
@@ -63,18 +63,23 @@ opRSDC_common(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es);
|
||||
ES = readmemw(0, easeg + cpu_state.eaaddr + 8);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds);
|
||||
DS = readmemw(0, easeg + cpu_state.eaaddr + 8);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss);
|
||||
SS = readmemw(0, easeg + cpu_state.eaaddr + 8);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs);
|
||||
FS = readmemw(0, easeg + cpu_state.eaaddr + 8);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs);
|
||||
GS = readmemw(0, easeg + cpu_state.eaaddr + 8);
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
@@ -216,8 +221,10 @@ opSMINT(UNUSED(uint32_t fetchdat))
|
||||
{
|
||||
if (in_smm)
|
||||
fatal("opSMINT\n");
|
||||
else
|
||||
x86illegal();
|
||||
else {
|
||||
is_smint = 1;
|
||||
enter_smm(0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -855,6 +855,7 @@ opREPNE(uint32_t fetchdat)
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
rep_op = fetchdat & 0xff;
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
@@ -869,6 +870,7 @@ opREPE(uint32_t fetchdat)
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
rep_op = fetchdat & 0xff;
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
|
||||
@@ -843,6 +843,7 @@ opREPNE(uint32_t fetchdat)
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
rep_op = fetchdat & 0xff;
|
||||
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
@@ -857,6 +858,7 @@ opREPE(uint32_t fetchdat)
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
rep_op = fetchdat & 0xff;
|
||||
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
|
||||
@@ -761,6 +761,7 @@ opREPNE(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
rep_op = fetchdat & 0xff;
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
@@ -774,6 +775,7 @@ opREPE(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
rep_op = fetchdat & 0xff;
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
|
||||
@@ -2581,19 +2581,17 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_flat_ds = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (seg == &cpu_state.seg_cs)
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
if (seg == &cpu_state.seg_ss) {
|
||||
if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
set_stack32((segdat[3] & 0x40) ? 1 : 0);
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_flat_ss = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
src/io.c
16
src/io.c
@@ -28,6 +28,7 @@
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include <86box/m_amstrad.h>
|
||||
#include <86box/pci.h>
|
||||
|
||||
@@ -344,6 +345,8 @@ inb(uint16_t port)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_port = port;
|
||||
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
io_debug_check_addr(port);
|
||||
#endif
|
||||
@@ -408,6 +411,9 @@ outb(uint16_t port, uint8_t val)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_port = port;
|
||||
io_val = val;
|
||||
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
io_debug_check_addr(port);
|
||||
#endif
|
||||
@@ -464,6 +470,8 @@ inw(uint16_t port)
|
||||
#endif
|
||||
uint8_t ret8[2];
|
||||
|
||||
io_port = port;
|
||||
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
io_debug_check_addr(port);
|
||||
#endif
|
||||
@@ -540,6 +548,9 @@ outw(uint16_t port, uint16_t val)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_port = port;
|
||||
io_val = val;
|
||||
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
io_debug_check_addr(port);
|
||||
#endif
|
||||
@@ -612,6 +623,8 @@ inl(uint16_t port)
|
||||
int qfound = 0;
|
||||
#endif
|
||||
|
||||
io_port = port;
|
||||
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
io_debug_check_addr(port);
|
||||
#endif
|
||||
@@ -720,6 +733,9 @@ outl(uint16_t port, uint32_t val)
|
||||
#endif
|
||||
int i = 0;
|
||||
|
||||
io_port = port;
|
||||
io_val = val;
|
||||
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
io_debug_check_addr(port);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user