Subversion Repositories Kolibri OS

Rev

Rev 86 | Rev 91 | 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                                                 ;;
83 diamond 6
;; LFN support by diamond                                               ;;
1 ha 7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
 
5 halyavin 9
; calculate fat chain
1 ha 10
 
5 halyavin 11
calculatefatchain:
12
 
13
   pushad
14
 
15
   mov  esi,0x100000+512
16
   mov  edi,0x280000
17
 
18
 fcnew:
19
   mov  eax,dword [esi]
20
   mov  ebx,dword [esi+4]
21
   mov  ecx,dword [esi+8]
22
   mov  edx,ecx
23
   shr  edx,4   ;8 ok
24
   shr  dx,4    ;7 ok
25
   xor  ch,ch
26
   shld ecx,ebx,20 ;6 ok
27
   shr  cx,4     ;5 ok
28
   shld ebx,eax,12
29
   and  ebx,0x0fffffff  ;4 ok
30
   shr  bx,4    ;3 ok
31
   shl  eax,4
32
   and  eax,0x0fffffff  ;2 ok
33
   shr  ax,4  ;1 ok
78 diamond 34
   mov  dword [edi],eax
35
   mov  dword [edi+4],ebx
36
   mov  dword [edi+8],ecx
37
   mov  dword [edi+12],edx
38
   add  edi,16
5 halyavin 39
   add  esi,12
40
 
41
   cmp  edi,0x280000+2856*2   ;2849 clusters
42
   jnz  fcnew
43
 
44
   popad
45
   ret
46
 
47
 
48
restorefatchain:   ; restore fat chain
49
 
50
   pushad
51
 
52
   mov  esi,0x280000
53
   mov  edi,0x100000+512
54
 
55
  fcnew2:
56
   mov  eax,dword [esi]
57
   mov  ebx,dword [esi+4]
58
   shl  ax,4
59
   shl  eax,4
60
   shl  bx,4
61
   shr  ebx,4
62
   shrd eax,ebx,8
63
   shr  ebx,8
78 diamond 64
   mov  dword [edi],eax
65
   mov  word [edi+4],bx
66
   add  edi,6
5 halyavin 67
   add  esi,8
68
 
69
   cmp  edi,0x100000+512+4278     ;4274 bytes - all used FAT
70
   jb   fcnew2
71
 
72
   mov  esi,0x100000+512           ; duplicate fat chain
73
   mov  edi,0x100000+512+0x1200
74
   mov  ecx,1069        ;4274/4
75
   cld
76
   rep  movsd
77
 
78
   popad
79
   ret
80
 
81
 
1 ha 82
ramdisk_free_space:
83
;---------------------------------------------
84
;
85
; returns free space in edi
86
; rewr.by Mihasik
87
;---------------------------------------------
88
 
89
        push   eax ebx ecx
90
 
91
        mov  edi,0x280000 ;start of FAT
92
        xor  ax,ax    ;Free cluster=0x0000 in FAT
93
        xor  ebx,ebx  ;counter
5 halyavin 94
        mov  ecx,2849 ;2849 clusters
1 ha 95
        cld
96
    rdfs1:
97
        repne scasw
98
        jnz  rdfs2    ;if last cluster not 0
99
        inc  ebx
78 diamond 100
        test    ecx, ecx
101
        jnz     rdfs1
1 ha 102
    rdfs2:
103
        shl  ebx,9    ;free clusters*512
104
        mov  edi,ebx
105
 
106
        pop    ecx ebx eax
107
        ret
108
 
109
 
110
expand_filename:
111
;---------------------------------------------
112
;
113
; exapand filename with '.' to 11 character
114
; eax - pointer to filename
115
;---------------------------------------------
116
 
117
        push esi edi ebx
118
 
119
        mov  edi,esp                  ; check for '.' in the name
120
        add  edi,12+8
121
 
122
        mov  esi,eax
123
 
124
        mov  eax,edi
125
        mov  [eax+0],dword '    '
126
        mov  [eax+4],dword '    '
127
        mov  [eax+8],dword '    '
128
 
129
      flr1:
130
 
131
        cmp  [esi],byte '.'
132
        jne  flr2
133
        mov  edi,eax
134
        add  edi,7
135
        jmp  flr3
136
 
137
      flr2:
138
 
139
        mov  bl,[esi]
140
        mov  [edi],bl
141
 
142
      flr3:
143
 
144
        inc  esi
145
        inc  edi
146
 
147
        mov  ebx,eax
148
        add  ebx,11
149
 
150
        cmp  edi,ebx
151
        jbe  flr1
152
 
153
        pop  ebx edi esi
154
        ret
155
 
156
fileread:
157
;----------------------------------------------------------------
158
;
159
;  fileread - sys floppy
160
;
161
;  eax  points to filename 11 chars
162
;  ebx  first wanted block       ; 1+ ; if 0 then set to 1
163
;  ecx  number of blocks to read ; 1+ ; if 0 then set to 1
164
;  edx  mem location to return data
165
;  esi  length of filename 12*X 0=root
166
;
167
;  ret ebx = size or 0xffffffff file not found
168
;      eax = 0 ok read or other = errormsg
169
;
170
;--------------------------------------------------------------
171
        test   ebx,ebx ;if ebx=0 - set to 1
172
        jnz    frfl5
173
        inc    ebx
174
      frfl5:
175
        test   ecx,ecx ;if ecx=0 - set to 1
176
        jnz    frfl6
177
        inc    ecx
178
      frfl6:
179
        test   esi,esi          ; return ramdisk root
180
        jnz    fr_noroot        ;if not root
181
        cmp    ebx,14           ;14 clusters=root dir
182
        ja     oorr
183
        cmp    ecx,14
184
        ja     oorr
185
        jmp    fr_do
186
      oorr:
187
        mov    eax,5            ;out of root range (fnf)
188
        xor    ebx,ebx
189
        dec    ebx              ;0xffffffff
190
        ret
191
 
192
      fr_do:                    ;reading rootdir
193
        mov    edi,edx
194
        dec    ebx
195
        push   edx
196
        mov    edx,ecx
197
        add    edx,ebx
5 halyavin 198
        cmp    edx,15     ;ebx+ecx=14+1
1 ha 199
        pushf
200
        jbe    fr_do1
201
        sub    edx,14
202
        sub    ecx,edx
203
      fr_do1:
204
        shl    ebx,9
205
        mov    esi,0x100000+512*19
206
        add    esi,ebx
207
        shl    ecx,7
208
        cld
209
        rep    movsd
210
        popf
211
        pop    edx
5 halyavin 212
        jae    fr_do2
1 ha 213
        xor    eax,eax ; ok read
214
        xor    ebx,ebx
215
        ret
216
      fr_do2:        ;if last cluster
217
        mov    eax,6  ;end of file
218
        xor    ebx,ebx
219
        ret
220
 
221
     fr_noroot:
222
 
223
        sub    esp,32
224
        call   expand_filename
225
 
226
        dec    ebx
227
 
228
        push   eax
229
 
230
        push   eax ebx ecx edx esi edi
231
        call   rd_findfile
232
        je     fifound
233
        add    esp,32+28   ;if file not found
234
        ret
235
 
236
     fifound:
237
 
238
        mov    ebx,[edi-11+28]          ;file size
239
        mov    [esp+20],ebx
240
        mov    [esp+24],ebx
241
        add    edi,0xf
242
        movzx  eax,word [edi]
243
        mov    edi,eax                  ;edi=cluster
244
 
245
      frnew:
246
 
247
        add    eax,31                   ;bootsector+2*fat+filenames
248
        shl    eax,9                    ;*512
249
        add    eax,0x100000             ;image base
250
        mov    ebx,[esp+8]
251
        mov    ecx,512                  ;[esp+4]
252
 
253
        cmp    [esp+16],dword 0         ; wanted cluster ?
254
        jne    frfl7
255
        call   memmove
256
        add    [esp+8],dword 512
257
        dec    dword [esp+12]           ; last wanted cluster ?
258
        je     frnoread
259
        jmp    frfl8
260
      frfl7:
261
        dec    dword [esp+16]
262
      frfl8:
71 diamond 263
        movzx  eax,word [edi*2+0x280000]	; find next cluster from FAT
1 ha 264
        mov    edi,eax
265
        cmp    edi,4095                 ;eof  - cluster
266
        jz     frnoread2
267
 
268
        cmp    [esp+24],dword 512       ;eof  - size
269
        jb     frnoread
270
        sub    [esp+24],dword 512
271
 
272
        jmp    frnew
273
 
274
      frnoread2:
275
 
276
        cmp    [esp+16],dword 0         ; eof without read ?
277
        je     frnoread
278
 
279
        pop    edi esi edx ecx
280
        add    esp,4
281
        pop    ebx     ; ebx <- eax : size of file
282
        add    esp,36
283
        mov    eax,6   ; end of file
284
        ret
285
 
286
      frnoread:
287
 
288
        pop    edi esi edx ecx
289
        add    esp,4
290
        pop    ebx     ; ebx <- eax : size of file
291
        add    esp,36
292
        xor    eax,eax  ;read ok
293
        ret
294
 
295
filedelete:
296
;--------------------------------------------
297
;
298
; filedelete - sys floppy
299
; in:
300
; eax -  pointer to filename 11 chars
301
;
302
; out:
303
; eax - 0 = successful, 5 = file not found
304
;
305
;--------------------------------------------
306
 
307
        sub    esp,32
308
        call   expand_filename
309
 
310
        push   eax ebx ecx edx esi edi
311
 
312
        call   rd_findfile
313
        je     fifoundd
314
        pop    edi esi edx ecx ebx eax ;file not found
315
        add    esp,32
316
        mov    eax,5
317
        ret
318
 
319
     fifoundd:
320
 
321
        mov    [edi-11],byte 0xE5       ;mark filename deleted
322
        add    edi,0xf
323
        movzx  eax,word [edi]
324
        mov    edi,eax                  ;edi = cluster
325
 
326
      frnewd:
327
 
328
        shl    edi,1                    ;find next cluster from FAT
329
        add    edi,0x280000
330
        movzx  eax,word [edi]
331
        mov    [edi],word 0x0           ;clear fat chain cluster
332
        mov    edi,eax
333
        cmp    edi,dword 0xff8          ;last cluster ?
334
        jb     frnewd
335
 
336
        pop    edi esi edx ecx ebx eax
337
        add    esp,32
338
        xor    eax,eax       ; file found
339
        ret
340
 
341
 
342
 
343
filesave:
344
;----------------------------------------------------------
345
;
346
; filesave - sys floppy
347
;
348
; eax points to filename 11 chars
349
;
350
;        eax      ; pointer to file name
351
;        ebx      ; buffer
352
;        ecx      ; count to write in bytes
353
;        edx      ; 0 create new , 1 append
354
;
355
;-----------------------------------------------------------
356
 
357
        sub  esp,32
358
        call expand_filename
359
        test edx,edx
360
        jnz  fsdel
361
        pusha
362
        call filedelete
363
        popa
364
 
365
      fsdel:
366
 
367
        call   ramdisk_free_space
368
        cmp    ecx,edi
369
        jbe    rd_do_save
370
        add    esp,32
371
        mov    eax,8    ;disk full
372
        ret
373
 
374
      rd_do_save:
375
 
376
        push   eax ebx ecx edx esi edi
377
 
378
        mov    edi,0x100000+512*18+512  ;Point at directory
379
        mov    edx,224 +1
380
        ; find an empty spot for filename in the root dir
381
     l20ds:
382
        dec    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
 
71 diamond 478
; \begin{diamond}
479
 
480
uni2ansi_str:
481
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
482
; in: esi->source, edi->buffer (may be esi=edi)
483
; destroys: eax,esi,edi
83 diamond 484
        lodsw
485
        test    ax, ax
486
        jz      .done
487
        cmp     ax, 0x80
488
        jb      .ascii
489
        cmp     ax, 0x401
490
        jz      .yo1
491
        cmp     ax, 0x451
492
        jz      .yo2
493
        cmp     ax, 0x410
494
        jb      .unk
495
        cmp     ax, 0x440
496
        jb      .rus1
497
        cmp     ax, 0x450
498
        jb      .rus2
71 diamond 499
.unk:
83 diamond 500
        mov     al, '_'
501
        jmp     .doit
71 diamond 502
.yo1:
83 diamond 503
        mov     al, 'ð'
504
        jmp     .doit
71 diamond 505
.yo2:
83 diamond 506
        mov     al, 'ñ'
507
        jmp     .doit
71 diamond 508
.rus1:
509
; 0x410-0x43F -> 0x80-0xAF
83 diamond 510
        add     al, 0x70
511
        jmp     .doit
71 diamond 512
.rus2:
75 diamond 513
; 0x440-0x44F -> 0xE0-0xEF
83 diamond 514
        add     al, 0xA0
71 diamond 515
.ascii:
516
.doit:
83 diamond 517
        stosb
518
        jmp     uni2ansi_str
71 diamond 519
.done:
83 diamond 520
        mov     byte [edi], 0
521
        ret
71 diamond 522
 
75 diamond 523
ansi2uni_char:
524
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
525
        mov     ah, 0
526
; 0x00-0x7F - trivial map
527
        cmp     al, 0x80
528
        jb      .ret
529
; 0x80-0xAF -> 0x410-0x43F
530
        cmp     al, 0xB0
531
        jae     @f
532
        add     ax, 0x410-0x80
533
.ret:
534
        ret
535
@@:
536
; 0xE0-0xEF -> 0x440-0x44F
537
        cmp     al, 0xE0
538
        jb      .unk
539
        cmp     al, 0xF0
540
        jae     @f
541
        add     ax, 0x440-0xE0
542
        ret
543
; 0xF0 -> 0x401
544
; 0xF1 -> 0x451
545
@@:
546
        cmp     al, 'ð'
547
        jz      .yo1
548
        cmp     al, 'ñ'
549
        jz      .yo2
550
.unk:
551
        mov     al, '_'         ; ah=0
552
        ret
553
.yo1:
554
        mov     ax, 0x401
555
        ret
556
.yo2:
557
        mov     ax, 0x451
558
        ret
559
 
71 diamond 560
char_toupper:
561
; convert character to uppercase, using cp866 encoding
562
; in: al=symbol
563
; out: al=converted symbol
83 diamond 564
        cmp     al, 'a'
565
        jb      .ret
566
        cmp     al, 'z'
567
        jbe     .az
568
        cmp     al, ' '
569
        jb      .ret
570
        cmp     al, 'à'
571
        jb      .rus1
572
        cmp     al, 'ï'
573
        ja      .ret
71 diamond 574
; 0xE0-0xEF -> 0x90-0x9F
83 diamond 575
        sub     al, 'à'-''
71 diamond 576
.ret:
83 diamond 577
        ret
71 diamond 578
.rus1:
579
; 0xA0-0xAF -> 0x80-0x8F
580
.az:
83 diamond 581
        and     al, not 0x20
582
        ret
71 diamond 583
 
584
fat_get_name:
585
; in: edi->FAT entry
586
; out: CF=1 - no valid entry
587
; else CF=0 and ebp->ASCIIZ-name
588
; (maximum length of filename is 255 (wide) symbols without trailing 0,
589
;  but implementation requires buffer 261 words)
590
; destroys eax
83 diamond 591
        cmp     byte [edi], 0
592
        jz      .no
593
        cmp     byte [edi], 0xE5
594
        jnz     @f
71 diamond 595
.no:
83 diamond 596
        stc
597
        ret
71 diamond 598
@@:
83 diamond 599
        cmp     byte [edi+11], 0xF
600
        jz      .longname
601
        push    ecx
602
        mov     ecx, 8
603
        push    edi ebp ecx
78 diamond 604
        test    byte [ebp-4], 1
75 diamond 605
        jnz     .unicode_short
71 diamond 606
@@:
83 diamond 607
        mov     al, [edi]
608
        inc     edi
609
        mov     [ebp], al
610
        inc     ebp
611
        loop    @b
612
        pop     ecx
71 diamond 613
@@:
83 diamond 614
        cmp     byte [ebp-1], ' '
615
        jnz     @f
616
        dec     ebp
617
        loop    @b
71 diamond 618
@@:
83 diamond 619
        mov     byte [ebp], '.'
620
        inc     ebp
621
        mov     ecx, 3
622
        push    ecx
71 diamond 623
@@:
83 diamond 624
        mov     al, [edi]
625
        inc     edi
626
        mov     [ebp], al
627
        inc     ebp
628
        loop    @b
629
        pop     ecx
71 diamond 630
@@:
83 diamond 631
        cmp     byte [ebp-1], ' '
632
        jnz     @f
633
        dec     ebp
634
        loop    @b
635
        dec     ebp
71 diamond 636
@@:
83 diamond 637
        and     byte [ebp], 0	; CF=0
638
        pop     ebp edi ecx
639
        ret
75 diamond 640
.unicode_short:
641
@@:
642
        mov     al, [edi]
643
        inc     edi
644
        call    ansi2uni_char
645
        mov     [ebp], ax
646
        inc     ebp
647
        inc     ebp
648
        loop    @b
649
        pop     ecx
650
@@:
83 diamond 651
        cmp     word [ebp-2], ' '
652
        jnz     @f
653
        dec     ebp
654
        dec     ebp
655
        loop    @b
75 diamond 656
@@:
83 diamond 657
        mov     word [ebp], '.'
658
        inc     ebp
659
        inc     ebp
660
        mov     ecx, 3
661
        push    ecx
75 diamond 662
@@:
83 diamond 663
        mov     al, [edi]
664
        inc     edi
665
        call    ansi2uni_char
666
        mov     [ebp], ax
75 diamond 667
        inc     ebp
668
        inc     ebp
669
        loop    @b
670
        pop     ecx
671
@@:
83 diamond 672
        cmp     word [ebp-2], ' '
673
        jnz     @f
674
        dec     ebp
675
        dec     ebp
676
        loop    @b
677
        dec     ebp
678
        dec     ebp
75 diamond 679
@@:
83 diamond 680
        and     word [ebp], 0	; CF=0
681
        pop     ebp edi ecx
682
        ret
71 diamond 683
.longname:
684
; LFN
83 diamond 685
        mov     al, byte [edi]
686
        and     eax, 0x3F
687
        dec     eax
688
        cmp     al, 20
689
        jae     .no     ; ignore invalid entries
690
        mov     word [ebp+260*2], 0     ; force null-terminating for orphans
691
        imul    eax, 13*2
692
        add     ebp, eax
693
        test    byte [edi], 0x40
694
        jz      @f
695
        mov     word [ebp+13*2], 0
71 diamond 696
@@:
83 diamond 697
        push    eax
71 diamond 698
; now copy name from edi to ebp ...
83 diamond 699
        mov     eax, [edi+1]
700
        mov     [ebp], eax      ; symbols 1,2
701
        mov     eax, [edi+5]
702
        mov     [ebp+4], eax	; 3,4
703
        mov     eax, [edi+9]
704
        mov     [ebp+8], ax	; 5
705
        mov     eax, [edi+14]
706
        mov     [ebp+10], eax	; 6,7
707
        mov     eax, [edi+18]
708
        mov     [ebp+14], eax	; 8,9
709
        mov     eax, [edi+22]
710
        mov     [ebp+18], eax	; 10,11
711
        mov     eax, [edi+28]
712
        mov     [ebp+22], eax	; 12,13
71 diamond 713
; ... done
83 diamond 714
        pop     eax
715
        sub     ebp, eax
716
        test    eax, eax
717
        jz      @f
71 diamond 718
; if this is not first entry, more processing required
83 diamond 719
        stc
720
        ret
71 diamond 721
@@:
722
; if this is first entry:
78 diamond 723
        test    byte [ebp-4], 1
75 diamond 724
        jnz     .ret
71 diamond 725
; buffer at ebp contains UNICODE name, convert it to ANSI
83 diamond 726
        push    esi edi
727
        mov     esi, ebp
728
        mov     edi, ebp
729
        call    uni2ansi_str
730
        pop     edi esi
75 diamond 731
.ret:
83 diamond 732
        clc
733
        ret
71 diamond 734
 
735
fat_compare_name:
736
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
737
; in: esi->name, ebp->name
738
; out: if names match: ZF=1 and esi->next component of name
739
;      else: ZF=0, esi is not changed
740
; destroys eax
83 diamond 741
        push    ebp esi
71 diamond 742
.loop:
83 diamond 743
        mov     al, [ebp]
744
        inc     ebp
745
        call    char_toupper
746
        push    eax
747
        lodsb
748
        call    char_toupper
749
        cmp     al, [esp]
750
        jnz     .done
751
        pop     eax
752
        test    al, al
753
        jnz     .loop
754
        dec     esi
755
        pop     eax
756
        pop     ebp
757
        xor     eax, eax	; set ZF flag
758
        ret
71 diamond 759
.done:
83 diamond 760
        cmp     al, '/'
761
        jnz     @f
762
        cmp     byte [esp], 0
763
        jnz     @f
764
        mov     [esp+4], esi
71 diamond 765
@@:
83 diamond 766
        pop     eax
767
        pop     esi ebp
768
        ret
71 diamond 769
 
75 diamond 770
fat_time_to_bdfe:
771
; in: eax=FAT time
772
; out: eax=BDFE time
83 diamond 773
        push    ecx edx
774
        mov     ecx, eax
775
        mov     edx, eax
776
        shr     eax, 11
777
        shl     eax, 16	; hours
778
        and     edx, 0x1F
779
        add     edx, edx
780
        mov     al, dl	; seconds
781
        shr     ecx, 5
782
        and     ecx, 0x3F
783
        mov     ah, cl	; minutes
784
        pop     edx ecx
785
        ret
75 diamond 786
 
787
fat_date_to_bdfe:
83 diamond 788
        push    ecx edx
789
        mov     ecx, eax
790
        mov     edx, eax
791
        shr     eax, 9
792
        add     ax, 1980
793
        shl     eax, 16	; year
794
        and     edx, 0x1F
795
        mov     al, dl	; day
796
        shr     ecx, 5
797
        and     ecx, 0xF
798
        mov     ah, cl	; month
799
        pop     edx ecx
800
        ret
75 diamond 801
 
86 diamond 802
bdfe_to_fat_time:
803
        push    edx
804
        mov     edx, eax
805
        shr     eax, 16
806
        and     dh, 0x3F
807
        shl     eax, 6
808
        or      al, dh
809
        shr     dl, 1
810
        and     dl, 0x1F
811
        shl     eax, 5
812
        or      al, dl
813
        pop     edx
814
        ret
815
 
816
bdfe_to_fat_date:
817
        push    edx
818
        mov     edx, eax
819
        shr     eax, 16
820
        sub     ax, 1980
821
        and     dh, 0xF
822
        shl     eax, 4
823
        or      al, dh
824
        and     dl, 0x1F
825
        shl     eax, 5
826
        or      al, dl
827
        pop     edx
828
        ret
829
 
75 diamond 830
fat_entry_to_bdfe:
831
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
832
; destroys eax
86 diamond 833
        mov     eax, [ebp-4]
834
        mov     [esi+4], eax	; ASCII/UNICODE name
835
fat_entry_to_bdfe2:
75 diamond 836
        movzx   eax, byte [edi+11]
837
        mov     [esi], eax	; attributes
838
        movzx   eax, word [edi+14]
839
        call    fat_time_to_bdfe
840
        mov     [esi+8], eax	; creation time
841
        movzx   eax, word [edi+16]
842
        call    fat_date_to_bdfe
843
        mov     [esi+12], eax	; creation date
844
        and     dword [esi+16], 0	; last access time is not supported on FAT
845
        movzx   eax, word [edi+18]
846
        call    fat_date_to_bdfe
847
        mov     [esi+20], eax	; last access date
848
        movzx   eax, word [edi+22]
849
        call    fat_time_to_bdfe
850
        mov     [esi+24], eax	; last write time
851
        movzx   eax, word [edi+24]
852
        call    fat_date_to_bdfe
853
        mov     [esi+28], eax	; last write date
854
        mov     eax, [edi+28]
855
        mov     [esi+32], eax	; file size (low dword)
856
        xor     eax, eax
857
        mov     [esi+36], eax	; file size (high dword)
86 diamond 858
        test    ebp, ebp
859
        jz      .ret
75 diamond 860
        push    ecx edi
861
        lea     edi, [esi+40]
862
        mov     esi, ebp
78 diamond 863
        test    byte [esi-4], 1
864
        jz      .ansi
865
        mov     ecx, 260/2
75 diamond 866
        rep     movsd
78 diamond 867
        mov     [edi-2], ax
868
@@:
75 diamond 869
        mov     esi, edi
870
        pop     edi ecx
86 diamond 871
.ret:
75 diamond 872
        ret
78 diamond 873
.ansi:
874
        mov     ecx, 264/4
875
        rep     movsd
876
        mov     [edi-1], al
877
        jmp     @b
75 diamond 878
 
86 diamond 879
bdfe_to_fat_entry:
880
; convert BDFE at edx to FAT entry at edi
881
; destroys eax
882
; attributes byte
883
        test    byte [edi+11], 8        ; volume label?
884
        jnz     @f
885
        mov     al, [edx]
886
        and     al, 0x27
887
        and     byte [edi+11], 0x10
888
        or      byte [edi+11], al
889
@@:
890
        mov     eax, [edx+8]
891
        call    bdfe_to_fat_time
892
        mov     [edi+14], ax            ; creation time
893
        mov     eax, [edx+12]
894
        call    bdfe_to_fat_date
895
        mov     [edi+16], ax            ; creation date
896
        mov     eax, [edx+20]
897
        call    bdfe_to_fat_date
898
        mov     [edi+18], ax            ; last access date
899
        mov     eax, [edx+24]
900
        call    bdfe_to_fat_time
901
        mov     [edi+22], ax            ; last write time
902
        mov     eax, [edx+28]
903
        call    bdfe_to_fat_date
904
        mov     [edi+24], ax            ; last write date
905
        ret
906
 
907
ramdisk_root_first:
908
        mov     edi, 0x100000+512*19
909
        clc
910
        ret
911
ramdisk_root_next:
912
        add     edi, 0x20
913
        cmp     edi, 0x100000+512*33
914
        cmc
915
        ret
916
 
71 diamond 917
rd_find_lfn:
918
; in: esi->name
919
; out: CF=1 - file not found
920
;      else CF=0 and edi->direntry
86 diamond 921
        push    esi edi
922
        push    ramdisk_root_first
923
        push    ramdisk_root_next
924
        call    fat_find_lfn
925
        jc      .notfound
926
        cmp     byte [esi], 0
927
        jnz     .notfound
928
        add     esp, 12
929
        pop     esi
930
        ret     ; CF=0
71 diamond 931
.notfound:
86 diamond 932
        add     esp, 8
933
        pop     edi esi
78 diamond 934
        stc
935
        ret
71 diamond 936
 
937
;----------------------------------------------------------------
938
;
939
;  fs_RamdiskRead - LFN variant for reading sys floppy
940
;
941
;  esi  points to filename
942
;  ebx  pointer to 64-bit number = first wanted byte, 0+
943
;       may be ebx=0 - start from first byte
944
;  ecx  number of bytes to read, 0+
945
;  edx  mem location to return data
946
;
77 diamond 947
;  ret ebx = bytes read or 0xffffffff file not found
71 diamond 948
;      eax = 0 ok read or other = errormsg
949
;
950
;--------------------------------------------------------------
951
fs_RamdiskRead:
75 diamond 952
        cmp     byte [esi], 0
953
        jnz     @f
954
        or      ebx, -1
955
        mov     eax, 10         ; access denied
956
        ret
71 diamond 957
@@:
75 diamond 958
        push    edi
959
        call    rd_find_lfn
960
        jnc     .found
961
        pop     edi
962
        or      ebx, -1
963
        mov     eax, 5          ; file not found
964
        ret
71 diamond 965
.found:
75 diamond 966
        test    ebx, ebx
967
        jz      .l1
968
        cmp     dword [ebx+4], 0
969
        jz      @f
77 diamond 970
        xor     ebx, ebx
71 diamond 971
.reteof:
75 diamond 972
        mov     eax, 6          ; EOF
973
        pop     edi
974
        ret
71 diamond 975
@@:
75 diamond 976
        mov     ebx, [ebx]
71 diamond 977
.l1:
77 diamond 978
        push    ecx edx
979
        push    0
980
        mov     eax, [edi+28]
981
        sub     eax, ebx
982
        jb      .eof
983
        cmp     eax, ecx
984
        jae     @f
985
        mov     ecx, eax
986
        mov     byte [esp], 6           ; EOF
987
@@:
75 diamond 988
        movzx   edi, word [edi+26]	; cluster
71 diamond 989
.new:
75 diamond 990
        jecxz   .done
991
        test    edi, edi
992
        jz      .eof
993
        cmp     edi, 0xFF8
994
        jae     .eof
995
        lea     eax, [edi+31]           ; bootsector+2*fat+filenames
996
        shl     eax, 9                  ; *512
997
        add     eax, 0x100000           ; image base
71 diamond 998
; now eax points to data of cluster
75 diamond 999
        sub     ebx, 512
1000
        jae     .skip
1001
        lea     eax, [eax+ebx+512]
1002
        neg     ebx
1003
        push    ecx
1004
        cmp     ecx, ebx
1005
        jbe     @f
1006
        mov     ecx, ebx
71 diamond 1007
@@:
75 diamond 1008
        mov     ebx, edx
1009
        call    memmove
1010
        add     edx, ecx
1011
        sub     [esp], ecx
1012
        pop     ecx
1013
        xor     ebx, ebx
71 diamond 1014
.skip:
75 diamond 1015
        movzx   edi, word [edi*2+0x280000]      ; find next cluster from FAT
1016
        jmp     .new
71 diamond 1017
.eof:
77 diamond 1018
        mov     ebx, edx
1019
        pop     eax edx ecx
1020
        sub     ebx, edx
75 diamond 1021
        jmp     .reteof
71 diamond 1022
.done:
77 diamond 1023
        mov     ebx, edx
1024
        pop     eax edx ecx edi
1025
        sub     ebx, edx
75 diamond 1026
        ret
71 diamond 1027
 
75 diamond 1028
;----------------------------------------------------------------
1029
;
1030
;  fs_RamdiskReadFolder - LFN variant for reading sys floppy folder
1031
;
1032
;  esi  points to filename; only root is folder on ramdisk
78 diamond 1033
;  ebx  pointer to structure 32-bit number = first wanted block
1034
;                          & flags (bitfields)
1035
; flags: bit 0: 0=ANSI names, 1=UNICODE names
75 diamond 1036
;  ecx  number of blocks to read, 0+
1037
;  edx  mem location to return data
1038
;
1039
;  ret ebx = size or 0xffffffff file not found
1040
;      eax = 0 ok read or other = errormsg
1041
;
1042
;--------------------------------------------------------------
1043
fs_RamdiskReadFolder:
1044
        cmp     byte [esi], 0
1045
        jz      @f
1046
; ramdisk doesn't support folders
1047
        mov     eax, ERROR_ACCESS_DENIED
1048
        or      ebx, -1
1049
        ret
1050
@@:
1051
        push    esi edi ecx
1052
; init header
1053
        push    ecx
1054
        mov     edi, edx
1055
        mov     ecx, 32/4
1056
        xor     eax, eax
1057
        rep     stosd
1058
        mov     byte [edx], 1   ; version
1059
        pop     ecx
1060
        push    ebp
1061
        sub     esp, 262*2      ; allocate space for LFN
1062
        mov     ebp, esp
78 diamond 1063
        push    dword [ebx+4]   ; for fat_get_name: read ANSI/UNICODE name
1064
        mov     ebx, [ebx]
75 diamond 1065
; read root
1066
        mov     esi, edi        ; esi points to block of data of folder entry (BDFE)
1067
        mov     edi, 0x100000+512*19
1068
.l1:
1069
        call    fat_get_name
1070
        jc      .l2
1071
        cmp     byte [edi+11], 0xF
1072
        jnz     @f
1073
        add     edi, 0x20
1074
@@:
1075
        inc     dword [edx+8]   ; new file found
1076
        dec     ebx
1077
        jns     .l2
1078
        dec     ecx
1079
        js      .l2
1080
        inc     dword [edx+4]  ; new file block copied
1081
        call    fat_entry_to_bdfe
1082
.l2:
1083
        add     edi, 0x20
1084
        cmp     edi, 0x100000+512*33
1085
        jb      .l1
1086
        add     esp, 262*2+4
1087
        pop     ebp
77 diamond 1088
        mov     ebx, [edx+4]
75 diamond 1089
        xor     eax, eax
1090
        dec     ecx
1091
        js      @f
1092
        mov     al, ERROR_END_OF_FILE
1093
@@:
1094
        pop     ecx edi esi
1095
        ret
1096
 
83 diamond 1097
iglobal
1098
label fat_legal_chars byte
1099
; 0 = not allowed
1100
; 1 = allowed only in long names
1101
; 3 = allowed
1102
        times 32 db 0
1103
;                 ! " # $ % & ' ( ) * + , - . /
1104
        db      1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
1105
;               0 1 2 3 4 5 6 7 8 9 : ; < = > ?
1106
        db      3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
1107
;               @ A B C D E F G H I J K L M N O
1108
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
1109
;               P Q R S T U V W X Y Z [ \ ] ^ _
1110
        db      3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
1111
;               ` a b c d e f g h i j k l m n o
1112
        db      3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
1113
;               p q r s t u v w x y z { | } ~
1114
        db      3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
1115
endg
1116
 
1117
fat_name_is_legal:
1118
; in: esi->(long) name
1119
; out: CF set <=> legal
1120
; destroys eax
1121
        push    esi
1122
        xor     eax, eax
1123
@@:
1124
        lodsb
1125
        test    al, al
1126
        jz      .done
1127
        cmp     al, 80h
1128
        jae     .big
1129
        test    [fat_legal_chars+eax], 1
1130
        jnz     @b
1131
.err:
1132
        pop     esi
1133
        clc
1134
        ret
1135
.big:
1136
; 0x80-0xAF, 0xE0-0xEF
1137
        cmp     al, 0xB0
1138
        jb      @b
1139
        cmp     al, 0xE0
1140
        jb      .err
1141
        cmp     al, 0xF0
1142
        jb      @b
1143
        jmp     .err
1144
.done:
1145
        sub     esi, [esp]
1146
        cmp     esi, 257
1147
        pop     esi
1148
        ret
1149
 
1150
fat_next_short_name:
1151
; in: edi->8+3 name
1152
; out: name corrected
1153
;      CF=1 <=> error
1154
        pushad
1155
        mov     ecx, 8
1156
        mov     al, '~'
1157
        std
1158
        push    edi
1159
        add     edi, 7
1160
        repnz   scasb
1161
        pop     edi
1162
        cld
1163
        jz      .tilde
1164
; tilde is not found, insert "~1" at end
1165
        add     edi, 6
1166
        cmp     word [edi], '  '
1167
        jnz     .insert_tilde
1168
@@:     dec     edi
1169
        cmp     byte [edi], ' '
1170
        jz      @b
1171
        inc     edi
1172
.insert_tilde:
1173
        mov     word [edi], '~1'
1174
        popad
1175
;       clc     ; CF already cleared
1176
        ret
1177
.tilde:
1178
        push    edi
1179
        add     edi, 7
1180
        xor     ecx, ecx
1181
@@:
1182
; after tilde may be only digits and trailing spaces
1183
        cmp     byte [edi], '~'
1184
        jz      .break
1185
        cmp     byte [edi], ' '
1186
        jz      .space
1187
        cmp     byte [edi], '9'
1188
        jnz     .found
1189
        dec     edi
1190
        jmp     @b
1191
.space:
1192
        dec     edi
1193
        inc     ecx
1194
        jmp     @b
1195
.found:
1196
        inc     byte [edi]
1197
.succ:
1198
        pop     edi
1199
        popad
1200
        clc
1201
        ret
1202
.break:
1203
        jecxz   .noplace
1204
        inc     edi
1205
        mov     al, '1'
1206
@@:
1207
        xchg    al, [edi]
1208
        inc     edi
1209
        cmp     al, ' '
1210
        mov     al, '0'
1211
        jnz     @b
1212
        jmp     .succ
1213
.noplace:
1214
        dec     edi
1215
        cmp     edi, [esp]
1216
        jz      .err
1217
        add     dword [esp], 8
1218
        mov     word [edi], '~1'
1219
        inc     edi
1220
        inc     edi
1221
@@:
1222
        mov     byte [edi], '0'
1223
        inc     edi
1224
        cmp     edi, [esp]
1225
        jb      @b
1226
        pop     edi
1227
        popad
1228
        ;clc    ; automatically
1229
        ret
1230
.err:
1231
        pop     edi
1232
        popad
1233
        stc
1234
        ret
1235
 
1236
fat_gen_short_name:
1237
; in: esi->long name
1238
;     edi->buffer (8+3=11 chars)
1239
; out: buffer filled
1240
        pushad
1241
        mov     eax, '    '
1242
        push    edi
1243
        stosd
1244
        stosd
1245
        stosd
1246
        pop     edi
1247
        xor     eax, eax
1248
        push    8
1249
        pop     ebx
1250
        lea     ecx, [edi+8]
1251
.loop:
1252
        lodsb
1253
        test    al, al
1254
        jz      .done
1255
        call    char_toupper
1256
        cmp     al, ' '
1257
        jz      .space
1258
        cmp     al, 80h
1259
        ja      .big
1260
        test    [fat_legal_chars+eax], 2
1261
        jnz     .symbol
1262
.inv_symbol:
1263
        mov     al, '_'
1264
        or      bh, 1
1265
.symbol:
1266
        cmp     al, '.'
1267
        jz      .dot
1268
.normal_symbol:
1269
        dec     bl
1270
        jns     .store
1271
        mov     bl, 0
1272
.space:
1273
        or      bh, 1
1274
        jmp     .loop
1275
.store:
1276
        stosb
1277
        jmp     .loop
1278
.big:
1279
        cmp     al, 0xB0
1280
        jb      .normal_symbol
1281
        cmp     al, 0xE0
1282
        jb      .inv_symbol
1283
        cmp     al, 0xF0
1284
        jb      .normal_symbol
1285
        jmp     .inv_symbol
1286
.dot:
1287
        test    bh, 2
1288
        jz      .firstdot
1289
        pop     ebx
1290
        add     ebx, edi
1291
        sub     ebx, ecx
1292
        push    ebx
1293
        cmp     edi, ecx
1294
        jbe     .skip
1295
@@:
1296
        dec     edi
1297
        mov     al, ' '
1298
        xchg    al, [edi]
1299
        dec     ebx
1300
        mov     [ebx], al
1301
        cmp     edi, ecx
1302
        ja      @b
1303
.skip:
1304
        mov     bh, 3
1305
        jmp     @f
1306
.firstdot:
1307
        cmp     bl, 8
1308
        jz      .space
1309
        push    edi
1310
        or      bh, 2
1311
@@:
1312
        mov     edi, ecx
1313
        mov     bl, 3
1314
        jmp     .loop
1315
.done:
1316
        test    bh, 2
1317
        jz      @f
1318
        pop     edi
1319
@@:
1320
        lea     edi, [ecx-8]
1321
        test    bh, 1
1322
        jz      @f
1323
        call    fat_next_short_name
1324
@@:
1325
        popad
1326
        ret
1327
 
1328
;----------------------------------------------------------------
1329
;
1330
;  fs_RamdiskRewrite - LFN variant for writing sys floppy
1331
;
1332
;  esi  points to filename
1333
;  ebx  ignored (reserved)
1334
;  ecx  number of bytes to write, 0+
1335
;  edx  mem location to data
1336
;
1337
;  ret ebx = number of written bytes
1338
;      eax = 0 ok read or other = errormsg
1339
;
1340
;--------------------------------------------------------------
1341
@@:
1342
        mov     eax, ERROR_ACCESS_DENIED
1343
        xor     ebx, ebx
1344
        ret
1345
 
1346
fs_RamdiskRewrite:
1347
        cmp     byte [esi], 0
1348
        jz      @b
1349
; ramdisk doesn't support folders
1350
        push    esi
1351
@@:
1352
        lodsb
1353
        test    al, al
1354
        jz      @f
1355
        cmp     al, '/'
1356
        jnz     @b
1357
        pop     esi
1358
.err5:
1359
        mov     eax, 5  ; file not found
1360
        xor     ebx, ebx
1361
        ret
1362
@@:
1363
        pop     esi
1364
; check existence
1365
        push    edi
1366
        call    rd_find_lfn
1367
        jc      .notfound
1368
; found, delete FAT chain
1369
        push    edi
1370
        xor     eax, eax
1371
        mov     dword [edi+28], eax     ; zero size
1372
        xchg    ax, word [edi+26]       ; start cluster
1373
        test    eax, eax
1374
        jz      .done1
1375
@@:
1376
        cmp     eax, 0xFF8
1377
        jae     .done1
1378
        lea     edi, [0x280000 + eax*2] ; position in FAT
1379
        xor     eax, eax
1380
        xchg    ax, [edi]
1381
        jmp     @b
1382
.done1:
1383
        pop     edi
1384
        call    get_time_for_file
1385
        mov     [edi+22], ax
1386
        call    get_date_for_file
1387
        mov     [edi+24], ax
1388
        mov     [edi+18], ax
1389
        or      byte [edi+11], 20h      ; set 'archive' attribute
1390
        jmp     .doit
1391
.notfound:
1392
; file is not found; generate short name
1393
        call    fat_name_is_legal
1394
        jc      @f
1395
        pop     edi
1396
        jmp     .err5
1397
@@:
1398
        sub     esp, 12
1399
        mov     edi, esp
1400
        call    fat_gen_short_name
1401
.test_short_name_loop:
1402
        push    esi ecx
1403
        mov     esi, 0x100000+512*19
1404
.test_short_name_entry:
1405
        cmp     byte [esi+11], 0xF
1406
        jz      .test_short_name_cont
1407
        mov     ecx, 11
1408
        push    esi edi
1409
        repz    cmpsb
1410
        pop     edi esi
1411
        jz      .short_name_found
1412
.test_short_name_cont:
1413
        add     esi, 20h
1414
        cmp     esi, 0x100000+512*33
1415
        jb      .test_short_name_entry
1416
        pop     ecx esi
1417
        jmp     .found
1418
.short_name_found:
1419
        call    fat_next_short_name
1420
        pop     ecx esi
1421
        jnc     .test_short_name_loop
1422
.disk_full:
1423
        add     esp, 12
1424
        pop     edi
1425
        mov     eax, ERROR_DISK_FULL
1426
        xor     ebx, ebx
1427
        ret
1428
.found:
1429
; now find space in directory
1430
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
1431
        mov     al, '~'
1432
        push    ecx edi
1433
        mov     ecx, 8
1434
        repnz   scasb
1435
        push    1
1436
        pop     eax     ; 1 entry
1437
        jnz     .notilde
1438
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
1439
        xor     eax, eax
1440
@@:
1441
        cmp     byte [esi], 0
1442
        jz      @f
1443
        inc     esi
1444
        inc     eax
1445
        jmp     @b
1446
@@:
1447
        sub     esi, eax
1448
        add     eax, 12+13
1449
        mov     ecx, 13
1450
        push    edx
1451
        cdq
1452
        div     ecx
1453
        pop     edx
1454
.notilde:
1455
; find  successive entries in directory
1456
        xor     ecx, ecx
1457
        mov     edi, 0x100000+512*19
1458
.scan_dir:
1459
        cmp     byte [edi], 0
1460
        jz      .free
1461
        cmp     byte [edi], 0xE5
1462
        jz      .free
1463
        xor     ecx, ecx
1464
.scan_cont:
1465
        add     edi, 0x20
1466
        cmp     edi, 0x100000+512*33
1467
        jb      .scan_dir
1468
        pop     edi ecx
1469
        jmp     .disk_full
1470
.free:
1471
        inc     ecx
1472
        cmp     ecx, eax
1473
        jb      .scan_cont
1474
; found!
1475
; calculate name checksum
1476
        push    esi ecx
1477
        mov     esi, [esp+8]
1478
        mov     ecx, 11
1479
        xor     eax, eax
1480
@@:
1481
        ror     al, 1
1482
        add     al, [esi]
1483
        inc     esi
1484
        loop    @b
1485
        pop     ecx esi
1486
; edi points to last entry in free chunk
1487
        dec     ecx
1488
        jz      .nolfn
1489
        push    esi
1490
        push    edi
1491
.writelfn:
1492
        sub     edi, 20h
1493
        push    ecx eax
1494
        mov     eax, [esp+8]
1495
        sub     eax, edi
1496
        shr     eax, 5
1497
        cmp     ecx, 1
1498
        jnz     @f
1499
        or      al, 40h
1500
@@:
1501
        stosb
1502
        mov     cl, 5
1503
        call    .read_symbols
1504
        mov     ax, 0xF
1505
        stosw
1506
        pop     eax
1507
        stosb
1508
        push    eax
1509
        mov     cl, 6
1510
        call    .read_symbols
1511
        xor     eax, eax
1512
        stosw
1513
        mov     cl, 2
1514
        call    .read_symbols
1515
        pop     eax ecx
1516
        sub     edi, 0x20
1517
        loop    .writelfn
1518
        pop     edi
1519
        pop     esi
1520
.nolfn:
1521
        xchg    esi, [esp]
1522
        mov     ecx, 11
1523
        rep     movsb
1524
        mov     word [edi], 20h         ; attributes
1525
        sub     edi, 11
1526
        pop     esi ecx
1527
        add     esp, 12
1528
        mov     byte [edi+13], 0        ; tenths of a second at file creation time
1529
        call    get_time_for_file
1530
        mov     [edi+14], ax            ; creation time
1531
        mov     [edi+22], ax            ; last write time
1532
        call    get_date_for_file
1533
        mov     [edi+16], ax            ; creation date
1534
        mov     [edi+24], ax            ; last write date
1535
        mov     [edi+18], ax            ; last access date
1536
        and     word [edi+20], 0        ; high word of cluster
1537
        and     word [edi+26], 0        ; low word of cluster - to be filled
1538
        and     dword [edi+28], 0       ; file size - to be filled
1539
.doit:
1540
        push    ecx edx
1541
        push    ecx
1542
        push    edi
1543
        add     edi, 26         ; edi points to low word of cluster
1544
        push    edi
1545
        jecxz   .done
1546
        mov     ecx, 2849
1547
        mov     edi, 0x280000
1548
.write_loop:
1549
; allocate new cluster
1550
        xor     eax, eax
1551
        repnz   scasw
1552
        jnz     .disk_full2
1553
        dec     edi
1554
        dec     edi
1555
        lea     eax, [edi-0x280000]
1556
        shr     eax, 1                  ; eax = cluster
1557
        mov     word [edi], 0xFFF       ; mark as last cluster
1558
        xchg    edi, [esp]
1559
        stosw
1560
        pop     edi
1561
        push    edi
1562
        inc     ecx
1563
; write data
1564
        shl     eax, 9
1565
        add     eax, 0x100000+31*512
1566
        mov     ebx, edx
1567
        xchg    eax, ebx
1568
        push    ecx
1569
        mov     ecx, 512
1570
        cmp     dword [esp+12], ecx
1571
        jae     @f
1572
        mov     ecx, [esp+12]
1573
@@:
1574
        call    memmove
1575
        add     edx, ecx
1576
        sub     [esp+12], ecx
1577
        pop     ecx
1578
        jnz     .write_loop
1579
.done:
1580
        mov     ebx, edx
1581
        pop     edi edi ecx edx ecx
1582
        sub     ebx, edx
1583
        mov     [edi+28], ebx
1584
        pop     edi
1585
        xor     eax, eax
1586
        ret
1587
.disk_full2:
1588
        mov     ebx, edx
1589
        pop     edi edi ecx edx ecx
1590
        sub     ebx, edx
1591
        mov     [edi+28], ebx
1592
        pop     edi
1593
        push    ERROR_DISK_FULL
1594
        pop     eax
1595
        ret
1596
 
1597
.read_symbol:
1598
        or      ax, -1
1599
        test    esi, esi
1600
        jz      .retFFFF
1601
        lodsb
1602
        test    al, al
1603
        jnz     ansi2uni_char
1604
        xor     eax, eax
1605
        xor     esi, esi
1606
.retFFFF:
1607
        ret
1608
 
1609
.read_symbols:
1610
        call    .read_symbol
1611
        stosw
1612
        loop    .read_symbols
1613
        ret
1614
 
86 diamond 1615
fs_RamdiskGetFileInfo:
1616
        cmp     byte [esi], 0
1617
        jnz     @f
1618
        mov     eax, 2  ; unsupported
1619
        ret
1620
@@:
1621
        push    edi
1622
        call    rd_find_lfn
1623
fs_GetFileInfo_finish:
1624
        jnc     @f
1625
        pop     edi
1626
        mov     eax, ERROR_FILE_NOT_FOUND
1627
        ret
1628
@@:
1629
        push    esi ebp
1630
        xor     ebp, ebp
1631
        mov     esi, edx
1632
        and     dword [esi+4], 0
1633
        call    fat_entry_to_bdfe2
1634
        pop     ebp esi
1635
        pop     edi
1636
        xor     eax, eax
1637
        ret
1638
 
1639
fs_RamdiskSetFileInfo:
1640
        cmp     byte [esi], 0
1641
        jnz     @f
1642
        mov     eax, 2  ; unsupported
1643
        ret
1644
@@:
1645
        push    edi
1646
        call    rd_find_lfn
1647
        jnc     @f
1648
        pop     edi
1649
        mov     eax, ERROR_FILE_NOT_FOUND
1650
        ret
1651
@@:
1652
        call    bdfe_to_fat_entry
1653
        pop     edi
1654
        xor     eax, eax
1655
        ret
1656
 
78 diamond 1657
; \end{diamond}