Subversion Repositories Kolibri OS

Rev

Rev 7209 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7209 Rev 7597
Line 1... Line 1...
1
(*
1
(*
2
    Copyright 2016, 2017, 2018 Anton Krotov
2
    BSD 2-Clause License
Line 3... Line -...
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
3
 
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
4
    Copyright (c) 2018, Anton Krotov
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 .
5
    All rights reserved.
Line 16... Line 6...
16
*)
6
*)
Line 17... Line 7...
17
 
7
 
Line 18... Line 8...
18
MODULE API;
8
MODULE API;
Line 19... Line 9...
19
 
9
 
Line 39... Line 29...
39
    heap, endheap: INTEGER;
29
    heap, endheap: INTEGER;
40
    pockets: ARRAY MAX_SIZE DIV 32 + 1 OF INTEGER;
30
    pockets: ARRAY MAX_SIZE DIV 32 + 1 OF INTEGER;
Line 41... Line 31...
41
 
31
 
Line -... Line 32...
-
 
32
    CriticalSection: CRITICAL_SECTION;
-
 
33
 
-
 
34
    import*, multi: BOOLEAN;
-
 
35
 
-
 
36
    eol*:  ARRAY 3 OF CHAR;
Line 42... Line 37...
42
    CriticalSection: CRITICAL_SECTION;
37
    base*: INTEGER;
43
 
38
 
-
 
39
 
-
 
40
PROCEDURE [stdcall] zeromem* (dwords: INTEGER; adr: INTEGER);
-
 
41
BEGIN
-
 
42
    SYSTEM.CODE(
-
 
43
    0FCH,               (*  cld                            *)
44
 
44
    031H, 0C0H,         (*  xor     eax, eax               *)
-
 
45
    057H,               (*  push    edi                    *)
-
 
46
    08BH, 07DH, 00CH,   (*  mov     edi, dword [ebp + 12]  *)
-
 
47
    08BH, 04DH, 008H,   (*  mov     ecx, dword [ebp +  8]  *)
45
PROCEDURE [stdcall] zeromem* (size, adr: INTEGER);
48
    0F3H, 0ABH,         (*  rep     stosd                  *)
Line 46... Line 49...
46
BEGIN
49
    05FH                (*  pop     edi                    *)
47
    sys.CODE("578B7D0C8B4D0833C09CFCF3AB9D5F")
50
    )
48
END zeromem;
51
END zeromem;
49
 
52
 
50
 
53
 
51
PROCEDURE mem_commit* (adr, size: INTEGER);
54
PROCEDURE mem_commit* (adr, size: INTEGER);
52
VAR
55
VAR
53
    tmp: INTEGER;
56
    tmp: INTEGER;
Line 54... Line -...
54
BEGIN
-
 
55
    FOR tmp := adr TO adr + size - 1 BY 4096 DO
-
 
56
        sys.PUT(tmp, 0)
-
 
57
    END
-
 
58
END mem_commit;
-
 
59
 
-
 
60
 
-
 
61
PROCEDURE strncmp* (a, b, n: INTEGER): INTEGER;
-
 
62
VAR
-
 
63
    A, B: CHAR;
-
 
64
    Res: INTEGER;
-
 
65
BEGIN
-
 
66
    Res := 0;
-
 
67
    WHILE n > 0 DO
-
 
68
        sys.GET(a, A); INC(a);
-
 
69
        sys.GET(b, B); INC(b);
-
 
70
        DEC(n);
-
 
71
        IF A # B THEN
-
 
72
            Res := ORD(A) - ORD(B);
-
 
73
            n := 0
-
 
74
        ELSIF A = 0X THEN
-
 
75
            n := 0
-
 
76
        END
-
 
77
    END
-
 
78
    RETURN Res
-
 
79
END strncmp;
-
 
80
 
-
 
81
 
-
 
82
PROCEDURE [stdcall] sysfunc1* (arg1: INTEGER): INTEGER;
-
 
83
BEGIN
-
 
84
    sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
-
 
85
    sys.CODE("CD40");             (* int     40h              *)
-
 
86
    sys.CODE("C9");               (* leave                    *)
-
 
87
    sys.CODE("C20400");           (* ret     04h              *)
-
 
88
    RETURN 0
-
 
89
END sysfunc1;
-
 
90
 
-
 
91
 
-
 
92
PROCEDURE [stdcall] sysfunc2* (arg1, arg2: INTEGER): INTEGER;
-
 
93
BEGIN
-
 
94
    sys.CODE("53");               (* push    ebx              *)
-
 
95
    sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
-
 
96
    sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
-
 
97
    sys.CODE("CD40");             (* int     40h              *)
-
 
98
    sys.CODE("5B");               (* pop     ebx              *)
-
 
99
    sys.CODE("C9");               (* leave                    *)
-
 
100
    sys.CODE("C20800");           (* ret     08h              *)
-
 
101
    RETURN 0
-
 
102
END sysfunc2;
-
 
103
 
-
 
104
 
-
 
105
PROCEDURE [stdcall] sysfunc3* (arg1, arg2, arg3: INTEGER): INTEGER;
-
 
106
BEGIN
-
 
107
    sys.CODE("53");               (* push    ebx              *)
-
 
108
    sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
-
 
109
    sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
-
 
110
    sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
-
 
111
    sys.CODE("CD40");             (* int     40h              *)
-
 
112
    sys.CODE("5B");               (* pop     ebx              *)
-
 
113
    sys.CODE("C9");               (* leave                    *)
-
 
114
    sys.CODE("C20C00");           (* ret     0Ch              *)
-
 
115
    RETURN 0
-
 
116
END sysfunc3;
-
 
117
 
-
 
118
 
-
 
119
PROCEDURE [stdcall] sysfunc4* (arg1, arg2, arg3, arg4: INTEGER): INTEGER;
-
 
120
BEGIN
-
 
121
    sys.CODE("53");               (* push    ebx              *)
-
 
122
    sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
-
 
123
    sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
-
 
124
    sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
-
 
125
    sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
-
 
126
    sys.CODE("CD40");             (* int     40h              *)
-
 
127
    sys.CODE("5B");               (* pop     ebx              *)
-
 
128
    sys.CODE("C9");               (* leave                    *)
-
 
129
    sys.CODE("C21000");           (* ret     10h              *)
-
 
130
    RETURN 0
-
 
131
END sysfunc4;
-
 
132
 
-
 
133
 
-
 
134
PROCEDURE [stdcall] sysfunc5* (arg1, arg2, arg3, arg4, arg5: INTEGER): INTEGER;
-
 
135
BEGIN
-
 
136
    sys.CODE("53");               (* push    ebx              *)
-
 
137
    sys.CODE("56");               (* push    esi              *)
-
 
138
    sys.CODE("8B4508");           (* mov     eax, [ebp + 08h] *)
-
 
139
    sys.CODE("8B5D0C");           (* mov     ebx, [ebp + 0Ch] *)
-
 
140
    sys.CODE("8B4D10");           (* mov     ecx, [ebp + 10h] *)
-
 
141
    sys.CODE("8B5514");           (* mov     edx, [ebp + 14h] *)
-
 
142
    sys.CODE("8B7518");           (* mov     esi, [ebp + 18h] *)
-
 
143
    sys.CODE("CD40");             (* int     40h              *)
-
 
144
    sys.CODE("5E");               (* pop     esi              *)
-
 
145
    sys.CODE("5B");               (* pop     ebx              *)
57
BEGIN
146
    sys.CODE("C9");               (* leave                    *)
-
 
147
    sys.CODE("C21400");           (* ret     14h              *)
-
 
148
    RETURN 0
58
    FOR tmp := adr TO adr + size - 1 BY 4096 DO
149
END sysfunc5;
59
        SYSTEM.PUT(tmp, 0)
150
 
60
    END
Line 151... Line 61...
151
 
61
END mem_commit;
152
PROCEDURE switch_task;
62
 
153
VAR
63
 
Line 154... Line 64...
154
    res: INTEGER;
64
PROCEDURE switch_task;
155
BEGIN
-
 
156
    res := sysfunc2(68, 1)
-
 
157
END switch_task;
65
BEGIN
158
 
66
    K.sysfunc2(68, 1)
159
 
67
END switch_task;
Line 160... Line 68...
160
PROCEDURE futex_create (ptr: INTEGER): INTEGER;
68
 
161
    RETURN sysfunc3(77, 0, ptr)
-
 
162
END futex_create;
-
 
163
 
69
 
164
 
70
PROCEDURE futex_create (ptr: INTEGER): INTEGER;
165
PROCEDURE futex_wait (futex, value, timeout: INTEGER);
71
    RETURN K.sysfunc3(77, 0, ptr)
Line 166... Line 72...
166
VAR
72
END futex_create;
167
    res: INTEGER;
73
 
Line 193... Line 99...
193
END LeaveCriticalSection;
99
END LeaveCriticalSection;
Line 194... Line 100...
194
 
100
 
195
 
101
 
196
PROCEDURE InitializeCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
102
PROCEDURE InitializeCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
197
BEGIN
103
BEGIN
198
    CriticalSection[0] := futex_create(sys.ADR(CriticalSection[1]));
104
    CriticalSection[0] := futex_create(SYSTEM.ADR(CriticalSection[1]));
Line 199... Line 105...
199
    CriticalSection[1] := 0
105
    CriticalSection[1] := 0
Line 206... Line 112...
206
BEGIN
112
BEGIN
207
    IF size <= MAX_SIZE THEN
113
    IF size <= MAX_SIZE THEN
208
        idx := ASR(size, 5);
114
        idx := ASR(size, 5);
209
        res := pockets[idx];
115
        res := pockets[idx];
210
        IF res # 0 THEN
116
        IF res # 0 THEN
211
            sys.GET(res, pockets[idx]);
117
            SYSTEM.GET(res, pockets[idx]);
212
            sys.PUT(res, size);
118
            SYSTEM.PUT(res, size);
213
            INC(res, 4)
119
            INC(res, 4)
214
        ELSE
120
        ELSE
215
            temp := 0;
121
            temp := 0;
216
            IF heap + size >= endheap THEN
122
            IF heap + size >= endheap THEN
217
                IF sysfunc2(18, 16) > ASR(HEAP_SIZE, 10) THEN
123
                IF K.sysfunc2(18, 16) > ASR(HEAP_SIZE, 10) THEN
218
                    temp := sysfunc3(68, 12, HEAP_SIZE)
124
                    temp := K.sysfunc3(68, 12, HEAP_SIZE)
219
                ELSE
125
                ELSE
220
                    temp := 0
126
                    temp := 0
221
                END;
127
                END;
222
                IF temp # 0 THEN
128
                IF temp # 0 THEN
223
                    mem_commit(temp, HEAP_SIZE);
129
                    mem_commit(temp, HEAP_SIZE);
Line 226... Line 132...
226
                ELSE
132
                ELSE
227
                    temp := -1
133
                    temp := -1
228
                END
134
                END
229
            END;
135
            END;
230
            IF (heap # 0) & (temp # -1) THEN
136
            IF (heap # 0) & (temp # -1) THEN
231
                sys.PUT(heap, size);
137
                SYSTEM.PUT(heap, size);
232
                res := heap + 4;
138
                res := heap + 4;
233
                heap := heap + size
139
                heap := heap + size
234
            ELSE
140
            ELSE
235
                res := 0
141
                res := 0
236
            END
142
            END
237
        END
143
        END
238
    ELSE
144
    ELSE
239
        IF sysfunc2(18, 16) > ASR(size, 10) THEN
145
        IF K.sysfunc2(18, 16) > ASR(size, 10) THEN
240
            res := sysfunc3(68, 12, size);
146
            res := K.sysfunc3(68, 12, size);
241
            IF res # 0 THEN
147
            IF res # 0 THEN
242
                mem_commit(res, size);
148
                mem_commit(res, size);
243
                sys.PUT(res, size);
149
                SYSTEM.PUT(res, size);
244
                INC(res, 4)
150
                INC(res, 4)
245
            END
151
            END
246
        ELSE
152
        ELSE
247
            res := 0
153
            res := 0
248
        END
154
        END
Line 257... Line 163...
257
PROCEDURE __DISPOSE (ptr: INTEGER): INTEGER;
163
PROCEDURE __DISPOSE (ptr: INTEGER): INTEGER;
258
VAR
164
VAR
259
    size, idx: INTEGER;
165
    size, idx: INTEGER;
260
BEGIN
166
BEGIN
261
    DEC(ptr, 4);
167
    DEC(ptr, 4);
262
    sys.GET(ptr, size);
168
    SYSTEM.GET(ptr, size);
263
    IF size <= MAX_SIZE THEN
169
    IF size <= MAX_SIZE THEN
264
        idx := ASR(size, 5);
170
        idx := ASR(size, 5);
265
        sys.PUT(ptr, pockets[idx]);
171
        SYSTEM.PUT(ptr, pockets[idx]);
266
        pockets[idx] := ptr
172
        pockets[idx] := ptr
267
    ELSE
173
    ELSE
268
        size := sysfunc3(68, 13, ptr)
174
        size := K.sysfunc3(68, 13, ptr)
269
    END
175
    END
270
    RETURN 0
176
    RETURN 0
271
END __DISPOSE;
177
END __DISPOSE;
Line 272... Line 178...
272
 
178
 
273
 
179
 
274
PROCEDURE NEW_DISPOSE (func, arg: INTEGER): INTEGER;
180
PROCEDURE NEW_DISPOSE (func, arg: INTEGER): INTEGER;
-
 
181
VAR
275
VAR
182
    res: INTEGER;
-
 
183
 
276
    res: INTEGER;
184
BEGIN
-
 
185
    IF multi THEN
Line 277... Line 186...
277
BEGIN
186
        EnterCriticalSection(CriticalSection)
278
    EnterCriticalSection(CriticalSection);
187
    END;
279
 
188
 
280
    IF func = _new THEN
189
    IF func = _new THEN
281
        res := __NEW(arg)
190
        res := __NEW(arg)
Line -... Line 191...
-
 
191
    ELSIF func = _dispose THEN
282
    ELSIF func = _dispose THEN
192
        res := __DISPOSE(arg)
-
 
193
    END;
-
 
194
 
283
        res := __DISPOSE(arg)
195
    IF multi THEN
284
    END;
196
        LeaveCriticalSection(CriticalSection)
Line 285... Line 197...
285
 
197
    END
Line 296... Line 208...
296
PROCEDURE _DISPOSE* (ptr: INTEGER): INTEGER;
208
PROCEDURE _DISPOSE* (ptr: INTEGER): INTEGER;
297
    RETURN NEW_DISPOSE(_dispose, ptr)
209
    RETURN NEW_DISPOSE(_dispose, ptr)
298
END _DISPOSE;
210
END _DISPOSE;
Line 299... Line 211...
299
 
211
 
300
 
212
 
301
PROCEDURE ExitProcess* (p1: INTEGER);
213
PROCEDURE exit* (p1: INTEGER);
302
BEGIN
214
BEGIN
Line 303... Line 215...
303
    p1 := sysfunc1(-1)
215
    K.sysfunc1(-1)
304
END ExitProcess;
216
END exit;
305
 
217
 
306
 
218
 
Line 307... Line 219...
307
PROCEDURE ExitThread* (p1: INTEGER);
219
PROCEDURE exit_thread* (p1: INTEGER);
308
BEGIN
-
 
309
    p1 := sysfunc1(-1)
-
 
310
END ExitThread;
220
BEGIN
311
 
221
    K.sysfunc1(-1)
312
 
222
END exit_thread;
Line -... Line 223...
-
 
223
 
-
 
224
 
-
 
225
PROCEDURE OutChar (c: CHAR);
-
 
226
BEGIN
-
 
227
    K.sysfunc3(63, 1, ORD(c))
-
 
228
END OutChar;
-
 
229
 
313
PROCEDURE OutChar (c: CHAR);
230
 
314
VAR
231
PROCEDURE OutLn;
315
    res: INTEGER;
232
BEGIN
316
BEGIN
233
    OutChar(0DX);
317
    res := sysfunc3(63, 1, ORD(c))
234
    OutChar(0AX)
318
END OutChar;
-
 
319
 
-
 
320
 
235
END OutLn;
321
PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER);
236
 
322
VAR
237
 
323
    c: CHAR;
238
PROCEDURE OutStr (pchar: INTEGER);
324
BEGIN
239
VAR
325
    IF lpCaption # 0 THEN
240
    c: CHAR;
326
        OutChar(0DX);
241
BEGIN
-
 
242
    IF pchar # 0 THEN
-
 
243
        REPEAT
-
 
244
            SYSTEM.GET(pchar, c);
-
 
245
            IF c # 0X THEN
-
 
246
                OutChar(c)
-
 
247
            END;
-
 
248
            INC(pchar)
-
 
249
        UNTIL c = 0X
-
 
250
    END
327
        OutChar(0AX);
251
END OutStr;
328
        REPEAT
-
 
329
            sys.GET(lpCaption, c);
252
 
330
            IF c # 0X THEN
-
 
331
                OutChar(c)
-
 
332
            END;
-
 
333
            INC(lpCaption)
-
 
334
        UNTIL c = 0X;
-
 
335
        OutChar(":");
253
 
336
        OutChar(0DX);
254
PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER);
337
        OutChar(0AX)
-
 
338
    END;
255
BEGIN
339
    REPEAT
-
 
340
        sys.GET(lpText, c);
256
    IF lpCaption # 0 THEN
341
        IF c # 0X THEN
257
        OutLn;
342
            OutChar(c)
258
        OutStr(lpCaption);
Line -... Line 259...
-
 
259
        OutChar(":");
-
 
260
        OutLn
-
 
261
    END;
-
 
262
    OutStr(lpText);
-
 
263
    IF lpCaption # 0 THEN
-
 
264
        OutLn
-
 
265
    END
-
 
266
END DebugMsg;
-
 
267
 
-
 
268
 
-
 
269
PROCEDURE OutString (s: ARRAY OF CHAR);
-
 
270
VAR
-
 
271
    i: INTEGER;
-
 
272
BEGIN
-
 
273
    i := 0;
-
 
274
    WHILE (i < LEN(s)) & (s[i] # 0X) DO
-
 
275
        OutChar(s[i]);
-
 
276
        INC(i)
-
 
277
    END
-
 
278
END OutString;
-
 
279
 
-
 
280
 
-
 
281
PROCEDURE imp_error;
-
 
282
BEGIN
343
        END;
283
    OutString("import error: ");
344
        INC(lpText)
284
    IF K.imp_error.error = 1 THEN
-
 
285
        OutString("can't load "); OutString(K.imp_error.lib)
-
 
286
    ELSIF K.imp_error.error = 2 THEN
-
 
287
        OutString("not found "); OutString(K.imp_error.proc); OutString(" in "); OutString(K.imp_error.lib)
345
    UNTIL c = 0X;
288
    END;
346
    IF lpCaption # 0 THEN
289
    OutLn
-
 
290
END imp_error;
-
 
291
 
-
 
292
 
-
 
293
PROCEDURE init* (_import, code: INTEGER);
-
 
294
BEGIN
347
        OutChar(0DX);
295
    multi := FALSE;
Line -... Line 296...
-
 
296
    eol[0] := 0DX; eol[1] := 0AX; eol[2] := 0X;
-
 
297
    base := code - 36;
-
 
298
    K.sysfunc2(68, 11);
-
 
299
    InitializeCriticalSection(CriticalSection);
-
 
300
    K._init;
-
 
301
    import := (K.dll_Load(_import) = 0) & (K.imp_error.error = 0);
-
 
302
    IF ~import THEN
-
 
303
        imp_error
-
 
304
    END
-
 
305
END init;
-
 
306
 
348
        OutChar(0AX)
307
 
349
    END
308
PROCEDURE SetMultiThr* (value: BOOLEAN);