Subversion Repositories Kolibri OS

Rev

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 [stdcall] malloc*(size: INTEGER): INTEGER;
  149. BEGIN
  150.   sys.CODE("60"); (* pusha *)
  151.   size := sysfunc3(68, 12, size);
  152.   sys.CODE("61")  (* popa  *)
  153.   RETURN size
  154. END malloc;
  155.  
  156. PROCEDURE [stdcall] free*(ptr: INTEGER): INTEGER;
  157. BEGIN
  158.   sys.CODE("60"); (* pusha *)
  159.   IF ptr # 0 THEN
  160.     ptr := sysfunc3(68, 13, ptr)
  161.   END;
  162.   sys.CODE("61")  (* popa  *)
  163.   RETURN 0
  164. END free;
  165.  
  166. PROCEDURE [stdcall] realloc*(ptr, size: INTEGER): INTEGER;
  167. BEGIN
  168.   sys.CODE("60"); (* pusha *)
  169.   ptr := sysfunc4(68, 20, size, ptr);
  170.   sys.CODE("61")  (* popa  *)
  171.   RETURN ptr
  172. END realloc;
  173.  
  174. PROCEDURE GetCommandLine*(): INTEGER;
  175. VAR param: INTEGER;
  176. BEGIN
  177.   sys.GET(28, param)
  178.   RETURN param
  179. END GetCommandLine;
  180.  
  181. PROCEDURE GetName*(): INTEGER;
  182. VAR name: INTEGER;
  183. BEGIN
  184.   sys.GET(32, name)
  185.   RETURN name
  186. END GetName;
  187.  
  188. PROCEDURE [stdcall] dll_init2(arg1, arg2, arg3, arg4, arg5: INTEGER);
  189. BEGIN
  190.   sys.CODE("60");               (* pusha                    *)
  191.   sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
  192.   sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
  193.   sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
  194.   sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
  195.   sys.CODE("8B7518");           (* mov     esi, [ebp + 18h] *)
  196.   sys.CODE("FFD6");             (* call    esi              *)
  197.   sys.CODE("61");               (* popa                     *)
  198.   sys.CODE("C9");               (* leave                    *)
  199.   sys.CODE("C21400");           (* ret     14h              *)
  200. END dll_init2;
  201.  
  202. PROCEDURE GetProcAdr*(name: ARRAY OF CHAR; lib: INTEGER): INTEGER;
  203. VAR cur, procname, adr: INTEGER;
  204.  
  205.   PROCEDURE streq(str1, str2: INTEGER): BOOLEAN;
  206.   VAR c1, c2: CHAR;
  207.   BEGIN
  208.     REPEAT
  209.       sys.GET(str1, c1);
  210.       sys.GET(str2, c2);
  211.       INC(str1);
  212.       INC(str2)
  213.     UNTIL (c1 # c2) OR (c1 = 0X)
  214.     RETURN c1 = c2
  215.   END streq;
  216.  
  217. BEGIN
  218.   adr := 0;
  219.   IF (lib # 0) & (name # "") THEN
  220.     cur := lib;
  221.     REPEAT
  222.       sys.GET(cur, procname);
  223.       INC(cur, 8)
  224.     UNTIL (procname = 0) OR streq(procname, sys.ADR(name[0]));
  225.     IF procname # 0 THEN
  226.       sys.GET(cur - 4, adr)
  227.     END
  228.   END
  229.   RETURN adr
  230. END GetProcAdr;
  231.  
  232. PROCEDURE init(dll: INTEGER);
  233. VAR lib_init: INTEGER;
  234. BEGIN
  235.   lib_init := GetProcAdr("lib_init", dll);
  236.   IF lib_init # 0 THEN
  237.     DLL_INIT(lib_init)
  238.   END;
  239.   lib_init := GetProcAdr("START", dll);
  240.   IF lib_init # 0 THEN
  241.     DLL_INIT(lib_init)
  242.   END;
  243. END init;
  244.  
  245. PROCEDURE [stdcall] dll_Load(import_table: INTEGER): INTEGER;
  246. VAR imp, lib, exp, proc, res: INTEGER;
  247.     fail, done: BOOLEAN;
  248.     procname, libname: STRING;
  249.  
  250.   PROCEDURE GetStr(adr, i: INTEGER; VAR str: STRING);
  251.   VAR c: CHAR;
  252.   BEGIN
  253.     REPEAT
  254.       sys.GET(adr, c); INC(adr);
  255.       str[i] := c; INC(i)
  256.     UNTIL c = 0X
  257.   END GetStr;
  258.  
  259. BEGIN
  260.   sys.CODE("60"); (* pusha *)
  261.   fail := FALSE;
  262.   done := FALSE;
  263.   res := 0;
  264.   libname := "/rd/1/lib/";
  265.   REPEAT
  266.     sys.GET(import_table, imp);
  267.     IF imp # 0 THEN
  268.       sys.GET(import_table + 4, lib);
  269.       GetStr(lib, 10, libname);
  270.       exp := sysfunc3(68, 19, sys.ADR(libname[0]));
  271.       fail := exp = 0;
  272.     ELSE
  273.       done := TRUE
  274.     END;
  275.     IF fail THEN
  276.       done := TRUE
  277.     END;
  278.     IF (imp # 0) & ~fail THEN
  279.       REPEAT
  280.         sys.GET(imp, proc);
  281.         IF proc # 0 THEN
  282.           GetStr(proc, 0, procname);
  283.           proc := GetProcAdr(procname, exp);
  284.           IF proc # 0 THEN
  285.             sys.PUT(imp, proc);
  286.             INC(imp, 4);
  287.           END
  288.         END
  289.       UNTIL proc = 0;
  290.       init(exp);
  291.       INC(import_table, 8)
  292.     END
  293.   UNTIL done;
  294.   IF fail THEN
  295.     res := 1
  296.   END;
  297.   import_table := res;
  298.   sys.CODE("61") (* popa *)
  299.   RETURN import_table
  300. END dll_Load;
  301.  
  302. PROCEDURE [stdcall] dll_Init(entry: INTEGER);
  303. BEGIN
  304.   sys.CODE("60"); (* pusha *)
  305.   IF entry # 0 THEN
  306.     dll_init2(sys.ADR(malloc), sys.ADR(free), sys.ADR(realloc), sys.ADR(dll_Load), entry)
  307.   END;
  308.   sys.CODE("61"); (* popa  *)
  309. END dll_Init;
  310.  
  311. PROCEDURE LoadLib*(name: ARRAY OF CHAR): INTEGER;
  312. VAR Lib: INTEGER;
  313. BEGIN
  314.   Lib := sysfunc3(68, 19, sys.ADR(name[0]));
  315.   IF Lib # 0 THEN
  316.     init(Lib)
  317.   END
  318.   RETURN Lib
  319. END LoadLib;
  320.  
  321. BEGIN
  322.   DLL_INIT := dll_Init
  323. END KOSAPI.