mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-12-26 05:31:30 +00:00
2.6.1.19 Symbol Table Cleanup
This commit is contained in:
parent
294b646b68
commit
7cc5229161
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@ using namespace std;
|
||||
#include "Debugger_Assembler.h"
|
||||
#include "Debugger_Help.h"
|
||||
#include "Debugger_Display.h"
|
||||
#include "Debugger_Symbols.h"
|
||||
#include "Util_MemoryTextFile.h"
|
||||
|
||||
// Globals __________________________________________________________________
|
||||
@ -155,7 +156,7 @@ using namespace std;
|
||||
// Symbol Table / Memory
|
||||
bool FindAddressFromSymbol( LPCSTR pSymbol, WORD * pAddress_ = NULL, int * iTable_ = NULL );
|
||||
WORD GetAddressFromSymbol (LPCTSTR symbol); // HACK: returns 0 if symbol not found
|
||||
void SymbolUpdate( Symbols_e eSymbolTable, char *pSymbolName, WORD nAddrss, bool bRemoveSymbol, bool bUpdateSymbol );
|
||||
void SymbolUpdate( SymbolTable_Index_e eSymbolTable, char *pSymbolName, WORD nAddrss, bool bRemoveSymbol, bool bUpdateSymbol );
|
||||
|
||||
LPCTSTR FindSymbolFromAddress (WORD nAdress, int * iTable_ = NULL );
|
||||
LPCTSTR GetSymbol (WORD nAddress, int nBytes);
|
||||
|
@ -1251,9 +1251,13 @@ Update_t CmdHelpSpecific (int nArgs)
|
||||
wsprintf( sText, "%s %s LIFE = 2000", CHC_EXAMPLE, pCommand->m_sName ); ConsolePrint( sText );
|
||||
wsprintf( sText, "%s %s LIFE" , CHC_EXAMPLE, pCommand->m_sName ); ConsolePrint( sText );
|
||||
break;
|
||||
case CMD_SYMBOLS_MAIN:
|
||||
case CMD_SYMBOLS_USER:
|
||||
case CMD_SYMBOLS_SRC :
|
||||
case CMD_SYMBOLS_ROM:
|
||||
case CMD_SYMBOLS_APPLESOFT:
|
||||
case CMD_SYMBOLS_ASSEMBLY:
|
||||
case CMD_SYMBOLS_USER_1:
|
||||
case CMD_SYMBOLS_USER_2:
|
||||
case CMD_SYMBOLS_SRC_1:
|
||||
case CMD_SYMBOLS_SRC_2:
|
||||
// ConsoleBufferPush( TEXT(" Usage: [ ON | OFF | symbol | address ]" ) );
|
||||
// ConsoleBufferPush( TEXT(" Usage: [ LOAD [\"filename\"] | SAVE \"filename\"]" ) );
|
||||
// ConsoleBufferPush( TEXT(" ON : Turns symbols on in the disasm window" ) );
|
||||
@ -1264,11 +1268,12 @@ Update_t CmdHelpSpecific (int nArgs)
|
||||
Colorize( sText, " Usage: [ <cmd> | symbol | address ]" );
|
||||
ConsolePrint( sText );
|
||||
ConsoleBufferPush( " Where <cmd> is one of:" );
|
||||
sprintf( sText, " %s " ": Turns symbols on in the disasm window" , g_aParameters[ PARAM_ON ].m_sName ); ConsoleBufferPush( sText );
|
||||
sprintf( sText, " %s " ": Turns symbols off in the disasm window" , g_aParameters[ PARAM_OFF ].m_sName ); ConsoleBufferPush( sText );
|
||||
sprintf( sText, " %s" ": Loads symbols from last/default \"filename\"", g_aParameters[ PARAM_SAVE ].m_sName ); ConsoleBufferPush( sText );
|
||||
sprintf( sText, " %s" ": Saves symbol table to \"filename\"" , g_aParameters[ PARAM_LOAD ].m_sName ); ConsoleBufferPush( sText );
|
||||
sprintf( sText, " %s" ": Clears the symbol table" , g_aParameters[ PARAM_CLEAR ].m_sName ); ConsoleBufferPush( sText );
|
||||
sprintf( sText, "%s%-5s%s: Turns symbols on in the disasm window" , CHC_STRING, g_aParameters[ PARAM_ON ].m_sName, CHC_DEFAULT ); ConsolePrint( sText );
|
||||
sprintf( sText, "%s%-5s%s: Turns symbols off in the disasm window" , CHC_STRING, g_aParameters[ PARAM_OFF ].m_sName, CHC_DEFAULT ); ConsolePrint( sText );
|
||||
sprintf( sText, "%s%-5s%s: Loads symbols from last/default \"filename\"", CHC_STRING, g_aParameters[ PARAM_SAVE ].m_sName, CHC_DEFAULT ); ConsolePrint( sText );
|
||||
sprintf( sText, "%s%-5s%s: Saves symbol table to \"filename\"" , CHC_STRING, g_aParameters[ PARAM_LOAD ].m_sName, CHC_DEFAULT ); ConsolePrint( sText );
|
||||
sprintf( sText, "%s%-5s%s: Clears the symbol table" , CHC_STRING, g_aParameters[ PARAM_CLEAR ].m_sName, CHC_DEFAULT ); ConsolePrint( sText );
|
||||
sprintf( sText, "%s%-5s%s: Remove symbol" , CHC_STRING, g_aTokens[ TOKEN_EXCLAMATION ] , CHC_DEFAULT ); ConsolePrint( sText );
|
||||
break;
|
||||
case CMD_SYMBOLS_LIST :
|
||||
Colorize( sText, " Usage: symbol" );
|
||||
|
862
AppleWin/source/Debugger_Symbols.cpp
Normal file
862
AppleWin/source/Debugger_Symbols.cpp
Normal file
@ -0,0 +1,862 @@
|
||||
#include "StdAfx.h"
|
||||
#pragma hdrstop
|
||||
|
||||
// Symbols ________________________________________________________________________________________
|
||||
|
||||
char* g_sFileNameSymbols[ NUM_SYMBOL_TABLES ] = {
|
||||
"APPLE2E.SYM",
|
||||
"A2_BASIC.SYM",
|
||||
"A2_ASM.SYM",
|
||||
"A2_USER1.SYM",
|
||||
"A2_USER2.SYM",
|
||||
"A2_SRC1.SYM",
|
||||
"A2_SRC2.SYM"
|
||||
};
|
||||
char g_sFileNameSymbolsUser [ MAX_PATH ] = "";
|
||||
|
||||
char * g_aSymbolTableNames[ NUM_SYMBOL_TABLES ] =
|
||||
{
|
||||
"Main",
|
||||
"Basic",
|
||||
"Assembly",
|
||||
"User1",
|
||||
"User2",
|
||||
"Src1",
|
||||
"Src2"
|
||||
};
|
||||
|
||||
bool g_bSymbolsDisplayMissingFile = true;
|
||||
|
||||
SymbolTable_t g_aSymbols[ NUM_SYMBOL_TABLES ];
|
||||
int g_nSymbolsLoaded = 0; // on Last Load
|
||||
bool g_aConfigSymbolsDisplayed[ NUM_SYMBOL_TABLES ] =
|
||||
{
|
||||
true,
|
||||
true,
|
||||
true
|
||||
};
|
||||
|
||||
|
||||
// Utils _ ________________________________________________________________________________________
|
||||
|
||||
//===========================================================================
|
||||
LPCTSTR GetSymbol (WORD nAddress, int nBytes)
|
||||
{
|
||||
LPCSTR pSymbol = FindSymbolFromAddress( nAddress );
|
||||
if (pSymbol)
|
||||
return pSymbol;
|
||||
|
||||
return FormatAddress( nAddress, nBytes );
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int GetSymbolTableFromCommand()
|
||||
{
|
||||
return (g_iCommand - CMD_SYMBOLS_ROM);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
LPCTSTR FindSymbolFromAddress (WORD nAddress, int * iTable_ )
|
||||
{
|
||||
// Bugfix/User feature: User symbols should be searched first
|
||||
int iTable = NUM_SYMBOL_TABLES;
|
||||
while (iTable-- > 0)
|
||||
{
|
||||
if (g_aSymbols[iTable].size())
|
||||
{
|
||||
map<WORD, string>::iterator iSymbols = g_aSymbols[iTable].find(nAddress);
|
||||
if(g_aSymbols[iTable].find(nAddress) != g_aSymbols[iTable].end())
|
||||
{
|
||||
if (iTable_)
|
||||
{
|
||||
*iTable_ = iTable;
|
||||
}
|
||||
return iSymbols->second.c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool FindAddressFromSymbol ( LPCTSTR pSymbol, WORD * pAddress_, int * iTable_ )
|
||||
{
|
||||
// Bugfix/User feature: User symbols should be searched first
|
||||
for (int iTable = NUM_SYMBOL_TABLES; iTable-- > 0; )
|
||||
{
|
||||
if (! g_aSymbols[iTable].size())
|
||||
continue;
|
||||
|
||||
// map<WORD, string>::iterator iSymbol = g_aSymbols[iTable].begin();
|
||||
SymbolTable_t :: iterator iSymbol = g_aSymbols[iTable].begin();
|
||||
while (iSymbol != g_aSymbols[iTable].end())
|
||||
{
|
||||
if (!_tcsicmp( iSymbol->second.c_str(), pSymbol))
|
||||
{
|
||||
if (pAddress_)
|
||||
{
|
||||
*pAddress_ = iSymbol->first;
|
||||
}
|
||||
if (iTable_)
|
||||
{
|
||||
*iTable_ = iTable;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
iSymbol++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Symbols ________________________________________________________________________________________
|
||||
|
||||
//===========================================================================
|
||||
WORD GetAddressFromSymbol (LPCTSTR pSymbol)
|
||||
{
|
||||
WORD nAddress;
|
||||
bool bFoundSymbol = FindAddressFromSymbol( pSymbol, & nAddress );
|
||||
if (! bFoundSymbol)
|
||||
{
|
||||
nAddress = 0;
|
||||
}
|
||||
return nAddress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========================================================================
|
||||
bool String2Address( LPCTSTR pText, WORD & nAddress_ )
|
||||
{
|
||||
TCHAR sHexApple[ CONSOLE_WIDTH ];
|
||||
|
||||
if (pText[0] == '$')
|
||||
{
|
||||
if (!TextIsHexString( pText+1))
|
||||
return false;
|
||||
|
||||
_tcscpy( sHexApple, "0x" );
|
||||
_tcsncpy( sHexApple+2, pText+1, MAX_SYMBOLS_LEN - 3 );
|
||||
pText = sHexApple;
|
||||
}
|
||||
|
||||
if (pText[0] == TEXT('0'))
|
||||
{
|
||||
if ((pText[1] == TEXT('X')) || pText[1] == TEXT('x'))
|
||||
{
|
||||
if (!TextIsHexString( pText+2))
|
||||
return false;
|
||||
|
||||
TCHAR *pEnd;
|
||||
nAddress_ = (WORD) _tcstol( pText, &pEnd, 16 );
|
||||
return true;
|
||||
}
|
||||
if (TextIsHexString( pText ))
|
||||
{
|
||||
TCHAR *pEnd;
|
||||
nAddress_ = (WORD) _tcstol( pText, &pEnd, 16 );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdSymbols (int nArgs)
|
||||
{
|
||||
if (! nArgs)
|
||||
return CmdSymbolsInfo( 0 );
|
||||
|
||||
Update_t iUpdate = _CmdSymbolsUpdate( nArgs, SYMBOL_TABLE_USER_1 );
|
||||
if (iUpdate != UPDATE_NOTHING)
|
||||
return iUpdate;
|
||||
|
||||
int bSymbolTables = (1 << NUM_SYMBOL_TABLES) - 1;
|
||||
return _CmdSymbolsListTables( nArgs, bSymbolTables );
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdSymbolsClear (int nArgs)
|
||||
{
|
||||
SymbolTable_Index_e eSymbolTable = SYMBOLS_USER_1;
|
||||
_CmdSymbolsClear( eSymbolTable );
|
||||
return (UPDATE_DISASM | UPDATE_SYMBOLS);
|
||||
}
|
||||
|
||||
void _CmdSymbolsInfoHeader( int iTable, char * pText )
|
||||
{
|
||||
int nSymbols = g_aSymbols[ iTable ].size();
|
||||
sprintf( pText, " %s: %s%d%s"
|
||||
, g_aSymbolTableNames[ iTable ]
|
||||
, CHC_NUM_DEC
|
||||
, nSymbols
|
||||
, CHC_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdSymbolsInfo (int nArgs)
|
||||
{
|
||||
char sText[ CONSOLE_WIDTH * 2 ] = "";
|
||||
char sTemp[ CONSOLE_WIDTH ] = "";
|
||||
|
||||
int bDisplaySymbolTables = 0;
|
||||
|
||||
if (! nArgs)
|
||||
{
|
||||
// default to all tables
|
||||
bDisplaySymbolTables = (1 << NUM_SYMBOL_TABLES) - 1;
|
||||
}
|
||||
else
|
||||
{ // Convert Command Index to parameter
|
||||
int iWhichTable = GetSymbolTableFromCommand();
|
||||
if ((iWhichTable < 0) || (iWhichTable >= NUM_SYMBOL_TABLES))
|
||||
{
|
||||
sprintf( sText, "Only %s%d%s symbol tables supported!"
|
||||
, CHC_NUM_DEC
|
||||
, NUM_SYMBOL_TABLES
|
||||
, CHC_DEFAULT );
|
||||
return ConsoleDisplayError( sText );
|
||||
}
|
||||
|
||||
bDisplaySymbolTables = (1 << iWhichTable);
|
||||
}
|
||||
|
||||
//sprintf( sText, " Symbols Main: %s%d%s User: %s%d%s Source: %s%d%s"
|
||||
|
||||
int bTable = 1;
|
||||
int iTable = 0;
|
||||
for( ; bTable <= bDisplaySymbolTables; iTable++, bTable <<= 1 ) {
|
||||
if( bDisplaySymbolTables & bTable ) {
|
||||
_CmdSymbolsInfoHeader( iTable, sTemp );
|
||||
strcat( sText, sTemp );
|
||||
}
|
||||
}
|
||||
ConsolePrint( sText );
|
||||
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
void _CmdPrintSymbol( LPCTSTR pSymbol, WORD nAddress, int iTable )
|
||||
{
|
||||
char sText[ CONSOLE_WIDTH ];
|
||||
sprintf( sText, " %s$%s%04X%s (%s%s%s) %s%s"
|
||||
, CHC_ARG_SEP
|
||||
, CHC_ADDRESS
|
||||
, nAddress
|
||||
, CHC_DEFAULT
|
||||
, CHC_STRING
|
||||
, g_aSymbolTableNames[ iTable ]
|
||||
, CHC_DEFAULT
|
||||
, CHC_SYMBOL
|
||||
, pSymbol );
|
||||
// ConsoleBufferPush( sText );
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
|
||||
|
||||
// Test if bit-mask to index (equal to number of bit-shifs required to reach table)
|
||||
//=========================================================================== */
|
||||
bool _FindSymbolTable( int bSymbolTables, int iTable )
|
||||
{
|
||||
// iTable is enumeration
|
||||
// bSymbolTables is bit-flags of enabled tables to search
|
||||
|
||||
if( bSymbolTables & (1 << iTable) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert bit-mask to index
|
||||
//=========================================================================== */
|
||||
int _GetSymbolTableFromFlag( int bSymbolTables )
|
||||
{
|
||||
int iTable = 0;
|
||||
int bTable = 1;
|
||||
|
||||
for( ; bTable <= bSymbolTables; iTable++, bTable <<= 1 )
|
||||
{
|
||||
if( bTable & bSymbolTables )
|
||||
break;
|
||||
}
|
||||
|
||||
return iTable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@param bSymbolTables Bit Flags of which symbol tables to search
|
||||
//=========================================================================== */
|
||||
bool _CmdSymbolList_Address2Symbol( int nAddress, int bSymbolTables )
|
||||
{
|
||||
int iTable;
|
||||
LPCTSTR pSymbol = FindSymbolFromAddress( nAddress, &iTable );
|
||||
|
||||
if (pSymbol)
|
||||
{
|
||||
if (_FindSymbolTable( bSymbolTables, iTable ))
|
||||
{
|
||||
_CmdPrintSymbol( pSymbol, nAddress, iTable );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
bool _CmdSymbolList_Symbol2Address( LPCTSTR pSymbol, int bSymbolTables )
|
||||
{
|
||||
int iTable;
|
||||
WORD nAddress;
|
||||
|
||||
|
||||
bool bFoundSymbol = FindAddressFromSymbol( pSymbol, &nAddress, &iTable );
|
||||
if (bFoundSymbol)
|
||||
{
|
||||
if (_FindSymbolTable( bSymbolTables, iTable ))
|
||||
{
|
||||
_CmdPrintSymbol( pSymbol, nAddress, iTable );
|
||||
}
|
||||
}
|
||||
return bFoundSymbol;
|
||||
}
|
||||
|
||||
// LIST is normally an implicit "LIST *", but due to the numbers of symbols
|
||||
// only look up symbols the user specifies
|
||||
//===========================================================================
|
||||
Update_t CmdSymbolsList (int nArgs )
|
||||
{
|
||||
int bSymbolTables = (1 << NUM_SYMBOL_TABLES) - 1; // default to all
|
||||
return _CmdSymbolsListTables( nArgs, bSymbolTables );
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
Update_t _CmdSymbolsListTables (int nArgs, int bSymbolTables )
|
||||
{
|
||||
if (! nArgs)
|
||||
{
|
||||
return Help_Arg_1( CMD_SYMBOLS_LIST );
|
||||
}
|
||||
|
||||
/*
|
||||
Test Cases
|
||||
|
||||
SYM 0 RESET FA6F $FA59
|
||||
$0000 LOC0
|
||||
$FA6F RESET
|
||||
$FA6F INITAN
|
||||
$FA59 OLDBRK
|
||||
SYM B
|
||||
|
||||
SYMBOL B = $2000
|
||||
SYM B
|
||||
*/
|
||||
|
||||
TCHAR sText[ CONSOLE_WIDTH ] = "";
|
||||
|
||||
for( int iArgs = 1; iArgs <= nArgs; iArgs++ )
|
||||
{
|
||||
WORD nAddress = g_aArgs[iArgs].nValue;
|
||||
LPCTSTR pSymbol = g_aArgs[iArgs].sArg;
|
||||
|
||||
// Dump all symbols for this table
|
||||
if( g_aArgRaw[iArgs].eToken == TOKEN_STAR)
|
||||
{
|
||||
// int iWhichTable = (g_iCommand - CMD_SYMBOLS_MAIN);
|
||||
// bDisplaySymbolTables = (1 << iWhichTable);
|
||||
|
||||
int iTable = 0;
|
||||
int bTable = 1;
|
||||
for( ; bTable <= bSymbolTables; iTable++, bTable <<= 1 )
|
||||
{
|
||||
if( bTable & bSymbolTables )
|
||||
{
|
||||
int nSymbols = g_aSymbols[iTable].size();
|
||||
if (nSymbols)
|
||||
{
|
||||
// map<WORD, string>::iterator iSymbol = g_aSymbols[iTable].begin();
|
||||
SymbolTable_t :: iterator iSymbol = g_aSymbols[iTable].begin();
|
||||
while (iSymbol != g_aSymbols[iTable].end())
|
||||
{
|
||||
const char *pSymbol = iSymbol->second.c_str();
|
||||
unsigned short nAddress = iSymbol->first;
|
||||
_CmdPrintSymbol( pSymbol, nAddress, iTable );
|
||||
++iSymbol;
|
||||
}
|
||||
}
|
||||
_CmdSymbolsInfoHeader( iTable, sText );
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (nAddress)
|
||||
{ // Have address, do symbol lookup first
|
||||
if (! _CmdSymbolList_Symbol2Address( pSymbol, bSymbolTables ))
|
||||
{
|
||||
// nope, ok, try as address
|
||||
if (! _CmdSymbolList_Address2Symbol( nAddress, bSymbolTables))
|
||||
{
|
||||
wsprintf( sText
|
||||
, TEXT(" Address not found: %s$%s%04X%s" )
|
||||
, CHC_ARG_SEP
|
||||
, CHC_ADDRESS, nAddress, CHC_DEFAULT );
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Have symbol, do address lookup
|
||||
if (! _CmdSymbolList_Symbol2Address( pSymbol, bSymbolTables ))
|
||||
{ // nope, ok, try as address
|
||||
if (String2Address( pSymbol, nAddress ))
|
||||
{
|
||||
if (! _CmdSymbolList_Address2Symbol( nAddress, bSymbolTables ))
|
||||
{
|
||||
wsprintf( sText
|
||||
, TEXT(" Symbol not found: %s%s%s")
|
||||
, CHC_SYMBOL, pSymbol, CHC_DEFAULT
|
||||
);
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf( sText
|
||||
, TEXT(" Symbol not found: %s%s%s")
|
||||
, CHC_SYMBOL, pSymbol, CHC_DEFAULT
|
||||
);
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
|
||||
|
||||
void Print_Current_Path()
|
||||
{
|
||||
ConsoleDisplayError( g_sProgramDir );
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
int ParseSymbolTable( TCHAR *pFileName, SymbolTable_Index_e eSymbolTableWrite, int nSymbolOffset )
|
||||
{
|
||||
int nSymbolsLoaded = 0;
|
||||
|
||||
if (! pFileName)
|
||||
return nSymbolsLoaded;
|
||||
|
||||
//#if _UNICODE
|
||||
// TCHAR sFormat1[ MAX_SYMBOLS_LEN ];
|
||||
// TCHAR sFormat2[ MAX_SYMBOLS_LEN ];
|
||||
// wsprintf( sFormat1, "%%x %%%ds", MAX_SYMBOLS_LEN ); // i.e. "%x %13s"
|
||||
// wsprintf( sFormat2, "%%%ds %%x", MAX_SYMBOLS_LEN ); // i.e. "%13s %x"
|
||||
// ascii
|
||||
char sFormat1[ MAX_SYMBOLS_LEN ];
|
||||
char sFormat2[ MAX_SYMBOLS_LEN ];
|
||||
sprintf( sFormat1, "%%x %%%ds", MAX_SYMBOLS_LEN ); // i.e. "%x %13s"
|
||||
sprintf( sFormat2, "%%%ds %%x", MAX_SYMBOLS_LEN ); // i.e. "%13s %x"
|
||||
|
||||
FILE *hFile = fopen(pFileName,"rt");
|
||||
|
||||
if( !hFile && g_bSymbolsDisplayMissingFile )
|
||||
{
|
||||
ConsoleDisplayError( "Symbol File not found:" );
|
||||
Print_Current_Path();
|
||||
nSymbolsLoaded = -1; // HACK: ERROR: FILE NOT EXIST
|
||||
}
|
||||
|
||||
bool bDupSymbolHeader = false;
|
||||
if( hFile )
|
||||
{
|
||||
while( !feof(hFile) )
|
||||
{
|
||||
// Support 2 types of symbols files:
|
||||
// 1) AppleWin:
|
||||
// . 0000 SYMBOL
|
||||
// . FFFF SYMBOL
|
||||
// 2) ACME:
|
||||
// . SYMBOL =$0000; Comment
|
||||
// . SYMBOL =$FFFF; Comment
|
||||
//
|
||||
DWORD nAddress = _6502_MEM_END + 1; // default to invalid address
|
||||
char sName[ MAX_SYMBOLS_LEN+1 ] = "";
|
||||
|
||||
const int MAX_LINE = 256;
|
||||
char szLine[ MAX_LINE ] = "";
|
||||
|
||||
if( !fgets(szLine, MAX_LINE-1, hFile) ) // Get next line
|
||||
{
|
||||
//ConsolePrint("<<EOF");
|
||||
break;
|
||||
}
|
||||
|
||||
if(strstr(szLine, "$") == NULL)
|
||||
{
|
||||
sscanf(szLine, sFormat1, &nAddress, sName);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* p = strstr(szLine, "="); // Optional
|
||||
if(p) *p = ' ';
|
||||
p = strstr(szLine, "$");
|
||||
if(p) *p = ' ';
|
||||
p = strstr(szLine, ";"); // Optional
|
||||
if(p) *p = 0;
|
||||
p = strstr(szLine, " "); // 1st space between name & value
|
||||
int nLen = p - szLine;
|
||||
if (nLen > MAX_SYMBOLS_LEN)
|
||||
{
|
||||
memset(&szLine[MAX_SYMBOLS_LEN], ' ', nLen-MAX_SYMBOLS_LEN); // sscanf fails for nAddress if string too long
|
||||
}
|
||||
sscanf(szLine, sFormat2, sName, &nAddress);
|
||||
}
|
||||
|
||||
// SymbolOffset
|
||||
nAddress += nSymbolOffset;
|
||||
|
||||
if( (nAddress > _6502_MEM_END) || (sName[0] == 0) )
|
||||
continue;
|
||||
|
||||
#if 1 // _DEBUG
|
||||
// If updating symbol, print duplicate symbols
|
||||
WORD nAddressPrev;
|
||||
int iTable;
|
||||
bool bExists = FindAddressFromSymbol( sName, &nAddressPrev, &iTable );
|
||||
if( bExists )
|
||||
{
|
||||
char sText[ CONSOLE_WIDTH * 3 ];
|
||||
if( !bDupSymbolHeader )
|
||||
{
|
||||
bDupSymbolHeader = true;
|
||||
sprintf( sText, " %sDup Symbol Name%s (%s%s%s) %s"
|
||||
, CHC_ERROR
|
||||
, CHC_DEFAULT
|
||||
, CHC_STRING
|
||||
, g_aSymbolTableNames[ iTable ]
|
||||
, CHC_DEFAULT
|
||||
, pFileName
|
||||
);
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
|
||||
sprintf( sText, " %s$%s%04X %s%-31s%s"
|
||||
, CHC_ARG_SEP
|
||||
, CHC_ADDRESS
|
||||
, nAddress
|
||||
, CHC_SYMBOL
|
||||
, sName
|
||||
, CHC_DEFAULT
|
||||
);
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
#endif
|
||||
g_aSymbols[ eSymbolTableWrite ] [ (WORD) nAddress ] = sName;
|
||||
nSymbolsLoaded++;
|
||||
}
|
||||
fclose(hFile);
|
||||
}
|
||||
|
||||
return nSymbolsLoaded;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdSymbolsLoad (int nArgs)
|
||||
{
|
||||
TCHAR sFileName[MAX_PATH];
|
||||
_tcscpy(sFileName,g_sProgramDir);
|
||||
|
||||
int iSymbolTable = GetSymbolTableFromCommand();
|
||||
if ((iSymbolTable < 0) || (iSymbolTable >= NUM_SYMBOL_TABLES))
|
||||
{
|
||||
wsprintf( sFileName, "Only %d symbol tables supported!", NUM_SYMBOL_TABLES );
|
||||
return ConsoleDisplayError( sFileName );
|
||||
}
|
||||
|
||||
int nSymbols = 0;
|
||||
|
||||
if (! nArgs)
|
||||
{
|
||||
// Default to main table
|
||||
// if (g_iCommand == CMD_SYMBOLS_MAIN)
|
||||
// _tcscat(sFileName, g_sFileNameSymbolsMain );
|
||||
// else
|
||||
// {
|
||||
// if (! _tcslen( g_sFileNameSymbolsUser ))
|
||||
// {
|
||||
// return ConsoleDisplayError(TEXT("No user symbol file to reload."));
|
||||
// }
|
||||
// // load user symbols
|
||||
// _tcscat( sFileName, g_sFileNameSymbolsUser );
|
||||
// }
|
||||
_tcscat(sFileName, g_sFileNameSymbols[ iSymbolTable ]);
|
||||
nSymbols = ParseSymbolTable( sFileName, (SymbolTable_Index_e) iSymbolTable );
|
||||
}
|
||||
|
||||
int iArg = 1;
|
||||
if (iArg <= nArgs)
|
||||
{
|
||||
TCHAR *pFileName = NULL;
|
||||
|
||||
if( g_aArgs[ iArg ].bType & TYPE_QUOTED_2 )
|
||||
{
|
||||
pFileName = g_aArgs[ iArg ].sArg;
|
||||
|
||||
_tcscpy(sFileName,g_sProgramDir);
|
||||
_tcscat(sFileName, pFileName);
|
||||
|
||||
// Remember File Name of last symbols loaded
|
||||
_tcscpy( g_sFileNameSymbolsUser, pFileName );
|
||||
}
|
||||
|
||||
// SymbolOffset
|
||||
// sym load "filename" [,symbol_offset]
|
||||
int nOffsetAddr = 0;
|
||||
|
||||
iArg++;
|
||||
if( iArg <= nArgs)
|
||||
{
|
||||
if (g_aArgs[ iArg ].eToken == TOKEN_COMMA)
|
||||
{
|
||||
iArg++;
|
||||
if( iArg <= nArgs )
|
||||
{
|
||||
nOffsetAddr = g_aArgs[ iArg ].nValue;
|
||||
if( (nOffsetAddr < _6502_MEM_BEGIN) || (nOffsetAddr > _6502_MEM_END) )
|
||||
{
|
||||
nOffsetAddr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pFileName )
|
||||
{
|
||||
nSymbols = ParseSymbolTable( sFileName, (SymbolTable_Index_e) iSymbolTable, nOffsetAddr );
|
||||
}
|
||||
}
|
||||
|
||||
if( nSymbols > 0 )
|
||||
{
|
||||
g_nSymbolsLoaded = nSymbols;
|
||||
}
|
||||
|
||||
Update_t bUpdateDisplay = UPDATE_DISASM;
|
||||
bUpdateDisplay |= (nSymbols > 0) ? UPDATE_SYMBOLS : 0;
|
||||
|
||||
return bUpdateDisplay;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
Update_t _CmdSymbolsClear( SymbolTable_Index_e eSymbolTable )
|
||||
{
|
||||
g_aSymbols[ eSymbolTable ].clear();
|
||||
|
||||
return UPDATE_SYMBOLS;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void SymbolUpdate( SymbolTable_Index_e eSymbolTable, char *pSymbolName, WORD nAddress, bool bRemoveSymbol, bool bUpdateSymbol )
|
||||
{
|
||||
if (bRemoveSymbol)
|
||||
pSymbolName = g_aArgs[2].sArg;
|
||||
|
||||
if (_tcslen( pSymbolName ) < MAX_SYMBOLS_LEN)
|
||||
{
|
||||
WORD nAddressPrev;
|
||||
int iTable;
|
||||
bool bExists = FindAddressFromSymbol( pSymbolName, &nAddressPrev, &iTable );
|
||||
|
||||
if (bExists)
|
||||
{
|
||||
if (iTable == eSymbolTable)
|
||||
{
|
||||
if (bRemoveSymbol)
|
||||
{
|
||||
ConsoleBufferPush( TEXT(" Removing symbol." ) );
|
||||
}
|
||||
|
||||
g_aSymbols[ eSymbolTable ].erase( nAddressPrev );
|
||||
|
||||
if (bUpdateSymbol)
|
||||
{
|
||||
char sText[ CONSOLE_WIDTH * 2 ];
|
||||
sprintf( sText, " Updating %s%s%s from %s$%s%04X%s to %s$%s%04X%s"
|
||||
, CHC_SYMBOL, pSymbolName, CHC_DEFAULT
|
||||
, CHC_ARG_SEP
|
||||
, CHC_ADDRESS, nAddressPrev, CHC_DEFAULT
|
||||
, CHC_ARG_SEP
|
||||
, CHC_ADDRESS, nAddress, CHC_DEFAULT
|
||||
);
|
||||
ConsolePrint( sText );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bRemoveSymbol)
|
||||
{
|
||||
ConsoleBufferPush( TEXT(" Symbol not in table." ) );
|
||||
}
|
||||
}
|
||||
|
||||
if (bUpdateSymbol)
|
||||
{
|
||||
#if _DEBUG
|
||||
LPCTSTR pSymbol = FindSymbolFromAddress( nAddress, &iTable );
|
||||
{
|
||||
// Found another symbol for this address. Harmless.
|
||||
// TODO: Probably should check if same name?
|
||||
}
|
||||
#endif
|
||||
g_aSymbols[ eSymbolTable ][ nAddress ] = pSymbolName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
Update_t _CmdSymbolsUpdate( int nArgs, int bSymbolTables )
|
||||
{
|
||||
bool bRemoveSymbol = false;
|
||||
bool bUpdateSymbol = false;
|
||||
|
||||
if ((nArgs == 2) &&
|
||||
((g_aArgs[ 1 ].eToken == TOKEN_EXCLAMATION) || (g_aArgs[1].eToken == TOKEN_TILDE)) )
|
||||
bRemoveSymbol = true;
|
||||
|
||||
if ((nArgs == 3) && (g_aArgs[ 2 ].eToken == TOKEN_EQUAL ))
|
||||
bUpdateSymbol = true;
|
||||
|
||||
if (bRemoveSymbol || bUpdateSymbol)
|
||||
{
|
||||
TCHAR *pSymbolName = g_aArgs[1].sArg;
|
||||
WORD nAddress = g_aArgs[3].nValue;
|
||||
|
||||
int iTable = _GetSymbolTableFromFlag( bSymbolTables );
|
||||
SymbolUpdate( (SymbolTable_Index_e) iTable, pSymbolName, nAddress, bRemoveSymbol, bUpdateSymbol );
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
|
||||
return UPDATE_NOTHING;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
Update_t _CmdSymbolsCommon ( int nArgs, int bSymbolTables )
|
||||
{
|
||||
if (! nArgs)
|
||||
{
|
||||
return Help_Arg_1( g_iCommand );
|
||||
}
|
||||
|
||||
Update_t iUpdate = _CmdSymbolsUpdate( nArgs, bSymbolTables );
|
||||
if (iUpdate != UPDATE_NOTHING)
|
||||
return iUpdate;
|
||||
|
||||
TCHAR sText[ CONSOLE_WIDTH ];
|
||||
|
||||
int iArg = 0;
|
||||
while (iArg++ <= nArgs)
|
||||
{
|
||||
int iParam;
|
||||
int nParams = FindParam( g_aArgs[iArg].sArg, MATCH_EXACT, iParam ); // MATCH_FUZZY
|
||||
if (nParams)
|
||||
{
|
||||
if (iParam == PARAM_CLEAR)
|
||||
{
|
||||
int iTable = _GetSymbolTableFromFlag( bSymbolTables );
|
||||
if (iTable != NUM_SYMBOL_TABLES)
|
||||
{
|
||||
Update_t iUpdate = _CmdSymbolsClear( (SymbolTable_Index_e) iTable );
|
||||
wsprintf( sText, TEXT(" Cleared symbol table: %s"),
|
||||
g_aSymbolTableNames[ iTable ]
|
||||
);
|
||||
ConsoleBufferPush( sText );
|
||||
iUpdate |= ConsoleUpdate();
|
||||
return iUpdate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleBufferPush( TEXT(" Error: Unknown Symbol Table Type") );
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
// if (bSymbolTable & SYMBOL_TABLE_MAIN)
|
||||
// return _CmdSymbolsClear( SYMBOLS_MAIN );
|
||||
// else
|
||||
// if (bSymbolsTable & SYMBOL_TABLE_USER)
|
||||
// return _CmdSymbolsClear( SYMBOLS_USER );
|
||||
// else
|
||||
// Shouldn't have multiple symbol tables selected
|
||||
// nArgs = _Arg_1( eSymbolsTable );
|
||||
}
|
||||
else
|
||||
if (iParam == PARAM_LOAD)
|
||||
{
|
||||
nArgs = _Arg_Shift( iArg, nArgs);
|
||||
Update_t bUpdate = CmdSymbolsLoad( nArgs );
|
||||
|
||||
int iTable = _GetSymbolTableFromFlag( bSymbolTables );
|
||||
if (iTable != NUM_SYMBOL_TABLES)
|
||||
{
|
||||
if( bUpdate & UPDATE_SYMBOLS )
|
||||
{
|
||||
wsprintf( sText, " Symbol Table: %s, loaded symbols: %d",
|
||||
g_aSymbolTableNames[ iTable ], g_nSymbolsLoaded );
|
||||
ConsoleBufferPush( sText );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleBufferPush( TEXT(" Error: Unknown Symbol Table Type") );
|
||||
}
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
else
|
||||
if (iParam == PARAM_SAVE)
|
||||
{
|
||||
nArgs = _Arg_Shift( iArg, nArgs);
|
||||
return CmdSymbolsSave( nArgs );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return _CmdSymbolsListTables( nArgs, bSymbolTables ); // bSymbolTables
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ConsoleUpdate();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdSymbolsCommand (int nArgs)
|
||||
{
|
||||
if (! nArgs)
|
||||
{
|
||||
return CmdSymbolsInfo( 1 );
|
||||
}
|
||||
|
||||
int bSymbolTable = SYMBOL_TABLE_MAIN << GetSymbolTableFromCommand();
|
||||
return _CmdSymbolsCommon( nArgs, SYMBOL_TABLE_MAIN );
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
Update_t CmdSymbolsSave (int nArgs)
|
||||
{
|
||||
return UPDATE_CONSOLE_DISPLAY;
|
||||
}
|
17
AppleWin/source/Debugger_Symbols.h
Normal file
17
AppleWin/source/Debugger_Symbols.h
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
// Variables
|
||||
extern SymbolTable_t g_aSymbols[ NUM_SYMBOL_TABLES ];
|
||||
|
||||
// Prototypes
|
||||
|
||||
Update_t _CmdSymbolsClear ( SymbolTable_Index_e eSymbolTable );
|
||||
Update_t _CmdSymbolsCommon ( int nArgs, SymbolTable_Index_e eSymbolTable );
|
||||
Update_t _CmdSymbolsListTables (int nArgs, int bSymbolTables );
|
||||
Update_t _CmdSymbolsUpdate ( int nArgs, int bSymbolTables );
|
||||
|
||||
bool _CmdSymbolList_Address2Symbol ( int nAddress , int bSymbolTables );
|
||||
bool _CmdSymbolList_Symbol2Address ( LPCTSTR pSymbol, int bSymbolTables );
|
||||
|
||||
// SymbolOffset
|
||||
int ParseSymbolTable ( TCHAR *pFileName, SymbolTable_Index_e eWhichTableToLoad, int nSymbolOffset = 0 );
|
||||
|
@ -531,10 +531,9 @@
|
||||
// Memory
|
||||
, CMD_MEMORY_COMPARE
|
||||
|
||||
, _CMD_MEM_MINI_DUMP_HEX_1_1 // alias MD
|
||||
, _CMD_MEM_MINI_DUMP_HEX_1_2 // alias MD = D
|
||||
, CMD_MEM_MINI_DUMP_HEX_1
|
||||
, CMD_MEM_MINI_DUMP_HEX_2
|
||||
, _CMD_MEM_MINI_DUMP_HEX_1_1 // Memory Dump
|
||||
, CMD_MEM_MINI_DUMP_HEX_1 // Mini Memory Dump 1
|
||||
, CMD_MEM_MINI_DUMP_HEX_2 // Mini Memory Dump 2
|
||||
, _CMD_MEM_MINI_DUMP_HEX_1_3 // alias M1
|
||||
, _CMD_MEM_MINI_DUMP_HEX_2_1 // alias M2
|
||||
|
||||
@ -572,9 +571,13 @@
|
||||
// Symbols
|
||||
, CMD_SYMBOLS_LOOKUP
|
||||
// , CMD_SYMBOLS
|
||||
, CMD_SYMBOLS_MAIN
|
||||
, CMD_SYMBOLS_USER
|
||||
, CMD_SYMBOLS_SRC
|
||||
, CMD_SYMBOLS_ROM
|
||||
, CMD_SYMBOLS_APPLESOFT
|
||||
, CMD_SYMBOLS_ASSEMBLY
|
||||
, CMD_SYMBOLS_USER_1
|
||||
, CMD_SYMBOLS_USER_2
|
||||
, CMD_SYMBOLS_SRC_1
|
||||
, CMD_SYMBOLS_SRC_2
|
||||
// , CMD_SYMBOLS_FIND
|
||||
// , CMD_SYMBOLS_CLEAR
|
||||
, CMD_SYMBOLS_INFO
|
||||
@ -789,11 +792,16 @@
|
||||
Update_t CmdSymbolsList (int nArgs);
|
||||
Update_t CmdSymbolsLoad (int nArgs);
|
||||
Update_t CmdSymbolsInfo (int nArgs);
|
||||
Update_t CmdSymbolsMain (int nArgs);
|
||||
Update_t CmdSymbolsUser (int nArgs);
|
||||
Update_t CmdSymbolsSave (int nArgs);
|
||||
Update_t CmdSymbolsSource (int nArgs);
|
||||
// View
|
||||
|
||||
Update_t CmdSymbolsCommand (int nArgs);
|
||||
// Update_t CmdSymbolsMain (int nArgs);
|
||||
// Update_t CmdSymbolsBasic (int nArgs);
|
||||
// Update_t CmdSymbolsUser (int nArgs);
|
||||
// Update_t CmdSymbolsAssembly (int nArgs);
|
||||
// Update_t CmdSymbolsSource (int nArgs);
|
||||
|
||||
// View
|
||||
Update_t CmdViewOutput_Text4X (int nArgs);
|
||||
Update_t CmdViewOutput_Text41 (int nArgs);
|
||||
Update_t CmdViewOutput_Text42 (int nArgs);
|
||||
@ -1467,26 +1475,34 @@
|
||||
};
|
||||
|
||||
// ****************************************
|
||||
// WARNING: This is the simple enumeration.
|
||||
// WARNING: This is the index (enumeration) to select which table
|
||||
// See: g_aSymbols[]
|
||||
// ****************************************
|
||||
enum Symbols_e
|
||||
enum SymbolTable_Index_e // Symbols_e -> SymbolTable_Index_e
|
||||
{
|
||||
SYMBOLS_MAIN,
|
||||
SYMBOLS_USER,
|
||||
SYMBOLS_SRC ,
|
||||
NUM_SYMBOL_TABLES = 3
|
||||
SYMBOLS_APPLESOFT,
|
||||
SYMBOLS_ASSEMBLY,
|
||||
SYMBOLS_USER_1,
|
||||
SYMBOLS_USER_2,
|
||||
SYMBOLS_SRC_1,
|
||||
SYMBOLS_SRC_2,
|
||||
NUM_SYMBOL_TABLES
|
||||
};
|
||||
|
||||
// ****************************************
|
||||
// WARNING: This is the bit-flags to select which table.
|
||||
// See: CmdSymbolsListTable()
|
||||
// ****************************************
|
||||
enum SymbolTable_e
|
||||
enum SymbolTable_Masks_e // SymbolTable_e ->
|
||||
{
|
||||
SYMBOL_TABLE_MAIN = (1 << 0),
|
||||
SYMBOL_TABLE_USER = (1 << 1),
|
||||
SYMBOL_TABLE_SRC = (1 << 2),
|
||||
SYMBOL_TABLE_MAIN = (1 << 0),
|
||||
SYMBOL_TABLE_APPLESOFT = (1 << 1),
|
||||
SYMBOL_TABLE_ASSEMBLY = (1 << 2),
|
||||
SYMBOL_TABLE_USER_1 = (1 << 3),
|
||||
SYMBOL_TABLE_USER_2 = (1 << 4),
|
||||
SYMBOL_TABLE_SRC_1 = (1 << 5),
|
||||
SYMBOL_TABLE_SRC_2 = (1 << 6),
|
||||
};
|
||||
|
||||
typedef map<WORD, string> SymbolTable_t;
|
||||
|
Loading…
Reference in New Issue
Block a user