Machine monitor/visualisation
From an educational point of view, this project is pretty promising.
How would it be possible to add or interface a visual monitor of the emulated system like the one we can find in some simulators?
Hello,
Thank you for your interest in this project!
The CPU fields are all located within memory and can be read either by using a direct pointer (e.g., uint32_t *get_eax_ptr(void) { return &cpu.reg32[0]; }) or a helper function (e.g., uint32_t get_eax(void) { return cpu.reg32[0]; }). Some fields require you to access them via a helper function, since the full state is not kept within a single field, e.g. cpu_get_eflags(). RAM can be accessed through a pointer in the CPU state. Afterwards, it's a simple matter of displaying those values in the interface of your choosing. Unfortunately, there is no built-in debugger interface yet, as I typically use GDB and set breakpoints while debugging.
I think that in order to achieve what you're looking for, you'll also need to implement single-stepping. There is no built-in support for that right now, so it would have to be done by hacking the source code. In principle, you would want to comment out some of the loops so that the function yields immediately. You could also set cpu.cycles_to_run to 1, but there are opcodes that modify it in weird ways, and so you may run into some cases where more than one instruction runs. This is not a problem in the emulator, since its goal is to run as many instructions as quickly as possible.
For instance, you may want to have a global single-step flag modify src/cpu/opcodes.c in the following way:
int single_step = 0; // set to 1 if you want to single-step
void cpu_execute(void)
{
struct decoded_instruction* i = cpu_get_trace();
do {
i = i->handler(i);
if (single_step) // <-- new line
break; // <-- new line
if (!--cpu.cycles_to_run)
break;
} while (1);
}
And, of course, you would want to modify src/cpu/cpu.c accordingly as well.