// =====================================================================
//  $Id: TVmeDaughterBoardMemoryModule.hh,v 1.1.1.1 2003/06/27 02:56:41 goiwai Exp $
//  $Name: CLDAQ-1-06-02 $
// =====================================================================
#ifndef __TVMEDAUGHTERBOARDMEMORYMODULE_HH
#define __TVMEDAUGHTERBOARDMEMORYMODULE_HH

#include "Tglobals.h"
#include "TVmeModule.hh"

class TDataElement;
class TVmeMpx201aModule;

class TVmeDaughterBoardMemoryModule
  : public TVmeModule
{

  public:
    enum { tDataUnderflow = SHRT_MIN, tDataOverflow = SHRT_MAX };

  private:
    Tint theNumberOfSampling;

  public:
    TVmeDaughterBoardMemoryModule( Toff_t offset, Tint mapsize, Tint nblock, Tint nch = 1 );
    TVmeDaughterBoardMemoryModule( const TVmeMpx201aModule* mpx201a, Tint nch = 1 );
    TVmeDaughterBoardMemoryModule( const TVmeDaughterBoardMemoryModule& right );
    ~TVmeDaughterBoardMemoryModule();

  public:
    const TVmeDaughterBoardMemoryModule& operator=( const TVmeDaughterBoardMemoryModule& right );
    Tbool operator==( const TVmeDaughterBoardMemoryModule& right ) const;
    Tbool operator!=( const TVmeDaughterBoardMemoryModule& right ) const;

  public:
    Tint GetNumberOfSampling() const;
    Tvoid SetNumberOfSampling( Tint nsamples );

  public:
    Tint Clear();
    Tint Update();
    Tint Initialize();
    Tvoid FillData( TDataElement& element, Tint channel );

  private:
    Tshort modifyData( Tlong databuf ) const;

};

inline Tint TVmeDaughterBoardMemoryModule::GetNumberOfSampling() const
{
  return( theNumberOfSampling );
}

inline Tvoid TVmeDaughterBoardMemoryModule::SetNumberOfSampling( Tint nsamples )
{
  theNumberOfSampling = nsamples;
  return;
}

inline Tshort TVmeDaughterBoardMemoryModule::modifyData( Tlong databuf ) const
{
  if ( ( databuf & 0x0000fff0 ) == 0x7ff0 ) {
    // overflow
    return( tDataOverflow );
  } else if ( ( databuf & 0x0000fff0 ) == 0x8000 ) {
    // underflow
    return( tDataUnderflow );
  }
 
  Tshort retval = (Tshort)( databuf & 0x0000fff0 );
  Tbit sign = ( retval & 0x8000 ) >> 15;
  if ( sign == 1 ) {
    // case of negative value
    retval &= 0x7ff0;
    retval = retval >> 4;
  } else if ( sign == 0 ) {
    // case of positive value
    retval = retval >> 4;
    retval += 0x0800;
  } else {
    Tcerr << "TVmeDaughterBoardMemoryModule::modifyData: failed." << Tendl;
  }

  return( retval );
}

#endif
