@Stanislav: Heh. First, I have to get my version finished, to see what it is that I actually need.
The first big question is whether the debugger will always be compiled together with Bochs into the bochs executable?
If so, the code can use #ifdefs regarding whether optional features like MMX, SSE, FPU, 64bit, etc are actually supported in the build. If the debugger needs to test each of those things from the interface, it needs more things than I listed.
But basically, it seems that I need:
1. A function to read and set physical memory addresses.
-- Note: it is best if it can copy a large number of bytes (without crossing a 4K page boundary, of course).
-- It would be acceptable (but painful) if the copy process had to be done 1, 4, or 8 bytes at a time.
2. The CPU index of the CPU that is currently being simulated.
3. The total number of CPUs.
4. A function to convert a linear address to a physical address for a particular CPU.
5. A signal from the simulator, every time bochs gets to a "break" of any kind.
6. A way to force the simulator to break.
7. A way to force the simulator to quit.
8. A function to disassemble the next mnemonic at a linear address -- it should return the bytelength, and the disassembly as a string. I can pass a buffer for the string. The disassembly function would need to handle all the "guard" stuff ITSELF.
9. A count of the total maximum number of breakpoints -- so I can preallocate a buffer.
10. An array or enumeration of all the breakpoints -- addresses, type, index number.
11. A count of the total maximum number of watchpoints -- so I can preallocate a buffer.
12. An array or enumeration of all the watchpoints -- addresses, length, type, index number.
13. A function to add and delete breakpoints.
14. A function to add and delete watchpoints.
15. A tree (or whatever) that will tell me all the available emulated registers.
16. Functions that will read 32bit and 64bit registers, for a particular CPU.
-- Note: if possible, I want to get a function pointer, or something, that I can store and use repeatedly to get/set the value of a register. I do not want to have to search the tree every single time I try to read a register.
17. Functions that will set any registers that are allowed to be set, for a particular CPU.
18. Something that will tell me if I should be using 16, 32, or 64 bit addressing for a particular CPU. (It changes my formatting.)
19. Total amount of emulated physical mem.
20. If textconfig is still going to be part of bochs, I need a function that will send user commands to it.
21. A signal from textconfig, when it is ready to accept a new command.
22. Again with textconfig -- if it creates output, I need a signal that there is output to read, and a way to get it.
23. ptime
24. proceed, step (#), and continue commands
25. A function that will convert CS:RIP/EIP into a linear address for a particular CPU -- to handle unReal/Real mode craziness.
Optional things that would be nice:
1. A flag on each CPU to let me know if its mode had changed since the previous break.
2. A flag on memory to let me know if memory had been modified since the last break.
3. A ping function that would let me know that the sim has not crashed/gone into an infinite loop.
-- That's all I can think of right off the top of my head.
Maybe enough to start a discussion.
@WindowsNT: The code that I listed is not mine -- it was lifted directly from debug_main.cpp. I think it is just as ugly as you do.
However, you should know that when a C++ compiler does its magic on your C++ classes -- the kind of C that I listed is EXACTLY what the compiler turns your code into. You may choose to hide from that fact, if you wish.
Also, this code is what already works with bochs. We are too late to affect that. And the siminterface is ten times worse.
And why do I prefer C so much over C++? Because it's 10 to 50 times faster with typical coding. It's not nice to waste all of a user's CPU power, like your program is the only one that will ever run on their machine.