There is often a real time wrapping counter available.
The ticks counter on the Pentium (RDTSC instruction), or micro second counters on the Orange pi one plus (offset $9100 in the virtual io
space) Raspberry pi 1 (offset $3000) and most famously the timers on
The IBM pc available from the 80's to my AMD EUFI machine on I/O
addresses $40 ..$43.
If the counter wrap on e.g. 16 bits and you are on e.g. a 64 bit
system, you have to shift the count left 48 bits to get a proper
wrapping counter.
Such a counter makes it possible to wait until a certain wall
clock time by polling, but there is a pit-fall.
This is an example of old code.
On the pc the timer wraps each 1/16 seconds, e.g.
1.198180 divided by 16.
: INITIALISE-TIMER ( -- )
$34 $43 PC! \ set time mode 2, read/write channel 0
$00 $40 PC!
$00 $40 PC!
;
\ * WRONG *
\ old code. MICROTICKS gives a double on a 16 bit code.
\ Wait +n * 100 microseconds
\ /MS compares the time with the time of this call plus wait time.
: /MS ( +n -- )
TIMERFREQUENCY ROT 10000 M*/
MICROTICKS D+
BEGIN
2DUP MICROTICKS DU< \ D< change into DU<
UNTIL
2DROP
;
This code is *wrong*. Neither signed or unsigned comparison will
do the trick!
The correct code is this.
\ ***************************************************8
\ Compare TIME1 and TIME2 (ticks).
\ Return "time1 IS earlier".
\ This is tricky: the - is an unsigned subtracting actually.
\ The result is interpreted as signed!
: EARLIER? - 0< ;
\ ***************************************************8
This is maximally accurate. It gives a lee way of half the
wrapping period. On a 4 GHz pentium with a 32 Forth that
means half a second. tmanx (a musics program) encounters
notes that last longer, so it is not something to be
ignored.
Groetjes Albert
--
"in our communism country Viet Nam, people are forced to be
alive and in the western country like US, people are free to
die from Covid 19 lol" duc ha
albert &=n http://home.hccnet.nl/a.w.m.van.der.horst
Op zaterdag 17 december 2022 om 14:09:28 UTC+1 schreef none albert:
There is often a real time wrapping counter available.
The ticks counter on the Pentium (RDTSC instruction), or micro second
counters on the Orange pi one plus (offset $9100 in the virtual io
space) Raspberry pi 1 (offset $3000) and most famously the timers on
The IBM pc available from the 80's to my AMD EUFI machine on I/O
addresses $40 ..$43.
If the counter wrap on e.g. 16 bits and you are on e.g. a 64 bit
system, you have to shift the count left 48 bits to get a proper
wrapping counter.
Such a counter makes it possible to wait until a certain wall
clock time by polling, but there is a pit-fall.
This is an example of old code.
On the pc the timer wraps each 1/16 seconds, e.g.
1.198180 divided by 16.
: INITIALISE-TIMER ( -- )
$34 $43 PC! \ set time mode 2, read/write channel 0
$00 $40 PC!
$00 $40 PC!
;
\ * WRONG *
\ old code. MICROTICKS gives a double on a 16 bit code.
\ Wait +n * 100 microseconds
\ /MS compares the time with the time of this call plus wait time.
: /MS ( +n -- )
TIMERFREQUENCY ROT 10000 M*/
MICROTICKS D+
BEGIN
2DUP MICROTICKS DU< \ D< change into DU<
UNTIL
2DROP
;
This code is *wrong*. Neither signed or unsigned comparison will
do the trick!
The correct code is this.
\ ***************************************************8
\ Compare TIME1 and TIME2 (ticks).
\ Return "time1 IS earlier".
\ This is tricky: the - is an unsigned subtracting actually.
\ The result is interpreted as signed!
: EARLIER? - 0< ;
\ ***************************************************8
This is maximally accurate. It gives a lee way of half the
wrapping period. On a 4 GHz pentium with a 32 Forth that
means half a second. tmanx (a musics program) encounters
notes that last longer, so it is not something to be
ignored.
Groetjes Albert
--
"in our communism country Viet Nam, people are forced to be
alive and in the western country like US, people are free to
die from Covid 19 lol" duc ha
albert &=n http://home.hccnet.nl/a.w.m.van.der.horst
That made me think about my tElapsed?
Now it has been changed as follows:
: u>d ( n1 -- d1 ) 0 ;
: tElapsed? ( ms-elapsed timer - flag )
2@
if + u>d ms@ u>d d- d>s 0< \ Time elapsed?
else 2drop false \ The timer is off
then ;
\ Test
2variable ttimer
: start-timer ( timer - ) ms@ true rot 2! ;
: test-1second ( - )
ttimer start-timer begin 1000 ttimer tElapsed? until ;
test-1second
d turns a wrapping timer to a non-wrapping timer.
\s Jos
If you're going to count milliseconds with a 64 bit counter,
you need not be worried about wrapping the first few million years
anyhow.
If ever there were a Multitasking Wordset for standard Forth accorded,
words for counting microseconds and to control idle and deep sleep mode
would become lovely candidates for an extended wordset.
none albert schrieb am Montag, 19. Dezember 2022 um 16:40:30 UTC+1:
If you're going to count milliseconds with a 64 bit counter,
you need not be worried about wrapping the first few million years
anyhow.
One would not want a million year running counter without sleep mode.
The costs for all those terawatthours times inflation rate....
If ever there were a Multitasking Wordset for standard Forth accorded,
words for counting microseconds and to control idle and deep sleep mode
would become lovely candidates for an extended wordset.
Just dawdling ... better go back to my hot spiced wine pot ... ;o)
In article <4ec931f9-1b70-4f3b..>,Sorry I missed that condition.
Jos Ven ~> wrote:
Op zaterdag 17 december 2022 om 14:09:28 UTC+1 schreef none albert:
There is often a real time wrapping counter available.
The ticks counter on the Pentium (RDTSC instruction), or micro second
counters on the Orange pi one plus (offset $9100 in the virtual io
space) Raspberry pi 1 (offset $3000) and most famously the timers on
The IBM pc available from the 80's to my AMD EUFI machine on I/O
addresses $40 ..$43.
If the counter wrap on e.g. 16 bits and you are on e.g. a 64 bit
system, you have to shift the count left 48 bits to get a proper
wrapping counter.
Such a counter makes it possible to wait until a certain wall
clock time by polling, but there is a pit-fall.
This is an example of old code.
On the pc the timer wraps each 1/16 seconds, e.g.
1.198180 divided by 16.
: INITIALISE-TIMER ( -- )
$34 $43 PC! \ set time mode 2, read/write channel 0
$00 $40 PC!
$00 $40 PC!
;
\ * WRONG *
\ old code. MICROTICKS gives a double on a 16 bit code.
\ Wait +n * 100 microseconds
\ /MS compares the time with the time of this call plus wait time.
: /MS ( +n -- )
TIMERFREQUENCY ROT 10000 M*/
MICROTICKS D+
BEGIN
2DUP MICROTICKS DU< \ D< change into DU<
UNTIL
2DROP
;
This code is *wrong*. Neither signed or unsigned comparison will
do the trick!
The correct code is this.
\ ***************************************************8
\ Compare TIME1 and TIME2 (ticks).
\ Return "time1 IS earlier".
\ This is tricky: the - is an unsigned subtracting actually.
\ The result is interpreted as signed!
: EARLIER? - 0< ;
\ ***************************************************8
This is maximally accurate. It gives a lee way of half the
wrapping period. On a 4 GHz pentium with a 32 Forth that
means half a second. tmanx (a musics program) encounters
notes that last longer, so it is not something to be
ignored.
Groetjes Albert
--
"in our communism country Viet Nam, people are forced to be
alive and in the western country like US, people are free to
die from Covid 19 lol" duc ha
albert
That made me think about my tElapsed?
Now it has been changed as follows:
: u>d ( n1 -- d1 ) 0 ;
: tElapsed? ( ms-elapsed timer - flag )
2@
if + u>d ms@ u>d d- d>s 0< \ Time elapsed?
else 2drop false \ The timer is off
then ;
\ Test
2variable ttimer
: start-timer ( timer - ) ms@ true rot 2! ;
: test-1second ( - )
ttimer start-timer begin 1000 ttimer tElapsed? until ;
test-1secondPuzzled. The observation I gave works only with wrapping times, that
goes from 0x7FF... to 0x800...
d turns a wrapping timer to a non-wrapping timer.
If you're going to count milliseconds with a 64 bit counter,
you need not be worried about wrapping the first few million years
anyhow.
HEX
0 1 1000 FM/MOD \ period in your ticks i.e. MS
2 / \ wrap around time
60 / 24 / \ in hours
365 / \ in years
.
749784172 OK
\s JosGroetjes Albert
--
"in our communism country Viet Nam, people are forced to be
alive and in the western country like US, people are free to
die from Covid 19 lol" duc ha
albert~=n http://home.hccnet.nl/a.w.m.van.der.horst
Puzzled. The observation I gave works only with wrapping times, that
goes from 0x7FF... to 0x800...
Sorry I missed that condition.
So, I guess the following old version can still be used:
: tElapsed? ( ms-elapsed timer - flag )
2@
if + ms@ < \ Time elapsed?
else 2drop false \ The timer is off
then ;
Also note: tElapsed? is used to detect an action that must take place inside >a loop in a program. In my case the exact time is not very important. >test-1second is just a way to test tElapsed?
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 475 |
Nodes: | 16 (2 / 14) |
Uptime: | 18:19:25 |
Calls: | 9,487 |
Calls today: | 6 |
Files: | 13,617 |
Messages: | 6,121,091 |