Subversion Repositories Kolibri OS

Rev

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

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