Atmel ATmega168 VGA
First I did VGA with an FPGA, then with the SX Microcontroller, and now with an Atmel ATmega168. This differs from the SX version in that I used interrupts to control the timing. Also, since this chip is 20MHz instead of 50MHz, some of the timings are not quite accurate. Seems to work fine although there is some jitter starting halfway down the screen. Could be fixable. 20MHz is pretty much a bad clock rate for VGA 640x480@60Hz since each pixel clock should be 1 tick of a 25MHz clock. A single scan line now is 800pixels*(20MHz/25MHz) which comes out at an even 640, which is good, but the hsync which should start after 8 25MHz clocks and stop after completing 96 25MHz clocks, come out to non-round numbers (6.4 and 76.8 respectively). Still seemed to work, although like I said, there is some jitter which since this is just a useless proof of concept, I don't feel like working on it any more to fix it :).
So how it works: Basically I took all the timings of the FPGA project I did and multipied them by (20/25) to get the timings for a 20MHz clock. I set up 2 interrupts. The first is using the timer compare A, I set it for 640 clocks (equal to 800 25MHz pixel clocks). This gives me pretty nice timing of when a scan line is finished. At this point the timer also resets to 0 again. I then set up interrupts an interrupt at 7 cycles using the timer's compare B. At this point I turn on the hsync pin and do some calculations on my vertical scan since I have about 76 cycles here to play with. I also tell it that compare B is now 84 clocks and change the 16 bit Z register (r30 and r31 combined) so the next ijmp instruction will jump to a different routine. The next routine is the hsync off routine which turns off the hsync, does some more vertical scan calculations and gets ready to draw the playfield. I set the Z register to point to the playfield routine and set compare B to something higher than 122 (playfield starts at 122, but I start drawing a little later to center stuff). The playfield routine draws one scan line. The scan line information is pulled out of flash which is inserted into the source code from an include file that is generated from the Python script included in the zipfile below. When the scan line is done it changes the interrupt information for timer compare B back to 7 cycles and points again to hsync on. Kinda looks like a linked list of interrupt handlers.
Copyright 1997-2013 - Michael Kohn