13

I'm trying to emulate programs from the 80s, but with an accurate clock-speed¹ (pretending its an 8086). Meaning that if a 8086 would take X ms/opcode, the emulator should take X ms (+- a bit of jitter as I'm not running a RTOS). If it should take Y ms to access RAM, the emulator should take Y ms to access RAM.

Is there such an emulator (preferably running on Linux or web)?

¹ Which is why I can't use something like qemu.

pipe
  • 1,718
  • 17
  • 20
multics
  • 561
  • 5
  • 8
  • Looks like you are aiming for Machine Cycle level emulation which is pretty rare. The majority of emulators use just Clock Tics (time bursting) which is allowing just specific CPU CLK clock cycles be elapsed in some time interval (like timer) to throttle the speed to relevant emulated clock. Yes in such case the emulation speed seems correct but HW access is far from it. Look here Question about cycle counting accuracy when emulating a CPU sadly I do not know of any MC level emulation of x86 out there but I did not look for it either... – Spektre Oct 04 '18 at 08:12
  • 1
    Do you mean a cycle exact emulator as per Stephen Kitt's answer or one that runs at the same speed exactly as a real 8086? You will not find the latter because no modern general purpose computer can accurately synchronise at the microsecond level. The best I think you'll get is a cycle accurate emulator that runs the exact number of cycles between screen refreshes and then pauses until the next screen refresh. I did that with a Spectrum emulator and it was good enough to play games without any sound. – JeremyP Oct 04 '18 at 10:21
  • @JeremyP you can have good sound with clock tics too you just need to create a sound buffer and set the sound at position dependent on emulated time instead of real time and play it latter. The drawback is that you will have bigger latency so sound will be a bit shifted (delayed) to your simulation but shifts up to 10 ms are hardly noticeable – Spektre Oct 04 '18 at 11:26
  • @JeremyP As its mentioned in the link in my previous comment all the HW is doable with clock tics too but you need to do (sometimes crazy) hacks for those that are timing demanding. On the other hand MC level timings do not need any hacks and can be connected to real or simulated HW directly. Beware Instruction level timing is not the same as MC level timing and sometimes also needs hacks (especially for contention and I/O interfacing with other HW. – Spektre Oct 04 '18 at 11:28
  • 6
    To clarify what I think @Spektre means, there’s a huge difference between emulating a CPU’s instruction timing tables (e.g., CLI takes 2 cycles on 808x, 3 on 286, 8 on 386, 5 on 486), including cycle eaters, and emulating the timing diagrams you’ll find in the CPU’s datasheets (and those of all the other chips in a computer). The latter involves simulating the electrical signals on each wire in the system, along with all the different clocks, and requires much, much finer granularity in the simulation (it’s not emulation any more ;-). – Stephen Kitt Oct 04 '18 at 11:57
  • 1
  • 2
    @StephenKitt the MC level timing does not necessarily mean simulating pins of HW but usually does at least some like AB,DB busses at specific times so underlying IC emulation can be done at correct time with actual simulated state they need. As the OP implies correct memory access timing I assume MC level emulation is the target.... but to get back to simulation of MC the idea is to break down each instruction to set of basic operations (just like target CPU does) so the memory and IO is accessed the same ways as on the real HW and underlaying flags/states are updated in the same order too. – Spektre Oct 04 '18 at 12:26
  • Surely there must be a better title for this question, as being cycle exact is only a necessary precursor for being, ummm, time exact (to cycle precision?)? – Tommy Oct 05 '18 at 17:37

3 Answers3

23

PCem aims to be an accurate emulator, and its 8086/8088 timings are accurate. It can emulate a wide variety of hardware, and can model specific PCs with their ROMs (such as the original IBM PC, the Amstrad 1640, and many others). It is available for Linux and Windows.

Its 8086 emulation is implemented in src/808x.c — you can see there that it keeps track of the cycles taken by each instruction, and each memory access, and takes into account memory prefetches and the cycles lost to memory refresh. It even emulates CGA snow!

Eilon
  • 105
  • 4
Stephen Kitt
  • 121,835
  • 17
  • 505
  • 462
3

Not an emulator but the MicroCore Labs MCL86 is a 8086/8088 core which has the option to be "cycle-compatible" (accurate to within one or two clocks) with a 4.77 MHz 8088. I don't know if it accesses RAM cycle-accurately. A compatible board (Lattice MachXO2-7000HE) is about $30.

snips-n-snails
  • 17,548
  • 3
  • 63
  • 120
0

A bit hard to answer with the little information you give. Since you especially mention the8086 (not 8088), it may be safe you're not about to emulate an IBM PC.

The i8086emu might be right for you. It emulates a rather straight foreward 8086 singleboard computer with the somewhat generic name SBC8086 :)) That machine runs on 5 MHz, and the emulator is suppoesed to be close. It's made to run under Linux, using GTK2 as frontend, but also compiles for 32 bit Windows.

The emulator got a quite remarkable software structure with interfaces for easy integration of 'new' simulated chips and I/O hardware.

There might be a little hurdle, as most documentation is in German :))

Raffzahn
  • 222,541
  • 22
  • 631
  • 918
  • 2
    i8086emu is far from cycle-exact. It simply halts the emulated CPU every soandso many instructions (50000 per default) to slow it down to somewhere like 5MHz. So, it creates the impression of a 5MHz 8086, but the real speed between pauses depends purely on your host's performance. – tofro Oct 04 '18 at 09:49
  • @tofro I don't see any other way to get the right speed on a general purpose PC. – JeremyP Oct 04 '18 at 10:24
  • 4
    @JeremyP Cycle exact emulators measure and adjust the timing for each instruction, not the average spent for 50k. When i8086emu was written back in 2004 that was probably not possible, or at least difficult with the hardware available back then (Also clearly not the intent of the developers, so no blame on them). Today, it definitely is. Also, this emulator might have a hard time running the sort of programs the question is asking for (but admittedly, the question is not very clear on this) – tofro Oct 04 '18 at 10:28
  • @tofro But to adjust the timing on an instruction by instruction basis, you'd need to be able to time an interval of less than a microsecond (for 8086). How would you do that on a modern PC? – JeremyP Oct 04 '18 at 10:32
  • 2
    @JeremyP on x86 PC from Pentium and latter very simply. Its just wait loop using RDTSC ... so read cycles at start of instruction and after its done read cycles again and loop until cycles are bigger or equal then simulated time ... so RDTSC and 32/64 bit cmp and conditional jump so 3 or 4 instruction loop in assembly... You just need to set affinity for your process and stabilize host CPU clock. This way you can have even ~40ns granularity these days. – Spektre Oct 04 '18 at 11:19
  • @Spektre you'll also have to bump yourself up in scheduling priority and possibly policy, but I'm probably being needlessly petty in saying so; as I'm sure you omitted only for brevity, affinity just means you won't be executed on a different core, not that another thread might not share your core. – Tommy Oct 04 '18 at 11:30
  • 1
    @Tommy exactly in Windows its done like this: Cache size estimation on your system? and you need to take in mind this Negative clock cycle measurements with back-to-back rdtsc? – Spektre Oct 04 '18 at 11:31
  • 1
    Err, even *if all of this works, it solves a non existing problem. The usual case of pseudo accuracy. Like converting feet into Meter to the 5th digit when it's about a sign pointing to the next loo. For evey day use a 50 (or 60) Hz time slice is perfect. In case of a 5 MHz CPU that would be 100k (83k) cycles per slice followed by an adjusting wait. This combines easy system integration (highly monoton 50 (60) Hz timing is available in most systems) with reasonable implementation effort for a workable solution in next to any environment. – Raffzahn Oct 04 '18 at 14:15
  • I thought a 8088 was practically the same as an 8086 – multics Oct 04 '18 at 18:20
  • 1
    @multics Well, codewise they are the same, Similar for the instruction timing within the CPU. Just due the 8 bit bus, it needs to do two bus cycles per word access. THanks to the rather clever seperation in EU and BIU this does only result in an ~30% (average) lower thruput at the same clock rate - as usual this depends much on the task to be solved. – Raffzahn Oct 04 '18 at 19:05