Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
94 mario79 7
 
1531 diamond 8
$Revision: 3908 $
593 mikedld 9
 
10
 
87 mario79 11
uglobal
12
cd_current_pointer_of_input    dd  0
13
cd_current_pointer_of_input_2  dd  0
2434 Serge 14
cd_mem_location                dd  0
15
cd_counter_block               dd  0
16
IDE_Channel_1                  db  0
17
IDE_Channel_2                  db  0
87 mario79 18
endg
19
 
20
reserve_cd:
21
 
2434 Serge 22
        cli
23
        cmp     [cd_status], 0
24
        je      reserve_ok2
87 mario79 25
 
2434 Serge 26
        sti
27
        call    change_task
28
        jmp     reserve_cd
87 mario79 29
 
30
  reserve_ok2:
31
 
2434 Serge 32
        push    eax
33
        mov     eax, [CURRENT_TASK]
34
        shl     eax, 5
35
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
36
        mov     [cd_status], eax
37
        pop     eax
38
        sti
39
        ret
95 mario79 40
 
41
reserve_cd_channel:
2434 Serge 42
        cmp     [ChannelNumber], 1
43
        jne     .IDE_Channel_2
95 mario79 44
.IDE_Channel_1:
3908 Serge 45
        pushad
46
        mov     ecx, ide_channel1_mutex
47
        call    mutex_lock
2434 Serge 48
        mov     [IDE_Channel_1], 1
3908 Serge 49
        popad
2434 Serge 50
        ret
3908 Serge 51
.IDE_Channel_2:
52
        pushad
53
        mov     ecx, ide_channel2_mutex
54
        call    mutex_lock
2434 Serge 55
        mov     [IDE_Channel_2], 1
3908 Serge 56
        popad
2434 Serge 57
        ret
95 mario79 58
 
59
free_cd_channel:
2434 Serge 60
        cmp     [ChannelNumber], 1
61
        jne     .IDE_Channel_2
95 mario79 62
.IDE_Channel_1:
2434 Serge 63
        mov     [IDE_Channel_1], 0
3908 Serge 64
        pushad
65
        mov     ecx, ide_channel1_mutex
66
        call    mutex_unlock
67
        popad
2434 Serge 68
        ret
95 mario79 69
.IDE_Channel_2:
2434 Serge 70
        mov     [IDE_Channel_2], 0
3908 Serge 71
        pushad
72
        mov     ecx, ide_channel2_mutex
73
        call    mutex_unlock
74
        popad
2434 Serge 75
        ret
364 diamond 76
 
379 serge 77
uglobal
87 mario79 78
cd_status dd 0
364 diamond 79
endg
87 mario79 80
 
81
;----------------------------------------------------------------
82
;
83
;  fs_CdRead - LFN variant for reading CD disk
84
;
85
;  esi  points to filename /dir1/dir2/.../dirn/file,0
86
;  ebx  pointer to 64-bit number = first wanted byte, 0+
87
;       may be ebx=0 - start from first byte
88
;  ecx  number of bytes to read, 0+
89
;  edx  mem location to return data
90
;
91
;  ret ebx = bytes read or 0xffffffff file not found
92
;      eax = 0 ok read or other = errormsg
93
;
94
;--------------------------------------------------------------
95
fs_CdRead:
2434 Serge 96
        push    edi
97
        cmp     byte [esi], 0
98
        jnz     @f
87 mario79 99
.noaccess:
2434 Serge 100
        pop     edi
87 mario79 101
.noaccess_2:
2434 Serge 102
        or      ebx, -1
103
        mov     eax, ERROR_ACCESS_DENIED
104
        ret
379 serge 105
 
87 mario79 106
.noaccess_3:
2434 Serge 107
        pop     eax edx ecx edi
108
        jmp     .noaccess_2
87 mario79 109
 
110
@@:
2434 Serge 111
        call    cd_find_lfn
112
        jnc     .found
113
        pop     edi
114
        cmp     [DevErrorCode], 0
115
        jne     .noaccess_2
116
        or      ebx, -1
117
        mov     eax, ERROR_FILE_NOT_FOUND
118
        ret
87 mario79 119
 
120
.found:
2434 Serge 121
        mov     edi, [cd_current_pointer_of_input]
122
        test    byte [edi+25], 10b; do not allow read directories
123
        jnz     .noaccess
124
        test    ebx, ebx
125
        jz      .l1
126
        cmp     dword [ebx+4], 0
127
        jz      @f
128
        xor     ebx, ebx
87 mario79 129
.reteof:
2434 Serge 130
        mov     eax, 6; end of file
131
        pop     edi
132
        ret
87 mario79 133
@@:
2434 Serge 134
        mov     ebx, [ebx]
87 mario79 135
.l1:
2434 Serge 136
        push    ecx edx
137
        push    0
3555 Serge 138
        mov     eax, [edi+10] ; реальный размер файловой секции
2434 Serge 139
        sub     eax, ebx
140
        jb      .eof
141
        cmp     eax, ecx
142
        jae     @f
143
        mov     ecx, eax
144
        mov     byte [esp], 6
87 mario79 145
@@:
2434 Serge 146
        mov     eax, [edi+2]
147
        mov     [CDSectorAddress], eax
87 mario79 148
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
149
.new_sector:
2434 Serge 150
        test    ecx, ecx
151
        jz      .done
152
        sub     ebx, 2048
153
        jae     .next
154
        add     ebx, 2048
155
        jnz     .incomplete_sector
156
        cmp     ecx, 2048
157
        jb      .incomplete_sector
87 mario79 158
; we may read and memmove complete sector
2434 Serge 159
        mov     [CDDataBuf_pointer], edx
3555 Serge 160
        call    ReadCDWRetr; читаем сектор файла
2434 Serge 161
        cmp     [DevErrorCode], 0
162
        jne     .noaccess_3
163
        add     edx, 2048
164
        sub     ecx, 2048
154 diamond 165
.next:
2434 Serge 166
        inc     dword [CDSectorAddress]
167
        jmp     .new_sector
87 mario79 168
.incomplete_sector:
169
; we must read and memmove incomplete sector
2434 Serge 170
        mov     [CDDataBuf_pointer], CDDataBuf
3555 Serge 171
        call    ReadCDWRetr; читаем сектор файла
2434 Serge 172
        cmp     [DevErrorCode], 0
173
        jne     .noaccess_3
174
        push    ecx
175
        add     ecx, ebx
176
        cmp     ecx, 2048
177
        jbe     @f
178
        mov     ecx, 2048
87 mario79 179
@@:
2434 Serge 180
        sub     ecx, ebx
181
        push    edi esi ecx
182
        mov     edi, edx
183
        lea     esi, [CDDataBuf + ebx]
184
        cld
185
        rep movsb
186
        pop     ecx esi edi
187
        add     edx, ecx
188
        sub     [esp], ecx
189
        pop     ecx
190
        xor     ebx, ebx
191
        jmp     .next
379 serge 192
 
87 mario79 193
.done:
2434 Serge 194
        mov     ebx, edx
195
        pop     eax edx ecx edi
196
        sub     ebx, edx
197
        ret
87 mario79 198
.eof:
2434 Serge 199
        mov     ebx, edx
200
        pop     eax edx ecx
201
        sub     ebx, edx
202
        jmp     .reteof
87 mario79 203
 
204
;----------------------------------------------------------------
205
;
206
;  fs_CdReadFolder - LFN variant for reading CD disk folder
207
;
208
;  esi  points to filename  /dir1/dir2/.../dirn/file,0
209
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
210
;                          & flags (bitfields)
211
; flags: bit 0: 0=ANSI names, 1=UNICODE names
212
;  ecx  number of blocks to read, 0+
213
;  edx  mem location to return data
214
;
215
;  ret ebx = blocks read or 0xffffffff folder not found
216
;      eax = 0 ok read or other = errormsg
217
;
218
;--------------------------------------------------------------
219
fs_CdReadFolder:
2434 Serge 220
        push    edi
221
        call    cd_find_lfn
222
        jnc     .found
223
        pop     edi
224
        cmp     [DevErrorCode], 0
225
        jne     .noaccess_1
226
        or      ebx, -1
227
        mov     eax, ERROR_FILE_NOT_FOUND
228
        ret
87 mario79 229
.found:
2434 Serge 230
        mov     edi, [cd_current_pointer_of_input]
231
        test    byte [edi+25], 10b    ; do not allow read directories
232
        jnz     .found_dir
233
        pop     edi
87 mario79 234
.noaccess_1:
2434 Serge 235
        or      ebx, -1
236
        mov     eax, ERROR_ACCESS_DENIED
237
        ret
87 mario79 238
.found_dir:
2434 Serge 239
        mov     eax, [edi+2]    ; eax=cluster
240
        mov     [CDSectorAddress], eax
3555 Serge 241
        mov     eax, [edi+10]   ; размер директрории
87 mario79 242
.doit:
243
; init header
2434 Serge 244
        push    eax ecx
245
        mov     edi, edx
246
        mov     ecx, 32/4
247
        xor     eax, eax
248
        rep stosd
249
        pop     ecx eax
250
        mov     byte [edx], 1   ; version
251
        mov     [cd_mem_location], edx
252
        add     [cd_mem_location], 32
3555 Serge 253
; начинаем переброску БДВК в УСВК
87 mario79 254
;.mainloop:
2434 Serge 255
        mov     [cd_counter_block], dword 0
256
        dec     dword [CDSectorAddress]
257
        push    ecx
87 mario79 258
.read_to_buffer:
2434 Serge 259
        inc     dword [CDSectorAddress]
260
        mov     [CDDataBuf_pointer], CDDataBuf
3555 Serge 261
        call    ReadCDWRetr         ; читаем сектор директории
2434 Serge 262
        cmp     [DevErrorCode], 0
263
        jne     .noaccess_1
264
        call    .get_names_from_buffer
265
        sub     eax, 2048
3555 Serge 266
; директория закончилась?
2434 Serge 267
        ja      .read_to_buffer
268
        mov     edi, [cd_counter_block]
269
        mov     [edx+8], edi
270
        mov     edi, [ebx]
271
        sub     [edx+4], edi
272
        xor     eax, eax
273
        dec     ecx
274
        js      @f
275
        mov     al, ERROR_END_OF_FILE
364 diamond 276
@@:
2434 Serge 277
        pop     ecx edi
278
        mov     ebx, [edx+4]
279
        ret
364 diamond 280
 
87 mario79 281
.get_names_from_buffer:
2434 Serge 282
        mov     [cd_current_pointer_of_input_2], CDDataBuf
283
        push    eax esi edi edx
87 mario79 284
.get_names_from_buffer_1:
2434 Serge 285
        call    cd_get_name
286
        jc      .end_buffer
287
        inc     dword [cd_counter_block]
288
        mov     eax, [cd_counter_block]
289
        cmp     [ebx], eax
290
        jae     .get_names_from_buffer_1
291
        test    ecx, ecx
292
        jz      .get_names_from_buffer_1
293
        mov     edi, [cd_counter_block]
294
        mov     [edx+4], edi
295
        dec     ecx
296
        mov     esi, ebp
297
        mov     edi, [cd_mem_location]
298
        add     edi, 40
299
        test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
300
        jnz     .unicode
87 mario79 301
;    jmp  .unicode
302
.ansi:
2434 Serge 303
        cmp     [cd_counter_block], 2
304
        jbe     .ansi_parent_directory
305
        cld
306
        lodsw
307
        xchg    ah, al
308
        call    uni2ansi_char
309
        cld
310
        stosb
3555 Serge 311
; проверка конца файла
2434 Serge 312
        mov     ax, [esi]
3555 Serge 313
        cmp     ax, word 3B00h; сепаратор конца файла ';'
2434 Serge 314
        je      .cd_get_parameters_of_file_1
3555 Serge 315
; проверка для файлов не заканчивающихся сепаратором
2434 Serge 316
        movzx   eax, byte [ebp-33]
317
        add     eax, ebp
318
        sub     eax, 34
319
        cmp     esi, eax
320
        je      .cd_get_parameters_of_file_1
3555 Serge 321
; проверка конца папки
2434 Serge 322
        movzx   eax, byte [ebp-1]
323
        add     eax, ebp
324
        cmp     esi, eax
325
        jb      .ansi
87 mario79 326
.cd_get_parameters_of_file_1:
2434 Serge 327
        mov     [edi], byte 0
328
        call    cd_get_parameters_of_file
329
        add     [cd_mem_location], 304
330
        jmp     .get_names_from_buffer_1
87 mario79 331
 
332
.ansi_parent_directory:
2434 Serge 333
        cmp     [cd_counter_block], 2
334
        je      @f
335
        mov     [edi], byte '.'
336
        inc     edi
337
        jmp     .cd_get_parameters_of_file_1
87 mario79 338
@@:
2434 Serge 339
        mov     [edi], word '..'
340
        add     edi, 2
341
        jmp     .cd_get_parameters_of_file_1
87 mario79 342
 
343
.unicode:
2434 Serge 344
        cmp     [cd_counter_block], 2
345
        jbe     .unicode_parent_directory
346
        cld
347
        movsw
3555 Serge 348
; проверка конца файла
2434 Serge 349
        mov     ax, [esi]
3555 Serge 350
        cmp     ax, word 3B00h; сепаратор конца файла ';'
2434 Serge 351
        je      .cd_get_parameters_of_file_2
3555 Serge 352
; проверка для файлов не заканчивающихся сепаратором
2434 Serge 353
        movzx   eax, byte [ebp-33]
354
        add     eax, ebp
355
        sub     eax, 34
356
        cmp     esi, eax
357
        je      .cd_get_parameters_of_file_2
3555 Serge 358
; проверка конца папки
2434 Serge 359
        movzx   eax, byte [ebp-1]
360
        add     eax, ebp
361
        cmp     esi, eax
362
        jb      .unicode
87 mario79 363
.cd_get_parameters_of_file_2:
2434 Serge 364
        mov     [edi], word 0
365
        call    cd_get_parameters_of_file
366
        add     [cd_mem_location], 560
367
        jmp     .get_names_from_buffer_1
87 mario79 368
 
369
.unicode_parent_directory:
2434 Serge 370
        cmp     [cd_counter_block], 2
371
        je      @f
372
        mov     [edi], word 2E00h; '.'
373
        add     edi, 2
374
        jmp     .cd_get_parameters_of_file_2
87 mario79 375
@@:
2434 Serge 376
        mov     [edi], dword 2E002E00h; '..'
377
        add     edi, 4
378
        jmp     .cd_get_parameters_of_file_2
87 mario79 379
 
90 mario79 380
.end_buffer:
2434 Serge 381
        pop     edx edi esi eax
382
        ret
90 mario79 383
 
384
cd_get_parameters_of_file:
2434 Serge 385
        mov     edi, [cd_mem_location]
90 mario79 386
cd_get_parameters_of_file_1:
3555 Serge 387
; получаем атрибуты файла
2434 Serge 388
        xor     eax, eax
3555 Serge 389
; файл не архивировался
2434 Serge 390
        inc     eax
391
        shl     eax, 1
3555 Serge 392
; это каталог?
2434 Serge 393
        test    [ebp-8], byte 2
394
        jz      .file
395
        inc     eax
87 mario79 396
.file:
3555 Serge 397
; метка тома не как в FAT, в этом виде отсутсвует
398
; файл не является системным
2434 Serge 399
        shl     eax, 3
3555 Serge 400
; файл является скрытым? (атрибут существование)
2434 Serge 401
        test    [ebp-8], byte 1
402
        jz      .hidden
403
        inc     eax
87 mario79 404
.hidden:
2434 Serge 405
        shl     eax, 1
3555 Serge 406
; файл всегда только для чтения, так как это CD
2434 Serge 407
        inc     eax
408
        mov     [edi], eax
3555 Serge 409
; получаем время для файла
410
;час
2434 Serge 411
        movzx   eax, byte [ebp-12]
412
        shl     eax, 8
3555 Serge 413
;минута
2434 Serge 414
        mov     al, [ebp-11]
415
        shl     eax, 8
3555 Serge 416
;секунда
2434 Serge 417
        mov     al, [ebp-10]
3555 Serge 418
;время создания файла
2434 Serge 419
        mov     [edi+8], eax
3555 Serge 420
;время последнего доступа
2434 Serge 421
        mov     [edi+16], eax
3555 Serge 422
;время последней записи
2434 Serge 423
        mov     [edi+24], eax
3555 Serge 424
; получаем дату для файла
425
;год
2434 Serge 426
        movzx   eax, byte [ebp-15]
427
        add     eax, 1900
428
        shl     eax, 8
3555 Serge 429
;месяц
2434 Serge 430
        mov     al, [ebp-14]
431
        shl     eax, 8
3555 Serge 432
;день
2434 Serge 433
        mov     al, [ebp-13]
3555 Serge 434
;дата создания файла
2434 Serge 435
        mov     [edi+12], eax
3555 Serge 436
;время последнего доступа
2434 Serge 437
        mov     [edi+20], eax
3555 Serge 438
;время последней записи
2434 Serge 439
        mov     [edi+28], eax
3555 Serge 440
; получаем тип данных имени
2434 Serge 441
        xor     eax, eax
442
        test    dword [ebx+4], 1; 0=ANSI, 1=UNICODE
443
        jnz     .unicode_1
444
        mov     [edi+4], eax
445
        jmp     @f
87 mario79 446
.unicode_1:
2434 Serge 447
        inc     eax
448
        mov     [edi+4], eax
87 mario79 449
@@:
3555 Serge 450
; получаем размер файла в байтах
2434 Serge 451
        xor     eax, eax
452
        mov     [edi+32+4], eax
453
        mov     eax, [ebp-23]
454
        mov     [edi+32], eax
455
        ret
87 mario79 456
 
90 mario79 457
;----------------------------------------------------------------
458
;
459
;  fs_CdGetFileInfo - LFN variant for CD
460
;                     get file/directory attributes structure
379 serge 461
;
90 mario79 462
;----------------------------------------------------------------
463
fs_CdGetFileInfo:
2434 Serge 464
        cmp     byte [esi], 0
465
        jnz     @f
466
        mov     eax, 2
467
        ret
90 mario79 468
@@:
2434 Serge 469
        push    edi
470
        call    cd_find_lfn
471
        pushfd
472
        cmp     [DevErrorCode], 0
473
        jz      @f
474
        popfd
475
        pop     edi
476
        mov     eax, 11
477
        ret
90 mario79 478
@@:
2434 Serge 479
        popfd
480
        jnc     @f
481
        pop     edi
482
        mov     eax, ERROR_FILE_NOT_FOUND
483
        ret
90 mario79 484
@@:
485
 
2434 Serge 486
        mov     edi, edx
487
        push    ebp
488
        mov     ebp, [cd_current_pointer_of_input]
489
        add     ebp, 33
490
        call    cd_get_parameters_of_file_1
491
        pop     ebp
492
        and     dword [edi+4], 0
493
        pop     edi
494
        xor     eax, eax
495
        ret
90 mario79 496
 
628 mario79 497
;----------------------------------------------------------------
87 mario79 498
cd_find_lfn:
2434 Serge 499
        mov     [cd_appl_data], 0
521 diamond 500
; in: esi+ebp -> name
87 mario79 501
; out: CF=1 - file not found
758 mario79 502
; else CF=0 and [cd_current_pointer_of_input] direntry
2434 Serge 503
        push    eax esi
3555 Serge 504
; 16 сектор начало набора дескрипторов томов
758 mario79 505
 
2434 Serge 506
        call    WaitUnitReady
507
        cmp     [DevErrorCode], 0
508
        jne     .access_denied
758 mario79 509
 
2434 Serge 510
        call    prevent_medium_removal
3555 Serge 511
; тестовое чтение
2434 Serge 512
        mov     [CDSectorAddress], dword 16
513
        mov     [CDDataBuf_pointer], CDDataBuf
514
        call    ReadCDWRetr;_1
515
        cmp     [DevErrorCode], 0
516
        jne     .access_denied
758 mario79 517
 
3555 Serge 518
; вычисление последней сессии
2434 Serge 519
        call    WaitUnitReady
520
        cmp     [DevErrorCode], 0
521
        jne     .access_denied
522
        call    Read_TOC
523
        mov     ah, [CDDataBuf+4+4]
524
        mov     al, [CDDataBuf+4+5]
525
        shl     eax, 16
526
        mov     ah, [CDDataBuf+4+6]
527
        mov     al, [CDDataBuf+4+7]
528
        add     eax, 15
529
        mov     [CDSectorAddress], eax
758 mario79 530
;  mov  [CDSectorAddress],dword 15
2434 Serge 531
        mov     [CDDataBuf_pointer], CDDataBuf
758 mario79 532
 
87 mario79 533
.start:
2434 Serge 534
        inc     dword [CDSectorAddress]
535
        call    ReadCDWRetr;_1
536
        cmp     [DevErrorCode], 0
537
        jne     .access_denied
758 mario79 538
 
539
.start_check:
3555 Serge 540
; проверка на вшивость
2434 Serge 541
        cmp     [CDDataBuf+1], dword 'CD00'
542
        jne     .access_denied
543
        cmp     [CDDataBuf+5], byte '1'
544
        jne     .access_denied
3555 Serge 545
; сектор является терминатором набор дескрипторов томов?
2434 Serge 546
        cmp     [CDDataBuf], byte 0xff
547
        je      .access_denied
3555 Serge 548
; сектор является дополнительным и улучшенным дескриптором тома?
2434 Serge 549
        cmp     [CDDataBuf], byte 0x2
550
        jne     .start
3555 Serge 551
; сектор является дополнительным дескриптором тома?
2434 Serge 552
        cmp     [CDDataBuf+6], byte 0x1
553
        jne     .start
758 mario79 554
 
3555 Serge 555
; параметры root директрории
556
        mov     eax, [CDDataBuf+0x9c+2]; начало root директрории
2434 Serge 557
        mov     [CDSectorAddress], eax
3555 Serge 558
        mov     eax, [CDDataBuf+0x9c+10]; размер root директрории
2434 Serge 559
        cmp     byte [esi], 0
560
        jnz     @f
561
        mov     [cd_current_pointer_of_input], CDDataBuf+0x9c
562
        jmp     .done
87 mario79 563
@@:
3555 Serge 564
; начинаем поиск
87 mario79 565
.mainloop:
2434 Serge 566
        dec     dword [CDSectorAddress]
87 mario79 567
.read_to_buffer:
2434 Serge 568
        inc     dword [CDSectorAddress]
569
        mov     [CDDataBuf_pointer], CDDataBuf
3555 Serge 570
        call    ReadCDWRetr      ; читаем сектор директории
2434 Serge 571
        cmp     [DevErrorCode], 0
572
        jne     .access_denied
573
        push    ebp
574
        call    cd_find_name_in_buffer
575
        pop     ebp
576
        jnc     .found
577
        sub     eax, 2048
3555 Serge 578
; директория закончилась?
2434 Serge 579
        cmp     eax, 0
580
        ja      .read_to_buffer
3555 Serge 581
; нет искомого элемента цепочки
87 mario79 582
.access_denied:
2434 Serge 583
        pop     esi eax
584
        mov     [cd_appl_data], 1
585
        stc
586
        ret
3555 Serge 587
; искомый элемент цепочки найден
87 mario79 588
  .found:
3555 Serge 589
; конец пути файла
2434 Serge 590
        cmp     byte [esi-1], 0
591
        jz      .done
521 diamond 592
  .nested:
2434 Serge 593
        mov     eax, [cd_current_pointer_of_input]
594
        push    dword [eax+2]
3555 Serge 595
        pop     dword [CDSectorAddress]       ; начало директории
596
        mov     eax, [eax+2+8]; размер директории
2434 Serge 597
        jmp     .mainloop
3555 Serge 598
; указатель файла найден
87 mario79 599
   .done:
2434 Serge 600
        test    ebp, ebp
601
        jz      @f
602
        mov     esi, ebp
603
        xor     ebp, ebp
604
        jmp     .nested
521 diamond 605
@@:
2434 Serge 606
        pop     esi eax
607
        mov     [cd_appl_data], 1
608
        clc
609
        ret
379 serge 610
 
87 mario79 611
cd_find_name_in_buffer:
2434 Serge 612
        mov     [cd_current_pointer_of_input_2], CDDataBuf
87 mario79 613
.start:
2434 Serge 614
        call    cd_get_name
615
        jc      .not_found
616
        call    cd_compare_name
617
        jc      .start
379 serge 618
.found:
2434 Serge 619
        clc
620
        ret
87 mario79 621
.not_found:
2434 Serge 622
        stc
623
        ret
87 mario79 624
 
625
cd_get_name:
2434 Serge 626
        push    eax
627
        mov     ebp, [cd_current_pointer_of_input_2]
628
        mov     [cd_current_pointer_of_input], ebp
629
        mov     eax, [ebp]
3555 Serge 630
        test    eax, eax ; входы закончились?
2434 Serge 631
        jz      .next_sector
3555 Serge 632
        cmp     ebp, CDDataBuf+2048  ; буфер закончился?
2434 Serge 633
        jae     .next_sector
634
        movzx   eax, byte [ebp]
3555 Serge 635
        add     [cd_current_pointer_of_input_2], eax; следующий вход каталога
636
        add     ebp, 33; указатель установлен на начало имени
2434 Serge 637
        pop     eax
638
        clc
639
        ret
87 mario79 640
.next_sector:
2434 Serge 641
        pop     eax
642
        stc
643
        ret
87 mario79 644
 
645
cd_compare_name:
646
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
647
; in: esi->name, ebp->name
648
; out: if names match: ZF=1 and esi->next component of name
649
;      else: ZF=0, esi is not changed
650
; destroys eax
2434 Serge 651
        push    esi eax edi
652
        mov     edi, ebp
87 mario79 653
.loop:
2434 Serge 654
        cld
655
        lodsb
656
        push    eax
657
        call    char_todown
658
        call    ansi2uni_char
659
        xchg    ah, al
660
        scasw
661
        pop     eax
662
        je      .coincides
663
        call    char_toupper
664
        call    ansi2uni_char
665
        xchg    ah, al
666
        sub     edi, 2
667
        scasw
668
        jne     .name_not_coincide
87 mario79 669
.coincides:
3555 Serge 670
        cmp     [esi], byte '/'; разделитель пути, конец имени текущего элемента
2434 Serge 671
        je      .done
3555 Serge 672
        cmp     [esi], byte 0; разделитель пути, конец имени текущего элемента
2434 Serge 673
        je      .done
674
        jmp     .loop
87 mario79 675
.name_not_coincide:
2434 Serge 676
        pop     edi eax esi
677
        stc
678
        ret
87 mario79 679
.done:
3555 Serge 680
; проверка конца файла
681
        cmp     [edi], word 3B00h; сепаратор конца файла ';'
2434 Serge 682
        je      .done_1
3555 Serge 683
; проверка для файлов не заканчивающихся сепаратором
2434 Serge 684
        movzx   eax, byte [ebp-33]
685
        add     eax, ebp
686
        sub     eax, 34
687
        cmp     edi, eax
688
        je      .done_1
3555 Serge 689
; проверка конца папки
2434 Serge 690
        movzx   eax, byte [ebp-1]
691
        add     eax, ebp
692
        cmp     edi, eax
693
        jne     .name_not_coincide
87 mario79 694
.done_1:
2434 Serge 695
        pop     edi eax
696
        add     esp, 4
697
        inc     esi
698
        clc
699
        ret
379 serge 700
 
87 mario79 701
char_todown:
702
; convert character to uppercase, using cp866 encoding
703
; in: al=symbol
704
; out: al=converted symbol
2434 Serge 705
        cmp     al, 'A'
706
        jb      .ret
707
        cmp     al, 'Z'
708
        jbe     .az
3555 Serge 709
        cmp     al, 0x80 ; 'А'
2434 Serge 710
        jb      .ret
3555 Serge 711
        cmp     al, 0x90 ; 'Р'
2434 Serge 712
        jb      .rus1
3555 Serge 713
        cmp     al, 0x9F ; 'Я'
2434 Serge 714
        ja      .ret
87 mario79 715
; 0x90-0x9F -> 0xE0-0xEF
3555 Serge 716
        add     al, 0xE0-0x90
87 mario79 717
.ret:
2434 Serge 718
        ret
87 mario79 719
.rus1:
720
; 0x80-0x8F -> 0xA0-0xAF
721
.az:
2434 Serge 722
        add     al, 0x20
723
        ret
379 serge 724
 
87 mario79 725
uni2ansi_char:
726
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
727
; in: ax=UNICODE character
728
; out: al=converted ANSI character
2434 Serge 729
        cmp     ax, 0x80
730
        jb      .ascii
731
        cmp     ax, 0x401
732
        jz      .yo1
733
        cmp     ax, 0x451
734
        jz      .yo2
735
        cmp     ax, 0x410
736
        jb      .unk
737
        cmp     ax, 0x440
738
        jb      .rus1
739
        cmp     ax, 0x450
740
        jb      .rus2
87 mario79 741
.unk:
2434 Serge 742
        mov     al, '_'
743
        jmp     .doit
87 mario79 744
.yo1:
3555 Serge 745
        mov     al, 0xF0 ; 'Ё' in cp866
2434 Serge 746
        jmp     .doit
87 mario79 747
.yo2:
3555 Serge 748
        mov     al, 0xF1 ; 'ё' in cp866
2434 Serge 749
        jmp     .doit
87 mario79 750
.rus1:
751
; 0x410-0x43F -> 0x80-0xAF
2434 Serge 752
        add     al, 0x70
753
        jmp     .doit
87 mario79 754
.rus2:
755
; 0x440-0x44F -> 0xE0-0xEF
2434 Serge 756
        add     al, 0xA0
87 mario79 757
.ascii:
758
.doit:
2434 Serge 759
        ret