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?
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.)
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.
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.
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.
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.
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?
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.
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!
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:
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).
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 ...
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!