********************************
* VIDEO PONG (C) Rickard Gune *
********************************

(This text is mostly a copy of the Video Pong page on my homepage:
http://www.rickard.gunee.com/projects)

---- Introduction ----
I have made the game pong using a pic 16F84 running @ 12MHz. The game Pong was
the world's first video game in the early 70's, this is a modern version of it,
made with a little bit less hardware than the original version. In my version,
the video signal is generated in software. The only hardware used for the video
generation is two resistors forming a 2-bit DA converter. Usually the video
signal is generated in video games is created with a dedicated video chips,
reading the image data from a graphics memory. In this project the video signal
is calculated in real-time by the microprocessor as the electron beam sweeps
over the screen.
 

---- How to play the game ----
The first screen is where you select how you want to play by moving the joystick:
DOWN: Human vs. Human (H-H), LEFT: Human vs. Computer (H-C) or RIGHT: Computer vs.
Computer (C-C). Start with FIRE. Unfortunately it is impossible to beat the
computer, since there was not enough room to make the computer beatable. That make
 the computer vs. computer game to play forever until someone reset the game using
the reset switch. You start serving by pressing fire, it is also possible to
change direction and speed of the ball using fire. The player who has the serve
will get points. If the player with the serve miss the ball, then the serve goes
over to the other player. When someone wins a game over picture will show and tell
who won.

---- The software ----
With a processor performing 3MIPS, it is not easy to make a video signal in
software. Each instruction performed takes 1/3 us. Each scan-line on the screen
takes 64us, where 52us are visible, so it gives 52*3=156 visible clock cycles per
line. Maximum resolution that can be obtained is 156 pixels in x-axis if the
software is setting one pixel per clock (using for example only bcf and bsf), this
would not give any game, so to make a ball bounce around more stuff has to be done,
like loops and such. A loop quantifies the time to 3-clock pieces, giving a
resolution of 52 pixels. (One could obtain a kind of 156pixels resolution with one
or two offset nops, but the code to select this would eat to many clock cycles to
do any good). In the pong game each line is treated different if there is a ball on
it or not. If there is no ball on it, then all that has to be done is to show white
color for a couple of clock cycles in the beginning or the end, depending on if the
players are on this line or not. On a line with a ball, white should be shown in the
middle for a couple of clock cycles, the delay before and after these white cycles
are a function of the x position of the ball. The score is shown in the bottom of
the screen, by loading the PORTB with the bitmap for the number and shift it out.
In the main-screen, several letters are shown on each line. It is a little bit harder
task, because the string has to be loaded and character bitmap has to be loaded for
each letter. Doing all that and then showing it on the screen would make it possible
to show only like three letters per line with a lot of spacing between them, which
would be really ugly and useless as well. I solve this by calculating the bytes to
shift out in one scan-line, and showing them the next, making it possible to show 8
chars per line. Unfortunately the characters are only drawn on every second line,
but it is better than no characters at all. The text data is stored in the data
eeprom, and the character bitmaps are stored in program eeprom as retlw tables.

So far I've only talked about the graphic generation. But there is more to it to
get a video signal. All scan-lines first have a 4us-sync pulse, then black for 8us,
then the 52us graphic comes. These horizontalsync-pulses makes the TV understand
when a scan-line starts, but there is needed to send information about when a new
picture starts too, it is called vertical sync, and is a special pattern that tells
the TV that a new image is coming. There are two kinds of vertical sync, because the
image is divided into two part images, showing even and odd lines, to get less
flickering. In pong, the two images are identical, so the game is not using the full
y-resolution possible, but it doesn't matter because it is way better than the
x-resolution anyway, making the x-resolution the biggest problem.

The game stuff, like checking joystick and move stuff around, is taken care of in the
first scan-lines, when no graphics is drawn. The sound is played during some free cycles
close to the horizontal sync pulses, but not on all scan-lines, that's why the sound
sounds very distorted.

Making this kind of software is mostly a clock-cycle-counting project, all timings
are quite critical, so whatever paths the execution-flow of the program takes, it must
take the same number of clock cycles. This is quite hard, and I've not managed to do
this on all lines, so the image is a little bit bent in some places. (Most analog tv-sets
fix this, but on some digital projectors it is more visible)
 

---- The hardware ----
The hardware is quite simple because everything is made in software. Two resistors, forming
a DA converter together with the input impedance of the TV, generate the video signal.
This can generate the levels 0v (sync), 0.3v (black), 0.7v (gray), and 1.0v (white). To be
able to handle the variation of input resistance of different audio equipment, two resistors
are used to make a 1-bit DA to generate the audio. When generating the video, the PORTB is
used as a shift register to get one pixel per instruction when high-resolution text is shown
on the screen. Shifting a port requires the port to be set as output if a whole byte is to be
shifted out. First, this seems like a problem, the whole port can't be used for anything else
than video generation, but that is not quite correct. A port can be used as an input when not
used as a shift register, so in pong PORTB it is used for joystick input when not used as a
shift register. The digital joystick is a switch to ground, so all needed to connect it to the
PIC is a couple of pull up resistors, and that is available inside the PIC. Unfortunately it
is not that simple, if a pin on a port is grounded when used as an output, the output buffer
of the pic would burn up, so this is solved by adding one extra 1k resistor on each pin to
limit the current. What about those pull up resistors? There are 10k pull up resistors built
into the PIC that can be switched on and off. However, using them would be a too strong pull
up, so the 1k current limiting resistor (plus bad switches in the joystick) can't pull the input
low enough. Therefor an external 100k resistor pull up network is added. The power supply part
of the circuit is quite simple, it uses a standard 7805 to get a 5v supply. The input can be
8-18 volt, DC or AC (Thanks to the diode at the power input)

---- Over-clocking a PIC16X84 ----
To get enough processing power to generate the video signal, a little bit higher clock frequency
was needed. The clock frequency should be a multiple of 4Mhz to make it easier to generate the
correct timing. The PIC16X84s are available in a 4MHz version and a 10MHz version, but the 10Mhz
version was quite expensive when I started to make this project, so I tried to over-clock it, and
it worked without problems, well, almost anyway. The 16C84 became unerasable after a while when
over-clocked, but the 16F84 seemed to work without problems, I've had them running for hundreds
of hours without problems. (But I wouldn't recommend you to use a over-clocked PIC in a commercial
project). Some people claims that the 4Mhz and the 10Mhz versions are the same chip with different
text on the package, it would explain why the chip can be over-clocked more than 3 times, but I
don't know. 

 
---- Contens of ZIP-file ----

pong.txt		You're reading it now ! =)
gamefaq.txt		Frequently asked questions about my games.
pong.asm		The pong game main source code (PAL version)
pong.hex		The hex-file to put in a PIC16F84 to get the game up and running.
pongntsc.asm		The pong game main source code (NTSC version)
pongntsc.hex		The hex-file to put in a PIC16F84 to get the game up and running (NTSC version).
pong.jpg		Picture of the game in action.
pong_schematics.png	schematic over the hardware
pong_layout.png		the layout
pong_components.jpg	the component placement


---- Problems ? ----
If you have questions about the games, make sure to check out the video game FAQ (Frequently Asked Questions)
before you ask me. Also have a look at my microcontroller based projects homepage, which is located at
http://www.rickard.gunee.com/projects


---- Legal stuff ---- 

PIC-Pong (C) Rickard Gune. This is open source, use this at your own risk ! You may use the information on
this page for your own projects as long as you refer to the original author (by name and link to authors
homepage), don't do it for profit and don't hurt or harm anyone or anything with it. The author can not be
held responsible for any damage caused by the information on this and related pages.
