32-bit Variables and DIV32, Hourmeter 99999.9


Results 1 to 10 of 10

Threaded View

  1. #1
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default 32-bit Variables and DIV32, Hourmeter 99999.9

    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
    Last edited by Darrel Taylor; - 28th July 2005 at 10:34.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts