proctrac.mod 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. IMPLEMENTATION MODULE ProcTrace;
  2. IMPORT SYSTEM,IO,Lib,FIO,Str;
  3. CONST MaxMap = 2000;
  4. TYPE MapRec = RECORD
  5. Adr: LONGCARD;
  6. Pos: CARDINAL;
  7. END;
  8. VAR Map: ARRAY [1..MaxMap] OF MapRec;
  9. MapInit: BOOLEAN;
  10. File: FIO.File;
  11. FileBuf: ARRAY [1..1024+FIO.BufferOverhead] OF BYTE;
  12. VAR
  13. Int60[0:180H],Old60,Int61[0:184H],Old61,str : ADDRESS;
  14. Base,Level,l,cs,ip : CARDINAL;
  15. Term : PROC;
  16. MapFile : ARRAY[0..63] OF CHAR;
  17. PROCEDURE Get_Name (): Name;
  18. CONST NoName = "(Unknown)";
  19. VAR Adr: LONGCARD;
  20. seg: CARDINAL;
  21. N,P: CARDINAL;
  22. S: ARRAY [1..100] OF CHAR;
  23. BEGIN
  24. IF NOT MapInit THEN
  25. IO.WrStr("ProcTrace reading MAP-file..."); IO.WrLn;
  26. File := FIO.Open( MapFile );
  27. FIO.AssignBuffer( File , FileBuf );
  28. N := 0;
  29. REPEAT
  30. FIO.RdStr( File , S );
  31. UNTIL FIO.EOF OR (Str.Pos( S , ' by ' ) # MAX(CARDINAL) );
  32. IF FIO.EOF THEN Lib.FatalError('Invalid map file'); END;
  33. INCL( FIO.Separators , ':' );
  34. LOOP
  35. INC( N );
  36. IF N >= MaxMap-2 THEN Lib.FatalError("Map too big"); END;
  37. seg := FIO.RdHex( File );
  38. Adr := LONGCARD( seg ) << 4;
  39. IF NOT FIO.OK THEN EXIT; END;
  40. INC( Adr , LONGCARD( FIO.RdHex( File ) ) );
  41. Map[N].Adr := Adr;
  42. WHILE FIO.RdChar( File ) = ' ' DO END;
  43. Map[N].Pos := CARDINAL( FIO.GetPos( File ) ) - 1;
  44. FIO.RdStr( File , S );
  45. IF seg = 0 THEN DEC( N ); END;
  46. END;
  47. INC( N );
  48. Map[N].Adr := 100000H;
  49. Map[N].Pos := 0FFFFH;
  50. MapInit := TRUE;
  51. FIO.Close( File );
  52. File := FIO.Open( MapFile );
  53. END;
  54. Adr := LONGCARD(cs) << 4 + LONGCARD(ip);
  55. P := 0FFFFH;
  56. N := 1;
  57. WHILE Map[N].Adr <= Adr DO
  58. P := Map[N].Pos;
  59. INC( N );
  60. END;
  61. IF P = 0FFFFH THEN RETURN NoName; END;
  62. FIO.Seek( File , LONGCARD( P ) );
  63. FIO.RdStr( File , S );
  64. RETURN Name( S );
  65. END Get_Name;
  66. PROCEDURE GetBase( l : CARDINAL );
  67. BEGIN
  68. Base := [SYSTEM.Seg( l ):SYSTEM.Ofs( l )+4]^;
  69. END GetBase;
  70. PROCEDURE Monitor ( VAR W: WORD );
  71. BEGIN
  72. MonAdr := ADR( W );
  73. MonWrd := W;
  74. END Monitor;
  75. PROCEDURE Check ( S: ARRAY OF CHAR );
  76. BEGIN
  77. IF (MonAdr # NIL) AND (WORD(MonAdr^) # MonWrd) THEN
  78. IO.WrLn;
  79. IO.WrStr( "!!!!!!!!!!!!!!! Check: ");
  80. IO.WrStr( S );
  81. IO.WrLn;
  82. MonWrd := MonAdr^;
  83. END;
  84. END Check;
  85. PROCEDURE DefaultEntry;
  86. BEGIN
  87. IO.WrStr('Entering '); IO.WrStr(Get_Name()); IO.WrLn;
  88. Check( "Entering" );
  89. END DefaultEntry;
  90. PROCEDURE DefaultExit;
  91. BEGIN
  92. IO.WrStr('Exiting '); IO.WrStr(Get_Name()); IO.WrLn;
  93. Check( "Exiting" );
  94. END DefaultExit;
  95. PROCEDURE GetCsIp(): ADDRESS;
  96. BEGIN
  97. RETURN [cs:ip];
  98. END GetCsIp;
  99. (*$J+,C FF*)
  100. PROCEDURE EntryTrap( dummy : CARDINAL );
  101. VAR a,t : CARDINAL;
  102. BEGIN
  103. SYSTEM.EI;
  104. a := SYSTEM.Ofs( dummy )-4;
  105. t := [SYSTEM.Seg( dummy ) : a+2]^;
  106. cs := t-Base;
  107. ip := [SYSTEM.Seg( dummy ) : a]^;
  108. Entry;
  109. END EntryTrap;
  110. PROCEDURE ExitTrap( dummy : CARDINAL );
  111. VAR a,t : CARDINAL;
  112. BEGIN
  113. SYSTEM.EI;
  114. a := SYSTEM.Ofs( dummy )-4;
  115. t := [SYSTEM.Seg( dummy ) : a+2]^;
  116. cs :=t-Base;
  117. ip :=[SYSTEM.Seg( dummy ) : a]^;
  118. Exit;
  119. END ExitTrap;
  120. (*$J-,C F0*)
  121. PROCEDURE GetDosVersion(): CARDINAL;
  122. VAR r : SYSTEM.Registers; t : SHORTCARD;
  123. BEGIN
  124. WITH r DO
  125. AH := 30H;
  126. Lib.Dos(r);
  127. t := AH;
  128. AH :=AL;
  129. AL :=t;
  130. RETURN AX
  131. END;
  132. END GetDosVersion;
  133. PROCEDURE Finish;
  134. BEGIN
  135. Int60 := Old60;
  136. Int61 := Old61;
  137. Term;
  138. END Finish;
  139. PROCEDURE Install;
  140. BEGIN
  141. IF GetDosVersion() >= 300H THEN
  142. str := Lib.Environment(99);
  143. Str.Copy(MapFile,[SYSTEM.Seg(str^):SYSTEM.Ofs(str^)+3 Lib.CommandType]^);
  144. l := Str.Length( MapFile )-1;
  145. LOOP
  146. IF MapFile[l]='.' THEN EXIT END;
  147. IF l=0 THEN MapFile[0] := 0C; EXIT; END;
  148. DEC(l);
  149. END;
  150. MapFile[l+1] := 0C;
  151. Str.Append( MapFile,'MAP');
  152. IF NOT FIO.Exists(MapFile) THEN
  153. IO.WrStr(' MapFile ? ');
  154. IO.RdItem( MapFile );
  155. END;
  156. ELSE
  157. IO.WrStr(' MapFile ? ');
  158. IO.RdItem( MapFile );
  159. END;
  160. Entry := DefaultEntry;
  161. Exit := DefaultExit;
  162. Old60 := Int60;
  163. Int60 := ADR( EntryTrap );
  164. Old61 := Int61;
  165. Int61 := ADR( ExitTrap );
  166. Lib.Terminate( Finish, Term);
  167. Level := 0;
  168. END Install;
  169. BEGIN
  170. GetBase(0);
  171. MapInit := FALSE;
  172. MonAdr := NIL;
  173. END ProcTrace.
  174.