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

/***************************************************************************
**
** File name : disasm.cpp
** Author:John Zhou
** Description:
**    Having fucntions of disassembly.
**
**
**    Finished date: 1995.4.21
**
**
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/
#include "stdafx.h"

#include "dad.h"
#include "dadtbl.h"
#include "membase.h"
#include <string.h>

/*************************************************************************

**********************DISASSEMBLE*****************************************
The DisAsm function analyses the input string and convert the to 51's instructions
INPUT:(2)unsigned int DAsmInCodeBlkLen
         This value refers to the length of the hex codes being disassembled,
         and the max length is defined in AXHEXCODELEN;
         If the length is lager than the MAXHEXCODELEN,it will be converted
         to the MAXHEXCODELEN;
      (1)unsigned short DAsmStartAddr
         This value refers to the start code address of the first byte
         in *DAsmlnCodeBlk.
OUTPUT:(1)int *DAsmInstrNum
         This value indicates how many instructions have been produced
         by disassembled by this function,the MAX number is MAXINSTRUCTION
       (2)int *DAsmBytesNum
         This value indicates how many HEX bytes have been disassembled.
       (3)OneInstruction MyInstruction[]
          The result of disassembly is contained in the array of struct
          OneInstruction.for details please study it.
          The max number of the result instructions is defined in MAXINSTRUCTION.
RETURN: int >=0 refers to ok
             <0 refers to wrong
        May be the  DAsmInCodeBlkLen is not compatible with the DAsmInstrNum ,
        this time it will report error,but...
        After all,at any time the DAsmInstrNum is valid and the DAsmBytesNum
        is valid unless the return code is -4;
APPENDIX:If the DAsmStartAddr+DAsmInCodeBlkLen>0xffff,it will circle over 0;
         You can get the hex length by using MyOneInstruction[n+1].DAsmStarAddr-MyOneInstruction[n].DAsmStarAddr
         The 65th structure is defined for this using when the 64th structure is used.
*******************************************************************/

extern BOOL isSymDsm; //define by Roger to decide whether the disasm can use symbols.

#ifdef ABI
unsigned char gEPModule;
#endif
#ifndef ABI
unsigned char gEPModule=0; //cpu type ,globle
#endif
unsigned long CpuModule_H,CpuModule_L;

extern SFRNAME SFRbit;
extern SFRNAME SFRbyte;
extern void ShellAddrHextoText(FLAG AddrType,char *ShellAddrStr,unsigned short DadShellAddr);

//added by dragon
extern BOOL IsInCommonBank(unsigned short address);                 
//defined for the GetSymbol() to find the situation fo Disasm(code area or xdata area)
unsigned char WherePlace=ABI_CODE_ADDR_JOHN;

int DAOne (unsigned char *,unsigned short,unsigned int, OneInstructionPlus *OneInstr);
int HextoText(AddrStruct *Hex,unsigned char *textbuff,unsigned char Attribute);

/********************THIS BLOCK DESIGNED FOR INTERFACE WITH SYMBOL **************/
int GetSymbol(unsigned char Attribute,//xdata,idate,ibit,code,Sfr
               unsigned short Address,//0-0xffff
               unsigned char *Symbol, //return string containing symbol,ended with 0
               const unsigned char len)// length of *Symbol buffer=128 bytes
                              //this function only defined for test use
{ 
   int result,lentemp,lenbak;              
   union AddrTemp addrTemp;//only defined for HextoText()
                             
   if(!isSymDsm) return -1;
                             
   if(ABI_CODE_ADDR_JOHN==Attribute) Attribute=WherePlace;
   
   if(len<GATESLEN) return -1;        
   if( IsInCommonBank(Address) ) {
      Attribute = MEM_BANK1; 
   }
   result=AddrToSym( (const U8)Attribute , (U32) Address , (char*) Symbol );   
   
   if ( result==0 ) 
    {
      if ( Symbol[0]!='#' ) return -1;
                                          
      //append address behind symbol
      strcat((char __far *)Symbol,"("); 
      char tmpChar[30];
      ShellAddrHextoText(Attribute,tmpChar,Address);
      strcat((char __far *)Symbol,tmpChar);
      strcat((char __far *)Symbol,")"); 
      
      return strlen((const char __far *)Symbol);
    }
      
   return -1;//no
}
//return -1 error
//return 0 ok
/*********************************************************************/




int DisAsm(
            #ifndef ABI
            unsigned char *DAsmlnCodeBlk,  //point to codes to be disassembly
            #endif
            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
            #ifdef ABI
            FLAG ABIAddrType,  //refer to ABI address type
            #endif
            OneInstruction MyInstruction[] //used in disassembly and it must have MAXINSTRUCTION+1 parts
            );

//disassembly function
int DisAsm(
            #ifndef ABI
            unsigned char *DAsmlnCodeBlk,  //point to codes to be disassembly
            #endif
            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
            #ifdef ABI
            FLAG ABIAddrType,  //refer to ABI address type
            #endif
            OneInstruction MyInstruction[] //used in disassembly and it must have MAXINSTRUCTION+1 parts
            )

 {      
   #ifdef ABI
   unsigned char DAsmlnCodeBlk[MAXHEXCODELEN+10];  //point to codes to be disassembly
   ADDR AddrforABI1,AddrforABI2;
   WORD AddrMax,AddrMin ;
   #endif
   
   #ifndef ABI
   unsigned short AddrMax,AddrMin ;
   #endif
   
   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

   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
   #ifdef 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;ABIAddrType=ABI_CODE_ADDR_JOHN;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=ABIAddrType;
   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;
     }
   #endif
   #ifndef ABI
   AddrMax=0xffff;AddrMin=0;
   #endif

   InstrIndex=0;//for result struct number
   InputInstrIndex=0;//for input code location

   while(InputInstrIndex<DAsmInCodeBlkLen && InstrIndex<MAXINSTRUCTION)
    {
     *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)
      {
       MyInstruction[InstrIndex].InstrStartAddr=(unsigned short)((DAsmStartAddr+InputInstrIndex)%(AddrMax+1L));
       return j;
       }
     //record the result                            
        MyInstruction[InstrIndex].InstrStartAddr=MyOneInstruction.InstrStartAddr;
        for(i=0;i<j;i++)MyInstruction[InstrIndex].InstrString[i]=MyOneInstruction.InstrString[i];
        InputInstrIndex+=CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum;
        InstrIndex++;
     }
                              
   if(InputInstrIndex>DAsmInCodeBlkLen) return -4;                            
                                 
   *DAsmInstrNum=InstrIndex;
   *DAsmBytesNum=InputInstrIndex;
   MyInstruction[InstrIndex].InstrStartAddr=DAsmStartAddr+InputInstrIndex;

   if(InstrIndex>=MAXINSTRUCTION) return -2;

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

//this function disassemble only one instruction
int DAOne (unsigned char *Code,//point to the first bytes being disassembled
           unsigned short Addr,//code address used in disassembly
           unsigned int Num,   //how many bytes shoud be disassembled in this struction
           OneInstructionPlus *OneInstr//the result shoud be contain in this
           )

{
   unsigned int i,Pt,CodeInd;
   int len;//used in the return value of HextoText
   unsigned char *opcode;//point to opcode1,2,3
   unsigned char SymbolString[64];
   //defined for address convertion
   union AddrTemp addrTemp;

   //fill in the OneInstruction buffer with initial MSG
   addrTemp.addrShort=Addr;
   OneInstr->InstrString[0]=addrTemp.addrStruct.addrl;
   OneInstr->InstrString[1]=addrTemp.addrStruct.addrh;
   for(i=0;i<Num;i++) OneInstr->InstrString[6+i]=Code[i];
   OneInstr->InstrString[6+Num]=0;
   if(strlen((char *)(CMd_51[*Code]).Intruction)>MAXINSTRUCTIONSTRING) return -102;//Instruction to long in char
   strcpy((char *)(&(OneInstr->InstrString[14])),(char *)(CMd_51[*Code].Intruction));
   //adjust the space
   for(i=strlen((char *)(&(OneInstr->InstrString[14])));i<6;i++) OneInstr->InstrString[14+i]=' ';
   OneInstr->InstrString[14+i]=0;
   //fill in the OneInstruction buffer with OpCode
   Pt=STARTOPCODEINDEX;
   opcode=&(CMd_51[*Code].opcode1);
   CodeInd=1;

   while(CodeInd<=Num && (&(CMd_51[*Code].opcode3)-opcode)>=0)
   {
   switch(*opcode)
    {
          //for NONE
     case 0: OneInstr->InstrString[Pt]=0;
             Pt++;
             break;
          //for CONSTANT SYMBOL
     case 1:
     case 2:
     case 3:
     case 4:
     case 5:
     case 6:
     case 7:
     case 8:
     case 9:
     case 10:
     case 11:
     case 12:
     case 13:
     case 14:
     case 15:
     case 16:
     case 27://for contentDptr
              strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)(DAsmSpecialSymTbl[*opcode]));
              Pt=Pt+strlen((char *)(DAsmSpecialSymTbl[*opcode]))+1;
              break;
             //codeAddrH
             //suppose codeAddrH always followed by codeAddrL
     case 17: addrTemp.addrStruct.addrh=Code[CodeInd];
              addrTemp.addrStruct.addrl=Code[CodeInd+1];
              if(GetSymbol(WherePlace,addrTemp.addrShort,SymbolString,64)>0)
                {
                 strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)SymbolString);
                 Pt=Pt+strlen((char *)SymbolString)+1;
                 }
                else
                {
                 len=HextoText(&(addrTemp.addrStruct),&(OneInstr->InstrString[Pt]),ABI_CODE_ADDR_JOHN);
                 OneInstr->InstrString[Pt+len]=0;
                 Pt+=len+1;
                 }
              CodeInd++;CodeInd++;
              break;
             //for codeAddrL
     case 18: break;
             //for codeAddrPg(orient code address)
     case 19: addrTemp.addrShort=Addr+CMd_51[*Code].ByteNum;
              if((signed char)(Code[CodeInd])>=0)//rel range -128--127
                addrTemp.addrShort=addrTemp.addrShort+Code[CodeInd];
                else
                 {unsigned char k1;
                  k1=(unsigned char)(~Code[CodeInd]+1);
                  addrTemp.addrShort=addrTemp.addrShort-k1;
                  }

              if(GetSymbol(WherePlace,addrTemp.addrShort,SymbolString,64)>0)
                {
                 strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)SymbolString);
                 Pt=Pt+strlen((char *)SymbolString)+1;
                 }
                else
                {
                 len=HextoText(&(addrTemp.addrStruct),&(OneInstr->InstrString[Pt]),ABI_CODE_ADDR_JOHN);
                 OneInstr->InstrString[Pt+len]=0;
                 Pt+=len+1;
                 }
              CodeInd++;
              break;
             //for dataAddr (0-oxff data address)
     case 20: //for instruction:"MOV data,data " change the code order
              if(opcode<&(CMd_51[*Code].opcode3) && *(opcode+1)==20/*the same as *opcode*/)
               {
                 unsigned char  m;
                 m=Code[CodeInd];  Code[CodeInd]=Code[CodeInd+1];
                 Code[CodeInd+1]=m;
                 }                                                      
                 
              //try to get SFR NAME
#ifdef NOTTEST              
              { int tempInd;
                tempInd=GetByteSFRSymbolIndex(Code[CodeInd],&(SFRbyte),CpuModule_H,CpuModule_L);
                if(tempInd>=0)
                 {
                  strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)SFRbyte.Name);
                  Pt+=strlen((char *)SFRbyte.Name)+1;
                  CodeInd++;
                  break;
                  }
                }
#endif

              //try to get SYMBOL NAME
              addrTemp.addrShort=Code[CodeInd];
              if(GetSymbol(ABI_IDATA_ADDR,addrTemp.addrShort,SymbolString,64)>0)
               {
                strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)SymbolString);
                Pt=Pt+strlen((char *)SymbolString)+1;
                }
               else
                {
                 len=HextoText(&(addrTemp.addrStruct),&(OneInstr->InstrString[Pt]),ABI_IDATA_ADDR);
                 OneInstr->InstrString[Pt+len]=0;
                 Pt+=len+1;
                 }
              CodeInd++;
              break;
             //for dataByte
     case 21: OneInstr->InstrString[Pt]='#'; Pt++;
              //get the address convert function to deal with data convert
              addrTemp.addrShort=Code[CodeInd];
              len=HextoText(&(addrTemp.addrStruct),&(OneInstr->InstrString[Pt]),ABI_IDATA_ADDR);
              OneInstr->InstrString[Pt+len]=0;
              Pt+=len+1;
              CodeInd++;
              break;
             //for dataWord
     case 22: OneInstr->InstrString[Pt]='#'; Pt++;
              //get the address convert function to deal with data convert
              addrTemp.addrStruct.addrh=Code[CodeInd];
              addrTemp.addrStruct.addrl=Code[CodeInd+1];
              len=HextoText(&(addrTemp.addrStruct),&(OneInstr->InstrString[Pt]),ABI_CODE_ADDR_JOHN);
              OneInstr->InstrString[Pt+len]=0;
              Pt+=len+1;
              CodeInd++;CodeInd++;
              break;
             //for NbitAddr
     case 24: OneInstr->InstrString[Pt]='/';Pt++;
             //for bitAddr
     case 23: 
              //try to get SFR NAME
#ifdef NOTTEST              
              { int tempInd;
                tempInd=GetBitSFRSymbolIndex(Code[CodeInd],&(SFRbit),CpuModule_H,CpuModule_L);
                if(tempInd>=0)
                 {
                  strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)(SFRbit.Name));
                  Pt+=strlen((char *)(SFRbit.Name))+1;
                  CodeInd++;
                  break;
                  }
                }                                                          
#endif                
                
              //try to get SYMBOL NAME
              addrTemp.addrShort=Code[CodeInd];
              if(GetSymbol(ABI_BIT_ADDR,addrTemp.addrShort,SymbolString,64)>0)
               {
                strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)SymbolString);
                Pt=Pt+strlen((char *)SymbolString)+1;
                }
               else
                {
                 //try to get byte name
                 int tempInd;
                 unsigned char ucTmpByteAddr = Code[CodeInd]&0xf0;
                 unsigned char ucTmpBitOffset = Code[CodeInd]&0x0f;  
                 ucTmpByteAddr += (ucTmpBitOffset/8)*8;   
                 ucTmpBitOffset = ucTmpBitOffset%8;
                 tempInd=GetByteSFRSymbolIndex(ucTmpByteAddr,&(SFRbyte),CpuModule_H,CpuModule_L);
                 
                 len=HextoText(&(addrTemp.addrStruct),&(OneInstr->InstrString[Pt]),ABI_BIT_ADDR);
                 OneInstr->InstrString[Pt+len]=0;
                 
                 if(tempInd>=0)
                  {                                   
                   Pt+=len;
                   strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)"(");
                   Pt+=strlen((char *)"(");
                   strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)SFRbyte.Name);
                   Pt+=strlen((char *)SFRbyte.Name);
                   strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)".");
                   Pt+=strlen((char *)".");
                   unsigned char tmpOffsetStr[3];
                   tmpOffsetStr[0] = '0'+ ucTmpBitOffset;
                   tmpOffsetStr[1] = 0;      
                   strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)tmpOffsetStr);
                   Pt+=strlen((char *)tmpOffsetStr);
                   strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)")");
                   Pt+=strlen((char *)")")+1;
                   }  
                   else Pt+=len+1;
                 }
              CodeInd++;
              break;
             //for dataAddr11
     case 25: //convert address
              addrTemp.addrShort=Addr+CMd_51[*Code].ByteNum;
              addrTemp.addrStruct.addrl=Code[CodeInd];
              addrTemp.addrStruct.addrh>>=3;addrTemp.addrStruct.addrh<<=3;
              { unsigned char temp;
                temp=*Code; temp>>=5;
                addrTemp.addrStruct.addrh=(unsigned char)(addrTemp.addrStruct.addrh+temp);
                }

              if(GetSymbol(WherePlace,addrTemp.addrShort,SymbolString,64)>0)
                {
                 strcpy((char *)(&(OneInstr->InstrString[Pt])),(char *)SymbolString);
                 Pt+=strlen((char *)SymbolString)+1;
                 }
                else
                {
                 len=HextoText(&(addrTemp.addrStruct),&(OneInstr->InstrString[Pt]),ABI_CODE_ADDR_JOHN);
                 OneInstr->InstrString[Pt+len]=0;
                 Pt+=len+1;
                 }
              CodeInd++;
              break;
     }//switch

    if (Pt>ENDOPCODEINDEX) return -102;
    if (CodeInd>Num) return -101 ;
    opcode++;
    }//while

  if(CodeInd<Num) return -103;
  OneInstr->InstrString[Pt]=0;Pt++;
  return Pt;//ok

  }//DAOne
//return >=0 ok; value refers to the number of opcode bytes
//return -101 for having used overflowed hex code(in DAOne)
//return -102 for opcode buffer overflow(in one instruction buffer)
//return -103 refer to having more code left in DAOne,usually the instruction table is wrong



//This function convert the absolute address in hex pattern to it's text pattern
int HextoText(AddrStruct *Hex,unsigned char *textbuff,unsigned char Attribute)
{
  unsigned char ch;
  int i;
  i=0;
  if(Attribute==ABI_CODE_ADDR_JOHN || Attribute==ABI_XDATA_ADDR )
   {
    ch=(unsigned char)((Hex->addrh)/16);
    if(ch>9) { textbuff[i]='0';i++;}
    textbuff[i]=(unsigned char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    ch=(unsigned char)((Hex->addrh)%16);
    textbuff[i]=(unsigned char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    ch=(unsigned char)((Hex->addrl)/16);
    textbuff[i]=(unsigned char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    ch=(unsigned char)((Hex->addrl)%16);
    textbuff[i]=(unsigned char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    textbuff[i]='H';i++;
    return i;
    }

  if(Attribute==ABI_IDATA_ADDR || Attribute==ABI_BIT_ADDR)
   {
    ch=(unsigned char)((Hex->addrl)/16);
    if(ch>9) { textbuff[i]='0';i++;}
    textbuff[i]=(unsigned char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    ch=(unsigned char)((Hex->addrl)%16);
    textbuff[i]=(unsigned char)((ch<=9)?'0'+ch:'A'+ch-10);i++;
    textbuff[i]='H';i++;
    return i;
    }
    return 0;
}
//return 0:refer to no action
//      >0:refer to the length of text(not include the /0)

/******************* THE END OF FILE ***************************************/
