Subversion Repositories Kolibri OS

Rev

Rev 86 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 86 Rev 88
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;;  FAT32.INC                                                      ;;
3
;;  FAT32.INC                                                      ;;
4
;;                                                                 ;;
4
;;                                                                 ;;
5
;;  FAT16/32 functions for MenuetOS                                ;;
5
;;  FAT16/32 functions for MenuetOS                                ;;
6
;;                                                                 ;;
6
;;                                                                 ;;
7
;;  Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it          ;;
7
;;  Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it          ;;
8
;;                                                                 ;;
8
;;                                                                 ;;
9
;;  See file COPYING for details                                   ;;
9
;;  See file COPYING for details                                   ;;
10
;;  15.06.2006 LFN get/set file/folder info - diamond              ;;
10
;;  15.06.2006 LFN get/set file/folder info - diamond              ;;
11
;;  27.05.2006 LFN create/rewrite file - diamond                   ;;
11
;;  27.05.2006 LFN create/rewrite file - diamond                   ;;
12
;;  04.05.2006 LFN read folder - diamond                           ;;
12
;;  04.05.2006 LFN read folder - diamond                           ;;
13
;;  29.04.2006 Elimination of hangup after the                     ;;
13
;;  29.04.2006 Elimination of hangup after the                     ;;
14
;;             expiration hd_wait_timeout -  Mario79               ;;           
14
;;             expiration hd_wait_timeout -  Mario79               ;;           
15
;;  23.04.2006 LFN read file - diamond                             ;;
15
;;  23.04.2006 LFN read file - diamond                             ;;
16
;;  28.01.2006 find all Fat16/32 partition in all input point      ;;
16
;;  28.01.2006 find all Fat16/32 partition in all input point      ;;
17
;;             to MBR, see file part_set.inc - Mario79             ;;
17
;;             to MBR, see file part_set.inc - Mario79             ;;
18
;;  15.01.2005 get file size/attr/date, file_append - ATV          ;;
18
;;  15.01.2005 get file size/attr/date, file_append - ATV          ;;
19
;;  04.12.2004 skip volume label, file delete bug fixed - ATV      ;;
19
;;  04.12.2004 skip volume label, file delete bug fixed - ATV      ;;
20
;;  29.11.2004 get_free_FAT changed, append dir bug fixed - ATV    ;;
20
;;  29.11.2004 get_free_FAT changed, append dir bug fixed - ATV    ;;
21
;;  23.11.2004 don't allow overwrite dir with file - ATV           ;;
21
;;  23.11.2004 don't allow overwrite dir with file - ATV           ;;
22
;;  18.11.2004 get_disk_info and more error codes - ATV            ;;
22
;;  18.11.2004 get_disk_info and more error codes - ATV            ;;
23
;;  17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV      ;;
23
;;  17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV      ;;
24
;;  10.11.2004 removedir clear whole directory structure - ATV     ;;
24
;;  10.11.2004 removedir clear whole directory structure - ATV     ;;
25
;;  08.11.2004 rename - ATV                                        ;;
25
;;  08.11.2004 rename - ATV                                        ;;
26
;;  30.10.2004 file_read return also dirsize in bytes - ATV        ;;
26
;;  30.10.2004 file_read return also dirsize in bytes - ATV        ;;
27
;;  20.10.2004 Makedir/Removedir - ATV                             ;;
27
;;  20.10.2004 Makedir/Removedir - ATV                             ;;
28
;;  14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx)         ;;
28
;;  14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx)         ;;
29
;;  06.9.2004  Fix free space by Mario79 added - MH                ;;
29
;;  06.9.2004  Fix free space by Mario79 added - MH                ;;
30
;;  24.5.2004  Write back buffer for File_write -VT                ;;
30
;;  24.5.2004  Write back buffer for File_write -VT                ;;
31
;;  20.5.2004  File_read function to work with syscall 58 - VT     ;;
31
;;  20.5.2004  File_read function to work with syscall 58 - VT     ;;
32
;;  30.3.2004  Error parameters at function return - VT            ;;
32
;;  30.3.2004  Error parameters at function return - VT            ;;
33
;;  01.5.2002  Bugfix in device write - VT                         ;;
33
;;  01.5.2002  Bugfix in device write - VT                         ;;
34
;;  20.5.2002  Hd status check - VT                                ;;
34
;;  20.5.2002  Hd status check - VT                                ;;
35
;;  29.6.2002  Improved fat32 verification - VT                    ;;
35
;;  29.6.2002  Improved fat32 verification - VT                    ;;
36
;;                                                                 ;;
36
;;                                                                 ;;
37
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
37
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38
 
38
 
39
cache_max equ 1919      ; max. is 1919*512+0x610000=0x6ffe00
39
cache_max equ 1919      ; max. is 1919*512+0x610000=0x6ffe00
40
 
40
 
41
ERROR_SUCCESS        = 0
41
ERROR_SUCCESS        = 0
42
ERROR_DISK_BASE      = 1
42
ERROR_DISK_BASE      = 1
43
ERROR_UNSUPPORTED_FS = 2
43
ERROR_UNSUPPORTED_FS = 2
44
ERROR_UNKNOWN_FS     = 3
44
ERROR_UNKNOWN_FS     = 3
45
ERROR_PARTITION      = 4
45
ERROR_PARTITION      = 4
46
ERROR_FILE_NOT_FOUND = 5
46
ERROR_FILE_NOT_FOUND = 5
47
ERROR_END_OF_FILE    = 6
47
ERROR_END_OF_FILE    = 6
48
ERROR_MEMORY_POINTER = 7
48
ERROR_MEMORY_POINTER = 7
49
ERROR_DISK_FULL      = 8
49
ERROR_DISK_FULL      = 8
50
ERROR_FAT_TABLE      = 9
50
ERROR_FAT_TABLE      = 9
51
ERROR_ACCESS_DENIED  = 10
51
ERROR_ACCESS_DENIED  = 10
52
 
52
 
53
PUSHAD_EAX equ [esp+28]
53
PUSHAD_EAX equ [esp+28]
54
PUSHAD_ECX equ [esp+24]
54
PUSHAD_ECX equ [esp+24]
55
PUSHAD_EDX equ [esp+20]
55
PUSHAD_EDX equ [esp+20]
56
PUSHAD_EBX equ [esp+16]
56
PUSHAD_EBX equ [esp+16]
57
PUSHAD_EBP equ [esp+8]
57
PUSHAD_EBP equ [esp+8]
58
PUSHAD_ESI equ [esp+4]
58
PUSHAD_ESI equ [esp+4]
59
PUSHAD_EDI equ [esp+0]
59
PUSHAD_EDI equ [esp+0]
60
 
60
 
61
cluster              dd 0       ; used by file_write,makedir,append
61
cluster              dd 0       ; used by file_write,makedir,append
62
partition_count      dd 0       ; partitions found by set_FAT32_variables
62
partition_count      dd 0       ; partitions found by set_FAT32_variables
63
longname_sec1        dd 0       ; used by analyze_directory to save 2 previous
63
longname_sec1        dd 0       ; used by analyze_directory to save 2 previous
64
longname_sec2        dd 0       ; directory sectors for delete long filename
64
longname_sec2        dd 0       ; directory sectors for delete long filename
65
 
65
 
66
hd_error             dd 0       ; set by wait_for_sector_buffer
66
hd_error             dd 0       ; set by wait_for_sector_buffer
67
hd_setup             dd 0
67
hd_setup             dd 0
68
hd_wait_timeout      dd 0
68
hd_wait_timeout      dd 0
69
 
69
 
70
cluster_tmp          dd 0       ; used by analyze_directory
70
cluster_tmp          dd 0       ; used by analyze_directory
71
                                ; and analyze_directory_to_write
71
                                ; and analyze_directory_to_write
72
 
72
 
73
file_size            dd 0       ; used by file_read
73
file_size            dd 0       ; used by file_read
74
 
74
 
75
sector_tmp           dd 0       ; used by rename,append,file_write
75
sector_tmp           dd 0       ; used by rename,append,file_write
76
entry_pos            dd 0       ; used by rename,append,file_write
76
entry_pos            dd 0       ; used by rename,append,file_write
77
 
77
 
78
old_filesize         dd 0       ; used by append
78
old_filesize         dd 0       ; used by append
79
new_filepos          dd 0       ; used by append
79
new_filepos          dd 0       ; used by append
80
bytes2write          dd 0       ; used by append
80
bytes2write          dd 0       ; used by append
81
 
81
 
82
cache_search_start   dd 0       ; used by find_empty_slot
82
cache_search_start   dd 0       ; used by find_empty_slot
83
 
83
 
84
fat_in_cache         dd -1
84
fat_in_cache         dd -1
85
fat_cache:           times 512 db 0
85
fat_cache:           times 512 db 0
86
 
86
 
87
uglobal
87
uglobal
88
 Sector512:                      ; label for dev_hdcd.inc
88
 Sector512:                      ; label for dev_hdcd.inc
89
  buffer:              times 512 db 0
89
  buffer:              times 512 db 0
90
  deltree_buffer:      times 512 db 0
90
  deltree_buffer:      times 512 db 0
91
endg
91
endg
92
 
92
 
93
iglobal
93
iglobal
94
  NewDirEntry1         db ".          ",0x10
94
  NewDirEntry1         db ".          ",0x10
95
                     times 20 db 0
95
                     times 20 db 0
96
  NewDirEntry2         db "..         ",0x10
96
  NewDirEntry2         db "..         ",0x10
97
                     times 20 db 0
97
                     times 20 db 0
98
endg
98
endg
99
 
99
 
100
uglobal
100
uglobal
101
  dir_entry:           times 32 db 0
101
  dir_entry:           times 32 db 0
102
 
102
 
103
  startpath:           times 255 db 0
103
  startpath:           times 255 db 0
104
 
104
 
105
  fat16_root           db 0       ; flag for fat16 rootdir
105
  fat16_root           db 0       ; flag for fat16 rootdir
106
  f_del                db 0       ; 1=overwrite fat entry
106
  f_del                db 0       ; 1=overwrite fat entry
107
  fat_change           db 0       ; 1=fat has changed
107
  fat_change           db 0       ; 1=fat has changed
108
 
108
 
109
endg
109
endg
110
 
110
 
111
reserve_hd1:
111
reserve_hd1:
112
 
112
 
113
    cli
113
    cli
114
    cmp   [hd1_status],0
114
    cmp   [hd1_status],0
115
    je    reserve_ok1
115
    je    reserve_ok1
116
 
116
 
117
    sti
117
    sti
118
    call  change_task
118
    call  change_task
119
    jmp   reserve_hd1
119
    jmp   reserve_hd1
120
 
120
 
121
  reserve_ok1:
121
  reserve_ok1:
122
 
122
 
123
    push  eax
123
    push  eax
124
    mov   eax,[0x3000]
124
    mov   eax,[0x3000]
125
    shl   eax,5
125
    shl   eax,5
126
    mov   eax,[eax+0x3000+4]
126
    mov   eax,[eax+0x3000+4]
127
    mov   [hd1_status],eax
127
    mov   [hd1_status],eax
128
    pop   eax
128
    pop   eax
129
    sti
129
    sti
130
    ret
130
    ret
131
 
131
 
132
 
132
 
133
clear_hd_cache:
133
clear_hd_cache:
134
 
134
 
135
    push  eax ecx edi
135
    push  eax ecx edi
136
    mov   edi,0x600000
136
    mov   edi,0x600000
137
    mov   ecx,16384
137
    mov   ecx,16384
138
    xor   eax,eax
138
    xor   eax,eax
139
    cld
139
    cld
140
    rep   stosd                 ; clear hd cache with 0
140
    rep   stosd                 ; clear hd cache with 0
141
    mov   [cache_search_start],eax
141
    mov   [cache_search_start],eax
142
    mov   [fat_in_cache],-1
142
    mov   [fat_in_cache],-1
143
    mov   [fat_change],0
143
    mov   [fat_change],0
144
    pop   edi ecx eax
144
    pop   edi ecx eax
145
    ret
145
    ret
146
 
146
 
147
problem_partition db 0  ; used for partitions search 
147
problem_partition db 0  ; used for partitions search 
148
 
148
 
149
include  'part_set.inc'
149
include  'part_set.inc'
150
 
150
 
151
set_FAT:
151
set_FAT:
152
;--------------------------------
152
;--------------------------------
153
; input  : EAX = cluster
153
; input  : EAX = cluster
154
;          EDX = value to save
154
;          EDX = value to save
155
; output : EDX = old value
155
; output : EDX = old value
156
;--------------------------------
156
;--------------------------------
157
    push  eax ebx esi
157
    push  eax ebx esi
158
 
158
 
159
    cmp   eax,2
159
    cmp   eax,2
160
    jb    sfc_error
160
    jb    sfc_error
161
    cmp   eax,[LAST_CLUSTER]
161
    cmp   eax,[LAST_CLUSTER]
162
    ja    sfc_error
162
    ja    sfc_error
163
    cmp   [fat_type],16
163
    cmp   [fat_type],16
164
    je    sfc_1
164
    je    sfc_1
165
    add   eax,eax
165
    add   eax,eax
166
  sfc_1:
166
  sfc_1:
167
    add   eax,eax
167
    add   eax,eax
168
    mov   esi,511
168
    mov   esi,511
169
    and   esi,eax               ; esi = position in fat sector
169
    and   esi,eax               ; esi = position in fat sector
170
    shr   eax,9                 ; eax = fat sector
170
    shr   eax,9                 ; eax = fat sector
171
    add   eax,[FAT_START]
171
    add   eax,[FAT_START]
172
    mov   ebx,fat_cache
172
    mov   ebx,fat_cache
173
 
173
 
174
    cmp   eax,[fat_in_cache]    ; is fat sector already in memory?
174
    cmp   eax,[fat_in_cache]    ; is fat sector already in memory?
175
    je    sfc_in_cache          ; yes
175
    je    sfc_in_cache          ; yes
176
 
176
 
177
    cmp   [fat_change],0        ; is fat changed?
177
    cmp   [fat_change],0        ; is fat changed?
178
    je    sfc_no_change         ; no
178
    je    sfc_no_change         ; no
179
    call  write_fat_sector      ; yes. write it into disk
179
    call  write_fat_sector      ; yes. write it into disk
180
    cmp   [hd_error],0
180
    cmp   [hd_error],0
181
    jne   sfc_error
181
    jne   sfc_error
182
 
182
 
183
  sfc_no_change:
183
  sfc_no_change:
184
    mov   [fat_in_cache],eax    ; save fat sector
184
    mov   [fat_in_cache],eax    ; save fat sector
185
    call  hd_read
185
    call  hd_read
186
    cmp  [hd_error],0
186
    cmp  [hd_error],0
187
    jne  sfc_error
187
    jne  sfc_error
188
    
188
    
189
 
189
 
190
  sfc_in_cache:
190
  sfc_in_cache:
191
    cmp   [fat_type],16
191
    cmp   [fat_type],16
192
    jne   sfc_test32
192
    jne   sfc_test32
193
 
193
 
194
    cmp   [f_del],1             ; overwrite previous value?
194
    cmp   [f_del],1             ; overwrite previous value?
195
    je    sfc_set16             ; yes
195
    je    sfc_set16             ; yes
196
    cmp   word [ebx+esi],0      ; is cluster free?
196
    cmp   word [ebx+esi],0      ; is cluster free?
197
    je    sfc_set16             ; yes
197
    je    sfc_set16             ; yes
198
    mov   dword [8*0x100000],0xffffff
198
    mov   dword [8*0x100000],0xffffff
199
    mov   edx,[ebx+esi]         ; get old value
199
    mov   edx,[ebx+esi]         ; get old value
200
    jmp   sfc_nonzero
200
    jmp   sfc_nonzero
201
 
201
 
202
  sfc_set16:
202
  sfc_set16:
203
    xchg  [ebx+esi],dx          ; save new value and get old value
203
    xchg  [ebx+esi],dx          ; save new value and get old value
204
    jmp   sfc_write
204
    jmp   sfc_write
205
 
205
 
206
  sfc_test32:
206
  sfc_test32:
207
    mov   eax,[fatMASK]
207
    mov   eax,[fatMASK]
208
    cmp   [f_del],1             ; overwrite previous value?
208
    cmp   [f_del],1             ; overwrite previous value?
209
    je    sfc_set32             ; yes
209
    je    sfc_set32             ; yes
210
    test  eax,[ebx+esi]         ; is cluster free?
210
    test  eax,[ebx+esi]         ; is cluster free?
211
    je    sfc_set32             ; yes
211
    je    sfc_set32             ; yes
212
    mov   dword [8*0x100000],0xffffff
212
    mov   dword [8*0x100000],0xffffff
213
    mov   edx,[ebx+esi]         ; get old value
213
    mov   edx,[ebx+esi]         ; get old value
214
    jmp   sfc_nonzero
214
    jmp   sfc_nonzero
215
 
215
 
216
  sfc_set32:
216
  sfc_set32:
217
    and   edx,eax
217
    and   edx,eax
218
    xor   eax,-1                ; mask for high bits
218
    xor   eax,-1                ; mask for high bits
219
    and   eax,[ebx+esi]         ; get high 4 bits
219
    and   eax,[ebx+esi]         ; get high 4 bits
220
    or    eax,edx
220
    or    eax,edx
221
    mov   edx,[ebx+esi]         ; get old value
221
    mov   edx,[ebx+esi]         ; get old value
222
    mov   [ebx+esi],eax         ; save new value
222
    mov   [ebx+esi],eax         ; save new value
223
 
223
 
224
  sfc_write:
224
  sfc_write:
225
    mov   [fat_change],1        ; fat has changed
225
    mov   [fat_change],1        ; fat has changed
226
 
226
 
227
  sfc_nonzero:
227
  sfc_nonzero:
228
    and   edx,[fatMASK]
228
    and   edx,[fatMASK]
229
 
229
 
230
  sfc_error:
230
  sfc_error:
231
    pop   esi ebx eax
231
    pop   esi ebx eax
232
    ret
232
    ret
233
 
233
 
234
 
234
 
235
get_FAT:
235
get_FAT:
236
;--------------------------------
236
;--------------------------------
237
; input  : EAX = cluster
237
; input  : EAX = cluster
238
; output : EAX = next cluster
238
; output : EAX = next cluster
239
;--------------------------------
239
;--------------------------------
240
    push  ebx esi
240
    push  ebx esi
241
 
241
 
242
    cmp   [fat_type],16
242
    cmp   [fat_type],16
243
    je    gfc_1
243
    je    gfc_1
244
    add   eax,eax
244
    add   eax,eax
245
  gfc_1:
245
  gfc_1:
246
    add   eax,eax
246
    add   eax,eax
247
    mov   esi,511
247
    mov   esi,511
248
    and   esi,eax               ; esi = position in fat sector
248
    and   esi,eax               ; esi = position in fat sector
249
    shr   eax,9                 ; eax = fat sector
249
    shr   eax,9                 ; eax = fat sector
250
    add   eax,[FAT_START]
250
    add   eax,[FAT_START]
251
    mov   ebx,fat_cache
251
    mov   ebx,fat_cache
252
 
252
 
253
    cmp   eax,[fat_in_cache]    ; is fat sector already in memory?
253
    cmp   eax,[fat_in_cache]    ; is fat sector already in memory?
254
    je    gfc_in_cache
254
    je    gfc_in_cache
255
 
255
 
256
    cmp   [fat_change],0        ; is fat changed?
256
    cmp   [fat_change],0        ; is fat changed?
257
    je    gfc_no_change         ; no
257
    je    gfc_no_change         ; no
258
    call  write_fat_sector      ; yes. write it into disk
258
    call  write_fat_sector      ; yes. write it into disk
259
    cmp  [hd_error],0
259
    cmp  [hd_error],0
260
    jne  hd_error_01
260
    jne  hd_error_01
261
 
261
 
262
  gfc_no_change:
262
  gfc_no_change:
263
    mov   [fat_in_cache],eax
263
    mov   [fat_in_cache],eax
264
    call  hd_read
264
    call  hd_read
265
    cmp  [hd_error],0
265
    cmp  [hd_error],0
266
    jne  hd_error_01
266
    jne  hd_error_01
267
 
267
 
268
  gfc_in_cache:
268
  gfc_in_cache:
269
    mov   eax,[ebx+esi]
269
    mov   eax,[ebx+esi]
270
    and   eax,[fatMASK]
270
    and   eax,[fatMASK]
271
 hd_error_01:
271
 hd_error_01:
272
    pop   esi ebx
272
    pop   esi ebx
273
    ret
273
    ret
274
 
274
 
275
 
275
 
276
get_free_FAT:
276
get_free_FAT:
277
;-----------------------------------------------------------
277
;-----------------------------------------------------------
278
; input  : EAX = # cluster for start the searching
278
; input  : EAX = # cluster for start the searching
279
; output : if CARRY=0 EAX = # first cluster found free
279
; output : if CARRY=0 EAX = # first cluster found free
280
;          if CARRY=1 disk full
280
;          if CARRY=1 disk full
281
; Note   : for more speed need to use fat_cache directly
281
; Note   : for more speed need to use fat_cache directly
282
;-----------------------------------------------------------
282
;-----------------------------------------------------------
283
    push  ecx
283
    push  ecx
284
    mov   ecx,[LAST_CLUSTER]    ; counter for full disk
284
    mov   ecx,[LAST_CLUSTER]    ; counter for full disk
285
    sub   ecx,2
285
    sub   ecx,2
286
 
286
 
287
  gff_test:
287
  gff_test:
288
    cmp   eax,[LAST_CLUSTER]    ; if above last cluster start at cluster 2
288
    cmp   eax,[LAST_CLUSTER]    ; if above last cluster start at cluster 2
289
    jbe   gff_in_range
289
    jbe   gff_in_range
290
    mov   eax,2
290
    mov   eax,2
291
 
291
 
292
  gff_in_range:
292
  gff_in_range:
293
    push  eax
293
    push  eax
294
    call  get_FAT               ; get cluster state
294
    call  get_FAT               ; get cluster state
295
    cmp   [hd_error],0
295
    cmp   [hd_error],0
296
    jne   gff_not_found_1
296
    jne   gff_not_found_1
297
 
297
 
298
    test  eax,eax               ; is it free?
298
    test  eax,eax               ; is it free?
299
    pop   eax
299
    pop   eax
300
    je    gff_found             ; yes
300
    je    gff_found             ; yes
301
    inc   eax                   ; next cluster
301
    inc   eax                   ; next cluster
302
    dec   ecx                   ; is all checked?
302
    dec   ecx                   ; is all checked?
303
    jns   gff_test              ; no
303
    jns   gff_test              ; no
304
 
304
 
305
  gff_not_found_1:
305
  gff_not_found_1:
306
    add   esp,4
306
    add   esp,4
307
  gff_not_found:
307
  gff_not_found:
308
    pop   ecx                   ; yes. disk is full
308
    pop   ecx                   ; yes. disk is full
309
    stc
309
    stc
310
    ret
310
    ret
311
 
311
 
312
  gff_found:
312
  gff_found:
313
    pop   ecx
313
    pop   ecx
314
    clc
314
    clc
315
    ret
315
    ret
316
 
316
 
317
 
317
 
318
write_fat_sector:
318
write_fat_sector:
319
;-----------------------------------------------------------
319
;-----------------------------------------------------------
320
; write changed fat to disk
320
; write changed fat to disk
321
;-----------------------------------------------------------
321
;-----------------------------------------------------------
322
    push  eax ebx ecx
322
    push  eax ebx ecx
323
 
323
 
324
    mov   [fat_change],0
324
    mov   [fat_change],0
325
    mov   eax,[fat_in_cache]
325
    mov   eax,[fat_in_cache]
326
    cmp   eax,-1
326
    cmp   eax,-1
327
    jz    write_fat_not_used
327
    jz    write_fat_not_used
328
    mov   ebx,fat_cache
328
    mov   ebx,fat_cache
329
    mov   ecx,[NUMBER_OF_FATS]
329
    mov   ecx,[NUMBER_OF_FATS]
330
 
330
 
331
  write_next_fat:
331
  write_next_fat:
332
    call  hd_write
332
    call  hd_write
333
    cmp   [hd_error],0
333
    cmp   [hd_error],0
334
    jne   write_fat_not_used
334
    jne   write_fat_not_used
335
 
335
 
336
    add   eax,[SECTORS_PER_FAT]
336
    add   eax,[SECTORS_PER_FAT]
337
    dec   ecx
337
    dec   ecx
338
    jnz   write_next_fat
338
    jnz   write_next_fat
339
 
339
 
340
  write_fat_not_used:
340
  write_fat_not_used:
341
    pop   ecx ebx eax
341
    pop   ecx ebx eax
342
    ret
342
    ret
343
 
343
 
344
 
344
 
345
analyze_directory:
345
analyze_directory:
346
;-----------------------------------------------------------
346
;-----------------------------------------------------------
347
; input  : EAX = first cluster of the directory
347
; input  : EAX = first cluster of the directory
348
;          EBX = pointer to filename
348
;          EBX = pointer to filename
349
; output : IF CARRY=0 EAX = sector where th file is found
349
; output : IF CARRY=0 EAX = sector where th file is found
350
;                     EBX = pointer in buffer
350
;                     EBX = pointer in buffer
351
;                     [buffer .. buffer+511]
351
;                     [buffer .. buffer+511]
352
;                     ECX,EDX,ESI,EDI not changed
352
;                     ECX,EDX,ESI,EDI not changed
353
;          IF CARRY=1 filename not found
353
;          IF CARRY=1 filename not found
354
; Note   : if cluster=0 it's changed to read rootdir
354
; Note   : if cluster=0 it's changed to read rootdir
355
;          save 2 previous directory sectors in longname_sec
355
;          save 2 previous directory sectors in longname_sec
356
;-----------------------------------------------------------
356
;-----------------------------------------------------------
357
    push  ecx edx esi edi ebx   ; ebx = [esp+0]
357
    push  ecx edx esi edi ebx   ; ebx = [esp+0]
358
    mov   [longname_sec1],0
358
    mov   [longname_sec1],0
359
    mov   [longname_sec2],0
359
    mov   [longname_sec2],0
360
 
360
 
361
  adr_new_cluster:
361
  adr_new_cluster:
362
    mov   [cluster_tmp],eax
362
    mov   [cluster_tmp],eax
363
    mov   [fat16_root],0
363
    mov   [fat16_root],0
364
    cmp   eax,[LAST_CLUSTER]
364
    cmp   eax,[LAST_CLUSTER]
365
    ja    adr_not_found         ; too big cluster number, something is wrong
365
    ja    adr_not_found         ; too big cluster number, something is wrong
366
    cmp   eax,2
366
    cmp   eax,2
367
    jnb   adr_data_cluster
367
    jnb   adr_data_cluster
368
 
368
 
369
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
369
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
370
    cmp   [fat_type],16
370
    cmp   [fat_type],16
371
    jne   adr_data_cluster
371
    jne   adr_data_cluster
372
    mov   eax,[ROOT_START]
372
    mov   eax,[ROOT_START]
373
    mov   edx,[ROOT_SECTORS]
373
    mov   edx,[ROOT_SECTORS]
374
    mov   [fat16_root],1        ; flag for fat16 rootdir
374
    mov   [fat16_root],1        ; flag for fat16 rootdir
375
    jmp   adr_new_sector
375
    jmp   adr_new_sector
376
 
376
 
377
  adr_data_cluster:
377
  adr_data_cluster:
378
    sub   eax,2
378
    sub   eax,2
379
    mov   edx,[SECTORS_PER_CLUSTER]
379
    mov   edx,[SECTORS_PER_CLUSTER]
380
    imul  eax,edx
380
    imul  eax,edx
381
    add   eax,[DATA_START]
381
    add   eax,[DATA_START]
382
 
382
 
383
  adr_new_sector:
383
  adr_new_sector:
384
    mov   ebx,buffer
384
    mov   ebx,buffer
385
    call  hd_read
385
    call  hd_read
386
    cmp  [hd_error],0
386
    cmp  [hd_error],0
387
    jne  adr_not_found
387
    jne  adr_not_found
388
 
388
 
389
    mov   ecx,512/32            ; count of dir entrys per sector = 16
389
    mov   ecx,512/32            ; count of dir entrys per sector = 16
390
 
390
 
391
  adr_analyze:
391
  adr_analyze:
392
    mov   edi,[ebx+11]          ; file attribute
392
    mov   edi,[ebx+11]          ; file attribute
393
    and   edi,0xf
393
    and   edi,0xf
394
    cmp   edi,0xf
394
    cmp   edi,0xf
395
    je    adr_long_filename
395
    je    adr_long_filename
396
    test  edi,0x8               ; skip over volume label
396
    test  edi,0x8               ; skip over volume label
397
    jne   adr_long_filename     ; Note: label can be same name as file/dir
397
    jne   adr_long_filename     ; Note: label can be same name as file/dir
398
 
398
 
399
    mov   esi,[esp+0]           ; filename need to be uppercase
399
    mov   esi,[esp+0]           ; filename need to be uppercase
400
    mov   edi,ebx
400
    mov   edi,ebx
401
    push  ecx
401
    push  ecx
402
    mov   ecx,11
402
    mov   ecx,11
403
    cld
403
    cld
404
    rep   cmpsb                 ; compare 8+3 filename
404
    rep   cmpsb                 ; compare 8+3 filename
405
    pop   ecx
405
    pop   ecx
406
    je    adr_found
406
    je    adr_found
407
 
407
 
408
  adr_long_filename:
408
  adr_long_filename:
409
    add   ebx,32                ; position of next dir entry
409
    add   ebx,32                ; position of next dir entry
410
    dec   ecx
410
    dec   ecx
411
    jnz   adr_analyze
411
    jnz   adr_analyze
412
 
412
 
413
    mov   ecx,[longname_sec1]   ; save 2 previous directory sectors
413
    mov   ecx,[longname_sec1]   ; save 2 previous directory sectors
414
    mov   [longname_sec1],eax   ; for delete long filename
414
    mov   [longname_sec1],eax   ; for delete long filename
415
    mov   [longname_sec2],ecx
415
    mov   [longname_sec2],ecx
416
    inc   eax                   ; next sector
416
    inc   eax                   ; next sector
417
    dec   edx
417
    dec   edx
418
    jne   adr_new_sector
418
    jne   adr_new_sector
419
    cmp   [fat16_root],1        ; end of fat16 rootdir
419
    cmp   [fat16_root],1        ; end of fat16 rootdir
420
    je    adr_not_found
420
    je    adr_not_found
421
 
421
 
422
  adr_next_cluster:
422
  adr_next_cluster:
423
    mov   eax,[cluster_tmp]
423
    mov   eax,[cluster_tmp]
424
    call  get_FAT               ; get next cluster
424
    call  get_FAT               ; get next cluster
425
    cmp  [hd_error],0
425
    cmp  [hd_error],0
426
    jne  adr_not_found
426
    jne  adr_not_found
427
 
427
 
428
    cmp   eax,2                 ; incorrect fat chain?
428
    cmp   eax,2                 ; incorrect fat chain?
429
    jb    adr_not_found         ; yes
429
    jb    adr_not_found         ; yes
430
    cmp   eax,[fatRESERVED]     ; is it end of directory?
430
    cmp   eax,[fatRESERVED]     ; is it end of directory?
431
    jb    adr_new_cluster       ; no. analyse it
431
    jb    adr_new_cluster       ; no. analyse it
432
 
432
 
433
  adr_not_found:
433
  adr_not_found:
434
    pop   edi edi esi edx ecx   ; first edi will remove ebx
434
    pop   edi edi esi edx ecx   ; first edi will remove ebx
435
    stc                         ; file not found
435
    stc                         ; file not found
436
    ret
436
    ret
437
 
437
 
438
  adr_found:
438
  adr_found:
439
    pop   edi edi esi edx ecx   ; first edi will remove ebx
439
    pop   edi edi esi edx ecx   ; first edi will remove ebx
440
    clc                         ; file found
440
    clc                         ; file found
441
    ret
441
    ret
442
 
442
 
443
 
443
 
444
analyze_directory_to_write:
444
analyze_directory_to_write:
445
;-----------------------------------------------------------
445
;-----------------------------------------------------------
446
; input  : EAX = first cluster of the directory
446
; input  : EAX = first cluster of the directory
447
; output : IF CARRY=0 EAX = sector where the empty pos is found
447
; output : IF CARRY=0 EAX = sector where the empty pos is found
448
;                     EBX = pointer in buffer
448
;                     EBX = pointer in buffer
449
;                     [buffer .. buffer+511]
449
;                     [buffer .. buffer+511]
450
;                     ECX,EDX,ESI,EDI not changed
450
;                     ECX,EDX,ESI,EDI not changed
451
;          IF CARRY=1 disk full or fat corrupted
451
;          IF CARRY=1 disk full or fat corrupted
452
; Note   : if cluster=0 it's changed to read rootdir
452
; Note   : if cluster=0 it's changed to read rootdir
453
;-----------------------------------------------------------
453
;-----------------------------------------------------------
454
    push  ecx edx edi
454
    push  ecx edx edi
455
 
455
 
456
  adw_new_cluster:
456
  adw_new_cluster:
457
    mov   [cluster_tmp],eax
457
    mov   [cluster_tmp],eax
458
    mov   [fat16_root],0
458
    mov   [fat16_root],0
459
    cmp   eax,[LAST_CLUSTER]
459
    cmp   eax,[LAST_CLUSTER]
460
    ja    adw_not_found         ; too big cluster number, something is wrong
460
    ja    adw_not_found         ; too big cluster number, something is wrong
461
    cmp   eax,2
461
    cmp   eax,2
462
    jnb   adw_data_cluster
462
    jnb   adw_data_cluster
463
 
463
 
464
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
464
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
465
    cmp   [fat_type],16
465
    cmp   [fat_type],16
466
    jne   adw_data_cluster
466
    jne   adw_data_cluster
467
    mov   eax,[ROOT_START]
467
    mov   eax,[ROOT_START]
468
    mov   edx,[ROOT_SECTORS]
468
    mov   edx,[ROOT_SECTORS]
469
    mov   [fat16_root],1        ; flag for fat16 rootdir
469
    mov   [fat16_root],1        ; flag for fat16 rootdir
470
    jmp   adw_new_sector
470
    jmp   adw_new_sector
471
 
471
 
472
  adw_data_cluster:
472
  adw_data_cluster:
473
    sub   eax,2
473
    sub   eax,2
474
    mov   edx,[SECTORS_PER_CLUSTER]
474
    mov   edx,[SECTORS_PER_CLUSTER]
475
    imul  eax,edx
475
    imul  eax,edx
476
    add   eax,[DATA_START]
476
    add   eax,[DATA_START]
477
 
477
 
478
  adw_new_sector:
478
  adw_new_sector:
479
    mov   ebx,buffer
479
    mov   ebx,buffer
480
    call  hd_read
480
    call  hd_read
481
    cmp  [hd_error],0
481
    cmp  [hd_error],0
482
    jne  adw_not_found
482
    jne  adw_not_found
483
 
483
 
484
    mov   ecx,512/32            ; count of dir entrys per sector = 16
484
    mov   ecx,512/32            ; count of dir entrys per sector = 16
485
 
485
 
486
  adw_analyze:
486
  adw_analyze:
487
    cmp   byte [ebx],0x00       ; is free entry?
487
    cmp   byte [ebx],0x00       ; is free entry?
488
    je    adw_found             ; yes
488
    je    adw_found             ; yes
489
    cmp   byte [ebx],0xe5       ; is deleted entry?
489
    cmp   byte [ebx],0xe5       ; is deleted entry?
490
    je    adw_found             ; yes
490
    je    adw_found             ; yes
491
    add   ebx,32                ; position of next dir entry
491
    add   ebx,32                ; position of next dir entry
492
    dec   ecx
492
    dec   ecx
493
    jnz   adw_analyze
493
    jnz   adw_analyze
494
 
494
 
495
    inc   eax                   ; next sector
495
    inc   eax                   ; next sector
496
    dec   edx
496
    dec   edx
497
    jne   adw_new_sector
497
    jne   adw_new_sector
498
    cmp   [fat16_root],1        ; end of fat16 rootdir
498
    cmp   [fat16_root],1        ; end of fat16 rootdir
499
    je    adw_not_found
499
    je    adw_not_found
500
 
500
 
501
    mov   eax,[cluster_tmp]
501
    mov   eax,[cluster_tmp]
502
    call  get_FAT               ; get next cluster
502
    call  get_FAT               ; get next cluster
503
    cmp   [hd_error],0
503
    cmp   [hd_error],0
504
    jne   adw_not_found
504
    jne   adw_not_found
505
 
505
 
506
    cmp   eax,2                 ; incorrect fat chain?
506
    cmp   eax,2                 ; incorrect fat chain?
507
    jb    adw_not_found         ; yes
507
    jb    adw_not_found         ; yes
508
    cmp   eax,[fatRESERVED]     ; is it end of directory?
508
    cmp   eax,[fatRESERVED]     ; is it end of directory?
509
    jb    adw_new_cluster       ; no. analyse it
509
    jb    adw_new_cluster       ; no. analyse it
510
 
510
 
511
    mov   eax,2                 ; this block of code add a new cluster
511
    mov   eax,2                 ; this block of code add a new cluster
512
    call  get_free_FAT          ; for the directory because the directory
512
    call  get_free_FAT          ; for the directory because the directory
513
    jc    adw_not_found         ; is full
513
    jc    adw_not_found         ; is full
514
 
514
 
515
    mov   edx,[fatEND]          ; new end for directory
515
    mov   edx,[fatEND]          ; new end for directory
516
    call  set_FAT
516
    call  set_FAT
517
    cmp  [hd_error],0
517
    cmp  [hd_error],0
518
    jne  adw_not_found
518
    jne  adw_not_found
519
 
519
 
520
    push  eax                   ; save new cluster
520
    push  eax                   ; save new cluster
521
    mov   edx,eax
521
    mov   edx,eax
522
    mov   eax,[cluster_tmp]     ; change last cluster to point new cluster
522
    mov   eax,[cluster_tmp]     ; change last cluster to point new cluster
523
    mov   [f_del],1
523
    mov   [f_del],1
524
    call  set_FAT
524
    call  set_FAT
525
    cmp  [hd_error],0
525
    cmp  [hd_error],0
526
    jne  adw_not_found_1
526
    jne  adw_not_found_1
527
 
527
 
528
    mov   [f_del],0
528
    mov   [f_del],0
529
 
529
 
530
    mov   ecx,-1                ; remove 1 cluster from free disk space
530
    mov   ecx,-1                ; remove 1 cluster from free disk space
531
    call  add_disk_free_space
531
    call  add_disk_free_space
532
    cmp  [hd_error],0
532
    cmp  [hd_error],0
533
    jne    adw_not_found_1
533
    jne    adw_not_found_1
534
 
534
 
535
    mov   ecx,512/4
535
    mov   ecx,512/4
536
    xor   eax,eax
536
    xor   eax,eax
537
    mov   edi,buffer
537
    mov   edi,buffer
538
    cld
538
    cld
539
    rep   stosd                 ; clear new directory cluster
539
    rep   stosd                 ; clear new directory cluster
540
    pop   eax
540
    pop   eax
541
 
541
 
542
    sub   eax,2
542
    sub   eax,2
543
    mov   ecx,[SECTORS_PER_CLUSTER]
543
    mov   ecx,[SECTORS_PER_CLUSTER]
544
    imul  eax,ecx
544
    imul  eax,ecx
545
    add   eax,[DATA_START]
545
    add   eax,[DATA_START]
546
    mov   ebx,buffer
546
    mov   ebx,buffer
547
    push  eax                   ; save sector number
547
    push  eax                   ; save sector number
548
 
548
 
549
  adw_set_empty_directory:
549
  adw_set_empty_directory:
550
    call  hd_write
550
    call  hd_write
551
    cmp   [hd_error],0
551
    cmp   [hd_error],0
552
    jne   adw_not_found_1
552
    jne   adw_not_found_1
553
 
553
 
554
    inc   eax                   ; next sector
554
    inc   eax                   ; next sector
555
    dec   ecx
555
    dec   ecx
556
    jnz   adw_set_empty_directory
556
    jnz   adw_set_empty_directory
557
 
557
 
558
    pop   eax
558
    pop   eax
559
 
559
 
560
  adw_found:
560
  adw_found:
561
    pop   edi edx ecx
561
    pop   edi edx ecx
562
    clc                         ; free space found
562
    clc                         ; free space found
563
    ret
563
    ret
564
  adw_not_found_1:
564
  adw_not_found_1:
565
    add  esp,4
565
    add  esp,4
566
  adw_not_found:
566
  adw_not_found:
567
    pop   edi edx ecx
567
    pop   edi edx ecx
568
    stc                         ; free space not found
568
    stc                         ; free space not found
569
    ret
569
    ret
570
 
570
 
571
 
571
 
572
get_data_cluster:
572
get_data_cluster:
573
;-----------------------------------------------------------
573
;-----------------------------------------------------------
574
; input  : EAX = cluster
574
; input  : EAX = cluster
575
;          EBX = pointer to buffer
575
;          EBX = pointer to buffer
576
;          EDX = # blocks to read in buffer
576
;          EDX = # blocks to read in buffer
577
;          ESI = # blocks to skip over
577
;          ESI = # blocks to skip over
578
; output : if CARRY=0 ok EBX/EDX/ESI updated
578
; output : if CARRY=0 ok EBX/EDX/ESI updated
579
;          if CARRY=1 cluster out of range
579
;          if CARRY=1 cluster out of range
580
; Note   : if cluster=0 it's changed to read rootdir
580
; Note   : if cluster=0 it's changed to read rootdir
581
;-----------------------------------------------------------
581
;-----------------------------------------------------------
582
    push  eax ecx
582
    push  eax ecx
583
 
583
 
584
    mov   [fat16_root],0
584
    mov   [fat16_root],0
585
    cmp   eax,[LAST_CLUSTER]
585
    cmp   eax,[LAST_CLUSTER]
586
    ja    gdc_error             ; too big cluster number, something is wrong
586
    ja    gdc_error             ; too big cluster number, something is wrong
587
    cmp   eax,2
587
    cmp   eax,2
588
    jnb   gdc_cluster
588
    jnb   gdc_cluster
589
 
589
 
590
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
590
    mov   eax,[ROOT_CLUSTER]    ; if cluster < 2 then read rootdir
591
    cmp   [fat_type],16
591
    cmp   [fat_type],16
592
    jne   gdc_cluster
592
    jne   gdc_cluster
593
    mov   eax,[ROOT_START]
593
    mov   eax,[ROOT_START]
594
    mov   ecx,[ROOT_SECTORS]    ; Note: not cluster size
594
    mov   ecx,[ROOT_SECTORS]    ; Note: not cluster size
595
    mov   [fat16_root],1        ; flag for fat16 rootdir
595
    mov   [fat16_root],1        ; flag for fat16 rootdir
596
    jmp   gdc_read
596
    jmp   gdc_read
597
 
597
 
598
  gdc_cluster:
598
  gdc_cluster:
599
    sub   eax,2
599
    sub   eax,2
600
    mov   ecx,[SECTORS_PER_CLUSTER]
600
    mov   ecx,[SECTORS_PER_CLUSTER]
601
    imul  eax,ecx
601
    imul  eax,ecx
602
    add   eax,[DATA_START]
602
    add   eax,[DATA_START]
603
 
603
 
604
  gdc_read:
604
  gdc_read:
605
    test  esi,esi               ; first wanted block
605
    test  esi,esi               ; first wanted block
606
    je    gdcl1                 ; yes, skip count is 0
606
    je    gdcl1                 ; yes, skip count is 0
607
    dec   esi
607
    dec   esi
608
    jmp   gdcl2
608
    jmp   gdcl2
609
 
609
 
610
  gdcl1:
610
  gdcl1:
611
    call  hd_read
611
    call  hd_read
612
    cmp  [hd_error],0
612
    cmp  [hd_error],0
613
    jne  gdc_error    
613
    jne  gdc_error    
614
 
614
 
615
    add   ebx,512               ; update pointer
615
    add   ebx,512               ; update pointer
616
    dec   edx
616
    dec   edx
617
 
617
 
618
  gdcl2:
618
  gdcl2:
619
    test  edx,edx               ; is all read?
619
    test  edx,edx               ; is all read?
620
    je    out_of_read
620
    je    out_of_read
621
 
621
 
622
    inc   eax                   ; next sector
622
    inc   eax                   ; next sector
623
    dec   ecx
623
    dec   ecx
624
    jnz   gdc_read
624
    jnz   gdc_read
625
 
625
 
626
  out_of_read:
626
  out_of_read:
627
    pop   ecx eax
627
    pop   ecx eax
628
    clc
628
    clc
629
    ret
629
    ret
630
 
630
 
631
  gdc_error:
631
  gdc_error:
632
    pop   ecx eax
632
    pop   ecx eax
633
    stc
633
    stc
634
    ret
634
    ret
635
 
635
 
636
 
636
 
637
set_data_cluster:
637
set_data_cluster:
638
;-----------------------------------------------------------
638
;-----------------------------------------------------------
639
; input  : EAX = cluster
639
; input  : EAX = cluster
640
;          EBX = pointer to buffer
640
;          EBX = pointer to buffer
641
; output : if CARRY=0 ok
641
; output : if CARRY=0 ok
642
;          if CARRY=1 cluster out of range
642
;          if CARRY=1 cluster out of range
643
;-----------------------------------------------------------
643
;-----------------------------------------------------------
644
    push  eax ebx edx
644
    push  eax ebx edx
645
 
645
 
646
    cmp   eax,[LAST_CLUSTER]
646
    cmp   eax,[LAST_CLUSTER]
647
    ja    sdc_error             ; too big cluster number, something is wrong
647
    ja    sdc_error             ; too big cluster number, something is wrong
648
    sub   eax,2
648
    sub   eax,2
649
    jb    sdc_error             ; don't allow rootdir write
649
    jb    sdc_error             ; don't allow rootdir write
650
 
650
 
651
    mov   edx,[SECTORS_PER_CLUSTER]
651
    mov   edx,[SECTORS_PER_CLUSTER]
652
    imul  eax,edx
652
    imul  eax,edx
653
    add   eax,[DATA_START]
653
    add   eax,[DATA_START]
654
 
654
 
655
  sdc_write:
655
  sdc_write:
656
    call  hd_write
656
    call  hd_write
657
    cmp   [hd_error],0
657
    cmp   [hd_error],0
658
    jne   sdc_error
658
    jne   sdc_error
659
 
659
 
660
    add   ebx,512               ; update pointer
660
    add   ebx,512               ; update pointer
661
    inc   eax
661
    inc   eax
662
    dec   edx
662
    dec   edx
663
    jnz   sdc_write
663
    jnz   sdc_write
664
    pop   edx ebx eax
664
    pop   edx ebx eax
665
    clc
665
    clc
666
    ret
666
    ret
667
 
667
 
668
  sdc_error:
668
  sdc_error:
669
    pop   edx ebx eax
669
    pop   edx ebx eax
670
    stc
670
    stc
671
    ret
671
    ret
672
 
672
 
673
 
673
 
674
get_cluster_of_a_path:
674
get_cluster_of_a_path:
675
;---------------------------------------------------------
675
;---------------------------------------------------------
676
; input  : EBX = pointer to a path string
676
; input  : EBX = pointer to a path string
677
;          (example: the path "/files/data/document" become
677
;          (example: the path "/files/data/document" become
678
;                             "files......data.......document...0"
678
;                             "files......data.......document...0"
679
;          '.' = space char
679
;          '.' = space char
680
;          '0' = char(0) (ASCII=0) !!! )
680
;          '0' = char(0) (ASCII=0) !!! )
681
; output : if (CARRY=1) -> ERROR in the PATH
681
; output : if (CARRY=1) -> ERROR in the PATH
682
;          if (CARRY=0) -> EAX=cluster
682
;          if (CARRY=0) -> EAX=cluster
683
;---------------------------------------------------------
683
;---------------------------------------------------------
684
    push  ebx edx
684
    push  ebx edx
685
 
685
 
686
    mov   eax,[ROOT_CLUSTER]
686
    mov   eax,[ROOT_CLUSTER]
687
    mov   edx,ebx
687
    mov   edx,ebx
688
 
688
 
689
search_end_of_path:
689
search_end_of_path:
690
    cmp   byte [edx],0
690
    cmp   byte [edx],0
691
    je    found_end_of_path
691
    je    found_end_of_path
692
 
692
 
693
    inc   edx ; '/'
693
    inc   edx ; '/'
694
    mov   ebx,edx
694
    mov   ebx,edx
695
    call  analyze_directory
695
    call  analyze_directory
696
    jc    directory_not_found
696
    jc    directory_not_found
697
 
697
 
698
    mov   eax,[ebx+20-2]        ; read the HIGH 16bit cluster field
698
    mov   eax,[ebx+20-2]        ; read the HIGH 16bit cluster field
699
    mov   ax,[ebx+26]           ; read the LOW 16bit cluster field
699
    mov   ax,[ebx+26]           ; read the LOW 16bit cluster field
700
    and   eax,[fatMASK]
700
    and   eax,[fatMASK]
701
    add   edx,11                ; 8+3 (name+extension)
701
    add   edx,11                ; 8+3 (name+extension)
702
    jmp   search_end_of_path
702
    jmp   search_end_of_path
703
 
703
 
704
found_end_of_path:
704
found_end_of_path:
705
    pop   edx ebx
705
    pop   edx ebx
706
    clc                         ; no errors
706
    clc                         ; no errors
707
    ret
707
    ret
708
 
708
 
709
directory_not_found:
709
directory_not_found:
710
    pop   edx ebx
710
    pop   edx ebx
711
    stc                         ; errors occour
711
    stc                         ; errors occour
712
    ret
712
    ret
713
 
713
 
714
 
714
 
715
bcd2bin:
715
bcd2bin:
716
;----------------------------------
716
;----------------------------------
717
; input  : AL=BCD number (eg. 0x11)
717
; input  : AL=BCD number (eg. 0x11)
718
; output : AH=0
718
; output : AH=0
719
;          AL=decimal number (eg. 11)
719
;          AL=decimal number (eg. 11)
720
;----------------------------------
720
;----------------------------------
721
    xor   ah,ah
721
    xor   ah,ah
722
    shl   ax,4
722
    shl   ax,4
723
    shr   al,4
723
    shr   al,4
724
    aad
724
    aad
725
    ret
725
    ret
726
 
726
 
727
 
727
 
728
get_date_for_file:
728
get_date_for_file:
729
;-----------------------------------------------------
729
;-----------------------------------------------------
730
; Get date from CMOS and pack day,month,year in AX
730
; Get date from CMOS and pack day,month,year in AX
731
; DATE   bits  0..4   : day of month 0..31
731
; DATE   bits  0..4   : day of month 0..31
732
;              5..8   : month of year 1..12
732
;              5..8   : month of year 1..12
733
;              9..15  : count of years from 1980
733
;              9..15  : count of years from 1980
734
;-----------------------------------------------------
734
;-----------------------------------------------------
735
    mov   al,0x7        ;day
735
    mov   al,0x7        ;day
736
    out   0x70,al
736
    out   0x70,al
737
    in    al,0x71
737
    in    al,0x71
738
    call  bcd2bin
738
    call  bcd2bin
739
    ror   eax,5
739
    ror   eax,5
740
 
740
 
741
    mov   al,0x8        ;month
741
    mov   al,0x8        ;month
742
    out   0x70,al
742
    out   0x70,al
743
    in    al,0x71
743
    in    al,0x71
744
    call  bcd2bin
744
    call  bcd2bin
745
    ror   eax,4
745
    ror   eax,4
746
 
746
 
747
    mov   al,0x9        ;year
747
    mov   al,0x9        ;year
748
    out   0x70,al
748
    out   0x70,al
749
    in    al,0x71
749
    in    al,0x71
750
    call  bcd2bin
750
    call  bcd2bin
751
    add   ax,20         ;because CMOS return only the two last
751
    add   ax,20         ;because CMOS return only the two last
752
                        ;digit (eg. 2000 -> 00 , 2001 -> 01) and we
752
                        ;digit (eg. 2000 -> 00 , 2001 -> 01) and we
753
    rol   eax,9         ;need the difference with 1980 (eg. 2001-1980)
753
    rol   eax,9         ;need the difference with 1980 (eg. 2001-1980)
754
    ret
754
    ret
755
 
755
 
756
 
756
 
757
get_time_for_file:
757
get_time_for_file:
758
;-----------------------------------------------------
758
;-----------------------------------------------------
759
; Get time from CMOS and pack hour,minute,second in AX
759
; Get time from CMOS and pack hour,minute,second in AX
760
; TIME   bits  0..4   : second (the low bit is lost)
760
; TIME   bits  0..4   : second (the low bit is lost)
761
;              5..10  : minute 0..59
761
;              5..10  : minute 0..59
762
;              11..15 : hour 0..23
762
;              11..15 : hour 0..23
763
;-----------------------------------------------------
763
;-----------------------------------------------------
764
    mov   al,0x0        ;second
764
    mov   al,0x0        ;second
765
    out   0x70,al
765
    out   0x70,al
766
    in    al,0x71
766
    in    al,0x71
767
    call  bcd2bin
767
    call  bcd2bin
768
    ror   eax,6
768
    ror   eax,6
769
 
769
 
770
    mov   al,0x2        ;minute
770
    mov   al,0x2        ;minute
771
    out   0x70,al
771
    out   0x70,al
772
    in    al,0x71
772
    in    al,0x71
773
    call  bcd2bin
773
    call  bcd2bin
774
    ror   eax,6
774
    ror   eax,6
775
 
775
 
776
    mov   al,0x4        ;hour
776
    mov   al,0x4        ;hour
777
    out   0x70,al
777
    out   0x70,al
778
    in    al,0x71
778
    in    al,0x71
779
    call  bcd2bin
779
    call  bcd2bin
780
    rol   eax,11
780
    rol   eax,11
781
    ret
781
    ret
782
 
782
 
783
 
783
 
784
set_current_time_for_entry:
784
set_current_time_for_entry:
785
;-----------------------------------------------------
785
;-----------------------------------------------------
786
; Set current time/date for file entry
786
; Set current time/date for file entry
787
; input  : ebx = file entry pointer
787
; input  : ebx = file entry pointer
788
;-----------------------------------------------------
788
;-----------------------------------------------------
789
    push  eax
789
    push  eax
790
    call  get_time_for_file     ; update files date/time
790
    call  get_time_for_file     ; update files date/time
791
    mov   [ebx+22],ax
791
    mov   [ebx+22],ax
792
    call  get_date_for_file
792
    call  get_date_for_file
793
    mov   [ebx+24],ax
793
    mov   [ebx+24],ax
794
    pop   eax
794
    pop   eax
795
    ret
795
    ret
796
 
796
 
797
 
797
 
798
makedir:
798
makedir:
799
;-----------------------------------------------------
799
;-----------------------------------------------------
800
; input  : eax = directory name
800
; input  : eax = directory name
801
;          edx = path
801
;          edx = path
802
; output : eax = 0 - ok
802
; output : eax = 0 - ok
803
;                3 - unknown FS
803
;                3 - unknown FS
804
;                5 - file not found
804
;                5 - file not found
805
;                8 - disk full
805
;                8 - disk full
806
;               10 - access denied
806
;               10 - access denied
807
; Note   : can only make one directory at time
807
; Note   : can only make one directory at time
808
;-----------------------------------------------------
808
;-----------------------------------------------------
809
    cmp   [fat_type],0
809
    cmp   [fat_type],0
810
    jnz   make_dir_fat_ok
810
    jnz   make_dir_fat_ok
811
    mov   eax,ERROR_UNKNOWN_FS
811
    mov   eax,ERROR_UNKNOWN_FS
812
    ret
812
    ret
813
 
813
 
814
  make_dir_fat_ok:
814
  make_dir_fat_ok:
815
;    call  reserve_hd1
815
;    call  reserve_hd1
816
 
816
 
817
    pushad
817
    pushad
818
 
818
 
819
    mov   ebx,edx
819
    mov   ebx,edx
820
    call  get_cluster_of_a_path
820
    call  get_cluster_of_a_path
821
    jnc   make_dir_found_path
821
    jnc   make_dir_found_path
822
    cmp   [hd_error],0
822
    cmp   [hd_error],0
823
    jne   make_dir_error_1
823
    jne   make_dir_error_1
824
 
824
 
825
  make_dir_path_not_found:
825
  make_dir_path_not_found:
826
    popad
826
    popad
827
    call  update_disk           ; write all of cache and fat to hd
827
    call  update_disk           ; write all of cache and fat to hd
828
    cmp   [hd_error],0
828
    cmp   [hd_error],0
829
    jne   make_dir_error_2
829
    jne   make_dir_error_2
830
 
830
 
831
    mov   [hd1_status],0
831
    mov   [hd1_status],0
832
    mov   eax,ERROR_FILE_NOT_FOUND
832
    mov   eax,ERROR_FILE_NOT_FOUND
833
    ret
833
    ret
834
 
834
 
835
  make_dir_disk_full:
835
  make_dir_disk_full:
836
    cmp  [hd_error],0
836
    cmp  [hd_error],0
837
    jne   make_dir_error_1
837
    jne   make_dir_error_1
838
    popad
838
    popad
839
    call  update_disk           ; write all of cache and fat to hd
839
    call  update_disk           ; write all of cache and fat to hd
840
    cmp   [hd_error],0
840
    cmp   [hd_error],0
841
    jne   make_dir_error_2
841
    jne   make_dir_error_2
842
 
842
 
843
    mov   [hd1_status],0
843
    mov   [hd1_status],0
844
    mov   eax,ERROR_DISK_FULL
844
    mov   eax,ERROR_DISK_FULL
845
    ret
845
    ret
846
 
846
 
847
  make_dir_already_exist:
847
  make_dir_already_exist:
848
    cmp  [hd_error],0
848
    cmp  [hd_error],0
849
    jne   make_dir_error_1    
849
    jne   make_dir_error_1    
850
    mov   eax,[cluster]         ; directory cluster
850
    mov   eax,[cluster]         ; directory cluster
851
    xor   edx,edx               ; free
851
    xor   edx,edx               ; free
852
    mov   [f_del],1
852
    mov   [f_del],1
853
    call  set_FAT
853
    call  set_FAT
854
    cmp  [hd_error],0
854
    cmp  [hd_error],0
855
    jne   make_dir_error_1
855
    jne   make_dir_error_1
856
 
856
 
857
    mov   [f_del],0
857
    mov   [f_del],0
858
 
858
 
859
    popad
859
    popad
860
    call  update_disk           ; write all of cache and fat to hd
860
    call  update_disk           ; write all of cache and fat to hd
861
  make_dir_error_2:
861
  make_dir_error_2:
862
    mov   [hd1_status],0
862
    mov   [hd1_status],0
863
    mov   eax,ERROR_ACCESS_DENIED
863
    mov   eax,ERROR_ACCESS_DENIED
864
    ret
864
    ret
865
 
865
 
866
  make_dir_error_1:
866
  make_dir_error_1:
867
    popad
867
    popad
868
    jmp   make_dir_error_2
868
    jmp   make_dir_error_2
869
 
869
 
870
  make_dir_error_3:
870
  make_dir_error_3:
871
    add  esp,4
871
    add  esp,4
872
    jmp   make_dir_error_1
872
    jmp   make_dir_error_1
873
 
873
 
874
  make_dir_found_path:
874
  make_dir_found_path:
875
    cmp   eax,[ROOT_CLUSTER]
875
    cmp   eax,[ROOT_CLUSTER]
876
    jnz   make_dir_not_root
876
    jnz   make_dir_not_root
877
    xor   eax,eax
877
    xor   eax,eax
878
 
878
 
879
  make_dir_not_root:
879
  make_dir_not_root:
880
    mov   ecx,eax               ; directorys start cluster
880
    mov   ecx,eax               ; directorys start cluster
881
    mov   word [NewDirEntry2+26],cx ; 16 bits low of cluster
881
    mov   word [NewDirEntry2+26],cx ; 16 bits low of cluster
882
    shr   ecx,16
882
    shr   ecx,16
883
    mov   word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16)
883
    mov   word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16)
884
 
884
 
885
    push  eax                   ; save parent directory cluster
885
    push  eax                   ; save parent directory cluster
886
    mov   eax,2
886
    mov   eax,2
887
    call  get_free_FAT
887
    call  get_free_FAT
888
    mov   [cluster],eax         ; first free cluster
888
    mov   [cluster],eax         ; first free cluster
889
    pop   eax
889
    pop   eax
890
    jc    make_dir_disk_full
890
    jc    make_dir_disk_full
891
 
891
 
892
    push  eax
892
    push  eax
893
    mov   eax,[cluster]         ; directory cluster
893
    mov   eax,[cluster]         ; directory cluster
894
    mov   edx,[fatEND]          ; end for directory
894
    mov   edx,[fatEND]          ; end for directory
895
    call  set_FAT
895
    call  set_FAT
896
    cmp  [hd_error],0
896
    cmp  [hd_error],0
897
    jne   make_dir_error_3
897
    jne   make_dir_error_3
898
    pop   eax
898
    pop   eax
899
 
899
 
900
    mov   ebx,PUSHAD_EAX        ; dir name
900
    mov   ebx,PUSHAD_EAX        ; dir name
901
    push  eax
901
    push  eax
902
    call  analyze_directory     ; check if directory already exist
902
    call  analyze_directory     ; check if directory already exist
903
    cmp   [hd_error],0
903
    cmp   [hd_error],0
904
    jne   make_dir_error_1
904
    jne   make_dir_error_1
905
 
905
 
906
    pop   eax
906
    pop   eax
907
    jnc   make_dir_already_exist ; need to free allocated cluster!
907
    jnc   make_dir_already_exist ; need to free allocated cluster!
908
 
908
 
909
    call  analyze_directory_to_write
909
    call  analyze_directory_to_write
910
    jc    make_dir_already_exist ; need to free allocated cluster!
910
    jc    make_dir_already_exist ; need to free allocated cluster!
911
 
911
 
912
    mov   esi,PUSHAD_EAX        ; dir name
912
    mov   esi,PUSHAD_EAX        ; dir name
913
    mov   edi,ebx               ; pointer in buffer
913
    mov   edi,ebx               ; pointer in buffer
914
    mov   ecx,11
914
    mov   ecx,11
915
    cld
915
    cld
916
    rep   movsb
916
    rep   movsb
917
 
917
 
918
    mov   dword [ebx+28],0      ; dir size is always 0
918
    mov   dword [ebx+28],0      ; dir size is always 0
919
    mov   ecx,[cluster]
919
    mov   ecx,[cluster]
920
    mov   [ebx+26],cx           ; 16 bits low of cluster
920
    mov   [ebx+26],cx           ; 16 bits low of cluster
921
    mov   word [NewDirEntry1+26],cx
921
    mov   word [NewDirEntry1+26],cx
922
    shr   ecx,16
922
    shr   ecx,16
923
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
923
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
924
    mov   word [NewDirEntry1+20],cx
924
    mov   word [NewDirEntry1+20],cx
925
    mov   byte [ebx+11],0x10    ; attribute = directory
925
    mov   byte [ebx+11],0x10    ; attribute = directory
926
 
926
 
927
    call  set_current_time_for_entry
927
    call  set_current_time_for_entry
928
    mov   ecx,[ebx+22]
928
    mov   ecx,[ebx+22]
929
    mov   dword [NewDirEntry1+22],ecx
929
    mov   dword [NewDirEntry1+22],ecx
930
    mov   dword [NewDirEntry2+22],ecx
930
    mov   dword [NewDirEntry2+22],ecx
931
 
931
 
932
    mov   ebx,buffer            ; save the directory name,length,cluster
932
    mov   ebx,buffer            ; save the directory name,length,cluster
933
    call  hd_write
933
    call  hd_write
934
    cmp   [hd_error],0
934
    cmp   [hd_error],0
935
    jne   make_dir_error_1
935
    jne   make_dir_error_1
936
 
936
 
937
    mov   ecx,512/4
937
    mov   ecx,512/4
938
    xor   eax,eax
938
    xor   eax,eax
939
    mov   edi,buffer
939
    mov   edi,buffer
940
    cld
940
    cld
941
    rep   stosd                 ; clear new directory cluster
941
    rep   stosd                 ; clear new directory cluster
942
 
942
 
943
    mov   eax,[cluster]         ; new directory cluster
943
    mov   eax,[cluster]         ; new directory cluster
944
    sub   eax,2
944
    sub   eax,2
945
    mov   edx,[SECTORS_PER_CLUSTER]
945
    mov   edx,[SECTORS_PER_CLUSTER]
946
    imul  eax,edx
946
    imul  eax,edx
947
    add   eax,[DATA_START]
947
    add   eax,[DATA_START]
948
    mov   ebx,buffer
948
    mov   ebx,buffer
949
    add   eax,edx               ; start from last sector
949
    add   eax,edx               ; start from last sector
950
 
950
 
951
  dir_set_empty_directory:
951
  dir_set_empty_directory:
952
    dec   eax                   ; next sector
952
    dec   eax                   ; next sector
953
    cmp   edx,1                 ; is first directory sector?
953
    cmp   edx,1                 ; is first directory sector?
954
    jnz   not_first_sector      ; no. write empty sector
954
    jnz   not_first_sector      ; no. write empty sector
955
    mov   esi,NewDirEntry1
955
    mov   esi,NewDirEntry1
956
    mov   edi,buffer
956
    mov   edi,buffer
957
    mov   ecx,64/4
957
    mov   ecx,64/4
958
    cld
958
    cld
959
    rep   movsd                 ; copy 2 first directory entrys "." and ".."
959
    rep   movsd                 ; copy 2 first directory entrys "." and ".."
960
 
960
 
961
  not_first_sector:
961
  not_first_sector:
962
    call  hd_write
962
    call  hd_write
963
    cmp   [hd_error],0
963
    cmp   [hd_error],0
964
    jne   make_dir_error_1
964
    jne   make_dir_error_1
965
  
965
  
966
    dec   edx
966
    dec   edx
967
    jnz   dir_set_empty_directory
967
    jnz   dir_set_empty_directory
968
 
968
 
969
    mov   ecx,-1                ; remove 1 cluster from free disk space
969
    mov   ecx,-1                ; remove 1 cluster from free disk space
970
    call  add_disk_free_space
970
    call  add_disk_free_space
971
    cmp  [hd_error],0
971
    cmp  [hd_error],0
972
    jne   make_dir_error_1
972
    jne   make_dir_error_1
973
 
973
 
974
    popad
974
    popad
975
    call  update_disk           ; write all of cache and fat to hd
975
    call  update_disk           ; write all of cache and fat to hd
976
    cmp   [hd_error],0
976
    cmp   [hd_error],0
977
    jne   make_dir_error_2
977
    jne   make_dir_error_2
978
    mov   [hd1_status],0
978
    mov   [hd1_status],0
979
    xor   eax,eax
979
    xor   eax,eax
980
    ret
980
    ret
981
 
981
 
982
 
982
 
983
removedir:
983
removedir:
984
;-----------------------------------------------------
984
;-----------------------------------------------------
985
; input  : eax = file/directory name
985
; input  : eax = file/directory name
986
;          edx = path
986
;          edx = path
987
; output : eax = 0 - ok
987
; output : eax = 0 - ok
988
;                3 - unknown FS
988
;                3 - unknown FS
989
;                5 - file not found
989
;                5 - file not found
990
;               10 - access denied
990
;               10 - access denied
991
;-----------------------------------------------------
991
;-----------------------------------------------------
992
    cmp   [fat_type],0
992
    cmp   [fat_type],0
993
    jnz   remove_dir_fat_ok
993
    jnz   remove_dir_fat_ok
994
    mov   eax,ERROR_UNKNOWN_FS
994
    mov   eax,ERROR_UNKNOWN_FS
995
    ret
995
    ret
996
 
996
 
997
  remove_dir_fat_ok:
997
  remove_dir_fat_ok:
998
;    call  reserve_hd1
998
;    call  reserve_hd1
999
 
999
 
1000
    push  edi
1000
    push  edi
1001
    mov   edi,1                 ; allow directory remove
1001
    mov   edi,1                 ; allow directory remove
1002
    call  file_delete
1002
    call  file_delete
1003
    cmp   [hd_error],0
1003
    cmp   [hd_error],0
1004
    jne   @f
1004
    jne   @f
1005
 
1005
 
1006
    pop   edi
1006
    pop   edi
1007
 
1007
 
1008
    call  update_disk           ; write all of cache and fat to hd
1008
    call  update_disk           ; write all of cache and fat to hd
1009
  @@:
1009
  @@:
1010
    mov   [hd1_status],0
1010
    mov   [hd1_status],0
1011
    ret
1011
    ret
1012
   
1012
   
1013
 
1013
 
1014
add_disk_free_space:
1014
add_disk_free_space:
1015
;-----------------------------------------------------
1015
;-----------------------------------------------------
1016
; input  : ecx = cluster count
1016
; input  : ecx = cluster count
1017
; Note   : negative = remove clusters from free space
1017
; Note   : negative = remove clusters from free space
1018
;          positive = add clusters to free space
1018
;          positive = add clusters to free space
1019
;-----------------------------------------------------
1019
;-----------------------------------------------------
1020
    test  ecx,ecx               ; no change
1020
    test  ecx,ecx               ; no change
1021
    je    add_dfs_no
1021
    je    add_dfs_no
1022
    cmp   [fat_type],32         ; free disk space only used by fat32
1022
    cmp   [fat_type],32         ; free disk space only used by fat32
1023
    jne   add_dfs_no
1023
    jne   add_dfs_no
1024
 
1024
 
1025
    push  eax ebx
1025
    push  eax ebx
1026
    mov   eax,[ADR_FSINFO]
1026
    mov   eax,[ADR_FSINFO]
1027
    mov   ebx,buffer
1027
    mov   ebx,buffer
1028
    call  hd_read
1028
    call  hd_read
1029
    cmp  [hd_error],0
1029
    cmp  [hd_error],0
1030
    jne  add_not_fs
1030
    jne  add_not_fs
1031
 
1031
 
1032
    cmp   dword [ebx+0x1fc],0xaa550000 ; check sector id
1032
    cmp   dword [ebx+0x1fc],0xaa550000 ; check sector id
1033
    jne   add_not_fs
1033
    jne   add_not_fs
1034
 
1034
 
1035
    add   [ebx+0x1e8],ecx
1035
    add   [ebx+0x1e8],ecx
1036
    call  hd_write
1036
    call  hd_write
1037
    cmp   [hd_error],0
1037
    cmp   [hd_error],0
1038
    jne   add_not_fs
1038
    jne   add_not_fs
1039
 
1039
 
1040
  add_not_fs:
1040
  add_not_fs:
1041
    pop   ebx eax
1041
    pop   ebx eax
1042
 
1042
 
1043
  add_dfs_no:
1043
  add_dfs_no:
1044
    ret
1044
    ret
1045
 
1045
 
1046
 
1046
 
1047
file_append:
1047
file_append:
1048
;-----------------------------------------------------
1048
;-----------------------------------------------------
1049
; input  : eax = file name
1049
; input  : eax = file name
1050
;          edx = path
1050
;          edx = path
1051
;          ecx = pointer to buffer
1051
;          ecx = pointer to buffer
1052
;          ebx = bytes to write (0 = truncate file)
1052
;          ebx = bytes to write (0 = truncate file)
1053
;          esi = start position (-1 = end of file)
1053
;          esi = start position (-1 = end of file)
1054
; output : eax = 0 - ok
1054
; output : eax = 0 - ok
1055
;                3 - unknown FS
1055
;                3 - unknown FS
1056
;                5 - file not found
1056
;                5 - file not found
1057
;                6 - end of file
1057
;                6 - end of file
1058
;                8 - disk full
1058
;                8 - disk full
1059
;                9 - fat table corrupted
1059
;                9 - fat table corrupted
1060
;               10 - access denied
1060
;               10 - access denied
1061
;          ebx = bytes written
1061
;          ebx = bytes written
1062
;-----------------------------------------------------
1062
;-----------------------------------------------------
1063
    cmp   [fat_type],0
1063
    cmp   [fat_type],0
1064
    jnz   append_fat_ok
1064
    jnz   append_fat_ok
1065
    mov   eax,ERROR_UNKNOWN_FS
1065
    mov   eax,ERROR_UNKNOWN_FS
1066
    ret
1066
    ret
1067
 
1067
 
1068
  append_fat_ok:
1068
  append_fat_ok:
1069
;    call  reserve_hd1
1069
;    call  reserve_hd1
1070
 
1070
 
1071
    pushad
1071
    pushad
1072
 
1072
 
1073
    mov   ebx,edx
1073
    mov   ebx,edx
1074
    call  get_cluster_of_a_path
1074
    call  get_cluster_of_a_path
1075
    jc    append_not_found
1075
    jc    append_not_found
1076
 
1076
 
1077
    mov   ebx,PUSHAD_EAX        ; file name
1077
    mov   ebx,PUSHAD_EAX        ; file name
1078
    call  analyze_directory
1078
    call  analyze_directory
1079
    jc    append_not_found
1079
    jc    append_not_found
1080
 
1080
 
1081
    mov   [sector_tmp],eax
1081
    mov   [sector_tmp],eax
1082
    mov   [entry_pos],ebx
1082
    mov   [entry_pos],ebx
1083
 
1083
 
1084
    test  byte [ebx+11],0x10    ; is it directory?
1084
    test  byte [ebx+11],0x10    ; is it directory?
1085
    jnz   append_access         ; yes
1085
    jnz   append_access         ; yes
1086
 
1086
 
1087
    mov   ecx,[ebx+28]          ; file size
1087
    mov   ecx,[ebx+28]          ; file size
1088
    mov   edi,PUSHAD_ESI        ; write position
1088
    mov   edi,PUSHAD_ESI        ; write position
1089
    cmp   edi,-1                ; -1 = eof
1089
    cmp   edi,-1                ; -1 = eof
1090
    jnz   append_inside_file
1090
    jnz   append_inside_file
1091
    mov   edi,ecx               ; file size
1091
    mov   edi,ecx               ; file size
1092
 
1092
 
1093
  append_inside_file:
1093
  append_inside_file:
1094
    cmp   edi,ecx               ; start above old file size?
1094
    cmp   edi,ecx               ; start above old file size?
1095
    ja    append_eof            ; yes
1095
    ja    append_eof            ; yes
1096
 
1096
 
1097
    mov   [old_filesize],ecx
1097
    mov   [old_filesize],ecx
1098
    mov   [new_filepos],edi
1098
    mov   [new_filepos],edi
1099
 
1099
 
1100
    mov   ecx,PUSHAD_EBX        ; bytes to write
1100
    mov   ecx,PUSHAD_EBX        ; bytes to write
1101
    test  ecx,ecx               ; truncate?
1101
    test  ecx,ecx               ; truncate?
1102
    jz    append_truncate       ; yes
1102
    jz    append_truncate       ; yes
1103
 
1103
 
1104
    mov   [bytes2write],ecx     ; bytes to write
1104
    mov   [bytes2write],ecx     ; bytes to write
1105
    mov   esi,PUSHAD_ECX        ; pointer to buffer
1105
    mov   esi,PUSHAD_ECX        ; pointer to buffer
1106
    mov   eax,[ebx+20-2]        ; FAT entry
1106
    mov   eax,[ebx+20-2]        ; FAT entry
1107
    mov   ax,[ebx+26]
1107
    mov   ax,[ebx+26]
1108
    and   eax,[fatMASK]
1108
    and   eax,[fatMASK]
1109
    jnz   append_find_pos       ; first cluster <> 0
1109
    jnz   append_find_pos       ; first cluster <> 0
1110
 
1110
 
1111
    mov   eax,2
1111
    mov   eax,2
1112
    call  get_free_FAT
1112
    call  get_free_FAT
1113
    jc    append_disk_full
1113
    jc    append_disk_full
1114
    mov   ecx,eax               ; set files first cluster
1114
    mov   ecx,eax               ; set files first cluster
1115
    mov   [ebx+26],cx           ; 16 bits low of cluster
1115
    mov   [ebx+26],cx           ; 16 bits low of cluster
1116
    shr   ecx,16
1116
    shr   ecx,16
1117
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
1117
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
1118
    mov   edx,[fatEND]          ; new end for cluster chain
1118
    mov   edx,[fatEND]          ; new end for cluster chain
1119
    call  set_FAT
1119
    call  set_FAT
1120
    cmp  [hd_error],0
1120
    cmp  [hd_error],0
1121
    jne   append_access
1121
    jne   append_access
1122
 
1122
 
1123
    push  eax                   ; save first cluster
1123
    push  eax                   ; save first cluster
1124
    mov   eax,[sector_tmp]
1124
    mov   eax,[sector_tmp]
1125
    mov   ebx,buffer
1125
    mov   ebx,buffer
1126
    call  hd_write              ; write new file entry back to disk
1126
    call  hd_write              ; write new file entry back to disk
1127
    cmp   [hd_error],0
1127
    cmp   [hd_error],0
1128
    jne   append_access_1
1128
    jne   append_access_1
1129
 
1129
 
1130
    pop   eax
1130
    pop   eax
1131
 
1131
 
1132
  append_remove_free:
1132
  append_remove_free:
1133
    mov   ecx,-1                ; remove 1 cluster from free disk space
1133
    mov   ecx,-1                ; remove 1 cluster from free disk space
1134
    call  add_disk_free_space   ; Note: uses buffer
1134
    call  add_disk_free_space   ; Note: uses buffer
1135
    cmp  [hd_error],0
1135
    cmp  [hd_error],0
1136
    jne   append_access
1136
    jne   append_access
1137
 
1137
 
1138
  append_found_cluster:
1138
  append_found_cluster:
1139
    mov   [cluster],eax
1139
    mov   [cluster],eax
1140
    sub   eax,2
1140
    sub   eax,2
1141
    mov   ecx,[SECTORS_PER_CLUSTER]
1141
    mov   ecx,[SECTORS_PER_CLUSTER]
1142
    imul  eax,ecx
1142
    imul  eax,ecx
1143
    add   eax,[DATA_START]
1143
    add   eax,[DATA_START]
1144
    xor   edi,edi
1144
    xor   edi,edi
1145
 
1145
 
1146
  append_new_sector:
1146
  append_new_sector:
1147
    cmp   [hd_error],0
1147
    cmp   [hd_error],0
1148
    jne   append_access    
1148
    jne   append_access    
1149
    push  ecx
1149
    push  ecx
1150
    mov   ecx,[bytes2write]     ; bytes left in buffer
1150
    mov   ecx,[bytes2write]     ; bytes left in buffer
1151
    mov   ebx,512
1151
    mov   ebx,512
1152
    sub   ebx,edi               ; bytes left in sector
1152
    sub   ebx,edi               ; bytes left in sector
1153
    cmp   ecx,ebx
1153
    cmp   ecx,ebx
1154
    jb    append_bytes_ok
1154
    jb    append_bytes_ok
1155
    mov   ecx,ebx
1155
    mov   ecx,ebx
1156
 
1156
 
1157
  append_bytes_ok:
1157
  append_bytes_ok:
1158
    cmp   ecx,512               ; overwrite full sector?
1158
    cmp   ecx,512               ; overwrite full sector?
1159
    jz    append_full_sector    ; yes
1159
    jz    append_full_sector    ; yes
1160
    mov   ebx,buffer            ; overwrite part of sector
1160
    mov   ebx,buffer            ; overwrite part of sector
1161
    call  hd_read               ; read old sector
1161
    call  hd_read               ; read old sector
1162
    cmp  [hd_error],0
1162
    cmp  [hd_error],0
1163
    jne  append_access_1
1163
    jne  append_access_1
1164
 
1164
 
1165
  append_full_sector:
1165
  append_full_sector:
1166
    sub   [bytes2write],ecx
1166
    sub   [bytes2write],ecx
1167
    add   [new_filepos],ecx
1167
    add   [new_filepos],ecx
1168
    add   edi,buffer
1168
    add   edi,buffer
1169
    cld
1169
    cld
1170
    rep   movsb
1170
    rep   movsb
1171
    pop   ecx
1171
    pop   ecx
1172
 
1172
 
1173
    mov   ebx,buffer
1173
    mov   ebx,buffer
1174
    call  hd_write
1174
    call  hd_write
1175
    cmp   [hd_error],0
1175
    cmp   [hd_error],0
1176
    jne   append_access
1176
    jne   append_access
1177
 
1177
 
1178
    cmp   [bytes2write],0       ; is all done?
1178
    cmp   [bytes2write],0       ; is all done?
1179
    jz    append_done
1179
    jz    append_done
1180
    xor   edi,edi
1180
    xor   edi,edi
1181
    inc   eax
1181
    inc   eax
1182
    dec   ecx
1182
    dec   ecx
1183
    jnz   append_new_sector
1183
    jnz   append_new_sector
1184
 
1184
 
1185
    mov   eax,[cluster]
1185
    mov   eax,[cluster]
1186
    call  get_FAT
1186
    call  get_FAT
1187
    cmp   [hd_error],0
1187
    cmp   [hd_error],0
1188
    jne   append_access
1188
    jne   append_access
1189
 
1189
 
1190
    cmp   eax,2
1190
    cmp   eax,2
1191
    jb    append_fat
1191
    jb    append_fat
1192
    cmp   eax,[LAST_CLUSTER]
1192
    cmp   eax,[LAST_CLUSTER]
1193
    jbe   append_found_cluster
1193
    jbe   append_found_cluster
1194
 
1194
 
1195
  append_alloc_cluster:
1195
  append_alloc_cluster:
1196
    mov   eax,2                 ; ToDo: use temp array to keep track
1196
    mov   eax,2                 ; ToDo: use temp array to keep track
1197
    call  get_free_FAT          ;       of last free cluster
1197
    call  get_free_FAT          ;       of last free cluster
1198
    jc    append_disk_full
1198
    jc    append_disk_full
1199
    push  eax                   ; save new cluster
1199
    push  eax                   ; save new cluster
1200
    mov   edx,[fatEND]          ; new end for cluster chain
1200
    mov   edx,[fatEND]          ; new end for cluster chain
1201
    call  set_FAT
1201
    call  set_FAT
1202
    cmp  [hd_error],0
1202
    cmp  [hd_error],0
1203
    jne  append_access_1
1203
    jne  append_access_1
1204
      
1204
      
1205
    mov   edx,eax
1205
    mov   edx,eax
1206
    mov   eax,[cluster]
1206
    mov   eax,[cluster]
1207
    mov   [f_del],1
1207
    mov   [f_del],1
1208
    call  set_FAT               ; update previous cluster
1208
    call  set_FAT               ; update previous cluster
1209
    cmp  [hd_error],0
1209
    cmp  [hd_error],0
1210
    jne  append_access_1
1210
    jne  append_access_1
1211
 
1211
 
1212
    mov   [f_del],0
1212
    mov   [f_del],0
1213
    pop   eax
1213
    pop   eax
1214
    jmp   append_remove_free
1214
    jmp   append_remove_free
1215
 
1215
 
1216
  append_find_pos:
1216
  append_find_pos:
1217
    call  find_filepos
1217
    call  find_filepos
1218
    mov   [cluster],ebx
1218
    mov   [cluster],ebx
1219
    jnc   append_new_sector
1219
    jnc   append_new_sector
1220
    test  edi,edi
1220
    test  edi,edi
1221
    jz    append_alloc_cluster
1221
    jz    append_alloc_cluster
1222
 
1222
 
1223
  append_fat:
1223
  append_fat:
1224
    mov   eax,ERROR_FAT_TABLE
1224
    mov   eax,ERROR_FAT_TABLE
1225
    jmp   append_ret_code
1225
    jmp   append_ret_code
1226
                        
1226
                        
1227
  append_disk_full:
1227
  append_disk_full:
1228
    cmp  [hd_error],0
1228
    cmp  [hd_error],0
1229
    jne  append_access
1229
    jne  append_access
1230
    mov   eax,ERROR_DISK_FULL
1230
    mov   eax,ERROR_DISK_FULL
1231
    jmp   append_ret_code
1231
    jmp   append_ret_code
1232
 
1232
 
1233
  append_done:
1233
  append_done:
1234
    xor   eax,eax
1234
    xor   eax,eax
1235
 
1235
 
1236
  append_ret_code:
1236
  append_ret_code:
1237
    mov   PUSHAD_EAX,eax        ; return code
1237
    mov   PUSHAD_EAX,eax        ; return code
1238
 
1238
 
1239
    mov   eax,[sector_tmp]      ; update directory entry
1239
    mov   eax,[sector_tmp]      ; update directory entry
1240
    mov   ebx,buffer
1240
    mov   ebx,buffer
1241
    call  hd_read
1241
    call  hd_read
1242
    cmp  [hd_error],0
1242
    cmp  [hd_error],0
1243
    jne  append_access
1243
    jne  append_access
1244
     
1244
     
1245
    mov   ebx,[entry_pos]
1245
    mov   ebx,[entry_pos]
1246
    mov   ecx,[new_filepos]
1246
    mov   ecx,[new_filepos]
1247
    cmp   ecx,[old_filesize]    ; is file pos above old size?
1247
    cmp   ecx,[old_filesize]    ; is file pos above old size?
1248
    jbe   append_size_ok        ; no
1248
    jbe   append_size_ok        ; no
1249
    mov   [ebx+28],ecx          ; new file size
1249
    mov   [ebx+28],ecx          ; new file size
1250
 
1250
 
1251
  append_size_ok:
1251
  append_size_ok:
1252
    call  set_current_time_for_entry
1252
    call  set_current_time_for_entry
1253
    mov   ebx,buffer
1253
    mov   ebx,buffer
1254
    call  hd_write              ; write new file entry back to disk
1254
    call  hd_write              ; write new file entry back to disk
1255
    cmp   [hd_error],0
1255
    cmp   [hd_error],0
1256
    jne   append_access
1256
    jne   append_access
1257
 
1257
 
1258
    sub   ecx,PUSHAD_ESI        ; start position
1258
    sub   ecx,PUSHAD_ESI        ; start position
1259
    mov   PUSHAD_EBX,ecx        ; bytes written
1259
    mov   PUSHAD_EBX,ecx        ; bytes written
1260
    popad
1260
    popad
1261
    call  update_disk           ; write all of cache and fat to hd
1261
    call  update_disk           ; write all of cache and fat to hd
1262
    cmp   [hd_error],0
1262
    cmp   [hd_error],0
1263
    jne   append_access_2
1263
    jne   append_access_2
1264
 
1264
 
1265
    mov   [hd1_status],0
1265
    mov   [hd1_status],0
1266
    ret
1266
    ret
1267
 
1267
 
1268
  append_eof:
1268
  append_eof:
1269
    popad
1269
    popad
1270
    mov   [hd1_status],0
1270
    mov   [hd1_status],0
1271
    xor   ebx,ebx
1271
    xor   ebx,ebx
1272
    mov   eax,ERROR_END_OF_FILE
1272
    mov   eax,ERROR_END_OF_FILE
1273
    ret
1273
    ret
1274
 
1274
 
1275
  append_not_found:
1275
  append_not_found:
1276
    cmp  [hd_error],0
1276
    cmp  [hd_error],0
1277
    jne   append_access
1277
    jne   append_access
1278
    popad
1278
    popad
1279
    mov   [hd1_status],0
1279
    mov   [hd1_status],0
1280
    xor   ebx,ebx
1280
    xor   ebx,ebx
1281
    mov   eax,ERROR_FILE_NOT_FOUND
1281
    mov   eax,ERROR_FILE_NOT_FOUND
1282
    ret        
1282
    ret        
1283
  append_access_1:
1283
  append_access_1:
1284
    add   esp,4
1284
    add   esp,4
1285
  append_access:
1285
  append_access:
1286
    popad
1286
    popad
1287
  append_access_2:
1287
  append_access_2:
1288
    mov   [hd1_status],0
1288
    mov   [hd1_status],0
1289
    xor   ebx,ebx
1289
    xor   ebx,ebx
1290
    mov   eax,ERROR_ACCESS_DENIED
1290
    mov   eax,ERROR_ACCESS_DENIED
1291
    ret
1291
    ret
1292
 
1292
 
1293
  append_truncate:
1293
  append_truncate:
1294
    mov   edx,[ebx+20-2]        ; FAT entry
1294
    mov   edx,[ebx+20-2]        ; FAT entry
1295
    mov   dx,[ebx+26]
1295
    mov   dx,[ebx+26]
1296
    and   edx,[fatMASK]
1296
    and   edx,[fatMASK]
1297
    mov   [ebx+28],edi          ; set new file size
1297
    mov   [ebx+28],edi          ; set new file size
1298
    test  edi,edi               ; 0 length file?
1298
    test  edi,edi               ; 0 length file?
1299
    jnz   truncate_save_size    ; no
1299
    jnz   truncate_save_size    ; no
1300
    mov   [ebx+20],di           ; FAT entry = 0
1300
    mov   [ebx+20],di           ; FAT entry = 0
1301
    mov   [ebx+26],di
1301
    mov   [ebx+26],di
1302
 
1302
 
1303
  truncate_save_size:
1303
  truncate_save_size:
1304
    call  set_current_time_for_entry
1304
    call  set_current_time_for_entry
1305
    mov   ebx,buffer
1305
    mov   ebx,buffer
1306
    call  hd_write
1306
    call  hd_write
1307
    cmp   [hd_error],0
1307
    cmp   [hd_error],0
1308
    jne   append_access
1308
    jne   append_access
1309
 
1309
 
1310
    mov   eax,edx               ; first cluster
1310
    mov   eax,edx               ; first cluster
1311
    test  edi,edi               ; 0 length file?
1311
    test  edi,edi               ; 0 length file?
1312
    jz    truncate_clear_chain
1312
    jz    truncate_clear_chain
1313
 
1313
 
1314
    imul  esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes
1314
    imul  esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes
1315
 
1315
 
1316
  truncate_new_cluster:
1316
  truncate_new_cluster:
1317
    cmp   eax,2                 ; incorrect fat chain?
1317
    cmp   eax,2                 ; incorrect fat chain?
1318
    jb    truncate_eof          ; yes
1318
    jb    truncate_eof          ; yes
1319
    cmp   eax,[fatRESERVED]     ; is it end of file?
1319
    cmp   eax,[fatRESERVED]     ; is it end of file?
1320
    jnb   truncate_eof          ; yes
1320
    jnb   truncate_eof          ; yes
1321
    sub   edi,esi
1321
    sub   edi,esi
1322
    jbe   truncate_pos_found
1322
    jbe   truncate_pos_found
1323
    call  get_FAT               ; get next cluster
1323
    call  get_FAT               ; get next cluster
1324
    cmp   [hd_error],0
1324
    cmp   [hd_error],0
1325
    jne   append_access
1325
    jne   append_access
1326
 
1326
 
1327
    jmp   truncate_new_cluster
1327
    jmp   truncate_new_cluster
1328
 
1328
 
1329
  truncate_pos_found:
1329
  truncate_pos_found:
1330
    mov   edx,[fatEND]          ; new end for cluster chain
1330
    mov   edx,[fatEND]          ; new end for cluster chain
1331
    mov   [f_del],1
1331
    mov   [f_del],1
1332
    call  set_FAT
1332
    call  set_FAT
1333
    cmp  [hd_error],0
1333
    cmp  [hd_error],0
1334
    jne  append_access
1334
    jne  append_access
1335
 
1335
 
1336
    mov   [f_del],0
1336
    mov   [f_del],0
1337
    mov   eax,edx               ; clear rest of chain
1337
    mov   eax,edx               ; clear rest of chain
1338
 
1338
 
1339
  truncate_clear_chain:
1339
  truncate_clear_chain:
1340
    call  clear_cluster_chain
1340
    call  clear_cluster_chain
1341
    cmp  [hd_error],0
1341
    cmp  [hd_error],0
1342
    jne  append_access
1342
    jne  append_access
1343
 
1343
 
1344
  truncate_eof:
1344
  truncate_eof:
1345
    popad
1345
    popad
1346
    call  update_disk           ; write all of cache and fat to hd
1346
    call  update_disk           ; write all of cache and fat to hd
1347
    cmp   [hd_error],0
1347
    cmp   [hd_error],0
1348
    jne   append_access_2
1348
    jne   append_access_2
1349
 
1349
 
1350
    mov   [hd1_status],0
1350
    mov   [hd1_status],0
1351
    xor   ebx,ebx
1351
    xor   ebx,ebx
1352
    xor   eax,eax
1352
    xor   eax,eax
1353
    ret
1353
    ret
1354
 
1354
 
1355
 
1355
 
1356
find_filepos:
1356
find_filepos:
1357
;-----------------------------------------------------
1357
;-----------------------------------------------------
1358
; input  : eax = first cluster
1358
; input  : eax = first cluster
1359
;          edi = bytes to skip over (start position)
1359
;          edi = bytes to skip over (start position)
1360
; output : if CARRY=0 file position found
1360
; output : if CARRY=0 file position found
1361
;          if CARRY=1 end of file found
1361
;          if CARRY=1 end of file found
1362
;          eax = current file sector
1362
;          eax = current file sector
1363
;          ebx = last cluster
1363
;          ebx = last cluster
1364
;          ecx = sector count in last cluster
1364
;          ecx = sector count in last cluster
1365
;          edi = bytes to skip over (sector position)
1365
;          edi = bytes to skip over (sector position)
1366
;-----------------------------------------------------
1366
;-----------------------------------------------------
1367
    push  esi
1367
    push  esi
1368
    mov   ecx,[SECTORS_PER_CLUSTER]
1368
    mov   ecx,[SECTORS_PER_CLUSTER]
1369
    imul  esi,ecx,512           ; esi = cluster size in bytes
1369
    imul  esi,ecx,512           ; esi = cluster size in bytes
1370
    mov   ebx,eax
1370
    mov   ebx,eax
1371
 
1371
 
1372
  filepos_new_cluster:
1372
  filepos_new_cluster:
1373
    cmp   eax,2                 ; incorrect fat chain?
1373
    cmp   eax,2                 ; incorrect fat chain?
1374
    jb    filepos_eof           ; yes
1374
    jb    filepos_eof           ; yes
1375
    cmp   eax,[fatRESERVED]     ; is it end of file?
1375
    cmp   eax,[fatRESERVED]     ; is it end of file?
1376
    jnb   filepos_eof           ; yes
1376
    jnb   filepos_eof           ; yes
1377
 
1377
 
1378
    mov   ebx,eax
1378
    mov   ebx,eax
1379
    cmp   edi,esi               ; skip over full cluster?
1379
    cmp   edi,esi               ; skip over full cluster?
1380
    jb    filepos_cluster_ok    ; no
1380
    jb    filepos_cluster_ok    ; no
1381
 
1381
 
1382
    sub   edi,esi
1382
    sub   edi,esi
1383
    call  get_FAT               ; get next cluster
1383
    call  get_FAT               ; get next cluster
1384
    cmp   [hd_error],0
1384
    cmp   [hd_error],0
1385
    jne   filepos_eof
1385
    jne   filepos_eof
1386
 
1386
 
1387
    jmp   filepos_new_cluster
1387
    jmp   filepos_new_cluster
1388
 
1388
 
1389
  filepos_cluster_ok:
1389
  filepos_cluster_ok:
1390
    sub   eax,2
1390
    sub   eax,2
1391
    imul  eax,ecx
1391
    imul  eax,ecx
1392
    add   eax,[DATA_START]
1392
    add   eax,[DATA_START]
1393
 
1393
 
1394
  filepos_new_sector:
1394
  filepos_new_sector:
1395
    cmp   edi,512               ; skip over full sector?
1395
    cmp   edi,512               ; skip over full sector?
1396
    jb    filepos_sector_ok     ; no
1396
    jb    filepos_sector_ok     ; no
1397
    sub   edi,512
1397
    sub   edi,512
1398
    inc   eax
1398
    inc   eax
1399
    dec   ecx
1399
    dec   ecx
1400
    jnz   filepos_new_sector
1400
    jnz   filepos_new_sector
1401
 
1401
 
1402
  filepos_eof:
1402
  filepos_eof:
1403
    pop   esi
1403
    pop   esi
1404
    stc
1404
    stc
1405
    ret
1405
    ret
1406
 
1406
 
1407
  filepos_sector_ok:
1407
  filepos_sector_ok:
1408
    pop   esi
1408
    pop   esi
1409
    clc
1409
    clc
1410
    ret
1410
    ret
1411
 
1411
 
1412
 
1412
 
1413
file_write:
1413
file_write:
1414
;--------------------------------------------------------------------------
1414
;--------------------------------------------------------------------------
1415
;   INPUT : user-reg  register-in-this  meaning      symbol-in-this-routine
1415
;   INPUT : user-reg  register-in-this  meaning      symbol-in-this-routine
1416
;
1416
;
1417
;            EAX        EDI            system call to write    /
1417
;            EAX        EDI            system call to write    /
1418
;            EBX        EAX   (PAR0)   pointer to file-name    PAR0
1418
;            EBX        EAX   (PAR0)   pointer to file-name    PAR0
1419
;            EDX        ECX   (PAR1)   pointer to buffer       PAR1
1419
;            EDX        ECX   (PAR1)   pointer to buffer       PAR1
1420
;            ECX        EBX   (PAR2)   file size               PAR2
1420
;            ECX        EBX   (PAR2)   file size               PAR2
1421
;            ESI        EDX   (PAR3)   pointer to path         PAR3
1421
;            ESI        EDX   (PAR3)   pointer to path         PAR3
1422
;
1422
;
1423
; output : eax = 0 - ok
1423
; output : eax = 0 - ok
1424
;                3 - unknown FS
1424
;                3 - unknown FS
1425
;                5 - file not found
1425
;                5 - file not found
1426
;                8 - disk full
1426
;                8 - disk full
1427
;               10 - access denied
1427
;               10 - access denied
1428
;--------------------------------------------------------------------------
1428
;--------------------------------------------------------------------------
1429
    cmp   [fat_type],0
1429
    cmp   [fat_type],0
1430
    jnz   fat_ok_for_writing
1430
    jnz   fat_ok_for_writing
1431
    mov   eax,ERROR_UNKNOWN_FS
1431
    mov   eax,ERROR_UNKNOWN_FS
1432
    ret
1432
    ret
1433
 
1433
 
1434
  fat_ok_for_writing:
1434
  fat_ok_for_writing:
1435
;    call  reserve_hd1
1435
;    call  reserve_hd1
1436
 
1436
 
1437
    pushad
1437
    pushad
1438
 
1438
 
1439
    xor   edi,edi               ; don't allow directory remove
1439
    xor   edi,edi               ; don't allow directory remove
1440
    call  file_delete           ; try to delete the file first
1440
    call  file_delete           ; try to delete the file first
1441
    cmp   [hd_error],0
1441
    cmp   [hd_error],0
1442
    jne   exit_write_access_1
1442
    jne   exit_write_access_1
1443
 
1443
 
1444
    test  eax,eax
1444
    test  eax,eax
1445
    jz    old_deleted           ; deleted ok
1445
    jz    old_deleted           ; deleted ok
1446
    cmp   eax,ERROR_FILE_NOT_FOUND
1446
    cmp   eax,ERROR_FILE_NOT_FOUND
1447
    jnz   exit_write_access     ; it exist but can't delete
1447
    jnz   exit_write_access     ; it exist but can't delete
1448
 
1448
 
1449
  old_deleted:
1449
  old_deleted:
1450
    mov   ebx,PUSHAD_EDX
1450
    mov   ebx,PUSHAD_EDX
1451
    call  get_cluster_of_a_path
1451
    call  get_cluster_of_a_path
1452
    jnc   found_directory_for_writing
1452
    jnc   found_directory_for_writing
1453
    cmp   [hd_error],0
1453
    cmp   [hd_error],0
1454
    jne   exit_write_access
1454
    jne   exit_write_access
1455
 
1455
 
1456
  exit_writing_with_error:
1456
  exit_writing_with_error:
1457
    popad
1457
    popad
1458
    call  update_disk           ; write all of cache and fat to hd
1458
    call  update_disk           ; write all of cache and fat to hd
1459
    cmp   [hd_error],0
1459
    cmp   [hd_error],0
1460
    jne   exit_write_access_2
1460
    jne   exit_write_access_2
1461
 
1461
 
1462
    mov   [hd1_status],0
1462
    mov   [hd1_status],0
1463
    mov   eax,ERROR_FILE_NOT_FOUND
1463
    mov   eax,ERROR_FILE_NOT_FOUND
1464
    ret
1464
    ret
1465
 
1465
 
1466
  exit_writing_disk_full_clear:
1466
  exit_writing_disk_full_clear:
1467
    cmp  [hd_error],0
1467
    cmp  [hd_error],0
1468
    jne  exit_write_access_1
1468
    jne  exit_write_access_1
1469
    mov   eax,[sector_tmp]
1469
    mov   eax,[sector_tmp]
1470
    mov   ebx,buffer
1470
    mov   ebx,buffer
1471
    call  hd_read               ; read directory sector
1471
    call  hd_read               ; read directory sector
1472
    cmp  [hd_error],0
1472
    cmp  [hd_error],0
1473
    jne  exit_write_access_1
1473
    jne  exit_write_access_1
1474
 
1474
 
1475
    mov   edx,[entry_pos]
1475
    mov   edx,[entry_pos]
1476
    mov   byte [edx],0xe5       ; mark as deleted
1476
    mov   byte [edx],0xe5       ; mark as deleted
1477
    call  hd_write
1477
    call  hd_write
1478
    cmp   [hd_error],0
1478
    cmp   [hd_error],0
1479
    jne   exit_write_access_1
1479
    jne   exit_write_access_1
1480
 
1480
 
1481
    mov   eax,[edx+20-2]        ; FAT entry
1481
    mov   eax,[edx+20-2]        ; FAT entry
1482
    mov   ax,[edx+26]
1482
    mov   ax,[edx+26]
1483
    and   eax,[fatMASK]
1483
    and   eax,[fatMASK]
1484
    call  clear_cluster_chain
1484
    call  clear_cluster_chain
1485
 
1485
 
1486
  exit_writing_disk_full:
1486
  exit_writing_disk_full:
1487
    cmp  [hd_error],0
1487
    cmp  [hd_error],0
1488
    jne  exit_write_access_1
1488
    jne  exit_write_access_1
1489
    popad
1489
    popad
1490
    call  update_disk           ; write all of cache and fat to hd
1490
    call  update_disk           ; write all of cache and fat to hd
1491
    cmp   [hd_error],0
1491
    cmp   [hd_error],0
1492
    jne   exit_write_access_2
1492
    jne   exit_write_access_2
1493
    mov   [hd1_status],0
1493
    mov   [hd1_status],0
1494
    mov   eax,ERROR_DISK_FULL
1494
    mov   eax,ERROR_DISK_FULL
1495
    ret
1495
    ret
1496
 
1496
 
1497
  exit_write_access:
1497
  exit_write_access:
1498
    popad
1498
    popad
1499
    call  update_disk           ; write all of cache and fat to hd
1499
    call  update_disk           ; write all of cache and fat to hd
1500
    mov   [hd1_status],0
1500
    mov   [hd1_status],0
1501
    mov   eax,ERROR_ACCESS_DENIED
1501
    mov   eax,ERROR_ACCESS_DENIED
1502
    ret
1502
    ret
1503
 
1503
 
1504
  exit_write_access_1:
1504
  exit_write_access_1:
1505
    popad
1505
    popad
1506
  exit_write_access_2:
1506
  exit_write_access_2:
1507
    mov   [hd1_status],0
1507
    mov   [hd1_status],0
1508
    mov   eax,ERROR_ACCESS_DENIED
1508
    mov   eax,ERROR_ACCESS_DENIED
1509
    ret
1509
    ret
1510
 
1510
 
1511
found_directory_for_writing:
1511
found_directory_for_writing:
1512
    call  analyze_directory_to_write
1512
    call  analyze_directory_to_write
1513
    jc    exit_writing_disk_full
1513
    jc    exit_writing_disk_full
1514
 
1514
 
1515
    mov   [sector_tmp],eax
1515
    mov   [sector_tmp],eax
1516
    mov   [entry_pos],ebx
1516
    mov   [entry_pos],ebx
1517
    push  eax                   ; save directory sector
1517
    push  eax                   ; save directory sector
1518
    mov   eax,2
1518
    mov   eax,2
1519
    call  get_free_FAT
1519
    call  get_free_FAT
1520
    mov   [cluster],eax         ; first free cluster
1520
    mov   [cluster],eax         ; first free cluster
1521
    pop   eax
1521
    pop   eax
1522
    jc    exit_writing_disk_full
1522
    jc    exit_writing_disk_full
1523
 
1523
 
1524
    mov   esi,PUSHAD_EAX        ; file name
1524
    mov   esi,PUSHAD_EAX        ; file name
1525
    mov   edi,ebx               ; pointer in buffer
1525
    mov   edi,ebx               ; pointer in buffer
1526
    mov   ecx,11
1526
    mov   ecx,11
1527
    cld
1527
    cld
1528
    rep   movsb
1528
    rep   movsb
1529
 
1529
 
1530
    mov   esi,PUSHAD_EBX        ; file size (bytes left)
1530
    mov   esi,PUSHAD_EBX        ; file size (bytes left)
1531
    mov   [ebx+28],esi          ; file size
1531
    mov   [ebx+28],esi          ; file size
1532
    mov   ecx,[cluster]
1532
    mov   ecx,[cluster]
1533
    mov   [ebx+26],cx           ; 16 bits low of cluster
1533
    mov   [ebx+26],cx           ; 16 bits low of cluster
1534
    shr   ecx,16
1534
    shr   ecx,16
1535
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
1535
    mov   [ebx+20],cx           ; 16 bits high of cluster (=0 fat16)
1536
    mov   byte [ebx+11],0x20    ; attribute = archive
1536
    mov   byte [ebx+11],0x20    ; attribute = archive
1537
 
1537
 
1538
    call  set_current_time_for_entry
1538
    call  set_current_time_for_entry
1539
 
1539
 
1540
    mov   ebx,buffer            ; save the directory name,length,cluster
1540
    mov   ebx,buffer            ; save the directory name,length,cluster
1541
    call  hd_write
1541
    call  hd_write
1542
    cmp   [hd_error],0
1542
    cmp   [hd_error],0
1543
    jne   exit_write_access_1
1543
    jne   exit_write_access_1
1544
 
1544
 
1545
    imul  edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes
1545
    imul  edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes
1546
    xor   ecx,ecx               ; cluster count
1546
    xor   ecx,ecx               ; cluster count
1547
    mov   ebx,PUSHAD_ECX        ; ebx = buffer
1547
    mov   ebx,PUSHAD_ECX        ; ebx = buffer
1548
 
1548
 
1549
hd_new_block_write:
1549
hd_new_block_write:
1550
 
1550
 
1551
    mov   eax,[cluster]         ; eax = block
1551
    mov   eax,[cluster]         ; eax = block
1552
    call  set_data_cluster
1552
    call  set_data_cluster
1553
    cmp   [hd_error],0
1553
    cmp   [hd_error],0
1554
    jne   exit_write_access_1
1554
    jne   exit_write_access_1
1555
 
1555
 
1556
    sub   esi,edi               ; sub wrote bytes
1556
    sub   esi,edi               ; sub wrote bytes
1557
    jbe   file_saved_OK         ; end if all done
1557
    jbe   file_saved_OK         ; end if all done
1558
    add   ebx,edi               ; update buffer position
1558
    add   ebx,edi               ; update buffer position
1559
 
1559
 
1560
    inc   eax
1560
    inc   eax
1561
    call  get_free_FAT          ; next free in FAT
1561
    call  get_free_FAT          ; next free in FAT
1562
    jc    exit_writing_disk_full_clear
1562
    jc    exit_writing_disk_full_clear
1563
 
1563
 
1564
    mov   edx,eax
1564
    mov   edx,eax
1565
    xchg  eax,[cluster]         ; get old cluster and save new cluster
1565
    xchg  eax,[cluster]         ; get old cluster and save new cluster
1566
    call  set_FAT               ; add it in cluster chain
1566
    call  set_FAT               ; add it in cluster chain
1567
    cmp  [hd_error],0
1567
    cmp  [hd_error],0
1568
    jne   exit_write_access_1
1568
    jne   exit_write_access_1
1569
 
1569
 
1570
    dec   ecx                   ; update cluster count
1570
    dec   ecx                   ; update cluster count
1571
    jmp   hd_new_block_write
1571
    jmp   hd_new_block_write
1572
 
1572
 
1573
file_saved_OK:
1573
file_saved_OK:
1574
 
1574
 
1575
    mov   edx,[fatEND]          ; new end for cluster chain
1575
    mov   edx,[fatEND]          ; new end for cluster chain
1576
    call  set_FAT
1576
    call  set_FAT
1577
    cmp  [hd_error],0
1577
    cmp  [hd_error],0
1578
    jne   exit_write_access_1
1578
    jne   exit_write_access_1
1579
 
1579
 
1580
    dec   ecx                   ; update cluster count
1580
    dec   ecx                   ; update cluster count
1581
 
1581
 
1582
    call  add_disk_free_space   ; remove clusters from free disk space
1582
    call  add_disk_free_space   ; remove clusters from free disk space
1583
    cmp  [hd_error],0
1583
    cmp  [hd_error],0
1584
    jne   exit_write_access_1
1584
    jne   exit_write_access_1
1585
 
1585
 
1586
    popad
1586
    popad
1587
    call  update_disk           ; write all of cache and fat to hd
1587
    call  update_disk           ; write all of cache and fat to hd
1588
    cmp   [hd_error],0
1588
    cmp   [hd_error],0
1589
    jne   exit_write_access_2
1589
    jne   exit_write_access_2
1590
    mov   [hd1_status],0
1590
    mov   [hd1_status],0
1591
    xor   eax,eax
1591
    xor   eax,eax
1592
    ret
1592
    ret
1593
 
1593
 
1594
 
1594
 
1595
file_read:
1595
file_read:
1596
;--------------------------------------------------------------------------
1596
;--------------------------------------------------------------------------
1597
;   INPUT :  user-register register-in-this  meaning         symbol-in-this
1597
;   INPUT :  user-register register-in-this  meaning         symbol-in-this
1598
;
1598
;
1599
;            EAX           EDI               system call to write   /
1599
;            EAX           EDI               system call to write   /
1600
;            EBX           EAX   (PAR0)      pointer to file-name   PAR0
1600
;            EBX           EAX   (PAR0)      pointer to file-name   PAR0
1601
;            EDX           ECX   (PAR1)      pointer to buffer      PAR1
1601
;            EDX           ECX   (PAR1)      pointer to buffer      PAR1
1602
;            ECX           EBX   (PAR2)   vt file blocks to read    PAR2
1602
;            ECX           EBX   (PAR2)   vt file blocks to read    PAR2
1603
;            ESI           EDX   (PAR3)      pointer to path        PAR3
1603
;            ESI           EDX   (PAR3)      pointer to path        PAR3
1604
;            EDI           ESI            vt first 512 block to read
1604
;            EDI           ESI            vt first 512 block to read
1605
;                          EDI               if 0 - read root
1605
;                          EDI               if 0 - read root
1606
;
1606
;
1607
; output : eax = 0 - ok
1607
; output : eax = 0 - ok
1608
;                3 - unknown FS
1608
;                3 - unknown FS
1609
;                5 - file not found
1609
;                5 - file not found
1610
;                6 - end of file
1610
;                6 - end of file
1611
;                9 - fat table corrupted
1611
;                9 - fat table corrupted
1612
;               10 - access denied
1612
;               10 - access denied
1613
;          ebx = size of file/directory
1613
;          ebx = size of file/directory
1614
;--------------------------------------------------------------------------
1614
;--------------------------------------------------------------------------
1615
    cmp   [fat_type],0
1615
    cmp   [fat_type],0
1616
    jnz   fat_ok_for_reading
1616
    jnz   fat_ok_for_reading
1617
    xor   ebx,ebx
1617
    xor   ebx,ebx
1618
    mov   eax,ERROR_UNKNOWN_FS
1618
    mov   eax,ERROR_UNKNOWN_FS
1619
    mov   [hd1_status], ebx
1619
    mov   [hd1_status], ebx
1620
    ret
1620
    ret
1621
 
1621
 
1622
  fat_ok_for_reading:
1622
  fat_ok_for_reading:
1623
;    call  reserve_hd1
1623
;    call  reserve_hd1
1624
 
1624
 
1625
    pushad
1625
    pushad
1626
 
1626
 
1627
    mov   ebx,edx
1627
    mov   ebx,edx
1628
    call  get_cluster_of_a_path
1628
    call  get_cluster_of_a_path
1629
    jc    file_to_read_not_found
1629
    jc    file_to_read_not_found
1630
 
1630
 
1631
    test  edi,edi               ; read rootdir
1631
    test  edi,edi               ; read rootdir
1632
    jne   no_read_root
1632
    jne   no_read_root
1633
 
1633
 
1634
    xor   eax,eax
1634
    xor   eax,eax
1635
    call  get_dir_size          ; return rootdir size
1635
    call  get_dir_size          ; return rootdir size
1636
    cmp   [hd_error],0
1636
    cmp   [hd_error],0
1637
    jne   file_access_denied
1637
    jne   file_access_denied
1638
 
1638
 
1639
    mov   [file_size],eax
1639
    mov   [file_size],eax
1640
    mov   eax,[ROOT_CLUSTER]
1640
    mov   eax,[ROOT_CLUSTER]
1641
    jmp   file_read_start
1641
    jmp   file_read_start
1642
 
1642
 
1643
  no_read_root:
1643
  no_read_root:
1644
    mov   ebx,PUSHAD_EAX        ; file name
1644
    mov   ebx,PUSHAD_EAX        ; file name
1645
    call  analyze_directory
1645
    call  analyze_directory
1646
    jc    file_to_read_not_found
1646
    jc    file_to_read_not_found
1647
 
1647
 
1648
    mov   eax,[ebx+28]          ; file size
1648
    mov   eax,[ebx+28]          ; file size
1649
    test  byte [ebx+11],0x10    ; is it directory?
1649
    test  byte [ebx+11],0x10    ; is it directory?
1650
    jz    read_set_size         ; no
1650
    jz    read_set_size         ; no
1651
 
1651
 
1652
    mov   eax,[ebx+20-2]        ; FAT entry
1652
    mov   eax,[ebx+20-2]        ; FAT entry
1653
    mov   ax,[ebx+26]
1653
    mov   ax,[ebx+26]
1654
    and   eax,[fatMASK]
1654
    and   eax,[fatMASK]
1655
    call  get_dir_size
1655
    call  get_dir_size
1656
    cmp   [hd_error],0
1656
    cmp   [hd_error],0
1657
    jne   file_access_denied
1657
    jne   file_access_denied
1658
 
1658
 
1659
  read_set_size:
1659
  read_set_size:
1660
    mov   [file_size],eax
1660
    mov   [file_size],eax
1661
 
1661
 
1662
    mov   eax,[ebx+20-2]        ; FAT entry
1662
    mov   eax,[ebx+20-2]        ; FAT entry
1663
    mov   ax,[ebx+26]
1663
    mov   ax,[ebx+26]
1664
    and   eax,[fatMASK]
1664
    and   eax,[fatMASK]
1665
 
1665
 
1666
  file_read_start:
1666
  file_read_start:
1667
    mov   ebx,PUSHAD_ECX        ; pointer to buffer
1667
    mov   ebx,PUSHAD_ECX        ; pointer to buffer
1668
    mov   edx,PUSHAD_EBX        ; file blocks to read
1668
    mov   edx,PUSHAD_EBX        ; file blocks to read
1669
    mov   esi,PUSHAD_ESI        ; first 512 block to read
1669
    mov   esi,PUSHAD_ESI        ; first 512 block to read
1670
 
1670
 
1671
  file_read_new_cluster:
1671
  file_read_new_cluster:
1672
    call  get_data_cluster
1672
    call  get_data_cluster
1673
    jc    file_read_eof         ; end of file or cluster out of range
1673
    jc    file_read_eof         ; end of file or cluster out of range
1674
 
1674
 
1675
    test  edx,edx               ; is all read?
1675
    test  edx,edx               ; is all read?
1676
    je    file_read_OK          ; yes
1676
    je    file_read_OK          ; yes
1677
 
1677
 
1678
    call  get_FAT               ; get next cluster
1678
    call  get_FAT               ; get next cluster
1679
    cmp   [hd_error],0
1679
    cmp   [hd_error],0
1680
    jne   file_access_denied
1680
    jne   file_access_denied
1681
 
1681
 
1682
    cmp   eax,[fatRESERVED]     ; end of file
1682
    cmp   eax,[fatRESERVED]     ; end of file
1683
    jnb   file_read_eof
1683
    jnb   file_read_eof
1684
    cmp   eax,2                 ; incorrect fat chain
1684
    cmp   eax,2                 ; incorrect fat chain
1685
    jnb   file_read_new_cluster
1685
    jnb   file_read_new_cluster
1686
 
1686
 
1687
    popad
1687
    popad
1688
    mov   [hd1_status],0
1688
    mov   [hd1_status],0
1689
    mov   ebx,[file_size]
1689
    mov   ebx,[file_size]
1690
    mov   eax,ERROR_FAT_TABLE
1690
    mov   eax,ERROR_FAT_TABLE
1691
    ret
1691
    ret
1692
 
1692
 
1693
  file_read_eof:
1693
  file_read_eof:
1694
    cmp   [hd_error],0
1694
    cmp   [hd_error],0
1695
    jne   file_access_denied
1695
    jne   file_access_denied
1696
    popad
1696
    popad
1697
    mov   [hd1_status],0
1697
    mov   [hd1_status],0
1698
    mov   ebx,[file_size]
1698
    mov   ebx,[file_size]
1699
    mov   eax,ERROR_END_OF_FILE
1699
    mov   eax,ERROR_END_OF_FILE
1700
    ret
1700
    ret
1701
 
1701
 
1702
  file_read_OK:
1702
  file_read_OK:
1703
    popad
1703
    popad
1704
    mov   [hd1_status],0
1704
    mov   [hd1_status],0
1705
    mov   ebx,[file_size]
1705
    mov   ebx,[file_size]
1706
    xor   eax,eax
1706
    xor   eax,eax
1707
    ret
1707
    ret
1708
 
1708
 
1709
  file_to_read_not_found:
1709
  file_to_read_not_found:
1710
    cmp   [hd_error],0
1710
    cmp   [hd_error],0
1711
    jne   file_access_denied
1711
    jne   file_access_denied
1712
    popad
1712
    popad
1713
    mov   [hd1_status],0
1713
    mov   [hd1_status],0
1714
    xor   ebx,ebx
1714
    xor   ebx,ebx
1715
    mov   eax,ERROR_FILE_NOT_FOUND
1715
    mov   eax,ERROR_FILE_NOT_FOUND
1716
    ret
1716
    ret
1717
 
1717
 
1718
  file_access_denied:
1718
  file_access_denied:
1719
    popad
1719
    popad
1720
    mov   [hd1_status],0
1720
    mov   [hd1_status],0
1721
    xor   ebx,ebx
1721
    xor   ebx,ebx
1722
    mov   eax,ERROR_ACCESS_DENIED
1722
    mov   eax,ERROR_ACCESS_DENIED
1723
    ret
1723
    ret
1724
 
1724
 
1725
get_dir_size:
1725
get_dir_size:
1726
;-----------------------------------------------------
1726
;-----------------------------------------------------
1727
; input  : eax = first cluster (0=rootdir)
1727
; input  : eax = first cluster (0=rootdir)
1728
; output : eax = directory size in bytes
1728
; output : eax = directory size in bytes
1729
;-----------------------------------------------------
1729
;-----------------------------------------------------
1730
    push  edx
1730
    push  edx
1731
    xor   edx,edx               ; count of directory clusters
1731
    xor   edx,edx               ; count of directory clusters
1732
    test  eax,eax
1732
    test  eax,eax
1733
    jnz   dir_size_next
1733
    jnz   dir_size_next
1734
 
1734
 
1735
    mov   eax,[ROOT_SECTORS]
1735
    mov   eax,[ROOT_SECTORS]
1736
    shl   eax,9                 ; fat16 rootdir size in bytes
1736
    shl   eax,9                 ; fat16 rootdir size in bytes
1737
    cmp   [fat_type],16
1737
    cmp   [fat_type],16
1738
    je    dir_size_ret
1738
    je    dir_size_ret
1739
    mov   eax,[ROOT_CLUSTER]
1739
    mov   eax,[ROOT_CLUSTER]
1740
 
1740
 
1741
  dir_size_next:
1741
  dir_size_next:
1742
    cmp   eax,2                 ; incorrect fat chain
1742
    cmp   eax,2                 ; incorrect fat chain
1743
    jb    dir_size_end
1743
    jb    dir_size_end
1744
    cmp   eax,[fatRESERVED]     ; end of directory
1744
    cmp   eax,[fatRESERVED]     ; end of directory
1745
    ja    dir_size_end
1745
    ja    dir_size_end
1746
    call  get_FAT               ; get next cluster
1746
    call  get_FAT               ; get next cluster
1747
    cmp   [hd_error],0
1747
    cmp   [hd_error],0
1748
    jne   dir_size_ret
1748
    jne   dir_size_ret
1749
 
1749
 
1750
    inc   edx
1750
    inc   edx
1751
    jmp   dir_size_next
1751
    jmp   dir_size_next
1752
 
1752
 
1753
  dir_size_end:
1753
  dir_size_end:
1754
    imul  eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
1754
    imul  eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
1755
    imul  eax,edx
1755
    imul  eax,edx
1756
 
1756
 
1757
  dir_size_ret:
1757
  dir_size_ret:
1758
    pop   edx
1758
    pop   edx
1759
    ret
1759
    ret
1760
 
1760
 
1761
 
1761
 
1762
file_delete:
1762
file_delete:
1763
;-----------------------------------------------------
1763
;-----------------------------------------------------
1764
; input  : eax = file/directory name
1764
; input  : eax = file/directory name
1765
;          edx = path
1765
;          edx = path
1766
;          edi = 1 - allow directory remove else don't remove directory
1766
;          edi = 1 - allow directory remove else don't remove directory
1767
; output : eax = 0 - ok
1767
; output : eax = 0 - ok
1768
;                3 - unknown FS
1768
;                3 - unknown FS
1769
;                5 - file not found
1769
;                5 - file not found
1770
;               10 - access denied
1770
;               10 - access denied
1771
;-----------------------------------------------------
1771
;-----------------------------------------------------
1772
    cmp   [fat_type],0
1772
    cmp   [fat_type],0
1773
    jnz   file_del_fat_ok
1773
    jnz   file_del_fat_ok
1774
    mov   eax,ERROR_UNKNOWN_FS
1774
    mov   eax,ERROR_UNKNOWN_FS
1775
    ret
1775
    ret
1776
 
1776
 
1777
  file_del_fat_ok:
1777
  file_del_fat_ok:
1778
    pushad
1778
    pushad
1779
 
1779
 
1780
    mov   ebx,edx
1780
    mov   ebx,edx
1781
    call  get_cluster_of_a_path
1781
    call  get_cluster_of_a_path
1782
    jc    file_to_delete_not_found
1782
    jc    file_to_delete_not_found
1783
 
1783
 
1784
    mov   ebx,PUSHAD_EAX        ; file/directory name
1784
    mov   ebx,PUSHAD_EAX        ; file/directory name
1785
    call  analyze_directory
1785
    call  analyze_directory
1786
    jc    file_to_delete_not_found
1786
    jc    file_to_delete_not_found
1787
 
1787
 
1788
    test  byte [ebx+11],0x10    ; is it directory?
1788
    test  byte [ebx+11],0x10    ; is it directory?
1789
    jz    delete_notdir         ; no. it's file
1789
    jz    delete_notdir         ; no. it's file
1790
    cmp   edi,1                 ; allow directory remove
1790
    cmp   edi,1                 ; allow directory remove
1791
    jnz   delete_no_access      ; no
1791
    jnz   delete_no_access      ; no
1792
 
1792
 
1793
    push  eax                   ; save directory sector
1793
    push  eax                   ; save directory sector
1794
    mov   eax,[ebx+20-2]        ; first cluster of file
1794
    mov   eax,[ebx+20-2]        ; first cluster of file
1795
    mov   ax,[ebx+26]           ; 0 length files start cluster = 0
1795
    mov   ax,[ebx+26]           ; 0 length files start cluster = 0
1796
    and   eax,[fatMASK]
1796
    and   eax,[fatMASK]
1797
    xor   ebp,ebp               ; counter for directory deepnes
1797
    xor   ebp,ebp               ; counter for directory deepnes
1798
    call  clear_directory
1798
    call  clear_directory
1799
    pop   eax
1799
    pop   eax
1800
    jc    delete_no_access
1800
    jc    delete_no_access
1801
 
1801
 
1802
    push  ebx                   ; save directory pointer in buffer
1802
    push  ebx                   ; save directory pointer in buffer
1803
    mov   ebx,buffer
1803
    mov   ebx,buffer
1804
    call  hd_read               ; read directory sector
1804
    call  hd_read               ; read directory sector
1805
    cmp  [hd_error],0
1805
    cmp  [hd_error],0
1806
    jne  delete_no_access_1
1806
    jne  delete_no_access_1
1807
    pop   ebx
1807
    pop   ebx
1808
 
1808
 
1809
  delete_notdir:
1809
  delete_notdir:
1810
    call  delete_entry_name
1810
    call  delete_entry_name
1811
    cmp   [hd_error],0
1811
    cmp   [hd_error],0
1812
    jne   delete_no_access
1812
    jne   delete_no_access
1813
 
1813
 
1814
    mov   eax,ecx               ; first cluster of file
1814
    mov   eax,ecx               ; first cluster of file
1815
    call  clear_cluster_chain
1815
    call  clear_cluster_chain
1816
    cmp   [hd_error],0
1816
    cmp   [hd_error],0
1817
    jne   delete_no_access
1817
    jne   delete_no_access
1818
 
1818
 
1819
    popad
1819
    popad
1820
    xor   eax,eax
1820
    xor   eax,eax
1821
    ret
1821
    ret
1822
 
1822
 
1823
  delete_no_access_1:
1823
  delete_no_access_1:
1824
     add esp,4
1824
     add esp,4
1825
  delete_no_access:
1825
  delete_no_access:
1826
    popad
1826
    popad
1827
    mov   eax,ERROR_ACCESS_DENIED
1827
    mov   eax,ERROR_ACCESS_DENIED
1828
    ret
1828
    ret
1829
 
1829
 
1830
  file_to_delete_not_found:
1830
  file_to_delete_not_found:
1831
    cmp  [hd_error],0
1831
    cmp  [hd_error],0
1832
    jne  delete_no_access
1832
    jne  delete_no_access
1833
    popad
1833
    popad
1834
    mov   eax,ERROR_FILE_NOT_FOUND
1834
    mov   eax,ERROR_FILE_NOT_FOUND
1835
    ret
1835
    ret
1836
 
1836
 
1837
 
1837
 
1838
clear_cluster_chain:
1838
clear_cluster_chain:
1839
;-----------------------------------------------------
1839
;-----------------------------------------------------
1840
; input  : eax = first cluster
1840
; input  : eax = first cluster
1841
;-----------------------------------------------------
1841
;-----------------------------------------------------
1842
    push  eax ecx edx
1842
    push  eax ecx edx
1843
    xor   ecx,ecx               ; cluster count
1843
    xor   ecx,ecx               ; cluster count
1844
    mov   [f_del],1             ; delete on
1844
    mov   [f_del],1             ; delete on
1845
 
1845
 
1846
  clean_new_chain:
1846
  clean_new_chain:
1847
    cmp   eax,[LAST_CLUSTER]    ; end of file
1847
    cmp   eax,[LAST_CLUSTER]    ; end of file
1848
    ja    delete_OK
1848
    ja    delete_OK
1849
    cmp   eax,2                 ; unfinished fat chain or zero length file
1849
    cmp   eax,2                 ; unfinished fat chain or zero length file
1850
    jb    delete_OK
1850
    jb    delete_OK
1851
    cmp   eax,[ROOT_CLUSTER]    ; don't remove root cluster
1851
    cmp   eax,[ROOT_CLUSTER]    ; don't remove root cluster
1852
    jz    delete_OK
1852
    jz    delete_OK
1853
 
1853
 
1854
    xor   edx,edx
1854
    xor   edx,edx
1855
    call  set_FAT               ; clear fat entry
1855
    call  set_FAT               ; clear fat entry
1856
    cmp  [hd_error],0
1856
    cmp  [hd_error],0
1857
    jne  access_denied_01
1857
    jne  access_denied_01
1858
 
1858
 
1859
    inc   ecx                   ; update cluster count
1859
    inc   ecx                   ; update cluster count
1860
    mov   eax,edx               ; old cluster
1860
    mov   eax,edx               ; old cluster
1861
    jmp   clean_new_chain
1861
    jmp   clean_new_chain
1862
 
1862
 
1863
  delete_OK:
1863
  delete_OK:
1864
    call  add_disk_free_space   ; add clusters to free disk space
1864
    call  add_disk_free_space   ; add clusters to free disk space
1865
  access_denied_01:
1865
  access_denied_01:
1866
    mov   [f_del],0
1866
    mov   [f_del],0
1867
    pop   edx ecx eax
1867
    pop   edx ecx eax
1868
    ret
1868
    ret
1869
 
1869
 
1870
 
1870
 
1871
clear_directory:
1871
clear_directory:
1872
;-----------------------------------------------------
1872
;-----------------------------------------------------
1873
; input  : eax = directory cluster
1873
; input  : eax = directory cluster
1874
;          ebp = directory deepnes
1874
;          ebp = directory deepnes
1875
; Note   : use recursive call
1875
; Note   : use recursive call
1876
;-----------------------------------------------------
1876
;-----------------------------------------------------
1877
    pushad
1877
    pushad
1878
    inc   ebp
1878
    inc   ebp
1879
    cmp   ebp,64                ; if over 63 directory deep
1879
    cmp   ebp,64                ; if over 63 directory deep
1880
    jnb   clear_error           ; something must be wrong
1880
    jnb   clear_error           ; something must be wrong
1881
 
1881
 
1882
  clear_new_cluster:
1882
  clear_new_cluster:
1883
    cmp   eax,[LAST_CLUSTER]
1883
    cmp   eax,[LAST_CLUSTER]
1884
    ja    clear_end
1884
    ja    clear_end
1885
    cmp   eax,[ROOT_CLUSTER]    ; don't remove root cluster
1885
    cmp   eax,[ROOT_CLUSTER]    ; don't remove root cluster
1886
    jz    clear_end
1886
    jz    clear_end
1887
    mov   esi,eax               ; esi = current directory cluster
1887
    mov   esi,eax               ; esi = current directory cluster
1888
    sub   eax,2
1888
    sub   eax,2
1889
    jb    clear_end
1889
    jb    clear_end
1890
    mov   ecx,[SECTORS_PER_CLUSTER]
1890
    mov   ecx,[SECTORS_PER_CLUSTER]
1891
    imul  eax,ecx
1891
    imul  eax,ecx
1892
    add   eax,[DATA_START]
1892
    add   eax,[DATA_START]
1893
 
1893
 
1894
  clear_new_sector:
1894
  clear_new_sector:
1895
    mov   edi,eax               ; edi = current directory sector
1895
    mov   edi,eax               ; edi = current directory sector
1896
    mov   ebx,deltree_buffer
1896
    mov   ebx,deltree_buffer
1897
    call  hd_read
1897
    call  hd_read
1898
    cmp  [hd_error],0
1898
    cmp  [hd_error],0
1899
    jne  clear_error    
1899
    jne  clear_error    
1900
 
1900
 
1901
    mov   edx,512/32            ; count of dir entrys per sector = 16
1901
    mov   edx,512/32            ; count of dir entrys per sector = 16
1902
 
1902
 
1903
  clear_analyze:
1903
  clear_analyze:
1904
    mov   al,[ebx+11]           ; file attribute
1904
    mov   al,[ebx+11]           ; file attribute
1905
    and   al,0xf
1905
    and   al,0xf
1906
    cmp   al,0xf
1906
    cmp   al,0xf
1907
    je    clear_long_filename
1907
    je    clear_long_filename
1908
 
1908
 
1909
    cmp   byte [ebx],'.'        ; parent or current directory
1909
    cmp   byte [ebx],'.'        ; parent or current directory
1910
    je    clear_next_entry
1910
    je    clear_next_entry
1911
    cmp   byte [ebx],0xe5       ; deleted
1911
    cmp   byte [ebx],0xe5       ; deleted
1912
    je    clear_next_entry
1912
    je    clear_next_entry
1913
    cmp   byte [ebx],0          ; empty
1913
    cmp   byte [ebx],0          ; empty
1914
    je    clear_write_last
1914
    je    clear_write_last
1915
    ;je    clear_next_entry
1915
    ;je    clear_next_entry
1916
 
1916
 
1917
    mov   eax,[ebx+20-2]        ; first cluster of entry
1917
    mov   eax,[ebx+20-2]        ; first cluster of entry
1918
    mov   ax,[ebx+26]
1918
    mov   ax,[ebx+26]
1919
    and   eax,[fatMASK]
1919
    and   eax,[fatMASK]
1920
 
1920
 
1921
    test  byte [ebx+11],0x10    ; is it directory?
1921
    test  byte [ebx+11],0x10    ; is it directory?
1922
    jz    clear_file            ; no
1922
    jz    clear_file            ; no
1923
 
1923
 
1924
    push  eax ebx
1924
    push  eax ebx
1925
    mov   eax,edi
1925
    mov   eax,edi
1926
    mov   ebx,deltree_buffer    ; save buffer over recursive call
1926
    mov   ebx,deltree_buffer    ; save buffer over recursive call
1927
    call  hd_write              ; write directory sector to disk
1927
    call  hd_write              ; write directory sector to disk
1928
    cmp   [hd_error],0
1928
    cmp   [hd_error],0
1929
    jne   clear_error    
1929
    jne   clear_error    
1930
 
1930
 
1931
    pop   ebx eax
1931
    pop   ebx eax
1932
 
1932
 
1933
    call  clear_directory       ; recursive call !!!
1933
    call  clear_directory       ; recursive call !!!
1934
    jc    clear_error           ; exit if error found
1934
    jc    clear_error           ; exit if error found
1935
 
1935
 
1936
    push  eax ebx
1936
    push  eax ebx
1937
    mov   eax,edi
1937
    mov   eax,edi
1938
    mov   ebx,deltree_buffer
1938
    mov   ebx,deltree_buffer
1939
    call  hd_read               ; read directory sector again
1939
    call  hd_read               ; read directory sector again
1940
    cmp  [hd_error],0
1940
    cmp  [hd_error],0
1941
    jne   clear_error_1
1941
    jne   clear_error_1
1942
 
1942
 
1943
    pop   ebx eax
1943
    pop   ebx eax
1944
 
1944
 
1945
  clear_file:
1945
  clear_file:
1946
    call  clear_cluster_chain
1946
    call  clear_cluster_chain
1947
    cmp  [hd_error],0
1947
    cmp  [hd_error],0
1948
    jne   clear_error
1948
    jne   clear_error
1949
 
1949
 
1950
  clear_long_filename:
1950
  clear_long_filename:
1951
    mov   byte [ebx],0xe5
1951
    mov   byte [ebx],0xe5
1952
 
1952
 
1953
  clear_next_entry:
1953
  clear_next_entry:
1954
    add   ebx,32                ; position of next dir entry
1954
    add   ebx,32                ; position of next dir entry
1955
    dec   edx
1955
    dec   edx
1956
    jnz   clear_analyze
1956
    jnz   clear_analyze
1957
 
1957
 
1958
    mov   eax,edi
1958
    mov   eax,edi
1959
    mov   ebx,deltree_buffer
1959
    mov   ebx,deltree_buffer
1960
    call  hd_write              ; write directory sector to disk
1960
    call  hd_write              ; write directory sector to disk
1961
    cmp   [hd_error],0
1961
    cmp   [hd_error],0
1962
    jne   clear_error
1962
    jne   clear_error
1963
 
1963
 
1964
    inc   eax                   ; next sector
1964
    inc   eax                   ; next sector
1965
    dec   ecx
1965
    dec   ecx
1966
    jnz   clear_new_sector
1966
    jnz   clear_new_sector
1967
 
1967
 
1968
    mov   eax,esi
1968
    mov   eax,esi
1969
    call  get_FAT               ; get next cluster
1969
    call  get_FAT               ; get next cluster
1970
    cmp   [hd_error],0
1970
    cmp   [hd_error],0
1971
    jne   clear_error
1971
    jne   clear_error
1972
 
1972
 
1973
    jmp   clear_new_cluster     ; clear it
1973
    jmp   clear_new_cluster     ; clear it
1974
 
1974
 
1975
  clear_write_last:
1975
  clear_write_last:
1976
    mov   eax,edi
1976
    mov   eax,edi
1977
    mov   ebx,deltree_buffer
1977
    mov   ebx,deltree_buffer
1978
    call  hd_write              ; write directory sector to disk
1978
    call  hd_write              ; write directory sector to disk
1979
    cmp   [hd_error],0
1979
    cmp   [hd_error],0
1980
    jne   clear_error
1980
    jne   clear_error
1981
 
1981
 
1982
  clear_end:
1982
  clear_end:
1983
    popad
1983
    popad
1984
    clc
1984
    clc
1985
    ret
1985
    ret
1986
clear_error_1:
1986
clear_error_1:
1987
    add  esp,8
1987
    add  esp,8
1988
  clear_error:
1988
  clear_error:
1989
    popad
1989
    popad
1990
    stc
1990
    stc
1991
    ret
1991
    ret
1992
 
1992
 
1993
 
1993
 
1994
delete_entry_name:
1994
delete_entry_name:
1995
;-----------------------------------------------------
1995
;-----------------------------------------------------
1996
; input  : eax = directory sector
1996
; input  : eax = directory sector
1997
;          ebx = directory pointer in buffer
1997
;          ebx = directory pointer in buffer
1998
;          longname_sec = 2 previous directory sectors
1998
;          longname_sec = 2 previous directory sectors
1999
; output : ecx = first cluster
1999
; output : ecx = first cluster
2000
; change : eax,ebx,edx
2000
; change : eax,ebx,edx
2001
;-----------------------------------------------------
2001
;-----------------------------------------------------
2002
    mov   byte [ebx],0xe5
2002
    mov   byte [ebx],0xe5
2003
    mov   ecx,[ebx+20-2]        ; first cluster of file
2003
    mov   ecx,[ebx+20-2]        ; first cluster of file
2004
    mov   cx,[ebx+26]           ; 0 length files start cluster = 0
2004
    mov   cx,[ebx+26]           ; 0 length files start cluster = 0
2005
    and   ecx,[fatMASK]
2005
    and   ecx,[fatMASK]
2006
 
2006
 
2007
  delete_empty:
2007
  delete_empty:
2008
    sub   ebx,32
2008
    sub   ebx,32
2009
    cmp   ebx,buffer
2009
    cmp   ebx,buffer
2010
    jnb   delete_test_long
2010
    jnb   delete_test_long
2011
 
2011
 
2012
    mov   ebx,buffer
2012
    mov   ebx,buffer
2013
    call  hd_write              ; write directory sector back
2013
    call  hd_write              ; write directory sector back
2014
    cmp   [hd_error],0
2014
    cmp   [hd_error],0
2015
    jne   delete_name_end
2015
    jne   delete_name_end
2016
 
2016
 
2017
    xor   eax,eax
2017
    xor   eax,eax
2018
    xchg  eax,[longname_sec2]
2018
    xchg  eax,[longname_sec2]
2019
    xchg  eax,[longname_sec1]
2019
    xchg  eax,[longname_sec1]
2020
    test  eax,eax               ; is there previous directory sector?
2020
    test  eax,eax               ; is there previous directory sector?
2021
    jz    delete_name_end       ; no
2021
    jz    delete_name_end       ; no
2022
 
2022
 
2023
    mov   ebx,buffer
2023
    mov   ebx,buffer
2024
    call  hd_read               ; read previous sector
2024
    call  hd_read               ; read previous sector
2025
    cmp  [hd_error],0
2025
    cmp  [hd_error],0
2026
    jne  delete_name_end    
2026
    jne  delete_name_end    
2027
 
2027
 
2028
    mov   ebx,buffer+0x1e0      ; start from last entry
2028
    mov   ebx,buffer+0x1e0      ; start from last entry
2029
 
2029
 
2030
  delete_test_long:
2030
  delete_test_long:
2031
    mov   dh,[ebx+11]           ; file attribute
2031
    mov   dh,[ebx+11]           ; file attribute
2032
    and   dh,0xf
2032
    and   dh,0xf
2033
    cmp   dh,0xf
2033
    cmp   dh,0xf
2034
    jne   delete_write_buffer
2034
    jne   delete_write_buffer
2035
 
2035
 
2036
    cmp   byte [ebx],0x40       ; end of long dir entry?
2036
    cmp   byte [ebx],0x40       ; end of long dir entry?
2037
    mov   byte [ebx],0xe5
2037
    mov   byte [ebx],0xe5
2038
    jb    delete_empty
2038
    jb    delete_empty
2039
 
2039
 
2040
  delete_write_buffer:
2040
  delete_write_buffer:
2041
    mov   ebx,buffer
2041
    mov   ebx,buffer
2042
    call  hd_write              ; write directory sector back
2042
    call  hd_write              ; write directory sector back
2043
 
2043
 
2044
  delete_name_end:
2044
  delete_name_end:
2045
    ret
2045
    ret
2046
 
2046
 
2047
 
2047
 
2048
rename:
2048
rename:
2049
;-----------------------------------------------------------
2049
;-----------------------------------------------------------
2050
; input  : eax = source directory name
2050
; input  : eax = source directory name
2051
;          edx = source path
2051
;          edx = source path
2052
;          ebx = dest directory name
2052
;          ebx = dest directory name
2053
;          edi = dest path
2053
;          edi = dest path
2054
; output : eax = 0 - ok
2054
; output : eax = 0 - ok
2055
;                3 - unknown FS
2055
;                3 - unknown FS
2056
;                5 - file not found
2056
;                5 - file not found
2057
;                8 - disk full
2057
;                8 - disk full
2058
;               10 - access denied
2058
;               10 - access denied
2059
;-----------------------------------------------------------
2059
;-----------------------------------------------------------
2060
    cmp   [fat_type],0
2060
    cmp   [fat_type],0
2061
    jnz   fat_ok_for_rename
2061
    jnz   fat_ok_for_rename
2062
    mov   eax,ERROR_UNKNOWN_FS
2062
    mov   eax,ERROR_UNKNOWN_FS
2063
    ret
2063
    ret
2064
 
2064
 
2065
  fat_ok_for_rename:
2065
  fat_ok_for_rename:
2066
;    call  reserve_hd1
2066
;    call  reserve_hd1
2067
 
2067
 
2068
    pushad
2068
    pushad
2069
 
2069
 
2070
    mov   ebx,edx               ; source path
2070
    mov   ebx,edx               ; source path
2071
    call  get_cluster_of_a_path
2071
    call  get_cluster_of_a_path
2072
    jc    rename_entry_not_found
2072
    jc    rename_entry_not_found
2073
 
2073
 
2074
    mov   ebx,PUSHAD_EAX        ; source directory name
2074
    mov   ebx,PUSHAD_EAX        ; source directory name
2075
    call  analyze_directory
2075
    call  analyze_directory
2076
    jc    rename_entry_not_found
2076
    jc    rename_entry_not_found
2077
 
2077
 
2078
    mov   [sector_tmp],eax      ; save source sector
2078
    mov   [sector_tmp],eax      ; save source sector
2079
    mov   [entry_pos],ebx
2079
    mov   [entry_pos],ebx
2080
    mov   esi,ebx
2080
    mov   esi,ebx
2081
    mov   edi,dir_entry
2081
    mov   edi,dir_entry
2082
    mov   ecx,32/4
2082
    mov   ecx,32/4
2083
    cld
2083
    cld
2084
    rep   movsd                 ; save entry
2084
    rep   movsd                 ; save entry
2085
 
2085
 
2086
    mov   ebx,PUSHAD_EDI        ; dest path
2086
    mov   ebx,PUSHAD_EDI        ; dest path
2087
    call  get_cluster_of_a_path
2087
    call  get_cluster_of_a_path
2088
    jc    rename_entry_not_found
2088
    jc    rename_entry_not_found
2089
 
2089
 
2090
    mov   edx,eax               ; save dest directory cluster
2090
    mov   edx,eax               ; save dest directory cluster
2091
    mov   ebx,PUSHAD_EBX        ; dest directory name
2091
    mov   ebx,PUSHAD_EBX        ; dest directory name
2092
    push  [longname_sec1]
2092
    push  [longname_sec1]
2093
    push  [longname_sec2]
2093
    push  [longname_sec2]
2094
    call  analyze_directory     ; check if entry already exist
2094
    call  analyze_directory     ; check if entry already exist
2095
    cmp  [hd_error],0
2095
    cmp  [hd_error],0
2096
    jne  rename_entry_already_exist_1
2096
    jne  rename_entry_already_exist_1
2097
 
2097
 
2098
    pop   [longname_sec2]
2098
    pop   [longname_sec2]
2099
    pop   [longname_sec1]
2099
    pop   [longname_sec1]
2100
    jnc   rename_entry_already_exist
2100
    jnc   rename_entry_already_exist
2101
 
2101
 
2102
    mov   eax,edx
2102
    mov   eax,edx
2103
    call  analyze_directory_to_write
2103
    call  analyze_directory_to_write
2104
    jc    rename_disk_full
2104
    jc    rename_disk_full
2105
 
2105
 
2106
    mov   esi,dir_entry
2106
    mov   esi,dir_entry
2107
    mov   edi,ebx
2107
    mov   edi,ebx
2108
    mov   ecx,32/4
2108
    mov   ecx,32/4
2109
    cld
2109
    cld
2110
    rep   movsd                 ; copy entry
2110
    rep   movsd                 ; copy entry
2111
    mov   esi,PUSHAD_EBX        ; dest directory name
2111
    mov   esi,PUSHAD_EBX        ; dest directory name
2112
    mov   edi,ebx
2112
    mov   edi,ebx
2113
    mov   ecx,11
2113
    mov   ecx,11
2114
    rep   movsb                 ; copy name
2114
    rep   movsb                 ; copy name
2115
 
2115
 
2116
    mov   ebx,buffer            ; save the directory name,length,cluster
2116
    mov   ebx,buffer            ; save the directory name,length,cluster
2117
    call  hd_write
2117
    call  hd_write
2118
 
2118
 
2119
    test  byte [dir_entry+11],0x10 ; is it directory?
2119
    test  byte [dir_entry+11],0x10 ; is it directory?
2120
    jz    rename_not_dir           ; no
2120
    jz    rename_not_dir           ; no
2121
    mov   eax,[dir_entry+20-2]     ; FAT entry
2121
    mov   eax,[dir_entry+20-2]     ; FAT entry
2122
    mov   ax,[dir_entry+26]
2122
    mov   ax,[dir_entry+26]
2123
    and   eax,[fatMASK]
2123
    and   eax,[fatMASK]
2124
    call  change_2dot_cluster
2124
    call  change_2dot_cluster
2125
    cmp   [hd_error],0
2125
    cmp   [hd_error],0
2126
    jne   rename_entry_already_exist
2126
    jne   rename_entry_already_exist
2127
 
2127
 
2128
  rename_not_dir:
2128
  rename_not_dir:
2129
    cmp   [hd_error],0
2129
    cmp   [hd_error],0
2130
    jne   rename_entry_already_exist
2130
    jne   rename_entry_already_exist
2131
    mov   eax,[sector_tmp]
2131
    mov   eax,[sector_tmp]
2132
    mov   ebx,buffer
2132
    mov   ebx,buffer
2133
    call  hd_read               ; read source directory sector
2133
    call  hd_read               ; read source directory sector
2134
    cmp  [hd_error],0
2134
    cmp  [hd_error],0
2135
    jne  rename_entry_already_exist
2135
    jne  rename_entry_already_exist
2136
 
2136
 
2137
    mov   ebx,[entry_pos]
2137
    mov   ebx,[entry_pos]
2138
    call  delete_entry_name
2138
    call  delete_entry_name
2139
    cmp   [hd_error],0
2139
    cmp   [hd_error],0
2140
    jne   rename_entry_already_exist
2140
    jne   rename_entry_already_exist
2141
 
2141
 
2142
    popad
2142
    popad
2143
    call  update_disk           ; write all of cache and fat to hd
2143
    call  update_disk           ; write all of cache and fat to hd
2144
    cmp   [hd_error],0
2144
    cmp   [hd_error],0
2145
    jne   rename_entry_already_exist_2
2145
    jne   rename_entry_already_exist_2
2146
    mov   [hd1_status],0
2146
    mov   [hd1_status],0
2147
    xor   eax,eax
2147
    xor   eax,eax
2148
    ret
2148
    ret
2149
 
2149
 
2150
  rename_entry_not_found:
2150
  rename_entry_not_found:
2151
    cmp  [hd_error],0
2151
    cmp  [hd_error],0
2152
    jne  rename_entry_already_exist
2152
    jne  rename_entry_already_exist
2153
    popad
2153
    popad
2154
    mov   [hd1_status],0
2154
    mov   [hd1_status],0
2155
    mov   eax,ERROR_FILE_NOT_FOUND
2155
    mov   eax,ERROR_FILE_NOT_FOUND
2156
    ret
2156
    ret
2157
 
2157
 
2158
  rename_entry_already_exist_1:
2158
  rename_entry_already_exist_1:
2159
    add   esp,8
2159
    add   esp,8
2160
  rename_entry_already_exist:
2160
  rename_entry_already_exist:
2161
    popad
2161
    popad
2162
  rename_entry_already_exist_2:
2162
  rename_entry_already_exist_2:
2163
    mov   [hd1_status],0
2163
    mov   [hd1_status],0
2164
    mov   eax,ERROR_ACCESS_DENIED
2164
    mov   eax,ERROR_ACCESS_DENIED
2165
    ret
2165
    ret
2166
 
2166
 
2167
  rename_disk_full:
2167
  rename_disk_full:
2168
    cmp  [hd_error],0
2168
    cmp  [hd_error],0
2169
    jne  rename_entry_already_exist
2169
    jne  rename_entry_already_exist
2170
    popad
2170
    popad
2171
    mov   [hd1_status],0
2171
    mov   [hd1_status],0
2172
    mov   eax,ERROR_DISK_FULL
2172
    mov   eax,ERROR_DISK_FULL
2173
    ret
2173
    ret
2174
 
2174
 
2175
 
2175
 
2176
change_2dot_cluster:
2176
change_2dot_cluster:
2177
;-----------------------------------------------------------
2177
;-----------------------------------------------------------
2178
; input  : eax = directory cluster
2178
; input  : eax = directory cluster
2179
;          edx = value to save
2179
;          edx = value to save
2180
; change : eax,ebx,edx
2180
; change : eax,ebx,edx
2181
;-----------------------------------------------------------
2181
;-----------------------------------------------------------
2182
    cmp   eax,[LAST_CLUSTER]
2182
    cmp   eax,[LAST_CLUSTER]
2183
    ja    not_2dot              ; too big cluster number, something is wrong
2183
    ja    not_2dot              ; too big cluster number, something is wrong
2184
    sub   eax,2
2184
    sub   eax,2
2185
    jb    not_2dot
2185
    jb    not_2dot
2186
 
2186
 
2187
    imul  eax,[SECTORS_PER_CLUSTER]
2187
    imul  eax,[SECTORS_PER_CLUSTER]
2188
    add   eax,[DATA_START]
2188
    add   eax,[DATA_START]
2189
    mov   ebx,buffer
2189
    mov   ebx,buffer
2190
    call  hd_read
2190
    call  hd_read
2191
    cmp  [hd_error],0
2191
    cmp  [hd_error],0
2192
    jne  not_2dot
2192
    jne  not_2dot
2193
 
2193
 
2194
    cmp   dword [ebx+32],'..  '
2194
    cmp   dword [ebx+32],'..  '
2195
    jnz   not_2dot
2195
    jnz   not_2dot
2196
 
2196
 
2197
    cmp   edx,[ROOT_CLUSTER]    ; is rootdir cluster?
2197
    cmp   edx,[ROOT_CLUSTER]    ; is rootdir cluster?
2198
    jne   not_2dot_root
2198
    jne   not_2dot_root
2199
    xor   edx,edx               ; yes. set it zero
2199
    xor   edx,edx               ; yes. set it zero
2200
 
2200
 
2201
  not_2dot_root:
2201
  not_2dot_root:
2202
    mov   [ebx+32+26],dx        ; 16 bits low of cluster
2202
    mov   [ebx+32+26],dx        ; 16 bits low of cluster
2203
    shr   edx,16
2203
    shr   edx,16
2204
    mov   [ebx+32+20],dx        ; 16 bits high of cluster (=0 fat16)
2204
    mov   [ebx+32+20],dx        ; 16 bits high of cluster (=0 fat16)
2205
    call  hd_write
2205
    call  hd_write
2206
 
2206
 
2207
  not_2dot:
2207
  not_2dot:
2208
    ret
2208
    ret
2209
 
2209
 
2210
 
-
 
2211
get_filesize:
-
 
2212
;-----------------------------------------------------------
-
 
2213
; input  : eax = file name
-
 
2214
;          edx = path
-
 
2215
;          edi = if 0 - read rootdir else normal dir/file size
-
 
2216
; output : eax = 0 - ok
-
 
2217
;                3 - unknown FS
-
 
2218
;                5 - file not found
-
 
2219
;               10 - access denied
-
 
2220
;          ebx = file size
-
 
2221
;-----------------------------------------------------------
-
 
2222
    cmp   [fat_type],0
-
 
2223
    jnz   get_filesize_fat_ok
-
 
2224
    xor   ebx,ebx
-
 
2225
    mov   eax,ERROR_UNKNOWN_FS
-
 
2226
    ret
-
 
2227
 
-
 
2228
  get_filesize_fat_ok:
-
 
2229
;    call  reserve_hd1
-
 
2230
 
-
 
2231
    pushad
-
 
2232
    xor   eax,eax
-
 
2233
    test  edi,edi               ; is read rootdir?
-
 
2234
    je    get_filesize_dirsize  ; yes
-
 
2235
 
-
 
2236
  get_filesize_no_root:
-
 
2237
    mov   ebx,edx
-
 
2238
    call  get_cluster_of_a_path
-
 
2239
    jc    get_filesize_not_found
-
 
2240
 
-
 
2241
    mov   ebx,PUSHAD_EAX        ; file name
-
 
2242
    call  analyze_directory
-
 
2243
    jc    get_filesize_not_found
-
 
2244
 
-
 
2245
    mov   eax,[ebx+28]          ; file size
-
 
2246
    test  byte [ebx+11],0x10    ; is it directory?
-
 
2247
    jz    get_filesize_set_size ; no
-
 
2248
 
-
 
2249
    mov   eax,[ebx+20-2]        ; FAT entry
-
 
2250
    mov   ax,[ebx+26]
-
 
2251
    and   eax,[fatMASK]
-
 
2252
 
-
 
2253
  get_filesize_dirsize:
-
 
2254
    call  get_dir_size
-
 
2255
    cmp   [hd_error],0
-
 
2256
    jne   get_filesize_access_denied
-
 
2257
 
-
 
2258
  get_filesize_set_size:
-
 
2259
    mov   PUSHAD_EBX,eax
-
 
2260
    popad
-
 
2261
    mov   [hd1_status],0
-
 
2262
    xor   eax,eax
-
 
2263
    ret
-
 
2264
 
-
 
2265
  get_filesize_not_found:
-
 
2266
    cmp   [hd_error],0
-
 
2267
    jne   get_filesize_access_denied
-
 
2268
    popad
-
 
2269
    mov   [hd1_status],0
-
 
2270
    xor   ebx,ebx
-
 
2271
    mov   eax,ERROR_FILE_NOT_FOUND
-
 
2272
    ret
-
 
2273
 
-
 
2274
  get_filesize_access_denied:
-
 
2275
    popad
-
 
2276
    mov   [hd1_status],0
-
 
2277
    xor   ebx,ebx
-
 
2278
    mov   eax,ERROR_ACCESS_DENIED
-
 
2279
    ret
-
 
2280
 
-
 
2281
get_fileattr:
-
 
2282
;-----------------------------------------------------------
-
 
2283
; input  : eax = file name
-
 
2284
;          edx = path
-
 
2285
; output : eax = 0 - ok
-
 
2286
;                3 - unknown FS
-
 
2287
;                5 - file not found
-
 
2288
;               10 - access denied
-
 
2289
;          ebx = file attribute
-
 
2290
;-----------------------------------------------------------
-
 
2291
    cmp   [fat_type],0
-
 
2292
    jnz   get_fileattr_fat_ok
-
 
2293
    xor   ebx,ebx
-
 
2294
    mov   eax,ERROR_UNKNOWN_FS
-
 
2295
    ret
-
 
2296
 
-
 
2297
  get_fileattr_fat_ok:
-
 
2298
;    call  reserve_hd1
-
 
2299
 
-
 
2300
    pushad
-
 
2301
    mov   ebx,edx
-
 
2302
    call  get_cluster_of_a_path
-
 
2303
    jc    get_fileattr_not_found
-
 
2304
 
-
 
2305
    mov   ebx,PUSHAD_EAX        ; file name
-
 
2306
    call  analyze_directory
-
 
2307
    jc    get_fileattr_not_found
-
 
2308
 
-
 
2309
    movzx eax,byte [ebx+11]     ; file attribute
-
 
2310
    mov   PUSHAD_EBX,eax
-
 
2311
    popad
-
 
2312
    mov   [hd1_status],0
-
 
2313
    xor   eax,eax
-
 
2314
    ret
-
 
2315
 
-
 
2316
  get_fileattr_not_found:
-
 
2317
    cmp   [hd_error],0
-
 
2318
    jne   get_fileattr_access_denied
-
 
2319
    popad
-
 
2320
    mov   [hd1_status],0
-
 
2321
    xor   ebx,ebx
-
 
2322
    mov   eax,ERROR_FILE_NOT_FOUND
-
 
2323
    ret
-
 
2324
 
-
 
2325
  get_fileattr_access_denied:
-
 
2326
    popad
-
 
2327
    mov   [hd1_status],0
-
 
2328
    xor   ebx,ebx
-
 
2329
    mov   eax,ERROR_ACCESS_DENIED
-
 
2330
    ret
-
 
2331
 
-
 
2332
get_filedate:
-
 
2333
;-----------------------------------------------------------
-
 
2334
; input  : eax = file name
-
 
2335
;          edx = path
-
 
2336
; output : eax = 0 - ok
-
 
2337
;                3 - unknown FS
-
 
2338
;                5 - file not found
-
 
2339
;               10 - access denied
-
 
2340
;          ebx = file date/time
-
 
2341
;                bits 31..25 = year-1980
-
 
2342
;                bits 24..21 = month
-
 
2343
;                bits 20..16 = day
-
 
2344
;                bits 15..11 = hour
-
 
2345
;                bits 10..5  = minute
-
 
2346
;                bits 4..0   = second/2
-
 
2347
;-----------------------------------------------------------
-
 
2348
    cmp   [fat_type],0
-
 
2349
    jnz   get_filedate_fat_ok
-
 
2350
    xor   ebx,ebx
-
 
2351
    mov   eax,ERROR_UNKNOWN_FS
-
 
2352
    ret
-
 
2353
 
-
 
2354
  get_filedate_fat_ok:
-
 
2355
;    call  reserve_hd1
-
 
2356
 
-
 
2357
    pushad
-
 
2358
    mov   ebx,edx
-
 
2359
    call  get_cluster_of_a_path
-
 
2360
    jc    get_filedate_not_found
-
 
2361
 
-
 
2362
    mov   ebx,PUSHAD_EAX        ; file name
-
 
2363
    call  analyze_directory
-
 
2364
    jc    get_filedate_not_found
-
 
2365
 
-
 
2366
    mov   eax,[ebx+22]          ; file date/time
-
 
2367
    mov   PUSHAD_EBX,eax
-
 
2368
    popad
-
 
2369
    mov   [hd1_status],0
-
 
2370
    xor   eax,eax
-
 
2371
    ret
-
 
2372
 
-
 
2373
  get_filedate_not_found:
-
 
2374
    cmp   [hd_error],0
-
 
2375
    jne   get_filedate_access_denied
-
 
2376
    popad
-
 
2377
    mov   [hd1_status],0
-
 
2378
    xor   ebx,ebx
-
 
2379
    mov   eax,ERROR_FILE_NOT_FOUND
-
 
2380
    ret
-
 
2381
 
-
 
2382
  get_filedate_access_denied:
-
 
2383
    popad
-
 
2384
    mov   [hd1_status],0
-
 
2385
    xor   ebx,ebx
-
 
2386
    mov   eax,ERROR_ACCESS_DENIED
-
 
2387
    ret
-
 
2388
 
2210
 
2389
get_hd_info:
2211
get_hd_info:
2390
;-----------------------------------------------------------
2212
;-----------------------------------------------------------
2391
; output : eax = 0 - ok
2213
; output : eax = 0 - ok
2392
;                3 - unknown FS
2214
;                3 - unknown FS
2393
;               10 - access denied
2215
;               10 - access denied
2394
;          edx = cluster size in bytes
2216
;          edx = cluster size in bytes
2395
;          ebx = total clusters on disk
2217
;          ebx = total clusters on disk
2396
;          ecx = free clusters on disk
2218
;          ecx = free clusters on disk
2397
;-----------------------------------------------------------
2219
;-----------------------------------------------------------
2398
    cmp   [fat_type],0
2220
    cmp   [fat_type],0
2399
    jnz   info_fat_ok
2221
    jnz   info_fat_ok
2400
    xor   edx,edx
2222
    xor   edx,edx
2401
    xor   ebx,ebx
2223
    xor   ebx,ebx
2402
    xor   ecx,ecx
2224
    xor   ecx,ecx
2403
    mov   eax,ERROR_UNKNOWN_FS
2225
    mov   eax,ERROR_UNKNOWN_FS
2404
    ret
2226
    ret
2405
 
2227
 
2406
  info_fat_ok:
2228
  info_fat_ok:
2407
;    call  reserve_hd1
2229
;    call  reserve_hd1
2408
 
2230
 
2409
    xor   ecx,ecx               ; count of free clusters
2231
    xor   ecx,ecx               ; count of free clusters
2410
    mov   eax,2
2232
    mov   eax,2
2411
    mov   ebx,[LAST_CLUSTER]
2233
    mov   ebx,[LAST_CLUSTER]
2412
 
2234
 
2413
  info_cluster:
2235
  info_cluster:
2414
    push  eax
2236
    push  eax
2415
    call  get_FAT               ; get cluster info
2237
    call  get_FAT               ; get cluster info
2416
    cmp   [hd_error],0
2238
    cmp   [hd_error],0
2417
    jne   info_access_denied
2239
    jne   info_access_denied
2418
 
2240
 
2419
    test  eax,eax               ; is it free?
2241
    test  eax,eax               ; is it free?
2420
    jnz   info_used             ; no
2242
    jnz   info_used             ; no
2421
    inc   ecx
2243
    inc   ecx
2422
 
2244
 
2423
  info_used:
2245
  info_used:
2424
    pop   eax
2246
    pop   eax
2425
    inc   eax
2247
    inc   eax
2426
    cmp   eax,ebx               ; is above last cluster?
2248
    cmp   eax,ebx               ; is above last cluster?
2427
    jbe   info_cluster          ; no. test next cluster
2249
    jbe   info_cluster          ; no. test next cluster
2428
 
2250
 
2429
    dec   ebx                   ; cluster count
2251
    dec   ebx                   ; cluster count
2430
    imul  edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
2252
    imul  edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
2431
    mov   [hd1_status],0
2253
    mov   [hd1_status],0
2432
    xor   eax,eax
2254
    xor   eax,eax
2433
    ret
2255
    ret
2434
 
2256
 
2435
  info_access_denied:
2257
  info_access_denied:
2436
    add   esp,4 
2258
    add   esp,4 
2437
    xor   edx,edx
2259
    xor   edx,edx
2438
    xor   ebx,ebx
2260
    xor   ebx,ebx
2439
    xor   ecx,ecx
2261
    xor   ecx,ecx
2440
    mov   eax,ERROR_ACCESS_DENIED
2262
    mov   eax,ERROR_ACCESS_DENIED
2441
    ret
2263
    ret
2442
 
2264
 
2443
update_disk:
2265
update_disk:
2444
;-----------------------------------------------------------
2266
;-----------------------------------------------------------
2445
; write changed fat and cache to disk
2267
; write changed fat and cache to disk
2446
;-----------------------------------------------------------
2268
;-----------------------------------------------------------
2447
    cmp   [fat_change],0        ; is fat changed?
2269
    cmp   [fat_change],0        ; is fat changed?
2448
    je    upd_no_change
2270
    je    upd_no_change
2449
 
2271
 
2450
    call  write_fat_sector
2272
    call  write_fat_sector
2451
    cmp   [hd_error],0
2273
    cmp   [hd_error],0
2452
    jne   update_disk_acces_denied
2274
    jne   update_disk_acces_denied
2453
 
2275
 
2454
  upd_no_change:
2276
  upd_no_change:
2455
 
2277
 
2456
    call  write_cache
2278
    call  write_cache
2457
  update_disk_acces_denied:
2279
  update_disk_acces_denied:
2458
    ret
2280
    ret
2459
 
2281
 
2460
 
2282
 
2461
;**************************************************************************
2283
;**************************************************************************
2462
;
2284
;
2463
;   0x600008  - first entry in cache list
2285
;   0x600008  - first entry in cache list
2464
;
2286
;
2465
;            +0   - lba sector
2287
;            +0   - lba sector
2466
;            +4   - state of cache sector
2288
;            +4   - state of cache sector
2467
;                   0 = empty
2289
;                   0 = empty
2468
;                   1 = used for read  ( same as in hd )
2290
;                   1 = used for read  ( same as in hd )
2469
;                   2 = used for write ( differs from hd )
2291
;                   2 = used for write ( differs from hd )
2470
;
2292
;
2471
;      +65536 - cache entries
2293
;      +65536 - cache entries
2472
;
2294
;
2473
;**************************************************************************
2295
;**************************************************************************
2474
 
2296
 
2475
 
2297
 
2476
hd_read:
2298
hd_read:
2477
;-----------------------------------------------------------
2299
;-----------------------------------------------------------
2478
; input  : eax = block to read
2300
; input  : eax = block to read
2479
;          ebx = destination
2301
;          ebx = destination
2480
;-----------------------------------------------------------
2302
;-----------------------------------------------------------
2481
    push  ecx esi edi           ; scan cache
2303
    push  ecx esi edi           ; scan cache
2482
 
2304
 
2483
    mov   ecx,cache_max         ; entries in cache
2305
    mov   ecx,cache_max         ; entries in cache
2484
    mov   esi,0x600000+8
2306
    mov   esi,0x600000+8
2485
    mov   edi,1
2307
    mov   edi,1
2486
 
2308
 
2487
  hdreadcache:
2309
  hdreadcache:
2488
 
2310
 
2489
    cmp   dword [esi+4],0       ; empty
2311
    cmp   dword [esi+4],0       ; empty
2490
    je    nohdcache
2312
    je    nohdcache
2491
 
2313
 
2492
    cmp   [esi],eax             ; correct sector
2314
    cmp   [esi],eax             ; correct sector
2493
    je    yeshdcache
2315
    je    yeshdcache
2494
 
2316
 
2495
  nohdcache:
2317
  nohdcache:
2496
 
2318
 
2497
    add   esi,8
2319
    add   esi,8
2498
    inc   edi
2320
    inc   edi
2499
    dec   ecx
2321
    dec   ecx
2500
    jnz   hdreadcache
2322
    jnz   hdreadcache
2501
 
2323
 
2502
    call  find_empty_slot       ; ret in edi
2324
    call  find_empty_slot       ; ret in edi
2503
    cmp   [hd_error],0
2325
    cmp   [hd_error],0
2504
    jne   return_01
2326
    jne   return_01
2505
 
2327
 
2506
    push  eax edx
2328
    push  eax edx
2507
 
2329
 
2508
    call  wait_for_hd_idle
2330
    call  wait_for_hd_idle
2509
    cmp   [hd_error],0
2331
    cmp   [hd_error],0
2510
    jne   hd_read_error    
2332
    jne   hd_read_error    
2511
 
2333
 
2512
    cli
2334
    cli
2513
    xor   eax,eax
2335
    xor   eax,eax
2514
    mov   edx,[hdbase]
2336
    mov   edx,[hdbase]
2515
    inc   edx
2337
    inc   edx
2516
    out   dx,al   ; ATAFeatures ॣ¨áâà "®á®¡¥­­®á⥩"
2338
    out   dx,al   ; ATAFeatures ॣ¨áâà "®á®¡¥­­®á⥩"
2517
    inc   edx
2339
    inc   edx
2518
    inc   eax
2340
    inc   eax
2519
    out   dx,al   ; ATASectorCount áç¥â稪 ᥪâ®à®¢
2341
    out   dx,al   ; ATASectorCount áç¥â稪 ᥪâ®à®¢
2520
    inc   edx
2342
    inc   edx
2521
    mov   eax,[esp+4]
2343
    mov   eax,[esp+4]
2522
    out   dx,al   ; ATASectorNumber ॣ¨áâà ­®¬¥à  ᥪâ®à 
2344
    out   dx,al   ; ATASectorNumber ॣ¨áâà ­®¬¥à  ᥪâ®à 
2523
    shr   eax,8
2345
    shr   eax,8
2524
    inc   edx
2346
    inc   edx
2525
    out   dx,al   ; ATACylinder ­®¬¥à 樫¨­¤à  (¬« ¤è¨© ¡ ©â)
2347
    out   dx,al   ; ATACylinder ­®¬¥à 樫¨­¤à  (¬« ¤è¨© ¡ ©â)
2526
    shr   eax,8
2348
    shr   eax,8
2527
    inc   edx
2349
    inc   edx
2528
    out   dx,al   ; ­®¬¥à 樫¨­¤à  (áâ à訩 ¡ ©â)
2350
    out   dx,al   ; ­®¬¥à 樫¨­¤à  (áâ à訩 ¡ ©â)
2529
    shr   eax,8
2351
    shr   eax,8
2530
    inc   edx
2352
    inc   edx
2531
    and   al,1+2+4+8
2353
    and   al,1+2+4+8
2532
    add   al,byte [hdid]
2354
    add   al,byte [hdid]
2533
    add   al,128+64+32
2355
    add   al,128+64+32
2534
    out   dx,al   ; ­®¬¥à £®«®¢ª¨/­®¬¥à ¤¨áª 
2356
    out   dx,al   ; ­®¬¥à £®«®¢ª¨/­®¬¥à ¤¨áª 
2535
    inc   edx
2357
    inc   edx
2536
    mov   al,20h
2358
    mov   al,20h
2537
    out   dx,al   ; ATACommand ॣ¨áâà ª®¬ ­¤
2359
    out   dx,al   ; ATACommand ॣ¨áâà ª®¬ ­¤
2538
    sti
2360
    sti
2539
 
2361
 
2540
    call  wait_for_sector_buffer
2362
    call  wait_for_sector_buffer
2541
 
2363
 
2542
    cmp   [hd_error],0
2364
    cmp   [hd_error],0
2543
    jne   hd_read_error
2365
    jne   hd_read_error
2544
 
2366
 
2545
    cli
2367
    cli
2546
    push  edi
2368
    push  edi
2547
    shl   edi,9
2369
    shl   edi,9
2548
    add   edi,0x600000+65536
2370
    add   edi,0x600000+65536
2549
    mov   ecx,256
2371
    mov   ecx,256
2550
    mov   edx,[hdbase]
2372
    mov   edx,[hdbase]
2551
    cld
2373
    cld
2552
    rep   insw
2374
    rep   insw
2553
    pop   edi
2375
    pop   edi
2554
    sti
2376
    sti
2555
 
2377
 
2556
    pop   edx eax
2378
    pop   edx eax
2557
 blok_read_2:
2379
 blok_read_2:
2558
    lea   esi,[edi*8+0x600000]
2380
    lea   esi,[edi*8+0x600000]
2559
    mov   [esi],eax             ; sector number
2381
    mov   [esi],eax             ; sector number
2560
    mov   dword [esi+4],1       ; hd read - mark as same as in hd
2382
    mov   dword [esi+4],1       ; hd read - mark as same as in hd
2561
 
2383
 
2562
  yeshdcache:
2384
  yeshdcache:
2563
 
2385
 
2564
    mov   esi,edi
2386
    mov   esi,edi
2565
    shl   esi,9
2387
    shl   esi,9
2566
    add   esi,0x600000+65536
2388
    add   esi,0x600000+65536
2567
    mov   edi,ebx
2389
    mov   edi,ebx
2568
    mov   ecx,512/4
2390
    mov   ecx,512/4
2569
    cld
2391
    cld
2570
    rep   movsd                 ; move data
2392
    rep   movsd                 ; move data
2571
 return_01:
2393
 return_01:
2572
    pop   edi esi ecx
2394
    pop   edi esi ecx
2573
    ret
2395
    ret
2574
    
2396
    
2575
 
2397
 
2576
hd_write:
2398
hd_write:
2577
;-----------------------------------------------------------
2399
;-----------------------------------------------------------
2578
; input  : eax = block
2400
; input  : eax = block
2579
;          ebx = pointer to memory
2401
;          ebx = pointer to memory
2580
;-----------------------------------------------------------
2402
;-----------------------------------------------------------
2581
    push  ecx esi edi
2403
    push  ecx esi edi
2582
 
2404
 
2583
    ; check if the cache already has the sector and overwrite it
2405
    ; check if the cache already has the sector and overwrite it
2584
 
2406
 
2585
    mov   ecx,cache_max
2407
    mov   ecx,cache_max
2586
    mov   esi,0x600000+8
2408
    mov   esi,0x600000+8
2587
    mov   edi,1
2409
    mov   edi,1
2588
 
2410
 
2589
  hdwritecache:
2411
  hdwritecache:
2590
 
2412
 
2591
    cmp   dword [esi+4],0       ; if cache slot is empty
2413
    cmp   dword [esi+4],0       ; if cache slot is empty
2592
    je    not_in_cache_write
2414
    je    not_in_cache_write
2593
 
2415
 
2594
    cmp   [esi],eax             ; if the slot has the sector
2416
    cmp   [esi],eax             ; if the slot has the sector
2595
    je    yes_in_cache_write
2417
    je    yes_in_cache_write
2596
 
2418
 
2597
  not_in_cache_write:
2419
  not_in_cache_write:
2598
 
2420
 
2599
    add   esi,8
2421
    add   esi,8
2600
    inc   edi
2422
    inc   edi
2601
    dec   ecx
2423
    dec   ecx
2602
    jnz   hdwritecache
2424
    jnz   hdwritecache
2603
 
2425
 
2604
    ; sector not found in cache
2426
    ; sector not found in cache
2605
    ; write the block to a new location
2427
    ; write the block to a new location
2606
 
2428
 
2607
    call  find_empty_slot       ; ret in edi
2429
    call  find_empty_slot       ; ret in edi
2608
    cmp   [hd_error],0
2430
    cmp   [hd_error],0
2609
    jne   hd_write_access_denied
2431
    jne   hd_write_access_denied
2610
 
2432
 
2611
    lea   esi,[edi*8+0x600000]
2433
    lea   esi,[edi*8+0x600000]
2612
    mov   [esi],eax             ; sector number
2434
    mov   [esi],eax             ; sector number
2613
 
2435
 
2614
  yes_in_cache_write:
2436
  yes_in_cache_write:
2615
 
2437
 
2616
    mov   dword [esi+4],2       ; write - differs from hd
2438
    mov   dword [esi+4],2       ; write - differs from hd
2617
 
2439
 
2618
    shl   edi,9
2440
    shl   edi,9
2619
    add   edi,0x600000+65536
2441
    add   edi,0x600000+65536
2620
    mov   esi,ebx
2442
    mov   esi,ebx
2621
    mov   ecx,512/4
2443
    mov   ecx,512/4
2622
    cld
2444
    cld
2623
    rep   movsd                 ; move data
2445
    rep   movsd                 ; move data
2624
 hd_write_access_denied:
2446
 hd_write_access_denied:
2625
    pop   edi esi ecx
2447
    pop   edi esi ecx
2626
    ret
2448
    ret
2627
 
2449
 
2628
 
2450
 
2629
write_cache:
2451
write_cache:
2630
;-----------------------------------------------------------
2452
;-----------------------------------------------------------
2631
; write all changed sectors to disk
2453
; write all changed sectors to disk
2632
;-----------------------------------------------------------
2454
;-----------------------------------------------------------
2633
    push  eax ecx edx esi edi
2455
    push  eax ecx edx esi edi
2634
 
2456
 
2635
    ; write difference ( 2 ) from cache to hd
2457
    ; write difference ( 2 ) from cache to hd
2636
 
2458
 
2637
    mov   ecx,cache_max
2459
    mov   ecx,cache_max
2638
    mov   esi,0x600000+8
2460
    mov   esi,0x600000+8
2639
    mov   edi,1
2461
    mov   edi,1
2640
 
2462
 
2641
  write_cache_more:
2463
  write_cache_more:
2642
 
2464
 
2643
    cmp   dword [esi+4],2       ; if cache slot is not different
2465
    cmp   dword [esi+4],2       ; if cache slot is not different
2644
    jne   does_not_need_writing
2466
    jne   does_not_need_writing
2645
 
2467
 
2646
    mov   dword [esi+4],1       ; same as in hd
2468
    mov   dword [esi+4],1       ; same as in hd
2647
    mov   eax,[esi]             ; eax = sector to write
2469
    mov   eax,[esi]             ; eax = sector to write
2648
 
2470
 
2649
    cmp   eax,[PARTITION_START]
2471
    cmp   eax,[PARTITION_START]
2650
    jb    danger
2472
    jb    danger
2651
    cmp   eax,[PARTITION_END]
2473
    cmp   eax,[PARTITION_END]
2652
    ja    danger
2474
    ja    danger
2653
 
2475
 
2654
    call  wait_for_hd_idle
2476
    call  wait_for_hd_idle
2655
    cmp   [hd_error],0
2477
    cmp   [hd_error],0
2656
    jne   hd_write_error
2478
    jne   hd_write_error
2657
 
2479
 
2658
    cli
2480
    cli
2659
    xor   eax,eax
2481
    xor   eax,eax
2660
    mov   edx,[hdbase]
2482
    mov   edx,[hdbase]
2661
    inc   edx
2483
    inc   edx
2662
    out   dx,al
2484
    out   dx,al
2663
    inc   edx
2485
    inc   edx
2664
    inc   eax
2486
    inc   eax
2665
    out   dx,al
2487
    out   dx,al
2666
    inc   edx
2488
    inc   edx
2667
    mov   eax,[esi]             ; eax = sector to write
2489
    mov   eax,[esi]             ; eax = sector to write
2668
    out   dx,al
2490
    out   dx,al
2669
    shr   eax,8
2491
    shr   eax,8
2670
    inc   edx
2492
    inc   edx
2671
    out   dx,al
2493
    out   dx,al
2672
    shr   eax,8
2494
    shr   eax,8
2673
    inc   edx
2495
    inc   edx
2674
    out   dx,al
2496
    out   dx,al
2675
    shr   eax,8
2497
    shr   eax,8
2676
    inc   edx
2498
    inc   edx
2677
    and   al,1+2+4+8
2499
    and   al,1+2+4+8
2678
    add   al,byte [hdid]
2500
    add   al,byte [hdid]
2679
    add   al,128+64+32
2501
    add   al,128+64+32
2680
    out   dx,al
2502
    out   dx,al
2681
    inc   edx
2503
    inc   edx
2682
    mov   al,30h
2504
    mov   al,30h
2683
    out   dx,al
2505
    out   dx,al
2684
    sti
2506
    sti
2685
 
2507
 
2686
    call  wait_for_sector_buffer
2508
    call  wait_for_sector_buffer
2687
 
2509
 
2688
    cmp   [hd_error],0
2510
    cmp   [hd_error],0
2689
    jne   hd_write_error
2511
    jne   hd_write_error
2690
 
2512
 
2691
    push  ecx esi
2513
    push  ecx esi
2692
 
2514
 
2693
    cli
2515
    cli
2694
    mov   esi,edi
2516
    mov   esi,edi
2695
    shl   esi,9
2517
    shl   esi,9
2696
    add   esi,0x600000+65536    ; esi = from memory position
2518
    add   esi,0x600000+65536    ; esi = from memory position
2697
    mov   ecx,256
2519
    mov   ecx,256
2698
    mov   edx,[hdbase]
2520
    mov   edx,[hdbase]
2699
    cld
2521
    cld
2700
    rep   outsw
2522
    rep   outsw
2701
    sti
2523
    sti
2702
 
2524
 
2703
    pop   esi ecx
2525
    pop   esi ecx
2704
 
2526
 
2705
  danger:
2527
  danger:
2706
  does_not_need_writing:
2528
  does_not_need_writing:
2707
 
2529
 
2708
    add   esi,8
2530
    add   esi,8
2709
    inc   edi
2531
    inc   edi
2710
    dec   ecx
2532
    dec   ecx
2711
    jnz   write_cache_more
2533
    jnz   write_cache_more
2712
 return_02:
2534
 return_02:
2713
    pop   edi esi edx ecx eax
2535
    pop   edi esi edx ecx eax
2714
    ret
2536
    ret
2715
 
2537
 
2716
 
2538
 
2717
find_empty_slot:
2539
find_empty_slot:
2718
;-----------------------------------------------------------
2540
;-----------------------------------------------------------
2719
; find empty or read slot, flush cache if next 10% is used by write
2541
; find empty or read slot, flush cache if next 10% is used by write
2720
; output : edi = cache slot
2542
; output : edi = cache slot
2721
;-----------------------------------------------------------
2543
;-----------------------------------------------------------
2722
    push  ecx esi
2544
    push  ecx esi
2723
 
2545
 
2724
  search_again:
2546
  search_again:
2725
 
2547
 
2726
    mov   ecx,cache_max*10/100
2548
    mov   ecx,cache_max*10/100
2727
    mov   edi,[cache_search_start]
2549
    mov   edi,[cache_search_start]
2728
 
2550
 
2729
  search_for_empty:
2551
  search_for_empty:
2730
 
2552
 
2731
    inc   edi
2553
    inc   edi
2732
    cmp   edi,cache_max
2554
    cmp   edi,cache_max
2733
    jbe   inside_cache
2555
    jbe   inside_cache
2734
    mov   edi,1
2556
    mov   edi,1
2735
 
2557
 
2736
  inside_cache:
2558
  inside_cache:
2737
 
2559
 
2738
    cmp   dword [edi*8+0x600000+4],2    ; get cache slot info
2560
    cmp   dword [edi*8+0x600000+4],2    ; get cache slot info
2739
    jb    found_slot                    ; it's empty or read
2561
    jb    found_slot                    ; it's empty or read
2740
    dec   ecx
2562
    dec   ecx
2741
    jnz   search_for_empty
2563
    jnz   search_for_empty
2742
 
2564
 
2743
    call  write_cache                   ; no empty slots found, write all
2565
    call  write_cache                   ; no empty slots found, write all
2744
    cmp   [hd_error],0
2566
    cmp   [hd_error],0
2745
    jne   found_slot_access_denied
2567
    jne   found_slot_access_denied
2746
 
2568
 
2747
    jmp   search_again                  ; and start again
2569
    jmp   search_again                  ; and start again
2748
 
2570
 
2749
  found_slot:
2571
  found_slot:
2750
 
2572
 
2751
    mov   [cache_search_start],edi
2573
    mov   [cache_search_start],edi
2752
  found_slot_access_denied:
2574
  found_slot_access_denied:
2753
    pop   esi ecx
2575
    pop   esi ecx
2754
    ret
2576
    ret
2755
 
2577
 
2756
 
2578
 
2757
save_hd_wait_timeout:
2579
save_hd_wait_timeout:
2758
 
2580
 
2759
    push  eax
2581
    push  eax
2760
    mov   eax,[timer_ticks];[0xfdf0]
2582
    mov   eax,[timer_ticks];[0xfdf0]
2761
    add   eax,300               ; 3 sec timeout
2583
    add   eax,300               ; 3 sec timeout
2762
    mov   [hd_wait_timeout],eax
2584
    mov   [hd_wait_timeout],eax
2763
    pop   eax
2585
    pop   eax
2764
    ret
2586
    ret
2765
 
2587
 
2766
 
2588
 
2767
check_hd_wait_timeout:
2589
check_hd_wait_timeout:
2768
 
2590
 
2769
    push  eax
2591
    push  eax
2770
    mov   eax,[hd_wait_timeout]
2592
    mov   eax,[hd_wait_timeout]
2771
    cmp   [timer_ticks], eax ;[0xfdf0],eax
2593
    cmp   [timer_ticks], eax ;[0xfdf0],eax
2772
    jg    hd_timeout_error
2594
    jg    hd_timeout_error
2773
    pop   eax
2595
    pop   eax
2774
    mov   [hd_error],0
2596
    mov   [hd_error],0
2775
    ret
2597
    ret
2776
 
2598
 
2777
iglobal
2599
iglobal
2778
  hd_timeout_str   db 'K : FS - HD timeout',13,10,0
2600
  hd_timeout_str   db 'K : FS - HD timeout',13,10,0
2779
  hd_read_str      db 'K : FS - HD read error',13,10,0
2601
  hd_read_str      db 'K : FS - HD read error',13,10,0
2780
  hd_write_str     db 'K : FS - HD write error',13,10,0
2602
  hd_write_str     db 'K : FS - HD write error',13,10,0
2781
  hd_lba_str       db 'K : FS - HD LBA error',13,10,0
2603
  hd_lba_str       db 'K : FS - HD LBA error',13,10,0
2782
endg
2604
endg
2783
 
2605
 
2784
hd_timeout_error:
2606
hd_timeout_error:
2785
 
2607
 
2786
    call  clear_hd_cache
2608
    call  clear_hd_cache
2787
    call  clear_application_table_status
2609
    call  clear_application_table_status
2788
    mov   esi,hd_timeout_str
2610
    mov   esi,hd_timeout_str
2789
    call  sys_msg_board_str
2611
    call  sys_msg_board_str
2790
;    jmp   $
2612
;    jmp   $
2791
    mov   [hd_error],1
2613
    mov   [hd_error],1
2792
    pop   eax
2614
    pop   eax
2793
    ret
2615
    ret
2794
 
2616
 
2795
hd_read_error:
2617
hd_read_error:
2796
 
2618
 
2797
    call  clear_hd_cache
2619
    call  clear_hd_cache
2798
    call  clear_application_table_status
2620
    call  clear_application_table_status
2799
    mov   esi,hd_read_str
2621
    mov   esi,hd_read_str
2800
    call  sys_msg_board_str
2622
    call  sys_msg_board_str
2801
    pop   edx eax
2623
    pop   edx eax
2802
    jmp    return_01
2624
    jmp    return_01
2803
;    jmp   $
2625
;    jmp   $
2804
 
2626
 
2805
hd_write_error:
2627
hd_write_error:
2806
 
2628
 
2807
    call  clear_hd_cache
2629
    call  clear_hd_cache
2808
    call  clear_application_table_status
2630
    call  clear_application_table_status
2809
    mov   esi,hd_write_str
2631
    mov   esi,hd_write_str
2810
    call  sys_msg_board_str
2632
    call  sys_msg_board_str
2811
    jmp    return_02
2633
    jmp    return_02
2812
;    jmp   $
2634
;    jmp   $
2813
 
2635
 
2814
hd_lba_error:
2636
hd_lba_error:
2815
    call  clear_hd_cache
2637
    call  clear_hd_cache
2816
    call  clear_application_table_status
2638
    call  clear_application_table_status
2817
    mov   esi,hd_lba_str
2639
    mov   esi,hd_lba_str
2818
    call  sys_msg_board_str
2640
    call  sys_msg_board_str
2819
    jmp   LBA_read_ret
2641
    jmp   LBA_read_ret
2820
 
2642
 
2821
 
2643
 
2822
wait_for_hd_idle:
2644
wait_for_hd_idle:
2823
 
2645
 
2824
    push  eax edx
2646
    push  eax edx
2825
 
2647
 
2826
    call  save_hd_wait_timeout
2648
    call  save_hd_wait_timeout
2827
 
2649
 
2828
    mov   edx,[hdbase]
2650
    mov   edx,[hdbase]
2829
    add   edx,0x7
2651
    add   edx,0x7
2830
 
2652
 
2831
  wfhil1:
2653
  wfhil1:
2832
 
2654
 
2833
    call  check_hd_wait_timeout
2655
    call  check_hd_wait_timeout
2834
    cmp   [hd_error],0
2656
    cmp   [hd_error],0
2835
    jne   @f
2657
    jne   @f
2836
 
2658
 
2837
    in    al,dx
2659
    in    al,dx
2838
    test  al,128
2660
    test  al,128
2839
    jnz   wfhil1
2661
    jnz   wfhil1
2840
  
2662
  
2841
 @@:
2663
 @@:
2842
 
2664
 
2843
    pop   edx eax
2665
    pop   edx eax
2844
    ret
2666
    ret
2845
 
2667
 
2846
 
2668
 
2847
 
2669
 
2848
wait_for_sector_buffer:
2670
wait_for_sector_buffer:
2849
 
2671
 
2850
    push  eax edx
2672
    push  eax edx
2851
 
2673
 
2852
    mov   edx,[hdbase]
2674
    mov   edx,[hdbase]
2853
    add   edx,0x7
2675
    add   edx,0x7
2854
 
2676
 
2855
    call  save_hd_wait_timeout
2677
    call  save_hd_wait_timeout
2856
 
2678
 
2857
  hdwait_sbuf:                  ; wait for sector buffer to be ready
2679
  hdwait_sbuf:                  ; wait for sector buffer to be ready
2858
 
2680
 
2859
    call  check_hd_wait_timeout
2681
    call  check_hd_wait_timeout
2860
    cmp   [hd_error],0
2682
    cmp   [hd_error],0
2861
    jne   @f
2683
    jne   @f
2862
 
2684
 
2863
    in    al,dx
2685
    in    al,dx
2864
    test  al,8
2686
    test  al,8
2865
    jz    hdwait_sbuf
2687
    jz    hdwait_sbuf
2866
 
2688
 
2867
    mov   [hd_error],0
2689
    mov   [hd_error],0
2868
 
2690
 
2869
    cmp   [hd_setup],1          ; do not mark error for setup request
2691
    cmp   [hd_setup],1          ; do not mark error for setup request
2870
    je    buf_wait_ok
2692
    je    buf_wait_ok
2871
 
2693
 
2872
    test  al,1                  ; previous command ended up with an error
2694
    test  al,1                  ; previous command ended up with an error
2873
    jz    buf_wait_ok
2695
    jz    buf_wait_ok
2874
 @@:
2696
 @@:
2875
    mov   [hd_error],1
2697
    mov   [hd_error],1
2876
 
2698
 
2877
  buf_wait_ok:
2699
  buf_wait_ok:
2878
 
2700
 
2879
    pop   edx eax
2701
    pop   edx eax
2880
    ret
2702
    ret
2881
 
2703
 
2882
 
2704
 
2883
 
2705
 
2884
read_hd_file:
2706
read_hd_file:
2885
;-----------------------------------------------------------------
2707
;-----------------------------------------------------------------
2886
;
2708
;
2887
; Converting old reading function for hd-application start.
2709
; Converting old reading function for hd-application start.
2888
;
2710
;
2889
; IN:
2711
; IN:
2890
;
2712
;
2891
; eax - pointer to file (0 = read only first sector of drive: eg 'label')
2713
; eax - pointer to file (0 = read only first sector of drive: eg 'label')
2892
; ebx - file lenght
2714
; ebx - file lenght
2893
; ecx - start 512 byte block number
2715
; ecx - start 512 byte block number
2894
; edx - number of blocks to read
2716
; edx - number of blocks to read
2895
; esi - pointer to return/work area (atleast 20 000 bytes)
2717
; esi - pointer to return/work area (atleast 20 000 bytes)
2896
;
2718
;
2897
; For new read function
2719
; For new read function
2898
;
2720
;
2899
; EAX   (PAR0)      pointer to file-name
2721
; EAX   (PAR0)      pointer to file-name
2900
; ECX   (PAR1)      pointer to buffer
2722
; ECX   (PAR1)      pointer to buffer
2901
; EBX   (PAR2)   vt file blocks to read
2723
; EBX   (PAR2)   vt file blocks to read
2902
; EDX   (PAR3)      pointer to path
2724
; EDX   (PAR3)      pointer to path
2903
; ESI            vt first 512 block to read
2725
; ESI            vt first 512 block to read
2904
; EDI               if 0 - return root
2726
; EDI               if 0 - return root
2905
;--------------------------------------------------------------------------
2727
;--------------------------------------------------------------------------
2906
 
2728
 
2907
    push  ecx esi edi
2729
    push  ecx esi edi
2908
    mov   esi,eax
2730
    mov   esi,eax
2909
    mov   edi,startpath
2731
    mov   edi,startpath
2910
    mov   ecx,250
2732
    mov   ecx,250
2911
    cld
2733
    cld
2912
    rep   movsb
2734
    rep   movsb
2913
    pop   edi esi ecx
2735
    pop   edi esi ecx
2914
 
2736
 
2915
    mov   eax,startpath
2737
    mov   eax,startpath
2916
    mov   [eax+ebx-12],byte 0
2738
    mov   [eax+ebx-12],byte 0
2917
 
2739
 
2918
    push  eax ebx ecx edx esi
2740
    push  eax ebx ecx edx esi
2919
 
2741
 
2920
    pop   ecx ; pointer to buffer
2742
    pop   ecx ; pointer to buffer
2921
    add   ecx,1024
2743
    add   ecx,1024
2922
    pop   ebx ; number of blocks to read
2744
    pop   ebx ; number of blocks to read
2923
    pop   esi ; first block to read
2745
    pop   esi ; first block to read
2924
    dec   esi
2746
    dec   esi
2925
    pop   eax ; file length
2747
    pop   eax ; file length
2926
    pop   edx ; pointer to path
2748
    pop   edx ; pointer to path
2927
 
2749
 
2928
    mov   edi,12
2750
    mov   edi,12
2929
    lea   eax,[eax+edx-12+1]
2751
    lea   eax,[eax+edx-12+1]
2930
    call  file_read
2752
    call  file_read
2931
 
2753
 
2932
    ret
2754
    ret
2933
 
2755
 
2934
; \begin{diamond}
2756
; \begin{diamond}
2935
hd_find_lfn:
2757
hd_find_lfn:
2936
; in: esi->name
2758
; in: esi->name
2937
; out: CF=1 - file not found
2759
; out: CF=1 - file not found
2938
;      else CF=0 and edi->direntry, eax=sector
2760
;      else CF=0 and edi->direntry, eax=sector
2939
; destroys eax
2761
; destroys eax
2940
        push    esi edi
2762
        push    esi edi
2941
        push    0
2763
        push    0
2942
        push    0
2764
        push    0
2943
        push    fat16_root_first
2765
        push    fat16_root_first
2944
        push    fat16_root_next
2766
        push    fat16_root_next
2945
        mov     eax, [ROOT_CLUSTER]
2767
        mov     eax, [ROOT_CLUSTER]
2946
        cmp     [fat_type], 32
2768
        cmp     [fat_type], 32
2947
        jz      .fat32
2769
        jz      .fat32
2948
.loop:
2770
.loop:
2949
        call    fat_find_lfn
2771
        call    fat_find_lfn
2950
        jc      .notfound
2772
        jc      .notfound
2951
        cmp     byte [esi], 0
2773
        cmp     byte [esi], 0
2952
        jz      .found
2774
        jz      .found
2953
        test    byte [edi+11], 10h
2775
        test    byte [edi+11], 10h
2954
        jz      .notfound
2776
        jz      .notfound
2955
        and     dword [esp+12], 0
2777
        and     dword [esp+12], 0
-
 
2778
        mov     eax, [edi+20-2]
2956
        movzx   eax, word [edi+26]      ; cluster
2779
        mov     ax, [edi+26]    ; cluster
2957
.fat32:
2780
.fat32:
2958
        mov     [esp+8], eax
2781
        mov     [esp+8], eax
2959
        mov     dword [esp+4], fat_notroot_first
2782
        mov     dword [esp+4], fat_notroot_first
2960
        mov     dword [esp], fat_notroot_next
2783
        mov     dword [esp], fat_notroot_next
2961
        jmp     .loop
2784
        jmp     .loop
2962
.notfound:
2785
.notfound:
2963
        add     esp, 16
2786
        add     esp, 16
2964
        pop     edi esi
2787
        pop     edi esi
2965
        stc
2788
        stc
2966
        ret
2789
        ret
2967
.found:
2790
.found:
2968
        lea     eax, [esp+8]
2791
        lea     eax, [esp+8]
2969
        cmp     dword [eax], 0
2792
        cmp     dword [eax], 0
2970
        jz      .root
2793
        jz      .root
2971
        call    fat_get_sector
2794
        call    fat_get_sector
2972
        jmp     .cmn
2795
        jmp     .cmn
2973
.root:
2796
.root:
2974
        mov     eax, [eax+4]
2797
        mov     eax, [eax+4]
2975
        add     eax, [ROOT_START]
2798
        add     eax, [ROOT_START]
2976
.cmn:
2799
.cmn:
2977
        add     esp, 20         ; CF=0
2800
        add     esp, 20         ; CF=0
2978
        pop     esi
2801
        pop     esi
2979
        ret
2802
        ret
2980
 
2803
 
2981
;----------------------------------------------------------------
2804
;----------------------------------------------------------------
2982
;
2805
;
2983
;  fs_HdRead - LFN variant for reading hard disk
2806
;  fs_HdRead - LFN variant for reading hard disk
2984
;
2807
;
2985
;  esi  points to filename
2808
;  esi  points to filename
2986
;  ebx  pointer to 64-bit number = first wanted byte, 0+
2809
;  ebx  pointer to 64-bit number = first wanted byte, 0+
2987
;       may be ebx=0 - start from first byte
2810
;       may be ebx=0 - start from first byte
2988
;  ecx  number of bytes to read, 0+
2811
;  ecx  number of bytes to read, 0+
2989
;  edx  mem location to return data
2812
;  edx  mem location to return data
2990
;
2813
;
2991
;  ret ebx = bytes read or 0xffffffff file not found
2814
;  ret ebx = bytes read or 0xffffffff file not found
2992
;      eax = 0 ok read or other = errormsg
2815
;      eax = 0 ok read or other = errormsg
2993
;
2816
;
2994
;--------------------------------------------------------------
2817
;--------------------------------------------------------------
2995
fs_HdRead:
2818
fs_HdRead:
2996
    cmp    [fat_type], 0
2819
    cmp    [fat_type], 0
2997
    jnz    @f
2820
    jnz    @f
2998
    or    ebx, -1
2821
    or    ebx, -1
2999
    mov    eax, ERROR_UNKNOWN_FS
2822
    mov    eax, ERROR_UNKNOWN_FS
3000
    ret
2823
    ret
3001
@@:
2824
@@:
3002
    push    edi
2825
    push    edi
3003
    cmp    byte [esi], 0
2826
    cmp    byte [esi], 0
3004
    jnz    @f
2827
    jnz    @f
3005
.noaccess:
2828
.noaccess:
3006
    pop    edi
2829
    pop    edi
3007
.noaccess_2:
2830
.noaccess_2:
3008
    or    ebx, -1
2831
    or    ebx, -1
3009
    mov    eax, ERROR_ACCESS_DENIED
2832
    mov    eax, ERROR_ACCESS_DENIED
3010
    ret
2833
    ret
3011
 
2834
 
3012
.noaccess_3:
2835
.noaccess_3:
3013
    add esp,4
2836
    add esp,4
3014
.noaccess_1:
2837
.noaccess_1:
3015
    add esp,4
2838
    add esp,4
3016
.noaccess_4:
2839
.noaccess_4:
3017
    add esp,4*5
2840
    add esp,4*5
3018
    jmp  .noaccess_2
2841
    jmp  .noaccess_2
3019
 
2842
 
3020
@@:
2843
@@:
3021
    call    hd_find_lfn
2844
    call    hd_find_lfn
3022
    jnc    .found
2845
    jnc    .found
3023
    pop    edi
2846
    pop    edi
3024
    cmp   [hd_error],0
2847
    cmp   [hd_error],0
3025
    jne   .noaccess_2
2848
    jne   .noaccess_2
3026
    or    ebx, -1
2849
    or    ebx, -1
3027
    mov    eax, ERROR_FILE_NOT_FOUND
2850
    mov    eax, ERROR_FILE_NOT_FOUND
3028
    ret
2851
    ret
3029
 
2852
 
3030
.found:
2853
.found:
3031
    test    byte [edi+11], 0x10    ; do not allow read directories
2854
    test    byte [edi+11], 0x10    ; do not allow read directories
3032
    jnz    .noaccess
2855
    jnz    .noaccess
3033
    test    ebx, ebx
2856
    test    ebx, ebx
3034
    jz    .l1
2857
    jz    .l1
3035
    cmp    dword [ebx+4], 0
2858
    cmp    dword [ebx+4], 0
3036
    jz    @f
2859
    jz    @f
3037
        xor     ebx, ebx
2860
        xor     ebx, ebx
3038
.reteof:
2861
.reteof:
3039
    mov    eax, 6
2862
    mov    eax, 6
3040
    pop    edi
2863
    pop    edi
3041
    ret
2864
    ret
3042
@@:
2865
@@:
3043
    mov    ebx, [ebx]
2866
    mov    ebx, [ebx]
3044
.l1:
2867
.l1:
3045
        push    ecx edx
2868
        push    ecx edx
3046
        push    0
2869
        push    0
3047
        mov     eax, [edi+28]
2870
        mov     eax, [edi+28]
3048
        sub     eax, ebx
2871
        sub     eax, ebx
3049
        jb      .eof
2872
        jb      .eof
3050
        cmp     eax, ecx
2873
        cmp     eax, ecx
3051
        jae     @f
2874
        jae     @f
3052
        mov     ecx, eax
2875
        mov     ecx, eax
3053
        mov     byte [esp], 6
2876
        mov     byte [esp], 6
3054
@@:
2877
@@:
3055
    mov    eax, [edi+20-2]
2878
    mov    eax, [edi+20-2]
3056
    mov    ax, [edi+26]
2879
    mov    ax, [edi+26]
3057
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
2880
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
3058
.new_cluster:
2881
.new_cluster:
3059
    jecxz    .new_sector
2882
    jecxz    .new_sector
3060
    test    eax, eax
2883
    test    eax, eax
3061
    jz    .eof
2884
    jz    .eof
3062
    cmp    eax, [fatRESERVED]
2885
    cmp    eax, [fatRESERVED]
3063
    jae    .eof
2886
    jae    .eof
3064
    mov    [cluster_tmp], eax
2887
    mov    [cluster_tmp], eax
3065
    dec    eax
2888
    dec    eax
3066
    dec    eax
2889
    dec    eax
3067
    mov    edi, [SECTORS_PER_CLUSTER]
2890
    mov    edi, [SECTORS_PER_CLUSTER]
3068
    imul    eax, edi
2891
    imul    eax, edi
3069
    add    eax, [DATA_START]
2892
    add    eax, [DATA_START]
3070
.new_sector:
2893
.new_sector:
3071
    test    ecx, ecx
2894
    test    ecx, ecx
3072
    jz    .done
2895
    jz    .done
3073
    sub    ebx, 512
2896
    sub    ebx, 512
3074
    jae    .skip
2897
    jae    .skip
3075
    add    ebx, 512
2898
    add    ebx, 512
3076
    jnz    .force_buf
2899
    jnz    .force_buf
3077
    cmp    ecx, 512
2900
    cmp    ecx, 512
3078
    jb    .force_buf
2901
    jb    .force_buf
3079
; we may read directly to given buffer
2902
; we may read directly to given buffer
3080
    push    ebx
2903
    push    ebx
3081
    mov    ebx, edx
2904
    mov    ebx, edx
3082
    call    hd_read
2905
    call    hd_read
3083
    cmp  [hd_error],0
2906
    cmp  [hd_error],0
3084
    jne  .noaccess_1    
2907
    jne  .noaccess_1    
3085
    pop    ebx
2908
    pop    ebx
3086
    add    edx, 512
2909
    add    edx, 512
3087
    sub    ecx, 512
2910
    sub    ecx, 512
3088
    jmp    .skip
2911
    jmp    .skip
3089
.force_buf:
2912
.force_buf:
3090
; we must read sector to temporary buffer and then copy it to destination
2913
; we must read sector to temporary buffer and then copy it to destination
3091
    push    eax ebx
2914
    push    eax ebx
3092
    mov    ebx, buffer
2915
    mov    ebx, buffer
3093
    call    hd_read
2916
    call    hd_read
3094
    cmp  [hd_error],0
2917
    cmp  [hd_error],0
3095
    jne  .noaccess_3
2918
    jne  .noaccess_3
3096
 
2919
 
3097
    mov    eax, ebx
2920
    mov    eax, ebx
3098
    pop    ebx
2921
    pop    ebx
3099
    add    eax, ebx
2922
    add    eax, ebx
3100
    push    ecx
2923
    push    ecx
3101
    add    ecx, ebx
2924
    add    ecx, ebx
3102
    cmp    ecx, 512
2925
    cmp    ecx, 512
3103
    jbe    @f
2926
    jbe    @f
3104
    mov    ecx, 512
2927
    mov    ecx, 512
3105
@@:
2928
@@:
3106
    sub    ecx, ebx
2929
    sub    ecx, ebx
3107
    mov    ebx, edx
2930
    mov    ebx, edx
3108
    call    memmove
2931
    call    memmove
3109
    add    edx, ecx
2932
    add    edx, ecx
3110
    sub    [esp], ecx
2933
    sub    [esp], ecx
3111
    pop    ecx
2934
    pop    ecx
3112
    pop    eax
2935
    pop    eax
3113
    xor    ebx, ebx
2936
    xor    ebx, ebx
3114
.skip:
2937
.skip:
3115
    inc    eax
2938
    inc    eax
3116
    dec    edi
2939
    dec    edi
3117
    jnz    .new_sector
2940
    jnz    .new_sector
3118
    mov    eax, [cluster_tmp]
2941
    mov    eax, [cluster_tmp]
3119
    call    get_FAT
2942
    call    get_FAT
3120
    cmp   [hd_error],0
2943
    cmp   [hd_error],0
3121
    jne   .noaccess_4
2944
    jne   .noaccess_4
3122
 
2945
 
3123
    jmp    .new_cluster
2946
    jmp    .new_cluster
3124
.done:
2947
.done:
3125
        mov     ebx, edx
2948
        mov     ebx, edx
3126
        pop     eax edx ecx edi
2949
        pop     eax edx ecx edi
3127
        sub     ebx, edx
2950
        sub     ebx, edx
3128
        ret
2951
        ret
3129
.eof:
2952
.eof:
3130
        mov     ebx, edx
2953
        mov     ebx, edx
3131
        pop     eax edx ecx
2954
        pop     eax edx ecx
3132
        sub     ebx, edx
2955
        sub     ebx, edx
3133
        jmp     .reteof
2956
        jmp     .reteof
3134
 
2957
 
3135
;----------------------------------------------------------------
2958
;----------------------------------------------------------------
3136
;
2959
;
3137
;  fs_HdReadFolder - LFN variant for reading hard disk folder
2960
;  fs_HdReadFolder - LFN variant for reading hard disk folder
3138
;
2961
;
3139
;  esi  points to filename
2962
;  esi  points to filename
3140
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
2963
;  ebx  pointer to structure 32-bit number = first wanted block, 0+
3141
;                          & flags (bitfields)
2964
;                          & flags (bitfields)
3142
; flags: bit 0: 0=ANSI names, 1=UNICODE names
2965
; flags: bit 0: 0=ANSI names, 1=UNICODE names
3143
;  ecx  number of blocks to read, 0+
2966
;  ecx  number of blocks to read, 0+
3144
;  edx  mem location to return data
2967
;  edx  mem location to return data
3145
;
2968
;
3146
;  ret ebx = blocks read or 0xffffffff folder not found
2969
;  ret ebx = blocks read or 0xffffffff folder not found
3147
;      eax = 0 ok read or other = errormsg
2970
;      eax = 0 ok read or other = errormsg
3148
;
2971
;
3149
;--------------------------------------------------------------
2972
;--------------------------------------------------------------
3150
fs_HdReadFolder:
2973
fs_HdReadFolder:
3151
        mov     eax, [ROOT_CLUSTER]
2974
        mov     eax, [ROOT_CLUSTER]
3152
        push    edi
2975
        push    edi
3153
        cmp     byte [esi], 0
2976
        cmp     byte [esi], 0
3154
        jz      .doit
2977
        jz      .doit
3155
        call    hd_find_lfn
2978
        call    hd_find_lfn
3156
        jnc     .found
2979
        jnc     .found
3157
        pop     edi
2980
        pop     edi
3158
        or      ebx, -1
2981
        or      ebx, -1
3159
        mov     eax, ERROR_FILE_NOT_FOUND
2982
        mov     eax, ERROR_FILE_NOT_FOUND
3160
        ret
2983
        ret
3161
.found:
2984
.found:
3162
        test    byte [edi+11], 0x10     ; do not allow read files
2985
        test    byte [edi+11], 0x10     ; do not allow read files
3163
        jnz     .found_dir
2986
        jnz     .found_dir
3164
        pop     edi
2987
        pop     edi
3165
        or      ebx, -1
2988
        or      ebx, -1
3166
        mov     eax, ERROR_ACCESS_DENIED
2989
        mov     eax, ERROR_ACCESS_DENIED
3167
        ret
2990
        ret
3168
.found_dir:
2991
.found_dir:
3169
        mov     eax, [edi+20-2]
2992
        mov     eax, [edi+20-2]
3170
        mov     ax, [edi+26]    ; eax=cluster
2993
        mov     ax, [edi+26]    ; eax=cluster
3171
.doit:
2994
.doit:
3172
        push    esi ecx
2995
        push    esi ecx
3173
        push    ebp
2996
        push    ebp
3174
        sub     esp, 262*2      ; reserve space for LFN
2997
        sub     esp, 262*2      ; reserve space for LFN
3175
        mov     ebp, esp
2998
        mov     ebp, esp
3176
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE name
2999
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE name
3177
        mov     ebx, [ebx]
3000
        mov     ebx, [ebx]
3178
; init header
3001
; init header
3179
        push    eax ecx
3002
        push    eax ecx
3180
        mov     edi, edx
3003
        mov     edi, edx
3181
        mov     ecx, 32/4
3004
        mov     ecx, 32/4
3182
        xor     eax, eax
3005
        xor     eax, eax
3183
        rep     stosd
3006
        rep     stosd
3184
        pop     ecx eax
3007
        pop     ecx eax
3185
        mov     byte [edx], 1   ; version
3008
        mov     byte [edx], 1   ; version
3186
        mov     esi, edi        ; esi points to BDFE
3009
        mov     esi, edi        ; esi points to BDFE
3187
.new_cluster:
3010
.new_cluster:
3188
        mov     [cluster_tmp], eax
3011
        mov     [cluster_tmp], eax
3189
        test    eax, eax
3012
        test    eax, eax
3190
        jnz     @f
3013
        jnz     @f
3191
        cmp     [fat_type], 32
3014
        cmp     [fat_type], 32
3192
        jz      .notfound
3015
        jz      .notfound
3193
        mov     eax, [ROOT_START]
3016
        mov     eax, [ROOT_START]
3194
        push    [ROOT_SECTORS]
3017
        push    [ROOT_SECTORS]
3195
        push    ebx
3018
        push    ebx
3196
        jmp     .new_sector
3019
        jmp     .new_sector
3197
@@:
3020
@@:
3198
        dec     eax
3021
        dec     eax
3199
        dec     eax
3022
        dec     eax
3200
        imul    eax, [SECTORS_PER_CLUSTER]
3023
        imul    eax, [SECTORS_PER_CLUSTER]
3201
        push    [SECTORS_PER_CLUSTER]
3024
        push    [SECTORS_PER_CLUSTER]
3202
        add     eax, [DATA_START]
3025
        add     eax, [DATA_START]
3203
        push    ebx
3026
        push    ebx
3204
.new_sector:
3027
.new_sector:
3205
        mov     ebx, buffer
3028
        mov     ebx, buffer
3206
        mov     edi, ebx
3029
        mov     edi, ebx
3207
        call    hd_read
3030
        call    hd_read
3208
        cmp     [hd_error], 0
3031
        cmp     [hd_error], 0
3209
        jnz     .notfound2
3032
        jnz     .notfound2
3210
        add     ebx, 512
3033
        add     ebx, 512
3211
        push    eax
3034
        push    eax
3212
.l1:
3035
.l1:
3213
        call    fat_get_name
3036
        call    fat_get_name
3214
        jc      .l2
3037
        jc      .l2
3215
        cmp     byte [edi+11], 0xF
3038
        cmp     byte [edi+11], 0xF
3216
        jnz     .do_bdfe
3039
        jnz     .do_bdfe
3217
        add     edi, 0x20
3040
        add     edi, 0x20
3218
        cmp     edi, ebx
3041
        cmp     edi, ebx
3219
        jb      .do_bdfe
3042
        jb      .do_bdfe
3220
        pop     eax
3043
        pop     eax
3221
        inc     eax
3044
        inc     eax
3222
        dec     dword [esp+4]
3045
        dec     dword [esp+4]
3223
        jnz     @f
3046
        jnz     @f
3224
        mov     eax, [cluster_tmp]
3047
        mov     eax, [cluster_tmp]
3225
        test    eax, eax
3048
        test    eax, eax
3226
        jz      .done
3049
        jz      .done
3227
        call    get_FAT
3050
        call    get_FAT
3228
        cmp     [hd_error], 0
3051
        cmp     [hd_error], 0
3229
        jnz     .notfound2
3052
        jnz     .notfound2
3230
        cmp     eax, 2
3053
        cmp     eax, 2
3231
        jb      .done
3054
        jb      .done
3232
        cmp     eax, [fatRESERVED]
3055
        cmp     eax, [fatRESERVED]
3233
        jae     .done
3056
        jae     .done
3234
        push    eax
3057
        push    eax
3235
        mov     eax, [SECTORS_PER_CLUSTER]
3058
        mov     eax, [SECTORS_PER_CLUSTER]
3236
        mov     [esp+8], eax
3059
        mov     [esp+8], eax
3237
        pop     eax
3060
        pop     eax
3238
        mov     [cluster_tmp], eax
3061
        mov     [cluster_tmp], eax
3239
        dec     eax
3062
        dec     eax
3240
        dec     eax
3063
        dec     eax
3241
        imul    eax, [SECTORS_PER_CLUSTER]
3064
        imul    eax, [SECTORS_PER_CLUSTER]
3242
        add     eax, [DATA_START]
3065
        add     eax, [DATA_START]
3243
@@:
3066
@@:
3244
        mov     ebx, buffer
3067
        mov     ebx, buffer
3245
        mov     edi, ebx
3068
        mov     edi, ebx
3246
        call    hd_read
3069
        call    hd_read
3247
        cmp     [hd_error], 0
3070
        cmp     [hd_error], 0
3248
        jnz     .notfound2
3071
        jnz     .notfound2
3249
        add     ebx, 512
3072
        add     ebx, 512
3250
        push    eax
3073
        push    eax
3251
.do_bdfe:
3074
.do_bdfe:
3252
        inc     dword [edx+8]   ; new file found
3075
        inc     dword [edx+8]   ; new file found
3253
        dec     dword [esp+4]
3076
        dec     dword [esp+4]
3254
        jns     .l2
3077
        jns     .l2
3255
        dec     ecx
3078
        dec     ecx
3256
        js      .l2
3079
        js      .l2
3257
        inc     dword [edx+4]   ; new file block copied
3080
        inc     dword [edx+4]   ; new file block copied
3258
        call    fat_entry_to_bdfe
3081
        call    fat_entry_to_bdfe
3259
.l2:
3082
.l2:
3260
        add     edi, 0x20
3083
        add     edi, 0x20
3261
        cmp     edi, ebx
3084
        cmp     edi, ebx
3262
        jb      .l1
3085
        jb      .l1
3263
        pop     eax
3086
        pop     eax
3264
        inc     eax
3087
        inc     eax
3265
        dec     dword [esp+4]
3088
        dec     dword [esp+4]
3266
        jnz     .new_sector
3089
        jnz     .new_sector
3267
        mov     eax, [cluster_tmp]
3090
        mov     eax, [cluster_tmp]
3268
        test    eax, eax
3091
        test    eax, eax
3269
        jz      .done
3092
        jz      .done
3270
        call    get_FAT
3093
        call    get_FAT
3271
        cmp     [hd_error], 0
3094
        cmp     [hd_error], 0
3272
        jnz     .notfound2
3095
        jnz     .notfound2
3273
        cmp     eax, 2
3096
        cmp     eax, 2
3274
        jb      .done
3097
        jb      .done
3275
        cmp     eax, [fatRESERVED]
3098
        cmp     eax, [fatRESERVED]
3276
        jae     .done
3099
        jae     .done
3277
        push    eax
3100
        push    eax
3278
        mov     eax, [SECTORS_PER_CLUSTER]
3101
        mov     eax, [SECTORS_PER_CLUSTER]
3279
        mov     [esp+8], eax
3102
        mov     [esp+8], eax
3280
        pop     eax
3103
        pop     eax
3281
        pop     ebx
3104
        pop     ebx
3282
        add     esp, 4
3105
        add     esp, 4
3283
        jmp     .new_cluster
3106
        jmp     .new_cluster
3284
.notfound2:
3107
.notfound2:
3285
        add     esp, 8
3108
        add     esp, 8
3286
.notfound:
3109
.notfound:
3287
        add     esp, 262*2+4
3110
        add     esp, 262*2+4
3288
        pop     ebp ecx esi edi
3111
        pop     ebp ecx esi edi
3289
        mov     eax, ERROR_FILE_NOT_FOUND
3112
        mov     eax, ERROR_FILE_NOT_FOUND
3290
        or      ebx, -1
3113
        or      ebx, -1
3291
        ret
3114
        ret
3292
.done:
3115
.done:
3293
        add     esp, 262*2+4+8
3116
        add     esp, 262*2+4+8
3294
        pop     ebp
3117
        pop     ebp
3295
        mov     ebx, [edx+4]
3118
        mov     ebx, [edx+4]
3296
        xor     eax, eax
3119
        xor     eax, eax
3297
        dec     ecx
3120
        dec     ecx
3298
        js      @f
3121
        js      @f
3299
        mov     al, ERROR_END_OF_FILE
3122
        mov     al, ERROR_END_OF_FILE
3300
@@:
3123
@@:
3301
        pop     ecx esi edi
3124
        pop     ecx esi edi
3302
        ret
3125
        ret
3303
 
3126
 
3304
fat16_root_next:
3127
fat16_root_next:
3305
        cmp     edi, buffer+0x200-0x20
3128
        cmp     edi, buffer+0x200-0x20
3306
        jae     fat16_root_next_sector
3129
        jae     fat16_root_next_sector
3307
        add     edi, 0x20
3130
        add     edi, 0x20
3308
        ret     ; CF=0
3131
        ret     ; CF=0
3309
fat16_root_next_sector:
3132
fat16_root_next_sector:
3310
; read next sector
3133
; read next sector
3311
        push    ecx
3134
        push    ecx
3312
        mov     ecx, [eax+4]
3135
        mov     ecx, [eax+4]
3313
        inc     ecx
3136
        inc     ecx
3314
        mov     [eax+4], ecx
3137
        mov     [eax+4], ecx
3315
        cmp     ecx, [ROOT_SECTORS]
3138
        cmp     ecx, [ROOT_SECTORS]
3316
        pop     ecx
3139
        pop     ecx
3317
        jae     fat16_root_first.readerr
3140
        jae     fat16_root_first.readerr
3318
fat16_root_first:
3141
fat16_root_first:
3319
        mov     eax, [eax+4]
3142
        mov     eax, [eax+4]
3320
        add     eax, [ROOT_START]
3143
        add     eax, [ROOT_START]
3321
        push    ebx
3144
        push    ebx
3322
        mov     edi, buffer
3145
        mov     edi, buffer
3323
        mov     ebx, edi
3146
        mov     ebx, edi
3324
        call    hd_read
3147
        call    hd_read
3325
        pop     ebx
3148
        pop     ebx
3326
        cmp     [hd_error], 0
3149
        cmp     [hd_error], 0
3327
        jnz     .readerr
3150
        jnz     .readerr
3328
        ret     ; CF=0
3151
        ret     ; CF=0
3329
.readerr:
3152
.readerr:
3330
        stc
3153
        stc
3331
        ret
3154
        ret
3332
fat16_root_begin_write:
3155
fat16_root_begin_write:
3333
        push    edi eax
3156
        push    edi eax
3334
        call    fat16_root_first
3157
        call    fat16_root_first
3335
        pop     eax edi
3158
        pop     eax edi
3336
        ret
3159
        ret
3337
fat16_root_end_write:
3160
fat16_root_end_write:
3338
        pusha
3161
        pusha
3339
        mov     eax, [eax+4]
3162
        mov     eax, [eax+4]
3340
        add     eax, [ROOT_START]
3163
        add     eax, [ROOT_START]
3341
        mov     ebx, buffer
3164
        mov     ebx, buffer
3342
        call    hd_write
3165
        call    hd_write
3343
        popa
3166
        popa
3344
        ret
3167
        ret
3345
fat16_root_next_write:
3168
fat16_root_next_write:
3346
        cmp     edi, buffer+0x200
3169
        cmp     edi, buffer+0x200
3347
        jae     @f
3170
        jae     @f
3348
        ret
3171
        ret
3349
@@:
3172
@@:
3350
        call    fat16_root_end_write
3173
        call    fat16_root_end_write
3351
        jmp     fat16_root_next_sector
3174
        jmp     fat16_root_next_sector
3352
fat16_root_extend_dir:
3175
fat16_root_extend_dir:
3353
        stc
3176
        stc
3354
        ret
3177
        ret
3355
 
3178
 
3356
fat_notroot_next:
3179
fat_notroot_next:
3357
        cmp     edi, buffer+0x200-0x20
3180
        cmp     edi, buffer+0x200-0x20
3358
        jae     fat_notroot_next_sector
3181
        jae     fat_notroot_next_sector
3359
        add     edi, 0x20
3182
        add     edi, 0x20
3360
        ret     ; CF=0
3183
        ret     ; CF=0
3361
fat_notroot_next_sector:
3184
fat_notroot_next_sector:
3362
        push    ecx
3185
        push    ecx
3363
        mov     ecx, [eax+4]
3186
        mov     ecx, [eax+4]
3364
        inc     ecx
3187
        inc     ecx
3365
        cmp     ecx, [SECTORS_PER_CLUSTER]
3188
        cmp     ecx, [SECTORS_PER_CLUSTER]
3366
        jae     fat_notroot_next_cluster
3189
        jae     fat_notroot_next_cluster
3367
        mov     [eax+4], ecx
3190
        mov     [eax+4], ecx
3368
        jmp     @f
3191
        jmp     @f
3369
fat_notroot_next_cluster:
3192
fat_notroot_next_cluster:
3370
        push    eax
3193
        push    eax
3371
        mov     eax, [eax]
3194
        mov     eax, [eax]
3372
        call    get_FAT
3195
        call    get_FAT
3373
        mov     ecx, eax
3196
        mov     ecx, eax
3374
        pop     eax
3197
        pop     eax
3375
        cmp     [hd_error], 0
3198
        cmp     [hd_error], 0
3376
        jnz     fat_notroot_next_err
3199
        jnz     fat_notroot_next_err
3377
        cmp     ecx, [fatRESERVED]
3200
        cmp     ecx, [fatRESERVED]
3378
        jae     fat_notroot_next_err
3201
        jae     fat_notroot_next_err
3379
        mov     [eax], ecx
3202
        mov     [eax], ecx
3380
        and     dword [eax+4], 0
3203
        and     dword [eax+4], 0
3381
@@:
3204
@@:
3382
        pop     ecx
3205
        pop     ecx
3383
fat_notroot_first:
3206
fat_notroot_first:
3384
        call    fat_get_sector
3207
        call    fat_get_sector
3385
        push    ebx
3208
        push    ebx
3386
        mov     edi, buffer
3209
        mov     edi, buffer
3387
        mov     ebx, edi
3210
        mov     ebx, edi
3388
        call    hd_read
3211
        call    hd_read
3389
        pop     ebx
3212
        pop     ebx
3390
        cmp     [hd_error], 0
3213
        cmp     [hd_error], 0
3391
        jnz     @f
3214
        jnz     @f
3392
        ret     ; CF=0
3215
        ret     ; CF=0
3393
fat_notroot_next_err:
3216
fat_notroot_next_err:
3394
        pop     ecx
3217
        pop     ecx
3395
@@:
3218
@@:
3396
        stc
3219
        stc
3397
        ret
3220
        ret
3398
fat_notroot_begin_write:
3221
fat_notroot_begin_write:
3399
        push    eax edi
3222
        push    eax edi
3400
        call    fat_notroot_first
3223
        call    fat_notroot_first
3401
        pop     edi eax
3224
        pop     edi eax
3402
        ret
3225
        ret
3403
fat_notroot_end_write:
3226
fat_notroot_end_write:
3404
        call    fat_get_sector
3227
        call    fat_get_sector
3405
        push    ebx
3228
        push    ebx
3406
        mov     ebx, buffer
3229
        mov     ebx, buffer
3407
        call    hd_write
3230
        call    hd_write
3408
        pop     ebx
3231
        pop     ebx
3409
        ret
3232
        ret
3410
fat_notroot_next_write:
3233
fat_notroot_next_write:
3411
        cmp     edi, buffer+0x200
3234
        cmp     edi, buffer+0x200
3412
        jae     @f
3235
        jae     @f
3413
        ret
3236
        ret
3414
@@:
3237
@@:
3415
        push    eax
3238
        push    eax
3416
        call    fat_notroot_end_write
3239
        call    fat_notroot_end_write
3417
        pop     eax
3240
        pop     eax
3418
        jmp     fat_notroot_next_sector
3241
        jmp     fat_notroot_next_sector
3419
fat_notroot_extend_dir:
3242
fat_notroot_extend_dir:
3420
        push    eax
3243
        push    eax
3421
        mov     eax, [eax]
3244
        mov     eax, [eax]
3422
        call    get_free_FAT
3245
        call    get_free_FAT
3423
        jnc     .found
3246
        jnc     .found
3424
        pop     eax
3247
        pop     eax
3425
        ret     ; CF=1
3248
        ret     ; CF=1
3426
.found:
3249
.found:
3427
        push    edx
3250
        push    edx
3428
        mov     edx, [fatEND]
3251
        mov     edx, [fatEND]
3429
        call    set_FAT
3252
        call    set_FAT
3430
        mov     edx, eax
3253
        mov     edx, eax
3431
        mov     eax, [esp+4]
3254
        mov     eax, [esp+4]
3432
        mov     eax, [eax]
3255
        mov     eax, [eax]
3433
        push    edx
3256
        push    edx
3434
        mov     [f_del], 1
3257
        mov     [f_del], 1
3435
        call    set_FAT
3258
        call    set_FAT
3436
        pop     edx
3259
        pop     edx
3437
        cmp     [hd_error], 0
3260
        cmp     [hd_error], 0
3438
        jz      @f
3261
        jz      @f
3439
        pop     edx
3262
        pop     edx
3440
        pop     eax
3263
        pop     eax
3441
        stc
3264
        stc
3442
        ret
3265
        ret
3443
@@:
3266
@@:
3444
        push    ecx
3267
        push    ecx
3445
        or      ecx, -1
3268
        or      ecx, -1
3446
        call    add_disk_free_space
3269
        call    add_disk_free_space
3447
; zero new cluster
3270
; zero new cluster
3448
        mov     ecx, 512/4
3271
        mov     ecx, 512/4
3449
        mov     edi, buffer
3272
        mov     edi, buffer
3450
        push    edi
3273
        push    edi
3451
        xor     eax, eax
3274
        xor     eax, eax
3452
        rep     stosd
3275
        rep     stosd
3453
        pop     edi
3276
        pop     edi
3454
        pop     ecx
3277
        pop     ecx
3455
        mov     eax, [esp+4]
3278
        mov     eax, [esp+4]
3456
        mov     [eax], edx
3279
        mov     [eax], edx
3457
        and     dword [eax+4], 0
3280
        and     dword [eax+4], 0
3458
        pop     edx
3281
        pop     edx
3459
        mov     eax, [eax]
3282
        mov     eax, [eax]
3460
        dec     eax
3283
        dec     eax
3461
        dec     eax
3284
        dec     eax
3462
        push    ebx ecx
3285
        push    ebx ecx
3463
        mov     ecx, [SECTORS_PER_CLUSTER]
3286
        mov     ecx, [SECTORS_PER_CLUSTER]
3464
        imul    eax, ecx
3287
        imul    eax, ecx
3465
        add     eax, [DATA_START]
3288
        add     eax, [DATA_START]
3466
        mov     ebx, edi
3289
        mov     ebx, edi
3467
@@:
3290
@@:
3468
        call    hd_write
3291
        call    hd_write
3469
        inc     eax
3292
        inc     eax
3470
        loop    @b
3293
        loop    @b
3471
        pop     ecx ebx eax
3294
        pop     ecx ebx eax
3472
        clc
3295
        clc
3473
        ret
3296
        ret
3474
 
3297
 
3475
fat_get_sector:
3298
fat_get_sector:
3476
        push    ecx
3299
        push    ecx
3477
        mov     ecx, [eax]
3300
        mov     ecx, [eax]
3478
        dec     ecx
3301
        dec     ecx
3479
        dec     ecx
3302
        dec     ecx
3480
        imul    ecx, [SECTORS_PER_CLUSTER]
3303
        imul    ecx, [SECTORS_PER_CLUSTER]
3481
        add     ecx, [DATA_START]
3304
        add     ecx, [DATA_START]
3482
        add     ecx, [eax+4]
3305
        add     ecx, [eax+4]
3483
        mov     eax, ecx
3306
        mov     eax, ecx
3484
        pop     ecx
3307
        pop     ecx
3485
        ret
3308
        ret
3486
 
3309
 
3487
;----------------------------------------------------------------
3310
;----------------------------------------------------------------
3488
;
3311
;
3489
;  fs_HdRewrite - LFN variant for writing hard disk
3312
;  fs_HdRewrite - LFN variant for writing hard disk
3490
;
3313
;
3491
;  esi  points to filename
3314
;  esi  points to filename
3492
;  ebx  ignored (reserved)
3315
;  ebx  ignored (reserved)
3493
;  ecx  number of bytes to write, 0+
3316
;  ecx  number of bytes to write, 0+
3494
;  edx  mem location to data
3317
;  edx  mem location to data
3495
;
3318
;
3496
;  ret ebx = number of written bytes
3319
;  ret ebx = number of written bytes
3497
;      eax = 0 ok read or other = errormsg
3320
;      eax = 0 ok read or other = errormsg
3498
;
3321
;
3499
;--------------------------------------------------------------
3322
;--------------------------------------------------------------
3500
fshrad:
3323
fshrad:
3501
        mov     eax, ERROR_ACCESS_DENIED
3324
        mov     eax, ERROR_ACCESS_DENIED
3502
        xor     ebx, ebx
3325
        xor     ebx, ebx
3503
        ret
3326
        ret
3504
fshrfs:
3327
fshrfs:
3505
        mov     eax, ERROR_UNKNOWN_FS
3328
        mov     eax, ERROR_UNKNOWN_FS
3506
        xor     ebx, ebx
3329
        xor     ebx, ebx
3507
        ret
3330
        ret
3508
 
3331
 
3509
fs_HdRewrite:
3332
fs_HdRewrite:
3510
        cmp     [fat_type], 0
3333
        cmp     [fat_type], 0
3511
        jz      fshrfs
3334
        jz      fshrfs
3512
        cmp     byte [esi], 0
3335
        cmp     byte [esi], 0
3513
        jz      fshrad
3336
        jz      fshrad
3514
        pushad
3337
        pushad
3515
        xor     ebp, ebp
3338
        xor     ebp, ebp
3516
        push    esi
3339
        push    esi
3517
@@:
3340
@@:
3518
        lodsb
3341
        lodsb
3519
        test    al, al
3342
        test    al, al
3520
        jz      @f
3343
        jz      @f
3521
        cmp     al, '/'
3344
        cmp     al, '/'
3522
        jnz     @b
3345
        jnz     @b
3523
        lea     ebp, [esi-1]
3346
        lea     ebp, [esi-1]
3524
        jmp     @b
3347
        jmp     @b
3525
@@:
3348
@@:
3526
        pop     esi
3349
        pop     esi
3527
        test    ebp, ebp
3350
        test    ebp, ebp
3528
        jnz     .noroot
3351
        jnz     .noroot
3529
        mov     ebp, [ROOT_CLUSTER]
3352
        mov     ebp, [ROOT_CLUSTER]
3530
        cmp     [fat_type], 32
3353
        cmp     [fat_type], 32
3531
        jz      .pushnotroot
3354
        jz      .pushnotroot
3532
        push    fat16_root_extend_dir
3355
        push    fat16_root_extend_dir
3533
        push    fat16_root_end_write
3356
        push    fat16_root_end_write
3534
        push    fat16_root_next_write
3357
        push    fat16_root_next_write
3535
        push    fat16_root_begin_write
3358
        push    fat16_root_begin_write
3536
        xor     ebp, ebp
3359
        xor     ebp, ebp
3537
        push    ebp
3360
        push    ebp
3538
        push    ebp
3361
        push    ebp
3539
        push    fat16_root_first
3362
        push    fat16_root_first
3540
        push    fat16_root_next
3363
        push    fat16_root_next
3541
        jmp     .common1
3364
        jmp     .common1
3542
.noroot:
3365
.noroot:
3543
; check existence
3366
; check existence
3544
        mov     byte [ebp], 0
3367
        mov     byte [ebp], 0
3545
        call    hd_find_lfn
3368
        call    hd_find_lfn
3546
        mov     byte [ebp], '/'
3369
        mov     byte [ebp], '/'
3547
        lea     esi, [ebp+1]
3370
        lea     esi, [ebp+1]
3548
        jnc     @f
3371
        jnc     @f
3549
        mov     eax, ERROR_FILE_NOT_FOUND
3372
        mov     eax, ERROR_FILE_NOT_FOUND
3550
.ret1:
3373
.ret1:
3551
        mov     [esp+28], eax
3374
        mov     [esp+28], eax
3552
        popad
3375
        popad
3553
        xor     ebx, ebx
3376
        xor     ebx, ebx
3554
        ret
3377
        ret
3555
@@:
3378
@@:
3556
        test    byte [edi+11], 0x10     ; must be directory
3379
        test    byte [edi+11], 0x10     ; must be directory
3557
        mov     eax, ERROR_ACCESS_DENIED
3380
        mov     eax, ERROR_ACCESS_DENIED
3558
        jz      .ret1
3381
        jz      .ret1
3559
        mov     ebp, [edi+20-2]
3382
        mov     ebp, [edi+20-2]
3560
        mov     bp, [edi+26]            ; ebp=cluster
3383
        mov     bp, [edi+26]            ; ebp=cluster
3561
        mov     eax, ERROR_FAT_TABLE
3384
        mov     eax, ERROR_FAT_TABLE
3562
        cmp     ebp, 2
3385
        cmp     ebp, 2
3563
        jb      .ret1
3386
        jb      .ret1
3564
.pushnotroot:
3387
.pushnotroot:
3565
        push    fat_notroot_extend_dir
3388
        push    fat_notroot_extend_dir
3566
        push    fat_notroot_end_write
3389
        push    fat_notroot_end_write
3567
        push    fat_notroot_next_write
3390
        push    fat_notroot_next_write
3568
        push    fat_notroot_begin_write
3391
        push    fat_notroot_begin_write
3569
        push    0
3392
        push    0
3570
        push    ebp
3393
        push    ebp
3571
        push    fat_notroot_first
3394
        push    fat_notroot_first
3572
        push    fat_notroot_next
3395
        push    fat_notroot_next
3573
.common1:
3396
.common1:
3574
        call    fat_find_lfn
3397
        call    fat_find_lfn
3575
        jc      .notfound
3398
        jc      .notfound
3576
; found, delete FAT chain
3399
; found, delete FAT chain
3577
        push    edi
3400
        push    edi
3578
        xor     eax, eax
3401
        xor     eax, eax
3579
        mov     dword [edi+28], eax     ; zero size
3402
        mov     dword [edi+28], eax     ; zero size
3580
        xor     ecx, ecx
3403
        xor     ecx, ecx
3581
        mov     eax, [edi+20-2]
3404
        mov     eax, [edi+20-2]
3582
        mov     ax, [edi+26]
3405
        mov     ax, [edi+26]
3583
        mov     word [edi+20], cx
3406
        mov     word [edi+20], cx
3584
        mov     word [edi+26], cx
3407
        mov     word [edi+26], cx
3585
        test    eax, eax
3408
        test    eax, eax
3586
        jz      .done1
3409
        jz      .done1
3587
        mov     [f_del], 1
3410
        mov     [f_del], 1
3588
@@:
3411
@@:
3589
        cmp     eax, [fatRESERVED]
3412
        cmp     eax, [fatRESERVED]
3590
        jae     .done1
3413
        jae     .done1
3591
        push    edx
3414
        push    edx
3592
        xor     edx, edx
3415
        xor     edx, edx
3593
        call    set_FAT
3416
        call    set_FAT
3594
        mov     eax, edx
3417
        mov     eax, edx
3595
        pop     edx
3418
        pop     edx
3596
        inc     ecx
3419
        inc     ecx
3597
        jmp     @b
3420
        jmp     @b
3598
.done1:
3421
.done1:
3599
        pop     edi
3422
        pop     edi
3600
        call    get_time_for_file
3423
        call    get_time_for_file
3601
        mov     [edi+22], ax
3424
        mov     [edi+22], ax
3602
        call    get_date_for_file
3425
        call    get_date_for_file
3603
        mov     [edi+24], ax
3426
        mov     [edi+24], ax
3604
        mov     [edi+18], ax
3427
        mov     [edi+18], ax
3605
        or      byte [edi+11], 20h      ; set 'archive' attribute
3428
        or      byte [edi+11], 20h      ; set 'archive' attribute
3606
        jmp     .doit
3429
        jmp     .doit
3607
.notfound:
3430
.notfound:
3608
; file is not found; generate short name
3431
; file is not found; generate short name
3609
        call    fat_name_is_legal
3432
        call    fat_name_is_legal
3610
        jc      @f
3433
        jc      @f
3611
        add     esp, 32
3434
        add     esp, 32
3612
        popad
3435
        popad
3613
        mov     eax, ERROR_FILE_NOT_FOUND
3436
        mov     eax, ERROR_FILE_NOT_FOUND
3614
        xor     ebx, ebx
3437
        xor     ebx, ebx
3615
        ret
3438
        ret
3616
@@:
3439
@@:
3617
        sub     esp, 12
3440
        sub     esp, 12
3618
        mov     edi, esp
3441
        mov     edi, esp
3619
        call    fat_gen_short_name
3442
        call    fat_gen_short_name
3620
.test_short_name_loop:
3443
.test_short_name_loop:
3621
        push    esi edi ecx
3444
        push    esi edi ecx
3622
        mov     esi, edi
3445
        mov     esi, edi
3623
        lea     eax, [esp+12+12+8]
3446
        lea     eax, [esp+12+12+8]
3624
        mov     [eax], ebp
3447
        mov     [eax], ebp
3625
        and     dword [eax+4], 0
3448
        and     dword [eax+4], 0
3626
        call    dword [eax-4]
3449
        call    dword [eax-4]
3627
        jc      .found
3450
        jc      .found
3628
.test_short_name_entry:
3451
.test_short_name_entry:
3629
        cmp     byte [edi+11], 0xF
3452
        cmp     byte [edi+11], 0xF
3630
        jz      .test_short_name_cont
3453
        jz      .test_short_name_cont
3631
        mov     ecx, 11
3454
        mov     ecx, 11
3632
        push    esi edi
3455
        push    esi edi
3633
        repz    cmpsb
3456
        repz    cmpsb
3634
        pop     edi esi
3457
        pop     edi esi
3635
        jz      .short_name_found
3458
        jz      .short_name_found
3636
.test_short_name_cont:
3459
.test_short_name_cont:
3637
        lea     eax, [esp+12+12+8]
3460
        lea     eax, [esp+12+12+8]
3638
        call    dword [eax-8]
3461
        call    dword [eax-8]
3639
        jnc     .test_short_name_entry
3462
        jnc     .test_short_name_entry
3640
        jmp     .found
3463
        jmp     .found
3641
.short_name_found:
3464
.short_name_found:
3642
        pop     ecx edi esi
3465
        pop     ecx edi esi
3643
        call    fat_next_short_name
3466
        call    fat_next_short_name
3644
        jnc     .test_short_name_loop
3467
        jnc     .test_short_name_loop
3645
.disk_full:
3468
.disk_full:
3646
        add     esp, 12+32
3469
        add     esp, 12+32
3647
        popa
3470
        popa
3648
        mov     eax, ERROR_DISK_FULL
3471
        mov     eax, ERROR_DISK_FULL
3649
        xor     ebx, ebx
3472
        xor     ebx, ebx
3650
        ret
3473
        ret
3651
.found:
3474
.found:
3652
        pop     ecx edi esi
3475
        pop     ecx edi esi
3653
; now find space in directory
3476
; now find space in directory
3654
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
3477
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
3655
        mov     al, '~'
3478
        mov     al, '~'
3656
        push    ecx edi
3479
        push    ecx edi
3657
        mov     ecx, 8
3480
        mov     ecx, 8
3658
        repnz   scasb
3481
        repnz   scasb
3659
        push    1
3482
        push    1
3660
        pop     eax     ; 1 entry
3483
        pop     eax     ; 1 entry
3661
        jnz     .notilde
3484
        jnz     .notilde
3662
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
3485
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
3663
        xor     eax, eax
3486
        xor     eax, eax
3664
@@:
3487
@@:
3665
        cmp     byte [esi], 0
3488
        cmp     byte [esi], 0
3666
        jz      @f
3489
        jz      @f
3667
        inc     esi
3490
        inc     esi
3668
        inc     eax
3491
        inc     eax
3669
        jmp     @b
3492
        jmp     @b
3670
@@:
3493
@@:
3671
        sub     esi, eax
3494
        sub     esi, eax
3672
        add     eax, 12+13
3495
        add     eax, 12+13
3673
        mov     ecx, 13
3496
        mov     ecx, 13
3674
        push    edx
3497
        push    edx
3675
        cdq
3498
        cdq
3676
        div     ecx
3499
        div     ecx
3677
        pop     edx
3500
        pop     edx
3678
.notilde:
3501
.notilde:
3679
        push    -1
3502
        push    -1
3680
        push    -1
3503
        push    -1
3681
        push    -1
3504
        push    -1
3682
; find  successive entries in directory
3505
; find  successive entries in directory
3683
        xor     ecx, ecx
3506
        xor     ecx, ecx
3684
        push    eax
3507
        push    eax
3685
        lea     eax, [esp+16+8+12+8]
3508
        lea     eax, [esp+16+8+12+8]
3686
        mov     [eax], ebp
3509
        mov     [eax], ebp
3687
        and     dword [eax+4], 0
3510
        and     dword [eax+4], 0
3688
        call    dword [eax-4]
3511
        call    dword [eax-4]
3689
        pop     eax
3512
        pop     eax
3690
        jnc     .scan_dir
3513
        jnc     .scan_dir
3691
.fsfrfe3:
3514
.fsfrfe3:
3692
        add     esp, 12+8+12+32
3515
        add     esp, 12+8+12+32
3693
        popad
3516
        popad
3694
        mov     eax, 11
3517
        mov     eax, 11
3695
        xor     ebx, ebx
3518
        xor     ebx, ebx
3696
        ret
3519
        ret
3697
.scan_dir:
3520
.scan_dir:
3698
        cmp     byte [edi], 0
3521
        cmp     byte [edi], 0
3699
        jz      .free
3522
        jz      .free
3700
        cmp     byte [edi], 0xE5
3523
        cmp     byte [edi], 0xE5
3701
        jz      .free
3524
        jz      .free
3702
        xor     ecx, ecx
3525
        xor     ecx, ecx
3703
.scan_cont:
3526
.scan_cont:
3704
        push    eax
3527
        push    eax
3705
        lea     eax, [esp+16+8+12+8]
3528
        lea     eax, [esp+16+8+12+8]
3706
        call    dword [eax-8]
3529
        call    dword [eax-8]
3707
        pop     eax
3530
        pop     eax
3708
        jnc     .scan_dir
3531
        jnc     .scan_dir
3709
        cmp     [hd_error], 0
3532
        cmp     [hd_error], 0
3710
        jnz     .fsfrfe3
3533
        jnz     .fsfrfe3
3711
        push    eax
3534
        push    eax
3712
        lea     eax, [esp+16+8+12+8]
3535
        lea     eax, [esp+16+8+12+8]
3713
        call    dword [eax+20]          ; extend directory
3536
        call    dword [eax+20]          ; extend directory
3714
        pop     eax
3537
        pop     eax
3715
        jnc     .scan_dir
3538
        jnc     .scan_dir
3716
        add     esp, 12+8+12+32
3539
        add     esp, 12+8+12+32
3717
        popad
3540
        popad
3718
        mov     eax, ERROR_DISK_FULL
3541
        mov     eax, ERROR_DISK_FULL
3719
        xor     ebx, ebx
3542
        xor     ebx, ebx
3720
        ret
3543
        ret
3721
.free:
3544
.free:
3722
        test    ecx, ecx
3545
        test    ecx, ecx
3723
        jnz     @f
3546
        jnz     @f
3724
        mov     [esp], edi
3547
        mov     [esp], edi
3725
        mov     ecx, [esp+12+8+12+8]
3548
        mov     ecx, [esp+12+8+12+8]
3726
        mov     [esp+4], ecx
3549
        mov     [esp+4], ecx
3727
        mov     ecx, [esp+12+8+12+12]
3550
        mov     ecx, [esp+12+8+12+12]
3728
        mov     [esp+8], ecx
3551
        mov     [esp+8], ecx
3729
        xor     ecx, ecx
3552
        xor     ecx, ecx
3730
@@:
3553
@@:
3731
        inc     ecx
3554
        inc     ecx
3732
        cmp     ecx, eax
3555
        cmp     ecx, eax
3733
        jb      .scan_cont
3556
        jb      .scan_cont
3734
; found!
3557
; found!
3735
; calculate name checksum
3558
; calculate name checksum
3736
        push    esi ecx
3559
        push    esi ecx
3737
        mov     esi, [esp+8+12]
3560
        mov     esi, [esp+8+12]
3738
        mov     ecx, 11
3561
        mov     ecx, 11
3739
        xor     eax, eax
3562
        xor     eax, eax
3740
@@:
3563
@@:
3741
        ror     al, 1
3564
        ror     al, 1
3742
        add     al, [esi]
3565
        add     al, [esi]
3743
        inc     esi
3566
        inc     esi
3744
        loop    @b
3567
        loop    @b
3745
        pop     ecx esi
3568
        pop     ecx esi
3746
        pop     edi
3569
        pop     edi
3747
        pop     dword [esp+8+12+12]
3570
        pop     dword [esp+8+12+12]
3748
        pop     dword [esp+8+12+12]
3571
        pop     dword [esp+8+12+12]
3749
; edi points to first entry in free chunk
3572
; edi points to first entry in free chunk
3750
        dec     ecx
3573
        dec     ecx
3751
        jz      .nolfn
3574
        jz      .nolfn
3752
        push    esi
3575
        push    esi
3753
        push    eax
3576
        push    eax
3754
        lea     eax, [esp+8+8+12+8]
3577
        lea     eax, [esp+8+8+12+8]
3755
        call    dword [eax+8]         ; begin write
3578
        call    dword [eax+8]         ; begin write
3756
        mov     al, 40h
3579
        mov     al, 40h
3757
.writelfn:
3580
.writelfn:
3758
        or      al, cl
3581
        or      al, cl
3759
        mov     esi, [esp+4]
3582
        mov     esi, [esp+4]
3760
        push    ecx
3583
        push    ecx
3761
        dec     ecx
3584
        dec     ecx
3762
        imul    ecx, 13
3585
        imul    ecx, 13
3763
        add     esi, ecx
3586
        add     esi, ecx
3764
        stosb
3587
        stosb
3765
        mov     cl, 5
3588
        mov     cl, 5
3766
        call    fs_RamdiskRewrite.read_symbols
3589
        call    fs_RamdiskRewrite.read_symbols
3767
        mov     ax, 0xF
3590
        mov     ax, 0xF
3768
        stosw
3591
        stosw
3769
        mov     al, [esp+4]
3592
        mov     al, [esp+4]
3770
        stosb
3593
        stosb
3771
        mov     cl, 6
3594
        mov     cl, 6
3772
        call    fs_RamdiskRewrite.read_symbols
3595
        call    fs_RamdiskRewrite.read_symbols
3773
        xor     eax, eax
3596
        xor     eax, eax
3774
        stosw
3597
        stosw
3775
        mov     cl, 2
3598
        mov     cl, 2
3776
        call    fs_RamdiskRewrite.read_symbols
3599
        call    fs_RamdiskRewrite.read_symbols
3777
        pop     ecx
3600
        pop     ecx
3778
        lea     eax, [esp+8+8+12+8]
3601
        lea     eax, [esp+8+8+12+8]
3779
        call    dword [eax+12]         ; next write
3602
        call    dword [eax+12]         ; next write
3780
        xor     eax, eax
3603
        xor     eax, eax
3781
        loop    .writelfn
3604
        loop    .writelfn
3782
        pop     eax
3605
        pop     eax
3783
        pop     esi
3606
        pop     esi
3784
;        lea     eax, [esp+8+12+8]
3607
;        lea     eax, [esp+8+12+8]
3785
;        call    dword [eax+16]          ; end write
3608
;        call    dword [eax+16]          ; end write
3786
.nolfn:
3609
.nolfn:
3787
        xchg    esi, [esp]
3610
        xchg    esi, [esp]
3788
        mov     ecx, 11
3611
        mov     ecx, 11
3789
        rep     movsb
3612
        rep     movsb
3790
        mov     word [edi], 20h         ; attributes
3613
        mov     word [edi], 20h         ; attributes
3791
        sub     edi, 11
3614
        sub     edi, 11
3792
        pop     esi ecx
3615
        pop     esi ecx
3793
        add     esp, 12
3616
        add     esp, 12
3794
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
3617
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
3795
        call    get_time_for_file
3618
        call    get_time_for_file
3796
        mov     [edi+14], ax            ; creation time
3619
        mov     [edi+14], ax            ; creation time
3797
        mov     [edi+22], ax            ; last write time
3620
        mov     [edi+22], ax            ; last write time
3798
        call    get_date_for_file
3621
        call    get_date_for_file
3799
        mov     [edi+16], ax            ; creation date
3622
        mov     [edi+16], ax            ; creation date
3800
        mov     [edi+24], ax            ; last write date
3623
        mov     [edi+24], ax            ; last write date
3801
        mov     [edi+18], ax            ; last access date
3624
        mov     [edi+18], ax            ; last access date
3802
        xor     ecx, ecx
3625
        xor     ecx, ecx
3803
        mov     word [edi+20], cx       ; high word of cluster
3626
        mov     word [edi+20], cx       ; high word of cluster
3804
        mov     word [edi+26], cx       ; low word of cluster - to be filled
3627
        mov     word [edi+26], cx       ; low word of cluster - to be filled
3805
        mov     dword [edi+28], ecx     ; file size - to be filled
3628
        mov     dword [edi+28], ecx     ; file size - to be filled
3806
.doit:
3629
.doit:
3807
        lea     eax, [esp+8]
3630
        lea     eax, [esp+8]
3808
        call    dword [eax+16]  ; flush directory
3631
        call    dword [eax+16]  ; flush directory
3809
        push    ecx
3632
        push    ecx
3810
        mov     ecx, [esp+4+32+24]
3633
        mov     ecx, [esp+4+32+24]
3811
        push    ecx
3634
        push    ecx
3812
        push    edi
3635
        push    edi
3813
        mov     esi, edx
3636
        mov     esi, edx
3814
        test    ecx, ecx
3637
        test    ecx, ecx
3815
        jz      .done
3638
        jz      .done
3816
        mov     eax, 2
3639
        mov     eax, 2
3817
        call    get_free_FAT
3640
        call    get_free_FAT
3818
        jc      .diskfull
3641
        jc      .diskfull
3819
        push    eax
3642
        push    eax
3820
        mov     [edi+26], ax
3643
        mov     [edi+26], ax
3821
        shr     eax, 16
3644
        shr     eax, 16
3822
        mov     [edi+20], ax
3645
        mov     [edi+20], ax
3823
        lea     eax, [esp+16+8]
3646
        lea     eax, [esp+16+8]
3824
        call    dword [eax+16]  ; flush directory
3647
        call    dword [eax+16]  ; flush directory
3825
        pop     eax
3648
        pop     eax
3826
        push    edx
3649
        push    edx
3827
        mov     edx, [fatEND]
3650
        mov     edx, [fatEND]
3828
        call    set_FAT
3651
        call    set_FAT
3829
        pop     edx
3652
        pop     edx
3830
.write_cluster:
3653
.write_cluster:
3831
        push    eax
3654
        push    eax
3832
        dec     eax
3655
        dec     eax
3833
        dec     eax
3656
        dec     eax
3834
        mov     ebp, [SECTORS_PER_CLUSTER]
3657
        mov     ebp, [SECTORS_PER_CLUSTER]
3835
        imul    eax, ebp
3658
        imul    eax, ebp
3836
        add     eax, [DATA_START]
3659
        add     eax, [DATA_START]
3837
; write data
3660
; write data
3838
.write_sector:
3661
.write_sector:
3839
        mov     ecx, 512
3662
        mov     ecx, 512
3840
        cmp     dword [esp+8], ecx
3663
        cmp     dword [esp+8], ecx
3841
        jb      .writeshort
3664
        jb      .writeshort
3842
; we can write directly from given buffer
3665
; we can write directly from given buffer
3843
        mov     ebx, esi
3666
        mov     ebx, esi
3844
        add     esi, ecx
3667
        add     esi, ecx
3845
        jmp     .writecommon
3668
        jmp     .writecommon
3846
.writeshort:
3669
.writeshort:
3847
        mov     ecx, [esp+8]
3670
        mov     ecx, [esp+8]
3848
        push    ecx
3671
        push    ecx
3849
        mov     edi, buffer
3672
        mov     edi, buffer
3850
        mov     ebx, edi
3673
        mov     ebx, edi
3851
        rep     movsb
3674
        rep     movsb
3852
        mov     ecx, buffer+0x200
3675
        mov     ecx, buffer+0x200
3853
        sub     ecx, edi
3676
        sub     ecx, edi
3854
        push    eax
3677
        push    eax
3855
        xor     eax, eax
3678
        xor     eax, eax
3856
        rep     stosb
3679
        rep     stosb
3857
        pop     eax
3680
        pop     eax
3858
        pop     ecx
3681
        pop     ecx
3859
.writecommon:
3682
.writecommon:
3860
        call    hd_write
3683
        call    hd_write
3861
        cmp     [hd_error], 0
3684
        cmp     [hd_error], 0
3862
        jnz     .writeerr
3685
        jnz     .writeerr
3863
        inc     eax
3686
        inc     eax
3864
        sub     dword [esp+8], ecx
3687
        sub     dword [esp+8], ecx
3865
        jz      .writedone
3688
        jz      .writedone
3866
        dec     ebp
3689
        dec     ebp
3867
        jnz     .write_sector
3690
        jnz     .write_sector
3868
; allocate new cluster
3691
; allocate new cluster
3869
        pop     eax
3692
        pop     eax
3870
        mov     ecx, eax
3693
        mov     ecx, eax
3871
        call    get_free_FAT
3694
        call    get_free_FAT
3872
        jc      .diskfull
3695
        jc      .diskfull
3873
        mov     [f_del], 1
3696
        mov     [f_del], 1
3874
        push    edx
3697
        push    edx
3875
        mov     edx, [fatEND]
3698
        mov     edx, [fatEND]
3876
        call    set_FAT
3699
        call    set_FAT
3877
        xchg    eax, ecx
3700
        xchg    eax, ecx
3878
        mov     edx, ecx
3701
        mov     edx, ecx
3879
        call    set_FAT
3702
        call    set_FAT
3880
        pop     edx
3703
        pop     edx
3881
        xchg    eax, ecx
3704
        xchg    eax, ecx
3882
        jmp     .write_cluster
3705
        jmp     .write_cluster
3883
.diskfull:
3706
.diskfull:
3884
        mov     eax, ERROR_DISK_FULL
3707
        mov     eax, ERROR_DISK_FULL
3885
        jmp     .ret
3708
        jmp     .ret
3886
.writeerr:
3709
.writeerr:
3887
        pop     eax
3710
        pop     eax
3888
        sub     esi, ecx
3711
        sub     esi, ecx
3889
        mov     eax, 11
3712
        mov     eax, 11
3890
        jmp     .ret
3713
        jmp     .ret
3891
.writedone:
3714
.writedone:
3892
        pop     eax
3715
        pop     eax
3893
.done:
3716
.done:
3894
        xor     eax, eax
3717
        xor     eax, eax
3895
.ret:
3718
.ret:
3896
        pop     edi ecx
3719
        pop     edi ecx
3897
        mov     ebx, esi
3720
        mov     ebx, esi
3898
        sub     ebx, edx
3721
        sub     ebx, edx
3899
        pop     ebp
3722
        pop     ebp
3900
        mov     [esp+32+28], eax
3723
        mov     [esp+32+28], eax
3901
        lea     eax, [esp+8]
3724
        lea     eax, [esp+8]
3902
        call    dword [eax+8]
3725
        call    dword [eax+8]
3903
        mov     [edi+28], ebx
3726
        mov     [edi+28], ebx
3904
        call    dword [eax+16]
3727
        call    dword [eax+16]
3905
        mov     [esp+32+16], ebx
3728
        mov     [esp+32+16], ebx
3906
        lea     eax, [ebx+511]
3729
        lea     eax, [ebx+511]
3907
        shr     eax, 9
3730
        shr     eax, 9
3908
        mov     ecx, [SECTORS_PER_CLUSTER]
3731
        mov     ecx, [SECTORS_PER_CLUSTER]
3909
        lea     eax, [eax+ecx-1]
3732
        lea     eax, [eax+ecx-1]
3910
        xor     edx, edx
3733
        xor     edx, edx
3911
        div     ecx
3734
        div     ecx
3912
        mov     ecx, ebp
3735
        mov     ecx, ebp
3913
        sub     ecx, eax
3736
        sub     ecx, eax
3914
        call    add_disk_free_space
3737
        call    add_disk_free_space
3915
        add     esp, 32
3738
        add     esp, 32
3916
        call    update_disk
3739
        call    update_disk
3917
        popad
3740
        popad
3918
        ret
3741
        ret
3919
 
3742
 
3920
fs_HdGetFileInfo:
3743
fs_HdGetFileInfo:
3921
        cmp     [fat_type], 0
3744
        cmp     [fat_type], 0
3922
        jnz     @f
3745
        jnz     @f
3923
        mov     eax, ERROR_UNKNOWN_FS
3746
        mov     eax, ERROR_UNKNOWN_FS
3924
        ret
3747
        ret
3925
@@:
3748
@@:
3926
        cmp     byte [esi], 0
3749
        cmp     byte [esi], 0
3927
        jnz     @f
3750
        jnz     @f
3928
        mov     eax, 2
3751
        mov     eax, 2
3929
        ret
3752
        ret
3930
@@:
3753
@@:
3931
        push    edi
3754
        push    edi
3932
        call    hd_find_lfn
3755
        call    hd_find_lfn
3933
        pushfd
3756
        pushfd
3934
        cmp     [hd_error], 0
3757
        cmp     [hd_error], 0
3935
        jz      @f
3758
        jz      @f
3936
        popfd
3759
        popfd
3937
        pop     edi
3760
        pop     edi
3938
        mov     eax, 11
3761
        mov     eax, 11
3939
        ret
3762
        ret
3940
@@:
3763
@@:
3941
        popfd
3764
        popfd
3942
        jmp     fs_GetFileInfo_finish
3765
        jmp     fs_GetFileInfo_finish
3943
 
3766
 
3944
fs_HdSetFileInfo:
3767
fs_HdSetFileInfo:
3945
        cmp     [fat_type], 0
3768
        cmp     [fat_type], 0
3946
        jnz     @f
3769
        jnz     @f
3947
        mov     eax, ERROR_UNKNOWN_FS
3770
        mov     eax, ERROR_UNKNOWN_FS
3948
        ret
3771
        ret
3949
@@:
3772
@@:
3950
        cmp     byte [esi], 0
3773
        cmp     byte [esi], 0
3951
        jnz     @f
3774
        jnz     @f
3952
        mov     eax, 2
3775
        mov     eax, 2
3953
        ret
3776
        ret
3954
@@:
3777
@@:
3955
        push    edi
3778
        push    edi
3956
        call    hd_find_lfn
3779
        call    hd_find_lfn
3957
        pushfd
3780
        pushfd
3958
        cmp     [hd_error], 0
3781
        cmp     [hd_error], 0
3959
        jz      @f
3782
        jz      @f
3960
        popfd
3783
        popfd
3961
        pop     edi
3784
        pop     edi
3962
        mov     eax, 11
3785
        mov     eax, 11
3963
        ret
3786
        ret
3964
@@:
3787
@@:
3965
        popfd
3788
        popfd
3966
        jnc     @f
3789
        jnc     @f
3967
        pop     edi
3790
        pop     edi
3968
        mov     eax, ERROR_FILE_NOT_FOUND
3791
        mov     eax, ERROR_FILE_NOT_FOUND
3969
        ret
3792
        ret
3970
@@:
3793
@@:
3971
        push    eax
3794
        push    eax
3972
        call    bdfe_to_fat_entry
3795
        call    bdfe_to_fat_entry
3973
        pop     eax
3796
        pop     eax
3974
        mov     ebx, buffer
3797
        mov     ebx, buffer
3975
        call    hd_write
3798
        call    hd_write
3976
        call    update_disk
3799
        call    update_disk
3977
        pop     edi
3800
        pop     edi
3978
        xor     eax, eax
3801
        xor     eax, eax
3979
        ret
3802
        ret
3980
 
3803
 
3981
; \end{diamond}
3804
; \end{diamond}