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

RE: [colorforth] precision delay


For longer delays in the ms ranges, I use an interrupt routine based on the
timer that usually runs at a 55ms interval.  I reinitialize it to run at
1ms, use that to decrement a variable number of counters, and then call the
original timer routine every 55th time through.  If a counter is non-0, then
it gets decremented, else it is left alone.  This way a high level word can
load the number of ms it wants to delay and then just waits for the counter
to go to 0.  This works great in a multitasking environment. The next to
last counter counts 1000ms and the increments the last counter to keep track
of seconds for even longer delays. This was done in F83 and here are the
screens.

Scr # 1         timer.blk
  0 \ timer load screen                                   24aug01sat
  1
  2 variable 1ms-counters   10 allot     ( 6 counters )
  3
  4 1ms-counters     constant ms-delay
  5 1ms-counters 4 + constant recv-timer
  6 1ms-counters 8 + constant seconds
  7
  8
  9   2  4 thru
 10
 11
 12
 13
 14
 15
 ok
ll
Scr # 2         timer.blk
  0 \ timer interrupt                                     11may88sat
  1
  2 code new-timer
  3   ax push  bx push  cx push   4 # cx mov
  4   1ms-counters  2- #  bx mov
  5   begin  bx inc  bx inc  cs: 0 [bx] ax  mov  ax ax or  0<>
  6          if ax dec   cs: ax 0 [bx] mov  then
  7   loop  drop
  8   ax ax or  0= if cs: 1000 # 0 [bx] mov
  9     bx inc  bx inc  cs: 0 [bx] inc  else  bx inc  bx inc  then
 10   bx inc  bx inc   cs: 0 [bx] ax mov  ax dec   cs: ax 0 [bx] mov
 11      0= if  cs: 55 #  0 [bx] mov   96 int
 12         else  hex 20 # al mov  20 # al out  then
 13    cx pop  bx pop  ax pop  iret  end-code
 14 decimal
 15
Scr # 3         timer.blk
  0 \                                                     16aug88sat
  1 hex
  2 code di  cli next  end-code
  3 code ei  sti next  end-code
  4 code cs@   cs ax mov  1push  end-code
  5
  6 : 8253-1ms
  7    36 43 pc!   a9 40 pc!   4 40 pc!  ; ( 1193 divisor )
  8
  9 : time-init
 10    di
 11    0 20 x@  0 180 x!    0 22 x@  0 182 x!
 12    cs@ 0 22 x! [ ' new-timer 2+ ] literal 0 20 x!
 13  [ decimal ]   55  1ms-counters 10 + !
 14    8253-1ms  ei ;
 15
 ok
ll
Scr # 4         timer.blk
  0 \                                                     06apr94sat
  1 hex
  2
  3 : 8253-55ms
  4    36 43 pc!   0 40 pc!  0 40 pc!  ; ( 65535 divisor )
  5
  6 : time-restore
  7    di
  8    0 180 x@  0 20 x!
  9    0 182 x@  0 22 x!
 10    8253-55ms ei  ;
 11
 12 0 20 x@  0 180 x!   0 22 x@  0 182 x!
 13 : bye   time-restore [ dos ] 0 4C bdos ;
 14
 15 decimal

This is more complex than what would be needed in colorforth since we don't
have to worry about keeping the system clock current and we don't have to
restore anything when we exit.

Steve Taylor


Mark Slicker <maslicke@xxxxxxxxxxx> said:
> Hello,
>    I was wondering if anyone has had the need for a precision delay
> yet in colorForth? My own use in my graphics initialization requires a
> greater than or equal to 200 microsecond delay, and also a 100 millisecond
> delay. I noticed in Linux they use a udelay routine quite frequently
> throughout the kernel. The code for this is quite elaborate, they use one
> of two different methods based on cpu detection. Does anyone have a better
> way? Otherwise I will probably just use a simplified method based on a
> calibrated time stamp counter (TSC) which available on my CPU.
>
> Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: colorforth-unsubscribe@xxxxxxxxxxxxxxxxxx
List problems, e-mail:  list-admin@xxxxxxxxxxxxxxxxxx
Main web site:  http://www.colorforth.com


---------------------------------------------------------------------
To unsubscribe, e-mail: colorforth-unsubscribe@xxxxxxxxxxxxxxxxxx
List problems, e-mail:  list-admin@xxxxxxxxxxxxxxxxxx
Main web site:  http://www.colorforth.com