Confused about multiple branches without compare

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Confused about multiple branches without compare
by on (#104373)
I've seen code with many Branch opcodes with without a Compare Opcode preceding it.

I've done a little nesasm testing but i can't seem to pindown the logic behind 'delayed' branch commands.

Code:
  LDA #$88
  CMP #$88 
 
 ;sprite is drawn
 
  LDA #$78
  BEQ Skip
  JSR Draw_Sprite
 
 
Skip:


I would expect the comparison flag is saved so it would skip, but it isnt' (Draw_Sprite is called.)
The sprite is skipped here, but i don't know why:

Code:
  LDA #$88
  CMP #$88 
 
 ;sprite not drawn
 
  LDA #$78
  BNE Skip
  JSR Draw_Sprite
 
 
Skip:


And this also doesn't draw... ? I'm wondering if the comparison flag is cleared somewhere..?
Code:
  LDA #$88
  CMP #$88 
 
 ;sprite not drawn
 
  LDA #$88
  BNE Skip
  JSR Draw_Sprite
 
 
Skip:
Re: Confused about multiple branches without compare
by on (#104374)
The zero flag is killed then LDA happens because the loaded value isn't zero, so it clears the zero (also is the equal) flag. That code is just badly written if you pulled it from somewhere. The only thing the CMP can do it set the C flag to check later in that code, because that's the only thing LDA doesn't colobber. Plus, comparing to set numbers usually doesn't make sense because there's not much use as this is programming, and it needs to be dynamic. :)
Re: Confused about multiple branches without compare
by on (#104375)
A lot of instructions will change flags that can be branched on. CMP is only needed when you want to compare two values against each-other without clobbering the A register. I very often branch based on the result of a LDA or INX, for example.

This reference may be useful: http://www.6502.org/tutorials/6502opcodes.html

Read the section on branches, and take a look at which flags various instructions affect.
Re: Confused about multiple branches without compare
by on (#104377)
3gengames wrote:
The zero flag is killed then LDA happens because the loaded value isn't zero, so it clears the zero (also is the equal) flag.


Ok, thank you that clears it up!

rainwarrior wrote:
A lot of instructions will change flags that can be branched on. CMP is only needed when you want to compare two values against each-other without clobbering the A register...
...This reference may be useful: http://www.6502.org/tutorials/6502opcodes.html


I look at that site often but i didn't really grasp the importance of flags until now, thank you for the branch explanation.
Re: Confused about multiple branches without compare
by on (#104390)
Being used to high level languages, the status flags can be a bit hard to understand at first. The fact is that a lot of instructions affect the flags, not only comparisons, and that branch instructions will do their thing based on the state of the flags, regardless of how they got to that state.

Things like loading values into registers and adding and subtracting numbers affect many flags, so you can often make decisions based on the results of these operations without having to compare anything. Use a good 6502 documentation that explains how all the flags are modified by each instruction so you know when the best time to use branch instructions is. Knowing which instructions don't affect certain flags is important as well, in case you need to delay branches.

Another common reason for "orphan" conditional branch instructions in 6502 ASM is the lack of a BRA ("branch always") instruction. Sometimes programmers want to jump to a nearby location and one of the status flags has a known state at that point in the code, so they use the appropriate branch instruction in place of the JMP instruction, saving 1 byte. When I do this, I always write a "branch always" comment to make it clear that the instruction isn't making any decisions, just jumping somewhere.
Re: Confused about multiple branches without compare
by on (#106505)
This looks like a good way to observe the flags in action:
http://e-tradition.net/bytes/6502/
Re: Confused about multiple branches without compare
by on (#106533)
Brickman, you have to be sure disassembling code, not data.
Re: Confused about multiple branches without compare
by on (#106750)
Another thing I catch myself doing without thinking is:

Code:
dec variable
cmp #blah
bne label


And I spend a while troubleshooting why the branch doesn't work as I'd expect, without realizing the code shouldn't work. Sometimes I overlook actual logic as I'm typing out code :).