Tracy Smith says
Here are a couple of ideas for getting 1<<TestBit
10 cycles:
2^n:
clrw
btfsc TestBit,2
movlw b'11111100'
addwf TestBit,f
incf TestBit,w
btfsc TestBit,1
iorwf TestBit,f
incf TestBit,f
skpnc
swapf TestBit,f
.........
another way (7 cycles [including the call])
two_to_n:
andlw 7
addwf pcl,f
retlw 1
retlw 2
retlw 4
retlw 8
retlw 0x10
retlw 0x20
retlw 0x40
retlw 0x80
............
or probably more to the point
movf portb,w
movwf portb_shadow
btfss TestBit,2
swapf portb_swadow,f
btfss TestBit,0
rlf portb_shadow,f
movlw b'10000000'
btfss TestBit,1
movlw b'00100000'
andwf portb_shadow,f
skpnz
goto _the_bit_is_set
.lo
Kevin Blain says:
clrf mask ; empty the mask ; a file called bit contains the 0 to 7 value of the bit position incf bit ; make it 1 to 8, so decfsz works nicely bsf STATUS, C ; set the carry flag. This will be rotated in 'bit' times loop: rlf mask, f decfsz bit, f ; skip out after 'bit' times. goto loop ..... ; rest of code... Of course, it would be good to ensure that bit is not greater than 7 when entering the routine.
Scott Dattalo says
set_bit:
;Get a pointer to the byte containing the bit we want:
rrf bit_position,w
movwf fsr
rrf fsr,f
rrf fsr,w
andlw BIT_ARRAY_MASK
addlw bit_array
movwf fsr
; find 1<<(bit_position&7) [note, this could be made 2-cycles
; shorter]
movlw 0101b
btfsc bit_position,0
movlw 1010b
movwf mask
movlw 0011b
btfsc bit_position,1
movlw 1100b
andwf mask,f
btfsc bit_position,2
swapf mask,f
; now set or clear the bit
movf mask,w
iorwf indf,f ; Assume we're setting.
btfss new_state,0
xorwf indf,w ; assumption was wrong
Dmitry says:
;Probably it would be better to pre allocate bit position value in cell ;shifted by one bit to left, like xxxx.yyyz where xxxx is byte offset ;and yyy bit offset. It let us write more tight code for this case. set_bit: swapf bit_position,W andlw 0x0F addlw bit_array movwf FSR movlw 1 btfsc bit_position,2 ;y.1 movlw 4 movwf mask btfsc bit_position,1 ;y.0 addwf mask,F btfsc bit_position,3 ;y.2 swapf mask,F movfw mask iorwf INDF,F btfss bit_position,0 ;we can use z for this why not? xorwf INDF,F
Bob Ammerman says:
To turn on bit "BitNum" of port "PortNum":
movf PortNum,W
movwf FSR
movf BitNum,W
call BitToMask
iorwf INDF,F
To turn off bit "BitNum" of port "PortNum":
movf PortNum,W
movwf FSR
movf BitNum,W
call BitToMask
xorlw 0xFF
andwf INDF,F
; To test bit "BitNum" or port "PortNum"
movf PortNum,W
movwf FSR
movf BitNum,W
call BitToMask
andwf INDF,W
; At this point Z is set if PortNum,BitNum was clear
; Z is clear if PortNum,BitNum was set
BitToMask:
addwf pcl
retlw 1
retlw 2
retlw 4
retlw 8
retlw 16
retlw 32
retlw 64
retlw 128
See Also:
Code: