Syntax
Numbers
Binary, decimal, octal, hexadecimal, and ASCII character are all valid numbers.
| Base | Example A | Example B |
|---|---|---|
| Binary | %01000001 | 01000001b |
| Decimal | 65 | 65d |
| Octal | 0101 | 101o |
| Hexadecimal | $41 | 41h |
| ASCII char | 'A' |
Symbols
Mathematical Operators
| Symbol | Description |
|---|---|
| + | Add |
| - | Subtract |
| * | Multiply |
| / | Divide |
| ** | Exponent |
| & | Bitwise AND |
| | | Bitwise OR |
| ^ | Bitwise XOR |
| >> | Shift right |
| << | Shift left |
| % | Modulo |
Comparison Operators
| Symbol | Description |
|---|---|
| == | Equals |
| != | Not equals |
| < | Less than |
| > | Greater than |
| <= | Less than or equals |
| >= | Greater than or equals |
Special
| Symbol | Description |
|---|---|
| -> | Accessor (functions like +) |
Labels
Named
Named label declarations must be in the follow format:
NAME:
NAME- Label name, required.
Example:
LDX #$08
loop:
DEX
BNE loop
BRK
Output:
00000000 a2 08 ca d0 fd 00 |......|
00000006
Temporary
Temporary/un-named labels may also be declared by placing only a colon.
:
To jump to a temporary label, the direction of the jump must be given.
JMP :[+-]
[+-] - Direction, required.
A + direction means to jump to the temporary label that is further down in the
code.
A - direction means to jump to the temporary label that is further up in the
code.
Example:
LDX #$08
:
DEX
BNE :-
BRK
Output:
00000000 a2 08 ca d0 fd 00 |......|
00000006
Mnemonics
All 56 mnemonics are supported:
| Mnemonic | Description |
|---|---|
| ADC | Add with Carry |
| AND | Bitwise AND with Accumulator |
| ASL | Arithmetic shift left |
| BIT | Test bits |
| BCC | Branch on Carry clear |
| BCS | Branch on Carry set |
| BEQ | Branch on equal |
| BMI | Branch on minus |
| BNE | Branch on not equal |
| BPL | Branch on plus |
| BRK | Break |
| BVC | Branch on Overflow clear |
| BVS | Branch on Overflow set |
| CLC | Clear Carry |
| CLD | Clear Decimal |
| CLI | Clear Interrupt |
| CLV | Clear Overflow |
| CMP | Compare Accumulator |
| CPX | Compare X register |
| CPY | Compare Y register |
| DEC | Decrement memory |
| DEX | Decrement X register |
| DEY | Decrement Y register |
| EOR | Bitwise exclusive OR |
| INC | Increment memory |
| INX | Increment X register |
| INY | Increment Y register |
| JMP | Jump |
| JSR | Jump to subroutine |
| LDA | Load Accumulator |
| LDX | Load X register |
| LDY | Load Y register |
| LSR | Logical shift right |
| NOP | No operation |
| ORA | Bitwise OR with Accumulator |
| PHA | Push Accumulator |
| PHP | Push processor status |
| PLA | Pull Accumulator |
| PLP | Pull processor status |
| ROL | Rotate left |
| ROR | Rotate right |
| RTI | Return from Interrupt |
| RTS | Return from subroutine |
| SBC | Subtract with Carry |
| SEC | Set Carry |
| SED | Set Decimal |
| SEI | Set Interrupt |
| STA | Store Accumulator |
| STX | Store X register |
| STY | Store Y register |
| TAX | Transfer Accumulator to X register |
| TAY | Transfer Accumulator to Y register |
| TSX | Transfer Stack Pointer to X register |
| TXA | Transfer X register to Accumulator |
| TXS | Transfer X register to Stack Pointer |
| TYA | Transfer Y register to Accumulator |
Read more about 6502 opcodes here.
In addition, 24 illegal/undocumented mnemonics may be used when assembled with
the -u, --undocumented flag.
| Mnemonic | Description |
|---|---|
| AAC | AND with Accumulator |
| AAX | AND X register with Accumulator |
| ARR | AND with Accumulator |
| ASR | AND with Accumulator |
| ATX | AND with Accumulator |
| AXA | AND X register with Accumulator |
| AXS | AND X register with Accumulator |
| DCP | Subtract 1 from memory |
| DOP | No operation (x2) |
| ICS | Increase memory by 1 |
| KIL | Stop program counter |
| LAR | AND memory with stack pointer |
| LAX | Load Accumulator and X register |
| NOP | No operation |
| RLA | Rotate one bit left in memory |
| RRA | Rotate one bit right in memory |
| SBC | Subtract with Carry |
| SLO | Shift left one bit in memory |
| SRE | Shift right one bit in memory |
| SXA | AND Y register with the high byte of address |
| SYA | AND Y register with the high byte of address |
| TOP | No operation (x3) |
| XAA | Unknown |
| XAS | AND X register with Accumulator |
Read more about undocumented 6502 opcodes here.
Addressing Modes
| Mode | Example |
|---|---|
| Implied | RTS |
| Accumulator | ROL A |
| Immediate | LDA #$42 |
| Zeropage | STA <$42 |
| Zeropage, X | EOR <$42, X |
| Zeropage, Y | LDX <$42, Y |
| Absolute | STA $4200 |
| Absolute, X | EOR $4200, X |
| Absolute, Y | LDX $4200, Y |
| Indirect | JMP [$4200] |
| Indirect, X | LDA [$42, X] |
| Indirect, Y | STA [$42], Y |
| Relative | BEQ label |
Note
nessembleuses square brackets[]instead of parentheses()in its addressing modes because the latter are used to indicate precedence in mathematical operations.
Read more about 6502 addressing modes here.
Functions
| Function | Description |
|---|---|
| HIGH() | Get high byte of address |
| LOW() | Get low byte of address |
| BANK() | Get bank of address |
Pseudo-Instructions
| Pseudo-Instruction | Description |
|---|---|
| .ascii | Convert ASCII string to bytes |
| .byte | Alias for .db |
| .checksum | Calculate crc32 checksum |
| .chr | Set CHR bank index |
| .color | Convert hex color to NES color |
| .db | Define 8-bit byte(s) |
| .defchr | Define CHR tile |
| .dw | Define 16-bit word(s) |
| .else | Else condition of an .if/.ifdef/.ifndef statement |
| .endenum | End .enum |
| .endif | End .if/.ifdef/.ifndef statement |
| .endm | End .macrodef |
| .enum | Start enumerated variable declarations |
| .fill | Fill with bytes |
| .font | Generate font character tile |
| .hibytes | Output only the high byte of 16-bit word(s) |
| .if | Test if condition |
| .ifdef | Test if variable is defined |
| .ifndef | Test if variable has not been defined |
| .incbin | Include binary file |
| .include | Include assembly file |
| .incpal | Include palette from PNG |
| .incpng | Include PNG |
| .incrle | Include binary data to be RLE-encoded |
| .incwav | Include WAV |
| .ineschr | iNES CHR count |
| .inesmap | iNES mapper number |
| .inesmir | iNES mirroring |
| .inesprg | iNES PRG count |
| .inestrn | iNES trainer include |
| .lobytes | Output only the low byte of 16-bit word(s) |
| .macro | Call macro |
| .macrodef | Start macro definition |
| .org | Organize code |
| .out | Output debugging message |
| .prg | Set PRG bank index |
| .random | Output random byte(s) |
| .rsset | Set initial value for .rs declarations |
| .rs | Reserve space for variable declaration |
| .segment | Set code segment |
| .word | Alias for .dw |
.ascii
Convert ASCII string to bytes.
Usage:
.ascii "STRING"[(+/-)NUMBER]
"STRING"- String, required. ASCII string to turn into bytes. Must be within quotes.(+/-)NUMBER- Number, optional. Amount to increase/decrease ASCII values.
Example:
.ascii "When, in disgrace with fortune and men's eyes"
Output:
00000000 57 68 65 6e 2c 20 69 6e 20 64 69 73 67 72 61 63 |When, in disgrac|
00000010 65 20 77 69 74 68 20 66 6f 72 74 75 6e 65 20 61 |e with fortune a|
00000020 6e 64 20 6d 65 6e 27 73 20 65 79 65 73 |nd men's eyes|
0000002d
The +/- operators may also be used to increase/decrease the output.
Example:
.ascii "I all alone beweep my outcast state"-32
Output:
00000000 29 00 41 4c 4c 00 41 4c 4f 4e 45 00 42 45 57 45 |).ALL.ALONE.BEWE|
00000010 45 50 00 4d 59 00 4f 55 54 43 41 53 54 00 53 54 |EP.MY.OUTCAST.ST|
00000020 41 54 45 |ATE|
00000023
.checksum
Calculate crc32 checksum.
Usage:
.checksum LABEL
LABEL- Label, required. Label at which to start generating the checksum.
Example:
start:
LDA #$01
STA <$02
.checksum start
Output:
00000000 a9 01 85 02 b8 1f ee 86 |........|
00000008
The checksum is b8 1f ee 86.
Note
Checksums may only be performed on preceding data.
.chr
Set CHR bank index.
Usage:
.chr NUMBER
NUMBER- Number, required. CHR bank index.
Example:
.chr 0
Note
CHR banks are 2K bytes (0x2000) in size.
.color
Convert hex color to NES color.
Finds the closest valid NES color to the given hex color.
Usage:
.color NUMBER[, NUMBER, ...]
NUMBER- Number, required. At least one number is required., NUMBER, ...- Number(s), optional. Additional comma-separated numbers may be used.
Example:
.color $FF0000
Output:
00000000 16 |.|
00000001
Read more about the NES color palette here.
.db
Define 8-bit byte(s).
Usage:
.db NUMBER[, NUMBER, ...]
NUMBER- Number, required. At least one number is required., NUMBER, ...- Number(s), optional. Additional comma-separated numbers may be used.
Example:
.db $12, $34
Output:
00000000 12 34 |.4|
00000002
.defchr
Define CHR tile.
Only numbers from 0-3 may be used: 0 representing black, 1 dark grey, 2
light grey, and 3 representing white.
Usage:
.defchr XXXXXXXX,
XXXXXXXX,
XXXXXXXX,
XXXXXXXX,
XXXXXXXX,
XXXXXXXX,
XXXXXXXX,
XXXXXXXX
XXXXXXXX,- Number, required. Must be exactly 8 numbers of 8-characters each.
Example:
.defchr 333333333,
300000003,
300000003,
300000003,
300000003,
300000003,
300000003,
333333333
Output:
00000000 ff 01 01 01 01 01 01 ff ff 01 01 01 01 01 01 ff |................|
00000010
Read more about PPU pattern tables here.
.dw
Define 16-bit word(s).
Usage:
.dw NUMBER[, NUMBER, ...]
NUMBER- Number, required. At least one number is required., NUMBER, ...- Number(s), optional. Additional comma-separated numbers may be used.
Example:
.dw $1234, $45678
Output:
00000000 34 12 78 56 |4.xV|
00000004
.else
Else condition of an .if/.ifdef/.ifndef statement.
Usage:
.else
Example:
.ifdef SOMETHING
STA $00
.else
STA $01
.endif
.endenum
End .enum.
Usage:
.endenum
Example:
.enum $0080
TEST_0 .rs 1
TEST_1 .rs 2
TEST_2 .rs 1
.endenum
.endif
End .if/.ifdef/.ifndef statement.
Usage:
.endif
Example:
.ifdef SOMETHING
STA $00
.else
STA $01
.endif
.endm
End .macrodef.
Usage:
.endm
Example:
.macrodef TEST_MACRO
LDA #\1
STA <\2
.endm
See the section on Macros for more information.
.enum
Start enumerated variable declarations.
Usage:
.enum START[, INC]
START- Number, required. Value at which to start enumerating., INC- Number, optional. Amount to increment after each enumeration.
Example:
.enum $0080
TEST_0 .rs 1
TEST_1 .rs 2
TEST_2 .rs 1
.endenum
.fill
Fill with bytes.
Usage:
.fill COUNT[, VALUE]
COUNT- Number, required. Number of bytes to fill., VALUE- Number, optional. Value of each byte. Defaults to $FF.
Example:
.fill 16
Output:
00000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
00000010
.font
Generate font character tile.
Usage:
.font START[, END]
START- Character/number, required. Starting ASCII character or code.[, END]- Character/number, optional. Ending ASCII character or code. If included, all font tiles fromSTARTto[, END](inclusive) will be generated.
Example:
.font 'A', 'G'
Output:
00000000 38 44 7c 44 44 44 44 00 38 44 7c 44 44 44 44 00 |8D|DDDD.8D|DDDD.|
00000010 78 44 78 44 44 44 78 00 78 44 78 44 44 44 78 00 |xDxDDDx.xDxDDDx.|
00000020 38 44 40 40 40 44 38 00 38 44 40 40 40 44 38 00 |8D@@@D8.8D@@@D8.|
00000030 78 44 44 44 44 44 78 00 78 44 44 44 44 44 78 00 |xDDDDDx.xDDDDDx.|
00000040 7c 40 70 40 40 40 7c 00 7c 40 70 40 40 40 7c 00 ||@p@@@|.|@p@@@|.|
00000050 7c 40 70 40 40 40 40 00 7c 40 70 40 40 40 40 00 ||@p@@@@.|@p@@@@.|
00000060 3c 40 4c 44 44 44 38 00 3c 40 4c 44 44 44 38 00 |<@LDDD8.<@LDDD8.|
00000070
Read more about PPU pattern tables here.
.hibytes
Output only the high byte of 16-bit word(s).
Usage:
.hibytes NUMBER[, NUMBER]
NUMBER- Number, required. At least one number is required., NUMBER, ...- Number(s), optional. Additional comma-separated numbers may be used.
Example:
.hibytes $1234, $5678
Output:
00000000 12 56 |.V|
00000002
.if
Test if condition.
Can be accompanied by an .else and must be accompanied by an
.endif.
Usage:
.if CONDITION
CONDITION- Condition, required. The code that follows will be processed if the condition is true. See Comparison Operators.
Example:
.if SOMETHING == $01
LDA #$01
.endif
.ifdef
Test if variable is defined.
Can be accompanied by an .else and must be accompanied by an
.endif.
Usage:
.ifdef VARIABLE
VARIABLE- Variable/constant/etc., required. The code that follows will be processed if the variable has been defined.
Example:
.ifdef SOMETHING
STA $00
.else
STA $01
.endif
.ifndef
Test if variable has not been defined.
Can be accompanied by an .else and must be accompanied by an
.endif.
Usage:
.ifndef VARIABLE
VARIABLE- Variable/constant/etc., required. The code that follows will be processed if the variable has not been defined.
Example:
.ifndef SOMETHING
STA $01
.else
STA $00
.endif
.incbin
Include binary file.
Usage:
.incbin "FILENAME"[, OFFSET[, LIMIT]]
"FILENAME"- Path to file, required. Must be within quotes.[, OFFSET- File offset index, optional. Index at which to start including binary file.[, LIMIT]]- Limit in bytes, optional. Number of total bytes to include.
Example:
.incbin "file.bin"
.include
Include assembly file.
Usage:
.incbin "FILENAME"
"FILENAME"- Path to file, required. Must be within quotes.
Example:
.include "file.asm"
Note
Included files share a global state with other included files and the main entry point file. That means if a variable is defined in one file, it is available to all other files, provided that they are included after the definition.
.incpal
Include palette from PNG.
Usage:
.incpal "FILENAME"
"FILENAME"- Path to file, required. Must be within quotes.
Example:
.incpal "palette.png"
Note
The PNG will be scanned, row-by-row/pixel-by-pixel, from the top-left to the bottom-right until it encounters 4 different, but not necessarily unique, colors.
.incpng
Include PNG.
Converts the PNG to CHR tiles. The image must include only 4 colors:
| Color | Name | RGB | Hex |
|---|---|---|---|
| Black | 0, 0, 0 | #000000 | |
| Dark Grey | 85, 85, 85 | #555555 | |
| Light Grey | 170, 170, 170 | #AAAAAA | |
| White | 255, 255, 255 | #FFFFFF |
Note
Other colors may be used, but accuracy is not guaranteed.
Usage:
.incpng "FILENAME"
"FILENAME"- Path to file, required. Must be within quotes.
Example:
.incpng "image.png"
Read more about PPU pattern tables here.
.incrle
Include binary data to be RLE-encoded
The RLE-encoding scheme used is one featured in a few Konami NES titles, known
as Konami RLE. The breakdown of bytes:
| Value | Description |
|---|---|
| 00-80 | Read another byte and write it to the output N times |
| 81-FE | Copy N-128 bytes from input to output |
| FF | End of compressed data |
Usage:
.incrle "FILENAME"
"FILENAME"- Path to file, required. Must be within quotes.
Read more about NES RLE compression here.
.incwav
Include WAV.
Converts WAV to a 1-bit PCM.
Usage:
.incwav "FILENAME"[, AMPLITUDE]
"FILENAME"- Path to file, required. Must be within quotes.[, AMPLITUDE]- Amplitude, optional. Amplitude of WAV.
Example:
.incwav "audio.wav", 24
.ineschr
iNES CHR count.
Usage:
.ineschr COUNT
COUNT- Number, required. Number of CHR banks.
Example:
.ineschr 1
.inesmap
iNES mapper number.
Usage:
.inesmap NUMBER
NUMBER- Number, required. Mapper number.
Read more about NES mappers here.
.inesmir
iNES mirroring.
xxxx3210
||||
|||+- Mirroring: 0: horizontal (vertical arrangement)
||| 1: vertical (horizontal arrangement)
||+-- 1: Cartridge contains battery-backed PRG-RAM
|+--- 1: 512-byte trainer at $7000-$71FF
+---- 1: Ignore mirroring control, provide 4-screen VRAM
| Value | Binary | Mirroring | PRG-RAM | Trainer | 4-Screen |
|---|---|---|---|---|---|
| 0 | 00000000 | Horizontal | |||
| 1 | 00000001 | Vertical | |||
| 2 | 00000010 | Horizontal | |||
| 3 | 00000011 | Vertical | |||
| 4 | 00000100 | Horizontal | |||
| 5 | 00000101 | Vertical | |||
| 6 | 00000110 | Horizontal | |||
| 7 | 00000111 | Vertical | |||
| 8 | 00001000 | Horizontal | |||
| 9 | 00001001 | Vertical | |||
| 10 | 00001010 | Horizontal | |||
| 11 | 00001011 | Vertical | |||
| 12 | 00001100 | Horizontal | |||
| 13 | 00001101 | Vertical | |||
| 14 | 00001110 | Horizontal | |||
| 15 | 00001111 | Vertical |
Usage:
.inesmir NUMBER
NUMBER- Number, required. Mirroring type.
.inesprg
iNES PRG count.
Usage:
.inesprg COUNT
COUNT- Number, required. Number of PRG banks.
Example:
.inesprg 1
.inestrn
iNES trainer include.
Note
The assembled trainer must be no larger than 512 (0x200) bytes. The appropriate flag is automatically set in the iNES header to indicate a trainer is present.
Usage:
.inestrn "FILENAME"
"FILENAME"- Path to file, required. Must be within quotes.
Example:
.inestrn "trainer.asm"
.lobytes
Output only the low byte of 16-bit word(s).
Usage:
.lobytes NUMBER[, NUMBER]
NUMBER- Number, required. At least one number is required., NUMBER, ...- Number(s), optional. Additional comma-separated numbers may be used.
Example:
.lobytes $1234, $5678
Output:
00000000 34 78 |4x|
00000002
.macro
Call macro.
Usage:
.macro MACRO[, NUMBER, ...]
MACRO- Name, required. Name of previously-defined macro., NUMBER, ...- Number(s), optional. Additional comma-separated numbers may be used.
Example:
.macro TEST_MACRO
See the section on Macros for more information.
.macrodef
Start macro definition.
Usage:
.macrodef MACRO
CODE...
.endm
MACRO- Name, required. Name of macro.CODE...- Code, required. Assembly code.
Example:
.macrodef TEST_MACRO
LDA #\1
STA <\2
.endm
See the section on Macros for more information.
.org
Organize code.
Set the address of the current bank in which to start organizing code.
Usage:
.org ADDRESS
Example:
.org $C000
.out
Output debugging message.
The message will only be output during assembly.
Usage:
.out "STRING"
"STRING"- String, required. ASCII string to output. Must be within quotes.
Example:
.out "She swore, in faith 'twas strange, 'twas passing strange"
.prg
Set PRG bank index.
Usage:
.prg NUMBER
NUMBER- Number, required. PRG bank index.
Example:
.prg 0
Note
PRG banks are 4K bytes (0x4000) in size.
.random
Output random byte(s).
The algorithm for the PRNG is the suggested POSIX implementation of rand().
Usage:
.random [SEED[, COUNT]]
[SEED- Number or string, optional. Seeds the random number generator. Defaults to the current system time.[, COUNT]]- Number of bytes to output, optional. Defaults to 1.
Example:
.random "Secret Key", 16
.rsset
Set initial value for .rs declarations.
Usage:
.rsset ADDRESS
ADDRESS- Number, required. Address to start.rsdeclarations.
Example:
.rsset $0000
.rs
Reserve space for variable declaration.
Usage:
VARIABLE .rs NUMBER
VARIABLE- Variable name, required. Name of variable to declare.NUMBER- Number (in bytes) to reserve, required.
Example:
.rsset $0000
label_01 .rs 1
label_02 .rs 2
label_03 .rs 1
.db label_01, label_02, label_03
Output:
00000000 00 01 03 |...|
00000003
.segment
Set code segment.
Usage:
.segment "SEGMENT[0-9]+"
SEGMENT- Type of segment, required.PRGorCHR.[0-9]+- Number, required. Segment index.
Note
The whole segment must be within quotes.
Example:
.segment "PRG1"
Note
This is an alias for.prg x.
Optional Scripts
Some scripts are included with nessemble, but totally optional. They must be
installed with the scripts command which provides additional
pseudo-instructions to use.
| Pseudo-Instruction | Description |
|---|---|
| .ease | Generates bytes to simulate easing |
.ease
Generates bytes to simulate easing
Usage:
.ease FUNCTION[, START[, END[, STEPS]]]
FUNCTION- String, required. Easing function to perform. Must be within quotes.[, START- Number, optional. Starting value. Defaults to 0.[, END- Number, optional. Ending value. Defaults to 16.[, STEPS]]]- Number, optional. Steps to perform. Defaults to 16.
Valid FUNCTIONs include:
- "easeInQuad"
- "easeOutQuad"
- "easeInOutQuad"
- "easeInCubic"
- "easeOutCubic"
- "easeInOutCubic"
- "easeInQuint"
- "easeOutQuint"
- "easeInOutQuint"
- "easeInBounce"
- "easeOutBounce"
- "easeInOutBounce"
Example:
.ease "easeOutBounce", 0, $20, $40
Output:
00000000 00 00 00 00 00 01 02 02 03 04 06 07 08 0a 0b 0d |................|
00000010 0f 11 13 16 18 1a 1d 1f 1e 1d 1c 1b 1a 19 19 18 |................|
00000020 18 18 18 18 18 18 18 19 19 1a 1b 1c 1d 1e 1f 1f |................|
00000030 1e 1e 1e 1e 1e 1e 1e 1e 1f 1f 1f 1f 1f 1f 1f 20 |............... |
00000040
Macros
Macros may be utilized to maximize code-reuse and may also be treated as custom functions.
Example:
.macrodef TEST_MACRO
LDA #$00
STA $2005
STA $2005
.endm
.macro TEST_MACRO
Output:
00000000 a9 00 8d 05 20 8d 05 20 |.... .. |
00000008
Parameters
Macros may also have parameters.
Example:
.macrodef TEST_MACRO
LDA #\1
STA \2
STA \2
.endm
.macro TEST_MACRO, $00, $2005
Output:
.macrodef TEST_MACRO
LDA #\1
STA \2
STA \2
.endm
.macro TEST_MACRO, $00, $2005
One macro may have up to 256 parameters which are denoted with a \ prefix. The
first parameter being \1, the next \2, and so on up to \256. All
parameters must be numbers (or label variables).
There is also a pseudo-parameter, \#, that returns the number of input
parameters.
Example:
.macrodef COUNT_PARAMS
.db \#
.endm
.macro COUNT_PARAMS, $01, $01, $01
Output:
00000000 03 |.|
00000001
There is another pseudo-parameter, \@, that returns a unique number every time
the macro is called.
Example:
.macrodef TEST_MACRO
LDX #$08
label_\@:
DEX
BNE label_\@:
.endm
.macro TEST_MACRO
.macro TEST_MACRO
.macro TEST_MACRO
Output:
00000000 a2 08 ca d0 fd a2 08 ca d0 fd a2 08 ca d0 fd |...............|
0000000f