I guess branch instructions can be a little tricky because there are other things you need to understand before you can utilize them effectively. First you need to understand the processor status registers. The flags in this register are set or cleared based on the result of a lot of the other instructions. You can look at a 6502 instruction reference to see exactly which instructions set which flags. The flags that the branches can use are:
Z – Zero Flag – This is set whenever an instruction results in a zero. So if you do a LDA #$00, the flag will be set, or if the X register contain 1 and you do a DEX, the zero flag will be set. Any other result will clear the zero flag. This is the flag you will probably use most often.
C – Carry Flag – This is set whenever the A register rolls over from $FF to $00. So if A contains #$F0 and you do ADC #$20 then the carry flag will be set. This is a really important flag when you are doing 16-bit addition.
N – Negative Flag – This is set equal to bit 7 of the result. When doing signed arithmetic bit 7 indicates a negative number thus the name Negative Flag.
V – Overflow Flag – This is used when doing BCD arithmetic. It can be pretty confusing so I won’t get into it here.
One important thing to remember about these flags, once they are set or cleared they remain in this state until another instruction that affects the flag is executed. Since not every instruction affects every flag it’s possible for a flag to carry over numerous instructions.
Once you understand the flags the branch instructions are pretty simple. Each one checks the state of a flag and either branches execution to another memory location, or continues with the next instruction after the branch. The one tricky thing about this is that branches are “relative”. Branch instruction only takes up two bytes, the first byte is the opcode and the second is how far from the current memory location to jump. So if the second byte of a branch is $08 then the 8 will be added to the program counter and that’s where execution will continue. Since only one byte is used for this offset you can only branch 128 bytes forward, or 127 bytes backward. When working in assembler you don’t have to worry much about this offset, you just specify the address (usually a label) you want to branch to and the assembler will calculate the offset. The assembler will also tell you if you try to branch too far.
So here are a few examples of the branch instructions:
BNE – Branch if not equal (to zero). This will branch if the zero flag is not set. For example:
Ldx #$00 loop inx bne loop
This piece of code the loop until X rolls over to zero.
BEQ is the opposite of BNE, it branches when the zero flag is cleared.
If you go through the instruction reference you will find branch instruction that test each flag for being set or being cleared.
One more important instruction to understand is the CMP, Compare, instruction. The instruction takes the operand data, subtracts it from the accumulator, set the N, Z, C flags and then discards the result, the accumulator is not modified. Here is an example:
Lda $50 CMP #$22 BEQ endgame
In this code if memory location $50 contains #$22 the branch will jump to the code at “endgame”. The compare instruction will subtract $22 from the accumulator, so if it contains $22 the result will be zero and the Z flag will be set. BEQ will test for the Z flag being set and take the branch.
Edited by DanBoris, Thu Nov 27, 2008 7:49 AM.















