
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/LDR.CPP   1.8   20 Jun 1996 09:24:50   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/LDR.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:24:50   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.7   11 Jun 1996 10:29:22   ZJRD
** EasyPack/SLD Version 1.97
** 
**    Rev 1.5   05 Jun 1996 14:58:00   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:28:34   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:05:48   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:11:50   ZJRD
** EasyPack/SLD Version 1.93
** 
**    Rev 1.1   02 May 1996 10:27:12   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 13:00:52   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:38:46   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:51:42   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:06:10   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:32:42   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:46:56   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:13:30   Shirley
** EasyPack/SLD Version 0.35b
** 
**    Rev 1.23   26 Jan 1996 09:17:44   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:17:40   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:37:06   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:27:36   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.19   18 Jan 1996 10:10:52   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:11:52   Shirley
** EasyPack/SLD Version 0.34a
** 
**    Rev 1.17   04 Jan 1996 11:11:26   Shirley
** EasyPack/SLD Version 0.34
** 
**    Rev 1.16   30 Nov 1995 09:08:52   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:31:40   Shirley
** EasyPack/SLD Version 0.32
** 
**    Rev 1.14   21 Nov 1995 11:18:20   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:24:02   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:32:12   Shirley
** EasyPack/SLD Version 0.24
** 
**    Rev 1.11   08 Nov 1995 16:34:16   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:44:12   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:05:06   Shirley
** EasyPack/SLD Version 0.21
** 
**    Rev 1.8   27 Oct 1995 16:51:00   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:44:46   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:32:00   Shirley
** EasyPack/SLD Version 0.1f
** 
**    Rev 1.5   18 Oct 1995 14:47:52   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:20:10   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:50:40   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:53:24   Shirley
** EasyPack/SLD Version 0.1b
** 
**    Rev 1.1   15 Sep 1995 09:48:06   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:54:28   Shirley
** Initial revision.
**
****************************************************************************/

/****************************************************************************
**
**  Name:  LDR.CPP
**
**  Description:
**      Entry points for Loader.
**
**  Status:  CODED
**
**    Rev 1.0   1 Sept. 1995 8:30:00am   Gates Hua, Jamoon Chow
** Initial revision.
**
**  Copyright (C) 1995 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdafx.h"
#include <stdarg.h>
#include <ctype.h>
#include <sys\types.h>
#include <sys\stat.h>
//#include <io.h>
//#include <sys\timeb.h>
//#include <time.h>

#include "symblsvr.h"
#include "ldr.h"
#include "uicom.h"
#include "abibase.h"
#include "hosterrs.h"
                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
/*
** Note:  all data global to this file will either be recycled/reset on
** a new load invocation, and destroyed/deallocated at the end of this load.
*/
class LoaderServer ldrObject;   // global load object .

SYM_DESCRIPTOR curModDesc;

U16 uSrcLineNum = 0;
U32 uLoadBytes = 0L;

//U32 startPC;
//U32 stackTop, stackSize;
//BOOLEAN hasStackInfo;


                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

// extern char *strLineFileName , *strSymFileName;

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

void LoadCmd(int nArgc, char* pszArgv[]);
RETCODE LdrLoadModuleByDesc(SYM_DESCRIPTOR moduleDesc);
int SrcIsLoaded(void);
int SrcIsStatement(void);
int SrcIsIEEE(void);
int SrcGetLoadPath( CString& str );
int SrcGetStartAddress( U32& addr );
int SrcOpenFile(U32 inputSymbol);
int SrcReadLine(char *buff);

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

extern STATUS AbiSetReg(int iRegId, UINT uRegValue);
//extern void prn_err( int num );
//extern void win_err( int num ); 
extern void InitVarExtendLink( void );
extern void ClearStkAndVar(void);
extern void SrcResetView(void);
extern void SrcSetLoadFileName(const char * str);
//extern void ErrShow(U32 errorCode,BOOL bUI);
extern BOOL GetCpuStatus(unsigned char & uchStatus);

/***************************************************************************
*                                                                          *
*  LoadCmd - Shell Window Load Command  entry pointer                      *
*                                                                          *
*  parameter :                                                             *
*       input :                                                            *
*           argc - argument count                                          *
*           argv - argument string array                                   *
*                                                                          *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoadCmd(int nArgc, char* pszArgv[])
{
    ldrObject.LoadCmd(nArgc , pszArgv);
}   

/***************************************************************************
*                                                                          *
*  LoaderServer - LoaderServer initial routine                             *
*                                                                          *
*  parameter :                                                             *
*       None                                                               *
*                                                                          *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
LoaderServer::LoaderServer() 
{                           
	m_bSpecSymbol = FALSE;		// skip processing ?-symbol
    m_dwErrorNum = 0;
    m_loaderFile = -1;
    m_compilerUser = LFILE_UNKNOWN; 
    m_IsLoaded = FALSE;
    m_addrunit = 2; 
    m_absflag = 0;
    m_startaddress = 0;
    m_ldrFlags = LDR_DEFAULT;     
    m_window = LOAD_FROM_DIALOG;  
    m_lpBuffer = 0;
    m_uBufInFilePos = 0;
    m_uBufSize = 0;
    m_uBufPos = 0;
    m_version = 0;
    m_lpFileName = 0;
    m_lpFileRef = 0;
    m_lpModuleName = 0;
    m_lpModuleRef = 0;   
    m_onDemand = TRUE;
    m_time.year = -1;
    m_time.hour = -1;
                     
    m_typeDelta = 0;                     
    m_typeNum = 0;
    m_symbolNo = 0; 
    m_typeNo = 0;
    m_moduleNo = 0;
	m_lstFileInfo = NULL;
	
    m_pSec = 0;
    m_pCurrentSec = 0;
}

/***************************************************************************
*                                                                          *
*  ~LoaderServer - LoaderServer free memory routine                        *
*                                                                          *
*  parameter :                                                             *
*       None                                                               *
*                                                                          *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
LoaderServer::~LoaderServer()                      
{
    ClearUp();
}

/***************************************************************************
*                                                                          *
*  ClearUp - Delete All Memory                                             *
*                                                                          *
*  parameter :                                                             *
*       None                                                               *
*                                                                          *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::ClearUp(void)
{                   
    LoadInit();
    m_typeDelta = 0;
    m_typeNum = 0;
    if ( m_lpFileName ) {
        delete m_lpFileName;
        m_lpFileName = 0;
    }
    if ( m_lpFileRef ) {
        delete m_lpFileRef;
        m_lpFileRef = 0;
    }
    if ( m_lpModuleName ) {
        delete m_lpModuleName;
        m_lpModuleName = 0;
    }
    if ( m_lpModuleRef ) {
        delete m_lpModuleRef;
        m_lpModuleRef = 0;
    }
/*    done in LoadInit()
    if ( ClearUpModuleBlock() == FAILURE )
        return FAILURE;
    if ( m_loaderFile != -1 ) {
        if ( CloseLoadFile() == FAILURE )
            return FAILURE;
    }   
    if ( m_lpBuffer ) {
        delete m_lpBuffer;
        m_lpBuffer = 0;
        m_uBufInFilePos = 0;
        m_uBufPos = 0;
        m_uBufSize = 0; 
    }
*/
    return GOOD;
}

/***************************************************************************
*                                                                          *
*  ClearUpModuleBlock - Delete All Memory of ModuleBlock node              *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::ClearUpSec(void)
{
    struct SEC_INFO *temp;
    
    temp = m_pSec;
    while( temp ) {
        m_pSec = temp;
        if ( temp->str ) delete temp->str;
        temp->str = 0;
        temp = temp->next;
        delete m_pSec;
        m_pSec = 0;
    }        
    m_pSec = 0;
    m_pCurrentSec = 0;
    return GOOD;
}

/***************************************************************************
*                                                                          *
*  ClearUpModuleBlock - Delete All Memory of ModuleBlock node              *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::ClearUpModuleBlock(void)
{             
    if ( m_modNode.name ) {
        delete m_modNode.name;
        m_modNode.name = 0;
    }
    if ( m_modNode.lpblock ) {
        if ( ClearUpBlockBlock(m_modNode.lpblock) == FAILURE )
            return FAILURE;                           
        delete m_modNode.lpblock;   
        m_modNode.lpblock = 0;
    }
    if ( m_lstFileInfo ) {
    	delete m_lstFileInfo;
    	m_lstFileInfo = NULL;
    }
    return GOOD;
}

/***************************************************************************
*                                                                          *
*  ClearUpBlockBlock - Delete All Memory of BlockBlock node                *
*  parameter :                                                             *
*       node  --  free memory of the BlockBlock node link                  *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::ClearUpBlockBlock(struct BlockBlock far *node)
{                                                        
    if ( node->funcName ) {
        delete node->funcName;
        node->funcName = 0;
    }
    if ( node->son ) {
        if ( ClearUpBlockBlock(node->son) == FAILURE )
            return(FAILURE);        
        delete node->son;   
        node->son = 0;
    }
    if ( node->next ) {
        if ( ClearUpBlockBlock(node->next) == FAILURE )
            return(FAILURE);  
        delete node->next;  
        node->next = 0;
    }
    return(GOOD);
}

/***************************************************************************
*                                                                          *
*  DistinguishCompiler - Distinguish loader file compiler                  *
*  parameter :                                                             *
*       None ( result in class LoaderServer member compilerUser )          *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::DistinguishCompiler(void)
{   
    U8 ch;
/*    
    if ( _lread(m_loaderFile , &ch , 1) == HFILE_ERROR ) {
        return(FAILURE);
    }
    else {
        if ( _llseek(m_loaderFile , 0L , 0) == HFILE_ERROR ) return(FAILURE);
    }
*/    
    if ( GetOneByte( &ch ) == FAILURE )	return(FAILURE);
       
    while ( ch == 0x70 ) {
    	m_absflag = 1;
    	U8 data[3];
    	if ( GetBytes(data,2) == FAILURE ) return FAILURE;
    	U16 len = BinToU16( data );
    	if ( SeekLoadFile(len , SEEK_CUR) == FAILURE ) return FAILURE;
    	if ( GetOneByte( &ch ) == FAILURE ) return FAILURE;
    }

    if ( SeekLoadFile( 0L , 0) == FAILURE ) return(FAILURE);
    
    switch ( ch ) {
    case 0x4D :
    case 0xA5 :
//    case 0x5A :
        m_compilerUser = LFILE_UBROF;
        break;
    case 0x02 :
    case 0x70 :
        m_compilerUser = LFILE_OMF51;
        break;
//  case 0xE0 :
//  case 0xFC :
    case 0xFE :
        m_compilerUser = LFILE_2500AD;
        break;       
    case 0xF0 :
        m_compilerUser = LFILE_2500AD_E;
        break;       
    case ':' :
        m_compilerUser = LFILE_HEX;
        break;
    case 0xE0 :
        m_compilerUser = LFILE_IEEE695;
        break;
    default :
        m_compilerUser = LFILE_UNKNOWN;
        break;
    }
    return (GOOD);  
}   

/***************************************************************************
*                                                                          *
*  LoadInit - Loader Initialize routine                                    *
*                                                                          *
*  parameter :                                                             *
*       None                                                               *
*                                                                          *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::LoadInit(void)
{
	m_ctime = CTime();
	
    m_typeDelta = 0;
    m_typeNum = 0;
    if ( ClearUpModuleBlock() == -1 )
        return ;
    if ( ClearUpSec() == -1 ) 
        return;
    if ( m_loaderFile != -1 ) {
        if ( CloseLoadFile() == -1 )
            return ;
    }   
    if ( m_lpBuffer ) {
        delete m_lpBuffer;
        m_lpBuffer = 0;
        m_uBufInFilePos = 0;
        m_uBufPos = 0;
        m_uBufSize = 0; 
    }                       
    SymRemoveSymbols();
    InitVarExtendLink();
    m_IsLoaded = FALSE;
    ClearStkAndVar();
    uLoadBytes = 0L;
//    m_dwErrorNum = 0;
}

/***************************************************************************
*                                                                          *
*  LoadCmd - Loader Command entry pointer                                  *
*                                                                          *
*  parameter :                                                             *
*       input :                                                            *
*           argc - argument count                                          *
*           argv - argument string array                                   *
*                                                                          *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
int LoaderServer::LoadCmd(int argc , char *argv[])
{            
    int err;      
    int ldrOldFlags;            // Load option flag
    LPSTR lpOldFileName;            // load file name
    LPSTR lpOldFileRef;         // load file reference
    LPSTR lpOldModuleName;      // load module name
    LPSTR lpOldModuleRef;       // load module reference 
    BOOL onOldDemand;           // onDamand flag
    unsigned char    uch;

    m_window = LOAD_FROM_SHELL;
	GetCpuStatus(uch);
	if ( uch ) {
		OutError( ER_GOFLY_ERR_MSG);
//       	::ErrShow(ER_GOFLY_ERR_MSG,FALSE);
		return FAILURE;
	}
                
    ldrOldFlags = m_ldrFlags;
    lpOldFileName = m_lpFileName;
    lpOldFileRef = m_lpFileRef;
    lpOldModuleName = m_lpModuleName;
    lpOldModuleRef = m_lpModuleRef;
    onOldDemand = m_onDemand;

    m_lpFileName = 0;
    m_lpFileRef = 0;
    m_lpModuleName = 0;
    m_lpModuleRef = 0;                   
    err = LdrProcessArgs(argc , argv);
    if ( (err==0)&&(m_lpModuleName != 0) ) {
        if (    m_IsLoaded == FALSE || 
                ( LOAD_SYM(ldrOldFlags) == 0 ) ) {
            err = -2;
        }       
        else {
            char *lpStr;                           
            char *lpModule;
            OFSTRUCT pof;
            int len;        
            CString filename;
                     
            filename = m_lpFileRef;
            filename += m_lpFileName;                         
            OpenFile(filename.GetBuffer(filename.GetLength()),&pof,OF_PARSE);
            len = lstrlen(pof.szPathName);              
            err = lstrcmpi(m_lpFileName , lpOldFileName);
            if ( err == 0 ) {
                err = lstrcmpi(pof.szPathName , lpOldFileRef);
            }
            
            if ( err == 0 ) {
                err = lstrlen(m_lpModuleName);
                lpModule = new char[err+1];
                if ( lpModule == 0 ) {
//                    ShowLine("memory alloc failure!");
                    OutError( ER_OUT_OF_MEMORY );
//                    OutError( ER_LDR_MEMORY_ALLOC );
                    return FAILURE;
                }
                lstrcpy(lpModule , m_lpModuleName);
//                lpStr = strstr("." , lpModule);
                lpStr = strstr(lpModule,".");
                if (lpStr) *lpStr = '\0';        
                
//				
				CString modName;
				
				modName = lpModule;
				
				modName.MakeUpper();
                err = (U16) SymGetModuleDesc(
               			modName.GetBuffer(modName.GetLength()),
                        m_lpModuleRef,&curModDesc);
				if ( err ) {
					modName.MakeLower();
	                err = (U16) SymGetModuleDesc(
	               			modName.GetBuffer(modName.GetLength()),
	                        m_lpModuleRef,&curModDesc);
				}				                
/*
                err = (U16) SymGetModuleDesc(lpModule,
                            m_lpModuleRef,&curModDesc);
*/
                if ( lpModule ) delete lpModule;
                if ( err != 0 ) err = -4;
            }
            else err = -3;
            
            if ( err == 0 ) {
			    CString filename;			                     
			    filename = m_lpFileRef;
			    filename += m_lpFileName;                         
			    if ((m_loaderFile=_lopen(filename.GetBuffer(filename.GetLength()), 
			        READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR)
            	 	err = -3;
   				else {
	   				struct _stat s;
					if (_fstat(m_loaderFile, &s) == 0) {
	   					CTime time(s.st_ctime);
						if ( m_ctime != time ) err = -3;
					}
					else err = -3;
					_lclose(m_loaderFile);
					m_loaderFile = -1;
				}
            }		// check on demand load file time
        }                
        if ( err == 0 ) {
            m_onDemand = onOldDemand;           
        }
    }
    if ( err != 0 ) {
        m_ldrFlags = ldrOldFlags;
        if ( m_lpFileName ) delete m_lpFileName;
        m_lpFileName = lpOldFileName;           
        if ( m_lpFileRef ) delete m_lpFileRef;
        m_lpFileRef = lpOldFileRef;           
        if ( m_lpModuleName ) delete m_lpModuleName;
        m_lpModuleName = lpOldModuleName;           
        if ( m_lpModuleRef ) delete m_lpModuleRef;
        m_lpModuleRef = lpOldModuleRef;
        m_onDemand = onOldDemand;
/*        
        switch (err) {
        case -2 :
            ShowLine("symbol infomation have not be loaded!");
            break;
        case -3 :
            ShowLine("load file is not same as OnDemand load file!");
            break;
        case -4 :
            ShowLine("no such module!");
            break;
        default :
            ShowLine("Loader Unknown error!");
            break;
        }           
*/
        if ( err <= -2 && err >= -4 ) 
        	OutError ( ER_LDR_UNKNOWN+(U32)(-err) );
        else OutError ( ER_LDR_UNKNOWN );
        return FAILURE;
    }                                           
            
    if ( lpOldFileName ) delete lpOldFileName;
    if ( lpOldFileRef ) delete lpOldFileRef;
    if ( lpOldModuleName ) delete lpOldModuleName;
    if ( lpOldModuleRef ) delete lpOldModuleRef;
    
    if ( (m_lpModuleName==NULL)&&(m_IsLoaded == TRUE) ) {
        LoadInit();
    }              
    else if ( m_lpModuleName == NULL ) {
        uLoadBytes = 0L;
    }

//    m_window = LOAD_FROM_SHELL;
    err=LdrLoadProcess( m_lpFileName , m_onDemand , m_ldrFlags );          
    SrcResetView();
    m_window = LOAD_FROM_DIALOG;
    return err;
}

/***************************************************************************
*                                                                          *
*  LdrProcessArgs - Process Loader arguments                               *
*                                                                          *
*  parameter :                                                             *
*       input :                                                            *
*           argc - argument count                                          *
*           argv - argument string array                                   *
*       output : ( data in class LoaderServer )                            *
*           lpfile - returned filename                                     *
*           m_onDemand - returned m_onDemand flag                          *
*           m_ldrFlags - returned loader flags                             *
*           m_lpFileName - load file name                                  *
*           m_lpFileRef -  load file path reference                        *
*           m_lpModuleName - module name (if module-only load)             *
*           m_lpModuleRef -  module path reference (if module-only load)   *
*                                                                          *
*  return value :                                                          *
*       -1  -  argument error                                              *
*        0  -  ok                                                          *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrProcessArgs(int argc, char *argv[])
{
    char temp[ARGLEN];
    int len , i;
                    
/* we copy to local buffer so we can use strnicmp */
/* actually, we *can* use far CHAR string, with _fstrnicmp */
/* take load filename */
    len = lstrlen( argv[1] );
    lstrcpy((LPSTR)temp, (LPSTR)argv[1]);
    if ( GetFileName(temp , 0) != GOOD ) 
        return (FAILURE);
    
/* set default options */
//  m_onDemand = TRUE;              /* on demand is default */
    m_onDemand = FALSE;
    m_ldrFlags = LDR_DEFAULT;       /* load code, symbols, display progress ,
                                    issue warnings and mangle */
/* process options */
    for (i = 2; i < argc; i++) {
        lstrcpy((LPSTR)temp, (LPSTR)argv[i]);
        switch (toupper(temp[0])) {
        case 'C':   /* load code */
            if (strnicmp(temp, "COD", 3) == 0) m_ldrFlags |= LDR_CODE;
            else return(FAILURE);
            break;
        case 'D':   /* onDemand load */
            if (strnicmp(temp, "DEM", 3) == 0) m_onDemand = TRUE;
            else return(FAILURE);
            break;
        case 'M':   /* module-only load, mangled names */
            if (strnicmp(temp, "MOD", 3) == 0) {
                /* next argument is module name */
                lstrcpy((LPSTR)temp, (LPSTR)argv[++i]);
                /* Parse the m_lpModuleRef to path and module name */
                if ((GetFileName(temp, 1) != 0) ||
                    (lstrlen(m_lpModuleName) == 0)) {
                    return(FAILURE);
                }
            } else if (strnicmp(temp, "MAN", 3) == 0) {
                m_ldrFlags |= LDR_MANGLE;
            } else return(FAILURE);
            break;
        case 'N':   /* turn off option */
            if (strnicmp(temp, "NOSYM", 5) == 0)
                m_ldrFlags &= ~LDR_SYMBOL;
            else if (strnicmp(temp, "NOCOD", 5) == 0)
                m_ldrFlags &= ~LDR_CODE;
            else if (strnicmp(temp, "NOPRO", 5) == 0)
                m_ldrFlags &= ~LDR_STATUS;
            else if (strnicmp(temp, "NODEM", 5) == 0)
                m_onDemand = FALSE;
            /* no more warning */
            else if (strnicmp(temp, "NOWAR", 5) == 0) {
                m_ldrFlags &= ~LDR_WARNING;
            }
            else if (strnicmp(temp, "NOMAN", 5) == 0)
                m_ldrFlags &= ~LDR_MANGLE;
            else return(FAILURE);
            break;
        case 'P':   /* progress indicator */
            if (strnicmp(temp, "PRO", 3) == 0)
                m_ldrFlags |= LDR_STATUS;
            if (strnicmp(temp, "P:", 2) == 0)
                m_ldrFlags &= ~LDR_TODATA;
            else return(FAILURE);
            break;
        case 'S':   /* symbol load */
            if (strnicmp(temp, "SYM", 3) == 0)
                m_ldrFlags |= LDR_SYMBOL;
            else return(FAILURE);
            break;
        case 'W':   /* warnings */
            if (strnicmp(temp, "WAR", 3) == 0) {
                m_ldrFlags |= LDR_WARNING;
            }
            else return(FAILURE);
            break;
        case 'X':   /* warnings */
            if (strnicmp(temp, "X:", 2) == 0) {
                m_ldrFlags |= LDR_TODATA;
            }
            else return(FAILURE);
            break;
        default:
            return(FAILURE);
        }
    }

/* check for consistency of arguments */
    return(GOOD);
}  /* LdrProcessArgs */

/***************************************************************************
*                                                                          *
*  LdrLoadProcess - Loader main process routine                            *
*  parameter :                                                             *
*       filename     --  load file name                                    *
*       onDemandFlag --  load onDemand flag                                *
*                        if TRUE , only load global information            *
*                        else load everything                              *
*       loaderFlags  --  load option flag                                  *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrLoadProcess(   LPSTR filename,
                                    BOOL onDemandFlag, 
                                    int loaderFlags)
{                                  
    int err;
    
    if ( m_window == LOAD_FROM_DIALOG ) {
	    unsigned char    uch;
	
		GetCpuStatus(uch);
		if ( uch ) {
			OutError(ER_GOFLY_ERR_MSG);
//	       	::ErrShow(ER_GOFLY_ERR_MSG,TRUE);
			return GOOD;
		}

        if ( m_lpFileName ) {
            delete m_lpFileName;
            m_lpFileName = 0;
        }
        if ( m_lpFileRef ) {
            delete m_lpFileRef;
            m_lpFileRef = 0;
        }
        if ( m_lpModuleName ) {
            delete m_lpModuleName;
            m_lpModuleName = 0;
        }
        if ( m_lpModuleRef ) {
            delete m_lpModuleRef;
            m_lpModuleRef = 0;
        }
        uLoadBytes = 0L;
    }   
    if ( (m_window == LOAD_FROM_DIALOG)&&(m_IsLoaded == TRUE) ) {
        LoadInit();
    }

    m_compilerUser = LFILE_UNKNOWN;
    m_version = 0;
    if ( m_window == LOAD_FROM_DIALOG ) {
        if ( GetFileName(filename , 0) == -1 ) {
            SrcInitModule();
            return (FAILURE);
        }     
        m_onDemand = onDemandFlag;
        m_ldrFlags = loaderFlags;
    }
    if ( OpenLoadFile() == -1 ) {
//        Warning("Download file can not be opened!");
		Warning( ER_LDR_OPENFILE_ERROR );
        SrcInitModule();
        return (FAILURE);
    }       

    if ( DistinguishCompiler() == -1 ) {
        LoadInit();     
        SrcInitModule();
        return (FAILURE);
    }                        
    err=0;
    if (m_compilerUser==LFILE_UBROF) {  
#ifdef _DUMP_
		Message("Load Ubrof file begin.\r\n");
#endif
        err = LdrUbrofLoadProcess() ;
    }
    else if (m_compilerUser==LFILE_HEX) {
#ifdef _DUMP_
		Message("Load HEX file begin.\r\n");
#endif
        err = Ldr2500ADLoadProcess() ; 
    }
    else if ( (m_compilerUser==LFILE_2500AD)
        ||(m_compilerUser==LFILE_2500AD_E) ) {
#ifdef _DUMP_
		Message("Load 2500AD file begin.\r\n");
#endif
        err = Ldr2500ADLoadProcess() ;
    }   
    else if ( m_compilerUser==LFILE_OMF51 ) {
#ifdef _DUMP_
		Message("Load OMF51 file begin.\r\n");
#endif
        err = LdrOmf51LoadProcess() ;
    } 
    else if ( m_compilerUser==LFILE_IEEE695 ) {
#ifdef _DUMP_
		Message("Load IEEE695 file begin.\r\n");
#endif
        err = Ldr695LoadProcess() ;
    } 
    else {
//        Warning("Load file format has not been supported !");
        Warning ( ER_LDR_UNKNOWN_FORMAT, RE_LDR_COMPILER );
        LoadInit();     
        SrcInitModule();
        return(FAILURE);
    }
    if ( err == -1 ) { 
        LoadInit();     
/*
        if ( LOAD_WARNING( m_ldrFlags ) ) {
            if ( m_window == LOAD_FROM_SHELL )
                prn_err( nErrorNum );
            else 
                win_err( nErrorNum );
        }
        else
            nErrorNum = 0;
*/      
		Warning( m_dwErrorNum );
		m_dwErrorNum = 0;
        SrcInitModule();
        return(FAILURE);
    }       
    if ( LOAD_SYM( m_ldrFlags ) ) {
        SymAddLoadEnd();
        m_IsLoaded = TRUE;
    }       
    if ( (m_window == LOAD_FROM_DIALOG)&&(m_ldrFlags & LDR_STATUS) ) {
        TestMessage();
    }
    if ( m_window != LOAD_FROM_DIALOG ) {
        SrcSetLoadFileName( m_lpFileRef );
    }   
    if ( m_loaderFile != -1 ) {
        _lclose(m_loaderFile);
        m_loaderFile = -1;
    }
                            
#ifdef _ZLR_    

    if ( LOAD_CODE( m_ldrFlags ) ) {
        
        if ( AbiSetReg( 0 , (UINT)m_startaddress) != ICE_OK ) {
//            Warning("Set register value failure!");
            Warning( ER_ABI_SET_REG );
	        SrcInitModule();
            return(FAILURE);
        }
        
        if ( AbiSetReg( 4 , 0x07 ) != ICE_OK ) {
//            Warning("Set register value failure!");
            Warning( ER_ABI_SET_REG );
	        SrcInitModule();
            return(FAILURE);
        }
        
    }
    
#endif
  
    if ( TRUE == SrcInitModule() ) 
        return(GOOD);   
    else 
        return(FAILURE);
}

/***************************************************************************
*                                                                          *
*  LdrLoadModuleOnly - Load a module only        NO USED                   *
*  parameter :                                                             *
*       None (Information all in class LoaderServer)                       *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrLoadModuleOnly(void)
{          
    return GOOD;
}

/***************************************************************************
*                                                                          *
*  LdrLoadModuleByDesc - Load a module local information for OnDemand load *
*                        Only loader block,symbol and linenum information  *
*  parameter :                                                             *
*       offset  --  this module in load file position .                    *
*       moduleDesc --  the module descriptor                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrLoadModuleByDesc(U32 offset, SYM_DESCRIPTOR moduleDesc)
{        
    if ((m_loaderFile=_lopen(m_lpFileRef, 
        READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR)
        return ( FAILURE );

    int err = 0;
    curModDesc = moduleDesc ;
    if (m_compilerUser==LFILE_UBROF) {  
        err = LdrUbrofLoadModuleByDesc(offset);
    }
    else if ( m_compilerUser==LFILE_OMF51 ) {
        err = LdrOmf51LoadModuleByDesc(offset);
    } 
    else if ( m_compilerUser==LFILE_IEEE695 ) {
        err = Ldr695LoadModuleByDesc(offset);
    }
    if( err != GOOD ) Warning( m_dwErrorNum );
    m_dwErrorNum = 0;

    if ( m_loaderFile != -1 ) {
        _lclose(m_loaderFile);
        m_loaderFile = -1;
    }
    return ( err );
}           

/***************************************************************************
*                                                                          *
*  LdrLoadModule - Load a module information by m_ldrFlags and             * 
*                  onDemand flag      NO USED                              *
*  parameter :                                                             *
*       None (Information all in class LoaderServer)                       *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrLoadModule(void)
{            
    return GOOD;
}

/***************************************************************************
*                                                                          *
*  LdrShowProcess - Show currently load status                             *
*  parameter :                                                             *
*       None (Information all in class LoaderServer)                       *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrShowProcess(void)
{            
    return GOOD;
}

/***************************************************************************
*                                                                          *
*  LdrShowProcessDone - Show load status done                              *
*  parameter :                                                             *
*       None (Information all in class LoaderServer)                       *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrShowProcessDone(void)
{            
    return GOOD;
}

#ifdef _DUMP_    
/***************************************************************************
*                                                                          *
*  Warning - Show warning infomation                                       *
*  parameter :                                                             *
*       str  --  warning information string                                *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::Warning(char *str)
{
    if ( m_window == LOAD_FROM_SHELL ) {
        if ( LOAD_WARNING(m_ldrFlags) ) {
            ShowLine(str);
        }
    }
    else {
        if ( LOAD_WARNING(m_ldrFlags) ) {
//            MessageBox(NULL , str , NULL , MB_OK);
            AfxMessageBox(str);
        }
    }
}   

/***************************************************************************
*                                                                          *
*  Message - Show dump infomation                                       *
*  parameter :                                                             *
*       format  --  information format string                                *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::Message(char *format,...)
{
	char Str[256];
   	va_list marker;
   	va_start( marker, format );     /* Initialize variable arguments. */
	wvsprintf(Str,format,marker);
	va_end( marker );
#ifdef _DUMP_
    ShowLine(Str);
#else
    if ( m_window == LOAD_FROM_SHELL ) {
        ShowLine(Str);
    }
    else {
        AfxMessageBox(Str);
    }
#endif
}

#endif

/***************************************************************************
*                                                                          *
*  Warning - Show warning infomation                                       *
*  parameter :                                                             *
*       ulErrCode  --  error code                                           *
*       ulRecCode  --  recovery code                                        *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::Warning(U32 ulErrCode, U32 ulRecCode)
{
#ifdef _DUMP_
	OutError( ulErrCode, ulRecCode);
#else
    if (  LOAD_WARNING(m_ldrFlags) ) OutError( ulErrCode, ulRecCode);
#endif
}

/***************************************************************************
*                                                                          *
*  OutError - Show error infomation                                        *
*  parameter :                                                             *
*       ulErrCode  --  error code                                           *
*       ulRecCode  --  recovery code                                        *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::OutError(U32 ulErrCode, U32 ulRecCode)
{
	CString strErr, strRec;
	if( ulRecCode==0 ) {
		switch( ulErrCode ) {
		case ER_LDR_FILE_FORMAT			:
		case ER_LDR_READ_FILE			:
		case ER_LDR_UNKNOWN_FORMAT		:
		case ER_LDR_DOWNLOAD_FILE		:
		case ER_LDR_OMF51_FORMAT		: 
		case ER_LDR_SCOPE				:
		case ER_LDR_UBROF_FORMAT		:
		case ER_LDR_TYPE				:
			ulRecCode = RE_LDR_COMPILER;
			break;
		case ER_LDR_MEMORY_ALLOC		:
			ulRecCode = RE_MEMORY_ALLOC;
			break;
		case ER_LDR_MODNAME_NOT_MATCH	:
		case ER_LDR_DIFF_ONDEM_FILE		:
		case ER_LDR_NO_MODULE			:
			ulRecCode = RE_LDR_MODNAME;
			break;
		case ER_LDR_FUNCNAME_NOT_MATCH	:
			ulRecCode = RE_LDR_FUNCNAME;
			break;
		case ER_LDR_NOT_RL51			:
		case ER_LDR_RELOC_ADDR			:
		case ER_LDR_RELOC_SYM			:
			ulRecCode = RE_LDR_RELOCATE;
			break;
/*
		case 		:
			ulRecCode = ;
			break;
*/
		}
	}

    if ( m_window == LOAD_FROM_SHELL ) {
    	if( ErrGetErrorText( ulErrCode, ulRecCode, strErr, strRec ) != GOOD ) {
    		if( ErrGetErrorText( ER_NO_SUCH_ERRORCODE, strErr)!= GOOD )
    			return;
    		ulRecCode = 0;
    	}
        ShowLine((LPSTR)(LPCSTR)strErr);
        if( ulRecCode ) ShowLine((LPSTR)(LPCSTR)strRec);
    }
    else {
    	ErrDisplayError(ulErrCode, ulRecCode );
    }
}

/***************************************************************************
*                                                                          *
*  SrcIsLoaded - check symbol information is loaded                        *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0    ---   GOOD         -1   ---   FAILURE                         *
*                                                                          *
***************************************************************************/
int SrcIsLoaded(void)
{
    if ( TRUE == ldrObject.IsSymbolLoaded() ) return GOOD;
    else return FAILURE;
}

/***************************************************************************
*                                                                          *
*  SrcIsStatement - check line information is statement ( UBROF )          *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0    ---   GOOD         -1   ---   FAILURE                         *
*                                                                          *
***************************************************************************/
int SrcIsStatement(void)
{
    if ( TRUE == ldrObject.IsSymbolLoaded() ) {
        if ( TRUE == ldrObject.IsUbrof() ) return GOOD;
//        if ( TRUE == ldrObject.IsIEEE() ) return GOOD;
    }
    return FAILURE;
}                                             

/***************************************************************************
*                                                                          *
*  SrcIsIEEE - check loader is BSO IEEE                                    *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0    ---   GOOD         -1   ---   FAILURE                         *
*                                                                          *
***************************************************************************/
int SrcIsIEEE(void)
{
    if ( TRUE == ldrObject.IsSymbolLoaded() ) {
        if ( TRUE == ldrObject.IsIEEE() ) return GOOD;
    }
    return FAILURE;
}                                             

/***************************************************************************
*                                                                          *
*  LdrLoadModuleByDesc - Ondemand Load for symbol server                   *
*  parameter :                                                             *
*       moduleDesc  -   which module load local information on demand      *
*  return value :                                                          *
*       0    ---   GOOD         -1   ---   FAILURE                         *
*                                                                          *
***************************************************************************/
RETCODE LdrLoadModuleByDesc(SYM_DESCRIPTOR moduleDesc)
{
    RETCODE err;                  
    U32 moduleOffset , ul ;
    
//    err = SymAddLoadStart(
//            m_lpFileName,
//          m_onDemand,
//            TRUE,
//            &m_time );
//    if ( err != GOOD ) {
//        nErrorNum = 0x4025;
//        return( FAILURE );
//    }
    err = SymAddModuleOpenByDesc( moduleDesc , &moduleOffset , &ul );
    if ( err != GOOD ) return err;
    err = (U32) ldrObject.LdrLoadModuleByDesc( moduleOffset , moduleDesc );
    if ( err == GOOD ) SymAddLoadEnd();
    return ( err );
}       

/***************************************************************************
*                                                                          *
*  SrcGetLoadPath - get loader file full path                              *
*  parameter :                                                             *
*       str  ---   full path ( output )                                    *
*  return value :                                                          *
*       0    ---   GOOD         -1   ---   FAILURE                         *
*                                                                          *
***************************************************************************/
int SrcGetLoadPath( CString& str )
{
    return ( ldrObject.GetLpFileRef( str ) );
}

/***************************************************************************
*                                                                          *
*  SrcGetStartAddress - get loader file code start address                 *
*  parameter :                                                             *
*       addr  ---   start address ( output )                               *
*  return value :                                                          *
*       0    ---   GOOD         -1   ---   FAILURE                         *
*                                                                          *
***************************************************************************/
int SrcGetStartAddress( U32& addr )
{
    ldrObject.GetStartAddress( addr );
    return ( GOOD );
}                                              

int SrcOpenFile(U32 inputSymbol)
{
U32 offset;
U8 j;
U8 data[256];
U16 ui;

    if ( GOOD != SymGetModuleSourceFilePosition(inputSymbol,&offset) )
        return 0;

    if ( offset == 0 ) return 0;
    if ( GOOD != ldrObject.SeekLoadFile(offset,0) )
        return 0;

    if ( ldrObject.GetBytes(data , 3) == -1 ) {
        return 0;
    }
    ui = ldrObject.BinToU16(&data[1]);
    if ( ldrObject.GetOneByte(&j) == -1 ) {
        return 0;
    }
    if ( ldrObject.GetBytes(data , j) == -1 ) {
        return 0;
    }
    uSrcLineNum = ui;

    return 1;
}

int SrcReadLine(char *buff)
{
U8 *data;
U8 temp[2];
U16 ui;
// int l;

    if ( uSrcLineNum != 0 ) uSrcLineNum--;
    else {
        *buff = '\0';
        return 7;
    }

    if ( ldrObject.GetBytes(temp , 2) == -1 ) {
        return 4;
    }
    ui = ldrObject.BinToU16(temp);
    data = new unsigned char [ ui+1 ];
    if ( data == 0 ) return 4;
    if ( ldrObject.GetBytes(data , ui) == -1 ) {
        delete data;
        return 4;
    }
    data[ui] = '\0';
    if ( ui > 510 ) data[510] = '\0';
    strcpy( buff , (char *) data );
    delete data;

    if ( ui > 510 ) return 6;
    return 0;
}


LstFileInfoSvr::LstFileInfoSvr() 
{
	lineNum = 0;
	memNum  = 50;
	hData = GlobalAlloc(GHND, memNum*2*sizeof(UINT) );
	if ( hData ) OmftoSrc =(UINT FAR*) GlobalLock(hData);
	else memNum = 0;
//	OmftoSrc =(UINT FAR*) LocalAlloc(LPTR, memNum*2*sizeof(UINT));
	lstFuncInfoPtr = lstFuncInfoHdr = NULL;
	modName = NULL;
}
	
LstFileInfoSvr::~LstFileInfoSvr() 
{
	if ( hData ) {
		GlobalUnlock(hData);
		GlobalFree(hData);
	}
//	LocalFree( (HLOCAL) OmftoSrc );
	LstFuncInfo *ptr;
	while ( lstFuncInfoHdr ) {
		ptr = lstFuncInfoHdr;
		lstFuncInfoHdr = ptr->next;
		if ( ptr->funcName ) delete ptr->funcName;
		delete ptr;
	}
	if ( modName ) delete modName;
}

void LstFileInfoSvr::SetModuleName(LPCSTR lpFileName)
{
   	char drive[_MAX_DRIVE];
   	char dir[_MAX_DIR];
   	char fname[_MAX_FNAME];
   	char ext[_MAX_EXT];
   	_splitpath( lpFileName, drive, dir, fname, ext );
	modName = new char[lstrlen(fname)+1];
	if ( modName == NULL ) return;
	lstrcpy(modName,fname);
}

void LstFileInfoSvr::AddData(UINT nOmfLine,UINT nSrcLine) 
{
    if ( memNum <= lineNum ) {
    	memNum += 50;
   		GlobalUnlock(hData);
   		HANDLE hData2 = GlobalReAlloc(hData,memNum*2*sizeof(UINT), GHND );
   		if ( hData2 ) {
   			hData = hData2;
			OmftoSrc =(UINT FAR*) GlobalLock(hData);
		}
		else {
			memNum -= 50;
			return;
		}
//		OmftoSrc =(UINT FAR*) LocalReAlloc( (HLOCAL)OmftoSrc, 
//				memNum*2*sizeof(UINT), LPTR);
    }
    *(OmftoSrc + lineNum*2) = nOmfLine;
    *(OmftoSrc + lineNum*2 +1) = nSrcLine;
    lineNum++;
}
    
BOOL LstFileInfoSvr::MapLine(LINENUM_TYPE& srcLine,OFFSET_ADDR_TYPE addr) 
{
	lstFuncInfoPtr = lstFuncInfoHdr;
	while ( lstFuncInfoPtr ) {
		if ( lstFuncInfoPtr->srcStart == srcLine ) {
			lstFuncInfoPtr->srcStart = addr;
			break;
		}
		else if ( lstFuncInfoPtr->srcEnd == srcLine ) {
			lstFuncInfoPtr->srcEnd = addr;
			break;
		}
		lstFuncInfoPtr = lstFuncInfoPtr->next;
	}
	
   	UINT FAR* lpLine = OmftoSrc;
   	for ( UINT i = 0 ; i < lineNum; i++ , lpLine += 2 ) {
   		if ( *lpLine == srcLine ) {
   			srcLine = (LINENUM_TYPE)*(lpLine +1);
   			return TRUE;
   		}
   	}
   	return FALSE;
};

void LstFileInfoSvr::AddFunc(LPSTR funcName)
{
	while ( isspace(*funcName) ) funcName++;
	LPSTR ptr = funcName;
	while ( __iscsym(*ptr) ) ptr++;
	*ptr = '\0';
	LstFuncInfo *funcPtr = new LstFuncInfo;
	funcPtr->funcName = new char[lstrlen(funcName)+1];
	if ( !funcPtr || !funcPtr->funcName ) return;
	lstrcpy(funcPtr->funcName,funcName);
	_strupr(funcPtr->funcName);
	if ( lstFuncInfoHdr ) {
		lstFuncInfoPtr->next =  funcPtr;
		lstFuncInfoPtr = funcPtr;
	}
	else {
		lstFuncInfoHdr = lstFuncInfoPtr = funcPtr;
	}
}

void LstFileInfoSvr::SetFuncSrcRange(int mode,LINENUM_TYPE line)
{
	if ( mode == 0 ) // start line
		lstFuncInfoPtr->srcStart = line;
	else
		lstFuncInfoPtr->srcEnd = line;	
}

void LstFileInfoSvr::FuncSetAddr()
{
	QUAL_ADDR_RANGE_TYPE qaddr;
	
	U32 fileOff,typeDel;
	if ( SymAddModuleOpenByDesc(curModDesc,&fileOff,&typeDel) == GOOD ) {
		lstFuncInfoPtr = lstFuncInfoHdr;
		while ( lstFuncInfoPtr ) {
			if ( SymAddFuncOpen(lstFuncInfoPtr->funcName) == GOOD ) {
				qaddr.startAddr = lstFuncInfoPtr->srcStart;
				qaddr.endAddr = lstFuncInfoPtr->srcEnd;
				qaddr.startValid = qaddr.endValid = TRUE;
				SymAddFuncClose();
				SymAddSymbolSetAddr(&qaddr);
			}
			lstFuncInfoPtr = lstFuncInfoPtr->next;
		}
		SymAddModuleClose(FALSE);
	}
}

/******************************** E O F ***********************************/
