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