Subversion Repositories Kolibri OS

Rev

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