/***************************************************************************
**
**  Name:  dq186.c
**
**  Description:
**     This is a dequeuer for Intel 80186/80188
**
**
**  Status:
**
**
**  $Header:
**
**  Copyright (C) 1991 Microtek International.  All rights reserved.
**
***************************************************************************/

//#ifndef _STRING_
//#include <strlib.h>
//#endif

#ifndef _BASEWIND_
#include "basewind.h"
#endif

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

#ifndef _PDASM86_
#include "pdasm86.h"
#endif

#ifndef _DADDEF86_
#include "daddef86.h"
#endif

#ifndef _DQ186_
#include "dq186.h"
#endif

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

#ifndef _SSHARED_
#include "sshared.h"
#endif

#ifndef _SDPROBE_
#include "sdprobe.h"
#endif

#ifndef _SDNUM_
#include "sdnum.h"
#endif

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

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

#ifndef __STDIO_H
#include <stdio.h>
#endif

#ifndef __DOS_H
#include <dos.h>
#endif

#include "string.h"


// temp variable start

BOOLEAN dsmAddrGiven;
S32 dsmAddr,lastFrame;
S16 accessSize;
STATIC S16 MaxIndexLen;
// temp variable end

                        /****************************
                         *                          *
                         *     DEFINITIONS          *
                         *                          *
                         ****************************/
#define NULL_FRAME_NO 0x10000000l
#define TRACE_FRAME_WIDTH     23 // the length of each trace frame. <Judy 10-23-96>
#define END_TRACE_DATA       -10
#define MAX_SEARCH_DEPTH_186   5
#define MAX_SEARCH_DEPTH_188   6
#define MAX_NUM_DQ          150 /* Judy 5/27/1997*/
#define MAX_ITEM            100 /* Judy */

TRC_FRAME traceFrame;
                        /****************************
                         *                          *
                         *     EXTERNALS            *
                         *                          *
                         ****************************/

extern HANDLE cliServerHandle;

                        /****************************
                         *                          *
                         *     LOCAL VARIABLES      *
                         *                          *
                         ****************************/
#define READ_FRAMES_DATA     SDN_FIND_FLUSH_INSTS
#define SPACE_MASK           0x07
CHAR *spaceString[] = {"AK","I","O","H","S","R","W"};
BOOLEAN showTS;  


//LOCAL char statusCode[8] = {
//   'A', 'I', 'O', 'H', 'S', 'R', 'W', 'D'
//};

                        /****************************
                         *                          *
                         *     LOCAL PROTOTYPES     *
                         *                          *
                         ****************************/

RETCODE DqReadTraceFrame
        (DESCRIPTOR dqStateId,
         U8 *frameCunt,
         S32 startReadFrame,
         DQ_FRAME *dqFrame,
         SPACE_TYPE spaceType);
RETCODE SearchMatchAddress(DESCRIPTOR dqStateId,U32 searchAddr,S32 *matchFrame);

/////////////////////// Temporal function of trace //////////////////////////
VOID OutputStringToFile(LPSTR buffer,U16 textLen){
FILE *fStream;

   fStream = fopen("dqstring.log","w");
   fwrite(buffer, textLen, 1, fStream);
   fclose(fStream);
}

                        /****************************
                         *                          *
                         *     EXECUTABLE           *
                         *                          *
                         ****************************/

/****************************************************************************
**
** Name:  AdddqStateTable
**
****************************************************************************/
RETCODE AddDqStateTable(DESCRIPTOR dqStateId,S32 newFrameNo) {
DQ_STATE *dqState;
U32 numGotten;
S32 oldFrameNo;
U16 lp;
RETCODE err;
LPSTR buffer;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return ER_DAD_INVALID_ID_DESCRIPTOR;
   TrcReadFrameGet(dqState->traceId,&oldFrameNo);
   TrcReadFrameSet(dqState->traceId,newFrameNo);
   for (lp = 0; lp < FRAME_BUFF_LEN; lp++)
      dqState->frameArray[lp].frameNo = NULL_FRAME_NO;
   if ((err = TrcTraceReadRaw(dqState->traceId,FRAME_BUFF_LEN,
              (U32 far *)&numGotten, &buffer)) != GOOD) return(err);
   for (lp = 0; lp < numGotten; lp++) {
      memcpy(&(dqState->frameArray[lp]),
             (buffer+lp*TRACE_FRAME_WIDTH),TRACE_FRAME_WIDTH);
   }
   TFree(buffer);
   TrcReadFrameSet(dqState->traceId,oldFrameNo);
   dqState->frameStart = dqState->frameArray[0].frameNo;
   dqState->frameEnd = dqState->frameArray[(U16)(numGotten - 1)].frameNo;
   dqState->traceArrayCount = numGotten;
   return(GOOD);
}

/****************************************************************************
**
** Name:  CreatedqStateTable // Create Dis-continue Table
**
****************************************************************************/
RETCODE CreateDqStateTable (DESCRIPTOR dqStateId) {
DQ_STATE  *dqState;
S32 curFrame;
U16 tempBuffId;
PROBE_TYPE cpuMode;


   ProcReturnSpecificProcessor((PROBE_TYPE FAR *)&cpuMode);
   switch (cpuMode) {
      case I80C186_MP :
      case I80C186XL_MP :
      case I80C186EA_MP :
      case I80C186EB_MP :
      case I80C186EC_MP :
         accessSize = ACCESSSIZE86;
         break;
      case I80C188_MP :
      case I80C188XL_MP :
      case I80C188EA_MP :
      case I80C188EB_MP :
      case I80C188EC_MP :
          accessSize = ACCESSSIZE88;
   }
   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return ER_DAD_INVALID_ID_DESCRIPTOR;
   TrcReadBufferGet(dqState->traceId,(U16 FAR *)&tempBuffId); // read current buffer ID
   dqState->traceBufId = tempBuffId; // read current buffer ID
   TrcReadFrameGet(dqState->traceId,&curFrame);
   return(AddDqStateTable(dqStateId,curFrame));

}

/****************************************************************************
**
** Name:  DestroydqStateTable // Create
**
****************************************************************************/
RETCODE DestroyDqStateTable(DESCRIPTOR id) {
DQ_STATE *dqState;
RETCODE err;

   if ((dqState = (DQ_STATE FAR *)id) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);
   if ((err = TFree((LPSTR)dqState)) != GOOD)
      return err;
   return(GOOD);
}

/****************************************************************************
**
** Name:  CheckSpaceType
**
****************************************************************************/
RETCODE CheckSpaceType(SPACE_TYPE spaceType, U8 statusPin) {

   statusPin &= 0x0f;
   switch (spaceType) {
      case S_PROGRAM :
         if (statusPin == 0x0c) return(GOOD);
         break;
      case S_DATA :
         if ((statusPin  == 0x0d) || (statusPin  == 0x0e) ||
             (statusPin  == 0x09) || (statusPin  == 0x0a))
           return(GOOD);
         break;
      case S_DONT_CARE :
         return(GOOD);
      default :
         return(!GOOD);
   }
   return(!GOOD);
}

/****************************************************************************
**
** Name:  ReadOneTrace
**
****************************************************************************/
RETCODE ReadOneTrace
        (DESCRIPTOR dqStateId,
         S32 startReadFrame,
         DQ_FRAME *dqFrame){
DQ_STATE FAR *dqState;
S32 curOffset;
U16 traceBuf;
RETCODE err;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);
   TrcReadBufferGet(dqState->traceId,&traceBuf);

   dqFrame->frameNo = NULL_FRAME_NO;
   if (dqState->traceBufId != traceBuf) {
      dqState->traceBufId = traceBuf;
      if ((err = AddDqStateTable(dqStateId,startReadFrame)) != GOOD)
         return(err);
   }
   else if ((startReadFrame < dqState->frameStart)||
            (startReadFrame > dqState->frameEnd)) {
      if ((dqState->traceArrayCount < FRAME_BUFF_LEN) &&
          (startReadFrame > dqState->frameEnd)) return(END_TRACE_DATA);
      if ((err = AddDqStateTable(dqStateId,startReadFrame)) != GOOD) return(err);
   }

   curOffset = (U16)(startReadFrame- dqState->frameStart);
   dqFrame->frameNo = dqState->frameArray[(U16)curOffset].frameNo;
   dqFrame->addr = dqState->frameArray[(U16)curOffset].addr;
   dqFrame->data = dqState->frameArray[(U16)curOffset].data;
   dqFrame->statusPin = dqState->frameArray[(U16)curOffset].statusPin;

   if (dqFrame->frameNo == NULL_FRAME_NO) return(END_TRACE_DATA);
   return(GOOD);
}
/****************************************************************************
**
** Name:  SkipTraceData
**
** input :
**       dataLen : size of bytes
**
****************************************************************************/
RETCODE SkipTraceData
        (DESCRIPTOR dqStateId,
         S8 dataLen,
         S32 startSkipFrame,
         SPACE_TYPE spaceType){
DQ_STATE FAR *dqState;
S32 curOffset,lp,nextStartFrame;
S32 newest,trig,oldest;
U8 count = 0;
U16 remainByte;
RETCODE err = GOOD;
DQ_FRAME dqFrame;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);
   curOffset = lp = 0;
   DadGetDqOffset(dqStateId,&remainByte);
   if (remainByte == 1) {
     count++;
     curOffset++;
     lp++;
   }
   do{
      if ((err = ReadOneTrace(dqStateId,startSkipFrame+lp,&dqFrame)) != GOOD)
         break;
      if (CheckSpaceType(spaceType, dqFrame.statusPin) == GOOD) {
         if (accessSize == ACCESSSIZE88) count++;
         else {
            if (dqFrame.addr & 1) count++; /* odd address */
            else {
               if (IS_BHE(dqFrame.statusPin)) count++;
               else count+=2;
            }
         }
      }
      lp++;
   }while(count < dataLen);

   if ((err = TrcTraceBufferInfoGet(dqState->traceId,&oldest,&newest,&trig))
      != GOOD) return(err);
   if (count == dataLen) nextStartFrame = startSkipFrame+lp;
   else nextStartFrame = startSkipFrame+lp-1;
//   if (nextStartFrame > newest) nextStartFrame = newest;
   while (1) { /* skip all RW frames */
      if (nextStartFrame >= newest) break;
      ReadOneTrace(dqStateId,nextStartFrame,&dqFrame);
      if (CheckSpaceType(spaceType, dqFrame.statusPin) == GOOD) break;
      nextStartFrame++; 
   }
   err = TrcReadFrameSet(dqState->traceId,nextStartFrame);

   if(count == (dataLen+1)) DadSetDqOffset(dqStateId,1);
   else DadSetDqOffset(dqStateId,0);
   return(err);
}

/****************************************************************************
**
** Name:  DqReadTraceFrame
**
****************************************************************************/
RETCODE DqReadTraceFrame
        (DESCRIPTOR dqStateId,
         U8 *frameCount,
         S32 startReadFrame,
         DQ_FRAME *dqFrame,
         SPACE_TYPE spaceType){
U8 count = 0;
U16 lp = 0;
RETCODE err = GOOD;
DQ_FRAME *framePtr;

   framePtr = dqFrame;
   dqFrame->frameNo = NULL_FRAME_NO;
   do {
      if ((err = ReadOneTrace(dqStateId,startReadFrame+lp,framePtr)) != GOOD)
         break;
      if (CheckSpaceType(spaceType, dqFrame->statusPin) == GOOD) {
         framePtr++;
         count++;
      }
      lp++;
      if (lp > MAX_ITEM) break;
   } while (*frameCount > count);
   *frameCount = count;
   return(err);
}

/****************************************************************************
**
** Name:  ReadInstDataAndAddress
**
****************************************************************************/
RETCODE ReadInstDataAndAddress(
        DESCRIPTOR dqStateId,U8 *objCode,U8 *objLen, U32 *startAddr) {
DQ_STATE FAR *dqState;
DQ_FRAME dqFrame;
S32 curFrame, firstFrame;
U8 instPos,frameCount;
U16 remainByte;
RETCODE err;
U32 lastFrameAddr=0xFFFFFFFFFL;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);
   TrcReadFrameGet(dqState->traceId,&curFrame);
   firstFrame = curFrame;
   DadGetDqOffset(dqStateId,&remainByte);
   instPos = *objLen = 0;
   do {
      frameCount = 1;
      if ((err = DqReadTraceFrame(dqStateId,&frameCount,curFrame,&dqFrame,
                                S_PROGRAM)) != GOOD)
         return(err);
      if (firstFrame != curFrame && lastFrameAddr == dqFrame.addr) {
         curFrame++;
//0514        TrcReadFrameSet(dqState->traceId,firstFrame+1);
        continue;
      } 
      curFrame = dqFrame.frameNo + 1;
      if (instPos == 0) {
         TrcReadFrameSet(dqState->traceId,dqFrame.frameNo);
         lastFrameAddr = *startAddr = dqFrame.addr;
         if (remainByte == 1) (*startAddr)++;
      }
      if (accessSize == ACCESSSIZE88) {   /* 80x88 */
         objCode[instPos] = LSB(dqFrame.data);
         instPos++;
         (*objLen)++;
      }
      else                             /* 80x86 */
      if (dqFrame.addr & 1) {                  /* odd address */
         objCode[instPos] = MSB(dqFrame.data);
         instPos++;
         (*objLen)++;
      }
      else                           /* even address */
      if (remainByte == 1) {
          objCode[instPos] = MSB(dqFrame.data);
      //objCode[instPos] = LSB(dqFrame.data);
          instPos++;
          (*objLen)++;
          remainByte = 0;
      }
      else {                      /* two bytes effective */
          objCode[instPos] = LSB(dqFrame.data);
          objCode[instPos+1] = MSB(dqFrame.data);
          instPos += 2;
          (*objLen)+=2;
      }
   }while (instPos < MAX_INST_LEN);
   return(GOOD);
}

TRACE_STATUS_PIN cycleSequence[3][10] = {
    // RRRRWWWWWW for 188
    {READ_FLUSH, READ_FLUSH, READ_FLUSH, READ_FLUSH,
    WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH},
    // RRWWW for 186
    {READ_FLUSH, READ_FLUSH,
    WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH,
    0xffff,0xffff,0xffff,0xffff},
    // RRWWWWWW for 186
    {READ_FLUSH, READ_FLUSH,
    WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH, WRITE_FLUSH,
    0xffff,0xffff}
};
#define RW_DEPTH_188            10
#define ADD_DEPTH_188            4
#define RW_DEPTH_186             5
#define RW_DEPTH_186_ODD         8
#define ADD_DEPTH_186            5
INT_CYCLE_TYPE CheckIntCycle(DQ_FRAME dqFrame[],U32 *intAddr,U32 *toAddr) {
U16 lp,pos;

   if (accessSize == ACCESSSIZE88) {
      for (pos = 0; pos < (ADD_DEPTH_188+1); pos++) {
         if ((dqFrame[pos].statusPin & 0x4f) == cycleSequence[0][0])
            break;
      }
      if (pos > ADD_DEPTH_188) return(NO_INT);
      for (lp = pos; lp < (pos+RW_DEPTH_188); lp++) {
         if ((dqFrame[lp].statusPin & 0x4f) != cycleSequence[0][lp-pos])
            return(NO_INT);
      }
      *toAddr = ((((U32)(dqFrame[3+pos].data & 0xff) << 8) +
                  (U32)(dqFrame[2+pos].data & 0xff)      ) << 4) +
                  ((U32)(dqFrame[1+pos].data & 0xff) << 8) +
                  (U32)(dqFrame[0+pos].data & 0xff);
      *intAddr = ((((U32)(dqFrame[7+pos].data & 0xff) << 8) +
                  (U32)(dqFrame[6+pos].data & 0xff)      ) << 4) +
                  ((U32)(dqFrame[9+pos].data & 0xff) << 8) +
                  (U32)(dqFrame[8+pos].data & 0xff);
      return(INT_88);
   }
   else {
      for (pos = 0; pos < (ADD_DEPTH_186+1); pos++) {
         if ((dqFrame[pos].statusPin & 0x4f) == cycleSequence[1][0])
            break;
      }
      if (pos > ADD_DEPTH_186) return(NO_INT);
      for (lp = pos; lp < (pos+RW_DEPTH_186); lp++) {
         if ((dqFrame[lp].statusPin & 0x4f) != cycleSequence[1][lp-pos])
            return(NO_INT);
      }
      if (((dqFrame[2+pos].addr/2)*2) == dqFrame[2+pos].addr) { //sp is even
         *toAddr = ((U32)dqFrame[1+pos].data << 4) + dqFrame[0+pos].data;
         *intAddr = ((U32)dqFrame[3+pos].data << 4) + dqFrame[4+pos].data;
         return(INT_86);
      }
      else { // sp is odd.
         for (lp = (pos+RW_DEPTH_186); lp < (pos+RW_DEPTH_186+3); lp++) {
            if ((dqFrame[lp].statusPin & 0x4f) != cycleSequence[2][lp-pos])
               return(NO_INT);
         }
         *toAddr = ((U32)dqFrame[1+pos].data << 4) + dqFrame[0+pos].data;
         *intAddr = ((((U32)(dqFrame[5+pos].data & 0xff) << 8) +
                     (U32)(dqFrame[4+pos].data & 0xff)      ) << 4) +
                     ((U32)(dqFrame[7+pos].data & 0xff) << 8) +
                     (U32)(dqFrame[6+pos].data & 0xff);
         return(INT_86);

      }
   }

}
/****************************************************************************
**
** Name:  CheckInterrupt
**
****************************************************************************/
INST_TYPE CheckInterrupt(DESCRIPTOR dqStateId, S32 startCheckFrame, U32 nextAddr) {
DQ_STATE FAR *dqState;
DQ_FRAME dqFrame[RW_DEPTH_188+ADD_DEPTH_188];
U32 intAddr,toAddr;
INT_CYCLE_TYPE intStatus = NO_INT;
S32 matchFrame;
U8 frameCount;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);

   if (accessSize == ACCESSSIZE88) {
      frameCount = RW_DEPTH_188 + 4; // add 4 r/w cycle
      DqReadTraceFrame(dqStateId,&frameCount,startCheckFrame,dqFrame,S_DATA);
      if (frameCount < RW_DEPTH_188) return(NORMAL_INST);
      intStatus = CheckIntCycle(dqFrame,&intAddr,&toAddr);
      if ((intStatus == INT_88) && (nextAddr == intAddr)) {
         SearchMatchAddress(dqStateId,toAddr,&matchFrame);
         TrcReadFrameSet(dqState->traceId,matchFrame);
         DadSetDqOffset(dqStateId,0);
         return(HW_INT);
      }
      else return(NORMAL_INST);
   }
   else {
      frameCount = RW_DEPTH_186 + 5;  // add 8 cycle
      DqReadTraceFrame(dqStateId,&frameCount,startCheckFrame,dqFrame,S_DATA);
      if (frameCount < RW_DEPTH_186) return(NORMAL_INST);
      intStatus = CheckIntCycle(dqFrame,&intAddr,&toAddr);
      if ((intStatus == INT_86) && (nextAddr == intAddr)) {
         SearchMatchAddress(dqStateId,toAddr,&matchFrame);
         TrcReadFrameSet(dqState->traceId,matchFrame);
         DadSetDqOffset(dqStateId,0);
         return(HW_INT);
      }
      else return(NORMAL_INST);
   }

}

/****************************************************************************
**
** Name:  PrintRemainsFrame
**
****************************************************************************/
VOID PrintRemainsFrame(DESCRIPTOR dqStateId, S32 startFrame,S32 *endFrame,
                       LPSTR string, LPSTR FAR *buffIndex, U16 *countInst,
                       DESCRIPTOR *descs) {
S32 offset,lp;
DQ_FRAME printFrame;
U8 frameCount,tempBuffer[80];
U8 *cycleFormat;
U16 byteData;

   //return; // temp inst.
   offset = *endFrame - startFrame;
   for (lp = 0; lp <= offset; lp++){
      //DqReadTraceFrame(dqStateId,offset,startFrame,&printFrame,S_DONT_CARE);
      frameCount = 1;
      if (DqReadTraceFrame(dqStateId,&frameCount,startFrame+lp,&printFrame,S_DONT_CARE))
         return;
      if (((printFrame.statusPin & SPACE_MASK) != 4) &&
          (printFrame.frameNo != NULL_FRAME_NO)) {
         if ((accessSize == ACCESSSIZE86) && !(printFrame.addr & 1)
             && !IS_BHE(printFrame.statusPin)) {
            /* 80x86, even address, word transfer */
            cycleFormat = "      %05lX   %04X    %2s \r\n"; 
            byteData = printFrame.data;
         }
         else {
            cycleFormat = "      %05lX     %02X    %2s \r\n";
            if ((accessSize == ACCESSSIZE86) && (printFrame.addr & 1))   /* 80x86, odd address */
               byteData = MSB(printFrame.data);
            else   /* 80x86, byte transfer on even address, or 80x88 */
               byteData = LSB(printFrame.data);
         }

 /* <Winky 10/17/1997> */
         wsprintf(tempBuffer,"%8ld ", printFrame.frameNo);
         strcat((LPSTR)string,(LPSTR)tempBuffer);
         if (showTS) {
            wsprintf(tempBuffer,"             ", printFrame.frameNo);
            strcat((LPSTR)string,(LPSTR)tempBuffer);
         }
         wsprintf(tempBuffer,cycleFormat,
              printFrame.addr,
              byteData,
              spaceString[(U16)(printFrame.statusPin & SPACE_MASK)]);
 /* eof <Winky 10/17/1997> */

         strcat((LPSTR)string,(LPSTR)tempBuffer);
         AdrCreateAddressWithType(ADDR_PHYSICAL,&descs[*countInst]);
         AdrSetAddrOffset(descs[*countInst],printFrame.addr);
         buffIndex[++(*countInst)] = string +  _fstrlen(string);
      }
      if (*countInst >= MaxIndexLen) {
          *endFrame = startFrame + lp;
          break;
      }
   }

}

/****************************************************************************
**
** Name:  PrintRWCycle
**
****************************************************************************/
VOID PrintRWCycle(DESCRIPTOR dqStateId, S32 curFrame, S32 *endFrame, LPSTR string,
                  LPSTR FAR *buffIndex, U16 *countInst, DESCRIPTOR *descs,
                  U16 numInst) {
S32 lp;
DQ_FRAME printFrame;
U8 frameCount,tempBuffer[80];
U8 *cycleFormat;
U16 byteData;

   //return; // temp inst.
   for (lp = 0;;lp++){
      frameCount = 1;
      if (DqReadTraceFrame(dqStateId,&frameCount,curFrame+lp,&printFrame,S_DONT_CARE))
         return;
      if (((printFrame.statusPin & SPACE_MASK) != 4) &&
          (printFrame.frameNo != NULL_FRAME_NO)) {
         if ((accessSize == ACCESSSIZE86) && !(printFrame.addr & 1)
             && !IS_BHE(printFrame.statusPin)) {
            /* 80x86, even address, word transfer */
            cycleFormat = "%8ld       %05lX    %04X    %2s \r\n";
            byteData = printFrame.data;
         }
         else {
            cycleFormat = "%8ld       %05lX      %02X    %2s \r\n";
            if ((accessSize == ACCESSSIZE86) && (printFrame.addr & 1))   /* 80x86, odd address */
               byteData = MSB(printFrame.data);
            else   /* 80x86, byte transfer on even address, or 80x88 */
               byteData = LSB(printFrame.data);
         }
         sprintf(tempBuffer,cycleFormat,
              printFrame.frameNo,
              printFrame.addr,
              (U8)byteData,
              spaceString[(U16)(printFrame.statusPin & SPACE_MASK)]);
         strcat((LPSTR)string,(LPSTR)tempBuffer);
         AdrCreateAddressWithType(ADDR_PHYSICAL,&descs[*countInst]);
         AdrSetAddrOffset(descs[*countInst],printFrame.addr);
         buffIndex[++(*countInst)] = string +  _fstrlen(string);
         if ((*countInst >= numInst) || (*countInst >= MaxIndexLen)) {
             *endFrame = curFrame + lp;
             break;
         }
      }
      else break;
   }
}
/***************************************************************************
**
**  Name: SearchMatchAddress
**
**  Description:
**
**  Input:
**
**  Output:
**
****************************************************************************/
RETCODE SearchMatchAddress(DESCRIPTOR dqStateId,U32 searchAddr,S32 *matchFrame) {
S32 flushFrame,lp;
DQ_FRAME dqFrame;
DQ_STATE FAR *dqState;
//U16 bytesRemain;
U32 alignAddr;
U8 frameCount;
RETCODE err;
U16 maxSearchDepth;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);
   TrcReadFrameGet(dqState->traceId,&flushFrame);
   //if (accessSize = ACCESSSIZE86) {
   //   if(searchAddr != (alignAddr = (searchAddr/2)*2)) bytesRemain = 1;
   //   else bytesRemain = 0;
   //}
   // else bytesRemain = 0;
   alignAddr = searchAddr;
   lp = 0;
   if (accessSize == ACCESSSIZE86) maxSearchDepth = MAX_SEARCH_DEPTH_186;
   else maxSearchDepth = MAX_SEARCH_DEPTH_188;
   do {
      frameCount = 1;
      if (err = DqReadTraceFrame(dqStateId,&frameCount,flushFrame+1,&dqFrame,S_PROGRAM))
         return(err);
//      if (dqFrame.addr == alignAddr) {
      if ((dqFrame.addr == alignAddr) && (ISFLUSH(dqFrame.statusPin))) {
         *matchFrame = dqFrame.frameNo;
         TrcReadFrameSet(dqState->traceId,dqFrame.frameNo);
         //DadSetDqOffset(dqStateId,bytesRemain);
         DadSetDqOffset(dqStateId,0);
         break;
      }
      flushFrame = dqFrame.frameNo;
      lp++;
   }while (lp < maxSearchDepth); // buffer depth : 10
   return(GOOD);
}

/***************************************************************************
**
**  Name: FindBranchSignals()
**
**  Description:
**
**  Input:
**
**  Output:
**
****************************************************************************/
RETCODE FindFlushSignals(DESCRIPTOR dqStateId,BOOLEAN *findFlush,
                         S32 *targetFrame,U32 *nextAddr) {
DQ_STATE *dqState;
RETCODE err;
S32 curFrame;
U16 lp = 1;
U16 sFrameCount, maxSearchDepth;
DQ_FRAME dqFrame;
U8 frameCount;
U8 fSignal,sSignal;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);
   *findFlush = FALSE;
   TrcReadFrameGet(dqState->traceId,&curFrame);
   sFrameCount = 0;
   if (accessSize == ACCESSSIZE86) maxSearchDepth = MAX_SEARCH_DEPTH_186;
   else maxSearchDepth = MAX_SEARCH_DEPTH_188;
   do {
      frameCount = 1;
      if (err = DqReadTraceFrame(dqStateId,&frameCount,curFrame+lp,&dqFrame,S_DONT_CARE))
         return(err);
//      if ((ISFLUSH(dqFrame.statusPin)) && (IS_S(dqFrame.statusPin))) {
      fSignal = ISFLUSH(dqFrame.statusPin);
      sSignal = IS_S(dqFrame.statusPin);
      if (fSignal && sSignal) {
         *findFlush = TRUE;
         *targetFrame = curFrame+lp;
         *nextAddr = dqFrame.addr;
         break;
      }
      if (sSignal) sFrameCount++;
      lp++;
   } while ((sFrameCount < maxSearchDepth) && (lp <= MAX_ITEM));
   TrcReadFrameSet(dqState->traceId,curFrame);
   return(GOOD);
}

/***************************************************************************
**
**  Name: CheckFlush(dqStateId, instNo)
**
**  Description:
**     check if flush occurs, and set correct end frame No. if necessary
**
**  Input:  current end frame No., codes, and No. of remain bytes
**
**  Output: number of remaining bytes, end frame No.
**
**  Return: 1 if flush, 0 if no flush, -1 if cannot judge
**
****************************************************************************/
CHECK_INST_TYPE CheckFlush(DESCRIPTOR dqStateId, DASM_INFO *dasmInfo,
                           U32 startAddr){
CHECK_INST_TYPE checkStatus;
S32 flushFrame,targetFrame;
U16 remainByte;
DQ_STATE FAR *dqState;
BOOLEAN findFlush;
U32 targetAddr,nextAddr;

   checkStatus = TRACE_INST;
   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);
   DadGetDqOffset(dqStateId,&remainByte);
   TrcReadFrameGet(dqState->traceId,&flushFrame);
   switch (dasmInfo->transfer) {
      case FALSE :
         CheckInterrupt(dqStateId,flushFrame,startAddr+(U32)dasmInfo->bytesUsed);
         //CheckInterrupt(dqStateId,flushFrame,startAddr);
         break;
      case TRUE :
         if (CheckInterrupt(dqStateId,flushFrame,
                    startAddr+(U32)dasmInfo->bytesUsed) == HW_INT) break;
         FindFlushSignals(dqStateId,&findFlush,&targetFrame,&nextAddr);
         if (findFlush == TRUE) {
            if (dasmInfo->knownAddr == TRUE) {
               AdrGetAddrPhysicalOffset(dasmInfo->target,(U32 far *)&targetAddr);
               if (targetAddr == nextAddr) {
                  checkStatus = TRACE_TRANSFER_INST;
                  TrcReadFrameSet(dqState->traceId,targetFrame);
                  DadSetDqOffset(dqStateId,0);
               } else {
//                  if (dasmInfo->conditional == FALSE) checkStatus = QUEUE_INST;
               }
            } else {
               checkStatus = TRACE_TRANSFER_INST;
               TrcReadFrameSet(dqState->traceId,targetFrame);
               DadSetDqOffset(dqStateId,0);
            }
         } else {
            if(dasmInfo->conditional != FALSE) checkStatus = QUEUE_INST;
         }
         break;
   }
   return(checkStatus);
}  /* end of CheckFlush() */


/****************************************************************************
**
** Name:  DqInst
**
****************************************************************************/
RETCODE DqInst(DESCRIPTOR dqStateId,U32 *numInst,S32 FAR *startFrame,
               S32 FAR *endFrame, LPSTR *buffer, LPSTR FAR *buffIndex, U16 *indexLen,
               DESCRIPTOR *descs) {
U8 objCode[30];
BOOLEAN dasmSym;
U16 trcBuffer,bufferDepth,countInst,codeOffset;
U16 tempCount,lp;
DASM_INFO dasmInfo;
S32 oldest,newest,trig,firstFrame,curFrame,printStartFrame,printEndFrame;
U32 startAddr,numFrames,addrOffset;
DQ_STATE FAR *dqState;
RETCODE retStatus,err=GOOD; // add GOOD by cjchen 1997.6.12
LPSTR bufferPtr;
U8 tempBuffer[MAX_ITEM],instText[50],objLen;
U16 remainByte,preRemainByte;
DESCRIPTOR addrId;
CHECK_INST_TYPE checkStatus;
//U16 tempLen;
DQ_FRAME dqFrame;
S32 tmpFrame;
U8 instInt[]="INT    3";
 /* <Winky 10/17/1997> */
S32 prevFrame;
U32 FrameTS;
U8  FrameTSM;
 /* eof <Winky 10/17/1997> */

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);

   bufferDepth = 80*(MAX_NUM_DQ)*2;
   if ((*buffer = TMalloc(bufferDepth)) == NULL)
      return(ER_OUT_OF_MEMORY);

   bufferPtr = *buffer;
   _fmemset(bufferPtr,'\0',bufferDepth); /* initialize string */
   if ((retStatus = TrcFrameDisplayModeSet(dqState->traceId,TRIGGER_ALIGN))
         != GOOD) {
      TFree(*buffer);
      return(retStatus);
   }
   if ((retStatus = DadGetDasmSymbol(&dasmSym)) != GOOD) return(retStatus);
//   *startFrame = *endFrame = 0;
   if((retStatus=TrcNumFramesGet(dqState->traceId, &numFrames))!=GOOD)
      return(retStatus);
   if( !numFrames ) return(ER_DQ_NO_FRAMES_AVAILABLE); /* no frames just get out! */

   if ((retStatus = TrcTraceBufferInfoGet(dqState->traceId,&oldest,&newest,&trig))
      != GOOD) return(retStatus);
   if ((retStatus = TrcReadFrameGet(dqState->traceId, &firstFrame)) != GOOD)
      return(retStatus);
   if ((retStatus = TrcReadBufferGet(dqState->traceId, &trcBuffer)) != GOOD)
      return(retStatus);

   *indexLen = 0;
   retStatus = GOOD;
   AdrCreateAddressWithType(ADDR_PHYSICAL,(DESCRIPTOR FAR *)&addrId);
   countInst = 0;
   curFrame = firstFrame;
 /* <Winky 10/17/1997> */
   prevFrame = curFrame;
   TrcTimestampGet(dqState->traceId, &showTS);
 /* eof <Winky 10/17/1997> */
   AdrCreateAddressWithType(ADDR_PHYSICAL,(DESCRIPTOR FAR *)&dasmInfo.target);
   buffIndex[0] = bufferPtr;
   PrintRWCycle(dqStateId,curFrame,&printEndFrame, bufferPtr, buffIndex,
      &countInst,descs,(U16)(*numInst));
   while (curFrame <= newest) {
      if (countInst >= *numInst)  break;
      retStatus = ReadInstDataAndAddress(dqStateId,objCode,&objLen,&startAddr);
      if (objLen == 0) break;

      TrcReadFrameGet(dqState->traceId,&curFrame);
      if (countInst == 0) *startFrame = curFrame;

      AdrSetAddrOffset(addrId,startAddr);
      printStartFrame = curFrame;

      instText[0] = 0;
      DadGetDqOffset(dqStateId,&preRemainByte);
      retStatus = DadGetDasmInstruction(addrId, ADDR_USE_16, objCode,
                                        instText,&dasmInfo);
      if (dasmInfo.bytesUsed > objLen) break;
      if (retStatus == GOOD) {
         if ((retStatus = TrcReadFrameGet(dqState->traceId, &curFrame)) != GOOD)
            return(retStatus);
         err = SkipTraceData(dqStateId,dasmInfo.bytesUsed,curFrame,S_PROGRAM);
         if (err != GOOD) break;

         /* Check flush */
         checkStatus = CheckFlush(dqStateId, &dasmInfo, startAddr);

         /* Display instruction */
         _fmemset(tempBuffer,0,MAX_ITEM); /* initialize struct */

 /* <Winky 10/17/1997> */
         if (strcmp(instText,instInt)!=0) {
            wsprintf(tempBuffer, "%8ld ", curFrame);
            lstrcat((LPSTR)(bufferPtr),(LPSTR)tempBuffer);
            if (showTS) {
               Sds2AbiReadFrameStamp(0,curFrame,&FrameTS,&FrameTSM);
               if ((retStatus = TrcGetTimestampText(dqState->traceId,FrameTS,
                  FrameTSM,prevFrame,bufferPtr)) != GOOD) return(retStatus);
               prevFrame = curFrame;
            }
            wsprintf(tempBuffer, "  %05lX   %s\r\n", startAddr, instText);
            lstrcat((LPSTR)(bufferPtr),(LPSTR)tempBuffer);
         }
 /* eof <Winky 10/17/1997> */

         if ((err = AdrCreateAddressWithType(ADDR_PHYSICAL,&descs[countInst]))!=GOOD)
            return(err);
         AdrSetAddrOffset(descs[countInst],startAddr);
         buffIndex[++countInst] = bufferPtr +  _fstrlen(bufferPtr);
         if (countInst >= MaxIndexLen)
            break;

         /* Check whether remaining bytes construct a complete instruction */
         DadGetDqOffset(dqStateId,&remainByte);
         TrcReadFrameGet(dqState->traceId,&printEndFrame);
         if (checkStatus == TRACE_TRANSFER_INST) {
            while (1) { /* skip till RW frames */
               if (printStartFrame == printEndFrame) break;
               ReadOneTrace(dqStateId,printStartFrame,&dqFrame);
               if (CheckSpaceType(S_PROGRAM, dqFrame.statusPin) != GOOD) 
                    break;
               printStartFrame++; 
            }
         }
         if (printStartFrame != printEndFrame) {
            tempCount = countInst;
            PrintRemainsFrame(dqStateId,printStartFrame,&printEndFrame,
               bufferPtr,buffIndex,&countInst,descs);
            for (lp = tempCount; lp < countInst; lp++)
               AdrSetAddrOffset(descs[lp],startAddr);
            printStartFrame = printEndFrame;
            if ((countInst >= *numInst) || (countInst >= MaxIndexLen))
                break;
         }
         if ((remainByte > 0) && (checkStatus != TRACE_TRANSFER_INST) &&
             (accessSize != ACCESSSIZE88)) {
            codeOffset = dasmInfo.bytesUsed;
            instText[0] = 0;
            addrOffset = startAddr+dasmInfo.bytesUsed;
            AdrSetAddrOffset(addrId,addrOffset);
            TrcReadFrameGet(dqState->traceId,&curFrame);
            retStatus = DadGetDasmInstruction(addrId, ADDR_USE_16,
                            &objCode[codeOffset],instText,&dasmInfo);
            if ((retStatus = TrcReadFrameGet(dqState->traceId, &curFrame)) != GOOD)
               return(retStatus);
            if (dasmInfo.bytesUsed == remainByte) {

               if ((instText[0] != '\0') && (checkStatus != QUEUE_INST)) {

 /* <Winky 10/17/1997> */
                  if (strcmp(instText,instInt)!=0) {
                     wsprintf(tempBuffer, "%8ld ", curFrame);
                     lstrcat((LPSTR)(bufferPtr),(LPSTR)tempBuffer);
                     if (showTS) {
                        Sds2AbiReadFrameStamp(0,curFrame,&FrameTS,&FrameTSM);
                        if ((retStatus = TrcGetTimestampText(dqState->traceId,
                             FrameTS,FrameTSM,prevFrame,bufferPtr)) != GOOD)
                           return(retStatus);
                        prevFrame = curFrame;
                     }
                     wsprintf(tempBuffer,"  %05lX   %s\r\n",startAddr,instText);
                     lstrcat((LPSTR)(bufferPtr),(LPSTR)tempBuffer);
                  }
 /* eof <Winky 10/17/1997> */

                  if ((err = AdrCreateAddressWithType(ADDR_PHYSICAL,&descs[countInst]))!=GOOD)
                     return(err);
                  AdrSetAddrOffset(descs[countInst],addrOffset);
                  buffIndex[++countInst] = bufferPtr + _fstrlen(bufferPtr);
                  if (countInst >= MaxIndexLen)
                     break;
               }
               DadSetDqOffset(dqStateId,0);
               if ((retStatus = TrcReadFrameGet(dqState->traceId, &curFrame)) != GOOD)
                  return(retStatus);
               if (curFrame == newest) break;
               if ((retStatus = TrcReadFrameSet(dqState->traceId,curFrame+1)) != GOOD) 
                  return(retStatus);
               PrintRWCycle(dqStateId,curFrame+1,&tmpFrame,bufferPtr,
                  buffIndex,&countInst,descs,(U16)*numInst);
               CheckFlush(dqStateId, &dasmInfo,startAddr+remainByte);
            }
            if (printStartFrame != printEndFrame) {
               tempCount = countInst;
               PrintRemainsFrame(dqStateId,printStartFrame,&printEndFrame,bufferPtr,
                          buffIndex,&countInst,descs);
               for (lp = tempCount; lp < countInst; lp++)
                  AdrSetAddrOffset(descs[lp],addrOffset);
            }
         }
         TrcReadFrameGet(dqState->traceId,&printEndFrame);
      }
      else _fstrcat((LPSTR)(bufferPtr), (LPSTR)"   (??)");   /* cannot judge */
      if ((countInst >= *numInst) || (countInst >= MaxIndexLen))
         break;

      if ((retStatus = TrcReadFrameGet(dqState->traceId, &curFrame)) != GOOD)
         return(retStatus);
      if (curFrame > newest) break;
   }  /* end of while (Frame <= newest) */

   if (err != GOOD) {
      printEndFrame = newest;    
      PrintRemainsFrame(dqStateId,printStartFrame,&printEndFrame,
         bufferPtr,buffIndex,&countInst,descs);
   }

   AdrDestroyAddress(dasmInfo.target);
   AdrDestroyAddress(addrId);
   DadGetDqOffset(dqStateId,&remainByte);
   ReadOneTrace(dqStateId,printEndFrame,&dqFrame);
   lastFrame = printEndFrame;
   if ((remainByte == 0) && (printEndFrame != newest) &&
       (CheckSpaceType(S_PROGRAM, dqFrame.statusPin) == GOOD)) {
         *endFrame = printEndFrame-1;
   }
   else *endFrame = printEndFrame;
   *indexLen = countInst;
   *numInst = countInst;
   return(retStatus);
}



/****************************************************************************
**
** Name:  FindInstStart
**
****************************************************************************/
RETCODE FindInstStart(DESCRIPTOR dqStateId, S32 curFrame, S32 *startFrame){
DQ_FRAME findFrame[FRAME_BUFF_LEN];
U32 numGotten;
S32 oldFrameNo,oldest,newest,trig,tmpFrame,preTmpFrame;
U16 lp,readLen,lp2;
LPSTR buffer;
RETCODE err = GOOD;
U8 objCode[30];
DASM_INFO dasmInfo;
U32 startAddr;
DQ_STATE FAR *dqState;
U8 instText[80],objLen;
DESCRIPTOR addrId;
U16 remainByte,preRemainByte;

   if ((dqState = (DQ_STATE FAR *)dqStateId) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);

   AdrCreateAddressWithType(ADDR_PHYSICAL,(DESCRIPTOR FAR *)&addrId);
   AdrCreateAddressWithType(ADDR_PHYSICAL,(DESCRIPTOR FAR *)&dasmInfo.target);

   for (lp = 0; lp < FRAME_BUFF_LEN; lp++)
      findFrame[lp].frameNo = NULL_FRAME_NO;
   TrcReadFrameGet(dqState->traceId,&oldFrameNo);

   if ((err = TrcTraceBufferInfoGet(dqState->traceId,&oldest,&newest,&trig))
      != GOOD) return(err);
   if ((curFrame - 63) < oldest) {
      TrcReadFrameSet(dqState->traceId,oldest);
      readLen = curFrame - oldest + 1;
   }
   else {
      TrcReadFrameSet(dqState->traceId,curFrame-63);
      readLen = FRAME_BUFF_LEN;
   }
   if ((err = TrcTraceReadRaw(dqState->traceId,readLen,
              (U32 far *)&numGotten, &buffer)) != GOOD) return(err);

   for (lp = 0; lp < numGotten; lp++) {
      memcpy(&(findFrame[lp]),
             (buffer+lp*TRACE_FRAME_WIDTH),TRACE_FRAME_WIDTH);
   }
   TFree(buffer);
   TrcReadFrameSet(dqState->traceId,oldFrameNo);
//   DadSetDqOffset(dqStateId,0);

   for (lp = numGotten;lp > 0; lp--) {
      if (ISFLUSH(findFrame[lp-1].statusPin)) {
         tmpFrame = curFrame + lp - numGotten;
         ///////
         for (lp2 = 0;lp2 < 128;lp2++) {
            TrcReadFrameSet(dqState->traceId,tmpFrame);

            ReadInstDataAndAddress(dqStateId,objCode,&objLen,&startAddr);
            TrcReadFrameGet(dqState->traceId,&tmpFrame);
            preTmpFrame = tmpFrame;
            if (objLen == 0) break;
            AdrSetAddrOffset(addrId,startAddr);
            instText[0] = 0;
            DadGetDqOffset(dqStateId,&preRemainByte);
            DadGetDasmInstruction(addrId, ADDR_USE_16, objCode,
                                  instText,&dasmInfo);
            SkipTraceData(dqStateId,dasmInfo.bytesUsed,tmpFrame,S_PROGRAM);
            TrcReadFrameGet(dqState->traceId,&tmpFrame);
            if (tmpFrame > curFrame) {
                tmpFrame = preTmpFrame;
                DadSetDqOffset(dqStateId,preRemainByte);
                break;
            }
            else if (tmpFrame == curFrame) {
                tmpFrame = curFrame;
                if (dasmInfo.bytesUsed == 1) DadSetDqOffset(dqStateId,0);
                break;
            }
         }
         DadGetDqOffset(dqStateId,&remainByte);
         ///////
         *startFrame = tmpFrame;
         break;
      }
   }
   AdrDestroyAddress(dasmInfo.target);
   AdrDestroyAddress(addrId);
   if (lp == 0) *startFrame = curFrame;
   return(err);
}

/****************************************************************************
**
** Name:  DadForwardDqInst
**
****************************************************************************/
RETCODE EXPORT DadForwardDqInst(DESCRIPTOR id,U32 numInst,S32 FAR *startFrame,
                        S32 FAR *endFrame, LPSTR *buffer, U16 FAR *textLen,
                        DESCRIPTOR FAR **addrDesc) {

U32 instNo = numInst;
S32 curFrame,firstFrame,secondFrame,flushFrame,tmpEnd;
DQ_STATE FAR *dqState;
RETCODE status;
LPSTR buffIndex[MAX_NUM_DQ+1]; //add 1 by cjchen 1997.6.12
U16 totalLen,lp,indexLen = 0,instCount;
DESCRIPTOR checkDesc[MAX_NUM_DQ];
S32 oldest, newest, trig;

   if ((dqState = (DQ_STATE FAR *)id) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);

   if ((status = TrcReadFrameGet(dqState->traceId, &curFrame)) != GOOD)
      return(status);
   if ((status = TrcTraceBufferInfoGet(dqState->traceId,&oldest,&newest,&trig))
      != GOOD) return(status);

   if (curFrame < oldest) {
      curFrame = oldest;
      TrcReadFrameSet(dqState->traceId,curFrame);
   } else if (curFrame > newest) {
      curFrame = newest;
      TrcReadFrameSet(dqState->traceId,curFrame);
   }

   AddDqStateTable(id,curFrame);
   FindInstStart(id,curFrame,&flushFrame);
   if ((status = TrcReadFrameSet(dqState->traceId, flushFrame)) != GOOD)
         return(status);
   if (accessSize == ACCESSSIZE86) instNo += (curFrame - flushFrame)*2;
   else instNo += (curFrame - flushFrame);
   if (instNo > MAX_NUM_DQ) instNo = MAX_NUM_DQ;

   if((*addrDesc=(DESCRIPTOR *)TMalloc(sizeof(DESCRIPTOR)*MAX_NUM_DQ))
       == NULL) {
      return(ER_OUT_OF_MEMORY);
   }
   for (lp = 0; lp < MAX_NUM_DQ; lp++)
      addrDesc[0][lp] = checkDesc[lp] = NULL;

   MaxIndexLen = MAX_NUM_DQ;
   if ((status = DqInst(id,&instNo,startFrame,endFrame,buffer,buffIndex,
                        &indexLen,checkDesc))
      != GOOD) return(status);

   tmpEnd = *endFrame;
   if (curFrame == newest && curFrame == lastFrame) indexLen = 0;

   if (indexLen <= 1) {
      if (indexLen == 1) {
         sscanf(buffIndex[0]," %ld",endFrame);
         if (curFrame > *endFrame) {
            **buffer = 0;
            *textLen = 0;
            *startFrame = *endFrame = curFrame;
            AdrDestroyAddress(checkDesc[0]);
            checkDesc[0] = NULL;
         }
         else {
            memcpy(*buffer,buffIndex[0],strlen(buffIndex[0]));
            *textLen = lstrlen(*buffer);
            *startFrame = *endFrame;
         }
      }
      else {
         **buffer = 0;
         *textLen = 0;
         *startFrame = *endFrame = curFrame;
      }
   }
   else {
      lp = 0;
      while(indexLen > (lp+1)) {
         sscanf(buffIndex[lp]," %ld",&firstFrame);
         sscanf(buffIndex[lp+1]," %ld",&secondFrame);
         if (curFrame == firstFrame) break;
         else if((firstFrame < curFrame) && (secondFrame > curFrame)) {
           lp++;
           break;
         }
         lp++;
      };
      for (instCount = 0; instCount < lp; instCount++) {
         AdrDestroyAddress(checkDesc[instCount]);
         checkDesc[instCount] = NULL;
      }
/* <Judy 5/27/1997> The block makes some instructions missing
      if ((indexLen- lp) > numInst) {
         *(buffIndex[(U16)(lp+numInst)]) = 0;
         sscanf(buffIndex[(U16)(lp+numInst-1)]," %ld",endFrame);
         tmpEnd = *endFrame;
         totalLen = numInst; ** temp data.
 **         for (instCount = (lp+numInst-1); instCount < instNo; instCount++) {
         for (instCount = (lp+numInst); instCount < instNo; instCount++) {
            AdrDestroyAddress(checkDesc[instCount]);
            checkDesc[instCount] = NULL;
         }
      }
      else {
         sscanf(buffIndex[indexLen-1]," %ld",endFrame);
         totalLen = indexLen - lp + 1;
      } */
      sscanf(buffIndex[indexLen-1]," %ld",endFrame);
      totalLen = indexLen - lp + 1;
/* eof <Judy 5/27/1997> */
      if ((indexLen <= (lp+1)) && (curFrame > *endFrame)) {
         **buffer = 0;
         *textLen = 0;
         *startFrame = *endFrame = curFrame;
         for (instCount = totalLen; instCount < instNo; instCount++) {
            AdrDestroyAddress(checkDesc[instCount]);
            checkDesc[instCount] = NULL;
         }
      }
      else {
         memcpy(*buffer,buffIndex[lp],strlen(buffIndex[lp]));
         for (instCount = 0; instCount < totalLen; instCount++) {
            checkDesc[instCount] = checkDesc[lp+instCount];
         }
   //    memcpy(*addrDesc,addrDesc[0][lp],sizeof(DESCRIPTOR)*totalLen);
         for (instCount = totalLen; instCount < instNo; instCount++)
            checkDesc[instCount] = NULL;
         *(*buffer+ strlen(buffIndex[lp])) = 0;
         *textLen = lstrlen(*buffer);
         sscanf(*buffer," %ld",startFrame);
      }
   }

   for (instCount = 0; instCount < indexLen; instCount++)
      addrDesc[0][instCount] = checkDesc[instCount];

   if ((status = TrcReadFrameGet(dqState->traceId, &curFrame)) != GOOD) {
       for (lp = 0; lp < MAX_NUM_DQ; lp++) {
          if (checkDesc[lp] != NULL)
             AdrDestroyAddress(checkDesc[lp]);
          checkDesc[lp] = NULL;
       }
      return(status);
   }
//   if ((status = TrcReadFrameSet(dqState->traceId, curFrame)) != GOOD)
//      return(status);
   *endFrame = tmpEnd;

/*   for (lp = 0; lp < MAX_NUM_DQ; lp++) {
      if (checkDesc[lp] != NULL)
         AdrDestroyAddress(checkDesc[lp]);
      checkDesc[lp] = NULL;
   } */
   return(GOOD);

}

/****************************************************************************
**
** Name:  DadBackwardDqInst
**
****************************************************************************/
RETCODE EXPORT DadBackwardDqInst(DESCRIPTOR id,U32 numInst,S32 FAR *startFrame,
                        S32 FAR *endFrame, LPSTR *buffer, U16 FAR *textLen,
                        DESCRIPTOR FAR **addrDesc) {
U32 instNo = numInst;
S32 curFrame,preFrame,instFrame;
DQ_STATE FAR *dqState;
RETCODE status;
LPSTR partBuff[5],tempBuff;//,headPtr
U16 lp,lp2,lp3;
U16 totalLen,remainByte;
S16 tempSegment,tempOffset;
//S8 frmaeNoStr[10];
S32 oldest,newest,trig,firstFrame,secondFrame;
LPSTR buffIndex[MAX_NUM_DQ+1]; //add 1 by cjchen 1997.6.12
U16 indexLen[5],totalIndexLen = 0;
U32 indexOffset;
U16 stringLen,instCount;
DESCRIPTOR checkDesc[MAX_NUM_DQ];

   if ((dqState = (DQ_STATE FAR *)id) == NULL)
      return (ER_DAD_INVALID_ID_DESCRIPTOR);

   if ((status = TrcReadFrameGet(dqState->traceId, &curFrame)) != GOOD)
      return(status);
   if ((status = TrcTraceBufferInfoGet(dqState->traceId,&oldest,&newest,&trig))
      != GOOD) return(status);

   if (curFrame < oldest) {
      curFrame = oldest;
      TrcReadFrameSet(dqState->traceId,curFrame);
   } else if (curFrame > newest) {
      curFrame = newest;
      TrcReadFrameSet(dqState->traceId,curFrame);
   }

   if((*addrDesc=(DESCRIPTOR *)TMalloc(sizeof(DESCRIPTOR)*MAX_NUM_DQ))
       == NULL) {
      TFree(*buffer);
      return(ER_OUT_OF_MEMORY);
   }
   for (lp = 0; lp < MAX_NUM_DQ; lp++)
      addrDesc[0][lp] = checkDesc[lp] = NULL;

//   instNo += numInst/5;
   if (accessSize == ACCESSSIZE86) preFrame = curFrame - numInst*3/2;
   else preFrame = curFrame - numInst*2;
   if (preFrame < oldest) preFrame = oldest;
   FindInstStart(id, preFrame, &instFrame);
   preFrame = instFrame;
   lp =0;
   DadSetDqOffset(id,0);

   do {
      if ((status = TrcReadFrameSet(dqState->traceId, preFrame)) != GOOD)
         return(status);
      MaxIndexLen = MAX_NUM_DQ - totalIndexLen;
      if ((status = DqInst(id,&instNo,startFrame,endFrame,&partBuff[lp],
             &buffIndex[totalIndexLen],&indexLen[lp],&(checkDesc[totalIndexLen])))
      != GOOD) return(status);
/* <Judy 5/23/97> To adjust next needed instruction number */
      instNo=((curFrame-(*endFrame)) > 100) ? 100: curFrame-(*endFrame);
/* eof <Judy 5/27/1997> */
      totalIndexLen += indexLen[lp];
//    if (curFrame > *endFrame) {
//    }
      lp++;

      DadGetDqOffset(id,&remainByte);
      if (remainByte == 0) preFrame = *endFrame + 1;
      else preFrame = *endFrame;
   }while((curFrame > *endFrame) && (lp < 5));

   totalLen = 0;
   for (lp2 = 0; lp2 < lp; lp2++)
      totalLen += strlen(partBuff[lp2]);
   if ((tempBuff = TMalloc(totalLen+1)) == NULL)
      return(ER_OUT_OF_MEMORY);


   memset(tempBuff,'\0',2);
   for (lp2 = 0; lp2 < lp; lp2++)
      strcat(tempBuff,partBuff[lp2]);


   stringLen = 0;
   totalIndexLen = 0;
   for (lp3 = 0; lp3 < lp ; lp3++) {
      tempSegment = FP_SEG(buffIndex[totalIndexLen]) - FP_SEG(tempBuff);
      tempOffset = FP_OFF(buffIndex[totalIndexLen]) - FP_OFF(tempBuff);
      tempOffset -= stringLen;
      stringLen += strlen(partBuff[lp3]);
      for (lp2 = 0; lp2 < indexLen[lp3]; lp2++) {
         indexOffset = FP_SEG(buffIndex[lp2+totalIndexLen]) - tempSegment;
         indexOffset <<=16;
         indexOffset += (FP_OFF(buffIndex[lp2+totalIndexLen]) - tempOffset);
         buffIndex[lp2+totalIndexLen] = (LPSTR)indexOffset;// +
         //   (FP_OFF(buffIndex[lp2+totalIndexLen]) - tempOffset);
      }
      totalIndexLen += indexLen[lp3];
   }

   lp3 = 0;
   while(totalIndexLen > lp3) {
      sscanf(buffIndex[lp3]," %ld",&firstFrame);
      sscanf(buffIndex[lp3+1]," %ld",&secondFrame);
      if (curFrame == firstFrame) {
         lp3++;
         break;
      }
      else if((firstFrame < curFrame) && (secondFrame > curFrame)) {
         lp3++;
         break;
      }
      lp3++;
   };
   *endFrame = firstFrame;
   for (instCount = lp3; instCount < totalIndexLen; instCount++) {
      AdrDestroyAddress(checkDesc[instCount]);
      checkDesc[instCount] = NULL;
   }

   *(tempBuff+ strlen(tempBuff) - strlen(buffIndex[lp3])) = 0;
   if (lp3 > numInst) {
      stringLen = strlen(buffIndex[(U16)(lp3-numInst)]);
      memcpy(tempBuff,buffIndex[(U16)(lp3-numInst)],stringLen);
      for (instCount = 0; instCount < (lp3 - numInst); instCount++) {
         AdrDestroyAddress(checkDesc[instCount]);
         checkDesc[instCount] = NULL;
      }
      memcpy(*addrDesc,&checkDesc[instCount],
             (U16)(sizeof(DESCRIPTOR)*(numInst)));
   }
   else {
      memcpy(*addrDesc,&checkDesc[0], sizeof(DESCRIPTOR)*(lp3));

      stringLen = strlen(buffIndex[0]);
      memcpy(tempBuff,buffIndex[0],stringLen);
   }
   *(tempBuff+stringLen) = 0;
   sscanf(tempBuff," %ld",startFrame);



   totalLen = strlen(tempBuff);
   if ((*buffer = TMalloc(totalLen+1)) == NULL)
      return(ER_OUT_OF_MEMORY);
   memcpy(*buffer,tempBuff,totalLen);
   if ((status = TrcReadFrameSet(dqState->traceId, curFrame)) != GOOD)
      return(status);

   *textLen = lstrlen(*buffer);
   for (lp2 = 0; lp2 < lp; lp2++) {
      if (*(partBuff[lp2])!='\0')
         TFree(partBuff[lp2]);
   }
   if (*tempBuff!='\0')
      TFree(tempBuff);

/*   for (lp = 0; lp < MAX_NUM_DQ; lp++) {
      if (checkDesc[lp] != NULL)
         AdrDestroyAddress(checkDesc[lp]);
      checkDesc[lp] = NULL;
   } */
//   OutputStringToFile(*buffer,*textLen);
   return(GOOD);

}


/****************************************************************************
**
**  DadDqFlush
**
****************************************************************************/
#pragma argsused
RETCODE EXPORT DadDqFlush(DESCRIPTOR id) {
   return(GOOD);
}
//--------------------------- end of dequeuer-186 --------------------------
