Subversion Repositories Kolibri OS

Rev

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

Rev 819 Rev 823
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2007. 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: 819 $
8
$Revision: 823 $
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/4
94
           mov ecx, 64/4
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, [MEM_AMOUNT]
141
           mov ecx, [MEM_AMOUNT]
142
           sub ecx, (HEAP_BASE - OS_BASE + 4096*MEM_BLOCK_SIZE)
142
           sub ecx, (HEAP_BASE - OS_BASE + 4096*MEM_BLOCK_SIZE)
143
           mov [heap_size], ecx
143
           mov [heap_size], ecx
144
           mov [heap_free], ecx
144
           mov [heap_free], ecx
145
           mov [ebx+block_size], ecx
145
           mov [ebx+block_size], ecx
146
           mov [ebx+block_flags], FREE_BLOCK
146
           mov [ebx+block_flags], FREE_BLOCK
147
 
147
 
148
           mov [mem_block_mask], eax
148
           mov [mem_block_mask], eax
149
           mov [mem_block_mask+4],0x80000000
149
           mov [mem_block_mask+4],0x80000000
150
 
150
 
151
           mov [mem_block_list+63*4], ebx
151
           mov [mem_block_list+63*4], ebx
152
           mov byte [mem_block_map], 0xFC
152
           mov byte [mem_block_map], 0xFC
153
           and [heap_mutex], 0
153
           and [heap_mutex], 0
154
           mov [heap_blocks], 4095
154
           mov [heap_blocks], 4095
155
           mov [free_blocks], 4095
155
           mov [free_blocks], 4095
156
           ret
156
           ret
157
endp
157
endp
158
 
158
 
159
; param
159
; param
160
;  eax= required size
160
;  eax= required size
161
;
161
;
162
; retval
162
; retval
163
;  edi= memory block descriptor
163
;  edi= memory block descriptor
164
;  ebx= descriptor index
164
;  ebx= descriptor index
165
 
165
 
166
align 4
166
align 4
167
get_small_block:
167
get_small_block:
168
           mov ecx, eax
168
           mov ecx, eax
169
           shr ecx, 12
169
           shr ecx, 12
170
           dec ecx
170
           dec ecx
171
           cmp ecx, 63
171
           cmp ecx, 63
172
           jle .get_index
172
           jle .get_index
173
           mov ecx, 63
173
           mov ecx, 63
174
.get_index:
174
.get_index:
175
           lea esi, [mem_block_mask]
175
           lea esi, [mem_block_mask]
176
           xor ebx, ebx
176
           xor ebx, ebx
177
           or edx, -1
177
           or edx, -1
178
 
178
 
179
           cmp ecx, 32
179
           cmp ecx, 32
180
           jb .bit_test
180
           jb .bit_test
181
 
181
 
182
           sub ecx, 32
182
           sub ecx, 32
183
           add ebx, 32
183
           add ebx, 32
184
           add esi, 4
184
           add esi, 4
185
.bit_test:
185
.bit_test:
186
           shl edx, cl
186
           shl edx, cl
187
           and edx, [esi]
187
           and edx, [esi]
188
.find:
188
.find:
189
           bsf edi, edx
189
           bsf edi, edx
190
           jz .high_mask
190
           jz .high_mask
191
           add ebx, edi
191
           add ebx, edi
192
           mov edi, [mem_block_list+ebx*4]
192
           mov edi, [mem_block_list+ebx*4]
193
.check_size:
193
.check_size:
194
           cmp eax, [edi+block_size]
194
           cmp eax, [edi+block_size]
195
           ja .next
195
           ja .next
196
           ret
196
           ret
197
 
197
 
198
.high_mask:
198
.high_mask:
199
           add esi, 4
199
           add esi, 4
200
           cmp esi, mem_block_mask+8
200
           cmp esi, mem_block_mask+8
201
           jae .err
201
           jae .err
202
           add ebx, 32
202
           add ebx, 32
203
           mov edx, [esi]
203
           mov edx, [esi]
204
           jmp .find
204
           jmp .find
205
.next:
205
.next:
206
           mov edi, [edi+list_fd]
206
           mov edi, [edi+list_fd]
207
           test edi, edi
207
           test edi, edi
208
           jnz .check_size
208
           jnz .check_size
209
.err:
209
.err:
210
           xor edi, edi
210
           xor edi, edi
211
           ret
211
           ret
212
 
212
 
213
align 4
213
align 4
214
alloc_mem_block:
214
alloc_mem_block:
215
 
215
 
216
           mov ebx, [mem_block_start]
216
           mov ebx, [mem_block_start]
217
           mov ecx, [mem_block_end]
217
           mov ecx, [mem_block_end]
218
.l1:
218
.l1:
219
           bsf eax,[ebx];
219
           bsf eax,[ebx];
220
           jnz found
220
           jnz found
221
           add ebx,4
221
           add ebx,4
222
           cmp ebx, ecx
222
           cmp ebx, ecx
223
           jb .l1
223
           jb .l1
224
           xor eax,eax
224
           xor eax,eax
225
           ret
225
           ret
226
 
226
 
227
found:
227
found:
228
           btr [ebx], eax
228
           btr [ebx], eax
229
           mov [mem_block_start],ebx
229
           mov [mem_block_start],ebx
230
           sub ebx, mem_block_map
230
           sub ebx, mem_block_map
231
           lea eax,[eax+ebx*8]
231
           lea eax,[eax+ebx*8]
232
           shl eax, 5
232
           shl eax, 5
233
           add eax, [mem_block_arr]
233
           add eax, [mem_block_arr]
234
           dec [free_blocks]
234
           dec [free_blocks]
235
           ret
235
           ret
236
align 4
236
align 4
237
free_mem_block:
237
free_mem_block:
238
           mov dword [eax], 0
238
           mov dword [eax], 0
239
           mov dword [eax+4], 0
239
           mov dword [eax+4], 0
240
           mov dword [eax+8], 0
240
           mov dword [eax+8], 0
241
           mov dword [eax+12], 0
241
           mov dword [eax+12], 0
242
           mov dword [eax+16], 0
242
           mov dword [eax+16], 0
243
;           mov dword [eax+20], 0
243
;           mov dword [eax+20], 0
244
           mov dword [eax+24], 0
244
           mov dword [eax+24], 0
245
           mov dword [eax+28], 0
245
           mov dword [eax+28], 0
246
 
246
 
247
           sub eax, [mem_block_arr]
247
           sub eax, [mem_block_arr]
248
           shr eax, 5
248
           shr eax, 5
249
 
249
 
250
           mov ebx, mem_block_map
250
           mov ebx, mem_block_map
251
           bts [ebx], eax
251
           bts [ebx], eax
252
           inc [free_blocks]
252
           inc [free_blocks]
253
           shr eax, 3
253
           shr eax, 3
254
           and eax, not 3
254
           and eax, not 3
255
           add eax, ebx
255
           add eax, ebx
256
           cmp [mem_block_start], eax
256
           cmp [mem_block_start], eax
257
           ja @f
257
           ja @f
258
           ret
258
           ret
259
@@:
259
@@:
260
           mov [mem_block_start], eax
260
           mov [mem_block_start], eax
261
	   ret
261
	   ret
262
.err:
262
.err:
263
           xor eax, eax
263
           xor eax, eax
264
	   ret
264
	   ret
265
 
265
 
266
align 4
266
align 4
267
proc alloc_kernel_space stdcall, size:dword
267
proc alloc_kernel_space stdcall, size:dword
268
           local block_ind:DWORD
268
           local block_ind:DWORD
269
 
269
 
270
           push ebx
270
           push ebx
271
           push esi
271
           push esi
272
           push edi
272
           push edi
273
 
273
 
274
           mov eax, [size]
274
           mov eax, [size]
275
           add eax, 4095
275
           add eax, 4095
276
           and eax, not 4095
276
           and eax, not 4095
277
           mov [size], eax
277
           mov [size], eax
278
 
278
 
279
           mov ebx, heap_mutex
279
           mov ebx, heap_mutex
280
           call wait_mutex    ;ebx
280
           call wait_mutex    ;ebx
281
 
281
 
282
           cmp eax, [heap_free]
282
           cmp eax, [heap_free]
283
           ja .error
283
           ja .error
284
 
284
 
285
           call get_small_block ; eax
285
           call get_small_block ; eax
286
           test edi, edi
286
           test edi, edi
287
           jz .error
287
           jz .error
288
 
288
 
289
           cmp [edi+block_flags], FREE_BLOCK
289
           cmp [edi+block_flags], FREE_BLOCK
290
           jne .error
290
           jne .error
291
 
291
 
292
           mov [block_ind], ebx   ;index of allocated block
292
           mov [block_ind], ebx   ;index of allocated block
293
 
293
 
294
           mov eax, [edi+block_size]
294
           mov eax, [edi+block_size]
295
           cmp eax, [size]
295
           cmp eax, [size]
296
           je .m_eq_size
296
           je .m_eq_size
297
 
297
 
298
           call alloc_mem_block
298
           call alloc_mem_block
299
           and eax, eax
299
           and eax, eax
300
           jz .error
300
           jz .error
301
 
301
 
302
           mov esi, eax           ;esi - splitted block
302
           mov esi, eax           ;esi - splitted block
303
 
303
 
304
           mov [esi+block_next], edi
304
           mov [esi+block_next], edi
305
           mov eax, [edi+block_prev]
305
           mov eax, [edi+block_prev]
306
           mov [esi+block_prev], eax
306
           mov [esi+block_prev], eax
307
           mov [edi+block_prev], esi
307
           mov [edi+block_prev], esi
308
           mov [esi+list_fd], 0
308
           mov [esi+list_fd], 0
309
           mov [esi+list_bk], 0
309
           mov [esi+list_bk], 0
310
           and eax, eax
310
           and eax, eax
311
           jz @f
311
           jz @f
312
           mov [eax+block_next], esi
312
           mov [eax+block_next], esi
313
@@:
313
@@:
314
           mov ebx, [edi+block_base]
314
           mov ebx, [edi+block_base]
315
           mov [esi+block_base], ebx
315
           mov [esi+block_base], ebx
316
           mov edx, [size]
316
           mov edx, [size]
317
           mov [esi+block_size], edx
317
           mov [esi+block_size], edx
318
           add [edi+block_base], edx
318
           add [edi+block_base], edx
319
           sub [edi+block_size], edx
319
           sub [edi+block_size], edx
320
 
320
 
321
           mov eax, [edi+block_size]
321
           mov eax, [edi+block_size]
322
           shr eax, 12
322
           shr eax, 12
323
           sub eax, 1
323
           sub eax, 1
324
           cmp eax, 63
324
           cmp eax, 63
325
           jna @f
325
           jna @f
326
           mov eax, 63
326
           mov eax, 63
327
@@:
327
@@:
328
           cmp eax, [block_ind]
328
           cmp eax, [block_ind]
329
           je .m_eq_ind
329
           je .m_eq_ind
330
 
330
 
331
           remove_from_list edi
331
           remove_from_list edi
332
 
332
 
333
           mov ecx, [block_ind]
333
           mov ecx, [block_ind]
334
           mov [mem_block_list+ecx*4], edx
334
           mov [mem_block_list+ecx*4], edx
335
 
335
 
336
           test edx, edx
336
           test edx, edx
337
           jnz @f
337
           jnz @f
338
           btr [mem_block_mask], ecx
338
           btr [mem_block_mask], ecx
339
@@:
339
@@:
340
           mov edx, [mem_block_list+eax*4]
340
           mov edx, [mem_block_list+eax*4]
341
           mov [edi+list_fd], edx
341
           mov [edi+list_fd], edx
342
           test edx, edx
342
           test edx, edx
343
           jz @f
343
           jz @f
344
           mov [edx+list_bk], edi
344
           mov [edx+list_bk], edi
345
@@:
345
@@:
346
           mov [mem_block_list+eax*4], edi
346
           mov [mem_block_list+eax*4], edi
347
           bts [mem_block_mask], eax
347
           bts [mem_block_mask], eax
348
.m_eq_ind:
348
.m_eq_ind:
349
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
349
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
350
           mov edx, [ecx+list_fd]
350
           mov edx, [ecx+list_fd]
351
           mov [esi+list_fd], edx
351
           mov [esi+list_fd], edx
352
           mov [esi+list_bk], ecx
352
           mov [esi+list_bk], ecx
353
           mov [ecx+list_fd], esi
353
           mov [ecx+list_fd], esi
354
           mov [edx+list_bk], esi
354
           mov [edx+list_bk], esi
355
 
355
 
356
           mov [esi+block_flags], USED_BLOCK
356
           mov [esi+block_flags], USED_BLOCK
357
           mov eax, [esi+block_base]
357
           mov eax, [esi+block_base]
358
           mov ebx, [size]
358
           mov ebx, [size]
359
           sub [heap_free], ebx
359
           sub [heap_free], ebx
360
           and [heap_mutex], 0
360
           and [heap_mutex], 0
361
           pop edi
361
           pop edi
362
           pop esi
362
           pop esi
363
           pop ebx
363
           pop ebx
364
           ret
364
           ret
365
.m_eq_size:
365
.m_eq_size:
366
           remove_from_list edi
366
           remove_from_list edi
367
           mov [mem_block_list+ebx*4], edx
367
           mov [mem_block_list+ebx*4], edx
368
           and edx, edx
368
           and edx, edx
369
           jnz @f
369
           jnz @f
370
           btr [mem_block_mask], ebx
370
           btr [mem_block_mask], ebx
371
@@:
371
@@:
372
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
372
           mov ecx, mem_used.fd-MEM_LIST_OFFSET
373
           mov edx, [ecx+list_fd]
373
           mov edx, [ecx+list_fd]
374
           mov [edi+list_fd], edx
374
           mov [edi+list_fd], edx
375
           mov [edi+list_bk], ecx
375
           mov [edi+list_bk], ecx
376
           mov [ecx+list_fd], edi
376
           mov [ecx+list_fd], edi
377
           mov [edx+list_bk], edi
377
           mov [edx+list_bk], edi
378
 
378
 
379
           mov [edi+block_flags], USED_BLOCK
379
           mov [edi+block_flags], USED_BLOCK
380
           mov eax, [edi+block_base]
380
           mov eax, [edi+block_base]
381
           mov ebx, [size]
381
           mov ebx, [size]
382
           sub [heap_free], ebx
382
           sub [heap_free], ebx
383
           and [heap_mutex], 0
383
           and [heap_mutex], 0
384
           pop edi
384
           pop edi
385
           pop esi
385
           pop esi
386
           pop ebx
386
           pop ebx
387
           ret
387
           ret
388
.error:
388
.error:
389
           xor eax, eax
389
           xor eax, eax
390
           mov [heap_mutex], eax
390
           mov [heap_mutex], eax
391
           pop edi
391
           pop edi
392
           pop esi
392
           pop esi
393
           pop ebx
393
           pop ebx
394
           ret
394
           ret
395
endp
395
endp
396
 
396
 
397
align 4
397
align 4
398
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
398
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
399
           push ebx
399
           push ebx
400
           push esi
400
           push esi
401
           push edi
401
           push edi
402
           mov ebx, heap_mutex
402
           mov ebx, heap_mutex
403
           call wait_mutex    ;ebx
403
           call wait_mutex    ;ebx
404
 
404
 
405
           mov eax, [base]
405
           mov eax, [base]
406
           mov esi, [mem_used.fd]
406
           mov esi, [mem_used.fd]
407
@@:
407
@@:
408
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
408
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
409
           je .fail
409
           je .fail
410
 
410
 
411
           cmp [esi+block_base], eax
411
           cmp [esi+block_base], eax
412
           je .found
412
           je .found
413
           mov esi, [esi+list_fd]
413
           mov esi, [esi+list_fd]
414
           jmp @b
414
           jmp @b
415
.found:
415
.found:
416
           cmp [esi+block_flags], USED_BLOCK
416
           cmp [esi+block_flags], USED_BLOCK
417
           jne .fail
417
           jne .fail
418
 
418
 
419
           mov eax, [esi+block_size]
419
           mov eax, [esi+block_size]
420
           add [heap_free], eax
420
           add [heap_free], eax
421
 
421
 
422
           mov edi, [esi+block_next]
422
           mov edi, [esi+block_next]
423
           test edi, edi
423
           test edi, edi
424
           jz .prev
424
           jz .prev
425
 
425
 
426
           cmp [edi+block_flags], FREE_BLOCK
426
           cmp [edi+block_flags], FREE_BLOCK
427
           jne .prev
427
           jne .prev
428
 
428
 
429
           remove_from_free edi
429
           remove_from_free edi
430
 
430
 
431
           mov edx, [edi+block_next]
431
           mov edx, [edi+block_next]
432
           mov [esi+block_next], edx
432
           mov [esi+block_next], edx
433
           test edx, edx
433
           test edx, edx
434
           jz @f
434
           jz @f
435
 
435
 
436
           mov [edx+block_prev], esi
436
           mov [edx+block_prev], esi
437
@@:
437
@@:
438
           mov ecx, [edi+block_size]
438
           mov ecx, [edi+block_size]
439
           add [esi+block_size], ecx
439
           add [esi+block_size], ecx
440
 
440
 
441
           mov eax, edi
441
           mov eax, edi
442
           call free_mem_block
442
           call free_mem_block
443
.prev:
443
.prev:
444
           mov edi, [esi+block_prev]
444
           mov edi, [esi+block_prev]
445
           test edi, edi
445
           test edi, edi
446
           jz .insert
446
           jz .insert
447
 
447
 
448
           cmp [edi+block_flags], FREE_BLOCK
448
           cmp [edi+block_flags], FREE_BLOCK
449
           jne .insert
449
           jne .insert
450
 
450
 
451
           remove_from_used esi
451
           remove_from_used esi
452
 
452
 
453
           mov edx, [esi+block_next]
453
           mov edx, [esi+block_next]
454
           mov [edi+block_next], edx
454
           mov [edi+block_next], edx
455
           test edx, edx
455
           test edx, edx
456
           jz @f
456
           jz @f
457
           mov [edx+block_prev], edi
457
           mov [edx+block_prev], edi
458
@@:
458
@@:
459
           mov eax, esi
459
           mov eax, esi
460
           call free_mem_block
460
           call free_mem_block
461
 
461
 
462
           mov ecx, [edi+block_size]
462
           mov ecx, [edi+block_size]
463
           mov eax, [esi+block_size]
463
           mov eax, [esi+block_size]
464
           add eax, ecx
464
           add eax, ecx
465
           mov [edi+block_size], eax
465
           mov [edi+block_size], eax
466
 
466
 
467
           calc_index eax
467
           calc_index eax
468
           calc_index ecx
468
           calc_index ecx
469
           cmp eax, ecx
469
           cmp eax, ecx
470
           je .m_eq
470
           je .m_eq
471
 
471
 
472
           push ecx
472
           push ecx
473
           remove_from_list edi
473
           remove_from_list edi
474
           pop ecx
474
           pop ecx
475
 
475
 
476
           cmp [mem_block_list+ecx*4], edi
476
           cmp [mem_block_list+ecx*4], edi
477
           jne @f
477
           jne @f
478
           mov [mem_block_list+ecx*4], edx
478
           mov [mem_block_list+ecx*4], edx
479
@@:
479
@@:
480
           cmp [mem_block_list+ecx*4], 0
480
           cmp [mem_block_list+ecx*4], 0
481
           jne @f
481
           jne @f
482
           btr [mem_block_mask], ecx
482
           btr [mem_block_mask], ecx
483
@@:
483
@@:
484
           mov esi, [mem_block_list+eax*4]
484
           mov esi, [mem_block_list+eax*4]
485
           mov [mem_block_list+eax*4], edi
485
           mov [mem_block_list+eax*4], edi
486
           mov [edi+list_fd], esi
486
           mov [edi+list_fd], esi
487
           test esi, esi
487
           test esi, esi
488
           jz @f
488
           jz @f
489
           mov [esi+list_bk], edi
489
           mov [esi+list_bk], edi
490
@@:
490
@@:
491
           bts [mem_block_mask], eax
491
           bts [mem_block_mask], eax
492
.m_eq:
492
.m_eq:
493
           xor eax, eax
493
           xor eax, eax
494
           mov [heap_mutex], eax
494
           mov [heap_mutex], eax
495
           dec eax
495
           dec eax
496
           pop edi
496
           pop edi
497
           pop esi
497
           pop esi
498
           pop ebx
498
           pop ebx
499
           ret
499
           ret
500
.insert:
500
.insert:
501
           remove_from_used esi
501
           remove_from_used esi
502
 
502
 
503
           mov eax, [esi+block_size]
503
           mov eax, [esi+block_size]
504
           calc_index eax
504
           calc_index eax
505
 
505
 
506
           mov edi, [mem_block_list+eax*4]
506
           mov edi, [mem_block_list+eax*4]
507
           mov [mem_block_list+eax*4], esi
507
           mov [mem_block_list+eax*4], esi
508
           mov [esi+list_fd], edi
508
           mov [esi+list_fd], edi
509
           test edi, edi
509
           test edi, edi
510
           jz @f
510
           jz @f
511
           mov [edi+list_bk], esi
511
           mov [edi+list_bk], esi
512
@@:
512
@@:
513
           bts [mem_block_mask], eax
513
           bts [mem_block_mask], eax
514
           mov [esi+block_flags],FREE_BLOCK
514
           mov [esi+block_flags],FREE_BLOCK
515
           xor eax, eax
515
           xor eax, eax
516
           mov [heap_mutex], eax
516
           mov [heap_mutex], eax
517
           dec eax
517
           dec eax
518
           pop edi
518
           pop edi
519
           pop esi
519
           pop esi
520
           pop ebx
520
           pop ebx
521
           ret
521
           ret
522
.fail:
522
.fail:
523
           xor eax, eax
523
           xor eax, eax
524
           mov [heap_mutex], eax
524
           mov [heap_mutex], eax
525
           pop edi
525
           pop edi
526
           pop esi
526
           pop esi
527
           pop ebx
527
           pop ebx
528
           ret
528
           ret
529
endp
529
endp
530
 
530
 
531
align 4
531
align 4
532
proc kernel_alloc stdcall, size:dword
532
proc kernel_alloc stdcall, size:dword
533
           locals
533
           locals
534
             lin_addr    dd ?
534
             lin_addr    dd ?
535
             pages_count dd ?
535
             pages_count dd ?
536
           endl
536
           endl
537
 
537
 
538
           push ebx
538
           push ebx
539
           push edi
539
           push edi
540
 
540
 
541
           mov eax, [size]
541
           mov eax, [size]
542
           add eax, 4095
542
           add eax, 4095
543
           and eax, not 4095;
543
           and eax, not 4095;
544
           mov [size], eax
544
           mov [size], eax
545
           and eax, eax
545
           and eax, eax
546
           jz .err
546
           jz .err
547
           mov ebx, eax
547
           mov ebx, eax
548
           shr ebx, 12
548
           shr ebx, 12
549
           mov [pages_count], ebx
549
           mov [pages_count], ebx
550
 
550
 
551
           stdcall alloc_kernel_space, eax
551
           stdcall alloc_kernel_space, eax
552
           test eax, eax
552
           test eax, eax
553
           jz .err
553
           jz .err
554
           mov [lin_addr], eax
554
           mov [lin_addr], eax
555
 
555
 
556
           mov ecx, [pages_count]
556
           mov ecx, [pages_count]
557
           mov edx, eax
557
           mov edx, eax
558
           mov ebx, ecx
558
           mov ebx, ecx
559
 
559
 
560
           shr ecx, 3
560
           shr ecx, 3
561
           jz .next
561
           jz .next
562
 
562
 
563
           and ebx, not 7
563
           and ebx, not 7
564
           push ebx
564
           push ebx
565
           stdcall alloc_pages, ebx
565
           stdcall alloc_pages, ebx
566
           pop ecx                   ; yes ecx!!!
566
           pop ecx                   ; yes ecx!!!
567
           and eax, eax
567
           and eax, eax
568
           jz .err
568
           jz .err
569
 
569
 
570
           mov edi, eax
570
           mov edi, eax
571
           mov edx, [lin_addr]
571
           mov edx, [lin_addr]
572
@@:
572
@@:
573
           stdcall map_page,edx,edi,dword PG_SW
573
           stdcall map_page,edx,edi,dword PG_SW
574
           add edx, 0x1000
574
           add edx, 0x1000
575
           add edi, 0x1000
575
           add edi, 0x1000
576
           dec ecx
576
           dec ecx
577
           jnz @B
577
           jnz @B
578
.next:
578
.next:
579
           mov ecx, [pages_count]
579
           mov ecx, [pages_count]
580
           and ecx, 7
580
           and ecx, 7
581
           jz .end
581
           jz .end
582
@@:
582
@@:
583
           push ecx
583
           push ecx
584
           call alloc_page
584
           call alloc_page
585
           pop ecx
585
           pop ecx
586
           test eax, eax
586
           test eax, eax
587
           jz .err
587
           jz .err
588
 
588
 
589
           stdcall map_page,edx,eax,dword PG_SW
589
           stdcall map_page,edx,eax,dword PG_SW
590
           add edx, 0x1000
590
           add edx, 0x1000
591
           dec ecx
591
           dec ecx
592
           jnz @B
592
           jnz @B
593
.end:
593
.end:
594
           mov eax, [lin_addr]
594
           mov eax, [lin_addr]
595
           pop edi
595
           pop edi
596
           pop ebx
596
           pop ebx
597
           ret
597
           ret
598
.err:
598
.err:
599
           xor eax, eax
599
           xor eax, eax
600
           pop edi
600
           pop edi
601
           pop ebx
601
           pop ebx
602
           ret
602
           ret
603
endp
603
endp
604
 
604
 
605
align 4
605
align 4
606
proc kernel_free stdcall, base:dword
606
proc kernel_free stdcall, base:dword
607
           push ebx esi
607
           push ebx esi
608
 
608
 
609
           mov ebx, heap_mutex
609
           mov ebx, heap_mutex
610
           call wait_mutex    ;ebx
610
           call wait_mutex    ;ebx
611
 
611
 
612
           mov eax, [base]
612
           mov eax, [base]
613
           mov esi, [mem_used.fd]
613
           mov esi, [mem_used.fd]
614
@@:
614
@@:
615
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
615
           cmp esi, mem_used.fd-MEM_LIST_OFFSET
616
           je .fail
616
           je .fail
617
 
617
 
618
           cmp [esi+block_base], eax
618
           cmp [esi+block_base], eax
619
           je .found
619
           je .found
620
           mov esi, [esi+list_fd]
620
           mov esi, [esi+list_fd]
621
           jmp @b
621
           jmp @b
622
.found:
622
.found:
623
           cmp [esi+block_flags], USED_BLOCK
623
           cmp [esi+block_flags], USED_BLOCK
624
           jne .fail
624
           jne .fail
625
 
625
 
626
           and [heap_mutex], 0
626
           and [heap_mutex], 0
627
 
627
 
628
           push ecx
628
           push ecx
629
           mov ecx, [esi+block_size];
629
           mov ecx, [esi+block_size];
630
           shr ecx, 12
630
           shr ecx, 12
631
           call release_pages   ;eax, ecx
631
           call release_pages   ;eax, ecx
632
           pop ecx
632
           pop ecx
633
           stdcall free_kernel_space, [base]
633
           stdcall free_kernel_space, [base]
634
           pop esi ebx
634
           pop esi ebx
635
           ret
635
           ret
636
.fail:
636
.fail:
637
           and [heap_mutex], 0
637
           and [heap_mutex], 0
638
           pop esi ebx
638
           pop esi ebx
639
           ret
639
           ret
640
endp
640
endp
641
 
641
 
642
restore block_next
642
restore block_next
643
restore block_prev
643
restore block_prev
644
restore block_list
644
restore block_list
645
restore block_base
645
restore block_base
646
restore block_size
646
restore block_size
647
restore block_flags
647
restore block_flags
648
 
648
 
649
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
649
;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
650
 
650
 
651
HEAP_TOP  equ 0x5FC00000
651
HEAP_TOP  equ 0x5FC00000
652
 
652
 
653
align 4
653
align 4
654
proc init_heap
654
proc init_heap
655
 
655
 
656
           mov ebx,[current_slot]
656
           mov ebx,[current_slot]
657
           mov eax, [ebx+APPDATA.heap_top]
657
           mov eax, [ebx+APPDATA.heap_top]
658
           test eax, eax
658
           test eax, eax
659
           jz @F
659
           jz @F
660
           sub eax,[ebx+APPDATA.heap_base]
660
           sub eax,[ebx+APPDATA.heap_base]
661
           sub eax, 4096
661
           sub eax, 4096
662
           ret
662
           ret
663
@@:
663
@@:
664
           mov esi, [ebx+APPDATA.mem_size]
664
           mov esi, [ebx+APPDATA.mem_size]
665
           add esi, 4095
665
           add esi, 4095
666
           and esi, not 4095
666
           and esi, not 4095
667
           mov [ebx+APPDATA.mem_size], esi
667
           mov [ebx+APPDATA.mem_size], esi
668
           mov eax, HEAP_TOP
668
           mov eax, HEAP_TOP
669
           mov [ebx+APPDATA.heap_base], esi
669
           mov [ebx+APPDATA.heap_base], esi
670
           mov [ebx+APPDATA.heap_top], eax
670
           mov [ebx+APPDATA.heap_top], eax
671
 
671
 
672
           sub eax, esi
672
           sub eax, esi
673
           shr esi, 10
673
           shr esi, 10
674
           mov ecx, eax
674
           mov ecx, eax
675
           sub eax, 4096
675
           sub eax, 4096
676
           or ecx, FREE_BLOCK
676
           or ecx, FREE_BLOCK
677
           mov [page_tabs+esi], ecx
677
           mov [page_tabs+esi], ecx
678
           ret
678
           ret
679
endp
679
endp
680
 
680
 
681
align 4
681
align 4
682
proc user_alloc stdcall, alloc_size:dword
682
proc user_alloc stdcall, alloc_size:dword
683
 
683
 
684
           push ebx
684
           push ebx
685
           push esi
685
           push esi
686
           push edi
686
           push edi
687
 
687
 
688
           mov ecx, [alloc_size]
688
           mov ecx, [alloc_size]
689
           add ecx, (4095+4096)
689
           add ecx, (4095+4096)
690
           and ecx, not 4095
690
           and ecx, not 4095
691
 
691
 
692
           mov ebx, [current_slot]
692
           mov ebx, [current_slot]
693
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
693
           mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
694
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
694
           mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
695
l_0:
695
l_0:
696
           cmp esi, edi
696
           cmp esi, edi
697
           jae m_exit
697
           jae m_exit
698
 
698
 
699
           mov ebx, esi
699
           mov ebx, esi
700
           shr ebx, 12
700
           shr ebx, 12
701
           mov eax, [page_tabs+ebx*4]
701
           mov eax, [page_tabs+ebx*4]
702
           test al, FREE_BLOCK
702
           test al, FREE_BLOCK
703
           jz test_used
703
           jz test_used
704
           and eax, 0xFFFFF000
704
           and eax, 0xFFFFF000
705
           cmp eax, ecx    ;alloc_size
705
           cmp eax, ecx    ;alloc_size
706
           jb  m_next
706
           jb  m_next
707
	   jz  @f
707
	   jz  @f
708
 
708
 
709
           lea edx, [esi+ecx]
709
           lea edx, [esi+ecx]
710
           sub eax, ecx
710
           sub eax, ecx
711
           or al, FREE_BLOCK
711
           or al, FREE_BLOCK
712
           shr edx, 12
712
           shr edx, 12
713
           mov [page_tabs+edx*4], eax
713
           mov [page_tabs+edx*4], eax
714
@@:
714
@@:
715
           or ecx, USED_BLOCK
715
           or ecx, USED_BLOCK
716
           mov [page_tabs+ebx*4], ecx
716
           mov [page_tabs+ebx*4], ecx
717
           shr ecx, 12
717
           shr ecx, 12
718
           inc ebx
718
           inc ebx
719
           dec ecx
719
           dec ecx
720
           jz  .no
720
           jz  .no
721
@@:
721
@@:
722
           mov dword [page_tabs+ebx*4], 2
722
           mov dword [page_tabs+ebx*4], 2
723
           inc ebx
723
           inc ebx
724
           dec ecx
724
           dec ecx
725
           jnz @B
725
           jnz @B
726
.no:
726
.no:
727
 
727
 
728
           mov     edx, [current_slot]
728
           mov     edx, [current_slot]
729
           mov     ebx, [alloc_size]
729
           mov     ebx, [alloc_size]
730
           add     ebx, 0xFFF
730
           add     ebx, 0xFFF
731
           and     ebx, not 0xFFF
731
           and     ebx, not 0xFFF
732
           add     ebx, [edx+APPDATA.mem_size]
732
           add     ebx, [edx+APPDATA.mem_size]
733
           call    update_mem_size
733
           call    update_mem_size
734
 
734
 
735
           lea eax, [esi+4096]
735
           lea eax, [esi+4096]
736
 
736
 
737
           pop edi
737
           pop edi
738
           pop esi
738
           pop esi
739
           pop ebx
739
           pop ebx
740
           ret
740
           ret
741
test_used:
741
test_used:
742
           test al, USED_BLOCK
742
           test al, USED_BLOCK
743
           jz m_exit
743
           jz m_exit
744
 
744
 
745
           and eax, 0xFFFFF000
745
           and eax, 0xFFFFF000
746
m_next:
746
m_next:
747
           add esi, eax
747
           add esi, eax
748
           jmp l_0
748
           jmp l_0
749
m_exit:
749
m_exit:
750
           xor eax, eax
750
           xor eax, eax
751
           pop edi
751
           pop edi
752
           pop esi
752
           pop esi
753
           pop ebx
753
           pop ebx
754
           ret
754
           ret
755
endp
755
endp
756
 
756
 
757
align 4
757
align 4
758
proc user_free stdcall, base:dword
758
proc user_free stdcall, base:dword
759
 
759
 
760
           push esi
760
           push esi
761
 
761
 
762
           mov esi, [base]
762
           mov esi, [base]
763
           test esi, esi
763
           test esi, esi
764
           jz .exit
764
           jz .exit
765
 
765
 
766
           push ebx
766
           push ebx
767
 
767
 
768
           xor ebx, ebx
768
           xor ebx, ebx
769
           shr esi, 12
769
           shr esi, 12
770
           mov eax, [page_tabs+(esi-1)*4]
770
           mov eax, [page_tabs+(esi-1)*4]
771
           test al, USED_BLOCK
771
           test al, USED_BLOCK
772
           jz .cantfree
772
           jz .cantfree
773
           test al, DONT_FREE_BLOCK
773
           test al, DONT_FREE_BLOCK
774
           jnz .cantfree
774
           jnz .cantfree
775
 
775
 
776
           and eax, not 4095
776
           and eax, not 4095
777
           mov ecx, eax
777
           mov ecx, eax
778
           or al, FREE_BLOCK
778
           or al, FREE_BLOCK
779
           mov [page_tabs+(esi-1)*4], eax
779
           mov [page_tabs+(esi-1)*4], eax
780
           sub ecx, 4096
780
           sub ecx, 4096
781
           mov ebx, ecx
781
           mov ebx, ecx
782
           shr ecx, 12
782
           shr ecx, 12
783
           jz .released
783
           jz .released
784
.release:
784
.release:
785
           xor eax, eax
785
           xor eax, eax
786
           xchg eax, [page_tabs+esi*4]
786
           xchg eax, [page_tabs+esi*4]
787
           test al, 1
787
           test al, 1
788
           jz @F
788
           jz @F
789
           call free_page
789
           call free_page
790
           mov eax, esi
790
           mov eax, esi
791
           shl eax, 12
791
           shl eax, 12
792
           invlpg [eax]
792
           invlpg [eax]
793
@@:
793
@@:
794
           inc esi
794
           inc esi
795
           dec ecx
795
           dec ecx
796
           jnz .release
796
           jnz .release
797
.released:
797
.released:
798
           push edi
798
           push edi
799
 
799
 
800
           mov edx, [current_slot]
800
           mov edx, [current_slot]
801
           mov esi, dword [edx+APPDATA.heap_base]
801
           mov esi, dword [edx+APPDATA.heap_base]
802
           mov edi, dword [edx+APPDATA.heap_top]
802
           mov edi, dword [edx+APPDATA.heap_top]
803
           sub ebx, [edx+APPDATA.mem_size]
803
           sub ebx, [edx+APPDATA.mem_size]
804
           neg ebx
804
           neg ebx
805
           call update_mem_size
805
           call update_mem_size
806
           call user_normalize
806
           call user_normalize
807
           pop edi
807
           pop edi
808
           pop ebx
808
           pop ebx
809
           pop esi
809
           pop esi
810
           ret
810
           ret
811
.exit:
811
.exit:
812
           xor eax, eax
812
           xor eax, eax
813
           inc eax
813
           inc eax
814
           pop esi
814
           pop esi
815
           ret
815
           ret
816
.cantfree:
816
.cantfree:
817
           xor eax, eax
817
           xor eax, eax
818
           pop ebx
818
           pop ebx
819
           pop esi
819
           pop esi
820
           ret
820
           ret
821
endp
821
endp
822
 
822
 
823
user_normalize:
823
user_normalize:
824
; in: esi=heap_base, edi=heap_top
824
; in: esi=heap_base, edi=heap_top
825
; out: eax=0 <=> OK
825
; out: eax=0 <=> OK
826
; destroys: ebx,edx,esi,edi
826
; destroys: ebx,edx,esi,edi
827
           shr esi, 12
827
           shr esi, 12
828
           shr edi, 12
828
           shr edi, 12
829
@@:
829
@@:
830
           mov eax, [page_tabs+esi*4]
830
           mov eax, [page_tabs+esi*4]
831
           test al, USED_BLOCK
831
           test al, USED_BLOCK
832
           jz .test_free
832
           jz .test_free
833
           shr eax, 12
833
           shr eax, 12
834
           add esi, eax
834
           add esi, eax
835
           jmp @B
835
           jmp @B
836
.test_free:
836
.test_free:
837
           test al, FREE_BLOCK
837
           test al, FREE_BLOCK
838
           jz .err
838
           jz .err
839
           mov edx, eax
839
           mov edx, eax
840
           shr edx, 12
840
           shr edx, 12
841
           add edx, esi
841
           add edx, esi
842
           cmp edx, edi
842
           cmp edx, edi
843
           jae .exit
843
           jae .exit
844
 
844
 
845
           mov ebx, [page_tabs+edx*4]
845
           mov ebx, [page_tabs+edx*4]
846
           test bl, USED_BLOCK
846
           test bl, USED_BLOCK
847
           jz .next_free
847
           jz .next_free
848
 
848
 
849
           shr ebx, 12
849
           shr ebx, 12
850
           add edx, ebx
850
           add edx, ebx
851
           mov esi, edx
851
           mov esi, edx
852
           jmp @B
852
           jmp @B
853
.next_free:
853
.next_free:
854
           test bl, FREE_BLOCK
854
           test bl, FREE_BLOCK
855
           jz .err
855
           jz .err
856
           and dword [page_tabs+edx*4], 0
856
           and dword [page_tabs+edx*4], 0
857
           add eax, ebx
857
           add eax, ebx
858
           and eax, not 4095
858
           and eax, not 4095
859
           or eax, FREE_BLOCK
859
           or eax, FREE_BLOCK
860
           mov [page_tabs+esi*4], eax
860
           mov [page_tabs+esi*4], eax
861
           jmp @B
861
           jmp @B
862
.exit:
862
.exit:
863
           xor eax, eax
863
           xor eax, eax
864
           inc eax
864
           inc eax
865
           ret
865
           ret
866
.err:
866
.err:
867
           xor eax, eax
867
           xor eax, eax
868
           ret
868
           ret
869
 
869
 
870
user_realloc:
870
user_realloc:
871
; in: eax = pointer, ebx = new size
871
; in: eax = pointer, ebx = new size
872
; out: eax = new pointer or NULL
872
; out: eax = new pointer or NULL
873
        test    eax, eax
873
        test    eax, eax
874
        jnz     @f
874
        jnz     @f
875
; realloc(NULL,sz) - same as malloc(sz)
875
; realloc(NULL,sz) - same as malloc(sz)
876
        push    ebx
876
        push    ebx
877
        call    user_alloc
877
        call    user_alloc
878
        ret
878
        ret
879
@@:
879
@@:
880
        push    ecx edx
880
        push    ecx edx
881
        lea     ecx, [eax - 0x1000]
881
        lea     ecx, [eax - 0x1000]
882
        shr     ecx, 12
882
        shr     ecx, 12
883
        mov     edx, [page_tabs+ecx*4]
883
        mov     edx, [page_tabs+ecx*4]
884
        test    dl, USED_BLOCK
884
        test    dl, USED_BLOCK
885
        jnz     @f
885
        jnz     @f
886
; attempt to realloc invalid pointer
886
; attempt to realloc invalid pointer
887
.ret0:
887
.ret0:
888
        pop     edx ecx
888
        pop     edx ecx
889
        xor     eax, eax
889
        xor     eax, eax
890
        ret
890
        ret
891
@@:
891
@@:
892
        test    dl, DONT_FREE_BLOCK
892
        test    dl, DONT_FREE_BLOCK
893
        jnz     .ret0
893
        jnz     .ret0
894
        add     ebx, 0x1FFF
894
        add     ebx, 0x1FFF
895
        shr     edx, 12
895
        shr     edx, 12
896
        shr     ebx, 12
896
        shr     ebx, 12
897
; edx = allocated size, ebx = new size
897
; edx = allocated size, ebx = new size
898
        add     edx, ecx
898
        add     edx, ecx
899
        add     ebx, ecx
899
        add     ebx, ecx
900
        cmp     edx, ebx
900
        cmp     edx, ebx
901
        jb      .realloc_add
901
        jb      .realloc_add
902
; release part of allocated memory
902
; release part of allocated memory
903
.loop:
903
.loop:
904
        cmp     edx, ebx
904
        cmp     edx, ebx
905
        jz      .release_done
905
        jz      .release_done
906
        dec     edx
906
        dec     edx
907
        xor     eax, eax
907
        xor     eax, eax
908
        xchg    eax, [page_tabs+edx*4]
908
        xchg    eax, [page_tabs+edx*4]
909
        test    al, 1
909
        test    al, 1
910
        jz      .loop
910
        jz      .loop
911
        call    free_page
911
        call    free_page
912
        mov     eax, edx
912
        mov     eax, edx
913
        shl     eax, 12
913
        shl     eax, 12
914
        invlpg  [eax]
914
        invlpg  [eax]
915
        jmp     .loop
915
        jmp     .loop
916
.release_done:
916
.release_done:
917
        sub     ebx, ecx
917
        sub     ebx, ecx
918
        cmp     ebx, 1
918
        cmp     ebx, 1
919
        jnz     .nofreeall
919
        jnz     .nofreeall
920
        mov     eax, [page_tabs+ecx*4]
920
        mov     eax, [page_tabs+ecx*4]
921
        and     eax, not 0xFFF
921
        and     eax, not 0xFFF
922
        mov     edx, [current_slot]
922
        mov     edx, [current_slot]
923
        mov     ebx, [APPDATA.mem_size+edx]
923
        mov     ebx, [APPDATA.mem_size+edx]
924
        sub     ebx, eax
924
        sub     ebx, eax
925
        add     ebx, 0x1000
925
        add     ebx, 0x1000
926
        or      al, FREE_BLOCK
926
        or      al, FREE_BLOCK
927
        mov     [page_tabs+ecx*4], eax
927
        mov     [page_tabs+ecx*4], eax
928
        push    esi edi
928
        push    esi edi
929
        mov     esi, [APPDATA.heap_base+edx]
929
        mov     esi, [APPDATA.heap_base+edx]
930
        mov     edi, [APPDATA.heap_top+edx]
930
        mov     edi, [APPDATA.heap_top+edx]
931
        call    update_mem_size
931
        call    update_mem_size
932
        call    user_normalize
932
        call    user_normalize
933
        pop     edi esi
933
        pop     edi esi
934
        jmp     .ret0   ; all freed
934
        jmp     .ret0   ; all freed
935
.nofreeall:
935
.nofreeall:
936
        sub     edx, ecx
936
        sub     edx, ecx
937
        shl     ebx, 12
937
        shl     ebx, 12
938
        or      ebx, USED_BLOCK
938
        or      ebx, USED_BLOCK
939
        xchg    [page_tabs+ecx*4], ebx
939
        xchg    [page_tabs+ecx*4], ebx
940
        shr     ebx, 12
940
        shr     ebx, 12
941
        sub     ebx, edx
941
        sub     ebx, edx
942
        push    ebx ecx edx
942
        push    ebx ecx edx
943
        mov     edx, [current_slot]
943
        mov     edx, [current_slot]
944
        shl     ebx, 12
944
        shl     ebx, 12
945
        sub     ebx, [APPDATA.mem_size+edx]
945
        sub     ebx, [APPDATA.mem_size+edx]
946
        neg     ebx
946
        neg     ebx
947
        call    update_mem_size
947
        call    update_mem_size
948
        pop     edx ecx ebx
948
        pop     edx ecx ebx
949
        lea     eax, [ecx+1]
949
        lea     eax, [ecx+1]
950
        shl     eax, 12
950
        shl     eax, 12
951
        push    eax
951
        push    eax
952
        add     ecx, ebx
952
        add     ecx, edx
953
        add     edx, ecx
953
        lea     edx, [ecx+ebx]
954
        shl     ebx, 12
954
        shl     ebx, 12
955
        jz      .ret
955
        jz      .ret
956
        push    esi
956
        push    esi
957
        mov     esi, [current_slot]
957
        mov     esi, [current_slot]
958
        mov     esi, [APPDATA.heap_top+esi]
958
        mov     esi, [APPDATA.heap_top+esi]
959
        shr     esi, 12
959
        shr     esi, 12
960
@@:
960
@@:
961
        cmp     edx, esi
961
        cmp     edx, esi
962
        jae     .merge_done
962
        jae     .merge_done
963
        mov     eax, [page_tabs+edx*4]
963
        mov     eax, [page_tabs+edx*4]
964
        test    al, USED_BLOCK
964
        test    al, USED_BLOCK
965
        jz      .merge_done
965
        jnz     .merge_done
966
        and     dword [page_tabs+edx*4], 0
966
        and     dword [page_tabs+edx*4], 0
967
        and     eax, not 0xFFF
-
 
968
        add     ebx, eax
967
        shr     eax, 12
969
        add     edx, eax
968
        add     edx, eax
-
 
969
        shl     eax, 12
-
 
970
        add     ebx, eax
970
        jmp     @b
971
        jmp     @b
971
.merge_done:
972
.merge_done:
972
        pop     esi
973
        pop     esi
973
        or      ebx, FREE_BLOCK
974
        or      ebx, FREE_BLOCK
974
        mov     [page_tabs+ecx*4], ebx
975
        mov     [page_tabs+ecx*4], ebx
975
.ret:
976
.ret:
976
        pop     eax edx ecx
977
        pop     eax edx ecx
977
        ret
978
        ret
978
.realloc_add:
979
.realloc_add:
979
; get some additional memory
980
; get some additional memory
980
        mov     eax, [current_slot]
981
        mov     eax, [current_slot]
981
        mov     eax, [APPDATA.heap_top+eax]
982
        mov     eax, [APPDATA.heap_top+eax]
982
        shr     eax, 12
983
        shr     eax, 12
983
        cmp     edx, eax
984
        cmp     edx, eax
984
        jae     .cant_inplace
985
        jae     .cant_inplace
985
        mov     eax, [page_tabs+edx*4]
986
        mov     eax, [page_tabs+edx*4]
986
        test    al, FREE_BLOCK
987
        test    al, FREE_BLOCK
987
        jz      .cant_inplace
988
        jz      .cant_inplace
988
        shr     eax, 12
989
        shr     eax, 12
989
        add     eax, edx
990
        add     eax, edx
990
        sub     eax, ebx
991
        sub     eax, ebx
991
        jb      .cant_inplace
992
        jb      .cant_inplace
992
        jz      @f
993
        jz      @f
993
        shl     eax, 12
994
        shl     eax, 12
994
        or      al, FREE_BLOCK
995
        or      al, FREE_BLOCK
995
        mov     [page_tabs+ebx*4], eax
996
        mov     [page_tabs+ebx*4], eax
996
@@:
997
@@:
997
        mov     eax, ebx
998
        mov     eax, ebx
998
        sub     eax, ecx
999
        sub     eax, ecx
999
        shl     eax, 12
1000
        shl     eax, 12
1000
        or      al, USED_BLOCK
1001
        or      al, USED_BLOCK
1001
        mov     [page_tabs+ecx*4], eax
1002
        mov     [page_tabs+ecx*4], eax
1002
        lea     eax, [ecx+1]
1003
        lea     eax, [ecx+1]
1003
        shl     eax, 12
1004
        shl     eax, 12
1004
        push    eax
1005
        push    eax
1005
        push    edi
1006
        push    edi
1006
        lea     edi, [page_tabs+edx*4]
1007
        lea     edi, [page_tabs+edx*4]
1007
        mov     eax, 2
1008
        mov     eax, 2
1008
        sub     ebx, edx
1009
        sub     ebx, edx
1009
        mov     ecx, ebx
1010
        mov     ecx, ebx
1010
        cld
1011
        cld
1011
        rep     stosd
1012
        rep     stosd
1012
        pop     edi
1013
        pop     edi
1013
        mov     edx, [current_slot]
1014
        mov     edx, [current_slot]
1014
        shl     ebx, 12
1015
        shl     ebx, 12
1015
        add     ebx, [APPDATA.mem_size+edx]
1016
        add     ebx, [APPDATA.mem_size+edx]
1016
        call    update_mem_size
1017
        call    update_mem_size
1017
        pop     eax edx ecx
1018
        pop     eax edx ecx
1018
        ret
1019
        ret
1019
.cant_inplace:
1020
.cant_inplace:
1020
        push    esi edi
1021
        push    esi edi
1021
        mov     eax, [current_slot]
1022
        mov     eax, [current_slot]
1022
        mov     esi, [APPDATA.heap_base+eax]
1023
        mov     esi, [APPDATA.heap_base+eax]
1023
        mov     edi, [APPDATA.heap_top+eax]
1024
        mov     edi, [APPDATA.heap_top+eax]
1024
        shr     esi, 12
1025
        shr     esi, 12
1025
        shr     edi, 12
1026
        shr     edi, 12
1026
        sub     ebx, ecx
1027
        sub     ebx, ecx
1027
.find_place:
1028
.find_place:
1028
        cmp     esi, edi
1029
        cmp     esi, edi
1029
        jae     .place_not_found
1030
        jae     .place_not_found
1030
        mov     eax, [page_tabs+esi*4]
1031
        mov     eax, [page_tabs+esi*4]
1031
        test    al, FREE_BLOCK
1032
        test    al, FREE_BLOCK
1032
        jz      .next_place
1033
        jz      .next_place
1033
        shr     eax, 12
1034
        shr     eax, 12
1034
        cmp     eax, ebx
1035
        cmp     eax, ebx
1035
        jae     .place_found
1036
        jae     .place_found
1036
        add     esi, eax
1037
        add     esi, eax
1037
        jmp     .find_place
1038
        jmp     .find_place
1038
.next_place:
1039
.next_place:
1039
        shr     eax, 12
1040
        shr     eax, 12
1040
        add     esi, eax
1041
        add     esi, eax
1041
        jmp     .find_place
1042
        jmp     .find_place
1042
.place_not_found:
1043
.place_not_found:
1043
        pop     edi esi
1044
        pop     edi esi
1044
        jmp     .ret0
1045
        jmp     .ret0
1045
.place_found:
1046
.place_found:
1046
        sub     eax, ebx
1047
        sub     eax, ebx
1047
        jz      @f
1048
        jz      @f
1048
        push    esi
1049
        push    esi
1049
        add     esi, ebx
1050
        add     esi, ebx
1050
        shl     eax, 12
1051
        shl     eax, 12
1051
        or      al, FREE_BLOCK
1052
        or      al, FREE_BLOCK
1052
        mov     [page_tabs+esi*4], eax
1053
        mov     [page_tabs+esi*4], eax
1053
        pop     esi
1054
        pop     esi
1054
@@:
1055
@@:
1055
        mov     eax, ebx
1056
        mov     eax, ebx
1056
        shl     eax, 12
1057
        shl     eax, 12
1057
        or      al, USED_BLOCK
1058
        or      al, USED_BLOCK
1058
        mov     [page_tabs+esi*4], eax
1059
        mov     [page_tabs+esi*4], eax
1059
        inc     esi
1060
        inc     esi
1060
        mov     eax, esi
1061
        mov     eax, esi
1061
        shl     eax, 12
1062
        shl     eax, 12
1062
        push    eax
1063
        push    eax
1063
        mov     eax, [page_tabs+ecx*4]
1064
        mov     eax, [page_tabs+ecx*4]
1064
        and     eax, not 0xFFF
1065
        and     eax, not 0xFFF
1065
        or      al, FREE_BLOCK
1066
        or      al, FREE_BLOCK
1066
        sub     edx, ecx
1067
        sub     edx, ecx
1067
        mov     [page_tabs+ecx*4], eax
1068
        mov     [page_tabs+ecx*4], eax
1068
        inc     ecx
1069
        inc     ecx
1069
        dec     ebx
1070
        dec     ebx
1070
        dec     edx
1071
        dec     edx
1071
        jz      .no
1072
        jz      .no
1072
@@:
1073
@@:
1073
        xor     eax, eax
1074
        xor     eax, eax
1074
        xchg    eax, [page_tabs+ecx*4]
1075
        xchg    eax, [page_tabs+ecx*4]
1075
        mov     [page_tabs+esi*4], eax
1076
        mov     [page_tabs+esi*4], eax
1076
	mov     eax, ecx
1077
	mov     eax, ecx
1077
	shl     eax, 12
1078
	shl     eax, 12
1078
	invlpg  [eax]
1079
	invlpg  [eax]
1079
        inc     esi
1080
        inc     esi
1080
        inc     ecx
1081
        inc     ecx
1081
        dec     ebx
1082
        dec     ebx
1082
        dec     edx
1083
        dec     edx
1083
        jnz     @b
1084
        jnz     @b
1084
.no:
1085
.no:
1085
        push    ebx
1086
        push    ebx
1086
        mov     edx, [current_slot]
1087
        mov     edx, [current_slot]
1087
        shl     ebx, 12
1088
        shl     ebx, 12
1088
        add     ebx, [APPDATA.mem_size+edx]
1089
        add     ebx, [APPDATA.mem_size+edx]
1089
        call    update_mem_size
1090
        call    update_mem_size
1090
        pop     ebx
1091
        pop     ebx
1091
@@:
1092
@@:
1092
        mov     dword [page_tabs+esi*4], 2
1093
        mov     dword [page_tabs+esi*4], 2
1093
        inc     esi
1094
        inc     esi
1094
        dec     ebx
1095
        dec     ebx
1095
        jnz     @b
1096
        jnz     @b
1096
        pop     eax edi esi edx ecx
1097
        pop     eax edi esi edx ecx
1097
        ret
1098
        ret
1098
 
1099
 
1099
if 0
1100
if 0
1100
align 4
1101
align 4
1101
proc alloc_dll
1102
proc alloc_dll
1102
           pushf
1103
           pushf
1103
           cli
1104
           cli
1104
           bsf eax, [dll_map]
1105
           bsf eax, [dll_map]
1105
           jnz .find
1106
           jnz .find
1106
           popf
1107
           popf
1107
           xor eax, eax
1108
           xor eax, eax
1108
           ret
1109
           ret
1109
.find:
1110
.find:
1110
           btr [dll_map], eax
1111
           btr [dll_map], eax
1111
           popf
1112
           popf
1112
           shl eax, 5
1113
           shl eax, 5
1113
           add eax, dll_tab
1114
           add eax, dll_tab
1114
           ret
1115
           ret
1115
endp
1116
endp
1116
 
1117
 
1117
align 4
1118
align 4
1118
proc alloc_service
1119
proc alloc_service
1119
           pushf
1120
           pushf
1120
           cli
1121
           cli
1121
           bsf eax, [srv_map]
1122
           bsf eax, [srv_map]
1122
           jnz .find
1123
           jnz .find
1123
           popf
1124
           popf
1124
           xor eax, eax
1125
           xor eax, eax
1125
           ret
1126
           ret
1126
.find:
1127
.find:
1127
           btr [srv_map], eax
1128
           btr [srv_map], eax
1128
           popf
1129
           popf
1129
           shl eax,0x02
1130
           shl eax,0x02
1130
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
1131
           lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
1131
           ret
1132
           ret
1132
endp
1133
endp
1133
 
1134
 
1134
end if
1135
end if