home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.os.msdos.programmer
- Path: 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
-
- 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.
-