Subversion Repositories Kolibri OS

Rev

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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
;;                                                              ;;
593 mikedld 6
;; FAT12.INC                                                    ;;
7
;; (C) 2005 Mario79, License: GPL                               ;;
8
;;                                                              ;;
431 serge 9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 ha 10
 
593 mikedld 11
$Revision: 3626 $
12
 
13
 
1 ha 14
n_sector    dd 0  ; temporary save for sector value
15
flp_status  dd 0
16
clust_tmp_flp dd 0  ; used by analyze_directory and analyze_directory_to_write
17
path_pointer_flp dd 0
18
pointer_file_name_flp dd 0
19
save_root_flag db 0
20
save_flag   db 0
21
root_read   db 0  ; 0-necessary to load root, 1-not to load root
22
flp_fat     db 0  ; 0-necessary to load fat, 1-not to load fat
23
flp_number  db 0  ; 1- Floppy A, 2-Floppy B
24
old_track   db 0  ; old value track
25
flp_label   rb 15 ; Label and ID of inserted floppy disk
26
 
27
reserve_flp:
28
 
2434 Serge 29
        cli
30
        cmp     [flp_status], 0
31
        je      reserve_flp_ok
1 ha 32
 
2434 Serge 33
        sti
34
        call    change_task
35
        jmp     reserve_flp
1 ha 36
 
37
  reserve_flp_ok:
38
 
2434 Serge 39
        push    eax
40
        mov     eax, [CURRENT_TASK]
41
        shl     eax, 5
42
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
43
        mov     [flp_status], eax
44
        pop     eax
45
        sti
46
        ret
1 ha 47
 
48
 
49
floppy_fileread:
50
;----------------------------------------------------------------
51
;
52
;  fileread - sys floppy
53
;
54
;  eax  points to filename 11 chars  - for root directory
55
;  ebx  first wanted block       ; 1+ ; if 0 then set to 1
56
;  ecx  number of blocks to read ; 1+ ; if 0 then set to 1
57
;  edx  mem location to return data
58
;  esi  length of filename 12*X
59
;  edi  pointer to path   /fd/1/......  - for all files in nested directories
60
;
61
;  ret ebx = size or 0xffffffff file not found
62
;      eax = 0 ok read or other = errormsg
63
;            10 = access denied
64
;--------------------------------------------------------------
65
 
2434 Serge 66
        mov     [save_flag], 0
67
        mov     [path_pointer_flp], edi
68
        test    esi, esi     ; return ramdisk root
69
        jnz     fr_noroot_1
70
        cmp     ebx, 224/16
71
        jbe     fr_do_1
72
        mov     eax, 5
73
        xor     ebx, ebx
74
        mov     [flp_status], ebx
75
        ret
1 ha 76
 
77
fr_do_1:
2434 Serge 78
        push    ebx ecx edx
79
        call    read_flp_root
80
        pop     edx ecx ebx
81
        cmp     [FDC_Status], 0
82
        jne     fdc_status_error_1
83
        mov     edi, edx
84
        dec     ebx
85
        shl     ebx, 9
86
        mov     esi, FLOPPY_BUFF
87
        add     esi, ebx
88
        shl     ecx, 9
89
        cld
90
        rep movsb
91
        xor     eax, eax
92
        xor     ebx, ebx
1229 Lrz 93
;    mov    eax,0 ; ok read
94
;    mov    ebx,0
2434 Serge 95
        mov     [flp_status], eax
96
        ret
1 ha 97
fdc_status_error_1:
2434 Serge 98
        xor     eax, eax
99
        mov     [flp_status], eax
100
        mov     eax, 10
101
        or      ebx, -1
102
        ret
1 ha 103
 
104
fr_noroot_1:
2434 Serge 105
        sub     esp, 32
106
        call    expand_filename
1 ha 107
frfloppy_1:
2434 Serge 108
        test    ebx, ebx
109
        jnz     frfl5_1
110
        mov     ebx, 1
1 ha 111
frfl5_1:
2434 Serge 112
        test    ecx, ecx
113
        jnz     frfl6_1
114
        mov     ecx, 1
1 ha 115
frfl6_1:
2434 Serge 116
        dec     ebx
117
        push    eax
118
        push    eax ebx ecx edx esi edi
119
        call    read_flp_fat
120
        cmp     [FDC_Status], 0
121
        jne     fdc_status_error_3_1
3555 Serge 122
        mov     [FDD_Track], 0; Цилиндр
123
        mov     [FDD_Head], 1; Сторона
124
        mov     [FDD_Sector], 2; Сектор
2434 Serge 125
        call    SeekTrack
126
        mov     dh, 14
1 ha 127
l.20_1:
2434 Serge 128
        call    ReadSectWithRetr
129
        cmp     [FDC_Status], 0
130
        jne     fdc_status_error_3_1
131
        mov     dl, 16
132
        mov     edi, FDD_BUFF
133
        inc     [FDD_Sector]
1 ha 134
l.21_1:
2434 Serge 135
        mov     esi, eax      ;Name of file we want
136
        mov     ecx, 11
137
        cld
138
        rep cmpsb           ;Found the file?
139
        je      fifound_1     ;Yes
140
        add     ecx, 21
141
        add     edi, ecx    ;Advance to next entry
142
        dec     dl
143
        test    dl, dl
144
        jnz     l.21_1
145
        dec     dh
146
        test    dh, dh
147
        jnz     l.20_1
1 ha 148
fdc_status_error_3:
2434 Serge 149
        mov     eax, 5      ; file not found ?
150
        or      ebx, -1
151
        add     esp, 32+28
152
        mov     [flp_status], 0
153
        ret
1 ha 154
fdc_status_error_3_2:
2434 Serge 155
        cmp     [FDC_Status], 0
156
        je      fdc_status_error_3
1 ha 157
fdc_status_error_3_1:
2434 Serge 158
        add     esp, 32+28
159
        jmp     fdc_status_error_1
1 ha 160
 
161
fifound_1:
2434 Serge 162
        mov     eax, [path_pointer_flp]
163
        cmp     [eax+36], byte 0
164
        je      fifound_2
165
        add     edi, 0xf
166
        mov     eax, [edi]
167
        and     eax, 65535
168
        mov     ebx, [path_pointer_flp]
169
        add     ebx, 36
170
        call    get_cluster_of_a_path_flp
171
        jc      fdc_status_error_3_2
172
        mov     ebx, [ebx-11+28]  ;file size
173
        mov     [esp+20], ebx
174
        mov     [esp+24], ebx
175
        jmp     fifound_3
1 ha 176
fifound_2:
2434 Serge 177
        mov     ebx, [edi-11+28]  ;file size
178
        mov     [esp+20], ebx
179
        mov     [esp+24], ebx
180
        add     edi, 0xf
181
        mov     eax, [edi]
1 ha 182
fifound_3:
2434 Serge 183
        and     eax, 65535
184
        mov     [n_sector], eax      ;eax=cluster
1 ha 185
frnew_1:
2434 Serge 186
        add     eax, 31      ;bootsector+2*fat+filenames
187
        cmp     [esp+16], dword 0; wanted cluster ?
188
        jne     frfl7_1
189
        call    read_chs_sector
190
        cmp     [FDC_Status], 0
191
        jne     fdc_status_error_5
192
        mov     edi, [esp+8]
193
        call    give_back_application_data_1
194
        add     [esp+8], dword 512
195
        dec     dword [esp+12]   ; last wanted cluster ?
196
        cmp     [esp+12], dword 0
197
        je      frnoread_1
198
        jmp     frfl8_1
1 ha 199
frfl7_1:
2434 Serge 200
        dec     dword [esp+16]
1 ha 201
frfl8_1:
2434 Serge 202
        mov     edi, [n_sector]
203
        shl     edi, 1      ;find next cluster from FAT
204
        add     edi, FLOPPY_FAT
205
        mov     eax, [edi]
206
        and     eax, 4095
207
        mov     edi, eax
208
        mov     [n_sector], edi
209
        cmp     edi, 4095   ;eof  - cluster
210
        jz      frnoread2_1
211
        cmp     [esp+24], dword 512;eof  - size
212
        jb      frnoread_1
213
        sub     [esp+24], dword 512
214
        jmp     frnew_1
1 ha 215
 
131 diamond 216
read_chs_sector:
2434 Serge 217
        call    calculate_chs
218
        call    ReadSectWithRetr
219
        ret
1 ha 220
 
221
frnoread2_1:
2434 Serge 222
        cmp     [esp+16], dword 0; eof without read ?
223
        je      frnoread_1
224
        mov     [fdc_irq_func], fdc_null
225
        pop     edi esi edx ecx
226
        add     esp, 4
227
        pop     ebx; ebx <- eax : size of file
228
        add     esp, 36
229
        mov     eax, 6; end of file
230
        mov     [flp_status], 0
231
        ret
1 ha 232
 
233
frnoread_1:
2434 Serge 234
        pop     edi esi edx ecx
235
        add     esp, 4
236
        pop     ebx; ebx <- eax : size of file
237
        add     esp, 36
238
        xor     eax, eax
239
        mov     [flp_status], eax
240
        ret
1 ha 241
 
242
fdc_status_error_5:
2434 Serge 243
        pop     edi esi edx ecx
244
        add     esp, 4
245
        pop     ebx; ebx <- eax : size of file
246
        add     esp, 36
247
        jmp     fdc_status_error_1
1 ha 248
 
249
read_flp_root:
2434 Serge 250
        pusha
251
        call    check_label
252
        cmp     [FDC_Status], 0
253
        jne     unnecessary_root_read
254
        cmp     [root_read], 1
255
        je      unnecessary_root_read
3555 Serge 256
        mov     [FDD_Track], 0; Цилиндр
257
        mov     [FDD_Head], 1; Сторона
258
        mov     [FDD_Sector], 2; Сектор
2434 Serge 259
        mov     edi, FLOPPY_BUFF
260
        call    SeekTrack
1 ha 261
read_flp_root_1:
2434 Serge 262
        call    ReadSectWithRetr
263
        cmp     [FDC_Status], 0
264
        jne     unnecessary_root_read
265
        push    edi
266
        call    give_back_application_data_1
267
        pop     edi
268
        add     edi, 512
269
        inc     [FDD_Sector]
270
        cmp     [FDD_Sector], 16
271
        jne     read_flp_root_1
272
        mov     [root_read], 1
1 ha 273
unnecessary_root_read:
2434 Serge 274
        popa
275
        ret
1 ha 276
 
277
 
278
read_flp_fat:
2434 Serge 279
        pusha
280
        call    check_label
281
        cmp     [FDC_Status], 0
282
        jne     unnecessary_flp_fat
283
        cmp     [flp_fat], 1
284
        je      unnecessary_flp_fat
3555 Serge 285
        mov     [FDD_Track], 0; Цилиндр
286
        mov     [FDD_Head], 0; Сторона
287
        mov     [FDD_Sector], 2; Сектор
2434 Serge 288
        mov     edi, FLOPPY_BUFF
289
        call    SeekTrack
1 ha 290
read_flp_fat_1:
2434 Serge 291
        call    ReadSectWithRetr
292
        cmp     [FDC_Status], 0
293
        jne     unnecessary_flp_fat
294
        push    edi
295
        call    give_back_application_data_1
296
        pop     edi
297
        add     edi, 512
298
        inc     [FDD_Sector]
299
        cmp     [FDD_Sector], 19
300
        jne     read_flp_fat_1
301
        mov     [FDD_Sector], 1
302
        mov     [FDD_Head], 1
303
        call    ReadSectWithRetr
304
        cmp     [FDC_Status], 0
305
        jne     unnecessary_flp_fat
306
        call    give_back_application_data_1
307
        call    calculatefatchain_flp
308
        mov     [root_read], 0
309
        mov     [flp_fat], 1
1 ha 310
unnecessary_flp_fat:
2434 Serge 311
        popa
312
        ret
1 ha 313
 
314
calculatefatchain_flp:
2434 Serge 315
        pushad
1 ha 316
 
2434 Serge 317
        mov     esi, FLOPPY_BUFF
318
        mov     edi, FLOPPY_FAT
1 ha 319
 
320
 fcnew_1:
2434 Serge 321
        mov     eax, dword [esi]
322
        mov     ebx, dword [esi+4]
323
        mov     ecx, dword [esi+8]
324
        mov     edx, ecx
325
        shr     edx, 4;8 ok
326
        shr     dx, 4;7 ok
327
        xor     ch, ch
328
        shld    ecx, ebx, 20;6 ok
329
        shr     cx, 4;5 ok
330
        shld    ebx, eax, 12
331
        and     ebx, 0x0fffffff;4 ok
332
        shr     bx, 4;3 ok
333
        shl     eax, 4
334
        and     eax, 0x0fffffff;2 ok
335
        shr     ax, 4;1 ok
336
        mov     dword [edi], eax
337
        add     edi, 4
338
        mov     dword [edi], ebx
339
        add     edi, 4
340
        mov     dword [edi], ecx
341
        add     edi, 4
342
        mov     dword [edi], edx
343
        add     edi, 4
344
        add     esi, 12
1 ha 345
 
2434 Serge 346
        cmp     edi, FLOPPY_FAT+2856*2;2849 clusters
347
        jnz     fcnew_1
1 ha 348
 
2434 Serge 349
        popad
350
        ret
131 diamond 351
 
1 ha 352
check_label:
2434 Serge 353
        pushad
3555 Serge 354
        mov     [FDD_Track], 0; Цилиндр
355
        mov     [FDD_Head], 0; Сторона
356
        mov     [FDD_Sector], 1; Сектор
2434 Serge 357
        call    SetUserInterrupts
358
        call    FDDMotorON
359
        call    RecalibrateFDD
360
        cmp     [FDC_Status], 0
361
        jne     fdc_status_error
362
        call    SeekTrack
363
        cmp     [FDC_Status], 0
364
        jne     fdc_status_error
365
        call    ReadSectWithRetr
366
        cmp     [FDC_Status], 0
367
        jne     fdc_status_error
368
        mov     esi, flp_label
369
        mov     edi, FDD_BUFF+39
370
        mov     ecx, 15
371
        cld
372
        rep cmpsb
373
        je      same_label
374
        mov     [root_read], 0
375
        mov     [flp_fat], 0
1 ha 376
same_label:
2434 Serge 377
        mov     esi, FDD_BUFF+39
378
        mov     edi, flp_label
379
        mov     ecx, 15
380
        cld
381
        rep movsb
382
        popad
383
        ret
1 ha 384
fdc_status_error:
2434 Serge 385
        popad
386
        ret
1 ha 387
 
388
save_flp_root:
2434 Serge 389
        pusha
390
        call    check_label
391
        cmp     [FDC_Status], 0
392
        jne     unnecessary_root_save
393
        cmp     [root_read], 0
394
        je      unnecessary_root_save
3555 Serge 395
        mov     [FDD_Track], 0; Цилиндр
396
        mov     [FDD_Head], 1; Сторона
397
        mov     [FDD_Sector], 2; Сектор
2434 Serge 398
        mov     esi, FLOPPY_BUFF
399
        call    SeekTrack
1 ha 400
save_flp_root_1:
2434 Serge 401
        push    esi
402
        call    take_data_from_application_1
403
        pop     esi
404
        add     esi, 512
405
        call    WriteSectWithRetr
406
        cmp     [FDC_Status], 0
407
        jne     unnecessary_root_save
408
        inc     [FDD_Sector]
409
        cmp     [FDD_Sector], 16
410
        jne     save_flp_root_1
1 ha 411
unnecessary_root_save:
2434 Serge 412
        mov     [fdc_irq_func], fdc_null
413
        popa
414
        ret
131 diamond 415
 
1 ha 416
save_flp_fat:
2434 Serge 417
        pusha
418
        call    check_label
419
        cmp     [FDC_Status], 0
420
        jne     unnecessary_flp_fat_save
421
        cmp     [flp_fat], 0
422
        je      unnecessary_flp_fat_save
423
        call    restorefatchain_flp
3555 Serge 424
        mov     [FDD_Track], 0; Цилиндр
425
        mov     [FDD_Head], 0; Сторона
426
        mov     [FDD_Sector], 2; Сектор
2434 Serge 427
        mov     esi, FLOPPY_BUFF
428
        call    SeekTrack
1 ha 429
save_flp_fat_1:
2434 Serge 430
        push    esi
431
        call    take_data_from_application_1
432
        pop     esi
433
        add     esi, 512
434
        call    WriteSectWithRetr
435
        cmp     [FDC_Status], 0
436
        jne     unnecessary_flp_fat_save
437
        inc     [FDD_Sector]
438
        cmp     [FDD_Sector], 19
439
        jne     save_flp_fat_1
440
        mov     [FDD_Sector], 1
441
        mov     [FDD_Head], 1
442
        call    take_data_from_application_1
443
        call    WriteSectWithRetr
444
        cmp     [FDC_Status], 0
445
        jne     unnecessary_flp_fat_save
446
        mov     [root_read], 0
1 ha 447
unnecessary_flp_fat_save:
2434 Serge 448
        mov     [fdc_irq_func], fdc_null
449
        popa
450
        ret
1 ha 451
 
131 diamond 452
 
1 ha 453
restorefatchain_flp:   ; restore fat chain
2434 Serge 454
        pushad
1 ha 455
 
2434 Serge 456
        mov     esi, FLOPPY_FAT
457
        mov     edi, FLOPPY_BUFF
1 ha 458
 
459
  fcnew2_1:
2434 Serge 460
        mov     eax, dword [esi]
461
        mov     ebx, dword [esi+4]
462
        shl     ax, 4
463
        shl     eax, 4
464
        shl     bx, 4
465
        shr     ebx, 4
466
        shrd    eax, ebx, 8
467
        shr     ebx, 8
468
        mov     dword [edi], eax
469
        add     edi, 4
470
        mov     word [edi], bx
471
        add     edi, 2
472
        add     esi, 8
1 ha 473
 
2434 Serge 474
        cmp     edi, FLOPPY_BUFF+0x1200;4274 bytes - all used FAT
475
        jb      fcnew2_1
1 ha 476
 
2434 Serge 477
        mov     esi, FLOPPY_BUFF  ; duplicate fat chain
478
        mov     edi, FLOPPY_BUFF+0x1200
479
        mov     ecx, 0x1200/4
480
        cld
481
        rep movsd
1 ha 482
 
2434 Serge 483
        popad
484
        ret
1 ha 485
 
486
 
487
save_chs_sector:
2434 Serge 488
        call    calculate_chs
489
        call    WriteSectWithRetr
490
        ret
131 diamond 491
 
1 ha 492
calculate_chs:
2434 Serge 493
        mov     bl, [FDD_Track]
494
        mov     [old_track], bl
495
        mov     ebx, 18
496
        xor     edx, edx
497
        div     ebx
498
        inc     edx
499
        mov     [FDD_Sector], dl
500
        xor     edx, edx
501
        mov     ebx, 2
502
        div     ebx
503
        mov     [FDD_Track], al
504
        mov     [FDD_Head], 0
505
        test    edx, edx
506
        jz      no_head_2
507
        inc     [FDD_Head]
1 ha 508
no_head_2:
2434 Serge 509
        mov     dl, [old_track]
510
        cmp     dl, [FDD_Track]
511
        je      no_seek_track_1
512
        call    SeekTrack
1 ha 513
no_seek_track_1:
2434 Serge 514
        ret
1 ha 515
 
131 diamond 516
 
1 ha 517
get_cluster_of_a_path_flp:
518
;---------------------------------------------------------
519
; input  : EBX = pointer to a path string
520
;          (example: the path "/files/data/document" become
521
;                             "files......data.......document...0"
522
;          '.' = space char
523
;          '0' = char(0) (ASCII=0) !!! )
524
; output : if (CARRY=1) -> ERROR in the PATH
525
;          if (CARRY=0) -> EAX=cluster
526
;---------------------------------------------------------
527
 
2434 Serge 528
        push    edx
529
        mov     edx, ebx
1 ha 530
 
531
search_end_of_path_flp:
2434 Serge 532
        cmp     [save_flag], 0
533
        jne     search_end_of_path_flp_1
534
        cmp     byte [edx], 0
535
        je      found_end_of_path_flp
536
        jmp     search_end_of_path_flp_2
1 ha 537
search_end_of_path_flp_1:
2434 Serge 538
        cmp     byte [edx+12], 0
539
        je      found_end_of_path_flp
1 ha 540
search_end_of_path_flp_2:
2434 Serge 541
        inc     edx; '/'
542
        call    analyze_directory_flp
543
        jc      directory_not_found_flp
1 ha 544
 
2434 Serge 545
        mov     eax, [ebx+20-2] ; read the HIGH 16bit cluster field
546
        mov     ax, [ebx+26]    ; read the LOW 16bit cluster field
547
        and     eax, 0xfff    ;[fatMASK]
548
        add     edx, 11         ; 8+3 (name+extension)
549
        jmp     search_end_of_path_flp
1 ha 550
 
551
found_end_of_path_flp:
2434 Serge 552
        inc     edx
553
        mov     [pointer_file_name_flp], edx
554
        pop     edx
555
        clc                     ; no errors
556
        ret
1 ha 557
 
558
directory_not_found_flp:
2434 Serge 559
        pop     edx
560
        stc                     ; errors occour
561
        ret
131 diamond 562
 
1 ha 563
analyze_directory_flp:
564
;--------------------------------
565
; input  : EAX = first cluster of the directory
566
;          EBX = pointer to filename
567
; output : IF CARRY=0 EAX = sector where th file is found
568
;                     EBX = pointer in buffer
569
;                     [buffer .. buffer+511]
570
;                     ECX,EDX,EDI,EDI not changed
571
;          IF CARRY=1
572
;--------------------------------
2434 Serge 573
        push    ebx;[esp+16]
574
        push    ecx
575
        push    edx
576
        push    esi
577
        push    edi
131 diamond 578
 
579
 
1 ha 580
adr56_flp:
2434 Serge 581
        mov     [clust_tmp_flp], eax
582
        add     eax, 31
583
        pusha
584
        call    read_chs_sector
585
        popa
586
        cmp     [FDC_Status], 0
587
        jne     not_found_file_analyze_flp
1 ha 588
 
2434 Serge 589
        mov     ecx, 512/32
590
        mov     ebx, FDD_BUFF
131 diamond 591
 
1 ha 592
adr1_analyze_flp:
2434 Serge 593
        mov     esi, edx;[esp+16]
594
        mov     edi, ebx
595
        cld
596
        push    ecx
597
        mov     ecx, 11
598
        rep cmpsb
599
        pop     ecx
600
        je      found_file_analyze_flp
131 diamond 601
 
2434 Serge 602
        add     ebx, 32
603
        loop    adr1_analyze_flp
131 diamond 604
 
2434 Serge 605
        mov     eax, [clust_tmp_flp]
606
        shl     eax, 1      ;find next cluster from FAT
607
        add     eax, FLOPPY_FAT
608
        mov     eax, [eax]
609
        and     eax, 4095
610
        cmp     eax, 0x0ff8
611
        jb      adr56_flp
131 diamond 612
not_found_file_analyze_flp:
2434 Serge 613
        pop     edi
614
        pop     esi
615
        pop     edx
616
        pop     ecx
617
        add     esp, 4
618
        stc     ;file not found
619
        ret
131 diamond 620
 
1 ha 621
found_file_analyze_flp:
2434 Serge 622
        pop     edi
623
        pop     esi
624
        pop     edx
625
        pop     ecx
626
        add     esp, 4
627
        clc     ;file found
628
        ret
131 diamond 629
 
630
 
71 diamond 631
; \begin{diamond}
83 diamond 632
fat_find_lfn:
71 diamond 633
; in: esi->name
83 diamond 634
;     [esp+4] = next
635
;     [esp+8] = first
636
;     [esp+C]... - possibly parameters for first and next
2987 Serge 637
; out: CF=1 - file not found, eax=error code
83 diamond 638
;      else CF=0, esi->next name component, edi->direntry
75 diamond 639
        pusha
83 diamond 640
        lea     eax, [esp+0Ch+20h]
641
        call    dword [eax-4]
642
        jc      .reterr
75 diamond 643
        sub     esp, 262*2      ; reserve place for LFN
644
        push    0               ; for fat_get_name: read ASCII name
83 diamond 645
.l1:
2987 Serge 646
        lea     ebp, [esp+4]
75 diamond 647
        call    fat_get_name
83 diamond 648
        jc      .l2
75 diamond 649
        call    fat_compare_name
650
        jz      .found
83 diamond 651
.l2:
2987 Serge 652
        mov     ebp, [esp+8+262*2+4]
83 diamond 653
        lea     eax, [esp+0Ch+20h+262*2+4]
654
        call    dword [eax-8]
655
        jnc     .l1
75 diamond 656
        add     esp, 262*2+4
83 diamond 657
.reterr:
2987 Serge 658
        mov     [esp+28], eax
83 diamond 659
        stc
75 diamond 660
        popa
661
        ret
71 diamond 662
.found:
83 diamond 663
        add     esp, 262*2+4
2987 Serge 664
        mov     ebp, [esp+8]
83 diamond 665
; if this is LFN entry, advance to true entry
75 diamond 666
        cmp     byte [edi+11], 0xF
83 diamond 667
        jnz     @f
668
        lea     eax, [esp+0Ch+20h]
669
        call    dword [eax-8]
670
        jc      .reterr
671
@@:
672
        add     esp, 8          ; CF=0
673
        push    esi
674
        push    edi
675
        popa
676
        ret
677
 
171 diamond 678
uglobal
679
; this is for delete support
680
fd_prev_sector          dd      ?
681
fd_prev_prev_sector     dd      ?
682
endg
683
 
83 diamond 684
flp_root_next:
465 serge 685
        cmp     edi, OS_BASE+0xD200-0x20
83 diamond 686
        jae     @f
75 diamond 687
        add     edi, 0x20
83 diamond 688
        ret     ; CF=0
689
@@:
690
; read next sector
691
        inc     dword [eax]
692
        cmp     dword [eax], 14
693
        jae     flp_root_first.readerr
171 diamond 694
        push    [fd_prev_sector]
695
        pop     [fd_prev_prev_sector]
696
        push    eax
697
        mov     eax, [eax]
698
        add     eax, 19-1
699
        mov     [fd_prev_sector], eax
700
        pop     eax
83 diamond 701
flp_root_first:
702
        mov     eax, [eax]
703
        pusha
704
        add     eax, 19
75 diamond 705
        call    read_chs_sector
83 diamond 706
        popa
75 diamond 707
        cmp     [FDC_Status], 0
83 diamond 708
        jnz     .readerr
380 serge 709
        mov     edi, FDD_BUFF
83 diamond 710
        ret     ; CF=0
711
.readerr:
712
        stc
713
        ret
714
 
715
flp_rootmem_first:
380 serge 716
        mov     edi, FLOPPY_BUFF
83 diamond 717
        clc
718
        ret
719
flp_rootmem_next:
720
        add     edi, 0x20
380 serge 721
        cmp     edi, FLOPPY_BUFF+14*0x200
83 diamond 722
        cmc
723
flp_rootmem_next_write:
724
flp_rootmem_begin_write:
725
flp_rootmem_end_write:
726
        ret
727
flp_rootmem_extend_dir:
728
        stc
729
        ret
730
 
731
flp_notroot_next:
465 serge 732
        cmp     edi, OS_BASE+0xD200-0x20
83 diamond 733
        jae     flp_notroot_next_sector
734
        add     edi, 0x20
735
        ret     ; CF=0
736
flp_notroot_next_sector:
737
        push    ecx
738
        mov     ecx, [eax]
171 diamond 739
        push    [fd_prev_sector]
740
        pop     [fd_prev_prev_sector]
741
        add     ecx, 31
742
        mov     [fd_prev_sector], ecx
381 serge 743
        mov     ecx, [(ecx-31)*2+FLOPPY_FAT]
83 diamond 744
        and     ecx, 0xFFF
745
        cmp     ecx, 2849
746
        jae     flp_notroot_first.err2
747
        mov     [eax], ecx
748
        pop     ecx
749
flp_notroot_first:
750
        mov     eax, [eax]
751
        cmp     eax, 2
752
        jb      .err
753
        cmp     eax, 2849
754
        jae     .err
755
        pusha
75 diamond 756
        add     eax, 31
83 diamond 757
        call    read_chs_sector
758
        popa
380 serge 759
        mov     edi, FDD_BUFF
83 diamond 760
        cmp     [FDC_Status], 0
761
        jnz     .err
762
        ret     ; CF=0
763
.err2:
764
        pop     ecx
765
.err:
766
        stc
75 diamond 767
        ret
83 diamond 768
flp_notroot_begin_write:
769
        pusha
770
        mov     eax, [eax]
771
        add     eax, 31
772
        call    read_chs_sector
773
        popa
774
        ret
775
flp_notroot_end_write:
776
        pusha
777
        mov     eax, [eax]
778
        add     eax, 31
779
        call    save_chs_sector
780
        popa
781
        ret
782
flp_notroot_next_write:
465 serge 783
        cmp     edi, OS_BASE+0xD200
83 diamond 784
        jae     @f
785
        ret
786
@@:
787
        call    flp_notroot_end_write
788
        jmp     flp_notroot_next_sector
789
flp_notroot_extend_dir:
790
; find free cluster in FAT
791
        pusha
792
        xor     eax, eax
381 serge 793
        mov     edi, FLOPPY_FAT
83 diamond 794
        mov     ecx, 2849
2434 Serge 795
        repnz scasw
83 diamond 796
        jnz     .notfound
797
        mov     word [edi-2], 0xFFF     ; mark as last cluster
381 serge 798
        sub     edi, FLOPPY_FAT
83 diamond 799
        shr     edi, 1
800
        dec     edi
801
        mov     eax, [esp+28]
802
        mov     ecx, [eax]
381 serge 803
        mov     [FLOPPY_FAT+ecx*2], di
83 diamond 804
        mov     [eax], edi
805
        xor     eax, eax
380 serge 806
        mov     edi, FDD_BUFF
83 diamond 807
        mov     ecx, 128
2434 Serge 808
        rep stosd
83 diamond 809
        popa
810
        call    flp_notroot_end_write
380 serge 811
        mov     edi, FDD_BUFF
83 diamond 812
        clc
813
        ret
814
.notfound:
815
        popa
816
        stc
817
        ret
71 diamond 818
 
83 diamond 819
fd_find_lfn:
521 diamond 820
; in: esi+ebp -> name
83 diamond 821
; out: CF=1 - file not found
86 diamond 822
;      else CF=0 and edi->direntry, eax=directory cluster (0 for root)
83 diamond 823
        push    esi edi
824
        push    0
825
        push    flp_root_first
826
        push    flp_root_next
827
.loop:
828
        call    fat_find_lfn
829
        jc      .notfound
830
        cmp     byte [esi], 0
831
        jz      .found
521 diamond 832
.continue:
83 diamond 833
        test    byte [edi+11], 10h
834
        jz      .notfound
835
        movzx   eax, word [edi+26]      ; cluster
836
        mov     [esp+8], eax
837
        mov     dword [esp+4], flp_notroot_first
838
        mov     dword [esp], flp_notroot_next
839
        jmp     .loop
840
.notfound:
841
        add     esp, 12
842
        pop     edi esi
843
        stc
844
        ret
845
.found:
521 diamond 846
        test    ebp, ebp
847
        jz      @f
848
        mov     esi, ebp
849
        xor     ebp, ebp
850
        jmp     .continue
851
@@:
86 diamond 852
        mov     eax, [esp+8]
131 diamond 853
        add     eax, 31
854
        cmp     dword [esp], flp_root_next
855
        jnz     @f
856
        add     eax, -31+19
857
@@:
83 diamond 858
        add     esp, 16         ; CF=0
859
        pop     esi
860
        ret
861
 
71 diamond 862
;----------------------------------------------------------------
863
;
864
;  fs_FloppyRead - LFN variant for reading floppy
865
;
866
;  esi  points to filename
867
;  ebx  pointer to 64-bit number = first wanted byte, 0+
868
;       may be ebx=0 - start from first byte
869
;  ecx  number of bytes to read, 0+
870
;  edx  mem location to return data
871
;
77 diamond 872
;  ret ebx = bytes read or 0xffffffff file not found
71 diamond 873
;      eax = 0 ok read or other = errormsg
874
;
875
;--------------------------------------------------------------
876
fs_FloppyRead:
75 diamond 877
        call    read_flp_fat
878
        cmp     byte [esi], 0
879
        jnz     @f
880
        or      ebx, -1
881
        mov     eax, 10         ; access denied
882
        ret
71 diamond 883
@@:
75 diamond 884
        push    edi
885
        call    fd_find_lfn
886
        jnc     .found
887
        pop     edi
888
        or      ebx, -1
889
        mov     eax, 5          ; file not found
890
        ret
71 diamond 891
.found:
75 diamond 892
        test    ebx, ebx
893
        jz      .l1
894
        cmp     dword [ebx+4], 0
895
        jz      @f
77 diamond 896
        xor     ebx, ebx
71 diamond 897
.reteof:
75 diamond 898
        mov     eax, 6          ; EOF
899
        pop     edi
900
        ret
71 diamond 901
@@:
75 diamond 902
        mov     ebx, [ebx]
71 diamond 903
.l1:
77 diamond 904
        push    ecx edx
905
        push    0
906
        mov     eax, [edi+28]
907
        sub     eax, ebx
908
        jb      .eof
909
        cmp     eax, ecx
910
        jae     @f
911
        mov     ecx, eax
912
        mov     byte [esp], 6           ; EOF
913
@@:
75 diamond 914
        movzx   edi, word [edi+26]
71 diamond 915
.new:
75 diamond 916
        jecxz   .done
917
        test    edi, edi
918
        jz      .eof
919
        cmp     edi, 0xFF8
920
        jae     .eof
113 diamond 921
        sub     ebx, 512
922
        jae     .skip
77 diamond 923
        lea     eax, [edi+31]
75 diamond 924
        pusha
925
        call    read_chs_sector
926
        popa
927
        cmp     [FDC_Status], 0
928
        jnz     .err
380 serge 929
        lea     eax, [FDD_BUFF+ebx+512]
75 diamond 930
        neg     ebx
931
        push    ecx
932
        cmp     ecx, ebx
933
        jbe     @f
934
        mov     ecx, ebx
71 diamond 935
@@:
75 diamond 936
        mov     ebx, edx
937
        call    memmove
938
        add     edx, ecx
939
        sub     [esp], ecx
940
        pop     ecx
941
        xor     ebx, ebx
71 diamond 942
.skip:
381 serge 943
        movzx   edi, word [edi*2+FLOPPY_FAT]
75 diamond 944
        jmp     .new
71 diamond 945
.done:
77 diamond 946
        mov     ebx, edx
947
        pop     eax edx ecx edi
948
        sub     ebx, edx
75 diamond 949
        ret
71 diamond 950
.eof:
77 diamond 951
        mov     ebx, edx
952
        pop     eax edx ecx
75 diamond 953
        jmp     .reteof
71 diamond 954
.err:
77 diamond 955
        mov     ebx, edx
956
        pop     eax edx ecx edi
957
        sub     ebx, edx
83 diamond 958
        mov     al, 11
75 diamond 959
        ret
960
 
961
;----------------------------------------------------------------
962
;
963
;  fs_FloppyReadFolder - LFN variant for reading floppy folders
964
;
965
;  esi  points to filename
78 diamond 966
;  ebx  pointer to structure: 32-bit number = first wanted block, 0+
967
;                           & flags (bitfields)
968
; flags: bit 0: 0=ANSI names, 1=UNICODE names
75 diamond 969
;  ecx  number of blocks to read, 0+
970
;  edx  mem location to return data
971
;
77 diamond 972
;  ret ebx = blocks read or 0xffffffff folder not found
75 diamond 973
;      eax = 0 ok read or other = errormsg
974
;
975
;--------------------------------------------------------------
976
fs_FloppyReadFolder:
977
        call    read_flp_fat
978
        push    edi
979
        cmp     byte [esi], 0
980
        jz      .root
981
        call    fd_find_lfn
982
        jnc     .found
983
        pop     edi
984
        or      ebx, -1
985
        mov     eax, ERROR_FILE_NOT_FOUND
986
        ret
987
.found:
988
        test    byte [edi+11], 0x10     ; do not allow read files
989
        jnz     .found_dir
990
        pop     edi
991
        or      ebx, -1
992
        mov     eax, ERROR_ACCESS_DENIED
993
        ret
994
.found_dir:
995
        movzx   eax, word [edi+26]
996
        add     eax, 31
997
        push    0
998
        jmp     .doit
999
.root:
1000
        mov     eax, 19
1001
        push    14
1002
.doit:
1003
        push    ecx ebp
1004
        sub     esp, 262*2      ; reserve space for LFN
1005
        mov     ebp, esp
78 diamond 1006
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE names
1007
        mov     ebx, [ebx]
75 diamond 1008
; init header
1009
        push    eax ecx
1010
        mov     edi, edx
1011
        mov     ecx, 32/4
1012
        xor     eax, eax
2434 Serge 1013
        rep stosd
75 diamond 1014
        pop     ecx eax
1015
        mov     byte [edx], 1   ; version
1016
        mov     esi, edi        ; esi points to BDFE
1017
.main_loop:
1018
        pusha
1019
        call    read_chs_sector
1020
        popa
1021
        cmp     [FDC_Status], 0
1022
        jnz     .error
380 serge 1023
        mov     edi, FDD_BUFF
75 diamond 1024
        push    eax
1025
.l1:
1026
        call    fat_get_name
1027
        jc      .l2
1028
        cmp     byte [edi+11], 0xF
1029
        jnz     .do_bdfe
1030
        add     edi, 0x20
465 serge 1031
        cmp     edi, OS_BASE+0xD200
75 diamond 1032
        jb      .do_bdfe
1033
        pop     eax
1034
        inc     eax
1035
        dec     byte [esp+262*2+12]
1036
        jz      .done
1037
        jns     @f
1038
; read next sector from FAT
381 serge 1039
        mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
75 diamond 1040
        and     eax, 0xFFF
1041
        cmp     eax, 0xFF8
1042
        jae     .done
1043
        add     eax, 31
1044
        mov     byte [esp+262*2+12], 0
1045
@@:
1046
        pusha
1047
        call    read_chs_sector
1048
        popa
1049
        cmp     [FDC_Status], 0
1050
        jnz     .error
380 serge 1051
        mov     edi, FDD_BUFF
75 diamond 1052
        push    eax
1053
.do_bdfe:
1054
        inc     dword [edx+8]   ; new file found
1055
        dec     ebx
1056
        jns     .l2
1057
        dec     ecx
1058
        js      .l2
1059
        inc     dword [edx+4]   ; new file block copied
1060
        call    fat_entry_to_bdfe
1061
.l2:
1062
        add     edi, 0x20
465 serge 1063
        cmp     edi, OS_BASE+0xD200
75 diamond 1064
        jb      .l1
1065
        pop     eax
1066
        inc     eax
1067
        dec     byte [esp+262*2+12]
1068
        jz      .done
1069
        jns     @f
1070
; read next sector from FAT
381 serge 1071
        mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
75 diamond 1072
        and     eax, 0xFFF
1073
        cmp     eax, 0xFF8
1074
        jae     .done
1075
        add     eax, 31
1076
        mov     byte [esp+262*2+12], 0
1077
@@:
1078
        jmp     .main_loop
1079
.error:
1080
        add     esp, 262*2+4
1081
        pop     ebp ecx edi edi
1082
        or      ebx, -1
1083
        mov     eax, ERROR_FILE_NOT_FOUND
1084
        ret
1085
.done:
1086
        add     esp, 262*2+4
1087
        pop     ebp
77 diamond 1088
        mov     ebx, [edx+4]
75 diamond 1089
        xor     eax, eax
1090
        dec     ecx
1091
        js      @f
1092
        mov     al, ERROR_END_OF_FILE
1093
@@:
1094
        pop     ecx edi edi
1095
        ret
1096
 
83 diamond 1097
;----------------------------------------------------------------
1098
;
1099
;  fs_FloppyRewrite - LFN variant for writing sys floppy
1100
;
1101
;  esi  points to filename
1102
;  ebx  ignored (reserved)
1103
;  ecx  number of bytes to write, 0+
1104
;  edx  mem location to data
1105
;
1106
;  ret ebx = number of written bytes
1107
;      eax = 0 ok read or other = errormsg
1108
;
1109
;--------------------------------------------------------------
1110
@@:
1111
        mov     eax, ERROR_ACCESS_DENIED
1112
        xor     ebx, ebx
1113
        ret
1114
fsfrfe2:
1115
        popad
1116
fsfrfe:
1117
        mov     eax, 11
1118
        xor     ebx, ebx
1119
        ret
1120
 
321 diamond 1121
fs_FloppyCreateFolder:
1122
        mov     al, 1
1123
        jmp     fs_FloppyRewrite.common
1124
 
83 diamond 1125
fs_FloppyRewrite:
321 diamond 1126
        xor     eax, eax
1127
.common:
83 diamond 1128
        cmp     byte [esi], 0
1129
        jz      @b
1130
        call    read_flp_fat
1131
        cmp     [FDC_Status], 0
1132
        jnz     fsfrfe
1133
        pushad
521 diamond 1134
        xor     edi, edi
83 diamond 1135
        push    esi
521 diamond 1136
        test    ebp, ebp
1137
        jz      @f
1138
        mov     esi, ebp
83 diamond 1139
@@:
1140
        lodsb
1141
        test    al, al
1142
        jz      @f
1143
        cmp     al, '/'
1144
        jnz     @b
521 diamond 1145
        lea     edi, [esi-1]
83 diamond 1146
        jmp     @b
1147
@@:
1148
        pop     esi
521 diamond 1149
        test    edi, edi
1150
        jnz     .noroot
83 diamond 1151
        test    ebp, ebp
521 diamond 1152
        jnz     .hasebp
83 diamond 1153
        call    read_flp_root
1154
        cmp     [FDC_Status], 0
1155
        jnz     fsfrfe2
1156
        push    flp_rootmem_extend_dir
1157
        push    flp_rootmem_end_write
1158
        push    flp_rootmem_next_write
1159
        push    flp_rootmem_begin_write
1160
        xor     ebp, ebp
1161
        push    ebp
1162
        push    flp_rootmem_first
1163
        push    flp_rootmem_next
1164
        jmp     .common1
521 diamond 1165
.hasebp:
1166
        mov     eax, ERROR_ACCESS_DENIED
1167
        cmp     byte [ebp], 0
1168
        jz      .ret1
1169
        push    ebp
1170
        xor     ebp, ebp
1171
        call    fd_find_lfn
1172
        pop     esi
1173
        jc      .notfound0
1174
        jmp     .common0
83 diamond 1175
.noroot:
335 diamond 1176
        mov     eax, ERROR_ACCESS_DENIED
521 diamond 1177
        cmp     byte [edi+1], 0
335 diamond 1178
        jz      .ret1
83 diamond 1179
; check existence
521 diamond 1180
        mov     byte [edi], 0
1181
        push    edi
83 diamond 1182
        call    fd_find_lfn
521 diamond 1183
        pop     esi
1184
        mov     byte [esi], '/'
83 diamond 1185
        jnc     @f
521 diamond 1186
.notfound0:
83 diamond 1187
        mov     eax, ERROR_FILE_NOT_FOUND
1188
.ret1:
1189
        mov     [esp+28], eax
1190
        popad
1191
        xor     ebx, ebx
1192
        ret
1193
@@:
521 diamond 1194
        inc     esi
1195
.common0:
83 diamond 1196
        test    byte [edi+11], 0x10     ; must be directory
1197
        mov     eax, ERROR_ACCESS_DENIED
1198
        jz      .ret1
1199
        movzx   ebp, word [edi+26]      ; ebp=cluster
1200
        mov     eax, ERROR_FAT_TABLE
1201
        cmp     ebp, 2
1202
        jb      .ret1
1203
        cmp     ebp, 2849
1204
        jae     .ret1
1205
        push    flp_notroot_extend_dir
1206
        push    flp_notroot_end_write
1207
        push    flp_notroot_next_write
1208
        push    flp_notroot_begin_write
1209
        push    ebp
1210
        push    flp_notroot_first
1211
        push    flp_notroot_next
1212
.common1:
1213
        call    fat_find_lfn
1214
        jc      .notfound
321 diamond 1215
; found
91 diamond 1216
        test    byte [edi+11], 10h
321 diamond 1217
        jz      .exists_file
1218
; found directory; if we are creating directory, return OK,
1219
;                  if we are creating file, say "access denied"
1220
        add     esp, 28
1221
        popad
1222
        test    al, al
1223
        mov     eax, ERROR_ACCESS_DENIED
91 diamond 1224
        jz      @f
321 diamond 1225
        mov     al, 0
1226
@@:
1227
        xor     ebx, ebx
1228
        ret
1229
.exists_file:
1230
; found file; if we are creating directory, return "access denied",
1231
;             if we are creating file, delete existing file and continue
1232
        cmp     byte [esp+28+28], 0
1233
        jz      @f
91 diamond 1234
        add     esp, 28
1235
        popad
1236
        mov     eax, ERROR_ACCESS_DENIED
1237
        xor     ebx, ebx
1238
        ret
1239
@@:
1240
; delete FAT chain
83 diamond 1241
        push    edi
1242
        xor     eax, eax
1243
        mov     dword [edi+28], eax     ; zero size
1244
        xchg    ax, word [edi+26]       ; start cluster
1245
        test    eax, eax
1246
        jz      .done1
1247
@@:
1248
        cmp     eax, 0xFF8
1249
        jae     .done1
321 diamond 1250
        lea     edi, [FLOPPY_FAT + eax*2] ; position in FAT
83 diamond 1251
        xor     eax, eax
1252
        xchg    ax, [edi]
1253
        jmp     @b
1254
.done1:
1255
        pop     edi
1256
        call    get_time_for_file
1257
        mov     [edi+22], ax
1258
        call    get_date_for_file
1259
        mov     [edi+24], ax
1260
        mov     [edi+18], ax
1261
        or      byte [edi+11], 20h      ; set 'archive' attribute
1262
        jmp     .doit
1263
.notfound:
1264
; file is not found; generate short name
1265
        call    fat_name_is_legal
1266
        jc      @f
1267
        add     esp, 28
1268
        popad
1269
        mov     eax, ERROR_FILE_NOT_FOUND
1270
        xor     ebx, ebx
1271
        ret
1272
@@:
1273
        sub     esp, 12
1274
        mov     edi, esp
1275
        call    fat_gen_short_name
1276
.test_short_name_loop:
1277
        push    esi edi ecx
1278
        mov     esi, edi
1279
        lea     eax, [esp+12+12+8]
1280
        mov     [eax], ebp
1281
        call    dword [eax-4]
1282
        jc      .found
1283
.test_short_name_entry:
1284
        cmp     byte [edi+11], 0xF
1285
        jz      .test_short_name_cont
1286
        mov     ecx, 11
1287
        push    esi edi
2434 Serge 1288
        repz cmpsb
83 diamond 1289
        pop     edi esi
1290
        jz      .short_name_found
1291
.test_short_name_cont:
1292
        lea     eax, [esp+12+12+8]
1293
        call    dword [eax-8]
1294
        jnc     .test_short_name_entry
1295
        jmp     .found
1296
.short_name_found:
1297
        pop     ecx edi esi
1298
        call    fat_next_short_name
1299
        jnc     .test_short_name_loop
1300
.disk_full:
1301
        add     esp, 12+28
1302
        popa
1303
        mov     eax, ERROR_DISK_FULL
1304
        xor     ebx, ebx
1305
        ret
1306
.found:
1307
        pop     ecx edi esi
1308
; now find space in directory
1309
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1310
        mov     al, '~'
1311
        push    ecx edi
1312
        mov     ecx, 8
2434 Serge 1313
        repnz scasb
3626 Serge 1314
        movi    eax, 1     ; 1 entry
83 diamond 1315
        jnz     .notilde
1316
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1317
        xor     eax, eax
1318
@@:
1319
        cmp     byte [esi], 0
1320
        jz      @f
1321
        inc     esi
1322
        inc     eax
1323
        jmp     @b
1324
@@:
1325
        sub     esi, eax
1326
        add     eax, 12+13
1327
        mov     ecx, 13
1328
        push    edx
1329
        cdq
1330
        div     ecx
1331
        pop     edx
1332
.notilde:
1333
        push    -1
1334
        push    -1
1335
; find  successive entries in directory
1336
        xor     ecx, ecx
1337
        push    eax
1338
        lea     eax, [esp+12+8+12+8]
1339
        mov     [eax], ebp
1340
        call    dword [eax-4]
1341
        pop     eax
1342
        jnc     .scan_dir
1343
.fsfrfe3:
1344
        add     esp, 8+8+12+28
1345
        popad
1346
        mov     eax, 11
1347
        xor     ebx, ebx
1348
        ret
1349
.scan_dir:
1350
        cmp     byte [edi], 0
1351
        jz      .free
1352
        cmp     byte [edi], 0xE5
1353
        jz      .free
1354
        xor     ecx, ecx
1355
.scan_cont:
1356
        push    eax
1357
        lea     eax, [esp+12+8+12+8]
1358
        call    dword [eax-8]
1359
        pop     eax
1360
        jnc     .scan_dir
1361
        cmp     [FDC_Status], 0
1362
        jnz     .fsfrfe3
1363
        push    eax
1364
        lea     eax, [esp+12+8+12+8]
1365
        call    dword [eax+16]          ; extend directory
1366
        pop     eax
1367
        jnc     .scan_dir
1368
        add     esp, 8+8+12+28
1369
        popad
1370
        mov     eax, ERROR_DISK_FULL
1371
        xor     ebx, ebx
1372
        ret
1373
.free:
1374
        test    ecx, ecx
1375
        jnz     @f
1376
        mov     [esp], edi
1377
        mov     ecx, [esp+8+8+12+8]
1378
        mov     [esp+4], ecx
1379
        xor     ecx, ecx
1380
@@:
1381
        inc     ecx
1382
        cmp     ecx, eax
1383
        jb      .scan_cont
1384
; found!
1385
; calculate name checksum
1386
        push    esi ecx
1387
        mov     esi, [esp+8+8]
1388
        mov     ecx, 11
1389
        xor     eax, eax
1390
@@:
1391
        ror     al, 1
1392
        add     al, [esi]
1393
        inc     esi
1394
        loop    @b
1395
        pop     ecx esi
1396
        pop     edi
1397
        pop     dword [esp+8+12+8]
1398
; edi points to first entry in free chunk
1399
        dec     ecx
1400
        jz      .nolfn
1401
        push    esi
1402
        push    eax
1403
        lea     eax, [esp+8+8+12+8]
1404
        call    dword [eax+4]         ; begin write
1405
        mov     al, 40h
1406
.writelfn:
1407
        or      al, cl
1408
        mov     esi, [esp+4]
1409
        push    ecx
1410
        dec     ecx
1411
        imul    ecx, 13
1412
        add     esi, ecx
1413
        stosb
1414
        mov     cl, 5
1415
        call    fs_RamdiskRewrite.read_symbols
1416
        mov     ax, 0xF
1417
        stosw
1418
        mov     al, [esp+4]
1419
        stosb
1420
        mov     cl, 6
1421
        call    fs_RamdiskRewrite.read_symbols
1422
        xor     eax, eax
1423
        stosw
1424
        mov     cl, 2
1425
        call    fs_RamdiskRewrite.read_symbols
1426
        pop     ecx
1427
        lea     eax, [esp+8+8+12+8]
1428
        call    dword [eax+8]         ; next write
1429
        xor     eax, eax
1430
        loop    .writelfn
1431
        pop     eax
1432
        pop     esi
1433
;        lea     eax, [esp+8+12+8]
1434
;        call    dword [eax+12]          ; end write
1435
.nolfn:
1436
        xchg    esi, [esp]
1437
        mov     ecx, 11
2434 Serge 1438
        rep movsb
83 diamond 1439
        mov     word [edi], 20h         ; attributes
1440
        sub     edi, 11
1441
        pop     esi ecx
1442
        add     esp, 12
1443
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1444
        call    get_time_for_file
1445
        mov     [edi+14], ax            ; creation time
1446
        mov     [edi+22], ax            ; last write time
1447
        call    get_date_for_file
1448
        mov     [edi+16], ax            ; creation date
1449
        mov     [edi+24], ax            ; last write date
1450
        mov     [edi+18], ax            ; last access date
1451
        and     word [edi+20], 0        ; high word of cluster
1452
        and     word [edi+26], 0        ; low word of cluster - to be filled
1453
        and     dword [edi+28], 0       ; file size - to be filled
321 diamond 1454
        cmp     byte [esp+28+28], 0
1455
        jz      .doit
1456
; create directory
1457
        mov     byte [edi+11], 10h      ; attributes: folder
1458
        mov     ecx, 32*2
1459
        mov     edx, edi
83 diamond 1460
.doit:
1461
        lea     eax, [esp+8]
1462
        call    dword [eax+12]  ; flush directory
1463
        push    ecx
1464
        push    edi
133 diamond 1465
        push    0
83 diamond 1466
        mov     esi, edx
321 diamond 1467
        test    ecx, ecx
1468
        jz      .done
83 diamond 1469
        mov     ecx, 2849
321 diamond 1470
        mov     edi, FLOPPY_FAT
83 diamond 1471
        push    0       ; first cluster
1472
.write_loop:
1473
; allocate new cluster
1474
        xor     eax, eax
2434 Serge 1475
        repnz scasw
83 diamond 1476
        mov     al, ERROR_DISK_FULL
1477
        jnz     .ret
1478
        dec     edi
1479
        dec     edi
465 serge 1480
 
2434 Serge 1481
        mov     eax, edi
1482
        sub     eax, FLOPPY_FAT
465 serge 1483
 
83 diamond 1484
        shr     eax, 1                  ; eax = cluster
1485
        mov     word [edi], 0xFFF       ; mark as last cluster
133 diamond 1486
        xchg    edi, [esp+4]
83 diamond 1487
        cmp     dword [esp], 0
1488
        jz      .first
1489
        stosw
1490
        jmp     @f
1491
.first:
1492
        mov     [esp], eax
1493
@@:
133 diamond 1494
        mov     edi, [esp+4]
83 diamond 1495
        inc     ecx
1496
; write data
1497
        push    ecx edi
1498
        mov     ecx, 512
1499
        cmp     dword [esp+20], ecx
1500
        jae     @f
1501
        mov     ecx, [esp+20]
1502
@@:
380 serge 1503
        mov     edi, FDD_BUFF
321 diamond 1504
        cmp     byte [esp+24+28+28], 0
1505
        jnz     .writedir
83 diamond 1506
        push    ecx
2434 Serge 1507
        rep movsb
83 diamond 1508
        pop     ecx
321 diamond 1509
.writedircont:
83 diamond 1510
        push    ecx
1511
        sub     ecx, 512
1512
        neg     ecx
1513
        push    eax
1514
        xor     eax, eax
2434 Serge 1515
        rep stosb
83 diamond 1516
        pop     eax
1517
        add     eax, 31
1518
        pusha
1519
        call    save_chs_sector
1520
        popa
1521
        pop     ecx
1522
        cmp     [FDC_Status], 0
1523
        jnz     .diskerr
1524
        sub     [esp+20], ecx
1525
        pop     edi ecx
1526
        jnz     .write_loop
1527
.done:
1528
        xor     eax, eax
1529
.ret:
1530
        pop     ebx edi edi ecx
1531
        mov     [esp+28+28], eax
1532
        lea     eax, [esp+8]
1533
        call    dword [eax+4]
1534
        mov     [edi+26], bx
1535
        mov     ebx, esi
1536
        sub     ebx, edx
1537
        mov     [edi+28], ebx
1538
        call    dword [eax+12]
1539
        mov     [esp+28+16], ebx
1540
        test    ebp, ebp
1541
        jnz     @f
1542
        call    save_flp_root
1543
@@:
1544
        add     esp, 28
1545
        cmp     [FDC_Status], 0
1546
        jnz     .err3
1547
        call    save_flp_fat
1548
        cmp     [FDC_Status], 0
1549
        jnz     .err3
1550
        popa
1551
        ret
1552
.err3:
1553
        popa
1554
        mov     al, 11
1555
        xor     ebx, ebx
1556
        ret
1557
.diskerr:
1558
        sub     esi, ecx
1559
        mov     eax, 11
1560
        pop     edi ecx
1561
        jmp     .ret
321 diamond 1562
.writedir:
1563
        push    ecx
1564
        mov     ecx, 32/4
1565
        push    ecx esi
2434 Serge 1566
        rep movsd
321 diamond 1567
        pop     esi ecx
1568
        mov     dword [edi-32], '.   '
1569
        mov     dword [edi-32+4], '    '
1570
        mov     dword [edi-32+8], '    '
1571
        mov     byte [edi-32+11], 10h
1572
        mov     word [edi-32+26], ax
1573
        push    esi
2434 Serge 1574
        rep movsd
321 diamond 1575
        pop     esi
1576
        mov     dword [edi-32], '..  '
1577
        mov     dword [edi-32+4], '    '
1578
        mov     dword [edi-32+8], '    '
1579
        mov     byte [edi-32+11], 10h
1580
        mov     ecx, [esp+28+8]
1581
        mov     word [edi-32+26], cx
1582
        pop     ecx
1583
        jmp     .writedircont
83 diamond 1584
 
131 diamond 1585
;----------------------------------------------------------------
1586
;
1587
;  fs_FloppyWrite - LFN variant for writing to floppy
1588
;
1589
;  esi  points to filename
1590
;  ebx  pointer to 64-bit number = first wanted byte, 0+
1591
;       may be ebx=0 - start from first byte
1592
;  ecx  number of bytes to write, 0+
1593
;  edx  mem location to data
1594
;
1595
;  ret ebx = bytes written (maybe 0)
1596
;      eax = 0 ok write or other = errormsg
1597
;
1598
;--------------------------------------------------------------
1599
 
1600
@@:
1601
        push    ERROR_ACCESS_DENIED
1602
fs_FloppyWrite.ret0:
1603
        pop     eax
1604
        xor     ebx, ebx
1605
        ret
1606
 
1607
fs_FloppyWrite.ret11:
1608
        push    11
1609
        jmp     fs_FloppyWrite.ret0
1610
 
1611
fs_FloppyWrite:
1612
        cmp     byte [esi], 0
1613
        jz      @b
1614
        call    read_flp_fat
1615
        cmp     [FDC_Status], 0
1616
        jnz     .ret11
1617
        pushad
1618
        call    fd_find_lfn
1619
        jnc     .found
1620
        popad
1621
        push    ERROR_FILE_NOT_FOUND
1622
        jmp     .ret0
1623
.found:
1624
; FAT does not support files larger than 4GB
1625
        test    ebx, ebx
1626
        jz      .l1
1627
        cmp     dword [ebx+4], 0
1628
        jz      @f
1629
.eof:
1630
        popad
1631
        push    ERROR_END_OF_FILE
1632
        jmp     .ret0
1633
@@:
1634
        mov     ebx, [ebx]
1635
.l1:
1636
; now edi points to direntry, ebx=start byte to write,
1637
; ecx=number of bytes to write, edx=data pointer
1638
 
1639
; extend file if needed
1640
        add     ecx, ebx
1641
        jc      .eof    ; FAT does not support files larger than 4GB
1642
        push    eax     ; save directory cluster
1643
        push    0       ; return value=0
1644
 
1645
        call    get_time_for_file
1646
        mov     [edi+22], ax            ; last write time
1647
        call    get_date_for_file
1648
        mov     [edi+24], ax            ; last write date
1649
        mov     [edi+18], ax            ; last access date
1650
 
1651
        push    dword [edi+28]          ; save current file size
1652
        cmp     ecx, [edi+28]
1653
        jbe     .length_ok
1654
        cmp     ecx, ebx
1655
        jz      .length_ok
1656
        call    floppy_extend_file
1657
        jnc     .length_ok
1658
        mov     [esp+4], eax
1659
; floppy_extend_file can return two error codes: FAT table error or disk full.
1660
; First case is fatal error, in second case we may write some data
1661
        cmp     al, ERROR_DISK_FULL
1662
        jz      .disk_full
1663
        pop     eax
1664
        pop     eax
1665
        mov     [esp+4+28], eax
1666
        pop     eax
1667
        popad
1668
        xor     ebx, ebx
1669
        ret
1670
.disk_full:
1671
; correct number of bytes to write
1672
        mov     ecx, [edi+28]
1673
        cmp     ecx, ebx
1674
        ja      .length_ok
1675
.ret:
1676
        pop     eax
1677
        pop     eax
1678
        mov     [esp+4+28], eax ; eax=return value
1679
        pop     eax
1680
        sub     edx, [esp+20]
1681
        mov     [esp+16], edx   ; ebx=number of written bytes
1682
        popad
1683
        ret
1684
.length_ok:
1685
; save FAT & directory
1686
; note that directory must be saved first because save_flp_fat uses buffer at 0xD000
1687
        mov     esi, [edi+28]
1688
        movzx   edi, word [edi+26]      ; starting cluster
1689
        mov     eax, [esp+8]
1690
        pusha
1691
        call    save_chs_sector
1692
        popa
1693
        cmp     [FDC_Status], 0
1694
        jnz     .device_err
1695
        call    save_flp_fat
1696
        cmp     [FDC_Status], 0
1697
        jz      @f
1698
.device_err:
1699
        mov     byte [esp+4], 11
1700
        jmp     .ret
1701
@@:
1702
 
1703
; now ebx=start pos, ecx=end pos, both lie inside file
1704
        sub     ecx, ebx
1705
        jz      .ret
1706
        call    SetUserInterrupts
1707
.write_loop:
321 diamond 1708
; skip unmodified sectors
1709
        cmp     dword [esp], 0x200
1710
        jb      .modify
1711
        sub     ebx, 0x200
1712
        jae     .skip
1713
        add     ebx, 0x200
1714
.modify:
131 diamond 1715
        lea     eax, [edi+31]   ; current sector
1716
; get length of data in current sector
1717
        push    ecx
1718
        sub     ebx, 0x200
1719
        jb      .hasdata
1720
        neg     ebx
1721
        xor     ecx, ecx
1722
        jmp     @f
1723
.hasdata:
1724
        neg     ebx
1725
        cmp     ecx, ebx
1726
        jbe     @f
1727
        mov     ecx, ebx
1728
@@:
1729
; load sector if needed
1730
        cmp     dword [esp+4], 0        ; we don't need to read uninitialized data
1731
        jz      .noread
1732
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
1733
        jz      .noread
1734
        cmp     ecx, esi        ; (same for the last sector)
1735
        jz      .noread
1736
        pusha
1737
        call    read_chs_sector
1738
        popa
1739
        cmp     [FDC_Status], 0
1740
        jz      @f
1741
.device_err2:
1742
        pop     ecx
1743
        jmp     .device_err
1744
@@:
1745
.noread:
1746
; zero uninitialized data if file was extended (because floppy_extend_file does not this)
1747
        push    eax ecx edi
1748
        xor     eax, eax
1749
        mov     ecx, 0x200
1750
        sub     ecx, [esp+4+12]
1751
        jbe     @f
380 serge 1752
        mov     edi, FDD_BUFF
131 diamond 1753
        add     edi, [esp+4+12]
2434 Serge 1754
        rep stosb
131 diamond 1755
@@:
1756
; zero uninitialized data in the last sector
1757
        mov     ecx, 0x200
1758
        sub     ecx, esi
1759
        jbe     @f
380 serge 1760
        mov     edi, FDD_BUFF
131 diamond 1761
        add     edi, esi
2434 Serge 1762
        rep stosb
131 diamond 1763
@@:
1764
        pop     edi ecx eax
1765
; copy new data
1766
        push    eax
1767
        mov     eax, edx
1768
        neg     ebx
1769
        jecxz   @f
380 serge 1770
        add     ebx, FDD_BUFF+0x200
131 diamond 1771
        call    memmove
1772
        xor     ebx, ebx
1773
@@:
1774
        pop     eax
1775
; save sector
1776
        pusha
1777
        call    save_chs_sector
1778
        popa
1779
        cmp     [FDC_Status], 0
1780
        jnz     .device_err2
1781
        add     edx, ecx
1782
        sub     [esp], ecx
1783
        pop     ecx
1784
        jz      .done
321 diamond 1785
.skip:
131 diamond 1786
.next_cluster:
381 serge 1787
        movzx   edi, word [edi*2+FLOPPY_FAT]
131 diamond 1788
        sub     esi, 0x200
1789
        jae     @f
1790
        xor     esi, esi
1791
@@:
1792
        sub     dword [esp], 0x200
1793
        jae     .write_loop
1794
        and     dword [esp], 0
1795
        jmp     .write_loop
1796
.done:
1797
        mov     [fdc_irq_func], fdc_null
1798
        jmp     .ret
1799
 
1800
floppy_extend_file.zero_size:
1801
        xor     eax, eax
1802
        jmp     floppy_extend_file.start_extend
1803
 
1804
; extends file on floppy to given size (new data area is undefined)
1805
; in: edi->direntry, ecx=new size
133 diamond 1806
; out: CF=0 => OK, eax=0
131 diamond 1807
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
1808
floppy_extend_file:
1809
        push    ecx
1810
; find the last cluster of file
1811
        movzx   eax, word [edi+26]      ; first cluster
1812
        mov     ecx, [edi+28]
1813
        jecxz   .zero_size
1814
@@:
1815
        sub     ecx, 0x200
1816
        jbe     @f
381 serge 1817
        mov     eax, [eax*2+FLOPPY_FAT]
131 diamond 1818
        and     eax, 0xFFF
1819
        jz      .fat_err
1820
        cmp     eax, 0xFF8
1821
        jb      @b
1822
.fat_err:
1823
        pop     ecx
3626 Serge 1824
        movi    eax, ERROR_FAT_TABLE
131 diamond 1825
        stc
1826
        ret
1827
@@:
1828
        push    eax
381 serge 1829
        mov     eax, [eax*2+FLOPPY_FAT]
131 diamond 1830
        and     eax, 0xFFF
1831
        cmp     eax, 0xFF8
1832
        pop     eax
1833
        jb      .fat_err
1834
; set length to full number of sectors
1835
        sub     [edi+28], ecx
1836
.start_extend:
1837
        pop     ecx
1838
; now do extend
1839
        push    edx esi
381 serge 1840
        mov     esi, FLOPPY_FAT+2*2       ; start scan from cluster 2
131 diamond 1841
        mov     edx, 2847               ; number of clusters to scan
1842
.extend_loop:
1843
        cmp     [edi+28], ecx
1844
        jae     .extend_done
1845
; add new sector
1846
        push    ecx
1847
        push    edi
1848
.scan:
1849
        mov     ecx, edx
1850
        mov     edi, esi
1851
        jecxz   .disk_full
1852
        push    eax
1853
        xor     eax, eax
2434 Serge 1854
        repnz scasw
131 diamond 1855
        pop     eax
1856
        jnz     .disk_full
1857
        mov     word [edi-2], 0xFFF
1858
        mov     esi, edi
1859
        mov     edx, ecx
381 serge 1860
        sub     edi, FLOPPY_FAT
131 diamond 1861
        shr     edi, 1
1862
        dec     edi     ; now edi=new cluster
1863
        test    eax, eax
1864
        jz      .first_cluster
381 serge 1865
        mov     [FLOPPY_FAT+eax*2], di
131 diamond 1866
        jmp     @f
1867
.first_cluster:
1868
        pop     eax             ; eax->direntry
1869
        push    eax
1870
        mov     [eax+26], di
1871
@@:
1872
        mov     eax, edi        ; eax=new cluster
1873
        pop     edi             ; edi->direntry
1874
        pop     ecx             ; ecx=required size
1875
        add     dword [edi+28], 0x200
1876
        jmp     .extend_loop
1877
.extend_done:
1878
        mov     [edi+28], ecx
1879
        pop     esi edx
133 diamond 1880
        xor     eax, eax        ; CF=0
131 diamond 1881
        ret
1882
.disk_full:
1883
        pop     edi ecx
1884
        pop     esi edx
1885
        stc
3626 Serge 1886
        movi    eax, ERROR_DISK_FULL
131 diamond 1887
        ret
1888
 
133 diamond 1889
;----------------------------------------------------------------
1890
;
1891
;  fs_FloppySetFileEnd - set end of file on floppy
1892
;
1893
;  esi  points to filename
1894
;  ebx  points to 64-bit number = new file size
1895
;  ecx  ignored (reserved)
1896
;  edx  ignored (reserved)
1897
;
1898
;  ret eax = 0 ok or other = errormsg
1899
;
1900
;--------------------------------------------------------------
1901
fs_FloppySetFileEnd:
1902
        call    read_flp_fat
1903
        cmp     [FDC_Status], 0
1904
        jnz     ret11
1905
        cmp     byte [esi], 0
1906
        jnz     @f
1907
.access_denied:
1908
        push    ERROR_ACCESS_DENIED
1909
        jmp     .ret
1910
@@:
1911
        push    edi
1912
        call    fd_find_lfn
1913
        jnc     @f
1914
        pop     edi
1915
        push    ERROR_FILE_NOT_FOUND
1916
.ret:
1917
        pop     eax
1918
        jmp     .doret
1919
@@:
1920
; must not be directory
1921
        test    byte [edi+11], 10h
1922
        jz      @f
1923
        pop     edi
1924
        jmp     .access_denied
1925
@@:
1926
; file size must not exceed 4 Gb
1927
        cmp     dword [ebx+4], 0
1928
        jz      @f
1929
        pop     edi
1930
        push    ERROR_END_OF_FILE
1931
        jmp     .ret
1932
@@:
1933
        push    eax
1934
; set file modification date/time to current
1935
        call    fat_update_datetime
1936
        mov     eax, [ebx]
1937
        cmp     eax, [edi+28]
1938
        jb      .truncate
1939
        ja      .expand
1940
        pop     eax
1941
        pushad
1942
        call    save_chs_sector
1943
        popad
1944
        pop     edi
1945
        xor     eax, eax
1946
        cmp     [FDC_Status], 0
1947
        jz      @f
1948
        mov     al, 11
1949
@@:
1950
.doret:
1951
        mov     [fdc_irq_func], fdc_null
1952
        ret
1953
.expand:
1954
        push    ecx
1955
        push    dword [edi+28]  ; save old size
1956
        mov     ecx, eax
1957
        call    floppy_extend_file
1958
        push    eax     ; return code
1959
        jnc     .expand_ok
1960
        cmp     al, ERROR_DISK_FULL
1961
        jz      .disk_full
1962
        pop     eax ecx ecx edi edi
1963
        jmp     .doret
1964
.device_err:
1965
        pop     eax
1966
.device_err2:
1967
        pop     ecx ecx eax edi
1968
        push    11
1969
        jmp     .ret
1970
.disk_full:
1971
.expand_ok:
1972
; save directory & FAT
1973
        mov     eax, [edi+28]
1974
        xchg    eax, [esp+12]
1975
        movzx   edi, word [edi+26]
1976
        pusha
1977
        call    save_chs_sector
1978
        popa
1979
        cmp     [FDC_Status], 0
1980
        jnz     .device_err
1981
        call    save_flp_fat
1982
        cmp     [FDC_Status], 0
1983
        jnz     .device_err
1984
        call    SetUserInterrupts
1985
; now zero new data
1986
; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code
1987
.zero_loop:
1988
        sub     dword [esp+4], 0x200
1989
        jae     .next_cluster
1990
        cmp     dword [esp+4], -0x200
1991
        jz      .noread
1992
        lea     eax, [edi+31]
1993
        pusha
1994
        call    read_chs_sector
1995
        popa
1996
        cmp     [FDC_Status], 0
1997
        jnz     .err_next
1998
.noread:
1999
        mov     ecx, [esp+4]
2000
        neg     ecx
2001
        push    edi
380 serge 2002
        mov     edi, FDD_BUFF+0x200
133 diamond 2003
        add     edi, [esp+8]
2004
        xor     eax, eax
2005
        mov     [esp+8], eax
2434 Serge 2006
        rep stosb
133 diamond 2007
        pop     edi
2008
        lea     eax, [edi+31]
2009
        pusha
2010
        call    save_chs_sector
2011
        popa
2012
        cmp     [FDC_Status], 0
2013
        jz      .next_cluster
2014
.err_next:
2015
        mov     byte [esp], 11
2016
.next_cluster:
2017
        sub     dword [esp+12], 0x200
2018
        jbe     .expand_done
381 serge 2019
        movzx   edi, word [FLOPPY_FAT+edi*2]
133 diamond 2020
        jmp     .zero_loop
2021
.expand_done:
2022
        pop     eax ecx ecx edi edi
2023
        jmp     .doret
2024
.truncate:
2025
        mov     [edi+28], eax
2026
        push    ecx
2027
        movzx   ecx, word [edi+26]
2028
        test    eax, eax
2029
        jz      .zero_size
2030
; find new last sector
2031
@@:
2032
        sub     eax, 0x200
2033
        jbe     @f
381 serge 2034
        movzx   ecx, word [FLOPPY_FAT+ecx*2]
133 diamond 2035
        jmp     @b
2036
@@:
2037
; we will zero data at the end of last sector - remember it
2038
        push    ecx
2039
; terminate FAT chain
381 serge 2040
        lea     ecx, [FLOPPY_FAT+ecx+ecx]
133 diamond 2041
        push    dword [ecx]
2042
        mov     word [ecx], 0xFFF
2043
        pop     ecx
2044
        and     ecx, 0xFFF
2045
        jmp     .delete
2046
.zero_size:
2047
        and     word [edi+26], 0
2048
        push    0
2049
.delete:
2050
; delete FAT chain starting with ecx
2051
; mark all clusters as free
2052
        cmp     ecx, 0xFF8
2053
        jae     .deleted
381 serge 2054
        lea     ecx, [FLOPPY_FAT+ecx+ecx]
133 diamond 2055
        push    dword [ecx]
2056
        and     word [ecx], 0
2057
        pop     ecx
2058
        and     ecx, 0xFFF
2059
        jmp     .delete
2060
.deleted:
2061
        mov     edi, [edi+28]
2062
; save directory & FAT
2063
        mov     eax, [esp+8]
2064
        pusha
2065
        call    save_chs_sector
2066
        popa
2067
        cmp     [FDC_Status], 0
2068
        jnz     .device_err2
2069
        call    save_flp_fat
2070
        cmp     [FDC_Status], 0
2071
        jnz     .device_err2
2072
; zero last sector, ignore errors
2073
        pop     eax
2074
        add     eax, 31
2075
        and     edi, 0x1FF
2076
        jz      .truncate_done
2077
        call    SetUserInterrupts
2078
        pusha
2079
        call    read_chs_sector
2080
        popa
380 serge 2081
        add     edi, FDD_BUFF
2082
        mov     ecx, FDD_BUFF+0x200
133 diamond 2083
        sub     ecx, edi
2084
        push    eax
2085
        xor     eax, eax
2434 Serge 2086
        rep stosb
133 diamond 2087
        pop     eax
2088
        pusha
2089
        call    save_chs_sector
2090
        popa
2091
.truncate_done:
2092
        pop     ecx eax edi
2093
        xor     eax, eax
2094
        jmp     .doret
2095
 
86 diamond 2096
fs_FloppyGetFileInfo:
2097
        call    read_flp_fat
2098
        cmp     [FDC_Status], 0
2099
        jnz     ret11
2100
        cmp     byte [esi], 0
2101
        jnz     @f
2102
        mov     eax, 2  ; unsupported
2103
        ret
2104
@@:
2105
        push    edi
2106
        call    fd_find_lfn
2107
        jmp     fs_GetFileInfo_finish
2108
 
2109
ret11:
2110
        mov     eax, 11
2111
        ret
2112
 
2113
fs_FloppySetFileInfo:
2114
        call    read_flp_fat
2115
        cmp     [FDC_Status], 0
2116
        jnz     ret11
2117
        cmp     byte [esi], 0
2118
        jnz     @f
2119
        mov     eax, 2  ; unsupported
2120
        ret
2121
@@:
2122
        push    edi
2123
        call    fd_find_lfn
2124
        jnc     @f
2125
        pop     edi
2126
        mov     eax, ERROR_FILE_NOT_FOUND
2127
        ret
2128
@@:
2129
        push    eax
2130
        call    bdfe_to_fat_entry
2131
        pop     eax
2132
        pusha
2133
        call    save_chs_sector
2134
        popa
2135
        pop     edi
2136
        xor     eax, eax
1322 Lrz 2137
        cmp     [FDC_Status], al
86 diamond 2138
        jz      @f
2139
        mov     al, 11
2140
@@:
2141
        ret
2142
 
91 diamond 2143
;----------------------------------------------------------------
2144
;
171 diamond 2145
;  fs_FloppyDelete - delete file or empty folder from floppy
2146
;
2147
;  esi  points to filename
2148
;
2149
;  ret  eax = 0 ok or other = errormsg
2150
;
2151
;--------------------------------------------------------------
2152
fs_FloppyDelete:
2153
        call    read_flp_fat
2154
        cmp     [FDC_Status], 0
2155
        jz      @f
2156
        push    11
2157
        jmp     .pop_ret
2158
@@:
2159
        cmp     byte [esi], 0
2160
        jnz     @f
2161
; cannot delete root!
2162
.access_denied:
2163
        push    ERROR_ACCESS_DENIED
2164
.pop_ret:
2165
        pop     eax
2166
        ret
2167
@@:
2168
        and     [fd_prev_sector], 0
2169
        and     [fd_prev_prev_sector], 0
2170
        push    edi
2171
        call    fd_find_lfn
2172
        jnc     .found
2173
        pop     edi
2174
        push    ERROR_FILE_NOT_FOUND
2175
        jmp     .pop_ret
2176
.found:
2177
        cmp     dword [edi], '.   '
2178
        jz      .access_denied2
2179
        cmp     dword [edi], '..  '
2180
        jz      .access_denied2
2181
        test    byte [edi+11], 10h
2182
        jz      .dodel
2183
; we can delete only empty folders!
2184
        push    eax
2185
        movzx   eax, word [edi+26]
2186
        push    ebx
2187
        pusha
2188
        add     eax, 31
2189
        call    read_chs_sector
2190
        popa
380 serge 2191
        mov     ebx, FDD_BUFF + 2*0x20
171 diamond 2192
.checkempty:
2193
        cmp     byte [ebx], 0
2194
        jz      .empty
2195
        cmp     byte [ebx], 0xE5
2196
        jnz     .notempty
2197
        add     ebx, 0x20
380 serge 2198
        cmp     ebx, FDD_BUFF + 0x200
171 diamond 2199
        jb      .checkempty
2200
        movzx   eax, word [FLOPPY_FAT + eax*2]
2201
        pusha
2202
        add     eax, 31
2203
        call    read_chs_sector
2204
        popa
380 serge 2205
        mov     ebx, FDD_BUFF
171 diamond 2206
        jmp     .checkempty
2207
.notempty:
2208
        pop     ebx
2209
        pop     eax
2210
.access_denied2:
2211
        pop     edi
2212
        jmp     .access_denied
2213
.empty:
2214
        pop     ebx
2215
        pop     eax
2216
        pusha
2217
        call    read_chs_sector
2218
        popa
2219
.dodel:
2220
        push    eax
2221
        movzx   eax, word [edi+26]
2222
        xchg    eax, [esp]
2223
; delete folder entry
2224
        mov     byte [edi], 0xE5
2225
; delete LFN (if present)
2226
.lfndel:
380 serge 2227
        cmp     edi, FDD_BUFF
171 diamond 2228
        ja      @f
2229
        cmp     [fd_prev_sector], 0
2230
        jz      .lfndone
2231
        push    [fd_prev_sector]
2232
        push    [fd_prev_prev_sector]
2233
        pop     [fd_prev_sector]
2234
        and     [fd_prev_prev_sector], 0
2235
        pusha
2236
        call    save_chs_sector
2237
        popa
2238
        pop     eax
2239
        pusha
2240
        call    read_chs_sector
2241
        popa
380 serge 2242
        mov     edi, FDD_BUFF+0x200
171 diamond 2243
@@:
2244
        sub     edi, 0x20
2245
        cmp     byte [edi], 0xE5
2246
        jz      .lfndone
2247
        cmp     byte [edi+11], 0xF
2248
        jnz     .lfndone
2249
        mov     byte [edi], 0xE5
2250
        jmp     .lfndel
2251
.lfndone:
2252
        pusha
2253
        call    save_chs_sector
2254
        popa
2255
; delete FAT chain
2256
        pop     eax
2257
@@:
3500 Serge 2258
        cmp     eax, 2
2259
        jb      .done
2260
        cmp     eax, 0xFF8
2261
        jae     .done
171 diamond 2262
        lea     eax, [FLOPPY_FAT + eax*2]
2263
        push    dword [eax]
2264
        and     word [eax], 0
2265
        pop     eax
2266
        and     eax, 0xFFF
3500 Serge 2267
        jmp     @b
171 diamond 2268
.done:
2269
        call    save_flp_fat
2270
        pop     edi
2271
        xor     eax, eax
2272
        ret
2273
 
78 diamond 2274
; \end{diamond}