/***************************************************************************
**
** File name : dadob.h
** Author:John Zhou
** Description:
**    class definition of dad class
**
**
**    Finished date: 1996.9
**                                            
**
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

#ifndef _DADOB_H
#define _DADOB_H

#include "stdafx.h"        
#include "abitype.h"

class COpSet;

/********************** for class CDADValue *******************************/
//for value convert (str to digit or digit to str)

//*********only for HEX***********

class CDADValue : public CByteArray
{
//member
protected:
	BYTE m_bWidth;  
	CString m_strValue;         
public:
	void Clear() {
		m_bWidth = 0;
		RemoveAll();
		m_strValue = "";
	};
//virtual operation
protected:
	virtual BOOL StrToValue();
	virtual BOOL StrToValueDec();
	virtual BOOL ValueToStr();                     
	virtual BOOL ValueToStrDec();                     
//operation	
public:	
	BYTE GetWidth() { return m_bWidth; };		
	const CString& GetStr() { 
		ValueToStr();
		return m_strValue; 
	};               
	const CString& GetStrDec() { 
		ValueToStrDec();
		return m_strValue; 
	}; 

//construct           
public:
	CDADValue() {
		m_bWidth = 0;
		m_strValue = "";
	};	
	                                    
	
//operation
public:	
	BYTE operator<<(const CString& str) {
		Clear();
		m_strValue = str;
		StrToValue();
		return m_bWidth;
	};
	
	BYTE InputDecStr(const CString& str) {
		Clear();
		m_strValue = str;
		StrToValueDec();	
		return m_bWidth;
	};             
	                    
	//return 0, refers it can't be converted	                    
	BYTE operator<<(const char* str) {
		Clear();
		m_strValue = str;
		StrToValue();
		return m_bWidth;
	};            
	
	//when you call this function,you must use convert (BYTE)
	void SetByte(BYTE bValue) {
		Clear();
		Add(bValue); 
		m_bWidth++;
	};
	
	//when you call this function,you must use convert (BYTE)
	//continue add
	void AddByte(BYTE bValue) {
		Add(bValue);
		m_bWidth++;
	};
	
	//when you call this function,you must use convert (WORD)
	void SetWord(WORD wValue);
	//continue add
	void AddWord(WORD wValue);
    
    //when you call this function,you must use convert (DWORD)
    void SetDWord(DWORD dwValue);
	//when you call this function,you must use convert (DWORD)	                                  
	//continue add	                                  
	void AddDWord(DWORD dwValue);
	//set 24bit width datum
	void Set24(DWORD dwValue);
	void Add24(DWORD dwValue);
	
	BYTE GetByte(int i=0) {
		if ( i >= GetSize()) return 0;
		return CByteArray::GetAt(i);
	};                 
	
	WORD GetWord() {               
		DWORD pdwTmp[7];
		pdwTmp[6] = 0;
		for (int i=0; i<GetSize() && i<2; i++) {
			pdwTmp[i] = GetAt(i);
			pdwTmp[6] += pdwTmp[i]<<(8*i);
		}               
	
	return (WORD)pdwTmp[6];						   
	};                             
	
	DWORD Get24();
	DWORD GetDWord();             
	
	void SetValue(CDADValue& val){
		Clear();
		for (int i=0; i<val.GetSize(); i++)
			AddByte(val.GetByte(i));
	};
	void AddValue(CDADValue& val){
		for (int i=0; i<val.GetSize(); i++)
			AddByte(val.GetByte(i));
	};

 } ;
/********************** for class C251DADSym *******************************/
class CDADAddr : public CObject
{ 
//member
public:
	BYTE m_bAttribute;
	DWORD m_dwAddr; 
	enum { UNDEFINED = 0xff };
//operator	
	void operator=(const CDADAddr& addr) {
		m_bAttribute = addr.m_bAttribute;
		m_dwAddr=addr.m_dwAddr;
	};
	
	void operator=(DWORD dwAddr) {
		m_bAttribute = 0;
		m_dwAddr=dwAddr;
	};
	
	void Add(BYTE bAttribute,DWORD dwAddr) {
		m_bAttribute = bAttribute;
		m_dwAddr = dwAddr;	
	}
//construct
public:
	CDADAddr() {
		m_bAttribute = 0;
		m_dwAddr = 0;
	};
			
	CDADAddr(BYTE bAttribute,DWORD dwAddr) {
		m_bAttribute = bAttribute;
		m_dwAddr = dwAddr;
	};
	
	CDADAddr(DWORD dwAddr) {
		m_bAttribute = 0;
		m_dwAddr = dwAddr;
	};      
	
	CDADAddr(const CDADAddr& addr) {
		m_bAttribute = addr.m_bAttribute;
		m_dwAddr = addr.m_dwAddr;
	};
 };
 
/********************** for class CDADAddress *******************************/
//deal with HEX DAD address
class CDADAddress : public CDADValue
{                
//member
public:
	BYTE m_bAttribute;
//virtual operation
protected:
	virtual CString AddPrefix() { return ""; };
	virtual BOOL GetPrefix(CString& str) { 
		if(0 == str.GetLength()) return FALSE;
		return ( str[0] >= '0' && str[0] <= '9' ); 
	};
public:	
	//if is same 64k bank range
	virtual BOOL IsSameSeg(CDADAddress& tmpAddr) {
		return ((GetDWord()&0xffff0000) == (tmpAddr.GetDWord()&0xffff0000));
	};	
	//minus
	virtual void operator-(CDADAddress& tmpAddr) {
		DWORD dw1,dw2,dw3;
		dw1 = GetDWord();  dw2 = tmpAddr.GetDWord();
		dw3 = (long)dw1 - dw2;
		Clear();
		AddDWord(dw3);
	};
	//add
	virtual void operator+(CDADAddress& tmpAddr) {
		DWORD dw1,dw2,dw3;
		dw1 = GetDWord();  dw2 = tmpAddr.GetDWord();
		dw3 = dw1 + dw2;
		Clear();      
		AddDWord(dw3);
	};	
	
    virtual CDADAddr StrToAddr(CString) { CDADAddr tmp; return tmp; };
    virtual CDADAddr StrToAddr(char*) {  CDADAddr tmp; return tmp; }; 
public:	      
	CString GetStr();
	BYTE GetAttribute() { return m_bAttribute; };
	BYTE operator<<(CString str);
	//return 0, refers it can't be converted	                    
	BYTE operator<<(char* pCh);
	//when you call this function,you must use convert (BYTE)
	void SetByte(BYTE bAttribute,BYTE bValue);
	//when you call this function,you must use convert (BYTE)
	//continue add
	void AddByte(BYTE bValue);
	//when you call this function,you must use convert (WORD)
	void SetWord(BYTE bAttribute,WORD wValue);
	//when you call this function,you must use convert (WORD)
	//continue add
	void AddWord(WORD wValue);
    //when you call this function,you must use convert (DWORD)	
	void SetDWord(BYTE bAttribute,DWORD dwValue);
	//when you call this function,you must use convert (DWORD)	
	//continue add
	void AddDWord(DWORD dwValue);
	void Set24(BYTE bAttribute,DWORD dwValue);
		
};

/********************** for class CInstruction *******************************/
//deal with assemble instruction
class CInstruction : public CStringArray
{ 
//member
protected:
	CString m_strTotal;
	char m_cDevide1,m_cDevide2;
	//enum { MAXOPERATORS = 10, MAXCHAR = 256 };
//operator
protected:
	int Add(CString str) {
		if(str[0] != '#') str.MakeUpper();
		return CStringArray::Add(str);
	};
	virtual void Devide();	
public:
	void operator=(const CString&);
	void operator=(const char*);
	
	WORD operator<<(const CString& str) {
		*this=(str);
		return (WORD)(GetSize());	
	};                   
	
	WORD operator<<(const char* str) {
		*this=(str);
		return (WORD)(GetSize());	
	};
	
	void Clear() {      
		m_strTotal = ""; 
		RemoveAll();             
	};
	
	CString operator[](int i) {
		ASSERT( i < GetSize() );
		return GetAt(i);
	};     
	                      
	const CString& GetStr() {
		m_strTotal = "";
		for (int i=0; i<GetSize(); i++) {
			m_strTotal += GetAt(i);      
			if (i != GetSize()-1 && i != 0)
				m_strTotal += ",";
			if (0 == i && i != GetSize()-1)	
				m_strTotal += " ";
		}	
		return m_strTotal;	
	};               
	
	void operator+=(const CString& str) {
		m_strTotal += str;
		Add(str);
	};
	
	void operator+=(const char* str) {
		CString strTmp = str;
		m_strTotal += strTmp;
		Add(strTmp);
	}                 

//construct
public:
	CInstruction() {
		m_strTotal = "";       
		m_cDevide1 = ' ';
		m_cDevide2 = ',';
	};	
 };      

/********************** for class CNextIceAddr *******************************/
//to guess the next address after this instruction executing for emulation server
class CNextIceAddr : public CObject
{   
//member
protected:
	DWORD m_dwValue;
	BYTE m_bAttribute;
//operator             
public:
	virtual ADDR GetNextIceAddr() {
		ADDR tmpAddr;
		tmpAddr.addrType = m_bAttribute;
		tmpAddr.addr = m_dwValue;
		return tmpAddr;
	};
	void SetValue(DWORD dwValue)	{
		m_dwValue = dwValue;
	};
	void SetValue(DWORD dwValue,BYTE bAttribute)	{
		m_dwValue = dwValue;   
		m_bAttribute = bAttribute;
	};
	void SetValue(ADDR addr)	{
		m_dwValue = addr.addr;
	    m_bAttribute = (BYTE)addr.addrType;
	};
//construct
public:
	CNextIceAddr(DWORD dwValue) {
		m_dwValue = dwValue;
	};	
	CNextIceAddr() {
		m_dwValue = 0;
	};
	CNextIceAddr(ADDR addr) {
	    m_dwValue = addr.addr;
	    m_bAttribute = (BYTE)addr.addrType;
	};
	CNextIceAddr(DWORD dwValue,BYTE bAttribute)	{
		m_dwValue = dwValue;   
		m_bAttribute = bAttribute;
	};	

 };

/********************** for class CAnalyseInstruction *******************************/
//opcode total set
class CAnalyseInstruction : public CObject
{ 
//member
public:
	CInstruction m_Instruction;
	CObArray m_OpSetSet,m_OpDealSet;
	CDWordArray m_CodeSet;
	BYTE m_bNum;
	BYTE m_bNeedNum;
	BOOL m_isAsm;
	int m_nErrCode;
	int m_nCpuMode;
	BOOL m_isDirtyResult; //97.6.26
	//for save next address if have
	CObArray m_NextAddrSet; 
	int m_nInstructionType;
protected:
	CString m_strCodeHead;
	
public:
	enum { ERR_INVALID = 2000};	
	enum { TYPE_NORMAL,TYPE_JUMP,TYPE_MAYBE_JUMP};	
//operation	
public:             
	void SetCodeHeadStr(CString str) { m_strCodeHead = str; }; 
	void SetCodeHeadStr(char* str) { m_strCodeHead = str; }; 
	int GetErrCode() { 
		return m_nErrCode;
	};   
	BYTE GetNeedNum() { 
		return (BYTE)(m_bNeedNum - m_bNum); 
	};
	
	BOOL IsAsm() { return m_isAsm; };
	CString GetCodeStr();
	DWORD GetLeftCodeLen();
	void Clear();
	int GetInstructionType() { return m_nInstructionType; };
	
	void operator<<(COpSet* opSet) {
		m_OpSetSet.Add((CObject*)opSet);
	};                         
	
	COpSet* operator>>(int i) {
		return (COpSet*)m_OpSetSet[i];
	};
		
	DWORD GetCode(int i) {
		ASSERT(i<m_CodeSet.GetSize());
		return m_CodeSet[i];
	};
	
	void AddCode(DWORD dwCode){
		m_CodeSet.Add(dwCode);	
		m_bNum++;      
		m_isAsm = FALSE;
	};
	
	void SetCode(DWORD dwCode){
		m_CodeSet.RemoveAll();
		m_CodeSet.Add(dwCode);	
		m_bNum = 1;   
		m_isAsm = FALSE;
	};          
	
	CInstruction& operator()() {
		return m_Instruction;
	};  
	
	void operator = (char* ucStr) {
		m_Instruction = ucStr;
		m_isAsm = TRUE;
	};               
	
	void operator = (CString str) {
		m_Instruction = str;
		m_isAsm = TRUE;
	};                   

//virtual operation
public:
	virtual BOOL Do(CDADAddress* pCurrentAddr);	
	
//construct & destruct
public:
	CAnalyseInstruction() {
		m_Instruction = "";
		m_bNum = 0;     
		m_bNeedNum = 0;         
		m_isAsm = FALSE;  
		m_strCodeHead = "";
		m_isDirtyResult = FALSE;
	};	                   
	virtual ~CAnalyseInstruction() {
		Clear();
	};
		
 };


/********************** for class CBaseDADSFRByte *******************************/
//you must make the construct of derived class to set the m_nCpuID
class CBaseDADSFRByte : public CObject 
{                           
//member 
public:
	DWORD m_dwCpuID;

//virtual operation
protected:
	virtual BOOL SelectByAddr() = 0;
	virtual BOOL SelectByStr() = 0;
public:
	virtual	const CDADAddr& operator << (const CString& str) = 0;
	virtual const CDADAddr& operator << (const char* str) = 0;
	virtual const CString& operator << (CDADAddr& addr) = 0;
                     
 } ;
 
/********************** for class CBaseDADSFRBit *******************************/
class CBaseDADSFRBit : public CObject 
{                           
//member 
public:
	DWORD m_dwCpuID;         
	BYTE m_bBit;

//virtual operation
protected:
	virtual BOOL SelectByAddr() = 0;
	virtual BOOL SelectByStr() = 0;           
public:
	const virtual CDADAddr& Str2Addr51(const CString& str) = 0;
	const virtual CDADAddr& Str2Addr251(const CString& str,BYTE& bit) = 0;
	const virtual CString& Addr2Str51(CDADAddr& addr) = 0;	          
	const virtual CString& Addr2Str251(CDADAddr& addr,BYTE bit) = 0;	          
                     
 } ;
 
/********************** for class CBaseDADSym *******************************/
//for symbol
class CBaseDADSym : public CObject 
{                           
//virtual operation
protected:
	virtual BOOL SelectByAddr() = 0;
	virtual BOOL SelectByStr() = 0;                  
public:	
	const virtual CDADAddr& operator << (const CString& str) = 0;
	const virtual CDADAddr& operator << (const char* str) = 0;
	const virtual CString& operator << (CDADAddr& addr) = 0;
	       
 } ;
 
/********************** for class CBaseDADConstSym *******************************/
//for const symbol
class CBaseDADConstSym : public CObject 
{
//virtual operation
protected:
	virtual BOOL SelectByIndex() = 0;
	virtual BOOL SelectByStr() = 0;                     
public:
	virtual WORD operator << (const CString& str)	= 0;
	virtual WORD operator << (const char* str) = 0;
	virtual const CString& operator << (WORD nIndex) = 0;
		
 } ;

/********************** for class CDADDatum *******************************/
//deal with HEX DAD DATUM
class CDADDatum : public CDADValue
{
//operation
protected:
	virtual CString AddPrefix() { return "#"; };
	virtual BOOL GetPrefix(CString& str) { 
		if ('#' == str[0]) {                   
			if (1 == str.GetLength()) return FALSE;
			str = str.Right(str.GetLength()-1);
			return TRUE; 
		}	
		else return FALSE;
	};
public:	
	BYTE operator<<(CString str) {
		//get rid of last 'h'
		if( str.GetLength() >0 &&
			'H' ==  toupper(str[str.GetLength()-1]) ) {
			str = str.Left(str.GetLength()-1);
			if (0 == str.GetLength()) {
				Clear();
				return 0;
			}
		}                 
		if(!GetPrefix(str)) {
			Clear();
			return 0;
		}
		return *(CDADValue*)(this)<<str;
	};             
	                    
	//return 0, refers it can't be converted	                    
	BYTE operator<<(char* pCh) {
		CString str = pCh;
		if( str.GetLength() >0 &&
			'H' ==  toupper(str[str.GetLength()-1]) ) {
			str = str.Left(str.GetLength()-1);
		}
		if(!GetPrefix(str)) {
			Clear();
			return 0;
		}
		return *(CDADValue*)(this)<<str;
	};  
	CString GetStr() {
		//add last 'h'   
		//if ("" == CDADValue::GetStr()) return "";
		return AddPrefix() + CDADValue::GetStr()+'H';
	}           
                     
 }; 
 
/********************** for class CBaseDADKey *******************************/
//for instruction table
class CBaseDADKey : public CObject 
{                                 
//member
public:
	int m_nErrCode;
	enum {ERR_NEED_MORE_BYTE = 2050};	
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&) = 0;
	virtual	BOOL SelectByInstr(CAnalyseInstruction&) = 0;
//operator
public:
	int GetErrCode() { return m_nErrCode; }	
                     
 } ;        

/********************** for class CDADDOLLARS *******************************/
//for operator '$'
class CDADDOLLARS : public CInstruction
{ 
//member
protected:
	CString m_strTotal;
public:
	char m_cOperator;
	CDADValue m_Offset;  
//operator
public:
	void Clear() {
		CInstruction::Clear();
	};	
	BOOL operator<<(CString str); 
//virtual operator	
 };


/********************** for class COpDeal *******************************/
//base object to deal with definit operator code
class COpDeal : public CDADValue
{
//member
protected:
	int m_nErrCode;
 
//virtual operate  
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,
					CDADAddress* pCurrentAddr) 
				 = 0;
//operator
public:
	int GetErrCode() { return m_nErrCode; };	
					 
 };

/********************** for class COpDealWriteDigit *******************************/
//base object to deal with write several byte to the output buffer
//the high byte is in the first place
class COpDealWriteDigit : public COpDeal
{                                            
//virtual operator
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress*) {
		//for 51 high byte first
		for (int i=GetWidth()-1; i>=0; i--) 
			Baby.AddCode(GetByte(i));                     
		return TRUE;	
		
	}; 
	
 };
 
/********************** for class COpDealReadDigit *******************************/
//base object to deal with write several byte to the output buffer
//the high byte is in the first place
class COpDealReadDigit : public COpDeal
{                          
//member
protected:
	BYTE m_bNum;
//construction
public:
	COpDealReadDigit(CAnalyseInstruction& Baby,BYTE bLoc,BYTE bNum) {
		for ( int j=bLoc; j<bLoc+bNum; j++ ) {
			AddByte((BYTE)(Baby.GetCode(j)));				
		}
	};		                  
//virtual operator
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* ) {
		Baby.m_Instruction += GetStr();
		return TRUE;	
		
	}; 
	
 };

/********************** for class COpDealConstDigit *******************************/
//base object to deal with write several byte to the output buffer
//the high byte is in the first place
class COpDealConstInstr : public COpDealReadDigit
{   
//member
protected:
	CString m_Str;                       
//construction
public:
	COpDealConstInstr(CAnalyseInstruction& Baby,char* strInstr) : COpDealReadDigit(Baby,0,0) {
		 m_Str = strInstr;
	};		                  
	COpDealConstInstr(CAnalyseInstruction& Baby,const CString& strInstr) : COpDealReadDigit(Baby,0,0) {
		 m_Str = strInstr;
	};		                  
//virtual operator
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* ) {
		Baby.m_Instruction += m_Str;
		return TRUE;	
	}; 
	
 };


/********************** for class COpSet *******************************/
//opcode set
class COpSet : public CByteArray
{           
//member
public:
	CDADValue m_Value;
//operation
public:
	void operator+=(BYTE ucOpcode) {
		Add(ucOpcode);	
	};
	
	void Clear() { 
		RemoveAll();  
		m_Value.Clear();
	};
	
	//for search
	BOOL operator()(BYTE ucOpcode) {
	    for(int i=0;i<GetSize();i++) 
	    	if(ucOpcode == GetAt(i)) return TRUE;
	    return FALSE;	
	};

 };

/********************** for class CBaseOpCodeAnalyse *******************************/
//Get opcode total set
class CBaseOpCodeAnalyse : public CObject
{             
//member 
protected:
	CBaseDADSFRByte* m_pSFRByte;
	CBaseDADSFRBit* m_pSFRBit;
	CBaseDADSym* m_pSym;  
	CBaseDADConstSym* m_pConstSym;
	CDADAddress* m_pAddress;
	CDADDatum* m_pDatum;
	CDADDOLLARS* m_pDollars;      
	int m_nErrCode;
//virtual operator
public:
	virtual BOOL Do(CAnalyseInstruction&,CDADAddress&)=0;	
//operator
public:
	int GetErrCode() { return m_nErrCode; };	
	
 };
 
/********************** for class CBaseDADMem *******************************/
class CBaseDADMem : public CObject 
{ 
//member
protected:
	CDADAddr m_curAddr;
	DWORD m_dwMax;        
	int m_nErrCode;
public:
	enum { ERR_MEM_WRITE = 2100, ERR_MEM_READ , ERR_ADDR_INVALID};	
//construct	& destruct
public:
	CBaseDADMem() {
	m_dwMax = 0xffff;
	};                
	virtual ~CBaseDADMem() { return;};
//operator
public:                      
	int GetErrCode() { return m_nErrCode; };
	BOOL SetAddr(CDADAddr& addr) {
		m_curAddr = addr;
		return TRUE;
	};
	BOOL SetAddr(ADDR addr) {
		m_curAddr.Add((BYTE)addr.addrType,(DWORD)addr.addr);
		return TRUE;
	};	               
	BOOL SetAddr(DWORD dwAddr) {
		m_curAddr.Add(m_curAddr.m_bAttribute,dwAddr);
		return TRUE;
	};
	void SetMaxAddr(DWORD dwMax) {
		m_dwMax = dwMax;	
	};                  
	CDADAddr GetAddr() {
		return m_curAddr;
	};
	void GetAddr(ADDR& addr) {
		addr.addrType = m_curAddr.m_bAttribute;
		addr.addr = m_curAddr.m_dwAddr;
	}
	DWORD GetMaxAddr() {          
		return m_dwMax;
	};                                     
	virtual void operator++() {
		if (++m_curAddr.m_dwAddr > m_dwMax) m_curAddr.m_dwAddr = 0;
	};
	virtual void operator--() {
		if (--m_curAddr.m_dwAddr == 0xffffffff) m_curAddr.m_dwAddr = m_dwMax;
	};
	virtual void operator+(DWORD dwTmp) {
		m_curAddr.m_dwAddr += dwTmp;
		while (m_curAddr.m_dwAddr > m_dwMax) m_curAddr.m_dwAddr -= m_dwMax;
	};
	virtual void operator-(DWORD dwTmp) {  
		m_curAddr.m_dwAddr -= dwTmp;
		if (m_curAddr.m_dwAddr > m_dwMax) m_curAddr.m_dwAddr -= m_dwMax;
	};
	virtual BOOL operator<(ADDR addr) {  
		return (m_curAddr.m_dwAddr<addr.addr);
	};
	virtual BOOL operator<=(ADDR addr) {  
		return (m_curAddr.m_dwAddr<=addr.addr);
	};                              
	virtual BOOL operator>(ADDR addr) {  
		return (m_curAddr.m_dwAddr>addr.addr);
	};
	virtual BOOL operator>=(ADDR addr) {  
		return (m_curAddr.m_dwAddr>=addr.addr);
	};		                        
	virtual BOOL operator==(ADDR addr) {  
		return (m_curAddr.m_dwAddr==addr.addr);
	};

//virtual operator
public: 
	virtual BOOL WriteBytes(BYTE*,BYTE bNum=1) = 0;
	virtual BOOL ReadByte(BYTE&) = 0;  
	virtual BOOL UpdateBuffer() = 0;                                                                
};
                                                              
/********************** for class CBaseDAD *******************************/
class CBaseDAD : public CObject 
{                 
//member                             
public:
	CAnalyseInstruction Baby;
    int m_nError;
    int m_nDetailError;
protected:    
    int m_nCpuMode;
public:    
    CDADAddress m_CurrentAddr;
        
    enum { ERR_NO = 2150,ERR_PRE,ERR_AFTER,ERR_PROCESS};

//virtual operation
protected:                                   
	virtual BOOL AfterDisasm(CBaseDADMem& DADMem) { 
		//prepare next addr
		DWORD dwLeftLen = Baby.GetLeftCodeLen();
		if (dwLeftLen != 0) {
			DADMem-dwLeftLen;
		}             
		
		//make next address (maybe) 
		CNextIceAddr* pNextAddr = new CNextIceAddr(((DADMem.GetAddr()).m_dwAddr));
		Baby.m_NextAddrSet.Add((CObject*)pNextAddr);
		return TRUE; 
	};
	virtual BOOL PreAsm(CBaseDADMem&) { return TRUE; };
	virtual BOOL PreDisasm(CBaseDADMem& mem) { 
		if (0 == Baby.m_bNum) {
			BYTE bTmp;
			if (!mem.ReadByte(bTmp)) {
				m_nError = ERR_PRE;
				m_nDetailError = mem.GetErrCode();
				return FALSE;
			}                      
			Baby.AddCode((DWORD)bTmp);
		}
		return TRUE; 
	};
	virtual BOOL AfterAsm(CBaseDADMem&) { 
		return TRUE; 
	};
	virtual BOOL ProcessAsm(CBaseDADMem&) = 0;
	virtual BOOL ProcessDisasm(CBaseDADMem&) = 0;
//operation	
public: 
	BOOL Asm(CBaseDADMem&);
	BOOL Das(CBaseDADMem&);
	int GetErrCode() { return m_nError; };
	int GetDetailErrCode() { return m_nDetailError; };
	BYTE GetUsedDasByte() {
		return Baby.m_bNum;
	};	                   
	void SetCpuMode(int nCpuMode) { 
		m_nCpuMode = nCpuMode; 
		Baby.m_nCpuMode = nCpuMode; 
	};    	
	

 };             
 
 
#endif                                                                   

/***********************  end of file **********************************/