diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 8b9a999..c602ffc 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -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(); } diff --git a/src/codegen_timing_486.c b/src/codegen_timing_486.c index 7647e6d..160c16c 100644 --- a/src/codegen_timing_486.c +++ b/src/codegen_timing_486.c @@ -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] = diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index b8662dc..436f385 100644 --- a/src/codegen_timing_pentium.c +++ b/src/codegen_timing_pentium.c @@ -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] = diff --git a/src/cpu.c b/src/cpu.c index b3bcce6..ab1d2a3 100644 --- a/src/cpu.c +++ b/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; diff --git a/src/cpu.h b/src/cpu.h index 6215c03..8492d3c 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -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 diff --git a/src/x86_ops_call.h b/src/x86_ops_call.h index 24fb06a..70103dd 100644 --- a/src/x86_ops_call.h +++ b/src/x86_ops_call.h @@ -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; diff --git a/src/x86_ops_jump.h b/src/x86_ops_jump.h index cf66872..a26283d 100644 --- a/src/x86_ops_jump.h +++ b/src/x86_ops_jump.h @@ -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; } diff --git a/src/x86_ops_ret.h b/src/x86_ops_ret.h index 71fd4f4..42ebdc5 100644 --- a/src/x86_ops_ret.h +++ b/src/x86_ops_ret.h @@ -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; diff --git a/src/x86seg.c b/src/x86seg.c index 8f7ac01..5b3ff70 100644 --- a/src/x86seg.c +++ b/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