;NXOS ;Written by: Alberto Venturini (Alb‚) - 2001 ;Email address: -albe-@libero.it ;Questo codice funziona ma Š abbastanza "bad coded" (vedi Fat12_FileSearch)... ;Appena ho tempo lo devo riscrivere. ;Procedure "pubbliche": ; ;1) Fat12_FatInit ; (no input, no output) ; ;2) Fat12_OpenFile ; Input: DS:SI punta al nome del file da aprire ; Output: SI Š il file handler. ; ;3) Fat12_CloseFile ; Input: SI file handler ; ;4) Fat12_ReadFile ; Input DX: numero di bytes da leggere ; SI: file handler ; ES:DI buffer in cui memorizzare il file ;5) Fat12_ChDir ; Input DS:SI punta al nome della directory Fat12_MaxFiles equ 5 ;------------------------------------------------------------------------------ Fat12_DriveParams: ;chiama l'int 13h per sapere i parametri del drive 00h (il primo floppy drive) ;memorizza il numero di heads, sectors e cylinders del drive. ;Input: no inputs. Output: no outputs. ;Modifica AX,CX,DX mov ah,08h xor dx,dx int 13h mov al,dh xor ah,ah inc ax mov cs:[Fat12_Heads],ax mov al,cl and ax,3fh mov cs:[Fat12_Sectors],ax mov al,ch mov ah,cl mov cl,6 shr ah,cl inc ax mov cs:[Fat12_Cylinders],ax ret ;------------------------------------------------------------------------------ Fat12_FatInit: ;inizializza le variabili che serviranno per la lettura dei file con la FAT12 ;Questa procedura Š da chiamare prima di eseguire qualsiasi operazione con i ;file. push ax push cx push dx push es call Fat12_DriveParams mov ax,0800h mov cs:[Fat12_FatSegment],ax push si xor si,si xor ax,ax Fat12_FatInit_ClearFile: mov word ptr cs:[Fat12_FileSector+si],ax add si,2 cmp si,(Fat12_MaxFiles*2) jb Fat12_FatInit_ClearFile pop si xor ax,ax mov es,ax mov ax,word ptr es:[7c00h+0eh] ;reserved sectors (logical sector in cui inizia la fat) mov cs:[Fat12_FatStart],ax mov ax,word ptr es:[7c00h+16h] ;sectors per fat mov cs:[Fat12_SectorsPerFat],ax push ax mov al,byte ptr es:[7c00h+10h] ;number of fats mov cs:[Fat12_NumberOfFats],al cbw mov cx,ax pop ax mul cx add ax,cs:[Fat12_FatStart] mov cs:[Fat12_RootStart],ax mov cs:[Fat12_CurrentDir],ax mov ax,word ptr es:[7c00h+11h] ;root directory entries mov cs:[Fat12_RootEntries],ax mov ax,cs:[Fat12_SectorsPerFat] xor cx,cx mov cl,cs:[Fat12_NumberOfFats] mul cx ;AX=total fat sectors mov bx,ax mov ax,cs:[Fat12_RootEntries] mov cl,4 shr ax,cl mov cs:[Fat12_RootSectors],ax mov cs:[Fat12_CurrentDirSize],ax add ax,bx add ax,cs:[Fat12_FatStart] mov cs:[Fat12_DataArea],ax pop es pop dx pop cx pop ax ret ;------------------------------------------------------------------------------ Fat12_ReadSector: ;this translates the logical sector value in AX, in CHS value ;logical sector in DX:AX (or simply in AX); then read the sector in ES:BX ;input: ;DX:AX=logical sector ;ES:BX=buffer ;CL=number of sectors to read ;Modifica AX,BX,CX,DX,SI push bx push cx mov bx,ax mov ax,dx xor dx,dx div cs:[Fat12_Sectors] mov cx,ax mov ax,bx div cs:[Fat12_Sectors] inc dx xchg cx,dx div cs:[Fat12_Heads] mov ch,al ror ah,1 ror ah,1 or cl,ah mov dh,dl mov dl,00h pop si pop bx mov ax,si mov ah,02h int 13h ret ;------------------------------------------------------------------------------ Fat12_WriteSector: ;this translates the logical sector value in AX, in CHS value ;logical sector in DX:AX (or simply in AX); then writes the sector from ES:BX ;input: ;DX:AX=logical sector to write ;ES:BX=data buffer ;CL=number of sectors to write ; push bx ; push cx ; mov bx,ax ; mov ax,dx ; xor dx,dx ; div [Fat12_Sectors] ; mov cx,ax ; mov ax,bx ; div [Fat12_sectors] ; inc dx ; xchg cx,dx ; div [Fat12_Heads] ; mov ch,al ; ror ah,1 ; ror ah,1 ; or cl,ah ; mov dh,dl ; mov dl,00h ; pop si ; pop bx ; mov ax,si ; mov ah,03h ; int 13h ; ret ;------------------------------------------------------------------------------ Fat12_NextCluster: ;input AX=current cluster ;output AX=fat value for current cluster (next cluster or eof...etc) ;Modifica AX push dx push es push di push ax mov di,3 mul di shr ax,1 mov di,ax mov ax,cs:[Fat12_FatSegment] mov es,ax mov ax,word ptr es:[di] pop di and di,1 test di,di jz nextcluster_even push cx mov cl,4 shr ax,cl pop cx jmp nextcluster_done nextcluster_even: and ax,0fffh nextcluster_done: pop di pop es pop dx ret ;------------------------------------------------------------------------------ Fat12_FileSearch: ;this looks for a file in the current directory ;entry: ;DS:SI=pointer to file name ;output:carry set if file not found ;carry clear if found - ES:DI points to file entry ;If a bad sector is found, the carry is set and DI is set to 0ffffh ;Modifica AX,BX,CX,DX,DI,ES ;Questa Š una delle procedure pi— "critiche" di tutto il supporto Fat... push cs:[Fat12_RootSectors] push cs:[Fat12_CurrentDir] ; push cs ; pop es push si push ds ; call Fat12_GetFileName file_ini: xor dx,dx mov ax,cs:[Fat12_CurrentDir] ;DX:AX=directory starting sector mov bx,offset Fat12_DirBuffer ;ES:BX=buffer push bx mov cl,1 ;legge 1 settore push si call Fat12_ReadSector pop si pop di ;ES:DI=buffer xor dx,dx ;DX=counter filenext: mov cx,11 ;ogni nome di file Š lungo 11 bytes push si push di rep cmpsb pop di pop si je filefound add di,32 ;passa alla prossima entry add dx,32 cmp dx,512 jb filenext ;se DX>512 vuol dire che dobbiamo passare ad un altro settore mov ax,cs:[Fat12_CurrentDir] cmp cs:[Fat12_DataArea],ax ja rootdir add ax,2 sub ax,cs:[Fat12_Dataarea] ;sistemazione del valore del settore call Fat12_nextcluster cmp ax,0ff7h ;controlla se siamo alla fine della directory ja filenotfound je filesearch_badsector sub ax,2 add ax,cs:[Fat12_DataArea] mov cs:[Fat12_CurrentDir],ax jmp file_ini rootdir: dec cs:[Fat12_RootSectors] jz filenotfound inc cs:[Fat12_CurrentDir] jmp file_ini filenotfound: stc ; mov bx,0000h ;setta l'errore 0000h ; mov ah,01h ; int 21h jmp filesearch_end filesearch_badsector: stc ; mov bx,0001h ;setta l'errore 0001h ; mov ah01h ; int 21h mov di,0ffffh jmp filesearch_end filefound: clc filesearch_end: pop ds pop si pop cs:[Fat12_CurrentDir] pop cs:[Fat12_RootSectors] ret ;------------------------------------------------------------------------------ Fat12_GetFileName: ;input DS:[SI] name of the file ;This routine translates the name "namefile.ext" into NAMEFILEEXT push ax push cx push di push es mov di,offset GetFileNameBuffer mov cx,9 GetFileName_StoreFileName: lodsb cmp al,96 jbe GetFileName_UpCaseOk sub al,32 GetFileName_UpCaseOk: cmp al,'.' je GetFileName_StoreExtension dec cx jz GetFileName_StoreExtension stosb jmp GetFileName_StoreFileName GetFileName_StoreExtension: test cx,cx ; jz GetFileName_StoreExtension2 jnz GetFileName_CompleteName lodsb cmp al,'.' jne GetFileName_NoExtension jmp GetFileName_StoreExtension GetFileName_CompleteName: dec cx test cx,cx jz GetFileName_StoreExtension2 mov al,' ' rep stosb GetFileName_StoreExtension2: mov cx,3 rep movsb GetFileName_NoExtension: mov si,offset GetFileNameBuffer push cs pop ds pop es pop di pop cx pop ax ret GetFileNameBuffer db 12 dup (?) ;------------------------------------------------------------------------------ Fat12_ChDir: ;Cambia la directory corrente ;entry: ;DS:SI=pointer to directory name ;output:carry set if directory not found ;Modifica AX,BX,CX,DX,DI,ES push ax push bx push cx push dx push es push di push si push ds call Fat12_GetFileName push si add si,8 mov al,' ' mov cx,3 Fat12_ChDir_1: mov byte ptr ds:[si],al inc si loop Fat12_ChDir_1 pop si call Fat12_FileSearch jc chdir_notfound mov al,byte ptr es:[di+0bh] ;legge gli attributi del file and al,00010000b cmp al,10h ;controlla se si tratta di una subdir stc jne chdir_notfound mov ax,word ptr es:[di+1ah] sub ax,2 add ax,cs:[Fat12_DataArea] mov cs:[Fat12_CurrentDir],ax mov cx,8 mov di,offset Fat12_DirName ChDir_StoreName1: mov al,byte ptr ds:[si] cmp al,' ' jne ChDir_StoreName2 mov al,0 ChDir_StoreName2: mov byte ptr cs:[di],al loop ChDir_StoreName1 clc chdir_notfound: pop ds pop si pop di pop es pop dx pop cx pop bx pop ax ret ;------------------------------------------------------------------------------ Fat12_GetCurrentDirName: ;output ES:DI=pointer to directory name mov di,cs mov es,di mov di,offset Fat12_DirName ret Fat12_DirName db '\',0,' ' ;initial directory name (root directory) ;------------------------------------------------------------------------------ Fat12_OpenFile: ;entry: ;DS:SI=pointer to file name ;output:carry set if file not found ;SI=file number (if file was found) ;inizializes [file_sector] to the first sector of the file push ax push bx push cx push dx push es push di push cs pop es push ds push si call Fat12_GetFileName call Fat12_FileSearch pop si pop ds jc open_file_error2 mov cx,Fat12_MaxFiles+1 xor si,si open_file_1: mov ax,cs:[Fat12_FileSector+si] test ax,ax jz open_file_2 dec cx jz open_file_error add si,2 jmp open_file_1 open_file_2: mov cx,si mov ax,es:[di+1ah] sub ax,2 add ax,cs:[Fat12_DataArea] mov cs:[Fat12_FileSector+si],ax xor ax,ax mov cs:[Fat12_FileBytes+si],ax mov ax,word ptr es:[di+1ch] push si add si,si mov word ptr cs:[Fat12_FileSize+si+2],ax mov ax,word ptr es:[di+1eh] mov word ptr cs:[Fat12_FileSize+si],ax pop si mov al,byte ptr es:[di+0bh] shr si,1 mov byte ptr cs:[Fat12_FileAttr+si],al mov si,cx clc jmp open_file_error2 open_file_error: stc open_file_error2: ; pop si ; pop ds pop di pop es pop dx pop cx pop bx pop ax ret ;------------------------------------------------------------------------------ Fat12_CloseFile: ;input SI:number of file to close push ax xor ax,ax mov cs:[Fat12_FileSector+si],ax pop ax ret ;------------------------------------------------------------------------------ Fat12_ReadFile: ;input DX=number of bytes to read ;SI=file number ;ES:DI=buffer for data push ax push bx push cx push dx push si push di test dx,dx jz readfile_end1 readfile_ini: mov bx,offset Fat12_DirBuffer push dx xor dx,dx mov ax,cs:[Fat12_FileSector+si] mov cl,1 push si push es push cs pop es call Fat12_ReadSector pop es pop si mov cx,cs:[Fat12_FileBytes+si] add bx,cx mov ax,512 sub ax,cx mov cx,ax pop dx r1: mov al,byte ptr cs:[bx] mov byte ptr es:[di],al inc word ptr cs:[Fat12_FileBytes+si] ; dec dx ; jz readfile_end1 push si add si,si dec word ptr cs:[Fat12_FileSize+si+2] jnz r2 cmp word ptr cs:[Fat12_FileSize+si],0 je readfile_eof dec word ptr cs:[Fat12_FileSize+si] mov ax,0ffffh mov word ptr cs:[Fat12_FileSize+si+2],ax jmp r2 readfile_end1: jmp readfile_end r2: pop si dec dx jz readfile_end inc bx inc di loop r1 xor ax,ax mov word ptr cs:[Fat12_FileBytes+si],ax mov ax,word ptr cs:[Fat12_FileSector+si] add ax,2 sub ax,cs:[Fat12_DataArea] call Fat12_NextCluster cmp ax,0ff7h ja readfile_badcluster ; je readfile_eof je readfile_end sub ax,2 add ax,cs:[Fat12_DataArea] mov word ptr cs:[Fat12_FileSector+si],ax jmp readfile_ini readfile_eof: pop si readfile_badcluster: readfile_end: pop di pop si pop dx pop cx pop bx pop ax ret ;------------------------------------------------------------------------------ Fat12_WriteFile: ;This procedure writes to a file. ;input: ;SI=number of file ;ES:DI=data buffer ;DX=number of bytes to write ; ret ;------------------------------------------------------------------------------ Fat12_GetFileSize: ;Input SI=file handler ;Output AX=File size (per ora solo word...) ;Attenzione: questa procedura ritorna un valore corretto SOLO se viene chiamata ;subito dopo aver aperto il file. push si add si,si mov ax,word ptr cs:[Fat12_FileSize+si+2] pop si ret ;------------------------------------------------------------------------------