;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; RAMDISK functions ;; ;; (C) 2004 Ville Turjanmaa, License: GPL ;; ;; Addings by M.Lisovin ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; calculate fat chain calculatefatchain: pushad mov esi,0x100000+512 mov edi,0x280000 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 add edi,4 mov dword [edi],ebx add edi,4 mov dword [edi],ecx add edi,4 mov dword [edi],edx add edi,4 add esi,12 cmp edi,0x280000+2856*2 ;2849 clusters jnz fcnew popad ret restorefatchain: ; restore fat chain pushad mov esi,0x280000 mov edi,0x100000+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 add edi,4 mov word [edi],bx add edi,2 add esi,8 cmp edi,0x100000+512+4278 ;4274 bytes - all used FAT jb fcnew2 mov esi,0x100000+512 ; duplicate fat chain mov edi,0x100000+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,0x280000 ;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 jcxz rdfs2 ;if last cluster=0 jmp rdfs1 ;if not last 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,0x100000+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,0x100000 ;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 ? cmp [esp+12],dword 0 je frnoread jmp frfl8 frfl7: dec dword [esp+16] frfl8: shl edi,1 ;find next cluster from FAT add edi,0x280000 movzx eax,word [edi] 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,0x280000 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,0x100000+512*18+512 ;Point at directory mov edx,224 +1 ; find an empty spot for filename in the root dir l20ds: dec edx test edx,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,0x280000 ;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,0x100000 mov eax,[esp+32+16] mov ecx,512 call memmove popa mov eax,[esp+12] cmp eax,512 jb flnsa sub eax,512 mov [esp+12],eax mov eax,[esp+16] add eax,512 mov [esp+16],eax jmp frnewds flnsa: dec edi dec edi mov [edi],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,0x100000+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,0x100000+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 rd_getfileinfo: ;get date, time, size or attributes of file ;IN: eax - pointer to file, ebx - type of function: 12-get filesize, 13-get fileattr, 14-get filedate ;ecx - filelengh 0=root ;OUT: eax=0 - Ok or 5 - file not found ebx - date/time, size or attributes test ecx,ecx jnz no_getfinfo_root mov eax,5 ;if root - fnf xor ebx,ebx dec ebx ret no_getfinfo_root: ;if not root sub esp,32 call expand_filename call rd_findfile je fifoundi add esp,32 ;if file not found ret fifoundi: cmp ebx,13 jne no_rd_attr movzx ebx,byte [edi] ;get attributes jmp rd_getfileinfo_end no_rd_attr: cmp ebx,14 jne no_rd_date mov ebx,dword [edi+11] ;get date/time jmp rd_getfileinfo_end no_rd_date: mov ebx,dword [edi+17] ;get size rd_getfileinfo_end: xor eax,eax add esp,32 ret