Syntax

' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Demonstrates GOSUB with parameter passing across page boundaries. Note
' that the GOSUB keyword is no longer required when using version 1.2
' syntax (SUB definition).  Note, too, that the INVERT8 function returns
' an 8-bit value even when a 16-bit (word) is passed as a parameter.

' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ            4_000_000
ID              "GOSUB"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

LEDs            VAR     RB
TRIS_LEDs       VAR     TRIS_B

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

Speed           CON     100                     ' loop delay control

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

zigzag          VAR     Byte                    ' zigzag controller
tmpW1           VAR     Word                    ' subroutine work var

' =========================================================================
  PROGRAM Start
' =========================================================================

' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

DELAY           SUB     1, 2                    ' delay in milliseconds
INVERT8         FUNC    1, 1, 2                 ' invert bits in byte
INVERT16        FUNC    2, 1, 2                 ' invert bits in word

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  TRIS_LEDs = %00000000                         ' make LEDs pins outputs

Main:
  zigzag = %00000011
  DO
    LEDs = INVERT8 zigzag                       ' invert LED pattern
    DELAY Speed                                 ' loop delay
    zigzag = zigzag << 1                        ' shift bit left
  LOOP UNTIL zigzag = %10000000

  zigzag = %10000000
  DO
    LEDs = INVERT8 zigzag
    DELAY Speed
    zigzag = zigzag >> 1                        ' shift bit right
  LOOP UNTIL zigzag = %00000001

  GOTO Main

' -------------------------------------------------------------------------
' Subroutines Code
' -------------------------------------------------------------------------

' Use: DELAY ms
' -- 'ms' is delay in milliseconds, 1 - 65535

DELAY:
  IF __PARAMCNT = 1 THEN
    tmpW1 = __PARAM1                            ' save byte value
  ELSE
    tmpW1 = __WPARAM12                          ' save word value
  ENDIF
  PAUSE tmpW1
  RETURN

' -------------------------------------------------------------------------

' Use: aVar = INVERT theByte
' -- inverts the bits in 'theByte'
' -- returns 8-bit value, even if 'theByte' is a word (returns inverted LSB)

INVERT8:
  tmpW1_LSB = __PARAM1                          ' get current value
  tmpW1_LSB = ~tmpW1_LSB                        ' invert the bits
  RETURN tmpW1_LSB                              ' return byte to caller

' -------------------------------------------------------------------------

' Use: aVar = INVERT theWord
' -- inverts the bits in 'theWord'
' -- returns 16-bit value, even if 'theWord' is a byte

INVERT16:
  IF __PARAMCNT = 1 THEN
    tmpW1 = __PARAM1                            ' convert byte to word
  ELSE
    tmpW1 = __WPARAM12                          ' save word value
  ENDIF
  tmpW1 = ~tmpW1                                ' invert the bits
  RETURN tmpW1                                  ' return word to caller

The following example demonstrates the ability to return more than two bytes from a function:

' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Demonstrates the use of a function and a method for collecting all
' returned bytes when simple (non-array) variables are used.

' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ            4_000_000
ID              "FUNC"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

result          VAR     Word                    ' 32-bit result
resultHi        VAR     Word
bigVal          VAR     Byte(4)

tmpW1           VAR     Word                    ' subroutine work vars
tmpW2           VAR     Word
tmpW3           VAR     Word

WATCH result, 32, UHEX                          ' display 32-bit result
WATCH bigVal, 32, UHEX

' =========================================================================
  PROGRAM Start
' =========================================================================

' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

MULT32          FUNC    4, 2, 4
BREAK_NOW       SUB     0

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  result = MULT32 $FFFF, $0100                  ' get low word
  resultHi = __PARAM3, __PARAM4                 ' get high word
  BREAK_NOW

  bigVal = MULT32 $1234, $10                    ' all return bytes assigned
  BREAK_NOW

  END

' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------

' Use: MULT32 value1, value2
' -- multiplies two values
' -- when mixing a word and byte, the word must be declared first

MULT32:
  IF __PARAMCNT = 2 THEN                        ' byte * byte
    tmpW1 = __PARAM1
    tmpW2 = __PARAM2
  ENDIF
  IF __PARAMCNT = 3 THEN                        ' word * byte
    tmpW1 = __WPARAM12
    tmpW2 = __PARAM3
  ENDIF
  IF __PARAMCNT = 4 THEN                        ' word * word
    tmpW1 = __WPARAM12
    tmpW2 = __WPARAM34
  ENDIF
  tmpW3 = tmpW1 ** tmpW2                        ' calculate high word
  tmpW2 = tmpW1 * tmpW2                         ' calculate low word
  RETURN tmpW2, tmpW3                           ' return 32 bits, LSW first

' -------------------------------------------------------------------------

' Allows multiple breakpoints in program.

BREAK_NOW:
  BREAK
  RETURN