Hi All!
It seems I found out what was going wrong with the timers. As soon as you
store a number in TIM64T, it *IMMEDIATLY* decrements it! So, in the
following code:
lda #3
sta TIM64T
lda INTIM
after the last instruction, accumulator value is 2, not 3 as it "should"
be! From the Z26 trace log:
( 0 1 0 -68) ( 97 97 96 96 96) nvbdiZc 00 00 00 ff f000: a9
03 lda #03
( 0 1 2 -62) ( 97 97 96 96 96) nvbdizc 03 00 00 ff f002: 8d 96 02
sta TIM64T
( 0 1 6 -50) ( 97 97 96 96 96) nvbdizc 03 00 00 ff f005: ad 84 02
lda INTIM
( 0 1 10 -38) ( 97 97 96 96 96) nvbdizc 02 00 00 ff f008: 4c 00 f0
jmp f000
The column after "nvbdiZc" in each line shows the accumulator content right
before executing the line's instruction, or, in other words, right after
the execution of the previous instruction. And, in our example, it shows
accumulator going from 0 to 3 to 2, even if we had just started the timer.
And why it acts this way?
I have a theory. From the Bibl... oops, Stella Programmers Guide:
"The PIA decrements the value or count loaded into it once each interval
until it reaches 0. It holds that 0 counts for one interval, then the counter
flips to FF(HEX) and decrements once each clock cycle, rather than once per
interval."
This way we have a full interval at 0, and *we must wait for it*. So, when
we set the timer to 3, it immediatly decrements from 3 to 2, then it wait
64 cycles, go to 1, wait more 64, goes to zero, and then waits 64 cycles
before flipping to FF.
If we use a BNE to test if the time is over, as we usually do, it would be
triggered somewhere in the beggining of the last interval, and thus a lot
less then 3*64 cycles would have passed! (actually, would have passed at
most 2*64 + 4 or 5)
To fix this problem, one can do one of the following:
- Simply add +1 to the desired timer. So, if your math says you must wait
43 intervals (typical VBlank timer), go for 43+1 = 44
- Change the comparison from BNE to BPL. Then the wait loop will go on
until timer goes from 0 to FF (-1). This way you will fully wait the last
interval, and only stop when timer goes negative. I guess this is the
"natural way", the way the timers were designed to be used (I dont think
you were supposed to add +1 just for Stella decrement it as soon as the
timer starts)
The only problem with this method is that you cant use the timer with a
value higher then 128, because BPL would think it is a negative value, and
timer loop would end in the first test.
This said, ive found something in the "Stella Programmers Guide" that, if
its not wrong, its at least misleading:
"For example, if the value of 100 were written to TIM64T (HEX address 296)
the timer would decrement to 0 in 6400 clocks (64 clocks per interval x 100
intervals)"
Nope... actually it would decrement to 0 in 99*64=6336 clocks. In 6400
clocks it would decrement *from* 0 to FF.
And also,
"The timer may be read any number of times after it is loaded of course,
but the programmer is usually interested in whether or not the timer has
reached 0."
Actually, he is usually interested when it reaches FF, not 0.
All of this were tested only with the TIM64T Timer, but it should hold true
for the olher timers as well. Actually, its hard to test with such small
timers as TIM8T, as the management loop (lda INTIM / BNE) would waste
almost a full interval...
Btw... was this a known behaviour of the timers? If so, sorry for bothering
you... I Tried to search the Stella archives, but find nothing about it...
and guess the Stella guide is really misleading... so i guess its worth to
post such a huge email with this "add +1 or change to BPL when using
timers" hint ;)
Thats all folks..
Cya,
Rodrigo
PS: now my template works frawlessly! :)
----------------------------------------------------------------------------------------------
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/