diff --git a/docs/Debugger_Changelog.txt b/docs/Debugger_Changelog.txt index b2ca5a724..3e1db1aa2 100644 --- a/docs/Debugger_Changelog.txt +++ b/docs/Debugger_Changelog.txt @@ -1,5 +1,39 @@ /* - +2.9.1.13 Added: CD now detects ".." to change to the previous directory and chops the trailing sub-directory from the current path. + It worked before but would clutter up the current directory with a trailing "..\". +2.9.1.12 Added: New commands HGR0, HGR3, HGR4, HGR5 to see pseudo pages $00, $60, $80, $A0 respectively. +2.9.1.11 Fixed: Right justify signed decimal values. + Example: + U 300 + 300:A9 80 A9 81 A9 FF A9 00 A9 01 A9 7E A9 7F + Will display as: + LDA #$80 #-128 + LDA #$81 #-127 + LDA #$FF #-1 + LDA #$00 + LDA #$01 #+1 + LDA #$7E #+126 + LDA #$7F #+127 +2.9.1.10 Fixed: Immedate #80 was not showing -128 for the signed decimal value. +2.9.1.9 Fixed: Immediate #0 was showing '#' prefix but not showing zero for the signed decimal value. Changed to show the signed decimal value only if non zero. +2.9.1.8 Changed: Disassembly window now lists symbol labels and symbol target address from User2 in orange. + Example: + U 300 + SYM @ = 303 + 300: 20 03 03 +2.9.1.7 Added: Extended SYM command to auto-generate symbol names when reverse engineering. NOTE: These symbols will be placed in User2. + Example: + SYM @ = 800 // Alias for: SYM _0800 = 0800 +2.9.1.6 Added: Branch instructions now show target address. +2.9.1.5 Added: Disassembly window now shows signed decimal values for immediate values. +2.9.1.4 Changed: Show symbol warnings in Orange, and length of symbols in light blue. +2.9.1.3 Added: DB commanoptionally supports = + DB HGR = 2000:3FFF +2.9.1.2 Fixed: Off by one end address when deleting DisasmData_t +2.9.1.1 Added: X command now supports a range and will chop off the appropiate data sections. + DB 2000:2005 + X 2002:2003 +Released post 1.30.7.0 2.9.1.0 Added: Bookmarks now have their own indicator (a number with a box around it) and replace the ":" seperator. Updated Debug_Font.bmp diff --git a/source/Debugger/Debug.cpp b/source/Debugger/Debug.cpp index 1a08edca1..f898751cb 100644 --- a/source/Debugger/Debug.cpp +++ b/source/Debugger/Debug.cpp @@ -51,7 +51,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define ALLOW_INPUT_LOWERCASE 1 // See /docs/Debugger_Changelog.txt for full details - const int DEBUGGER_VERSION = MAKE_VERSION(2,9,1,0); + const int DEBUGGER_VERSION = MAKE_VERSION(2,9,1,13); // Public _________________________________________________________________________________________ @@ -3745,7 +3745,10 @@ Update_t CmdConfigGetDebugDir (int nArgs) return ConsoleUpdate(); } -// "CD" +// Usage: +// CD "" +// CD ".." +// Note: Subdirectory MUST be quoted with double quotes. //=========================================================================== Update_t CmdConfigSetDebugDir (int nArgs) { @@ -3780,8 +3783,71 @@ Update_t CmdConfigSetDebugDir (int nArgs) } else // Relative { - // TODO: Support ".." - currently just appends (which still works) - sPath = g_sCurrentDir + g_aArgs[1].sArg; // TODO: debugger dir has no ` CONSOLE_COLOR_ESCAPE_CHAR ?!?! + std::string SAME_DIR( "." ); SAME_DIR += PATH_SEPARATOR; + std::string UP_DIR ( ".."); UP_DIR += PATH_SEPARATOR; + std::string sNewPath( g_aArgs[1].sArg ); + + // if new path doesn't have a trailing slash, append one + if (*(sNewPath.rbegin()) != PATH_SEPARATOR) + sNewPath += PATH_SEPARATOR; + + // Support ".." and various permutations + // cd "..\" + // cd "abc\..\def\" + // + // 1. find next slash in newpath + // 2. subdir = newpath.substr() + // 3. if subdir == "..\" + // reverse find slash in g_sCurrentDir + // g_sCurrentDir = g_sCurrentDir.substr() + // else + // g_sCurrentDir += subdir + size_t iPrevSeparator = 0; + size_t iPathSeparator = 0; + + while ((iPathSeparator = sNewPath.find( PATH_SEPARATOR, iPrevSeparator )) != std::string::npos) + { +#if _DEBUG + char zDebug[128]; + sprintf( zDebug, "Prev: %d\n", iPrevSeparator ); OutputDebugStringA( zDebug ); + sprintf( zDebug, "Next: %d\n", iPathSeparator ); OutputDebugStringA( zDebug ); + sprintf( zDebug, "%s\n", sNewPath.c_str() ); OutputDebugStringA( zDebug ); + sprintf( zDebug, "%*s%s\n", iPathSeparator, "", "^"); OutputDebugStringA( zDebug ); +#endif + + std::string sSubDir = sNewPath.substr( iPrevSeparator, iPathSeparator - iPrevSeparator + 1 ); + const size_t nSubDirLen = sSubDir.size(); + + if ((nSubDirLen == 2) && (sSubDir == SAME_DIR)) // Same directory ".\" in the subpath? + { + // Intentional: Nothing to do + } + else + if ((nSubDirLen == 3) && (sSubDir == UP_DIR)) // Up directory "..\" in the subpath? + { + size_t nCurrentLen = g_sCurrentDir.size(); + size_t nLastSeperator = g_sCurrentDir.rfind( '\\', nCurrentLen - 2 ); + + if (nLastSeperator != std::string::npos) + { +#if _DEBUG + sprintf( zDebug, "Last: %d\n", nLastSeperator ); OutputDebugStringA( zDebug ); + sprintf( zDebug, "%s\n", g_sCurrentDir.c_str() ); OutputDebugStringA( zDebug ); + sprintf( zDebug, "%*s%s\n", nLastSeperator, "", "^"); OutputDebugStringA( zDebug ); +#endif + std::string sCurrentDir = g_sCurrentDir.substr( 0, nLastSeperator + 1 ); // Path always has trailing slash so include it + g_sCurrentDir = sCurrentDir; + } + } + else + g_sCurrentDir += sSubDir; + + iPathSeparator++; // start next search past path separator + iPrevSeparator = iPathSeparator; + } + + // TODO: debugger dir has no ` CONSOLE_COLOR_ESCAPE_CHAR ?!?! + sPath = g_sCurrentDir; } if ( SetCurrentImageDir( sPath ) ) @@ -6470,8 +6536,12 @@ Update_t CmdCyclesReset(int /*nArgs*/) enum ViewVideoPage_t { VIEW_PAGE_X, // current page + VIEW_PAGE_0, // Pseudo VIEW_PAGE_1, - VIEW_PAGE_2 + VIEW_PAGE_2, + VIEW_PAGE_3, // Pseudo + VIEW_PAGE_4, // Pseudo + VIEW_PAGE_5 // Pseudo }; Update_t _ViewOutput( ViewVideoPage_t iPage, int bVideoModeFlags ) @@ -6482,8 +6552,12 @@ Update_t _ViewOutput( ViewVideoPage_t iPage, int bVideoModeFlags ) bVideoModeFlags |= !GetVideo().VideoGetSWPAGE2() ? 0 : VF_PAGE2; bVideoModeFlags |= !GetVideo().VideoGetSWMIXED() ? 0 : VF_MIXED; break; // Page Current & current MIXED state - case VIEW_PAGE_1: bVideoModeFlags |= 0; break; // Page 1 - case VIEW_PAGE_2: bVideoModeFlags |= VF_PAGE2; break; // Page 2 + case VIEW_PAGE_0: bVideoModeFlags |= VF_PAGE0; break; // Pseudo Page 0 ($0000) + case VIEW_PAGE_1: bVideoModeFlags |= 0 ; break; // Hardware Page 1 ($2000), NOTE: VF_HIRES will be passed in + case VIEW_PAGE_2: bVideoModeFlags |= VF_PAGE2; break; // Hardware Page 2 ($4000) + case VIEW_PAGE_3: bVideoModeFlags |= VF_PAGE3; break; // Pseudo Page 3 ($6000) + case VIEW_PAGE_4: bVideoModeFlags |= VF_PAGE4; break; // Pseudo Page 4 ($8000) + case VIEW_PAGE_5: bVideoModeFlags |= VF_PAGE5; break; // Pseudo Page 5 ($A000) default: _ASSERT(0); break; @@ -6551,6 +6625,10 @@ Update_t _ViewOutput( ViewVideoPage_t iPage, int bVideoModeFlags ) { return _ViewOutput( VIEW_PAGE_X, VF_HIRES ); } + Update_t CmdViewOutput_HGR0 (int nArgs) + { + return _ViewOutput( VIEW_PAGE_0, VF_HIRES ); // Pseudo page ($0000) + } Update_t CmdViewOutput_HGR1 (int nArgs) { return _ViewOutput( VIEW_PAGE_1, VF_HIRES ); @@ -6559,6 +6637,18 @@ Update_t _ViewOutput( ViewVideoPage_t iPage, int bVideoModeFlags ) { return _ViewOutput( VIEW_PAGE_2, VF_HIRES ); } + Update_t CmdViewOutput_HGR3 (int nArgs) + { + return _ViewOutput( VIEW_PAGE_3, VF_HIRES ); // Pseudo page ($6000) + } + Update_t CmdViewOutput_HGR4 (int nArgs) + { + return _ViewOutput( VIEW_PAGE_4, VF_HIRES ); // Pseudo page ($8000) + } + Update_t CmdViewOutput_HGR5 (int nArgs) + { + return _ViewOutput( VIEW_PAGE_5, VF_HIRES ); // Pseudo page ($A000) + } // Double Hi-Res Update_t CmdViewOutput_DHGRX (int nArgs) { diff --git a/source/Debugger/Debugger_Color.cpp b/source/Debugger/Debugger_Color.cpp index 2ef90c117..3db6714b1 100644 --- a/source/Debugger/Debugger_Color.cpp +++ b/source/Debugger/Debugger_Color.cpp @@ -95,6 +95,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA G8, // FG_DISASM_SYMBOL C8, // FG_DISASM_CHAR G8, // FG_DISASM_BRANCH + COLOR_CUSTOM_01, // FG_DISASM_SINT8 C3, // BG_INFO (C4, C2 too dark) C3, // BG_INFO_WATCH diff --git a/source/Debugger/Debugger_Color.h b/source/Debugger/Debugger_Color.h index 22a1757c5..9cef06cfd 100644 --- a/source/Debugger/Debugger_Color.h +++ b/source/Debugger/Debugger_Color.h @@ -89,6 +89,7 @@ /*ZZZ*/ , FG_DISASM_SYMBOL // Green HOME , FG_DISASM_CHAR // Cyan 'c' , FG_DISASM_BRANCH // Green ^ = v + , FG_DISASM_SINT8 // Lite Blue , BG_INFO // Cyan Regs/Stack/BP/Watch/ZP , BG_INFO_WATCH // Cyan diff --git a/source/Debugger/Debugger_Commands.cpp b/source/Debugger/Debugger_Commands.cpp index a880128bf..abd55a8e0 100644 --- a/source/Debugger/Debugger_Commands.cpp +++ b/source/Debugger/Debugger_Commands.cpp @@ -262,8 +262,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA {TEXT("DGR1") , CmdViewOutput_DGR1 , CMD_VIEW_DGR1 , "View Double lo-res Page 1" }, {TEXT("DGR2") , CmdViewOutput_DGR2 , CMD_VIEW_DGR2 , "View Double lo-res Page 2" }, {TEXT("HGR") , CmdViewOutput_HGRX , CMD_VIEW_HGRX , "View Hi-res (current page)" }, - {TEXT("HGR1") , CmdViewOutput_HGR1 , CMD_VIEW_HGR1 , "View Hi-res Page 1" }, - {TEXT("HGR2") , CmdViewOutput_HGR2 , CMD_VIEW_HGR2 , "View Hi-res Page 2" }, + {TEXT("HGR0") , CmdViewOutput_HGR0 , CMD_VIEW_HGR0 , "View pseudo Hi-res Page 0 ($0000)" }, + {TEXT("HGR1") , CmdViewOutput_HGR1 , CMD_VIEW_HGR1 , "View Hi-res Page 1 ($2000)" }, + {TEXT("HGR2") , CmdViewOutput_HGR2 , CMD_VIEW_HGR2 , "View Hi-res Page 2 ($4000)" }, + {TEXT("HGR3") , CmdViewOutput_HGR3 , CMD_VIEW_HGR3 , "View pseudo Hi-res Page 3 ($6000)" }, + {TEXT("HGR4") , CmdViewOutput_HGR4 , CMD_VIEW_HGR4 , "View pseudo Hi-res Page 4 ($8000)" }, + {TEXT("HGR5") , CmdViewOutput_HGR5 , CMD_VIEW_HGR5 , "View pseudo Hi-res Page 5 ($A000)" }, {TEXT("DHGR") , CmdViewOutput_DHGRX , CMD_VIEW_DHGRX , "View Double Hi-res (current page)" }, {TEXT("DHGR1") , CmdViewOutput_DHGR1 , CMD_VIEW_DHGR1 , "View Double Hi-res Page 1" }, {TEXT("DHGR2") , CmdViewOutput_DHGR2 , CMD_VIEW_DHGR2 , "View Double Hi-res Page 2" }, diff --git a/source/Debugger/Debugger_Console.h b/source/Debugger/Debugger_Console.h index 4f4e193bf..2ac3e4d49 100644 --- a/source/Debugger/Debugger_Console.h +++ b/source/Debugger/Debugger_Console.h @@ -68,12 +68,12 @@ #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 (_SearchMemoryDisplay), S D000:FFFF A9 00, PROFILE, HELP BP + #define CHC_NUM_DEC "`:" // Lite Blue looks better then yellow (_SearchMemoryDisplay), S D000:FFFF A9 00, PROFILE, HELP BP #define CHC_NUM_HEX "`3" #define CHC_SYMBOL "`2" // Symbols #define CHC_ADDRESS "`8" // Hex Address #define CHC_ERROR "`1" // Red - #define CHC_WARNING "`5" // Purple + #define CHC_WARNING "`8" // Orange #define CHC_INFO "`3" // Yellow #define CHC_STRING "`6" // #define CHC_EXAMPLE "`:" diff --git a/source/Debugger/Debugger_Disassembler.cpp b/source/Debugger/Debugger_Disassembler.cpp index 8649ac09f..52da8652f 100644 --- a/source/Debugger/Debugger_Disassembler.cpp +++ b/source/Debugger/Debugger_Disassembler.cpp @@ -243,41 +243,39 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_) bDisasmFormatFlags |= DISASM_FORMAT_BRANCH; if (nTarget < nBaseAddress) - { sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorUp[g_iConfigDisasmBranchType]); - } else - if (nTarget > nBaseAddress) - { - sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorDown[g_iConfigDisasmBranchType]); - } - else - { - sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorEqual[g_iConfigDisasmBranchType]); - } + if (nTarget > nBaseAddress) + sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorDown[g_iConfigDisasmBranchType]); + else + sprintf(line_.sBranch, "%s", g_sConfigBranchIndicatorEqual[g_iConfigDisasmBranchType]); + + bDisasmFormatFlags |= DISASM_FORMAT_TARGET_POINTER; + if (g_iConfigDisasmTargets & DISASM_TARGET_ADDR) + sprintf(line_.sTargetPointer, "%04X", nTarget & 0xFFFF); } // intentional re-test AM_R ... -// if ((iOpmode >= AM_A) && (iOpmode <= AM_NA)) - if ((iOpmode == AM_A) || // Absolute - (iOpmode == AM_Z) || // Zeropage - (iOpmode == AM_AX) || // Absolute, X - (iOpmode == AM_AY) || // Absolute, Y - (iOpmode == AM_ZX) || // Zeropage, X - (iOpmode == AM_ZY) || // Zeropage, Y - (iOpmode == AM_R) || // Relative +// if ((iOpmode >= AM_A ) && (iOpmode <= AM_NA)) + if ((iOpmode == AM_A ) || // Absolute + (iOpmode == AM_Z ) || // Zeropage + (iOpmode == AM_AX ) || // Absolute, X + (iOpmode == AM_AY ) || // Absolute, Y + (iOpmode == AM_ZX ) || // Zeropage, X + (iOpmode == AM_ZY ) || // Zeropage, Y + (iOpmode == AM_R ) || // Relative (iOpmode == AM_IZX) || // Indexed (Zeropage Indirect, X) (iOpmode == AM_IAX) || // Indexed (Absolute Indirect, X) (iOpmode == AM_NZY) || // Indirect (Zeropage) Index, Y - (iOpmode == AM_NZ) || // Indirect (Zeropage) - (iOpmode == AM_NA)) //(Indirect Absolute) + (iOpmode == AM_NZ ) || // Indirect (Zeropage) + (iOpmode == AM_NA )) //(Indirect Absolute) { line_.nTarget = nTarget; const char* pTarget = NULL; const char* pSymbol = 0; - pSymbol = FindSymbolFromAddress(nTarget); + pSymbol = FindSymbolFromAddress(nTarget, &line_.iTargetTable); // Data Assembler if (pData && (!pData->bSymbolLookup)) @@ -292,7 +290,7 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_) if (!(bDisasmFormatFlags & DISASM_FORMAT_SYMBOL)) { - pSymbol = FindSymbolFromAddress(nTarget - 1); + pSymbol = FindSymbolFromAddress(nTarget - 1, &line_.iTargetTable); if (pSymbol) { bDisasmFormatFlags |= DISASM_FORMAT_SYMBOL; @@ -314,7 +312,7 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_) // nSecondTarget = g_bDebugConfig_DisasmMatchSymbolOffsetMinus1First ? nTarget+1 : nTarget-1; if (!(bDisasmFormatFlags & DISASM_FORMAT_SYMBOL) || pData) { - pSymbol = FindSymbolFromAddress(nTarget + 1); + pSymbol = FindSymbolFromAddress(nTarget + 1,&line_.iTargetTable); if (pSymbol) { bDisasmFormatFlags |= DISASM_FORMAT_SYMBOL; @@ -390,22 +388,28 @@ int GetDisassemblyLine(WORD nBaseAddress, DisasmLine_t& line_) if (iOpmode == AM_M) { // sprintf( sTarget, g_aOpmodes[ iOpmode ]._sFormat, (unsigned)nTarget ); - sprintf(line_.sTarget, "%02X", (unsigned)nTarget); + sprintf(line_.sTarget , "%02X", (unsigned)nTarget); - if (iOpmode == AM_M) - { - bDisasmFormatFlags |= DISASM_FORMAT_CHAR; - line_.nImmediate = (BYTE)nTarget; - unsigned _char = FormatCharTxtCtrl(FormatCharTxtHigh(line_.nImmediate, NULL), NULL); + if (nTarget == 0) + line_.sImmediateSignedDec[0] = 0; // nothing + else + if (nTarget < 128) + sprintf(line_.sImmediateSignedDec, "+%d" , nTarget ); + else + if (nTarget >= 128) + sprintf(line_.sImmediateSignedDec, "-%d" , (~nTarget + 1) & 0xFF ); - sprintf(line_.sImmediate, "%c", _char); + bDisasmFormatFlags |= DISASM_FORMAT_CHAR; + line_.nImmediate = (BYTE)nTarget; + unsigned _char = FormatCharTxtCtrl(FormatCharTxtHigh(line_.nImmediate, NULL), NULL); + + sprintf(line_.sImmediate, "%c", _char); #if OLD_CONSOLE_COLOR - if (ConsoleColorIsEscapeMeta(_char)) - sprintf(line_.sImmediate, "%c%c", _char, _char); - else - sprintf(line_.sImmediate, "%c", _char); + if (ConsoleColorIsEscapeMeta(_char)) + sprintf(line_.sImmediate, "%c%c", _char, _char); + else + sprintf(line_.sImmediate, "%c", _char); #endif - } } } diff --git a/source/Debugger/Debugger_DisassemblerData.cpp b/source/Debugger/Debugger_DisassemblerData.cpp index 24cec4754..011530ec8 100644 --- a/source/Debugger/Debugger_DisassemblerData.cpp +++ b/source/Debugger/Debugger_DisassemblerData.cpp @@ -32,8 +32,38 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // __ Debugger Interface ____________________________________________________________________________ +void _GetAutoSymbolName ( const Nopcode_e &nopcode, const WORD nStartAddress, char *pSymbolName ) +{ + switch (nopcode) + { + case NOP_ADDRESS: + sprintf( pSymbolName, "A_%04X", nStartAddress ); // DA range + break; + + case NOP_STRING_ASCII: + case NOP_STRING_APPLE: + sprintf( pSymbolName, "T_%04X", nStartAddress ); // ASC range + break; + + case NOP_WORD_1: + case NOP_WORD_2: + case NOP_WORD_4: + sprintf( pSymbolName, "W_%04X", nStartAddress ); // DW range + break; + + case NOP_BYTE_1: + case NOP_BYTE_2: + case NOP_BYTE_4: + case NOP_BYTE_8: + default: + sprintf( pSymbolName, "B_%04X", nStartAddress ); // DB range + break; + } +} + +// @param tData_ Filled out with range data //=========================================================================== -WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) +WORD _GetDataRange (int nArgs, int iArg, DisasmData_t& tData_) { WORD nAddress = 0; WORD nAddress2 = 0; @@ -46,12 +76,14 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) // DB symbol // bool bisAddress ... - if( nArgs < 1 ) + if (nArgs < 1) { nAddress = g_nDisasmCurAddress; } else { + // DB foo = 300 // nArgs == 3 + RangeType_t eRange = Range_Get( nAddress, nAddress2, iArg); if ((eRange == RANGE_HAS_END) || (eRange == RANGE_HAS_LEN)) @@ -61,8 +93,16 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) } else { - if( nArgs > 1 ) - nAddress = g_aArgs[ 2 ].nValue; + if (nArgs > 1) + { + // 2.9.1.1 Add: Support for equal sign, also make it optional for command DB + // DB FOO 300 + // DB FOO = 300 + if (g_aArgs[2].bType == TOKEN_EQUAL) + nAddress = g_aArgs[ 3 ].nValue; + else + nAddress = g_aArgs[ 2 ].nValue; + } else nAddress = g_aArgs[ 1 ].nValue; } @@ -78,10 +118,23 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) tData_.nStartAddress = nAddress; tData_.nEndAddress = nAddress + nLen; -// tData_.nArraySize = 0; + + return nAddress; +} + +//=========================================================================== +WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) +{ + WORD nAddress = 0; + WORD nAddress2 = 0; + WORD nEnd = 0; + int nLen = 0; + + nAddress = _GetDataRange(nArgs,iArg,tData_); const char *pSymbolName = ""; char aSymbolName[ MAX_SYMBOLS_LEN+1 ]; + SymbolTable_Index_e eSymbolTable = SYMBOLS_ASSEMBLY; bool bAutoDefineName = false; // 2.7.0.34 @@ -108,20 +161,27 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) // DB 801 if( bAutoDefineName ) { - if( g_iCommand == CMD_DEFINE_DATA_STR ) - sprintf( aSymbolName, "T_%04X", tData_.nStartAddress ); // ASC range - else - if( g_iCommand == CMD_DEFINE_DATA_WORD1 ) - sprintf( aSymbolName, "W_%04X", tData_.nStartAddress ); // DW range - else - sprintf( aSymbolName, "B_%04X", tData_.nStartAddress ); // DB range + Nopcode_e nopcode = NOP_BYTE_1; + bool isString = (g_iCommand == CMD_DEFINE_DATA_STR); + if( isString ) + nopcode = NOP_STRING_ASCII; + + bool isWord1 = (g_iCommand == CMD_DEFINE_DATA_WORD1); + if( isWord1 ) + nopcode = NOP_WORD_1; + + bool isAddr = (g_iCommand == CMD_DEFINE_ADDR_WORD); + if( isAddr ) + nopcode = NOP_ADDRESS; + + _GetAutoSymbolName( nopcode, tData_.nStartAddress , aSymbolName ); pSymbolName = aSymbolName; } // bRemoveSymbol = false // use arg[2] // bUpdateSymbol = true // add the symbol to the table - SymbolUpdate( eSymbolTable, pSymbolName, nAddress, false, true ); + SymbolUpdate( eSymbolTable, pSymbolName, nAddress, false, true ); // TODO: Note: need to call ConsoleUpdate(), as may print symbol has been updated @@ -131,18 +191,38 @@ WORD _CmdDefineByteRange(int nArgs,int iArg,DisasmData_t & tData_) } // Undefine Data +// +// X +// X addr +// X addr:addr +// +// Example: +// DB hgr 2000:3FFF +// U 1FFF +// X 1FFF:2001 //=========================================================================== Update_t CmdDisasmDataDefCode (int nArgs) { // treat memory (bytes) as code - if (! ((nArgs <= 2) || (nArgs == 4))) + if (! ((nArgs <= 2) || (nArgs == 4)) && (nArgs != 3)) { return Help_Arg_1( CMD_DISASM_CODE ); } - DisasmData_t tData; - int iArg = 2; - WORD nAddress = _CmdDefineByteRange( nArgs, iArg, tData ); + DisasmData_t tData; // X 1FFF:2001 + WORD nAddress = 0; // 8191 + int iArg = 0; + + if (nArgs == 3) + { + iArg = 1; // #### : #### + nAddress = _GetDataRange( nArgs, iArg, tData ); + } + else + { + iArg = 2; + nAddress = _GetDataRange( nArgs, iArg, tData ); + } // Need to iterate through all blocks // DB TEST1 300:320 @@ -150,18 +230,72 @@ Update_t CmdDisasmDataDefCode (int nArgs) // DB TEST3 320:340 // X TEST1 - DisasmData_t *pData = Disassembly_IsDataAddress( nAddress ); - if( pData ) + /* + // Edge cases: + U 1FFF + DB 2000:2005 + X 1FFF:2001 // Chop 2 head + X 2004:2006 // Chop 2 tail + X 1FFF:2006 // Chop entire + + U 1FFF + DB 2000:2000 + X 2000:2000 // Chop entire + + U 1FFF + DB 2000:2002 + X 2001:2001 // Chop middle + + U 1FFF + DB 2000:2005 + X 2002:2003 // Chop middle + */ + while (nAddress <= tData.nEndAddress) { - // TODO: Do we need to split the data !? - //Disassembly_DelData( tData ); - pData->iDirective = _NOP_REMOVED; + DisasmData_t *pData = Disassembly_IsDataAddress( nAddress ); + if( pData ) + { + if (( nAddress <= pData->nStartAddress) + && (tData.nEndAddress >= pData->nEndAddress )) + { + // remove entire + Disassembly_DelData( *pData ); + } + else + if (( nAddress <= pData->nStartAddress) + && (tData.nStartAddress < pData->nEndAddress )) + { + // head + pData->nStartAddress = nAddress+1; + } + else + if (( nAddress > pData->nStartAddress) + && (tData.nEndAddress >= pData->nEndAddress )) + { + // tail + pData->nEndAddress = nAddress-1; + } + else + { + // middle + SymbolTable_Index_e eSymbolTable = SYMBOLS_ASSEMBLY; - // TODO: Remove symbol 'D_FA62' from symbol table! - } - else - { - Disassembly_DelData( tData ); + DisasmData_t tSplit = *pData; + pData->nEndAddress = nAddress - 1; + + const char *pSymbolName = tSplit.sSymbol; + + tSplit.nStartAddress = tData.nEndAddress + 1; // nAddress + 1; + _GetAutoSymbolName( pData->eElementType, tSplit.nStartAddress, tSplit.sSymbol ); + + SymbolUpdate( eSymbolTable, pSymbolName, tSplit.nStartAddress, false, true ); + Disassembly_AddData( tSplit ); + } + + // TODO: Remove symbol 'D_FA62' from symbol table! + } + + nAddress++; } return UPDATE_DISASM | ConsoleUpdate(); @@ -545,9 +679,11 @@ void Disassembly_DelData( DisasmData_t tData) { if (pData->iDirective != _NOP_REMOVED) { - if ((nAddress >= pData->nStartAddress) && (nAddress < pData->nEndAddress)) + if ((nAddress >= pData->nStartAddress) && (nAddress <= pData->nEndAddress)) { pData->iDirective = _NOP_REMOVED; + + // TODO: delete from vector? } } pData++; diff --git a/source/Debugger/Debugger_Display.cpp b/source/Debugger/Debugger_Display.cpp index 31478f5d5..eee3d5c0a 100644 --- a/source/Debugger/Debugger_Display.cpp +++ b/source/Debugger/Debugger_Display.cpp @@ -1330,7 +1330,9 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress ) int iOpmode; int nOpbyte; DisasmLine_t line; - const char* pSymbol = FindSymbolFromAddress( nBaseAddress ); + + int iTable = NUM_SYMBOL_TABLES; + const char* pSymbol = FindSymbolFromAddress( nBaseAddress, &iTable ); const char* pMnemonic = NULL; // Data Disassembler @@ -1367,9 +1369,7 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress ) // int X_BRANCH = 46 * nDefaultFontWidth; float aTabs[ _NUM_TAB_STOPS ] = -// { 6, 16, 26, 41, 46, 49 }; // 6, 17, 26, 40, 46 #if USE_APPLE_FONT -// { 5, 14, 20, 40, 46, 49 }; // xxxx:xx xx xx LABELxxxxxx MNEMONIC 'E' = // 0 45 14 26 { 5, 14, 26, 41, 48, 49 }; @@ -1515,7 +1515,7 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress ) } - // Address Seperator + // Address Seperator if (! bCursorLine) DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_OPERATOR ) ); @@ -1557,7 +1557,12 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress ) if (pSymbol) { if (! bCursorLine) - DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) ); + { + if (iTable == SYMBOLS_USER_2) + DebuggerSetColorFG( DebuggerGetColor( FG_INFO_ADDRESS ) ); // Show user symbols 2 in different color for organization when reverse engineering. Table 1 = known, Table 2 = unknown. + else + DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) ); + } PrintTextCursorX( pSymbol, linerect ); } @@ -1606,7 +1611,10 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress ) { if (bDisasmFormatFlags & DISASM_FORMAT_SYMBOL) { - DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) ); + if (line.iTargetTable == SYMBOLS_USER_2) + DebuggerSetColorFG( DebuggerGetColor( FG_INFO_ADDRESS ) ); // Show user symbols 2 in different color for organization when reverse engineering. Table 1 = known, Table 2 = unknown. + else + DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SYMBOL ) ); } else { @@ -1782,6 +1790,29 @@ WORD DrawDisassemblyLine ( int iLine, const WORD nBaseAddress ) } } + // 2.9.1.4: Print decimal for immediate values + if (line.bTargetImmediate) + { + linerect.left = (int) aTabs[ TS_IMMEDIATE ]; + + if( line.nImmediate ) + { + /* + 300:A9 80 A9 81 A9 FF A9 00 A9 01 A9 7E A9 7F + */ + + // Right justify to target ADDR:## + size_t len = strlen( line.sImmediateSignedDec ); + linerect.left += (2 + (4 - len)) * nDefaultFontWidth; + + DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR )); + PrintTextCursorX( "#", linerect ); + + DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_SINT8 )); + PrintTextCursorX( line.sImmediateSignedDec, linerect); + } + } + // Immediate Char if (bDisasmFormatFlags & DISASM_FORMAT_CHAR) { diff --git a/source/Debugger/Debugger_Symbols.cpp b/source/Debugger/Debugger_Symbols.cpp index 636a5e617..5466f7273 100644 --- a/source/Debugger/Debugger_Symbols.cpp +++ b/source/Debugger/Debugger_Symbols.cpp @@ -140,11 +140,17 @@ int GetSymbolTableFromCommand() return (g_iCommand - CMD_SYMBOLS_ROM); } +// @param iTable_ Which symbol table the symbol is in if any. If none will be NUM_SYMBOL_TABLES //=========================================================================== const char* FindSymbolFromAddress (WORD nAddress, int * iTable_ ) { // Bugfix/User feature: User symbols should be searched first int iTable = NUM_SYMBOL_TABLES; + if (iTable_) + { + *iTable_ = iTable; + } + while (iTable-- > 0) { if (! g_aSymbols[iTable].size()) @@ -273,7 +279,7 @@ Update_t CmdSymbols (int nArgs) //=========================================================================== Update_t CmdSymbolsClear (int nArgs) { - SymbolTable_Index_e eSymbolTable = SYMBOLS_USER_1; + SymbolTable_Index_e eSymbolTable = SYMBOLS_USER_1; _CmdSymbolsClear( eSymbolTable ); return (UPDATE_DISASM | UPDATE_SYMBOLS); } @@ -648,12 +654,17 @@ int ParseSymbolTable(const std::string & pPathFileName, SymbolTable_Index_e eSym int nLen = strlen( sName ); if (nLen > nMaxLen) { - ConsolePrintFormat( sText, " %sWarn.: %s%s (%d > %d)" + ConsolePrintFormat( sText, " %sWarn.: %s%s %s(%s%d %s> %s%d%s)" , CHC_WARNING , CHC_SYMBOL , sName + , CHC_ARG_SEP + , CHC_NUM_DEC , nLen + , CHC_ARG_SEP + , CHC_NUM_DEC , nMaxLen + , CHC_ARG_SEP ); ConsoleUpdate(); // Flush buffered output so we don't ask the user to pause } @@ -898,25 +909,45 @@ void SymbolUpdate( SymbolTable_Index_e eSymbolTable, const char *pSymbolName, WO } } - +// Syntax: +// sym ! +// sym ~ +// sym = +// sym @ = +// NOTE: Listing of the symbols is handled via returning UPDATE_NOTHING which is triggered by: +// sym * //=========================================================================== 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)) ) + TCHAR *pSymbolName = g_aArgs[1].sArg; + WORD nAddress = g_aArgs[3].nValue; + + 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) + // 2.9.1.7 Added: QoL for automatic symbol names + if ((nArgs == 2) + && (g_aArgRaw[ 1 ].eToken == TOKEN_AT ) // NOTE: @ is parsed and evaluated and NOT in the cooked args + && (g_aArgs [ 1 ].eToken == TOKEN_EQUAL)) { - TCHAR *pSymbolName = g_aArgs[1].sArg; - WORD nAddress = g_aArgs[3].nValue; + if (bSymbolTables == SYMBOL_TABLE_USER_1) + bSymbolTables = SYMBOL_TABLE_USER_2; // Autogenerated symbol names go in table 2 for organization when reverse engineering. Table 1 = known, Table 2 = unknown. + + nAddress = g_aArgs[2].nValue; + sprintf( g_aArgs[1].sArg, "_%04X", nAddress ); // Autogenerated symbol name + bUpdateSymbol = true; + } + + if (bRemoveSymbol || bUpdateSymbol) + { int iTable = _GetSymbolTableFromFlag( bSymbolTables ); SymbolUpdate( (SymbolTable_Index_e) iTable, pSymbolName, nAddress, bRemoveSymbol, bUpdateSymbol ); return ConsoleUpdate(); diff --git a/source/Debugger/Debugger_Types.h b/source/Debugger/Debugger_Types.h index 3b42763d4..90a2a60e4 100644 --- a/source/Debugger/Debugger_Types.h +++ b/source/Debugger/Debugger_Types.h @@ -504,8 +504,12 @@ , CMD_VIEW_DGR1 , CMD_VIEW_DGR2 , CMD_VIEW_HGRX + , CMD_VIEW_HGR0 , CMD_VIEW_HGR1 , CMD_VIEW_HGR2 + , CMD_VIEW_HGR3 + , CMD_VIEW_HGR4 + , CMD_VIEW_HGR5 , CMD_VIEW_DHGRX , CMD_VIEW_DHGR1 , CMD_VIEW_DHGR2 @@ -766,8 +770,12 @@ Update_t CmdViewOutput_DGR2 (int nArgs); Update_t CmdViewOutput_HGRX (int nArgs); + Update_t CmdViewOutput_HGR0 (int nArgs); Update_t CmdViewOutput_HGR1 (int nArgs); Update_t CmdViewOutput_HGR2 (int nArgs); + Update_t CmdViewOutput_HGR3 (int nArgs); + Update_t CmdViewOutput_HGR4 (int nArgs); + Update_t CmdViewOutput_HGR5 (int nArgs); Update_t CmdViewOutput_DHGRX (int nArgs); Update_t CmdViewOutput_DHGR1 (int nArgs); Update_t CmdViewOutput_DHGR2 (int nArgs); @@ -844,20 +852,20 @@ enum Nopcode_e { _NOP_REMOVED - ,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 = 2 bytes (no symbol lookup) - ,NOP_WORD_2 // 2 words/line = 4 bytes - ,NOP_WORD_4 // 4 words/line = 8 bytes - ,NOP_ADDRESS// 1 word/line = 2 bytes (with symbol lookup) - ,NOP_HEX // hex string =16 bytes - ,NOP_CHAR // char string // TODO: FIXME: needed?? - ,NOP_STRING_ASCII // Low Ascii - ,NOP_STRING_APPLE // High Ascii + ,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 = 2 bytes (no symbol lookup) + ,NOP_WORD_2 // 2 words/line = 4 bytes + ,NOP_WORD_4 // 4 words/line = 8 bytes + ,NOP_ADDRESS // 1 word/line = 2 bytes (with symbol lookup) + ,NOP_HEX // hex string =16 bytes + ,NOP_CHAR // char string // TODO: FIXME: needed?? + ,NOP_STRING_ASCII // Low Ascii + ,NOP_STRING_APPLE // High Ascii ,NOP_STRING_APPLESOFT // Mixed Low/High - ,NOP_FAC + ,NOP_FAC // Applesoft Floating-Point Format (5 bytes), i.e. $F069 = 0x81490FDAA2 = pi/2 ,NOP_SPRITE ,NUM_NOPCODE_TYPES }; @@ -960,6 +968,9 @@ const DisasmData_t* pDisasmData; // If != NULL then bytes are marked up as data char sTargetValue [ CHARS_FOR_ADDRESS ]; // char sTargetAddress[ CHARS_FOR_ADDRESS ]; + int iTargetTable; // Which symbol table this appears in if any. See: SYMBOLS_USER_2, DrawDisassemblyLine(), GetDisassemblyLine(), FindSymbolFromAddress() + + char sImmediateSignedDec[ 6 ]; // "-128" .. "+127" char sImmediate[ 4 ]; // 'c' char nImmediate; char sBranch [ 4 ]; // ^ diff --git a/source/NTSC.cpp b/source/NTSC.cpp index 7db815110..eda0cc56f 100644 --- a/source/NTSC.cpp +++ b/source/NTSC.cpp @@ -780,16 +780,20 @@ inline void updateVideoScannerAddress() //=========================================================================== INLINE uint16_t getVideoScannerAddressTXT() { - return (g_aClockVertOffsetsTXT[g_nVideoClockVert/8] + - g_pHorzClockOffset [g_nVideoClockVert/64][g_nVideoClockHorz] + (g_nTextPage * 0x400)); + uint16_t nAddress = (g_aClockVertOffsetsTXT[g_nVideoClockVert/8] + + g_pHorzClockOffset [g_nVideoClockVert/64][g_nVideoClockHorz] + + (g_nTextPage * 0x400)); + return nAddress; } //=========================================================================== INLINE uint16_t getVideoScannerAddressHGR() { // NB. For both A2 and //e use APPLE_IIE_HORZ_CLOCK_OFFSET - see VideoGetScannerAddress() where only TEXT mode adds $1000 - return (g_aClockVertOffsetsHGR[g_nVideoClockVert ] + - APPLE_IIE_HORZ_CLOCK_OFFSET[g_nVideoClockVert/64][g_nVideoClockHorz] + (g_nHiresPage * 0x2000)); + uint16_t nAddress = (g_aClockVertOffsetsHGR[g_nVideoClockVert ] + + APPLE_IIE_HORZ_CLOCK_OFFSET[g_nVideoClockVert/64][g_nVideoClockHorz] + + (g_nHiresPage * 0x2000)); + return nAddress; } // Non-Inline _________________________________________________________ @@ -1910,6 +1914,26 @@ void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ ) } } + if( uVideoModeFlags & VF_PAGE0) // Pseudo page ($0000) + { + g_nHiresPage = 0; + } + + if( uVideoModeFlags & VF_PAGE3) // Pseudo page ($6000) + { + g_nHiresPage = 3; + } + + if( uVideoModeFlags & VF_PAGE4) // Pseudo page ($8000) + { + g_nHiresPage = 4; + } + + if( uVideoModeFlags & VF_PAGE5) // Pseudo page ($A000) + { + g_nHiresPage = 5; + } + if (GetVideo().GetVideoRefreshRate() == VR_50HZ && g_pVideoAddress) // GH#763 / NB. g_pVideoAddress==NULL when called via VideoResetState() { if (uVideoModeFlags & VF_TEXT) diff --git a/source/Utilities.cpp b/source/Utilities.cpp index f6d817ac6..b9296b2ac 100644 --- a/source/Utilities.cpp +++ b/source/Utilities.cpp @@ -295,8 +295,8 @@ void LoadConfiguration(bool loadImages) GetCardMgr().Insert(SLOT4, (SS_CARDTYPE)dwTmp); else if (slot == SLOT5 && REGLOAD(TEXT(REGVALUE_SLOT5), &dwTmp)) GetCardMgr().Insert(SLOT5, (SS_CARDTYPE)dwTmp); - else if (slot == SLOT7 && REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp)) - GetCardMgr().Insert(SLOT7, (SS_CARDTYPE)dwTmp); + else if (slot == SLOT7 && REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp) && dwTmp == 1) // GH#1015 + GetCardMgr().Insert(SLOT7, CT_GenericHDD); } } diff --git a/source/Video.h b/source/Video.h index ea930fed0..f88ec6c10 100644 --- a/source/Video.h +++ b/source/Video.h @@ -54,9 +54,13 @@ enum VideoFlag_e VF_HIRES = 0x00000004, VF_80STORE= 0x00000008, VF_MIXED = 0x00000010, - VF_PAGE2 = 0x00000020, + VF_PAGE2 = 0x00000020, // Text or Hires VF_TEXT = 0x00000040, - VF_SHR = 0x00000080 // For VidHD's support for IIgs SHR video modes + VF_SHR = 0x00000080, // For VidHD's support for IIgs SHR video modes + VF_PAGE0 = 0x00000100, // Pseudo Page $00 (Poorman's heatmap) + VF_PAGE3 = 0x00000200, // Pseudo Page $60 (Poorman's heatmap) + VF_PAGE4 = 0x00000400, // Pseudo Page $80 (Poorman's heatmap) + VF_PAGE5 = 0x00000800, // Pseudo Page $A0 (Poorman's heatmap) }; enum AppleFont_e