Fixed SMM, now it works correctly, and is now also operating on all CPU's from 386 onwards.
This commit is contained in:
46
src/apm.c
46
src/apm.c
@@ -14,6 +14,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2019 Miran Grca.
|
* Copyright 2019 Miran Grca.
|
||||||
*/
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -24,13 +25,7 @@
|
|||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "86box_io.h"
|
#include "86box_io.h"
|
||||||
|
#include "apm.h"
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t cmd,
|
|
||||||
stat;
|
|
||||||
} apm_t;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_APM_LOG
|
#ifdef ENABLE_APM_LOG
|
||||||
@@ -53,6 +48,13 @@ apm_log(const char *fmt, ...)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
apm_set_do_smi(apm_t *apm, uint8_t do_smi)
|
||||||
|
{
|
||||||
|
apm->do_smi = do_smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apm_out(uint16_t port, uint8_t val, void *p)
|
apm_out(uint16_t port, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
@@ -64,34 +66,8 @@ apm_out(uint16_t port, uint8_t val, void *p)
|
|||||||
|
|
||||||
if (port == 0x0000) {
|
if (port == 0x0000) {
|
||||||
apm->cmd = val;
|
apm->cmd = val;
|
||||||
|
if (apm->do_smi)
|
||||||
switch (apm->cmd) {
|
smi_line = 1;
|
||||||
case 0x07: /* Set Power State */
|
|
||||||
if (CH == 0x00) switch (CX) {
|
|
||||||
case 0x0000:
|
|
||||||
#ifdef ENABLE_APM_LOG
|
|
||||||
apm_log("APM Set Power State: APM Enabled\n");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 0x0001:
|
|
||||||
#ifdef ENABLE_APM_LOG
|
|
||||||
apm_log("APM Set Power State: Standby\n");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 0x0002:
|
|
||||||
#ifdef ENABLE_APM_LOG
|
|
||||||
apm_log("APM Set Power State: Suspend\n");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 0x0003: /* Off */
|
|
||||||
#ifdef ENABLE_APM_LOG
|
|
||||||
apm_log("APM Set Power State: Off\n");
|
|
||||||
#endif
|
|
||||||
exit(-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
apm->stat = val;
|
apm->stat = val;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,19 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t cmd,
|
||||||
|
stat, do_smi;
|
||||||
|
} apm_t;
|
||||||
|
|
||||||
|
|
||||||
/* Global variables. */
|
/* Global variables. */
|
||||||
extern const device_t apm_device;
|
extern const device_t apm_device;
|
||||||
|
|
||||||
|
|
||||||
/* Functions. */
|
/* Functions. */
|
||||||
|
extern void apm_set_do_smi(apm_t *apm, uint8_t do_smi);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
121
src/apm_new.c
121
src/apm_new.c
@@ -1,121 +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.
|
|
||||||
*
|
|
||||||
* Advanced Power Management emulation.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
|
||||||
*
|
|
||||||
* Copyright 2019 Miran Grca.
|
|
||||||
*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <wchar.h>
|
|
||||||
#define HAVE_STDARG_H
|
|
||||||
#include "86box.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "device.h"
|
|
||||||
#include "86box_io.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t cmd,
|
|
||||||
stat;
|
|
||||||
} apm_t;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_APM_LOG
|
|
||||||
int apm_do_log = ENABLE_APM_LOG;
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
apm_log(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
if (apm_do_log) {
|
|
||||||
va_start(ap, fmt);
|
|
||||||
pclog_ex(fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define apm_log(fmt, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
apm_out(uint16_t port, uint8_t val, void *p)
|
|
||||||
{
|
|
||||||
apm_t *apm = (apm_t *) p;
|
|
||||||
|
|
||||||
apm_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX);
|
|
||||||
|
|
||||||
port &= 0x0001;
|
|
||||||
|
|
||||||
if (port == 0x0000) apm->cmd = val;
|
|
||||||
else apm->stat = val;
|
|
||||||
|
|
||||||
smi_line = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
|
||||||
apm_in(uint16_t port, void *p)
|
|
||||||
{
|
|
||||||
apm_t *apm = (apm_t *) p;
|
|
||||||
|
|
||||||
apm_log("[%04X:%08X] APM read: %04X = FF\n", CS, cpu_state.pc, port);
|
|
||||||
|
|
||||||
port &= 0x0001;
|
|
||||||
|
|
||||||
if (port == 0x0000)
|
|
||||||
return apm->cmd;
|
|
||||||
else
|
|
||||||
return apm->stat;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
apm_close(void *p)
|
|
||||||
{
|
|
||||||
apm_t *dev = (apm_t *)p;
|
|
||||||
|
|
||||||
free(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
*apm_init(const device_t *info)
|
|
||||||
{
|
|
||||||
apm_t *apm = (apm_t *) malloc(sizeof(apm_t));
|
|
||||||
memset(apm, 0, sizeof(apm_t));
|
|
||||||
|
|
||||||
io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, apm);
|
|
||||||
|
|
||||||
return apm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const device_t apm_device =
|
|
||||||
{
|
|
||||||
"Advanced Power Management",
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
apm_init,
|
|
||||||
apm_close,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
@@ -481,7 +481,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
case INTEL_430FX: case INTEL_430FX_PB640:
|
case INTEL_430FX: case INTEL_430FX_PB640:
|
||||||
case INTEL_430VX:
|
case INTEL_430VX:
|
||||||
regs[addr] = val/* & 0x3f*/;
|
regs[addr] = val & 0x3f;
|
||||||
break;
|
break;
|
||||||
case INTEL_430TX:
|
case INTEL_430TX:
|
||||||
regs[addr] = val & 0x7f;
|
regs[addr] = val & 0x7f;
|
||||||
@@ -637,9 +637,13 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
case 0x72: /* SMRAM */
|
case 0x72: /* SMRAM */
|
||||||
if (dev->type >= INTEL_430FX) {
|
if (dev->type >= INTEL_430FX) {
|
||||||
if ((regs[0x72] ^ val) & 0x48)
|
if ((regs[0x72] & 0x10) || (val & 0x10)) {
|
||||||
|
regs[0x72] = (val & 0x38) | 0x02;
|
||||||
|
i4x0_map(0xa0000, 0x20000, 0);
|
||||||
|
} else {
|
||||||
|
regs[0x72] = (val & 0x78) | 0x02;
|
||||||
i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
|
i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
|
||||||
regs[0x72] = val & 0x7f;
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((regs[0x72] ^ val) & 0x20)
|
if ((regs[0x72] ^ val) & 0x20)
|
||||||
i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0);
|
i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0);
|
||||||
@@ -1006,7 +1010,7 @@ i4x0_reset(void *priv)
|
|||||||
memset(dev->regs_locked[i], 0x00, 256 * sizeof(uint8_t));
|
memset(dev->regs_locked[i], 0x00, 256 * sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
smbase = 0xa0000;
|
// smbase = 0xa0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1222,7 +1226,7 @@ static void
|
|||||||
i4x0_write(regs[0x5e], 0x5e, 0x00, dev);
|
i4x0_write(regs[0x5e], 0x5e, 0x00, dev);
|
||||||
i4x0_write(regs[0x5f], 0x5f, 0x00, dev);
|
i4x0_write(regs[0x5f], 0x5f, 0x00, dev);
|
||||||
|
|
||||||
smbase = 0xa0000;
|
// smbase = 0xa0000;
|
||||||
|
|
||||||
if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) {
|
if (((dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) && (dev->max_func == 1)) {
|
||||||
regs = (uint8_t *) dev->regs[1];
|
regs = (uint8_t *) dev->regs[1];
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ uint8_t opcode2;
|
|||||||
static void seg_reset(x86seg *s)
|
static void seg_reset(x86seg *s)
|
||||||
{
|
{
|
||||||
s->access = (0 << 5) | 2 | 0x80;
|
s->access = (0 << 5) | 2 | 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->limit = 0xFFFF;
|
s->limit = 0xFFFF;
|
||||||
s->limit_low = 0;
|
s->limit_low = 0;
|
||||||
s->limit_high = 0xffff;
|
s->limit_high = 0xffff;
|
||||||
@@ -135,6 +136,7 @@ void x86_doabrt(int x86_abrt)
|
|||||||
CS = oldcs;
|
CS = oldcs;
|
||||||
cpu_state.pc = cpu_state.oldpc;
|
cpu_state.pc = cpu_state.oldpc;
|
||||||
cpu_state.seg_cs.access = (oldcpl << 5) | 0x80;
|
cpu_state.seg_cs.access = (oldcpl << 5) | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
|
|
||||||
if (msw & 1)
|
if (msw & 1)
|
||||||
pmodeint(x86_abrt, 0);
|
pmodeint(x86_abrt, 0);
|
||||||
@@ -247,6 +249,7 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
|
|||||||
if (is386)
|
if (is386)
|
||||||
s->base |= ((segdat[3] >> 8) << 24);
|
s->base |= ((segdat[3] >> 8) << 24);
|
||||||
s->access = segdat[2] >> 8;
|
s->access = segdat[2] >> 8;
|
||||||
|
s->ar_high = segdat[3] & 0xff;
|
||||||
|
|
||||||
if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
|
if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
|
||||||
{
|
{
|
||||||
@@ -278,6 +281,7 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
|
|||||||
static void do_seg_v86_init(x86seg *s)
|
static void do_seg_v86_init(x86seg *s)
|
||||||
{
|
{
|
||||||
s->access = (3 << 5) | 2 | 0x80;
|
s->access = (3 << 5) | 2 | 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->limit = 0xffff;
|
s->limit = 0xffff;
|
||||||
s->limit_low = 0;
|
s->limit_low = 0;
|
||||||
s->limit_high = 0xffff;
|
s->limit_high = 0xffff;
|
||||||
@@ -344,6 +348,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
}
|
}
|
||||||
s->seg = 0;
|
s->seg = 0;
|
||||||
s->access = 0x80;
|
s->access = 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->base=-1;
|
s->base=-1;
|
||||||
if (s == &cpu_state.seg_ds)
|
if (s == &cpu_state.seg_ds)
|
||||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||||
@@ -463,6 +468,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
s->access = (3 << 5) | 2 | 0x80;
|
s->access = (3 << 5) | 2 | 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->base = seg << 4;
|
s->base = seg << 4;
|
||||||
s->seg = seg;
|
s->seg = seg;
|
||||||
s->checked = 1;
|
s->checked = 1;
|
||||||
@@ -593,6 +599,7 @@ void loadcs(uint16_t seg)
|
|||||||
CS=seg & 0xFFFF;
|
CS=seg & 0xFFFF;
|
||||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -814,6 +821,7 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
|||||||
CS=seg;
|
CS=seg;
|
||||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
cycles -= timing_jmp_rm;
|
cycles -= timing_jmp_rm;
|
||||||
}
|
}
|
||||||
@@ -1281,6 +1289,7 @@ void loadcscall(uint16_t seg)
|
|||||||
CS=seg;
|
CS=seg;
|
||||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1903,6 +1912,7 @@ void pmodeiret(int is32)
|
|||||||
cpu_state.seg_cs.limit_low = 0;
|
cpu_state.seg_cs.limit_low = 0;
|
||||||
cpu_state.seg_cs.limit_high = 0xffff;
|
cpu_state.seg_cs.limit_high = 0xffff;
|
||||||
cpu_state.seg_cs.access |= 0x80;
|
cpu_state.seg_cs.access |= 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
CS=seg;
|
CS=seg;
|
||||||
cpu_state.flags=(cpu_state.flags&0x3000)|(tempflags&0xCFD5)|2;
|
cpu_state.flags=(cpu_state.flags&0x3000)|(tempflags&0xCFD5)|2;
|
||||||
cycles -= timing_iret_rm;
|
cycles -= timing_iret_rm;
|
||||||
@@ -1973,6 +1983,7 @@ void pmodeiret(int is32)
|
|||||||
cpu_state.seg_cs.limit_high = 0xffff;
|
cpu_state.seg_cs.limit_high = 0xffff;
|
||||||
CS=seg;
|
CS=seg;
|
||||||
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high=0x10;
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
|
|
||||||
ESP=newsp;
|
ESP=newsp;
|
||||||
@@ -2577,4 +2588,5 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
tr.base=base;
|
tr.base=base;
|
||||||
tr.limit=limit;
|
tr.limit=limit;
|
||||||
tr.access=segdat[2]>>8;
|
tr.access=segdat[2]>>8;
|
||||||
|
tr.ar_high = segdat[3] & 0xff;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,6 +272,14 @@ exec386(int cycs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!in_smm && smi_line/* && is_pentium*/) {
|
||||||
|
enter_smm();
|
||||||
|
smi_line = 0;
|
||||||
|
} else if (in_smm && smi_line/* && is_pentium*/) {
|
||||||
|
smi_latched = 1;
|
||||||
|
smi_line = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ins_cycles -= cycles;
|
ins_cycles -= cycles;
|
||||||
tsc += ins_cycles;
|
tsc += ins_cycles;
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,80 @@
|
|||||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||||
|
|
||||||
|
|
||||||
|
/* These #define's and enum have been borrowed from Bochs. */
|
||||||
|
/* SMM feature masks */
|
||||||
|
#define SMM_IO_INSTRUCTION_RESTART (0x00010000)
|
||||||
|
#define SMM_SMBASE_RELOCATION (0x00020000)
|
||||||
|
|
||||||
|
/* TODO: Which CPU added SMBASE relocation? */
|
||||||
|
#define SMM_REVISION_ID SMM_SMBASE_RELOCATION
|
||||||
|
// #define SMM_REVISION_ID 0
|
||||||
|
|
||||||
|
#define SMM_SAVE_STATE_MAP_SIZE 128
|
||||||
|
|
||||||
|
|
||||||
|
enum SMMRAM_Fields {
|
||||||
|
SMRAM_FIELD_SMBASE_OFFSET = 0,
|
||||||
|
SMRAM_FIELD_SMM_REVISION_ID,
|
||||||
|
SMRAM_FIELD_EAX,
|
||||||
|
SMRAM_FIELD_ECX,
|
||||||
|
SMRAM_FIELD_EDX,
|
||||||
|
SMRAM_FIELD_EBX,
|
||||||
|
SMRAM_FIELD_ESP,
|
||||||
|
SMRAM_FIELD_EBP,
|
||||||
|
SMRAM_FIELD_ESI,
|
||||||
|
SMRAM_FIELD_EDI,
|
||||||
|
SMRAM_FIELD_EIP,
|
||||||
|
SMRAM_FIELD_EFLAGS,
|
||||||
|
SMRAM_FIELD_DR6,
|
||||||
|
SMRAM_FIELD_DR7,
|
||||||
|
SMRAM_FIELD_CR0,
|
||||||
|
SMRAM_FIELD_CR3,
|
||||||
|
SMRAM_FIELD_CR4,
|
||||||
|
SMRAM_FIELD_EFER,
|
||||||
|
SMRAM_FIELD_IO_INSTRUCTION_RESTART,
|
||||||
|
SMRAM_FIELD_AUTOHALT_RESTART,
|
||||||
|
SMRAM_FIELD_NMI_MASK,
|
||||||
|
SMRAM_FIELD_TR_SELECTOR,
|
||||||
|
SMRAM_FIELD_TR_BASE,
|
||||||
|
SMRAM_FIELD_TR_LIMIT,
|
||||||
|
SMRAM_FIELD_TR_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_LDTR_SELECTOR,
|
||||||
|
SMRAM_FIELD_LDTR_BASE,
|
||||||
|
SMRAM_FIELD_LDTR_LIMIT,
|
||||||
|
SMRAM_FIELD_LDTR_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_IDTR_BASE,
|
||||||
|
SMRAM_FIELD_IDTR_LIMIT,
|
||||||
|
SMRAM_FIELD_GDTR_BASE,
|
||||||
|
SMRAM_FIELD_GDTR_LIMIT,
|
||||||
|
SMRAM_FIELD_ES_SELECTOR,
|
||||||
|
SMRAM_FIELD_ES_BASE,
|
||||||
|
SMRAM_FIELD_ES_LIMIT,
|
||||||
|
SMRAM_FIELD_ES_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_CS_SELECTOR,
|
||||||
|
SMRAM_FIELD_CS_BASE,
|
||||||
|
SMRAM_FIELD_CS_LIMIT,
|
||||||
|
SMRAM_FIELD_CS_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_SS_SELECTOR,
|
||||||
|
SMRAM_FIELD_SS_BASE,
|
||||||
|
SMRAM_FIELD_SS_LIMIT,
|
||||||
|
SMRAM_FIELD_SS_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_DS_SELECTOR,
|
||||||
|
SMRAM_FIELD_DS_BASE,
|
||||||
|
SMRAM_FIELD_DS_LIMIT,
|
||||||
|
SMRAM_FIELD_DS_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_FS_SELECTOR,
|
||||||
|
SMRAM_FIELD_FS_BASE,
|
||||||
|
SMRAM_FIELD_FS_LIMIT,
|
||||||
|
SMRAM_FIELD_FS_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_GS_SELECTOR,
|
||||||
|
SMRAM_FIELD_GS_BASE,
|
||||||
|
SMRAM_FIELD_GS_LIMIT,
|
||||||
|
SMRAM_FIELD_GS_SELECTOR_AR,
|
||||||
|
SMRAM_FIELD_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int inrecomp = 0, cpu_block_end = 0;
|
int inrecomp = 0, cpu_block_end = 0;
|
||||||
int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
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;
|
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||||
@@ -262,218 +336,401 @@ static void prefetch_flush()
|
|||||||
#define PREFETCH_FLUSH() prefetch_flush()
|
#define PREFETCH_FLUSH() prefetch_flush()
|
||||||
|
|
||||||
|
|
||||||
|
static void set_stack32(int s)
|
||||||
|
{
|
||||||
|
stack32 = s;
|
||||||
|
if (stack32)
|
||||||
|
cpu_cur_status |= CPU_STATUS_STACK32;
|
||||||
|
else
|
||||||
|
cpu_cur_status &= ~CPU_STATUS_STACK32;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void set_use32(int u)
|
||||||
|
{
|
||||||
|
if (u)
|
||||||
|
{
|
||||||
|
use32 = 0x300;
|
||||||
|
cpu_cur_status |= CPU_STATUS_USE32;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
use32 = 0;
|
||||||
|
cpu_cur_status &= ~CPU_STATUS_USE32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void smm_seg_load(x86seg *s)
|
||||||
|
{
|
||||||
|
if (!is386)
|
||||||
|
s->base &= 0x00ffffff;
|
||||||
|
|
||||||
|
if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/
|
||||||
|
{
|
||||||
|
s->limit_high = s->limit;
|
||||||
|
s->limit_low = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s->limit_high = (s->ar_high & 0x40) ? 0xffffffff : 0xffff;
|
||||||
|
s->limit_low = s->limit + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG))
|
||||||
|
s->checked = s->seg ? 1 : 0;
|
||||||
|
else
|
||||||
|
s->checked = 1;
|
||||||
|
|
||||||
|
if (s == &cpu_state.seg_cs)
|
||||||
|
set_use32(s->ar_high & 0x40);
|
||||||
|
if (s == &cpu_state.seg_ds)
|
||||||
|
{
|
||||||
|
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||||
|
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
|
||||||
|
else
|
||||||
|
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||||
|
}
|
||||||
|
if (s == &cpu_state.seg_ss)
|
||||||
|
{
|
||||||
|
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||||
|
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
|
||||||
|
else
|
||||||
|
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||||
|
set_stack32((s->ar_high & 0x40) ? 1 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void smram_save_state(uint32_t *saved_state)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
saved_state[SMRAM_FIELD_SMM_REVISION_ID] = SMM_REVISION_ID;
|
||||||
|
saved_state[SMRAM_FIELD_SMBASE_OFFSET] = smbase;
|
||||||
|
|
||||||
|
for (n = 0; n < 8; n++)
|
||||||
|
saved_state[SMRAM_FIELD_EAX + n] = cpu_state.regs[n].l;
|
||||||
|
|
||||||
|
saved_state[SMRAM_FIELD_EIP] = cpu_state.pc;
|
||||||
|
saved_state[SMRAM_FIELD_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags);
|
||||||
|
|
||||||
|
saved_state[SMRAM_FIELD_CR0] = cr0;
|
||||||
|
saved_state[SMRAM_FIELD_CR3] = cr3;
|
||||||
|
if (is_pentium) {
|
||||||
|
saved_state[SMRAM_FIELD_CR4] = cr4;
|
||||||
|
/* TODO: Properly implement EFER */
|
||||||
|
/* saved_state[SMRAM_FIELD_EFER] = efer; */
|
||||||
|
}
|
||||||
|
saved_state[SMRAM_FIELD_DR6] = dr[6];
|
||||||
|
saved_state[SMRAM_FIELD_DR7] = dr[7];
|
||||||
|
|
||||||
|
/* TR */
|
||||||
|
saved_state[SMRAM_FIELD_TR_SELECTOR] = tr.seg;
|
||||||
|
saved_state[SMRAM_FIELD_TR_BASE] = tr.base;
|
||||||
|
saved_state[SMRAM_FIELD_TR_LIMIT] = tr.limit;
|
||||||
|
saved_state[SMRAM_FIELD_TR_SELECTOR_AR] = (tr.ar_high << 24) | (tr.access << 16) | tr.seg;
|
||||||
|
|
||||||
|
/* LDTR */
|
||||||
|
saved_state[SMRAM_FIELD_LDTR_SELECTOR] = ldt.seg;
|
||||||
|
saved_state[SMRAM_FIELD_LDTR_BASE] = ldt.base;
|
||||||
|
saved_state[SMRAM_FIELD_LDTR_LIMIT] = ldt.limit;
|
||||||
|
saved_state[SMRAM_FIELD_LDTR_SELECTOR_AR] = (ldt.ar_high << 24) | (ldt.access << 16) | ldt.seg;
|
||||||
|
|
||||||
|
/* IDTR */
|
||||||
|
saved_state[SMRAM_FIELD_IDTR_BASE] = idt.base;
|
||||||
|
saved_state[SMRAM_FIELD_IDTR_LIMIT] = idt.limit;
|
||||||
|
|
||||||
|
/* GDTR */
|
||||||
|
saved_state[SMRAM_FIELD_GDTR_BASE] = gdt.base;
|
||||||
|
saved_state[SMRAM_FIELD_GDTR_LIMIT] = gdt.limit;
|
||||||
|
|
||||||
|
/* ES */
|
||||||
|
saved_state[SMRAM_FIELD_ES_SELECTOR] = cpu_state.seg_es.seg;
|
||||||
|
saved_state[SMRAM_FIELD_ES_BASE] = cpu_state.seg_es.base;
|
||||||
|
saved_state[SMRAM_FIELD_ES_LIMIT] = cpu_state.seg_es.limit;
|
||||||
|
saved_state[SMRAM_FIELD_ES_SELECTOR_AR] =
|
||||||
|
(cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg;
|
||||||
|
|
||||||
|
/* CS */
|
||||||
|
saved_state[SMRAM_FIELD_CS_SELECTOR] = cpu_state.seg_cs.seg;
|
||||||
|
saved_state[SMRAM_FIELD_CS_BASE] = cpu_state.seg_cs.base;
|
||||||
|
saved_state[SMRAM_FIELD_CS_LIMIT] = cpu_state.seg_cs.limit;
|
||||||
|
saved_state[SMRAM_FIELD_CS_SELECTOR_AR] =
|
||||||
|
(cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg;
|
||||||
|
|
||||||
|
/* DS */
|
||||||
|
saved_state[SMRAM_FIELD_DS_SELECTOR] = cpu_state.seg_ds.seg;
|
||||||
|
saved_state[SMRAM_FIELD_DS_BASE] = cpu_state.seg_ds.base;
|
||||||
|
saved_state[SMRAM_FIELD_DS_LIMIT] = cpu_state.seg_ds.limit;
|
||||||
|
saved_state[SMRAM_FIELD_DS_SELECTOR_AR] =
|
||||||
|
(cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg;
|
||||||
|
|
||||||
|
/* SS */
|
||||||
|
saved_state[SMRAM_FIELD_SS_SELECTOR] = cpu_state.seg_ss.seg;
|
||||||
|
saved_state[SMRAM_FIELD_SS_BASE] = cpu_state.seg_ss.base;
|
||||||
|
saved_state[SMRAM_FIELD_SS_LIMIT] = cpu_state.seg_ss.limit;
|
||||||
|
saved_state[SMRAM_FIELD_SS_SELECTOR_AR] =
|
||||||
|
(cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg;
|
||||||
|
|
||||||
|
/* FS */
|
||||||
|
saved_state[SMRAM_FIELD_FS_SELECTOR] = cpu_state.seg_fs.seg;
|
||||||
|
saved_state[SMRAM_FIELD_FS_BASE] = cpu_state.seg_fs.base;
|
||||||
|
saved_state[SMRAM_FIELD_FS_LIMIT] = cpu_state.seg_fs.limit;
|
||||||
|
saved_state[SMRAM_FIELD_FS_SELECTOR_AR] =
|
||||||
|
(cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg;
|
||||||
|
|
||||||
|
/* GS */
|
||||||
|
saved_state[SMRAM_FIELD_GS_SELECTOR] = cpu_state.seg_gs.seg;
|
||||||
|
saved_state[SMRAM_FIELD_GS_BASE] = cpu_state.seg_gs.base;
|
||||||
|
saved_state[SMRAM_FIELD_GS_LIMIT] = cpu_state.seg_gs.limit;
|
||||||
|
saved_state[SMRAM_FIELD_GS_SELECTOR_AR] =
|
||||||
|
(cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void smram_restore_state(uint32_t *saved_state)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
for (n = 0; n < 8; n++)
|
||||||
|
cpu_state.regs[n].l = saved_state[SMRAM_FIELD_EAX + n];
|
||||||
|
|
||||||
|
cpu_state.pc = saved_state[SMRAM_FIELD_EIP];
|
||||||
|
cpu_state.eflags = saved_state[SMRAM_FIELD_EFLAGS] >> 16;
|
||||||
|
cpu_state.flags = saved_state[SMRAM_FIELD_EFLAGS] & 0xffff;
|
||||||
|
|
||||||
|
cr0 = saved_state[SMRAM_FIELD_CR0];
|
||||||
|
cr3 = saved_state[SMRAM_FIELD_CR3];
|
||||||
|
if (is_pentium) {
|
||||||
|
cr4 = saved_state[SMRAM_FIELD_CR4];
|
||||||
|
/* TODO: Properly implement EFER */
|
||||||
|
/* efer = saved_state[SMRAM_FIELD_EFER]; */
|
||||||
|
}
|
||||||
|
dr[6] = saved_state[SMRAM_FIELD_DR6];
|
||||||
|
dr[7] = saved_state[SMRAM_FIELD_DR7];
|
||||||
|
|
||||||
|
/* TR */
|
||||||
|
tr.seg = saved_state[SMRAM_FIELD_TR_SELECTOR];
|
||||||
|
tr.base = saved_state[SMRAM_FIELD_TR_BASE];
|
||||||
|
tr.limit = saved_state[SMRAM_FIELD_TR_LIMIT];
|
||||||
|
tr.access = (saved_state[SMRAM_FIELD_TR_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
tr.ar_high = (saved_state[SMRAM_FIELD_TR_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&tr);
|
||||||
|
|
||||||
|
/* LDTR */
|
||||||
|
ldt.seg = saved_state[SMRAM_FIELD_LDTR_SELECTOR];
|
||||||
|
ldt.base = saved_state[SMRAM_FIELD_LDTR_BASE];
|
||||||
|
ldt.limit = saved_state[SMRAM_FIELD_LDTR_LIMIT];
|
||||||
|
ldt.access = (saved_state[SMRAM_FIELD_LDTR_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
ldt.ar_high = (saved_state[SMRAM_FIELD_LDTR_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&ldt);
|
||||||
|
|
||||||
|
/* IDTR */
|
||||||
|
idt.base = saved_state[SMRAM_FIELD_IDTR_BASE];
|
||||||
|
idt.limit = saved_state[SMRAM_FIELD_IDTR_LIMIT];
|
||||||
|
|
||||||
|
/* GDTR */
|
||||||
|
gdt.base = saved_state[SMRAM_FIELD_GDTR_BASE];
|
||||||
|
gdt.limit = saved_state[SMRAM_FIELD_GDTR_LIMIT];
|
||||||
|
|
||||||
|
/* ES */
|
||||||
|
cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_ES_SELECTOR];
|
||||||
|
cpu_state.seg_es.base = saved_state[SMRAM_FIELD_ES_BASE];
|
||||||
|
cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_ES_LIMIT];
|
||||||
|
cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_ES_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_ES_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&cpu_state.seg_es);
|
||||||
|
|
||||||
|
/* CS */
|
||||||
|
cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_CS_SELECTOR];
|
||||||
|
cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_CS_BASE];
|
||||||
|
cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_CS_LIMIT];
|
||||||
|
cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_CS_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_CS_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&cpu_state.seg_cs);
|
||||||
|
|
||||||
|
/* DS */
|
||||||
|
cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_DS_SELECTOR];
|
||||||
|
cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_DS_BASE];
|
||||||
|
cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_DS_LIMIT];
|
||||||
|
cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_DS_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_DS_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&cpu_state.seg_ds);
|
||||||
|
|
||||||
|
/* SS */
|
||||||
|
cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_SS_SELECTOR];
|
||||||
|
cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_SS_BASE];
|
||||||
|
cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_SS_LIMIT];
|
||||||
|
cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_SS_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_SS_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&cpu_state.seg_ss);
|
||||||
|
|
||||||
|
/* FS */
|
||||||
|
cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_FS_SELECTOR];
|
||||||
|
cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_FS_BASE];
|
||||||
|
cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_FS_LIMIT];
|
||||||
|
cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_FS_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_FS_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&cpu_state.seg_fs);
|
||||||
|
|
||||||
|
/* GS */
|
||||||
|
cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_GS_SELECTOR];
|
||||||
|
cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_GS_BASE];
|
||||||
|
cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_GS_LIMIT];
|
||||||
|
cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_GS_SELECTOR_AR] >> 16) & 0xff;
|
||||||
|
cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_GS_SELECTOR_AR] >> 24) & 0xff;
|
||||||
|
smm_seg_load(&cpu_state.seg_gs);
|
||||||
|
|
||||||
|
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
|
||||||
|
smbase = saved_state[SMRAM_FIELD_SMBASE_OFFSET];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void enter_smm()
|
void enter_smm()
|
||||||
{
|
{
|
||||||
uint32_t smram_state = smbase + 0xfe00;
|
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
|
||||||
uint32_t old_cr0 = cr0;
|
uint32_t smram_state = smbase + 0x10000;
|
||||||
uint32_t old_flags = cpu_state.flags | ((uint32_t)cpu_state.eflags << 16);
|
|
||||||
|
x386_dynarec_log("enter_smm(): smbase = %08X\n", smbase);
|
||||||
|
x386_dynarec_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low,
|
||||||
|
cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high);
|
||||||
|
x386_dynarec_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low,
|
||||||
|
cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high);
|
||||||
|
x386_dynarec_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low,
|
||||||
|
cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high);
|
||||||
|
x386_dynarec_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low,
|
||||||
|
cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high);
|
||||||
|
x386_dynarec_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low,
|
||||||
|
cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high);
|
||||||
|
x386_dynarec_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low,
|
||||||
|
cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high);
|
||||||
|
x386_dynarec_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high);
|
||||||
|
x386_dynarec_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high);
|
||||||
|
x386_dynarec_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high);
|
||||||
|
x386_dynarec_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high);
|
||||||
|
x386_dynarec_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]);
|
||||||
|
x386_dynarec_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags);
|
||||||
|
x386_dynarec_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n",
|
||||||
|
EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP);
|
||||||
|
|
||||||
|
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
|
||||||
|
smram_save_state(saved_state);
|
||||||
|
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||||
|
smram_state -= 4;
|
||||||
|
mem_writel_phys(smram_state, saved_state[n]);
|
||||||
|
}
|
||||||
|
|
||||||
cr0 &= ~0x8000000d;
|
cr0 &= ~0x8000000d;
|
||||||
cpu_state.flags = 2;
|
cpu_state.flags = 2;
|
||||||
cpu_state.eflags = 0;
|
cpu_state.eflags = 0;
|
||||||
|
|
||||||
in_smm = 1;
|
/* Intel 4x0 chipset stuff. */
|
||||||
mem_set_mem_state(smbase, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
mem_set_mem_state(0xa0000, 131072, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
smi_latched = 1;
|
flushmmucache_cr3();
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
if (is_pentium)
|
||||||
cr4 = 0;
|
cr4 = 0;
|
||||||
dr[7] = 0x400;
|
dr[7] = 0x400;
|
||||||
cpu_state.pc = 0x8000;
|
cpu_state.pc = 0x8000;
|
||||||
|
|
||||||
|
cpu_state.seg_ds.seg = 0x00000000;
|
||||||
|
cpu_state.seg_ds.base = 0x00000000;
|
||||||
|
cpu_state.seg_ds.limit = 0xffffffff;
|
||||||
|
cpu_state.seg_ds.access = 0x93;
|
||||||
|
cpu_state.seg_ds.ar_high = 0x80;
|
||||||
|
|
||||||
|
memcpy(&cpu_state.seg_es, &cpu_state.seg_ds, sizeof(x86seg));
|
||||||
|
memcpy(&cpu_state.seg_ss, &cpu_state.seg_ds, sizeof(x86seg));
|
||||||
|
memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg));
|
||||||
|
memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg));
|
||||||
|
|
||||||
|
CS = (smbase >> 4);
|
||||||
|
cpu_state.seg_cs.base = smbase;
|
||||||
|
cpu_state.seg_cs.limit = 0xffffffff;
|
||||||
|
cpu_state.seg_cs.access = 0x93;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x80;
|
||||||
|
cpu_state.seg_cs.checked = 1;
|
||||||
|
|
||||||
|
smm_seg_load(&cpu_state.seg_es);
|
||||||
|
smm_seg_load(&cpu_state.seg_cs);
|
||||||
|
smm_seg_load(&cpu_state.seg_ds);
|
||||||
|
smm_seg_load(&cpu_state.seg_ss);
|
||||||
|
smm_seg_load(&cpu_state.seg_fs);
|
||||||
|
smm_seg_load(&cpu_state.seg_gs);
|
||||||
|
|
||||||
nmi_mask = 0;
|
nmi_mask = 0;
|
||||||
|
|
||||||
|
in_smm = 1;
|
||||||
|
CPU_BLOCK_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void leave_smm()
|
void leave_smm()
|
||||||
{
|
{
|
||||||
uint32_t smram_state = smbase + 0xfe00;
|
uint32_t saved_state[SMM_SAVE_STATE_MAP_SIZE], n;
|
||||||
|
uint32_t smram_state = smbase + 0x10000;
|
||||||
|
|
||||||
smbase = mem_readl_phys(smram_state + 0xf8);
|
memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t));
|
||||||
cr4 = mem_readl_phys(smram_state + 0x128);
|
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||||
|
smram_state -= 4;
|
||||||
cpu_state.seg_es.limit = cpu_state.seg_es.limit_high = mem_readl_phys(smram_state + 0x130);
|
saved_state[n] = mem_readl_phys(smram_state);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
smram_restore_state(saved_state);
|
||||||
|
|
||||||
mem_restore_mem_state(smbase, 131072);
|
/* Intel 4x0 chipset stuff. */
|
||||||
in_smm = 0;
|
mem_restore_mem_state(0xa0000, 131072);
|
||||||
|
flushmmucache_cr3();
|
||||||
|
|
||||||
nmi_mask = 1;
|
nmi_mask = 1;
|
||||||
|
|
||||||
|
in_smm = 0;
|
||||||
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
|
x386_dynarec_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low,
|
||||||
|
cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high);
|
||||||
|
x386_dynarec_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low,
|
||||||
|
cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high);
|
||||||
|
x386_dynarec_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low,
|
||||||
|
cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high);
|
||||||
|
x386_dynarec_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low,
|
||||||
|
cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high);
|
||||||
|
x386_dynarec_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low,
|
||||||
|
cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high);
|
||||||
|
x386_dynarec_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low,
|
||||||
|
cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high);
|
||||||
|
x386_dynarec_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high);
|
||||||
|
x386_dynarec_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high);
|
||||||
|
x386_dynarec_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high);
|
||||||
|
x386_dynarec_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n",
|
||||||
|
idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high);
|
||||||
|
x386_dynarec_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]);
|
||||||
|
x386_dynarec_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags);
|
||||||
|
x386_dynarec_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n",
|
||||||
|
EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP);
|
||||||
|
x386_dynarec_log("leave_smm()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define OP_TABLE(name) ops_ ## name
|
#define OP_TABLE(name) ops_ ## name
|
||||||
#define CLOCK_CYCLES(c) cycles -= (c)
|
#define CLOCK_CYCLES(c) cycles -= (c)
|
||||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||||
@@ -552,7 +809,7 @@ void exec386_dynarec(int cycs)
|
|||||||
if (((cs + cpu_state.pc) >> 12) != pccache)
|
if (((cs + cpu_state.pc) >> 12) != pccache)
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
if (in_smm && smi_line && is_pentium)
|
if (!in_smm && smi_line/* && is_pentium*/)
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
if (cpu_state.abrt)
|
if (cpu_state.abrt)
|
||||||
@@ -781,7 +1038,7 @@ void exec386_dynarec(int cycs)
|
|||||||
#endif
|
#endif
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
if (in_smm && smi_line && is_pentium)
|
if (!in_smm && smi_line/* && is_pentium*/)
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
if (trap)
|
if (trap)
|
||||||
@@ -867,7 +1124,7 @@ void exec386_dynarec(int cycs)
|
|||||||
#endif
|
#endif
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
if (in_smm && smi_line && is_pentium)
|
if (!in_smm && smi_line/* && is_pentium*/)
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
if (trap)
|
if (trap)
|
||||||
@@ -926,9 +1183,12 @@ void exec386_dynarec(int cycs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_smm && smi_line && is_pentium)
|
if (!in_smm && smi_line/* && is_pentium*/) {
|
||||||
{
|
|
||||||
enter_smm();
|
enter_smm();
|
||||||
|
smi_line = 0;
|
||||||
|
} else if (in_smm && smi_line/* && is_pentium*/) {
|
||||||
|
smi_latched = 1;
|
||||||
|
smi_line = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (trap)
|
else if (trap)
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||||
@@ -401,7 +401,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||||
@@ -423,7 +423,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||||
@@ -445,7 +445,7 @@ const OpFn OP_TABLE(386_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||||
@@ -470,7 +470,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -492,7 +492,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -514,7 +514,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -536,7 +536,7 @@ const OpFn OP_TABLE(486_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -561,7 +561,7 @@ const OpFn OP_TABLE(winchip_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -583,7 +583,7 @@ const OpFn OP_TABLE(winchip_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -605,7 +605,7 @@ const OpFn OP_TABLE(winchip_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -627,7 +627,7 @@ const OpFn OP_TABLE(winchip_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -652,7 +652,7 @@ const OpFn OP_TABLE(winchip2_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -674,7 +674,7 @@ const OpFn OP_TABLE(winchip2_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -696,7 +696,7 @@ const OpFn OP_TABLE(winchip2_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
@@ -718,7 +718,7 @@ const OpFn OP_TABLE(winchip2_0f)[1024] =
|
|||||||
|
|
||||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||||
|
|
||||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||||
|
|||||||
@@ -970,6 +970,9 @@ reset_common(int hard)
|
|||||||
cpu_ven_reset();
|
cpu_ven_reset();
|
||||||
|
|
||||||
cpu_alu_op = 0;
|
cpu_alu_op = 0;
|
||||||
|
|
||||||
|
in_smm = smi_latched = 0;
|
||||||
|
smi_line = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ typedef struct {
|
|||||||
uint32_t base;
|
uint32_t base;
|
||||||
uint32_t limit;
|
uint32_t limit;
|
||||||
uint8_t access;
|
uint8_t access;
|
||||||
|
uint8_t ar_high;
|
||||||
uint16_t seg;
|
uint16_t seg;
|
||||||
uint32_t limit_low,
|
uint32_t limit_low,
|
||||||
limit_high;
|
limit_high;
|
||||||
|
|||||||
@@ -950,10 +950,13 @@ static int opWRMSR(uint32_t fetchdat)
|
|||||||
|
|
||||||
static int opRSM(uint32_t fetchdat)
|
static int opRSM(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
if(!in_smm)
|
if (in_smm)
|
||||||
{
|
{
|
||||||
leave_smm();
|
leave_smm();
|
||||||
if(smi_latched) enter_smm();
|
if (smi_latched) {
|
||||||
|
smi_latched = 0;
|
||||||
|
enter_smm();
|
||||||
|
}
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ uint8_t opcode2;
|
|||||||
static void seg_reset(x86seg *s)
|
static void seg_reset(x86seg *s)
|
||||||
{
|
{
|
||||||
s->access = (0 << 5) | 2 | 0x80;
|
s->access = (0 << 5) | 2 | 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->limit = 0xFFFF;
|
s->limit = 0xFFFF;
|
||||||
s->limit_low = 0;
|
s->limit_low = 0;
|
||||||
s->limit_high = 0xffff;
|
s->limit_high = 0xffff;
|
||||||
@@ -247,6 +248,7 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
|
|||||||
if (is386)
|
if (is386)
|
||||||
s->base |= ((segdat[3] >> 8) << 24);
|
s->base |= ((segdat[3] >> 8) << 24);
|
||||||
s->access = segdat[2] >> 8;
|
s->access = segdat[2] >> 8;
|
||||||
|
s->ar_high = segdat[3] & 0xff;
|
||||||
|
|
||||||
if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
|
if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/
|
||||||
{
|
{
|
||||||
@@ -278,6 +280,7 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
|
|||||||
static void do_seg_v86_init(x86seg *s)
|
static void do_seg_v86_init(x86seg *s)
|
||||||
{
|
{
|
||||||
s->access = (3 << 5) | 2 | 0x80;
|
s->access = (3 << 5) | 2 | 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->limit = 0xffff;
|
s->limit = 0xffff;
|
||||||
s->limit_low = 0;
|
s->limit_low = 0;
|
||||||
s->limit_high = 0xffff;
|
s->limit_high = 0xffff;
|
||||||
@@ -344,6 +347,7 @@ int loadseg(uint16_t seg, x86seg *s)
|
|||||||
}
|
}
|
||||||
s->seg=0;
|
s->seg=0;
|
||||||
s->access = 0x80;
|
s->access = 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->base=-1;
|
s->base=-1;
|
||||||
if (s == &cpu_state.seg_ds)
|
if (s == &cpu_state.seg_ds)
|
||||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||||
@@ -455,6 +459,7 @@ int loadseg(uint16_t seg, x86seg *s)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
s->access = (3 << 5) | 2 | 0x80;
|
s->access = (3 << 5) | 2 | 0x80;
|
||||||
|
s->ar_high = 0x10;
|
||||||
s->base = seg << 4;
|
s->base = seg << 4;
|
||||||
s->seg = seg;
|
s->seg = seg;
|
||||||
s->checked = 1;
|
s->checked = 1;
|
||||||
@@ -810,6 +815,7 @@ void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
|||||||
CS=seg;
|
CS=seg;
|
||||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
oldcpl = CPL;
|
oldcpl = CPL;
|
||||||
cycles -= timing_jmp_rm;
|
cycles -= timing_jmp_rm;
|
||||||
@@ -1275,6 +1281,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc)
|
|||||||
CS=seg;
|
CS=seg;
|
||||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
oldcpl = CPL;
|
oldcpl = CPL;
|
||||||
}
|
}
|
||||||
@@ -1897,6 +1904,7 @@ void pmodeiret(int is32)
|
|||||||
cpu_state.seg_cs.limit_low = 0;
|
cpu_state.seg_cs.limit_low = 0;
|
||||||
cpu_state.seg_cs.limit_high = 0xffff;
|
cpu_state.seg_cs.limit_high = 0xffff;
|
||||||
cpu_state.seg_cs.access |= 0x80;
|
cpu_state.seg_cs.access |= 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
CS=seg;
|
CS=seg;
|
||||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2;
|
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2;
|
||||||
cycles -= timing_iret_rm;
|
cycles -= timing_iret_rm;
|
||||||
@@ -1966,6 +1974,7 @@ void pmodeiret(int is32)
|
|||||||
cpu_state.seg_cs.limit_high = 0xffff;
|
cpu_state.seg_cs.limit_high = 0xffff;
|
||||||
CS=seg;
|
CS=seg;
|
||||||
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||||
|
cpu_state.seg_cs.ar_high = 0x10;
|
||||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||||
oldcpl = CPL;
|
oldcpl = CPL;
|
||||||
|
|
||||||
@@ -2576,5 +2585,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||||||
tr.base=base;
|
tr.base=base;
|
||||||
tr.limit=limit;
|
tr.limit=limit;
|
||||||
tr.access=segdat[2]>>8;
|
tr.access=segdat[2]>>8;
|
||||||
|
tr.ar_high = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ typedef struct
|
|||||||
ddma_t ddma[2];
|
ddma_t ddma[2];
|
||||||
power_t power;
|
power_t power;
|
||||||
piix_smbus_t smbus;
|
piix_smbus_t smbus;
|
||||||
|
apm_t * apm;
|
||||||
nvr_t * nvr;
|
nvr_t * nvr;
|
||||||
} piix_t;
|
} piix_t;
|
||||||
|
|
||||||
@@ -773,10 +774,18 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xa0:
|
case 0xa0:
|
||||||
if (dev->type < 4)
|
if (dev->type < 4) {
|
||||||
fregs[addr] = val & 0x1f;
|
fregs[addr] = val & 0x1f;
|
||||||
|
apm_set_do_smi(dev->apm, (val & 0x01) | (fregs[0xa2] & 0x80));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xa2: case 0xa5: case 0xa6: case 0xa8:
|
case 0xa2:
|
||||||
|
if (dev->type < 4) {
|
||||||
|
fregs[addr] = val & 0xff;
|
||||||
|
apm_set_do_smi(dev->apm, (fregs[0xa0] & 0x01) | (val & 0x80));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xa5: case 0xa6: case 0xa8:
|
||||||
case 0xaa: case 0xac: case 0xae:
|
case 0xaa: case 0xac: case 0xae:
|
||||||
if (dev->type < 4)
|
if (dev->type < 4)
|
||||||
fregs[addr] = val & 0xff;
|
fregs[addr] = val & 0xff;
|
||||||
@@ -924,9 +933,10 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
} else if (func == 3) switch(addr) { /* Power Management */
|
} else if (func == 3) switch(addr) { /* Power Management */
|
||||||
case 0x04:
|
case 0x04:
|
||||||
fregs[0x04] = (val & 1);
|
fregs[0x04] = (val & 0x01);
|
||||||
power_update_io_mapping(dev);
|
power_update_io_mapping(dev);
|
||||||
smbus_update_io_mapping(dev);
|
smbus_update_io_mapping(dev);
|
||||||
|
apm_set_do_smi(dev->apm, !!(fregs[0x5b] & 0x02) && !!(val & 0x01));
|
||||||
break;
|
break;
|
||||||
case 0x07:
|
case 0x07:
|
||||||
if (val & 0x08)
|
if (val & 0x08)
|
||||||
@@ -989,6 +999,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
case 0x5b:
|
case 0x5b:
|
||||||
fregs[addr] = val & 0x03;
|
fregs[addr] = val & 0x03;
|
||||||
|
apm_set_do_smi(dev->apm, !!(val & 0x02) && !!(fregs[0x04] & 0x01));
|
||||||
break;
|
break;
|
||||||
case 0x63:
|
case 0x63:
|
||||||
fregs[addr] = val & 0xf7;
|
fregs[addr] = val & 0xf7;
|
||||||
@@ -1237,7 +1248,7 @@ static void
|
|||||||
|
|
||||||
piix_reset_hard(dev);
|
piix_reset_hard(dev);
|
||||||
|
|
||||||
device_add(&apm_device);
|
dev->apm = device_add(&apm_device);
|
||||||
device_add(&port_92_pci_device);
|
device_add(&port_92_pci_device);
|
||||||
|
|
||||||
dma_alias_set();
|
dma_alias_set();
|
||||||
@@ -1278,9 +1289,10 @@ static void
|
|||||||
dev->readout_regs[1] |= 0x80;
|
dev->readout_regs[1] |= 0x80;
|
||||||
|
|
||||||
io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
||||||
io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
// io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
||||||
|
|
||||||
dev->board_config[0] = 0xff;
|
dev->board_config[0] = 0xff;
|
||||||
|
dev->board_config[0] = 0x00;
|
||||||
/* Register 0x0079: */
|
/* Register 0x0079: */
|
||||||
/* Bit 7: 0 = Keep password, 0 = Clear password. */
|
/* Bit 7: 0 = Keep password, 0 = Clear password. */
|
||||||
/* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */
|
/* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */
|
||||||
|
|||||||
42
src/mem.c
42
src/mem.c
@@ -1209,14 +1209,12 @@ mem_readl_phys(uint32_t addr)
|
|||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
|
|
||||||
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
|
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
|
||||||
return ((uint32_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK];
|
return ((uint32_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_QMASK];
|
||||||
else if (map && map->read_l)
|
else if (map && map->read_l)
|
||||||
return map->read_l(addr, map->p);
|
return map->read_l(addr, map->p);
|
||||||
else {
|
else {
|
||||||
temp = mem_readb_phys(addr + 3) << 24;
|
temp = mem_readw_phys(addr + 2) << 16;
|
||||||
temp |= mem_readb_phys(addr + 2) << 16;
|
temp |= mem_readw_phys(addr);
|
||||||
temp |= mem_readb_phys(addr + 1) << 8;
|
|
||||||
temp |= mem_readb_phys(addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
@@ -1235,21 +1233,34 @@ mem_writeb_phys(uint32_t addr, uint8_t val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
mem_writew_phys(uint32_t addr, uint16_t val)
|
||||||
|
{
|
||||||
|
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||||
|
|
||||||
|
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
|
||||||
|
((uint16_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_HMASK] = val;
|
||||||
|
else if (map && map->write_w)
|
||||||
|
map->write_w(addr, val, map->p);
|
||||||
|
else {
|
||||||
|
mem_writeb_phys(addr, val & 0xff);
|
||||||
|
mem_writeb_phys(addr + 1, (val >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mem_writel_phys(uint32_t addr, uint32_t val)
|
mem_writel_phys(uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
|
||||||
|
|
||||||
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
|
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
|
||||||
_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val;
|
((uint32_t *) _mem_exec[addr >> MEM_GRANULARITY_BITS])[(addr >> 1) & MEM_GRANULARITY_QMASK] = val;
|
||||||
else if (map && map->write_l)
|
else if (map && map->write_l)
|
||||||
map->write_l(addr, val, map->p);
|
map->write_l(addr, val, map->p);
|
||||||
else
|
else {
|
||||||
{
|
mem_writew_phys(addr, val & 0xffff);
|
||||||
mem_writeb_phys(addr, val & 0xff);
|
mem_writew_phys(addr + 2, (val >> 16) & 0xffff);
|
||||||
mem_writeb_phys(addr + 1, (val >> 8) & 0xff);
|
|
||||||
mem_writeb_phys(addr + 2, (val >> 16) & 0xff);
|
|
||||||
mem_writeb_phys(addr + 3, (val >> 24) & 0xff);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1884,6 +1895,8 @@ mem_set_mem_state(uint32_t base, uint32_t size, int state)
|
|||||||
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
|
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
|
||||||
_mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS];
|
_mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state[(c + base) >> MEM_GRANULARITY_BITS];
|
||||||
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state;
|
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = state;
|
||||||
|
// if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
|
||||||
|
// pclog("Set mem state for block at %08X to %02X\n", c + base, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_mapping_recalc(base, size);
|
mem_mapping_recalc(base, size);
|
||||||
@@ -1895,8 +1908,11 @@ mem_restore_mem_state(uint32_t base, uint32_t size)
|
|||||||
{
|
{
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
|
|
||||||
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE)
|
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
|
||||||
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS];
|
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = _mem_state_bak[(c + base) >> MEM_GRANULARITY_BITS];
|
||||||
|
// if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
|
||||||
|
// pclog("Reset mem state for block at %08X\n", c + base);
|
||||||
|
}
|
||||||
|
|
||||||
mem_mapping_recalc(base, size);
|
mem_mapping_recalc(base, size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ extern uint8_t mem_readb_phys(uint32_t addr);
|
|||||||
extern uint16_t mem_readw_phys(uint32_t addr);
|
extern uint16_t mem_readw_phys(uint32_t addr);
|
||||||
extern uint32_t mem_readl_phys(uint32_t addr);
|
extern uint32_t mem_readl_phys(uint32_t addr);
|
||||||
extern void mem_writeb_phys(uint32_t addr, uint8_t val);
|
extern void mem_writeb_phys(uint32_t addr, uint8_t val);
|
||||||
|
extern void mem_writew_phys(uint32_t addr, uint16_t val);
|
||||||
extern void mem_writel_phys(uint32_t addr, uint32_t val);
|
extern void mem_writel_phys(uint32_t addr, uint32_t val);
|
||||||
|
|
||||||
extern uint8_t mem_read_ram(uint32_t addr, void *priv);
|
extern uint8_t mem_read_ram(uint32_t addr, void *priv);
|
||||||
|
|||||||
@@ -558,7 +558,7 @@ CXXFLAGS := $(CFLAGS)
|
|||||||
#########################################################################
|
#########################################################################
|
||||||
# Create the (final) list of objects to build. #
|
# Create the (final) list of objects to build. #
|
||||||
#########################################################################
|
#########################################################################
|
||||||
MAINOBJ := pc.o config.o random.o timer.o io.o apm_new.o dma.o nmi.o \
|
MAINOBJ := pc.o config.o random.o timer.o io.o apm.o dma.o nmi.o \
|
||||||
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
|
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
|
||||||
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o $(VNCOBJ) $(RDPOBJ)
|
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o $(VNCOBJ) $(RDPOBJ)
|
||||||
|
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ CXXFLAGS := $(CFLAGS)
|
|||||||
#########################################################################
|
#########################################################################
|
||||||
# Create the (final) list of objects to build. #
|
# Create the (final) list of objects to build. #
|
||||||
#########################################################################
|
#########################################################################
|
||||||
MAINOBJ := pc.o config.o random.o timer.o io.o apm_new.o dma.o nmi.o \
|
MAINOBJ := pc.o config.o random.o timer.o io.o am.o dma.o nmi.o \
|
||||||
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
|
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
|
||||||
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o $(VNCOBJ) $(RDPOBJ)
|
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o $(VNCOBJ) $(RDPOBJ)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user