====== Alphabetical Listing ====== ^ ADC | Add (with carry) memory to accumulator | ^ AND | Bitwise AND accumulator with memory | ^ ASL | (Arithmetic) shift left accumulator / memory | ^ BCC | Branch if carry clear | ^ BCS | Branch if carry set | ^ BEQ | Branch if equal (zero set) | ^ BIT | Bit test accumulator with memory | ^ BNE | Branch if not equal (zero clear) | ^ BPL | Branch if plus (negative clear) | ^ BMI | Branch if minus (negative set) | ^ BRA | Branch (unconditional) | ^ BRK | Breakpoint interrupt | ^ BRL | Branch long (unconditional) | ^ BVC | Branch if overflow clear | ^ BVS | Branch if overflow set | ^ CLC | Clear carry flag | ^ CLD | Clear decimal mode flag | ^ CLI | Clear interrupt-disable flag | ^ CLV | Clear overflow flag | ^ CMP | Compare accumulator with memory | ^ COP | Coprocessor interrupt | ^ CPX | Compare index register X with memory | ^ CPY | Compare index register Y with memory | ^ DEC | Decrement accumulator / memory | ^ DEX | Decrement index register X | ^ DEY | Decrement index register Y | ^ EOR | Bitwise XOR accumulator with memory | ^ INC | Increment accumulator / memory | ^ INX | Increment index register X | ^ INY | Increment index register Y | ^ JML | Jump long (can change banks) | ^ JMP | Jump (within current bank) | ^ JSL | Jump to subroutine long (can change banks) | ^ JSR | Jump to subroutine (within current bank) | ^ LDA | Load to accumulator from memory | ^ LDX | Load to index register X from memory | ^ LDY | Load to index register Y from memory | ^ LSR | Logical shift right accumulator / memory | ^ MVN | Move memory in the negative direction | ^ MVP | Move memory in the positive direction | ^ NOP | No operation | ^ ORA | Bitwise OR accumulator with memory | ^ PEA | Push effective absolute | ^ PEI | Push effective indirect | ^ PER | Push effective relative | ^ PHA | Push accumulator | ^ PHB | Push data bank register | ^ PHD | Push direct page register | ^ PHK | Push program bank register | ^ PHP | Push processor status register | ^ PHX | Push index register X | ^ PHY | Push index register Y | ^ PLA | Pull to accumulator | ^ PLB | Pull to data bank register | ^ PLD | Pull to direct page register | ^ PLP | Pull to status flags | ^ PLX | Pull to index register X | ^ PLY | Pull to index register Y | ^ REP | Reset processor status register bits | ^ ROL | Rotate accumulator / memory left (with carry) | ^ ROR | Rotate accumulator / memory right (with carry) | ^ RTI | Return from interrupt | ^ RTL | Return from subroutine long (from JSL) | ^ RTS | Return from subroutine (from JSR) | ^ SBC | Subtract (with carry) memory from accumulator | ^ SEC | Set carry flag | ^ SED | Set decimal mode flag | ^ SEI | Set interrupt-disable flag | ^ SEP | Set processor status register bits | ^ STA | Store accumulator to memory | ^ STP | Stop CPU | ^ STX | Store index register X to memory | ^ STY | Store index register Y to memory | ^ STZ | Store zero to memory | ^ TAX | Transfer accumulator to index register X | ^ TAY | Transfer accumulator to index register Y | ^ TCD | Transfer accumulator to direct page register | ^ TCS | Transfer accumulator to stack pointer | ^ TDC | Transfer direct page register to accumulator | ^ TRB | Test and reset memory bits against accumulator | ^ TSB | Test and set memory bits with accumulator | ^ TSC | Transfer stack pointer to accumulator | ^ TSX | Transfer stack pointer to index register X | ^ TXA | Transfer index register X to accumulator | ^ TXS | Transfer index register X to stack pointer | ^ TXY | Transfer index register X to Y | ^ TYA | Transfer index register Y to accumulator | ^ TYX | Transfer index register Y to X | ^ WAI | Wait for interrupt | ^ WDM | William David Mensch Jr., 65816 designer (reserved, no operation) | ^ XBA | Exchange bytes of the accumulator | ^ XCE | Exchange carry and emulation bits | ====== Functional Grouping ====== ===== Arithmetic ===== ^ ADC | Add with carry to A | ^ SBC | Subtract with borrow from carry from A | ^ ASL | Shift left by one bit, aka multiply by 2 | ^ LSR | Shift right by one bit, aka divide by 2 | ^ INC/INX/INY | Increment, adds 1 | ^ DEC/DEX/DEY | Decrement, subtracts 1 | There are no general multiply/divide instructions on the CPU. Super Metroid has a routine at $80:82D6 that (inaccurately--it's missing a carry) multiplies two 16-bit values (from A and Y) and stores a result in $05F1-$05F4. ===== Bitwise Operations ===== ^ AND | AND value with A | ^ BIT | Test bits against A and set flags | ^ EOR | Exclusive-or (xor) value with A | ^ ORA | OR value with A | ^ TRB | NAND memory with A, but set Z flag as if it were BIT | ^ TSB | OR memory with A, but set Z flag as if it were BIT | ^ ROL | Rotate left, through carry | ^ ROR | Rotate right, through carry | The rotate operations can be used like shift operations, for data that's bigger than the size of a register. TRB/TSB oddly affect **memory** and not the A register. BIT does not affect the value in A. ===== Branching/Conditionals ===== ^ BRA | Always branch | ^ BCC / BCS | Branch if carry clear or set | ^ BVC / BVS | Branch if overflow clear or set | ^ BPL / BMI | Branch if minus flag clear or set | ^ BNE / BEQ | Branch if zero clear or set | ^ CMP/CPX/CPY | Compare value with A/Y/X and set flags | I'm not sure if BRL (long branch) is useful, since it uses the same space as a JMP but can't always travel as far. CMP does its work by subtracting the compared value from A, setting the flags, and throwing away the result. When the value and A were equal, the subtraction yields 0, and the Z flag is set. Which is why BEQ branches on Zero. The Super Metroid engine occasionally returns single bits of information from subroutines via the carry flag. For example, whether a block should be treated as solid (SEC) or not (CLC) during touch/collision. ===== Jumping ===== ^ JSR - RTS | Jump to subroutine in the same bank - return from it | ^ JSL - RTL | Jump to subroutine in any bank - return from it | ^ JMP | Go to address in the same bank | ^ JML | Go to address in any bank | JSL-RTL use one extra instruction byte and one additional byte on the stack, compared to JSR-RTS. ===== Moving Between Registers ===== What most other chips call "move," the 65c816 calls "transfer." ^ TAX | Accumulator (A) to X | ^ TXA | X to Accumulator | ^ TAY | Accumulator to Y | ^ TYA | Y to Accumulator | ^ TXY | X to Y | ^ TYX | Y to X | ===== Moving Between Memory ===== There are no memory/memory operations. Everything involving two values happens between memory and a register. Also, see the stack section for moving between registers and the stack. ^ LDA/LDX/LDY | Load from memory to A/X/Y register | ^ STA/STX/STY | Store to memory from A/X/Y register | ^ STZ | Store zero to memory | ===== Stack ===== All of the PH* instructions have a corresponding PL*, except for PHK. The only way to affect the code segment is through JSL or JML. ^ PHP | Push processor flags (frequently before SEP/REP) | ^ PHK | Push code bank | ^ PHB | Push data bank | ^ PHD | Push direct page register | ^ PHA/PHX/PHY | Push A/X/Y register | ^ PEA | Push address (may have to write PEA.w in xkas) | Super Metroid occasionally does things like: PHB : PHK : PLB : (a section of code) : PLB : RTL This saves the data bank, then sets the data bank to the current code bank for the section of code. Finally, the original data bank is restored just before returning. Another common sequence is: PEA $8200 : PLB : PLB This sets bank $82 as the data bank. PEA writes the stack so that it says $00 $82, making the first PLB set the data bank to $00, and the second one sets the intended $82. ===== Processor Flags ===== ^ CLC/CLD/CLI/CLV | Clear carry/decimal/interrupt/overflow | ^ SEC/SED/SEI | Set carry/decimal/interrupt | ^ REP | Clear (reset) status bits | ^ SEP | Set status bits | Interrupts are disabled when SEI is used, and allowed when CLI is used. NMIs, as usual, cannot be disabled. Overflow can only be set by doing arithmetic that sets it, such as ADC, or using SEP. ==== Status Bits ==== ^ 80 | Negative (BPL/BMI) | ^ 40 | Overflow (BVC/BVS) | ^ 20 | A register size: 0 for 16-bit, 1 for 8-bit | ^ 10 | X/Y register size: 0 for 16-bit, 1 for 8-bit | ^ 08 | Decimal mode, may not be emulated properly | ^ 04 | IRQ Disable: 0 for enabled, 1 for disabled | ^ 02 | Zero (BEQ/BNE) | ^ 01 | Carry (BCC/BCS) | The most common bits changed with SEP and REP in Super Metroid are $10 and $20 (sometimes combined as $30.) SEP changes the flags to 1, and REP changes them to 0, so REP #$30 sets 16-bit mode for A and X/Y.