More accurate timing for INT, IRET, CALL far, RET far and JMP far.
This commit is contained in:
parent
0ad692ad5c
commit
94f33aa873
9 changed files with 290 additions and 43 deletions
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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] =
|
||||
|
|
|
|||
|
|
@ -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
235
src/cpu.c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
16
src/x86seg.c
16
src/x86seg.c
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue