The heart of Pong, and any of the discrete logic games is the horizontal and vertical counter. These counters continuously step through each horizontal and vertical position on the screen. The output of the counters is fed to all the other logic of the game which ultimately determines if each pixel should be on or off (or what color it should be in the case of color graphics).
Everything begins here
This is the main clock generator in Pong. The crystal (which
The vertical sync circuit works similar to the horizontal sync circuit. Again we have an RS flip-flop composed of two logic gates (F5), but this one is triggered by a high instead of a low. At the end of the vertical count, V RESET will go high, which will set VBLANK high which indicates the start of the vertical blank period. When the vertical counter reaches 4, the output of G5 will go low which is the vertical sync signal. When the count reaches 8, 8V goes high, the output of H5 goes low whic
The next section I am going to talk about is the score generation circuit. In Pong, each player has a two digit score that is displayed at the top of the screen on either side of the net. The circuit that generates the score display is a little complex, but I find it to be a very interesting design. I am going to start from the center of the circuit and work out.
At the heart of the score generator is as 7448 BCD to 7-segment decoder chip.
This chip is usuall
This is the final section of the score generation circuit, which I call the segment decoder. For each point on the screen, this circuit determines which of the seven digit segments should be enabled.
The segment outputs from 7448 are labeled ‘a’ through ‘g’ and go into the three input NAND gates (C4, D4, D5). Each of these outputs corresponds to a segment of the score as follows.
The other two inputs to each NAND gate will go high when the corres
We have almost looked at the entire Pong circuit, just a few miscellaneous sections to go. This is the server timer circuit
2puck.zip
During normal play the output of F4, /RUN and STOP G will all be low which will make the output of E5 high, which will keep the SERVE output of B5 low. When the ball is missed, /MISS will go low, pin 6 of E6 will go high which resets the ball speed counter. Pin 3 of E6 will then go low which triggers the 555 timer and sets the output high, and sets the o
The next thing I want to talk about is the attract mode, which is the mode the game is in when it’s not being played, designed to “attract” new players. Most of the schematics for this section I have posted already, so I will just describe how attract effects each section. The attract signal is generated by the game control circuit and is fed as both an active high and active low signal to various other circuits in the game.
In the paddle circuit, /ATTRACT holds the preset pin of flip-flop
Looks like we have finally come to the last Pong circuit we need to cover. I just looked back at the archive for this blog and was shocked when I realized that I have been doing this Pong circuit description for almost 2 years! I know I was going through this pretty slowly but never realized I had taken that long. On to the final circuit...
This circuit is used to generate a sound whenever the ball hits the top or bottom of the screen. During normal play /SERVER is high so the flip/flo
Occasionally questions come up about the special “hidden” control register in the 7800, and I usually end up searching back through the forum archive for the answer, so I thought I’d finally document it somewhere I can find it!
The purpose of this control register is to switch the 7800 from 7800 mode to 2600 mode. The register can be written to using any address between $0000 and $001F. This address range overlaps the TIA so once the register is set you need to set the lock bit (see below) b
I’ve recently been doing some research into how scrolling games work on the 7800. I have created a demo program that shows a method for doing horizontal and vertical fine scrolling controlled with the player one joystick. I’ve tested this program on an emulator but on the actual hardware. The attached ZIP files contains the source and binary that can be used with an emulator.
Display List
The display list for the demo consists of 24, 8 line high regions. Each region will display 41 chara
Next let’s look at some simple byte variable manipulation. Here is the first sample Action program:
BYTE I
PROC MAIN()
I=1
I=I+2
RETURN
And the assembly code
24B3: .byte $00
24B4: JMP $24B7
24B7: LDY #$01
24B9: STY $24B3
24BC: CLC
24BD: LDA $24B3
24C0: ADC #$02
24C2: STA $24B3
24C5: RTS
This code starts at memory location $24B3 which is where the global variable I is stored. Next we have a jump instruction that gets us to the MAIN procedure. Like
One of the trickier parts of the 7800’s MARIA graphics chip is understanding how to setup the display lists and display list list (DL and DLL). Even trying to put a single sprite on the screen can be tricky. In this article I will explain how to setup these data structures to get a simple sprite on the screen.
In this example we will take a very narrow scenario just to explain the basics of how to get a sprite on the screen. I will show how to display a single 16 line high by 1 byte wide spr
I can’t believe it’s been over a year since my last blog post, time sure does fly! I thought it was about time to get back to some posts and continue my Action! language topic.
Last time I talked about BYTE math, this time we will start looking at CARDinal math. In Action the CARD data type is a two byte unsigned value. Here is the first piece of Action! code:
CARD I
PROC MAIN()
I=1
I=I+1
RETURN
Here is the resulting disassembly:
0E6A: .BYTE #$00,#$00
0E6C: 4C 6F 0E J
In my last post I showed how the Action! compiler produces some pretty optimized code for CARD math under certain circumstances. This time I will show the more general case which should be pretty familiar to anyone who has done 6502 programming.
Here is the Action! program and it’s dis-assembly:
CARD I
PROC MAIN()
I=2
I=I+2
RETURN
0E6C: .BYTE 00,00
0E6E: 4C 71 0E JMP $0E71
;I=2
0E71: A0 00 LDY #$00
0E73: 8C 6D 0E STY $0E6D
0E76: A9 02 L