View Single Post
  #6   Spotlight this post!  
Unread 04-01-2008, 12:23
dcbrown dcbrown is offline
Registered User
AKA: Bud
no team
Team Role: Mentor
 
Join Date: Jan 2005
Rookie Year: 2005
Location: Hollis,NH
Posts: 236
dcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud ofdcbrown has much to be proud of
Re: Manipulating bits

Code:
144:                   var1 = var1 >> 2;
 04524    0101     MOVLB 0x1
 04526    90D8     BCF 0xfd8, 0, ACCESS                ; set Carry flag to '0'
 04528    33E7     RRCF 0xe7, F, BANKED                ; C -> var1.hi -> C
 0452A    33E6     RRCF 0xe6, F, BANKED                ; C -> var1.lo -> C
 0452C    90D8     BCF 0xfd8, 0, ACCESS                ; set C flag to '0'
 0452E    33E7     RRCF 0xe7, F, BANKED                ; shift again
 04530    33E6     RRCF 0xe6, F, BANKED
Its more accurate to say the compiler doesn't support signed shifts. The PIC is capable of doing signed shifts if asked to. All shifts are treated as unsigned by the compiler and have the carry in flag set to zero during the rotations. The PIC is capable of shifting in a '1' for negative values but the compile chooses not to -- 'cause all shifting operations are unsigned. Other compilers, such as HI-TECH's PIC C compiler chose to preserve the sign bit. This is a compiler specific implementation selection allowed by the ANSI C spec.

If you want to do signed shifts, you have to roll your own and change the instructions to:

Code:
    BTFSC 0xe7, 7, BANKED
    BRA     NEGVALUE_SHIFT
POSVALUE_SHIFT:
    BCF     0xfd8, 0, ACCESS                      ; Set CARRY (C) flag to '0'
    RRCF    0xe7, F, BANKED                       ; C -> var1.hi -> C
    RRCF    0xe6, F, BANKED                       ; C -> var1.lo -> C
    BCF     0xfd8, 0, ACCESS                      ; clear C flag for next shift op
    RRCF    0xe7, F, BANKED
    RRCF    0xe6, F, BANKED
    BRA     DONE_SHIFT
NEGVALUE_SHIFT:
    BSF     0xfd8, 0, ACCESS                      ; Set CARRY (C) flag to '1'
    RRCF    0xe7, F, BANKED                       ; C -> var1.hi -> C
    RRCF    0xe6, F, BANKED                       ; C -> var1.lo -> C
    BSF     0xfd8, 0, ACCESS                      ; set C flag for next shift op
    RRCF    0xe7, F, BANKED
    RRCF    0xe6, F, BANKED
    BRA     DONE_SHIFT
DONE_SHIFT:
alternatively, in C a little more convoluted... plus there are other methods.

Code:
    if (var1 > 0)
        var1 = (var1 >> 2);
    else
        var1 = (varl >> 2) | 0xC000;