
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/LDR.CPP   1.2.1.4   17 Apr 1997 15:53:48   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/LDR.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 15:53:48   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:25:16   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:35:48   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:15:44   ZJRD
** 2.09E
** 
**    Rev 1.2.1.0   28 Mar 1997 10:20:52   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:31:12   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:47:20   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:16:58   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 13:00:14   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.4   09 Sep 1996 13:20:24   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:31:54   ZJRD
** EasyPack/SLD Version 1.9e
** 
**    Rev 1.7.1.2   02 Sep 1996 09:58:58   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:51:12   ZJRD
** EasyPack/SLD Version 1.9b
** 
**    Rev 1.7.1.0   12 Aug 1996 10:54:56   ZJRD
** EasyPack/SLD Version 1.98
** 
**    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 "uicom.h"   
#include "srccom.h"
#include "abibase.h"  
#include "ldr.h"
#include "abitype.h"
#include "abiextfn.h"
#include "hosterrs.h"
//add by chris for CSrcFile
#include "trcserve.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 SrcIsOMF51(void);
int SrcGetLoadPath( CString& str );
int SrcGetStartAddress(int& BankNum, U32& addr );
int SrcOpenFile(U32 inputSymbol);
int SrcReadLine(char *buff);
                                     
//Added by Dragon
BOOL SrcSupportBankSwitch();
BOOL LdrBankFuncAddr(ADDR& addr1, ADDR& addr2);         //for john
int  StkNumConvertToBank(int ul );
U32  StkAddressConvertToBank(U32 ul);
BOOL IsInCommonBank(int address);
                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

extern STATUS AbiSetReg(int iRegId, UINT uRegValue);
extern STATUS AbiInitBank(BANKINIT bank);
extern void InitTempStruct( void );
extern void InitVarExtendLink( void );
extern void ClearStkAndVar(void);
extern void SrcResetView(void);
extern void SrcSetLoadFileName(const char * str);
extern BOOL GetCpuStatus(unsigned char & uchStatus);
extern STATUS SetPCBank(int);
extern int GetPCBank();

/***************************************************************************
*                                                                          *
*  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
  // for bank switching
    LoadBankInit();
    m_bLoadInit = 0;
        
    m_dwErrorNum = 0; 
    m_bDispOff = 0;
    m_dwOffset = 0;//added by dragon
    m_loaderFile = -1;
    m_compilerUser = LFILE_UNKNOWN; 
    m_IsLoaded = FALSE;            
    m_bAppSym = FALSE; //added by dragon
    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;
    }
    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 ( 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 :
        m_compilerUser = LFILE_UBROF;
        break;
    case 0x02 :
    case 0x70 :
    case 0x2e :   //for bank switching
        m_compilerUser = LFILE_OMF51;
        break;
    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);  
}   

/***************************************************************************
*                                                                          *
*  LoadBankInit - Loader Initialize routine //Added by Dragon              *
*                                                                          *
*  parameter :                                                             *
*       None                                                               *
*                                                                          *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::LoadBankInit()
{    
    m_IsBankSwitchOn = 0;    //  for UBROF,OMF51
    m_bCallBank = 0;         //  for UBROF
    m_bRetBank = 0;          //  for UBROF
    m_uBankCallAddr = 0;     //  for UBROF,OMF51
    m_uBankRetAddr = 0;      //  for UBROF
    m_BankStartAddr = 0xffff; //for UBROF
    for(int i=0;i<5;i++){    //may be skipped
        m_nBankInfo[i]=0;
    }
    m_bBankReady = TRUE;
    for(i=0;i<4;i++){
        m_uCallBankAddr[i]=0;
        m_uSwitchBankAddr[i]=0;
        m_bCallFlag[i]=0;
        m_bSwitchFlag[i]=0;
    }
}

/***************************************************************************
*                                                                          *
*  LoadInit - Loader Initialize routine                                    *
*                                                                          *
*  parameter :                                                             *
*       None                                                               *
*                                                                          *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::LoadInit(void)
{
    m_ctime = CTime();
    
    //Added by Dragon
    //for bank switching
    LoadBankInit();
    m_bLoadInit = 1;
    
    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; 
    }
    //added by Dragon 2/25/1997                       
    if(!(LOAD_APPSYM(m_ldrFlags)&&(m_window==LOAD_FROM_SHELL))){   //for load n times, added by dragon.
       m_typeDelta = 0;
       m_typeNum = 0;
       SymRemoveSymbols();
    }
    InitVarExtendLink();
    InitTempStruct();
    ClearStkAndVar();
   
    m_IsLoaded = FALSE;
    uLoadBytes = 0L;
}

/***************************************************************************
*                                                                          *
*  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);
        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);
    //added by dragon
    if(LOAD_APPSYM(m_ldrFlags)){
       m_bAppSym = 1;
    }
    else m_bAppSym = 0;
                      
    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 ) {
                    OutError( ER_OUT_OF_MEMORY );
                    return FAILURE;
                }
                lstrcpy(lpModule , m_lpModuleName);
                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);
                }                               
                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;
        if ( err <= -2 && err >= -4 ) 
            OutError ( ER_LDR_UNKNOWN+(U32)(-err) );
        else OutError ( m_dwErrorNum,0,m_dwOffset );
        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;
    }

    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_dwErrorNum = ER_LDR_UNKNOWN;
    m_bDispOff = 0;
    
    m_onDemand = FALSE;           
    m_bLoadToBank = 0;              //load to specified bank
    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 'A':
            if (strnicmp(temp, "APPEND", 3) == 0) m_ldrFlags |= LDR_APPSYM;
            else return(FAILURE);
            break;            
        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;  
            //added for loading n time by dragon 2/24/1997
            else if (strnicmp(temp, "P0:", 3) == 0){
                m_ldrFlags |= LDR_TOBANK0;          
                m_bLoadToBank = 6;
             }
            else if (strnicmp(temp, "P1:", 3) == 0){
                m_ldrFlags |= LDR_TOBANK1;
                m_bLoadToBank = 7;
             }
            else if (strnicmp(temp, "P2:", 3) == 0){
                m_ldrFlags |= LDR_TOBANK2;
                m_bLoadToBank = 8;
             }
            else if (strnicmp(temp, "P3:", 3) == 0){
                m_ldrFlags |= LDR_TOBANK3;
                m_bLoadToBank = 9;
             }
            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);
        }
    }
   //Added by Dragon      2/26/1997
    if(m_bLoadToBank){
       if((m_bLoadToBank-5)>g_nBankNum){
           m_dwErrorNum = ER_LDR_OUTOF_BANKNUM; 
           m_bDispOff = 1;
           m_dwOffset = g_nBankNum;
           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);
            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_bAppSym = 0;
    }

    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;
    }
    
    m_bSpecSymbol = LOAD_SYSTEM(m_ldrFlags);
    
    if ( OpenLoadFile() == -1 ) {
        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();     
        Warning( m_dwErrorNum,0,m_dwOffset );
        m_dwErrorNum = 0;
        m_bDispOff = 0;
        m_dwOffset = 0;
        SrcInitModule();
        return(FAILURE);
    }       
    if ( LOAD_SYM( m_ldrFlags ) ) {  //may by updated by Dragon
        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(m_IsBankSwitchOn){
           LoadInfo.m_nBank = m_nStartBank+6;                    
           if(SetPCBank(m_nStartBank+6) != ICE_OK){
              Warning( ER_SEL_BANK );
              SrcInitModule();
              return(FAILURE);
           }
        }
        //for load to different bank
        if(m_bLoadToBank&&m_window==LOAD_FROM_SHELL){
           if(SetPCBank(m_bLoadToBank) != ICE_OK){
              Warning( ER_SEL_BANK );
              SrcInitModule();
              return(FAILURE);
           }
        }
        if ( AbiSetReg( 0 , (UINT)m_startaddress) != ICE_OK ) {
            Warning( ER_ABI_SET_REG );
            SrcInitModule();
            return(FAILURE);
        }
        if ( AbiSetReg( 4 , 0x07 ) != ICE_OK ) {
            Warning( ER_ABI_SET_REG );
            SrcInitModule();
            return(FAILURE);
        }
    }
#endif

//add by chris: init SrcFile:
extern CSrcFile SrcFile;

    SrcFile.ClearData();
//init SrcFile end.
    
    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 );
    struct _stat s;
    int err = 0;
    if (_fstat(m_loaderFile, &s) == 0) {
    CTime time(s.st_ctime);
        if ( m_ctime != time ) err = -3;
    }
    else err = -3;
    if ( err < 0 ) {
        _lclose(m_loaderFile);
        m_loaderFile = -1;
        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,0,m_dwOffset );
    m_dwErrorNum = 0;
    m_dwOffset = 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) ) {
            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, U32 offset)
{
#ifdef _DUMP_
    OutError( ulErrCode, ulRecCode, U32 offset);
#else
    if (  LOAD_WARNING(m_ldrFlags) ) OutError( ulErrCode, ulRecCode, offset);
#endif
}

/***************************************************************************
*                                                                          *
*  OutError - Show error infomation                                        *
*  parameter :                                                             *
*       ulErrCode  --  error code                                           *
*       ulRecCode  --  recovery code                                        *
*  return value :                                                          *
*       None                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::OutError(U32 ulErrCode, U32 ulRecCode,U32 offset)
{
    CString strErr, strRec, strOffset;
    U32 rtn;
    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;
        }
    }
  // Modified by Dragon 12/30/1996
    if (m_window == LOAD_FROM_SHELL ) {
        if(m_bDispOff){
           rtn=ErrGetErrorText( ulErrCode, ulRecCode, strErr, strRec, offset );
        }
        else {
           rtn=ErrGetErrorText( ulErrCode, ulRecCode, strErr, strRec);
        }
        if(rtn != GOOD){
           if(ErrGetErrorText( ER_NO_SUCH_ERRORCODE, strErr)!= GOOD )
              return;
           ulRecCode = 0;
        }
        ShowLine((LPSTR)(LPCSTR)strErr);
        if( ulRecCode ) ShowLine((LPSTR)(LPCSTR)strRec);                           
    }
    else{
         if(m_bDispOff){
            ErrDisplayError(ulErrCode, ulRecCode, offset );
         }
         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;
    }
    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;
}                                             

int SrcIsOMF51(void)
{
    if ( TRUE == ldrObject.IsSymbolLoaded() ) {
        if ( TRUE == ldrObject.IsOMF() ) 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 = 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 ) );
}


//for bank switching
/***************************************************************************
*                                                                          *
*  SrcGetStartAddress - get loader file code start address                 *
*  parameter :                                                             *
*       addr  ---   start address ( output )                               *
*  return value :                                                          *
*       0    ---   GOOD         -1   ---   FAILURE                         *
*                                                                          *
***************************************************************************/
int SrcGetStartAddress(int& BankNum, U32& addr )
{   
    U32 tmp;
    ldrObject.GetStartAddress( addr );
    tmp = addr;
    addr = addr & 0x0000FFFF;
    if(ldrObject.m_IsBankSwitchOn){
       BankNum = (int)(tmp >> 16)+6;
    }
    else if(g_nBankNum) 
      BankNum = 6;
    else
      BankNum = 1;

    return ( GOOD );
}                                              

BOOL SrcSupportBankSwitch()
{
 if(ldrObject.m_IsBankSwitchOn){
    return 1;                   
 }
 return 0;
}

BOOL LdrBankFuncAddr(ADDR& addr1, ADDR& addr2)
{
 if(!ldrObject.m_IsBankSwitchOn){
    return 0;
 }
 if(ldrObject.m_compilerUser==LFILE_UBROF){
    addr1.addr = (U16)ldrObject.m_uBankCallAddr;
    addr1.addrType = 6;
    addr2.addr = (U16)ldrObject.m_uBankRetAddr;
    addr2.addrType = 6;
    return 1;
 }
 else if(ldrObject.m_compilerUser==LFILE_OMF51){
    int nCurBank;
     
    if(!g_nBankNum) return 0;
    nCurBank = GetPCBank()-6;
     
    addr1.addr=U16(ldrObject.m_uCallBankAddr[nCurBank]);
    addr1.addrType=U8(nCurBank+6);
    addr2.addr=U16(ldrObject.m_uSwitchBankAddr[nCurBank]);
    addr2.addrType=U8(nCurBank+6); 
    return 1;
 }
 else return 0;
}

int  StkNumConvertToBank(int ul )
{
 if(!g_nBankNum){
    return -1;
 }
 
 int LowBit, HighBit;
 
 if(g_nBankNum==4){
    LowBit = int((ul >> g_nPortLowBit) & 1);
    HighBit = int((ul >> g_nPortHighBit) & 1);
  }
  else
    LowBit = int((ul >> g_nPortLowBit) & 1);
 
 if(g_nBankNum==2){
    if(LowBit==0){
       if(g_nSignal) return 1;
        else  return 2;
    }
    else{ 
       if(g_nSignal) return 2;
       else return 1;
    }
 }
 else{
    if(LowBit==0&&HighBit==0){
    if(g_nSignal) return 1;
    else  return 4;
    }
    else if(LowBit==1&&HighBit==0){
    if(g_nSignal) return 2;
    else return 3;
    }
    else if(LowBit==0&&HighBit==1){
    if(g_nSignal) return 3;
    else return 2;
    }
    else {
    if(g_nSignal) return 4;
    else return 1;
    }
 }
 return -1; 
} 

U32  StkAddressConvertToBank(U32 ul)
 {
  if(!g_nBankNum) return -1;
  if(!ldrObject.m_IsBankSwitchOn) return -1;
  if(SrcIsOMF51()==-1) return -1;
             
  for(int i=0;i<4;i++){
      if(ul==ldrObject.m_uSwitchBankAddr[i])
         return i;
  }
  return -1; 
 }
 
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;
// Modified by Gates Hua    
//    hData = GlobalAlloc(GHND, memNum*2*sizeof(UINT) );
    hData = GlobalAlloc(GHND, memNum*4*sizeof(UINT) );
    if ( hData ) OmftoSrc =(UINT FAR*) GlobalLock(hData);
    else memNum = 0;
//    lstFuncInfoPtr = lstFuncInfoHdr = NULL;
	hFuncData = NULL;
	funcNum = 0;
	funcMemSpace = 0;
	
	hSymData = NULL;
	symNum = symMemSpace = 0;
	
	modName = NULL;
	
	m_bSymPos = FALSE;

    // Added by Gates Hua for ( support ASM linenum 
    bFranklin = FALSE;
}
    
LstFileInfoSvr::~LstFileInfoSvr() 
{
    if ( hData ) {
        GlobalUnlock(hData);
        GlobalFree(hData);
    }
/*    LstFuncInfo *ptr;
    while ( lstFuncInfoHdr ) {
        ptr = lstFuncInfoHdr;
        lstFuncInfoHdr = ptr->next;
        if ( ptr->funcName ) delete ptr->funcName;
        delete ptr;
    }
*/
	if (hFuncData) {
		GlobalUnlock(hFuncData);
		GlobalFree(hFuncData);
	}
	
	if (hSymData) {
		GlobalUnlock(hSymData);
		GlobalFree(hSymData);
	}
    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);
// Modified by Gates Hua    
//        HANDLE hData2 = GlobalReAlloc(hData,memNum*2*sizeof(UINT), GHND );
        HANDLE hData2 = GlobalReAlloc(hData,memNum*4*sizeof(UINT), GHND );
        if ( hData2 ) {
            hData = hData2;
            OmftoSrc =(UINT FAR*) GlobalLock(hData);
        }
        else {
            memNum -= 50;
            return;
        }
    }
//        HANDLE hData2 = GlobalReAlloc(hData,memNum*2*sizeof(UINT), GHND );
//    *(OmftoSrc + lineNum*2) = nOmfLine;
//    *(OmftoSrc + lineNum*2 +1) = nSrcLine;
    memset( OmftoSrc + lineNum*4 , 0 , 4*sizeof(UINT) );
    *(OmftoSrc + lineNum*4) = nOmfLine;
    *(OmftoSrc + lineNum*4 + 1) = nSrcLine;
//    *(OmftoSrc + lineNum*4 + 2) = 0;       
//    *(OmftoSrc + lineNum*4 + 3) = 0;       
    if ( bFranklin ) {
        if ( lineNum ) {
            if ( nOmfLine > *(OmftoSrc + (lineNum-1)*4)+1 ) {
                *(OmftoSrc + (lineNum-1)*4 + 2) = nOmfLine;  
//                return;
            }
        }
    }                  
    
    lineNum++;
}
    
BOOL LstFileInfoSvr::MapLine(LINENUM_TYPE& srcLine,OFFSET_ADDR_TYPE addr) 
{
    if ( !bFranklin ) {
/*        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;
    // Modified by Gates Hua    
    //    for ( UINT i = 0 ; i < lineNum; i++ , lpLine += 2 ) {
        for ( UINT i = 0 ; i < lineNum; i++ , lpLine += 4 ) {
            if ( *lpLine == srcLine ) {
                srcLine = (LINENUM_TYPE)*(lpLine +1);
                return TRUE;
            }
			else if (*lpLine > srcLine) {
	   			srcLine = (LINENUM_TYPE)*(lpLine -3);
	   			return TRUE;
			}
        }
    }
    else {
        UINT FAR* lpLine = OmftoSrc;
        for ( UINT i = 0 ; i < lineNum; i++ , lpLine += 4 ) {
            if ( *(lpLine+2) > 0 && *(lpLine+3) == 0 ) {
                if ( *lpLine > srcLine ) return FALSE;
                else if ( *lpLine <= srcLine && *(lpLine+2) > srcLine ) {
                    *(lpLine+3) = 1;
                    srcLine = (LINENUM_TYPE)*(lpLine +1);
                    return TRUE;
                }
//                srcLine = (LINENUM_TYPE)*(lpLine +1);
//                return TRUE;
            }
            else if ( *lpLine == srcLine ) {
                srcLine = (LINENUM_TYPE)*(lpLine +1);
                return TRUE;
            }
        }
    }    
    return FALSE;
};

BOOL LstFileInfoSvr::AddFunc(LPSTR lpszName,LPSTR lpszAddr,LPSTR lpszType)
{
	if (funcNum >= funcMemSpace) {
		funcMemSpace += 10;
		if (funcNum) {
   			hFuncData = GlobalReAlloc(hFuncData,funcMemSpace*sizeof(LstFuncInfo), GHND );
		}
		else {
			hFuncData = GlobalAlloc(GHND, funcMemSpace*sizeof(LstFuncInfo) );
		}
   		if ( hFuncData ) {
			lstFuncInfoPtr =(LstFuncInfo FAR*) GlobalLock(hFuncData);
		}
		else {
			funcMemSpace -= 10;
			return FALSE;
		}
	}

	LstFuncInfo FAR* funcPtr = lstFuncInfoPtr+funcNum;
	funcNum++;

	lstrcpy(funcPtr->funcName,lpszName);
	while ( isspace(*lpszAddr) ) lpszAddr++;
	LPSTR ptr;
	funcPtr->srcStart = strtol(lpszAddr,&ptr,10);
	lpszAddr = ptr;
	while ( isspace(*lpszAddr) ) lpszAddr++;
	while ( !isspace(*lpszAddr) ) lpszAddr++;
	while ( isspace(*lpszAddr) ) lpszAddr++;
	funcPtr->srcEnd = strtol(lpszAddr,&ptr,10);
	return TRUE;
}

void LstFileInfoSvr::AddFunc(LPSTR funcName,LINENUM_TYPE lineStart)
{
	while ( isspace(*funcName) ) funcName++;
	LPSTR ptr = funcName;
//	while (!isspace(*ptr) && *ptr != ':' ) ptr++;
	while ( __iscsym(*ptr) || *ptr=='$' || *ptr=='#' || *ptr=='@') ptr++;
	*ptr = '\0';

	if (funcNum >= funcMemSpace) {
		funcMemSpace += 10;
		if (funcNum) {
   			hFuncData = GlobalReAlloc(hFuncData,funcMemSpace*sizeof(LstFuncInfo), GHND );
		}
		else {
			hFuncData = GlobalAlloc(GHND, funcMemSpace*sizeof(LstFuncInfo) );
		}
   		if ( hFuncData ) {
			lstFuncInfoPtr =(LstFuncInfo FAR*) GlobalLock(hFuncData);
		}
		else {
			funcMemSpace -= 10;
			return;
		}
	}

//	LstFuncInfo *funcPtr = new LstFuncInfo;
//	funcPtr->funcName = new char[lstrlen(funcName)+1];
//	if ( !funcPtr || !funcPtr->funcName ) return;
	LstFuncInfo FAR* funcPtr = lstFuncInfoPtr+funcNum;
	funcNum++;

//	lstrcpy(funcPtr->funcName,funcName);
	int nLen = lstrlen(funcName);
	LPSTR lpDst = funcPtr->funcName;
	for (int i = 0; i < nLen;i++,funcName++) {
		if (*funcName!='$' && *funcName!='#' && *funcName!='@')
			*lpDst++ = *funcName;
	}
	_strupr(funcPtr->funcName);
	funcPtr->srcStart = lineStart;
/*	if ( lstFuncInfoHdr ) {
		lstFuncInfoPtr->next =  funcPtr;
		lstFuncInfoPtr = funcPtr;
	}
	else {
		lstFuncInfoHdr = lstFuncInfoPtr = funcPtr;
	}
*/
}

void LstFileInfoSvr::SetFuncSrcRange(int mode,LINENUM_TYPE line)
{
	if (!funcNum) return;
	LstFuncInfo FAR* funcPtr = lstFuncInfoPtr+funcNum-1;
	if ( mode == 0 ) // start line
		funcPtr->srcStart = line;
	else
		funcPtr->srcEnd = line;	
}

BOOL LstFileInfoSvr::SetFuncEndLine(LPSTR szLine,LINENUM_TYPE line)
{
	while ( isspace(*szLine) ) szLine++;
	if (_strnicmp(szLine,"end",3) == 0) {
		if (isspace(szLine[3]) || szLine[3] == ':' || szLine[3] == ';') {
			SetFuncSrcRange(1,line);
			return TRUE;
		}
	}
	return FALSE;
}

BOOL LstFileInfoSvr::AddSymbol(LPSTR szLine)
{       
	if (!m_bSymPos) {
		char seps[] = " ,\t\n";
		char *token;
		//   DEFN  SPACE  SIZE  NAME                  ATTRIBUTES
		token = strtok(szLine,seps);
		if (!token) return FALSE;
		if (0 != _stricmp(token,"DEFN")) return FALSE;

		token = strtok(NULL,seps);
		if (!token) return FALSE;
		if (0 != _stricmp(token,"SPACE")) return FALSE;

		token = strtok(NULL,seps);
		if (!token) return FALSE;
		if (0 != _stricmp(token,"SIZE")) return FALSE;

		token = strtok(NULL,seps);
		if (!token) return FALSE;
		if (0 != _stricmp(token,"NAME")) return FALSE;
		m_nNamePos = token - szLine;
		
		token = strtok(NULL,seps);
		if (!token) return FALSE;
		if (0 != _stricmp(token,"ATTRIBUTES")) return FALSE;
		m_nAttrPos = token - szLine;
		m_bSymPos = TRUE;
		return TRUE;
	}

	U16 type = 0;
	U16 bReg = 0;
	LPSTR szName = szLine+m_nNamePos;//22;
	LPSTR szType = szLine+m_nAttrPos;//35;
	szLine[34] = '\0';

	while ( isspace(*szName) ) szName++; 
	LPSTR ptr = szName;
	while (__iscsym(*ptr)) ptr++;
	*ptr = '\0';
	if (lstrlen(szName) == 0) return FALSE;

	while ( isspace(*szType) ) szType++;
	if (_strnicmp(szType,"BIT",3) == 0 && isspace(szType[3]))
		type = BI_BIT;//1;
	else if (_strnicmp(szType,"BYTE",4) == 0 && isspace(szType[4]))
		type = BI_U8_UCHAR;//2;
	else if (_strnicmp(szType,"WORD",4) == 0 && isspace(szType[4]))
		type = BI_U16_UINT;//3;
	else if (_strnicmp(szType,"LABEL",5) == 0 && isspace(szType[5]))
		type = BI_JUMP;//4;
	else if (_strnicmp(szType,"PROCEDURE",9) == 0 && isspace(szType[9]))
		return AddFunc(szName,szLine,szType);
//		type = BI_JUMP;//4;
	else return FALSE;
	if (strstr(szType,"REGISTER")) bReg = TRUE;
	
	if (symNum >= symMemSpace) {
		symMemSpace += 50;
		if (symNum) {
   			hSymData = GlobalReAlloc(hSymData,symMemSpace*sizeof(LstSymInfo), GHND );
		}
		else {
			hSymData = GlobalAlloc(GHND, symMemSpace*sizeof(LstSymInfo) );
		}
   		if ( hSymData ) {
			lstSymInfoPtr =(LstSymInfo FAR*) GlobalLock(hSymData);
		}
		else {
			symMemSpace -= 50;
			return FALSE;
		}
	}

	LstSymInfo FAR* symPtr = (LstSymInfo HUGE*)lstSymInfoPtr+symNum;
	symNum++;
	lstrcpy(symPtr->symName,szName);
	symPtr->type = type;
	symPtr->reg = bReg;
	return TRUE;
}

U16 LstFileInfoSvr::SymGetType(LPSTR lpszSym)
{
	LstSymInfo FAR* symPtr = lstSymInfoPtr;
	for (U16 i = 0; i < symNum; i++,symPtr++) {
		if (_stricmp(lpszSym,symPtr->symName) == 0)
			return symPtr->type;
	}
	return 0;
}

void LstFileInfoSvr::FuncSetAddr()
{
	QUAL_ADDR_RANGE_TYPE qaddr;
	
	U32 fileOff,typeDel;
//	if ( SymAddModuleOpenByDesc(curModDesc,&fileOff,&typeDel) == GOOD ) {
	LstFuncInfo FAR* funcPtr = lstFuncInfoPtr;
	ADDR_RANGE_TYPE addr;
	LINENUM_TYPE actLine;
	COLUMN_TYPE  actCol;
	LINENUM_DESCRIPTOR nextId;
	OFFSET_ADDR_TYPE usedA;
	for (UINT i = 0; i < funcNum; i++,funcPtr++) {
		if ( SymAddModuleOpenByDesc(curModDesc,&fileOff,&typeDel) == GOOD ) {
			if ( SymAddFuncOpen(funcPtr->funcName) == GOOD ) {
				LINENUM_TYPE srcLine = funcPtr->srcStart;
				if (MapLine(srcLine,usedA)) {
#ifdef _DUMP_
					qaddr.startAddr = funcPtr->srcStart;
					qaddr.endAddr = funcPtr->srcEnd;
#else
					if (SymGetLinenum(curModDesc,srcLine,&addr,&actLine,&actCol,&nextId)) 
						continue;
					qaddr.startAddr = addr.startAddr;
					qaddr.endAddr = qaddr.startAddr + funcPtr->srcEnd - 1;
#endif
				}
//				if (SymGetLinenum(curModDesc,funcPtr->srcStart,&addr,&actLine,&actCol,&nextId)) 
//					continue;
//				qaddr.startAddr = addr.startAddr;
//				if (SymGetLinenum(curModDesc,funcPtr->srcEnd,&addr,&actLine,&actCol,&nextId)) 
//					continue;
//				if (funcPtr->srcEnd != actLine) qaddr.endAddr = addr.startAddr-1;
//				else qaddr.endAddr = addr.endAddr;
				qaddr.startValid = qaddr.endValid = TRUE;
				SymAddFuncClose();
				SymAddSymbolSetAddr(&qaddr);
			}
		}
		SymAddModuleClose(FALSE);
/*		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);
*/
	}
}


//for bank switching,or load n time
 BOOL LoaderServer::IsModuleExist(LPSTR name)
  {
   ASSERT(name != NULL);
   
   int err;
   SYM_DESCRIPTOR  offset;
   
   err = (U16) SymGetModuleDesc(name,"",&offset); 
   if(err == GOOD)  return 1;
   else  return 0;
 }                              
  
 void LoaderServer::ConvertAddrToBank(U32& addr)
  {
   ASSERT(m_bLoadToBank>5);
   addr |= (U32(m_bLoadToBank-6)<<16);
  } 

BOOL IsInCommonBank(unsigned short address)
 {                              
  if(!ldrObject.m_IsBankSwitchOn)
     return 0;
  return BOOL(address<ldrObject.m_BankStartAddr);
 }
/******************************** E O F ***********************************/
