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

/***************************************************************************
**
** File name :  PERBASE.CPP
**
** Author:      Richard Guo
** Description: basic functions for peripheral window.
**
** coding from: Oct 24, 1996
** Finished date:
**
**
**    Copyright (C) 1996 Microtek International, Inc.
**    All Rights Reserved
**                        
****************************************************************************/

#include "stdafx.h"
#include <assert.h>    
#include <ctype.h>

#include "perbase.h"
#include "regsvr.h" 
#include "abiextfn.h"
#include "cpusvr.h"

/////////////////////////////////////////////////////////////////////////////
//
//  Name:  gstrtok()  
//
//  Description: retrieve token defined in szToken from szBuffer
//				 szBuffer will be modified when this function is called
//
//  Input: szBuffer  source character buffer 
//		   szToken   comprise all user defined token
//
//  Output: szBuffer move to next token beginning.
//
//  Return: NULL means failure.
//			Else return first string meeting the condition.
//                                           
//  Notes: Be sure szBuffer is only a pointer, not static char pointer .
//		   I do not use strtok() because it will bring you unwanted results
//		   when you call other function which also calls strtok between a
//		   serial of strtok() calls.
//
/////////////////////////////////////////////////////////////////////////////
        
char* gstrtok(char* &szBuffer, char* szToken)
{
	char* szDes = szBuffer;
	
	if (!*szBuffer) return NULL;
	if(szToken != NULL)
		while(*szBuffer){
			char *szTemp = szToken;
			while(*szTemp)
				if (*szBuffer == *szTemp){
					szDes[szBuffer-szDes] = '\0';
					szBuffer++;
					return szDes;
				}         
				else szTemp++;
			szBuffer++;
		}
	return szDes;			
}

void RegBitStartLen(const char* szBitInfo, WORD& wStart, WORD& wLen)
{
	char* szCur = strchr(szBitInfo, '-'); 
	
	wStart = (WORD)atoi(szBitInfo);
	if (szCur == NULL)
		wLen = 1;
	else {
		wLen = (WORD)atoi(szCur+1);
		wLen = wLen - wStart + 1;
	} 
}  

/*
BOOL MergeBitName(WORD wSerialNo, BYTE byBitFrom, BYTE byBitTo, char* szName)
{
	assert(byBitTo >= byBitFrom);
	
	char szBitTo[15];
	if (GetRegBitName(wSerialNo, byBitTo, szBitTo)){    
		if (byBitTo==byBitFrom){
			strcpy(szName, szBitTo);
			return TRUE;
		}
		
		int nToSite = strRevIndig(szBitTo);
		assert(nToSite > 0);
		
		char szBitFrom[15];
		GetRegBitName(wSerialNo, byBitFrom, szBitFrom);
		int nFromSite = strRevIndig(szBitFrom);
		assert(nFromSite > 0);  
		              		
        // Code below may be strange for some bits have two names.
		if (nToSite < nFromSite){
			strncpy(szName, szBitTo, nToSite);  
			wsprintf(szName+nToSite, "%s-%s", szBitFrom+nFromSite, 
					szBitTo+nToSite);  
			}
		else{ 
			strncpy(szName, szBitFrom, nFromSite);
			wsprintf(szName+nFromSite, "%s-%s", szBitFrom+nFromSite, 
					szBitTo+nToSite);  
			}
	}
	else{ 
		GetRegName(wSerialNo, szName);
		wsprintf(szName+strlen(szName), "%1d-%1d", byBitFrom, byBitTo);
	}
	
	return 0;
}
*/		

int strRevIndig(const char* szSrc)
{
	assert(szSrc != NULL);
	int nLen = strlen(szSrc);   
	for(int i=1; i<=nLen; i++){
		if (isdigit(szSrc[nLen-i]) || (szSrc[nLen-i]=='.')) 
			continue;
		break;
	}
	
	return nLen-i+1;	
}

BOOL MergeRegAddr(WORD wSerialNo, char* szAddr)
{                               
	CRegItem regInfo;
	
	regInfo.wSerial = wSerialNo;

	szAddr[0] = '\0';
	
	if (!ByteFromRegID(&regInfo)) return FALSE;	
	
	if (regInfo.wType == 0) // undefined
		return TRUE;
		
	switch(regInfo.wLen){
		case 1:
//			wsprintf(szAddr, "%lXH", regInfo.dwAddr);
//			break;
		case 2:
//			wsprintf(szAddr, "%lXH", regInfo.dwAddr);
//			break;
		case 4:
			wsprintf(szAddr, "%04lXH", regInfo.dwAddr);
			break;
	}			
	
	return TRUE;
}

/*
BOOL GetRegValue(WORD wSerial, DWORD& wValue)
{
	if (emuGetReg(0, wSerial, &wValue)==ICE_OK) 
		return TRUE;
	else return FALSE;
}   
*/

BOOL SetRegValue(WORD wSerial, DWORD wValue)
{
	if(emuSetReg(0, wSerial, wValue)==ICE_OK)
		return TRUE;
	else return FALSE;
}

BOOL GetRegLen(WORD wSerial, int& nLen)
{
	CRegItem regInfo;
	
	regInfo.wSerial = wSerial;
	
	nLen = 1;
	
	if (!ByteFromRegID(&regInfo)) return FALSE;	
	
	nLen = (int)regInfo.wLen;
	
	return TRUE;
}

void GetRegBitName(const char* szStr, BYTE bySite, char* szName)
{
	char* szTemp;
	
	char szBuf[20];
	
	szTemp = strchr(szStr, ' ');
	ASSERT(szTemp != NULL);
	
	strncpy(szBuf, szStr, szTemp-szStr); 
	szBuf[szTemp-szStr] = '\0';
	
	szTemp = strchr(szBuf, '-');
	
	
	if (szTemp){       
        char* szOld = szTemp;
        
		while(isdigit(*(szTemp-1))) szTemp--;
		
		if (szOld != szTemp){
			BYTE byBase = (BYTE)atoi(szTemp);
					
			strncpy(szName, szBuf, szTemp-szBuf);
			wsprintf(szName+(szTemp-szBuf), "%d", bySite+byBase);
		}
		else{
			if (bySite==0){
				strncpy(szName, szBuf, szOld-szBuf);
				szName[szOld-szBuf] = '\0';
			}
			else strcpy(szName, szOld+1); 
		}
	}
	else strcpy(szName, szBuf);
}

DWORD Hex2Dec(char* reg_value)
{      
   DWORD sum=0;
   int i=0; 
   
   while( reg_value[i] == ' ') i++;
   
   while(  (reg_value[i] !=' ') &&(reg_value[i] !='H') && (reg_value[i] !='\0') )
   {   
       sum*=16;
       switch(reg_value[i]){
              case '0': sum+=0; 
                        break; 
              case '1': sum+=1;
                        break;
              case '2': sum+=2;
                        break;
              case '3': sum+=3;
                        break;
              case '4': sum+=4;
                        break;
              case '5': sum+=5;          
                        break;
              case '6': sum+=6;
                        break;
              case '7': sum+=7;
                        break;
              case '8': sum+=8;
                        break;
              case '9': sum+=9;
                        break;
              case 'A': sum+=10;
                        break;
              case 'B': sum+=11;
                        break;
              case 'C': sum+=12;
                        break;
              case 'D': sum+=13;
                        break;
              case 'E': sum+=14;
                        break;
              case 'F': sum+=15;
                        break;
           }

       
      i++;    
   }
   return sum;
}                                       

int CheckString(CString string, DWORD dwMaxVal)
{
	int len,i=0; 
	len=string.GetLength();
	DWORD sum=0;
	
//	string.MakeUpper();
	  
    if(NULL==strstr( string.GetBuffer(16), "0X" )) //Decimal
    {
 	   string.ReleaseBuffer();
   	   while((i<len) && (string[i]==' ')) i++; 
	   
	   while( (i<len) && ((string[i]>='0') &&(string[i]<='9')) )
		{
		   sum *= 10;
		   sum += string[i]-'0';
		   i++;      
		 }
       while( i<len ) 
         if(string[i]==' ')  i++; 
         else return PER_INVALID_CARD; // invalid input

	 }
	 else
	 {
      	string.ReleaseBuffer();
	    while((i<len) && (string[i]==' ')) i++; 
	    if (i<len-2){
	    	if ((string[i]!='0') && (string[i+1]!='X'))
				return PER_INVALID_CARD;
			i += 2;
		}
		else return PER_INVALID_CARD;	    		
	    
	    while( (i<len) && (((string[i]>='0')&&(string[i]<='9'))||
	    	   ((string[i]<='F')&&(string[i]>='A'))) )
	    {
		   sum *= 16;			   		
		   if ((string[i]>='0') && (string[i]<='9'))
		   		sum += (string[i]-'0');
		   else
		   		sum += 10 + (string[i]-'A');
		   i++;     
		 }              
		                     
	    while( i<len ) 
	       if(string[i]==' ')  i++; 
	    else return PER_INVALID_CARD;
	    
	  } 
	  
	  if (sum > dwMaxVal) return PER_TOO_LARGE;
	  
	  return PER_OK;
}	


#ifdef __cplusplus
extern "C" {
#endif	// __cplusplus                                       

int WINAPI GetCurHWindow()
{
	WORD wCpuID;
	
	wCpuID = GetCpuId();
	
	if ((wCpuID <= EP9X_CPUID_END) || (wCpuID >= EP196MC_CPUID_START))
		return 0;
		
	// Assume WSR serial number is 22
	DWORD dwValue;
	BYTE  byValue;
	if (!GetRegValue(22, dwValue))
		dwValue = 0;
		
	byValue = (BYTE)dwValue;	     
		
//	if (wCpuID <= EP196KA_CPUID_END)
//	{
//	}
	if (wCpuID <= EP196KB_CPUID_END)
	{
		return (int)byValue;
	}
	else if (wCpuID <= EP196KC_CPUID_END)
	{
		if ((byValue & 0x70) == 0)
			return (int)(byValue & 0xf);
		else return 0;
	}
	else return 0;
}

#ifdef __cplusplus
}
#endif	// __cplusplus          
	
/***********************end of file****************************/