As I have mentioned previously on this blog, one of my most favourite games of all time is the 1989 classic Snake Rattle 'n' Roll, brought to us by a very young Rare. I fondly remember playing it as a child, and thinking to myself, "Wow, video games are awesome. When I grow up, I am going to make video games for a living." This was a far more pragmatic choice than the average eight-year-old, who imagines being an astronaut, or a cowboy, or a dinosaur when they grow up.
Nowadays, twenty-seven years later, I still say the same thing: when I grow up, I fully intend to make video games for a living. In the meantime, I study the works of the Old Masters carefully, to see how they worked within the limitations of their time, and I find their works fascinating. Regular readers of this blog have already seen the results of this study in the Tileset series I wrote at the inception of this blog. This post marks the first in a series exploring the gritty details, nuts and bolts of the audio module for Snake Rattle 'n' Roll.
Producing this series required many hours of poring over documentation to gain skills that are practically lost to developers today. The excellent 6500 Programming Manual is the go-to source for the NMOS 6502 microprocessor. Knowledge of 6502 assembly programming (or, more specifically, 6502 disassembly) was instrumental in understanding the Snake Rattle 'n' Roll cartridge, as the NES uses a modified 6502 microprocesor: the 2A03 microprocessor manufactured by Ricoh. The wiki at NES DEV was likewise indispensable for its details on the NES architecture, filling in the gaps left behind once the assembly code was understood. For tools, I cannot recommend Nintendulator highly enough: it is by far the most accurate NES emulator available today, and its debugging capabilities were invaluable in producing this document.
This series will not go into the details of how I reverse-engineered the audio module. I thought about including information on my techniques, but opted against it on the grounds that it would make the series much less accessible to the lay reader. If you are sufficiently inclined, you can take the linked resources above and a copy of the Snake Rattle 'n' Roll ROM dump (or another game of your choice), and start working backwards with liberal use of breakpoints in Nintendulator. If you do decide to embark on this path, drop me a line and let me know what you find. I would be keenly interested to know if other games have a similar audio module; I have an untested theory that NES development kits (if they even existed) may have included a boilerplate audio module that developers could leverage, similar to (but much more simpler than) the audio modules in today's consoles.
Let us begin the series, then, by heeding the advice from the novel Dune to "take the most delicate care that the balances are correct", and define some terminology for use in later installments of this series. Snake Rattle 'n' Roll has nine 'songs': the audio you hear in the background while you are playing, according to the following list:
Song Number | Song Name |
---|---|
0 | Level 1 |
1 | Levels 5 and 8 |
2 | Levels 6, 9 and 10 |
3 | Level 2 |
4 | Level 3 |
5 | Levels 4 and 7 |
6 | Time Out |
7 | Game Over |
8 | Main Titles and End Credits |
Each song is composed of four 'tracks', and each track provides the data for one of the four audio channels present in the NES Audio Processing Unit (APU), according to the following list:
Track Number | APU Channel |
---|---|
$0 | Pulse 1 |
$4 | Pulse 2 |
$8 | Triangle |
$C | Noise |
Throughout this series, I will adopt the 6502 convention of writing hexadecimal numbers with a leading dollar sign, as in $DEADBEEF, as opposed to the more modern convention of using '0x', as in 0xCAFEBABE. It may seem odd that I have numbered the song tracks incrementing by four instead of by one; my reasoning will become apparent in later posts.
To continue the cassette metaphor, the data for each track are stored in a 'tape'. A tape consists of a sequence of 'messages'. Some of these are 'control messages', which alter how the audio module interprets the bytes in the tape. Some of these are 'effect messages', which alter how a given note will be played by the APU channel. Most of these are 'note messages', which tell the audio module to emit a note to the APU channel. A large portion of the audio module handles reading of tape bytes, interpreting the messages, and processing them.
The audio module supports many 'effects', as controlled by effect messages. These are:
- Sound effect rate-limiting control
- Direct control of APU channel values
- Applying vibrato to a note
- Applying a slide effect to a note, dropping its pitch
- Applying a crescendo or decrescendo to a note's volume
- Shifting the pitch of the notes in a song
- Adjusting the tempo of a song
The APU channels do double-duty, playing both the background music and sound effects while the game is being played. You can observe this while playing, noting that while a sound effect is being played, parts of the background music are not heard. This is not unique to Snake Rattle 'n' Roll: most NES games had the same limitation, although there were a few that included additional audio processors in the cartridge itself to produce richer audio than the basic system provided. The audio module for Snake Rattle 'n' Roll supports playing sound effects over the background music, while remembering where in the music it is so that it can continue playing the song once the effect ends.
In the next post in the series, we will find where on the cartridge the track tapes are located.
No comments:
Post a Comment