$Revision: 442 $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; RAMDISK functions ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; Addings by M.Lisovin ;;
;; LFN support by diamond ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; calculate fat chain
calculatefatchain:
pushad
mov esi,RAMDISK+512
mov edi,RAMDISK_FAT
fcnew:
mov eax,dword [esi]
mov ebx,dword [esi+4]
mov ecx,dword [esi+8]
mov edx,ecx
shr edx,4 ;8 ok
shr dx,4 ;7 ok
xor ch,ch
shld ecx,ebx,20 ;6 ok
shr cx,4 ;5 ok
shld ebx,eax,12
and ebx,0x0fffffff ;4 ok
shr bx,4 ;3 ok
shl eax,4
and eax,0x0fffffff ;2 ok
shr ax,4 ;1 ok
mov dword [edi],eax
mov dword [edi+4],ebx
mov dword [edi+8],ecx
mov dword [edi+12],edx
add edi,16
add esi,12
cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters
jnz fcnew
popad
ret
restorefatchain: ; restore fat chain
pushad
mov esi,RAMDISK_FAT
mov edi,RAMDISK+512
fcnew2:
mov eax,dword [esi]
mov ebx,dword [esi+4]
shl ax,4
shl eax,4
shl bx,4
shr ebx,4
shrd eax,ebx,8
shr ebx,8
mov dword [edi],eax
mov word [edi+4],bx
add edi,6
add esi,8
cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT
jb fcnew2
mov esi,RAMDISK+512 ; duplicate fat chain
mov edi,RAMDISK+512+0x1200
mov ecx,1069 ;4274/4
cld
rep movsd
popad
ret
ramdisk_free_space:
;---------------------------------------------
;
; returns free space in edi
; rewr.by Mihasik
;---------------------------------------------
push eax ebx ecx
mov edi,RAMDISK_FAT ;start of FAT
xor ax,ax ;Free cluster=0x0000 in FAT
xor ebx,ebx ;counter
mov ecx,2849 ;2849 clusters
cld
rdfs1:
repne scasw
jnz rdfs2 ;if last cluster not 0
inc ebx
test ecx, ecx
jnz rdfs1
rdfs2:
shl ebx,9 ;free clusters*512
mov edi,ebx
pop ecx ebx eax
ret
expand_filename:
;---------------------------------------------
;
; exapand filename with '.' to 11 character
; eax - pointer to filename
;---------------------------------------------
push esi edi ebx
mov edi,esp ; check for '.' in the name
add edi,12+8
mov esi,eax
mov eax,edi
mov [eax+0],dword ' '
mov [eax+4],dword ' '
mov [eax+8],dword ' '
flr1:
cmp [esi],byte '.'
jne flr2
mov edi,eax
add edi,7
jmp flr3
flr2:
mov bl,[esi]
mov [edi],bl
flr3:
inc esi
inc edi
mov ebx,eax
add ebx,11
cmp edi,ebx
jbe flr1
pop ebx edi esi
ret
fileread:
;----------------------------------------------------------------
;
; fileread - sys floppy
;
; eax points to filename 11 chars
; ebx first wanted block ; 1+ ; if 0 then set to 1
; ecx number of blocks to read ; 1+ ; if 0 then set to 1
; edx mem location to return data
; esi length of filename 12*X 0=root
;
; ret ebx = size or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
test ebx,ebx ;if ebx=0 - set to 1
jnz frfl5
inc ebx
frfl5:
test ecx,ecx ;if ecx=0 - set to 1
jnz frfl6
inc ecx
frfl6:
test esi,esi ; return ramdisk root
jnz fr_noroot ;if not root
cmp ebx,14 ;14 clusters=root dir
ja oorr
cmp ecx,14
ja oorr
jmp fr_do
oorr:
mov eax,5 ;out of root range (fnf)
xor ebx,ebx
dec ebx ;0xffffffff
ret
fr_do: ;reading rootdir
mov edi,edx
dec ebx
push edx
mov edx,ecx
add edx,ebx
cmp edx,15 ;ebx+ecx=14+1
pushf
jbe fr_do1
sub edx,14
sub ecx,edx
fr_do1:
shl ebx,9
mov esi,RAMDISK+512*19
add esi,ebx
shl ecx,7
cld
rep movsd
popf
pop edx
jae fr_do2
xor eax,eax ; ok read
xor ebx,ebx
ret
fr_do2: ;if last cluster
mov eax,6 ;end of file
xor ebx,ebx
ret
fr_noroot:
sub esp,32
call expand_filename
dec ebx
push eax
push eax ebx ecx edx esi edi
call rd_findfile
je fifound
add esp,32+28 ;if file not found
ret
fifound:
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
movzx eax,word [edi]
mov edi,eax ;edi=cluster
frnew:
add eax,31 ;bootsector+2*fat+filenames
shl eax,9 ;*512
add eax,RAMDISK ;image base
mov ebx,[esp+8]
mov ecx,512 ;[esp+4]
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7
call memmove
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
je frnoread
jmp frfl8
frfl7:
dec dword [esp+16]
frfl8:
movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT
mov edi,eax
cmp edi,4095 ;eof - cluster
jz frnoread2
cmp [esp+24],dword 512 ;eof - size
jb frnoread
sub [esp+24],dword 512
jmp frnew
frnoread2:
cmp [esp+16],dword 0 ; eof without read ?
je frnoread
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
ret
frnoread:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
xor eax,eax ;read ok
ret
filedelete:
;--------------------------------------------
;
; filedelete - sys floppy
; in:
; eax - pointer to filename 11 chars
;
; out:
; eax - 0 = successful, 5 = file not found
;
;--------------------------------------------
sub esp,32
call expand_filename
push eax ebx ecx edx esi edi
call rd_findfile
je fifoundd
pop edi esi edx ecx ebx eax ;file not found
add esp,32
mov eax,5
ret
fifoundd:
mov [edi-11],byte 0xE5 ;mark filename deleted
add edi,0xf
movzx eax,word [edi]
mov edi,eax ;edi = cluster
frnewd:
shl edi,1 ;find next cluster from FAT
add edi,RAMDISK_FAT
movzx eax,word [edi]
mov [edi],word 0x0 ;clear fat chain cluster
mov edi,eax
cmp edi,dword 0xff8 ;last cluster ?
jb frnewd
pop edi esi edx ecx ebx eax
add esp,32
xor eax,eax ; file found
ret
filesave:
;----------------------------------------------------------
;
; filesave - sys floppy
;
; eax points to filename 11 chars
;
; eax ; pointer to file name
; ebx ; buffer
; ecx ; count to write in bytes
; edx ; 0 create new , 1 append
;
;-----------------------------------------------------------
sub esp,32
call expand_filename
test edx,edx
jnz fsdel
pusha
call filedelete
popa
fsdel:
call ramdisk_free_space
cmp ecx,edi
jbe rd_do_save
add esp,32
mov eax,8 ;disk full
ret
rd_do_save:
push eax ebx ecx edx esi edi
mov edi,RAMDISK+512*18+512 ;Point at directory
mov edx,224 +1
; find an empty spot for filename in the root dir
l20ds:
dec edx
jz frnoreadds
l21ds:
cmp [edi],byte 0xE5
jz fifoundds
cmp [edi],byte 0x0
jz fifoundds
add edi,32 ; Advance to next entry
jmp l20ds
fifoundds:
push edi ; move the filename to root dir
mov esi,[esp+4+20]
mov ecx,11
cld
rep movsb
pop edi
mov edx,edi
add edx,11+0xf ; edx <- cluster save position
mov ebx,[esp+12] ; save file size
mov [edi+28],ebx
mov [edi+11],byte 0x20 ; attribute
; Ivan Poddubny 11/12/2003:
call get_date_for_file ; from FAT32.INC
mov [edi+24],ax ; date
call get_time_for_file ; from FAT32.INC
mov [edi+22],ax ; time
; End
mov edi,RAMDISK_FAT ;pointer to first cluster
mov ecx,2849
cld
frnewds:
xor ax,ax
repne scasw
mov ebx,2848
sub ebx,ecx
mov [edx],bx ; save next cluster pos. to prev cl.
mov edx,edi ; next save pos abs mem add
dec edx
dec edx
call fdc_filesave
pusha ; move save to floppy cluster
add ebx,31
shl ebx,9
add ebx,RAMDISK
mov eax,[esp+32+16]
mov ecx,512
call memmove
popa
mov eax,[esp+12]
cmp eax,512
jbe flnsa
sub eax,512
mov [esp+12],eax
add dword [esp+16], 512
jmp frnewds
flnsa:
mov [edi-2],word 4095 ; mark end of file - last cluster
frnoreadds:
pop edi esi edx ecx ebx eax
add esp,32
; pusha
; cli
; call fdc_commitfile
; sti
; popa
xor eax,eax ;ok write
ret
rd_findfile:
;by Mihasik
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx
mov edi,RAMDISK+512*18+512 ;Point at directory
cld
rd_newsearch:
mov esi,eax
mov ecx,11
rep cmpsb
je rd_ff
add cl,21
add edi,ecx
cmp edi,RAMDISK+512*33
jb rd_newsearch
mov eax,5 ;if file not found - eax=5
xor ebx,ebx
dec ebx ;ebx=0xffffffff and zf=0
rd_ff:
ret
; \begin{diamond}
uni2ansi_str:
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
; in: esi->source, edi->buffer (may be esi=edi)
; destroys: eax,esi,edi
lodsw
test ax, ax
jz .done
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
.ascii:
.doit:
stosb
jmp uni2ansi_str
.done:
mov byte [edi], 0
ret
ansi2uni_char:
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
mov ah, 0
; 0x00-0x7F - trivial map
cmp al, 0x80
jb .ret
; 0x80-0xAF -> 0x410-0x43F
cmp al, 0xB0
jae @f
add ax, 0x410-0x80
.ret:
ret
@@:
; 0xE0-0xEF -> 0x440-0x44F
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jae @f
add ax, 0x440-0xE0
ret
; 0xF0 -> 0x401
; 0xF1 -> 0x451
@@:
cmp al, 'ð'
jz .yo1
cmp al, 'ñ'
jz .yo2
.unk:
mov al, '_' ; ah=0
ret
.yo1: