64bit TIMER in BASIC


One of our users was asking about the possibility of a 64 bit TIMER and 64 bit integer arithmetic. The need was to time both millisecond and long time - minutes or even hours. The 32 bit TIMER rolls over every 70 minutes or so. The ARM is a 32 processor, so that dictates the 32 bit math. But in BASIC with a little help from assembly can handle 64 bit math.

The 64 bit TIMER is implimented in pure BASIC as follows. You would call this routine in your main loop to keep track of long time constants.

dim __VAR_TIME_L__ as integer
dim __VAR_TIME_H__ as integer

sub time64bit
    dim now

    now = TIMER             ' you should only read it once it could roll over in the middle of this test
    if now >= 0  and __VAR_TIME_L__ < 0 then __VAR_TIME_H__ += 1
    __VAR_TIME_L__ = now

end sub

And here is a add64bit routine which you call with 2 64bit numbers and the result is saved in a global ACCUMATE value. There is 1 assembly language instruction to branch on carry set, which occurs overflowing from &HFFFF---- to &H0000----. The BCC jumps over 6 bytes, 2 for the BCS and 4 for the GOTO. Note that within the scope of a SUB the labels are local. The actual ARM BCSinstruction adds 2 to the PC, encoded as a 1 offset as the PC relative is 4 bytes ahead of the instruction. Those adjustments are handled by the ASMinlineBASIC.bas pre-processor file.

#include <ASMinlineBASIC.bas>

dim __ACCUMULATE_H__ as integer
dim __ACCUMULATE_L__ as integer

sub add64bit (val_a_h, val_a_l, val_b_h, val_b_l)
    __ACCUMULATE_L__ = val_a_l + val_b_l

    ASM_BCS (6)
    goto NO_CARRY

    __ACCUMULATE_H__ = val_a_h + val_b_h + 1
    return

  NO_CARRY:
    __ACCUMULATE_H__ = val_a_h + val_b_h

end sub

And to measure elapsed time, you need a 64bit subtract, shown below


sub subtract64bit (val_a_h, val_a_l, val_b_h, val_b_l)
    __ACCUMULATE_L__ = val_a_l - val_b_l

    ASM_BCC (6)
    goto NO_CARRY

    __ACCUMULATE_H__ = val_a_h - val_b_h - 1
    return

  NO_CARRY:
    __ACCUMULATE_H__ = val_a_h - val_b_h

end sub

I have a test program running on the timer, it handles the 32 bit rollover every 70 minutes or so, but to check the 64 bit rollover will happen in 285 thousand years. Sitting by my computer waiting for that. :)

For the full test here is the source. Where I first tested the arithmetic operations and then the timer.

And if you need a 64 bit comparison--

' this compare64bit returns 0 for equal, 1 for a>b, or -1 for a<b

function compare64bit (val_a_h, val_a_l, val_b_h, val_b_l)
    subtract64bit (val_a_h, val_a_l, val_b_h, val_b_l)

    if __ACCUMULATE_H__ = 0
        if __ACCUMULATE_L__ = 0 then return 0 else return 1
    endif
    if __ACCUMULATE_H__ < 0 then return -1 else return 1

end function

Previous Next