6502 Jumps, Branches, and Procedures
Very few computer programs are perfectly lineary in their instruction sequence - the sequence of instructions executed may be repeated (loops), conditional (if/then/else), and involve procedures (aka subroutines, functions, or methods).
On the 6502 processor, there are three main ways to move to a specific code location in memory: jumps, branches, and procedures (or subroutines).
Jumps
Jumps are unconditional and cause the program counter to move to a particular address. The instruction is JMP both relative and absolute addressing modes are available.
Here is an example using the absolute addressing mode:
JMP $f027 ; unconditional jump to absolute address
This will cause the program counter (PC) to be loaded with the value $f027, causing the processor to execute the instruction at that address next. This is effectively a "GOTO".
This example uses indirect addressing:
JMP ($6094)
This loads the PC with the value in memory at $6094:$6095. Effectively, $6094 is a pointer to the address of the next instruction to be executed.
Branches
Branches are conditional on the state of a processor flag. The destination of the branch is given as a signed byte relative to the current value of the PC, so the destination must be within -128 to +127 bytes of the byte after the branch instruction. These are the branch instructions available:
BCC ; Branch on Carry flag (C) Clear BCS ; Branch on Carry flag (C) Set BEQ ; Branch on EQual (zero Z flag set) BNE ; Branch on Not Equal (zero Z flag clear) BMI ; Branch on MInus (negative flag S set) BPL ; Branch on PLus (negative bit S clear) BVC ; Branch on oVerflow flag V Clear BVS ; Branch on oVerflow flag V Set
In assembler, you typically specify the address or label to which you wish to branch, and the assembler calculates the relative value for the branch offset.
For example:
LOOP: STA (POINTER),Y INY BNE LOOP
In this code, the BNE LOOP
line is assembled as:
d0 fb ; BNE $0600
Where $FB represents -5 in two's compliment notation, since the processor needs to branch back 5 bytes from the current PC location (which is the byte after the end of the BNE instruction).
Procedures
Proedures - also called subroutines, functions, or methods - are a special case, because the program flow needs to return to the calling code when the procedure has finished.
In the 6502, the JSR (Jump to SubRoutine) instruction is used to push the current value of the program counter on the stack, and then perform an unconditional jump to the address specified (using the absolute addressing mode):
JSR $F000
To return from the procedure, the RTS (ReTurn from Subroutine) instruction loads the PC from the stack, causing execution to continue at the instruction immediately after the JSR.