In this lesson we will packet binary coded decimal (BCD) and how to maintain it during addition, increment, subtraction and decrement operations.
License Terms  


Packed BCD Format  
Our microprocessor normally works with two's complement, hexadecimal numbers. This is this most efficient notation for performing operations, as it contains both sign and magnitude of the data and fully utilizes all bit positions. However, there is another data format used for special purposes. This notation is called packed binary coded decimal, or most frequently, simply BCD.
BCD contains only magnitude information (no sign). Each byte contains two, backtoback, four bit 'nibbles'; each representing a binary value between zero and nine. The least significant four bits are the units value, and the most significant four bits are the tens value. Together they represent values from 0 to 99 inclusive.
BCD is most frequently used to directly drive digital read out (DRO)) devices and for format conversions to American Standard Code for Information Interchange (ASCII) or UNICODE characters for display or printing; since adding 30 hex to a BCD nibble in either code set will form the character equivalent of the value. 

BCD Addition  
So what happens when we add BCD numbers on a two's complement computer? Well that depends on the magnitude and carry of the result on a per nibble basis. If the magnitude of the result in a particular nibble is nine or less, and there is no carry, the result is the same for both BCD and two's complement addition; as in:
But suppose the two's complement addition resulted in a carry from, let's say, the lowermost nibble; what happens then?
But what if the two's complement addition results in a purely hexadecimal value, in let's suppose, the lower nibble, and no carry occurs?
What caused this? Well first of all you must understand that each nibble in BCD is a separate, standalone entity. When a carry is required, or occurs; the value carried should be ten. A carry out of a nibble on a two's complement computer is sixteen, which, in essence, you took six more than required from the nibble that initiated the carry. To put the results back into BCD, you must add that six back. In the case of a purely hexadecimal result, the cause is the same, except that there is a disconnect between when the carry should have occurred and when it actually does. 

The DAA Instruction  
The 8085 microprocessor contains one additional flag, AF, which is used by the decimal adjust for addition (DAA) instruction. This flag indicates that a carry out of the lowermost nibble has occurred. The 8085 uses the AF and CF flags to determine whether or not to add six to the appropriate nibble. It also checks each nibble for a hexadecimal value in making this decision.
This method works until we get to the number 99 (BCD), then something else that must be accounted for occurs:
In this case, the DAA instruction itself forced a carry to occur from the lowermost nibble, causing the uppermost nibble to assume a hexadecimal value during the instruction. The solution is to anticipate the effects of this carry on the uppermost nibble if that nibble is greater than eight.
Another breakdown happens between 159(BCD) and 160 (BCD) if we simply use the carry out of the DAA instruction as the new CF:
Here, disposing of the old carry and replacing it with the carry out of the DAA instruction, effectively threw out a hundred. If you are in the practice of throwing out a hundred, I would sure like to meet you, friend. The DAA instruction actually OR's the old carry with the carry out of the adjustment to form the new CF. 

Decimal Adjust for Subtract  
So what happens when we subtract instead of add? First of all, we must be able to detect when the result is the result of a subtract. After all, if you remember binary math, a subtract is nothing more than adding a two's complement value to the primary operand. The S8085C and S8085D manage this task by adding an additional flag, the NF (negative flag), which gets set on all eightbit subtract and decrement operations, and cleared for all other transactions. The NF helps us to determine how to adjust the result.
When you are performing two's complement subtraction by hand, if the magnitude of the subtrahend is greater than or equal to the minuend a carry occurs. If the minuend is greater, no carry occurs. The 8085 complements the carry bit automatically to set or clear the CF and AF flags, which are used to indicate borrows during subtract and decrement operations.
Similar to the carry in addition, the magnitude of a borrow is sixteen instead of ten. That means if you are performing a BCD subtraction, your result will be six greater than what you wanted. To adjust the value back to BCD, you will need to subtract six from that nibble. Observe:


Hundreds Complement Notation  
What happens when our subtraction yields a negative result? Let's look:
So what went wrong? Fact is  nothing. The result is correct. The borrow indicates another hundred hanging out there, like you subtracted 99 from 198 instead of 98. The result is in hundreds complement notation. Hundreds complement notation is simply the difference between one hundred and the absolute value of the result. This is done because BCD math is seldom performed on atomic (single) digit pairs. It must assume some more significant digits are out there. If your final result ends of negative, you can convert from hundreds complement to absolute notation by subtracting each byte of the result from zero (which represents 100 with the borrow).


True Sign Logic  
True sign logic assumes the operand magnitudes in the preceding instruction were greater than zero. That means the sign of any DAA result after an increment or add operation should be zero (positive). The sign of the DAA instruction after a decrement or subtract operation becomes 1 (negative) only if the carry flag from the preceding operation was set. In effect, this means that the sign flag from a DAA operation is nf & cf. 

IMPLEMENTATION  
To avoid additional inputs and decision making logic in the microcode state machine, the DAA instruction always adds the calculated adjustment value to the accumulator. In the 8085B version this is a straight forward exercise, with the exception of the corner cases noted above. In the S8085C and S8085D versions it is a little more complex. the decimal adjust for subtract is totally reliant on the incoming state of the auxiliary carry and the carry flags. Since DCRx instructions do not affect carry, you must do an ORAA instruction prior to the decrement to clear carry. Consequently, a DAA following a DCRA will not support negative results.
The flag logic for carry and auxiliary carry required modification to support the DAA instruction. The DAA adjustment value calculation was moved to the register file. I also, as promised, checked the uf flag and, since it works correctly as coded, decided that no modification was necessary.
With the DAA instruction added; our project has become a complete microprocessor, equivalent to the original 8085A and 8085B, and new 8085C microprocessors.


SIMULATION  
Of course, I don't expect you to believe a word of this without a simulation at least. Since a simple simulation requires a much longer simulation period (not to mention we really want to see the decimal adjust for subtract enhancements), we will need a new definitions file :


and a new test bench :


This time I'm not going to show you a bunch of pretty pictures. That's for you to do. Feel free to modify the test bench and try out different instruction sequences. 

Exercise  
