Continuing the series of using DIV32
If you missed them, the first 2 threads are ...
Retrieving 32bit Multiply Result
Retrieving Div32 Remainder
Here's another macro that allows you to use a 32-bit variable as the input to DIV32.
Code:
;----[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
Now, 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.
Code:
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.
Code:
;----[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
And 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 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
Code:
@ PutMulResult?D _Hours
then DIV32 that by 1000
Code:
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.
Code:
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
Code:
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
Bookmarks