VOGONS


First post, by DaveDDS

User metadata
Rank Oldbie
Rank
Oldbie

In case anyone else is interested:

While evaluating some 8086 PC/DOS emulators, I wrote a "quick and dirty"
tool to get a feel for how closely they could approximate the "real time"
of my actual DOS systems.

It is NOT a detailed instruction/timing analysis or test - all it does is
provide a feel for "how many instructions" are performed over 1 second
intervals.

It does have a few options for different ways of evaluating the passage
of time (can be trick to do accurately in some emulators), tweak it's
accuracy, test with simple/more-complex set of instructions etc.

Look for EPCEXTST.ZIP in the download area of my site.

Btw, I've included within EPCEXTST.TXT (it's document) the summary resuts
from running it on 5 of my "real" DOS systems, as well as 12 different
emulators (or at lease, different emulation settings of an emulator).

Additions to the summary list would be welcome!

Dave ::: https://dunfield.themindfactory.com ::: "Daves Old Computers"->Personal

Reply 1 of 7, by DaveDDS

User metadata
Rank Oldbie
Rank
Oldbie

Corrected some minor error/clarity in the description and help output.

Also fixed problem where ESC to cancel didn't work unless the timer was
"ticking" (eg: if you choose timing via speed of a COM port that's not
looped back to itself)

Dave ::: https://dunfield.themindfactory.com ::: "Daves Old Computers"->Personal

Reply 2 of 7, by oso2k

User metadata
Rank Newbie
Rank
Newbie

I see a reference to a
#include "R:\\Help.h"
in the source that isn't in the zip file.

Reply 3 of 7, by DaveDDS

User metadata
Rank Oldbie
Rank
Oldbie
oso2k wrote on 2025-06-05, 00:02:

I see a reference to a
#include "R:\\Help.h"
in the source that isn't in the zip file.

I have a tool (on my site) called "CHT" (C Help Text) which reads the /*Cht... comments in the source file
and create the .H file with the encoded text - R: is my RamDrive -adjust as needed.

Dave ::: https://dunfield.themindfactory.com ::: "Daves Old Computers"->Personal

Reply 4 of 7, by DaveDDS

User metadata
Rank Oldbie
Rank
Oldbie

Btw, I include the .C file so you can see exactly what it's doing.

Easiest to use the included .COM executable.

If you want to build my stuff (and don't want to do a lot of "porting"), you should use my tools,
most notably my "Micro-C/PC" compiler, and sometimes other of my tools (like CHT, HFC etc.)
best to refer to BUILD.TXT in my "source code" section.

Do be aware: A lot of my code was written 20+ years ago, and I still mainly use the same tools when
creating DOS stuff.

Dave ::: https://dunfield.themindfactory.com ::: "Daves Old Computers"->Personal

Reply 5 of 7, by superfury

User metadata
Rank l33t++
Rank
l33t++

What timing source does it use? CMOS, PIT, APIC, XTRTC or TSC?
UniPCemu can sync all to the CPU clock, or sync just the CMOS/XTRTC to the host time (updated at 32kHz intervals and read using the most accurate source it finds (gettimeofday or equivalent (nanoseconds), down to SDL as it's slowest source)).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 6 of 7, by DaveDDS

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on 2025-06-05, 06:51:

What timing source does it use?

It has several options and is pretty simple (quick & dirty test tool) - it also doesn't
try to achieve ms resolution... it's just trying to give an idea of "how fast"
code is executed so I can compare with "real" systems.

It can use the hardware RTC, the BIOS 55ms tick, the DOS time-of-day clock
.. these are all "inside" the emulation and may not be reliable when the emulator
"bogs down" - (hopefully the RTC is highest-priority, 55ms tick next-highest and
DOS TOD next... but you can never know (unless you wrote the emulator)

So.. my preferred (if the emulator supports it) is passthrough to a "real" COM port
which has been looped-back to itself (receives what it sends). The time it takes to
send a character is pretty deterministic - I operate the COM at 100bps, 10 bit characters
(start+stop+8data) which means a pretty reliable 10 "ticks"/second (outside of the
emulation) - COM ports are pretty simple/low code to talk to at a low level which means
that even a "bogged down" emulator should be fast enough to keep it "full" - and if I have
doubts I can scope the TX/RX signal to see exactly how fast it's ticking...

More information/detail is in a .TXT file that accompanies the tool.

Dave ::: https://dunfield.themindfactory.com ::: "Daves Old Computers"->Personal

Reply 7 of 7, by superfury

User metadata
Rank l33t++
Rank
l33t++

Also interesting, if it can use the CMOS BIOS interrupt (interrupt 1A calls), I also made a BIOS option ROM (2KB) for the PC/XT that adds function 2/3h GET/SET TIME function calls to the BIOS (it hooks interrupt 19h for initialization, interrupt 15h for it's data storage (hooked vectors using AX=FE00 to give DS:BX pointer to the data storage area inside itself) and interrupt 1Ah for the XT-RTC support. The data storage area is very small (2KB), containing the data area and a small INT15h handler (at it's base address) only, copied into the top of RAM from the option ROM, stealing it for it's use (using the BDA).
The data storage area contains an initialization flag and the hooked BIOS entry points.
It uses a clever stack setup to pass control to the BIOS and accesses it's private data area for the vectors using pushes, data movement, pops and finally flags and iret into the BIOS old handler.
Roughly the same otherwise, but to the caller without the bios override (functions 2/3).
The startup is simple: pushf for keeping flags for BIOS passthrough, retrieve it's data area and handle if it's range, otherwise passthrough (2 interrupt handlers in ROM, only INT15h in RAM).
https://bitbucket.org/superfury/unipcemu_pcxtbios_at/

The time handler can run multiple times only if time rollover happens while reading the XT-RTC fields, though. It basically resets the XT-RTC rollover flag before the loop, reads the date and time and then again reads the rollover flag. If it's indicating rollover happened (10us if I'm not mistaken), try again. Repeat until rollover doesn't happen. That way it ensures that the integrity of the read date/time is correct. Otherwise you can end up with weird rollover values (with lower and upper parts of the timestamp indicating different date or time periods for example, like 0:0:01.00.9 instead of 0:0:0:00.99.9 for example (hⓂ️s:s100.s10000) due to rollover when reading the timestamp from the chip (it has no read latching, only write latching of sorts (the "go" command, executed during a "set date/time" in INT 1Ah))).
Those can happen more frequently on slow processors though, but not often.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io