groepaz wrote:btw, VICE also uses this "run until something interesting happens" approach for the CIA and VIA cores. and its exactly what makes this code so terrible and almost unmaintainable
I used it for a cycle-perfect emulation of a non-Commodore 6502 machine back in the early-'00s; it was definitely beneficial to performance, but displeasingly oblique.
Structurally, my favourite is a ZX80/81 emulator I wrote about five years ago in which the only thing that is shared between devices is 128 bits describing the status of the bus. To run it you have to pump the clock, somebody explicitly has to be in there producing chip select signals for RAM and ROM, the ULA (or its pre-ULA equivalent in the '80) has to latch content it grabs parasitically from the bus per that machine's very unique approach to saving money on video hardware, etc.
Every emulated chip is a completely isolated island, individually testable, and one expresses all the logic in a direct manner. But then we're talking about a 3.25Mhz clock rate, so that's seven million function calls a second just to pump the clock. I wrote the individual chips as purely functional, so they declare which lines they're monitoring and are asked to update output only upon a relevant change in input (so, e.g. the RAM knows nothing of the clock signal), so it wasn't as bad as each getting messaged upon every clock change but once you factor in resolving complicated bus changes between components (component A changes line Q, which component B uses as an input; as a result component B changes line R, which component C uses as an input; as a result component C changes line S, which component D uses as an input...) it just turns into a lot of bookkeeping.
The full-fat i7 MacBook Pro I was running at the time needed to use something like 80% of a core to run that. So I'm not sure it's scalable to particularly sophisticated machines without serious reconsideration.
So now I'm at templated execution units with machine-specific bus code, with the execution units providing the same quantity of information as if they were toggling each line but at a higher level. You have to write and rewrite bus logic per machine at a level of abstraction much closer to the programmer's manual than the repair manual but if it makes things feasible and isn't actually less accurate then that's probably a gain. Though one I'm sad about.