15 months since last post, that must be some kind of record! =)
Well, a lot of good stuff happened in the meantime ... the not so good news is that I didn't have much time to allocate to ParaJVE/ParaJVD coding.
Yet I finally managed to plug in the debug engine (that can execute in normal or step in/over/out modes) and to write a memory viewer, a registers editor, an ASM source viewer, and a breakpoints manager.
- The breakpoints manager handles standard breakpoints (double-clicking a program line in the Source Viewer will automatically create an execution breakpoint for the instruction's address) as well as memory access breakpoints (you can specify if you want it to monitor read, write or read/write access to a single address or to a whole address range).
More breakpoint types will be added eventually (for example: invalid memory access, invalid instruction, interrupt, timers timeout, cycles count, end of frame, ...)
- The Memory Viewer component lets you see the content of any memory area : RAM, ROM, CARTRIDGE (and even some special cartridges areas like the Cartridge-RAM embedded at $2000 in "Animaction").
The areas that are tagged as RAM can be edited by the user, and are also monitored for changes during program execution (the bytes that changed will be displayed with a yellow background). This "snapshot" feature can be cumulative (snapshot updated manually on user-action) or not (snapshot updated automatically whenever the execution resumes).
- The Registers Window provides you with a way to watch and edit (guess what?) the registers values. It also monitors the changes whenever the engines suspends execution, and displays the modified values using a different background color.
- The Source Viewer component is not quite advanced yet. All it does is to load the source file(s) at startup, then scroll to the current executed line as the debug session goes on.
The main concern with this approach is that if, for some reason, the executed address cannot be found in the loaded source file(s), the component cannot display anything. This will happen for instance if the program executes some dynamic code stored in RAM. To bypass this issue, the source viewer needs a way to be coupled with a dynamic disassembler (such a disassembler already exists within ParaJVE, I just need to think about how to integrate it tightly with the source viewer).
For now, the viewer can load two kinds of source files :
- Raw ASM files - provided that each line holding an instruction starts with the address (prefixed with any number of white spaces). The list output files (.LST) generated by the AS09 assembler are perfect candidates.
- Debug output files (.DBG) generated by AS09
I'd like to add support for many more assemblers, so please tell me which is your preferred assembler and I'll try to go for it (or even better, I'll exhibit a public API so that you can write your own loader and add it to ParaJVD as a pluggin).
And since pictures are worth a thousand words, here is a screen grab of a debugging session I just had yesterday, while trying to check a corrupted ROM image (Mail Plane) :
The "ParaJVE" tab embeds the emulator display, whereas some other tabs are not functional yet and are just place-holders ("Disassembly", "VIA-6522" and "Watches"). Each window and tab can be resized/docked/moved around to match the user preferences.