superfury wrote:It doesn't make a difference if I process a loop calling tickPIT 1.19 million times per second or do it within the function itself? It will only generate more function overhead compared to the current method? (Function being called ~1190000 times a second)
It does if you only record one PIT state per channel between calls while the PIT state can be changed more than once during that time.
As I say, in 8088 MPH the PIT one-shot is reprogrammed every 288 CPU cycles, so that is every 72 PIT ticks.
superfury wrote:About CPU synchronization: I just need to add cycle counting to the 8086/8088 to all instructions and synchronize the instructions using the high resolution clock by delaying until cycles match/precede current time(about the same way the Dosbox-style 'cycles' is applied in my emulator? Only with clock cycles used on the instruction converted to time elapsed(ns passed), added to last instruction time(starts at 0us for the first emulated instruction executed), next delay until current time(in ns) goes past or matches the new timestamp. Then you've got cycle-accurate PIT and 8086/8088 timing that matches (cycle wise, although 1.19MHz vs 4MHz).
It's most important to synchronize the different components of your emulator to eachother, so the CPU, the PIT, the CRTC and possibly other hardware.
You also need to emulate bus cycles properly, so that the CGA hardware will generate wait states for the CPU. Which also includes emulating the bus cycles for instruction fetches (so that the prefetch buffer is only filled when there are bus cycles available).
That is what is required for accurate emulation of the hardware, so that code like 8088 MPH works as expected. Synchronizing it with the high resolution timer is not important for emulation accuracy itself, but only for the user, so the system runs more or less at the proper speed.
On a real machine, you have a 14.318 MHz clock to which everything is synchronized.
It is divided by 3 for the 4.77 MHz CPU core, and by 12 for the 1.19 MHz PIT.
I think for an emulator it would be enough to have a 4.77 MHz base clock and divide it by 3 for the PIT.
You also need to feed 4.77 MHz to the CRTC I believe (in a real system it also takes this from the clock signal on the ISA bus, so it is synchronized. MDA/Hercules, EGA and VGA are not synchronized to the bus, but have their own crystal, so they work asynchronously. This means that you cannot write cycle-accurate code on them, because different machines have different crystals, and you get slight deviations).
superfury wrote:Edit: The problem with the PIT being faster than processor interrupts at 1.19MHz interrupts per second is also on real PCs? Since the interrupt handler takes longer than a PIT tick(with IF==0)?
Yes, basically if you set your timer interrupt too fast (or make your interrupt handler too long), you will hang the machine.
Edit: it might be useful to study the source of a C64 or Amiga emulator sometime.
As far as I know, nobody ever wrote a proper PC emulator. All emulators I've seen just emulate the different parts of a PC to a certain extent, but they make no attempt to emulate a *machine*, as in, how the different parts interact. There is no attempt to perform overall synchronization.
On a C64 or Amiga, you NEED to have synchronization, else a lot of things simply will not work. A lot of software depends on the video chip performing a certain operation at a certain CPU cycle, so your video chip emulation and CPU emulation have to be in perfect sync at all times in order to run this software.
8088 MPH might well be the only software in existence that does the same thing on the PC. It puts the same demands on emulation as C64/Amiga do (as well as various other home computers and consoles).
So looking at other PC emulators won't help you much, but looking at eg WinVice or WinUAE should give you some good ideas how they implemented the whole system (which is more than the sum of its parts). They emulate the individual chips, and also the internal buses, so the memory accesses of one chip can cause wait states for another chip.
The interesting thing is that if your PC emulator can do that, you can even emulate CGA snow accurately. CGA snow is basically CPU data that 'leaks' to the output circuitry in 80-column mode, because the access to memory is mutually exclusive, and the CPU overrides the data bus. The CGA card just sees whatever byte the CPU is trying to access at that moment, rather than the byte at the address it was trying to generate for its output.