/* ************BITFIFO.C************* with bug ******** // Debugging lab example // *****There is a bug placed in PutBit() on purpose** Pointer implementation of the a bitFIFO These routines can be used to save (PutBit) and recall (GetBit) binary data 1 bit at a time (bit streams) Information is saved/recalled in a first in first out manner FIFOSIZE is the number of 16-bit words in the Fifo the FIFO is full when it has (16*FIFOSIZE)-1 bits */ // Last modified 1/21/02 by Jonathan W. Valvano // Copyright 2002 by Jonathan W. Valvano, valvano@uts.cc.utexas.edu // You may use, edit, run or distribute this file // as long as the above copyright notice remains unsigned int Fifo[FIFOSIZE]; // storage for Bit Stream struct BitPointer{ unsigned int Mask; // 0x8000, 0x4000,...,2,1 unsigned int *WPt;}; // Pointer to word containing bit typedef struct BitPointer BitPointerType; BitPointerType PutPt; // Pointer of where to put next BitPointerType GetPt; // Pointer of where to get next /* BitFIFO is empty if PutPt==GetPt */ /* BitFIFO is full if PutPt+1==GetPt */ //******** SameBit *************** // return true if the two addresses match int static SameBit(BitPointerType p1, BitPointerType p2){ if((p1.WPt==p2.WPt)&&(p1.Mask==p2.Mask)){ return(1); // yes } return(0); // no } //******** BitFifo_Init *************** // Initialize BitFifo // Make PutPt and GetPt both point to the top void BitFifo_Init(void){ PutPt.Mask = GetPt.Mask = 0x8000; PutPt.WPt = GetPt.WPt = &Fifo[0]; /* Empty when PutPt==GetPt */ } //******** BitFifo_Put *************** // Enter a bit (data) into the BitFifo // returns TRUE=1 if successful, FALSE=0 if full and data not saved // input is boolean FALSE if data==0 // *********************************************************************************** // ******There is a bug in this routine, placed here on purpose ********************** // *********************************************************************************** int BitFifo_Put(int data){ BitPointerType tempPutPt; tempPutPt = PutPt; tempPutPt.Mask = tempPutPt.Mask>>1; if(tempPutPt.Mask==0){ tempPutPt.Mask = 0x8000; if((tempPutPt.WPt++)==&Fifo[FIFOSIZE]){ tempPutPt.WPt = &Fifo[0]; // wrap } } if (SameBit(tempPutPt,GetPt)){ return(0); /* Failed, fifo was full */ } else { if(data){ (*PutPt.WPt) |= PutPt.Mask; // set bit } else{ (*PutPt.WPt) &= ~PutPt.Mask; // clear bit } PutPt = tempPutPt; return(1); } } //******** BitFifo_Get *************** // Remove a bit (*datapt) from the BitFifo // returns TRUE=1 if successful, FALSE=0 if empty and data not removed // output is boolean 0 means FALSE, nonzero is true int BitFifo_Get(unsigned int *datapt) { if (SameBit(PutPt,GetPt)){ return(0); /* Failed, fifo was empty */ } else{ *datapt = (*GetPt.WPt)&GetPt.Mask; GetPt.Mask = GetPt.Mask>>1; if(GetPt.Mask==0){ GetPt.Mask = 0x8000; if((++GetPt.WPt)==&Fifo[FIFOSIZE]){ GetPt.WPt = &Fifo[0]; // wrap } } return(1); } }