mirror of
https://github.com/AppleWin/AppleWin.git
synced 2025-01-11 05:29:55 +00:00
debugger source cleanup -> moved 'source/debugger'
This commit is contained in:
parent
c946cb00bb
commit
b9a2c7cd5f
8965
AppleWin/source/Debugger/Debug.cpp
Normal file
8965
AppleWin/source/Debugger/Debug.cpp
Normal file
File diff suppressed because it is too large
Load Diff
192
AppleWin/source/Debugger/Debug.h
Normal file
192
AppleWin/source/Debugger/Debug.h
Normal 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 );
|
||||||
|
|
1361
AppleWin/source/Debugger/Debugger_Assembler.cpp
Normal file
1361
AppleWin/source/Debugger/Debugger_Assembler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
180
AppleWin/source/Debugger/Debugger_Assembler.h
Normal file
180
AppleWin/source/Debugger/Debugger_Assembler.h
Normal 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
|
625
AppleWin/source/Debugger/Debugger_Console.cpp
Normal file
625
AppleWin/source/Debugger/Debugger_Console.cpp
Normal 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 );
|
||||||
|
}
|
256
AppleWin/source/Debugger/Debugger_Console.h
Normal file
256
AppleWin/source/Debugger/Debugger_Console.h
Normal 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
|
367
AppleWin/source/Debugger/Debugger_DisassemblerData.cpp
Normal file
367
AppleWin/source/Debugger/Debugger_DisassemblerData.cpp
Normal 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( );
|
||||||
|
}
|
||||||
|
|
55
AppleWin/source/Debugger/Debugger_DisassemblerData.h
Normal file
55
AppleWin/source/Debugger/Debugger_DisassemblerData.h
Normal 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
|
3383
AppleWin/source/Debugger/Debugger_Display.cpp
Normal file
3383
AppleWin/source/Debugger/Debugger_Display.cpp
Normal file
File diff suppressed because it is too large
Load Diff
96
AppleWin/source/Debugger/Debugger_Display.h
Normal file
96
AppleWin/source/Debugger/Debugger_Display.h
Normal 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
|
1552
AppleWin/source/Debugger/Debugger_Help.cpp
Normal file
1552
AppleWin/source/Debugger/Debugger_Help.cpp
Normal file
File diff suppressed because it is too large
Load Diff
33
AppleWin/source/Debugger/Debugger_Help.h
Normal file
33
AppleWin/source/Debugger/Debugger_Help.h
Normal 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
|
1060
AppleWin/source/Debugger/Debugger_Parser.cpp
Normal file
1060
AppleWin/source/Debugger/Debugger_Parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
240
AppleWin/source/Debugger/Debugger_Parser.h
Normal file
240
AppleWin/source/Debugger/Debugger_Parser.h
Normal 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
|
123
AppleWin/source/Debugger/Debugger_Range.cpp
Normal file
123
AppleWin/source/Debugger/Debugger_Range.cpp
Normal 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;
|
||||||
|
}
|
4
AppleWin/source/Debugger/Debugger_Range.h
Normal file
4
AppleWin/source/Debugger/Debugger_Range.h
Normal 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_ );
|
862
AppleWin/source/Debugger/Debugger_Symbols.cpp
Normal file
862
AppleWin/source/Debugger/Debugger_Symbols.cpp
Normal 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;
|
||||||
|
}
|
17
AppleWin/source/Debugger/Debugger_Symbols.h
Normal file
17
AppleWin/source/Debugger/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 );
|
||||||
|
|
1579
AppleWin/source/Debugger/Debugger_Types.h
Normal file
1579
AppleWin/source/Debugger/Debugger_Types.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user