Subversion Repositories Kolibri OS

Rev

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

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