Task: Combining Redefined Characters Sets and Player-Missile Graphics in BASIC
Time: 30-60 minutes
It takes time to learn the ins and outs of Atari graphics. This is especially true if you aspire to make a game. I have previously demonstrated how to make a playfield using redefined character sets and later provided an example for Halloween. I also previously demonstrated how to make and move a player around the screen using player-missile graphics (PMG). I recommend reading these previous posts first. For this project, I combined the two to provide a custom playfield with a player that can be moved around on top of it. The PMG demo I did before created a player that looked like Darth Vader’s tie fighter. I stuck with that theme and created a playfield consisting of the Death Star (pre-destruction) and a few stars to complete the space scene. I created the custom character sets for the Death Star very much like I did for the pumpkins in the Halloween demo mentioned above using letters A through J in a 4×4 grid.
It is interesting to work through the popular Atari books that go through all the methods for creating graphics. Something I noted is that they present each example independently of the others and rarely combine them into one demo or game. The ones that do combine them fail to provide key comments on how all the pieces work together. For example, it is often the case that page 6 of memory (address 1536) is used to place the machine language code used to make loading the characters set or moving players faster. What happens if you have several graphics elements that need machine learning code? Page 6 only has 256 bytes (i.e. one page). This is not enough to store more than one or two sets of code. In the example here, I first load in and execute the character set move code I need. Since I am only loading it once, I can use page 6 later for the fast player movement code. I simply overwrite the first set of machine learning code with the second set. If you need both, you will need to find another place in memory for the second or third sets of code. The best solution is to store your code in strings as BASIC will automatically place them in memory and keep track of the address. As a side note, you might wonder how the Atari knows when the end of the machine language code has been reached. There is an RTS instruction in the code that is the queue for the Atari that it has reached the end. The decimal code for RTS is 96. You will see this at the end of the data statements for the machine learning routines.
The other consideration I had was reserving memory for both the character set (which is moved from ROM to RAM for modification) and the PMG. I need four pages or 1024 bytes for the full character set. This is handled by moving the top of memory (MEMTOP) down by four pages thus freeing up that space above for the character set. We tell ANTIC that this is the new top of memory. We call this new address GRTOP in the code because just below is where the screen GRaphics and the display list are automatically stored by the Atari. Since we are using Graphics 2+16 we only need 420 bytes for the screen memory and another 24 bytes or so for the display list. So, the screen graphics only take up about two pages (i.e. 512 bytes). Higher resolution graphics will take up more.
The next thing we need to do is reserve memory for the PMG. Since we are using single-line resolution we need to reserve 2K bytes or eight pages of memory. The first half of this (four pages) will be unused in our example, The second half is where the player data is stored (one page for each of the four players = four pages). So, we need to go backward from GRTOP to reserve the PMG memory but, in doing so, need to leave room for the screen graphics. Some references suggest reserving 16 pages for PMG to allow eight pages for the screen graphics along with the eight pages required by PMG for single-line resolution. The tricky party (there is always a tricky part!) is that the start of PMG needs to fall on a memory address that is a multiple of 2048 bytes! Sheesh. So, we went back four pages for the character set and another 16 pages for the PMG. This is 20 pages total. Unfortunately, 20 * 256 is 5120 which is not a multiple of 2048. We have a choice to make. We could reserve more than we need for PMG or just enough for our graphics mode of 2+16. The advantage of the latter choice is that it will leave more memory for our BASIC program. This could be important for big game or program. The disadvantage is that we might have to change the code if we decide to use a higher resolution graphics mode. I took the first option and reserved more than I needed with 20 pages for PMG. This makes 24 total (24 * 256 = 6144) with the character set which is a multiple of 2048 (6144 / 2048 = 3).
I provide below the code and a heavily commented version of the code that I hope is instructional.
The following instructions are for running the example PM code in the Altirra emulator. You can of course type the code in by hand and run it on original hardware with BASIC or boot the ATR file and load the BASIC file using SIO2PC. You could also load it from a flash device. Here is the text file. Here is a zip with the ATR file. Here is a heavily commented version of the BASIC code. Note that it runs much better on original hardware. There is a slight delay for the drawing of the playfield and then again for the player to show up.
Open Altirra and load BASIC. I used Turbo BASIC XL. You can also load the built-in BASIC from Altirra from the File->Attach special cartridge menu.
Open the BASIC code in your PC text editor or web browser and copy the text to your clipboard. Click on the View tab of Altirra and choose the paste text option from the bottom of the list. Altirra will slowly paste the text into the BASIC command line. It is important to keep focus on the Altirra window or the paste will stop and it will lose some characters.
I learned a number of new things going through this exercise. Putting multiple graphics elements together presented some new challenges that I had not encountered when doing each individually. I hope this post makes it easier for you to see how redefined character sets and player-missile graphics can be combined. A next step would be to add a custom display list or take advantage of the display list interrupt. I was excited to put these pieces together. I can see the beginnings of the code needed to make a game in BASIC.