News:

Let's find out together what makes a PIC Tick!

Main Menu

Procedure: Result or not result?

Started by AlbertoFS, Jun 28, 2023, 02:54 PM

Previous topic - Next topic

AlbertoFS

Hi all,
I'm posting a lot of code these past few weeks. And I have realized that something is missing in the Positron Procedure.
To give an example, I am trying to emulate the LookUp or LookDown command with data written to RAM.
(simple exercise to play). This difficulty has been repeated several times writing code for expanders.

First example: Procedure LookUpRAM()

    Dim TableNumbers[11] As Byte = 10,20,30,40,50,60,70,80,90,100,0
    Dim xxFSR0 As FSR0L.Word
    Dim xxFSR1 As FSR1L.Word

Proc LookUpRAM(ByRef pArrayIn As xxFSR0, pIndex As PRODL),Byte
    #ifdef watchdog_req
    Clrwdt
    #endif
    xxFSR1 = xxFSR0 + PRODL
    '/--------------------------------------------------------------------------
    Do
        If POSTINC0 = 0 Then Break  '/ Check array until final 0.
    Loop   
    xxFSR0 = xxFSR0 - 2
    '/--------------------------------------------------------------------------
    If xxFSR1 > xxFSR0 Then         '/ If index is not correct then exit
        ExitProc                    '/ Error then return nothing???
    EndIf
    Result = INDF1
EndProc
I had liked being able to perform the same function as the standard LookUp command. When the pIndex variable is out of range, the return variable should not be modified.
In the case of procedure, it is always performed: ReturnVar = LookUpRAMResult.

In this example the Result variable has not been loaded with any value, but the procedure does the following:
ReturnVar = 0. Which modifies the return variable.

In the following example, which is identical code but done in an asm macro, everything works perfectly because I can do what I want. It is more versatile.

Second example:
    Dim xxIndex As Byte
    Dim xxResult As Byte
    Dim xxF_EnableReturnVar As Bit

mLookUpRAM Macro pArrayIn, pIndex
#if (Prm_Count != 2)         
#error "Incorrect amount of parameters for mLookUpRAM macro. 2 Parameters required!"
Exitm
#else
    #if (Prm_Count < 1)
        #error "mLookUpRAM - Too few parameters"
        Exitm
    #else
        #if (Prm_1 == Byte_Array_Ptr) || (Prm_1 == String)
            Num_FSR0 pArrayIn
        #endif 
        #if (Prm_2 == Byte)
            Byte_Byte pIndex, xxIndex
        #else
            #if (Prm_1 == Num8)
                Num_Byte pIndex, xxIndex
            #endif
        #endif
        GoSub mLookUpRAM_Sub
        If xxF_EnableReturnVar = 1 Then
            #if (Return_Type == Byte)
                Byte_Byte xxResult, Return_Var
            #endif
        EndIf
    #endif
#endif       
Endm

#ifMacro mLookUpRAM       
mLookUpRAM_Sub:
    #ifdef watchdog_req
    Clrwdt
    #endif
    xxFSR1 = xxFSR0 + xxIndex
    '/--------------------------------------------------------------------------
    Do
        If POSTINC0 = 0 Then Break  '/ Check array until final 0.
    Loop   
    xxFSR0 = xxFSR0 - 2
    '/--------------------------------------------------------------------------
    If xxFSR1 > xxFSR0 Then         '/ If index is incorrect then exit
        xxF_EnableReturnVar = 0     '/ Disable ReturnVar
        Return                      '/ error then NO return_Var
    EndIf
    '/--------------------------------------------------------------------------
    xxResult = INDF1
    xxF_EnableReturnVar = 1         '/ Enable Return_Var
    Return
#endIfMacro
A trick can be used, feeding back the ReturnVar variable as input.
For example:
$define LookUpRAM(pArrayIn, pIndex, pResult)    '
pResult = pLookUpRAM(pArrayIn, pIndex, pResult)

Proc pLookUpRAM(ByRef pArrayIn As xxFSR0, pIndex As PRODL, pResult As PRODH),Byte
    #ifdef watchdog_req
    Clrwdt
    #endif
    Result = PRODH
    xxFSR1 = xxFSR0 + PRODL
    '/--------------------------------------------------------------------------
    Do
        If POSTINC0 = 0 Then Break  '/ Check array until final 0.
    Loop   
    xxFSR0 = xxFSR0 - 2
    '/--------------------------------------------------------------------------
    If xxFSR1 > xxFSR0 Then         '/ If index is not correct then exit
        ExitProc                    '/ Error then return nothing???
    EndIf
    Result = INDF1
EndProc
This case works fine, but it's not as efficient as I wanted.

Conclusion:
Would it be possible to create a new command inside the Procedure, to override the line: ReturnVar = LookUpRAMResult?
If this command is executed then this line would not be written, such as an "ExitProcNull" command, for example.

It is a subject for discussion.
Sorry by English, using a translator.

Regards
73's de EA3AGV

top204

#1
Hello Alberto.

Excellent code, and it is so good to see someone understanding and using the compiler so intimately. :-)

I'm not quite sure of your request, but remember, the Result variable is not reset upon a procedure's entry, so the last Result value will still be in the variable when the procedure is called again. Which means that with an early return from a procedure, the Result variable will still contain its last value. It is very important to reset the Result variable when a procedure first starts if the procedure has early returns in it, or give the Result a value before the early return. It has caught me out a few times as well, so I now give the Result variable a default value when the procedure is first entered, so it will return with a value that is not the previous value. :-)

As a spin off of the procedure mechanism that I invented for the once flat language, a ByVal parameter can also be used as the procedure's return variable. For example:

Proc MyProc(pParam1 As Byte, pParam2 As Word), pParam2

See how the Result variable is also the variable used for pParam2? And these can also be alias' to other SFRs or variables used as a parameter:

Proc MyProc(pParam1 As PRODL, pParam2 As Word), pParam1

It is something I did not plan in the procedure mechanism, but comes in handy sometimes. :-)