Quote
In article <363139F8.BD375...@pc.jaring.my>, Leo <kpc...@pc.jaring.my> wrote:
>Urgent! Help!
>I'm using Turbo Pascal 7.0 on my brand new PC (Celeron 300Mhz, Windows
>98) and just unable to compile or run (Ctrl+F9) any of my previous
>program including the examples came together with Turbo Pascal 7.0.
>I even tried on my friend's PC (Pentium II 350Mhz, Window 98), still
>recieving the same runtime error (Error 200 : Division by Zero).
>At first I thought it was my new OS - Windows 98 (I used to use Win95 on
>my old Pentium 200Mhz PC) but most of my friend have no problem running
>Turbo Pascal 7.0 (Compile or Run Program) under Windows 98 with their
>Pentium (P5) base PC.
>Could it be cause by Intel P6 new architecture or P6 motherboard???
This is a VFAQ. It seems to be asked twice a day currently. Please try
to read before you post. The error is caused by a bug in the delay
calibration routine in the initialization code of the CRT unit. On fast
CPUs it causes division overflow which TP understands as division by
zero.
Here is one solution. Use this unit before you use CRT. If you need
Delay, call it in a loop Dfix times.
Unit Fdelay; { Use this before CRT }
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.
Osmo