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_sw %02x %04x:%04x\n", num, CS,pc);
// pclog("x86_int\n"); // pclog("x86_int\n");
flags_rebuild(); flags_rebuild();
cycles -= timing_int;
if (msw&1) if (msw&1)
{ {
pmodeint(num,1); pmodeint(num,1);
@ -260,8 +261,8 @@ void x86_int_sw(int num)
oxpc=pc; oxpc=pc;
pc=readmemw(0,addr); pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2)); loadcs(readmemw(0,addr+2));
cycles -= timing_int_rm;
} }
cycles-=70;
trap = 0; trap = 0;
CPU_BLOCK_END(); 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, /*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), /*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), /*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, /*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, /*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), /*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 /*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, /*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), /*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), /*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, /*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, /*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), /*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 /*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] = 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] = 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] = static int *opcode_timings_d8[8] =

View file

@ -238,7 +238,7 @@ static uint32_t opcode_timings[256] =
/* XCHG XCHG XCHG XCHG*/ /* XCHG XCHG XCHG XCHG*/
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
/* CBW CWD CALL far WAIT*/ /* 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*/ /* PUSHF POPF SAHF LAHF*/
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), 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*/ /* LES LDS MOV MOV*/
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
/* ENTER LEAVE RETF RETF*/ /* 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*/ /* 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, /*d0*/ INVALID, INVALID, INVALID, INVALID,
@ -277,7 +277,7 @@ static uint32_t opcode_timings[256] =
/* IN AL IN AX OUT_AL OUT_AX*/ /* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12),
/* CALL JMP JMP JMP*/ /* 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*/ /* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), 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*/ /* XCHG XCHG XCHG XCHG*/
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
/* CBW CWD CALL far WAIT*/ /* 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*/ /* PUSHF POPF SAHF LAHF*/
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), 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*/ /* LES LDS MOV MOV*/
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
/* ENTER LEAVE RETF RETF*/ /* 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*/ /* 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, /*d0*/ INVALID, INVALID, INVALID, INVALID,
@ -414,7 +414,7 @@ static uint32_t opcode_timings_mod3[256] =
/* IN AL IN AX OUT_AL OUT_AX*/ /* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12),
/* CALL JMP JMP JMP*/ /* 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*/ /* IN AL IN AX OUT_AL OUT_AX*/
PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(12), PAIR_NP | CYCLES(12), 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] = static uint32_t opcode_timings_ff[8] =
{ {
/* INC DEC CALL CALL far*/ /* 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*/ /* 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] = static uint32_t opcode_timings_ff_mod3[8] =
{ {
/* INC DEC CALL CALL far*/ /* 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*/ /* 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] = 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_rm, timing_rml;
int timing_mm, timing_mml; int timing_mm, timing_mml;
int timing_bt, timing_bnt; 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 static struct
{ {
@ -514,6 +519,25 @@ void cpu_set()
timing_mml = 11; /*memory dest - memory src*/ timing_mml = 11; /*memory dest - memory src*/
timing_bt = 7-3; /*branch taken*/ timing_bt = 7-3; /*branch taken*/
timing_bnt = 3; /*branch not 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; break;
case CPU_386SX: case CPU_386SX:
@ -526,6 +550,25 @@ void cpu_set()
timing_mml = 10; /*memory dest - memory src*/ timing_mml = 10; /*memory dest - memory src*/
timing_bt = 7-3; /*branch taken*/ timing_bt = 7-3; /*branch taken*/
timing_bnt = 3; /*branch not 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; break;
case CPU_386DX: case CPU_386DX:
@ -538,6 +581,25 @@ void cpu_set()
timing_mml = 6; /*memory dest - memory src*/ timing_mml = 6; /*memory dest - memory src*/
timing_bt = 7-3; /*branch taken*/ timing_bt = 7-3; /*branch taken*/
timing_bnt = 3; /*branch not 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; break;
case CPU_486SLC: case CPU_486SLC:
@ -550,6 +612,26 @@ void cpu_set()
timing_mml = 7; timing_mml = 7;
timing_bt = 6-1; /*branch taken*/ timing_bt = 6-1; /*branch taken*/
timing_bnt = 1; /*branch not 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; break;
case CPU_486DLC: case CPU_486DLC:
@ -562,6 +644,26 @@ void cpu_set()
timing_mml = 3; timing_mml = 3;
timing_bt = 6-1; /*branch taken*/ timing_bt = 6-1; /*branch taken*/
timing_bnt = 1; /*branch not 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; break;
case CPU_i486SX: case CPU_i486SX:
@ -575,6 +677,25 @@ void cpu_set()
timing_mml = 3; timing_mml = 3;
timing_bt = 3-1; /*branch taken*/ timing_bt = 3-1; /*branch taken*/
timing_bnt = 1; /*branch not 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; break;
case CPU_Am486SX: case CPU_Am486SX:
@ -589,6 +710,25 @@ void cpu_set()
timing_mml = 3; timing_mml = 3;
timing_bt = 3-1; /*branch taken*/ timing_bt = 3-1; /*branch taken*/
timing_bnt = 1; /*branch not 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; break;
case CPU_Cx486S: case CPU_Cx486S:
@ -602,6 +742,25 @@ void cpu_set()
timing_mml = 3; timing_mml = 3;
timing_bt = 4-1; /*branch taken*/ timing_bt = 4-1; /*branch taken*/
timing_bnt = 1; /*branch not 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; break;
case CPU_Cx5x86: case CPU_Cx5x86:
@ -614,6 +773,25 @@ void cpu_set()
timing_mml = 2; timing_mml = 2;
timing_bt = 5-1; /*branch taken*/ timing_bt = 5-1; /*branch taken*/
timing_bnt = 1; /*branch not 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; break;
case CPU_WINCHIP: case CPU_WINCHIP:
@ -632,6 +810,25 @@ void cpu_set()
cpu_hasMMX = cpu_hasMSR = 1; cpu_hasMMX = cpu_hasMSR = 1;
cpu_hasCR4 = 1; cpu_hasCR4 = 1;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; 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; break;
case CPU_PENTIUM: case CPU_PENTIUM:
@ -645,6 +842,25 @@ void cpu_set()
timing_mml = 3; timing_mml = 3;
timing_bt = 0; /*branch taken*/ timing_bt = 0; /*branch taken*/
timing_bnt = 2; /*branch not 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; cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0; cpu_hasMMX = 0;
@ -665,6 +881,25 @@ void cpu_set()
timing_mml = 3; timing_mml = 3;
timing_bt = 0; /*branch taken*/ timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not 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; cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1; cpu_hasMMX = 1;

View file

@ -38,6 +38,11 @@ extern int timing_rm, timing_rml;
extern int timing_mm, timing_mml; extern int timing_mm, timing_mml;
extern int timing_bt, timing_bnt; 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 typedef struct

View file

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

View file

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

View file

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

View file

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