> Currently I am trying to implement a pre-/post-payment power meter
> utilising MSP430, maybe some other people can help in implementing
> the four basic math functions - add, subtract, divide & multiply -
> in BCD... :)
Except for divide (which is always intricate on machines without
hardware support), the other three are pretty trivial...
Add: Use the DADD instruction. Clear the carry bit first. If the carry
bit is set at the end, you've overflowed.
Subtract: Invert, set the carry bit, and add. "Invert" in
BCD is subtracting from 0x9999. If the carry bit is clear at the
ed, you've gone negative.
Multiply: To compute z = x * y, Reduce this to a single-digit multiply:
z = z * 10 + x * ydigit
Normally, in binary, "10" is 2 and "ydigit" is 0 or 1, which simplifies
it, but this can be simplified to a 5-stage and a bianry stage:
z = z * 5 + x * (ydigit/2)
z = z * 2 + x * (ydigit%2)
And the first can be done simply by making a copy of z initially:
/* z = z*5 + x*(ydigit/2) */
z1 = z;
if (ydigit/2 == 4)
z += x;
z *= 2
if (ydigit/2 == 2 or 3)
z += x;
x *= 2;
if (ydigit/2 == 1 or 3)
z += x;
z += z1
/* z = z*2 + x*(ydigit%2) */
z *= 2;
if (ydigit is odd)
z += x;
An alternative technique, which would be similarly efficient but could
produce smaller code, would be to convert y to binary and then use
the standard binary multiplication technique with BCD addition to
multiply z = x*y. Assuming you already had a BCD-to-binary routine,
this would reduce the size of the multiply inner loop.
Divide: This is just like pencil-and-paper long division. See Knuth
for techniques. Basically, you use the first few digits to estimate a
quotient digit that might be too large but is never too small, subtract
the divisor * quotient_digit, and if your subtraction wraps (which should
be infrequent if your estimate was good), you need to decrement your
quotient digit and add the dividend until the addition wraps back.
Basically all division schemes work this way, estimating a quotient
digit and then coping if the guess was wrong. This one-sided error
is not too hard to generate and convenient for software.
Hardware generally uses SRT division, where you guess and subtract, then
let the next quotient digit be negative if necessary to correct it. At
the end, you have to add up the quotient digits, because they "overlap".
This is tricky in different ways, but it avoids unpredictable timing.
If you have to do enough computation that this becomes worth-while,
it's probably worth converting to binary in the first place.