/***************************************************************************
**
** File name : reg86.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/25/1992 By Cheerson
**        0. Check "register operation"
**
**
**
**
**    Copyright (C) 1992 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

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

#ifndef _COMM_
#include "comm.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>

extern U8 BASE_TIME;
/**************************************************************************
**
** Local define
**
***************************************************************************/

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

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

/**************************************************************************
**
** Name : SetReg(regmode,reg_id,content)
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/

RETCODE SetReg(REG_MODE regMode, S16 regId, U32 content) {
U16 lp;
U8 varWidth;
RETCODE status;

   lp = 0;
   SaveId(SET_REG,lp);

   varWidth = 2;
   SaveVar(regMode,lp,varWidth);

   varWidth = 2;
   SaveVar(regId,lp,varWidth);

   varWidth = sizeof(content);
   SaveVar(content,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) {
      if (regMode == I86_REG) {           // kkk
//       RegValid[regId]=1;
         cpu_regs[regId]=content;
      }
   }
   return(status);
}                 /* end of SetReg(regMode,reg_id,content) */


/**************************************************************************
**
** Name : emuSetReg(reg_id,content)
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceSetReg(REG_MODE regMode, S16 regId,U32 content) {
U32 regData;
RETCODE status;

   status = ICE_OK;
   switch (regMode) {
      case I86_REG :
         switch (regId) {
            case REG_PC :
               regData = (content >> 16) & 0xffff;
               status=SetReg(regMode,CS, regData);
               if (status != ICE_OK) return(status);
               regData = content & 0xffff;
               status=SetReg(regMode,IP, regData);
               break;
            case REG_SP :
               regData = (content >> 16) & 0xffff;
               status=SetReg(regMode,SS, regData);
               if (status != ICE_OK) return(status);
               regData = content & 0xffff;
               status=SetReg(regMode,RSP, regData);
               break;
            case REG_FP :
               regData = (content >> 16) & 0xffff;
               status=SetReg(regMode,SS, regData);
               if (status != ICE_OK) return(status);
               regData = content & 0xffff;
               status=SetReg(regMode,BP, regData);
               break;
            default :
               status=SetReg(regMode,regId, content);
         }
         break;
      case INTERNAL_REG :
         status=SetReg(regMode,regId, content);
         break;
   }
   return (status);
}                 /* end of emuSetReg(reg_id,content) */

/**************************************************************************
**
** Name : GetReg (reg_id)
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE GetReg (REG_MODE regMode, S16 regId, U32 *content) {
RETCODE status;
U16 lp;
U8 varWidth;


   lp = 0;
   SaveId(GET_REG,lp);

   varWidth = 2;
   SaveVar(regMode,lp,varWidth);

   varWidth = 2;
   SaveVar(regId,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) && (inputStream[2] == 2))
      memcpy(content,&inputStream[3],2);
   return(status);
}                 /* end of GetReg (reg_id) */

/**************************************************************************
**
** Name : emuGetReg (reg_id)
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes: 1. To get the register contents of the INTERNAL_REG group,
**           a conversion process named ConvertInternalRegID() is a must.
**           So another function named GetRegister() is recommanded.
**************************************************************************/

RETCODE EXPORT iceGetReg(REG_MODE regMode, int regId,U32 *content) {
RETCODE status;
U32 regHigh, regLow;

   switch (regMode) {
      case I86_REG :
         switch(regId) {
            case REG_PC :
               status=GetReg(regMode,CS, &regHigh);
               if (status != ICE_OK) return(status);
               status=GetReg(regMode,IP, &regLow);
               *content = (regHigh << 16) + (U16)regLow;
               break;
            case REG_SP :
               status=GetReg(regMode,SS, &regHigh);
               if (status != ICE_OK) return(status);
               status=GetReg(regMode,RSP, &regLow);
               *content = (regHigh << 16) + (U16)regLow;
               break;
            case REG_FP :
               status=GetReg(regMode,SS, &regHigh);
               if (status != ICE_OK) return(status);
               status=GetReg(regMode,BP, &regLow);
               *content = (regHigh << 16) + (U16)regLow;
               break;
            default :
               status = GetReg(regMode,regId, &regHigh);
               *content = regHigh;
         }
         break;
      case INTERNAL_REG :
         status = GetReg(regMode,regId, &regHigh);
         *content = regHigh & 0xffffL;
         break;
   }

   return (status);
}                 /* end of emuGetReg (reg_id) */

/**************************************************************************
**
** Name : TransferReg
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
VOID TransferReg(U16 *regBuff) {
   cpu_regs[AX] = regBuff[R_AX];
   cpu_regs[BX] = regBuff[R_BX];
   cpu_regs[CX] = regBuff[R_CX];
   cpu_regs[DX] = regBuff[R_DX];
   cpu_regs[RSP] = regBuff[R_SP];
   cpu_regs[BP] = regBuff[R_BP];
   cpu_regs[SI] = regBuff[R_SI];
   cpu_regs[DI] = regBuff[R_DI];
   cpu_regs[DS] = regBuff[R_DS];
   cpu_regs[SS] = regBuff[R_SS];
   cpu_regs[ES] = regBuff[R_ES];
   cpu_regs[CS] = regBuff[R_CS];
   cpu_regs[IP] = regBuff[R_IP];
   cpu_regs[FLAGS] = regBuff[R_FS];
}

/**************************************************************************
**
** Name : emuGetAllReg()
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGetAllReg(U16 *regBuff) {
RETCODE status;
U16 lp;
U8 regLen;

   lp = 0;
   SaveId(GET_ALL_REG,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]);
   regLen = inputStream[2];
   if(status == ICE_OK) {
      memcpy(regBuff,&inputStream[3],regLen);
   }
   return(status);
}

/**************************************************************************
**
** Name : emuGetAllIntReg()
**
** Function
**
**    Input  :
**
**    Output :
**
** Notes:
**
**************************************************************************/
RETCODE EXPORT iceGetAllIntReg(U16 *intReg) {
RETCODE status;
U16 lp;
U8 regLen;

   lp = 0;
   SaveId(GET_ALL_INTERNAL_REG,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]);
   regLen = inputStream[2];
   if(status == ICE_OK)
      memcpy(intReg,&inputStream[3],regLen*2);  // kkk
   return(status);
}

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