Binary Coded Decimal is a system for representing decimal numbers using hexadecimal numbers, where you simply "skip" the digits A to F. It is useful because some relatively simple routines allow arithmetic to be performed on BCD numbers using binary routines, with an "adjustment".


  ld a,$15 ; represents 15 (decimal)
  ld b,$27 ; represents 27 (decimal)
  add a,b  ; a now contains $3C (not a valid BCD number)
  daa      ; a now contains $42, representing 42 (decimal) = 15+27
  ld a,$09 ; represents 9 (decimal)
  inc a    ; a now contains $0a (not a valid BCD number)
  daa      ; a now contains $10, representing 10 (decimal) = 9+1

Advantages and disadvantages

It's useful for things like score counters because there is no need to convert the number from hexadecimal to decimal for display, which can save a lot of time. It can also be used to chain together as many BCD bytes as you like to get arbitrary-length numbers for things like high scores.

The downside is that you're much more limited with your mathematical flexibility (see below), it takes longer to do calculations (so it's only really useful for displayed values), you have to manually chain bytes together, and because you can only store up to 99 in a single byte, you run out of space and have to deal with multiple bytes a lot more quickly (you can store up to 65535 in a 16-bit integer and use normal instructions for arithmetic but you'd need 3 chained BCD bytes and custom routines to store it as BCD).

The daa instruction adjusts the contents of register a after the (8-bit) add, adc, sub, sbc, inc, dec and neg instructions. It does not adjust after any other opcodes. The h and n flags are there just for this instruction to be able to work; it also uses the c flag.

Using daa to convert a number to BCD

This is somewhat controversial because some people claim it can't be done; but it can:

; Hex to BCD
; converts a hex number (eg. $10) to its BCD representation (eg. $16).
; Input: a = hex number
; Output: a = BCD number
; Clobbers: b,c
   ld c,a  ; Original (hex) number
   ld b,8  ; How many bits
   xor a   ; Output (BCD) number, starts at 0
-: sla c   ; shift c into carry
   adc a,a
   daa     ; Decimal adjust a, so shift = BCD x2 plus carry
   djnz -  ; Repeat for 8 bits

Return to top