• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

_Microseconds bug in Mini vMac?


Well-known member
I shared this with gryphel but posting here in case anyone @cheesestraws has seen it or can find something wrong with my very simple code blow:

In short, the _Microseconds trap, when called repeatedly in a tight loop in Mini vMac (tested on multiple modern machines) seems to start repeating values very quickly (much too fast to be due to the long int rolling over).

The sample code below falls into the SysError() call after several seconds, every time.

My Mini vMac variation options are as follows. I'm running at 16x.
-br 36 -t mc64 -m II -vres 450 -fullscreen 1 -magnify 1 -drives 8 -speed 4 -dct 5 -kyt 3 -kyr 1

I hope this is user error on my part somehow - _Microseconds is really useful!

// _Microseconds puts the high 32 bits in A0 and the low 32 bits in D0.  THINK C
// returns long function results in D0, so just declaring it this way (in a non-'pascal'
// function) gets us the low 32 bits in the return value as desired (and if needed,
// caller can still grab the high part in A0 from an asm block):

#define _Microseconds 0xA193
long Microseconds(void) = { _Microseconds };

void main(void)
    long previous = 0;

    while (!Button())
        // calling Microseconds in a tight loop seems to get the emulator
        // permanently in a state where Microseconds returns values that bounce
        // around in a tight range and never exceed some nearby value, breaking anything
        // trying to run a microsecond timer.  For the record, rollover of the
        // unsigned long is not the issue, this happens way before that's possible
        // (and also if I just use regular longs).  In particular it seems that the
        // high world gets permanently stuck; the low word is different every time.
        // Once I get into this state, ANY subsequent call to Microseconds (including
        // from NOT in a "tight loop") continues to return these rangebound values.
        // I tested this running Mini vMac at 16x, emulating a Mac II,
        // compiling with THINK C 6.
        // If I add some QuickDraw or DebugStr() calls into the loop below, this
        // stops happening, presumably because the loop is no longer too "tight"?

        const long x = Microseconds();

        if (x < 0)
            // avoid worrying about microseconds rolling over, breaking compare below
            DebugStr("\pmicroseconds signed long has rolled over");
        else if (x < previous)
            Str255 s1, s2;
            NumToString(previous, s1);
            NumToString(x, s2);
            DebugStr("\p**** Microseconds went backward:  from ____ to ____");
            SysError(2000);  // should never get here -- but we do!
        previous = x;


Well-known member
Sorry! Just remembered I was going to reply to this, though I can't say much useful.

I've not come across this myself, but I haven't really used _Microseconds in Mini vMac, either.

Does this correlate in any way to tick changes? That would be my immediate thought, but that's total speculation.

Not sure how useful sending it over to gryphel will be, Paul C. Pratt seems to have disappeared off the 'net :-|. Hopefully he's OK...


Well-known member
Oh gosh I hadn’t known that but now see the related e-maculation thread. That’s very concerning.


Well-known member
Just for the heck of it, try reading the tick count from the memory location ($16A) where the vertical retrace manager keeps it. Do you have the same bouncing around problem?


Well-known member
No already tried that - the Ticks lomem global is fine (if not it would be a much worse issue, since anything using _TickCount would be screwy), the issue is somewhere in the VIA emulation I expect.