From: https://forums.atariage.com/topic/133686-please-explain-riot-timmers/#comment-1617207 NOTE about timer initial state from (https://forums.atariage.com/topic/256802-two-questions-about-the-pia/): - the increment seem to be always set to 1024T (unless you just played a game and swap it with the testrom leaving the console unpowered for a very short time) - the actual timer value is random - the interrupt flag is also random The documentation for the 6532 "RIOT" chip calls it the "interrupt flag register." The VCS.H file calls it "TIMINT" (for "timer interrupt"). It's located at address $5 of the RIOT chip. On the Atari 2600, the RIOT chip addresses begin at address $280, so that means the TIMINT register is at address $285 (and its many mirrors). This register holds two RIOT interrupt flags-- the timer interrupt flag (bit 7) and the PA7 edge-detect interrupt flag (bit 6). These flags will trigger IRQ interrupts, but they have no "real" effect on an Atari 2600, because the Atari 2600 uses a 6507 CPU, and the 6507 chip doesn't have an IRQ line, therefore the Atari 2600 doesn't have IRQ interrupts. I don't know if the PA7 edge-detect interrupt flag has any significance for Atari 2600 programming, so I won't try to explain it. But the timer interrupt flag can be used to tell if the timer has counted down past 0. Whenever you set the interval timer by writing a value to TIM1T, TIM8T, TIM64T, or T1024T, the timer interrupt flag will be cleared automatically. The timer then counts down to 0, starting from the value you've set it to. The first decrement occurs right after you set the timer (i.e., 1 cycle later), but the subsequent decrements occur at the interval you've selected (i.e., after every 1 cycle, 8 cycles, 64 cycles, or 1024 cycles). When the timer reaches 0, it will stay 0 for the indicated interval, and will then wrap around to 255. The moment it wraps around from 0 to 255, the timer interrupt flag will be set. Once the timer has wrapped around and the timer interrupt flag has been set, the timer will decrement every 1 cycle. Whenever you read the timer or the timer interrupt flag, the timer interrupt flag will be cleared. However, the flag will *not* be cleared if you read it (or the timer) at the same moment that the flag is set. Anyway, let's suppose you write a value of 5 to TIM8T, which will cause the timer to count down from 5 to 0 at an interval of 8 cycles. The timer and the timer interrupt flag will contain the following values: Instruction: | Cycle: | Timer: | Flag: -------------|------------|--------------|------------- LDA #5 | 00, 01 | ???, ??? | ???, ??? STA TIM8T | 02, ... 05 | ???, ... 005 | ???, ... 000 | 06, ... 13 | 004, ... 004 | 000, ... 000 | 14, ... 21 | 003, ... 003 | 000, ... 000 | 22, ... 29 | 002, ... 002 | 000, ... 000 | 30, ... 37 | 001, ... 001 | 000, ... 000 | 38, ... 45 | 000, ... 000 | 000, ... 000 | 46 | 255 | 128 | 47 | 254 | 128 | 48 | 253 | 128 | etc. | etc. | etc. In other words, "LDA #5" takes 2 cycles, and we don't know what the timer or the flag are set to. "STA TIM8T" takes 4 cycles. On the last cycle of that instruction, the timer will be set to 5, and the flag will be cleared. On the very next cycle, the timer will decrement from 5 to 4, but the flag will still be 0. The timer will stay at 4 for 8 cycles, then it will decrement to 3 and stay at 3 for 8 cycles, etc. When the timer reaches 0, it will stay at 0 for 8 cycles. Then the timer will decrement from 0 to 255, and the flag will be set. The timer flag is bit 7, so it has a value of 128. The timer will continue decrementing, but it will decrement once each cycle, rather than every 8 cycles as before. One way to check when the timer has finished counting down is to read the timer (or INTIM), which tells us what value is in the timer at that moment. We could then test the value of the timer to see if it's equal to 0, not equal to 0, plus/positive (0 to 127), or minus/negative (128 to 255). But that method can present problems, depending on what value we set the timer to, and how we're testing its value. For example, if you set the timer to 255, and then test whether its value is minus, then it will be minus right away. Or if you set the timer to 64, and then test whether its value is plus, then it will be plus right away. A more generic test would be to see if its 0 yet-- but that would mean you aren't waiting until it's counted *past* 0. Another way to check when the timer has finished counting down is to read the timer flag (or TIMINT). As long as TIMINT is still 0, the timer hasn't finished counting down yet. But if TIMINT is 128, then the timer has finished counting down. If you aren't worried about the PA7 edge-detect interrupt flag (bit 6 of TIMINT), then you can just use "not equal 0." So let's say you want to wait for 20 scan lines before doing something. A scan line is 76 cycles long, so 20 scan lines would be 1520 cycles. Dividing that by 64, we get 23.75. So we could do the following: LDA #23 STA TIM64T ; do some stuff here, then start checking the timer flag LOOP LDA TIMINT BEQ LOOP; this will keep looping as long as the flag isn't set yet STA WSYNC; finish off the scan line so we resume at the beginning of a scan line ; now we've waited 20 scan lines Note that it takes time to set the timer, and it takes time to read the timer, so that needs to be factored into the amount of time we set the timer for. You might need to adjust the number you set the timer to in order to get the desired result. For example, we might need to use "LDA #22" instead of "LDA #23."