8-bit and 16-bit mode

The SNES is able to enter 8-bit or 16-bit modes. This means that the A, X and Y registers contain 16-bit values instead of 8-bit values.

There are a few ways to switch between 8-bit and 16-bit modes. Here are all the possible manners:



REP #$10

Sets X and Y to 16-bit mode

REP #$20

Sets A to 16-bit mode

REP #$30

Sets A, X and Y to 16-bit mode

SEP #$10

Sets X and Y to 8-bit mode

SEP #$20

Sets A to 8-bit mode

SEP #$30

Sets A, X and Y to 8-bit mode

The opcodes REP and SEP are explained later in this tutorial. For now, this is all you need to know.

In 16-bit A mode, the following features take effect:

  • When accessing the memory, you will involve 2 RAM addresses as opposed to 1.

  • Those two RAM addresses are always adjacent to each other.

  • Immediate values (#$) are now 16-bit.

  • Loaded and stored values are little-endian in the memory, but you don't have to worry about that at all.

Let's begin with an example immediately:

REP #$20
LDA #$0001
STA $7E0000
SEP #$20

And breaking it down:

REP #$20

This sets the A register to 16-bit mode.

LDA #$0001

This will load the 16-bit value $0001 into A, so A now has the value $0001.

If you write $01 instead of $0001, the code would most-likely crash! This is because the code expects a 16-bit parameter, but you only give it an 8-bit one. The code therefore takes the next opcode as part of the 16-bit parameter, causing the following opcodes to become bogus.

Each opcode (disregarding the parameters) becomes an 8-bit value when assembled. This is why you only see hexadecimal values when you open a ROM in a hex editor. To disassemble these values into human-readable ASM, you'll need to use a "disassembler".

STA $7E0000

This will store the 16-bit A value into the RAM address $7E0000 AND $7E0001. Why two addresses? Because a 16-bit value won't fit into one address. Remember that an address represents an 8-bit value, so two addresses can represent a 16-bit one. $7E0000 and $7E0001 combined will now have the value $0001.

SEP #$20

Exits A from 16-bit mode.

After executing these 4 instructions, if we take a peek into the RAM, we see will see something like this:

$7E0000 | [01] [00] [XX] [XX] [XX] […]

The first value, $01, is the value of RAM address $7E0000. The second value belongs to $7E0001. The third value belongs to $7E0002, etc.

As you can see, the stored value became little-endian, but normally we don't have to worry about this. If we try to load it back into A, we would have to use LDA $7E0000. It would load the value $0001 into A again if A is in 16-bit mode. If you tried to load it back when A was in 8-bit mode it would load the value $01 into A instead.

There's a 16-bit X and Y mode too. This is not related to 16-bit A mode at all. If A is 8-bit mode and XY are 16-bit mode, the following is definitely possible:

LDA #$13
LDX #$4242

Last updated