Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ha 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;;  FAT32.INC                                                      ;;
4
;;                                                                 ;;
5
;;  FAT16/32 functions for MenuetOS                                ;;
6
;;                                                                 ;;
7
;;  Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it          ;;
8
;;                                                                 ;;
9
;;  See file COPYING for details                                   ;;
10
;;                                                                 ;;
11
;;  15.01.2005 get file size/attr/date, file_append - ATV          ;;
12
;;  04.12.2004 skip volume label, file delete bug fixed - ATV      ;;
13
;;  29.11.2004 get_free_FAT changed, append dir bug fixed - ATV    ;;
14
;;  23.11.2004 don't allow overwrite dir with file - ATV           ;;
15
;;  18.11.2004 get_disk_info and more error codes - ATV            ;;
16
;;  17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV      ;;
17
;;  10.11.2004 removedir clear whole directory structure - ATV     ;;
18
;;  08.11.2004 rename - ATV                                        ;;
19
;;  30.10.2004 file_read return also dirsize in bytes - ATV        ;;
20
;;  20.10.2004 Makedir/Removedir - ATV                             ;;
21
;;  14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx)         ;;
22
;;  06.9.2004  Fix free space by Mario79 added - MH                ;;
23
;;  24.5.2004  Write back buffer for File_write -VT                ;;
24
;;  20.5.2004  File_read function to work with syscall 58 - VT     ;;
25
;;  30.3.2004  Error parameters at function return - VT            ;;
26
;;  01.5.2002  Bugfix in device write - VT                         ;;
27
;;  20.5.2002  Hd status check - VT                                ;;
28
;;  29.6.2002  Improved fat32 verification - VT                    ;;
29
;;                                                                 ;;
30
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31
 
32
cache_max equ 1919      ; max. is 1919*512+0x610000=0x6ffe00
33
 
34
ERROR_DISK_BASE      equ 1
35
ERROR_UNSUPPORTED_FS equ 2
36
ERROR_UNKNOWN_FS     equ 3
37
ERROR_PARTITION      equ 4
38
ERROR_FILE_NOT_FOUND equ 5
39
ERROR_END_OF_FILE    equ 6
40
ERROR_MEMORY_POINTER equ 7
41
ERROR_DISK_FULL      equ 8
42
ERROR_FAT_TABLE      equ 9
43
ERROR_ACCESS_DENIED  equ 10
44
 
45
PUSHAD_EAX equ [esp+28]
46
PUSHAD_ECX equ [esp+24]
47
PUSHAD_EDX equ [esp+20]
48
PUSHAD_EBX equ [esp+16]
49
PUSHAD_EBP equ [esp+8]
50
PUSHAD_ESI equ [esp+4]
51
PUSHAD_EDI equ [esp+0]
52
 
53
align 4
54
;******************************************************
55
; Please do not change this place - variables  in text
56
; Mario79
57
; START place
58
;******************************************************
59
PARTITION_START      dd 0x3f
60
PARTITION_END        dd 0
61
SECTORS_PER_FAT      dd 0x1f3a
62
NUMBER_OF_FATS       dd 0x2
63
SECTORS_PER_CLUSTER  dd 0x8
64
BYTES_PER_SECTOR     dd 0x200   ; Note: if BPS <> 512 need lots of changes
65
ROOT_CLUSTER         dd 2       ; first rootdir cluster
66
FAT_START            dd 0       ; start of fat table
67
ROOT_START           dd 0       ; start of rootdir (only fat16)
68
ROOT_SECTORS         dd 0       ; count of rootdir sectors (only fat16)
69
DATA_START           dd 0       ; start of data area (=first cluster 2)
70
LAST_CLUSTER         dd 0       ; last availabe cluster
71
ADR_FSINFO           dd 0       ; used only by fat32
72
 
73
fatRESERVED          dd 0x0FFFFFF6
74
fatBAD               dd 0x0FFFFFF7
75
fatEND               dd 0x0FFFFFF8
76
fatMASK              dd 0x0FFFFFFF
77
 
78
fat_type             db 0       ; 0=none, 16=fat16, 32=fat32
79
;***************************************************************************
80
; End place
81
; Mario79
82
;***************************************************************************
83
cluster              dd 0       ; used by file_write,makedir,append
84
partition_count      dd 0       ; partitions found by set_FAT32_variables
85
longname_sec1        dd 0       ; used by analyze_directory to save 2 previous
86
longname_sec2        dd 0       ; directory sectors for delete long filename
87
 
88
hd_error             dd 0       ; set by wait_for_sector_buffer
89
hd_setup             dd 0
90
hd_wait_timeout      dd 0
91
 
92
cluster_tmp          dd 0       ; used by analyze_directory
93
                                ; and analyze_directory_to_write
94
 
95
file_size            dd 0       ; used by file_read
96
 
97
sector_tmp           dd 0       ; used by rename,append,file_write
98
entry_pos            dd 0       ; used by rename,append,file_write
99
 
100
old_filesize         dd 0       ; used by append
101
new_filepos          dd 0       ; used by append
102
bytes2write          dd 0       ; used by append
103
 
104
cache_search_start   dd 0       ; used by find_empty_slot
105
 
106
fat_in_cache         dd -1
107
fat_cache:           times 512 db 0
108
 
109
uglobal
110
 Sector512:                      ; label for dev_hdcd.inc
111
  buffer:              times 512 db 0
112
  deltree_buffer:      times 512 db 0
113
endg
114
 
115
iglobal
116
  NewDirEntry1         db ".          ",0x10
117
                     times 20 db 0
118
  NewDirEntry2         db "..         ",0x10
119
                     times 20 db 0
120
endg
121
 
122
uglobal
123
  dir_entry:           times 32 db 0
124
 
125
  startpath:           times 255 db 0
126
 
127
  fat16_root           db 0       ; flag for fat16 rootdir
128
  f_del                db 0       ; 1=overwrite fat entry
129
  fat_change           db 0       ; 1=fat has changed
130
 
131
endg
132
 
133
iglobal
134
  partition_types:              ; list of fat16/32 partitions
135
    db    0x04                  ; DOS: fat16 <32M
136
    db    0x06                  ; DOS: fat16 >32M
137
    db    0x0b                  ; WIN95: fat32
138
    db    0x0c                  ; WIN95: fat32, LBA-mapped
139
    db    0x0e                  ; WIN95: fat16, LBA-mapped
140
    db    0x14                  ; Hidden DOS: fat16 <32M
141
    db    0x16                  ; Hidden DOS: fat16 >32M
142
    db    0x1b                  ; Hidden WIN95: fat32
143
    db    0x1c                  ; Hidden WIN95: fat32, LBA-mapped
144
    db    0x1e                  ; Hidden WIN95: fat16, LBA-mapped
145
    db    0xc4                  ; DRDOS/secured: fat16 <32M
146
    db    0xc6                  ; DRDOS/secured: fat16 >32M
147
    db    0xcb                  ; DRDOS/secured: fat32
148
    db    0xcc                  ; DRDOS/secured: fat32, LBA-mapped
149
    db    0xce                  ; DRDOS/secured: fat16, LBA-mapped
150
    db    0xd4                  ; Old Multiuser DOS secured: fat16 <32M
151
    db    0xd6                  ; Old Multiuser DOS secured: fat16 >32M
152
  partition_types_end:
153
 
154
 
155
  extended_types:               ; list of extended partitions
156
    db    0x05                  ; DOS: extended partition
157
    db    0x0f                  ; WIN95: extended partition, LBA-mapped
158
    db    0xc5                  ; DRDOS/secured: extended partition
159
    db    0xd5                  ; Old Multiuser DOS secured: extended partition
160
  extended_types_end:
161
 
162
endg
163
 
164
 
165
reserve_hd1:
166
 
167
    cli
168
    cmp   [hd1_status],0
169
    je    reserve_ok1
170
 
171
    sti
172
    call  change_task
173
    jmp   reserve_hd1
174
 
175
  reserve_ok1:
176
 
177
    push  eax
178
    mov   eax,[0x3000]
179
    shl   eax,5
180
    mov   eax,[eax+0x3000+4]
181
    mov   [hd1_status],eax
182
    pop   eax
183
    sti
184
    ret
185
 
186
 
187
clear_hd_cache:
188
 
189
    push  eax ecx edi
190
    mov   edi,0x600000
191
    mov   ecx,16384
192
    xor   eax,eax
193
    cld
194
    rep   stosd                 ; clear hd cache with 0
195
    mov   [cache_search_start],eax
196
    mov   [fat_in_cache],-1
197
    mov   [fat_change],0
198
    pop   edi ecx eax
199
    ret
200
 
201
problem_partition db 0  ; used for partitions search
202
 
203
; Partition chain used:
204
; MBR        ;   PARTITION2 ;   PARTITION3 ;   PARTITION4
205
;==========================================================
206
; fat16/32   +-- fat16/32   +-- fat16/32   +-- fat16/32   +--
207
; extended --+   extended --+   extended --+   extended --+
208
; 0              0              0              0
209
; 0              0              0              0
210
; Notes:
211
; - extended partition need to be in second entry on table
212
; - it will skip over removed partitions
213
 
214
set_FAT32_variables:
215
    mov   [0xfe10],dword 0      ; entries in hd cache
216
    mov   [problem_partition],0
217
    call  reserve_hd1
218
    call  clear_hd_cache
219
 
220
    cmp   dword [hdpos],0
221
    je    problem_hd
222
 
223
    pushad
224
    xor   ecx,ecx               ; partition count
225
    mov   edx,-1                ; flag for partition
226
    xor   eax,eax               ; read MBR
227
    xor   ebp,ebp               ; extended partition start
228
 
229
new_partition:
230
    test  ebp,ebp               ; is there extended partition?
231
    jnz   extended_already_set  ; yes
232
    xchg  ebp,eax               ; no. set it now
233
 
234
extended_already_set:
235
    add   eax,ebp               ; mbr=mbr+0, ext_part=ext_start+relat_start
236
    mov   ebx,buffer
237
    call  hd_read
238
 
239
    cmp   word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
240
    jnz   end_partition_chain
241
    cmp   dword [ebx+0x1be+0xc],0 ; skip over empty partition
242
    jz    next_partition
243
 
244
    push  eax ecx
245
    mov   edi,partition_types
246
    mov   ecx,partition_types_end-partition_types
247
    mov   al,[ebx+0x1be+4]      ; get partition type
248
    cld
249
    repne scasb                 ; is partition type ok?
250
    pop   ecx eax
251
    jnz   next_partition        ; no. skip over
252
 
253
    inc   ecx
254
    cmp   ecx,[fat32part]       ; is it wanted partition?
255
    jnz   next_partition        ; no
256
 
257
    mov   edx,eax               ; start sector
258
    add   edx,[ebx+0x1be+8]     ; add relative start
259
 
260
next_partition:
261
    push  ecx
262
    mov   edi,extended_types
263
    mov   ecx,extended_types_end-extended_types
264
    mov   al,[ebx+0x1be+4+16]   ; get second partition type
265
    cld
266
    repne scasb                 ; is it extended partition?
267
    pop   ecx
268
    jnz   end_partition_chain   ; no. end chain
269
 
270
    mov   eax,[ebx+0x1be+8+16]  ; get start of extended partition
271
    test  eax,eax               ; is there extended partition?
272
    jnz   new_partition         ; yes. read it
273
 
274
end_partition_chain:
275
    mov   [partition_count],ecx
276
 
277
    cmp   edx,-1                ; found wanted partition?
278
    jnz   hd_and_partition_ok   ; yes. install it
279
    jmp   problem_partition_or_fat
280
 
281
problem_fat_dec_count:          ; bootsector is missing or another problem
282
    dec   [partition_count]     ; remove it from partition_count
283
 
284
problem_partition_or_fat:
285
    popad
286
 
287
problem_hd:
288
    mov   [fat_type],0
289
    mov   [hd1_status],0        ; free
290
    mov   [problem_partition],1
291
    ret
292
 
293
hd_and_partition_ok:
294
    mov   eax,edx
295
    mov   [PARTITION_START],eax
296
 
297
    mov   [hd_setup],1
298
    mov   ebx,buffer
299
    call  hd_read               ; read boot sector of partition
300
    mov   [hd_setup],0
301
 
302
    cmp   word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
303
    jnz   problem_fat_dec_count
304
 
305
    movzx eax,word [ebx+0xe]    ; sectors reserved
306
    add   eax,[PARTITION_START]
307
    mov   [FAT_START],eax       ; fat_start = partition_start + reserved
308
 
309
    movzx eax,byte [ebx+0xd]    ; sectors per cluster
310
    mov   [SECTORS_PER_CLUSTER],eax
311
 
312
    movzx ecx,word [ebx+0xb]    ; bytes per sector
313
    mov   [BYTES_PER_SECTOR],ecx
314
 
315
    movzx eax,word [ebx+0x11]   ; count of rootdir entries (=0 fat32)
316
    mov   edx,32
317
    mul   edx
318
    dec   ecx
319
    add   eax,ecx               ; round up if not equal count
320
    inc   ecx                   ; bytes per sector
321
    div   ecx
322
    mov   [ROOT_SECTORS],eax    ; count of rootdir sectors
323
 
324
    movzx eax,word [ebx+0x16]   ; sectors per fat <65536
325
    test  eax,eax
326
    jnz   fat16_fatsize
327
    mov   eax,[ebx+0x24]        ; sectors per fat
328
  fat16_fatsize:
329
    mov   [SECTORS_PER_FAT],eax
330
 
331
    movzx eax,byte [ebx+0x10]   ; number of fats
332
    test  eax,eax               ; if 0 it's not fat partition
333
    jz    problem_fat_dec_count
334
    mov   [NUMBER_OF_FATS],eax
335
    imul  eax,[SECTORS_PER_FAT]
336
    add   eax,[FAT_START]
337
    mov   [ROOT_START],eax      ; rootdir = fat_start + fat_size * fat_count
338
    add   eax,[ROOT_SECTORS]    ; rootdir sectors should be 0 on fat32
339
    mov   [DATA_START],eax      ; data area = rootdir + rootdir_size
340
 
341
    movzx eax,word [ebx+0x13]   ; total sector count <65536
342
    test  eax,eax
343
    jnz   fat16_total
344
    mov   eax,[ebx+0x20]        ; total sector count
345
  fat16_total:
346
    add   eax,[PARTITION_START]
347
    dec   eax
348
    mov   [PARTITION_END],eax
349
    inc   eax
350
    sub   eax,[DATA_START]      ; eax = count of data sectors
351
    xor   edx,edx
352
    div   dword [SECTORS_PER_CLUSTER]
353
    inc   eax
354
    mov   [LAST_CLUSTER],eax
355
    dec   eax                   ; cluster count
356
 
357
    ; limits by Microsoft Hardware White Paper v1.03
358
    cmp   eax,4085              ; 0xff5
359
    jb    problem_fat_dec_count ; fat12 not supported
360
    cmp   eax,65525             ; 0xfff5
361
    jb    fat16_partition
362
 
363
fat32_partition:
364
    mov   eax,[ebx+0x2c]        ; rootdir cluster
365
    mov   [ROOT_CLUSTER],eax
366
    movzx eax,word [ebx+0x30]   ; fs info sector
367
    add   eax,[PARTITION_START]
368
    mov   [ADR_FSINFO],eax
369
 
370
    popad
371
 
372
    mov   [fatRESERVED],0x0FFFFFF6
373
    mov   [fatBAD],0x0FFFFFF7
374
    mov   [fatEND],0x0FFFFFF8
375
    mov   [fatMASK],0x0FFFFFFF
376
    mov   [fat_type],32         ; Fat32
377
    mov   [hd1_status],0        ; free
378
    ret
379
 
380
fat16_partition:
381
    xor   eax,eax
382
    mov   [ROOT_CLUSTER],eax
383
 
384
    popad
385
 
386
    mov   [fatRESERVED],0x0000FFF6
387
    mov   [fatBAD],0x0000FFF7
388
    mov   [fatEND],0x0000FFF8
389
    mov   [fatMASK],0x0000FFFF
390
    mov   [fat_type],16         ; Fat16
391
    mov   [hd1_status],0        ; free
392
    ret
393
 
394
 
395
set_FAT:
396
;--------------------------------
397
; input  : EAX = cluster
398
;          EDX = value to save
399
; output : EDX = old value
400
;--------------------------------
401
    push  eax ebx esi
402
 
403
    cmp   eax,2
404
    jb    sfc_error
405
    cmp   eax,[LAST_CLUSTER]
406
    ja    sfc_error
407
    cmp   [fat_type],16
408
    je    sfc_1
409
    add   eax,eax
410
  sfc_1:
411
    add   eax,eax
412
    mov   esi,511
413
    and   esi,eax               ; esi = position in fat sector
414
    shr   eax,9                 ; eax = fat sector
415
    add   eax,[FAT_START]
416
    mov   ebx,fat_cache
417
 
418
    cmp   eax,[fat_in_cache]    ; is fat sector already in memory?
419
    je    sfc_in_cache          ; yes
420
 
421
    cmp   [fat_change],0        ; is fat changed?
422
    je    sfc_no_change         ; no
423
    call  write_fat_sector      ; yes. write it into disk
424
 
425
  sfc_no_change:
426
    mov   [fat_in_cache],eax    ; save fat sector
427
    call  hd_read
428
 
429
  sfc_in_cache:
430
    cmp   [fat_type],16
431
    jne   sfc_test32
432
 
433
    cmp   [f_del],1             ; overwrite previous value?
434
    je    sfc_set16             ; yes
435
    cmp   word [ebx+esi],0      ; is cluster free?
436
    je    sfc_set16             ; yes
437
    mov   dword [8*0x100000],0xffffff
438
    mov   edx,[ebx+esi]         ; get old value
439
    jmp   sfc_nonzero
440
 
441
  sfc_set16:
442
    xchg  [ebx+esi],dx          ; save new value and get old value
443
    jmp   sfc_write
444
 
445
  sfc_test32:
446
    mov   eax,[fatMASK]
447
    cmp   [f_del],1             ; overwrite previous value?
448
    je    sfc_set32             ; yes
449
    test  eax,[ebx+esi]         ; is cluster free?
450
    je    sfc_set32             ; yes
451
    mov   dword [8*0x100000],0xffffff
452
    mov   edx,[ebx+esi]         ; get old value
453
    jmp   sfc_nonzero
454
 
455
  sfc_set32:
456
    and   edx,eax
457
    xor   eax,-1                ; mask for high bits
458
    and   eax,[ebx+esi]         ; get high 4 bits
459
    or    eax,edx
460
    mov   edx,[ebx+esi]         ; get old value
461
    mov   [ebx+esi],eax         ; save new value
462
 
463
  sfc_write:
464
    mov   [fat_change],1        ; fat has changed
465
 
466
  sfc_nonzero:
467
    and   edx,[fatMASK]
468
 
469
  sfc_error:
470
    pop   esi ebx eax
471
    ret
472
 
473
 
474
get_FAT:
475
;--------------------------------
476
; input  : EAX = cluster
477
; output : EAX = next cluster
478
;--------------------------------
479
    push  ebx esi
480
 
481
    cmp   [fat_type],16
482
    je    gfc_1
483
    add   eax,eax
484
  gfc_1:
485
    add   eax,eax
486
    mov   esi,511
487
    and   esi,eax               ; esi = position in fat sector
488
    shr   eax,9                 ; eax = fat sector
489
    add   eax,[FAT_START]
490
    mov   ebx,fat_cache
491
 
492
    cmp   eax,[fat_in_cache]    ; is fat sector already in memory?
493
    je    gfc_in_cache
494
 
495
    cmp   [fat_change],0        ; is fat changed?
496
    je    gfc_no_change         ; no
497
    call  write_fat_sector      ; yes. write it into disk
498
 
499
  gfc_no_change:
500
    mov   [fat_in_cache],eax
501
    call  hd_read
502
 
503
  gfc_in_cache:
504
    mov   eax,[ebx+esi]
505
    and   eax,[fatMASK]
506
    pop   esi ebx
507
    ret
508
 
509
 
510
get_free_FAT:
511
;-----------------------------------------------------------
512
; input  : EAX = # cluster for start the searching
513
; output : if CARRY=0 EAX = # first cluster found free
514
;          if CARRY=1 disk full
515
; Note   : for more speed need to use fat_cache directly
516
;-----------------------------------------------------------
517
    push  ecx
518
    mov   ecx,[LAST_CLUSTER]    ; counter for full disk
519
    sub   ecx,2
520
 
521
  gff_test:
522
    cmp   eax,[LAST_CLUSTER]    ; if above last cluster start at cluster 2
523
    jbe   gff_in_range
524
    mov   eax,2
525
 
526
  gff_in_range:
527
    push  eax
528
    call  get_FAT               ; get cluster state
529
    test  eax,eax               ; is it free?
530
    pop   eax
531
    je    gff_found             ; yes
532
    inc   eax                   ; next cluster
533
    dec   ecx                   ; is all checked?
534
    jns   gff_test              ; no
535
 
536
  gff_not_found:
537
    pop   ecx                   ; yes. disk is full
538
    stc
539
    ret
540
 
541
  gff_found:
542
    pop   ecx
543
    clc
544
    ret
545
 
546
 
547
write_fat_sector:
548
;-----------------------------------------------------------
549
; write changed fat to disk
550
;-----------------------------------------------------------
551
    push  eax ebx ecx
552
 
553
    mov   [fat_change],0
554
    mov   eax,[fat_in_cache]
555
    cmp   eax,-1
556
    jz    write_fat_not_used
557
    mov   ebx,fat_cache
558
    mov   ecx,[NUMBER_OF_FATS]
559
 
560
  write_next_fat:
561
    call  hd_write
562
    add   eax,[SECTORS_PER_FAT]
563
    dec   ecx
564
    jnz   write_next_fat
565
 
566
  write_fat_not_used:
567
    pop   ecx ebx eax
568
    ret
569
 
570
 
571
analyze_directory:
572
;-----------------------------------------------------------
573
; input  : EAX = first cluster of the directory
574
;          EBX = pointer to filename
575
; output : IF CARRY=0 EAX = sector where th file is found
576
;                     EBX = pointer in buffer
577
;                     [buffer .. buffer+511]
578
;                     ECX,EDX,ESI,EDI not changed
579
;          IF CARRY=1 filename not found
580
; Note   : if cluster=0 it's changed to read rootdir
581
;          save 2 previous directory sectors in longname_sec
582
;-----------------------------------------------------------
583
    push  ecx edx esi edi ebx   ; ebx = [esp+0]
584
    mov   [longname_sec1],0
585
    mov   [longname_sec2],0
586
 
587
  adr_new_cluster:
588
    mov   [cluster_tmp],eax
589
    mov   [fat16_root],0
590
    cmp   eax,[LAST_CLUSTER]
591
    ja    adr_not_found         ; too big cluster number, something is wrong
592
    cmp   eax,2
593
    jnb   adr_data_cluster
594
 
595
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
596
    cmp   [fat_type],16
597
    jne   adr_data_cluster
598
    mov   eax,[ROOT_START]
599
    mov   edx,[ROOT_SECTORS]
600
    mov   [fat16_root],1        ; flag for fat16 rootdir
601
    jmp   adr_new_sector
602
 
603
  adr_data_cluster:
604
    sub   eax,2
605
    mov   edx,[SECTORS_PER_CLUSTER]
606
    imul  eax,edx
607
    add   eax,[DATA_START]
608
 
609
  adr_new_sector:
610
    mov   ebx,buffer
611
    call  hd_read
612
    mov   ecx,512/32            ; count of dir entrys per sector = 16
613
 
614
  adr_analyze:
615
    mov   edi,[ebx+11]          ; file attribute
616
    and   edi,0xf
617
    cmp   edi,0xf
618
    je    adr_long_filename
619
    test  edi,0x8               ; skip over volume label
620
    jne   adr_long_filename     ; Note: label can be same name as file/dir
621
 
622
    mov   esi,[esp+0]           ; filename need to be uppercase
623
    mov   edi,ebx
624
    push  ecx
625
    mov   ecx,11
626
    cld
627
    rep   cmpsb                 ; compare 8+3 filename
628
    pop   ecx
629
    je    adr_found
630
 
631
  adr_long_filename:
632
    add   ebx,32                ; position of next dir entry
633
    dec   ecx
634
    jnz   adr_analyze
635
 
636
    mov   ecx,[longname_sec1]   ; save 2 previous directory sectors
637
    mov   [longname_sec1],eax   ; for delete long filename
638
    mov   [longname_sec2],ecx
639
    inc   eax                   ; next sector
640
    dec   edx
641
    jne   adr_new_sector
642
    cmp   [fat16_root],1        ; end of fat16 rootdir
643
    je    adr_not_found
644
 
645
  adr_next_cluster:
646
    mov   eax,[cluster_tmp]
647
    call  get_FAT               ; get next cluster
648
    cmp   eax,2                 ; incorrect fat chain?
649
    jb    adr_not_found         ; yes
650
    cmp   eax,[fatRESERVED]     ; is it end of directory?
651
    jb    adr_new_cluster       ; no. analyse it
652
 
653
  adr_not_found:
654
    pop   edi edi esi edx ecx   ; first edi will remove ebx
655
    stc                         ; file not found
656
    ret
657
 
658
  adr_found:
659
    pop   edi edi esi edx ecx   ; first edi will remove ebx
660
    clc                         ; file found
661
    ret
662
 
663
 
664
analyze_directory_to_write:
665
;-----------------------------------------------------------
666
; input  : EAX = first cluster of the directory
667
; output : IF CARRY=0 EAX = sector where the empty pos is found
668
;                     EBX = pointer in buffer
669
;                     [buffer .. buffer+511]
670
;                     ECX,EDX,ESI,EDI not changed
671
;          IF CARRY=1 disk full or fat corrupted
672
; Note   : if cluster=0 it's changed to read rootdir
673
;-----------------------------------------------------------
674
    push  ecx edx edi
675
 
676
  adw_new_cluster:
677
    mov   [cluster_tmp],eax
678
    mov   [fat16_root],0
679
    cmp   eax,[LAST_CLUSTER]
680
    ja    adw_not_found         ; too big cluster number, something is wrong
681
    cmp   eax,2
682
    jnb   adw_data_cluster
683
 
684
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
685
    cmp   [fat_type],16
686
    jne   adw_data_cluster
687
    mov   eax,[ROOT_START]
688
    mov   edx,[ROOT_SECTORS]
689
    mov   [fat16_root],1        ; flag for fat16 rootdir
690
    jmp   adw_new_sector
691
 
692
  adw_data_cluster:
693
    sub   eax,2
694
    mov   edx,[SECTORS_PER_CLUSTER]
695
    imul  eax,edx
696
    add   eax,[DATA_START]
697
 
698
  adw_new_sector:
699
    mov   ebx,buffer
700
    call  hd_read
701
    mov   ecx,512/32            ; count of dir entrys per sector = 16
702
 
703
  adw_analyze:
704
    cmp   byte [ebx],0x00       ; is free entry?
705
    je    adw_found             ; yes
706
    cmp   byte [ebx],0xe5       ; is deleted entry?
707
    je    adw_found             ; yes
708
    add   ebx,32                ; position of next dir entry
709
    dec   ecx
710
    jnz   adw_analyze
711
 
712
    inc   eax                   ; next sector
713
    dec   edx
714
    jne   adw_new_sector
715
    cmp   [fat16_root],1        ; end of fat16 rootdir
716
    je    adw_not_found
717
 
718
    mov   eax,[cluster_tmp]
719
    call  get_FAT               ; get next cluster
720
    cmp   eax,2                 ; incorrect fat chain?
721
    jb    adw_not_found         ; yes
722
    cmp   eax,[fatRESERVED]     ; is it end of directory?
723
    jb    adw_new_cluster       ; no. analyse it
724
 
725
    mov   eax,2                 ; this block of code add a new cluster
726
    call  get_free_FAT          ; for the directory because the directory
727
    jc    adw_not_found         ; is full
728
 
729
    mov   edx,[fatEND]          ; new end for directory
730
    call  set_FAT
731
 
732
    push  eax                   ; save new cluster
733
    mov   edx,eax
734
    mov   eax,[cluster_tmp]     ; change last cluster to point new cluster
735
    mov   [f_del],1
736
    call  set_FAT
737
    mov   [f_del],0
738
 
739
    mov   ecx,-1                ; remove 1 cluster from free disk space
740
    call  add_disk_free_space
741
 
742
    mov   ecx,512/4
743
    xor   eax,eax
744
    mov   edi,buffer
745
    cld
746
    rep   stosd                 ; clear new directory cluster
747
    pop   eax
748
 
749
    sub   eax,2
750
    mov   ecx,[SECTORS_PER_CLUSTER]
751
    imul  eax,ecx
752
    add   eax,[DATA_START]
753
    mov   ebx,buffer
754
    push  eax                   ; save sector number
755
 
756
  adw_set_empty_directory:
757
    call  hd_write
758
    inc   eax                   ; next sector
759
    dec   ecx
760
    jnz   adw_set_empty_directory
761
 
762
    pop   eax
763
 
764
  adw_found:
765
    pop   edi edx ecx
766
    clc                         ; free space found
767
    ret
768
 
769
  adw_not_found:
770
    pop   edi edx ecx
771
    stc                         ; free space not found
772
    ret
773
 
774
 
775
get_data_cluster:
776
;-----------------------------------------------------------
777
; input  : EAX = cluster
778
;          EBX = pointer to buffer
779
;          EDX = # blocks to read in buffer
780
;          ESI = # blocks to skip over
781
; output : if CARRY=0 ok EBX/EDX/ESI updated
782
;          if CARRY=1 cluster out of range
783
; Note   : if cluster=0 it's changed to read rootdir
784
;-----------------------------------------------------------
785
    push  eax ecx
786
 
787
    mov   [fat16_root],0
788
    cmp   eax,[LAST_CLUSTER]
789
    ja    gdc_error             ; too big cluster number, something is wrong
790
    cmp   eax,2
791
    jnb   gdc_cluster
792
 
793
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
794
    cmp   [fat_type],16
795
    jne   gdc_cluster
796
    mov   eax,[ROOT_START]
797
    mov   ecx,[ROOT_SECTORS]    ; Note: not cluster size
798
    mov   [fat16_root],1        ; flag for fat16 rootdir
799
    jmp   gdc_read
800
 
801
  gdc_cluster:
802
    sub   eax,2
803
    mov   ecx,[SECTORS_PER_CLUSTER]
804
    imul  eax,ecx
805
    add   eax,[DATA_START]
806
 
807
  gdc_read:
808
    test  esi,esi               ; first wanted block
809
    je    gdcl1                 ; yes, skip count is 0
810
    dec   esi
811
    jmp   gdcl2
812
 
813
  gdcl1:
814
    call  hd_read
815
    add   ebx,512               ; update pointer
816
    dec   edx
817
 
818
  gdcl2:
819
    test  edx,edx               ; is all read?
820
    je    out_of_read
821
 
822
    inc   eax                   ; next sector
823
    dec   ecx
824
    jnz   gdc_read
825
 
826
  out_of_read:
827
    pop   ecx eax
828
    clc
829
    ret
830
 
831
  gdc_error:
832
    pop   ecx eax
833
    stc
834
    ret
835
 
836
 
837
set_data_cluster:
838
;-----------------------------------------------------------
839
; input  : EAX = cluster
840
;          EBX = pointer to buffer
841
; output : if CARRY=0 ok
842
;          if CARRY=1 cluster out of range
843
;-----------------------------------------------------------
844
    push  eax ebx edx
845
 
846
    cmp   eax,[LAST_CLUSTER]
847
    ja    sdc_error             ; too big cluster number, something is wrong
848
    sub   eax,2
849
    jb    sdc_error             ; don't allow rootdir write
850
 
851
    mov   edx,[SECTORS_PER_CLUSTER]
852
    imul  eax,edx
853
    add   eax,[DATA_START]
854
 
855
  sdc_write:
856
    call  hd_write
857
    add   ebx,512               ; update pointer
858
    inc   eax
859
    dec   edx
860
    jnz   sdc_write
861
    pop   edx ebx eax
862
    clc
863
    ret
864
 
865
  sdc_error:
866
    pop   edx ebx eax
867
    stc
868
    ret
869
 
870
 
871
get_cluster_of_a_path:
872
;---------------------------------------------------------
873
; input  : EBX = pointer to a path string
874
;          (example: the path "/files/data/document" become
875
;                             "files......data.......document...0"
876
;          '.' = space char
877
;          '0' = char(0) (ASCII=0) !!! )
878
; output : if (CARRY=1) -> ERROR in the PATH
879
;          if (CARRY=0) -> EAX=cluster
880
;---------------------------------------------------------
881
    push  ebx edx
882
 
883
    mov   eax,[ROOT_CLUSTER]
884
    mov   edx,ebx
885
 
886
search_end_of_path:
887
    cmp   byte [edx],0
888
    je    found_end_of_path
889
 
890
    inc   edx ; '/'
891
    mov   ebx,edx
892
    call  analyze_directory
893
    jc    directory_not_found
894
 
895
    mov   eax,[ebx+20-2]        ; read the HIGH 16bit cluster field
896
    mov   ax,[ebx+26]           ; read the LOW 16bit cluster field
897
    and   eax,[fatMASK]
898
    add   edx,11                ; 8+3 (name+extension)
899
    jmp   search_end_of_path
900
 
901
found_end_of_path:
902
    pop   edx ebx
903
    clc                         ; no errors
904
    ret
905
 
906
directory_not_found:
907
    pop   edx ebx
908
    stc                         ; errors occour
909
    ret
910
 
911
 
912
bcd2bin:
913
;----------------------------------
914
; input  : AL=BCD number (eg. 0x11)
915
; output : AH=0
916
;          AL=decimal number (eg. 11)
917
;----------------------------------
918
    xor   ah,ah
919
    shl   ax,4
920
    shr   al,4
921
    aad
922
    ret
923
 
924
 
925
get_date_for_file:
926
;-----------------------------------------------------
927
; Get date from CMOS and pack day,month,year in AX
928
; DATE   bits  0..4   : day of month 0..31
929
;              5..8   : month of year 1..12
930
;              9..15  : count of years from 1980
931
;-----------------------------------------------------
932
    mov   al,0x7        ;day
933
    out   0x70,al
934
    in    al,0x71
935
    call  bcd2bin
936
    ror   eax,5
937
 
938
    mov   al,0x8        ;month
939
    out   0x70,al
940
    in    al,0x71
941
    call  bcd2bin
942
    ror   eax,4
943
 
944
    mov   al,0x9        ;year
945
    out   0x70,al
946
    in    al,0x71
947
    call  bcd2bin
948
    add   ax,20         ;because CMOS return only the two last
949
                        ;digit (eg. 2000 -> 00 , 2001 -> 01) and we
950
    rol   eax,9         ;need the difference with 1980 (eg. 2001-1980)
951
    ret
952
 
953
 
954
get_time_for_file:
955
;-----------------------------------------------------
956
; Get time from CMOS and pack hour,minute,second in AX
957
; TIME   bits  0..4   : second (the low bit is lost)
958
;              5..10  : minute 0..59
959
;              11..15 : hour 0..23
960
;-----------------------------------------------------
961
    mov   al,0x0        ;second
962
    out   0x70,al
963
    in    al,0x71
964
    call  bcd2bin
965
    ror   eax,6
966
 
967
    mov   al,0x2        ;minute
968
    out   0x70,al
969
    in    al,0x71
970
    call  bcd2bin
971
    ror   eax,6
972
 
973
    mov   al,0x4        ;hour
974
    out   0x70,al
975
    in    al,0x71
976
    call  bcd2bin
977
    rol   eax,11
978
    ret
979
 
980
 
981
set_current_time_for_entry:
982
;-----------------------------------------------------
983
; Set current time/date for file entry
984
; input  : ebx = file entry pointer
985
;-----------------------------------------------------
986
    push  eax
987
    call  get_time_for_file     ; update files date/time
988
    mov   [ebx+22],ax
989
    call  get_date_for_file
990
    mov   [ebx+24],ax
991
    pop   eax
992
    ret
993
 
994
 
995
makedir:
996
;-----------------------------------------------------
997
; input  : eax = directory name
998
;          edx = path
999
; output : eax = 0 - ok
1000
;                3 - unknown FS
1001
;                5 - file not found
1002
;                8 - disk full
1003
;               10 - access denied
1004
; Note   : can only make one directory at time
1005
;-----------------------------------------------------
1006
    cmp   [fat_type],0
1007
    jnz   make_dir_fat_ok
1008
    mov   eax,ERROR_UNKNOWN_FS
1009
    ret
1010
 
1011
  make_dir_fat_ok:
1012
;    call  reserve_hd1
1013
 
1014
    pushad
1015
 
1016
    mov   ebx,edx
1017
    call  get_cluster_of_a_path
1018
    jnc   make_dir_found_path
1019
 
1020
  make_dir_path_not_found:
1021
    popad
1022
    call  update_disk           ; write all of cache and fat to hd
1023
    mov   [hd1_status],0
1024
    mov   eax,ERROR_FILE_NOT_FOUND
1025
    ret
1026
 
1027
  make_dir_disk_full:
1028
    popad
1029
    call  update_disk           ; write all of cache and fat to hd
1030
    mov   [hd1_status],0
1031
    mov   eax,ERROR_DISK_FULL
1032
    ret
1033
 
1034
  make_dir_already_exist:
1035
    mov   eax,[cluster]         ; directory cluster
1036
    xor   edx,edx               ; free
1037
    mov   [f_del],1
1038
    call  set_FAT
1039
    mov   [f_del],0
1040
 
1041
    popad
1042
    call  update_disk           ; write all of cache and fat to hd
1043
    mov   [hd1_status],0
1044
    mov   eax,ERROR_ACCESS_DENIED
1045
    ret
1046
 
1047
  make_dir_found_path:
1048
    cmp   eax,[ROOT_CLUSTER]
1049
    jnz   make_dir_not_root
1050
    xor   eax,eax
1051
 
1052
  make_dir_not_root:
1053
    mov   ecx,eax               ; directorys start cluster
1054
    mov   word [NewDirEntry2+26],cx ; 16 bits low of cluster
1055
    shr   ecx,16
1056
    mov   word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16)
1057
 
1058
    push  eax                   ; save parent directory cluster
1059
    mov   eax,2
1060
    call  get_free_FAT
1061
    mov   [cluster],eax         ; first free cluster
1062
    pop   eax
1063
    jc    make_dir_disk_full
1064
 
1065
    push  eax
1066
    mov   eax,[cluster]         ; directory cluster
1067
    mov   edx,[fatEND]          ; end for directory
1068
    call  set_FAT
1069
    pop   eax
1070
 
1071
    mov   ebx,PUSHAD_EAX        ; dir name
1072
    push  eax
1073
    call  analyze_directory     ; check if directory already exist
1074
    pop   eax
1075
    jnc   make_dir_already_exist ; need to free allocated cluster!
1076
 
1077
    call  analyze_directory_to_write
1078
    jc    make_dir_already_exist ; need to free allocated cluster!
1079
 
1080
    mov   esi,PUSHAD_EAX        ; dir name
1081
    mov   edi,ebx               ; pointer in buffer
1082
    mov   ecx,11
1083
    cld
1084
    rep   movsb
1085
 
1086
    mov   dword [ebx+28],0      ; dir size is always 0
1087
    mov   ecx,[cluster]
1088
    mov   [ebx+26],cx           ; 16 bits low of cluster
1089
    mov   word [NewDirEntry1+26],cx
1090
    shr   ecx,16
1091
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
1092
    mov   word [NewDirEntry1+20],cx
1093
    mov   byte [ebx+11],0x10    ; attribute = directory
1094
 
1095
    call  set_current_time_for_entry
1096
    mov   ecx,[ebx+22]
1097
    mov   dword [NewDirEntry1+22],ecx
1098
    mov   dword [NewDirEntry2+22],ecx
1099
 
1100
    mov   ebx,buffer            ; save the directory name,length,cluster
1101
    call  hd_write
1102
 
1103
    mov   ecx,512/4
1104
    xor   eax,eax
1105
    mov   edi,buffer
1106
    cld
1107
    rep   stosd                 ; clear new directory cluster
1108
 
1109
    mov   eax,[cluster]         ; new directory cluster
1110
    sub   eax,2
1111
    mov   edx,[SECTORS_PER_CLUSTER]
1112
    imul  eax,edx
1113
    add   eax,[DATA_START]
1114
    mov   ebx,buffer
1115
    add   eax,edx               ; start from last sector
1116
 
1117
  dir_set_empty_directory:
1118
    dec   eax                   ; next sector
1119
    cmp   edx,1                 ; is first directory sector?
1120
    jnz   not_first_sector      ; no. write empty sector
1121
    mov   esi,NewDirEntry1
1122
    mov   edi,buffer
1123
    mov   ecx,64/4
1124
    cld
1125
    rep   movsd                 ; copy 2 first directory entrys "." and ".."
1126
 
1127
  not_first_sector:
1128
    call  hd_write
1129
    dec   edx
1130
    jnz   dir_set_empty_directory
1131
 
1132
    mov   ecx,-1                ; remove 1 cluster from free disk space
1133
    call  add_disk_free_space
1134
 
1135
    popad
1136
    call  update_disk           ; write all of cache and fat to hd
1137
    mov   [hd1_status],0
1138
    xor   eax,eax
1139
    ret
1140
 
1141
 
1142
removedir:
1143
;-----------------------------------------------------
1144
; input  : eax = file/directory name
1145
;          edx = path
1146
; output : eax = 0 - ok
1147
;                3 - unknown FS
1148
;                5 - file not found
1149
;               10 - access denied
1150
;-----------------------------------------------------
1151
    cmp   [fat_type],0
1152
    jnz   remove_dir_fat_ok
1153
    mov   eax,ERROR_UNKNOWN_FS
1154
    ret
1155
 
1156
  remove_dir_fat_ok:
1157
;    call  reserve_hd1
1158
 
1159
    push  edi
1160
    mov   edi,1                 ; allow directory remove
1161
    call  file_delete
1162
    pop   edi
1163
 
1164
    call  update_disk           ; write all of cache and fat to hd
1165
    mov   [hd1_status],0
1166
    ret
1167
 
1168
 
1169
add_disk_free_space:
1170
;-----------------------------------------------------
1171
; input  : ecx = cluster count
1172
; Note   : negative = remove clusters from free space
1173
;          positive = add clusters to free space
1174
;-----------------------------------------------------
1175
    test  ecx,ecx               ; no change
1176
    je    add_dfs_no
1177
    cmp   [fat_type],32         ; free disk space only used by fat32
1178
    jne   add_dfs_no
1179
 
1180
    push  eax ebx
1181
    mov   eax,[ADR_FSINFO]
1182
    mov   ebx,buffer
1183
    call  hd_read
1184
    cmp   dword [ebx+0x1fc],0xaa550000 ; check sector id
1185
    jne   add_not_fs
1186
 
1187
    add   [ebx+0x1e8],ecx
1188
    call  hd_write
1189
 
1190
  add_not_fs:
1191
    pop   ebx eax
1192
 
1193
  add_dfs_no:
1194
    ret
1195
 
1196
 
1197
file_append:
1198
;-----------------------------------------------------
1199
; input  : eax = file name
1200
;          edx = path
1201
;          ecx = pointer to buffer
1202
;          ebx = bytes to write (0 = truncate file)
1203
;          esi = start position (-1 = end of file)
1204
; output : eax = 0 - ok
1205
;                3 - unknown FS
1206
;                5 - file not found
1207
;                6 - end of file
1208
;                8 - disk full
1209
;                9 - fat table corrupted
1210
;               10 - access denied
1211
;          ebx = bytes written
1212
;-----------------------------------------------------
1213
    cmp   [fat_type],0
1214
    jnz   append_fat_ok
1215
    mov   eax,ERROR_UNKNOWN_FS
1216
    ret
1217
 
1218
  append_fat_ok:
1219
;    call  reserve_hd1
1220
 
1221
    pushad
1222
 
1223
    mov   ebx,edx
1224
    call  get_cluster_of_a_path
1225
    jc    append_not_found
1226
 
1227
    mov   ebx,PUSHAD_EAX        ; file name
1228
    call  analyze_directory
1229
    jc    append_not_found
1230
 
1231
    mov   [sector_tmp],eax
1232
    mov   [entry_pos],ebx
1233
 
1234
    test  byte [ebx+11],0x10    ; is it directory?
1235
    jnz   append_access         ; yes
1236
 
1237
    mov   ecx,[ebx+28]          ; file size
1238
    mov   edi,PUSHAD_ESI        ; write position
1239
    cmp   edi,-1                ; -1 = eof
1240
    jnz   append_inside_file
1241
    mov   edi,ecx               ; file size
1242
 
1243
  append_inside_file:
1244
    cmp   edi,ecx               ; start above old file size?
1245
    ja    append_eof            ; yes
1246
 
1247
    mov   [old_filesize],ecx
1248
    mov   [new_filepos],edi
1249
 
1250
    mov   ecx,PUSHAD_EBX        ; bytes to write
1251
    test  ecx,ecx               ; truncate?
1252
    jz    append_truncate       ; yes
1253
 
1254
    mov   [bytes2write],ecx     ; bytes to write
1255
    mov   esi,PUSHAD_ECX        ; pointer to buffer
1256
    mov   eax,[ebx+20-2]        ; FAT entry
1257
    mov   ax,[ebx+26]
1258
    and   eax,[fatMASK]
1259
    jnz   append_find_pos       ; first cluster <> 0
1260
 
1261
    mov   eax,2
1262
    call  get_free_FAT
1263
    jc    append_disk_full
1264
    mov   ecx,eax               ; set files first cluster
1265
    mov   [ebx+26],cx           ; 16 bits low of cluster
1266
    shr   ecx,16
1267
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
1268
    mov   edx,[fatEND]          ; new end for cluster chain
1269
    call  set_FAT
1270
 
1271
    push  eax                   ; save first cluster
1272
    mov   eax,[sector_tmp]
1273
    mov   ebx,buffer
1274
    call  hd_write              ; write new file entry back to disk
1275
    pop   eax
1276
 
1277
  append_remove_free:
1278
    mov   ecx,-1                ; remove 1 cluster from free disk space
1279
    call  add_disk_free_space   ; Note: uses buffer
1280
 
1281
  append_found_cluster:
1282
    mov   [cluster],eax
1283
    sub   eax,2
1284
    mov   ecx,[SECTORS_PER_CLUSTER]
1285
    imul  eax,ecx
1286
    add   eax,[DATA_START]
1287
    xor   edi,edi
1288
 
1289
  append_new_sector:
1290
    push  ecx
1291
    mov   ecx,[bytes2write]     ; bytes left in buffer
1292
    mov   ebx,512
1293
    sub   ebx,edi               ; bytes left in sector
1294
    cmp   ecx,ebx
1295
    jb    append_bytes_ok
1296
    mov   ecx,ebx
1297
 
1298
  append_bytes_ok:
1299
    cmp   ecx,512               ; overwrite full sector?
1300
    jz    append_full_sector    ; yes
1301
    mov   ebx,buffer            ; overwrite part of sector
1302
    call  hd_read               ; read old sector
1303
 
1304
  append_full_sector:
1305
    sub   [bytes2write],ecx
1306
    add   [new_filepos],ecx
1307
    add   edi,buffer
1308
    cld
1309
    rep   movsb
1310
    pop   ecx
1311
 
1312
    mov   ebx,buffer
1313
    call  hd_write
1314
    cmp   [bytes2write],0       ; is all done?
1315
    jz    append_done
1316
    xor   edi,edi
1317
    inc   eax
1318
    dec   ecx
1319
    jnz   append_new_sector
1320
 
1321
    mov   eax,[cluster]
1322
    call  get_FAT
1323
    cmp   eax,2
1324
    jb    append_fat
1325
    cmp   eax,[LAST_CLUSTER]
1326
    jbe   append_found_cluster
1327
 
1328
  append_alloc_cluster:
1329
    mov   eax,2                 ; ToDo: use temp array to keep track
1330
    call  get_free_FAT          ;       of last free cluster
1331
    jc    append_disk_full
1332
    push  eax                   ; save new cluster
1333
    mov   edx,[fatEND]          ; new end for cluster chain
1334
    call  set_FAT
1335
    mov   edx,eax
1336
    mov   eax,[cluster]
1337
    mov   [f_del],1
1338
    call  set_FAT               ; update previous cluster
1339
    mov   [f_del],0
1340
    pop   eax
1341
    jmp   append_remove_free
1342
 
1343
  append_find_pos:
1344
    call  find_filepos
1345
    mov   [cluster],ebx
1346
    jnc   append_new_sector
1347
    test  edi,edi
1348
    jz    append_alloc_cluster
1349
 
1350
  append_fat:
1351
    mov   eax,ERROR_FAT_TABLE
1352
    jmp   append_ret_code
1353
 
1354
  append_disk_full:
1355
    mov   eax,ERROR_DISK_FULL
1356
    jmp   append_ret_code
1357
 
1358
  append_done:
1359
    xor   eax,eax
1360
 
1361
  append_ret_code:
1362
    mov   PUSHAD_EAX,eax        ; return code
1363
 
1364
    mov   eax,[sector_tmp]      ; update directory entry
1365
    mov   ebx,buffer
1366
    call  hd_read
1367
    mov   ebx,[entry_pos]
1368
    mov   ecx,[new_filepos]
1369
    cmp   ecx,[old_filesize]    ; is file pos above old size?
1370
    jbe   append_size_ok        ; no
1371
    mov   [ebx+28],ecx          ; new file size
1372
 
1373
  append_size_ok:
1374
    call  set_current_time_for_entry
1375
    mov   ebx,buffer
1376
    call  hd_write              ; write new file entry back to disk
1377
 
1378
    sub   ecx,PUSHAD_ESI        ; start position
1379
    mov   PUSHAD_EBX,ecx        ; bytes written
1380
    popad
1381
    call  update_disk           ; write all of cache and fat to hd
1382
    mov   [hd1_status],0
1383
    ret
1384
 
1385
  append_eof:
1386
    popad
1387
    mov   [hd1_status],0
1388
    xor   ebx,ebx
1389
    mov   eax,ERROR_END_OF_FILE
1390
    ret
1391
 
1392
  append_not_found:
1393
    popad
1394
    mov   [hd1_status],0
1395
    xor   ebx,ebx
1396
    mov   eax,ERROR_FILE_NOT_FOUND
1397
    ret
1398
 
1399
  append_access:
1400
    popad
1401
    mov   [hd1_status],0
1402
    xor   ebx,ebx
1403
    mov   eax,ERROR_ACCESS_DENIED
1404
    ret
1405
 
1406
  append_truncate:
1407
    mov   edx,[ebx+20-2]        ; FAT entry
1408
    mov   dx,[ebx+26]
1409
    and   edx,[fatMASK]
1410
    mov   [ebx+28],edi          ; set new file size
1411
    test  edi,edi               ; 0 length file?
1412
    jnz   truncate_save_size    ; no
1413
    mov   [ebx+20],di           ; FAT entry = 0
1414
    mov   [ebx+26],di
1415
 
1416
  truncate_save_size:
1417
    call  set_current_time_for_entry
1418
    mov   ebx,buffer
1419
    call  hd_write
1420
    mov   eax,edx               ; first cluster
1421
    test  edi,edi               ; 0 length file?
1422
    jz    truncate_clear_chain
1423
 
1424
    imul  esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes
1425
 
1426
  truncate_new_cluster:
1427
    cmp   eax,2                 ; incorrect fat chain?
1428
    jb    truncate_eof          ; yes
1429
    cmp   eax,[fatRESERVED]     ; is it end of file?
1430
    jnb   truncate_eof          ; yes
1431
    sub   edi,esi
1432
    jbe   truncate_pos_found
1433
    call  get_FAT               ; get next cluster
1434
    jmp   truncate_new_cluster
1435
 
1436
  truncate_pos_found:
1437
    mov   edx,[fatEND]          ; new end for cluster chain
1438
    mov   [f_del],1
1439
    call  set_FAT
1440
    mov   [f_del],0
1441
    mov   eax,edx               ; clear rest of chain
1442
 
1443
  truncate_clear_chain:
1444
    call  clear_cluster_chain
1445
 
1446
  truncate_eof:
1447
    popad
1448
    call  update_disk           ; write all of cache and fat to hd
1449
    mov   [hd1_status],0
1450
    xor   ebx,ebx
1451
    xor   eax,eax
1452
    ret
1453
 
1454
 
1455
find_filepos:
1456
;-----------------------------------------------------
1457
; input  : eax = first cluster
1458
;          edi = bytes to skip over (start position)
1459
; output : if CARRY=0 file position found
1460
;          if CARRY=1 end of file found
1461
;          eax = current file sector
1462
;          ebx = last cluster
1463
;          ecx = sector count in last cluster
1464
;          edi = bytes to skip over (sector position)
1465
;-----------------------------------------------------
1466
    push  esi
1467
    mov   ecx,[SECTORS_PER_CLUSTER]
1468
    imul  esi,ecx,512           ; esi = cluster size in bytes
1469
    mov   ebx,eax
1470
 
1471
  filepos_new_cluster:
1472
    cmp   eax,2                 ; incorrect fat chain?
1473
    jb    filepos_eof           ; yes
1474
    cmp   eax,[fatRESERVED]     ; is it end of file?
1475
    jnb   filepos_eof           ; yes
1476
 
1477
    mov   ebx,eax
1478
    cmp   edi,esi               ; skip over full cluster?
1479
    jb    filepos_cluster_ok    ; no
1480
 
1481
    sub   edi,esi
1482
    call  get_FAT               ; get next cluster
1483
    jmp   filepos_new_cluster
1484
 
1485
  filepos_cluster_ok:
1486
    sub   eax,2
1487
    imul  eax,ecx
1488
    add   eax,[DATA_START]
1489
 
1490
  filepos_new_sector:
1491
    cmp   edi,512               ; skip over full sector?
1492
    jb    filepos_sector_ok     ; no
1493
    sub   edi,512
1494
    inc   eax
1495
    dec   ecx
1496
    jnz   filepos_new_sector
1497
 
1498
  filepos_eof:
1499
    pop   esi
1500
    stc
1501
    ret
1502
 
1503
  filepos_sector_ok:
1504
    pop   esi
1505
    clc
1506
    ret
1507
 
1508
 
1509
file_write:
1510
;--------------------------------------------------------------------------
1511
;   INPUT : user-reg  register-in-this  meaning      symbol-in-this-routine
1512
;
1513
;            EAX        EDI            system call to write    /
1514
;            EBX        EAX   (PAR0)   pointer to file-name    PAR0
1515
;            EDX        ECX   (PAR1)   pointer to buffer       PAR1
1516
;            ECX        EBX   (PAR2)   file size               PAR2
1517
;            ESI        EDX   (PAR3)   pointer to path         PAR3
1518
;
1519
; output : eax = 0 - ok
1520
;                3 - unknown FS
1521
;                5 - file not found
1522
;                8 - disk full
1523
;               10 - access denied
1524
;--------------------------------------------------------------------------
1525
    cmp   [fat_type],0
1526
    jnz   fat_ok_for_writing
1527
    mov   eax,ERROR_UNKNOWN_FS
1528
    ret
1529
 
1530
  fat_ok_for_writing:
1531
;    call  reserve_hd1
1532
 
1533
    pushad
1534
 
1535
    xor   edi,edi               ; don't allow directory remove
1536
    call  file_delete           ; try to delete the file first
1537
    test  eax,eax
1538
    jz    old_deleted           ; deleted ok
1539
    cmp   eax,ERROR_FILE_NOT_FOUND
1540
    jnz   exit_write_access     ; it exist but can't delete
1541
 
1542
  old_deleted:
1543
    mov   ebx,PUSHAD_EDX
1544
    call  get_cluster_of_a_path
1545
    jnc   found_directory_for_writing
1546
 
1547
  exit_writing_with_error:
1548
    popad
1549
    call  update_disk           ; write all of cache and fat to hd
1550
    mov   [hd1_status],0
1551
    mov   eax,ERROR_FILE_NOT_FOUND
1552
    ret
1553
 
1554
  exit_writing_disk_full_clear:
1555
    mov   eax,[sector_tmp]
1556
    mov   ebx,buffer
1557
    call  hd_read               ; read directory sector
1558
    mov   edx,[entry_pos]
1559
    mov   byte [edx],0xe5       ; mark as deleted
1560
    call  hd_write
1561
    mov   eax,[edx+20-2]        ; FAT entry
1562
    mov   ax,[edx+26]
1563
    and   eax,[fatMASK]
1564
    call  clear_cluster_chain
1565
 
1566
  exit_writing_disk_full:
1567
    popad
1568
    call  update_disk           ; write all of cache and fat to hd
1569
    mov   [hd1_status],0
1570
    mov   eax,ERROR_DISK_FULL
1571
    ret
1572
 
1573
  exit_write_access:
1574
    popad
1575
    call  update_disk           ; write all of cache and fat to hd
1576
    mov   [hd1_status],0
1577
    mov   eax,ERROR_ACCESS_DENIED
1578
    ret
1579
 
1580
found_directory_for_writing:
1581
    call  analyze_directory_to_write
1582
    jc    exit_writing_disk_full
1583
 
1584
    mov   [sector_tmp],eax
1585
    mov   [entry_pos],ebx
1586
    push  eax                   ; save directory sector
1587
    mov   eax,2
1588
    call  get_free_FAT
1589
    mov   [cluster],eax         ; first free cluster
1590
    pop   eax
1591
    jc    exit_writing_disk_full
1592
 
1593
    mov   esi,PUSHAD_EAX        ; file name
1594
    mov   edi,ebx               ; pointer in buffer
1595
    mov   ecx,11
1596
    cld
1597
    rep   movsb
1598
 
1599
    mov   esi,PUSHAD_EBX        ; file size (bytes left)
1600
    mov   [ebx+28],esi          ; file size
1601
    mov   ecx,[cluster]
1602
    mov   [ebx+26],cx           ; 16 bits low of cluster
1603
    shr   ecx,16
1604
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
1605
    mov   byte [ebx+11],0x20    ; attribute = archive
1606
 
1607
    call  set_current_time_for_entry
1608
 
1609
    mov   ebx,buffer            ; save the directory name,length,cluster
1610
    call  hd_write
1611
 
1612
    imul  edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes
1613
    xor   ecx,ecx               ; cluster count
1614
    mov   ebx,PUSHAD_ECX        ; ebx = buffer
1615
 
1616
hd_new_block_write:
1617
 
1618
    mov   eax,[cluster]         ; eax = block
1619
    call  set_data_cluster
1620
 
1621
    sub   esi,edi               ; sub wrote bytes
1622
    jbe   file_saved_OK         ; end if all done
1623
    add   ebx,edi               ; update buffer position
1624
 
1625
    inc   eax
1626
    call  get_free_FAT          ; next free in FAT
1627
    jc    exit_writing_disk_full_clear
1628
 
1629
    mov   edx,eax
1630
    xchg  eax,[cluster]         ; get old cluster and save new cluster
1631
    call  set_FAT               ; add it in cluster chain
1632
    dec   ecx                   ; update cluster count
1633
    jmp   hd_new_block_write
1634
 
1635
file_saved_OK:
1636
 
1637
    mov   edx,[fatEND]          ; new end for cluster chain
1638
    call  set_FAT
1639
    dec   ecx                   ; update cluster count
1640
 
1641
    call  add_disk_free_space   ; remove clusters from free disk space
1642
 
1643
    popad
1644
    call  update_disk           ; write all of cache and fat to hd
1645
    mov   [hd1_status],0
1646
    xor   eax,eax
1647
    ret
1648
 
1649
 
1650
file_read:
1651
;--------------------------------------------------------------------------
1652
;   INPUT :  user-register register-in-this  meaning         symbol-in-this
1653
;
1654
;            EAX           EDI               system call to write   /
1655
;            EBX           EAX   (PAR0)      pointer to file-name   PAR0
1656
;            EDX           ECX   (PAR1)      pointer to buffer      PAR1
1657
;            ECX           EBX   (PAR2)   vt file blocks to read    PAR2
1658
;            ESI           EDX   (PAR3)      pointer to path        PAR3
1659
;            EDI           ESI            vt first 512 block to read
1660
;                          EDI               if 0 - read root
1661
;
1662
; output : eax = 0 - ok
1663
;                3 - unknown FS
1664
;                5 - file not found
1665
;                6 - end of file
1666
;                9 - fat table corrupted
1667
;          ebx = size of file/directory
1668
;--------------------------------------------------------------------------
1669
    cmp   [fat_type],0
1670
    jnz   fat_ok_for_reading
1671
    xor   ebx,ebx
1672
    mov   eax,ERROR_UNKNOWN_FS
1673
    ret
1674
 
1675
  fat_ok_for_reading:
1676
;    call  reserve_hd1
1677
 
1678
    pushad
1679
 
1680
    mov   ebx,edx
1681
    call  get_cluster_of_a_path
1682
    jc    file_to_read_not_found
1683
 
1684
    test  edi,edi               ; read rootdir
1685
    jne   no_read_root
1686
 
1687
    xor   eax,eax
1688
    call  get_dir_size          ; return rootdir size
1689
    mov   [file_size],eax
1690
    mov   eax,[ROOT_CLUSTER]
1691
    jmp   file_read_start
1692
 
1693
  no_read_root:
1694
    mov   ebx,PUSHAD_EAX        ; file name
1695
    call  analyze_directory
1696
    jc    file_to_read_not_found
1697
 
1698
    mov   eax,[ebx+28]          ; file size
1699
    test  byte [ebx+11],0x10    ; is it directory?
1700
    jz    read_set_size         ; no
1701
 
1702
    mov   eax,[ebx+20-2]        ; FAT entry
1703
    mov   ax,[ebx+26]
1704
    and   eax,[fatMASK]
1705
    call  get_dir_size
1706
 
1707
  read_set_size:
1708
    mov   [file_size],eax
1709
 
1710
    mov   eax,[ebx+20-2]        ; FAT entry
1711
    mov   ax,[ebx+26]
1712
    and   eax,[fatMASK]
1713
 
1714
  file_read_start:
1715
    mov   ebx,PUSHAD_ECX        ; pointer to buffer
1716
    mov   edx,PUSHAD_EBX        ; file blocks to read
1717
    mov   esi,PUSHAD_ESI        ; first 512 block to read
1718
 
1719
  file_read_new_cluster:
1720
    call  get_data_cluster
1721
    jc    file_read_eof         ; end of file or cluster out of range
1722
 
1723
    test  edx,edx               ; is all read?
1724
    je    file_read_OK          ; yes
1725
 
1726
    call  get_FAT               ; get next cluster
1727
    cmp   eax,[fatRESERVED]     ; end of file
1728
    jnb   file_read_eof
1729
    cmp   eax,2                 ; incorrect fat chain
1730
    jnb   file_read_new_cluster
1731
 
1732
    popad
1733
    mov   [hd1_status],0
1734
    mov   ebx,[file_size]
1735
    mov   eax,ERROR_FAT_TABLE
1736
    ret
1737
 
1738
  file_read_eof:
1739
    popad
1740
    mov   [hd1_status],0
1741
    mov   ebx,[file_size]
1742
    mov   eax,ERROR_END_OF_FILE
1743
    ret
1744
 
1745
  file_read_OK:
1746
    popad
1747
    mov   [hd1_status],0
1748
    mov   ebx,[file_size]
1749
    xor   eax,eax
1750
    ret
1751
 
1752
  file_to_read_not_found:
1753
    popad
1754
    mov   [hd1_status],0
1755
    xor   ebx,ebx
1756
    mov   eax,ERROR_FILE_NOT_FOUND
1757
    ret
1758
 
1759
 
1760
get_dir_size:
1761
;-----------------------------------------------------
1762
; input  : eax = first cluster (0=rootdir)
1763
; output : eax = directory size in bytes
1764
;-----------------------------------------------------
1765
    push  edx
1766
    xor   edx,edx               ; count of directory clusters
1767
    test  eax,eax
1768
    jnz   dir_size_next
1769
 
1770
    mov   eax,[ROOT_SECTORS]
1771
    shl   eax,9                 ; fat16 rootdir size in bytes
1772
    cmp   [fat_type],16
1773
    je    dir_size_ret
1774
    mov   eax,[ROOT_CLUSTER]
1775
 
1776
  dir_size_next:
1777
    cmp   eax,2                 ; incorrect fat chain
1778
    jb    dir_size_end
1779
    cmp   eax,[fatRESERVED]     ; end of directory
1780
    ja    dir_size_end
1781
    call  get_FAT               ; get next cluster
1782
    inc   edx
1783
    jmp   dir_size_next
1784
 
1785
  dir_size_end:
1786
    imul  eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
1787
    imul  eax,edx
1788
 
1789
  dir_size_ret:
1790
    pop   edx
1791
    ret
1792
 
1793
 
1794
file_delete:
1795
;-----------------------------------------------------
1796
; input  : eax = file/directory name
1797
;          edx = path
1798
;          edi = 1 - allow directory remove else don't remove directory
1799
; output : eax = 0 - ok
1800
;                3 - unknown FS
1801
;                5 - file not found
1802
;               10 - access denied
1803
;-----------------------------------------------------
1804
    cmp   [fat_type],0
1805
    jnz   file_del_fat_ok
1806
    mov   eax,ERROR_UNKNOWN_FS
1807
    ret
1808
 
1809
  file_del_fat_ok:
1810
    pushad
1811
 
1812
    mov   ebx,edx
1813
    call  get_cluster_of_a_path
1814
    jc    file_to_delete_not_found
1815
 
1816
    mov   ebx,PUSHAD_EAX        ; file/directory name
1817
    call  analyze_directory
1818
    jc    file_to_delete_not_found
1819
 
1820
    test  byte [ebx+11],0x10    ; is it directory?
1821
    jz    delete_notdir         ; no. it's file
1822
    cmp   edi,1                 ; allow directory remove
1823
    jnz   delete_no_access      ; no
1824
 
1825
    push  eax                   ; save directory sector
1826
    mov   eax,[ebx+20-2]        ; first cluster of file
1827
    mov   ax,[ebx+26]           ; 0 length files start cluster = 0
1828
    and   eax,[fatMASK]
1829
    xor   ebp,ebp               ; counter for directory deepnes
1830
    call  clear_directory
1831
    pop   eax
1832
    jc    delete_no_access
1833
 
1834
    push  ebx                   ; save directory pointer in buffer
1835
    mov   ebx,buffer
1836
    call  hd_read               ; read directory sector
1837
    pop   ebx
1838
 
1839
  delete_notdir:
1840
    call  delete_entry_name
1841
    mov   eax,ecx               ; first cluster of file
1842
    call  clear_cluster_chain
1843
    popad
1844
    xor   eax,eax
1845
    ret
1846
 
1847
  delete_no_access:
1848
    popad
1849
    mov   eax,ERROR_ACCESS_DENIED
1850
    ret
1851
 
1852
  file_to_delete_not_found:
1853
    popad
1854
    mov   eax,ERROR_FILE_NOT_FOUND
1855
    ret
1856
 
1857
 
1858
clear_cluster_chain:
1859
;-----------------------------------------------------
1860
; input  : eax = first cluster
1861
;-----------------------------------------------------
1862
    push  eax ecx edx
1863
    xor   ecx,ecx               ; cluster count
1864
    mov   [f_del],1             ; delete on
1865
 
1866
  clean_new_chain:
1867
    cmp   eax,[LAST_CLUSTER]    ; end of file
1868
    ja    delete_OK
1869
    cmp   eax,2                 ; unfinished fat chain or zero length file
1870
    jb    delete_OK
1871
    cmp   eax,[ROOT_CLUSTER]    ; don't remove root cluster
1872
    jz    delete_OK
1873
 
1874
    xor   edx,edx
1875
    call  set_FAT               ; clear fat entry
1876
    inc   ecx                   ; update cluster count
1877
    mov   eax,edx               ; old cluster
1878
    jmp   clean_new_chain
1879
 
1880
  delete_OK:
1881
    call  add_disk_free_space   ; add clusters to free disk space
1882
    mov   [f_del],0
1883
    pop   edx ecx eax
1884
    ret
1885
 
1886
 
1887
clear_directory:
1888
;-----------------------------------------------------
1889
; input  : eax = directory cluster
1890
;          ebp = directory deepnes
1891
; Note   : use recursive call
1892
;-----------------------------------------------------
1893
    pushad
1894
    inc   ebp
1895
    cmp   ebp,64                ; if over 63 directory deep
1896
    jnb   clear_error           ; something must be wrong
1897
 
1898
  clear_new_cluster:
1899
    cmp   eax,[LAST_CLUSTER]
1900
    ja    clear_end
1901
    cmp   eax,[ROOT_CLUSTER]    ; don't remove root cluster
1902
    jz    clear_end
1903
    mov   esi,eax               ; esi = current directory cluster
1904
    sub   eax,2
1905
    jb    clear_end
1906
    mov   ecx,[SECTORS_PER_CLUSTER]
1907
    imul  eax,ecx
1908
    add   eax,[DATA_START]
1909
 
1910
  clear_new_sector:
1911
    mov   edi,eax               ; edi = current directory sector
1912
    mov   ebx,deltree_buffer
1913
    call  hd_read
1914
    mov   edx,512/32            ; count of dir entrys per sector = 16
1915
 
1916
  clear_analyze:
1917
    mov   al,[ebx+11]           ; file attribute
1918
    and   al,0xf
1919
    cmp   al,0xf
1920
    je    clear_long_filename
1921
 
1922
    cmp   byte [ebx],'.'        ; parent or current directory
1923
    je    clear_next_entry
1924
    cmp   byte [ebx],0xe5       ; deleted
1925
    je    clear_next_entry
1926
    cmp   byte [ebx],0          ; empty
1927
    je    clear_write_last
1928
    ;je    clear_next_entry
1929
 
1930
    mov   eax,[ebx+20-2]        ; first cluster of entry
1931
    mov   ax,[ebx+26]
1932
    and   eax,[fatMASK]
1933
 
1934
    test  byte [ebx+11],0x10    ; is it directory?
1935
    jz    clear_file            ; no
1936
 
1937
    push  eax ebx
1938
    mov   eax,edi
1939
    mov   ebx,deltree_buffer    ; save buffer over recursive call
1940
    call  hd_write              ; write directory sector to disk
1941
    pop   ebx eax
1942
 
1943
    call  clear_directory       ; recursive call !!!
1944
    jc    clear_error           ; exit if error found
1945
 
1946
    push  eax ebx
1947
    mov   eax,edi
1948
    mov   ebx,deltree_buffer
1949
    call  hd_read               ; read directory sector again
1950
    pop   ebx eax
1951
 
1952
  clear_file:
1953
    call  clear_cluster_chain
1954
 
1955
  clear_long_filename:
1956
    mov   byte [ebx],0xe5
1957
 
1958
  clear_next_entry:
1959
    add   ebx,32                ; position of next dir entry
1960
    dec   edx
1961
    jnz   clear_analyze
1962
 
1963
    mov   eax,edi
1964
    mov   ebx,deltree_buffer
1965
    call  hd_write              ; write directory sector to disk
1966
 
1967
    inc   eax                   ; next sector
1968
    dec   ecx
1969
    jnz   clear_new_sector
1970
 
1971
    mov   eax,esi
1972
    call  get_FAT               ; get next cluster
1973
    jmp   clear_new_cluster     ; clear it
1974
 
1975
  clear_write_last:
1976
    mov   eax,edi
1977
    mov   ebx,deltree_buffer
1978
    call  hd_write              ; write directory sector to disk
1979
 
1980
  clear_end:
1981
    popad
1982
    clc
1983
    ret
1984
 
1985
  clear_error:
1986
    popad
1987
    stc
1988
    ret
1989
 
1990
 
1991
delete_entry_name:
1992
;-----------------------------------------------------
1993
; input  : eax = directory sector
1994
;          ebx = directory pointer in buffer
1995
;          longname_sec = 2 previous directory sectors
1996
; output : ecx = first cluster
1997
; change : eax,ebx,edx
1998
;-----------------------------------------------------
1999
    mov   byte [ebx],0xe5
2000
    mov   ecx,[ebx+20-2]        ; first cluster of file
2001
    mov   cx,[ebx+26]           ; 0 length files start cluster = 0
2002
    and   ecx,[fatMASK]
2003
 
2004
  delete_empty:
2005
    sub   ebx,32
2006
    cmp   ebx,buffer
2007
    jnb   delete_test_long
2008
 
2009
    mov   ebx,buffer
2010
    call  hd_write              ; write directory sector back
2011
    xor   eax,eax
2012
    xchg  eax,[longname_sec2]
2013
    xchg  eax,[longname_sec1]
2014
    test  eax,eax               ; is there previous directory sector?
2015
    jz    delete_name_end       ; no
2016
 
2017
    mov   ebx,buffer
2018
    call  hd_read               ; read previous sector
2019
    mov   ebx,buffer+0x1e0      ; start from last entry
2020
 
2021
  delete_test_long:
2022
    mov   dh,[ebx+11]           ; file attribute
2023
    and   dh,0xf
2024
    cmp   dh,0xf
2025
    jne   delete_write_buffer
2026
 
2027
    cmp   byte [ebx],0x40       ; end of long dir entry?
2028
    mov   byte [ebx],0xe5
2029
    jb    delete_empty
2030
 
2031
  delete_write_buffer:
2032
    mov   ebx,buffer
2033
    call  hd_write              ; write directory sector back
2034
 
2035
  delete_name_end:
2036
    ret
2037
 
2038
 
2039
rename:
2040
;-----------------------------------------------------------
2041
; input  : eax = source directory name
2042
;          edx = source path
2043
;          ebx = dest directory name
2044
;          edi = dest path
2045
; output : eax = 0 - ok
2046
;                3 - unknown FS
2047
;                5 - file not found
2048
;                8 - disk full
2049
;               10 - access denied
2050
;-----------------------------------------------------------
2051
    cmp   [fat_type],0
2052
    jnz   fat_ok_for_rename
2053
    mov   eax,ERROR_UNKNOWN_FS
2054
    ret
2055
 
2056
  fat_ok_for_rename:
2057
;    call  reserve_hd1
2058
 
2059
    pushad
2060
 
2061
    mov   ebx,edx               ; source path
2062
    call  get_cluster_of_a_path
2063
    jc    rename_entry_not_found
2064
 
2065
    mov   ebx,PUSHAD_EAX        ; source directory name
2066
    call  analyze_directory
2067
    jc    rename_entry_not_found
2068
 
2069
    mov   [sector_tmp],eax      ; save source sector
2070
    mov   [entry_pos],ebx
2071
    mov   esi,ebx
2072
    mov   edi,dir_entry
2073
    mov   ecx,32/4
2074
    cld
2075
    rep   movsd                 ; save entry
2076
 
2077
    mov   ebx,PUSHAD_EDI        ; dest path
2078
    call  get_cluster_of_a_path
2079
    jc    rename_entry_not_found
2080
 
2081
    mov   edx,eax               ; save dest directory cluster
2082
    mov   ebx,PUSHAD_EBX        ; dest directory name
2083
    push  [longname_sec1]
2084
    push  [longname_sec2]
2085
    call  analyze_directory     ; check if entry already exist
2086
    pop   [longname_sec2]
2087
    pop   [longname_sec1]
2088
    jnc   rename_entry_already_exist
2089
 
2090
    mov   eax,edx
2091
    call  analyze_directory_to_write
2092
    jc    rename_disk_full
2093
 
2094
    mov   esi,dir_entry
2095
    mov   edi,ebx
2096
    mov   ecx,32/4
2097
    cld
2098
    rep   movsd                 ; copy entry
2099
    mov   esi,PUSHAD_EBX        ; dest directory name
2100
    mov   edi,ebx
2101
    mov   ecx,11
2102
    rep   movsb                 ; copy name
2103
 
2104
    mov   ebx,buffer            ; save the directory name,length,cluster
2105
    call  hd_write
2106
 
2107
    test  byte [dir_entry+11],0x10 ; is it directory?
2108
    jz    rename_not_dir           ; no
2109
    mov   eax,[dir_entry+20-2]     ; FAT entry
2110
    mov   ax,[dir_entry+26]
2111
    and   eax,[fatMASK]
2112
    call  change_2dot_cluster
2113
 
2114
  rename_not_dir:
2115
    mov   eax,[sector_tmp]
2116
    mov   ebx,buffer
2117
    call  hd_read               ; read source directory sector
2118
 
2119
    mov   ebx,[entry_pos]
2120
    call  delete_entry_name
2121
 
2122
    popad
2123
    call  update_disk           ; write all of cache and fat to hd
2124
    mov   [hd1_status],0
2125
    xor   eax,eax
2126
    ret
2127
 
2128
  rename_entry_not_found:
2129
    popad
2130
    mov   [hd1_status],0
2131
    mov   eax,ERROR_FILE_NOT_FOUND
2132
    ret
2133
 
2134
  rename_entry_already_exist:
2135
    popad
2136
    mov   [hd1_status],0
2137
    mov   eax,ERROR_ACCESS_DENIED
2138
    ret
2139
 
2140
  rename_disk_full:
2141
    popad
2142
    mov   [hd1_status],0
2143
    mov   eax,ERROR_DISK_FULL
2144
    ret
2145
 
2146
 
2147
change_2dot_cluster:
2148
;-----------------------------------------------------------
2149
; input  : eax = directory cluster
2150
;          edx = value to save
2151
; change : eax,ebx,edx
2152
;-----------------------------------------------------------
2153
    cmp   eax,[LAST_CLUSTER]
2154
    ja    not_2dot              ; too big cluster number, something is wrong
2155
    sub   eax,2
2156
    jb    not_2dot
2157
 
2158
    imul  eax,[SECTORS_PER_CLUSTER]
2159
    add   eax,[DATA_START]
2160
    mov   ebx,buffer
2161
    call  hd_read
2162
 
2163
    cmp   dword [ebx+32],'..  '
2164
    jnz   not_2dot
2165
 
2166
    cmp   edx,[ROOT_CLUSTER]    ; is rootdir cluster?
2167
    jne   not_2dot_root
2168
    xor   edx,edx               ; yes. set it zero
2169
 
2170
  not_2dot_root:
2171
    mov   [ebx+32+26],dx        ; 16 bits low of cluster
2172
    shr   edx,16
2173
    mov   [ebx+32+20],dx        ; 16 bits high of cluster (=0 fat16)
2174
    call  hd_write
2175
 
2176
  not_2dot:
2177
    ret
2178
 
2179
 
2180
get_filesize:
2181
;-----------------------------------------------------------
2182
; input  : eax = file name
2183
;          edx = path
2184
;          edi = if 0 - read rootdir else normal dir/file size
2185
; output : eax = 0 - ok
2186
;                3 - unknown FS
2187
;                5 - file not found
2188
;          ebx = file size
2189
;-----------------------------------------------------------
2190
    cmp   [fat_type],0
2191
    jnz   get_filesize_fat_ok
2192
    xor   ebx,ebx
2193
    mov   eax,ERROR_UNKNOWN_FS
2194
    ret
2195
 
2196
  get_filesize_fat_ok:
2197
;    call  reserve_hd1
2198
 
2199
    pushad
2200
    xor   eax,eax
2201
    test  edi,edi               ; is read rootdir?
2202
    je    get_filesize_dirsize  ; yes
2203
 
2204
  get_filesize_no_root:
2205
    mov   ebx,edx
2206
    call  get_cluster_of_a_path
2207
    jc    get_filesize_not_found
2208
 
2209
    mov   ebx,PUSHAD_EAX        ; file name
2210
    call  analyze_directory
2211
    jc    get_filesize_not_found
2212
 
2213
    mov   eax,[ebx+28]          ; file size
2214
    test  byte [ebx+11],0x10    ; is it directory?
2215
    jz    get_filesize_set_size ; no
2216
 
2217
    mov   eax,[ebx+20-2]        ; FAT entry
2218
    mov   ax,[ebx+26]
2219
    and   eax,[fatMASK]
2220
 
2221
  get_filesize_dirsize:
2222
    call  get_dir_size
2223
 
2224
  get_filesize_set_size:
2225
    mov   PUSHAD_EBX,eax
2226
    popad
2227
    mov   [hd1_status],0
2228
    xor   eax,eax
2229
    ret
2230
 
2231
  get_filesize_not_found:
2232
    popad
2233
    mov   [hd1_status],0
2234
    xor   ebx,ebx
2235
    mov   eax,ERROR_FILE_NOT_FOUND
2236
    ret
2237
 
2238
 
2239
get_fileattr:
2240
;-----------------------------------------------------------
2241
; input  : eax = file name
2242
;          edx = path
2243
; output : eax = 0 - ok
2244
;                3 - unknown FS
2245
;                5 - file not found
2246
;          ebx = file attribute
2247
;-----------------------------------------------------------
2248
    cmp   [fat_type],0
2249
    jnz   get_fileattr_fat_ok
2250
    xor   ebx,ebx
2251
    mov   eax,ERROR_UNKNOWN_FS
2252
    ret
2253
 
2254
  get_fileattr_fat_ok:
2255
;    call  reserve_hd1
2256
 
2257
    pushad
2258
    mov   ebx,edx
2259
    call  get_cluster_of_a_path
2260
    jc    get_fileattr_not_found
2261
 
2262
    mov   ebx,PUSHAD_EAX        ; file name
2263
    call  analyze_directory
2264
    jc    get_fileattr_not_found
2265
 
2266
    movzx eax,byte [ebx+11]     ; file attribute
2267
    mov   PUSHAD_EBX,eax
2268
    popad
2269
    mov   [hd1_status],0
2270
    xor   eax,eax
2271
    ret
2272
 
2273
  get_fileattr_not_found:
2274
    popad
2275
    mov   [hd1_status],0
2276
    xor   ebx,ebx
2277
    mov   eax,ERROR_FILE_NOT_FOUND
2278
    ret
2279
 
2280
 
2281
get_filedate:
2282
;-----------------------------------------------------------
2283
; input  : eax = file name
2284
;          edx = path
2285
; output : eax = 0 - ok
2286
;                3 - unknown FS
2287
;                5 - file not found
2288
;          ebx = file date/time
2289
;                bits 31..25 = year-1980
2290
;                bits 24..21 = month
2291
;                bits 20..16 = day
2292
;                bits 15..11 = hour
2293
;                bits 10..5  = minute
2294
;                bits 4..0   = second/2
2295
;-----------------------------------------------------------
2296
    cmp   [fat_type],0
2297
    jnz   get_filedate_fat_ok
2298
    xor   ebx,ebx
2299
    mov   eax,ERROR_UNKNOWN_FS
2300
    ret
2301
 
2302
  get_filedate_fat_ok:
2303
;    call  reserve_hd1
2304
 
2305
    pushad
2306
    mov   ebx,edx
2307
    call  get_cluster_of_a_path
2308
    jc    get_filedate_not_found
2309
 
2310
    mov   ebx,PUSHAD_EAX        ; file name
2311
    call  analyze_directory
2312
    jc    get_filedate_not_found
2313
 
2314
    mov   eax,[ebx+22]          ; file date/time
2315
    mov   PUSHAD_EBX,eax
2316
    popad
2317
    mov   [hd1_status],0
2318
    xor   eax,eax
2319
    ret
2320
 
2321
  get_filedate_not_found:
2322
    popad
2323
    mov   [hd1_status],0
2324
    xor   ebx,ebx
2325
    mov   eax,ERROR_FILE_NOT_FOUND
2326
    ret
2327
 
2328
 
2329
get_hd_info:
2330
;-----------------------------------------------------------
2331
; output : eax = 0 - ok
2332
;                3 - unknown FS
2333
;          edx = cluster size in bytes
2334
;          ebx = total clusters on disk
2335
;          ecx = free clusters on disk
2336
;-----------------------------------------------------------
2337
    cmp   [fat_type],0
2338
    jnz   info_fat_ok
2339
    xor   edx,edx
2340
    xor   ebx,ebx
2341
    xor   ecx,ecx
2342
    mov   eax,ERROR_UNKNOWN_FS
2343
    ret
2344
 
2345
  info_fat_ok:
2346
;    call  reserve_hd1
2347
 
2348
    xor   ecx,ecx               ; count of free clusters
2349
    mov   eax,2
2350
    mov   ebx,[LAST_CLUSTER]
2351
 
2352
  info_cluster:
2353
    push  eax
2354
    call  get_FAT               ; get cluster info
2355
    test  eax,eax               ; is it free?
2356
    jnz   info_used             ; no
2357
    inc   ecx
2358
 
2359
  info_used:
2360
    pop   eax
2361
    inc   eax
2362
    cmp   eax,ebx               ; is above last cluster?
2363
    jbe   info_cluster          ; no. test next cluster
2364
 
2365
    dec   ebx                   ; cluster count
2366
    imul  edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
2367
    mov   [hd1_status],0
2368
    xor   eax,eax
2369
    ret
2370
 
2371
 
2372
update_disk:
2373
;-----------------------------------------------------------
2374
; write changed fat and cache to disk
2375
;-----------------------------------------------------------
2376
    cmp   [fat_change],0        ; is fat changed?
2377
    je    upd_no_change
2378
 
2379
    call  write_fat_sector
2380
 
2381
  upd_no_change:
2382
 
2383
    call  write_cache
2384
    ret
2385
 
2386
 
2387
;**************************************************************************
2388
;
2389
;   0x600008  - first entry in cache list
2390
;
2391
;            +0   - lba sector
2392
;            +4   - state of cache sector
2393
;                   0 = empty
2394
;                   1 = used for read  ( same as in hd )
2395
;                   2 = used for write ( differs from hd )
2396
;
2397
;      +65536 - cache entries
2398
;
2399
;**************************************************************************
2400
 
2401
 
2402
hd_read:
2403
;-----------------------------------------------------------
2404
; input  : eax = block to read
2405
;          ebx = destination
2406
;-----------------------------------------------------------
2407
    push  ecx esi edi           ; scan cache
2408
 
2409
    mov   ecx,cache_max         ; entries in cache
2410
    mov   esi,0x600000+8
2411
    mov   edi,1
2412
 
2413
  hdreadcache:
2414
 
2415
    cmp   dword [esi+4],0       ; empty
2416
    je    nohdcache
2417
 
2418
    cmp   [esi],eax             ; correct sector
2419
    je    yeshdcache
2420
 
2421
  nohdcache:
2422
 
2423
    add   esi,8
2424
    inc   edi
2425
    dec   ecx
2426
    jnz   hdreadcache
2427
 
2428
    call  find_empty_slot       ; ret in edi
2429
 
2430
    call  wait_for_hd_idle
2431
    push  eax edx
2432
 
2433
    cli
2434
    xor   eax,eax
2435
    mov   edx,[hdbase]
2436
    inc   edx
2437
    out   dx,al   ; ATAFeatures ðåãèñòð "îñîáåííîñòåé"
2438
    inc   edx
2439
    inc   eax
2440
    out   dx,al   ; ATASectorCount ñ÷åò÷èê ñåêòîðîâ
2441
    inc   edx
2442
    mov   eax,[esp+4]
2443
    out   dx,al   ; ATASectorNumber ðåãèñòð íîìåðà ñåêòîðà
2444
    shr   eax,8
2445
    inc   edx
2446
    out   dx,al   ; ATACylinder íîìåð öèëèíäðà (ìëàäøèé áàéò)
2447
    shr   eax,8
2448
    inc   edx
2449
    out   dx,al   ; íîìåð öèëèíäðà (ñòàðøèé áàéò)
2450
    shr   eax,8
2451
    inc   edx
2452
    and   al,1+2+4+8
2453
    add   al,byte [hdid]
2454
    add   al,128+64+32
2455
    out   dx,al   ; íîìåð ãîëîâêè/íîìåð äèñêà
2456
    inc   edx
2457
    mov   al,20h
2458
    out   dx,al   ; ATACommand ðåãèñòð êîìàíä
2459
    sti
2460
 
2461
    call  wait_for_sector_buffer
2462
 
2463
    cmp   [hd_error],0
2464
    jne   hd_read_error
2465
 
2466
    cli
2467
    push  edi
2468
    shl   edi,9
2469
    add   edi,0x600000+65536
2470
    mov   ecx,256
2471
    mov   edx,[hdbase]
2472
    cld
2473
    rep   insw
2474
    pop   edi
2475
    sti
2476
 
2477
    pop   edx eax
2478
 blok_read_2:
2479
    lea   esi,[edi*8+0x600000]
2480
    mov   [esi],eax             ; sector number
2481
    mov   dword [esi+4],1       ; hd read - mark as same as in hd
2482
 
2483
  yeshdcache:
2484
 
2485
    mov   esi,edi
2486
    shl   esi,9
2487
    add   esi,0x600000+65536
2488
    mov   edi,ebx
2489
    mov   ecx,512/4
2490
    cld
2491
    rep   movsd                 ; move data
2492
; blok_read_2:
2493
    pop   edi esi ecx
2494
    ret
2495
 
2496
 
2497
hd_write:
2498
;-----------------------------------------------------------
2499
; input  : eax = block
2500
;          ebx = pointer to memory
2501
;-----------------------------------------------------------
2502
    push  ecx esi edi
2503
 
2504
    ; check if the cache already has the sector and overwrite it
2505
 
2506
    mov   ecx,cache_max
2507
    mov   esi,0x600000+8
2508
    mov   edi,1
2509
 
2510
  hdwritecache:
2511
 
2512
    cmp   dword [esi+4],0       ; if cache slot is empty
2513
    je    not_in_cache_write
2514
 
2515
    cmp   [esi],eax             ; if the slot has the sector
2516
    je    yes_in_cache_write
2517
 
2518
  not_in_cache_write:
2519
 
2520
    add   esi,8
2521
    inc   edi
2522
    dec   ecx
2523
    jnz   hdwritecache
2524
 
2525
    ; sector not found in cache
2526
    ; write the block to a new location
2527
 
2528
    call  find_empty_slot       ; ret in edi
2529
 
2530
    lea   esi,[edi*8+0x600000]
2531
    mov   [esi],eax             ; sector number
2532
 
2533
  yes_in_cache_write:
2534
 
2535
    mov   dword [esi+4],2       ; write - differs from hd
2536
 
2537
    shl   edi,9
2538
    add   edi,0x600000+65536
2539
    mov   esi,ebx
2540
    mov   ecx,512/4
2541
    cld
2542
    rep   movsd                 ; move data
2543
 
2544
    pop   edi esi ecx
2545
    ret
2546
 
2547
 
2548
write_cache:
2549
;-----------------------------------------------------------
2550
; write all changed sectors to disk
2551
;-----------------------------------------------------------
2552
    push  eax ecx edx esi edi
2553
 
2554
    ; write difference ( 2 ) from cache to hd
2555
 
2556
    mov   ecx,cache_max
2557
    mov   esi,0x600000+8
2558
    mov   edi,1
2559
 
2560
  write_cache_more:
2561
 
2562
    cmp   dword [esi+4],2       ; if cache slot is not different
2563
    jne   does_not_need_writing
2564
 
2565
    mov   dword [esi+4],1       ; same as in hd
2566
    mov   eax,[esi]             ; eax = sector to write
2567
 
2568
    cmp   eax,[PARTITION_START]
2569
    jb    danger
2570
    cmp   eax,[PARTITION_END]
2571
    ja    danger
2572
 
2573
    call  wait_for_hd_idle
2574
 
2575
    cli
2576
    xor   eax,eax
2577
    mov   edx,[hdbase]
2578
    inc   edx
2579
    out   dx,al
2580
    inc   edx
2581
    inc   eax
2582
    out   dx,al
2583
    inc   edx
2584
    mov   eax,[esi]             ; eax = sector to write
2585
    out   dx,al
2586
    shr   eax,8
2587
    inc   edx
2588
    out   dx,al
2589
    shr   eax,8
2590
    inc   edx
2591
    out   dx,al
2592
    shr   eax,8
2593
    inc   edx
2594
    and   al,1+2+4+8
2595
    add   al,byte [hdid]
2596
    add   al,128+64+32
2597
    out   dx,al
2598
    inc   edx
2599
    mov   al,30h
2600
    out   dx,al
2601
    sti
2602
 
2603
    call  wait_for_sector_buffer
2604
 
2605
    cmp   [hd_error],0
2606
    jne   hd_write_error
2607
 
2608
    push  ecx esi
2609
 
2610
    cli
2611
    mov   esi,edi
2612
    shl   esi,9
2613
    add   esi,0x600000+65536    ; esi = from memory position
2614
    mov   ecx,256
2615
    mov   edx,[hdbase]
2616
    cld
2617
    rep   outsw
2618
    sti
2619
 
2620
    pop   esi ecx
2621
 
2622
  danger:
2623
  does_not_need_writing:
2624
 
2625
    add   esi,8
2626
    inc   edi
2627
    dec   ecx
2628
    jnz   write_cache_more
2629
 
2630
    pop   edi esi edx ecx eax
2631
    ret
2632
 
2633
 
2634
find_empty_slot:
2635
;-----------------------------------------------------------
2636
; find empty or read slot, flush cache if next 10% is used by write
2637
; output : edi = cache slot
2638
;-----------------------------------------------------------
2639
    push  ecx esi
2640
 
2641
  search_again:
2642
 
2643
    mov   ecx,cache_max*10/100
2644
    mov   edi,[cache_search_start]
2645
 
2646
  search_for_empty:
2647
 
2648
    inc   edi
2649
    cmp   edi,cache_max
2650
    jbe   inside_cache
2651
    mov   edi,1
2652
 
2653
  inside_cache:
2654
 
2655
    cmp   dword [edi*8+0x600000+4],2    ; get cache slot info
2656
    jb    found_slot                    ; it's empty or read
2657
    dec   ecx
2658
    jnz   search_for_empty
2659
 
2660
    call  write_cache                   ; no empty slots found, write all
2661
    jmp   search_again                  ; and start again
2662
 
2663
  found_slot:
2664
 
2665
    mov   [cache_search_start],edi
2666
 
2667
    pop   esi ecx
2668
    ret
2669
 
2670
 
2671
save_hd_wait_timeout:
2672
 
2673
    push  eax
2674
    mov   eax,[timer_ticks];[0xfdf0]
2675
    add   eax,300               ; 3 sec timeout
2676
    mov   [hd_wait_timeout],eax
2677
    pop   eax
2678
    ret
2679
 
2680
 
2681
check_hd_wait_timeout:
2682
 
2683
    push  eax
2684
    mov   eax,[hd_wait_timeout]
2685
    cmp   [timer_ticks], eax ;[0xfdf0],eax
2686
    jg    hd_timeout_error
2687
    pop   eax
2688
    ret
2689
 
2690
iglobal
2691
  hd_timeout_str   db 'K : FS - HD timeout',13,10,0
2692
  hd_read_str      db 'K : FS - HD read error',13,10,0
2693
  hd_write_str     db 'K : FS - HD write error',13,10,0
2694
endg
2695
 
2696
hd_timeout_error:
2697
 
2698
    call  clear_hd_cache
2699
    call  clear_application_table_status
2700
    mov   esi,hd_timeout_str
2701
    call  sys_msg_board_str
2702
    jmp   $
2703
 
2704
 
2705
hd_read_error:
2706
 
2707
    call  clear_hd_cache
2708
    call  clear_application_table_status
2709
    mov   esi,hd_read_str
2710
    call  sys_msg_board_str
2711
    jmp   $
2712
 
2713
hd_write_error:
2714
 
2715
    call  clear_hd_cache
2716
    call  clear_application_table_status
2717
    mov   esi,hd_write_str
2718
    call  sys_msg_board_str
2719
    jmp   $
2720
 
2721
 
2722
 
2723
 
2724
wait_for_hd_idle:
2725
 
2726
    push  eax edx
2727
 
2728
    call  save_hd_wait_timeout
2729
 
2730
    mov   edx,[hdbase]
2731
    add   edx,0x7
2732
 
2733
  wfhil1:
2734
 
2735
    call  check_hd_wait_timeout
2736
 
2737
    in    al,dx
2738
    test  al,128
2739
    jnz   wfhil1
2740
 
2741
    pop   edx eax
2742
    ret
2743
 
2744
 
2745
wait_for_sector_buffer:
2746
 
2747
    push  eax edx
2748
 
2749
    mov   edx,[hdbase]
2750
    add   edx,0x7
2751
 
2752
    call  save_hd_wait_timeout
2753
 
2754
  hdwait_sbuf:                  ; wait for sector buffer to be ready
2755
 
2756
    call  check_hd_wait_timeout
2757
 
2758
    in    al,dx
2759
    test  al,8
2760
    jz    hdwait_sbuf
2761
 
2762
    mov   [hd_error],0
2763
 
2764
    cmp   [hd_setup],1          ; do not mark error for setup request
2765
    je    buf_wait_ok
2766
 
2767
    test  al,1                  ; previous command ended up with an error
2768
    jz    buf_wait_ok
2769
    mov   [hd_error],1
2770
 
2771
  buf_wait_ok:
2772
 
2773
    pop   edx eax
2774
    ret
2775
 
2776
 
2777
 
2778
read_hd_file:
2779
;-----------------------------------------------------------------
2780
;
2781
; Converting old reading function for hd-application start.
2782
;
2783
; IN:
2784
;
2785
; eax - pointer to file (0 = read only first sector of drive: eg 'label')
2786
; ebx - file lenght
2787
; ecx - start 512 byte block number
2788
; edx - number of blocks to read
2789
; esi - pointer to return/work area (atleast 20 000 bytes)
2790
;
2791
; For new read function
2792
;
2793
; EAX   (PAR0)      pointer to file-name
2794
; ECX   (PAR1)      pointer to buffer
2795
; EBX   (PAR2)   vt file blocks to read
2796
; EDX   (PAR3)      pointer to path
2797
; ESI            vt first 512 block to read
2798
; EDI               if 0 - return root
2799
;--------------------------------------------------------------------------
2800
 
2801
    push  ecx esi edi
2802
    mov   esi,eax
2803
    mov   edi,startpath
2804
    mov   ecx,250
2805
    cld
2806
    rep   movsb
2807
    pop   edi esi ecx
2808
 
2809
    mov   eax,startpath
2810
    mov   [eax+ebx-12],byte 0
2811
 
2812
    push  eax ebx ecx edx esi
2813
 
2814
    pop   ecx ; pointer to buffer
2815
    add   ecx,1024
2816
    pop   ebx ; number of blocks to read
2817
    pop   esi ; first block to read
2818
    dec   esi
2819
    pop   eax ; file length
2820
    pop   edx ; pointer to path
2821
 
2822
    mov   edi,12
2823
    lea   eax,[eax+edx-12+1]
2824
    call  file_read
2825
 
2826
    ret
2827