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

/***************************************************************************
**
** File name : source.cpp
** Author:John Zhou
** Description:
**    This file is for Roger to use in source window
**
**
**    Finished date: 1995.4.21 v0.1
**    Fixed    date: 1995.9.11 v0.1a
**                   in SRCDisAsm(...) to edit error expression
**
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/
#include "stdafx.h"
#include "dad.h"
#ifdef SOURCE
#include "dadtbl.h"
#include <string.h>
#include "errcodec.h"
#include "hosterrs.h"

#include <sys\types.h>
#include <sys\timeb.h>

extern unsigned char gEPModule;
extern unsigned long CpuModule_H,CpuModule_L;                                                              
extern unsigned char WherePlace; //used in GetSymbol to decide the code area or xdata area


extern int DAOne (unsigned char *,unsigned short,unsigned int, OneInstructionPlus *OneInstr);
void CodeHextoText(char *Hex,char *textbuff,int num);
extern 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 

//editted because of the request that I must fill the buffer if having dad error
int OwnSRCDisAsm(    
			int nBank,
            unsigned int DAsmStartAddr,   // the start address to be disassembly
            unsigned int DAsmInCodeBlkLen,  // the code block length
            unsigned int *DAsmInstrNum,  // disassembly instruction number
            unsigned int *DAsmBytesNum, // despite the function's failure,they are valuable
            char        **InstrArray,// these to buffers contain the results(instructions and length)
            unsigned int *AddrLenArray, // max array numbler is 100
            char        **LabelArray  // contain the label string if finding
            )

 { 
    FLAG ABIAddrType; //refer to ABI address type
   
   unsigned char DAsmlnCodeBlk[MAXHEXCODELEN+10];  //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

   int i,j;     
   
   ABIAddrType=nBank;

   *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;
     }
    
   WherePlace=ABIAddrType;
   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) return j;
     
     //record the result                            
     
     //num
     AddrLenArray[InstrIndex]=CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum;
     
     //label      
     *(LabelArray[InstrIndex]+0)=0;
     {
      unsigned char SymStr[70];
      int ResTmp;
      
      ResTmp=GetSymbol(nBank,(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,":");
         strcat(LabelArray[InstrIndex],(char *)SymStr);
         }
      }
        
     //instruction
     *(InstrArray[InstrIndex]+0)=0;
     
     CodeHextoText((char *)(&(MyOneInstruction.InstrString[6])),(InstrArray[InstrIndex]+0),
                    AddrLenArray[InstrIndex]);//insert obj code
     strcat(InstrArray[InstrIndex]," ");
     
     strcat(InstrArray[InstrIndex],(char *)(&(MyOneInstruction.InstrString[14])));
     strcat(InstrArray[InstrIndex]," ");
      {
       unsigned char *OPCODE;
       OPCODE=&(MyOneInstruction.InstrString[21]); 
       while(*OPCODE!=0)
        {
         strcat(InstrArray[InstrIndex],(char *)OPCODE);
         strcat(InstrArray[InstrIndex],",");
         OPCODE+=strlen((char *)OPCODE)+1;
         }      
       *(
         InstrArray[InstrIndex]+
         ((strlen(InstrArray[InstrIndex])>0)?strlen(InstrArray[InstrIndex])-1:0)
        )=0;  
       }
         
     InputInstrIndex+=CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum;
     InstrIndex++;
     }
         
   if(InputInstrIndex>DAsmInCodeBlkLen)  return -4; 
   
   *DAsmInstrNum=InstrIndex;
   *DAsmBytesNum=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
  }
  
//disassembly function(from DisAsm()) and defined for source
int SRCDisAsm(    
			int			 nBankArg,			//6, 7, 8, 9
            unsigned int DAsmStartAddr,   // the start address to be disassembly
            unsigned int DAsmInCodeBlkLen,  // the code block length
            unsigned int *DAsmInstrNum,  // disassembly instruction number
            unsigned int *DAsmBytesNum, // despite the function's failure,they are valuable
            char        **InstrArray,// these to buffers contain the results(instructions and length)
            unsigned int *AddrLenArray, // 
            char        **LabelArray  // contain the label string if finding
            )
{            

	struct _timeb buffer;
	unsigned long lTime1, lTime2;
	_ftime(&buffer);
	lTime1 = buffer.time*1000+buffer.millitm;
	
//	TRACE1("Start = %u\n", lTime1);
                          
 int result= OwnSRCDisAsm(   
            nBankArg,
            DAsmStartAddr,   // the start address to be disassembly
            DAsmInCodeBlkLen,  // the code block length
            DAsmInstrNum,  // disassembly instruction number
            DAsmBytesNum, // despite the function's failure,they are valuable
            InstrArray,// these to buffers contain the results(instructions and length)
            AddrLenArray, // max array numbler is 100
            LabelArray  // contain the label string if finding
            );
 
	_ftime(&buffer);
	lTime2 = buffer.time*1000+buffer.millitm;
//	TRACE1("End = %u\n", lTime2);
	
//	TRACE1("Diff = %u\n", lTime2-lTime1+1);
//    TRACE1("length = %d\n",*DAsmInstrNum);        
	//char tmpx[100];
	//sprintf(tmpx,"%04x",(WORD)(lTime2-lTime1));
	//AfxMessageBox(tmpx);
            
 if(result==0 || result==-4)  return 0;
 
 char tmp[40]; tmp[0]=0; CString strTmp = "";
 switch(result)
 {
  case -2:if(0 != ErrGetErrorText(ER_EMU_DAD_SRC_2, strTmp)) break;
          strcat(tmp,strTmp.GetBuffer(strTmp.GetLength()+2)); break;
  case -3:if(0 != ErrGetErrorText(ER_EMU_DAD_SRC_3, strTmp)) break;
          strcat(tmp,strTmp.GetBuffer(strTmp.GetLength()+2)); break;
  case -6:if(0 != ErrGetErrorText(ER_EMU_DAD_SRC_6, strTmp)) break;
          strcat(tmp,strTmp.GetBuffer(strTmp.GetLength()+2)); break;
  case -7:if(0 != ErrGetErrorText(ER_EMU_DAD_SRC_7, strTmp)) break;
          strcat(tmp,strTmp.GetBuffer(strTmp.GetLength()+2)); break;
  case -105:if(0 != ErrGetErrorText(ER_EMU_DAD_SRC_105, strTmp)) break;
          strcat(tmp,strTmp.GetBuffer(strTmp.GetLength()+2)); break;
  default:if(0 != ErrGetErrorText(ER_EMU_DAD_SRC_DEFAULT, strTmp)) break;
          strcat(tmp,strTmp.GetBuffer(strTmp.GetLength()+2)); break;
  }
 
 AfxMessageBox(tmp);
 //fill the buff
 if(DAsmInCodeBlkLen==0) DAsmInCodeBlkLen=MAXINSTRUCTION;
 *DAsmInstrNum= DAsmInCodeBlkLen;
 *DAsmBytesNum= DAsmInCodeBlkLen;
 for(unsigned int i=0;i<*DAsmInstrNum;i++) 
  {
   AddrLenArray[i]=1;               
   *(InstrArray[i]+0)=0;     
   strcat(InstrArray[i],"NOP"); 
   *(LabelArray[i]+0)=0;
   }             
 return result;  
 }              

//added by john 96.4
int SpaDisAsm(                                          
			int			 nBankArg,			//6, 7, 8, 9
            unsigned short DAsmStartAddr,   // the start address to be disassembly
            unsigned short DAsmInCodeBlkLen,  // the code block length
            unsigned short &usNextAddr,
            CStringList* &pList
            )

 { 
   FLAG ABIAddrType; //refer to ABI address type
   
   unsigned char DAsmlnCodeBlk[0xff+10];  //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

   int i,j;     
   char strInstrTmp[256];
   char strObject[20];
   
   ABIAddrType=nBankArg;
   
   
   //*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=ABIAddrType;
   AddrforABI2.addr=(WORD)(DAsmStartAddr+(DAsmInCodeBlkLen-1));
   if(AddrforABI1.addr<=AddrforABI2.addr) {
    if(AbiGetMemN(AddrforABI1,AddrforABI2,(char *)DAsmlnCodeBlk)!=0) return -105;
   }
    else
    {
     ASSERT(FALSE);
     }
    
   WherePlace=ABIAddrType;
   InstrIndex=0;//for result struct number
   InputInstrIndex=0;//for input code location
   
   unsigned short usTmp = 0;
   while(InputInstrIndex<DAsmInCodeBlkLen && InstrIndex<MAXINSTRUCTION)
    {
     //*DAsmInstrNum=InstrIndex;
     usTmp = 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;
     
     //record the result                            
     
     
     strInstrTmp[0] = 0; strObject[0] = 0;
     
     wsprintf(strInstrTmp,"%04X     ",
              (unsigned short)((DAsmStartAddr+InputInstrIndex)%(AddrMax+1L)));
     
     CodeHextoText((char *)(&(MyOneInstruction.InstrString[6])),
                   strObject,
                   CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum);//insert obj code
     strcat(strInstrTmp,strObject);              
     strcat(strInstrTmp,"  ");
     
     strcat(strInstrTmp,(char *)(&(MyOneInstruction.InstrString[14])));//
     strcat(strInstrTmp," ");
      {
       unsigned char *OPCODE;
       OPCODE=&(MyOneInstruction.InstrString[21]); 
       while(*OPCODE!=0)
        {
         strcat(strInstrTmp,(char *)OPCODE);
         strcat(strInstrTmp,",");
         OPCODE+=strlen((char *)OPCODE)+1;
         }            
       strInstrTmp[((strlen(strInstrTmp)>0)?strlen(strInstrTmp)-1:0)] = 0;  
       }
     
     CString tmpStr = strInstrTmp;
     pList->AddTail(tmpStr);
         
     InputInstrIndex+=CMd_51[DAsmlnCodeBlk[InputInstrIndex]].ByteNum;
     InstrIndex++;
     } //while
                                      
   
   if(InputInstrIndex>DAsmInCodeBlkLen)  {
   	   usNextAddr = (unsigned short)((DAsmStartAddr+usTmp)%(AddrMax+1L));
   	   if ( !pList->IsEmpty() ) {
   	   		pList->RemoveTail();
   	   }
       return -4; 
   }
   //*DAsmInstrNum=InstrIndex;
   //*DAsmBytesNum=InputInstrIndex;
   
   if((unsigned long)InstrIndex>0x100) 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
  }

  
#endif
