Subversion Repositories Kolibri OS

Rev

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

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