Yes, that 1 cycle out of 500,000 / frame is always enough to cause jitter.
If you are using GCC, you could code your interrupt in ASM and then use the Jitter Fixer code I posted at AVR Freaks. You could even call your render loop from there if you prefer to stay in C.
Here is an example from a VGA video game system I did for an Atmega-328.
The ASM side handles the interrup entry here, including jitter fixer...
Code:
// VIDEO INTERRUPT ENTRY POINT (4)
.global TIMER1_COMPA_vect
TIMER1_COMPA_vect: ;4
// SAVE STATUS REGISTER (5)
push r16 ;2
in r16,SREG ;1
push r16 ;2
// LATENCY EQUALIZER (11)
lds r16,TCNT1L ;2
cpi r16,14 ;1
brlo AVRC_FIX1 ;1/2
AVRC_FIX1:
cpi r16,15 ;1
brlo AVRC_FIX2 ;1/2
AVRC_FIX2:
cpi r16,16 ;1
brlo AVRC_FIX3 ;1/2
AVRC_FIX3:
Instead of rendering the frame here, you could always boot out and just call your C driver instead.
Code:
pop r16 ;2
out SREG,r16 ;1
pop r16 ;2
// RETURN TO MAIN
reti ;4
I based my timing on this one for 640x480 @ 60Hz...
Code:
// [40 MHZ HORIZONTAL TIMING FOR 640 X 480 @ 60 HZ]
// HSP : 0150 FROM 0000 TO 0149 (-)
// HBP : 0074 FROM 0150 TO 0223
// HPX : 1024 FROM 0224 TO 1247
// HFP : 0024 FROM 1248 TO 1271
// TOT : 1272
// [VERTICAL LINE TIMING]
// VLN : 480 FROM 000 TO 479
// VFP : 011 FROM 480 TO 490
// VSP : 002 FROM 491 TO 492 (-)
// VBP : 031 FROM 493 TO 523
// TOT : 524
Here are the timer settings...
Code:
// TIMER 1 VIDEO INTERRUPT @ 1272 CYCLES
ldi r18,9
sts TCCR1B,r18
ldi r18,2
sts TIMSK1,r18
ldi r18,hi8(1271)
sts OCR1AH,r18
ldi r18,lo8(1271)
sts OCR1AL,r18
Being a 328P, it overclocks to 40Mhz (32MHz safe margin), so there is a lot of headroom for graphics!
The 1284P is a better choice for retro BW video though, as it has so much internal SRAM.
Sadly, the 1284 will not run safely beyond 25MHz.
Here is a quick NTSC Timing Calc I made that allows you to try various clock settings...
http://lucidscience.com/temp/ntsc.exeIt also keeps to the burst multiple in case you ever want to do color.
Brad