This the multi-page printable view of this section.Click here to print.

Return to the regular view of this page.

Program Flow

Branch & Jumps

Table of Contents

1 - Flags

Flag manipulation

The flag instructions manipulate some of the flags in the status register.

CLC - Clear Carry Flag

CLC is used prior to addition with the ADC instruction to keep the carry flag affecting the result.

On the 6502 a CLC before a BCC instruction can be used to implement a branch always, which is relocatable. This is unnecessary since the 65C02 with it's BRA instruction.

On the 16-bit processors a CLC followed by XCE instruction is used to switch the 65802 & 65816 processors into native mode.

SEC - Set Carry Flag

SEC is used prior to subtraction using the SBC instruction to keep the carry flag affecting the result.

On the 16-bit processors a SEC followed by XCE instruction is used to switch the 65802 & 65816 processors into 6502 emulation mode.

CLD - Clear Decimal Mode

CLD is used to switch the processors into binary mode so that the ADC & SBC instructions will perform binary not BCD arithmetic.

SED - Set Decimal Mode

SED is used to switch the processors into decimal mode so that the ADC & SBC instructions will perform BCD not binary arithmetic.

CLI - Clear Interrupt Disable Flag

CLI is used to re-enable hardware interrupts.

When the processor starts the interrupt handler it sets the i flag to prevent another interrupt to occur during that handler. If the handler want's to allow interrupts to happen whilst it's handling a previous one it can use CLI to re-enable them. The handler doesn't need to use CLI as the RTI (ReTurn from Interrupt) instruction will clear the i flag automatically.

In user code, CLI can be used to re-enable interrupts after an SEI instruction. This is usually used during time-critical code or code that cannot be interrupted.

SEI - Clear Interrupt Disable Flag

SEI is used to disable hardware interrupts.

When the i bit is set, maskable hardware interrupts are ignored. When the processor starts the interrupt handler it sets the i flag to prevent another interrupt to occur during that handler. If the handler want's to allow interrupts to happen whilst it's handling a previous one it can use CLI to re-enable them. The handler doesn't need to use CLI as the RTI (ReTurn from Interrupt) instruction will clear the i flag automatically.

In user code, SEI can be used to disable interrupts when it needs to run time-critical code or code that cannot be interrupted. It should then use CLI once it's finished that time-critical code.

CLV - Clear Overflow Flag

CLV clears the overflow flag.

Unlike other clear flag instructions, there is no set overflow flag available. The only way the overflow flag can be set is either:

  • The BIT instruction will set overflow if bit 6 of the mask & memory is set
  • The 65816 REP instruction can clear the overflow
  • Use the Overflow pin on the processor. This is rarely used & is often not even connected.

On the 6502 a CLC before a BVC instruction can be used to implement a branch always, which is relocatable. This is unnecessary since the 65C02 with it's BRA instruction.

REP - Reset Status Bits

For each bit set in the operand byte, reset the corresponding bit in the status register. For each bit not set in the operand byte leaves the corresponding bit unchanged.

This instruction lets you clear any flag or flags in a single instruction. It is the only direct means of resetting the m & x flags.

In 6502 emulation mode (e=1) neither the b flag or bit 5 (the 6502's non-flag bit) is affected by this instruction.

Flags Affected
7 6 5 4 3 2 1 0
6502 emulation mode e=1 n v d i z c
65816 native mode e=0 n v m x d i z c

SEP - Set Status Bits

For each bit set in the operand byte, set the corresponding bit in the status register. For each bit not set in the operand byte leaves the corresponding bit unchanged.

This instruction lets you set any flag or flags in a single instruction. It is the only direct means of setting the m & x flags.

In 6502 emulation mode (e=1) neither the b flag or bit 5 (the 6502's non-flag bit) is affected by this instruction.

The bit's in the operand & their relationship with the status register is the same as the REP instruction.

Instructions
SyntaxActionOpcode Available on: # of # of Addressing Mode
(hex) 6502 65C02 65816 bytes cycles
CLC Clear Carry 18 x x x 1 2 Implied
SEC Set Carry 38 x x x 1 2 Implied
CLD Clear Decimal D8 x x x 1 2 Implied
SED Set Decimal F8 x x x 1 2 Implied
CLI Enable hardware interrupts 58 x x x 1 2 Implied
SEI Disable hardware interrupts 78 x x x 1 2 Implied
CLV Clear Overflow B8 x x x 1 2 Implied
REP #const Reset status bits C2 x 2 3 Immediate
SEP #const Set status bits E2 x 2 3 Immediate

2 - Compare Accumulator

Compare Accumulator with Memory

CMP subtracts the data at the address in the operand from the contents of the accumulator, setting the n, z & c flags based on the result. The Accumulator & Memory are unaffected by this operation.

Data size

On all processors, the data added from memory is 8-bit. However, for 16-bit processors with the m flag is clear then the data added is 16-bit with the low-order 8-bits at the effective address and the high-order 8-bits at the effective address plus one.

Flags Affected
Flags
n-----zc
nSet if most-significant bit of result is set
zSet if result is zero
cSet if register value greater than or equal or Cleared if less than memory value
Instructions
SyntaxOpcode Available on: # of # of Addressing Mode
(hex) 6502 65C02 65816 bytes cycles
CMP #constC9 x x x 21 22 Immediate
CMP addrCD x x x 3 42 Absolute
CMP longCF x 4 52 Absolute Long
CMP dpC5 x x x 2 32, 3 Direct Page
CMP (dp)D2 x x 2 52, 3 Direct Page Indirect
CMP [dp]C7 x 2 62, 3 Direct Page Indirect Long
CMP addr,XDD x x x 3 42, 4 Absolute Indexed X
CMP long,XDF x 4 52 Absolute Long Indexed X
CMP addr,YD9 x x x 3 42, 4 Absolute Indexed Y
CMP dp,XD5 x x x 2 42, 3 Direct Page Indexed X
CMP (dp,X)C1 x x x 2 62, 3 Direct Page Indexed Indirect X
CMP (dp),YD1 x x x 2 52, 3, 4 Direct Page Indirect Indexed Y
CMP [dp],YD7 x 2 62, 3 Direct Page Indirect Long Indexed Y
CMP sr,SC3 x 2 42 Stack Relative
CMP (sr,S),YD3 x 2 72 Stack Relative Indirect Indexed Y

Notes:

  1. 65816: Add 1 byte if m=0 (16-bit memory/accumulator)
  2. 65816: Add 1 cycle if m=0 (16-bit memory/accumulator)
  3. 65816: Add 1 cycle if low byte of Direct Page register is not 0
  4. Add 1 cycle if adding index crosses a page boundary

3 - Compare Index Register

Compare Index Register with Memory

The CPX & CPY instructions subtracts the data at the address in the operand from the contents of the relevant index register, setting the n, z & c flags based on the result. The register & Memory are unaffected by this operation.

The primary use of the CPX or CPY instructions is to test the value of the index register against loop boundaries.

Data size

On all processors, the data added from memory is 8-bit. However, for 16-bit processors with the m flag is clear then the data added is 16-bit with the low-order 8-bits at the effective address and the high-order 8-bits at the effective address plus one.

Flags Affected
Flags
n-----zc
nSet if most-significant bit of result is set
zSet if result is zero
cSet if register value greater than or equal or Cleared if less than memory value
Instructions
SyntaxOpcode Available on: # of # of Addressing Mode
(hex) 6502 65C02 65816 bytes cycles
CPX #constE0 x x x 21 22 Immediate
CPX addrEC x x x 3 42 Absolute
CPX dpE4 x x x 2 32, 3 Direct Page
CPY #constC0 x x x 21 22 Immediate
CPY addrCC x x x 3 42 Absolute
CPY dpC4 x x x 2 32, 3 Direct Page

Notes:

  1. 65816: Add 1 byte if m=0 (16-bit memory/accumulator)
  2. 65816: Add 1 cycle if m=0 (16-bit memory/accumulator)
  3. 65816: Add 1 cycle if low byte of Direct Page register is not 0

4 - Branch

Perform a test & branch based on that test

The branch instructions perform a test against one of the processor's flags. Depending on the instruction a branch is taken if it is either clear or set.

If the branch is taken, a 1-byte signed displacement in the second byte of the instruction is sign-extended to 16-bits and added to the Program Counter. If the branch is not taken then the instruction immediately following the 2-byte instruction is executed.

The allowable range of the displacement is -128 to +127 from the instruction immediately following the branch.

BCC - Branch if Carry Clear

BCC tests the Carry flag and branches if it is clear.

It can be used in several ways:

  • Test the result of a shift into the carry
  • Determine if the result of a comparison is less than

Some assemblers accept BLT (Branch if Less Than) as an alternate mnemonic for BCC.

BCS - Branch if Carry Set

BCS tests the Carry flag and branches if it is set.

It can be used in several ways:

  • Test the result of a shift into the carry
  • Determine if the result of a comparison is greater than or equal

Some assemblers accept BGE (Branch if Greater Than or Equal) as an alternate mnemonic for BCS.

BEQ - Branch if Equal

BEQ tests the Zero flag and branches if it is set.

It can be used in several ways:

  • Test the result of a comparison is equal
  • Test the result of an Increment or Decrement operation is zero, useful in loops.
  • Test the value just loaded is zero
  • Test the result of an arithmetic operation is zero

BNE - Branch if Not Equal

BNE tests the Zero flag and branches if it is clear.

It can be used in several ways:

  • Test the result of a comparison is not equal
  • Test the result of an Increment or Decrement operation is not zero
  • Test the value just loaded is not zero
  • Test the result of an arithmetic operation is not zero

BMI - Branch if Minus

BMI tests the Negative flag and branches if it is set. The high bit of the value most recently affected will set the N flag. On 8-bit operations this is bit 7. On 16-bit operations (65816 only) this is bit 15.

This is normally used to determine if a two's-complement value is negative but can also be used in a loop to determine if zero has been passed when looping down through zero (the initial value must be positive)

BPL - Branch if Positive

BPL tests the Negative flag and branches if it is clear. The high bit of the value most recently affected will set the N flag. On 8-bit operations this is bit 7. On 16-bit operations (65816 only) this is bit 15.

This is normally used to determine if a two's-complement value is positive or if the high bit of the value is clear.

BVC - Branch if Overflow Clear

BVC tests the Overflow flag and branches if it is clear.

On the 6502 only 3 instructions alter the overflow flag: ADC, SBC & CLV.

On the 65C02 the BIT instruction also alters the overflow flag.

The PLP & RTI alter the flags as they restore all flags from the stack.

On the 65816 the SEP & REP instructions modify the v flag.

On some processors there's a Set Overflow hardware signal available, but on many systems there is no connection to that pin.

BVS - Branch if Overflow Set

BVS tests the Overflow flag and branches if it is set. It has the same limitations as the BVC instruction.

Flags Affected
None.
Instructions
SyntaxBranch ifOpcode Available on: # of # of Addressing Mode
(hex) 6502 65C02 65816 bytes cycles
BCC nearlabel Carry clear 90 x x x 2 21, 2 Program Counter Relative
BCS nearlabel Carry set B0 x x x 2 21, 2 Program Counter Relative
BEQ nearlabel Equal, z=1 F0 x x x 2 21, 2 Program Counter Relative
BNE nearlabel Not Equal, z=0 D0 x x x 2 21, 2 Program Counter Relative
BMI nearlabel Minus, n=1 30 x x x 2 21, 2 Program Counter Relative
BPL nearlabel Positive, n=0 10 x x x 2 21, 2 Program Counter Relative
BVC nearlabel Overflow clear, v=0 50 x x x 2 21, 2 Program Counter Relative
BVS nearlabel Overflow set, v=1 70 x x x 2 21, 2 Program Counter Relative

Notes:

  1. Add 1 cycle if branch taken
  2. Add 1 more cycle if branch taken crosses page boundary on a 6502, 65C02 or a 65816 in 6502 emulation mode (e=1)

5 - Jump to location

Transfer control to the address specified by the operand field.

The branch instructions sets the Program Counter to a new value from which the next instruction will be taken.

JMP - Jump to location

The program counter is loaded with the target address. If a long JMP is executed the bank is loaded from the third byte of the address.

Some assemblers accept JML as an alternate mnemonic for JMP long.

BRA - Branch Always

A branch is always taken, no test is performed. It is equivalent to a JMP instruction, except that as it uses a signed displacement it is only 2 bytes in length instead of 3 for JMP. In addition, because it uses displacements, code using BRA is relocatable.

The 1-byte signed displacement in the second byte of the instruction is sign-extended to 16-bits and added to the Program Counter. If the branch is not taken then the instruction immediately following the 2-byte instruction is executed.

The allowable range of the displacement is -128 to +127 from the instruction immediately following the branch.

BRA was introduced with the 65C02 processor.

BRL - Branch Always Long

A branch is always taken, no test is performed. It is equivalent to a BRA instruction, except that BRL is a 3 byte instruction. The two bytes after the opcode form a 16-bit signed displacement from the Program Counter.

The allowable range of the displacement is anywhere within the current 64K program bank.

The advantage of BRL is that it makes code relocatable, although it is 1 cycle slower than the absolute JMP instruction.

BRL was introduced with the 65802 processor.

Flags Affected
None.
Instructions
SyntaxOpcode Available on: # of # of Addressing Mode
(hex) 6502 65C02 65816 bytes cycles
BRA nearlabel80 x x 2 33 Program Counter Relative
BRL label82 x 3 4 Program Counter Relative Long
JMP addr4C x x x 3 3 Absolute
JMP (addr)6C x x x 3 51, 2 Absolute Indirect
JMP (addr,X)7C x x 3 6 Absolute Indexed Indirect
JMP long5C x 4 4 Absolute Long
JMP [addr]DC x 3 6 Absolute Indirect Long

Notes:

  1. Add 1 cycle if 65C02
  2. 6502: If low byte of address is 0xFF yields incorrect result
  3. Add 1 more cycle if branch taken crosses page boundary on a 6502, 65C02 or a 65816 in 6502 emulation mode (e=1)

6 - Subroutines

Calling subroutines

The JSR & RTS instructions allows for subroutines to be implemented. The work by utilising 2 bytes on the stack consisting of the address before the next instruction to execute when the subroutine returns - not the actual address of that instruction.

On the 16-bit 65816 there are the JSL & RTL instructions. These use 3 bytes on the stack. The extra byte is the return bank address. Like RTS the address on the stack is the address before the next instruction not the actual instruction

For Interrupt routines there's the RTI instruction. That instruction is on the Interrupt page.

JSR - Jump to Subroutine

Transfer control to a subroutine, pushing the return address onto the stack. The 16-bit address placed on the stack is the address of the 3rd byte of the instruction, not the address of the next instruction.

Subroutines called by JSR must return using the RTS instruction.

Some assemblers recognise JSR as an alternate to the 65816 JSL instruction where if the address is greater than &FFFF then the 24 bit JSL instruction is used instead.

RTS - Return from Subroutine

Returns from a subroutine called by JSR. It pulls the 16-bit program counter from the stack, incrementing it by one so that the next instruction is the one immediately after the calling JSR instruction.

JSL - Jump to Subroutine Long

Transfer control to a subroutine, pushing the return address onto the stack. The 24-bit address placed on the stack is the address of the 4th byte of the instruction, not the address of the next instruction.

Subroutines called by JSL must return using the RTL instruction.

RTL - Return from Subroutine Long

Returns from a subroutine called by JSL. It pulls the 24-bit program counter from the stack, incrementing it by one so that the next instruction is the one immediately after the calling JSL instruction.

Flags Affected
None.
Instructions
SyntaxOpcode Available on: # of # of Addressing Mode
(hex) 6502 65C02 65816 bytes cycles
JSL long22 x 4 8 Absolute Long
JSR addr20 x x x 3 6 Absolute
JSR (addr,X)FC x 3 8 Absolute Indexed Indirect
RTL 6B x 1 6 Implied
RTS 60 x x x 1 6 Implied