6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue Jun 25, 2024 7:15 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Mon Jul 19, 2004 8:34 am 
Offline

Joined: Sat Jul 17, 2004 11:10 am
Posts: 1
hi all,

my problem is related to branch word relative instruction...i'm bit confused here...i want to know what will be the jump address if BCC goes true..

suppose my program is like this

8000: CLC;
8001: BCC $82D8;word relative address
8004: SED;

Then ...at which address program counter will jump after execution of BCC
instruction...can anybody help me to clear my doubt.

thanks


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jul 19, 2004 10:23 am 
Offline

Joined: Tue Sep 03, 2002 12:58 pm
Posts: 305
That example shouldn't assemble: the destination is too far away. Branch instructions have a range of -128..127 bytes from the first byte of the instruction after the branch.

Also, branch instructions are only two bytes, not the three that your example has. The machine code has one byte for the opcode, followed by one byte for the offset. Assemblers will usually calculate the offset for you, given an address. So if you enter

8000: CLC
8001: BCC $8010
8003: SED

you'll get an offset of 13 ($0D). In this case, C is cleared before the branch, so it will always branch (to $8010).


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jul 19, 2004 10:58 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8460
Location: Southern California
As John said, the branch instructions are only for local relatve branching. In the case you brought up, the assembler would generate an error message. The more approprate instruction would be JMP $82D8, whch takes a total of only three bytes and three clocks (and it works).

The instructions starting with "B" (like BCC, BCS, BMI, BPL, BEQ, etc.) have one operand byte. The high bit of that byte tells if you're branching forward or backward. It's a 1 if branching backward.

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.

If you want the BCC to branch back to itself, the operand would be a -2 (which is $FE in the one-byte operand). If the next instruction is SED and you want to skip that, the operand will be 01 since SED is a one-byte instruction.

The vast majority of relative branches are to addresses that are nearby. I seldom need to wonder if a branch is nearly at the branch distance limit. On those few occasions when you need to go more than half a page away, you can choose the opposite branch condition (like BCS instead of BCC) and use it to branch around a JMP to the desired address. 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.

BTW-- For maintainability and readability, there should be very few actual numbers in your source code. Use labels and equates and let the assembler figure out the numbers, so you don't need to make a lot of changes in the code when you find you have to do things like insert or delete instructions or change a number that should have been named a constant.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Jul 22, 2004 2:55 am 
Offline
User avatar

Joined: Thu Mar 11, 2004 7:42 am
Posts: 362
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.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 36 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: