In the first part of this series, we kicked everything off with a nice sample project in which we displayed hello world using the NES. However, the majority of this code was written for us, and was really hidden away. The real goal of the last post was to get our tools setup before we start actually writing code, using the sample code only to confirm our tools are working. Thus, for this next post, we’re instead going to focus on writing our own entire project! A lot of this was put together with help from the NesDev Wiki, so make sure to check that out as well!
Let’s start with getting an understanding of the hardware we are working with: One of the big appeals of working with the NES these days is that it is incredibly simple to work with compared to modern systems in many ways. This ultimate starts with its main chip: The 6502 chip. This chip is super simple, and is where we will be doing the majority of our work in assembly code. To that end, I’d highly recommend brushing up on your assembly, and maybe going over this tutorial before continuing on. All of these posts are going to be in assembly, so if you’re really out of practice like I was before this, it’ll be helpful to do some reviewing. The 6502 chip used in the NES is documented pretty well here on NesDev: It’s got only a handful of registers and Opcodes (all of which you can view here), and is relatively slow at just 1.78 MHz. For comparison, modern CPUs run at well over 3.5 GHz, an order of magnitude about 2000x faster. We do not have a lot of power here, and as a result, every cycle counts. The Opcode documentation linked previously is great because it actually tells us how many cycles each call will take, something that we will need to carefully watch over as we build our game.
So, what do we need to do to get a hello world running with our own code? Unfortunately, the NES Picture Processing Unit (PPU) takes quite a bit of work to setup for something as simple as displaying text, and thus we really don’t want to do all of that work just to confirm we’ve initialized everything properly. The Audio Processing Unit (APU) however, is very simple, and we can play some simple tones with very minimal work. Thus, we will instead use this to confirm our hello world application is working now instead. If you want to see the final code right away, you can check it out at this…