![]() |
HardwareIn order to provide something for the Nintendo Controllers to plug into, a NES Four Score (See Picture) was deconstructed and had all its guts ripped out and replaced. An old cable was sacrificed to provide the plug so the new and improved NES Four Score could plug into PORTB. Pin PB7, in conjunction with Timer2, is used to generate sound effects on par with a PC speaker.
The state of each of the eight buttons is shifted out from each controller through a single data line. All four controllers are read in unison by common Latch and Clock signals from the STK500. This means that four bits of information are read in every NES Clock Cycle. The only drawback is that the NES Controllers are not very shielded and get confused if they are clocked too fast. This limitation is discussed in the Time Management section below.

NES Controller Pinouto GNDVTG o o ClockNC o o LatchNC o o DataOut
0 |
NC |
Player 1 Data |
1 |
2 |
Player 2 Data |
Player 3 Data |
3 |
4 |
Player 4 Data |
Common Clock |
5 |
6 |
Common Latch |
Audio Buzzer |
7 |
8 |
GND |
VTG |
9 |
Pins 1-4 are Inputs
Pins 5-7 are Outputs

As anyone can guess, a game that does not maintain a relatively constant frame rate can become unnecessarily difficult to play. This can be especially difficult when a vast amount of the processors resources are going towards updating the TV Screen. So, how do you write a game with so many moving objects to keep track of and render? Only updating objects when they move can both cut down on flicker and save CPU cycles, but now each frame takes more or less time to render depending on how many objects are moving, resulting in jerky game play. Nevertheless, there is also a more demanding task: that of shifting in the key commands from the NES Controllers. The controllers will wait forever, but they hate to be rushed, and they need to shift-in in their entirety every frame. In fact, it takes no less than 16 steps to shift in all 8 buttons. So, Timer0 was used to divide each frame up into 16 time slices, and after each time slice the NES controller code will execute and then the next time slice in a round-robin fashion. All tasks that were to be performed would be divided up and squeezed into a single time slice as you can see in the Figure on the Left. A complete listing of the task to be performed by each time-slice is shown below. The next problem is that some tasks can take longer than the single time-slice it was allotted. The most obvious cause of this would be an interruption by the STIGLitz renderer (See Recovery Time-Line Below). When this occurs, rather than cutting the interrupted task short and interrupting functionality, it will resume and finish normally, but will have missed the overflow of Timer0. Inserting short or “Free” tasks among the time-slices provides an outlet for time-slice violation. In the Recovery Time-Line below, Task 0 completes normally, but Task 1 is interrupted by STIGLitz and violates its time-slice. Luckily, Task 2 is a “Free” slot and completes early enough to restore normal operation.

|
Time Slice |
Task |
|
0 |
Move Player 3 Paddle Right |
|
1 |
Free |
|
2 |
Erase Ball 0 |
|
3 |
Execute Ball 0 Physics |
|
4 |
Draw Ball 0 |
|
5 |
Free |
|
6 |
Erase Ball 1 |
|
7 |
Execute Ball 1 Physics |
|
8 |
Draw Ball 1 |
|
9 |
Free |
|
10 |
Move Player 1 Paddle Up |
|
11 |
Move Player 2 Paddle Up |
|
12 |
Move Player 1 Paddle Down |
|
13 |
Move Player 2 Paddle Down |
|
14 |
Move Player 4 Paddle Left |
|
15 |
Move Player 3 Paddle Left |
|
16 |
Move Player 4 Paddle Right |
The only modification needed for the STIGLitz code was to free up PORTB so I could have a place to plug in the NES Four Score. PORTB was previously being used to output debug information from several places throughout the code. The following files needed to be modified to complete this task: glib.h, glib.c, sddl_int.int.s, sdhl_int.int.s. All other code written by me can be found in main.c.
STIGLitz with all modification and code for GPong can be downloaded from here: http://nekkid.homeip.net/GPong/GPong.zip
PORTF currently handles all debugging signals from my code. During controller detection is output the status of the four controller ports: on for detected, off for not detected. During the configuration screens, it displays the status of the select-buttons from all detected controllers: on for pressed, off for not pressed, LED0 for Player 1, LED1 for Player 2, etc. This can be useful if you are trying to determine which player your controller is plugged into. While the game is running, even while paused, it is displaying the number of time-slice violations per frame. If all four lights are on often, then the system is hopelessly un-schedulable with the current load and the frame rate will rise and fall accordingly.
Useful Links
E-Mail the Author, Gregory Parsons: gsparson@eos.ncsu.edu
Author’s Web Site: http://www4.ncsu.edu/~gsparson/
STIGLitz Web Site: http://www.cesr.ncsu.edu/agdean/stiglitz/index.htm