User Tools

Site Tools


super:technical_information:asm_mnemonics

This is an old revision of the document!


Alphabetical Listing

  • ADC Add memory and carry to accumulator
  • AND And accumulator with memory
  • ASL Shift memory or accumulator left one bit
  • BCC Branch if carry clear
  • BCS Branch if carry set
  • BEQ Branch if equal
  • BIT Test memory bits against accumulator
  • BNE Branch if not equal
  • BPL Branch if plus (greater than)
  • BMI Branch if minus (less than)
  • BRA Branch always (unconditional)
  • BRK Branch if plus Software break (interrupt)
  • BRL Branch always long
  • 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 Co-processor empowerment
  • CPX Compare index register X with memory
  • CPY Compare index register Y with memory
  • DEC Decrement
  • DEX Decrement index register X
  • DEY Decrement index register Y
  • EOR Exclusive-OR accumulator with memory
  • INC Increment
  • INX Increment index register X
  • INY Increment index register Y
  • JML Jump long (interbank)
  • JMP Jump
  • JSL Jump to subroutine long(interbank)
  • JSR Jump to subroutine
  • LDA Load accumulator from memory
  • LDX Load index register X from memory
  • LDY Load index register Y from memory
  • LSR Logical shift memory or accumulator right
  • MVN Block move negative
  • MVP Block move positive
  • NOP No operation
  • ORA OR accumulator with memory
  • PEA Push effective absolute address onto stack
  • PEI Push effective indirect address onto stack
  • PER Push effective program counter relative address onto stack
  • PHA Push accumulator onto stack
  • PHB Push data bank register onto stack
  • PHD Push direct page register onto stack
  • PHK Push program bank register onto stack
  • PHP Push status flags onto stack
  • PHX Push index register X onto stack
  • PHY Push index register Y onto stack
  • PLA Pull accumulator from stack
  • PLB Pull data bank register from stack
  • PLD Pull direct page register from stack
  • PLP Pull status flags from stack
  • PLX Pull index register X form stack
  • PLY Pull index register Y from stack
  • REP Reset status bits
  • ROL Rotate memory or accumulator left one bit
  • ROR Rotate memory or accumulator fight one bit
  • RTI Return from interrupt
  • RTL Return from subroutine long
  • RTS Return from subroutine
  • SBC Subtract memory with borrow from accumulator
  • SEC Set carry flag
  • SED Set decimal mode flag
  • SEI Set interrupt-disable flag
  • SEP Set status bits
  • STA Store accumulator to memory
  • STP Stop the processor
  • 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 16-bit accumulator to direct page register
  • TCS Transfer accumulator to stack pointer
  • TDC Transfer direct page register to 16-bit accumulator
  • TRB Test and reset (clear) memory bits against accumulator
  • TSB Test and set memory bits against accumulator
  • TSC Transfer stack pointer to 16-bit accumulator
  • TSX Transfer stacker point to index register X
  • TXA Transfer index register X to accumulator
  • TXS Transfer index register X to stack pointer
  • TXY Transfer index registers X to Y
  • TYA Transfer index register Y to accumulator
  • TYX Transfer index registers Y to X
  • WAI Wait for interrupt
  • WDM Reserved for future two-byte opcodes
  • XBA Exchange the B and A accumulators (upper/lower bytes of register A)
  • 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.

super/technical_information/asm_mnemonics.1550193150.txt.gz · Last modified: 2019/02/15 01:12 by smileuser96