
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/LDR2500.CPP   1.2.1.4   17 Apr 1997 15:53:56   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/LDR2500.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 15:53:56   ZJRD
** 2.09G
** 
**    Rev 1.2.1.3   16 Apr 1997 10:25:26   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:36:00   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:15:50   ZJRD
** 2.09E
** 
**    Rev 1.2.1.0   28 Mar 1997 10:20:58   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:31:16   ZJRD
** Easy Pack SLD 2.09c
** 
**    Rev 1.0   12 Mar 1997 14:47:22   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:16:50   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 13:00:04   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.4   09 Sep 1996 13:20:04   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:31:34   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 09:58:38   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:50:52   ZJRD
** EasyPack/SLD Version 1.9b
** 
**    Rev 1.7.1.0   12 Aug 1996 10:54:44   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.5   05 Jun 1996 14:57:44   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:34:32   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 08:59:58   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:16:30   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:30:52   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:55:58   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:35:00   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:49:26   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:04:54   Shirley
** EasyPack/SLD Version 1.0
** 
**    Rev 1.26   06 Feb 1996 15:31:28   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:46:20   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:19:50   Shirley
** EasyPack/SLD Version 0.35b
** 
**    Rev 1.23   26 Jan 1996 09:16:42   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:16:36   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:34:30   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:25:18   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.19   18 Jan 1996 10:08:04   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:17:12   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:14:18   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:14:32   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:35:12   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:24:26   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:25:10   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:29:36   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:33:00   Shirley
** EasyPack/SLD Version 0.23
** 
**    Rev 1.10   08 Nov 1995 12:44:58   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:03:30   Shirley
** EasyPack/SLD Version 0.21
** 
**    Rev 1.8   27 Oct 1995 16:46:40   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:45:42   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:27:16   Shirley
** EasyPack/SLD Version 0.1f
** 
**    Rev 1.5   18 Oct 1995 14:51:24   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:20:50   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:51:34   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:53:28   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:48:10   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:54:30   Shirley
** Initial revision.
**
****************************************************************************/

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

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

#include "stdafx.h"
#include <ctype.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>

#include "symblsvr.h"
#include "abibase.h"
#include "ldr.h"           
#include "ldr2500.h"
#include "uicom.h"
#include "hosterrs.h"

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

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

extern SYM_DESCRIPTOR curModDesc;
extern U32 uLoadBytes;

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

// void displayPC(U16 addr);
unsigned char asc__h(unsigned char a);
unsigned char asc2hex(unsigned char a,unsigned char b);

int g_nErrorNumber = 0;

unsigned char dw_buf2[512];
int dw_byte;
ADDR g_nextAddr;
unsigned char *g_ptrCode = NULL;

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

extern STATUS AbiFill(ADDR addr1, ADDR addr2,char* pchBuff,UINT uPatternLen);
extern void ShlReshowLine(char * pch, int nLen);
extern RETCODE SymAddLoadStartAgain();

void LoaderServer::InitDownloadCode()
{
    dw_byte = 0;
    g_nextAddr.addrType = 0;
    g_nextAddr.addr = 0;
    g_ptrCode = (unsigned char *)&dw_buf2[0];
}


BOOL LoaderServer::DownloadCode()
{
    ADDR stAddr , endAddr;
    int err;
    
    if ( dw_byte <= 0 ) return GOOD;
    
    stAddr.addrType = endAddr.addrType = g_nextAddr.addrType;
    stAddr.addr = (unsigned short)( g_nextAddr.addr - (unsigned int) dw_byte );
    if ( dw_byte < 255 ) {
        endAddr.addr=(unsigned short)(g_nextAddr.addr - 1);

#ifdef _ZLR_                
        err=AbiFill(stAddr , endAddr , (char *)dw_buf2 , dw_byte);
        if ( err != ICE_OK ) {
            m_dwErrorNum = ER_ICE_FAIL_MEM_WRITE;   // 0x4002;
            return(-1);
        }
#endif              
        g_ptrCode = dw_buf2;

        uLoadBytes += (U32)dw_byte;

        dw_byte = 0;
    }
    else {
        endAddr.addr=(unsigned short)(stAddr.addr + 254);

#ifdef _ZLR_                                
        err=AbiFill(stAddr , endAddr , (char *)dw_buf2 , 255);
        if ( err != ICE_OK ) {
            m_dwErrorNum = ER_ICE_FAIL_MEM_WRITE;   // 0x4002;
            return(-1);
        }
#endif
        uLoadBytes += 255L;
                
        dw_byte -= 255;
        g_ptrCode = &dw_buf2[dw_byte];
        if ( dw_byte ) {
            memcpy( dw_buf2 , &dw_buf2[255] , dw_byte );
        }   
    }
    return TRUE;
}

/***************************************************************************
*                                                                          *
*  Ldr2500ADLoadProcess - 2500AD Loader main process routine               *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::Ldr2500ADLoadProcess(void)
{       
    int err;       
    int symFlag;
    U8 key;
    U8 data[4]; 
    RETCODE retCode;
    int ii;                
    
    symFlag = LOAD_SYM(m_ldrFlags);
    m_absflag = 0;     
    g_nErrorNumber = 0;

    if (m_lpModuleName) {
/* load module only */
/* Get the module descriptor from moduleName and moduleReference */
        m_dwErrorNum = ER_LDR_2500AD_NO_ONDEM;  // 0x400D;        
        return(-1);
    }
    else {
        m_startaddress = 0;                                                   
/* load 2500ad file all information */
                              
        if ( (err = TestKey(VK_ESCAPE)) == 1 ) {
            m_dwErrorNum = ER_LDR_ABORT;        // 0x4010;
            return( -1 );
        } 
        if ( (m_window == LOAD_FROM_DIALOG)&&(m_ldrFlags & LDR_STATUS) ) {
            if ( IsLoadCanceled() ) {
                m_dwErrorNum = ER_LDR_ABORT;    // 0x4010;
                return( -1 );
            }                  
            TestMessage();
        }
        if ( m_compilerUser == LFILE_HEX ) {
            if ( LOAD_CODE( m_ldrFlags ) ) {
                err = LdrIntelHexDownload();
                if ( err == -1 ) return(-1);
            }
            if ( LOAD_SYM( m_ldrFlags ) ) {
                if ( CloseLoadFile() == -1 ) {
                    return(-1);
                }                      
                if ( m_lpFileName ) delete m_lpFileName;
                m_lpFileName = 0;
                LPSTR tmp = m_lpFileRef ;             
                int len = strlen(tmp);
                m_lpFileRef = 0;
                LPSTR ptr = new char[ len + 6 ];
                strcpy( ptr , tmp );
                if ( tmp ) delete tmp;
                int i = len - 1;
                while ( i > 0 ) {
                    if ( ptr[i] == '.' ) break;
                    if ( ptr[i] == '/' ) break;
                    if ( ptr[i] == '\\' ) break;
                    if ( ptr[i] == ':' ) break;
                    i--;
                }
                if ( (i>0)&&(ptr[i]=='.') ) {
                    ptr[i+1] = 'S';
                    ptr[i+2] = 'Y';
                    ptr[i+3] = 'M';
                    ptr[i+4] = '\0';
                }
                else {
                    ptr[len] = '.';
                    ptr[len+1] = 'S';
                    ptr[len+2] = 'Y';
                    ptr[len+3] = 'M';
                    ptr[len+4] = '\0';
                }
                if ( GetFileName( ptr , 0 ) == -1 ) {
                    return ( -1 );
                }
                if ( ptr ) delete ptr;
                if ( OpenLoadFile() == -1 ) {
                    m_dwErrorNum = 0;
//                    return (-1);
                    return GOOD;
                }
            }
            else 
                return GOOD;
        }
        else {
            if(! LOAD_SYM( m_ldrFlags ) ){
                 AfxMessageBox("Please you load a HEX file");
                 return -1;
            }
            if ( LOAD_CODE( m_ldrFlags ) ) {
                if ( CloseLoadFile() == -1 ) {
                    return(-1);
                }                      
                if ( m_lpFileName ) delete m_lpFileName;
                m_lpFileName = 0;
                LPSTR tmp = m_lpFileRef ;             
                int len = strlen(tmp);
                m_lpFileRef = 0;
                LPSTR ptr = new char[ len + 6 ];
                strcpy( ptr , tmp );
                int i = len - 1;
                while ( i > 0 ) {
                    if ( ptr[i] == '.' ) break;
                    if ( ptr[i] == '/' ) break;
                    if ( ptr[i] == '\\' ) break;
                    if ( ptr[i] == ':' ) break;
                    i--;
                }
                if ( (i>0)&&(ptr[i]=='.') ) {
                    ptr[i+1] = 'H';
                    ptr[i+2] = 'E';
                    ptr[i+3] = 'X';
                    ptr[i+4] = '\0';
                }
                else {
                    ptr[len] = '.';
                    ptr[len+1] = 'H';
                    ptr[len+2] = 'E';
                    ptr[len+3] = 'X';
                    ptr[len+4] = '\0';
                }
                if ( GetFileName( ptr , 0 ) == -1 ) {
                    return ( -1 );
                }
                if ( ptr ) delete ptr;
                if ( OpenLoadFile() != -1 ) {
                    err = LdrIntelHexDownload();
                    CloseLoadFile();
                    m_dwErrorNum = 0;
                }
                else m_dwErrorNum = 0;
                                
                if ( m_lpFileName ) delete m_lpFileName;
                m_lpFileName = 0;
                if ( m_lpFileRef ) delete m_lpFileRef;
                m_lpFileRef = 0;            
                if ( GetFileName( tmp , 0 ) == -1 ) {
                    return (-1);
                }
                if ( tmp ) delete tmp;
                if ( OpenLoadFile() == -1 ) {
                    return (-1);
                }
            }           
        }                                          

        m_absflag = 1;
        
        if( LOAD_SYM( m_ldrFlags )&&m_bAppSym&&m_bLoadInit){
            retCode = SymAddLoadStartAgain();
            if ( retCode != GOOD ) {
                m_dwErrorNum = ER_LDR_SYM_SERVER;   // 0x4025;
                return( FAILURE );
            }
        }

        if (LOAD_SYM(m_ldrFlags)&&(!m_bAppSym||!m_bLoadInit)) {
                        
            retCode = SymAddLoadStart(
                        m_lpFileName,
                        FALSE,
                        &m_time );
            if ( retCode != GOOD ) {
                m_dwErrorNum = ER_LDR_SYM_SERVER;       // 0x4025;
                return( FAILURE );
            }

            if ( (err = GetOneByte(&key)) == -1 ) {
                m_dwErrorNum = ER_LDR_READ_FILE;        // 0x400F;
                m_bDispOff = 1;
                m_dwOffset = GetFileCurPos();
                return(-1);
            }
            if ( key == 0xFE ) {
                m_compilerUser = LFILE_2500AD;
            }
            else if ( key == 0xF0 ) {
                m_compilerUser = LFILE_2500AD_E;
            }
            else {
                m_dwErrorNum = ER_LDR_SYM_FILE_FORMAT;  // 0x400E;
                return(-1);
            }
            if ( (err = GetOneByte(&key)) == -1 ) {
                m_dwErrorNum = ER_LDR_READ_FILE;        // 0x400F;
                m_bDispOff = 1;
                m_dwOffset = GetFileCurPos();
                return(-1);
            }              
            while ( key != AD2500_END ) {         
                if ( (err = TestKey(VK_ESCAPE)) == 1 ) {
                    m_dwErrorNum = ER_LDR_ABORT;        // 0x4010;
                    return( -1 );
                } 
                if ( (m_window == LOAD_FROM_DIALOG)&&(m_ldrFlags&LDR_STATUS) ) {
                    if ( IsLoadCanceled() ) {
                        m_dwErrorNum = ER_LDR_ABORT;    // 0x4010;
                        return( -1 );
                    }                  
                    TestMessage();
                }
                ClearUpModuleBlock();
                ModuleNodeInit();
                m_modNode.offset = m_uBufInFilePos + m_uBufPos - 1 ;
                if(m_modNode.name) delete m_modNode.name;
                m_modNode.name = new char[key+1];
                ASSERT( m_modNode.name ) ;
                if ( (err = GetBytes((unsigned char far *)m_modNode.name ,
                    key)) == -1 ) {
                    m_dwErrorNum = ER_LDR_READ_FILE;    // 0x400F;
                    m_bDispOff = 1;
                    m_dwOffset = GetFileCurPos();
                    return(-1);
                }
                m_modNode.name[key] = '\0';

                for( ii=key-1;ii>=0;ii-- )
                    if( m_modNode.name[ii] == '.' ) m_modNode.name[ii] = '\0';
                
                int iii;
                ii = 0;
                for( iii=0 ; iii<strlen(m_modNode.name); iii++ ) {
                    if( m_modNode.name[iii] == ':' ) {
                        ii = iii;                     
                        break;
                    }
                }         
                if ( ii && ii < strlen(m_modNode.name)-1 ) {
                    for( iii=0; iii<strlen(m_modNode.name)-ii; iii++ ) {
                        m_modNode.name[iii] = m_modNode.name[ii+iii];
                    }
                    m_modNode.name[strlen(m_modNode.name)-ii] = '\0';
                }
                
                if(IsModuleExist(m_modNode.name)){
                   symFlag = 0;
                }
                if ( (err = GetBytes(data , 4)) == -1 ) {
                    m_dwErrorNum = ER_LDR_READ_FILE;    // 0x400F;
                    m_bDispOff = 1;
                    m_dwOffset = GetFileCurPos();
                    return(-1);
                }
                if ( data[3] != 0x02 ) {
                    m_dwErrorNum = ER_LDR_2500AD_SYM_ADDR;  // 0x4011;
                    return(-1);
                }               
                
                if(symFlag){
                   retCode = SymAddModuleCreate(
                        m_modNode.name ,
                        &m_modNode.time ,
                        &m_modNode.codeaddr ,
                        m_modNode.offset ,
                        FALSE , // m_onDemand ,
                        0,
                        &curModDesc );
                   if ( retCode != GOOD ) {
                       m_dwErrorNum = ER_LDR_SYM_SERVER;    // 0x4025;
                       return( FAILURE );
                   }
                }

                if ( (err = Ldr2500ADLoadModule(symFlag) ) == -1 ) {
                    return(-1);
                }
                                              
                if ( (err = GetOneByte(&key)) == -1 ) {
                    m_dwErrorNum = ER_LDR_READ_FILE;    // 0x400F;
                    m_bDispOff = 1;
                    m_dwOffset = GetFileCurPos();
                    return(-1);
                }              
            };

        }   
    } 
    if ( g_nErrorNumber ) {
        g_nErrorNumber = 0;
        if ( m_window == LOAD_FROM_SHELL ) {
            if ( LOAD_WARNING(m_ldrFlags) ) {
                ShowLine("Warning: some symbols have duplicate , please check it.");
            }
        }
        else {
            if ( LOAD_WARNING(m_ldrFlags) ) {
                AfxMessageBox("Warning: some symbols have duplicate, please check it.");
            }
        }
    }
    return (err);
}

/***************************************************************************
*                                                                          *
*  Ldr2500ADLoadModule - Load a module symbol information                  *
*  parameter :                                                             *
*       None (Information all in class LoaderServer)                       *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::Ldr2500ADLoadModule(int symFlag)
{       
    int err;
    U8 key;
    U8 data[512];
    U8 data1[4];
    U32 ui;    
    RETCODE retCode;
   
    VAR_STORAGE_CLASS varStorage;
    VAR_REGISTER_CLASS registerClass;
//    BOOL isConst , isValid ;
    BOOLEAN isConst , isValid ;
    ADD_VAR_ADDR_UNION addr;
    SYM_DESCRIPTOR symDesc;
    TYPE_INDEX typeIndex;
            
    varStorage = GLOBAL_VAR_CLASS;  
    
    while (1) {
        registerClass = NOT_REG;
        if ((err = GetOneByte(&key)) == -1 ) {
            m_dwErrorNum = ER_LDR_READ_FILE;    // 0x400F;
            m_bDispOff = 1;
            m_dwOffset = GetFileCurPos();
            return(FAILURE);
        }              
        if ((m_compilerUser==LFILE_2500AD)&&(key==AD2500_START) ) {
            ClearUpModuleBlock();
            if(symFlag){
               retCode = SymAddModuleClose( FALSE );
               if ( retCode != GOOD ) {
                   m_dwErrorNum = ER_LDR_SYM_SERVER;    // 0x4025;
                   return( FAILURE );
               }
            }
           break;
        }    
        else if ( (m_compilerUser==LFILE_2500AD_E)&&(key==AD2500_E_START) ) {
            ClearUpModuleBlock();
            if(symFlag){
               retCode = SymAddModuleClose( FALSE );
               if ( retCode != GOOD ) {
                   m_dwErrorNum = ER_LDR_SYM_SERVER;    // 0x4025;
                   return( FAILURE );
               }
            }
            break;
        }
        if ( (err = GetBytes(data , key)) == -1 ) {
            m_dwErrorNum = ER_LDR_READ_FILE;        // 0x400F;
            m_bDispOff = 1;
            m_dwOffset = GetFileCurPos();
            return(FAILURE);
        }
        data[key] = '\0';

        if ( m_compilerUser==LFILE_2500AD ) {
            if ( (err = GetBytes(data1 , 2)) == -1 ) {
                m_dwErrorNum = ER_LDR_READ_FILE;        // 0x400F;
                m_bDispOff = 1;
                m_dwOffset = GetFileCurPos();
                return(FAILURE);
            }              
            ui = (U32)BinToU16(data1);
            //for load to specified bank
            if(m_bLoadToBank&&m_window==LOAD_FROM_SHELL){
               ConvertAddrToBank(ui);                    
            }
//            addr.fixedAddr = (U32) ui;
            isConst = FALSE;
            isValid = TRUE;
            addr.addr.segType = SEG_CODE;
            addr.addr.addr = ui;
            if(symFlag){
               retCode = SymAddVar( (LPSTR)data , 0L , varStorage , 
                     registerClass , &addr,isConst,isValid,&symDesc);
               if ( retCode != GOOD ) g_nErrorNumber = 1;
//               if ( retCode != GOOD ) {
//                   m_dwErrorNum = ER_LDR_SYM_SERVER;  // 0x4025;
//                   return( FAILURE );
//               }
            }
        }
        else {
            if ( (err = GetBytes(data1 , 3)) == -1 ) {
                m_dwErrorNum = ER_LDR_READ_FILE;    // 0x400F;
                m_bDispOff = 1;
                m_dwOffset = GetFileCurPos();
                return(FAILURE);
            }              
            ui = (U32)BinToU16(data1);
            //for load to specified bank
            if(m_bLoadToBank&&m_window==LOAD_FROM_SHELL){
               ConvertAddrToBank(ui);
            }
            switch ( data1[2] ) {
            case 0 :
                typeIndex = BI_UNKNOWN ;
                break;
            case 1 :
                typeIndex = BI_U8_UCHAR ;
                break;
            case 2 :
                typeIndex = BI_U16_UINT ;
                break;
            case 3 :
                typeIndex = BI_U32_ULONG ;
                break;
            case 4 :
                typeIndex = BI_F32 ;
                break;
            case 5 :
                typeIndex = BI_F64 ;
                break;                
            case 6 :
                typeIndex = BI_BIT ;
                break;  
            case 7 :                  
                typeIndex = BI_U8_UCHAR ;
                break;
            case 8 :
            case 9 :
                typeIndex = BI_UNKNOWN ;
                break;
            default :
#ifdef _DUMP_
                Message("\r\n???Unknown type  at file %lx",
                            GetFileCurPos()-3);
#endif
                m_dwErrorNum = ER_LDR_SYM_TYPE;     // 0x4012;
                return(-1);
                break;
            }
            if ( data1[2] == 7 ) {
                isConst = FALSE;
                isValid = TRUE;
                registerClass = LIVING_REG;
            }
            else if ( data1[2] == 8 ) {
// Modified by Gates Hua , for fix a bug about label and equ(const) symbol same name.
                if(symFlag){
                   retCode = SymAddLabelPublic( (LPSTR)data, ui );
                   if ( retCode != GOOD ) g_nErrorNumber = 1;
                }
                continue;   
            }
            else if ( data1[2] == 0 ) {
// Modified by Gates Hua , for fix a bug about label and equ(const) symbol same name.
                if(symFlag){
                   retCode = SymAddLabelPublic( (LPSTR)data,ui );
                   if ( retCode != GOOD ) g_nErrorNumber = 1;
                }
                continue;   
            }
            else if ( data1[2] == 9 ) {
                isConst = TRUE;
                isValid = TRUE;
            }
            else {
                isConst = FALSE;
                isValid = TRUE;
            }
            if ( registerClass == NOT_REG ) {
                if ( typeIndex == BI_UNKNOWN ) {
                    addr.addr.segType = SEG_CODE;
                }
                else if ( typeIndex == BI_BIT ) {
                    addr.addr.segType = SEG_DATA;
//                  addr.addr.segType = SEG_BIT;
                }
                else addr.addr.segType = SEG_XDATA;
                addr.addr.addr = ui;
            }
            else {
                registerClass = NOT_REG ;
                addr.addr.segType = SEG_DATA;
                addr.addr.addr = ui;
//              addr.registerIndex = ui;
            } 
            if(symFlag){
               retCode = SymAddVar( (LPSTR)data , typeIndex , 
                        varStorage , registerClass ,
                        &addr, isConst,isValid,&symDesc);
               if ( retCode != GOOD ) g_nErrorNumber = 1;
//             if ( retCode != GOOD ) {
//                 m_dwErrorNum = 0x4025;
//                 return( FAILURE );
            }
        }
    }   
    return 0;
}
                                            
/***************************************************************************
*                                                                          *
*  LdrIntelHexDownload - Intel hex format main process routine             *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::LdrIntelHexDownload(void)
{
unsigned int old_pc;
int err;
unsigned char *ptr;
unsigned int next_pc;
unsigned char dw_buf[512];
// Modified by Gates Hua 9/02/97 for optimize download file speed
//int dw_byte;
//unsigned char dw_buf2[512];
int i,j;    
CString sss;

    dw_byte = 0;
    next_pc = 0;
    ptr = dw_buf2;                              
    if ( m_window == LOAD_FROM_SHELL) {
        ErrGetErrorText(ERI_LDR_DOWNLOAD,(LPSTR)dw_buf);
        ShowLine((LPSTR)dw_buf);
//        ShowLine("Download file : ");
    }
    for (;;) {
        if ( (err = TestKey(VK_ESCAPE)) == 1 ) {
            m_dwErrorNum = ER_LDR_ABORT;        // 0x4010;
            return( -1 );
        } 
        if ( (m_window == LOAD_FROM_DIALOG)&&(m_ldrFlags & LDR_STATUS) ) {
            if ( IsLoadCanceled() ) {
                m_dwErrorNum = ER_LDR_ABORT;    // 0x4010;
                return( -1 );
            }                  
            TestMessage();
        }
        if ( GetBytes(dw_buf , 9) == -1 ) {
            m_dwErrorNum = ER_LDR_FILE_FORMAT;      // 0x4014;
            m_bDispOff = 1;
            m_dwOffset = GetFileCurPos();
            return(-1);                        
        }                            
        switch (dw_buf[8]) {
        case '2':
            if ( GetBytes(dw_buf , 8) == -1 ) {
                m_dwErrorNum = ER_LDR_FILE_FORMAT;  // 0x4014;
                m_bDispOff = 1;
                m_dwOffset = GetFileCurPos();
                return(-1);                        
            }    
            break;                        
        case '0':
            old_pc = 0;
            for (i=0;i<4;i++) old_pc = (old_pc << 4) + asc__h(dw_buf[3+i]);
            if (dw_byte && (old_pc != next_pc)) {
                ADDR stAddr , endAddr;

                //for bank switching   
                if(g_nBankNum){
                    stAddr.addrType = endAddr.addrType = 6;    
                }
                else
                    stAddr.addrType = endAddr.addrType = 1;
                //for load to x area                    
                if ( LOAD_TODATA( m_ldrFlags ) ){
                    stAddr.addrType = endAddr.addrType = 2;
                }
                //for load to specified bank
                if(g_nBankNum){   
                   if(m_bLoadToBank&&m_window==LOAD_FROM_SHELL){
                      stAddr.addrType = endAddr.addrType = U8(m_bLoadToBank);
                   }
                }
                stAddr.addr=(unsigned short)(next_pc-(unsigned int) dw_byte);
                endAddr.addr=(unsigned short)(next_pc - 1);

#ifdef _ZLR_                
                err=AbiFill(stAddr , endAddr , (char *)dw_buf2 , dw_byte);
                if ( err != ICE_OK ) {
                    m_dwErrorNum = ER_ICE_FAIL_MEM_WRITE;   // 0x4002;
                    return(-1);
                }
                displayPC( stAddr.addr );
#endif              
                ptr = dw_buf2;

                uLoadBytes += (U32)dw_byte;

                dw_byte = 0;
            }
            j = (int) asc2hex(dw_buf[1],dw_buf[2]);
            
            dw_byte += j;
            next_pc = old_pc + (unsigned int) j;
            j = j*2;
            if ( GetBytes(&dw_buf[9] , j+4) == -1 ) {
                m_dwErrorNum = ER_LDR_READ_FILE;    // 0x400f;//0x4014;
                m_bDispOff = 1;
                m_dwOffset = GetFileCurPos();
                return(-1);                        
            }
#ifndef _ZLR_           
            else {            
                dw_buf[j+11] = '\0';
                if ( m_window == LOAD_FROM_SHELL) 
                    ShowLine( (char *) dw_buf );
            }
#endif          
            
            for (i=0; i < j; i += 2)
                *ptr++ = asc2hex(dw_buf[9+i], dw_buf[i+10]);
            
            if (dw_byte >= 255) {
                ADDR stAddr , endAddr;

                                //for bank switching   
                if(g_nBankNum){
                    stAddr.addrType = endAddr.addrType = 6;    
                }
                else
                    stAddr.addrType = endAddr.addrType = 1;
                //for load to x area                    
                if ( LOAD_TODATA( m_ldrFlags ) ){
                    stAddr.addrType = endAddr.addrType = 2;
                }
                //for load to specified bank
                if(g_nBankNum){
                   if(m_bLoadToBank&&m_window==LOAD_FROM_SHELL){
                      stAddr.addrType = endAddr.addrType = U8(m_bLoadToBank);
                   }   
                }
                stAddr.addr=(unsigned short)(next_pc-(unsigned int) dw_byte);
                endAddr.addr=(unsigned short)(stAddr.addr + 254);

#ifdef _ZLR_                                
                err=AbiFill(stAddr , endAddr , (char *)dw_buf2 , 255);
                if ( err != ICE_OK ) {
                    m_dwErrorNum = ER_ICE_FAIL_MEM_WRITE;   // 0x4002;
                    return(-1);
                }
#endif
                uLoadBytes += 255L;
                
                dw_byte -= 255;
                ptr = &dw_buf2[dw_byte];
                if ( dw_byte ) {
                    memcpy( dw_buf2 , &dw_buf2[255] , dw_byte );
                }   

#ifdef _ZLR_                
                displayPC( stAddr.addr );
#endif
                
            }
            break;
        case '1':
            if (dw_byte) {
                ADDR stAddr , endAddr;

                if(g_nBankNum){
                    stAddr.addrType = endAddr.addrType = 6;    
                }
                else
                    stAddr.addrType = endAddr.addrType = 1;
                //for load to x area                    
                if ( LOAD_TODATA( m_ldrFlags ) ){
                    stAddr.addrType = endAddr.addrType = 2;
                }
                //for load to specified bank
                if(g_nBankNum){
                   if(m_bLoadToBank&&m_window==LOAD_FROM_SHELL){
                      stAddr.addrType = endAddr.addrType = U8(m_bLoadToBank);
                   }
                }
                stAddr.addr=(unsigned short)(next_pc-(unsigned int) dw_byte);
                endAddr.addr=(unsigned short)(next_pc - 1);

#ifdef _ZLR_                                
                err=AbiFill(stAddr , endAddr , (char *)dw_buf2 , dw_byte);
                if ( err != ICE_OK ) {
                    m_dwErrorNum = ER_ICE_FAIL_MEM_WRITE;   // 0x4002;
                    return(-1);
                }
                displayPC( stAddr.addr );
#endif
                
                ptr = dw_buf2;

                uLoadBytes += (U32)dw_byte;

                dw_byte = 0;
            }
            return (0);
        case '3':
            j = (int) asc2hex(dw_buf[1],dw_buf[2]);
            j *= 2;
            if ( GetBytes(dw_buf , j+4) == -1 ) {
                m_dwErrorNum = ER_LDR_READ_FILE;    // 0x4014;
                m_bDispOff = 1;
                m_dwOffset = GetFileCurPos();
                return(-1);                        
            }    
            old_pc = 0;
            for (i=0;i<4;i++) old_pc = (old_pc << 4) + asc__h(dw_buf[i]);
            m_startaddress = (U32) old_pc;
#ifdef _DUMP_
            Message("   Starting Address: %lx",m_startaddress);
#endif
            break;          
        default:
#ifdef _DUMP_
            Message("\r\n???Unknown hex tag at file %lx",
                            GetFileCurPos()-9);
#endif
            m_dwErrorNum = ER_LDR_FILE_FORMAT;      // 0x4014;
            m_bDispOff = 1;
            m_dwOffset = GetFileCurPos();
            return(-1);
            break;                             
        }
    }
    return (0);     // unreachable code
}        /* end of downrecord() */

/***************************************************************************
*                                                                          *
*  asc__h - convert a ascii char to hex value                              *
*  parameter :                                                             *
*       a     ----     ascii char '0'-'F'                                  *
*  return value :                                                          *
*       value of a                                                         *
*                                                                          *
***************************************************************************/
unsigned char asc__h(unsigned char a)
{
    if ( (a>='0')&&(a<='9') ) a = (unsigned char)(a-'0');
    else if ( (a>='A')&&(a<='F') ) a = (unsigned char)(a-'A'+10);
    else if ( (a>='a')&&(a<='f') ) a = (unsigned char)(a-'a'+10);
    else a = 0;
    return( a );
}

/***************************************************************************
*                                                                          *
*  asc2hex - convert two ascii char to hex value                           *
*  parameter :                                                             *
*       a     ----     high half-byte char '0'-'F'                         *
*       b     ----     low  half-byte char '0'-'F'                         *
*  return value :                                                          *
*       value of ab                                                        *
*                                                                          *
***************************************************************************/
unsigned char asc2hex(unsigned char a,unsigned char b)
{
   unsigned char r;
   r = asc__h(a);
   r = (unsigned char) ((r << 4) | asc__h(b));
   return(r);
}

/***************************************************************************
*                                                                          *
*  displayPC - display pc value string                                     *
*  parameter :                                                             *
*       addr  ----     pc value                                            *
*  return value :                                                          *
*       NONE                                                               *
*                                                                          *
***************************************************************************/
void LoaderServer::displayPC(U16 addr)
{
    char tempStr[100];
    int l , i , j;

    ErrGetErrorText(ERI_LDR_DOWNLOAD, tempStr);
//    sprintf(tempStr , "Download file : ");
    l = strlen(tempStr);
    for( i=0; i < 4;i++) {
        j = addr & 0x000F;
        if ( j < 10 ) tempStr[3-i+l] = (char) ('0' + j);
        else tempStr[3-i+l] = (char) ('A' + j - 10);
        addr = addr >> 4;
    }
    tempStr[4+l] = '\0';                         

    if ( m_window == LOAD_FROM_SHELL ) {
        if ( LOAD_WARNING(m_ldrFlags) ) {
            ShlReshowLine(tempStr , 4+l);
        }
    }
}        /* end of displayCSIP() */

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