Subversion Repositories Kolibri OS

Rev

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

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