Page 1 of 1

Branch instructions

Posted: Wed Sep 02, 2020 1:32 am
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

Re: Branch instructions

Posted: Wed Sep 02, 2020 1:41 am
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

Re: Branch instructions

Posted: Wed Sep 02, 2020 2:45 am
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

Re: Branch instructions

Posted: Wed Sep 02, 2020 2:48 am
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.

Re: Branch instructions

Posted: Wed Sep 02, 2020 2:55 am
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.

Re: Branch instructions

Posted: Wed Sep 02, 2020 3:02 am
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.

Re: Branch instructions

Posted: Wed Sep 02, 2020 3:09 am
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

Re: Branch instructions

Posted: Wed Sep 02, 2020 3:13 am
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.

Re: Branch instructions

Posted: Wed Sep 02, 2020 4:09 am
by IamRob
More often than not, you can rearrange the code so that the processor byte never needs to be pushed or pulled.

Re: Branch instructions

Posted: Wed Sep 02, 2020 4:29 am
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.

Re: Branch instructions

Posted: Wed Sep 02, 2020 7:15 am
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.

Re: Branch instructions

Posted: Wed Sep 02, 2020 12:50 pm
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).

Re: Branch instructions

Posted: Wed Sep 02, 2020 5:40 pm
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: