~ubuntu-branches/ubuntu/raring/mame/raring-proposed

« back to all changes in this revision

Viewing changes to mess/src/emu/attotime.h

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
    attotime.h
4
 
 
5
 
    Support functions for working with attotime data.
6
 
 
7
 
****************************************************************************
8
 
 
9
 
    Copyright Aaron Giles
10
 
    All rights reserved.
11
 
 
12
 
    Redistribution and use in source and binary forms, with or without
13
 
    modification, are permitted provided that the following conditions are
14
 
    met:
15
 
 
16
 
        * Redistributions of source code must retain the above copyright
17
 
          notice, this list of conditions and the following disclaimer.
18
 
        * Redistributions in binary form must reproduce the above copyright
19
 
          notice, this list of conditions and the following disclaimer in
20
 
          the documentation and/or other materials provided with the
21
 
          distribution.
22
 
        * Neither the name 'MAME' nor the names of its contributors may be
23
 
          used to endorse or promote products derived from this software
24
 
          without specific prior written permission.
25
 
 
26
 
    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
27
 
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
 
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
 
    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
30
 
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31
 
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
 
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33
 
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34
 
    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35
 
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
 
    POSSIBILITY OF SUCH DAMAGE.
37
 
 
38
 
****************************************************************************
39
 
 
40
 
    Attotime is an attosecond-accurate timing system implemented as
41
 
    96-bit integers.
42
 
 
43
 
        1 second      = 1e0 seconds
44
 
        1 millisecond = 1e-3 seconds
45
 
        1 microsecond = 1e-6 seconds
46
 
        1 nanosecond  = 1e-9 seconds
47
 
        1 picosecond  = 1e-12 seconds
48
 
        1 femtosecond = 1e-15 seconds
49
 
        1 attosecond  = 1e-18 seconds
50
 
 
51
 
    This may seem insanely accurate, but it has its uses when multiple
52
 
    clocks in the system are run by independent crystals. It is also
53
 
    useful to compute the attotime for something small, say 1 clock tick,
54
 
    and still have it be accurate and useful for scaling.
55
 
 
56
 
    Attotime consists of a 32-bit seconds count and a 64-bit attoseconds
57
 
    count. Because the lower bits are kept as attoseconds and not as a
58
 
    full 64-bit value, there is headroom to make some operations simpler.
59
 
 
60
 
***************************************************************************/
61
 
 
62
 
#pragma once
63
 
 
64
 
#ifndef __ATTOTIME_H__
65
 
#define __ATTOTIME_H__
66
 
 
67
 
#include <math.h>
68
 
#undef min
69
 
#undef max
70
 
 
71
 
 
72
 
 
73
 
//**************************************************************************
74
 
//  CONSTANTS
75
 
//**************************************************************************
76
 
 
77
 
// core components of the attotime structure
78
 
typedef INT64 attoseconds_t;
79
 
typedef INT32 seconds_t;
80
 
 
81
 
// core definitions
82
 
const attoseconds_t ATTOSECONDS_PER_SECOND_SQRT = 1000000000;
83
 
const attoseconds_t ATTOSECONDS_PER_SECOND = ATTOSECONDS_PER_SECOND_SQRT * ATTOSECONDS_PER_SECOND_SQRT;
84
 
const attoseconds_t ATTOSECONDS_PER_MILLISECOND = ATTOSECONDS_PER_SECOND / 1000;
85
 
const attoseconds_t ATTOSECONDS_PER_MICROSECOND = ATTOSECONDS_PER_SECOND / 1000000;
86
 
const attoseconds_t ATTOSECONDS_PER_NANOSECOND = ATTOSECONDS_PER_SECOND / 1000000000;
87
 
 
88
 
const seconds_t ATTOTIME_MAX_SECONDS = 1000000000;
89
 
 
90
 
 
91
 
 
92
 
//**************************************************************************
93
 
//  MACROS
94
 
//**************************************************************************
95
 
 
96
 
// convert between a double and attoseconds
97
 
#define ATTOSECONDS_TO_DOUBLE(x)                ((double)(x) * 1e-18)
98
 
#define DOUBLE_TO_ATTOSECONDS(x)                ((attoseconds_t)((x) * 1e18))
99
 
 
100
 
// convert between hertz (as a double) and attoseconds
101
 
#define ATTOSECONDS_TO_HZ(x)                    ((double)ATTOSECONDS_PER_SECOND / (double)(x))
102
 
#define HZ_TO_ATTOSECONDS(x)                    ((attoseconds_t)(ATTOSECONDS_PER_SECOND / (x)))
103
 
 
104
 
// macros for converting other seconds types to attoseconds
105
 
#define ATTOSECONDS_IN_SEC(x)                   ((attoseconds_t)(x) * ATTOSECONDS_PER_SECOND)
106
 
#define ATTOSECONDS_IN_MSEC(x)                  ((attoseconds_t)(x) * ATTOSECONDS_PER_MILLISECOND)
107
 
#define ATTOSECONDS_IN_USEC(x)                  ((attoseconds_t)(x) * ATTOSECONDS_PER_MICROSECOND)
108
 
#define ATTOSECONDS_IN_NSEC(x)                  ((attoseconds_t)(x) * ATTOSECONDS_PER_NANOSECOND)
109
 
 
110
 
 
111
 
 
112
 
//**************************************************************************
113
 
//  TYPE DEFINITIONS
114
 
//***************************************************************************/
115
 
 
116
 
// the attotime structure itself
117
 
class attotime
118
 
{
119
 
public:
120
 
        // construction/destruction
121
 
        attotime()
122
 
                : seconds(0),
123
 
                  attoseconds(0) { }
124
 
 
125
 
        attotime(seconds_t secs, attoseconds_t attos)
126
 
                : seconds(secs),
127
 
                  attoseconds(attos) { }
128
 
 
129
 
        // queries
130
 
        bool is_zero() const { return (seconds == 0 && attoseconds == 0); }
131
 
        bool is_never() const { return (seconds >= ATTOTIME_MAX_SECONDS); }
132
 
 
133
 
        // conversion to other forms
134
 
        double as_double() const { return double(seconds) + ATTOSECONDS_TO_DOUBLE(attoseconds); }
135
 
        attoseconds_t as_attoseconds() const;
136
 
        UINT64 as_ticks(UINT32 frequency) const;
137
 
        const char *as_string(int precision = 9) const;
138
 
 
139
 
        // conversion from other forms
140
 
        static attotime from_double(double _time);
141
 
        static attotime from_ticks(UINT64 ticks, UINT32 frequency);
142
 
        static attotime from_seconds(INT32 seconds) { return attotime(seconds, 0); }
143
 
        static attotime from_msec(INT64 msec) { return attotime(msec / 1000, (msec % 1000) * (ATTOSECONDS_PER_SECOND / 1000)); }
144
 
        static attotime from_usec(INT64 usec) { return attotime(usec / 1000000, (usec % 1000000) * (ATTOSECONDS_PER_SECOND / 1000000)); }
145
 
        static attotime from_nsec(INT64 nsec) { return attotime(nsec / 1000000000, (nsec % 1000000000) * (ATTOSECONDS_PER_SECOND / 1000000000)); }
146
 
        static attotime from_hz(double frequency) { return attotime(0, double(ATTOSECONDS_PER_SECOND) / frequency); }
147
 
 
148
 
        // math
149
 
        attotime &operator+=(const attotime &right);
150
 
        attotime &operator-=(const attotime &right);
151
 
        attotime &operator*=(UINT32 factor);
152
 
        attotime &operator/=(UINT32 factor);
153
 
 
154
 
        // members
155
 
        seconds_t               seconds;
156
 
        attoseconds_t   attoseconds;
157
 
 
158
 
        // constants
159
 
        static const attotime never;
160
 
        static const attotime zero;
161
 
};
162
 
 
163
 
 
164
 
 
165
 
//**************************************************************************
166
 
//  INLINE FUNCTIONS
167
 
//**************************************************************************
168
 
 
169
 
//-------------------------------------------------
170
 
//  operator+ - handle addition between two
171
 
//  attotimes
172
 
//-------------------------------------------------
173
 
 
174
 
inline attotime operator+(const attotime &left, const attotime &right)
175
 
{
176
 
        attotime result;
177
 
 
178
 
        // if one of the items is never, return never
179
 
        if (left.seconds >= ATTOTIME_MAX_SECONDS || right.seconds >= ATTOTIME_MAX_SECONDS)
180
 
                return attotime::never;
181
 
 
182
 
        // add the seconds and attoseconds
183
 
        result.attoseconds = left.attoseconds + right.attoseconds;
184
 
        result.seconds = left.seconds + right.seconds;
185
 
 
186
 
        // normalize and return
187
 
        if (result.attoseconds >= ATTOSECONDS_PER_SECOND)
188
 
        {
189
 
                result.attoseconds -= ATTOSECONDS_PER_SECOND;
190
 
                result.seconds++;
191
 
        }
192
 
 
193
 
        // overflow
194
 
        if (result.seconds >= ATTOTIME_MAX_SECONDS)
195
 
                return attotime::never;
196
 
        return result;
197
 
}
198
 
 
199
 
inline attotime &attotime::operator+=(const attotime &right)
200
 
{
201
 
        // if one of the items is never, return never
202
 
        if (this->seconds >= ATTOTIME_MAX_SECONDS || right.seconds >= ATTOTIME_MAX_SECONDS)
203
 
                return *this = never;
204
 
 
205
 
        // add the seconds and attoseconds
206
 
        attoseconds += right.attoseconds;
207
 
        seconds += right.seconds;
208
 
 
209
 
        // normalize and return
210
 
        if (this->attoseconds >= ATTOSECONDS_PER_SECOND)
211
 
        {
212
 
                this->attoseconds -= ATTOSECONDS_PER_SECOND;
213
 
                this->seconds++;
214
 
        }
215
 
 
216
 
        // overflow
217
 
        if (this->seconds >= ATTOTIME_MAX_SECONDS)
218
 
                return *this = never;
219
 
        return *this;
220
 
}
221
 
 
222
 
 
223
 
//-------------------------------------------------
224
 
//  operator- - handle subtraction between two
225
 
//  attotimes
226
 
//-------------------------------------------------
227
 
 
228
 
inline attotime operator-(const attotime &left, const attotime &right)
229
 
{
230
 
        attotime result;
231
 
 
232
 
        // if time1 is never, return never
233
 
        if (left.seconds >= ATTOTIME_MAX_SECONDS)
234
 
                return attotime::never;
235
 
 
236
 
        // add the seconds and attoseconds
237
 
        result.attoseconds = left.attoseconds - right.attoseconds;
238
 
        result.seconds = left.seconds - right.seconds;
239
 
 
240
 
        // normalize and return
241
 
        if (result.attoseconds < 0)
242
 
        {
243
 
                result.attoseconds += ATTOSECONDS_PER_SECOND;
244
 
                result.seconds--;
245
 
        }
246
 
        return result;
247
 
}
248
 
 
249
 
inline attotime &attotime::operator-=(const attotime &right)
250
 
{
251
 
        // if time1 is never, return never
252
 
        if (this->seconds >= ATTOTIME_MAX_SECONDS)
253
 
                return *this = never;
254
 
 
255
 
        // add the seconds and attoseconds
256
 
        attoseconds -= right.attoseconds;
257
 
        seconds -= right.seconds;
258
 
 
259
 
        // normalize and return
260
 
        if (this->attoseconds < 0)
261
 
        {
262
 
                this->attoseconds += ATTOSECONDS_PER_SECOND;
263
 
                this->seconds--;
264
 
        }
265
 
        return *this;
266
 
}
267
 
 
268
 
 
269
 
//-------------------------------------------------
270
 
//  operator* - handle multiplication/division by
271
 
//  an integral factor; defined in terms of the
272
 
//  assignment operators
273
 
//-------------------------------------------------
274
 
 
275
 
inline attotime operator*(const attotime &left, UINT32 factor)
276
 
{
277
 
        attotime result = left;
278
 
        result *= factor;
279
 
        return result;
280
 
}
281
 
 
282
 
inline attotime operator*(UINT32 factor, const attotime &right)
283
 
{
284
 
        attotime result = right;
285
 
        result *= factor;
286
 
        return result;
287
 
}
288
 
 
289
 
inline attotime operator/(const attotime &left, UINT32 factor)
290
 
{
291
 
        attotime result = left;
292
 
        result /= factor;
293
 
        return result;
294
 
}
295
 
 
296
 
 
297
 
//-------------------------------------------------
298
 
//  operator== - handle comparisons between
299
 
//  attotimes
300
 
//-------------------------------------------------
301
 
 
302
 
inline bool operator==(const attotime &left, const attotime &right)
303
 
{
304
 
        return (left.seconds == right.seconds && left.attoseconds == right.attoseconds);
305
 
}
306
 
 
307
 
inline bool operator!=(const attotime &left, const attotime &right)
308
 
{
309
 
        return (left.seconds != right.seconds || left.attoseconds != right.attoseconds);
310
 
}
311
 
 
312
 
inline bool operator<(const attotime &left, const attotime &right)
313
 
{
314
 
        return (left.seconds < right.seconds || (left.seconds == right.seconds && left.attoseconds < right.attoseconds));
315
 
}
316
 
 
317
 
inline bool operator<=(const attotime &left, const attotime &right)
318
 
{
319
 
        return (left.seconds < right.seconds || (left.seconds == right.seconds && left.attoseconds <= right.attoseconds));
320
 
}
321
 
 
322
 
inline bool operator>(const attotime &left, const attotime &right)
323
 
{
324
 
        return (left.seconds > right.seconds || (left.seconds == right.seconds && left.attoseconds > right.attoseconds));
325
 
}
326
 
 
327
 
inline bool operator>=(const attotime &left, const attotime &right)
328
 
{
329
 
        return (left.seconds > right.seconds || (left.seconds == right.seconds && left.attoseconds >= right.attoseconds));
330
 
}
331
 
 
332
 
 
333
 
//-------------------------------------------------
334
 
//  min - return the minimum of two attotimes
335
 
//-------------------------------------------------
336
 
 
337
 
inline attotime min(const attotime &left, const attotime &right)
338
 
{
339
 
        if (left.seconds > right.seconds)
340
 
                return right;
341
 
        if (left.seconds < right.seconds)
342
 
                return left;
343
 
        if (left.attoseconds > right.attoseconds)
344
 
                return right;
345
 
        return left;
346
 
}
347
 
 
348
 
 
349
 
//-------------------------------------------------
350
 
//  max - return the maximum of two attotimes
351
 
//-------------------------------------------------
352
 
 
353
 
inline attotime max(const attotime &left, const attotime &right)
354
 
{
355
 
        if (left.seconds > right.seconds)
356
 
                return left;
357
 
        if (left.seconds < right.seconds)
358
 
                return right;
359
 
        if (left.attoseconds > right.attoseconds)
360
 
                return left;
361
 
        return right;
362
 
}
363
 
 
364
 
 
365
 
//-------------------------------------------------
366
 
//  as_attoseconds - convert to an attoseconds
367
 
//  value, clamping to +/- 1 second
368
 
//-------------------------------------------------
369
 
 
370
 
inline attoseconds_t attotime::as_attoseconds() const
371
 
{
372
 
        // positive values between 0 and 1 second
373
 
        if (seconds == 0)
374
 
                return attoseconds;
375
 
 
376
 
        // negative values between -1 and 0 seconds
377
 
        else if (seconds == -1)
378
 
                return attoseconds - ATTOSECONDS_PER_SECOND;
379
 
 
380
 
        // out-of-range positive values
381
 
        else if (seconds > 0)
382
 
                return ATTOSECONDS_PER_SECOND;
383
 
 
384
 
        // out-of-range negative values
385
 
        else
386
 
                return -ATTOSECONDS_PER_SECOND;
387
 
}
388
 
 
389
 
 
390
 
//-------------------------------------------------
391
 
//  as_ticks - convert to ticks at the given
392
 
//  frequency
393
 
//-------------------------------------------------
394
 
 
395
 
inline UINT64 attotime::as_ticks(UINT32 frequency) const
396
 
{
397
 
        UINT32 fracticks = (attotime(0, attoseconds) * frequency).seconds;
398
 
        return mulu_32x32(seconds, frequency) + fracticks;
399
 
}
400
 
 
401
 
 
402
 
//-------------------------------------------------
403
 
//  from_ticks - create an attotime from a tick
404
 
//  count at the given frequency
405
 
//-------------------------------------------------
406
 
 
407
 
inline attotime attotime::from_ticks(UINT64 ticks, UINT32 frequency)
408
 
{
409
 
        attoseconds_t attos_per_tick = HZ_TO_ATTOSECONDS(frequency);
410
 
 
411
 
        if (ticks < frequency)
412
 
                return attotime(0, ticks * attos_per_tick);
413
 
 
414
 
        UINT32 remainder;
415
 
        INT32 secs = divu_64x32_rem(ticks, frequency, &remainder);
416
 
        return attotime(secs, (UINT64)remainder * attos_per_tick);
417
 
}
418
 
 
419
 
 
420
 
//-------------------------------------------------
421
 
//  from_double - create an attotime from floating
422
 
//  point count of seconds
423
 
//-------------------------------------------------
424
 
 
425
 
inline attotime attotime::from_double(double _time)
426
 
{
427
 
        seconds_t secs = floor(_time);
428
 
        _time -= double(secs);
429
 
        attoseconds_t attos = DOUBLE_TO_ATTOSECONDS(_time);
430
 
        return attotime(secs, attos);
431
 
}
432
 
 
433
 
 
434
 
#endif  // __ATTOTIME_H__