Subversion Repositories Kolibri OS

Rev

Rev 7107 | 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.   main_thread_id: INTEGER;
  33.  
  34. PROCEDURE [stdcall] _halt*(n: INTEGER);
  35. BEGIN
  36.   API.ExitProcess(n)
  37. END _halt;
  38.  
  39. PROCEDURE [stdcall] _newrec*(size, t: INTEGER; VAR ptr: INTEGER);
  40. BEGIN
  41.   ptr := API._NEW(size);
  42.   IF ptr # 0 THEN
  43.     sys.PUT(ptr, t);
  44.     INC(ptr, 4)
  45.   END
  46. END _newrec;
  47.  
  48. PROCEDURE [stdcall] _disprec*(VAR ptr: INTEGER);
  49. BEGIN
  50.   IF ptr # 0 THEN
  51.     ptr := API._DISPOSE(ptr - 4)
  52.   END
  53. END _disprec;
  54.  
  55. PROCEDURE [stdcall] _rset*(y, x: INTEGER);
  56. BEGIN
  57.   sys.CODE("8B45088B4D0C3BC87F0A83F91F760B83F81F760633C0C9C2080083F9007D0233C983F81F7E05B81F000000BA000000802BC8F7D9D3FA83E81F8BC8F7D9D3EA8BC2C9C20800")
  58. END _rset;
  59.  
  60. PROCEDURE [stdcall] _inset*(y, x: INTEGER);
  61. BEGIN
  62.   sys.CODE("8B45088B4D0C83F91F7709D3E883E001C9C20800C933C0C20800")
  63. END _inset;
  64.  
  65. PROCEDURE [stdcall] _checktype*(table, t, r: INTEGER);
  66. BEGIN
  67.   table := rtab;
  68.   sys.CODE("8B450C8B4D1085C975076A0158C9C20C008B51FC8B4D083BD0740D85D27409C1E20203D18B12EBEF33C93BC20F94C18BC1C9C20C00")
  69. END _checktype;
  70.  
  71. PROCEDURE [stdcall] _savearr*(size, source, dest: INTEGER);
  72. BEGIN
  73.   sys.CODE("9CFC8BD78BC68B7D108B750C8B4D08F3A48BFA8BF09D")
  74. END _savearr;
  75.  
  76. PROCEDURE [stdcall] _saverec*(dyn, stat, size, source, dest: INTEGER): BOOLEAN;
  77. VAR res: BOOLEAN;
  78. BEGIN
  79.   res := dyn = stat;
  80.   IF res THEN
  81.     _savearr(size, source, dest)
  82.   END
  83.   RETURN res
  84. END _saverec;
  85.  
  86. PROCEDURE [stdcall] _arrayidx*(Dim: INTEGER; VAR Arr: IntArray; bsize, idx, c: INTEGER);
  87. VAR i, m: INTEGER;
  88. BEGIN
  89.   m := bsize * idx;
  90.   FOR i := 4 TO Dim + 2 DO
  91.     m := m * Arr[i]
  92.   END;
  93.   IF (Arr[3] > idx) & (idx >= 0) THEN
  94.     Arr[3] := c + m
  95.   ELSE
  96.     Arr[3] := 0
  97.   END
  98. END _arrayidx;
  99.  
  100. PROCEDURE [stdcall] _arrayidx1*(VAR Arr: IntArray; bsize, idx, c: INTEGER);
  101. BEGIN
  102.   IF (Arr[3] > idx) & (idx >= 0) THEN
  103.     Arr[3] := bsize * idx + c
  104.   ELSE
  105.     Arr[3] := 0
  106.   END
  107. END _arrayidx1;
  108.  
  109. PROCEDURE [stdcall] _arrayrot*(m, n: INTEGER; VAR Arr: IntArray);
  110. VAR i, j, t: INTEGER;
  111. BEGIN
  112.   FOR i := 1 TO n DO
  113.     t := Arr[0];
  114.     FOR j := 0 TO m + n - 1 DO
  115.       Arr[j] := Arr[j + 1]
  116.     END;
  117.     Arr[m + n] := t
  118.   END
  119. END _arrayrot;
  120.  
  121. PROCEDURE [stdcall] _length*(s: ARRAY OF CHAR): INTEGER;
  122. BEGIN
  123.   sys.CODE("8B4508");     //  mov     eax, [ebp + 08h]
  124.   sys.CODE("8B4D0C");     //  mov     ecx, [ebp + 0Ch]
  125.   sys.CODE("48");         //  dec     eax
  126.                           //  L1:
  127.   sys.CODE("40");         //  inc     eax
  128.   sys.CODE("803800");     //  cmp     byte ptr [eax], 0
  129.   sys.CODE("7403");       //  jz      L2
  130.   sys.CODE("E2F8");       //  loop    L1
  131.   sys.CODE("40");         //  inc     eax
  132.                           //  L2:
  133.   sys.CODE("2B4508");     //  sub     eax, [ebp + 08h]
  134.   sys.CODE("C9");         //  leave
  135.   sys.CODE("C20800");     //  ret     08h
  136.   RETURN 0
  137. END _length;
  138.  
  139. PROCEDURE [stdcall] _strcopy*(b, blen, a, alen: INTEGER);
  140. BEGIN
  141.   _savearr(MIN(alen, blen), a, b);
  142.   IF blen > alen THEN
  143.     sys.PUT(b + alen, 0X)
  144.   END
  145. END _strcopy;
  146.  
  147. PROCEDURE [stdcall] _strcmp*(op: INTEGER; b, a: ARRAY OF CHAR): BOOLEAN;
  148. VAR i: INTEGER; Res: BOOLEAN;
  149. BEGIN
  150.   i := API.strncmp(sys.ADR(a), sys.ADR(b), MIN(LEN(a), LEN(b)));
  151.   IF i = 0 THEN
  152.     i := _length(a) - _length(b)
  153.   END;
  154.   CASE op OF
  155.   |0: Res := i = 0
  156.   |1: Res := i # 0
  157.   |2: Res := i < 0
  158.   |3: Res := i > 0
  159.   |4: Res := i <= 0
  160.   |5: Res := i >= 0
  161.   ELSE
  162.   END
  163.   RETURN Res
  164. END _strcmp;
  165.  
  166. PROCEDURE [stdcall] _lstrcmp*(op: INTEGER; b: CHAR; a: ARRAY OF CHAR): BOOLEAN;
  167. VAR s: ARRAY 2 OF CHAR;
  168. BEGIN
  169.   s[0] := b;
  170.   s[1] := 0X;
  171.   RETURN _strcmp(op, s, a)
  172. END _lstrcmp;
  173.  
  174. PROCEDURE [stdcall] _rstrcmp*(op: INTEGER; b: ARRAY OF CHAR; a: CHAR): BOOLEAN;
  175. VAR s: ARRAY 2 OF CHAR;
  176. BEGIN
  177.   s[0] := a;
  178.   s[1] := 0X;
  179.   RETURN _strcmp(op, b, s)
  180. END _rstrcmp;
  181.  
  182. PROCEDURE Int(x: INTEGER; VAR str: STRING);
  183. VAR i, a, b: INTEGER; c: CHAR;
  184. BEGIN
  185.   i := 0;
  186.   a := 0;
  187.   REPEAT
  188.     str[i] := CHR(x MOD 10 + ORD("0"));
  189.     x := x DIV 10;
  190.     INC(i)
  191.   UNTIL x = 0;
  192.   b := i - 1;
  193.   WHILE a < b DO
  194.     c := str[a];
  195.     str[a] := str[b];
  196.     str[b] := c;
  197.     INC(a);
  198.     DEC(b)
  199.   END;
  200.   str[i] := 0X
  201. END Int;
  202.  
  203. PROCEDURE [stdcall] _assrt*(code, m: INTEGER; modname: STRING; line: INTEGER);
  204. VAR msg, int: STRING; pos, n: INTEGER;
  205.  
  206.   PROCEDURE StrAppend(s: STRING);
  207.   VAR i, n: INTEGER;
  208.   BEGIN
  209.     n := LEN(s);
  210.     i := 0;
  211.     WHILE (i < n) & (s[i] # 0X) DO
  212.       msg[pos] := s[i];
  213.       INC(pos);
  214.       INC(i)
  215.     END
  216.   END StrAppend;
  217.  
  218. BEGIN
  219.   pos := 0;
  220.   n := line MOD 16;
  221.   line := line DIV 16;
  222.   CASE n OF
  223.   |1: StrAppend("assertion failure")
  224.   |2: StrAppend("variable of a procedure type has NIL as value")
  225.   |3: StrAppend("typeguard error")
  226.   |4: StrAppend("inadmissible dynamic type")
  227.   |5: StrAppend("index check error")
  228.   |6: StrAppend("NIL pointer dereference")
  229.   |7: StrAppend("invalid value in case statement")
  230.   |8: StrAppend("division by zero")
  231.   ELSE
  232.   END;
  233.   StrAppend(0DX);
  234.   StrAppend(0AX);
  235.   StrAppend("module ");
  236.   StrAppend(modname);
  237.   StrAppend(0DX);
  238.   StrAppend(0AX);
  239.   StrAppend("line ");
  240.   Int(line, int);
  241.   StrAppend(int);
  242.   IF m = 2 THEN
  243.     StrAppend(0DX);
  244.     StrAppend(0AX);
  245.     StrAppend("code ");
  246.     Int(code, int);
  247.     StrAppend(int)
  248.   END;    
  249.   API.DebugMsg(sys.ADR(msg), SelfName);
  250.   IF API.GetCurrentThreadId() = main_thread_id THEN
  251.     API.ExitProcess(0)
  252.   ELSE
  253.     API.ExitThread(0)
  254.   END
  255. END _assrt;
  256.  
  257. PROCEDURE [stdcall] _close*;
  258. BEGIN
  259.   IF CloseProc # NIL THEN
  260.     CloseProc
  261.   END
  262. END _close;
  263.  
  264. PROCEDURE [stdcall] _init*(self, rec, gsize, gadr, esp: INTEGER);
  265. BEGIN
  266.   IF ~init THEN
  267.     API.zeromem(gsize, gadr);
  268.     init := TRUE;
  269.     API.init(esp);
  270.     main_thread_id := API.GetCurrentThreadId();
  271.     SelfName := self;
  272.     rtab := rec;
  273.     CloseProc := NIL
  274.   END
  275. END _init;
  276.  
  277. PROCEDURE SetClose*(proc: PROC);
  278. BEGIN
  279.   CloseProc := proc
  280. END SetClose;
  281.  
  282. END RTL.