/****************************************************************************
**
**  Name:  dq.c
**
**  Description:
**     This is a dequeuer for Motorola 68332.
**
**  Status:  REVIEWED
**
**  $Log:   S:/tbird/mt2_68k/dad32/dq.c_v  $
** 
**    Rev 1.2   23 Mar 1998 17:30:22   gene
** added LC302
** 
**    Rev 1.1   10 Feb 1998 12:01:22   Eric
** Add return error code in DqOpen function.
** 
**    Rev 1.0   13 Feb 1997 08:45:14   gene
** Initial revision.
** 
**    Rev 1.3   08 Oct 1996 13:33:32   kevin
** Get processor type by dasm.c instead by dq.c
** 
**    Rev 1.2   28 Jun 1996 14:24:54   kevin
** added coretype checking
** 
**    Rev 1.1   12 Mar 1996 10:10:14   gene
** changed to large model
** 
**    Rev 1.0   07 Sep 1995 10:16:52   gene
** Initial revision.
** 
**    Rev 1.12   28 Jul 1993 13:25:34   ernie
** (For Mindy) Free dq buffer in error cases.
** 
**    Rev 1.11   24 Jul 1993 13:46:46   mindy
** update starting frame number for _dt command
** 
**    Rev 1.10   22 Jul 1993 15:29:20   mindy
** added dq backup
** 
**    Rev 1.9   13 Jul 1993 19:23:10   doug
** Errors consolidated in errtext/mkerrors.h and use generic syntax error
** 
**    Rev 1.8   25 May 1993 12:03:40   ernie
** Changed dasmSym to be system-wide global
** 
**    Rev 1.7   09 Dec 1992 10:33:18   mindy
** interface to dq forward changed
** 
**    Rev 1.6   14 Oct 1992 14:37:04   ernie
** 1. Removed extraneous code used for debugging memory leaks.
** 2. Changed interface to DqInsts.
** 
**    Rev 1.5   18 Sep 1992 10:02:34   marilyn
** Fixed memory leaks.
** 
**    Rev 1.4   31 Aug 1992 09:28:56   marilyn
** Re-established previous interface for DadForwardDqInst to use HANDLE instead
** of buffer. MemAlloc is used instead of TMalloc for consistency with the 
** trace server.
** 
**    Rev 1.3   31 Aug 1992 09:25:46   marilyn
** Re-established previous interface for Dad
** 
**    Rev 1.2   12 Aug 1992 12:01:06   marilyn
** Changed interface params for TrcGetCliId call.
** 
**    Rev 1.1   05 Aug 1992 10:36:18   marilyn
** Now setting the address space upon initialization of dqState.
** 
**    Rev 1.0   31 Jul 1992 12:47:50   marilyn
** Initial revision.
**
**  $Header:   S:/tbird/mt2_68k/dad32/dq.c_v   1.2   23 Mar 1998 17:30:22   gene  $
**
**  Copyright (C) 1991 Microtek International.  All rights reserved.
**
*****************************************************************************/

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

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

#ifndef _DAD_SERVER_
#include "dasm.h"
#endif

#ifndef _SYMBLSVR_
#include "symblsvr.h"
#endif

#ifndef _DAD_DEFINE_
#include "daddef.h"
#endif

#ifndef _DQ306_
#include "dq306.h"
#endif

#ifndef _ADDR_
#include "addr.h"
#endif

#ifndef _HEAP_
#include "heap.h"
#endif

#ifndef _HOSTERRS_
#include "hosterrs.h"
#endif

#ifndef _TRACE_
#include "trace.h"
#endif

#ifndef __STDLIB_H_
#include <stdlib.h>
#endif


                       /****************************
                        *                          *
                        *     EXTERNALS            *
                        *                          *
                        ****************************/

extern U8 *SymSet[];
extern PROBE_TYPE gProcessor;
extern HANDLE  cliServerHandle;

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

STATIC DESCRIPTOR cliDqId=0;

                        /***************************
                        *                          *
                        *        PROTOTYPES        *
                        *                          *
                        ***************************/

                        /***************************
                        *                          *
                        *     EXECUTABLE CODE      *
                        *                          *
                        ***************************/

/****************************************************************************
**
**  Name:  DadDqOpen
**
****************************************************************************/
RETCODE EXPORT DadDqOpen(DESCRIPTOR FAR *id, DESCRIPTOR traceId) {

   DQ_STATE FAR *dqState;
   RETCODE err;
   U32 numFrames;

   if ((dqState = (DQ_STATE FAR *)TMalloc(sizeof(DQ_STATE))) == NULL)
      return ER_DAD_INVALID_ID_DESCRIPTOR;
   *id = (DESCRIPTOR)dqState;
   dqState->DqFilter   = NO_FILTER;
   dqState->Search     = OFF;
   dqState->Offset     = 0;
   dqState->traceId    = traceId;
   dqState->coreType   = MODE_16BITS;
   //Eric 2/3/98
   if((err=TrcNumFramesGet(dqState->traceId, &numFrames))!=GOOD)
      return(err);
   if( !numFrames ) {
      TFree((LPSTR)dqState);
      return(ER_DQ_NO_FRAMES_AVAILABLE); /* no frames just get out! */
   }
   //eof Eric 2/3/98
   if ((dqState->dqFrame = (FRAME_TYPE FAR *)TMalloc(sizeof(FRAME_TYPE)))
         == NULL)
      return ER_OUT_OF_MEMORY;
   if ((err = AdrCreateAddress(&dqState->dqFrame->frameAddr)) != GOOD)
      return err;
   if ((err = AdrSetAddrSpace(dqState->dqFrame->frameAddr,SPACE_SP)) != GOOD)
      return err;
   if ((err = AdrSetAddrOffset(dqState->dqFrame->frameAddr,0)) != GOOD)
      return err;
   dqState->dqFrame->frameNo = 0;
   dqState->dqFrame->synched = FALSE;
   dqState->dqFrame->frameValid = FALSE;
   //CreateDqStateTable(*id);
   //Eric 2/3/98 for Bug ID#199
   if((err=CreateDqStateTable(*id)) != GOOD) {
      return(ER_DQ_NO_FRAMES_AVAILABLE); /* no frames just get out! */
   }
   //eof Eric 2/3/98

   if (gProcessor == M68302_MP || gProcessor == M68302LC_MP) {
      U16 coreType;

      if ((err=Sds2AbiGetCoreType(&coreType)) != GOOD)
         return err;
      dqState->coreType = (coreType==1) ? MODE_8BITS : MODE_16BITS;
   }
   return(GOOD);
}

/****************************************************************************
**
** Name:  DadForwardDqInst
**
****************************************************************************/
//RETCODE EXPORT DadForwardDqInst(DESCRIPTOR id,U32 numInst,S32 FAR *startFrame,
//                        S32 FAR *endFrame, LPSTR *buffer, U16 FAR *textLen) {
//   DQ_STATE FAR *dqState;
//   RETCODE err;
//   *textLen = 0;
//   if ((dqState = (DQ_STATE FAR *)id) == NULL)
//      return ER_DAD_INVALID_ID_DESCRIPTOR;
//
//   if ((*buffer = TMalloc(MAX_LINE_LENGTH*numInst)) == NULL)
//      return(ER_OUT_OF_MEMORY);
//
//   _fmemset(*buffer,'\0',(U16)numInst*MAX_LINE_LENGTH); /* initialize string */
//   if ((err = TrcFrameDisplayModeSet(dqState->traceId,TRIGGER_ALIGN))
//         != GOOD) {
//      TFree(*buffer);
//      return err;
//   }
//
//   if ((err = DqInsts(dqState,numInst,*buffer)) != GOOD) {
//      TFree(*buffer);
//      return err;
//   }
//
//   GetStartEndFrame(startFrame,endFrame);
//
//   *textLen = lstrlen(*buffer);
//   return(GOOD);
//}
//
/****************************************************************************
**
** Name:  DadBackwardDqInst
**
****************************************************************************/
//RETCODE EXPORT DadBackwardDqInst(DESCRIPTOR id,U32 numInst,S32 FAR *startFrame,
//                        S32 FAR *endFrame, LPSTR *buffer, U16 FAR *textLen) {
//   DQ_STATE FAR *dqState;
//   RETCODE err;
//   *textLen = 0;
//   if ((dqState = (DQ_STATE FAR *)id) == NULL)
//      return ER_DAD_INVALID_ID_DESCRIPTOR;
//
//   if ((*buffer = TMalloc(MAX_LINE_LENGTH*numInst)) == NULL)
//      return(ER_OUT_OF_MEMORY);
//
//   _fmemset(*buffer,'\0',(U16)numInst*MAX_LINE_LENGTH); /* initialize string */
//   if ((err = TrcFrameDisplayModeSet(dqState->traceId,TRIGGER_ALIGN))
//         != GOOD) {
//      TFree(*buffer);
//      return err;
//   }
//
//   if ((err = DqInsts(dqState,0-numInst,*buffer)) != GOOD) {
//      TFree(*buffer);
//      return err;
//   }
//
//   GetStartEndFrame(startFrame,endFrame);
//
//   *textLen = lstrlen(*buffer);
//   return(GOOD);
//}
//
/****************************************************************************
**
** Name:  DadSetDqOffset
**
****************************************************************************/
RETCODE EXPORT DadSetDqOffset(DESCRIPTOR id, U16 offset) {

   if (id == NULL)
      return ER_DAD_INVALID_ID_DESCRIPTOR;
   ((DQ_STATE FAR *)id)->Offset = offset;
   return(GOOD);
}

/****************************************************************************
**
**  Name:  DadGetDqOffset
**
****************************************************************************/
RETCODE EXPORT DadGetDqOffset(DESCRIPTOR id, U16 FAR *offset) {

   if (id == NULL)
      return ER_DAD_INVALID_ID_DESCRIPTOR;
   *offset = ((DQ_STATE FAR *)id)->Offset;
   return(GOOD);
}

/****************************************************************************
**
** Name:  DadDqClose
**
****************************************************************************/
RETCODE EXPORT DadDqClose(DESCRIPTOR id) {
   DQ_STATE FAR  *dqState;
   RETCODE err;


   if ((dqState = (DQ_STATE FAR *)id) == NULL)
      return ER_DAD_INVALID_ID_DESCRIPTOR;
   if ((err = AdrDestroyAddress(dqState->dqFrame->frameAddr)) != GOOD)
      return err;
   if ((err = TFree((LPSTR)dqState->dqFrame)) != GOOD)
      return err;
   if ((err = TFree((LPSTR)dqState)) != GOOD)
      return err;
   return(GOOD);
}

/***************************************************************************
**
**  DqCliOpen
**
**************************************************************************/
RETCODE DqCliOpen(void) {
   RETCODE err;
   DESCRIPTOR traceId;

   if((err=TrcGetCliId(&traceId))!=GOOD) return(err);
   if((err=DadDqOpen(&cliDqId,traceId)) != GOOD) return(err);
   return(err);
}

/***************************************************************************
**
**  DadCliDqOffset
**
**************************************************************************/
RETCODE EXPORT DadCliDqOffset(LPSTR cmdString, U32 argc, U32 argv[]) {

   U16 offset;
   U8 resultBuff[128];
   RETCODE err;
   S8 *endptr;

   if (argc > 2) return (ER_CLI_SYNTAX);
   if( !cliDqId ) {
      if((err=DqCliOpen())!=GOOD) return(err);
   }
   if( argc == 2 ) {
      offset = (U16)strtoul(&cmdString[argv[1]],&endptr,16);
      if((err=DadSetDqOffset(cliDqId,offset))!=GOOD) return(err);
   }
   if( (err=DadGetDqOffset(cliDqId,&offset)) != GOOD ) return(err);
   wsprintf(resultBuff,"dq offset: %x", offset);
   return(SendCliMessage(cliServerHandle,resultBuff));
}

/*************************************************************************
**
** DadCliGetDqInst
**
***************************************************************************/
RETCODE EXPORT DadCliGetDqInst(LPSTR cmdString, U32 argc, U32 argv[]) {
   RETCODE err;
   LPSTR buffer;
   S32 end,start;
   S8 *endptr;
   U16 len;
   U32 numInst = 1;
   DQ_STATE FAR *dqState;

   if (!cliDqId) {
      if((err=DqCliOpen())!=GOOD)
         return(err);
   }
   if (argc == 2)
      numInst = strtoul(&cmdString[argv[1]],&endptr,16);
   if ((err=DadForwardDqInst(cliDqId,numInst,&start,&end,&buffer,&len))!=GOOD)
      return(err);

   if((dqState=(DQ_STATE FAR *)cliDqId)==NULL)
      return ER_DAD_INVALID_ID_DESCRIPTOR;
   if((err=TrcReadFrameSet(dqState->traceId,end+1))!=GOOD) return(err);
   
   err = SendCliMessage(cliServerHandle,buffer);
   TFree(buffer);
   return(err);
}
/**************************** E O F ***************************************/
