Subversion Repositories Kolibri OS

Rev

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

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