Positron Compiler Documentation

Parameter as an Alias to a Global Variable or SFR

Source: Positron8 Compiler User Manual, PDF page 42

A procedure’s parameter can also use an existing global variable or microcontroller SFR (Special Function Register) as the RAM that holds its data. This is useful for accessing a procedure with speed because a global variable held in Access RAM (for an 18F devices) , or a microcontroller’s SFR may not need RAM bank switching, so will operate faster.

Proc MyProc(pValue as WREG)

The above procedure template will use the microcontroller’s WREG as the container for the name pValue.

Dim MyWord as Word
                                     ' Create a global Word variable
Proc MyProc(pValue as MyWord)  ' Use global MyWord to hold value sent to procedure

Example.

' A test procedure using two global variables as the containers for the parameters
'
  Device = 18F26K40
                                     ' Select the device to compile for
  Declare Xtal = 16 ' Tell the compiler the device will be operating at 16MHz
  Declare Hserial_Baud = 9600
                                     ' Set the Baud rate for HRsout
  Dim MyWord1 as Word
                                     ' Create a global Word variable
  Dim MyWord2 as Word
                                     ' Create a global Word variable
  Dim MyWord3 as Word
                                     ' Create a global Word variable
'
' Create a demo procedure to multiply 2 parameter values and return the result
'
  Proc TestProc(pValue1 as MyWord1, pValue2 as MyWord2), Word
     Result = pValue1 * pValue2
  EndProc
MyWord3 = TestProc(2000, 10)
                                ' Call the procedure to multiply the 2 parameters
HRsoutLn Dec MyWord3 ' Display the value held in MyWord3 (The procedure's return)

Parameter Notes

Be careful when using any of the microcontroller’s SFRs for an alias to a parameter because they are classed as volatile, and may be changed by some of the code within a procedure’s routines. Especially the WREG SFR.

Because the underlying assembler program has a limitation of 32 characters per label or variable, a Procedure's name is limited to 25 characters in length, and parameter names are limited dynamically so that their lengths are not in excess of 32 characters. A procedure parameter's name is created by using the procedure's name preceding the parameter's name, so a parameter name pParam1, of a procedure named Proc1 would be Proc1pParam1 in the Asm listing. This is within the limits of 32 characters so will not produce an error message. However, a parameter name of pMyParameter in a procedure named MyProcedureToDoSomething will produce the underlying name of ; MyProcedureToDoSomethingpMyParameter, which has a length (in characters) of 36, so will produce an error message by the compiler.

Keeping the names of the procedure and parameters makes the underlying asm produced by the compiler easier to read, however, it has its limitations, so future versions of the compiler may create pseudonyms of variable and procedure names in the asm listing, so that names in the BASIC program can be as long as required. But, this will make the underlying asm listing more difficult to follow, which is something that the compiler has always taken pride of doing. i.e. Making the Asm listing easy to follow and match with the BASIC program.

A parameter that is passed ByRef or BycRef can only ever be a Byte, Word, Long or Dword type, because it will hold the address of the variable or flash memory passed to it and not its value. This is then used by either Ptr8, Ptr16, Ptr24, or Ptr32 for RAM access, or cPtr8, cPtr16, cPtr24, or cPtr32 for flash memory, in order to manipulate the address indirectly. An example of this mechanism is shown below:

' Demonstrate a procedure for finding the length of a RAM based word array
' given a particular terminator value
'
  Device = 18F26K40
                                     ' Select the device to compile for
  Declare Xtal = 16 ' Tell the compiler the device will be operating at 16MHz
'
' USART1 declares
'
  Declare Hserial_Baud = 9600      ' UART1 Baud rate for HRsout
  Declare HRsout1_Pin = PORTC.6
                                     ' Select the pin for TX with USART1
  Dim wMyLength As Word
  Dim wMyArray[20] As Word = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,0
'---------------------------------------------------------------------------
' Find the length of a word array with a user defined terminator
' Input     : pInAddr holds the address of the word array
'           : pTerm holds the terminator value
' Output    : Returns the length of the word array up to the terminator
' Notes     : Uses indirect RAM addressing using ByRef and Ptr16
'
Proc LengthOf(ByRef pInAddr As Word, pTerm As Word), Word
  Result = 0
                                     ' Clear the result of the procedure
  Do
                                     ' Create an infinite loop
     '
     ' Increment up the array and exit the loop when the terminator is found
     '
     If Ptr16(pInAddr++) = pTerm Then Break
     Inc Result                    ' Increment the count
  Loop
      EndProc
      '---------------------------------------------------------------------------
      Main:
      '
      ' Find the length of a null terminated word array
      '
         wMyLength = LengthOf(wMyArray, 0)
         HRsoutLn Dec wMyLength
                                    ' Display the result on a serial terminal