Board index » delphi » TP/BP7 CRT bug - no source code available - a possible fix

TP/BP7 CRT bug - no source code available - a possible fix

There have been a number of requests for solving the RTE 200 bug in the
CRT unit when source is not available.

ISTM that Osmo Ronkanen's code for the fdelay unit could also be used as
a program (similarly to the Loadfix program supplied with DOs 6.xx) to
intercept the relevant interrupts then release them when the TP/BP7
program loads.

Test code below. It works on my machine, some code could be, I'm sure,
improved - all thoughts welcomed. I will upload the source to a suitable
location when and if appropriate. I would appreciate anyone who is able
to test the code to do so.

Memory usage of 5760 bytes.

-------code follows-------------

{Heavily based on Osmo Ronkanen's Fdelay unit source}
{Osmo's comments on his code retained in the source }

{$A+,B-,D-,E-,F+,G,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+}
{$M 1300,0,0}

Program bpfix;

uses dos;

const dfix:word=1;       { call delay() dfix times }

var   st : string[130];
var   st1: string[64];
var   i  : byte;

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
     SwapVectors;        {we need our own $00 and $21 vectors}
                         {so swapvectors first}
     asm
        cli              {do not interrupt vector changes}
     end;
     GetIntVec(0,pr(@oldints)^.int0);
     GetIntVec($21,pr(@oldints)^.int21);

     SetIntVec(0,@int0);
     SetIntVec($21,@int21h);
     asm
        sti              {finish vector changes- allow interrupts}
     end;

     If paramcount = 0 then        {no parameters then exit}
     begin
          SwapVectors;             {restore vectors}
          exit
     end

     else if paramcount=1 then     {only program name given}
     begin
          st1 := fsearch(paramstr(1),getenv('path'));
          exec(st1,' ');
          swapvectors;             {restore vectors}
     end
     else
     begin                         {parameters have been provided}
          fillchar(st[0],131,#32);
          st[0] := #1;
          for i := 2 to paramcount do
          begin
               st1 := paramstr(i);
               move(st1[1],st[succ(length(st))],length(st1));
               inc(st[0],succ(length(st1)));
          end;
          st1 := fsearch(paramstr(1),getenv('path'));
          exec(st1,st);
          swapvectors;          {restore vectors}
     end;
end.

{Note: full name of program inc. extension must be given}

--
Pedt Scragg

Never challenge a porcupine to an ass-kicking contest

 

Re:TP/BP7 CRT bug - no source code available - a possible fix


In article <2RfxPAA3kDS2Y...@pedt.demon.co.uk>,
Pedt Scragg  <newsmas...@pedt.demon.co.uk> wrote:

Quote
>There have been a number of requests for solving the RTE 200 bug in the
>CRT unit when source is not available.

>ISTM that Osmo Ronkanen's code for the fdelay unit could also be used as
>a program (similarly to the Loadfix program supplied with DOs 6.xx) to
>intercept the relevant interrupts then release them when the TP/BP7
>program loads.

>Test code below. It works on my machine, some code could be, I'm sure,
>improved - all thoughts welcomed. I will upload the source to a suitable
>location when and if appropriate. I would appreciate anyone who is able
>to test the code to do so.

I have to test it.  I just made the same thing myself:

{$M 1100,0,0}

uses dos;  { better not use CRT :-) }

procedure oldints; assembler; { "variables" in the code segment }
          asm dd 0,0; db 0 end;

Procedure Int0; assembler;
          asm
          cmp byte ptr oldints+8,0     { Done with the fix? }
          jnz @old

          cmp cx,55       { If CX<>55 we are at some other point }
          jne @x
          cmp dx,cx       { If DX<CX we are at some other point }
          jae @ok

@x:       mov byte ptr oldints+8,1     { unexpected division overflow }
                                       { we probably have a slow machine }
                                       { and are done with the fix }

@old:     jmp dword ptr oldints

@ok:
          mov dx,54                    { slowest possible delay }
          mov ax,65535
          mov byte ptr oldints+8,1     { we are done with the fix }
          iret                         { return to the DIV (286+) }
          end;

Procedure Int21h; assembler;
          asm
          cmp byte ptr oldints+8,0
          jnz @old

          cmp ax,$2500
          jne @x
          mov word ptr oldints,dx
          mov word ptr oldints+2,ds
          iret

@x:
          cmp ax,$251B
          jne @old                      { Not setint 1Bh? }
          mov byte ptr oldints+8,1      { inavtivate! }

@old:     jmp dword ptr oldints+4

          end;

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

     ps=^string;

var i,j:integer;
    pname,cline:string[128];
    i21save,i00save:pointer;

begin
  cline:=ps(ptr(prefixseg,128))^;
  while (cline<>'') and (cline[1]=' ') do delete(cline,1,1);

  i:=1;
  while (i<=length(cline)) and (cline[i]<>' ') do inc(i);
  pname:=copy(cline,1,i-1);
  for j:=1 to length(pname) do pname[j]:=upcase(pname[j]);
  if copy(pname,length(pname)-3,4)<>'.EXE' then pname:=pname+'.EXE';
  pname:=fsearch(pname,getenv('path'));

  if pname<>'' then begin
     swapvectors;

     GetIntVec(0,i00save);
     GetIntVec($21,i21save);

     with pr(@oldints)^ do begin
       int0:=i00Save;
       int21:=i21save;
       flag:=0;
     End;

     SetIntVec(0,@int0);
     SetIntVec($21,@int21h);

     exec(pname,copy(cline,i,255));

     SetIntVec($21,i21Save);     { Note the order, int 21h first so }
     SetIntVec(0,i00Save);       { it does not catch setting of int 0}

     swapvectors;
  end
  else begin
         Writeln('TFix: Error: program not found');
         Writeln('Usage: Tfix program [parameters]')
       End;

end.

Osmo

Re:TP/BP7 CRT bug - no source code available - a possible fix


In comp.lang.pascal.borland, Osmo Ronkanen spluttered:

Quote
>In article <2RfxPAA3kDS2Y...@pedt.demon.co.uk>,
>Pedt Scragg  <newsmas...@pedt.demon.co.uk> wrote:
>>There have been a number of requests for solving the RTE 200 bug in the
>>CRT unit when source is not available.

>>ISTM that Osmo Ronkanen's code for the fdelay unit could also be used as
>>a program
>I have to test it.  I just made the same thing myself:

>{$M 1100,0,0}

>uses dos;  { better not use CRT :-) }

<program snipped>

Nice one Osmo.

Maybe not as easy to understand for non-experts as using paramstr but
far neater and smaller in code & data usage that what I came up with.
Also saves having to specify the .exe extension to files.

--
Pedt Scragg

Never challenge a porcupine to an ass-kicking contest

Re:TP/BP7 CRT bug - no source code available - a possible fix


In article <2RfxPAA3kDS2Y...@pedt.demon.co.uk>,
Pedt Scragg  <newsmas...@pedt.demon.co.uk> wrote:

Quote
>There have been a number of requests for solving the RTE 200 bug in the
>CRT unit when source is not available.

>ISTM that Osmo Ronkanen's code for the fdelay unit could also be used as
>a program (similarly to the Loadfix program supplied with DOs 6.xx) to
>intercept the relevant interrupts then release them when the TP/BP7
>program loads.

>Test code below. It works on my machine, some code could be, I'm sure,
>improved - all thoughts welcomed. I will upload the source to a suitable
>location when and if appropriate. I would appreciate anyone who is able
>to test the code to do so.

On what machine did you test it? I have found several problems with it.
The main problem is that TP programs set the int 0 handler, it does not
matter what you set outside of the program with this kind of a loader.
The initialization code of the system unit sets its own handler anyway.

The TP Division by zero interrupt is simply:

"; Divide by zero interrupt handler. Control arrives here upon
; executing a DIV or IDIV instruction with a zero divisor.

Int00Handler:

        MOV     AX,200

; RunError standard procedure

HaltError:

        POP     CX
        POP     BX
        JMP     SHORT Terminate"

This gets control when the the division by zero occurs. The version
from the loader never gets control.

In my version I solved this by catching the int 21h call that sets the
handler.

Quote

>Memory usage of 5760 bytes.

>-------code follows-------------

>{Heavily based on Osmo Ronkanen's Fdelay unit source}
>{Osmo's comments on his code retained in the source }

>{$A+,B-,D-,E-,F+,G,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+}
>{$M 1300,0,0}

>Program bpfix;

>uses dos;

>const dfix:word=1;       { call delay() dfix times }

>var   st : string[130];
>var   st1: string[64];
>var   i  : byte;

>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

Now this would be dangerous if this handler ever got control. One is
executing the runerror in the loader triggered by an interrupt in the
main program. This could cause unpredictable results.

Quote
>@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;

Keeping the dfix makes no sense as the code is not modified to use it.
It is better just to set the maximum possible delay: dx=54; ax=65535.

- Show quoted text -

Quote
>{ 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
>     SwapVectors;        {we need our own $00 and $21 vectors}
>                         {so swapvectors first}
>     asm
>        cli              {do not interrupt vector changes}
>     end;

Why cli?

- Show quoted text -

Quote
>     GetIntVec(0,pr(@oldints)^.int0);
>     GetIntVec($21,pr(@oldints)^.int21);

>     SetIntVec(0,@int0);
>     SetIntVec($21,@int21h);
>     asm
>        sti              {finish vector changes- allow interrupts}
>     end;

>     If paramcount = 0 then        {no parameters then exit}
>     begin
>          SwapVectors;             {restore vectors}
>          exit
>     end

>     else if paramcount=1 then     {only program name given}
>     begin
>          st1 := fsearch(paramstr(1),getenv('path'));
>          exec(st1,' ');

Why space as parameter?

Quote
>          swapvectors;             {restore vectors}
>     end
>     else
>     begin                         {parameters have been provided}
>          fillchar(st[0],131,#32);
>          st[0] := #1;
>          for i := 2 to paramcount do
>          begin
>               st1 := paramstr(i);
>               move(st1[1],st[succ(length(st))],length(st1));
>               inc(st[0],succ(length(st1)));
>          end;

Note you cannot construct the original command line with paramstr().

Quote
>          st1 := fsearch(paramstr(1),getenv('path'));

This could be longer than 64 characters.

Quote
>          exec(st1,st);
>          swapvectors;          {restore vectors}
>     end;
>end.

>{Note: full name of program inc. extension must be given}

>--
>Pedt Scragg

>Never challenge a porcupine to an ass-kicking contest

Osmo

Re:TP/BP7 CRT bug - no source code available - a possible fix


Quote
Pedt Scragg wrote in message <2RfxPAA3kDS2Y...@pedt.demon.co.uk>...
>There have been a number of requests for solving the RTE 200 bug in the
>CRT unit when source is not available.

Surely this is not a problem as the compiled units are available for
download
from many places e.g.

http://home.t-online.de/adreas.killer/crt.zip

and as everyone has TPUMover, they can simply remove the old units from
TURBO.TPL and TPP.TPL and replace them with the new ones.

Re:TP/BP7 CRT bug - no source code available - a possible fix


In comp.lang.pascal.borland, Osmo Ronkanen spluttered:

Quote
>In article <2RfxPAA3kDS2Y...@pedt.demon.co.uk>,
>Pedt Scragg  <newsmas...@pedt.demon.co.uk> wrote:
>>There have been a number of requests for solving the RTE 200 bug in the
>>CRT unit when source is not available.

>On what machine did you test it? I have found several problems with it.

PII 350MHz

Agree with all the problems. Your code posted since is far better.

--
Pedt Scragg

Never challenge a porcupine to an ass-kicking contest

Re:TP/BP7 CRT bug - no source code available - a possible fix


In article <910725077.1774.0.nnrp-08.c1edb...@news.demon.co.uk>,

Quote
Steve Storey <Steve.Sto...@KissTechnologies.Co.UK> wrote:

>Pedt Scragg wrote in message <2RfxPAA3kDS2Y...@pedt.demon.co.uk>...
>>There have been a number of requests for solving the RTE 200 bug in the
>>CRT unit when source is not available.

>Surely this is not a problem as the compiled units are available for
>download
>from many places e.g.

>http://home.t-online.de/adreas.killer/crt.zip

Distributing copyrighted software is not legal. The fact that one can
distribute the code as part of compiled programs does not mean that one
can distribute the units separately.

Also one cannot access that page.

Quote

>and as everyone has TPUMover, they can simply remove the old units from
>TURBO.TPL and TPP.TPL and replace them with the new ones.

Also the issue was when the source of the program is not available. No
unit can help in that case.

Osmo

Re:TP/BP7 CRT bug - no source code available - a possible fix


Quote
Steve Storey (Steve.Sto...@KissTechnologies.Co.UK) wrote:

: http://home.t-online.de/adreas.killer/crt.zip

This doesn't work, try instead:
http://home.t-online.de/home/andreas.killer/crt.zip

--
Klaus Hartnegg, Institut fuer Biophysik, Hansa-Strasse 9a, D-79104 Freiburg
hartn...@uni-freiburg.de   http://www.brain.uni-freiburg.de/~klaus/

Other Threads