Branch instructions

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
DanielS
Posts: 43
Joined: 12 Aug 2020

Branch instructions

Post by DanielS »

Hey guys.

Does a branch instruction have to come right after a compare?
Or can there be other instructions between them as long as they don't affect the carry or zero flags?

Example...

Code: Select all

lda #$ff
cmp #$ff
; some other code
beq somewhere_if_a_equals_ff
DanielS
Posts: 43
Joined: 12 Aug 2020

Re: Branch instructions

Post by DanielS »

Looks like perhaps I can push the processor flags, do stuff, then pull them.

Code: Select all

lda #$ff
cmp #$ff
php
; do stuff
plp
beq somethere_if_a_equals_ff
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Branch instructions

Post by Dr Jefyll »

DanielS wrote:
Looks like perhaps I can push the processor flags, do stuff, then pull them.
Yes, you can -- but it won't always be necessary.

Your previous post has the right idea. There can be other instructions between them as long as they don't affect the carry or zero flags. (But if they *do* affect the flag you're interested in, that's when pushing then later popping the flags may be the best alternative. I say "may" because it's often possible to rearrange the instruction order instead.)

Cheers,
Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Branch instructions

Post by GARTHWILSON »

The flags will persist as long as the instructions executed don't alter them. For example, if you have something that leaves the V flag for you to branch on later, and the intervening instructions only affect Z, C, and N, there's no reason to push the processor status and then pull it off the stack later.

Note of course that pushing and pulling the status is an automatic part of the interrupt sequence and RTI, so you don't need to bracket an ISR with PHP and PLP. In fact, there are situations where doing so could even cause problems.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: Branch instructions

Post by BillG »

DanielS wrote:
Does a branch instruction have to come right after a compare?
Or can there be other instructions between them as long as they don't affect the carry or zero flags?
There can be any number of instructions in between the setting of a flag and a test for it.

For example, the code on this post

viewtopic.php?p=77950#p77950

sets the carry flag on line 54 and uses it on line 61.
DanielS
Posts: 43
Joined: 12 Aug 2020

Re: Branch instructions

Post by DanielS »

Here's an example...

Code: Select all

_validate_1 ; left, right, down
    cpx ch_left
    php
    ldy #0
    plp
    beq _valid
    cpx ch_right
    php
    ldy #2
    plp
    beq _valid
    cpx ch_down
    php
    ldy #4
    plp
    beq _valid
    jmp _invalid
Y needs to be used in the next section. If I do it this way then I can avoid many, seemingly unnecessary, BEQs. The value of Y is based on the value of X.

Maybe this is a hacky way of doing it but it seems to work.
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: Branch instructions

Post by BillG »

DanielS wrote:
Here's an example...

Code: Select all

_validate_1 ; left, right, down
    cpx ch_left
    php
    ldy #0
    plp
    beq _valid
    cpx ch_right
    php
    ldy #2
    plp
    beq _valid
    cpx ch_down
    php
    ldy #4
    plp
    beq _valid
    jmp _invalid
Y needs to be used in the next section. If I do it this way then I can avoid many, seemingly unnecessary, BEQs. The value of Y is based on the value of X.

Maybe this is a hacky way of doing it but it seems to work.
Can't you just do

Code: Select all

_validate_1 ; left, right, down
    ldy #0
    cpx ch_left
    beq _valid
    ldy #2
    cpx ch_right
    beq _valid
    ldy #4
    cpx ch_down
    beq _valid
    jmp _invalid
DanielS
Posts: 43
Joined: 12 Aug 2020

Re: Branch instructions

Post by DanielS »



Can't you just do

Code: Select all

_validate_1 ; left, right, down
    ldy #0
    cpx ch_left
    beq _valid
    ldy #2
    cpx ch_right
    beq _valid
    ldy #4
    cpx ch_down
    beq _valid
    jmp _invalid
Damn. Yes I can. That never occurred to me. I'm still in the C++ mindset I guess so the "simple" things here are, for now, elusive.
IamRob
Posts: 357
Joined: 26 Apr 2020

Re: Branch instructions

Post by IamRob »

More often than not, you can rearrange the code so that the processor byte never needs to be pushed or pulled.
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Branch instructions

Post by BigDumbDinosaur »

DanielS wrote:
Hey guys.

Does a branch instruction have to come right after a compare?
Or can there be other instructions between them as long as they don't affect the carry or zero flags?

Example...

Code: Select all

lda #$ff
cmp #$ff
; some other code
beq somewhere_if_a_equals_ff
Short answer is no. The long answer is as long the relevant status register bit (Z in this case) is not affected by intervening instructions your branch will be reliable.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Branch instructions

Post by barrym95838 »

Lemme see if I can recite from memory all the ones that don't affect Z ... nop clc sec cli sei cld sed clv sta stx sty pha php jmp bxx jsr rts txs ... not many. I remember being frustrated at the 68xx for inexplicably messing with Z during a store operation, but not for pula or pulb. It's actually just a minor inconvenience, but so irksome, IMO.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Branch instructions

Post by cjs »

barrym95838 wrote:
Lemme see if I can recite from memory all the ones that don't affect Z ... nop clc sec cli sei cld sed clv sta stx sty pha php jmp bxx jsr rts txs ... not many.
I found it useful to create a little table listing the flags and all the instructions that affect each one:

Code: Select all

C   SEC CLC
    ADC SBC                                         ASL LSR ROL ROR
    BIT CMP CPX CPY

NZ          LDA LDX LDY TAX TXA TAY TYA     TSX PLA
    ADC SBC INC DEC INX DEX INY DEY     AND ORA EOR ASL LSR ROL ROR
    BIT CMP CPX CPY

V       CLV
    ADC SBC
    BIT

D   SED CLD
I   SEI CLI BRK
(4) BRK
Quote:
I remember being frustrated at the 68xx for inexplicably messing with Z during a store operation, but not for pula or pulb. It's actually just a minor inconvenience, but so irksome, IMO.
Yeah, totally irksome. But probably not as inconvenient as not having PSHX and PULX instructions (though the 6801/6803 added those).
Curt J. Sampson - github.com/0cjs
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Branch instructions

Post by barrym95838 »

cjs wrote:
Yeah, totally irksome. But probably not as inconvenient as not having PSHX and PULX instructions (though the 6801/6803 added those).
Oof, yeah, that's a real eye-roller. How many quadrillions of total machine cycles have been spent executing the awkward work-around for that one? The average temperature on Earth is probably .00001° hotter because of it ... :lol:
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
Post Reply