Skip to content

Commit bbfad63

Browse files
committed
make scrolling comment-sensitive (for real)
This has the added benefits that PC relative positioning works right, and there is no longer a need for that HACK that ensures the PC is visible when you jump to it.
1 parent 25c4e34 commit bbfad63

File tree

1 file changed

+73
-47
lines changed

1 file changed

+73
-47
lines changed

src/drivers/win/debugger.cpp

Lines changed: 73 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,7 @@ std::vector<std::vector<uint16>> disassembly_operands;
130130
// this is used to autoscroll the Disassembly window while keeping relative position of the ">" pointer inside this window
131131
unsigned int PC_pointerOffset = 0;
132132
int PCLine = -1;
133-
// this is used for dirty, but unavoidable hack, which is necessary to ensure the ">" pointer is visible when stepping/seeking to PC
134-
bool PCPointerWasDrawn = false;
135-
// and another hack...
133+
// hack to help syntax highlighting find the PC
136134
int beginningOfPCPointerLine = -1; // index of the first char within debug_str[] string, where the ">" line starts
137135
static int skipLinesStatic = 0;
138136

@@ -257,8 +255,33 @@ unsigned int AddBreak(HWND hwndDlg)
257255
return 0;
258256
}
259257

260-
// This function is for "smart" scrolling...
261-
// it attempts to scroll up one line by a whole instruction
258+
// Tells you how many lines the comments and label name take for a given address.
259+
// Used for smoothly scrolling through comments.
260+
static int NumAnnotationLines(int addr)
261+
{
262+
if (symbDebugEnabled)
263+
{
264+
Name* node = findNode(getNamesPointerForAddress(addr), addr);
265+
if (node)
266+
{
267+
int count = 0;
268+
269+
if (node->name)
270+
count++;
271+
272+
char* str = node->comment;
273+
for (; str; count++)
274+
str = strstr(str + 1, "\n");
275+
276+
return count;
277+
}
278+
}
279+
280+
return 0;
281+
}
282+
283+
// This function is for "smart" scrolling.
284+
// It attempts to scroll up by a whole instruction heuristically.
262285
// Should we add the label-respecting logic from dumper.cpp?
263286
int InstructionUp(int from)
264287
{
@@ -290,8 +313,17 @@ int InstructionUp(int from)
290313
return 0; // of course, if we can't scroll up, just return 0!
291314
}
292315

293-
// This all works great if each scrollup call is accompanied by a disassembletowindow call.
294-
// Realistically, I just need to make this function get the nodes and set things in a sane way.
316+
int InstructionDown(int from)
317+
{
318+
int tmp = opsize[GetMem(si.nPos)];
319+
if ((tmp))
320+
return from + tmp;
321+
else
322+
return from + 1; // this is data or undefined instruction
323+
}
324+
325+
// Scroll up one visible line, respecting comments and labels.
326+
// skipLinesStatic will eventually tell the DisassembleToWindow function how many comment lines to skip.
295327
int ScrollUp(int from)
296328
{
297329
if (skipLinesStatic)
@@ -300,24 +332,25 @@ int ScrollUp(int from)
300332
return from;
301333
}
302334

303-
skipLinesStatic = -1;
304-
return InstructionUp(from);
335+
int addr = InstructionUp(from);
336+
skipLinesStatic = NumAnnotationLines(addr);
337+
return addr;
305338
}
306339

307340
// Can probably get rid of the parameters and let the static vars do the talking
308341
int ScrollDown(int from)
309342
{
310-
skipLinesStatic++;
311-
return from;
312-
}
313-
314-
int InstructionDown(int from)
315-
{
316-
int tmp = opsize[GetMem(si.nPos)];
317-
if ((tmp))
318-
return from + tmp;
343+
// TODO: Store this annotationLines info so we can stop recomputing it!
344+
if (skipLinesStatic == NumAnnotationLines(from))
345+
{
346+
skipLinesStatic = 0;
347+
return InstructionDown(from);
348+
}
319349
else
320-
return from + 1; // this is data or undefined instruction
350+
{
351+
skipLinesStatic++;
352+
return from;
353+
}
321354
}
322355

323356
static void UpdateDialog(HWND hwndDlg) {
@@ -596,6 +629,19 @@ void UpdateDisassembleView(HWND hWnd, UINT id, int lines, bool text = false)
596629
SendDlgItemMessage(hWnd, id, EM_SETEVENTMASK, 0, eventMask);
597630
}
598631

632+
/**
633+
* Starting at addr, disassembles code to the debugger window. The number of lines is automatically determined
634+
* by the window size. id and scrollid tell the function which dialog items to modify, although a hardcoded ID
635+
* is mixed in, so, eh.
636+
* skiplines is used so that large comments can appear/disappear line by line, as you would expect in a text file,
637+
* rather than jumping in all at once.
638+
*
639+
* @param hWnd Handle to the debugger window
640+
* @param id id of the disassembly textbox
641+
* @param scrollid id of the scrollbar
642+
* @param addr starting address for disassembly
643+
* @param skiplines how many comment/label lines to skip, used for smooth scrolling (default 0)
644+
*/
599645
void DisassembleToWindow(HWND hWnd, int id, int scrollid, unsigned int addr, int skiplines)
600646
{
601647
// Why is this getting called twice per scroll?
@@ -606,7 +652,6 @@ void DisassembleToWindow(HWND hWnd, int id, int scrollid, unsigned int addr, int
606652
unsigned int instruction_addr;
607653

608654
disassembly_addresses.resize(0);
609-
PCPointerWasDrawn = false;
610655
beginningOfPCPointerLine = -1;
611656

612657
if (symbDebugEnabled)
@@ -615,6 +660,7 @@ void DisassembleToWindow(HWND hWnd, int id, int scrollid, unsigned int addr, int
615660
disassembly_operands.resize(0);
616661
}
617662

663+
skipLinesStatic = skiplines;
618664
si.nPos = addr;
619665
SetScrollInfo(GetDlgItem(hWnd,scrollid),SB_CTL,&si,TRUE);
620666

@@ -689,27 +735,18 @@ void DisassembleToWindow(HWND hWnd, int id, int scrollid, unsigned int addr, int
689735
}
690736
}
691737
}
692-
if (skiplines > 0)
738+
if (skiplines)
693739
{
694740
// We were told to skip more comment/name lines than exist.
695-
skipLinesStatic = skiplines = 0;
696-
si.nPos = addr = InstructionDown(addr);
697-
SetScrollInfo(GetDlgItem(hWnd, scrollid), SB_CTL, &si, TRUE);
698-
continue;
699-
}
700-
if (skiplines < 0)
701-
{
702-
// Negative skiplines means it just kept going so this is our count
703-
skipLinesStatic = -skiplines - 1;
741+
skipLinesStatic -= skiplines;
704742
skiplines = 0;
705-
printf("Janky negative skiplines: %d\n", skipLinesStatic);
743+
continue;
706744
}
707745
}
708746

709747
if (addr == X.PC)
710748
{
711749
PC_pointerOffset = line_count;
712-
PCPointerWasDrawn = true;
713750
beginningOfPCPointerLine = wcslen(debug_wstr);
714751
wcscat(debug_wstr, L">");
715752
PCLine = line_count;
@@ -961,7 +998,9 @@ void UpdateDebugger(bool jump_to_pc)
961998

962999
if (jump_to_pc || disassembly_addresses.size() == 0)
9631000
{
1001+
// For relative positioning, we want start pos to be PC address with the comments scrolled offscreen.
9641002
starting_address = X.PC;
1003+
skipLinesStatic = NumAnnotationLines(starting_address);
9651004

9661005
// ensure that PC pointer will be visible even after the window was resized
9671006
RECT rect;
@@ -970,27 +1009,14 @@ void UpdateDebugger(bool jump_to_pc)
9701009
if (PC_pointerOffset >= lines)
9711010
PC_pointerOffset = 0;
9721011

973-
// PC_PointerOffset now indicates number of visible lines, which totally breaks this and that "HACK" below.
974-
// Might need to change InstructionUp.
9751012
// keep the relative position of the ">" pointer inside the Disassembly window
9761013
for (int i = PC_pointerOffset; i > 0; i--)
9771014
{
9781015
starting_address = ScrollUp(starting_address);
9791016
}
9801017
DisassembleToWindow(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, starting_address, skipLinesStatic);
981-
982-
// HACK, but I don't see any other way to ensure the ">" pointer is visible when "Symbolic debug" is enabled
983-
if (!PCPointerWasDrawn && PC_pointerOffset)
984-
{
985-
// we've got a problem, probably due to Symbolic info taking so much space that PC pointer couldn't be seen with (PC_pointerOffset > 0)
986-
PC_pointerOffset = 0;
987-
starting_address = X.PC;
988-
// retry with (PC_pointerOffset = 0) now
989-
DisassembleToWindow(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, starting_address);
990-
}
991-
992-
starting_address = X.PC;
993-
} else
1018+
}
1019+
else
9941020
{
9951021
starting_address = disassembly_addresses[0];
9961022
DisassembleToWindow(hDebug, IDC_DEBUGGER_DISASSEMBLY, IDC_DEBUGGER_DISASSEMBLY_VSCR, starting_address, skipLinesStatic);

0 commit comments

Comments
 (0)