Menu

True constant with Bit variables doesn't work as expected

Nivek
2018-09-26
2018-10-20
  • Nivek

    Nivek - 2018-09-26

    Hello everybody,

    I am a new user to GCB and found a little issue with bit variables and the True constant:

    Version GCB 13/05/2018:v0.98.02

    Using the predefined constant True causes problem when doing comparisions with bit variables

    From help file (Constants topic)
    Great Cow BASIC Pre-defined constants are:

    #define ON 1
    #define OFF 0
    #define TRUE 255
    #define FALSE 0
    

    It's not a problem to assign a bit variable = False because the compiler correctly clears it (since False is defined as 0)
    Basic/Asm:

    ;some_bit_var = False  
        bcf SYSBITVAR0,0
    

    It's OK to set a bit variable = True because the compiler sets it fine.

    ;some_bit_var = True
        bsf SYSBITVAR0,0
    

    It's also not a problem to compare bit variables to False, this works as if the bit variable was compared to 0.

    However, using True with bit variables does not work same as 1.
    True is defined as 255 and doing a comparision on a bit variable like
    If some_bit_var = True then goto it_was_true
    does not execute correctly. My PIC assembler skills are rusty since it's been a long time but it looks like the compiler is doing something other than a straight 0/1 compare - maybe 255?

    The ideal thing would be if True for bit variables would be treated as 1, similar to how False = 0.
    Maybe False = 0, anything non-zero = True for bit compares?

    Workarounds:
    For bit variables, use ON or OFF which are predefined constants 1 and 0 respectively.
    Compare bit variables to False, not True? (invert your logic test)

    I would appreciate comments from someone more experienced than me with GCB/compiler internals, and if I am correct with the above.

    GCB is really fantastic and thanks to the developers, I am sure it will get even better with time.
    By the way, I would be interested in helping with documentation for GCB.
    Oh, and GCB could use a TOGGLE command to easily flip an output pin.

    Thanks
    Kevin.

     
  • Chris Roper

    Chris Roper - 2018-09-26

    Hi Kevin,

    Welcome to Great Cow BASIC I am glad you are enjoying your explorations.

    Take a look here http://gcbasic.sourceforge.net/help/_setwith.html

    a quick excerpt:

    SetWith
    Syntax:

    SetWith(TargetBit, Source)
    

    Command Availability:

    Available on all microcontrollers.

    Explanation:

    SetWith is an extended version of SET, it allows a Bit Field to be set or cleared by evaluating the content of Source. SetWith should always be used when TargetBit is an I/O Bit and Source is a Function, in order to avoid the possibility of I/O jitter.

    Source may be a variable and of type: Bit, Byte, Word or Long, a Constant, an expression or a Function.

    It will SET TargetBit to 1 if Source evaluates to anything other than zero. TargetBit will always be a 1 or a 0 regardless of the variable type of TargetBit.

    Cheers
    Chris

     
  • Nivek

    Nivek - 2018-09-26

    Chris,

    While SetWith is useful, this is a little different than my situation - I am trying to test (evaluate) a bit variable with True in an If Then statement. I am not trying to set/clear a bit based on some condition.

    The compare does not work properly, because while the compiler properly recognises True in a bit assignment statement as setting the bit, it does not understand that when using True in an If Then statement simple "is bit set or clear" logic is required.

    Here's an example, this is the GCB source code:

    ' bit compare problem test (asm difference if then compare using True vs using 1)
    #option explicit
    #chip 12f683, 4 ' model, frequency in MHz
    #config OSC = INTOSCIO, MCLRE_OFF, FCMEN_OFF, IESO_OFF, PWRTE_ON, BOREN_ON, WDTE_OFF
    
    Dim some_bit_var as Bit
    some_bit_var = 1 ' set initial state
    some_bit_var = True ' set initial state
    some_bit_var = 0 ' set initial state
    some_bit_var = False ' set initial state
    ' all of the above work fine for set/clear the bit
    
    ' but there is a difference in the output asm code for
    ' 1. using = 1
    if some_bit_var = 1 then goto it_was_true
    ' 2. using = True
    if some_bit_var = True then goto it_was_true
    
    it_was_true:
    

    Below is the .asm output output:

    ;Program compiled by Great Cow BASIC (0.98.02 2018-05-10)
    ;********************************************************************************
    ;Set up the assembler options (Chip type, clock source, other bits and pieces)
     LIST p=12F683, r=DEC
    #include <P12F683.inc>
     __CONFIG _FCMEN_OFF & _IESO_OFF & _BOREN_ON & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _FOSC_INTOSCIO
    ;********************************************************************************
    ;Set aside memory locations for variables
    SYSBITVAR0  EQU 32
    SYSCALCTEMPA    EQU 117
    ;********************************************************************************
    ;Vectors
        ORG 0
        pagesel BASPROGRAMSTART
        goto    BASPROGRAMSTART
        ORG 4
        retfie
    ;********************************************************************************
    ;Start of program memory page 0
        ORG 5
    BASPROGRAMSTART
    ;Call initialisation routines
        call    INITSYS
    ;Start of the main program
    ;bit compare problem test (asm difference if then compare using True vs using 1)
    ;Dim some_bit_var as Bit
    ;some_bit_var = 1 ' set initial state
        bsf SYSBITVAR0,0
    ;some_bit_var = True ' set initial state
        bsf SYSBITVAR0,0
    ;some_bit_var = 0 ' set initial state
        bcf SYSBITVAR0,0
    ;some_bit_var = False ' set initial state
        bcf SYSBITVAR0,0
    ;all of the above work fine for set/clear the bit
    ;but there is a difference in the output asm code for
    ;1. using = 1
    ;if some_bit_var = 1 then goto it_was_true
        btfsc   SYSBITVAR0,0
        goto    IT_WAS_TRUE
    ENDIF1
    ;2. using = True
    ;if some_bit_var = True then goto it_was_true
        clrf    SysCalcTempA
        btfsc   SYSBITVAR0,0
        incf    SysCalcTempA,F
    ENDIF3
        incf    SysCalcTempA,W
        btfsc   STATUS, Z
        goto    IT_WAS_TRUE
    ENDIF2
    IT_WAS_TRUE
    BASPROGRAMEND
        sleep
        goto    BASPROGRAMEND
    
    ;********************************************************************************
    ' init code not shown because it's not relevant
    

    Observe the difference for "If Then lines 1 & 2" - compiler produces different code when = True is used. I feel True should be treated like 1 for bit variables.

    Thanks,
    Kevin.

     
  • stan cartwright

    stan cartwright - 2018-09-26

    "I am trying to test (evaluate) a bit variable with True in an If Then statement. "
    Could you use if var and true then ?

     
  • Chris Roper

    Chris Roper - 2018-10-19

    Thanks for Posting the asm output, I had not looked that deep befor.

    Most compilers, as you probably know, define Zero as FALSE and Non Zero as TRUE so I agree with you that TRUE and 1 should be the same but, unfortunately, GCBASIC defines TRUE as 0xFF and not 1.
    I have previously voiced my opinion and welcome your verification but, due to all the legasy code in the examples folder, I doubt our calls will carry much weight.

    As a workaround this may help:

    Function  isTrue(in MyExp)
        isTrue = FALSE
        If MyExp != 0 Then isTrue = TRUE
    End Function
    

    untested so far but I will give it a try on the morrow.

    Cheers
    Chris

     

    Last edit: Chris Roper 2018-10-19
  • Hugh Considine

    Hugh Considine - 2018-10-20

    For now, the shortest workaround is to forget the = True part. This code would work as expected:

    If some_bit_var then goto it_was_true
    

    For the longer term, we'll do whatever we can to make this less confusing without breaking existing programs. TRUE and FALSE have to stay as they are to avoid causing problems, but some special handling of bit values in the compiler should improve the situation.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.