Subversion Repositories Kolibri OS

Rev

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

Rev 3442 Rev 3539
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;; FAT12.INC                                                    ;;
6
;; FAT12.INC                                                    ;;
7
;; (C) 2005 Mario79, License: GPL                               ;;
7
;; (C) 2005 Mario79, License: GPL                               ;;
8
;;                                                              ;;
8
;;                                                              ;;
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
 
10
 
11
$Revision: 3442 $
11
$Revision: 3539 $
12
 
12
 
13
 
13
 
14
n_sector    dd 0  ; temporary save for sector value
14
n_sector    dd 0  ; temporary save for sector value
15
flp_status  dd 0
15
flp_status  dd 0
16
clust_tmp_flp dd 0  ; used by analyze_directory and analyze_directory_to_write
16
clust_tmp_flp dd 0  ; used by analyze_directory and analyze_directory_to_write
17
path_pointer_flp dd 0
17
path_pointer_flp dd 0
18
pointer_file_name_flp dd 0
18
pointer_file_name_flp dd 0
19
save_root_flag db 0
19
save_root_flag db 0
20
save_flag   db 0
20
save_flag   db 0
21
root_read   db 0  ; 0-necessary to load root, 1-not to load root
21
root_read   db 0  ; 0-necessary to load root, 1-not to load root
22
flp_fat     db 0  ; 0-necessary to load fat, 1-not to load fat
22
flp_fat     db 0  ; 0-necessary to load fat, 1-not to load fat
23
flp_number  db 0  ; 1- Floppy A, 2-Floppy B
23
flp_number  db 0  ; 1- Floppy A, 2-Floppy B
24
old_track   db 0  ; old value track
24
old_track   db 0  ; old value track
25
flp_label   rb 15 ; Label and ID of inserted floppy disk
25
flp_label   rb 15 ; Label and ID of inserted floppy disk
26
 
26
 
27
reserve_flp:
27
reserve_flp:
28
 
28
 
29
        cli
29
        cli
30
        cmp     [flp_status], 0
30
        cmp     [flp_status], 0
31
        je      reserve_flp_ok
31
        je      reserve_flp_ok
32
 
32
 
33
        sti
33
        sti
34
        call    change_task
34
        call    change_task
35
        jmp     reserve_flp
35
        jmp     reserve_flp
36
 
36
 
37
  reserve_flp_ok:
37
  reserve_flp_ok:
38
 
38
 
39
        push    eax
39
        push    eax
40
        mov     eax, [CURRENT_TASK]
40
        mov     eax, [CURRENT_TASK]
41
        shl     eax, 5
41
        shl     eax, 5
42
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
42
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
43
        mov     [flp_status], eax
43
        mov     [flp_status], eax
44
        pop     eax
44
        pop     eax
45
        sti
45
        sti
46
        ret
46
        ret
47
 
47
 
48
 
48
 
49
floppy_fileread:
49
floppy_fileread:
50
;----------------------------------------------------------------
50
;----------------------------------------------------------------
51
;
51
;
52
;  fileread - sys floppy
52
;  fileread - sys floppy
53
;
53
;
54
;  eax  points to filename 11 chars  - for root directory
54
;  eax  points to filename 11 chars  - for root directory
55
;  ebx  first wanted block       ; 1+ ; if 0 then set to 1
55
;  ebx  first wanted block       ; 1+ ; if 0 then set to 1
56
;  ecx  number of blocks to read ; 1+ ; if 0 then set to 1
56
;  ecx  number of blocks to read ; 1+ ; if 0 then set to 1
57
;  edx  mem location to return data
57
;  edx  mem location to return data
58
;  esi  length of filename 12*X
58
;  esi  length of filename 12*X
59
;  edi  pointer to path   /fd/1/......  - for all files in nested directories
59
;  edi  pointer to path   /fd/1/......  - for all files in nested directories
60
;
60
;
61
;  ret ebx = size or 0xffffffff file not found
61
;  ret ebx = size or 0xffffffff file not found
62
;      eax = 0 ok read or other = errormsg
62
;      eax = 0 ok read or other = errormsg
63
;            10 = access denied
63
;            10 = access denied
64
;--------------------------------------------------------------
64
;--------------------------------------------------------------
65
 
65
 
66
        mov     [save_flag], 0
66
        mov     [save_flag], 0
67
        mov     [path_pointer_flp], edi
67
        mov     [path_pointer_flp], edi
68
        test    esi, esi     ; return ramdisk root
68
        test    esi, esi     ; return ramdisk root
69
        jnz     fr_noroot_1
69
        jnz     fr_noroot_1
70
        cmp     ebx, 224/16
70
        cmp     ebx, 224/16
71
        jbe     fr_do_1
71
        jbe     fr_do_1
72
        mov     eax, 5
72
        mov     eax, 5
73
        xor     ebx, ebx
73
        xor     ebx, ebx
74
        mov     [flp_status], ebx
74
        mov     [flp_status], ebx
75
        ret
75
        ret
76
 
76
 
77
fr_do_1:
77
fr_do_1:
78
        push    ebx ecx edx
78
        push    ebx ecx edx
79
        call    read_flp_root
79
        call    read_flp_root
80
        pop     edx ecx ebx
80
        pop     edx ecx ebx
81
        cmp     [FDC_Status], 0
81
        cmp     [FDC_Status], 0
82
        jne     fdc_status_error_1
82
        jne     fdc_status_error_1
83
        mov     edi, edx
83
        mov     edi, edx
84
        dec     ebx
84
        dec     ebx
85
        shl     ebx, 9
85
        shl     ebx, 9
86
        mov     esi, FLOPPY_BUFF
86
        mov     esi, FLOPPY_BUFF
87
        add     esi, ebx
87
        add     esi, ebx
88
        shl     ecx, 9
88
        shl     ecx, 9
89
        cld
89
        cld
90
        rep movsb
90
        rep movsb
91
        xor     eax, eax
91
        xor     eax, eax
92
        xor     ebx, ebx
92
        xor     ebx, ebx
93
;    mov    eax,0 ; ok read
93
;    mov    eax,0 ; ok read
94
;    mov    ebx,0
94
;    mov    ebx,0
95
        mov     [flp_status], eax
95
        mov     [flp_status], eax
96
        ret
96
        ret
97
fdc_status_error_1:
97
fdc_status_error_1:
98
        xor     eax, eax
98
        xor     eax, eax
99
        mov     [flp_status], eax
99
        mov     [flp_status], eax
100
        mov     eax, 10
100
        mov     eax, 10
101
        or      ebx, -1
101
        or      ebx, -1
102
        ret
102
        ret
103
 
103
 
104
fr_noroot_1:
104
fr_noroot_1:
105
        sub     esp, 32
105
        sub     esp, 32
106
        call    expand_filename
106
        call    expand_filename
107
frfloppy_1:
107
frfloppy_1:
108
        test    ebx, ebx
108
        test    ebx, ebx
109
        jnz     frfl5_1
109
        jnz     frfl5_1
110
        mov     ebx, 1
110
        mov     ebx, 1
111
frfl5_1:
111
frfl5_1:
112
        test    ecx, ecx
112
        test    ecx, ecx
113
        jnz     frfl6_1
113
        jnz     frfl6_1
114
        mov     ecx, 1
114
        mov     ecx, 1
115
frfl6_1:
115
frfl6_1:
116
        dec     ebx
116
        dec     ebx
117
        push    eax
117
        push    eax
118
        push    eax ebx ecx edx esi edi
118
        push    eax ebx ecx edx esi edi
119
        call    read_flp_fat
119
        call    read_flp_fat
120
        cmp     [FDC_Status], 0
120
        cmp     [FDC_Status], 0
121
        jne     fdc_status_error_3_1
121
        jne     fdc_status_error_3_1
122
        mov     [FDD_Track], 0; Öèëèíäð
122
        mov     [FDD_Track], 0; Цилиндр
123
        mov     [FDD_Head], 1; Ñòîðîíà
123
        mov     [FDD_Head], 1; Сторона
124
        mov     [FDD_Sector], 2; Ñåêòîð
124
        mov     [FDD_Sector], 2; Сектор
125
        call    SeekTrack
125
        call    SeekTrack
126
        mov     dh, 14
126
        mov     dh, 14
127
l.20_1:
127
l.20_1:
128
        call    ReadSectWithRetr
128
        call    ReadSectWithRetr
129
        cmp     [FDC_Status], 0
129
        cmp     [FDC_Status], 0
130
        jne     fdc_status_error_3_1
130
        jne     fdc_status_error_3_1
131
        mov     dl, 16
131
        mov     dl, 16
132
        mov     edi, FDD_BUFF
132
        mov     edi, FDD_BUFF
133
        inc     [FDD_Sector]
133
        inc     [FDD_Sector]
134
l.21_1:
134
l.21_1:
135
        mov     esi, eax      ;Name of file we want
135
        mov     esi, eax      ;Name of file we want
136
        mov     ecx, 11
136
        mov     ecx, 11
137
        cld
137
        cld
138
        rep cmpsb           ;Found the file?
138
        rep cmpsb           ;Found the file?
139
        je      fifound_1     ;Yes
139
        je      fifound_1     ;Yes
140
        add     ecx, 21
140
        add     ecx, 21
141
        add     edi, ecx    ;Advance to next entry
141
        add     edi, ecx    ;Advance to next entry
142
        dec     dl
142
        dec     dl
143
        test    dl, dl
143
        test    dl, dl
144
        jnz     l.21_1
144
        jnz     l.21_1
145
        dec     dh
145
        dec     dh
146
        test    dh, dh
146
        test    dh, dh
147
        jnz     l.20_1
147
        jnz     l.20_1
148
fdc_status_error_3:
148
fdc_status_error_3:
149
        mov     eax, 5      ; file not found ?
149
        mov     eax, 5      ; file not found ?
150
        or      ebx, -1
150
        or      ebx, -1
151
        add     esp, 32+28
151
        add     esp, 32+28
152
        mov     [flp_status], 0
152
        mov     [flp_status], 0
153
        ret
153
        ret
154
fdc_status_error_3_2:
154
fdc_status_error_3_2:
155
        cmp     [FDC_Status], 0
155
        cmp     [FDC_Status], 0
156
        je      fdc_status_error_3
156
        je      fdc_status_error_3
157
fdc_status_error_3_1:
157
fdc_status_error_3_1:
158
        add     esp, 32+28
158
        add     esp, 32+28
159
        jmp     fdc_status_error_1
159
        jmp     fdc_status_error_1
160
 
160
 
161
fifound_1:
161
fifound_1:
162
        mov     eax, [path_pointer_flp]
162
        mov     eax, [path_pointer_flp]
163
        cmp     [eax+36], byte 0
163
        cmp     [eax+36], byte 0
164
        je      fifound_2
164
        je      fifound_2
165
        add     edi, 0xf
165
        add     edi, 0xf
166
        mov     eax, [edi]
166
        mov     eax, [edi]
167
        and     eax, 65535
167
        and     eax, 65535
168
        mov     ebx, [path_pointer_flp]
168
        mov     ebx, [path_pointer_flp]
169
        add     ebx, 36
169
        add     ebx, 36
170
        call    get_cluster_of_a_path_flp
170
        call    get_cluster_of_a_path_flp
171
        jc      fdc_status_error_3_2
171
        jc      fdc_status_error_3_2
172
        mov     ebx, [ebx-11+28]  ;file size
172
        mov     ebx, [ebx-11+28]  ;file size
173
        mov     [esp+20], ebx
173
        mov     [esp+20], ebx
174
        mov     [esp+24], ebx
174
        mov     [esp+24], ebx
175
        jmp     fifound_3
175
        jmp     fifound_3
176
fifound_2:
176
fifound_2:
177
        mov     ebx, [edi-11+28]  ;file size
177
        mov     ebx, [edi-11+28]  ;file size
178
        mov     [esp+20], ebx
178
        mov     [esp+20], ebx
179
        mov     [esp+24], ebx
179
        mov     [esp+24], ebx
180
        add     edi, 0xf
180
        add     edi, 0xf
181
        mov     eax, [edi]
181
        mov     eax, [edi]
182
fifound_3:
182
fifound_3:
183
        and     eax, 65535
183
        and     eax, 65535
184
        mov     [n_sector], eax      ;eax=cluster
184
        mov     [n_sector], eax      ;eax=cluster
185
frnew_1:
185
frnew_1:
186
        add     eax, 31      ;bootsector+2*fat+filenames
186
        add     eax, 31      ;bootsector+2*fat+filenames
187
        cmp     [esp+16], dword 0; wanted cluster ?
187
        cmp     [esp+16], dword 0; wanted cluster ?
188
        jne     frfl7_1
188
        jne     frfl7_1
189
        call    read_chs_sector
189
        call    read_chs_sector
190
        cmp     [FDC_Status], 0
190
        cmp     [FDC_Status], 0
191
        jne     fdc_status_error_5
191
        jne     fdc_status_error_5
192
        mov     edi, [esp+8]
192
        mov     edi, [esp+8]
193
        call    give_back_application_data_1
193
        call    give_back_application_data_1
194
        add     [esp+8], dword 512
194
        add     [esp+8], dword 512
195
        dec     dword [esp+12]   ; last wanted cluster ?
195
        dec     dword [esp+12]   ; last wanted cluster ?
196
        cmp     [esp+12], dword 0
196
        cmp     [esp+12], dword 0
197
        je      frnoread_1
197
        je      frnoread_1
198
        jmp     frfl8_1
198
        jmp     frfl8_1
199
frfl7_1:
199
frfl7_1:
200
        dec     dword [esp+16]
200
        dec     dword [esp+16]
201
frfl8_1:
201
frfl8_1:
202
        mov     edi, [n_sector]
202
        mov     edi, [n_sector]
203
        shl     edi, 1      ;find next cluster from FAT
203
        shl     edi, 1      ;find next cluster from FAT
204
        add     edi, FLOPPY_FAT
204
        add     edi, FLOPPY_FAT
205
        mov     eax, [edi]
205
        mov     eax, [edi]
206
        and     eax, 4095
206
        and     eax, 4095
207
        mov     edi, eax
207
        mov     edi, eax
208
        mov     [n_sector], edi
208
        mov     [n_sector], edi
209
        cmp     edi, 4095   ;eof  - cluster
209
        cmp     edi, 4095   ;eof  - cluster
210
        jz      frnoread2_1
210
        jz      frnoread2_1
211
        cmp     [esp+24], dword 512;eof  - size
211
        cmp     [esp+24], dword 512;eof  - size
212
        jb      frnoread_1
212
        jb      frnoread_1
213
        sub     [esp+24], dword 512
213
        sub     [esp+24], dword 512
214
        jmp     frnew_1
214
        jmp     frnew_1
215
 
215
 
216
read_chs_sector:
216
read_chs_sector:
217
        call    calculate_chs
217
        call    calculate_chs
218
        call    ReadSectWithRetr
218
        call    ReadSectWithRetr
219
        ret
219
        ret
220
 
220
 
221
frnoread2_1:
221
frnoread2_1:
222
        cmp     [esp+16], dword 0; eof without read ?
222
        cmp     [esp+16], dword 0; eof without read ?
223
        je      frnoread_1
223
        je      frnoread_1
224
        mov     [fdc_irq_func], fdc_null
224
        mov     [fdc_irq_func], fdc_null
225
        pop     edi esi edx ecx
225
        pop     edi esi edx ecx
226
        add     esp, 4
226
        add     esp, 4
227
        pop     ebx; ebx <- eax : size of file
227
        pop     ebx; ebx <- eax : size of file
228
        add     esp, 36
228
        add     esp, 36
229
        mov     eax, 6; end of file
229
        mov     eax, 6; end of file
230
        mov     [flp_status], 0
230
        mov     [flp_status], 0
231
        ret
231
        ret
232
 
232
 
233
frnoread_1:
233
frnoread_1:
234
        pop     edi esi edx ecx
234
        pop     edi esi edx ecx
235
        add     esp, 4
235
        add     esp, 4
236
        pop     ebx; ebx <- eax : size of file
236
        pop     ebx; ebx <- eax : size of file
237
        add     esp, 36
237
        add     esp, 36
238
        xor     eax, eax
238
        xor     eax, eax
239
        mov     [flp_status], eax
239
        mov     [flp_status], eax
240
        ret
240
        ret
241
 
241
 
242
fdc_status_error_5:
242
fdc_status_error_5:
243
        pop     edi esi edx ecx
243
        pop     edi esi edx ecx
244
        add     esp, 4
244
        add     esp, 4
245
        pop     ebx; ebx <- eax : size of file
245
        pop     ebx; ebx <- eax : size of file
246
        add     esp, 36
246
        add     esp, 36
247
        jmp     fdc_status_error_1
247
        jmp     fdc_status_error_1
248
 
248
 
249
read_flp_root:
249
read_flp_root:
250
        pusha
250
        pusha
251
        call    check_label
251
        call    check_label
252
        cmp     [FDC_Status], 0
252
        cmp     [FDC_Status], 0
253
        jne     unnecessary_root_read
253
        jne     unnecessary_root_read
254
        cmp     [root_read], 1
254
        cmp     [root_read], 1
255
        je      unnecessary_root_read
255
        je      unnecessary_root_read
256
        mov     [FDD_Track], 0; Öèëèíäð
256
        mov     [FDD_Track], 0; Цилиндр
257
        mov     [FDD_Head], 1; Ñòîðîíà
257
        mov     [FDD_Head], 1; Сторона
258
        mov     [FDD_Sector], 2; Ñåêòîð
258
        mov     [FDD_Sector], 2; Сектор
259
        mov     edi, FLOPPY_BUFF
259
        mov     edi, FLOPPY_BUFF
260
        call    SeekTrack
260
        call    SeekTrack
261
read_flp_root_1:
261
read_flp_root_1:
262
        call    ReadSectWithRetr
262
        call    ReadSectWithRetr
263
        cmp     [FDC_Status], 0
263
        cmp     [FDC_Status], 0
264
        jne     unnecessary_root_read
264
        jne     unnecessary_root_read
265
        push    edi
265
        push    edi
266
        call    give_back_application_data_1
266
        call    give_back_application_data_1
267
        pop     edi
267
        pop     edi
268
        add     edi, 512
268
        add     edi, 512
269
        inc     [FDD_Sector]
269
        inc     [FDD_Sector]
270
        cmp     [FDD_Sector], 16
270
        cmp     [FDD_Sector], 16
271
        jne     read_flp_root_1
271
        jne     read_flp_root_1
272
        mov     [root_read], 1
272
        mov     [root_read], 1
273
unnecessary_root_read:
273
unnecessary_root_read:
274
        popa
274
        popa
275
        ret
275
        ret
276
 
276
 
277
 
277
 
278
read_flp_fat:
278
read_flp_fat:
279
        pusha
279
        pusha
280
        call    check_label
280
        call    check_label
281
        cmp     [FDC_Status], 0
281
        cmp     [FDC_Status], 0
282
        jne     unnecessary_flp_fat
282
        jne     unnecessary_flp_fat
283
        cmp     [flp_fat], 1
283
        cmp     [flp_fat], 1
284
        je      unnecessary_flp_fat
284
        je      unnecessary_flp_fat
285
        mov     [FDD_Track], 0; Öèëèíäð
285
        mov     [FDD_Track], 0; Цилиндр
286
        mov     [FDD_Head], 0; Ñòîðîíà
286
        mov     [FDD_Head], 0; Сторона
287
        mov     [FDD_Sector], 2; Ñåêòîð
287
        mov     [FDD_Sector], 2; Сектор
288
        mov     edi, FLOPPY_BUFF
288
        mov     edi, FLOPPY_BUFF
289
        call    SeekTrack
289
        call    SeekTrack
290
read_flp_fat_1:
290
read_flp_fat_1:
291
        call    ReadSectWithRetr
291
        call    ReadSectWithRetr
292
        cmp     [FDC_Status], 0
292
        cmp     [FDC_Status], 0
293
        jne     unnecessary_flp_fat
293
        jne     unnecessary_flp_fat
294
        push    edi
294
        push    edi
295
        call    give_back_application_data_1
295
        call    give_back_application_data_1
296
        pop     edi
296
        pop     edi
297
        add     edi, 512
297
        add     edi, 512
298
        inc     [FDD_Sector]
298
        inc     [FDD_Sector]
299
        cmp     [FDD_Sector], 19
299
        cmp     [FDD_Sector], 19
300
        jne     read_flp_fat_1
300
        jne     read_flp_fat_1
301
        mov     [FDD_Sector], 1
301
        mov     [FDD_Sector], 1
302
        mov     [FDD_Head], 1
302
        mov     [FDD_Head], 1
303
        call    ReadSectWithRetr
303
        call    ReadSectWithRetr
304
        cmp     [FDC_Status], 0
304
        cmp     [FDC_Status], 0
305
        jne     unnecessary_flp_fat
305
        jne     unnecessary_flp_fat
306
        call    give_back_application_data_1
306
        call    give_back_application_data_1
307
        call    calculatefatchain_flp
307
        call    calculatefatchain_flp
308
        mov     [root_read], 0
308
        mov     [root_read], 0
309
        mov     [flp_fat], 1
309
        mov     [flp_fat], 1
310
unnecessary_flp_fat:
310
unnecessary_flp_fat:
311
        popa
311
        popa
312
        ret
312
        ret
313
 
313
 
314
calculatefatchain_flp:
314
calculatefatchain_flp:
315
        pushad
315
        pushad
316
 
316
 
317
        mov     esi, FLOPPY_BUFF
317
        mov     esi, FLOPPY_BUFF
318
        mov     edi, FLOPPY_FAT
318
        mov     edi, FLOPPY_FAT
319
 
319
 
320
 fcnew_1:
320
 fcnew_1:
321
        mov     eax, dword [esi]
321
        mov     eax, dword [esi]
322
        mov     ebx, dword [esi+4]
322
        mov     ebx, dword [esi+4]
323
        mov     ecx, dword [esi+8]
323
        mov     ecx, dword [esi+8]
324
        mov     edx, ecx
324
        mov     edx, ecx
325
        shr     edx, 4;8 ok
325
        shr     edx, 4;8 ok
326
        shr     dx, 4;7 ok
326
        shr     dx, 4;7 ok
327
        xor     ch, ch
327
        xor     ch, ch
328
        shld    ecx, ebx, 20;6 ok
328
        shld    ecx, ebx, 20;6 ok
329
        shr     cx, 4;5 ok
329
        shr     cx, 4;5 ok
330
        shld    ebx, eax, 12
330
        shld    ebx, eax, 12
331
        and     ebx, 0x0fffffff;4 ok
331
        and     ebx, 0x0fffffff;4 ok
332
        shr     bx, 4;3 ok
332
        shr     bx, 4;3 ok
333
        shl     eax, 4
333
        shl     eax, 4
334
        and     eax, 0x0fffffff;2 ok
334
        and     eax, 0x0fffffff;2 ok
335
        shr     ax, 4;1 ok
335
        shr     ax, 4;1 ok
336
        mov     dword [edi], eax
336
        mov     dword [edi], eax
337
        add     edi, 4
337
        add     edi, 4
338
        mov     dword [edi], ebx
338
        mov     dword [edi], ebx
339
        add     edi, 4
339
        add     edi, 4
340
        mov     dword [edi], ecx
340
        mov     dword [edi], ecx
341
        add     edi, 4
341
        add     edi, 4
342
        mov     dword [edi], edx
342
        mov     dword [edi], edx
343
        add     edi, 4
343
        add     edi, 4
344
        add     esi, 12
344
        add     esi, 12
345
 
345
 
346
        cmp     edi, FLOPPY_FAT+2856*2;2849 clusters
346
        cmp     edi, FLOPPY_FAT+2856*2;2849 clusters
347
        jnz     fcnew_1
347
        jnz     fcnew_1
348
 
348
 
349
        popad
349
        popad
350
        ret
350
        ret
351
 
351
 
352
check_label:
352
check_label:
353
        pushad
353
        pushad
354
        mov     [FDD_Track], 0; Öèëèíäð
354
        mov     [FDD_Track], 0; Цилиндр
355
        mov     [FDD_Head], 0; Ñòîðîíà
355
        mov     [FDD_Head], 0; Сторона
356
        mov     [FDD_Sector], 1; Ñåêòîð
356
        mov     [FDD_Sector], 1; Сектор
357
        call    SetUserInterrupts
357
        call    SetUserInterrupts
358
        call    FDDMotorON
358
        call    FDDMotorON
359
        call    RecalibrateFDD
359
        call    RecalibrateFDD
360
        cmp     [FDC_Status], 0
360
        cmp     [FDC_Status], 0
361
        jne     fdc_status_error
361
        jne     fdc_status_error
362
        call    SeekTrack
362
        call    SeekTrack
363
        cmp     [FDC_Status], 0
363
        cmp     [FDC_Status], 0
364
        jne     fdc_status_error
364
        jne     fdc_status_error
365
        call    ReadSectWithRetr
365
        call    ReadSectWithRetr
366
        cmp     [FDC_Status], 0
366
        cmp     [FDC_Status], 0
367
        jne     fdc_status_error
367
        jne     fdc_status_error
368
        mov     esi, flp_label
368
        mov     esi, flp_label
369
        mov     edi, FDD_BUFF+39
369
        mov     edi, FDD_BUFF+39
370
        mov     ecx, 15
370
        mov     ecx, 15
371
        cld
371
        cld
372
        rep cmpsb
372
        rep cmpsb
373
        je      same_label
373
        je      same_label
374
        mov     [root_read], 0
374
        mov     [root_read], 0
375
        mov     [flp_fat], 0
375
        mov     [flp_fat], 0
376
same_label:
376
same_label:
377
        mov     esi, FDD_BUFF+39
377
        mov     esi, FDD_BUFF+39
378
        mov     edi, flp_label
378
        mov     edi, flp_label
379
        mov     ecx, 15
379
        mov     ecx, 15
380
        cld
380
        cld
381
        rep movsb
381
        rep movsb
382
        popad
382
        popad
383
        ret
383
        ret
384
fdc_status_error:
384
fdc_status_error:
385
        popad
385
        popad
386
        ret
386
        ret
387
 
387
 
388
save_flp_root:
388
save_flp_root:
389
        pusha
389
        pusha
390
        call    check_label
390
        call    check_label
391
        cmp     [FDC_Status], 0
391
        cmp     [FDC_Status], 0
392
        jne     unnecessary_root_save
392
        jne     unnecessary_root_save
393
        cmp     [root_read], 0
393
        cmp     [root_read], 0
394
        je      unnecessary_root_save
394
        je      unnecessary_root_save
395
        mov     [FDD_Track], 0; Öèëèíäð
395
        mov     [FDD_Track], 0; Цилиндр
396
        mov     [FDD_Head], 1; Ñòîðîíà
396
        mov     [FDD_Head], 1; Сторона
397
        mov     [FDD_Sector], 2; Ñåêòîð
397
        mov     [FDD_Sector], 2; Сектор
398
        mov     esi, FLOPPY_BUFF
398
        mov     esi, FLOPPY_BUFF
399
        call    SeekTrack
399
        call    SeekTrack
400
save_flp_root_1:
400
save_flp_root_1:
401
        push    esi
401
        push    esi
402
        call    take_data_from_application_1
402
        call    take_data_from_application_1
403
        pop     esi
403
        pop     esi
404
        add     esi, 512
404
        add     esi, 512
405
        call    WriteSectWithRetr
405
        call    WriteSectWithRetr
406
        cmp     [FDC_Status], 0
406
        cmp     [FDC_Status], 0
407
        jne     unnecessary_root_save
407
        jne     unnecessary_root_save
408
        inc     [FDD_Sector]
408
        inc     [FDD_Sector]
409
        cmp     [FDD_Sector], 16
409
        cmp     [FDD_Sector], 16
410
        jne     save_flp_root_1
410
        jne     save_flp_root_1
411
unnecessary_root_save:
411
unnecessary_root_save:
412
        mov     [fdc_irq_func], fdc_null
412
        mov     [fdc_irq_func], fdc_null
413
        popa
413
        popa
414
        ret
414
        ret
415
 
415
 
416
save_flp_fat:
416
save_flp_fat:
417
        pusha
417
        pusha
418
        call    check_label
418
        call    check_label
419
        cmp     [FDC_Status], 0
419
        cmp     [FDC_Status], 0
420
        jne     unnecessary_flp_fat_save
420
        jne     unnecessary_flp_fat_save
421
        cmp     [flp_fat], 0
421
        cmp     [flp_fat], 0
422
        je      unnecessary_flp_fat_save
422
        je      unnecessary_flp_fat_save
423
        call    restorefatchain_flp
423
        call    restorefatchain_flp
424
        mov     [FDD_Track], 0; Öèëèíäð
424
        mov     [FDD_Track], 0; Цилиндр
425
        mov     [FDD_Head], 0; Ñòîðîíà
425
        mov     [FDD_Head], 0; Сторона
426
        mov     [FDD_Sector], 2; Ñåêòîð
426
        mov     [FDD_Sector], 2; Сектор
427
        mov     esi, FLOPPY_BUFF
427
        mov     esi, FLOPPY_BUFF
428
        call    SeekTrack
428
        call    SeekTrack
429
save_flp_fat_1:
429
save_flp_fat_1:
430
        push    esi
430
        push    esi
431
        call    take_data_from_application_1
431
        call    take_data_from_application_1
432
        pop     esi
432
        pop     esi
433
        add     esi, 512
433
        add     esi, 512
434
        call    WriteSectWithRetr
434
        call    WriteSectWithRetr
435
        cmp     [FDC_Status], 0
435
        cmp     [FDC_Status], 0
436
        jne     unnecessary_flp_fat_save
436
        jne     unnecessary_flp_fat_save
437
        inc     [FDD_Sector]
437
        inc     [FDD_Sector]
438
        cmp     [FDD_Sector], 19
438
        cmp     [FDD_Sector], 19
439
        jne     save_flp_fat_1
439
        jne     save_flp_fat_1
440
        mov     [FDD_Sector], 1
440
        mov     [FDD_Sector], 1
441
        mov     [FDD_Head], 1
441
        mov     [FDD_Head], 1
442
        call    take_data_from_application_1
442
        call    take_data_from_application_1
443
        call    WriteSectWithRetr
443
        call    WriteSectWithRetr
444
        cmp     [FDC_Status], 0
444
        cmp     [FDC_Status], 0
445
        jne     unnecessary_flp_fat_save
445
        jne     unnecessary_flp_fat_save
446
        mov     [root_read], 0
446
        mov     [root_read], 0
447
unnecessary_flp_fat_save:
447
unnecessary_flp_fat_save:
448
        mov     [fdc_irq_func], fdc_null
448
        mov     [fdc_irq_func], fdc_null
449
        popa
449
        popa
450
        ret
450
        ret
451
 
451
 
452
 
452
 
453
restorefatchain_flp:   ; restore fat chain
453
restorefatchain_flp:   ; restore fat chain
454
        pushad
454
        pushad
455
 
455
 
456
        mov     esi, FLOPPY_FAT
456
        mov     esi, FLOPPY_FAT
457
        mov     edi, FLOPPY_BUFF
457
        mov     edi, FLOPPY_BUFF
458
 
458
 
459
  fcnew2_1:
459
  fcnew2_1:
460
        mov     eax, dword [esi]
460
        mov     eax, dword [esi]
461
        mov     ebx, dword [esi+4]
461
        mov     ebx, dword [esi+4]
462
        shl     ax, 4
462
        shl     ax, 4
463
        shl     eax, 4
463
        shl     eax, 4
464
        shl     bx, 4
464
        shl     bx, 4
465
        shr     ebx, 4
465
        shr     ebx, 4
466
        shrd    eax, ebx, 8
466
        shrd    eax, ebx, 8
467
        shr     ebx, 8
467
        shr     ebx, 8
468
        mov     dword [edi], eax
468
        mov     dword [edi], eax
469
        add     edi, 4
469
        add     edi, 4
470
        mov     word [edi], bx
470
        mov     word [edi], bx
471
        add     edi, 2
471
        add     edi, 2
472
        add     esi, 8
472
        add     esi, 8
473
 
473
 
474
        cmp     edi, FLOPPY_BUFF+0x1200;4274 bytes - all used FAT
474
        cmp     edi, FLOPPY_BUFF+0x1200;4274 bytes - all used FAT
475
        jb      fcnew2_1
475
        jb      fcnew2_1
476
 
476
 
477
        mov     esi, FLOPPY_BUFF  ; duplicate fat chain
477
        mov     esi, FLOPPY_BUFF  ; duplicate fat chain
478
        mov     edi, FLOPPY_BUFF+0x1200
478
        mov     edi, FLOPPY_BUFF+0x1200
479
        mov     ecx, 0x1200/4
479
        mov     ecx, 0x1200/4
480
        cld
480
        cld
481
        rep movsd
481
        rep movsd
482
 
482
 
483
        popad
483
        popad
484
        ret
484
        ret
485
 
485
 
486
 
486
 
487
save_chs_sector:
487
save_chs_sector:
488
        call    calculate_chs
488
        call    calculate_chs
489
        call    WriteSectWithRetr
489
        call    WriteSectWithRetr
490
        ret
490
        ret
491
 
491
 
492
calculate_chs:
492
calculate_chs:
493
        mov     bl, [FDD_Track]
493
        mov     bl, [FDD_Track]
494
        mov     [old_track], bl
494
        mov     [old_track], bl
495
        mov     ebx, 18
495
        mov     ebx, 18
496
        xor     edx, edx
496
        xor     edx, edx
497
        div     ebx
497
        div     ebx
498
        inc     edx
498
        inc     edx
499
        mov     [FDD_Sector], dl
499
        mov     [FDD_Sector], dl
500
        xor     edx, edx
500
        xor     edx, edx
501
        mov     ebx, 2
501
        mov     ebx, 2
502
        div     ebx
502
        div     ebx
503
        mov     [FDD_Track], al
503
        mov     [FDD_Track], al
504
        mov     [FDD_Head], 0
504
        mov     [FDD_Head], 0
505
        test    edx, edx
505
        test    edx, edx
506
        jz      no_head_2
506
        jz      no_head_2
507
        inc     [FDD_Head]
507
        inc     [FDD_Head]
508
no_head_2:
508
no_head_2:
509
        mov     dl, [old_track]
509
        mov     dl, [old_track]
510
        cmp     dl, [FDD_Track]
510
        cmp     dl, [FDD_Track]
511
        je      no_seek_track_1
511
        je      no_seek_track_1
512
        call    SeekTrack
512
        call    SeekTrack
513
no_seek_track_1:
513
no_seek_track_1:
514
        ret
514
        ret
515
 
515
 
516
 
516
 
517
get_cluster_of_a_path_flp:
517
get_cluster_of_a_path_flp:
518
;---------------------------------------------------------
518
;---------------------------------------------------------
519
; input  : EBX = pointer to a path string
519
; input  : EBX = pointer to a path string
520
;          (example: the path "/files/data/document" become
520
;          (example: the path "/files/data/document" become
521
;                             "files......data.......document...0"
521
;                             "files......data.......document...0"
522
;          '.' = space char
522
;          '.' = space char
523
;          '0' = char(0) (ASCII=0) !!! )
523
;          '0' = char(0) (ASCII=0) !!! )
524
; output : if (CARRY=1) -> ERROR in the PATH
524
; output : if (CARRY=1) -> ERROR in the PATH
525
;          if (CARRY=0) -> EAX=cluster
525
;          if (CARRY=0) -> EAX=cluster
526
;---------------------------------------------------------
526
;---------------------------------------------------------
527
 
527
 
528
        push    edx
528
        push    edx
529
        mov     edx, ebx
529
        mov     edx, ebx
530
 
530
 
531
search_end_of_path_flp:
531
search_end_of_path_flp:
532
        cmp     [save_flag], 0
532
        cmp     [save_flag], 0
533
        jne     search_end_of_path_flp_1
533
        jne     search_end_of_path_flp_1
534
        cmp     byte [edx], 0
534
        cmp     byte [edx], 0
535
        je      found_end_of_path_flp
535
        je      found_end_of_path_flp
536
        jmp     search_end_of_path_flp_2
536
        jmp     search_end_of_path_flp_2
537
search_end_of_path_flp_1:
537
search_end_of_path_flp_1:
538
        cmp     byte [edx+12], 0
538
        cmp     byte [edx+12], 0
539
        je      found_end_of_path_flp
539
        je      found_end_of_path_flp
540
search_end_of_path_flp_2:
540
search_end_of_path_flp_2:
541
        inc     edx; '/'
541
        inc     edx; '/'
542
        call    analyze_directory_flp
542
        call    analyze_directory_flp
543
        jc      directory_not_found_flp
543
        jc      directory_not_found_flp
544
 
544
 
545
        mov     eax, [ebx+20-2] ; read the HIGH 16bit cluster field
545
        mov     eax, [ebx+20-2] ; read the HIGH 16bit cluster field
546
        mov     ax, [ebx+26]    ; read the LOW 16bit cluster field
546
        mov     ax, [ebx+26]    ; read the LOW 16bit cluster field
547
        and     eax, 0xfff    ;[fatMASK]
547
        and     eax, 0xfff    ;[fatMASK]
548
        add     edx, 11         ; 8+3 (name+extension)
548
        add     edx, 11         ; 8+3 (name+extension)
549
        jmp     search_end_of_path_flp
549
        jmp     search_end_of_path_flp
550
 
550
 
551
found_end_of_path_flp:
551
found_end_of_path_flp:
552
        inc     edx
552
        inc     edx
553
        mov     [pointer_file_name_flp], edx
553
        mov     [pointer_file_name_flp], edx
554
        pop     edx
554
        pop     edx
555
        clc                     ; no errors
555
        clc                     ; no errors
556
        ret
556
        ret
557
 
557
 
558
directory_not_found_flp:
558
directory_not_found_flp:
559
        pop     edx
559
        pop     edx
560
        stc                     ; errors occour
560
        stc                     ; errors occour
561
        ret
561
        ret
562
 
562
 
563
analyze_directory_flp:
563
analyze_directory_flp:
564
;--------------------------------
564
;--------------------------------
565
; input  : EAX = first cluster of the directory
565
; input  : EAX = first cluster of the directory
566
;          EBX = pointer to filename
566
;          EBX = pointer to filename
567
; output : IF CARRY=0 EAX = sector where th file is found
567
; output : IF CARRY=0 EAX = sector where th file is found
568
;                     EBX = pointer in buffer
568
;                     EBX = pointer in buffer
569
;                     [buffer .. buffer+511]
569
;                     [buffer .. buffer+511]
570
;                     ECX,EDX,EDI,EDI not changed
570
;                     ECX,EDX,EDI,EDI not changed
571
;          IF CARRY=1
571
;          IF CARRY=1
572
;--------------------------------
572
;--------------------------------
573
        push    ebx;[esp+16]
573
        push    ebx;[esp+16]
574
        push    ecx
574
        push    ecx
575
        push    edx
575
        push    edx
576
        push    esi
576
        push    esi
577
        push    edi
577
        push    edi
578
 
578
 
579
 
579
 
580
adr56_flp:
580
adr56_flp:
581
        mov     [clust_tmp_flp], eax
581
        mov     [clust_tmp_flp], eax
582
        add     eax, 31
582
        add     eax, 31
583
        pusha
583
        pusha
584
        call    read_chs_sector
584
        call    read_chs_sector
585
        popa
585
        popa
586
        cmp     [FDC_Status], 0
586
        cmp     [FDC_Status], 0
587
        jne     not_found_file_analyze_flp
587
        jne     not_found_file_analyze_flp
588
 
588
 
589
        mov     ecx, 512/32
589
        mov     ecx, 512/32
590
        mov     ebx, FDD_BUFF
590
        mov     ebx, FDD_BUFF
591
 
591
 
592
adr1_analyze_flp:
592
adr1_analyze_flp:
593
        mov     esi, edx;[esp+16]
593
        mov     esi, edx;[esp+16]
594
        mov     edi, ebx
594
        mov     edi, ebx
595
        cld
595
        cld
596
        push    ecx
596
        push    ecx
597
        mov     ecx, 11
597
        mov     ecx, 11
598
        rep cmpsb
598
        rep cmpsb
599
        pop     ecx
599
        pop     ecx
600
        je      found_file_analyze_flp
600
        je      found_file_analyze_flp
601
 
601
 
602
        add     ebx, 32
602
        add     ebx, 32
603
        loop    adr1_analyze_flp
603
        loop    adr1_analyze_flp
604
 
604
 
605
        mov     eax, [clust_tmp_flp]
605
        mov     eax, [clust_tmp_flp]
606
        shl     eax, 1      ;find next cluster from FAT
606
        shl     eax, 1      ;find next cluster from FAT
607
        add     eax, FLOPPY_FAT
607
        add     eax, FLOPPY_FAT
608
        mov     eax, [eax]
608
        mov     eax, [eax]
609
        and     eax, 4095
609
        and     eax, 4095
610
        cmp     eax, 0x0ff8
610
        cmp     eax, 0x0ff8
611
        jb      adr56_flp
611
        jb      adr56_flp
612
not_found_file_analyze_flp:
612
not_found_file_analyze_flp:
613
        pop     edi
613
        pop     edi
614
        pop     esi
614
        pop     esi
615
        pop     edx
615
        pop     edx
616
        pop     ecx
616
        pop     ecx
617
        add     esp, 4
617
        add     esp, 4
618
        stc     ;file not found
618
        stc     ;file not found
619
        ret
619
        ret
620
 
620
 
621
found_file_analyze_flp:
621
found_file_analyze_flp:
622
        pop     edi
622
        pop     edi
623
        pop     esi
623
        pop     esi
624
        pop     edx
624
        pop     edx
625
        pop     ecx
625
        pop     ecx
626
        add     esp, 4
626
        add     esp, 4
627
        clc     ;file found
627
        clc     ;file found
628
        ret
628
        ret
629
 
629
 
630
 
630
 
631
; \begin{diamond}
631
; \begin{diamond}
632
fat_find_lfn:
632
fat_find_lfn:
633
; in: esi->name
633
; in: esi->name
634
;     [esp+4] = next
634
;     [esp+4] = next
635
;     [esp+8] = first
635
;     [esp+8] = first
636
;     [esp+C]... - possibly parameters for first and next
636
;     [esp+C]... - possibly parameters for first and next
637
; out: CF=1 - file not found, eax=error code
637
; out: CF=1 - file not found, eax=error code
638
;      else CF=0, esi->next name component, edi->direntry
638
;      else CF=0, esi->next name component, edi->direntry
639
        pusha
639
        pusha
640
        lea     eax, [esp+0Ch+20h]
640
        lea     eax, [esp+0Ch+20h]
641
        call    dword [eax-4]
641
        call    dword [eax-4]
642
        jc      .reterr
642
        jc      .reterr
643
        sub     esp, 262*2      ; reserve place for LFN
643
        sub     esp, 262*2      ; reserve place for LFN
644
        push    0               ; for fat_get_name: read ASCII name
644
        push    0               ; for fat_get_name: read ASCII name
645
.l1:
645
.l1:
646
        lea     ebp, [esp+4]
646
        lea     ebp, [esp+4]
647
        call    fat_get_name
647
        call    fat_get_name
648
        jc      .l2
648
        jc      .l2
649
        call    fat_compare_name
649
        call    fat_compare_name
650
        jz      .found
650
        jz      .found
651
.l2:
651
.l2:
652
        mov     ebp, [esp+8+262*2+4]
652
        mov     ebp, [esp+8+262*2+4]
653
        lea     eax, [esp+0Ch+20h+262*2+4]
653
        lea     eax, [esp+0Ch+20h+262*2+4]
654
        call    dword [eax-8]
654
        call    dword [eax-8]
655
        jnc     .l1
655
        jnc     .l1
656
        add     esp, 262*2+4
656
        add     esp, 262*2+4
657
.reterr:
657
.reterr:
658
        mov     [esp+28], eax
658
        mov     [esp+28], eax
659
        stc
659
        stc
660
        popa
660
        popa
661
        ret
661
        ret
662
.found:
662
.found:
663
        add     esp, 262*2+4
663
        add     esp, 262*2+4
664
        mov     ebp, [esp+8]
664
        mov     ebp, [esp+8]
665
; if this is LFN entry, advance to true entry
665
; if this is LFN entry, advance to true entry
666
        cmp     byte [edi+11], 0xF
666
        cmp     byte [edi+11], 0xF
667
        jnz     @f
667
        jnz     @f
668
        lea     eax, [esp+0Ch+20h]
668
        lea     eax, [esp+0Ch+20h]
669
        call    dword [eax-8]
669
        call    dword [eax-8]
670
        jc      .reterr
670
        jc      .reterr
671
@@:
671
@@:
672
        add     esp, 8          ; CF=0
672
        add     esp, 8          ; CF=0
673
        push    esi
673
        push    esi
674
        push    edi
674
        push    edi
675
        popa
675
        popa
676
        ret
676
        ret
677
 
677
 
678
uglobal
678
uglobal
679
; this is for delete support
679
; this is for delete support
680
fd_prev_sector          dd      ?
680
fd_prev_sector          dd      ?
681
fd_prev_prev_sector     dd      ?
681
fd_prev_prev_sector     dd      ?
682
endg
682
endg
683
 
683
 
684
flp_root_next:
684
flp_root_next:
685
        cmp     edi, OS_BASE+0xD200-0x20
685
        cmp     edi, OS_BASE+0xD200-0x20
686
        jae     @f
686
        jae     @f
687
        add     edi, 0x20
687
        add     edi, 0x20
688
        ret     ; CF=0
688
        ret     ; CF=0
689
@@:
689
@@:
690
; read next sector
690
; read next sector
691
        inc     dword [eax]
691
        inc     dword [eax]
692
        cmp     dword [eax], 14
692
        cmp     dword [eax], 14
693
        jae     flp_root_first.readerr
693
        jae     flp_root_first.readerr
694
        push    [fd_prev_sector]
694
        push    [fd_prev_sector]
695
        pop     [fd_prev_prev_sector]
695
        pop     [fd_prev_prev_sector]
696
        push    eax
696
        push    eax
697
        mov     eax, [eax]
697
        mov     eax, [eax]
698
        add     eax, 19-1
698
        add     eax, 19-1
699
        mov     [fd_prev_sector], eax
699
        mov     [fd_prev_sector], eax
700
        pop     eax
700
        pop     eax
701
flp_root_first:
701
flp_root_first:
702
        mov     eax, [eax]
702
        mov     eax, [eax]
703
        pusha
703
        pusha
704
        add     eax, 19
704
        add     eax, 19
705
        call    read_chs_sector
705
        call    read_chs_sector
706
        popa
706
        popa
707
        cmp     [FDC_Status], 0
707
        cmp     [FDC_Status], 0
708
        jnz     .readerr
708
        jnz     .readerr
709
        mov     edi, FDD_BUFF
709
        mov     edi, FDD_BUFF
710
        ret     ; CF=0
710
        ret     ; CF=0
711
.readerr:
711
.readerr:
712
        stc
712
        stc
713
        ret
713
        ret
714
 
714
 
715
flp_rootmem_first:
715
flp_rootmem_first:
716
        mov     edi, FLOPPY_BUFF
716
        mov     edi, FLOPPY_BUFF
717
        clc
717
        clc
718
        ret
718
        ret
719
flp_rootmem_next:
719
flp_rootmem_next:
720
        add     edi, 0x20
720
        add     edi, 0x20
721
        cmp     edi, FLOPPY_BUFF+14*0x200
721
        cmp     edi, FLOPPY_BUFF+14*0x200
722
        cmc
722
        cmc
723
flp_rootmem_next_write:
723
flp_rootmem_next_write:
724
flp_rootmem_begin_write:
724
flp_rootmem_begin_write:
725
flp_rootmem_end_write:
725
flp_rootmem_end_write:
726
        ret
726
        ret
727
flp_rootmem_extend_dir:
727
flp_rootmem_extend_dir:
728
        stc
728
        stc
729
        ret
729
        ret
730
 
730
 
731
flp_notroot_next:
731
flp_notroot_next:
732
        cmp     edi, OS_BASE+0xD200-0x20
732
        cmp     edi, OS_BASE+0xD200-0x20
733
        jae     flp_notroot_next_sector
733
        jae     flp_notroot_next_sector
734
        add     edi, 0x20
734
        add     edi, 0x20
735
        ret     ; CF=0
735
        ret     ; CF=0
736
flp_notroot_next_sector:
736
flp_notroot_next_sector:
737
        push    ecx
737
        push    ecx
738
        mov     ecx, [eax]
738
        mov     ecx, [eax]
739
        push    [fd_prev_sector]
739
        push    [fd_prev_sector]
740
        pop     [fd_prev_prev_sector]
740
        pop     [fd_prev_prev_sector]
741
        add     ecx, 31
741
        add     ecx, 31
742
        mov     [fd_prev_sector], ecx
742
        mov     [fd_prev_sector], ecx
743
        mov     ecx, [(ecx-31)*2+FLOPPY_FAT]
743
        mov     ecx, [(ecx-31)*2+FLOPPY_FAT]
744
        and     ecx, 0xFFF
744
        and     ecx, 0xFFF
745
        cmp     ecx, 2849
745
        cmp     ecx, 2849
746
        jae     flp_notroot_first.err2
746
        jae     flp_notroot_first.err2
747
        mov     [eax], ecx
747
        mov     [eax], ecx
748
        pop     ecx
748
        pop     ecx
749
flp_notroot_first:
749
flp_notroot_first:
750
        mov     eax, [eax]
750
        mov     eax, [eax]
751
        cmp     eax, 2
751
        cmp     eax, 2
752
        jb      .err
752
        jb      .err
753
        cmp     eax, 2849
753
        cmp     eax, 2849
754
        jae     .err
754
        jae     .err
755
        pusha
755
        pusha
756
        add     eax, 31
756
        add     eax, 31
757
        call    read_chs_sector
757
        call    read_chs_sector
758
        popa
758
        popa
759
        mov     edi, FDD_BUFF
759
        mov     edi, FDD_BUFF
760
        cmp     [FDC_Status], 0
760
        cmp     [FDC_Status], 0
761
        jnz     .err
761
        jnz     .err
762
        ret     ; CF=0
762
        ret     ; CF=0
763
.err2:
763
.err2:
764
        pop     ecx
764
        pop     ecx
765
.err:
765
.err:
766
        stc
766
        stc
767
        ret
767
        ret
768
flp_notroot_begin_write:
768
flp_notroot_begin_write:
769
        pusha
769
        pusha
770
        mov     eax, [eax]
770
        mov     eax, [eax]
771
        add     eax, 31
771
        add     eax, 31
772
        call    read_chs_sector
772
        call    read_chs_sector
773
        popa
773
        popa
774
        ret
774
        ret
775
flp_notroot_end_write:
775
flp_notroot_end_write:
776
        pusha
776
        pusha
777
        mov     eax, [eax]
777
        mov     eax, [eax]
778
        add     eax, 31
778
        add     eax, 31
779
        call    save_chs_sector
779
        call    save_chs_sector
780
        popa
780
        popa
781
        ret
781
        ret
782
flp_notroot_next_write:
782
flp_notroot_next_write:
783
        cmp     edi, OS_BASE+0xD200
783
        cmp     edi, OS_BASE+0xD200
784
        jae     @f
784
        jae     @f
785
        ret
785
        ret
786
@@:
786
@@:
787
        call    flp_notroot_end_write
787
        call    flp_notroot_end_write
788
        jmp     flp_notroot_next_sector
788
        jmp     flp_notroot_next_sector
789
flp_notroot_extend_dir:
789
flp_notroot_extend_dir:
790
; find free cluster in FAT
790
; find free cluster in FAT
791
        pusha
791
        pusha
792
        xor     eax, eax
792
        xor     eax, eax
793
        mov     edi, FLOPPY_FAT
793
        mov     edi, FLOPPY_FAT
794
        mov     ecx, 2849
794
        mov     ecx, 2849
795
        repnz scasw
795
        repnz scasw
796
        jnz     .notfound
796
        jnz     .notfound
797
        mov     word [edi-2], 0xFFF     ; mark as last cluster
797
        mov     word [edi-2], 0xFFF     ; mark as last cluster
798
        sub     edi, FLOPPY_FAT
798
        sub     edi, FLOPPY_FAT
799
        shr     edi, 1
799
        shr     edi, 1
800
        dec     edi
800
        dec     edi
801
        mov     eax, [esp+28]
801
        mov     eax, [esp+28]
802
        mov     ecx, [eax]
802
        mov     ecx, [eax]
803
        mov     [FLOPPY_FAT+ecx*2], di
803
        mov     [FLOPPY_FAT+ecx*2], di
804
        mov     [eax], edi
804
        mov     [eax], edi
805
        xor     eax, eax
805
        xor     eax, eax
806
        mov     edi, FDD_BUFF
806
        mov     edi, FDD_BUFF
807
        mov     ecx, 128
807
        mov     ecx, 128
808
        rep stosd
808
        rep stosd
809
        popa
809
        popa
810
        call    flp_notroot_end_write
810
        call    flp_notroot_end_write
811
        mov     edi, FDD_BUFF
811
        mov     edi, FDD_BUFF
812
        clc
812
        clc
813
        ret
813
        ret
814
.notfound:
814
.notfound:
815
        popa
815
        popa
816
        stc
816
        stc
817
        ret
817
        ret
818
 
818
 
819
fd_find_lfn:
819
fd_find_lfn:
820
; in: esi+ebp -> name
820
; in: esi+ebp -> name
821
; out: CF=1 - file not found
821
; out: CF=1 - file not found
822
;      else CF=0 and edi->direntry, eax=directory cluster (0 for root)
822
;      else CF=0 and edi->direntry, eax=directory cluster (0 for root)
823
        push    esi edi
823
        push    esi edi
824
        push    0
824
        push    0
825
        push    flp_root_first
825
        push    flp_root_first
826
        push    flp_root_next
826
        push    flp_root_next
827
.loop:
827
.loop:
828
        call    fat_find_lfn
828
        call    fat_find_lfn
829
        jc      .notfound
829
        jc      .notfound
830
        cmp     byte [esi], 0
830
        cmp     byte [esi], 0
831
        jz      .found
831
        jz      .found
832
.continue:
832
.continue:
833
        test    byte [edi+11], 10h
833
        test    byte [edi+11], 10h
834
        jz      .notfound
834
        jz      .notfound
835
        movzx   eax, word [edi+26]      ; cluster
835
        movzx   eax, word [edi+26]      ; cluster
836
        mov     [esp+8], eax
836
        mov     [esp+8], eax
837
        mov     dword [esp+4], flp_notroot_first
837
        mov     dword [esp+4], flp_notroot_first
838
        mov     dword [esp], flp_notroot_next
838
        mov     dword [esp], flp_notroot_next
839
        jmp     .loop
839
        jmp     .loop
840
.notfound:
840
.notfound:
841
        add     esp, 12
841
        add     esp, 12
842
        pop     edi esi
842
        pop     edi esi
843
        stc
843
        stc
844
        ret
844
        ret
845
.found:
845
.found:
846
        test    ebp, ebp
846
        test    ebp, ebp
847
        jz      @f
847
        jz      @f
848
        mov     esi, ebp
848
        mov     esi, ebp
849
        xor     ebp, ebp
849
        xor     ebp, ebp
850
        jmp     .continue
850
        jmp     .continue
851
@@:
851
@@:
852
        mov     eax, [esp+8]
852
        mov     eax, [esp+8]
853
        add     eax, 31
853
        add     eax, 31
854
        cmp     dword [esp], flp_root_next
854
        cmp     dword [esp], flp_root_next
855
        jnz     @f
855
        jnz     @f
856
        add     eax, -31+19
856
        add     eax, -31+19
857
@@:
857
@@:
858
        add     esp, 16         ; CF=0
858
        add     esp, 16         ; CF=0
859
        pop     esi
859
        pop     esi
860
        ret
860
        ret
861
 
861
 
862
;----------------------------------------------------------------
862
;----------------------------------------------------------------
863
;
863
;
864
;  fs_FloppyRead - LFN variant for reading floppy
864
;  fs_FloppyRead - LFN variant for reading floppy
865
;
865
;
866
;  esi  points to filename
866
;  esi  points to filename
867
;  ebx  pointer to 64-bit number = first wanted byte, 0+
867
;  ebx  pointer to 64-bit number = first wanted byte, 0+
868
;       may be ebx=0 - start from first byte
868
;       may be ebx=0 - start from first byte
869
;  ecx  number of bytes to read, 0+
869
;  ecx  number of bytes to read, 0+
870
;  edx  mem location to return data
870
;  edx  mem location to return data
871
;
871
;
872
;  ret ebx = bytes read or 0xffffffff file not found
872
;  ret ebx = bytes read or 0xffffffff file not found
873
;      eax = 0 ok read or other = errormsg
873
;      eax = 0 ok read or other = errormsg
874
;
874
;
875
;--------------------------------------------------------------
875
;--------------------------------------------------------------
876
fs_FloppyRead:
876
fs_FloppyRead:
877
        call    read_flp_fat
877
        call    read_flp_fat
878
        cmp     byte [esi], 0
878
        cmp     byte [esi], 0
879
        jnz     @f
879
        jnz     @f
880
        or      ebx, -1
880
        or      ebx, -1
881
        mov     eax, 10         ; access denied
881
        mov     eax, 10         ; access denied
882
        ret
882
        ret
883
@@:
883
@@:
884
        push    edi
884
        push    edi
885
        call    fd_find_lfn
885
        call    fd_find_lfn
886
        jnc     .found
886
        jnc     .found
887
        pop     edi
887
        pop     edi
888
        or      ebx, -1
888
        or      ebx, -1
889
        mov     eax, 5          ; file not found
889
        mov     eax, 5          ; file not found
890
        ret
890
        ret
891
.found:
891
.found:
892
        test    ebx, ebx
892
        test    ebx, ebx
893
        jz      .l1
893
        jz      .l1
894
        cmp     dword [ebx+4], 0
894
        cmp     dword [ebx+4], 0
895
        jz      @f
895
        jz      @f
896
        xor     ebx, ebx
896
        xor     ebx, ebx
897
.reteof:
897
.reteof:
898
        mov     eax, 6          ; EOF
898
        mov     eax, 6          ; EOF
899
        pop     edi
899
        pop     edi
900
        ret
900
        ret
901
@@:
901
@@:
902
        mov     ebx, [ebx]
902
        mov     ebx, [ebx]
903
.l1:
903
.l1:
904
        push    ecx edx
904
        push    ecx edx
905
        push    0
905
        push    0
906
        mov     eax, [edi+28]
906
        mov     eax, [edi+28]
907
        sub     eax, ebx
907
        sub     eax, ebx
908
        jb      .eof
908
        jb      .eof
909
        cmp     eax, ecx
909
        cmp     eax, ecx
910
        jae     @f
910
        jae     @f
911
        mov     ecx, eax
911
        mov     ecx, eax
912
        mov     byte [esp], 6           ; EOF
912
        mov     byte [esp], 6           ; EOF
913
@@:
913
@@:
914
        movzx   edi, word [edi+26]
914
        movzx   edi, word [edi+26]
915
.new:
915
.new:
916
        jecxz   .done
916
        jecxz   .done
917
        test    edi, edi
917
        test    edi, edi
918
        jz      .eof
918
        jz      .eof
919
        cmp     edi, 0xFF8
919
        cmp     edi, 0xFF8
920
        jae     .eof
920
        jae     .eof
921
        sub     ebx, 512
921
        sub     ebx, 512
922
        jae     .skip
922
        jae     .skip
923
        lea     eax, [edi+31]
923
        lea     eax, [edi+31]
924
        pusha
924
        pusha
925
        call    read_chs_sector
925
        call    read_chs_sector
926
        popa
926
        popa
927
        cmp     [FDC_Status], 0
927
        cmp     [FDC_Status], 0
928
        jnz     .err
928
        jnz     .err
929
        lea     eax, [FDD_BUFF+ebx+512]
929
        lea     eax, [FDD_BUFF+ebx+512]
930
        neg     ebx
930
        neg     ebx
931
        push    ecx
931
        push    ecx
932
        cmp     ecx, ebx
932
        cmp     ecx, ebx
933
        jbe     @f
933
        jbe     @f
934
        mov     ecx, ebx
934
        mov     ecx, ebx
935
@@:
935
@@:
936
        mov     ebx, edx
936
        mov     ebx, edx
937
        call    memmove
937
        call    memmove
938
        add     edx, ecx
938
        add     edx, ecx
939
        sub     [esp], ecx
939
        sub     [esp], ecx
940
        pop     ecx
940
        pop     ecx
941
        xor     ebx, ebx
941
        xor     ebx, ebx
942
.skip:
942
.skip:
943
        movzx   edi, word [edi*2+FLOPPY_FAT]
943
        movzx   edi, word [edi*2+FLOPPY_FAT]
944
        jmp     .new
944
        jmp     .new
945
.done:
945
.done:
946
        mov     ebx, edx
946
        mov     ebx, edx
947
        pop     eax edx ecx edi
947
        pop     eax edx ecx edi
948
        sub     ebx, edx
948
        sub     ebx, edx
949
        ret
949
        ret
950
.eof:
950
.eof:
951
        mov     ebx, edx
951
        mov     ebx, edx
952
        pop     eax edx ecx
952
        pop     eax edx ecx
953
        jmp     .reteof
953
        jmp     .reteof
954
.err:
954
.err:
955
        mov     ebx, edx
955
        mov     ebx, edx
956
        pop     eax edx ecx edi
956
        pop     eax edx ecx edi
957
        sub     ebx, edx
957
        sub     ebx, edx
958
        mov     al, 11
958
        mov     al, 11
959
        ret
959
        ret
960
 
960
 
961
;----------------------------------------------------------------
961
;----------------------------------------------------------------
962
;
962
;
963
;  fs_FloppyReadFolder - LFN variant for reading floppy folders
963
;  fs_FloppyReadFolder - LFN variant for reading floppy folders
964
;
964
;
965
;  esi  points to filename
965
;  esi  points to filename
966
;  ebx  pointer to structure: 32-bit number = first wanted block, 0+
966
;  ebx  pointer to structure: 32-bit number = first wanted block, 0+
967
;                           & flags (bitfields)
967
;                           & flags (bitfields)
968
; flags: bit 0: 0=ANSI names, 1=UNICODE names
968
; flags: bit 0: 0=ANSI names, 1=UNICODE names
969
;  ecx  number of blocks to read, 0+
969
;  ecx  number of blocks to read, 0+
970
;  edx  mem location to return data
970
;  edx  mem location to return data
971
;
971
;
972
;  ret ebx = blocks read or 0xffffffff folder not found
972
;  ret ebx = blocks read or 0xffffffff folder not found
973
;      eax = 0 ok read or other = errormsg
973
;      eax = 0 ok read or other = errormsg
974
;
974
;
975
;--------------------------------------------------------------
975
;--------------------------------------------------------------
976
fs_FloppyReadFolder:
976
fs_FloppyReadFolder:
977
        call    read_flp_fat
977
        call    read_flp_fat
978
        push    edi
978
        push    edi
979
        cmp     byte [esi], 0
979
        cmp     byte [esi], 0
980
        jz      .root
980
        jz      .root
981
        call    fd_find_lfn
981
        call    fd_find_lfn
982
        jnc     .found
982
        jnc     .found
983
        pop     edi
983
        pop     edi
984
        or      ebx, -1
984
        or      ebx, -1
985
        mov     eax, ERROR_FILE_NOT_FOUND
985
        mov     eax, ERROR_FILE_NOT_FOUND
986
        ret
986
        ret
987
.found:
987
.found:
988
        test    byte [edi+11], 0x10     ; do not allow read files
988
        test    byte [edi+11], 0x10     ; do not allow read files
989
        jnz     .found_dir
989
        jnz     .found_dir
990
        pop     edi
990
        pop     edi
991
        or      ebx, -1
991
        or      ebx, -1
992
        mov     eax, ERROR_ACCESS_DENIED
992
        mov     eax, ERROR_ACCESS_DENIED
993
        ret
993
        ret
994
.found_dir:
994
.found_dir:
995
        movzx   eax, word [edi+26]
995
        movzx   eax, word [edi+26]
996
        add     eax, 31
996
        add     eax, 31
997
        push    0
997
        push    0
998
        jmp     .doit
998
        jmp     .doit
999
.root:
999
.root:
1000
        mov     eax, 19
1000
        mov     eax, 19
1001
        push    14
1001
        push    14
1002
.doit:
1002
.doit:
1003
        push    ecx ebp
1003
        push    ecx ebp
1004
        sub     esp, 262*2      ; reserve space for LFN
1004
        sub     esp, 262*2      ; reserve space for LFN
1005
        mov     ebp, esp
1005
        mov     ebp, esp
1006
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE names
1006
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE names
1007
        mov     ebx, [ebx]
1007
        mov     ebx, [ebx]
1008
; init header
1008
; init header
1009
        push    eax ecx
1009
        push    eax ecx
1010
        mov     edi, edx
1010
        mov     edi, edx
1011
        mov     ecx, 32/4
1011
        mov     ecx, 32/4
1012
        xor     eax, eax
1012
        xor     eax, eax
1013
        rep stosd
1013
        rep stosd
1014
        pop     ecx eax
1014
        pop     ecx eax
1015
        mov     byte [edx], 1   ; version
1015
        mov     byte [edx], 1   ; version
1016
        mov     esi, edi        ; esi points to BDFE
1016
        mov     esi, edi        ; esi points to BDFE
1017
.main_loop:
1017
.main_loop:
1018
        pusha
1018
        pusha
1019
        call    read_chs_sector
1019
        call    read_chs_sector
1020
        popa
1020
        popa
1021
        cmp     [FDC_Status], 0
1021
        cmp     [FDC_Status], 0
1022
        jnz     .error
1022
        jnz     .error
1023
        mov     edi, FDD_BUFF
1023
        mov     edi, FDD_BUFF
1024
        push    eax
1024
        push    eax
1025
.l1:
1025
.l1:
1026
        call    fat_get_name
1026
        call    fat_get_name
1027
        jc      .l2
1027
        jc      .l2
1028
        cmp     byte [edi+11], 0xF
1028
        cmp     byte [edi+11], 0xF
1029
        jnz     .do_bdfe
1029
        jnz     .do_bdfe
1030
        add     edi, 0x20
1030
        add     edi, 0x20
1031
        cmp     edi, OS_BASE+0xD200
1031
        cmp     edi, OS_BASE+0xD200
1032
        jb      .do_bdfe
1032
        jb      .do_bdfe
1033
        pop     eax
1033
        pop     eax
1034
        inc     eax
1034
        inc     eax
1035
        dec     byte [esp+262*2+12]
1035
        dec     byte [esp+262*2+12]
1036
        jz      .done
1036
        jz      .done
1037
        jns     @f
1037
        jns     @f
1038
; read next sector from FAT
1038
; read next sector from FAT
1039
        mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
1039
        mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
1040
        and     eax, 0xFFF
1040
        and     eax, 0xFFF
1041
        cmp     eax, 0xFF8
1041
        cmp     eax, 0xFF8
1042
        jae     .done
1042
        jae     .done
1043
        add     eax, 31
1043
        add     eax, 31
1044
        mov     byte [esp+262*2+12], 0
1044
        mov     byte [esp+262*2+12], 0
1045
@@:
1045
@@:
1046
        pusha
1046
        pusha
1047
        call    read_chs_sector
1047
        call    read_chs_sector
1048
        popa
1048
        popa
1049
        cmp     [FDC_Status], 0
1049
        cmp     [FDC_Status], 0
1050
        jnz     .error
1050
        jnz     .error
1051
        mov     edi, FDD_BUFF
1051
        mov     edi, FDD_BUFF
1052
        push    eax
1052
        push    eax
1053
.do_bdfe:
1053
.do_bdfe:
1054
        inc     dword [edx+8]   ; new file found
1054
        inc     dword [edx+8]   ; new file found
1055
        dec     ebx
1055
        dec     ebx
1056
        jns     .l2
1056
        jns     .l2
1057
        dec     ecx
1057
        dec     ecx
1058
        js      .l2
1058
        js      .l2
1059
        inc     dword [edx+4]   ; new file block copied
1059
        inc     dword [edx+4]   ; new file block copied
1060
        call    fat_entry_to_bdfe
1060
        call    fat_entry_to_bdfe
1061
.l2:
1061
.l2:
1062
        add     edi, 0x20
1062
        add     edi, 0x20
1063
        cmp     edi, OS_BASE+0xD200
1063
        cmp     edi, OS_BASE+0xD200
1064
        jb      .l1
1064
        jb      .l1
1065
        pop     eax
1065
        pop     eax
1066
        inc     eax
1066
        inc     eax
1067
        dec     byte [esp+262*2+12]
1067
        dec     byte [esp+262*2+12]
1068
        jz      .done
1068
        jz      .done
1069
        jns     @f
1069
        jns     @f
1070
; read next sector from FAT
1070
; read next sector from FAT
1071
        mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
1071
        mov     eax, [(eax-31-1)*2+FLOPPY_FAT]
1072
        and     eax, 0xFFF
1072
        and     eax, 0xFFF
1073
        cmp     eax, 0xFF8
1073
        cmp     eax, 0xFF8
1074
        jae     .done
1074
        jae     .done
1075
        add     eax, 31
1075
        add     eax, 31
1076
        mov     byte [esp+262*2+12], 0
1076
        mov     byte [esp+262*2+12], 0
1077
@@:
1077
@@:
1078
        jmp     .main_loop
1078
        jmp     .main_loop
1079
.error:
1079
.error:
1080
        add     esp, 262*2+4
1080
        add     esp, 262*2+4
1081
        pop     ebp ecx edi edi
1081
        pop     ebp ecx edi edi
1082
        or      ebx, -1
1082
        or      ebx, -1
1083
        mov     eax, ERROR_FILE_NOT_FOUND
1083
        mov     eax, ERROR_FILE_NOT_FOUND
1084
        ret
1084
        ret
1085
.done:
1085
.done:
1086
        add     esp, 262*2+4
1086
        add     esp, 262*2+4
1087
        pop     ebp
1087
        pop     ebp
1088
        mov     ebx, [edx+4]
1088
        mov     ebx, [edx+4]
1089
        xor     eax, eax
1089
        xor     eax, eax
1090
        dec     ecx
1090
        dec     ecx
1091
        js      @f
1091
        js      @f
1092
        mov     al, ERROR_END_OF_FILE
1092
        mov     al, ERROR_END_OF_FILE
1093
@@:
1093
@@:
1094
        pop     ecx edi edi
1094
        pop     ecx edi edi
1095
        ret
1095
        ret
1096
 
1096
 
1097
;----------------------------------------------------------------
1097
;----------------------------------------------------------------
1098
;
1098
;
1099
;  fs_FloppyRewrite - LFN variant for writing sys floppy
1099
;  fs_FloppyRewrite - LFN variant for writing sys floppy
1100
;
1100
;
1101
;  esi  points to filename
1101
;  esi  points to filename
1102
;  ebx  ignored (reserved)
1102
;  ebx  ignored (reserved)
1103
;  ecx  number of bytes to write, 0+
1103
;  ecx  number of bytes to write, 0+
1104
;  edx  mem location to data
1104
;  edx  mem location to data
1105
;
1105
;
1106
;  ret ebx = number of written bytes
1106
;  ret ebx = number of written bytes
1107
;      eax = 0 ok read or other = errormsg
1107
;      eax = 0 ok read or other = errormsg
1108
;
1108
;
1109
;--------------------------------------------------------------
1109
;--------------------------------------------------------------
1110
@@:
1110
@@:
1111
        mov     eax, ERROR_ACCESS_DENIED
1111
        mov     eax, ERROR_ACCESS_DENIED
1112
        xor     ebx, ebx
1112
        xor     ebx, ebx
1113
        ret
1113
        ret
1114
fsfrfe2:
1114
fsfrfe2:
1115
        popad
1115
        popad
1116
fsfrfe:
1116
fsfrfe:
1117
        mov     eax, 11
1117
        mov     eax, 11
1118
        xor     ebx, ebx
1118
        xor     ebx, ebx
1119
        ret
1119
        ret
1120
 
1120
 
1121
fs_FloppyCreateFolder:
1121
fs_FloppyCreateFolder:
1122
        mov     al, 1
1122
        mov     al, 1
1123
        jmp     fs_FloppyRewrite.common
1123
        jmp     fs_FloppyRewrite.common
1124
 
1124
 
1125
fs_FloppyRewrite:
1125
fs_FloppyRewrite:
1126
        xor     eax, eax
1126
        xor     eax, eax
1127
.common:
1127
.common:
1128
        cmp     byte [esi], 0
1128
        cmp     byte [esi], 0
1129
        jz      @b
1129
        jz      @b
1130
        call    read_flp_fat
1130
        call    read_flp_fat
1131
        cmp     [FDC_Status], 0
1131
        cmp     [FDC_Status], 0
1132
        jnz     fsfrfe
1132
        jnz     fsfrfe
1133
        pushad
1133
        pushad
1134
        xor     edi, edi
1134
        xor     edi, edi
1135
        push    esi
1135
        push    esi
1136
        test    ebp, ebp
1136
        test    ebp, ebp
1137
        jz      @f
1137
        jz      @f
1138
        mov     esi, ebp
1138
        mov     esi, ebp
1139
@@:
1139
@@:
1140
        lodsb
1140
        lodsb
1141
        test    al, al
1141
        test    al, al
1142
        jz      @f
1142
        jz      @f
1143
        cmp     al, '/'
1143
        cmp     al, '/'
1144
        jnz     @b
1144
        jnz     @b
1145
        lea     edi, [esi-1]
1145
        lea     edi, [esi-1]
1146
        jmp     @b
1146
        jmp     @b
1147
@@:
1147
@@:
1148
        pop     esi
1148
        pop     esi
1149
        test    edi, edi
1149
        test    edi, edi
1150
        jnz     .noroot
1150
        jnz     .noroot
1151
        test    ebp, ebp
1151
        test    ebp, ebp
1152
        jnz     .hasebp
1152
        jnz     .hasebp
1153
        call    read_flp_root
1153
        call    read_flp_root
1154
        cmp     [FDC_Status], 0
1154
        cmp     [FDC_Status], 0
1155
        jnz     fsfrfe2
1155
        jnz     fsfrfe2
1156
        push    flp_rootmem_extend_dir
1156
        push    flp_rootmem_extend_dir
1157
        push    flp_rootmem_end_write
1157
        push    flp_rootmem_end_write
1158
        push    flp_rootmem_next_write
1158
        push    flp_rootmem_next_write
1159
        push    flp_rootmem_begin_write
1159
        push    flp_rootmem_begin_write
1160
        xor     ebp, ebp
1160
        xor     ebp, ebp
1161
        push    ebp
1161
        push    ebp
1162
        push    flp_rootmem_first
1162
        push    flp_rootmem_first
1163
        push    flp_rootmem_next
1163
        push    flp_rootmem_next
1164
        jmp     .common1
1164
        jmp     .common1
1165
.hasebp:
1165
.hasebp:
1166
        mov     eax, ERROR_ACCESS_DENIED
1166
        mov     eax, ERROR_ACCESS_DENIED
1167
        cmp     byte [ebp], 0
1167
        cmp     byte [ebp], 0
1168
        jz      .ret1
1168
        jz      .ret1
1169
        push    ebp
1169
        push    ebp
1170
        xor     ebp, ebp
1170
        xor     ebp, ebp
1171
        call    fd_find_lfn
1171
        call    fd_find_lfn
1172
        pop     esi
1172
        pop     esi
1173
        jc      .notfound0
1173
        jc      .notfound0
1174
        jmp     .common0
1174
        jmp     .common0
1175
.noroot:
1175
.noroot:
1176
        mov     eax, ERROR_ACCESS_DENIED
1176
        mov     eax, ERROR_ACCESS_DENIED
1177
        cmp     byte [edi+1], 0
1177
        cmp     byte [edi+1], 0
1178
        jz      .ret1
1178
        jz      .ret1
1179
; check existence
1179
; check existence
1180
        mov     byte [edi], 0
1180
        mov     byte [edi], 0
1181
        push    edi
1181
        push    edi
1182
        call    fd_find_lfn
1182
        call    fd_find_lfn
1183
        pop     esi
1183
        pop     esi
1184
        mov     byte [esi], '/'
1184
        mov     byte [esi], '/'
1185
        jnc     @f
1185
        jnc     @f
1186
.notfound0:
1186
.notfound0:
1187
        mov     eax, ERROR_FILE_NOT_FOUND
1187
        mov     eax, ERROR_FILE_NOT_FOUND
1188
.ret1:
1188
.ret1:
1189
        mov     [esp+28], eax
1189
        mov     [esp+28], eax
1190
        popad
1190
        popad
1191
        xor     ebx, ebx
1191
        xor     ebx, ebx
1192
        ret
1192
        ret
1193
@@:
1193
@@:
1194
        inc     esi
1194
        inc     esi
1195
.common0:
1195
.common0:
1196
        test    byte [edi+11], 0x10     ; must be directory
1196
        test    byte [edi+11], 0x10     ; must be directory
1197
        mov     eax, ERROR_ACCESS_DENIED
1197
        mov     eax, ERROR_ACCESS_DENIED
1198
        jz      .ret1
1198
        jz      .ret1
1199
        movzx   ebp, word [edi+26]      ; ebp=cluster
1199
        movzx   ebp, word [edi+26]      ; ebp=cluster
1200
        mov     eax, ERROR_FAT_TABLE
1200
        mov     eax, ERROR_FAT_TABLE
1201
        cmp     ebp, 2
1201
        cmp     ebp, 2
1202
        jb      .ret1
1202
        jb      .ret1
1203
        cmp     ebp, 2849
1203
        cmp     ebp, 2849
1204
        jae     .ret1
1204
        jae     .ret1
1205
        push    flp_notroot_extend_dir
1205
        push    flp_notroot_extend_dir
1206
        push    flp_notroot_end_write
1206
        push    flp_notroot_end_write
1207
        push    flp_notroot_next_write
1207
        push    flp_notroot_next_write
1208
        push    flp_notroot_begin_write
1208
        push    flp_notroot_begin_write
1209
        push    ebp
1209
        push    ebp
1210
        push    flp_notroot_first
1210
        push    flp_notroot_first
1211
        push    flp_notroot_next
1211
        push    flp_notroot_next
1212
.common1:
1212
.common1:
1213
        call    fat_find_lfn
1213
        call    fat_find_lfn
1214
        jc      .notfound
1214
        jc      .notfound
1215
; found
1215
; found
1216
        test    byte [edi+11], 10h
1216
        test    byte [edi+11], 10h
1217
        jz      .exists_file
1217
        jz      .exists_file
1218
; found directory; if we are creating directory, return OK,
1218
; found directory; if we are creating directory, return OK,
1219
;                  if we are creating file, say "access denied"
1219
;                  if we are creating file, say "access denied"
1220
        add     esp, 28
1220
        add     esp, 28
1221
        popad
1221
        popad
1222
        test    al, al
1222
        test    al, al
1223
        mov     eax, ERROR_ACCESS_DENIED
1223
        mov     eax, ERROR_ACCESS_DENIED
1224
        jz      @f
1224
        jz      @f
1225
        mov     al, 0
1225
        mov     al, 0
1226
@@:
1226
@@:
1227
        xor     ebx, ebx
1227
        xor     ebx, ebx
1228
        ret
1228
        ret
1229
.exists_file:
1229
.exists_file:
1230
; found file; if we are creating directory, return "access denied",
1230
; found file; if we are creating directory, return "access denied",
1231
;             if we are creating file, delete existing file and continue
1231
;             if we are creating file, delete existing file and continue
1232
        cmp     byte [esp+28+28], 0
1232
        cmp     byte [esp+28+28], 0
1233
        jz      @f
1233
        jz      @f
1234
        add     esp, 28
1234
        add     esp, 28
1235
        popad
1235
        popad
1236
        mov     eax, ERROR_ACCESS_DENIED
1236
        mov     eax, ERROR_ACCESS_DENIED
1237
        xor     ebx, ebx
1237
        xor     ebx, ebx
1238
        ret
1238
        ret
1239
@@:
1239
@@:
1240
; delete FAT chain
1240
; delete FAT chain
1241
        push    edi
1241
        push    edi
1242
        xor     eax, eax
1242
        xor     eax, eax
1243
        mov     dword [edi+28], eax     ; zero size
1243
        mov     dword [edi+28], eax     ; zero size
1244
        xchg    ax, word [edi+26]       ; start cluster
1244
        xchg    ax, word [edi+26]       ; start cluster
1245
        test    eax, eax
1245
        test    eax, eax
1246
        jz      .done1
1246
        jz      .done1
1247
@@:
1247
@@:
1248
        cmp     eax, 0xFF8
1248
        cmp     eax, 0xFF8
1249
        jae     .done1
1249
        jae     .done1
1250
        lea     edi, [FLOPPY_FAT + eax*2] ; position in FAT
1250
        lea     edi, [FLOPPY_FAT + eax*2] ; position in FAT
1251
        xor     eax, eax
1251
        xor     eax, eax
1252
        xchg    ax, [edi]
1252
        xchg    ax, [edi]
1253
        jmp     @b
1253
        jmp     @b
1254
.done1:
1254
.done1:
1255
        pop     edi
1255
        pop     edi
1256
        call    get_time_for_file
1256
        call    get_time_for_file
1257
        mov     [edi+22], ax
1257
        mov     [edi+22], ax
1258
        call    get_date_for_file
1258
        call    get_date_for_file
1259
        mov     [edi+24], ax
1259
        mov     [edi+24], ax
1260
        mov     [edi+18], ax
1260
        mov     [edi+18], ax
1261
        or      byte [edi+11], 20h      ; set 'archive' attribute
1261
        or      byte [edi+11], 20h      ; set 'archive' attribute
1262
        jmp     .doit
1262
        jmp     .doit
1263
.notfound:
1263
.notfound:
1264
; file is not found; generate short name
1264
; file is not found; generate short name
1265
        call    fat_name_is_legal
1265
        call    fat_name_is_legal
1266
        jc      @f
1266
        jc      @f
1267
        add     esp, 28
1267
        add     esp, 28
1268
        popad
1268
        popad
1269
        mov     eax, ERROR_FILE_NOT_FOUND
1269
        mov     eax, ERROR_FILE_NOT_FOUND
1270
        xor     ebx, ebx
1270
        xor     ebx, ebx
1271
        ret
1271
        ret
1272
@@:
1272
@@:
1273
        sub     esp, 12
1273
        sub     esp, 12
1274
        mov     edi, esp
1274
        mov     edi, esp
1275
        call    fat_gen_short_name
1275
        call    fat_gen_short_name
1276
.test_short_name_loop:
1276
.test_short_name_loop:
1277
        push    esi edi ecx
1277
        push    esi edi ecx
1278
        mov     esi, edi
1278
        mov     esi, edi
1279
        lea     eax, [esp+12+12+8]
1279
        lea     eax, [esp+12+12+8]
1280
        mov     [eax], ebp
1280
        mov     [eax], ebp
1281
        call    dword [eax-4]
1281
        call    dword [eax-4]
1282
        jc      .found
1282
        jc      .found
1283
.test_short_name_entry:
1283
.test_short_name_entry:
1284
        cmp     byte [edi+11], 0xF
1284
        cmp     byte [edi+11], 0xF
1285
        jz      .test_short_name_cont
1285
        jz      .test_short_name_cont
1286
        mov     ecx, 11
1286
        mov     ecx, 11
1287
        push    esi edi
1287
        push    esi edi
1288
        repz cmpsb
1288
        repz cmpsb
1289
        pop     edi esi
1289
        pop     edi esi
1290
        jz      .short_name_found
1290
        jz      .short_name_found
1291
.test_short_name_cont:
1291
.test_short_name_cont:
1292
        lea     eax, [esp+12+12+8]
1292
        lea     eax, [esp+12+12+8]
1293
        call    dword [eax-8]
1293
        call    dword [eax-8]
1294
        jnc     .test_short_name_entry
1294
        jnc     .test_short_name_entry
1295
        jmp     .found
1295
        jmp     .found
1296
.short_name_found:
1296
.short_name_found:
1297
        pop     ecx edi esi
1297
        pop     ecx edi esi
1298
        call    fat_next_short_name
1298
        call    fat_next_short_name
1299
        jnc     .test_short_name_loop
1299
        jnc     .test_short_name_loop
1300
.disk_full:
1300
.disk_full:
1301
        add     esp, 12+28
1301
        add     esp, 12+28
1302
        popa
1302
        popa
1303
        mov     eax, ERROR_DISK_FULL
1303
        mov     eax, ERROR_DISK_FULL
1304
        xor     ebx, ebx
1304
        xor     ebx, ebx
1305
        ret
1305
        ret
1306
.found:
1306
.found:
1307
        pop     ecx edi esi
1307
        pop     ecx edi esi
1308
; now find space in directory
1308
; now find space in directory
1309
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1309
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1310
        mov     al, '~'
1310
        mov     al, '~'
1311
        push    ecx edi
1311
        push    ecx edi
1312
        mov     ecx, 8
1312
        mov     ecx, 8
1313
        repnz scasb
1313
        repnz scasb
1314
        push    1
1314
        push    1
1315
        pop     eax     ; 1 entry
1315
        pop     eax     ; 1 entry
1316
        jnz     .notilde
1316
        jnz     .notilde
1317
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1317
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1318
        xor     eax, eax
1318
        xor     eax, eax
1319
@@:
1319
@@:
1320
        cmp     byte [esi], 0
1320
        cmp     byte [esi], 0
1321
        jz      @f
1321
        jz      @f
1322
        inc     esi
1322
        inc     esi
1323
        inc     eax
1323
        inc     eax
1324
        jmp     @b
1324
        jmp     @b
1325
@@:
1325
@@:
1326
        sub     esi, eax
1326
        sub     esi, eax
1327
        add     eax, 12+13
1327
        add     eax, 12+13
1328
        mov     ecx, 13
1328
        mov     ecx, 13
1329
        push    edx
1329
        push    edx
1330
        cdq
1330
        cdq
1331
        div     ecx
1331
        div     ecx
1332
        pop     edx
1332
        pop     edx
1333
.notilde:
1333
.notilde:
1334
        push    -1
1334
        push    -1
1335
        push    -1
1335
        push    -1
1336
; find  successive entries in directory
1336
; find  successive entries in directory
1337
        xor     ecx, ecx
1337
        xor     ecx, ecx
1338
        push    eax
1338
        push    eax
1339
        lea     eax, [esp+12+8+12+8]
1339
        lea     eax, [esp+12+8+12+8]
1340
        mov     [eax], ebp
1340
        mov     [eax], ebp
1341
        call    dword [eax-4]
1341
        call    dword [eax-4]
1342
        pop     eax
1342
        pop     eax
1343
        jnc     .scan_dir
1343
        jnc     .scan_dir
1344
.fsfrfe3:
1344
.fsfrfe3:
1345
        add     esp, 8+8+12+28
1345
        add     esp, 8+8+12+28
1346
        popad
1346
        popad
1347
        mov     eax, 11
1347
        mov     eax, 11
1348
        xor     ebx, ebx
1348
        xor     ebx, ebx
1349
        ret
1349
        ret
1350
.scan_dir:
1350
.scan_dir:
1351
        cmp     byte [edi], 0
1351
        cmp     byte [edi], 0
1352
        jz      .free
1352
        jz      .free
1353
        cmp     byte [edi], 0xE5
1353
        cmp     byte [edi], 0xE5
1354
        jz      .free
1354
        jz      .free
1355
        xor     ecx, ecx
1355
        xor     ecx, ecx
1356
.scan_cont:
1356
.scan_cont:
1357
        push    eax
1357
        push    eax
1358
        lea     eax, [esp+12+8+12+8]
1358
        lea     eax, [esp+12+8+12+8]
1359
        call    dword [eax-8]
1359
        call    dword [eax-8]
1360
        pop     eax
1360
        pop     eax
1361
        jnc     .scan_dir
1361
        jnc     .scan_dir
1362
        cmp     [FDC_Status], 0
1362
        cmp     [FDC_Status], 0
1363
        jnz     .fsfrfe3
1363
        jnz     .fsfrfe3
1364
        push    eax
1364
        push    eax
1365
        lea     eax, [esp+12+8+12+8]
1365
        lea     eax, [esp+12+8+12+8]
1366
        call    dword [eax+16]          ; extend directory
1366
        call    dword [eax+16]          ; extend directory
1367
        pop     eax
1367
        pop     eax
1368
        jnc     .scan_dir
1368
        jnc     .scan_dir
1369
        add     esp, 8+8+12+28
1369
        add     esp, 8+8+12+28
1370
        popad
1370
        popad
1371
        mov     eax, ERROR_DISK_FULL
1371
        mov     eax, ERROR_DISK_FULL
1372
        xor     ebx, ebx
1372
        xor     ebx, ebx
1373
        ret
1373
        ret
1374
.free:
1374
.free:
1375
        test    ecx, ecx
1375
        test    ecx, ecx
1376
        jnz     @f
1376
        jnz     @f
1377
        mov     [esp], edi
1377
        mov     [esp], edi
1378
        mov     ecx, [esp+8+8+12+8]
1378
        mov     ecx, [esp+8+8+12+8]
1379
        mov     [esp+4], ecx
1379
        mov     [esp+4], ecx
1380
        xor     ecx, ecx
1380
        xor     ecx, ecx
1381
@@:
1381
@@:
1382
        inc     ecx
1382
        inc     ecx
1383
        cmp     ecx, eax
1383
        cmp     ecx, eax
1384
        jb      .scan_cont
1384
        jb      .scan_cont
1385
; found!
1385
; found!
1386
; calculate name checksum
1386
; calculate name checksum
1387
        push    esi ecx
1387
        push    esi ecx
1388
        mov     esi, [esp+8+8]
1388
        mov     esi, [esp+8+8]
1389
        mov     ecx, 11
1389
        mov     ecx, 11
1390
        xor     eax, eax
1390
        xor     eax, eax
1391
@@:
1391
@@:
1392
        ror     al, 1
1392
        ror     al, 1
1393
        add     al, [esi]
1393
        add     al, [esi]
1394
        inc     esi
1394
        inc     esi
1395
        loop    @b
1395
        loop    @b
1396
        pop     ecx esi
1396
        pop     ecx esi
1397
        pop     edi
1397
        pop     edi
1398
        pop     dword [esp+8+12+8]
1398
        pop     dword [esp+8+12+8]
1399
; edi points to first entry in free chunk
1399
; edi points to first entry in free chunk
1400
        dec     ecx
1400
        dec     ecx
1401
        jz      .nolfn
1401
        jz      .nolfn
1402
        push    esi
1402
        push    esi
1403
        push    eax
1403
        push    eax
1404
        lea     eax, [esp+8+8+12+8]
1404
        lea     eax, [esp+8+8+12+8]
1405
        call    dword [eax+4]         ; begin write
1405
        call    dword [eax+4]         ; begin write
1406
        mov     al, 40h
1406
        mov     al, 40h
1407
.writelfn:
1407
.writelfn:
1408
        or      al, cl
1408
        or      al, cl
1409
        mov     esi, [esp+4]
1409
        mov     esi, [esp+4]
1410
        push    ecx
1410
        push    ecx
1411
        dec     ecx
1411
        dec     ecx
1412
        imul    ecx, 13
1412
        imul    ecx, 13
1413
        add     esi, ecx
1413
        add     esi, ecx
1414
        stosb
1414
        stosb
1415
        mov     cl, 5
1415
        mov     cl, 5
1416
        call    fs_RamdiskRewrite.read_symbols
1416
        call    fs_RamdiskRewrite.read_symbols
1417
        mov     ax, 0xF
1417
        mov     ax, 0xF
1418
        stosw
1418
        stosw
1419
        mov     al, [esp+4]
1419
        mov     al, [esp+4]
1420
        stosb
1420
        stosb
1421
        mov     cl, 6
1421
        mov     cl, 6
1422
        call    fs_RamdiskRewrite.read_symbols
1422
        call    fs_RamdiskRewrite.read_symbols
1423
        xor     eax, eax
1423
        xor     eax, eax
1424
        stosw
1424
        stosw
1425
        mov     cl, 2
1425
        mov     cl, 2
1426
        call    fs_RamdiskRewrite.read_symbols
1426
        call    fs_RamdiskRewrite.read_symbols
1427
        pop     ecx
1427
        pop     ecx
1428
        lea     eax, [esp+8+8+12+8]
1428
        lea     eax, [esp+8+8+12+8]
1429
        call    dword [eax+8]         ; next write
1429
        call    dword [eax+8]         ; next write
1430
        xor     eax, eax
1430
        xor     eax, eax
1431
        loop    .writelfn
1431
        loop    .writelfn
1432
        pop     eax
1432
        pop     eax
1433
        pop     esi
1433
        pop     esi
1434
;        lea     eax, [esp+8+12+8]
1434
;        lea     eax, [esp+8+12+8]
1435
;        call    dword [eax+12]          ; end write
1435
;        call    dword [eax+12]          ; end write
1436
.nolfn:
1436
.nolfn:
1437
        xchg    esi, [esp]
1437
        xchg    esi, [esp]
1438
        mov     ecx, 11
1438
        mov     ecx, 11
1439
        rep movsb
1439
        rep movsb
1440
        mov     word [edi], 20h         ; attributes
1440
        mov     word [edi], 20h         ; attributes
1441
        sub     edi, 11
1441
        sub     edi, 11
1442
        pop     esi ecx
1442
        pop     esi ecx
1443
        add     esp, 12
1443
        add     esp, 12
1444
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1444
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1445
        call    get_time_for_file
1445
        call    get_time_for_file
1446
        mov     [edi+14], ax            ; creation time
1446
        mov     [edi+14], ax            ; creation time
1447
        mov     [edi+22], ax            ; last write time
1447
        mov     [edi+22], ax            ; last write time
1448
        call    get_date_for_file
1448
        call    get_date_for_file
1449
        mov     [edi+16], ax            ; creation date
1449
        mov     [edi+16], ax            ; creation date
1450
        mov     [edi+24], ax            ; last write date
1450
        mov     [edi+24], ax            ; last write date
1451
        mov     [edi+18], ax            ; last access date
1451
        mov     [edi+18], ax            ; last access date
1452
        and     word [edi+20], 0        ; high word of cluster
1452
        and     word [edi+20], 0        ; high word of cluster
1453
        and     word [edi+26], 0        ; low word of cluster - to be filled
1453
        and     word [edi+26], 0        ; low word of cluster - to be filled
1454
        and     dword [edi+28], 0       ; file size - to be filled
1454
        and     dword [edi+28], 0       ; file size - to be filled
1455
        cmp     byte [esp+28+28], 0
1455
        cmp     byte [esp+28+28], 0
1456
        jz      .doit
1456
        jz      .doit
1457
; create directory
1457
; create directory
1458
        mov     byte [edi+11], 10h      ; attributes: folder
1458
        mov     byte [edi+11], 10h      ; attributes: folder
1459
        mov     ecx, 32*2
1459
        mov     ecx, 32*2
1460
        mov     edx, edi
1460
        mov     edx, edi
1461
.doit:
1461
.doit:
1462
        lea     eax, [esp+8]
1462
        lea     eax, [esp+8]
1463
        call    dword [eax+12]  ; flush directory
1463
        call    dword [eax+12]  ; flush directory
1464
        push    ecx
1464
        push    ecx
1465
        push    edi
1465
        push    edi
1466
        push    0
1466
        push    0
1467
        mov     esi, edx
1467
        mov     esi, edx
1468
        test    ecx, ecx
1468
        test    ecx, ecx
1469
        jz      .done
1469
        jz      .done
1470
        mov     ecx, 2849
1470
        mov     ecx, 2849
1471
        mov     edi, FLOPPY_FAT
1471
        mov     edi, FLOPPY_FAT
1472
        push    0       ; first cluster
1472
        push    0       ; first cluster
1473
.write_loop:
1473
.write_loop:
1474
; allocate new cluster
1474
; allocate new cluster
1475
        xor     eax, eax
1475
        xor     eax, eax
1476
        repnz scasw
1476
        repnz scasw
1477
        mov     al, ERROR_DISK_FULL
1477
        mov     al, ERROR_DISK_FULL
1478
        jnz     .ret
1478
        jnz     .ret
1479
        dec     edi
1479
        dec     edi
1480
        dec     edi
1480
        dec     edi
1481
 
1481
 
1482
        mov     eax, edi
1482
        mov     eax, edi
1483
        sub     eax, FLOPPY_FAT
1483
        sub     eax, FLOPPY_FAT
1484
 
1484
 
1485
        shr     eax, 1                  ; eax = cluster
1485
        shr     eax, 1                  ; eax = cluster
1486
        mov     word [edi], 0xFFF       ; mark as last cluster
1486
        mov     word [edi], 0xFFF       ; mark as last cluster
1487
        xchg    edi, [esp+4]
1487
        xchg    edi, [esp+4]
1488
        cmp     dword [esp], 0
1488
        cmp     dword [esp], 0
1489
        jz      .first
1489
        jz      .first
1490
        stosw
1490
        stosw
1491
        jmp     @f
1491
        jmp     @f
1492
.first:
1492
.first:
1493
        mov     [esp], eax
1493
        mov     [esp], eax
1494
@@:
1494
@@:
1495
        mov     edi, [esp+4]
1495
        mov     edi, [esp+4]
1496
        inc     ecx
1496
        inc     ecx
1497
; write data
1497
; write data
1498
        push    ecx edi
1498
        push    ecx edi
1499
        mov     ecx, 512
1499
        mov     ecx, 512
1500
        cmp     dword [esp+20], ecx
1500
        cmp     dword [esp+20], ecx
1501
        jae     @f
1501
        jae     @f
1502
        mov     ecx, [esp+20]
1502
        mov     ecx, [esp+20]
1503
@@:
1503
@@:
1504
        mov     edi, FDD_BUFF
1504
        mov     edi, FDD_BUFF
1505
        cmp     byte [esp+24+28+28], 0
1505
        cmp     byte [esp+24+28+28], 0
1506
        jnz     .writedir
1506
        jnz     .writedir
1507
        push    ecx
1507
        push    ecx
1508
        rep movsb
1508
        rep movsb
1509
        pop     ecx
1509
        pop     ecx
1510
.writedircont:
1510
.writedircont:
1511
        push    ecx
1511
        push    ecx
1512
        sub     ecx, 512
1512
        sub     ecx, 512
1513
        neg     ecx
1513
        neg     ecx
1514
        push    eax
1514
        push    eax
1515
        xor     eax, eax
1515
        xor     eax, eax
1516
        rep stosb
1516
        rep stosb
1517
        pop     eax
1517
        pop     eax
1518
        add     eax, 31
1518
        add     eax, 31
1519
        pusha
1519
        pusha
1520
        call    save_chs_sector
1520
        call    save_chs_sector
1521
        popa
1521
        popa
1522
        pop     ecx
1522
        pop     ecx
1523
        cmp     [FDC_Status], 0
1523
        cmp     [FDC_Status], 0
1524
        jnz     .diskerr
1524
        jnz     .diskerr
1525
        sub     [esp+20], ecx
1525
        sub     [esp+20], ecx
1526
        pop     edi ecx
1526
        pop     edi ecx
1527
        jnz     .write_loop
1527
        jnz     .write_loop
1528
.done:
1528
.done:
1529
        xor     eax, eax
1529
        xor     eax, eax
1530
.ret:
1530
.ret:
1531
        pop     ebx edi edi ecx
1531
        pop     ebx edi edi ecx
1532
        mov     [esp+28+28], eax
1532
        mov     [esp+28+28], eax
1533
        lea     eax, [esp+8]
1533
        lea     eax, [esp+8]
1534
        call    dword [eax+4]
1534
        call    dword [eax+4]
1535
        mov     [edi+26], bx
1535
        mov     [edi+26], bx
1536
        mov     ebx, esi
1536
        mov     ebx, esi
1537
        sub     ebx, edx
1537
        sub     ebx, edx
1538
        mov     [edi+28], ebx
1538
        mov     [edi+28], ebx
1539
        call    dword [eax+12]
1539
        call    dword [eax+12]
1540
        mov     [esp+28+16], ebx
1540
        mov     [esp+28+16], ebx
1541
        test    ebp, ebp
1541
        test    ebp, ebp
1542
        jnz     @f
1542
        jnz     @f
1543
        call    save_flp_root
1543
        call    save_flp_root
1544
@@:
1544
@@:
1545
        add     esp, 28
1545
        add     esp, 28
1546
        cmp     [FDC_Status], 0
1546
        cmp     [FDC_Status], 0
1547
        jnz     .err3
1547
        jnz     .err3
1548
        call    save_flp_fat
1548
        call    save_flp_fat
1549
        cmp     [FDC_Status], 0
1549
        cmp     [FDC_Status], 0
1550
        jnz     .err3
1550
        jnz     .err3
1551
        popa
1551
        popa
1552
        ret
1552
        ret
1553
.err3:
1553
.err3:
1554
        popa
1554
        popa
1555
        mov     al, 11
1555
        mov     al, 11
1556
        xor     ebx, ebx
1556
        xor     ebx, ebx
1557
        ret
1557
        ret
1558
.diskerr:
1558
.diskerr:
1559
        sub     esi, ecx
1559
        sub     esi, ecx
1560
        mov     eax, 11
1560
        mov     eax, 11
1561
        pop     edi ecx
1561
        pop     edi ecx
1562
        jmp     .ret
1562
        jmp     .ret
1563
.writedir:
1563
.writedir:
1564
        push    ecx
1564
        push    ecx
1565
        mov     ecx, 32/4
1565
        mov     ecx, 32/4
1566
        push    ecx esi
1566
        push    ecx esi
1567
        rep movsd
1567
        rep movsd
1568
        pop     esi ecx
1568
        pop     esi ecx
1569
        mov     dword [edi-32], '.   '
1569
        mov     dword [edi-32], '.   '
1570
        mov     dword [edi-32+4], '    '
1570
        mov     dword [edi-32+4], '    '
1571
        mov     dword [edi-32+8], '    '
1571
        mov     dword [edi-32+8], '    '
1572
        mov     byte [edi-32+11], 10h
1572
        mov     byte [edi-32+11], 10h
1573
        mov     word [edi-32+26], ax
1573
        mov     word [edi-32+26], ax
1574
        push    esi
1574
        push    esi
1575
        rep movsd
1575
        rep movsd
1576
        pop     esi
1576
        pop     esi
1577
        mov     dword [edi-32], '..  '
1577
        mov     dword [edi-32], '..  '
1578
        mov     dword [edi-32+4], '    '
1578
        mov     dword [edi-32+4], '    '
1579
        mov     dword [edi-32+8], '    '
1579
        mov     dword [edi-32+8], '    '
1580
        mov     byte [edi-32+11], 10h
1580
        mov     byte [edi-32+11], 10h
1581
        mov     ecx, [esp+28+8]
1581
        mov     ecx, [esp+28+8]
1582
        mov     word [edi-32+26], cx
1582
        mov     word [edi-32+26], cx
1583
        pop     ecx
1583
        pop     ecx
1584
        jmp     .writedircont
1584
        jmp     .writedircont
1585
 
1585
 
1586
;----------------------------------------------------------------
1586
;----------------------------------------------------------------
1587
;
1587
;
1588
;  fs_FloppyWrite - LFN variant for writing to floppy
1588
;  fs_FloppyWrite - LFN variant for writing to floppy
1589
;
1589
;
1590
;  esi  points to filename
1590
;  esi  points to filename
1591
;  ebx  pointer to 64-bit number = first wanted byte, 0+
1591
;  ebx  pointer to 64-bit number = first wanted byte, 0+
1592
;       may be ebx=0 - start from first byte
1592
;       may be ebx=0 - start from first byte
1593
;  ecx  number of bytes to write, 0+
1593
;  ecx  number of bytes to write, 0+
1594
;  edx  mem location to data
1594
;  edx  mem location to data
1595
;
1595
;
1596
;  ret ebx = bytes written (maybe 0)
1596
;  ret ebx = bytes written (maybe 0)
1597
;      eax = 0 ok write or other = errormsg
1597
;      eax = 0 ok write or other = errormsg
1598
;
1598
;
1599
;--------------------------------------------------------------
1599
;--------------------------------------------------------------
1600
 
1600
 
1601
@@:
1601
@@:
1602
        push    ERROR_ACCESS_DENIED
1602
        push    ERROR_ACCESS_DENIED
1603
fs_FloppyWrite.ret0:
1603
fs_FloppyWrite.ret0:
1604
        pop     eax
1604
        pop     eax
1605
        xor     ebx, ebx
1605
        xor     ebx, ebx
1606
        ret
1606
        ret
1607
 
1607
 
1608
fs_FloppyWrite.ret11:
1608
fs_FloppyWrite.ret11:
1609
        push    11
1609
        push    11
1610
        jmp     fs_FloppyWrite.ret0
1610
        jmp     fs_FloppyWrite.ret0
1611
 
1611
 
1612
fs_FloppyWrite:
1612
fs_FloppyWrite:
1613
        cmp     byte [esi], 0
1613
        cmp     byte [esi], 0
1614
        jz      @b
1614
        jz      @b
1615
        call    read_flp_fat
1615
        call    read_flp_fat
1616
        cmp     [FDC_Status], 0
1616
        cmp     [FDC_Status], 0
1617
        jnz     .ret11
1617
        jnz     .ret11
1618
        pushad
1618
        pushad
1619
        call    fd_find_lfn
1619
        call    fd_find_lfn
1620
        jnc     .found
1620
        jnc     .found
1621
        popad
1621
        popad
1622
        push    ERROR_FILE_NOT_FOUND
1622
        push    ERROR_FILE_NOT_FOUND
1623
        jmp     .ret0
1623
        jmp     .ret0
1624
.found:
1624
.found:
1625
; FAT does not support files larger than 4GB
1625
; FAT does not support files larger than 4GB
1626
        test    ebx, ebx
1626
        test    ebx, ebx
1627
        jz      .l1
1627
        jz      .l1
1628
        cmp     dword [ebx+4], 0
1628
        cmp     dword [ebx+4], 0
1629
        jz      @f
1629
        jz      @f
1630
.eof:
1630
.eof:
1631
        popad
1631
        popad
1632
        push    ERROR_END_OF_FILE
1632
        push    ERROR_END_OF_FILE
1633
        jmp     .ret0
1633
        jmp     .ret0
1634
@@:
1634
@@:
1635
        mov     ebx, [ebx]
1635
        mov     ebx, [ebx]
1636
.l1:
1636
.l1:
1637
; now edi points to direntry, ebx=start byte to write,
1637
; now edi points to direntry, ebx=start byte to write,
1638
; ecx=number of bytes to write, edx=data pointer
1638
; ecx=number of bytes to write, edx=data pointer
1639
 
1639
 
1640
; extend file if needed
1640
; extend file if needed
1641
        add     ecx, ebx
1641
        add     ecx, ebx
1642
        jc      .eof    ; FAT does not support files larger than 4GB
1642
        jc      .eof    ; FAT does not support files larger than 4GB
1643
        push    eax     ; save directory cluster
1643
        push    eax     ; save directory cluster
1644
        push    0       ; return value=0
1644
        push    0       ; return value=0
1645
 
1645
 
1646
        call    get_time_for_file
1646
        call    get_time_for_file
1647
        mov     [edi+22], ax            ; last write time
1647
        mov     [edi+22], ax            ; last write time
1648
        call    get_date_for_file
1648
        call    get_date_for_file
1649
        mov     [edi+24], ax            ; last write date
1649
        mov     [edi+24], ax            ; last write date
1650
        mov     [edi+18], ax            ; last access date
1650
        mov     [edi+18], ax            ; last access date
1651
 
1651
 
1652
        push    dword [edi+28]          ; save current file size
1652
        push    dword [edi+28]          ; save current file size
1653
        cmp     ecx, [edi+28]
1653
        cmp     ecx, [edi+28]
1654
        jbe     .length_ok
1654
        jbe     .length_ok
1655
        cmp     ecx, ebx
1655
        cmp     ecx, ebx
1656
        jz      .length_ok
1656
        jz      .length_ok
1657
        call    floppy_extend_file
1657
        call    floppy_extend_file
1658
        jnc     .length_ok
1658
        jnc     .length_ok
1659
        mov     [esp+4], eax
1659
        mov     [esp+4], eax
1660
; floppy_extend_file can return two error codes: FAT table error or disk full.
1660
; floppy_extend_file can return two error codes: FAT table error or disk full.
1661
; First case is fatal error, in second case we may write some data
1661
; First case is fatal error, in second case we may write some data
1662
        cmp     al, ERROR_DISK_FULL
1662
        cmp     al, ERROR_DISK_FULL
1663
        jz      .disk_full
1663
        jz      .disk_full
1664
        pop     eax
1664
        pop     eax
1665
        pop     eax
1665
        pop     eax
1666
        mov     [esp+4+28], eax
1666
        mov     [esp+4+28], eax
1667
        pop     eax
1667
        pop     eax
1668
        popad
1668
        popad
1669
        xor     ebx, ebx
1669
        xor     ebx, ebx
1670
        ret
1670
        ret
1671
.disk_full:
1671
.disk_full:
1672
; correct number of bytes to write
1672
; correct number of bytes to write
1673
        mov     ecx, [edi+28]
1673
        mov     ecx, [edi+28]
1674
        cmp     ecx, ebx
1674
        cmp     ecx, ebx
1675
        ja      .length_ok
1675
        ja      .length_ok
1676
.ret:
1676
.ret:
1677
        pop     eax
1677
        pop     eax
1678
        pop     eax
1678
        pop     eax
1679
        mov     [esp+4+28], eax ; eax=return value
1679
        mov     [esp+4+28], eax ; eax=return value
1680
        pop     eax
1680
        pop     eax
1681
        sub     edx, [esp+20]
1681
        sub     edx, [esp+20]
1682
        mov     [esp+16], edx   ; ebx=number of written bytes
1682
        mov     [esp+16], edx   ; ebx=number of written bytes
1683
        popad
1683
        popad
1684
        ret
1684
        ret
1685
.length_ok:
1685
.length_ok:
1686
; save FAT & directory
1686
; save FAT & directory
1687
; note that directory must be saved first because save_flp_fat uses buffer at 0xD000
1687
; note that directory must be saved first because save_flp_fat uses buffer at 0xD000
1688
        mov     esi, [edi+28]
1688
        mov     esi, [edi+28]
1689
        movzx   edi, word [edi+26]      ; starting cluster
1689
        movzx   edi, word [edi+26]      ; starting cluster
1690
        mov     eax, [esp+8]
1690
        mov     eax, [esp+8]
1691
        pusha
1691
        pusha
1692
        call    save_chs_sector
1692
        call    save_chs_sector
1693
        popa
1693
        popa
1694
        cmp     [FDC_Status], 0
1694
        cmp     [FDC_Status], 0
1695
        jnz     .device_err
1695
        jnz     .device_err
1696
        call    save_flp_fat
1696
        call    save_flp_fat
1697
        cmp     [FDC_Status], 0
1697
        cmp     [FDC_Status], 0
1698
        jz      @f
1698
        jz      @f
1699
.device_err:
1699
.device_err:
1700
        mov     byte [esp+4], 11
1700
        mov     byte [esp+4], 11
1701
        jmp     .ret
1701
        jmp     .ret
1702
@@:
1702
@@:
1703
 
1703
 
1704
; now ebx=start pos, ecx=end pos, both lie inside file
1704
; now ebx=start pos, ecx=end pos, both lie inside file
1705
        sub     ecx, ebx
1705
        sub     ecx, ebx
1706
        jz      .ret
1706
        jz      .ret
1707
        call    SetUserInterrupts
1707
        call    SetUserInterrupts
1708
.write_loop:
1708
.write_loop:
1709
; skip unmodified sectors
1709
; skip unmodified sectors
1710
        cmp     dword [esp], 0x200
1710
        cmp     dword [esp], 0x200
1711
        jb      .modify
1711
        jb      .modify
1712
        sub     ebx, 0x200
1712
        sub     ebx, 0x200
1713
        jae     .skip
1713
        jae     .skip
1714
        add     ebx, 0x200
1714
        add     ebx, 0x200
1715
.modify:
1715
.modify:
1716
        lea     eax, [edi+31]   ; current sector
1716
        lea     eax, [edi+31]   ; current sector
1717
; get length of data in current sector
1717
; get length of data in current sector
1718
        push    ecx
1718
        push    ecx
1719
        sub     ebx, 0x200
1719
        sub     ebx, 0x200
1720
        jb      .hasdata
1720
        jb      .hasdata
1721
        neg     ebx
1721
        neg     ebx
1722
        xor     ecx, ecx
1722
        xor     ecx, ecx
1723
        jmp     @f
1723
        jmp     @f
1724
.hasdata:
1724
.hasdata:
1725
        neg     ebx
1725
        neg     ebx
1726
        cmp     ecx, ebx
1726
        cmp     ecx, ebx
1727
        jbe     @f
1727
        jbe     @f
1728
        mov     ecx, ebx
1728
        mov     ecx, ebx
1729
@@:
1729
@@:
1730
; load sector if needed
1730
; load sector if needed
1731
        cmp     dword [esp+4], 0        ; we don't need to read uninitialized data
1731
        cmp     dword [esp+4], 0        ; we don't need to read uninitialized data
1732
        jz      .noread
1732
        jz      .noread
1733
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
1733
        cmp     ecx, 0x200      ; we don't need to read sector if it is fully rewritten
1734
        jz      .noread
1734
        jz      .noread
1735
        cmp     ecx, esi        ; (same for the last sector)
1735
        cmp     ecx, esi        ; (same for the last sector)
1736
        jz      .noread
1736
        jz      .noread
1737
        pusha
1737
        pusha
1738
        call    read_chs_sector
1738
        call    read_chs_sector
1739
        popa
1739
        popa
1740
        cmp     [FDC_Status], 0
1740
        cmp     [FDC_Status], 0
1741
        jz      @f
1741
        jz      @f
1742
.device_err2:
1742
.device_err2:
1743
        pop     ecx
1743
        pop     ecx
1744
        jmp     .device_err
1744
        jmp     .device_err
1745
@@:
1745
@@:
1746
.noread:
1746
.noread:
1747
; zero uninitialized data if file was extended (because floppy_extend_file does not this)
1747
; zero uninitialized data if file was extended (because floppy_extend_file does not this)
1748
        push    eax ecx edi
1748
        push    eax ecx edi
1749
        xor     eax, eax
1749
        xor     eax, eax
1750
        mov     ecx, 0x200
1750
        mov     ecx, 0x200
1751
        sub     ecx, [esp+4+12]
1751
        sub     ecx, [esp+4+12]
1752
        jbe     @f
1752
        jbe     @f
1753
        mov     edi, FDD_BUFF
1753
        mov     edi, FDD_BUFF
1754
        add     edi, [esp+4+12]
1754
        add     edi, [esp+4+12]
1755
        rep stosb
1755
        rep stosb
1756
@@:
1756
@@:
1757
; zero uninitialized data in the last sector
1757
; zero uninitialized data in the last sector
1758
        mov     ecx, 0x200
1758
        mov     ecx, 0x200
1759
        sub     ecx, esi
1759
        sub     ecx, esi
1760
        jbe     @f
1760
        jbe     @f
1761
        mov     edi, FDD_BUFF
1761
        mov     edi, FDD_BUFF
1762
        add     edi, esi
1762
        add     edi, esi
1763
        rep stosb
1763
        rep stosb
1764
@@:
1764
@@:
1765
        pop     edi ecx eax
1765
        pop     edi ecx eax
1766
; copy new data
1766
; copy new data
1767
        push    eax
1767
        push    eax
1768
        mov     eax, edx
1768
        mov     eax, edx
1769
        neg     ebx
1769
        neg     ebx
1770
        jecxz   @f
1770
        jecxz   @f
1771
        add     ebx, FDD_BUFF+0x200
1771
        add     ebx, FDD_BUFF+0x200
1772
        call    memmove
1772
        call    memmove
1773
        xor     ebx, ebx
1773
        xor     ebx, ebx
1774
@@:
1774
@@:
1775
        pop     eax
1775
        pop     eax
1776
; save sector
1776
; save sector
1777
        pusha
1777
        pusha
1778
        call    save_chs_sector
1778
        call    save_chs_sector
1779
        popa
1779
        popa
1780
        cmp     [FDC_Status], 0
1780
        cmp     [FDC_Status], 0
1781
        jnz     .device_err2
1781
        jnz     .device_err2
1782
        add     edx, ecx
1782
        add     edx, ecx
1783
        sub     [esp], ecx
1783
        sub     [esp], ecx
1784
        pop     ecx
1784
        pop     ecx
1785
        jz      .done
1785
        jz      .done
1786
.skip:
1786
.skip:
1787
.next_cluster:
1787
.next_cluster:
1788
        movzx   edi, word [edi*2+FLOPPY_FAT]
1788
        movzx   edi, word [edi*2+FLOPPY_FAT]
1789
        sub     esi, 0x200
1789
        sub     esi, 0x200
1790
        jae     @f
1790
        jae     @f
1791
        xor     esi, esi
1791
        xor     esi, esi
1792
@@:
1792
@@:
1793
        sub     dword [esp], 0x200
1793
        sub     dword [esp], 0x200
1794
        jae     .write_loop
1794
        jae     .write_loop
1795
        and     dword [esp], 0
1795
        and     dword [esp], 0
1796
        jmp     .write_loop
1796
        jmp     .write_loop
1797
.done:
1797
.done:
1798
        mov     [fdc_irq_func], fdc_null
1798
        mov     [fdc_irq_func], fdc_null
1799
        jmp     .ret
1799
        jmp     .ret
1800
 
1800
 
1801
floppy_extend_file.zero_size:
1801
floppy_extend_file.zero_size:
1802
        xor     eax, eax
1802
        xor     eax, eax
1803
        jmp     floppy_extend_file.start_extend
1803
        jmp     floppy_extend_file.start_extend
1804
 
1804
 
1805
; extends file on floppy to given size (new data area is undefined)
1805
; extends file on floppy to given size (new data area is undefined)
1806
; in: edi->direntry, ecx=new size
1806
; in: edi->direntry, ecx=new size
1807
; out: CF=0 => OK, eax=0
1807
; out: CF=0 => OK, eax=0
1808
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
1808
;      CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
1809
floppy_extend_file:
1809
floppy_extend_file:
1810
        push    ecx
1810
        push    ecx
1811
; find the last cluster of file
1811
; find the last cluster of file
1812
        movzx   eax, word [edi+26]      ; first cluster
1812
        movzx   eax, word [edi+26]      ; first cluster
1813
        mov     ecx, [edi+28]
1813
        mov     ecx, [edi+28]
1814
        jecxz   .zero_size
1814
        jecxz   .zero_size
1815
@@:
1815
@@:
1816
        sub     ecx, 0x200
1816
        sub     ecx, 0x200
1817
        jbe     @f
1817
        jbe     @f
1818
        mov     eax, [eax*2+FLOPPY_FAT]
1818
        mov     eax, [eax*2+FLOPPY_FAT]
1819
        and     eax, 0xFFF
1819
        and     eax, 0xFFF
1820
        jz      .fat_err
1820
        jz      .fat_err
1821
        cmp     eax, 0xFF8
1821
        cmp     eax, 0xFF8
1822
        jb      @b
1822
        jb      @b
1823
.fat_err:
1823
.fat_err:
1824
        pop     ecx
1824
        pop     ecx
1825
        push    ERROR_FAT_TABLE
1825
        push    ERROR_FAT_TABLE
1826
        pop     eax
1826
        pop     eax
1827
        stc
1827
        stc
1828
        ret
1828
        ret
1829
@@:
1829
@@:
1830
        push    eax
1830
        push    eax
1831
        mov     eax, [eax*2+FLOPPY_FAT]
1831
        mov     eax, [eax*2+FLOPPY_FAT]
1832
        and     eax, 0xFFF
1832
        and     eax, 0xFFF
1833
        cmp     eax, 0xFF8
1833
        cmp     eax, 0xFF8
1834
        pop     eax
1834
        pop     eax
1835
        jb      .fat_err
1835
        jb      .fat_err
1836
; set length to full number of sectors
1836
; set length to full number of sectors
1837
        sub     [edi+28], ecx
1837
        sub     [edi+28], ecx
1838
.start_extend:
1838
.start_extend:
1839
        pop     ecx
1839
        pop     ecx
1840
; now do extend
1840
; now do extend
1841
        push    edx esi
1841
        push    edx esi
1842
        mov     esi, FLOPPY_FAT+2*2       ; start scan from cluster 2
1842
        mov     esi, FLOPPY_FAT+2*2       ; start scan from cluster 2
1843
        mov     edx, 2847               ; number of clusters to scan
1843
        mov     edx, 2847               ; number of clusters to scan
1844
.extend_loop:
1844
.extend_loop:
1845
        cmp     [edi+28], ecx
1845
        cmp     [edi+28], ecx
1846
        jae     .extend_done
1846
        jae     .extend_done
1847
; add new sector
1847
; add new sector
1848
        push    ecx
1848
        push    ecx
1849
        push    edi
1849
        push    edi
1850
.scan:
1850
.scan:
1851
        mov     ecx, edx
1851
        mov     ecx, edx
1852
        mov     edi, esi
1852
        mov     edi, esi
1853
        jecxz   .disk_full
1853
        jecxz   .disk_full
1854
        push    eax
1854
        push    eax
1855
        xor     eax, eax
1855
        xor     eax, eax
1856
        repnz scasw
1856
        repnz scasw
1857
        pop     eax
1857
        pop     eax
1858
        jnz     .disk_full
1858
        jnz     .disk_full
1859
        mov     word [edi-2], 0xFFF
1859
        mov     word [edi-2], 0xFFF
1860
        mov     esi, edi
1860
        mov     esi, edi
1861
        mov     edx, ecx
1861
        mov     edx, ecx
1862
        sub     edi, FLOPPY_FAT
1862
        sub     edi, FLOPPY_FAT
1863
        shr     edi, 1
1863
        shr     edi, 1
1864
        dec     edi     ; now edi=new cluster
1864
        dec     edi     ; now edi=new cluster
1865
        test    eax, eax
1865
        test    eax, eax
1866
        jz      .first_cluster
1866
        jz      .first_cluster
1867
        mov     [FLOPPY_FAT+eax*2], di
1867
        mov     [FLOPPY_FAT+eax*2], di
1868
        jmp     @f
1868
        jmp     @f
1869
.first_cluster:
1869
.first_cluster:
1870
        pop     eax             ; eax->direntry
1870
        pop     eax             ; eax->direntry
1871
        push    eax
1871
        push    eax
1872
        mov     [eax+26], di
1872
        mov     [eax+26], di
1873
@@:
1873
@@:
1874
        mov     eax, edi        ; eax=new cluster
1874
        mov     eax, edi        ; eax=new cluster
1875
        pop     edi             ; edi->direntry
1875
        pop     edi             ; edi->direntry
1876
        pop     ecx             ; ecx=required size
1876
        pop     ecx             ; ecx=required size
1877
        add     dword [edi+28], 0x200
1877
        add     dword [edi+28], 0x200
1878
        jmp     .extend_loop
1878
        jmp     .extend_loop
1879
.extend_done:
1879
.extend_done:
1880
        mov     [edi+28], ecx
1880
        mov     [edi+28], ecx
1881
        pop     esi edx
1881
        pop     esi edx
1882
        xor     eax, eax        ; CF=0
1882
        xor     eax, eax        ; CF=0
1883
        ret
1883
        ret
1884
.disk_full:
1884
.disk_full:
1885
        pop     edi ecx
1885
        pop     edi ecx
1886
        pop     esi edx
1886
        pop     esi edx
1887
        stc
1887
        stc
1888
        push    ERROR_DISK_FULL
1888
        push    ERROR_DISK_FULL
1889
        pop     eax
1889
        pop     eax
1890
        ret
1890
        ret
1891
 
1891
 
1892
;----------------------------------------------------------------
1892
;----------------------------------------------------------------
1893
;
1893
;
1894
;  fs_FloppySetFileEnd - set end of file on floppy
1894
;  fs_FloppySetFileEnd - set end of file on floppy
1895
;
1895
;
1896
;  esi  points to filename
1896
;  esi  points to filename
1897
;  ebx  points to 64-bit number = new file size
1897
;  ebx  points to 64-bit number = new file size
1898
;  ecx  ignored (reserved)
1898
;  ecx  ignored (reserved)
1899
;  edx  ignored (reserved)
1899
;  edx  ignored (reserved)
1900
;
1900
;
1901
;  ret eax = 0 ok or other = errormsg
1901
;  ret eax = 0 ok or other = errormsg
1902
;
1902
;
1903
;--------------------------------------------------------------
1903
;--------------------------------------------------------------
1904
fs_FloppySetFileEnd:
1904
fs_FloppySetFileEnd:
1905
        call    read_flp_fat
1905
        call    read_flp_fat
1906
        cmp     [FDC_Status], 0
1906
        cmp     [FDC_Status], 0
1907
        jnz     ret11
1907
        jnz     ret11
1908
        cmp     byte [esi], 0
1908
        cmp     byte [esi], 0
1909
        jnz     @f
1909
        jnz     @f
1910
.access_denied:
1910
.access_denied:
1911
        push    ERROR_ACCESS_DENIED
1911
        push    ERROR_ACCESS_DENIED
1912
        jmp     .ret
1912
        jmp     .ret
1913
@@:
1913
@@:
1914
        push    edi
1914
        push    edi
1915
        call    fd_find_lfn
1915
        call    fd_find_lfn
1916
        jnc     @f
1916
        jnc     @f
1917
        pop     edi
1917
        pop     edi
1918
        push    ERROR_FILE_NOT_FOUND
1918
        push    ERROR_FILE_NOT_FOUND
1919
.ret:
1919
.ret:
1920
        pop     eax
1920
        pop     eax
1921
        jmp     .doret
1921
        jmp     .doret
1922
@@:
1922
@@:
1923
; must not be directory
1923
; must not be directory
1924
        test    byte [edi+11], 10h
1924
        test    byte [edi+11], 10h
1925
        jz      @f
1925
        jz      @f
1926
        pop     edi
1926
        pop     edi
1927
        jmp     .access_denied
1927
        jmp     .access_denied
1928
@@:
1928
@@:
1929
; file size must not exceed 4 Gb
1929
; file size must not exceed 4 Gb
1930
        cmp     dword [ebx+4], 0
1930
        cmp     dword [ebx+4], 0
1931
        jz      @f
1931
        jz      @f
1932
        pop     edi
1932
        pop     edi
1933
        push    ERROR_END_OF_FILE
1933
        push    ERROR_END_OF_FILE
1934
        jmp     .ret
1934
        jmp     .ret
1935
@@:
1935
@@:
1936
        push    eax
1936
        push    eax
1937
; set file modification date/time to current
1937
; set file modification date/time to current
1938
        call    fat_update_datetime
1938
        call    fat_update_datetime
1939
        mov     eax, [ebx]
1939
        mov     eax, [ebx]
1940
        cmp     eax, [edi+28]
1940
        cmp     eax, [edi+28]
1941
        jb      .truncate
1941
        jb      .truncate
1942
        ja      .expand
1942
        ja      .expand
1943
        pop     eax
1943
        pop     eax
1944
        pushad
1944
        pushad
1945
        call    save_chs_sector
1945
        call    save_chs_sector
1946
        popad
1946
        popad
1947
        pop     edi
1947
        pop     edi
1948
        xor     eax, eax
1948
        xor     eax, eax
1949
        cmp     [FDC_Status], 0
1949
        cmp     [FDC_Status], 0
1950
        jz      @f
1950
        jz      @f
1951
        mov     al, 11
1951
        mov     al, 11
1952
@@:
1952
@@:
1953
.doret:
1953
.doret:
1954
        mov     [fdc_irq_func], fdc_null
1954
        mov     [fdc_irq_func], fdc_null
1955
        ret
1955
        ret
1956
.expand:
1956
.expand:
1957
        push    ecx
1957
        push    ecx
1958
        push    dword [edi+28]  ; save old size
1958
        push    dword [edi+28]  ; save old size
1959
        mov     ecx, eax
1959
        mov     ecx, eax
1960
        call    floppy_extend_file
1960
        call    floppy_extend_file
1961
        push    eax     ; return code
1961
        push    eax     ; return code
1962
        jnc     .expand_ok
1962
        jnc     .expand_ok
1963
        cmp     al, ERROR_DISK_FULL
1963
        cmp     al, ERROR_DISK_FULL
1964
        jz      .disk_full
1964
        jz      .disk_full
1965
        pop     eax ecx ecx edi edi
1965
        pop     eax ecx ecx edi edi
1966
        jmp     .doret
1966
        jmp     .doret
1967
.device_err:
1967
.device_err:
1968
        pop     eax
1968
        pop     eax
1969
.device_err2:
1969
.device_err2:
1970
        pop     ecx ecx eax edi
1970
        pop     ecx ecx eax edi
1971
        push    11
1971
        push    11
1972
        jmp     .ret
1972
        jmp     .ret
1973
.disk_full:
1973
.disk_full:
1974
.expand_ok:
1974
.expand_ok:
1975
; save directory & FAT
1975
; save directory & FAT
1976
        mov     eax, [edi+28]
1976
        mov     eax, [edi+28]
1977
        xchg    eax, [esp+12]
1977
        xchg    eax, [esp+12]
1978
        movzx   edi, word [edi+26]
1978
        movzx   edi, word [edi+26]
1979
        pusha
1979
        pusha
1980
        call    save_chs_sector
1980
        call    save_chs_sector
1981
        popa
1981
        popa
1982
        cmp     [FDC_Status], 0
1982
        cmp     [FDC_Status], 0
1983
        jnz     .device_err
1983
        jnz     .device_err
1984
        call    save_flp_fat
1984
        call    save_flp_fat
1985
        cmp     [FDC_Status], 0
1985
        cmp     [FDC_Status], 0
1986
        jnz     .device_err
1986
        jnz     .device_err
1987
        call    SetUserInterrupts
1987
        call    SetUserInterrupts
1988
; now zero new data
1988
; now zero new data
1989
; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code
1989
; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code
1990
.zero_loop:
1990
.zero_loop:
1991
        sub     dword [esp+4], 0x200
1991
        sub     dword [esp+4], 0x200
1992
        jae     .next_cluster
1992
        jae     .next_cluster
1993
        cmp     dword [esp+4], -0x200
1993
        cmp     dword [esp+4], -0x200
1994
        jz      .noread
1994
        jz      .noread
1995
        lea     eax, [edi+31]
1995
        lea     eax, [edi+31]
1996
        pusha
1996
        pusha
1997
        call    read_chs_sector
1997
        call    read_chs_sector
1998
        popa
1998
        popa
1999
        cmp     [FDC_Status], 0
1999
        cmp     [FDC_Status], 0
2000
        jnz     .err_next
2000
        jnz     .err_next
2001
.noread:
2001
.noread:
2002
        mov     ecx, [esp+4]
2002
        mov     ecx, [esp+4]
2003
        neg     ecx
2003
        neg     ecx
2004
        push    edi
2004
        push    edi
2005
        mov     edi, FDD_BUFF+0x200
2005
        mov     edi, FDD_BUFF+0x200
2006
        add     edi, [esp+8]
2006
        add     edi, [esp+8]
2007
        xor     eax, eax
2007
        xor     eax, eax
2008
        mov     [esp+8], eax
2008
        mov     [esp+8], eax
2009
        rep stosb
2009
        rep stosb
2010
        pop     edi
2010
        pop     edi
2011
        lea     eax, [edi+31]
2011
        lea     eax, [edi+31]
2012
        pusha
2012
        pusha
2013
        call    save_chs_sector
2013
        call    save_chs_sector
2014
        popa
2014
        popa
2015
        cmp     [FDC_Status], 0
2015
        cmp     [FDC_Status], 0
2016
        jz      .next_cluster
2016
        jz      .next_cluster
2017
.err_next:
2017
.err_next:
2018
        mov     byte [esp], 11
2018
        mov     byte [esp], 11
2019
.next_cluster:
2019
.next_cluster:
2020
        sub     dword [esp+12], 0x200
2020
        sub     dword [esp+12], 0x200
2021
        jbe     .expand_done
2021
        jbe     .expand_done
2022
        movzx   edi, word [FLOPPY_FAT+edi*2]
2022
        movzx   edi, word [FLOPPY_FAT+edi*2]
2023
        jmp     .zero_loop
2023
        jmp     .zero_loop
2024
.expand_done:
2024
.expand_done:
2025
        pop     eax ecx ecx edi edi
2025
        pop     eax ecx ecx edi edi
2026
        jmp     .doret
2026
        jmp     .doret
2027
.truncate:
2027
.truncate:
2028
        mov     [edi+28], eax
2028
        mov     [edi+28], eax
2029
        push    ecx
2029
        push    ecx
2030
        movzx   ecx, word [edi+26]
2030
        movzx   ecx, word [edi+26]
2031
        test    eax, eax
2031
        test    eax, eax
2032
        jz      .zero_size
2032
        jz      .zero_size
2033
; find new last sector
2033
; find new last sector
2034
@@:
2034
@@:
2035
        sub     eax, 0x200
2035
        sub     eax, 0x200
2036
        jbe     @f
2036
        jbe     @f
2037
        movzx   ecx, word [FLOPPY_FAT+ecx*2]
2037
        movzx   ecx, word [FLOPPY_FAT+ecx*2]
2038
        jmp     @b
2038
        jmp     @b
2039
@@:
2039
@@:
2040
; we will zero data at the end of last sector - remember it
2040
; we will zero data at the end of last sector - remember it
2041
        push    ecx
2041
        push    ecx
2042
; terminate FAT chain
2042
; terminate FAT chain
2043
        lea     ecx, [FLOPPY_FAT+ecx+ecx]
2043
        lea     ecx, [FLOPPY_FAT+ecx+ecx]
2044
        push    dword [ecx]
2044
        push    dword [ecx]
2045
        mov     word [ecx], 0xFFF
2045
        mov     word [ecx], 0xFFF
2046
        pop     ecx
2046
        pop     ecx
2047
        and     ecx, 0xFFF
2047
        and     ecx, 0xFFF
2048
        jmp     .delete
2048
        jmp     .delete
2049
.zero_size:
2049
.zero_size:
2050
        and     word [edi+26], 0
2050
        and     word [edi+26], 0
2051
        push    0
2051
        push    0
2052
.delete:
2052
.delete:
2053
; delete FAT chain starting with ecx
2053
; delete FAT chain starting with ecx
2054
; mark all clusters as free
2054
; mark all clusters as free
2055
        cmp     ecx, 0xFF8
2055
        cmp     ecx, 0xFF8
2056
        jae     .deleted
2056
        jae     .deleted
2057
        lea     ecx, [FLOPPY_FAT+ecx+ecx]
2057
        lea     ecx, [FLOPPY_FAT+ecx+ecx]
2058
        push    dword [ecx]
2058
        push    dword [ecx]
2059
        and     word [ecx], 0
2059
        and     word [ecx], 0
2060
        pop     ecx
2060
        pop     ecx
2061
        and     ecx, 0xFFF
2061
        and     ecx, 0xFFF
2062
        jmp     .delete
2062
        jmp     .delete
2063
.deleted:
2063
.deleted:
2064
        mov     edi, [edi+28]
2064
        mov     edi, [edi+28]
2065
; save directory & FAT
2065
; save directory & FAT
2066
        mov     eax, [esp+8]
2066
        mov     eax, [esp+8]
2067
        pusha
2067
        pusha
2068
        call    save_chs_sector
2068
        call    save_chs_sector
2069
        popa
2069
        popa
2070
        cmp     [FDC_Status], 0
2070
        cmp     [FDC_Status], 0
2071
        jnz     .device_err2
2071
        jnz     .device_err2
2072
        call    save_flp_fat
2072
        call    save_flp_fat
2073
        cmp     [FDC_Status], 0
2073
        cmp     [FDC_Status], 0
2074
        jnz     .device_err2
2074
        jnz     .device_err2
2075
; zero last sector, ignore errors
2075
; zero last sector, ignore errors
2076
        pop     eax
2076
        pop     eax
2077
        add     eax, 31
2077
        add     eax, 31
2078
        and     edi, 0x1FF
2078
        and     edi, 0x1FF
2079
        jz      .truncate_done
2079
        jz      .truncate_done
2080
        call    SetUserInterrupts
2080
        call    SetUserInterrupts
2081
        pusha
2081
        pusha
2082
        call    read_chs_sector
2082
        call    read_chs_sector
2083
        popa
2083
        popa
2084
        add     edi, FDD_BUFF
2084
        add     edi, FDD_BUFF
2085
        mov     ecx, FDD_BUFF+0x200
2085
        mov     ecx, FDD_BUFF+0x200
2086
        sub     ecx, edi
2086
        sub     ecx, edi
2087
        push    eax
2087
        push    eax
2088
        xor     eax, eax
2088
        xor     eax, eax
2089
        rep stosb
2089
        rep stosb
2090
        pop     eax
2090
        pop     eax
2091
        pusha
2091
        pusha
2092
        call    save_chs_sector
2092
        call    save_chs_sector
2093
        popa
2093
        popa
2094
.truncate_done:
2094
.truncate_done:
2095
        pop     ecx eax edi
2095
        pop     ecx eax edi
2096
        xor     eax, eax
2096
        xor     eax, eax
2097
        jmp     .doret
2097
        jmp     .doret
2098
 
2098
 
2099
fs_FloppyGetFileInfo:
2099
fs_FloppyGetFileInfo:
2100
        call    read_flp_fat
2100
        call    read_flp_fat
2101
        cmp     [FDC_Status], 0
2101
        cmp     [FDC_Status], 0
2102
        jnz     ret11
2102
        jnz     ret11
2103
        cmp     byte [esi], 0
2103
        cmp     byte [esi], 0
2104
        jnz     @f
2104
        jnz     @f
2105
        mov     eax, 2  ; unsupported
2105
        mov     eax, 2  ; unsupported
2106
        ret
2106
        ret
2107
@@:
2107
@@:
2108
        push    edi
2108
        push    edi
2109
        call    fd_find_lfn
2109
        call    fd_find_lfn
2110
        jmp     fs_GetFileInfo_finish
2110
        jmp     fs_GetFileInfo_finish
2111
 
2111
 
2112
ret11:
2112
ret11:
2113
        mov     eax, 11
2113
        mov     eax, 11
2114
        ret
2114
        ret
2115
 
2115
 
2116
fs_FloppySetFileInfo:
2116
fs_FloppySetFileInfo:
2117
        call    read_flp_fat
2117
        call    read_flp_fat
2118
        cmp     [FDC_Status], 0
2118
        cmp     [FDC_Status], 0
2119
        jnz     ret11
2119
        jnz     ret11
2120
        cmp     byte [esi], 0
2120
        cmp     byte [esi], 0
2121
        jnz     @f
2121
        jnz     @f
2122
        mov     eax, 2  ; unsupported
2122
        mov     eax, 2  ; unsupported
2123
        ret
2123
        ret
2124
@@:
2124
@@:
2125
        push    edi
2125
        push    edi
2126
        call    fd_find_lfn
2126
        call    fd_find_lfn
2127
        jnc     @f
2127
        jnc     @f
2128
        pop     edi
2128
        pop     edi
2129
        mov     eax, ERROR_FILE_NOT_FOUND
2129
        mov     eax, ERROR_FILE_NOT_FOUND
2130
        ret
2130
        ret
2131
@@:
2131
@@:
2132
        push    eax
2132
        push    eax
2133
        call    bdfe_to_fat_entry
2133
        call    bdfe_to_fat_entry
2134
        pop     eax
2134
        pop     eax
2135
        pusha
2135
        pusha
2136
        call    save_chs_sector
2136
        call    save_chs_sector
2137
        popa
2137
        popa
2138
        pop     edi
2138
        pop     edi
2139
        xor     eax, eax
2139
        xor     eax, eax
2140
        cmp     [FDC_Status], al
2140
        cmp     [FDC_Status], al
2141
        jz      @f
2141
        jz      @f
2142
        mov     al, 11
2142
        mov     al, 11
2143
@@:
2143
@@:
2144
        ret
2144
        ret
2145
 
2145
 
2146
;----------------------------------------------------------------
2146
;----------------------------------------------------------------
2147
;
2147
;
2148
;  fs_FloppyDelete - delete file or empty folder from floppy
2148
;  fs_FloppyDelete - delete file or empty folder from floppy
2149
;
2149
;
2150
;  esi  points to filename
2150
;  esi  points to filename
2151
;
2151
;
2152
;  ret  eax = 0 ok or other = errormsg
2152
;  ret  eax = 0 ok or other = errormsg
2153
;
2153
;
2154
;--------------------------------------------------------------
2154
;--------------------------------------------------------------
2155
fs_FloppyDelete:
2155
fs_FloppyDelete:
2156
        call    read_flp_fat
2156
        call    read_flp_fat
2157
        cmp     [FDC_Status], 0
2157
        cmp     [FDC_Status], 0
2158
        jz      @f
2158
        jz      @f
2159
        push    11
2159
        push    11
2160
        jmp     .pop_ret
2160
        jmp     .pop_ret
2161
@@:
2161
@@:
2162
        cmp     byte [esi], 0
2162
        cmp     byte [esi], 0
2163
        jnz     @f
2163
        jnz     @f
2164
; cannot delete root!
2164
; cannot delete root!
2165
.access_denied:
2165
.access_denied:
2166
        push    ERROR_ACCESS_DENIED
2166
        push    ERROR_ACCESS_DENIED
2167
.pop_ret:
2167
.pop_ret:
2168
        pop     eax
2168
        pop     eax
2169
        ret
2169
        ret
2170
@@:
2170
@@:
2171
        and     [fd_prev_sector], 0
2171
        and     [fd_prev_sector], 0
2172
        and     [fd_prev_prev_sector], 0
2172
        and     [fd_prev_prev_sector], 0
2173
        push    edi
2173
        push    edi
2174
        call    fd_find_lfn
2174
        call    fd_find_lfn
2175
        jnc     .found
2175
        jnc     .found
2176
        pop     edi
2176
        pop     edi
2177
        push    ERROR_FILE_NOT_FOUND
2177
        push    ERROR_FILE_NOT_FOUND
2178
        jmp     .pop_ret
2178
        jmp     .pop_ret
2179
.found:
2179
.found:
2180
        cmp     dword [edi], '.   '
2180
        cmp     dword [edi], '.   '
2181
        jz      .access_denied2
2181
        jz      .access_denied2
2182
        cmp     dword [edi], '..  '
2182
        cmp     dword [edi], '..  '
2183
        jz      .access_denied2
2183
        jz      .access_denied2
2184
        test    byte [edi+11], 10h
2184
        test    byte [edi+11], 10h
2185
        jz      .dodel
2185
        jz      .dodel
2186
; we can delete only empty folders!
2186
; we can delete only empty folders!
2187
        push    eax
2187
        push    eax
2188
        movzx   eax, word [edi+26]
2188
        movzx   eax, word [edi+26]
2189
        push    ebx
2189
        push    ebx
2190
        pusha
2190
        pusha
2191
        add     eax, 31
2191
        add     eax, 31
2192
        call    read_chs_sector
2192
        call    read_chs_sector
2193
        popa
2193
        popa
2194
        mov     ebx, FDD_BUFF + 2*0x20
2194
        mov     ebx, FDD_BUFF + 2*0x20
2195
.checkempty:
2195
.checkempty:
2196
        cmp     byte [ebx], 0
2196
        cmp     byte [ebx], 0
2197
        jz      .empty
2197
        jz      .empty
2198
        cmp     byte [ebx], 0xE5
2198
        cmp     byte [ebx], 0xE5
2199
        jnz     .notempty
2199
        jnz     .notempty
2200
        add     ebx, 0x20
2200
        add     ebx, 0x20
2201
        cmp     ebx, FDD_BUFF + 0x200
2201
        cmp     ebx, FDD_BUFF + 0x200
2202
        jb      .checkempty
2202
        jb      .checkempty
2203
        movzx   eax, word [FLOPPY_FAT + eax*2]
2203
        movzx   eax, word [FLOPPY_FAT + eax*2]
2204
        pusha
2204
        pusha
2205
        add     eax, 31
2205
        add     eax, 31
2206
        call    read_chs_sector
2206
        call    read_chs_sector
2207
        popa
2207
        popa
2208
        mov     ebx, FDD_BUFF
2208
        mov     ebx, FDD_BUFF
2209
        jmp     .checkempty
2209
        jmp     .checkempty
2210
.notempty:
2210
.notempty:
2211
        pop     ebx
2211
        pop     ebx
2212
        pop     eax
2212
        pop     eax
2213
.access_denied2:
2213
.access_denied2:
2214
        pop     edi
2214
        pop     edi
2215
        jmp     .access_denied
2215
        jmp     .access_denied
2216
.empty:
2216
.empty:
2217
        pop     ebx
2217
        pop     ebx
2218
        pop     eax
2218
        pop     eax
2219
        pusha
2219
        pusha
2220
        call    read_chs_sector
2220
        call    read_chs_sector
2221
        popa
2221
        popa
2222
.dodel:
2222
.dodel:
2223
        push    eax
2223
        push    eax
2224
        movzx   eax, word [edi+26]
2224
        movzx   eax, word [edi+26]
2225
        xchg    eax, [esp]
2225
        xchg    eax, [esp]
2226
; delete folder entry
2226
; delete folder entry
2227
        mov     byte [edi], 0xE5
2227
        mov     byte [edi], 0xE5
2228
; delete LFN (if present)
2228
; delete LFN (if present)
2229
.lfndel:
2229
.lfndel:
2230
        cmp     edi, FDD_BUFF
2230
        cmp     edi, FDD_BUFF
2231
        ja      @f
2231
        ja      @f
2232
        cmp     [fd_prev_sector], 0
2232
        cmp     [fd_prev_sector], 0
2233
        jz      .lfndone
2233
        jz      .lfndone
2234
        push    [fd_prev_sector]
2234
        push    [fd_prev_sector]
2235
        push    [fd_prev_prev_sector]
2235
        push    [fd_prev_prev_sector]
2236
        pop     [fd_prev_sector]
2236
        pop     [fd_prev_sector]
2237
        and     [fd_prev_prev_sector], 0
2237
        and     [fd_prev_prev_sector], 0
2238
        pusha
2238
        pusha
2239
        call    save_chs_sector
2239
        call    save_chs_sector
2240
        popa
2240
        popa
2241
        pop     eax
2241
        pop     eax
2242
        pusha
2242
        pusha
2243
        call    read_chs_sector
2243
        call    read_chs_sector
2244
        popa
2244
        popa
2245
        mov     edi, FDD_BUFF+0x200
2245
        mov     edi, FDD_BUFF+0x200
2246
@@:
2246
@@:
2247
        sub     edi, 0x20
2247
        sub     edi, 0x20
2248
        cmp     byte [edi], 0xE5
2248
        cmp     byte [edi], 0xE5
2249
        jz      .lfndone
2249
        jz      .lfndone
2250
        cmp     byte [edi+11], 0xF
2250
        cmp     byte [edi+11], 0xF
2251
        jnz     .lfndone
2251
        jnz     .lfndone
2252
        mov     byte [edi], 0xE5
2252
        mov     byte [edi], 0xE5
2253
        jmp     .lfndel
2253
        jmp     .lfndel
2254
.lfndone:
2254
.lfndone:
2255
        pusha
2255
        pusha
2256
        call    save_chs_sector
2256
        call    save_chs_sector
2257
        popa
2257
        popa
2258
; delete FAT chain
2258
; delete FAT chain
2259
        pop     eax
2259
        pop     eax
2260
@@:
2260
@@:
2261
        cmp     eax, 2
2261
        cmp     eax, 2
2262
        jb      .done
2262
        jb      .done
2263
        cmp     eax, 0xFF8
2263
        cmp     eax, 0xFF8
2264
        jae     .done
2264
        jae     .done
2265
        lea     eax, [FLOPPY_FAT + eax*2]
2265
        lea     eax, [FLOPPY_FAT + eax*2]
2266
        push    dword [eax]
2266
        push    dword [eax]
2267
        and     word [eax], 0
2267
        and     word [eax], 0
2268
        pop     eax
2268
        pop     eax
2269
        and     eax, 0xFFF
2269
        and     eax, 0xFFF
2270
        jmp     @b
2270
        jmp     @b
2271
.done:
2271
.done:
2272
        call    save_flp_fat
2272
        call    save_flp_fat
2273
        pop     edi
2273
        pop     edi
2274
        xor     eax, eax
2274
        xor     eax, eax
2275
        ret
2275
        ret
2276
 
2276
 
2277
; \end{diamond}
2277
; \end{diamond}