# 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.

{% hint style="info" %}
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".
{% endhint %}

```
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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ersanio.gitbook.io/assembly-for-the-snes/the-basics/816.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
