Subversion Repositories Kolibri OS

Rev

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