Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
425 victor 1
$Revision: 425 $
164 serge 2
 
357 serge 3
tmp_page_tab      equ HEAP_BASE
164 serge 4
 
5
align 4
6
proc mem_test
214 serge 7
 
164 serge 8
           mov eax, cr0
212 serge 9
           and eax, not (CR0_CD+CR0_NW)
214 serge 10
           or eax, CR0_CD         ;disable caching
164 serge 11
           mov cr0, eax
214 serge 12
           wbinvd                 ;invalidate cache
164 serge 13
 
214 serge 14
           xor edi, edi
164 serge 15
           mov ebx, 'TEST'
16
@@:
17
           add edi, 0x400000
18
           xchg ebx, dword [edi]
19
           cmp dword [edi], 'TEST'
20
           xchg ebx, dword [edi]
21
           je @b
357 serge 22
           mov [MEM_AMOUNT], edi
164 serge 23
 
212 serge 24
           and eax, not (CR0_CD+CR0_NW)  ;enable caching
164 serge 25
           mov cr0, eax
26
           mov eax, edi
214 serge 27
           mov [LFBSize], 0x00800000
164 serge 28
           ret
29
endp
30
 
31
align 4
357 serge 32
proc init_mem
33
 
34
           mov eax, [MEM_AMOUNT]
35
 
36
           mov [pg_data.mem_amount], eax
37
           mov [pg_data.kernel_max], eax
38
 
39
           shr eax, 12
40
           mov edx, eax
41
           mov [pg_data.pages_count], eax
42
           mov [pg_data.kernel_pages], eax
43
 
44
           shr eax, 3
45
           mov [pg_data.pagemap_size], eax
46
 
47
           shr edx, 10
48
           cmp edx, 3
49
           ja @f
50
           inc edx       ;at least 4Mb for kernel heap
51
@@:
52
           mov [pg_data.kernel_tables], edx
53
 
164 serge 54
           xor eax, eax
55
           mov edi, sys_pgdir
56
           mov ecx, 2048
357 serge 57
           cld
164 serge 58
           rep stosd
59
 
357 serge 60
           mov edx, sys_pgdir
164 serge 61
           bt [cpu_caps], CAPS_PSE
62
           jnc .no_PSE
63
 
64
           mov ebx, cr4
65
           or ebx, CR4_PSE
66
           mov eax, PG_LARGE+PG_SW
67
           bt [cpu_caps], CAPS_PGE
68
           jnc @F
69
           or eax, PG_GLOBAL
70
           or ebx, CR4_PGE
71
@@:
168 serge 72
           mov cr4, ebx
357 serge 73
           sub [pg_data.kernel_tables], 2
168 serge 74
 
357 serge 75
           mov [edx], eax
164 serge 76
           add eax, 0x00400000
357 serge 77
           mov [edx+4], eax
78
           add edx, 8
164 serge 79
 
357 serge 80
           mov eax, 0x800000+PG_SW
81
           mov ecx, (HEAP_BASE-0x800000)/4096
82
           jmp .map_low
164 serge 83
.no_PSE:
84
           mov eax, PG_SW
357 serge 85
           mov ecx, HEAP_BASE/4096
164 serge 86
.map_low:
357 serge 87
           mov edi, tmp_page_tab
88
@@:                                   ;
89
           stosd
164 serge 90
           add eax, 0x1000
91
           dec ecx
357 serge 92
           jnz @B
164 serge 93
 
94
           mov ecx, [pg_data.kernel_tables]
357 serge 95
           shl ecx, 10
96
           xor eax, eax
97
           rep stosd
98
 
99
           mov ecx, [pg_data.kernel_tables]
164 serge 100
           mov eax, tmp_page_tab+PG_SW
357 serge 101
           mov edi, edx
164 serge 102
 
103
.map_kernel_tabs:
104
 
357 serge 105
           stosd
164 serge 106
           add eax, 0x1000
107
           dec ecx
108
           jnz .map_kernel_tabs
109
 
378 serge 110
           mov dword [sys_pgdir+(page_tabs shr 20)], sys_pgdir+PG_SW
164 serge 111
           ret
112
endp
113
 
114
align 4
115
proc init_page_map
357 serge 116
 
164 serge 117
           mov edi, sys_pgmap
357 serge 118
           mov ecx, (HEAP_BASE/4096)/32      ;384/4
119
           mov ebx, ecx
164 serge 120
           xor eax,eax
121
           cld
122
           rep stosd
123
 
124
           not eax
125
           mov ecx, [pg_data.pagemap_size]
357 serge 126
           sub ecx, ebx
164 serge 127
           shr ecx, 2
128
           rep stosd
129
 
357 serge 130
           lea edi, [sys_pgmap+ebx*4]         ;+384
164 serge 131
           mov edx, [pg_data.pages_count]
132
           mov ecx, [pg_data.kernel_tables]
357 serge 133
           add ecx, (HEAP_BASE/4096) and 31
134
           sub edx, HEAP_BASE/4096
164 serge 135
           sub edx, ecx
136
           mov [pg_data.pages_free], edx
137
 
138
           xor eax, eax
139
           mov ebx, ecx
140
           shr ecx, 5
141
           rep stosd
142
 
143
           not eax
144
           mov ecx, ebx
145
           and ecx, 31
146
           shl eax, cl
357 serge 147
           mov [page_start], edi;           sys_pgmap+384
164 serge 148
           stosd
149
 
150
           mov ebx, sys_pgmap
151
           add ebx, [pg_data.pagemap_size]
152
           mov [page_end], ebx
153
 
154
           mov [pg_data.pg_mutex], 0
155
 
156
           ret
157
endp
158
 
159
align 4
160
proc alloc_page
161
 
162
           pushfd
163
           cli
164
           mov ebx, [page_start]
165
           mov ecx, [page_end]
166
.l1:
167
           bsf eax,[ebx];
168
           jnz .found
169
           add ebx,4
170
           cmp ebx, ecx
171
           jb .l1
172
           popfd
173
           xor eax,eax
174
           ret
175
.found:
176
           btr [ebx], eax
177
           mov [page_start],ebx
178
           sub ebx, sys_pgmap
254 serge 179
           lea eax, [eax+ebx*8]
164 serge 180
           shl eax, 12
181
           dec [pg_data.pages_free]
182
           popfd
183
           ret
184
endp
185
 
186
align 4
187
proc alloc_pages stdcall, count:dword
188
           pushfd
189
           cli
190
           mov eax, [count]
191
           add eax, 7
192
           shr eax, 3
193
           mov [count], eax
194
           cmp eax, [pg_data.pages_free]
195
           ja .fail
196
 
197
           mov ecx, [page_start]
198
           mov ebx, [page_end]
199
.find:
200
           mov edx, [count]
201
           mov edi, ecx
202
.match:
203
           cmp byte [ecx], 0xFF
204
           jne .next
205
           dec edx
206
           jz .ok
207
           inc ecx
208
           cmp ecx,ebx
209
           jb .match
210
.fail:     xor eax, eax
211
           popfd
212
           ret
213
.next:
214
           inc ecx
215
           cmp ecx, ebx
216
           jb .find
217
           popfd
218
           xor eax, eax
219
           ret
220
.ok:
221
           sub ecx, edi
222
           inc ecx
223
           mov esi, edi
224
           xor eax, eax
225
           rep stosb
226
           sub esi, sys_pgmap
227
           shl esi, 3+12
228
           mov eax, esi
229
           mov ebx, [count]
230
           shl ebx, 3
231
           sub [pg_data.pages_free], ebx
232
           popfd
233
           ret
234
endp
235
 
236
align 4
237
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
321 diamond 238
           push ebx
164 serge 239
           mov eax, [phis_addr]
240
           and eax, not 0xFFF
241
           or eax, [flags]
242
           mov ebx, [lin_addr]
243
           shr ebx, 12
365 serge 244
           mov [page_tabs+ebx*4], eax
164 serge 245
           mov eax, [lin_addr]
246
           invlpg [eax]
321 diamond 247
           pop ebx
164 serge 248
           ret
249
endp
250
 
251
align 4
281 serge 252
map_space:    ;not implemented
253
 
254
 
255
           ret
256
 
257
 
258
align 4
164 serge 259
proc free_page
260
;arg:  eax  page address
261
           pushfd
262
           cli
263
           shr eax, 12              ;page index
264
           mov ebx, sys_pgmap
265
           bts [ebx], eax           ;that's all!
291 serge 266
           cmc
328 serge 267
           adc [pg_data.pages_free], 0
164 serge 268
           shr eax, 3
269
           and eax, not 3           ;dword offset from page_map
270
           add eax, ebx
271
           cmp [page_start], eax
272
           ja @f
273
           popfd
274
           ret
275
@@:
276
           mov [page_start], eax
277
           popfd
278
           ret
279
endp
280
 
279 serge 281
; param
328 serge 282
;  eax= page base + page flags
281 serge 283
;  ebx= liear address
284
;  ecx= count
285
 
286
align 4
328 serge 287
commit_pages:
281 serge 288
 
328 serge 289
           test ecx, ecx
290
           jz .fail
281 serge 291
 
328 serge 292
           mov edi, ebx
293
           mov ebx, pg_data.pg_mutex
294
           call wait_mutex      ;ebx
295
 
296
           mov edx, 0x1000
297
           mov ebx, edi
298
           shr ebx, 12
299
@@:
365 serge 300
           mov [page_tabs+ebx*4], eax
328 serge 301
           invlpg [edi]
302
           add edi, edx
303
           add eax, edx
304
           inc ebx
305
           dec ecx
306
           jnz @B
307
           mov [pg_data.pg_mutex],ecx
308
.fail:
281 serge 309
           ret
310
 
328 serge 311
 
281 serge 312
; param
279 serge 313
;  eax= base
281 serge 314
;  ecx= count
279 serge 315
 
164 serge 316
align 4
279 serge 317
release_pages:
321 diamond 318
 
319
           pushad
279 serge 320
           mov ebx, pg_data.pg_mutex
321
           call wait_mutex      ;ebx
322
 
323
           mov esi, eax
324
           mov edi, eax
325
 
326
           shr esi, 10
365 serge 327
           add esi, page_tabs
328 serge 328
 
329
           mov ebp, [pg_data.pages_free]
279 serge 330
           mov ebx, [page_start]
331
           mov edx, sys_pgmap
332
@@:
333
           xor eax, eax
334
           xchg eax, [esi]
335
           invlpg [edi]
336
 
337
           test eax, 1
338
           jz .next
339
 
340
           shr eax, 12
341
           bts [edx], eax
291 serge 342
           cmc
328 serge 343
           adc ebp, 0
279 serge 344
           shr eax, 3
345
           and eax, -4
346
           add eax, edx
347
           cmp eax, ebx
348
           jae .next
349
 
350
           mov ebx, eax
351
.next:
352
           add edi, 0x1000
353
           add esi, 4
354
           dec ecx
355
           jnz @B
328 serge 356
           mov [pg_data.pages_free], ebp
279 serge 357
           and [pg_data.pg_mutex],0
321 diamond 358
           popad
279 serge 359
           ret
360
 
361
align 4
188 serge 362
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
321 diamond 363
           push ebx
164 serge 364
           mov ebx, [lin_addr]
365
           shr ebx, 22
366
           mov eax, [phis_addr]
367
           and eax, not 0xFFF
368
           or eax, PG_UW          ;+PG_NOCACHE
378 serge 369
           mov dword [master_tab+ebx*4], eax
164 serge 370
           mov eax, [lin_addr]
371
           shr eax, 10
365 serge 372
           add eax, page_tabs
164 serge 373
           invlpg [eax]
321 diamond 374
           pop ebx
164 serge 375
           ret
376
endp
377
 
378
align 4
379
proc init_LFB
378 serge 380
           locals
381
             pg_count dd ?
382
           endl
383
 
164 serge 384
           cmp dword [LFBAddress], -1
385
           jne @f
412 serge 386
           mov [BOOT_VAR+0x901c],byte 2
164 serge 387
           stdcall kernel_alloc, 0x280000
388
           mov [LFBAddress], eax
389
           ret
390
@@:
391
           test [SCR_MODE],word 0100000000000000b
211 serge 392
           jnz @f
412 serge 393
           mov [BOOT_VAR+0x901c],byte 2
211 serge 394
           ret
395
@@:
378 serge 396
           mov edx, LFB_BASE
397
           mov esi, [LFBAddress]
164 serge 398
           mov edi, [LFBSize]
379 serge 399
           mov dword [exp_lfb+4], edx
214 serge 400
 
164 serge 401
           shr edi, 12
402
           mov [pg_count], edi
403
           shr edi, 10
404
 
405
           bt [cpu_caps], CAPS_PSE
406
           jnc .map_page_tables
407
           or esi, PG_LARGE+PG_UW
378 serge 408
           shr edx, 20
409
           mov ecx, edx
164 serge 410
@@:
378 serge 411
           mov [sys_pgdir+edx], esi
412
           add edx, 4
164 serge 413
           add esi, 0x00400000
414
           dec edi
415
           jnz @B
416
 
207 serge 417
           bt [cpu_caps], CAPS_PGE
418
           jnc @F
164 serge 419
           or dword [sys_pgdir+ecx], PG_GLOBAL
207 serge 420
@@:
378 serge 421
           mov dword [LFBAddress], LFB_BASE
164 serge 422
           mov eax, cr3       ;flush TLB
423
           mov cr3, eax
424
           ret
425
 
426
.map_page_tables:
427
 
428
           call alloc_page
378 serge 429
           stdcall map_page_table, edx, eax
389 serge 430
           add edx, 0x00400000
164 serge 431
           dec edi
389 serge 432
           jnz .map_page_tables
164 serge 433
 
434
           mov eax, [LFBAddress]
378 serge 435
           mov edi, page_tabs + (LFB_BASE shr 10)
164 serge 436
           or eax, PG_UW
437
           mov ecx, [pg_count]
378 serge 438
           cld
389 serge 439
@@:
440
           stosd
441
           add eax, 0x1000
442
           dec ecx
443
           jnz @B
164 serge 444
 
378 serge 445
           mov dword [LFBAddress], LFB_BASE
164 serge 446
           mov eax, cr3       ;flush TLB
447
           mov cr3, eax
448
 
449
           ret
450
endp
451
 
452
align 4
453
proc new_mem_resize stdcall, new_size:dword
454
 
276 serge 455
           mov ebx, pg_data.pg_mutex
456
           call wait_mutex    ;ebx
164 serge 457
 
458
           mov edi, [new_size]
459
           add edi,4095
460
           and edi,not 4095
461
           mov [new_size], edi
462
 
463
           mov edx,[CURRENT_TASK]
464
           shl edx,8
380 serge 465
           cmp [SLOT_BASE+APPDATA.heap_base+edx],0
172 serge 466
           jne .exit
467
 
380 serge 468
           mov esi, [SLOT_BASE+APPDATA.mem_size+edx]
164 serge 469
           add esi, 4095
470
           and esi, not 4095
471
 
472
           cmp edi, esi
473
           jae .expand
474
 
475
           shr edi, 12
476
           shr esi, 12
477
@@:
378 serge 478
           mov eax, [app_page_tabs+edi*4]
164 serge 479
           test eax, 1
480
           jz .next
378 serge 481
           mov dword [app_page_tabs+edi*4], 2
164 serge 482
           mov ebx, edi
483
           shl ebx, 12
484
           invlpg [ebx+std_application_base_address]
485
           call free_page
486
 
487
.next:     add edi, 1
488
           cmp edi, esi
489
           jb @B
490
 
491
.update_size:
294 diamond 492
        mov     ebx, [new_size]
493
        call    update_mem_size
164 serge 494
 
495
           xor eax, eax
496
           dec [pg_data.pg_mutex]
497
           ret
498
 
499
.expand:
500
           add edi, new_app_base
501
           add esi, new_app_base
502
 
503
           push esi
504
           push edi
505
 
506
           add edi, 0x3FFFFF
507
           and edi, not(0x3FFFFF)
508
           add esi, 0x3FFFFF
509
           and esi, not(0x3FFFFF)
510
 
511
           cmp esi, edi
512
           jae .grow
513
 
514
           xchg esi, edi
515
 
516
@@:
517
           call alloc_page
518
           test eax, eax
519
           jz .exit
520
 
188 serge 521
           stdcall map_page_table, edi, eax
164 serge 522
 
523
           push edi
524
           shr edi, 10
365 serge 525
           add edi, page_tabs
164 serge 526
           mov ecx, 1024
527
           xor eax, eax
528
           cld
529
           rep stosd
530
           pop edi
531
 
532
           add edi, 0x00400000
533
           cmp edi, esi
534
           jb @B
535
.grow:
536
           pop edi
537
           pop esi
538
@@:
539
           call alloc_page
540
           test eax, eax
541
           jz .exit
542
           stdcall map_page,esi,eax,dword PG_UW
543
 
544
           push edi
545
           mov edi, esi
546
           xor eax, eax
547
           mov ecx, 1024
548
           cld
549
           rep stosd
550
           pop edi
551
 
552
           add esi, 0x1000
553
           cmp esi, edi
294 diamond 554
           jb  @B
164 serge 555
 
556
           jmp .update_size
557
.exit:
558
           xor eax, eax
559
           inc eax
560
           dec [pg_data.pg_mutex]
561
           ret
562
endp
563
 
294 diamond 564
update_mem_size:
565
; in: edx = slot shl 8
566
;     ebx = new memory size
567
; destroys eax,ecx,edx
568
 
380 serge 569
           mov    [SLOT_BASE+APPDATA.mem_size+edx],ebx
294 diamond 570
;search threads and update
571
;application memory size infomation
380 serge 572
           mov    ecx,[SLOT_BASE+APPDATA.dir_table+edx]
294 diamond 573
           mov    eax,2
574
 
575
.search_threads:
576
;eax = current slot
577
;ebx = new memory size
578
;ecx = page directory
579
           cmp    eax,[TASK_COUNT]
580
           jg     .search_threads_end
581
           mov    edx,eax
582
           shl    edx,5
583
           cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
584
           jz     .search_threads_next
585
           shl    edx,3
380 serge 586
           cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
294 diamond 587
           jnz    .search_threads_next
380 serge 588
           mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
294 diamond 589
.search_threads_next:
590
           inc    eax
591
           jmp    .search_threads
592
.search_threads_end:
593
           ret
594
 
285 serge 595
; param
596
;  eax= linear address
597
;
598
; retval
599
;  eax= phisical page address
600
 
164 serge 601
align 4
285 serge 602
get_pg_addr:
603
           shr eax, 12
365 serge 604
           mov eax, [page_tabs+eax*4]
164 serge 605
           and eax, 0xFFFFF000
606
           ret
607
 
188 serge 608
align 4
164 serge 609
proc page_fault_handler
610
           pushad
611
 
612
           mov ebp, esp
613
           mov eax, cr2
172 serge 614
           push eax
164 serge 615
           push ds
188 serge 616
           push es
164 serge 617
 
618
           mov ax, 0x10
619
           mov ds, ax
188 serge 620
           mov es, ax
164 serge 621
 
188 serge 622
           inc [pg_data.pages_faults]
623
 
164 serge 624
           mov ebx, [ebp-4]
625
 
378 serge 626
           cmp ebx, 0x80000000
164 serge 627
           jae .user_space
628
 
378 serge 629
           cmp ebx, app_page_tabs
188 serge 630
           jae .alloc
631
 
378 serge 632
           cmp ebx, page_tabs
164 serge 633
           jae .tab_space
634
 
378 serge 635
           cmp ebx, 0x7DC00000
636
           jae .lfb_addr
637
 
164 serge 638
           jmp .kernel_space
639
 
640
.user_space:
641
           shr ebx, 12
172 serge 642
           mov ecx, ebx
643
           shr ecx, 10
644
           mov edx, [master_tab+ecx*4]
645
           test edx, 1
646
           jz .fail
647
 
365 serge 648
           mov eax, [page_tabs+ebx*4]
164 serge 649
           test eax, 2
172 serge 650
           jz .fail
188 serge 651
.alloc:
164 serge 652
           call alloc_page
653
           and eax, eax
654
           jz .exit
655
 
656
           stdcall map_page,[ebp-4],eax,dword PG_UW
657
 
188 serge 658
           mov edi, [ebp-4]
659
           and edi, 0xFFFFF000
164 serge 660
           mov ecx, 1024
661
           xor eax, eax
188 serge 662
           cld
663
           rep stosd
164 serge 664
.exit:
188 serge 665
           pop es
164 serge 666
           pop ds
667
           mov esp, ebp
668
           popad
669
           add esp, 4
670
           iretd
172 serge 671
.fail:
188 serge 672
           pop es
172 serge 673
           pop ds
674
           mov esp, ebp
675
           popad
676
           add esp, 4
164 serge 677
 
172 serge 678
           save_ring3_context     ;debugger support
679
 
680
           mov bl, 14
681
           jmp exc_c
682
           iretd
683
 
164 serge 684
.kernel_space:
188 serge 685
;           shr ebx, 12
365 serge 686
;           mov eax, [page_tabs+ebx*4]
188 serge 687
;           shr ebx, 10
688
;           mov eax, [master_tab+ebx*4]
689
           jmp .exit
164 serge 690
.old_addr:
188 serge 691
;           shr ebx, 12
365 serge 692
;           mov eax, [page_tabs+ebx*4]
188 serge 693
;           shr ebx, 10
694
;           mov eax, [master_tab+ebx*4]
695
           jmp .exit
164 serge 696
.lfb_addr:
188 serge 697
;           shr ebx, 22
698
;           ;mov ecx, [sys_page_dir]
699
;           mov eax, [master_tab+ebx*4]
700
           jmp .exit
164 serge 701
.tab_space:
188 serge 702
;           shr ebx, 12
365 serge 703
;           mov eax, [page_tabs+ebx*4]
188 serge 704
;           shr ebx, 10
705
;           ;mov ecx, [sys_page_dir]
706
;           mov eax, [master_tab+ebx*4]
707
           jmp .exit
164 serge 708
endp
709
 
710
align 4
711
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
712
                      ofs:dword,buf_size:dword
713
           mov eax, [buf_size]
714
           test eax, eax
715
           jz .exit
716
 
717
           mov eax, [pdir]
718
           and eax, 0xFFFFF000
719
 
720
           stdcall map_page,[ipc_pdir],eax,dword PG_UW
721
           mov ebx, [ofs]
722
           shr ebx, 22
723
           mov esi, [ipc_pdir]
724
           mov edi, [ipc_ptab]
725
           mov eax, [esi+ebx*4]
726
           and eax, 0xFFFFF000
727
           test eax, eax
728
           jz .exit
729
           stdcall map_page,edi,eax,dword PG_UW
730
;           inc ebx
731
;           add edi, 0x1000
732
;           mov eax, [esi+ebx*4]
733
;           test eax, eax
734
;           jz @f
735
;          and eax, 0xFFFFF000
736
;           stdcall map_page, edi, eax
737
 
738
@@:        mov edi, [lin_addr]
739
           and edi, 0xFFFFF000
740
           mov ecx, [buf_size]
741
           add ecx, 4095
742
           shr ecx, 12
743
           inc ecx
744
 
745
           mov edx, [ofs]
746
           shr edx, 12
747
           and edx, 0x3FF
748
           mov esi, [ipc_ptab]
749
 
750
.map:      mov eax, [esi+edx*4]
751
           and eax, 0xFFFFF000
752
           test eax, eax
753
           jz .exit
754
           stdcall map_page,edi,eax,dword PG_UW
755
           add edi, 0x1000
756
           inc edx
757
           dec ecx
758
           jnz .map
759
 
760
.exit:
761
           ret
762
endp
763
 
764
align 4
765
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
766
                        ofs:dword,buf_size:dword
767
           mov eax, [buf_size]
768
           test eax, eax
769
           jz .exit
770
 
771
           mov eax, [pdir]
772
           and eax, 0xFFFFF000
773
 
774
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
775
           mov ebx, [ofs]
776
           shr ebx, 22
777
           mov esi, [proc_mem_pdir]
778
           mov edi, [proc_mem_tab]
779
           mov eax, [esi+ebx*4]
780
           and eax, 0xFFFFF000
781
           test eax, eax
782
           jz .exit
783
           stdcall map_page,edi,eax,dword PG_UW
784
 
785
@@:        mov edi, [lin_addr]
786
           and edi, 0xFFFFF000
787
           mov ecx, [buf_size]
788
           add ecx, 4095
789
           shr ecx, 12
790
           inc ecx
791
 
792
           mov edx, [ofs]
793
           shr edx, 12
794
           and edx, 0x3FF
795
           mov esi, [proc_mem_tab]
796
 
797
.map:      mov eax, [esi+edx*4]
798
;           and eax, 0xFFFFF000
799
;           test eax, eax
800
;           jz .exit
801
           stdcall map_page,edi,eax,dword PG_UW
802
           add edi, 0x1000
803
           inc edx
804
           dec ecx
805
           jnz .map
806
.exit:
807
           ret
808
endp
809
 
810
 
811
 
812
 
813
sys_IPC:
814
;input:
815
;  eax=1 - set ipc buffer area
816
;    ebx=address of buffer
817
;    ecx=size of buffer
818
;  eax=2 - send message
819
;    ebx=PID
820
;    ecx=address of message
821
;    edx=size of message
822
 
823
           cmp  eax,1
824
           jne @f
825
           call set_ipc_buff
826
           mov [esp+36], eax
827
           ret
828
@@:
829
           cmp eax, 2
830
           jne @f
831
           stdcall sys_ipc_send, ebx, ecx, edx
832
           mov [esp+36], eax
833
           ret
834
@@:
835
           xor eax, eax
836
           not eax
837
           mov [esp+36], eax
838
           ret
839
 
840
align 4
841
proc set_ipc_buff
842
 
843
           mov  eax,[CURRENT_TASK]
844
           shl  eax,8
380 serge 845
           add  eax, SLOT_BASE
164 serge 846
           pushf
847
           cli
848
           mov  [eax+0xA0],ebx     ;set fields in extended information area
849
           mov  [eax+0xA4],ecx
850
 
851
           add ebx,  new_app_base
852
           add ecx, ebx
853
           add ecx, 4095
854
           and ecx, not 4095
855
 
856
.touch:    mov eax, [ebx]
857
           add ebx, 0x1000
858
           cmp ebx, ecx
859
           jna .touch
860
 
861
           popf
862
           xor eax, eax
863
           ret
864
endp
865
 
866
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
867
           locals
868
             dst_slot   dd ?
869
             dst_offset dd ?
870
             buf_size   dd ?
871
           endl
872
 
873
           pushf
874
           cli
875
 
876
           mov  eax, [PID]
877
           call pid_to_slot
878
           test eax,eax
879
           jz   .no_pid
880
 
881
           mov [dst_slot], eax
882
           shl  eax,8
380 serge 883
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
164 serge 884
           test edi,edi
885
           jz   .no_ipc_area
886
 
887
           mov ebx, edi
888
           add edi, new_app_base
889
           and ebx, 0xFFF
890
           mov [dst_offset], ebx
891
 
380 serge 892
           mov esi, [eax+SLOT_BASE+0xa4]
164 serge 893
           mov [buf_size], esi
894
 
380 serge 895
           stdcall map_mem, [ipc_tmp], [SLOT_BASE+eax+0xB8],\
164 serge 896
                             edi, esi
897
 
898
           mov edi, [dst_offset]
899
           add edi, [ipc_tmp]
900
           cmp dword [edi], 0
901
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
227 serge 902
 
164 serge 903
           mov ebx, dword [edi+4]
904
           mov edx, ebx
905
           add ebx, 8
906
           add ebx, [msg_size]
907
           cmp ebx, [buf_size]
908
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
227 serge 909
 
164 serge 910
           mov dword [edi+4], ebx
911
           mov eax,[TASK_BASE]
912
           mov eax, [eax+0x04]         ;eax - our PID
913
           mov edi, [dst_offset]
914
           add edi, [ipc_tmp]
915
           add edi, edx
916
           mov [edi], eax
917
           mov ecx, [msg_size]
918
 
919
           mov [edi+4], ecx
920
           add edi, 8
921
           mov esi, [msg_addr]
922
           add esi, new_app_base
923
           cld
924
           rep movsb
925
 
926
           mov ebx, [ipc_tmp]
927
           mov edx, ebx
928
           shr ebx, 12
929
           xor eax, eax
365 serge 930
           mov [page_tabs+ebx*4], eax
164 serge 931
           invlpg [edx]
932
 
933
           mov ebx, [ipc_pdir]
934
           mov edx, ebx
935
           shr ebx, 12
936
           xor eax, eax
365 serge 937
           mov [page_tabs+ebx*4], eax
164 serge 938
           invlpg [edx]
939
 
940
           mov ebx, [ipc_ptab]
941
           mov edx, ebx
942
           shr ebx, 12
943
           xor eax, eax
365 serge 944
           mov [page_tabs+ebx*4], eax
164 serge 945
           invlpg [edx]
946
 
947
           mov  eax, [dst_slot]
948
           shl eax, 8
380 serge 949
           or   [eax+SLOT_BASE+0xA8],dword 0x40
164 serge 950
           cmp  dword [check_idle_semaphore],20
951
           jge  .ipc_no_cis
952
 
953
           mov  dword [check_idle_semaphore],5
954
.ipc_no_cis:
955
           popf
956
           xor eax, eax
957
           ret
958
.no_pid:
959
           popf
960
           mov  eax, 4
961
           ret
962
.no_ipc_area:
963
           popf
964
           xor eax, eax
965
           inc eax
966
           ret
967
.ipc_blocked:
968
           popf
969
           mov  eax, 2
970
           ret
971
.buffer_overflow:
972
           popf
973
           mov  eax, 3
974
           ret
975
endp
976
 
977
align 4
170 serge 978
sysfn_meminfo:
164 serge 979
 
170 serge 980
           add ebx, new_app_base
172 serge 981
           cmp ebx, new_app_base
982
           jb .fail
983
 
164 serge 984
           mov eax, [pg_data.pages_count]
170 serge 985
           mov [ebx], eax
172 serge 986
           shl eax, 12
987
           mov [esp+36], eax
170 serge 988
           mov ecx, [pg_data.pages_free]
989
           mov [ebx+4], ecx
990
           mov edx, [pg_data.pages_faults]
991
           mov [ebx+8], edx
992
           mov esi, [heap_size]
993
           mov [ebx+12], esi
994
           mov edi, [heap_free]
995
           mov [ebx+16], edi
996
           mov eax, [heap_blocks]
997
           mov [ebx+20], eax
998
           mov ecx, [free_blocks]
999
           mov [ebx+24], ecx
164 serge 1000
           ret
172 serge 1001
.fail:
1002
           mov dword [esp+36], -1
1003
           ret
164 serge 1004
 
1005
align 4
1006
new_services:
1007
 
1008
           cmp  eax,4
1009
           jle  sys_sheduler
1010
 
170 serge 1011
           cmp eax, 11
164 serge 1012
           jb .fail
1013
           ja @f
1014
 
188 serge 1015
           call init_heap
164 serge 1016
           mov [esp+36], eax
1017
           ret
1018
@@:
1019
           cmp eax, 12
1020
           ja @f
1021
 
1022
           stdcall user_alloc, ebx
1023
           mov [esp+36], eax
1024
           ret
1025
@@:
1026
           cmp eax, 13
1027
           ja @f
188 serge 1028
           add ebx, new_app_base
164 serge 1029
           stdcall user_free, ebx
1030
           mov [esp+36], eax
1031
           ret
1032
@@:
1033
           cmp eax, 14
1034
           ja @f
227 serge 1035
           add ebx, new_app_base
172 serge 1036
           cmp ebx, new_app_base
1037
           jb .fail
227 serge 1038
           stdcall get_event_ex, ebx, ecx
1039
           mov [esp+36], eax
164 serge 1040
           ret
1041
@@:
1042
           cmp eax, 15
1043
           ja @f
1044
           mov ecx, [CURRENT_TASK]
1045
           shl ecx, 8
380 serge 1046
           mov eax, [ecx+SLOT_BASE+APPDATA.fpu_handler]
1047
           mov [ecx+SLOT_BASE+APPDATA.fpu_handler], ebx
164 serge 1048
           mov [esp+36], eax
1049
           ret
1050
@@:
1051
           cmp eax, 16
1052
           ja @f
1053
 
188 serge 1054
           test ebx, ebx
1055
           jz .fail
164 serge 1056
           add ebx, new_app_base
172 serge 1057
           cmp ebx, new_app_base
1058
           jb .fail
164 serge 1059
           stdcall get_service, ebx
1060
           mov [esp+36], eax
1061
           ret
1062
@@:
1063
           cmp eax, 17
1064
           ja @f
378 serge 1065
           call srv_handlerEx   ;ebx
164 serge 1066
           mov [esp+36], eax
1067
           ret
168 serge 1068
@@:
1069
           cmp eax, 18
1070
           ja @f
1071
           mov ecx, [CURRENT_TASK]
1072
           shl ecx, 8
380 serge 1073
           mov eax, [ecx+SLOT_BASE+APPDATA.sse_handler]
1074
           mov [ecx+SLOT_BASE+APPDATA.sse_handler], ebx
168 serge 1075
           mov [esp+36], eax
1076
           ret
164 serge 1077
@@:
198 serge 1078
           cmp eax, 19
227 serge 1079
           ja .fail
198 serge 1080
           add ebx, new_app_base
1081
           cmp ebx, new_app_base
1082
           jb .fail
1083
           stdcall load_library, ebx
1084
           mov [esp+36], eax
1085
           ret
227 serge 1086
 
164 serge 1087
.fail:
1088
           xor eax, eax
1089
           mov [esp+36], eax
1090
           ret
1091
 
1092
align 4
1093
proc strncmp stdcall, str1:dword, str2:dword, count:dword
1094
 
1095
          mov ecx,[count]
1096
          jecxz .end
1097
 
1098
          mov ebx,ecx
1099
 
1100
          mov edi,[str1]
1101
          mov esi,edi
1102
          xor eax,eax
1103
          repne scasb
1104
          neg ecx             ; cx = count - strlen
1105
          add ecx,ebx         ; strlen + count - strlen
1106
 
1107
.okay:
1108
          mov edi,esi
1109
          mov esi,[str2]
1110
          repe cmpsb
1111
          mov al,[esi-1]
1112
          xor ecx,ecx
1113
 
1114
          cmp al,[edi-1]
1115
          ja .str2_big
1116
          je .end
1117
 
1118
.str1_big:
1119
          sub ecx,2
1120
 
1121
.str2_big:
1122
          not ecx
1123
.end:
1124
          mov eax,ecx
1125
          ret
1126
endp
1127
 
1128
align 4
1129
proc test_cpu
1130
           locals
166 serge 1131
              cpu_type   dd ?
1132
              cpu_id     dd ?
1133
              cpu_Intel  dd ?
1134
              cpu_AMD    dd ?
164 serge 1135
           endl
1136
 
1137
           mov [cpu_type], 0
211 serge 1138
           xor eax, eax
1139
           mov [cpu_caps], eax
1140
           mov [cpu_caps+4], eax
164 serge 1141
 
1142
           pushfd
1143
           pop eax
1144
           mov ecx, eax
1145
           xor eax, 0x40000
1146
           push eax
1147
           popfd
1148
           pushfd
1149
           pop eax
1150
           xor eax, ecx
1151
           mov [cpu_type], CPU_386
221 serge 1152
           jz .end_cpuid
164 serge 1153
           push ecx
1154
           popfd
1155
 
1156
           mov [cpu_type], CPU_486
1157
           mov eax, ecx
1158
           xor eax, 0x200000
1159
           push eax
1160
           popfd
1161
           pushfd
1162
           pop eax
1163
           xor eax, ecx
221 serge 1164
           je .end_cpuid
164 serge 1165
           mov [cpu_id], 1
1166
 
1167
           xor eax, eax
1168
           cpuid
1169
           mov [cpu_vendor], ebx
1170
           mov [cpu_vendor+4], edx
1171
           mov [cpu_vendor+8], ecx
1172
           cmp ebx, dword [intel_str]
1173
           jne .check_AMD
1174
           cmp edx, dword [intel_str+4]
1175
           jne .check_AMD
1176
           cmp ecx, dword [intel_str+8]
1177
           jne .check_AMD
1178
           mov [cpu_Intel], 1
1179
           cmp eax, 1
1180
           jl .end_cpuid
1181
           mov eax, 1
1182
           cpuid
1183
           mov [cpu_sign], eax
1184
           mov [cpu_info],  ebx
1185
           mov [cpu_caps],  edx
1186
           mov [cpu_caps+4],ecx
1187
 
1188
           shr eax, 8
1189
           and eax, 0x0f
1190
           ret
1191
.end_cpuid:
1192
           mov eax, [cpu_type]
1193
           ret
1194
 
1195
.check_AMD:
1196
           cmp ebx, dword [AMD_str]
221 serge 1197
           jne .unknown
164 serge 1198
           cmp edx, dword [AMD_str+4]
221 serge 1199
           jne .unknown
164 serge 1200
           cmp ecx, dword [AMD_str+8]
221 serge 1201
           jne .unknown
164 serge 1202
           mov [cpu_AMD], 1
1203
           cmp eax, 1
221 serge 1204
           jl .unknown
164 serge 1205
           mov eax, 1
1206
           cpuid
1207
           mov [cpu_sign], eax
1208
           mov [cpu_info],  ebx
1209
           mov [cpu_caps],  edx
1210
           mov [cpu_caps+4],ecx
1211
           shr eax, 8
1212
           and eax, 0x0f
1213
           ret
221 serge 1214
.unknown:
1215
           mov eax, 1
1216
           cpuid
1217
           mov [cpu_sign], eax
1218
           mov [cpu_info],  ebx
1219
           mov [cpu_caps],  edx
1220
           mov [cpu_caps+4],ecx
1221
           shr eax, 8
1222
           and eax, 0x0f
1223
           ret
164 serge 1224
endp
1225
 
1226
MEM_WB     equ 6               ;write-back memory
1227
MEM_WC     equ 1               ;write combined memory
1228
MEM_UC     equ 0               ;uncached memory
1229
 
1230
align 4
1231
proc init_mtrr
1232
 
412 serge 1233
           cmp [BOOT_VAR+0x901c],byte 2
164 serge 1234
           je  .exit
1235
 
211 serge 1236
           bt [cpu_caps], CAPS_MTRR
1237
           jnc .exit
1238
 
164 serge 1239
           mov eax, cr0
1240
           or eax, 0x60000000   ;disable caching
1241
           mov cr0, eax
1242
           wbinvd               ;invalidate cache
1243
 
1244
           mov ecx, 0x2FF
1245
           rdmsr                ;
1246
           push eax
1247
 
1248
           xor edx, edx
1249
           xor eax, eax
1250
           mov ecx, 0x2FF
1251
           wrmsr                ;disable all MTRR
1252
 
1253
           stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
1254
           stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
1255
           xor edx, edx
1256
           xor eax, eax
1257
           mov ecx, 0x204
1258
           mov ebx, 6
1259
@@:
1260
           wrmsr                ;disable unused MTRR
1261
           inc ecx
1262
           wrmsr
1263
           inc ecx
1264
           dec ebx
1265
           jnz @b
1266
 
1267
           wbinvd               ;again invalidate
1268
 
1269
           pop eax
1270
           or eax, 0x800        ;set default memtype to UC
1271
           and al, 0xF0
1272
           mov ecx, 0x2FF
1273
           wrmsr                ;and enable MTRR
1274
 
1275
           mov eax, cr0
1276
           and eax, not 0x60000000
1277
           mov cr0, eax         ; enable caching
1278
.exit:
1279
           ret
1280
endp
1281
 
1282
align 4
1283
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
1284
 
1285
           xor edx, edx
1286
           mov eax, [base]
1287
           or eax, [mem_type]
1288
           mov ecx, [reg]
1289
           lea ecx, [0x200+ecx*2]
1290
           wrmsr
1291
 
1292
           mov ebx, [size]
1293
           dec ebx
1294
           mov eax, 0xFFFFFFFF
1295
           mov edx, 0x0000000F
1296
           sub eax, ebx
1297
           sbb edx, 0
1298
           or eax, 0x800
1299
           inc ecx
1300
           wrmsr
1301
           ret
1302
endp
1303
 
172 serge 1304
align 4
1305
proc stall stdcall, delay:dword
1306
           push ecx
1307
           push edx
1308
           push ebx
1309
           push eax
1310
 
1311
           mov eax, [delay]
1312
           mul [stall_mcs]
1313
           mov ebx, eax       ;low
1314
           mov ecx, edx       ;high
1315
           rdtsc
1316
           add ebx, eax
1317
           adc ecx,edx
1318
@@:
1319
           rdtsc
1320
           sub eax, ebx
1321
           sbb edx, ecx
1322
           jb @B
1323
 
1324
           pop eax
1325
           pop ebx
1326
           pop edx
1327
           pop ecx
1328
           ret
1329
endp
1330
 
164 serge 1331
iglobal
1332
align 4
1333
  intel_str    db "GenuineIntel",0
1334
  AMD_str      db "AuthenticAMD",0
1335
endg
1336
 
1337
uglobal
1338
align 16
1339
  irq_tab           rd 16
1340
 
1341
  MEM_FreeSpace     rd 1
1342
 
1343
  ipc_tmp           rd 1
1344
  ipc_pdir          rd 1
1345
  ipc_ptab          rd 1
1346
 
1347
  proc_mem_map      rd 1
1348
  proc_mem_pdir     rd 1
1349
  proc_mem_tab      rd 1
1350
 
1351
  tmp_task_pdir     rd 1
1352
  tmp_task_ptab     rd 1
1353
 
1354
  fdd_buff          rd 1
214 serge 1355
  LFBSize           rd 1
164 serge 1356
 
172 serge 1357
  stall_mcs         rd 1
164 serge 1358
;;CPUID information
1359
 
1360
  cpu_vendor        rd 3
1361
  cpu_sign          rd 1
1362
  cpu_info          rd 1
1363
 
221 serge 1364
;;;;;   cursors data
1365
 
1366
align 16
1367
cur_saved_data   rb 4096
1368
 
1369
def_cursor       rd 1
233 serge 1370
hw_cursor        rd 1
221 serge 1371
 
1372
scr_width        rd 1
1373
scr_height       rd 1
1374
 
1375
cur_def_interl   rd 1
1376
cur_saved_base   rd 1
1377
cur_saved_interl rd 1
1378
cur_saved_w      rd 1
1379
cur_saved_h      rd 1
1380
 
164 serge 1381
endg
1382
 
1383
uglobal
1384
align 16
357 serge 1385
   fpu_data:
1386
                   rb 512
227 serge 1387
 
276 serge 1388
   mst MEM_STATE
1389
 
227 serge 1390
   mem_block_map   rb 512
354 serge 1391
   event_map       rb 64
227 serge 1392
   mem_block_list  rd 64
1393
   mem_block_mask  rd 2
1394
 
278 serge 1395
   srv.fd          rd 1
1396
   srv.bk          rd 1
1397
 
357 serge 1398
   mem_used.fd     rd 1
1399
   mem_used.bk     rd 1
1400
 
164 serge 1401
   mem_block_arr   rd 1
1402
   mem_block_start rd 1
1403
   mem_block_end   rd 1
279 serge 1404
 
1405
   heap_mutex      rd 1
170 serge 1406
   heap_size       rd 1
1407
   heap_free       rd 1
1408
   heap_blocks     rd 1
1409
   free_blocks     rd 1
164 serge 1410
 
1411
   page_start      rd 1
1412
   page_end        rd 1
227 serge 1413
   events          rd 1
1414
   event_start     rd 1
1415
   event_end       rd 1
354 serge 1416
   event_uid       rd 1
164 serge 1417
   sys_page_map    rd 1
357 serge 1418
   os_stack        rd 1
164 serge 1419
endg
1420
 
328 serge 1421
if 0
1422
     push eax
1423
     push edx
1424
     mov edx, 0x400   ;bocsh
1425
     mov al,0xff      ;bocsh
1426
     out dx, al       ;bocsh
1427
     pop edx
1428
     pop eax
1429
end if
164 serge 1430
 
237 serge 1431
align 4
1432
k_strrchr:
1433
        push eax
1434
        xor eax,eax
1435
        or  ecx,-1
1436
        repne scasb
1437
        add ecx,1
1438
        neg ecx
1439
        sub edi,1
1440
        pop eax
1441
        std
1442
        repne scasb
1443
        cld
1444
        add edi,1
1445
 
1446
        cmp [edi],al
1447
        jne @F
1448
        mov eax,edi
1449
        ret
1450
@@:
1451
        xor eax,eax
1452
        ret
1453
 
1454
align 4
1455
proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword
1456
        mov eax, [dest]
1457
        mov esi, [src]
1458
        mov ecx, [maxlen]
1459
        test eax, eax
1460
        jz .L9
1461
        test esi, esi
1462
        jz .L9
1463
        test ecx, ecx
1464
        jz .L9
1465
 
1466
        sub  esi, eax
1467
        jmp .L1
1468
 
1469
align 4
1470
.L2:
1471
        mov edx, [esi+eax]
1472
        mov [eax], dl
1473
        test dl, dl
1474
        jz .L7
1475
 
1476
        mov [eax+1], dh
1477
        test dh, dh
1478
        jz .L6
1479
 
1480
        shr edx, 16
1481
        mov [eax+2],dl
1482
        test dl, dl
1483
        jz .L5
1484
 
1485
        mov [eax+3], dh
1486
        test dh, dh
1487
        jz .L4
1488
        add eax, 4
1489
.L1:
1490
        sub ecx, 4
1491
        jae .L2
1492
 
1493
        add ecx, 4
1494
        jz .L9
1495
 
1496
        mov dl, [eax+esi]
1497
        mov [eax], dl
1498
        test dl, dl
1499
        jz .L3
1500
 
1501
        inc eax
1502
        dec ecx
1503
        jz .L9
1504
 
1505
        mov dl, [eax+esi]
1506
        mov [eax], dl
1507
        test dl, dl
1508
        jz .L3
1509
 
1510
        inc eax
1511
        dec ecx
1512
        jz .L9
1513
 
1514
        mov dl, [eax+esi]
1515
        mov [eax], dl
1516
        test dl, dl
1517
        jz .L3
1518
 
1519
        inc eax
1520
        jmp .L9
1521
 
1522
.L4:    dec ecx
1523
        inc eax
1524
 
1525
.L5:    dec ecx
1526
        inc eax
1527
 
1528
.L6:    dec ecx
1529
        inc eax
1530
.L7:
1531
        add ecx,3
1532
        jz .L9
1533
.L8:
1534
        mov byte [ecx+eax], 0
1535
.L3:
1536
        dec ecx
1537
        jnz .L8
1538
.L9:
1539
	ret
1540
endp
1541
 
1542
if 0
1543
 
1544
magic equ 0xfefefeff
1545
 
1546
k_strlen:
1547
        mov eax,[esp+4]
1548
        mov edx, 3
1549
 
1550
        and edx, eax
1551
        jz .L1
1552
        jp .L0
1553
 
1554
        cmp dh, byte [eax]
1555
        je .L2
1556
 
1557
        inc eax
1558
        cmp dh, byte [eax]
1559
 
1560
        je .L2
1561
 
1562
        inc eax
1563
        xor edx, 2
1564
 
1565
        jz .L1
1566
.L0:
1567
        cmp dh, [eax]
1568
        je .L2
1569
 
1570
        inc eax
1571
        xor edx, edx
1572
 
1573
.L1:
1574
        mov ecx, [eax]
1575
        add eax, 4
1576
 
1577
        sub edx, ecx
1578
        add ecx, magic
1579
 
1580
        dec edx
1581
        jnc .L3
1582
 
1583
        xor edx, ecx
1584
        and edx, not magic
1585
        jne .L3
1586
 
1587
        mov ecx, [eax]
1588
        add eax, 4
1589
 
1590
        sub edx, ecx
1591
        add ecx, magic
1592
        dec edx
1593
        jnc .L3
1594
 
1595
        xor edx, ecx
1596
        and edx, not magic
1597
        jne .L3
1598
 
1599
        mov ecx, [eax]
1600
        add eax, 4
1601
 
1602
        sub edx, ecx
1603
        add ecx, magic
1604
 
1605
        dec edx
1606
        jnc .L3
1607
 
1608
        xor edx, ecx
1609
 
1610
        and edx, not magic
1611
        jne .L3
1612
 
1613
        mov ecx, [eax]
1614
        add eax, 4
1615
 
1616
        sub edx, ecx
1617
        add ecx, magic
1618
 
1619
        dec edx
1620
        jnc .L3
1621
 
1622
        xor edx, ecx
1623
 
1624
        and edx, not magic
1625
        je .L1
1626
 
1627
.L3:    sub eax ,4
1628
        sub ecx, magic
1629
 
1630
        cmp cl, 0
1631
        jz .L2
1632
 
1633
        inc eax
1634
        test ch, ch
1635
        jz .L2
1636
 
1637
        shr ecx, 16
1638
        inc eax
1639
 
1640
        cmp cl,0
1641
        jz .L2
1642
 
1643
        inc eax
1644
 
1645
.L2:
1646
        sub eax, [esp+4]
1647
	ret
1648
 
1649
end if