Subversion Repositories Kolibri OS

Rev

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

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