Subversion Repositories Kolibri OS

Rev

Rev 1635 | Rev 2138 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1635 Rev 2130
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 1615 $
8
$Revision: 2130 $
9
 
9
 
10
 
10
 
11
struc MEM_BLOCK
11
struc MEM_BLOCK
12
{  .next_block  dd ?
12
{  .next_block  dd ?
13
   .prev_block  dd ? ;+4
13
   .prev_block  dd ? ;+4
14
   .list_fd     dd ? ;+8
14
   .list_fd     dd ? ;+8
15
   .list_bk     dd ? ;+12
15
   .list_bk     dd ? ;+12
16
   .base        dd ? ;+16
16
   .base        dd ? ;+16
17
   .size        dd ? ;+20
17
   .size        dd ? ;+20
18
   .flags       dd ? ;+24
18
   .flags       dd ? ;+24
19
   .handle      dd ? ;+28
19
   .handle      dd ? ;+28
20
}
20
}
21
 
21
 
22
MEM_LIST_OFFSET equ  8
22
MEM_LIST_OFFSET equ  8
23
FREE_BLOCK      equ  4
23
FREE_BLOCK      equ  4
24
USED_BLOCK      equ  8
24
USED_BLOCK      equ  8
25
DONT_FREE_BLOCK equ  10h
25
DONT_FREE_BLOCK equ  10h
26
 
26
 
27
virtual at 0
27
virtual at 0
28
  MEM_BLOCK MEM_BLOCK
28
  MEM_BLOCK MEM_BLOCK
29
end virtual
29
end virtual
30
 
30
 
31
MEM_BLOCK_SIZE equ 8*4
31
MEM_BLOCK_SIZE equ 8*4
32
 
32
 
33
block_next   equ MEM_BLOCK.next_block
33
block_next   equ MEM_BLOCK.next_block
34
block_prev   equ MEM_BLOCK.prev_block
34
block_prev   equ MEM_BLOCK.prev_block
35
list_fd      equ MEM_BLOCK.list_fd
35
list_fd      equ MEM_BLOCK.list_fd
36
list_bk      equ MEM_BLOCK.list_bk
36
list_bk      equ MEM_BLOCK.list_bk
37
block_base   equ MEM_BLOCK.base
37
block_base   equ MEM_BLOCK.base
38
block_size   equ MEM_BLOCK.size
38
block_size   equ MEM_BLOCK.size
39
block_flags  equ MEM_BLOCK.flags
39
block_flags  equ MEM_BLOCK.flags
40
 
40
 
41
macro calc_index op
41
macro calc_index op
42
{          shr op, 12
42
{          shr op, 12
43
           dec op
43
           dec op
44
           cmp op, 63
44
           cmp op, 63
45
           jna @f
45
           jna @f
46
           mov op, 63
46
           mov op, 63
47
@@:
47
@@:
48
}
48
}
49
 
49
 
50
macro remove_from_list op
50
macro remove_from_list op
51
{          mov edx, [op+list_fd]
51
{          mov edx, [op+list_fd]
52
           mov ecx, [op+list_bk]
52
           mov ecx, [op+list_bk]
53
           test edx, edx
53
           test edx, edx
54
           jz @f
54
           jz @f
55
           mov [edx+list_bk], ecx
55
           mov [edx+list_bk], ecx
56
@@:
56
@@:
57
           test ecx, ecx
57
           test ecx, ecx
58
           jz @f
58
           jz @f
59
           mov [ecx+list_fd], edx
59
           mov [ecx+list_fd], edx
60
@@:
60
@@:
61
           mov [op+list_fd],0
61
           mov [op+list_fd],0
62
           mov [op+list_bk],0
62
           mov [op+list_bk],0
63
}
63
}
64
 
64
 
65
macro remove_from_free op
65
macro remove_from_free op
66
{
66
{
67
           remove_from_list op
67
           remove_from_list op
68
 
68
 
69
           mov eax, [op+block_size]
69
           mov eax, [op+block_size]
70
           calc_index eax
70
           calc_index eax
71
           cmp [mem_block_list+eax*4], op
71
           cmp [mem_block_list+eax*4], op
72
           jne @f
72
           jne @f
73
           mov [mem_block_list+eax*4], edx
73
           mov [mem_block_list+eax*4], edx
74
@@:
74
@@:
75
           cmp [mem_block_list+eax*4], 0
75
           cmp [mem_block_list+eax*4], 0
76
           jne @f
76
           jne @f
77
           btr [mem_block_mask], eax
77
           btr [mem_block_mask], eax
78
@@:
78
@@:
79
}
79
}
80
 
80
 
81
macro remove_from_used op
81
macro remove_from_used op
82
{
82
{
83
           mov edx, [op+list_fd]
83
           mov edx, [op+list_fd]
84
           mov ecx, [op+list_bk]
84
           mov ecx, [op+list_bk]
85
           mov [edx+list_bk], ecx
85
           mov [edx+list_bk], ecx
86
           mov [ecx+list_fd], edx
86
           mov [ecx+list_fd], edx
87
           mov [op+list_fd], 0
87
           mov [op+list_fd], 0
88
           mov [op+list_bk], 0
88
           mov [op+list_bk], 0
89
}
89
}
90
 
90
 
91
align 4
91
align 4
92
proc init_kernel_heap
92
proc init_kernel_heap
93
 
93
 
94
           mov ecx, 64
94
           mov ecx, 64
95
           mov edi, mem_block_list
95
           mov edi, mem_block_list
96
           xor eax, eax
96
           xor eax, eax
97
           cld
97
           cld
98
           rep stosd
98
           rep stosd
99
 
99
 
100
           mov ecx, 512/4
100
           mov ecx, 512/4
101
           mov edi, mem_block_map
101
           mov edi, mem_block_map
102
           not eax
102
           not eax
103
           rep stosd
103
           rep stosd
104
 
104
 
105
           mov [mem_block_start], mem_block_map
105
           mov [mem_block_start], mem_block_map
106
           mov [mem_block_end], mem_block_map+512
106
           mov [mem_block_end], mem_block_map+512
107
           mov [mem_block_arr], HEAP_BASE
107
           mov [mem_block_arr], HEAP_BASE
108
 
108
 
109
           mov eax, mem_used.fd-MEM_LIST_OFFSET
109
           mov eax, mem_used.fd-MEM_LIST_OFFSET
110
           mov [mem_used.fd], eax
110
           mov [mem_used.fd], eax
111
           mov [mem_used.bk], eax
111
           mov [mem_used.bk], eax
112
 
112
 
113
           stdcall alloc_pages, dword 32
113
           stdcall alloc_pages, dword 32
114
           mov ecx, 32
114
           mov ecx, 32
115
           mov edx, eax
115
           mov edx, eax
116
           mov edi, HEAP_BASE
116
           mov edi, HEAP_BASE
117
.l1:
117
.l1:
118
           stdcall map_page,edi,edx,PG_SW
118
           stdcall map_page,edi,edx,PG_SW
119
           add edi, 0x1000
119
           add edi, 0x1000
120
           add edx, 0x1000
120
           add edx, 0x1000
121
           dec ecx
121
           dec ecx
122
           jnz .l1
122
           jnz .l1
123
 
123
 
124
           mov edi, HEAP_BASE
124
           mov edi, HEAP_BASE
125
           mov ebx, HEAP_BASE+MEM_BLOCK_SIZE
125
           mov ebx, HEAP_BASE+MEM_BLOCK_SIZE
126
           xor eax, eax
126
           xor eax, eax
127
           mov [edi+block_next], ebx
127
           mov [edi+block_next], ebx
128
           mov [edi+block_prev], eax
128
           mov [edi+block_prev], eax
129
           mov [edi+list_fd], eax
129
           mov [edi+list_fd], eax
130
           mov [edi+list_bk], eax
130
           mov [edi+list_bk], eax
131
           mov [edi+block_base], HEAP_BASE
131
           mov [edi+block_base], HEAP_BASE
132
           mov [edi+block_size], 4096*MEM_BLOCK_SIZE
132
           mov [edi+block_size], 4096*MEM_BLOCK_SIZE
133
           mov [edi+block_flags], USED_BLOCK
133
           mov [edi+block_flags], USED_BLOCK
134
 
134
 
135
           mov [ebx+block_next], eax
135
           mov [ebx+block_next], eax
136
           mov [ebx+block_prev], eax
136
           mov [ebx+block_prev], eax
137
           mov [ebx+list_fd], eax
137
           mov [ebx+list_fd], eax
138
           mov [ebx+list_bk], eax
138
           mov [ebx+list_bk], eax
139
           mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
139
           mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
140
 
140
 
141
           mov ecx, [pg_data.kernel_pages]
141
           mov ecx, [pg_data.kernel_pages]
142
           shl ecx, 12
142
           shl ecx, 12
143
           sub ecx, HEAP_BASE-OS_BASE+4096*MEM_BLOCK_SIZE
143
           sub ecx, HEAP_BASE-OS_BASE+4096*MEM_BLOCK_SIZE
144
           mov [heap_size], ecx
144
           mov [heap_size], ecx
145
           mov [heap_free], ecx
145
           mov [heap_free], ecx
146
           mov [ebx+block_size], ecx
146
           mov [ebx+block_size], ecx
147
           mov [ebx+block_flags], FREE_BLOCK
147
           mov [ebx+block_flags], FREE_BLOCK
148
 
148
 
149
           mov [mem_block_mask], eax
149
           mov [mem_block_mask], eax
150
           mov [mem_block_mask+4],0x80000000
150
           mov [mem_block_mask+4],0x80000000
151
 
151
 
152
           mov [mem_block_list+63*4], ebx
152
           mov [mem_block_list+63*4], ebx
153
           mov byte [mem_block_map], 0xFC
153
           mov byte [mem_block_map], 0xFC
154
           and [heap_mutex], 0
154
           mov ecx, heap_mutex
-
 
155
           call mutex_init
155
           mov [heap_blocks], 4095
156
           mov [heap_blocks], 4095
156
           mov [free_blocks], 4094
157
           mov [free_blocks], 4094
157
           ret
158
           ret
158
endp
159
endp
159
 
160
 
160
; param
161
; param
161
;  eax= required size
162
;  eax= required size
162
;
163
;
163
; retval
164
; retval
164
;  edi= memory block descriptor
165
;  edi= memory block descriptor
165
;  ebx= descriptor index
166
;  ebx= descriptor index
166
 
167
 
167
align 4
168
align 4
168
get_small_block:
169
get_small_block:
169
           mov ecx, eax
170
           mov ecx, eax
170
           shr ecx, 12
171
           shr ecx, 12
171
           dec ecx
172
           dec ecx
172
           cmp ecx, 63
173
           cmp ecx, 63
173
           jle .get_index
174
           jle .get_index
174
           mov ecx, 63
175
           mov ecx, 63
175
.get_index:
176
.get_index:
176
           lea esi, [mem_block_mask]
177
           lea esi, [mem_block_mask]
177
           xor ebx, ebx
178
           xor ebx, ebx
178
           or edx, -1
179
           or edx, -1
179
 
180
 
180
           cmp ecx, 32
181
           cmp ecx, 32
181
           jb .bit_test
182
           jb .bit_test
182
 
183
 
183
           sub ecx, 32
184
           sub ecx, 32
184
           add ebx, 32
185
           add ebx, 32
185
           add esi, 4
186
           add esi, 4
186
.bit_test:
187
.bit_test:
187
           shl edx, cl
188
           shl edx, cl
188
           and edx, [esi]
189
           and edx, [esi]
189
.find:
190
.find:
190
           bsf edi, edx
191
           bsf edi, edx
191
           jz .high_mask
192
           jz .high_mask
192
           add ebx, edi
193
           add ebx, edi
193
           mov edi, [mem_block_list+ebx*4]
194
           mov edi, [mem_block_list+ebx*4]
194
.check_size:
195
.check_size:
195
           cmp eax, [edi+block_size]
196
           cmp eax, [edi+block_size]
196
           ja .next
197
           ja .next
197
           ret
198
           ret
198
 
199
 
199
.high_mask:
200
.high_mask:
200
           add esi, 4
201
           add esi, 4
201
           cmp esi, mem_block_mask+8
202
           cmp esi, mem_block_mask+8
202
           jae .err
203
           jae .err
203
           add ebx, 32
204
           add ebx, 32
204
           mov edx, [esi]
205
           mov edx, [esi]
205
           jmp .find
206
           jmp .find
206
.next:
207
.next:
207
           mov edi, [edi+list_fd]
208
           mov edi, [edi+list_fd]
208
           test edi, edi
209
           test edi, edi
209
           jnz .check_size
210
           jnz .check_size
210
.err:
211
.err:
211
           xor edi, edi
212
           xor edi, edi
212
           ret
213
           ret
213
 
214
 
214
align 4
215
align 4
215
alloc_mem_block:
216
alloc_mem_block:
216
 
217
 
217
           mov ebx, [mem_block_start]
218
           mov ebx, [mem_block_start]
218
           mov ecx, [mem_block_end]
219
           mov ecx, [mem_block_end]
219
.l1:
220
.l1:
220
           bsf eax,[ebx];
221
           bsf eax,[ebx];
221
           jnz found
222
           jnz found
222
           add ebx,4
223
           add ebx,4
223
           cmp ebx, ecx
224
           cmp ebx, ecx
224
           jb .l1
225
           jb .l1
225
           xor eax,eax
226
           xor eax,eax
226
           ret
227
           ret
227
 
228
 
228
found:
229
found:
229
           btr [ebx], eax
230
           btr [ebx], eax
230
           mov [mem_block_start],ebx
231
           mov [mem_block_start],ebx
231
           sub ebx, mem_block_map
232
           sub ebx, mem_block_map
232
           lea eax,[eax+ebx*8]
233
           lea eax,[eax+ebx*8]
233
           shl eax, 5
234
           shl eax, 5
234
           add eax, [mem_block_arr]
235
           add eax, [mem_block_arr]
235
           dec [free_blocks]
236
           dec [free_blocks]
236
           ret
237
           ret
237
align 4
238
align 4
238
free_mem_block:
239
free_mem_block:
239
           mov dword [eax], 0
240
           mov dword [eax], 0
240
           mov dword [eax+4], 0
241
           mov dword [eax+4], 0
241
           mov dword [eax+8], 0
242
           mov dword [eax+8], 0
242
           mov dword [eax+12], 0
243
           mov dword [eax+12], 0
243
           mov dword [eax+16], 0
244
           mov dword [eax+16], 0
244
;           mov dword [eax+20], 0
245
;           mov dword [eax+20], 0
245
           mov dword [eax+24], 0
246
           mov dword [eax+24], 0
246
           mov dword [eax+28], 0
247
           mov dword [eax+28], 0
247
 
248
 
248
           sub eax, [mem_block_arr]
249
           sub eax, [mem_block_arr]
249
           shr eax, 5
250
           shr eax, 5
250
 
251
 
251
           mov ebx, mem_block_map
252
           mov ebx, mem_block_map
252
           bts [ebx], eax
253
           bts [ebx], eax
253
           inc [free_blocks]
254
           inc [free_blocks]
254
           shr eax, 3
255
           shr eax, 3
255
           and eax, not 3
256
           and eax, not 3
256
           add eax, ebx
257
           add eax, ebx
257
           cmp [mem_block_start], eax
258
           cmp [mem_block_start], eax
258
           ja @f
259
           ja @f
259
           ret
260
           ret
260
@@:
261
@@:
261
           mov [mem_block_start], eax
262
           mov [mem_block_start], eax
262
	   ret
263
	   ret
263
.err:
264
.err:
264
           xor eax, eax
265
           xor eax, eax
265
	   ret
266
	   ret
266
 
267
 
267
align 4
268
align 4
268
proc alloc_kernel_space stdcall, size:dword
269
proc alloc_kernel_space stdcall, size:dword
269
           local block_ind:DWORD
270
           local block_ind:DWORD
270
 
271
 
271
           push ebx
272
           push ebx
272
           push esi
273
           push esi
273
           push edi
274
           push edi
-
 
275
 
-
 
276
           mov ecx, heap_mutex
-
 
277
           call mutex_lock
274
 
278
 
275
           mov eax, [size]
279
           mov eax, [size]
276
           add eax, 4095
280
           add eax, 4095
277
           and eax, not 4095
281
           and eax, not 4095
278
           mov [size], eax
282
           mov [size], eax
279
 
-
 
280
           mov ebx, heap_mutex
-
 
281
           call wait_mutex    ;ebx
-
 
282
 
283
 
283
           cmp eax, [heap_free]
284
           cmp eax, [heap_free]
284
           ja .error
285
           ja .error
285
 
286
 
286
           call get_small_block ; eax
287
           call get_small_block ; eax
287
           test edi, edi
288
           test edi, edi
288
           jz .error
289
           jz .error
289
 
290
 
290
           cmp [edi+block_flags], FREE_BLOCK
291
           cmp [edi+block_flags], FREE_BLOCK
291
           jne .error
292
           jne .error
292
 
293
 
293
           mov [block_ind], ebx   ;index of allocated block
294
           mov [block_ind], ebx   ;index of allocated block
294
 
295
 
295
           mov eax, [edi+block_size]
296
           mov eax, [edi+block_size]
296
           cmp eax, [size]
297
           cmp eax, [size]
297
           je .m_eq_size
298
           je .m_eq_size
298
 
299
 
299
           call alloc_mem_block
300
           call alloc_mem_block
300
           and eax, eax
301
           and eax, eax
301
           jz .error
302
           jz .error
302
 
303
 
303
           mov esi, eax           ;esi - splitted block
304
           mov esi, eax           ;esi - splitted block
304
 
305
 
305
           mov [esi+block_next], edi
306
           mov [esi+block_next], edi
306
           mov eax, [edi+block_prev]
307
           mov eax, [edi+block_prev]
307
           mov [esi+block_prev], eax
308
           mov [esi+block_prev], eax
308
           mov [edi+block_prev], esi
309
           mov [edi+block_prev], esi
309
           mov [esi+list_fd], 0
310
           mov [esi+list_fd], 0
310
           mov [esi+list_bk], 0
311
           mov [esi+list_bk], 0
311
           and eax, eax
312
           and eax, eax
312
           jz @f
313
           jz @f
313
           mov [eax+block_next], esi
314
           mov [eax+block_next], esi
314
@@:
315
@@:
315
           mov ebx, [edi+block_base]
316
           mov ebx, [edi+block_base]
316
           mov [esi+block_base], ebx
317
           mov [esi+block_base], ebx
317
           mov edx, [size]
318
           mov edx, [size]
318
           mov [esi+block_size], edx
319
           mov [esi+block_size], edx
319
           add [edi+block_base], edx
320
           add [edi+block_base], edx
320
           sub [edi+block_size], edx
321
           sub [edi+block_size], edx
321
 
322
 
322
           mov eax, [edi+block_size]
323
           mov eax, [edi+block_size]
323
           shr eax, 12
324
           shr eax, 12
324
           sub eax, 1
325
           sub eax, 1
325
           cmp eax, 63
326
           cmp eax, 63
326
           jna @f
327
           jna @f
327
           mov eax, 63
328
           mov eax, 63
328
@@:
329
@@:
329
           cmp eax, [block_ind]
330
           cmp eax, [block_ind]
330
           je .m_eq_ind
331
           je .m_eq_ind
331
 
332
 
332
           remove_from_list edi
333
           remove_from_list edi
333
 
334
 
334
           mov ecx, [block_ind]
335
           mov ecx, [block_ind]
335
           mov [mem_block_list+ecx*4], edx
336
           mov [mem_block_list+ecx*4], edx
336
 
337
 
337
           test edx, edx
338
           test edx, edx
338
           jnz @f
339
           jnz @f
339
           btr [mem_block_mask], ecx
340
           btr [mem_block_mask], ecx
340
@@:
341
@@:
341
           mov edx, [mem_block_list+eax*4]
342
           mov edx, [mem_block_list+eax*4]
342
           mov [edi+list_fd], edx
343
           mov [edi+list_fd], edx
343
           test edx, edx
344
           test edx, edx
344
           jz @f
345
           jz @f
345
           mov [edx+list_bk], edi
346
           mov [edx+list_bk], edi
346
@@:
347
@@:
347
           mov [mem_block_list+eax*4], edi
348
           mov [mem_block_list+eax*4], edi
348
           bts [mem_block_mask], eax
349
           bts [mem_block_mask], eax
349
.m_eq_ind:
350
.m_eq_ind:
350
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
351
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
351
           mov edx, [ecx+list_fd]
352
           mov edx, [ecx+list_fd]
352
           mov [esi+list_fd], edx
353
           mov [esi+list_fd], edx
353
           mov [esi+list_bk], ecx
354
           mov [esi+list_bk], ecx
354
           mov [ecx+list_fd], esi
355
           mov [ecx+list_fd], esi
355
           mov [edx+list_bk], esi
356
           mov [edx+list_bk], esi
356
 
357
 
357
           mov [esi+block_flags], USED_BLOCK
358
           mov [esi+block_flags], USED_BLOCK
358
           mov eax, [esi+block_base]
-
 
359
           mov ebx, [size]
359
           mov ebx, [size]
360
           sub [heap_free], ebx
360
           sub [heap_free], ebx
361
           and [heap_mutex], 0
361
           mov ecx, heap_mutex
-
 
362
           call mutex_unlock
-
 
363
           mov eax, [esi+block_base]
362
           pop edi
364
           pop edi
363
           pop esi
365
           pop esi
364
           pop ebx
366
           pop ebx
365
           ret
367
           ret
366
.m_eq_size:
368
.m_eq_size:
367
           remove_from_list edi
369
           remove_from_list edi
368
           mov [mem_block_list+ebx*4], edx
370
           mov [mem_block_list+ebx*4], edx
369
           and edx, edx
371
           and edx, edx
370
           jnz @f
372
           jnz @f
371
           btr [mem_block_mask], ebx
373
           btr [mem_block_mask], ebx
372
@@:
374
@@:
373
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
375
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
374
           mov edx, [ecx+list_fd]
376
           mov edx, [ecx+list_fd]
375
           mov [edi+list_fd], edx
377
           mov [edi+list_fd], edx
376
           mov [edi+list_bk], ecx
378
           mov [edi+list_bk], ecx
377
           mov [ecx+list_fd], edi
379
           mov [ecx+list_fd], edi
378
           mov [edx+list_bk], edi
380
           mov [edx+list_bk], edi
379
 
381
 
380
           mov [edi+block_flags], USED_BLOCK
382
           mov [edi+block_flags], USED_BLOCK
381
           mov eax, [edi+block_base]
-
 
382
           mov ebx, [size]
383
           mov ebx, [size]
383
           sub [heap_free], ebx
384
           sub [heap_free], ebx
384
           and [heap_mutex], 0
385
           mov ecx, heap_mutex
-
 
386
           call mutex_unlock
-
 
387
           mov eax, [edi+block_base]
385
           pop edi
388
           pop edi
386
           pop esi
389
           pop esi
387
           pop ebx
390
           pop ebx
388
           ret
391
           ret
389
.error:
392
.error:
-
 
393
           mov ecx, heap_mutex
-
 
394
           call mutex_unlock
390
           xor eax, eax
395
           xor eax, eax
391
           mov [heap_mutex], eax
-
 
392
           pop edi
396
           pop edi
393
           pop esi
397
           pop esi
394
           pop ebx
398
           pop ebx
395
           ret
399
           ret
396
endp
400
endp
397
 
401
 
398
align 4
402
align 4
399
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
403
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
400
           push ebx
404
           push ebx
401
           push esi
405
           push esi
402
           push edi
406
           push edi
-
 
407
 
403
           mov ebx, heap_mutex
408
           mov ecx, heap_mutex
404
           call wait_mutex    ;ebx
409
           call mutex_lock
405
 
410
 
406
           mov eax, [base]
411
           mov eax, [base]
407
           mov esi, [mem_used.fd]
412
           mov esi, [mem_used.fd]
408
@@:
413
@@:
409
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
414
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
410
           je .fail
415
           je .fail
411
 
416
 
412
           cmp [esi+block_base], eax
417
           cmp [esi+block_base], eax
413
           je .found
418
           je .found
414
           mov esi, [esi+list_fd]
419
           mov esi, [esi+list_fd]
415
           jmp @b
420
           jmp @b
416
.found:
421
.found:
417
           cmp [esi+block_flags], USED_BLOCK
422
           cmp [esi+block_flags], USED_BLOCK
418
           jne .fail
423
           jne .fail
419
 
424
 
420
           mov eax, [esi+block_size]
425
           mov eax, [esi+block_size]
421
           add [heap_free], eax
426
           add [heap_free], eax
422
 
427
 
423
           mov edi, [esi+block_next]
428
           mov edi, [esi+block_next]
424
           test edi, edi
429
           test edi, edi
425
           jz .prev
430
           jz .prev
426
 
431
 
427
           cmp [edi+block_flags], FREE_BLOCK
432
           cmp [edi+block_flags], FREE_BLOCK
428
           jne .prev
433
           jne .prev
429
 
434
 
430
           remove_from_free edi
435
           remove_from_free edi
431
 
436
 
432
           mov edx, [edi+block_next]
437
           mov edx, [edi+block_next]
433
           mov [esi+block_next], edx
438
           mov [esi+block_next], edx
434
           test edx, edx
439
           test edx, edx
435
           jz @f
440
           jz @f
436
 
441
 
437
           mov [edx+block_prev], esi
442
           mov [edx+block_prev], esi
438
@@:
443
@@:
439
           mov ecx, [edi+block_size]
444
           mov ecx, [edi+block_size]
440
           add [esi+block_size], ecx
445
           add [esi+block_size], ecx
441
 
446
 
442
           mov eax, edi
447
           mov eax, edi
443
           call free_mem_block
448
           call free_mem_block
444
.prev:
449
.prev:
445
           mov edi, [esi+block_prev]
450
           mov edi, [esi+block_prev]
446
           test edi, edi
451
           test edi, edi
447
           jz .insert
452
           jz .insert
448
 
453
 
449
           cmp [edi+block_flags], FREE_BLOCK
454
           cmp [edi+block_flags], FREE_BLOCK
450
           jne .insert
455
           jne .insert
451
 
456
 
452
           remove_from_used esi
457
           remove_from_used esi
453
 
458
 
454
           mov edx, [esi+block_next]
459
           mov edx, [esi+block_next]
455
           mov [edi+block_next], edx
460
           mov [edi+block_next], edx
456
           test edx, edx
461
           test edx, edx
457
           jz @f
462
           jz @f
458
           mov [edx+block_prev], edi
463
           mov [edx+block_prev], edi
459
@@:
464
@@:
460
           mov eax, esi
465
           mov eax, esi
461
           call free_mem_block
466
           call free_mem_block
462
 
467
 
463
           mov ecx, [edi+block_size]
468
           mov ecx, [edi+block_size]
464
           mov eax, [esi+block_size]
469
           mov eax, [esi+block_size]
465
           add eax, ecx
470
           add eax, ecx
466
           mov [edi+block_size], eax
471
           mov [edi+block_size], eax
467
 
472
 
468
           calc_index eax
473
           calc_index eax
469
           calc_index ecx
474
           calc_index ecx
470
           cmp eax, ecx
475
           cmp eax, ecx
471
           je .m_eq
476
           je .m_eq
472
 
477
 
473
           push ecx
478
           push ecx
474
           remove_from_list edi
479
           remove_from_list edi
475
           pop ecx
480
           pop ecx
476
 
481
 
477
           cmp [mem_block_list+ecx*4], edi
482
           cmp [mem_block_list+ecx*4], edi
478
           jne @f
483
           jne @f
479
           mov [mem_block_list+ecx*4], edx
484
           mov [mem_block_list+ecx*4], edx
480
@@:
485
@@:
481
           cmp [mem_block_list+ecx*4], 0
486
           cmp [mem_block_list+ecx*4], 0
482
           jne @f
487
           jne @f
483
           btr [mem_block_mask], ecx
488
           btr [mem_block_mask], ecx
484
@@:
489
@@:
485
           mov esi, [mem_block_list+eax*4]
490
           mov esi, [mem_block_list+eax*4]
486
           mov [mem_block_list+eax*4], edi
491
           mov [mem_block_list+eax*4], edi
487
           mov [edi+list_fd], esi
492
           mov [edi+list_fd], esi
488
           test esi, esi
493
           test esi, esi
489
           jz @f
494
           jz @f
490
           mov [esi+list_bk], edi
495
           mov [esi+list_bk], edi
491
@@:
496
@@:
492
           bts [mem_block_mask], eax
497
           bts [mem_block_mask], eax
493
.m_eq:
498
.m_eq:
-
 
499
           mov ecx, heap_mutex
-
 
500
           call mutex_unlock
494
           xor eax, eax
501
           xor eax, eax
495
           mov [heap_mutex], eax
-
 
496
           dec eax
502
           not eax
497
           pop edi
503
           pop edi
498
           pop esi
504
           pop esi
499
           pop ebx
505
           pop ebx
500
           ret
506
           ret
501
.insert:
507
.insert:
502
           remove_from_used esi
508
           remove_from_used esi
503
 
509
 
504
           mov eax, [esi+block_size]
510
           mov eax, [esi+block_size]
505
           calc_index eax
511
           calc_index eax
506
 
512
 
507
           mov edi, [mem_block_list+eax*4]
513
           mov edi, [mem_block_list+eax*4]
508
           mov [mem_block_list+eax*4], esi
514
           mov [mem_block_list+eax*4], esi
509
           mov [esi+list_fd], edi
515
           mov [esi+list_fd], edi
510
           test edi, edi
516
           test edi, edi
511
           jz @f
517
           jz @f
512
           mov [edi+list_bk], esi
518
           mov [edi+list_bk], esi
513
@@:
519
@@:
514
           bts [mem_block_mask], eax
520
           bts [mem_block_mask], eax
515
           mov [esi+block_flags],FREE_BLOCK
521
           mov [esi+block_flags],FREE_BLOCK
-
 
522
           mov ecx, heap_mutex
-
 
523
           call mutex_unlock
516
           xor eax, eax
524
           xor eax, eax
517
           mov [heap_mutex], eax
-
 
518
           dec eax
525
           not eax
519
           pop edi
526
           pop edi
520
           pop esi
527
           pop esi
521
           pop ebx
528
           pop ebx
522
           ret
529
           ret
523
.fail:
530
.fail:
-
 
531
           mov ecx, heap_mutex
-
 
532
           call mutex_unlock
524
           xor eax, eax
533
           xor eax, eax
525
           mov [heap_mutex], eax
-
 
526
           pop edi
534
           pop edi
527
           pop esi
535
           pop esi
528
           pop ebx
536
           pop ebx
529
           ret
537
           ret
530
endp
538
endp
531
 
539
 
532
align 4
540
align 4
533
proc kernel_alloc stdcall, size:dword
541
proc kernel_alloc stdcall, size:dword
534
           locals
542
           locals
535
             lin_addr    dd ?
543
             lin_addr    dd ?
536
             pages_count dd ?
544
             pages_count dd ?
537
           endl
545
           endl
538
 
546
 
539
           push ebx
547
           push ebx
540
           push edi
548
           push edi
541
 
549
 
542
           mov eax, [size]
550
           mov eax, [size]
543
           add eax, 4095
551
           add eax, 4095
544
           and eax, not 4095;
552
           and eax, not 4095;
545
           mov [size], eax
553
           mov [size], eax
546
           and eax, eax
554
           and eax, eax
547
           jz .err
555
           jz .err
548
           mov ebx, eax
556
           mov ebx, eax
549
           shr ebx, 12
557
           shr ebx, 12
550
           mov [pages_count], ebx
558
           mov [pages_count], ebx
551
 
559
 
552
           stdcall alloc_kernel_space, eax
560
           stdcall alloc_kernel_space, eax
553
           test eax, eax
561
           test eax, eax
554
           jz .err
562
           jz .err
555
           mov [lin_addr], eax
563
           mov [lin_addr], eax
556
 
564
 
557
           mov ecx, [pages_count]
565
           mov ecx, [pages_count]
558
           mov edx, eax
566
           mov edx, eax
559
           mov ebx, ecx
567
           mov ebx, ecx
560
 
568
 
561
           shr ecx, 3
569
           shr ecx, 3
562
           jz .next
570
           jz .next
563
 
571
 
564
           and ebx, not 7
572
           and ebx, not 7
565
           push ebx
573
           push ebx
566
           stdcall alloc_pages, ebx
574
           stdcall alloc_pages, ebx
567
           pop ecx                   ; yes ecx!!!
575
           pop ecx                   ; yes ecx!!!
568
           and eax, eax
576
           and eax, eax
569
           jz .err
577
           jz .err
570
 
578
 
571
           mov edi, eax
579
           mov edi, eax
572
           mov edx, [lin_addr]
580
           mov edx, [lin_addr]
573
@@:
581
@@:
574
           stdcall map_page,edx,edi,dword PG_SW
582
           stdcall map_page,edx,edi,dword PG_SW
575
           add edx, 0x1000
583
           add edx, 0x1000
576
           add edi, 0x1000
584
           add edi, 0x1000
577
           dec ecx
585
           dec ecx
578
           jnz @B
586
           jnz @B
579
.next:
587
.next:
580
           mov ecx, [pages_count]
588
           mov ecx, [pages_count]
581
           and ecx, 7
589
           and ecx, 7
582
           jz .end
590
           jz .end
583
@@:
591
@@:
584
           push ecx
592
           push ecx
585
           call alloc_page
593
           call alloc_page
586
           pop ecx
594
           pop ecx
587
           test eax, eax
595
           test eax, eax
588
           jz .err
596
           jz .err
589
 
597
 
590
           stdcall map_page,edx,eax,dword PG_SW
598
           stdcall map_page,edx,eax,dword PG_SW
591
           add edx, 0x1000
599
           add edx, 0x1000
592
           dec ecx
600
           dec ecx
593
           jnz @B
601
           jnz @B
594
.end:
602
.end:
595
           mov eax, [lin_addr]
603
           mov eax, [lin_addr]
596
           pop edi
604
           pop edi
597
           pop ebx
605
           pop ebx
598
           ret
606
           ret
599
.err:
607
.err:
600
           xor eax, eax
608
           xor eax, eax
601
           pop edi
609
           pop edi
602
           pop ebx
610
           pop ebx
603
           ret
611
           ret
604
endp
612
endp
605
 
613
 
606
align 4
614
align 4
607
proc kernel_free stdcall, base:dword
615
proc kernel_free stdcall, base:dword
608
           push ebx esi
616
           push ebx esi
609
 
617
 
610
           mov ebx, heap_mutex
618
           mov ecx, heap_mutex
611
           call wait_mutex    ;ebx
619
           call mutex_lock
612
 
620
 
613
           mov eax, [base]
621
           mov eax, [base]
614
           mov esi, [mem_used.fd]
622
           mov esi, [mem_used.fd]
615
@@:
623
@@:
616
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
624
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
617
           je .fail
625
           je .fail
618
 
626
 
619
           cmp [esi+block_base], eax
627
           cmp [esi+block_base], eax
620
           je .found
628
           je .found
621
           mov esi, [esi+list_fd]
629
           mov esi, [esi+list_fd]
622
           jmp @b
630
           jmp @b
623
.found:
631
.found:
624
           cmp [esi+block_flags], USED_BLOCK
632
           cmp [esi+block_flags], USED_BLOCK
625
           jne .fail
633
           jne .fail
626
 
634
 
627
           and [heap_mutex], 0
-
 
628
 
635
           call mutex_unlock
629
           push ecx
636
 
630
           mov ecx, [esi+block_size];
637
           mov ecx, [esi+block_size];
631
           shr ecx, 12
638
           shr ecx, 12
632
           call release_pages   ;eax, ecx
639
           call release_pages   ;eax, ecx
633
           pop ecx
-
 
634
           stdcall free_kernel_space, [base]
640
           stdcall free_kernel_space, [base]
635
           pop esi ebx
641
           pop esi ebx
636
           ret
642
           ret
637
.fail:
643
.fail:
-
 
644
           call mutex_unlock
638
           xor eax, eax
645
           xor eax, eax
639
           mov [heap_mutex], eax
-
 
640
           pop esi ebx
646
           pop esi ebx
641
           ret
647
           ret
642
endp
648
endp
643
 
649
 
644
restore block_next
650
restore block_next
645
restore block_prev
651
restore block_prev
646
restore block_list
652
restore block_list
647
restore block_base
653
restore block_base
648
restore block_size
654
restore block_size
649
restore block_flags
655
restore block_flags
650
 
656
 
651
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
657
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
652
 
658
 
653
HEAP_TOP  equ 0x5FC00000
659
HEAP_TOP  equ 0x5FC00000
654
 
660
 
655
align 4
661
align 4
656
proc init_heap
662
proc init_heap
657
 
663
 
658
           mov ebx,[current_slot]
664
           mov ebx,[current_slot]
659
           mov eax, [ebx+APPDATA.heap_top]
665
           mov eax, [ebx+APPDATA.heap_top]
660
           test eax, eax
666
           test eax, eax
661
           jz @F
667
           jz @F
662
           sub eax,[ebx+APPDATA.heap_base]
668
           sub eax,[ebx+APPDATA.heap_base]
663
           sub eax, 4096
669
           sub eax, 4096
664
           ret
670
           ret
665
@@:
671
@@:
666
           mov esi, [ebx+APPDATA.mem_size]
672
           mov esi, [ebx+APPDATA.mem_size]
667
           add esi, 4095
673
           add esi, 4095
668
           and esi, not 4095
674
           and esi, not 4095
669
           mov [ebx+APPDATA.mem_size], esi
675
           mov [ebx+APPDATA.mem_size], esi
670
           mov eax, HEAP_TOP
676
           mov eax, HEAP_TOP
671
           mov [ebx+APPDATA.heap_base], esi
677
           mov [ebx+APPDATA.heap_base], esi
672
           mov [ebx+APPDATA.heap_top], eax
678
           mov [ebx+APPDATA.heap_top], eax
673
 
679
 
674
           sub eax, esi
680
           sub eax, esi
675
           shr esi, 10
681
           shr esi, 10
676
           mov ecx, eax
682
           mov ecx, eax
677
           sub eax, 4096
683
           sub eax, 4096
678
           or ecx, FREE_BLOCK
684
           or ecx, FREE_BLOCK
679
           mov [page_tabs+esi], ecx
685
           mov [page_tabs+esi], ecx
680
           ret
686
           ret
681
endp
687
endp
682
 
688
 
683
align 4
689
align 4
684
proc user_alloc stdcall, alloc_size:dword
690
proc user_alloc stdcall, alloc_size:dword
685
 
691
 
686
           push ebx
692
           push ebx
687
           push esi
693
           push esi
688
           push edi
694
           push edi
689
 
695
 
690
           mov ecx, [alloc_size]
696
           mov ecx, [alloc_size]
691
           add ecx, (4095+4096)
697
           add ecx, (4095+4096)
692
           and ecx, not 4095
698
           and ecx, not 4095
693
 
699
 
694
           mov ebx, [current_slot]
700
           mov ebx, [current_slot]
695
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
701
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
696
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
702
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
697
l_0:
703
l_0:
698
           cmp esi, edi
704
           cmp esi, edi
699
           jae m_exit
705
           jae m_exit
700
 
706
 
701
           mov ebx, esi
707
           mov ebx, esi
702
           shr ebx, 12
708
           shr ebx, 12
703
           mov eax, [page_tabs+ebx*4]
709
           mov eax, [page_tabs+ebx*4]
704
           test al, FREE_BLOCK
710
           test al, FREE_BLOCK
705
           jz test_used
711
           jz test_used
706
           and eax, 0xFFFFF000
712
           and eax, 0xFFFFF000
707
           cmp eax, ecx    ;alloc_size
713
           cmp eax, ecx    ;alloc_size
708
           jb  m_next
714
           jb  m_next
709
           jz  @f
715
           jz  @f
710
 
716
 
711
           lea edx, [esi+ecx]
717
           lea edx, [esi+ecx]
712
           sub eax, ecx
718
           sub eax, ecx
713
           or al, FREE_BLOCK
719
           or al, FREE_BLOCK
714
           shr edx, 12
720
           shr edx, 12
715
           mov [page_tabs+edx*4], eax
721
           mov [page_tabs+edx*4], eax
716
@@:
722
@@:
717
           or ecx, USED_BLOCK
723
           or ecx, USED_BLOCK
718
           mov [page_tabs+ebx*4], ecx
724
           mov [page_tabs+ebx*4], ecx
719
           shr ecx, 12
725
           shr ecx, 12
720
           inc ebx
726
           inc ebx
721
           dec ecx
727
           dec ecx
722
           jz  .no
728
           jz  .no
723
@@:
729
@@:
724
           mov dword [page_tabs+ebx*4], 2
730
           mov dword [page_tabs+ebx*4], 2
725
           inc ebx
731
           inc ebx
726
           dec ecx
732
           dec ecx
727
           jnz @B
733
           jnz @B
728
.no:
734
.no:
729
 
735
 
730
           mov     edx, [current_slot]
736
           mov     edx, [current_slot]
731
           mov     ebx, [alloc_size]
737
           mov     ebx, [alloc_size]
732
           add     ebx, 0xFFF
738
           add     ebx, 0xFFF
733
           and     ebx, not 0xFFF
739
           and     ebx, not 0xFFF
734
           add     ebx, [edx+APPDATA.mem_size]
740
           add     ebx, [edx+APPDATA.mem_size]
735
           call    update_mem_size
741
           call    update_mem_size
736
 
742
 
737
           lea eax, [esi+4096]
743
           lea eax, [esi+4096]
738
 
744
 
739
           pop edi
745
           pop edi
740
           pop esi
746
           pop esi
741
           pop ebx
747
           pop ebx
742
           ret
748
           ret
743
test_used:
749
test_used:
744
           test al, USED_BLOCK
750
           test al, USED_BLOCK
745
           jz m_exit
751
           jz m_exit
746
 
752
 
747
           and eax, 0xFFFFF000
753
           and eax, 0xFFFFF000
748
m_next:
754
m_next:
749
           add esi, eax
755
           add esi, eax
750
           jmp l_0
756
           jmp l_0
751
m_exit:
757
m_exit:
752
           xor eax, eax
758
           xor eax, eax
753
           pop edi
759
           pop edi
754
           pop esi
760
           pop esi
755
           pop ebx
761
           pop ebx
756
           ret
762
           ret
757
endp
763
endp
758
 
764
 
759
align 4
765
align 4
760
proc user_alloc_at stdcall, address:dword, alloc_size:dword
766
proc user_alloc_at stdcall, address:dword, alloc_size:dword
761
 
767
 
762
           push ebx
768
           push ebx
763
           push esi
769
           push esi
764
           push edi
770
           push edi
765
 
771
 
766
           mov ebx, [current_slot]
772
           mov ebx, [current_slot]
767
           mov edx, [address]
773
           mov edx, [address]
768
           and edx, not 0xFFF
774
           and edx, not 0xFFF
769
           mov [address], edx
775
           mov [address], edx
770
           sub edx, 0x1000
776
           sub edx, 0x1000
771
           jb  .error
777
           jb  .error
772
           mov esi, [ebx+APPDATA.heap_base]
778
           mov esi, [ebx+APPDATA.heap_base]
773
           mov edi, [ebx+APPDATA.heap_top]
779
           mov edi, [ebx+APPDATA.heap_top]
774
           cmp edx, esi
780
           cmp edx, esi
775
           jb  .error
781
           jb  .error
776
.scan:
782
.scan:
777
           cmp esi, edi
783
           cmp esi, edi
778
           jae .error
784
           jae .error
779
           mov ebx, esi
785
           mov ebx, esi
780
           shr ebx, 12
786
           shr ebx, 12
781
           mov eax, [page_tabs+ebx*4]
787
           mov eax, [page_tabs+ebx*4]
782
           mov ecx, eax
788
           mov ecx, eax
783
           and ecx, 0xFFFFF000
789
           and ecx, 0xFFFFF000
784
           add ecx, esi
790
           add ecx, esi
785
           cmp edx, ecx
791
           cmp edx, ecx
786
           jb  .found
792
           jb  .found
787
           mov esi, ecx
793
           mov esi, ecx
788
           jmp .scan
794
           jmp .scan
789
.error:
795
.error:
790
           xor eax, eax
796
           xor eax, eax
791
           pop edi
797
           pop edi
792
           pop esi
798
           pop esi
793
           pop ebx
799
           pop ebx
794
           ret
800
           ret
795
.found:
801
.found:
796
           test al, FREE_BLOCK
802
           test al, FREE_BLOCK
797
           jz  .error
803
           jz  .error
798
           mov eax, ecx
804
           mov eax, ecx
799
           sub eax, edx
805
           sub eax, edx
800
           sub eax, 0x1000
806
           sub eax, 0x1000
801
           cmp eax, [alloc_size]
807
           cmp eax, [alloc_size]
802
           jb  .error
808
           jb  .error
803
 
809
 
804
; Here we have 1 big free block which includes requested area.
810
; Here we have 1 big free block which includes requested area.
805
; In general, 3 other blocks must be created instead:
811
; In general, 3 other blocks must be created instead:
806
; free at [esi, edx);
812
; free at [esi, edx);
807
; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000));
813
; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000));
808
; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx)
814
; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx)
809
; First or third block (or both) may be absent.
815
; First or third block (or both) may be absent.
810
           mov eax, edx
816
           mov eax, edx
811
           sub eax, esi
817
           sub eax, esi
812
           jz  .nofirst
818
           jz  .nofirst
813
           or  al, FREE_BLOCK
819
           or  al, FREE_BLOCK
814
           mov [page_tabs+ebx*4], eax
820
           mov [page_tabs+ebx*4], eax
815
.nofirst:
821
.nofirst:
816
           mov eax, [alloc_size]
822
           mov eax, [alloc_size]
817
           add eax, 0x1FFF
823
           add eax, 0x1FFF
818
           and eax, not 0xFFF
824
           and eax, not 0xFFF
819
           mov ebx, edx
825
           mov ebx, edx
820
           add edx, eax
826
           add edx, eax
821
           shr ebx, 12
827
           shr ebx, 12
822
           or  al, USED_BLOCK
828
           or  al, USED_BLOCK
823
           mov [page_tabs+ebx*4], eax
829
           mov [page_tabs+ebx*4], eax
824
           shr eax, 12
830
           shr eax, 12
825
           dec eax
831
           dec eax
826
           jz  .second_nofill
832
           jz  .second_nofill
827
           inc ebx
833
           inc ebx
828
.fill:
834
.fill:
829
           mov dword [page_tabs+ebx*4], 2
835
           mov dword [page_tabs+ebx*4], 2
830
           inc ebx
836
           inc ebx
831
           dec eax
837
           dec eax
832
           jnz .fill
838
           jnz .fill
833
.second_nofill:
839
.second_nofill:
834
           sub ecx, edx
840
           sub ecx, edx
835
           jz  .nothird
841
           jz  .nothird
836
           or  cl, FREE_BLOCK
842
           or  cl, FREE_BLOCK
837
           mov [page_tabs+ebx*4], ecx
843
           mov [page_tabs+ebx*4], ecx
838
.nothird:
844
.nothird:
839
 
845
 
840
           mov     edx, [current_slot]
846
           mov     edx, [current_slot]
841
           mov     ebx, [alloc_size]
847
           mov     ebx, [alloc_size]
842
           add     ebx, 0xFFF
848
           add     ebx, 0xFFF
843
           and     ebx, not 0xFFF
849
           and     ebx, not 0xFFF
844
           add     ebx, [edx+APPDATA.mem_size]
850
           add     ebx, [edx+APPDATA.mem_size]
845
           call    update_mem_size
851
           call    update_mem_size
846
 
852
 
847
           mov eax, [address]
853
           mov eax, [address]
848
 
854
 
849
           pop edi
855
           pop edi
850
           pop esi
856
           pop esi
851
           pop ebx
857
           pop ebx
852
           ret
858
           ret
853
endp
859
endp
854
 
860
 
855
align 4
861
align 4
856
proc user_free stdcall, base:dword
862
proc user_free stdcall, base:dword
857
 
863
 
858
           push esi
864
           push esi
859
 
865
 
860
           mov esi, [base]
866
           mov esi, [base]
861
           test esi, esi
867
           test esi, esi
862
           jz .exit
868
           jz .exit
863
 
869
 
864
           push ebx
870
           push ebx
865
 
871
 
866
           xor ebx, ebx
872
           xor ebx, ebx
867
           shr esi, 12
873
           shr esi, 12
868
           mov eax, [page_tabs+(esi-1)*4]
874
           mov eax, [page_tabs+(esi-1)*4]
869
           test al, USED_BLOCK
875
           test al, USED_BLOCK
870
           jz .cantfree
876
           jz .cantfree
871
           test al, DONT_FREE_BLOCK
877
           test al, DONT_FREE_BLOCK
872
           jnz .cantfree
878
           jnz .cantfree
873
 
879
 
874
           and eax, not 4095
880
           and eax, not 4095
875
           mov ecx, eax
881
           mov ecx, eax
876
           or al, FREE_BLOCK
882
           or al, FREE_BLOCK
877
           mov [page_tabs+(esi-1)*4], eax
883
           mov [page_tabs+(esi-1)*4], eax
878
           sub ecx, 4096
884
           sub ecx, 4096
879
           mov ebx, ecx
885
           mov ebx, ecx
880
           shr ecx, 12
886
           shr ecx, 12
881
           jz .released
887
           jz .released
882
.release:
888
.release:
883
           xor eax, eax
889
           xor eax, eax
884
           xchg eax, [page_tabs+esi*4]
890
           xchg eax, [page_tabs+esi*4]
885
           test al, 1
891
           test al, 1
886
           jz @F
892
           jz @F
887
           test eax, PG_SHARED
893
           test eax, PG_SHARED
888
           jnz @F
894
           jnz @F
889
           call free_page
895
           call free_page
890
           mov eax, esi
896
           mov eax, esi
891
           shl eax, 12
897
           shl eax, 12
892
           invlpg [eax]
898
           invlpg [eax]
893
@@:
899
@@:
894
           inc esi
900
           inc esi
895
           dec ecx
901
           dec ecx
896
           jnz .release
902
           jnz .release
897
.released:
903
.released:
898
           push edi
904
           push edi
899
 
905
 
900
           mov edx, [current_slot]
906
           mov edx, [current_slot]
901
           mov esi, dword [edx+APPDATA.heap_base]
907
           mov esi, dword [edx+APPDATA.heap_base]
902
           mov edi, dword [edx+APPDATA.heap_top]
908
           mov edi, dword [edx+APPDATA.heap_top]
903
           sub ebx, [edx+APPDATA.mem_size]
909
           sub ebx, [edx+APPDATA.mem_size]
904
           neg ebx
910
           neg ebx
905
           call update_mem_size
911
           call update_mem_size
906
           call user_normalize
912
           call user_normalize
907
           pop edi
913
           pop edi
908
           pop ebx
914
           pop ebx
909
           pop esi
915
           pop esi
910
           ret
916
           ret
911
.exit:
917
.exit:
912
           xor eax, eax
918
           xor eax, eax
913
           inc eax
919
           inc eax
914
           pop esi
920
           pop esi
915
           ret
921
           ret
916
.cantfree:
922
.cantfree:
917
           xor eax, eax
923
           xor eax, eax
918
           pop ebx
924
           pop ebx
919
           pop esi
925
           pop esi
920
           ret
926
           ret
921
endp
927
endp
922
 
928
 
923
user_normalize:
929
user_normalize:
924
; in: esi=heap_base, edi=heap_top
930
; in: esi=heap_base, edi=heap_top
925
; out: eax=0 <=> OK
931
; out: eax=0 <=> OK
926
; destroys: ebx,edx,esi,edi
932
; destroys: ebx,edx,esi,edi
927
           shr esi, 12
933
           shr esi, 12
928
           shr edi, 12
934
           shr edi, 12
929
@@:
935
@@:
930
           mov eax, [page_tabs+esi*4]
936
           mov eax, [page_tabs+esi*4]
931
           test al, USED_BLOCK
937
           test al, USED_BLOCK
932
           jz .test_free
938
           jz .test_free
933
           shr eax, 12
939
           shr eax, 12
934
           add esi, eax
940
           add esi, eax
935
           jmp @B
941
           jmp @B
936
.test_free:
942
.test_free:
937
           test al, FREE_BLOCK
943
           test al, FREE_BLOCK
938
           jz .err
944
           jz .err
939
           mov edx, eax
945
           mov edx, eax
940
           shr edx, 12
946
           shr edx, 12
941
           add edx, esi
947
           add edx, esi
942
           cmp edx, edi
948
           cmp edx, edi
943
           jae .exit
949
           jae .exit
944
 
950
 
945
           mov ebx, [page_tabs+edx*4]
951
           mov ebx, [page_tabs+edx*4]
946
           test bl, USED_BLOCK
952
           test bl, USED_BLOCK
947
           jz .next_free
953
           jz .next_free
948
 
954
 
949
           shr ebx, 12
955
           shr ebx, 12
950
           add edx, ebx
956
           add edx, ebx
951
           mov esi, edx
957
           mov esi, edx
952
           jmp @B
958
           jmp @B
953
.next_free:
959
.next_free:
954
           test bl, FREE_BLOCK
960
           test bl, FREE_BLOCK
955
           jz .err
961
           jz .err
956
           and dword [page_tabs+edx*4], 0
962
           and dword [page_tabs+edx*4], 0
957
           add eax, ebx
963
           add eax, ebx
958
           and eax, not 4095
964
           and eax, not 4095
959
           or eax, FREE_BLOCK
965
           or eax, FREE_BLOCK
960
           mov [page_tabs+esi*4], eax
966
           mov [page_tabs+esi*4], eax
961
           jmp @B
967
           jmp @B
962
.exit:
968
.exit:
963
           xor eax, eax
969
           xor eax, eax
964
           inc eax
970
           inc eax
965
           ret
971
           ret
966
.err:
972
.err:
967
           xor eax, eax
973
           xor eax, eax
968
           ret
974
           ret
969
 
975
 
970
user_realloc:
976
user_realloc:
971
; in: eax = pointer, ebx = new size
977
; in: eax = pointer, ebx = new size
972
; out: eax = new pointer or NULL
978
; out: eax = new pointer or NULL
973
        test    eax, eax
979
        test    eax, eax
974
        jnz     @f
980
        jnz     @f
975
; realloc(NULL,sz) - same as malloc(sz)
981
; realloc(NULL,sz) - same as malloc(sz)
976
        push    ebx
982
        push    ebx
977
        call    user_alloc
983
        call    user_alloc
978
        ret
984
        ret
979
@@:
985
@@:
980
        push    ecx edx
986
        push    ecx edx
981
        lea     ecx, [eax - 0x1000]
987
        lea     ecx, [eax - 0x1000]
982
        shr     ecx, 12
988
        shr     ecx, 12
983
        mov     edx, [page_tabs+ecx*4]
989
        mov     edx, [page_tabs+ecx*4]
984
        test    dl, USED_BLOCK
990
        test    dl, USED_BLOCK
985
        jnz     @f
991
        jnz     @f
986
; attempt to realloc invalid pointer
992
; attempt to realloc invalid pointer
987
.ret0:
993
.ret0:
988
        pop     edx ecx
994
        pop     edx ecx
989
        xor     eax, eax
995
        xor     eax, eax
990
        ret
996
        ret
991
@@:
997
@@:
992
        test    dl, DONT_FREE_BLOCK
998
        test    dl, DONT_FREE_BLOCK
993
        jnz     .ret0
999
        jnz     .ret0
994
        add     ebx, 0x1FFF
1000
        add     ebx, 0x1FFF
995
        shr     edx, 12
1001
        shr     edx, 12
996
        shr     ebx, 12
1002
        shr     ebx, 12
997
; edx = allocated size, ebx = new size
1003
; edx = allocated size, ebx = new size
998
        add     edx, ecx
1004
        add     edx, ecx
999
        add     ebx, ecx
1005
        add     ebx, ecx
1000
        cmp     edx, ebx
1006
        cmp     edx, ebx
1001
        jb      .realloc_add
1007
        jb      .realloc_add
1002
; release part of allocated memory
1008
; release part of allocated memory
1003
.loop:
1009
.loop:
1004
        cmp     edx, ebx
1010
        cmp     edx, ebx
1005
        jz      .release_done
1011
        jz      .release_done
1006
        dec     edx
1012
        dec     edx
1007
        xor     eax, eax
1013
        xor     eax, eax
1008
        xchg    eax, [page_tabs+edx*4]
1014
        xchg    eax, [page_tabs+edx*4]
1009
        test    al, 1
1015
        test    al, 1
1010
        jz      .loop
1016
        jz      .loop
1011
        call    free_page
1017
        call    free_page
1012
        mov     eax, edx
1018
        mov     eax, edx
1013
        shl     eax, 12
1019
        shl     eax, 12
1014
        invlpg  [eax]
1020
        invlpg  [eax]
1015
        jmp     .loop
1021
        jmp     .loop
1016
.release_done:
1022
.release_done:
1017
        sub     ebx, ecx
1023
        sub     ebx, ecx
1018
        cmp     ebx, 1
1024
        cmp     ebx, 1
1019
        jnz     .nofreeall
1025
        jnz     .nofreeall
1020
        mov     eax, [page_tabs+ecx*4]
1026
        mov     eax, [page_tabs+ecx*4]
1021
        and     eax, not 0xFFF
1027
        and     eax, not 0xFFF
1022
        mov     edx, [current_slot]
1028
        mov     edx, [current_slot]
1023
        mov     ebx, [APPDATA.mem_size+edx]
1029
        mov     ebx, [APPDATA.mem_size+edx]
1024
        sub     ebx, eax
1030
        sub     ebx, eax
1025
        add     ebx, 0x1000
1031
        add     ebx, 0x1000
1026
        or      al, FREE_BLOCK
1032
        or      al, FREE_BLOCK
1027
        mov     [page_tabs+ecx*4], eax
1033
        mov     [page_tabs+ecx*4], eax
1028
        push    esi edi
1034
        push    esi edi
1029
        mov     esi, [APPDATA.heap_base+edx]
1035
        mov     esi, [APPDATA.heap_base+edx]
1030
        mov     edi, [APPDATA.heap_top+edx]
1036
        mov     edi, [APPDATA.heap_top+edx]
1031
        call    update_mem_size
1037
        call    update_mem_size
1032
        call    user_normalize
1038
        call    user_normalize
1033
        pop     edi esi
1039
        pop     edi esi
1034
        jmp     .ret0   ; all freed
1040
        jmp     .ret0   ; all freed
1035
.nofreeall:
1041
.nofreeall:
1036
        sub     edx, ecx
1042
        sub     edx, ecx
1037
        shl     ebx, 12
1043
        shl     ebx, 12
1038
        or      ebx, USED_BLOCK
1044
        or      ebx, USED_BLOCK
1039
        xchg    [page_tabs+ecx*4], ebx
1045
        xchg    [page_tabs+ecx*4], ebx
1040
        shr     ebx, 12
1046
        shr     ebx, 12
1041
        sub     ebx, edx
1047
        sub     ebx, edx
1042
        push    ebx ecx edx
1048
        push    ebx ecx edx
1043
        mov     edx, [current_slot]
1049
        mov     edx, [current_slot]
1044
        shl     ebx, 12
1050
        shl     ebx, 12
1045
        sub     ebx, [APPDATA.mem_size+edx]
1051
        sub     ebx, [APPDATA.mem_size+edx]
1046
        neg     ebx
1052
        neg     ebx
1047
        call    update_mem_size
1053
        call    update_mem_size
1048
        pop     edx ecx ebx
1054
        pop     edx ecx ebx
1049
        lea     eax, [ecx+1]
1055
        lea     eax, [ecx+1]
1050
        shl     eax, 12
1056
        shl     eax, 12
1051
        push    eax
1057
        push    eax
1052
        add     ecx, edx
1058
        add     ecx, edx
1053
        lea     edx, [ecx+ebx]
1059
        lea     edx, [ecx+ebx]
1054
        shl     ebx, 12
1060
        shl     ebx, 12
1055
        jz      .ret
1061
        jz      .ret
1056
        push    esi
1062
        push    esi
1057
        mov     esi, [current_slot]
1063
        mov     esi, [current_slot]
1058
        mov     esi, [APPDATA.heap_top+esi]
1064
        mov     esi, [APPDATA.heap_top+esi]
1059
        shr     esi, 12
1065
        shr     esi, 12
1060
@@:
1066
@@:
1061
        cmp     edx, esi
1067
        cmp     edx, esi
1062
        jae     .merge_done
1068
        jae     .merge_done
1063
        mov     eax, [page_tabs+edx*4]
1069
        mov     eax, [page_tabs+edx*4]
1064
        test    al, USED_BLOCK
1070
        test    al, USED_BLOCK
1065
        jnz     .merge_done
1071
        jnz     .merge_done
1066
        and     dword [page_tabs+edx*4], 0
1072
        and     dword [page_tabs+edx*4], 0
1067
        shr     eax, 12
1073
        shr     eax, 12
1068
        add     edx, eax
1074
        add     edx, eax
1069
        shl     eax, 12
1075
        shl     eax, 12
1070
        add     ebx, eax
1076
        add     ebx, eax
1071
        jmp     @b
1077
        jmp     @b
1072
.merge_done:
1078
.merge_done:
1073
        pop     esi
1079
        pop     esi
1074
        or      ebx, FREE_BLOCK
1080
        or      ebx, FREE_BLOCK
1075
        mov     [page_tabs+ecx*4], ebx
1081
        mov     [page_tabs+ecx*4], ebx
1076
.ret:
1082
.ret:
1077
        pop     eax edx ecx
1083
        pop     eax edx ecx
1078
        ret
1084
        ret
1079
.realloc_add:
1085
.realloc_add:
1080
; get some additional memory
1086
; get some additional memory
1081
        mov     eax, [current_slot]
1087
        mov     eax, [current_slot]
1082
        mov     eax, [APPDATA.heap_top+eax]
1088
        mov     eax, [APPDATA.heap_top+eax]
1083
        shr     eax, 12
1089
        shr     eax, 12
1084
        cmp     edx, eax
1090
        cmp     edx, eax
1085
        jae     .cant_inplace
1091
        jae     .cant_inplace
1086
        mov     eax, [page_tabs+edx*4]
1092
        mov     eax, [page_tabs+edx*4]
1087
        test    al, FREE_BLOCK
1093
        test    al, FREE_BLOCK
1088
        jz      .cant_inplace
1094
        jz      .cant_inplace
1089
        shr     eax, 12
1095
        shr     eax, 12
1090
        add     eax, edx
1096
        add     eax, edx
1091
        sub     eax, ebx
1097
        sub     eax, ebx
1092
        jb      .cant_inplace
1098
        jb      .cant_inplace
1093
        jz      @f
1099
        jz      @f
1094
        shl     eax, 12
1100
        shl     eax, 12
1095
        or      al, FREE_BLOCK
1101
        or      al, FREE_BLOCK
1096
        mov     [page_tabs+ebx*4], eax
1102
        mov     [page_tabs+ebx*4], eax
1097
@@:
1103
@@:
1098
        mov     eax, ebx
1104
        mov     eax, ebx
1099
        sub     eax, ecx
1105
        sub     eax, ecx
1100
        shl     eax, 12
1106
        shl     eax, 12
1101
        or      al, USED_BLOCK
1107
        or      al, USED_BLOCK
1102
        mov     [page_tabs+ecx*4], eax
1108
        mov     [page_tabs+ecx*4], eax
1103
        lea     eax, [ecx+1]
1109
        lea     eax, [ecx+1]
1104
        shl     eax, 12
1110
        shl     eax, 12
1105
        push    eax
1111
        push    eax
1106
        push    edi
1112
        push    edi
1107
        lea     edi, [page_tabs+edx*4]
1113
        lea     edi, [page_tabs+edx*4]
1108
        mov     eax, 2
1114
        mov     eax, 2
1109
        sub     ebx, edx
1115
        sub     ebx, edx
1110
        mov     ecx, ebx
1116
        mov     ecx, ebx
1111
        cld
1117
        cld
1112
        rep     stosd
1118
        rep     stosd
1113
        pop     edi
1119
        pop     edi
1114
        mov     edx, [current_slot]
1120
        mov     edx, [current_slot]
1115
        shl     ebx, 12
1121
        shl     ebx, 12
1116
        add     ebx, [APPDATA.mem_size+edx]
1122
        add     ebx, [APPDATA.mem_size+edx]
1117
        call    update_mem_size
1123
        call    update_mem_size
1118
        pop     eax edx ecx
1124
        pop     eax edx ecx
1119
        ret
1125
        ret
1120
.cant_inplace:
1126
.cant_inplace:
1121
        push    esi edi
1127
        push    esi edi
1122
        mov     eax, [current_slot]
1128
        mov     eax, [current_slot]
1123
        mov     esi, [APPDATA.heap_base+eax]
1129
        mov     esi, [APPDATA.heap_base+eax]
1124
        mov     edi, [APPDATA.heap_top+eax]
1130
        mov     edi, [APPDATA.heap_top+eax]
1125
        shr     esi, 12
1131
        shr     esi, 12
1126
        shr     edi, 12
1132
        shr     edi, 12
1127
        sub     ebx, ecx
1133
        sub     ebx, ecx
1128
.find_place:
1134
.find_place:
1129
        cmp     esi, edi
1135
        cmp     esi, edi
1130
        jae     .place_not_found
1136
        jae     .place_not_found
1131
        mov     eax, [page_tabs+esi*4]
1137
        mov     eax, [page_tabs+esi*4]
1132
        test    al, FREE_BLOCK
1138
        test    al, FREE_BLOCK
1133
        jz      .next_place
1139
        jz      .next_place
1134
        shr     eax, 12
1140
        shr     eax, 12
1135
        cmp     eax, ebx
1141
        cmp     eax, ebx
1136
        jae     .place_found
1142
        jae     .place_found
1137
        add     esi, eax
1143
        add     esi, eax
1138
        jmp     .find_place
1144
        jmp     .find_place
1139
.next_place:
1145
.next_place:
1140
        shr     eax, 12
1146
        shr     eax, 12
1141
        add     esi, eax
1147
        add     esi, eax
1142
        jmp     .find_place
1148
        jmp     .find_place
1143
.place_not_found:
1149
.place_not_found:
1144
        pop     edi esi
1150
        pop     edi esi
1145
        jmp     .ret0
1151
        jmp     .ret0
1146
.place_found:
1152
.place_found:
1147
        sub     eax, ebx
1153
        sub     eax, ebx
1148
        jz      @f
1154
        jz      @f
1149
        push    esi
1155
        push    esi
1150
        add     esi, ebx
1156
        add     esi, ebx
1151
        shl     eax, 12
1157
        shl     eax, 12
1152
        or      al, FREE_BLOCK
1158
        or      al, FREE_BLOCK
1153
        mov     [page_tabs+esi*4], eax
1159
        mov     [page_tabs+esi*4], eax
1154
        pop     esi
1160
        pop     esi
1155
@@:
1161
@@:
1156
        mov     eax, ebx
1162
        mov     eax, ebx
1157
        shl     eax, 12
1163
        shl     eax, 12
1158
        or      al, USED_BLOCK
1164
        or      al, USED_BLOCK
1159
        mov     [page_tabs+esi*4], eax
1165
        mov     [page_tabs+esi*4], eax
1160
        inc     esi
1166
        inc     esi
1161
        mov     eax, esi
1167
        mov     eax, esi
1162
        shl     eax, 12
1168
        shl     eax, 12
1163
        push    eax
1169
        push    eax
1164
        mov     eax, [page_tabs+ecx*4]
1170
        mov     eax, [page_tabs+ecx*4]
1165
        and     eax, not 0xFFF
1171
        and     eax, not 0xFFF
1166
        or      al, FREE_BLOCK
1172
        or      al, FREE_BLOCK
1167
        sub     edx, ecx
1173
        sub     edx, ecx
1168
        mov     [page_tabs+ecx*4], eax
1174
        mov     [page_tabs+ecx*4], eax
1169
        inc     ecx
1175
        inc     ecx
1170
        dec     ebx
1176
        dec     ebx
1171
        dec     edx
1177
        dec     edx
1172
        jz      .no
1178
        jz      .no
1173
@@:
1179
@@:
1174
        xor     eax, eax
1180
        xor     eax, eax
1175
        xchg    eax, [page_tabs+ecx*4]
1181
        xchg    eax, [page_tabs+ecx*4]
1176
        mov     [page_tabs+esi*4], eax
1182
        mov     [page_tabs+esi*4], eax
1177
        mov     eax, ecx
1183
        mov     eax, ecx
1178
        shl     eax, 12
1184
        shl     eax, 12
1179
        invlpg  [eax]
1185
        invlpg  [eax]
1180
        inc     esi
1186
        inc     esi
1181
        inc     ecx
1187
        inc     ecx
1182
        dec     ebx
1188
        dec     ebx
1183
        dec     edx
1189
        dec     edx
1184
        jnz     @b
1190
        jnz     @b
1185
.no:
1191
.no:
1186
        push    ebx
1192
        push    ebx
1187
        mov     edx, [current_slot]
1193
        mov     edx, [current_slot]
1188
        shl     ebx, 12
1194
        shl     ebx, 12
1189
        add     ebx, [APPDATA.mem_size+edx]
1195
        add     ebx, [APPDATA.mem_size+edx]
1190
        call    update_mem_size
1196
        call    update_mem_size
1191
        pop     ebx
1197
        pop     ebx
1192
@@:
1198
@@:
1193
        mov     dword [page_tabs+esi*4], 2
1199
        mov     dword [page_tabs+esi*4], 2
1194
        inc     esi
1200
        inc     esi
1195
        dec     ebx
1201
        dec     ebx
1196
        jnz     @b
1202
        jnz     @b
1197
        pop     eax edi esi edx ecx
1203
        pop     eax edi esi edx ecx
1198
        ret
1204
        ret
1199
 
1205
 
1200
if 0
1206
if 0
1201
align 4
1207
align 4
1202
proc alloc_dll
1208
proc alloc_dll
1203
           pushf
1209
           pushf
1204
           cli
1210
           cli
1205
           bsf eax, [dll_map]
1211
           bsf eax, [dll_map]
1206
           jnz .find
1212
           jnz .find
1207
           popf
1213
           popf
1208
           xor eax, eax
1214
           xor eax, eax
1209
           ret
1215
           ret
1210
.find:
1216
.find:
1211
           btr [dll_map], eax
1217
           btr [dll_map], eax
1212
           popf
1218
           popf
1213
           shl eax, 5
1219
           shl eax, 5
1214
           add eax, dll_tab
1220
           add eax, dll_tab
1215
           ret
1221
           ret
1216
endp
1222
endp
1217
 
1223
 
1218
align 4
1224
align 4
1219
proc alloc_service
1225
proc alloc_service
1220
           pushf
1226
           pushf
1221
           cli
1227
           cli
1222
           bsf eax, [srv_map]
1228
           bsf eax, [srv_map]
1223
           jnz .find
1229
           jnz .find
1224
           popf
1230
           popf
1225
           xor eax, eax
1231
           xor eax, eax
1226
           ret
1232
           ret
1227
.find:
1233
.find:
1228
           btr [srv_map], eax
1234
           btr [srv_map], eax
1229
           popf
1235
           popf
1230
           shl eax,0x02
1236
           shl eax,0x02
1231
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
1237
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
1232
           ret
1238
           ret
1233
endp
1239
endp
1234
 
1240
 
1235
end if
1241
end if
1236
 
1242
 
1237
 
1243
 
1238
;;;;;;;;;;;;;;      SHARED      ;;;;;;;;;;;;;;;;;
1244
;;;;;;;;;;;;;;      SHARED      ;;;;;;;;;;;;;;;;;
1239
 
1245
 
1240
 
1246
 
1241
; param
1247
; param
1242
;  eax= shm_map object
1248
;  eax= shm_map object
1243
 
1249
 
1244
align 4
1250
align 4
1245
destroy_smap:
1251
destroy_smap:
1246
 
1252
 
1247
           pushfd
1253
           pushfd
1248
           cli
1254
           cli
1249
 
1255
 
1250
           push esi
1256
           push esi
1251
           push edi
1257
           push edi
1252
 
1258
 
1253
           mov edi, eax
1259
           mov edi, eax
1254
           mov esi, [eax+SMAP.parent]
1260
           mov esi, [eax+SMAP.parent]
1255
           test esi, esi
1261
           test esi, esi
1256
           jz .done
1262
           jz .done
1257
 
1263
 
1258
           lock dec [esi+SMEM.refcount]
1264
           lock dec [esi+SMEM.refcount]
1259
           jnz .done
1265
           jnz .done
1260
 
1266
 
1261
           mov ecx, [esi+SMEM.bk]
1267
           mov ecx, [esi+SMEM.bk]
1262
           mov edx, [esi+SMEM.fd]
1268
           mov edx, [esi+SMEM.fd]
1263
 
1269
 
1264
           mov [ecx+SMEM.fd], edx
1270
           mov [ecx+SMEM.fd], edx
1265
           mov [edx+SMEM.bk], ecx
1271
           mov [edx+SMEM.bk], ecx
1266
 
1272
 
1267
           stdcall kernel_free, [esi+SMEM.base]
1273
           stdcall kernel_free, [esi+SMEM.base]
1268
           mov eax, esi
1274
           mov eax, esi
1269
           call free
1275
           call free
1270
.done:
1276
.done:
1271
           mov eax, edi
1277
           mov eax, edi
1272
           call destroy_kernel_object
1278
           call destroy_kernel_object
1273
 
1279
 
1274
           pop edi
1280
           pop edi
1275
           pop esi
1281
           pop esi
1276
           popfd
1282
           popfd
1277
 
1283
 
1278
           ret
1284
           ret
1279
 
1285
 
1280
E_NOTFOUND      equ  5
1286
E_NOTFOUND      equ  5
1281
E_ACCESS        equ 10
1287
E_ACCESS        equ 10
1282
E_NOMEM         equ 30
1288
E_NOMEM         equ 30
1283
E_PARAM         equ 33
1289
E_PARAM         equ 33
1284
 
1290
 
1285
SHM_READ        equ 0
1291
SHM_READ        equ 0
1286
SHM_WRITE       equ 1
1292
SHM_WRITE       equ 1
1287
 
1293
 
1288
SHM_ACCESS_MASK equ 3
1294
SHM_ACCESS_MASK equ 3
1289
 
1295
 
1290
SHM_OPEN        equ (0 shl 2)
1296
SHM_OPEN        equ (0 shl 2)
1291
SHM_OPEN_ALWAYS equ (1 shl 2)
1297
SHM_OPEN_ALWAYS equ (1 shl 2)
1292
SHM_CREATE      equ (2 shl 2)
1298
SHM_CREATE      equ (2 shl 2)
1293
 
1299
 
1294
SHM_OPEN_MASK   equ (3 shl 2)
1300
SHM_OPEN_MASK   equ (3 shl 2)
1295
 
1301
 
1296
align 4
1302
align 4
1297
proc shmem_open stdcall name:dword, size:dword, access:dword
1303
proc shmem_open stdcall name:dword, size:dword, access:dword
1298
           locals
1304
           locals
1299
              action         dd ?
1305
              action         dd ?
1300
              owner_access   dd ?
1306
              owner_access   dd ?
1301
              mapped         dd ?
1307
              mapped         dd ?
1302
           endl
1308
           endl
1303
 
1309
 
1304
           push ebx
1310
           push ebx
1305
           push esi
1311
           push esi
1306
           push edi
1312
           push edi
1307
 
1313
 
1308
           mov [mapped], 0
1314
           mov [mapped], 0
1309
           mov [owner_access], 0
1315
           mov [owner_access], 0
1310
 
1316
 
1311
           pushfd                      ;mutex required
1317
           pushfd                      ;mutex required
1312
           cli
1318
           cli
1313
 
1319
 
1314
           mov eax, [access]
1320
           mov eax, [access]
1315
           and eax, SHM_OPEN_MASK
1321
           and eax, SHM_OPEN_MASK
1316
           mov [action], eax
1322
           mov [action], eax
1317
 
1323
 
1318
           mov ebx, [name]
1324
           mov ebx, [name]
1319
           test ebx, ebx
1325
           test ebx, ebx
1320
           mov edx, E_PARAM
1326
           mov edx, E_PARAM
1321
           jz .fail
1327
           jz .fail
1322
 
1328
 
1323
           mov esi, [shmem_list.fd]
1329
           mov esi, [shmem_list.fd]
1324
align 4
1330
align 4
1325
@@:
1331
@@:
1326
           cmp esi, shmem_list
1332
           cmp esi, shmem_list
1327
           je .not_found
1333
           je .not_found
1328
 
1334
 
1329
           lea edx, [esi+SMEM.name] ; link , base, size
1335
           lea edx, [esi+SMEM.name] ; link , base, size
1330
           stdcall strncmp, edx, ebx, 32
1336
           stdcall strncmp, edx, ebx, 32
1331
           test eax, eax
1337
           test eax, eax
1332
           je .found
1338
           je .found
1333
 
1339
 
1334
           mov esi, [esi+SMEM.fd]
1340
           mov esi, [esi+SMEM.fd]
1335
           jmp @B
1341
           jmp @B
1336
 
1342
 
1337
.not_found:
1343
.not_found:
1338
           mov eax, [action]
1344
           mov eax, [action]
1339
 
1345
 
1340
           cmp eax, SHM_OPEN
1346
           cmp eax, SHM_OPEN
1341
           mov edx, E_NOTFOUND
1347
           mov edx, E_NOTFOUND
1342
           je .fail
1348
           je .fail
1343
 
1349
 
1344
           cmp eax, SHM_CREATE
1350
           cmp eax, SHM_CREATE
1345
           mov edx, E_PARAM
1351
           mov edx, E_PARAM
1346
           je .create_shm
1352
           je .create_shm
1347
 
1353
 
1348
           cmp eax, SHM_OPEN_ALWAYS
1354
           cmp eax, SHM_OPEN_ALWAYS
1349
           jne .fail
1355
           jne .fail
1350
 
1356
 
1351
.create_shm:
1357
.create_shm:
1352
 
1358
 
1353
           mov ecx, [size]
1359
           mov ecx, [size]
1354
           test ecx, ecx
1360
           test ecx, ecx
1355
           jz .fail
1361
           jz .fail
1356
 
1362
 
1357
           add ecx, 4095
1363
           add ecx, 4095
1358
           and ecx, -4096
1364
           and ecx, -4096
1359
           mov [size], ecx
1365
           mov [size], ecx
1360
 
1366
 
1361
           mov eax, SMEM.sizeof
1367
           mov eax, SMEM.sizeof
1362
           call malloc
1368
           call malloc
1363
           test eax, eax
1369
           test eax, eax
1364
           mov esi, eax
1370
           mov esi, eax
1365
           mov edx, E_NOMEM
1371
           mov edx, E_NOMEM
1366
           jz .fail
1372
           jz .fail
1367
 
1373
 
1368
           stdcall kernel_alloc, [size]
1374
           stdcall kernel_alloc, [size]
1369
           test eax, eax
1375
           test eax, eax
1370
           mov [mapped], eax
1376
           mov [mapped], eax
1371
           mov edx, E_NOMEM
1377
           mov edx, E_NOMEM
1372
           jz .cleanup
1378
           jz .cleanup
1373
 
1379
 
1374
           mov ecx, [size]
1380
           mov ecx, [size]
1375
           mov edx, [access]
1381
           mov edx, [access]
1376
           and edx, SHM_ACCESS_MASK
1382
           and edx, SHM_ACCESS_MASK
1377
 
1383
 
1378
           mov [esi+SMEM.base], eax
1384
           mov [esi+SMEM.base], eax
1379
           mov [esi+SMEM.size], ecx
1385
           mov [esi+SMEM.size], ecx
1380
           mov [esi+SMEM.access], edx
1386
           mov [esi+SMEM.access], edx
1381
           mov [esi+SMEM.refcount], 0
1387
           mov [esi+SMEM.refcount], 0
1382
           mov [esi+SMEM.name+28], 0
1388
           mov [esi+SMEM.name+28], 0
1383
 
1389
 
1384
           lea eax, [esi+SMEM.name]
1390
           lea eax, [esi+SMEM.name]
1385
           stdcall strncpy, eax, [name], 31
1391
           stdcall strncpy, eax, [name], 31
1386
 
1392
 
1387
           mov eax, [shmem_list.fd]
1393
           mov eax, [shmem_list.fd]
1388
           mov [esi+SMEM.bk], shmem_list
1394
           mov [esi+SMEM.bk], shmem_list
1389
           mov [esi+SMEM.fd], eax
1395
           mov [esi+SMEM.fd], eax
1390
 
1396
 
1391
           mov [eax+SMEM.bk], esi
1397
           mov [eax+SMEM.bk], esi
1392
           mov [shmem_list.fd], esi
1398
           mov [shmem_list.fd], esi
1393
 
1399
 
1394
           mov [action], SHM_OPEN
1400
           mov [action], SHM_OPEN
1395
           mov [owner_access], SHM_WRITE
1401
           mov [owner_access], SHM_WRITE
1396
 
1402
 
1397
.found:
1403
.found:
1398
           mov eax, [action]
1404
           mov eax, [action]
1399
 
1405
 
1400
           cmp eax, SHM_CREATE
1406
           cmp eax, SHM_CREATE
1401
           mov edx, E_ACCESS
1407
           mov edx, E_ACCESS
1402
           je .exit
1408
           je .exit
1403
 
1409
 
1404
           cmp eax, SHM_OPEN
1410
           cmp eax, SHM_OPEN
1405
           mov edx, E_PARAM
1411
           mov edx, E_PARAM
1406
           je .create_map
1412
           je .create_map
1407
 
1413
 
1408
           cmp eax, SHM_OPEN_ALWAYS
1414
           cmp eax, SHM_OPEN_ALWAYS
1409
           jne .fail
1415
           jne .fail
1410
 
1416
 
1411
.create_map:
1417
.create_map:
1412
 
1418
 
1413
           mov eax, [access]
1419
           mov eax, [access]
1414
           and eax, SHM_ACCESS_MASK
1420
           and eax, SHM_ACCESS_MASK
1415
           cmp eax, [esi+SMEM.access]
1421
           cmp eax, [esi+SMEM.access]
1416
           mov [access], eax
1422
           mov [access], eax
1417
           mov edx, E_ACCESS
1423
           mov edx, E_ACCESS
1418
           ja .fail
1424
           ja .fail
1419
 
1425
 
1420
           mov ebx, [CURRENT_TASK]
1426
           mov ebx, [CURRENT_TASK]
1421
           shl ebx, 5
1427
           shl ebx, 5
1422
           mov ebx, [CURRENT_TASK+ebx+4]
1428
           mov ebx, [CURRENT_TASK+ebx+4]
1423
           mov eax, SMAP.sizeof
1429
           mov eax, SMAP.sizeof
1424
 
1430
 
1425
           call create_kernel_object
1431
           call create_kernel_object
1426
           test eax, eax
1432
           test eax, eax
1427
           mov edi, eax
1433
           mov edi, eax
1428
           mov edx, E_NOMEM
1434
           mov edx, E_NOMEM
1429
           jz .fail
1435
           jz .fail
1430
 
1436
 
1431
           inc [esi+SMEM.refcount]
1437
           inc [esi+SMEM.refcount]
1432
 
1438
 
1433
           mov [edi+SMAP.magic], 'SMAP'
1439
           mov [edi+SMAP.magic], 'SMAP'
1434
           mov [edi+SMAP.destroy], destroy_smap
1440
           mov [edi+SMAP.destroy], destroy_smap
1435
           mov [edi+SMAP.parent], esi
1441
           mov [edi+SMAP.parent], esi
1436
           mov [edi+SMAP.base], 0
1442
           mov [edi+SMAP.base], 0
1437
 
1443
 
1438
           stdcall user_alloc, [esi+SMEM.size]
1444
           stdcall user_alloc, [esi+SMEM.size]
1439
           test eax, eax
1445
           test eax, eax
1440
           mov [mapped], eax
1446
           mov [mapped], eax
1441
           mov edx, E_NOMEM
1447
           mov edx, E_NOMEM
1442
           jz .cleanup2
1448
           jz .cleanup2
1443
 
1449
 
1444
           mov [edi+SMAP.base], eax
1450
           mov [edi+SMAP.base], eax
1445
 
1451
 
1446
           mov ecx, [esi+SMEM.size]
1452
           mov ecx, [esi+SMEM.size]
1447
           mov [size], ecx
1453
           mov [size], ecx
1448
 
1454
 
1449
           shr ecx, 12
1455
           shr ecx, 12
1450
           shr eax, 10
1456
           shr eax, 10
1451
 
1457
 
1452
           mov esi, [esi+SMEM.base]
1458
           mov esi, [esi+SMEM.base]
1453
           shr esi, 10
1459
           shr esi, 10
1454
           lea edi, [page_tabs+eax]
1460
           lea edi, [page_tabs+eax]
1455
           add esi, page_tabs
1461
           add esi, page_tabs
1456
 
1462
 
1457
           mov edx, [access]
1463
           mov edx, [access]
1458
           or edx, [owner_access]
1464
           or edx, [owner_access]
1459
           shl edx, 1
1465
           shl edx, 1
1460
           or edx, PG_USER+PG_SHARED
1466
           or edx, PG_USER+PG_SHARED
1461
@@:
1467
@@:
1462
           lodsd
1468
           lodsd
1463
           and eax, 0xFFFFF000
1469
           and eax, 0xFFFFF000
1464
           or eax, edx
1470
           or eax, edx
1465
           stosd
1471
           stosd
1466
           loop @B
1472
           loop @B
1467
 
1473
 
1468
           xor edx, edx
1474
           xor edx, edx
1469
 
1475
 
1470
           cmp [owner_access], 0
1476
           cmp [owner_access], 0
1471
           jne .fail
1477
           jne .fail
1472
.exit:
1478
.exit:
1473
           mov edx, [size]
1479
           mov edx, [size]
1474
.fail:
1480
.fail:
1475
           mov eax, [mapped]
1481
           mov eax, [mapped]
1476
 
1482
 
1477
           popfd
1483
           popfd
1478
           pop edi
1484
           pop edi
1479
           pop esi
1485
           pop esi
1480
           pop ebx
1486
           pop ebx
1481
           ret
1487
           ret
1482
.cleanup:
1488
.cleanup:
1483
           mov [size], edx
1489
           mov [size], edx
1484
           mov eax, esi
1490
           mov eax, esi
1485
           call free
1491
           call free
1486
           jmp .exit
1492
           jmp .exit
1487
 
1493
 
1488
.cleanup2:
1494
.cleanup2:
1489
           mov [size], edx
1495
           mov [size], edx
1490
           mov eax, edi
1496
           mov eax, edi
1491
           call destroy_smap
1497
           call destroy_smap
1492
           jmp .exit
1498
           jmp .exit
1493
endp
1499
endp
1494
 
1500
 
1495
align 4
1501
align 4
1496
proc shmem_close stdcall, name:dword
1502
proc shmem_close stdcall, name:dword
1497
 
1503
 
1498
           mov eax, [name]
1504
           mov eax, [name]
1499
           test eax, eax
1505
           test eax, eax
1500
           jz .fail
1506
           jz .fail
1501
 
1507
 
1502
           push esi
1508
           push esi
1503
           push edi
1509
           push edi
1504
           pushfd
1510
           pushfd
1505
           cli
1511
           cli
1506
 
1512
 
1507
           mov esi, [current_slot]
1513
           mov esi, [current_slot]
1508
           add esi, APP_OBJ_OFFSET
1514
           add esi, APP_OBJ_OFFSET
1509
.next:
1515
.next:
1510
           mov eax, [esi+APPOBJ.fd]
1516
           mov eax, [esi+APPOBJ.fd]
1511
           test eax, eax
1517
           test eax, eax
1512
           jz @F
1518
           jz @F
1513
 
1519
 
1514
           cmp eax, esi
1520
           cmp eax, esi
1515
           mov esi, eax
1521
           mov esi, eax
1516
           je @F
1522
           je @F
1517
 
1523
 
1518
           cmp [eax+SMAP.magic], 'SMAP'
1524
           cmp [eax+SMAP.magic], 'SMAP'
1519
           jne .next
1525
           jne .next
1520
 
1526
 
1521
           mov edi, [eax+SMAP.parent]
1527
           mov edi, [eax+SMAP.parent]
1522
           test edi, edi
1528
           test edi, edi
1523
           jz .next
1529
           jz .next
1524
 
1530
 
1525
           lea edi, [edi+SMEM.name]
1531
           lea edi, [edi+SMEM.name]
1526
           stdcall strncmp, [name], edi, 32
1532
           stdcall strncmp, [name], edi, 32
1527
           test eax, eax
1533
           test eax, eax
1528
           jne .next
1534
           jne .next
1529
 
1535
 
1530
           stdcall user_free, [esi+SMAP.base]
1536
           stdcall user_free, [esi+SMAP.base]
1531
 
1537
 
1532
           mov eax,esi
1538
           mov eax,esi
1533
           call [esi+APPOBJ.destroy]
1539
           call [esi+APPOBJ.destroy]
1534
@@:
1540
@@:
1535
           popfd
1541
           popfd
1536
           pop edi
1542
           pop edi
1537
           pop esi
1543
           pop esi
1538
.fail:
1544
.fail:
1539
           ret
1545
           ret
1540
endp
1546
endp