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

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

#include "stdafx.h"             
#include "dad196.h"  
#include "string.h"
#include "address.h"
//#include "tbl196.h"
//int GetCurWindow(){ return 1; }
/********************** for class C196DADRegIndirect *******************************/ 
// 
//	CLASS NAME : C196DADRegIndirect
//
//  HEAD FILE  : dad196.H
//
/**************************************************************************/
const CDADAddr C196DADRegIndirect::StrToAddr(CString str)
{ 
	BOOL isPlus = FALSE; //sample : [10]+
	CDADAddr addrRet;                       
		
	addrRet.m_bAttribute = UNDEFINED;
	
	if('[' != str[0]) return addrRet;
	if (1 == str.GetLength()) return addrRet;
	str = str.Right(str.GetLength()-1);
	
	int loc = str.Find(']');
	if(-1 == loc) return addrRet;
	if(str.GetLength()>loc+1 && '+' == str[loc+1]) {
		if(loc+2 != str.GetLength()) return addrRet;
		isPlus = TRUE;
	}	
	str = str.Left(loc);
	if("" == str) return addrRet;
	//AfxMessageBox(str);
	//check sfr
	addrRet = m_sfr<<str;
	if (C196DADSFRByte::UNDEFINED != addrRet.m_bAttribute &&
	    addrRet.m_dwAddr <= 0xff &&
	    (addrRet.m_dwAddr&0x1)==0 ) {                         
	    if(isPlus) {
	    	addrRet.m_bAttribute = INDIRECT_PLUS;
	    	addrRet.m_dwAddr++;
	    } else addrRet.m_bAttribute = INDIRECT;
		return addrRet;
	}                
	//check sym
	addrRet = m_sym<<str;
	if (MEM_I == addrRet.m_bAttribute &&
	    addrRet.m_dwAddr <= 0xff &&
	    (addrRet.m_dwAddr&0x1)==0 ) {                         
	    if(isPlus) {
	    	addrRet.m_bAttribute = INDIRECT_PLUS;
	    	addrRet.m_dwAddr++;
	    } else addrRet.m_bAttribute = INDIRECT;
		return addrRet;
	}               
	//check addr
	addrRet = m_addr.StrToAddr(str);
	if (addrRet.m_bAttribute != C196DADAddrAnalyse::UNDEFINED &&
		addrRet.m_dwAddr <= 0xff &&
		(addrRet.m_dwAddr&0x1)==0 ) {
		if(isPlus) {
			addrRet.m_bAttribute = INDIRECT_PLUS;
			addrRet.m_dwAddr++;
		} else addrRet.m_bAttribute = INDIRECT;
		return addrRet;
	}	
	addrRet.m_bAttribute = UNDEFINED;
	return addrRet;
 }                                                 
 
CString C196DADRegIndirect::AddrToStr(CDADAddr addr)
{       
	CString tmp = "[";
	CString str="";
	BOOL isPlus = FALSE;
	
	if(addr.m_dwAddr > 0xff) return str;
	if((addr.m_dwAddr&0x1) == 1) {
		isPlus = TRUE;
		(addr.m_dwAddr)--;  
	}
	
	str = m_sfr<<addr;
	if (str != "") {
		str = tmp + str;
		str += "]";
		if(isPlus) str += "+";
		return str;
	}
	
	addr.m_bAttribute = MEM_I;
	str = m_sym<<addr;
	if (str != "") {
		str = tmp + str;
		str += "]";
		if(isPlus) str += "+";
		return str;
	}
	
	m_addr.SetByte(addr.m_bAttribute,(BYTE)addr.m_dwAddr);
	str = m_addr.GetStr();
	if (str != "") {
		str = tmp + str;
		str += "]";
		if(isPlus) str += "+";
		return str;
	}   
	
	return str;	
 }
 
/********************** for class C196DADRegIndex *******************************/ 
// 
//	CLASS NAME : C196DADRegIndex
//
//  HEAD FILE  : dad196.H
//
/**************************************************************************/
const CDADAddr& C196DADRegIndex::StrToAddr(CString str)
{   
	CString strBaseAddr,strReg;               
	BOOL isLong = FALSE;
	m_regAddr.m_bAttribute = UNDEFINED;
	
	int loc = str.Find('[');
	if(-1 == loc) return m_regAddr;
	
	strBaseAddr = str.Left(loc);
	if("" == strBaseAddr) return m_regAddr;
	
	strReg = str.Right(str.GetLength()-loc);
	loc = strReg.Find(']');
	if ( loc == -1 || strReg.GetLength()!=loc+1) return m_regAddr;
	strReg = strReg.Mid(1,strReg.GetLength()-2);
	if("" == strReg) return m_regAddr;                        
	
	//check symbol
	m_baseAddr = m_sym<<strBaseAddr;
	if (m_baseAddr.m_bAttribute<MEM_X0 || m_baseAddr.m_bAttribute>MEM_X3) {
		//check address
		m_baseAddr = m_addr.StrToAddr(strBaseAddr);
		if(C196DADAddrAnalyse::UNDEFINED == m_baseAddr.m_bAttribute)
			return m_regAddr;
	} 
	
	if(	m_baseAddr.m_dwAddr > 0xffff ) return m_regAddr;
	if( m_baseAddr.m_dwAddr > 0xff) isLong = TRUE;	
	
	//make reg address
	//check sfr
	m_regAddr = m_sfr<<strReg;
	if (C196DADSFRByte::UNDEFINED != m_regAddr.m_bAttribute &&
	    m_regAddr.m_dwAddr <= 0xff &&
	    (m_regAddr.m_dwAddr&0x1)==0 ) {                         
	    if(isLong) {
			m_regAddr.m_bAttribute = INDEX_LONG;
			m_regAddr.m_dwAddr++;
		} else {
		    m_regAddr.m_bAttribute = INDEX;
		}	           
		return m_regAddr;
	}                                
	//check sym
	m_regAddr = m_sym<<strReg;
	if (MEM_I == m_regAddr.m_bAttribute &&
	    m_regAddr.m_dwAddr <= 0xff &&
	    (m_regAddr.m_dwAddr&0x1)==0 ) {                         
	    if(isLong) {
	    	m_regAddr.m_bAttribute = INDEX_LONG;
	    	m_regAddr.m_dwAddr++;
	    } else m_regAddr.m_bAttribute = INDEX;
		return m_regAddr;
	}               
	//check address
	m_regAddr = m_addr.StrToAddr(strReg);
	if (C196DADAddrAnalyse::UNDEFINED != m_regAddr.m_bAttribute &&
	    m_regAddr.m_dwAddr <= 0xff &&
	    (m_regAddr.m_dwAddr&0x1)==0 ) {                         
	    if(isLong) {
			m_regAddr.m_bAttribute = INDEX_LONG;
			m_regAddr.m_dwAddr++;
		} else {
		    m_regAddr.m_bAttribute = INDEX;
		}	           
		return m_regAddr;
	}
	
	m_regAddr.m_bAttribute = UNDEFINED;
	return m_regAddr;
 }                                                 
 
CString C196DADRegIndex::AddrToStr(CDADAddr addrReg,CDADAddr addrBase )
{       
	CString tmp = "[";
	BOOL isLong = FALSE;
	CString strBaseAddr,strReg="";                
	
	m_regAddr = addrReg;
	m_baseAddr = addrBase;
	
	//make base
	if(m_baseAddr.m_dwAddr > 0xffff) return strReg;
	if(m_regAddr.m_dwAddr > 0xff) return strReg;
	if(m_baseAddr.m_dwAddr > 0xff || m_baseAddr.m_bAttribute == 1) {
		isLong = TRUE;
		m_regAddr.m_dwAddr--;
	}	
	
	if(isLong) {
		m_addr.SetWord(ADDRX16,(WORD)m_baseAddr.m_dwAddr);
		strBaseAddr = m_addr.GetStr();
	}	
	else {            
		m_addr.SetByte(ADDRX16,(BYTE)m_baseAddr.m_dwAddr);	
		strBaseAddr = m_addr.GetStr();
	}	
	if (strBaseAddr != "") {
		strReg = strBaseAddr;
	} else {
		strBaseAddr = m_sym<<m_baseAddr;
		if (strBaseAddr != "") strReg = strBaseAddr;		
		else return strReg;
	}
	
	strReg = m_sfr<<m_regAddr;
	if (strReg != "") {
		strReg = tmp + strReg;
		strReg += "]";
		strReg = strBaseAddr + strReg;
		return strReg;
	}
	
	strReg = m_sym<<m_regAddr;
	if (strReg != "") {
		strReg = tmp + strReg;
		strReg += "]";
		strReg = strBaseAddr + strReg;
		return strReg;
	}                                                               
	
	m_addr.SetByte(m_regAddr.m_bAttribute,(BYTE)m_regAddr.m_dwAddr);
	strReg = m_addr.GetStr();
	
	if (strReg != "") {  
		strReg = tmp + strReg;
		strReg += "]";
		strReg = strBaseAddr + strReg;
		return strReg;
	}   
	
    strReg = "";
	return strReg;	
 }

/********************** for class C196DADSym *******************************/
// 
//	CLASS NAME : C196DADSym
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
#include "ldrexp.h"
BOOL C196DADSym::m_isSymbolic = TRUE;
C196DADSym::C196DADSym()
{ 
	m_strSym = ""; 
	m_cHead = '#';                 
	m_addr.Add(0,0);	
 }                             

BOOL C196DADSym::SelectByAddr()
{   
	if(!m_isSymbolic) return FALSE;                
	m_strSym = "";
	ADDRESS tmpAddr;
	
	tmpAddr.adrSpace = m_addr.m_bAttribute;
	tmpAddr.adrAddress = m_addr.m_dwAddr;
	
	GetRootBankValue(tmpAddr);
					  
	BOOL ret = AdrAddrToSymbol( tmpAddr,m_strSym);
	if(TRUE != ret) return FALSE;
	return TRUE;
 }
 
BOOL C196DADSym::SelectByStr()
{   
	m_addr.Add(CDADAddr::UNDEFINED,0);                    
    ADDRESS tmpAddr;
	if(m_strSym[0] != m_cHead) return FALSE;    
    ADDR_RETCODE ret = AdrTextToAddr(m_strSym,tmpAddr);            
    if(ADR_OK != ret) return FALSE;
    
    if(tmpAddr.adrSpace>=MEM_P0 && tmpAddr.adrSpace<=MEM_P3) {
    	m_addr.m_bAttribute = ADDR16;
    } else if(tmpAddr.adrSpace>=MEM_X0 && tmpAddr.adrSpace<=MEM_X3) {
    	m_addr.m_bAttribute = ADDRX16;
    } else if(tmpAddr.adrSpace==ADDRI && tmpAddr.adrAddress<0x100) {
    	m_addr.m_bAttribute = ADDRI;
    } else return FALSE;
    m_addr.m_dwAddr = tmpAddr.adrAddress;
    return TRUE;
 }

/********************** for class C196DADSFRByte *******************************/
// 
//	CLASS NAME : C196DADSFRByte
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
int C196DADSFRByte::m_nCurWindow = 0;
BOOL C196DADSFRByte::SelectByAddr() 
{   
	CRegItem riOutput;
	riOutput.dwAddr = m_addr.m_dwAddr;
	riOutput.wType = ::MEM_I;
	riOutput.wAttr = (WORD)m_nAttr;
    riOutput.wLen = (WORD)m_nLen;
    riOutput.wWindow = (WORD)m_nCurWindow;
	
	if (!RegNameFromAddr(&riOutput)) {
		m_strName = "";
		return FALSE;
	}                   
	
	m_strName = riOutput.szName;
	return TRUE;
 }          
      
BOOL C196DADSFRByte::SelectByStr()
{                                                               
	CRegItem riOutput;
	
	if(m_strName.GetLength() > 18) m_strName = m_strName.Left(18);
	strcpy(riOutput.szName,m_strName.GetBuffer(m_strName.GetLength()+2));
	m_strName.ReleaseBuffer();
	riOutput.wWindow = (WORD)m_nCurWindow;
    riOutput.dwAddr = 0;    
    //AfxMessageBox(riOutput.szName);
    if( !RegAddrFromName(&riOutput) || riOutput.dwAddr>=0x100) {
    	//AfxMessageBox("fail");
		m_addr.Add(UNDEFINED,0);
		return FALSE;    					 
    }           
    //AfxMessageBox("ok"); 
    //char tmp[100];
    //sprintf(tmp,"%04x",riOutput.dwAddr); 
    //AfxMessageBox(tmp); 
    //sprintf(tmp,"%04x",riOutput.wType); 
    //AfxMessageBox(tmp);                  
    m_addr.m_dwAddr = riOutput.dwAddr;
    m_addr.m_bAttribute = (BYTE)riOutput.wType;
    m_nAttr = (int)riOutput.wAttr;
    m_nLen = (int)riOutput.wLen;
    m_nCurWindow = (int)riOutput.wWindow;
    
	return TRUE;
 }

/********************** for class C196DADAddrAnalyse *******************************/
// 
//	CLASS NAME : C196DADAddrAnalyse
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
//deal with HEX DAD address
CString C196DADAddrAnalyse::AddPrefix() 
{
	CString strTmp = "";
	return strTmp;
 }       

BOOL C196DADAddrAnalyse::GetPrefix(CString& strTmp) 
{                     
	m_bAttribute = !UNDEFINED;
	return CDADAddress::GetPrefix(strTmp);
 }
                       
 
/********************** for class COpDeal196ASMAddrPg11 *******************************/ 
// 
//	CLASS NAME : COpDeal196ASMAddrPg11
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL COpDeal196ASMAddrPg11::Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr) 
{
	//get current instruction lenght
	WORD wAddr;
	//first byte is current instruction length
	BYTE bLen = GetByte();     
	BYTE bTmp;               
	//then is the address          
	RemoveAt(0);        
	wAddr = GetWord();
	CDADValue::Clear();
		
	//make next address
	WORD wNextAddr = bLen + pCurrentAddr->GetWord();
		
	long lTmp = (long)wAddr - wNextAddr;
	if (lTmp>=-1024 && lTmp<=1023) {    
		bTmp = (BYTE)(lTmp&0xff);
		Baby.AddCode(bTmp);
		bTmp = (BYTE)(Baby.GetCode(0));
		bTmp = (BYTE)((bTmp&0xf8)|((lTmp>>8)&0x07)); 
    	Baby.m_CodeSet.SetAt(0,bTmp);
	}	
	else {
		m_nErrCode = ERR_ASM_ADDRPG11;
		return FALSE;
	}     
	return TRUE;
}

/********************** for class COpDeal196ASMAddrPg *******************************/ 
// 
//	CLASS NAME : COpDeal196ASMAddrPg
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL COpDeal196ASMAddrPg::Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr) 
{
	//get current instruction lenght
	WORD wAddr;
	//first byte is current instruction length
	BYTE bLen = GetByte();     
	//then is the address          
	RemoveAt(0);        
	wAddr = GetWord();
	CDADValue::Clear();
		
	//make next address
	WORD wNextAddr = bLen + pCurrentAddr->GetWord();
		
	long lTmp = (long)wAddr - wNextAddr;
	if (lTmp>=-128 && lTmp<=127) {
		Baby.AddCode((BYTE)lTmp);    
	}	
	else {
		m_nErrCode = ERR_ASM_ADDRPG;
		return FALSE;
	}     
	return TRUE;
}

/********************** for class COpDeal196Addr16 *******************************/ 
// 
//	CLASS NAME : COpDeal196Addr16
//
//  HEAD FILE  : DAD196.H              
//
/**************************************************************************/
//very special, in 196, the lcall ljmp have 16bit address offset,not direct address 16
BOOL COpDeal196ASMAddr16::Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr) 
{ 
	//get current instruction length
	WORD wAddr;
	//first byte is current instruction length
	BYTE bLen = GetByte();     
	BYTE bTmp;               
	//then is the address          
	RemoveAt(0);        
	wAddr = GetWord();
	CDADValue::Clear();
		
	//make next address
	WORD wNextAddr = bLen + pCurrentAddr->GetWord();
	/*	
	long lTmp = (long)wAddr - wNextAddr;
	if (lTmp>=-32768 && lTmp<=32767) {    
		bTmp = (BYTE)(lTmp&0xff);
		Baby.AddCode(bTmp);
		bTmp = (BYTE)((lTmp&0xff00)>>8); 
    	Baby.AddCode(bTmp);
	}	
	else {
		m_nErrCode = ERR_ASM_ADDR16;
		return FALSE;
	}*/
	WORD wTmp = wAddr - wNextAddr;    
	bTmp = (BYTE)(wTmp&0xff);
	Baby.AddCode(bTmp);
	bTmp = (BYTE)((wTmp&0xff00)>>8); 
	Baby.AddCode(bTmp);
	     
	return TRUE;
	
}
/********************** for class COpDeal196DASAddr16 *******************************/ 
// 
//	CLASS NAME : COpDeal196DASAddr16
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
//very special, in 196, the lcall ljmp have 16bit address offset,not direct address 16
BOOL COpDeal196DASAddr16::Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr) 
{   
    C196DADAddrAnalyse addr;
	WORD wAddr,wNextAddr;             
	CDADAddr tmpAddr;
	C196DADSym sym;
	CString strBak;                
	BYTE bLen = m_bLen; 
	
	WORD wOffset = (unsigned)GetWord();
	//make next addr
	wNextAddr = pCurrentAddr->GetWord() + m_bLen;
	//make jmp addr
	wAddr = wNextAddr + (signed short)(wOffset);     
	addr.SetWord(pCurrentAddr->m_bAttribute,wAddr);
	strBak = addr.GetStr();
	                                  
	tmpAddr.Add(addr.GetAttribute(),addr.GetWord());
	
	CString tmpStr = sym << tmpAddr;
	if ( "" != tmpStr ) {
		Baby.m_Instruction += tmpStr;
		return TRUE;
	}               
	
	//if no symbol
	Baby.m_Instruction += strBak;
	//make next address (maybe) 
	CNextIceAddr* pNextAddr = new CNextIceAddr(tmpAddr.m_dwAddr,tmpAddr.m_bAttribute);
	Baby.m_NextAddrSet.Add((CObject*)pNextAddr);
	return TRUE;
	
 }
 
/********************** for class COpDeal196DASAddrPg11 *******************************/ 
// 
//	CLASS NAME : COpDeal196DASAddrPg11
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL COpDeal196DASAddrPg11::Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr) 
{                                
	C196DADAddrAnalyse addr;
	WORD wAddr,wNextAddr;             
	CDADAddr tmpAddr;
	C196DADSym sym;
	CString strBak;                
	BYTE bLen = m_bLen; 
	WORD wOffset = (WORD)(GetByte() + (WORD)((m_bFirst&0x07)<<8));
	unsigned short usOffset = ((wOffset&0x0400) == 0) ? 
							  (unsigned short)(wOffset&0x03ff) :
							  (unsigned short)(wOffset|0xf800); 
	//make next addr
	wNextAddr = pCurrentAddr->GetWord() + m_bLen;
	//make jmp addr
	wAddr = wNextAddr + (signed short)usOffset;     
	addr.SetWord(pCurrentAddr->m_bAttribute,wAddr);
	strBak = addr.GetStr();
	                                  
	tmpAddr.Add(addr.GetAttribute(),addr.GetWord());
	
	CString tmpStr = sym << tmpAddr;
	if ( "" != tmpStr ) {
		Baby.m_Instruction += tmpStr;
		return TRUE;
	}               
	
	//if no symbol
	Baby.m_Instruction += strBak;
	//make next address (maybe) 
	CNextIceAddr* pNextAddr = new CNextIceAddr(tmpAddr.m_dwAddr,tmpAddr.m_bAttribute);
	Baby.m_NextAddrSet.Add((CObject*)pNextAddr);
	return TRUE;
 }

/********************** for class COpDeal196DASAddrPg *******************************/ 
// 
//	CLASS NAME : COpDeal196DASAddrPg
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL COpDeal196DASAddrPg::Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr) 
{                                
	C196DADAddrAnalyse addr;
	WORD wAddr,wNextAddr;
	CDADAddr tmpAddr;
	C196DADSym sym;
	CString strBak;                
	BYTE bLen = m_bLen; 
	signed char bOffset = GetByte();
	//make next addr
	wNextAddr = pCurrentAddr->GetWord() + m_bLen;
	//make jmp addr
	wAddr = wNextAddr + bOffset;     
	addr.SetWord(ADDR16,wAddr);
	strBak = addr.GetStr();
	                                  
	tmpAddr.Add(pCurrentAddr->m_bAttribute,addr.GetWord());
	
	CString tmpStr = sym << tmpAddr;
	if ( "" != tmpStr ) {
		Baby.m_Instruction += tmpStr;
		return TRUE;
	}               
	
	//if no symbol
	Baby.m_Instruction += strBak;
	//make next address (maybe) 
	CNextIceAddr* pNextAddr = new CNextIceAddr(tmpAddr.m_dwAddr,tmpAddr.m_bAttribute);
	Baby.m_NextAddrSet.Add((CObject*)pNextAddr);
	return TRUE;
 }


/********************** for class COpDeal196DASAddr11 *******************************/ 
// 
//	CLASS NAME : COpDeal196DASAddr11
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
/*
BOOL COpDeal196DASAddr11::Do(CAnalyseInstruction& Baby,CDADAddress* pCurrentAddr) 
{               
    C196DADAddrAnalyse tmpAddress1,tmpAddress2;
	CDADAddr tmpAddr;
	C196DADSym sym;
	CString strBak;                
	BYTE bLen = m_bLen;     
	WORD wOffSet = GetByte(1);
	BYTE bTmp = (GetByte(0))&0x07;
	if(1 == (bTmp&0x04)) bTmp |= 0xf8;
	wOffSet += bTmp*256;
	
	tmpAddress1.SetWord(NORMALAREA,(*pCurrentAddr).GetWord());
	tmpAddress2.SetWord(NORMALAREA,(WORD)bLen);
	tmpAddress1 + tmpAddress2;
	                                       
	//check Pg range -128--+127	                                       
	if( (int)(wOffSet) >= 0 )	{
		tmpAddress2.SetWord(NORMALAREA,(WORD)bOffSet);
		strBak = tmpAddress1 + tmpAddress2;
	} else {
		WORD tmpK;
        tmpK =(WORD)(~wOffSet+1);
        tmpAddress2.SetWord(NORMALAREA,tmpK);
        strBak = tmpAddress1 - tmpAddress2;
	}
	 
	tmpAddr.Add(tmpAddress1.GetAttribute(),tmpAddress1.GetWord());
	
	CString tmpStr = sym << tmpAddr;
	if ( "" != tmpStr ) {
		Baby.m_Instruction += tmpStr;
		return TRUE;
	}               
	
	//if no symbol
	Baby.m_Instruction += strBak;
	//make next address (maybe) 
	CNextIceAddr* pNextAddr = new CNextIceAddr(tmpAddr.m_dwAddr,tmpAddr.m_bAttribute);
	Baby.m_NextAddrSet.Add((CObject*)pNextAddr);
	return TRUE;
	
 }
*/
/********************** for class COpDeal196DASAddrI *******************************/ 
// 
//	CLASS NAME : COpDeal196DASAddrI
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
//internal data 0x00 -- 0xff
BOOL COpDeal196DASAddrI::Do(CAnalyseInstruction& Baby,CDADAddress* ) 
{                           
	C196DADAddrAnalyse tmpAddress1;
	CDADAddr tmpAddr;
	C196DADSym sym;
	C196DADSFRByte sfr;
	CString strBak;                
	
	/*
	if(2==m_nLen && (GetByte()&0x01) !=0) {
		Baby.m_Instruction += "?";
		return TRUE;
	}
	
	if(4==m_nLen && (GetByte()&0x03) !=0) {
		Baby.m_Instruction += "?";
		return TRUE;
	}
	*/
	
	if(2==m_nLen && (GetByte()&0x01) !=0) {
		Baby.m_isDirtyResult = TRUE;
	}
	
	if(4==m_nLen && (GetByte()&0x03) !=0) {
		Baby.m_isDirtyResult = TRUE;
	}
	                                       
	//make the internal address
	tmpAddress1.SetByte(ADDRI,GetByte());
	strBak = tmpAddress1.GetStr();
	
	tmpAddr.Add(ADDRI,(DWORD)GetByte());
	
	CString tmpStr = sym << tmpAddr;
	if ( "" != tmpStr ) {
		Baby.m_Instruction += tmpStr;
		return TRUE;
	}               
	sfr.SetOption(m_nLen,m_nAttr);
	tmpStr = sfr << tmpAddr;
	if ( "" != tmpStr ) {
		tmpStr = sfr.GetSfrName();
		if ("" != tmpStr) {
			Baby.m_Instruction += tmpStr;
			return TRUE;
		}	
	}               
	
	//if no symbol
	Baby.m_Instruction += strBak;
	return TRUE;
 }
////////////////////////////////////////////////
/********************** for class C196DADKeyMost *******************************/
// 
//	CLASS NAME : C196DADKeyMost
//
//  HEAD FILE  : dad196.H
//
/**************************************************************************/
BOOL C196DADKeyMost::SelectByValue(CAnalyseInstruction& Baby)
{
	BYTE bValue,bIndex,bOffset;
	COpDealReadDigit* pTmpOb;
	COpDealReadDigit* pArrayOb[5];
	CDADAddr tmpAddr,tmpAddr2;
	int nArraySize = 0;
	
	//add for signed 
	int nSigned = 0;
	
	bValue = (BYTE)(Baby.GetCode(0));
	if(bValue == 0xfe) nSigned = 1;
	
	if(nSigned == 1) {
		Baby.m_bNeedNum = 2;	
		if ( Baby.m_bNeedNum > Baby.m_bNum ) {
			m_nErrCode = ERR_NEED_MORE_BYTE;
			return FALSE;
		}
	}
	
	if(nSigned == 1) bValue = (BYTE)(Baby.GetCode(1));
	
	if(bValue<0x40 || bValue>0xcf || bValue==0xc1 ||
	   bValue==0xc5 || bValue==0xcd) {
	   m_nErrCode = ERR_NOTHING;
	   return FALSE;
	}
	bIndex = (BYTE)((bValue-0x40)/4); bOffset = (BYTE)((bValue-0x40)%4);
	
	switch (bOffset) {
		case 0 : 
		case 2 : Baby.m_bNeedNum = (BYTE)(m_Tbl[bIndex].bType+1);
				 break;
		case 1 : Baby.m_bNeedNum = (BYTE)(m_Tbl[bIndex].bType+
								   (m_Tbl[bIndex].bWidth==10?1: (m_Tbl[bIndex].bWidth==20?2:m_Tbl[bIndex].bWidth) ));
				 break;		 		 
		case 3 : if(nSigned) {
					 if(1 == Baby.m_bNum) {
					 	Baby.m_bNeedNum = 3;
					 } else if(Baby.m_bNum>=3) {
						if((BYTE)(Baby.GetCode(1+nSigned)&0x01)==0x01) {        
							Baby.m_bNeedNum = (BYTE)(m_Tbl[bIndex].bType+3);
						} else {
							Baby.m_bNeedNum = (BYTE)(m_Tbl[bIndex].bType+2);
						} 
					 }
				 } else {                                       
				     if(1 == Baby.m_bNum) {
					 	Baby.m_bNeedNum = 2;
					 } else if(Baby.m_bNum>=2) {
						if((BYTE)(Baby.GetCode(1+nSigned)&0x01)==0x01) {        
							Baby.m_bNeedNum = (BYTE)(m_Tbl[bIndex].bType+3);
						} else {
							Baby.m_bNeedNum = (BYTE)(m_Tbl[bIndex].bType+2);
						} 
					 }
				 }	  	
				 break;		 		 		           
		default: ASSERT(FALSE);		 
	}
	                                  
	Baby.m_bNeedNum += nSigned;                                  
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}                                                  
	
	CString strInstruction = m_Tbl[bIndex].pIntruction;
	if(1 == nSigned) {
		if("DIVU" == strInstruction) strInstruction = "DIV";
		else if("DIVUB" == strInstruction) strInstruction = "DIVB";
		else if("MULU" == strInstruction) strInstruction = "MUL";
		else if("MULUB" == strInstruction) strInstruction = "MULB";
	}	
	
	pTmpOb = new COpDealConstInstr(Baby,strInstruction.GetBuffer(strInstruction.GetLength()));
	strInstruction.ReleaseBuffer;
	Baby.m_OpDealSet.Add(pTmpOb);            	       
	
	CString strRet;  
	C196DADDAtumAnalyse datum;                   
	
	int nLen = m_Tbl[bIndex].bWidth==10?1: (m_Tbl[bIndex].bWidth==20?2:m_Tbl[bIndex].bWidth);
	int nAttr = (bIndex == 35) ? OP_W : OP_R;                   
	C196DADRegIndirect indirect;
	indirect.SetOption(nLen,nAttr);
	
	C196DADRegIndex index;
	index.SetOption(nLen,nAttr);
	int nUsedCode = 2 + nSigned;
	
	switch (bOffset) {
		case 0 : pArrayOb[nArraySize++] = (COpDealReadDigit*)(new COpDeal196DASAddrI(Baby,nLen,nAttr,1+nSigned,1));
				 break;
				 
		case 1 : if (m_Tbl[bIndex].bWidth == 1 || m_Tbl[bIndex].bWidth == 10) 
				 	 datum.SetByte((BYTE)(Baby.GetCode(1+nSigned)));
				 else {
				     datum.SetByte((BYTE)(Baby.GetCode(1+nSigned)));
				     datum.AddByte((BYTE)(Baby.GetCode(2+nSigned)));			 	
				     nUsedCode = 3+nSigned;
				 }    
				 pArrayOb[nArraySize++] = (COpDealReadDigit*)(new COpDealConstInstr(Baby,datum.GetStr()));
				 break;
		
		case 2 : tmpAddr = (DWORD)(Baby.GetCode(1+nSigned));
				 pArrayOb[nArraySize++] = (COpDealReadDigit*)(new COpDealConstInstr(Baby,indirect.AddrToStr(tmpAddr)));
				 break;
		case 3 : tmpAddr = (DWORD)(Baby.GetCode(1+nSigned));
				 if((tmpAddr.m_dwAddr&0x00000001) == 1) {
				 	WORD w1 = (WORD)Baby.GetCode(3+nSigned);
				 	w1 = w1<<8;
				 	WORD w2 = (WORD)Baby.GetCode(2+nSigned);
				 	tmpAddr2 = (DWORD)(w1+w2);
				 	nUsedCode = 4 + nSigned;
				 	tmpAddr2.m_bAttribute = 1;
				 } else {	                              
				    tmpAddr2 = (DWORD)(Baby.GetCode(2+nSigned));
				    nUsedCode = 3 + nSigned;  
				    tmpAddr2.m_bAttribute = 0;
				 }   
				 pArrayOb[nArraySize++] = (COpDealReadDigit*)(new COpDealConstInstr(Baby,index.AddrToStr(tmpAddr,tmpAddr2)));
				 break;
		default : ASSERT(FALSE);		 
	}                           
	
	
	if(m_Tbl[bIndex].bType == 2) {
		nLen = m_Tbl[bIndex].bWidth==10?2: (m_Tbl[bIndex].bWidth==20?4:m_Tbl[bIndex].bWidth);
		nAttr = OP_W;
		pArrayOb[nArraySize++] = new COpDeal196DASAddrI(Baby,nLen,nAttr,nUsedCode++,1);
	} 
	
	if(m_Tbl[bIndex].bType == 3) {       
		nLen = m_Tbl[bIndex].bWidth==10?1: (m_Tbl[bIndex].bWidth==20?2:m_Tbl[bIndex].bWidth);
		pArrayOb[nArraySize++] = new COpDeal196DASAddrI(Baby,nLen,nAttr,nUsedCode++,1);
		nLen = m_Tbl[bIndex].bWidth==10?2: (m_Tbl[bIndex].bWidth==20?4:m_Tbl[bIndex].bWidth);
		nAttr = OP_W;
		pArrayOb[nArraySize++] = new COpDeal196DASAddrI(Baby,nLen,nAttr,nUsedCode++,1);
	}
	
	for(int i=nArraySize-1;i>=0;i--) {
		Baby.m_OpDealSet.Add(pArrayOb[i]);            	       
	}
	return TRUE;
 }
 
BOOL C196DADKeyMost::SelectByInstr(CAnalyseInstruction& Baby)
{    
	//ADD FOR MUL..
	BOOL isSiagned = TRUE;
	CString strSave = Baby()[0];
	if("DIV" == strSave) strSave = "DIVU";
	else if("DIVB" == strSave) strSave = "DIVUB";
	else if("MUL" == strSave) strSave = "MULU";
	else if("MULB" == strSave) strSave = "MULUB";
	else isSiagned = FALSE;
		
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
	COpDealWriteDigit* pTmpOb;                 
	BYTE bIndex = 0xff,bType,bOffSet;
	
	for(int i = MAX_TABLE_NUM-1; i >=0; i--) {
	   if(strSave == m_Tbl[i].pIntruction) {
	   	   if((*(Baby>>m_Tbl[i].bType-1))(INDEX)) {
	   	       bType = INDEX;       
	   	       bOffSet = 3;
	   	   } else if((*(Baby>>(m_Tbl[i].bType-1)))(INDEX_LONG)) {
	   	       bType = INDEX_LONG;
	   	       bOffSet = 3;
	   	   } else if((*(Baby>>(m_Tbl[i].bType-1)))(INDIRECT)) {
	   	       bType = INDIRECT;
	   	       bOffSet = 2;
	   	   } else if((*(Baby>>(m_Tbl[i].bType-1)))(INDIRECT_PLUS)) {
	   	       bType = INDIRECT_PLUS;
	   	       bOffSet = 2;
	   	   } else if((m_Tbl[i].bWidth==1||m_Tbl[i].bWidth==10) && (*(Baby>>(m_Tbl[i].bType-1)))(DATA8)) {
	   	   	   if(m_Tbl[i].bCode==0xc0 ||m_Tbl[i].bCode==0xc4 || m_Tbl[i].bCode==0xcc) {
	   	   	   	   m_nErrCode = ERR_NOTHING;
	   	   	   	   return FALSE;                                                        
	   	   	   }	   
	   	       bType = DATA8;
	   	       bOffSet = 1;
	   	   } else if((m_Tbl[i].bWidth==2||m_Tbl[i].bWidth==20) && ( (*(Baby>>(m_Tbl[i].bType-1)))(DATA16) || (*(Baby>>(m_Tbl[i].bType-1)))(DATA8)) ) {
	   	   	   if(m_Tbl[i].bCode==0xc0 ||m_Tbl[i].bCode==0xc4 || m_Tbl[i].bCode==0xcc) {
	   	   	   	   m_nErrCode = ERR_NOTHING;
	   	   	   	   return FALSE;                                                        
	   	   	   }	   
	   	       bType = DATA16;
	   	       bOffSet = 1;
	   	   } else if((*(Baby>>(m_Tbl[i].bType-1)))(ADDRI)) {
	   	       bType = ADDRI;
	   	       bOffSet = 0;
	   	   } else if((*(Baby>>(m_Tbl[i].bType-1)))(ADDRX16)) {
	   	   	   if((*(Baby>>m_Tbl[i].bType-1)).m_Value.GetDWord() > 0xff) {
	   	   	   	   bType = INDEX_LONG;                                  
	   	   	   	   (*(Baby>>m_Tbl[i].bType-1)).m_Value.SetDWord(
	   	   	   	   	   (((*(Baby>>m_Tbl[i].bType-1)).m_Value.GetDWord())|0x10000)
	   	   	   	   );	   
	   	   	   } else bType = ADDRX16;
	   	       bOffSet = 3;
	   	   } else continue;
	   	   //check none
	   	   int j;
	   	   for(j=m_Tbl[i].bType;j<3;j++) {
				if(!(*(Baby>>j))(NONE)) {
					break;
				}	
		   } 
		   if(j!=3) continue;
		   
	   	   bIndex = (BYTE)i;
	   	   break;
	   }//if
	}//for          
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	
	for(i=0;i<m_Tbl[bIndex].bType-1;i++) {
		if(!(*(Baby>>i))(ADDRI)) {
			m_nErrCode = ERR_NOTHING;
			return FALSE;
		}	
	} 
	
	//for head code                               
	pTmpOb = new COpDealWriteDigit;
	if(isSiagned) {            
	    pTmpOb->SetByte((BYTE)(m_Tbl[bIndex].bCode + bOffSet));
	    pTmpOb->AddByte(0xfe);
	} else {
		pTmpOb->SetByte((BYTE)(m_Tbl[bIndex].bCode + bOffSet));
	}
		
	Baby.m_OpDealSet.Add(pTmpOb);
	
	//write waop,baop
	//check operator width type ok                
	if(bType == ADDRI && m_Tbl[bIndex].bWidth == 2 && 
		((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.GetByte())&0x01 != 0) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;                                                    
	}	
	pTmpOb = new COpDealWriteDigit;              
	
	if(DATA16 == bType) {
		pTmpOb->SetByte((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.GetByte(1));
		pTmpOb->AddByte((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.GetByte());
	} else if(DATA8 == bType) {
		pTmpOb->SetByte((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.GetByte());
	} else if(INDEX_LONG == bType) {                                        
		pTmpOb->SetByte((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.GetByte(1));
		pTmpOb->AddByte((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.GetByte());
		pTmpOb->AddByte((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.GetByte(2));
	} else {
	    pTmpOb->SetValue((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value);
	} 
	
	//if(ADDRX16 == bType) (*(Baby>>m_Tbl[bIndex].bType-1)).m_Value.AddByte(0); 
    //pTmpOb->SetValue((*(Baby>>m_Tbl[bIndex].bType-1)).m_Value);
    Baby.m_OpDealSet.Add(pTmpOb);
	
	//write rest
	for (i=m_Tbl[bIndex].bType-2; i>=0; i--) {
		//check operator width type ok                
		//for word
		if (0 == i){
			if(( m_Tbl[bIndex].bWidth == 2 || m_Tbl[bIndex].bWidth==10) && 
				(((*(Baby>>i)).m_Value.GetByte())&0x01) != 0 ) {
				m_nErrCode = ERR_NOTHING;
				return FALSE;                                 
			}         
			//for deword              
			if(( m_Tbl[bIndex].bWidth == 4 || m_Tbl[bIndex].bWidth==20) && 
				(((*(Baby>>i)).m_Value.GetByte())&0x03) != 0 ) {
				m_nErrCode = ERR_NOTHING;
				return FALSE;                                 
			}                                       
		} else {
			if(( m_Tbl[bIndex].bWidth == 2 || m_Tbl[bIndex].bWidth==20) && 
				(((*(Baby>>i)).m_Value.GetByte())&0x01) != 0 ) {
				m_nErrCode = ERR_NOTHING;
				return FALSE;                                 
			}
		}
		pTmpOb = new COpDealWriteDigit;
	    pTmpOb->SetValue((*(Baby>>i)).m_Value);
	    Baby.m_OpDealSet.Add(pTmpOb);		
	}
	
	return TRUE;
 } 
                              
int C196DADKeyMost::MAX_TABLE_NUM = 36;                              
CMDMOSTTBL C196DADKeyMost::m_Tbl[] =
	{                                                   //Hex Code
	{ "AND",    0x40,  2,  3 },  
	{ "ADD" ,   0x44,  2,  3 },
	{ "SUB",    0x48,  2,  3 },  
	{ "MULU" ,  0x4C,  20,  3 }, //IREG,WAOP
	{ "ANDB",   0x50,  1,  3 },  
	{ "ADDB" ,  0x54,  1,  3 },
	{ "SUBB",   0x58,  1,  3 },  
	{ "MULUB" , 0x5C,  10,  3 }, 
	{ "AND",    0x60,  2,  2 },  
	{ "ADD" ,   0x64,  2,  2 },
	{ "SUB",    0x68,  2,  2 },  
	{ "MULU" ,  0x6C,  20,  2 }, 
	{ "ANDB",   0x70,  1,  2 },  
	{ "ADDB" ,  0x74,  1,  2 },
	{ "SUBB",   0x78,  1,  2 },  
	{ "MULUB" , 0x7C,  10,  2 }, 
	{ "OR",     0x80,  2,  2 },  
	{ "XOR" ,   0x84,  2,  2 },
	{ "CMP",    0x88,  2,  2 },  
	{ "DIVU" ,  0x8C,  20,  2 },
	{ "ORB",    0x90,  1,  2 },  
	{ "XORB" ,  0x94,  1,  2 },
	{ "CMPB",   0x98,  1,  2 },  
	{ "DIVUB",  0x9C,  10,  2 },
	{ "LD",     0xA0,  2,  2 },  
	{ "ADDC" ,  0xA4,  2,  2 },
	{ "SUBC",   0xA8,  2,  2 },  
	{ "LDBZE" , 0xAC,  10, 2 },//WREG,BAOP
	{ "LDB",    0xB0,  1,  2 },  
	{ "ADDCB" , 0xB4,  1,  2 },
	{ "SUBCB",  0xB8,  1,  2 },  
	{ "LDBSE",  0xBC,  10, 2 },
	{ "ST",     0xC0,  2,  2 },  
	{ "STB" ,   0xC4,  1,  2 },
	{ "PUSH",   0xC8,  2,  1 },  
	{ "POP",    0xCC,  2,  1 },
	};                  


/********************** for class C196OpCodeAnalyse *******************************/
// 
//	CLASS NAME : C196OpCodeAnalyse
//
//  HEAD FILE  : dad196.H
//
/**************************************************************************/
C196OpCodeAnalyse::C196OpCodeAnalyse()
{ 
	m_pSFRByte = (CBaseDADSFRByte*)new C196DADSFRByte;
	m_pSFRBit = NULL;
	m_pSym = (CBaseDADSym*)new C196DADSym;  
	m_pConstSym = NULL;
	m_pAddress = (CDADAddress*)new C196DADAddrAnalyse;
	m_pDatum = new CDADDatum;
	m_pDollars = new CDADDOLLARS;
	m_p196RegIndirect = new C196DADRegIndirect;
	m_p196RegIndex = new C196DADRegIndex;
	
 }

C196OpCodeAnalyse::~C196OpCodeAnalyse()
{                                
	if (m_pSFRByte) delete m_pSFRByte;
	if (m_pSFRBit)  delete m_pSFRBit;
	if (m_pSym)  delete m_pSym;  
	if (m_pConstSym) delete m_pConstSym;
	if (m_pAddress) delete m_pAddress;
	if (m_pDatum) delete m_pDatum;
	if (m_pDollars) delete m_pDollars;
	if (m_p196RegIndirect) delete m_p196RegIndirect;
	if (m_p196RegIndex) delete m_p196RegIndex;
 }

BOOL C196OpCodeAnalyse::Do(CAnalyseInstruction& Baby,CDADAddress& BabyAddr)
{       
	//CHECK VALID               
	CString strInstr;
	COpSet* pOpSet;
	int nLen = Baby().GetSize();
	if(0 == nLen) {
		m_nErrCode = Baby.GetErrCode();
		return FALSE;
	}	
	
	//GET OPCODE
	for ( int i=1; i<nLen; i++ ) {
		pOpSet = NULL;
		
		strInstr = Baby()[i];
		ASSERT(0 != strInstr.GetLength());

		while (TRUE) {
			WORD wTmp;           
			CDADAddr tmpAddr;
			//check indirect
			tmpAddr = m_p196RegIndirect->StrToAddr(strInstr);
			if (C196DADRegIndirect::UNDEFINED != tmpAddr.m_bAttribute) {
				pOpSet = new COpSet;
				*pOpSet += (BYTE)tmpAddr.m_bAttribute;
				pOpSet->m_Value.SetByte((BYTE)(tmpAddr.m_dwAddr));
				Baby<<pOpSet;			
				break;
			}
			
			//check index
			tmpAddr = m_p196RegIndex->StrToAddr(strInstr);
			if (C196DADRegIndex::UNDEFINED != tmpAddr.m_bAttribute) {
				pOpSet = new COpSet;
				*pOpSet += (BYTE)tmpAddr.m_bAttribute;
				if (INDEX == tmpAddr.m_bAttribute)                        
					pOpSet->m_Value.SetByte((BYTE)(m_p196RegIndex->m_baseAddr.m_dwAddr));
				else {
					pOpSet->m_Value.SetWord((WORD)(m_p196RegIndex->m_baseAddr.m_dwAddr));
				}	
				pOpSet->m_Value.AddByte((BYTE)(tmpAddr.m_dwAddr));	
				Baby<<pOpSet;			
				break;
			}
						
			//check '$'  
			if ( TRUE == *(m_pDollars)<<strInstr) {
				pOpSet = new COpSet;
				*pOpSet += ADDR16;   
				WORD wTmp;
				switch (m_pDollars->m_cOperator) {
					case '+' : wTmp = BabyAddr.GetWord()+m_pDollars->m_Offset.GetWord();
							   break;
					case '-' : wTmp = BabyAddr.GetWord()-m_pDollars->m_Offset.GetWord();
							   break;		   
					default : ASSERT(FALSE);		   
				}   
				pOpSet->m_Value.SetWord(wTmp);
				Baby<<pOpSet;
				break;
			} 
			
			//check '#' datum
			wTmp = *(m_pDatum)<<strInstr;
			if ( 1 == wTmp ) {
				pOpSet = new COpSet;
				*pOpSet += DATA8;			
				*pOpSet += DATA16;
				pOpSet->m_Value.SetByte(m_pDatum->GetByte());						
				Baby<<pOpSet;
				break;
			}
			if ( 2 == wTmp ) {
				pOpSet = new COpSet;
				*pOpSet += DATA16;
				pOpSet->m_Value.SetWord(m_pDatum->GetWord());						
				Baby<<pOpSet;
				break;
			}         
			
			//check address
			tmpAddr = (*m_pAddress).StrToAddr(strInstr);
			if(C196DADAddrAnalyse::UNDEFINED != tmpAddr.m_bAttribute) {
				pOpSet = new COpSet;
				if(tmpAddr.m_dwAddr>0xff) {
					*pOpSet += ADDRX16;	
					*pOpSet += ADDR16;	
				    pOpSet->m_Value.SetWord((WORD)(tmpAddr.m_dwAddr));           
				} else {
					*pOpSet += ADDRI;
					*pOpSet += ADDRX16;
					*pOpSet += ADDR16;	
					if(tmpAddr.m_dwAddr<8) *pOpSet += BITOFFSET;	
					pOpSet->m_Value.SetByte((BYTE)(tmpAddr.m_dwAddr));           
				}
				                                                   
				Baby<<pOpSet;			
				break;
			}       
			
			//check symbol
			tmpAddr = *(m_pSym)<<strInstr;
			if(C196DADSym::UNDEFINED != tmpAddr.m_bAttribute) {
				pOpSet = new COpSet;   
				*pOpSet += tmpAddr.m_bAttribute;
				pOpSet->m_Value.SetWord((WORD)(tmpAddr.m_dwAddr)); 
				Baby<<pOpSet;			
				break;
			}
			
			//check byte SFR
			tmpAddr = *(m_pSFRByte)<<strInstr;
			if(C196DADSFRByte::UNDEFINED != tmpAddr.m_bAttribute
			   && 0xff >= tmpAddr.m_dwAddr) {
				if(NULL == pOpSet) pOpSet = new COpSet;
				*pOpSet+=ADDRI;	
				pOpSet->m_Value.SetByte((BYTE)tmpAddr.m_dwAddr);
				Baby<<pOpSet;			
				break;
			}
			
			m_nErrCode = ERR_OPCODE;			
			return FALSE;
		}//WHILE(TRUE)
		
	}//for   
	                                       
	ASSERT(nLen == (Baby.m_OpSetSet).GetSize()+1);
	if (nLen >4) {                          
		m_nErrCode = ERR_TOOMUCHOPCODE;
		return FALSE;	                              

	}
	for (int j = nLen; j<=3; j++) {
		pOpSet = new COpSet;
		*pOpSet += NONE;	
		Baby<<pOpSet;				
	}                  
	
	return TRUE;
	
 }	                                                                     

/********************** for class C196DAD *******************************/ 
// 
//	CLASS NAME : C196DAD
//
//  HEAD FILE  : dad196.H
//
/**************************************************************************/
BOOL C196DAD::ProcessAsm(CBaseDADMem& mem)
{ 
	if (!m_analyseInstr.Do(Baby,m_CurrentAddr)) {
		m_nDetailError = m_analyseInstr.GetErrCode();
		m_nError = ERR_PROCESS;
		return FALSE;
	}                
	                                                                     
	if (!m_keyMost.SelectByInstr(Baby) &&
		!m_keyAddrPg11.SelectByInstr(Baby) && 
		!m_keyAddrPg.SelectByInstr(Baby) &&
		!m_keyMisc.SelectByInstr(Baby) &&
		!m_keyShift.SelectByInstr(Baby) &&
		!m_keyOne.SelectByInstr(Baby) &&
		!m_keyAddr16.SelectByInstr(Baby) &&
		!m_keyMost2.SelectByInstr(Baby)) {
		m_nDetailError = m_keyMost.GetErrCode();
		m_nError = ERR_PROCESS;
		return FALSE;
	}                                    
	
	if (!Baby.Do(&m_CurrentAddr)) {
		m_nDetailError = Baby.GetErrCode();
		m_nError = ERR_PROCESS;
		return FALSE;
	}           
	
	int i = 0;
	int j = 0; 
	BYTE pByte[25];       
	for (i=0 ; i<Baby.m_bNum; i++) {
		pByte[j++] = (BYTE)(Baby.GetCode(i));
	}
	Baby.m_bNum = (BYTE)j;
	
	if (!mem.WriteBytes(pByte,(BYTE)j)) {
		m_nDetailError = mem.GetErrCode();
		m_nError = ERR_PROCESS;	          
		return FALSE;
	}   
	
	return TRUE;           
 }      
 
BOOL C196DAD::ProcessDisasm(CBaseDADMem& mem)
{                       
    for (int j = 0; j<m_bKeyTblNum; j++) {
RETRY:  if (m_pKey[j]->SelectByValue(Baby)) break;
		m_nDetailError = m_pKey[j]->GetErrCode();
		m_nError = ERR_PROCESS;    	
		if (CBaseDADKey::ERR_NEED_MORE_BYTE != m_nDetailError) continue;
		int nNeedNum = Baby.m_bNeedNum-Baby.m_bNum;
		for (int i = 0; i < nNeedNum; i++) {
			BYTE bType;
			if (!mem.ReadByte(bType)) {
				m_nDetailError = mem.GetErrCode();
				m_nError = ERR_PROCESS;	          
				return FALSE;
			};
			Baby.AddCode((DWORD)bType);
		}		
		goto RETRY;
    }
    
    if( m_bKeyTblNum == j ) return FALSE;
    
	if (!Baby.Do(&m_CurrentAddr)) {
		m_nDetailError = Baby.GetErrCode();
		m_nError = ERR_PROCESS;
		return FALSE;
	}
	
	//if ( Baby.m_bNeedNum  Baby.m_bNum )
	
	return TRUE;
 }          

BOOL C196DAD::PreDisasm(CBaseDADMem& mem) { 
	m_CurrentAddr.SetWord((mem.GetAddr()).m_bAttribute,
						(WORD)((mem.GetAddr()).m_dwAddr));
	return CBaseDAD::PreDisasm(mem);
}                                                                        
 

C196DAD::C196DAD()
{
    m_pKey[0] = &m_keyMost;
    m_pKey[1] = &m_keyAddrPg11;
    m_pKey[2] = &m_keyAddrPg;
    m_pKey[3] = &m_keyMisc;
    m_pKey[4] = &m_keyShift;
    m_pKey[5] = &m_keyOne;
    m_pKey[6] = &m_keyAddr16;
    m_pKey[7] = &m_keyMost2;
    m_bKeyTblNum = 8;
}
 
/********************** for class C196DADMem *******************************/ 
// 
//	CLASS NAME : C196DADMem
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/  
BOOL C196DADMem::WriteBytes(BYTE* pByte,BYTE bNum)
{                           
	ADDR tempAddr;
	RET_ADDR retAddr;
	tempAddr.addrType = m_curAddr.m_bAttribute;
	tempAddr.addr = m_curAddr.m_dwAddr;         
	//check address invalid
	if (!AdrCheckAddrRange(tempAddr)) {
		m_nErrCode = ERR_ADDR_INVALID;
		return FALSE;
	}	
	if (ICE_OK != ::emuSetMemN(tempAddr, pByte, bNum,&retAddr)) {
		m_nErrCode = ERR_MEM_WRITE;
		return FALSE;
	}         
	for (int i=0;i<bNum;i++)
		++(*this);
	return TRUE;
 }

BOOL C196DADMem::ReadByte(BYTE& bByte)
{              
	ADDR tempAddr;
	tempAddr.addrType = m_curAddr.m_bAttribute;
	tempAddr.addr = m_curAddr.m_dwAddr;
	//check address invalid
	if (!AdrCheckAddrRange(tempAddr)) {
		m_nErrCode = ERR_ADDR_INVALID;
		return FALSE;
	}
	if ( (m_curAddr.m_bAttribute != m_bufStart.m_bAttribute) ||
		 !(m_curAddr.m_dwAddr>=m_bufStart.m_dwAddr &&
		   m_curAddr.m_dwAddr<=m_bufStart.m_dwAddr+m_dwBufLen-1) ||
		 !isReadBufInvalid ) {
		if (!UpdateBuffer()) {
			m_nErrCode = ERR_MEM_READ;
			return FALSE;
		}
	}	 
	
	ASSERT(m_curAddr.m_bAttribute == m_bufStart.m_bAttribute &&
		   m_curAddr.m_dwAddr>=m_bufStart.m_dwAddr &&
		   m_curAddr.m_dwAddr<=m_bufStart.m_dwAddr+m_dwBufLen &&
		   isReadBufInvalid);
	
	bByte = m_pBuffer[m_curAddr.m_dwAddr-m_bufStart.m_dwAddr];
	++(*this);
	return TRUE;
 }                                    
 
BOOL C196DADMem::UpdateBuffer() 
{                                                
	ADDR tempAddr;                                          
	RET_ADDR retAddr;                          
	WORD len;
	tempAddr.addrType = m_curAddr.m_bAttribute;
	tempAddr.addr = m_curAddr.m_dwAddr;
	if ( (m_dwMax-m_curAddr.m_dwAddr+1) < BUFFERLEN )
		len = (WORD)(m_dwMax-m_curAddr.m_dwAddr+1);
	else len = BUFFERLEN;
	if (ICE_OK != ::emuGetMemN(tempAddr,len,m_pBuffer,&retAddr)) {
		m_nErrCode = ERR_MEM_READ;
		return FALSE;
	}                                                      
	
	m_bufStart.m_bAttribute = (BYTE)(tempAddr.addrType);
	m_bufStart.m_dwAddr = tempAddr.addr;
	m_dwBufLen = len;
	isReadBufInvalid = TRUE;
	return TRUE;
 }                                                                       

BOOL AdrCheckAddrRange(ADDR addr)
{ 
	ADDRESS addrTmp;
	addrTmp.adrSpace = (BYTE)(addr.addrType);
	addrTmp.adrAddress = addr.addr;  
	return TRUE;
	return AdrCheckAddrRange(addrTmp);
 }

/********************** for class C196DADKeyMisc *******************************/
// 
//	CLASS NAME : C196DADKeyMisc
//
//  HEAD FILE  : dad196.H
//
/**************************************************************************/
BOOL C196DADKeyMisc::SelectByValue(CAnalyseInstruction& Baby)
{ 
	BYTE bValue,bValue1;
	COpDealReadDigit* pTmpOb;
	//CNextIceAddr* pNextAddr;
	
	bValue = (BYTE)(Baby.GetCode(0));
	if(bValue == 0xf6) Baby.m_bNeedNum = 2;
	else Baby.m_bNeedNum = 1;
	//check length
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}
	
	if(bValue == 0xf6) bValue1 = (BYTE)(Baby.GetCode(1));
	
	for(int i=0; i<MAX_TABLE_NUM;i++) {
		if(m_Tbl[i].bCode == bValue) {
//			Baby.m_bNeedNum = 1;
			pTmpOb = new COpDealConstInstr(Baby,m_Tbl[i].pIntruction);
			Baby.m_OpDealSet.Add(pTmpOb);            	
			if(bValue == 0xf6) {
				C196DADDAtumAnalyse datum;                   
		    	datum.SetByte(bValue1);
		    	pTmpOb = new COpDealConstInstr(Baby,datum.GetStr());
		    	Baby.m_OpDealSet.Add(pTmpOb);
			}   
			if(i == 2 || i == 15) Baby.m_nInstructionType = CAnalyseInstruction::TYPE_JUMP;
			return TRUE;
		}
	}
	
	m_nErrCode = ERR_NOTHING;
	return FALSE;
	
 }

BOOL C196DADKeyMisc::SelectByInstr(CAnalyseInstruction& Baby)
{                  
	
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
	COpDealWriteDigit* pTmpOb;
	                                   
	for(int i=0; i<MAX_TABLE_NUM;i++) {
		if ( Baby()[0] == m_Tbl[i].pIntruction )
			if( (i==7 && (*(Baby>>0))(DATA8) && (*(Baby>>1))(NONE) && (*(Baby>>2))(NONE))  
			|| ( i!=7 && (*(Baby>>0))(NONE) && (*(Baby>>1))(NONE) && (*(Baby>>2))(NONE))  
	   		) {                                   
				pTmpOb = new COpDealWriteDigit;
				pTmpOb->SetByte(m_Tbl[i].bCode);
				Baby.m_OpDealSet.Add(pTmpOb);
				if(i==7) {                      
					pTmpOb = new COpDealWriteDigit;
					pTmpOb->SetByte((*(Baby>>0)).m_Value.GetByte());
					Baby.m_OpDealSet.Add(pTmpOb);
				}
				return TRUE;
			}	
	}	
	
	m_nErrCode = ERR_NOTHING;
	return FALSE;
	
 }                           

int C196DADKeyMisc::MAX_TABLE_NUM = 16;                              
CMDMISCTBL C196DADKeyMisc::m_Tbl[] =
	{                                                   //Hex Code
	{ "DPTS",    0xEC},
	{ "EPTS",    0xED},
	{ "RET",     0xF0},
	{ "PUSHF",   0xF2},
	{ "POPF",    0xF3},
	{ "PUSHA",   0xF4},
	{ "POPA",    0xF5},
	{ "IDLPD",   0xF6},
	{ "TRAP",    0xF7},
	{ "CLRC",    0xF8},
	{ "SETC",    0xF9},
	{ "DI",      0xFA},
	{ "EI",      0xFB},
	{ "CLRVT",   0xFC},
	{ "NOP",     0xFD},
	{ "RST",     0xFF}
	};                  

/********************** for class C196DADKeyOne *******************************/
// 
//	CLASS NAME : C196DADKeyOne
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL C196DADKeyOne::SelectByValue(CAnalyseInstruction& Baby)
{ 
	BYTE bValue,bIndex;
	COpDealReadDigit* pTmpOb;
	
	bValue = (BYTE)(Baby.GetCode(0));
	bIndex  = 0xff;
	
	for (int i = 0; i < MAX_TABLE_NUM; i++) {
		if (bValue == m_Tbl[i].bCode) {
			bIndex = (BYTE)i;
			break;
		}	
	}
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	//check length
	Baby.m_bNeedNum = 2;
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}
	
	pTmpOb = new COpDealConstInstr(Baby,m_Tbl[bIndex].pIntruction);
	Baby.m_OpDealSet.Add(pTmpOb);            	
	
    pTmpOb = new COpDeal196DASAddrI(Baby,m_Tbl[bIndex].bWidth,OP_W,1,1);
    Baby.m_OpDealSet.Add(pTmpOb);
    
    return TRUE;
	
 }

BOOL C196DADKeyOne::SelectByInstr(CAnalyseInstruction& Baby)
{                  
	COpDealWriteDigit* pTmpOb;
	BYTE bIndex = 0xff;
	
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
	
	for(int i = 0; i < MAX_TABLE_NUM; i++) {
	   if((Baby()[0] == m_Tbl[i].pIntruction)
	   	  && (*(Baby>>0))(ADDRI) 
	   	  && (*(Baby>>1))(NONE)
	   	  && (*(Baby>>2))(NONE) ) {
	       bIndex = (BYTE)i;
	       break;
	   }    
	}
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	
	if( m_Tbl[bIndex].bWidth == 2 && 
		((*(Baby>>0)).m_Value.GetByte())&0x01 != 0) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;                                                    
	}
	
	if( m_Tbl[bIndex].bWidth == 4) {
		BYTE bTmp = (*(Baby>>0)).m_Value.GetByte();
		bTmp = bTmp & 0x03;
		if (bTmp!=0) {
			m_nErrCode = ERR_NOTHING;
			return FALSE;                                                    
		}	
	}
	
	//for head code                               
	pTmpOb = new COpDealWriteDigit;
	pTmpOb->SetByte(m_Tbl[bIndex].bCode);
	Baby.m_OpDealSet.Add(pTmpOb);
	
	pTmpOb = new COpDealWriteDigit;
	pTmpOb->SetValue((*(Baby>>0)).m_Value);
	Baby.m_OpDealSet.Add(pTmpOb);
	
    return TRUE;
 }                           

int C196DADKeyOne::MAX_TABLE_NUM = 13;                              
CMDMOSTTBL C196DADKeyOne::m_Tbl[] =
    {                                                   //Hex Code
    { "SKIP" ,   0x0,  1,1},  
    { "CLR" ,   0x01,  2,1},  
    { "NOT" ,   0x02,  2,1},  
    { "NEG" ,  0x03,  2,1},  
    { "DEC" ,  0x05,  2,1},  
    { "EXT" , 0x06,  4,1},  
    { "INC" ,  0x07,  2,1},  
    { "CLRB" ,  0x11,  1,1},  
    { "NOTB" , 0x12,  1,1},
    { "NEGB" ,  0x13,  1,1},  
    { "DECB" , 0x15,  1,1},    
    { "EXTB" ,  0x16,  2,1},  
    { "INCB" , 0x17,  1,1},    
    };                  

/********************** for class C196DADKeyShift *******************************/
// 
//	CLASS NAME : C196DADKeyShift
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL C196DADKeyShift::SelectByValue(CAnalyseInstruction& Baby)
{ 
	BYTE bValue,bIndex;
	COpDealReadDigit* pTmpOb;
	
	bValue = (BYTE)(Baby.GetCode(0));
	bIndex  = 0xff;
	
	for (int i = 0; i < MAX_TABLE_NUM; i++) {
		if (bValue == m_Tbl[i].bCode) {
			bIndex = (BYTE)i;
			break;
		}	
	}
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	//check length
	Baby.m_bNeedNum = 3;
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}
	
	pTmpOb = new COpDealConstInstr(Baby,m_Tbl[bIndex].pIntruction);
	Baby.m_OpDealSet.Add(pTmpOb);            	
	
    pTmpOb = new COpDeal196DASAddrI(Baby,m_Tbl[bIndex].bWidth,OP_W,2,1);
    Baby.m_OpDealSet.Add(pTmpOb);
    
    BYTE bTmp = (BYTE)(Baby.GetCode(1));
    if(bTmp<=15) {
    	C196DADDAtumAnalyse datum;                   
    	datum.SetByte(bTmp);
    	pTmpOb = new COpDealConstInstr(Baby,datum.GetStr());
    	Baby.m_OpDealSet.Add(pTmpOb);
    } else {
    	pTmpOb = new COpDeal196DASAddrI(Baby,1,OP_R,1,1);
    	Baby.m_OpDealSet.Add(pTmpOb);
    }

    return TRUE;
	
 }

BOOL C196DADKeyShift::SelectByInstr(CAnalyseInstruction& Baby)
{                  
	COpDealWriteDigit* pTmpOb;
	BYTE bIndex = 0xff;
	
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
	
	for(int i = 0; i < MAX_TABLE_NUM; i++) {
	   if((Baby()[0] == m_Tbl[i].pIntruction)
	   	  && (*(Baby>>0))(ADDRI) 
	   	  && ( (*(Baby>>1))(ADDRI) || (*(Baby>>1))(DATA8) )
	   	  && (*(Baby>>2))(NONE) ) {
	       bIndex = (BYTE)i;
	       break;
	   }    
	}
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	
	if( m_Tbl[bIndex].bWidth == 2 && 
		((*(Baby>>0)).m_Value.GetByte())&0x01 != 0) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;                                                    
	}
	
	if( m_Tbl[bIndex].bWidth == 4) {
		BYTE bTmp = (*(Baby>>0)).m_Value.GetByte();
		bTmp = bTmp & 0x03;
		if (bTmp!=0) {
			m_nErrCode = ERR_NOTHING;
			return FALSE;                                                    
		}	
	}	
	
	BYTE bTmp = (*(Baby>>1)).m_Value.GetByte();
	if((*(Baby>>1))(ADDRI) && bTmp<=15) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	
	if((*(Baby>>1))(DATA8) && bTmp>15) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	
	//for head code                               
	pTmpOb = new COpDealWriteDigit;
	pTmpOb->SetByte(m_Tbl[bIndex].bCode);
	Baby.m_OpDealSet.Add(pTmpOb);
	
	pTmpOb = new COpDealWriteDigit;
	pTmpOb->SetByte(bTmp);
	Baby.m_OpDealSet.Add(pTmpOb);
	
	pTmpOb = new COpDealWriteDigit;
    pTmpOb->SetValue((*(Baby>>0)).m_Value);
    Baby.m_OpDealSet.Add(pTmpOb);			
	
    return TRUE;
 }                            

int C196DADKeyShift::MAX_TABLE_NUM = 9;                              
CMDMOSTTBL C196DADKeyShift::m_Tbl[] =
    {                                                   //Hex Code
    { "SHR" ,   0x08,  2,2},  
    { "SHL" ,   0x09,  2,2},  
    { "SHRA" ,  0x0A,  2,2},  
    { "SHRL" ,  0x0C,  4,2},  
    { "SHLL" ,  0x0D,  4,2},  
    { "SHRAL" , 0x0E,  4,2},  
    { "SHRB" ,  0x18,  1,2},  
    { "SHLB" ,  0x19,  1,2},  
    { "SHRAB" , 0x1A,  1,2}  
    };                  

/********************** for class C196DADKeyAddrPg11 *******************************/
// 
//	CLASS NAME : C196DADKeyAddrPg11
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL C196DADKeyAddrPg11::SelectByValue(CAnalyseInstruction& Baby)
{ 
	BYTE bValue;
	COpDealReadDigit* pTmpOb;
	
	bValue = (BYTE)(Baby.GetCode(0));
	if (0x20 != (bValue&0xf0)) { 
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}	
	
	
	//check length
	Baby.m_bNeedNum = 2;
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}
	
	pTmpOb = new COpDealConstInstr(Baby,bValue>0x27?"SCALL":"SJMP");
	Baby.m_OpDealSet.Add(pTmpOb);            	
	
    pTmpOb = new COpDeal196DASAddrPg11(Baby,2,bValue,1,1);
    Baby.m_OpDealSet.Add(pTmpOb);
    Baby.m_nInstructionType = CAnalyseInstruction::TYPE_JUMP;
    return TRUE;
	
 }

BOOL C196DADKeyAddrPg11::SelectByInstr(CAnalyseInstruction& Baby)
{                  
	COpDealWriteDigit* pTmpOb;
	BYTE bValue;
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
	
	if(Baby()[0] == "SJMP") bValue = 0x20;
	else if (Baby()[0] == "SCALL") bValue = 0x28;
	else return FALSE;
	
	if(!(*(Baby>>0))(ADDR16)) return FALSE;
	
	//for head code                               
	pTmpOb = new COpDealWriteDigit;
	pTmpOb->SetByte(bValue);
	Baby.m_OpDealSet.Add(pTmpOb);
	
	pTmpOb = new COpDeal196ASMAddrPg11;
	pTmpOb->SetByte(2);
	pTmpOb->AddValue((*(Baby>>0)).m_Value);
	Baby.m_OpDealSet.Add(pTmpOb);
	
    return TRUE;
 }                   
         
/********************** for class C196DADKeyAddrPg *******************************/
// 
//	CLASS NAME : C196DADKeyAddrPg
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL C196DADKeyAddrPg::SelectByValue(CAnalyseInstruction& Baby)
{ 
	BYTE bValue,bValue2;
	BYTE bIndex;
	COpDealReadDigit* pTmpOb;
	
	bValue2 = bValue = (BYTE)(Baby.GetCode(0));
	if (0x30 == (BYTE)(bValue&0xf0))
		bValue2 = (BYTE)(bValue&0xf8);
	bIndex = 0xff;
	
	for (int i = 0; i < MAX_TABLE_NUM; i++) {
		if (bValue2 == m_Tbl[i].bCode) {
			bIndex = (BYTE)i;
			break;
		}	
	}
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	
	//check length   
	if(bIndex <2 || bIndex>17) Baby.m_bNeedNum = 3;
	else Baby.m_bNeedNum = 2;
	
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}
	
	pTmpOb = new COpDealConstInstr(Baby,m_Tbl[bIndex].pIntruction);
	Baby.m_OpDealSet.Add(pTmpOb);            	
	
	if(m_Tbl[bIndex].bType>1) {
		pTmpOb = new COpDeal196DASAddrI(Baby,m_Tbl[bIndex].bWidth,OP_R,1,1);
    	Baby.m_OpDealSet.Add(pTmpOb);
	}
	
	if(bIndex<2) {                          
		char tmp[5];
		tmp[1] =0; tmp[0] = (char)('0' + (BYTE)(bValue&0x07));
		pTmpOb = new COpDealConstInstr(Baby,tmp);
    	Baby.m_OpDealSet.Add(pTmpOb);
	}
	
    pTmpOb = new COpDeal196DASAddrPg(Baby,Baby.m_bNeedNum,Baby.m_bNeedNum-1,1);
    Baby.m_OpDealSet.Add(pTmpOb);
    Baby.m_nInstructionType = CAnalyseInstruction::TYPE_MAYBE_JUMP; 
    return TRUE;
	
 }

BOOL C196DADKeyAddrPg::SelectByInstr(CAnalyseInstruction& Baby)
{                  
	COpDealWriteDigit* pTmpOb;
	BYTE bValue;
	BYTE bIndex = 0xff;     
	BYTE bBytes;
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
	
	for(int i = 0; i < MAX_TABLE_NUM; i++) {
	   if(Baby()[0] == m_Tbl[i].pIntruction) {
	       bIndex = (BYTE)i;
	       break;
	   }    
	}
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}         
	
	bBytes = 2;
	if(bIndex<2) {
		if(!(*(Baby>>0))(ADDRI) || !(*(Baby>>1))(BITOFFSET) || !(*(Baby>>2))(ADDR16) ) {
		    m_nErrCode = ERR_NOTHING;
			return FALSE;
			}
		bBytes = 3;		   
	} else if(bIndex > 17) {
		if(!(*(Baby>>0))(ADDRI) || !(*(Baby>>1))(ADDR16) || !(*(Baby>>2))(NONE)) {
		    m_nErrCode = ERR_NOTHING;
			return FALSE;
		}
		if(m_Tbl[bIndex].bWidth == 2 && (*(Baby>>0)).m_Value.GetByte()&0x01==0x01) {
		    m_nErrCode = ERR_NOTHING;
			return FALSE;
		}
		bBytes = 3;	   
	} else if(!(*(Baby>>0))(ADDR16) || !(*(Baby>>1))(NONE) || !(*(Baby>>2))(NONE)) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
	
	
	//for head code                               
	pTmpOb = new COpDealWriteDigit;
	if(bIndex<2) bValue = m_Tbl[bIndex].bCode + (*(Baby>>1)).m_Value.GetByte();
	else bValue = m_Tbl[bIndex].bCode;
	pTmpOb->SetByte(bValue);
	Baby.m_OpDealSet.Add(pTmpOb);
	
	if(m_Tbl[bIndex].bType>1) {
		pTmpOb = new COpDealWriteDigit;
		pTmpOb->SetByte((*(Baby>>0)).m_Value.GetByte());
		Baby.m_OpDealSet.Add(pTmpOb);		
	}
	
	pTmpOb = new COpDeal196ASMAddrPg;
	pTmpOb->SetByte(bBytes);
	pTmpOb->AddValue((*(Baby>>(m_Tbl[bIndex].bType-1))).m_Value);
	Baby.m_OpDealSet.Add(pTmpOb);
	
    return TRUE;
 }                         
   
int C196DADKeyAddrPg::MAX_TABLE_NUM = 20;                              
CMDMOSTTBL C196DADKeyAddrPg::m_Tbl[] =
    {                                                   //Hex Code
    { "JBC" ,   0x30,  1,3},  
    { "JBS" ,   0x38,  1,3},  
    { "JNST" ,  0xD0,  0,1},  
    { "JNH" ,   0xD1,  0,1},  
    { "JGT" ,   0xD2,  0,1},  
    { "JNC" ,   0xD3,  0,1},  
    { "JNVT" ,  0xD4,  0,1},  
    { "JNV" ,   0xD5,  0,1},  
    { "JGE" ,   0xD6,  0,1},  
    { "JNE" ,   0xD7,  0,1},  
    { "JST" ,   0xD8,  0,1},  
    { "JH" ,    0xD9,  0,1},  
    { "JLE" ,   0xDA,  0,1},  
    { "JC" ,    0xDB,  0,1},  
    { "JVT" ,   0xDC,  0,1},  
    { "JV" ,    0xDD,  0,1},  
    { "JLT" ,   0xDE,  0,1},  
    { "JE" ,    0xDF,  0,1},
    { "DJNZ" ,  0xE0,  1,2},  
    { "DJNZW" , 0xE1,  2,2}
    };                  

/********************** for class C196DADKeyAddr16 *******************************/
// 
//	CLASS NAME : C196DADKeyAddr16
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL C196DADKeyAddr16::SelectByValue(CAnalyseInstruction& Baby)
{ 
	BYTE bValue;
	COpDealReadDigit* pTmpOb;
	CString tmpStr;
	
	bValue = (BYTE)(Baby.GetCode(0));
	switch (bValue) {
		case 0xe2 : Baby.m_bNeedNum = 4; tmpStr="TIJMP"; break;
		case 0xe3 : Baby.m_bNeedNum = 2; tmpStr="BR"; break;
		case 0xe7 : Baby.m_bNeedNum = 3; tmpStr="LJMP"; break;
		case 0xef : Baby.m_bNeedNum = 3; tmpStr="LCALL"; break;
		default : m_nErrCode = ERR_NOTHING;
				  return FALSE;
	}
	
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}
	
	pTmpOb = new COpDealConstInstr(Baby,tmpStr);
	Baby.m_OpDealSet.Add(pTmpOb);            
	//TJMP LCALL
	if(Baby.m_bNeedNum == 3) {
	    pTmpOb = new COpDeal196DASAddr16(Baby,1,2,Baby.m_bNeedNum);
    	Baby.m_OpDealSet.Add(pTmpOb);                            
    	Baby.m_nInstructionType = CAnalyseInstruction::TYPE_JUMP;
    	return TRUE;
	}               
	//BR
	C196DADRegIndirect indirect;    
	CDADAddr tmpAddr;
	if(Baby.m_bNeedNum == 2) {              
		indirect.SetOption(2,OP_R);   
		tmpAddr = (DWORD)(Baby.GetCode(1));
		CString strTmp = indirect.AddrToStr(tmpAddr);
		if(strTmp[strTmp.GetLength()-1] == '+') {
			m_nErrCode = ERR_INVALID_REG;
			return FALSE;
		}
		pTmpOb = new COpDealConstInstr(Baby,strTmp);
    	Baby.m_OpDealSet.Add(pTmpOb);                        
    	Baby.m_nInstructionType = CAnalyseInstruction::TYPE_JUMP;
    	return TRUE;
	}	
	//for TIJMP                
	pTmpOb = new COpDeal196DASAddrI(Baby,2,OP_R,3,1);
    Baby.m_OpDealSet.Add(pTmpOb);     
    
    indirect.SetOption(2,OP_R);    
    tmpAddr = (DWORD)(Baby.GetCode(1));
	CString strTmp = indirect.AddrToStr(tmpAddr);
	if(strTmp[strTmp.GetLength()-1] == '+') {
		m_nErrCode = ERR_INVALID_REG;
		return FALSE;
	}
	pTmpOb = new COpDealConstInstr(Baby,strTmp);
	Baby.m_OpDealSet.Add(pTmpOb); 
	
	C196DADDAtumAnalyse datum;
	bValue = (BYTE)(Baby.GetCode(2));
	if(bValue>=0x80) {   
		m_nErrCode = ERR_INVALID_REG;
		return FALSE;
	}
	datum.SetByte(bValue); 
	pTmpOb = new COpDealConstInstr(Baby,datum.GetStr());
	Baby.m_OpDealSet.Add(pTmpOb);
    Baby.m_nInstructionType = CAnalyseInstruction::TYPE_JUMP;
    return TRUE;
	
 }

BOOL C196DADKeyAddr16::SelectByInstr(CAnalyseInstruction& Baby)
{                  
	COpDealWriteDigit* pTmpOb;
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
	
	if((Baby()[0] == "LCALL" || Baby()[0] == "LJMP") &&
		(*(Baby>>0))(ADDR16) && (*(Baby>>1))(NONE) && (*(Baby>>2))(NONE) ) {
		pTmpOb = new COpDealWriteDigit;
		if(Baby()[0] == "LCALL") pTmpOb->SetByte(0xef);
		else pTmpOb->SetByte(0xe7);
		Baby.m_OpDealSet.Add(pTmpOb);
		
		pTmpOb = new COpDeal196ASMAddr16;
		pTmpOb->SetByte(3);
		pTmpOb->AddWord((*(Baby>>0)).m_Value.GetWord());
		Baby.m_OpDealSet.Add(pTmpOb);
		return TRUE;
	}
	
	if( Baby()[0] == "BR" && (*(Baby>>0))(INDIRECT) && 
		(*(Baby>>1))(NONE) && (*(Baby>>2))(NONE) ) {
		pTmpOb = new COpDealWriteDigit;
		pTmpOb->SetByte(0xe3);
		Baby.m_OpDealSet.Add(pTmpOb);
		                               
		if ( ((*(Baby>>0)).m_Value.GetByte())&0x01 != 0 ) {
			m_nErrCode = ERR_INVALID_REG;
			return FALSE;
		}                  
		pTmpOb = new COpDealWriteDigit;
		pTmpOb->SetValue((*(Baby>>0)).m_Value);
		Baby.m_OpDealSet.Add(pTmpOb);
		return TRUE;
	}
	
	if( Baby()[0] == "TIJMP" && (*(Baby>>0))(ADDRI) && 
		(*(Baby>>1))(INDIRECT) && (*(Baby>>2))(DATA8) ) {
		pTmpOb = new COpDealWriteDigit;
		pTmpOb->SetByte(0xe2);
		Baby.m_OpDealSet.Add(pTmpOb);
		//[index]                               
		if ( ((*(Baby>>1)).m_Value.GetByte())&0x01 != 0 ) {
			m_nErrCode = ERR_INVALID_REG;
			return FALSE;
		}                  
		pTmpOb = new COpDealWriteDigit;
		pTmpOb->SetValue((*(Baby>>1)).m_Value);
		Baby.m_OpDealSet.Add(pTmpOb);
		//#mask         
		if ( ((*(Baby>>2)).m_Value.GetByte())>=0X80 ) {
			m_nErrCode = ERR_INVALID_REG;
			return FALSE;
		}
		pTmpOb = new COpDealWriteDigit;
		pTmpOb->SetByte((*(Baby>>2)).m_Value.GetByte());
		Baby.m_OpDealSet.Add(pTmpOb);
		//tbase   
		if ( ((*(Baby>>0)).m_Value.GetByte())&0x01 != 0 ) {
			m_nErrCode = ERR_INVALID_REG;
			return FALSE;
		}
		pTmpOb = new COpDealWriteDigit;
		pTmpOb->SetValue((*(Baby>>0)).m_Value);
		Baby.m_OpDealSet.Add(pTmpOb);
		return TRUE;
	}
	
	m_nErrCode = ERR_NOTHING;
    return FALSE;
 }                         


/********************** for class C196DADKeyMost2 *******************************/
// 
//	CLASS NAME : C196DADKeyMost2
//
//  HEAD FILE  : DAD196.H
//
/**************************************************************************/
BOOL C196DADKeyMost2::SelectByValue(CAnalyseInstruction& Baby)
{   
	BYTE bValue,bValue2;
	BYTE bIndex = 0xff;
	COpDealReadDigit* pTmpOb;
	CString tmpStr;
	
	bValue = (BYTE)(Baby.GetCode(0));
	for (int i = 0; i < MAX_TABLE_NUM; i++) {
		if (bValue == m_Tbl[i].bCode) {
			bIndex = (BYTE)i;
			break;
		}	
	}
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
    
	Baby.m_bNeedNum = 3;
	
	if ( Baby.m_bNeedNum > Baby.m_bNum ) {
		m_nErrCode = ERR_NEED_MORE_BYTE;
		return FALSE;
	}
    
	pTmpOb = new COpDealConstInstr(Baby,m_Tbl[bIndex].pIntruction);
	Baby.m_OpDealSet.Add(pTmpOb);             
	
	C196DADRegIndirect indirect;    
	CDADAddr tmpAddr;
	bValue = (BYTE)Baby.GetCode(1);
	bValue2 = (BYTE)Baby.GetCode(2);
	
	/*if((m_Tbl[bIndex].bWidth0==4 && bValue2&0x03!=0) ||
		(m_Tbl[bIndex].bWidth0==2 && bValue2&0x01!=0) ) {
		m_nErrCode = ERR_INVALID_REG;
		return FALSE;
	}*/
		
	tmpAddr = (DWORD)(bValue2);
	pTmpOb = new COpDeal196DASAddrI(Baby,m_Tbl[bIndex].bWidth0,bIndex<6?OP_RW:OP_W,2,1);
	Baby.m_OpDealSet.Add(pTmpOb);
	
	if(m_Tbl[bIndex].bOp1 == ADDRI) {
		/*if(m_Tbl[bIndex].bWidth1==4 && bValue&0x03!=0) {
			m_nErrCode = ERR_INVALID_REG;
			return FALSE;
		}*/
		pTmpOb = new COpDeal196DASAddrI(Baby,m_Tbl[bIndex].bWidth1,bIndex<6?OP_RW:OP_R,1,1);
    	Baby.m_OpDealSet.Add(pTmpOb);     
	} else {                                                          
		/*if((m_Tbl[bIndex].bWidth1==4 && bValue&0x03!=0) ||
			(m_Tbl[bIndex].bWidth1==2 && bValue&0x01!=0) ) {
			m_nErrCode = ERR_INVALID_REG;
			return FALSE;
		}*/
		tmpAddr = (DWORD)(bValue);
		indirect.SetOption(m_Tbl[bIndex].bWidth1,bIndex<6?OP_RW:OP_R);               
		pTmpOb = new COpDealConstInstr(Baby,indirect.AddrToStr(tmpAddr));
		Baby.m_OpDealSet.Add(pTmpOb);             
	}	
	
	return TRUE;                                            
 }

BOOL C196DADKeyMost2::SelectByInstr(CAnalyseInstruction& Baby)
{                  
	COpDealWriteDigit* pTmpOb;
	ASSERT(Baby.m_OpSetSet.GetSize()==3);              
    BYTE bIndex = 0xff;
	
	for(int i = MAX_TABLE_NUM-1; i >=0; i--) {
	   if(Baby()[0] == m_Tbl[i].pIntruction &&
	   	  (*(Baby>>0))(m_Tbl[i].bOp0) &&
	   	  (*(Baby>>1))(m_Tbl[i].bOp1) &&
	   	  (*(Baby>>2))(NONE) ) {
	   	   bIndex = (BYTE)i;
	   	   break;
	   }//if
	}//for          
	
	if (0xff == bIndex) {
		m_nErrCode = ERR_NOTHING;
		return FALSE;
	}
    
    pTmpOb = new COpDealWriteDigit;
	pTmpOb->SetByte(m_Tbl[bIndex].bCode);
	Baby.m_OpDealSet.Add(pTmpOb);
    
    C196DADRegIndirect indirect;    
	CDADAddr tmpAddr;
    if(m_Tbl[bIndex].bOp1 == ADDRI) {
    	if((m_Tbl[bIndex].bWidth1 == 2 && 
		   (((*(Baby>>1)).m_Value.GetByte())&0x01) != 0) || 
		   (m_Tbl[bIndex].bWidth1 == 4 && 
		   (((*(Baby>>1)).m_Value.GetByte())&0x03) != 0)) {
		    m_nErrCode = ERR_INVALID_REG;
			return FALSE;                                
		}	
		pTmpOb = new COpDealWriteDigit;
    	pTmpOb->SetValue((*(Baby>>1)).m_Value);
    	Baby.m_OpDealSet.Add(pTmpOb);			
    } else {
    	pTmpOb = new COpDealWriteDigit;
	    pTmpOb->SetValue((*(Baby>>1)).m_Value);
	    Baby.m_OpDealSet.Add(pTmpOb);	
    }
    
    if((m_Tbl[bIndex].bWidth0 == 2 && 
	   (((*(Baby>>0)).m_Value.GetByte())&0x01) != 0) || 
	   (m_Tbl[bIndex].bWidth0 == 4 && 
	   (((*(Baby>>0)).m_Value.GetByte())&0x03) != 0)) {
	    m_nErrCode = ERR_INVALID_REG;
		return FALSE;                                
	}	
	
    pTmpOb = new COpDealWriteDigit;
    pTmpOb->SetValue((*(Baby>>0)).m_Value);
    Baby.m_OpDealSet.Add(pTmpOb);			
    
    return TRUE;
	
 }                         

int C196DADKeyMost2::MAX_TABLE_NUM = 10;
CMDMOSTTBL2 C196DADKeyMost2::m_Tbl[] =
	{                                                   //Hex Code
	{ "XCH",    0x04,  ADDRI,  ADDRI, 2, 2 },  
	{ "XCH" ,   0x0B,  ADDRI,  INDIRECT, 2, 2 },
	{ "XCH" ,   0x0B,  ADDRI,  INDIRECT_PLUS, 2, 2 },
	{ "XCHB",   0x14,  ADDRI,  ADDRI, 1, 1 },  
	{ "XCHB",   0x1B,  ADDRI,  INDIRECT, 1, 1 },  
	{ "XCHB",   0x1B,  ADDRI,  INDIRECT_PLUS, 1, 1 },  
	{ "BMOV",   0xC1,  ADDRI,  ADDRI, 4, 2 },  
	{ "CMPL" ,  0xC5,  ADDRI,  ADDRI, 4, 4 },
	{ "BMOVI",  0xCD,  ADDRI,  ADDRI, 4, 2 },
	{ "NORML",  0x0F,  ADDRI,  ADDRI, 4, 1 }
	};                  

#ifdef __cplusplus
extern "C" {
#endif	// __cplusplus
//add 1997.5.15 to support step
// if return TRUE, ret = call address
BOOL WINAPI IsScall(ADDR pc,ADDR& ret ) {   
	BYTE mem[20];       
	RET_ADDR retAddr;
	if(ICE_OK != emuGetMemN(pc,2,mem,&retAddr)) return FALSE;
	if(0x28 != (mem[0]&0xf8)) return FALSE;
	
	C196DADAddrAnalyse addr;
	WORD wAddr,wNextAddr;             
	BYTE bLen = 2; 
	WORD wOffset = (WORD)(mem[1] + (WORD)((mem[0]&0x07)<<8));
	unsigned short usOffset = ((wOffset&0x0400) == 0) ? 
							  (unsigned short)(wOffset&0x03ff) :
							  (unsigned short)(wOffset|0xf800); 
	//make next addr
	wNextAddr = pc.addr + 2;
	//make jmp addr
	wAddr = wNextAddr + (signed short)usOffset;     
	ret.addrType = pc.addrType;
	ret.addr = wAddr;
	                                  
	return TRUE;
	
		
}

//add 1997.5.15 to support step
// if return TRUE, ret = call address
BOOL WINAPI IsLcall(ADDR pc,ADDR& ret ) {   
	BYTE mem[20];       
	RET_ADDR retAddr;
	if(ICE_OK != emuGetMemN(pc,3,mem,&retAddr)) return FALSE;
	if(0xef != (mem[0]&0xef)) return FALSE;
	
	C196DADAddrAnalyse addr;
	WORD wAddr,wNextAddr;             
	BYTE bLen = 3; 
	WORD wOffset = (WORD)(mem[1] + (WORD)(((WORD)mem[2])<<8));
	//make next addr
	wNextAddr = pc.addr + 3;
	//make jmp addr
	wAddr = wNextAddr + (signed short)wOffset;     
	ret.addrType = pc.addrType;
	ret.addr = wAddr;
	                                  
	return TRUE;
	
}
#ifdef __cplusplus
}
#endif	// __cplusplus
/***********************  end of file **********************************/