I have always wanted to make some sort of computer game that is controlled by an embedded device. I plan to go about this by first making a reliable VGA output for an Atmega 644p. As I will only be making a simple game I have decided a colour bit depth of 3-bit will be enough (RGB).
This is a ruffly based on lucid sciences vga generator. After trying out lucid sciences project I decided that a full rewrite of the code was in order to make it easier to understand and to increase flexibility. It was also required so that I could reduce the bit depth of the output. The requirements of the VGA output are as follows:
- Double buffered.
- As many pixels as possible.
- Does not require any additional hardware.
With these strict requirements a couple clever ideas had to be thought up. The image will have to be saved onto the onboard ram. There is only 4K of ram on a 644p. Therefore for a double buffered image I have less than 4K bytes available. The microcontroller is running at 20MHz and can output 480 * 512 in theory. In practise code takes time and to load data from ram it takes 3 cycles (ld ;2,out ;1). This takes output down to 160*170. As this is 27,200 pixels at 3 bit a pixel this is 10.2K bytes sadly too many and not double buffered and this assumes we can get to all the bits. Since we have only 3 bits and ram is accessed by the byte we could place 8 pixels in 3 bytes. To access this we could use the following code.
ld r19,X+ ;2 out RGBPORT,r19 ;1 lsr r19 ;1 lsr r19 ;1 lsr r19 ;1 ld r17,X ;2 lsl r17 ;1 out RGBPORT,r19 ;1 lsr r19 ;1 lsr r19 ;1 lsr r19 ;1 lsl r17 ;1 and r17,r19 ;1 nop ;1 out RGBPORT,r17 ;1 ld r17,X+ ;2 lsr r17 ;1 ld r19,X ;2 nop ;1 out RGBPORT,r17 ;1 lsr r17 ;1 lsr r17 ;1 lsr r17 ;1 lsl r19 ;1 nop ;1 nop ;1 out RGBPORT,r17 ;1 lsr r17 ;1 lsr r17 ;1 lsr r17 ;1 and r19,r17 ;1 nop ;1 nop ;1 out RGBPORT,r19 ;1 ld r19,X+ ;2 lsr r19 ;1 lsr r19 ;1 nop ;1 nop ;1 out RGBPORT,r19 ;1 lsr r19 ;1 lsr r19 ;1 lsr r19 ;1 nop ;1 nop ;1 nop ;1 out RGBPORT,r19
As can be seen the code takes 7 cycles for each pixel but manages to achieve the goal of storing 8 pixels in 3 bytes. At 7 cycles a pixel this gives an estimated resolution of 68*73 = 4,964 pixels. At 8 pixels per 3 bytes this is 1,860 bytes. This is under the 4K of the ram and therefore can be used (Remember it is double buffered so actually uses 3,720 bytes).