char *GetRecExtension(void)
{
  TRACEENTER();

  dword                 i;
  tToppyInfo           *ToppyInfo;
  tFWDATHeader         *FWDatHeader;
  static char          *RecExtension = NULL;

  if(RecExtension == NULL)
  {
    if(LoadFirmwareDat(&FWDatHeader, &ToppyInfo, NULL))
    {
      for(i = 0; i < FWDatHeader->NrOfToppyInfoEntries; i++, ToppyInfo++)
      {
        if(ToppyInfo->SysID == TAP_GetSystemId())
        {
          switch(ToppyInfo->RecExtension)
          {
            case 0: RecExtension = ".rec"; break;
            case 1: RecExtension = ".mpg"; break;
              default:
                break;
          }
          break;
        }
      }
    }
  }

  TRACEEXIT();
  return RecExtension ? RecExtension : ".rec";
}
//--------------------------------------- FlashInitialize --------------------------------
//
dword FlashInitialize (dword SystemID)
{
    dword                 i;
    tToppyInfo           *ToppyInfo;
    tFWDATHeader         *FWDatHeader;

    if (FlashOffset != 0) return FlashOffset;

    if (!LibInitialized) InitTAPex ();
    if (!LibInitialized) return 0;

    //Get toppy information
    if (!LoadFirmwareDat(&FWDatHeader, &ToppyInfo, NULL)) return 0;

    for (i = 0; i < FWDatHeader->NrOfToppyInfoEntries; i++, ToppyInfo++)
    {
        if (ToppyInfo->SysID == SystemID)
        {
            SystemType = ToppyInfo->SystemType;
            break;
        }
    }

    //Copy the appropriate offset table
    switch (SystemType)
    {
    case ST_DVBS    :
        memcpy (FlashBlockOffset, FlashBlockOffsetS, (BLOCKS + 1) * sizeof (dword));
        break ;
    case ST_DVBT    :
        memcpy (FlashBlockOffset, FlashBlockOffsetT, (BLOCKS + 1) * sizeof (dword));
        break ;
    case ST_DVBC    :
        memcpy (FlashBlockOffset, FlashBlockOffsetC, (BLOCKS + 1) * sizeof (dword));
        break ;
    case ST_DVBT5700:
        memcpy (FlashBlockOffset, FlashBlockOffsetT5700, (BLOCKS + 1) * sizeof (dword));
        break ;
    default:
        return 0;
    }

    //The following code searches for the start of the Flash in the RAM. It uses the following method:
    //the Flash starts with the CRC which is never 0xFFFF. The word after the CRC is always 0xFFFF and the next word isn't 0xFFFF again.
    if (!(FlashOffset = FIS_vFlash())) return 0;

    //Add the start of the flash to the FlashBlockOffset array to make its address entries absolute.
    for (i = TVServices; i <= BLOCKS; i++) FlashBlockOffset [i] += FlashOffset;

    return FlashOffset;
}
char *GetToppyString(word SysID)
{
  TRACEENTER();

  dword                 i;
  tToppyInfo           *ToppyInfo;
  tFWDATHeader         *FWDatHeader;

  if(LoadFirmwareDat(&FWDatHeader, &ToppyInfo, NULL))
  {
    for(i = 0; i < FWDatHeader->NrOfToppyInfoEntries; i++, ToppyInfo++)
    {
      if(ToppyInfo->SysID == SysID)
      {
        TRACEEXIT();
        return ToppyInfo->Device;
      }
    }
  }

  TRACEEXIT();
  return "???";
}
bool KeyTranslate(bool Enable, void *EventHandler)
{
  tTMSTAPTaskTable     *TMSTAPTaskTable;
  dword                 i;
  tToppyInfo           *ToppyInfo;
  tFWDATHeader         *FWDatHeader;

  TRACEENTER();

  //Get toppy information
  if(LoadFirmwareDat(&FWDatHeader, &ToppyInfo, NULL))
  {
    for(i = 0; i < FWDatHeader->NrOfToppyInfoEntries; i++, ToppyInfo++)
    {
      if(ToppyInfo->SysID == TAP_GetSystemId())
      {
        RemoteType = ToppyInfo->RemoteType;
        break;
      }
    }
  }

  //Get the address to the TAP table
  TMSTAPTaskTable = (tTMSTAPTaskTable*)FIS_vTAPTable();
  if(!TMSTAPTaskTable)
  {
    TRACEEXIT();
    return FALSE;
  }

  //The curTapTask variable is not thread safe. Call InitTAPex() if this function will be called from a sub thread
  if(TAP_TableIndex == 0xffffffff)
  {
    dword                *curTapTask;

    curTapTask = (dword*)FIS_vCurTapTask();
    if(!curTapTask)
    {
      TRACEEXIT();
      return -3;
    }
    TAP_TableIndex = *curTapTask;
  }

  if(Enable && (TMSTAPTaskTable[TAP_TableIndex].TAP_EventHandler == (dword)EventHandler))
  {
    Original_TAP_EventHandler = (void*)TMSTAPTaskTable[TAP_TableIndex].TAP_EventHandler;
    TMSTAPTaskTable[TAP_TableIndex].TAP_EventHandler = (dword)&KeyTranslateHook;

    TRACEEXIT();
    return TRUE;
  }
  else if(!Enable && (TMSTAPTaskTable[TAP_TableIndex].TAP_EventHandler == (dword)KeyTranslateHook))
  {
    TMSTAPTaskTable[TAP_TableIndex].TAP_EventHandler = (dword)Original_TAP_EventHandler;
    Original_TAP_EventHandler = NULL;

    TRACEEXIT();
    return TRUE;
  }

  TRACEEXIT();
  return FALSE;
}