On Sun, 29 Nov 1998 13:29:44 +1300 Seth Fischer writes: >What does it mean to rotate a file _through the carry bit_ (RLF and >RRF)? The value of the carry bit before the instruction goes into one end of the byte being rotated. The bit that is rotated out of the byte goes into the carry bit. In somewhat graphical form, we have rlf : C <- dddddddd <- C rrf : C -> dddddddd -> C A single rrf is merely a shift. But repeated rrf or rlf will rotate 9 bits of data, 8 being in the data byte and one in the carry bit. > >When executing RLF on portB (8 LEDs) I get this: > >portB = 00000001 > RLF portb >portB = 00000011 ; I want only one bit high and 'walking' left > RLF portB >portB = 00000110 > RLF portB >portB = 00001100 > >What is happening? The result you see is exactly what should happen if the C bit were 1 at the start of the process. To keep from getting more than one 1 bit in the result, you should clear the carry bit before each rotate, except for the case of 10000000 going back to 00000001. This code will approximatley "work." However I don't recommend that you use it for anything other than an exercise. It implements a true 8 bit rotate by setting the C bit before shifting. You would need to initialize PORTB to 00000001 first. clrc ;Always clear C btfsc PORTB,7 ;except if a 1 is coming out setc ; in which case set C. rlf PORTB,f Now this code does "work" but it has a couple of bad practices in it. First, it is possible for patterns other than the desired ones containing just one 1 to continually rotate around. If a glitch causes the PORTB pins to read back improperly (which can happen because of heavy loads on the pins for example), some bits may get set when they aren't supposed to. Or, an all-zero pattern could persist. We should use a better test to be sure that the routine will "count out of" undesired states. A better method is to shift in zeros unless the value is X0000000. Here's a test for X0000000: movfw PORTB andlw b'01111111' ;Test if 7 low bits are all zero. clrc ;Prepare to have C clear if they aren't. skpnz setc rlf PORTB The other bad practice is reading back the output pins. Sure it works most of the time, but unless you just can't avoid it it is best to read ports only to determine the state of the input pins. This makes the program less likely to malfunction due to transients from the external circuitry. Set up the output value in RAM instead and write it to the port. So we'd define a RAM varaible "shadowb" and do all the rotating on it instead. Combining that with the enhanced test above: movfw shadowb andlw b'00000001' clrc skpnz setc rlf shadowb,f movfw shadowb ;Get bit pattern out of RAM movwf PORTB ;Write to PORTB. This code can be optimized some, though it becomes more obscure. rlf shadowb,w ;W= dddddddX andlw b'11111110' ;See if need to put in a new 1. skpnz ;No, value OK. movlw b'00000001' ;Restart at 00000001 movwf shadowb ;Update RAM variable movwf PORTB ;Update port value. With these routines there isn't a need to initialize the shadowb/PORTB values unless it is important that the output be correct for the first 8 shifts. ___________________________________________________________________ You don't need to buy Internet access to use free Internet e-mail. Get completely free e-mail from Juno at http://www.juno.com/getjuno.html or call Juno at (800) 654-JUNO [654-5866]