From 0cbc0cbe3941c49ef6ea113b576bdd5ad2b26674 Mon Sep 17 00:00:00 2001 From: jensadne Date: Tue, 2 Sep 2008 20:47:32 +0000 Subject: [PATCH] eh, ja --- TIKI-100_emul-src/messaudio/attotime.h | 226 +++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 TIKI-100_emul-src/messaudio/attotime.h diff --git a/TIKI-100_emul-src/messaudio/attotime.h b/TIKI-100_emul-src/messaudio/attotime.h new file mode 100644 index 0000000..6d94e7c --- /dev/null +++ b/TIKI-100_emul-src/messaudio/attotime.h @@ -0,0 +1,226 @@ +/*************************************************************************** + + attotime.h + + Support functions for working with attotime data. + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**************************************************************************** + + Attotime is an attosecond-accurate timing system implemented as + 96-bit integers. + + 1 second = 1e0 seconds + 1 millisecond = 1e-3 seconds + 1 microsecond = 1e-6 seconds + 1 nanosecond = 1e-9 seconds + 1 picosecond = 1e-12 seconds + 1 femtosecond = 1e-15 seconds + 1 attosecond = 1e-18 seconds + + This may seem insanely accurate, but it has its uses when multiple + clocks in the system are run by independent crystals. It is also + useful to compute the attotime for something small, say 1 clock tick, + and still have it be accurate and useful for scaling. + + Attotime consists of a 32-bit seconds count and a 64-bit attoseconds + count. Because the lower bits are kept as attoseconds and not as a + full 64-bit value, there is headroom to make some operations simpler. + +***************************************************************************/ + +#pragma once + +#ifndef __ATTOTIME_H__ +#define __ATTOTIME_H__ + +#include "mamecore.h" +#include + + +/*************************************************************************** + CONSTANTS +***************************************************************************/ + +#define ATTOSECONDS_PER_SECOND_SQRT ((attoseconds_t)1000000000) +#define ATTOSECONDS_PER_SECOND (ATTOSECONDS_PER_SECOND_SQRT * ATTOSECONDS_PER_SECOND_SQRT) +#define ATTOSECONDS_PER_MILLISECOND (ATTOSECONDS_PER_SECOND / 1000) +#define ATTOSECONDS_PER_MICROSECOND (ATTOSECONDS_PER_SECOND / 1000000) +#define ATTOSECONDS_PER_NANOSECOND (ATTOSECONDS_PER_SECOND / 1000000000) + +#define ATTOTIME_MAX_SECONDS ((seconds_t)1000000000) + + + +/*************************************************************************** + MACROS +***************************************************************************/ + +/* convert between a double and attoseconds */ +#define ATTOSECONDS_TO_DOUBLE(x) ((double)(x) * 1e-18) +#define DOUBLE_TO_ATTOSECONDS(x) ((attoseconds_t)((x) * 1e18)) + +/* convert between hertz (as a double) and attoseconds */ +#define ATTOSECONDS_TO_HZ(x) ((double)ATTOSECONDS_PER_SECOND / (double)(x)) +#define HZ_TO_ATTOSECONDS(x) ((attoseconds_t)(ATTOSECONDS_PER_SECOND / (x))) + +/* macros for converting other seconds types to attoseconds */ +#define ATTOSECONDS_IN_SEC(x) ((attoseconds_t)(x) * ATTOSECONDS_PER_SECOND) +#define ATTOSECONDS_IN_MSEC(x) ((attoseconds_t)(x) * ATTOSECONDS_PER_MILLISECOND) +#define ATTOSECONDS_IN_USEC(x) ((attoseconds_t)(x) * ATTOSECONDS_PER_MICROSECOND) +#define ATTOSECONDS_IN_NSEC(x) ((attoseconds_t)(x) * ATTOSECONDS_PER_NANOSECOND) + +/* macros for building attotimes from other types at runtime */ +#define ATTOTIME_IN_HZ(hz) attotime_make((0), (HZ_TO_ATTOSECONDS(hz))) +#define ATTOTIME_IN_SEC(s) attotime_make(((s) / 1), ((s) % 1)) +#define ATTOTIME_IN_MSEC(ms) attotime_make(((ms) / 1000), (ATTOSECONDS_IN_MSEC((ms) % 1000))) +#define ATTOTIME_IN_USEC(us) attotime_make(((us) / 1000000), (ATTOSECONDS_IN_USEC((us) % 1000000))) +#define ATTOTIME_IN_NSEC(ns) attotime_make(((ns) / 1000000000), (ATTOSECONDS_IN_NSEC((ns) % 1000000000))) + +/* macros for building attotimes from other types at compile time */ +#define STATIC_ATTOTIME_IN_HZ(hz) { (0), (HZ_TO_ATTOSECONDS(hz)) } +#define STATIC_ATTOTIME_IN_SEC(s) { ((s) / 1), ((s) % 1) } +#define STATIC_ATTOTIME_IN_MSEC(ms) { ((ms) / 1000), (ATTOSECONDS_IN_MSEC((ms) % 1000)) } +#define STATIC_ATTOTIME_IN_USEC(us) { ((us) / 1000000), (ATTOSECONDS_IN_USEC((us) % 1000000)) } +#define STATIC_ATTOTIME_IN_NSEC(ns) { ((ns) / 1000000000), (ATTOSECONDS_IN_NSEC((ns) % 1000000000)) } + +/* macros for building a reduced-resolution attotime for tokenized storage in a UINT64 */ +/* this form supports up to 1000 seconds and sacrifices 1/1000 of the full attotime resolution */ +#define UINT64_ATTOTIME_IN_HZ(hz) ((UINT64)((ATTOSECONDS_PER_SECOND / 1000) / (hz))) +#define UINT64_ATTOTIME_IN_SEC(s) ((UINT64)(s) * (ATTOSECONDS_PER_SECOND / 1000)) +#define UINT64_ATTOTIME_IN_MSEC(ms) ((UINT64)(ms) * (ATTOSECONDS_PER_SECOND / 1000 / 1000)) +#define UINT64_ATTOTIME_IN_USEC(us) ((UINT64)(us) * (ATTOSECONDS_PER_SECOND / 1000 / 1000 / 1000)) +#define UINT64_ATTOTIME_IN_NSEC(ns) ((UINT64)(ns) * (ATTOSECONDS_PER_SECOND / 1000 / 1000 / 1000 / 1000)) + +/* macros for converting a UINT64 attotime to a full attotime */ +#define UINT64_ATTOTIME_TO_ATTOTIME(v) attotime_make((v) / (ATTOSECONDS_PER_SECOND / 1000), ((v) % (ATTOSECONDS_PER_SECOND / 1000)) * 1000) + + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +/* core components of the attotime structure */ +typedef INT64 attoseconds_t; +typedef INT32 seconds_t; + + +/* the attotime structure itself */ +typedef struct _attotime attotime; +struct _attotime +{ + seconds_t seconds; + attoseconds_t attoseconds; +}; + + + +/*************************************************************************** + GLOBAL VARIABLES +***************************************************************************/ + +/* constant times for zero and never */ +extern const attotime attotime_zero; +extern const attotime attotime_never; + + + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +/* ----- conversion helpers ----- */ + +/* convert an attotime to attoseconds, clamping to maximum positive/negative values */ +attoseconds_t attotime_to_attoseconds(attotime _time); + + +/* ----- core math functions ----- */ + +/* add two attotimes */ +attotime attotime_add(attotime _time1, attotime _time2); + +/* add attoseconds to an attotime */ +attotime attotime_add_attoseconds(attotime _time1, attoseconds_t _attoseconds); + +/* subtract two attotimes */ +attotime attotime_sub(attotime _time1, attotime _time2); + +/* subtract attoseconds from an attotime */ +attotime attotime_sub_attoseconds(attotime _time1, attoseconds_t _attoseconds); + +/* multiply an attotime by a constant */ +attotime attotime_mul(attotime _time1, UINT32 factor); + +/* divide an attotime by a constant */ +attotime attotime_div(attotime _time1, UINT32 factor); + +/* compare two attotimes */ +int attotime_compare(attotime _time1, attotime _time2); + +/* return the minimum of two attotimes */ +attotime attotime_min(attotime _time1, attotime _time2); + +/* return the maximum of two attotimes */ +attotime attotime_max(attotime _time1, attotime _time2); + + +/* ----- misc utilities ----- */ + +/* return a temporary printable string describing an attotime */ +const char *attotime_string(attotime _time, int precision); + + + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +/*------------------------------------------------- + attotime_make - assemble an attotime from + seconds and attoseconds components +-------------------------------------------------*/ + +INLINE attotime attotime_make(seconds_t _secs, attoseconds_t _subsecs) +{ + attotime result; + result.seconds = _secs; + result.attoseconds = _subsecs; + return result; +} + + +/*------------------------------------------------- + attotime_to_double - convert from attotime + to double +-------------------------------------------------*/ + +INLINE double attotime_to_double(attotime _time) +{ + return (double)_time.seconds + ATTOSECONDS_TO_DOUBLE(_time.attoseconds); +} + + +/*------------------------------------------------- + double_to_attotime - convert from double to + attotime +-------------------------------------------------*/ + +INLINE attotime double_to_attotime(double _time) +{ + attotime result; + + /* set seconds to the integral part */ + result.seconds = floor(_time); + + /* set attoseconds to the fractional part */ + _time -= (double)result.seconds; + result.attoseconds = DOUBLE_TO_ATTOSECONDS(_time); + return result; +} + + +#endif /* __ATTOTIME_H__ */