|
Our software for this project not only includes the Battleship game itself, but also software routines to check NES controller input and send and receive Ethernet packets. We also had dedicated software libraries of data or assembly calls, used to display different sprites on the VGA screen.
Main Game
The main game consists of two parts: a main initialization routine and the Battleship game itself. The main initialization is written in assembly and is used to initialize the timer interrupts for the NES controller, as well as initialize the MPC823’s SCC2 serial controller to work in Ethernet mode. The main routine also checks one slide switch to tell it whether its station is acting as the slave or master for a game (The master is simply the player that attacks first, but this information is also used to initialize the Ethernet controller and determine the MAC addresses for each of the stations). The main function then branches to the game itself.
The game is essentially all the logic used to implement the actual game of Battleship in C code. It checks controller inputs, looks for and sends Ethernet input and output data, and does software calls to display sprites on the VGA screen.
Sprite Libraries
The graphical sprites we used in this project were split into two different groups: those that were part of the user interface (used to display text, button layouts, and enemy ships sunk), and those that appeared on different squares of the game boards (the cursor, ship segments, and attack “pegs”).
At the hardware level, we only created functions in software that could clear the game board, clear a board square, or write a pixel of a certain color to an X,Y coordinate on the screen. To display sprites to the VGA screen, we had to write large sequences of pixel-writing calls to the hardware. These sequences of code were either pure assembly instructions (used for speed and displaying the user interface sprites, since we could hard-code their locations in assembly), or sequences of halfwords that were placed in memory and decoded on-the-fly (used for space efficiency and for sprites that had to appear in different squares, where we had to specify coordinates). We made these sprites as bitmaps in Photoshop, used a third-party program to translate these bitmaps into pixel arrays, and we created a C++ program to turn these arrays into either assembly calls or formatted halfwords. Whenever we needed to display a sprite, we either branched to an assembly function that would do direct calls to hardware to draw pixels, or we branched to a C function that would decode halfwords and draw pixels at appropriate points on the screen.
SCC2 Controller (in Ethernet mode)
The SCC2 is the main serial peripheral microcontroller on the MPC823 board, and is responsible for driving everything that requires serial communication. In order to use Ethernet on the board, we had to set up the SCC2 to work in “Ethernet mode”, so it could communicate through the Ethernet jack on the board via standard 10 BASE-T Ethernet protocol. In order to set the microcontroller up, we had to write a lengthy initialization routine that set the correct SCC2 parameters for Ethernet mode and gave the master and slave board unique MAC (media access control) addresses on the network. We had specialized sending and receiving functions in C used to send minimal Ethernet packets with information about which squares a player was attacking, or any special actions he or she wanted to do. These functions would only respond to the MAC address of the other player’s board, so we could connect the boards to the university network and they would ignore any traffic not meant for them and could still play against each other!
One of the main problems of Ethernet communication is that it is a very lossy protocol, and there is a very good chance that packets sent over Ethernet won’t make it to the other machine. To address this, we had to create a sequence numbering scheme that would assign every transaction a unique number that the recipient would expect to see. If the recipient didn’t see a packet with the number it expected, it would ask the other machine to send it again and wait until it successfully got the packet it was looking for. It would then acknowledge to the other machine that it got the packet.

|