Hi Robb
There are two solutions I can suggest related to z88dk. I use one of them for a lot of different purposes, including debugging. The other one I don't use because its capability extends way beyond my needs. But both are related to z88dk-ticks. So let me start with the second one first, the one I know least about.
z88dk-gdb provides the debugger interface from ticks and connects to a gdbserver to permit line-by-line debugging of software in emulators or on real hardware. The
gdbserver connects to a hardware debugger for the ZX Spectrum, and is used by many people are developing complex, timing sensitive, games.
z88dk-gdb also connects to VSCode and to CLion using the
FUSE Emulator from Speccy Tools and CMake.
OK. So I don't use any of the above as my needs are more mundane. But, if you do use z88dk-gdb you can get support from the z88dk forum (probably Alex who built most of it). And if you get it going, please write it up and let us know.
The simpler solution is to use a command line emulator and debugger tool called
z88dk-ticks. It provides an instruction by instruction view of the registers and stack, and is fully symbolic so it is easy to use. The original function was to time code segments to understand what is fastest, and it is used to produce the
benchmarks.
z88dk-ticks can emulate many machines and different CPUs (8080, 8085, gbz80, z80, z180, ez80, etc). If you feed it a COM file then it automatically assumes that it needs to emulate "CP/M 2.2". If you feed it a file (partially) named "rc2014" it assumes that you want to emulate a RC2014 Machine with ACIA serial interfaces, and it also supports calls to an emulated Am9511A APU and for an 8255 I/O device.
The CP/M emulation is not 100% complete and the BDOS file IO calls are emulated rather than being accurate. But for testing your program code (as opposed to testing BDOS code) it is sufficient.
z88dk-ticks will normally run in cycle timing mode, and usually a +test target build (a simple no I/O platform) is done and total ticks are calculated.
There is a debug mode where breakpoints can be entered and halted at. There is a trace mode, which produces a full text machine state, which can be useful for tracking where a program goes wrong too.
Hope that helps.
P.