• Waiting till a specified time.

    From none) (albert@21:1/5 to All on Sat Dec 17 14:09:25 2022
    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@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jos Ven@21:1/5 to All on Mon Dec 19 05:18:30 2022
    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
    \s Jos

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to josv@planet.nl on Mon Dec 19 16:40:27 2022
    In article <4ec931f9-1b70-4f3b-bc18-8c3881d55e6fn@googlegroups.com>,
    Jos Ven <josv@planet.nl> 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 &=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

    Puzzled. 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 Jos

    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@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@arcor.de@21:1/5 to none albert on Mon Dec 19 09:09:26 2022
    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)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to minf...@arcor.de on Mon Dec 19 10:07:15 2022
    On Monday, December 19, 2022 at 6:09:28 PM UTC+1, minf...@arcor.de wrote:
    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.

    Indeed. The transputer could wait on TIME, and there we actually encountered this problem (with 16-bit parts). IIRC, the transputer documentation warned
    for this, possibly there was even a dedicated instruction (Or Occam keyword) for it.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to minf...@arcor.de on Tue Dec 20 10:36:56 2022
    In article <b9116f9d-be1d-4655-a47e-962d437463fbn@googlegroups.com>, minf...@arcor.de <minforth@arcor.de> wrote:
    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)

    tmanx does a polling wait on a counter with 250 nSecond ticks.
    That goes well, because if I see in the queue that the next event is
    more than 15 millisecond away I execute `` 10 MS '' .
    A properly implemented MS on a system like Linux or MS-Windows
    does not do a busy wait.

    Willem Ouwerkerk has deep seep mode under control with his
    MSP noforth. Where it counts: battery operated uP's that go
    on for years. As I understand it deep sleep modes are very specific.


    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@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jos Ven@21:1/5 to All on Tue Dec 20 04:57:44 2022
    Op maandag 19 december 2022 om 16:40:30 UTC+1 schreef none albert:
    In article <4ec931f9-1b70-4f3b..>,
    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-1second
    Puzzled. 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 Jos
    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

    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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to josv@planet.nl on Tue Dec 20 14:38:53 2022
    In article <ba6000c1-7cad-438d-9f40-0da3193e039an@googlegroups.com>,
    Jos Ven <josv@planet.nl> wrote:
    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?

    Correct. You have no problem. The problem is for 32 bits counter
    on a 4 Ghz machine (if you're interested in delays in the order of
    seconds) or for the 16 bits counter in the speaker pc timer that wraps
    more that 10 times per second.

    ms@ is a wrapping timer, I hope.
    I solved the discontinuity going from
    FF...FF to 0 (unsigned) or from 7F.. to 80.. (signed).
    The point is that you cannot escape from the discontinuity as long as
    you insist in comparing with < U< D< UD< .
    : ms@-double ms@ 0 ;
    is an unsigned double timer that wraps in the middle and is no good.

    Postponing the trouble a couple million years is a valid Forth solution.

    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@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)