I encountered a few oddities while writing the graphical LCD code (see Contributions) and a later program, the first two of which I have also emailed, but I am posting the entire set here in case they are of help, or the emails have not got through.

I am using GCB v0.9 3/2/2010 with a copy of UPDATE.ZIP dated/downloaded 5th April.

My program contains the following GCB variable declaration and subroutine. It is being compiled with a #chip 16F873A, 4 directive.

DIM GLCD_gen0 AS BYTE ' general variable used for calculations (eg column addresses), loops, etc
....
SUB GLCD_serial(oct)
FOR GLCD_gen0 = 1 TO 8
SET GLCD_SCLK OFF ' ensure clock line is low
SET GLCD_SID OFF ' set data bit to be sent as 0
{ IF statement goes here - see below }
SET GLCD_SCLK ON ' clock bit into module on rising edge of clock line
ROTATE oct LEFT SIMPLE ' move to next bit
NEXT
SET GLCD_SCLK OFF ' ensure clock line is low
EXIT SUB

The part that is generating assembler that I don't understand is the IF statement in the middle of this routine which is intended to test bit 7 of the variable and set an output port accordingly.

On other BASICs I have used in the past there is an implied "<> 0" for any IF condition. But when I use:

IF oct AND b'10000000' THEN SET GLCD_SID ON

The compiler generates the assembler:

GLCD_SERIAL
    clrf    GLCD_GEN0
SysForLoop1
    incf    GLCD_GEN0,F
    bcf PORTB,2
    bcf PORTB,1
    movf    OCT & B'10000000',F
    btfss   STATUS,Z
    bsf PORTB,1
    bsf PORTB,2
    rlf OCT,W
    rlf OCT,F
    movlw   8
    subwf   GLCD_GEN0,W
    btfss   STATUS, C
    goto    SysForLoop1
    bcf PORTB,2
    return
    return

Which appears to be ANDing the address of OCT with 128 and putting the result in F (have I got that right?)

I presumed that this was because a specific test for "> 0" had to be included, so I tried:

IF oct AND b'10000000' > 0 THEN SET GLCD_SID ON

This gives the assembler:

GLCD_SERIAL
    clrf    GLCD_GEN0
SysForLoop1
    incf    GLCD_GEN0,F
    bcf PORTB,2
    bcf PORTB,1
    movlw   255
    andwf   OCT,W
    movwf   SysTemp1
    btfsc   SysTemp1,0
    bsf PORTB,1
    bsf PORTB,2
    rlf OCT,W
    rlf OCT,F
    movlw   8
    subwf   GLCD_GEN0,W
    btfss   STATUS, C
    goto    SysForLoop1
    bcf PORTB,2
    return
    return

This appears to be ANDing the contents of OCT with 255 and testing bit 0 of the result (I don't understand this at all, but I don't believe it will do what I want it to do)

I then guessed that this was an operator precedence error and tried this version of the IF statement:

IF (oct AND b'10000000') > 0 THEN SET GLCD_SID ON

This gives what looks to me to be assembler that will do what I need it to do:

GLCD_SERIAL
    clrf    GLCD_GEN0
SysForLoop1
    incf    GLCD_GEN0,F
    bcf PORTB,2
    bcf PORTB,1
    movlw   128
    andwf   OCT,W
    movwf   SysTemp1
    movwf   SysCalcTempB
    clrf    SysCalcTempA
    call    SysCompLessThan
    btfsc   SysCalcTempX,0
    bsf PORTB,1
    bsf PORTB,2
    rlf OCT,W
    rlf OCT,F
    movlw   8
    subwf   GLCD_GEN0,W
    btfss   STATUS, C
    goto    SysForLoop1
    bcf PORTB,2
    return
    return

As you would expect the statement:

IF oct.7 ON THEN SET GLCD_SID ON

also works entirely correctly (and more efficiently, of course) and is the version I should have used from the start.

GLCD_SERIAL
    clrf    GLCD_GEN0
SysForLoop1
    incf    GLCD_GEN0,F
    bcf PORTB,2
    bcf PORTB,1
    btfsc   OCT,7
    bsf PORTB,1
    bsf PORTB,2
    rlf OCT,W
    rlf OCT,F
    movlw   8
    subwf   GLCD_GEN0,W
    btfss   STATUS, C
    goto    SysForLoop1
    bcf PORTB,2
    return
    return

(Not sure about the double "return" though…)

Mark