Subversion Repositories Kolibri OS

Rev

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

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