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