RTL.ob07 7.0 KB

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