The actual code changes.

This commit is contained in:
OBattler
2026-01-10 02:25:25 +01:00
parent 3ed1ac905b
commit b857e809bf
11 changed files with 156 additions and 128 deletions

View File

@@ -1,6 +1,14 @@
#ifndef _TIMER_H_
#define _TIMER_H_
#ifndef int128_t
#define int128_t __int128
#endif
#ifndef uint128_t
#define uint128_t unsigned __int128
#endif
extern uint64_t tsc;
/* Maximum period, currently 1 second. */
@@ -11,18 +19,6 @@ extern uint64_t tsc;
#define TIMER_SPLIT 2
#define TIMER_ENABLED 1
#pragma pack(push, 1)
typedef struct ts_struct_t {
uint32_t frac;
uint32_t integer;
} ts_struct_t;
#pragma pack(pop)
typedef union ts_t {
uint64_t ts64;
ts_struct_t ts32;
} ts_t;
/*Timers are based on the CPU Time Stamp Counter. Timer timestamps are in a
32:32 fixed point format, with the integer part compared against the TSC. The
fractional part is used when advancing the timestamp to ensure a more accurate
@@ -36,12 +32,8 @@ typedef union ts_t {
to repeat, the callback must call timer_advance_u64(). This is a change from
the old timer API.*/
typedef struct pc_timer_t {
#ifdef USE_PCEM_TIMER
uint32_t ts_integer;
uint64_t ts_integer;
uint32_t ts_frac;
#else
ts_t ts;
#endif
int flags; /* The flags are defined above. */
int in_callback;
double period; /* This is used for large period timers to count
@@ -60,7 +52,7 @@ extern "C" {
/*Timestamp of nearest enabled timer. CPU emulation must call timer_process()
when TSC matches or exceeds this.*/
extern uint32_t timer_target;
extern uint64_t timer_target;
/*Enable timer, without updating timestamp*/
extern void timer_enable(pc_timer_t *timer);
@@ -82,18 +74,33 @@ extern void timer_add(pc_timer_t *timer, void (*callback)(void *priv), void *pri
extern uint64_t TIMER_USEC;
/*True if timer a expires before timer b*/
#define TIMER_LESS_THAN(a, b) ((int64_t) ((a)->ts.ts64 - (b)->ts.ts64) <= 0)
#define TIMER_LESS_THAN(a, b) ((int64_t) ((a)->ts_integer - (b)->ts_integer) <= 0)
/*True if timer a expires before 32 bit integer timestamp b*/
#define TIMER_LESS_THAN_VAL(a, b) ((int32_t) ((a)->ts.ts32.integer - (b)) <= 0)
#define TIMER_LESS_THAN_VAL(a, b) ((int64_t) ((a)->ts_integer - (b)) <= 0)
/*True if 32 bit integer timestamp a expires before 32 bit integer timestamp b*/
#define TIMER_VAL_LESS_THAN_VAL(a, b) ((int32_t) ((a) - (b)) <= 0)
#define TIMER_VAL_LESS_THAN_VAL(a, b) ((int64_t) ((a) - (b)) <= 0)
#ifndef printf
#include <stdio.h>
#endif
/*Advance timer by delay, specified in 32:32 format. This should be used to
resume a recurring timer in a callback routine*/
static __inline void
timer_advance_u64(pc_timer_t *timer, uint64_t delay)
{
timer->ts.ts64 += delay;
uint64_t int_delay = delay >> 32;
uint32_t frac_delay = delay & 0xffffffff;
if (int_delay & 0x0000000080000000ULL) {
printf("timer_advance_u64(): Negative delay: %08X%08X!\n", (uint32_t) (int_delay), frac_delay);
int_delay |= 0xffffffff00000000ULL;
}
if ((frac_delay + timer->ts_frac) < frac_delay)
timer->ts_integer++;
timer->ts_frac += frac_delay;
timer->ts_integer += int_delay;
timer_enable(timer);
}
@@ -103,9 +110,16 @@ timer_advance_u64(pc_timer_t *timer, uint64_t delay)
static __inline void
timer_set_delay_u64(pc_timer_t *timer, uint64_t delay)
{
timer->ts.ts64 = 0ULL;
timer->ts.ts32.integer = tsc;
timer->ts.ts64 += delay;
uint64_t int_delay = delay >> 32;
uint32_t frac_delay = delay & 0xffffffff;
if (int_delay & 0x0000000080000000ULL) {
printf("timer_set_delay_u64(): Negative delay: %08X%08X!\n", (uint32_t) (int_delay), frac_delay);
int_delay |= 0xffffffff00000000ULL;
}
timer->ts_frac = frac_delay;
timer->ts_integer = int_delay + (uint64_t)tsc;
timer_enable(timer);
}
@@ -125,21 +139,19 @@ timer_is_on(pc_timer_t *timer)
}
/*Return integer timestamp of timer*/
static __inline uint32_t
static __inline uint64_t
timer_get_ts_int(pc_timer_t *timer)
{
return timer->ts.ts32.integer;
return timer->ts_integer;
}
/*Return remaining time before timer expires, in us. If the timer has already
expired then return 0*/
static __inline uint32_t
static __inline uint64_t
timer_get_remaining_us(pc_timer_t *timer)
{
int64_t remaining;
if (timer->flags & TIMER_ENABLED) {
remaining = (int64_t) (timer->ts.ts64 - (uint64_t) (tsc << 32));
int128_t remaining = (((uint128_t)timer->ts_integer << 32) | timer->ts_frac) - ((uint128_t)tsc << 32);
if (remaining < 0)
return 0;
@@ -151,13 +163,11 @@ timer_get_remaining_us(pc_timer_t *timer)
/*Return remaining time before timer expires, in 32:32 timestamp format. If the
timer has already expired then return 0*/
static __inline uint64_t
static __inline uint128_t
timer_get_remaining_u64(pc_timer_t *timer)
{
int64_t remaining;
if (timer->flags & TIMER_ENABLED) {
remaining = (int64_t) (timer->ts.ts64 - (uint64_t) (tsc << 32));
int128_t remaining = (((uint128_t)timer->ts_integer << 32) | timer->ts_frac) - ((uint128_t)tsc << 32);
if (remaining < 0)
return 0;