HOST.ob07 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2019-2022, Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE HOST;
  7. IMPORT SYSTEM, API;
  8. CONST
  9. slash* = "/";
  10. eol* = 0AX;
  11. bit_depth* = (ORD(LSL(1, 31) > 0) + 1) * 32;
  12. maxint* = ROR(-2, 1);
  13. minint* = ROR(1, 1);
  14. RTLD_LAZY = 1;
  15. TYPE
  16. TP = ARRAY 2 OF INTEGER;
  17. VAR
  18. maxreal*, inf*: REAL;
  19. argc: INTEGER;
  20. libc, librt: INTEGER;
  21. stdout: INTEGER;
  22. fread, fwrite : PROCEDURE [linux] (buffer, bytes, blocks, file: INTEGER): INTEGER;
  23. fopen : PROCEDURE [linux] (fname, fmode: INTEGER): INTEGER;
  24. fclose : PROCEDURE [linux] (file: INTEGER): INTEGER;
  25. _chmod : PROCEDURE [linux] (fname: INTEGER; mode: SET): INTEGER;
  26. time : PROCEDURE [linux] (ptr: INTEGER): INTEGER;
  27. clock_gettime : PROCEDURE [linux] (clock_id: INTEGER; VAR tp: TP): INTEGER;
  28. exit : PROCEDURE [linux] (code: INTEGER);
  29. getcwd : PROCEDURE [linux] (dir, len: INTEGER): INTEGER;
  30. PROCEDURE ExitProcess* (code: INTEGER);
  31. BEGIN
  32. exit(code)
  33. END ExitProcess;
  34. PROCEDURE GetArg* (n: INTEGER; VAR s: ARRAY OF CHAR);
  35. VAR
  36. i, len, ptr: INTEGER;
  37. c: CHAR;
  38. BEGIN
  39. i := 0;
  40. len := LEN(s) - 1;
  41. IF (n < argc) & (len > 0) THEN
  42. SYSTEM.GET(API.MainParam + (n + 1) * SYSTEM.SIZE(INTEGER), ptr);
  43. REPEAT
  44. SYSTEM.GET(ptr, c);
  45. s[i] := c;
  46. INC(i);
  47. INC(ptr)
  48. UNTIL (c = 0X) OR (i = len)
  49. END;
  50. s[i] := 0X
  51. END GetArg;
  52. PROCEDURE GetCurrentDirectory* (VAR path: ARRAY OF CHAR);
  53. VAR
  54. n: INTEGER;
  55. BEGIN
  56. n := getcwd(SYSTEM.ADR(path[0]), LEN(path) - 2);
  57. n := LENGTH(path);
  58. path[n] := slash;
  59. path[n + 1] := 0X
  60. END GetCurrentDirectory;
  61. PROCEDURE FileRead* (F: INTEGER; VAR Buffer: ARRAY OF CHAR; bytes: INTEGER): INTEGER;
  62. VAR
  63. res: INTEGER;
  64. BEGIN
  65. res := fread(SYSTEM.ADR(Buffer[0]), 1, bytes, F);
  66. IF res <= 0 THEN
  67. res := -1
  68. END
  69. RETURN res
  70. END FileRead;
  71. PROCEDURE FileWrite* (F: INTEGER; Buffer: ARRAY OF BYTE; bytes: INTEGER): INTEGER;
  72. VAR
  73. res: INTEGER;
  74. BEGIN
  75. res := fwrite(SYSTEM.ADR(Buffer[0]), 1, bytes, F);
  76. IF res <= 0 THEN
  77. res := -1
  78. END
  79. RETURN res
  80. END FileWrite;
  81. PROCEDURE FileCreate* (FName: ARRAY OF CHAR): INTEGER;
  82. RETURN fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("wb"))
  83. END FileCreate;
  84. PROCEDURE FileClose* (File: INTEGER);
  85. BEGIN
  86. File := fclose(File)
  87. END FileClose;
  88. PROCEDURE chmod* (FName: ARRAY OF CHAR);
  89. VAR
  90. res: INTEGER;
  91. BEGIN
  92. res := _chmod(SYSTEM.ADR(FName[0]), {0, 2..8}) (* rwxrwxr-x *)
  93. END chmod;
  94. PROCEDURE FileOpen* (FName: ARRAY OF CHAR): INTEGER;
  95. RETURN fopen(SYSTEM.ADR(FName[0]), SYSTEM.SADR("rb"))
  96. END FileOpen;
  97. PROCEDURE OutChar* (c: CHAR);
  98. VAR
  99. res: INTEGER;
  100. BEGIN
  101. res := fwrite(SYSTEM.ADR(c), 1, 1, stdout)
  102. END OutChar;
  103. PROCEDURE GetTickCount* (): INTEGER;
  104. VAR
  105. tp: TP;
  106. res: INTEGER;
  107. BEGIN
  108. IF clock_gettime(0, tp) = 0 THEN
  109. res := tp[0] * 100 + tp[1] DIV 10000000
  110. ELSE
  111. res := 0
  112. END
  113. RETURN res
  114. END GetTickCount;
  115. PROCEDURE isRelative* (path: ARRAY OF CHAR): BOOLEAN;
  116. RETURN path[0] # slash
  117. END isRelative;
  118. PROCEDURE UnixTime* (): INTEGER;
  119. RETURN time(0)
  120. END UnixTime;
  121. PROCEDURE splitf* (x: REAL; VAR a, b: INTEGER): INTEGER;
  122. VAR
  123. res: INTEGER;
  124. BEGIN
  125. a := 0;
  126. b := 0;
  127. SYSTEM.GET32(SYSTEM.ADR(x), a);
  128. SYSTEM.GET32(SYSTEM.ADR(x) + 4, b);
  129. SYSTEM.GET(SYSTEM.ADR(x), res)
  130. RETURN res
  131. END splitf;
  132. PROCEDURE d2s* (x: REAL): INTEGER;
  133. VAR
  134. h, l, s, e: INTEGER;
  135. BEGIN
  136. e := splitf(x, l, h);
  137. s := ASR(h, 31) MOD 2;
  138. e := (h DIV 100000H) MOD 2048;
  139. IF e <= 896 THEN
  140. h := (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8 + 800000H;
  141. REPEAT
  142. h := h DIV 2;
  143. INC(e)
  144. UNTIL e = 897;
  145. e := 896;
  146. l := (h MOD 8) * 20000000H;
  147. h := h DIV 8
  148. ELSIF (1151 <= e) & (e < 2047) THEN
  149. e := 1151;
  150. h := 0;
  151. l := 0
  152. ELSIF e = 2047 THEN
  153. e := 1151;
  154. IF (h MOD 100000H # 0) OR (BITS(l) * {0..31} # {}) THEN
  155. h := 80000H;
  156. l := 0
  157. END
  158. END;
  159. DEC(e, 896)
  160. RETURN LSL(s, 31) + LSL(e, 23) + (h MOD 100000H) * 8 + (l DIV 20000000H) MOD 8
  161. END d2s;
  162. PROCEDURE GetSym (lib: INTEGER; name: ARRAY OF CHAR; VarAdr: INTEGER);
  163. VAR
  164. sym: INTEGER;
  165. BEGIN
  166. sym := API.dlsym(lib, SYSTEM.ADR(name[0]));
  167. ASSERT(sym # 0);
  168. SYSTEM.PUT(VarAdr, sym)
  169. END GetSym;
  170. BEGIN
  171. inf := SYSTEM.INF();
  172. maxreal := 1.9;
  173. PACK(maxreal, 1023);
  174. SYSTEM.GET(API.MainParam, argc);
  175. libc := API.libc;
  176. GetSym(libc, "fread", SYSTEM.ADR(fread));
  177. GetSym(libc, "fwrite", SYSTEM.ADR(fwrite));
  178. GetSym(libc, "fopen", SYSTEM.ADR(fopen));
  179. GetSym(libc, "fclose", SYSTEM.ADR(fclose));
  180. GetSym(libc, "chmod", SYSTEM.ADR(_chmod));
  181. GetSym(libc, "time", SYSTEM.ADR(time));
  182. GetSym(libc, "exit", SYSTEM.ADR(exit));
  183. GetSym(libc, "getcwd", SYSTEM.ADR(getcwd));
  184. GetSym(libc, "stdout", SYSTEM.ADR(stdout)); SYSTEM.GET(stdout, stdout);
  185. librt := API.dlopen(SYSTEM.SADR("librt.so.1"), RTLD_LAZY);
  186. GetSym(librt, "clock_gettime", SYSTEM.ADR(clock_gettime))
  187. END HOST.