home .. forth .. colorforth mail list archive ..

Re: [colorforth] Hello - and where to begin?


Quoting "Ray St. Marie" <ray.stmarie@xxxxxxxxx>:
> On Sun, Mar 9, 2008 at 1:14 AM, Ray St. Marie
> <ray.stmarie@xxxxxxxxx> wrote:
> 
> I'd like to learn to use the system timer and if
> anyone would care to
> enlighten me... please?
> 
> Ray
> 

Nick here: Dear Ray, 

Thanks for your interest, below are further details; 
rather long, but might be suitable for one of John
Drake's tutorials.

Caritas,

NickM

***************************

Timing and Music - Tutorial  

Howerd Oakford's CFDOS4 has three blocks which
illustrate 
the use of PC timers.  You can make a boot floppy from
DOS 
by following the instructions on Howerd's website; or  
just copy his bootable image cfdos4.blk with Linux,  
   dd   if=cfdos4.blk   of=/dev/fd0 

The PC has 3 timers.  The newest and fastest is the 64
bit 
RDTSC (Time Stamp Counter) which ticks at CPU rate, ns,

and loads the time, in clock ticks, onto EAX lo  &  EDX
hi.  
CF has a macro word "time" which calls RDTSC, with lo 32
 
bits on stack, EAX.  The first thing Howerd does is to
bring  
this macro word "time" into his forth dictionary, block
20, 

forth   : time  time ;    --u

I find it useful to stack the higher 32 bits as well. 
This can
be called by the the forth word "a", which stacks EDX. 
So my version of "time" is "clk", 

( still in forth)    : clk  time  a ;    --ulo uhi  

Block 28 uses the fast 64 bit PC timer to make delays in

msec "ms" and "secs".  Howard uses the PC's second timer

for calibration.  Real Time Clock (RTC) at port 70h,
ticks 
hi and lo every second.   Howerd defines a variable 
"khz" 
to store the number of PC CPU ticks in one sec, divided
by 
1000 to bring it to ms.  (I find "1ms" a useful memnonic
for 
"khz").  The word "cal" ought to put your CPU's clock
rate 
into the variable "khz".   

 : cal   hi lo time invert  ( howerd's word to change
sign) 
          hi lo  time   +      ( time diff, no of clks
in 1 sec) 
          1000 /   khz !   ;    ( ditto, in 1 msec)  

But if the CPU is faster than 1GHz,  a one sec
calibration 
period will be too long, because the lower 32 bit
register 
of the RDTS counter will overflow.  Hence I call the
higher 
32 bit register as well, and scale the 2 numbers
appropriately 
before adding them to make a 32 bit time scale.

: clk   time 10 shr   a 31 and 22 shl   + ;   --u (
hi+lo, scaled)

: cal   clk invert   clk +   1000 /   khz !   ;  

Having calibrated his time interval (for length of a
note) 
Howerd then uses the PC's 3rd timer to set the
frequency.    
The Programmable Interrupt Timers (PIT) tick microsec. 
See Mark Feldman's tutorial "Controlling the PC speaker"
  
on the popular Australian website, "JollySWAGman"

 http://www.bsdg.org/SWAG/SOUND/0107.PAS.html

The PC speaker is tied to the NMI status port 61h. 
There 
are caveats about writing to some other bits (see Intel
doc 
ICH7) but, essentially, bit 0 will activate the speaker
and 
bit 1 will tie it to the pulses from PIT 2.  This timer
is 
selected by writing a byte to port 43, and its
oscillatory 
half-period is entered as hibyte lobyte--  to port 42h. 
  
Therefor Howerd introduces the macro word "swapbytes" 
and defines a forth word to "split" 16bits into 2 bytes,

before moving on to make music. 

Block 68 is straightforward, and rather neat.  It save a
bit 
of repetitive naming by use of the CF facility where one
word 
can elide into its successor if its   ";"   is omited.

 : tn   ( this is the note length t, scaled to msec) 

 : hz  ( this is the PIT rate 1,193,000 ticks per sec,
divided 
           by the freq in Hz - actually, this is the
pulse period) 

 : tone  ( the period is split and written to PIT2,
which sets 
              up oscillation freq; PIT2 output is tied
to speaker 
              by writing a 3 to port 61, then it is
untied - after   
              t msec - by replacing the 3 with a 1; this
silences  
              the tone, plus 20 ms delay before next
tone)  ;  


*************************

---------------------------------------------------------------------
To unsubscribe, e-mail: colorforth-unsubscribe@xxxxxxxxxxxxxxxxxx
For additional commands, e-mail: colorforth-help@xxxxxxxxxxxxxxxxxx
Main web page - http://www.colorforth.com