Debugger: Extend watches: 'WA <n> v' to show video scanner address & video data (aux and/or main or shr 4-byte)
This commit is contained in:
parent
4fc07b4a7a
commit
dfaaa2823e
|
@ -114,6 +114,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
"M", // Mem RW
|
"M", // Mem RW
|
||||||
"M", // Mem READ_ONLY
|
"M", // Mem READ_ONLY
|
||||||
"M", // Mem WRITE_ONLY
|
"M", // Mem WRITE_ONLY
|
||||||
|
// Watches
|
||||||
|
"M", // Memory
|
||||||
|
"V", // Video Scanner
|
||||||
// TODO: M0 ram bank 0, M1 aux ram ?
|
// TODO: M0 ram bank 0, M1 aux ram ?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6655,7 +6658,7 @@ Update_t CmdWatch (int nArgs)
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
Update_t CmdWatchAdd (int nArgs)
|
Update_t CmdWatchAdd (int nArgs)
|
||||||
{
|
{
|
||||||
// WA [adddress]
|
// WA [address]
|
||||||
// WA # address
|
// WA # address
|
||||||
if (! nArgs)
|
if (! nArgs)
|
||||||
{
|
{
|
||||||
|
@ -6673,6 +6676,18 @@ Update_t CmdWatchAdd (int nArgs)
|
||||||
bool bAdded = false;
|
bool bAdded = false;
|
||||||
for (; iArg <= nArgs; iArg++ )
|
for (; iArg <= nArgs; iArg++ )
|
||||||
{
|
{
|
||||||
|
if (g_aArgs[iArg].eToken == TOKEN_ALPHANUMERIC && g_aArgs[iArg].sArg[0] == 'v') // 'video' ?
|
||||||
|
{
|
||||||
|
g_aWatches[iWatch].bSet = true;
|
||||||
|
g_aWatches[iWatch].bEnabled = true;
|
||||||
|
g_aWatches[iWatch].eSource = BP_SRC_VIDEO_SCANNER;
|
||||||
|
g_aWatches[iWatch].nAddress = 0xDEAD;
|
||||||
|
bAdded = true;
|
||||||
|
g_nWatches++;
|
||||||
|
iWatch++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
WORD nAddress = g_aArgs[iArg].nValue;
|
WORD nAddress = g_aArgs[iArg].nValue;
|
||||||
|
|
||||||
// Make sure address isn't an IO address
|
// Make sure address isn't an IO address
|
||||||
|
@ -6698,6 +6713,7 @@ Update_t CmdWatchAdd (int nArgs)
|
||||||
{
|
{
|
||||||
g_aWatches[iWatch].bSet = true;
|
g_aWatches[iWatch].bSet = true;
|
||||||
g_aWatches[iWatch].bEnabled = true;
|
g_aWatches[iWatch].bEnabled = true;
|
||||||
|
g_aWatches[iWatch].eSource = BP_SRC_MEMORY;
|
||||||
g_aWatches[iWatch].nAddress = (WORD) nAddress;
|
g_aWatches[iWatch].nAddress = (WORD) nAddress;
|
||||||
bAdded = true;
|
bAdded = true;
|
||||||
g_nWatches++;
|
g_nWatches++;
|
||||||
|
|
|
@ -2767,7 +2767,7 @@ void DrawWatches (int line)
|
||||||
#if DEBUG_FORCE_DISPLAY // Watch
|
#if DEBUG_FORCE_DISPLAY // Watch
|
||||||
if (true)
|
if (true)
|
||||||
#else
|
#else
|
||||||
if (g_aWatches[iWatch].bEnabled)
|
if (g_aWatches[iWatch].bEnabled && g_aWatches[iWatch].eSource == BP_SRC_MEMORY)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
RECT rect2 = rect;
|
RECT rect2 = rect;
|
||||||
|
@ -2779,40 +2779,32 @@ void DrawWatches (int line)
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_BULLET ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_BULLET ));
|
||||||
PrintTextCursorX( StrFormat( "%X ", iWatch ).c_str(), rect2 );
|
PrintTextCursorX( StrFormat( "%X ", iWatch ).c_str(), rect2 );
|
||||||
|
|
||||||
// DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR ));
|
|
||||||
// PrintTextCursorX( ".", rect2 );
|
|
||||||
|
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_ADDRESS ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_DISASM_ADDRESS ));
|
||||||
PrintTextCursorX( WordToHexStr( g_aWatches[iWatch].nAddress ).c_str(), rect2 );
|
PrintTextCursorX( WordToHexStr( g_aWatches[iWatch].nAddress ).c_str(), rect2 );
|
||||||
|
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR ));
|
||||||
PrintTextCursorX( ":", rect2 );
|
PrintTextCursorX( ":", rect2 );
|
||||||
|
|
||||||
BYTE nTarget8 = 0;
|
//
|
||||||
|
|
||||||
nTarget8 = (unsigned)*(LPBYTE)(mem+g_aWatches[iWatch].nAddress);
|
BYTE nTargetL = *(LPBYTE)(mem + g_aWatches[iWatch].nAddress);
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPCODE ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPCODE ));
|
||||||
PrintTextCursorX( ByteToHexStr( nTarget8 ).c_str(), rect2 );
|
PrintTextCursorX( ByteToHexStr( nTargetL ).c_str(), rect2 );
|
||||||
|
|
||||||
nTarget8 = (unsigned)*(LPBYTE)(mem+g_aWatches[iWatch].nAddress + 1);
|
BYTE nTargetH = *(LPBYTE)(mem + ((g_aWatches[iWatch].nAddress + 1) & 0xffff));
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPCODE ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPCODE ));
|
||||||
PrintTextCursorX( ByteToHexStr( nTarget8 ).c_str(), rect2 );
|
PrintTextCursorX( ByteToHexStr( nTargetH ).c_str(), rect2 );
|
||||||
|
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR ));
|
||||||
PrintTextCursorX( "(", rect2 );
|
PrintTextCursorX( "(", rect2 );
|
||||||
|
|
||||||
WORD nTarget16 = (unsigned)*(LPWORD)(mem+g_aWatches[iWatch].nAddress);
|
WORD nTarget16 = (((WORD)nTargetH) << 8) | ((WORD)nTargetL);
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_ADDRESS ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_ADDRESS ));
|
||||||
PrintTextCursorX( WordToHexStr( nTarget16 ).c_str(), rect2 );
|
PrintTextCursorX( WordToHexStr( nTarget16 ).c_str(), rect2 );
|
||||||
|
|
||||||
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR ));
|
DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPERATOR ));
|
||||||
// PrintTextCursorX( ":", rect2 );
|
|
||||||
PrintTextCursorX( ")", rect2 );
|
PrintTextCursorX( ")", rect2 );
|
||||||
|
|
||||||
// BYTE nValue8 = *(LPBYTE)(mem + nTarget16);
|
|
||||||
// DebuggerSetColorFG( DebuggerGetColor( FG_INFO_OPCODE ));
|
|
||||||
// PrintTextCursorX( ByteToHexStr( nValue8 ).c_str(), rect2 );
|
|
||||||
|
|
||||||
rect.top += g_nFontHeight;
|
rect.top += g_nFontHeight;
|
||||||
rect.bottom += g_nFontHeight;
|
rect.bottom += g_nFontHeight;
|
||||||
|
|
||||||
|
@ -2836,6 +2828,54 @@ void DrawWatches (int line)
|
||||||
PrintTextCursorX( ByteToHexStr( nValue8 ).c_str(), rect2 );
|
PrintTextCursorX( ByteToHexStr( nValue8 ).c_str(), rect2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (g_aWatches[iWatch].bEnabled && g_aWatches[iWatch].eSource == BP_SRC_VIDEO_SCANNER)
|
||||||
|
{
|
||||||
|
uint32_t data;
|
||||||
|
int dataSize;
|
||||||
|
g_aWatches[iWatch].nAddress = NTSC_GetScannerAddressAndData(data, dataSize);
|
||||||
|
|
||||||
|
RECT rect2 = rect;
|
||||||
|
|
||||||
|
DebuggerSetColorBG(DebuggerGetColor(BG_INFO_WATCH));
|
||||||
|
DebuggerSetColorFG(DebuggerGetColor(FG_INFO_TITLE));
|
||||||
|
PrintTextCursorX("W", rect2);
|
||||||
|
|
||||||
|
DebuggerSetColorFG(DebuggerGetColor(FG_INFO_BULLET));
|
||||||
|
PrintTextCursorX(StrFormat("%X ", iWatch).c_str(), rect2);
|
||||||
|
|
||||||
|
DebuggerSetColorFG(DebuggerGetColor(FG_DISASM_ADDRESS));
|
||||||
|
PrintTextCursorX(WordToHexStr(g_aWatches[iWatch].nAddress).c_str(), rect2);
|
||||||
|
|
||||||
|
DebuggerSetColorFG(DebuggerGetColor(FG_INFO_OPERATOR));
|
||||||
|
PrintTextCursorX(":", rect2);
|
||||||
|
|
||||||
|
DebuggerSetColorFG(DebuggerGetColor(FG_INFO_OPCODE));
|
||||||
|
if (dataSize == 1)
|
||||||
|
{
|
||||||
|
PrintTextCursorX(ByteToHexStr(data).c_str(), rect2);
|
||||||
|
}
|
||||||
|
else if (dataSize == 2)
|
||||||
|
{
|
||||||
|
PrintTextCursorX("a:", rect2);
|
||||||
|
PrintTextCursorX(ByteToHexStr(data>>8).c_str(), rect2);
|
||||||
|
PrintTextCursorX(" m:", rect2);
|
||||||
|
PrintTextCursorX(ByteToHexStr(data).c_str(), rect2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ASSERT(dataSize == 4);
|
||||||
|
PrintTextCursorX(DWordToHexStr(data).c_str(), rect2);
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.top += g_nFontHeight;
|
||||||
|
rect.bottom += g_nFontHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect.top += g_nFontHeight;
|
||||||
|
rect.bottom += g_nFontHeight;
|
||||||
|
}
|
||||||
|
|
||||||
rect.top += g_nFontHeight;
|
rect.top += g_nFontHeight;
|
||||||
rect.bottom += g_nFontHeight;
|
rect.bottom += g_nFontHeight;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,9 @@
|
||||||
BP_SRC_MEM_READ_ONLY,
|
BP_SRC_MEM_READ_ONLY,
|
||||||
BP_SRC_MEM_WRITE_ONLY,
|
BP_SRC_MEM_WRITE_ONLY,
|
||||||
|
|
||||||
|
BP_SRC_MEMORY, // For watches
|
||||||
|
BP_SRC_VIDEO_SCANNER, // For watches
|
||||||
|
|
||||||
NUM_BREAKPOINT_SOURCES
|
NUM_BREAKPOINT_SOURCES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -516,7 +519,7 @@
|
||||||
, CMD_VIEW_DHGR2
|
, CMD_VIEW_DHGR2
|
||||||
, CMD_VIEW_SHR
|
, CMD_VIEW_SHR
|
||||||
// Watch
|
// Watch
|
||||||
, CMD_WATCH // TODO: Deprecated ?
|
, CMD_WATCH
|
||||||
, CMD_WATCH_ADD
|
, CMD_WATCH_ADD
|
||||||
, CMD_WATCH_CLEAR
|
, CMD_WATCH_CLEAR
|
||||||
, CMD_WATCH_DISABLE
|
, CMD_WATCH_DISABLE
|
||||||
|
|
102
source/NTSC.cpp
102
source/NTSC.cpp
|
@ -869,6 +869,16 @@ INLINE uint16_t getVideoScannerAddressHGR()
|
||||||
return nAddress;
|
return nAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
INLINE uint16_t getVideoScannerAddressSHR()
|
||||||
|
{
|
||||||
|
// 2 pixels per byte in 320-pixel mode = 160 bytes/scanline
|
||||||
|
// 4 pixels per byte in 640-pixel mode = 160 bytes/scanline
|
||||||
|
const UINT kBytesPerScanline = 160;
|
||||||
|
const UINT kBytesPerCycle = 4;
|
||||||
|
return 0x2000 + kBytesPerScanline * g_nVideoClockVert + kBytesPerCycle * (g_nVideoClockHorz - VIDEO_SCANNER_HORZ_START);
|
||||||
|
}
|
||||||
|
|
||||||
// Non-Inline _________________________________________________________
|
// Non-Inline _________________________________________________________
|
||||||
|
|
||||||
// Build the 4 phase chroma lookup table
|
// Build the 4 phase chroma lookup table
|
||||||
|
@ -1822,14 +1832,10 @@ void updateScreenSHR(long cycles6502)
|
||||||
{
|
{
|
||||||
for (; cycles6502 > 0; --cycles6502)
|
for (; cycles6502 > 0; --cycles6502)
|
||||||
{
|
{
|
||||||
// 2 pixels per byte in 320-pixel mode = 160 bytes/scanline
|
|
||||||
// 4 pixels per byte in 640-pixel mode = 160 bytes/scanline
|
|
||||||
const UINT kBytesPerScanline = 160;
|
|
||||||
const UINT kBytesPerCycle = 4;
|
|
||||||
uint16_t addr = 0x2000 + kBytesPerScanline * g_nVideoClockVert + kBytesPerCycle * (g_nVideoClockHorz - VIDEO_SCANNER_HORZ_START);
|
|
||||||
|
|
||||||
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY_IIGS)
|
if (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY_IIGS)
|
||||||
{
|
{
|
||||||
|
uint16_t addr = getVideoScannerAddressSHR();
|
||||||
|
|
||||||
if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
|
if (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START)
|
||||||
{
|
{
|
||||||
uint32_t* pAux = (uint32_t*) MemGetAuxPtr(addr); // 8 pixels (320 mode) / 16 pixels (640 mode)
|
uint32_t* pAux = (uint32_t*) MemGetAuxPtr(addr); // 8 pixels (320 mode) / 16 pixels (640 mode)
|
||||||
|
@ -1947,6 +1953,8 @@ void NTSC_SetVideoTextMode( int cols )
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ )
|
void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ )
|
||||||
{
|
{
|
||||||
|
g_uNewVideoModeFlags = uVideoModeFlags;
|
||||||
|
|
||||||
if (uVideoModeFlags & VF_SHR)
|
if (uVideoModeFlags & VF_SHR)
|
||||||
{
|
{
|
||||||
g_pFuncUpdateGraphicsScreen = updateScreenSHR;
|
g_pFuncUpdateGraphicsScreen = updateScreenSHR;
|
||||||
|
@ -1965,7 +1973,6 @@ void NTSC_SetVideoMode( uint32_t uVideoModeFlags, bool bDelay/*=false*/ )
|
||||||
// (GH#670) NB. if g_bFullSpeed then NTSC_VideoUpdateCycles() won't be called on the next 6502 opcode.
|
// (GH#670) NB. if g_bFullSpeed then NTSC_VideoUpdateCycles() won't be called on the next 6502 opcode.
|
||||||
// - Instead it's called when !g_bFullSpeed (eg. drive motor off), then the stale g_uNewVideoModeFlags will get used for NTSC_SetVideoMode()!
|
// - Instead it's called when !g_bFullSpeed (eg. drive motor off), then the stale g_uNewVideoModeFlags will get used for NTSC_SetVideoMode()!
|
||||||
g_bDelayVideoMode = true;
|
g_bDelayVideoMode = true;
|
||||||
g_uNewVideoModeFlags = uVideoModeFlags;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2711,3 +2718,84 @@ bool NTSC_IsVisible(void)
|
||||||
{
|
{
|
||||||
return (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) && (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START);
|
return (g_nVideoClockVert < VIDEO_SCANNER_Y_DISPLAY) && (g_nVideoClockHorz >= VIDEO_SCANNER_HORZ_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For debugger
|
||||||
|
uint16_t NTSC_GetScannerAddressAndData(uint32_t& data, int& dataSize)
|
||||||
|
{
|
||||||
|
uint16_t addr = 0;
|
||||||
|
|
||||||
|
if (g_uNewVideoModeFlags & VF_SHR)
|
||||||
|
{
|
||||||
|
addr = getVideoScannerAddressSHR();
|
||||||
|
uint32_t* pAux = (uint32_t*)MemGetAuxPtr(addr); // 8 pixels (320 mode) / 16 pixels (640 mode)
|
||||||
|
data = pAux[0];
|
||||||
|
dataSize = 4;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
if ( (g_nVideoMixed && g_nVideoClockVert >= VIDEO_SCANNER_Y_MIXED) ||
|
||||||
|
(g_uNewVideoModeFlags & VF_TEXT) ||
|
||||||
|
!(g_uNewVideoModeFlags & VF_HIRES) )
|
||||||
|
{
|
||||||
|
addr = getVideoScannerAddressTXT();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr = getVideoScannerAddressHGR();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy logic from NTSC_SetVideoMode()
|
||||||
|
if (g_uNewVideoModeFlags & VF_TEXT)
|
||||||
|
{
|
||||||
|
if (g_uNewVideoModeFlags & VF_80COL)
|
||||||
|
dataSize = 2;
|
||||||
|
else
|
||||||
|
dataSize = 1;
|
||||||
|
}
|
||||||
|
else if (g_uNewVideoModeFlags & VF_HIRES)
|
||||||
|
{
|
||||||
|
if (g_uNewVideoModeFlags & VF_DHIRES)
|
||||||
|
{
|
||||||
|
if (g_uNewVideoModeFlags & VF_80COL)
|
||||||
|
dataSize = 2;
|
||||||
|
else
|
||||||
|
dataSize = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataSize = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (g_uNewVideoModeFlags & VF_DHIRES)
|
||||||
|
{
|
||||||
|
if (g_uNewVideoModeFlags & VF_80COL)
|
||||||
|
dataSize = 2;
|
||||||
|
else
|
||||||
|
dataSize = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataSize = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extra logic for MIXED mode
|
||||||
|
if (g_nVideoMixed && g_nVideoClockVert >= VIDEO_SCANNER_Y_MIXED && (g_uNewVideoModeFlags & VF_80COL))
|
||||||
|
dataSize = 2;
|
||||||
|
|
||||||
|
|
||||||
|
data = 0;
|
||||||
|
if (dataSize == 2)
|
||||||
|
{
|
||||||
|
uint8_t* pAux = MemGetAuxPtr(addr);
|
||||||
|
data = pAux[0] << 8;
|
||||||
|
}
|
||||||
|
uint8_t* pMain = MemGetMainPtr(addr);
|
||||||
|
data |= pMain[0];
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
|
@ -29,3 +29,4 @@ UINT NTSC_GetCyclesPerLine(void);
|
||||||
UINT NTSC_GetVideoLines(void);
|
UINT NTSC_GetVideoLines(void);
|
||||||
UINT NTSC_GetCyclesUntilVBlank(int cycles);
|
UINT NTSC_GetCyclesUntilVBlank(int cycles);
|
||||||
bool NTSC_IsVisible(void);
|
bool NTSC_IsVisible(void);
|
||||||
|
uint16_t NTSC_GetScannerAddressAndData(uint32_t& data, int& dataSize);
|
||||||
|
|
|
@ -75,4 +75,12 @@ inline std::string WordToHexStr(uint16_t n)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string DWordToHexStr(uint32_t n)
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
StrAppendWordAsHex(s, n >> 16);
|
||||||
|
StrAppendWordAsHex(s, n);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue