Subversion Repositories Kolibri OS

Rev

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

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