Subversion Repositories Kolibri OS

Rev

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

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