# How does Decimal Mode in an ALU work?

Trying to wrap my head around the basic of how to do decimal addition in an ALU. Here is what I have so far.

I am primarily looking at the MOS 6502 CPU architecture. It has two modes in which you can do operations on values. The first is normal mode. Give it two hex number and you get a hex number. Example,

0x5 + 0x6 = 0xA


The second mode (decimal mode) will take two hex numbers (between 0-9) and output the result in hex BUT adjusted so it looks like decimal. Example,

0x5 + 0x6 = 0x11


So I fell back to my python programming to write out a simple function to emulate the mode. Basically, every time your hex number is divisible 0xA(10) then you add 6 to the result.

def add(a, b):
c = (a+b) + (((a+b)/10) * 6)
return hex(c)

'0x30'


So,

How is this done using digital logic?

• Not an answer, but, if you are interested in 6502 implementation details, you should look at visual6502.org Commented Nov 6, 2014 at 21:47

I don't know what logic the 6502 uses exactly, but many micros have a decimal adjust instruction that depends on having carry and nibble carry flags available. It is applied after a binary 8-bit addition.

The logic works like this:

If there's a nibble carry or if the LSD is > 9, add 0x06 ('or' the carry flag previous with new)

If there's a carry or if the MSD is > 9, add 0x60 and set carry.

So if, for example:

add 0x43 and 0x39 in binary you get 0x7C with no nibble carry. Since LSD > 9, add 0x06 to give the result of 0x82 (no carry), which is the correct packed BCD result.

add 0x49 and 0x49 in binary you get 0x92 with a nibble carry Since nibble carry, add 0x06 to give result of 0x92 (no carry)

add 0x50 and 0x50 n binary, you get 0xA0 with no nibble carry Since MSD > 9, add 0x60 to give result 00 with carry.

etc.

Now, if you want do it in one step, you can easily make a BCD adder for packed two-digit BCD by combining two nibble BCD adders with a carry between, as seen here, which is just the logic I described above, but ripple-through rather than sequential.

You could easily add some AND gates to the above circuit to make it dual mode (binary/decimal) as in the venerable 6502.

• The NMOS 6502 is the only processor I know of which performs a two-digit BCD addition in a single cycle; CMOS versions of that processor require an extra cycle. I suspect that's because CMOS logic requires implementing all logic in "inverted-in" and "inverted-out" forms [e.g. a CMOS NAND combines an inverted-input OR gate with an inverted-output AND gate]; for simple gates both forms will have equal complexity, but for some kinds of logic one form may be much simpler than the other. Commented Feb 18, 2015 at 23:12
• I think that the second example should say a result of 0x98 at the end? Commented Apr 4, 2017 at 22:54

Nibble by nibble. As such there's no need to divide by 0xA, since each nibble sum can be either less than 0xA, or not less than 0xA (at which point we add 6 before the next stage).

• OK, that makes sense about breaking down to nibbles but, could you explain a bit more. How exactly is 6 added between "stages"? Commented Nov 6, 2014 at 18:52
• Normally in an adder the carry is rippled directly from one unit to the next. In the case of a BCD adder you ignore the normal carry generated from the nibble addition and instead compare the 5-bit sum with 0xA. The result of this compare becomes the new carry, plus it determines whether or not you need to add 6 before outputting the nibble. Commented Nov 6, 2014 at 19:12