// ldricc.cpp : implementation file
//

#include "stdafx.h"

#include "abiextfn.h"
#include "ldrsvr.h"
#include "ldricc.h"
#include "bankinit.h"
#include "hosterrs.h"
#include "srcexp.h" 
#include "cpusvr.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CLdrOMF96

 CLdrICC196::CLdrICC196(LPCSTR lpsczFile , int nFlag, int where)
 {
  // Load File Full Path
   m_strFile = lpsczFile; 
  // Compiler Type
   m_nCompilerType = LDR_ICC196;  
  // flag of loader
   m_nLdrOptFlag = nFlag;
  // Hi Byte before or after 
   m_bHiLoFlag = 0; 
   m_bIsAssemble = 0;
  // init list
   varExtHdrPtr=varExtPtr=NULL;
   attrExtHdrPtr=attrExtPtr=NULL; 
   m_CurSymbol = NULL;
   
   //for bank switching
   m_bSwitchOn = 0;
   m_bCallAddr = 0;
   m_bRetAddr = 0;
   m_uGROff = 0;
   m_uLROff = 0;
   m_uCallAddr = 0xffff;
   m_uRetAddr = 0xffff;
   m_uBankLow = 0;  
   m_bBankLow=0;
   
   if(nFlag&0xff00) m_nLoadToBank = U8((nFlag&0xff00)>>8);

   //for multiple loaded
#ifndef _LONG_          
   if(where==0)  SymRemoveSymbols();
#endif
   m_bSpecSymbol =  LOAD_SYSTEM(nFlag)?1:0;

 }

 CLdrICC196::~CLdrICC196()
 {                       
   InitList();
 }

 
 void CLdrICC196::InitList( void )
 {
    struct StoreExtendVar *temp;
    struct attrCC *tmp;

    varExtPtr = varExtHdrPtr ;
    while ( varExtPtr ) {
        temp = varExtPtr->next ;
        if(varExtPtr->name){
           delete varExtPtr->name;
           varExtPtr->name = 0;
        }
        delete varExtPtr ;
        varExtPtr = temp;
    }
    varExtPtr = varExtHdrPtr = 0;

    attrExtPtr = attrExtHdrPtr ;
    while(attrExtPtr){
          tmp = attrExtPtr->next ;
          delete attrExtPtr ;
          attrExtPtr = tmp;
    }
    attrExtPtr = attrExtHdrPtr = 0;
 }

 void CLdrICC196::UbrofTypeConv(U16& ti)
 {
    if(ti >= 0x64){
       ti += 156;
    }
    else {
       switch( ti ) {
       case 0 :
            ti = BI_UNKNOWN;
            break;
       case 1 :
            ti = BI_U8_UCHAR;
            break;
       case 2 :    /* signed char */
            ti = BI_S8_CHAR;            
            break;             
       case 3 :
            ti = BI_S16_USHORT;
            break;
       case 4 :
            ti = BI_S16_SHORT;
            break;
       case 5 :
            ti = BI_U16_UINT;
            break;
       case 6 :             
            ti = BI_S16_SINT;
            break;
       case 7 :             
            ti = BI_U32_ULONG;
            break;
       case 8 :
            ti = BI_S32_LONG;
            break;
       case 9 :
            ti = BI_F32;
            break;
       case 10 :
       case 0x0B :
            ti = BI_F64;
            break;
       case 0x0C :
            ti = BI_VOID;
            break;
       default :
            ti = BI_UNKNOWN;
            break;
       }
    }
 } //end of function          

 void CLdrICC196::UbrofMatchFuncType(LPSTR str , TYPE_INDEX& typeIndex)
 {
   struct StoreExtendVar *temp;

   temp = varExtHdrPtr ;
   while(temp){
         if(0 == _fstrcmp(LPSTR(temp->name) , str)){
             break;
         }
         temp = temp->next;
    }
    if (temp) {
        U16 ti ;
        
        ti = temp->typeindex;
        UbrofMatchAttrType( ti );
        UbrofTypeConv( ti );
        typeIndex = (U32) ti;
    }
    else typeIndex = 0;
}

 void CLdrICC196::UbrofMatchAttrType(U16& uType)
 {
   struct attrCC *temp;

   temp = attrExtHdrPtr ;
   while(temp){
         if(uType == temp->num){
            break;
         }
         temp = temp->next;
   }
   if(temp){
      uType = (U16)temp->type;
   }
 }              

 BOOL CLdrICC196::UbrofProcessModSym(void)
 {
    ASSERT(m_CurSymbol!=NULL);
    
    U16 ti;
    U32 address;     
    VAR_STORAGE_CLASS varStorage;
    VAR_REGISTER_CLASS registerClass;
    BOOLEAN isConst , isValid ;
    ADD_VAR_ADDR_UNION addr;
#ifndef _LONG_    
    SYM_DESCRIPTOR symDesc;
#endif    
    CPUMEMORYRANGE cmr;
           
    varStorage = GLOBAL_VAR_CLASS;                     
    registerClass = NOT_REG;
    address = m_CurSymbol->addr;
    //for multiple loaded
    if(m_nLoadToBank){
       if(m_CurSymbol->segnum==1||m_CurSymbol->segnum==3){
          ConvertAddrToBank(address);
       }
    }
    
    //if(m_CurSymbol->segnum == 6 ) isValid = FALSE ;
    //else isValid = TRUE; 
    isValid = TRUE;
    //if(m_CurSymbol->segnum == 7 ) isConst = TRUE;
    //else isConst = FALSE;
    isConst = FALSE;
    if (isValid) {
        if(m_CurSymbol->SC==1||m_CurSymbol->SC==3){
           GetMemoryRange(cmr);
           if(cmr.iMax > ((U16)address)) addr.addr.segType=SEG_DATA;
           else addr.addr.segType = SEG_CODE;
        }
        else UbrofSegIdToEnum( (U8)m_CurSymbol->segnum , &addr.addr.segType );
        addr.addr.addr = address;
        if(addr.addr.segType==SEG_DATA){
           GetMemoryRange(cmr);
           if(cmr.iMax < ((U16)address)){
              if(m_nLoadToBank) ConvertAddrToBank(address);
              addr.addr.segType=SEG_XDATA;
           }
        }
    }
   /* else {
        registerClass = LIVING_REG;
        addr.registerIndex = (U16) address;
    }*/
    ti = m_CurSymbol->typeindex;
    UbrofMatchAttrType(ti);
    UbrofTypeConv(ti);                     
    if(m_CurSymbol->name[0] == '?' && !m_bSpecSymbol ) return 1;
    
#ifndef _LONG_
    if(GOOD != SymAddVar((LPSTR)m_CurSymbol->name,ti,
       varStorage,registerClass,&addr,isConst,
       isValid,&symDesc)) {
       if(m_bIsAssemble){
		  SymAddVar((LPSTR)m_CurSymbol->name,BI_UNKNOWN,
		     varStorage,registerClass,&addr,isConst,
		     isValid,&symDesc);
	   }
       
       if(varExtHdrPtr){
          varExtPtr->next = new StoreExtendVar;
          if(varExtPtr->next == 0 ) {
             m_dwErrMsg = ER_LDR_MEMORY_ALLOC;		
             return 0;
          }
          (varExtPtr->next)->name = new U8[strlen((const char*)m_CurSymbol->name)+1];
          varExtPtr = varExtPtr->next;
        }
        else {          
            varExtHdrPtr = varExtPtr = new StoreExtendVar;
            varExtPtr->name = new U8[strlen((const char*)m_CurSymbol->name)+1];
            if(varExtPtr == 0 ) {
               m_dwErrMsg = ER_LDR_MEMORY_ALLOC;		
               return 0;
            }
        }                       
        varExtPtr->typeindex = m_CurSymbol->typeindex;
        
        strcpy((LPSTR)varExtPtr->name , (const char*)(LPSTR)m_CurSymbol->name);
    }
#endif                          
    return 1;
 } //end of function  
 
 BOOL CLdrICC196::UbrofProcessBlockSym(void)
  {
    ASSERT(m_CurSymbol != NULL);
    
    U16 ti, segtype;
    U32 address;     
    
    VAR_STORAGE_CLASS varStorage;
    VAR_REGISTER_CLASS registerClass;
    BOOLEAN isConst , isValid ;
    ADD_VAR_ADDR_UNION addr;
#ifndef _LONG_    
    SYM_DESCRIPTOR symDesc;
#endif    
    registerClass = NOT_REG;
    address = m_CurSymbol->addr;  
    //for multiple loaded
    segtype = m_CurSymbol->segnum;
    if(m_nLoadToBank){
       if(segtype==1) ConvertAddrToBank(address);
    }
       
    ti = m_CurSymbol->typeindex;
    
    if(m_CurSymbol->SC==7) varStorage = AUTO_VAR_CLASS ;
    else if(m_CurSymbol->SC== 4) varStorage = STATIC_VAR_CLASS ;
    else if(m_CurSymbol->SC== 8) {
        varStorage = AUTO_VAR_CLASS ;
        registerClass = LIVING_REG;
    }
    else {
        varStorage = UNKNOWN_VAR_CLASS ;
        return 1;
    }
    //if(segtype == 6) isValid = FALSE ;
    //else isValid = TRUE;
    isValid = TRUE;
    //if(segtype == 7) isConst = TRUE;
    //else isConst = FALSE;
    isConst = FALSE;
    
    if(segtype == 6){
       registerClass = LIVING_REG;
       addr.registerIndex = (U16)address;
    }
    else{
       if(m_CurSymbol->SC==7) addr.autoVar = (U16)address;
       else{
		   UbrofSegIdToEnum((U8)segtype , &addr.addr.segType );
		   addr.addr.addr = address;
	        if(addr.addr.segType==SEG_DATA){
	           CPUMEMORYRANGE cmr;
	           
	           GetMemoryRange(cmr);
	           if(cmr.iMax < ((U16)address)){
	              ConvertAddrToBank(address);
	              addr.addr.segType=SEG_XDATA;
	           }
	        }
       }
    }

    UbrofMatchAttrType(ti);
    UbrofTypeConv(ti);
    if(m_CurSymbol->name[0] == '?' && !m_bSpecSymbol ) return 1;

#ifndef _LONG_    
    if(GOOD != SymAddVar((LPSTR)m_CurSymbol->name,ti,varStorage,
        registerClass,&addr,isConst,isValid,&symDesc) ) {
        m_dwErrMsg = ER_LDR_SYM_SERVER;	
        return 0;
    }        
#endif    
    return 1;
 }//end of function

 void  CLdrICC196::UbrofSegIdToEnum(U8 ui , SEGMENTTYPE* type)
{
    switch (ui) {
    case 0:
        *type = SEG_UNTYPED ;
        break;
    case 1:         
        *type = SEG_CODE ;
        break;
    case 2:
    case 4:
        *type = SEG_DATA ;
        break;
    case 3:
        *type = SEG_XDATA ;
        break;
    case 5:
        *type = SEG_BIT ;
        break;
    case 6:
        *type = SEG_REGISTER ;
        break;
    case 7:
        *type = SEG_CONST ;
        break;
    default :
        *type = SEG_UNTYPED ;
        break;
    }
 }//end of function

 BOOL CLdrICC196::AddLineToSym(SYM_DESCRIPTOR moduleDesc )
  {
#ifndef _LONG_    
    RETCODE retCode;
#endif    
    SOURCE_RANGE_TYPE srcState;
    ADDR_RANGE_TYPE addrState;
 
    if(m_modNode.linecnt == 0){
#ifndef _LONG_
       retCode = SymAddLinenumStart(moduleDesc);
       if(retCode != GOOD){
          m_dwErrMsg = ER_LDR_SYM_SERVER;
          return 0;
       }
#endif       
    }
    srcState.lineNumStart=BinToU16(m_uLineInfo);
    srcState.columnStart=BinToU16(&m_uLineInfo[2]);
    srcState.lineNumEnd=BinToU16(&m_uLineInfo[4]);
    srcState.columnEnd=BinToU16(&m_uLineInfo[6]);
    addrState.startAddr=stat_addr.start.addr;
    addrState.endAddr=stat_addr.end.addr;
    addrState.segType=SEG_CODE;
#ifndef _LONG_    
    if(m_nLoadToBank){
    	if(addrState.startAddr != DEFAULT_START_ADDR &&
    	   addrState.endAddr != DEFAULT_END_ADDR) {
       	   ConvertAddrToBank(addrState.startAddr);
       	   ConvertAddrToBank(addrState.endAddr);
       	}
    }
    
    retCode = SymAddSourceState(&srcState , &addrState);
    if(retCode != GOOD){
       m_dwErrMsg = ER_LDR_SYM_SERVER;	
       return 0;
    }
#endif    
    return 1;
 }//end of function
 
 void CLdrICC196::AdjustModBlkRange(U8 uTag)
  {
   if(m_pCurBlock == 0) return;
   if(m_pCurBlock){
      if(m_pCurBlock->codeaddr.startAddr>
                     stat_addr.start.addr) 
         m_pCurBlock->codeaddr.startAddr = stat_addr.start.addr;
      if(m_pCurBlock->codeaddr.endAddr < 
                       stat_addr.end.addr) 
         m_pCurBlock->codeaddr.endAddr = stat_addr.end.addr;
   }                           
   if(m_uStart > stat_addr.start.addr) 
            m_uStart = stat_addr.start.addr;
   if(m_uEnd < stat_addr.end.addr) 
            m_uEnd = stat_addr.end.addr;
   stat_addr.start.addr = DEFAULT_START_ADDR;
   stat_addr.end.addr = DEFAULT_END_ADDR;
   stat_addr.flag = 0;
   if(uTag==t_src_stat) return;
   
   if(m_pCurBlock->father){
      if(m_pCurBlock->father->codeaddr.startAddr
                            > m_pCurBlock->codeaddr.startAddr) {
         m_pCurBlock->father->codeaddr.startAddr =
                              m_pCurBlock->codeaddr.startAddr;
      }
      if(m_pCurBlock->father->codeaddr.endAddr
                            < m_pCurBlock->codeaddr.endAddr) {
         m_pCurBlock->father->codeaddr.endAddr =
                              m_pCurBlock->codeaddr.endAddr;
      }                   
    }
    else {
       if(m_uStart > m_pCurBlock->codeaddr.startAddr )
          m_uStart = m_pCurBlock->codeaddr.startAddr;
          if(m_uEnd < m_pCurBlock->codeaddr.endAddr) {
             m_uEnd = m_pCurBlock->codeaddr.endAddr;
          }                   
     }
    m_qaddr.startAddr = m_pCurBlock->codeaddr.startAddr;
    m_qaddr.endAddr = m_pCurBlock->codeaddr.endAddr;
    m_qaddr.startValid = TRUE;
    m_qaddr.endValid = TRUE;                      
    if(m_qaddr.startAddr > m_qaddr.endAddr){
       m_qaddr.startValid = FALSE;
       m_qaddr.endValid = FALSE;
    }
   
 }//end of function

 BOOL CLdrICC196::AddFunToSym(U8* name, U8* data)
  {
#ifndef _LONG_    
    RETCODE retCode;
#endif    
    FUNC_CLASS funcClass;

    ASSERT(m_pCurBlock==NULL);
    m_pCurBlock = new BlockBlock;
    if(m_pCurBlock == 0){
       m_dwErrMsg = ER_LDR_MEMORY_ALLOC;		
       return 0;
    }
    m_pCurBlock->scope = m_modNode.scope;
    m_pCurBlock->codeaddr.segType=(SEGMENTTYPE)SEG_CODE;
    m_pCurBlock->codeaddr.startAddr = DEFAULT_START_ADDR ;
    m_pCurBlock->codeaddr.endAddr = DEFAULT_END_ADDR ;
    m_pCurBlock->funcName = (LPSTR)name;
    m_pCurBlock->srcRange.lineNumStart = BinToU16(data);
    m_pCurBlock->srcRange.columnStart = BinToU16(&data[2]);
    m_pCurBlock->srcRange.lineNumEnd = BinToU16(&data[4]);
    m_pCurBlock->srcRange.columnEnd = BinToU16(&data[6]);
    if(m_pCurBlock->scope != 1 ) funcClass = FUNC_LOCAL ;
    else funcClass = FUNC_GLOBAL;
    UbrofMatchFuncType( m_pCurBlock->funcName , m_pCurBlock->typeIndex );
#ifndef _LONG_    
    retCode = SymAddFuncCreate(     
                  m_pCurBlock->funcName ,
                  funcClass ,
                  m_pCurBlock->stacksize ,
                  &(m_pCurBlock->codeaddr) ,
                  m_pCurBlock->typeIndex,
                  0,
                  0,
                  0,
                  0 );
    if(retCode != GOOD){
       m_dwErrMsg = ER_LDR_SYM_SERVER;	
       return 0;
     }      
#endif               
    return 1;
  }//end of function
  
  BOOL CLdrICC196::AddBlkOfFuncToSym()
   {
     ASSERT(m_pCurBlock);
  
#ifndef _LONG_     
     RETCODE retCode;
#endif     
     FUNC_CLASS funcClass;
     
     m_pCurBlock->son = new BlockBlock;
     ASSERT(m_pCurBlock->son);                        
     if(m_pCurBlock->son == 0){
        m_dwErrMsg = ER_LDR_MEMORY_ALLOC;		
        return 0;
     }
     m_pCurBlock->son->father = m_pCurBlock ;
     m_pCurBlock = m_pCurBlock->son;
     m_modNode.scope++;
     m_pCurBlock->scope = m_modNode.scope;
     m_pCurBlock->codeaddr.segType = (SEGMENTTYPE) SEG_CODE;
     m_pCurBlock->codeaddr.startAddr = DEFAULT_START_ADDR ;
     m_pCurBlock->codeaddr.endAddr = DEFAULT_END_ADDR ;
     if(m_pCurBlock->scope != 1 ) funcClass = FUNC_LOCAL ;
     else funcClass = FUNC_GLOBAL;
#ifndef _LONG_     
     retCode = SymAddFuncCreate(     
                         "",
                   funcClass ,
                   m_pCurBlock->stacksize ,
                   &(m_pCurBlock->codeaddr) ,
                   m_pCurBlock->typeIndex,
                   0,
                   0,
                   0,
                   0 );
     if(retCode != GOOD){
        m_dwErrMsg = ER_LDR_SYM_SERVER;	
        return 0;
     }        
#endif     
     return 1;
   }//end of function               
 
  BOOL CLdrICC196::CloseFuncToSym()
   {  
      ASSERT(m_pCurBlock);
      
#ifndef _LONG_      
      RETCODE retCode;
#endif      
      
#ifndef _LONG_      
      retCode = SymAddFuncClose();
      if(retCode != GOOD){
         m_dwErrMsg = ER_LDR_SYM_SERVER;	
         return 0;
      }      
      if(m_qaddr.startValid || m_qaddr.endValid ) {
         if(m_nLoadToBank){
        	if(m_qaddr.startAddr != DEFAULT_START_ADDR &&
        		m_qaddr.endAddr != DEFAULT_END_ADDR ) {
           		ConvertAddrToBank(m_qaddr.startAddr);
           		ConvertAddrToBank(m_qaddr.endAddr);
           	}
         }
         retCode = SymAddSymbolSetAddr( &m_qaddr );
         if(retCode != GOOD){
         m_dwErrMsg = ER_LDR_SYM_SERVER;	
           return 0;
         }
      }
#endif      
      if(m_pCurBlock->father ) {
         m_pCurBlock = m_pCurBlock->father;
         ClearUpBlockBlock(m_pCurBlock->son);
         delete m_pCurBlock->son;
         m_pCurBlock->son = 0;
      }
      else {
         ClearUpBlockBlock(m_pCurBlock);
         delete m_pCurBlock ;
         m_pCurBlock = 0;
      }
      return 1;
  }//end of function
 
 int CLdrICC196::JutifyBank()
  {
    int nBankNum;                                         
    
    if(m_bSwitchOn){
       m_nMemMode = DllLdrGetMemMode();
       m_nBankNum = DllLdrGetBankNumber();
    }   
    nBankNum = int(m_uCurAddr.addr >> 16); 
    if(!m_bSwitchOn&&nBankNum){
       m_dwErrMsg = ER_LDR_NO_BANK;
       return 0;
    }
    else{
       if(!m_bBankLow){
          //m_dwErrMsg = ER_LDR_CONTL_FILE;
          return 0;
       }
       if(m_nBankNum*2<=nBankNum){
          m_dwErrMsg = ER_LDR_BANKSIZE;
          return 0;
       }
    }
    if((U16)m_uCurAddr.addr<m_uBankLow) return 2;
    return 1;
 }
 
 BOOL CLdrICC196::FillCodeToMem(U8 * data)
  {
    ADDR stAddr , endAddr;
    int err=0;    
    int nBankNum;
    U8 dwBytes;
    
#ifdef _LINK_ABI
    RET_ADDR ret;
#endif    
    
    dwBytes = m_uCurByte;
    if(m_uCurAddr.type == SEG_CODE || m_uCurAddr.type == SEG_CONST||
        m_uCurAddr.type == SEG_UNTYPED ) {

       if(m_bSwitchOn)
          if((err = JutifyBank())==0) return 0;
   
       nBankNum = int(m_uCurAddr.addr >> 16); 
       stAddr.addrType = endAddr.addrType = U16(nBankNum+1);
       //for multiple loaded
       if(m_nLoadToBank){
          stAddr.addrType = endAddr.addrType = U16(m_nLoadToBank);
       }
       endAddr.addr=(unsigned short)(m_uCurAddr.addr+ m_uCurByte-1);
       
#ifdef _LINK_ABI
       int pos=0;
       
       if(err == 2){
          for(int i=0;i<m_nBankNum*2;i++){
              stAddr.addrType = endAddr.addrType = U16(i+1);
              pos = 0;
	          while(int(dwBytes) > 120){
                  stAddr.addr=(unsigned short)m_uCurAddr.addr+pos;
		          err=emuSetMemN(stAddr, &data[pos], 120, &ret);
		          if(err!=ICE_OK){
                     m_dwErrMsg = ER_ICE_ERROR_WRITE;	
		             return 0;
		          }        
		          pos += 120;       
		          dwBytes -= 120;
		      }
              stAddr.addr=(unsigned short)m_uCurAddr.addr+pos;
	          err=emuSetMemN(stAddr, &data[pos], U16(dwBytes), &ret);
	          if(err!=ICE_OK){
	            m_dwErrMsg = ER_ICE_ERROR_WRITE;	
	             return 0;
	          }
	          dwBytes = m_uCurByte;
	      }
	   }
	   else{
	          while(int(dwBytes) > 120){
                  stAddr.addr=(unsigned short)m_uCurAddr.addr+pos;
		          err=emuSetMemN(stAddr, &data[pos], 120, &ret);
		          if(err!=ICE_OK){
		            m_dwErrMsg = ER_ICE_ERROR_WRITE;
		             return 0;
		          }        
		          pos += 120;       
		          dwBytes -= 120;
		      }
              stAddr.addr=(unsigned short)m_uCurAddr.addr+pos;
	          err=emuSetMemN(stAddr, &data[pos], U16(dwBytes), &ret);
	          if(err!=ICE_OK){
	            m_dwErrMsg = ER_ICE_ERROR_WRITE;	
	             return 0;
	          }
	      }
#endif                  
       m_dwLoadBytes += (U32)m_uCurByte;
     }                  
     else {
       //Warning( ER_CODE_NOT_IN_CODESEG );
       return 0;
     }              
     return 1;
  }//end of function

 BOOL CLdrICC196::LoadProcess()
 {
   
   U8 uTag,data[2],*temp;
#ifndef _LONG_
   int err;
#endif   
   if(!LoadStarter()) return 0;
   
   if(!GetOneByte(&uTag)){
      m_dwErrMsg = ER_LDR_READ_FILE;
      return 0;
   }
   
   while(1){
#ifndef _LONG_
      if((err = TestKey(VK_ESCAPE)) == 1){
          m_dwErrMsg = ER_LDR_ABORT;	
          return 0;
      } 
      if((m_where == LOAD_FROM_DIALOG)&&(m_nLdrOptFlag&LDR_STATUS)){
          if(SrcIsLoadAbort()){
             m_dwErrMsg = ER_LDR_ABORT;	
             return 0;
           }                  
          TestMessage();
      }
#endif
      switch(uTag){
        case t_version:
             if(!GetVersionInfo()) return 0;
             break;
        case t_seg_info:
             if(!GetSegInfo()) return 0;
             break;
        case t_def_ptr_types:
             temp = new U8[5];
             if(temp==NULL){
                m_dwErrMsg = ER_LDR_MEMORY_ALLOC;
                return 0;
             }
             if(!GetBytes(temp,5)){
                m_dwErrMsg = ER_LDR_READ_FILE;
                delete temp;
                return 0;
             }
             delete temp;
             break;
        case t_type:
             if(!LoadTypes(uTag)) return 0;
             break;
        case t_grp:     
             if(!GetGrpInfo()) return 0;
             break;
        case t_end:
             if(!GetBytes(data,2)){
                m_dwErrMsg = ER_LDR_READ_FILE;
                return 0;
             }
             break;
        case t_beg_lib:
        case t_beg_pgm:
             if(!LdrGetModule(uTag)) return 0;
             break;
        default:
             m_dwErrMsg = ER_LDR_FILE_FORMAT;
             return 0;         
       }
   
       if(!GetOneByte(&uTag)){
          m_dwErrMsg = ER_LDR_READ_FILE;
          return 0;
       }
#ifdef _DUMP_
       long pos = GetFileCurPos();
#endif       
       if(uTag == t_ubrof_eof) return 1;
   }//end of while
 }//end of function
                             
 
 BOOL CLdrICC196::LoadStarter()
  {
    U8 data[7];     
    CString filename;
#ifndef _LONG_
    RETCODE retCode;
#endif
    
    if (!GetOneByte(&m_uCurByte)) {
        m_dwErrMsg = ER_LDR_READ_FILE;	
        return 0;                        
    }
    switch (m_uCurByte ) {
    case t_beg_file :
        if (! GetBytes(data , 3)){
            m_dwErrMsg = ER_LDR_READ_FILE;	 
            return 0;
        }
        m_time.day = data[0];
        m_time.month = data[1];                
        m_time.year = 1900 ;
        m_time.year +=  ( (U16) data[2] ) ; 
        m_time.hour = -1;
        break;
    case t_beg_file1 :
        if (! GetBytes(data , 6)) {
            m_dwErrMsg = ER_LDR_READ_FILE;	
            return 0;
        }      
        m_time.second = data[0];
        m_time.minute = data[1];
        m_time.hour = data[2];
        m_time.day = data[3];
        m_time.month = data[4];                
        m_time.year = 1900 ;
        m_time.year +=  ( (U16) data[5] ) ; 
        m_time.hour = -1;
        break;
    default :
#ifdef _DUMP_
		Message("\r\n???Unknown record in STARTER at file %lx",
				GetFileCurPos()-1);
#endif
        m_dwErrMsg = ER_LDR_FILE_FORMAT;	
        return 0;
        break;
    }   
  if(LOAD_SYM(m_nLdrOptFlag)){ 
       filename = m_strFileName;
#ifndef _LONG_ 
       if(!m_bAppSym){
	       retCode = SymAddLoadStart(
	                 filename.GetBuffer(filename.GetLength()) ,
	                 FALSE, &m_time );
	       if(retCode != 0){
	          m_dwErrMsg = ER_LDR_SYM_SERVER;
	          return 0;
	       } 
	   }
	   else{
	       retCode = SymAddLoadStartAgain();
           if ( retCode != GOOD ) {
                m_dwErrMsg = ER_LDR_SYM_SERVER;	
                return 0;
            }
       }
#endif
    }
    return 1;       
 }//end of function
 
 BOOL CLdrICC196::GetLenBytes(U8 tag)
  {
    U8 * data,temp[2];
    U16 tmp;
    if(!GetBytes(temp , 2)){
        m_dwErrMsg = ER_LDR_READ_FILE;	
        return 0;                        
    }                     
    tmp = BinToU16(temp);
    if(tag==t_symbol_def1||tag==t_func_begin1||
        tag==t_func_begin2||tag == t_block_begin1||
              tag == t_block_begin2) tmp *= 13;
    if(tmp==0) return 1;
    data = new U8[tmp];       
    ASSERT(data);
    if(!GetBytes(data , tmp)){
       m_dwErrMsg = ER_LDR_READ_FILE;	
        delete data;
        return 0;                        
     }
    delete data;
    return 1;
 }                  
                           
 BOOL CLdrICC196::GetVersionInfo()
  { 
    U8 data[4], *tmp;           
    U8 uTagNo,uTag;
    
    if(!GetBytes(data,4)){
       m_dwErrMsg = ER_LDR_READ_FILE;
       return 0;
    }
    
    m_uMajorVer = data[0];
    m_uMinorVer = data[1];
    m_uRevision = data[2];
    
    uTagNo = data[4];
    
    while(uTagNo){
          if(!GetBytes(data,2)){
             m_dwErrMsg = ER_LDR_READ_FILE;
             return 0;
          }
          uTag = data[0];
          if(data[1]<0x80){
             tmp = new U8[data[1]];
             if(tmp == NULL){
                m_dwErrMsg = ER_LDR_MEMORY_ALLOC;
                return 0;
             }
             if(!GetBytes(tmp,data[1])){
                m_dwErrMsg = ER_LDR_READ_FILE;
                 delete tmp;
                 return 0;
             }
             delete tmp;
          }
          else if(data[1]==0xfd){
             if(!GetOneByte(&m_uCurByte)){
                m_dwErrMsg = ER_LDR_READ_FILE;
                return 0;
             }
          }
          else if(data[1]==0xfe){
             if(!GetBytes(data,2)){
                m_dwErrMsg = ER_LDR_READ_FILE;
                return 0;
             }
          }
          else if(data[1]==0xff){
             if(!GetBytes(data,4)){
                m_dwErrMsg = ER_LDR_READ_FILE;
                return 0;
             }
          }
          else{
             m_dwErrMsg = ER_LDR_FILE_FORMAT;
             return 0;
          }
          uTagNo --;
    }//end of while
    return 1;
  }//end of function
  
 BOOL CLdrICC196::LoadTypes(U8 tag)
  {
    U8  data[3],Sub_Tag;
    U16 typeindex,index;
    int err;
    RETCODE retCode;
    
    while(1){
#ifndef _LONG_
        if((err = TestKey(VK_ESCAPE)) == 1){
            m_dwErrMsg = ER_LDR_ABORT;	
            return 0;
        } 
        if((m_where == LOAD_FROM_DIALOG)&&(m_nLdrOptFlag&LDR_STATUS)){
            if ( SrcIsLoadAbort() ) {
                m_dwErrMsg = ER_LDR_ABORT;	
                return 0;
            }                  
            TestMessage();
        }
#endif
        switch(tag){
          case t_end       :
          case t_grp       :
               UngetOneByte();
               return 1;
          case t_type      : /* 0x4A */
               if(!GetBytes(data , 3)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                  return 0;
               }
               typeindex = BinToU16(data) + 156;
               Sub_Tag = data[2];
               if(!LoadSubType(typeindex,Sub_Tag)) return 0;
               break;
          case t_size_type : /* 0x4F */
               if(!GetBytes(data , 2)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                  return 0;
               }
#ifndef _LONG_   
               if (LOAD_SYM(m_nLdrOptFlag) ) {
                   index = U16(data[0]);
                   UbrofTypeConv(index);
                   retCode = SymAddTypeOverwriteSize((U8)index , data[1]);
                   if(retCode != GOOD){
                      m_dwErrMsg = ER_LDR_SYM_SERVER;	
                      return 0;
                    }
               }
#endif
               break;
          default          :
#ifdef _DUMP_
		       Message("\r\n???Unknown type record at file %lx",
		                      GetFileCurPos()-1);
#endif
               m_dwErrMsg = ER_LDR_TYPE;
               return 0;
        }//end of switch
        
        if(!GetOneByte(&tag)){
           m_dwErrMsg = ER_LDR_READ_FILE;
           return 0;
        } 
#ifdef _DUMP_
       long pos = GetFileCurPos();
#endif
    }//end of while
  }//end of function
  
 BOOL CLdrICC196::LoadSubType(U16 ti,U16 subtag)
  {                 
     U8 *name;
     int i;
     U8 temp[8];
     U16 typeindex, memNo;
     U32 size;
#ifndef _LONG_     
     RETCODE retCode;
#endif     
     TYPE_S_U_STRUCT member;
     TYPE_HEADER_TYPE typeHdrInfo;
     
     typeHdrInfo.typeName = "\0";                    
     typeHdrInfo.sizeInMAUs = 0;      
     typeHdrInfo.sizeCalculated = FALSE;
     typeHdrInfo.typeChoice = (TYPE_CLASS) COMPLEX_TYPE_CLASS;
           
     switch(subtag){
       case t_type_pointer  : /* 0x0F */ 
            if(!GetBytes(temp , 2)){
               m_dwErrMsg = ER_LDR_READ_FILE;	
               return 0;
            }
            typeindex = BinToU16(temp);
            UbrofMatchAttrType(typeindex );
            UbrofTypeConv(typeindex );
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
               typeHdrInfo.sizeCalculated = TRUE;
               typeHdrInfo.sizeInMAUs = 0x03L;
               typeHdrInfo.t.complexType = TY_SMALL_PTR;
               retCode = SymAddTypeHeader(ti , &typeHdrInfo);
               if (retCode != GOOD ) {
                   m_dwErrMsg = ER_LDR_SYM_SERVER;
                   return 0;
               }
               retCode = SymAddTypePointerTypeIndex(ti , typeindex);
               if (retCode != GOOD ) {
                   m_dwErrMsg = ER_LDR_SYM_SERVER;	
                   return 0;
               }
             }
#endif
            break;
       case t_type_array : /* 0x10 */
            if (!GetBytes(temp , 8)){
                 m_dwErrMsg = ER_LDR_READ_FILE;	
                 return 0;
            }
            typeindex = BinToU16(temp);
            UbrofMatchAttrType(typeindex);
            UbrofTypeConv(typeindex);
            size = BinToU32(&temp[2]);
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
               TYPE_C_ARRAY_STRUCT arr;
              
               typeHdrInfo.sizeCalculated = TRUE;
               typeHdrInfo.sizeInMAUs = size;
               typeHdrInfo.t.complexType = TY_C_ARRAY;
               arr.typeIndex = typeindex;
               memNo = BinToU16(&temp[6]);
               arr.highBound = memNo - 1;
               retCode = SymAddTypeHeader(ti , &typeHdrInfo);
               if(retCode != GOOD ) {
                  m_dwErrMsg = ER_LDR_SYM_SERVER;	
                  return 0;
               }
               retCode = SymAddTypeCArray(ti , &arr);
               if(retCode != GOOD){
                  m_dwErrMsg = ER_LDR_SYM_SERVER;	
                  return 0;
               }
             }
#endif
            break;
       case t_type_struct : /* 0x11 */
            U8 * structname;
            
            if(!GetName(name)) return 0;
            typeHdrInfo.typeName = (LPSTR)name;
            if(!GetBytes(temp , 6)) {
               m_dwErrMsg = ER_LDR_READ_FILE;	
               if(name) delete name;
               return 0;
            }
            size = BinToU32(temp);
            memNo = BinToU16(&temp[4]);
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
                 typeHdrInfo.sizeCalculated = TRUE;
                 typeHdrInfo.sizeInMAUs = size;
                 typeHdrInfo.t.complexType = TY_STRUCT;
                 retCode = SymAddTypeHeader(ti , &typeHdrInfo);
                 if(retCode != GOOD) {
                    if(name) delete name; 
                    m_dwErrMsg = ER_LDR_SYM_SERVER;	
                    return 0;
               }
            }
#endif                  
            for(i=0;(unsigned int)i<memNo;i++) {
                if(!GetBytes(temp , 4)){ 
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   if(name) delete name;
                   return 0;
                }
                member.offset = (U16)BinToU32(temp);
                if(!GetName(structname)) return 0;
                ASSERT(structname);
                member.name = (LPSTR)structname ;
                if(!GetBytes(temp , 2)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   if(structname) delete structname;
                   if(name) delete name;
                   return 0;
                }
                typeindex = BinToU16(temp);
                UbrofMatchAttrType(typeindex);
                UbrofTypeConv(typeindex);
                member.typeIndex = typeindex;
#ifndef _LONG_
                if(LOAD_SYM(m_nLdrOptFlag)){
                   retCode = SymAddTypeStructUnion(ti , &member);
                   if(retCode != GOOD ) {
                      m_dwErrMsg = ER_LDR_SYM_SERVER;
                      if(structname) delete structname;	
                      if(name) delete name;
                      return 0;
                    }
                 }
#endif
                if(structname)  delete structname ;
            }//end of for
            if(name) delete name;
            break;
       case t_type_union : /* 0x12 */              
            U8 * unionname;
            
            if(!GetName(name)) return 0;
            typeHdrInfo.typeName = (LPSTR)name;
            if (!GetBytes(temp , 6)){
                m_dwErrMsg = ER_LDR_READ_FILE;	
                if(name) delete name;
                return 0;
            }
            size = BinToU32(temp);
            memNo = BinToU16(&temp[4]);
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
                 typeHdrInfo.sizeCalculated = TRUE;
                 typeHdrInfo.sizeInMAUs = size;
                 typeHdrInfo.t.complexType = TY_UNION;
                 retCode = SymAddTypeHeader(ti , &typeHdrInfo);
                 if(retCode != GOOD ) {
                    if(name) delete name;
                    m_dwErrMsg = ER_LDR_SYM_SERVER;	
                    return 0;
                 }
             }                   
#endif
            for(i=0;((unsigned int)i)<memNo ; i++) {
                if(!GetName(unionname)) return 0;
                ASSERT(unionname);
                member.name = (LPSTR)unionname;
                if(!GetBytes(temp , 2)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                    if(name) delete name;
                    if(unionname) delete unionname;
                    return 0;
                 }
                typeindex = BinToU16(temp);
                UbrofMatchAttrType(typeindex);
                UbrofTypeConv(typeindex);
                member.typeIndex = typeindex;
                member.offset = 0;
#ifndef _LONG_
                if(LOAD_SYM(m_nLdrOptFlag)){
                     retCode = SymAddTypeStructUnion(ti , &member);
                     if(retCode != GOOD){
                        if(name) delete name;
                        if(unionname) delete unionname;
                        m_dwErrMsg = ER_LDR_SYM_SERVER;	
                        return 0;
                     }
                  }
#endif
                if(unionname) delete unionname ;
            }//end of for                 
            if(name) delete name;
            break;
       case t_type_bits : /* 0x13 */
            if(!GetBytes(temp , 4)){
               m_dwErrMsg = ER_LDR_READ_FILE;	
               return 0;
            }
            typeindex = BinToU16(&temp[2]);
            UbrofMatchAttrType(typeindex);
            UbrofTypeConv(typeindex);
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
               TYPE_BITFIELD_STRUCT bit;
              
               typeHdrInfo.sizeCalculated = FALSE;
               typeHdrInfo.t.complexType = TY_BITFIELD; 
               retCode = SymAddTypeHeader(ti , &typeHdrInfo);
               if(retCode != GOOD){
                  m_dwErrMsg = ER_LDR_SYM_SERVER;	
                  return 0;
               }
               bit.bitfieldSigned = 1;
               bit.size = temp[0];
               bit.offset = temp[1];
               bit.baseTypeIndex = typeindex;
               retCode = SymAddTypeBitfield(ti , &bit);
               if(retCode != GOOD ) {
                  m_dwErrMsg = ER_LDR_SYM_SERVER;	
                  return 0;
               }
            }
#endif
            break;
       case t_type_func : /* 0x14 */
       case t_type_func1 : /* 0x23 */
            U8 frameType, argCount;
            U32 attr;
                                  
            attr = 0xFFFFFFFF;                                
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
               typeHdrInfo.t.complexType = TY_FUNC_DEP;
               retCode = SymAddTypeHeader(ti , &typeHdrInfo);
               if(retCode != GOOD){
                  m_dwErrMsg = ER_LDR_SYM_SERVER;	
                  return 0;
                }
            }
#endif
            if(!GetBytes(temp , 3)){
               m_dwErrMsg = ER_LDR_READ_FILE;	
                return 0;
            }
            typeindex = BinToU16(temp);
            UbrofMatchAttrType(typeindex);
            UbrofTypeConv(typeindex);
            frameType = temp[2];
            if(subtag == t_type_func ) {
               if(!GetOneByte(temp)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;
               }
               argCount = temp[0];
            }
            else {
               if(!GetBytes(temp , 5)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;
                }
               argCount = temp[4];
               attr = BinToU32(temp);
            }
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
               retCode = SymAddTypeFunc(ti,attr,frameType,0L,typeindex,argCount,0,"");
               if(retCode != GOOD ){
                  m_dwErrMsg = ER_LDR_SYM_SERVER;
                  return 0;
               }
            }
#endif
            for (i=0 ; i < argCount ; i++) {
                 if(!GetBytes(temp , 2)){
                     m_dwErrMsg = ER_LDR_READ_FILE;	
                     return 0;
                 }
                 typeindex = BinToU16(temp);
                 UbrofMatchAttrType(typeindex);
                 UbrofTypeConv(typeindex);
                 if(LOAD_SYM(m_nLdrOptFlag)){
#ifndef _LONG_                    
                    retCode = SymAddTypeFuncParam(ti,typeindex);
                    if(retCode != GOOD){
                       m_dwErrMsg = ER_LDR_SYM_SERVER;	
                       return 0;
                    }
#endif                    
                 }
            }//end of for                       
            break;
       case t_type_attr  : /* 0x15 */
       case t_type_attr1 : /* 0x24 */
            if(subtag == t_type_attr){
               if(!GetBytes(temp , 3)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                  return 0;
               }
            }
            else{
               if(!GetBytes(temp, 6)){
                  m_dwErrMsg = ER_LDR_READ_FILE;
                  return 0;
               }
            }
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
               if(attrExtHdrPtr){
                  attrExtPtr->next = new attrCC;
                  if(attrExtPtr->next == 0 ) {
                     m_dwErrMsg = ER_LDR_MEMORY_ALLOC;		
                     return 0;
                  }
                  attrExtPtr = attrExtPtr->next;
               }
               else {
                  attrExtHdrPtr = attrExtPtr = new attrCC;
                  if(attrExtPtr == 0){
                     m_dwErrMsg = ER_LDR_MEMORY_ALLOC;		
                     return 0;
                  }
               }
               attrExtPtr->num = ti - 156;
               if(subtag == t_type_attr){
                  attrExtPtr->attr = (U16)temp[0];
                  typeindex = BinToU16(&temp[1]);
               }
               else{
                  attrExtPtr->attr = (U16)BinToU32(temp);
                  typeindex = BinToU16(&temp[4]);
               }   
               UbrofMatchAttrType(typeindex);
               attrExtPtr->type = typeindex;
            }
#endif
            break;
       case t_type_dptr0 : /* 0x17 */
       case t_type_dptr1 : /* 0x18 */
       case t_type_dptr2 : /* 0x19 */
       case t_type_dptr3 : /* 0x1A */
       case t_type_dptr4 : /* 0x1B */
       case t_type_dptr5 : /* 0x1C */
       case t_type_dptr6 : /* 0x1D */
       case t_type_dptr7 : /* 0x1E */
       case t_type_cptr0 : /* 0x1F */
       case t_type_cptr1 : /* 0x20 */
       case t_type_cptr2 : /* 0x21 */
       case t_type_cptr3 : /* 0x22 */
       case t_type_cptr4 : /* 0x25 */
       case t_type_cptr5 : /* 0x26 */
       case t_type_cptr6 : /* 0x27 */
       case t_type_cptr7 : /* 0x28 */
            U8 flag;
            
            flag = U8(subtag - t_type_dptr0) ;
            if(!GetBytes(temp , 2)){
                m_dwErrMsg = ER_LDR_READ_FILE;	
                return 0;
            }
            typeindex = BinToU16(temp);
            UbrofMatchAttrType(typeindex);
            UbrofTypeConv(typeindex);
#ifndef _LONG_
            if(LOAD_SYM(m_nLdrOptFlag)){
               typeHdrInfo.sizeCalculated = TRUE; 
               if(flag==0||flag==1||flag==8)
                  typeHdrInfo.sizeInMAUs = 0x02L;
               else                              
                  typeHdrInfo.sizeInMAUs = 0x03L;
               typeHdrInfo.t.complexType = (COMPLEX_TYPE) (TY_DPTR0 + flag);
               retCode = SymAddTypeHeader(ti , &typeHdrInfo);
               if(retCode != GOOD){
                  m_dwErrMsg = ER_LDR_SYM_SERVER;	
                  return 0;
               }
               retCode = SymAddTypePointerTypeIndex(ti , typeindex);
               if(retCode != GOOD){
                  m_dwErrMsg = ER_LDR_SYM_SERVER;	
                  return 0;
               }
            }
#endif            
            break;
       default :
#ifdef _DUMP_
			Message("\r\n???Unknown type record at file %lx",
			                GetFileCurPos()-1);
#endif
            m_dwErrMsg = ER_LDR_TYPE;		
            return 0;            
       }
    return 1;
  }//end of function
  
  BOOL CLdrICC196::GetSegInfo()
   {
     U8 data[4];
     U32 reclen;
     
     if(!GetBytes(data,4)){
        m_dwErrMsg = ER_LDR_READ_FILE;
        return 0;
     }
     reclen = BinToU32(data);
     if(!SkipRecord(reclen)) return 0;
     return 1;
  }
        
  BOOL CLdrICC196::GetGrpInfo()
   {
     U8 data[4];
     U32 reclen;
     
     if(!GetBytes(data,4)){
        m_dwErrMsg = ER_LDR_READ_FILE;
        return 0;
     }
     reclen = BinToU32(data);
     if(!SkipRecord(reclen)) return 0;
     return 1;
  }
  
  BOOL CLdrICC196::GetSymbol(U8 uTag,int symFlag)
   {
      
      U8 data[256], ti[2];

#ifdef _DUMP_      
      long pos = GetFileCurPos();
#endif      
      if(m_CurSymbol){
         if(m_CurSymbol->name) delete m_CurSymbol->name;
         delete m_CurSymbol;
         m_CurSymbol = NULL;                          
      }
      m_CurSymbol = new symbol();
      ASSERT(m_CurSymbol);
              
      if(!GetBytes(data , 7)){
         m_dwErrMsg = ER_LDR_READ_FILE;	
          return 0;                        
      }                            
      if(!GetName(m_CurSymbol->name)) return 0;
      m_CurSymbol->SC = data[0];
      m_CurSymbol->segnum = BinToU16(&data[1]);
      m_CurSymbol->addr = BinToU32(&data[3]);
              
      if(!GetBytes(ti, 2)){
          m_dwErrMsg = ER_LDR_READ_FILE;	
          return 0;                        
      }
      m_CurSymbol->typeindex = BinToU16(ti);
      if(uTag == t_symbol_def1||uTag == t_func_begin1||
              uTag == t_func_begin2||uTag == t_block_begin1||
              uTag == t_block_begin2) {
         if(!GetLenBytes(uTag)) return 0;
      }
      if(uTag==t_func_begin2||uTag==t_block_begin2){
         if(!GetBytes(data, 10)){
            m_dwErrMsg = ER_LDR_READ_FILE;
            return 0;
         }
      } 
      if(uTag == t_symbol_def1||uTag == t_symbol_def){
         if(!GetOneByte(&m_uCurByte)){
            m_dwErrMsg = ER_LDR_READ_FILE;	
             return 0;                        
         }
         if(!GetBytes(data , m_uCurByte)){
            m_dwErrMsg = ER_LDR_READ_FILE;	
            return 0;                        
         }
      }       
      //for bank switching 
      if(!m_bBankLow){
         if(strcmp((char*)m_CurSymbol->name, "?BANK_LOW")==0){
            m_uBankLow = m_CurSymbol->addr;
            m_bBankLow = 1;
            m_bSwitchOn=1;
         }
      }
      //for register variable
      if(strcmp((char*)m_CurSymbol->name, "?GR")==0){
         m_uGROff = U16(m_CurSymbol->addr);
      }
      if(strcmp((char*)m_CurSymbol->name, "?LR")==0){
         m_uLROff = U16(m_CurSymbol->addr);
      }
            
      if(!(m_bCallAddr&&m_bRetAddr)){
         GetBankCallRetAddr(m_CurSymbol->addr, (char*)m_CurSymbol->name);
      }
#ifndef _LONG_      
      if(symFlag){
         if(uTag==t_symbol_def||uTag==t_symbol_def1){    
            if(m_CurSymbol->SC==2||m_CurSymbol->SC==4||
            m_CurSymbol->SC==1||m_CurSymbol->SC==3){
               m_modNode.symno++;
               if(!UbrofProcessModSym()) return 0;
            }
         }
         else{
            if(m_CurSymbol->SC==7||m_CurSymbol->SC==4||
                 m_CurSymbol->SC==8){
               m_pCurBlock->localsymno++;
               if(!UbrofProcessBlockSym()) return 0;
             }
          }
       }
#endif                               
     return 1;  
  } //end of function  
   
  BOOL CLdrICC196::LdrGetModule(U8 tag)
   {
     U8 * name;
     U8  data[256],uTag;
     U16 temp;
     int i, symFlag , codeFlag;
     SYM_DESCRIPTOR moduleDesc;
#ifndef _LONG_ 
     RETCODE retCode;
     int err;
#endif        
     //for special reason
     uTag = tag;
     
     ASSERT(tag==0||tag==1);     
     //initiazing             
     ClearUpModuleBlock();
     m_pCurBlock = 0;
     
     symFlag = LOAD_SYM(m_nLdrOptFlag);
     codeFlag = LOAD_CODE(m_nLdrOptFlag);
     
     m_uStart = DEFAULT_START_ADDR;
     m_uEnd = DEFAULT_END_ADDR;
     ModuleNodeInit();
    
     m_modNode.offset = m_uBufInFilePos + m_uBufPos - 1 ;
     
     if(!GetBytes(data , 6)){
        m_dwErrMsg = ER_LDR_READ_FILE;	
        return 0;                        
     }                            
     m_uRevision = data[0];
     //m_bHiLoFlag = data[1] & 0x01;
     //for c source calling assembling source
     if(int(data[2]>>4)==0) m_bIsAssemble = 1;
     else m_bIsAssemble = 0;
       
     m_modNode.time.day = data[3];
     m_modNode.time.month = data[4];                
     m_modNode.time.year = 1900 + (U16)data[5];
     m_modNode.time.hour = -1;
     //for get name of module
     if(!GetName(m_modNode.name)) return 0;
     ASSERT( m_modNode.name );
     
     stat_addr.flag = 0;           
     //for rejecting module with '?'
     if(m_modNode.name){
        if(m_modNode.name[0] == '?' && !m_bSpecSymbol) symFlag = 0;
     }
    
     m_uCurAddr.type = SEG_CODE;
     m_uCurAddr.addr = 0;        
    
#ifndef _LONG_
     if(symFlag ) {   
        retCode = SymAddModuleCreate(
                  (LPSTR)m_modNode.name ,
                  &m_modNode.time ,
                  &m_modNode.codeaddr ,
                  m_modNode.offset ,
                  FALSE ,
                  0,
                  &moduleDesc );
        if(retCode != GOOD ) {
           m_dwErrMsg = ER_LDR_SYM_SERVER;	
           return 0;
        }
        m_uCurModDesc = moduleDesc;
    }
#endif
    if(!GetOneByte(&uTag)){
        m_dwErrMsg = ER_LDR_READ_FILE;	
        return 0;                        
    }                            
    
    while(1){
#ifndef  _LONG_
        if((err = TestKey(VK_ESCAPE)) == 1 ) {
            m_dwErrMsg = ER_LDR_ABORT;	
            return 0;
        } 
        if((m_where == LOAD_FROM_DIALOG)&&(m_nLdrOptFlag & LDR_STATUS)){
            if(SrcIsLoadAbort()){
               m_dwErrMsg = ER_LDR_ABORT;	
                return 0;
            }                  
            TestMessage();
        }
#endif
        switch(uTag) {
          case t_end : /* 0x3F */
          case t_end_abs : /* 0x3D */
               if(uTag == t_end_abs){
                  if(!GetBytes(data , 6)){
                    m_dwErrMsg = ER_LDR_READ_FILE;	
                    return 0;                        
                  }                            
                  temp = BinToU16(data);
                  m_lStartAddress = BinToU32(&data[2]);
#ifdef _DUMP_
				  Message("Starting Address: %lx",m_lStartAddress);
#endif
               }
               if(m_modNode.scope != 0){
                  m_dwErrMsg = ER_LDR_MODULE_FORMAT;	
                  return 0;
               }
               if (!GetBytes(data , 2)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }                            
#ifndef _LONG_               
               if(symFlag){
                  if(!CloseModToSym()) return 0;
               }
#endif              
               return 1;
          case t_debug : /* 0x52 */
               if(!GetOneByte(data)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                  return 0;                        
               }                            
               break;
          case t_aux : /* 0x53 */
               if(!GetBytes(data , 2) ) {
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               } 
               break;
          case t_aux_1 : /* 0x54 */
               if(!GetBytes(data , 2)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }                            
               if(!GetOneByte(&m_uCurByte)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }
               if(!GetBytes(data , m_uCurByte)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }            
               break;
          case t_file : /* 0x46 */
               U16 No_Lines;
               
               m_modNode.tfileoffset = m_uBufInFilePos + m_uBufPos - 1;
               if(!GetBytes(data , 2)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                  return 0;                        
               }                            
               No_Lines = BinToU16(data);
               if(!GetName(name)) return 0;
               for(i=0;((U16)i)<No_Lines;i++ ) {
                   if(!GetLenBytes()) return 0;
               }
#ifndef _LONG_               
               if(symFlag){    
                  retCode = SymAddModuleSourceFilePosition( moduleDesc ,
                                    m_modNode.tfileoffset );
                  if(retCode != GOOD ) {
                     if(name) delete name;
                     m_dwErrMsg = ER_LDR_SYM_SERVER;
                     return 0;
                   }
               }
#endif        
               if(name) delete name;
               break;
         case t_file_ref		: // 0xB9	
        	  if(!GetBytes(data, 3)){
                 m_dwErrMsg = ER_LDR_READ_FILE;	
                  return 0;                        
              }
              if(!GetLenBytes()) return 0;
              if(!GetBytes(data, 6)){
                 m_dwErrMsg = ER_LDR_READ_FILE;	
                  return 0;                        
              }
        	  break;
         case t_grp_ref         :
              if(!GetBytes(data,2)){
                 m_dwErrMsg = ER_LDR_READ_FILE;
                  return 0;
              }
              break;
         case t_symbol_def : /* 0x4C */
         case t_symbol_def1 : /* 0xA6 */
              if(!GetSymbol(uTag,symFlag)) return 0;
              break;
         case t_macro : /* 4E */
              if(!GetName(name)) return 0;
              if(!GetLenBytes()){
                  if(name) delete name;
                  return 0;
              }
              if(name) delete name;
              break;
         case t_new_file		:	// 0xBA
         case t_src_stat        :
         case t_abs_var         :
         case t_org             :
              if(!GetCodeOfMod(uTag,symFlag,moduleDesc)) return 0;
              break;
         default :
#ifdef _DUMP_
			  Message("\r\n???Unknown MOD record at file %lx",
					GetFileCurPos()-1);
#endif
              m_dwErrMsg = ER_LDR_UBROF_FORMAT;		
              return 0;
       }            
       if(!GetOneByte(&uTag)) {
           m_dwErrMsg = ER_LDR_READ_FILE;	
           return 0;                        
       }                            
    }//end of while
  }//end of function            
              
  BOOL CLdrICC196::GetCodeOfMod(U8 uTag, int symFlag,SYM_DESCRIPTOR moduleDesc)
   {            
     U8 *name, data[256];
     U16 num;
     int i,err;
     long pos;
     
     while(1)
      {
#ifndef  _LONG_
        if((err = TestKey(VK_ESCAPE)) == 1 ) {
            m_dwErrMsg = ER_LDR_ABORT;	
            return 0;
        } 
        if((m_where == LOAD_FROM_DIALOG)&&(m_nLdrOptFlag & LDR_STATUS)){
            if(SrcIsLoadAbort()){
               m_dwErrMsg = ER_LDR_ABORT;	
                return 0;
            }                  
            TestMessage();
        }
#endif
        switch(uTag) {
          case t_end:
          case t_end_abs:
               if(!UngetOneByte()) return 0;
               return 1;
          case t_new_file :
               if(!GetBytes(data,2)){
                   m_dwErrMsg = ER_LDR_READ_FILE;
                   return 0;
               }
               break;
          case t_src_stat : /* 0x47 */
               pos = GetFileCurPos();
               if(stat_addr.flag == 1 ) {
#ifndef _LONG_
                  if(!AddLineToSym(moduleDesc)) return 0;
#endif
                  m_modNode.linecnt++;
                  if(symFlag)
                     AdjustModBlkRange(uTag);
               }
               if(!GetBytes(data , 9)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }                            
               if(symFlag){
                  memcpy(m_uLineInfo,data , 8);
                  stat_addr.flag = 1;
                  stat_addr.start.addr = DEFAULT_START_ADDR;
                  stat_addr.end.addr = DEFAULT_END_ADDR;
               }
               break;
          case t_func_begin : /* 0x50 */
          case t_func_begin1 : /* 0xA7 */     
          case t_func_begin2:
               if(m_modNode.scope != 0) {
                  m_dwErrMsg = ER_LDR_SCOPE;
                  return 0;
               }
               m_modNode.scope++;
               if(!GetName(name)) return 0;
               if(!GetBytes(data , 10)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }  
#ifndef _LONG_
               if(symFlag){
                  if(!AddFunToSym(name,data)) return 0;
               }
#endif
               num = BinToU16(&data[8]);
               for(i = 0; ((unsigned int)i) < num; i++){
                   if(!GetSymbol(uTag, symFlag)){
                       return 0;                        
                   }
               }                            
               break;
          case t_block_begin : /* 0x48 */
          case t_block_begin1 : /* 0xA8 */
          case t_block_begin2 :
               if(m_modNode.scope < 1){ 
                  m_dwErrMsg = ER_LDR_SCOPE;	
                  return 0;
               }
               else if(symFlag){
                  if(!AddBlkOfFuncToSym()) return 0;
               }
               else m_modNode.scope++;
               if(!GetBytes(data , 2)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }                            
               num = BinToU16(data);
               for(i=0;((unsigned int)i)<num;i++) {
                   if(!GetSymbol(uTag,symFlag)) return 0;
               }
               break;
          case t_block_end : /* 0x49 */
               if(m_modNode.scope == 0){
                  m_dwErrMsg = ER_LDR_SCOPE;	
                  return(0);
               }
               if(stat_addr.flag == 1){  
                  if(!AddLineToSym(moduleDesc)) return 0;
                  m_modNode.linecnt++;
                  if(symFlag)
                     AdjustModBlkRange(uTag);
               }
#ifndef _LONG_               
               if(symFlag){
                  if(!CloseFuncToSym()) return 0;
               }
#endif               
               m_modNode.scope--;
               break;
          case t_abs_var : /* 0x39 */
               if(!GetOneByte(&m_uCurByte)){
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }                            
               if(!GetBytes(data , m_uCurByte)){
                   m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
               }
#ifdef _LINK_ABI
               if(LOAD_CODE(m_nLdrOptFlag)){
                  if(!FillCodeToMem(data)) return 0;
               }
#endif               
               //for adjusting address of different statements
               if(m_uCurAddr.type == SEG_CODE ||m_uCurAddr.type == 
                   SEG_CONST||m_uCurAddr.type == SEG_UNTYPED){
                  if(stat_addr.flag){
                     U32 address;
                     
                     address = m_uCurAddr.addr;
                     if(m_nLoadToBank){
                        ConvertAddrToBank(address);
                     }
                     
                     if(stat_addr.start.addr>address)
                        stat_addr.start.addr = address; 
                        address += m_uCurByte - 1;
                     if(stat_addr.end.addr<address)
                        stat_addr.end.addr = address;
                  }
               }
               else {
                      m_dwErrMsg = ER_CODE_NOT_IN_CODESEG;
                      return 0;
               }
               m_uCurAddr.addr += m_uCurByte;                  
               break;
          case t_org : /* 0x51 */
               if(!GetBytes(data , 5)){  
                  m_dwErrMsg = ER_LDR_READ_FILE;	
                   return 0;                        
                }                            
               UbrofSegIdToEnum( data[0] , &m_uCurAddr.type );
               m_uCurAddr.addr = BinToU32(&data[1]);
               break;
          default :
#ifdef _DUMP_
			   Message("\r\n???Unknown MOD record at file %lx",
			            GetFileCurPos()-1);
#endif
               m_dwErrMsg = ER_LDR_UBROF_FORMAT;		
               return 0;
        }//end of switch        
        if(!GetOneByte(&uTag)) {
            m_dwErrMsg = ER_LDR_READ_FILE;	
            return 0;                        
        }                            
#ifdef _DUMP_
       long pos = GetFileCurPos();
#endif
     }//end of while
//     return 1;
  } //end of function    
  
void CLdrICC196::GetBankCallRetAddr(U32 addr, char * Name)
{
 char call[12]="?X_CALL_L07";
 char ret[11]="?X_RET_L07";
 
 if(!m_bCallAddr && strcmp(Name,call)==0){
    m_uCallAddr = addr;
    m_bCallAddr = 1;
 }
 
 if(m_bCallAddr && strcmp(Name,ret)==0){
    m_uRetAddr = addr;
    m_bRetAddr = 1;
 } 
 if(m_bCallAddr && m_bRetAddr) m_bSwitchOn = 1;
 if(m_bSwitchOn&&m_nLoadToBank){
    m_dwErrMsg = ER_LDR_FILE_BANK;
    return ;
 }
}                 


////////////////////////////

