/***************************************************************************
**
** File name : mem86.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".
**
**
**    Copyright (C) 1992 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#ifndef _COMM_
#include "comm.h"
#endif

#ifndef _ABI_FUNC_
#include "abifunc.h"
#endif

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

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

#ifndef _SD_ABI_DEF_
#include "sdabidef.h"
#endif

#include <string.h>

extern U8 BASE_TIME;
                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
#define BUFF_SIZE        240


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

   lp = 0;
   attr |= 0x60;

   SaveId(SET_MAP,lp);

   varWidth = sizeof(addr1);
   SaveVar(addr1,lp,varWidth);
   varWidth = sizeof(addr2);
   SaveVar(addr2,lp,varWidth);
   varWidth = sizeof(attr);
   SaveVar(attr,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 iceGetMapSize(U8 *emmSize) {
S16 status;
U8 lp;

   lp = 0;
   SaveId(GET_MAP_SIZE,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) {
      *emmSize = inputStream[3];
   }
   return(status);
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGetMap(MAP_INFO *mapData) {
S16 status;
U16 lp;
U8 *inputPtr, emmSize;

   lp = 0;
   iceGetMapSize(&emmSize);
   if(emmSize != 0) {
      SaveId(GET_MAP,lp);
      outputStream[lp++] = 0;
      SendStream(outputStream,lp);
      status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME);
      if (status == ICE_REC_TIME_OUT) return(status);
      inputPtr = inputStream + 2;
      status = *((U16 *)&inputStream[0]);
      lp = 0;
      if (status == ICE_OK) {
         while ((*(U16 *)inputPtr != 0xaa55) && lp < (mapNo -1)) {
            memcpy(&mapData[lp],inputPtr,8);  // kkk
            mapData[lp].attr = (U8)(*(U16 *)(inputPtr+8)); // kkk
            inputPtr +=10;
            lp++;
         }
         mapData[lp].addr1 = 0xfffffffful; // kkk
      }
      return(status);
   }
   else mapData[0].addr1 = 0xfffffffful; // No EMM
   return(NO_EMM);
}

/****************************************************************************
**
**  emuSize
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
**        return data --
**
****************************************************************************/
RETCODE EXPORT iceSize(BUS_SIZE size) {
U16 lp;
S16 status;
U8 varWidth;

   lp = 0;
   SaveId(SET_SIZE,lp);

   varWidth = sizeof(size);
   SaveVar(size,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]));

}

/****************************************************************************
**
**  emuFill
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
**        return data --
**
****************************************************************************/
RETCODE EXPORT iceFill(ADDR addr, U32 len, U8 *buff, U16 patternLen) {
S16 status;
U16 lp,tCount;
U8 varWidth;

   lp = 0;

   SaveId(FILL_COMMAND,lp);

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

   SaveVar(len,lp,varWidth);
   SaveBuff(buff,lp,patternLen);

   outputStream[lp++] = 0;
   tCount = (U16)(len/M128K) + 1;

   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*tCount);
   if (status == ICE_REC_TIME_OUT) return(status);
   status = *((U16 *)&inputStream[0]);
   if ((status == ICE_NOT_READY) || (status == ICE_ERROR_WRITE))
      memcpy(&ret_addr1,&inputStream[3],4); // error addr  // kkk
   return(status);
}

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

RETCODE GetMem240(ADDR addr, U8 *buff, U8 len) {
S16 status;
U16 lp;
U8 varWidth;

   lp = 0;

   SaveId(READ_MEM_N,lp);

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

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

   outputStream[lp++] = 0;

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

/****************************************************************************
**
**   emuGetMemN
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
**        return data --
**
****************************************************************************/
RETCODE EXPORT iceGetMemN(ADDR addr, U8 *buff, U16 len) {
S16 status;
U16 lp,blockLen;
U8 patternLen,*buffPtr;

   status = ICE_OK;
   buffPtr = buff;
   blockLen = len / BUFF_SIZE;
   for (lp = 0; lp < blockLen; lp++) {
      if ((status = GetMem240(addr,buffPtr,BUFF_SIZE)) == ICE_OK) {
         AdvanceAddr(&addr, BUFF_SIZE);
         buffPtr += BUFF_SIZE;
      }
      else break;
   }
   patternLen = len % BUFF_SIZE;
   if ((patternLen) && (status == ICE_OK))
      status = GetMem240(addr,buffPtr,patternLen);
   if (status == ICE_NOT_READY)
      memcpy(&ret_addr1,&inputStream[3],4); /* error addr */
   return(status);
}

/****************************************************************************
**
**   emuGetMem
**
**  Description:
**
**  Parameters:
**     input:
**
**     output:
**
**        return data --
**
****************************************************************************/
RETCODE EXPORT iceGetMem(ADDR addr, U8 *buff) {
S16 status;
U16 len,lp;
U8 varWidth;

   len = 1;
   lp = 0;

   SaveId(READ_MEM_N,lp);

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

   varWidth = sizeof(len);
   SaveVar(len,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];
   if (status  == ICE_OK)
      *buff = inputStream[3];
   else if (status == ICE_NOT_READY)
      memcpy(&ret_addr1,&inputStream[3],4); /* error addr */  // kkk
   return(status);

}

/**************************************************************************
**
** Name : SetMem240()
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE SetMem240(ADDR addr, U8 *buff, U8 patternLen) {
S16 status;
U16 lp;
U8 varWidth;

   lp = 0;

   SaveId(SET_MEM_N,lp);

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

   SaveBuff(buff,lp,patternLen);

   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 iceSetMemN(ADDR addr, U8 *buff, U16 patternLen) {
S16 status;
U16 lp,len;
U8 *buffPtr;

   status = ICE_OK;
   buffPtr = buff;
   len = patternLen / BUFF_SIZE;
   for (lp = 0; lp < len; lp++) {
      if ((status = SetMem240(addr,buffPtr,BUFF_SIZE)) == ICE_OK) {
         AdvanceAddr(&addr, BUFF_SIZE);
         buffPtr += BUFF_SIZE;
      }
      else break;
   }
   len = patternLen % BUFF_SIZE;
   if ((len) && (status == ICE_OK))
      status = SetMem240(addr,buffPtr,(U8)len);
   if ((status == ICE_NOT_READY) || (status == ICE_ERROR_WRITE))
      memcpy(&ret_addr1,&inputStream[3],4); /* error addr */
   return(status);

}

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

RETCODE EXPORT iceSetMem(ADDR addr, U8 ch) {
S16 status;
U16 lp;
U8 patternLen,varWidth;
U8 buff[4];

   lp = 0;
   buff[0]=ch;

   SaveId(SET_MEM_N,lp);

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

   patternLen = 1;
   SaveBuff(buff,lp,patternLen);

   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_NOT_READY) || (status == ICE_ERROR_WRITE))
      memcpy(&ret_addr1,&inputStream[3],4); /* error addr */  // kkk
   return(status);
}

/**************************************************************************
**
** Name : emuCopy()
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/

//RETCODE EXPORT iceCopy(ADDR addr1, U32 len, ADDR addr2) { //Eric 2/11/98
RETCODE EXPORT iceCopy(ADDR addr1, U32 len, ADDR addr2, BOOLEAN srcTarget) {
S16 status;
U16 lp,tCount;
U8 varWidth;

   lp = 0;
   SaveId(COPY,lp);

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

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

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

   varWidth = sizeof(srcTarget);  //Eric 2/11/98
   SaveVar(srcTarget,lp,varWidth);//Eric 2/11/98

   outputStream[lp++] = 0;

   tCount = (U16)(len/M128K) + 1;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*tCount);
   if (status == ICE_REC_TIME_OUT) return(status);
   status = *((U16 *)&inputStream[0]);
   if (status == ICE_NOT_READY || ICE_ERROR_WRITE) {
      memcpy(&ret_addr1,&inputStream[3],4); // addr1  // kkk
      memcpy(&ret_addr2,&inputStream[7],4); // addr2  // kkk
   }
   return(status);
}

/**************************************************************************
**
** Name : emuCompare()
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceCompare(ADDR addr1, U32 len, ADDR addr2, RET_ADDR *findAddr1, RET_ADDR *findAddr2) {
S16 status;
U16 lp,tCount;
U8 varWidth;

   lp = 0;
   SaveId(COMPARE,lp);

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

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

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

   outputStream[lp++] = 0;

   tCount = (U16)(len/M128K) + 1;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*tCount);
   if (status == ICE_REC_TIME_OUT) return(status);
   status = *((S16 *)&inputStream[0]);
//   if (status == ICE_OK) {
   if (status == ICE_DIFF_FOUND) {
      memcpy(findAddr1,&inputStream[3],6); // addr1  // kkk
      memcpy(findAddr2,&inputStream[9],6); // addr2  // kkk
   }
   else if (status == ICE_NOT_READY) {
      memcpy(&ret_addr1,&inputStream[3],4); // addr1  // kkk
      memcpy(&ret_addr2,&inputStream[9],4); // addr2  // kkk
   }
   return(status);
}                       /* end of emuCompare() */

/**************************************************************************
**
** Name : emuSearch(addr, len, buff, size)
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/

RETCODE EXPORT iceSearch(ADDR addr, U32 len, U8 *buff, U16 patternLen) {  /* search block for pattern */
S16 status;
U16 lp,tCount;
U8 varWidth;

   lp = 0;
   SaveId(SEARCH,lp);

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

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

   SaveBuff(buff,lp,patternLen);

   outputStream[lp++] = 0;

   tCount = (U16)(len/M128K) + 1;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*tCount);
   if (status == ICE_REC_TIME_OUT) return(status);
   status = *((U16 *)&inputStream[0]);
   if ((status == ICE_MATCH) || (status == ICE_NOT_READY))
      memcpy(&ret_addr1,&inputStream[3],4);  // kkk
   return(status);
} /* end of emuSearch() */

/**************************************************************************
**
** Name : emuChecksum(addr, len, buff, size)
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceChecksum(ADDR addr, U32 len, U16 *n) {
S16 status;
U16 lp,tCount;
U8 varWidth;

   lp = 0;
   SaveId(CHECKSUM,lp);

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

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

   outputStream[lp++] = 0;

   tCount = (U16)(len/M128K) + 1;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*tCount);
   if (status == ICE_REC_TIME_OUT) return(status);
   status = (*(U16 *)&inputStream[0]);
   if (status == ICE_OK)
      *n = *(U16 *)&inputStream[3]; /* checksum */
   else if (status == ICE_NOT_READY)
           memcpy(&ret_addr1,&inputStream[3],4); /* error addr */  // kkk
   return(status);
}

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

RETCODE EXPORT iceTest(ADDR addr, U32 len) {
S16 status;
U16 lp,tCount;
U8 varWidth;

   lp = 0;
   SaveId(TEST,lp);

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

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

   outputStream[lp++] = 0;

   tCount = (U16)(len/M128K) + 1;
   SendStream(outputStream,lp);
   status = ReceiveStream(inputStream,&inputStreamLen,BASE_TIME*tCount);
   if (status == ICE_REC_TIME_OUT) return(status);
   status = *(U16 *)(&inputStream[0]);
   if (status == ICE_NOT_READY || status == ICE_TEST_FAIL || status == ICE_ERROR_WRITE)
      memcpy(&ret_addr1,&inputStream[3],4);  // kkk
   return(status);
}

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

RETCODE EXPORT iceInput(U16 port, U16 len, U16 size, U8 *buff) {
S16 status;
U16 lp;
U8 varWidth;

   lp = 0;
   SaveId(INPUT,lp);

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

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

   varWidth = sizeof(size);
   SaveVar(size,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]);
   if (status == ICE_OK)
     memcpy(buff,&inputStream[3],inputStream[2]); /* input data */
   return(status);
}

/**************************************************************************
**
** Name :
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceOutput(U16 port, U8 *data, U16 len, U16 size) {
U16 lp;
S16 status;
U8 varWidth;

   lp = 0;
   SaveId(OUTPUT,lp);

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

   SaveBuff(data,lp,len);

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

   varWidth = sizeof(size);
   SaveVar(size,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]));
}

void EXPORT AdvanceAddr(U32 *addr, int len)
{
long segment, offset;

   segment = *addr & 0xFFFF0000L;
   offset = (*addr & 0x0000FFFF) + len;
   *addr = segment + (offset & 0x0000FFFF);
   if (offset >= 0x10000L) *addr += 0x10000000L;
   else if (offset < 0) *addr -= 0x10000000L;
}

void EXPORT iceGetVerifyErrorInfo(BAD_MEMORY *badMemory)
{
U32 tempOffset;
U8 tmpData;
   tempOffset = ret_addr1.cs;
   badMemory->offset = tempOffset*16 + ret_addr1.ip;
   tempOffset = (tempOffset << 16) + ret_addr1.ip;
   iceGetMem(tempOffset, &tmpData);
   badMemory->actual = tmpData;
}
/**************************** End of File **********************************/
