Announcement

Collapse
No announcement yet.

USERCOMMAND (Introduction - Start Here)

Collapse
This topic is closed.
X
This is a sticky topic.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Darrel Taylor
    replied
    Adding a command to the module

    Each .pbpmod (module file) can have multiple commands in them.
    In this case, we'll add a DECR (decrement) command to go along with INCR (increment).

    Essentially, you just duplicate the INCR command and modify it to do a decrement.

    Add the USERCOMMAND line, create the basic subroutine ...
    Code:
    GOTO Over_INCR                  ; Jump over the code
    
    USERCOMMAND "INCR"              ; Create a command called INCR
    USERCOMMAND "DECR"              ; Create a command called DECR
    
    #IF __LONG__ = 1                ; if using LONG version of PBP
      TempVar VAR LONG              ;  Tempvar is a LONG
    #ELSE
      TempVar VAR WORD              ;  otherwise it's a WORD
    #ENDIF
    
    ;----[Main Code - Called by the macros]-------------------------------------
    Increment:
        TempVar = TempVar + 1 
    RETURN
    
    Decrement:
        TempVar = TempVar - 1
    RETURN
    ... and create the interface macros.
    Code:
    ASM
    ;----[Decrement a Byte]-----------------------------------------------------
    DECR?B  macro Bin
        MOVE?BB  Bin, _TempVar      ; copy user var to TempVar
        L?CALL   _Decrement         ; run the decrement subroutine
        MOVE?BB  _TempVar, Bin      ; copy result back to user var
      endm
    
    ;----[Decrement a Word]-----------------------------------------------------
    DECR?W  macro Win
        MOVE?WW  Win, _TempVar      ; copy user var to TempVar
        L?CALL   _Decrement         ; run the decrement subroutine
        MOVE?WW  _TempVar, Win      ; copy result back to user var
      endm
    
    ;----[Decrement a Long]-----------------------------------------------------
    DECR?N  macro Nin
        MOVE?NN  Nin, _TempVar      ; copy user var to TempVar
        L?CALL   _Decrement         ; run the decrement subroutine
        MOVE?NN  _TempVar, Nin      ; copy result back to user var
      endm
    
    ;----[Constant]-------------------------------------------------------------
    DECR?C  macro Cin
        ERROR You cannot decrement a constant
      endm
    
    ;----[String]---------------------------------------------------------------
    DECR?S  macro Cin
        ERROR You cannot decrement a String
      endm
    
    ;----[Label]----------------------------------------------------------------
    DECR?L  macro Cin
        ERROR You cannot decrement a Label
      endm
    
    ;----[Bit]------------------------------------------------------------------
    DECR?T  macro Regin, Bitin
        ERROR Decrementing a BIT is not supported 
      endm
    
    ENDASM
    And now you have a complete module file with two new commands.
    To use it, just INCLUDE the module, and the new commands are available.
    Code:
    INCLUDE "INCR_DECR.pbpmod"
    Attached Files
    Last edited by Darrel Taylor; 12-20-2011, 02:32 PM.

    Leave a comment:


  • Darrel Taylor
    replied
    Making it "Complete"

    Although the above example will work with Bytes and Words, to be fully compatible with PBP3 it also needs to accept LONGs.

    You can add another macro for the longs, but the TempVar variable has to be changed to a LONG as well. However, if you are using the 16-bit version of PBP, the LONG variable would cause an error.
    So you need to use some "Conditional Compiling" to let PBP decide what size the variable should be.

    Code:
    #IF __LONG__ = 1             ; if using LONGs
        TempVar VAR LONG         ;  Tempvar is also a LONG
    #ELSE
        TempVar VAR WORD         ;  otherwise it's a WORD
    #ENDIF
    When you use the LONG version, the temp variable will be a LONG so that all variable types will work.

    Then add a macro for LONG vars.
    Code:
    ;----[Increment a Long]-----------------------------------------------------
    INCR?N  macro Nin
        MOVE?NN  Nin, _TempVar   ; copy user var to TempVar
        L?CALL   _Increment      ; run the increment subroutine
        MOVE?NN  _TempVar, Nin   ; copy result back to user var
      endm
    To be "Complete", adding macros for the unsupported types is preferred. This will give meaningful errors that make it easier to debug.

    Code:
    ;----[Constant]-------------------------------------------------------------
    INCR?C  macro Cin
        ERROR You cannot increment a constant
      endm
    
    ;----[String]---------------------------------------------------------------
    INCR?S  macro Cin
        ERROR You cannot increment a String
      endm
    
    ;----[Label]----------------------------------------------------------------
    INCR?L  macro Cin
        ERROR You cannot increment a Label
      endm
    
    ;----[Bit]------------------------------------------------------------------
    INCR?T  macro Regin, Bitin
        ERROR You cannot increment a Bit
      endm
    And finally, these routines should all be placed in a separate "Module" file so they can be easily included in any PBP3 programs.

    As with any include file, the routines should be jumped over with a GOTO so that execution doesn't accidentally "Fall Into" the code.
    Putting it all together, here's what the module file looks like.
    Code:
    ' Name        : INCR.pbpmod
    ' Compiler    : PICBASIC PRO Compiler 3.0
    ' Target PIC  : Any
    ' Hardware    : Any
    ' Oscillator  : Any
    ' Keywords    : USERCOMMAND
    ' Description : PICBASIC PRO module to Increment a variable
    '____________________________________________________________________________
    
    GOTO Over_INCR               ; Jump over the code
    
    USERCOMMAND "INCR"           ; Create a command called INCR
    
    #IF __LONG__ = 1             ; if using LONG version of PBP
      TempVar VAR LONG           ;  Tempvar is a LONG
    #ELSE
      TempVar VAR WORD           ;  otherwise it's a WORD
    #ENDIF
    
    ;----[Main Code - Called by the macros]-------------------------------------
    Increment:
        TempVar = TempVar + 1 
    RETURN
    
    ASM
    ;----[Increment a Byte]-----------------------------------------------------
    INCR?B  macro Bin
        MOVE?BB  Bin, _TempVar   ; copy user var to TempVar
        L?CALL   _Increment      ; run the increment subroutine
        MOVE?BB  _TempVar, Bin   ; copy result back to user var
      endm
    
    ;----[Increment a Word]-----------------------------------------------------
    INCR?W  macro Win
        MOVE?WW  Win, _TempVar   ; copy user var to TempVar
        L?CALL   _Increment      ; run the increment subroutine
        MOVE?WW  _TempVar, Win   ; copy result back to user var
      endm
    
    ;----[Increment a Long]-----------------------------------------------------
    INCR?N  macro Nin
        MOVE?NN  Nin, _TempVar   ; copy user var to TempVar
        L?CALL   _Increment      ; run the increment subroutine
        MOVE?NN  _TempVar, Nin   ; copy result back to user var
      endm
    
    ;----[Constant]-------------------------------------------------------------
    INCR?C  macro Cin
        ERROR You cannot increment a constant
      endm
    
    ;----[String]---------------------------------------------------------------
    INCR?S  macro Cin
        ERROR You cannot increment a String
      endm
    
    ;----[Label]----------------------------------------------------------------
    INCR?L  macro Cin
        ERROR You cannot increment a Label
      endm
    
    ;----[Bit]------------------------------------------------------------------
    INCR?T  macro Regin, Bitin
        ERROR Incrementing a BIT is not supported 
      endm
    
    ENDASM
    
    Over_INCR:

    Leave a comment:


  • Darrel Taylor
    replied
    Writing the macros

    There are two different ways to approach writing the macros.

    1) The easiest method is to write a common subroutine in Basic Language, then just use the macros to pass the parameters to/from that subroutine.

    2) The most efficient method is to write the macro's in straight Assembly Language. But it's also the hardest.

    Let's look at the easy way first.
    The INCR command is going to simply increment a variable, so we'll write a Basic Language routine that accomplishes that. In this case it's pretty simple.
    Code:
    TempVar VAR WORD
    
    Increment:
        TempVar = TempVar + 1 
    RETURN
    Then the macros copy the parameter to the Temp Variable, run the subroutine and finally copy the result back to the parameter variable, which looks like this ...
    Code:
    ASM
    ;----[Increment a Byte]-----------------------------------------------------
    INCR?B  macro Bin
        MOVE?BB  Bin, _TempVar   ; copy user var to TempVar
        L?CALL   _Increment      ; run the increment subroutine
        MOVE?BB  _TempVar, Bin   ; copy result back to user var
      endm
    
    ;----[Increment a Word]-----------------------------------------------------
    INCR?W  macro Win
        MOVE?WW  Win, _TempVar   ; copy user var to TempVar
        L?CALL   _Increment      ; run the increment subroutine
        MOVE?WW  _TempVar, Win   ; copy result back to user var
      endm
    ENDASM
    The MOVE? macros are part of PBP and will copy variables or constants to other variables. They handle all the bank switching required to access the variables, making it much easier than using straight ASM. We'll talk about them in the Assembly Language forum later.
    L?CALL is another PBP macro that is identical to GOSUB in Basic.

    ----------------------------------------------------------------------------

    Now you have a New Working command in PBP3.
    You can use it in your program like any other command.
    Code:
    Counter  VAR WORD
    
    Main:
        INCR Counter
        HSEROUT [DEC Counter,13,10]
        PAUSE 100
    GOTO Main

    Leave a comment:


  • Darrel Taylor
    replied
    Creating a command

    The USERCOMMAND statement tells PBP the "Name" of the new command.
    All of the usual rules apply ... it must start with a letter, be less than 32 characters and the only special character allowed is the underscore.

    By itself, the USERCOMMAND statement does nothing more than assign a name.
    It is not executable, it does not do anything at run-time.
    It only has an affect during the compile process.

    The command looks like this.
    Notice that the name is in quotes ...
    Code:
    USERCOMMAND "INCR"
    PBP will now recognize INCR (short for Increment) as a new command, although neither MicroCode Studio or MPLAB will highlight it.

    When you use the command in your program, the compiler determines which macro to call according to the parameters specified in the command.

    For instance, if you use INCR with a BYTE variable, it will call the INCR?B macro. Or with a WORD variable, it will use INCR?W.
    Here are the possibilities for parameter types.

    B = BYTE
    C = Constant
    L = Label
    N = LONG
    S = String
    T = BIT
    W = WORD

    A macro must be written for each possiblity of parameters.

    Leave a comment:


  • Darrel Taylor
    started a topic USERCOMMAND (Introduction - Start Here)

    USERCOMMAND (Introduction - Start Here)

    USERCOMMAND's are a new feature of PBP3.
    A recent update (PBP 3.0.4.x) fixed some issues with the way USERCOMMAND and #DEFINE work, which makes it possible to now create your own commands for PBP3.

    These commands will act much like the built-in commands that we are all familiar with.
    There are no @ signs, you can pass parameters with different variable types and the compiler will decide which macros to call.

    Yes, I said "macros". Which means "Assembly Language".
    Although you are creating PBP commands, it's done with assembly language macros.
    I don't expect too many people to jump on the bandwagon for that reason, but I hope some of you do because I believe this will unlock an incredable amount of power that I'm pretty excited about.

    New commands, new complete modules, modules that use other modules.
    This is going to be so cool.

    I'll try to explain how it works in the following posts and threads, but before you start ...
    Make sure you have installed the latest version of PBP3 (3.0.4.x or higher).
    The update is free for all users of PBP3.
    http://pbp3.com/downloadtrial
Working...
X