Branches | Decimal Mode | Interrupt Flag | Overflow Flag | Program Counter | Stack | Times | Wrap-around |
ADC | AND | ASL | BCC | BCS | BEQ | BIT | BMI | BNE | BPL | BRK | BVC | BVS | CLC |
CLD | CLI | CLV | CMP | CPX | CPY | DEC | DEX | DEY | EOR | INC | INX | INY | JMP |
JSR | LDA | LDX | LDY | LSR | NOP | ORA | PHA | PHP | PLA | PLP | ROL | ROR | RTI |
RTS | SBC | SEC | SED | SEI | STA | STX | STY | TAX | TAY | TSX | TXA | TXS | TYA |
Affects Flags: N V Z C
MODE SYNTAX HEX LEN TIMImmediate ADC #$44 $69 2 2Zero Page ADC $44 $65 2 3Zero Page,X ADC $44,X $75 2 4Absolute ADC $4400 $6D 3 4Absolute,X ADC $4400,X $7D 3 4+Absolute,Y ADC $4400,Y $79 3 4+Indirect,X ADC ($44,X) $61 2 6Indirect,Y ADC ($44),Y $71 2 5++ add 1 cycle if page boundary crossedADC results are dependant on the setting of thedecimal flag. In decimalmode, addition is carried out on the assumption that the values involved arepacked BCD (Binary Coded Decimal).
There is no way to add without carry.
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMImmediate AND #$44 $29 2 2Zero Page AND $44 $25 2 3Zero Page,X AND $44,X $35 2 4Absolute AND $4400 $2D 3 4Absolute,X AND $4400,X $3D 3 4+Absolute,Y AND $4400,Y $39 3 4+Indirect,X AND ($44,X) $21 2 6Indirect,Y AND ($44),Y $31 2 5++ add 1 cycle if page boundary crossed
Affects Flags: N Z C
MODE SYNTAX HEX LEN TIMAccumulator ASL A $0A 1 2Zero Page ASL $44 $06 2 5Zero Page,X ASL $44,X $16 2 6Absolute ASL $4400 $0E 3 6Absolute,X ASL $4400,X $1E 3 7ASL shifts all bits left one position. 0 is shifted into bit 0 and theoriginal bit 7 is shifted into the Carry.
Affects Flags: N V Z
MODE SYNTAX HEX LEN TIMZero Page BIT $44 $24 2 3Absolute BIT $4400 $2C 3 4BIT sets the Z flag as though the value in the address tested were ANDedwith the accumulator. The N and V flags are set to match bits 7 and 6respectively in the value stored at the tested address.
BIT is often used to skip one or two following bytes as in:
CLOSE1 LDX #$10 If entered here, we .BYTE $2C effectively performCLOSE2 LDX #$20 a BIT test on $20A2, .BYTE $2C another one on $30A2,CLOSE3 LDX #$30 and end up with the XCLOSEX LDA #12 register still at $10 STA ICCOM,X upon arrival here.Beware: a BIT instruction used in this way as a NOP does have effects: the flagsmay be modified, and the read of the absolute address, if it happens to access anI/O device, may cause an unwanted action.
Affect Flags: none
All branches are relative mode and have a length of two bytes. Syntax is "BxxDisplacement" or (better) "Bxx Label". See the notes on theProgram Counter for more ondisplacements.
Branches are dependant on the status of the flag bits when the op code isencountered. A branch not taken requires two machine cycles. Add one if thebranch is taken and add one more if the branch crosses a page boundary.
MNEMONIC HEXBPL (Branch on PLus) $10BMI (Branch on MInus) $30BVC (Branch on oVerflow Clear) $50BVS (Branch on oVerflow Set) $70BCC (Branch on Carry Clear) $90BCS (Branch on Carry Set) $B0BNE (Branch on Not Equal) $D0BEQ (Branch on EQual) $F0There is no BRA (BRanch Always) instruction but it can be easily emulatedby branching on the basis of a known condition. One of the best flags to use forthis purpose is theoVerflow which is unchangedby all but addition and subtraction operations.
A page boundary crossing occurs when the branch destination is on a differentpage than the instruction AFTER the branch instruction. For example:
SEC BCS LABEL NOPA page boundary crossing occurs (i.e. the BCS takes 4 cycles) when (theaddress of) LABEL and the NOP are on different pages. This means that
CLV BVC LABEL LABEL NOPthe BVC instruction will take 3 cycles no matter what address it is locatedat.
Affects Flags: B
MODE SYNTAX HEX LEN TIMImplied BRK $00 1 7BRK causes a non-maskable interrupt and increments the program counter byone. Therefore anRTI willgo to the address of the BRK +2 so that BRK may be used to replace atwo-byte instruction for debugging and the subsequent RTI will be correct.
Affects Flags: N Z C
MODE SYNTAX HEX LEN TIMImmediate CMP #$44 $C9 2 2Zero Page CMP $44 $C5 2 3Zero Page,X CMP $44,X $D5 2 4Absolute CMP $4400 $CD 3 4Absolute,X CMP $4400,X $DD 3 4+Absolute,Y CMP $4400,Y $D9 3 4+Indirect,X CMP ($44,X) $C1 2 6Indirect,Y CMP ($44),Y $D1 2 5++ add 1 cycle if page boundary crossedCompare sets flags as if a subtraction had been carried out. If the valuein the accumulator is equal or greater than the compared value, the Carry willbe set. The equal (Z) and negative (N) flags will be set based on equality or lackthereof and the sign (i.e. A>=$80) of the accumulator.
Affects Flags: N Z C
MODE SYNTAX HEX LEN TIMImmediate CPX #$44 $E0 2 2Zero Page CPX $44 $E4 2 3Absolute CPX $4400 $EC 3 4Operation and flag results are identical to equivalent mode accumulatorCMP ops.
Affects Flags: N Z C
MODE SYNTAX HEX LEN TIMImmediate CPY #$44 $C0 2 2Zero Page CPY $44 $C4 2 3Absolute CPY $4400 $CC 3 4Operation and flag results are identical to equivalent mode accumulatorCMP ops.
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMZero Page DEC $44 $C6 2 5Zero Page,X DEC $44,X $D6 2 6Absolute DEC $4400 $CE 3 6Absolute,X DEC $4400,X $DE 3 7
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMImmediate EOR #$44 $49 2 2Zero Page EOR $44 $45 2 3Zero Page,X EOR $44,X $55 2 4Absolute EOR $4400 $4D 3 4Absolute,X EOR $4400,X $5D 3 4+Absolute,Y EOR $4400,Y $59 3 4+Indirect,X EOR ($44,X) $41 2 6Indirect,Y EOR ($44),Y $51 2 5++ add 1 cycle if page boundary crossed
Affect Flags: as noted
These instructions are implied mode, have a length of one byte and requiretwo machine cycles.
MNEMONIC HEXCLC (CLear Carry) $18SEC (SEt Carry) $38CLI (CLear Interrupt) $58SEI (SEt Interrupt) $78CLV (CLear oVerflow) $B8CLD (CLear Decimal) $D8SED (SEt Decimal) $F8Notes:
The Interrupt flag is used to prevent (SEI) orenable (CLI) maskable interrupts (aka IRQ's). It does not signal the presence orabsence of an interrupt condition. The 6502 will set this flag automatically inresponse to an interrupt and restore it to its prior status on completion of theinterrupt service routine. If you want your interrupt service routine to permitother maskable interrupts, you must clear the I flag in your code.
The Decimal flag controls how the 6502 adds andsubtracts. If set, arithmetic is carried out in packed binary coded decimal.This flag is unchanged by interrupts and is unknown on power-up. The implicationis that a CLD should be included in boot or interrupt coding.
The Overflow flag is generally misunderstood andtherefore under-utilised. After an ADC or SBC instruction, the overflow flagwill be set if the twos complement result is less than -128 or greater than+127, and it will cleared otherwise. In twos complement, $80 through $FFrepresents -128 through -1, and $00 through $7F represents 0 through +127.Thus, after:
CLC LDA #$7F ; +127 ADC #$01 ; + +1the overflow flag is 1 (+127 + +1 = +128), and after:
CLC LDA #$81 ; -127 ADC #$FF ; + -1the overflow flag is 0 (-127 + -1 = -128). The overflow flag is notaffected by increments, decrements, shifts and logical operations i.e. onlyADC, BIT, CLV, PLP, RTI and SBC affect it. There is no op code to set theoverflow but a BIT test on an RTS instruction will do the trick.
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMZero Page INC $44 $E6 2 5Zero Page,X INC $44,X $F6 2 6Absolute INC $4400 $EE 3 6Absolute,X INC $4400,X $FE 3 7
Affects Flags: none
MODE SYNTAX HEX LEN TIMAbsolute JMP $5597 $4C 3 3Indirect JMP ($5597) $6C 3 5JMP transfers program execution to the following address (absolute) or tothe location contained in the following address (indirect). Note that there isno carry associated with the indirect jump so:
AN INDIRECT JUMP MUST NEVER USE AVECTOR BEGINNING ON THE LAST BYTEOF A PAGEFor example if address $3000 contains $40, $30FF contains $80, and $3100contains $50, the result of JMP ($30FF) will be a transfer of control to $4080rather than $5080 as you intended i.e. the 6502 took the low byte of the addressfrom $30FF and the high byte from $3000.
Affects Flags: none
MODE SYNTAX HEX LEN TIMAbsolute JSR $5597 $20 3 6JSR pushes the address-1 of the next operation on to the stack beforetransferring program control to the following address. Subroutines are normallyterminated by aRTS opcode.
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMImmediate LDA #$44 $A9 2 2Zero Page LDA $44 $A5 2 3Zero Page,X LDA $44,X $B5 2 4Absolute LDA $4400 $AD 3 4Absolute,X LDA $4400,X $BD 3 4+Absolute,Y LDA $4400,Y $B9 3 4+Indirect,X LDA ($44,X) $A1 2 6Indirect,Y LDA ($44),Y $B1 2 5++ add 1 cycle if page boundary crossed
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMImmediate LDX #$44 $A2 2 2Zero Page LDX $44 $A6 2 3Zero Page,Y LDX $44,Y $B6 2 4Absolute LDX $4400 $AE 3 4Absolute,Y LDX $4400,Y $BE 3 4++ add 1 cycle if page boundary crossed
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMImmediate LDY #$44 $A0 2 2Zero Page LDY $44 $A4 2 3Zero Page,X LDY $44,X $B4 2 4Absolute LDY $4400 $AC 3 4Absolute,X LDY $4400,X $BC 3 4++ add 1 cycle if page boundary crossed
Affects Flags: N Z C
MODE SYNTAX HEX LEN TIMAccumulator LSR A $4A 1 2Zero Page LSR $44 $46 2 5Zero Page,X LSR $44,X $56 2 6Absolute LSR $4400 $4E 3 6Absolute,X LSR $4400,X $5E 3 7LSR shifts all bits right one position. 0 is shifted into bit 7 and theoriginal bit 0 is shifted into the Carry.
Use caution with indexed zero page operations as they are subject towrap-around. For example, if the X register holds $FF and you execute LDA $80,Xyou will not access $017F as you might expect; instead you access $7F i.e.$80-1. This characteristic can be used to advantage but make sure your code iswell commented.
It is possible, however, to access $017F when X = $FF by using the Absolute,Xaddressing mode of LDA $80,X. That is, instead of:
LDA $80,X ; ZeroPage,X - the resulting object code is: B5 80which accesses $007F when X=$FF, use:
LDA $0080,X ; Absolute,X - the resulting object code is: BD 80 00which accesses $017F when X = $FF (a at cost of one additional byte and oneadditional cycle). All of the ZeroPage,X and ZeroPage,Y instructions exceptSTX ZeroPage,Y and STY ZeroPage,X have a corresponding Absolute,X andAbsolute,Y instruction. Unfortunately, a lot of 6502 assemblers don't have aneasy way to force Absolute addressing, i.e. most will assemble a LDA $0080,Xas B5 80. One way to overcome this is to insert the bytes using the .BYTEpseudo-op (on some 6502 assemblers this pseudo-op is called DB or DFB,consult the assembler documentation) as follows:
.BYTE $BD,$80,$00 ; LDA $0080,X (absolute,X addressing mode)The comment is optional, but highly recommended for clarity.
In cases where you are writing code that will be relocated you must considerwrap-around when assigning dummy values for addresses that will be adjusted.Both zero and the semi-standard $FFFF should be avoided for dummy labels. Theuse of zero or zero page values will result in assembled code with zero pageopcodes when you wanted absolute codes. With $FFFF, the problem is inaddresses+1 as you wrap around to page 0.
When the 6502 is ready for the next instruction it increments the programcounter before fetching the instruction. Once it has the op code, it incrementsthe program counter by the length of the operand, if any. This must be accountedfor when calculating branches or when pushing bytes to create a false returnaddress (i.e. jump table addresses are made up of addresses-1 when it isintended to use an RTS rather than a JMP).
The program counter is loaded least signifigant byte first. Therefore themost signifigant byte must be pushed first when creating a false return address.
When calculating branches a forward branch of 6 skips the following 6 bytesso, effectively the program counter points to the address that is 8 bytes beyondthe address of the branch opcode; and a backward branch of $FA (256-6) goes toan address 4 bytes before the branch instruction.
Op code execution times are measured in machine cycles; one machine cycleequals one clock cycle. Many instructions require one extra cycle forexecution if a page boundary is crossed; these are indicated by a + followingthe time values shown.
Affects Flags: none
MODE SYNTAX HEX LEN TIMImplied NOP $EA 1 2NOP is used to reserve space for future modifications or effectively REMout existing code.
Affects Flags: N Z
MODE SYNTAX HEX LEN TIMImmediate ORA #$44 $09 2 2Zero Page ORA $44 $05 2 3Zero Page,X ORA $44,X $15 2 4Absolute ORA $4400 $0D 3 4Absolute,X ORA $4400,X $1D 3 4+Absolute,Y ORA $4400,Y $19 3 4+Indirect,X ORA ($44,X) $01 2 6Indirect,Y ORA ($44),Y $11 2 5++ add 1 cycle if page boundary crossed
Affect Flags: N Z
These instructions are implied mode, have a length of one byte and requiretwo machine cycles.
MNEMONIC HEXTAX (Transfer A to X) $AATXA (Transfer X to A) $8ADEX (DEcrement X) $CAINX (INcrement X) $E8TAY (Transfer A to Y) $A8TYA (Transfer Y to A) $98DEY (DEcrement Y) $88INY (INcrement Y) $C8
Affects Flags: N Z C
MODE SYNTAX HEX LEN TIMAccumulator ROL A $2A 1 2Zero Page ROL $44 $26 2 5Zero Page,X ROL $44,X $36 2 6Absolute ROL $4400 $2E 3 6Absolute,X ROL $4400,X $3E 3 7ROL shifts all bits left one position. The Carry is shifted into bit 0 andthe original bit 7 is shifted into the Carry.
Affects Flags: N Z C
MODE SYNTAX HEX LEN TIMAccumulator ROR A $6A 1 2Zero Page ROR $44 $66 2 5Zero Page,X ROR $44,X $76 2 6Absolute ROR $4400 $6E 3 6Absolute,X ROR $4400,X $7E 3 7ROR shifts all bits right one position. The Carry is shifted into bit 7and the original bit 0 is shifted into the Carry.
Affects Flags: all
MODE SYNTAX HEX LEN TIMImplied RTI $40 1 6RTI retrieves the Processor Status Word (flags) and the Program Counterfrom the stack in that order (interrupts push the PC first and then the PSW).
Note that unlike RTS, the return address on the stack is the actual addressrather than the address-1.
Affects Flags: none
MODE SYNTAX HEX LEN TIMImplied RTS $60 1 6RTS pulls the top two bytes off the stack (low byte first) and transfersprogram control to that address+1. It is used, as expected, to exit a subroutineinvoked viaJSR whichpushed the address-1.
RTS is frequently used to implement a jump table where addresses-1 are pushedonto the stack and accessed via RTS eg. to access the second of four routines:
LDX #1 JSR EXEC JMP SOMEWHERELOBYTE .BYTE <ROUTINE0-1,<ROUTINE1-1 .BYTE <ROUTINE2-1,<ROUTINE3-1HIBYTE .BYTE >ROUTINE0-1,>ROUTINE1-1 .BYTE >ROUTINE2-1,>ROUTINE3-1EXEC LDA HIBYTE,X PHA LDA LOBYTE,X PHA RTS
Affects Flags: N V Z C
MODE SYNTAX HEX LEN TIMImmediate SBC #$44 $E9 2 2Zero Page SBC $44 $E5 2 3Zero Page,X SBC $44,X $F5 2 4Absolute SBC $4400 $ED 3 4Absolute,X SBC $4400,X $FD 3 4+Absolute,Y SBC $4400,Y $F9 3 4+Indirect,X SBC ($44,X) $E1 2 6Indirect,Y SBC ($44),Y $F1 2 5++ add 1 cycle if page boundary crossedSBC results are dependant on the setting of the decimal flag. In decimalmode, subtraction is carried out on the assumption that the values involved arepacked BCD (Binary Coded Decimal).
There is no way to subtract without the carry which works as an inverseborrow. i.e, to subtract you set the carry before the operation. If the carry iscleared by the operation, it indicates a borrow occurred.
Affects Flags: none
MODE SYNTAX HEX LEN TIMZero Page STA $44 $85 2 3Zero Page,X STA $44,X $95 2 4Absolute STA $4400 $8D 3 4Absolute,X STA $4400,X $9D 3 5Absolute,Y STA $4400,Y $99 3 5Indirect,X STA ($44,X) $81 2 6Indirect,Y STA ($44),Y $91 2 6
These instructions are implied mode, have a length of one byte and requiremachine cycles as indicated. The "PuLl" operations are known as "POP" on mostother microprocessors. With the 6502, the stack is always on page one($100-$1FF) and works top down.
MNEMONIC HEX TIMTXS (Transfer X to Stack ptr) $9A 2TSX (Transfer Stack ptr to X) $BA 2PHA (PusH Accumulator) $48 3PLA (PuLl Accumulator) $68 4PHP (PusH Processor status) $08 3PLP (PuLl Processor status) $28 4
Affects Flags: none
MODE SYNTAX HEX LEN TIMZero Page STX $44 $86 2 3Zero Page,Y STX $44,Y $96 2 4Absolute STX $4400 $8E 3 4
Affects Flags: none
MODE SYNTAX HEX LEN TIMZero Page STY $44 $84 2 3Zero Page,X STY $44,X $94 2 4Absolute STY $4400 $8C 3 4