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