How does this affect ADC or SBC? Sorry if this is painstakingly obvious, but I've been using these for well over half a year without even knowing what purpose they serve.Carry flag
This flag is set on unsigned overflow for ADC ($00 roll over to $FF) or when underflow for SBC does not happen. It also gets set depending on the result of ASL/LSR/ROL/ROR and more.
What is the purpuse of CLC and SEC?
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
What is the purpuse of CLC and SEC?
I know it sets and clears the carry flag in the processor status bits, but how does that affect anything? I looked at what the carry flag was for, and this is what I found:
Re: What is the purpuse of CLC and SEC?
ADC is short for "ADd with Carry". Meaning that, the result you get from an ADC is the Accumulator plus the operand, PLUS the carry bit. So if you don't CLC before you ADC, and there's a chance the carry bit might be set, your addition may be off by one.
Similarly, because of how binary subtraction works, SEC is the opposite: When you subtract, it is expected the carry bit is set before you start.
The reason why you'd WANT adc to include the carry bit is so that you can chain together repeated additions, carrying in the carry bit from the previous ADC, to add numbers larger than 16 bits.
Similarly, because of how binary subtraction works, SEC is the opposite: When you subtract, it is expected the carry bit is set before you start.
The reason why you'd WANT adc to include the carry bit is so that you can chain together repeated additions, carrying in the carry bit from the previous ADC, to add numbers larger than 16 bits.
Re: What is the purpuse of CLC and SEC?
For further details, please see this -- it is long, and verbose, and should be read, not skimmed: http://www.6502.org/tutorials/vflag.html#2.4
(The behaviour on 65816 is the same, regardless of the fact that registers can be/are 16-bit)
There is also http://wiki.nesdev.com/w/images/7/76/Programmanual.pdf -- please see Chapter 9 (page 122) onward. Again: read, do not skim.
(The behaviour on 65816 is the same, regardless of the fact that registers can be/are 16-bit)
There is also http://wiki.nesdev.com/w/images/7/76/Programmanual.pdf -- please see Chapter 9 (page 122) onward. Again: read, do not skim.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: What is the purpuse of CLC and SEC?
The carry is needed when you want to operate on values bigger than one byte. It works exactly like you were probably taught in school, except instead of working with decimal digits (0-9) you're using byte digits (0-255).
When you add two numbers together, and the result is too big to fit in a byte, the carry flag is set, so you can pass it on to the next addition step.
When you add two numbers together, and the result is too big to fit in a byte, the carry flag is set, so you can pass it on to the next addition step.
Code: Select all
; Example 16-bit addition
; 503 + 311
; $1F7 + $137
lda #<503 ; A = $F7 = 247 (low 8 bits of 503)
clc ; carry = 0
adc #<311 ; A += $37 + carry
sta result_low ; result_low = $2E, carry = 1
lda #>503 ; A = $01 = 1 (high 8 bits of 503)
adc #>311 ; A += $01 + carry
sta result_high ; result_high = $03
; result_low + (256 * result_high) = $32E = 814Re: What is the purpuse of CLC and SEC?
Or word, since this is the SNESdev forum and Espozo works mostly with the 65816.rainwarrior wrote:The carry is needed when you want to operate on values bigger than one byte.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: What is the purpuse of CLC and SEC?
Yes, it's the same concept with whatever size you have for your digits.
BTW you should CLC before ADC, and SEC before SBC in most cases when you're doing single-digit math too. There are some other uses for CLC and SEC, but their main purpose is to prepare for ADC/SBC. It might have been nice to have separate ADD and SUB instructions with an implicit CLC/SEC; the closest we have to that is CMP, which acts like SEC+SBC, but it doesn't return the result to A.
Also, I find it weird that the INC/DEC family of instructions don't set the carry flag. I can't think of any reason why the shouldn't, but they don't.
BTW you should CLC before ADC, and SEC before SBC in most cases when you're doing single-digit math too. There are some other uses for CLC and SEC, but their main purpose is to prepare for ADC/SBC. It might have been nice to have separate ADD and SUB instructions with an implicit CLC/SEC; the closest we have to that is CMP, which acts like SEC+SBC, but it doesn't return the result to A.
Also, I find it weird that the INC/DEC family of instructions don't set the carry flag. I can't think of any reason why the shouldn't, but they don't.
Re: What is the purpuse of CLC and SEC?
Well, if INC/DEC affected the carry, it would probably take more cycles (not good). Also, you might want to INC/DEC X or Y in between memory-indexed additions with the Accumulator, so different flag behaviour between INC A and INC X would be kinda weird.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: What is the purpuse of CLC and SEC?
For all the clc and sec's adding extra cycles throughout the code, it would probably have been faster to have gotten rid of the carry flag and just made it to where you had to do some sort of crazy maneuver for 32 bit instructions. It would have been awesome if there was a way to turn it off. I guess it affects all the instructions like bcc, bcs, and cmp though...
Just thinking though, if you have a routine where you're adding and you know that the result is never going to be greater than 256, couldn't you just not do sec at all?
About 32 bit instructions, I can't think of a single time where I'd want to use them on the SNES. It would be slow as all get out anyway.
Just thinking though, if you have a routine where you're adding and you know that the result is never going to be greater than 256, couldn't you just not do sec at all?
I only work with the 65816. I don't know any information about the 6502.tokumaru wrote:Or word, since this is the SNESdev forum and Espozo works mostly with the 65816.
About 32 bit instructions, I can't think of a single time where I'd want to use them on the SNES. It would be slow as all get out anyway.
Re: What is the purpuse of CLC and SEC?
It'd be clc for addition. And note that the state of the carry BEFORE the add/subtract affects the outcome, so you can only avoid it if you know the PREVIOUS result has initialized the carry correctly.Espozo wrote:Just thinking though, if you have a routine where you're adding and you know that the result is never going to be greater than 256, couldn't you just not do sec at all?
Code: Select all
clc
lda #$00
adc #$10
;Carry guaranteed clear
;clc;So no CLC needed for the next add
lda whatever
adc whatever2
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: What is the purpuse of CLC and SEC?
Dang it! Why am I being so stupid today...Kasumi wrote:It'd be clc for addition.Espozo wrote:Just thinking though, if you have a routine where you're adding and you know that the result is never going to be greater than 256, couldn't you just not do sec at all?
Thank you for answering my question though. It looks like I better look through my code...
-
psycopathicteen
- Posts: 3001
- Joined: Wed May 19, 2010 6:12 pm
Re: What is the purpuse of CLC and SEC?
I could never understand why they didn't have a normal ADD and SUB instruction like every other CPU at the time. If they ran out of instructions, they could've took some addressing modes out, like $00,s and ($00,s),y.
Re: What is the purpuse of CLC and SEC?
WDC's datasheet for the 65816 specifically mentions reentrant and recursive subroutines as reasons for the dd,S and (dd,S),Y addressing modes.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: What is the purpuse of CLC and SEC?
Incrementing an index not wanting to affect carry makes sense. That's a good thought, thanks.ccovell wrote:Well, if INC/DEC affected the carry, it would probably take more cycles (not good). Also, you might want to INC/DEC X or Y in between memory-indexed additions with the Accumulator, so different flag behaviour between INC A and INC X would be kinda weird.
I doubt a carry flag would have taken any more cycles. Stuff like that can usually be done in parallel. ADC immediate is only 2 cycles and affects 7 different flags, I'm sure INX/INY could have had managed the carry flag in 2 cycles, if they wanted it to.
You really would need the dedicated ADD/SUB instructions I suggested. The problem is that if you can't fold the carry in with the addition like in ADC, the only way to apply the carry is to do another ADD based on a branch. With 2-digit adds this is bad, with 3 it's really bad. For every carry you add, you have to check if there's another carry, all the way to the end of the line. Here's 2 and 3-digit adds as if we had ADD (SEC+ADC) instead of ADC:Espozo wrote:For all the clc and sec's adding extra cycles throughout the code, it would probably have been faster to have gotten rid of the carry flag and just made it to where you had to do some sort of crazy maneuver for 32 bit instructions. It would have been awesome if there was a way to turn it off.
Code: Select all
; a1:a0 += b1:b0
add2:
lda a0
add b0
sta a0
lda a1
bcc @digit1
; apply carry to a1
add #1
@digit1:
add b1
sta a1
rts
; a2:a1:a0 += b2:b1:b0
add3:
lda a0
add b0
sta a0
lda a1
bcc @digit1
; apply carry to a1
add #1
sta a1
bcc @digit1
; carry add caused another carry, apply to a2
lda a2
add #1
sta a2
lda a1
@digit1:
adc b1
sta a1
bcc @digit2
; apply carry to a2
lda a2
add #1
@digit2:
add b2
sta a2
rtsMaybe the sad part is that dedicated ADD/SUB instructions would have been able to do the implicit CLC/SEC without adding the extra 2 cycles or 1 byte of code, just like CMP is able to.
But... I can dream about a better 6502 all day. I'm stuck with the one I've already got.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: What is the purpuse of CLC and SEC?
I would loooove to be able to use the stack pointer as an index on the 6502. :Stepples wrote:WDC's datasheet for the 65816 specifically mentions reentrant and recursive subroutines as reasons for the dd,S and (dd,S),Y addressing modes.
Re: What is the purpuse of CLC and SEC?
Sometimes I use SEC and CLC before an RTS, if I only need to return one bit of status from the subroutine. It's kind of a pointless optimization, saving 1 or 2 bytes while code size usually doesn't matter.