Subversion Repositories Kolibri OS

Rev

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

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