Subversion Repositories Kolibri OS

Rev

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