I have not yet cleaned up my code so I’m not going to post it here just explain it.

Code is now available here

How and Why

If you google for Binary to BCD conversion you will come up with the following algorithm

  1. Rotate the bits from the binary into the BCD
  2. In the BCD Check if 5 or higher
  3. If so add 3
  4. Go to step 1

So why are we adding 3 to 5 or higher
If we look at a sequence of binary representations between 0 and 15. And convert them from binary to BCD

================
HEX        BCD
0           0
1           1
2           2
3           3
4           4
5           5
6           6
7           7
8           8
9           9
A          10
B          11
C          12
D          13
E          14
F          15

You can see that there is a direct mapping between digits 0-9 in binary and BCD but digits A-F are a special case. So if we just copy a nibble from binary to BCD it works for 0-9 and not A-F. Further if we copy by rotation we can see this happen with A.

start
BCD is [0000 0000]
binary is [0000 1010]
rotate step 1  BCD [0000 0001] $01
rotate step 2  BCD [0000 0010] $02
rotate step 3  BCD [0000 0101] $05
rotate step 4  BCD [0000 1010] $0A

In step 3 we notice that in the BCD byte there is a value of $05. The next rotation of that byte will create $0A but we don’t want that we want $10 (BCD for 10) so we add 3 to the $05 and then rotate.

rotate step 3  BCD [0000 0101] $05
add 3          BCD [0000 1000] $08
rotate step 4  BCD [0001 0000] $10

Thus by adding the 3 prior to the rotation the next rotation creates the correct BCD value.

So a better algorithm may be

  1. for each nibble in the BCD
  2. check if the value is 5, if so add 3
  3. Rotate the bits from the binary into the BCD
  4. go to step 1

Further ponderings:

Question:

If the BCD result is actually 5 or above, how does the algorithm not add 3 and ruin the result?

Answer:

By doing the rotations after the summing, the last rotation results are not checked by the algorithm.

Question:

How does this work for multiple bytes, for example $50 needs 3 added to the high nibble is there

Answer:

Because this works only on a nibble basis it only manipulates one nibble. Therefore it does not matter where each nibble is in the sequence. It operates by manipulating the top bits of the nibble forcing the bit to be moved by the rotation, the sum itself never carries over into the next nibble.