From 3a401af84e95480d9e79bd23fa6f5b009b474eb7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 May 2020 01:36:52 +0200 Subject: [PATCH] Changes to update_tsc() - no longer requires a parameter and advances by all the currently accumulated cycles. Also changed TSC-related delta's to be correctly uint64_t. --- src/cpu_common/386_dynarec.c | 31 ++++++++++++++++++++++++------- src/cpu_common/cpu.h | 2 +- src/io.c | 6 +++--- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/cpu_common/386_dynarec.c b/src/cpu_common/386_dynarec.c index f341efab9..af004521a 100644 --- a/src/cpu_common/386_dynarec.c +++ b/src/cpu_common/386_dynarec.c @@ -273,13 +273,28 @@ static void prefetch_flush() #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC -static int cycles_main = 0; +static int cycles_main = 0, cycles_old = 0; +static uint64_t tsc_old = 0; -void update_tsc(int cycs) +void update_tsc(void) { - if (cycs > 0) { - tsc += cycs; + int cycdiff; + uint64_t delta; + cycdiff = cycles_old - cycles; + delta = tsc - tsc_old; + if (delta > 0) { + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; + if (cycdiff > 0) + tsc += cycdiff; + } else { + /* TSC has not changed. */ + tsc += cycdiff; + } + + if (cycdiff > 0) { if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) timer_process(); } @@ -291,9 +306,9 @@ void exec386_dynarec(int cycs) uint32_t addr; int tempi; int cycdiff; - int oldcyc, oldtsc; + int oldcyc; int oldcyc2; - int delta; + uint64_t oldtsc, delta; uint32_t start_pc = 0; int cyc_period = cycs / 2000; /*5us*/ @@ -317,7 +332,9 @@ void exec386_dynarec(int cycs) cycdiff=0; #endif oldcyc = oldcyc2 = cycles; + cycles_old = cycles; oldtsc = tsc; + tsc_old = tsc; if (!CACHE_ON()) /*Interpret block*/ { cpu_block_end = 0; @@ -723,7 +740,7 @@ void exec386_dynarec(int cycs) /* TSC has not changed. */ tsc += cycdiff; } - + if (cpu_state.abrt) { flags_rebuild(); diff --git a/src/cpu_common/cpu.h b/src/cpu_common/cpu.h index 9129a7ab0..3a7d67d78 100644 --- a/src/cpu_common/cpu.h +++ b/src/cpu_common/cpu.h @@ -565,7 +565,7 @@ extern int cpu_effective, cpu_alt_reset; extern void cpu_dynamic_switch(int new_cpu); extern void cpu_ven_reset(void); -extern void update_tsc(int cycs); +extern void update_tsc(void); extern int sysenter(uint32_t fetchdat); extern int sysexit(uint32_t fetchdat); diff --git a/src/io.c b/src/io.c index 89d341f76..fe356cfbf 100644 --- a/src/io.c +++ b/src/io.c @@ -331,7 +331,7 @@ outb(uint16_t port, uint8_t val) if (!found) { sub_cycles(io_delay); if (cpu_use_dynarec && (port == 0xeb)) - update_tsc(io_delay); + update_tsc(); } io_log("(%i, %i, %04i) outb(%04X, %02X)\n", in_smm, found, qfound, port, val); @@ -424,7 +424,7 @@ outw(uint16_t port, uint16_t val) if (!found) { sub_cycles(io_delay); if (cpu_use_dynarec && (port == 0xeb)) - update_tsc(io_delay); + update_tsc(); } io_log("(%i, %i, %04i) outw(%04X, %04X)\n", in_smm, found, qfound, port, val); @@ -551,7 +551,7 @@ outl(uint16_t port, uint32_t val) if (!found) { sub_cycles(io_delay); if (cpu_use_dynarec && (port == 0xeb)) - update_tsc(io_delay); + update_tsc(); } io_log("(%i, %i, %04i) outl(%04X, %08X)\n", in_smm, found, qfound, port, val);