Well, it was as I expected.
It's all about the assignment statement.
Whatever "Type" the left side of the assignment statement is drives the operation.
If you are assigning the value to a Byte, then the compiler does the steps as a byte.
If you are assigning the value to a BIT, then the compiler does the steps as a bit.
Here is a simple test program.
The "Destination" of the value is tested against a Byte variable or a Bit variable.
The "Source" of the value is tested against a Byte variable, a Port Alias and a Bit Alias.
Code:
myBit var bit
myByte var byte
TRISB = $FF
TestPin var PORTB.6
TestByte var byte
TestBit var TestByte.6
'Test Variable Alias with direct assignment to byte variable
TestByte = %01000000
'Assign Logical NOT (!) bit value to byte variable
myByte = !TestBit
'Assign Bitwise NOT (~) bit value to byte variable
myByte = ~TestBit
'Test Port Alias with direct assignment to byte variable
'Assign Logical NOT (!) bit value to byte variable
myByte = !TestPin
'Assign Bitwise NOT (~) bit value to byte variable
myByte = ~TestPin
'Test Variable Alias with direct assignment to bit variable
TestByte = %01000000
'Assign Logical NOT (!) bit value to bit variable
myBit = !TestBit
'Assign Bitwise NOT (~) bit value to bit variable
myBit = ~TestBit
'Test Port Alias with direct assignment to bit variable
'Assign Logical NOT (!) bit value to byte variable
myBit = !TestPin
'Assign Bitwise NOT (~) bit value to byte variable
myBit = ~TestPin
Here is the PBP assembler listing for the above code.
Notice that there are (2) macros for each operator type (! or ~)
LNOT?TB and LNOT?TT (Logical NOT !)
NOT?TB and NOT?TT (Bitwise NOT ~)
The TB stands for biT in and Byte out. The input is a Bit type and the Output is a Byte type.
This is when you get the results that are not what you might expect.
The TT stands for biT in and biT out. The input is a Bit type and the Output is a Bit type.
Code:
;assembler variables
_myByte EQU RAM_START + 01Ah
PB01 EQU RAM_START + 01Bh
_TestByte EQU RAM_START + 01Ch
;assembler defines
#define _myBit PB01, 000h
#define _TestPin _PORTB??6
#define _TestBit _TestByte??6
#define _PORTB??6 PORTB, 006h
#define _TestByte??6 _TestByte, 006h
; 00022 TestByte = %01000000
MOVE?CB 040h, _TestByte
; 00025 myByte = !TestBit
LNOT?TB _TestBit, _myByte
; 00028 myByte = ~TestBit
NOT?TB _TestBit, _myByte
; 00033 myByte = !TestPin
LNOT?TB _TestPin, _myByte
; 00036 myByte = ~TestPin
NOT?TB _TestPin, _myByte
; 00039 TestByte = %01000000
MOVE?CB 040h, _TestByte
; 00042 myBit = !TestBit
LNOT?TT _TestBit, _myBit
; 00045 myBit = ~TestBit
NOT?TT _TestBit, _myBit
; 00050 myBit = !TestPin
LNOT?TT _TestPin, _myBit
; 00053 myBit = ~TestPin
NOT?TT _TestPin, _myBit
Here are the actual macros that are called above.
I made some comments, not for everything but some.
Code:
NOT?TB macro Regin, Bitin, Bout
CHK?RP Regin
movlw -1 ;load dec 255 into w register
btfsc Regin, Bitin ;If Regin.Bitin = 0, skip the next instruction
movlw -2 ;load dec 254 into w register
MOVE?AB Bout ;Move W to Bout
endm
NOT?TT macro Regin, Bitin, Regout, Bitout
CHK?RP Regin
clrw ;Clear the w register
btfss Regin, Bitin ;If Regin.Bitin = 1, skip the next instruction
addlw 1 ;Load dec 1 into the w Register
CHK?RP Regout
btfsc STATUS, Z
bcf Regout, Bitout ;Clear Regout.Bitout
btfss STATUS, Z
bsf Regout, Bitout ;Set Regout.Bitout
endm
LNOT?TB macro Regin, Bitin, Bout
CHK?RP Regin
clrw
btfss Regin, Bitin
movlw -1
MOVE?AB Bout
endm
LNOT?TT macro Regin, Bitin, Regout, Bitout
CHK?RP Regin
clrw
btfss Regin, Bitin
addlw 1
CHK?RP Regout
btfsc STATUS, Z
bcf Regout, Bitout
btfss STATUS, Z
bsf Regout, Bitout
endm
Bookmarks