/***************************************************************************
**
** File name : exec86.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 emuGetPC() routine.
**    1. Replace the "emuGetPC()" calling of the emuRunUntil() to be
**       emuGetRegister(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_FUNC_
#include "abifunc.h"
#endif

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

#ifndef _REG86_DEFINE_
#include "reg86.h"
#endif

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

#include <string.h>

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

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;

extern U8 BASE_TIME;
/**************************************************************************
**
** Local define
**
***************************************************************************/
typedef enum { ACTIVE_LOW, ACTIVE_HIGH, ACTIVE_HIZ } ACTIVE_STATE;


/**************************************************************************
**
** 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 (status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}

/**************************************************************************
**
** Name : emuStepRange()
**
** 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 (status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}      /* end of emuStepRange() */

/**************************************************************************
**
** Name : emuStepOne()
**
** 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 (status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}      /* end of emuStepOne() */

/**************************************************************************
**
** 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 (status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));
}

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

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

   old = pc;
   emuGetReg(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);
      emuGetReg(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 : emuReset
**
** 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 (status == ICE_REC_TIME_OUT) return(status);
   return(*(U16 *)(&inputStream[0]));

}
/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
S16 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 (status == ICE_REC_TIME_OUT) return(status);
   *goEnd = inputStream[2];
   return(*((S16 *)&inputStream[0]));
}

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

   for (lp=0;lp < TRC_ARRAY_SIZE; lp++) bNo[lp]=0;
   curBuffID = 0xffff;
   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);
   if (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 (status == ICE_REC_TIME_OUT) return(status);
   _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;
//   *frameLen = inputStream[2];
   index = (startFrame-oldestFrame) % TRC_BUFF_SIZE;
   for(lp = 0; lp < inputStream[2]; lp++) {
      pos = lp*15;
      traceBuff[index+lp].frameNo = startFrame + lp;
      traceBuff[index+lp].addr = *(U32 *)&inputStream[pos+3];
      traceBuff[index+lp].data = *(U16 *)&inputStream[pos+7];
      traceBuff[index+lp].stat = inputStream[pos+9];
      traceBuff[index+lp].tbit   = inputStream[pos+10];
      traceBuff[index+lp].tstamp = *(U32 *)&inputStream[pos+11];
      traceBuff[index+lp].tstampMSB = inputStream[pos+15];
      traceBuff[index+lp].evtMatch = inputStream[pos+16];
      traceBuff[index+lp].seqLevel = inputStream[pos+17];
   }
   return(status);
}

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[10];
   qualifyBuff[0].tstamp = *(U32 *)&inputStream[11];
   qualifyBuff[0].tstampMSB = inputStream[15];
   qualifyBuff[0].evtMatch = inputStream[16];
   qualifyBuff[0].seqLevel = inputStream[17];
   qualifyBuff[0].frameNo = *(U32 *)&inputStream[18];
   return(status);
}

RETCODE GetAllQualifyFrame(S16 bufID, S32 startFrame, QUALIFY_LIST *cond,
            U8 *numFrame){
RETCODE status;
U16 pos, 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);
   *numFrame = inputStream[2];
   for(lp = 0; lp < inputStream[2]; lp++) {
      pos = lp*19;
      qualifyBuff[lp].addr = *(U32 *)&inputStream[pos+3];
      qualifyBuff[lp].data = *(U16 *)&inputStream[pos+7];
      qualifyBuff[lp].stat = inputStream[pos+9];
      qualifyBuff[lp].tbit = inputStream[pos+10];
      qualifyBuff[lp].tstamp = *(U32 *)&inputStream[pos+11];
      qualifyBuff[lp].tstampMSB = inputStream[pos+15];
      qualifyBuff[lp].evtMatch = inputStream[pos+16];
      qualifyBuff[lp].seqLevel = inputStream[pos+17];
      qualifyBuff[lp].frameNo = *(U32 *)&inputStream[pos+18];
   }
   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)) {
      *frameLen = 0;
      return(GOOD);
   }
//   if (startFrame < oldestFrame) startFrame = oldestFrame;
//   if (startFrame > newestFrame) startFrame = newestFrame;
//   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) {
            *frameLen = lp+1;
            break;
         }
      }
//   } else {
//      GetQualifyFrame(bufID, startFrame, cond);
//      memcpy(&frameData[0], &qualifyBuff[0],sizeof(MP_TRACE_INFO));
//   }
   return(GOOD);
}

RETCODE EXPORT iceGetQualifyFrame(U16 bufID, S32 startFrame, QUALIFY_LIST *cond,
                                U8 *frameLen, MP_TRACE_INFO *frameData) {
U8 numFrame;

   if (curBuffID != bufID) {
      iceGetTraceBufferInfo(bufID, &oldestFrame, &newestFrame);
      curBuffID = bufID;
   }
   if ((startFrame < oldestFrame) || (startFrame > newestFrame))
      return(ICE_BAD_FRAME);
   GetAllQualifyFrame(bufID, startFrame, cond, &numFrame);
   memcpy(frameData, &qualifyBuff,sizeof(MP_TRACE_INFO)*numFrame);
   *frameLen = numFrame;
   return(GOOD);
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
//RETCODE EXPORT iceListTraceBuff(int bufID, S32 startFrame,QUALIFY_LIST *cond, U8 *frameLen, TRACE_INFO *frameData) {
//U16 lp;
//U8 varWidth,frameWidth,headLen;
//RETCODE status;

//   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 (cond->qFlag == ON) {
//      frameWidth = 13;
//      headLen = 4;
//   }
//   else {
//      frameWidth = 9;
//      headLen = 0;
//   }
//   for (lp = 0; lp < *frameLen; lp++) {
//      if (cond->qFlag)
//         frameData[lp].frameNo = *(U32 *)&inputStream[3+lp*frameWidth];
//      frameData[lp].addr = *(U32 *)&inputStream[3+headLen+lp*frameWidth];
//      frameData[lp].stat = inputStream[7+headLen+lp*frameWidth];
//      frameData[lp].data = *(U16 *)&inputStream[8+headLen+lp*frameWidth];
//      frameData[lp].tstamp = inputStream[10+headLen+lp*frameWidth];
//      frameData[lp].tbit   = inputStream[11+headLen+lp*frameWidth];
//   }
//   return(*((U16 *)&inputStream[0]));
//}

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

   if (busEventData->addrLow == busEventData->addrHigh &&
      busEventData->addrSpec == RANGE_ADDR) {
      busEventData->addrSpec = SINGLE_ADDR;
      busEventData->addrHigh = 0xfffffL;
   }
   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 (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 (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 (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 (status == ICE_REC_TIME_OUT) return(status);

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

   pos += dataLen;
   dataLen = sizeof(EXEC_EVENT)*2;
   memcpy(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;

   evId -= 10; // ev0 - ev9 reserve for other event.
   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 (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 (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;

   lp = 0;
   SaveId(SET_TRIG,lp);

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

   dataLen = sizeof(tmpTrig->phySet);
   SaveVar(tmpTrig->phySet,lp,dataLen);

   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 (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 (status == ICE_REC_TIME_OUT) return(status);
   status = *((U16 *)&inputStream[0]);
   if (status == ICE_OK) {
      dataLen = inputStream[2];
      count = 3;
      for (lp = 0; lp < 4; lp++) {
         memcpy(&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 (status == ICE_REC_TIME_OUT) return(status);
   status = *((U16 *)&inputStream[0]);
   if (status == ICE_OK) {
      *lastBuff = *(U16 *)&inputStream[2] + 1;  // kkk
      *curCNT1 = *(U32 *)&inputStream[4];  // kkk
      *curCNT0 = *(U32 *)&inputStream[8];  // kkk
      *bufNO = *(U16 *)&inputStream[12];  // kkk
   }
   return(status);

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

   SaveId(SET_TIMER_COUNTER,lp);

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

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

   varWidth = sizeof(tcData1);
   SaveVar(tcData1,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 :
**
** 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 (status == ICE_REC_TIME_OUT) return(status);

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

}

/**************************************************************************
**
** Name : iceSetTraceBreak(U16)
** Function  set trace break on trace buffer full condition
**           0 : non active , 1 : active
**
**        iceSetTrcOffOnFull(U16)
** Function  set trace off on trace buffer full condition
**           0 : non active , 1 : active
**
**        iceSetTrigOutAction(U16)
** Function  set trigger out signal active state
**           ACTIVE_LOW : low active , ACTIVE_HIGH : high active
** 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 (status == ICE_REC_TIME_OUT) return(status);

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

}

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 : iceReadFrameStamp
**
** Function :  read time stamp vlaue of trace frame
**
**    Input  : U8  0 : stop trace, 1 : start trace
**
**    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);
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
#define ESC 0x1b

RETCODE EXPORT iceRunUntil(U32 addr) {
U8 goEndFlag;
S16 status;
U32 breakAddr;

   iceSetBP(10,addr);
   for (;;) {
      iceStepRange(0L,0L);
      iceGetReg(I86_REG,REG_PC,&breakAddr);
      if (breakAddr == addr) break;
      iceGo(0);
      for (;;) {
         status = iceGetCpuStatus(&goEndFlag);
         if (status == ICE_HALT_USER || (chk_hlt() == ESC && !goEndFlag)) {
            status = iceAbort();
            iceClearEvent(10); /* clear execbp1 */
            return(ICE_HALT_USER);
         }
         if (goEndFlag == 2) continue;//Eric 8/11/98; goEndFlag |= TRC_FLAG in FW;
         if (goEndFlag) break;
      }
      if (status == ICE_BKPT1_HALT) break;
   }
   iceClearEvent(10); /* clear execbp1 */
   return(ICE_OK);
}
//
//  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,U32 start,U32 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(U32 start,U32 end,U8 FAR *buff,BOOLEAN *flagHalt) {
RETCODE status;
//U16 lp, retLen,listLen,count,i,len,dumpLen; //Eric 7/9/98 for bug #307
U16 lp, retLen,count,i,dumpLen;
U32 listLen,len;
U8 varWidth;
U8 FAR *buffPtr;
U32 shiftAddr,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 - start + 1); //Eric 7/9/98 for bug #307
      len = end - start + 1;
      shiftAddr = start % 8;
      listAddr = start - shiftAddr;
      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 += (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]));
}

/**************************************************************************
**
** 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]));
}

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