PDA

View Full Version : 32-bit Variables and DIV32, Hourmeter 99999.9



Darrel Taylor
- 22nd June 2005, 05:15
Continuing the series of using DIV32

If you missed them, the first 2 threads are ...
Retrieving 32bit Multiply Result (http://www.picbasic.co.uk/forum/showthread.php?t=24)
Retrieving Div32 Remainder (http://www.picbasic.co.uk/forum/showthread.php?t=48)

Here's another macro that allows you to use a 32-bit variable as the input to DIV32.
;----[Load a 32-bit (Dword) variable into PBP registers, Prior to DIV32]--------
Asm
PutMulResult?D macro Din
MOVE?BB Din, R2
MOVE?BB Din + 1 , R2 + 1
MOVE?BB Din + 2, R0
MOVE?BB Din + 3, R0 + 1
RST?RP
endm
EndAsmNow, before you ask ... Yes, PicBasic Pro does allow 32-bit variables, it just doesn't handle them for you.

A recent request from someone here was to have a Runtime Hourmeter that counts up to 99999.9 hours. Since it takes more than 65535 to hold the value, how can you (1) keep track of that large of a number and (2) Display the number once you have it.

Let's look at the first part, Making a 32-bit variable.

Hours VAR WORD[2] ; 32-bit (Dword)
HoursH VAR Hours(1)
HoursL Var Hours(0)
The above will create a 2 word Array called Hours.
HoursL points to the low Word - Hours(0)
HoursH points to the high Word - Hours(1)

Since it's only going to be counting time, all we need to do is add 1 each time. Fortunately, that makes things easy. This next routine should be called once every 6 minutes (.1 hour) preferably timed by Interrupts.
;----[Add 1 tenth of an hour to the hourmeter]----------------------------------
AddHourTenth:
HoursL = HoursL + 1
IF HoursL = 0 then HoursH = HoursH + 1
if (HoursH = $F) and (HoursL = $4240) then ; Roll over at 1,000,000
HoursH = 0 ; 99999.9 + .1
HoursL = 0
endif
returnAnd all that's left to do is display it (2)
For this it takes a little trick that was descibed in the Retrieving Div32 Remainder (http://www.picbasic.co.uk/forum/showthread.php?t=48) thread.

Let's say the value of Hours is 917,456. To get this down to usable numbers we can use DIV32.

First, load the 32-bit Hours value into PBP's registers using PutMulResult?D
@ PutMulResult?D _Hours
then DIV32 that by 1000
Result = DIV32 1000
Remainder = R2
Notice that you have to get the remainder immediately after the DIV32.

So now you have the first 917 in the Result variable and the last 456 in the Remainder variable. All the digits are there, it's just a matter of displaying them.
LCDOUT $FE, 2 ; Home Cursor
IF Result > 0 then
LCDOUT Dec Result, DEC2 Remainder/10,".",DEC1 Remainder//10
else
LCDOUT DEC Remainder/10,".",DEC1 Remainder//10
endif
This of course will display 91745.6

Here's the whole program for the Hourmeter. Timing not included
Hours VAR WORD[2] ; 32-bit (Dword) Holds up to 99999.9 hours
HoursH VAR Hours(1)
HoursL Var Hours(0)

Result Var Word
Remainder Var Word

;----[Load a 32-bit (Dword) variable into PBP registers, Prior to DIV32]--------
Asm
PutMulResult?D macro Din
MOVE?BB Din, R2
MOVE?BB Din + 1 , R2 + 1
MOVE?BB Din + 2, R0
MOVE?BB Din + 3, R0 + 1
RST?RP
endm
EndAsm

;====[Simple loop to test the HourMeter]========================================
MainLoop:
gosub AddHourTenth
Gosub ShowHourMeter
goto MainLoop ;================================================= ===========


;----[Add 1 tenth of an hour to the hourmeter]----------------------------------
AddHourTenth:
HoursL = HoursL + 1
IF HoursL = 0 then HoursH = HoursH + 1
if (HoursH = $F) and (HoursL = $4240) then ; Roll over at 1,000,000
HoursH = 0 ; 99999.9 + .1
HoursL = 0
endif
return

;----[Display hourmeter using LCDOUT]-------------------------------------------
ShowHourMeter:
@ PutMulResult?D _Hours
Result = DIV32 1000
Remainder = R2
LCDOUT $FE, 2 ; Home Cursor
IF Result > 0 then
LCDOUT Dec Result, DEC2 Remainder/10,".",DEC1 Remainder//10
else
LCDOUT DEC Remainder/10,".",DEC1 Remainder//10
endif
return

Best regards,
   Darrel Taylor

palmed
- 2nd March 2006, 15:46
Hi,

this is my first post, I'm German so please excuse, if my English is not so very well.

I often used DIV32 before and never had a problem. It works fine.

Now I have the problem, that I have to produce a reciprocal value, to be exact, I have to divide 1,25E9 by values between 6200 and 32000. Dividing by 32000 is no problem again, I'll get 1,25E9/32000=39062, but dividing by 6200 will result in 1,25E9/6200=201612, which is way beyond a word variable.
Does anybody know if there is a chance to access this result?

Any help is greatly appreciated.

Peter

Darrel Taylor
- 2nd March 2006, 22:16
Hi Peter,

Sure, you can do it.

First off, you'll need to lose one of zero's from that 1,250,000,000

If you start off with 125,000,000 it brings it down to a managable range.

125,000,000 / 32000 = 3906.2
125,000,000 / 6200 = 20161.2

Then you have most of the number from the integer portion, and the last digit is in the remainder, in the form of a Modulas. By dividing the (Modulas*10) by the original divisor, you can recover the last digit.
<font color="#000000"><b>Temp </b><font color="#008000"><b>VAR WORD</b></font>
<b>Divisor </b><font color="#008000"><b>VAR WORD
</b></font><b>Remainder </b><font color="#008000"><b>VAR WORD

</b></font><font color="#0000FF"><b><i>;----[Load a 32-bit constant into PBP registers, Prior to DIV32]--------
</i></b></font><font color="#008000"><b>ASM
</b></font><font color="#000080">PutMulResult macro Const32
MOVE?CB low Const32, R2
MOVE?CB low (Const32 &gt;&gt; 8), R2 + 1
MOVE?CB low (Const32 &gt;&gt; 16), R0
MOVE?CB low (Const32 &gt;&gt; 24), R0 + 1
endm
</font><font color="#008000"><b>ENDASM

</b></font><b>Divisor </b>= <b>6200
</b><font color="#000080">@ PutMulResult 125000000
</font><b>Temp </b>= <font color="#008000"><b>DIV32 </b></font><b>Divisor
Remainder </b>= <b>R2 </b>* <b>10
Remainder </b>= <font color="#008000"><b>DIV32 </b></font><b>Divisor
</b><font color="#008000"><b>LCDOUT </b></font><font color="#FF0000">&quot;Result=&quot;</font>,<font color="#008000"><b>DEC </b></font><b>Temp</b>,<font color="#008000"><b>DEC1 </b></font><b>Remainder</b>

Result = 201612

HTH,
&nbsp;&nbsp;Darrel

palmed
- 3rd March 2006, 09:38
Hi, Darrel,

thanks a lot. After all, the answer was contained in some postings before, but sometimes you "don't see the trees in the wood" (correct saying?).

I tested it and it works great!

Peter

Charles Linquis
- 2nd August 2006, 03:04
Darrel,

You constantly amaze me. What would this forum do without you?

mister_e
- 2nd August 2006, 04:34
probably just trying to use the PBP statement stated in the manual or ... hum hum.. change to another boat... wich, after trying, i reaaaallly don't recommend :)

Darrel Taylor
- 2nd August 2006, 17:55
Thanks Charles,

And, without me... The forum would be reading a lot more SPAM from PCB houses in China. :) &nbsp; Love that delete command.

But, with over 2400 posts, I'm wondering what we'd do without mister_e.
Glad he didn't like the other boat. He makes up for like 10 people.

DT

mister_e
- 2nd August 2006, 18:22
The first one to blame here is Bruce... if i'd never discover his website, i'd never buyed this addictive compiler... can't live without! Chances are that the other boat wasn't buyed from him... i would hate him now LMAO!

Well thanks to the forum ! I learn almost everything here by trying to help other with their questions. Learning by trying/debugging never killed.. kinda challenge. My avatar choice says long ;) It also give me a better english.. oh yeah far to be perfect but better than before... i guess... i hope. Where are my firsts posts?

Thanks Darrel, Bruce, Melanie and all other gurus... i wish one day i'll be as good as you are!

charudatt
- 23rd November 2006, 07:48
Thanks steve for your tip in #6 on the other boat. I was about to buy it.

Thanks once again for sharing your wisdom on this forum, which goes to all the guru's.

really appreciate help from all.

regards

mister_e
- 23rd November 2006, 08:23
My pleasure Charudatt AND you're welcome!