Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6613 leency 1
(*
7107 akron1 2
    Copyright 2016, 2017 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 API;
19
 
20
IMPORT sys := SYSTEM;
21
 
7110 akron1 22
 
6613 leency 23
CONST
24
 
7110 akron1 25
    MAX_SIZE  = 16 * 400H;
26
    HEAP_SIZE =  1 * 100000H;
27
 
28
    _new = 1;
29
    _dispose = 2;
6613 leency 30
 
7110 akron1 31
 
32
TYPE
33
 
34
    CRITICAL_SECTION = ARRAY 2 OF INTEGER;
35
 
36
 
6613 leency 37
VAR
38
 
7110 akron1 39
    heap, endheap: INTEGER;
40
    pockets: ARRAY MAX_SIZE DIV 32 + 1 OF INTEGER;
6613 leency 41
 
7110 akron1 42
    CriticalSection: CRITICAL_SECTION;
43
 
44
 
45
PROCEDURE [stdcall] zeromem* (size, adr: INTEGER);
6613 leency 46
BEGIN
7110 akron1 47
    sys.CODE("578B7D0C8B4D0833C09CFCF3AB9D5F")
48
END zeromem;
6613 leency 49
 
7110 akron1 50
 
51
PROCEDURE mem_commit* (adr, size: INTEGER);
52
VAR
53
    tmp: INTEGER;
6647 akron1 54
BEGIN
7110 akron1 55
    FOR tmp := adr TO adr + size - 1 BY 4096 DO
56
        sys.PUT(tmp, 0)
57
    END
58
END mem_commit;
6647 akron1 59
 
7110 akron1 60
 
61
PROCEDURE strncmp* (a, b, n: INTEGER): INTEGER;
62
VAR
63
    A, B: CHAR;
64
    Res: INTEGER;
6613 leency 65
BEGIN
7110 akron1 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
6613 leency 77
    END
7110 akron1 78
    RETURN Res
79
END strncmp;
6613 leency 80
 
7110 akron1 81
 
82
PROCEDURE [stdcall] sysfunc1* (arg1: INTEGER): INTEGER;
6613 leency 83
BEGIN
7110 akron1 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;
6613 leency 90
 
7110 akron1 91
 
92
PROCEDURE [stdcall] sysfunc2* (arg1, arg2: INTEGER): INTEGER;
6613 leency 93
BEGIN
7110 akron1 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;
6613 leency 103
 
7110 akron1 104
 
105
PROCEDURE [stdcall] sysfunc3* (arg1, arg2, arg3: INTEGER): INTEGER;
6613 leency 106
BEGIN
7110 akron1 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
6613 leency 116
END sysfunc3;
117
 
7110 akron1 118
 
119
PROCEDURE [stdcall] sysfunc4* (arg1, arg2, arg3, arg4: INTEGER): INTEGER;
6613 leency 120
BEGIN
7110 akron1 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              *)
146
    sys.CODE("C9");               (* leave                    *)
147
    sys.CODE("C21400");           (* ret     14h              *)
148
    RETURN 0
149
END sysfunc5;
150
 
151
 
152
PROCEDURE switch_task;
153
VAR
154
    res: INTEGER;
155
BEGIN
156
    res := sysfunc2(68, 1)
157
END switch_task;
158
 
159
 
160
PROCEDURE futex_create (ptr: INTEGER): INTEGER;
161
    RETURN sysfunc3(77, 0, ptr)
162
END futex_create;
163
 
164
 
165
PROCEDURE futex_wait (futex, value, timeout: INTEGER);
166
VAR
167
    res: INTEGER;
168
BEGIN
169
    res := sysfunc5(77, 2, futex, value, timeout)
170
END futex_wait;
171
 
172
 
173
PROCEDURE futex_wake (futex, number: INTEGER);
174
VAR
175
    res: INTEGER;
176
BEGIN
177
    res := sysfunc4(77, 3, futex, number)
178
END futex_wake;
179
 
180
 
181
PROCEDURE EnterCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
182
BEGIN
183
    switch_task;
184
    futex_wait(CriticalSection[0], 1, 10000);
185
    CriticalSection[1] := 1
186
END EnterCriticalSection;
187
 
188
 
189
PROCEDURE LeaveCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
190
BEGIN
191
    CriticalSection[1] := 0;
192
    futex_wake(CriticalSection[0], 1)
193
END LeaveCriticalSection;
194
 
195
 
196
PROCEDURE InitializeCriticalSection* (VAR CriticalSection: CRITICAL_SECTION);
197
BEGIN
198
    CriticalSection[0] := futex_create(sys.ADR(CriticalSection[1]));
199
    CriticalSection[1] := 0
200
END InitializeCriticalSection;
201
 
202
 
203
PROCEDURE __NEW (size: INTEGER): INTEGER;
204
VAR
205
    res, idx, temp: INTEGER;
206
BEGIN
207
    IF size <= MAX_SIZE THEN
208
        idx := ASR(size, 5);
209
        res := pockets[idx];
210
        IF res # 0 THEN
211
            sys.GET(res, pockets[idx]);
212
            sys.PUT(res, size);
213
            INC(res, 4)
214
        ELSE
215
            temp := 0;
216
            IF heap + size >= endheap THEN
217
                IF sysfunc2(18, 16) > ASR(HEAP_SIZE, 10) THEN
218
                    temp := sysfunc3(68, 12, HEAP_SIZE)
219
                ELSE
220
                    temp := 0
221
                END;
222
                IF temp # 0 THEN
223
                    mem_commit(temp, HEAP_SIZE);
224
                    heap := temp;
225
                    endheap := heap + HEAP_SIZE
226
                ELSE
227
                    temp := -1
228
                END
229
            END;
230
            IF (heap # 0) & (temp # -1) THEN
231
                sys.PUT(heap, size);
232
                res := heap + 4;
233
                heap := heap + size
234
            ELSE
235
                res := 0
236
            END
237
        END
6613 leency 238
    ELSE
7110 akron1 239
        IF sysfunc2(18, 16) > ASR(size, 10) THEN
240
            res := sysfunc3(68, 12, size);
241
            IF res # 0 THEN
242
                mem_commit(res, size);
243
                sys.PUT(res, size);
244
                INC(res, 4)
245
            END
7107 akron1 246
        ELSE
7110 akron1 247
            res := 0
7107 akron1 248
        END
7110 akron1 249
    END;
250
    IF res # 0 THEN
251
        zeromem(ASR(size, 2) - 1, res)
6613 leency 252
    END
7110 akron1 253
    RETURN res
254
END __NEW;
255
 
256
 
257
PROCEDURE __DISPOSE (ptr: INTEGER): INTEGER;
258
VAR
259
    size, idx: INTEGER;
260
BEGIN
261
    DEC(ptr, 4);
262
    sys.GET(ptr, size);
263
    IF size <= MAX_SIZE THEN
264
        idx := ASR(size, 5);
265
        sys.PUT(ptr, pockets[idx]);
266
        pockets[idx] := ptr
6613 leency 267
    ELSE
7110 akron1 268
        size := sysfunc3(68, 13, ptr)
6613 leency 269
    END
7110 akron1 270
    RETURN 0
271
END __DISPOSE;
272
 
273
 
274
PROCEDURE NEW_DISPOSE (func, arg: INTEGER): INTEGER;
275
VAR
276
    res: INTEGER;
277
BEGIN
278
    EnterCriticalSection(CriticalSection);
279
 
280
    IF func = _new THEN
281
        res := __NEW(arg)
282
    ELSIF func = _dispose THEN
283
        res := __DISPOSE(arg)
284
    END;
285
 
286
    LeaveCriticalSection(CriticalSection)
287
    RETURN res
288
END NEW_DISPOSE;
289
 
290
 
291
PROCEDURE _NEW* (size: INTEGER): INTEGER;
292
    RETURN NEW_DISPOSE(_new, size)
6613 leency 293
END _NEW;
7110 akron1 294
 
6613 leency 295
 
7110 akron1 296
PROCEDURE _DISPOSE* (ptr: INTEGER): INTEGER;
297
    RETURN NEW_DISPOSE(_dispose, ptr)
6613 leency 298
END _DISPOSE;
299
 
7110 akron1 300
 
301
PROCEDURE ExitProcess* (p1: INTEGER);
6613 leency 302
BEGIN
303
  p1 := sysfunc1(-1)
7110 akron1 304
END ExitProcess;
6613 leency 305
 
7110 akron1 306
 
307
PROCEDURE ExitThread* (p1: INTEGER);
7107 akron1 308
BEGIN
7110 akron1 309
    p1 := sysfunc1(-1)
310
END ExitThread;
7107 akron1 311
 
7110 akron1 312
 
313
PROCEDURE OutChar (c: CHAR);
314
VAR
315
    res: INTEGER;
6613 leency 316
BEGIN
7110 akron1 317
    res := sysfunc3(63, 1, ORD(c))
318
END OutChar;
6613 leency 319
 
7110 akron1 320
 
321
PROCEDURE DebugMsg* (lpText, lpCaption: INTEGER);
322
VAR
323
    c: CHAR;
6613 leency 324
BEGIN
7110 akron1 325
    IF lpCaption # 0 THEN
326
        OutChar(0DX);
327
        OutChar(0AX);
328
        REPEAT
329
            sys.GET(lpCaption, c);
330
            IF c # 0X THEN
331
                OutChar(c)
332
            END;
333
            INC(lpCaption)
334
        UNTIL c = 0X;
335
        OutChar(":");
336
        OutChar(0DX);
337
        OutChar(0AX)
338
    END;
6613 leency 339
    REPEAT
7110 akron1 340
        sys.GET(lpText, c);
341
        IF c # 0X THEN
342
            OutChar(c)
343
        END;
344
        INC(lpText)
6613 leency 345
    UNTIL c = 0X;
7110 akron1 346
    IF lpCaption # 0 THEN
347
        OutChar(0DX);
348
        OutChar(0AX)
349
    END
350
END DebugMsg;
6613 leency 351
 
7110 akron1 352
 
6613 leency 353
PROCEDURE init* (p1: INTEGER);
354
BEGIN
7110 akron1 355
    p1 := sysfunc2(68, 11);
356
    InitializeCriticalSection(CriticalSection)
357
END init;
6613 leency 358
 
7110 akron1 359
 
6613 leency 360
END API.