Reconstructing on an FPGA

Stephen A. Edwards Department of Science, Columbia University

h¶h«–þóì–Õó, December óþÕó

Abstract I describe in detail the circuitry of the original ÕÉßó Pong video arcade and how I reconstructed it on an €£Z—a modern-day programmable logic device. In the original circuit, I discover some sloppy timing and a previously unidentied bug that subtly ašected gameplay. I emulate the quasi-synchronous behavior of the original circuit by running a synchronous “simulation” circuit with a ó× clock and replacing each žip-žop with a circuit that ešectively simulates one. e result is an accurate reproduction that exhibits many idiosyncracies of the original.

Õ Pong Circuit Descriptionó Õ.Õ e Main Clock...... ó Õ.ó e Horizontal Counter...... ó Õ.ì e Vertical Counter...... ¢ Õ.¦ Horizontal and Vertical Sync...... ¢ Õ.¢ e Net...... ß Õ.ä e Paddles...... ß Õ.ß e Score...... É Õ.˜ Horizontal Ball Control...... ÕÕ Õ.É Vertical Ball Control...... Õ¢ Õ.Õþ Video Generation...... Õß Õ.ÕÕ Sound...... Õß Õ.Õó Game Control...... ÕÉ

ó Reconstructing Pong on an FPGA óÕ ó.Õ Handling Quasi-Synchronous Circuits...... óÕ ó.ó A Minimal Hardware Description Language...... óó ó.ì I/O on the Terasic ouó board...... ó¢

ì Conclusions óä

Õ Introduction is work started with a desire to play Pong, ’s ÕÉßó video that ešectively launched the industry [ÕÕ]. While I could have sought out one of the few remaining machines, I chose instead to reconstruct it on an €£Z, much as I had done for the Apple II computer [ß] and others have done for various other classic video arcade [˜]. Pong and other early games were implemented largely with discrete ±± chips, hence my choice of an €£Z. By contrast, most later games were processor-based and have been successfully emulated in soŸware using an instruction-set simulator interacting with a high- level ad hoc simulator for the video hardware [É]. While modern processors are vastly faster than the roughly ß MHz clock frequency of Pong and many have written Pong-like programs in soŸware, my goal was precise (cycle-accurate) emulation. I ruled out doing so in soŸware because I expect it would be di›cult to implement a soŸware circuit simulator able to consistently run this fast. However, while the Pong circuit is ostensibly synchronous, it is actually littered with ripple counters, §« latches built from discrete •Z•o gates, and žip-žops clocked from combinational logic, all of which are anathema to robust €£Z designs. Below, I describe the circuit of the original Pong with a focus on its timing and analog components (§Õ), then describe my technique for reconstructing it on a modern-day, fully synchronous €£Z (§ó). Õ Pong Circuit Description In addition to reading the schematics for Pong that can be found online (they appear to have been scanned from service manuals), Dan Boris [¦] presents an extensive description of the circuit; much of what I write here is derived from his work, especially his division of the circuit into sections. Arkush [Õ¢] also describes part of the circuitry in Pong, focusing closely on how counters are used to control the position of the ball. Õ.Õ e Main Clock FigureÕ shows the main clock generator: a Õ¦.ì՘ MHz crystal oscillator Õ driving a •Z•o gate driving a Ž žip-žip that halves the frequency and generates a ¢þÛ duty-cycle square wave: the ß.Õ¢É MHz master clock. Õ¦.ì՘ MHz is a common crystal frequency in video circuits because it is four times the •±«h colorburst frequency of ìÕ¢/˜˜ MHz = ì.¢ßÉ¢¦¢ MHz. Pong, however, is black-and-white so another frequency could have been used. Õ.ó e Horizontal Counter e horizontal counter (Figureó), built from two ߦÉìs ( €˜ and €É) and a ߦÕþß (€ä), keeps track of the horizontal position of the video beam. e ߦÉì is a four-bit ripple counter built from four negative-edge-triggered ± žip-žops.

Õe frequency is not labeled on the schematic, but multiple sources, including schematics of Pong clones, conrm this value. 14.318 MHz 100pF

330Ω 330Ω

C9e 0.1µF C9d 11 10 9 8 7404 7404 1 3 12 1 J Q CLK E6d 11 12 F6a 13 7400 4 74107 2 1 K Q 13 1

Figure Õ: e main clock oscillator. is generates a ß.Õ¢É MHz square wave.

Abstractly, the eight-input •Z•o €ß detects the count ó¢ä + Õó˜ + ä¦ + ¦ + ó = ¦¢¦ and causes the counter to reset, but the behavior is slightly more subtle, as shown in Figure¦. Because the ripple counters are triggered on the negative edge of the clock but the output of €ß is bušered by the positive-edge-triggered o žip-žip ußb, the count ¦¢¦ is only seen for half a clock period while the count þ is seen for one-and-a-half clock periods because the „§u«u± signal only rises aŸer the next rising edge of the clock, ešectively surpressing the count on the next falling edge of the clock. e period of „§u«u± is thus ß.Õ¢É MHz~¦¢¢ = Õ¢.ßì¦ kHz, exactly the •±«h horizontal frequency. e horizontal counter is one of the most active parts of the circuit, yet Alcorn used slower, more problematic ripple counters instead of synchronous counters. Why he did this is not clear; one hypothesis is that it was a cost-saving measure: ߦÉìs were nearly half the price of ߦÕäÕs in ÕÉߢ [Õþ]. e use of ripple counters in the horizontal timing circuitry of these games appears to be characteristic of Alcorn. Bushnell’s earlier, more complex, and far less successful (Nutting Associates, ÕÉßì) did use ߦÕäÕs [Õó]. Alcorn designed [ä] Atari’s ÕÉßì successor to Pong, Space Race [ÕÕ], and again used ߦÉìs [ì]. Atari’s ÕÉߦ Pin Pong, not designed by Alcorn, used synchronous counters (ÉìÕäs) [ó]. e presence of ripple counters makes the timing of this circuit worth discussing. In Figureó, I drew some of the internal structure of the counters to help explain the behavior of this circuit. e outputs Մ...ó¢ä„ do not change simultaneously: they ripple, which can be problematic for decoding particular columns. To decode ¦¢¦ as needed, fortunately, the delay is ešectively modest because it is triggered by ó„ going high, which occurs only two žip-žop delays aŸer the falling edge of the ß.Õ¢É MHz clock—all the other signals went high in a previous cycle and stay stable just before reaching a count of ¦¢¦. 3 2 3 2 1 7493 F8 7493 F9 8 5 J Q 14 14 CLK 9 F6b 11 74107 6 K Q 256H 12 1 9 8 11 12 1 9 8 11 10 1 1 11 12 5 10 F7 812 9 6 D Q HRESET 7430 11 E7b 2 7474 8 3 Q HRESET 1H 2H 8H 32H 128H 4H 16H 64H 256H 4 13

Figure ó: e horizontal counter: is counts þ, Õ, ..., ¦¢¦, generating a Õ¢.ßì¦ kHz horizontal frequency.

3 2 3 2 1 R02 R01 R02 R01 8 5 14 14 J Q HRESET CKA E8 CKA E9 9 D9b 1 1 CKB 7493 CKB 7493 11 74107 6 QA QB QC QD QA QB QC QD K Q 256V 12 9 8 11 12 9 8 11 10 9 4 10 D8c 82 5 D Q VRESET 11 7410 3 E7a 7474 6 Q VRESET 1 1 1V 2V 64V 128V 256V 4V 8V 16V 32V

Figure ì: e vertical counter: is counts þ, Õ, ..., óäÕ CLK 7M 1H-256H 451 452 453 454 0 2 3 HRESET HBLANK

1V-256V 261 0 VRESET

1V-256V 0 1 VRESET

1V-256V 1 2 VRESET

Figure ¦: Behavior of the horizontal and vertical counters at the end of a horizontal line

Õ.ì e Vertical Counter e vertical counter (Figureì) is similar to the horizontal counter, but is clocked once per eld by the „§u«u± signal generated by the horizontal counter and resets on a count of Õ + ¦ + ó¢ä = óäÕ. is gives a vertical refresh frequency of Õ¢.ßì¦ kHz~óäó = äþ.þ¢ Hz, which is certainly close enough to äþ Hz for most monitors. A strictly compliant (interlaced) •±«h signal actually has ¢ó¢~ó = óäó.¢ horizontal line periods per eld. Again the ߦÉìs are negative-edge triggered, so the vertical count changes when „§u«u± falls and is reset when „§u«u± rises—see Figure¦. Õ.¦ Horizontal and Vertical Sync Figure¢ shows the circuits for generating horizontal and vertical blanking and synchronization signals. ese are two §« latches built from discrete gates with some extra gating logic. Part of the timing of the horizontal blanking latch is problematic. e „§u«u± signal is not a problem because it comes directly from a žip-žop triggered by the clock (ußb, see Figureó, so „fZ•Ž falls quickly aŸer the rising edge of the clock. However, for „fZ•Ž to rise, 䦄 must be high and •Z•o ¢b looks for the rising edge of Õä„ (a count of ä¦ + Õä = ˜þ). is is initiated by a falling edge on the ß MHz clock and occurs aŸer passing through ve žip-žop stages (all of the €˜ ripple counter and the rst stage of €É). Below is an accounting of delays based on numbers from ±†’s Õɘ˜ data book [Õ¦]. 3 16H 4 G5b 64 H5b 6 5 7410 5 HBLANK 64H 7400

9 H5c 8 10 HBLANK HRESET 7400 12 H5d 11 13 HSYNC 32H 7400

8 VRESET F5c 10 9 7402 VBLANK

11 F5d 13 12 VBLANK 16V 7402 1 2 G5a 12 4V VSYNC 1 13 7410 8V H5a 3 2 7400

Figure ¢: Horizontal and Vertical Blanking and Sync

CLK 7M 1H-256H 77 78 79 80 81 82 HBLANK

Figure ä: Behavior of „fZ•Ž near the start of the line. Because of the ripple counters in the horizontal counter, „fZ•Ž rises aŸer the next rising edge of the clock.

Path Typ. Max. hŽ falling to ˜H falling ¦ä ns ßþ ˜H falling to ÕäH rising Õþ Õä ÕäH rising to G¢b-ä falling ß Õ¢ G¢b-ä falling to „fZ•Ž rising ÕÕ óó hŽ falling to „fZ•Ž rising ߦ Õóì However, the ß MHz clock has a period of about Õ¦þ ns, meaning „fZ•Ž rises aŸer the next rising edge of the clock. Figureä illustrates this. „«í•h only goes low when „fZ•Ž is low (horizontal counts þ–ßÉ) and ìó„ is high, i.e., from horizontal counts ìó to äì inclusive. Using similar reasoning, êfZ•Ž goes low when ê§u«u± goes high: during line þ, and high again at the start of line Õä. ê«í•h is only low when êfZ•Ž is low, ¦ê is high, and ˜ê is low: lines ¦ through ß inclusive. 3 VBLANK 4 G2b 6 V4 NET 5 7427 4 G3b 6 5 8 5 7400 256H J Q 9 F3b CLK 11 74107 6 256H K Q 10 1

Figure ß: Circuit that generates the net

Õ.¢ e Net e net is a simple graphic object—a dashed line going down the center of the screen—that does not ašect gameplay. Figureß shows the circuit, which displays a vertical line in column ó¢ä that alternates between four pixels on and four pixels oš. Before the horizontal counter reaches ó¢ä, ó¢ä„ is low and ó¢ä„ is high, so €ìb’s ¤ is high. When the horizontal counter reaches ó¢ä, ó¢ä„ goes high, sending the output of ìb low, enabling ób to pass ê¦ as the net signal when out of vertical blanking. In the next cycle, since ó¢ä„ was high and ó¢ä„ was low, €ìb’s ¤ falls, setting •u± low. Õ.ä e Paddles Figure˜ shows the circuit generating the signals that indicate when (and hence where) each player’s is displayed. ere are two identical circuits, one for each player. Each ¢¢¢ is wired as a one-shot triggered near the bottom of the screen; the paddle sets the delay time, controlling on which line the one-shot expires. Player Õ’s paddle is a ¢K potentiometeró that forms a voltage divider feeding the control voltage input of ¢¢¢ timer fÉ. Internally, this pin is connected to a ladder of three ¢K that sets its nominal voltage to ó/ì Vcc; the paddle input shiŸs the control voltage away from this value. e þ.ÕµF capacitor on h±§ input bypasses the reference voltage to help keep it constant. At rest, ™¶± is low and the diode clamps the þ.ÕµF capacitor to ground through the o†« pin. Pulling ±§ low turns on ™¶± and žoats o†«, allowing the ¢äK xed and ¢þK trim pot to charge the þ.ÕµF capacitor. When the voltage on ±„§ reaches that on h±§, ™¶± goes low and the capacitor is again discharged through o†« for another cycle. Figure˜ shows a rough diagram of these waveforms. While the exact period of the one-shot is a complex, nonlinear function, it is ≈ RC = ˜.Õms for R = ˜ÕK and C = þ.ÕµF. e vertical refresh period is approximately Õäms, so with a suitable setting of the ¢þK trim pot, and adjusting the paddle voltage divided, the one-shot period should vary from the top to the bottom of the screen.

óis value is not marked on the original schematics; manuals and schematics of clones [Õ] conrm this value. +5 TRG 50K OUT

THR 56K C9b 6 3 3 4 1 0.1 THR OUT B7a 3 VPAD1 11 +5 7 2

µ DIS B9 7404 7400 10 G2c 8 F 2 256H PAD1 256V TRG555 9 7427 5K 470Ω 5 PADDLE 1 14 CTRL 0.1 RST µ F 4 1 3 2 10 5 R02 R01 G3c 8 B7b 6 14 9 4 CKA B8 ATTRACT 7400 HSYNC 7400 1 4 CKB 7493 2 5 QA QB QC QD 128H D Q 3 H3a 12 9 8 11 4H 9 7474 6 Q +5 10 A7b 8 1 12 7420 50K 13 1 B1 C1 D1

56K 13 C9a 2 G2a 12 6 3 1 2 13 256H PAD2 0.1 THR OUT B7d 11 VPAD2 1 7427 +5 7 12

µ DIS A9 7404 7400 F 2 256V TRG555 5K 470Ω 5 PADDLE 2 18 CTRL 0.1 RST µ F 4 1 3 2 9 R02 R01 B7c 8 14 10 CKA A8 HSYNC 7400 1 CKB 7493 QA QB QC QD 12 9 8 11 1 2 A7a 6 4 7420 5 B2 D2 C2

Figure ˜: e paddle circuit. ¢¢¢ timers ZÉ and fÉ operate as one-shots triggered by ó¢äê that select the top line of each player’s paddle. Counters Z˜ and f˜ and žip-žop „ìa make each paddle Õ¢ lines high and ¦ pixels wide. However, Alcorn explains,

e other—not hack—but, one of my lessons learned, is that if you can’t x it, call it a feature. e paddles on the original Pong didn’t go all the way to the top. ere was a defect in the [circuit]—I used a very simple circuit, I had to, to make the paddles, but they didn’t go to the top. I could have xed it, but it turned out to be important, because if you get two good players they could just volley and play the game forever. And the game has to end in about three or four minutes otherwise it’s a failure as a game. So that gap at the top, again—a feature. So that was sort of a happy accident. [Õì]

Going higher on the screen corresponds to a shorter timeout, which in this circuit is limited in part by how low the voltage can go on h±§, which is ašected by the internal ¢K resistor ladder. While the ¢¢¢’s ™¶± is high, the paddle is not displayed because the the output of Bßa stays high, £ZoÕ stays low, and the four-bit ripple counter f˜ is reset. e paddle starts to be displayed on the line where ™¶± rst goes low and continues to be displayed for the next fourteen lines. Here, both the output of inverter hÉb and the output of Zßb are high, so ê£ZoÕ is low. e output of Zßb stays high until the counter reaches Ÿeen. fßb clocks it on the rising edge of „«í•h. On the count of Ÿeen, the output of Zßb falls sending f˜’s clock Z high. is is a glitch: the output of fßb falls, causing ¤Z to rise, causing the output of Zßb to fall, which nally causes the output of fßb to rise again. However, the ߦÉì only requires a Õ¢ ns pulse on hŽZ for proper operation and the delay from hŽZ to ¤Z is typically Õþ ns and the delay through a ߦóþ is typically ˜ ns, so it should work. e three higher-order output bits of each paddle’s vertical counter are used to determine the angle at which the ball bounces oš the paddle; see § Õ.É. Together, „ìa and ìc determine the horizontal width and position of the paddle: the output of ìc goes low between the rising edge of Õó˜„ (horizontal counts Õó˜ and 옦) and the next rising edge of ¦„ (horizontal counts Õìó and 옘) to give a four-pixel-wide paddle. is occurs twice per line, once when ó¢ä„ is low, displaying the leŸ paddle through óc, and once when ó¢ä„ is high, displaying the right through óa. Õ.ß e Score Pong displays two two-digit scores in “seven-segment” style on the upper part of the screen. Each player’s score is held in a decade ripple counter for the rst digit augmented with a Ž žip-žop to represent the tens digit. A controls whether the game ends when either player reaches a score of ÕÕ or Õ¢. At the core of the circuit is a ߦ¦˜ fho-to-seven-segment decoder, which was originally designed to drive seven-segment uo displays. In Pong, a pair of four-to-one multiplexers steer one of the four score digits to the ߦ¦˜, which feeds the decoded number into a bank of seven •Z•o gates that are each activated during a “segment” region on the screen. Finally, 1 MISS 1 2 11 SW1A S1A H6a 6 9 D1f 2 D8a 12 HVID 4 E6c 8 13 12 1 7420 10 E1a 3 S1C 13 7410 5 7400 2 15 S1E 1 7404 7400 B2a 3 2 STOP G HBLANK 3 7400 11 SW1B S2A ATTRACT 4 D8b 6 S2C 5 7410 MISSED 15 S2E 6 3 F5b 4 F5a 1 5 2 L 7402 0 0 R 7402 0 0 SRST 2 3 6 7 2 3 6 7 R01 R02 R91 R92 1 3 R01 R02 R91 R92 8 5 14 1 J Q S1E 14 1 J Q S2E CKA C7 12 C8a CKA D7 9 C8b 1 1 CKB 7490 4 74107 2 CKB 7490 11 74107 6 QA QB QC QD 1 K Q S1E QA QB QC QD 1 K Q S2E 12 9 8 11 13 12 9 8 11 10

SRST S1A S1B S1C S1D S2A S2B S2C S2D

S2A S2B S2C S2D 1 S2E S2E S2E 64H 32H D C B A S1A S1B S1C S1D 0 0 1111, 0001 when player one ≥ 1 S1E S1E S1E Õþ 0 1 Low four bits of player one's score 6 5 4 3 10 11 12 13 6 5 4 3 10 11 12 13 1 0 1111, 0001 when player two 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 ≥ Õþ 14 1 14 1 32H A C6 1G 0 A D6 1G 0 1 1 Low four bits of player two's score 2 15 2 15 64H B 74153 2G 0 B 74153 2G 0 1Y 2Y 1Y 2Y 7 9 7 9

2 32V G1a 1 3 3 256H 7402 1 4 E3b 6 7 1 2 6 64H 2 A B C D 5 7427 64V F2a 6 4 4 BI/RBO 1 128V 7425 5 C5 5 0 RBI 2 E3a 12 9 9 8 3 7448 128H 0 7427 D2c 10 LT 13 10 E2c 8 10 E3c 8 9 7402 a b c d e f g 11 7410 11 7427 13 12 11 10 9 15 14 a b c d e f g E4c 4H 4H 5 6 1 16V 2 D4a 12 a 7404 f 13 7410 4V f b 9 e 8V 9 10 D5c 8 4V g 10 E5c 8 11 7410 11 7427 9 4V e c 16V 10 C4c 8 12 8V 12 11 7410 5 4V d 4H C3d 11 5 b 13 D2b 4 1 4 8H 7400 6 8H 7402 2 D5a 12 1 c D3 8 13 7410 2 SCORE 1 7430 9 11 a 3 10 D4c 8 6 7410 E4b 4 E5b 6 11 3 3 4 5 7427 3 16H g 7404 4 D4b 6 1 5 7410 4V E4a 2 E2a 12 1 2 3 8V 7410 13 7404 4 D5b 6 5 7410 d

Figure É: Score circuitry: the outputs of €¢b and €¢a pulse when a player has scored; hß, h˜a, oß, and h˜b maintain the score; the remainder displays the score as two two-digit seven-segment decimal numbers. the output of these gates are fed into an eight-input •Z•o gate that ešectively sums them to produce the nal score display signal, which is mixed to produce a slightly dimmer display than the signal for the ball, paddles, and net. Starting from the top leŸ of FigureÉ, „ê†o is low where the ball is present (see § Õ.˜), so “†«« goes low when the ball reaches the horizontal blanking region (i.e., oš the leŸ or right of the screen). When the game is not in attract mode, this causes the “†««uo signal to go low, sending the clock of either hß or oß high. If the ball was moving leŸ when this happens (i.e., past player one), R will be low, pulsing the clock of oß high. When it falls, player two’s score counter (oß) will increment. Player one’s score counter consists of the four-bit ripple decade counter hä and Ž žip-žop h˜a. AŸer hß reaches a count of nine, it will reset itself to zero on the next cycle, dropping ¤o and causing h˜a to toggle, indicating a score of ten. Player two’s score counter (oß and h˜b) is wired similarly. NZ•o gates o˜a and o˜b detect the end-of-game condition, dictated by «ëÕ. In its “ÕÕ” position, the inputs to o˜a and o˜b žoat high, meaning «±™£  will rise when either player reaches a score of ÕÕ. Similarly, when «ëÕ is in the “Õ¢” position, the rst, third, and Ÿh bits of the score must be one: a score of Õ¢. Depending on horizontal counter values ìó„ and 䦄, four-input muxes oä and hä steer either the low digit of each player’s score, Õ when the high-order bit of a player’s score is Õ, or Õ¢ when it is zero, to the seven-segment decoder h¢. e ߦ¦˜ turns oš all digits when fed an input of Õ¢, so this logic disables a leading zero. Gates uìa, uìb, uóc, uìc, Õa, oóa, and €óa enable the outputs of h¢ when the beam is over the score area at the top of the screen. Gates u¦b, hìd, u¢c, oób, u¢b, u¦a, and u¦c compute functions for displaying the segments as shown on the map on the leŸ of FigureÉ. Consider the output of o¦b. It drives the output of oì high when g is high, ¦ê and ˜ê are high, Õäê is low, and Õä„ is high. is produces the horizontal bar that appears above the midpoint as shown in the diagram. It turns out Õä„ must be high for any segment to be visible; the constraints on ¦ê, ˜ê, Õäê, ¦„, and ˜„ vary depending on the segment. Õ.˜ Horizontal Ball Control To control the position of the ball, Pong uses a clever technique described in Bushnell’s ÕÉߦ patent [¢] that involves running “position” counters at almost the same frequency as the horizontal and vertical counters. In such a situation, the phase of these “position” counters relative to the main horizontal counters determine where on the screen the ball will appear; slight perturbations to the period of the position counters cause the ball to move. Figure Õþ shows the circuit responsible for the horizontal position of the ball. is is built around a nine-bit counter built from ß, „ß, and äb, which reloads itself when it reaches a count of ¢ÕÕ. 8 256H G1c 10 9 VRESET 7402

RST SPEED 1 Hits H1-8 6 H4a 3 3 2 8 5 1 3 2 12 R02 R01 1 J Q J Q 7400 E1d 11 14 03 0 1 9 H2b 12 H2a 13 CKA F1 HIT SOUND 7400 1 411 1 0 11 74107 6 4 74107 2 CKB 7493 K Q K Q QA QB QC QD 12 0 0 10 13 11/MOVE 12 9 8 11 0 9 9 E1c 8 13 H1c 8 01/MOVE 10 7400 H1d 11 10 7400 12 7400 11 1 10/MOVE G1d 13 H1a 3 4 12 2 H1b 6 7402 7400 5 7400 00/MOVE

MOVE

L HIT2 MOVE L R Aa Ba Range Period Movement 10 12 H4d 11 9 12 9 13 H4c 8 12 D1a D Q 7400 10 0  01 138,. . . ,511 374 Stationary SC C1d 11 1 2 11 H3b 4 7400 13 H4b 6 1 1 0 1 1 139,. . . ,511 373 Left ATTRACT 7400 7474 8 5 7404 Q 7400 Ba 1 0 1 1 0 137,. . . ,511 375 Right

13 R HIT1 Aa

0 1 0 0 0 1

9 3 4 5 6 1 9 9 LD A B C D 3 4 5 6 7 10 G5c 8 ENP LD A B C D 2 G7 15 7 8 5 11 7410 CLK RCO ENP 1 J Q 10 9316 2 H7 15 9 G6b HBLANK ENT CLK RCO 10 9316 11 74107 6 CLRQA QB QC QD 1 ENT 1 K Q 1 14 13 12 11 CLRQA QB QC QD 10 CLK 14 13 12 11 1 9 10 4 H6b 8 ATTRACT E1b 6 12 HVID 5 7420 SERVE 7400 13

Figure Õþ: Ball horizontal circuit. e output, „ê†o, is asserted when the ball is visible in the current column. Four-bit counter FÕ counts hits and speeds up the ball in response. e duration of the MOVE signal controls how many pixels to move the ball leŸ or right. Finally, the phase of the nine-bit counter formed by Gß, Hß, and Gäb determines the horizontal position of the ball. When the “™êu signal is low, the horizontal ball counter stays in phase with the master horizontal counters, in ešect keeping the ball in the same horizontal position. When “™êu is low. „¦b, „¦c, and „¦d set Aa and Bb, inputs to the synchronous four-bit counter ß (a ÉìÕä, pin compatible with the more familiar ߦÕäÕ chip), to þ and Õ respectively. us, when the horizontal ball counter reaches ¢ÕÕ, the output of ¢c goes low and the counter is loaded with the value þÕþþþÕþÕþ = Õó˜ + ˜ + ó = Õì˜ on the next rising edge of the clock („ß’s §h™ falls when this value is loaded, toggling Gäb, which becomes a þ because it was a Õ to activate ¢c). In this mode, therefore, it counts Õì˜, ÕìÉ, ..., ¢ÕÕ: a period of ìߦ. e horizontal ball counter only advances on rising edges of the clock when „fZ•Ž is high since „fZ•Ž drives ß’s u•± input. From the discussion in § Õ.¦, this occurs during horizontal counts ˜Õ, ˜ó, ..., ¦¢¦: ìߦ times per line. us, when “™êu is low, the horizontal ball counter stays in sync with the horizontal counters. e „ê†o signal indicates the position of the ball. It is asserted when the horizontal ball counter has values ÕÕÕÕÕÕÕþþ–ÕÕÕÕÕÕÕÕÕ, i.e., ¢þ˜, ¢þÉ, ..., ¢ÕÕ, making the ball four pixels wide. When “™êu is high, the horizontal ball counter resets to a slightly dišerent value, ešec- tively making the ball move leŸ or right. „ìb, a o žip-žop, controls the direction. When  is Õ, § is þ, Ba is Õ, and Aa is Õ, making the counter reset to Õó˜ + ˜ + ó + Õ = ÕìÉ. is makes the period one less then the duration of „fZ•Ž, moving the ball to the leŸ. Conversely, when “™êu is high and  is þ, § is Õ, Ba is þ and Aa is Õ, making the counter reset to Õó˜ + ˜ + Õ = Õìß and moving the ball to the right. Hìb makes the ball bounce oš the players’ paddles. When the leŸ paddle (player one) touches the ball, „†±Õ goes low, setting „ìB into a state where L=þ and R=Õ, thus sending the ball right. Similarly, colliding with player two’s paddle sends the ball leŸ. Note that because these signals set the direction of the ball, rather than change it, there is no danger of the ball becoming trapped inside a paddle that suddenly appears from being moved very quickly. Hìb also makes the ball bounce oš the leŸ and right edges of the screen in attract mode. e «h signal pulses high for a few clock cycles when the ball goes oš the screen horizontally (i.e., causing a score if the game were being played). In attract mode, hÕd passes this pulse through to „ìb’s clock, causing it to toggle once when the ball hits the edge of the screen. Ripple counter €Õ counts the number of hits, which is used to increase the (horizontal) speed of the ball. §«± «£uuo goes high briežy during game play when one player scores a point, resetting counter €Õ. AŸer reset, ¤h and ¤o are low, setting uÕc’s output high. ereaŸer, when „†± «™¶•o pulses high (when the ball hits either paddle), it clocks €Õ. Once €Õ reaches a count of ˜ + ¦ = Õó, uÕc’s output goes low, inhibiting further counts until the next point. e output of counter €Õ is decoded to control the clear inputs of Ž žip-žops „óa and „ób, which form a state machine that controls whether “™êu is asserted on one, two, or three lines per eld, controlling the horizontal speed of the ball. Figure Õþ shows the state transition diagram for this machine, which is clocked on the falling edge of ó¢ä„ except on the rst line of each eld (when ê§u«u± is high), when •Z•o gates „Õb and „Õc set the state of this machine. 1 3 VVID J Q 12 A2a VBLANK 4 74107 2 K Q AöB£A£A£ B®-A B®-B Range 13 HIT a a a b ®îö× ®îö× 3 D1 1 1 2 B6b 4 ÿ ÿ ÿ ÿ ÿÿÿÿ ÿ××× à,...,ö££ 256H 6 2 5 13 B6a 4 D Q 8 D2 3 B5a 9 ÿ ÿ ÿ × ÿÿÿ× ÿ××× ™,...,ö££ 5 7450 256H 7474 6 10 7450 ÿ ÿ × ÿ ÿÿ×ÿ ÿ××× Ì,...,ö££ Q 1 ÿ ÿ × × ÿÿ×× ÿ××× ×ÿ,...,ö££ 3 1 ÿ × ÿ ÿ ÿ×ÿÿ ÿ××ÿ ×ÿ,...,ö££ C1 4 4 2 A6b A4b 6 6 2 5 5 4 D Q 7486 ÿ × ÿ × ÿ×ÿ× ÿ××ÿ ××,...,ö££ C2 3 A5a 5 7450 ÿ × × ÿ ÿ××ÿ ÿ××ÿ ×ö,...,ö££ 7474 6 Q ÿ × × × ÿ××× ÿ××ÿ ×î,...,ö££ 1 1 × ÿ ÿ ÿ ÿ××× ÿ××ÿ ×î,...,ö££ 1 1 B2 2 C4a 12 13 A6a 10 × ÿ ÿ × ÿ××ÿ ÿ××ÿ ×ö,...,ö££ 8 12 9 9 13 7410 9 D Q A4c 8 11 A5b 10 × ÿ × ÿ ÿ×ÿ× ÿ××ÿ ××,...,ö££ 10 7450 7486 B1 7474 8 Q 0 1 1 0 × ÿ × × ÿ×ÿÿ ÿ××ÿ ×ÿ,...,ö££ D1c 10 8 3 1 11 7 4 16 5 6 13 × × ÿ ÿ ÿÿ×× ÿ××× ×ÿ,...,ö££ ATTRACT A1 A2 A3 A4 B1 B2 B3 B4 13 B4 14 × × ÿ × ÿÿ×ÿ ÿ××× Ì,...,ö££ 7404 0 C0 C4 7483 HIT × × × ÿ ÿÿÿ× ÿ××× ™,...,ö££ Σ1 Σ2 Σ3 Σ4 9 6 2 15 × × × × ÿÿÿÿ ÿ××× à,...,ö££ Ab Bb Cb Db

9 3 4 5 6 0 0 0 0 A B C D 9 3 4 5 6 7 LD 1 ENP LD A B C D 2 B3 15 7 HSYNC CLK RCO ENP 10 9316 2 A3 15 4 VBLANK ENT CLK RCO B2b 6 10 9316 5 CLRQA QB QC QD 1 ENT 7400 14 13 12 11 CLRQA QB QC QD 1 VBALL240 1 14 13 12 11 VVID 1 5 1 11 4 E2b 6 D2d 13 12 VVID 3 7410 7402 VBALL16 VBALL32

Figure ÕÕ: Ball vertical circuit. e output, êê†o, is asserted when the ball is visible on the current line. Flip-žops f¢a, Z¢b, and Z¢b remember the position at which the ball last hit a paddle; Zóa toggles to rebound the ball oš the top or bottom. Four-bit adder f¦ translates the ball motion signals into a reset value for the eight-bit counter formed by Zì and fì, which determines the vertical position of the ball. Õ.É Vertical Ball Control FigureÕÕ shows the circuit responsible for the vertical position of the ball. Like the horizontal circuit, it consists of a counter (only eight bits for the vertical counter: Zì and fì) whose period, and hence vertical ball speed, is set by a state machine ašected by a ball hitting a paddle or the top or bottom of the screen. When the game is in attract mode, the paddles are hidden and the ball travels at one speed diagonally, bouncing oš the sides of the screen. In this state, inverter oÕc drives the clear inputs of o žip-žops f¢a, Z¢a, and Z¢b, setting their ¤’s to all þ. JŽ žip-žop Zóa, together with exclusive-™§ gates Z¦b, Z¦c, and fäa (an Z•o-™§-invert gate wired to compute exclusive-™§) are responsible for bouncing the ball oš the top and bottom of the screen. When Zóa’s ¤ is low, the exclusive-™§ gates pass the outputs of the three o žip-žops unchanged and invert them when the ¤ output is high. e state of Zóa toggles when the ball hits the screen top or bottom: when êê†o is high (i.e., when the ball is visible on the current line) at the end of vertical blanking (when êfZ•Ž falls). As in the horizontal circuit, the phase of the vertical counter (formed by synchronous four-bit counters Zì and fì) ašects the vertical position of the ball and the period of the counter ašects the ball’s vertical velocity. Here, however, the counter is clocked by the rising edge of „«í•h and gated by êfZ•Ž. As discussed in § Õ.¦, there are óäó lines per eld and êfZ•Ž is active for Õä of them, giving the ball vertical counter óäó − Õä = ó¦ä counts per eld. us loading the vertical ball counter with Õþ will hold the ball in the same position vertically; smaller numbers increase the period, causing the ball to move down on the screen; larger numbers will cause it to move up. In attract mode, the counter is loaded with ß or Õì depending on Zóa, so it will move at the maximum speed vertically. During gameplay, the ball rebounds oš the paddle at an angle determined by where the ball hit the paddle. o žip-žops f¢a, Z¢a, and Z¢b remember this collision location; binary adder f¦ transforms it into a value with which to load the ball vertical counter. When the ball hits the paddle, „†± pulses high, resetting Zóa and loading o žip-žops f¢a, Z¢a, and Z¢b with the one’s complement of the top three bits of one of the paddle counters (see § Õ.ä). And-or-invert gates Zäa, Zäb, and fäb are wired as two-input multiplexers that pass the top three bits of player one’s paddle position (fÕ, hÕ, and oÕ) when ó¢ä„ is low (i.e., the ball is to the leŸ of the net) and player two’s paddle position when ó¢ä„ is high. In the table in FigureÕÕ, note that the range Õþ,...,ó¢¢ appears four times instead of two. is makes it easier to rebound the ball purely horizontally—there is a large area in the center of the paddle where this will happen. It appears the inputs to Zäa are wired incorrectly. While fäb and Zäb select data from player one when ó¢ä„ is low as we would expect, Zäa selects data from player two. e schematic in FigureÕÕ is consistent with the original schematics (Figure Õó) as well as the board.ì Even the schematic for an (unauthorized) clone of Pong has this error [Õ].

ìI traced the signals on a high-resolution photo of the front and back of the two-layer board. Figure Õó: Part of Pong’s original schematic: the vertical ball counter. e intention of the top Z•o-™§-invert gate (Zä) is clear: pass fÕ under the same conditions as hÕ and oÕ, but pins Õ and Õþ are swapped: pins Õ and Õì are one group; É and Õþ are the other. 1.2K SCORE 12 E4e 5µF 10V HSYNC A4d 11 11 10 2.2K 20 Video Out 13 7486 VSYNC 7404 9 PAD1 10 E4f NET F2b 8 13 12 1K 12 PAD2 7425 13 7404 12 B2d 11 5 13 HIT HVID G1b 4 7400 6 1 VVID 7402 G3a 3 2 7400 HIT2 9 B2c 8 HIT 10 7400 12 G3d 11 13 7400 HIT1

Figure Õì: Video generation circuitry. Fób combines the signal from the two paddles, the net, and the ball. e score display is mixed with a Õ.óK resistor, making it slightly dimmer.

Õ.Õþ Video Generation Figure Õì shows the circuit that combines the horizontal and vertical synchronization signals (§ Õ.¦), the net (§ Õ.¢), paddles (§ Õ.ä), score (§ Õ.ß), and the ball (§§ Õ.˜ and Õ.É) to produce the nal composite (black-and-white) video signal. A resistor summing network combines the score, sync, and other video elements. Note a higher-value resistor is used for the score (Õ.óK); this makes it slightly dimmer than the paddles, ball, and net. A ¢µF coupling capacitor removes any oh bias. Also in Figure Õì is the logic generating „†±, „†±Õ, and „†±ó, used, e.g., by the ball vertical circuit. Õ.ÕÕ Sound e sound in Pong is legendarily simple, perfect, and almost serendipitous, as Alcorn relates:

Now the issue of sound ...People have talked about the sound and I’ve seen articles written about how intelligently the sound was done and how appropriate the sound was. e truth is, I was running out of parts on the board. Nolan wanted the roar of a crowd of thousands—the approving roar of cheering people when you made a point. told me to make a boo and a hiss when you lost a point, because for every winner there’s a loser. I said, “Screw it, I don’t know how to make any one of those sounds. I don’t have enough parts anyhow.” Since I had the wire wrapped on the scope, I poked around the sync generator to nd an appropriate frequency or a tone. So those sounds were don in half a day. ey were the sounds that were already in the machine. [ÕÕ] ATTRACT 4 VBALL32 C3b 6 3 4 1 3 5 C1b 6 VVID J Q 7400 4 C4b 6 5 16 SOUND 12 F3a 7400 VBLANK 5 7410 4 74107 2 VVID K Q Top Hit Sound 13 SERVE 1 4 Hit Sound 2 5 1 D Q HIT SOUND 3 C2a VBALL240 7474 6 1 Q C3a 3 2 7400 1 HIT VBALL16

+5 32V 220K 9 C3c 8 6 3 10 THR OUT 7400 7 1.0 DIS G4 2 MISS TRG555 SC 5 CTRL Score Sound

0.1 RST 4 0

Figure Õ¦: Sound Circuitry FigureÕ¦ bears this out. Pong generates three sounds: a “ping” sound when the ball hits a paddle, a “pong” sound when the ball režects oš the top or bottom of the screen, and a similar sound when either player scores a point. JŽ žip-žop €ìa is active when the ball is bouncing oš the top or bottom, much like Zóa does for the vertical ball control (FigureÕÕ). Fìa takes a new value at the top of each screen (i.e., when êfZ•Ž falls before the rst line of the screen). If the ball was visible at the end of vertical blanking (i.e., went oš the top or bottom of the screen), €ìa’s ¤ output goes high for a eld, enabling hìb, which passes êfZìó (the sixth bit of the vertical ball counter). is is Õ¢.ßì¦ kHz / Õä = ɘþ Hz, near B¢ on the piano. D žip-žop hóa turns on briežy aŸer the ball is hit. Normally, hóa’s ¤ is low, disabling hìa, but when the ball is hit, the hóa’s reset goes low, sending ¤ high and gating êfZÕä (the Ÿh bit from the vertical ball counter). is is Õ¢.ßì¦ kHz / ìó = ¦Éþ Hz, near B¦ on the piano. Timer ¦ activates the score sound for a period of time aŸer “†«« pulses low, which occurs when the ball goes oš the screen horizontally—see FigureÉ. e óóþK resistor and Õ.þµF capacitor set the width of the pulse, which is roughly Õ.Õ ⋅ óóþK ⋅ Õ.þµF = ó¦þ ms. is sound is set by ìóê, the sixth bit of the vertical counter, which also counts at about ɘþ Hz. C¦b “sums” the three sound sources, which are silenced during attract mode by hÕb. e sound output is sent, unamplied, to the ±ê monitor. Õ.Õó Game Control Figure Õ¢ shows the game control circuitry. It consists of a debouncing circuit for the coin switch (inverters hÉc and hÉf), a latch/power-on reset circuit built from discrete transistors (¤Õ, ¤ó, and associated and capacitors), and the serve timer (€¦). When the game powers up, the coin switch pulls «§«± low, «§«± high, and transistors ¤Õ and ¤ó remain oš, allowing the ÕþþΩ and ìþþΩ resistors to pull §¶• high, so Z±±§Zh± falls and the game enters attract mode (paddles are hidden, ball bounces oš the sides of the screen instead of causing a score). Inserting a coin žips the state of the ¤Õ-¤ó latch to indicate the game is being played: «§«± briežy pulses low, resetting the score and pulling ¤Õ’s collector low through the ՕÉÕ¦ diode. is drops the voltage on ¤ó’s base and turns it on, raising the voltage on ¤Õ’s base and turning it on, pulling §¶• down, which keeps ¤ó turned on aŸer «§«± rises. At the same time, when «§«± pulses low, §«± «£uuo pulses high to reset the horizontal ball speed and triggers ¢¢¢ €¦, the serve timer, which is wired as a one-shot, so €¦’s ™¶± pulses high for roughly Õ.Õ ⋅ ììþK ⋅ ¦.ßµF = Õ.ßs. is puts the output of u¢a low, which asserts «u§êu. Once ™¶± falls, the output of u¢a rises and «u§êu falls on the next rising edge of £ZoÕ. When either player’s score reaches ÕÕ or Õ¢, the game ends: the score counters assert «±™£ , which pulls the base of ¤Õ low, turning oš ¤ó as well, raising §¶• and asserting Z±±§Zh±. e “Antenna” input is intended to prevent free games initiated by a static shock to, say, the coin logic. If the voltage on the base of ¤ì rises, it pulls the base of ¤Õ low, turning it oš and letting §¶• rise. +5 0.1 100 µ Ω

F Q2 300 100 Ω +5 E4d 1N914 Ω 9 8 STOP G 7404

1N914 220 1N4001

Q1 Ω SRST Q3

C9f C9c 0.1 13 12 5 6 100

SRST µ 15 Antenna Ω 7404 7404 F 1N914

10 12 D1b ONSW COIN 3 4 RUN ATTRACT +5 7404

330K 2 D2a 1 3 7402 ATTRACT 1 1 10 4.7 2 E5a 12 12 9

µ D Q SERVE F 6 3 13 7427 11 B5b THR OUT PAD1 7 7474 8 4 1 DIS F4 Q SERVE E6b 6 E6a 3 2 555 5 2 TRG 13 MISS 7400 7400 5 CTRL 0.1 RST SERVE TIMER 4 RST SPEED 1

Figure Õ¢: Game Control Circuitry ó Reconstructing Pong on an FPGA Virtually all of Pong is digital so implementing it on a modern €£Z is feasible, but not straightforward. First, there are a handful of analog sections: the master oscillator; the one- shot timers for the paddles, score, and serve; and the nal video output circuitry. F£Zs typically use external clock oscillators anyway, so this part is easy. e timers can be emulated with counters. e video circuitry is a primitive o/Z converter with four levels: sync, black, gray, and white. Gray is used for displaying the score; the ball, paddles, and net are all white. As described earlier, Pong’s sound is actually digital: a Õ-bit output produces square waves at three frequencies. ó.Õ Handling Quasi-Synchronous Circuits Despite utilizing a ß.Õ¢É MHz master oscillator, Pong is not classically synchronous. Deviations from this ideal (i.e., acyclic combinational logic between žip-žips driven by a global clock) include the ripple counters in the horizontal and vertical circuits, which cause the unexpected timing of „fZ•Ž that I described in § Õ.¦; §-« latches built from discrete gates that generate horizontal and vertical sync (Figure¢); and numerous žip-žops driven by clocks driven by derived signals and employing asynchronous set and reset signals. Most of these were reasonable shortcuts to take in ÕÉßó, but are anathema in modern €£Z designs. My solution for reconstructing Pong in a purely synchronous style was to construct synchronous circuits that essemtially simulate the asynchronous aspects of the original Pong circuit. My goal was to make the behavior of the reconstructed circuit match the original on the edges of the ß.Õ¢É MHz clock (since parts of Pong are sensitive to both rising and falling edges) and to assume the absence of glitches on the generated clocks in the original circuit, i.e., that any switch more quickly than the global clock. Figure Õä shows the circuit I use to emulate the ߦߦ: a positive-edge-triggered dual o žip-žop with asynchronous set and reset inputs. I replace each original o žip-žop with three žip-žops: “¤” to hold the current state, “o” to capture the (possibly irrelevant) next state, and “h” to remember the previous value of the (asynchronous) clock. is circuit assumes it is clocked fast enough so that neither the clock nor the “o” input transitions more than once per cycle. e Z•o gate marked “§†«u” and the “h” žip-žop detect whether hŽ has risen since it was last sampled. If hŽ rose, the mux supplies the value of the o input sampled before the rising edge by the “o” žip-žop. Otherwise, hŽ was stable and the mux delivers the previous value of ¤, held by the “¤” žip-žop. Combinational inputs h§ and £§u set and clear the output regardless of the behavior of hŽ; the feedback loop ensures their ešect is felt in the next cycle even if hŽ did not rise. is circuit can simulate the original žip-žop provided it is run at least twice as fast. In the exactly twice-as-fast case, the hŽ input is high in alternate cycles and makes the mux alternate between the “o” and “¤” žip-žops, which latches the o input in cycles when hŽ is low. Q 0 D 1 D Q Q RISE CLK C CLR

PRE

Figure Õä: My circuit for emulating a ߦߦ positive-edge-triggered D žip-žop. e Z•o gate “§†«u” detects a rising edge on the hŽ input and either delivers the old Q output or the newly latched value of D.

e remaining sequential elements in Pong are ߦÕþß negative-edge-triggered Ž žip- žops, ߦÉì four-bit ripple counters, ߦÉþ four-bit ripple decade counters, and ÉìÕä four-bit synchronous counters. My circuits for each closely parallel that for the ߦߦ I describe above. In particular, I assemble the ripple counters from a cascade of Ž žip-žops. For the §-« latches for „«í•h and ê«í•h, I simply inserted a one-cycle delay (a o žip-žop) to break the combinational feedback loop. ó.ó A Minimal Hardware Description Language V„o and Verilog are the hardware description languages accepted by most synthesis tools, including the ones I used. I certainly could have written the Pong netlist in one of these formats, but I chose to develop a simple language of my own to keep the length of the description to a minimum. I chose its syntax to be simple enough to “parse” with an ZëŽ script. e basic challenge is to specify the type and connectivity of each component. To do this, my basic syntax resembles that of «£†hu: a typical line describes an instance of a component and consists of a component type, a designator, and a list of connected nets ordered by the pins dened for the component. FigureÕß shows my code for the horizontal counter. I cut a corner here and used a ve-input •Z•o gate even though the actual circuit uses a ߦìþ eight-input •Z•o with three inputs tied high. A net name is any sequence of printable characters (not space, newline, or control char- acters). is allows the use of existing, natural names such as “䦄” (horizontal counter bit representing sixty-four), notation such as /HRESET to represent the complement of the „§u«u± signal, and “þ” and “Õ” to represent logical false and true. Nets are never explicitly dened; their rst reference in an instance line brings them into scope. Each is assumed to carry a single bit. One special rule: the “underscore” net (_) means “unconnected;” it is intended for repre- senting unconnected outputs since I do not provide a connect-by-name syntax. I adopted this from the “-derived functional languages. # Horizontal counter SN7493 F8 CLK7M 1H HRESET HRESET 1H 2H 4H 8H SN7493 F9 8H 16H HRESET HRESET 16H 32H 64H 128H SN74107 F6B 1 1 128H /HRESET 256H /256H TTLNAND5 F7 256H 4H 2H 64H 128H n13 SN7474 E7B n13 1 CLK7M 1 /HRESET HRESET

Figure Õß: Code in my „o for dening the horizontal counter circuit; cf. Figureó. e k line is a comment. Each other line lists a component name, a component designator, and the names of the nets to which its pins should connect.

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;

entity TTLINV is port ( clk : in std_logic; :TTLINV A !Y A: in std_logic; Y <= not A; Y: out std_logic ); end TTLINV;

architecture ttl of TTLINV is begin Y <= not A; end ttl;

Figure ՘: An inverter component dened in my „o and the ê„o code I generate for it.

A component denition line starts consists of a colon, the name of the component, and a space-separated list of pins. Pin names prexed with an exclamation mark are outputs; all others are inputs. Lines aŸer the initial denition are treated as ê„o that denes the body of the component. e body denition continues until the next non-empty line that does not start with a space (e.g., a comment, another component denition, or an instance). e lines containing the ê„o keyword “signal” aŸer the initial space are understood to dene signals and are placed before the “begin” keyword for the body of the instance. Figure ՘ compares the denition of an inverter component in my „o to one my translator generates for one in ê„o. Note that the clk input is added automatically to each component to support sequential elements; it goes unused on this entity. Figure ÕÉ show some simple component denitions followed by a more complicated one. Note the use of the ê„o \... \ extended identier notation. :XOR2 A B !Y Y <= A xor B; :TTLNAND2 A B !Y Y <= A nand B; :TTLNAND5 A B C D E !Y Y <= not (A and B and C and D and E); # Delta delay to break feedback loops(e.g., inRS latches) :DELTA D !Q process (clk) begin if rising_edge(clk) then Q <= D; end if; end process;

#(Dual)D-type positive-edge-triggered flip-flops with preset and clear :SN7474 D /PRE CLOCK /CLR !Q !/Q signal next_d, last_d, next_q1, next_q, last_q, last_clock : std_logic := ’0’;

process (clk) begin if rising_edge(clk) then last_d <= next_d; last_q <= next_q; last_clock <= CLOCK; end if; end process;

next_q1 <= last_d when clock = ’1’ and last_clock = ’0’ else last_q; next_q <= (next_q1 and \_CLR\) or not \_PRE\; next_d <= d;

Q <= next_q; \_Q\ <= not next_q;

Figure ÕÉ: Denition of some combinational gates, a “delta” delay component, and the deni- tion for an “asynchronously clocked” D žip-žop; cf. Figure Õä. ó.ì I/O on the Terasic ouó board I targeted a Terasic ouó board as the emulation platform for Pong. Pong has limited I/O: a coin input, two paddle inputs, and audio and video out.¦ Each of these needs to be emulated on the board. e coin input was the simplest: the ouó has a number of keyswitches that provide one-bit inputs. I coded a small synchronous module that emulates the discrete components of the game control circuitry, basically the top half of Figure Õ¢, that generates «§«± and §¶• from the coin input and «±™£ . e video output was probably second hardest. e ouó has a video oZh driving a standard Õ¢-pin êZ jack and I had plenty of êZ-capable ho panels around. One problem is that Pong generates •±«h-speed video (Õ¢.ßì¦ kHz horizontal refresh), while êZ expects exactly twice that (ìÕ.¦ä˜ä kHz). I implemented a line doubler that uses a double-ported Õþó¦ × óbit §Z“. e line doubler lls half of the bušer with video data from Pong (two bits per pixel: one representing the brightness for the score; the other representing all others) while displaying the other half. Every other •±«h line, the roles of the two halves of the bušer are swapped. e line doubler expects exactly the horizontal timing produced by Pong, generates a êZ-speed horizontal sync signal, and passes the vertical sync signal directly to the monitor. e audio output, ironically, was even more di›cult. e ouó has a Wolfson 듘ßìÕ ó¦-bit stereo audio codec connected to ì.¢mm headphone jacks, which is certainly overkill for Pong’s Õ-bit digital audio output, but I chose to use it anyway because I did not want to build additional hardware. e 듘ßìÕ must be congured through an IóC bus interface, so I took a circuit from other projects that generates the appropriate IóC signals to congure the codec along with the logic necessary to generate the timing signals it desires (clocks, framing, leŸ/right). AŸer all of this, I simply feed the single bit from the Pong audio output into the most signicant bit of both channels of the codec. It beeps. e two paddle inputs presented a conundrum: while perhaps the most authentic route would have been to build the ¢¢¢-based timing circuitry and communicate appropriate timing pulses to/from the Pong core, I wanted to avoid adding anything but oš-the-shelf peripherals. I settled on connecting a mechanical £«/ó mouse to the ouó because it had the proper connector and is fairly easy to interface, but manually spinning the two optical encoders in the mouse hardly makes for convenient game play. I instantiated an open-source £«/ó controller block and created a fairly complicated state machine that reset the mouse and sent an “enable data reporting” byte to it so it would start sending back movement information that my €«“ could interpret and convert to coordinates. Finally, the raw coordinates are converted into counts for a ¢¢¢ timer emulator circuit that waits for a “start” pulse to start a counter that times out based on the coordinates from the mouse controller. ¦It also has an antenna input and a coin counter output, which I ignore. Alcorn’s comments about the upper range of the paddle timers suggest that it would be worthwhile to have a more careful understanding of exactly the low and high ranges of the paddle timers; in my current design, they are su›cient to make the game playable, but may provide a wider range of motion than the original game. ere are two more ¢¢¢ timers in Pong: one that sets the duration of the “score” sound, and one that controls the serve delay. Each are congured as digitally triggered one-shots whose period is set by §h networks. To emulate these, I created digital counters whose delays roughly match those of the ¢¢¢’s. I did not attempt to match the delays precisely because of Pong’s use of low-tolerance components (an §h network with an electrolytic capacitor) and because they do not drastically ašect game play. ì Conclusions It was great fun going through and understanding the circuitry of the original Pong in such detail, although it took far longer to redraw the schematics and write about them than I expected. e €£Z reconstruction was easier since someone else had already digitized the schematic, but it was still puzzling at times, largely because of timing anomalies arising from imperfectly synchronous behavior. e use of a £«/ó mouse as a controller is unsatisfactory, although it could be reasonable if there was a convenient way to remove and separate the two optical interrupters. Acknowledgements I must thank Andrew Welburn [Õä], who subjected his own Syzyzy Pong board to a logic analyzer to verify my hypothesis about the horizontal timing, the delays of the various ¢¢¢s on the board. He also pointed out value of the ¢K pots, supplied photos, conrmed my observation about the odd wiring around Zä, and conrmed my reconstruction exhibited many of the same odd behaviors as the original. References [Õ] Allied Leisure Industries, Inc., ó¦¢ West ߦth Place, Hialeah, Floria ììþÕþ. Allied’s Paddle Battle Parts & Wiring Catalog, ÕÉßì.

[ó] Atari, Inc., Õ¦äþþ Winchester Boulevard, Los Gatos, California. Pin Pong Operation and Maintenance Manual, ÕÉߦ. Part Number TM-þþß.

[ì] Atari, Inc. Space Race Service Manual, ÕÉßä. Part number TM-þþ˜. Schematics dated ˜/¢/ߦ.

[¦] Dan Boris. Dan boris’ tech blog. Online, óþþß. http://www.atariage.com/forums/ blog/52-danboris-tech-blog/.

[¢] Nolan K. Bushnell. Video image positioning control system for amusement device. US Patent ì,ßɦ,ì˜ì, February ÕÉߦ.

[ä] Brian Deuel. Interview with Al Alcorn. Online, óþþþ? http://atari.vg-network. com/aainterview.html.

[ß] Stephen A. Edwards. Retrocomputing on an FPGA. Circuit Cellar, óìì:ó¦–ì¢, December óþþÉ.

[˜] Mike Johnson et al. €£Z arcade. Online. http://fpgaarcade.com.

[É] Nicola Salmoria et al. “Z“u: e multiple arcade machine emulator. Online, ÕÉÉß–. http://mamedev.org.

[Õþ] James . Advertisement. Byte Magazine, Õ(Õ):˜ì, ÕÉߢ. An SNߦÉìN was gþ.˜ó; an SNߦÕäÕN was gÕ.¦¢.

[ÕÕ] Steven L. Kent. e Ultimate History of Video Games. Prima Publishing, óþþÕ.

[Õó] Nutting Associates. Two-Player Computer Space Trouble-Shooting Guide, April ÕÉßì. Nolan K. Bushnell, Chief Engineer.

[Õì] Cam Shea. Al alcorn interview. Online, March óþþ˜. http://retro.ign.com/ articles/858/858351p1.html.

[Õ¦] Texas Instruments. e TTL Logic Data Book, Õɘ˜.

[Õ¢] William Arkush (uncredited). e Textbook of Logic, volume I. Kush N’ Stuš Amusement Electronics, äþ Dillon Avenue, Campbell, California, ÕÉßä.

[Õä] Andrew Welburn. Andys-arcade. Online. http://www.andysarcade.net.