The carry (C) flag is the much simpler of the two. For addition, it works pretty much like a carry works when you add on paper. You'll normally start with C clear. If the first column (in the paper analogy) generates a carry, C gets set, which adds one to the next colum.
For subtraction, C=1 just means you haven't borrowed. Pretty simple. The examples below cover C. Now on to the V flag.
WDC's programming manual says that to get the V flag, the 6502 XOR's the carry out of bit 6 with the carry out of bit 7 (which ends up in the C flag). In other words, V will reflect the result of the XOR of these two carry values.
I decided to actually try it. Sometimes the rules are harder to understand without examples. Here's what I got (all numbers in hex):
First with ADC, starting with C clear: (1st number, 2nd number, then the resulting number and flags)
Code:
1st 2nd result N V C
-----------------------------------------------
7 -2 5 0 0 1
7 2 9 0 0 0
7 80 87 1 0 0
7 -9 -2 1 0 0
7 7A 81 1 1 0
80 90 10 0 1 1
F0 F0 E0 1 0 1
F8 0A 2 0 0 1
Now with SBC, starting with C set:
F8 0A EE 1 0 1
81 7 7A 0 1 1
7 2 5 0 0 1
7 -2 9 0 0 0
7 9 FE 1 0 0
7 90 77 0 0 0
10 90 80 1 1 0
10 91 7F 0 0 0
Again, the book says that to determine the correct overflow flag value, the processor XORs the carry out of bit 6 with the carry out of bit 7 (which winds up in the carry flag), and transfers the result to the overflow flag.
More simply, V=1 means the sign of the result is wrong. Take for example the second-to-last line of the table above. 10 minus 90 is, in signed numbers, 10 minus -70, or 10+70. The result has to be positive; but 80 with its bit 7 set looks negative, so the sign is wrong and the V flag is set to indicate that fact.
Garth Wilson