Subversion Repositories Kolibri OS

Rev

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

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