6502DecimalMode

From VisualChips

(Difference between revisions)
Jump to: navigation, search
m (fix P adjustment)
m
Line 20: Line 20:
* 24 + 56 and C=0 gives 80 and N=1 V=1 Z=0 C=0 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a90a48a924286956ea08aa6849c2ea simulate])
* 24 + 56 and C=0 gives 80 and N=1 V=1 Z=0 C=0 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a90a48a924286956ea08aa6849c2ea simulate])
* 93 + 82 and C=0 gives 75 and N=0 V=1 Z=0 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a98e48a993286982ea08aa6849c2ea simulate])
* 93 + 82 and C=0 gives 75 and N=0 V=1 Z=0 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a98e48a993286982ea08aa6849c2ea simulate])
-
* 89 + 76 and C=0 gives 55 and N=0 V=0 Z=1 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a9fd48a989286976ea08aa6849c2ea simulate])
+
* 89 + 76 and C=0 gives 55 and N=0 V=0 Z=0 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a9fe48a989286976ea08aa6849c2ea simulate])
 +
* 89 + 76 and C=1 gives 56 and N=0 V=0 Z=1 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a9fd48a989286976ea08aa6849c2ea simulate])
* 80 + f0 and C=0 gives d0 and N=0 V=1 Z=0 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a9ba48a9802869f0ea08aa6849c2ea simulate])
* 80 + f0 and C=0 gives d0 and N=0 V=1 Z=0 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a9ba48a9802869f0ea08aa6849c2ea simulate])
* 80 + fa and C=0 gives e0 and N=1 V=0 Z=0 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a97e48a9802869faea08aa6849c2ea simulate])
* 80 + fa and C=0 gives e0 and N=1 V=0 Z=0 C=1 ([http://visual6502.org/JSSim/expert.html?graphics=f&steps=56&a=0&d=a97e48a9802869faea08aa6849c2ea simulate])

Revision as of 20:48, 14 December 2010

The 6502 had a couple of unique selling points compared to its predecessor the 6800, and the decimal mode was crucial because it was patent protected. It saves an instruction and a couple of cycles from each byte of decimal arithmetic, and removes the half-carry from the status byte - it also works for both addition and subtraction.

Decimal mode only affects ADC and SBC instructions, and on the NMOS 6502 only usefully sets the C flag. The N, V and Z flags are set, but don't correspond to what you might expect from a 10's complement decimal operation.

Nonetheless, all four flags are set, so it's worth understanding how they are set, and why. (Link to Ijor's paper, and Bruce's tutorial)

Many (software) emulators have decimal mode correct, and many have it incorrect or missing. Because the CMOS 6502 and later parts set the flags differently, correctness can only be judged relative to a specific part.

We need some test cases - these may yet be added to the py65 test suite (link), once they have been validated against the transistor-level simulation. At the time of writing, py65 will fail some of these tests, but perhaps not for long.

Need a list of interesting signals to probe to observe the decimal mode adjustments. (The presently released JSSim doesn't have C34 named, but it will on next update)

The two operands, and the carry in, are added as a pair of nibbles. The carry-out from bit3 is adjusted in decimal mode, only for ADC. So the ALU is not a binary byte-wide ALU with a decimal adjustment, it is a pair of binary nibble ALUs with a decimal adjustment. In the tests, we don't specifically need to test that carry-in is used (except to prove that carry-out is changing the carry bit, if we have that freedom)

Some of the tests below are found in Bruce Clark's V flag tutorial.

Tests for ADC

  • 00 + 00 and C=0 gives 00 and N=0 V=0 Z=1 C=0 (simulate)
  • 79 + 00 and C=1 gives 80 and N=1 V=1 Z=0 C=0 (simulate)
  • 24 + 56 and C=0 gives 80 and N=1 V=1 Z=0 C=0 (simulate)
  • 93 + 82 and C=0 gives 75 and N=0 V=1 Z=0 C=1 (simulate)
  • 89 + 76 and C=0 gives 55 and N=0 V=0 Z=0 C=1 (simulate)
  • 89 + 76 and C=1 gives 56 and N=0 V=0 Z=1 C=1 (simulate)
  • 80 + f0 and C=0 gives d0 and N=0 V=1 Z=0 C=1 (simulate)
  • 80 + fa and C=0 gives e0 and N=1 V=0 Z=0 C=1 (simulate)
  • 2f + 4f and C=0 gives 74 and N=0 V=0 Z=0 C=0 (simulate)

Tests for SBC

  • 00 - 00 and C=0 gives 99 and N=1 V=0 Z=0 C=0 (simulate)
  • 00 - 00 and C=1 gives 00 and N=0 V=0 Z=1 C=1 (simulate)
  • 0a - 00 and C=1 gives 0a and N=0 V=0 Z=0 C=1 (simulate)
  • 0b - 00 and C=0 gives 0a and N=0 V=0 Z=0 C=1 (simulate)
  • 9a - 00 and C=1 gives 9a and N=1 V=0 Z=0 C=1 (simulate)
  • 9b - 00 and C=0 gives 9a and N=1 V=0 Z=0 C=1 (simulate)

One form of test program sets all the input flags using PLP:

lda #$c8
pha
lda #$00
plp
adc #$00
nop

and to calculate what that initial value of PLP should be, we can use a bit more code

php
pla
EOR #$c3   // #$c2 if we don't want to invert the carry
nop
Personal tools