Article View: comp.os.msdos.programmer
Article #997Tiny TSR contest entry - 160 bytes.
From: Duncan Murdoch
Date: Thu, 27 Aug 1992 15:25
Date: Thu, 27 Aug 1992 15:25
120 lines
3851 bytes
3851 bytes
In article <2a964930@ralf> Ralf.Brown@B.GP.CS.CMU.EDU writes:
>The TSR I was thinking of swaps two pairs of keys on the keyboard in 53
>bytes of resident code. You need to keep the first 64 bytes of the PSP
>(though you can clobber the first ten), so the TSR actually takes 128
>bytes when loaded low, 64 when loaded into a UMB.
The quick little Turbo Pascal program below swaps Esc and Backspace, and
X and Z, just to drive you a little crazy. It takes 160 bytes when
resident, according to TSRCOM's MAPMEM. I'd guess it would take 96 bytes in
a UMB, but I don't know how to put it there.
{$S-,R-} { Don't want stack or range checking }
program swapkeys;
{ A tiny TSR to swap the ESC and BackSpace keys, and the Z and X keys. }
uses dos,
opinline, { The "op" units are part of the Object Professional library }
opdos,
opstring,
opint,
optsr;
const
Esc = $01;
Backspace = $0E;
XKey = $2D;
ZKey = $2C;
OrigAddr = ptr($1234,$5678); { This will be replaced with the
original INT 15 address }
procedure Int15ISR(bp:word); interrupt;
var
regs : intregisters absolute bp;
begin
with regs do
begin
if ah = $4f then
case al of
Esc: al := Backspace;
Backspace: al := Esc;
Zkey: al := XKey;
Xkey: al := ZKey;
end;
JumpToOldIsr(OrigAddr);
end;
end;
procedure EndMarker;
begin end;
procedure FreeSeg(seg:word);
{ I'm not sure why Turbopower doesn't supply this routine. Maybe I just
missed it. }
var
regs : registers;
begin
with regs do
begin
ah := $49;
es := seg;
end;
MsDos(Regs);
end;
const
ISRhandle = 20; { Used by the ISR management routines in OPINT }
var
p,q : pointer; { Used for some memory fiddling }
signature : word;
position : word;
paras : word;
israddress : pointer;
thisenv : envrec;
begin
RestoreAllVectors; { OPint and OPTSR install several handlers; we
don't want those }
{ Release the environment block }
CurrentEnv(thisenv);
Freeseg(thisenv.envseg);
{ Copy our ISR down into the PSP. Don't overwrite the first 4 paras. }
{ Note that TP generates 10 bytes we don't need at the end of our
ISR }
paras := (ofs(endmarker)+15-10) div 16;
ISRaddress := ptr(Prefixseg+4,0);
move(@Int15ISR^, ISRaddress^ , 16*paras);
if not initvector($15,
ISRHandle,
ISRaddress) then
begin
writeln('InitVector failed! Aborting.');
halt(99);
end;
{ Now put the old ISR address into our service routine. }
signature := $5678;
p := ptr(seg(ISRaddress^),search(ISRaddress^,16*paras, signature, 2));
q := IsrArray[ISRHandle].OrigAddr;
Move(q,p^,2);
signature := $1234;
p := ptr(seg(p^),search(ISRaddress^,16*paras, signature, 2));
q := pointer(longint(q) shr 16); { Shift the segment to the offset }
Move(q,p^,2);
paras := seg(ISRaddress^) - prefixseg { the PSP }
+ paras; { plus our code }
{ Have to trick StayRes to let us release so much memory }
heapptr := ptr(pred(prefixseg+paras),0);
StayRes(Paras, 0);
writeln('StayRes failed! We''re not resident.');
end.
Technical Details
Message-ID:
<dmurdoch.73.714929106@mast.queensu.ca>Path:
arc1-ca.pugleaf.net!sparky!uunet!gatech!rpi!utcsri!torn!news.ccs.queensu.ca!mast.queensu.ca!dmurdochReferences:
<2a964930@ralf>Show Full Headers
Complete Article Headers
Newsgroups: comp.os.msdos.programmer Path: arc1-ca.pugleaf.net!sparky!uunet!gatech!rpi!utcsri!torn!news.ccs.queensu.ca!mast.queensu.ca!dmurdoch From: dmurdoch@mast.queensu.ca (Duncan Murdoch) Subject: Tiny TSR contest entry - 160 bytes. Message-ID: <dmurdoch.73.714929106@mast.queensu.ca> Lines: 120 Sender: news@knot.ccs.queensu.ca (Netnews control) Organization: Queen's University References: <2a964930@ralf> Date: Thu, 27 Aug 1992 15:25:06 GMT