Machine Cycle Step Not Available
CPU8080.steps(N) always executes a full instruction, even when that exceeds the number of machine cycles given. This makes the code unsuitable for emulating systems such as the Altair 8800, where "single-step" steps through cycles, rather than instructions. Cycle-stepping is important not only for accuracy, but also to make debugging easier, as described here.
It would be nice to have cycle-step functionality so that this web-based Altair 8800 emulator could work like a real Altair in this respect.
Hello, you are right, it is not a cycle-perfect simulator, but an emulator with "near to cycle perfect" approach. The cycle perfect simulator needs a complete rewrite to an FSM-based machine. I won't tell it's impossible, but please allow me a couple of days to rethink all the concept, OK?
First, if you don't have time to do this, I think that's fair enough. I'd suggest leaving the ticket open as "a nice feature to have, if someone wants to implement it." (And also to help developers keep in mind, as they make changes, that maybe we want to head this direction someday.)
If you do have time to work on this, that's great! Take all the time you need; I'm in no hurry.
This doesn't really need to be cycle perfect at the clock or timing level, it just needs to expand the "step" functionality to do "bus cycle steps" rather than "instruction steps." Still, I agree this isn't a trivial change; as well as the internal stuff to deal with the "current/next bus address" as well as the now-separate program counter, it also requires an expansion of the API to allow emulators to get the information about the bus cycles so they can, e.g., display the current address and data read in the last cycle on the front panel. The step function would then change to take a maximum number of instructions, rather than cycles, if you're going to remain backward-compatible. (But it might make things more clear, if you don't mind changing that API, to rename the function to something that expresses that it's doing an instruction step rather than a bus cycle step.)
No, it is not an "I have no time" issue. :) It would be a great mental exercise. But I have a lot of ideas in progress, so I have to "insert it to the pipeline".
I think the best way is to re-implement the 8080's state machine in a program way. I have to make some experiments, and when the FSM will be ready, the rest is a piece of cake, as long as the instruction handlers can be generated. The step() can stay as is, I believe, with some kind of finishCurrentInstruction() and getCurrentState(). The main goal of step is for timed emulators, i.e. "make 2M Ts per second", so I can call step(2000000) each second and I know that the last instruction is finished, although it can take a few more Ts. It could remain untouched, I guess...
"Into the pipeline" is great; thanks!
So step() actually does take real "clock ticks?" (It's not clear to me if those are clock cycles or bus cycles.) It sounds like then you have all the cycle timings you need and are cycle accurate already, so yeah, you just need to change the internal workings to be able to break down the instructions into their component parts that do memory reads, writes, and internal processing without memory read/write.