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 |
|
2-4 |
N=0 |
Sign Clear |
see below |
BMI target |
|
2-4 |
N=1 |
Sign Set |
see below |
BVC target |
|
2-4 |
V=0 |
Overflow Clear |
No signed overflow |
BVS target |
|
2-4 |
V=1 |
Overflow Set |
Signed overflow |
BCC target |
|
2-4 |
C=0 |
Carry Clear |
A < B (unsigned) |
BCS target |
|
2-4 |
C=1 |
Carry Set |
A >= B (unsigned) |
BNE target |
|
2-4 |
Z=0 |
Zero Clear |
A != B |
BEQ target |
|
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:
...