Conditional Branch Instructions

The 6502 processor has a set of eight branch instructions which provide a way to alter the flow of program execution based on the state of certain status flags. Each branch instruction operates on a different flag, and a different condition (branch when set, or branch when clear.)

Branch instructions have a signed 8-bit operand which specifies how far to jump if the specified flag condition is true. If the branch condition is true, the signed operand is added to the address immediately following the branch instruction (PC + 2) and then the CPU jumps to that address.

Instruction Table

Here are the eight branch instructions, the condition for each, and the equivalent condition when used with a compare or subtract operation:

Syntax

Bytes

Cycles

Flag

Condition

CMP or SBC

BPL target

10 nn

2-4

N=0

Sign Clear

see below

BMI target

30 nn

2-4

N=1

Sign Set

see below

BVC target

50 nn

2-4

V=0

Overflow Clear

No signed overflow

BVS target

70 nn

2-4

V=1

Overflow Set

Signed overflow

BCC target

90 nn

2-4

C=0

Carry Clear

A < B (unsigned)

BCS target

B0 nn

2-4

C=1

Carry Set

A >= B (unsigned)

BNE target

D0 nn

2-4

Z=0

Zero Clear

A != B

BEQ target

F0 nn

2-4

Z=1

Zero Set

A == B

Signed Comparisons

The proper method for signed comparison using the CMP instruction and branch instructions in the 6502 microprocessor involves the exclusive-or (eor) of the N (Negative) and V (Overflow) flags.

  • Perform a CMP instruction to compare the accumulator (A) with the given operand. This effectively performs the subtraction (A - operand) without updating the accumulator with the result.

  • The result of the subtraction affects the processor status flags. N (Negative) flag is set if the result’s most significant bit (MSB) is set. V (Overflow) flag is set if signed overflow occurs in the subtraction.

  • To determine if A < operand in signed arithmetic, check if (N eor V) is 1. Conversely, to determine if A >= operand in signed arithmetic, check if (N eor V) is 0.

To implement this in assembly, you can use a combination of branch instructions to check the result of N eor V. Here’s a sample implementation for A < operand (signed comparison):

    CMP operand
    BMI .is_less_than ; if N = 1, jump to .is_less_than
    BVC .is_greater_equal ; if V = 0, jump to .is_greater_equal
.is_less_than:
    ; A < operand in signed arithmetic; insert code for this case
    JMP .done
.is_greater_equal:
    ; A >= operand in signed arithmetic; insert code for this case
.done:

Timing

The number of CPU cycles taken by branch instructions in the 6502 microprocessor depends on whether the branch is taken or not and whether a page boundary is crossed when the branch is taken.

  • 2 cycles - Branch not taken

  • 3 cycles - Branch taken, no page boundary crossed

  • 4 cycles - Branch taken, page boundary crossed

Example

    LDA #10      ; load A with constant 10
    CMP #5       ; compare A with constant 5
    BEQ equal    ; branch to "equal" label if A == 5
    ...
equal:
    ...

Comments