Subversion Repositories Kolibri OS

Rev

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

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