This commit is contained in:
OBattler
2024-06-22 18:30:30 +02:00
3 changed files with 38 additions and 6 deletions

View File

@@ -40,6 +40,7 @@
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/gdbstub.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
@@ -3492,7 +3493,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
@@ -3568,7 +3569,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */
case 0xc1:
@@ -3664,7 +3665,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x00000010:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Array Access Register */
case 0x00000082:
@@ -3834,7 +3835,7 @@ amd_k_invalid_wrmsr:
/* Time Stamp Counter */
case 0x00000010:
case 0x80000010:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x00000011:
@@ -3919,7 +3920,7 @@ pentium_invalid_wrmsr:
msr.tr5 = EAX & 0x008f0f3b;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
@@ -3952,7 +3953,7 @@ pentium_invalid_wrmsr:
break;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Unknown */
case 0x18:

View File

@@ -185,6 +185,9 @@ timer_set_p(pc_timer_t *timer, void *priv)
extern void timer_stop(pc_timer_t *timer);
extern void timer_on_auto(pc_timer_t *timer, double period);
/* Change TSC, taking into account the timers. */
extern void timer_set_new_tsc(uint64_t new_tsc);
#ifdef __cplusplus
}
#endif

View File

@@ -253,3 +253,31 @@ timer_on_auto(pc_timer_t *timer, double period)
else
timer_stop(timer);
}
void
timer_set_new_tsc(uint64_t new_tsc)
{
pc_timer_t *timer = NULL;
/* Run timers already expired. */
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
if (!timer_head) {
tsc = new_tsc;
return;
}
timer = timer_head;
timer_target = new_tsc + (int32_t)(timer_get_ts_int(timer_head) - (uint32_t)tsc);
while (timer) {
int32_t offset_from_current_tsc = (int32_t)(timer_get_ts_int(timer) - (uint32_t)tsc);
timer->ts.ts32.integer = new_tsc + offset_from_current_tsc;
timer = timer->next;
}
tsc = new_tsc;
}