Need to Run DOS Testing Program in XP Pro

M

Mike

Hi, at workk our PCs are running XP Pro sp2. We need to run a circa 1998
psychological testing program on PCs running XP Pro sp2. When I attempt to
runing the DOS program from the Run Line (Start\Run\CMD\) T The
program won't run. but the following error message is generated:

runtime error 200 at 33d4:0091

I googled the error messagew but didn't get any links.

Any suggestions what I need to do to get this program working?
 
C

Carey Frisch [MVP]

Error message when you install or start a MS-DOS or
16-bit Windows-based program
http://support.microsoft.com/default.aspx?scid=kb;en-us;324767

How to Troubleshoot 16-Bit Windows Programs in Windows XP
http://support.microsoft.com/default.aspx?scid=kb;en-us;314495

How to use the Program Compatibility Wizard in Windows XP
http://support.microsoft.com/default.aspx?scid=kb;en-us;301911

--
Carey Frisch
Microsoft MVP
Windows - Shell/User
Microsoft Community Newsgroups
news://msnews.microsoft.com/

-------------------------------------------------------------------------------------------

:

| Hi, at workk our PCs are running XP Pro sp2. We need to run a circa 1998
| psychological testing program on PCs running XP Pro sp2. When I attempt to
| runing the DOS program from the Run Line (Start\Run\CMD\) T The
| program won't run. but the following error message is generated:
|
| runtime error 200 at 33d4:0091
|
| I googled the error messagew but didn't get any links.
|
| Any suggestions what I need to do to get this program working?
 
A

ANONYMOUS

Is the prgram written n Borland/Turbo Pascal? If so then the error
relates to using a dos program (in particular crt Unit) on fast PCs. I
think there is a patch for it. I will sarch for it and come back to
you.

Regards,
 
A

ANONYMOUS

I found the solution. It is this (Please pass this info to the
programmer so that he would know how to fix it):


From (e-mail address removed) Wed Oct 27 05:24:00 2004
Subject: Crt.delay problem on a fast PC
Date: Wed, 27 Oct 2004 05:24:00
From: (e-mail address removed) (Timo Salmi)

124. *****

Q: Curing Crt initialization runtime error 200 on fast machines

A: I was not familiar with this problem myself since I have run
only sub-200MHz PCs, but I'll store here what I learned from the
excellent discussion on the subject in by programmers much more knowledgeable than I. First of all the Crt
initialization crash only concerns TP and BP bersions 7.00 and 7.01.
Quoting Osmo Ronkanen: "The earlier versions had a bug that caused
only delays to be too slow from machines 386-33 or so on. This was
fixed in version 7.0 and the fix caused a new bug i.e. the division
by zero error on machines that were 55 times faster than the ones on
which the old bug appeared."
First some references. Please be aware that I can't guarantee
that the URL addresses below will stay current.

Prevent the "Divide by 0" error, Roger Donais. You'll need
ftp://users.southeast.net/private/rdonais/rdelay.zip
ftp://users.southeast.net/private/rdonais/util.zip

NewDelay, Fix for bug in Crt unit's Delay procedure, by F.Heckenbach
http://fjf.gnu.de/programs.html#NewDelay

Problems with the Crt.Delay procedure, by Dr John Stockton
http://www.merlyn.demon.co.uk/pas-r200.htm

Fix for "Runtime Error 200" bug of Borland Pascal 7 on fast PCs,
by Klaus Hartnegg
http://www.brain.uni-freiburg.de/~klaus/pascal/runerr200/

ERROR 200:Div. by zero
A posting in http://www.deja.com/getdoc.xp?AN=721178015

Roger's solution is also available as (or whichever version numbers
are current when you read this):
4903 Jan 20 1997 ftp://garbo.uwasa.fi/pc/turbopas/rdelay10.zip
rdelay10.zip Prevent the divide-by-0 Crt error on fast machines,
R.Donais
:
56849 Jun 21 1997 ftp://garbo.uwasa.fi/pc/turbopas/rutil10.zip
rutil10.zip Turbo Pascal utilities by R.Donais, (needed by rdelay)

Then there also is
ftp://garbo.uwasa.fi/pc/turbspec/bp7patch.zip
CRT Delay patch for TURBO.TPL 48,432 10-27-92 7:00a
and probably later versions in circulation. Furthermore, there is a
replacement
30394 Aug 14 1999 ftp://garbo.uwasa.fi/pc/turbopas/crt.zip
crt.zip Replacement CRT units for Turbo/Borland Pascal, P.Scragg

The bug is in the Crt routine's initialization code. For example
Osmo Ronkanen writes "In the initialization code TP runs the delay
loop for one clock cycle. Then the result is divided by 55
(milliseconds in the cycle) to get loop size for one millisecond
delay. Now if that becomes greater than 65535 then the divide
overflow interrupt is called and that causes the runtime error to be
signaled." Dr John Stockton wrote "... initialize contains the
dreaded MOV 55 ; DIV CX"

A trivial solution to the problem is not to use the Crt unit at
all and to use the 'Wait' procedure from the item "If Delay
procedure does not work properly, how do I fix it?" instead of the
Crt.Delay.
Frank Heckenbach wrote about the 'Wait' procedure. "Besides the
fact that it doesn't prevent the runtime error 200 [if uses Crt is
included], as Osmo explained, this version's accuracy is only 1/18.2
seconds in contrast to 1 ms of the original Delay which should be
stuck to in replacements, IMHO."
Frank continued: "I'd also like to draw your attention to another
problem that the above version as well as the original Delay code
suffer from, namely busy waiting, this means executing some code
during the most time of the delay. Whereas this doesn't matter on a
single tasking DOS, it will significantly reduce the CPU time
available to other processes when run under multi tasking OS's. (And
such environments should really be taken into account these days.)"

Osmo Ronkanen posted the following solution for TP 7.0 which is
brief enough to be included in here. Osmo wrote about its previous
version: "[This runtime fix] does not disable delay. Delay works
just as it does before on machines that are slower than those that
cause problem. On faster machines it also works but as the counter
is set to 65535 instead of its true value of that would be something
higher the delays get slower and slower. So on machines that are
twice as fast as the ones that just cause the error the delays are
half as log as they should be." (Timo's addition. If the resolution
of 'Wait' procedure is sufficient for the programmer's purposes,
then it is better to use FDelay+Wait than FDelay+Delay.)

Unit Fdelay; { Place this before CRT. Real mode only }
interface
const dfix:word=1; { call delay() dfix times }

implementation
uses dos;

procedure oldints; assembler; { "variables" in the code segment }
asm dd 0,0 end;
Procedure error;
begin
runerror(200);
End;

Procedure Int0; assembler;
asm
cmp cx,55 { If CX<>55 we are at some other point }
je @ok
sti
call error
@ok:
shr dx,1 { divide dx:ax by 2 }
rcr ax,1
shl Dfix,1 { multiply Dfix by 2 }
iret { return to the DIV (286+) }
end;

{ Int21h handler removes the int0 handler (as well as itself) from
the memory when CtrlBreak vector is set by CRT right after
calculating the delay counter. Note DS does NOT point to the data
segment when this is called }

Procedure Int21h; assembler;
asm
cmp ax,$251B
jne @old { Not setint 1Bh? }
push es; push si; push di
mov si,offset oldints
xor di,di
mov es,di
cld
segcs; movsw
segcs; movsw { restore int 0 }
mov di,$21*4
segcs; movsw { restore int 21h }
segcs; movsw
pop di; pop si; pop es
@old: db $2e,$ff,$2e { jmp far indirect cs:[oldints+4] }
dw offset oldints+4
end;

type tr=record int0,int21:pointer; End;
pr=^tr;

begin
GetIntVec(0,pr(@oldints)^.int0);
GetIntVec($21,pr(@oldints)^.int21);
SetIntVec(0,@int0);
SetIntVec($21,@int21h);
end.

Roger Donais emailed me the following version based on Osmo's codes.
It is for TP 4.0-7.0. Just put
uses FDelay, Crt;
at the top of your program. Nothing else is needed. Not even a call
at the beginning of the main program. This is a nice end result of
the concerted efforts of the newsgroup.
Please note, however, that the code below does not have all the
safeguards that the code above does according to its author.
UNIT FDelay;
{ Purpose is to intercept 1st divide by zero error and if it appears
it could be from CRT to allow it to pass thereby allowing TP 7.0
(real mode) to use CRT (w/o delay) on systems with fast processors.
This solution will not work w/ multiple divide by 0 errors and may
leave the system unstable if an error occurs during TP exit process.
}

INTERFACE
USES DOS;

IMPLEMENTATION

VAR Old0 : Pointer;
TPExit: Pointer;

PROCEDURE Int0 (Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP
: Word); interrupt;
BEGIN
SetIntVec(0, Old0);
If CX = 55 Then Begin
AX := 65535;
DX := 54;
End; { Else error recurs w/ original int0 handler }
END;

PROCEDURE OnExit; FAR;
BEGIN
ExitProc := TPExit;
SetIntVec(0, Old0);
END;

BEGIN
GetIntVec(0, Old0);
SetIntVec(0, @Int0);
TPExit := ExitProc;
ExitProc := @OnExit;
END.

If you wish to solve the problem by not using the Crt unit at all,
below is a list of all the Crt unit procedures and functions and the
replacements that yours truly (Timo) has released or that can be
found in the FAQ.
Crt Replacement Where
--- ----------- -----
AssignCrt .. ..
ClrEol .. ..
ClrScr ClrScreen,CLS,CLS40 FAQ #117
Delay Wait FAQ #67
DelLine .. ..
GotoXY GOATXY TSUNTG in tspa*.zip
HighVideo .. ..
InsLine .. ..
KeyPressed KEYPREFN TSUNTM in tspa*.zip
LowVideo .. ..
NormVideo .. ..
NoSound .. ..
ReadKey READKEFN,RDENKEFN TSUNTM in tspa*.zip
Sound AUDIO TSUNTD in tspa*.zip
TextBackground ..
TextColor ..
TextMode TextSet /pc/turbopa7/textset.zip
WhereX WHEREXFN TSUNTG in tspa*.zip
WhereY WHEREYFN TSUNTG in tspa*.zip
Window ..

Q2: If the delay() statement isn't called, does the code compile
bad anyway?

A2: Had you first carefully read the first part of this FAQ item
#124 "Curing Crt initialization runtime error 200 on fast machines"
you would have noted "The bug is in the [TP7] Crt routine's
initialization code". It is NOT calling delay() that causes the
error. It is the "Uses Crt". Thus you can't avoid the problem by
just not using delay() if you insert the Crt unit into a TP 7.0
program on a fast PC. The error is a Crt initialization error, not a
delay() error. The (further) problem with delay() is that it can be
inaccurate. That aspect is covered in the item #67 "If Delay
procedure does not work properly, how do I fix it?".

A3: A terminology comment from Paul Schlyter: "BTW it's not really
a "divide by 0", but rather a division overflow, where the 32-bit
numerator divided by the 16-bit denominator makes the quotient
overflow 16 bits. However, the same hardware interrupt is generated
for division overflow as for division by zero."

A4: If you have an executable with this error but you do not have
the source code to recompile, see
3511 Feb 1 1999 ftp://garbo.uwasa.fi/pc/turbopa7/tfix.zip
tfix.zip Loader source to avoid TP 7.0 Crt RTE200, Osmo Ronkanen
or
20739 Sep 6 2000 ftp://garbo.uwasa.fi/pc/turbopa7/crtfix15.zip
crtfix15.zip Borland Pascal Crt unit RTE 200 fix, freeware, E.Toder

A5: Also see the (further) references in the mini-FAQ regularly
posted by Pedt Scragg to
 
M

Mike

It's a psychological testing program from a small shop circa 1998.
No telling what it was written it thaT I know of.

Mike
 
M

Mike

The program has not been supported by the vendor for a long several years,
but I'll pas it onto to them.

I remember years a go, there where programs out there that would fool the
DOS program
to run on (then) fast PCs.

Mike



ANONYMOUS said:
I found the solution. It is this (Please pass this info to the
programmer so that he would know how to fix it):


From (e-mail address removed) Wed Oct 27 05:24:00 2004
Subject: Crt.delay problem on a fast PC
Date: Wed, 27 Oct 2004 05:24:00
From: (e-mail address removed) (Timo Salmi)

124. *****

Q: Curing Crt initialization runtime error 200 on fast machines

A: I was not familiar with this problem myself since I have run
only sub-200MHz PCs, but I'll store here what I learned from the
excellent discussion on the subject in by programmers much more knowledgeable than I. First of all the Crt
initialization crash only concerns TP and BP bersions 7.00 and 7.01.
Quoting Osmo Ronkanen: "The earlier versions had a bug that caused
only delays to be too slow from machines 386-33 or so on. This was
fixed in version 7.0 and the fix caused a new bug i.e. the division
by zero error on machines that were 55 times faster than the ones on
which the old bug appeared."
First some references. Please be aware that I can't guarantee
that the URL addresses below will stay current.

Prevent the "Divide by 0" error, Roger Donais. You'll need
ftp://users.southeast.net/private/rdonais/rdelay.zip
ftp://users.southeast.net/private/rdonais/util.zip

NewDelay, Fix for bug in Crt unit's Delay procedure, by F.Heckenbach
http://fjf.gnu.de/programs.html#NewDelay

Problems with the Crt.Delay procedure, by Dr John Stockton
http://www.merlyn.demon.co.uk/pas-r200.htm

Fix for "Runtime Error 200" bug of Borland Pascal 7 on fast PCs,
by Klaus Hartnegg
http://www.brain.uni-freiburg.de/~klaus/pascal/runerr200/

ERROR 200:Div. by zero
A posting in http://www.deja.com/getdoc.xp?AN=721178015

Roger's solution is also available as (or whichever version numbers
are current when you read this):
4903 Jan 20 1997 ftp://garbo.uwasa.fi/pc/turbopas/rdelay10.zip
rdelay10.zip Prevent the divide-by-0 Crt error on fast machines,
R.Donais
:
56849 Jun 21 1997 ftp://garbo.uwasa.fi/pc/turbopas/rutil10.zip
rutil10.zip Turbo Pascal utilities by R.Donais, (needed by rdelay)

Then there also is
ftp://garbo.uwasa.fi/pc/turbspec/bp7patch.zip
CRT Delay patch for TURBO.TPL 48,432 10-27-92 7:00a
and probably later versions in circulation. Furthermore, there is a
replacement
30394 Aug 14 1999 ftp://garbo.uwasa.fi/pc/turbopas/crt.zip
crt.zip Replacement CRT units for Turbo/Borland Pascal, P.Scragg

The bug is in the Crt routine's initialization code. For example
Osmo Ronkanen writes "In the initialization code TP runs the delay
loop for one clock cycle. Then the result is divided by 55
(milliseconds in the cycle) to get loop size for one millisecond
delay. Now if that becomes greater than 65535 then the divide
overflow interrupt is called and that causes the runtime error to be
signaled." Dr John Stockton wrote "... initialize contains the
dreaded MOV 55 ; DIV CX"

A trivial solution to the problem is not to use the Crt unit at
all and to use the 'Wait' procedure from the item "If Delay
procedure does not work properly, how do I fix it?" instead of the
Crt.Delay.
Frank Heckenbach wrote about the 'Wait' procedure. "Besides the
fact that it doesn't prevent the runtime error 200 [if uses Crt is
included], as Osmo explained, this version's accuracy is only 1/18.2
seconds in contrast to 1 ms of the original Delay which should be
stuck to in replacements, IMHO."
Frank continued: "I'd also like to draw your attention to another
problem that the above version as well as the original Delay code
suffer from, namely busy waiting, this means executing some code
during the most time of the delay. Whereas this doesn't matter on a
single tasking DOS, it will significantly reduce the CPU time
available to other processes when run under multi tasking OS's. (And
such environments should really be taken into account these days.)"

Osmo Ronkanen posted the following solution for TP 7.0 which is
brief enough to be included in here. Osmo wrote about its previous
version: "[This runtime fix] does not disable delay. Delay works
just as it does before on machines that are slower than those that
cause problem. On faster machines it also works but as the counter
is set to 65535 instead of its true value of that would be something
higher the delays get slower and slower. So on machines that are
twice as fast as the ones that just cause the error the delays are
half as log as they should be." (Timo's addition. If the resolution
of 'Wait' procedure is sufficient for the programmer's purposes,
then it is better to use FDelay+Wait than FDelay+Delay.)

Unit Fdelay; { Place this before CRT. Real mode only }
interface
const dfix:word=1; { call delay() dfix times }

implementation
uses dos;

procedure oldints; assembler; { "variables" in the code segment }
asm dd 0,0 end;
Procedure error;
begin
runerror(200);
End;

Procedure Int0; assembler;
asm
cmp cx,55 { If CX<>55 we are at some other point }
je @ok
sti
call error
@ok:
shr dx,1 { divide dx:ax by 2 }
rcr ax,1
shl Dfix,1 { multiply Dfix by 2 }
iret { return to the DIV (286+) }
end;

{ Int21h handler removes the int0 handler (as well as itself) from
the memory when CtrlBreak vector is set by CRT right after
calculating the delay counter. Note DS does NOT point to the data
segment when this is called }

Procedure Int21h; assembler;
asm
cmp ax,$251B
jne @old { Not setint 1Bh? }
push es; push si; push di
mov si,offset oldints
xor di,di
mov es,di
cld
segcs; movsw
segcs; movsw { restore int 0 }
mov di,$21*4
segcs; movsw { restore int 21h }
segcs; movsw
pop di; pop si; pop es
@old: db $2e,$ff,$2e { jmp far indirect cs:[oldints+4] }
dw offset oldints+4
end;

type tr=record int0,int21:pointer; End;
pr=^tr;

begin
GetIntVec(0,pr(@oldints)^.int0);
GetIntVec($21,pr(@oldints)^.int21);
SetIntVec(0,@int0);
SetIntVec($21,@int21h);
end.

Roger Donais emailed me the following version based on Osmo's codes.
It is for TP 4.0-7.0. Just put
uses FDelay, Crt;
at the top of your program. Nothing else is needed. Not even a call
at the beginning of the main program. This is a nice end result of
the concerted efforts of the newsgroup.
Please note, however, that the code below does not have all the
safeguards that the code above does according to its author.
UNIT FDelay;
{ Purpose is to intercept 1st divide by zero error and if it appears
it could be from CRT to allow it to pass thereby allowing TP 7.0
(real mode) to use CRT (w/o delay) on systems with fast processors.
This solution will not work w/ multiple divide by 0 errors and may
leave the system unstable if an error occurs during TP exit process.
}

INTERFACE
USES DOS;

IMPLEMENTATION

VAR Old0 : Pointer;
TPExit: Pointer;

PROCEDURE Int0 (Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP
: Word); interrupt;
BEGIN
SetIntVec(0, Old0);
If CX = 55 Then Begin
AX := 65535;
DX := 54;
End; { Else error recurs w/ original int0 handler }
END;

PROCEDURE OnExit; FAR;
BEGIN
ExitProc := TPExit;
SetIntVec(0, Old0);
END;

BEGIN
GetIntVec(0, Old0);
SetIntVec(0, @Int0);
TPExit := ExitProc;
ExitProc := @OnExit;
END.

If you wish to solve the problem by not using the Crt unit at all,
below is a list of all the Crt unit procedures and functions and the
replacements that yours truly (Timo) has released or that can be
found in the FAQ.
Crt Replacement Where
--- ----------- -----
AssignCrt .. ..
ClrEol .. ..
ClrScr ClrScreen,CLS,CLS40 FAQ #117
Delay Wait FAQ #67
DelLine .. ..
GotoXY GOATXY TSUNTG in tspa*.zip
HighVideo .. ..
InsLine .. ..
KeyPressed KEYPREFN TSUNTM in tspa*.zip
LowVideo .. ..
NormVideo .. ..
NoSound .. ..
ReadKey READKEFN,RDENKEFN TSUNTM in tspa*.zip
Sound AUDIO TSUNTD in tspa*.zip
TextBackground ..
TextColor ..
TextMode TextSet /pc/turbopa7/textset.zip
WhereX WHEREXFN TSUNTG in tspa*.zip
WhereY WHEREYFN TSUNTG in tspa*.zip
Window ..

Q2: If the delay() statement isn't called, does the code compile
bad anyway?

A2: Had you first carefully read the first part of this FAQ item
#124 "Curing Crt initialization runtime error 200 on fast machines"
you would have noted "The bug is in the [TP7] Crt routine's
initialization code". It is NOT calling delay() that causes the
error. It is the "Uses Crt". Thus you can't avoid the problem by
just not using delay() if you insert the Crt unit into a TP 7.0
program on a fast PC. The error is a Crt initialization error, not a
delay() error. The (further) problem with delay() is that it can be
inaccurate. That aspect is covered in the item #67 "If Delay
procedure does not work properly, how do I fix it?".

A3: A terminology comment from Paul Schlyter: "BTW it's not really
a "divide by 0", but rather a division overflow, where the 32-bit
numerator divided by the 16-bit denominator makes the quotient
overflow 16 bits. However, the same hardware interrupt is generated
for division overflow as for division by zero."

A4: If you have an executable with this error but you do not have
the source code to recompile, see
3511 Feb 1 1999 ftp://garbo.uwasa.fi/pc/turbopa7/tfix.zip
tfix.zip Loader source to avoid TP 7.0 Crt RTE200, Osmo Ronkanen
or
20739 Sep 6 2000 ftp://garbo.uwasa.fi/pc/turbopa7/crtfix15.zip
crtfix15.zip Borland Pascal Crt unit RTE 200 fix, freeware, E.Toder

A5: Also see the (further) references in the mini-FAQ regularly
posted by Pedt Scragg to
Is the prgram written n Borland/Turbo Pascal? If so then the error
relates to using a dos program (in particular crt Unit) on fast PCs. I
think there is a patch for it. I will sarch for it and come back to
you.

Regards,
 
A

ANONYMOUS

Mike,

I suggest ask them to send you the source code which I can help you to
recompile so that it works on all machines irrespective of speed.

I still write DOS programs using Turbo/Borland pascal mainly for
database manipulation.

If you want, we could reverse-engineer the program (but very risky
indeed) but it is now illegal to do so. In the 80s and 90s I got away
with many things but now I take extra special care in everything I do!!

Regards,


The program has not been supported by the vendor for a long several years,
but I'll pas it onto to them.

I remember years a go, there where programs out there that would fool the
DOS program
to run on (then) fast PCs.

Mike

ANONYMOUS said:
I found the solution. It is this (Please pass this info to the
programmer so that he would know how to fix it):


From (e-mail address removed) Wed Oct 27 05:24:00 2004
Subject: Crt.delay problem on a fast PC
Date: Wed, 27 Oct 2004 05:24:00
From: (e-mail address removed) (Timo Salmi)

124. *****

Q: Curing Crt initialization runtime error 200 on fast machines

A: I was not familiar with this problem myself since I have run
only sub-200MHz PCs, but I'll store here what I learned from the
excellent discussion on the subject in by programmers much more knowledgeable than I. First of all the Crt
initialization crash only concerns TP and BP bersions 7.00 and 7.01.
Quoting Osmo Ronkanen: "The earlier versions had a bug that caused
only delays to be too slow from machines 386-33 or so on. This was
fixed in version 7.0 and the fix caused a new bug i.e. the division
by zero error on machines that were 55 times faster than the ones on
which the old bug appeared."
First some references. Please be aware that I can't guarantee
that the URL addresses below will stay current.

Prevent the "Divide by 0" error, Roger Donais. You'll need
ftp://users.southeast.net/private/rdonais/rdelay.zip
ftp://users.southeast.net/private/rdonais/util.zip

NewDelay, Fix for bug in Crt unit's Delay procedure, by F.Heckenbach
http://fjf.gnu.de/programs.html#NewDelay

Problems with the Crt.Delay procedure, by Dr John Stockton
http://www.merlyn.demon.co.uk/pas-r200.htm

Fix for "Runtime Error 200" bug of Borland Pascal 7 on fast PCs,
by Klaus Hartnegg
http://www.brain.uni-freiburg.de/~klaus/pascal/runerr200/

ERROR 200:Div. by zero
A posting in http://www.deja.com/getdoc.xp?AN=721178015

Roger's solution is also available as (or whichever version numbers
are current when you read this):
4903 Jan 20 1997 ftp://garbo.uwasa.fi/pc/turbopas/rdelay10.zip
rdelay10.zip Prevent the divide-by-0 Crt error on fast machines,
R.Donais
:
56849 Jun 21 1997 ftp://garbo.uwasa.fi/pc/turbopas/rutil10.zip
rutil10.zip Turbo Pascal utilities by R.Donais, (needed by rdelay)

Then there also is
ftp://garbo.uwasa.fi/pc/turbspec/bp7patch.zip
CRT Delay patch for TURBO.TPL 48,432 10-27-92 7:00a
and probably later versions in circulation. Furthermore, there is a
replacement
30394 Aug 14 1999 ftp://garbo.uwasa.fi/pc/turbopas/crt.zip
crt.zip Replacement CRT units for Turbo/Borland Pascal, P.Scragg

The bug is in the Crt routine's initialization code. For example
Osmo Ronkanen writes "In the initialization code TP runs the delay
loop for one clock cycle. Then the result is divided by 55
(milliseconds in the cycle) to get loop size for one millisecond
delay. Now if that becomes greater than 65535 then the divide
overflow interrupt is called and that causes the runtime error to be
signaled." Dr John Stockton wrote "... initialize contains the
dreaded MOV 55 ; DIV CX"

A trivial solution to the problem is not to use the Crt unit at
all and to use the 'Wait' procedure from the item "If Delay
procedure does not work properly, how do I fix it?" instead of the
Crt.Delay.
Frank Heckenbach wrote about the 'Wait' procedure. "Besides the
fact that it doesn't prevent the runtime error 200 [if uses Crt is
included], as Osmo explained, this version's accuracy is only 1/18.2
seconds in contrast to 1 ms of the original Delay which should be
stuck to in replacements, IMHO."
Frank continued: "I'd also like to draw your attention to another
problem that the above version as well as the original Delay code
suffer from, namely busy waiting, this means executing some code
during the most time of the delay. Whereas this doesn't matter on a
single tasking DOS, it will significantly reduce the CPU time
available to other processes when run under multi tasking OS's. (And
such environments should really be taken into account these days.)"

Osmo Ronkanen posted the following solution for TP 7.0 which is
brief enough to be included in here. Osmo wrote about its previous
version: "[This runtime fix] does not disable delay. Delay works
just as it does before on machines that are slower than those that
cause problem. On faster machines it also works but as the counter
is set to 65535 instead of its true value of that would be something
higher the delays get slower and slower. So on machines that are
twice as fast as the ones that just cause the error the delays are
half as log as they should be." (Timo's addition. If the resolution
of 'Wait' procedure is sufficient for the programmer's purposes,
then it is better to use FDelay+Wait than FDelay+Delay.)

Unit Fdelay; { Place this before CRT. Real mode only }
interface
const dfix:word=1; { call delay() dfix times }

implementation
uses dos;

procedure oldints; assembler; { "variables" in the code segment }
asm dd 0,0 end;
Procedure error;
begin
runerror(200);
End;

Procedure Int0; assembler;
asm
cmp cx,55 { If CX<>55 we are at some other point }
je @ok
sti
call error
@ok:
shr dx,1 { divide dx:ax by 2 }
rcr ax,1
shl Dfix,1 { multiply Dfix by 2 }
iret { return to the DIV (286+) }
end;

{ Int21h handler removes the int0 handler (as well as itself) from
the memory when CtrlBreak vector is set by CRT right after
calculating the delay counter. Note DS does NOT point to the data
segment when this is called }

Procedure Int21h; assembler;
asm
cmp ax,$251B
jne @old { Not setint 1Bh? }
push es; push si; push di
mov si,offset oldints
xor di,di
mov es,di
cld
segcs; movsw
segcs; movsw { restore int 0 }
mov di,$21*4
segcs; movsw { restore int 21h }
segcs; movsw
pop di; pop si; pop es
@old: db $2e,$ff,$2e { jmp far indirect cs:[oldints+4] }
dw offset oldints+4
end;

type tr=record int0,int21:pointer; End;
pr=^tr;

begin
GetIntVec(0,pr(@oldints)^.int0);
GetIntVec($21,pr(@oldints)^.int21);
SetIntVec(0,@int0);
SetIntVec($21,@int21h);
end.

Roger Donais emailed me the following version based on Osmo's codes.
It is for TP 4.0-7.0. Just put
uses FDelay, Crt;
at the top of your program. Nothing else is needed. Not even a call
at the beginning of the main program. This is a nice end result of
the concerted efforts of the newsgroup.
Please note, however, that the code below does not have all the
safeguards that the code above does according to its author.
UNIT FDelay;
{ Purpose is to intercept 1st divide by zero error and if it appears
it could be from CRT to allow it to pass thereby allowing TP 7.0
(real mode) to use CRT (w/o delay) on systems with fast processors.
This solution will not work w/ multiple divide by 0 errors and may
leave the system unstable if an error occurs during TP exit process.
}

INTERFACE
USES DOS;

IMPLEMENTATION

VAR Old0 : Pointer;
TPExit: Pointer;

PROCEDURE Int0 (Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP
: Word); interrupt;
BEGIN
SetIntVec(0, Old0);
If CX = 55 Then Begin
AX := 65535;
DX := 54;
End; { Else error recurs w/ original int0 handler }
END;

PROCEDURE OnExit; FAR;
BEGIN
ExitProc := TPExit;
SetIntVec(0, Old0);
END;

BEGIN
GetIntVec(0, Old0);
SetIntVec(0, @Int0);
TPExit := ExitProc;
ExitProc := @OnExit;
END.

If you wish to solve the problem by not using the Crt unit at all,
below is a list of all the Crt unit procedures and functions and the
replacements that yours truly (Timo) has released or that can be
found in the FAQ.
Crt Replacement Where
--- ----------- -----
AssignCrt .. ..
ClrEol .. ..
ClrScr ClrScreen,CLS,CLS40 FAQ #117
Delay Wait FAQ #67
DelLine .. ..
GotoXY GOATXY TSUNTG in tspa*.zip
HighVideo .. ..
InsLine .. ..
KeyPressed KEYPREFN TSUNTM in tspa*.zip
LowVideo .. ..
NormVideo .. ..
NoSound .. ..
ReadKey READKEFN,RDENKEFN TSUNTM in tspa*.zip
Sound AUDIO TSUNTD in tspa*.zip
TextBackground ..
TextColor ..
TextMode TextSet /pc/turbopa7/textset.zip
WhereX WHEREXFN TSUNTG in tspa*.zip
WhereY WHEREYFN TSUNTG in tspa*.zip
Window ..

Q2: If the delay() statement isn't called, does the code compile
bad anyway?

A2: Had you first carefully read the first part of this FAQ item
#124 "Curing Crt initialization runtime error 200 on fast machines"
you would have noted "The bug is in the [TP7] Crt routine's
initialization code". It is NOT calling delay() that causes the
error. It is the "Uses Crt". Thus you can't avoid the problem by
just not using delay() if you insert the Crt unit into a TP 7.0
program on a fast PC. The error is a Crt initialization error, not a
delay() error. The (further) problem with delay() is that it can be
inaccurate. That aspect is covered in the item #67 "If Delay
procedure does not work properly, how do I fix it?".

A3: A terminology comment from Paul Schlyter: "BTW it's not really
a "divide by 0", but rather a division overflow, where the 32-bit
numerator divided by the 16-bit denominator makes the quotient
overflow 16 bits. However, the same hardware interrupt is generated
for division overflow as for division by zero."

A4: If you have an executable with this error but you do not have
the source code to recompile, see
3511 Feb 1 1999 ftp://garbo.uwasa.fi/pc/turbopa7/tfix.zip
tfix.zip Loader source to avoid TP 7.0 Crt RTE200, Osmo Ronkanen
or
20739 Sep 6 2000 ftp://garbo.uwasa.fi/pc/turbopa7/crtfix15.zip
crtfix15.zip Borland Pascal Crt unit RTE 200 fix, freeware, E.Toder

A5: Also see the (further) references in the mini-FAQ regularly
posted by Pedt Scragg to
Is the prgram written n Borland/Turbo Pascal? If so then the error
relates to using a dos program (in particular crt Unit) on fast PCs. I
think there is a patch for it. I will sarch for it and come back to
you.

Regards,

Mike wrote:

Hi, at workk our PCs are running XP Pro sp2. We need to run a circa
1998
psychological testing program on PCs running XP Pro sp2. When I
attempt to
runing the DOS program from the Run Line (Start\Run\CMD\) T
The
program won't run. but the following error message is generated:

runtime error 200 at 33d4:0091

I googled the error messagew but didn't get any links.

Any suggestions what I need to do to get this program working?
 
M

Manny Borges

google dosbox

--
Manny Borges
MCSE NT4-2003 (+ Security)
MCT, Certified Cheese Master

The pen is mightier than the sword, and considerably easier to write with.
-- Marty Feldman
 
M

Mike

Thanks Anonymous, but I've found this vendor holds that infomration very
tight.
I'll call them next week.

Mike

ANONYMOUS said:
Mike,

I suggest ask them to send you the source code which I can help you to
recompile so that it works on all machines irrespective of speed.

I still write DOS programs using Turbo/Borland pascal mainly for
database manipulation.

If you want, we could reverse-engineer the program (but very risky
indeed) but it is now illegal to do so. In the 80s and 90s I got away
with many things but now I take extra special care in everything I do!!

Regards,


The program has not been supported by the vendor for a long several
years,
but I'll pas it onto to them.

I remember years a go, there where programs out there that would fool the
DOS program
to run on (then) fast PCs.

Mike

ANONYMOUS said:
I found the solution. It is this (Please pass this info to the
programmer so that he would know how to fix it):


From (e-mail address removed) Wed Oct 27 05:24:00 2004
Subject: Crt.delay problem on a fast PC
Date: Wed, 27 Oct 2004 05:24:00
From: (e-mail address removed) (Timo Salmi)

124. *****

Q: Curing Crt initialization runtime error 200 on fast machines

A: I was not familiar with this problem myself since I have run
only sub-200MHz PCs, but I'll store here what I learned from the
excellent discussion on the subject in by programmers much more knowledgeable than I. First of all the Crt
initialization crash only concerns TP and BP bersions 7.00 and 7.01.
Quoting Osmo Ronkanen: "The earlier versions had a bug that caused
only delays to be too slow from machines 386-33 or so on. This was
fixed in version 7.0 and the fix caused a new bug i.e. the division
by zero error on machines that were 55 times faster than the ones on
which the old bug appeared."
First some references. Please be aware that I can't guarantee
that the URL addresses below will stay current.

Prevent the "Divide by 0" error, Roger Donais. You'll need
ftp://users.southeast.net/private/rdonais/rdelay.zip
ftp://users.southeast.net/private/rdonais/util.zip

NewDelay, Fix for bug in Crt unit's Delay procedure, by F.Heckenbach
http://fjf.gnu.de/programs.html#NewDelay

Problems with the Crt.Delay procedure, by Dr John Stockton
http://www.merlyn.demon.co.uk/pas-r200.htm

Fix for "Runtime Error 200" bug of Borland Pascal 7 on fast PCs,
by Klaus Hartnegg
http://www.brain.uni-freiburg.de/~klaus/pascal/runerr200/

ERROR 200:Div. by zero
A posting in http://www.deja.com/getdoc.xp?AN=721178015

Roger's solution is also available as (or whichever version numbers
are current when you read this):
4903 Jan 20 1997 ftp://garbo.uwasa.fi/pc/turbopas/rdelay10.zip
rdelay10.zip Prevent the divide-by-0 Crt error on fast machines,
R.Donais
:
56849 Jun 21 1997 ftp://garbo.uwasa.fi/pc/turbopas/rutil10.zip
rutil10.zip Turbo Pascal utilities by R.Donais, (needed by rdelay)

Then there also is
ftp://garbo.uwasa.fi/pc/turbspec/bp7patch.zip
CRT Delay patch for TURBO.TPL 48,432 10-27-92 7:00a
and probably later versions in circulation. Furthermore, there is a
replacement
30394 Aug 14 1999 ftp://garbo.uwasa.fi/pc/turbopas/crt.zip
crt.zip Replacement CRT units for Turbo/Borland Pascal, P.Scragg

The bug is in the Crt routine's initialization code. For example
Osmo Ronkanen writes "In the initialization code TP runs the delay
loop for one clock cycle. Then the result is divided by 55
(milliseconds in the cycle) to get loop size for one millisecond
delay. Now if that becomes greater than 65535 then the divide
overflow interrupt is called and that causes the runtime error to be
signaled." Dr John Stockton wrote "... initialize contains the
dreaded MOV 55 ; DIV CX"

A trivial solution to the problem is not to use the Crt unit at
all and to use the 'Wait' procedure from the item "If Delay
procedure does not work properly, how do I fix it?" instead of the
Crt.Delay.
Frank Heckenbach wrote about the 'Wait' procedure. "Besides the
fact that it doesn't prevent the runtime error 200 [if uses Crt is
included], as Osmo explained, this version's accuracy is only 1/18.2
seconds in contrast to 1 ms of the original Delay which should be
stuck to in replacements, IMHO."
Frank continued: "I'd also like to draw your attention to another
problem that the above version as well as the original Delay code
suffer from, namely busy waiting, this means executing some code
during the most time of the delay. Whereas this doesn't matter on a
single tasking DOS, it will significantly reduce the CPU time
available to other processes when run under multi tasking OS's. (And
such environments should really be taken into account these days.)"

Osmo Ronkanen posted the following solution for TP 7.0 which is
brief enough to be included in here. Osmo wrote about its previous
version: "[This runtime fix] does not disable delay. Delay works
just as it does before on machines that are slower than those that
cause problem. On faster machines it also works but as the counter
is set to 65535 instead of its true value of that would be something
higher the delays get slower and slower. So on machines that are
twice as fast as the ones that just cause the error the delays are
half as log as they should be." (Timo's addition. If the resolution
of 'Wait' procedure is sufficient for the programmer's purposes,
then it is better to use FDelay+Wait than FDelay+Delay.)

Unit Fdelay; { Place this before CRT. Real mode only }
interface
const dfix:word=1; { call delay() dfix times }

implementation
uses dos;

procedure oldints; assembler; { "variables" in the code segment }
asm dd 0,0 end;
Procedure error;
begin
runerror(200);
End;

Procedure Int0; assembler;
asm
cmp cx,55 { If CX<>55 we are at some other point }
je @ok
sti
call error
@ok:
shr dx,1 { divide dx:ax by 2 }
rcr ax,1
shl Dfix,1 { multiply Dfix by 2 }
iret { return to the DIV (286+) }
end;

{ Int21h handler removes the int0 handler (as well as itself) from
the memory when CtrlBreak vector is set by CRT right after
calculating the delay counter. Note DS does NOT point to the data
segment when this is called }

Procedure Int21h; assembler;
asm
cmp ax,$251B
jne @old { Not setint 1Bh? }
push es; push si; push di
mov si,offset oldints
xor di,di
mov es,di
cld
segcs; movsw
segcs; movsw { restore int 0 }
mov di,$21*4
segcs; movsw { restore int 21h }
segcs; movsw
pop di; pop si; pop es
@old: db $2e,$ff,$2e { jmp far indirect cs:[oldints+4] }
dw offset oldints+4
end;

type tr=record int0,int21:pointer; End;
pr=^tr;

begin
GetIntVec(0,pr(@oldints)^.int0);
GetIntVec($21,pr(@oldints)^.int21);
SetIntVec(0,@int0);
SetIntVec($21,@int21h);
end.

Roger Donais emailed me the following version based on Osmo's codes.
It is for TP 4.0-7.0. Just put
uses FDelay, Crt;
at the top of your program. Nothing else is needed. Not even a call
at the beginning of the main program. This is a nice end result of
the concerted efforts of the newsgroup.
Please note, however, that the code below does not have all the
safeguards that the code above does according to its author.
UNIT FDelay;
{ Purpose is to intercept 1st divide by zero error and if it appears
it could be from CRT to allow it to pass thereby allowing TP 7.0
(real mode) to use CRT (w/o delay) on systems with fast processors.
This solution will not work w/ multiple divide by 0 errors and may
leave the system unstable if an error occurs during TP exit process.
}

INTERFACE
USES DOS;

IMPLEMENTATION

VAR Old0 : Pointer;
TPExit: Pointer;

PROCEDURE Int0 (Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP
: Word); interrupt;
BEGIN
SetIntVec(0, Old0);
If CX = 55 Then Begin
AX := 65535;
DX := 54;
End; { Else error recurs w/ original int0 handler }
END;

PROCEDURE OnExit; FAR;
BEGIN
ExitProc := TPExit;
SetIntVec(0, Old0);
END;

BEGIN
GetIntVec(0, Old0);
SetIntVec(0, @Int0);
TPExit := ExitProc;
ExitProc := @OnExit;
END.

If you wish to solve the problem by not using the Crt unit at all,
below is a list of all the Crt unit procedures and functions and the
replacements that yours truly (Timo) has released or that can be
found in the FAQ.
Crt Replacement Where
--- ----------- -----
AssignCrt .. ..
ClrEol .. ..
ClrScr ClrScreen,CLS,CLS40 FAQ #117
Delay Wait FAQ #67
DelLine .. ..
GotoXY GOATXY TSUNTG in tspa*.zip
HighVideo .. ..
InsLine .. ..
KeyPressed KEYPREFN TSUNTM in tspa*.zip
LowVideo .. ..
NormVideo .. ..
NoSound .. ..
ReadKey READKEFN,RDENKEFN TSUNTM in tspa*.zip
Sound AUDIO TSUNTD in tspa*.zip
TextBackground ..
TextColor ..
TextMode TextSet /pc/turbopa7/textset.zip
WhereX WHEREXFN TSUNTG in tspa*.zip
WhereY WHEREYFN TSUNTG in tspa*.zip
Window ..

Q2: If the delay() statement isn't called, does the code compile
bad anyway?

A2: Had you first carefully read the first part of this FAQ item
#124 "Curing Crt initialization runtime error 200 on fast machines"
you would have noted "The bug is in the [TP7] Crt routine's
initialization code". It is NOT calling delay() that causes the
error. It is the "Uses Crt". Thus you can't avoid the problem by
just not using delay() if you insert the Crt unit into a TP 7.0
program on a fast PC. The error is a Crt initialization error, not a
delay() error. The (further) problem with delay() is that it can be
inaccurate. That aspect is covered in the item #67 "If Delay
procedure does not work properly, how do I fix it?".

A3: A terminology comment from Paul Schlyter: "BTW it's not really
a "divide by 0", but rather a division overflow, where the 32-bit
numerator divided by the 16-bit denominator makes the quotient
overflow 16 bits. However, the same hardware interrupt is generated
for division overflow as for division by zero."

A4: If you have an executable with this error but you do not have
the source code to recompile, see
3511 Feb 1 1999 ftp://garbo.uwasa.fi/pc/turbopa7/tfix.zip
tfix.zip Loader source to avoid TP 7.0 Crt RTE200, Osmo Ronkanen
or
20739 Sep 6 2000 ftp://garbo.uwasa.fi/pc/turbopa7/crtfix15.zip
crtfix15.zip Borland Pascal Crt unit RTE 200 fix, freeware, E.Toder

A5: Also see the (further) references in the mini-FAQ regularly
posted by Pedt Scragg to

ANONYMOUS wrote:

Is the prgram written n Borland/Turbo Pascal? If so then the error
relates to using a dos program (in particular crt Unit) on fast PCs.
I
think there is a patch for it. I will sarch for it and come back to
you.

Regards,

Mike wrote:

Hi, at workk our PCs are running XP Pro sp2. We need to run a circa
1998
psychological testing program on PCs running XP Pro sp2. When I
attempt to
runing the DOS program from the Run Line (Start\Run\CMD\) T
The
program won't run. but the following error message is generated:

runtime error 200 at 33d4:0091

I googled the error messagew but didn't get any links.

Any suggestions what I need to do to get this program working?
 
M

Mike

That just might do it!

Mike

Manny Borges said:
google dosbox

--
Manny Borges
MCSE NT4-2003 (+ Security)
MCT, Certified Cheese Master

The pen is mightier than the sword, and considerably easier to write with.
-- Marty Feldman
 
M

Manny Borges

It is a sweet little program and it has made my life much simpler when
trying to support dos apps.

--
Manny Borges
MCSE NT4-2003 (+ Security)
MCT, Certified Cheese Master

The pen is mightier than the sword, and considerably easier to write with.
-- Marty Feldman
 
M

Mike

Haven't had a chance to try it yet.

Mike

Manny Borges said:
It is a sweet little program and it has made my life much simpler when
trying to support dos apps.

--
Manny Borges
MCSE NT4-2003 (+ Security)
MCT, Certified Cheese Master

The pen is mightier than the sword, and considerably easier to write with.
-- Marty Feldman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top