Subversion Repositories Kolibri OS

Rev

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

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