// ldrsvr.h : header file
#ifndef _LDRSRV_H_
#define _LDRSRV_H_

#include "symblsvr.h"

typedef enum {
   LDR_UNKNOWN,    /* Unrecognizable loadfile */
   LDR_OMF96,      /* OMF96 */
   LDR_ICC196,
   LDR_HEX196,
   LDR_UPLOAD      /* Upload defined extended intel hex format */
}  LDR_COMPILER_TYPE;

typedef enum {
    LOAD_FROM_SHELL,    /* Load from shell command */
    LOAD_FROM_DIALOG    /* Load from dialog */
}   LOAD_WHERE;

#define ARGLEN    256        /* command-line argument length */
#define LDR_BUFSIZE 4096
#define LDR_DEFAULT     0xF /* symbol,code,process,warning and nomangle */
#define LDR_SYMBOL      0x2
#define LDR_CODE        0x1
#define LDR_STATUS      0x4
#define LDR_WARNING     0x8
#define LDR_TODATA      0x10
#define LDR_SYSTEM      0x20

#define LOAD_SYM(flags)     ((flags) & LDR_SYMBOL)
#define LOAD_CODE(flags)    ((flags) & LDR_CODE)
#define LOAD_STATUS(flags)  ((flags) & LDR_STATUS)
#define LOAD_WARNING(flags) ((flags) & LDR_WARNING)
#define LOAD_TODATA(flags)  ((flags) & LDR_TODATA)
#define LOAD_SYSTEM(flags)  ((flags) & LDR_SYSTEM)

struct BlockBlock {   
    LPSTR funcName;         // function name , if len = 0 , it is block
    U32   stacksize;
  //for omf96  
    U16   Frame_Ptr;
    U16   Ret_Offset;  
    U8    Prologue_Size;
    BOOL  bFramePtr;
               
    U16   localsymno;         // local symbol number
    int   scope;              // block scope

    ADDR_RANGE_TYPE       codeaddr; // function or block code range                
    SOURCE_RANGE_TYPE     srcRange; // source range
    TYPE_INDEX            typeIndex;   // function return type
    struct BlockBlock far *next; // next node , <same scope>
    struct BlockBlock far *son;  // son node , <nest block node>
    struct BlockBlock far *father; // father node 

public :
    BlockBlock() {
        funcName = 0;
        localsymno = 0;
        scope = 0;
        stacksize = 0;  
        next = 0;
        son = 0;
        father = 0;
        typeIndex = 0;
        bFramePtr = 0;
    };
};
/***********************************************************************
*    The Loader use the struct to save enough information for a module *
*  , So loader can call symbol server routine SymAddModuleCreate() at  *
*    one module end .                                                  *
***********************************************************************/                        
struct ModuleBlock {
    U8    * name;        // module name 
    U32   offset;     // module starter at load file position <offset>
    U32   symno;      // module symbol number
    U32   blkcnt;     // module block and function number
    U32   linecnt;    // module linenum record number
    int   scope;      // block scope 
    U32 tfileoffset; // TFILE record at load file position , Only UBROF used

    TIMESTAMP_TYPE        time; // module time
    ADDR_RANGE_TYPE       codeaddr; // module code range
    struct BlockBlock far *lpblock; // This module function and block tree
    
public :
    ModuleBlock() {
        name = 0;
        offset = 0;
        symno = 0;
        blkcnt = 0;
        linecnt = 0;              
        scope = 0;
        lpblock = 0;
    };
};                                           

/////////////////////////////////////////////////////////////////////////////
// CLdrSvr base class

class CLdrSvr  
{   
	//DECLARE_DYNCREATE(CLdrSvr)
protected:
	CLdrSvr();			
// Attributes 
public:
    BOOL        m_bSpecSymbol;
    U32         m_dwLoadBytes;      // total bytes of loader     
    U32         m_dwErrMsg;             // error message
    //for bank
    BOOL        m_bSwitchOn;
    BOOL        m_bCallAddr;
    BOOL        m_bRetAddr; 
    BOOL        m_bBankLow;
    U32         m_uCallAddr;
    U32         m_uRetAddr;
    U32         m_uBankLow;

#ifdef _DUMP_
    long        m_dwRecStartPos; 
#endif
// Attributes
//for filling code
    U8          m_ptrData[128];
//for filling to different bank
    int         m_nLoadToBank;
    BOOL        m_bAppSym;
public:
    HFILE       m_hLdrFile;              //handle of loaded file
    CString     m_strFileName;         // load file name
    CString     m_strFilePath;         // load file path
    CString     m_strFile;         // load full file name
    long        m_lFileLen;            // file length
    BOOL        m_bSymLoaded;               // is symbol loaded  
    BOOL        m_IsLoaded;               // flag of loader
    int         m_nLdrOptFlag;            // flag of load option
    U32         m_lStartAddress ;         // PC value  
    BOOL        m_bHiLoFlag;             // Hi Byte before or after 
public:    
    LOAD_WHERE          m_where;           //load dialog or shell window
    LDR_COMPILER_TYPE   m_nCompilerType;//Type of compiler
    TIMESTAMP_TYPE      m_time;      // load OBJ file time
public:  
    U8          *m_lpBuffer;               // tempory buffer
    U32         m_uBufInFilePos;
    U16         m_uBufSize;
    U16         m_uBufPos;
    U32         m_typeDelta;
    U32         m_typeNum;          
    U32         m_symbolNo;             // total symbol number
    U32         m_typeNo;               // total type number
    U32         m_moduleNo;             // total module number 
    U32         m_uStart; 
    U32         m_uEnd;         
    U8          m_uCurByte;               // Current byte 
    U32         m_uCurTypeDelta;
    ModuleBlock              m_modNode;      // current module information node
    struct BlockBlock far    *m_pCurBlock ;
    SYM_DESCRIPTOR           m_uCurModDesc;
 
   //for UBROF
    U16   m_uGROff;
    U16   m_uLROff;

public:
    U16         BinToU16(U8 *s);
    U32         BinToU32(U8 *s);
    BOOL        UngetOneByte();
    BOOL        GetOneByte(U8 *ch);
    BOOL        GetBytes(U8 *ch , U32 num);  
    BOOL        GetName(U8 *& str);
	BOOL        PeekByte(U8 *ch);
    BOOL        SeekLoadFile(long off , int nOrg);
    BOOL        SkipRecord(U32 len);

public:
    BOOL        CloseModToSym();
    BOOL        ClearUpModuleBlock();
    BOOL        ClearUpBlockBlock(struct BlockBlock far *node);
    BOOL        ModuleNodeInit();
    void        LoadInit(); 
    BOOL        LoadCmd(int argc , char * argv[]);
    BOOL        LdrProcessArgs(int argc , char * argv[]); 
    BOOL        LoadFile();
    virtual BOOL LoadProcess() =0;   
public: 
    long        GetFileCurPos();	
    BOOL        GetFileInfo();	
    BOOL        IsOMF96(void);  
    void        ConvertAddrToBank(U32& addr);
public:
    void        Error(char* str);
    void        Error(U32 ulErrCode, U32 ulRecCode);
    void        Message(char *format,...);
    void        DisplayErrorRecord(U32 errorStartPos); 
    void        OutError(U32 ulErrCode, U32 ulRecCode);
    int         TestKey(WORD key);
    void        TestMessage();
// Implementation
public:
    virtual ~CLdrSvr();

};

#endif

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