debugger source cleanup -> moved 'source/debugger'

This commit is contained in:
mpohoreski 2010-06-11 15:38:22 +00:00
parent c946cb00bb
commit b9a2c7cd5f
19 changed files with 20950 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,192 @@
#pragma once
#include <vector>
#include <algorithm> // sort, find
#include <map>
using namespace std;
#include "Debugger_Types.h"
#include "Debugger_DisassemblerData.h"
#include "Debugger_Range.h"
#include "Debugger_Parser.h"
#include "Debugger_Console.h"
#include "Debugger_Assembler.h"
#include "Debugger_Help.h"
#include "Debugger_Display.h"
#include "Debugger_Symbols.h"
#include "Util_MemoryTextFile.h"
// Globals __________________________________________________________________
// All (Global)
extern bool g_bDebuggerEatKey;
// Benchmarking
extern DWORD extbench;
// Bookmarks
extern int g_nBookmarks;
extern Bookmark_t g_aBookmarks[ MAX_BOOKMARKS ];
// extern vector<int> g_aBookmarks;
// Breakpoints
extern int g_nBreakpoints;
extern Breakpoint_t g_aBreakpoints[ MAX_BREAKPOINTS ];
extern const char *g_aBreakpointSource [ NUM_BREAKPOINT_SOURCES ];
extern const TCHAR *g_aBreakpointSymbols[ NUM_BREAKPOINT_OPERATORS ];
// Full-Speed debugging
extern int g_nDebugOnBreakInvalid;
extern int g_iDebugOnOpcode ;
extern bool g_bDebugDelayBreakCheck;
// Commands
extern const int NUM_COMMANDS_WITH_ALIASES; // = sizeof(g_aCommands) / sizeof (Command_t); // Determined at compile-time ;-)
extern int g_iCommand; // last command
extern Command_t g_aCommands[];
extern Command_t g_aParameters[];
class commands_functor_compare
{
public:
bool operator() ( const Command_t & rLHS, const Command_t & rRHS ) const
{
// return true if lhs<rhs
return (_tcscmp( rLHS.m_sName, rRHS.m_sName ) <= 0) ? true : false;
}
};
// Config - FileName
extern char g_sFileNameConfig[];
// Cursor
extern WORD g_nDisasmTopAddress ;
extern WORD g_nDisasmBotAddress ;
extern WORD g_nDisasmCurAddress ;
extern bool g_bDisasmCurBad ;
extern int g_nDisasmCurLine ; // Aligned to Top or Center
extern int g_iDisasmCurState ;
extern int g_nDisasmWinHeight;
extern const int WINDOW_DATA_BYTES_PER_LINE;
// Config - Disassembly
extern bool g_bConfigDisasmAddressView ;
extern bool g_bConfigDisasmAddressColon ;
extern bool g_bConfigDisasmOpcodesView ;
extern bool g_bConfigDisasmOpcodeSpaces ;
extern int g_iConfigDisasmTargets ;
extern int g_iConfigDisasmBranchType ;
extern int g_bConfigDisasmImmediateChar;
// Config - Info
extern bool g_bConfigInfoTargetPointer ;
// Disassembly
extern int g_aDisasmTargets[ MAX_DISPLAY_LINES ];
// Display
extern bool g_bDebuggerViewingAppleOutput;
// Font
extern int g_nFontHeight;
extern int g_iFontSpacing;
// Memory
extern MemoryDump_t g_aMemDump[ NUM_MEM_DUMPS ];
// extern MemorySearchArray_t g_vMemSearchMatches;
extern vector<int> g_vMemorySearchResults;
// Source Level Debugging
extern TCHAR g_aSourceFileName[ MAX_PATH ];
extern MemoryTextFile_t g_AssemblerSourceBuffer;
extern int g_iSourceDisplayStart ;
extern int g_nSourceAssembleBytes ;
extern int g_nSourceAssemblySymbols;
// Version
extern const int DEBUGGER_VERSION;
// Watches
extern int g_nWatches;
extern Watches_t g_aWatches[ MAX_WATCHES ];
// Window
extern int g_iWindowLast;
extern int g_iWindowThis;
extern WindowSplit_t g_aWindowConfig[ NUM_WINDOWS ];
// Zero Page
extern int g_nZeroPagePointers;
extern ZeroPagePointers_t g_aZeroPagePointers[ MAX_ZEROPAGE_POINTERS ]; // TODO: use vector<> ?
// Prototypes _______________________________________________________________
// Bookmarks
bool Bookmark_Find( const WORD nAddress );
// Breakpoints
bool GetBreakpointInfo ( WORD nOffset, bool & bBreakpointActive_, bool & bBreakpointEnable_ );
// 0 = Brk, 1 = Invalid1, .. 3 = Invalid 3
inline bool IsDebugBreakOnInvalid( int iOpcodeType )
{
bool bActive = (g_nDebugOnBreakInvalid >> iOpcodeType) & 1;
return bActive;
}
inline void SetDebugBreakOnInvalid( int iOpcodeType, int nValue )
{
if (iOpcodeType <= AM_3)
{
g_nDebugOnBreakInvalid &= ~ ( 1 << iOpcodeType);
g_nDebugOnBreakInvalid |= ((nValue & 1) << iOpcodeType);
}
}
// Color
inline COLORREF DebuggerGetColor( int iColor );
// Source Level Debugging
int FindSourceLine( WORD nAddress );
LPCTSTR FormatAddress( WORD nAddress, int nBytes );
// 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( 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);
Update_t DebuggerProcessCommand( const bool bEchoConsoleInput );
// Prototypes _______________________________________________________________
enum
{
DEBUG_EXIT_KEY = 0x1B, // Escape
DEBUG_TOGGLE_KEY = VK_F1 + BTN_DEBUG
};
void DebugBegin ();
void DebugContinueStepping ();
void DebugDestroy ();
void DebugDisplay (BOOL);
void DebugEnd ();
void DebugInitialize ();
// void DebugProcessChar (TCHAR);
void DebuggerInputConsoleChar( TCHAR ch );
// void DebugProcessCommand (int);
void DebuggerProcessKey( int keycode );
void DebuggerUpdate();
void DebuggerCursorNext();
void DebuggerMouseClick( int x, int y );

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
#ifndef DEBUGGER_ASSEMBLER_H
#define DEBUGGER_ASSEMBLER_H
// Directives
// Assemblers
// A = Acme
// B = Big Mac S= S-C Macro Assembler
// K = DOS Tool Kit T = TED II
// L = Lisa W = Weller's Assembler
// M = Merlin
// u = MicroSparc
// O = ORCA/M
enum AsmAcmeDirective_e
{
ASM_A_DEFINE_BYTE
,NUM_ASM_A_DIRECTIVES
};
enum AsmBigMacDirective_e
{
ASM_B_DEFINE_BYTE
,NUM_ASM_B_DIRECTIVES
};
enum AsmDosToolKitDirective_e
{
ASM_K_DEFINE_BYTE
,NUM_ASM_K_DIRECTIVES
};
enum AsmLisaDirective_e
{
ASM_L_DEFINE_BYTE
,NUM_ASM_L_DIRECTIVES
};
enum AsmMerlinDirective_e
{
ASM_M_ASCII
, ASM_M_DEFINE_WORD
, ASM_M_DEFINE_BYTE
, ASM_M_DEFINE_STORAGE
, ASM_M_HEX
, ASM_M_ORIGIN
, NUM_ASM_M_DIRECTIVES
, ASM_M_DEFINE_BYTE_ALIAS
, ASM_M_DEFINE_WORD_ALIAS
};
enum AsmMicroSparcDirective_e
{
ASM_u_DEFINE_BYTE
,NUM_ASM_u_DIRECTIVES
};
enum AsmOrcamDirective_e
{
ASM_O_DEFINE_BYTE
,NUM_ASM_O_DIRECTIVES
};
enum AsmSCMacroDirective_e
{
ASM_S_ORIGIN
,ASM_S_TARGET_ADDRESS
,ASM_S_END_PROGRAM
,ASM_S_EQUATE
,ASM_S_DATA
,ASM_S_ASCII_STRING
,ASM_S_HEX_STRING
,NUM_ASM_S_DIRECTIVES
};
enum AsmTedDirective_e
{
ASM_T_DEFINE_BYTE
,NUM_ASM_T_DIRECTIVES
};
enum AsmWellersDirective_e
{
ASM_W_DEFINE_BYTE
,NUM_ASM_W_DIRECTIVES
};
// NOTE: Must keep in sync: AsmDirectives_e g_aAssemblerDirectives
enum AsmDirectives_e
{
FIRST_A_DIRECTIVE = 1,
FIRST_B_DIRECTIVE = FIRST_A_DIRECTIVE + NUM_ASM_A_DIRECTIVES, // Acme
FIRST_K_DIRECTIVE = FIRST_B_DIRECTIVE + NUM_ASM_B_DIRECTIVES, // Big Mac
FIRST_L_DIRECTIVE = FIRST_K_DIRECTIVE + NUM_ASM_K_DIRECTIVES, // DOS Tool Kit
FIRST_M_DIRECTIVE = FIRST_L_DIRECTIVE + NUM_ASM_L_DIRECTIVES, // Lisa
FIRST_u_DIRECTIVE = FIRST_M_DIRECTIVE + NUM_ASM_M_DIRECTIVES, // Merlin
FIRST_O_DIRECTIVE = FIRST_u_DIRECTIVE + NUM_ASM_u_DIRECTIVES, // MicroSparc
FIRST_S_DIRECTIVE = FIRST_O_DIRECTIVE + NUM_ASM_O_DIRECTIVES, // Orca
FIRST_T_DIRECTIVE = FIRST_S_DIRECTIVE + NUM_ASM_S_DIRECTIVES, // SC
FIRST_W_DIRECTIVE = FIRST_T_DIRECTIVE + NUM_ASM_T_DIRECTIVES, // Ted
NUM_ASM_DIRECTIVES= FIRST_W_DIRECTIVE + NUM_ASM_W_DIRECTIVES, // Ted
// NUM_ASM_DIRECTIVES = 1 + // Opcode ... rest are psuedo opcodes
// NUM_ASM_A_DIRECTIVES + // Acme
// NUM_ASM_B_DIRECTIVES + // Big Mac
// NUM_ASM_K_DIRECTIVES + // DOS Tool Kit
// NUM_ASM_L_DIRECTIVES + // Lisa
// NUM_ASM_M_DIRECTIVES + // Merlin
// NUM_ASM_u_DIRECTIVES + // MicroSparc
// NUM_ASM_O_DIRECTIVES + // Orca
// NUM_ASM_S_DIRECTIVES + // SC
// NUM_ASM_T_DIRECTIVES + // Ted
// NUM_ASM_W_DIRECTIVES // Weller
};
// Addressing _____________________________________________________________________________________
extern AddressingMode_t g_aOpmodes[ NUM_ADDRESSING_MODES ];
// Assembler ______________________________________________________________________________________
// Hashing for Assembler
typedef unsigned int Hash_t;
struct HashOpcode_t
{
int m_iOpcode;
Hash_t m_nValue;
// functor
bool operator () (const HashOpcode_t & rLHS, const HashOpcode_t & rRHS) const
{
bool bLessThan = (rLHS.m_nValue < rRHS.m_nValue);
return bLessThan;
}
};
struct AssemblerDirective_t
{
char *m_pMnemonic;
Hash_t m_nHash;
};
extern int g_bAssemblerOpcodesHashed; // = false;
extern Hash_t g_aOpcodesHash[ NUM_OPCODES ]; // for faster mnemonic lookup, for the assembler
extern bool g_bAssemblerInput; // = false;
extern int g_nAssemblerAddress; // = 0;
extern const Opcodes_t *g_aOpcodes; // = NULL; // & g_aOpcodes65C02[ 0 ];
extern const Opcodes_t g_aOpcodes65C02[ NUM_OPCODES ];
extern const Opcodes_t g_aOpcodes6502 [ NUM_OPCODES ];
extern AssemblerDirective_t g_aAssemblerDirectives[ NUM_ASM_DIRECTIVES ];
// Prototypes _______________________________________________________________
int _6502_GetOpmodeOpbyte( const int iAddress, int & iOpmode_, int & nOpbytes_ );
// void _6502_GetOpcodeOpmode( int & iOpcode_, int & iOpmode_, int & nOpbytes_ );
void _6502_GetOpcodeOpmodeOpbyte( int & iOpcode_, int & iOpmode_, int & nOpbytes_ );
bool _6502_GetStackReturnAddress( WORD & nAddress_ );
bool _6502_GetTargets( WORD nAddress, int *pTargetPartial_, int *pTargetPointer_, int * pBytes_
, const bool bIgnoreJSRJMP = true, bool bIgnoreBranch = true );
bool _6502_GetTargetAddress( const WORD & nAddress, WORD & nTarget_ );
bool _6502_IsOpcodeBranch( int nOpcode );
bool _6502_IsOpcodeValid( int nOpcode );
int AssemblerHashMnemonic ( const TCHAR * pMnemonic );
void AssemblerHashOpcodes ();
void AssemblerHashMerlinDirectives ();
// bool AssemblerGetAddressingMode ( int iArg, int nArgs, WORD nAddress, vector<int> & vOpcodes );
void _CmdAssembleHashDump ();
int AssemblerDelayedTargetsSize();
void AssemblerStartup ();
bool Assemble( int iArg, int nArgs, WORD nAddress );
void AssemblerOn ();
void AssemblerOff ();
#endif

View File

@ -0,0 +1,625 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: Debugger
*
* Author: Copyright (C) 2006, Michael Pohoreski
*/
#include "StdAfx.h"
// Console ________________________________________________________________________________________
// See ConsoleInputReset() for why the console input
// is tied to the zero'th output of g_aConsoleDisplay
// and not using a seperate var: g_aConsoleInput[ CONSOLE_WIDTH ];
//
// : g_aConsoleBuffer[4] | ^ g_aConsoleDisplay[5] :
// : g_aConsoleBuffer[3] | | g_aConsoleDisplay[4] <- g_nConsoleDisplayTotal
// g_nConsoleBuffer -> g_aConsoleBuffer[2] | | g_aConsoleDisplay[3] :
// : g_aConsoleBuffer[1] v | g_aConsoleDisplay[2] :
// . g_aConsoleBuffer[0] -----> | g_aConsoleDisplay[1] .
// |
// g_aBufferedInput[0] -----> ConsoleInput ----> | g_aConsoleDisplay[0]
// g_aBufferedInput[1] ^
// g_aBufferedInput[2] |
// g_aBufferedInput[3] |
// Buffer
bool g_bConsoleBufferPaused = false; // buffered output is waiting for user to continue
int g_nConsoleBuffer = 0;
conchar_t g_aConsoleBuffer[ CONSOLE_BUFFER_HEIGHT ][ CONSOLE_WIDTH ]; // TODO: stl::vector< line_t >
// Cursor
char g_sConsoleCursor[] = "_";
// Display
char g_aConsolePrompt[] = ">!"; // input, assembler // NUM_PROMPTS
char g_sConsolePrompt[] = ">"; // No, NOT Integer Basic! The nostalgic '*' "Monitor" doesn't look as good, IMHO. :-(
int g_nConsolePromptLen = 1;
bool g_bConsoleFullWidth = true; // false
int g_iConsoleDisplayStart = 0; // to allow scrolling
int g_nConsoleDisplayTotal = 0; // number of lines added to console
int g_nConsoleDisplayLines = 0;
int g_nConsoleDisplayWidth = 0;
conchar_t g_aConsoleDisplay[ CONSOLE_HEIGHT ][ CONSOLE_WIDTH ];
// Input History
int g_nHistoryLinesStart = 0;
int g_nHistoryLinesTotal = 0; // number of commands entered
char g_aHistoryLines[ HISTORY_HEIGHT ][ HISTORY_WIDTH ] = {""};
// Input Line
// Raw input Line (has prompt)
char g_aConsoleInput[ CONSOLE_WIDTH ]; // = g_aConsoleDisplay[0];
// Cooked input line (no prompt)
int g_nConsoleInputChars = 0;
char * g_pConsoleInput = 0; // points to past prompt
const char * g_pConsoleFirstArg = 0; // points to first arg
bool g_bConsoleInputQuoted = false; // Allows lower-case to be entered
char g_nConsoleInputSkip = '~';
// Prototypes _______________________________________________________________
// Console ________________________________________________________________________________________
int ConsoleLineLength( const conchar_t * pText )
{
int nLen = 0;
const conchar_t *pSrc = pText;
if (pText )
{
while (*pSrc)
{
pSrc++;
}
nLen = pSrc - pText;
}
return nLen;
}
//===========================================================================
const conchar_t* ConsoleBufferPeek ()
{
return g_aConsoleBuffer[ 0 ];
}
//===========================================================================
bool ConsolePrint ( const char * pText )
{
while (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
// Convert color string to native console color text
// Ignores g_nConsoleDisplayWidth
char c;
int x = 0;
const char *pSrc = pText;
conchar_t *pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
conchar_t g = 0;
bool bHaveColor = false;
char cColor = 0;
while ((x < CONSOLE_WIDTH) && (c = *pSrc))
{
if ((c == '\n') || (x >= (CONSOLE_WIDTH - 1)))
{
*pDst = 0;
x = 0;
if (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
else
{
g_nConsoleBuffer++;
}
pSrc++;
pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
}
else
{
g = (c & _CONSOLE_COLOR_MASK);
// `# `A color encode mouse text
if (ConsoleColor_IsCharMeta( c ))
{
if (! pSrc[1])
break;
if (ConsoleColor_IsCharMeta( pSrc[1] )) // ` `
{
bHaveColor = false;
cColor = 0;
g = ConsoleColor_MakeColor( cColor, c );
*pDst = g;
x++;
pDst++;
}
else
if (ConsoleColor_IsCharColor( pSrc[1] )) // ` #
{
cColor = pSrc[1];
bHaveColor = true;
}
else // ` @
{
c = ConsoleColor_MakeMouse( pSrc[1] );
g = ConsoleColor_MakeColor( cColor, c );
*pDst = g;
x++;
pDst++;
}
pSrc++;
pSrc++;
}
else
{
if (bHaveColor)
{
g = ConsoleColor_MakeColor( cColor, c );
bHaveColor = false;
}
*pDst = g;
x++;
pDst++;
pSrc++;
}
}
/*
if (ConsoleColor_IsCharMeta( c ))
{
// Convert mult-byte to packed char
// 0 1 2 Offset
// =====
// 1 ~ - null
// 2 ~ 0 - null - exit
// 3 ~ 0 x color (3 bytes packed into char16
// 4 ~ @ - mouse text
// 5 ~ @ x mouse Text
// 6 ~ ~ ~
// Legend:
// ~ Color escape
// x Any char
// - Null
if (pSrc[1])
{
if (ConsoleColor_IsCharMeta( pSrc[1] )) // 6
{
*pDst = c;
x++;
pSrc += 2;
pDst++;
}
else
if (ConsoleColor_IsCharColor( pSrc[1] ))
{
if (pSrc[2]) // 3
{
x++;
*pDst = ConsoleColor_MakeColor( pSrc[1], pSrc[2] );
pSrc += 3;
pDst++;
}
else
break; // 2
}
else // 4 or 5
{
*pDst = ConsoleColor_MakeMeta( pSrc[1] );
x++;
pSrc += 2;
pDst++;
}
}
else
break; // 1
}
else
{
*pDst = (c & _CONSOLE_COLOR_MASK);
x++;
pSrc++;
pDst++;
}
*/
}
*pDst = 0;
g_nConsoleBuffer++;
return true;
}
// Add string to buffered output
// Shifts the buffered console output lines "Up"
//===========================================================================
bool ConsoleBufferPush ( const char * pText )
{
while (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
conchar_t c;
int x = 0;
const char *pSrc = pText;
conchar_t *pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
while ((x < CONSOLE_WIDTH) && (c = *pSrc))
{
if ((c == '\n') || (x == (CONSOLE_WIDTH - 1)))
{
*pDst = 0;
x = 0;
if (g_nConsoleBuffer >= CONSOLE_BUFFER_HEIGHT)
{
ConsoleBufferToDisplay();
}
else
{
g_nConsoleBuffer++;
}
pSrc++;
pDst = & g_aConsoleBuffer[ g_nConsoleBuffer ][ 0 ];
}
else
{
*pDst = (c & _CONSOLE_COLOR_MASK);
x++;
pSrc++;
pDst++;
}
}
*pDst = 0;
g_nConsoleBuffer++;
return true;
}
// Shifts the buffered console output "down"
//===========================================================================
void ConsoleBufferPop ()
{
int y = 0;
while (y < g_nConsoleBuffer)
{
memcpy(
g_aConsoleBuffer[ y ],
g_aConsoleBuffer[ y+1 ],
sizeof( conchar_t ) * CONSOLE_WIDTH
);
y++;
}
g_nConsoleBuffer--;
if (g_nConsoleBuffer < 0)
g_nConsoleBuffer = 0;
}
// Remove string from buffered output
//===========================================================================
void ConsoleBufferToDisplay ()
{
ConsoleDisplayPush( ConsoleBufferPeek() );
ConsoleBufferPop();
}
// No mark-up. Straight ASCII conversion
//===========================================================================
void ConsoleConvertFromText ( conchar_t * sText, const char * pText )
{
int x = 0;
const char *pSrc = pText;
conchar_t *pDst = sText;
while (pSrc && *pSrc)
{
*pDst = (conchar_t) (*pSrc & _CONSOLE_COLOR_MASK);
pSrc++;
pDst++;
}
*pDst = 0;
}
//===========================================================================
Update_t ConsoleDisplayError ( const char * pText)
{
ConsoleBufferPush( pText );
return ConsoleUpdate();
}
//===========================================================================
void ConsoleDisplayPush ( const char * pText )
{
conchar_t sText[ CONSOLE_WIDTH * 2 ];
ConsoleConvertFromText( sText, pText );
ConsoleDisplayPush( sText );
}
// Shifts the console display lines "up"
//===========================================================================
void ConsoleDisplayPush ( const conchar_t * pText )
{
int nLen = MIN( g_nConsoleDisplayTotal, CONSOLE_HEIGHT - 1 - CONSOLE_FIRST_LINE);
while (nLen--)
{
memcpy(
(char*) g_aConsoleDisplay[(nLen + 1 + CONSOLE_FIRST_LINE )]
, (char*) g_aConsoleDisplay[nLen + CONSOLE_FIRST_LINE]
, sizeof(conchar_t) * CONSOLE_WIDTH
);
}
if (pText)
{
memcpy(
(char*) g_aConsoleDisplay[ CONSOLE_FIRST_LINE ]
, pText
, sizeof(conchar_t) * CONSOLE_WIDTH
);
}
g_nConsoleDisplayTotal++;
if (g_nConsoleDisplayTotal > (CONSOLE_HEIGHT - CONSOLE_FIRST_LINE))
g_nConsoleDisplayTotal = (CONSOLE_HEIGHT - CONSOLE_FIRST_LINE);
}
//===========================================================================
void ConsoleDisplayPause ()
{
if (g_nConsoleBuffer)
{
#if CONSOLE_INPUT_CHAR16
ConsoleConvertFromText(
g_aConsoleInput,
"...press SPACE continue, ESC skip..."
);
g_nConsolePromptLen = ConsoleLineLength( g_pConsoleInput ) + 1;
#else
strcpy(
g_aConsoleInput,
"...press SPACE continue, ESC skip..."
);
g_nConsolePromptLen = strlen( g_pConsoleInput ) + 1;
#endif
g_nConsoleInputChars = 0;
g_bConsoleBufferPaused = true;
}
else
{
ConsoleInputReset();
}
}
//===========================================================================
bool ConsoleInputBackSpace ()
{
if (g_nConsoleInputChars)
{
g_pConsoleInput[ g_nConsoleInputChars ] = CHAR_SPACE;
g_nConsoleInputChars--;
if ((g_pConsoleInput[ g_nConsoleInputChars ] == CHAR_QUOTE_DOUBLE) ||
(g_pConsoleInput[ g_nConsoleInputChars ] == CHAR_QUOTE_SINGLE))
g_bConsoleInputQuoted = ! g_bConsoleInputQuoted;
g_pConsoleInput[ g_nConsoleInputChars ] = CHAR_SPACE;
return true;
}
return false;
}
// Clears prompt too
//===========================================================================
bool ConsoleInputClear ()
{
ZeroMemory( g_aConsoleInput, CONSOLE_WIDTH );
if (g_nConsoleInputChars)
{
g_nConsoleInputChars = 0;
return true;
}
return false;
}
//===========================================================================
bool ConsoleInputChar ( const char ch )
{
if (g_nConsoleInputChars < g_nConsoleDisplayWidth) // bug? include prompt?
{
g_pConsoleInput[ g_nConsoleInputChars ] = ch;
g_nConsoleInputChars++;
return true;
}
return false;
}
//===========================================================================
void ConsoleUpdateCursor ( char ch )
{
if (ch)
g_sConsoleCursor[0] = ch;
else
{
ch = (char) g_aConsoleInput[ g_nConsoleInputChars + g_nConsolePromptLen ];
if (! ch)
{
ch = CHAR_SPACE;
}
g_sConsoleCursor[0] = ch;
}
}
//===========================================================================
const char * ConsoleInputPeek ()
{
// return g_aConsoleDisplay[0];
// return g_pConsoleInput;
return g_aConsoleInput;
}
//===========================================================================
void ConsoleInputReset ()
{
// Not using g_aConsoleInput since we get drawing of the input Line for "Free"
// Even if we add console scrolling, we don't need any special logic to draw the input line.
g_bConsoleInputQuoted = false;
ConsoleInputClear();
// _tcscpy( g_aConsoleInput, g_sConsolePrompt ); // Assembler can change prompt
g_aConsoleInput[0] = g_sConsolePrompt[0];
g_nConsolePromptLen = 1;
// int nLen = strlen( g_aConsoleInput );
#if CONSOLE_INPUT_CHAR16
int nLen = ConsoleLineLength( g_aConsoleInput );
#else
int nLen = strlen( g_aConsoleInput );
#endif
g_pConsoleInput = &g_aConsoleInput[ g_nConsolePromptLen ];
g_nConsoleInputChars = 0;
}
//===========================================================================
int ConsoleInputTabCompletion ()
{
return UPDATE_CONSOLE_INPUT;
}
//===========================================================================
Update_t ConsoleScrollHome ()
{
g_iConsoleDisplayStart = g_nConsoleDisplayTotal - CONSOLE_FIRST_LINE;
if (g_iConsoleDisplayStart < 0)
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollEnd ()
{
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollUp ( int nLines )
{
g_iConsoleDisplayStart += nLines;
if (g_iConsoleDisplayStart > (g_nConsoleDisplayTotal - CONSOLE_FIRST_LINE))
g_iConsoleDisplayStart = (g_nConsoleDisplayTotal - CONSOLE_FIRST_LINE);
if (g_iConsoleDisplayStart < 0)
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollDn ( int nLines )
{
g_iConsoleDisplayStart -= nLines;
if (g_iConsoleDisplayStart < 0)
g_iConsoleDisplayStart = 0;
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollPageUp ()
{
ConsoleScrollUp( g_nConsoleDisplayLines - CONSOLE_FIRST_LINE );
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleScrollPageDn ()
{
ConsoleScrollDn( g_nConsoleDisplayLines - CONSOLE_FIRST_LINE );
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
Update_t ConsoleBufferTryUnpause (int nLines)
{
for( int y = 0; y < nLines; y++ )
{
ConsoleBufferToDisplay();
}
g_bConsoleBufferPaused = false;
if (g_nConsoleBuffer)
{
g_bConsoleBufferPaused = true;
ConsoleDisplayPause();
return UPDATE_CONSOLE_INPUT | UPDATE_CONSOLE_DISPLAY;
}
return UPDATE_CONSOLE_DISPLAY;
}
// Flush the console
//===========================================================================
Update_t ConsoleUpdate ()
{
if (! g_bConsoleBufferPaused)
{
int nLines = MIN( g_nConsoleBuffer, g_nConsoleDisplayLines - 1);
return ConsoleBufferTryUnpause( nLines );
}
return UPDATE_CONSOLE_DISPLAY;
}
//===========================================================================
void ConsoleFlush ()
{
int nLines = g_nConsoleBuffer;
ConsoleBufferTryUnpause( nLines );
}

View File

@ -0,0 +1,256 @@
#ifndef DEBUGGER_CONSOLE_H
#define DEBUGGER_CONSOLE_H
enum
{
CONSOLE_HEIGHT = 384, // Lines, was 128, but need ~ 256+16 for PROFILE LIST
CONSOLE_WIDTH = 80,
// need min 256+ lines for "profile list"
CONSOLE_BUFFER_HEIGHT = 384,
HISTORY_HEIGHT = 128,
HISTORY_WIDTH = 128,
CONSOLE_FIRST_LINE = 1, // where ConsoleDisplay is pushed up from
};
// Color ____________________________________________________________________
// typedef unsigned char conchar_t;
typedef short conchar_t;
enum ConsoleColors_e
{
CONSOLE_COLOR_K, // 0
CONSOLE_COLOR_x = 0, // default console foreground
CONSOLE_COLOR_R, // 1
CONSOLE_COLOR_G, // 2
CONSOLE_COLOR_Y, // 3
CONSOLE_COLOR_B, // 4
CONSOLE_COLOR_M, // 5 Lite Blue
CONSOLE_COLOR_C, // 6
CONSOLE_COLOR_W, // 7
CONSOLE_COLOR_O, // 8
CONSOLE_COLOR_k, // 9 Grey
NUM_CONSOLE_COLORS
};
extern COLORREF g_anConsoleColor[ NUM_CONSOLE_COLORS ];
// Note: THe ` ~ key should always display ~ to prevent rendering errors
#define CONSOLE_COLOR_ESCAPE_CHAR '`'
#define _CONSOLE_COLOR_MASK 0x7F
/* Help Colors
*/
#if 1 // USE_APPLE_FONT
// Console Help Color
#define CHC_DEFAULT "`0"
#define CHC_USAGE "`3"
#define CHC_CATEGORY "`6"
#define CHC_COMMAND "`2"
#define CHC_KEY "`1"
#define CHC_ARG_MAND "`7" // < >
#define CHC_ARG_OPT "`4" // [ ]
#define CHC_ARG_SEP "`9" // | grey
#define CHC_NUM_DEC "`6" // cyan looks better then yellow
#define CHC_NUM_HEX "`3"
#define CHC_SYMBOL "`2"
#define CHC_ADDRESS "`8"
#define CHC_ERROR "`1"
#define CHC_STRING "`6"
#define CHC_EXAMPLE "`5"
#else
#define CHC_DEFAULT ""
#define CHC_USAGE ""
#define CHC_COMMAND ""
#define CHC_KEY ""
#define CHC_ARG_MAND ""
#define CHC_ARG_OPT ""
#define CHC_ARG_SEP ""
#define CHC_NUMBER ""
#define CHC_SYMBOL ""
#define CHC_ADDRESS ""
#define CHC_ERROR ""
#define CHC_STRING ""
#define CHC_EXAMPLE ""
#endif
// ascii markup
inline bool ConsoleColor_IsCharMeta( unsigned char c )
{
if (CONSOLE_COLOR_ESCAPE_CHAR == c)
return true;
return false;
}
inline bool ConsoleColor_IsCharColor( unsigned char c )
{
if ((c >= '0') && ((c - '0') < NUM_CONSOLE_COLORS))
return true;
return false;
}
// Console "Native" Chars
//
// There are a few different ways of encoding color chars & mouse text
// Simplist method is to use a user-defined ESCAPE char to shift
// into color mode, or mouse text mode. The other solution
// is to use a wide-char, simulating unicode16.
//
// C1C0 char16 of High Byte (c1) and Low Byte (c0)
// 1) --?? Con: Colors chars take up extra chars.
// Con: String Length is complicated.
// Pro: simple to parse
//
// <-- WE USE THIS
// 2) ccea Pro: Efficient packing of plain text and mouse text
// Pro: Color is optional (only record new color)
// Con: need to provide char8 and char16 API
// Con: little more difficult to parse/convert plain text
// i.e.
// ea = 0x20 - 0x7F ASCII
// 0x80 - 0xFF Mouse Text '@'-'Z' -> 0x00 - 0x1F
// cc = ASCII '0' - '9' (color)
// 3) ??cc Con: Colors chars take up extra chars
// 4) f?? Con: Colors chars take up extra chars
//
// Legend:
// f Flag
// -- Not Applicable (n/a)
// ?? ASCII (0x20 - 0x7F)
// ea Extended ASCII with High-Bit representing Mouse Text
// cc Encoded Color / Mouse Text
//
inline bool ConsoleColor_IsColorOrMouse( conchar_t g )
{
if (g > _CONSOLE_COLOR_MASK)
return true;
return false;
}
inline bool ConsoleColor_IsColor( conchar_t g )
{
return ConsoleColor_IsCharColor (g >> 8);
}
inline COLORREF ConsoleColor_GetColor( conchar_t g )
{
const int iColor = (g >> 8) - '0';
if (iColor < NUM_CONSOLE_COLORS)
return g_anConsoleColor[ iColor ];
return g_anConsoleColor[ 0 ];
}
inline char ConsoleColor_GetMeta( conchar_t g )
{
return ((g >> 8) & _CONSOLE_COLOR_MASK);
}
inline char ConsoleChar_GetChar( conchar_t g )
{
return (g & _CONSOLE_COLOR_MASK);
}
inline char ConsoleColor_MakeMouse( unsigned char c )
{
return ((c - '@') + (_CONSOLE_COLOR_MASK + 1));
}
inline conchar_t ConsoleColor_MakeMeta( unsigned char c )
{
conchar_t g = (ConsoleColor_MakeMouse(c) << 8);
return g;
}
inline conchar_t ConsoleColor_MakeColor( unsigned char color, unsigned char text )
{
conchar_t g = (color << 8) | text;
return g;
}
// Globals __________________________________________________________________
// Buffer
extern bool g_bConsoleBufferPaused;
extern int g_nConsoleBuffer;
extern conchar_t g_aConsoleBuffer[ CONSOLE_BUFFER_HEIGHT ][ CONSOLE_WIDTH ]; // TODO: stl::vector< line_t >
// Cursor
extern char g_sConsoleCursor[];
// Display
extern char g_aConsolePrompt[];// = TEXT(">!"); // input, assembler // NUM_PROMPTS
extern char g_sConsolePrompt[];// = TEXT(">"); // No, NOT Integer Basic! The nostalgic '*' "Monitor" doesn't look as good, IMHO. :-(
extern int g_nConsolePromptLen;
extern bool g_bConsoleFullWidth;// = false;
extern int g_iConsoleDisplayStart ; // to allow scrolling
extern int g_nConsoleDisplayTotal ; // number of lines added to console
extern int g_nConsoleDisplayLines ;
extern int g_nConsoleDisplayWidth ;
extern conchar_t g_aConsoleDisplay[ CONSOLE_HEIGHT ][ CONSOLE_WIDTH ];
// Input History
extern int g_nHistoryLinesStart;// = 0;
extern int g_nHistoryLinesTotal;// = 0; // number of commands entered
extern char g_aHistoryLines[ HISTORY_HEIGHT ][ HISTORY_WIDTH ];// = {TEXT("")};
// Input Line
// Raw input Line (has prompt)
extern char g_aConsoleInput[ CONSOLE_WIDTH ];
// Cooked input line (no prompt)
extern int g_nConsoleInputChars ;
extern char * g_pConsoleInput ; // points to past prompt
extern const char * g_pConsoleFirstArg ; // points to first arg
extern bool g_bConsoleInputQuoted ;
extern char g_nConsoleInputSkip ;
// Prototypes _______________________________________________________________
// Console
// Buffered
bool ConsolePrint( const char * pText );
void ConsoleBufferToDisplay ();
const conchar_t* ConsoleBufferPeek ();
void ConsoleBufferPop ();
bool ConsoleBufferPush ( const char * pString );
void ConsoleConvertFromText( conchar_t * sText, const char * pText );
// Display
Update_t ConsoleDisplayError ( const char * pTextError );
void ConsoleDisplayPause ();
void ConsoleDisplayPush ( const char * pText );
void ConsoleDisplayPush ( const conchar_t * pText );
Update_t ConsoleUpdate ();
void ConsoleFlush ();
// Input
void ConsoleInputToDisplay ();
const char *ConsoleInputPeek ();
bool ConsoleInputClear ();
bool ConsoleInputBackSpace ();
bool ConsoleInputChar ( TCHAR ch );
void ConsoleInputReset ();
int ConsoleInputTabCompletion ();
void ConsoleUpdateCursor( char ch );
Update_t ConsoleBufferTryUnpause (int nLines);
// Scrolling
Update_t ConsoleScrollHome ();
Update_t ConsoleScrollEnd ();
Update_t ConsoleScrollUp ( int nLines );
Update_t ConsoleScrollDn ( int nLines );
Update_t ConsoleScrollPageUp ();
Update_t ConsoleScrollPageDn ();
#endif

View File

@ -0,0 +1,367 @@
/*
AppleWin : An Apple //e emulator for Windows
/* Description: Data Blocks shown in Disassembler
*
* Author: Copyright (C) 2009 Michael Pohoreski
*/
#include "StdAfx.h"
// Disassembler Data ______________________________________________________________________________
// __ Debugger Interaface ____________________________________________________________________________
//===========================================================================
WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_)
{
WORD nAddress = 0;
WORD nAddress2 = 0;
WORD nEnd = 0;
int nLen = 0;
if( nArgs < 2 )
{
nAddress = g_nDisasmCurAddress;
}
else
{
RangeType_t eRange = Range_Get( nAddress, nAddress2, iArg);
if ((eRange == RANGE_HAS_END) ||
(eRange == RANGE_HAS_LEN))
{
Range_CalcEndLen( eRange, nAddress, nAddress2, nEnd, nLen );
//dArg = 2;
}
else
{
nAddress = g_aArgs[ 2 ].nValue;
}
}
if (!nLen)
{
nLen = 1;
}
tData_.nStartAddress = nAddress;
tData_.nEndAddress = nAddress + nLen;
char *pSymbolName = "";
if( nArgs )
{
pSymbolName = g_aArgs[ 1 ].sArg;
SymbolTable_Index_e eSymbolTable = SYMBOLS_ASSEMBLY;
// bRemoveSymbol = false // use arg[2]
// bUpdateSymbol = true // add the symbol to the table
SymbolUpdate( eSymbolTable, pSymbolName, nAddress, false, true );
// Note: need to call ConsoleUpdate(), as may print symbol has been updated
}
else
{
// TODO: 'DB' with no args, should define D_# DB $XX
}
strcpy( tData_.sSymbol, pSymbolName );
return nAddress;
}
// Undefine Data
//===========================================================================
Update_t CmdDisasmDataDefCode (int nArgs)
{
// treat memory (bytes) as code
if (! ((nArgs <= 2) || (nArgs == 4)))
{
return Help_Arg_1( CMD_DISASM_CODE );
}
DisasmData_t tData;
int iArg = 2;
WORD nAddress = _CmdDefineByteRange( nArgs, iArg, tData );
// Need to iterate through all blocks
// DB TEST1 300:320
// DB TEST2 310:330
// DB TEST3 320:340
// !DB 300
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
if( pData )
{
// Need to split the data
// *pData = tData;
Disassembly_AddData( tData );
}
else
{
Disassembly_DelData( tData );
}
return UPDATE_DISASM | ConsoleUpdate();
}
// List the data blocks
//===========================================================================
Update_t CmdDisasmDataList (int nArgs)
{
// Need to iterate through all blocks
DisasmData_t* pData = NULL;
char sText[ CONSOLE_WIDTH ];
while( pData = Disassembly_Enumerate( pData ) )
{
// `TEST `300`:`320
sprintf( sText, "%s%s %s%04X%s:%s%04X\n"
, CHC_SYMBOL
, pData->sSymbol
, CHC_ADDRESS
, pData->nStartAddress
, CHC_ARG_SEP
, pData->nEndAddress
);
ConsolePrint( sText );
}
return UPDATE_DISASM | ConsoleUpdate();
}
// Common code
//===========================================================================
Update_t _CmdDisasmDataDefByteX (int nArgs)
{
// DB
// DB symbol
// DB symbol address
// symbol range:range
int iCmd = NOP_BYTE_1 - g_aArgs[0].nValue;
if (! ((nArgs <= 2) || (nArgs == 4)))
{
return Help_Arg_1( CMD_DEFINE_DATA_BYTE1 + iCmd );
}
DisasmData_t tData;
int iArg = 2;
WORD nAddress = _CmdDefineByteRange( nArgs, iArg, tData );
tData.iDirective = FIRST_M_DIRECTIVE + ASM_M_DEFINE_BYTE;
tData.eElementType = NOP_BYTE_1 + iCmd;
tData.bSymbolLookup = false;
tData.nTargetAddress = 0;
// Already exists, so update
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
if( pData )
{
*pData = tData;
}
else
Disassembly_AddData( tData );
return UPDATE_DISASM | ConsoleUpdate();
}
//===========================================================================
Update_t _CmdDisasmDataDefWordX (int nArgs)
{
// DW
// DW symbol
// DW symbol address
// symbol range:range
int iCmd = NOP_WORD_1 - g_aArgs[0].nValue;
if (! ((nArgs <= 2) || (nArgs == 4)))
{
return Help_Arg_1( CMD_DEFINE_DATA_WORD1 + iCmd );
}
DisasmData_t tData;
int iArg = 2;
WORD nAddress = _CmdDefineByteRange( nArgs, iArg, tData );
tData.iDirective = FIRST_M_DIRECTIVE + ASM_M_DEFINE_WORD;
tData.eElementType = NOP_WORD_1 + iCmd;
tData.bSymbolLookup = false;
tData.nTargetAddress = 0;
// Already exists, so update
DisasmData_t *pData = Disassembly_IsDataAddress( nAddress );
if( pData )
{
*pData = tData;
}
else
Disassembly_AddData( tData );
return UPDATE_DISASM | ConsoleUpdate();
}
//===========================================================================
Update_t CmdDisasmDataDefAddress8H (int nArgs)
{
return UPDATE_DISASM;
}
//===========================================================================
Update_t CmdDisasmDataDefAddress8L (int nArgs)
{
return UPDATE_DISASM;
}
//===========================================================================
Update_t CmdDisasmDataDefAddress16 (int nArgs)
{
return UPDATE_DISASM;
}
Update_t CmdDisasmDataDefByte1 ( int nArgs )
{
g_aArgs[0].nValue = NOP_BYTE_1;
return _CmdDisasmDataDefByteX( nArgs );
}
Update_t CmdDisasmDataDefByte2 ( int nArgs )
{
g_aArgs[0].nValue = NOP_BYTE_2;
return _CmdDisasmDataDefByteX( nArgs );
}
Update_t CmdDisasmDataDefByte4 ( int nArgs )
{
g_aArgs[0].nValue = NOP_BYTE_4;
return _CmdDisasmDataDefByteX( nArgs );
}
Update_t CmdDisasmDataDefByte8 ( int nArgs )
{
g_aArgs[0].nValue = NOP_BYTE_8;
return _CmdDisasmDataDefByteX( nArgs );
}
Update_t CmdDisasmDataDefWord1 ( int nArgs )
{
g_aArgs[0].nValue = NOP_WORD_1;
return _CmdDisasmDataDefWordX( nArgs );
}
Update_t CmdDisasmDataDefWord2 ( int nArgs )
{
g_aArgs[0].nValue = NOP_WORD_2;
return _CmdDisasmDataDefWordX( nArgs );
}
Update_t CmdDisasmDataDefWord4 ( int nArgs )
{
g_aArgs[0].nValue = NOP_WORD_4;
return _CmdDisasmDataDefWordX( nArgs );
}
Update_t CmdDisasmDataDefString ( int nArgs )
{
return UPDATE_DISASM;
}
// __ Disassembler View Interface ____________________________________________________________________
/// @param pCurrent NULL start a new serch, or continue enumerating
//===========================================================================
DisasmData_t* Disassembly_Enumerate( DisasmData_t *pCurrent )
{
DisasmData_t *pData = NULL; // bIsNopcode = false
int nDataTargets = g_aDisassemblerData.size();
if( pCurrent )
{
pCurrent++;
pData = & g_aDisassemblerData[ nDataTargets ];
if( pCurrent < pData )
return pCurrent;
else
return NULL;
}
else
{
pData = & g_aDisassemblerData[ 0 ];
if( nDataTargets )
return pData;
else
return NULL;
}
}
// returns NULL if address has no data associated with it
//===========================================================================
DisasmData_t* Disassembly_IsDataAddress ( WORD nAddress )
{
DisasmData_t *pData = NULL; // bIsNopcode = false
int nDataTargets = g_aDisassemblerData.size();
if( nDataTargets )
{
// TODO: Replace with binary search -- should store data in sorted order, via start address
pData = & g_aDisassemblerData[ 0 ];
for( int iTarget = 0; iTarget < nDataTargets; iTarget++ )
{
if( (nAddress >= pData->nStartAddress) && (nAddress < pData->nEndAddress) )
{
return pData;
}
pData++;
}
pData = NULL; // bIsNopCode = false
}
return pData;
}
//===========================================================================
void Disassembly_AddData( DisasmData_t tData)
{
g_aDisassemblerData.push_back( tData );
}
//===========================================================================
void Disassembly_GetData ( WORD nBaseAddress, const DisasmData_t *pData, DisasmLine_t & line_ )
{
line_.ClearFlags();
line_.iNoptype = pData->eElementType;
switch( pData->eElementType )
{
case NOP_BYTE_1:
line_.nOpbyte = 1;
break;
case NOP_BYTE_2:
line_.nOpbyte = 2;
break;
case NOP_WORD_1:
line_.nOpbyte= 2;
break;
case NOP_WORD_2:
line_.nOpbyte= 4;
break;
case NOP_STRING_APPLESOFT:
// scan memory for high byte
line_.nOpbyte = 8;
break;
default:
line_.nOpbyte = 1;
break;
}
FormatOpcodeBytes( nBaseAddress, line_ );
//pMnemonic = g_aOpcodes[ iOpcode ].sMnemonic;
line_.iNopcode = pData->iDirective;
strcpy( line_.sMnemonic, g_aAssemblerDirectives[ line_.iNopcode ].m_pMnemonic );
FormatNopcodeBytes( nBaseAddress, line_ );
}
//===========================================================================
void Disassembly_DelData( DisasmData_t tData)
{
// g_aDisassemblerData.erase( );
}

View File

@ -0,0 +1,55 @@
#ifndef DEBUGGER_DISASSEMBLERDATA_H
#define DEBUGGER_DISASSEMBLERDATA_H
enum NopcodeType_e
{
NOP_BYTE_1 // 1 bytes/line
,NOP_BYTE_2 // 2 bytes/line
,NOP_BYTE_4 // 4 bytes/line
,NOP_BYTE_8 // 8 bytes/line
,NOP_WORD_1 // 1 words/line
,NOP_WORD_2 // 2 words/line
,NOP_WORD_4 // 4 words/line
,NOP_ADDRESS// 1 word/line
,NOP_HEX
,NOP_CHAR
,NOP_STRING_ASCII
,NOP_STRING_APPLE
,NOP_STRING_APPLESOFT
,NOP_FAC
,NUM_NOPCODE_TYPES
};
// Disassembler Data
// type symbol[start:end]
struct DisasmData_t
{
char sSymbol[ MAX_SYMBOLS_LEN+1 ];
WORD iDirective ; // Assembler directive -> nopcode
WORD nStartAddress; // link to block [start,end)
WORD nEndAddress ;
WORD nArraySize ; // Total bytes
// WORD nBytePerRow ; // 1, 8
char eElementType; //
// with symbol lookup
char bSymbolLookup ;
WORD nTargetAddress;
};
Update_t _CmdDisasmDataDefByteX (int nArgs);
Update_t _CmdDisasmDataDefWordX (int nArgs);
// Data Disassembler ______________________________________________________________________________
int Disassembly_FindOpcode( WORD nAddress );
DisasmData_t* Disassembly_IsDataAddress( WORD nAddress );
void Disassembly_AddData( DisasmData_t tData);
void Disassembly_GetData ( WORD nBaseAddress, const DisasmData_t *pData_, DisasmLine_t & line_ );
void Disassembly_DelData( DisasmData_t tData);
DisasmData_t* Disassembly_Enumerate( DisasmData_t *pCurrent = NULL );
extern vector<DisasmData_t> g_aDisassemblerData;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
#ifndef DEBUGGER_DISPLAY_H
#define DEBUGGER_DISPLAY_H
// use the new Debugger Font (Apple Font)
#define USE_APPLE_FONT 1
// Test Colors & Glyphs
#define DEBUG_APPLE_FONT 0
// Win32 Debugger Font
// 1 = Use Debugger_Font.BMP (7x8)
// 0 = Use CHARSET40.bmp (fg & bg colors aren't proper)
#define APPLE_FONT_NEW 1
#if APPLE_FONT_NEW
#define APPLE_FONT_BITMAP_PADDED 0
#else
#define APPLE_FONT_BITMAP_PADDED 1
#endif
enum ConsoleFontSize_e
{
#if APPLE_FONT_NEW
// Grid Alignment
CONSOLE_FONT_GRID_X = 7,
CONSOLE_FONT_GRID_Y = 8,
// Font Char Width/Height in pixels
CONSOLE_FONT_WIDTH = 7,
CONSOLE_FONT_HEIGHT = 8,
#else
CONSOLE_FONT_GRID_X = 8,
CONSOLE_FONT_GRID_Y = 8,
// Font Char Width/Height in pixels
CONSOLE_FONT_WIDTH = 7,
CONSOLE_FONT_HEIGHT = 8,
#endif
};
// extern HDC g_hDstDC ;
extern HBRUSH g_hConsoleBrushFG;
extern HBRUSH g_hConsoleBrushBG;
extern HDC g_hConsoleFontDC;
extern HBRUSH g_hConsoleFontBrush;
extern HBITMAP g_hConsoleFontBitmap;
enum
{
DISPLAY_HEIGHT = 384,
MAX_DISPLAY_LINES = DISPLAY_HEIGHT / CONSOLE_FONT_HEIGHT,
};
int GetConsoleTopPixels( int y );
extern FontConfig_t g_aFontConfig[ NUM_FONTS ];
void DebuggerSetColorFG( COLORREF nRGB );
void DebuggerSetColorBG( COLORREF nRGB, bool bTransparent = false );
void PrintGlyph ( const int x, const int y, const int iChar );
int PrintText ( const char * pText, RECT & rRect );
int PrintTextCursorX( const char * pText, RECT & rRect );
int PrintTextCursorY( const char * pText, RECT & rRect );
void PrintTextColor ( const conchar_t * pText, RECT & rRect );
void DrawWindow_Source (Update_t bUpdate);
void DrawBreakpoints ( int line);
void DrawConsoleInput ();
void DrawConsoleLine ( const conchar_t * pText, int y);
void DrawConsoleCursor ();
int GetDisassemblyLine( const WORD nOffset, DisasmLine_t & line_ );
// , int iOpcode, int iOpmode, int nOpbytes
// char *sAddress_, char *sOpCodes_,
// char *sTarget_, char *sTargetOffset_, int & nTargetOffset_, char *sTargetValue_,
// char * sImmediate_, char & nImmediate_, char *sBranch_ );
WORD DrawDisassemblyLine ( int line, const WORD offset );
void FormatDisassemblyLine( const DisasmLine_t & line, char *sDisassembly_, const int nBufferSize );
void FormatOpcodeBytes ( WORD nBaseAddress, DisasmLine_t & line_ );
void FormatNopcodeBytes ( WORD nBaseAddress, DisasmLine_t & line_ );
void DrawFlags ( int line, WORD nRegFlags, LPTSTR pFlagNames_);
void DrawMemory ( int line, int iMem );
void DrawRegister ( int line, LPCTSTR name, int bytes, WORD value, int iSource = 0 );
void DrawStack ( int line);
void DrawTargets ( int line);
void DrawWatches ( int line);
void DrawZeroPagePointers ( int line);
void Debug_UpdatePalette( BYTE *pPalDst );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
#ifndef DEBUGGER_HELP_H
#define DEBUGGER_HELP_H
enum Match_e
{
MATCH_EXACT,
MATCH_FUZZY
};
// Prototypes _______________________________________________________________
Update_t HelpLastCommand();
void DisplayAmbigiousCommands ( int nFound );
int FindParam( LPTSTR pLookupName, Match_e eMatch, int & iParam_, const int iParamBegin = 0, const int iParamEnd = NUM_PARAMS - 1 );
int FindCommand( LPTSTR pName, CmdFuncPtr_t & pFunction_, int * iCommand_ = NULL );
inline void UnpackVersion( const unsigned int nVersion,
int & nMajor_, int & nMinor_, int & nFixMajor_ , int & nFixMinor_ )
{
nMajor_ = (nVersion >> 24) & 0xFF;
nMinor_ = (nVersion >> 16) & 0xFF;
nFixMajor_ = (nVersion >> 8) & 0xFF;
nFixMinor_ = (nVersion >> 0) & 0xFF;
}
bool TestStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize );
bool TryStringCat ( TCHAR * pDst, LPCSTR pSrc, const int nDstSize );
int StringCat( TCHAR * pDst, LPCSTR pSrc, const int nDstSize );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,240 @@
#ifndef DEBUGGER_PARSER_H
#define DEBUGGER_PARSER_H
#define CHAR_LF '\x0D'
#define CHAR_CR '\x0A'
#define CHAR_SPACE ' '
#define CHAR_TAB '\t'
#define CHAR_QUOTE_DOUBLE '"'
#define CHAR_QUOTE_SINGLE '\''
#define CHAR_ESCAPE '\x1B'
// Globals __________________________________________________________________
extern int g_nArgRaw;
extern Arg_t g_aArgRaw[ MAX_ARGS ]; // pre-processing
extern Arg_t g_aArgs [ MAX_ARGS ]; // post-processing
extern const TCHAR * g_pConsoleFirstArg; // = 0; // points to first arg
extern const TokenTable_t g_aTokens[ NUM_TOKENS ];
extern const TCHAR TCHAR_LF ;//= 0x0D;
extern const TCHAR TCHAR_CR ;//= 0x0A;
extern const TCHAR TCHAR_SPACE ;//= TEXT(' ');
extern const TCHAR TCHAR_TAB ;//= TEXT('\t');
extern const TCHAR TCHAR_QUOTE_DOUBLE;
extern const TCHAR TCHAR_QUOTE_SINGLE;
// Prototypes _______________________________________________________________
// Arg - Command Processing
Update_t Help_Arg_1( int iCommandHelp );
int _Arg_1 ( int nValue );
int _Arg_1 ( LPTSTR pName );
int _Arg_Shift ( int iSrc, int iEnd, int iDst = 0 );
int _Args_Insert( int iSrc, int iEnd, int nLen );
void ArgsClear ();
bool ArgsGetValue ( Arg_t *pArg, WORD * pAddressValue_, const int nBase = 16 );
bool ArgsGetImmediateValue ( Arg_t *pArg, WORD * pAddressValue_ );
int ArgsGet ( TCHAR * pInput );
bool ArgsGetRegisterValue ( Arg_t *pArg, WORD * pAddressValue_ );
void ArgsRawParse ( void );
int ArgsCook ( const int nArgs ); // const int bProcessMask );
// Token
const char * ParserFindToken( const char *pSrc, const TokenTable_t *aTokens, const int nTokens, ArgToken_e * pToken_ );
// Text Util
/*
inline const char* SkipEOL ( const char *pSrc )
{
while (pSrc && ((*pSrc == CHAR_LF) || (*pSrc == CHAR_CR)))
if (pSrc)
{
pSrc++;
}
return pSrc;
}
*/
inline const char* EatEOL ( const char *pSrc )
{
if (pSrc)
{
if (*pSrc == CHAR_LF)
pSrc++;
if (*pSrc == CHAR_CR)
pSrc++;
}
return pSrc;
}
inline const char* SkipWhiteSpace ( const char *pSrc )
{
while (pSrc && ((*pSrc == CHAR_SPACE) || (*pSrc == CHAR_TAB)))
{
pSrc++;
}
return pSrc;
}
inline const char* SkipWhiteSpaceReverse ( const char *pSrc, const char *pStart )
{
while (pSrc && ((*pSrc == CHAR_SPACE) || (*pSrc == CHAR_TAB)) && (pSrc > pStart))
{
pSrc--;
}
return pSrc;
}
inline const char* SkipUntilChar ( const char *pSrc, const char nDelim )
{
while (pSrc && (*pSrc))
{
if (*pSrc == nDelim)
break;
pSrc++;
}
return pSrc;
}
inline const char* SkipUntilEOL ( const char *pSrc )
{
// EOL delims: NULL, LF, CR
while (pSrc && (*pSrc))
{
if ((*pSrc == CHAR_LF) || (*pSrc == CHAR_CR))
{
break;
}
pSrc++;
}
return pSrc;
}
inline const char* SkipUntilTab ( const char *pSrc)
{
while (pSrc && (*pSrc))
{
if (*pSrc == CHAR_TAB)
{
break;
}
pSrc++;
}
return pSrc;
}
inline const char* SkipUntilToken ( const char *pSrc, const TokenTable_t *aTokens, const int nTokens, ArgToken_e *pToken_ )
{
if ( pToken_)
*pToken_ = NO_TOKEN;
while (pSrc && (*pSrc))
{
if (ParserFindToken( pSrc, aTokens, nTokens, pToken_ ))
return pSrc;
pSrc++;
}
return pSrc;
}
inline const char* SkipUntilWhiteSpace ( const char *pSrc )
{
while (pSrc && (*pSrc))
{
if ((*pSrc == CHAR_SPACE) || (*pSrc == CHAR_TAB))
{
break;
}
pSrc++;
}
return pSrc;
}
inline const char* SkipUntilWhiteSpaceReverse ( const char *pSrc, const char *pStart )
{
while (pSrc && (pSrc > pStart))
{
if ((*pSrc == CHAR_SPACE) || (*pSrc == CHAR_TAB))
{
break;
}
pSrc--;
}
return pSrc;
}
/*
const TCHAR* SkipEOL ( const TCHAR *pSrc );
const TCHAR* SkipWhiteSpace ( const TCHAR *pSrc );
const TCHAR* SkipWhiteSpaceReverse ( const TCHAR *pSrc, const TCHAR *pStart );
const TCHAR* SkipUntilChar ( const TCHAR *pSrc, const TCHAR nDelim );
const TCHAR* SkipUntilEOL ( const TCHAR *pSrc );
const TCHAR* SkipUntilToken ( const TCHAR *pSrc, const TokenTable_t *aTokens, const int nTokens, ArgToken_e *pToken_ );
const TCHAR* SkipUntilWhiteSpace ( const TCHAR *pSrc );
const TCHAR* SkipUntilWhiteSpaceReverse ( const TCHAR *pSrc, const TCHAR *pStart );
const TCHAR* SkipUntilTab ( const TCHAR *pSrc);
*/
const TCHAR * FindTokenOrAlphaNumeric ( const TCHAR *pSrc, const TokenTable_t *aTokens, const int nTokens, ArgToken_e * pToken_ );
// TextRemoveWhiteSpaceReverse
int RemoveWhiteSpaceReverse ( char *pSrc );
// TextExpandTabsToSpaces
void TextConvertTabsToSpaces( TCHAR *pDeTabified_, LPCTSTR pText, const int nDstSize, int nTabStop = 0 );
/** Assumes text are valid hex digits!
//=========================================================================== */
inline BYTE TextConvert2CharsToByte ( char *pText )
{
BYTE n = ((pText[0] <= '@') ? (pText[0] - '0') : (pText[0] - 'A' + 10)) << 4;
n += ((pText[1] <= '@') ? (pText[1] - '0') : (pText[1] - 'A' + 10)) << 0;
return n;
}
//===========================================================================
inline bool TextIsHexChar( char nChar )
{
if ((nChar >= '0') && (nChar <= '9'))
return true;
if ((nChar >= 'A') && (nChar <= 'F'))
return true;
if ((nChar >= 'a') && (nChar <= 'f'))
return true;
return false;
}
//===========================================================================
inline bool TextIsHexByte( char *pText )
{
if (TextIsHexChar( pText[0] ) &&
TextIsHexChar( pText[1] ))
return true;
return false;
}
//===========================================================================
inline bool TextIsHexString ( LPCSTR pText )
{
while (*pText)
{
if (! TextIsHexChar( *pText ))
return false;
pText++;
}
return true;
}
#endif

View File

@ -0,0 +1,123 @@
/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2009, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: Debugger Utility Range
*
* Author: Copyright (C) 2006-2009 Michael Pohoreski
*/
#include "StdAfx.h"
// Util - Range _______________________________________________________________
//===========================================================================
bool Range_CalcEndLen( const RangeType_t eRange
, const WORD & nAddress1, const WORD & nAddress2
, WORD & nAddressEnd_, int & nAddressLen_ )
{
bool bValid = false;
if (eRange == RANGE_HAS_LEN)
{
// BSAVE 2000,0 Len=0 End=n/a
// BSAVE 2000,1 Len=1 End=2000
// 0,FFFF [,)
// End = FFFE = Len-1
// Len = FFFF
nAddressLen_ = nAddress2;
unsigned int nTemp = nAddress1 + nAddressLen_ - 1;
if (nTemp > _6502_MEM_END)
nTemp = _6502_MEM_END;
nAddressEnd_ = nTemp;
bValid = true;
}
else
if (eRange == RANGE_HAS_END)
{
// BSAVE 2000:2000 Len=0, End=n/a
// BSAVE 2000:2001 Len=1, End=2000
// 0:FFFF [,]
// End = FFFF
// Len = 10000 = End+1
nAddressEnd_ = nAddress2;
nAddressLen_ = nAddress2 - nAddress1 + 1;
bValid = true;
}
return bValid;
}
//===========================================================================
RangeType_t Range_Get( WORD & nAddress1_, WORD & nAddress2_, const int iArg ) // =1
{
nAddress1_ = (unsigned) g_aArgs[ iArg ].nValue;
if (nAddress1_ > _6502_MEM_END)
nAddress1_ = _6502_MEM_END;
nAddress2_ = 0;
int nTemp = 0;
RangeType_t eRange = RANGE_MISSING_ARG_2;
if (g_aArgs[ iArg + 1 ].eToken == TOKEN_COMMA)
{
// 0,FFFF [,) // Note the mathematical range
// End = FFFE = Len-1
// Len = FFFF
eRange = RANGE_HAS_LEN;
nTemp = g_aArgs[ iArg + 2 ].nValue;
nAddress2_ = nTemp;
}
else
if (g_aArgs[ iArg + 1 ].eToken == TOKEN_COLON)
{
// 0:FFFF [,] // Note the mathematical range
// End = FFFF
// Len = 10000 = End+1
eRange = RANGE_HAS_END;
nTemp = g_aArgs[ iArg + 2 ].nValue;
// i.e.
// FFFF:D000
// 1 2 Temp
// FFFF D000
// FFFF
// D000
if (nAddress1_ > nTemp)
{
nAddress2_ = nAddress1_;
nAddress1_ = nTemp;
}
else
nAddress2_ = nTemp;
}
// .17 Bug Fix: D000,FFFF -> D000,CFFF (nothing searched!)
// if (nTemp > _6502_MEM_END)
// nTemp = _6502_MEM_END;
return eRange;
}

View File

@ -0,0 +1,4 @@
RangeType_t Range_Get( WORD & nAddress1_, WORD &nAddress2_, const int iArg = 1 );
bool Range_CalcEndLen( const RangeType_t eRange
, const WORD & nAddress1, const WORD & nAddress2
, WORD & nAddressEnd_, int & nAddressLen_ );

View File

@ -0,0 +1,862 @@
#include "StdAfx.h"
// 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]
unsigned 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;
}

View 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 );

File diff suppressed because it is too large Load Diff