## BCD arithmetics

37 posts / 0 new
Author
Message

Hi guys,
I want to make algorithms in assembly about bcd arithmetics(addition,subtraction,multiplication,division) with 2 and 4 digits bcd numbers (atmega32)
Can anyone help me? or give me links etc

Last Edited: Sat. Dec 29, 2018 - 08:01 AM
Total votes: 0

I would be very suprised if Atmel don't have an application note about BCD. Have you searched for prior art?

Total votes: 0

Can I ask why ?

I would convert to and from binary.

Total votes: 0

Probably assigned as a learning exercise that makes you think about masks, shifts, splits, carries and other basic concepts.
.
Agree that binary arithmetic with conversion at the point of use seems a "better" idea though.

Total votes: 0

Yes in deed.But doing binary arithmetics and then converting in bcd is still a right way to go?

Total votes: 0

Its easier!

Total votes: 0

There must be a reason for that H flag in SREG.

clawson wrote:
Its easier!

Well, yeah.  But IME always an exception to the rule.

Back when I was your age, a project was a rework for a 10-digit high-speed industrial counter to AVR from the semi-custom now-obsolete early micro.  The intent was to make a drop-in with an AVR.  Display was 7-seg LED, x10.

The counting was done in the ISR -- increment/decrement 40-bit value, compare to trip point, etc.  The mainline updated the display.  At high speeds, the display update "starved".

I did some experiments.  YMMV, and you 'Freaks might be better than I am, but I found that the fastest for me was to do the increment in BCD.  Then do the compare as a 5-byte value.  Doing the straightforward "work in binary then convert for display" wasn't as fast.  Perhaps as the 40 bits needed to roll over properly and the extra tests were costly.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Total votes: 0

clawson wrote:
I would be very suprised if Atmel don't have an application note about BCD. Have you searched for prior art?

https://www.microchip.com/wwwApp...

Essentially the same question a year ago:  https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Total votes: 0

But OP don't ask for a counter, there it make sense to do it in BCD.

Total votes: 0

But the it don't cover multiplication and division

Add. and sub. can that can be done simpler in BCD but I doubt that mul and div can.

But I guess you can prove me wrong

Last Edited: Sat. Dec 29, 2018 - 05:48 PM
Total votes: 0

You could do all your maths in BCD on a 6502.    Very few people ever did.

Other micros had a DAA opcode.

On an AVR you would have to implement the DAA in software.

I would think it is easier to calculate in binary and convert the final result to BCD.

However you could do each low level step and DAA every time.

I have not seen the Atmel App Note.    I suspect that is what they do.

David.

Total votes: 0

I once ported an old 8080 basic interpreter that had a BCD maths library.  Implementing the DAA instruction is only a handful of AVR opcodes.

Calculators use BCD, it is great for extended precision.

Somewhere I have a one inch thick textbook on 'Floating point rounding errors.'  Probably someones thesis.  Can not remember if that was the one that invoked the Gollum of Prauge as an example. Where all it takes is a single letter to instill life in the inanimate. Rounding errors can have similar effects when dealing with real world simulations. Gollums I am told are great servants, till they discover that they also have free will, and a mind of their own.

Anyway here is the Gollum:

```; code macro for decimal accumulator adjust
DAA:
; the 8 bit number in the accumulator is adjusted to form two
; four bit Binary Coded Decimal digits by the following process:
;
; 1. If the value of the lease significant 4 bits
; of the accumulator is greater than 9 or if the
; AC flag is set, 6 is added to the accumulator
; 2. If the value of the most significant 4 buts
; of the accumulator is greater than 9 or if the CY
; flag is set 6 is added to the most significant
; four bits of the accumulator
; Note: All flags are affected

;	push A		; r16
;	push ARGL	; r17
;	push ARGH	; r18
;	push r25    ; r19

;	push A
mov ARGL,A
mov ARGH,A
in r25,SREG
andi r25, (1<<SREG_C)

clc
brhs DAA_adjlo		; Half carry set
andi ARGL,0x0F
cpi ARGL,10
brlo DAA_hi
DAA_adjlo:
ldi ARGL, 6
add A,ARGL

DAA_hi:
tst r25
brne DAA_adjhi
mov ARGL,ARGH
cpi ARGL,0x9A
brlo DAA_nadjhi
DAA_adjhi:
ldi ARGL,0x60
add A,ARGL
sec
rjmp DAA_end
DAA_nadjhi:
clc

DAA_end:
;	pop r25
;	pop ARGH
;	pop ARGL
;	pop A

ret```

and a link to the git with the full BCD library PT Extended Basic Git

Total votes: 0

sparrow2 wrote:
Add. and sub. can that can be done simpler in BCD but I doubt that mul and div can.
If you really like BCD, then use Burroughs Medium Systems in COBOL. ;)

Same (or nearly so) question a year ago, with the same AVR model as the target. https://www.avrfreaks.net/commen... A uni course, and it is that time of the term for this assignment?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Total votes: 0

Since OP need BCD mul and div it don't make any sense not to convert to and from binary.

so I don't know why you write this :

If you really like BCD

and why do you continue to as links to threads that don't involve mul and div of BCD ? (please be a bit serious)

Total votes: 0

sparrow2 wrote:
and why do you continue to ...

Because I am the Surly Curmudgeon.  Didja look at the OP from Jan 2018 link?  Sure sounds like the same question to me.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Total votes: 0

???

jan 18 :

Could i have assembly codes about  1) BCD to binary
(Atmega 32A AVR studio 4.19)        2) binary to BCD
3) addition and subtraction of numbers in BCD code

where is the mul and div part ?

OP dec 18 :

I want to make algorithms in assembly about bcd arithmetics(addition,subtraction,multiplication,division)

I see a big difference if it make sense to make BCD code or just conversion code

Total votes: 0

sparrow2 wrote:
where is the mul and div part ?

Ease off.  Didn't you learn multi-digit multiplication when you were about 8?  And long division soon after?

Yah, if you are making a library then you may need to cycle-count.  OP's second post hints that he's leaning toward standard arithmetic, and conversion for display.

Remember I'm old and retiring.  I guess what you are saying is that I need to be more retiring.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Total votes: 0

sparrow2 wrote:

where is the mul and div part ?

I gave this thread a git link to the PT basic interpreter converted to AVRASM.  The four function maths package starts on line 8422.  It is too large to post here.  Why such places as git exist.

here is a direct link https://github.com/sheepdoll/PTExtendedBasicArduino/blob/master/EXBASICArduino.asm#L8422 to the line where the bcd code starts.  This was a separate library PT licensed from one of the other early program shops.

Granted this code was written over 40 years ago. There is enough ageism in this industry as it is.

That does not make it any less viable to learn from.   One can also see how the other functions commonly found on calculators are coded.  There are also some pretty neat and powerful matrix operators too. These can be used to solve simultaneous linear equations.

Total votes: 0

guys a little help.I am trying to implement the 5 digit bcd to 16bit conversion as is in the avr204 app note and I am getting a false result
Here is how I wrote the code

## Attachment(s):

Total votes: 0

What is a "false result".

IOW say what input data you used, say what output you expected to get, say what output you actually got.

BTW it's quite misleading to do:

```.def fBCD0=R16
.def fBCD1=R17
.def fBCD2=R18```

and then:

```LDI R16,0x99
LDI R17,0x99
LDI R18,0x09
RCALL BCDtoBIN16```

and then:

```BCDtoBIN16:
ANDI fBCD2,0x0F```

Why did you not use

```LDI fBDC0,0x99
LDI fBDC1,0x99
LDI fBDC2,0x09
RCALL BCDtoBIN16```

in the middle section? Otherwise assigning symbolic names to the registers is just plain confusing!

Last Edited: Thu. Jan 10, 2019 - 05:11 PM
Total votes: 0

Yes you re right.So as bcd numbers (input) I use 99999 and as a result I got 5F90.But 5F90 in decimal is 24.464

Total votes: 0

gunny5 wrote:
Yes you re right.

I'm not interested enough to dig it out, but wouldn't there be ASM source code already part of that app note?

gunny5 wrote:
So as bcd numbers (input) I use 99999 and as a result I got 5F90.But 5F90 in decimal is 24.464
gunny5 wrote:
.I am trying to implement the 5 digit bcd to 16bit conversion

"You cannot fit ten pounds of stuff into a five pound box." -- Ancient wisdom

As someone said above:

clawson wrote:
say what output you expected to get,

You did give the input value; you did say what you got.  But you did not tell us your expected result.

Enough hints yet?  How would you code 99999 in 16-bits ?  I'm surprised the app note did not mention that.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Fri. Jan 11, 2019 - 08:12 PM
Total votes: 0

Well the first problem I see is that this is not wide enough. On my (Windows) calculator it tells me that 99,999 in binary is 0x01869F which is THREE bytes. So if you were hoping for output in "L"/"H" registers it was never going to work anyway. 9999 might have been OK. That is 0x270F so will fit into two bytes/registers but the largest number you can hold in just 2 registers is 65535 so 99999 was never going to fit.

If, you cut this down to 9999 and that doesn't end up with 0x270F THEN you have a real problem! (By the same token 65535 should end up with 0xFFFF and that's the largest value you can cope with in a 2 byte output)

The alternative is to widen the output to cater for larger numbers. If you had 3 output registers the largest value that could be output is 0xFFFFFF which is 16777215.

EDIT: not typing fast enough!!

Total votes: 0

Surely you just Multiply the current binary result by 10,  add the next BCD digit.   Rinse and repeat.

Exactly the same as ASCII2BIN or any other evaluation.

Or you could have a table of decades e.g. 1, 10, 100, 1000, 10000.

For each BCD digit add the appropriate decade the digit value number of times.

The second method is not unreasonable.   I used to use it to evaluate numbers in 6502.

A typical execution is 4 24-bit MULTIPLY + 4 24-bit ADD versus 23 24-bit ADD

Of course 0x99999 is a worst case i.e. 45 ADDs.

0x65535 would be the maximum BCD value you can fit into a uint16_t.

David.

Last Edited: Thu. Jan 10, 2019 - 05:50 PM
Total votes: 0

Yes I took the asm code from the app note as is
originally I wanted to convert a 4 digit bcd to a 16 bit value
anyway as a result I expected 1 860F or at least 860F thats the conversion 99999 to hex that the calculator does.I am not sure if this is the right to check it but in the asm code 2 digit bcd to 8bit of the same app note I then check my result with the pc calculator and it was right

Total votes: 0

clawson wrote:

Well the first problem I see is that this is not wide enough. On my (Windows) calculator it tells me that 99,999 in binary is 0x01869F which is THREE bytes. So if you were hoping for output in "L"/"H" registers it was never going to work anyway. 9999 might have been OK. That is 0x270F so will fit into two bytes/registers but the largest number you can hold in just 2 registers is 65535 so 99999 was never going to fit.

If, you cut this down to 9999 and that doesn't end up with 0x270F THEN you have a real problem! (By the same token 65535 should end up with 0xFFFF and that's the largest value you can cope with in a 2 byte output)

The alternative is to widen the output to cater for larger numbers. If you had 3 output registers the largest value that could be output is 0xFFFFFF which is 16777215.

EDIT: not typing fast enough!!

So I gave the msd register of the bcd digitis the value of 0 and the other bcd digits the value of 9999 and as a result I got 0. So I delete the lines for fBCD2 (msd) and the result is still wrong(not 0x270F)
Sidenote:english is not my ordinary language and not typing fast enough feel free to joke around all jokes are accepted

Total votes: 0

gunny5 wrote:
I expected 1 860F or at least 860F thats the conversion 99999 to hex that the calculator does

What calculator are you using, 0x1860f = 99855 on mine!

Jim

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

Total votes: 0

Guys thanks for all your help I fixed my problem I dont know how....I just copy the code from the asm file and run it and it run right
Again thanks for your time

Total votes: 0

Ouch!  how does that help you learn.  If you just copy something with out understanding it, how does that advance the knowledge of society? The whole point of an advanced education is to come up with something new, that has not been done before.  Otherwise one just has an elementary  or Third grade education which means you can read write and do arithmetic by rote memorization.

It took me 40 years to find the BCD code from the 1970s.  I wanted to Understand how it worked, not simply copy it.  Then share that knowledge with others.

No wonder modern bridges and building fall down.

gunny5 wrote:

Guys thanks for all your help I fixed my problem I dont know how....I just copy the code from the asm file and run it and it run right
Again thanks for your time

Total votes: 0

jporter wrote:

Ouch!  how does that help you learn.  If you just copy something with out understanding it, how does that advance the knowledge of society? The whole point of an advanced education is to come up with something new, that has not been done before.  Otherwise one just has an elementary  or Third grade education which means you can read write and do arithmetic by rote memorization.

It took me 40 years to find the BCD code from the 1970s.  I wanted to Understand how it worked, not simply copy it.  Then share that knowledge with others.

No wonder modern bridges and building fall down.

gunny5 wrote:

Guys thanks for all your help I fixed my problem I dont know how....I just copy the code from the asm file and run it and it run right
Again thanks for your time

Fully agreed.Fun fact I spend hours to understand the app note and finally did.Wrote the code in the order I wanted and seems I wrote wrong as we saw
As a last effort I copy the code as it was in the app note and worked.I suspected a misconception in the .def oeders if thats possible

Total votes: 0

Just make sure you are using the latest AVR204 app, since in 2002 I found a bug in the old AVR204 app, later Atmel correct it

Both versions still on the net, just look for the new one.

Later I posted it here at AVRFreaks:

https://www.avrfreaks.net/forum/bugged-avr204-atmel-application-note

Cheers, Wagner.

Wagner Lipnharski
Orlando Florida USA

Last Edited: Fri. Jan 11, 2019 - 06:56 PM
Total votes: 0

gunny5 wrote:
I spend hours to understand the app note and finally did.

But apparently you haven't figured out that 99999 does NOT fit into 16 bits?!?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Total votes: 0

theusch wrote:

gunny5 wrote:
I spend hours to understand the app note and finally did.

But apparently you haven't figured out that 99999 does NOT fit into 16 bits?!?

Yes I did.Fixed all my mistakes.Thanks a lot

Total votes: 0

Another question (sorry for the many questions) but I am trying to find anything about arithmetics with signed bcd numbers
So I know how to split bcds in possitive and negative numbers but how I do arithmetics? Do I go with the sign extetion such as in binary numbers or there's another way?

Total votes: 0

What do you need to know that the Wikipeadia article doesn't tell you?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Total votes: 0

gunny5 wrote:

Another question (sorry for the many questions) but I am trying to find anything about arithmetics with signed bcd numbers
So I know how to split bcds in possitive and negative numbers but how I do arithmetics? Do I go with the sign extetion such as in binary numbers or there's another way?

Did you ever look at the standalone BCD maths package in the interpreter code I linked to up thred?  Signage take a good portion of that library package. Granted this is floating point BCD, where the exponent is scaled to the mantissa. The principles should remain the same.  Usually this is done with 10s compliment, which has different scaling than two's compliment.  Babbage's 1830s machines worked with 10s complement as did the CARDIAC cardboard computer distributed by AT&T.  I will admit I spent a bunch of time attempting to figure out why the DAA code above kept producing 9999. Finally I realized this was how -1 was stored internally.

Unlike real world abstractions of numbers, Digital systems (including octal and binary.) are finite bounded to the number of storage digits in addition to the sign.  So signage is going to take storage and time.  One of my mentors from the slipstick era, kept on about how can one trust the results, without a firm grasp of reality. This was in the days of the Pentium maths bug. It was from him that I became aware that computer maths are an illusion.  That there are only a few million possibilities of numbers that can be represented in 32 bits of storage at any given time.  The Greeks had a word for this, they called it a myriad. The largest number one can comprehend.  They also knew that there were an infinity of myriads. Finite infinities are not the easiest thing to grock, such however are the key to many abstractions like the point, line, plane and circle.

Total votes: 0

For ASM BCD math beyond 4 digits there is an AVR Freaks project  Math library  https://community.atmel.com/projects/math-library

7.8 signed fixed point binary coded decimal math library by Rolf R Bakke

Range  -9999999.99999999 to 9999999.99999999