Problem with ADC and nestest

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Problem with ADC and nestest
by on (#224241)
Hello.
I am testing my 6502 emulator and I am having some trouble with ADC. I am using this nestest log for this purpose: http://www.qmtpro.com/~nes/misc/nestest.log

Code:
C966  A9 7F     LDA #$7F                        A:FF X:00 Y:00 P:E4 SP:FB CYC: 95
C968  69 80     ADC #$80                        A:7F X:00 Y:00 P:64 SP:FB CYC:101
C96A  10 0B     BPL $C977                       A:FF X:00 Y:00 P:A4 SP:FB CYC:107


According to this, C = 0 before ADC. Therefore, the operation is: A = $7F + $80. The result should be A = $FF. As the sign changes V flag should be 1. However, this log shows P = $A4, when I think it should be P = $E4. Why is this happening? Am I wrong?
Re: Problem with ADC and nestest
by on (#224243)
That adds -128 to +127. The result, -1, still fits in a signed 8 bit number, so oVerflow is not set.
Re: Problem with ADC and nestest
by on (#224245)
Overflow flag isn't for sign changes. It's for if the result isn't represented correctly.

Here's a helpful page: http://www.righto.com/2012/12/the-6502- ... ained.html
Re: Problem with ADC and nestest
by on (#224256)
adc/sbc have been discussed heavily over the years, and still remain the top struggle point for people writing 6502 cores. Here's reference material, including actual (very simple) code you can use to accomplish proper implementation: viewtopic.php?p=119626#p119626

P.S. -- Are you just writing a 6502 core, or are you writing a NES emulator? Thanks.
Re: Problem with ADC and nestest
by on (#224273)
Signed numbers range from -128 to 127, so whenever the output is in that range, V should be clear. No addition of inputs with different signs can generate an invalid output (e.g. 0 + -128 = -128; 127 + -128 = -1), but when the inputs have the same sign, it's possible for the result to go below -128 or over 127 (e.g. -128 + -1 = -129; 127 + 1 = 128), resulting in invalid 8-bit 2's complement values. This means that the rule for the V flag is: if both inputs have the same sign AND the output has a different sign, set the V flag, otherwise, clear it.

BTW, this logic is for ADC, but when emulating the 6502, the simplest way to implement SBC is to reuse the ADC code but XOR the operand with 255. If I'm not mistaken, even the real chip implements SBC that way.
Re: Problem with ADC and nestest
by on (#224294)
Thank you all for your answers. I was clearly wrong about the V flag. Now I can go on with the emulator.

koitsu wrote:
adc/sbc have been discussed heavily over the years, and still remain the top struggle point for people writing 6502 cores. Here's reference material, including actual (very simple) code you can use to accomplish proper implementation: http://forums.nesdev.com/viewtopic.php?p=119626#p119626

P.S. -- Are you just writing a 6502 core, or are you writing a NES emulator? Thanks.


I am writing a NES emulator.
Re: Problem with ADC and nestest
by on (#229748)
Here is how I handle the V flag. I hope this helps you understand better how overflow works.

int temp;

temp = (char)A + (char)DataBus + C;

V = (temp < -128 || temp > 127);

Edits: Formatting.