Archives
- April 2025
- March 2025
- February 2025
- January 2025
- December 2024
- November 2024
- October 2024
- September 2024
- August 2024
- July 2024
- June 2024
- May 2024
- April 2024
- March 2024
- February 2024
- January 2024
- October 2023
- September 2023
- August 2023
- July 2023
- June 2023
- May 2023
- April 2023
- March 2023
- January 2023
- December 2022
- November 2022
- October 2022
- September 2022
- July 2022
- June 2022
- May 2022
- April 2022
- March 2022
- February 2022
- January 2022
- December 2021
- November 2021
- October 2021
- September 2021
- August 2021
- July 2021
- June 2021
- May 2021
- April 2021
- March 2021
- February 2021
- January 2021
- December 2020
- November 2020
- October 2020
- September 2020
- August 2020
- July 2020
- June 2020
- May 2020
- April 2020
- March 2020
- February 2020
- January 2020
- December 2019
- November 2019
- October 2019
- September 2019
- August 2019
- July 2019
- June 2019
- May 2019
- April 2019
- March 2019
- February 2019
- January 2019
- December 2018
- November 2018
- October 2018
- August 2018
- July 2018
- June 2018
- May 2018
- April 2018
- March 2018
- February 2018
- January 2018
- December 2017
- November 2017
- October 2017
- August 2017
- July 2017
- June 2017
- May 2017
- April 2017
- March 2017
- February 2017
- January 2017
- December 2016
- November 2016
- October 2016
- September 2016
- August 2016
- July 2016
- June 2016
- May 2016
- April 2016
- March 2016
- February 2016
- January 2016
- December 2015
- November 2015
- October 2015
- September 2015
- August 2015
- July 2015
- June 2015
- May 2015
- April 2015
- March 2015
- February 2015
- January 2015
- December 2014
- November 2014
- October 2014
- September 2014
- August 2014
- July 2014
- June 2014
- May 2014
- April 2014
- March 2014
- February 2014
- January 2014
- December 2013
- November 2013
- October 2013
- September 2013
- August 2013
- July 2013
- June 2013
- May 2013
- April 2013
- March 2013
- February 2013
- January 2013
- December 2012
- November 2012
- October 2012
- September 2012
- August 2012
- July 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- January 2012
- December 2011
- November 2011
- October 2011
- September 2011
- August 2011
- July 2011
- June 2011
- May 2011
- April 2011
- March 2011
- January 2011
- November 2010
- October 2010
- August 2010
- July 2010
Undocumented RDTSC
The other day I wrote a simple DOS program which used the RDTSC instruction in order to obtain precise time measurements (of how long it takes a PS/2 keyboard to send data; more about that some other time). The 16-bit DOS program worked fine in a VM running PC DOS 2000, as well as in NTVDM on Windows running on a system with a Core 2 class CPU. But when I tried running it on an old IBM ThinkPad 760XL laptop with a 166 MHz Pentium MMX processor running PC DOS 2000, it just hung when executing RDTSC. Unless I disabled EMM386, and then it worked fine.
That was a bit of a mystery. The Pentium MMX does obviously support the RDTSC instruction. The only troublesome possibility would be if perhaps someone set the CR4.TSD bit (the Time Stamp Disable bit) which would cause RDTSC (and RDTSCP on newer CPUs which support it) to #GP fault outside of ring 0. But old EMM386 does not even touch CR4, and at any rate the same program with the same EMM386 version worked on a newer CPU. Could the ThinkPad’s BIOS be setting CR4.TSD?
A quick experiment showed that no, the ThinkPad’s BIOS does not set CR4.TSD. But unless CR4.TSD is set, the Intel SDM clearly documents RDTSC to work in V86 mode without any problem! Given that RDTSC only works on registers, it essentially cannot fail.
And yet it did on the Pentium MMX. Okay, clearly something is amiss. What did Intel’s Pentium documentation say? Let’s check the original Pentium Processor Family Developer’s Manual, Volume 3: Architecture and Programming Manual (Intel document order number 241430-004, 1995). RDTSC is documented on page 25-264.
Wow, look at that: Virtual 8086 Mode Exceptions: #GP(0) if instruction execution is attempted! That would certainly explain why RDTSC refuses to work on the Pentium CPU with EMM386. Intel completely fails to document this behavior in the current SDM, which is supposed to cover the Pentium. Good thing the old documentation survived.
So what is going on? Not surprisingly, I’m not the only one who noticed this oddity recently, although in that case the author incorrectly concluded that it’s somehow related to a specific EMM386 version, rather than the CPU model (to be fair, EMM386 could handle RDTSC in V86 mode, but clearly EMM386 versions at least from the mid-1990s don’t).
Fortunately, this problem was noticed in the old days as well, and there’s an explanation for the strange misbehavior. According to unverified but very plausible information, Intel’s design was to have RDTSC working in V86 mode, which really makes perfect sense. But due to a misunderstanding, RDTSC cannot be used in V86 mode on the Pentium. Whatever the real reason, the Pentium documentation does accurately describe the actual behavior.
On the Pentium Pro (and all subsequent Intel CPUs), RDTSC works as originally intended and can be used in V86 mode (subject to CR4.TSD). Since the current SDM evolved from the Pentium Pro/Pentium II documentation, the Pentium behavior was forgotten and left out (it’s not mentioned in the Pentium Pro documentation because users were expected to look at the separate Pentium documentation).
In the original 1993 Pentium documentation, RDTSC was documented in the infamous Appendix H, so it’s difficult to check exactly what the documentation said.
It is notable that the AMD K5/5k86 is documented to behave like the Intel Pentium (RDTSC always faults in V86 mode). The behavior of AMD K6 and K7 CPUs is not entirely clear. All AMD64 processors are documented to behave the same as modern Intel processors, i.e. RDTSC is supported in V86 mode.
Cyrix introduced RDTSC in the 6x86MX processor (1997). Cyrix documentation implies that RDTSC should be usable in V86 mode. IDT likewise makes no mention that RDTSC should be unusable in V86 mode.
Conclusion: The RDTSC instruction cannot be used in V86 mode on a set of older processors which includes the Intel Pentium (but not Pentium Pro and later), AMD K5, and possibly some other processors. On modern CPUs this restriction does not exist.
15 Responses to Undocumented RDTSC
I think old EMM386 did handle RDMSR.
Yes, that occurred to me too. So maybe reading MSR 10h can be used as an alternative.
I wonder what was the first version of EMM386 that did it though.
EMM386 4.48 (MS-DOS 6.2 and PC DOS 6.3)
Interesting. I should throw together a test case and see if NEC’s fork of EMM386 supported it. It has some very different options from regular EMM386, particularly support for exclusions in two different memory map modes for “high resolution” systems.
Try JEMM386 on the laptop, and see what happens.
techfury90,
Are you referring to the PC98 version of EMM386 ? Theoretically it should have been derived from the standard MS-DOS version of EMM386. Granted PC98 hardware is different from PC hardware but the GP handler code should be the same.
By the way do you have older PC98 software ? If so then could you check if MS-DOS 2.25 ran on that platform ? Supposedly MS-DOS 2.25 was done for some Far East OEM.
I’ll let someone else do that. The result is not really relevant to me, what matters for me is that on a Pentium CPU, RDTSC can’t be expected to be usable in V86 mode. If that works in some specific configurations that’s great, but unfortunately doesn’t help me much.
dosfan- Yes, the PC-98 one. I have some older versions of DOS. Mainly 3.x, but I have two revisions of Epson-branded 2.11 and NEC’s 2.11 (the initial public PC-98 DOS release from 1983: note that DOS was actually ported after the PC-9801 went on sale)
At one point, I theorized that the Epson 2.11 release may have really been 2.25 under the covers since it wasn’t released until 1988. That was proven false when I tracked it down. I believe Michal said that most of the extant information relating to 2.25 hints that it would have been a Korean-market release (presence of the word Hangul in documentation et al), and I’m inclined to agree. I cannot find any conclusive evidence of any Japanese OEM using it, they all used 2.11 (initial release with Japanese support) or 3.x. However, it appears that at least some versions of PC-98 DOS (at least 3.3 and later, earlier has not been tested but Japanese sources say 3.2 doesn’t have it) have the DBCS lead byte table function that was added in 2.25. However, none of the official documentation from ASCII/MS or NEC makes any reference to this function. I was actually unable to find any Japanese primary source that mentions that function as well, at least sifting through about a dozen dead tree/PDF sources. So, I’m pretty sure Korea is where one needs to be looking for 2.25.
techfury90,
You are correct, INT 21h function 63h was originally called “Hongeul” (there’s an old DOS 3.1 “SYSTEM3.DOC” which mentions this) but this was changed to ECS_Call in later versions. How big was the South Korean PC market in the mid-80s ? I’m starting to wonder if MS-DOS 2.25 was ever released since there seems to be no evidence that it did.
Back to RDTSC, I vaguely remember reading something about RDTSC not working in V86 mode on the Pentium being an error. The whole point of having a separate opcode to read the TSC was for it to be usable regardless of CPL as opposed to RDMSR/WRMSR.
That’s the mystery. I suspect it was actually released, but didn’t sell many copies. As I understand things, 2.25 would have been released sometime around 1984-1985. There is evidence that Korean OEMs like Samsung and GoldStar (present-day LG) started producing PCs around this time, and they were being exported to the US around the same time.
We do know that they had special video cards designed around Korean text support, as later versions of Korean DOS used them, eventually switching over to software-based support using VESA graphics modes. My knowledge stops right here, however. I can only read and write English, German, and Japanese, so sifting through Korean sources is sadly pretty much out of the picture for the most part.
Regarding the size of the market: I think that might be an explanation for why we have not seen 2.25. I do not have figures for the Korean market, but it seems to have “started” in the mid-1980s, right around the time of 2.25’s theoretical release. It is important to consider a few facts, however: in the 1980s, South Korea was still a (rapidly) developing economy. I doubt consumer disposable income had risen to appropriate levels for PCs to be affordable to the average citizen at this point. I just looked for numbers and found a 1987 NY Times article that states that at the time, South Korean household incomes were an eighth of that of US or Japanese households, on average. Obviously, this is not the case anymore, but would explain the rarity of 2.25: not many copies were sold except to business users, almost certainly.
Samsung and Goldstar (LG = Lucky Goldstar, btw) certainly produced semiconductors in the second half of the 80’s. I remember building electronic stuff in the late 80’s and got Samsung and Goldstar parts from a locally well renowned distributor. But that was simpler parts like voltage regulators, 74xx logic and so on. Hundai however made atleast SRAMs at about that time. So they probably had most of the technology to make PC’s without importing that much stuff, thus it seems likely that they actually started making PC’s.
But I wounder how important language support in DOS were?
Leading Edge Model D is the proof in the pudding: Daewoo manufactured it in South Korea for Leading Edge and it was launched in the US in 1985.
It would be interesting to see how the South Korean semiconductor business got started. If it’s anything like most of their electronics industry and heavy industry in general, I suspect they had considerable amounts of help from the Japanese semiconductor manufacturers. Example: Kia cars were originally license-built Mazdas. Samsung TVs? Product of a 1970 partnership with NEC to acquire CRT technology. The list goes on and on; I suspect they probably sold them all the equipment and designs necessary.
WRT language support: I truly don’t know. Nor am I exactly certain how many parts of DBCS support in CJK variants of DOS comes from DOS inasmuch as the OEM extensions left and right.
On the PC-98, we have a driver called KKCFUNC.SYS that provides an API that is then used by your FEP/IME (front end processor/input method editor, common choices are NECAI, ATOK, and VJE) to hook into the console input routines and such. The FEP handles the actual input, but KKCFUNC provides the API they hook onto. As I understand it, it’s totally different on DOS/V and (at least later versions of) Korean DOS: they have all sorts of display driver/font stuff that PC-98 users didn’t have, as the PC-98’s character ROM contains the complete JIS character set, and the display hardware fully supports mixed 1/2 byte characters.
The other thing, now that I think of it: DOS on the PC-98 doesn’t actually have much in the way of DBCS functions. Every PC-98 programming book has an entire chapter on dealing with DBCS strings and conversions between the different encoding schemes.
DOS still needs to handle file names, and at a minimum it needs to not freak out when presented with DBCS characters. It’s true that the OS as such does very little when it comes to inputting and displaying the characters.
FWIW, Japan was one of the first foreign countries Microsoft was interested in, that goes back at least to the early 1980s and is the reason for things like MSX.
Korea has much in common with Japan (just don’t tell either of them…) and the way the government supports industry is similar in both countries. I’d be shocked if, like in Japan, the semicon industry in Korea wasn’t part of gigantic conglomerates from the earliest days.
This site uses Akismet to reduce spam. Learn how your comment data is processed.