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