Subversion Repositories Kolibri OS

Rev

Rev 6647 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6613 leency 1
(*
7209 akron1 2
    Copyright 2016, 2018 Anton Krotov
6613 leency 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 .
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
 
6647 akron1 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
 
6613 leency 156
PROCEDURE [stdcall] malloc*(size: INTEGER): INTEGER;
6647 akron1 157
VAR ptr: INTEGER;
6613 leency 158
BEGIN
159
  sys.CODE("60"); (* pusha *)
6647 akron1 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;
6613 leency 168
  sys.CODE("61")  (* popa  *)
6647 akron1 169
  RETURN ptr
6613 leency 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
 
7209 akron1 190
PROCEDURE AppAdr(): INTEGER;
191
VAR
192
    buf: ARRAY 1024 OF CHAR;
193
    a: INTEGER;
194
BEGIN
195
    a := sysfunc3(9, sys.ADR(buf), -1);
196
    sys.GET(sys.ADR(buf) + 22, a)
197
    RETURN a
198
END AppAdr;
199
 
6613 leency 200
PROCEDURE GetCommandLine*(): INTEGER;
201
VAR param: INTEGER;
202
BEGIN
7209 akron1 203
  sys.GET(28 + AppAdr(), param)
6613 leency 204
  RETURN param
205
END GetCommandLine;
206
 
207
PROCEDURE GetName*(): INTEGER;
208
VAR name: INTEGER;
209
BEGIN
7209 akron1 210
  sys.GET(32 + AppAdr(), name)
6613 leency 211
  RETURN name
212
END GetName;
213
 
214
PROCEDURE [stdcall] dll_init2(arg1, arg2, arg3, arg4, arg5: INTEGER);
215
BEGIN
216
  sys.CODE("60");               (* pusha                    *)
217
  sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
218
  sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
219
  sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
220
  sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
221
  sys.CODE("8B7518");           (* mov     esi, [ebp + 18h] *)
222
  sys.CODE("FFD6");             (* call    esi              *)
223
  sys.CODE("61");               (* popa                     *)
224
  sys.CODE("C9");               (* leave                    *)
225
  sys.CODE("C21400");           (* ret     14h              *)
226
END dll_init2;
227
 
228
PROCEDURE GetProcAdr*(name: ARRAY OF CHAR; lib: INTEGER): INTEGER;
229
VAR cur, procname, adr: INTEGER;
230
 
231
  PROCEDURE streq(str1, str2: INTEGER): BOOLEAN;
232
  VAR c1, c2: CHAR;
233
  BEGIN
234
    REPEAT
235
      sys.GET(str1, c1);
236
      sys.GET(str2, c2);
237
      INC(str1);
238
      INC(str2)
239
    UNTIL (c1 # c2) OR (c1 = 0X)
240
    RETURN c1 = c2
241
  END streq;
242
 
243
BEGIN
244
  adr := 0;
245
  IF (lib # 0) & (name # "") THEN
246
    cur := lib;
247
    REPEAT
248
      sys.GET(cur, procname);
249
      INC(cur, 8)
250
    UNTIL (procname = 0) OR streq(procname, sys.ADR(name[0]));
251
    IF procname # 0 THEN
252
      sys.GET(cur - 4, adr)
253
    END
254
  END
255
  RETURN adr
256
END GetProcAdr;
257
 
258
PROCEDURE init(dll: INTEGER);
259
VAR lib_init: INTEGER;
260
BEGIN
261
  lib_init := GetProcAdr("lib_init", dll);
262
  IF lib_init # 0 THEN
263
    DLL_INIT(lib_init)
264
  END;
265
  lib_init := GetProcAdr("START", dll);
266
  IF lib_init # 0 THEN
267
    DLL_INIT(lib_init)
268
  END;
269
END init;
270
 
271
PROCEDURE [stdcall] dll_Load(import_table: INTEGER): INTEGER;
272
VAR imp, lib, exp, proc, res: INTEGER;
273
    fail, done: BOOLEAN;
274
    procname, libname: STRING;
275
 
276
  PROCEDURE GetStr(adr, i: INTEGER; VAR str: STRING);
277
  VAR c: CHAR;
278
  BEGIN
279
    REPEAT
280
      sys.GET(adr, c); INC(adr);
281
      str[i] := c; INC(i)
282
    UNTIL c = 0X
283
  END GetStr;
284
 
285
BEGIN
286
  sys.CODE("60"); (* pusha *)
287
  fail := FALSE;
288
  done := FALSE;
289
  res := 0;
290
  libname := "/rd/1/lib/";
291
  REPEAT
292
    sys.GET(import_table, imp);
293
    IF imp # 0 THEN
294
      sys.GET(import_table + 4, lib);
295
      GetStr(lib, 10, libname);
296
      exp := sysfunc3(68, 19, sys.ADR(libname[0]));
297
      fail := exp = 0;
298
    ELSE
299
      done := TRUE
300
    END;
301
    IF fail THEN
302
      done := TRUE
303
    END;
304
    IF (imp # 0) & ~fail THEN
305
      REPEAT
306
	sys.GET(imp, proc);
307
	IF proc # 0 THEN
308
	  GetStr(proc, 0, procname);
309
	  proc := GetProcAdr(procname, exp);
310
	  IF proc # 0 THEN
311
	    sys.PUT(imp, proc);
312
	    INC(imp, 4);
313
	  END
314
	END
315
      UNTIL proc = 0;
316
      init(exp);
317
      INC(import_table, 8)
318
    END
319
  UNTIL done;
320
  IF fail THEN
321
    res := 1
322
  END;
323
  import_table := res;
324
  sys.CODE("61") (* popa *)
325
  RETURN import_table
326
END dll_Load;
327
 
328
PROCEDURE [stdcall] dll_Init(entry: INTEGER);
329
BEGIN
330
  sys.CODE("60"); (* pusha *)
331
  IF entry # 0 THEN
332
    dll_init2(sys.ADR(malloc), sys.ADR(free), sys.ADR(realloc), sys.ADR(dll_Load), entry)
333
  END;
334
  sys.CODE("61"); (* popa  *)
335
END dll_Init;
336
 
337
PROCEDURE LoadLib*(name: ARRAY OF CHAR): INTEGER;
338
VAR Lib: INTEGER;
339
BEGIN
6647 akron1 340
  DLL_INIT := dll_Init;
6613 leency 341
  Lib := sysfunc3(68, 19, sys.ADR(name[0]));
342
  IF Lib # 0 THEN
343
    init(Lib)
344
  END
345
  RETURN Lib
346
END LoadLib;
347
 
348
END KOSAPI.