Added VME emulation to Intel DX4, Pentium and Pentium MMX.
Temporarily disabled recompilation of CLI and STI.
This commit is contained in:
parent
8fbebead19
commit
1f33b52451
11 changed files with 259 additions and 62 deletions
Binary file not shown.
|
|
@ -7,6 +7,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc);
|
||||||
void pmoderetf(int is32, uint16_t off);
|
void pmoderetf(int is32, uint16_t off);
|
||||||
void pmodeiret(int is32);
|
void pmodeiret(int is32);
|
||||||
void x86_int_sw(int num);
|
void x86_int_sw(int num);
|
||||||
|
int x86_int_sw_rm(int num);
|
||||||
|
|
||||||
int divl(uint32_t val);
|
int divl(uint32_t val);
|
||||||
int idivl(int32_t val);
|
int idivl(int32_t val);
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,38 @@ void x86_int_sw(int num)
|
||||||
CPU_BLOCK_END();
|
CPU_BLOCK_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int x86_int_sw_rm(int num)
|
||||||
|
{
|
||||||
|
uint32_t addr;
|
||||||
|
uint16_t new_pc, new_cs;
|
||||||
|
|
||||||
|
flags_rebuild();
|
||||||
|
cycles -= timing_int;
|
||||||
|
|
||||||
|
addr = num << 2;
|
||||||
|
new_pc = readmemw(0, addr);
|
||||||
|
new_cs = readmemw(0, addr + 2);
|
||||||
|
|
||||||
|
if (cpu_state.abrt) return 1;
|
||||||
|
|
||||||
|
writememw(ss,((SP-2)&0xFFFF),flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; }
|
||||||
|
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||||
|
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {pclog("abrt6\n"); return 1; }
|
||||||
|
SP-=6;
|
||||||
|
|
||||||
|
eflags &= ~VIF_FLAG;
|
||||||
|
flags &= ~T_FLAG;
|
||||||
|
cpu_state.pc = new_pc;
|
||||||
|
loadcs(new_cs);
|
||||||
|
oxpc=cpu_state.pc;
|
||||||
|
|
||||||
|
cycles -= timing_int_rm;
|
||||||
|
trap = 0;
|
||||||
|
CPU_BLOCK_END();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void x86illegal()
|
void x86illegal()
|
||||||
{
|
{
|
||||||
// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
|
// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
|
||||||
|
|
|
||||||
|
|
@ -602,7 +602,7 @@ chdir(pcempath);
|
||||||
if (is386)
|
if (is386)
|
||||||
{
|
{
|
||||||
printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
|
printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
|
||||||
printf("CR0=%08X CR2=%08X CR3=%08X\n",cr0,cr2,cr3);
|
printf("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4);
|
||||||
}
|
}
|
||||||
printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
|
printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
|
||||||
for (c=0;c<1024*1024;c++)
|
for (c=0;c<1024*1024;c++)
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,13 @@ static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
|
||||||
|
|
||||||
static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||||
{
|
{
|
||||||
|
return 0;
|
||||||
CLEAR_BITS((uintptr_t)&flags, I_FLAG);
|
CLEAR_BITS((uintptr_t)&flags, I_FLAG);
|
||||||
return op_pc;
|
return op_pc;
|
||||||
}
|
}
|
||||||
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||||
{
|
{
|
||||||
|
return 0;
|
||||||
SET_BITS((uintptr_t)&flags, I_FLAG);
|
SET_BITS((uintptr_t)&flags, I_FLAG);
|
||||||
return op_pc;
|
return op_pc;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
src/cpu.c
40
src/cpu.c
|
|
@ -51,6 +51,7 @@ OpFn *x86_opcodes_df_a32;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CPUID_FPU = (1 << 0),
|
CPUID_FPU = (1 << 0),
|
||||||
|
CPUID_VME = (1 << 1),
|
||||||
CPUID_TSC = (1 << 4),
|
CPUID_TSC = (1 << 4),
|
||||||
CPUID_MSR = (1 << 5),
|
CPUID_MSR = (1 << 5),
|
||||||
CPUID_CMPXCHG8B = (1 << 8),
|
CPUID_CMPXCHG8B = (1 << 8),
|
||||||
|
|
@ -67,6 +68,7 @@ int cpu_busspeed;
|
||||||
int cpu_hasrdtsc;
|
int cpu_hasrdtsc;
|
||||||
int cpu_hasMMX, cpu_hasMSR;
|
int cpu_hasMMX, cpu_hasMSR;
|
||||||
int cpu_hasCR4;
|
int cpu_hasCR4;
|
||||||
|
int cpu_hasVME;
|
||||||
int cpu_use_dynarec;
|
int cpu_use_dynarec;
|
||||||
int cpu_cyrix_alignment;
|
int cpu_cyrix_alignment;
|
||||||
|
|
||||||
|
|
@ -294,8 +296,8 @@ CPU cpus_i486[] =
|
||||||
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
||||||
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
|
||||||
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6},
|
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6},
|
||||||
{"iDX4/75", CPU_i486DX, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, /*CPUID available on DX4, >= 75 MHz*/
|
{"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, /*CPUID available on DX4, >= 75 MHz*/
|
||||||
{"iDX4/100", CPU_i486DX,10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
|
{"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
|
||||||
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7},
|
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7},
|
||||||
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8},
|
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8},
|
||||||
{"", -1, 0, 0, 0}
|
{"", -1, 0, 0, 0}
|
||||||
|
|
@ -761,7 +763,11 @@ void cpu_set()
|
||||||
timing_jmp_pm_gate = 37;
|
timing_jmp_pm_gate = 37;
|
||||||
timing_misaligned = 3;
|
timing_misaligned = 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CPU_iDX4:
|
||||||
|
cpu_hasCR4 = 1;
|
||||||
|
cpu_hasVME = 1;
|
||||||
|
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME;
|
||||||
case CPU_i486SX:
|
case CPU_i486SX:
|
||||||
case CPU_i486DX:
|
case CPU_i486DX:
|
||||||
timing_rr = 1; /*register dest - register src*/
|
timing_rr = 1; /*register dest - register src*/
|
||||||
|
|
@ -971,7 +977,8 @@ void cpu_set()
|
||||||
cpu_hasMMX = 0;
|
cpu_hasMMX = 0;
|
||||||
cpu_hasMSR = 1;
|
cpu_hasMSR = 1;
|
||||||
cpu_hasCR4 = 1;
|
cpu_hasCR4 = 1;
|
||||||
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
cpu_hasVME = 1;
|
||||||
|
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
||||||
codegen_timing_set(&codegen_timing_pentium);
|
codegen_timing_set(&codegen_timing_pentium);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1011,7 +1018,8 @@ void cpu_set()
|
||||||
cpu_hasMMX = 1;
|
cpu_hasMMX = 1;
|
||||||
cpu_hasMSR = 1;
|
cpu_hasMSR = 1;
|
||||||
cpu_hasCR4 = 1;
|
cpu_hasCR4 = 1;
|
||||||
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
cpu_hasVME = 1;
|
||||||
|
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
||||||
codegen_timing_set(&codegen_timing_pentium);
|
codegen_timing_set(&codegen_timing_pentium);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1197,6 +1205,24 @@ void cpu_CPUID()
|
||||||
EAX = 0;
|
EAX = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CPU_iDX4:
|
||||||
|
if (!EAX)
|
||||||
|
{
|
||||||
|
EAX = 0x00000001;
|
||||||
|
EBX = 0x756e6547;
|
||||||
|
EDX = 0x49656e69;
|
||||||
|
ECX = 0x6c65746e;
|
||||||
|
}
|
||||||
|
else if (EAX == 1)
|
||||||
|
{
|
||||||
|
EAX = CPUID;
|
||||||
|
EBX = ECX = 0;
|
||||||
|
EDX = CPUID_FPU | CPUID_VME;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
EAX = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case CPU_Am486SX:
|
case CPU_Am486SX:
|
||||||
if (!EAX)
|
if (!EAX)
|
||||||
{
|
{
|
||||||
|
|
@ -1273,7 +1299,7 @@ void cpu_CPUID()
|
||||||
{
|
{
|
||||||
EAX = CPUID;
|
EAX = CPUID;
|
||||||
EBX = ECX = 0;
|
EBX = ECX = 0;
|
||||||
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
|
EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EAX = 0;
|
EAX = 0;
|
||||||
|
|
@ -1291,7 +1317,7 @@ void cpu_CPUID()
|
||||||
{
|
{
|
||||||
EAX = CPUID;
|
EAX = CPUID;
|
||||||
EBX = ECX = 0;
|
EBX = ECX = 0;
|
||||||
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
|
EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EAX = 0;
|
EAX = 0;
|
||||||
|
|
|
||||||
18
src/cpu.h
18
src/cpu.h
|
|
@ -23,16 +23,17 @@ extern int cpu, cpu_manufacturer;
|
||||||
#define CPU_i486DX 10
|
#define CPU_i486DX 10
|
||||||
#define CPU_Am486DX 11
|
#define CPU_Am486DX 11
|
||||||
#define CPU_Cx486DX 12
|
#define CPU_Cx486DX 12
|
||||||
#define CPU_Cx5x86 13
|
#define CPU_iDX4 13
|
||||||
|
#define CPU_Cx5x86 14
|
||||||
|
|
||||||
/*586 class CPUs*/
|
/*586 class CPUs*/
|
||||||
#define CPU_WINCHIP 14
|
#define CPU_WINCHIP 15
|
||||||
#define CPU_PENTIUM 15
|
#define CPU_PENTIUM 16
|
||||||
#define CPU_PENTIUMMMX 16
|
#define CPU_PENTIUMMMX 17
|
||||||
#define CPU_Cx6x86 17
|
#define CPU_Cx6x86 18
|
||||||
#define CPU_Cx6x86MX 18
|
#define CPU_Cx6x86MX 19
|
||||||
#define CPU_Cx6x86L 19
|
#define CPU_Cx6x86L 20
|
||||||
#define CPU_CxGX1 20
|
#define CPU_CxGX1 21
|
||||||
|
|
||||||
#define MANU_INTEL 0
|
#define MANU_INTEL 0
|
||||||
#define MANU_AMD 1
|
#define MANU_AMD 1
|
||||||
|
|
@ -106,6 +107,7 @@ extern int cpu_hasrdtsc;
|
||||||
extern int cpu_hasMSR;
|
extern int cpu_hasMSR;
|
||||||
extern int cpu_hasMMX;
|
extern int cpu_hasMMX;
|
||||||
extern int cpu_hasCR4;
|
extern int cpu_hasCR4;
|
||||||
|
extern int cpu_hasVME;
|
||||||
|
|
||||||
#define CR4_TSD (1 << 2)
|
#define CR4_TSD (1 << 2)
|
||||||
#define CR4_DE (1 << 3)
|
#define CR4_DE (1 << 3)
|
||||||
|
|
|
||||||
|
|
@ -244,9 +244,14 @@ uint32_t dr[8];
|
||||||
#define V_FLAG 0x0800
|
#define V_FLAG 0x0800
|
||||||
#define NT_FLAG 0x4000
|
#define NT_FLAG 0x4000
|
||||||
#define VM_FLAG 0x0002 /*In EFLAGS*/
|
#define VM_FLAG 0x0002 /*In EFLAGS*/
|
||||||
|
#define VIF_FLAG 0x0008 /*In EFLAGS*/
|
||||||
|
#define VIP_FLAG 0x0010 /*In EFLAGS*/
|
||||||
|
|
||||||
#define WP_FLAG 0x10000 /*In CR0*/
|
#define WP_FLAG 0x10000 /*In CR0*/
|
||||||
|
|
||||||
|
#define CR4_VME (1 << 0)
|
||||||
|
#define CR4_PVI (1 << 1)
|
||||||
|
|
||||||
#define IOPL ((flags>>12)&3)
|
#define IOPL ((flags>>12)&3)
|
||||||
|
|
||||||
#define IOPLp ((!(msw&1)) || (CPL<=IOPL))
|
#define IOPLp ((!(msw&1)) || (CPL<=IOPL))
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,16 @@ static int opCLI(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
if (!IOPLp)
|
if (!IOPLp)
|
||||||
{
|
{
|
||||||
x86gpf(NULL,0);
|
if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||||
return 1;
|
((eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||||
|
{
|
||||||
|
eflags &= ~VIF_FLAG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x86gpf(NULL,0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
flags &= ~I_FLAG;
|
flags &= ~I_FLAG;
|
||||||
|
|
@ -57,8 +65,22 @@ static int opSTI(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
if (!IOPLp)
|
if (!IOPLp)
|
||||||
{
|
{
|
||||||
x86gpf(NULL,0);
|
if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||||
return 1;
|
((eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||||
|
{
|
||||||
|
if (eflags & VIP_FLAG)
|
||||||
|
{
|
||||||
|
x86gpf(NULL,0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
eflags |= VIF_FLAG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x86gpf(NULL,0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
flags |= I_FLAG;
|
flags |= I_FLAG;
|
||||||
|
|
@ -94,11 +116,27 @@ static int opPUSHF(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||||
{
|
{
|
||||||
x86gpf(NULL,0);
|
if (cr4 & CR4_VME)
|
||||||
return 1;
|
{
|
||||||
|
uint16_t temp;
|
||||||
|
|
||||||
|
flags_rebuild();
|
||||||
|
temp = (flags & ~I_FLAG) | 0x3000;
|
||||||
|
if (eflags & VIF_FLAG)
|
||||||
|
temp |= I_FLAG;
|
||||||
|
PUSH_W(temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x86gpf(NULL,0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags_rebuild();
|
||||||
|
PUSH_W(flags);
|
||||||
}
|
}
|
||||||
flags_rebuild();
|
|
||||||
PUSH_W(flags);
|
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
|
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
|
||||||
return cpu_state.abrt;
|
return cpu_state.abrt;
|
||||||
|
|
@ -111,8 +149,9 @@ static int opPUSHFD(uint32_t fetchdat)
|
||||||
x86gpf(NULL, 0);
|
x86gpf(NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (CPUID) tempw = eflags & 0x24;
|
if (cpu_CR4_mask & CR4_VME) tempw = eflags & 0x3c;
|
||||||
else tempw = eflags & 4;
|
else if (CPUID) tempw = eflags & 0x24;
|
||||||
|
else tempw = eflags & 4;
|
||||||
flags_rebuild();
|
flags_rebuild();
|
||||||
PUSH_L(flags | (tempw << 16));
|
PUSH_L(flags | (tempw << 16));
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
|
|
@ -151,15 +190,48 @@ static int opPOPF(uint32_t fetchdat)
|
||||||
|
|
||||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||||
{
|
{
|
||||||
x86gpf(NULL, 0);
|
if (cr4 & CR4_VME)
|
||||||
return 1;
|
{
|
||||||
}
|
uint32_t old_esp = ESP;
|
||||||
|
|
||||||
tempw = POP_W(); if (cpu_state.abrt) return 1;
|
|
||||||
|
|
||||||
if (!(CPL) || !(msw & 1)) flags = (tempw & 0x7fd5) | 2;
|
tempw = POP_W();
|
||||||
else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
if (cpu_state.abrt)
|
||||||
else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
{
|
||||||
|
ESP = old_esp;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (eflags & VIP_FLAG)))
|
||||||
|
{
|
||||||
|
ESP = old_esp;
|
||||||
|
x86gpf(NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (tempw & I_FLAG)
|
||||||
|
eflags |= VIF_FLAG;
|
||||||
|
else
|
||||||
|
eflags &= ~VIF_FLAG;
|
||||||
|
flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x86gpf(NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tempw = POP_W();
|
||||||
|
if (cpu_state.abrt)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!(CPL) || !(msw & 1))
|
||||||
|
flags = (tempw & 0x7fd5) | 2;
|
||||||
|
else if (IOPLp)
|
||||||
|
flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||||
|
else
|
||||||
|
flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||||
|
}
|
||||||
flags_extract();
|
flags_extract();
|
||||||
|
|
||||||
CLOCK_CYCLES(5);
|
CLOCK_CYCLES(5);
|
||||||
|
|
@ -185,11 +257,12 @@ static int opPOPFD(uint32_t fetchdat)
|
||||||
else if (IOPLp) flags = (flags & 0x3000) | (templ & 0x4fd5) | 2;
|
else if (IOPLp) flags = (flags & 0x3000) | (templ & 0x4fd5) | 2;
|
||||||
else flags = (flags & 0x3200) | (templ & 0x4dd5) | 2;
|
else flags = (flags & 0x3200) | (templ & 0x4dd5) | 2;
|
||||||
|
|
||||||
templ &= is486 ? 0x240000 : 0;
|
templ &= is486 ? 0x3c0000 : 0;
|
||||||
templ |= ((eflags&3) << 16);
|
templ |= ((eflags&3) << 16);
|
||||||
if (CPUID) eflags = (templ >> 16) & 0x27;
|
if (cpu_CR4_mask & CR4_VME) eflags = (templ >> 16) & 0x3f;
|
||||||
else if (is486) eflags = (templ >> 16) & 7;
|
else if (CPUID) eflags = (templ >> 16) & 0x27;
|
||||||
else eflags = (templ >> 16) & 3;
|
else if (is486) eflags = (templ >> 16) & 7;
|
||||||
|
else eflags = (templ >> 16) & 3;
|
||||||
|
|
||||||
flags_extract();
|
flags_extract();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,15 +29,39 @@ static int opINT1(uint32_t fetchdat)
|
||||||
static int opINT(uint32_t fetchdat)
|
static int opINT(uint32_t fetchdat)
|
||||||
{
|
{
|
||||||
int cycles_old = cycles; UNUSED(cycles_old);
|
int cycles_old = cycles; UNUSED(cycles_old);
|
||||||
uint8_t temp;
|
uint8_t temp = getbytef();
|
||||||
|
|
||||||
/*if (msw&1) pclog("INT %i %i %i\n",cr0&1,eflags&VM_FLAG,IOPL);*/
|
|
||||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||||
{
|
{
|
||||||
|
if (cr4 & CR4_VME)
|
||||||
|
{
|
||||||
|
uint16_t t;
|
||||||
|
uint8_t d;
|
||||||
|
|
||||||
|
cpl_override = 1;
|
||||||
|
t = readmemw(tr.base, 0x66) - 32;
|
||||||
|
cpl_override = 0;
|
||||||
|
if (cpu_state.abrt) return 1;
|
||||||
|
|
||||||
|
t += (temp >> 3);
|
||||||
|
if (t <= tr.limit)
|
||||||
|
{
|
||||||
|
cpl_override = 1;
|
||||||
|
d = readmemb(tr.base, t);// + (temp >> 3));
|
||||||
|
cpl_override = 0;
|
||||||
|
if (cpu_state.abrt) return 1;
|
||||||
|
|
||||||
|
if (!(d & (1 << (temp & 7))))
|
||||||
|
{
|
||||||
|
x86_int_sw_rm(temp);
|
||||||
|
PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
x86gpf(NULL,0);
|
x86gpf(NULL,0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
temp = getbytef();
|
|
||||||
// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc);
|
// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc);
|
||||||
// if (CS == 0x0028 && pc == 0xC03813C0)
|
// if (CS == 0x0028 && pc == 0xC03813C0)
|
||||||
// output = 3;
|
// output = 3;
|
||||||
|
|
|
||||||
|
|
@ -141,35 +141,67 @@ static int opIRET(uint32_t fetchdat)
|
||||||
|
|
||||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||||
{
|
{
|
||||||
x86gpf(NULL,0);
|
if (cr4 & CR4_VME)
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (msw&1)
|
|
||||||
{
|
|
||||||
optype = IRET;
|
|
||||||
pmodeiret(0);
|
|
||||||
optype = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint16_t new_cs;
|
|
||||||
oxpc = cpu_state.pc;
|
|
||||||
if (stack32)
|
|
||||||
{
|
{
|
||||||
cpu_state.pc = readmemw(ss, ESP);
|
uint16_t new_pc, new_cs, new_flags;
|
||||||
new_cs = readmemw(ss, ESP + 2);
|
|
||||||
flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
new_pc = readmemw(ss, SP);
|
||||||
ESP += 6;
|
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||||
|
new_flags = readmemw(ss, ((SP + 4) & 0xffff));
|
||||||
|
if (cpu_state.abrt)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (eflags & VIP_FLAG)))
|
||||||
|
{
|
||||||
|
x86gpf(NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
SP += 6;
|
||||||
|
if (new_flags & I_FLAG)
|
||||||
|
eflags |= VIF_FLAG;
|
||||||
|
else
|
||||||
|
eflags &= ~VIF_FLAG;
|
||||||
|
flags = (flags & 0x3300) | (new_flags & 0x4cd5) | 2;
|
||||||
|
loadcs(new_cs);
|
||||||
|
cpu_state.pc = new_pc;
|
||||||
|
|
||||||
|
cycles -= timing_iret_rm;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cpu_state.pc = readmemw(ss, SP);
|
x86gpf(NULL,0);
|
||||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
return 1;
|
||||||
flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
}
|
||||||
SP += 6;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (msw&1)
|
||||||
|
{
|
||||||
|
optype = IRET;
|
||||||
|
pmodeiret(0);
|
||||||
|
optype = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t new_cs;
|
||||||
|
oxpc = cpu_state.pc;
|
||||||
|
if (stack32)
|
||||||
|
{
|
||||||
|
cpu_state.pc = readmemw(ss, ESP);
|
||||||
|
new_cs = readmemw(ss, ESP + 2);
|
||||||
|
flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||||
|
ESP += 6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpu_state.pc = readmemw(ss, SP);
|
||||||
|
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||||
|
flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
||||||
|
SP += 6;
|
||||||
|
}
|
||||||
|
loadcs(new_cs);
|
||||||
|
cycles -= timing_iret_rm;
|
||||||
}
|
}
|
||||||
loadcs(new_cs);
|
|
||||||
cycles -= timing_iret_rm;
|
|
||||||
}
|
}
|
||||||
flags_extract();
|
flags_extract();
|
||||||
nmi_enable = 1;
|
nmi_enable = 1;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue