## RE: [stella] Math riddle : Loading TIM64T with 43 burns only 36scanlines (not 37)

 Subject: RE: [stella] Math riddle : Loading TIM64T with 43 burns only 36scanlines (not 37) From: Chris Wilkson Date: Mon, 10 May 2004 18:34:33 -0400 (EDT)
```Grrr....I *knew* there was something funny about the RIOT timers
in the 2600.  Here it is...

(BTW, Erik you were right on how it works.  Here's why.)

The timer is in fact decremented immediately.  But that's not what causes
the confusion.  Your code checks to see if the timer is zero and branches
as soon as this happens.  But remember that the RIOT's timer ends at the
*end* of the zero count, not the beginning.

In the real world, i.e. one with interrupts, this is how the RIOT works:
(assume we're using the mythical TIM3T...for space reasons)

I write 3 to the TIM3T timer:

_   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _
clock _| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_|
_
write _________| |_______________________________________________________
___________ ___________ ___________ ___________ ___ ___ ___ ___ ___
count _____0_____|_____2_____|_____1_____|_____0_____|255|254|253|252|251
_________________
interrupt _____________________________________________|

Notice some things....the count is immediately decremented as Erik said
before.  But the RIOT doesn't actually tell the world that it's done
timing until the *end* of the zero count, when it sets the interrupt flag.
(the flag stays high until the timer is read)  When the interrupt flag goes
high, the count is decremented on *every* clock cycle until it reaches
zero.  It then stays at zero.

Of course in the 2600, there are no interrupts.  So you have to check when
the count is 255.  But you'll probably miss it.  (you might read when it's
as low as 251 because of the loop delay)  So you should read if it's negative
or positive or add one to the value you store and read if it's zero as Erik
suggests.

The preferred method would be to store the actual delay you want and do a BPL
to read the sign of the count.  Then you're still using the timer the way it
was meant to be used, but you're just ignoring the interrupt flag.  This will
work for any count value less than or equal to 127.  This gives you a delay
that's only 4 cycles short of 107 scanlines.  I can't imagine why you would
want to delay more for video.  For logic, you can use TIM1024T for longer
delays.

Thanks Erik for jogging my memory on this one...

-Chris

On Mon, 10 May 2004, Erik Mooney wrote:

> Christian Bogey <khryssun@xxxxxxxx> wrote:
>
> > Using the following code burns only 36 scanlines
> > instead of 37 (?!?) :
> >
> >     LDA  #43
> >     STA  TIM64T
> >
> > Wait_VBLANK_End
> >     LDA INTIM
> >     BNE Wait_VBLANK_End
> >     STA WSYNC
> >
> > But I don't understand why !!! indeed :
> > - Storing 43 into TIM64T burns 43*64 = 2752 cycles
>
> Not exactly.  Based on a quick test in PCAEWin's debugger, when you
> store 43 into TIM64T, it *immediately* decrements to 42, then waits
> 64 cycles before decrementing to 41, 40, and so on. Storing 43 to TIM64T
> actually makes INTTIM reach 0 at 1+42*64 = 2689 cycles later, or only
> 35.38 scanlines later.
>
> Either store 44 instead of 43 to TIM64T (which is how the sample code
> from Nick Bensema's original "How To Draw A Playfield" does it, although
> make it wait an extra 64 cycles until the 0 in INTTIM decrements to \$FF.)
>
> (At least I believe this is the answer, although I could be wrong. :) )
> ----------------------------------------------------------------------------------------------
> Archives (includes files) at http://www.biglist.com/lists/stella/archives/
> Unsub & more at http://www.biglist.com/lists/stella/
>
>

----------------------------------------------------------------------------------------------
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/

```