code did not compile correctly - if portb.0

2013-04-14
2013-05-30
  • Jim giordano
    Jim giordano
    2013-04-14

    The following code

      if portb.0 <> tmp then
        portb.0 = tmp
      end if
    

    compiled as

    ;if portb.0 <> tmp then
        movf    TMP,W
        subwf   PORTB.0,W                    '**********
        btfsc   STATUS, Z
        goto    ENDIF1
    ;portb.0 = tmp
        bcf PORTB,0
        movf    TMP,F
        btfss   STATUS,Z
        bsf PORTB,0
    ;end if
    ENDIF1
    

    The assembler was not happy with PORT.0 on the subwf line


    Also,  I only discovered this because the following line-

    if portb.0 <> portb.4 then portb.0 = portb.4
    

    would always clear portb.0 before setting it to portb.4 even if it was already on and was supposed to be set on, which really had me confused for quite a while.
    resulting code:

    ;if portb.0 <> portb.4 then portb.0 = portb.4
        clrw
        btfsc   PORTB,0
        xorlw   255
        btfsc   PORTB,4
        xorlw   255
        btfss   STATUS,Z
        goto    ENDIF1
        bcf PORTB,0
        btfsc   PORTB,4
        bsf PORTB,0
    ENDIF1
    
     
  • Jim giordano
    Jim giordano
    2013-04-14

    I'm sure it's here somewhere, but I couldn't find the edit button to fix the typos in my post.  so….

    the line -   "The assembler was not happy with PORT.0 on the subwf line"
    should have read The MPASM v5.49 assembler was not happy with PORTB.0 on the subwf line

     

  • Anonymous
    2013-04-15

    Hi ,

    try this

    varA=portb.0
    if varA <> tmp then portb.0 =tmp
    

    and your next piece of code could be written like this:

    varA=portb.0
    varB=portb.4
    if varA <> varB then portb.0 =varB
    
     
  • It appears you are comparing a bit to a byte and
    it appears the compiler is treating portb.0 as a byte since it's being compared to a byte variable tmp.
    PORTB.0 isn't a register the compiler recognizes so it kicks it out.
    Since it appears that you are testing if the the variable temp is empty,
    Try it this way:

    If tmp = 0 then
    portb.0 = 0
    else
    portb.0 = 1
    endif

    Or
    declare tmp as a bit variable and then see if it fixes the problem.

     
  • Jim giordano
    Jim giordano
    2013-04-15

    Well, yes, both methods will probably work, and I did what I wanted with even a third method, but…

    I was just reporting a compiler bug that I thought should be fixed. 

     
  • Jim giordano
    Jim giordano
    2013-04-15

    Also, apologies for posting in the wrong section of the forum, I see now this is the graphical section.  Oops.

     
  • I believe you did find a bug in the command line: if portb.0 <> portb.4 then portb.0 = portb.4.
    I don't believe it works properly at all.
    I believe the
    btfss STATUS,Z
    should be replaced by
    btfsc STATUS,Z

    Here is my summary, in case someone can find an error in my conclusion, I think this minor change will fix the bug you found.

    ************************************* Current Execution with btfss STATUS,Z  ***********************************

    ----- portb.0 = 0, portb.4 = 0 ---------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;clear so skip next line
    xorlw 255
    btfsc PORTB,4 ;clear so skip next line
    xorlw 255
    btfss STATUS,Z ;Z = 1 so skip next line
    goto ENDIF1
    bcf PORTB,0 ;portb.0 = 0
    btfsc PORTB,4 ;portb.4 = 0 so skip next line
    bsf PORTB,0
    ENDIF1

    Result: portb.0 = 0, portb.4 = 0
    Issue: None

    ------- portb.0 = 1, portb.4 = 1 -------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;not clear so next line
    xorlw 255 ;w = 255
    btfsc PORTB,4 ;not clear so next line
    xorlw 255 ;w = 0
    btfss STATUS,Z ;Z = 1 so skip next line
    goto ENDIF1
    bcf PORTB,0 ;clear portb.0
    btfsc PORTB,4 ;not clear so next line
    bsf PORTB,0 ;set portb.0
    ENDIF1

    Result: portb.0 = 1, portb,4 = 1
    Issue: portb.0 glitches 1-0-1 for one clock cycle.

    ----- portb.0 = 0, portb.4 = 1 ----------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;clear skip next line
    xorlw 255
    btfsc PORTB,4 ;not clear so next line
    xorlw 255 ;w = 255
    btfss STATUS,Z ;Z = 0 so next line
    goto ENDIF1
    bcf PORTB,0
    btfsc PORTB,4
    bsf PORTB,0
    ENDIF1

    Result: portb.0 = 0, portb.4 = 1
    Issue: Since they are unequal, portb.0 should be set to one to match portb.4

    ----- portb.0 = 1, portb.4 = 0 ---------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;not clear so next line
    xorlw 255 ;w = 255
    btfsc PORTB,4 ;clear so skip next line
    xorlw 255
    btfss STATUS,Z ;Z = 0 so next line
    goto ENDIF1
    bcf PORTB,0
    btfsc PORTB,4
    bsf PORTB,0
    ENDIF1

    Result: portb.0 = 1, portb.4 = 0
    Issue: Since they are unequal, portb.0 should be set to zero.

    ************************************* Fix: Replace btfss STATUS,Z with btfsc STATUS,Z ***********************************

    ----- portb.0 = 0, portb.4 = 0 ---------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;clear so skip next line
    xorlw 255
    btfsc PORTB,4 ;clear so skip next line
    xorlw 255
    btfsc STATUS,Z ;Z = 1 so next line
    goto ENDIF1
    bcf PORTB,0
    btfsc PORTB,4
    bsf PORTB,0
    ENDIF1

    Result: portb.0 = 0, portb.4 = 0
    Issue: None

    ------- portb.0 = 1, portb.4 = 1 -------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;not clear so next line
    xorlw 255 ;w = 255
    btfsc PORTB,4 ;not clear so next line
    xorlw 255 ;w = 0
    btfsc STATUS,Z ;Z = 1 so next line
    goto ENDIF1
    bcf PORTB,0
    btfsc PORTB,4
    bsf PORTB,0
    ENDIF1

    Result: portb.0 = 1, portb,4 = 1
    Issue: none

    ----- portb.0 = 0, portb.4 = 1 ----------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;clear skip next line
    xorlw 255
    btfsc PORTB,4 ;not clear so next line
    xorlw 255 ;w = 255
    btfsc STATUS,Z ;Z = 0 so skip next line
    goto ENDIF1
    bcf PORTB,0 ;portb.0 = 0
    btfsc PORTB,4 ;portb.4 = 1 so next line
    bsf PORTB,0 ;portb.0 = 1
    ENDIF1

    Result: portb.0 = 1, portb.4 = 1
    Issue: none

    ----- portb.0 = 1, portb.4 = 0 ---------

    ;if portb.0 <> portb.4 then portb.0 = portb.4
    clrw ;w = 0
    btfsc PORTB,0 ;not clear so next line
    xorlw 255 ;w = 255
    btfsc PORTB,4 ;clear so skip next line
    xorlw 255
    btfsc STATUS,Z ;Z = 0 so skip next line
    goto ENDIF1
    bcf PORTB,0 ;portb.0 = 0
    btfsc PORTB,4 ;portb.4 = 1 so skip next line
    bsf PORTB,0
    ENDIF1

    Result: portb.0 = 0, portb.4 = 0
    Issue: none

     
  • Does anybody know where this source code is within GCB?
    I'd like to read it over to understand where this is generated.
    I also sent an email to Hugh pointing out this potential bug for his expert view on this.

     
  • Hugh Considine
    Hugh Considine
    2013-04-21

    I've made a few changes to GCBASIC that should fix these problems. Please download the update from http://gcbasic.sourceforge.net/update.html and let me know if that helps!

    The problem was in the CompileConditions subroutine, which is inside gcbasic.bas.

     
  • Max
    Max
    2013-04-21

    When i try to dezip update.zip i got always HEADER CORRUPTED.
    The zip file size on disk is 3,45 MB (3.620.864 byte)

    PS: GCB i wordefull program :)

     
  • Jim giordano
    Jim giordano
    2013-04-30

    Sorry I took so long to get back.  The new update.zip change works for me.  Thanks much.