Starting off with:
Also helpful: http://wiki.nesdev.com/w/index.php/Before_the_basics
NES development is very close-to-the-hardware. It is very important to be comfortable converting from everyday decimal system numbers to binary and hex.
One of the best calculators I have seen is CALC-P for android. I love its interface since it has keys separated for decimal, hex, and binary.
Everyone uses the decimal system in their day to day.The decimal system is base 10. Every digit can be 0-9. Each digit place is a power of 10. Each digit place to the left is 10 times more than the previous digit place. If you take the number 10 and put a 0 to the right, it becomes 100 which is 10 times more. Remove the 0 from the right, it becomes 1 which is 10 times less.
|100’s place||10’s place||1’s place|
To get the value of a number, you multiply each digit by it’s place value and add them all together.Ex. 249 = 2*100 + 4*10 + 9*1 = 249
Binary is different.
Everything in computers is done in base 2, binary. This is because the lowest level of computing is a switch; on/off, 1/0.
( See my post where I build a virtual CPU from nothing but these “switches”.)
Base 2 binary works the same way, except each digit can be 0-1 and the place values are powers of 2 instead of 10. Insert a 0 to the right of a number and it becomes 2 times bigger. Remove a 0 and it becomes 2 times smaller.
We dont have the luxury of symbols like 3 with its curvyness and looking all kinda like a rounded backwards capital E to denote that I have three apples. I have only ON or OFF, 0 or 1, or 0 and X. Lets see if I can take the numbers from earlier.
We can use hexadecimal for our NES, which is a little bit easier to understand and work-with instead of binary, but that’s a topic for later. Lets focus on working in binary for now.
|256’s place||128’s place||64’s place||32’s place||16’s place||8’s place||4’s place||2’s place||1’s place|
Eventually you become fast at reading binary numbers, or at least recognizing patterns. You can see that one byte can only range from 0-255. For numbers bigger than that you must use 2 or more bytes. There are also no negative numbers. More on that later.
The NES is an 8 bit system, which means the binary number it works with are 8 binary digits long. 8 bits is one byte. Some examples are:
00000000 = 0
00001111 = 15
00010000 = 16
10101010 = 170
11111111 = 255
By modern standards, 8-bit computers are EXTREMELY limited. Heck, they were considered pretty limited even in their time. Your laptop is probably a 64-bit system, meaning lots of things, one being that you can install a LOT of ram into it, enabling you to run more programs simultaneously and smoothly. You probably have about 8 Gigabytes of ram at this very moment, and if you had the cash (and the manufacturers made it for your computer) you could install TERABYTES of ram and your system could make use of it.
If you are my age (35 here in 2019), then you probably had a slightly older laptop or desktop around your high school and college years. It probably ran Windows XP or MacOS-9. You probably didn’t have wifi internet, but you could plug in to a wall. You could have Microsoft Word, Adobe Photoshop, Netscape, a DVD player, and AOL Chat all open at once…but…all of these computers were about to hit a major wall. They were all 32 bit systems… meaning the maximum RAM accessable to most of them was capped at just 4GB. You could survive with 4GB ram today, but not very well.
The nintendo is far far more primitave. It is a small computer on par with the Apple 2, the commodore 64, and some of the earliest DOS computers.
The “next step up” from decimal notation for our purposes would be hexadecimal. Hexadecimal or Hex is base 16, so each digit is 0-15 and each digit place is a power of 16. The problem is anything 10 and above needs 2 digits. To fix this letters are used instead of numbers starting with A:
0 = 0
1 = 1
9 = 9
10 = A
11 = B
12 = C
13 = D
14 = E
15 = F
Hex is largely used because it is much faster to write than binary. An 8 digit binary number turns into a 2 digit hex number:
split | |
in half / \
into | |
hex 6 A
put \ /
01101010 = 6A
Binary Hex Decimal
00000000 = 00 = 0
00001111 = 0F = 15
00010000 = 10 = 16
10101010 = AA = 170
11111111 = FF = 255
For easy converting open up the built in Windows calculator and switch it to scientific mode. Choose the base (Hex, Dec, or Bin), type the number, then switch to another base.
When the numbers are written an extra character is added so you can tell which base is being used. Binary is typically prefixed with a %, like %00001111. Hex is prefixed with a $ like $2A. Some other conventions are postfixing binary with a b like 00001111b and postfixing hex with an h like 2Ah.
The NES has a 16 bit address bus (more on that later), so it can access 2^16 bytes of memory. 16 binary digits turns into 4 hex digits, so typical NES addresses look like $8000, $FFFF, and $4017.
Core Programming Concepts
All programming languages have three basic concepts. They are instructions, variables, and control flow. If any of those three are missing it is no longer a true programming language. For example HTML has no control flow so it is not a programming language.
An instruction is the smallest command that the processor runs. Instructions are run one at a time, one after another. In the NES processor there are only 56 instructions. Typically around 10 of those will be used constantly, and at least 10 will be completely ignored. Some examples of these would be addition, loading a number, or comparing a variable to zero.
A variable is a place that stores data that can be modified. An example of this would be the vertical position of Mario on the screen. It can be changed any time during the game. Variables in source code all have names you set, so it would be something like MarioHorizPosition.
Normally your instructions run in sequential order. Sometimes you will want to run a different section of code depending on a variable. This would be a control flow statement which changes the normal flow of your program. An example would be if Mario is falling, jump to the code that checks if he hit the ground yet.
The Ricoh 2A03 CPU (eh, its close enough to the 6502, so for easier learning and understanding, lets call it a 6502 from now on, just remember it doesn’t have decimal mode) is an 8-bit CPU. This thing isn’t very powerful. Runs at about 1.5 MHz. 8-bit CPU’s use an 8-bit data bus and can therefore access 8 bits of data in a single machine instruction.
Now the thing about 8 bit cpu’s, if you built a computer with a matching 8-bit ADDRESS bus, the maximum amount of RAM that the computer could use is. like, 0.255KB… even in the 60s that would be nearly useless.
So 8-bit computers, while only having 8-bit data buses, will usually have a 16 bit address bus, so with that, the max amount of ram available to such a setup is 64KB (which is the case with the commodore 64 setup)
So as you can see, theoretically the 8-bit cpu should only be able to address 0.255KB, but some effort and engineering gets us to 64K. In fact, further engineering lead to higher amounts of Ram addressable, but the tricks ran out eventually.
…the later 16-bit cpu’s could address 64K out the gate, but with further engineering, most 16-bit computers crossed that threshold by a great amount.
…now with the 32 bit era,, there were not as many tricks to employ, that and some enterprising manufacturers and corporations might have detected an opportunity to productize a built in feature. Most consumer computers COULD have addressed more than 4GB ram if a bit of engineering was introduced….but most consumers did not opt for it since its now for better or worse, more expensive to do so and the engineering is now only available for select product lines… So most folks were stuck at max 4GB until 64bit cpu’s and OS’es hit the market.
This week: general overview of the NES architecture with the major components covered. All general purpose computers are arranged the same way with a place to store code (ROM), a place to store variables (RAM), and a processor to run code (CPU). The NES also adds another processor to generate the graphics (PPU) and a section of the CPU to generate audio (APU). Everything here is very general and will have more details than you want in the next few weeks.
| TV | |xx xx xx xx x |
+–^-+ |xx xx xxx |
| | NES D-PAD 1 x |
| | +—-+ | |
|+-+-+ |APU | | +——-+|
|| | |—-| | |LOCKOUT||
||PPU<----+ | | +---^---+| NES |+-^-+ |CPU <---+ | | | | +--^-+ | | +--|---------|-----------|----+ | | | +--|---------|-----------|----+ | | | | | |+-+-----++--+-----+ | | ||CHR ROM||PRG ROM | +---v---+| ||or RAM || | |LOCKOUT|| CART || || | +-------+| |+-------++--------+ | |+-----------+ +------------+| ||WRAM (OPT.)|<-+BATTERY(OPT)|| |+-----------+ +------------+| +-----------------------------+