Subversion Repositories Kolibri OS

Rev

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

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