Subversion Repositories Kolibri OS

Rev

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

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