
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/DADSHELL.CPP   1.2.1.5   17 Apr 1997 15:47:28   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/DADSHELL.CPP  $
** 
**    Rev 1.2.1.5   17 Apr 1997 15:47:28   ZJRD
** No change.
** 
**    Rev 1.2.1.4   16 Apr 1997 10:18:52   ZJRD
** No change.
** 
**    Rev 1.2.1.3   10 Apr 1997 15:30:16   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:11:16   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:16:16   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:27:26   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:45:30   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:15:52   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 12:59:08   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.0   12 Aug 1996 10:55:28   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.5   05 Jun 1996 14:58:32   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:30:54   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:04:08   ZJRD
** EasyPack/SLD Version 1.94
** 
**    Rev 1.2   10 May 1996 09:13:02   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:27:54   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:58:46   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:42:24   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:54:26   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:02:42   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:27:58   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:43:36   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:16:30   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:19:08   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:19:02   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:35:12   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:26:00   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.18   15 Jan 1996 16:17:36   Shirley
** EasyPack/SLD Version 0.34a
** 
**    Rev 1.16   30 Nov 1995 09:11:04   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:30:10   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:20:26   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:28:10   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:30:00   Shirley
** EasyPack/SLD Version 0.24
** 
**    Rev 1.11   08 Nov 1995 16:33:12   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:43:30   Shirley
** EasyPack/SLD Version 0.22
** 
**    Rev 1.9   02 Nov 1995 10:05:32   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:49:38   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:49:02   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:28:38   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:49:52   Shirley
** EasyPack/SLD Version 0.1e
** 
**    Rev 1.3   29 Sep 1995 09:52:46   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:52:36   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:44:42   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:53:22   Shirley
** Initial revision.
**
****************************************************************************/

/***************************************************************************
**
** File name : dadshell.cpp
** Author:John Zhou
** Description:
**    Functions defined in this file are prepared for the using of shell window.
**                      
**
**    Finished date: 1995.4.28
**
**
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

#include "stdafx.h"
#include "cpust.h" //96.4
            
#include "dad.h"
#ifdef SHELL    
#include <string.h>
#include "dadtbl.h"
#include "errcodec.h"
#define REG_PC 0
enum { PMT_NORMAL = 0, PMT_RUN, PMT_FLY, PMT_MACRO, PMT_RND, PMT_CNT };
extern char * PromptStr[PMT_CNT];
extern void ShowLine(char* pszBuffer);
extern unsigned char TRCGetInstLen(unsigned char code);                                

//for stop during disassemble in shell
#ifdef ESC_KEY  
int TestKey(WORD wKey); //1 for getkey ok
#endif

void SrcUpdate(void); //to update source window
void RepaintMemory(void);
void RepaintStack(void);
void RepaintVariable(void);
extern STATUS AbiGetOneReg(int iRegId, UINT* uRegValue);
extern void ErrShow(U32 errorCode,BOOL bUI);

extern unsigned char gEPModule; //cpu type ,globle
extern unsigned long CpuModule_H,CpuModule_L;  //only used in DAD ,eg:CM31--8031
extern unsigned char WherePlace; //used in GetSymbol to decide the code area or xdata are

extern int StrtoHex(unsigned char *Input,unsigned short *Output);                                                   
extern int GetSymbol(unsigned char Attribute,unsigned short Address,
              unsigned char *Symbol,const unsigned char len);
extern int DAOne (unsigned char *,unsigned short,unsigned int, OneInstructionPlus *OneInstr);
extern int Asm (unsigned char * PAsmInput, unsigned short AsmAddr,
                unsigned char * PAsmResult,unsigned int *AsmBytes,
                FLAG ABIAddrType  
                );    
                
int StrtoHexLength(unsigned char *Input,unsigned long *Output);                                     
void CodeHextoText(char *,char *,int);//to convert hex code text to show in shell window
void ShellAddrHextoText(FLAG ,char *,unsigned short);//to convert address to text used in shell window
int DisAsmShell(unsigned long DAsmInCodeBlkLen,unsigned short DAsmStartAddr,   
                int *DAsmInstrNum,int *DAsmBytesNum,FLAG ABIAddrType);
void DisassembleCmd(int nArgc,char *psgArgv[]);//
void AssembleCmd(int nArgc,char *psgArgv[]);  //for chen using  
void DadAssemble(char *);//for Roger using 
int GetAddress(FLAG,unsigned short);//defined for get DAD start address from symbol

//defined for showing address in shell windows
char ShellAddrStrA[10];          
char ShellAddrStrDA[10];
unsigned short DadShellAddrA=0;
unsigned short DadShellAddrDA=0;
FLAG AddrTypeA=ABI_CODE_ADDR_JOHN;
FLAG AddrTypeDA=ABI_CODE_ADDR_JOHN;
int nBank = 0;

//to convert hex code text to show in UI window
void CodeHextoText(char *Hex,char *textbuff,int num)
{
  char ch;
  int i,j;
  i=0;
  for(j=0;j<num;j++)
   {         
    ch=(char)((unsigned char)(Hex[j])/16);
    textbuff[i]=(char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    ch=(char)((unsigned char)(Hex[j])%16);
    textbuff[i]=(char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    }    
  //FILL ' '
  for(j=num;j<3;j++) 
   {
    textbuff[i]=' '; i++;
    textbuff[i]=' '; i++;
    }
       
  textbuff[i]=0; 
}                       

//john 96.12
int AdrTextToAddrEx(const LPSTR  adrstr,BYTE& attribute, WORD& addr)
{ 
	ADDRESS tmpAddr;
	ADDR_RETCODE nAddrRet = AdrTextToAddr(adrstr,tmpAddr);	
	attribute = tmpAddr.adrSpace;
	addr = tmpAddr.adrAddress;
	if(ADR_OK == nAddrRet) return 0;
	return -1;
 }


//defined for get DAD start address from symbol
//return =0 refer to ok!
//else refer to not ok!
                   
//the output <0xffffff                   
int StrtoHexLength(unsigned char *Input,unsigned long *Output)
{
 int i,j;
 unsigned long kk,k;
 
 for(;*Input=='0' && Input[1]=='0';Input++);
 for(unsigned char *P=Input;*P!=0;P++)
     *P=(*P>='a' && *P<='z')?(unsigned char)(*P-'a'+'A'):*P;
 
 i=strlen((char *)Input);  kk=0;k=1;  *Output=0;
 if(i==0) return -101;
 if(Input[i-1]=='H') i--;
 if(i==0 || i>7) return -101;
 for(j=i;j>0;j--)
  {
   if(!(Input[j-1]>='0' && Input[j-1]<='9') && !(Input[j-1]>='A' && Input[j-1]<='F')) return -101;
   if(Input[j-1]>='A' && Input[j-1]<='F') Input[j-1]=(unsigned char)(Input[j-1]-'A'+'9'+1);
   kk+=k*(Input[j-1]-'0');
   k*=16;
   }

 if(kk>0x0ffffff) return -102;
 *Output=kk;
 return 0;//ok
}
//return 0 refers to ok
//return -101 refers to the wrong string
//return -102 refers to too large number

int GetAddress(FLAG *AddrType,unsigned char *SymbolStr,unsigned short *Address)
{ 
  U32 AddressTmp; 
  U8 AddrTypeTmp;
  int i;
  
  
  i = (SymToAddr( (char *)SymbolStr , &AddrTypeTmp , &AddressTmp ));
  
  if(i==0)
   {          
    //check if the address type is proper for DAD
    if((AddrTypeTmp!=ABI_CODE_ADDR_JOHN) && (AddrTypeTmp!=ABI_XDATA_ADDR)
    	&&!(AddrTypeTmp>=ABI_DAD_BANK1 && AddrTypeTmp<=ABI_DAD_BANK4)) 
    	return -1;
    *Address=(unsigned short)AddressTmp;
    *AddrType=(FLAG)AddrTypeTmp;
    return 0;
    }
  
  return -1; 
  }

//this function only used in converting DadShellAddrA to ShellAddrStrA
////to convert address to text used in shell window
//retur 0 refer ok
void ShellAddrHextoText(FLAG AddrType,char *ShellAddrStr,unsigned short DadShellAddr)
{
  ADDRESS addr;            
  addr.adrSpace = (ADDR_SPACE)AddrType;
  addr.adrAddress = DadShellAddr;
  
  ADDR_RETCODE result = 
  AdrDadAddrToHex( addr,ShellAddrStr);
   
}
                            
//This function comes from DisAsm(),and it only translate instructions one by
//one.It doesn't save the result but it can show the results in shell window one by one                            
int DisAsmShell(unsigned int DAsmInCodeBlkLen,  // the code block length
                unsigned short DAsmStartAddr,   // the start address to be disassembly
                int *DAsmInstrNum,  // disassembly instruction number
                int *DAsmBytesNum, // despite the function's failure,they are valuable
                FLAG ABIAddrType  //refer to ABI address type
                )
               
 {      
   unsigned char DAsmlnCodeBlk[MAXHEXCODELEN];  //point to codes to be disassembly
   ADDR AddrforABI1,AddrforABI2;
   WORD AddrMax,AddrMin ;
   
   
   unsigned int InstrIndex;  //index to the current instruction to be dissambled
                             //used in MyInstruction
   unsigned int InputInstrIndex;//index to the current instruction byte being
                                  //disasembled in DAsmlnCodeBlk
   unsigned char OneInstrCode[7]; //defining more memory than it's need
   OneInstructionPlus MyOneInstruction;//for DAOne using
   char ShellStr[256];//used in showing in show window
   int i,j;

   *DAsmInstrNum=*DAsmBytesNum =0;

   if(gEPModule>63) return -3;
   
//convert the cpu module to own definition
   if(gEPModule<32)
   {
    CpuModule_L=1;  CpuModule_H=0;
    CpuModule_L<<=gEPModule;
    }                            
    else
     { 
      CpuModule_L=0;  CpuModule_H=1;
      CpuModule_H<<=(gEPModule-32);
      }
//check length
   if(DAsmInCodeBlkLen==0) return -6;//return for the code length is zero
   if(DAsmInCodeBlkLen>MAXHEXCODELEN)DAsmInCodeBlkLen=MAXHEXCODELEN;
//get bytes from ABI
   switch(ABIAddrType)
    {
     case ABI_CODE_ADDR_JOHN  : AddrMax=ABI_CODE_ADDR_JOHN_MAX;AddrMin=ABI_CODE_ADDR_JOHN_MIN;break;
     case ABI_XDATA_ADDR : AddrMax=ABI_XDATA_ADDR_MAX;AddrMin=ABI_XDATA_ADDR_MIN;break;
     //case ABI_IDATA_ADDR : AddrMax=ABI_IDATA_ADDR_MAX;AddrMin=ABI_IDATA_ADDR_MIN;break;
     //case ABI_SFR_ADDR   : AddrMax=ABI_SFR_ADDR_MAX;AddrMin=ABI_SFR_ADDR_MIN;break;
     //case ABI_BIT_ADDR   : AddrMax=ABI_BIT_ADDR_MAX;AddrMin=ABI_BIT_ADDR_MIN;break;
     default           : AddrMax=ABI_CODE_ADDR_JOHN_MAX;AddrMin=ABI_CODE_ADDR_JOHN_MIN;break;
     }
   if((WORD)DAsmStartAddr>AddrMax || (WORD)DAsmStartAddr<AddrMin) return -7;//refer to having wrong address comparing to address type
   
   AddrforABI1.addrType=ABIAddrType;
   AddrforABI1.addr=(WORD)DAsmStartAddr;
   AddrforABI2.addrType=AddrforABI1.addrType;
   AddrforABI2.addr=(WORD)(DAsmStartAddr+(DAsmInCodeBlkLen-1));
   if(AddrforABI1.addr<=AddrforABI2.addr)
    { if(AbiGetMemN(AddrforABI1,AddrforABI2,(char *)DAsmlnCodeBlk)!=0) return -105;}
    else
    {
     ADDR addrTemp;                    
   	 addrTemp.addrType=ABIAddrType;
     addrTemp.addr=AddrMax;
     if(AbiGetMemN(AddrforABI1,addrTemp,(char *)DAsmlnCodeBlk)!=0) return -105;
     addrTemp.addr=AddrMin;
     if(AbiGetMemN(addrTemp,AddrforABI2,(char *)(&DAsmlnCodeBlk[0xffff-AddrforABI1.addr+1]))!=0) return -105;
     }
   AddrMax=0xffff;AddrMin=0;
   
   WherePlace=ABIAddrType;
   InstrIndex=0;//for result struct number
   InputInstrIndex=0;//for input code location
   
   while(InputInstrIndex<DAsmInCodeBlkLen )
    {
    
//******************STOP IF ESCAPE KEY IS DOWN*************************
     #ifdef ESC_KEY  
     if(TestKey(VK_ESCAPE)) return -106;
     #endif
//*********************************************************************
     
     *DAsmInstrNum=InstrIndex;
     *DAsmBytesNum=InputInstrIndex;
     for(i=0;i<3;i++) OneInstrCode[i]=0;
     for(i=0;i<CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum;i++) OneInstrCode[i]=DAsmlnCodeBlk[InputInstrIndex+i];
     j=DAOne(OneInstrCode,(unsigned short)((DAsmStartAddr+InputInstrIndex)%(AddrMax+1L)),CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum,&MyOneInstruction);
     if(j<0)  return j;
     if(InputInstrIndex+CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum>DAsmInCodeBlkLen) 
     { 
       return -4;
       }
     
     //show the result                            
       
       //get address symbol        
       {
        unsigned char SymStr[70];
        int ResTmp;
            
        ResTmp=GetSymbol(ABIAddrType,(unsigned short)((DAsmStartAddr+InputInstrIndex)%(AddrMax+1L)),SymStr,64);    
        if( ResTmp>=0 )
          {
           unsigned char *tmppoint;
           tmppoint=SymStr;
           while(*tmppoint!=0 && *tmppoint!='(') tmppoint++;
           *tmppoint=0;
           strcat((char *)SymStr,":");
           ShowLine((char *)SymStr);
           }
        }
        
       ShellAddrHextoText(AddrTypeDA,ShellAddrStrDA,DAsmStartAddr+InputInstrIndex);
       ShellStr[0]=0;
       strcat(ShellStr,ShellAddrStrDA);
       strcat(ShellStr,"   ");
       CodeHextoText((char *)(&(MyOneInstruction.InstrString[6])),&(ShellStr[strlen(ShellStr)]),
                     CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum);
       strcat(ShellStr,"             ");
       ShellStr[20]=0;
       strcat(ShellStr,(char *)(&(MyOneInstruction.InstrString[14])));
       strcat(ShellStr," ");
       {
        unsigned char *OPCODE;
        OPCODE=&(MyOneInstruction.InstrString[21]); 
        while(*OPCODE!=0)
         {
          strcat(ShellStr,(char *)OPCODE);strcat(ShellStr,",");
          OPCODE+=strlen((char *)OPCODE)+1;
          }      
         ShellStr[((strlen(ShellStr)>0)?strlen(ShellStr)-1:0)]=0;//remove last ',' or ' '
        }
       
       ShowLine(ShellStr);
       
       InstrIndex++;
       InputInstrIndex+=CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum;
     }//while
                                    
   *DAsmInstrNum=InstrIndex;
   *DAsmBytesNum=InputInstrIndex;                                 
   

   return 0;//OK!
  }
//return  0 ok
//return <=-100 DADOne error
//return -3 invalid cpu moduel
//return -4 last instruction needs more code
//return -105 ABI reading error
//return -6 return for the code length is zero
//return -7 refer to having wrong address comparing to address type
//return -105 refer to ABI call error  
//return -106 get ESCAPE KEY


                                                                          

//this function defined for shell window's disassemble commmand using(only called by Chen)
void DisassembleCmd(int nArgc,char *psgArgv[])
{
 int i;
 unsigned long DAsmInCodeBlkLen;               
 int DAsmInstrNum;
 int DAsmBytesNum;
 STATUS  m_nErrorID;                
 WORD tmpAddr;
 FLAG tmpType;
 
 //john 96.4
 if(GetXviewAppJohn()->m_nCpuStatus == STATUS_GO ) {
    ::ErrShow(ER_GOFLY_ERR_MSG,FALSE);
    return;
 }
         
 i=0;                                          
 switch(nArgc)
  {            
   case 1: //get PC from ABI    
           m_nErrorID = AbiGetOneReg( REG_PC , (UINT*) (&DadShellAddrDA) ); 
           if(ICE_OK != m_nErrorID)    
           { 
            ShowLine("Communication error!");
            return;
            }
           AddrTypeDA = GetPCBank();
           DAsmInCodeBlkLen=DisassemblyDefaultLength;
           break;
           
   case 2:  if (0 != AdrTextToAddrEx(psgArgv[1],AddrTypeDA,DadShellAddrDA))
            ASSERT(FALSE);
            DAsmInCodeBlkLen=DisassemblyDefaultLength;
            break;
   case 3:  if(0 != AdrTextToAddrEx(psgArgv[2],tmpType,tmpAddr))
   			ASSERT(FALSE);  
   			if (0 != AdrTextToAddrEx(psgArgv[1],AddrTypeDA,DadShellAddrDA))
            ASSERT(FALSE);                            
            if(tmpType !=0 && tmpType != AddrTypeDA) {
            	ShowLine("Syntax error!"); 
            	return;
            }
   			DAsmInCodeBlkLen = tmpAddr - DadShellAddrDA +1;
            break; 
   case 4:  if (0 != AdrTextToAddrEx(psgArgv[1],AddrTypeDA,DadShellAddrDA))
            ASSERT(FALSE);
             
           i=0;
           {
            unsigned long temp;
            if(StrtoHexLength((unsigned char *)(&(psgArgv[3][i])),&temp)!=0)
             {
              ShowLine("Length error!");
              return;        
              }
            DAsmInCodeBlkLen=temp;
            }
           break; 
   default:DadShellAddrDA=0;
           DAsmInCodeBlkLen=1;        
  } //switch
 i=0; 
 
 //show in shell window if necessary
 { 
  char ShellStrTmp[35];
  ShellStrTmp[0]=0;
  strcat(ShellStrTmp,"LOC       OBJ CODE  SOURCE CODE ");
  ShowLine(ShellStrTmp);
  }
 while(DAsmInCodeBlkLen!=0)
  {                    
   unsigned int temp;
   
   if(DAsmInCodeBlkLen>0xf0) temp=0xf0; else temp=(unsigned int)DAsmInCodeBlkLen;
   i=DisAsmShell(temp,DadShellAddrDA,&DAsmInstrNum,&DAsmBytesNum,
                 AddrTypeDA);
                 
   if(i==-106) 
    { //ShowLine("Being interrupted!");
      return;                        
      }
   
   DAsmInCodeBlkLen=DAsmInCodeBlkLen-DAsmBytesNum;              
   DadShellAddrDA=DadShellAddrDA+DAsmBytesNum;
                                                
   if(i<0 && !(temp>=3 && i==-4)) break;
                                                   
   }
 
 switch(i)
  {
   case  0: break;                 
   case -4://ErrShow(ER_EMU_DAD_SRC_DEFAULT,FALSE);
            break;
   case -3: ErrShow(ER_EMU_DAD_6,FALSE);
            break;
   case -105:ErrShow(ER_EMU_DAD_19,FALSE);
            break;
   case -6:ErrShow(ER_EMU_DAD_SRC_6,FALSE);
            break;
   case -7:ErrShow(ER_EMU_DAD_20,FALSE);
            break;
   default:ErrShow(ER_EMU_DAD_SRC_DEFAULT,FALSE);
   }          
 }
 
              
                                               
//this function prepared for chen(syntax) go give me the address                                               
void AssembleCmd(int nArgc,char *psgArgv[])
{      
 int i; i=0;
 char strTmpTmp[20];
 CString str = psgArgv[1];
 
 DadShellAddrA=0;
 ShellAddrHextoText(AddrTypeA,ShellAddrStrA,DadShellAddrA);
 strcpy(strTmpTmp," ");
 strcat(strTmpTmp,ShellAddrStrA);
 strcpy(ShellAddrStrA,strTmpTmp);
 PromptStr[PMT_RND]=ShellAddrStrA;
 
 if (nArgc==1)
  { 
   //get PC from ABI    
   STATUS  m_nErrorID = AbiGetOneReg( REG_PC , (UINT*) (&DadShellAddrA) ); 
   if(ICE_OK != m_nErrorID)    
    {      
      ErrShow(ER_ICE_OK+m_nErrorID,FALSE);
      return;
      }
    
   AddrTypeA=GetPCBank();
   ShellAddrHextoText(AddrTypeA,ShellAddrStrA,DadShellAddrA);
   strcpy(strTmpTmp," ");
   strcat(strTmpTmp,ShellAddrStrA);
   strcat(strTmpTmp,"  ");
   strcpy(ShellAddrStrA,strTmpTmp);
   PromptStr[PMT_RND]=ShellAddrStrA;
   return;
   }
                                
 if (0 != AdrTextToAddrEx(psgArgv[1],AddrTypeA,DadShellAddrA))
    ASSERT(FALSE);
   
 ShellAddrHextoText(AddrTypeA,ShellAddrStrA,DadShellAddrA);
 strcpy(strTmpTmp," ");
 strcat(strTmpTmp,ShellAddrStrA);
 strcat(strTmpTmp,"  ");
 strcpy(ShellAddrStrA,strTmpTmp);
 PromptStr[PMT_RND]=ShellAddrStrA;    
 
 return;  
 }      
extern void CreateCmd(int nArgc, char* pszArgv[]);//96.4 john                                                                
char* LabelAnalyse(char *strInstr,unsigned short usTmpAddr)
{ 
	if(':' != strInstr[0]) return strInstr;
	char* tmpStrPoint = strchr((char*)(&(strInstr[1])),':');
	if (NULL == tmpStrPoint) return strInstr;
	*tmpStrPoint = 0;                                        
	char strCreate[] = "CREATE";
	char *tmpStr = new char[strlen((char*)(&(strInstr[1])))+10];
	if (NULL == tmpStr) {
		ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
		return strInstr;
	}
	tmpStr[0] = 0;
	//NOW CREATE A SYMBOL FROM GATES                      
	strcat(tmpStr,"#LABEL");
	strcat(tmpStr,(char*)(&(strInstr[1])));
	char* pszArgv[3];  
	char  ShellAddrStrATmp[10];
	ShellAddrStrATmp[0] = 0; strcat(ShellAddrStrATmp,ShellAddrStrA);
	ShellAddrStrATmp[6] = 0;
	pszArgv[0] = strCreate; pszArgv[1] = tmpStr; pszArgv[2] = ShellAddrStrATmp;        
	CreateCmd(3,pszArgv);                 
	//if only input label return the label addr
	
	return ((char*)(&(tmpStrPoint[1])));
	
}
//this function defined for Roger(Shell window) to call asssembly function                                                                
void DadAssemble(char *RogerInstr) 
{         
 int i;
 char AsmResult[5]; 
 unsigned int AsmBytes;                                                      
 
 //if NULL input,return  
 ADDR addrTemp1,addrTemp2;      
 char chTmp[10];
 int iTmp,iTmp2;            
 OneInstructionPlus OneInstr;
 CString strTmp;
 if( 0 == *RogerInstr ) {          
	addrTemp1.addrType=AddrTypeA;
	addrTemp1.addr = DadShellAddrA;
	addrTemp2.addrType  = addrTemp1.addrType;
	addrTemp2.addr = addrTemp1.addr + 5;
	if (addrTemp2.addr > 0xffff) addrTemp2.addr = addrTemp2.addr-0xffff-1;
	if(addrTemp1.addr<=addrTemp2.addr)
    { if(AbiGetMemN(addrTemp1,addrTemp2,chTmp)!=0) {
		ErrShow(ER_EMU_DAD_19,FALSE);
		return;
	  }           
    }
    else
    {
     ADDR addrTemp;      
     addrTemp.addrType=addrTemp1.addrType;
     addrTemp.addr=0xffff;
     if(AbiGetMemN(addrTemp1,addrTemp,chTmp)!=0) {
		ErrShow(ER_EMU_DAD_19,FALSE);
		return;
	  }           
     addrTemp.addr=0;
     if(AbiGetMemN(addrTemp,addrTemp1,chTmp)!=0) {
		ErrShow(ER_EMU_DAD_19,FALSE);
		return;
	  }           
    }
     
	iTmp = TRCGetInstLen(chTmp[0]);
	WORD dwBak = DadShellAddrA;
	iTmp = DAOne ((unsigned char *)chTmp,dwBak,iTmp,&OneInstr);
	if (iTmp>0) {    
	    char pcTmpn[10]; 
	    pcTmpn[0] = 0;
	    strcat(pcTmpn,&(ShellAddrStrA[1]));
		strTmp = pcTmpn;  
		strTmp += (char *)(&(OneInstr.InstrString[14]));
        //strTmp += "   ";
        {
	        unsigned char *OPCODE;
	        OPCODE=&(OneInstr.InstrString[21]); 
	        while(*OPCODE!=0)
	         {
	          strTmp += (char *)OPCODE;
	          strTmp += ",";
	          OPCODE+=strlen((char *)OPCODE)+1;
	          }      
	         if (' ' == strTmp[strTmp.GetLength()-1] ||
	         	 ',' == strTmp[strTmp.GetLength()-1]) {
	         	 strTmp = strTmp.Left(strTmp.GetLength()-1);
	         }                                              //remove last ',' or ' '
         }
        
		ShowLine(strTmp.GetBuffer(strTmp.GetLength()));
		strTmp.ReleaseBuffer();	
	}
 	return;
 }
  
 if(strlen(RogerInstr)>99) 
  {                                            
   ErrShow(ER_EMU_DAD_7,FALSE);
   return;
   }
 
 //analysis label if any   
 unsigned short usTmpAddr;
 char * szPoint = LabelAnalyse(RogerInstr,usTmpAddr);
 //if only input label, goto label
 if(0 == *szPoint) {
 	//DadShellAddrA = usTmpAddr; 
    //ShellAddrHextoText(AddrTypeA,ShellAddrStrA,DadShellAddrA);
    //PromptStr[PMT_RND] = ShellAddrStrA;
    return;
 }   
 
 i=Asm((unsigned char *)(szPoint),DadShellAddrA,
       (unsigned char *)AsmResult,&AsmBytes,AddrTypeA);
 char strTmpTmp[20];
 switch(i)
  {
   case  0:DadShellAddrA=(unsigned short)(DadShellAddrA+AsmBytes); 
           ShellAddrHextoText(AddrTypeA,ShellAddrStrA,DadShellAddrA);
 		   strcpy(strTmpTmp," ");
           strcat(strTmpTmp,ShellAddrStrA);    
           strcat(strTmpTmp,"  ");
           strcpy(ShellAddrStrA,strTmpTmp);
           PromptStr[PMT_RND]=ShellAddrStrA;          
            SrcUpdate();  
            RepaintMemory();
            RepaintStack();
            RepaintVariable();
           break;
   case -1:
   case -2:
   case -3:ErrShow(ER_EMU_DAD_3,FALSE);
           break;
   case -6:ErrShow(ER_EMU_DAD_6,FALSE);
           break;
   case -7:ErrShow(ER_EMU_DAD_7,FALSE);
           break;
   case -8:ErrShow(ER_EMU_DAD_8,FALSE);
           break;
   case -9:ErrShow(ER_EMU_DAD_9,FALSE);
           break;
   case -10:ErrShow(ER_EMU_DAD_10,FALSE);
            break;
   case -11:ErrShow(ER_EMU_DAD_11,FALSE);
            break;
   case -12:ErrShow(ER_EMU_DAD_12,FALSE);
            break;
   case -13:ErrShow(ER_EMU_DAD_13,FALSE);
            break;
   case -14:ErrShow(ER_EMU_DAD_14,FALSE);
            break;
   case -15:ErrShow(ER_EMU_DAD_15,FALSE);
            break;
   case -16:ErrShow(ER_EMU_DAD_16,FALSE);
            //the number of return codes is wrong,the Cmd_51 table may be wrong
            break;
   case -17:ErrShow(ER_EMU_DAD_17,FALSE);
            break;                                   
   case -18:ErrShow(ER_EMU_DAD_18,FALSE);
            break;
   case -19:ErrShow(ER_EMU_DAD_19,FALSE);
            break;
   case -20:ErrShow(ER_EMU_DAD_20,FALSE);
            break;                                                   
   case -99:ErrShow(ER_EMU_DAD_99,FALSE);
            break;                
   default:ErrShow(ER_EMU_DAD_DEFAULT,FALSE);
            break;
   }//switch
   
 }//function   
 
#endif 
