Difference between revisions of "6502 opcodes for hackers"

From 8BitDev.org - Atari 7800 Development Wiki
Jump to: navigation, search
(Created page with "'''6502 Opcodes for Hackers''' is a reference guide for experienced programmers. It focuses on the practical application of both standard and stable non-standard NMOS 6502 opc...")
(No difference)

Revision as of 18:11, 29 June 2025

6502 Opcodes for Hackers is a reference guide for experienced programmers. It focuses on the practical application of both standard and stable non-standard NMOS 6502 opcodes, including common tricks and non-obvious behaviors. It intentionally omits highly unstable opcodes to provide a focused, practical resource.

Opcode Matrix

This table provides a complete overview of the NMOS 6502 opcode map. Each mnemonic links to its detailed description below.

Legend:

  • Blue: Standard Opcodes
  • Green: Stable Illegal Opcodes
  • Yellow: Semi-Stable Illegal Opcodes (use with caution)
  • Red: Unstable/Unreliable Opcodes (details not included below)
NMOS 6502 Opcode Matrix
HI -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F
0- BRK ORA JAM SLO NOP ORA ASL SLO PHP ORA ASL ANC NOP ORA ASL SLO
1- BPL ORA JAM SLO NOP ORA ASL SLO CLC ORA NOP SLO NOP ORA ASL SLO
2- JSR AND JAM RLA BIT AND ROL RLA PLP AND ROL ANC BIT AND ROL RLA
3- BMI AND JAM RLA NOP AND ROL RLA SEC AND NOP RLA NOP AND ROL RLA
4- RTI EOR JAM SRE NOP EOR LSR SRE PHA EOR LSR ALR JMP EOR LSR SRE
5- BVC EOR JAM SRE NOP EOR LSR SRE CLI EOR NOP SRE NOP EOR LSR SRE
6- RTS ADC JAM RRA NOP ADC ROR RRA PLA ADC ROR ARR JMP ADC ROR RRA
7- BVS ADC JAM RRA NOP ADC ROR RRA SEI ADC NOP RRA NOP ADC ROR RRA
8- NOP STA NOP SAX STY STA STX SAX DEY NOP TXA ANE STY STA STX SAX
9- BCC STA JAM SHA STY STA STX SAX TYA STA TXS TAS SHY STA SHX SHA
A- LDY LDA LDX LAX LDY LDA LDX LAX TAY LDA TAX LAX LDY LDA LDX LAX
B- BCS LDA JAM LAX LDY LDA LDX LAX CLV LDA TSX LAS LDY LDA LDX LAX
C- CPY CMP NOP DCP CPY CMP DEC DCP INY CMP DEX SBX CPY CMP DEC DCP
D- BNE CMP JAM DCP NOP CMP DEC DCP CLD CMP NOP DCP NOP CMP DEC DCP
E- CPX SBC NOP ISC CPX SBC INC ISC INX SBC NOP SBC CPX SBC INC ISC
F- BEQ SBC JAM ISC NOP SBC INC ISC SED SBC NOP ISC NOP SBC INC ISC

Standard Opcodes

This section covers the official, documented NMOS 6502 opcodes.

ADC (ADd with Carry)

Adds memory and the Carry flag to the accumulator. To perform an 8-bit addition, a preceding `CLC` is required. The `V` flag detects signed overflow, and the `D` flag enables BCD arithmetic. Affects Flags: N, V, Z, C

Mode Syntax HEX LEN TIM
Immediate ADC #$44 $69 2 2
Zero Page ADC $44 $65 2 3
Zero Page,X ADC $44,X $75 2 4
Absolute ADC $4400 $6D 3 4
Absolute,X ADC $4400,X $7D 3 4+
Absolute,Y ADC $4400,Y $79 3 4+
Indirect,X ADC ($44,X) $61 2 6
Indirect,Y ADC ($44),Y $71 2 5+

AND (bitwise AND with accumulator)

Performs a bitwise AND between the accumulator and a memory value. Primarily used to mask (clear) bits. Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Immediate AND #$44 $29 2 2
Zero Page AND $44 $25 2 3
Zero Page,X AND $44,X $35 2 4
Absolute AND $4400 $2D 3 4
Absolute,X AND $4400,X $3D 3 4+
Absolute,Y AND $4400,Y $39 3 4+
Indirect,X AND ($44,X) $21 2 6
Indirect,Y AND ($44),Y $31 2 5+

ASL (Arithmetic Shift Left)

Shifts an operand left by one bit. Bit 0 is cleared to 0, and the old bit 7 is shifted into the Carry flag. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Accumulator ASL A $0A 1 2
Zero Page ASL $44 $06 2 5
Zero Page,X ASL $44,X $16 2 6
Absolute ASL $4400 $0E 3 6
Absolute,X ASL $4400,X $1E 3 7

Branch Instructions

Branch instructions alter program flow based on the state of a specific flag. All use relative addressing, taking a signed 8-bit offset. A branch costs 2 cycles if not taken, 3 if taken within the same page, and 4 if the destination crosses a page boundary. To create an unconditional branch (`BRA`), branch on a flag with a known state. The `V` flag is a good candidate, as it is unaffected by most operations: `CLV` followed by `BVC` will always branch. Affects Flags: none

Mnemonic Name HEX
BCC Branch on Carry Clear (C=0) $90
BCS Branch on Carry Set (C=1) $B0
BEQ Branch on EQual (Z=1) $F0
BNE Branch on Not Equal (Z=0) $D0
BMI Branch on MInus (N=1) $30
BPL Branch on PLus (N=0) $10
BVC Branch on oVerflow Clear (V=0) $50
BVS Branch on oVerflow Set (V=1) $70

BIT (test BITS)

Performs a non-destructive `AND` between the accumulator and memory to set the Z flag, without altering any registers. It also copies bit 7 and bit 6 of the memory operand directly to the N and V flags, respectively. This makes it an essential tool for polling I/O registers. Affects Flags: N, V, Z

Mode Syntax HEX LEN TIM
Zero Page BIT $44 $24 2 3
Absolute BIT $4400 $2C 3 4

BRK (BReaK)

Forces a software interrupt. It pushes PC+2 and the processor status (with the B flag set) to the stack, then jumps via the IRQ vector ($FFFE). An `RTI` returns to the address of `BRK + 2`, allowing it to replace a 2-byte instruction for debugging purposes. Affects Flags: B

Mode Syntax HEX LEN TIM
Implied BRK $00 1 7

Compare Instructions

These instructions perform a non-destructive subtraction (`Register - Memory`) to set the N, Z, and C flags. They are fundamental for conditional logic and comparisons.

  • C flag: Set if `Register >= Memory` (no borrow).
  • Z flag: Set if `Register == Memory`.
  • N flag: Set to bit 7 of the subtraction result.

CMP (CoMPare accumulator)

Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Immediate CMP #$44 $C9 2 2
Zero Page CMP $44 $C5 2 3
Zero Page,X CMP $44,X $D5 2 4
Absolute CMP $4400 $CD 3 4
Absolute,X CMP $4400,X $DD 3 4+
Absolute,Y CMP $4400,Y $D9 3 4+
Indirect,X CMP ($44,X) $C1 2 6
Indirect,Y CMP ($44),Y $D1 2 5+

CPX (ComPare X register)

Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Immediate CPX #$44 $E0 2 2
Zero Page CPX $44 $E4 2 3
Absolute CPX $4400 $EC 3 4

CPY (ComPare Y register)

Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Immediate CPY #$44 $C0 2 2
Zero Page CPY $44 $C4 2 3
Absolute CPY $4400 $CC 3 4

Decrement & Increment Instructions

These modify a register or memory location by one. Register operations are 1-byte, 2-cycle instructions. Memory operations are read-modify-write and take longer.

DEC (DECrement memory)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Zero Page DEC $44 $C6 2 5
Zero Page,X DEC $44,X $D6 2 6
Absolute DEC $4400 $CE 3 6
Absolute,X DEC $4400,X $DE 3 7

DEX (DEcrement X register)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Implied DEX $CA 1 2

DEY (DEcrement Y register)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Implied DEY $88 1 2

INC (INCrement memory)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Zero Page INC $44 $E6 2 5
Zero Page,X INC $44,X $F6 2 6
Absolute INC $4400 $EE 3 6
Absolute,X INC $4400,X $FE 3 7

INX (INcrement X register)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Implied INX $E8 1 2

INY (INcrement Y register)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Implied INY $C8 1 2

EOR (bitwise Exclusive OR)

Performs a bitwise XOR between the accumulator and memory. Useful for flipping specific bits or for simple checksum calculations. Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Immediate EOR #$44 $49 2 2
Zero Page EOR $44 $45 2 3
Zero Page,X EOR $44,X $55 2 4
Absolute EOR $4400 $4D 3 4
Absolute,X EOR $4400,X $5D 3 4+
Absolute,Y EOR $4400,Y $59 3 4+
Indirect,X EOR ($44,X) $41 2 6
Indirect,Y EOR ($44),Y $51 2 5+

Flag Instructions

These single-byte, 2-cycle instructions directly manipulate the processor status flags. It is critical to use `CLD` on startup, as the power-on state of the D flag is undefined. Affects Flags: as noted

Mnemonic Function HEX
CLC C = 0 $18
SEC C = 1 $38
CLD D = 0 $D8
SED D = 1 $F8
CLI I = 0 (Enable IRQs) $58
SEI I = 1 (Disable IRQs) $78
CLV V = 0 $B8

JMP (JuMP)

Unconditionally transfers program control to a new location. The indirect mode has an infamous hardware bug: if the low byte of the indirect vector is $FF (e.g., `JMP ($30FF)`), the high byte of the jump address is fetched from `$3000`, not `$3100`. Affects Flags: none

Mode Syntax HEX LEN TIM
Absolute JMP $5597 $4C 3 3
Indirect JMP ($5597) $6C 3 5

JSR (Jump to SubRoutine)

Pushes the return address (the address of the last byte of the `JSR` instruction) onto the stack and jumps to a new location. Paired with `RTS` for standard subroutine calls. Affects Flags: none

Mode Syntax HEX LEN TIM
Absolute JSR $5597 $20 3 6

Load Instructions

Load instructions copy a byte from memory into a register, setting the N and Z flags based on the value loaded. Note the addressing mode asymmetries: `LDX` has a `Zero Page,Y` mode while `LDY` has an `Absolute,X` mode, but not vice-versa.

LDA (LoaD Accumulator)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Immediate LDA #$44 $A9 2 2
Zero Page LDA $44 $A5 2 3
Zero Page,X LDA $44,X $B5 2 4
Absolute LDA $4400 $AD 3 4
Absolute,X LDA $4400,X $BD 3 4+
Absolute,Y LDA $4400,Y $B9 3 4+
Indirect,X LDA ($44,X) $A1 2 6
Indirect,Y LDA ($44),Y $B1 2 5+

LDX (LoaD X register)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Immediate LDX #$44 $A2 2 2
Zero Page LDX $44 $A6 2 3
Zero Page,Y LDX $44,Y $B6 2 4
Absolute LDX $4400 $AE 3 4
Absolute,Y LDX $4400,Y $BE 3 4+

LDY (LoaD Y register)

Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Immediate LDY #$44 $A0 2 2
Zero Page LDY $44 $A4 2 3
Zero Page,X LDY $44,X $B4 2 4
Absolute LDY $4400 $AC 3 4
Absolute,X LDY $4400,X $BC 3 4+

LSR (Logical Shift Right)

Shifts an operand right by one bit. Bit 7 is cleared to 0, and the old bit 0 is shifted into the Carry flag. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Accumulator LSR A $4A 1 2
Zero Page LSR $44 $46 2 5
Zero Page,X LSR $44,X $56 2 6
Absolute LSR $4400 $4E 3 6
Absolute,X LSR $4400,X $5E 3 7

NOP (No OPeration)

The official NOP wastes 2 cycles and does nothing else. Many illegal opcodes also function as NOPs with different cycle and byte counts; some still perform memory reads, which can be useful for I/O timing or acknowledging interrupts without altering registers. Affects Flags: none

Mode Syntax HEX LEN TIM
Implied NOP $EA 1 2

ORA (bitwise OR with Accumulator)

Performs a bitwise OR between the accumulator and a memory value. Primarily used to set bits. Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Immediate ORA #$44 $09 2 2
Zero Page ORA $44 $05 2 3
Zero Page,X ORA $44,X $15 2 4
Absolute ORA $4400 $0D 3 4
Absolute,X ORA $4400,X $1D 3 4+
Absolute,Y ORA $4400,Y $19 3 4+
Indirect,X ORA ($44,X) $01 2 6
Indirect,Y ORA ($44),Y $11 2 5+

Register Instructions

These 1-byte, 2-cycle instructions transfer data between registers. `TXS` is unique in that it does not affect any flags. Affects Flags: N, Z (except TXS)

Mnemonic Description HEX
TAX Transfer A to X $AA
TAY Transfer A to Y $A8
TXA Transfer X to A $8A
TYA Transfer Y to A $98
TSX Transfer Stack Pointer to X $BA
TXS Transfer X to Stack Pointer $9A

ROL (ROtate Left)

Rotates an operand left by one bit. The old bit 7 is moved to the Carry flag, and the old Carry flag is moved into bit 0. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Accumulator ROL A $2A 1 2
Zero Page ROL $44 $26 2 5
Zero Page,X ROL $44,X $36 2 6
Absolute ROL $4400 $2E 3 6
Absolute,X ROL $4400,X $3E 3 7

ROR (ROtate Right)

Rotates an operand right by one bit. The old bit 0 is moved to the Carry flag, and the old Carry flag is moved into bit 7. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Accumulator ROR A $6A 1 2
Zero Page ROR $44 $66 2 5
Zero Page,X ROR $44,X $76 2 6
Absolute ROR $4400 $6E 3 6
Absolute,X ROR $4400,X $7E 3 7

RTI (ReTurn from Interrupt)

Restores the processor state after an interrupt by pulling the processor status register and program counter from the stack. Affects Flags: all

Mode Syntax HEX LEN TIM
Implied RTI $40 1 6

RTS (ReTurn from Subroutine)

Returns from a subroutine by pulling the program counter from the stack and incrementing it. Can be used to implement powerful jump tables by pushing crafted return addresses onto the stack. Affects Flags: none

Mode Syntax HEX LEN TIM
Implied RTS $60 1 6

SBC (SuBtract with Carry)

Subtracts memory and an inverted Carry flag (borrow) from the accumulator. To perform an 8-bit subtraction, a preceding `SEC` (to indicate "no borrow") is required. The `D` flag enables BCD arithmetic. Affects Flags: N, V, Z, C

Mode Syntax HEX LEN TIM
Immediate SBC #$44 $E9 2 2
Zero Page SBC $44 $E5 2 3
Zero Page,X SBC $44,X $F5 2 4
Absolute SBC $4400 $ED 3 4
Absolute,X SBC $4400,X $FD 3 4+
Absolute,Y SBC $4400,Y $F9 3 4+
Indirect,X SBC ($44,X) $E1 2 6
Indirect,Y SBC ($44),Y $F1 2 5+

Stack Instructions

These instructions interact with the hardware stack located at page one ($0100-$01FF). The 6502 stack pointer grows downwards. Affects Flags: all (for PLP) or none

Mnemonic Description HEX TIM
PHA PusH Accumulator $48 3
PLA PuLl Accumulator $68 4
PHP PusH Processor status $08 3
PLP PuLl Processor status $28 4

Store Instructions

Store instructions copy the content of a register to memory. They do not affect any flags. Note the addressing mode asymmetries, particularly the absence of accumulator-relative addressing and the presence of `STX zp,Y` and `STY zp,X`.

STA (STore Accumulator)

Affects Flags: none

Mode Syntax HEX LEN TIM
Zero Page STA $44 $85 2 3
Zero Page,X STA $44,X $95 2 4
Absolute STA $4400 $8D 3 4
Absolute,X STA $4400,X $9D 3 5
Absolute,Y STA $4400,Y $99 3 5
Indirect,X STA ($44,X) $81 2 6
Indirect,Y STA ($44),Y $91 2 6

STX (STore X register)

Affects Flags: none

Mode Syntax HEX LEN TIM
Zero Page STX $44 $86 2 3
Zero Page,Y STX $44,Y $96 2 4
Absolute STX $4400 $8E 3 4

STY (STore Y register)

Affects Flags: none

Mode Syntax HEX LEN TIM
Zero Page STY $44 $84 2 3
Zero Page,X STY $44,X $94 2 4
Absolute STY $4400 $8C 3 4

Stable & Semi-Stable Illegal Opcodes

This section details non-standard opcodes that are generally stable on NMOS 6502 and its direct variants. They often combine two standard operations into one, saving bytes and/or cycles. "Semi-stable" opcodes are marked and should be used with an understanding of their specific quirks, which are detailed in their descriptions.

SLO (ASO)

Function: ` {addr} = {addr} * 2`, then `A = A OR {addr}` (ASL followed by ORA)
Performs an `ASL` on a memory location, then `ORA`s the new value with the accumulator. Useful for multi-byte shifts where the result must be combined into a register. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Zero Page SLO $44 $07 2 5
Zero Page,X SLO $44,X $17 2 6
Absolute SLO $4400 $0F 3 6
Absolute,X SLO $4400,X $1F 3 7
Absolute,Y SLO $4400,Y $1B 3 7
Indirect,X SLO ($44,X) $03 2 8
Indirect,Y SLO ($44),Y $13 2 8

Example: A 24-bit shift where the high byte is also needed in A.

; Assuming A is zero before this sequence:
  SLO data+2    ; Shifts data+2, A now holds the result
  ROL data+1
  ROL data+0
; This saves an LDA instruction compared to the standard ASL/ROL sequence.

RLA

Function: `{addr} = ROL {addr}`, then `A = A AND {addr}` (ROL followed by AND)
Performs a `ROL` on memory, then `AND`s the new value with the accumulator. Excellent for scrolling effects where a rotated tile needs to be masked by a background. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Zero Page RLA $44 $27 2 5
Zero Page,X RLA $44,X $37 2 6
Absolute RLA $4400 $2F 3 6
Absolute,X RLA $4400,X $3F 3 7
Absolute,Y RLA $4400,Y $3B 3 7
Indirect,X RLA ($44,X) $23 2 8
Indirect,Y RLA ($44),Y $33 2 8

Example: Combining a sliding sprite with a background mask.

; Standard method (16 bytes, 18 cycles):
  ROL scroll_gfx
  LDA scroll_gfx
  AND background_mask
  STA screen_ram
; Faster method (12 bytes, 14 cycles):
  LDA background_mask
  RLA scroll_gfx       ; shift left and combine in one go
  STA screen_ram

SRE (LSE)

Function: `{addr} = LSR {addr}`, then `A = A EOR {addr}` (LSR followed by EOR)
Performs an `LSR` on memory, then `EOR`s the new value with the accumulator. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Zero Page SRE $44 $47 2 5
Zero Page,X SRE $44,X $57 2 6
Absolute SRE $4400 $4F 3 6
Absolute,X SRE $4400,X $5F 3 7
Absolute,Y SRE $4400,Y $5B 3 7
Indirect,X SRE ($44,X) $43 2 8
Indirect,Y SRE ($44),Y $53 2 8

RRA

Function: `{addr} = ROR {addr}`, then `A = A ADC {addr}` (ROR followed by ADC)
Performs a `ROR` on memory, then adds the new value with carry to the accumulator. Inherits the decimal mode dependency from `ADC`. Affects Flags: N, V, Z, C

Mode Syntax HEX LEN TIM
Zero Page RRA $44 $67 2 5
Zero Page,X RRA $44,X $77 2 6
Absolute RRA $4400 $6F 3 6
Absolute,X RRA $4400,X $7F 3 7
Absolute,Y RRA $4400,Y $7B 3 7
Indirect,X RRA ($44,X) $63 2 8
Indirect,Y RRA ($44),Y $73 2 8

SAX (AXS)

Function: `{addr} = A & X`
Stores the result of a bitwise `AND` between the A and X registers into memory. The A and X registers themselves are not modified, and no flags are affected. Affects Flags: none

Mode Syntax HEX LEN TIM
Zero Page SAX $44 $87 2 3
Zero Page,Y SAX $44,X $97 2 4
Absolute SAX $4400 $8F 3 4
Indirect,X SAX ($44,X) $83 2 6

LAX

Function: `A, X = {addr}`
Loads both the A and X registers with the same value from memory. Saves a byte and cycles over a standard `LDA`/`TAX` pair. Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Zero Page LAX $44 $A7 2 3
Zero Page,Y LAX $44,Y $B7 2 4
Absolute LAX $4400 $AF 3 4
Absolute,Y LAX $4400,Y $BF 3 4+
Indirect,X LAX ($44,X) $A3 2 6
Indirect,Y LAX ($44),Y $B3 2 5+

DCP (DCM)

Function: `{addr} = {addr} - 1`, then `A CMP {addr}` (DEC followed by CMP)
Decrements a memory location, then compares the new value with the accumulator. Excellent for loop counters. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Zero Page DCP $44 $C7 2 5
Zero Page,X DCP $44,X $D7 2 6
Absolute DCP $4400 $CF 3 6
Absolute,X DCP $4400,X $DF 3 7
Absolute,Y DCP $4400,Y $DB 3 7
Indirect,X DCP ($44,X) $C3 2 8
Indirect,Y DCP ($44),Y $D3 2 8

Example: A more efficient 16-bit decrement loop on `ptr`.

; Instead of DEC ptr / LDA ptr / CMP #$FF ...
  LDA #$FF
  DCP ptr       ; Decrements ptr, compares new value with A.
  BNE loop      ; Branch if ptr did not underflow from $00
  DEC ptr+1     ; Handle high byte underflow
loop:

ISC (ISB, INS)

Function: `{addr} = {addr} + 1`, then `A = A SBC {addr}` (INC followed by SBC)
Increments a memory location, then subtracts the new value from the accumulator. Inherits decimal mode dependency from `SBC`. Affects Flags: N, V, Z, C

Mode Syntax HEX LEN TIM
Zero Page ISC $44 $E7 2 5
Zero Page,X ISC $44,X $F7 2 6
Absolute ISC $4400 $EF 3 6
Absolute,X ISC $4400,X $FF 3 7
Absolute,Y ISC $4400,Y $FB 3 7
Indirect,X ISC ($44,X) $E3 2 8
Indirect,Y ISC ($44),Y $F3 2 8

Example: A loop that counts up to a value in A.

; Instead of INC counter / LDA counter / CMP #END_VALUE
  LDA #END_VALUE
  SEC
loop:
  ISC counter   ; INC counter, then SBC counter. Z will be set when they match.
  BNE loop

ANC

Function: `A = A & #{imm}`, then `C = N`
Performs a standard `AND` immediate, but also copies the resulting N flag (bit 7 of A) into the C flag. This is an excellent way to perform a mask and a bit test in a single, 2-cycle instruction. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Immediate ANC #$44 $0B 2 2
Immediate ANC #$44 $2B 2 2

Example: Test bit 7 and branch, without needing to preserve the Carry flag.

; Instead of PHP / AND #$80 / BEQ ... PLP
  ANC #$80      ; Sets C=1 if bit 7 is set, N=1 if bit 7 is set, Z=0 if bit 7 is set.
  BCC bit_is_clear

ALR (ASR)

Function: `A = (A & #{imm}) / 2` (AND immediate followed by LSR A)
Performs an `AND` immediate, then performs a logical shift right on the accumulator. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Immediate ALR #$44 $4B 2 2

ARR

Function: `A = (A & #{imm})`, then a complex `ROR`-like operation.
Performs an `AND` immediate, then rotates the accumulator right. Warning: Flag calculation is unusual and decimal mode dependent. After the `AND`, V is set by `(A bit 6) EOR (A bit 7)`. During the rotate, C is set from the original A bit 6, and the new bit 7 is set from the original C flag. Bit 0 is lost. Due to its complexity, it is rarely used. Affects Flags: N, V, Z, C

Mode Syntax HEX LEN TIM
Immediate ARR #$44 $6B 2 2

SBX (AXS)

Function: `X = (A & X) - #{imm}`
Calculates `A & X`, then subtracts an immediate value from this temporary result, storing the final value in X. Flags are set as if from a `CMP` instruction (`(A & X) >= imm` sets the Carry). Does not respect decimal mode and is not affected by the initial state of the Carry flag. Affects Flags: N, Z, C

Mode Syntax HEX LEN TIM
Immediate SBX #$44 $CB 2 2

Example: A faster decrement of X by a constant value.

; Standard method (8 cycles, 5 bytes):
  TXA
  SEC
  SBC #$10
  TAX
; Faster method (4 cycles, 3 bytes):
  TXA         ; A and X are now equal, so (A & X) = X.
  SBX #$10    ; C flag state before this instruction is irrelevant.

'Unstable High Byte' Opcodes

The following opcodes are semi-stable. They combine a load or store operation with a bitwise `AND`, but their behavior can be unreliable under specific hardware conditions. Warning:

  1. Page Boundary Crossing: If the effective address calculation (`address + index`) crosses a page boundary, the result can be unpredictable. Avoid crossing page boundaries with these instructions.
  2. Hardware Dependency: The `AND` operation part of the instruction may fail if the CPU's RDY line is pulled low during a specific cycle (e.g., by sprite DMA). This makes the instruction behave like a standard store (`STA`/`STX`/`STY`). To mitigate this, one can use a target address where the high byte is `$FE`, so the `AND` with `(HighByte+1)` becomes an `AND` with `$FF`, which has no effect.

SHA (AXA, AHX)

(Semi-Stable) Function: `{addr} = A & X & (HighByte({addr}) + 1)`
Stores the result of `A AND X AND (High Byte of target address + 1)` into memory. See warnings above. Affects Flags: none

Mode Syntax HEX LEN TIM
Absolute,Y SHA $4400,Y $9F 3 5
Indirect,Y SHA ($44),Y $93 2 6

SHX (SXA)

(Semi-Stable) Function: `{addr} = X & (HighByte({addr}) + 1)`
Stores the result of `X AND (High Byte of target address + 1)` into memory. See warnings above. Affects Flags: none

Mode Syntax HEX LEN TIM
Absolute,Y SHX $4400,Y $9E 3 5

SHY (SYA)

(Semi-Stable) Function: `{addr} = Y & (HighByte({addr}) + 1)`
Stores the result of `Y AND (High Byte of target address + 1)` into memory. See warnings above. Affects Flags: none

Mode Syntax HEX LEN TIM
Absolute,X SHY $4400,X $9C 3 5

LAS

(Semi-Stable) Function: `A, X, S = {addr} & S`
Loads memory, `AND`s it with the Stack Pointer, and loads the result into A, X, and the Stack Pointer. See warnings above. Affects Flags: N, Z

Mode Syntax HEX LEN TIM
Absolute,Y LAS $4400,Y $BB 3 4+

TAS (SHS)

(Semi-Stable) Function: `S = A & X`, then `{addr} = S & (HighByte({addr}) + 1)`
Calculates `A & X` and puts the result in the Stack Pointer. Then it `AND`s this new S value with `(High Byte of target address + 1)` and stores the result in memory. See warnings above. Affects Flags: none

Mode Syntax HEX LEN TIM
Absolute,Y TAS $4400,Y $9B 3 5