RTL.ob07 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2019-2021, Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE RTL;
  7. IMPORT SYSTEM, Trap;
  8. CONST
  9. bit_depth = 64;
  10. maxint = ROR(-2, 1);
  11. minint = ROR(1, 1);
  12. WORD = bit_depth DIV 8;
  13. MAX_SET = bit_depth - 1;
  14. VAR
  15. Heap, Types, TypesCount: INTEGER;
  16. PROCEDURE _error* (modnum, _module, err, line: INTEGER);
  17. BEGIN
  18. Trap.trap(modnum, _module, err, line)
  19. END _error;
  20. PROCEDURE syscall1 (fn, p1: INTEGER): INTEGER;
  21. BEGIN
  22. Trap.syscall(SYSTEM.ADR(fn))
  23. RETURN fn
  24. END syscall1;
  25. PROCEDURE syscall2 (fn, p1, p2: INTEGER): INTEGER;
  26. BEGIN
  27. Trap.syscall(SYSTEM.ADR(fn))
  28. RETURN fn
  29. END syscall2;
  30. PROCEDURE syscall3 (fn, p1, p2, p3: INTEGER): INTEGER;
  31. BEGIN
  32. Trap.syscall(SYSTEM.ADR(fn))
  33. RETURN fn
  34. END syscall3;
  35. PROCEDURE _fmul* (b, a: INTEGER): INTEGER;
  36. RETURN syscall2(100, b, a)
  37. END _fmul;
  38. PROCEDURE _fdiv* (b, a: INTEGER): INTEGER;
  39. RETURN syscall2(101, b, a)
  40. END _fdiv;
  41. PROCEDURE _fdivi* (b, a: INTEGER): INTEGER;
  42. RETURN syscall2(101, a, b)
  43. END _fdivi;
  44. PROCEDURE _fadd* (b, a: INTEGER): INTEGER;
  45. RETURN syscall2(102, b, a)
  46. END _fadd;
  47. PROCEDURE _fsub* (b, a: INTEGER): INTEGER;
  48. RETURN syscall2(103, b, a)
  49. END _fsub;
  50. PROCEDURE _fsubi* (b, a: INTEGER): INTEGER;
  51. RETURN syscall2(103, a, b)
  52. END _fsubi;
  53. PROCEDURE _fcmp* (op, b, a: INTEGER): BOOLEAN;
  54. RETURN syscall3(104, op, b, a) # 0
  55. END _fcmp;
  56. PROCEDURE _floor* (x: INTEGER): INTEGER;
  57. RETURN syscall1(105, x)
  58. END _floor;
  59. PROCEDURE _flt* (x: INTEGER): INTEGER;
  60. RETURN syscall1(106, x)
  61. END _flt;
  62. PROCEDURE _pack* (n: INTEGER; VAR x: SET);
  63. BEGIN
  64. n := LSL((LSR(ORD(x), 52) MOD 2048 + n) MOD 2048, 52);
  65. x := x - {52..62} + BITS(n)
  66. END _pack;
  67. PROCEDURE _unpk* (VAR n: INTEGER; VAR x: SET);
  68. BEGIN
  69. n := LSR(ORD(x), 52) MOD 2048 - 1023;
  70. x := x - {62} + {52..61}
  71. END _unpk;
  72. PROCEDURE _rot* (VAR A: ARRAY OF INTEGER);
  73. VAR
  74. i, n, k: INTEGER;
  75. BEGIN
  76. k := LEN(A) - 1;
  77. n := A[0];
  78. i := 0;
  79. WHILE i < k DO
  80. A[i] := A[i + 1];
  81. INC(i)
  82. END;
  83. A[k] := n
  84. END _rot;
  85. PROCEDURE _set* (b, a: INTEGER): INTEGER;
  86. BEGIN
  87. IF (a <= b) & (a <= MAX_SET) & (b >= 0) THEN
  88. IF b > MAX_SET THEN
  89. b := MAX_SET
  90. END;
  91. IF a < 0 THEN
  92. a := 0
  93. END;
  94. a := LSR(ASR(minint, b - a), MAX_SET - b)
  95. ELSE
  96. a := 0
  97. END
  98. RETURN a
  99. END _set;
  100. PROCEDURE _set1* (a: INTEGER): INTEGER;
  101. BEGIN
  102. IF ASR(a, 6) = 0 THEN
  103. a := LSL(1, a)
  104. ELSE
  105. a := 0
  106. END
  107. RETURN a
  108. END _set1;
  109. PROCEDURE _length* (len, str: INTEGER): INTEGER;
  110. VAR
  111. c: CHAR;
  112. res: INTEGER;
  113. BEGIN
  114. res := 0;
  115. REPEAT
  116. SYSTEM.GET(str, c);
  117. INC(str);
  118. DEC(len);
  119. INC(res)
  120. UNTIL (len = 0) OR (c = 0X);
  121. RETURN res - ORD(c = 0X)
  122. END _length;
  123. PROCEDURE _move* (bytes, dest, source: INTEGER);
  124. VAR
  125. b: BYTE;
  126. i: INTEGER;
  127. BEGIN
  128. IF (source MOD WORD = 0) & (dest MOD WORD = 0) THEN
  129. WHILE bytes >= WORD DO
  130. SYSTEM.GET(source, i);
  131. SYSTEM.PUT(dest, i);
  132. INC(source, WORD);
  133. INC(dest, WORD);
  134. DEC(bytes, WORD)
  135. END
  136. END;
  137. WHILE bytes > 0 DO
  138. SYSTEM.GET(source, b);
  139. SYSTEM.PUT8(dest, b);
  140. INC(source);
  141. INC(dest);
  142. DEC(bytes)
  143. END
  144. END _move;
  145. PROCEDURE _lengthw* (len, str: INTEGER): INTEGER;
  146. VAR
  147. c: WCHAR;
  148. res: INTEGER;
  149. BEGIN
  150. res := 0;
  151. REPEAT
  152. SYSTEM.GET(str, c);
  153. INC(str, 2);
  154. DEC(len);
  155. INC(res)
  156. UNTIL (len = 0) OR (c = 0X);
  157. RETURN res - ORD(c = 0X)
  158. END _lengthw;
  159. PROCEDURE strncmp (a, b, n: INTEGER): INTEGER;
  160. VAR
  161. A, B: CHAR;
  162. res: INTEGER;
  163. BEGIN
  164. res := minint;
  165. WHILE n > 0 DO
  166. SYSTEM.GET(a, A); INC(a);
  167. SYSTEM.GET(b, B); INC(b);
  168. DEC(n);
  169. IF A # B THEN
  170. res := ORD(A) - ORD(B);
  171. n := 0
  172. ELSIF A = 0X THEN
  173. res := 0;
  174. n := 0
  175. END
  176. END
  177. RETURN res
  178. END strncmp;
  179. PROCEDURE _strcmp* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
  180. VAR
  181. res: INTEGER;
  182. bRes: BOOLEAN;
  183. c: CHAR;
  184. BEGIN
  185. res := strncmp(str1, str2, MIN(len1, len2));
  186. IF res = minint THEN
  187. IF len1 > len2 THEN
  188. SYSTEM.GET(str1 + len2, c);
  189. res := ORD(c)
  190. ELSIF len1 < len2 THEN
  191. SYSTEM.GET(str2 + len1, c);
  192. res := -ORD(c)
  193. ELSE
  194. res := 0
  195. END
  196. END;
  197. CASE op OF
  198. |0: bRes := res = 0
  199. |1: bRes := res # 0
  200. |2: bRes := res < 0
  201. |3: bRes := res <= 0
  202. |4: bRes := res > 0
  203. |5: bRes := res >= 0
  204. END
  205. RETURN bRes
  206. END _strcmp;
  207. PROCEDURE strncmpw (a, b, n: INTEGER): INTEGER;
  208. VAR
  209. A, B: WCHAR;
  210. res: INTEGER;
  211. BEGIN
  212. res := minint;
  213. WHILE n > 0 DO
  214. SYSTEM.GET(a, A); INC(a, 2);
  215. SYSTEM.GET(b, B); INC(b, 2);
  216. DEC(n);
  217. IF A # B THEN
  218. res := ORD(A) - ORD(B);
  219. n := 0
  220. ELSIF A = 0X THEN
  221. res := 0;
  222. n := 0
  223. END
  224. END
  225. RETURN res
  226. END strncmpw;
  227. PROCEDURE _strcmpw* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
  228. VAR
  229. res: INTEGER;
  230. bRes: BOOLEAN;
  231. c: WCHAR;
  232. BEGIN
  233. res := strncmpw(str1, str2, MIN(len1, len2));
  234. IF res = minint THEN
  235. IF len1 > len2 THEN
  236. SYSTEM.GET(str1 + len2 * 2, c);
  237. res := ORD(c)
  238. ELSIF len1 < len2 THEN
  239. SYSTEM.GET(str2 + len1 * 2, c);
  240. res := -ORD(c)
  241. ELSE
  242. res := 0
  243. END
  244. END;
  245. CASE op OF
  246. |0: bRes := res = 0
  247. |1: bRes := res # 0
  248. |2: bRes := res < 0
  249. |3: bRes := res <= 0
  250. |4: bRes := res > 0
  251. |5: bRes := res >= 0
  252. END
  253. RETURN bRes
  254. END _strcmpw;
  255. PROCEDURE _arrcpy* (base_size, len_dst, dst, len_src, src: INTEGER): BOOLEAN;
  256. VAR
  257. res: BOOLEAN;
  258. BEGIN
  259. IF len_src > len_dst THEN
  260. res := FALSE
  261. ELSE
  262. _move(len_src * base_size, dst, src);
  263. res := TRUE
  264. END
  265. RETURN res
  266. END _arrcpy;
  267. PROCEDURE _strcpy* (chr_size, len_src, src, len_dst, dst: INTEGER);
  268. BEGIN
  269. _move(MIN(len_dst, len_src) * chr_size, dst, src)
  270. END _strcpy;
  271. PROCEDURE _new* (t, size: INTEGER; VAR p: INTEGER);
  272. VAR
  273. ptr: INTEGER;
  274. BEGIN
  275. ptr := Heap;
  276. IF ptr + size < Trap.sp() - 128 THEN
  277. INC(Heap, size);
  278. p := ptr + WORD;
  279. SYSTEM.PUT(ptr, t);
  280. INC(ptr, WORD);
  281. DEC(size, WORD);
  282. WHILE size > 0 DO
  283. SYSTEM.PUT(ptr, 0);
  284. INC(ptr, WORD);
  285. DEC(size, WORD)
  286. END
  287. ELSE
  288. p := 0
  289. END
  290. END _new;
  291. PROCEDURE _guard* (t, p: INTEGER): BOOLEAN;
  292. VAR
  293. _type: INTEGER;
  294. BEGIN
  295. SYSTEM.GET(p, p);
  296. IF p # 0 THEN
  297. SYSTEM.GET(p - WORD, _type);
  298. WHILE (_type # t) & (_type # 0) DO
  299. SYSTEM.GET(Types + _type * WORD, _type)
  300. END
  301. ELSE
  302. _type := t
  303. END
  304. RETURN _type = t
  305. END _guard;
  306. PROCEDURE _is* (t, p: INTEGER): BOOLEAN;
  307. VAR
  308. _type: INTEGER;
  309. BEGIN
  310. _type := 0;
  311. IF p # 0 THEN
  312. SYSTEM.GET(p - WORD, _type);
  313. WHILE (_type # t) & (_type # 0) DO
  314. SYSTEM.GET(Types + _type * WORD, _type)
  315. END
  316. END
  317. RETURN _type = t
  318. END _is;
  319. PROCEDURE _guardrec* (t0, t1: INTEGER): BOOLEAN;
  320. BEGIN
  321. WHILE (t1 # t0) & (t1 # 0) DO
  322. SYSTEM.GET(Types + t1 * WORD, t1)
  323. END
  324. RETURN t1 = t0
  325. END _guardrec;
  326. PROCEDURE _init* (tcount, heap, types: INTEGER);
  327. BEGIN
  328. Heap := heap;
  329. TypesCount := tcount;
  330. Types := types
  331. END _init;
  332. END RTL.