To put it in the simplest terms possible,

**V means that the N flag is wrong**-- an addition has gone outside the range 0 to 127, or a subtraction has gone outside the range -128 to -1, and so caused a false change of sign.

This happens whenever an

**ADC**instruction with a positive addend already in the accumulator and a positive augend specified in the instruction produces a

*negative*-looking sum (when it's actually between 128 and 255); or an

**SBC**instruction with a negative minuend already in the accumulator and a positive subtrahend being taken away from it produces a

*positive*-looking difference (actually between -256 and -129). Subsequent arithmetic operations may push it back into range, of course, and the way twos-complement arithmetic works will mean the answer is then right (they may just as easily make it wronger and wronger; even eventually going past -256 or +255, where things begin to look right again until we exceed -384 or +383 .....) but right now, the important thing we need to know is:

**if V is set following an addition or subtraction, N is wrong.**V=1 and N=1 together indicate a

*positive*number; V=1 and N=0 indicate a

*negative*number. If V=0 then we do not have to worry, of course: N is correct.

(Part of my day job involves testing edge cases. And the V flag is a nice example of an edge case test, right there in the 6502 hardware.)

For all but the most significant byte of a multi-byte quantity, V is as meaningless as N (which is set from the high bit of the last byte seen, but is

*only*the sign bit when it's the

*very highest*bit, i.e., in the highest byte.)

In the case of higher-or-lower comparisons between signed numbers, this is important.

**CMP**performs an

*unsigned*comparison without borrow, and sets C if the subtrahend is smaller than or equal to the minuend and Z if it is equal. That's fine for unsigned numbers. But -128 (which looks like 128) appears larger than 127, and -1 (which looks like 255) appears larger than 1. In fact, all simple comparisons between negative and positive numbers fail this way.

If we add 128 to the negative numbers -128 to -1 (giving a range 0 to 127 instead of -128 to -1) and subtract 128 from the positive numbers 0 to 127 (giving a range -128 to -1, which looks like 128 to 255, instead of 0 to 127) the two ends of the range effectively swap places, putting the whole number line into the right-looking order for the

**CMP**instruction. And that operation is basically just toggling bit 7 of each of the minuend (comparand?) and subtrahend (comparator?), which can be done with

**EOR #&80**.

For multi-byte signed numbers, we can't really use

**CMP**because it doesn't allow for importing a borrow. So instead we will have to do a multi-byte subtraction, starting with

**SEC**and then

**LDA**/

**SBC**pairs. And this is where we are likely to run afoul of sign bit issues.

Here's an example from BCP, of course:

Code: Select all

```
\ Test whether the point is off to the left (bottom) of the box
\ Y=0 for left, Y=2 for bottom
.testLB
SEC
LDA (ptb),Y \ point base
SBC (bxb),Y \ box base
INY
LDA (ptb),Y
SBC (bxb),Y
\ now if V is set, N will be wrong
BVC testLB1
EOR #&80 \ flip bit 7
.testLB1
\...
```

**EOR**instruction to toggle the sign bit.

Anyway, now you know what V does. Well, almost. Because there is another instruction, besides

**ADC**and

**SBC**, which can affect it:

**BIT**.

**BIT**is limited to absolute addressing (though it has "long" and "short" forms) and performs an AND operation between the contents of the accumulator and the contents of the address supplied in the operand; the result is discarded, but the Z flag is set if all bits of the result were zero. It also sets N and V to bits 7 and 6 respectively of the address contents before the AND -- this enables you to test a flag in either bit 6 or bit 7 of a byte without wasting cycles and without disturbing the contents of the accumulator.

You can test the V flag and conditionally branch with

**BVC**and

**BVS**; and you can clear it with

**CLV**. (If you ever need some code to be able to run independently of its position in memory,

**CLV**followed by

**BVC**will simulate an unconditional relative branch without affecting N, Z or C.) There's no

**SEV**instruction; but if you ever need to set the V flag, you can do it with a

**BIT**instruction pointing to an address which you know contains a value with bit 6 set -- an

**RTS**instruction in your code is as good as anything. Other instructions that can affect V are

**PLP**,

**RTI**and there is also an input pin on the processor to allow it to be set by hardware.

And that's about it for V.