nxos/FAT12D.ASM
2014-01-27 10:02:18 +01:00

671 lines
12 KiB
NASM
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;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
;------------------------------------------------------------------------------