home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / TURBOPAS / PASCAL.ZIP / MAPMEM.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-01-05  |  5.9 KB  |  203 lines

  1. {************************************************************************
  2. * maps system memory blocks for PCDOS 3.0 and higher.                   *
  3. * may work on other versions of DOS but hasn't been tested.             *
  4. * copyright (c) K. Kokkonen, TurboPower Software.                       *
  5. * released to the public domain for personal, non-commercial use only.  *
  6. * written 1/2/86.                                                       *
  7. * telephone: 408-378-3672, CompuServe: 72457,2131.                      *
  8. * requires Turbo version 3 to compile                                   *
  9. * BE SURE to compile with mAx dynamic memory = A000                     *
  10. * limited to environment sizes of 255 bytes (default is 128 bytes)      *
  11. ************************************************************************}
  12.  
  13. PROGRAM MapMem;
  14.  {-look at the system memory map using DOS memory control blocks}
  15.  
  16. TYPE
  17.  address=RECORD
  18.           offset,segment:Integer;
  19.          END;
  20. VAR
  21.  mcbseg:Integer;{potential segment address of an MCB}
  22.  nextseg:Integer;{computed segment address for the next MCB}
  23.  prevseg:Integer;{segment address of the previous PSP}
  24.  pspadd:Integer;{segment address of the current PSP}
  25.  mcblen:Integer;{size of the current memory block in paragraphs}
  26.  gotfirst:Boolean;{true after first MCB is found}
  27.  gotlast:Boolean;{true after last MCB is found}
  28.  idbyte:Byte;{byte that DOS uses to identify an MCB}
  29.  vectors:ARRAY[0..$FF] OF address ABSOLUTE 0:0;
  30.  
  31.  PROCEDURE ShowTheBlock(VAR mcbseg,prevseg,nextseg:Integer;
  32.                         VAR gotfirst,gotlast:Boolean);
  33.   {-display information regarding the memory block}
  34.  TYPE
  35.   pathname=STRING[64];
  36.   hexstring=STRING[4];
  37.  VAR
  38.   st:pathname;
  39.  
  40.   FUNCTION Hex(i:Integer):hexstring;
  41.    {-return the hex equivalent of an integer}
  42.   CONST
  43.    hc:STRING[16]='0123456789ABCDEF';
  44.   VAR
  45.    l,h:Byte;
  46.   BEGIN
  47.    l:=Lo(i);h:=Hi(i);
  48.    Hex:=
  49.    hc[Succ(h SHR 4)]+hc[Succ(h AND $F)]+hc[Succ(l SHR 4)]+hc[Succ(l AND $F)];
  50.   END;{hex}
  51.  
  52.   FUNCTION Cardinal(i:Integer):Real;
  53.    {-return an unsigned integer 0..65535}
  54.   VAR
  55.    r:Real;
  56.   BEGIN
  57.    r:=i;
  58.    IF r<0 THEN r:=r+65536.0;
  59.    Cardinal:=r;
  60.   END;{cardinal}
  61.  
  62.   FUNCTION Owner(startadd:Integer):pathname;
  63.    {-return the name of the owner program of an MCB}
  64.   VAR
  65.    e:STRING[255];
  66.    i:Integer;
  67.    t:pathname;
  68.  
  69.    PROCEDURE StripPathname(VAR pname:pathname);
  70.     {-remove leading drive or path name from the input}
  71.    VAR
  72.     spos,cpos,rpos:Byte;
  73.    BEGIN
  74.     spos:=Pos('\',pname);
  75.     cpos:=Pos(':',pname);
  76.     IF spos+cpos=0 THEN Exit;
  77.     IF spos<>0 THEN BEGIN
  78.      {find the last slash in the pathname}
  79.      rpos:=Length(pname);
  80.      WHILE (rpos>0) AND (pname[rpos]<>'\') DO rpos:=Pred(rpos);
  81.     END ELSE
  82.      rpos:=cpos;
  83.     Delete(pname,1,rpos);
  84.    END;{strippathname}
  85.  
  86.   BEGIN
  87.    {get the environment string to scan}
  88.    e[0]:=#255;
  89.    Move(Mem[startadd:0],e[1],255);
  90.  
  91.    {find end of the standard environment}
  92.    i:=Pos(#0#0,e);
  93.    IF i=0 THEN BEGIN
  94.     {something's wrong, exit gracefully}
  95.     Owner:='';
  96.     Exit;
  97.    END;
  98.  
  99.    {end of environment found, get the program name that follows it}
  100.    t:='';
  101.    i:=i+5;
  102.    REPEAT
  103.     t:=t+Chr(Mem[startadd:i]);
  104.     i:=Succ(i);
  105.    UNTIL Chr(Mem[startadd:i])=#0;
  106.    StripPathname(t);
  107.    Owner:=t;
  108.  
  109.   END;{owner}
  110.  
  111.   PROCEDURE WriteHooks(start,stop:Integer);
  112.    {-show the trapped interrupt vectors}
  113.   VAR
  114.    v:Byte;
  115.    vadd,sadd,eadd:Real;
  116.  
  117.    FUNCTION RealAdd(a:address):Real;
  118.     {-return the real equivalent of an address (pointer)}
  119.    BEGIN
  120.     WITH a DO
  121.      RealAdd:=16.0*Cardinal(segment)+Cardinal(offset);
  122.    END;{realadd}
  123.  
  124.   BEGIN
  125.    sadd:=16.0*Cardinal(start);
  126.    eadd:=16.0*Cardinal(stop);
  127.    FOR v:=0 TO $40 DO BEGIN
  128.     vadd:=RealAdd(vectors[v]);
  129.     IF (vadd>=sadd) AND (vadd<=eadd) THEN
  130.      Write(Copy(Hex(v),3,2),' ');
  131.    END;
  132.   END;{writehooks}
  133.  
  134.  BEGIN{showtheblock}
  135.  
  136.   mcblen:=MemW[mcbseg:3];{size of the MCB in paragraphs}
  137.   nextseg:=Succ(mcbseg+mcblen);{where the next MCB should be}
  138.   pspadd:=MemW[mcbseg:1];{address of program segment prefix for MCB}
  139.  
  140.   IF (gotlast OR (Mem[nextseg:0]=$4D)) AND (pspadd<>0) THEN BEGIN
  141.    {found part of MCB chain}
  142.  
  143.    IF gotlast OR (pspadd=prevseg) THEN BEGIN
  144.  
  145.     {this is the MCB for the program, not for its environment}
  146.     Write(
  147.     ' ',Hex(mcbseg),'    ',{MCB address}
  148.     Hex(pspadd),'    ',{PSP address}
  149.     Hex(mcblen),'   ',{size of block in paragraphs}
  150.     16.0*Cardinal(mcblen):6:0,'  ');{size of block in bytes}
  151.  
  152.     {get the program owning this block by scanning the environment}
  153.     IF gotfirst THEN
  154.      st:=Owner(MemW[pspadd:$2C])
  155.     ELSE
  156.      st:='(DOS)';
  157.     WHILE Length(st)<13 DO st:=st+' ';
  158.     Write(st);
  159.  
  160.     {show any interrupt vectors trapped by the program}
  161.     IF gotfirst THEN
  162.      WriteHooks(pspadd,nextseg);
  163.  
  164.     WriteLn;
  165.     gotfirst:=True;
  166.    END;
  167.    prevseg:=pspadd;
  168.   END;
  169.  END;{showtheblock}
  170.  
  171. BEGIN{main}
  172.  
  173.  WriteLn;
  174.  WriteLn('                         Allocated Memory Map');
  175.  WriteLn;
  176.  WriteLn('MCB adr PSP adr  paras   bytes   owner        hooked vectors');
  177.  WriteLn('------- ------- ------- ------- ----------   ------------------------------');
  178.  
  179.  {start above the Basic work area, could probably start even higher}
  180.  mcbseg:=$50;
  181.  prevseg:=0;
  182.  gotfirst:=False;
  183.  gotlast:=False;
  184.  
  185.  {scan all memory until the last block is found}
  186.  WHILE mcbseg<>$A000 DO BEGIN
  187.   idbyte:=Mem[mcbseg:0];
  188.   IF idbyte=$4D THEN BEGIN
  189.    {an allocated block}
  190.    ShowTheBlock(mcbseg,prevseg,nextseg,gotfirst,gotlast);
  191.    IF gotfirst THEN mcbseg:=nextseg ELSE mcbseg:=Succ(mcbseg);
  192.   END ELSE IF (idbyte=$5A) AND gotfirst THEN BEGIN
  193.    {last block, exit}
  194.    gotlast:=True;
  195.    ShowTheBlock(mcbseg,prevseg,nextseg,gotfirst,gotlast);
  196.    mcbseg:=$A000;
  197.   END ELSE
  198.    {still looking for first block, try every paragraph boundary}
  199.    mcbseg:=Succ(mcbseg);
  200.  END;
  201.  
  202. END.
  203.