\ Real Time Clock vandys
\ Requires Pentium rdtsc instruction
only drivers definitions
code rdtsc ( -- du ) $0F c, $31 c, \ rdtsc -> eax, edx
eax push edx push next c;
$70 constant IO_RTC
$00 constant RTC_SEC
$0A constant RTC_STATUSA
$80 constant RTCSA_TUP
create tsc1sec 0 , 0 , create tsc1msec 0 ,
: (rtcin) ( port -- u ) IO_RTC outb $84 inb drop IO_RTC 1+ inb
$84 inb drop ;
: (wait_tup) ( -- ) begin RTC_STATUSA (rtcin) RTCSA_TUP and 0= until ;
: (wait_sec) ( sec -- sec' ) begin (wait_tup) RTC_SEC (rtcin)
2dup - if nip exit then drop again ;
: calc_tscfreq ( -- ) (wait_tup) RTC_SEC (rtcin)
(wait_sec) rdtsc dnegate rot (wait_sec) drop rdtsc d+
2dup tsc1sec 2! 1000 um/mod tsc1msec ! drop ;
only
Put this all in "drivers"
Quick and dirty rdtsc access
I/O port base for controlling RTC
RTC seconds counter
RTC status register A
Status: time updating, don't look
Calculated number of CPU ticks per second, and millisecond
NB: 1sec is a 64-bit count, 1msec only 32-bits
: (rtcin) Play nicely with the HW, pull in an RTC register
: (wait_tup) Wait for the timer to be out of an update window
: (wait_sec) Wait for the second counter to bump from the passed one
to something else... generally the next second
: calc_tscfreq Watch our RTC to get a one second interval, record
the delta in the rdtsc CPU cycle counter to get (approximately) the
number of CPU ticks per second, and millisecond