Subversion Repositories Kolibri OS

Rev

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

Rev 588 Rev 593
1
$Revision: 588 $
-
 
2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;                                                              ;;
2
;;                                                              ;;
4
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
5
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
6
;;                                                              ;;
5
;;                                                              ;;
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 
7
 
-
 
8
$Revision: 593 $
-
 
9
 
8
 
10
 
9
image_of_eax EQU esp+36
11
image_of_eax EQU esp+36
10
image_of_ebx EQU esp+24
12
image_of_ebx EQU esp+24
11
 
13
 
12
; System function 70 - files with long names (LFN)
14
; System function 70 - files with long names (LFN)
13
; diamond, 2006
15
; diamond, 2006
14
 
16
 
15
iglobal
17
iglobal
16
; in this table names must be in lowercase
18
; in this table names must be in lowercase
17
rootdirs:
19
rootdirs:
18
	db	2,'rd'
20
	db	2,'rd'
19
	dd	fs_OnRamdisk
21
	dd	fs_OnRamdisk
20
	dd	fs_NextRamdisk
22
	dd	fs_NextRamdisk
21
	db	7,'ramdisk'
23
	db	7,'ramdisk'
22
	dd	fs_OnRamdisk
24
	dd	fs_OnRamdisk
23
	dd	fs_NextRamdisk
25
	dd	fs_NextRamdisk
24
	db	2,'fd'
26
	db	2,'fd'
25
	dd	fs_OnFloppy
27
	dd	fs_OnFloppy
26
	dd	fs_NextFloppy
28
	dd	fs_NextFloppy
27
	db	10,'floppydisk'
29
	db	10,'floppydisk'
28
	dd	fs_OnFloppy
30
	dd	fs_OnFloppy
29
	dd	fs_NextFloppy
31
	dd	fs_NextFloppy
30
	db	3,'hd0'
32
	db	3,'hd0'
31
	dd	fs_OnHd0
33
	dd	fs_OnHd0
32
	dd	fs_NextHd0
34
	dd	fs_NextHd0
33
	db	3,'hd1'
35
	db	3,'hd1'
34
	dd	fs_OnHd1
36
	dd	fs_OnHd1
35
	dd	fs_NextHd1
37
	dd	fs_NextHd1
36
	db	3,'hd2'
38
	db	3,'hd2'
37
	dd	fs_OnHd2
39
	dd	fs_OnHd2
38
	dd	fs_NextHd2
40
	dd	fs_NextHd2
39
	db	3,'hd3'
41
	db	3,'hd3'
40
	dd	fs_OnHd3
42
	dd	fs_OnHd3
41
	dd	fs_NextHd3
43
	dd	fs_NextHd3
42
;**********************************************
44
;**********************************************
43
	db	3,'cd0'
45
	db	3,'cd0'
44
	dd	fs_OnCd0
46
	dd	fs_OnCd0
45
	dd	fs_NextCd
47
	dd	fs_NextCd
46
	db	3,'cd1'
48
	db	3,'cd1'
47
	dd	fs_OnCd1
49
	dd	fs_OnCd1
48
	dd	fs_NextCd
50
	dd	fs_NextCd
49
	db	3,'cd2'
51
	db	3,'cd2'
50
	dd	fs_OnCd2
52
	dd	fs_OnCd2
51
	dd	fs_NextCd
53
	dd	fs_NextCd
52
	db	3,'cd3'
54
	db	3,'cd3'
53
	dd	fs_OnCd3
55
	dd	fs_OnCd3
54
	dd	fs_NextCd
56
	dd	fs_NextCd
55
;***********************************************
57
;***********************************************
56
	db	0
58
	db	0
57
 
59
 
58
 
60
 
59
virtual_root_query:
61
virtual_root_query:
60
	dd	fs_HasRamdisk
62
	dd	fs_HasRamdisk
61
	db	'rd',0
63
	db	'rd',0
62
	dd	fs_HasFloppy
64
	dd	fs_HasFloppy
63
	db	'fd',0
65
	db	'fd',0
64
	dd	fs_HasHd0
66
	dd	fs_HasHd0
65
	db	'hd0',0
67
	db	'hd0',0
66
	dd	fs_HasHd1
68
	dd	fs_HasHd1
67
	db	'hd1',0
69
	db	'hd1',0
68
	dd	fs_HasHd2
70
	dd	fs_HasHd2
69
	db	'hd2',0
71
	db	'hd2',0
70
	dd	fs_HasHd3
72
	dd	fs_HasHd3
71
	db	'hd3',0
73
	db	'hd3',0
72
;**********************************************
74
;**********************************************
73
	dd	fs_HasCd0
75
	dd	fs_HasCd0
74
	db	'cd0',0
76
	db	'cd0',0
75
	dd	fs_HasCd1
77
	dd	fs_HasCd1
76
	db	'cd1',0
78
	db	'cd1',0
77
	dd	fs_HasCd2
79
	dd	fs_HasCd2
78
	db	'cd2',0
80
	db	'cd2',0
79
	dd	fs_HasCd3
81
	dd	fs_HasCd3
80
	db	'cd3',0
82
	db	'cd3',0
81
;**********************************************
83
;**********************************************
82
	dd	0
84
	dd	0
83
endg
85
endg
84
 
86
 
85
file_system_lfn:
87
file_system_lfn:
86
; in: eax->fileinfo block
88
; in: eax->fileinfo block
87
; operation codes:
89
; operation codes:
88
; 0 : read file
90
; 0 : read file
89
; 1 : read folder
91
; 1 : read folder
90
; 2 : create/rewrite file
92
; 2 : create/rewrite file
91
; 3 : write/append to file
93
; 3 : write/append to file
92
; 4 : set end of file
94
; 4 : set end of file
93
; 5 : get file/directory attributes structure
95
; 5 : get file/directory attributes structure
94
; 6 : set file/directory attributes structure
96
; 6 : set file/directory attributes structure
95
; 7 : start application
97
; 7 : start application
96
; 8 : delete file
98
; 8 : delete file
97
; 9 : create directory
99
; 9 : create directory
98
 
100
 
99
; parse file name
101
; parse file name
100
	xchg	ebx, eax
102
	xchg	ebx, eax
101
	lea	esi, [ebx+20]
103
	lea	esi, [ebx+20]
102
	lodsb
104
	lodsb
103
	test	al, al
105
	test	al, al
104
	jnz	@f
106
	jnz	@f
105
	mov	esi, [esi]
107
	mov	esi, [esi]
106
	lodsb
108
	lodsb
107
@@:
109
@@:
108
	cmp	al, '/'
110
	cmp	al, '/'
109
	jz	.notcurdir
111
	jz	.notcurdir
110
	dec	esi
112
	dec	esi
111
	mov	ebp, esi
113
	mov	ebp, esi
112
	test	al, al
114
	test	al, al
113
	jnz	@f
115
	jnz	@f
114
	xor	ebp, ebp
116
	xor	ebp, ebp
115
@@:
117
@@:
116
	mov	esi, [current_slot]
118
	mov	esi, [current_slot]
117
	mov	esi, [esi+APPDATA.cur_dir]
119
	mov	esi, [esi+APPDATA.cur_dir]
118
	jmp	.parse_normal
120
	jmp	.parse_normal
119
.notcurdir:
121
.notcurdir:
120
	cmp	byte [esi], 0
122
	cmp	byte [esi], 0
121
	jz	.rootdir
123
	jz	.rootdir
122
	call	process_replace_file_name
124
	call	process_replace_file_name
123
.parse_normal:
125
.parse_normal:
124
	cmp dword [ebx], 7
126
	cmp dword [ebx], 7
125
	jne @F
127
	jne @F
126
	mov edx, [ebx+4]
128
	mov edx, [ebx+4]
127
	mov ebx, [ebx+8]
129
	mov ebx, [ebx+8]
128
	call fs_execute  ; esi+ebp, ebx, edx
130
	call fs_execute  ; esi+ebp, ebx, edx
129
	mov [image_of_eax], eax
131
	mov [image_of_eax], eax
130
	ret
132
	ret
131
@@:
133
@@:
132
	mov	edi, rootdirs-8
134
	mov	edi, rootdirs-8
133
	xor	ecx, ecx
135
	xor	ecx, ecx
134
	push	esi
136
	push	esi
135
.scan1:
137
.scan1:
136
	pop	esi
138
	pop	esi
137
	add	edi, ecx
139
	add	edi, ecx
138
	scasd
140
	scasd
139
	scasd
141
	scasd
140
	mov	cl, byte [edi]
142
	mov	cl, byte [edi]
141
	test	cl, cl
143
	test	cl, cl
142
	jz	.notfound
144
	jz	.notfound
143
	inc	edi
145
	inc	edi
144
	push	esi
146
	push	esi
145
@@:
147
@@:
146
	lodsb
148
	lodsb
147
	or	al, 20h
149
	or	al, 20h
148
	scasb
150
	scasb
149
	loopz	@b
151
	loopz	@b
150
	jnz	.scan1
152
	jnz	.scan1
151
	lodsb
153
	lodsb
152
	cmp	al, '/'
154
	cmp	al, '/'
153
	jz	.found1
155
	jz	.found1
154
	test	al, al
156
	test	al, al
155
	jnz	.scan1
157
	jnz	.scan1
156
	pop	eax
158
	pop	eax
157
; directory /xxx
159
; directory /xxx
158
.maindir:
160
.maindir:
159
	cmp	dword [ebx], 1
161
	cmp	dword [ebx], 1
160
	jnz	.access_denied
162
	jnz	.access_denied
161
	xor	eax, eax
163
	xor	eax, eax
162
	mov	ebp, [ebx+12]
164
	mov	ebp, [ebx+12]
163
	mov	edx, [ebx+16]
165
	mov	edx, [ebx+16]
164
    ;    add     edx, std_application_base_address
166
    ;    add     edx, std_application_base_address
165
	push	dword [ebx+4]	; first block
167
	push	dword [ebx+4]	; first block
166
	mov	ebx, [ebx+8]	; flags
168
	mov	ebx, [ebx+8]	; flags
167
	mov	esi, [edi+4]
169
	mov	esi, [edi+4]
168
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
170
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
169
	mov	edi, edx
171
	mov	edi, edx
170
	mov	ecx, 32/4
172
	mov	ecx, 32/4
171
	rep	stosd
173
	rep	stosd
172
	mov	byte [edx], 1	; version
174
	mov	byte [edx], 1	; version
173
.maindir_loop:
175
.maindir_loop:
174
	call	esi
176
	call	esi
175
	jc	.maindir_done
177
	jc	.maindir_done
176
	inc	dword [edx+8]
178
	inc	dword [edx+8]
177
	dec	dword [esp]
179
	dec	dword [esp]
178
	jns	.maindir_loop
180
	jns	.maindir_loop
179
	dec	ebp
181
	dec	ebp
180
	js	.maindir_loop
182
	js	.maindir_loop
181
	inc	dword [edx+4]
183
	inc	dword [edx+4]
182
	mov	dword [edi], 0x10	; attributes: folder
184
	mov	dword [edi], 0x10	; attributes: folder
183
	mov	dword [edi+4], 1	; name type: UNICODE
185
	mov	dword [edi+4], 1	; name type: UNICODE
184
	push	eax
186
	push	eax
185
	xor	eax, eax
187
	xor	eax, eax
186
	add	edi, 8
188
	add	edi, 8
187
	mov	ecx, 40/4-2
189
	mov	ecx, 40/4-2
188
	rep	stosd
190
	rep	stosd
189
	pop	eax
191
	pop	eax
190
	push	eax edx
192
	push	eax edx
191
; convert number in eax to decimal UNICODE string
193
; convert number in eax to decimal UNICODE string
192
	push	edi
194
	push	edi
193
	push	-'0'
195
	push	-'0'
194
	mov	cl, 10
196
	mov	cl, 10
195
@@:
197
@@:
196
	xor	edx, edx
198
	xor	edx, edx
197
	div	ecx
199
	div	ecx
198
	push	edx
200
	push	edx
199
	test	eax, eax
201
	test	eax, eax
200
	jnz	@b
202
	jnz	@b
201
@@:
203
@@:
202
	pop	eax
204
	pop	eax
203
	add	al, '0'
205
	add	al, '0'
204
	stosb
206
	stosb
205
	test	bl, 1		; UNICODE name?
207
	test	bl, 1		; UNICODE name?
206
	jz	.ansi2
208
	jz	.ansi2
207
	mov	byte [edi], 0
209
	mov	byte [edi], 0
208
	inc	edi
210
	inc	edi
209
.ansi2:
211
.ansi2:
210
	test	al, al
212
	test	al, al
211
	jnz	@b
213
	jnz	@b
212
	mov	byte [edi-1], 0
214
	mov	byte [edi-1], 0
213
	pop	edi
215
	pop	edi
214
; UNICODE name length is 520 bytes, ANSI - 264
216
; UNICODE name length is 520 bytes, ANSI - 264
215
	add	edi, 520
217
	add	edi, 520
216
	test	bl, 1
218
	test	bl, 1
217
	jnz	@f
219
	jnz	@f
218
	sub	edi, 520-264
220
	sub	edi, 520-264
219
@@:
221
@@:
220
	pop	edx eax
222
	pop	edx eax
221
	jmp	.maindir_loop
223
	jmp	.maindir_loop
222
.maindir_done:
224
.maindir_done:
223
	pop	eax
225
	pop	eax
224
	mov	ebx, [edx+4]
226
	mov	ebx, [edx+4]
225
	xor	eax, eax
227
	xor	eax, eax
226
	dec	ebp
228
	dec	ebp
227
	js	@f
229
	js	@f
228
	mov	al, ERROR_END_OF_FILE
230
	mov	al, ERROR_END_OF_FILE
229
@@:
231
@@:
230
	mov	[image_of_eax], eax
232
	mov	[image_of_eax], eax
231
	mov	[image_of_ebx], ebx
233
	mov	[image_of_ebx], ebx
232
	ret
234
	ret
233
; directory /
235
; directory /
234
.rootdir:
236
.rootdir:
235
	cmp	dword [ebx], 1	; read folder?
237
	cmp	dword [ebx], 1	; read folder?
236
	jz	.readroot
238
	jz	.readroot
237
.access_denied:
239
.access_denied:
238
	mov	dword [image_of_eax], 10      ; access denied
240
	mov	dword [image_of_eax], 10      ; access denied
239
	ret
241
	ret
240
 
242
 
241
.readroot:
243
.readroot:
242
; virtual root folder - special handler
244
; virtual root folder - special handler
243
	mov	esi, virtual_root_query
245
	mov	esi, virtual_root_query
244
	mov	ebp, [ebx+12]
246
	mov	ebp, [ebx+12]
245
	mov	edx, [ebx+16]
247
	mov	edx, [ebx+16]
246
    ;    add     edx, std_application_base_address
248
    ;    add     edx, std_application_base_address
247
	push	dword [ebx+4]	; first block
249
	push	dword [ebx+4]	; first block
248
	mov	ebx, [ebx+8]	; flags
250
	mov	ebx, [ebx+8]	; flags
249
	xor	eax, eax
251
	xor	eax, eax
250
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
252
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
251
	mov	edi, edx
253
	mov	edi, edx
252
	mov	ecx, 32/4
254
	mov	ecx, 32/4
253
	rep	stosd
255
	rep	stosd
254
	mov	byte [edx], 1	; version
256
	mov	byte [edx], 1	; version
255
.readroot_loop:
257
.readroot_loop:
256
	cmp	dword [esi], eax
258
	cmp	dword [esi], eax
257
	jz	.readroot_done
259
	jz	.readroot_done
258
	call	dword [esi]
260
	call	dword [esi]
259
	add	esi, 4
261
	add	esi, 4
260
	test	eax, eax
262
	test	eax, eax
261
	jnz	@f
263
	jnz	@f
262
.readroot_next:
264
.readroot_next:
263
	or	ecx, -1
265
	or	ecx, -1
264
	xchg	esi, edi
266
	xchg	esi, edi
265
	repnz	scasb
267
	repnz	scasb
266
	xchg	esi, edi
268
	xchg	esi, edi
267
	jmp	.readroot_loop
269
	jmp	.readroot_loop
268
@@:
270
@@:
269
	xor	eax, eax
271
	xor	eax, eax
270
	inc	dword [edx+8]
272
	inc	dword [edx+8]
271
	dec	dword [esp]
273
	dec	dword [esp]
272
	jns	.readroot_next
274
	jns	.readroot_next
273
	dec	ebp
275
	dec	ebp
274
	js	.readroot_next
276
	js	.readroot_next
275
	inc	dword [edx+4]
277
	inc	dword [edx+4]
276
	mov	dword [edi], 0x10	; attributes: folder
278
	mov	dword [edi], 0x10	; attributes: folder
277
	mov	dword [edi+4], 1	; name type: UNICODE
279
	mov	dword [edi+4], 1	; name type: UNICODE
278
	add	edi, 8
280
	add	edi, 8
279
	mov	ecx, 40/4-2
281
	mov	ecx, 40/4-2
280
	rep	stosd
282
	rep	stosd
281
	push	edi
283
	push	edi
282
@@:
284
@@:
283
	lodsb
285
	lodsb
284
	stosb
286
	stosb
285
	test	bl, 1
287
	test	bl, 1
286
	jz	.ansi
288
	jz	.ansi
287
	mov	byte [edi], 0
289
	mov	byte [edi], 0
288
	inc	edi
290
	inc	edi
289
.ansi:
291
.ansi:
290
	test	eax, eax
292
	test	eax, eax
291
	jnz	@b
293
	jnz	@b
292
	pop	edi
294
	pop	edi
293
	add	edi, 520
295
	add	edi, 520
294
	test	bl, 1
296
	test	bl, 1
295
	jnz	.readroot_loop
297
	jnz	.readroot_loop
296
	sub	edi, 520-264
298
	sub	edi, 520-264
297
	jmp	.readroot_loop
299
	jmp	.readroot_loop
298
.readroot_done:
300
.readroot_done:
299
	pop	eax
301
	pop	eax
300
	mov	ebx, [edx+4]
302
	mov	ebx, [edx+4]
301
	xor	eax, eax
303
	xor	eax, eax
302
	dec	ebp
304
	dec	ebp
303
	js	@f
305
	js	@f
304
	mov	al, ERROR_END_OF_FILE
306
	mov	al, ERROR_END_OF_FILE
305
@@:
307
@@:
306
	mov	[image_of_eax], eax
308
	mov	[image_of_eax], eax
307
	mov	[image_of_ebx], ebx
309
	mov	[image_of_ebx], ebx
308
	ret
310
	ret
309
.notfound:
311
.notfound:
310
	mov	dword [image_of_eax], ERROR_FILE_NOT_FOUND
312
	mov	dword [image_of_eax], ERROR_FILE_NOT_FOUND
311
	and	dword [image_of_ebx], 0
313
	and	dword [image_of_ebx], 0
312
	ret
314
	ret
313
 
315
 
314
.found1:
316
.found1:
315
	pop	eax
317
	pop	eax
316
	cmp	byte [esi], 0
318
	cmp	byte [esi], 0
317
	jz	.maindir
319
	jz	.maindir
318
; read partition number
320
; read partition number
319
	xor	ecx, ecx
321
	xor	ecx, ecx
320
	xor	eax, eax
322
	xor	eax, eax
321
@@:
323
@@:
322
	lodsb
324
	lodsb
323
	cmp	al, '/'
325
	cmp	al, '/'
324
	jz	.done1
326
	jz	.done1
325
	test	al, al
327
	test	al, al
326
	jz	.done1
328
	jz	.done1
327
	sub	al, '0'
329
	sub	al, '0'
328
	cmp	al, 9
330
	cmp	al, 9
329
	ja	.notfound
331
	ja	.notfound
330
	lea	ecx, [ecx*5]
332
	lea	ecx, [ecx*5]
331
	lea	ecx, [ecx*2+eax]
333
	lea	ecx, [ecx*2+eax]
332
	jmp	@b
334
	jmp	@b
333
.done1:
335
.done1:
334
	jecxz	.notfound
336
	jecxz	.notfound
335
	test	al, al
337
	test	al, al
336
	jnz	@f
338
	jnz	@f
337
	dec	esi
339
	dec	esi
338
@@:
340
@@:
339
	cmp	byte [esi], 0
341
	cmp	byte [esi], 0
340
	jnz	@f
342
	jnz	@f
341
	test	ebp, ebp
343
	test	ebp, ebp
342
	jz	@f
344
	jz	@f
343
	mov	esi, ebp
345
	mov	esi, ebp
344
	xor	ebp, ebp
346
	xor	ebp, ebp
345
@@:
347
@@:
346
; now [edi] contains handler address, ecx - partition number,
348
; now [edi] contains handler address, ecx - partition number,
347
; esi points to ASCIIZ string - rest of name
349
; esi points to ASCIIZ string - rest of name
348
	jmp	dword [edi]
350
	jmp	dword [edi]
349
 
351
 
350
; handlers for devices
352
; handlers for devices
351
; in: ecx = 0 => query virtual directory /xxx
353
; in: ecx = 0 => query virtual directory /xxx
352
; in: ecx = partition number
354
; in: ecx = partition number
353
;     esi -> relative (for device) name
355
;     esi -> relative (for device) name
354
;     ebx -> fileinfo
356
;     ebx -> fileinfo
355
;     ebp = 0 or pointer to rest of name from folder addressed by esi
357
;     ebp = 0 or pointer to rest of name from folder addressed by esi
356
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
358
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
357
 
359
 
358
fs_OnRamdisk:
360
fs_OnRamdisk:
359
	cmp	ecx, 1
361
	cmp	ecx, 1
360
	jnz	file_system_lfn.notfound
362
	jnz	file_system_lfn.notfound
361
	mov	eax, [ebx]
363
	mov	eax, [ebx]
362
	cmp	eax, fs_NumRamdiskServices
364
	cmp	eax, fs_NumRamdiskServices
363
	jae	.not_impl
365
	jae	.not_impl
364
	mov	ecx, [ebx+12]
366
	mov	ecx, [ebx+12]
365
	mov	edx, [ebx+16]
367
	mov	edx, [ebx+16]
366
   ;     add     edx, std_application_base_address
368
   ;     add     edx, std_application_base_address
367
	add	ebx, 4
369
	add	ebx, 4
368
	call	dword [fs_RamdiskServices + eax*4]
370
	call	dword [fs_RamdiskServices + eax*4]
369
	mov	[image_of_eax], eax
371
	mov	[image_of_eax], eax
370
	mov	[image_of_ebx], ebx
372
	mov	[image_of_ebx], ebx
371
	ret
373
	ret
372
.not_impl:
374
.not_impl:
373
	mov	dword [image_of_eax], 2       ; not implemented
375
	mov	dword [image_of_eax], 2       ; not implemented
374
	ret
376
	ret
375
 
377
 
376
fs_NotImplemented:
378
fs_NotImplemented:
377
	mov	eax, 2
379
	mov	eax, 2
378
	ret
380
	ret
379
 
381
 
380
fs_RamdiskServices:
382
fs_RamdiskServices:
381
	dd	fs_RamdiskRead
383
	dd	fs_RamdiskRead
382
	dd	fs_RamdiskReadFolder
384
	dd	fs_RamdiskReadFolder
383
	dd	fs_RamdiskRewrite
385
	dd	fs_RamdiskRewrite
384
	dd	fs_RamdiskWrite
386
	dd	fs_RamdiskWrite
385
	dd	fs_RamdiskSetFileEnd
387
	dd	fs_RamdiskSetFileEnd
386
	dd	fs_RamdiskGetFileInfo
388
	dd	fs_RamdiskGetFileInfo
387
	dd	fs_RamdiskSetFileInfo
389
	dd	fs_RamdiskSetFileInfo
388
	dd	0
390
	dd	0
389
	dd	fs_RamdiskDelete
391
	dd	fs_RamdiskDelete
390
	dd	fs_RamdiskCreateFolder
392
	dd	fs_RamdiskCreateFolder
391
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
393
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
392
 
394
 
393
fs_OnFloppy:
395
fs_OnFloppy:
394
	cmp	ecx, 2
396
	cmp	ecx, 2
395
	ja	file_system_lfn.notfound
397
	ja	file_system_lfn.notfound
396
	mov	eax, [ebx]
398
	mov	eax, [ebx]
397
	cmp	eax, fs_NumFloppyServices
399
	cmp	eax, fs_NumFloppyServices
398
	jae	fs_OnRamdisk.not_impl
400
	jae	fs_OnRamdisk.not_impl
399
	call	reserve_flp
401
	call	reserve_flp
400
	mov	[flp_number], cl
402
	mov	[flp_number], cl
401
	mov	ecx, [ebx+12]
403
	mov	ecx, [ebx+12]
402
	mov	edx, [ebx+16]
404
	mov	edx, [ebx+16]
403
   ;     add     edx, std_application_base_address
405
   ;     add     edx, std_application_base_address
404
	add	ebx, 4
406
	add	ebx, 4
405
	call	dword [fs_FloppyServices + eax*4]
407
	call	dword [fs_FloppyServices + eax*4]
406
	and	[flp_status], 0
408
	and	[flp_status], 0
407
	mov	[image_of_eax], eax
409
	mov	[image_of_eax], eax
408
	mov	[image_of_ebx], ebx
410
	mov	[image_of_ebx], ebx
409
	ret
411
	ret
410
 
412
 
411
fs_FloppyServices:
413
fs_FloppyServices:
412
	dd	fs_FloppyRead
414
	dd	fs_FloppyRead
413
	dd	fs_FloppyReadFolder
415
	dd	fs_FloppyReadFolder
414
	dd	fs_FloppyRewrite
416
	dd	fs_FloppyRewrite
415
	dd	fs_FloppyWrite
417
	dd	fs_FloppyWrite
416
	dd	fs_FloppySetFileEnd
418
	dd	fs_FloppySetFileEnd
417
	dd	fs_FloppyGetFileInfo
419
	dd	fs_FloppyGetFileInfo
418
	dd	fs_FloppySetFileInfo
420
	dd	fs_FloppySetFileInfo
419
	dd	0
421
	dd	0
420
	dd	fs_FloppyDelete
422
	dd	fs_FloppyDelete
421
	dd	fs_FloppyCreateFolder
423
	dd	fs_FloppyCreateFolder
422
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
424
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
423
 
425
 
424
fs_OnHd0:
426
fs_OnHd0:
425
	call	reserve_hd1
427
	call	reserve_hd1
426
	mov	[hdbase], 0x1F0
428
	mov	[hdbase], 0x1F0
427
	mov	[hdid], 0
429
	mov	[hdid], 0
428
	push	1
430
	push	1
429
	jmp	fs_OnHd
431
	jmp	fs_OnHd
430
fs_OnHd1:
432
fs_OnHd1:
431
	call	reserve_hd1
433
	call	reserve_hd1
432
	mov	[hdbase], 0x1F0
434
	mov	[hdbase], 0x1F0
433
	mov	[hdid], 0x10
435
	mov	[hdid], 0x10
434
	push	2
436
	push	2
435
	jmp	fs_OnHd
437
	jmp	fs_OnHd
436
fs_OnHd2:
438
fs_OnHd2:
437
	call	reserve_hd1
439
	call	reserve_hd1
438
	mov	[hdbase], 0x170
440
	mov	[hdbase], 0x170
439
	mov	[hdid], 0
441
	mov	[hdid], 0
440
	push	3
442
	push	3
441
	jmp	fs_OnHd
443
	jmp	fs_OnHd
442
fs_OnHd3:
444
fs_OnHd3:
443
	call	reserve_hd1
445
	call	reserve_hd1
444
	mov	[hdbase], 0x170
446
	mov	[hdbase], 0x170
445
	mov	[hdid], 0x10
447
	mov	[hdid], 0x10
446
	push	4
448
	push	4
447
fs_OnHd:
449
fs_OnHd:
448
	call	reserve_hd_channel
450
	call	reserve_hd_channel
449
	pop	eax
451
	pop	eax
450
	mov	[hdpos], eax
452
	mov	[hdpos], eax
451
	cmp	ecx, 0x100
453
	cmp	ecx, 0x100
452
	jae	.nf
454
	jae	.nf
453
	cmp	cl, [DRIVE_DATA+1+eax]
455
	cmp	cl, [DRIVE_DATA+1+eax]
454
	jbe	@f
456
	jbe	@f
455
.nf:
457
.nf:
456
	call	free_hd_channel
458
	call	free_hd_channel
457
	and	[hd1_status], 0
459
	and	[hd1_status], 0
458
	mov	dword [image_of_eax], 5       ; not found
460
	mov	dword [image_of_eax], 5       ; not found
459
	ret
461
	ret
460
@@:
462
@@:
461
	mov	[fat32part], ecx
463
	mov	[fat32part], ecx
462
	push	ebx esi
464
	push	ebx esi
463
	call	choice_necessity_partition_1
465
	call	choice_necessity_partition_1
464
	pop	esi ebx
466
	pop	esi ebx
465
	mov	ecx, [ebx+12]
467
	mov	ecx, [ebx+12]
466
	mov	edx, [ebx+16]
468
	mov	edx, [ebx+16]
467
    ;    add     edx, std_application_base_address
469
    ;    add     edx, std_application_base_address
468
	mov	eax, [ebx]
470
	mov	eax, [ebx]
469
	cmp	eax, fs_NumHdServices
471
	cmp	eax, fs_NumHdServices
470
	jae	.not_impl
472
	jae	.not_impl
471
	add	ebx, 4
473
	add	ebx, 4
472
	call	dword [fs_HdServices + eax*4]
474
	call	dword [fs_HdServices + eax*4]
473
	call	free_hd_channel
475
	call	free_hd_channel
474
	and	[hd1_status], 0
476
	and	[hd1_status], 0
475
	mov	[image_of_eax], eax
477
	mov	[image_of_eax], eax
476
	mov	[image_of_ebx], ebx
478
	mov	[image_of_ebx], ebx
477
	ret
479
	ret
478
.not_impl:
480
.not_impl:
479
	call	free_hd_channel
481
	call	free_hd_channel
480
	and	[hd1_status], 0
482
	and	[hd1_status], 0
481
	mov	dword [image_of_eax], 2       ; not implemented
483
	mov	dword [image_of_eax], 2       ; not implemented
482
	ret
484
	ret
483
 
485
 
484
fs_HdServices:
486
fs_HdServices:
485
	dd	fs_HdRead
487
	dd	fs_HdRead
486
	dd	fs_HdReadFolder
488
	dd	fs_HdReadFolder
487
	dd	fs_HdRewrite
489
	dd	fs_HdRewrite
488
	dd	fs_HdWrite
490
	dd	fs_HdWrite
489
	dd	fs_HdSetFileEnd
491
	dd	fs_HdSetFileEnd
490
	dd	fs_HdGetFileInfo
492
	dd	fs_HdGetFileInfo
491
	dd	fs_HdSetFileInfo
493
	dd	fs_HdSetFileInfo
492
	dd	0
494
	dd	0
493
	dd	fs_HdDelete
495
	dd	fs_HdDelete
494
	dd	fs_HdCreateFolder
496
	dd	fs_HdCreateFolder
495
fs_NumHdServices = ($ - fs_HdServices)/4
497
fs_NumHdServices = ($ - fs_HdServices)/4
496
 
498
 
497
;*******************************************************
499
;*******************************************************
498
fs_OnCd0:
500
fs_OnCd0:
499
	call	reserve_cd
501
	call	reserve_cd
500
	mov  [ChannelNumber],1
502
	mov  [ChannelNumber],1
501
	mov  [DiskNumber],0
503
	mov  [DiskNumber],0
502
	push	6
504
	push	6
503
	push	1
505
	push	1
504
	jmp	fs_OnCd
506
	jmp	fs_OnCd
505
fs_OnCd1:
507
fs_OnCd1:
506
	call	reserve_cd
508
	call	reserve_cd
507
	mov  [ChannelNumber],1
509
	mov  [ChannelNumber],1
508
	mov  [DiskNumber],1
510
	mov  [DiskNumber],1
509
	push	4
511
	push	4
510
	push	2
512
	push	2
511
	jmp	fs_OnCd
513
	jmp	fs_OnCd
512
fs_OnCd2:
514
fs_OnCd2:
513
	call	reserve_cd
515
	call	reserve_cd
514
	mov  [ChannelNumber],2
516
	mov  [ChannelNumber],2
515
	mov  [DiskNumber],0
517
	mov  [DiskNumber],0
516
	push	2
518
	push	2
517
	push	3
519
	push	3
518
	jmp	fs_OnCd
520
	jmp	fs_OnCd
519
fs_OnCd3:
521
fs_OnCd3:
520
	call	reserve_cd
522
	call	reserve_cd
521
	mov  [ChannelNumber],2
523
	mov  [ChannelNumber],2
522
	mov  [DiskNumber],1
524
	mov  [DiskNumber],1
523
	push	0
525
	push	0
524
	push	4
526
	push	4
525
fs_OnCd:
527
fs_OnCd:
526
	call	reserve_cd_channel
528
	call	reserve_cd_channel
527
	pop	eax
529
	pop	eax
528
	mov	[cdpos], eax
530
	mov	[cdpos], eax
529
	pop	eax
531
	pop	eax
530
	cmp	ecx, 0x100
532
	cmp	ecx, 0x100
531
	jae	.nf
533
	jae	.nf
532
	push	ecx ebx
534
	push	ecx ebx
533
	mov	cl,al
535
	mov	cl,al
534
	mov	bl,[DRIVE_DATA+1]
536
	mov	bl,[DRIVE_DATA+1]
535
	shr	bl,cl
537
	shr	bl,cl
536
	test	bl,2
538
	test	bl,2
537
	pop	ebx ecx
539
	pop	ebx ecx
538
 
540
 
539
	jnz	@f
541
	jnz	@f
540
.nf:
542
.nf:
541
	call	free_cd_channel
543
	call	free_cd_channel
542
	and    [cd_status], 0
544
	and    [cd_status], 0
543
	mov	dword [image_of_eax], 5       ; not found
545
	mov	dword [image_of_eax], 5       ; not found
544
	ret
546
	ret
545
@@:
547
@@:
546
	mov	ecx, [ebx+12]
548
	mov	ecx, [ebx+12]
547
	mov	edx, [ebx+16]
549
	mov	edx, [ebx+16]
548
    ;    add     edx, std_application_base_address
550
    ;    add     edx, std_application_base_address
549
	mov	eax, [ebx]
551
	mov	eax, [ebx]
550
	cmp	eax,fs_NumCdServices
552
	cmp	eax,fs_NumCdServices
551
	jae	 .not_impl
553
	jae	 .not_impl
552
	add	ebx, 4
554
	add	ebx, 4
553
	call	dword [fs_CdServices + eax*4]
555
	call	dword [fs_CdServices + eax*4]
554
	call	free_cd_channel
556
	call	free_cd_channel
555
	and	[cd_status], 0
557
	and	[cd_status], 0
556
	mov	[image_of_eax], eax
558
	mov	[image_of_eax], eax
557
	mov	[image_of_ebx], ebx
559
	mov	[image_of_ebx], ebx
558
	ret
560
	ret
559
.not_impl:
561
.not_impl:
560
	call	free_cd_channel
562
	call	free_cd_channel
561
	and	[cd_status], 0
563
	and	[cd_status], 0
562
	mov	dword [image_of_eax], 2       ; not implemented
564
	mov	dword [image_of_eax], 2       ; not implemented
563
	ret
565
	ret
564
 
566
 
565
fs_CdServices:
567
fs_CdServices:
566
	dd	fs_CdRead
568
	dd	fs_CdRead
567
	dd	fs_CdReadFolder
569
	dd	fs_CdReadFolder
568
	dd	fs_NotImplemented
570
	dd	fs_NotImplemented
569
	dd	fs_NotImplemented
571
	dd	fs_NotImplemented
570
	dd	fs_NotImplemented
572
	dd	fs_NotImplemented
571
	dd	fs_CdGetFileInfo
573
	dd	fs_CdGetFileInfo
572
	dd	fs_NotImplemented
574
	dd	fs_NotImplemented
573
	dd	0
575
	dd	0
574
	dd	fs_NotImplemented
576
	dd	fs_NotImplemented
575
	dd	fs_NotImplemented
577
	dd	fs_NotImplemented
576
fs_NumCdServices = ($ - fs_CdServices)/4
578
fs_NumCdServices = ($ - fs_CdServices)/4
577
 
579
 
578
;*******************************************************
580
;*******************************************************
579
 
581
 
580
fs_HasRamdisk:
582
fs_HasRamdisk:
581
	mov	al, 1	; we always have ramdisk
583
	mov	al, 1	; we always have ramdisk
582
	ret
584
	ret
583
 
585
 
584
fs_HasFloppy:
586
fs_HasFloppy:
585
	cmp	byte [DRIVE_DATA], 0
587
	cmp	byte [DRIVE_DATA], 0
586
	setnz	al
588
	setnz	al
587
	ret
589
	ret
588
 
590
 
589
fs_HasHd0:
591
fs_HasHd0:
590
	mov	al, [DRIVE_DATA+1]
592
	mov	al, [DRIVE_DATA+1]
591
	and	al, 11000000b
593
	and	al, 11000000b
592
	cmp	al, 01000000b
594
	cmp	al, 01000000b
593
	setz	al
595
	setz	al
594
	ret
596
	ret
595
fs_HasHd1:
597
fs_HasHd1:
596
	mov	al, [DRIVE_DATA+1]
598
	mov	al, [DRIVE_DATA+1]
597
	and	al, 00110000b
599
	and	al, 00110000b
598
	cmp	al, 00010000b
600
	cmp	al, 00010000b
599
	setz	al
601
	setz	al
600
	ret
602
	ret
601
fs_HasHd2:
603
fs_HasHd2:
602
	mov	al, [DRIVE_DATA+1]
604
	mov	al, [DRIVE_DATA+1]
603
	and	al, 00001100b
605
	and	al, 00001100b
604
	cmp	al, 00000100b
606
	cmp	al, 00000100b
605
	setz	al
607
	setz	al
606
	ret
608
	ret
607
fs_HasHd3:
609
fs_HasHd3:
608
	mov	al, [DRIVE_DATA+1]
610
	mov	al, [DRIVE_DATA+1]
609
	and	al, 00000011b
611
	and	al, 00000011b
610
	cmp	al, 00000001b
612
	cmp	al, 00000001b
611
	setz	al
613
	setz	al
612
	ret
614
	ret
613
 
615
 
614
;*******************************************************
616
;*******************************************************
615
fs_HasCd0:
617
fs_HasCd0:
616
	mov	al, [DRIVE_DATA+1]
618
	mov	al, [DRIVE_DATA+1]
617
	and	al, 11000000b
619
	and	al, 11000000b
618
	cmp	al, 10000000b
620
	cmp	al, 10000000b
619
	setz	al
621
	setz	al
620
	ret
622
	ret
621
fs_HasCd1:
623
fs_HasCd1:
622
	mov	al, [DRIVE_DATA+1]
624
	mov	al, [DRIVE_DATA+1]
623
	and	al, 00110000b
625
	and	al, 00110000b
624
	cmp	al, 00100000b
626
	cmp	al, 00100000b
625
	setz	al
627
	setz	al
626
	ret
628
	ret
627
fs_HasCd2:
629
fs_HasCd2:
628
	mov	al, [DRIVE_DATA+1]
630
	mov	al, [DRIVE_DATA+1]
629
	and	al, 00001100b
631
	and	al, 00001100b
630
	cmp	al, 00001000b
632
	cmp	al, 00001000b
631
	setz	al
633
	setz	al
632
	ret
634
	ret
633
fs_HasCd3:
635
fs_HasCd3:
634
	mov	al, [DRIVE_DATA+1]
636
	mov	al, [DRIVE_DATA+1]
635
	and	al, 00000011b
637
	and	al, 00000011b
636
	cmp	al, 00000010b
638
	cmp	al, 00000010b
637
	setz	al
639
	setz	al
638
	ret
640
	ret
639
;*******************************************************
641
;*******************************************************
640
 
642
 
641
; fs_NextXXX functions:
643
; fs_NextXXX functions:
642
; in: eax = partition number, from which start to scan
644
; in: eax = partition number, from which start to scan
643
; out: CF=1 => no more partitions
645
; out: CF=1 => no more partitions
644
;      CF=0 => eax=next partition number
646
;      CF=0 => eax=next partition number
645
 
647
 
646
fs_NextRamdisk:
648
fs_NextRamdisk:
647
; we always have /rd/1
649
; we always have /rd/1
648
	test	eax, eax
650
	test	eax, eax
649
	stc
651
	stc
650
	jnz	@f
652
	jnz	@f
651
	mov	al, 1
653
	mov	al, 1
652
	clc
654
	clc
653
@@:
655
@@:
654
	ret
656
	ret
655
 
657
 
656
fs_NextFloppy:
658
fs_NextFloppy:
657
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
659
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
658
	test	byte [DRIVE_DATA], 0xF0
660
	test	byte [DRIVE_DATA], 0xF0
659
	jz	.no1
661
	jz	.no1
660
	test	eax, eax
662
	test	eax, eax
661
	jnz	.no1
663
	jnz	.no1
662
	inc	eax
664
	inc	eax
663
	ret	; CF cleared
665
	ret	; CF cleared
664
.no1:
666
.no1:
665
	test	byte [DRIVE_DATA], 0x0F
667
	test	byte [DRIVE_DATA], 0x0F
666
	jz	.no2
668
	jz	.no2
667
	cmp	al, 2
669
	cmp	al, 2
668
	jae	.no2
670
	jae	.no2
669
	mov	al, 2
671
	mov	al, 2
670
	clc
672
	clc
671
	ret
673
	ret
672
.no2:
674
.no2:
673
	stc
675
	stc
674
	ret
676
	ret
675
 
677
 
676
; on hdx, we have partitions from 1 to [0x40002+x]
678
; on hdx, we have partitions from 1 to [0x40002+x]
677
fs_NextHd0:
679
fs_NextHd0:
678
	push	0
680
	push	0
679
	jmp	fs_NextHd
681
	jmp	fs_NextHd
680
fs_NextHd1:
682
fs_NextHd1:
681
	push	1
683
	push	1
682
	jmp	fs_NextHd
684
	jmp	fs_NextHd
683
fs_NextHd2:
685
fs_NextHd2:
684
	push	2
686
	push	2
685
	jmp	fs_NextHd
687
	jmp	fs_NextHd
686
fs_NextHd3:
688
fs_NextHd3:
687
	push	3
689
	push	3
688
fs_NextHd:
690
fs_NextHd:
689
	pop	ecx
691
	pop	ecx
690
	movzx	ecx, byte [DRIVE_DATA+2+ecx]
692
	movzx	ecx, byte [DRIVE_DATA+2+ecx]
691
	cmp	eax, ecx
693
	cmp	eax, ecx
692
	jae	fs_NextFloppy.no2
694
	jae	fs_NextFloppy.no2
693
	inc	eax
695
	inc	eax
694
	clc
696
	clc
695
	ret
697
	ret
696
 
698
 
697
;*******************************************************
699
;*******************************************************
698
fs_NextCd:
700
fs_NextCd:
699
; we always have /cdX/1
701
; we always have /cdX/1
700
	test	eax, eax
702
	test	eax, eax
701
	stc
703
	stc
702
	jnz	@f
704
	jnz	@f
703
	mov	al, 1
705
	mov	al, 1
704
	clc
706
	clc
705
@@:
707
@@:
706
	ret
708
	ret
707
;*******************************************************
709
;*******************************************************
708
 
710
 
709
process_replace_file_name:
711
process_replace_file_name:
710
	mov	ebp, [full_file_name_table]
712
	mov	ebp, [full_file_name_table]
711
	mov	edi, [full_file_name_table.size]
713
	mov	edi, [full_file_name_table.size]
712
	dec	edi
714
	dec	edi
713
	shl	edi, 7
715
	shl	edi, 7
714
	add	edi, ebp
716
	add	edi, ebp
715
.loop:
717
.loop:
716
	cmp	edi, ebp
718
	cmp	edi, ebp
717
	jb	.notfound
719
	jb	.notfound
718
	push	esi edi
720
	push	esi edi
719
@@:
721
@@:
720
	cmp	byte [edi], 0
722
	cmp	byte [edi], 0
721
	jz	.dest_done
723
	jz	.dest_done
722
	lodsb
724
	lodsb
723
	test	al, al
725
	test	al, al
724
	jz	.cont
726
	jz	.cont
725
	or	al, 20h
727
	or	al, 20h
726
	scasb
728
	scasb
727
	jz	@b
729
	jz	@b
728
	jmp	.cont
730
	jmp	.cont
729
.dest_done:
731
.dest_done:
730
	cmp	byte [esi], 0
732
	cmp	byte [esi], 0
731
	jz	.found
733
	jz	.found
732
	cmp	byte [esi], '/'
734
	cmp	byte [esi], '/'
733
	jnz	.cont
735
	jnz	.cont
734
	inc	esi
736
	inc	esi
735
	jmp	.found
737
	jmp	.found
736
.cont:
738
.cont:
737
	pop	edi esi
739
	pop	edi esi
738
	sub	edi, 128
740
	sub	edi, 128
739
	jmp	.loop
741
	jmp	.loop
740
.found:
742
.found:
741
	pop	edi eax
743
	pop	edi eax
742
	mov	ebp, esi
744
	mov	ebp, esi
743
	cmp	byte [esi], 0
745
	cmp	byte [esi], 0
744
	lea	esi, [edi+64]
746
	lea	esi, [edi+64]
745
	jnz	.ret
747
	jnz	.ret
746
.notfound:
748
.notfound:
747
	xor	ebp, ebp
749
	xor	ebp, ebp
748
.ret:
750
.ret:
749
	ret
751
	ret
750
 
752
 
751
sys_current_directory:
753
sys_current_directory:
752
	mov	esi, [current_slot]
754
	mov	esi, [current_slot]
753
	mov	esi, [esi+APPDATA.cur_dir]
755
	mov	esi, [esi+APPDATA.cur_dir]
754
	mov	edx, esi
756
	mov	edx, esi
755
	dec	eax
757
	dec	eax
756
	jz	.set
758
	jz	.set
757
	dec	eax
759
	dec	eax
758
	jz	.get
760
	jz	.get
759
	ret
761
	ret
760
.get:
762
.get:
761
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
763
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
762
; for our code: ebx->buffer,ecx=len
764
; for our code: ebx->buffer,ecx=len
763
@@:
765
@@:
764
	lodsb
766
	lodsb
765
	test	al, al
767
	test	al, al
766
	jnz	@b
768
	jnz	@b
767
	sub	esi, edx
769
	sub	esi, edx
768
	inc	esi
770
	inc	esi
769
	mov	[esp+36], esi
771
	mov	[esp+36], esi
770
	cmp	ecx, esi
772
	cmp	ecx, esi
771
	jbe	@f
773
	jbe	@f
772
	mov	ecx, esi
774
	mov	ecx, esi
773
@@:
775
@@:
774
	cmp	ecx, 1
776
	cmp	ecx, 1
775
	jbe	.ret
777
	jbe	.ret
776
	mov	esi, edx
778
	mov	esi, edx
777
	mov	edi, ebx
779
	mov	edi, ebx
778
	mov	al, '/'
780
	mov	al, '/'
779
	stosb
781
	stosb
780
	dec	ecx
782
	dec	ecx
781
	dec	ecx
783
	dec	ecx
782
	rep	movsb
784
	rep	movsb
783
	mov	byte [edi], 0
785
	mov	byte [edi], 0
784
.ret:
786
.ret:
785
	ret
787
	ret
786
.set:
788
.set:
787
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
789
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
788
; for our code: ebx->string to set
790
; for our code: ebx->string to set
789
@@:
791
@@:
790
	inc	esi
792
	inc	esi
791
	cmp	byte [esi-1], 0
793
	cmp	byte [esi-1], 0
792
	jnz	@b
794
	jnz	@b
793
	dec	esi
795
	dec	esi
794
	cmp	byte [ebx], '/'
796
	cmp	byte [ebx], '/'
795
	jz	.set_absolute
797
	jz	.set_absolute
796
; string gives relative path
798
; string gives relative path
797
.relative:
799
.relative:
798
	cmp	byte [ebx], 0
800
	cmp	byte [ebx], 0
799
	jz	.set_ok
801
	jz	.set_ok
800
	cmp	word [ebx], '.'
802
	cmp	word [ebx], '.'
801
	jz	.set_ok
803
	jz	.set_ok
802
	cmp	word [ebx], './'
804
	cmp	word [ebx], './'
803
	jnz	@f
805
	jnz	@f
804
	add	ebx, 2
806
	add	ebx, 2
805
	jmp	.relative
807
	jmp	.relative
806
@@:
808
@@:
807
	cmp	word [ebx], '..'
809
	cmp	word [ebx], '..'
808
	jnz	.doset_relative
810
	jnz	.doset_relative
809
	cmp	byte [ebx+2], 0
811
	cmp	byte [ebx+2], 0
810
	jz	@f
812
	jz	@f
811
	cmp	byte [ebx+2], '/'
813
	cmp	byte [ebx+2], '/'
812
	jnz	.doset_relative
814
	jnz	.doset_relative
813
@@:
815
@@:
814
	dec	esi
816
	dec	esi
815
	cmp	byte [esi], '/'
817
	cmp	byte [esi], '/'
816
	jnz	@b
818
	jnz	@b
817
	mov	byte [esi], 0
819
	mov	byte [esi], 0
818
	add	ebx, 3
820
	add	ebx, 3
819
	jmp	.relative
821
	jmp	.relative
820
.doset_relative:
822
.doset_relative:
821
	add	edx, 0x1000
823
	add	edx, 0x1000
822
	mov	byte [esi], '/'
824
	mov	byte [esi], '/'
823
	inc	esi
825
	inc	esi
824
	cmp	esi, edx
826
	cmp	esi, edx
825
	jae	.overflow_esi
827
	jae	.overflow_esi
826
@@:
828
@@:
827
	mov	al, [ebx]
829
	mov	al, [ebx]
828
	inc	ebx
830
	inc	ebx
829
	mov	[esi], al
831
	mov	[esi], al
830
	inc	esi
832
	inc	esi
831
	test	al, al
833
	test	al, al
832
	jz	.set_ok
834
	jz	.set_ok
833
	cmp	esi, edx
835
	cmp	esi, edx
834
	jb	@b
836
	jb	@b
835
.overflow_esi:
837
.overflow_esi:
836
	mov	byte [esi-1], 0 	; force null-terminated string
838
	mov	byte [esi-1], 0 	; force null-terminated string
837
.set_ok:
839
.set_ok:
838
	ret
840
	ret
839
.set_absolute:
841
.set_absolute:
840
	lea	esi, [ebx+1]
842
	lea	esi, [ebx+1]
841
	call	process_replace_file_name
843
	call	process_replace_file_name
842
	mov	edi, edx
844
	mov	edi, edx
843
	add	edx, 0x1000
845
	add	edx, 0x1000
844
.set_copy:
846
.set_copy:
845
	lodsb
847
	lodsb
846
	stosb
848
	stosb
847
	test	al, al
849
	test	al, al
848
	jz	.set_part2
850
	jz	.set_part2
849
.set_copy_cont:
851
.set_copy_cont:
850
	cmp	edi, edx
852
	cmp	edi, edx
851
	jb	.set_copy
853
	jb	.set_copy
852
.overflow_edi:
854
.overflow_edi:
853
	mov	byte [edi-1], 0
855
	mov	byte [edi-1], 0
854
	ret
856
	ret
855
.set_part2:
857
.set_part2:
856
	mov	esi, ebp
858
	mov	esi, ebp
857
	xor	ebp, ebp
859
	xor	ebp, ebp
858
	test	esi, esi
860
	test	esi, esi
859
	jz	.set_ok
861
	jz	.set_ok
860
	mov	byte [edi-1], '/'
862
	mov	byte [edi-1], '/'
861
	jmp	.set_copy_cont
863
	jmp	.set_copy_cont