sbc is the same as cmp in cycles use... so after looking at tepples post again I'm guessing you save (don't require) an sec. Is that correct?
This is correct. Although, sometimes you can avoid the sec anyway, even when using sbc. What matters is not that sec is used, just that the carry is set.
Code: Select all
bcc somewhere
;If we're here, we didn't branch, so the carry is set.
lda variable
;sec;Not needed right here, because we can guarantee the carry is already set
sbc variable2;
somewhere:
Stuff like this is why it takes forever for me to write code. I think I like optimizing more than getting things working. *shrug*
I can see what happens but my brain is missing the why
I'm not sure I can explain that stuff better than the guides, but apparently I'm giving it a shot. Check the 6+5 = 11 on this poster:
http://www.abcteach.com/documents/poste ... elem-24639 (It's kiddy, but it actually shows what I want to show)
The orange 1 is basically like the carry bit. For the tens place, it's adding 0+0. PLUS CARRY (1 in this case)!
If you were adding 4+5, the tens place would add 0+0. PLUS CARRY (0, in that case! Because 4+5 doesn't carry to the tens place.)
So when you add on the 6502 with adc, you are
always adding the two numbers. PLUS CARRY! It just carries over to the next byte when it overflows, instead of the next place when you run out of digits.
This is why you clear the carry before most additions. If you don't, you will add an extra one if the carry was set!
Code: Select all
00|FF (the | separates the two bytes into "places" like the one and tens place in the decimal addition example)
+00|01
------
01|00
You'll notice for the high bytes, you're doing 00+00, just like for the tens place in that example poster. But, like in the example poster, the addition of the lower place causes an overflow. FF+01 is greater than 255, so the carry ends up set. 5+6 is greater than 9, so you end up carrying one.
Anytime you add a number and result would have been greater than the byte can hold, the carry is set. Otherwise it is cleared.
For clarity: ADC will always set/clear the carry based on the result of the addition. See this code:
Code: Select all
sec
lda #$00
adc #$00
;Carry is cleared.
The carry is not "left alone" (In this case, it does not stay set) if there was no carryover. If there was no carryover, it is clear. If there was, it is set. Nothing else.
This ensures that when you add the higher bytes (places) of the number, they get the correct result. This is why you DO NOT change the carry between operations that are part of the same multi byte add or subtract. The previous operations will make the carry right (whether there was a carry or not) and you don't have to worry about it to get the right result.
Now... subtraction is a bit different. It subtracts the two numbers and the OPPOSITE of the carry. So when the carry is set (1), it will just subtract one number from the other. When the carry is clear (0), it will subtract one number from the other, AND an additional one.
The way I used to remember it... If the carry is opposite what you would normally set it to before that operation, that's when you get the extra one. (You clear the carry before addition, so when it's set it adds one more. You set the carry before subtraction, so when it's clear, it subtracts one more.)
Three things to take away:
1. The carry is ALWAYS taken into account when you use adc or sbc, so make sure it's right for the operation you intend to do before that operation runs. (Clear before addition, set before subtraction)
2. The carry will become the opposite of what you would normally initialize it to if the operation goes outside the boundaries of a byte. (So if an addition would have yielded more than 255, or a subtraction would have yielded less than 0.) Otherwise, the carry becomes what you would normally initialize it to.
3. If the carry is the opposite of what you would normally initialize it to, one extra will be used in the operation. (One extra will be subtracted for sbc, or one extra will be added for adc.)
That's really all there is to it. The rest is the "why" behind it. With the knowledge, you can do fun stuff like this:
Code: Select all
bcc somewhere
;The carry is set because we didn't branch
;We want to add eight to the accumulator
;clc;We could clear the carry
;adc #$08;And add 8.
adc #$07;Or... we could add 7. Because we know the carry is set, and 7+1 is eight.
But... don't do stuff like that in your game until you're really sure about it. If you understand it why it works, though, you've got a handle on the carry.
I really do look forward to these posts. This is my favorite section of the forum, and I always feel bad when I mislead people.