Subversion Repositories Kolibri OS

Rev

Rev 83 | 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
34
    mov   eax,[0x3000]
35
    shl   eax,5
36
    mov   eax,[eax+0x3000+4]
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
52
    mov    eax,0x282000
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
 
68
 
69
 
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
107
    mov    esi,0x8000
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
118
    mov    eax,10
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
150
    mov     edi,0xD000
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
222
    add    edi,0x282000
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
 
234
read_chs_sector:
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      ; Сторона
276
    mov    [FDD_Sector],2      ; Сектор
277
    mov    edi,0x8000
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      ; Сторона
305
    mov    [FDD_Sector],2      ; Сектор
306
    mov    edi,0x8000
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
 
335
   mov  esi,0x8000
336
   mov  edi,0x282000
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
361
   add  edi,4
362
   add  esi,12
363
 
364
   cmp  edi,0x282000+2856*2   ;2849 clusters
365
   jnz  fcnew_1
366
 
367
   popad
368
   ret
369
 
370
check_label:
371
    pushad
372
    mov    [FDD_Track],0      ; Цилиндр
373
    mov    [FDD_Head],0      ; Сторона
374
    mov    [FDD_Sector],1      ; Сектор
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
385
    jne    fdc_status_error
386
    mov    esi,flp_label
387
    mov    edi,0xD000+39
388
    mov    ecx,15
389
    cld
390
    rep    cmpsb
391
    je     same_label
392
    mov    [root_read],0
393
    mov    [flp_fat],0
394
same_label:
395
    mov    esi,0xD000+39
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      ; Сторона
415
    mov    [FDD_Sector],2      ; Сектор
416
    mov    esi,0x8000
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
433
 
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      ; Сторона
444
    mov    [FDD_Sector],2      ; Сектор
445
    mov    esi,0x8000
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
 
470
 
471
restorefatchain_flp:   ; restore fat chain
472
   pushad
473
 
474
   mov  esi,0x282000
475
   mov  edi,0x8000
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
 
492
   cmp  edi,0x8000+0x1200     ;4274 bytes - all used FAT
493
   jb   fcnew2_1
494
 
495
   mov  esi,0x8000           ; duplicate fat chain
496
   mov  edi,0x8000+0x1200
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
537
    mov     edi,0xD000
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
566
    jc     frnoreadd_1_1
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
577
    add    edi,0x282000
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
620
;                5 - file not found / directory not found
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:
647
    popa
648
    add    esp,32
649
    jmp    fdc_status_error_1
650
 
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
665
    mov    edi,0x8000   ;Point at directory
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
692
    mov    edi,0xD000
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
752
    call   frnewds_2
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
786
    add    edi,0x282000
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
814
    je    fdc_status_error_8
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
824
 
825
calculate_chs:
826
    mov    bl,[FDD_Track]
827
    mov    [old_track],bl
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
 
849
 
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
895
 
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
911
 
912
 
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
923
   mov ebx,0xD000
924
 
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
934
 
935
   add ebx,32
936
   loop adr1_analyze_flp
937
 
938
    mov eax,[clust_tmp_flp]
939
    shl    eax,1            ;find next cluster from FAT
940
    add    eax,0x282000
941
    mov    eax,[eax]
942
    and    eax,4095
943
    cmp eax,0x0ff8
944
    jb  adr56_flp
945
not_found_file_analyze_flp:
946
   pop edi
947
   pop esi
948
   pop edx
949
   pop ecx
950
   add esp,4
951
   stc        ;file not found
952
   ret
953
 
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
962
 
963
 
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
;--------------------------------
973
 
974
   push ecx
975
   push edx
976
   push esi
977
 
978
adr561:
979
   mov [clust_tmp_flp],eax
980
   add    eax,31
981
   pusha
982
   call   read_chs_sector
983
   popa
984
   cmp    [FDC_Status],0
985
   jne    error_found_file_analyze1
986
 
987
   mov ecx,512/32
988
   mov ebx,0xD000
989
 
990
adr1_analyze1:
991
   cmp byte [ebx],0x00
992
   je  found_file_analyze1
993
   cmp byte [ebx],0xe5
994
   je  found_file_analyze1
995
 
996
avanti:
997
   add ebx,32
998
   loop adr1_analyze1
999
 
1000
   mov eax,[clust_tmp_flp]
1001
   shl    eax,1            ;find next cluster from FAT
1002
   add    eax,0x282000
1003
   mov    eax,[eax]
1004
   and    eax,4095
1005
   cmp eax,0x0ff8
1006
   jb  adr561
1007
 
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
1013
 
1014
   mov eax,[clust_tmp_flp]
1015
   shl    eax,1            ;find next cluster from FAT
1016
   add    eax,0x282000
1017
   sub    edi,0x282000
1018
   mov    [eax],di
1019
 
1020
   pusha
1021
   mov ecx,512/4
1022
   xor eax,eax
1023
   mov edi,0xD000
1024
   cld
1025
   rep stosd
1026
   popa
1027
 
1028
   mov    eax,edi
1029
   add    eax,31
1030
   pusha
1031
   call   save_chs_sector
1032
   popa
1033
   cmp    [FDC_Status],0
1034
   jne    error_found_file_analyze1
1035
   mov    ebx,0xD000
1036
 
1037
found_file_analyze1:
1038
 
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
1050
   ret
1051
 
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
1058
 
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
1064
    add    edi,0x282000
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
 
1117
flp_root_next:
1118
        cmp     edi, 0xD200-0x20
1119
        jae     @f
75 diamond 1120
        add     edi, 0x20
83 diamond 1121
        ret     ; CF=0
1122
@@:
1123
; read next sector
1124
        inc     dword [eax]
1125
        cmp     dword [eax], 14
1126
        jae     flp_root_first.readerr
1127
flp_root_first:
1128
        mov     eax, [eax]
1129
        pusha
1130
        add     eax, 19
75 diamond 1131
        call    read_chs_sector
83 diamond 1132
        popa
75 diamond 1133
        cmp     [FDC_Status], 0
83 diamond 1134
        jnz     .readerr
75 diamond 1135
        mov     edi, 0xD000
83 diamond 1136
        ret     ; CF=0
1137
.readerr:
1138
        stc
1139
        ret
1140
 
1141
flp_rootmem_first:
1142
        mov     edi, 0x8000
1143
        clc
1144
        ret
1145
flp_rootmem_next:
1146
        add     edi, 0x20
1147
        cmp     edi, 0x8000+14*0x200
1148
        cmc
1149
flp_rootmem_next_write:
1150
flp_rootmem_begin_write:
1151
flp_rootmem_end_write:
1152
        ret
1153
flp_rootmem_extend_dir:
1154
        stc
1155
        ret
1156
 
1157
flp_notroot_next:
1158
        cmp     edi, 0xD200-0x20
1159
        jae     flp_notroot_next_sector
1160
        add     edi, 0x20
1161
        ret     ; CF=0
1162
flp_notroot_next_sector:
1163
        push    ecx
1164
        mov     ecx, [eax]
1165
        mov     ecx, [ecx*2+0x282000]
1166
        and     ecx, 0xFFF
1167
        cmp     ecx, 2849
1168
        jae     flp_notroot_first.err2
1169
        mov     [eax], ecx
1170
        pop     ecx
1171
flp_notroot_first:
1172
        mov     eax, [eax]
1173
        cmp     eax, 2
1174
        jb      .err
1175
        cmp     eax, 2849
1176
        jae     .err
1177
        pusha
75 diamond 1178
        add     eax, 31
83 diamond 1179
        call    read_chs_sector
1180
        popa
1181
        mov     edi, 0xD000
1182
        cmp     [FDC_Status], 0
1183
        jnz     .err
1184
        ret     ; CF=0
1185
.err2:
1186
        pop     ecx
1187
.err:
1188
        stc
75 diamond 1189
        ret
83 diamond 1190
flp_notroot_begin_write:
1191
        pusha
1192
        mov     eax, [eax]
1193
        add     eax, 31
1194
        call    read_chs_sector
1195
        popa
1196
        ret
1197
flp_notroot_end_write:
1198
        pusha
1199
        mov     eax, [eax]
1200
        add     eax, 31
1201
        call    save_chs_sector
1202
        popa
1203
        ret
1204
flp_notroot_next_write:
1205
        cmp     edi, 0xD200
1206
        jae     @f
1207
        ret
1208
@@:
1209
        call    flp_notroot_end_write
1210
        jmp     flp_notroot_next_sector
1211
flp_notroot_extend_dir:
1212
; find free cluster in FAT
1213
        pusha
1214
        xor     eax, eax
1215
        mov     edi, 0x282000
1216
        mov     ecx, 2849
1217
        repnz   scasw
1218
        jnz     .notfound
1219
        mov     word [edi-2], 0xFFF     ; mark as last cluster
1220
        sub     edi, 0x282000
1221
        shr     edi, 1
1222
        dec     edi
1223
        mov     eax, [esp+28]
1224
        mov     ecx, [eax]
1225
        mov     [0x282000+ecx*2], di
1226
        mov     [eax], edi
1227
        xor     eax, eax
1228
        mov     edi, 0xD000
1229
        mov     ecx, 128
1230
        rep     stosd
1231
        popa
1232
        call    flp_notroot_end_write
1233
        mov     edi, 0xD000
1234
        clc
1235
        ret
1236
.notfound:
1237
        popa
1238
        stc
1239
        ret
71 diamond 1240
 
83 diamond 1241
fd_find_lfn:
1242
; in: esi->name
1243
; out: CF=1 - file not found
86 diamond 1244
;      else CF=0 and edi->direntry, eax=directory cluster (0 for root)
83 diamond 1245
        push    esi edi
1246
        push    0
1247
        push    flp_root_first
1248
        push    flp_root_next
1249
.loop:
1250
        call    fat_find_lfn
1251
        jc      .notfound
1252
        cmp     byte [esi], 0
1253
        jz      .found
1254
        test    byte [edi+11], 10h
1255
        jz      .notfound
1256
        movzx   eax, word [edi+26]      ; cluster
1257
        mov     [esp+8], eax
1258
        mov     dword [esp+4], flp_notroot_first
1259
        mov     dword [esp], flp_notroot_next
1260
        jmp     .loop
1261
.notfound:
1262
        add     esp, 12
1263
        pop     edi esi
1264
        stc
1265
        ret
1266
.found:
86 diamond 1267
        mov     eax, [esp+8]
83 diamond 1268
        add     esp, 16         ; CF=0
1269
        pop     esi
1270
        ret
1271
 
71 diamond 1272
;----------------------------------------------------------------
1273
;
1274
;  fs_FloppyRead - LFN variant for reading floppy
1275
;
1276
;  esi  points to filename
1277
;  ebx  pointer to 64-bit number = first wanted byte, 0+
1278
;       may be ebx=0 - start from first byte
1279
;  ecx  number of bytes to read, 0+
1280
;  edx  mem location to return data
1281
;
77 diamond 1282
;  ret ebx = bytes read or 0xffffffff file not found
71 diamond 1283
;      eax = 0 ok read or other = errormsg
1284
;
1285
;--------------------------------------------------------------
1286
fs_FloppyRead:
75 diamond 1287
        call    read_flp_fat
1288
        cmp     byte [esi], 0
1289
        jnz     @f
1290
        or      ebx, -1
1291
        mov     eax, 10         ; access denied
1292
        ret
71 diamond 1293
@@:
75 diamond 1294
        push    edi
1295
        call    fd_find_lfn
1296
        jnc     .found
1297
        pop     edi
1298
        or      ebx, -1
1299
        mov     eax, 5          ; file not found
1300
        ret
71 diamond 1301
.found:
75 diamond 1302
        test    ebx, ebx
1303
        jz      .l1
1304
        cmp     dword [ebx+4], 0
1305
        jz      @f
77 diamond 1306
        xor     ebx, ebx
71 diamond 1307
.reteof:
75 diamond 1308
        mov     eax, 6          ; EOF
1309
        pop     edi
1310
        ret
71 diamond 1311
@@:
75 diamond 1312
        mov     ebx, [ebx]
71 diamond 1313
.l1:
77 diamond 1314
        push    ecx edx
1315
        push    0
1316
        mov     eax, [edi+28]
1317
        sub     eax, ebx
1318
        jb      .eof
1319
        cmp     eax, ecx
1320
        jae     @f
1321
        mov     ecx, eax
1322
        mov     byte [esp], 6           ; EOF
1323
@@:
75 diamond 1324
        movzx   edi, word [edi+26]
71 diamond 1325
.new:
75 diamond 1326
        jecxz   .done
1327
        test    edi, edi
1328
        jz      .eof
1329
        cmp     edi, 0xFF8
1330
        jae     .eof
77 diamond 1331
        lea     eax, [edi+31]
75 diamond 1332
        pusha
1333
        call    read_chs_sector
1334
        popa
1335
        cmp     [FDC_Status], 0
1336
        jnz     .err
1337
        sub     ebx, 512
1338
        jae     .skip
77 diamond 1339
        lea     eax, [0xD000+ebx+512]
75 diamond 1340
        neg     ebx
1341
        push    ecx
1342
        cmp     ecx, ebx
1343
        jbe     @f
1344
        mov     ecx, ebx
71 diamond 1345
@@:
75 diamond 1346
        mov     ebx, edx
1347
        call    memmove
1348
        add     edx, ecx
1349
        sub     [esp], ecx
1350
        pop     ecx
1351
        xor     ebx, ebx
71 diamond 1352
.skip:
75 diamond 1353
        movzx   edi, word [edi*2+0x282000]
1354
        jmp     .new
71 diamond 1355
.done:
77 diamond 1356
        mov     ebx, edx
1357
        pop     eax edx ecx edi
1358
        sub     ebx, edx
75 diamond 1359
        ret
71 diamond 1360
.eof:
77 diamond 1361
        mov     ebx, edx
1362
        pop     eax edx ecx
75 diamond 1363
        jmp     .reteof
71 diamond 1364
.err:
77 diamond 1365
        mov     ebx, edx
1366
        pop     eax edx ecx edi
1367
        sub     ebx, edx
83 diamond 1368
        mov     al, 11
75 diamond 1369
        ret
1370
 
1371
;----------------------------------------------------------------
1372
;
1373
;  fs_FloppyReadFolder - LFN variant for reading floppy folders
1374
;
1375
;  esi  points to filename
78 diamond 1376
;  ebx  pointer to structure: 32-bit number = first wanted block, 0+
1377
;                           & flags (bitfields)
1378
; flags: bit 0: 0=ANSI names, 1=UNICODE names
75 diamond 1379
;  ecx  number of blocks to read, 0+
1380
;  edx  mem location to return data
1381
;
77 diamond 1382
;  ret ebx = blocks read or 0xffffffff folder not found
75 diamond 1383
;      eax = 0 ok read or other = errormsg
1384
;
1385
;--------------------------------------------------------------
1386
fs_FloppyReadFolder:
1387
        call    read_flp_fat
1388
        push    edi
1389
        cmp     byte [esi], 0
1390
        jz      .root
1391
        call    fd_find_lfn
1392
        jnc     .found
1393
        pop     edi
1394
        or      ebx, -1
1395
        mov     eax, ERROR_FILE_NOT_FOUND
1396
        ret
1397
.found:
1398
        test    byte [edi+11], 0x10     ; do not allow read files
1399
        jnz     .found_dir
1400
        pop     edi
1401
        or      ebx, -1
1402
        mov     eax, ERROR_ACCESS_DENIED
1403
        ret
1404
.found_dir:
1405
        movzx   eax, word [edi+26]
1406
        add     eax, 31
1407
        push    0
1408
        jmp     .doit
1409
.root:
1410
        mov     eax, 19
1411
        push    14
1412
.doit:
1413
        push    ecx ebp
1414
        sub     esp, 262*2      ; reserve space for LFN
1415
        mov     ebp, esp
78 diamond 1416
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE names
1417
        mov     ebx, [ebx]
75 diamond 1418
; init header
1419
        push    eax ecx
1420
        mov     edi, edx
1421
        mov     ecx, 32/4
1422
        xor     eax, eax
1423
        rep     stosd
1424
        pop     ecx eax
1425
        mov     byte [edx], 1   ; version
1426
        mov     esi, edi        ; esi points to BDFE
1427
.main_loop:
1428
        pusha
1429
        call    read_chs_sector
1430
        popa
1431
        cmp     [FDC_Status], 0
1432
        jnz     .error
1433
        mov     edi, 0xD000
1434
        push    eax
1435
.l1:
1436
        call    fat_get_name
1437
        jc      .l2
1438
        cmp     byte [edi+11], 0xF
1439
        jnz     .do_bdfe
1440
        add     edi, 0x20
1441
        cmp     edi, 0xD200
1442
        jb      .do_bdfe
1443
        pop     eax
1444
        inc     eax
1445
        dec     byte [esp+262*2+12]
1446
        jz      .done
1447
        jns     @f
1448
; read next sector from FAT
1449
        mov     eax, [(eax-31-1)*2+0x282000]
1450
        and     eax, 0xFFF
1451
        cmp     eax, 0xFF8
1452
        jae     .done
1453
        add     eax, 31
1454
        mov     byte [esp+262*2+12], 0
1455
@@:
1456
        pusha
1457
        call    read_chs_sector
1458
        popa
1459
        cmp     [FDC_Status], 0
1460
        jnz     .error
1461
        mov     edi, 0xD000
1462
        push    eax
1463
.do_bdfe:
1464
        inc     dword [edx+8]   ; new file found
1465
        dec     ebx
1466
        jns     .l2
1467
        dec     ecx
1468
        js      .l2
1469
        inc     dword [edx+4]   ; new file block copied
1470
        call    fat_entry_to_bdfe
1471
.l2:
1472
        add     edi, 0x20
1473
        cmp     edi, 0xD200
1474
        jb      .l1
1475
        pop     eax
1476
        inc     eax
1477
        dec     byte [esp+262*2+12]
1478
        jz      .done
1479
        jns     @f
1480
; read next sector from FAT
1481
        mov     eax, [(eax-31-1)*2+0x282000]
1482
        and     eax, 0xFFF
1483
        cmp     eax, 0xFF8
1484
        jae     .done
1485
        add     eax, 31
1486
        mov     byte [esp+262*2+12], 0
1487
@@:
1488
        jmp     .main_loop
1489
.error:
1490
        add     esp, 262*2+4
1491
        pop     ebp ecx edi edi
1492
        or      ebx, -1
1493
        mov     eax, ERROR_FILE_NOT_FOUND
1494
        ret
1495
.done:
1496
        add     esp, 262*2+4
1497
        pop     ebp
77 diamond 1498
        mov     ebx, [edx+4]
75 diamond 1499
        xor     eax, eax
1500
        dec     ecx
1501
        js      @f
1502
        mov     al, ERROR_END_OF_FILE
1503
@@:
1504
        pop     ecx edi edi
1505
        ret
1506
 
83 diamond 1507
;----------------------------------------------------------------
1508
;
1509
;  fs_FloppyRewrite - LFN variant for writing sys floppy
1510
;
1511
;  esi  points to filename
1512
;  ebx  ignored (reserved)
1513
;  ecx  number of bytes to write, 0+
1514
;  edx  mem location to data
1515
;
1516
;  ret ebx = number of written bytes
1517
;      eax = 0 ok read or other = errormsg
1518
;
1519
;--------------------------------------------------------------
1520
@@:
1521
        mov     eax, ERROR_ACCESS_DENIED
1522
        xor     ebx, ebx
1523
        ret
1524
fsfrfe2:
1525
        popad
1526
fsfrfe:
1527
        mov     eax, 11
1528
        xor     ebx, ebx
1529
        ret
1530
 
1531
fs_FloppyRewrite:
1532
        cmp     byte [esi], 0
1533
        jz      @b
1534
        call    read_flp_fat
1535
        cmp     [FDC_Status], 0
1536
        jnz     fsfrfe
1537
        pushad
1538
        xor     ebp, ebp
1539
        push    esi
1540
@@:
1541
        lodsb
1542
        test    al, al
1543
        jz      @f
1544
        cmp     al, '/'
1545
        jnz     @b
1546
        lea     ebp, [esi-1]
1547
        jmp     @b
1548
@@:
1549
        pop     esi
1550
        test    ebp, ebp
1551
        jnz     .noroot
1552
        call    read_flp_root
1553
        cmp     [FDC_Status], 0
1554
        jnz     fsfrfe2
1555
        push    flp_rootmem_extend_dir
1556
        push    flp_rootmem_end_write
1557
        push    flp_rootmem_next_write
1558
        push    flp_rootmem_begin_write
1559
        xor     ebp, ebp
1560
        push    ebp
1561
        push    flp_rootmem_first
1562
        push    flp_rootmem_next
1563
        jmp     .common1
1564
.noroot:
1565
; check existence
1566
        mov     byte [ebp], 0
1567
        call    fd_find_lfn
1568
        mov     byte [ebp], '/'
1569
        lea     esi, [ebp+1]
1570
        jnc     @f
1571
        mov     eax, ERROR_FILE_NOT_FOUND
1572
.ret1:
1573
        mov     [esp+28], eax
1574
        popad
1575
        xor     ebx, ebx
1576
        ret
1577
@@:
1578
        test    byte [edi+11], 0x10     ; must be directory
1579
        mov     eax, ERROR_ACCESS_DENIED
1580
        jz      .ret1
1581
        movzx   ebp, word [edi+26]      ; ebp=cluster
1582
        mov     eax, ERROR_FAT_TABLE
1583
        cmp     ebp, 2
1584
        jb      .ret1
1585
        cmp     ebp, 2849
1586
        jae     .ret1
1587
        push    flp_notroot_extend_dir
1588
        push    flp_notroot_end_write
1589
        push    flp_notroot_next_write
1590
        push    flp_notroot_begin_write
1591
        push    ebp
1592
        push    flp_notroot_first
1593
        push    flp_notroot_next
1594
.common1:
1595
        call    fat_find_lfn
1596
        jc      .notfound
1597
; found, delete FAT chain
1598
        push    edi
1599
        xor     eax, eax
1600
        mov     dword [edi+28], eax     ; zero size
1601
        xchg    ax, word [edi+26]       ; start cluster
1602
        test    eax, eax
1603
        jz      .done1
1604
@@:
1605
        cmp     eax, 0xFF8
1606
        jae     .done1
1607
        lea     edi, [0x282000 + eax*2] ; position in FAT
1608
        xor     eax, eax
1609
        xchg    ax, [edi]
1610
        jmp     @b
1611
.done1:
1612
        pop     edi
1613
        call    get_time_for_file
1614
        mov     [edi+22], ax
1615
        call    get_date_for_file
1616
        mov     [edi+24], ax
1617
        mov     [edi+18], ax
1618
        or      byte [edi+11], 20h      ; set 'archive' attribute
1619
        jmp     .doit
1620
.notfound:
1621
; file is not found; generate short name
1622
        call    fat_name_is_legal
1623
        jc      @f
1624
        add     esp, 28
1625
        popad
1626
        mov     eax, ERROR_FILE_NOT_FOUND
1627
        xor     ebx, ebx
1628
        ret
1629
@@:
1630
        sub     esp, 12
1631
        mov     edi, esp
1632
        call    fat_gen_short_name
1633
.test_short_name_loop:
1634
        push    esi edi ecx
1635
        mov     esi, edi
1636
        lea     eax, [esp+12+12+8]
1637
        mov     [eax], ebp
1638
        call    dword [eax-4]
1639
        jc      .found
1640
.test_short_name_entry:
1641
        cmp     byte [edi+11], 0xF
1642
        jz      .test_short_name_cont
1643
        mov     ecx, 11
1644
        push    esi edi
1645
        repz    cmpsb
1646
        pop     edi esi
1647
        jz      .short_name_found
1648
.test_short_name_cont:
1649
        lea     eax, [esp+12+12+8]
1650
        call    dword [eax-8]
1651
        jnc     .test_short_name_entry
1652
        jmp     .found
1653
.short_name_found:
1654
        pop     ecx edi esi
1655
        call    fat_next_short_name
1656
        jnc     .test_short_name_loop
1657
.disk_full:
1658
        add     esp, 12+28
1659
        popa
1660
        mov     eax, ERROR_DISK_FULL
1661
        xor     ebx, ebx
1662
        ret
1663
.found:
1664
        pop     ecx edi esi
1665
; now find space in directory
1666
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1667
        mov     al, '~'
1668
        push    ecx edi
1669
        mov     ecx, 8
1670
        repnz   scasb
1671
        push    1
1672
        pop     eax     ; 1 entry
1673
        jnz     .notilde
1674
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1675
        xor     eax, eax
1676
@@:
1677
        cmp     byte [esi], 0
1678
        jz      @f
1679
        inc     esi
1680
        inc     eax
1681
        jmp     @b
1682
@@:
1683
        sub     esi, eax
1684
        add     eax, 12+13
1685
        mov     ecx, 13
1686
        push    edx
1687
        cdq
1688
        div     ecx
1689
        pop     edx
1690
.notilde:
1691
        push    -1
1692
        push    -1
1693
; find  successive entries in directory
1694
        xor     ecx, ecx
1695
        push    eax
1696
        lea     eax, [esp+12+8+12+8]
1697
        mov     [eax], ebp
1698
        call    dword [eax-4]
1699
        pop     eax
1700
        jnc     .scan_dir
1701
.fsfrfe3:
1702
        add     esp, 8+8+12+28
1703
        popad
1704
        mov     eax, 11
1705
        xor     ebx, ebx
1706
        ret
1707
.scan_dir:
1708
        cmp     byte [edi], 0
1709
        jz      .free
1710
        cmp     byte [edi], 0xE5
1711
        jz      .free
1712
        xor     ecx, ecx
1713
.scan_cont:
1714
        push    eax
1715
        lea     eax, [esp+12+8+12+8]
1716
        call    dword [eax-8]
1717
        pop     eax
1718
        jnc     .scan_dir
1719
        cmp     [FDC_Status], 0
1720
        jnz     .fsfrfe3
1721
        push    eax
1722
        lea     eax, [esp+12+8+12+8]
1723
        call    dword [eax+16]          ; extend directory
1724
        pop     eax
1725
        jnc     .scan_dir
1726
        add     esp, 8+8+12+28
1727
        popad
1728
        mov     eax, ERROR_DISK_FULL
1729
        xor     ebx, ebx
1730
        ret
1731
.free:
1732
        test    ecx, ecx
1733
        jnz     @f
1734
        mov     [esp], edi
1735
        mov     ecx, [esp+8+8+12+8]
1736
        mov     [esp+4], ecx
1737
        xor     ecx, ecx
1738
@@:
1739
        inc     ecx
1740
        cmp     ecx, eax
1741
        jb      .scan_cont
1742
; found!
1743
; calculate name checksum
1744
        push    esi ecx
1745
        mov     esi, [esp+8+8]
1746
        mov     ecx, 11
1747
        xor     eax, eax
1748
@@:
1749
        ror     al, 1
1750
        add     al, [esi]
1751
        inc     esi
1752
        loop    @b
1753
        pop     ecx esi
1754
        pop     edi
1755
        pop     dword [esp+8+12+8]
1756
; edi points to first entry in free chunk
1757
        dec     ecx
1758
        jz      .nolfn
1759
        push    esi
1760
        push    eax
1761
        lea     eax, [esp+8+8+12+8]
1762
        call    dword [eax+4]         ; begin write
1763
        mov     al, 40h
1764
.writelfn:
1765
        or      al, cl
1766
        mov     esi, [esp+4]
1767
        push    ecx
1768
        dec     ecx
1769
        imul    ecx, 13
1770
        add     esi, ecx
1771
        stosb
1772
        mov     cl, 5
1773
        call    fs_RamdiskRewrite.read_symbols
1774
        mov     ax, 0xF
1775
        stosw
1776
        mov     al, [esp+4]
1777
        stosb
1778
        mov     cl, 6
1779
        call    fs_RamdiskRewrite.read_symbols
1780
        xor     eax, eax
1781
        stosw
1782
        mov     cl, 2
1783
        call    fs_RamdiskRewrite.read_symbols
1784
        pop     ecx
1785
        lea     eax, [esp+8+8+12+8]
1786
        call    dword [eax+8]         ; next write
1787
        xor     eax, eax
1788
        loop    .writelfn
1789
        pop     eax
1790
        pop     esi
1791
;        lea     eax, [esp+8+12+8]
1792
;        call    dword [eax+12]          ; end write
1793
.nolfn:
1794
        xchg    esi, [esp]
1795
        mov     ecx, 11
1796
        rep     movsb
1797
        mov     word [edi], 20h         ; attributes
1798
        sub     edi, 11
1799
        pop     esi ecx
1800
        add     esp, 12
1801
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1802
        call    get_time_for_file
1803
        mov     [edi+14], ax            ; creation time
1804
        mov     [edi+22], ax            ; last write time
1805
        call    get_date_for_file
1806
        mov     [edi+16], ax            ; creation date
1807
        mov     [edi+24], ax            ; last write date
1808
        mov     [edi+18], ax            ; last access date
1809
        and     word [edi+20], 0        ; high word of cluster
1810
        and     word [edi+26], 0        ; low word of cluster - to be filled
1811
        and     dword [edi+28], 0       ; file size - to be filled
1812
.doit:
1813
        lea     eax, [esp+8]
1814
        call    dword [eax+12]  ; flush directory
1815
        push    ecx
1816
        push    edi
1817
        add     edi, 26         ; edi points to low word of cluster
1818
        push    edi
1819
        mov     esi, edx
1820
        jecxz   .done
1821
        mov     ecx, 2849
1822
        mov     edi, 0x282000
1823
        push    0       ; first cluster
1824
.write_loop:
1825
; allocate new cluster
1826
        xor     eax, eax
1827
        repnz   scasw
1828
        mov     al, ERROR_DISK_FULL
1829
        jnz     .ret
1830
        dec     edi
1831
        dec     edi
1832
        lea     eax, [edi-0x282000]
1833
        shr     eax, 1                  ; eax = cluster
1834
        mov     word [edi], 0xFFF       ; mark as last cluster
1835
        cmp     dword [esp], 0
1836
        jz      .first
1837
        xchg    edi, [esp+4]
1838
        stosw
1839
        mov     edi, [esp+4]
1840
        jmp     @f
1841
.first:
1842
        mov     [esp], eax
1843
@@:
1844
        inc     ecx
1845
; write data
1846
        push    ecx edi
1847
        mov     ecx, 512
1848
        cmp     dword [esp+20], ecx
1849
        jae     @f
1850
        mov     ecx, [esp+20]
1851
@@:
1852
        push    ecx
1853
        mov     edi, 0xD000
1854
        rep     movsb
1855
        pop     ecx
1856
        push    ecx
1857
        sub     ecx, 512
1858
        neg     ecx
1859
        push    eax
1860
        xor     eax, eax
1861
        rep     stosb
1862
        pop     eax
1863
        add     eax, 31
1864
        pusha
1865
        call    save_chs_sector
1866
        popa
1867
        pop     ecx
1868
        cmp     [FDC_Status], 0
1869
        jnz     .diskerr
1870
        sub     [esp+20], ecx
1871
        pop     edi ecx
1872
        jnz     .write_loop
1873
.done:
1874
        xor     eax, eax
1875
.ret:
1876
        pop     ebx edi edi ecx
1877
        mov     [esp+28+28], eax
1878
        lea     eax, [esp+8]
1879
        call    dword [eax+4]
1880
        mov     [edi+26], bx
1881
        mov     ebx, esi
1882
        sub     ebx, edx
1883
        mov     [edi+28], ebx
1884
        call    dword [eax+12]
1885
        mov     [esp+28+16], ebx
1886
        test    ebp, ebp
1887
        jnz     @f
1888
        call    save_flp_root
1889
@@:
1890
        add     esp, 28
1891
        cmp     [FDC_Status], 0
1892
        jnz     .err3
1893
        call    save_flp_fat
1894
        cmp     [FDC_Status], 0
1895
        jnz     .err3
1896
        popa
1897
        ret
1898
.err3:
1899
        popa
1900
        mov     al, 11
1901
        xor     ebx, ebx
1902
        ret
1903
.diskerr:
1904
        sub     esi, ecx
1905
        mov     eax, 11
1906
        pop     edi ecx
1907
        jmp     .ret
1908
 
86 diamond 1909
fs_FloppyGetFileInfo:
1910
        call    read_flp_fat
1911
        cmp     [FDC_Status], 0
1912
        jnz     ret11
1913
        cmp     byte [esi], 0
1914
        jnz     @f
1915
        mov     eax, 2  ; unsupported
1916
        ret
1917
@@:
1918
        push    edi
1919
        call    fd_find_lfn
1920
        jmp     fs_GetFileInfo_finish
1921
 
1922
ret11:
1923
        mov     eax, 11
1924
        ret
1925
 
1926
fs_FloppySetFileInfo:
1927
        call    read_flp_fat
1928
        cmp     [FDC_Status], 0
1929
        jnz     ret11
1930
        cmp     byte [esi], 0
1931
        jnz     @f
1932
        mov     eax, 2  ; unsupported
1933
        ret
1934
@@:
1935
        push    edi
1936
        call    fd_find_lfn
1937
        jnc     @f
1938
        pop     edi
1939
        mov     eax, ERROR_FILE_NOT_FOUND
1940
        ret
1941
@@:
1942
        push    eax
1943
        call    bdfe_to_fat_entry
1944
        pop     eax
1945
        test    eax, eax
1946
        jz      .root
1947
        add     eax, 31
1948
        pusha
1949
        call    save_chs_sector
1950
        popa
1951
        jmp     .cmn
1952
.root:
1953
        call    save_flp_root
1954
.cmn:
1955
        pop     edi
1956
        xor     eax, eax
1957
        cmp     [FDC_Status], 0
1958
        jz      @f
1959
        mov     al, 11
1960
@@:
1961
        ret
1962
 
78 diamond 1963
; \end{diamond}