Following on from the issues with AND, here's another issue I uncovered while writing the graphical LCD code posted in Contributions.
Again, using GCB v0.9 3/2/2010 with a copy of UPDATE.ZIP dated/downloaded 5th April.
My program contains the following subroutine and once again is being compiled with a #chip 16F873A, 4 directive:
SUB GLCD_xy(xpos, ypos)
' extract and set upper (MS) 4 bits of Column Address
GLCD_gen0 = xpos
ROTATE GLCD_gen0 RIGHT SIMPLE
ROTATE GLCD_gen0 RIGHT SIMPLE
ROTATE GLCD_gen0 RIGHT SIMPLE
ROTATE GLCD_gen0 RIGHT SIMPLE
GLCD_gen0 = GLCD_gen0 AND b'00001111'
GLCD_cmd GLCD_gen0 OR b'00010000' ' b'0001xxxx' = set upper (MS) 4 bits of Column Address
GLCD_cmd xpos AND b'00001111' ' b'0000xxxx' = set lower (LS) 4 bits of Column Address
' set row address
GLCD_cmd ypos OR b'10110000' ' 0xB0 = set Page ("row") Address
EXIT SUB
But it generates the following assembler. To clarify, I've annotated with where I think the BASIC commands go that generate each part of the assembler (I wasn't aware of the /K:A compiler switch when I wrote this):
GLCD_XY
; GLCD_gen0 = xpos
movf XPOS,W
movwf GLCD_GEN0
; ROTATE GLCD_gen0 RIGHT SIMPLE (incidentally, a BASIC command for SWAP would be really helpful here...)
rrf GLCD_GEN0,W
rrf GLCD_GEN0,F
; ROTATE GLCD_gen0 RIGHT SIMPLE
rrf GLCD_GEN0,W
rrf GLCD_GEN0,F
; ROTATE GLCD_gen0 RIGHT SIMPLE
rrf GLCD_GEN0,W
rrf GLCD_GEN0,F
; ROTATE GLCD_gen0 RIGHT SIMPLE
rrf GLCD_GEN0,W
rrf GLCD_GEN0,F
; GLCD_gen0 = GLCD_gen0 AND b'00001111'
movlw 15
andwf GLCD_GEN0,F
; GLCD_cmd GLCD_gen0 OR b'00010000' ' b'0001xxxx' = set upper (MS) 4 bits of Column Address
movlw 16
iorwf GLCD_GEN0,W
movwf BYTE
call GLCD_CMD
; GLCD_cmd xpos AND b'00001111' ' b'0000xxxx' = set lower (LS) 4 bits of Column Address
clrf BYTE
call GLCD_CMD
; GLCD_cmd ypos OR b'10110000' ' 0xB0 = set Page ("row") Address
movlw 176
iorwf YPOS,W
movwf BYTE
call GLCD_CMD
; EXIT SUB
return
return
As you can see, the first call to GLCD_cmd works fine when GLCD_gen0 is ORed with b'10000' but the second call, where xpos is ANDed with b'1111' simply compiles to "clrf". The third call, where ypos is ORed with b'1011000' also works fine.
Putting brackets around the AND statement produces something closer to the correct assembler:
; GLCD_cmd (xpos AND b'00001111') ' b'0000xxxx' = set lower (LS) 4 bits of Column Address
movlw 15
andwf XPOS,W
movwf SysTemp1
call GLCD_CMD
But the resulting value is placed into SysTemp1 before the call, rather than BYTE, which is incorrect.
I tried changing the BASIC into two separate statements:
GLCD_gen0 = xpos AND b'00001111' ' b'0000xxxx' = set lower (LS) 4 bits of Column Address
GLCD_cmd GLCD_gen0
And got this code:
; GLCD_gen0 = xpos AND b'00001111' ' b'0000xxxx' = set lower (LS) 4 bits of Column Address
clrf GLCD_GEN0
movf GLCD_GEN0,W
movwf BYTE
call GLCD_CMD
movf BYTE,W
movwf GLCD_GEN0
The AND statement is still generating a CLRF, this time for GLCD_GEN0, before calling GLCD_CMD
At this point, I changed the AND statement to
SET GLCD_gen0.4 OFF
SET GLCD_gen0.5 OFF
SET GLCD_gen0.6 OFF
SET GLCD_gen0.7 OFF
Which did the trick, but I am confused as to why the AND statement didn't work, especially when the OR on ypos was fine the whole way through.
Mark
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Following on from the issues with AND, here's another issue I uncovered while writing the graphical LCD code posted in Contributions.
Again, using GCB v0.9 3/2/2010 with a copy of UPDATE.ZIP dated/downloaded 5th April.
My program contains the following subroutine and once again is being compiled with a #chip 16F873A, 4 directive:
But it generates the following assembler. To clarify, I've annotated with where I think the BASIC commands go that generate each part of the assembler (I wasn't aware of the /K:A compiler switch when I wrote this):
As you can see, the first call to GLCD_cmd works fine when GLCD_gen0 is ORed with b'10000' but the second call, where xpos is ANDed with b'1111' simply compiles to "clrf". The third call, where ypos is ORed with b'1011000' also works fine.
Putting brackets around the AND statement produces something closer to the correct assembler:
But the resulting value is placed into SysTemp1 before the call, rather than BYTE, which is incorrect.
I tried changing the BASIC into two separate statements:
GLCD_gen0 = xpos AND b'00001111' ' b'0000xxxx' = set lower (LS) 4 bits of Column Address
GLCD_cmd GLCD_gen0
And got this code:
The AND statement is still generating a CLRF, this time for GLCD_GEN0, before calling GLCD_CMD
At this point, I changed the AND statement to
SET GLCD_gen0.4 OFF
SET GLCD_gen0.5 OFF
SET GLCD_gen0.6 OFF
SET GLCD_gen0.7 OFF
Which did the trick, but I am confused as to why the AND statement didn't work, especially when the OR on ypos was fine the whole way through.
Mark