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

## BCD arithmetics

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

Can I ask why ?

I would convert to and from binary.

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.

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

Its easier!

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.

**clawson wrote:**

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

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

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

...

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

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

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.

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

**sparrow2 wrote:**

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

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?

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)

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

???

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

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

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

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

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!

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

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

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

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.

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

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

THENyou 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 b**cd 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**

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

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

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

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

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.

**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?!?

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

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?

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

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

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