/* CS 341 Spring 2002 */
/* Note segment 5 */
/* 14-Feb-2002 */
/* Taken by Apostolos Paul Pantazis */

Low Level Bit manipulation.

AS we al know it is quite possible at the higher level to program without
full knowledge of how bits work. The truth is that this is not as
effective and a knowledge of how hardware works is often quite vital.

Problem # 1. ( I believe this is the Biosequence one ..)

--> You need a mapping mechanism between numbers and symbols.
--> Output should be in ASCII.
--> A --> number --> Sequence of Bits (1001101) (*1)
    (*1): Just a quessed sequence.

ASCII: Designed for programers by programers(yeah baby!)
       Lots of conviniences..
       8-bit code, well ok not really its a 7-bit code.
       The 8th bit is often used as a parity bit or for
       Sync that is getting the receiver to Sync with the
       transmiter (figuring out the break between chars).

       * look up ascii under linux *

       The 3-letter mnemonics on the ascii table are non-
       printable characters, like DLE.

       Code for lower 'a' is 0X61 in Hex the bit pattern
       is 01100001
       Code for upper 'A' is 0x41 the bit part is
       We observe that the only difference is One 0.

       In C++ to set the case bit you do:
       c = c |(1 << 5) /* Shift by 5 bits cause case bit is the 5th.
       c = c | 0x20
       c = c |= 0x20

       Lets say we wanted to go Upper(); so we want to clear
       the case bit.
       c = & =~ 0x20 /* ~0x20 all bits reverse 11011111 = 0xDF*/
       & --> Bitwise & in C programming language.
       0x20 --> 00100000.

       Converting a digit to an Integer.
       Dividing corresponds to a right shift.

       Getting Bits out of Words.

       Computers are Byte adressable. At times the need exist to
       Deal directly with Bits
       Say you have a stream of Bits packed into words.      
       (How do we ger a particular bit out?)
       1. Keep a pointer to a register which points to the right word.
          (adress of word we are in).
       2. Another register will hold the bit index, that is the current
          bit that we are on.
       3. Get the target bit into another register.

       Obviously we need to fetch the word and get the bit out of the
       word. In C++ r3 = *r1;
       |	      |
        (0)...(12)...(31) --> Recall sparc is Big-Endian..
       We are going to && the above with a pattern that contains
       all zero's and a 1 in the 12th bit possition.
       Now we need to construct a mask that is 2^(32-i). To calculate
       this int you do : 1 << (31 - i) or 2^31 >> i
       This might be a hasle in Sparc cause it would be a little pain 
       to get a 2^31 value in a register since it is bigger than 12 bits
       (or if you like > 2^13 bits). [longer..]

       So with some magic way we will get the mask. Now we have
       a word with the bit that we need isolated. You can do an
       andcc and the BZ. If(result == 0){ Bit was zero}
       else{bit was non zero).
       After processing this bit you move your pointer to the next bit.
       First you will have to check if it hit 32.
       if(bit == 32){set bit_index to 0, word_index --) 
       /* and decrement the word index */

       Well, all is nice but sad truth is that this is a pretty bad
       way regarding efficiency to do things. The Bit index has to be
       constantly translated from a offset to a mask that pulls bits out.

       --> Better?
           Well maybe instead of storing teh bit itself we can store
           the mask and then to move the index we shift the mask by 1.
           To move to the next bit you would do a shift right(logical
           shift ! arithmetic):
           shift_rightcc r2,1,r2
           JNZ if(zero) /* need move next word */
                add r1,4,r1
                load r1,r3
           set_right_const 2^31, r2
           back on top.

         There is also another little hack that has to do with the 
         Overflow bit but I dont quite have that down yet. Will post
         as soon as I figure it out.