Subversion Repositories Kolibri OS

Rev

Rev 1229 | 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
;;                                                              ;;
431 serge 3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
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: 1322 $
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
 
29
    cli
30
    cmp   [flp_status],0
31
    je    reserve_flp_ok
32
 
33
    sti
34
    call  change_task
35
    jmp   reserve_flp
36
 
37
  reserve_flp_ok:
38
 
39
    push  eax
379 serge 40
    mov   eax,[CURRENT_TASK]
1 ha 41
    shl   eax,5
379 serge 42
    mov   eax,[eax+CURRENT_TASK+TASKDATA.pid]
1 ha 43
    mov   [flp_status],eax
44
    pop   eax
45
    sti
46
    ret
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
 
66
    mov    [save_flag],0
67
    mov    [path_pointer_flp],edi
1322 Lrz 68
    test   esi,esi           ; return ramdisk root
69
    jnz    fr_noroot_1
1 ha 70
    cmp    ebx,224/16
71
    jbe    fr_do_1
72
    mov    eax,5
1322 Lrz 73
    xor    ebx,ebx
74
    mov   [flp_status],ebx
1 ha 75
    ret
76
 
77
fr_do_1:
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
380 serge 86
    mov    esi,FLOPPY_BUFF
1 ha 87
    add    esi,ebx
88
    shl    ecx,9
89
    cld
90
    rep    movsb
1229 Lrz 91
	xor	eax,eax
92
	xor	ebx,ebx
93
;    mov    eax,0 ; ok read
94
;    mov    ebx,0
95
    mov   [flp_status],eax
1 ha 96
    ret
97
fdc_status_error_1:
1229 Lrz 98
	xor	eax,eax
99
    mov   [flp_status],eax
131 diamond 100
    mov    eax,10
1229 Lrz 101
    or    ebx,-1
1 ha 102
    ret
103
 
104
fr_noroot_1:
105
    sub    esp,32
106
    call   expand_filename
107
frfloppy_1:
1229 Lrz 108
    test   ebx,ebx
109
    jnz    frfl5_1
1 ha 110
    mov    ebx,1
111
frfl5_1:
1229 Lrz 112
    test   ecx,ecx
113
    jnz    frfl6_1
1 ha 114
    mov    ecx,1
115
frfl6_1:
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
122
    mov    [FDD_Track],0      ; Цилиндр
123
    mov    [FDD_Head],1      ; Сторона
124
    mov    [FDD_Sector],2      ; Сектор
125
    call    SeekTrack
126
    mov     dh,14
127
l.20_1:
128
    call    ReadSectWithRetr
129
    cmp    [FDC_Status],0
130
    jne    fdc_status_error_3_1
131
    mov     dl,16
380 serge 132
    mov     edi,FDD_BUFF
1 ha 133
    inc     [FDD_Sector]
134
l.21_1:
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
1229 Lrz 143
    test   dl,dl
144
    jnz    l.21_1
1 ha 145
    dec    dh
1229 Lrz 146
    test   dh,dh
147
    jnz    l.20_1
1 ha 148
fdc_status_error_3:
149
    mov    eax,5            ; file not found ?
1229 Lrz 150
    or     ebx,-1
1 ha 151
    add    esp,32+28
152
    mov   [flp_status],0
153
    ret
154
fdc_status_error_3_2:
155
    cmp    [FDC_Status],0
156
    je    fdc_status_error_3
157
fdc_status_error_3_1:
158
    add    esp,32+28
159
    jmp    fdc_status_error_1
160
 
161
fifound_1:
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
176
fifound_2:
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]
182
fifound_3:
183
    and    eax,65535
184
    mov    [n_sector],eax            ;eax=cluster
185
frnew_1:
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
199
frfl7_1:
200
    dec    dword [esp+16]
201
frfl8_1:
202
    mov    edi,[n_sector]
203
    shl    edi,1            ;find next cluster from FAT
381 serge 204
    add    edi,FLOPPY_FAT
1 ha 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
215
 
131 diamond 216
read_chs_sector:
1 ha 217
    call    calculate_chs
218
    call    ReadSectWithRetr
219
    ret
220
 
221
frnoread2_1:
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
232
 
233
frnoread_1:
234
    pop    edi esi edx ecx
235
    add    esp,4
236
    pop    ebx     ; ebx <- eax : size of file
237
    add    esp,36
1229 Lrz 238
    xor    eax,eax
239
    mov    [flp_status],eax
1 ha 240
    ret
241
 
242
fdc_status_error_5:
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
248
 
249
read_flp_root:
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
256
    mov    [FDD_Track],0      ; Цилиндр
257
    mov    [FDD_Head],1      ; Сторона
131 diamond 258
    mov    [FDD_Sector],2      ; Сектор
380 serge 259
    mov    edi,FLOPPY_BUFF
1 ha 260
    call   SeekTrack
261
read_flp_root_1:
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
273
unnecessary_root_read:
274
    popa
275
    ret
276
 
277
 
278
read_flp_fat:
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
285
    mov    [FDD_Track],0      ; Цилиндр
286
    mov    [FDD_Head],0      ; Сторона
131 diamond 287
    mov    [FDD_Sector],2      ; Сектор
380 serge 288
    mov    edi,FLOPPY_BUFF
1 ha 289
    call   SeekTrack
290
read_flp_fat_1:
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
310
unnecessary_flp_fat:
311
    popa
312
    ret
313
 
314
calculatefatchain_flp:
315
   pushad
316
 
380 serge 317
   mov  esi,FLOPPY_BUFF
381 serge 318
   mov  edi,FLOPPY_FAT
1 ha 319
 
320
 fcnew_1:
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
131 diamond 343
   add  edi,4
1 ha 344
   add  esi,12
345
 
381 serge 346
   cmp  edi,FLOPPY_FAT+2856*2   ;2849 clusters
1 ha 347
   jnz  fcnew_1
348
 
349
   popad
350
   ret
131 diamond 351
 
1 ha 352
check_label:
353
    pushad
354
    mov    [FDD_Track],0      ; Цилиндр
355
    mov    [FDD_Head],0      ; Сторона
131 diamond 356
    mov    [FDD_Sector],1      ; Сектор
1 ha 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
131 diamond 367
    jne    fdc_status_error
1 ha 368
    mov    esi,flp_label
380 serge 369
    mov    edi,FDD_BUFF+39
1 ha 370
    mov    ecx,15
371
    cld
131 diamond 372
    rep    cmpsb
1 ha 373
    je     same_label
374
    mov    [root_read],0
375
    mov    [flp_fat],0
376
same_label:
380 serge 377
    mov    esi,FDD_BUFF+39
1 ha 378
    mov    edi,flp_label
379
    mov    ecx,15
380
    cld
381
    rep    movsb
382
    popad
383
    ret
384
fdc_status_error:
385
    popad
386
    ret
387
 
388
save_flp_root:
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
395
    mov    [FDD_Track],0      ; Цилиндр
396
    mov    [FDD_Head],1      ; Сторона
131 diamond 397
    mov    [FDD_Sector],2      ; Сектор
380 serge 398
    mov    esi,FLOPPY_BUFF
1 ha 399
    call   SeekTrack
400
save_flp_root_1:
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
411
unnecessary_root_save:
412
    mov    [fdc_irq_func],fdc_null
413
    popa
414
    ret
131 diamond 415
 
1 ha 416
save_flp_fat:
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
424
    mov    [FDD_Track],0      ; Цилиндр
425
    mov    [FDD_Head],0      ; Сторона
131 diamond 426
    mov    [FDD_Sector],2      ; Сектор
380 serge 427
    mov    esi,FLOPPY_BUFF
1 ha 428
    call   SeekTrack
429
save_flp_fat_1:
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
447
unnecessary_flp_fat_save:
448
    mov    [fdc_irq_func],fdc_null
449
    popa
450
    ret
451
 
131 diamond 452
 
1 ha 453
restorefatchain_flp:   ; restore fat chain
454
   pushad
455
 
381 serge 456
   mov  esi,FLOPPY_FAT
380 serge 457
   mov  edi,FLOPPY_BUFF
1 ha 458
 
459
  fcnew2_1:
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
473
 
380 serge 474
   cmp  edi,FLOPPY_BUFF+0x1200     ;4274 bytes - all used FAT
1 ha 475
   jb   fcnew2_1
476
 
380 serge 477
   mov  esi,FLOPPY_BUFF           ; duplicate fat chain
478
   mov  edi,FLOPPY_BUFF+0x1200
1 ha 479
   mov  ecx,0x1200/4
480
   cld
481
   rep  movsd
482
 
483
   popad
484
   ret
485
 
486
 
487
save_chs_sector:
488
    call    calculate_chs
489
    call    WriteSectWithRetr
490
    ret
131 diamond 491
 
1 ha 492
calculate_chs:
493
    mov    bl,[FDD_Track]
131 diamond 494
    mov    [old_track],bl
1 ha 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
1229 Lrz 505
    test   edx,edx
506
    jz     no_head_2
1 ha 507
    inc    [FDD_Head]
508
no_head_2:
509
    mov     dl,[old_track]
510
    cmp     dl,[FDD_Track]
511
    je      no_seek_track_1
512
    call    SeekTrack
513
no_seek_track_1:
514
    ret
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
 
528
    push  edx
529
    mov   edx,ebx
530
 
531
search_end_of_path_flp:
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
537
search_end_of_path_flp_1:
538
    cmp   byte [edx+12],0
539
    je    found_end_of_path_flp
540
search_end_of_path_flp_2:
541
    inc   edx ; '/'
542
    call  analyze_directory_flp
543
    jc    directory_not_found_flp
544
 
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
550
 
551
found_end_of_path_flp:
552
    inc   edx
553
    mov   [pointer_file_name_flp],edx
554
    pop   edx
555
    clc                         ; no errors
556
    ret
557
 
558
directory_not_found_flp:
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
;--------------------------------
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:
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
588
 
589
   mov ecx,512/32
380 serge 590
   mov ebx,FDD_BUFF
131 diamond 591
 
1 ha 592
adr1_analyze_flp:
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
 
1 ha 602
   add ebx,32
603
   loop adr1_analyze_flp
131 diamond 604
 
1 ha 605
    mov eax,[clust_tmp_flp]
606
    shl    eax,1            ;find next cluster from FAT
381 serge 607
    add    eax,FLOPPY_FAT
1 ha 608
    mov    eax,[eax]
609
    and    eax,4095
610
    cmp eax,0x0ff8
611
    jb  adr56_flp
131 diamond 612
not_found_file_analyze_flp:
1 ha 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:
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
71 diamond 637
; out: CF=1 - file not found
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
        mov     ebp, esp
645
        push    0               ; for fat_get_name: read ASCII name
83 diamond 646
.l1:
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:
652
        lea     eax, [esp+0Ch+20h+262*2+4]
653
        call    dword [eax-8]
654
        jnc     .l1
75 diamond 655
        add     esp, 262*2+4
83 diamond 656
.reterr:
657
        stc
75 diamond 658
        popa
659
        ret
71 diamond 660
.found:
83 diamond 661
        add     esp, 262*2+4
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
792
        repnz   scasw
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
805
        rep     stosd
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
1010
        rep     stosd
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
1285
        repz    cmpsb
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
1310
        repnz   scasb
1311
        push    1
1312
        pop     eax     ; 1 entry
1313
        jnz     .notilde
1314
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1315
        xor     eax, eax
1316
@@:
1317
        cmp     byte [esi], 0
1318
        jz      @f
1319
        inc     esi
1320
        inc     eax
1321
        jmp     @b
1322
@@:
1323
        sub     esi, eax
1324
        add     eax, 12+13
1325
        mov     ecx, 13
1326
        push    edx
1327
        cdq
1328
        div     ecx
1329
        pop     edx
1330
.notilde:
1331
        push    -1
1332
        push    -1
1333
; find  successive entries in directory
1334
        xor     ecx, ecx
1335
        push    eax
1336
        lea     eax, [esp+12+8+12+8]
1337
        mov     [eax], ebp
1338
        call    dword [eax-4]
1339
        pop     eax
1340
        jnc     .scan_dir
1341
.fsfrfe3:
1342
        add     esp, 8+8+12+28
1343
        popad
1344
        mov     eax, 11
1345
        xor     ebx, ebx
1346
        ret
1347
.scan_dir:
1348
        cmp     byte [edi], 0
1349
        jz      .free
1350
        cmp     byte [edi], 0xE5
1351
        jz      .free
1352
        xor     ecx, ecx
1353
.scan_cont:
1354
        push    eax
1355
        lea     eax, [esp+12+8+12+8]
1356
        call    dword [eax-8]
1357
        pop     eax
1358
        jnc     .scan_dir
1359
        cmp     [FDC_Status], 0
1360
        jnz     .fsfrfe3
1361
        push    eax
1362
        lea     eax, [esp+12+8+12+8]
1363
        call    dword [eax+16]          ; extend directory
1364
        pop     eax
1365
        jnc     .scan_dir
1366
        add     esp, 8+8+12+28
1367
        popad
1368
        mov     eax, ERROR_DISK_FULL
1369
        xor     ebx, ebx
1370
        ret
1371
.free:
1372
        test    ecx, ecx
1373
        jnz     @f
1374
        mov     [esp], edi
1375
        mov     ecx, [esp+8+8+12+8]
1376
        mov     [esp+4], ecx
1377
        xor     ecx, ecx
1378
@@:
1379
        inc     ecx
1380
        cmp     ecx, eax
1381
        jb      .scan_cont
1382
; found!
1383
; calculate name checksum
1384
        push    esi ecx
1385
        mov     esi, [esp+8+8]
1386
        mov     ecx, 11
1387
        xor     eax, eax
1388
@@:
1389
        ror     al, 1
1390
        add     al, [esi]
1391
        inc     esi
1392
        loop    @b
1393
        pop     ecx esi
1394
        pop     edi
1395
        pop     dword [esp+8+12+8]
1396
; edi points to first entry in free chunk
1397
        dec     ecx
1398
        jz      .nolfn
1399
        push    esi
1400
        push    eax
1401
        lea     eax, [esp+8+8+12+8]
1402
        call    dword [eax+4]         ; begin write
1403
        mov     al, 40h
1404
.writelfn:
1405
        or      al, cl
1406
        mov     esi, [esp+4]
1407
        push    ecx
1408
        dec     ecx
1409
        imul    ecx, 13
1410
        add     esi, ecx
1411
        stosb
1412
        mov     cl, 5
1413
        call    fs_RamdiskRewrite.read_symbols
1414
        mov     ax, 0xF
1415
        stosw
1416
        mov     al, [esp+4]
1417
        stosb
1418
        mov     cl, 6
1419
        call    fs_RamdiskRewrite.read_symbols
1420
        xor     eax, eax
1421
        stosw
1422
        mov     cl, 2
1423
        call    fs_RamdiskRewrite.read_symbols
1424
        pop     ecx
1425
        lea     eax, [esp+8+8+12+8]
1426
        call    dword [eax+8]         ; next write
1427
        xor     eax, eax
1428
        loop    .writelfn
1429
        pop     eax
1430
        pop     esi
1431
;        lea     eax, [esp+8+12+8]
1432
;        call    dword [eax+12]          ; end write
1433
.nolfn:
1434
        xchg    esi, [esp]
1435
        mov     ecx, 11
1436
        rep     movsb
1437
        mov     word [edi], 20h         ; attributes
1438
        sub     edi, 11
1439
        pop     esi ecx
1440
        add     esp, 12
1441
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1442
        call    get_time_for_file
1443
        mov     [edi+14], ax            ; creation time
1444
        mov     [edi+22], ax            ; last write time
1445
        call    get_date_for_file
1446
        mov     [edi+16], ax            ; creation date
1447
        mov     [edi+24], ax            ; last write date
1448
        mov     [edi+18], ax            ; last access date
1449
        and     word [edi+20], 0        ; high word of cluster
1450
        and     word [edi+26], 0        ; low word of cluster - to be filled
1451
        and     dword [edi+28], 0       ; file size - to be filled
321 diamond 1452
        cmp     byte [esp+28+28], 0
1453
        jz      .doit
1454
; create directory
1455
        mov     byte [edi+11], 10h      ; attributes: folder
1456
        mov     ecx, 32*2
1457
        mov     edx, edi
83 diamond 1458
.doit:
1459
        lea     eax, [esp+8]
1460
        call    dword [eax+12]  ; flush directory
1461
        push    ecx
1462
        push    edi
133 diamond 1463
        push    0
83 diamond 1464
        mov     esi, edx
321 diamond 1465
        test    ecx, ecx
1466
        jz      .done
83 diamond 1467
        mov     ecx, 2849
321 diamond 1468
        mov     edi, FLOPPY_FAT
83 diamond 1469
        push    0       ; first cluster
1470
.write_loop:
1471
; allocate new cluster
1472
        xor     eax, eax
1473
        repnz   scasw
1474
        mov     al, ERROR_DISK_FULL
1475
        jnz     .ret
1476
        dec     edi
1477
        dec     edi
465 serge 1478
 
1479
        mov eax, edi
1480
        sub eax, FLOPPY_FAT
1481
 
83 diamond 1482
        shr     eax, 1                  ; eax = cluster
1483
        mov     word [edi], 0xFFF       ; mark as last cluster
133 diamond 1484
        xchg    edi, [esp+4]
83 diamond 1485
        cmp     dword [esp], 0
1486
        jz      .first
1487
        stosw
1488
        jmp     @f
1489
.first:
1490
        mov     [esp], eax
1491
@@:
133 diamond 1492
        mov     edi, [esp+4]
83 diamond 1493
        inc     ecx
1494
; write data
1495
        push    ecx edi
1496
        mov     ecx, 512
1497
        cmp     dword [esp+20], ecx
1498
        jae     @f
1499
        mov     ecx, [esp+20]
1500
@@:
380 serge 1501
        mov     edi, FDD_BUFF
321 diamond 1502
        cmp     byte [esp+24+28+28], 0
1503
        jnz     .writedir
83 diamond 1504
        push    ecx
1505
        rep     movsb
1506
        pop     ecx
321 diamond 1507
.writedircont:
83 diamond 1508
        push    ecx
1509
        sub     ecx, 512
1510
        neg     ecx
1511
        push    eax
1512
        xor     eax, eax
1513
        rep     stosb
1514
        pop     eax
1515
        add     eax, 31
1516
        pusha
1517
        call    save_chs_sector
1518
        popa
1519
        pop     ecx
1520
        cmp     [FDC_Status], 0
1521
        jnz     .diskerr
1522
        sub     [esp+20], ecx
1523
        pop     edi ecx
1524
        jnz     .write_loop
1525
.done:
1526
        xor     eax, eax
1527
.ret:
1528
        pop     ebx edi edi ecx
1529
        mov     [esp+28+28], eax
1530
        lea     eax, [esp+8]
1531
        call    dword [eax+4]
1532
        mov     [edi+26], bx
1533
        mov     ebx, esi
1534
        sub     ebx, edx
1535
        mov     [edi+28], ebx
1536
        call    dword [eax+12]
1537
        mov     [esp+28+16], ebx
1538
        test    ebp, ebp
1539
        jnz     @f
1540
        call    save_flp_root
1541
@@:
1542
        add     esp, 28
1543
        cmp     [FDC_Status], 0
1544
        jnz     .err3
1545
        call    save_flp_fat
1546
        cmp     [FDC_Status], 0
1547
        jnz     .err3
1548
        popa
1549
        ret
1550
.err3:
1551
        popa
1552
        mov     al, 11
1553
        xor     ebx, ebx
1554
        ret
1555
.diskerr:
1556
        sub     esi, ecx
1557
        mov     eax, 11
1558
        pop     edi ecx
1559
        jmp     .ret
321 diamond 1560
.writedir:
1561
        push    ecx
1562
        mov     ecx, 32/4
1563
        push    ecx esi
1564
        rep     movsd
1565
        pop     esi ecx
1566
        mov     dword [edi-32], '.   '
1567
        mov     dword [edi-32+4], '    '
1568
        mov     dword [edi-32+8], '    '
1569
        mov     byte [edi-32+11], 10h
1570
        mov     word [edi-32+26], ax
1571
        push    esi
1572
        rep     movsd
1573
        pop     esi
1574
        mov     dword [edi-32], '..  '
1575
        mov     dword [edi-32+4], '    '
1576
        mov     dword [edi-32+8], '    '
1577
        mov     byte [edi-32+11], 10h
1578
        mov     ecx, [esp+28+8]
1579
        mov     word [edi-32+26], cx
1580
        pop     ecx
1581
        jmp     .writedircont
83 diamond 1582
 
131 diamond 1583
;----------------------------------------------------------------
1584
;
1585
;  fs_FloppyWrite - LFN variant for writing to floppy
1586
;
1587
;  esi  points to filename
1588
;  ebx  pointer to 64-bit number = first wanted byte, 0+
1589
;       may be ebx=0 - start from first byte
1590
;  ecx  number of bytes to write, 0+
1591
;  edx  mem location to data
1592
;
1593
;  ret ebx = bytes written (maybe 0)
1594
;      eax = 0 ok write or other = errormsg
1595
;
1596
;--------------------------------------------------------------
1597
 
1598
@@:
1599
        push    ERROR_ACCESS_DENIED
1600
fs_FloppyWrite.ret0:
1601
        pop     eax
1602
        xor     ebx, ebx
1603
        ret
1604
 
1605
fs_FloppyWrite.ret11:
1606
        push    11
1607
        jmp     fs_FloppyWrite.ret0
1608
 
1609
fs_FloppyWrite:
1610
        cmp     byte [esi], 0
1611
        jz      @b
1612
        call    read_flp_fat
1613
        cmp     [FDC_Status], 0
1614
        jnz     .ret11
1615
        pushad
1616
        call    fd_find_lfn
1617
        jnc     .found
1618
        popad
1619
        push    ERROR_FILE_NOT_FOUND
1620
        jmp     .ret0
1621
.found:
1622
; FAT does not support files larger than 4GB
1623
        test    ebx, ebx
1624
        jz      .l1
1625
        cmp     dword [ebx+4], 0
1626
        jz      @f
1627
.eof:
1628
        popad
1629
        push    ERROR_END_OF_FILE
1630
        jmp     .ret0
1631
@@:
1632
        mov     ebx, [ebx]
1633
.l1:
1634
; now edi points to direntry, ebx=start byte to write,
1635
; ecx=number of bytes to write, edx=data pointer
1636
 
1637
; extend file if needed
1638
        add     ecx, ebx
1639
        jc      .eof    ; FAT does not support files larger than 4GB
1640
        push    eax     ; save directory cluster
1641
        push    0       ; return value=0
1642
 
1643
        call    get_time_for_file
1644
        mov     [edi+22], ax            ; last write time
1645
        call    get_date_for_file
1646
        mov     [edi+24], ax            ; last write date
1647
        mov     [edi+18], ax            ; last access date
1648
 
1649
        push    dword [edi+28]          ; save current file size
1650
        cmp     ecx, [edi+28]
1651
        jbe     .length_ok
1652
        cmp     ecx, ebx
1653
        jz      .length_ok
1654
        call    floppy_extend_file
1655
        jnc     .length_ok
1656
        mov     [esp+4], eax
1657
; floppy_extend_file can return two error codes: FAT table error or disk full.
1658
; First case is fatal error, in second case we may write some data
1659
        cmp     al, ERROR_DISK_FULL
1660
        jz      .disk_full
1661
        pop     eax
1662
        pop     eax
1663
        mov     [esp+4+28], eax
1664
        pop     eax
1665
        popad
1666
        xor     ebx, ebx
1667
        ret
1668
.disk_full:
1669
; correct number of bytes to write
1670
        mov     ecx, [edi+28]
1671
        cmp     ecx, ebx
1672
        ja      .length_ok
1673
.ret:
1674
        pop     eax
1675
        pop     eax
1676
        mov     [esp+4+28], eax ; eax=return value
1677
        pop     eax
1678
        sub     edx, [esp+20]
1679
        mov     [esp+16], edx   ; ebx=number of written bytes
1680
        popad
1681
        ret
1682
.length_ok:
1683
; save FAT & directory
1684
; note that directory must be saved first because save_flp_fat uses buffer at 0xD000
1685
        mov     esi, [edi+28]
1686
        movzx   edi, word [edi+26]      ; starting cluster
1687
        mov     eax, [esp+8]
1688
        pusha
1689
        call    save_chs_sector
1690
        popa
1691
        cmp     [FDC_Status], 0
1692
        jnz     .device_err
1693
        call    save_flp_fat
1694
        cmp     [FDC_Status], 0
1695
        jz      @f
1696
.device_err:
1697
        mov     byte [esp+4], 11
1698
        jmp     .ret
1699
@@:
1700
 
1701
; now ebx=start pos, ecx=end pos, both lie inside file
1702
        sub     ecx, ebx
1703
        jz      .ret
1704
        call    SetUserInterrupts
1705
.write_loop:
321 diamond 1706
; skip unmodified sectors
1707
        cmp     dword [esp], 0x200
1708
        jb      .modify
1709
        sub     ebx, 0x200
1710
        jae     .skip
1711
        add     ebx, 0x200
1712
.modify:
131 diamond 1713
        lea     eax, [edi+31]   ; current sector
1714
; get length of data in current sector
1715
        push    ecx
1716
        sub     ebx, 0x200
1717
        jb      .hasdata
1718
        neg     ebx
1719
        xor     ecx, ecx
1720
        jmp     @f
1721
.hasdata:
1722
        neg     ebx
1723
        cmp     ecx, ebx
1724
        jbe     @f
1725
        mov     ecx, ebx
1726
@@:
1727
; load sector if needed
1728
        cmp     dword [esp+4], 0        ; we don't need to read uninitialized data
1729
        jz      .noread
1730
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
1731
        jz      .noread
1732
        cmp     ecx, esi        ; (same for the last sector)
1733
        jz      .noread
1734
        pusha
1735
        call    read_chs_sector
1736
        popa
1737
        cmp     [FDC_Status], 0
1738
        jz      @f
1739
.device_err2:
1740
        pop     ecx
1741
        jmp     .device_err
1742
@@:
1743
.noread:
1744
; zero uninitialized data if file was extended (because floppy_extend_file does not this)
1745
        push    eax ecx edi
1746
        xor     eax, eax
1747
        mov     ecx, 0x200
1748
        sub     ecx, [esp+4+12]
1749
        jbe     @f
380 serge 1750
        mov     edi, FDD_BUFF
131 diamond 1751
        add     edi, [esp+4+12]
1752
        rep     stosb
1753
@@:
1754
; zero uninitialized data in the last sector
1755
        mov     ecx, 0x200
1756
        sub     ecx, esi
1757
        jbe     @f
380 serge 1758
        mov     edi, FDD_BUFF
131 diamond 1759
        add     edi, esi
1760
        rep     stosb
1761
@@:
1762
        pop     edi ecx eax
1763
; copy new data
1764
        push    eax
1765
        mov     eax, edx
1766
        neg     ebx
1767
        jecxz   @f
380 serge 1768
        add     ebx, FDD_BUFF+0x200
131 diamond 1769
        call    memmove
1770
        xor     ebx, ebx
1771
@@:
1772
        pop     eax
1773
; save sector
1774
        pusha
1775
        call    save_chs_sector
1776
        popa
1777
        cmp     [FDC_Status], 0
1778
        jnz     .device_err2
1779
        add     edx, ecx
1780
        sub     [esp], ecx
1781
        pop     ecx
1782
        jz      .done
321 diamond 1783
.skip:
131 diamond 1784
.next_cluster:
381 serge 1785
        movzx   edi, word [edi*2+FLOPPY_FAT]
131 diamond 1786
        sub     esi, 0x200
1787
        jae     @f
1788
        xor     esi, esi
1789
@@:
1790
        sub     dword [esp], 0x200
1791
        jae     .write_loop
1792
        and     dword [esp], 0
1793
        jmp     .write_loop
1794
.done:
1795
        mov     [fdc_irq_func], fdc_null
1796
        jmp     .ret
1797
 
1798
floppy_extend_file.zero_size:
1799
        xor     eax, eax
1800
        jmp     floppy_extend_file.start_extend
1801
 
1802
; extends file on floppy to given size (new data area is undefined)
1803
; in: edi->direntry, ecx=new size
133 diamond 1804
; out: CF=0 => OK, eax=0
131 diamond 1805
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
1806
floppy_extend_file:
1807
        push    ecx
1808
; find the last cluster of file
1809
        movzx   eax, word [edi+26]      ; first cluster
1810
        mov     ecx, [edi+28]
1811
        jecxz   .zero_size
1812
@@:
1813
        sub     ecx, 0x200
1814
        jbe     @f
381 serge 1815
        mov     eax, [eax*2+FLOPPY_FAT]
131 diamond 1816
        and     eax, 0xFFF
1817
        jz      .fat_err
1818
        cmp     eax, 0xFF8
1819
        jb      @b
1820
.fat_err:
1821
        pop     ecx
1822
        push    ERROR_FAT_TABLE
1823
        pop     eax
1824
        stc
1825
        ret
1826
@@:
1827
        push    eax
381 serge 1828
        mov     eax, [eax*2+FLOPPY_FAT]
131 diamond 1829
        and     eax, 0xFFF
1830
        cmp     eax, 0xFF8
1831
        pop     eax
1832
        jb      .fat_err
1833
; set length to full number of sectors
1834
        sub     [edi+28], ecx
1835
.start_extend:
1836
        pop     ecx
1837
; now do extend
1838
        push    edx esi
381 serge 1839
        mov     esi, FLOPPY_FAT+2*2       ; start scan from cluster 2
131 diamond 1840
        mov     edx, 2847               ; number of clusters to scan
1841
.extend_loop:
1842
        cmp     [edi+28], ecx
1843
        jae     .extend_done
1844
; add new sector
1845
        push    ecx
1846
        push    edi
1847
.scan:
1848
        mov     ecx, edx
1849
        mov     edi, esi
1850
        jecxz   .disk_full
1851
        push    eax
1852
        xor     eax, eax
1853
        repnz   scasw
1854
        pop     eax
1855
        jnz     .disk_full
1856
        mov     word [edi-2], 0xFFF
1857
        mov     esi, edi
1858
        mov     edx, ecx
381 serge 1859
        sub     edi, FLOPPY_FAT
131 diamond 1860
        shr     edi, 1
1861
        dec     edi     ; now edi=new cluster
1862
        test    eax, eax
1863
        jz      .first_cluster
381 serge 1864
        mov     [FLOPPY_FAT+eax*2], di
131 diamond 1865
        jmp     @f
1866
.first_cluster:
1867
        pop     eax             ; eax->direntry
1868
        push    eax
1869
        mov     [eax+26], di
1870
@@:
1871
        mov     eax, edi        ; eax=new cluster
1872
        pop     edi             ; edi->direntry
1873
        pop     ecx             ; ecx=required size
1874
        add     dword [edi+28], 0x200
1875
        jmp     .extend_loop
1876
.extend_done:
1877
        mov     [edi+28], ecx
1878
        pop     esi edx
133 diamond 1879
        xor     eax, eax        ; CF=0
131 diamond 1880
        ret
1881
.disk_full:
1882
        pop     edi ecx
1883
        pop     esi edx
1884
        stc
1885
        push    ERROR_DISK_FULL
1886
        pop     eax
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
2006
        rep     stosb
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
2086
        rep     stosb
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
        test    eax, eax
2258
        jz      .done
2259
@@:
2260
        lea     eax, [FLOPPY_FAT + eax*2]
2261
        push    dword [eax]
2262
        and     word [eax], 0
2263
        pop     eax
2264
        and     eax, 0xFFF
2265
        jnz     @b
2266
.done:
2267
        call    save_flp_fat
2268
        pop     edi
2269
        xor     eax, eax
2270
        ret
2271
 
78 diamond 2272
; \end{diamond}