# Transfers

Imagine the following situation: You're using the index register X and you'd like to increase it by #$40. There's `INX` which increases the value in X by one, but what about increasing it by $40? There's no opcode which increases the value in X by $40, [but there is one](/assembly-for-the-snes/mathemathics-and-logic/arithmetic.md) which increases the value in A by $40. How do you get the value in X into A?

There are a series of opcodes for exactly that purpose, and they're called "transfers". There are a bunch of transfer opcodes, all starting with the letter T.

## Transferring A, X and Y

There are opcodes which transfers the values between A, X and Y registers. All the combinations are possible:

| Opcode  | Full name       | Explanation                     |
| ------- | --------------- | ------------------------------- |
| **TAX** | Transfer A to X | Copies over the value of A to X |
| **TAY** | Transfer A to Y | Copies over the value of A to Y |
| **TXA** | Transfer X to A | Copies over the value of X to A |
| **TXY** | Transfer X to Y | Copies over the value of X to Y |
| **TYA** | Transfer Y to A | Copies over the value of Y to A |
| **TYX** | Transfer Y to X | Copies over the value of Y to X |

The opcodes are self-explanatory. Here's an example of a transfer:

```
LDA #$45           ; A = $45
LDY #$99           ; Y = $99
TAY                ; A = $45, Y = $45
```

As you can see, the values are *copied* over to the target register.

## 8-bit and 16-bit mode

Transfers work as you'd expect when the source and target registers are both 16-bit mode. You transfer a 16-bit value, like so:

```
LDA #$4512         ; A = $4512
LDY #$9900         ; Y = $9900
TAY                ; A = $4512, Y = $4512
```

If you want to transfer an 8-bit register's value to a 16-bit register, the SNES looks at the target register's size, and transfers the value's low byte accordingly. Here's an example involving an 8-bit transfer to the 16-bit A register:

```
LDA #$4512         ; A = $4512
LDY #$99           ; Y = $0099
TYA                ; A = $4599, Y = $0099
```

Here's an example involving a 16-bit transfer to the 8-bit A register:

```
LDA #$45           ; A = $xx45
LDY #$99AA         ; Y = $99AA
TYA                ; A = $xxAA, Y = $99AA
```

In the second example, the `xx` could be anything. Remember that [in the introduction of the A, X and Y registers](https://github.com/Ersanio/snes-assembly-book/tree/c7ff1077207f8a20e73f4ef3148c976dd96dcc25/docs/the-basics/register.md), it's mentioned that the A register can actually be treated to be always 16-bit. The high byte isn't touched during the transfer, even if A is in 8-bit mode. If A was `$1245` before the transfer, it'll be `$12AA` after the transfer. This doesn't apply to X and Y, as their high bytes are immediately cleared when they exit 16-bit mode.

## Transferring general registers

There are other opcodes which involve the general SNES registers.

| Opcode  | Full name                            | Explanation                                                                                                                                                                |
| ------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **TCD** | Transfer A to direct page register   | Transfers the 16-bit value in A, to the direct page register, regardless of A being in 16-bit mode or not                                                                  |
| **TDC** | Transfer direct page register to A   | Transfer the 16-bit value in the direct page register to the A register, regardless of A being in 16-bit mode or not                                                       |
| **TCS** | Transfer A to stack pointer register | Transfers the 16-bit value in A to the stack pointer register, regardless of A being in 16-bit mode or not                                                                 |
| **TSC** | Transfer stack pointer register to A | Transfers the 16-bit value in the stack pointer register to A, regardless of A being in 16-bit mode or not                                                                 |
| **TXS** | Transfer X to stack pointer register | Transfers the 16-bit value in X to the stack pointer register, regardless of X being in 16-bit mode or not. Note that when X is in 8-bit mode, the high byte is always $00 |
| **TSX** | Transfer stack pointer register to X | Transfers the 16-bit value in the stack pointer register to X. Note that when X is in 8-bit mode, the high byte stays $00 after the transfer                               |


---

# 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/processor-flags-and-registers/transfer.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.
