home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / turbopas / patch.pas < prev    next >
Pascal/Delphi Source File  |  1985-02-05  |  3KB  |  111 lines

  1. Program Patch;
  2.  
  3. {
  4.   PATCH: Patches a Turbo program to save the command line and
  5.           suppress the automatic calls to terminal initialization.
  6.   Written by CSEB (EBM)
  7.   Net address: J. Eliot B. Moss <EBM@MIT-XX.ARPA>
  8.   Last update: 07 JUN 84, 1650 EDT
  9. }
  10.  
  11. {$I-,W0}
  12.  
  13. const
  14.   SkelSize = 14;
  15.  
  16. var
  17.   Base     : integer;
  18.   CmdAddr  : integer;           { place for the command line to be stored }
  19.   EndAddr  : integer;           { next free byte after code }
  20.   StartAddr: integer;           { starting place of original Turbo code }
  21.   Buffer   : array [0..255] of byte;
  22.   FileName : string[16];
  23.   CmdString: string[31] absolute $0080;
  24.   ComFile  : file;
  25.  
  26. { - - - level 1 - - - }
  27.  
  28. Function GetInt (Offset: integer): integer;
  29.  
  30. begin
  31.   GetInt := Buffer[Offset] + (Buffer[Offset + 1] SHL 8);
  32. end;  { function GetInt }
  33.  
  34. { - - - level 1 - - - }
  35.  
  36. procedure PutInt (Offset, Value: integer);
  37.  
  38. begin
  39.   Buffer[Offset    ] := Lo (Value);
  40.   Buffer[Offset + 1] := Hi (Value);
  41. end;  { procedure PutInt }
  42.  
  43. { - - - level 1 - - - }
  44.  
  45. procedure Skeleton;
  46.  
  47. begin
  48.   Inline ($21 / $80 / $00 /     { LXI H, $0080 }
  49.           $11 / $00 / $00 /     { LXI D,  .... }
  50.           $01 / $80 / $00 /     { LXI B, $0080 }
  51.           $ED / $B0 /           { LDIR         }
  52.           $C3 / $00 / $00);     { JMP     .... }
  53. end;  { procedure Skeleton }
  54.  
  55. { - - - level 0b - - - }
  56.  
  57. begin  { program Patch }
  58.  
  59.   FileName := CmdString;
  60.   while (Length (FileName) > 0) AND (FileName[1] = ' ') do
  61.     Delete (FileName, 1, 1);
  62.   if FileName = '' then
  63.     Writeln ('PATCH takes the name of the file to patch as an argument.')
  64.   else begin  { do it all }
  65.     if Pos ('.', FileName) = 0 then
  66.       FileName := FileName + '.COM';
  67.     Assign (ComFile, FileName);
  68.     Reset (ComFile);
  69.     if IOResult <> 0 then
  70.       Writeln ('Sorry, could not open ', FileName, '.')
  71.     else begin  { find things out }
  72.       Seek (ComFile, 0);
  73.       BlockRead (ComFile, Buffer, 1);
  74.       StartAddr := GetInt ($01);
  75.       if StartAddr <> $1FC9 then
  76.         Writeln ('Program appears to have been patched already!')
  77.       else begin  { fix file }
  78.         Seek (ComFile, (StartAddr - $100) SHR 7);
  79.         BlockRead (ComFile, Buffer, 2);
  80.         Base := StartAddr AND $7F;
  81.         EndAddr := GetInt (Base + $10);
  82.         CmdAddr := GetInt (Base + $04);
  83.  
  84.         Seek (ComFile, 0);
  85.         BlockRead (ComFile, Buffer, 1);
  86.         PutInt ($01, EndAddr);
  87.         Seek (ComFile, 0);
  88.         BlockWrite (ComFile, Buffer, 1);
  89.  
  90.         Seek (ComFile, ($400 - $100) SHR 7);
  91.         BlockRead (ComFile, Buffer, 2);
  92.         Buffer[$D1] := Buffer[$D7];  { eliminate terminal calls }
  93.         Seek (ComFile, ($400 - $100) SHR 7);
  94.         BlockWrite (ComFile, Buffer, 2);
  95.  
  96.         Seek (ComFile, (EndAddr - $100) SHR 7);
  97.         BlockRead (ComFile, Buffer, 2);
  98.         Base := EndAddr AND $7F;
  99.         Move (Mem[Addr (Skeleton)], Buffer[Base], SkelSize);
  100.         PutInt (Base + $04, CmdAddr  );
  101.         PutInt (Base + $0C, StartAddr);
  102.         Seek (ComFile, (EndAddr - $100) SHR 7);
  103.         BlockWrite (ComFile, Buffer, (Base + SkelSize + 128) SHR 7);
  104.  
  105.         Close (ComFile)
  106.       end { fix file }
  107.     end { find things out }
  108.   end { do it all }
  109.  
  110. end.  { program Patch }
  111.