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