Subversion Repositories Kolibri OS

Rev

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

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