Subversion Repositories Kolibri OS

Rev

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

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