Subversion Repositories Kolibri OS

Rev

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

  1. (*
  2.     Copyright 2016, 2017 Anton Krotov
  3.  
  4.     This program is free software: you can redistribute it and/or modify
  5.     it under the terms of the GNU Lesser General Public License as published by
  6.     the Free Software Foundation, either version 3 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU Lesser General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU Lesser General Public License
  15.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16. *)
  17.  
  18. MODULE RTL;
  19.  
  20. IMPORT sys := SYSTEM, API;
  21.  
  22. TYPE
  23.  
  24.   IntArray = ARRAY 2048 OF INTEGER;
  25.   STRING = ARRAY 2048 OF CHAR;
  26.   PROC = PROCEDURE;
  27.  
  28. VAR
  29.  
  30.   SelfName, rtab: INTEGER; CloseProc: PROC;
  31.   init: BOOLEAN;
  32.  
  33. PROCEDURE [stdcall] _halt*(n: INTEGER);
  34. BEGIN
  35.   API.ExitProcess(n)
  36. END _halt;
  37.  
  38. PROCEDURE [stdcall] _newrec*(size, t: INTEGER; VAR ptr: INTEGER);
  39. BEGIN
  40.   ptr := API._NEW(size);
  41.   IF ptr # 0 THEN
  42.     sys.PUT(ptr, t);
  43.     INC(ptr, 4)
  44.   END
  45. END _newrec;
  46.  
  47. PROCEDURE [stdcall] _disprec*(VAR ptr: INTEGER);
  48. BEGIN
  49.   IF ptr # 0 THEN
  50.     ptr := API._DISPOSE(ptr - 4)
  51.   END
  52. END _disprec;
  53.  
  54. PROCEDURE [stdcall] _rset*(y, x: INTEGER);
  55. BEGIN
  56.   sys.CODE("8B45088B4D0C3BC87F0A83F91F760B83F81F760633C0C9C2080083F9007D0233C983F81F7E05B81F000000BA000000802BC8F7D9D3FA83E81F8BC8F7D9D3EA8BC2C9C20800")
  57. END _rset;
  58.  
  59. PROCEDURE [stdcall] _inset*(y, x: INTEGER);
  60. BEGIN
  61.   sys.CODE("8B45088B4D0C83F91F7709D3E883E001C9C20800C933C0C20800")
  62. END _inset;
  63.  
  64. PROCEDURE [stdcall] _checktype*(table, t, r: INTEGER);
  65. BEGIN
  66.   table := rtab;
  67.   sys.CODE("8B450C8B4D1085C975076A0158C9C20C008B51FC8B4D083BD0740D85D27409C1E20203D18B12EBEF33C93BC20F94C18BC1C9C20C00")
  68. END _checktype;
  69.  
  70. PROCEDURE [stdcall] _savearr*(size, source, dest: INTEGER);
  71. BEGIN
  72.   sys.CODE("9CFC8BD78BC68B7D108B750C8B4D08F3A48BFA8BF09D")
  73. END _savearr;
  74.  
  75. PROCEDURE [stdcall] _saverec*(dyn, stat, size, source, dest: INTEGER): BOOLEAN;
  76. VAR res: BOOLEAN;
  77. BEGIN
  78.   res := dyn = stat;
  79.   IF res THEN
  80.     _savearr(size, source, dest)
  81.   END
  82.   RETURN res
  83. END _saverec;
  84.  
  85. PROCEDURE [stdcall] _arrayidx*(Dim: INTEGER; VAR Arr: IntArray; bsize, idx, c: INTEGER);
  86. VAR i, m: INTEGER;
  87. BEGIN
  88.   m := bsize * idx;
  89.   FOR i := 4 TO Dim + 2 DO
  90.     m := m * Arr[i]
  91.   END;
  92.   IF (Arr[3] > idx) & (idx >= 0) THEN
  93.     Arr[3] := c + m
  94.   ELSE
  95.     Arr[3] := 0
  96.   END
  97. END _arrayidx;
  98.  
  99. PROCEDURE [stdcall] _arrayidx1*(VAR Arr: IntArray; bsize, idx, c: INTEGER);
  100. BEGIN
  101.   IF (Arr[3] > idx) & (idx >= 0) THEN
  102.     Arr[3] := bsize * idx + c
  103.   ELSE
  104.     Arr[3] := 0
  105.   END
  106. END _arrayidx1;
  107.  
  108. PROCEDURE [stdcall] _arrayrot*(m, n: INTEGER; VAR Arr: IntArray);
  109. VAR i, j, t: INTEGER;
  110. BEGIN
  111.   FOR i := 1 TO n DO
  112.     t := Arr[0];
  113.     FOR j := 0 TO m + n - 1 DO
  114.       Arr[j] := Arr[j + 1]
  115.     END;
  116.     Arr[m + n] := t
  117.   END
  118. END _arrayrot;
  119.  
  120. PROCEDURE [stdcall] _length*(s: ARRAY OF CHAR): INTEGER;
  121. BEGIN
  122.   sys.CODE("8B4508");     //  mov     eax, [ebp + 08h]
  123.   sys.CODE("8B4D0C");     //  mov     ecx, [ebp + 0Ch]
  124.   sys.CODE("48");         //  dec     eax
  125.                           //  L1:
  126.   sys.CODE("40");         //  inc     eax
  127.   sys.CODE("803800");     //  cmp     byte ptr [eax], 0
  128.   sys.CODE("7403");       //  jz      L2
  129.   sys.CODE("E2F8");       //  loop    L1
  130.   sys.CODE("40");         //  inc     eax
  131.                           //  L2:
  132.   sys.CODE("2B4508");     //  sub     eax, [ebp + 08h]
  133.   sys.CODE("C9");         //  leave
  134.   sys.CODE("C20800");     //  ret     08h
  135.   RETURN 0
  136. END _length;
  137.  
  138. PROCEDURE [stdcall] _strcopy*(b, blen, a, alen: INTEGER);
  139. BEGIN
  140.   _savearr(MIN(alen, blen), a, b);
  141.   IF blen > alen THEN
  142.     sys.PUT(b + alen, 0X)
  143.   END
  144. END _strcopy;
  145.  
  146. PROCEDURE [stdcall] _strcmp*(op: INTEGER; b, a: ARRAY OF CHAR): BOOLEAN;
  147. VAR i: INTEGER; Res: BOOLEAN;
  148. BEGIN
  149.   i := API.strncmp(sys.ADR(a), sys.ADR(b), MIN(LEN(a), LEN(b)));
  150.   IF i = 0 THEN
  151.     i := _length(a) - _length(b)
  152.   END;
  153.   CASE op OF
  154.   |0: Res := i = 0
  155.   |1: Res := i # 0
  156.   |2: Res := i < 0
  157.   |3: Res := i > 0
  158.   |4: Res := i <= 0
  159.   |5: Res := i >= 0
  160.   ELSE
  161.   END
  162.   RETURN Res
  163. END _strcmp;
  164.  
  165. PROCEDURE [stdcall] _lstrcmp*(op: INTEGER; b: CHAR; a: ARRAY OF CHAR): BOOLEAN;
  166. VAR s: ARRAY 2 OF CHAR;
  167. BEGIN
  168.   s[0] := b;
  169.   s[1] := 0X;
  170.   RETURN _strcmp(op, s, a)
  171. END _lstrcmp;
  172.  
  173. PROCEDURE [stdcall] _rstrcmp*(op: INTEGER; b: ARRAY OF CHAR; a: CHAR): BOOLEAN;
  174. VAR s: ARRAY 2 OF CHAR;
  175. BEGIN
  176.   s[0] := a;
  177.   s[1] := 0X;
  178.   RETURN _strcmp(op, b, s)
  179. END _rstrcmp;
  180.  
  181. PROCEDURE Int(x: INTEGER; VAR str: STRING);
  182. VAR i, a, b: INTEGER; c: CHAR;
  183. BEGIN
  184.   i := 0;
  185.   a := 0;
  186.   REPEAT
  187.     str[i] := CHR(x MOD 10 + ORD("0"));
  188.     x := x DIV 10;
  189.     INC(i)
  190.   UNTIL x = 0;
  191.   b := i - 1;
  192.   WHILE a < b DO
  193.     c := str[a];
  194.     str[a] := str[b];
  195.     str[b] := c;
  196.     INC(a);
  197.     DEC(b)
  198.   END;
  199.   str[i] := 0X
  200. END Int;
  201.  
  202. PROCEDURE [stdcall] _assrt*(code, m: INTEGER; modname: STRING; line: INTEGER);
  203. VAR msg, int: STRING; pos, n: INTEGER;
  204.  
  205.   PROCEDURE StrAppend(s: STRING);
  206.   VAR i, n: INTEGER;
  207.   BEGIN
  208.     n := LEN(s);
  209.     i := 0;
  210.     WHILE (i < n) & (s[i] # 0X) DO
  211.       msg[pos] := s[i];
  212.       INC(pos);
  213.       INC(i)
  214.     END
  215.   END StrAppend;
  216.  
  217. BEGIN
  218.   pos := 0;
  219.   n := line MOD 16;
  220.   line := line DIV 16;
  221.   CASE n OF
  222.   |1: StrAppend("assertion failure")
  223.   |2: StrAppend("variable of a procedure type has NIL as value")
  224.   |3: StrAppend("typeguard error")
  225.   |4: StrAppend("inadmissible dynamic type")
  226.   |5: StrAppend("index check error")
  227.   |6: StrAppend("NIL pointer dereference")
  228.   |7: StrAppend("invalid value in case statement")
  229.   |8: StrAppend("division by zero")
  230.   ELSE
  231.   END;
  232.   StrAppend(0DX);
  233.   StrAppend(0AX);
  234.   StrAppend("module ");
  235.   StrAppend(modname);
  236.   StrAppend(0DX);
  237.   StrAppend(0AX);
  238.   StrAppend("line ");
  239.   Int(line, int);
  240.   StrAppend(int);
  241.   IF m = 2 THEN
  242.     StrAppend(0DX);
  243.     StrAppend(0AX);
  244.     StrAppend("code ");
  245.     Int(code, int);
  246.     StrAppend(int)
  247.   END;
  248.   API.DebugMsg(sys.ADR(msg), SelfName);
  249.   API.ExitThread(0)
  250. END _assrt;
  251.  
  252. PROCEDURE [stdcall] _close*;
  253. BEGIN
  254.   IF CloseProc # NIL THEN
  255.     CloseProc
  256.   END
  257. END _close;
  258.  
  259. PROCEDURE [stdcall] _init*(self, rec, gsize, gadr, esp: INTEGER);
  260. BEGIN
  261.   IF ~init THEN
  262.     API.zeromem(gsize, gadr);
  263.     init := TRUE;
  264.     API.init(esp);
  265.     SelfName := self;
  266.     rtab := rec;
  267.     CloseProc := NIL
  268.   END
  269. END _init;
  270.  
  271. PROCEDURE SetClose*(proc: PROC);
  272. BEGIN
  273.   CloseProc := proc
  274. END SetClose;
  275.  
  276. END RTL.