System.Mod.txt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. MODULE System; (*JG 3.10.90 / NW 12.10.93 / NW 20.6.2016*)
  2. IMPORT SYSTEM, Kernel, FileDir, Files, Modules,
  3. Input, Display, Viewers, Fonts, Texts, Oberon, MenuViewers, TextFrames;
  4. CONST
  5. StandardMenu = "System.Close System.Copy System.Grow Edit.Search Edit.Store";
  6. LogMenu = "Edit.Locate Edit.Search System.Copy System.Grow System.Clear";
  7. VAR W: Texts.Writer;
  8. pat: ARRAY 32 OF CHAR;
  9. PROCEDURE GetArg(VAR S: Texts.Scanner);
  10. VAR T: Texts.Text; beg, end, time: LONGINT;
  11. BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
  12. IF (S.class = Texts.Char) & (S.c = "^") THEN
  13. Oberon.GetSelection(T, beg, end, time);
  14. IF time >= 0 THEN Texts.OpenScanner(S, T, beg); Texts.Scan(S) END
  15. END
  16. END GetArg;
  17. PROCEDURE EndLine;
  18. BEGIN Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
  19. END EndLine;
  20. (* ------------- Toolbox for system control ---------------*)
  21. PROCEDURE SetUser*;
  22. VAR i: INTEGER; ch: CHAR;
  23. user: ARRAY 8 OF CHAR;
  24. password: ARRAY 16 OF CHAR;
  25. BEGIN i := 0; Input.Read(ch);
  26. WHILE (ch # "/") & (i < 7) DO user[i] := ch; INC(i); Input.Read(ch) END;
  27. user[i] := 0X; i := 0; Input.Read(ch);
  28. WHILE (ch > " ") & (i < 15) DO password[i] := ch; INC(i); Input.Read(ch) END;
  29. password[i] := 0X; Oberon.SetUser(user, password)
  30. END SetUser;
  31. PROCEDURE SetFont*;
  32. VAR S: Texts.Scanner;
  33. BEGIN GetArg(S);
  34. IF S.class = Texts.Name THEN Oberon.SetFont(Fonts.This(S.s)) END
  35. END SetFont;
  36. PROCEDURE SetColor*;
  37. VAR S: Texts.Scanner;
  38. BEGIN GetArg(S);
  39. IF S.class = Texts.Int THEN Oberon.SetColor(S.i) END
  40. END SetColor;
  41. PROCEDURE SetOffset*;
  42. VAR S: Texts.Scanner;
  43. BEGIN GetArg(S);
  44. IF S.class = Texts.Int THEN Oberon.SetOffset(S.i) END
  45. END SetOffset;
  46. PROCEDURE Date*;
  47. VAR S: Texts.Scanner;
  48. dt, hr, min, sec, yr, mo, day: LONGINT;
  49. BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
  50. IF S.class = Texts.Int THEN (*set clock*)
  51. day := S.i; Texts.Scan(S); mo := S.i; Texts.Scan(S); yr := S.i; Texts.Scan(S);
  52. hr := S.i; Texts.Scan(S); min := S.i; Texts.Scan(S); sec := S.i;
  53. dt := ((((yr*16 + mo)*32 + day)*32 + hr)*64 + min)*64 + sec;
  54. Kernel.SetClock(dt)
  55. ELSE (*read clock*) Texts.WriteString(W, "System.Clock");
  56. dt := Oberon.Clock(); Texts.WriteClock(W, dt); EndLine
  57. END
  58. END Date;
  59. PROCEDURE Collect*;
  60. BEGIN Oberon.Collect(0)
  61. END Collect;
  62. (* ------------- Toolbox for standard display ---------------*)
  63. PROCEDURE Open*; (*open viewer in system track*)
  64. VAR X, Y: INTEGER;
  65. V: Viewers.Viewer;
  66. S: Texts.Scanner;
  67. BEGIN GetArg(S);
  68. IF S.class = Texts.Name THEN
  69. Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, X, Y);
  70. V := MenuViewers.New(
  71. TextFrames.NewMenu(S.s, StandardMenu),
  72. TextFrames.NewText(TextFrames.Text(S.s), 0), TextFrames.menuH, X, Y)
  73. END
  74. END Open;
  75. PROCEDURE Clear*; (*clear Log*)
  76. VAR T: Texts.Text; F: Display.Frame; buf: Texts.Buffer;
  77. BEGIN F := Oberon.Par.frame;
  78. IF (F # NIL) & (F.next IS TextFrames.Frame) & (F = Oberon.Par.vwr.dsc) THEN
  79. NEW(buf); Texts.OpenBuf(buf); T := F.next(TextFrames.Frame).text; Texts.Delete(T, 0, T.len, buf)
  80. END
  81. END Clear;
  82. PROCEDURE Close*;
  83. VAR V: Viewers.Viewer;
  84. BEGIN
  85. IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN V := Oberon.Par.vwr
  86. ELSE V := Oberon.MarkedViewer()
  87. END;
  88. Viewers.Close(V)
  89. END Close;
  90. PROCEDURE CloseTrack*;
  91. VAR V: Viewers.Viewer;
  92. BEGIN V := Oberon.MarkedViewer(); Viewers.CloseTrack(V.X)
  93. END CloseTrack;
  94. PROCEDURE Recall*;
  95. VAR V: Viewers.Viewer; M: Viewers.ViewerMsg;
  96. BEGIN Viewers.Recall(V);
  97. IF (V#NIL) & (V.state = 0) THEN
  98. Viewers.Open(V, V.X, V.Y + V.H); M.id := Viewers.restore; V.handle(V, M)
  99. END
  100. END Recall;
  101. PROCEDURE Copy*;
  102. VAR V, V1: Viewers.Viewer; M: Oberon.CopyMsg; N: Viewers.ViewerMsg;
  103. BEGIN V := Oberon.Par.vwr; V.handle(V, M); V1 := M.F(Viewers.Viewer);
  104. Viewers.Open(V1, V.X, V.Y + V.H DIV 2);
  105. N.id := Viewers.restore; V1.handle(V1, N)
  106. END Copy;
  107. PROCEDURE Grow*;
  108. VAR V, V1: Viewers.Viewer; M: Oberon.CopyMsg; N: Viewers.ViewerMsg;
  109. DW, DH: INTEGER;
  110. BEGIN V := Oberon.Par.vwr;
  111. DW := Oberon.DisplayWidth(V.X); DH := Oberon.DisplayHeight(V.X);
  112. IF V.H < DH - Viewers.minH THEN Oberon.OpenTrack(V.X, V.W)
  113. ELSIF V.W < DW THEN Oberon.OpenTrack(Oberon.UserTrack(V.X), DW)
  114. END;
  115. IF (V.H < DH - Viewers.minH) OR (V.W < DW) THEN
  116. V.handle(V, M); V1 := M.F(Viewers.Viewer);
  117. Viewers.Open(V1, V.X, DH);;
  118. N.id := Viewers.restore; V1.handle(V1, N)
  119. END
  120. END Grow;
  121. (* ------------- Toolbox for module management ---------------*)
  122. PROCEDURE Free1(VAR S: Texts.Scanner);
  123. BEGIN Texts.WriteString(W, S.s); Texts.WriteString(W, " unloading");
  124. Modules.Free(S.s);
  125. IF Modules.res # 0 THEN Texts.WriteString(W, " failed") END;
  126. EndLine
  127. END Free1;
  128. PROCEDURE Free*;
  129. VAR T: Texts.Text;
  130. beg, end, time: LONGINT;
  131. S: Texts.Scanner;
  132. BEGIN Texts.WriteString(W, "System.Free"); EndLine;
  133. Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
  134. IF (S.class = Texts.Char) & (S.c = "^") THEN
  135. Oberon.GetSelection(T, beg, end, time);
  136. IF time >= 0 THEN Texts.OpenScanner(S, T, beg); Texts.Scan(S);
  137. IF S.class = Texts.Name THEN Free1(S) END
  138. END
  139. ELSE
  140. WHILE S.class = Texts.Name DO Free1(S); Texts.Scan(S) END
  141. END ;
  142. Oberon.Collect(0)
  143. END Free;
  144. PROCEDURE FreeFonts*;
  145. BEGIN Texts.WriteString(W, "System.FreeFonts"); Fonts.Free; EndLine
  146. END FreeFonts;
  147. (* ------------- Toolbox of file system ---------------*)
  148. PROCEDURE List(name: FileDir.FileName; adr: LONGINT; VAR cont: BOOLEAN);
  149. VAR i0, i, j0, j: INTEGER; hp: FileDir.FileHeader;
  150. BEGIN
  151. i := 0;
  152. WHILE (pat[i] > "*") & (pat[i] = name[i]) DO INC(i) END ;
  153. IF (pat[i] = 0X) & (name[i] = 0X) THEN i0 := i; j0 := i
  154. ELSIF pat[i] = "*" THEN
  155. i0 := i; j0 := i+1;
  156. WHILE name[i0] # 0X DO
  157. i := i0; j := j0;
  158. WHILE (name[i] # 0X) & (name[i] = pat[j]) DO INC(i); INC(j) END ;
  159. IF pat[j] = 0X THEN
  160. IF name[i] = 0X THEN (*match*) j0 := j ELSE INC(i0) END
  161. ELSIF pat[j] = "*" THEN i0 := i; j0 := j+1
  162. ELSE INC(i0)
  163. END
  164. END
  165. END ;
  166. IF (name[i0] = 0X) & (pat[j0] = 0X) THEN (*found*)
  167. Texts.WriteString(W, name);
  168. IF pat[j0+1] = "!" THEN (*option*)
  169. Kernel.GetSector(adr, hp);
  170. Texts.Write(W, 9X); Texts.WriteClock(W, hp.date);
  171. Texts.WriteInt(W, hp.aleng*FileDir.SectorSize + hp.bleng - FileDir.HeaderSize, 8); (*length*)
  172. (*Texts.WriteHex(W, adr)*)
  173. END ;
  174. Texts.WriteLn(W)
  175. END
  176. END List;
  177. PROCEDURE Directory*;
  178. VAR X, Y, i: INTEGER; ch: CHAR;
  179. R: Texts.Reader;
  180. T, t: Texts.Text;
  181. V: Viewers.Viewer;
  182. beg, end, time: LONGINT;
  183. pre: ARRAY 32 OF CHAR;
  184. BEGIN Texts.OpenReader(R, Oberon.Par.text, Oberon.Par.pos); Texts.Read(R, ch);
  185. WHILE ch = " " DO Texts.Read(R, ch) END;
  186. IF (ch = "^") OR (ch = 0DX) THEN
  187. Oberon.GetSelection(T, beg, end, time);
  188. IF time >= 0 THEN
  189. Texts.OpenReader(R, T, beg); Texts.Read(R, ch);
  190. WHILE ch <= " " DO Texts.Read(R, ch) END
  191. END
  192. END ;
  193. i := 0;
  194. WHILE ch > "!" DO pat[i] := ch; INC(i); Texts.Read(R, ch) END;
  195. pat[i] := 0X;
  196. IF ch = "!" THEN pat[i+1] := "!" END ; (*directory option*)
  197. i := 0;
  198. WHILE pat[i] > "*" DO pre[i] := pat[i]; INC(i) END;
  199. pre[i] := 0X;
  200. Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, X, Y); t := TextFrames.Text("");
  201. V := MenuViewers.New(
  202. TextFrames.NewMenu("System.Directory", StandardMenu),
  203. TextFrames.NewText(t, 0), TextFrames.menuH, X, Y);
  204. FileDir.Enumerate(pre, List); Texts.Append(t, W.buf)
  205. END Directory;
  206. PROCEDURE CopyFiles*;
  207. VAR f, g: Files.File; Rf, Rg: Files.Rider; ch: CHAR;
  208. name: ARRAY 32 OF CHAR;
  209. S: Texts.Scanner;
  210. BEGIN GetArg(S);
  211. Texts.WriteString(W, "System.CopyFiles"); EndLine;
  212. WHILE S.class = Texts.Name DO
  213. name := S.s; Texts.Scan(S);
  214. IF (S.class = Texts.Char) & (S.c = "=") THEN Texts.Scan(S);
  215. IF (S.class = Texts.Char) & (S.c = ">") THEN Texts.Scan(S);
  216. IF S.class = Texts.Name THEN
  217. Texts.WriteString(W, name); Texts.WriteString(W, " => "); Texts.WriteString(W, S.s);
  218. Texts.WriteString(W, " copying"); Texts.Append(Oberon.Log, W.buf);
  219. f := Files.Old(name);
  220. IF f # NIL THEN g := Files.New(S.s);
  221. Files.Set(Rf, f, 0); Files.Set(Rg, g, 0); Files.Read(Rf, ch);
  222. WHILE ~Rf.eof DO Files.Write(Rg, ch); Files.Read(Rf, ch) END;
  223. Files.Register(g)
  224. ELSE Texts.WriteString(W, " failed")
  225. END ;
  226. EndLine
  227. END
  228. END
  229. END ;
  230. Texts.Scan(S)
  231. END
  232. END CopyFiles;
  233. PROCEDURE RenameFiles*;
  234. VAR res: INTEGER;
  235. name: ARRAY 32 OF CHAR;
  236. S: Texts.Scanner;
  237. BEGIN GetArg(S);
  238. Texts.WriteString(W, "System.RenameFiles"); EndLine;
  239. WHILE S.class = Texts.Name DO
  240. name := S.s; Texts.Scan(S);
  241. IF (S.class = Texts.Char) & (S.c = "=") THEN Texts.Scan(S);
  242. IF (S.class = Texts.Char) & (S.c = ">") THEN Texts.Scan(S);
  243. IF S.class = Texts.Name THEN
  244. Texts.WriteString(W, name); Texts.WriteString(W, " => "); Texts.WriteString(W, S.s);
  245. Texts.WriteString(W, " renaming"); Files.Rename(name, S.s, res);
  246. IF res > 1 THEN Texts.WriteString(W, " failed") END;
  247. EndLine
  248. END
  249. END
  250. END ;
  251. Texts.Scan(S)
  252. END
  253. END RenameFiles;
  254. PROCEDURE DeleteFiles*;
  255. VAR res: INTEGER; S: Texts.Scanner;
  256. BEGIN GetArg(S);
  257. Texts.WriteString(W, "System.DeleteFiles"); EndLine;
  258. WHILE S.class = Texts.Name DO
  259. Texts.WriteString(W, S.s); Texts.WriteString(W, " deleting");
  260. Files.Delete(S.s, res);
  261. IF res # 0 THEN Texts.WriteString(W, " failed") END;
  262. EndLine; Texts.Scan(S)
  263. END
  264. END DeleteFiles;
  265. (* ------------- Toolbox for system inspection ---------------*)
  266. PROCEDURE Watch*;
  267. BEGIN Texts.WriteString(W, "System.Watch"); Texts.WriteLn(W);
  268. Texts.WriteString(W, " Modules space (bytes)"); Texts.WriteInt(W, Modules.AllocPtr, 8);
  269. Texts.WriteInt(W, Modules.AllocPtr * 100 DIV Kernel.heapOrg, 4); Texts.Write(W, "%"); EndLine;
  270. Texts.WriteString(W, " Heap speace"); Texts.WriteInt(W, Kernel.allocated, 8);
  271. Texts.WriteInt(W, Kernel.allocated * 100 DIV (Kernel.heapLim - Kernel.heapOrg), 4); Texts.Write(W, "%"); EndLine;
  272. Texts.WriteString(W, " Disk sectors "); Texts.WriteInt(W, Kernel.NofSectors, 4);
  273. Texts.WriteInt(W, Kernel.NofSectors * 100 DIV 10000H, 4); Texts.Write(W, "%"); EndLine;
  274. Texts.WriteString(W, " Tasks"); Texts.WriteInt(W, Oberon.NofTasks, 4); EndLine
  275. END Watch;
  276. PROCEDURE ShowModules*;
  277. VAR T: Texts.Text;
  278. V: Viewers.Viewer;
  279. M: Modules.Module;
  280. X, Y: INTEGER;
  281. BEGIN T := TextFrames.Text("");
  282. Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, X, Y);
  283. V := MenuViewers.New(TextFrames.NewMenu("System.ShowModules", StandardMenu),
  284. TextFrames.NewText(T, 0), TextFrames.menuH, X, Y);
  285. M := Modules.root;
  286. WHILE M # NIL DO
  287. IF M.name[0] # 0X THEN
  288. Texts.WriteString(W, M.name); Texts.Write(W, 9X); Texts.WriteHex(W, ORD(M));
  289. Texts.WriteHex(W, M.code); Texts.WriteInt(W, M.refcnt, 4)
  290. ELSE Texts.WriteString(W, "---")
  291. END ;
  292. Texts.WriteLn(W); M := M.next
  293. END;
  294. Texts.Append(T, W.buf)
  295. END ShowModules;
  296. PROCEDURE ShowCommands*;
  297. VAR M: Modules.Module;
  298. comadr: LONGINT; ch: CHAR;
  299. T: Texts.Text;
  300. S: Texts.Scanner;
  301. V: Viewers.Viewer;
  302. X, Y: INTEGER;
  303. BEGIN GetArg(S);
  304. IF S.class = Texts.Name THEN
  305. Modules.Load(S.s, M);
  306. IF M # NIL THEN
  307. Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, X, Y); T := TextFrames.Text("");
  308. V := MenuViewers.New(TextFrames.NewMenu("System.Commands", StandardMenu),
  309. TextFrames.NewText(T, 0), TextFrames.menuH, X, Y);
  310. comadr := M.cmd; SYSTEM.GET(comadr, ch); INC(comadr);
  311. WHILE ch # 0X DO
  312. Texts.WriteString(W, S.s); Texts.Write(W, ".");
  313. REPEAT Texts.Write(W, ch); SYSTEM.GET(comadr, ch); INC(comadr)
  314. UNTIL ch = 0X;
  315. WHILE comadr MOD 4 # 0 DO INC(comadr) END ;
  316. Texts.WriteLn(W); INC(comadr, 4); SYSTEM.GET(comadr, ch); INC(comadr)
  317. END ;
  318. Texts.Append(T, W.buf)
  319. END
  320. END
  321. END ShowCommands;
  322. PROCEDURE ShowFonts*;
  323. VAR fnt: Fonts.Font;
  324. BEGIN Texts.WriteString(W, "System.ShowFonts"); Texts.WriteLn(W); fnt := Fonts.root;
  325. WHILE fnt # NIL DO
  326. Texts.Write(W, 9X); Texts.WriteString(W, fnt.name); Texts.WriteLn(W); fnt := fnt.next
  327. END ;
  328. Texts.Append(Oberon.Log, W.buf)
  329. END ShowFonts;
  330. PROCEDURE OpenViewers;
  331. VAR logV, toolV: Viewers.Viewer;
  332. menu, main: Display.Frame;
  333. d: LONGINT; X, Y: INTEGER;
  334. BEGIN d := Kernel.Clock(); Texts.WriteString(W, "Oberon V5 NW 14.4.2013"); EndLine;
  335. Oberon.AllocateSystemViewer(0, X, Y);
  336. menu := TextFrames.NewMenu("System.Log", LogMenu);
  337. main := TextFrames.NewText(Oberon.Log, 0);
  338. logV := MenuViewers.New(menu, main, TextFrames.menuH, X, Y);
  339. Oberon.AllocateSystemViewer(0, X, Y);
  340. menu := TextFrames.NewMenu("System.Tool", StandardMenu);
  341. main := TextFrames.NewText(TextFrames.Text("System.Tool"), 0);
  342. toolV := MenuViewers.New(menu, main, TextFrames.menuH, X, Y)
  343. END OpenViewers;
  344. PROCEDURE ExtendDisplay*;
  345. VAR V: Viewers.Viewer;
  346. X, Y, DX, DW, DH: INTEGER;
  347. S: Texts.Scanner;
  348. BEGIN GetArg(S);
  349. IF S.class = Texts.Name THEN
  350. DX := Viewers.curW; DW := Oberon.DisplayWidth(DX); DH := Oberon.DisplayHeight(DX);
  351. Oberon.OpenDisplay(DW DIV 8 * 5, DW DIV 8 * 3, DH);
  352. Oberon.AllocateSystemViewer(DX, X, Y);
  353. V := MenuViewers.New(
  354. TextFrames.NewMenu(S.s, StandardMenu),
  355. TextFrames.NewText(TextFrames.Text(S.s), 0),
  356. TextFrames.menuH, X, Y)
  357. END
  358. END ExtendDisplay;
  359. PROCEDURE Trap(VAR a: INTEGER; b: INTEGER);
  360. VAR u, v, w: INTEGER; mod: Modules.Module;
  361. BEGIN u := SYSTEM.REG(15); SYSTEM.GET(u - 4, v); w := v DIV 10H MOD 10H; (*trap number*)
  362. IF w = 0 THEN Kernel.New(a, b)
  363. ELSE (*trap*) Texts.WriteLn(W); Texts.WriteString(W, " pos "); Texts.WriteInt(W, v DIV 100H MOD 10000H, 4);
  364. Texts.WriteString(W, " TRAP"); Texts.WriteInt(W, w, 4); mod := Modules.root;
  365. WHILE (mod # NIL) & ((u < mod.code) OR (u >= mod.imp)) DO mod := mod.next END ;
  366. IF mod # NIL THEN Texts.WriteString(W, " in "); Texts.WriteString(W, mod.name) END ;
  367. Texts.WriteString(W, " at"); Texts.WriteHex(W, u);
  368. Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Oberon.Reset
  369. END
  370. END Trap;
  371. PROCEDURE Abort;
  372. VAR n: INTEGER;
  373. BEGIN n := SYSTEM.REG(15); Texts.WriteString(W, " ABORT "); Texts.WriteHex(W, n);
  374. Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Oberon.Reset
  375. END Abort;
  376. BEGIN Texts.OpenWriter(W);
  377. Oberon.OpenLog(TextFrames.Text("")); OpenViewers;
  378. Kernel.Install(SYSTEM.ADR(Trap), 20H); Kernel.Install(SYSTEM.ADR(Abort), 0);
  379. END System.