Trace.Mos 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. MODULE Trace; (** AUTHOR "fn"; PURPOSE "Low-level trace output based on KernelLog"; *)
  2. IMPORT SYSTEM;
  3. CONST MAXBUFLEN = 32;
  4. TYPE
  5. CharProc*= PROCEDURE (c:CHAR);
  6. VAR
  7. Char*: CharProc;
  8. Color*: PROCEDURE (c: SHORTINT);
  9. (** Send the specified characters to the trace output (cf. Streams.Sender). *)
  10. PROCEDURE Send*(CONST buf: ARRAY OF CHAR; ofs, len: LONGINT; propagate: BOOLEAN; VAR res: LONGINT);
  11. BEGIN INC (len, ofs); WHILE ofs # len DO Char (buf[ofs]); INC (ofs); END; res := 0;
  12. END Send;
  13. (** Skip to the next line on trace output. *)
  14. PROCEDURE Ln*;
  15. BEGIN Char (0DX); Char (0AX);
  16. END Ln;
  17. (** Write a string to the trace output. *)
  18. PROCEDURE String* (CONST s: ARRAY OF CHAR);
  19. VAR i: LONGINT;
  20. BEGIN i := 0; WHILE (i< LEN(s)) & (s[i] # 0X) DO Char (s[i]); INC (i) END;
  21. END String;
  22. PROCEDURE C*( CONST c : CHAR );
  23. BEGIN
  24. Char( c );
  25. END C;
  26. PROCEDURE StringA*( CONST s: ARRAY OF CHAR; CONST len : LONGINT; CONST addColon : BOOLEAN );
  27. VAR
  28. i : LONGINT;
  29. rest : LONGINT;
  30. BEGIN
  31. IF ( LEN( s ) < len ) THEN
  32. rest := len - LEN( s );
  33. ELSE
  34. rest := 0;
  35. END;
  36. String( s );
  37. FOR i := 0 TO rest -1 DO
  38. Char(' ');
  39. END;
  40. IF ( addColon ) THEN
  41. Char(':'); Char(' ');
  42. END;
  43. END StringA;
  44. PROCEDURE Real*(x: LONGREAL; dec, len: LONGINT);
  45. VAR
  46. res, i, n, x0: LONGINT;
  47. a: ARRAY MAXBUFLEN OF CHAR;
  48. z: LONGREAL;
  49. BEGIN
  50. n := 0;
  51. z := 1.0;
  52. WHILE n < dec DO
  53. z := z*10.0;
  54. INC(n)
  55. END;
  56. x0 := FLOOR(x*z);
  57. IF x < 0.0 THEN x0 := -x0 END;
  58. i := 0;
  59. IF n > 0 THEN
  60. WHILE i < n DO
  61. a[i] := CHR(x0 MOD 10 + 48);
  62. x0 := x0 DIV 10;
  63. INC(i)
  64. END;
  65. a[i] := '.';
  66. INC(i)
  67. END;
  68. REPEAT
  69. a[i] := CHR(x0 MOD 10 + 48);
  70. x0 := x0 DIV 10;
  71. INC(i)
  72. UNTIL (x0 = 0) OR (i = MAXBUFLEN);
  73. IF (x < 0.0) & (i < MAXBUFLEN) THEN a[i] := '-'; INC(i) END;
  74. WHILE (i < len) & (i < MAXBUFLEN) DO a[i] := ' '; INC(i) END;
  75. REPEAT DEC(i); Char( a[i] ); UNTIL i = 0
  76. END Real;
  77. (** Write a string to the trace output and skip to next line. *)
  78. PROCEDURE StringLn* (CONST s: ARRAY OF CHAR);
  79. BEGIN String (s); Ln;
  80. END StringLn;
  81. (** Write a character. *)
  82. PROCEDURE Int* (x,w: LONGINT);
  83. VAR i: SIZE; x0: LONGINT; a: ARRAY 21 OF CHAR;
  84. BEGIN
  85. IF x < 0 THEN
  86. IF x = MIN (LONGINT) THEN
  87. DEC (w, 20);
  88. WHILE w > 0 DO Char (' '); DEC (w) END;
  89. String ("-9223372036854775808");
  90. RETURN
  91. ELSE
  92. DEC (w); x0 := -x
  93. END
  94. ELSE
  95. x0 := x
  96. END;
  97. i := 0;
  98. REPEAT
  99. a[i] := CHR (x0 MOD 10 + 30H); x0 := x0 DIV 10; INC (i)
  100. UNTIL x0 = 0;
  101. WHILE w > i DO Char (' '); DEC (w) END;
  102. IF x < 0 THEN Char ('-') END;
  103. REPEAT DEC (i); Char (a[i]) UNTIL i = 0
  104. END Int;
  105. PROCEDURE HInt*( x : HUGEINT; w: LONGINT );
  106. VAR i: SIZE; x0: HUGEINT; a: ARRAY 32 OF CHAR;
  107. BEGIN
  108. IF x < 0 THEN
  109. IF x = MIN (HUGEINT) THEN
  110. DEC (w, 20);
  111. WHILE w > 0 DO Char (' '); DEC (w) END;
  112. String ("-tm");
  113. RETURN
  114. ELSE
  115. DEC (w); x0 := -x
  116. END
  117. ELSE
  118. x0 := x
  119. END;
  120. i := 0;
  121. REPEAT
  122. a[i] := CHR (x0 MOD 10 + 30H); x0 := x0 DIV 10; INC (i)
  123. UNTIL x0 = 0;
  124. WHILE w > i DO Char (' '); DEC (w) END;
  125. IF x < 0 THEN Char ('-') END;
  126. REPEAT DEC (i); Char (a[i]) UNTIL i = 0
  127. END HInt;
  128. PROCEDURE Boolean* (x : BOOLEAN);
  129. BEGIN IF x THEN String ("TRUE") ELSE String ("FALSE") END
  130. END Boolean;
  131. (** Write "x" as a decimal number with a power-of-two multiplier (K, M or G), followed by "suffix". "w" is the field width, excluding "suffix". *)
  132. PROCEDURE IntSuffix* (x, w: LONGINT; CONST suffix: ARRAY OF CHAR);
  133. CONST K = 1024; M = K*K; G = K*M;
  134. VAR mult: CHAR;
  135. BEGIN
  136. IF x MOD K # 0 THEN
  137. Int (x, w)
  138. ELSE
  139. IF x MOD M # 0 THEN mult := 'K'; x := x DIV K
  140. ELSIF x MOD G # 0 THEN mult := 'M'; x := x DIV M
  141. ELSE mult := 'G'; x := x DIV G
  142. END;
  143. Int (x, w-1); Char (mult)
  144. END;
  145. String (suffix)
  146. END IntSuffix;
  147. (**
  148. Write an integer in hexadecimal right-justified in a field of at least ABS(w) characters.
  149. If w < 0 THEN w least significant hex digits of x are written (possibly including leading zeros)
  150. *)
  151. PROCEDURE Hex*(x: LONGINT; w: LONGINT );
  152. VAR i: LONGINT;
  153. buf: ARRAY 2*SIZEOF(LONGINT)+2 OF CHAR;
  154. neg: BOOLEAN;
  155. c: LONGINT;
  156. BEGIN
  157. IF w >= 0 THEN
  158. i:= 0;
  159. IF x < 0 THEN neg := TRUE; x :=-x ELSIF x=0 THEN buf := "0" ELSE neg := FALSE END;
  160. i := 0;
  161. REPEAT
  162. c := x MOD 10H;
  163. IF c < 10 THEN buf[i] := CHR(c+ORD("0")) ELSE buf[i] := CHR(c-10+ORD("A")) END;
  164. x := x DIV 10H;
  165. INC(i);
  166. UNTIL (i = 2 * SIZEOF(LONGINT)) OR (x=0);
  167. IF c > 9 THEN buf[i] := "0"; INC(i) END;
  168. IF neg THEN buf[i] := "-"; INC(i) END;
  169. WHILE(w > i) DO Char(" "); DEC(w); END;
  170. REPEAT DEC(i); Char(buf[i]); UNTIL i=0;
  171. ELSE
  172. w := -w;
  173. WHILE(w>2*SIZEOF(LONGINT)) DO
  174. Char(" "); DEC(w);
  175. END;
  176. buf[w] := 0X;
  177. REPEAT
  178. DEC(w);
  179. c := x MOD 10H;
  180. IF c <10 THEN buf[w] := CHR(c+ORD("0")) ELSE buf[w] := CHR(c-10+ORD("A")) END;
  181. x := x DIV 10H;
  182. UNTIL w = 0;
  183. String(buf);
  184. END;
  185. END Hex;
  186. (** Write "x" as a hexadecimal address *)
  187. PROCEDURE Address* (x: ADDRESS);
  188. BEGIN
  189. Hex(x,-2*SIZEOF(ADDRESS));
  190. END Address;
  191. (** Write "x" as a hexadecimal number. "w" is the field width. Always prints 16 digits. *)
  192. PROCEDURE HIntHex* (x: LONGINT; w: LONGINT);
  193. BEGIN Hex (x, w);
  194. END HIntHex;
  195. (** Write "x" as a set. *)
  196. PROCEDURE Set*(x: SET);
  197. VAR first: BOOLEAN; i: LONGINT;
  198. BEGIN
  199. first := TRUE;
  200. Char("{");
  201. FOR i := 0 TO MAX(SET) DO
  202. IF i IN x THEN
  203. IF ~first THEN Char(",") ELSE first := FALSE END;
  204. Int(i,1);
  205. END;
  206. END;
  207. Char("}");
  208. END Set;
  209. (** Write a block of memory in hex. *)
  210. PROCEDURE Memory* (adr: ADDRESS; size: SIZE);
  211. VAR i, j: ADDRESS; ch: CHAR;
  212. BEGIN
  213. size := adr+size-1;
  214. FOR i := adr TO size BY 16 DO
  215. Address (i); Char (' ');
  216. FOR j := i TO i+15 DO
  217. IF j <= size THEN
  218. SYSTEM.GET (j, ch);
  219. Char(' ');
  220. Hex (ORD (ch), -2)
  221. ELSE
  222. Char (' ');
  223. END
  224. END;
  225. Char (' ');
  226. FOR j := i TO i+15 DO
  227. IF j <= size THEN
  228. SYSTEM.GET (j, ch);
  229. IF (ch < ' ') OR (ch >= CHR (127)) THEN ch := '.' END;
  230. Char (ch)
  231. END
  232. END;
  233. Ln
  234. END;
  235. END Memory;
  236. (** Write a buffer in hex. *)
  237. PROCEDURE Buffer* (CONST buf: ARRAY OF CHAR; ofs, len: LONGINT);
  238. BEGIN Memory (ADDRESSOF (buf[ofs]), len)
  239. END Buffer;
  240. (** Write bits (ofs..ofs+n-1) of x in binary. *)
  241. PROCEDURE Bits* (x: SET; ofs, n: LONGINT);
  242. BEGIN
  243. REPEAT
  244. DEC (n);
  245. IF (ofs+n) IN x THEN Char ('1') ELSE Char ('0') END
  246. UNTIL n = 0
  247. END Bits;
  248. (** Colors *)
  249. PROCEDURE Blue*;
  250. BEGIN Color (9);
  251. END Blue;
  252. PROCEDURE Green*;
  253. BEGIN Color (10);
  254. END Green;
  255. PROCEDURE Red*;
  256. BEGIN Color (12);
  257. END Red;
  258. PROCEDURE Yellow*;
  259. BEGIN Color (14);
  260. END Yellow;
  261. PROCEDURE Default*;
  262. BEGIN Color (7);
  263. END Default;
  264. PROCEDURE NullChar(c: CHAR);
  265. BEGIN
  266. END NullChar;
  267. PROCEDURE NullColor(c: SHORTINT);
  268. BEGIN
  269. END NullColor;
  270. PROCEDURE Init*;
  271. BEGIN
  272. Char := NullChar;
  273. Color := NullColor;
  274. END Init;
  275. PROCEDURE Enter *;
  276. END Enter;
  277. PROCEDURE Exit *;
  278. BEGIN
  279. Ln
  280. END Exit;
  281. (*
  282. BEGIN
  283. Char := NullChar;
  284. Color := NullColor;
  285. *)
  286. END Trace.