/***************************************************************************
**
** 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

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

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

#ifndef _BKPTEXEC_
#include "bkptexec.h"
#endif

#ifndef _WHPTEXEC_
#include "whptexec.h"
#endif

//#define TRC_BUFF_SIZE         1024
//#define TRC_BLOCK_SIZE        64
//#define TRC_ARRAY_SIZE        16 //TRC_BUFF_SIZE /TRC_BLOCK_SIZE
//S8 bNo[TRC_ARRAY_SIZE];
//MP_TRACE_INFO qualifyBuff[TRC_BLOCK_SIZE];

S32 oldestFrame = 0,newestFrame = 0;
S16 bufSeg = 0;
U16 curBuffID = 0xffff;

#define TRACE_BUFF_SIZE         0x8000
#define TRACE_BLOCK_SIZE        64
#define TRACE_IDX_SIZE          512
#define FRAME_INST      0
#define FRAME_DATA      1
typedef struct{
   U32 data;
   U8 type;
} FRAME_INFO;

//U32 curPC;
S32 TotalFrameNo=1;
U16 TrcBufIdx,IdxTableIdx;
FRAME_INFO FramePCTable[TRACE_BLOCK_SIZE];
BOOLEAN BuildTable=FALSE;
U8 tempTraceBuff[TRACE_BUFF_SIZE];
MCF_TRACE_INFO TrcIdxTable[TRACE_IDX_SIZE];

RETCODE GetQualifyFrame(S16 bufID, S32 startFrame, QUALIFY_LIST *cond );
RETCODE processBufData(VOID);
U32 GetTransPC(U16 *bufIdxPtr);
VOID AddIdxTable(U8 isData,U32 pc,U16 bufOff,U8 skip,U8 userMode);
VOID AddFramePCTable(U32 data,U8 type,U16 idx,U8 userMode);
U32 GetFrameData(U16 offset,U8 len);

typedef RETCODE (FAR PASCAL *FPADRCREATE)(DESCRIPTOR FAR *);
typedef RETCODE (FAR PASCAL *FPADRDESTROY)(DESCRIPTOR);
typedef RETCODE (FAR PASCAL *FPADRSETOFF)(DESCRIPTOR,U32);
typedef RETCODE (FAR PASCAL *FPADRGETOFF)(DESCRIPTOR,U32 FAR *);
typedef RETCODE (FAR PASCAL *FPDADCHECK)(DESCRIPTOR,BOOLEAN,U8 FAR *,
          BOOLEAN FAR *);
typedef RETCODE (FAR PASCAL *FPDADTRANS)(DESCRIPTOR,DESCRIPTOR,
          TRANSFER_TYPE FAR *);
/**************************************************************************
**
** 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 (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 (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 (status == ICE_REC_TIME_OUT) return(status);
   return(*((U16 *)&inputStream[0]));

}      /* end of iceStepOne() */

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

RETCODE EXPORT iceAbort(U16 nonMaskable) {
U16 lp;
RETCODE status;
U8  varWidth;

   lp = 0;
   SaveId(ABORT,lp);

   varWidth = sizeof(nonMaskable);
   SaveVar(nonMaskable,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:
**
**************************************************************************/
/*
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 (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 (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 (status == ICE_REC_TIME_OUT) return(status);
   BuildTable = FALSE;
   return(*((U16 *)&inputStream[0]));
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
#pragma argsused
RETCODE EXPORT iceGetTraceBufferInfo(U16 bufID, S32 *start, S32 *end) {
U16 lp, len;
RETCODE status = GOOD;
U8 varWidth;
U8 firstTime=TRUE, flagRead;

   if (!BuildTable) {
      TrcBufIdx = 0;
      oldestFrame = newestFrame = 0;

      lp = 0;
      SaveId(LIST_TRACE,lp);

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

      outputStream[lp++] = 0;
      SendStream(outputStream,lp);
      status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*8);
      if (status == ICE_REC_TIME_OUT) return(status);
      if ((status = *((U16 *)&inputStream[0])) != ICE_OK) {
         BuildTable = TRUE;
         TotalFrameNo = 1;
         return(status);
      }
      flagRead = inputStream[2];
      len = *(U16 *)&inputStream[3];
      _fmemcpy(&tempTraceBuff[TrcBufIdx],&inputStream[5],len);
      TrcBufIdx += len;
      while (flagRead) { // return status 1 mean not finish
         lp = 0;
         SaveId(LIST_TRACE,lp);

         firstTime = FALSE;
         varWidth = sizeof(U8);
         SaveVar(firstTime,lp,varWidth);

         outputStream[lp++] = 0;
         SendStream(outputStream,lp);
         status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*8);
         if (status == ICE_REC_TIME_OUT) return(status);
         if ((status = *((U16 *)&inputStream[0])) != ICE_OK) {
            BuildTable = TRUE;
            TotalFrameNo = 1;
            return(status);
         }
         flagRead = inputStream[2];
         len = *(U16 *)&inputStream[3];
         _fmemcpy(&tempTraceBuff[TrcBufIdx],&inputStream[5],len);
         TrcBufIdx += len;
      }
      BuildTable = TRUE;
      if (processBufData() != GOOD)
         return(ICE_BUFFER_EMPTY);
   }
   *start = 0-TotalFrameNo+1;
   *end = 0;
   return(status);
}

VOID dupFrameData(S32 oldest,S32 newest,S32 start,MP_TRACE_INFO *frameData,
              U8 *frameLen) {
   int i, startIdx;
   S32 logStartNo;
   U8 space;

   logStartNo = start-TotalFrameNo+1;
   startIdx = (int)(start - oldest);
   for (i = 0; (i < (newest-start)) && (i < *frameLen); i++) {
      space = 0;
      frameData[i].frameNo = logStartNo+i+1;
      frameData[i].addr = FramePCTable[startIdx+i].data;
      frameData[i].data = FramePCTable[startIdx+i].type & 0x0F;
      if (frameData[i].data == 0)
         space |= 0x04;  // instruction
      if (FramePCTable[startIdx+i].type & 0x80)
         space |= 0x01;
      else
         space |= 0x02;
      frameData[i].stat = ((U16)space) << 5;
   }
   *frameLen = (U8)(i & 0xFF);
}

#pragma argsused
RETCODE EXPORT iceGetTraceFrame(U16 bufID, S32 startFrame,QUALIFY_LIST *cond,
                                U8 *frameLen, MP_TRACE_INFO *frameData) {
   RETCODE err, err2;
   U16 bufOff,frameCount = 0, blockNo;
   U8 subId, instLen, i, repeatNo, skip, userMode;
   U32 pcVal,frameD;
   DESCRIPTOR AddrPC, AddrTrans;
   BOOLEAN DasmSym = FALSE,instValid;
   TRANSFER_TYPE tType;
   HANDLE hLibAddr, hLibDasm;
   FPADRCREATE lpfnCreate;
   FPADRDESTROY lpfnDestroy;
   FPADRSETOFF lpfnSetOff;
   FPADRGETOFF lpfnGetOff;
   FPDADCHECK lpfnCheck;
   FPDADTRANS lpfnTrans;
   BOOLEAN finish=FALSE;

   if (TotalFrameNo <= 1)
      return(ICE_BUFFER_EMPTY);

   startFrame += TotalFrameNo-1;
   if (startFrame >= oldestFrame && startFrame < newestFrame) {
      dupFrameData(oldestFrame,newestFrame,startFrame,frameData,frameLen);
      return GOOD;
   }

   hLibAddr = LoadLibrary("addr.dll");
   hLibDasm = LoadLibrary("dasm32.dll");

   lpfnCreate = (FPADRCREATE)GetProcAddress(hLibAddr,"AdrCreateAddress");
   lpfnDestroy = (FPADRDESTROY)GetProcAddress(hLibAddr,"AdrDestroyAddress");
   lpfnSetOff = (FPADRSETOFF)GetProcAddress(hLibAddr,"AdrSetAddrOffset");
   lpfnGetOff = (FPADRGETOFF)GetProcAddress(hLibAddr,"AdrGetAddrOffset");
   lpfnCheck = (FPDADCHECK)GetProcAddress(hLibDasm,"CheckDasmInst");
   lpfnTrans = (FPDADTRANS)GetProcAddress(hLibDasm,"IsTransfer");
   if ((err = lpfnCreate(&AddrPC)) != GOOD)
      goto CLEAN_UP;
   if ((err = lpfnCreate(&AddrTrans)) != GOOD)
      goto CLEAN_UP;

   blockNo = startFrame / 64;
   oldestFrame = blockNo * 64;
   if ((newestFrame = (blockNo+1) * 64) > TotalFrameNo)
      newestFrame = TotalFrameNo;
   pcVal = TrcIdxTable[blockNo].pc;
   bufOff = TrcIdxTable[blockNo].buffOffset;
   skip = TrcIdxTable[blockNo].skip;
   userMode = TrcIdxTable[blockNo].status & 0x02;
   while (!finish) {
      subId = tempTraceBuff[bufOff++];
      switch(subId & 0x0F) {
      case 0:
         pcVal = *(U32 *)&tempTraceBuff[bufOff];
         bufOff += 4;
         userMode = tempTraceBuff[bufOff++];
         break;
      case 1:
         repeatNo = subId >> 4 ;
         if (repeatNo == 0)
            repeatNo = tempTraceBuff[bufOff++];
         if (skip != 0) {
            repeatNo -= skip;
            skip = 0;
         }
         for (i = 0; i < repeatNo; i++) {
            AddFramePCTable(pcVal,FRAME_INST,frameCount,userMode);
            if ((err = lpfnSetOff(AddrPC,pcVal)) != GOOD)
               goto CLEAN_UP;
            if ((err = lpfnCheck(AddrPC,DasmSym,&instLen,&instValid)) !=GOOD)
               goto CLEAN_UP;
            pcVal += instLen;
            frameCount++;
            if (frameCount >= (newestFrame-oldestFrame)) {
               finish =TRUE;
               break;
            }
         }
         break;
      case 2:
         repeatNo = subId >> 4 ;
         if (repeatNo == 0)
            repeatNo = tempTraceBuff[bufOff++];
         if (skip != 0) {
            repeatNo -= skip;
            skip = 0;
         }
         for (i = 0; i < repeatNo; i++) {
            AddFramePCTable(pcVal,FRAME_INST,frameCount,userMode);
            if ((err = lpfnSetOff(AddrPC,pcVal)) != GOOD)
               goto CLEAN_UP;
            if ((err = lpfnTrans(AddrPC,AddrTrans,&tType)) != GOOD)
               goto CLEAN_UP;
            if (tType.destKnown) {
               if ((err = lpfnGetOff(AddrTrans,&pcVal)) != GOOD)
                  goto CLEAN_UP;
            } else
               pcVal = GetTransPC(&bufOff);
            frameCount++;
            if (frameCount >= (newestFrame-oldestFrame)) {
               finish =TRUE;
               break;
            }
         }
         break;
      case 3:
      case 4:
      case 5:
      case 6:
         frameD = GetFrameData(bufOff,subId-2);
         bufOff += (subId - 2);
         AddFramePCTable(frameD,subId-2,frameCount,userMode);
         frameCount++;
            if (frameCount >= (newestFrame-oldestFrame))
               finish =TRUE;
         break;
      case 8:
         userMode = 1;
         break;
      case 7:;
      }

//      subId = tempTraceBuff[bufOff++];
   }
   dupFrameData(oldestFrame,newestFrame,startFrame,frameData,frameLen);
CLEAN_UP:
   err2 = lpfnDestroy(AddrPC);
   if (!err) err = err2;
   err2 = lpfnDestroy(AddrTrans);
   if (!err) err = err2;
   FreeLibrary(hLibAddr);
   FreeLibrary(hLibDasm);

   return(err);
}

#pragma argsused
RETCODE GetQualifyFrame(S16 bufID, S32 startFrame, QUALIFY_LIST *cond ){
   return(GOOD);
}
//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].frameNo = *(U32 *)&inputStream[3];
//   qualifyBuff[0].data = *(U16 *)&inputStream[7];
//   qualifyBuff[0].stat = inputStream[11];
//   qualifyBuff[0].tstamp = inputStream[13];
//   qualifyBuff[0].spare  = inputStream[14];
//   qualifyBuff[0].addr = *(U32 *)&inputStream[15];
//   qualifyBuff[0].misc = *(U32 *)&inputStream[19];
//   return(status);
//}

/**************************************************************************
**
** 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 (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:
**
**************************************************************************/
#pragma argsused
RETCODE EXPORT iceSetExtEvent(U16 evData) {
   return(GOOD);
}
/*
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;
   _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 operator,U16 counter) {
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);

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

   varWidth = sizeof(counter);
   SaveVar(counter,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 iceSetWP(I_WATCHPOINT iwhpt,L_ADDR laddr, L_DATA ldata,
   L_WATCHPOINT lwhpt,WATCHPOINT_COUNTER whptCounter) {
U16 lp;
RETCODE status;
U8 varWidth;

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

   varWidth = sizeof(I_WATCHPOINT);
   SaveBuff(&iwhpt,lp,varWidth);

   varWidth = sizeof(L_ADDR);
   SaveBuff(&laddr,lp,varWidth);

   varWidth = sizeof(L_DATA);
   SaveBuff(&ldata,lp,varWidth);

   varWidth = sizeof(L_WATCHPOINT);
   SaveBuff(&lwhpt,lp,varWidth);

   varWidth = sizeof(WATCHPOINT_COUNTER);
   SaveBuff(&whptCounter,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->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 ((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, U16 *curCNT0, U16 *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 = *(U16 *)&inputStream[4];  // kkk
      *curCNT0 = *(U16 *)&inputStream[6];  // kkk
      *bufNO = *(U16 *)&inputStream[8];  // kkk
   }
   return(status);

}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
#pragma argsused
RETCODE EXPORT iceSetTimerCounter(U16 tcFlag, U32 tcData){
   return(GOOD);
}
/*
RETCODE status;
U16 lp = 0;
U8 varWidth;

   if (tcFlag == 0 || tcFlag == 1) { // counter-0 & counter-1
      if ((tcData == 0) || (tcData > 1024))
         return(ICE_CNT_ERROR); //output error
   } else { // timer
      if ((tcData == 0L) || (tcData > 0x100000L))
         return(ICE_TIMER_ERROR); // output error
   }

   SaveId(SET_TIMER_COUNTER,lp);

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

   varWidth = sizeof(tcData);
   SaveVar(tcData,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:
**
**************************************************************************/
#pragma argsused
RETCODE EXPORT iceSetTraceBuffer(U16 traceBufNum) {
   return(GOOD);
}

//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;
   return(GOOD);
}

#pragma argsused
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 (status == ICE_REC_TIME_OUT) return(status);

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

}

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

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
#pragma argsused
RETCODE EXPORT iceSetQualTrace(U32 addr,U32 addrMask,U16 qStatus,U16 qStatusMask) {
   return(GOOD);
}
/*
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 (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}
*/
/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceDisableQual(VOID) {
   return(GOOD);
}
/*
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 (status == ICE_REC_TIME_OUT) return(status);

   return(*((U16 *)&inputStream[0]));
}
*/
/**************************************************************************
**
** Name : iceTraceReset
**
** Function : reset trace buffer index pointer, clear trace buffer
**            content
**    Input  : none
**    Output : ICE_OK
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceTraceReset(VOID){
   RETCODE status;
   U16 lp;

   lp = 0;
   SaveId(TRACE_RESET,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]);
   BuildTable = FALSE;
   return(status);
}

RETCODE processBufData(VOID) {
   RETCODE err, err2;
   U16 bufIdx = 0, bufOffset;
   U8 subId = 0, instLen, i, repeatNo, userMode = 0;
   U32 pcVal;
   S32 curFrameNo = 0;
   DESCRIPTOR AddrPC, AddrTrans;
   BOOLEAN DasmSym = FALSE,instValid;
   TRANSFER_TYPE tType;
   HANDLE hLibAddr, hLibDasm;
   FPADRCREATE lpfnCreate;
   FPADRDESTROY lpfnDestroy;
   FPADRSETOFF lpfnSetOff;
   FPADRGETOFF lpfnGetOff;
   FPDADCHECK lpfnCheck;
   FPDADTRANS lpfnTrans;

   hLibAddr = LoadLibrary("addr.dll");
   hLibDasm = LoadLibrary("dasm32.dll");

   lpfnCreate = (FPADRCREATE)GetProcAddress(hLibAddr,"AdrCreateAddress");
   lpfnDestroy = (FPADRDESTROY)GetProcAddress(hLibAddr,"AdrDestroyAddress");
   lpfnSetOff = (FPADRSETOFF)GetProcAddress(hLibAddr,"AdrSetAddrOffset");
   lpfnGetOff = (FPADRGETOFF)GetProcAddress(hLibAddr,"AdrGetAddrOffset");
   lpfnCheck = (FPDADCHECK)GetProcAddress(hLibDasm,"CheckDasmInst");
   lpfnTrans = (FPDADTRANS)GetProcAddress(hLibDasm,"IsTransfer");
   if ((err = lpfnCreate(&AddrPC)) != GOOD)
      goto CLEAN_UP;
   if ((err = lpfnCreate(&AddrTrans)) != GOOD)
      goto CLEAN_UP;
   IdxTableIdx = 0;

   while (subId != 7) {
      subId = tempTraceBuff[bufIdx++];
      switch(subId & 0x0F) {
      case 0:
         pcVal = *(U32 *)&tempTraceBuff[bufIdx];
         bufIdx += 4;
         userMode = tempTraceBuff[bufIdx++];
         break;
      case 1:
         repeatNo = subId >> 4 ;
         bufOffset = bufIdx - 1;
         if (repeatNo == 0)
            repeatNo = tempTraceBuff[bufIdx++];
         for (i = 0; i < repeatNo; i++) {
            if (curFrameNo % 64 == 0)
               AddIdxTable(FALSE,pcVal,bufOffset,i,userMode);
            if ((err = lpfnSetOff(AddrPC,pcVal)) != GOOD)
               goto CLEAN_UP;
            if ((err = lpfnCheck(AddrPC,DasmSym,&instLen,&instValid)) != GOOD)
               goto CLEAN_UP;
            pcVal += instLen;
            curFrameNo++;
         }
         break;
      case 2:
         repeatNo = subId >> 4 ;
         bufOffset = bufIdx - 1;
         if (repeatNo == 0)
            repeatNo = tempTraceBuff[bufIdx++];
         for (i = 0; i < repeatNo; i++) {
           if (curFrameNo % 64 == 0)
              AddIdxTable(FALSE,pcVal,bufOffset,i,userMode);
            if ((err = lpfnSetOff(AddrPC,pcVal)) != GOOD)
               goto CLEAN_UP;
            if ((err = lpfnTrans(AddrPC,AddrTrans,&tType)) != GOOD)
               goto CLEAN_UP;
            if (!tType.transfer && !tType.call) {
               err = ICE_BUFFER_EMPTY;
               ErrDisplayError(ER_BAD_TRACE_INFO, FORCE_POPUP);
               goto CLEAN_UP;
            }
            if (tType.destKnown) {
               if ((err = lpfnGetOff(AddrTrans,&pcVal)) != GOOD)
                  goto CLEAN_UP;
            } else
               pcVal = GetTransPC(&bufIdx);
            curFrameNo++;
         }
         break;
      case 3:
      case 4:
      case 5:
      case 6:
         if (curFrameNo % 64 == 0)
            AddIdxTable(TRUE,pcVal,bufIdx-1,0,userMode);
         bufIdx += (subId - 2);
         curFrameNo++;
         break;
      case 8:
         userMode = 1;
         break;
      case 7:
         break;
      }

//      subId = tempTraceBuff[bufIdx++];
   }
   TotalFrameNo = curFrameNo;
CLEAN_UP:
   err2 = lpfnDestroy(AddrPC);
   if (!err) err = err2;
   err2 = lpfnDestroy(AddrTrans);
   if (!err) err = err2;
   FreeLibrary(hLibAddr);
   FreeLibrary(hLibDasm);
   return(err);
}

U32 GetTransPC(U16 *bufIdxPtr) {
   U32 retVal = 0;

   if (tempTraceBuff[(*bufIdxPtr)++] == 6) {
      retVal = *(U32 *)&tempTraceBuff[(*bufIdxPtr)];
      (*bufIdxPtr) += 4;
   }
   return retVal;
}

VOID AddIdxTable(U8 isData,U32 pc,U16 bufOff,U8 skip,U8 userMode) {

   TrcIdxTable[IdxTableIdx].status = 0;
   TrcIdxTable[IdxTableIdx].pc = pc;
   TrcIdxTable[IdxTableIdx].buffOffset = bufOff;
   TrcIdxTable[IdxTableIdx].skip = skip;
   if (isData)
      TrcIdxTable[IdxTableIdx].status |= 0x01;
   if (userMode)
      TrcIdxTable[IdxTableIdx].status |= 0x02;

   IdxTableIdx++;
   TrcIdxTable[IdxTableIdx].status = 0;
   TrcIdxTable[IdxTableIdx].pc = 0;
   TrcIdxTable[IdxTableIdx].buffOffset = 0;
   TrcIdxTable[IdxTableIdx].skip = 0;
}

VOID AddFramePCTable(U32 data,U8 type,U16 idx,U8 userMode) {
   FramePCTable[idx].data = data;
   FramePCTable[idx].type = type; // bit 0-3 : 0 inst, 1-4 data length
   if (userMode)
      FramePCTable[idx].type |= 0x80; // bit 7 : 0 supervisor, 1 user
}

U32 GetFrameData(U16 offset,U8 len) {
   U32 retVal=0;
   U8 i;
   for (i = 0; i < len; i++)
      retVal = retVal + (((U32)tempTraceBuff[offset+i]) << (i*8));
   return(retVal);
}

/**************************************************************************
**
** Name : iceGoEpDelay
**
** Function : Setting GO_EP Delay Flag
**    Input  : BOOLEAN delay : 0 => no delay route when trace buffer full
**                             1 => add delay route when trace buffer full
**    Output : ICE_OK
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGoEpDelay(U8 delay){
   RETCODE status;
   U16 lp;
   U8 varWidth;

   lp = 0;
   SaveId(GOEP_DELAY,lp);

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

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

/**************************************************************************
**
** Name : iceSetBkptNonmask()
**
** Function : enable/disable LCTRL2 nonmask bit
**    Input  : U16 enable
**
**    Output : ICE_OK (always)
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetBkptNonmask(U16 enable) {
   RETCODE status;
   U16 lp;
   U8 varWidth;

   lp = 0;
   SaveId(SET_BKPT_NONMASK,lp);

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

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

/**************************************************************************
**
** Name : iceSetISCT_SER()
**
** Function : Setup  instruction fetch show cycle and core serialize control
**    Input  : U16 value
**
**    Output : ICE_OK (always)
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetISCT_SER(U16 value) {
   RETCODE status;
   U16 lp;
   U8 varWidth;

   lp = 0;
   SaveId(SET_ISCT_SER,lp);

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

   outputStream[lp++] = 0;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
   if (status == ICE_REC_TIME_OUT) return(status);
   return(GOOD);
}
/**************************** End of File **********************************/

