Ever since I quit development of the PCem code, I have spent many months (and many hours nearly each day) building a new emulator built from the PCE code. While admittedly it is very basic as far as the upcoming build of the "normal" version is concerned, there is also a special version in the making for which I have devoted a great deal of time over the past few months which adds support for Intel 80386 CPUs, including the early steppings and all of the problems that they had.
Emulating a machine, as many in this topic have pointed out, is no easy task. In my case, it is not to simply get the software up and running, but rather to recreate each aspect of the machine itself (even the physical ones) as it originally existed when it was first new, and this by the way was the reason for why I chose PCE as the base for my project, since I knew for sure that I was starting out with an already similar emulator and continuing its development from there.
When building the 80386 emulator over the past few months, great care had to be taken in order to write down each changed CPU register down to the each detail. And I'm still dealing with it to this day (adding in 8192 segment descriptor tables all while maintaining a reasonable file size is no easy task).
Emulating different revisions of each chip is also often quite a challenge, especially when those problems also were very often the result of failures in the electrical design. Particularly, one such case was with a problem that the very early (nearly prototype) A1 stepping had, that would cause it to simply not terminate a memory cycle if the one pin (F13) happened to be disconnected from the 5V power supply. With the help of a friend of mine, however, and some C programming references that he gave me recently, I managed to implement even that, by using the "while" loop to simulate the same type of behavior in the PCE code if the emulator detects that pin F13 happens to be disconnected if it finds an A1 stepping running.
Developers of other emulators, on the other hand, have in many cases done at best very poor emulation of different CPUs. Even when the CPU is known to "work", the testing being done is often very questionable at best - I once saw one case of a problem in the MESS emulator, of one game causing a blue screen error in Microsoft Windows 95, which was automatically assumed to be a problem with the CD-ROM, even when they completely ignored the fact that "Exception 0E" specifically refers to "Page Fault", which is generated by the CPU when the system writes to a page that is either unavailable or in use, yet they apparently wanted to believe that the culprit was with the CD-ROM simply because they didn't want to accept that there was anything wrong with the emulated CPU.
Another point of mine is that an emulator of ANY type should also be easily readable as far as the code is concerned, so that it can be developed by other people, and easily extended in the future. The original PCE CPU code for the 8086 and 80186 was already like that, so it was very easily extendable to quite a number of 80386-style operations, not to also mention already being cycle-accurate, so it was very easy to change the 8086 clock cycles to their 80386 counterparts.
Reading the code of other emulators, however, is such an unthinkably unbearable mess that I cannot even begin to properly describe it all here. From reading the PCem CPU code, the commands were so cryptic that sometimes I actually had to guess what each statement referred to. It also doesn't help when developers don't leave decent comments in their source code so that people can actually understand it. Lesson to be learned: If you want your CPU code to be developed further by other people, then make sure that it's as easy to read and understand as possible.
--------------------------------
EDIT: From looking back at this thread, it seems that the discussion turned more towards emulation of sound chips (such as the OPL2 and OPL3 used in the Ad Lib and Sound Blaster). But my point still stands.