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, 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.     WHILE ((source MOD WORD # 0) OR (dest MOD WORD # 0)) & (bytes > 0) DO
  163.         SYSTEM.GET(source, b);
  164.         SYSTEM.PUT8(dest, b);
  165.         INC(source);
  166.         INC(dest);
  167.         DEC(bytes)
  168.     END;
  169.  
  170.     WHILE bytes >= WORD DO
  171.         SYSTEM.GET(source, i);
  172.         SYSTEM.PUT(dest, i);
  173.         INC(source, WORD);
  174.         INC(dest, WORD);
  175.         DEC(bytes, WORD)
  176.     END;
  177.  
  178.     WHILE bytes > 0 DO
  179.         SYSTEM.GET(source, b);
  180.         SYSTEM.PUT8(dest, b);
  181.         INC(source);
  182.         INC(dest);
  183.         DEC(bytes)
  184.     END
  185. END _move;
  186.  
  187.  
  188. PROCEDURE _lengthw* (len, str: INTEGER): INTEGER;
  189. VAR
  190.     c: WCHAR;
  191.     res: INTEGER;
  192.  
  193. BEGIN
  194.     res := 0;
  195.     REPEAT
  196.         SYSTEM.GET(str, c);
  197.         INC(str, 2);
  198.         DEC(len);
  199.         INC(res)
  200.     UNTIL (len = 0) OR (c = 0X);
  201.  
  202.     RETURN res - ORD(c = 0X)
  203. END _lengthw;
  204.  
  205.  
  206. PROCEDURE strncmp (a, b, n: INTEGER): INTEGER;
  207. VAR
  208.     A, B: CHAR;
  209.     res: INTEGER;
  210.  
  211. BEGIN
  212.     res := 0;
  213.     WHILE n > 0 DO
  214.         SYSTEM.GET(a, A); INC(a);
  215.         SYSTEM.GET(b, B); INC(b);
  216.         DEC(n);
  217.         IF A # B THEN
  218.             res := ORD(A) - ORD(B);
  219.             n := 0
  220.         ELSIF A = 0X THEN
  221.             n := 0
  222.         END
  223.     END
  224.     RETURN res
  225. END strncmp;
  226.  
  227.  
  228. PROCEDURE _strcmp* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
  229. VAR
  230.     res: INTEGER;
  231.     bRes: BOOLEAN;
  232.  
  233. BEGIN
  234.     res := strncmp(str1, str2, MIN(len1, len2));
  235.     IF res = 0 THEN
  236.         res := _length(len1, str1) - _length(len2, str2)
  237.     END;
  238.  
  239.     CASE op OF
  240.     |0: bRes := res =  0
  241.     |1: bRes := res #  0
  242.     |2: bRes := res <  0
  243.     |3: bRes := res <= 0
  244.     |4: bRes := res >  0
  245.     |5: bRes := res >= 0
  246.     END
  247.  
  248.     RETURN bRes
  249. END _strcmp;
  250.  
  251.  
  252. PROCEDURE strncmpw (a, b, n: INTEGER): INTEGER;
  253. VAR
  254.     A, B: WCHAR;
  255.     res:  INTEGER;
  256.  
  257. BEGIN
  258.     res := 0;
  259.     WHILE n > 0 DO
  260.         SYSTEM.GET(a, A); INC(a, 2);
  261.         SYSTEM.GET(b, B); INC(b, 2);
  262.         DEC(n);
  263.         IF A # B THEN
  264.             res := ORD(A) - ORD(B);
  265.             n := 0
  266.         ELSIF A = WCHR(0) THEN
  267.             n := 0
  268.         END
  269.     END
  270.     RETURN res
  271. END strncmpw;
  272.  
  273.  
  274. PROCEDURE _strcmpw* (op, len2, str2, len1, str1: INTEGER): BOOLEAN;
  275. VAR
  276.     res: INTEGER;
  277.     bRes: BOOLEAN;
  278.  
  279. BEGIN
  280.     res := strncmpw(str1, str2, MIN(len1, len2));
  281.     IF res = 0 THEN
  282.         res := _lengthw(len1, str1) - _lengthw(len2, str2)
  283.     END;
  284.  
  285.     CASE op OF
  286.     |0: bRes := res =  0
  287.     |1: bRes := res #  0
  288.     |2: bRes := res <  0
  289.     |3: bRes := res <= 0
  290.     |4: bRes := res >  0
  291.     |5: bRes := res >= 0
  292.     END
  293.  
  294.     RETURN bRes
  295. END _strcmpw;
  296.  
  297.  
  298. PROCEDURE _arrcpy* (base_size, len_dst, dst, len_src, src: INTEGER): BOOLEAN;
  299. VAR
  300.     res: BOOLEAN;
  301.  
  302. BEGIN
  303.     IF len_src > len_dst THEN
  304.         res := FALSE
  305.     ELSE
  306.         _move(len_src * base_size, dst, src);
  307.         res := TRUE
  308.     END
  309.  
  310.     RETURN res
  311. END _arrcpy;
  312.  
  313.  
  314. PROCEDURE _strcpy* (chr_size, len_src, src, len_dst, dst: INTEGER);
  315. BEGIN
  316.     _move(MIN(len_dst, len_src) * chr_size, dst, src)
  317. END _strcpy;
  318.  
  319.  
  320. PROCEDURE _new* (t, size: INTEGER; VAR p: INTEGER);
  321. BEGIN
  322.     IF Heap + size < Trap.sp() - 64 THEN
  323.         p := Heap + WORD;
  324.         REPEAT
  325.             SYSTEM.PUT(Heap, t);
  326.             INC(Heap, WORD);
  327.             DEC(size, WORD);
  328.             t := 0
  329.         UNTIL size = 0
  330.     ELSE
  331.         p := 0
  332.     END
  333. END _new;
  334.  
  335.  
  336. PROCEDURE _guard* (t, p: INTEGER): BOOLEAN;
  337. VAR
  338.     _type: INTEGER;
  339.  
  340. BEGIN
  341.     SYSTEM.GET(p, p);
  342.     IF p # 0 THEN
  343.         SYSTEM.GET(p - WORD, _type);
  344.         WHILE (_type # t) & (_type # 0) DO
  345.             SYSTEM.GET(Types + _type * WORD, _type)
  346.         END
  347.     ELSE
  348.         _type := t
  349.     END
  350.  
  351.     RETURN _type = t
  352. END _guard;
  353.  
  354.  
  355. PROCEDURE _is* (t, p: INTEGER): BOOLEAN;
  356. VAR
  357.     _type: INTEGER;
  358.  
  359. BEGIN
  360.     _type := 0;
  361.     IF p # 0 THEN
  362.         SYSTEM.GET(p - WORD, _type);
  363.         WHILE (_type # t) & (_type # 0) DO
  364.             SYSTEM.GET(Types + _type * WORD, _type)
  365.         END
  366.     END
  367.  
  368.     RETURN _type = t
  369. END _is;
  370.  
  371.  
  372. PROCEDURE _guardrec* (t0, t1: INTEGER): BOOLEAN;
  373. BEGIN
  374.     WHILE (t1 # t0) & (t1 # 0) DO
  375.         SYSTEM.GET(Types + t1 * WORD, t1)
  376.     END
  377.  
  378.     RETURN t1 = t0
  379. END _guardrec;
  380.  
  381.  
  382. PROCEDURE _init* (tcount, heap, types: INTEGER);
  383. BEGIN
  384.     Heap := heap;
  385.     TypesCount := tcount;
  386.     Types := types
  387. END _init;
  388.  
  389.  
  390. END RTL.