6502 assembly
introduction
The assembly language is a low-level processor centric programming language. We focus our interest on the human-readable 6502 processor and assembly, as opposed to x86 assembly language which is much less intelligible. This guide is meant to collect our resources to help you write projects for the classic Nintendo Entertainment System.
This is the language we used to create Donsol.
cookbook
We have assembled a collection of example projects to help you better understand the ecosystem, and we have created a spritesheet and nametable editor called Nasu.
basics
- Bit: The smallest unit in computers. It is either a 1 or a 0.
- Nibble: Half a byte, or 4 bits.
- Byte: 8 bits together form one byte, a number from 0 to 255. Bits in the byte are numbered starting from the right at 0.
- Short: Two bytes put together is 16 bits, forming a number from 0 to 65535. The low byte is the rightmost eight bits.
- Hex Number: A HEX number consisting of 4 numbers is 16-bit.
registers
The 6502 handles data in its registers, each of which holds one byte(8-bits) of data. There are a total of three general use and two special purpose registers:
- A: The accumulator handles all arithmetic and logic. The real heart of the system..
- X&Y: General purpose registers with limited abilities..
- SP: The stack pointer is decremented every time a byte is pushed onto the stack, and incremented when a byte is popped off the stack..
- PC: The program counter is how the processor knows at what point in the program it currently is. It’s like the current line number of an executing script. In the JavaScript simulator the code is assembled starting at memory location $0600, so PC always starts there..
- PF: The Processor flag contains 7 bits, each flag live in a single byte. The flags are set by the processor to give information about the previous instruction. More on that later. Read more about the registers and flags here..
architecture
- ROM: Read Only Memory, holds data that cannot be changed. This is where the game code or graphics is stored on the cart..
- RAM: Random Access Memory, holds data that can be read and written. When power is removed, the chip is erased. A battery can be used to keep power and data valid..
- PRG: Program memory, the code for the game.
- CHR: Character memory, the data for graphics.
- CPU: Central Processing Unit, the main processor chip.
- PPU: Picture Processing Unit, the graphics chip.
- APU: Audio Processing Unit, the sound chip inside the CPU.
directives
Directives are commands you send to the assembler to do things like locating code in memory. They start with . and are indented. This sample directive tells the assembler to put the code starting at memory location $8000, which is inside the game ROM area.
The label is aligned to the far left and has a : at the end. The label is just something you use to organize your code and make it easier to read. The assembler translates the label into an address.
The opcode is the instruction that the processor will run, and is indented like the directives.
The operands are additional information for the opcode. Opcodes have between one and three operands.
Comments are to help you understand in English what the code is doing. When you write code and come back later, the comments will save you. You do not need a comment on every line, but should have enough to explain what is happening. Comments start with a ; and are completely ignored by the assembler. They can be put anywhere horizontally, but are usually spaced beyond the long lines.
.org $8000 ; directive MyFunction: ; label LDA #$FF ; opcodes operands JMP MyFunction