Re: branch computation

From: Marko Mäkelä <msmakela_at_gmail.com>
Date: Sun, 13 Oct 2019 17:08:04 +0300
Message-ID: <20191013140804.GA2346_at_jyty>
On Sun, Oct 13, 2019 at 03:28:04PM +0200, didier_at_aida.org wrote:
>I'm writing a mini assembler.. my last step is to compute de offset 
>after a relative branch
>if it's easy to do in C, I don't find the right logic in 6502 assembler
>
>any idea on the shortest code to compute that ?
>I have the address  of the opcode and the target address

Branch instructions are 2 bytes on the 6502, and the address is relative 
to the address of the following instruction. The offset is stored in the 
1 byte that follows the branch instruction opcode. The branch target 
address can be between -128 and +127 bytes from the start of the 
following instruction.

Assuming that the "current address" is that of the following instruction 
(which is executed when no branch is taken) and the "target address", 
the branch offset is co of the target, the branch would be computed by 
simple subtraction: target_address-current_address.

You would want to subtract 16-bit numbers and obtain a signed 8-bit 
result, and you should also catch overflow.

I would start with something like this:

sec
lda target
sbc current
tax
lda target+1
sbc current+1
bmi branch_backwards
; the forward branch range may be 0..$7f
bne out_of_range
txa
bpl branch_ok
; fall through
out_of_range:
...

branch_backwards:
; the backward range may be $ff80..$ffff (-128..-1)
eor #$ff
bne out_of_range
txa
bpl out_of_range

branch_ok:
; the 8-bit branch offset is in the A and X registers

Disclaimer: I did not test this, and I have not done any 6502 coding for 
a couple of years.

I hope that this helps.

Side note: Has anyone tested whether the relative branch instructions 
can wrap around from $ffxx to $00yy or vice versa? I see no reason why 
they would not, but I never came around to testing it myself.

	Marko
Received on 2020-05-29 23:04:56

Archive generated by hypermail 2.3.0.