GARTHWILSON wrote:
To help understand the operand, BCC 00 (where 00 is the actual operand, a relative address rather than an absolute memory address) is basically a do-nothing instruction, since it will branch to the next instruction regardless of the carry flag anyway. Come to think of it, since a branch taken usually takes 3 clocks and one not taken requires only 2, it might be an interesting way to have a variable delay based on the C flag.
Yes, an instruction like:
LABEL BCC LABEL+2
which assembles to 90 00 (in hex), is occasionally used as a variable delay. Typically it is used to compensate in time-critical code, where the number of cycles might vary depending on some condition. After putting that condition into a flag and adding a branch instruction, the code would then take the same number of cycles no matter what. In other words, if you had a section of code that sometimes took 10 cycles and sometimes 11, you could use a branch instruction to take 3 cycles under the first condition and 2 cycles under the second condition to even things out.
The example above is used somewhat more frequently to delay 3 cycles when the carry (or some other) flag value is known. Since branch instructions do not affect any flags, they are usually a better choice than a BIT ZP instruction, say.
Interestingly, since that branch (when taken) does not cross a page boundary no matter where it is located, it will always take 2 or 3 cycles, never 4. So the following code (which assembles to 90 00 B0 00 in hex) will always take 5 cycles, no matter what the carry flag is, no matter where it is located, and no flags will be altered:
Code:
LABEL1 BCC LABEL1+2
LABEL2 BCS LABEL2+2
One other instance where you might see the first example is with self-modifying code. In other words, something like this:
Code:
LDA TABLE,X
STA BRANCH+1
BRANCH BPL BRANCH+2
ACTION0
; do something here
RTS
ACTION1
; do something else here
RTS
ACTION2
; do something different here
RTS
; etc.
TABLE .BYTE ACTION0-BRANCH-2
.BYTE ACTION1-BRANCH-2
.BYTE ACTION2-BRANCH-2
; etc.
In this case, the BPL instruction must be located in RAM.
GARTHWILSON wrote:
If you really want a long, truly relative branch as for relocatable code, it gets more complex. It can be done, but it's uncommon with the 6502.
On the 6502, yes. But it is worth noting that the 65816 has a BRL -- BRanch (always) Long -- instruction that can branch to an instruction -32768 to 32767 bytes away.