Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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