/***************************************************************************
**
** File name : exec68k.c
**
**
**
** Changing :
**
** A. Date -- 10/19/1992 By Cheerson
**    0. Received from Matthew as the initial version.
**    1. Gather and sort externals/includes/local definitions ..etc.
**    2. Program source code alignment, follow the "coding standard".
**
** B. Date -- 10/29/1992 By Cheerson
**     0. Update the include files.
**
**
**
** X. Date -- 12/18/1992 By Cheerson
**    0. Delete iceGetPC() routine.
**    1. Replace the "iceGetPC()" calling of the iceRunUntil() to be
**       iceGetRegister(REG_PC,&addr).
**
**
**    Copyright (C) 1992 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

/***************************************************************************
**
**    Include files
**
***************************************************************************/

//#include <ctype.h>

#ifndef _COMM_
#include "comm.h"
#endif

#ifndef _ABI_DEF_
#include "abidef.h"
#endif

#ifndef _REG68306_DEFINE_
#include "reg68k.h"
#endif

#ifndef _ABI_EXTERNAL_
#include "abiexts.h"
#endif

#define FRAME_WIDTH           22
#define TRC_BLOCK_SIZE        32
#define TRC_ARRAY_SIZE        16 //TRC_BUFF_SIZE /TRC_BLOCK_SIZE
#define TRC_BUFF_SIZE         (TRC_BLOCK_SIZE*TRC_ARRAY_SIZE)
#define CC_INFO_LEN          640   // get max 640 bytes data from FW

extern U8 BASE_TIME;

S8 bNo[TRC_ARRAY_SIZE];
MP_TRACE_INFO traceBuff[TRC_BUFF_SIZE];
MP_TRACE_INFO qualifyBuff[TRC_BLOCK_SIZE];
S32 oldestFrame,newestFrame;
S16 bufSeg = 0;
U16 curBuffID = 0xffff;

RETCODE GetQualifyFrame(S16 bufID, S32 startFrame, QUALIFY_LIST *cond );

/**************************************************************************
**
** Local define
**
***************************************************************************/

/**************************************************************************
**
** Local variables
**
***************************************************************************/

/**************************************************************************
**
** Externals
**
**************************************************************************/

/**************************************************************************
**
** Execution codes
**
**************************************************************************/

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceClearEvent(U16 evId) {
RETCODE status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(CLR_EVENT,lp);

   varWidth = sizeof(evId);
   SaveVar(evId,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name : iceStepRange()
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceStepRange(ADDR addr1, ADDR addr2) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(STEP,lp);

   varWidth = sizeof(addr1);
   SaveVar(addr1,lp,varWidth);

   varWidth = sizeof(addr2);
   SaveVar(addr2,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*4);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
//   iceGetAllReg();
   return(*((U16 *)&inputStream[0]));

}      /* end of iceStepRange() */

/**************************************************************************
**
** Name : iceStepOne()
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceStepOne(VOID){
U16 lp;
RETCODE status;

   lp = 0;
   SaveId(STEP_ONE,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*4);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}      /* end of iceStepOne() */

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/

RETCODE EXPORT iceAbort(VOID) {
U16 lp;
RETCODE status;

   lp = 0;
   SaveId(ABORT,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
/*
iceStepRange(U16 addr, S16 OVER) {

unsigned long old, line_begin, line_end, l;
unsigned long oldSP;
unsigned int i;

   old = pc;
   iceGetReg(I86_REG,CS, (U32)&oldCS);
   getAdrRange(old, addr);
    line_begin=RangeAdr.low;
   line_end=RangeAdr.high;
   if (OVER) oldSP = sp;
   if (step_range(line_begin, line_end) == HALT_USER) return(HALT_USER);
   if (!(ABS86_comp_addr(pc, line_end+1))) return(OK);
   if (OVER) {
      if (oldSP == sp) return(OK);
      iceGetReg(I86_REG,CS, &l);
      if (oldCS == l) {
         l = (oldCS << 16);
         l += (getStack(sp,0) & 0xffff);
      } else l = getStack(sp,1);
      if (ABS86_comp_addr(l, line_begin) >= 0 &&
            ABS86_comp_addr(l, line_end+1) <= 0)
         skipSub(); // skip subroutine/interrupt handler
      if (ABS86_comp_addr(pc, line_begin) >= 0 &&
            ABS86_comp_addr(pc, line_end) <= 0)
         step_range(pc, line_end);
   }
   return (OK);
}
*/
/**************************************************************************
**
** Name : iceReset
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceReset(VOID){
RETCODE status;
U16 lp = 0;

   SaveId(RESET,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*(U16 *)(&inputStream[0]));

}
/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGetCpuStatus(U8 *goEnd) {
U16 lp;
RETCODE status;

   lp = 0;
   SaveId(GET_CPU_STATUS,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   *goEnd = inputStream[2];
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGo(U16 mode) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(GO_COMMAND,lp);

   varWidth = sizeof(mode);
   SaveVar(mode,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   for (lp = 0; lp < TRC_ARRAY_SIZE; lp++)
      bNo[lp] = 0; // clear the cache of trace data.
   curBuffID = 0xffff; // clear bufID
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/

RETCODE EXPORT iceGetTraceBufferInfo(U16 bufID, S32 *start, S32 *end) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(GET_DEPTH,lp);
   varWidth = sizeof(bufID);
   SaveVar(bufID,lp,varWidth);
   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*8);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   //_fmemcpy(&traceDepth[bufID],&inputStream[3],sizeof(struct depth_strct));  // kkk
   _fmemcpy(start,&inputStream[3],sizeof(*start));
   _fmemcpy(end,&inputStream[3+sizeof(*start)],sizeof(*end));
   return(*((U16 *)&inputStream[0]));
}


/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE NextRead(S16 bufID, S32 startFrame){
RETCODE status,err;
QUALIFY_LIST condition;
U16 lp,index,pos;
U8 varWidth;

   status = GOOD;
   condition.qFlag = OFF;
   lp = 0;
   SaveId(LIST_TRACE,lp);

   varWidth = sizeof(bufID);
   SaveVar(bufID,lp,varWidth);

   varWidth = sizeof(startFrame);
   SaveVar(startFrame,lp,varWidth);

   varWidth = sizeof(QUALIFY_LIST);
   SaveBuff(&condition,lp,varWidth);

   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*8);
   //Eric 1/16/98
   err = *((U16 *)&inputStream[0]);
   if (err!=GOOD) return(err);
   //eof Eric 1/16/98
   //inputStream[2] = 64;
   index = (startFrame-oldestFrame) % TRC_BUFF_SIZE;
   for (lp = 0; lp < inputStream[2]; lp++) {
      pos = lp*FRAME_WIDTH;
      traceBuff[index+lp].frameNo = startFrame + lp;
      traceBuff[index+lp].addr = *(U32 *)&inputStream[pos+3];
      traceBuff[index+lp].data = *(U32 *)&inputStream[pos+7];
      traceBuff[index+lp].tbit = inputStream[pos+11];
      traceBuff[index+lp].stat = *(U16 *)&inputStream[pos+12];
      traceBuff[index+lp].TPort = *(U32 *)&inputStream[pos+14];
      traceBuff[index+lp].tstamp = *(U32 *)&inputStream[pos+18];
      traceBuff[index+lp].tstampMSB = inputStream[pos+22];
      traceBuff[index+lp].evtMatch = inputStream[pos+23];
      traceBuff[index+lp].seqLevel = inputStream[pos+24];
   }
   return(status);
}

RETCODE EXPORT iceGetTraceFrame(U16 bufID, S32 startFrame,QUALIFY_LIST *cond,
                                U8 *frameLen, MP_TRACE_INFO *frameData) {
S32 i, curFrame;
S32 curSeg, curOffset;
S16 lp,lp2;
RETCODE err;


   if (curBuffID != bufID) {
      iceGetTraceBufferInfo(bufID, &oldestFrame, &newestFrame);
      curBuffID = bufID;
      for (lp2=0;lp2 < TRC_ARRAY_SIZE; lp2++) bNo[lp2]=0;
   }
   if ((startFrame < oldestFrame) || (startFrame > newestFrame))
      return(ICE_BAD_FRAME);
   if (cond->qFlag == OFF) {
      for (lp = 0; lp < *frameLen; lp++) {
	 curFrame = (startFrame+lp)-oldestFrame;
	 curSeg = curFrame/TRC_BUFF_SIZE;
	 curOffset = curFrame % TRC_BUFF_SIZE;
	 if (bufSeg != curSeg) {
	    bufSeg = curSeg;
	    for (lp2=0;lp2 < TRC_ARRAY_SIZE; lp2++) bNo[lp2]=0;
	 }
	 i = curOffset/TRC_BLOCK_SIZE;
	 if (!bNo[i]) {
	    //if (NextRead(bufID, curFrame/TRC_BLOCK_SIZE*TRC_BLOCK_SIZE+oldestFrame)
	    //    == ICE_HALT_USER) return(ICE_HALT_USER);
	    /*Eric 1/19/98*/
	    if ((err=NextRead(bufID, curFrame/TRC_BLOCK_SIZE*TRC_BLOCK_SIZE+oldestFrame))
                == ICE_HALT_USER) return(ICE_HALT_USER);
            if (err!=GOOD) return(err);
	    /*eof Eric 1/19/98*/
	    bNo[i] = 1;
	 }
	 memcpy(&frameData[lp], &traceBuff[curOffset],sizeof(MP_TRACE_INFO));
	 if ((startFrame+lp+1) >= newestFrame) {  // gene
	    *frameLen = lp+1;
	    break;
	 }
      }
   } else {
      GetQualifyFrame(bufID, startFrame, cond);
      memcpy(&frameData[0], &qualifyBuff[0],sizeof(MP_TRACE_INFO));
   }
   return(GOOD);
}

RETCODE GetQualifyFrame(S16 bufID, S32 startFrame, QUALIFY_LIST *cond ){
RETCODE status;
U16 lp;
U8 varWidth;

   status = GOOD;
   lp = 0;
   SaveId(LIST_TRACE,lp);

   varWidth = sizeof(bufID);
   SaveVar(bufID,lp,varWidth);

   varWidth = sizeof(startFrame);
   SaveVar(startFrame,lp,varWidth);

   varWidth = sizeof(QUALIFY_LIST);
   SaveBuff(cond,lp,varWidth);

   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*8);
   qualifyBuff[0].addr = *(U32 *)&inputStream[3];
   qualifyBuff[0].data = *(U16 *)&inputStream[7];
   qualifyBuff[0].stat = inputStream[9];
   qualifyBuff[0].tbit = inputStream[11];
   qualifyBuff[0].TPort = *(U32 *)&inputStream[12];
   qualifyBuff[0].tstamp = *(U32 *)&inputStream[16];
   qualifyBuff[0].tstampMSB = inputStream[20];
   qualifyBuff[0].evtMatch = inputStream[21];
   qualifyBuff[0].seqLevel = inputStream[22];
   qualifyBuff[0].frameNo = *(U32 *)&inputStream[23];
   return(status);
}


//RETCODE EXPORT iceGetTraceFrame(U16 bufID, S32 startFrame,QUALIFY_LIST *cond, U8 *frameLen, MP_TRACE_INFO *frameData) {
//U16 lp, l;
//U8 varWidth;
//RETCODE status;
//
//   l = (U16)*frameLen;
//   lp = 0;
//   SaveId(LIST_TRACE,lp);
//
//   varWidth = sizeof(bufID);
//   SaveVar(bufID,lp,varWidth);
//
//   varWidth = sizeof(startFrame);
//   SaveVar(startFrame,lp,varWidth);
//
//   varWidth = sizeof(QUALIFY_LIST);
//   SaveBuff(cond,lp,varWidth);
//
//   outputStream[lp++] = 0;
//
//   SendStream(outputStream,lp);
//   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*8);
//   if (status == ICE_REC_TIME_OUT) return(status);
//   *frameLen = inputStream[2];
//   if (*frameLen > l) *frameLen = l;
//   for (lp = 0; lp < *frameLen; lp++) {
//// vincent      frameData[lp].frameNo = *(U32 *)&inputStream[3+lp*13];
//      l = lp*16 + 3;
//      frameData[lp].data = ((U16)inputStream[l] << 8);
//      frameData[lp].data |= inputStream[l+1];
//      frameData[lp].stat = *(U16 *)&inputStream[l+4];
//      frameData[lp].tstamp = inputStream[l+6];
//      frameData[lp].spare   = inputStream[l+7];
//      frameData[lp].addr = *(U32 *)&inputStream[l+8];
//      frameData[lp].misc = *(U32 *)&inputStream[l+12];
//   }
//   return(*((U16 *)&inputStream[0]));
//}
//
/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetEvent(U16 evId, BUS_EVENT *busEventData) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(SET_EVENT,lp);

   varWidth = sizeof(evId);
   SaveVar(evId,lp,varWidth);

   varWidth = sizeof(BUS_EVENT);
   SaveBuff(busEventData,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetAllEvents(BUS_EVENT *event_record, EXEC_EVENT *bp_record, U16 ext_record) {
U16 lp;
U8 varWidth;
RETCODE status;

   lp = 0;
   SaveId(SET_ALL_EVENT,lp);

   varWidth = sizeof(BUS_EVENT)*8;
   SaveBuff(event_record,lp,varWidth);

   varWidth = sizeof(EXEC_EVENT)*2;
   SaveBuff(bp_record,lp,varWidth);

   varWidth = sizeof(U16);
   SaveVar(ext_record,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetExtEvent(U16 evData) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(SET_EXT_EVENT,lp);

   varWidth = sizeof(evData);
   SaveVar(evData,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGetEvent(BUS_EVENT *event_record, EXEC_EVENT *bp_record, U16 *ext_record,
                 U8 *cntFlag, U32 *timerRecord, U16 *counter) {
U16 lp,tempFlag,pos,dataLen,data0,data1;
RETCODE status;

   lp = 0;
   SaveId(GET_EVENT,lp);
   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);

   pos = 3;
   dataLen = sizeof(BUS_EVENT)*8;
   _fmemcpy(event_record,&inputStream[pos],dataLen);  // kkk

   pos += dataLen;
   dataLen = sizeof(EXEC_EVENT)*2;
   _fmemcpy(bp_record,&inputStream[pos],dataLen);  // kkk

   pos += dataLen;
   *ext_record = *(U16 *)(&inputStream[pos]);  // kkk

   pos += 2;
   tempFlag = *(U16 *)(&inputStream[pos]);  // kkk

   pos += 2;
   data0 = *(U16 *)(&inputStream[pos]);  // kkk

   pos += 2;
   data1 = *(U16 *)(&inputStream[pos]);  // kkk

   if (tempFlag == 2) { // timer
      *cntFlag = 4;
      *timerRecord = (data1 << 10) + data0 + 1;  // kkk
   }
   else { // counter0 ,counter1
      counter[0] = data0+1;  // kkk
      counter[1] = data1+1;  // kkk
      *cntFlag = 3;
   }
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetBP(U16 evId, ADDR addr) {
U16 lp;
RETCODE status;
U8 varWidth;

// HLFW did bias too.   evId -= 10; // ev0 - ev9 reserve for other event.
   if (addr.space == 8) addr.space = 5;
   lp = 0;
   SaveId(SET_EX_BKPT,lp);

   varWidth = sizeof(evId);
   SaveVar(evId,lp,varWidth);

   varWidth = sizeof(addr);
   SaveVar(addr,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceClearTrig(U16 levelNo) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(CLR_TRIG,lp);

   varWidth = sizeof(levelNo);
   SaveVar(levelNo,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetTrig(U16 levelNo, MP_TRIGGER *tmpTrig){
RETCODE status;
U16 lp,dataLen;
U8 varWidth,zero=0,one=1;

   lp = 0;
   SaveId(SET_TRIG,lp);
                            // every time setting trigger,
   if (levelNo == 4) {      // should set all 4 level
      SaveVar(one,lp,1);    // really set into HW
   } else {
      SaveVar(zero,lp,1);   // dummy setting in FW
   }

   varWidth = sizeof(levelNo);
   SaveVar(levelNo,lp,varWidth);

   dataLen = sizeof(tmpTrig->evNo);
   SaveBuff(tmpTrig->evNo,lp,dataLen);

   dataLen = sizeof(tmpTrig->act);
   SaveBuff(tmpTrig->act,lp,dataLen);

   varWidth = sizeof(tmpTrig->mode);
   SaveVar(tmpTrig->mode,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGetAllTrig(MP_TRIGGER *trig_record){
RETCODE status;
U16 lp,count;
U8 dataLen;

   lp = 0;
   SaveId(GET_TRIG,lp);

   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   status = *((U16 *)&inputStream[0]);
   if ((U16)status == ICE_OK) {
      dataLen = inputStream[2];
      count = 3;
      for (lp = 0; lp < 4; lp++) {
         _fmemcpy(&trig_record[lp],&inputStream[count],dataLen);  // kkk
         trig_record[lp].defined = (trig_record[lp].evNo[0] != 0) ? 1 : 0;  // kkk
         count += (dataLen+1);  // kkk
      }
   }
   return(status);

}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGetTraceInfo(U16 *lastBuff, U32 *curCNT0, U32 *curCNT1, U16 *bufNO){
RETCODE status;
U16 lp;

   lp = 0;
   SaveId(GET_LAST_BUFF,lp);

   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   status = *((U16 *)&inputStream[0]);
   if ((U16)status == ICE_OK) {
      *lastBuff = *(U16 *)&inputStream[3] + 1;  // kkk
      *curCNT1 = *(U32 *)&inputStream[6];  // kkk
      *curCNT0 = *(U32 *)&inputStream[11];  // kkk
      *bufNO = *(U16 *)&inputStream[16];  // kkk
   }
   return(status);

}
/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetTimerCounter(U16 tcFlag, U32 tcData1,U32 tcData2){
RETCODE status;
U16 lp = 0;
U8 varWidth;

   SaveId(SET_TIMER_COUNTER,lp);

   varWidth = sizeof(tcFlag);
   SaveVar(tcFlag,lp,varWidth);

   varWidth = sizeof(tcData1);
   SaveVar(tcData1,lp,varWidth);

   varWidth = sizeof(tcData2);
   SaveVar(tcData2,lp,varWidth);

   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetTraceBuffer(U16 traceBufNum) {
RETCODE status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(SET_TRACE_BUFF,lp);

   varWidth = sizeof(traceBufNum);
   SaveVar(traceBufNum,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));

}

RETCODE EXPORT iceGetTraceBuffer(U16 *traceBufNum) {

   *traceBufNum = 1;    //vvv
   return(GOOD);

}

RETCODE EXPORT iceGetTriggerFrame(U16 buffer, U32 *frame)
{
   *frame = (U32)0;     // vincent
   return(GOOD);
}
/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetTraceBreak(U16 breakFull) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(SET_TRACE_BREAK,lp);

   varWidth = sizeof(breakFull);
   SaveVar(breakFull,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));

}

// the follwoing codes are new added by Vincent
RETCODE EXPORT iceIsTraceBufferFull(U16 buffer, BOOLEAN *full)
{
   *full = TRUE;
   return(ICE_OK);
}

RETCODE EXPORT iceSetTraceOff(U16 trcOffFull) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(SET_TRACE_OFF_FULL,lp);

   varWidth = sizeof(trcOffFull);
   SaveVar(trcOffFull,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));

}

RETCODE EXPORT iceSetTrigOutAction(U16 trigOutAct) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(SET_TRIG_OUT_ACT,lp);

   varWidth = sizeof(trigOutAct);
   SaveVar(trigOutAct,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name : iceTraceAction
**
** Function :  control trace action start or stop
**
**    Input  : U8  0 : stop trace, 1 : start trace
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceTraceAction(U8 traceAction) {
RETCODE status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(TRACE_ACTION,lp);

   varWidth = sizeof(traceAction);
   SaveVar(traceAction,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   if (traceAction == 1) {
      for (lp=0;lp < TRC_ARRAY_SIZE; lp++) bNo[lp]=0;
      curBuffID = 0xffff;
   }

   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetQualTrace(U32 addr,U32 addrMask,U16 qStatus,U16 qStatusMask) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(SET_QUAL_TRACE,lp);

   varWidth = sizeof(addr);
   SaveVar(addr,lp,varWidth);

   varWidth = sizeof(addrMask);
   SaveVar(addrMask,lp,varWidth);

   varWidth = sizeof(qStatus);
   SaveVar(qStatus,lp,varWidth);

   varWidth = sizeof(qStatusMask);
   SaveVar(qStatusMask,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceDisableQual(VOID) {
U16 lp;
RETCODE status;
U8 varWidth;

   lp = 0;
   SaveId(DISABLE_QUAL,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if ((U16)status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name : iceWFROM
**
** Function :  Write flush rom data
**
**    Input  : (U8 *) data length is 32 bytes
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceWFROM(U8 *data) {
RETCODE status;
U16 lp;

   lp = 0;
   SaveId(W_FLUSH_ROM,lp);

   SaveBuff(data,lp,32);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name : iceRFROM
**
** Function :  Read flush rom data
**
**    Input  : (U8 *) data length is 32 bytes
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceRFROM(U8 *data) {
RETCODE status;
U16 lp;
U8 len;

   lp = 0;
   SaveId(R_FLUSH_ROM,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   if (status == GOOD) {
      len = inputStream[2];
      memcpy(data,&inputStream[3],len);
   }

   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name : iceReadFrameStamp
**
** Function :  read time stamp vlaue of trace frame
**
**    Input  : U16  bufId   : buffer ID
**             S32  frameNo : frame No to read
**             U32* ,U8*    : return time stamp value
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceReadFrameStamp(U16 bufId,S32 frameNo,U32 *stamp,U8 *stampMSB) {
RETCODE status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(READ_STAMP,lp);

   varWidth = sizeof(bufId);
   SaveVar(bufId,lp,varWidth);

   varWidth = sizeof(frameNo);
   SaveVar(frameNo,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   *stamp = *(U32 *)&inputStream[2];
   *stampMSB = inputStream[6];

   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name : iceReadLastStamp
**
** Function  get the time stamp of halt-point 
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceReadLastStamp(U16 id,U32 *stamp,U8 *stampMSB) {
   RETCODE err;
   S32 start,end;


   err = iceGetTraceBufferInfo(0,&start,&end);
   if (!err) {
      err = iceReadFrameStamp(id,0x80000000l,stamp,stampMSB);
   }
   return(err);
}

//
//  SPA functions
/**************************************************************************
**
** Name : iceSPASetRange
**
** Function :  setting code range of SPA
**
**    Input  : U8 type : 0 MA, 1 TA, 2 CC
**             U8 id   : code range id
**             U32 startAddr : start address of range
**	       U32 endAddr : end address of range
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSPASetRange(U8 type,U8 id,ADDR start,ADDR end) {
RETCODE status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(SPA_SET_RANGE,lp);

   varWidth = sizeof(type);
   SaveVar(type,lp,varWidth);
   varWidth = sizeof(id);
   SaveVar(id,lp,varWidth);
   varWidth = sizeof(start);
   SaveVar(start,lp,varWidth);
   varWidth = sizeof(end);
   SaveVar(end,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));

}
/**************************************************************************
**
** Name : iceSPAClearRange
**
** Function :  clear code range of SPA setting
**
**    Input  : U8 type : 0 MA, 1 TA, 2 CC
**             U8 id   : code range id
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSPAClearRange(U8 type) {
RETCODE status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(SPA_CLEAR_RANGE,lp);

   varWidth = sizeof(type);
   SaveVar(type,lp,varWidth);
   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));

}
/**************************************************************************
**
** Name : iceSPAGetMAInfo
**
** Function :  get module analysis info
**
**    Input  : U32 *stamp   : return total time stamp value of running
**	       MA_INFO_NODE *info : return info pointer
**
**    Output :
**
** Notes: protocol : 0 1    | 2  3        | 4  5 6 7 8   | 
**                   status |    flagHalt |    timeStamp |
**
**                   9  10   | 1  2 3   | 4  5 6 7 8   | 9  20   |
**                      R Id |    count |    timeStamp |    R Id | ...
**************************************************************************/
#define ENDING 0xFF
RETCODE EXPORT iceSPAGetMAInfo(U32 *stamp,MA_INFO_NODE *info,BOOLEAN *flagHalt) {
RETCODE status;
U16 lp;
U8 rID,idxSTR;

   lp = 0;
   SaveId(SPA_GET_MA_INFO,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   memset(info,0,sizeof(MA_INFO_NODE)*4);
   *flagHalt = inputStream[3];
   memcpy(stamp,&(inputStream[5]),sizeof(U32));
   idxSTR = 9;
   for (lp = 0; lp < MA_RANGE_NO; lp++) {
      if (inputStream[idxSTR] == ENDING) break;
      memcpy(&rID,&inputStream[idxSTR+1],inputStream[idxSTR]);
      idxSTR += inputStream[idxSTR] + 1;
      memcpy(&(info[rID].count),&inputStream[idxSTR+1],inputStream[idxSTR]);
      idxSTR += inputStream[idxSTR] + 1;
      memcpy(&(info[rID].timeStamp),&inputStream[idxSTR+1],inputStream[idxSTR]);
      idxSTR += inputStream[idxSTR] + 1;
   }
   return(*((U16 *)&inputStream[0]));

}
/**************************************************************************
**
** Name : iceSPAGetTAInfo
**
** Function :  get time analysis info
**
**    Input  : U32 *stamp   : return total time stamp value of running
**	       TA_INFO_NODE *info : return info pointer
**
**    Output :
**
** Notes: protocol : 0 1    | 2  3        | 4  5 6 7 8   | 9  10 11 12 13
**                   status |    flagHalt |    tatol     |    longest

**                   | 14  15 16 17 18   | 19  20 21 22 23
**                   |     shortest      |     count[9]
**************************************************************************/
RETCODE EXPORT iceSPAGetTAInfo(U32 *stamp,U16 *info,BOOLEAN *flagHalt) {
RETCODE status;
U16 lp;

   lp = 0;
   SaveId(SPA_GET_TA_INFO,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   *flagHalt = inputStream[3];
   for (lp=0; lp<3 ; lp++)     // get total, longest, shortest TStamp
      memcpy(&(stamp[lp]),&(inputStream[5+lp*5]),4);
   memcpy(info,&inputStream[20],sizeof(U16)*TA_TIME_NO);

   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name : iceSPAGetCCInfo
**
** Function :  get code coverage analysis info
**
**    Input  : U32 start   : start address to get info
**             U16 len : info length
**             U8 *buf : return info data buffer
**
**    Output :  inputStream[] : 0 1   | 2 3 | 4 5 .......
**                              status  len   data
**
** Notes: max data length is 640 bytes to call firmware function each time ,
          return len (2 bytes).
**
**************************************************************************/
RETCODE EXPORT iceSPAGetCCInfo(ADDR start,ADDR end,U8 FAR *buff,BOOLEAN *flagHalt) {
RETCODE status;
U16 lp, retLen,listLen,count,i,len,dumpLen;
U8 varWidth;
U8 FAR *buffPtr;
U32 shiftAddr;
ADDR listAddr;

   if (*flagHalt == 0) {   // just get the halt flag
      SaveId(SPA_GET_CC_INFO,lp);

      varWidth = sizeof(listAddr);
      SaveVar(listAddr,lp,varWidth);

      varWidth = sizeof(dumpLen);
      SaveVar(dumpLen,lp,varWidth);

      varWidth = sizeof(*flagHalt);
      SaveVar(*flagHalt,lp,varWidth);
      outputStream[lp++] = 0;

      SendStream(outputStream,lp);
      status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
      if (status == ICE_REC_TIME_OUT) return(status);

      *flagHalt = inputStream[3];
   } else {                // get the code covrage data
      len = (U16)(end.pos - start.pos + 1);
      shiftAddr = start.pos % 8;
      listAddr.pos = start.pos - shiftAddr;
      listAddr.space = start.space;
      listLen = len + shiftAddr;
      if (listLen & 0x07)
         listLen = (listLen & 0xFFF8) + 0x08;
      count = (listLen / 8) / CC_INFO_LEN;

      buffPtr = buff;
      for (i = 0; i <= count; i++) {
         if (i == count)
            dumpLen = listLen;
         else
            dumpLen = 8 * CC_INFO_LEN;
         lp = 0;
         SaveId(SPA_GET_CC_INFO,lp);

         varWidth = sizeof(listAddr);
         SaveVar(listAddr,lp,varWidth);

         varWidth = sizeof(dumpLen);
         SaveVar(dumpLen,lp,varWidth);

         varWidth = sizeof(*flagHalt);
         SaveVar(*flagHalt,lp,varWidth);
         outputStream[lp++] = 0;

         SendStream(outputStream,lp);
         status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
         if (status == ICE_REC_TIME_OUT) return(status);

//         *flagHalt = inputStream[3];
         retLen = *(U16 *)&inputStream[4];
         _fmemcpy(buffPtr,(U8 FAR *)&inputStream[6],retLen);
         buffPtr += retLen;
         listAddr.pos += (8 * retLen);
         listLen -= (8 * retLen);
      }
   }
   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name : iceSPAClose
**
** Function :  user close SPA window
**
**    Input  :
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSPAClose() {
RETCODE status;
U16 lp;

   lp = 0;
   SaveId(SPA_CLOSE,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name : iceSPASetBkpt
**
** Function :  Set SPA execution breakpoint
**
**    Input  : (U8) enable : enable or disable bkpt
**             (ADDR) addr : bkpt physical address
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSPASetBkpt(U8 enable,ADDR addr) {
RETCODE status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(SPA_SETBKPT,lp);

   varWidth = sizeof(U8);
   SaveVar(enable,lp,varWidth);

   varWidth = sizeof(ADDR);
   SaveVar(addr,lp,varWidth);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name : iceSPAOpen
**
** Function :  Open SPA Window for SPA operation
**
**    Input  :
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSPAOpen() {
RETCODE status;
U16 lp;

   lp = 0;
   SaveId(SPA_OPEN,lp);

   outputStream[lp++] = 0;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}

/**************************** End of File **********************************/
