home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / HD / SmartFileSystem / V1.58 / Sources / bitfuncs.c < prev   
Encoding:
C/C++ Source or Header  |  1999-01-24  |  5.4 KB  |  284 lines

  1. // #include <exec/types.h>
  2. // #include <stdio.h>
  3.  
  4. #include "bitfuncs_protos.h"
  5.  
  6. /*
  7. main() {
  8.   ULONG bitmap[]={0x00000000,0x3fffffff,0xffffffff};
  9.  
  10.   printf("bmffo returns %ld\n",bmffo(bitmap,3,0));
  11.   printf("bfco returns %ld\n",bfco(0xFFFFFFFF));
  12.   printf("bfco returns %ld\n",bfco(0x0));
  13.   printf("bfco returns %ld\n",bfco(0xAAAAAAAA));
  14. }
  15. */
  16.  
  17. /* bitfield (bf) functions:
  18.  
  19.    These functions perform bit-operations on a single longword.
  20. */
  21.  
  22.  
  23.  
  24. WORD bfco(ULONG data) {
  25.   WORD n=32;
  26.   WORD cnt=0;
  27.  
  28.   /* Counts the number of set bits in the supplied 32-bit value */
  29.  
  30.   while(n-->0) {
  31.     if((LONG)data<0) {
  32.       cnt++;
  33.     }
  34.     data<<=1;
  35.   }
  36.  
  37.   return(cnt);
  38. }
  39.  
  40.  
  41.  
  42. WORD bfffo(ULONG data,WORD bitoffset) {
  43.   ULONG bitmask=1<<(31-bitoffset);
  44.  
  45.   /** Finds first set bit in /data/ starting at /bitoffset/.  This function
  46.       considers the MSB to be the first bit. */
  47.  
  48.   do {
  49.     if((data & bitmask)!=0) {
  50.       return(bitoffset);
  51.     }
  52.     bitoffset++;
  53.     bitmask>>=1;
  54.   } while(bitmask!=0);
  55.  
  56.   return(-1);
  57. }
  58.  
  59.  
  60. WORD bfffz(ULONG data,WORD bitoffset) {
  61.   ULONG bitmask=1<<(31-bitoffset);
  62.  
  63.   do {
  64.     if((data & bitmask)==0) {
  65.       return(bitoffset);
  66.     }
  67.     bitoffset++;
  68.     bitmask>>=1;
  69.   } while(bitmask!=0);
  70.  
  71.   return(-1);
  72. }
  73.  
  74.  
  75. WORD bfffz8(UBYTE data,WORD bitoffset) {
  76.   UBYTE bitmask=1<<(7-bitoffset);
  77.  
  78.   do {
  79.     if((data & bitmask)==0) {
  80.       return(bitoffset);
  81.     }
  82.     bitoffset++;
  83.     bitmask>>=1;
  84.   } while(bitmask!=0);
  85.  
  86.   return(-1);
  87. }
  88.  
  89.  
  90. ULONG bfset(ULONG data,WORD bitoffset,WORD bits) {
  91.   ULONG mask;
  92.  
  93.   /** Sets /bits/ bits starting from /bitoffset/ in /data/.
  94.       /bits/ must be between 1 and 32. */
  95.  
  96.   /* we want a mask which sets /bits/ bits starting from bit 31 */
  97.  
  98.   mask=~((1<<(32-bits))-1);
  99.   mask>>=bitoffset;
  100.  
  101.   return(data | mask);
  102. }
  103.  
  104.  
  105. ULONG bfclr(ULONG data,WORD bitoffset,WORD bits) {
  106.   ULONG mask;
  107.  
  108.   /* we want a mask which sets /bits/ bits starting from bit 31 */
  109.  
  110.   mask=~((1<<(32-bits))-1);
  111.   mask>>=bitoffset;
  112.  
  113.   return(data & ~mask);
  114. }
  115.  
  116.  
  117. /* bitmap (bm) functions:
  118.  
  119.    These functions perform bit-operations on regions of memory which
  120.    are a multiple of 4 bytes in length.
  121. */
  122.  
  123.  
  124. LONG bmffo(ULONG *bitmap,LONG longs,LONG bitoffset) {
  125.   ULONG *scan=bitmap;
  126.   ULONG longoffset;
  127.   WORD bit;
  128.  
  129.   /* This function finds the first set bit in a region of memory starting
  130.      with /bitoffset/.  The region of memory is /longs/ longs long.  It
  131.      returns the bitoffset of the first set bit it finds. */
  132.  
  133.   longoffset=bitoffset>>5;
  134.   longs-=longoffset;
  135.   scan+=longoffset;
  136.  
  137.   bitoffset=bitoffset & 0x1F;
  138.  
  139.   if(bitoffset!=0) {
  140.     if((bit=bfffo(*scan,bitoffset))>=0) {
  141.       return(bit+((scan-bitmap)<<5));
  142.     }
  143.  
  144.     scan++;
  145.     longs--;
  146.   }
  147.  
  148.   while(longs-->0) {
  149.     if(*scan++!=0) {
  150.       return(bfffo(*--scan,0)+((scan-bitmap)<<5));
  151.     }
  152.   }
  153.  
  154.   return(-1);
  155. }
  156.  
  157.  
  158. LONG bmffz(ULONG *bitmap,LONG longs,LONG bitoffset) {
  159.   ULONG *scan=bitmap;
  160.   ULONG longoffset;
  161.   WORD bit;
  162.  
  163.   /* This function finds the first unset bit in a region of memory starting
  164.      with /bitoffset/.  The region of memory is /longs/ longs long.  It
  165.      returns the bitoffset of the first unset bit it finds. */
  166.  
  167.   longoffset=bitoffset>>5;
  168.   longs-=longoffset;
  169.   scan+=longoffset;
  170.  
  171.   bitoffset=bitoffset & 0x1F;
  172.  
  173.   if(bitoffset!=0) {
  174.     if((bit=bfffz(*scan,bitoffset))>=0) {
  175.       return(bit+((scan-bitmap)<<5));
  176.     }
  177.  
  178.     scan++;
  179.     longs--;
  180.   }
  181.  
  182.   while(longs-->0) {
  183.     if(*scan++!=0xFFFFFFFF) {
  184.       return(bfffz(*--scan,0)+((scan-bitmap)<<5));
  185.     }
  186.   }
  187.  
  188.   return(-1);
  189. }
  190.  
  191. LONG bmclr(ULONG *bitmap,LONG longs,LONG bitoffset,LONG bits) {
  192.   ULONG *scan=bitmap;
  193.   ULONG longoffset;
  194.   LONG orgbits=bits;
  195.  
  196.   /* This function clears /bits/ bits in a region of memory starting
  197.      with /bitoffset/.  The region of memory is /longs/ longs long.  If
  198.      the region of memory is too small to clear /bits/ bits then this
  199.      function exits after having cleared all bits till the end of the
  200.      memory region.  In any case it returns the number of bits which
  201.      were actually cleared. */
  202.  
  203.   longoffset=bitoffset>>5;
  204.   longs-=longoffset;
  205.   scan+=longoffset;
  206.  
  207.   bitoffset=bitoffset & 0x1F;
  208.  
  209.   if(bitoffset!=0) {
  210.     if(bits<32) {
  211.       *scan=bfclr(*scan,bitoffset,bits);
  212.     }
  213.     else {
  214.       *scan=bfclr(*scan,bitoffset,32);
  215.     }
  216.  
  217.     scan++;
  218.     longs--;
  219.     bits-=32-bitoffset;
  220.   }
  221.  
  222.   while(bits>0 && longs-->0) {
  223.     if(bits>31) {
  224.       *scan++=0;
  225.     }
  226.     else {
  227.       *scan=bfclr(*scan,0,bits);
  228.     }
  229.     bits-=32;
  230.   }
  231.  
  232.   if(bits<=0) {
  233.     return(orgbits);
  234.   }
  235.   return(orgbits-bits);
  236. }
  237.  
  238. LONG bmset(ULONG *bitmap,LONG longs,LONG bitoffset,LONG bits) {
  239.   ULONG *scan=bitmap;
  240.   ULONG longoffset;
  241.   LONG orgbits=bits;
  242.  
  243.   /* This function sets /bits/ bits in a region of memory starting
  244.      with /bitoffset/.  The region of memory is /longs/ longs long.  If
  245.      the region of memory is too small to set /bits/ bits then this
  246.      function exits after having set all bits till the end of the
  247.      memory region.  In any case it returns the number of bits which
  248.      were actually set. */
  249.  
  250.   longoffset=bitoffset>>5;
  251.   longs-=longoffset;
  252.   scan+=longoffset;
  253.  
  254.   bitoffset=bitoffset & 0x1F;
  255.  
  256.   if(bitoffset!=0) {
  257.     if(bits<32) {
  258.       *scan=bfset(*scan,bitoffset,bits);
  259.     }
  260.     else {
  261.       *scan=bfset(*scan,bitoffset,32);
  262.     }
  263.  
  264.     scan++;
  265.     longs--;
  266.     bits-=32-bitoffset;
  267.   }
  268.  
  269.   while(bits>0 && longs-->0) {
  270.     if(bits>31) {
  271.       *scan++=0xFFFFFFFF;
  272.     }
  273.     else {
  274.       *scan=bfset(*scan,0,bits);
  275.     }
  276.     bits-=32;
  277.   }
  278.  
  279.   if(bits<=0) {
  280.     return(orgbits);
  281.   }
  282.   return(orgbits-bits);
  283. }
  284.