home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / os / msdos / programm / 8839 < prev    next >
Encoding:
Text File  |  1992-08-27  |  3.6 KB  |  132 lines

  1. Newsgroups: comp.os.msdos.programmer
  2. Path: sparky!uunet!gatech!rpi!utcsri!torn!news.ccs.queensu.ca!mast.queensu.ca!dmurdoch
  3. From: dmurdoch@mast.queensu.ca (Duncan Murdoch)
  4. Subject: Tiny TSR contest entry - 160 bytes.
  5. Message-ID: <dmurdoch.73.714929106@mast.queensu.ca>
  6. Lines: 120
  7. Sender: news@knot.ccs.queensu.ca (Netnews control)
  8. Organization: Queen's University
  9. References: <2a964930@ralf>
  10. Date: Thu, 27 Aug 1992 15:25:06 GMT
  11.  
  12. In article <2a964930@ralf> Ralf.Brown@B.GP.CS.CMU.EDU writes:
  13. >The TSR I was thinking of swaps two pairs of keys on the keyboard in 53
  14. >bytes of resident code.  You need to keep the first 64 bytes of the PSP
  15. >(though you can clobber the first ten), so the TSR actually takes 128
  16. >bytes when loaded low, 64 when loaded into a UMB.
  17.  
  18. The quick little Turbo Pascal program below swaps Esc and Backspace, and
  19. X and Z, just to drive you a little crazy.  It takes 160 bytes when 
  20. resident, according to TSRCOM's MAPMEM.  I'd guess it would take 96 bytes in 
  21. a UMB, but I don't know how to put it there.
  22.  
  23. {$S-,R-}        { Don't want stack or range checking }
  24. program swapkeys;
  25.  
  26. { A tiny TSR to swap the ESC and BackSpace keys, and the Z and X keys. }
  27.  
  28. uses dos,
  29.      opinline, { The "op" units are part of the Object Professional library }
  30.      opdos,
  31.      opstring,
  32.      opint,
  33.      optsr;
  34.  
  35. const
  36.   Esc       = $01;
  37.   Backspace = $0E;
  38.   XKey      = $2D;
  39.   ZKey      = $2C;
  40.  
  41.   OrigAddr  = ptr($1234,$5678);      { This will be replaced with the
  42.                                        original INT 15 address }
  43.  
  44. procedure Int15ISR(bp:word); interrupt;
  45. var
  46.   regs : intregisters absolute bp;
  47. begin
  48.   with regs do
  49.   begin
  50.     if ah = $4f then
  51.       case al of
  52.         Esc:       al := Backspace;
  53.         Backspace: al := Esc;
  54.         Zkey:      al := XKey;
  55.         Xkey:      al := ZKey;
  56.       end;
  57.     JumpToOldIsr(OrigAddr);
  58.   end;
  59. end;
  60.  
  61. procedure EndMarker;
  62. begin end;
  63.  
  64. procedure FreeSeg(seg:word);
  65. { I'm not sure why Turbopower doesn't supply this routine.  Maybe I just 
  66.   missed it. }
  67. var
  68.   regs : registers;
  69. begin
  70.   with regs do
  71.   begin
  72.     ah := $49;
  73.     es := seg;
  74.   end;
  75.   MsDos(Regs);
  76. end;
  77.  
  78. const
  79.   ISRhandle = 20;    { Used by the ISR management routines in OPINT }
  80.  
  81. var
  82.   p,q : pointer;     { Used for some memory fiddling }
  83.   signature : word;
  84.   position : word;
  85.  
  86.   paras : word;
  87.   israddress : pointer;
  88.   thisenv : envrec;
  89. begin
  90.   RestoreAllVectors;       { OPint and OPTSR install several handlers; we 
  91.                              don't want those }
  92.  
  93.   { Release the environment block }
  94.  
  95.   CurrentEnv(thisenv);
  96.   Freeseg(thisenv.envseg);
  97.  
  98.   { Copy our ISR down into the PSP.  Don't overwrite the first 4 paras. }
  99.   { Note that TP generates 10 bytes we don't need at the end of our
  100.     ISR }
  101.   paras := (ofs(endmarker)+15-10) div 16;
  102.   ISRaddress := ptr(Prefixseg+4,0);
  103.   move(@Int15ISR^, ISRaddress^ , 16*paras);
  104.  
  105.   if not initvector($15,
  106.                      ISRHandle,
  107.                      ISRaddress) then
  108.   begin
  109.     writeln('InitVector failed! Aborting.');
  110.     halt(99);
  111.   end;
  112.  
  113.   { Now put the old ISR address into our service routine. }
  114.  
  115.   signature := $5678;
  116.   p := ptr(seg(ISRaddress^),search(ISRaddress^,16*paras, signature, 2));
  117.   q := IsrArray[ISRHandle].OrigAddr;
  118.   Move(q,p^,2);
  119.  
  120.   signature := $1234;  
  121.   p := ptr(seg(p^),search(ISRaddress^,16*paras, signature, 2));  
  122.   q := pointer(longint(q) shr 16);   { Shift the segment to the offset }
  123.   Move(q,p^,2);
  124.  
  125.   paras := seg(ISRaddress^) - prefixseg          { the PSP }
  126.            + paras;                              { plus our code }
  127.   { Have to trick StayRes to let us release so much memory }
  128.   heapptr := ptr(pred(prefixseg+paras),0);
  129.   StayRes(Paras, 0);
  130.   writeln('StayRes failed!  We''re not resident.');
  131. end.
  132.