Subversion Repositories Kolibri OS

Rev

Rev 77 | Rev 83 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ha 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                      ;;
3
;; RAMDISK functions                                                    ;;
4
;; (C) 2004 Ville Turjanmaa, License: GPL                               ;;
5
;; Addings by M.Lisovin                                                 ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
5 halyavin 8
; calculate fat chain
1 ha 9
 
5 halyavin 10
calculatefatchain:
11
 
12
   pushad
13
 
14
   mov  esi,0x100000+512
15
   mov  edi,0x280000
16
 
17
 fcnew:
18
   mov  eax,dword [esi]
19
   mov  ebx,dword [esi+4]
20
   mov  ecx,dword [esi+8]
21
   mov  edx,ecx
22
   shr  edx,4   ;8 ok
23
   shr  dx,4    ;7 ok
24
   xor  ch,ch
25
   shld ecx,ebx,20 ;6 ok
26
   shr  cx,4     ;5 ok
27
   shld ebx,eax,12
28
   and  ebx,0x0fffffff  ;4 ok
29
   shr  bx,4    ;3 ok
30
   shl  eax,4
31
   and  eax,0x0fffffff  ;2 ok
32
   shr  ax,4  ;1 ok
78 diamond 33
   mov  dword [edi],eax
34
   mov  dword [edi+4],ebx
35
   mov  dword [edi+8],ecx
36
   mov  dword [edi+12],edx
37
   add  edi,16
5 halyavin 38
   add  esi,12
39
 
40
   cmp  edi,0x280000+2856*2   ;2849 clusters
41
   jnz  fcnew
42
 
43
   popad
44
   ret
45
 
46
 
47
restorefatchain:   ; restore fat chain
48
 
49
   pushad
50
 
51
   mov  esi,0x280000
52
   mov  edi,0x100000+512
53
 
54
  fcnew2:
55
   mov  eax,dword [esi]
56
   mov  ebx,dword [esi+4]
57
   shl  ax,4
58
   shl  eax,4
59
   shl  bx,4
60
   shr  ebx,4
61
   shrd eax,ebx,8
62
   shr  ebx,8
78 diamond 63
   mov  dword [edi],eax
64
   mov  word [edi+4],bx
65
   add  edi,6
5 halyavin 66
   add  esi,8
67
 
68
   cmp  edi,0x100000+512+4278     ;4274 bytes - all used FAT
69
   jb   fcnew2
70
 
71
   mov  esi,0x100000+512           ; duplicate fat chain
72
   mov  edi,0x100000+512+0x1200
73
   mov  ecx,1069        ;4274/4
74
   cld
75
   rep  movsd
76
 
77
   popad
78
   ret
79
 
80
 
1 ha 81
ramdisk_free_space:
82
;---------------------------------------------
83
;
84
; returns free space in edi
85
; rewr.by Mihasik
86
;---------------------------------------------
87
 
88
        push   eax ebx ecx
89
 
90
        mov  edi,0x280000 ;start of FAT
91
        xor  ax,ax    ;Free cluster=0x0000 in FAT
92
        xor  ebx,ebx  ;counter
5 halyavin 93
        mov  ecx,2849 ;2849 clusters
1 ha 94
        cld
95
    rdfs1:
96
        repne scasw
97
        jnz  rdfs2    ;if last cluster not 0
98
        inc  ebx
78 diamond 99
        test    ecx, ecx
100
        jnz     rdfs1
1 ha 101
    rdfs2:
102
        shl  ebx,9    ;free clusters*512
103
        mov  edi,ebx
104
 
105
        pop    ecx ebx eax
106
        ret
107
 
108
 
109
expand_filename:
110
;---------------------------------------------
111
;
112
; exapand filename with '.' to 11 character
113
; eax - pointer to filename
114
;---------------------------------------------
115
 
116
        push esi edi ebx
117
 
118
        mov  edi,esp                  ; check for '.' in the name
119
        add  edi,12+8
120
 
121
        mov  esi,eax
122
 
123
        mov  eax,edi
124
        mov  [eax+0],dword '    '
125
        mov  [eax+4],dword '    '
126
        mov  [eax+8],dword '    '
127
 
128
      flr1:
129
 
130
        cmp  [esi],byte '.'
131
        jne  flr2
132
        mov  edi,eax
133
        add  edi,7
134
        jmp  flr3
135
 
136
      flr2:
137
 
138
        mov  bl,[esi]
139
        mov  [edi],bl
140
 
141
      flr3:
142
 
143
        inc  esi
144
        inc  edi
145
 
146
        mov  ebx,eax
147
        add  ebx,11
148
 
149
        cmp  edi,ebx
150
        jbe  flr1
151
 
152
        pop  ebx edi esi
153
        ret
154
 
155
fileread:
156
;----------------------------------------------------------------
157
;
158
;  fileread - sys floppy
159
;
160
;  eax  points to filename 11 chars
161
;  ebx  first wanted block       ; 1+ ; if 0 then set to 1
162
;  ecx  number of blocks to read ; 1+ ; if 0 then set to 1
163
;  edx  mem location to return data
164
;  esi  length of filename 12*X 0=root
165
;
166
;  ret ebx = size or 0xffffffff file not found
167
;      eax = 0 ok read or other = errormsg
168
;
169
;--------------------------------------------------------------
170
        test   ebx,ebx ;if ebx=0 - set to 1
171
        jnz    frfl5
172
        inc    ebx
173
      frfl5:
174
        test   ecx,ecx ;if ecx=0 - set to 1
175
        jnz    frfl6
176
        inc    ecx
177
      frfl6:
178
        test   esi,esi          ; return ramdisk root
179
        jnz    fr_noroot        ;if not root
180
        cmp    ebx,14           ;14 clusters=root dir
181
        ja     oorr
182
        cmp    ecx,14
183
        ja     oorr
184
        jmp    fr_do
185
      oorr:
186
        mov    eax,5            ;out of root range (fnf)
187
        xor    ebx,ebx
188
        dec    ebx              ;0xffffffff
189
        ret
190
 
191
      fr_do:                    ;reading rootdir
192
        mov    edi,edx
193
        dec    ebx
194
        push   edx
195
        mov    edx,ecx
196
        add    edx,ebx
5 halyavin 197
        cmp    edx,15     ;ebx+ecx=14+1
1 ha 198
        pushf
199
        jbe    fr_do1
200
        sub    edx,14
201
        sub    ecx,edx
202
      fr_do1:
203
        shl    ebx,9
204
        mov    esi,0x100000+512*19
205
        add    esi,ebx
206
        shl    ecx,7
207
        cld
208
        rep    movsd
209
        popf
210
        pop    edx
5 halyavin 211
        jae    fr_do2
1 ha 212
        xor    eax,eax ; ok read
213
        xor    ebx,ebx
214
        ret
215
      fr_do2:        ;if last cluster
216
        mov    eax,6  ;end of file
217
        xor    ebx,ebx
218
        ret
219
 
220
     fr_noroot:
221
 
222
        sub    esp,32
223
        call   expand_filename
224
 
225
        dec    ebx
226
 
227
        push   eax
228
 
229
        push   eax ebx ecx edx esi edi
230
        call   rd_findfile
231
        je     fifound
232
        add    esp,32+28   ;if file not found
233
        ret
234
 
235
     fifound:
236
 
237
        mov    ebx,[edi-11+28]          ;file size
238
        mov    [esp+20],ebx
239
        mov    [esp+24],ebx
240
        add    edi,0xf
241
        movzx  eax,word [edi]
242
        mov    edi,eax                  ;edi=cluster
243
 
244
      frnew:
245
 
246
        add    eax,31                   ;bootsector+2*fat+filenames
247
        shl    eax,9                    ;*512
248
        add    eax,0x100000             ;image base
249
        mov    ebx,[esp+8]
250
        mov    ecx,512                  ;[esp+4]
251
 
252
        cmp    [esp+16],dword 0         ; wanted cluster ?
253
        jne    frfl7
254
        call   memmove
255
        add    [esp+8],dword 512
256
        dec    dword [esp+12]           ; last wanted cluster ?
257
        je     frnoread
258
        jmp    frfl8
259
      frfl7:
260
        dec    dword [esp+16]
261
      frfl8:
71 diamond 262
        movzx  eax,word [edi*2+0x280000]	; find next cluster from FAT
1 ha 263
        mov    edi,eax
264
        cmp    edi,4095                 ;eof  - cluster
265
        jz     frnoread2
266
 
267
        cmp    [esp+24],dword 512       ;eof  - size
268
        jb     frnoread
269
        sub    [esp+24],dword 512
270
 
271
        jmp    frnew
272
 
273
      frnoread2:
274
 
275
        cmp    [esp+16],dword 0         ; eof without read ?
276
        je     frnoread
277
 
278
        pop    edi esi edx ecx
279
        add    esp,4
280
        pop    ebx     ; ebx <- eax : size of file
281
        add    esp,36
282
        mov    eax,6   ; end of file
283
        ret
284
 
285
      frnoread:
286
 
287
        pop    edi esi edx ecx
288
        add    esp,4
289
        pop    ebx     ; ebx <- eax : size of file
290
        add    esp,36
291
        xor    eax,eax  ;read ok
292
        ret
293
 
294
filedelete:
295
;--------------------------------------------
296
;
297
; filedelete - sys floppy
298
; in:
299
; eax -  pointer to filename 11 chars
300
;
301
; out:
302
; eax - 0 = successful, 5 = file not found
303
;
304
;--------------------------------------------
305
 
306
        sub    esp,32
307
        call   expand_filename
308
 
309
        push   eax ebx ecx edx esi edi
310
 
311
        call   rd_findfile
312
        je     fifoundd
313
        pop    edi esi edx ecx ebx eax ;file not found
314
        add    esp,32
315
        mov    eax,5
316
        ret
317
 
318
     fifoundd:
319
 
320
        mov    [edi-11],byte 0xE5       ;mark filename deleted
321
        add    edi,0xf
322
        movzx  eax,word [edi]
323
        mov    edi,eax                  ;edi = cluster
324
 
325
      frnewd:
326
 
327
        shl    edi,1                    ;find next cluster from FAT
328
        add    edi,0x280000
329
        movzx  eax,word [edi]
330
        mov    [edi],word 0x0           ;clear fat chain cluster
331
        mov    edi,eax
332
        cmp    edi,dword 0xff8          ;last cluster ?
333
        jb     frnewd
334
 
335
        pop    edi esi edx ecx ebx eax
336
        add    esp,32
337
        xor    eax,eax       ; file found
338
        ret
339
 
340
 
341
 
342
filesave:
343
;----------------------------------------------------------
344
;
345
; filesave - sys floppy
346
;
347
; eax points to filename 11 chars
348
;
349
;        eax      ; pointer to file name
350
;        ebx      ; buffer
351
;        ecx      ; count to write in bytes
352
;        edx      ; 0 create new , 1 append
353
;
354
;-----------------------------------------------------------
355
 
356
        sub  esp,32
357
        call expand_filename
358
        test edx,edx
359
        jnz  fsdel
360
        pusha
361
        call filedelete
362
        popa
363
 
364
      fsdel:
365
 
366
        call   ramdisk_free_space
367
        cmp    ecx,edi
368
        jbe    rd_do_save
369
        add    esp,32
370
        mov    eax,8    ;disk full
371
        ret
372
 
373
      rd_do_save:
374
 
375
        push   eax ebx ecx edx esi edi
376
 
377
        mov    edi,0x100000+512*18+512  ;Point at directory
378
        mov    edx,224 +1
379
        ; find an empty spot for filename in the root dir
380
     l20ds:
381
        dec    edx
382
        test   edx,edx
383
        jz     frnoreadds
384
     l21ds:
385
        cmp    [edi],byte 0xE5
386
        jz     fifoundds
387
        cmp    [edi],byte 0x0
388
        jz     fifoundds
389
        add    edi,32                   ; Advance to next entry
390
        jmp    l20ds
391
     fifoundds:
392
 
393
        push   edi                      ; move the filename to root dir
394
        mov    esi,[esp+4+20]
395
        mov    ecx,11
396
        cld
397
        rep    movsb
398
        pop    edi
399
        mov    edx,edi
400
        add    edx,11+0xf               ; edx <- cluster save position
401
        mov    ebx,[esp+12]             ; save file size
402
        mov    [edi+28],ebx
403
        mov    [edi+11],byte 0x20       ; attribute
404
; Ivan Poddubny 11/12/2003:
405
call get_date_for_file   ; from FAT32.INC
406
mov [edi+24],ax          ; date
407
call get_time_for_file   ; from FAT32.INC
408
mov [edi+22],ax          ; time
409
; End
410
        mov    edi,0x280000            ;pointer to first cluster
411
        mov    ecx,2849
412
        cld
413
      frnewds:
414
        xor    ax,ax
415
        repne  scasw
416
        mov    ebx,2848
417
        sub    ebx,ecx
418
        mov    [edx],bx                 ; save next cluster pos. to prev cl.
419
        mov    edx,edi                  ; next save pos abs mem add
420
        dec    edx
421
        dec    edx
422
        call   fdc_filesave
423
        pusha                           ; move save to floppy cluster
424
        add    ebx,31
425
        shl    ebx,9
426
        add    ebx,0x100000
427
        mov    eax,[esp+32+16]
428
        mov    ecx,512
429
        call   memmove
430
        popa
431
 
432
        mov    eax,[esp+12]
433
        cmp    eax,512
48 halyavin 434
        jbe    flnsa
1 ha 435
        sub    eax,512
436
        mov    [esp+12],eax
78 diamond 437
        add     dword [esp+16], 512
1 ha 438
        jmp    frnewds
439
 
440
     flnsa:
78 diamond 441
        mov    [edi-2],word 4095          ; mark end of file - last cluster
1 ha 442
 
443
      frnoreadds:
444
 
445
        pop    edi esi edx ecx ebx eax
446
        add    esp,32
447
 
19 mario79 448
;        pusha
449
;        cli
450
;        call   fdc_commitfile
451
;        sti
452
;        popa
1 ha 453
 
454
        xor    eax,eax ;ok write
455
        ret
456
 
457
   rd_findfile:
458
   ;by Mihasik
459
   ;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx
460
 
461
        mov    edi,0x100000+512*18+512  ;Point at directory
462
        cld
463
    rd_newsearch:
464
        mov    esi,eax
465
        mov    ecx,11
466
        rep    cmpsb
467
        je     rd_ff
468
        add    cl,21
469
        add    edi,ecx
470
        cmp    edi,0x100000+512*33
471
        jb     rd_newsearch
472
        mov    eax,5      ;if file not found - eax=5
473
        xor    ebx,ebx
474
        dec    ebx    ;ebx=0xffffffff and zf=0
475
     rd_ff:
476
        ret
477
 
478
  rd_getfileinfo:
479
     ;get date, time, size or attributes of file
480
     ;IN: eax - pointer to file, ebx - type of function: 12-get filesize, 13-get fileattr, 14-get filedate
481
     ;ecx - filelengh 0=root
482
     ;OUT: eax=0 - Ok or 5 - file not found ebx - date/time, size or attributes
483
        test   ecx,ecx
484
        jnz    no_getfinfo_root
485
        mov    eax,5      ;if root - fnf
486
        xor    ebx,ebx
487
        dec    ebx
488
        ret
489
    no_getfinfo_root:     ;if not root
490
        sub    esp,32
491
        call   expand_filename
492
        call   rd_findfile
493
        je     fifoundi
494
        add    esp,32      ;if file not found
495
        ret
496
    fifoundi:
497
        cmp    ebx,13
498
        jne    no_rd_attr
499
        movzx ebx,byte [edi]    ;get attributes
500
        jmp    rd_getfileinfo_end
501
     no_rd_attr:
502
        cmp    ebx,14
503
        jne    no_rd_date
504
        mov    ebx,dword [edi+11] ;get date/time
505
        jmp    rd_getfileinfo_end
506
     no_rd_date:
507
        mov    ebx,dword [edi+17] ;get size
508
     rd_getfileinfo_end:
509
        xor    eax,eax
510
        add    esp,32
71 diamond 511
        ret
512
 
513
; \begin{diamond}
514
 
515
uni2ansi_str:
516
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
517
; in: esi->source, edi->buffer (may be esi=edi)
518
; destroys: eax,esi,edi
519
	lodsw
520
	test	ax, ax
521
	jz	.done
522
	cmp	ax, 0x80
523
	jb	.ascii
524
	cmp	ax, 0x401
525
	jz	.yo1
526
	cmp	ax, 0x451
527
	jz	.yo2
528
	cmp	ax, 0x410
529
	jb	.unk
530
	cmp	ax, 0x440
531
	jb	.rus1
532
	cmp	ax, 0x450
533
	jb	.rus2
534
.unk:
535
	mov	al, '_'
536
	jmp	.doit
537
.yo1:
538
	mov	al, 'ð'
539
	jmp	.doit
540
.yo2:
541
	mov	al, 'ñ'
542
	jmp	.doit
543
.rus1:
544
; 0x410-0x43F -> 0x80-0xAF
545
	add	al, 0x70
546
	jmp	.doit
547
.rus2:
75 diamond 548
; 0x440-0x44F -> 0xE0-0xEF
71 diamond 549
	add	al, 0xA0
550
.ascii:
551
.doit:
552
	stosb
553
	jmp	uni2ansi_str
554
.done:
555
	mov	byte [edi], 0
556
	ret
557
 
75 diamond 558
ansi2uni_char:
559
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
560
        mov     ah, 0
561
; 0x00-0x7F - trivial map
562
        cmp     al, 0x80
563
        jb      .ret
564
; 0x80-0xAF -> 0x410-0x43F
565
        cmp     al, 0xB0
566
        jae     @f
567
        add     ax, 0x410-0x80
568
.ret:
569
        ret
570
@@:
571
; 0xE0-0xEF -> 0x440-0x44F
572
        cmp     al, 0xE0
573
        jb      .unk
574
        cmp     al, 0xF0
575
        jae     @f
576
        add     ax, 0x440-0xE0
577
        ret
578
; 0xF0 -> 0x401
579
; 0xF1 -> 0x451
580
@@:
581
        cmp     al, 'ð'
582
        jz      .yo1
583
        cmp     al, 'ñ'
584
        jz      .yo2
585
.unk:
586
        mov     al, '_'         ; ah=0
587
        ret
588
.yo1:
589
        mov     ax, 0x401
590
        ret
591
.yo2:
592
        mov     ax, 0x451
593
        ret
594
 
71 diamond 595
char_toupper:
596
; convert character to uppercase, using cp866 encoding
597
; in: al=symbol
598
; out: al=converted symbol
599
	cmp	al, 'a'
600
	jb	.ret
601
	cmp	al, 'z'
602
	jbe	.az
603
	cmp	al, ' '
604
	jb	.ret
605
	cmp	al, 'à'
606
	jb	.rus1
607
	cmp	al, 'ï'
608
	ja	.ret
609
; 0xE0-0xEF -> 0x90-0x9F
610
	sub	al, 'à'-''
611
.ret:
612
	ret
613
.rus1:
614
; 0xA0-0xAF -> 0x80-0x8F
615
.az:
616
	and	al, not 0x20
617
	ret
618
 
619
fat_get_name:
620
; in: edi->FAT entry
621
; out: CF=1 - no valid entry
622
; else CF=0 and ebp->ASCIIZ-name
623
; (maximum length of filename is 255 (wide) symbols without trailing 0,
624
;  but implementation requires buffer 261 words)
625
; destroys eax
626
	cmp	byte [edi], 0
627
	jz	.no
628
	cmp	byte [edi], 0xE5
629
	jnz	@f
630
.no:
631
	stc
632
	ret
633
@@:
634
	cmp	byte [edi+11], 0xF
635
	jz	.longname
636
	push	ecx
637
	mov	ecx, 8
75 diamond 638
        push	edi ebp ecx
78 diamond 639
        test    byte [ebp-4], 1
75 diamond 640
        jnz     .unicode_short
71 diamond 641
@@:
642
	mov	al, [edi]
643
	inc	edi
644
	mov	[ebp], al
645
	inc	ebp
646
	loop	@b
647
	pop	ecx
648
@@:
649
	cmp	byte [ebp-1], ' '
650
	jnz	@f
651
	dec	ebp
652
	loop	@b
653
@@:
654
	mov	byte [ebp], '.'
655
	inc	ebp
656
	mov	ecx, 3
657
	push	ecx
658
@@:
659
	mov	al, [edi]
660
	inc	edi
661
	mov	[ebp], al
662
	inc	ebp
663
	loop	@b
664
	pop	ecx
665
@@:
666
	cmp	byte [ebp-1], ' '
667
	jnz	@f
668
	dec	ebp
669
	loop	@b
670
	dec	ebp
671
@@:
672
	and	byte [ebp], 0	; CF=0
673
	pop	ebp edi ecx
674
	ret
75 diamond 675
.unicode_short:
676
@@:
677
        mov     al, [edi]
678
        inc     edi
679
        call    ansi2uni_char
680
        mov     [ebp], ax
681
        inc     ebp
682
        inc     ebp
683
        loop    @b
684
        pop     ecx
685
@@:
686
	cmp	word [ebp-2], ' '
687
	jnz	@f
688
	dec	ebp
689
	dec     ebp
690
	loop	@b
691
@@:
692
	mov	word [ebp], '.'
693
	inc	ebp
694
	inc     ebp
695
	mov	ecx, 3
696
	push	ecx
697
@@:
698
	mov	al, [edi]
699
	inc	edi
700
	call    ansi2uni_char
701
	mov	[ebp], ax
702
        inc     ebp
703
        inc     ebp
704
        loop    @b
705
        pop     ecx
706
@@:
707
	cmp	word [ebp-2], ' '
708
	jnz	@f
709
	dec	ebp
710
	dec     ebp
711
	loop	@b
712
	dec	ebp
713
	dec     ebp
714
@@:
715
	and	word [ebp], 0	; CF=0
716
	pop	ebp edi ecx
717
	ret
71 diamond 718
.longname:
719
; LFN
720
	mov	al, byte [edi]
721
	and	eax, 0x3F
722
	dec	eax
723
	cmp	al, 20
724
	jae	.no	; ignore invalid entries
725
	mov	word [ebp+260*2], 0	; force null-terminating for orphans
726
	imul	eax, 13*2
727
	add	ebp, eax
728
	test	byte [edi], 0x40
729
	jz	@f
730
	mov	word [ebp+13*2], 0
731
@@:
732
	push	eax
733
; now copy name from edi to ebp ...
734
	mov	eax, [edi+1]
735
	mov	[ebp], eax	; symbols 1,2
736
	mov	eax, [edi+5]
737
	mov	[ebp+4], eax	; 3,4
738
	mov	eax, [edi+9]
739
	mov	[ebp+8], ax	; 5
740
	mov	eax, [edi+14]
741
	mov	[ebp+10], eax	; 6,7
742
	mov	eax, [edi+18]
743
	mov	[ebp+14], eax	; 8,9
744
	mov	eax, [edi+22]
745
	mov	[ebp+18], eax	; 10,11
746
	mov	eax, [edi+28]
747
	mov	[ebp+22], eax	; 12,13
748
; ... done
749
	pop	eax
750
	sub	ebp, eax
751
	test	eax, eax
752
	jz	@f
753
; if this is not first entry, more processing required
754
	stc
755
	ret
756
@@:
757
; if this is first entry:
78 diamond 758
        test    byte [ebp-4], 1
75 diamond 759
        jnz     .ret
71 diamond 760
; buffer at ebp contains UNICODE name, convert it to ANSI
761
	push	esi edi
762
	mov	esi, ebp
763
	mov	edi, ebp
764
	call	uni2ansi_str
765
	pop	edi esi
75 diamond 766
.ret:
71 diamond 767
	clc
768
	ret
769
 
770
fat_compare_name:
771
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
772
; in: esi->name, ebp->name
773
; out: if names match: ZF=1 and esi->next component of name
774
;      else: ZF=0, esi is not changed
775
; destroys eax
776
	push	ebp esi
777
.loop:
778
	mov	al, [ebp]
779
	inc	ebp
780
	call	char_toupper
781
	push	eax
782
	lodsb
783
	call	char_toupper
784
	cmp	al, [esp]
785
	jnz	.done
786
	pop	eax
787
	test	al, al
788
	jnz	.loop
789
	dec	esi
790
	pop	eax
791
	pop	ebp
792
	xor	eax, eax	; set ZF flag
793
	ret
794
.done:
795
	cmp	al, '/'
796
	jnz	@f
797
	cmp	byte [esp], 0
798
	jnz	@f
799
	mov	[esp+4], esi
800
@@:
801
	pop	eax
802
	pop	esi ebp
803
	ret
804
 
75 diamond 805
fat_time_to_bdfe:
806
; in: eax=FAT time
807
; out: eax=BDFE time
808
	push	ecx edx
809
	mov	ecx, eax
810
	mov	edx, eax
811
	shr	eax, 11
812
	shl	eax, 16	; hours
813
	and	edx, 0x1F
814
	add	edx, edx
815
	mov	al, dl	; seconds
816
	shr	ecx, 5
817
	and	ecx, 0x3F
818
	mov	ah, cl	; minutes
819
	pop	edx ecx
820
	ret
821
 
822
fat_date_to_bdfe:
823
	push	ecx edx
824
	mov	ecx, eax
825
	mov	edx, eax
826
	shr	eax, 9
827
	add	ax, 1980
828
	shl	eax, 16	; year
829
	and	edx, 0x1F
830
	mov	al, dl	; day
831
	shr	ecx, 5
832
	and	ecx, 0xF
833
	mov	ah, cl	; month
834
	pop	edx ecx
835
	ret
836
 
837
fat_entry_to_bdfe:
838
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
839
; destroys eax
840
        movzx   eax, byte [edi+11]
841
        mov     [esi], eax	; attributes
842
        mov     eax, [ebp-4]
843
        mov     [esi+4], eax	; ASCII/UNICODE name
844
        movzx   eax, word [edi+14]
845
        call    fat_time_to_bdfe
846
        mov     [esi+8], eax	; creation time
847
        movzx   eax, word [edi+16]
848
        call    fat_date_to_bdfe
849
        mov     [esi+12], eax	; creation date
850
        and     dword [esi+16], 0	; last access time is not supported on FAT
851
        movzx   eax, word [edi+18]
852
        call    fat_date_to_bdfe
853
        mov     [esi+20], eax	; last access date
854
        movzx   eax, word [edi+22]
855
        call    fat_time_to_bdfe
856
        mov     [esi+24], eax	; last write time
857
        movzx   eax, word [edi+24]
858
        call    fat_date_to_bdfe
859
        mov     [esi+28], eax	; last write date
860
        mov     eax, [edi+28]
861
        mov     [esi+32], eax	; file size (low dword)
862
        xor     eax, eax
863
        mov     [esi+36], eax	; file size (high dword)
864
        push    ecx edi
865
        lea     edi, [esi+40]
866
        mov     esi, ebp
78 diamond 867
        test    byte [esi-4], 1
868
        jz      .ansi
869
        mov     ecx, 260/2
75 diamond 870
        rep     movsd
78 diamond 871
        mov     [edi-2], ax
872
@@:
75 diamond 873
        mov     esi, edi
874
        pop     edi ecx
875
        ret
78 diamond 876
.ansi:
877
        mov     ecx, 264/4
878
        rep     movsd
879
        mov     [edi-1], al
880
        jmp     @b
75 diamond 881
 
71 diamond 882
rd_find_lfn:
883
; in: esi->name
884
; out: CF=1 - file not found
885
;      else CF=0 and edi->direntry
78 diamond 886
        push    esi ebp edi
887
        sub     esp, 262*2      ; allocate space for LFN
888
        mov     ebp, esp        ; ebp points to buffer
889
        push    0               ; for fat_get_name: read ASCII name
890
        mov     edi, 0x100000+512*19    ; to root dir
71 diamond 891
.l1:
78 diamond 892
        call    fat_get_name
893
        jc      .l2
894
        call    fat_compare_name
895
        jz      .found
71 diamond 896
.l2:
78 diamond 897
        add     edi, 0x20
898
        cmp     edi, 0x100000+512*33
899
        jb      .l1
71 diamond 900
.notfound:
78 diamond 901
        add     esp, 262*2+4
902
        pop     edi ebp esi
903
        stc
904
        ret
71 diamond 905
.found:
906
; found
907
; if this is LFN entry, advance to true entry
78 diamond 908
        cmp     byte [edi+11], 0xF
909
        jnz     @f
910
        add     edi, 0x20
71 diamond 911
@@:
912
; folders are not supported
78 diamond 913
        cmp     byte [esi], 0
914
        jnz     .notfound
915
        add     esp, 262*2+4+4  ; CF=0
916
        pop     ebp esi
917
        ret
71 diamond 918
 
919
;----------------------------------------------------------------
920
;
921
;  fs_RamdiskRead - LFN variant for reading sys floppy
922
;
923
;  esi  points to filename
924
;  ebx  pointer to 64-bit number = first wanted byte, 0+
925
;       may be ebx=0 - start from first byte
926
;  ecx  number of bytes to read, 0+
927
;  edx  mem location to return data
928
;
77 diamond 929
;  ret ebx = bytes read or 0xffffffff file not found
71 diamond 930
;      eax = 0 ok read or other = errormsg
931
;
932
;--------------------------------------------------------------
933
fs_RamdiskRead:
75 diamond 934
        cmp     byte [esi], 0
935
        jnz     @f
936
        or      ebx, -1
937
        mov     eax, 10         ; access denied
938
        ret
71 diamond 939
@@:
75 diamond 940
        push    edi
941
        call    rd_find_lfn
942
        jnc     .found
943
        pop     edi
944
        or      ebx, -1
945
        mov     eax, 5          ; file not found
946
        ret
71 diamond 947
.found:
75 diamond 948
        test    ebx, ebx
949
        jz      .l1
950
        cmp     dword [ebx+4], 0
951
        jz      @f
77 diamond 952
        xor     ebx, ebx
71 diamond 953
.reteof:
75 diamond 954
        mov     eax, 6          ; EOF
955
        pop     edi
956
        ret
71 diamond 957
@@:
75 diamond 958
        mov     ebx, [ebx]
71 diamond 959
.l1:
77 diamond 960
        push    ecx edx
961
        push    0
962
        mov     eax, [edi+28]
963
        sub     eax, ebx
964
        jb      .eof
965
        cmp     eax, ecx
966
        jae     @f
967
        mov     ecx, eax
968
        mov     byte [esp], 6           ; EOF
969
@@:
75 diamond 970
        movzx   edi, word [edi+26]	; cluster
71 diamond 971
.new:
75 diamond 972
        jecxz   .done
973
        test    edi, edi
974
        jz      .eof
975
        cmp     edi, 0xFF8
976
        jae     .eof
977
        lea     eax, [edi+31]           ; bootsector+2*fat+filenames
978
        shl     eax, 9                  ; *512
979
        add     eax, 0x100000           ; image base
71 diamond 980
; now eax points to data of cluster
75 diamond 981
        sub     ebx, 512
982
        jae     .skip
983
        lea     eax, [eax+ebx+512]
984
        neg     ebx
985
        push    ecx
986
        cmp     ecx, ebx
987
        jbe     @f
988
        mov     ecx, ebx
71 diamond 989
@@:
75 diamond 990
        mov     ebx, edx
991
        call    memmove
992
        add     edx, ecx
993
        sub     [esp], ecx
994
        pop     ecx
995
        xor     ebx, ebx
71 diamond 996
.skip:
75 diamond 997
        movzx   edi, word [edi*2+0x280000]      ; find next cluster from FAT
998
        jmp     .new
71 diamond 999
.eof:
77 diamond 1000
        mov     ebx, edx
1001
        pop     eax edx ecx
1002
        sub     ebx, edx
75 diamond 1003
        jmp     .reteof
71 diamond 1004
.done:
77 diamond 1005
        mov     ebx, edx
1006
        pop     eax edx ecx edi
1007
        sub     ebx, edx
75 diamond 1008
        ret
71 diamond 1009
 
75 diamond 1010
;----------------------------------------------------------------
1011
;
1012
;  fs_RamdiskReadFolder - LFN variant for reading sys floppy folder
1013
;
1014
;  esi  points to filename; only root is folder on ramdisk
78 diamond 1015
;  ebx  pointer to structure 32-bit number = first wanted block
1016
;                          & flags (bitfields)
1017
; flags: bit 0: 0=ANSI names, 1=UNICODE names
75 diamond 1018
;  ecx  number of blocks to read, 0+
1019
;  edx  mem location to return data
1020
;
1021
;  ret ebx = size or 0xffffffff file not found
1022
;      eax = 0 ok read or other = errormsg
1023
;
1024
;--------------------------------------------------------------
1025
fs_RamdiskReadFolder:
1026
        cmp     byte [esi], 0
1027
        jz      @f
1028
; ramdisk doesn't support folders
1029
        mov     eax, ERROR_ACCESS_DENIED
1030
        or      ebx, -1
1031
        ret
1032
@@:
1033
        push    esi edi ecx
1034
; init header
1035
        push    ecx
1036
        mov     edi, edx
1037
        mov     ecx, 32/4
1038
        xor     eax, eax
1039
        rep     stosd
1040
        mov     byte [edx], 1   ; version
1041
        pop     ecx
1042
        push    ebp
1043
        sub     esp, 262*2      ; allocate space for LFN
1044
        mov     ebp, esp
78 diamond 1045
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE name
1046
        mov     ebx, [ebx]
75 diamond 1047
; read root
1048
        mov     esi, edi        ; esi points to block of data of folder entry (BDFE)
1049
        mov     edi, 0x100000+512*19
1050
.l1:
1051
        call    fat_get_name
1052
        jc      .l2
1053
        cmp     byte [edi+11], 0xF
1054
        jnz     @f
1055
        add     edi, 0x20
1056
@@:
1057
        inc     dword [edx+8]   ; new file found
1058
        dec     ebx
1059
        jns     .l2
1060
        dec     ecx
1061
        js      .l2
1062
        inc     dword [edx+4]  ; new file block copied
1063
        call    fat_entry_to_bdfe
1064
.l2:
1065
        add     edi, 0x20
1066
        cmp     edi, 0x100000+512*33
1067
        jb      .l1
1068
        add     esp, 262*2+4
1069
        pop     ebp
77 diamond 1070
        mov     ebx, [edx+4]
75 diamond 1071
        xor     eax, eax
1072
        dec     ecx
1073
        js      @f
1074
        mov     al, ERROR_END_OF_FILE
1075
@@:
1076
        pop     ecx edi esi
1077
        ret
1078
 
78 diamond 1079
; \end{diamond}