Certain instructions, such as bcf and bsf, will read the entire register, perform some operation on it, and then write the result back to the register. For example, the instruction
bsf REG1,2, as you know, sets bit 2 of REG1. What really happens inside the PIC is that all 8 bits of REG1 are read into an internal work register inside the PIC's ALU, bit 2 is set there, and then all 8 bits are written back into REG1.
The snag that can happen with RMW instructions is when they are used on PORT registers where there are pins set as input. Reading a port register actually reads the state of the pins themselves. Writing a port register writes to the output data latches of the port. A RMW instruction may change bits in the output latch that weren't intended. For example, let's say that RB0 is a pin that's multiplexed and used as both an input and an output. RB7 is an output pin that we want to turn on with a bsf instruction. Last time you set RB0 when it was an output, you set it to a 0, so that's what's in the output latch for that bit. When RB0 is set to output, it will be low. But when it's an input, it will read whatever the pin voltage is at (high or low). So, if you do a
bsf PORTB,RB7 and RB0 as an input is high, the output data latch will end up with RB0 = 1 instead of 0.
The solution in this case is to use a shadow register to retain output pin values, do your RMW instructions there, then move the shadow register to the actual port.
Code:
bsf portb_shadow,7 ; Set portb to output in shadow
movfw portb_shadow ; Get shadow register
movwf PORTB ; and write to port B