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
Try it:
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
Try it:
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
nessemble
uses 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
Try it:
.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.
Try it:
.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.
Try it:
.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
Try it:
.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.
Try it:
.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
Try it:
.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
Try it:
.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 fromSTART
to[, 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.
Try it:
.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
Try it:
.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
Try it:
.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.rs
declarations.
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
Try it:
.segment
Set code segment.
Usage:
.segment "SEGMENT[0-9]+"
SEGMENT
- Type of segment, required.PRG
orCHR
.[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 FUNCTION
s 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
Try it:
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
Try it:
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