Subversion Repositories Kolibri OS

Rev

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

  1. (*
  2.     Copyright 2016 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 KOSAPI;
  19.  
  20. IMPORT sys := SYSTEM;
  21.  
  22. TYPE STRING = ARRAY 1024 OF CHAR;
  23.  
  24. VAR DLL_INIT: PROCEDURE [stdcall] (entry: INTEGER);
  25.  
  26. PROCEDURE [stdcall] sysfunc1*(arg1: INTEGER): INTEGER;
  27. BEGIN
  28.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  29.   sys.CODE("CD40");             (* int     40h              *)
  30.   sys.CODE("C9");               (* leave                    *)
  31.   sys.CODE("C20400");           (* ret     04h              *)
  32.   RETURN 0
  33. END sysfunc1;
  34.  
  35. PROCEDURE [stdcall] sysfunc2*(arg1, arg2: INTEGER): INTEGER;
  36. BEGIN
  37.   sys.CODE("53");               (* push    ebx              *)
  38.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  39.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  40.   sys.CODE("CD40");             (* int     40h              *)
  41.   sys.CODE("5B");               (* pop     ebx              *)
  42.   sys.CODE("C9");               (* leave                    *)
  43.   sys.CODE("C20800");           (* ret     08h              *)
  44.   RETURN 0
  45. END sysfunc2;
  46.  
  47. PROCEDURE [stdcall] sysfunc3*(arg1, arg2, arg3: INTEGER): INTEGER;
  48. BEGIN
  49.   sys.CODE("53");               (* push    ebx              *)
  50.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  51.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  52.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  53.   sys.CODE("CD40");             (* int     40h              *)
  54.   sys.CODE("5B");               (* pop     ebx              *)
  55.   sys.CODE("C9");               (* leave                    *)
  56.   sys.CODE("C20C00");           (* ret     0Ch              *)
  57.   RETURN 0
  58. END sysfunc3;
  59.  
  60. PROCEDURE [stdcall] sysfunc4*(arg1, arg2, arg3, arg4: INTEGER): INTEGER;
  61. BEGIN
  62.   sys.CODE("53");               (* push    ebx              *)
  63.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  64.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  65.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  66.   sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
  67.   sys.CODE("CD40");             (* int     40h              *)
  68.   sys.CODE("5B");               (* pop     ebx              *)
  69.   sys.CODE("C9");               (* leave                    *)
  70.   sys.CODE("C21000");           (* ret     10h              *)
  71.   RETURN 0
  72. END sysfunc4;
  73.  
  74. PROCEDURE [stdcall] sysfunc5*(arg1, arg2, arg3, arg4, arg5: INTEGER): INTEGER;
  75. BEGIN
  76.   sys.CODE("53");               (* push    ebx              *)
  77.   sys.CODE("56");               (* push    esi              *)
  78.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  79.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  80.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  81.   sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
  82.   sys.CODE("8B7518");           (* mov     esi, [ebp + 18h] *)
  83.   sys.CODE("CD40");             (* int     40h              *)
  84.   sys.CODE("5E");               (* pop     esi              *)
  85.   sys.CODE("5B");               (* pop     ebx              *)
  86.   sys.CODE("C9");               (* leave                    *)
  87.   sys.CODE("C21400");           (* ret     14h              *)
  88.   RETURN 0
  89. END sysfunc5;
  90.  
  91. PROCEDURE [stdcall] sysfunc6*(arg1, arg2, arg3, arg4, arg5, arg6: INTEGER): INTEGER;
  92. BEGIN
  93.   sys.CODE("53");               (* push    ebx              *)
  94.   sys.CODE("56");               (* push    esi              *)
  95.   sys.CODE("57");               (* push    edi              *)
  96.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  97.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  98.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  99.   sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
  100.   sys.CODE("8B7518");           (* mov     esi, [ebp + 18h] *)
  101.   sys.CODE("8B7D1C");           (* mov     edi, [ebp + 1Ch] *)
  102.   sys.CODE("CD40");             (* int     40h              *)
  103.   sys.CODE("5F");               (* pop     edi              *)
  104.   sys.CODE("5E");               (* pop     esi              *)
  105.   sys.CODE("5B");               (* pop     ebx              *)
  106.   sys.CODE("C9");               (* leave                    *)
  107.   sys.CODE("C21800");           (* ret     18h              *)
  108.   RETURN 0
  109. END sysfunc6;
  110.  
  111. PROCEDURE [stdcall] sysfunc7*(arg1, arg2, arg3, arg4, arg5, arg6, arg7: INTEGER): INTEGER;
  112. BEGIN
  113.   sys.CODE("53");               (* push    ebx              *)
  114.   sys.CODE("56");               (* push    esi              *)
  115.   sys.CODE("57");               (* push    edi              *)
  116.   sys.CODE("55");               (* push    ebp              *)
  117.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  118.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  119.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  120.   sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
  121.   sys.CODE("8B7518");           (* mov     esi, [ebp + 18h] *)
  122.   sys.CODE("8B7D1C");           (* mov     edi, [ebp + 1Ch] *)
  123.   sys.CODE("8B6D20");           (* mov     ebp, [ebp + 20h] *)
  124.   sys.CODE("CD40");             (* int     40h              *)
  125.   sys.CODE("5D");               (* pop     ebp              *)
  126.   sys.CODE("5F");               (* pop     edi              *)
  127.   sys.CODE("5E");               (* pop     esi              *)
  128.   sys.CODE("5B");               (* pop     ebx              *)
  129.   sys.CODE("C9");               (* leave                    *)
  130.   sys.CODE("C21C00");           (* ret     1Ch              *)
  131.   RETURN 0
  132. END sysfunc7;
  133.  
  134. PROCEDURE [stdcall] sysfunc22*(arg1, arg2: INTEGER; VAR res2: INTEGER): INTEGER;
  135. BEGIN
  136.   sys.CODE("53");               (* push    ebx              *)
  137.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  138.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  139.   sys.CODE("CD40");             (* int     40h              *)
  140.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  141.   sys.CODE("8919");             (* mov     [ecx], ebx       *)
  142.   sys.CODE("5B");               (* pop     ebx              *)
  143.   sys.CODE("C9");               (* leave                    *)
  144.   sys.CODE("C20C00");           (* ret     0Ch              *)
  145.   RETURN 0
  146. END sysfunc22;
  147.  
  148. PROCEDURE mem_commit(adr, size: INTEGER);
  149. VAR tmp: INTEGER;
  150. BEGIN
  151.   FOR tmp := adr TO adr + size - 1 BY 4096 DO
  152.     sys.PUT(tmp, 0)
  153.   END
  154. END mem_commit;
  155.  
  156. PROCEDURE [stdcall] malloc*(size: INTEGER): INTEGER;
  157. VAR ptr: INTEGER;
  158. BEGIN
  159.   sys.CODE("60"); (* pusha *)
  160.   IF sysfunc2(18, 16) > ASR(size, 10) THEN
  161.     ptr := sysfunc3(68, 12, size);
  162.     IF ptr # 0 THEN
  163.       mem_commit(ptr, size)
  164.     END
  165.   ELSE
  166.     ptr := 0
  167.   END;
  168.   sys.CODE("61")  (* popa  *)
  169.   RETURN ptr
  170. END malloc;
  171.  
  172. PROCEDURE [stdcall] free*(ptr: INTEGER): INTEGER;
  173. BEGIN
  174.   sys.CODE("60"); (* pusha *)
  175.   IF ptr # 0 THEN
  176.     ptr := sysfunc3(68, 13, ptr)
  177.   END;
  178.   sys.CODE("61")  (* popa  *)
  179.   RETURN 0
  180. END free;
  181.  
  182. PROCEDURE [stdcall] realloc*(ptr, size: INTEGER): INTEGER;
  183. BEGIN
  184.   sys.CODE("60"); (* pusha *)
  185.   ptr := sysfunc4(68, 20, size, ptr);
  186.   sys.CODE("61")  (* popa  *)
  187.   RETURN ptr
  188. END realloc;
  189.  
  190. PROCEDURE GetCommandLine*(): INTEGER;
  191. VAR param: INTEGER;
  192. BEGIN
  193.   sys.GET(28, param)
  194.   RETURN param
  195. END GetCommandLine;
  196.  
  197. PROCEDURE GetName*(): INTEGER;
  198. VAR name: INTEGER;
  199. BEGIN
  200.   sys.GET(32, name)
  201.   RETURN name
  202. END GetName;
  203.  
  204. PROCEDURE [stdcall] dll_init2(arg1, arg2, arg3, arg4, arg5: INTEGER);
  205. BEGIN
  206.   sys.CODE("60");               (* pusha                    *)
  207.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  208.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  209.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  210.   sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
  211.   sys.CODE("8B7518");           (* mov     esi, [ebp + 18h] *)
  212.   sys.CODE("FFD6");             (* call    esi              *)
  213.   sys.CODE("61");               (* popa                     *)
  214.   sys.CODE("C9");               (* leave                    *)
  215.   sys.CODE("C21400");           (* ret     14h              *)
  216. END dll_init2;
  217.  
  218. PROCEDURE GetProcAdr*(name: ARRAY OF CHAR; lib: INTEGER): INTEGER;
  219. VAR cur, procname, adr: INTEGER;
  220.  
  221.   PROCEDURE streq(str1, str2: INTEGER): BOOLEAN;
  222.   VAR c1, c2: CHAR;
  223.   BEGIN
  224.     REPEAT
  225.       sys.GET(str1, c1);
  226.       sys.GET(str2, c2);
  227.       INC(str1);
  228.       INC(str2)
  229.     UNTIL (c1 # c2) OR (c1 = 0X)
  230.     RETURN c1 = c2
  231.   END streq;
  232.  
  233. BEGIN
  234.   adr := 0;
  235.   IF (lib # 0) & (name # "") THEN
  236.     cur := lib;
  237.     REPEAT
  238.       sys.GET(cur, procname);
  239.       INC(cur, 8)
  240.     UNTIL (procname = 0) OR streq(procname, sys.ADR(name[0]));
  241.     IF procname # 0 THEN
  242.       sys.GET(cur - 4, adr)
  243.     END
  244.   END
  245.   RETURN adr
  246. END GetProcAdr;
  247.  
  248. PROCEDURE init(dll: INTEGER);
  249. VAR lib_init: INTEGER;
  250. BEGIN
  251.   lib_init := GetProcAdr("lib_init", dll);
  252.   IF lib_init # 0 THEN
  253.     DLL_INIT(lib_init)
  254.   END;
  255.   lib_init := GetProcAdr("START", dll);
  256.   IF lib_init # 0 THEN
  257.     DLL_INIT(lib_init)
  258.   END;
  259. END init;
  260.  
  261. PROCEDURE [stdcall] dll_Load(import_table: INTEGER): INTEGER;
  262. VAR imp, lib, exp, proc, res: INTEGER;
  263.     fail, done: BOOLEAN;
  264.     procname, libname: STRING;
  265.  
  266.   PROCEDURE GetStr(adr, i: INTEGER; VAR str: STRING);
  267.   VAR c: CHAR;
  268.   BEGIN
  269.     REPEAT
  270.       sys.GET(adr, c); INC(adr);
  271.       str[i] := c; INC(i)
  272.     UNTIL c = 0X
  273.   END GetStr;
  274.  
  275. BEGIN
  276.   sys.CODE("60"); (* pusha *)
  277.   fail := FALSE;
  278.   done := FALSE;
  279.   res := 0;
  280.   libname := "/rd/1/lib/";
  281.   REPEAT
  282.     sys.GET(import_table, imp);
  283.     IF imp # 0 THEN
  284.       sys.GET(import_table + 4, lib);
  285.       GetStr(lib, 10, libname);
  286.       exp := sysfunc3(68, 19, sys.ADR(libname[0]));
  287.       fail := exp = 0;
  288.     ELSE
  289.       done := TRUE
  290.     END;
  291.     IF fail THEN
  292.       done := TRUE
  293.     END;
  294.     IF (imp # 0) & ~fail THEN
  295.       REPEAT
  296.         sys.GET(imp, proc);
  297.         IF proc # 0 THEN
  298.           GetStr(proc, 0, procname);
  299.           proc := GetProcAdr(procname, exp);
  300.           IF proc # 0 THEN
  301.             sys.PUT(imp, proc);
  302.             INC(imp, 4);
  303.           END
  304.         END
  305.       UNTIL proc = 0;
  306.       init(exp);
  307.       INC(import_table, 8)
  308.     END
  309.   UNTIL done;
  310.   IF fail THEN
  311.     res := 1
  312.   END;
  313.   import_table := res;
  314.   sys.CODE("61") (* popa *)
  315.   RETURN import_table
  316. END dll_Load;
  317.  
  318. PROCEDURE [stdcall] dll_Init(entry: INTEGER);
  319. BEGIN
  320.   sys.CODE("60"); (* pusha *)
  321.   IF entry # 0 THEN
  322.     dll_init2(sys.ADR(malloc), sys.ADR(free), sys.ADR(realloc), sys.ADR(dll_Load), entry)
  323.   END;
  324.   sys.CODE("61"); (* popa  *)
  325. END dll_Init;
  326.  
  327. PROCEDURE LoadLib*(name: ARRAY OF CHAR): INTEGER;
  328. VAR Lib: INTEGER;
  329. BEGIN
  330.   DLL_INIT := dll_Init;
  331.   Lib := sysfunc3(68, 19, sys.ADR(name[0]));
  332.   IF Lib # 0 THEN
  333.     init(Lib)
  334.   END
  335.   RETURN Lib
  336. END LoadLib;
  337.  
  338. END KOSAPI.