A SNES 65816 Cross Assembler for the IBM PC

Version 1


SNASM is a 65816 Cross Assembler which produces SNES code in Super Magicom format.

SNASM is a fast 2 pass assembler, supporting source and binary include files, generation of listing files and labels files, generation of executable or object files and support for all 65816 instructions and addressing modes.

Command Line Options

The assembler is executed with the following command:

SNASM <filename> {<options>}

<filename> is the filename of the source code that you want to assemble.

The following options are available:

LIST This generates a ".lis" listing file which interleaves the code generated with the source code.

LABELS This generates a ".lab" file which contains all the public labels in alphabetic order.

OBJECT If this option is not specified, the assembler will generate an executable ".smc" file. The executable file will have a 512 byte Super Magicom header and will be padded to a bank boundary. If this option is specified, the assembler will generate an object ".obj" file. This will not have a SMC header and will not be padded to a bank boundary.

Pseudo Op Codes

ORG <absolute location>

This is used to set the start location for the assembly and must be specified before any instructions. Note that the start location must reside within valid code space (ie. lower 16-bits in $8000 to $FFFF).

Eg. ORG $8000 ; start assembly at location $8000


This will cause padding with 0's to the next bank boundary. Note that if already at a bank boundary, then this will have no effect.

PAD <absolute location>

This will cause padding with 0's to the specified location. Note that the location must reside within valid code space.

Eg. PAD $018000 ; pad to location $018000

INCLUDE "<filename>"

This will include the specified source file.

Eg. INCLUDE "equates.h" ; include the source file "equates.h"

INCBIN "<filename>"

This will include the specified binary file.

Eg. INCBIN "screen.dat" ; include the binary file "screen.dat"

DC.B <expression>|<string>{,<expression>|<string>}

This defines constant byte data.

Eg. DC.B "jethro",1,2,3,4+5/3,label1-label2,"tull"

DC.W <expression>{,<expression>}

This defines constant word data in 65816 low byte, high byte ordering.

Eg. DC.W $1234,$5678,$9ABC,%1010101010101010

DC.L <expression>{,<expression>}

This defines constant long data in 65816 low byte, middle byte, high byte ordering.

Eg. DC.L $018000,$028000,$038000,$048000

<label> EQU <expression>

This will equate the label to the expression.

Eg. ScreenMode EQU $2105

PUBLIC <label>

Indicates that a label should appear in the .LAB file.


The following operators are provided for forming expressions:

+ ... add

- ... negate/subtract

* ... multiply

/ ... divide

& ... and

| ... or

Expressions are evaluated in left to right order without any operator precedence.


10+20/10 evaluates to 3
$123456/$100&$FF evaluates to $34
-32/2+-8 evaluates to -24

Note that parenthesis are not provided.

Values and Labels

Values may be specified in either decimal, hex (when preceded by a $) or binary (when preceded by a %).

Labels can be up to 32 characters long and must start with an alphabetic character or an underscore. Labels may only contain alphanumeric and underscore characters. Note that labels are case sensitive but instructions and pseudo op codes are not case sensitive. A maximum of 8000 labels may be defined.


start ... is a valid label
START ... is also a valid label, but different from above
7up   ... is not a valid label (it's a soft drink)
_7up  ... is a valid label

Size Specifiers

Some assembly instructions may have 1, 2 or 3 byte operands. In order to indicate to the assembler the mode required, ".B", ".W" and ".L" size specifiers are available.


LDA.B #$00 specifies LDA with immediate single byte operand $00
LDA.W #$00 specifies LDA with immediate word operand $0000
LDA.L $00 specifies LDA with absolute long operand $000000

If the size specifier is omitted, the following defaults will be used:

immediate  ... ".B"
absolute   ... ".W"
absolute,x ... ".W"
absolute,y ... ".B"
indirect   ... ".B"

Note that some instructions do not require size specifiers. Rather than ignore these, the assembler will report an error as they make the source code confusing.

Addressing Modes

mode                      format

implied                   no operand
immediate (byte)          #byte
immediate (word)          #word
absolute                  word
absolute,x                word,x
absolute,y                word,y
indirect                  (word)
indirect,x                (word,x)
absolute long             long
absolute long,x           long,x
direct                    byte
direct,x                  byte,x
direct,y                  byte,y
indirect direct           (byte)
indirect direct,x         (byte,x)
indirect direct,y         (byte),y
long indirect direct      [byte]
long indirect direct,y    [byte],y
stack relative            byte,s
indirect stack relative,y (byte,s),y
8-bit relative offset     byte
16-bit relative offset    word

The mnemonics are taken from the article in BYTE August 1984 entitled "The 65816 Microprocessor, Part 1: Software". The only differences are that the BRK and COP instructions take an immediate byte operand and MVP and MVN take an immediate word operand.

Defining The Run Address

The run offset for a program is defined at location $FFFC. So to set the run/reset offset you should PAD to $FFFC then declare it.


DC.W $8000 ; run from location $8000