Subversion Repositories Kolibri OS

Rev

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

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