i386: preliminary cpu-side smi support (nw)
This commit is contained in:
parent
74b1a0a00b
commit
de38e289c9
@ -136,7 +136,7 @@ static void i386_load_segment_descriptor(i386_state *cpustate, int segment )
|
||||
{
|
||||
cpustate->sreg[segment].base = cpustate->sreg[segment].selector << 4;
|
||||
cpustate->sreg[segment].limit = 0xffff;
|
||||
cpustate->sreg[segment].flags = (segment == CS) ? 0x009a : 0x0092;
|
||||
cpustate->sreg[segment].flags = (segment == CS) ? 0x00fb : 0x00f3;
|
||||
cpustate->sreg[segment].d = 0;
|
||||
cpustate->sreg[segment].valid = true;
|
||||
}
|
||||
@ -3069,7 +3069,18 @@ static void i386_common_init(legacy_cpu_device *device, device_irq_acknowledge_c
|
||||
device->save_item(NAME(cpustate->irq_state));
|
||||
device->save_item(NAME(cpustate->performed_intersegment_jump));
|
||||
device->save_item(NAME(cpustate->mxcsr));
|
||||
device->save_item(NAME(cpustate->smm));
|
||||
device->save_item(NAME(cpustate->nmi_masked));
|
||||
device->save_item(NAME(cpustate->nmi_latched));
|
||||
device->save_item(NAME(cpustate->smbase));
|
||||
device->machine().save().register_postload(save_prepost_delegate(FUNC(i386_postload), cpustate));
|
||||
|
||||
i386_interface *intf = (i386_interface *) device->static_config();
|
||||
|
||||
if (intf != NULL)
|
||||
cpustate->smiact.resolve(intf->smiact, *device);
|
||||
else
|
||||
memset(&cpustate->smiact, 0, sizeof(cpustate->smiact));
|
||||
}
|
||||
|
||||
CPU_INIT( i386 )
|
||||
@ -3159,6 +3170,9 @@ static CPU_RESET( i386 )
|
||||
|
||||
cpustate->idtr.base = 0;
|
||||
cpustate->idtr.limit = 0x3ff;
|
||||
cpustate->smm = false;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
cpustate->a20_mask = ~0;
|
||||
|
||||
@ -3183,6 +3197,94 @@ static CPU_RESET( i386 )
|
||||
CHANGE_PC(cpustate,cpustate->eip);
|
||||
}
|
||||
|
||||
static void pentium_smi(i386_state *cpustate)
|
||||
{
|
||||
UINT32 smram_state = cpustate->smbase + 0xfe00;
|
||||
UINT32 old_cr0 = cpustate->cr[0];
|
||||
UINT32 old_flags = get_flags(cpustate);
|
||||
|
||||
if(cpustate->smm)
|
||||
return; // TODO: latch
|
||||
|
||||
cpustate->cr[0] &= ~(0x8000000d);
|
||||
set_flags(cpustate, 2);
|
||||
if(!cpustate->smiact.isnull())
|
||||
cpustate->smiact(true);
|
||||
cpustate->smm = true;
|
||||
|
||||
// save state
|
||||
WRITE32(cpustate, cpustate->cr[4], smram_state+SMRAM_IP5_CR4);
|
||||
WRITE32(cpustate, cpustate->sreg[ES].limit, smram_state+SMRAM_IP5_ESLIM);
|
||||
WRITE32(cpustate, cpustate->sreg[ES].base, smram_state+SMRAM_IP5_ESBASE);
|
||||
WRITE32(cpustate, cpustate->sreg[ES].flags, smram_state+SMRAM_IP5_ESACC);
|
||||
WRITE32(cpustate, cpustate->sreg[CS].limit, smram_state+SMRAM_IP5_CSLIM);
|
||||
WRITE32(cpustate, cpustate->sreg[CS].base, smram_state+SMRAM_IP5_CSBASE);
|
||||
WRITE32(cpustate, cpustate->sreg[CS].flags, smram_state+SMRAM_IP5_CSACC);
|
||||
WRITE32(cpustate, cpustate->sreg[SS].limit, smram_state+SMRAM_IP5_SSLIM);
|
||||
WRITE32(cpustate, cpustate->sreg[SS].base, smram_state+SMRAM_IP5_SSBASE);
|
||||
WRITE32(cpustate, cpustate->sreg[SS].flags, smram_state+SMRAM_IP5_SSACC);
|
||||
WRITE32(cpustate, cpustate->sreg[DS].limit, smram_state+SMRAM_IP5_DSLIM);
|
||||
WRITE32(cpustate, cpustate->sreg[DS].base, smram_state+SMRAM_IP5_DSBASE);
|
||||
WRITE32(cpustate, cpustate->sreg[DS].flags, smram_state+SMRAM_IP5_DSACC);
|
||||
WRITE32(cpustate, cpustate->sreg[FS].limit, smram_state+SMRAM_IP5_FSLIM);
|
||||
WRITE32(cpustate, cpustate->sreg[FS].base, smram_state+SMRAM_IP5_FSBASE);
|
||||
WRITE32(cpustate, cpustate->sreg[FS].flags, smram_state+SMRAM_IP5_FSACC);
|
||||
WRITE32(cpustate, cpustate->sreg[GS].limit, smram_state+SMRAM_IP5_GSLIM);
|
||||
WRITE32(cpustate, cpustate->sreg[GS].base, smram_state+SMRAM_IP5_GSBASE);
|
||||
WRITE32(cpustate, cpustate->sreg[GS].flags, smram_state+SMRAM_IP5_GSACC);
|
||||
WRITE32(cpustate, cpustate->ldtr.flags, smram_state+SMRAM_IP5_LDTACC);
|
||||
WRITE32(cpustate, cpustate->ldtr.limit, smram_state+SMRAM_IP5_LDTLIM);
|
||||
WRITE32(cpustate, cpustate->ldtr.base, smram_state+SMRAM_IP5_LDTBASE);
|
||||
WRITE32(cpustate, cpustate->gdtr.limit, smram_state+SMRAM_IP5_GDTLIM);
|
||||
WRITE32(cpustate, cpustate->gdtr.base, smram_state+SMRAM_IP5_GDTBASE);
|
||||
WRITE32(cpustate, cpustate->idtr.limit, smram_state+SMRAM_IP5_IDTLIM);
|
||||
WRITE32(cpustate, cpustate->idtr.base, smram_state+SMRAM_IP5_IDTBASE);
|
||||
WRITE32(cpustate, cpustate->task.limit, smram_state+SMRAM_IP5_TRLIM);
|
||||
WRITE32(cpustate, cpustate->task.base, smram_state+SMRAM_IP5_TRBASE);
|
||||
WRITE32(cpustate, cpustate->task.flags, smram_state+SMRAM_IP5_TRACC);
|
||||
|
||||
WRITE32(cpustate, cpustate->sreg[ES].selector, smram_state+SMRAM_ES);
|
||||
WRITE32(cpustate, cpustate->sreg[CS].selector, smram_state+SMRAM_CS);
|
||||
WRITE32(cpustate, cpustate->sreg[SS].selector, smram_state+SMRAM_SS);
|
||||
WRITE32(cpustate, cpustate->sreg[DS].selector, smram_state+SMRAM_DS);
|
||||
WRITE32(cpustate, cpustate->sreg[FS].selector, smram_state+SMRAM_FS);
|
||||
WRITE32(cpustate, cpustate->sreg[GS].selector, smram_state+SMRAM_GS);
|
||||
WRITE32(cpustate, cpustate->ldtr.segment, smram_state+SMRAM_LDTR);
|
||||
WRITE32(cpustate, cpustate->task.segment, smram_state+SMRAM_TR);
|
||||
|
||||
WRITE32(cpustate, cpustate->dr[7], smram_state+SMRAM_DR7);
|
||||
WRITE32(cpustate, cpustate->dr[6], smram_state+SMRAM_DR6);
|
||||
WRITE32(cpustate, REG32(EAX), smram_state+SMRAM_EAX);
|
||||
WRITE32(cpustate, REG32(ECX), smram_state+SMRAM_ECX);
|
||||
WRITE32(cpustate, REG32(EDX), smram_state+SMRAM_EDX);
|
||||
WRITE32(cpustate, REG32(EBX), smram_state+SMRAM_EBX);
|
||||
WRITE32(cpustate, REG32(ESP), smram_state+SMRAM_ESP);
|
||||
WRITE32(cpustate, REG32(EBP), smram_state+SMRAM_EBP);
|
||||
WRITE32(cpustate, REG32(ESI), smram_state+SMRAM_ESI);
|
||||
WRITE32(cpustate, REG32(EDI), smram_state+SMRAM_EDI);
|
||||
WRITE32(cpustate, cpustate->eip, smram_state+SMRAM_EIP);
|
||||
WRITE32(cpustate, old_flags, smram_state+SMRAM_EAX);
|
||||
WRITE32(cpustate, cpustate->cr[3], smram_state+SMRAM_CR3);
|
||||
WRITE32(cpustate, old_cr0, smram_state+SMRAM_CR0);
|
||||
|
||||
cpustate->sreg[DS].selector = cpustate->sreg[ES].selector = cpustate->sreg[FS].selector = cpustate->sreg[GS].selector = cpustate->sreg[SS].selector = 0;
|
||||
cpustate->sreg[DS].base = cpustate->sreg[ES].base = cpustate->sreg[FS].base = cpustate->sreg[GS].base = cpustate->sreg[SS].base = 0x00000000;
|
||||
cpustate->sreg[DS].limit = cpustate->sreg[ES].limit = cpustate->sreg[FS].limit = cpustate->sreg[GS].limit = cpustate->sreg[SS].limit = 0xffffffff;
|
||||
cpustate->sreg[DS].flags = cpustate->sreg[ES].flags = cpustate->sreg[FS].flags = cpustate->sreg[GS].flags = cpustate->sreg[SS].flags = 0x8093;
|
||||
cpustate->sreg[DS].valid = cpustate->sreg[ES].valid = cpustate->sreg[FS].valid = cpustate->sreg[GS].valid = cpustate->sreg[SS].valid =true;
|
||||
cpustate->sreg[CS].selector = 0x3000; // pentium only, ppro sel = smbase >> 4
|
||||
cpustate->sreg[CS].base = cpustate->smbase;
|
||||
cpustate->sreg[CS].limit = 0xffffffff;
|
||||
cpustate->sreg[CS].flags = 0x809b;
|
||||
cpustate->sreg[CS].valid = true;
|
||||
cpustate->cr[4] = 0;
|
||||
cpustate->dr[7] = 0x400;
|
||||
cpustate->eip = 0x8000;
|
||||
|
||||
cpustate->nmi_masked = true;
|
||||
CHANGE_PC(cpustate,cpustate->eip);
|
||||
}
|
||||
|
||||
static void i386_set_irq_line(i386_state *cpustate,int irqline, int state)
|
||||
{
|
||||
if (state != CLEAR_LINE && cpustate->halted)
|
||||
@ -3193,6 +3295,11 @@ static void i386_set_irq_line(i386_state *cpustate,int irqline, int state)
|
||||
if ( irqline == INPUT_LINE_NMI )
|
||||
{
|
||||
/* NMI (I do not think that this is 100% right) */
|
||||
if(cpustate->nmi_masked)
|
||||
{
|
||||
cpustate->nmi_latched = true;
|
||||
return;
|
||||
}
|
||||
if ( state )
|
||||
i386_trap(cpustate,2, 1, 0);
|
||||
}
|
||||
@ -3669,6 +3776,9 @@ static CPU_RESET( i486 )
|
||||
cpustate->eflags = 0;
|
||||
cpustate->eflags_mask = 0x00077fd7;
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->smm = false;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
@ -3781,6 +3891,10 @@ static CPU_RESET( pentium )
|
||||
cpustate->eflags_mask = 0x003f7fd7;
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->mxcsr = 0x1f80;
|
||||
cpustate->smm = false;
|
||||
cpustate->smbase = 0x30000;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
@ -3823,6 +3937,10 @@ static CPU_SET_INFO( pentium )
|
||||
i386_state *cpustate = get_safe_token(device);
|
||||
switch (state)
|
||||
{
|
||||
case CPUINFO_INT_INPUT_STATE+INPUT_LINE_SMI:
|
||||
if(state)
|
||||
pentium_smi(cpustate);
|
||||
break;
|
||||
case CPUINFO_INT_REGISTER + X87_CTRL: cpustate->x87_cw = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + X87_STATUS: cpustate->x87_sw = info->i; break;
|
||||
case CPUINFO_INT_REGISTER + X87_TAG: cpustate->x87_tw = info->i; break;
|
||||
@ -3907,6 +4025,9 @@ static CPU_RESET( mediagx )
|
||||
cpustate->eflags = 0x00200000;
|
||||
cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->smm = false;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
@ -4027,6 +4148,10 @@ static CPU_RESET( pentium_pro )
|
||||
cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->mxcsr = 0x1f80;
|
||||
cpustate->smm = false;
|
||||
cpustate->smbase = 0x30000;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
@ -4127,6 +4252,10 @@ static CPU_RESET( pentium_mmx )
|
||||
cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->mxcsr = 0x1f80;
|
||||
cpustate->smm = false;
|
||||
cpustate->smbase = 0x30000;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
@ -4227,6 +4356,10 @@ static CPU_RESET( pentium2 )
|
||||
cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->mxcsr = 0x1f80;
|
||||
cpustate->smm = false;
|
||||
cpustate->smbase = 0x30000;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
@ -4327,6 +4460,10 @@ static CPU_RESET( pentium3 )
|
||||
cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->mxcsr = 0x1f80;
|
||||
cpustate->smm = false;
|
||||
cpustate->smbase = 0x30000;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
@ -4429,6 +4566,10 @@ static CPU_RESET( pentium4 )
|
||||
cpustate->eflags_mask = 0x00277fd7; /* TODO: is this correct? */
|
||||
cpustate->eip = 0xfff0;
|
||||
cpustate->mxcsr = 0x1f80;
|
||||
cpustate->smm = false;
|
||||
cpustate->smbase = 0x30000;
|
||||
cpustate->nmi_masked = false;
|
||||
cpustate->nmi_latched = false;
|
||||
|
||||
x87_reset(cpustate);
|
||||
|
||||
|
@ -4,7 +4,12 @@
|
||||
#define __I386INTF_H__
|
||||
|
||||
#define INPUT_LINE_A20 1
|
||||
#define INPUT_LINE_SMI 2
|
||||
|
||||
struct i386_interface
|
||||
{
|
||||
devcb_write_line smiact;
|
||||
};
|
||||
|
||||
// mingw has this defined for 32-bit compiles
|
||||
#undef i386
|
||||
|
@ -2498,12 +2498,6 @@ static void I386OP(loadall)(i386_state *cpustate) // Opcode 0x0f 0x07 (0x0
|
||||
fatalerror("i386: LOADALL unimplemented at %08X\n", cpustate->pc - 1);
|
||||
}
|
||||
|
||||
static void I386OP(rsm)(i386_state *cpustate)
|
||||
{
|
||||
logerror("i386: Invalid RSM outside SMM at %08X\n", cpustate->pc - 1);
|
||||
i386_trap(cpustate, 6, 0, 0);
|
||||
}
|
||||
|
||||
static void I386OP(invalid)(i386_state *cpustate)
|
||||
{
|
||||
report_invalid_opcode(cpustate);
|
||||
|
@ -354,7 +354,7 @@ static const X86_OPCODE x86_opcode_table[] =
|
||||
{ 0xA5, OP_2BYTE|OP_I386, I386OP(shld16_cl), I386OP(shld32_cl), },
|
||||
{ 0xA8, OP_2BYTE|OP_I386, I386OP(push_gs16), I386OP(push_gs32), },
|
||||
{ 0xA9, OP_2BYTE|OP_I386, I386OP(pop_gs16), I386OP(pop_gs32), },
|
||||
{ 0xAA, OP_2BYTE|OP_I386, I386OP(rsm), I386OP(rsm), },
|
||||
{ 0xAA, OP_2BYTE|OP_PENTIUM, PENTIUMOP(rsm), PENTIUMOP(rsm), },
|
||||
{ 0xAB, OP_2BYTE|OP_I386, I386OP(bts_rm16_r16), I386OP(bts_rm32_r32), },
|
||||
{ 0xAC, OP_2BYTE|OP_I386, I386OP(shrd16_i8), I386OP(shrd32_i8), },
|
||||
{ 0xAD, OP_2BYTE|OP_I386, I386OP(shrd16_cl), I386OP(shrd32_cl), },
|
||||
|
@ -170,6 +170,76 @@ enum
|
||||
MMX_MM7=X87_ST7
|
||||
};
|
||||
|
||||
enum smram
|
||||
{
|
||||
SMRAM_SMBASE = 0xF8,
|
||||
SMRAM_SMREV = 0xFC,
|
||||
SMRAM_IORSRT = 0x100,
|
||||
SMRAM_AHALT = 0x102,
|
||||
SMRAM_IOEDI = 0x104,
|
||||
SMRAM_IOECX = 0x108,
|
||||
SMRAM_IOESI = 0x10C,
|
||||
|
||||
SMRAM_ES = 0x1A8,
|
||||
SMRAM_CS = 0x1AC,
|
||||
SMRAM_SS = 0x1B0,
|
||||
SMRAM_DS = 0x1B4,
|
||||
SMRAM_FS = 0x1B8,
|
||||
SMRAM_GS = 0x1BC,
|
||||
SMRAM_LDTR = 0x1C0,
|
||||
SMRAM_TR = 0x1C4,
|
||||
SMRAM_DR7 = 0x1C8,
|
||||
SMRAM_DR6 = 0x1CC,
|
||||
SMRAM_EAX = 0x1D0,
|
||||
SMRAM_ECX = 0x1D4,
|
||||
SMRAM_EDX = 0x1D8,
|
||||
SMRAM_EBX = 0x1DC,
|
||||
SMRAM_ESP = 0x1E0,
|
||||
SMRAM_EBP = 0x1E4,
|
||||
SMRAM_ESI = 0x1E8,
|
||||
SMRAM_EDI = 0x1EC,
|
||||
SMRAM_EIP = 0x1F0,
|
||||
SMRAM_EFLAGS = 0x1F4,
|
||||
SMRAM_CR3 = 0x1F8,
|
||||
SMRAM_CR0 = 0x1FC,
|
||||
};
|
||||
|
||||
enum smram_intel_p5
|
||||
{
|
||||
SMRAM_IP5_IOEIP = 0x110,
|
||||
SMRAM_IP5_CR4 = 0x128,
|
||||
SMRAM_IP5_ESLIM = 0x130,
|
||||
SMRAM_IP5_ESBASE = 0x134,
|
||||
SMRAM_IP5_ESACC = 0x138,
|
||||
SMRAM_IP5_CSLIM = 0x13C,
|
||||
SMRAM_IP5_CSBASE = 0x140,
|
||||
SMRAM_IP5_CSACC = 0x144,
|
||||
SMRAM_IP5_SSLIM = 0x148,
|
||||
SMRAM_IP5_SSBASE = 0x14C,
|
||||
SMRAM_IP5_SSACC = 0x150,
|
||||
SMRAM_IP5_DSLIM = 0x154,
|
||||
SMRAM_IP5_DSBASE = 0x158,
|
||||
SMRAM_IP5_DSACC = 0x15C,
|
||||
SMRAM_IP5_FSLIM = 0x160,
|
||||
SMRAM_IP5_FSBASE = 0x164,
|
||||
SMRAM_IP5_FSACC = 0x168,
|
||||
SMRAM_IP5_GSLIM = 0x16C,
|
||||
SMRAM_IP5_GSBASE = 0x170,
|
||||
SMRAM_IP5_GSACC = 0x174,
|
||||
SMRAM_IP5_LDTLIM = 0x178,
|
||||
SMRAM_IP5_LDTBASE = 0x17C,
|
||||
SMRAM_IP5_LDTACC = 0x180,
|
||||
SMRAM_IP5_GDTLIM = 0x184,
|
||||
SMRAM_IP5_GDTBASE = 0x188,
|
||||
SMRAM_IP5_GDTACC = 0x18C,
|
||||
SMRAM_IP5_IDTLIM = 0x190,
|
||||
SMRAM_IP5_IDTBASE = 0x194,
|
||||
SMRAM_IP5_IDTACC = 0x198,
|
||||
SMRAM_IP5_TRLIM = 0x19C,
|
||||
SMRAM_IP5_TRBASE = 0x1A0,
|
||||
SMRAM_IP5_TRACC = 0x1A4,
|
||||
};
|
||||
|
||||
/* Protected mode exceptions */
|
||||
#define FAULT_UD 6 // Invalid Opcode
|
||||
#define FAULT_NM 7 // Coprocessor not available
|
||||
@ -363,6 +433,12 @@ struct i386_state
|
||||
|
||||
vtlb_state *vtlb;
|
||||
|
||||
bool smm;
|
||||
bool nmi_masked;
|
||||
bool nmi_latched;
|
||||
UINT32 smbase;
|
||||
devcb_resolved_write_line smiact;
|
||||
|
||||
// bytes in current opcode, debug only
|
||||
#ifdef DEBUG_MISSING_OPCODE
|
||||
UINT8 opcode_bytes[16];
|
||||
|
@ -144,6 +144,98 @@ static void PENTIUMOP(ud2)(i386_state *cpustate) // Opcode 0x0f 0b
|
||||
i386_trap(cpustate, 6, 0, 0);
|
||||
}
|
||||
|
||||
static void PENTIUMOP(rsm)(i386_state *cpustate)
|
||||
{
|
||||
UINT32 smram_state = cpustate->smbase + 0xfe00;
|
||||
if(!cpustate->smm)
|
||||
{
|
||||
logerror("i386: Invalid RSM outside SMM at %08X\n", cpustate->pc - 1);
|
||||
i386_trap(cpustate, 6, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// load state, no sanity checks anywhere
|
||||
cpustate->smbase = READ32(cpustate, smram_state+SMRAM_SMBASE);
|
||||
cpustate->cr[4] = READ32(cpustate, smram_state+SMRAM_IP5_CR4);
|
||||
cpustate->sreg[ES].limit = READ32(cpustate, smram_state+SMRAM_IP5_ESLIM);
|
||||
cpustate->sreg[ES].base = READ32(cpustate, smram_state+SMRAM_IP5_ESBASE);
|
||||
cpustate->sreg[ES].flags = READ32(cpustate, smram_state+SMRAM_IP5_ESACC);
|
||||
cpustate->sreg[CS].limit = READ32(cpustate, smram_state+SMRAM_IP5_CSLIM);
|
||||
cpustate->sreg[CS].base = READ32(cpustate, smram_state+SMRAM_IP5_CSBASE);
|
||||
cpustate->sreg[CS].flags = READ32(cpustate, smram_state+SMRAM_IP5_CSACC);
|
||||
cpustate->sreg[SS].limit = READ32(cpustate, smram_state+SMRAM_IP5_SSLIM);
|
||||
cpustate->sreg[SS].base = READ32(cpustate, smram_state+SMRAM_IP5_SSBASE);
|
||||
cpustate->sreg[SS].flags = READ32(cpustate, smram_state+SMRAM_IP5_SSACC);
|
||||
cpustate->sreg[DS].limit = READ32(cpustate, smram_state+SMRAM_IP5_DSLIM);
|
||||
cpustate->sreg[DS].base = READ32(cpustate, smram_state+SMRAM_IP5_DSBASE);
|
||||
cpustate->sreg[DS].flags = READ32(cpustate, smram_state+SMRAM_IP5_DSACC);
|
||||
cpustate->sreg[FS].limit = READ32(cpustate, smram_state+SMRAM_IP5_FSLIM);
|
||||
cpustate->sreg[FS].base = READ32(cpustate, smram_state+SMRAM_IP5_FSBASE);
|
||||
cpustate->sreg[FS].flags = READ32(cpustate, smram_state+SMRAM_IP5_FSACC);
|
||||
cpustate->sreg[GS].limit = READ32(cpustate, smram_state+SMRAM_IP5_GSLIM);
|
||||
cpustate->sreg[GS].base = READ32(cpustate, smram_state+SMRAM_IP5_GSBASE);
|
||||
cpustate->sreg[GS].flags = READ32(cpustate, smram_state+SMRAM_IP5_GSACC);
|
||||
cpustate->ldtr.flags = READ32(cpustate, smram_state+SMRAM_IP5_LDTACC);
|
||||
cpustate->ldtr.limit = READ32(cpustate, smram_state+SMRAM_IP5_LDTLIM);
|
||||
cpustate->ldtr.base = READ32(cpustate, smram_state+SMRAM_IP5_LDTBASE);
|
||||
cpustate->gdtr.limit = READ32(cpustate, smram_state+SMRAM_IP5_GDTLIM);
|
||||
cpustate->gdtr.base = READ32(cpustate, smram_state+SMRAM_IP5_GDTBASE);
|
||||
cpustate->idtr.limit = READ32(cpustate, smram_state+SMRAM_IP5_IDTLIM);
|
||||
cpustate->idtr.base = READ32(cpustate, smram_state+SMRAM_IP5_IDTBASE);
|
||||
cpustate->task.limit = READ32(cpustate, smram_state+SMRAM_IP5_TRLIM);
|
||||
cpustate->task.base = READ32(cpustate, smram_state+SMRAM_IP5_TRBASE);
|
||||
cpustate->task.flags = READ32(cpustate, smram_state+SMRAM_IP5_TRACC);
|
||||
|
||||
cpustate->sreg[ES].selector = READ32(cpustate, smram_state+SMRAM_ES);
|
||||
cpustate->sreg[CS].selector = READ32(cpustate, smram_state+SMRAM_CS);
|
||||
cpustate->sreg[SS].selector = READ32(cpustate, smram_state+SMRAM_SS);
|
||||
cpustate->sreg[DS].selector = READ32(cpustate, smram_state+SMRAM_DS);
|
||||
cpustate->sreg[FS].selector = READ32(cpustate, smram_state+SMRAM_FS);
|
||||
cpustate->sreg[GS].selector = READ32(cpustate, smram_state+SMRAM_GS);
|
||||
cpustate->ldtr.segment = READ32(cpustate, smram_state+SMRAM_LDTR);
|
||||
cpustate->task.segment = READ32(cpustate, smram_state+SMRAM_TR);
|
||||
|
||||
cpustate->dr[7] = READ32(cpustate, smram_state+SMRAM_DR7);
|
||||
cpustate->dr[6] = READ32(cpustate, smram_state+SMRAM_DR6);
|
||||
REG32(EAX) = READ32(cpustate, smram_state+SMRAM_EAX);
|
||||
REG32(ECX) = READ32(cpustate, smram_state+SMRAM_ECX);
|
||||
REG32(EDX) = READ32(cpustate, smram_state+SMRAM_EDX);
|
||||
REG32(EBX) = READ32(cpustate, smram_state+SMRAM_EBX);
|
||||
REG32(ESP) = READ32(cpustate, smram_state+SMRAM_ESP);
|
||||
REG32(EBP) = READ32(cpustate, smram_state+SMRAM_EBP);
|
||||
REG32(ESI) = READ32(cpustate, smram_state+SMRAM_ESI);
|
||||
REG32(EDI) = READ32(cpustate, smram_state+SMRAM_EDI);
|
||||
cpustate->eip = READ32(cpustate, smram_state+SMRAM_EIP);
|
||||
cpustate->eflags = READ32(cpustate, smram_state+SMRAM_EAX);
|
||||
cpustate->cr[3] = READ32(cpustate, smram_state+SMRAM_CR3);
|
||||
cpustate->cr[0] = READ32(cpustate, smram_state+SMRAM_CR0);
|
||||
|
||||
cpustate->CPL = (cpustate->sreg[SS].flags >> 13) & 3; // cpl == dpl of ss
|
||||
|
||||
for(int i = 0; i < GS; i++)
|
||||
{
|
||||
if(PROTECTED_MODE && !V8086_MODE)
|
||||
{
|
||||
cpustate->sreg[i].valid = cpustate->sreg[i].selector ? true : false;
|
||||
cpustate->sreg[i].d = (cpustate->sreg[i].flags & 0x4000) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
cpustate->sreg[i].valid = true;
|
||||
}
|
||||
|
||||
if(!cpustate->smiact.isnull())
|
||||
cpustate->smiact(false);
|
||||
cpustate->smm = false;
|
||||
|
||||
CHANGE_PC(cpustate,cpustate->eip);
|
||||
cpustate->nmi_masked = false;
|
||||
if(cpustate->nmi_latched)
|
||||
{
|
||||
cpustate->nmi_latched = false;
|
||||
i386_trap(cpustate, 2, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void SSEOP(cvttss2si)(i386_state *cpustate) // Opcode f3 0f 2c
|
||||
{
|
||||
UINT32 src;
|
||||
|
Loading…
Reference in New Issue
Block a user