More accurate timing for INT, IRET, CALL far, RET far and JMP far.

This commit is contained in:
TomW 2016-02-06 18:08:10 +00:00
commit 94f33aa873
9 changed files with 290 additions and 43 deletions

View file

@ -233,6 +233,7 @@ void x86_int_sw(int num)
// pclog("x86_int_sw %02x %04x:%04x\n", num, CS,pc);
// pclog("x86_int\n");
flags_rebuild();
cycles -= timing_int;
if (msw&1)
{
pmodeint(num,1);
@ -260,8 +261,8 @@ void x86_int_sw(int num)
oxpc=pc;
pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
cycles -= timing_int_rm;
}
cycles-=70;
trap = 0;
CPU_BLOCK_END();
}

View file

@ -22,11 +22,11 @@ static int *opcode_timings[256] =
/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
/*80*/ &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm, &timing_rm, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6),
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(18), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(13), CYCLES(13), CYCLES(26), CYCLES(0), CYCLES(3), CYCLES(15),
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0),
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
@ -45,11 +45,11 @@ static int *opcode_timings_mod3[256] =
/*70*/ &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt, &timing_bnt,
/*80*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1),
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(18), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3),
/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6),
/*b0*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr,
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(13), CYCLES(13), CYCLES(26), CYCLES(0), CYCLES(3), CYCLES(15),
/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), &timing_int, &timing_int, CYCLES(3), CYCLES(0),
/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14),
/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), NULL, NULL, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), NULL
@ -127,11 +127,11 @@ static int *opcode_timings_f7_mod3[8] =
};
static int *opcode_timings_ff[8] =
{
&timing_mm, &timing_mm, CYCLES(5), CYCLES(17), CYCLES(5), CYCLES(13), CYCLES(5), NULL
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
};
static int *opcode_timings_ff_mod3[8] =
{
&timing_rr, &timing_rr, CYCLES(5), CYCLES(17), CYCLES(5), CYCLES(13), CYCLES(5), NULL
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
};
static int *opcode_timings_d8[8] =

View file

@ -238,7 +238,7 @@ static uint32_t opcode_timings[256] =
/* XCHG XCHG XCHG XCHG*/
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
/* CBW CWD CALL far WAIT*/
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(1),
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(1),
/* PUSHF POPF SAHF LAHF*/
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
@ -262,9 +262,9 @@ static uint32_t opcode_timings[256] =
/* LES LDS MOV MOV*/
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
/* ENTER LEAVE RETF RETF*/
PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4),
PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0),
/* INT3 INT INTO IRET*/
PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(16), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(10),
PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
/*d0*/ INVALID, INVALID, INVALID, INVALID,
@ -277,7 +277,7 @@ static uint32_t opcode_timings[256] =
/* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12),
/* CALL JMP JMP JMP*/
PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_V | CYCLES_REG,
PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(0), PAIR_V | CYCLES_REG,
/* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12),
@ -374,7 +374,7 @@ static uint32_t opcode_timings_mod3[256] =
/* XCHG XCHG XCHG XCHG*/
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
/* CBW CWD CALL far WAIT*/
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(1),
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(1),
/* PUSHF POPF SAHF LAHF*/
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
@ -398,9 +398,9 @@ static uint32_t opcode_timings_mod3[256] =
/* LES LDS MOV MOV*/
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
/* ENTER LEAVE RETF RETF*/
PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4),
PAIR_NP | CYCLES(15), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(0),
/* INT3 INT INTO IRET*/
PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(16), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(10),
PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
/*d0*/ INVALID, INVALID, INVALID, INVALID,
@ -414,7 +414,7 @@ static uint32_t opcode_timings_mod3[256] =
/* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12),
/* CALL JMP JMP JMP*/
PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_V | CYCLES_REG,
PAIR_V | CYCLES_REG, PAIR_V | CYCLES_REG, PAIR_NP | CYCLES(0), PAIR_V | CYCLES_REG,
/* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12),
@ -635,16 +635,16 @@ static uint32_t opcode_timings_f7_mod3[8] =
static uint32_t opcode_timings_ff[8] =
{
/* INC DEC CALL CALL far*/
PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4),
PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
/* JMP JMP far PUSH*/
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), INVALID
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID
};
static uint32_t opcode_timings_ff_mod3[8] =
{
/* INC DEC CALL CALL far*/
PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4),
PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
/* JMP JMP far PUSH*/
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), INVALID
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID
};
static uint32_t opcode_timings_d8[8] =

235
src/cpu.c
View file

@ -76,6 +76,11 @@ int timing_mr, timing_mrl;
int timing_rm, timing_rml;
int timing_mm, timing_mml;
int timing_bt, timing_bnt;
int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, timing_int_pm_outer;
int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer;
int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner;
int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
static struct
{
@ -514,6 +519,25 @@ void cpu_set()
timing_mml = 11; /*memory dest - memory src*/
timing_bt = 7-3; /*branch taken*/
timing_bnt = 3; /*branch not taken*/
timing_int = 0;
timing_int_rm = 23;
timing_int_v86 = 0;
timing_int_pm = 40;
timing_int_pm_outer = 78;
timing_iret_rm = 17;
timing_iret_v86 = 0;
timing_iret_pm = 31;
timing_iret_pm_outer = 55;
timing_call_rm = 13;
timing_call_pm = 26;
timing_call_pm_gate = 52;
timing_call_pm_gate_inner = 82;
timing_retf_rm = 15;
timing_retf_pm = 25;
timing_retf_pm_outer = 55;
timing_jmp_rm = 11;
timing_jmp_pm = 23;
timing_jmp_pm_gate = 38;
break;
case CPU_386SX:
@ -526,6 +550,25 @@ void cpu_set()
timing_mml = 10; /*memory dest - memory src*/
timing_bt = 7-3; /*branch taken*/
timing_bnt = 3; /*branch not taken*/
timing_int = 0;
timing_int_rm = 37;
timing_int_v86 = 59;
timing_int_pm = 99;
timing_int_pm_outer = 119;
timing_iret_rm = 22;
timing_iret_v86 = 60;
timing_iret_pm = 38;
timing_iret_pm_outer = 82;
timing_call_rm = 17;
timing_call_pm = 34;
timing_call_pm_gate = 52;
timing_call_pm_gate_inner = 86;
timing_retf_rm = 18;
timing_retf_pm = 32;
timing_retf_pm_outer = 68;
timing_jmp_rm = 12;
timing_jmp_pm = 27;
timing_jmp_pm_gate = 45;
break;
case CPU_386DX:
@ -538,6 +581,25 @@ void cpu_set()
timing_mml = 6; /*memory dest - memory src*/
timing_bt = 7-3; /*branch taken*/
timing_bnt = 3; /*branch not taken*/
timing_int = 0;
timing_int_rm = 37;
timing_int_v86 = 59;
timing_int_pm = 99;
timing_int_pm_outer = 119;
timing_iret_rm = 22;
timing_iret_v86 = 60;
timing_iret_pm = 38;
timing_iret_pm_outer = 82;
timing_call_rm = 17;
timing_call_pm = 34;
timing_call_pm_gate = 52;
timing_call_pm_gate_inner = 86;
timing_retf_rm = 18;
timing_retf_pm = 32;
timing_retf_pm_outer = 68;
timing_jmp_rm = 12;
timing_jmp_pm = 27;
timing_jmp_pm_gate = 45;
break;
case CPU_486SLC:
@ -550,6 +612,26 @@ void cpu_set()
timing_mml = 7;
timing_bt = 6-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
/*unknown*/
timing_int = 4;
timing_int_rm = 14;
timing_int_v86 = 82;
timing_int_pm = 49;
timing_int_pm_outer = 77;
timing_iret_rm = 14;
timing_iret_v86 = 66;
timing_iret_pm = 31;
timing_iret_pm_outer = 66;
timing_call_rm = 12;
timing_call_pm = 30;
timing_call_pm_gate = 41;
timing_call_pm_gate_inner = 83;
timing_retf_rm = 13;
timing_retf_pm = 26;
timing_retf_pm_outer = 61;
timing_jmp_rm = 9;
timing_jmp_pm = 26;
timing_jmp_pm_gate = 37;
break;
case CPU_486DLC:
@ -562,6 +644,26 @@ void cpu_set()
timing_mml = 3;
timing_bt = 6-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
/*unknown*/
timing_int = 4;
timing_int_rm = 14;
timing_int_v86 = 82;
timing_int_pm = 49;
timing_int_pm_outer = 77;
timing_iret_rm = 14;
timing_iret_v86 = 66;
timing_iret_pm = 31;
timing_iret_pm_outer = 66;
timing_call_rm = 12;
timing_call_pm = 30;
timing_call_pm_gate = 41;
timing_call_pm_gate_inner = 83;
timing_retf_rm = 13;
timing_retf_pm = 26;
timing_retf_pm_outer = 61;
timing_jmp_rm = 9;
timing_jmp_pm = 26;
timing_jmp_pm_gate = 37;
break;
case CPU_i486SX:
@ -575,6 +677,25 @@ void cpu_set()
timing_mml = 3;
timing_bt = 3-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_int = 4;
timing_int_rm = 26;
timing_int_v86 = 82;
timing_int_pm = 44;
timing_int_pm_outer = 71;
timing_iret_rm = 15;
timing_iret_v86 = 36; /*unknown*/
timing_iret_pm = 20;
timing_iret_pm_outer = 36;
timing_call_rm = 18;
timing_call_pm = 20;
timing_call_pm_gate = 35;
timing_call_pm_gate_inner = 69;
timing_retf_rm = 13;
timing_retf_pm = 17;
timing_retf_pm_outer = 35;
timing_jmp_rm = 17;
timing_jmp_pm = 19;
timing_jmp_pm_gate = 32;
break;
case CPU_Am486SX:
@ -589,6 +710,25 @@ void cpu_set()
timing_mml = 3;
timing_bt = 3-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_int = 4;
timing_int_rm = 26;
timing_int_v86 = 82;
timing_int_pm = 44;
timing_int_pm_outer = 71;
timing_iret_rm = 15;
timing_iret_v86 = 36; /*unknown*/
timing_iret_pm = 20;
timing_iret_pm_outer = 36;
timing_call_rm = 18;
timing_call_pm = 20;
timing_call_pm_gate = 35;
timing_call_pm_gate_inner = 69;
timing_retf_rm = 13;
timing_retf_pm = 17;
timing_retf_pm_outer = 35;
timing_jmp_rm = 17;
timing_jmp_pm = 19;
timing_jmp_pm_gate = 32;
break;
case CPU_Cx486S:
@ -602,6 +742,25 @@ void cpu_set()
timing_mml = 3;
timing_bt = 4-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_int = 4;
timing_int_rm = 14;
timing_int_v86 = 82;
timing_int_pm = 49;
timing_int_pm_outer = 77;
timing_iret_rm = 14;
timing_iret_v86 = 66; /*unknown*/
timing_iret_pm = 31;
timing_iret_pm_outer = 66;
timing_call_rm = 12;
timing_call_pm = 30;
timing_call_pm_gate = 41;
timing_call_pm_gate_inner = 83;
timing_retf_rm = 13;
timing_retf_pm = 26;
timing_retf_pm_outer = 61;
timing_jmp_rm = 9;
timing_jmp_pm = 26;
timing_jmp_pm_gate = 37;
break;
case CPU_Cx5x86:
@ -614,6 +773,25 @@ void cpu_set()
timing_mml = 2;
timing_bt = 5-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_int = 0;
timing_int_rm = 9;
timing_int_v86 = 82; /*unknown*/
timing_int_pm = 21;
timing_int_pm_outer = 32;
timing_iret_rm = 7;
timing_iret_v86 = 26; /*unknown*/
timing_iret_pm = 10;
timing_iret_pm_outer = 26;
timing_call_rm = 4;
timing_call_pm = 15;
timing_call_pm_gate = 26;
timing_call_pm_gate_inner = 35;
timing_retf_rm = 4;
timing_retf_pm = 7;
timing_retf_pm_outer = 23;
timing_jmp_rm = 5;
timing_jmp_pm = 7;
timing_jmp_pm_gate = 17;
break;
case CPU_WINCHIP:
@ -632,6 +810,25 @@ void cpu_set()
cpu_hasMMX = cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
/*unknown*/
timing_int_rm = 26;
timing_int_v86 = 82;
timing_int_pm = 44;
timing_int_pm_outer = 71;
timing_iret_rm = 7;
timing_iret_v86 = 26;
timing_iret_pm = 10;
timing_iret_pm_outer = 26;
timing_call_rm = 4;
timing_call_pm = 15;
timing_call_pm_gate = 26;
timing_call_pm_gate_inner = 35;
timing_retf_rm = 4;
timing_retf_pm = 7;
timing_retf_pm_outer = 23;
timing_jmp_rm = 5;
timing_jmp_pm = 7;
timing_jmp_pm_gate = 17;
break;
case CPU_PENTIUM:
@ -645,6 +842,25 @@ void cpu_set()
timing_mml = 3;
timing_bt = 0; /*branch taken*/
timing_bnt = 2; /*branch not taken*/
timing_int = 6;
timing_int_rm = 11;
timing_int_v86 = 54;
timing_int_pm = 25;
timing_int_pm_outer = 42;
timing_iret_rm = 7;
timing_iret_v86 = 27; /*unknown*/
timing_iret_pm = 10;
timing_iret_pm_outer = 27;
timing_call_rm = 4;
timing_call_pm = 4;
timing_call_pm_gate = 22;
timing_call_pm_gate_inner = 44;
timing_retf_rm = 4;
timing_retf_pm = 4;
timing_retf_pm_outer = 23;
timing_jmp_rm = 3;
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
@ -665,6 +881,25 @@ void cpu_set()
timing_mml = 3;
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_int = 6;
timing_int_rm = 11;
timing_int_v86 = 54;
timing_int_pm = 25;
timing_int_pm_outer = 42;
timing_iret_rm = 7;
timing_iret_v86 = 27; /*unknown*/
timing_iret_pm = 10;
timing_iret_pm_outer = 27;
timing_call_rm = 4;
timing_call_pm = 4;
timing_call_pm_gate = 22;
timing_call_pm_gate_inner = 44;
timing_retf_rm = 4;
timing_retf_pm = 4;
timing_retf_pm_outer = 23;
timing_jmp_rm = 3;
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;

View file

@ -38,6 +38,11 @@ extern int timing_rm, timing_rml;
extern int timing_mm, timing_mml;
extern int timing_bt, timing_bnt;
extern int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, timing_int_pm_outer;
extern int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer;
extern int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner;
extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
typedef struct

View file

@ -6,7 +6,11 @@
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
else loadcs(new_seg); \
else \
{ \
loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
if (abrt) { cgate16 = cgate32 = 0; return 1; } \
oldss = ss; \
@ -31,7 +35,11 @@
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
else loadcs(new_seg); \
else \
{ \
loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
if (abrt) { cgate16 = cgate32 = 0; return 1; } \
oldss = ss; \
@ -60,7 +68,6 @@ static int opCALL_far_w(uint32_t fetchdat)
CALL_FAR_w(new_cs, new_pc);
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 18 : 17);
return 0;
}
static int opCALL_far_l(uint32_t fetchdat)
@ -74,7 +81,6 @@ static int opCALL_far_l(uint32_t fetchdat)
CALL_FAR_l(new_cs, new_pc);
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 18 : 17);
return 0;
}
@ -116,8 +122,6 @@ static int opFF_w_a16(uint32_t fetchdat)
CALL_FAR_w(new_cs, new_pc);
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 17 : 22);
break;
case 0x20: /*JMP*/
new_pc = geteaw(); if (abrt) return 1;
@ -133,7 +137,6 @@ static int opFF_w_a16(uint32_t fetchdat)
pc = new_pc;
loadcsjmp(new_cs, oxpc); if (abrt) return 1;
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 13 : 12);
break;
case 0x30: /*PUSH w*/
temp = geteaw(); if (abrt) return 1;
@ -184,8 +187,6 @@ static int opFF_w_a32(uint32_t fetchdat)
CALL_FAR_w(new_cs, new_pc);
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 17 : 22);
break;
case 0x20: /*JMP*/
new_pc = geteaw(); if (abrt) return 1;
@ -201,7 +202,6 @@ static int opFF_w_a32(uint32_t fetchdat)
pc = new_pc;
loadcsjmp(new_cs, oxpc); if (abrt) return 1;
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 13 : 12);
break;
case 0x30: /*PUSH w*/
temp = geteaw(); if (abrt) return 1;
@ -253,8 +253,6 @@ static int opFF_l_a16(uint32_t fetchdat)
CALL_FAR_l(new_cs, new_pc);
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 17 : 22);
break;
case 0x20: /*JMP*/
new_pc = geteal(); if (abrt) return 1;
@ -270,7 +268,6 @@ static int opFF_l_a16(uint32_t fetchdat)
pc = new_pc;
loadcsjmp(new_cs, oxpc); if (abrt) return 1;
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 13 : 12);
break;
case 0x30: /*PUSH l*/
temp = geteal(); if (abrt) return 1;
@ -321,8 +318,6 @@ static int opFF_l_a32(uint32_t fetchdat)
CALL_FAR_l(new_cs, new_pc);
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 17 : 22);
break;
case 0x20: /*JMP*/
new_pc = geteal(); if (abrt) return 1;
@ -338,7 +333,6 @@ static int opFF_l_a32(uint32_t fetchdat)
pc = new_pc;
loadcsjmp(new_cs, oxpc); if (abrt) return 1;
CPU_BLOCK_END();
CLOCK_CYCLES(is486 ? 13 : 12);
break;
case 0x30: /*PUSH l*/
temp = geteal(); if (abrt) return 1;

View file

@ -219,7 +219,6 @@ static int opJMP_far_a16(uint32_t fetchdat)
pc = addr;
loadcsjmp(seg, oxpc);
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 17 : 12);
return 0;
}
static int opJMP_far_a32(uint32_t fetchdat)
@ -230,7 +229,6 @@ static int opJMP_far_a32(uint32_t fetchdat)
pc = addr;
loadcsjmp(seg, oxpc);
CPU_BLOCK_END();
CLOCK_CYCLES((is486) ? 17 : 12);
return 0;
}

View file

@ -18,7 +18,7 @@
if (abrt) return 1; \
if (stack32) ESP += 4 + stack_offset; \
else SP += 4 + stack_offset; \
CLOCK_CYCLES(is486 ? 13 : 18);
cycles -= timing_retf_rm;
#define RETF_a32(stack_offset) \
if ((msw&1) && !(eflags&VM_FLAG)) \
@ -40,7 +40,7 @@
if (abrt) return 1; \
if (stack32) ESP += 8 + stack_offset; \
else SP += 8 + stack_offset; \
CLOCK_CYCLES(is486 ? 13 : 18);
cycles -= timing_retf_rm;
static int opRETF_a16(uint32_t fetchdat)
{
@ -102,9 +102,9 @@ static int opIRET_286(uint32_t fetchdat)
SP += 6;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
CLOCK_CYCLES(is486 ? 15 : 22);
nmi_enable = 1;
CPU_BLOCK_END();
return abrt;
@ -142,9 +142,9 @@ static int opIRET(uint32_t fetchdat)
SP += 6;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
CLOCK_CYCLES(is486 ? 15 : 22);
nmi_enable = 1;
CPU_BLOCK_END();
return abrt;
@ -184,9 +184,9 @@ static int opIRETD(uint32_t fetchdat)
SP += 12;
}
loadcs(new_cs);
cycles -= timing_iret_rm;
}
flags_extract();
CLOCK_CYCLES(is486 ? 15 : 22);
nmi_enable = 1;
CPU_BLOCK_END();
return abrt;

View file

@ -6,6 +6,7 @@
#include "mem.h"
#include "x86.h"
#include "386.h"
#include "cpu.h"
/*Controls whether the accessed bit in a descriptor is set when CS is loaded. The
386 PRM is ambiguous on this subject, but BOCHS doesn't set it and Windows 98
@ -619,6 +620,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
do_seg_load(&_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
use32=(segdat[3]&0x40)?0x300:0;
cycles -= timing_jmp_pm;
}
else /*System segment*/
{
@ -728,6 +730,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
x86gpf(NULL,seg2&~3);
return;
}
cycles -= timing_jmp_pm_gate;
break;
@ -765,6 +768,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
if (eflags&VM_FLAG) _cs.access=(3<<5) | 2;
else _cs.access=(0<<5) | 2;
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
cycles -= timing_jmp_rm;
}
}
@ -944,6 +948,7 @@ void loadcscall(uint16_t seg)
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
use32=(segdat[3]&0x40)?0x300:0;
if (csout) pclog("Complete\n");
cycles -= timing_call_pm;
}
else
{
@ -1203,6 +1208,7 @@ void loadcscall(uint16_t seg)
// PUSHW(oldcs);
// PUSHW(oldpc); if (abrt) return;
}
cycles -= timing_call_pm_gate_inner;
break;
}
else if (DPL > CPL)
@ -1233,6 +1239,7 @@ void loadcscall(uint16_t seg)
writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
cpl_override = 0;
#endif
cycles -= timing_call_pm_gate;
break;
default:
@ -1401,6 +1408,7 @@ void pmoderetf(int is32, uint16_t off)
use32=(segdat[3]&0x40)?0x300:0;
// pclog("CPL=RPL return to %04X:%08X\n",CS,pc);
cycles -= timing_retf_pm;
}
else
{
@ -1558,6 +1566,7 @@ void pmoderetf(int is32, uint16_t off)
check_seg_valid(&_fs);
check_seg_valid(&_gs);
// pclog("CPL<RPL return to %04X:%08X %04X:%08X\n",CS,pc,SS,ESP);
cycles -= timing_retf_pm_outer;
}
}
@ -1827,6 +1836,7 @@ void pmodeint(int num, int soft)
}
cpl_override=0;
_cs.access=0;
cycles -= timing_int_pm_outer - timing_int_pm;
// pclog("Non-confirming int gate, CS = %04X\n");
break;
}
@ -1897,6 +1907,7 @@ void pmodeint(int num, int soft)
}
flags&=~(T_FLAG|NT_FLAG);
// if (output) pclog("Final Stack %04X:%08X\n",SS,ESP);
cycles -= timing_int_pm;
break;
case 0x500: /*Task gate*/
@ -1988,6 +1999,7 @@ void pmodeiret(int is32)
_cs.limit_high = 0xffff;
CS=seg;
flags=(flags&0x3000)|(tempflags&0xCFD5)|2;
cycles -= timing_iret_rm;
return;
}
@ -2079,7 +2091,7 @@ void pmodeiret(int is32)
do_seg_v86_init(&_ss);
use32=0;
flags=(tempflags&0xFFD5)|2;
cycles -= timing_iret_v86;
// pclog("V86 IRET to %04X:%04X %04X:%04X %04X %04X %04X %04X %i\n",CS,pc,SS,SP,DS,ES,FS,GS,abrt);
// if (CS==0xFFFF && pc==0xFFFFFFFF) timetolive=12;
/* {
@ -2197,6 +2209,7 @@ void pmodeiret(int is32)
writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
cpl_override = 0;
#endif
cycles -= timing_iret_pm;
}
else /*Return to outer level*/
{
@ -2311,6 +2324,7 @@ void pmodeiret(int is32)
check_seg_valid(&_es);
check_seg_valid(&_fs);
check_seg_valid(&_gs);
cycles -= timing_iret_pm_outer;
}
pc=newpc;
flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;