BCD<->Hex conversion in asm

By sd_snatcher

Prophet (3480)

sd_snatcher's picture

26-06-2011, 23:52

To me, one of the most annoying things when coding in asm for the Z80 is when I need to deal with decimal numbers, particularly the Hex->BCD, BCD->Hex conversion annoys me a lot and consumes a lot of precious time.

Is there any ready to use library for hex->BCD and BCD->Hex conversion?

It would be great to have those published on the MSX Assembly Page, just like the very useful Multiplications, divisions and shifts article.

Login or register to post comments

By sd_snatcher

Prophet (3480)

sd_snatcher's picture

27-06-2011, 00:12

Sorry, I mean BCD->Binary and Binary->BCD conversion.

By caro

Champion (511)

caro's picture

27-06-2011, 08:09

;****************************
;	a(BCD) => a(BIN) 
;	[00h..99h] -> [0..99]
;****************************
bcd2bin:
	push	bc
	ld	c,a
	and	0f0h
	srl	a
	ld	b,a
	srl	a
	srl	a
	add	a,b
	ld	b,a
	ld	a,c
	and	0fh
	add	a,b
	pop	bc
	ret
;*****************************
;	 a(BIN) =>  a(BCD) 
;	[0..99] => [00h..99h]
;*****************************
bin2bcd:
	push	bc
	ld	b,10
	ld	c,-1
div10:	inc	c
	sub	b
	jr	nc,div10
	add	a,b
	ld	b,a
	ld	a,c
	add	a,a
	add	a,a
	add	a,a
	add	a,a
	or	b
	pop	bc
	ret
;*******************************

By bore

Master (135)

bore's picture

27-06-2011, 08:54

For bin->bcd conversion I like this little trick with the daa instruction.

;*****************************
;	 a(BIN) =>  a(BCD) 
;	[0..99] => [00h..99h]
;*****************************
bin2bcd:
	push	bc
	ld	c, a
	ld	b, 8
	xor	a
.loop:
	sla	c
	adc	a, a
	daa
	djnz	.loop
	pop	bc
	ret

If you wonder wth this function does; have a look at bit 7 of the invalue. Without the daa instruction it would just be placed in the accumulator and then multiplied with 2 until it is worth 128 again. With daa it is the same thing but it will be bcd adjusted after each "multiplication".
Unrolling the loop will as usual trade codesize for speed and since the accumulator won't become more than 7 until after the first three shifts you can skip the daa instruction for those first unrolls.

By wouter_

Champion (469)

wouter_'s picture

27-06-2011, 19:17

To me, one of the most annoying things when coding in asm for the Z80 is when I need to deal with decimal numbers, particularly the Hex->BCD, BCD->Hex conversion annoys me a lot and consumes a lot of precious time.
Maybe I'm just confused about terminology here. But I find it strange you want to convert hex/binary to/from BCD. The whole point of BCD encoding is that you never have to perform any conversions: Printing/parsing a string from/to BCD is relatively easy. And you can directly calculate with numbers in BCD encoding (that's what the DAA instruction is for).
Did you instead want a routine to parse an ASCII string that represents a decimal number? And another routine to print a value in decimal format?

By sd_snatcher

Prophet (3480)

sd_snatcher's picture

27-06-2011, 21:45

@wouter_

Yes, you're right. I do need to print decimal numbers, and I thought BCD could make it easier because long ago I saw some games that used the DAA trick mentioned here to accomplish it.

Anyway, thanks caro and bore for those nice BCD routines! Big smile

By RetroTechie

Paragon (1563)

RetroTechie's picture

29-06-2011, 04:57

wouter_ is right for the case where you're initializing / updating a number yourself (like scores in a game, a digital clock & things like that).

As for binary->ASCII conversion, also have a look at this old thread.