20th Aug 2019

Atari's PONG is probably one of the oldest widely known videogame in history. Prior to this, other digital video games existed, but none were so well executed. It was a huge commercial success.

What's more amazing about this game, is that it was designed and created before microcontrollers existed. And therefore everything is made using discrete logic components. This means there was no software, no reprogramming and no easy way to fix the bugs.

It was also made long before the CAD and simulation tools we use today. So everything had to be designed by hand, carefully calculating and testing every step.

I also think this board has great educational value for people learning discrete logic electronics, and that's why I decided to recreate it myself, with a few modifications.

Part 1: Research

Of course I had absolutely no clue on how to even start so I began searching the web for posible resources. The first thing I encountered was a couple of high resolution images of other board clones, with one of them even showing both sides:

Look at all those traces!

As we can see, it's composed mostly of DIP14 and DIP16 ICs, organized in columns which vary depending on the clone. On the right side is the non-logic part of the board, composed mainly of input power and output video and audio and other things I've yet to discover. On the top right there seems to be a voltage regulator attached to a heatsink which is also attached to the main board traces to dissipate the heat. There also seems to be an big capacitor right after this transformer maybe to avoid fluctuations in the power supply.

The two main traces are the power traces which are usually thicker than traces carrying logic signals. Power is distributed through all the columns, having each column a ceramic or polyester film capacitor acting as decoupling capacitors to avoid brownout of the ICs.

These kind of capacitors are normally recommended to be placed as near as possible to the VCC/GND pins of ICs to ensure no tx-line effects affect the supply of power. However in this situation it seems the designers decided to let the ICs share the decoupling capacitors with some exceptions here and there.

There's also a switch in the middle of the board which I have no clue what it does.

If we observe the logic-signal traces, they seem to have been routed manually one by one. The traces on the top layer are oriented vertically and horizontally on the bottom layer. This is usually considered a good practice as if they were oriented in the same direction they would interfere with eachother, adding noise to the logic signal. Also, there's barely any room in the top layer for the traces to move because all ICs are surrounded by the power traces.

Okay enough analysis of the image. I was also able to find the original board topology and circuit diagram of the board:

Don't you just love looking at circuit schematics?

As we can see the board is made only using the 74xx family of logic ICs (and 555 timers). The schematic has been divided into sections which show the function of each block. (A lot later I found the full original document here .)

Even though the previous images are somewhat useful, the text was quite blurry and I wasn't able to read all the components and connections. So I kept searching...until I found the two most useful documents.

This was what I needed to get started.

Part 2: Redrawing the schematic in Altium Designer.

Note: If you don't want the whole circuit explanation, you can skip to Part 3 (waaay below) in which I make the PCB.

Using Dan Boris's schematics as a reference I was able to recreate most of the schematics. However, just as Pong74Is pointed out, some of the logic chips have become obsolete and had to be replaced with newer parts which performed the same function but had different pin connections. Some other components weren't even sold in my country and therefore I tried to replace them with a combination of other components.

I'll attempt to describe each part of the new design just as Dr Holden did, but showing the updated/modern schematics.

POWER

Pretty straightforward stuff. I decided the board would be powered via USB port, instead of the original slot. I think think this way it would be easier to just plug it in everywhere instead of having to carry around a transformer, etc.

There's a main cap (CP1) to maintain steady voltage globally. These caps are normally very slow, so they can't react to quick changes in voltage. For this I've added the capacitors CNn which, like in the original design, will be used as decoupling capacitors in each row of ICs in order to avoid brownout caused by the fast switching. The kind of capacitors normally used for this are small valued ceramic capacitors, which react faster than the large electrolytic ones.

CLK

This is the heart of the whole circuit. A Pierce Oscillator feeding a JK Flip-Flop which is set in Toggle Mode. This means the Q signal will toggle on every cycle of the original clock, dividing it once. This JK Flip-Flop is also acting as a buffer to the original clock as the circuits to make clocks are normally very sensitive and have a low current capacity (low output impedance).

The original schematic used another kind of oscillator and a NAND gate to buffer the signal, but I think this configuration might work.

As we can see, the crystal used is 14.318 Mhz, which is the standard crystal used for NTSC video (the reason for this value came from the color burst frequency after color was added to NTSC TV...but we don't care about that as we are only going to use Monochrome NTSC). If you don't know anything about composite video, you can checkout batsocks article which explains how everything works.

The CLK signal will therefore be 7.159 Mhz. This is the clock which will feed the rest of the circuit.

The tables below show the amount of cycles to count to produce the official NTSC timings.

NTSC Horizontal Timings Period (us) Cycles Cycles Approx Active Video 52.6 376.6 337 Front Porch 1.5 10.7 11 Sync Pulse 4.7 33.6 34 Back Porch 4.7 33.6 34 Full Horizontal Line 63.5 454.6 455 NTSC Vertical Timings Period (us) Lines Lines Approx Active Video 15335.25 241.5 242 Front Porch 190.5 3 3 Sync Pulse 190.5 3 3 Back Porch 762 12 12 Full Frame 33337.5 525 525

However, because the original designers wanted to reduce the amount of wiring and connections, they prioritized using less logic gates. These logic gates are the ones which combine the signals from the clock dividers to get the actual count.

Therefore, they could only use powers of two as cycle counts in their signal timings, so they ended up choosing the powers of two which approximated as closely as possible to the actual timings:

Pong Horizontal Timings Cycles Period (us) Active Video 375 52.38 Front Porch 32 4.47 Sync Pulse 32 4.47 Back Porch 32 2.23 Full Horizontal Line 455 63.56 Pong Vertical Timings Lines Period (us) Active Video 246 15634.67 Front Porch 4 254.22 Sync Pulse 4 254.22 Back Porch 8 508.44 Full Frame 524 ?

HSYNC

Each 74161 IC contains 4 flip-flops, each dividing the frequency of the clock by half. So the 1H signal will contain CLK /2, 2H will contain CLK /4, and so on...

This way, each flip-flop is able to count up to 15 in binary with a frequency of CLK . If we wish to count higher, we could connect the output of the signal with lowest frequency to the clk entrance of the next flip-flop as what's called a ripple counter.

Using the whole 9 flip flops included in the 7493 and the 74107, we're able to count up to 511!

In order to trigger something on a specific count, we use a NAND gate (7430) which will go LOW when all of it's inputs go HIGH. This means that if we connect the 256H , 128H , 64H , 4H and 2H signals, the output of the NAND will get LOW when the count is 256+128+64+4+2 = 454. This allows the 7474 Flip Flop to get triggered on the next cycle, making the HRESET signal LOW after 455 cycles and resetting all the counters. This is the amount of cycles we previously specified on our table as the length of a line in the TV.

The 64H and 16H pulses and the HRESET pulse are used to create the HBLANK and ~HBLANK (Horizontal Blanking and not Horizontal Blanking) and 32H pulses are used to create the ~HSYNC (not Horizontal synchronising pulses)

The two parallel 7400 NAND gates act as a negative edge S-R Latch, where HBLANK will get HIGH when the count is 80 (64H+16H), and will get LOW when HRESET is LOW. Which means HBLANK will be LOW from 0 to 80, and then it will be HIGH from 81 to 455.

The ~HSYNC signal is the intersection of the ~HBLANK signal and the 16H signal. Which means ~HSYNC will be LOW from 16 to 31, only when ~HBLANK is LOW.

If you were not able to follow along all the way, here's an image from Dr. Holden's document, along a simulation I made in Verilog:

Dr. Holden's Drawing

Verilog Simulation

VSYNC

This part is very similar to the HSYNC one, but this time, the counters are fed with the HRESET signal as a clock instead of CLK signal. This way the HRESET signal acts as a line counter for the frame.

The amount of lines we wish to count is 262, which is the amount of lines in a field (half a frame in interlaced NTSC). So as before we use the NAND gate to combine 256+4+1 = 261, plus the cycle the D Flip-Flop adds.

The VBLANK and VSYNC part also acts in a simliar way as the previous figure, but this time it's a NOR S-R Latch, which means it's postively triggered: when VRESET goes HIGH, VBLANK goes HIGH, and when the count is 16, ~VBLANK goes LOW.

~VSYNC is the intersection of VBLANK , 4V , and 8V , which means ~VSYNC will be LOW from 12 to 15, only when also VBLANK is HIGH.

Verilog Simulation

Now that we have the basic NTSC video functionality, we can start drawing stuff on the screen!

Just in case you have forgotten how the game looks, i'll leave a screenshot of it, this will aid us in the future sections:

Net

The net consists of a dashed line in the "center" of the screen, each dash is 4 lines tall (separated by 4 lines), with a thickness of 1 cycle/"pixel".

We use a gate circuit so we can generate gated pulse for drawing the net. In this case, the J-K Flop-Flop is acting as a D Flip-Flop, which on each 1H cycle clocks the 256H signal to Q. So assuming 256H is LOW, on each cycle ~Q will have HIGH, and therefore the output of the NAND gate will be HIGH. When 256H changes to HIGH, the NAND will instantly have HIGH in both of its inputs and will output LOW. After that, 256H gets clocked to ~Q , which will now be LOW, and therefore the output of the NAND will again be HIGH.

This way we obtain a single negative pulse at the output of the NAND, when the count is 256, which is about "half" of a line length (the net will get drawn at the "center" of the screen.)

In other words, we're positioning a pulse (the net) at 256H with a duration (thickness) of 1H .

This signal then gets NOR'd with VBLANK and 4V so that the Net only gets drawn every 4 lines, and when the screen isn't blanking.

Paddles

The paddles are 4 sync pulses/"pixels" thick and and 15 lines tall. The circuit for both paddles are exactly the same, the only difference is it's horizontal position.

The way it works is by using a potentiomenter, a 555 timer and a 4 bit counter.

When ~256V falls LOW at the beginning of vertical blanking, it triggers a 555 timer. This creates some delay depending on the position of the player's 1K potentiometer connected across the 5 volt supply and to the 470 ohm resistor connected to pin 5 of the 555 timer IC (this pin modulates the width of the 555 timer pulse within the 1.1*RC period).

When the 555 timing period ends, the reset pin in the 74161 falls LOW and starts to count horizontal sync pulses.

(In the original schematics they used a 7493 IC. But I've decided to try to replace it with a 74161.

Also, at the start of this count ~VPAD1 goes low. The counter counts up to 15 and at that time the output of the 4-input NAND goes LOW. This causes ~VPAD1 to go high and also stops the count leaving the counter full.

Effectively 15 lines are counted, starting at some point on the scan after a player controlled delay from the start of the vertical blanking interval.

When the 555 is retriggered from the ~256V the next time around and pin 3 of the 555 goes high again, the outputs of the 74161 get reset (zeroed) and the process repeats.

The least significant bit, from the counter’s Q0 output is not used. The binary values of the B1 , C1 & D1 outputs are ultimately encoded to a range of new values in the vertical velocity encoder

The second paddle is exactly the same as the first one

In the lower part of the figure above is the part which determines the positioning and thickness of the paddles.

Just like in the net part, there's a gated pulse happening at the D Flip-Flop, which should position the paddles at 128 and 384.

However, because this signal is combined with the 256H + VPAD1 and ~256H + VPAD2 at the NORs, it gets filtered to the left half of the screen (with the 256H ) forming the left paddle PAD1 , and to the right side of the screen (with ~256H ), forming the right paddle PAD2 .

Verilog Simulation

Ball

In order to render de ball, the board uses an identical sets of counters as in the HSYNC and VSYNC part. These counters, however, only count while in active video, beacuse they get suspended by HBLANK and VBLANK

This way, if the HSYNC counter and the HVID counter are in sync, the ball won't move in the horizontal direction. Same applies for the VSYNC counter, VVID counter and vertical direction.

The ball, then, will move when both counters are out of sync, as the ball rendering signal will get rendered before or after it should (signal will arrive early or delayed with respect to the sync signal).

The Aa , Bb , A6 , B6 , C6 and D6 are the values loaded as initial values for the counters, and they represent the following:

Bb Aa Decimal H. Ball Motion 0 1 1 Right 1 0 2 No Horizontal Motion 1 1 3 Left

D6 C6 B6 A6 Decimal V. Ball Motion 0 1 1 1 7 Fastest Downwards 1 0 0 0 8 1 0 0 1 9 1 0 1 0 10 No Vertical Motion 1 0 1 1 11 1 1 0 0 12 1 1 0 1 13 Fastest Upwards

In the case of horizontal motion, the two counters combined can count up to 255 (this is when the two TC signals get triggered). When this happens the JK flip flop gets toggled in the 256th clock cycle.

If we assume the output of this flip flop was LOW before it toggled, the NAND gate won't get triggered until the next time the counters are full. In other words, before triggering the NAND which loads initial values to the counter again, the counter has to get filled twice: the first time it toggles the flip flop, and the second one activates the NAND.

If we load, for example the number 2 into the counter (through Aa and Bb , which means there shouldn't be any horizontal motion), the first counter will actually get loaded with 8+2=10, while the second one will get loaded with 128.

The full counter, then, starts counting from 128+8+2 = 138. Which means that in order to fill the full counter, it has to count 255-138 = 117 cycles. This is what happens the first time the full counter gets filled, when the JK flip flop toggles.

In the next clock cycle (118) the counters overflow and start counting again for a second time. This time, the counters count from 0 and therefore count 255 cycles.

This means the grand total counted by the counters when the NAND activates is 255+118 = 373.

But wait! The loading of the initial values also takes one clock cycle. So in the 374th cycle, the counters load Aa and Bb again starting the whole cycle again.

This means the horizontal rendering of the ball is in sync with the number of cycles in Active Video, and therefore the ball shouldn't move (remember, this only happens because we loaded a 2 into the counter).

In the case of vertical motion, if we load the number 10 to the first counter, it will count 245 lines until both counters are full. When this happens, the new values waiting to be loaded ( A6-D6 ) are loaded into the counter. This action takes 1 extra clock cycle, so from the moment the counters are full to the next time the counters are full, 246 cycles/lines are counted. Which is exactly the amount of lines in Active Video, and therefore the ball won't move vertically.

The VVID signal which renders the vertical component of the ball is active from 255+8+4 = 267 to 255+16 = 271 (or 257 to 261 if 10 was loaded), which means it's active for 4 cycles giving a height of 4 lines.

Ball Position Encoding

Vertical Velocity Encoder

Each time the ball hits a paddle, it gets a different vertical velocity depending on which part of the paddle it hit. The closer it hits to the edges, the greater the vertical velocity. That means if the ball hits the paddle exactly in the middle, it will have no vertical velocity and therefore the ball will bounce pefectly perpendicular to the paddle

The vertical velocity also gets reversed/inverted when it hits the top and bottom edges of the screen

The B1 , B2 , C1 , C2 , D1 , D2 encode the vertical velocity which will get loaded into the "vertical velocity register" of the ball

In the left part (7408 + 7402) is the data selector. Just as in the previous section, ~256H selects the left side of the screen image and 256H the right so this is how each players bat is selected from two identical player bat data circuits.

The 3 bit bat data is inverted by the outputs of the NORs and is connected to the D inputs of the three 7474 flip flops. This data is then waiting to be clocked into Q by the HIT signal, which gets triggered when the paddle and the ball coincide. (more on this below)

The output of the flip flops is then passed through the inverting stage (the XORs + 74107 IC). In part handles the inverting of velocity when the ball hits the edges of the screen.

The VVID data is the vertical pulse signal of the ball, which is always getting clocked as LOW by the VBLANK unless it's HIGH when a VBLANK is reached. This only happens when the ball hits the edges of the screen.

When this happens the VVID signal gets clocked into the inputs of the XORs, which invert the velocity encoded by the paddle

The ~HIT ensures the applied velocity is not inverted when the ball hits a paddle again. Otherwise the ball would leave the paddle downwards when it hits the upper part of the paddle (instead of upwards)

The ATTRACT input is used when the game is not in use. Its results in the ball being visible and bouncing around the screen and the player bats and scores are missing. It was done this way to attract people to the machine.

The 74283 IC is a binary adder, which adds 6/7 to the value of the ball velocity. Dr. Holden explains this better in his figure:

Horizontal Velocity Encoder

In the case of the horizontal velocity of the ball, the circuit uses a counter which gets triggered by the HIT SOUND signal. This counter records the amount of hits the ball has taken. This is then used to increase the speed of the ball.

The next 6 gates (NANDs and NORs) look hard to follow but they are only used to encode the following table:

Hits < 4 4 to 11 Hits 12+ Hits LSB (First Flip-Flop) 0 1 0 MSB (Second Flip-Flop) 1 0 0

This way, depending on the hit count, different values will be loaded into the two-flip-flop counter.

The ball will MOVE only if the two-bit counter is full. Therefore when a higher value is loaded into the counter, it's easier to fill it and MOVE will get triggered more times per second, resulting in higher speed. If a low value is loaded into the counter it takes longer to fill it, and the ball will move slower.

The lower part...

Score count and display

In order to count score and display it, the circuit first checks if the ball's HVID intersected with a HBLANK . If this happens, MISS will be set, and MISSED too in case ATTRACT isn't set.

The MISSED signal is then combined with the L (moving left) and R (moving right) signal to know which of the players was the one that missed and increase the score accordingly.

Each time MISSED is triggered, it clocks the counter and increases score by one. Because QA is connected to B , the counter actually counts only to a decade instead of the full 16 binary value.

The flip-flop after it clocks to remember a decade has passed (the score is over 9), and used afterwards to display the number 1 on screen.

The STOPG signals are for stopping the game once any of the users reaches a score of 15.

Score Display

In order to display the score, the score bits of the previous stage are passed through a 4-to-1 multiplexer. This multiplexer uses the 64H and 32H signal to show the numbers in two 64H width window in the screen, each number using 32H space.

This makes it ideal for the 4-to-1 multiplexer, there are 4 windows/numbers which have to be selected in time and each multiplexer has 4 inputs from which to select.

If we observe the 64H and 32H signals closely, we can see that we can locate the first number when 64H is LOW and 32H is LOW, followed by the second number when 64H is LOW and 32H is HIGH, the third when 64H is HIGH and 32H is LOW and so on...

Therefore, we select the signals in the following way:

Number Window 64H 32H D C B A First 0 0 SCORE1_10 SCORE1_10 SCORE1_10 1 Second 0 1 SCORE1_8 SCORE1_4 SCORE1_2 SCORE1_1 Third 1 0 SCORE2_10 SCORE2_10 SCORE1_10 1 Fourth 1 1 SCORE2_8 SCORE1_4 SCORE1_2 SCORE2_1

This data is then fed to a BCD to 7-segment converter in the 7448 IC, which instead of actually going to a 7-segment LED display, it is combined with the rendering signals to display it on screen:

I don't think this part is worth a lot of analysis, but enough to say that each segment of the "supposed" 7-segment display is converted to segments on screen. The horizontal segments are 4V lines thick, while the vertical segments are 4H "pixels" thick. Everything is positioned accordingly.

Dr. Holden explains this beautifully with the following diagram:

Game control

This page of the schematic has more mixed parts of the circuit:

On the top is the logic to stop the game, if any of the players has 15 points, it will trigger the STOPG1 or STOPG2 which in turn will set the STOP G signal, when the game is STOP ped and ~RUN ning, the game will enter into ATTRACT mode.

On the left side is the coin switch which resets the system SRST and starts a new game throug RUN

On the right side is the part that detects the collision between the ball and the paddles and sets the HIT signal.

On the bottom is the part that handles what happens when the ball was MISS ed or the game was reset by a coin. After this, there's a delay before the ball is SERVE d which also depends on the position of PAD1 .

SYNC/VIDEO SUM

We're finally here! yaaaaaay!

In this part, all the rendering signals are combined to output it into the composite video output though the RCA connector.

Sound

This part handles the sound, I'm getting kinda lazy doing the explanations, but in short the upper part handles the hit sound with the top and bottom edges, the middle handles the hit sound with the paddles and the bottom handles the hit miss sound.

If the game is in ATTRACT mode, the sound is muted.

Part 3: Attempting to do the PCB

By looking at the pictures in Part 1, I tried to arrange the ICs in a similar fashion, placing them in columns with decoupling capacitors in the top of each colums

At first I thought of making the PCB with the traditional method of etching an FR4 board with Ferric Chloride, so I went to my local store to see if they had that FR4 pieces of that size and unfortunately the biggest chunk I could get my hands on was 30x20cm piece.

This meant everything was going to be tighter in the PCB design (Although after a while I decided not to do it this way as the traces are too thin and too many for the acid to etch properly. It would make it very easy to get disconnected traces in the final result).

Because there are waaay too many traces in this board (I believe the original board was completely traced by hand!), I just used the auto-router with certain design rules applied. I also had to limit the area on which the auto-router placed the traces by using keepout traces (which is why you see collisions and design rules violations colored in the figure above).

It is usually recommended to not use the autorouter in PCB design, but I think this is an exception and upon closer inspection I think the result isn't too bad.

Part 4: Building the board

Unfortunately a PCB of this size is very expensive to manufature, so I guess I'll just wait to have enough money to continue...