Hi,
while testing dos32a, dos4gw, cwsdpmi, cwstub, ... with the "pctest"
program which is part of either dos32a or cwsdpmi, I got a FreeDOS
(I guess) "illegal opcode 0f 31 ..." error message that killed pctest,
at least with some of those DOS extenders.
Now 0f 31 is "rdtsc" (read time stamp counter, the time stamp counter
is a 64bit counter of CPU cycles since reset). My processor is a
pentium-class one, but no actual Pentium, and it does not have a TSC.
So for my CPU, this is indeed an illegal instruction on my CPU.
My question: The message obviously occurs because those DOS extenders
fail to install their own illegal opcode handler. The offending code
looks like this (it is inside 32bit DPMI):
... install an timer int (IRQ 0 / int 8) handler that - I guess - counts
down or at least modifies a flag ... then program the timer chip, like this:
o 43 36
o 40 0
o 40 0
("speaking in debug language") ... then (using flat offsets of ndisasm -b32):
0000AF33 C605840900000A mov byte [0x984],0xa
0000AF3A B9FFFFFF07 mov ecx,0x7ffffff
0000AF3F FB sti
0000AF40 0F31 rdtsc
0000AF42 8BF0 mov esi,eax
0000AF44 8BFA mov edi,edx
0000AF46 803D8409000000 cmp byte [0x984],0x0
0000AF4D E0F7 loopne 0xaf46
0000AF4F 0F31 rdtsc
0000AF51 FA cli
0000AF52 2BC6 sub eax,esi
0000AF54 1BD7 sbb edx,edi
So now we have a 64bit count of how far the TSC got while waiting for that
timer chip event ...
0000AF56 8BEC mov ebp,esp
0000AF58 52 push edx
0000AF59 50 push eax
0000AF5A DF6DF8 fild qword [ebp-0x8]
0000AF5D DD058E090000 fld qword [0x98e]
0000AF63 DD0586090000 fld qword [0x986]
0000AF69 D9E8 fld1
0000AF6B DEF1 fdivrp st1
0000AF6D DEC9 fmulp st1
0000AF6F DEF9 fdivp st1,st0
0000AF71 DF7DF8 fistp qword [ebp-0x8]
0000AF74 58 pop eax
0000AF75 5A pop edx
... and finally we have ((1/[986])*[98e]) / that count
back in EDX:EAX (notice I am not sure about the order of
arguments in the divisions, I am not used to floating point
programming). I do not know the constants, sorry. The whole
subroutine finally returns EAX, which will probably be
something like "CPU cylces per second". By the way, the int
handler seems to be:
0000AF8A 1E push ds
0000AF8B 50 push eax
0000AF8C 2E8E1D96090000 mov ds,dword [cs:0x996]
0000AF93 FE0D84090000 dec byte [0x984]
0000AF99 B020 mov al,0x20
0000AF9B E620 out 0x20,al
0000AF9D 58 pop eax
0000AF9E 1F pop ds
0000AF9F CF iret
Okay, I was announcing a QUESTION. Do you think it makes sense
to simulate the TSC from DOS, even for DPMI ? We could for example
return 1000000 * timer ticks (the common 40:[6c] value...) or even
some more stupid value. Would that make sense??? Do you know of other
"TSC-less CPU helpers"?
I personally think that programs SHOULD first check for the existance
of the TSC before using it, but, well... some programs just fail to be
sane.
This ideas / questions / feature suggestions go to whoever knows a nice
solution and of course especially to the kernel people. I do not know of
any other DOS program that relies on the TSC but fails to check for its
existence, but this is probably because I only use pretty old DOS software
that is already happy with a 486 CPU.
Do not take this as an important feature request, but I would like some
feedback on this mail anyways...
Eric.
----------
list options/archives/etc.: http://www.topica.com/lists/fd-dev
unsubscribe: send blank email to: [EMAIL PROTECTED]
==^================================================================
This email was sent to: [email protected]
EASY UNSUBSCRIBE click here: http://topica.com/u/?bz8Rv5.bbRv4l.YXJjaGl2
Or send an email to: [EMAIL PROTECTED]
T O P I C A -- Register now to manage your mail!
http://www.topica.com/partner/tag02/register
==^================================================================