Announcement

Collapse
No announcement yet.

Assembly code insert for PBP

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Assembly code insert for PBP

    I am considering inserting some assembly code into a PBP program for the first time. I know the best way to learn is to just do it. Unfortunately, I know that calling assembly code from a higher level language can be tricky and my debugging resources are limited to using the PIC serial port to send select variable values to a terminal program running on my PC. I don't want to spend a lot of time with that method just to learn about basic stuff that probably you guys on the forum know right off.

    If someone can review my following example and let me know if it has a chance of success or what's not right with it, I would much appreciate that.

    So I have a PBP program to start, with three variables defined. Two variables I want to multiply using the fast, hardware multiplier in the PIC (VarA and VarB). The third variable is the result of the multiplication, (Result). I want to do this because the hardware multiplier is very fast and I have many of these multiplies to do in nested loops. All numbers are unsigned, positive.

    VarA var byte
    VarB var byte
    Result var word

    Next I have the assy code which I have done the best I can with, without testing, and without ever programming a PIC in assy language before -- just reading stuff. (Ignore the dots. I put them there just to make it more readable.)

    ASM ' (PBP statement)
    movf........_VarA, w
    mulwf ....._VarB ;mult A and B
    movf........PRODL, w
    movwf....._Result.BYTE0 ;put low byte in Result
    movf........PRODH, w
    movwf....._Result.BYTE1 ;put high byte in Result
    ENDASM ' (PBP statement)


    One thing I can't determine is if I can just insert this ASM code block anywhere in the PBP program and it will execute in sequence like ordinary PBP statements, or do I have to call it like a subroutine when I need it and place the code block at the beginning of the PBP program.

    Another question I have is if the .BYTE modifier will work in an ASM block, or do I have to store to separate byte variables and combine them in the PBP program.

    Also should that ASM code block work? Is there anything that looks wrong? Thanks.
    Last edited by Chuck Curtis; 04-23-2019, 05:45 PM. Reason: Added that the numbers are unsigned.

  • #2
    One thing I can't determine is if I can just insert this ASM code block anywhere in the PBP program and it will execute in sequence like ordinary PBP statements, or do I have to call it like a subroutine when I need it and place the code block at the beginning of the PBP program
    it can be done either way ,

    inline
    Code:
    asm
    code...
    banksel 0
    endasm
    as as subroutine

    Code:
    myasm:
    asm
    code...
    banlsel 0
    return
    end asm


    Another question I have is if the .BYTE modifier will work in an ASM block, or do I have to store to separate byte variables and combine them in the PBP program.
    no
    Code:
    banksel _result
    movwf....._Result put low byte in Result
    banksel _PRODH
    movf........PRODH, w
    movwf....._Result+1  ;put high byte in Result

    closer to whats required {untested}
    Code:
    ASM ' (PBP statement)
    banksel _VarA
    movf........_VarA, w
    banksel _VarB
    mulwf ....._VarB ;mult A and B
    banksel PRODL,; not really needed pic18
    movf........PRODL, w
    banksel  _Result
    movwf....._Result ;put low byte in Result
    banksel PRODL,; not really needed pic18
    movf........PRODH, w
    banksel  _Result
    movwf....._Result+1;put high byte in Result
    banksel 0
    ENDASM ' (PBP statement)

    a much easier way USING PBP'S MACROS
    Code:
    ASM ' (PBP statement)
    MOVE?BA  _VarA
    banksel _VarB
    mulwf ....._VarB ;mult A and B
    MOVE?WW PRODL, _Result
    banksel 0
    ENDASM ' (PBP statement)
    Last edited by richard; 04-23-2019, 07:43 PM. Reason: banksel not needed pic18

    Comment


    • #3
      Thanks you, Richard! I like that easier way. I have a few questions on that one, if you don't mind.

      1. There is a banksel for VarB, but not VarA. Why not for both?
      2. I see PRODL getting moved into Result, but not PRODH. I assume the MOVE?WW macro is handling the PRODH part too?
      3. I remember the PBP manual mentioning being careful with RAM banks. So I guess that's why it ends with banksel 0?

      Comment


      • #4
        1. There is a banksel for VarB, but not VarA. Why not for both?
        The pbp macro does the bank switching for you, there is no way to be sure vara and varb are in the same bank unless you declare them that way

        2. I see PRODL getting moved into Result, but not PRODH. I assume the MOVE?WW macro is handling the PRODH part too?
        yes The WW part means word vars , i'm assuming prodh equ prodl+1 {have not checked data sheet}

        3. I remember the PBP manual mentioning being careful with RAM banks. So I guess that's why it ends with banksel 0?
        the book says to return from asm routines with banksel=0
        you could use RST?RP , but i came unstuck doing that once, never established the reason ,i don't use it any longer because i had difficulty finding the macro's definition
        i do know where its defined now but have never gone back to the problem to solve it.

        Comment


        • #5
          I tried the group of code in the middle of the three groups and it worked perfectly the first time (I excluded the not necessary for PIC18 lines). I intend to try the easier (last) group too when I have time later.

          Unfortunately, it didn't speed things up much, but it did help a little. I guess WORD length additions are taking the most time since, other than compares in IF statements and the multiplies, that is all the more there is in my loops. The multiplies are obviously not the main time consumer I assumed they were. I am using PBP in W(ord) mode.

          But, I did do in-line assy code for the first time, and that is worth a lot to me. Thanks again, Richard.

          Comment


          • #6
            A few notes on using ASM in PBP. First, when you know you will be using a variable in ASM, try this:
            Code:
            VarA  VAR  BYTE [B]SYSTEM[/B]
            When you reference it in ASM you simply refer to "VarA" instead of "_VarA". Second:
            Code:
            VarA VAR BYTE [B]BANKA [/B]SYSTEM
            This places the variable VarA in the Access Bank. Doing this means you don't have to use BANKSEL VarA. Hope this helps.
            We can crack this cotton PIC'n thang!

            Comment


            • #7
              Indeed, that is helpful, mpgmike. In the case of including BANKA in the variable declaration, should I still use banksel 0 at the end before ENDASM, or can that be left out too?

              Comment


              • #8
                The BANKA Declaration places the variable in an address in the ACCESS BANK. The Access Bank is accessible from any bank without using MOVLB or BANKSEL commands. The INTCON, W, STATUS and FSROL Registers are a few examples of SFRs located in ACCESS. You might want to read Microchip's MPASM User's Guide. If you download and install MPLABX (currently v5.15), you get the Guide in C:\\(X86)\Microchip\MPLABX\Documents folder. There are things built into ASM beyond what is listed in the Data Sheets. As for PBP ASM Macros, I'm not aware of any official documentation outlining its use. Guys that know how to exploit them learned by writing code in PBP then filtering through the .LST and .ASM files.
                We can crack this cotton PIC'n thang!

                Comment

                Working...
                X