Subversion Repositories Kolibri OS

Rev

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

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