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 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

inc a ; a now contains $0a (not a valid BCD number)

daa ; a now contains $10, representing 10 (decimal) = 9+1

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.

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

HexToBCD:

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

; converts a hex number (eg. $10) to its BCD representation (eg. $16).

; Input: a = hex number

; Output: a = BCD number

; Clobbers: b,c

HexToBCD:

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

Retrieved from http://www.smspower.org/Development/BinaryCodedDecimal

Page last modified on Fri May 14, 2010 9:31 am