== Learning 65816 Assembly ==
I trust that you have learned some other kind of assembly language. If you
have not, I'm afraid that learning 65816 as your first assembly language may
be extremely hard. However, I won't stop you from trying. You will need other
65816 documents, because I do not teach much in this tutorial. These tutorials
are for teaching you how to use 65816 with the SNES, so I'm trying to write
the main material first. Maybe later I'll really expand this part and make it
full. But really, the 65816 documents I linked you to earlier teach everything,
so it would be really redundant for me to write a 65816 tutorial. However, if
I receive feedback asking for one, I will make an effort. Ok, let's begin.

== Modes of Operation ==

- The 65816 can run in 2 modes of operation, Native 65816 mode and 6502 Emulation mode.
- The 65816 boots up in 6502 Emulation mode. (I found that odd, but whatever)
- We'll be programming in Native mode, otherwise it would be like coding for NES (somewhat).

== Registers ==

Accumulator
      - This register may be either 16 or 8 bits (depending on bit 5 of
           the status register. more on this later).

      - This register is used for most general-purposes.

      - When in 8-bit mode, the low byte is accessible, and the high byte
           is not. However, you can exchange both the high and low byte.

      - when in 16-bit mode, all 2 bytes are accessible and the
           accumulator is designated as C.

X,Y Index Registers
      - The X and Y index registers can also be designated as 8 or 16
           bits in size.

      - I usually see these kept set as 16 bits in size.

      - You will come to see their usefulness. One example is using
           them as counters.

Direct Page Register (D), Stack Pointer (S), Program Bank Register (PBR),
Data Bank Register (DBR)

      - Please see section 3.13-3.16 of the 65816 Primer for information on
           these registers. I would only be quoting, and I don't feel
           like it, so just read those sections. I will at least provide
           some notes.

      - The stack grows downwards.
      - I usually see the program's init routine set the stack to $1FFF
      - I usually see a program's init routine set the DBR = PBR
      - I also see the direct page set to $0000

      - So far, I have not really had to do any heavy messing around
           with these registers, so if your a little confused by the
           descriptions have no fear.

Processor Status Register (P)
      - See Section 3.01 of the 65816 Primer for a GREAT graphic
           description of the processor status register.

== Number Format ==

It's the same as NES if you have coded NES before.
In previous asm languages you may have written in, you may have used
$10 or 10h to say that the number is in hex, and [$10] to say that
it's a hex address. Well it's a little different for the SNES.
To use an immediate value (not an address, just a number), you
place a # before the number. #16 = 16 decimal number. To use an
immediate hex value, use #$. #$10 = 10 hex, or 16 decimal. To
use an immediate binary value, use #%. #%00000011 = 3 decimal.
To say the number is an address, use $. $2000 for example.. We
basically took out the #, which meant it was an immediate value. See?
That's that!

== Changing bits in the P Register ==

To alter bits in the Processor Status Register, simply use the
opcodes SEP #xx or REP #xx. SEP sets bits (makes the bits 1)
and REP resets bits (makes the bits 0). Assuming you read
section 3.01 of the 65816 Primer, let's go and make the
accumulator 8 bits and the XY registers 16 bits in size.

rep #$10
sep #$20
I could also write (for visual simplicity)
rep #%00010000
sep #%00100000

nvMXdizc - these are simply helpful abbreviations of bits 0-7
of the Processor Status Register. See how we REP'd and SEP'd
the P register to set A to 8 bits, and X/Y to 16 bits?
Resetting the M or X bits (of nvmxdizc) makes the
register(s) 16 bits, setting the bit makes it 8 bits.

== Basic Opcodes ==

This is another crappy listing, simply because the docs already out there
are already enough to get you going. Nonetheless, here is a brief and crappy intro.

There are many ways to use most opcodes, so I will only list a couple
basic methods. I encourage you to look in Appendix A of the 65816
Primer for more addressing modes of each opcode. Appendix A tells
you everything for almost every opcode, so be sure to check it out.

Notes: I've taken the syntax conventions from 65816 Primer for simplicity.
addr
          2 byte address
const         1 or 2 byte constant (immediate number)
label          label of code in same 64K bank as instruction
nearlabel    label of code close enough to instruction to be reachable by a one-byte signed offset (-127/+127).
long           3-byte address (includes bank byte)

LDA : Load Accumulator with memory
Usage:

LDA #const
LDA addr
LDA long
LDA addr,X
...
- You will be using this a LOT to load values and values at
addresses.

LDX,LDY - Same as above, but for X/Y. Also, addressing modes are
more limited when using X/Y. See the primer.

STA : Store A into memory
Usage:

STA addr
STA long
STA addr,X
STA addr,Y
...
- You will be using this a LOT to store values in A into
addresses.

STY,STX - Same as Above, but for X/Y. Also, addressing modes are
more limited when using X/Y. See the primer.

STZ : Store zero byte to memory
Usage:

STZ addr
STZ addr,X
...
- A good replacement for:
lda #$00
sta $xxxx


CLC : Clear Carry Flag
- clc before adc
SEC : Set Carry Flag
- sec before sbc>

ADC : Add with carry
Usage:

ADC #const
ADC addr
ADC long
ADC addr,X
...
- You should CLC before ADC'ing.
- Carry flag set if overflow.

SBC : Subtract with carry
Usage: SBC #const
SBC addr
SBC long
SBC addr,X
...
- You should SEC before SBC-ing.
- Set if unsigned borrow not required.

Well that is enough for now don't you agree?? Again please look at the primer
and other CPU docs for some real opcode info.

back