Subversion Repositories Kolibri OS

Rev

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

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