Code: Select all
uint temp = (uint)(ACC - src - C_FLAG);
Z_FLAG = !(temp & 0xff);
N_FLAG = (temp & 0x80);
V_FLAG = ((ACC ^ temp) & (Memoria[PC] ^ temp) & 0x80)
C_FLAG = (temp < 0x100);
ACC = (byte)(temp & 0xff);
That code doesn't look correct.
First, the formula is A = A - M - 1 + C, where M (memory) is the operand of the SBC instruction. So the C flag should be inverted prior to the temp calculation (to be fair, since this is only an excerpt of code, maybe it was).
Second, for a calculation such as $10-$20, temp would be $F0 (-16), so there should be no overflow, but the V_FLAG calculation would be non-zero. Yet $20-$10 also has no overflow, but V_FLAG would be zero (which is correct).
Third, -- this is not necessarily an error, just an observation -- it's strange that src is used in the temp calculation but the Memoria array is used in the V_FLAG calculation.
Anyway, one way to determine the formula for the V flag is from the truth table for 1-bit subtraction. (In this table, N is the N flag, i.e. the A output.) A 1-bit twos complement number ranges from -1 to 0.
Code: Select all
A M c | N C V
------+------
0 0 0 | 1 0 0 0 - 0 - 1 + 0 = -1
0 0 1 | 0 1 0 0 - 0 - 1 + 1 = 0
0 1 0 | 0 0 0 0 - -1 - 1 + 0 = 0
0 1 1 | 1 0 1 0 - -1 - 1 + 1 = 1
1 0 0 | 0 1 1 -1 - 0 - 1 + 0 = -2
1 0 1 | 1 1 0 -1 - 0 - 1 + 1 = -1
1 1 0 | 1 0 0 -1 - -1 - 1 + 0 = -1
1 1 1 | 0 1 0 -1 - -1 - 1 + 1 = 0
Just as you can extend 8-bit to subtraction to 16 bits with a sequence like:
Code: Select all
LDA NUM1
SBC NUM2
STA NUM3
LDA NUM1
SBC NUM2
STA NUM3
a 1-bit subtraction can be extended to 2 bits, 3 bits, etc. in the same sort of way. So the 1-bit subtraction truth table above is actually sufficient to describe 8-bit addition. c represents the carry from the addition of the first 7 bits, A and M are the hi bits of the A and the operand, and then N, C, and V represent the N, C, and V flag results. (If you're having trouble seeing this, you could work out the 32 cases for a 2-bit addition by hand -- the input bits will be A1, A0, M1, M0, and c -- and you'll find that the formulas below still hold true.)
From the truth table, you can derive common formulas for the V flag:
V = C XOR c
V = ((NOT A) AND M AND N) OR (A AND (NOT M) AND (NOT N))
The latter formula is the same as:
V = (A XOR M) AND (A XOR N)
so replacing the second temp with ACC should do the trick.