 
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/BWSMDL.CPP   1.2.1.5   17 Apr 1997 15:42:22   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/BWSMDL.CPP  $
** 
**    Rev 1.2.1.5   17 Apr 1997 15:42:22   ZJRD
** No change.
** 
**    Rev 1.2.1.4   16 Apr 1997 10:16:48   ZJRD
** No change.
** 
**    Rev 1.2.1.3   10 Apr 1997 15:28:22   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:09:56   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:14:54   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:26:12   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:44:48   ZJRD
** Initial revision.
** 
**    Rev 1.6.1.0.1.2   09 Dec 1996 10:14:18   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.6.1.0.1.0   11 Nov 1996 12:57:34   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.6.1.4   09 Sep 1996 13:13:48   ZJRD
** No change.
** 
**    Rev 1.6.1.3   05 Sep 1996 11:25:20   ZJRD
** No change.
** 
**    Rev 1.6.1.2   02 Sep 1996 09:52:28   ZJRD
** No change.
** 
**    Rev 1.6.1.1   28 Aug 1996 15:44:54   ZJRD
** No change.
** 
**    Rev 1.6.1.0   12 Aug 1996 10:50:06   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.4   05 Jun 1996 14:52:16   ZJRD
** No change.
** 
**    Rev 1.3   29 May 1996 09:28:24   ZJRD
** No change.
** 
**    Rev 1.2   16 May 1996 09:08:46   ZJRD
** No change.
** 
**    Rev 1.1   10 May 1996 09:08:32   ZJRD
** No change.
** 
**    Rev 1.0   02 May 1996 10:26:06   ZJRD
** Initial revision.
** 
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  SRCMDL.CPP
//
//  Description:The implement file for the class: 
//                  BwsBwsModuleInfo
//
//  Author:     Hu Wei
//
//  Date:       04/25/96
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"

#include "zqueue.h"
#include "uicom.h"                  
#include "srccom.h"                    
#include "zlist.h"                    
#include "srclist.h"                   
#include "srcmdl.h"
#include "bwsmdl.h"
#include "symblsvr.h"   //gates
#include "abibase.h"
#include "ldr.h"

/////////////////////////////////////////////////////////////////////////////
// BwsModuleInfo
/////////////////////////////////////////////////////////////////////////////    
BwsModuleInfo bwsMdlInfo;    

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BwsModuleInfo::BwsModuleInfo(void)
: m_nModuleIdx(-1), m_pModuleValue(0), m_pModule(0), m_uModules(0)
{
    for(int i = 0; i < MAX_MODULE; i ++)    m_nModuleLoaded[i] = -1;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void BwsModuleInfo::Clean(void)
{
    // Set current module to null
    m_nModuleIdx = -1;           
    
    // Clean Loaded Module Buffer
    for(int i = 0; i < MAX_MODULE; i ++) {
        m_Module[i].Clean();
        m_nModuleLoaded[i] = -1;
    }                            
    
    // Delete Module Value
    if(m_pModuleValue)  delete [] m_pModuleValue;
    m_pModuleValue = 0;
    
    // Delete Module Index Buffer
    if(m_pModule)   delete [] m_pModule;
    m_pModule = 0;               
    
    // Set Module Number to 0
    m_uModules = 0;
                             
    // Clean current asm & mixed buffer                             
    BwsCleanAsm();
    BwsCleanMix();
}                           

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BwsModuleInfo::~BwsModuleInfo()
{
    Clean();
}                               

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////

//extern int GetSrcPathCntFromIni();
//extern BOOL FindFromIni(CString strPath);

extern void AddToRecentPathList(const char* pszPathName);

BOOL BwsModuleInfo::Init(void)
{
    Clean();
    
    // Clean Browsed Module List
    bwsBrsMdl.Clean();
                                
    // Set step option
    SrcEmu.m_nStepOpt = STEP_INSTRUCTION;

    // Clear Breakpoints                                
    BptClrAllBptfromWnd();     
    
    extern void BPClrSym(void);
    BPClrSym();

    // Add Load File to Loaded File List                        
    if(SrcGetLoadPath(LoadInfo.m_strFile) == -1)    return FALSE;
    AfxGetApp()->AddToRecentFileList(LoadInfo.m_strFile);
                     
    // Set Source Module Path                     

    CString strPath;         
    int n = LoadInfo.m_strFile.GetLength();
    int i;
    if(n > 0) {
        for(i = n - 1; i >= 0; i --) {        
            if(LoadInfo.m_strFile[i] == '\\') {
                strPath = LoadInfo.m_strFile.Left(i+1);
                break;
            }
        }
        AddToRecentPathList(".\\");
        if(strPath.GetLength() > 0){
	       AddToRecentPathList(strPath);
        }
    }
                             
    // Get Load Information                             
    char szModule[100];       
    int nDummy;
    if(SrcGetLdrStats(szModule, &(LoadInfo.m_lSymbols),
        &((unsigned short &)(LoadInfo.m_lModules)), &(LoadInfo.m_lTypes), 
        &(LoadInfo.m_lFunctions), &(LoadInfo.m_lLines),
        &(LoadInfo.m_lBytes), &nDummy, &(LoadInfo.m_bSupportBank)) == -1)
        return FALSE;                                
                     
    // Get Init PC                     
    if(SrcGetStartAddress(LoadInfo.m_nBank, (unsigned long &)(LoadInfo.m_lPC)) != 0)  
        return FALSE;    
                           
    // Get total module number                                
    if(SrcGetModuleNum(m_uModules) == -1 || m_uModules == 0) {
        //AfxMessageBox(IDS_ERR_bwsMdlInfo);
        return FALSE;                                  
    }
                              
    // Allocate buffer to hold module index                              
    m_pModule = new unsigned long [m_uModules];  
    if(!m_pModule) {
        AfxMessageBox(IDS_ERR_MEM);
        return FALSE;
    }                    
    
    // Get module index into buffer
    if(SrcGetModuleIndex(m_uModules, m_pModule, m_uModules) == -1) {
    	/*if(LoadOpt.m_isWarnings)
	        AfxMessageBox(IDS_ERR_bwsMdlInfo);*/
        return FALSE;                                  
    }
                                   
    // Allocate buffer for module value                                   
	ASSERT(m_uModules);
    m_pModuleValue = new unsigned [m_uModules];
    if(!m_pModuleValue) {
        AfxMessageBox(IDS_ERR_MEM);
        return FALSE;
    }           
                                       
    // Init module value                                       
    for(i = 0; i < int(m_uModules); i ++)      
        m_pModuleValue[i] = 0;            
        
    if(SrcEmu.GetPC())  SrcEmu.GetModule();
    
    return TRUE;   
}
                        
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Clean oldest module
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL BwsModuleInfo::CleanOldModule(void)
{             
    unsigned uVal = 0xFFFFU;                  
    for(int i = 0, j = -1, nModule; i < MAX_MODULE; i++) {     
        nModule = m_nModuleLoaded[i];
        if(nModule == -1)   continue;
        if(m_pModuleValue[nModule] <= uVal) {
            uVal = m_pModuleValue[nModule];
            j = i;
        }
    }              
    if(j > -1) {
        m_Module[j].Clean(); 
        m_nModuleLoaded[j] = -1; 
        return TRUE;
    } else return FALSE;
}       


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Get Current Module Index
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
unsigned long BwsModuleInfo::CurModule(void) const
{                   
    ASSERT(m_nModuleIdx != -1);
    
    return m_pModule[m_nModuleLoaded[m_nModuleIdx]]; 
}        
                           
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Get Module Path from Module Index
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CString BwsModuleInfo::MakeModulePath(unsigned long dwModuleIdx) const
{
//	if(SrcOpenFile(dwModuleIdx))	return EMBEDPATH;

    char psz[41];                                           
    
    if(SrcGetModuleName(dwModuleIdx, psz) == -1)    return  "";
    return SrcGetModuleFullName(psz);
}                         
                       
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Load New Module                       
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int BwsModuleInfo::LoadModuleIdx(unsigned long dwModuleIdx)
{                 
    // Get Module Path                     
    CString str = MakeModulePath(dwModuleIdx); 
    if(str.GetLength() == 0) {
    	if(LoadOpt.m_isWarnings)
        	AfxMessageBox(IDS_ERR_LOADMDL);
        return SRC_LOAD_ERROR;
    }
    const char * pName = (const char *)str;
    
                       
    // Convert module number -> module idx                       
    int nModuleIdx = -1;
    for(int i = 0; i < int(m_uModules); i ++) {
        if(m_pModule[i] == dwModuleIdx) nModuleIdx = i;    
    }                                                  
    if(nModuleIdx == -1) {
    	if(LoadOpt.m_isWarnings)
	        AfxMessageBox(IDS_ERR_LOADMDL);
        return SRC_LOAD_ERROR;
    }
    
    // check module active
    for(i = 0; i < MAX_MODULE; i ++) {
        if(m_nModuleLoaded[i] == nModuleIdx) {
            if(i == m_nModuleIdx)    // Module is the current module
                return SRC_LOAD_ALREADY;
            else {  // Module has been loaded before
                m_nModuleIdx = i;               
                ++ m_pModuleValue[nModuleIdx];
                BwsCleanAsm();
                BwsCleanMix();
                return SRC_LOAD_OK;
            }          
        }
    }
                        
    // check whether have empty cells                                          
    for(;;) {
        for(i = 0; i < MAX_MODULE; i ++) {
            if(m_nModuleLoaded[i] == -1) {  // empty cell
                int nRval = m_Module[i].Load(pName);
                if(nRval == SourceModule::ERR_OK) {
                    m_nModuleIdx = i;               
                    ++ m_pModuleValue[nModuleIdx];  
                    m_nModuleLoaded[i] = nModuleIdx;
                    BwsCleanAsm();
                    BwsCleanMix();
                    return SRC_LOAD_OK;
                } else if(nRval != SourceModule::ERR_MEM) {
                    // Load error not by memory error
                    // m_nModuleIdx = -1;	reserve old module loaded
                    
                    return SRC_LOAD_ERROR;
                } else break;
            }
        }
        if(CleanOldModule()==FALSE)    break;
    }     
 
    m_nModuleIdx = -1;
    BwsCleanAsm();
    BwsCleanMix();
    AfxMessageBox(IDS_ERR_MEM);
    return SRC_LOAD_ERROR;
}
                                                     
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Load Module Containing Current PC
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int BwsModuleInfo::LoadPCModule(void)
{   
    // Get PC    
    if(!SrcEmu.GetPC())	return SRC_LOAD_ERROR;
    long lAddr = SrcEmu.m_lPCAddr;
    
    unsigned long dwModule;
    unsigned short uLine;
                                                              
    if(SrcAddr2Linenum(SrcEmu.m_nPCBank, lAddr, uLine, dwModule) == -1)  return SRC_LOAD_ERROR;
    bwsBrsMdl.AddTail(dwModule);
    
    if(IsModuleOn() && dwModule == CurModule()) return SRC_LOAD_ALREADY;
    else return LoadModuleIdx(dwModule);
}                  

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int BwsModuleInfo::Reload(void)
{           
    int nRval;
    
    for(int i = 0; i < MAX_MODULE; i ++) {
        if(m_nModuleLoaded[i] != -1) {
            nRval = m_Module[i].Reload();
            if(nRval != SourceModule::ERR_OK)
                return SRC_LOAD_ERROR;        
        }
    }                                 
    return SRC_LOAD_OK;
}


/////////////////////////////////////////////////////////////////////////////
// Download File
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Load Module by Current PC
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int BwsLoadPCModule(void)
{      
	AfxGetApp()->DoWaitCursor(1);            
    int i = bwsMdlInfo.LoadPCModule();
	AfxGetApp()->DoWaitCursor(-1);            
	return	i;
}      
                            
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Load Module by Module Index                            
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int BwsLoadModule(unsigned long dwModule, BOOL isHist)
{
	AfxGetApp()->DoWaitCursor(1);            
    int nRval = bwsMdlInfo.LoadModuleIdx(dwModule);
	AfxGetApp()->DoWaitCursor(-1);            
    if(isHist && nRval != SRC_LOAD_ERROR)
        bwsBrsMdl.AddTail(dwModule);                        
    return nRval;
}
                              
    
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Convert Module Name to Module Index        
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
int SrcModuleName2Index(const char * pszModule, unsigned long & dwModule)
{                                                 
    char psz[80];  
        
    for(int i = 0; i < int(bwsMdlInfo.m_uModules); i ++) {
        if(SrcGetModuleName(bwsMdlInfo.m_pModule[i], psz) == 0)
            if(stricmp(pszModule, psz) == 0) {
                dwModule = bwsMdlInfo.m_pModule[i];    
                return  0;
            }
    }         
    
    return -1;
}
*/
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Called after Load Command    
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
BOOL SrcInitModule(void)
{                           
    BOOL is = MdlInfo.Init(); 
    SrcEmu.m_nStepOpt = STEP_INSTRUCTION;
    SrcEmu.m_isStatement = BOOL(SrcIsStatement() == 0);
*/    
/*    SrcEmu.m_nStepOpt = STEP_INSTRUCTION;
    SrcEmu.m_isStatement = BOOL(SrcIsStatement() == 0);
    if(is)  SrcLoadPCModule();
    if(!isSourceOn && is) {
        SrcOpenWindow(TRUE, (CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
    } else {
        SrcResetView();
        if(isSourceOn && pSourceWnd->IsIconic())
            pSourceWnd->ShowWindow(SW_RESTORE); 
        else if(isSourceOn)
            pSourceWnd->BringWindowToTop();
    }*/
//    return is;
//}      

/*
void SrcPostLoad(void)
{
    SrcEmu.m_nStepOpt = STEP_INSTRUCTION;
    SrcEmu.m_isStatement = BOOL(SrcIsStatement() == 0);
    SrcLoadPCModule();
    if(!isSourceOn) {
        SrcOpenWindow(TRUE, (CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
    } else {
        SrcResetView();
        if(isSourceOn && pSourceWnd->IsIconic())
            pSourceWnd->ShowWindow(SW_RESTORE); 
        else if(isSourceOn)
            pSourceWnd->BringWindowToTop();
    }
}             
*/
///////////////////////////////// (EOF) /////////////////////////////////////

                   
