Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;                                                              ;;
7
;; System service for filesystem call                           ;;
8
;; (C) 2004 Ville Turjanmaa, License: GPL                       ;;
9
;; 29.04.2006 Elimination of hangup after the                   ;;
10
;;            expiration hd_wait_timeout (for LBA) -  Mario79   ;;
11
;; 15.01.2005 get file size/attr/date,                          ;;
12
;;            file_append (only for hd) - ATV                   ;;
13
;; 23.11.2004 test if hd/partition is set - ATV                 ;;
14
;; 18.11.2004 get_disk_info and more error codes - ATV          ;;
15
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV       ;;
16
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV             ;;
17
;;                                                              ;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
 
20
$Revision: 2455 $
21
 
22
 
23
iglobal
24
dir0:
25
             db  'HARDDISK   '
26
             db  'RAMDISK    '
27
             db  'FLOPPYDISK '
28
             db  0
29
 
30
dir1:
31
             db  'FIRST      '
32
             db  'SECOND     '
33
             db  'THIRD      '
34
             db  'FOURTH     '
35
             db  0
36
 
37
not_select_IDE db 0
38
 
39
hd_address_table:
40
                   dd  0x1f0,0x00,0x1f0,0x10
41
                   dd  0x170,0x00,0x170,0x10
42
endg
43
 
44
file_system:
45
 
46
; IN:
47
;
48
; eax = 0  ; read file          /RamDisk/First  6
49
; eax = 8  ; lba read
50
; eax = 15 ; get_disk_info
51
;
52
; OUT:
53
;
54
; eax = 0  : read ok
55
; eax = 1  : no hd base and/or partition defined
56
; eax = 2  : function is unsupported for this FS
57
; eax = 3  : unknown FS
58
; eax = 4  : partition not defined at hd
59
; eax = 5  : file not found
60
; eax = 6  : end of file
61
; eax = 7  : memory pointer not in application area
62
; eax = 8  : disk full
63
; eax = 9  : fat table corrupted
64
; eax = 10 : access denied
65
; eax = 11 : disk error
66
;
67
; ebx = size
68
 
69
; \begin{diamond}[18.03.2006]
70
; for subfunction 16 (start application) error codes must be negative
71
;    because positive values are valid PIDs
72
; so possible return values are:
73
; eax > 0 : process created, eax=PID
74
 
75
; -0x10 <= eax < 0 : -eax is filesystem error code:
76
; eax = -1  = 0xFFFFFFFF : no hd base and/or partition defined
77
; eax = -3  = 0xFFFFFFFD : unknown FS
78
; eax = -5  = 0xFFFFFFFB : file not found
79
; eax = -6  = 0xFFFFFFFA : unexpected end of file (probably not executable file)
80
; eax = -9  = 0xFFFFFFF7 : fat table corrupted
81
; eax = -10 = 0xFFFFFFF6 : access denied
82
 
83
; -0x20 <= eax < -0x10: eax is process creation error code:
84
; eax = -0x20 = 0xFFFFFFE0 : too many processes
85
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
86
; eax = -0x1E = 0xFFFFFFE2 : no memory
87
 
88
; ebx is not changed
89
 
90
; \end{diamond}[18.03.2006]
91
 
92
    ; Extract parameters
93
 ;   add    eax, std_application_base_address    ; abs start of info block
94
 
95
        cmp     dword [eax+0], 15; GET_DISK_INFO
96
        je      fs_info
97
 
98
        cmp     dword [CURRENT_TASK], 1; no memory checks for kernel requests
99
        jz      no_checks_for_kernel
100
        mov     edx, eax
101
        cmp     dword [eax+0], 1
102
        jnz     .usual_check
103
        mov     ebx, [eax+12]
104
 ;   add   ebx,std_application_base_address
105
        mov     ecx, [eax+8]
106
        call    check_region
107
        test    eax, eax
108
        jnz     area_in_app_mem
109
 
110
.error_output:
111
        mov     esi, buffer_failed
112
        call    sys_msg_board_str
113
;    mov   eax,7
114
        mov     dword [esp+36], 7
115
        ret
116
iglobal
117
  buffer_failed db 'K : Buffer check failed',13,10,0
118
endg
119
.usual_check:
120
        cmp     dword [eax+0], 0
121
        mov     ecx, 512
122
        jnz     .small_size
123
        mov     ecx, [eax+8]
124
        shl     ecx, 9
125
.small_size:
126
        mov     ebx, [eax+12]
127
 ;   add   ebx,std_application_base_address
128
        call    check_region
129
        test    eax, eax
130
        jz      .error_output
131
  area_in_app_mem:
132
        mov     eax, edx
133
  no_checks_for_kernel:
134
 
135
  fs_read:
136
 
137
        mov     ebx, [eax+20]   ; program wants root directory ?
138
        test    bl, bl
139
        je      fs_getroot
140
        test    bh, bh
141
        jne     fs_noroot
142
  fs_getroot:
143
; \begin{diamond}[18.03.2006]
144
; root - only read is allowed
145
; other operations return "access denied", eax=10
146
; (execute operation returns eax=-10)
147
        cmp     dword [eax], 0
148
        jz      .read_root
149
        mov     dword [esp+36], 10
150
        ret
151
.read_root:
152
; \end{diamond}[18.03.2006]
153
        mov     esi, dir0
154
        mov     edi, [eax+12]
155
 ;   add   edi,std_application_base_address
156
        mov     ecx, 11
157
        push    ecx
158
;    cld    ; already is
159
        rep movsb
160
        mov     al, 0x10
161
        stosb
162
        add     edi, 32-11-1
163
        pop     ecx
164
        rep movsb
165
        stosb
166
        and     dword [esp+36], 0; ok read
167
        mov     dword [esp+24], 32*2; size of root
168
        ret
169
 
170
  fs_info:                      ;start of code - Mihasik
171
        push    eax
172
        cmp     [eax+21], byte 'h'
173
        je      fs_info_h
174
        cmp     [eax+21], byte 'H'
175
        je      fs_info_h
176
        cmp     [eax+21], byte 'r'
177
        je      fs_info_r
178
        cmp     [eax+21], byte 'R'
179
        je      fs_info_r
180
        mov     eax, 3          ;if unknown disk
181
        xor     ebx, ebx
182
        xor     ecx, ecx
183
        xor     edx, edx
184
        jmp     fs_info1
185
  fs_info_r:
186
        call    ramdisk_free_space;if ramdisk
187
        mov     ecx, edi        ;free space in ecx
188
        shr     ecx, 9          ;free clusters
189
        mov     ebx, 2847       ;total clusters
190
        mov     edx, 512        ;cluster size
191
        xor     eax, eax        ;always 0
192
        jmp     fs_info1
193
  fs_info_h:                    ;if harddisk
194
        call    get_hd_info
195
  fs_info1:
196
        pop     edi
197
        mov     [esp+36], eax
198
        mov     [esp+24], ebx    ; total clusters on disk
199
        mov     [esp+32], ecx    ; free clusters on disk
200
        mov     [edi], edx       ; cluster size in bytes
201
        ret                      ;end of code - Mihasik
202
 
203
  fs_noroot:
204
 
205
        push    dword [eax+0]   ; read/write/delete/.../makedir/rename/lba/run
206
        push    dword [eax+4]   ; 512 block number to read
207
        push    dword [eax+8]   ; bytes to write/append or 512 blocks to read
208
        mov     ebx, [eax+12]
209
 ;   add   ebx,std_application_base_address
210
        push    ebx             ; abs start of return/save area
211
 
212
        lea     esi, [eax+20]   ; abs start of dir + filename
213
        mov     edi, [eax+16]
214
 ;   add   edi,std_application_base_address    ; abs start of work area
215
 
216
        call    expand_pathz
217
 
218
        push    edi             ; dir start
219
        push    ebx             ; name of file start
220
 
221
        mov     eax, [edi+1]
222
        cmp     eax, 'RD  '
223
        je      fs_yesramdisk
224
        cmp     eax, 'RAMD'
225
        jne     fs_noramdisk
226
 
227
  fs_yesramdisk:
228
 
229
        cmp     byte [edi+1+11], 0
230
        je      fs_give_dir1
231
 
232
        mov     eax, [edi+1+12]
233
        cmp     eax, '1   '
234
        je      fs_yesramdisk_first
235
        cmp     eax, 'FIRS'
236
        jne     fs_noramdisk
237
 
238
  fs_yesramdisk_first:
239
 
240
        cmp     dword [esp+20], 8; LBA read ramdisk
241
        jne     fs_no_LBA_read_ramdisk
242
 
243
        mov     eax, [esp+16]   ; LBA block to read
244
        mov     ecx, [esp+8]    ; abs pointer to return area
245
 
246
        call    LBA_read_ramdisk
247
        jmp     file_system_return
248
 
249
 
250
  fs_no_LBA_read_ramdisk:
251
 
252
        cmp     dword [esp+20], 0; READ
253
        jne     fs_noramdisk_read
254
 
255
        mov     eax, [esp+4]    ; fname
256
        add     eax, 2*12+1
257
        mov     ebx, [esp+16]   ; block start
258
        inc     ebx
259
        mov     ecx, [esp+12]   ; block count
260
        mov     edx, [esp+8]    ; return
261
        mov     esi, [esp+0]
262
        sub     esi, eax
263
        add     esi, 12+1       ; file name length
264
        call    fileread
265
 
266
        jmp     file_system_return
267
 
268
 
269
  fs_noramdisk_read:
270
  fs_noramdisk:
271
 
272
  ;********************************************************************
273
        mov     eax, [edi+1]
274
        cmp     eax, 'FD  '
275
        je      fs_yesflpdisk
276
        cmp     eax, 'FLOP'
277
        jne     fs_noflpdisk
278
 
279
  fs_yesflpdisk:
280
        call    reserve_flp
281
 
282
        cmp     byte [edi+1+11], 0
283
        je      fs_give_dir1
284
 
285
        mov     eax, [edi+1+12]
286
        cmp     eax, '1   '
287
        je      fs_yesflpdisk_first
288
        cmp     eax, 'FIRS'
289
        je      fs_yesflpdisk_first
290
        cmp     eax, '2   '
291
        je      fs_yesflpdisk_second
292
        cmp     eax, 'SECO'
293
        jne     fs_noflpdisk
294
        jmp     fs_yesflpdisk_second
295
 
296
  fs_yesflpdisk_first:
297
        mov     [flp_number], 1
298
        jmp     fs_yesflpdisk_start
299
  fs_yesflpdisk_second:
300
        mov     [flp_number], 2
301
  fs_yesflpdisk_start:
302
        cmp     dword [esp+20], 0; READ
303
        jne     fs_noflpdisk_read
304
 
305
        mov     eax, [esp+4]    ; fname
306
        add     eax, 2*12+1
307
        mov     ebx, [esp+16]   ; block start
308
        inc     ebx
309
        mov     ecx, [esp+12]   ; block count
310
        mov     edx, [esp+8]    ; return
311
        mov     esi, [esp+0]
312
        sub     esi, eax
313
        add     esi, 12+1       ; file name length
314
        call    floppy_fileread
315
 
316
        jmp     file_system_return
317
 
318
 
319
  fs_noflpdisk_read:
320
  fs_noflpdisk:
321
  ;*****************************************************************
322
 
323
        mov     eax, [edi+1]
324
        cmp     eax, 'HD0 '
325
        je      fs_yesharddisk_IDE0
326
        cmp     eax, 'HD1 '
327
        je      fs_yesharddisk_IDE1
328
        cmp     eax, 'HD2 '
329
        je      fs_yesharddisk_IDE2
330
        cmp     eax, 'HD3 '
331
        je      fs_yesharddisk_IDE3
332
        jmp     old_path_harddisk
333
fs_yesharddisk_IDE0:
334
        call    reserve_hd1
335
        mov     [hdbase], 0x1f0
336
        mov     [hdid], 0x0
337
        mov     [hdpos], 1
338
        jmp     fs_yesharddisk_partition
339
fs_yesharddisk_IDE1:
340
        call    reserve_hd1
341
        mov     [hdbase], 0x1f0
342
        mov     [hdid], 0x10
343
        mov     [hdpos], 2
344
        jmp     fs_yesharddisk_partition
345
fs_yesharddisk_IDE2:
346
        call    reserve_hd1
347
        mov     [hdbase], 0x170
348
        mov     [hdid], 0x0
349
        mov     [hdpos], 3
350
        jmp     fs_yesharddisk_partition
351
fs_yesharddisk_IDE3:
352
        call    reserve_hd1
353
        mov     [hdbase], 0x170
354
        mov     [hdid], 0x10
355
        mov     [hdpos], 4
356
fs_yesharddisk_partition:
357
        call    reserve_hd_channel
358
;    call  choice_necessity_partition
359
;    jmp   fs_yesharddisk_all
360
        jmp     fs_for_new_semantic
361
 
362
choice_necessity_partition:
363
        mov     eax, [edi+1+12]
364
        call    StringToNumber
365
        mov     [fat32part], eax
366
choice_necessity_partition_1:
367
        mov     ecx, [hdpos]
368
        xor     eax, eax
369
        mov     [hd_entries], eax; entries in hd cache
370
        mov     edx, DRIVE_DATA+2
371
        cmp     ecx, 0x80
372
        jb      search_partition_array
373
        mov     ecx, 4
374
 search_partition_array:
375
        mov     bl, [edx]
376
        movzx   ebx, bl
377
        add     eax, ebx
378
        inc     edx
379
        loop    search_partition_array
380
        mov     ecx, [hdpos]
381
        mov     edx, BiosDiskPartitions
382
        sub     ecx, 0x80
383
        jb      .s
384
        je      .f
385
 @@:
386
        mov     ebx, [edx]
387
        add     edx, 4
388
        add     eax, ebx
389
        loop    @b
390
        jmp     .f
391
 .s:
392
        sub     eax, ebx
393
 .f:
394
        add     eax, [known_part];   add   eax,[fat32part]
395
        dec     eax
396
        xor     edx, edx
397
        imul    eax, 100
398
        add     eax, DRIVE_DATA+0xa
399
        mov     [transfer_adress], eax
400
        call    partition_data_transfer_1
401
        ret
402
 
403
 old_path_harddisk:
404
        mov     eax, [edi+1]
405
        cmp     eax, 'HD  '
406
        je      fs_yesharddisk
407
        cmp     eax, 'HARD'
408
        jne     fs_noharddisk
409
 
410
  fs_yesharddisk:
411
        cmp     dword [esp+20], 8; LBA read
412
        jne     fs_no_LBA_read
413
        mov     eax, [esp+16]   ; LBA block to read
414
        lea     ebx, [edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
415
        mov     ecx, [esp+8]    ; abs pointer to return area
416
        call    LBA_read
417
        jmp     file_system_return
418
 
419
  fs_no_LBA_read:
420
 
421
        cmp     byte [edi+1+11], 0; directory read
422
        je      fs_give_dir1
423
        call    reserve_hd1
424
 fs_for_new_semantic:
425
        call    choice_necessity_partition
426
 
427
  fs_yesharddisk_all:
428
        mov     eax, 1
429
        mov     ebx, [esp+24+24]
430
        cmp     [hdpos], 0      ; is hd base set?
431
        jz      hd_err_return
432
        cmp     [fat32part], 0  ; is partition set?
433
        jnz     @f
434
hd_err_return:
435
        call    free_hd_channel
436
        and     [hd1_status], 0
437
        jmp     file_system_return
438
@@:
439
 
440
        cmp     dword [esp+20], 0; READ
441
        jne     fs_noharddisk_read
442
 
443
        mov     eax, [esp+0]    ; /fname
444
        lea     edi, [eax+12]
445
        mov     byte [eax], 0   ; path to asciiz
446
        inc     eax             ; filename start
447
 
448
        mov     ebx, [esp+12]   ; count to read
449
        mov     ecx, [esp+8]    ; buffer
450
        mov     edx, [esp+4]
451
        add     edx, 12*2       ; dir start
452
        sub     edi, edx        ; path length
453
        mov     esi, [esp+16]   ; blocks to read
454
 
455
        call    file_read
456
 
457
        mov     edi, [esp+0]
458
        mov     byte [edi], '/'
459
 
460
        call    free_hd_channel
461
        and     [hd1_status], 0
462
        jmp     file_system_return
463
 
464
  fs_noharddisk_read:
465
 
466
        call    free_hd_channel
467
        and     [hd1_status], 0
468
 
469
  fs_noharddisk:
470
; \begin{diamond}[18.03.2006]
471
        mov     eax, 5   ; file not found
472
; а может быть, возвращать другой код ошибки?
473
        mov     ebx, [esp+24+24]; do not change ebx in application
474
; \end{diamond}[18.03.2006]
475
 
476
  file_system_return:
477
 
478
        add     esp, 24
479
 
480
        mov     [esp+36], eax
481
        mov     [esp+24], ebx
482
        ret
483
 
484
 
485
  fs_give_dir1:
486
 
487
; \begin{diamond}[18.03.2006]
488
; /RD,/FD,/HD - only read is allowed
489
; other operations return "access denied", eax=10
490
; (execute operation returns eax=-10)
491
        cmp     dword [esp+20], 0
492
        jz      .read
493
        add     esp, 20
494
        pop     ecx
495
        mov     dword [esp+36], 10
496
        ret
497
.read:
498
; \end{diamond}[18.03.2006]
499
        mov     al, 0x10
500
        mov     ebx, 1
501
        mov     edi, [esp+8]
502
        mov     esi, dir1
503
  fs_d1_new:
504
        mov     ecx, 11
505
;    cld
506
        rep movsb
507
        stosb
508
        add     edi, 32-11-1
509
        dec     ebx
510
        jne     fs_d1_new
511
 
512
        add     esp, 24
513
 
514
        and     dword [esp+36], 0; ok read
515
        mov     dword [esp+24], 32*1; dir/data size
516
        ret
517
 
518
 
519
 
520
LBA_read_ramdisk:
521
 
522
        cmp     [lba_read_enabled], 1
523
        je      lbarrl1
524
 
525
        xor     ebx, ebx
526
        mov     eax, 2
527
        ret
528
 
529
  lbarrl1:
530
 
531
        cmp     eax, 18*2*80
532
        jb      lbarrl2
533
        xor     ebx, ebx
534
        mov     eax, 3
535
        ret
536
 
537
  lbarrl2:
538
 
539
        pushad
540
 
541
        call    restorefatchain
542
 
543
        mov     edi, ecx
544
        mov     esi, eax
545
 
546
        shl     esi, 9
547
        add     esi, RAMDISK
548
        mov     ecx, 512/4
549
;    cld
550
        rep movsd
551
 
552
        popad
553
 
554
        xor     ebx, ebx
555
        xor     eax, eax
556
        ret
557
 
558
LBA_read:
559
 
560
; IN:
561
;
562
; eax = LBA block to read
563
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
564
; ecx = abs pointer to return area
565
 
566
        cmp     [lba_read_enabled], 1
567
        je      lbarl1
568
        mov     eax, 2
569
        ret
570
 
571
  lbarl1:
572
 
573
        call    reserve_hd1
574
 
575
        push    eax
576
        push    ecx
577
 
578
        mov     edi, hd_address_table
579
        mov     esi, dir1
580
        mov     eax, [ebx]
581
        mov     edx, '1   '
582
        mov     ecx, 4
583
  blar0:
584
        cmp     eax, [esi]
585
        je      blar2
586
        cmp     eax, edx
587
        je      blar2
588
        inc     edx
589
        add     edi, 8
590
        add     esi, 11
591
        dec     ecx
592
        jnz     blar0
593
 
594
        mov     eax, 1
595
        mov     ebx, 1
596
        jmp     LBA_read_ret
597
 
598
  blar2:
599
        mov     eax, [edi+0]
600
        mov     ebx, [edi+4]
601
 
602
        mov     [hdbase], eax
603
        mov     [hdid], ebx
604
 
605
        call    wait_for_hd_idle
606
        cmp     [hd_error], 0
607
        jne     hd_lba_error
608
 
609
    ; eax = hd port
610
    ; ebx = set for primary (0x00) or slave (0x10)
611
 
612
        cli
613
 
614
        mov     edx, eax
615
        inc     edx
616
        xor     eax, eax
617
        out     dx, al
618
        inc     edx
619
        inc     eax
620
        out     dx, al
621
        inc     edx
622
        mov     eax, [esp+4]
623
        out     dx, al
624
        shr     eax, 8
625
        inc     edx
626
        out     dx, al
627
        shr     eax, 8
628
        inc     edx
629
        out     dx, al
630
        shr     eax, 8
631
        inc     edx
632
        and     al, 1+2+4+8
633
        add     al, bl
634
        add     al, 128+64+32
635
        out     dx, al
636
 
637
        inc     edx
638
        mov     al, 20h
639
        out     dx, al
640
 
641
        sti
642
 
643
        call    wait_for_sector_buffer
644
        cmp     [hd_error], 0
645
        jne     hd_lba_error
646
 
647
        cli
648
 
649
        mov     edi, [esp+0]
650
        mov     ecx, 256
651
        sub     edx, 7
652
        cld
653
        rep insw
654
 
655
        sti
656
 
657
        xor     eax, eax
658
        xor     ebx, ebx
659
 
660
  LBA_read_ret:
661
        mov     [hd_error], 0
662
        mov     [hd1_status], 0
663
        add     esp, 2*4
664
 
665
        ret
666
 
667
 
668
expand_pathz:
669
; IN:
670
;   esi = asciiz path & file
671
;   edi = buffer for path & file name
672
; OUT:
673
;   edi = directory & file : / 11 + / 11 + / 11 - zero terminated
674
;   ebx = /file name - zero terminated
675
;   esi = pointer after source
676
 
677
        push    eax
678
        push    ecx
679
        push    edi;[esp+0]
680
 
681
  pathz_start:
682
        mov     byte [edi], '/'
683
        inc     edi
684
        mov     al, 32
685
        mov     ecx, 11
686
        cld
687
        rep stosb               ; clear filename area
688
        sub     edi, 11
689
        mov     ebx, edi        ; start of dir/file name
690
 
691
  pathz_new_char:
692
        mov     al, [esi]
693
        inc     esi
694
        cmp     al, 0
695
        je      pathz_end
696
 
697
        cmp     al, '/'
698
        jne     pathz_not_path
699
        cmp     edi, ebx        ; skip first '/'
700
        jz      pathz_new_char
701
        lea     edi, [ebx+11]   ; start of next directory
702
        jmp     pathz_start
703
 
704
  pathz_not_path:
705
        cmp     al, '.'
706
        jne     pathz_not_ext
707
        lea     edi, [ebx+8]    ; start of extension
708
        jmp     pathz_new_char
709
 
710
  pathz_not_ext:
711
        cmp     al, 'a'
712
        jb      pathz_not_low
713
        cmp     al, 'z'
714
        ja      pathz_not_low
715
        sub     al, 0x20        ; char to uppercase
716
 
717
  pathz_not_low:
718
        mov     [edi], al
719
        inc     edi
720
        mov     eax, [esp+0]    ; start_of_dest_path
721
        add     eax, 512        ; keep maximum path under 512 bytes
722
        cmp     edi, eax
723
        jb      pathz_new_char
724
 
725
  pathz_end:
726
        cmp     ebx, edi        ; if path end with '/'
727
        jnz     pathz_put_zero  ; go back 1 level
728
        sub     ebx, 12
729
 
730
  pathz_put_zero:
731
        mov     byte [ebx+11], 0
732
        dec     ebx             ; include '/' char into file name
733
        pop     edi
734
        pop     ecx
735
        pop     eax
736
        ret
737
 
738
;*******************************************
739
;* string to number
740
;* input eax - 4 byte string
741
;* output eax - number
742
;*******************************************
743
StringToNumber:
744
;    ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД
745
;    Вход:
746
;        EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh
747
;    Выход:
748
;        CF - индикатор ошибок:
749
;            0 - ошибок нет;
750
;            1 - ошибка
751
;        Если CF=0, то AX - число.
752
 
753
        push    bx
754
        push    cx
755
        push    dx
756
        push    edi
757
        mov     [partition_string], eax
758
        mov     edi, partition_string
759
        xor     cx, cx
760
i1:
761
        mov     al, [edi]
762
        cmp     al, 32;13
763
        je      i_exit
764
;    cmp    al,'0'
765
;    jb    err
766
;    cmp    al,'9'
767
;    ja    err
768
        sub     al, 48
769
        shl     cx, 1
770
        jc      error
771
        mov     bx, cx
772
        shl     cx, 1
773
        jc      error
774
        shl     cx, 1
775
        jc      error
776
        add     cx, bx
777
        jc      error
778
        cbw
779
        add     cx, ax
780
        jc      error
781
i3:
782
        inc     edi
783
        jmp     i1
784
i_exit:
785
        mov     ax, cx
786
        clc
787
i4:
788
        movzx   eax, ax
789
        pop     edi
790
        pop     dx
791
        pop     cx
792
        pop     bx
793
        ret
794
 
795
error:
796
        stc
797
        jmp     i4
798
 
799
partition_string:
800
                  dd 0
801
                  db 32