qbasicking:
You might like to try this, as you have a choice of several machines, whereas I've only got one. It is pretty accurate on my machine when run under DOS.
The first section, the test, counts the number of loops in one tick of the LSB of the Bios register (the Do routine starts when the reg changes, to get max accuracy). This takes 1/18.26 of a sec. From that the number of loops for 1 millisec is calculated. Min/Max gives the spread of loops.
Enter a multiplier for 'time'.
The second section loops for 'time' loops, with TIMER measuring time taken for the routine.
The dummy lines are to ensure that both DO-LOOP routines are the same length.
CLS
DEF SEG = &H40
min& = 1000000 : max& = 0 'initialise min/max
DO
IF INKEY$<>"" THEN END 'getout if using .exe version
'------- start of machine test ------
n = 0 : a% = PEEK(&H6C)
'/start when reg changes
DO : b% = PEEK(&H6C) : LOOP UNTIL a% <> b%
DO
n = n + 1
IF b > n THEN EXIT DO 'dummy line
a% = PEEK(&H6C)
IF a% <> b% THEN EXIT DO
LOOP
'----- end of machine test --------
IF n > max& THEN max& = n
IF n < min& THEN min& = n
PRINT "Peeks: ";a%;b%;: PRINT TAB(40); "Loops: ";n
PRINT "Min/Max: ";mni&;max&;
PRINT TAB(40);USING "###.##";(max& - min&)/min& * 100;
PRINT "% spread"
sec = n * 18.26 'loops per second
ms = sec/1000 'per ms
time = 1000 * ms 'for 1 sec delay
'----- start of delay routine ------
b% = 1 : c% = 1 'dummies
n = 0 : t1! = TIMER
DO
n = n + 1
IF n > time THEN EXIT DO 'active line
a% = PEEK(&H6C) 'dummy line
IF b% <> c% THEN EXIT DO 'dummy line
LOOP
'------ end of delay routine -------
t2! = TIMER
PRINT "Timers: ";t1!;t2!

RINT TAB(40);t2! - t1!;"secs"
PRINT
LOOP
END
I believe the Bios timer is advanced with a hardware interrupt, so it should never be wrong. So I think the spreads are due to possible delays in qbasic reading the regs to get TIMER. If that is the case, then this method should give the same results on any machine.
I would be intersted in your findings.