## Negating a number

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Dafydd
Posts: 114
Joined: Sun Mar 16, 2008 1:45 am
Location: Uppsala, Sweden

### Negating a number

So I found this code on the wiki and it seems to work:

Code: Select all

``````; A = -A
eor #\$FF
sec
but two's complement is normally inverting all the bits and then adding 1, so that e.g. \$00 = \$FF + \$01 = \$00 (where the addition, in this case, results in the carry flag being set).

However

Code: Select all

``````lda #\$00
eor #\$FF
``````
does not seem to yield a = 0.

What am I missing about the carry flag and why would it make a difference whether it's set before the adc instruction in the first code example? And why add with 0 instead of with 1?

lidnariq
Posts: 9690
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

### Re: Negating a number

Since neither LDA nor EOR affect the C flag, you should end up with 0 or 1 in A, corresponding to whether C was set before you started.

It doesn't matter whether the +1 in the correction after the EOR comes from #immediate or from C.

Dafydd
Posts: 114
Joined: Sun Mar 16, 2008 1:45 am
Location: Uppsala, Sweden

### Re: Negating a number

Wait - the contents of C are added to A when doing ADC? ... wow. This changes things. Thanks for clearing that up.

How could I not know this already

Dafydd
Posts: 114
Joined: Sun Mar 16, 2008 1:45 am
Location: Uppsala, Sweden

### Re: Negating a number

By the way, does SBC do A←A+C-argument, or A←A-C-argument?

lidnariq
Posts: 9690
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

### Re: Negating a number

The latter.

Dafydd
Posts: 114
Joined: Sun Mar 16, 2008 1:45 am
Location: Uppsala, Sweden

### Re: Negating a number

Actually that's what the C stands for in ADC: ADd with Carry.
Yeah, but I thought that only meant that it would set Carry upon overflow (whyever I would think that, and however useful that might be), as opposed to ADD which would only... add. I don't think I've ever seen it explained anywhere what it means to Add with Carry and that it would do A←A+C+argument.

ADC #10 | Perform the ADC operation between \$10 (Decimal 16) and the content of the Accumulator
... which does not mention Carry, and as far as I know, the Carry flag is not part of the content of the Accumulator.

Anyway, thanks to you, I know how it works now. So thanks again.

Dafydd
Posts: 114
Joined: Sun Mar 16, 2008 1:45 am
Location: Uppsala, Sweden

### Re: Negating a number

According to wikipedia,
subtract with carry computes a+not(b)+C
and since not(b) = (-b-1) = -(b+1), this should mean that SBC does A←A+C-(argument+1), or A←A+C-1-argument. So that's why the Carry flag needs to be set before subtractions.

blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

### Re: Negating a number

SBC is more like add carry and one's complement of operand to A. Thus you set carry to have it add two's complement to A (and clear carry to do a borrow). It's all so elegant.

BTW, a way of intuitively grasping negation is that you first flip all the bits, which is equivalent to subtracting the value from \$FF. But you want it subtracted from \$100, which is one more, so you add one.

tokumaru
Posts: 11864
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

### Re: Negating a number

Dafydd wrote:this should mean that SBC does A←A+C-(argument+1), or A←A+C-1-argument. So that's why the Carry flag needs to be set before subtractions.
In subtractions, I like to think of the carry flag as value you put there (i.e. SEC) to be borrowed. If it doesn't need to be borrowed (i.e. no underflow) it will remain there, otherwise it will be borrowed and the carry will be clear after the operation, indicating that the next SBC must borrow 1 from the next place. I know this is not the actual logic within the CPU, but conceptually this works fine.

koitsu
Posts: 4218
Joined: Sun Sep 19, 2004 9:28 pm

### Re: Negating a number

tokumaru wrote:
Dafydd wrote:this should mean that SBC does A←A+C-(argument+1), or A←A+C-1-argument. So that's why the Carry flag needs to be set before subtractions.
In subtractions, I like to think of the carry flag as value you put there (i.e. SEC) to be borrowed. If it doesn't need to be borrowed (i.e. no underflow) it will remain there, otherwise it will be borrowed and the carry will be clear after the operation, indicating that the next SBC must borrow 1 from the next place. I know this is not the actual logic within the CPU, but conceptually this works fine.
FWIW, this is exactly how I conceptualise it as well. :-)