Subversion Repositories Kolibri OS

Rev

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

Rev 819 Rev 821
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 819 $
8
$Revision: 821 $
9
 
9
 
10
 
10
 
11
align 4
11
align 4
12
proc alloc_page
12
proc alloc_page
13
 
13
 
14
           pushfd
14
           pushfd
15
           cli
15
           cli
16
           push ebx
16
           push ebx
17
           mov ebx, [page_start]
17
           mov ebx, [page_start]
18
           mov ecx, [page_end]
18
           mov ecx, [page_end]
19
.l1:
19
.l1:
20
           bsf eax,[ebx];
20
           bsf eax,[ebx];
21
           jnz .found
21
           jnz .found
22
           add ebx,4
22
           add ebx,4
23
           cmp ebx, ecx
23
           cmp ebx, ecx
24
           jb .l1
24
           jb .l1
25
           pop ebx
25
           pop ebx
26
           popfd
26
           popfd
27
           xor eax,eax
27
           xor eax,eax
28
           ret
28
           ret
29
.found:
29
.found:
30
           btr [ebx], eax
30
           btr [ebx], eax
31
           mov [page_start],ebx
31
           mov [page_start],ebx
32
           sub ebx, sys_pgmap
32
           sub ebx, sys_pgmap
33
           lea eax, [eax+ebx*8]
33
           lea eax, [eax+ebx*8]
34
           shl eax, 12
34
           shl eax, 12
35
           dec [pg_data.pages_free]
35
           dec [pg_data.pages_free]
36
           pop ebx
36
           pop ebx
37
           popfd
37
           popfd
38
           ret
38
           ret
39
endp
39
endp
40
 
40
 
41
align 4
41
align 4
42
proc alloc_pages stdcall, count:dword
42
proc alloc_pages stdcall, count:dword
43
           pushfd
43
           pushfd
44
           push ebx
44
           push ebx
45
           push edi
45
           push edi
46
           cli
46
           cli
47
           mov eax, [count]
47
           mov eax, [count]
48
           add eax, 7
48
           add eax, 7
49
           shr eax, 3
49
           shr eax, 3
50
           mov [count], eax
50
           mov [count], eax
51
           cmp eax, [pg_data.pages_free]
51
           cmp eax, [pg_data.pages_free]
52
           ja .fail
52
           ja .fail
53
 
53
 
54
           mov ecx, [page_start]
54
           mov ecx, [page_start]
55
           mov ebx, [page_end]
55
           mov ebx, [page_end]
56
.find:
56
.find:
57
           mov edx, [count]
57
           mov edx, [count]
58
           mov edi, ecx
58
           mov edi, ecx
59
.match:
59
.match:
60
           cmp byte [ecx], 0xFF
60
           cmp byte [ecx], 0xFF
61
           jne .next
61
           jne .next
62
           dec edx
62
           dec edx
63
           jz .ok
63
           jz .ok
64
           inc ecx
64
           inc ecx
65
           cmp ecx,ebx
65
           cmp ecx,ebx
66
           jb .match
66
           jb .match
67
.fail:
67
.fail:
68
           xor eax, eax
68
           xor eax, eax
69
           pop edi
69
           pop edi
70
           pop ebx
70
           pop ebx
71
           popfd
71
           popfd
72
           ret
72
           ret
73
.next:
73
.next:
74
           inc ecx
74
           inc ecx
75
           cmp ecx, ebx
75
           cmp ecx, ebx
76
           jb .find
76
           jb .find
77
           pop edi
77
           pop edi
78
           pop ebx
78
           pop ebx
79
           popfd
79
           popfd
80
           xor eax, eax
80
           xor eax, eax
81
           ret
81
           ret
82
.ok:
82
.ok:
83
           sub ecx, edi
83
           sub ecx, edi
84
           inc ecx
84
           inc ecx
85
           push esi
85
           push esi
86
           mov esi, edi
86
           mov esi, edi
87
           xor eax, eax
87
           xor eax, eax
88
           rep stosb
88
           rep stosb
89
           sub esi, sys_pgmap
89
           sub esi, sys_pgmap
90
           shl esi, 3+12
90
           shl esi, 3+12
91
           mov eax, esi
91
           mov eax, esi
92
           mov ebx, [count]
92
           mov ebx, [count]
93
           shl ebx, 3
93
           shl ebx, 3
94
           sub [pg_data.pages_free], ebx
94
           sub [pg_data.pages_free], ebx
95
           pop esi
95
           pop esi
96
           pop edi
96
           pop edi
97
           pop ebx
97
           pop ebx
98
           popfd
98
           popfd
99
           ret
99
           ret
100
endp
100
endp
101
 
101
 
102
align 4
102
align 4
103
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
103
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
104
           push ebx
104
           push ebx
105
           mov eax, [phis_addr]
105
           mov eax, [phis_addr]
106
           and eax, not 0xFFF
106
           and eax, not 0xFFF
107
           or eax, [flags]
107
           or eax, [flags]
108
           mov ebx, [lin_addr]
108
           mov ebx, [lin_addr]
109
           shr ebx, 12
109
           shr ebx, 12
110
           mov [page_tabs+ebx*4], eax
110
           mov [page_tabs+ebx*4], eax
111
           mov eax, [lin_addr]
111
           mov eax, [lin_addr]
112
           invlpg [eax]
112
           invlpg [eax]
113
           pop ebx
113
           pop ebx
114
           ret
114
           ret
115
endp
115
endp
116
 
116
 
117
align 4
117
align 4
118
map_space:    ;not implemented
118
map_space:    ;not implemented
119
 
119
 
120
 
120
 
121
           ret
121
           ret
122
 
122
 
123
 
123
 
124
align 4
124
align 4
125
proc free_page
125
proc free_page
126
;arg:  eax  page address
126
;arg:  eax  page address
127
           pushfd
127
           pushfd
128
           cli
128
           cli
129
           shr eax, 12                        ;page index
129
           shr eax, 12                        ;page index
130
           bts dword [sys_pgmap], eax         ;that's all!
130
           bts dword [sys_pgmap], eax         ;that's all!
131
           cmc
131
           cmc
132
           adc [pg_data.pages_free], 0
132
           adc [pg_data.pages_free], 0
133
           shr eax, 3
133
           shr eax, 3
134
           and eax, not 3                     ;dword offset from page_map
134
           and eax, not 3                     ;dword offset from page_map
135
           add eax, sys_pgmap
135
           add eax, sys_pgmap
136
           cmp [page_start], eax
136
           cmp [page_start], eax
137
           ja @f
137
           ja @f
138
           popfd
138
           popfd
139
           ret
139
           ret
140
@@:
140
@@:
141
           mov [page_start], eax
141
           mov [page_start], eax
142
           popfd
142
           popfd
143
           ret
143
           ret
144
endp
144
endp
145
 
145
 
146
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
146
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
147
 
147
 
148
           push ebx
148
           push ebx
149
           push edi
149
           push edi
150
           mov eax, [size]
150
           mov eax, [size]
151
           add eax, 4095
151
           add eax, 4095
152
           and eax, -4096
152
           and eax, -4096
153
           mov [size], eax
153
           mov [size], eax
154
           stdcall alloc_kernel_space, eax
154
           stdcall alloc_kernel_space, eax
155
           test eax, eax
155
           test eax, eax
156
           jz .fail
156
           jz .fail
157
           push eax
157
           push eax
158
 
158
 
159
           mov edi, 0x1000
159
           mov edi, 0x1000
160
           mov ebx, eax
160
           mov ebx, eax
161
           mov ecx,[size]
161
           mov ecx,[size]
162
           mov edx, [base]
162
           mov edx, [base]
163
           shr eax, 12
163
           shr eax, 12
164
           shr ecx, 12
164
           shr ecx, 12
165
           and edx, -4096
165
           and edx, -4096
166
           or edx, [flags]
166
           or edx, [flags]
167
@@:
167
@@:
168
           mov [page_tabs+eax*4], edx
168
           mov [page_tabs+eax*4], edx
169
          ; push eax
169
          ; push eax
170
          ; invlpg [ebx]
170
          ; invlpg [ebx]
171
          ; pop eax
171
          ; pop eax
172
           inc eax
172
           inc eax
173
           add ebx, edi
173
           add ebx, edi
174
           add edx, edi
174
           add edx, edi
175
           loop @B
175
           loop @B
176
 
176
 
177
           pop eax
177
           pop eax
178
           mov edx, [base]
178
           mov edx, [base]
179
           and edx, 4095
179
           and edx, 4095
180
           add eax, edx
180
           add eax, edx
181
.fail:
181
.fail:
182
           pop edi
182
           pop edi
183
           pop ebx
183
           pop ebx
184
           ret
184
           ret
185
endp
185
endp
186
 
186
 
187
; param
187
; param
188
;  eax= page base + page flags
188
;  eax= page base + page flags
189
;  ebx= linear address
189
;  ebx= linear address
190
;  ecx= count
190
;  ecx= count
191
 
191
 
192
align 4
192
align 4
193
commit_pages:
193
commit_pages:
194
           push edi
194
           push edi
195
           test ecx, ecx
195
           test ecx, ecx
196
           jz .fail
196
           jz .fail
197
 
197
 
198
           mov edi, ebx
198
           mov edi, ebx
199
           mov ebx, pg_data.pg_mutex
199
           mov ebx, pg_data.pg_mutex
200
           call wait_mutex      ;ebx
200
           call wait_mutex      ;ebx
201
 
201
 
202
           mov edx, 0x1000
202
           mov edx, 0x1000
203
           mov ebx, edi
203
           mov ebx, edi
204
           shr ebx, 12
204
           shr ebx, 12
205
@@:
205
@@:
206
           mov [page_tabs+ebx*4], eax
206
           mov [page_tabs+ebx*4], eax
207
          ; push eax
207
          ; push eax
208
          ; invlpg [edi]
208
          ; invlpg [edi]
209
          ; pop eax
209
          ; pop eax
210
           add edi, edx
210
           add edi, edx
211
           add eax, edx
211
           add eax, edx
212
           inc ebx
212
           inc ebx
213
           dec ecx
213
           dec ecx
214
           jnz @B
214
           jnz @B
215
           mov [pg_data.pg_mutex],ecx
215
           mov [pg_data.pg_mutex],ecx
216
.fail:
216
.fail:
217
           pop edi
217
           pop edi
218
           ret
218
           ret
219
 
219
 
220
 
220
 
221
; param
221
; param
222
;  eax= base
222
;  eax= base
223
;  ecx= count
223
;  ecx= count
224
 
224
 
225
align 4
225
align 4
226
release_pages:
226
release_pages:
227
 
227
 
228
           pushad
228
           pushad
229
           mov ebx, pg_data.pg_mutex
229
           mov ebx, pg_data.pg_mutex
230
           call wait_mutex      ;ebx
230
           call wait_mutex      ;ebx
231
 
231
 
232
           mov esi, eax
232
           mov esi, eax
233
           mov edi, eax
233
           mov edi, eax
234
 
234
 
235
           shr esi, 10
235
           shr esi, 10
236
           add esi, page_tabs
236
           add esi, page_tabs
237
 
237
 
238
           mov ebp, [pg_data.pages_free]
238
           mov ebp, [pg_data.pages_free]
239
           mov ebx, [page_start]
239
           mov ebx, [page_start]
240
           mov edx, sys_pgmap
240
           mov edx, sys_pgmap
241
@@:
241
@@:
242
           xor eax, eax
242
           xor eax, eax
243
           xchg eax, [esi]
243
           xchg eax, [esi]
244
           invlpg [edi]
244
           invlpg [edi]
245
 
245
 
246
           test eax, 1
246
           test eax, 1
247
           jz .next
247
           jz .next
248
 
248
 
249
           shr eax, 12
249
           shr eax, 12
250
           bts [edx], eax
250
           bts [edx], eax
251
           cmc
251
           cmc
252
           adc ebp, 0
252
           adc ebp, 0
253
           shr eax, 3
253
           shr eax, 3
254
           and eax, -4
254
           and eax, -4
255
           add eax, edx
255
           add eax, edx
256
           cmp eax, ebx
256
           cmp eax, ebx
257
           jae .next
257
           jae .next
258
 
258
 
259
           mov ebx, eax
259
           mov ebx, eax
260
.next:
260
.next:
261
           add edi, 0x1000
261
           add edi, 0x1000
262
           add esi, 4
262
           add esi, 4
263
           dec ecx
263
           dec ecx
264
           jnz @B
264
           jnz @B
265
           mov [pg_data.pages_free], ebp
265
           mov [pg_data.pages_free], ebp
266
           and [pg_data.pg_mutex],0
266
           and [pg_data.pg_mutex],0
267
           popad
267
           popad
268
           ret
268
           ret
269
 
269
 
270
; param
270
; param
271
;  eax= base
271
;  eax= base
272
;  ecx= count
272
;  ecx= count
273
 
273
 
274
align 4
274
align 4
275
unmap_pages:
275
unmap_pages:
276
 
276
 
277
           push edi
277
           push edi
278
 
278
 
279
           mov edi, eax
279
           mov edi, eax
280
           mov edx, eax
280
           mov edx, eax
281
 
281
 
282
           shr edi, 10
282
           shr edi, 10
283
           add edi, page_tabs
283
           add edi, page_tabs
284
 
284
 
285
           xor eax, eax
285
           xor eax, eax
286
@@:
286
@@:
287
           stosd
287
           stosd
288
           invlpg [edx]
288
           invlpg [edx]
289
           add edx, 0x1000
289
           add edx, 0x1000
290
           loop @b
290
           loop @b
291
 
291
 
292
           pop edi
292
           pop edi
293
           ret
293
           ret
294
 
294
 
295
 
295
 
296
align 4
296
align 4
297
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
297
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
298
           push ebx
298
           push ebx
299
           mov ebx, [lin_addr]
299
           mov ebx, [lin_addr]
300
           shr ebx, 22
300
           shr ebx, 22
301
           mov eax, [phis_addr]
301
           mov eax, [phis_addr]
302
           and eax, not 0xFFF
302
           and eax, not 0xFFF
303
           or eax, PG_UW          ;+PG_NOCACHE
303
           or eax, PG_UW          ;+PG_NOCACHE
304
           mov dword [master_tab+ebx*4], eax
304
           mov dword [master_tab+ebx*4], eax
305
           mov eax, [lin_addr]
305
           mov eax, [lin_addr]
306
           shr eax, 10
306
           shr eax, 10
307
           add eax, page_tabs
307
           add eax, page_tabs
308
           invlpg [eax]
308
           invlpg [eax]
309
           pop ebx
309
           pop ebx
310
           ret
310
           ret
311
endp
311
endp
312
 
312
 
313
align 4
313
align 4
314
proc init_LFB
314
proc init_LFB
315
           locals
315
           locals
316
             pg_count dd ?
316
             pg_count dd ?
317
           endl
317
           endl
318
 
318
 
319
           cmp dword [LFBAddress], -1
319
           cmp dword [LFBAddress], -1
320
           jne @f
320
           jne @f
321
           mov [BOOT_VAR+0x901c],byte 2
321
           mov [BOOT_VAR+0x901c],byte 2
322
           stdcall kernel_alloc, 0x280000
322
           stdcall kernel_alloc, 0x280000
323
           mov [LFBAddress], eax
323
           mov [LFBAddress], eax
324
           ret
324
           ret
325
@@:
325
@@:
326
           test [SCR_MODE],word 0100000000000000b
326
           test [SCR_MODE],word 0100000000000000b
327
           jnz @f
327
           jnz @f
328
           mov [BOOT_VAR+0x901c],byte 2
328
           mov [BOOT_VAR+0x901c],byte 2
329
           ret
329
           ret
330
@@:
330
@@:
331
           call init_mtrr
331
           call init_mtrr
332
 
332
 
333
           mov edx, LFB_BASE
333
           mov edx, LFB_BASE
334
           mov esi, [LFBAddress]
334
           mov esi, [LFBAddress]
335
           mov edi, 0x00800000
335
           mov edi, 0x00800000
336
           mov dword [exp_lfb+4], edx
336
           mov dword [exp_lfb+4], edx
337
 
337
 
338
           shr edi, 12
338
           shr edi, 12
339
           mov [pg_count], edi
339
           mov [pg_count], edi
340
           shr edi, 10
340
           shr edi, 10
341
 
341
 
342
           bt [cpu_caps], CAPS_PSE
342
           bt [cpu_caps], CAPS_PSE
343
           jnc .map_page_tables
343
           jnc .map_page_tables
344
           or esi, PG_LARGE+PG_UW
344
           or esi, PG_LARGE+PG_UW
345
           mov edx, sys_pgdir+(LFB_BASE shr 20)
345
           mov edx, sys_pgdir+(LFB_BASE shr 20)
346
@@:
346
@@:
347
           mov [edx], esi
347
           mov [edx], esi
348
           add edx, 4
348
           add edx, 4
349
           add esi, 0x00400000
349
           add esi, 0x00400000
350
           dec edi
350
           dec edi
351
           jnz @B
351
           jnz @B
352
 
352
 
353
           bt [cpu_caps], CAPS_PGE
353
           bt [cpu_caps], CAPS_PGE
354
           jnc @F
354
           jnc @F
355
           or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
355
           or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
356
@@:
356
@@:
357
           mov dword [LFBAddress], LFB_BASE
357
           mov dword [LFBAddress], LFB_BASE
358
           mov eax, cr3       ;flush TLB
358
           mov eax, cr3       ;flush TLB
359
           mov cr3, eax
359
           mov cr3, eax
360
           ret
360
           ret
361
 
361
 
362
.map_page_tables:
362
.map_page_tables:
363
 
363
 
364
@@:
364
@@:
365
           call alloc_page
365
           call alloc_page
366
           stdcall map_page_table, edx, eax
366
           stdcall map_page_table, edx, eax
367
           add edx, 0x00400000
367
           add edx, 0x00400000
368
           dec edi
368
           dec edi
369
           jnz @B
369
           jnz @B
370
 
370
 
371
           mov eax, [LFBAddress]
371
           mov eax, [LFBAddress]
372
           mov edi, page_tabs + (LFB_BASE shr 10)
372
           mov edi, page_tabs + (LFB_BASE shr 10)
373
           or eax, PG_UW
373
           or eax, PG_UW
374
           mov ecx, [pg_count]
374
           mov ecx, [pg_count]
375
           cld
375
           cld
376
@@:
376
@@:
377
           stosd
377
           stosd
378
           add eax, 0x1000
378
           add eax, 0x1000
379
           dec ecx
379
           dec ecx
380
           jnz @B
380
           jnz @B
381
 
381
 
382
           mov dword [LFBAddress], LFB_BASE
382
           mov dword [LFBAddress], LFB_BASE
383
           mov eax, cr3       ;flush TLB
383
           mov eax, cr3       ;flush TLB
384
           mov cr3, eax
384
           mov cr3, eax
385
 
385
 
386
           ret
386
           ret
387
endp
387
endp
388
 
388
 
389
align 4
389
align 4
390
proc new_mem_resize stdcall, new_size:dword
390
proc new_mem_resize stdcall, new_size:dword
391
 
391
 
392
           mov ebx, pg_data.pg_mutex
392
           mov ebx, pg_data.pg_mutex
393
           call wait_mutex    ;ebx
393
           call wait_mutex    ;ebx
394
 
394
 
395
           mov edi, [new_size]
395
           mov edi, [new_size]
396
           add edi,4095
396
           add edi,4095
397
           and edi,not 4095
397
           and edi,not 4095
398
           mov [new_size], edi
398
           mov [new_size], edi
399
 
399
 
400
           mov edx,[current_slot]
400
           mov edx,[current_slot]
401
           cmp [edx+APPDATA.heap_base],0
401
           cmp [edx+APPDATA.heap_base],0
402
           jne .exit
402
           jne .exit
403
 
403
 
404
           mov esi, [edx+APPDATA.mem_size]
404
           mov esi, [edx+APPDATA.mem_size]
405
           add esi, 4095
405
           add esi, 4095
406
           and esi, not 4095
406
           and esi, not 4095
407
 
407
 
408
           cmp edi, esi
408
           cmp edi, esi
409
           jae .expand
409
           jae .expand
410
 
410
 
411
           shr edi, 12
411
           shr edi, 12
412
           shr esi, 12
412
           shr esi, 12
413
@@:
413
@@:
414
           mov eax, [app_page_tabs+edi*4]
414
           mov eax, [app_page_tabs+edi*4]
415
           test eax, 1
415
           test eax, 1
416
           jz .next
416
           jz .next
417
           mov dword [app_page_tabs+edi*4], 2
417
           mov dword [app_page_tabs+edi*4], 2
418
           mov ebx, edi
418
           mov ebx, edi
419
           shl ebx, 12
419
           shl ebx, 12
420
           invlpg [ebx]
420
           invlpg [ebx]
421
           call free_page
421
           call free_page
422
 
422
 
423
.next:     add edi, 1
423
.next:     add edi, 1
424
           cmp edi, esi
424
           cmp edi, esi
425
           jb @B
425
           jb @B
426
 
426
 
427
.update_size:
427
.update_size:
428
           mov     ebx, [new_size]
428
           mov     ebx, [new_size]
429
           call    update_mem_size
429
           call    update_mem_size
430
 
430
 
431
           xor eax, eax
431
           xor eax, eax
432
           dec [pg_data.pg_mutex]
432
           dec [pg_data.pg_mutex]
433
           ret
433
           ret
434
.expand:
434
.expand:
435
 
435
 
436
           push esi
436
           push esi
437
           push edi
437
           push edi
438
 
438
 
439
           add edi, 0x3FFFFF
439
           add edi, 0x3FFFFF
440
           and edi, not(0x3FFFFF)
440
           and edi, not(0x3FFFFF)
441
           add esi, 0x3FFFFF
441
           add esi, 0x3FFFFF
442
           and esi, not(0x3FFFFF)
442
           and esi, not(0x3FFFFF)
443
 
443
 
444
           cmp esi, edi
444
           cmp esi, edi
445
           jae .grow
445
           jae .grow
446
 
446
 
447
           xchg esi, edi
447
           xchg esi, edi
448
 
448
 
449
@@:
449
@@:
450
           call alloc_page
450
           call alloc_page
451
           test eax, eax
451
           test eax, eax
452
           jz .exit
452
           jz .exit
453
 
453
 
454
           stdcall map_page_table, edi, eax
454
           stdcall map_page_table, edi, eax
455
 
455
 
456
           push edi
456
           push edi
457
           shr edi, 10
457
           shr edi, 10
458
           add edi, page_tabs
458
           add edi, page_tabs
459
           mov ecx, 1024
459
           mov ecx, 1024
460
           xor eax, eax
460
           xor eax, eax
461
           cld
461
           cld
462
           rep stosd
462
           rep stosd
463
           pop edi
463
           pop edi
464
 
464
 
465
           add edi, 0x00400000
465
           add edi, 0x00400000
466
           cmp edi, esi
466
           cmp edi, esi
467
           jb @B
467
           jb @B
468
.grow:
468
.grow:
469
           pop edi
469
           pop edi
470
           pop esi
470
           pop esi
471
@@:
471
@@:
472
           call alloc_page
472
           call alloc_page
473
           test eax, eax
473
           test eax, eax
474
           jz .exit
474
           jz .exit
475
           stdcall map_page,esi,eax,dword PG_UW
475
           stdcall map_page,esi,eax,dword PG_UW
476
 
476
 
477
           push edi
477
           push edi
478
           mov edi, esi
478
           mov edi, esi
479
           xor eax, eax
479
           xor eax, eax
480
           mov ecx, 1024
480
           mov ecx, 1024
481
           cld
481
           cld
482
           rep stosd
482
           rep stosd
483
           pop edi
483
           pop edi
484
 
484
 
485
           add esi, 0x1000
485
           add esi, 0x1000
486
           cmp esi, edi
486
           cmp esi, edi
487
           jb  @B
487
           jb  @B
488
 
488
 
489
           jmp .update_size
489
           jmp .update_size
490
.exit:
490
.exit:
491
           xor eax, eax
491
           xor eax, eax
492
           inc eax
492
           inc eax
493
           dec [pg_data.pg_mutex]
493
           dec [pg_data.pg_mutex]
494
           ret
494
           ret
495
endp
495
endp
496
 
496
 
497
update_mem_size:
497
update_mem_size:
498
; in: edx = slot base
498
; in: edx = slot base
499
;     ebx = new memory size
499
;     ebx = new memory size
500
; destroys eax,ecx,edx
500
; destroys eax,ecx,edx
501
 
501
 
502
           mov    [APPDATA.mem_size+edx],ebx
502
           mov    [APPDATA.mem_size+edx],ebx
503
;search threads and update
503
;search threads and update
504
;application memory size infomation
504
;application memory size infomation
505
           mov    ecx,[APPDATA.dir_table+edx]
505
           mov    ecx,[APPDATA.dir_table+edx]
506
           mov    eax,2
506
           mov    eax,2
507
 
507
 
508
.search_threads:
508
.search_threads:
509
;eax = current slot
509
;eax = current slot
510
;ebx = new memory size
510
;ebx = new memory size
511
;ecx = page directory
511
;ecx = page directory
512
           cmp    eax,[TASK_COUNT]
512
           cmp    eax,[TASK_COUNT]
513
           jg     .search_threads_end
513
           jg     .search_threads_end
514
           mov    edx,eax
514
           mov    edx,eax
515
           shl    edx,5
515
           shl    edx,5
516
           cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
516
           cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
517
           jz     .search_threads_next
517
           jz     .search_threads_next
518
           shl    edx,3
518
           shl    edx,3
519
           cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
519
           cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
520
           jnz    .search_threads_next
520
           jnz    .search_threads_next
521
           mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
521
           mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
522
.search_threads_next:
522
.search_threads_next:
523
           inc    eax
523
           inc    eax
524
           jmp    .search_threads
524
           jmp    .search_threads
525
.search_threads_end:
525
.search_threads_end:
526
           ret
526
           ret
527
 
527
 
528
; param
528
; param
529
;  eax= linear address
529
;  eax= linear address
530
;
530
;
531
; retval
531
; retval
532
;  eax= phisical page address
532
;  eax= phisical page address
533
 
533
 
534
align 4
534
align 4
535
get_pg_addr:
535
get_pg_addr:
536
           shr eax, 12
536
           shr eax, 12
537
           mov eax, [page_tabs+eax*4]
537
           mov eax, [page_tabs+eax*4]
538
           and eax, 0xFFFFF000
538
           and eax, 0xFFFFF000
539
           ret
539
           ret
540
 
540
 
541
 
541
 
542
align 4
542
align 4
543
proc page_fault_handler
543
proc page_fault_handler
544
 
544
 
545
        test    byte [esp+12+2], 2
545
        test    byte [esp+12+2], 2
546
        jnz     v86_page_fault
546
        jnz     v86_page_fault
547
 
547
 
548
        .err_code equ ebp+32
548
        .err_code equ ebp+32
549
        .err_addr equ ebp-4
549
        .err_addr equ ebp-4
550
 
550
 
551
           pushad
551
           pushad
552
           mov ebp, esp
552
           mov ebp, esp
553
           mov eax, cr2
553
           mov eax, cr2
554
           push eax
554
           push eax
555
 
555
 
556
           mov ax, app_data
556
           mov ax, app_data
557
           mov ds, ax
557
           mov ds, ax
558
           mov es, ax
558
           mov es, ax
559
 
559
 
560
           inc [pg_data.pages_faults]
560
           inc [pg_data.pages_faults]
561
 
561
 
562
;     push eax
562
;     push eax
563
;     push edx
563
;     push edx
564
;     mov edx, 0x400   ;bochs
564
;     mov edx, 0x400   ;bochs
565
;     mov al,0xff      ;bochs
565
;     mov al,0xff      ;bochs
566
;     out dx, al       ;bochs
566
;     out dx, al       ;bochs
567
;     pop edx
567
;     pop edx
568
;     pop eax
568
;     pop eax
569
 
569
 
570
           mov ebx, [.err_addr]
570
           mov ebx, [.err_addr]
571
           mov eax, [.err_code]
571
           mov eax, [.err_code]
572
 
572
 
573
           cmp ebx, OS_BASE
573
           cmp ebx, OS_BASE
574
           jb .user_space      ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
574
           jb .user_space      ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
575
 
575
 
576
           cmp ebx, page_tabs
576
           cmp ebx, page_tabs
577
           jb .kernel_space    ;ñòðàíèöà â ïàìÿòè ÿäðà
577
           jb .kernel_space    ;ñòðàíèöà â ïàìÿòè ÿäðà
578
 
578
 
579
           cmp ebx, kernel_tabs
579
           cmp ebx, kernel_tabs
580
           jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
580
           jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
581
                               ;ïðîñòî ñîçäàäèì îäíó
581
                               ;ïðîñòî ñîçäàäèì îäíó
582
 
582
 
583
           cmp ebx, LFB_BASE
583
           cmp ebx, LFB_BASE
584
           jb .core_tabs       ;òàáëèöû ñòðàíèö ÿäðà
584
           jb .core_tabs       ;òàáëèöû ñòðàíèö ÿäðà
585
                               ;Îøèáêà
585
                               ;Îøèáêà
586
.lfb:
586
.lfb:
587
                               ;îáëàñòü LFB
587
                               ;îáëàñòü LFB
588
                               ;Îøèáêà
588
                               ;Îøèáêà
589
           jmp .fail
589
           jmp .fail
590
 
590
 
591
align 4
591
align 4
592
.user_space:
592
.user_space:
593
           test eax, PG_MAP
593
           test eax, PG_MAP
594
           jnz .err_access     ;Ñòðàíèöà ïðèñóòñòâóåò
594
           jnz .err_access     ;Ñòðàíèöà ïðèñóòñòâóåò
595
                               ;Îøèáêà äîñòóïà ?
595
                               ;Îøèáêà äîñòóïà ?
596
 
596
 
597
           shr ebx, 12
597
           shr ebx, 12
598
           mov ecx, ebx
598
           mov ecx, ebx
599
           shr ecx, 10
599
           shr ecx, 10
600
           mov edx, [master_tab+ecx*4]
600
           mov edx, [master_tab+ecx*4]
601
           test edx, PG_MAP
601
           test edx, PG_MAP
602
           jz .fail            ;òàáëèöà ñòðàíèö íå ñîçäàíà
602
           jz .fail            ;òàáëèöà ñòðàíèö íå ñîçäàíà
603
                               ;íåâåðíûé àäðåñ â ïðîãðàììå
603
                               ;íåâåðíûé àäðåñ â ïðîãðàììå
604
 
604
 
605
           mov eax, [page_tabs+ebx*4]
605
           mov eax, [page_tabs+ebx*4]
606
           test eax, 2
606
           test eax, 2
607
           jz .fail            ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
607
           jz .fail            ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
608
                               ;èñïîëüçîâàíèÿ. Îøèáêà
608
                               ;èñïîëüçîâàíèÿ. Îøèáêà
609
.alloc:
609
.alloc:
610
           call alloc_page
610
           call alloc_page
611
           test eax, eax
611
           test eax, eax
612
           jz .fail
612
           jz .fail
613
 
613
 
614
           stdcall map_page,[ebp-4],eax,dword PG_UW
614
           stdcall map_page,[ebp-4],eax,dword PG_UW
615
 
615
 
616
           mov edi, [ebp-4]
616
           mov edi, [ebp-4]
617
           and edi, 0xFFFFF000
617
           and edi, 0xFFFFF000
618
           mov ecx, 1024
618
           mov ecx, 1024
619
           xor eax, eax
619
           xor eax, eax
620
           cld
620
           cld
621
           rep stosd
621
           rep stosd
622
.exit:
622
.exit:
623
           mov esp, ebp
623
           mov esp, ebp
624
           popad
624
           popad
625
           add esp, 4
625
           add esp, 4
626
           iretd
626
           iretd
627
 
627
 
628
.err_access:
628
.err_access:
629
;íèêîãäà íå ïðîèñõîäèò
629
;íèêîãäà íå ïðîèñõîäèò
630
           jmp .fail
630
           jmp .fail
631
 
631
 
632
.kernel_space:
632
.kernel_space:
633
           test eax, PG_MAP
633
           test eax, PG_MAP
634
           jz .fail        ;ñòðàíèöà íå ïðèñóòñòâóåò
634
           jz .fail        ;ñòðàíèöà íå ïðèñóòñòâóåò
635
 
635
 
636
           test eax, 4     ;U/S
636
           test eax, 4     ;U/S
637
           jnz .fail       ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
637
           jnz .fail       ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
638
                           ;ÿäðà
638
                           ;ÿäðà
639
           test eax, 8
639
           test eax, 8
640
           jnz .fail       ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
640
           jnz .fail       ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
641
                           ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
641
                           ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
642
 
642
 
643
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
643
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
644
 
644
 
645
           cmp ebx, tss._io_map_0
645
           cmp ebx, tss._io_map_0
646
           jb .fail
646
           jb .fail
647
 
647
 
648
           cmp ebx, tss._io_map_0+8192
648
           cmp ebx, tss._io_map_0+8192
649
           jae .fail
649
           jae .fail
650
 
650
 
651
; io permission map
651
; io permission map
652
; copy-on-write protection
652
; copy-on-write protection
653
 
653
 
654
           call alloc_page
654
           call alloc_page
655
           test eax, eax
655
           test eax, eax
656
           jz .fail
656
           jz .fail
657
 
657
 
658
           push eax
658
           push eax
659
           stdcall map_page,[ebp-4],eax,dword PG_SW
659
           stdcall map_page,[ebp-4],eax,dword PG_SW
660
           pop eax
660
           pop eax
661
           mov edi, [.err_addr]
661
           mov edi, [.err_addr]
662
           and edi, -4096
662
           and edi, -4096
663
           lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
663
           lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
664
 
664
 
665
           mov ebx, esi
665
           mov ebx, esi
666
           shr ebx, 12
666
           shr ebx, 12
667
           mov edx, [current_slot]
667
           mov edx, [current_slot]
668
           or eax, PG_SW
668
           or eax, PG_SW
669
           mov [edx+APPDATA.io_map+ebx*4], eax
669
           mov [edx+APPDATA.io_map+ebx*4], eax
670
 
670
 
671
           add esi, [default_io_map]
671
           add esi, [default_io_map]
672
           mov ecx, 4096/4
672
           mov ecx, 4096/4
673
           cld
673
           cld
674
           rep movsd
674
           rep movsd
675
           jmp .exit
675
           jmp .exit
676
 
676
 
677
 
677
 
678
;íå îáðàáàòûâàåì. Îøèáêà
678
;íå îáðàáàòûâàåì. Îøèáêà
679
 
679
 
680
.core_tabs:
680
.core_tabs:
681
.fail:
681
.fail:
682
           mov esp, ebp
682
           mov esp, ebp
683
           popad
683
           popad
684
           add esp, 4
684
           add esp, 4
685
 
685
 
686
;           iretd
686
;           iretd
687
 
687
 
688
           save_ring3_context     ;debugger support
688
           save_ring3_context     ;debugger support
689
 
689
 
690
           mov bl, 14
690
           mov bl, 14
691
           jmp exc_c
691
           jmp exc_c
692
           iretd
692
           iretd
693
endp
693
endp
694
 
694
 
695
align 4
695
align 4
696
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
696
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
697
                      ofs:dword,buf_size:dword
697
                      ofs:dword,buf_size:dword
698
           mov eax, [buf_size]
698
           mov eax, [buf_size]
699
           test eax, eax
699
           test eax, eax
700
           jz .exit
700
           jz .exit
701
 
701
 
702
           mov eax, [pdir]
702
           mov eax, [pdir]
703
           and eax, 0xFFFFF000
703
           and eax, 0xFFFFF000
704
 
704
 
705
           stdcall map_page,[ipc_pdir],eax,PG_UW
705
           stdcall map_page,[ipc_pdir],eax,PG_UW
706
           mov ebx, [ofs]
706
           mov ebx, [ofs]
707
           shr ebx, 22
707
           shr ebx, 22
708
           mov esi, [ipc_pdir]
708
           mov esi, [ipc_pdir]
709
           mov edi, [ipc_ptab]
709
           mov edi, [ipc_ptab]
710
           mov eax, [esi+ebx*4]
710
           mov eax, [esi+ebx*4]
711
           and eax, 0xFFFFF000
711
           and eax, 0xFFFFF000
712
           jz .exit
712
           jz .exit
713
           stdcall map_page,edi,eax,PG_UW
713
           stdcall map_page,edi,eax,PG_UW
714
;           inc ebx
714
;           inc ebx
715
;           add edi, 0x1000
715
;           add edi, 0x1000
716
;           mov eax, [esi+ebx*4]
716
;           mov eax, [esi+ebx*4]
717
;           test eax, eax
717
;           test eax, eax
718
;           jz @f
718
;           jz @f
719
;          and eax, 0xFFFFF000
719
;          and eax, 0xFFFFF000
720
;           stdcall map_page, edi, eax
720
;           stdcall map_page, edi, eax
721
 
721
 
722
@@:        mov edi, [lin_addr]
722
@@:        mov edi, [lin_addr]
723
           and edi, 0xFFFFF000
723
           and edi, 0xFFFFF000
724
           mov ecx, [buf_size]
724
           mov ecx, [buf_size]
725
           add ecx, 4095
725
           add ecx, 4095
726
           shr ecx, 12
726
           shr ecx, 12
727
           inc ecx
727
           inc ecx
728
 
728
 
729
           mov edx, [ofs]
729
           mov edx, [ofs]
730
           shr edx, 12
730
           shr edx, 12
731
           and edx, 0x3FF
731
           and edx, 0x3FF
732
           mov esi, [ipc_ptab]
732
           mov esi, [ipc_ptab]
733
 
733
 
734
.map:      mov eax, [esi+edx*4]
734
.map:      mov eax, [esi+edx*4]
735
           and eax, 0xFFFFF000
735
           and eax, 0xFFFFF000
736
           jz  .exit
736
           jz  .exit
737
           stdcall map_page,edi,eax,PG_UW
737
           stdcall map_page,edi,eax,PG_UW
738
           dec ecx
738
           dec ecx
739
           jz  .exit
739
           jz  .exit
740
           add edi, 0x1000
740
           add edi, 0x1000
741
           inc edx
741
           inc edx
742
           cmp edx, 0x400
742
           cmp edx, 0x400
743
           jnz .map
743
           jnz .map
744
           inc ebx
744
           inc ebx
745
           mov eax, [ipc_pdir]
745
           mov eax, [ipc_pdir]
746
           mov eax, [eax+ebx*4]
746
           mov eax, [eax+ebx*4]
747
           and eax, 0xFFFFF000
747
           and eax, 0xFFFFF000
748
           jz  .exit
748
           jz  .exit
749
           stdcall map_page,esi,eax,PG_UW
749
           stdcall map_page,esi,eax,PG_UW
750
           xor edx, edx
750
           xor edx, edx
751
           jmp .map
751
           jmp .map
752
 
752
 
753
.exit:
753
.exit:
754
           ret
754
           ret
755
endp
755
endp
756
 
756
 
757
align 4
757
align 4
758
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
758
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
759
                        ofs:dword,buf_size:dword
759
                        ofs:dword,buf_size:dword
760
           mov eax, [buf_size]
760
           mov eax, [buf_size]
761
           test eax, eax
761
           test eax, eax
762
           jz .exit
762
           jz .exit
763
 
763
 
764
           mov eax, [pdir]
764
           mov eax, [pdir]
765
           and eax, 0xFFFFF000
765
           and eax, 0xFFFFF000
766
 
766
 
767
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
767
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
768
           mov ebx, [ofs]
768
           mov ebx, [ofs]
769
           shr ebx, 22
769
           shr ebx, 22
770
           mov esi, [proc_mem_pdir]
770
           mov esi, [proc_mem_pdir]
771
           mov edi, [proc_mem_tab]
771
           mov edi, [proc_mem_tab]
772
           mov eax, [esi+ebx*4]
772
           mov eax, [esi+ebx*4]
773
           and eax, 0xFFFFF000
773
           and eax, 0xFFFFF000
774
           test eax, eax
774
           test eax, eax
775
           jz .exit
775
           jz .exit
776
           stdcall map_page,edi,eax,dword PG_UW
776
           stdcall map_page,edi,eax,dword PG_UW
777
 
777
 
778
@@:        mov edi, [lin_addr]
778
@@:        mov edi, [lin_addr]
779
           and edi, 0xFFFFF000
779
           and edi, 0xFFFFF000
780
           mov ecx, [buf_size]
780
           mov ecx, [buf_size]
781
           add ecx, 4095
781
           add ecx, 4095
782
           shr ecx, 12
782
           shr ecx, 12
783
           inc ecx
783
           inc ecx
784
 
784
 
785
           mov edx, [ofs]
785
           mov edx, [ofs]
786
           shr edx, 12
786
           shr edx, 12
787
           and edx, 0x3FF
787
           and edx, 0x3FF
788
           mov esi, [proc_mem_tab]
788
           mov esi, [proc_mem_tab]
789
 
789
 
790
.map:      mov eax, [esi+edx*4]
790
.map:      mov eax, [esi+edx*4]
791
;           and eax, 0xFFFFF000
791
;           and eax, 0xFFFFF000
792
;           test eax, eax
792
;           test eax, eax
793
;           jz .exit
793
;           jz .exit
794
           stdcall map_page,edi,eax,dword PG_UW
794
           stdcall map_page,edi,eax,dword PG_UW
795
           add edi, 0x1000
795
           add edi, 0x1000
796
           inc edx
796
           inc edx
797
           dec ecx
797
           dec ecx
798
           jnz .map
798
           jnz .map
799
.exit:
799
.exit:
800
           ret
800
           ret
801
endp
801
endp
802
 
802
 
803
 
803
 
804
 
804
 
805
 
805
 
806
sys_IPC:
806
sys_IPC:
807
;input:
807
;input:
808
;  eax=1 - set ipc buffer area
808
;  eax=1 - set ipc buffer area
809
;    ebx=address of buffer
809
;    ebx=address of buffer
810
;    ecx=size of buffer
810
;    ecx=size of buffer
811
;  eax=2 - send message
811
;  eax=2 - send message
812
;    ebx=PID
812
;    ebx=PID
813
;    ecx=address of message
813
;    ecx=address of message
814
;    edx=size of message
814
;    edx=size of message
815
 
815
 
816
           cmp  eax,1
816
           cmp  eax,1
817
           jne @f
817
           jne @f
818
           call set_ipc_buff
818
           call set_ipc_buff
819
           mov [esp+36], eax
819
           mov [esp+36], eax
820
           ret
820
           ret
821
@@:
821
@@:
822
           cmp eax, 2
822
           cmp eax, 2
823
           jne @f
823
           jne @f
824
           stdcall sys_ipc_send, ebx, ecx, edx
824
           stdcall sys_ipc_send, ebx, ecx, edx
825
           mov [esp+36], eax
825
           mov [esp+36], eax
826
           ret
826
           ret
827
@@:
827
@@:
828
           xor eax, eax
828
           xor eax, eax
829
           not eax
829
           not eax
830
           mov [esp+36], eax
830
           mov [esp+36], eax
831
           ret
831
           ret
832
 
832
 
833
align 4
833
align 4
834
proc set_ipc_buff
834
proc set_ipc_buff
835
 
835
 
836
           mov  eax,[current_slot]
836
           mov  eax,[current_slot]
837
           pushf
837
           pushf
838
           cli
838
           cli
839
           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
839
           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
840
           mov  [eax+APPDATA.ipc_size],ecx
840
           mov  [eax+APPDATA.ipc_size],ecx
841
 
841
 
842
           add ecx, ebx
842
           add ecx, ebx
843
           add ecx, 4095
843
           add ecx, 4095
844
           and ecx, not 4095
844
           and ecx, not 4095
845
 
845
 
846
.touch:    mov eax, [ebx]
846
.touch:    mov eax, [ebx]
847
           add ebx, 0x1000
847
           add ebx, 0x1000
848
           cmp ebx, ecx
848
           cmp ebx, ecx
849
           jb  .touch
849
           jb  .touch
850
 
850
 
851
           popf
851
           popf
852
           xor eax, eax
852
           xor eax, eax
853
           ret
853
           ret
854
endp
854
endp
855
 
855
 
856
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
856
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
857
           locals
857
           locals
858
             dst_slot   dd ?
858
             dst_slot   dd ?
859
             dst_offset dd ?
859
             dst_offset dd ?
860
             buf_size   dd ?
860
             buf_size   dd ?
861
             used_buf   dd ?
861
             used_buf   dd ?
862
           endl
862
           endl
863
 
863
 
864
           pushf
864
           pushf
865
           cli
865
           cli
866
 
866
 
867
           mov  eax, [PID]
867
           mov  eax, [PID]
868
           call pid_to_slot
868
           call pid_to_slot
869
           test eax,eax
869
           test eax,eax
870
           jz   .no_pid
870
           jz   .no_pid
871
 
871
 
872
           mov [dst_slot], eax
872
           mov [dst_slot], eax
873
           shl  eax,8
873
           shl  eax,8
874
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
874
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
875
           test edi,edi
875
           test edi,edi
876
           jz   .no_ipc_area
876
           jz   .no_ipc_area
877
 
877
 
878
           mov ebx, edi
878
           mov ebx, edi
879
           and ebx, 0xFFF
879
           and ebx, 0xFFF
880
           mov [dst_offset], ebx
880
           mov [dst_offset], ebx
881
 
881
 
882
           mov esi, [eax+SLOT_BASE+0xa4]
882
           mov esi, [eax+SLOT_BASE+0xa4]
883
           mov [buf_size], esi
883
           mov [buf_size], esi
884
 
884
 
885
           mov ecx, [ipc_tmp]
885
           mov ecx, [ipc_tmp]
886
           cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
886
           cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
887
           jbe @f
887
           jbe @f
888
           push eax esi edi
888
           push eax esi edi
889
           add esi,0x1000
889
           add esi,0x1000
890
           stdcall alloc_kernel_space,esi
890
           stdcall alloc_kernel_space,esi
891
           mov ecx, eax
891
           mov ecx, eax
892
           pop edi esi eax
892
           pop edi esi eax
893
@@:
893
@@:
894
           mov [used_buf], ecx
894
           mov [used_buf], ecx
895
           stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
895
           stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\
896
                             edi, esi
896
                             edi, esi
897
 
897
 
898
           mov edi, [dst_offset]
898
           mov edi, [dst_offset]
899
           add edi, [used_buf]
899
           add edi, [used_buf]
900
           cmp dword [edi], 0
900
           cmp dword [edi], 0
901
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
901
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
902
 
902
 
903
           mov edx, dword [edi+4]
903
           mov edx, dword [edi+4]
904
           lea ebx, [edx+8]
904
           lea ebx, [edx+8]
905
           add ebx, [msg_size]
905
           add ebx, [msg_size]
906
           cmp ebx, [buf_size]
906
           cmp ebx, [buf_size]
907
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
907
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
908
 
908
 
909
           mov dword [edi+4], ebx
909
           mov dword [edi+4], ebx
910
           mov eax,[TASK_BASE]
910
           mov eax,[TASK_BASE]
911
           mov eax, [eax+0x04]         ;eax - our PID
911
           mov eax, [eax+0x04]         ;eax - our PID
912
           add edi, edx
912
           add edi, edx
913
           mov [edi], eax
913
           mov [edi], eax
914
           mov ecx, [msg_size]
914
           mov ecx, [msg_size]
915
 
915
 
916
           mov [edi+4], ecx
916
           mov [edi+4], ecx
917
           add edi, 8
917
           add edi, 8
918
           mov esi, [msg_addr]
918
           mov esi, [msg_addr]
919
       ;    add esi, new_app_base
919
       ;    add esi, new_app_base
920
           cld
920
           cld
921
           rep movsb
921
           rep movsb
922
 
922
 
923
           mov ebx, [ipc_tmp]
923
           mov ebx, [ipc_tmp]
924
           mov edx, ebx
924
           mov edx, ebx
925
           shr ebx, 12
925
           shr ebx, 12
926
           xor eax, eax
926
           xor eax, eax
927
           mov [page_tabs+ebx*4], eax
927
           mov [page_tabs+ebx*4], eax
928
           invlpg [edx]
928
           invlpg [edx]
929
 
929
 
930
           mov ebx, [ipc_pdir]
930
           mov ebx, [ipc_pdir]
931
           mov edx, ebx
931
           mov edx, ebx
932
           shr ebx, 12
932
           shr ebx, 12
933
           xor eax, eax
933
           xor eax, eax
934
           mov [page_tabs+ebx*4], eax
934
           mov [page_tabs+ebx*4], eax
935
           invlpg [edx]
935
           invlpg [edx]
936
 
936
 
937
           mov ebx, [ipc_ptab]
937
           mov ebx, [ipc_ptab]
938
           mov edx, ebx
938
           mov edx, ebx
939
           shr ebx, 12
939
           shr ebx, 12
940
           xor eax, eax
940
           xor eax, eax
941
           mov [page_tabs+ebx*4], eax
941
           mov [page_tabs+ebx*4], eax
942
           invlpg [edx]
942
           invlpg [edx]
943
 
943
 
944
           mov  eax, [dst_slot]
944
           mov  eax, [dst_slot]
945
           shl eax, 8
945
           shl eax, 8
946
           or   [eax+SLOT_BASE+0xA8],dword 0x40
946
           or   [eax+SLOT_BASE+0xA8],dword 0x40
947
           cmp  dword [check_idle_semaphore],20
947
           cmp  dword [check_idle_semaphore],20
948
           jge  .ipc_no_cis
948
           jge  .ipc_no_cis
949
 
949
 
950
           mov  dword [check_idle_semaphore],5
950
           mov  dword [check_idle_semaphore],5
951
.ipc_no_cis:
951
.ipc_no_cis:
952
           push 0
952
           push 0
953
           jmp .ret
953
           jmp .ret
954
.no_pid:
954
.no_pid:
955
           popf
955
           popf
956
           mov eax, 4
956
           mov eax, 4
957
           ret
957
           ret
958
.no_ipc_area:
958
.no_ipc_area:
959
           popf
959
           popf
960
           xor eax, eax
960
           xor eax, eax
961
           inc eax
961
           inc eax
962
           ret
962
           ret
963
.ipc_blocked:
963
.ipc_blocked:
964
           push 2
964
           push 2
965
           jmp .ret
965
           jmp .ret
966
.buffer_overflow:
966
.buffer_overflow:
967
           push 3
967
           push 3
968
.ret:
968
.ret:
969
           mov eax, [used_buf]
969
           mov eax, [used_buf]
970
           cmp eax, [ipc_tmp]
970
           cmp eax, [ipc_tmp]
971
           jz @f
971
           jz @f
972
           stdcall free_kernel_space,eax
972
           stdcall free_kernel_space,eax
973
@@:
973
@@:
974
           pop eax
974
           pop eax
975
           popf
975
           popf
976
           ret
976
           ret
977
endp
977
endp
978
 
978
 
979
align 4
979
align 4
980
sysfn_meminfo:
980
sysfn_meminfo:
981
 
981
 
982
        ;   add ebx, new_app_base
982
        ;   add ebx, new_app_base
983
           cmp ebx, OS_BASE
983
           cmp ebx, OS_BASE
984
           jae .fail
984
           jae .fail
985
 
985
 
986
           mov eax, [pg_data.pages_count]
986
           mov eax, [pg_data.pages_count]
987
           mov [ebx], eax
987
           mov [ebx], eax
988
           shl eax, 12
988
           shl eax, 12
989
           mov [esp+36], eax
989
           mov [esp+36], eax
990
           mov ecx, [pg_data.pages_free]
990
           mov ecx, [pg_data.pages_free]
991
           mov [ebx+4], ecx
991
           mov [ebx+4], ecx
992
           mov edx, [pg_data.pages_faults]
992
           mov edx, [pg_data.pages_faults]
993
           mov [ebx+8], edx
993
           mov [ebx+8], edx
994
           mov esi, [heap_size]
994
           mov esi, [heap_size]
995
           mov [ebx+12], esi
995
           mov [ebx+12], esi
996
           mov edi, [heap_free]
996
           mov edi, [heap_free]
997
           mov [ebx+16], edi
997
           mov [ebx+16], edi
998
           mov eax, [heap_blocks]
998
           mov eax, [heap_blocks]
999
           mov [ebx+20], eax
999
           mov [ebx+20], eax
1000
           mov ecx, [free_blocks]
1000
           mov ecx, [free_blocks]
1001
           mov [ebx+24], ecx
1001
           mov [ebx+24], ecx
1002
           ret
1002
           ret
1003
.fail:
1003
.fail:
1004
           mov dword [esp+36], -1
1004
           mov dword [esp+36], -1
1005
           ret
1005
           ret
1006
 
1006
 
1007
align 4
1007
align 4
1008
new_services:
1008
new_services:
1009
 
1009
 
1010
           cmp  eax,4
1010
           cmp  eax,4
1011
           jle  sys_sheduler
1011
           jle  sys_sheduler
1012
 
1012
 
1013
           cmp eax, 11
1013
           cmp eax, 11
1014
           jb .fail
1014
           jb .fail
1015
           ja @f
1015
           ja @f
1016
 
1016
 
1017
           call init_heap
1017
           call init_heap
1018
           mov [esp+36], eax
1018
           mov [esp+36], eax
1019
           ret
1019
           ret
1020
@@:
1020
@@:
1021
           cmp eax, 12
1021
           cmp eax, 12
1022
           ja @f
1022
           ja @f
1023
 
1023
 
1024
           stdcall user_alloc, ebx
1024
           stdcall user_alloc, ebx
1025
           mov [esp+36], eax
1025
           mov [esp+36], eax
1026
           ret
1026
           ret
1027
@@:
1027
@@:
1028
           cmp eax, 13
1028
           cmp eax, 13
1029
           ja @f
1029
           ja @f
1030
           stdcall user_free, ebx
1030
           stdcall user_free, ebx
1031
           mov [esp+36], eax
1031
           mov [esp+36], eax
1032
           ret
1032
           ret
1033
@@:
1033
@@:
1034
           cmp eax, 14
1034
           cmp eax, 14
1035
           ja @f
1035
           ja @f
1036
           cmp ebx, OS_BASE
1036
           cmp ebx, OS_BASE
1037
           jae .fail
1037
           jae .fail
1038
           stdcall get_event_ex, ebx, ecx
1038
           stdcall get_event_ex, ebx, ecx
1039
           mov [esp+36], eax
1039
           mov [esp+36], eax
1040
           ret
1040
           ret
1041
@@:
1041
@@:
1042
           cmp eax, 15
1042
           cmp eax, 15
1043
           ja @f
1043
           ja @f
1044
           mov ecx, [current_slot]
1044
           mov ecx, [current_slot]
1045
           mov eax, [ecx+APPDATA.fpu_handler]
1045
           mov eax, [ecx+APPDATA.fpu_handler]
1046
           mov [ecx+APPDATA.fpu_handler], ebx
1046
           mov [ecx+APPDATA.fpu_handler], ebx
1047
           mov [esp+36], eax
1047
           mov [esp+36], eax
1048
           ret
1048
           ret
1049
@@:
1049
@@:
1050
           cmp eax, 16
1050
           cmp eax, 16
1051
           ja @f
1051
           ja @f
1052
 
1052
 
1053
           test ebx, ebx
1053
           test ebx, ebx
1054
           jz .fail
1054
           jz .fail
1055
           cmp ebx, OS_BASE
1055
           cmp ebx, OS_BASE
1056
           jae .fail
1056
           jae .fail
1057
           stdcall get_service, ebx
1057
           stdcall get_service, ebx
1058
           mov [esp+36], eax
1058
           mov [esp+36], eax
1059
           ret
1059
           ret
1060
@@:
1060
@@:
1061
           cmp eax, 17
1061
           cmp eax, 17
1062
           ja @f
1062
           ja @f
1063
           call srv_handlerEx   ;ebx
1063
           call srv_handlerEx   ;ebx
1064
           mov [esp+36], eax
1064
           mov [esp+36], eax
1065
           ret
1065
           ret
1066
@@:
1066
@@:
1067
           cmp eax, 18
1067
           cmp eax, 18
1068
           ja @f
1068
           ja @f
1069
           mov ecx, [current_slot]
1069
           mov ecx, [current_slot]
1070
           mov eax, [ecx+APPDATA.sse_handler]
1070
           mov eax, [ecx+APPDATA.sse_handler]
1071
           mov [ecx+APPDATA.sse_handler], ebx
1071
           mov [ecx+APPDATA.sse_handler], ebx
1072
           mov [esp+36], eax
1072
           mov [esp+36], eax
1073
           ret
1073
           ret
1074
@@:
1074
@@:
1075
           cmp eax, 19
1075
           cmp eax, 19
1076
           ja @f
1076
           ja @f
1077
           cmp ebx, OS_BASE
1077
           cmp ebx, OS_BASE
1078
           jae .fail
1078
           jae .fail
1079
           stdcall load_library, ebx
1079
           stdcall load_library, ebx
1080
           mov [esp+36], eax
1080
           mov [esp+36], eax
1081
           ret
1081
           ret
1082
@@:
1082
@@:
1083
           cmp     eax, 20
1083
           cmp     eax, 20
1084
           ja      @F
1084
           ja      @F
1085
           mov     eax, ecx
1085
           mov     eax, ecx
1086
           call    user_realloc
1086
           call    user_realloc
1087
           mov     [esp+36], eax
1087
           mov     [esp+36], eax
1088
           ret
1088
           ret
1089
@@:
1089
@@:
1090
           cmp eax, 21                     ;for test purposes only
1090
           cmp eax, 21                     ;for test purposes only
1091
           ja @f                           ;will be removed soon
1091
           ja @f                           ;will be removed soon
1092
           cmp ebx, OS_BASE
1092
           cmp ebx, OS_BASE
1093
           jae .fail
1093
           jae .fail
1094
 
1094
 
1095
           stdcall load_PE, ebx
1095
           stdcall load_PE, ebx
1096
 
1096
 
1097
           test eax, eax
1097
           test eax, eax
1098
           jz @F
1098
           jz @F
1099
 
1099
 
1100
           mov esi, eax
1100
           mov esi, eax
1101
           stdcall eax, DRV_ENTRY
1101
           stdcall eax, DRV_ENTRY
1102
 
1102
 
1103
           test eax, eax
1103
           test eax, eax
1104
           jz @F
1104
           jz @F
1105
 
1105
 
1106
           mov [eax+SRV.entry], esi
1106
           mov [eax+SRV.entry], esi
1107
 
1107
 
1108
@@:
1108
@@:
1109
           mov [esp+36], eax
1109
           mov [esp+36], eax
1110
           ret
1110
           ret
1111
 
1111
 
1112
 
1112
 
1113
.fail:
1113
.fail:
1114
           xor eax, eax
1114
           xor eax, eax
1115
           mov [esp+36], eax
1115
           mov [esp+36], eax
1116
           ret
1116
           ret
1117
 
1117
 
1118
align 4
1118
align 4
1119
proc load_pe_driver stdcall, file:dword
1119
proc load_pe_driver stdcall, file:dword
1120
 
1120
 
1121
           stdcall load_PE, [file]
1121
           stdcall load_PE, [file]
1122
           test eax, eax
1122
           test eax, eax
1123
           jz .fail
1123
           jz .fail
1124
 
1124
 
1125
           mov esi, eax
1125
           mov esi, eax
1126
           stdcall eax, DRV_ENTRY
1126
           stdcall eax, DRV_ENTRY
1127
           test eax, eax
1127
           test eax, eax
1128
           jz .fail
1128
           jz .fail
1129
 
1129
 
1130
           mov [eax+SRV.entry], esi
1130
           mov [eax+SRV.entry], esi
1131
           ret
1131
           ret
1132
 
1132
 
1133
.fail:
1133
.fail:
1134
           xor eax, eax
1134
           xor eax, eax
1135
           ret
1135
           ret
1136
endp
1136
endp
1137
 
1137
 
1138
 
1138
 
1139
align 4
1139
align 4
1140
proc init_mtrr
1140
proc init_mtrr
1141
 
1141
 
1142
           cmp [BOOT_VAR+0x901c],byte 2
1142
           cmp [BOOT_VAR+0x901c],byte 2
1143
           je  .exit
1143
           je  .exit
1144
 
1144
 
1145
           bt [cpu_caps], CAPS_MTRR
1145
           bt [cpu_caps], CAPS_MTRR
1146
           jnc .exit
1146
           jnc .exit
1147
 
1147
 
1148
           mov eax, cr0
1148
           mov eax, cr0
1149
           or eax, 0x60000000   ;disable caching
1149
           or eax, 0x60000000   ;disable caching
1150
           mov cr0, eax
1150
           mov cr0, eax
1151
           wbinvd               ;invalidate cache
1151
           wbinvd               ;invalidate cache
1152
 
1152
 
1153
           mov ecx, 0x2FF
1153
           mov ecx, 0x2FF
1154
           rdmsr                ;
1154
           rdmsr                ;
1155
           push eax
1155
           push eax
1156
 
1156
 
1157
           xor edx, edx
1157
           xor edx, edx
1158
           xor eax, eax
1158
           xor eax, eax
1159
           mov ecx, 0x2FF
1159
           mov ecx, 0x2FF
1160
           wrmsr                ;disable all MTRR
1160
           wrmsr                ;disable all MTRR
-
 
1161
 
-
 
1162
           mov eax, [MEM_AMOUNT]
-
 
1163
; round eax up to next power of 2
-
 
1164
           dec eax
-
 
1165
           bsr ecx, eax
-
 
1166
           mov eax, 2
1161
 
1167
           shl eax, cl
1162
           stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
1168
           stdcall set_mtrr, edx,edx,eax,MEM_WB
1163
           stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
1169
           stdcall set_mtrr, 1,[LFBAddress],[LFBSize],MEM_WC
1164
           xor edx, edx
1170
           xor edx, edx
1165
           xor eax, eax
1171
           xor eax, eax
1166
           mov ecx, 0x204
1172
           mov ecx, 0x204
1167
           mov ebx, 6
1173
           mov ebx, 6
1168
@@:
1174
@@:
1169
           wrmsr                ;disable unused MTRR
1175
           wrmsr                ;disable unused MTRR
1170
           inc ecx
1176
           inc ecx
1171
           wrmsr
1177
           wrmsr
1172
           inc ecx
1178
           inc ecx
1173
           dec ebx
1179
           dec ebx
1174
           jnz @b
1180
           jnz @b
1175
 
1181
 
1176
           wbinvd               ;again invalidate
1182
           wbinvd               ;again invalidate
1177
 
1183
 
1178
           pop eax
1184
           pop eax
1179
           or eax, 0x800        ;set default memtype to UC
1185
           or eax, 0x800        ;set default memtype to UC
1180
           and al, 0xF0
1186
           and al, 0xF0
1181
           mov ecx, 0x2FF
1187
           mov ecx, 0x2FF
1182
           wrmsr                ;and enable MTRR
1188
           wrmsr                ;and enable MTRR
1183
 
1189
 
1184
           mov eax, cr0
1190
           mov eax, cr0
1185
           and eax, not 0x60000000
1191
           and eax, not 0x60000000
1186
           mov cr0, eax         ; enable caching
1192
           mov cr0, eax         ; enable caching
1187
.exit:
1193
.exit:
1188
           ret
1194
           ret
1189
endp
1195
endp
1190
 
1196
 
1191
align 4
1197
align 4
1192
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
1198
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
1193
 
1199
 
1194
           xor edx, edx
1200
           xor edx, edx
1195
           mov eax, [base]
1201
           mov eax, [base]
1196
           or eax, [mem_type]
1202
           or eax, [mem_type]
1197
           mov ecx, [reg]
1203
           mov ecx, [reg]
1198
           lea ecx, [0x200+ecx*2]
1204
           lea ecx, [0x200+ecx*2]
1199
           wrmsr
1205
           wrmsr
1200
 
1206
 
1201
           mov ebx, [size]
1207
           mov ebx, [size]
1202
           dec ebx
1208
           dec ebx
1203
           mov eax, 0xFFFFFFFF
1209
           mov eax, 0xFFFFFFFF
1204
           mov edx, 0x0000000F
1210
           mov edx, 0x0000000F
1205
           sub eax, ebx
1211
           sub eax, ebx
1206
           sbb edx, 0
1212
           sbb edx, 0
1207
           or eax, 0x800
1213
           or eax, 0x800
1208
           inc ecx
1214
           inc ecx
1209
           wrmsr
1215
           wrmsr
1210
           ret
1216
           ret
1211
endp
1217
endp
1212
 
1218
 
1213
align 4
1219
align 4
1214
proc stall stdcall, delay:dword
1220
proc stall stdcall, delay:dword
1215
           push ecx
1221
           push ecx
1216
           push edx
1222
           push edx
1217
           push ebx
1223
           push ebx
1218
           push eax
1224
           push eax
1219
 
1225
 
1220
           mov eax, [delay]
1226
           mov eax, [delay]
1221
           mul [stall_mcs]
1227
           mul [stall_mcs]
1222
           mov ebx, eax       ;low
1228
           mov ebx, eax       ;low
1223
           mov ecx, edx       ;high
1229
           mov ecx, edx       ;high
1224
           rdtsc
1230
           rdtsc
1225
           add ebx, eax
1231
           add ebx, eax
1226
           adc ecx,edx
1232
           adc ecx,edx
1227
@@:
1233
@@:
1228
           rdtsc
1234
           rdtsc
1229
           sub eax, ebx
1235
           sub eax, ebx
1230
           sbb edx, ecx
1236
           sbb edx, ecx
1231
           jb @B
1237
           jb @B
1232
 
1238
 
1233
           pop eax
1239
           pop eax
1234
           pop ebx
1240
           pop ebx
1235
           pop edx
1241
           pop edx
1236
           pop ecx
1242
           pop ecx
1237
           ret
1243
           ret
1238
endp
1244
endp
1239
 
1245
 
1240
align 4
1246
align 4
1241
proc create_ring_buffer stdcall, size:dword, flags:dword
1247
proc create_ring_buffer stdcall, size:dword, flags:dword
1242
           locals
1248
           locals
1243
             buf_ptr  dd ?
1249
             buf_ptr  dd ?
1244
           endl
1250
           endl
1245
 
1251
 
1246
           mov eax, [size]
1252
           mov eax, [size]
1247
           test eax, eax
1253
           test eax, eax
1248
           jz .fail
1254
           jz .fail
1249
 
1255
 
1250
           add eax, eax
1256
           add eax, eax
1251
           stdcall alloc_kernel_space, eax
1257
           stdcall alloc_kernel_space, eax
1252
           test eax, eax
1258
           test eax, eax
1253
           jz .fail
1259
           jz .fail
1254
 
1260
 
1255
           push ebx
1261
           push ebx
1256
 
1262
 
1257
           mov [buf_ptr], eax
1263
           mov [buf_ptr], eax
1258
 
1264
 
1259
           mov ebx, [size]
1265
           mov ebx, [size]
1260
           shr ebx, 12
1266
           shr ebx, 12
1261
           push ebx
1267
           push ebx
1262
 
1268
 
1263
           stdcall alloc_pages, ebx
1269
           stdcall alloc_pages, ebx
1264
           pop ecx
1270
           pop ecx
1265
 
1271
 
1266
           test eax, eax
1272
           test eax, eax
1267
           jz .mm_fail
1273
           jz .mm_fail
1268
 
1274
 
1269
           push edi
1275
           push edi
1270
 
1276
 
1271
           or eax, [flags]
1277
           or eax, [flags]
1272
           mov edi, [buf_ptr]
1278
           mov edi, [buf_ptr]
1273
           mov ebx, [buf_ptr]
1279
           mov ebx, [buf_ptr]
1274
           mov edx, ecx
1280
           mov edx, ecx
1275
           shl edx, 2
1281
           shl edx, 2
1276
           shr edi, 10
1282
           shr edi, 10
1277
@@:
1283
@@:
1278
           mov [page_tabs+edi], eax
1284
           mov [page_tabs+edi], eax
1279
           mov [page_tabs+edi+edx], eax
1285
           mov [page_tabs+edi+edx], eax
1280
           add eax, 0x1000
1286
           add eax, 0x1000
1281
           add ebx, 0x1000
1287
           add ebx, 0x1000
1282
           add edi, 4
1288
           add edi, 4
1283
           dec ecx
1289
           dec ecx
1284
           jnz @B
1290
           jnz @B
1285
 
1291
 
1286
           mov eax, [buf_ptr]
1292
           mov eax, [buf_ptr]
1287
           pop edi
1293
           pop edi
1288
           pop ebx
1294
           pop ebx
1289
           ret
1295
           ret
1290
.mm_fail:
1296
.mm_fail:
1291
           stdcall free_kernel_space, [buf_ptr]
1297
           stdcall free_kernel_space, [buf_ptr]
1292
           xor eax, eax
1298
           xor eax, eax
1293
           pop ebx
1299
           pop ebx
1294
.fail:
1300
.fail:
1295
           ret
1301
           ret
1296
endp
1302
endp