Subversion Repositories Kolibri OS

Rev

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