/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

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

#ifndef _DAD196_H
#define _DAD196_H

#include "stdafx.h"             
#include "dadob.h"
//#include "tbl196.h"       
#include "abiextfn.h"
#include "regsvr.h"
#include "cpusvr.h"    
#include "address.h"
                        
//define for instruction table
#define NONE 0
#define ADDR16 2
#define DATA8 3
#define DATA16 4
#define INDIRECT 5
#define INDIRECT_PLUS 6
#define INDEX 7
#define INDEX_LONG 8
#define ADDRI 9
#define ADDRX16 10
#define BITOFFSET 15
//defined for internal datum type
#define BYTE_REG 11
#define WORD_REG 12
#define DWORD_REG 14

//extern function
extern BOOL AdrCheckAddrRange(ADDR addr );
//extern BOOL AdrCheckAddrRange(ADDRESS addr);

/********************** for class CBaseDADSFRByte *******************************/
class C196DADSFRByte : public CBaseDADSFRByte
{
//member            
public:
	enum {UNDEFINED = 0xff };
	static int m_nCurWindow;
	int m_nLen;
	int m_nAttr; 
protected:
	CString m_strName;
	CDADAddr m_addr;
		 
//construct                  
public:
	C196DADSFRByte() {	
		m_strName = "";	
		m_nLen = m_nAttr = 0;
		m_addr.Add(UNDEFINED,0);
	};                 
//virtual operation
protected:
	virtual BOOL SelectByAddr();
	virtual BOOL SelectByStr();
//operation
public:           
	void SetOption(int nLen,int nAttr) {
		m_nLen = nLen;
		m_nAttr = nAttr;	
	};

	CString& GetSfrName() { 
		return m_strName;
	};
	
	const CDADAddr& operator << (const CString& str)	{
		m_strName = str;
		SelectByStr();
		return m_addr; 
	};	                
	
	const CDADAddr& operator << (const char* str)	{
		m_strName = str;
		SelectByStr();
		return m_addr; 
	};	                
	
	const CString& operator << (CDADAddr& addr)	{
		m_addr = addr;
		SelectByAddr();
		return m_strName;
	};	                
	
 };
 

/********************** for class C196DADSym *******************************/
class C196DADSym : public CBaseDADSym
{                
//construct & destruct 
public:
	C196DADSym();
//member                    
protected:          
	CString m_strSym;    
	CDADAddr m_addr;         
public:	
	enum { UNDEFINED = 0xff};
	static BOOL m_isSymbolic;
protected:
	char m_cHead;	                        
//virtual operation
public:
	virtual BOOL SelectByAddr();
	virtual BOOL SelectByStr();                     
//operation             
    const CDADAddr& operator << (const CString& str) {
		m_strSym = str;
		SelectByStr();
		return m_addr; 
	};	                
	
	const CDADAddr& operator << (const char* str) {
		m_strSym = str;
		SelectByStr();
		return m_addr; 
	};	                
	
	const CString& operator << (CDADAddr& addr)	{
		m_addr = addr;
		SelectByAddr();
		return m_strSym;
	};	 
	
	const CString& operator << (CDADAddress& addr)	{
		m_addr.Add(addr.m_bAttribute,addr.GetDWord());
		SelectByAddr();
		return m_strSym;
	};               
                                     
 };                                  
 
/********************** for class C196DADDatumAnalyse *******************************/
//deal with HEX DAD datum                
//not use
class C196DADDAtumAnalyse : public CDADDatum
{
//vitual operator
protected:
	virtual CString AddPrefix() {
		CString strTmp = '#';
		return strTmp;
	};
		
	virtual BOOL GetPrefix(CString& strTmp) { 
		if ( 0 == strTmp.GetLength() ) return FALSE;
		return ('#' == strTmp[0]);
	};
                     
 };                                                                                   

/********************** for class C196DADAddrAnalyse *******************************/
//deal with HEX DAD address
class C196DADAddrAnalyse : public CDADAddress
{                                  
//member
public:
	enum { UNDEFINED = 0xff };	
//vitual operator
protected:
	virtual CString AddPrefix();
	virtual BOOL GetPrefix(CString& strTmp);
	public:	
	
	virtual CDADAddr StrToAddr(CString str) { 
		CDADAddr tmpAddr;
		if ( 0 == (*(CDADAddress*)(this)<<(str)) ) 
			tmpAddr.m_bAttribute = UNDEFINED;
		else 	
		    tmpAddr.m_bAttribute = m_bAttribute;
		tmpAddr.m_dwAddr = (DWORD)(GetWord());
		return tmpAddr;    
	};
	//return 0, refers it can't be converted	                    
	virtual CDADAddr StrToAddr(char* pCh) {
		CString str = pCh;
		CDADAddr tmpAddr;
		if ( 0 == (*(CDADAddress*)(this)<<(str)) ) 
			tmpAddr.m_bAttribute = UNDEFINED;
		else 	
		    tmpAddr.m_bAttribute = m_bAttribute;
		tmpAddr.m_dwAddr =(DWORD)(GetWord());
		return tmpAddr;    
	}; 
	
	//minus
	virtual void operator-(CDADAddress& tmpAddr) {
		WORD w1,w2,w3;
		w1 = GetWord();  w2 = tmpAddr.GetWord();
		w3 = w1 - w2;
		BYTE bAttr = GetAttribute();
		Clear();
		SetWord(bAttr,w3);
	};
	//add
	virtual void operator+(CDADAddress& tmpAddr) {
		WORD w1,w2,w3;
		w1 = GetWord();  w2 = tmpAddr.GetWord();
		w3 = w1 + w2;     
		BYTE bAttr = GetAttribute();
		Clear();
		SetWord(bAttr,w3);		
	};	
	
 };

/********************** for class C196DADRegIndirect *******************************/ 
//to deal with the 196 address type indirect ([30]+)
class C196DADRegIndirect : public CObject
{  
//member
public:	
	enum { UNDEFINED = 0xff};
protected:
	C196DADSFRByte m_sfr;
	C196DADAddrAnalyse m_addr;              
	C196DADSym m_sym;
//vitual operator
public:
	virtual const CDADAddr StrToAddr(CString str);
	//return 0, refers it can't be converted	                    
	virtual const CDADAddr StrToAddr(char* pCh) {
		CString str = pCh; 
		return StrToAddr(str);
	};                                                          
	virtual CString AddrToStr(CDADAddr addr);
//operator
public:                  
	void SetOption(int nLen,int nAttr) {
		m_sfr.SetOption(nLen,nAttr);
	};
		
 };    

/********************** for class C196DADRegIndex *******************************/ 
//to deal with the 196 address type index(20[30])
class C196DADRegIndex : public CObject
{  
//member
public:	
	enum { UNDEFINED = 0xff};
	CDADAddr m_regAddr;
	CDADAddr m_baseAddr;
protected:
	C196DADSFRByte m_sfr;
	C196DADAddrAnalyse m_addr;   
	C196DADSym m_sym;    
//vitual operator
public:
	virtual const CDADAddr& StrToAddr(CString str);
	virtual const CDADAddr& StrToAddr(char* pCh) {
		CString str = pCh; 
		return StrToAddr(str);
	};                                                          
	
	virtual CString AddrToStr(CDADAddr addrReg,CDADAddr addrBase );
//operator
public:                  
	void SetOption(int nLen,int nAttr) {    
		m_sfr.SetOption(nLen,nAttr);
	};
	
 };    

/********************** for class COpDeal196ASMAddrPg *******************************/ 
//to deal with 
class COpDeal196ASMAddrPg : public COpDealWriteDigit
{       
//member
public:
	enum { ERR_ASM_ADDRPG = 4050 };
//virtual class
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr);
 }; 

/********************** for class COpDeal196ASMAddrPg11 *******************************/ 
//to deal with 
class COpDeal196ASMAddrPg11 : public COpDealWriteDigit
{       
//member
public:
	enum { ERR_ASM_ADDRPG11 = 4350 };
//virtual class
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr);
 }; 

/********************** for class COpDeal196ASMAddr16 *******************************/ 
//to deal with 
class COpDeal196ASMAddr16 : public COpDealWriteDigit
{       
//member
public:
	enum { ERR_ASM_ADDR16 = 4150 };
//virtual class
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr);
 }; 
/********************** for class COpDeal196DASAddr16 *******************************/ 
//to deal with 
class COpDeal196DASAddr16 : public COpDealReadDigit
{                                 
//member
protected:
	BYTE m_bLen;//instruction len
//construct
public:
	COpDeal196DASAddr16(CAnalyseInstruction& Baby,BYTE bLoc,BYTE bNum,BYTE bLen)
					   :COpDealReadDigit(Baby,bLoc,bNum) {
		ASSERT(2 == bNum);
		m_bLen = bLen;
	};
//member
public:
	enum { ERR_DAS_ADDR16 = 4200 };
//virtual class
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr);
 }; 
 
/********************** for class COpDeal196DASAddrPg *******************************/ 
//to deal with 
class COpDeal196DASAddrPg : public COpDealReadDigit
{        
//member                                         
protected:
	BYTE m_bLen;
//construct
public:
	COpDeal196DASAddrPg(CAnalyseInstruction& Baby,BYTE bLen,BYTE bLoc,BYTE bNum)
					  :	COpDealReadDigit(Baby,bLoc,bNum) {
		ASSERT(1 == bNum);
		m_bLen = bLen;
	};
//member
public:
	enum { ERR_DAS_ADDRPg = 4250 };
//virtual class
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr);
 }; 

/********************** for class COpDeal196DASAddrPg11 *******************************/ 
//to deal with 
class COpDeal196DASAddrPg11 : public COpDealReadDigit
{        
//member                                         
protected:
	BYTE m_bLen;//instruction len
	BYTE m_bFirst;//save high three bits in the previous byte
//construct
public:
	COpDeal196DASAddrPg11(CAnalyseInstruction& Baby,BYTE bLen,BYTE bFirst,BYTE bLoc,BYTE bNum)
					  :	COpDealReadDigit(Baby,bLoc,bNum) {
		ASSERT(1 == bNum);
		m_bLen = bLen;
		m_bFirst = bFirst;
	};
//member
public:
	enum { ERR_DAS_ADDRPg = 4350 };
//virtual class
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr);
 }; 
                                        
/********************** for class COpDeal196DASAddrI *******************************/ 
//to deal with 196 internal data(r area) 00 - ff
class COpDeal196DASAddrI : public COpDealReadDigit
{
//member
public:
	enum { ERR_DAS_ADDRDATUM =4350 };
protected:	
    int m_nLen;
	int m_nAttr;     
//construct
public:
	COpDeal196DASAddrI(CAnalyseInstruction& Baby,int nLen,int nAttr,BYTE bLoc,BYTE bNum)
						  : COpDealReadDigit(Baby,bLoc,bNum) {
		m_nLen = nLen;
		m_nAttr = nAttr;				  
	};
//virtual class
public:
	virtual BOOL Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr);
 }; 
 
typedef struct {
    char *pIntruction;    
    BYTE bCode; //base code  
    BYTE bWidth;//1-2 bytes ; 10 -> LDBZE,LDBSE
    BYTE bType; //1 - operators;2 - 2 operators; 3 - 3 operators
} CMDMOSTTBL;    //defined for 196 for most insruction like mov reg,reg
     
/********************** for class C196DADKeyMost  *******************************/
//eg:mov reg,reg
//for instruction table
class C196DADKeyMost  : public CBaseDADKey 
{                                 
//member
protected:
	static CMDMOSTTBL m_Tbl[];
	static int MAX_TABLE_NUM; 
public:
    enum { ERR_NOTHING = 7000};
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);
                     
 } ;
  
typedef struct {
    char *pIntruction;    
    BYTE bCode;   
} CMDMISCTBL;    //defined for 196 for most insruction like mov reg,reg

typedef struct {
    char *pIntruction;    
    BYTE bCode; //base code  
    BYTE bOp0;
    BYTE bOp1;
    BYTE bWidth0;
    BYTE bWidth1;
} CMDMOSTTBL2;    //defined for 196 for most insruction like mov reg,reg
     

/********************** for class C196DADKeyMost2  *******************************/
//eg:xch,bmov,cmpl,bmovi
//for instruction table
class C196DADKeyMost2  : public CBaseDADKey 
{                                 
//member
protected:
	static CMDMOSTTBL2 m_Tbl[];
	static int MAX_TABLE_NUM; 
public:
    enum { ERR_NOTHING = 7000,ERR_INVALID_REG};
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);
                     
 } ;

/********************** for class C196DADKeyAddrPg11  *******************************/
//eg:mov reg,reg
//for instruction table
class C196DADKeyAddrPg11 : public CBaseDADKey 
{                                 
//member
public:
    enum { ERR_NOTHING = 7500};
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);
                     
 } ;

/********************** for class C196DADKeyAddrPg  *******************************/
//eg:mov reg,reg
//for instruction table
class C196DADKeyAddrPg : public CBaseDADKey 
{                                 
//member                                 
protected:
	static CMDMOSTTBL m_Tbl[];
	static int MAX_TABLE_NUM;  
public:
    enum { ERR_NOTHING = 7800};
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);
                     
 } ;

  
/********************** for class C196DADKeyMisc *******************************/
//for instruction table
class C196DADKeyMisc : public CBaseDADKey
{ 
public:
    enum { ERR_NOTHING = 7050};
//member
protected:
	static CMDMISCTBL m_Tbl[];
	static int MAX_TABLE_NUM; 
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);

 };                          
 
/********************** for class C196DADKeyShift *******************************/
//for instruction table : shr 30,#09
class C196DADKeyShift : public CBaseDADKey 
{                                 
//member
protected:
	static CMDMOSTTBL m_Tbl[];
	static int MAX_TABLE_NUM;  
public:
    enum { ERR_NOTHING = 7100,ERR_WRONG_CODE };
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);
                     
 } ; 
 
/********************** for class  C196DADKeyOne *******************************/
//for instruction table : clr 30,neg 23
class C196DADKeyOne : public CBaseDADKey 
{                                 
//member
protected:
	static CMDMOSTTBL m_Tbl[];
	static int MAX_TABLE_NUM;  
public:
    enum { ERR_NOTHING = 7150,ERR_WRONG_CODE };
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);
                     
 } ; 

/********************** for class  C196DADKeyAddr16 *******************************/
//for instruction table : lcall,ljmp,br,tijmp
class C196DADKeyAddr16 : public CBaseDADKey 
{                                 
//member
public:
    enum { ERR_NOTHING = 8050,ERR_INVALID_REG,ERR_WRONG_CODE };
//virtual operation
public:             
	virtual BOOL SelectByValue(CAnalyseInstruction&);
	virtual	BOOL SelectByInstr(CAnalyseInstruction&);
                     
 } ; 


/********************** for class C196OpCodeAnalyse *******************************/
//Get opcode total set
class C196OpCodeAnalyse : public CBaseOpCodeAnalyse
{
//member 
public:
	enum { ERR_DOLLARS = 1000,ERR_OPCODE,ERR_DOT,
		   ERR_REVERSE,ERR_TOOMUCHOPCODE };	              
protected:
	C196DADRegIndirect* m_p196RegIndirect; 
	C196DADRegIndex* m_p196RegIndex;
//construct & destruct
public:    
	C196OpCodeAnalyse(); 
	~C196OpCodeAnalyse();
//virtual instruct
public:
	virtual BOOL Do(CAnalyseInstruction&,CDADAddress&);			
//member	
	
 };  

/********************** for class C196DAD *******************************/
class C196DAD : public CBaseDAD
{        
//construct
public:
	C196DAD();         
//member
protected:
	C196OpCodeAnalyse m_analyseInstr;
	
	C196DADKeyMost m_keyMost;
	C196DADKeyMost2 m_keyMost2;
	C196DADKeyAddrPg11 m_keyAddrPg11;
	C196DADKeyAddrPg m_keyAddrPg;
	C196DADKeyMisc m_keyMisc;
	C196DADKeyShift m_keyShift;
	C196DADKeyOne m_keyOne;
	C196DADKeyAddr16 m_keyAddr16;
	CBaseDADKey* m_pKey[8];	
	BYTE m_bKeyTblNum;
	
    //enum { ERR_A5 = ,ERR_MODE = 11050}; 
//operator
public:
    void SetCurWindow(int nCurWindow) { 
        C196DADSFRByte::m_nCurWindow = nCurWindow;
    };
//virtual operation
protected:
	virtual BOOL ProcessAsm(CBaseDADMem&);
	virtual BOOL ProcessDisasm(CBaseDADMem&);
	virtual BOOL PreAsm(CBaseDADMem& mem) { 
		m_CurrentAddr.SetWord((mem.GetAddr()).m_bAttribute,
							  (WORD)((mem.GetAddr()).m_dwAddr));
		return TRUE;							   
	};

	virtual BOOL PreDisasm(CBaseDADMem& mem);
		
//operator
public:
	BYTE GetUsedDasByte() {
		return Baby.m_bNum;
	};	
	
 };                
                                        
/********************** for class C196DADMem *******************************/
class C196DADMem : public CBaseDADMem 
{     
//member
protected:
	CDADAddr m_bufStart; 
	DWORD m_dwBufLen;
	BYTE* m_pBuffer;
	BOOL isReadBufInvalid;   
public:
	enum { BUFFERLEN = 90 };	
//construct & destruct
public:
	C196DADMem() {
		m_bufStart.m_dwAddr =0;
		m_bufStart.m_bAttribute = 0;
		m_dwBufLen = 0;
		m_pBuffer = new BYTE[BUFFERLEN+2];
		isReadBufInvalid = FALSE;
	};	                                
	virtual ~C196DADMem() {
		if (NULL != m_pBuffer) delete m_pBuffer;
	};	
//virtual operator
public: 
	virtual BOOL WriteBytes(BYTE*,BYTE bNum=1);
	virtual BOOL ReadByte(BYTE&);
public:
	virtual BOOL UpdateBuffer();                                 
};

 
#endif

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