/****************************************************************************
**
**  Name:  trig.c
**
**  Description:
**       Routines to set up the trigger and trace management hardware
**
**  Status:  PRELIMINARY
**
**  $Log:   S:/tbird/mt2_68k/trace/trig.c_v  $
** 
**    Rev 1.7   18 Jun 1997 16:05:22   gene
** 
**    Rev 1.6   25 Apr 1997 18:29:44   gene
** 
**    Rev 1.5   17 Apr 1997 17:23:46   gene
** 
**    Rev 1.4   09 Apr 1997 09:35:32   gene
** 
**    Rev 1.3   24 Mar 1997 08:36:40   gene
** 
**    Rev 1.2   18 Mar 1997 09:04:48   gene
** 
**    Rev 1.1   04 Mar 1997 13:04:44   gene
** 
**    Rev 1.0   13 Feb 1997 09:07:26   gene
** Initial revision.
** 
**    Rev 1.7   21 Jun 1996 14:48:22   kevin
** defined hLib
** 
**    Rev 1.6   26 Dec 1995 11:39:50   kevin
** modified trigEventEnableSet() to get rid of the change of rev 1.4
** 
**    Rev 1.5   20 Dec 1995 13:22:04   kevin
** fixed a bug of trigger level
** 
**    Rev 1.4   18 Dec 1995 14:39:46   kevin
** max number of events is limited to 8
** 
**    Rev 1.3   01 Dec 1995 10:27:48   kevin
** fixed a bug of external-in
** 
**    Rev 1.2   20 Nov 1995 18:09:08   kevin
** supported 4 level of trigger settings
** 
**    Rev 1.0   07 Sep 1995 11:22:28   gene
** Initial revision.
** 
**    Rev 1.62   16 Jul 1993 12:50:18   ernie
** Removed local error defs; use generic errors
** 
**    Rev 1.61   16 Jul 1993 10:18:18   ernie
** Changed abortFromEsc from U16 to BOOLEAN
** 
**    Rev 1.60   13 Jul 1993 09:36:34   ernie
** Changed power-on state of programTrigger to TRUE to force the trigger
** hardware to be programmed the first time GO is used.  This prevents a
** problem seen where an old trigger is left active in the box when
** PowerViews is rebooted but the PowerPack chassis is not.  Now that the
** trigger programming speed is much faster, there is a barely noticeable
** speed difference as the trigger is programmed.
** 
**    Rev 1.59   28 Jun 1993 08:51:00   paul
** Change CHECK_ABORT to TskCheckAbort (esc key support)
** 
**    Rev 1.58   01 Jun 1993 12:28:34   ernie
** Added check for TMOD board present before trying to program it.
** Also changed unused events to have .not=1 as a flag to the firmware
** that the event can remain in its default state.  Improves performance
** greatly.
** 
**    Rev 1.57   05 Jan 1993 15:18:34   courtney
** Removed MemAlloc and related macros (no longer used).
** 
**    Rev 1.56   17 Dec 1992 09:58:18   mindy
** Moved sequencer programming to box to minimize comm link traffic.
** 
**    Rev 1.55   12 Nov 1992 08:13:16   ernie
** Fixed ppr7641.  The timer function worked only when the terminal count
** was greater than 1023 (i.e. when counter 1 was being used).  Changed to
** invoke actions on only timer 0 terminal count if only timer 0 being used.
** 
**    Rev 1.54   25 Oct 1992 11:13:24   mindy
** fixed bug in parse trace mode routine.
** 
**    Rev 1.53   21 Oct 1992 08:07:08   mindy
** a) added sequencer enable flag to prevent enabling sequencer if it is
** 
**    already enabled.  Fixes ppr 6798 and 6830
** b) Made changes to get rid of the two zillion warning messages.
** 
**    Rev 1.52   14 Oct 1992 18:36:42   mindy
** a) fixed ppr6766
** b) fixed ppr6933
** 
**    Rev 1.51   06 Oct 1992 06:39:34   mindy
** add event to notify when number of buffers changed
** 
**    Rev 1.50   23 Sep 1992 06:36:06   mindy
** a) bad counter value is now just a warning because we default counter
**    to max value.
** b) counters now default to 1 not 0.
** c) check counter mode before programming specific actions.
** 
**    Rev 1.49   16 Sep 1992 19:24:56   mindy
** use sdn calls instead of sd
** 
**    Rev 1.48   09 Sep 1992 11:31:26   ernie
** Fixed bug in timer terminal counts when multiple of 1024
** 
**    Rev 1.47   09 Sep 1992 09:52:38   mindy
** added close routines needed
** 
**    Rev 1.46   09 Sep 1992 08:58:56   mindy
** fixed a typo
** 
**    Rev 1.45   09 Sep 1992 08:42:40   mindy
** trig can't reference anything in event during libmain
** 
**    Rev 1.44   08 Sep 1992 16:07:12   doug
** Updated with new events.
** 
**    Rev 1.43   08 Sep 1992 15:58:26   mindy
** changes unknown (john)
** 
**    Rev 1.42   27 Aug 1992 07:16:48   mindy
** a) cleaned up some warnings
** 2) fixed programming trigger problem that actions were being programmed
**    when event was disabled.
** c) if tracing is on then we exit with an error before attempting to
**    disble the sequencer.
** 
**    Rev 1.41   21 Aug 1992 16:17:12   mindy
** a) EVENT_LL still being referenced in callback routine
** b) There's no need to do a clear trace notify after programming trigger - 
** I think trace presenter should not be cleared since user might want to
** view his old trace while he can.
** 
**    Rev 1.40   20 Aug 1992 13:48:58   ernie
** Added handshake on EnableSequencer actions
** 
**    Rev 1.39   18 Aug 1992 06:43:40   mindy
** removed cli program command
** 
**    Rev 1.38   14 Aug 1992 08:52:38   mindy
** put back disable of sequencer
** 
**    Rev 1.37   14 Aug 1992 08:46:28   mindy
** a) register on HL halt and not LL - since user only gets control back
**    after HL halt event happens.  By registering on LL I was slowing 
**    down the source step loop.
** b) When programming the trigger; if the trigger hasn't been modified I
**    still need to enable the sequencer since it is disabled upon getting
**    a halt event.
** c) Need to put disable sequencer in check entry condition routine back.
** 
**    Rev 1.36   11 Aug 1992 09:55:14   mindy
** fixed bug of NEXT never being programmed
** 
**    Rev 1.35   10 Aug 1992 08:20:36   mindy
** replaced initCServer routine for tom's new server registration
** 
**    Rev 1.34   10 Aug 1992 05:49:46   mindy
** No reason to program event if it is never enabled.
** 
**    Rev 1.33   06 Aug 1992 07:17:34   mindy
** a) removed check entry conditions from routines that just change the
**    active level and event pointers
** b) assume trigger is programmed initially by the fw.
** 
**    Rev 1.32   03 Aug 1992 06:26:30   mindy
** if event name is in trigger change modified flag
** 
**    Rev 1.31   24 Jul 1992 14:46:42   doug
** using generic shared data
** 
**    Rev 1.30   17 Jul 1992 13:31:00   mindy
** if user selects NEXT he better have more than one buffer
** 
**    Rev 1.29   11 Jul 1992 15:49:02   courtney
** Callback now gets MakeProcInstance before it is used in event registration.
** 
**    Rev 1.28   10 Jul 1992 08:59:26   mindy
** added include file(s) needed to get rid of 3.1 warnings
** 
**    Rev 1.27   25 Jun 1992 12:29:42   mindy
** a) renamed entry check routine
** b) added a check for trigId being zero before doing cli routines.
** c) moved sdreadmembername and sdwritemembername here
** 
**    Rev 1.26   22 Jun 1992 15:12:28   mindy
** removed swat calls
** 
**    Rev 1.25   15 Jun 1992 08:56:32   mindy
** a) added a routine to check active trigger to see if given event is
**    part of the trigger.
** b) added a flag to determine if program hardware needs to be done.  If
**    no trigger options changed don't need to re-program.
** c) Before allowing any trigger changes make sure tracing is OFF and
**    we automatically disable the sequencer.
** d) When emulation is halted we disable the sequencer.
** e) Changed trigger to have a single globally active trigger - this is
**    the id to use when programming hardware.
** 
**    Rev 1.24   14 May 1992 11:40:58   mindy
** removed GetErrorText routine and added ErrInitDLL call
** 
**    Rev 1.23   13 May 1992 08:10:28   mindy
** get dll handle since cli might not be initialized
** 
**    Rev 1.22   12 May 1992 13:07:36   mindy
** Added trigGetErrorText
** 
**    Rev 1.21   01 May 1992 11:28:14   mindy
** reworded number trace buffer cli output
** 
**    Rev 1.20   28 Apr 1992 08:36:06   mindy
** a) Fixed ppr5361 - added abort support
** b) Change open to use cli's id if cli already opened a trigger setup.
**    !!! Might want to just allow one trigger setup?
** c) Trigger presenter needed access to number of trace buffers - without
**    having to do an open on a trace server.  So added get and set of
**    trace configuration.
** 
**    Rev 1.19   23 Apr 1992 11:27:20   mindy
** a) changed all memory allocation to use TMalloc not MemAlloc
** b) changed all trigger cli commands to no longer use id
** c) added local parsing since cli server doesn't support keywords.
** 
**    Rev 1.18   13 Mar 1992 09:00:38   mindy
** changed cli interface.  Now trigger open keeps the id and all cli commands
** no longer need to pass in the id.
** 
**    Rev 1.17   17 Feb 1992 06:50:46   mindy
** a) added event notification when programming sequencer - this is a signal
** to the trace presenter(s) to clear their display.
** b) now program trigger writes to SD_TRACE_EMPTY to prevent trace presenter(s)
** from reading "old" data from the trigger positions.
** 
**    Rev 1.16   28 Jan 1992 11:36:14   ernie
** 1. Added test for timer terminal count < 1024, in which case only
**    counter 0 is used (terminal count 1 = 0).
** 2. Changed timer chaining logic to not reset sequence level that may
**    already be set up in the sequencer array.
** 
**    Rev 1.15   27 Jan 1992 10:07:50   ernie
** a) exttrig is an active low signal too.
** b) changing bits in sequencer for sequence level only worked for "setting"
**    bits but going from level 1 to 2 didn't work.
** 
**    Rev 1.14   23 Jan 1992 14:03:36   ernie
** we weren't handling programming the sequencer right for seq action.
** 
**    Rev 1.13   22 Jan 1992 13:32:58   courtney
** Added code to LibMain to unlock the heap.
** 
**    Rev 1.12   17 Jan 1992 11:19:20   courtney
** Revised LibMain return type.
** 
**    Rev 1.11   14 Jan 1992 11:43:24   ernie
** If TrigEventNameSet sends in a string of blanks it's not an error
** (this makes it easier for the presenter) but it's also not an event
** name.
** 
**    Rev 1.10   07 Jan 1992 10:11:26   ernie
** a) use BOOLEAN not BOOL
** b) qualifier mode needs to be initialized when trigger created.
** 
**    Rev 1.9   11 Dec 1991 14:54:06   mindy
** a) trig server in its own dll now.
** b) SendCliResults moved to evttmplt.c so there wasn't a circular 
** path of each libraries need to be loaded.
** 
**    Rev 1.8   06 Dec 1991 10:25:58   mindy
** Got rid of global descriptor now use common sd routines in swat.c
** 
**    Rev 1.7   02 Dec 1991 10:56:14   mindy
** a) use global errors for mem lock and alloc errors
** b) when programming evtrec used to put SWAT in timestamp mode.
** 
**    Rev 1.6   26 Nov 1991 11:39:50   mindy
** two commands were added to the trace cli
** 
**    Rev 1.5   20 Nov 1991 10:54:26   mindy
** a) cli indexes changed because the trace search commands were added.
** b) changed a sprintf call to wsprintf - there weren't any obvious problem
**    but to be consistent it was changed.
** 
**    Rev 1.4   15 Nov 1991 15:06:14   mindy
** a) changed error numbering to conform to system numbers.
** b) added cli command routines.
** 
**    Rev 1.3   07 Nov 1991 14:32:26   mindy
** uncommented out new trace features since I got a new version of the fw.
** 
**    Rev 1.2   01 Nov 1991 09:19:54   mindy
** added support for:
** a) timer mode
** b) not condition
** c) using real event server
** 
**    Rev 1.1   02 Oct 1991 12:24:28   ernie
** Completed implementation for PDR2
** 
**    Rev 1.0   28 Aug 1991 11:38:10   ernie
** Initial revision.
** 
**  $Header:   S:/tbird/mt2_68k/trace/trig.c_v   1.7   18 Jun 1997 16:05:22   gene  $
**
**  Copyright (C) 1991 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdlib.h"
#ifndef __STRING_H
#include <string.h>
#endif
#ifndef __CTYPE_H
#include "ctype.h"
#endif
#ifndef _BASEWIND_
#include "basewind.h"
#endif
#ifndef _TRIG_
#include "trig.h"
#endif
#ifndef _ENLIB_
#include "enlib.h"
#endif
#ifndef _EVENT_
#include "event.h"
#endif
#ifndef _EVENTS_
#include "events.h"
#endif
#ifndef _BKPTEXEC_
#include "bkptexec.h"
#endif
#ifndef _CLISRV_
#include "clisrv.h"
#endif
#ifndef _TRACE_
#include "trace.h"
#endif
#ifndef _SDPROBE_
#include "sdprobe.h"
#endif
#ifndef _SSHARED_
#include "sshared.h"
#endif
#ifndef _HEAP_
#include "heap.h"
#endif
#ifndef _HOSTERRS_
#include "hosterrs.h"
#endif
#ifndef _LOCAL_
#include "local.h"
#endif

#ifndef _PVTASK_
#include "pvtask.h"
#endif
#ifndef  _SDS2ABI_
#include "sds2abi.h"
#endif

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

#define INVALID_EVENT_COND (NUM_EVENT_COND+1)
#define NUM_COUNTERS       2

#define TIMER_TEXT "TIMER"
#define COUNT_COUNT_TEXT "COUNTER COUNTER"
#define COUNT_TIMER_TEXT "COUNTER TIMER"
#define TIMER_COUNT_TEXT "TIMER COUNTER"
#define TIMER_TIMER_TEXT "TIMER TIMER"
#define CLOCK_TEXT "CLOCK"
#define MAX_NAME_LENGTH 63

                        /****************************
                         *                          *
                         *    EXTERNAL VARIABLES    *
                         *                          *
                         ****************************/

                        /****************************
                         *                          *
                         *     LOCAL STORAGE        *
                         *                          *
                         ****************************/

HANDLE hLib;
static HANDLE cliServerHandle = 0;       /* return address for CLI results */
/* only one trigger can be open'd in the system (!!!currently) */
DESCRIPTOR trigId=0;
FARPROC lpTrigCallback;
static U16 defNumBuffers=1;
static TRACE_MODE defTraceMode=TRACE_PRE;
static COUNTER_TYPE defCounterMode=COUNT_TIMER;
static BOOLEAN defBreak=FALSE;
static QUAL_MODE defQMode=QUAL_BUS;
static BOOLEAN programTrigger = TRUE;
static BOOLEAN sequencerEnabled = FALSE; 
static U16 extEvent=0;
static BOOLEAN defExtOut=FALSE;
static U8 defModeUnit=0;
ACTION_MASK trc_action[NUM_EVENT_COND][NUM_LEVELS];
                        
                        /****************************
                         *                          *
                         *     LOCAL PROTOTYPES     *
                         *                          *
                         ****************************/
RETCODE CheckTriggerConditions(DESCRIPTOR id);
U16     ConvertCond(EVENT_COND cond);
TRACE_MODE ParseTraceMode(LPSTR ptr);
RETCODE ProgramEvents(TRIGGER FAR *trigger);
RETCODE EXPORT TrigCallback(U32 eventNum);
VOID    TriggerInitialize(TRIGGER FAR *trigger);
RETCODE EnableSequencer(BOOLEAN enable);
RETCODE EXPORT TrigInit(HANDLE hLib);
                        /****************************
                         *                          *
                         *      EXECUTABLE CODE     *
                         *                          *
                         ****************************/
#pragma argsused
int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize,
    LPSTR lpszCmdLine) {
   DESCRIPTOR descEvt;  /* unused return param from EnlRegister */

   hLib = hInstance;
   if (cbHeapSize != 0) UnlockData(0); /* allows heap to grow */
   ErrInitDLL(MODULE_TRIGGER,"trig.dll");
   if((lpTrigCallback=MakeProcInstance((FARPROC)TrigCallback,hInstance))
      !=NULL)
      EnlRegister(EVENT_BKPT_HALTED, 
         (EVCALLBACK)lpTrigCallback, &descEvt);

   {
      TRACE_MODE mode;
      BOOLEAN eBreak;
      char *ptr;
      COUNTER_TYPE cType=COUNT_COUNT;
      QUAL_MODE qType=QUAL_BUS;
      S8 str[128], profile[128];
      U16 numBuf,idx;
      U8 status;

      if(!GetProfileString("PowerViews","pwrviewdir","",profile,
         sizeof(profile))) lstrcpy(profile,"micepack.ini");
      GetPrivateProfileString("TrigInfo","numTraceBuffers","",(LPSTR)str,
         sizeof(str), profile);
      if((ptr=strchr(str,' ')) != NULL) *ptr = '\0';
      numBuf = atoi(str);
      if(numBuf!=defNumBuffers) {
         defNumBuffers = numBuf;
         programTrigger = TRUE;
      }
      GetPrivateProfileString("TrigInfo","traceAlignment","",(LPSTR)str,
         sizeof(str), profile);
      mode = ParseTraceMode(str);
      if( defTraceMode != mode ) {
         defTraceMode = mode;
         programTrigger = TRUE;
      }
      GetPrivateProfileString("TrigInfo","traceBreak","",(LPSTR)str,
	     sizeof(str), profile);
      if(strncmpi(str, "on", strlen(str))==0) 
             eBreak=TRUE;
      else
             eBreak=FALSE;
      status=defBreak;
      if( (status & 0x01) != eBreak ) {
             defBreak &= 0xfe;
             defBreak |= eBreak;
//           programTrigger = TRUE;
      }
      GetPrivateProfileString("TrigInfo","breakOnFull","",(LPSTR)str,
	     sizeof(str), profile);
      if(strncmpi(str, "on", strlen(str))==0) 
	     eBreak = TRUE;
      else
	     eBreak = FALSE;
      status=defBreak;
      if( ((status & 0x02) >> 1) != eBreak ) {
             defBreak &= 0xfd;
             status=eBreak;
             defBreak |= (status << 1);
//           programTrigger = TRUE;
      }

      GetPrivateProfileString("TrigInfo","counterTimer","",(LPSTR)str,
         sizeof(str), profile);
      if (strncmpi(str,COUNT_COUNT_TEXT,lstrlen(str))==0)
         cType = COUNT_COUNT;
      else if(strncmpi(str,COUNT_TIMER_TEXT,lstrlen(str))==0)
         cType = COUNT_TIMER;
      else if(strncmpi(str,TIMER_COUNT_TEXT,lstrlen(str))==0)
         cType = TIMER_COUNT;
      else if(strncmpi(str,TIMER_TIMER_TEXT,lstrlen(str))==0)
         cType = TIMER_TIMER;
      if(defCounterMode!=cType) {
	     defCounterMode = cType;
//           programTrigger = TRUE;
      }

      GetPrivateProfileString("TrigInfo","trigMode","",(LPSTR)str,
         sizeof(str), profile);
      if(strncmpi(str,CLOCK_TEXT,lstrlen(str))==0) qType = QUAL_CLOCK;
      if( defQMode != qType ) {
         defQMode = qType;
         programTrigger = TRUE;
      }

      GetPrivateProfileString("TrigInfo","externalOut","",(LPSTR)str,
	     sizeof(str), profile);
      if(strncmpi(str,"high",lstrlen(str))==0)
             defExtOut = 1;
      else if(strncmpi(str,"high-z",lstrlen(str))==0)
             defExtOut = 2;
      else
             defExtOut = 0;

      iceSetTrigOutAction(defExtOut);

      programTrigger = TRUE;
      defModeUnit=0;
      GetPrivateProfileString("TrigInfo","timer0Unit","",(LPSTR)str,
	     sizeof(str), profile);
      if (strncmpi(str,"s",lstrlen(str))==0)
             defModeUnit = 0x03;
      else if (strncmpi(str,"ms",lstrlen(str))==0)
             defModeUnit = 0x04;
      else if (strncmpi(str,"us",lstrlen(str))==0)
             defModeUnit = 0x05;
      GetPrivateProfileString("TrigInfo","timer1Unit","",(LPSTR)str,
	     sizeof(str), profile);
      if (strncmpi(str,"s",lstrlen(str))==0)
             defModeUnit |= 0x30;
      else if (strncmpi(str,"ms",lstrlen(str))==0)
             defModeUnit |= 0x40;
      else if (strncmpi(str,"us",lstrlen(str))==0)
             defModeUnit |= 0x50;
      programTrigger = TRUE;
      Sds2AbiClearEvent(-1); //clear all events & triggers
      for (idx = 0; idx < NUM_LEVELS; idx++)
           Sds2AbiClearTrig(idx+1);
   }
   
   // Since this version of trigger server is intended to connect with
   // MICEPack so register call back functions

   /* initialize successfully */
    return(TRUE);
}

/**************************************************************************
**
** InitCServer
**
***************************************************************************/
RETCODE EXPORT InitCServer(HANDLE cliHandle, HANDLE dllHandle) {
   CSERVER_NEW_REGISTRATION FAR * msgBufPtr;

   cliServerHandle = cliHandle;
   msgBufPtr =
      (CSERVER_NEW_REGISTRATION FAR *)TMalloc(sizeof(CSERVER_VARIABLE_VALUE));
   if (msgBufPtr == NULL) return(ER_OUT_OF_MEMORY);
   msgBufPtr->stringResourceHandle = dllHandle;
   msgBufPtr->serverNameIndex = 30;
   msgBufPtr->dllNameIndex = 31;
   msgBufPtr->numberOfCommandsIndex = 32;
   msgBufPtr->commandStartIndex = 33;
   SendMessage(cliHandle, CLI_NEW_SVR_REGISTRATION, CLI_NEW_SVR_REGISTRATION,
      (DWORD)msgBufPtr);
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigActionGet
** 
*****************************************************************************/
RETCODE EXPORT TrigActionGet(DESCRIPTOR id, ACTION_MASK FAR *mask) {
   TRIGGER FAR *trigger;
   trigger = (TRIGGER FAR *)id;
   *mask = 
      trigger->fw.action[ConvertCond(trigger->curCond)][trigger->curLevel];
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigActionSet
** 
*****************************************************************************/
RETCODE EXPORT TrigActionSet(DESCRIPTOR id, ACTION_MASK action) {
   TRIGGER FAR *trigger;
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
//   if( (action & TRIG_CONT_MASK)  /* user has selected NEXT action */
//      && (trigger->numTraceBuffers == 1) /* AND only one trace buffer */) {
//      err=ER_MULTI_BUFS_NEEDED;
//      action &= ~TRIG_CONT_MASK;
//   }
   if (action <4) {
      trigger->fw.action[ConvertCond(trigger->curCond)][trigger->curLevel] &=0xfffc;
      trc_action[ConvertCond(trigger->curCond)][trigger->curLevel]&=0xfffc;
   }
   trigger->fw.action[ConvertCond(trigger->curCond)][trigger->curLevel]|=action;
   trc_action[ConvertCond(trigger->curCond)][trigger->curLevel]|=action;
   return(err);
}

/*****************************************************************************
** 
**    TrigActionClear
** 
*****************************************************************************/
RETCODE EXPORT TrigActionClear(DESCRIPTOR id, ACTION_MASK action) {
   TRIGGER FAR *trigger;
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
   trigger->fw.action[ConvertCond(trigger->curCond)][trigger->curLevel]
      &=~action;
   trc_action[ConvertCond(trigger->curCond)][trigger->curLevel]
      &=~action;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrcActionGet
** 
*****************************************************************************/
RETCODE EXPORT TrcActionGet(U8 event, U8 level, ACTION_MASK FAR *mask) {
   *mask = trc_action[event][level];
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigCounterFunctionGet
** 
*****************************************************************************/
RETCODE EXPORT TrigCounterFunctionGet(DESCRIPTOR id, 
                                      COUNTER_TYPE FAR *function) {
   *function = ((TRIGGER FAR *)id)->fw.counterMode;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigCounterFunctionSet
** 
*****************************************************************************/
RETCODE EXPORT TrigCounterFunctionSet(DESCRIPTOR id, COUNTER_TYPE function) {
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   ((TRIGGER FAR *)id)->fw.counterMode = function;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigCounterValueGet
** 
*****************************************************************************/
RETCODE EXPORT TrigCounterValueGet(DESCRIPTOR id, U16 counter,
                                   U32 FAR *value) {
   TRIGGER FAR *trigger;

   trigger = (TRIGGER FAR *)id;
   switch(counter)
     {
      case 0:
           *value=trigger->terminalCount[counter] ;
           break;
      case 1:
           *value=trigger->terminalCount[counter];
           break;
      default:
           return(ER_BAD_COUNTER);
     }
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigCounterValueSet
** 
*****************************************************************************/
RETCODE EXPORT TrigCounterValueSet(DESCRIPTOR id, U16 counter, U32 value){
   TRIGGER FAR *trigger;
   RETCODE err;

   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   if(counter >= NUM_COUNTERS) return(ER_BAD_COUNTER);
   trigger = (TRIGGER FAR *)id;
//   if( value > 0xffffffffL ) {
//       err = ER_MAX_COUNTER_VALUE;
//       value = 0xffffffffL;
//     }
   value = (value == 0) ? 1 : value;
   switch(counter)
     {
      case 0:
           trigger->terminalCount[counter] = value;
           break;
      case 1:
           trigger->terminalCount[counter] = value;
           break;
      default:
           return(ER_BAD_COUNTER);
     }
   return(err);
}

/*****************************************************************************
** 
**    TrigModeUnitGet
** 
*****************************************************************************/
RETCODE EXPORT TrigModeUnitGet(DESCRIPTOR id, U8 counter,
                                   U8 FAR *value) {
   TRIGGER FAR *trigger;
   trigger = (TRIGGER FAR *)id;

   switch(counter)
     {
      case 0:
           *value=trigger->modeUnit & 0x0f ;
           break;
      case 1:
           *value=(trigger->modeUnit & 0xf0) >> 4;
           break;
      default:
           return(ER_BAD_COUNTER);
     }
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigModeUnitSet
** input: counter=0, COUNT0
**                1, COUNT1
** <judy 8/13/96>
*****************************************************************************/
RETCODE EXPORT TrigModeUnitSet(DESCRIPTOR id, U8 counter, U8 value){
   TRIGGER FAR *trigger;
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
   switch(counter)
     {
      case 0:
           trigger->modeUnit &= 0xf0;
           trigger->modeUnit |= (value & 0x0f);
           break;
      case 1:
           trigger->modeUnit &= 0x0f;
           trigger->modeUnit |= ((value << 4) & 0xf0);
           break;
      default:
           return(ER_BAD_COUNTER);
     }
   defModeUnit=trigger->modeUnit;
   return(err);
}

/*****************************************************************************
** 
**    TrigEventClear
** 
*****************************************************************************/
RETCODE EXPORT TrigEventClear(DESCRIPTOR id) {
   TRIGGER FAR *trigger;
   RETCODE err;
   U16 index;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
   index = ConvertCond(trigger->curCond);
   trigger->fw.useEvt[index][trigger->curLevel]=FALSE;
   trigger->fw.useExt[index][trigger->curLevel]=FALSE;
   trigger->fw.action[index][trigger->curLevel]=NULL_MASK;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventEnableGet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventEnableGet(DESCRIPTOR id, BOOLEAN FAR *enableEvt) {
   TRIGGER FAR *trigger;
   U16 index;
   trigger = (TRIGGER FAR *)id;
   index = ConvertCond(trigger->curCond);
   *enableEvt=trigger->fw.useEvt[index][trigger->curLevel];
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigExtGet
** 
*****************************************************************************/
RETCODE EXPORT TrigExtGet(DESCRIPTOR id, BOOLEAN FAR *enableExt) {
   TRIGGER FAR *trigger;
   trigger = (TRIGGER FAR *)id;
   *enableExt = 
      trigger->fw.useExt[ConvertCond(trigger->curCond)][trigger->curLevel];
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigExtEventGet
** 
*****************************************************************************/
RETCODE EXPORT TrigExtEventGet(DESCRIPTOR id, U16 FAR *extIn) {
   RETCODE err;

   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   *extIn = extEvent;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigExtEventSet
** 
*****************************************************************************/
RETCODE EXPORT TrigExtEventSet(DESCRIPTOR id, U16 extIn) {
   RETCODE err;

   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   if ((err = Sds2AbiSetExtEvent(extIn)) != GOOD) return(err);
   extEvent = extIn;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventEnableSet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventEnableSet(DESCRIPTOR id, BOOLEAN enable) {
   TRIGGER FAR *trigger;
   RETCODE err;
   U16 index;

   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
   index = ConvertCond(trigger->curCond);
   trigger->fw.useEvt[index][trigger->curLevel] = enable;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigExtSet
** 
*****************************************************************************/
RETCODE EXPORT TrigExtSet(DESCRIPTOR id, BOOLEAN enable) {
   TRIGGER FAR *trigger;
   RETCODE err;
   
// if (((U16)enable & 0xc0) != 0) {
//    U16 tmp = (U16)enable & 0x3f;
//    tmp <<= 8;
//    if (((U16)enable & 0x40) != 0)
//       tmp |= 0x0001;
//    extEvent = enable;
//    return(Sds2AbiSetExtEvent(tmp));
// }
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
   trigger->fw.useExt[ConvertCond(trigger->curCond)][trigger->curLevel] = enable;
   if (trigger->curCond == EXT_COND)
      trigger->fw.useEvt[ConvertCond(trigger->curCond)][trigger->curLevel] = enable;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventGet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventGet(DESCRIPTOR id, EVENT_COND FAR *event) {
   *event = ((TRIGGER FAR *)id)->curCond;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventNameGet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventNameGet(DESCRIPTOR id, LPSTR eventName, U16 maxLen){
   TRIGGER FAR *trigger;
   U16 index;
   trigger = (TRIGGER FAR *)id;
   if( (index = ConvertCond(trigger->curCond)) >= NUM_EVENTS ) 
      return(ER_ILLEGAL_EVENT);
   if( trigger->eventName[index][trigger->curLevel] != NULL ) {
      if (lstrlen(trigger->eventName[index][trigger->curLevel]) > maxLen) {
         return(ER_NAME_TOO_LONG);
      }
      lstrcpy(eventName,trigger->eventName[index][trigger->curLevel]);
   }
   else
      lstrcpy(eventName,"");
   
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventNameSet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventNameSet(DESCRIPTOR id, LPSTR eventName) {
   LOOP_VAR i;
   TRIGGER FAR *trigger;
   U16 index;
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
   if( (index = ConvertCond(trigger->curCond)) >= NUM_EVENTS ) 
      return(ER_ILLEGAL_EVENT);
   if( trigger->eventName[index][trigger->curLevel] != NULL ) {
      TFree((LPSTR)trigger->eventName[index][trigger->curLevel]);
      trigger->eventName[index][trigger->curLevel] = NULL;
   }
   for(i=0;i<lstrlen(eventName);i++) 
      if( !(isspace(eventName[i])) ) break;
   if( (i == lstrlen(eventName))  /* all spaces */
      || (lstrlen(eventName)== 0) /* no name given */) {
      return(GOOD); 
   }
   if((trigger->eventName[index][trigger->curLevel] = 
       (LPSTR)TMalloc(lstrlen(eventName)+1))==NULL){
      return(ER_OUT_OF_MEMORY);
   }
   lstrcpy(trigger->eventName[index][trigger->curLevel],eventName);
   
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventSet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventSet(DESCRIPTOR id, EVENT_COND event) {
   if( ConvertCond(event) == INVALID_EVENT_COND ) 
      return(ER_ILLEGAL_EVENT);
   ((TRIGGER FAR *)id)->curCond = event;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigFillActionGet
** 
*****************************************************************************/
RETCODE EXPORT TrigFillActionGet(DESCRIPTOR id,U8 action,BOOLEAN FAR *enableBreak) {

   if (action==0)          /* get trace break status */
      *enableBreak=((TRIGGER FAR *)id)->enableBreak & 0x01;
   else                    /* get trace off status */
      *enableBreak = (((TRIGGER FAR *)id)->enableBreak & 0x02) >> 1;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigFillActionSet
** 
*****************************************************************************/
RETCODE EXPORT TrigFillActionSet(DESCRIPTOR id,U8 action,BOOLEAN enableBreak) {
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   if (action == 0){
      ((TRIGGER FAR *)id)->enableBreak &= 0xfe;
      ((TRIGGER FAR *)id)->enableBreak |= (enableBreak & 0x01);
   } else {
      ((TRIGGER FAR *)id)->enableBreak &= 0xfd;
      ((TRIGGER FAR *)id)->enableBreak |= ((enableBreak & 0x01)<<1);
   }
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigSeqLevelGet
** 
*****************************************************************************/
RETCODE EXPORT TrigSeqLevelGet(DESCRIPTOR id, U16 FAR *seqLevel) {
   *seqLevel = ((TRIGGER FAR *)id)->curLevel;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigSeqLevelSet
** 
*****************************************************************************/
RETCODE EXPORT TrigSeqLevelSet(DESCRIPTOR id, U16 seqLevel) {
   ((TRIGGER FAR *)id)->curLevel = seqLevel;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTraceConfigureSet
** 
*****************************************************************************/
RETCODE EXPORT TrigTraceConfigureSet(DESCRIPTOR id, U16 numBuffers) {
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   ((TRIGGER FAR *)id)->numTraceBuffers = numBuffers;
   if((err=EnlEventNotify(EVENT_TRIG_TRC_BUF_NUM)) != GOOD ) return(err); 
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTraceConfigureGet
** 
*****************************************************************************/
RETCODE EXPORT TrigTraceConfigureGet(DESCRIPTOR id, U16 FAR *numBuffers) {
   *numBuffers = ((TRIGGER FAR *)id)->numTraceBuffers;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTraceModeGet
** 
*****************************************************************************/
RETCODE EXPORT TrigTraceModeGet(DESCRIPTOR id, TRACE_MODE FAR *mode) {
   *mode = ((TRIGGER FAR *)id)->traceMode;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTraceModeSet
** 
*****************************************************************************/
RETCODE EXPORT TrigTraceModeSet(DESCRIPTOR id, TRACE_MODE mode) {
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   ((TRIGGER FAR *)id)->traceMode = mode;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTriggerClear
** 
*****************************************************************************/
RETCODE EXPORT TrigTriggerClear(DESCRIPTOR id) {
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   TriggerInitialize(((TRIGGER FAR *)id));
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTriggerClose
** 
*****************************************************************************/
RETCODE EXPORT TrigTriggerClose(DESCRIPTOR id) {
   RETCODE err;

   if (trigId==0L)
      return(GOOD);
//   trigger = (TRIGGER FAR *)id;
   if ( ((TRIGGER FAR *)id)->trigModified ) {
      if ((err=TrigTriggerAccept(id))!=GOOD) return(err);
   }
/*
   if( (err=EvtCloseEvent(((TRIGGER FAR *)id)->eventServerId)) != GOOD )
      return(err);
   TFree((LPSTR)id);
   trigId = 0;
*/
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTriggerOpen
** 
*****************************************************************************/
RETCODE EXPORT TrigTriggerOpen(DESCRIPTOR FAR *id, LPSTR fileName,
                               LPSTR templateName) {
   TRIGGER FAR *trigger;
   RETCODE err;
   int hFile;
   if( trigId ) {
      *id = trigId;
      return(GOOD);
   }
   if((*id = (DESCRIPTOR)TMalloc(sizeof(TRIGGER))) == NULL) 
      return(ER_OUT_OF_MEMORY);
   trigger = (TRIGGER FAR *) *id;
   if (fileName && (lstrlen(fileName) > 0)) {
      if((hFile = _lopen(fileName,OF_READ)) == -1) return(ER_CANT_OPEN_FILE);
      if(_lread(hFile,(LPSTR)trigger,sizeof(*trigger)) != sizeof(*trigger))
         return(ER_READING_FILE);
      if(_lclose(hFile) == -1) return(ER_CANT_CLOSE_FILE);
      trigger->curCond = EV0_COND;
      trigger->curLevel = 0;
   }
   else {
      TriggerInitialize(trigger);
      trigger->numTraceBuffers = defNumBuffers;
      trigger->traceMode = defTraceMode;
      trigger->fw.counterMode = defCounterMode;
      trigger->enableBreak = defBreak;
      trigger->qualifierMode = defQMode;
      trigger->trigModified = programTrigger;
   }
   if( (err=EvtOpenEvent(&trigger->eventServerId,templateName)) != GOOD ) 
      return(err);
   trigId = *id;
   return(GOOD);
}

RETCODE EXPORT TrigCallback(U32 eventNum) {
   if( eventNum == EVENT_BKPT_HALTED ) {
      EnableSequencer(FALSE);
   }
   return(GOOD);  /* error ignored anyway! */
}

/*****************************************************************************
** 
**    TrigTriggerProgram
** 
*****************************************************************************/
RETCODE EXPORT TrigTriggerProgram(VOID) {
   RETCODE err;
   TRIGGER FAR *trigger;
   U32 tc0, tc1;
   BOOLEAN true=TRUE, timedOut, enable;
   BOOLEAN abortFromEsc;
   
   /* if trigger not open'd assume there's nothing to program */
   if( !trigId ) {
      if((err=TrigTriggerOpen(&trigId,"","default"))!=GOOD) return(err);
   }
   trigger = (TRIGGER FAR *)trigId;
   if( !trigger->trigModified ) {
      /* even if we didn't need to reprogram trigger we need to make
         suer the sequencer is enabled
       */
      if( !sequencerEnabled ) return(EnableSequencer(TRUE));
      return(GOOD);
   }
   if ((err=CheckTriggerConditions(trigId))!=GOOD) return(err);
   if ((err = EnableSequencer(FALSE)) != GOOD) return(err);

   enable=TRUE;
   if((err=SdnWriteMember(SDN_TRIGOUT_ENABLE,&enable,GOOD))!=GOOD)
      return(err);
   if((err=SdnWriteMember(SDN_QUAL_MODE,(U8 FAR *)&trigger->qualifierMode,
      GOOD))!=GOOD) return(err); 
   if((err=SdnWriteMember(SDN_NUM_TRCBUFS,(U8 FAR *)&trigger->numTraceBuffers,
      GOOD)) !=GOOD) return(err);
   if((err=SdnWriteMember(SDN_BRK_ON_TRACE_FULL,&trigger->enableBreak,GOOD))
      !=GOOD)return(err);
   if((err=SdnWriteMember(SDN_TRACE_MODE,(U8 FAR *)&trigger->traceMode,
      GOOD))!=GOOD) return(err);

   /*
   ** If in timer mode, we need to detect least significant bits = 0
   ** (timer terminal count is a multiple of 1024), but the hardware
   ** cannot do this.  So we kludge it by changing the timer terminal
   ** count to be one greater than a multiple of 1024.
   */

   tc0 = trigger->terminalCount[0];
   tc1 = trigger->terminalCount[1];

   if((err=SdnWriteMember(SDN_TERMINAL_COUNT_A,(U8 FAR *)&tc0,GOOD)) != GOOD)
      return(err);
   if((err=SdnWriteMember(SDN_TERMINAL_COUNT_B,(U8 FAR *)&tc1,GOOD)) != GOOD) 
      return(err);

   /* program event recognizers */
   if( (err=ProgramEvents(trigger)) != GOOD ) return(err);


   err = TskCheckAbort(&abortFromEsc);
   if(err!=GOOD) return err;
   if (abortFromEsc)
      return(ER_ABORT_FROM_ESC);


   /* Let firmware program trigger sequencer information */

   if((err = SdnWriteCmdChkAbortReadResponse(SDN_TRIGGER_INFO,
      &trigger->fw,GOOD,SDN_TRIGGER_PROG_ABORT, &true, GOOD,
      SDN_TRIGGER_PROGRAM_ACK, 60, &timedOut)) != GOOD)
      return(err);
   if ((err = EnableSequencer(TRUE)) != GOOD) return(err);
   /* need to prevent the trace presenter from reading trigger values
      until we are completely done programming trigger. This is
      sort of a kludge.
    */
   trigger->trigModified = FALSE;  /* programmed latest trig setup */
   if((err=SdnWriteMember(SDN_TRACE_EMPTY,&enable,GOOD))!= GOOD ) return(err);
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigTriggerSaveAs
** 
*****************************************************************************/
RETCODE EXPORT TrigTriggerSaveAs(DESCRIPTOR id, LPSTR fileName) {
   TRIGGER FAR *trigger;
   int hFile;
   trigger = (TRIGGER FAR *)id;
   if((hFile = _lcreat(fileName,0)) == -1) return(ER_CANT_OPEN_FILE);
   if(_lwrite(hFile,(LPSTR)trigger,sizeof(*trigger)) != sizeof(*trigger))
      return(ER_WRITING_FILE);
   if(_lclose(hFile) == -1) return(ER_CANT_CLOSE_FILE);
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigQualifierGet
** 
*****************************************************************************/
RETCODE EXPORT TrigQualifierGet(DESCRIPTOR id, QUAL_MODE FAR *mode) {
   *mode = ((TRIGGER FAR *)id)->qualifierMode;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigQualifierSet
** 
*****************************************************************************/
RETCODE EXPORT TrigQualifierSet(DESCRIPTOR id, QUAL_MODE mode) {
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   ((TRIGGER FAR *)id)->qualifierMode = mode;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventServerGet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventServerGet(DESCRIPTOR id, DESCRIPTOR FAR *serverId) {
   *serverId = ((TRIGGER FAR *)id)->eventServerId;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventServerSet
** 
*****************************************************************************/
RETCODE EXPORT TrigEventServerSet(DESCRIPTOR id, DESCRIPTOR serverId) {
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   ((TRIGGER FAR *)id)->eventServerId = serverId;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigEventInTrigger
** 
*****************************************************************************/
RETCODE EXPORT TrigEventInTrigger(LPSTR event, BOOLEAN FAR *found) {
   LOOP_VAR evt, level;
   TRIGGER FAR *trigger;
   *found = FALSE;
   if( !trigId ) return(GOOD);  
   trigger = (TRIGGER FAR *)trigId;
   for(evt=0; evt<NUM_EVENTS; evt++) {
      if( trigger->eventName[evt][trigger->curLevel]==NULL) continue;
      if( lstrcmp(event,trigger->eventName[evt][trigger->curLevel]) == 0 ) {
         for( level = 0; level < NUM_LEVELS; level++ ) {
            if( trigger->fw.useEvt[evt][level] ) {
               *found = TRUE;
               /* if event in question is in trigger assume user is changing
                  it and thus the trigger needs to be reprogramed before 
                  next start of emulation.
                */
               trigger->trigModified = TRUE;
               break;
            }
         }
      }
   }
   return(GOOD);
}

/*************************** CLI FUNCTIONS ******************************/
RETCODE HandleTrueFalse(BOOLEAN value) {
   S8 resultBuff[128];
   if( value ) lstrcpy(resultBuff,"TRUE");
   else lstrcpy(resultBuff,"FALSE");
   return(SendCliResults(resultBuff,cliServerHandle));
}
   
//#define SEQ_MASK_TEXT "SEQ"
//#define RESET_MASK_TEXT "RESET"
//#define TRIG_CONT_MASK_TEXT "NEXT"
//#define TRIG_HALT_MASK_TEXT "TOFF"
//#define EM_BRK_MASK_TEXT "BRK"
//#define INC0_MASK_TEXT "INC0"
//#define INC1_MASK_TEXT "INC1"
//#define RST0_MASK_TEXT "RST0"
//#define RST1_MASK_TEXT "RST1"
//#define START_TMR_MASK_TEXT "START_TMR"
//#define STOP_TMR_MASK_TEXT "STOP_TMR"
//#define RST_TMR_MASK_TEXT "RST_TMR"
//#define EXT_TRIG_ON_TEXT "EXT_ON"
//#define EXT_TRIG_OFF_TEXT "EXT_OFF"

#define  LV0_MASK_TEXT               "LV0"
#define  LV1_MASK_TEXT               "LV1"
#define  LV2_MASK_TEXT               "LV2"
#define  LV3_MASK_TEXT               "LV3"
#define  BRK_MASK_TEXT               "BRK"
#define  TC0_RST_MASK_TEXT           "RST0"
#define  TC1_RST_MASK_TEXT           "RST1"
#define  TMR0_START_MASK_TEXT        "TM0_ON"
#define  TMR1_START_MASK_TEXT        "TM1_ON"
#define  TMR0_STOP_MASK_TEXT         "TM0_OFF"
#define  TMR1_STOP_MASK_TEXT         "TM1_OFF"
#define  CNT0_INC_MASK_TEXT          "INC0"
#define  CNT1_INC_MASK_TEXT          "INC1"
#define  TRC_DIS_MASK_TEXT           "TRC_END"
#define  TRC_START_MASK_TEXT         "TRC_ON"
#define  TRC_STOP_MASK_TEXT          "TRC_OFF"
#define  TRC_QUAL_MASK_TEXT          "TRC_IN"
#define  TRIG_OUT_MASK_TEXT          "TRIG_OUT"

ACTION_MASK ParseTriggerActionParm(LPSTR ptr) {
   ACTION_MASK mask=0xFFFF;

   if(strncmpi(ptr,LV0_MASK_TEXT,lstrlen(ptr))==0)
      mask = LV0_MASK;
   else if(strncmpi(ptr,LV1_MASK_TEXT,lstrlen(ptr))==0)
      mask = LV1_MASK;
   else if(strncmpi(ptr,LV2_MASK_TEXT,lstrlen(ptr))==0)
      mask = LV2_MASK;
   else if(strncmpi(ptr,LV3_MASK_TEXT,lstrlen(ptr))==0)
      mask = LV3_MASK;
   else if(strncmpi(ptr,BRK_MASK_TEXT,lstrlen(ptr))==0)
      mask = BRK_MASK;
   else if(strncmpi(ptr,TC0_RST_MASK_TEXT,lstrlen(ptr))==0)
      mask = TC0_RST_MASK;
   else if(strncmpi(ptr,TC1_RST_MASK_TEXT,lstrlen(ptr))==0)
      mask = TC1_RST_MASK;
   else if(strncmpi(ptr,TMR0_START_MASK_TEXT,lstrlen(ptr))==0)
      mask = TMR0_START_MASK;
   else if(strncmpi(ptr,TMR1_START_MASK_TEXT,lstrlen(ptr))==0)
      mask = TMR1_START_MASK;
   else if(strncmpi(ptr,TMR0_STOP_MASK_TEXT,lstrlen(ptr))==0)
      mask = TMR0_STOP_MASK;
   else if(strncmpi(ptr,TMR1_STOP_MASK_TEXT,lstrlen(ptr))==0)
      mask = TMR1_STOP_MASK;
   else if(strncmpi(ptr,CNT0_INC_MASK_TEXT,lstrlen(ptr))==0)
      mask = CNT0_INC_MASK;
   else if(strncmpi(ptr,CNT1_INC_MASK_TEXT,lstrlen(ptr))==0)
      mask = CNT1_INC_MASK;
   else if(strncmpi(ptr,TRC_DIS_MASK_TEXT,lstrlen(ptr))==0)
      mask = TRC_DIS_MASK;
   else if(strncmpi(ptr,TRC_START_MASK_TEXT,lstrlen(ptr))==0)
      mask = TRC_START_MASK;
   else if(strncmpi(ptr,TRC_STOP_MASK_TEXT,lstrlen(ptr))==0)
      mask = TRC_STOP_MASK;
   else if(strncmpi(ptr,TRC_QUAL_MASK_TEXT,lstrlen(ptr))==0)
      mask = TRC_QUAL_MASK;
   else if(strncmpi(ptr,TRIG_OUT_MASK_TEXT,lstrlen(ptr))==0)
      mask = TRIG_OUT_MASK;
   return(mask);
}

VOID PrintTriggerAction(ACTION_MASK mask, LPSTR resultBuff) {
   COUNTER_TYPE type;

   if( (mask & LV3_MASK) ==LV3_MASK )
     lstrcat(resultBuff,LV3_MASK_TEXT);
   else if( (mask & LV2_MASK)==LV2_MASK )
     lstrcat(resultBuff,LV2_MASK_TEXT);
   else if( (mask & LV1_MASK)==LV1_MASK )
     lstrcat(resultBuff,LV1_MASK_TEXT);
   else if( (mask & LV0_MASK)==LV0_MASK )
     lstrcat(resultBuff,LV0_MASK_TEXT);

   if( (mask & BRK_MASK)==BRK_MASK )
      lstrcat(resultBuff,
            lstrlen(resultBuff) ? "|"BRK_MASK_TEXT : BRK_MASK_TEXT);

   if( (mask & TC0_RST_MASK)==TC0_RST_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TC0_RST_MASK_TEXT : TC0_RST_MASK_TEXT);
   if( (mask & TC1_RST_MASK)==TC1_RST_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TC1_RST_MASK_TEXT : TC1_RST_MASK_TEXT);
   TrigCounterFunctionGet(trigId, &type);
   if(type==COUNT_TIMER || type == TIMER_TIMER) {
     if( (mask & TMR0_START_MASK)==TMR0_START_MASK )
         lstrcat(resultBuff, lstrlen(resultBuff) ?
         "|"TMR0_START_MASK_TEXT : TMR0_START_MASK_TEXT);
     if( (mask & TMR0_STOP_MASK)==TMR0_STOP_MASK )
         lstrcat(resultBuff,lstrlen(resultBuff) ?
         "|"TMR0_STOP_MASK_TEXT : TMR0_STOP_MASK_TEXT);
   } else {
     if( (mask & CNT0_INC_MASK)==CNT0_INC_MASK )
         lstrcat(resultBuff, lstrlen(resultBuff) ?
         "|"CNT0_INC_MASK_TEXT : CNT0_INC_MASK_TEXT);
   }
   if(type==TIMER_COUNT || type == TIMER_TIMER) {
   if( (mask & TMR1_START_MASK)==TMR1_START_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TMR1_START_MASK_TEXT : TMR1_START_MASK_TEXT);
   if( (mask & TMR1_STOP_MASK)==TMR1_STOP_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TMR1_STOP_MASK_TEXT : TMR1_STOP_MASK_TEXT);
   } else {
      if( (mask & CNT1_INC_MASK)==CNT1_INC_MASK ) lstrcat(resultBuff,
         lstrlen(resultBuff) ? "|"CNT1_INC_MASK_TEXT : CNT1_INC_MASK_TEXT);
   }

   if( (mask & TRC_DIS_MASK)==TRC_DIS_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TRC_DIS_MASK_TEXT : TRC_DIS_MASK_TEXT);
   if( (mask & TRC_START_MASK)==TRC_START_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TRC_START_MASK_TEXT : TRC_START_MASK_TEXT);
   if( (mask & TRC_STOP_MASK)==TRC_STOP_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TRC_STOP_MASK_TEXT : TRC_STOP_MASK_TEXT);
   if( (mask & TRC_QUAL_MASK)==TRC_QUAL_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TRC_QUAL_MASK_TEXT : TRC_QUAL_MASK_TEXT);
   if( (mask & TRIG_OUT_MASK)==TRIG_OUT_MASK ) lstrcat(resultBuff,
      lstrlen(resultBuff) ? "|"TRIG_OUT_MASK_TEXT : TRIG_OUT_MASK_TEXT);
}

RETCODE EXPORT TrigCliAction(LPSTR cmdString, U32 argc, U32 argv[]) {
   ACTION_MASK mask=0,curMask;
   S8 resultBuff[128];
   U16 arg;
   RETCODE err;

   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc >= 2 ) {
      if( (err=TrigActionGet(trigId,&mask)) != GOOD )
         return(err);
      if ((mask & 0x03) ==0 ) {
         TrigSeqLevelGet(trigId, &curMask);
         if( (err=TrigActionSet(trigId,curMask)) != GOOD ) return(err);
      }
      for(arg=1; arg<argc; arg++) {
         curMask=ParseTriggerActionParm(&(cmdString[(U16)argv[arg]]));
         if (curMask == 0xFFFF)
            return(ER_INVALID_ACTION);

         if( (err=TrigActionSet(trigId,curMask)) != GOOD )
            return(err);
      }
   }
   if( (err=TrigActionGet(trigId,&mask)) != GOOD )
      return(err);
   resultBuff[0] = '\0';
   PrintTriggerAction(mask, resultBuff);
   return(SendCliResults(resultBuff,cliServerHandle));
}

RETCODE EXPORT TrigCliClearAction(LPSTR cmdString, U32 argc, U32 argv[]) {
   ACTION_MASK mask=0, curMask;
   S8 resultBuff[128];
   U16 arg;
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc >= 2 ) {
      for(arg=1; arg<argc; arg++) {
         if((curMask=ParseTriggerActionParm(&(cmdString[(U16)argv[arg]])))==0)
            return(ER_INVALID_ACTION);
         else
            mask |= curMask;
      }
      if( (err=TrigActionClear(trigId,mask)) != GOOD ) 
         return(err);
   }
   if( (err=TrigActionGet(trigId,&mask)) != GOOD )
      return(err);
   resultBuff[0] = '\0';
   PrintTriggerAction(mask, resultBuff);
   return(SendCliResults(resultBuff,cliServerHandle));
}

#define COUNTERS_TEXT "COUNTERS"
#define TIMER_TEXT "TIMER"
RETCODE EXPORT TrigCliCounterFunction(LPSTR cmdString, U32 argc, U32 argv[]) {
   COUNTER_TYPE type=COUNT_COUNT;
   S8 resultBuff[128];
   LPSTR ptr;
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      ptr = &cmdString[(U16)argv[1]];
      if(strncmpi(ptr,COUNT_COUNT_TEXT,lstrlen(ptr))==0)
         type = COUNT_COUNT;
      else if(strncmpi(ptr,COUNT_TIMER_TEXT,lstrlen(ptr))==0)
         type = COUNT_TIMER;
      else if(strncmpi(ptr,TIMER_COUNT_TEXT,lstrlen(ptr))==0)
         type = TIMER_COUNT;
      else if(strncmpi(ptr,TIMER_TIMER_TEXT,lstrlen(ptr))==0)
         type = TIMER_TIMER;
      if( (err=TrigCounterFunctionSet(trigId,type)) != GOOD ) return(err);
   }
   if( (err=TrigCounterFunctionGet(trigId,&type)) != GOOD )
      return(err);
   if( type == COUNT_COUNT ) lstrcpy(resultBuff,COUNT_COUNT_TEXT);
   else if( type == COUNT_TIMER ) lstrcpy(resultBuff,COUNT_TIMER_TEXT);
   else if( type == TIMER_COUNT ) lstrcpy(resultBuff,TIMER_COUNT_TEXT);
   else if( type == TIMER_TIMER ) lstrcpy(resultBuff,TIMER_TIMER_TEXT);
   else lstrcpy(resultBuff,"NOT SPECIFIED");
   return(SendCliResults(resultBuff,cliServerHandle));
}

RETCODE EXPORT TrigCliCounterValue(LPSTR cmdString, U32 argc, U32 argv[]) {
   U32 value;
   S8 resultBuff[128];
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 3 ) {
      if( (err=TrigCounterValueSet(trigId,
                  atoi(&cmdString[(U16)argv[1]]),
                  atoi(&cmdString[(U16)argv[2]])))!=GOOD)
         return(err);
   }
   else if( argc != 2 ) return(ER_CLI_SYNTAX);
   if( (err=TrigCounterValueGet(trigId,
                                atoi(&cmdString[(U16)argv[1]]),&value))!=GOOD)
      return(err);
   wsprintf(resultBuff,"%ld", value);
   return(SendCliResults(resultBuff,cliServerHandle));
}

/*****************************************************************************
** 
**    TrigFree
** 
*****************************************************************************/
RETCODE EXPORT TrigTriggerFree() {
   RETCODE err;

   if (trigId==0L)
      return(GOOD);
   if( (err=EvtCloseEvent(((TRIGGER FAR *)trigId)->eventServerId)) != GOOD )
      return(err);
   TFree((LPSTR)trigId);
   trigId = 0;
   return(GOOD);
}

#pragma argsused
RETCODE EXPORT TrigCliClearEvent(LPSTR cmdString, U32 argc, U32 argv[]) {
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   return(TrigEventClear(trigId));
}

RETCODE EXPORT TrigCliEventEnable(LPSTR cmdString, U32 argc, U32 argv[]) {
   BOOLEAN value;
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      value = ParseBoolean(&cmdString[(U16)argv[1]]);
      if( (err=TrigEventEnableSet(trigId,value)) != GOOD ) return(err);
   }
   if( (err=TrigEventEnableGet(trigId,&value)) != GOOD )
      return(err);
   return(HandleTrueFalse(value));
}

RETCODE EXPORT TrigCliExt(LPSTR cmdString, U32 argc, U32 argv[]) {
   BOOLEAN value;
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      value = ParseBoolean(&cmdString[(U16)argv[1]]);
      if( (err=TrigExtSet(trigId,value)) != GOOD ) return(err);
   }
   if( (err=TrigExtGet(trigId,&value)) != GOOD )
      return(err);
   return(HandleTrueFalse(value));
}

#define EV0_COND_TEXT "EV0"
#define EV1_COND_TEXT "EV1"
#define EV2_COND_TEXT "EV2"
#define EV3_COND_TEXT "EV3"
#define EV4_COND_TEXT "EV4"
#define EV5_COND_TEXT "EV5"
#define EV6_COND_TEXT "EV6"
#define EV7_COND_TEXT "EV7"
#define TC0_COND_TEXT "TC0"
#define TC1_COND_TEXT "TC1"
#define EXT_COND_TEXT "EXT"
EVENT_COND ParseEventConditionParm(LPSTR ptr) {
   EVENT_COND mask=0;
   if(strncmpi(ptr,EV0_COND_TEXT,lstrlen(ptr))==0)
      mask = EV0_COND;
   else if(strncmpi(ptr,EV1_COND_TEXT,lstrlen(ptr))==0)
      mask = EV1_COND;
   else if(strncmpi(ptr,EV2_COND_TEXT,lstrlen(ptr))==0)
      mask = EV2_COND;
   else if(strncmpi(ptr,EV3_COND_TEXT,lstrlen(ptr))==0) 
      mask = EV3_COND;
   else if(strncmpi(ptr,EV4_COND_TEXT,lstrlen(ptr))==0)
      mask = EV4_COND;
   else if(strncmpi(ptr,EV5_COND_TEXT,lstrlen(ptr))==0)
      mask = EV5_COND;
   else if(strncmpi(ptr,EV6_COND_TEXT,lstrlen(ptr))==0)
      mask = EV6_COND;
   else if(strncmpi(ptr,EV7_COND_TEXT,lstrlen(ptr))==0)
      mask = EV7_COND;
   else if(strncmpi(ptr,TC0_COND_TEXT,lstrlen(ptr))==0)
      mask = TC0_COND;
   else if(strncmpi(ptr,TC1_COND_TEXT,lstrlen(ptr))==0)
      mask = TC1_COND;
   else if(strncmpi(ptr,EXT_COND_TEXT,lstrlen(ptr))==0)
      mask = EXT_COND;
   return(mask);
}

RETCODE EXPORT TrigCliEvent(LPSTR cmdString, U32 argc, U32 argv[]) {
   EVENT_COND event;
   S8 resultBuff[128];
   LPSTR ptr;
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      if( (event = ParseEventConditionParm(&cmdString[(U16)argv[1]])) == 0 )
         return(ER_INVALID_EVENT);
      if( (err=TrigEventSet(trigId,event)) != GOOD ) 
         return(err);
   }
   if( (err=TrigEventGet(trigId,&event)) != GOOD )
      return(err);
   switch(event) {
      case EV0_COND: ptr = EV0_COND_TEXT; break;
      case EV1_COND: ptr = EV1_COND_TEXT; break;
      case EV2_COND: ptr = EV2_COND_TEXT; break;
      case EV3_COND: ptr = EV3_COND_TEXT; break;
      case EV4_COND: ptr = EV4_COND_TEXT; break;
      case EV5_COND: ptr = EV5_COND_TEXT; break;
      case EV6_COND: ptr = EV6_COND_TEXT; break;
      case EV7_COND: ptr = EV7_COND_TEXT; break;
      case TC0_COND: ptr = TC0_COND_TEXT; break;
      case TC1_COND: ptr = TC1_COND_TEXT; break;
      case EXT_COND: ptr = EXT_COND_TEXT; break;
      default: ptr = "BAD EVENT"; break;
   }
   lstrcpy(resultBuff,ptr);
   return(SendCliResults(resultBuff,cliServerHandle));
}

RETCODE EXPORT TrigCliEventName(LPSTR cmdString, U32 argc, U32 argv[]) {
   S8 resultBuff[128];
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      if( (err=TrigEventNameSet(trigId,
                           &cmdString[(U16)argv[1]])) != GOOD ) return(err);
   }
   if((err=TrigEventNameGet(trigId,resultBuff,128))!=GOOD)
      return(err);
   return(SendCliResults(resultBuff,cliServerHandle));
}

RETCODE EXPORT TrigCliEventServer(LPSTR cmdString, U32 argc, U32 argv[]) {
   DESCRIPTOR eventId;
   S8 resultBuff[128];
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      if( (err=TrigEventServerSet(trigId, 
                                  atoi(&cmdString[(U16)argv[1]]))) != GOOD ) 
      return(err);
   }
   if( (err=TrigEventServerGet(trigId,&eventId)) != GOOD )
      return(err);
   wsprintf(resultBuff,"%d", eventId);
   return(SendCliResults(resultBuff,cliServerHandle));
}

RETCODE EXPORT TrigCliBreakFull(LPSTR cmdString, U32 argc, U32 argv[]) {
   BOOLEAN value;
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      value = ParseBoolean(&cmdString[(U16)argv[1]]);
      if( (err=TrigFillActionSet(trigId,0,value))!=GOOD) return(err);
   }
   if( (err=TrigFillActionGet(trigId,0,&value)) != GOOD ) return(err);
   return(HandleTrueFalse(value));
}

#define BUS_TEXT "BUS"

RETCODE EXPORT TrigCliQualifier(LPSTR cmdString, U32 argc, U32 argv[]) {
   QUAL_MODE type=QUAL_BUS;
   S8 resultBuff[128];
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      if(strncmpi(&cmdString[(U16)argv[1]],CLOCK_TEXT,
         lstrlen(&cmdString[(U16)argv[1]]))==0) type = QUAL_CLOCK;  
      if( (err=TrigQualifierSet(trigId,type)) != GOOD ) return(err);
   }
   if( (err=TrigQualifierGet(trigId,&type)) != GOOD )
      return(err);
   if( type == QUAL_CLOCK ) lstrcpy(resultBuff,CLOCK_TEXT);
   else lstrcpy(resultBuff,BUS_TEXT);
   return(SendCliResults(resultBuff,cliServerHandle));
}

RETCODE EXPORT TrigCliSeqLevel(LPSTR cmdString, U32 argc, U32 argv[]) {
   U16 level;
   S8 resultBuff[128];
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      if( (err=TrigSeqLevelSet(trigId, 
                                  atoi(&cmdString[(U16)argv[1]]))) != GOOD ) 
      return(err);
   }
   if( (err=TrigSeqLevelGet(trigId,&level)) != GOOD )
      return(err);
   wsprintf(resultBuff,"%d", level);
   return(SendCliResults(resultBuff,cliServerHandle));
}

RETCODE EXPORT TrigCliTraceConfigure(LPSTR cmdString, U32 argc, U32 argv[]) {
   U16 num;
   S8 resultBuff[128];
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      if( (err=TrigTraceConfigureSet(trigId, 
                                  atoi(&cmdString[(U16)argv[1]]))) != GOOD ) 
      return(err);
   }
   if( (err=TrigTraceConfigureGet(trigId,&num)) != GOOD )
      return(err);
   if( num == 1 )
      lstrcpy(resultBuff,"1 trace buffer");
   else
      wsprintf(resultBuff,"%d trace buffers", num);
   return(SendCliResults(resultBuff,cliServerHandle));
}

#define PRE_TEXT "PRE"
#define POST_TEXT "POST"
#define CENTER_TEXT "CENTER"

TRACE_MODE ParseTraceMode(LPSTR ptr) {
   TRACE_MODE mode=-1;
   if(strncmpi(ptr,PRE_TEXT,lstrlen(ptr))==0)
      mode = TRACE_PRE;
   else if(strncmpi(ptr,POST_TEXT,lstrlen(ptr))==0)
      mode = TRACE_POST;
   else if(strncmpi(ptr,CENTER_TEXT,lstrlen(ptr))==0)
      mode = TRACE_CENTER;
   return(mode);
}

RETCODE EXPORT TrigCliTraceMode(LPSTR cmdString, U32 argc, U32 argv[]) {
   TRACE_MODE mode;
   S8 resultBuff[128];
   RETCODE err;
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc == 2 ) {
      if( (mode = ParseTraceMode(&cmdString[(U16)argv[1]])) == -1 )
         return(ER_INVALID_MODE);      
      if( (err=TrigTraceModeSet(trigId,mode)) != GOOD ) return(err);
   }
   if( (err=TrigTraceModeGet(trigId,&mode)) != GOOD )
      return(err);
   if( mode == TRACE_PRE ) lstrcpy(resultBuff,PRE_TEXT);
   else if( mode == TRACE_POST ) lstrcpy(resultBuff,POST_TEXT);
   else lstrcpy(resultBuff,CENTER_TEXT);
   return(SendCliResults(resultBuff,cliServerHandle));
}

#pragma argsused
RETCODE EXPORT TrigCliClearTrigger(LPSTR cmdString, U32 argc, U32 argv[]) {
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   return(TrigTriggerClear(trigId));
}

#pragma argsused
RETCODE EXPORT TrigCliClose( LPSTR cmdString, U32 argc, U32 argv[] ) {
   RETCODE err=GOOD;
   if( trigId ) {
      err = TrigTriggerClose(trigId);
//      trigId = 0;
   }
   return(err);
}

RETCODE EXPORT TrigCliOpen( LPSTR cmdString, U32 argc, U32 argv[] ) {
   RETCODE err;

//   if( trigId ) {
//      if((err=TrigTriggerClose(trigId))!=GOOD) return(err);
//      trigId = 0;
//   }
   if( argc != 2 ) return(ER_CLI_SYNTAX);
   return(TrigTriggerOpen(&trigId,NULL,&cmdString[(U16)argv[1]]));
}

RETCODE EXPORT TrigCliSave(LPSTR cmdString, U32 argc, U32 argv[]) {
   if( !trigId ) return(ER_NO_TRIG_DEFINED);
   if( argc != 2 ) return(ER_CLI_SYNTAX);
   return(TrigTriggerSaveAs(trigId,&cmdString[(U16)argv[1]]));
}

/****************************** LOCAL FUNCTIONS *****************************/

/*****************************************************************************
** 
**    TriggerInitialize
** 
**    Description:
**       Set trigger to default configuration.
**
**    Parameters:
**       input:
**          trigger:      far pointer to trigger structure to initialize
**       output:
**          none
*****************************************************************************/
VOID TriggerInitialize(TRIGGER FAR *trigger) {
   LOOP_VAR evt,level,cond,counter;
   U16 lv[] = { LV0_MASK, LV1_MASK, LV2_MASK, LV3_MASK};

   trigger->numTraceBuffers = 1;
   trigger->traceMode   = TRACE_PRE;
   trigger->fw.counterMode = defCounterMode;
   trigger->enableBreak = FALSE;
   trigger->qualifierMode = QUAL_BUS;

   trigger->curCond     = EV0_COND;
   trigger->curLevel    = 0;

   for(evt=0; evt<NUM_EVENTS; evt++) {
      for(level=0; level<NUM_LEVELS; level++) 
         trigger->eventName[evt][level] = NULL;
   }
   
   for(level=0; level<NUM_LEVELS; level++) {
      for (cond=0; cond<NUM_EVENT_COND; cond++) {
         trigger->fw.action[cond][level] = NULL_MASK | lv[level];
         trigger->fw.useEvt[cond][level] = FALSE;
         trigger->fw.useExt[cond][level] = FALSE;
      }
   }
   for (counter=0; counter<NUM_COUNTERS; counter++) {
      trigger->terminalCount[counter] = 1;
   }
}

/* Returns TRUE is event is never used in trigger */
BOOLEAN EventNotUsed(TRIGGER FAR *trigger, LOOP_VAR event) {
   LOOP_VAR level;
   for( level=0; level < NUM_LEVELS; level++ ) {
      if( trigger->fw.useEvt[event][level] ) return(FALSE);
   }
   return(TRUE);
}

U8 PRIVATE checkSettedEvent(CHAR *evName,
                CHAR evList[NUM_EVENTS][MAX_NAME_LENGTH+1],U8 idx) {
   LOOP_VAR i;

   for (i = 0; i < idx; i++) {
      if (stricmp(evName,evList[i]) == 0)
         return(i+1);
   }
   return(0);
}

/*****************************************************************************
** 
**    ProgramEvents
** 
**    Description:
**       Programs the events (address, data, status, extra).
**
**    Parameters:
**       input:
**          trigger:  trigger definition including array of names of events
**       output:
**          none
*****************************************************************************/
RETCODE ProgramEvents(TRIGGER FAR *trigger) {
   LOOP_VAR group, event, level;
//   U8 eventIdx, evNo;
   EVENT_GROUP_INFO sdEvent[NUM_EVENTS];
   RETCODE err;
   BOOLEAN slotPresent;
   BOOLEAN abortFromEsc;
   CHAR settedEventList[NUM_EVENTS][MAX_NAME_LENGTH+1];

   for (group=0; group<NUM_GROUPS; group++) {
      if ((err = SdnReadMember(SDN_TRACE_0_SLOT_PRESENT+group,&slotPresent))
          != GOOD) return(err);
      if (!slotPresent) continue;   /* NO TMOD --> skip programming */


//    **  initial sdEvent  **
//      eventIdx = 0;
      for (event=0; event<NUM_EVENTS; event++) {
         sdEvent[event].hi = sdEvent[event].lo = sdEvent[event].mask = 0;
         sdEvent[event].not = 1;
         settedEventList[event][0] = NULL;
      }

      err = TskCheckAbort(&abortFromEsc);
      if(err!=GOOD) return err;
      if (abortFromEsc)
         return(ER_ABORT_FROM_ESC);

      for (level=0; level<NUM_LEVELS; level++) {

         for (event=0; event<NUM_EVENTS; event++) {

            err = TskCheckAbort(&abortFromEsc);
            if(err!=GOOD) return err;
            if (abortFromEsc)
               return(ER_ABORT_FROM_ESC);

            if( (trigger->eventName[event][level]==NULL)
                || (lstrlen(trigger->eventName[event][level])==0)
                || !(trigger->fw.useEvt[event][level]) ) {

//                || EventNotUsed(trigger,event) )  {
//               sdEvent[event].hi = sdEvent[event].lo = sdEvent[event].mask = 0;
//               sdEvent[event].not = 1;
                continue;
            }
            else {
               LPSTR nameStr;
               BOOLEAN exists;
               nameStr = trigger->eventName[event][level];
//               evNo = checkSettedEvent(nameStr,settedEventList,eventIdx);
//               if( evNo == 0 ) {
               if (nameStr != NULL) {
                  if( (err=EvtDoesEventExist(nameStr,&exists))!=GOOD ) return(err);
                  if( !exists ) return(ER_INVALID_EVENT_NAME);
                  if( (err=EvtSetActiveEvent(trigger->eventServerId,nameStr))
                     != GOOD ) return(err);
                  if( (err=EvtGetEventGroupInfo(trigger->eventServerId,
                           group, &sdEvent[event])) != GOOD ) return(err);
                  strcpy(settedEventList[event],nameStr);
//                  trigger->fw.useEvt[event][level] = eventIdx + 1;
                  trigger->fw.useEvt[event][level] = event + 1;
//                  eventIdx++;
               } else
                  trigger->fw.useEvt[event][level] = 0;
            }
         }
      }

      err = TskCheckAbort(&abortFromEsc);
      if(err!=GOOD) return err;
      if (abortFromEsc)
         return(ER_ABORT_FROM_ESC);

      if (group != 2)
         {
         if((err=SdnWriteMemberNoCallback(SDN_EVTREC+group,(U8 FAR *)&sdEvent,GOOD))!=GOOD) return(err);
         }
      else {
         if((err=SdnWriteMember(SDN_EVTREC+group,(U8 FAR *)&sdEvent,GOOD))!=GOOD) return(err);
         }
   }
   return(GOOD);
}

U16 ConvertCond(EVENT_COND cond) {
   switch (cond) {
      case EV0_COND: return 0;
      case EV1_COND: return 1;
      case EV2_COND: return 2;
      case EV3_COND: return 3;
      case EV4_COND: return 4;
      case EV5_COND: return 5;
      case EV6_COND: return 6;
      case EV7_COND: return 7;
      case TC0_COND: return CNTR0_COND;
      case TC1_COND: return CNTR1_COND;
      case EXT_COND: return 10;
   }
   return INVALID_EVENT_COND;
}

RETCODE CheckTriggerConditions(DESCRIPTOR id) {
   BOOLEAN tracing;
   RETCODE err;

// Mark for trigger on the fly
//   if((err=SdnReadMember(SDN_TRACING,&tracing))!=GOOD) return(err);
   /* force sequencer off automatically? If we didn't "halt" sequencer
      could still be running. */
//   if( tracing ) return(ER_TRACE_TRIG_ON);
   if ((err = EnableSequencer(FALSE)) != GOOD) return(err);
   ((TRIGGER FAR *)id)->trigModified = TRUE;
   return(GOOD);
}

RETCODE EnableSequencer(BOOLEAN enable) {
   BOOLEAN timedOut;
   sequencerEnabled = enable;
   return(SdnWriteCmdReadResponse(SDN_ENABLE_SEQUENCER,&enable,GOOD,
                                  SDN_ENABLE_SEQUENCER_ACK,0,&timedOut));
}

/*****************************************************************************
** 
**    TrigCheckQualify
** 
*****************************************************************************/
RETCODE EXPORT TrigCheckQualify(DESCRIPTOR id, BOOLEAN *flag) {
   TRIGGER FAR *trigger;
   U16 idx, i, mask, mask2;

   trigger = (TRIGGER FAR *)id;
   mask2 = 0;
   for (idx = 0; idx < NUM_LEVELS; idx++) {
      for (i=0; i < NUM_EVENT_COND; i++) {
        if (!trigger->fw.useEvt[i][idx]) continue;
	mask = trigger->fw.action[i][idx];
        if ((mask & TRC_QUAL_MASK)==TRC_QUAL_MASK) mask2 |= TRC_QUAL_MASK;
      }
   }
   *flag = (mask2 == TRC_QUAL_MASK) ? 1 : 0;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigOutActionGet
** 
*****************************************************************************/
RETCODE EXPORT TrigOutActionGet(DESCRIPTOR id, U8 FAR *enableExt) {
   TRIGGER FAR *trigger;
   trigger = (TRIGGER FAR *)id;
   *enableExt = trigger->extOut;
   return(GOOD);
}

/*****************************************************************************
** 
**    TrigOutActionSet
** 
*****************************************************************************/
RETCODE EXPORT TrigOutActionSet(DESCRIPTOR id, U8 enable) {
   TRIGGER FAR *trigger;
   RETCODE err;
   if( (err=CheckTriggerConditions(id))!=GOOD ) return(err);
   trigger = (TRIGGER FAR *)id;
   trigger->extOut = enable;
   defExtOut=trigger->extOut;
   if( (err=iceSetTrigOutAction((U16)enable))!=GOOD ) return(err);

   return(GOOD);
}

/*****************************************************************************
** 
**    TrcCounterFunctionGet
** 
*****************************************************************************/
RETCODE EXPORT TrcCounterFunctionGet(COUNTER_TYPE FAR *function) {
   *function = defCounterMode;
   return(GOOD);
}

/******************************** E O F ***********************************/
