/***************************************************************************
**
**    $Header:   D:/EP196/SRC/LOG/CPUSVR.CPP   1.0   19 May 1997 14:39:14   ZJRD  $
**
**    $Log:   D:/EP196/SRC/LOG/CPUSVR.CPP  $
** 
**    Rev 1.0   19 May 1997 14:39:14   ZJRD
** Initial revision.
**                                                  
****************************************************************************/

/***************************************************************************
**
** File name : CPUSVR.CPP
** Author:BRIGHT CHEN  ,  JOHN CHOW, Chris Fang
** Description:
**
**
**    Finished date: 1995.9.1   V 0.1
**    UPDATE DATE  : 1995.9.8   V 0.1A
**                  Modify the void ResetCmd(int nArgc, char* pszArgv[]),
**                  because v0.1 don't support the string "P:xxxx" or
**                  "X:xxxx";
**                    1995.9.26  V 0.1B
**                  Modify BOOL CCpuServer::GetRegFromFile()
**                  to fix bug no.116
**
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

//////////////////////////////////////
//regserve.cpp
//Bright Cheng
//95/4
//////////////////////////////////////

///////////////////////////////NOTES//////////////////////////////
/********************************************************************
NOTES TO HOW TO ADD DIFFERENT:
STEP 1:
     ADD CPU NAME INT THE "enum CPU_MODULE_LIST " AREA LIKE OTHERS.
     PLEASE KEEP THE SEQUENCE OF THE CPU NAME AND AT SAME TIME THE
     ORDER MUST BE KEPT WITH THE ABI TABLE;
STEP 2:
     ADD REG TABLE IN THE END OF FILE LIKE OTHERS THOUGH THE ORDER
     OF REG TABLE IS NO USE.
     THE REG IN "enum COMMON_REG" AREA HAS NO NEED TO BE ADDED TO
     THE REG TABLE.
     THE REG SEQUENCE MUST BE KEPT WITH ABI TABLE.
STEP 3:
     UPDATE THE DAD REG TABLE AT THE SAME TIME, THIS MEANS THE EP-SLD
     MUST BE REBUILDED.
                                                       John.chow 95.8
*************************************************************************/

#include "stdafx.h"
#include <string.h>
#include <stdlib.h>

//#include "abibase.h"
//added by dragon

#include "cpucom.h"
#include "cpusvr.h"
#include "uicom2.h"
#include "address.h"
#include "hosterrs.h"
//#include "cpust.h"           
//#include "mainfrm.h"

//#include "contain.h"     
typedef WORD REG_ID;

extern char szAppPath[_MAX_PATH+1];

static CCpuServer CpuServer;
//ONLY USED FOR SHOWING REGS IN SHELL
static struct CPUModule
{
	char cpuName[MAXCPUNAMELEN];	//20
	Reg_Name_ID RegNameID[MAX_REGISTERS];
	int nMaxReg;
} cpuModule;

//notes:in this function anything needing initiation about cpu , dad
int InitCpu(int iRoger)
{
	return(CpuServer.Initialize(iRoger));
}

//added by john 96.1 to support 320 trace list
#ifdef __cplusplus
extern "C" {
#endif	// __cplusplus  
WORD WINAPI GetCpuId()
{ 
	return CpuServer.m_wCpuModule;
}
#ifdef __cplusplus
}
#endif

void GetCpuName(CString& strName)
{
	strName=CpuServer.CpuName;
}

BOOL _export Id2RegName(WORD id, char* pName)
{
CString name;

	if(!(CpuServer.Id2RegName(id, name)))
	{
		pName[0]=NULL;
		return FALSE;
	}
	ASSERT(name.GetLength()<20);
	strcpy(pName, name);
	return TRUE;
}

BOOL GetRegName(WORD wRegId, char* pOutput)
{
CString	strName;

	if(!CpuServer.Id2RegName(wRegId, strName))
	{
		pOutput[0]=NULL;
		return FALSE;
	}
	strcpy(pOutput, strName);
	return TRUE;
}

BOOL GetRegValue(WORD wRegId, DWORD& dwOutput)
{
	if (wRegId >= (WORD)nMaxReg)
	{
		ErrDisplayError(ER_PRE_REG_NOT_EXIST);
		return FALSE;
	}

	CpuServer.m_nErrorID = CpuServer.GetAllReg();
	if(ICE_OK == CpuServer.m_nErrorID)
	{
		dwOutput=RegValue[wRegId];
		return TRUE;
	}
	else
	{
		CpuServer.DisplayErrorMessageBox();
		return(FALSE);
	}
}

BOOL CpuGetAllReg()
{
	CpuServer.m_nErrorID = CpuServer.GetAllReg();
	if(ICE_OK == CpuServer.m_nErrorID)
		return(TRUE);
	else
	{
		CpuServer.DisplayErrorMessageBox();
		return(FALSE);
	}
}

BOOL CpuSetRegfromWnd(WORD reg_id,DWORD content)
{
	return(CpuServer.SetRegfromWnd(reg_id,content));
}

void RegisterCmd(int nArgc,char* pszArgv[])
{
WORD	reg_id;
DWORD	regval;
char*	stop_at;
BYTE	uchStatus;
CString	strMsg;
    
	GetCpuStatus(uchStatus);
	if(uchStatus==1)
	{
		ErrGetErrorText(ER_EMU_PROGRAM_IS_RUN, strMsg);
		ShowLine(strMsg.GetBuffer(strMsg.GetLength()+1));
		strMsg.ReleaseBuffer();
		return ;
	}

	if(1==nArgc)
	CpuServer.ShowAllRegToShell();

	if(3==nArgc||2==nArgc)
	{
		CString str = strupr(pszArgv[1]);
		for(int i = 0;i < nMaxValidReg; i++)
		{
			if(str == RegName[RegValid[i]])
			{
				reg_id = REG_ID(RegSelect[i]);
				break;
			}
		}
		if(2==nArgc)
			CpuServer.ShowOneRegToShell(reg_id);
		else
		{
			char nBank, value[10];
			WORD nBankNum = 0;
			
			
			if(pszArgv[2][0]=='P'||pszArgv[2][0]=='p'){
			   strcpy(value, pszArgv[2] + 3);
			   nBank = pszArgv[2][1];
               nBankNum= (WORD)strtoul(&nBank,&stop_at,16);
			}
			else
			   strcpy(value, pszArgv[2]);
			
			regval = (DWORD)strtoul(value,&stop_at,16);
			CpuServer.SetRegfromShell(reg_id,regval,nBankNum);
		}
	}
	
}

void ResetCmd(int nArgc, char* pszArgv[])
{
char*	stop_at;
//char*	tmpPoint;
//DWORD	addr;
    /*
	unsigned long uchStatus;
    if(emuGetCpuStatus(&uchStatus)!=ICE_OK){
       return ;
    }
    if(uchStatus&0x10){
    	ShowLine("Please Halt the CPU first !");
     	return;
    }*/ 	
	switch(nArgc)
	{
		case 1:
			CpuServer.ResetbyShell(GetLoadPC());
			break;
		case 2:
			char nBank, value[10];
			ADDRESS addr;
			
			if(pszArgv[1][0]=='P'||pszArgv[1][0]=='p'){
			   strcpy(value, pszArgv[1] + 3);
			   nBank = pszArgv[1][1];
               addr.adrSpace = (U8)(nBank + 1);
            }
			else{
			   strcpy(value, pszArgv[1]);
               addr.adrSpace = 1;
			}
			addr.adrAddress = (WORD)strtoul(value,&stop_at,16);
			CpuServer.ResetbyShell(addr);
			break;
		default:
			ASSERT(0);
	}
}

BOOL CpuReset(ADDRESS addr)
{
    return(CpuServer.ResetbyWnd(addr));
}

char** PreCpuInitialize(int &iRoger)
{
	return CpuServer.PreCpuInitialize(iRoger);
}

//these two routines are added to give cpu information

//return TRUE: success.
//return FALSE:failure.

#ifdef __cplusplus
extern "C" {
#endif	// __cplusplus  
void WINAPI GetMemoryRange(CPUMEMORYRANGE& cmr)
{
	cmr=CpuServer.cpuMemoryRange;
}

#ifdef __cplusplus
}
#endif

BOOL GetMemoryRange(RANGE_INFO& ri)
{
	ri.reservecount=1;
	ri.mr[0].begAddr=0x000000;
	ri.mr[0].endAddr=0xffffff;
	return TRUE;
}

int GetControlOption(CString &strReset,CString &strEa,CString &strEben)
{
	if(CpuServer.controlOption.controlReset==1)
		strReset="RESET";
	else strReset="";
	if(CpuServer.controlOption.controlEa==1)
		strEa="EA";
	else strEa="";
	if(CpuServer.controlOption.controlEben==1)
		strEben="EBEN";
	else strEben="";

	return 0;
}

// supported by Mr Xiao to define how to show all registers in shell
// the max number of registers in a line is defined by MAXALINE BY JOHN.CHOW 95.6
// the max number of lines in shell is defined by MAXLINES BY JOHN.CHOW 95.6

//for 8031 CPU

/*
   >REGISTER
    PC=1234 DPTR=1234 ACC=12 B=12 SP=12 PSW=12
    R0=12 R1=12 R2=12 R3=12 R4=12 R5=12 R6=12 R7=12
    IE=12 IP=12 SCON=12 TMOD=12
    TH0=12 TL0=12 TH1=12 TL1=12
    TCON=12 T2CON=12 P0=12 P1=12 P2=12 P3=12
   >
// for 8032 CPU
   >REGISTER
    PC=1234 DPTR=1234 ACC=12 B=12 SP=12 PSW=12
    R0=12 R1=12 R2=12 R3=12 R4=12 R5=12 R6=12 R7=12
    IE=12 TCON=12  T2CON=12 IP=12 SCON=12 TMOD=12
    TH0=12 TL0=12 TH1=12 TL1=12 TH2=12 TL2=12
    RCAP2H=12 RCAP2L=12 P0=12 P1=12 P2=12 P3=12
   >
//for 8051FA CPU
/* >REGISTER
    PC=1234 DPTR=1234 ACC=12 B=12 SP=12 PSW=12
    R0=12 R1=12 R2=12 R3=12 R4=12 R5=12 R6=12 R7=12
    IE=12 TCON=12 T2CON=12 IP=12 SCON=12 TMOD=12
    TH0=12 TL0=12 TH1=12 TL1=12 CCON=12 CH=12 CL=12 CMOD=12
    CCAP0H=12 CCAP1H=12 CCAP2H=12 CCAP3H=12 CCAP4H=12
    CCAP0L=12 CCAP1L=12 CCAP2L=12 CCAP3L=12 CCAP4L=12
    CCAPM0=12 CCAPM1=12 CCAPM2=12 CCAPM3=12 CCAPM4=12
    RACAP2H=12 RACAP2L=12 SADDR=12 SADEN=12 T2MOD=12
    TH2=12 TL2=12 PCON=12 P0=12 P1=12 P2=12 P3=12
   >
// for 8044 CPU
   >REGISTER
    PC=1234 DPTR=1234 ACC=12 B=12 SP=12 PSW=12
    R0=12 R1=12 R2=12 R3=12 R4=12 R5=12 R6=12 R7=12
    IE=12 TCON=12 IP=12 TMOD=12
    TH0=12 TL0=12 TH1=12 TL1=12
    SMD=12 STS=12 NSNR=12 STAD=12 TBS=12 TBL=12 TCB=12
    RBS=12 RBL=12 RFL=12 RCB=12 DMACNT=12 FIFO0=12 FIFO1=12
    SIUST=12 P0=12 P1=12 P2=12 P3=12
   >
// for 80652 CPU
   >REGISTER
    PC=1234 DPTR=1234 ACC=12 B=12 SP=12 PSW=12
    R0=12 R1=12 R2=12 R3=12 R4=12 R5=12 R6=12 R7=12
    IE=12 TCON=12 IP=12 TMOD=12
    TH0=12 TL0=12 TH1=12 TL1=12
    S0CON=12 S1CON=12 S1STA=12 S1ADR=12
    RFL=12 RCB=12 FIFO0=12 FIFO1=12 SIUST=12
    PCON=12 P0=12 P1=12 P2=12 P3=12
   >
// for 80528 CPU
   >REGISTER
    PC=1234 DPTR=1234 ACC=12 B=12 SP=12 PSW=12
    R0=12 R1=12 R2=12 R3=12 R4=12 R5=12 R6=12 R7=12
    IE=12 TCON=12 T2CON=12 IP=12 SCON=12 TMOD=12
    TH0=12 TL0=12 TH1=12 TL1=12 TH2=12 TL2=12
    RCAP2H=12 RCAPL=12 WDCON=12 S1SCS=12 S1BIT=12 S1INT=12
    T3=12 P0=12 P1=12 P2=12 P3=12
   >
 // for 80154 CPU
   >REGISTER
    PC=1234 DPTR=1234 ACC=12 B=12 SP=12 PSW=12
    R0=12 R1=12 R2=12 R3=12 R4=12 R5=12 R6=12 R7=12
    IE=12 TCON=12 T2CON=12 IP=12 SCON=12 TMOD=12
    TH0=12 TL0=12 TH1=12 TL1=12 TH2=12 TL2=12
    RCAP2H=12 RCAPL=12 IOCON=12
    PCON=12 P0=12 P1=12 P2=12 P3=12
   >
 */

//added to support set cpu module 95.10.25
//set:	1. sMaxCpuNum(supported);	2. cpuIDList;		3. cpuNameList
//description:	read supported cpu module info from "regtbl.dat"(marked with
//				"SUPPORT"), and set 3 varible value(see set line), this
//				function only called by PreCpuInitialize(...) at application
//				init.
BOOL CCpuServer::GetCpuListFromFile()
{
CString tblFileName, fileBuf;
CStdioFile tblFile;
int result=-1, tmp0;

	//get file path and create file full name
	tblFileName = szAppPath;
	tblFileName += "REGTBL.DAT";

	//open the file
	if(!tblFile.Open(tblFileName, CFile::modeRead | CFile::typeText ))
	{
	//AfxMessageBox((const char *)(tblFileName+" not found!"));
		return FALSE;
	}
	//get cpu name
	do
	{
		if(NULL==tblFile.ReadString(fileBuf.GetBuffer(300),300))
		{
			fileBuf.ReleaseBuffer();
			return FALSE;
		}
		fileBuf.ReleaseBuffer();
		result=fileBuf.Find("CPU_MODULE_LIST");
	}while(result==-1);

	for(WORD i=0; i<MAXCPUNUM; i++)		//i<60
	{
		if(NULL==tblFile.ReadString(fileBuf.GetBuffer(300),300))
		{
			fileBuf.ReleaseBuffer();
			return FALSE;
		}
		fileBuf.ReleaseBuffer();           
		result=fileBuf.Find("COMMON_REG");
		if(result!=-1)
			break;
		result=fileBuf.Find("EP");
		if(result==-1)
			break; 
		result+=2;
		tmp0=0;
		if(fileBuf.Find("SUPPORT")!=-1)
		{
			while(fileBuf[result]!=' ' && fileBuf[result]!=','
					&&fileBuf[result]!=NULL)
				(cpuNameList[sMaxCpuNum])[tmp0++]=fileBuf[result++];
			(cpuNameList[sMaxCpuNum])[tmp0++]=0;  
			cpuIDList[sMaxCpuNum] =(short) i;
			sMaxCpuNum++;
		}
	}
	return TRUE;
}

//set: 1. cpuModule;		2. cpuMemoryRange;		3. controlOption
//only called by Initialize(...)
BOOL CCpuServer::GetRegFromFile()
{
	//get file path and create file full name
CString tblFileName, fileBuf;
int result=-1, tmp0;

	tblFileName = szAppPath;
	tblFileName += "REGTBL.DAT";
	//open the file
	CStdioFile tblFile;
	if(!tblFile.Open(tblFileName, CFile::modeRead | CFile::typeText))
	{
	//AfxMessageBox((const char *)(tblFileName+" not found!"));
		return FALSE;
	}
	//get cpu name
	do
	{
		if(NULL==tblFile.ReadString(fileBuf.GetBuffer(300),300))
		{                                            
			fileBuf.ReleaseBuffer();
			return FALSE;
		}
		fileBuf.ReleaseBuffer();
		result=fileBuf.Find("CPU_MODULE_LIST");
	}while(result==-1);

	for(WORD i=0; i<m_wCpuModule+1; i++)
	{
		if(NULL==tblFile.ReadString(fileBuf.GetBuffer(300),300))
		{
			fileBuf.ReleaseBuffer();
			return FALSE;
		}
		fileBuf.ReleaseBuffer();
	}
	
	result=fileBuf.Find("EP");
	if(result==-1)
		return FALSE;
	result+=2;
	tmp0=0;
	while(fileBuf[result]!=' ' && fileBuf[result]!=',' && fileBuf[result]!=0)
		cpuModule.cpuName[tmp0++]=fileBuf[result++];
	cpuModule.cpuName[tmp0++]=NULL;
	//get common reg

int tmpY=0,tmpX=0,tmpNo=0; char *tmpPoint;
	do
	{
		if(NULL==tblFile.ReadString(fileBuf.GetBuffer(300),300))
		{
			fileBuf.ReleaseBuffer();
			return FALSE;
		}
		fileBuf.ReleaseBuffer();
		result=fileBuf.Find("COMMON_REG");
	} while(result==-1);
	
	while(TRUE)
	{
		tmpPoint=fileBuf.GetBuffer(300);
		if(NULL==tblFile.ReadString(tmpPoint,300))
			return FALSE;
		if(NULL!=strstr(tmpPoint,"COMMON_END"))
			break;

/*    remove this section by Richard because of 196MX
		while(tmpPoint!=NULL)
		{
			tmpPoint=strstr(tmpPoint,"REG_");
			if(tmpPoint==NULL)
				break;
			tmpPoint+=4;
			tmp0=0;
			while(tmpPoint[tmp0]!=' ' && tmpPoint[tmp0]!=','
				&&tmpPoint[tmp0]!=0)
			{
				cpuModule.RegNameID[tmpNo].Name[tmp0]=tmpPoint[tmp0];
				tmp0++;
			}
			cpuModule.RegNameID[tmpNo].Name[tmp0]=NULL;
			cpuModule.RegNameID[tmpNo].locY=tmpY;
			cpuModule.RegNameID[tmpNo].locX=tmpX++;
			
			cpuModule.RegNameID[tmpNo].ID=(unsigned char)tmpNo;
			tmpNo++;
		}
		tmpX=0; tmpY++;
*/		
		fileBuf.ReleaseBuffer();
	}//WHILE(TRUE)

	//get reg // remove this section by Richard because of 196MX
	
	// add new handler
	CRegItem pTotalReg[MAX_REGISTERS];  
	cpuModule.nMaxReg = MAX_REGISTERS;
	
	::GetAllReg(pTotalReg, cpuModule.nMaxReg);   

	tmpY = 0;
	
	for (int j=0; j<cpuModule.nMaxReg; j++){
		strcpy(cpuModule.RegNameID[j].Name, 
			pTotalReg[j].szName);
		
		if (pTotalReg[j].szName[0] == '\0')	continue;
		
		cpuModule.RegNameID[j].locY = tmpY;
		cpuModule.RegNameID[j].locX = tmpX++;
		cpuModule.RegNameID[j].ID = pTotalReg[j].wSerial;  
		if (tmpX >= 5){
			tmpX = 0;
			tmpY ++;
		}
	}
	

	do
	{
		if(NULL==tblFile.ReadString(fileBuf.GetBuffer(300),300))
		{
			fileBuf.ReleaseBuffer();
			return FALSE;
		}
		fileBuf.ReleaseBuffer();
		result=fileBuf.Find(cpuModule.cpuName);
	} while(result==-1);
	
	while(TRUE)
	{
		tmpPoint=fileBuf.GetBuffer(300);
		if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
		if(NULL!=strstr(tmpPoint,"REG_END")) break; 
/*		
		if (NULL!=strstr(tmpPoint, "enum")){
			fileBuf.ReleaseBuffer();
			continue;
		}

		while(tmpPoint!=NULL)
		{
			tmpPoint=strstr(tmpPoint,"REG_");
			if(tmpPoint==NULL)
				break;
			tmpPoint+=4;
			tmp0=0;
			while(tmpPoint[tmp0]!=' ' && tmpPoint[tmp0]!=','
				&&tmpPoint[tmp0]!=0)
			{
				cpuModule.RegNameID[tmpNo].Name[tmp0]=tmpPoint[tmp0];
				tmp0++;
			}
			cpuModule.RegNameID[tmpNo].Name[tmp0]=0;
			cpuModule.RegNameID[tmpNo].locY=tmpY;
			cpuModule.RegNameID[tmpNo].locX=tmpX++;
			cpuModule.RegNameID[tmpNo].ID=(unsigned char)tmpNo;
			tmpNo++;
		}
		tmpX=0; tmpY++;
*/
		fileBuf.ReleaseBuffer();
	}//WHILE(TRUE)

//	cpuModule.nMaxReg=tmpNo;


//cpu memory range section
//	/*
	//GET CPU MEMORY INFORMATION
	//GET PDATA
	{
		tmpPoint=fileBuf.GetBuffer(300);
		if(NULL==tblFile.ReadString(tmpPoint,300))
			return FALSE;
		if((tmpPoint=strstr(tmpPoint,"PDATA"))==NULL)
			return FALSE;
		
		tmpPoint+=5;
		if(tmpPoint==NULL) return FALSE;
		
		while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
		char strTmpDo[8];  char iTmpDo=0;
		while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
		      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
		{
		 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
		 iTmpDo++;
		 if(iTmpDo>9) return FALSE;
		 }
		tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
		cpuMemoryRange.pMin=strtoul(strTmpDo, NULL, 16);
	
		while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
		iTmpDo=0;
		while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
		      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
		{
		 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
		 iTmpDo++;
		 if(iTmpDo>9) return FALSE;
		 }
		tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
		cpuMemoryRange.pMax=strtoul(strTmpDo, NULL, 16);
		fileBuf.ReleaseBuffer();
	}
	
	//GET XDATA
	{
		tmpPoint=fileBuf.GetBuffer(300);
		if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
		if(NULL==(tmpPoint=strstr(tmpPoint,"XDATA"))) return FALSE;
		
		tmpPoint+=5;
		if(tmpPoint==NULL) return FALSE;
		
		while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
		char strTmpDo[8];  char iTmpDo=0;
		while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
		      && tmpPoint[iTmpDo]!=0 &&tmpPoint[iTmpDo]!='\n')
		{
		 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
		 iTmpDo++;
		 if(iTmpDo>9) return FALSE;
		 }
		tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
		cpuMemoryRange.xMin=strtoul(strTmpDo, NULL, 16);	
		while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
		iTmpDo=0;
		while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
		      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
		{
		 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
		 iTmpDo++;
		 if(iTmpDo>9) return FALSE;
		 }
		tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
		cpuMemoryRange.xMax=strtoul(strTmpDo, NULL, 16);
		fileBuf.ReleaseBuffer();
	}
	
	//GET IDATA
	{
		tmpPoint=fileBuf.GetBuffer(300);
		if(NULL==(tmpPoint=tblFile.ReadString(tmpPoint,300))) return FALSE;
		if(NULL==(tmpPoint=strstr(tmpPoint,"IDATA"))) return FALSE;
		
		tmpPoint+=5;
		if(tmpPoint==NULL) return FALSE;
		
		while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
		char strTmpDo[8];  char iTmpDo=0;
		while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
		      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
		{
		 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
		 iTmpDo++;
		 if(iTmpDo>9) return FALSE;
		 }
		tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
		cpuMemoryRange.iMin=strtoul(strTmpDo, NULL, 16);
		
		while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
		iTmpDo=0;
		while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
		      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
		{
		 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
		 iTmpDo++;
		 if(iTmpDo>9) return FALSE;
		 }
		tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
		cpuMemoryRange.iMax=strtoul(strTmpDo, NULL, 16);
		fileBuf.ReleaseBuffer();
	}
/*	
	//GET RDATA
	{
	tmpPoint=fileBuf.GetBuffer(300);
	if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
	if(NULL==(tmpPoint=strstr(tmpPoint,"RDATA"))) return FALSE;
	
	tmpPoint+=5;
	if(tmpPoint==NULL) return FALSE;
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	char strTmpDo[8];  char iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>9) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	cpuMemoryRange.rMin=strtoul(strTmpDo, NULL, 16);
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>9) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	cpuMemoryRange.rMax=strtoul(strTmpDo, NULL, 16);
	fileBuf.ReleaseBuffer();
	}
	
	//GET BDATA
	{
	tmpPoint=fileBuf.GetBuffer(300);
	if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
	if(NULL==(tmpPoint=strstr(tmpPoint,"BDATA"))) return FALSE;
	
	tmpPoint+=5;
	if(tmpPoint==NULL) return FALSE;
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	char strTmpDo[8];  char iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>9) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	cpuMemoryRange.bMin=strtoul(strTmpDo, NULL, 16);
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>9) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	cpuMemoryRange.bMax=strtoul(strTmpDo, NULL, 16);
	fileBuf.ReleaseBuffer();
	}

	//GET SDATA
	{
	tmpPoint=fileBuf.GetBuffer(300);
	if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
	if(NULL==(tmpPoint=strstr(tmpPoint,"SDATA"))) return FALSE;
	
	tmpPoint+=5;
	if(tmpPoint==NULL) return FALSE;
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	char strTmpDo[8];  char iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>9) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	cpuMemoryRange.sMin=strtoul(strTmpDo, NULL, 16);
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>9) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	cpuMemoryRange.sMax=strtoul(strTmpDo, NULL, 16);
	fileBuf.ReleaseBuffer();
	}
	
	//GET RESET
	{
	tmpPoint=fileBuf.GetBuffer(300);
	if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
	if(NULL==(tmpPoint=strstr(tmpPoint,"RESET"))) return FALSE;
	
	tmpPoint+=5;
	if(tmpPoint==NULL) return FALSE;
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	char strTmpDo[8];  char iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>1) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	controlOption.controlReset=strtoul(strTmpDo, NULL, 16);
	}
	
	//GET EA
	{
	tmpPoint=fileBuf.GetBuffer(300);
	if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
	if(NULL==(tmpPoint=strstr(tmpPoint,"EA"))) return FALSE;
	
	tmpPoint+=2;
	if(tmpPoint==NULL) return FALSE;
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	char strTmpDo[8];  char iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>1) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	controlOption.controlEa=strtoul(strTmpDo, NULL, 16);
	
	}
	
	//GET EBEN
	{
	tmpPoint=fileBuf.GetBuffer(300);
	if(NULL==tblFile.ReadString(tmpPoint,300)) return FALSE;
	if(NULL==(tmpPoint=strstr(tmpPoint,"EBEN"))) return FALSE;
	
	tmpPoint+=4;
	if(tmpPoint==NULL) return FALSE;
	
	while ((*tmpPoint)==' ' || (*tmpPoint)==',') tmpPoint++;
	char strTmpDo[8];  char iTmpDo=0;
	while (tmpPoint[iTmpDo]!=' ' && tmpPoint[iTmpDo]!=','
	      && tmpPoint[iTmpDo]!=0 && tmpPoint[iTmpDo]!='\n')
	{
	 strTmpDo[iTmpDo]=tmpPoint[iTmpDo];
	 iTmpDo++;
	 if(iTmpDo>1) return FALSE;
	 }
	tmpPoint=&(tmpPoint[iTmpDo]); strTmpDo[iTmpDo]=0;
	controlOption.controlEben=strtoul(strTmpDo, NULL, 16);
	}
*/	
	return TRUE;
}

//editted by John.Chow 95.6 to add a private routine to show all reg in shell
//only used in ShowAllRegToShell()
void CCpuServer::ShowAllRegByArray()
{
int i,k1,k2,k3;
char DisplayStr[20];
char DisplayWholeStr[100];
char *tmpBuffer[MAXLINES][MAXALINE];
//added by dragon
CRegItem regItem;
//WORD  nBank;

	for(k1=0;k1<MAXLINES;k1++)
		for(k2=0;k2<MAXALINE;k2++)
			tmpBuffer[k1][k2]=new char[MAXCHARS];
	
	for(k1=0;k1<MAXLINES;k1++)
		for(k2=0;k2<MAXALINE;k2++)
			for(k3=0;k3<MAXCHARS;k3++)
				tmpBuffer[k1][k2][k3]=0;
	
	i=0;                                    
	int nSite;
	while(i<nMaxValidReg)
	{
	    regItem.wSerial = (WORD)RegSelect[i];
	    regItem.wWindow = WINDOW_NONE;
	    
	    GetRegisterLen(&regItem , DisplayStr);
		
		nSite = RegValid[i];
		
		if(cpuModule.RegNameID[i].locY>=MAXLINES)
			break;
		strcat(tmpBuffer[cpuModule.RegNameID[nSite].locY]
				[cpuModule.RegNameID[nSite].locX], DisplayStr);
		i++;
	}//while

	for(k1=0;k1<MAXLINES;k1++)
	{
		DisplayWholeStr[0]=0;
		for(k2=0;k2<MAXALINE;k2++)
		{
			if(tmpBuffer[k1][k2][0]!=0)
			{
				strcat(DisplayWholeStr,tmpBuffer[k1][k2]);
				strcat(DisplayWholeStr," ");
			}
		}
		if(DisplayWholeStr[0]!=0) ShowLine(DisplayWholeStr);
	}

	for(k1=0;k1<MAXLINES;k1++)
		for(k2=0;k2<MAXALINE;k2++)
	delete []tmpBuffer[k1][k2];
}

//return FALSE: initial error,quit
//return TURE: OK
//set: 1. m_wCpuModule			2. ::nMaxReg
//	   3. ::RegName				4. CpuName			5. ::nCurRegs
BOOL CCpuServer::Initialize(int iRoger)
{         
BYTE emuInfo[6];
WORD CpuId;
//WORD tmpRoger;
int i;

	if(iRoger>=sMaxCpuNum) return FALSE;

	if(iRoger==-1)
	{
		m_nErrorID = emuGetID(emuInfo);
		CpuId = *((WORD*)emuInfo);
		if(ICE_OK!=m_nErrorID)
			return FALSE;
	}
	else
		CpuId=cpuIDValid[iRoger];
	m_nErrorID = emuSetID(CpuId);
	if(m_nErrorID!=ICE_OK) 
	{
		m_nErrorID = emuGetID(emuInfo);
		CpuId = *((WORD*)emuInfo);
		if(ICE_OK!=m_nErrorID)
			return FALSE;
		ErrDisplayError(ER_PRE_CPU_SETTING);

		// Added by Chen Jun, 08/08/96
		// Dome: Ignore the incorrect CPU type.
		CpuId = 0;
	}

//	switch (CpuId)//suport dad
//	{
//		case  8:  //EP80C152JA
//		case  9:  //EP83C152JA
//		case 12:  //EP80C152JC
//		case 13:  //EP83C152JC
//			gEPModule=8;
//			break;
//
//		case 10:  //EP80C152JB
//		case 11:  //EP83C152JB
//		case 14:  //EP80C152JD
//		case 15:  //EP83C152JD
//			gEPModule=10;
//			break;
//
//		case 16:  //80c51fa,fb,fc
//		case 17:  //83c51fa,fb,fc
//			gEPModule = 16;  //added by john 96.2
//			break;       
//		default:
//			gEPModule=(unsigned char)CpuId;
//			break;
//	}

	m_wCpuModule = CpuId;   
	if (!InitDllVar(m_wCpuModule)) return FALSE;
	
	if(FALSE==GetRegFromFile()) //added by john 95.8
	 //AfxMessageBox("Register Table Loading Error!");
	 	return FALSE;
	CpuName = cpuModule.cpuName;
	nMaxReg = cpuModule.nMaxReg;
//	nCurRegs= nMaxReg;
	//AbiSetRegNumber((WORD) nMaxReg);
    nMaxValidReg = 0;
	for(i=0;i<nMaxReg/*MAX_REGISTERS*/;i++)
	{
	    RegName[i] = cpuModule.RegNameID[i].Name;
	    if (RegName[i][0] != '\0'){
	    	RegSelect[nMaxValidReg] = cpuModule.RegNameID[i].ID;
	    	RegValid[nMaxValidReg++] = i;
	    	RegSite[cpuModule.RegNameID[i].ID] = i;
	    }
//	    RegSelect[i] = cpuModule.RegNameID[i].ID;
	}
	nCurRegs = nMaxValidReg;
	//init REGMAP.DLL:
	
	return TRUE;
}

//added to support set cpu module 95.10.25
//set:	1. sMaxCpuValid;	2. cpuIDValid;		3. cpuNameValid
//return:CpuServer.cpuNameValid;
//		 iRoger: is supported(by FW and file)cpu number, iRoger==sMaxCpuValid
//			
//description:	read supported cpu module info from FW(AbiGetTargetSupport),
//				and set 3 varible value(see set line), this function only 
//				called by CCputypeDialog constrcution at application init.
char ** CCpuServer::PreCpuInitialize(int &iRoger)
{
int tmp0;
WORD wCpuNum;
WORD wCpuType[256];
int tmp3;

	tmp0=0;
	if(GetCpuListFromFile()==FALSE)
		return 0;//initial error,quit
	m_nErrorID=emuGetFWSupport(&wCpuNum,wCpuType);
	if(ICE_OK!=m_nErrorID)
		return 0;
	if(wCpuNum == 0)
		return 0;

	for(WORD tmp=0;tmp<wCpuNum;tmp++)
	{
		for(int tmp2=0;tmp2<sMaxCpuNum;tmp2++)
		{
			if(cpuIDList[tmp2] == wCpuType[tmp])
			{
				cpuIDValid[tmp0] = cpuIDList[tmp2];
				tmp3=0;
				while(cpuNameList[tmp2][tmp3] != 0)
				{
					cpuNameValid[tmp0][tmp3] = cpuNameList[tmp2][tmp3];
					tmp3++;
				}
				cpuNameValid[tmp0][tmp3]=NULL;
				tmp0++;
			}
		 }
	}
  
   /* for(int tmp2=0;tmp2<sMaxCpuNum;tmp2++)
    { 
		cpuIDValid[tmp0] = cpuIDList[tmp2];
		tmp3=0;
		while(cpuNameList[tmp2][tmp3] != 0)
		{
			cpuNameValid[tmp0][tmp3] = cpuNameList[tmp2][tmp3];
			tmp3++;
		}
		cpuNameValid[tmp0][tmp3]=NULL;
		tmp0++;
	}*/
	strcat(cpuNameValid[0]," (Default)");

	sMaxCpuValid = iRoger = tmp0;
	return (char **)CpuServer.cpuNameValid;
}

STATUS CCpuServer::GetAllReg()
{
	return(emuGetAllReg(&RegValue[0]));
}

BOOL CCpuServer::Id2RegName(WORD id, CString& name)
{
	if(id>=WORD(cpuModule.nMaxReg))
	{
		name.Empty();
		return FALSE;
	}
	name=cpuModule.RegNameID[RegSite[id]].Name;
	return TRUE;
}

void CCpuServer::ShowOneRegToShell(REG_ID reg_id)
{
char DisplayStr[40];
CRegItem regItem;

	if (reg_id >= (WORD)nMaxReg)
	{
		ErrGetErrorText(ER_PRE_REG_NOT_EXIST, DisplayStr);
		ShowLine(DisplayStr);
		return;
	}

	m_nErrorID = GetAllReg();

	if(ICE_OK == m_nErrorID)
	{
		
       regItem.wSerial = (WORD)reg_id;
       regItem.wWindow = WINDOW_NONE;
       
       GetRegisterLen(&regItem, DisplayStr);
       ShowLine(DisplayStr);
	}
	else
		DisplayErrorMessage();
}

void CCpuServer::ShowAllRegToShell()
{
	m_nErrorID = GetAllReg();
	if(ICE_OK == m_nErrorID)
	{
		ShowAllRegByArray();
	}
	else
		DisplayErrorMessage();
}

BOOL CCpuServer::SetRegfromWnd(REG_ID reg_id, DWORD content)
{
unsigned char  uchStatus;

	if(reg_id<0||reg_id>=(WORD)nMaxReg)
	{
		ErrDisplayError(ER_PRE_REG_NOT_EXIST);
		return FALSE;
	}
	GetCpuStatus(uchStatus);
	if(uchStatus==1)
	{
		ErrDisplayError(ER_EMU_TARGET_CPU_HALT);
		return TRUE;
	}

	m_nErrorID = emuSetReg(0, reg_id,content);
	if(ICE_OK == m_nErrorID)
	{
		m_nErrorID = GetAllReg();
		if(ICE_OK != m_nErrorID)
		{
			DisplayErrorMessageBox();
			return(FALSE);
		}
		return(TRUE);
	}
	else
	{
		DisplayErrorMessageBox();
		return(FALSE);
	}
	return(TRUE);
}

void CCpuServer::SetRegfromShell(REG_ID reg_id, DWORD content, WORD nBank)
{
char DisplayStr[40];

//added by dragon
CRegItem regItem;
//char tmp[9];

/*
	if((0!= reg_id)&&(1!= reg_id))
		if(content > 0xff)
		{
			ErrGetErrorText(ER_PRE_REG_VALUE_OVERFLOW, DisplayStr);
			ShowLine(DisplayStr);
			return;
		}
*/  
    //for pc register
	if(reg_id==0&&nBank){
	   DWORD dwBank = DWORD(nBank)<<16;
	   content |= dwBank;
	}
	 
	m_nErrorID = emuSetReg(0, reg_id, content);
	if(ICE_OK == m_nErrorID)
	{   
		m_nErrorID = GetAllReg();
		if(ICE_OK == m_nErrorID)
		{        
	        regItem.wSerial = (WORD)reg_id;
	        regItem.wWindow = WINDOW_NONE;
	        GetRegisterLen(&regItem, DisplayStr, nBank, 1);
			ShowLine(DisplayStr);
		}
		else  
			DisplayErrorMessage();
	}
	else
		DisplayErrorMessage();
}

BOOL CCpuServer::ResetbyWnd(ADDRESS addr)
{
ADDR address;

	address.addrType=addr.adrSpace;
	address.addr=addr.adrAddress;
	m_nErrorID = emuReset(address);

	if(ICE_OK == m_nErrorID)
	{
		m_nErrorID = GetAllReg();
		if(ICE_OK != m_nErrorID)
			DisplayErrorMessageBox();
		// Added by John.
///		GetXviewAppJohn()->m_nCpuStatus = STATUS_HALT;

		// Add elapse timer.
		//Unmark when intergrated. by Chris.
//		((CMainFrame*)GetXviewAppJohn()->m_pMainWnd)->ShowElapseTimer();

		return(TRUE);
	}
	else
	{
		DisplayErrorMessageBox();
		return(FALSE);
	}
}

void CCpuServer::ResetbyShell(ADDRESS addr)
{
ADDR address;

	address.addrType=addr.adrSpace;
	address.addr=addr.adrAddress;
	m_nErrorID = emuReset(address);

	if(ICE_OK == m_nErrorID)
	{
		m_nErrorID = GetAllReg();
		if(ICE_OK != m_nErrorID)
			DisplayErrorMessageBox();

		// Added by John.
///		GetXviewAppJohn()->m_nCpuStatus = STATUS_HALT;

		// Add elapse timer.
		//unmark when intergrated, by Chris.
//		((CMainFrame*)((CXviewApp*)AfxGetApp())->m_pMainWnd)->ShowElapseTimer();
	}
	else
		DisplayErrorMessage();
}

void CCpuServer::DisplayErrorMessage(void) const
{
CString str;

	switch (m_nErrorID)
	{
		case 1:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));
				str.ReleaseBuffer();                  
			break;//target cannot step
		case 2:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;             //memory write failure
		case 3:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;          //map status not included
		case 4:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;           //map address boundary error
		case 5:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;
		case 6: 
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;
		case 7:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;
		case 8:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;
		case 16:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;
		case 17:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;
		case 18:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;
		case 19:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));                  
				str.ReleaseBuffer();
			break;      
		default:
			ErrGetErrorText(ER_ICE_OK+m_nErrorID,str);
				ShowLine( str.GetBuffer(str.GetLength()));     
				str.ReleaseBuffer();
			break;   
	}   
}   // End of CCpuServer::DisplayErrorMessage().


void CCpuServer::DisplayErrorMessageBox(void) const
{
	//FOR  Display the ABI error message using
	switch (m_nErrorID)
	{
		case 1:
			ErrDisplayError(ER_ICE_OK+m_nErrorID);                  
			break;//target cannot step
		case 2:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;             //memory write failure
		case 3:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;          //map status not included
		case 4:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;           //map address boundary error
		case 5:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;
		case 6:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;
		case 7:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;
		case 8:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;
		case 16:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;
		case 17:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;
		case 18:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;    
		case 19:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
			break;     
		default:
			ErrDisplayError(ER_ICE_OK+m_nErrorID); 
	}   
}   // End of CCpuServer::DisplayErrorMessageBox().

//added to support the set cpu module 95.10.25
//initial the cpuserver
CCpuServer::CCpuServer()
{                      
typedef char * PCHAR;
	
	m_wCpuModule=1;
	CpuName="80C196";
	sMaxCpuNum = 0;   

	cpuNameList = new PCHAR [MAXCPUNUM];
	ASSERT(cpuNameList != NULL);
	
	for(int i = 0; i < MAXCPUNUM; i ++){
		cpuNameList[i] = new char [MAXCPUNAMELENGTH];
		ASSERT(cpuNameList[i] != NULL);
	}
	cpuNameValid = new PCHAR [MAXCPUNUM];
	ASSERT(cpuNameValid != NULL);
	for(i = 0; i < MAXCPUNUM; i ++){
		cpuNameValid[i] = new char [MAXCPUNAMELENGTH];
		ASSERT(cpuNameValid[i] != NULL);
	}
}

CCpuServer::~CCpuServer()
{
	for(int i=0; i<MAXCPUNUM; i++)
		delete [] cpuNameList[i];
	delete []cpuNameList;

	for(i=0; i<MAXCPUNUM; i++)
		delete [] cpuNameValid[i];
	delete []cpuNameValid;
}

//get current pc bank,0 -- bank0 ...
#ifdef __cplusplus
extern "C" {
#endif	// __cplusplus  
WORD WINAPI GetCurrentBank() {
	DWORD dwPc;
	emuGetReg(0,0,&dwPc);
	return WORD((dwPc>>16)&0x03);
}
#ifdef __cplusplus
}
#endif	// __cplusplus  

//get bytes of register
int CCpuServer::GetRegisterLen(CRegItem * regItem, char* DisplayStr,WORD nBank, BOOL bFlag)
 {
    char tmp[9];
    int i;
    
//    i = regItem->wSerial;
	i = RegSite[regItem->wSerial];
    if(!ByteFromRegID(regItem)) {
        AfxMessageBox("Error: ID of register is not correct");
        return 0;
    }
    if(regItem->wLen == 1){
       wsprintf(DisplayStr,"%s=%02X",RegName[i],(U8)RegValue[i]);
       return 1;
    }
    else if(regItem->wLen == 2){
       wsprintf(DisplayStr,"%s=%04X",RegName[i],(U16)RegValue[i]);
       return 2;
    }
    else{
       if(!bFlag) nBank = GetCurrentBank();
       
       switch(nBank){
        case 0:
             strcpy(tmp, "P0:");
             break;
        case 1:
             strcpy(tmp, "P1:");
             break;
        case 2:
             strcpy(tmp, "P2:");
             break;
        case 3:
             strcpy(tmp, "P3:");
             break;
        default:
             ASSERT(0);
        }
       wsprintf(DisplayStr,"%s=%s%04X",RegName[i],tmp,RegValue[i]);
       return 4;
    }           
    return 0;
}

///////////////////////////////(EOF)////////////////////////////////
