/********************** 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();                                 
};


/********************** 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;
 }                                                                       

