Links

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:
Operation
Explanation
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