🎮
Assembly for the SNES
  • Introduction
  • Getting started
  • Contributing
  • The fundamentals
    • Hexadecimal
    • Binary
    • The SNES memory
    • The SNES registers
    • Addressing modes
    • Little-endian
    • Glossary
  • The basics
    • Loading and storing
    • Shorter addresses
    • 8-bit and 16-bit mode
    • Comparing, branching, labels
    • Jumping to subroutines
  • Collection of values
    • Tables and indexing
    • The stack
    • Copying data
  • Processor flags and registers
    • The processor flags
    • Changing the processor flags
    • Transfers
    • Stack pointer register
  • Mathemathics and logic
    • Arithmetic operations
    • Bit shifting operations
    • Bitwise operations
    • Hardware math
  • Deep dives
    • Addressing modes revisted
    • Miscellaneous opcodes
    • Machine cycles
    • Hardware vectors
    • Techniques
    • Common assembler syntax
    • Programming cautions
Powered by GitBook
On this page

Was this helpful?

  1. The basics

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
PreviousShorter addressesNextComparing, branching, labels

Last updated 3 years ago

Was this helpful?