; FILESYS.ASM- v 1.19 2005/03/25 12:16:06 Chris Evans

; ===========================================================================
; Floppy disk driver primitives
; ===========================================================================
include \nxdos\src\kernel\floppy.asm
; include \nxdos\src\kernel\hdd.asm

; 1 . need to take a path string and split it into path and file
;
; 2 . A function to browse through a directory starting at a specific cluster
; and match the string passed in with an entry in the directory table, and
; then returns the start cluster of this.
;
; 3 . A function to remove trailing spaces from filenames/paths.
;
; 4 . A function to use the match and search functions to traverse a path
; using start clusters found to find the next sublevel of directory in a
; directory string.
;
; 5 . A function to return the number of directories in a path string.
;
; 6 . A function to return a directory name from a path string from
; a sublevel value passed in.
;
; 7. Need to implement file system buffering, basic file I/O and file
; pointers, file access modes. Maintain and open file table, and include
; each file's access mode and pointer indicating next location to read
; or write
;
; Grants for giving 2005
; www.starbucks.com www.ktvu.com

; ===========================================================================
; FAT FS primitives
; ===========================================================================
FAT_SECTOR_SIZE          EQU 512
WRITING_TO_FAT32_ENABLED EQU 0
DELETED_DIR_ENTRY_MARKER EQU 0E5h
; FAT file system attribute bits
normal     EQU 0
readonly   EQU 01h
hidden     EQU 02h
system     EQU 04h
vol_id     EQU 08h
dir        EQU 10h
archive    EQU 20h
;device     EQU 40h 
compressed EQU 60h
encrypt    EQU 80h

; Test for 16 bit or 12 bit FAT
SIZEOF_CLUSTER16 EQU 2
SIZEOF_CLUSTER32 EQU 4

LONG_LAST_CLUSTER_32 EQU 0FFFFFFFh
LONG_BAD_32          EQU 0FFFFFF7h
LONG_LAST_CLUSTER    EQU 0FFFFh
LONG_BAD             EQU 0FFF7h
MASK16               EQU 0FFF8h
BAD16                EQU 0FFF7h
MASK12               EQU 0FF8h
BAD12                EQU 0FF7h

; magic constants: even though FF7 is BAD so FF6 could be a valid cluster,
; MS docs specify that FF5 is the maximal possible cluster number for FAT12
; similar for 16 and 32

FAT_MAGIC   EQU 4085
FAT_MAGIC16 EQU 65525
FAT_MAGIC32 EQU 268435455
DIRENTRY_SIZE EQU 32

; FAT-12 files of 0 size have starting cluster set to 0 or chkdsk get error
MAXFILES     EQU 255
filename_buf db 127 dup(0)
FS_wtemp     dw ?
FS_Drive     db 0
driveheads   db 2
driveSPT     db 18

FAT_CACHE_SIZE dw 0
NBLKBUFFS      dw 0  ; blocks in buffer pool
NUM_USERS      dw 4  ; maximum number of tasks that my access the file system
NUSERFILES     dw 10 ; maximum number of open files

; Maximum cluster count
FAT_TYPE_FAT12 dw 0ff0h      ; Minimum for 12 and 16 just divide max by 2
FAT_TYPE_FAT16 dw 0fff0h
FAT_TYPE_FAT32 dd 0ffffff0h  ; Minimum is FAT16 maximum

D_LFN      db readonly+hidden+system+vol_id
D_ALL      db readonly+hidden+system+dir+archive

; FAT file name constants
FNAME_SIZE db 8
FEXT_SIZE  db 3

; FAT deleted flag
DELETED     db 5                  ; if first char, delete file 
EXT_DELETED db 0e5h               ; external deleted flag

; FAT cluster special flags
FAT_FREE   db 0,0,0

FS_SEARCH_FCB:                           ; FAT file system directory entry
          FCB_bDrvID     db ?            ; sysdirentry
          FCB_abName     db 8 dup(0)     ; Filename + extension in FCB format
          FCB_abExt      db 3 dup(0)
          FCB_wCurBlock  dw 0            
          FCB_wRecSize   dw 0
          FCB_lFileSize  dd 0
          FCB_rDate      dw ?
          FCB_rTime      dw ?
          FCB_res        db 8 dup(0)
          FCB_wCurRecNo  dw ?
          FCB_lRndmRecNo dd ?
          FCB_SIZE       EQU 37
          FCB_Cluster    dw ?            ; Starting cluster 
          FCB_Attrib     db 0            ; File Attribute
          FCB_SIZE2      EQU 40

; Who at Microsoft came up with this mad structure?!?!
lfnentry    db 0 
lfnid       db 0                    ; Sequence number for this LFN entry
lfnname5    db 5 dup(0)             ; First 5 characters of LFN
lfnattrib   db 0                    ; LFN attribute, should be D_LFN == 0x0f
lfnreservd1 db 0
lfnchecksum db 0                    ;Checksum for the corresponding 8.3 name
lfnname_n6  db 6 dup(0)             ; Next 6 characters of LFN
lfnreservd2 dw 0
lfnname_l2  dw 2 dup(0)             ; Last 2 characters of LFN
; You know, I like 4-DOS method of long filenames, the descript.ion file
; filename.ext description blah blah blah

; DOUBLESPACE/DRIVESPACE STACKER drives are just DOS FORMATTED FATS with
; a CVS index and volume file stored in root directory (with is host drive).

; Windows 95/98 and Windows NT/2000 store long filenames on FAT in special
; directory entries with set attributes ReadOnly, Hidden, System and Volume,
; so if you access FAT volume from DOS you don't see these "files". These
; special entries have this mad structure:

vfat_slotseq      db ? ; byte              sequence number for slot
lfn_first5fn      db 10 dup(0) ; string(10)        first 5 characters in name
lfn_attrib        db ? ; byte              attribute byte
lfn_reserved      db 0 ; byte              always 0
lfn83aliaschksum  db ? ; byte              checksum for 8.3 alias
lfn_next6fn       db 12 dup(0) ; string(12)        6 more characters in name
lfn_startcluster  dw 0 ; word           starting cluster number, 0 in long slots
lfn_last2fn       db 4 dup(0); string(4)         last 2 characters in name

; Problem occur when you delete or modify file with long name from system
; without VFAT support, because only DOS 8+3 entry will be deleted or
; modified. Scandisk from Windows 95/98 can repair this problem.

UMSDOS_LFN        db '--linux.-.---',0
; Linux UMSDOS stores longfile names in the --linux-.--- file in each
; directory. I like this way better, instead of the hack MS did.
os2extattrib      db '\ea data. sf',0
os2extattrib2     db '\wp root. sf',0

_fsreadonly  db 0 ; if not exist, fail. ptr = 0
_fswriteonly db 1 ; if exist, erase it or create new. ptr = eof
_fsappend    db 2 ; if exist, open or create new. Initilize ptr to eof.
_fsreadwrite db 3 ; open/create file, initialize ptr to ofs 0

        include \nxdos\src\kernel\FAT12.ASM
;       include \nxdos\src\kernel\FAT16.ASM
;       include \nxdos\src\kernel\FAT32.ASM

fix_filename proc far
; SI : FILENAME.EXT
        call cs:FS_GDONE
        lea  di, dos_filespec
        mov  cx, 8
fixfile0:
        mov  al, byte ptr [si]
        cmp  al, '.'
        je   ff1
        mov  byte ptr [di], al
        cmp  al, 20h
        je   ff1
        inc  si
        inc  di
        loop fixfile0
ff1:
        inc  si
        mov  di, offset dos_filespec+8
        mov  cx, 3
fixfile1:
        mov  al, byte ptr [si]
        mov  byte ptr [di], al
        inc  si
        inc  di
        loop fixfile1
ff2:    lea  si, dos_filespec
        ret     
dos_filespec db 11 dup(20h),0
fix_filename endp

remove_filedot proc far
         mov  al, ' '
         mov  byte ptr [di+7], al    ; remove the dot
         ret
remove_filedot endp

; ===========================================================================
FS_OPEN proc far
; Input : ES:SI = *filename,0
;         AX    = file mode
; Output: CF    = NZ successful 
; ===========================================================================
           clc

           ret
FS_OPEN endp

; ===========================================================================
FS_CLOSE proc far
; Input : AX = FileHandleIndex
; Output: CF = NZ successful
; ===========================================================================
           clc
           ; release filehandle, return 1 for success, 0 failure
           ret
FS_CLOSE endp

; ===========================================================================
FS_READ proc far
; Input : ES:DI = *buffer
;         AX    = filehandleindex
;         CX    = buffer size
; Output: AX    = lower AX contains byte read, if CF = NZ
; ===========================================================================
           clc
           xor ax, ax
           ; read length of bytes from file with handle and store in buffer
           ; null terminate the buffer.
           ; advance the filepointer, as your read.
           ; return number of bytes successfully read in CX or -1 for fail
           ; if already at eof then return CX = 0
           ret
FS_READ endp

; ===========================================================================
FS_WRITE proc far
; Input : AX    = Filehandle
;         ES:SI = *buffer
;         CX    = size
; ===========================================================================
           clc
           xor ax, ax
           ; write len of bytes from buffer to filehandle in overwrite mode.
           ; return bytes successfully written
           ; always write forward from current file position
           ; if number of bytes written exceeds diskspacefree then dont write
           ; to disk just return error, -1
           ret
FS_WRITE endp

; ===========================================================================
FS_SEEK proc far
; Input : AX = filehandle
;         CX = location
; ===========================================================================
           clc
           ; advance filepointer to new location from beginning of file
           ; if new location is beyond the end of file, and not in read mode
           ; then enlarge the file to new size
           ; remember to fill in any new bytes allocated to file (20h is good
           ; choice)
           ; if seeking will go beyond available disk then don't move the
           ; pointer al all, return error code
           ret
FS_SEEK endp

FS_FLUSH proc far
; Flush file buffer to disk

         ret
FS_FLUSH endp

FS_CHSIZE proc far
; extend or truncate a file 

         ret
FS_CHSIZE endp

FS_TRUNCATE proc far
; truncate a file

         ret
FS_TRUNCATE endp

; File management
FS_FSTAT proc far
; Obtain statistics on open file

         ret
FS_FSTAT endp

FS_GETATTRIB proc far
; get file attributes

         ret
FS_GETATTRIB endp

FS_MV proc far
; rename a file or directory

         ret
FS_MV endp

FS_SETATTRIB proc far
; Set file attributes

         ret
FS_SETATTRIB endp

FS_UNLINK proc far
; Delete file

         ret
FS_UNLINK endp

; Directory Management

FS_DELTREE proc far
; truncate directory tree 
     ret
FS_DELTREE endp

FS_GET_CWD proc far
; get current working directory
   ret
FS_GET_CWD endp

FS_GDONE proc far
; free gnext and gfirst resources
        _save
        lea  di, FCB_bDrvId
        mov  cx, FCB_SIZE2
        mov  bl, 20h
        call fillarray
        _restore
    ret
FS_GDONE endp

FS_SEARCH  proc far
; DI = FILENAME.EXT
; return first entry in a directory matching specification
        call FS_GDONE
        mov  si, di
        call fix_filename
        mov  di, si
        ;
        mov  ax, FAT12_mounted
        or   ax, ax
        jz   FS_GF_TF16
        push cs
        pop  es
        push di
        mov  si, offset FAT12_ROOT
        call cs:FAT12_findfile
        jc   FS_GF_XX
        clc
        mov  FCB_Cluster, ax
        mov  FCB_Attrib, bl
        mov  FCB_rTime, cx
        mov  FCB_rDate, dx
        mov  word ptr FCB_lFilesize+2, si
        mov  word ptr FCB_lFilesize, di
        mov  al, FL_Drive
        mov  FCB_bDrvId, al
        pop  si
        lea  di, FCB_abName
        mov  cx, 8
        rep  movsb
        lea  di, FCB_abExt 
        mov  cx, 3
        rep  movsb
        lea  si, FCB_bDrvID
        mov  cx, 40
        jmp  FS_GF_X
FS_GF_TF16:
        mov  ax, 0
    ;   mov  ax, FAT16_mounted
        or   ax, ax
        jz   FS_GF_X
        ; search fat16 root
FS_GF_XX:
        stc
FS_GF_X:
        ret
FS_SEARCH endp

FS_ISDIR proc far
; test if path is directory
        ret
FS_ISDIR endp

FS_MKDIR proc far
        ret
FS_MKDIR endp

FS_PWD   proc far
; return to current working directory
        ret
FS_PWD   endp

FS_RMDIR proc far
        ret
FS_RMDIR endp

FS_SET_CWD proc far
; set current working directory
        ret
FS_SET_CWD endp

; Disk management

FS_CLUSTER_SIZE proc far
; disks cluster size
        ret
FS_CLUSTER_SIZE endp

FS_DISKABORT proc far
; Abort all operations with out modifying disk
        ret
FS_DISKABORT endp

FS_DISKFLUSH proc far
; Flush FAT and all files to disk
        ret
FS_DISKFLUSH endp

FS_FORMAT    proc far
        ret
FS_FORMAT    endp

FS_FREE      proc far
        ret
FS_FREE      endp

FS_GETDEFDRVNO proc far
        mov  al, FS_Drive
        ret
FS_GETDEFDRVNO endp

FS_ISVOL       proc far
ret
FS_ISVOL       endp

FS_SET_DEFAULTDRIVE proc far
ret
FS_SET_DEFAULTDRIVE endp

FS_STAT proc far
ret
FS_STAT endp     

FS_WRITEPROT   proc far
; Write protected disk? 
ret
FS_WRITEPROT   endp

; Contiguous I/O functions

FS_GET_FILE_EXTENTS proc far
; get the list of clusters that make up a file

           ret
FS_GET_FILE_EXTENTS endp

FS_GET_FREE_LIST proc far
; LIST OF FREE CLUSTERS ON DRIVE

         ret
FS_GET_FREE_LIST endp

FS_RAW_READ proc far

          ret
FS_RAW_READ endp

FS_RAW_WRITE proc far

          ret
FS_RAW_WRITE endp

FS_EXTEND_FILE proc far

              ret
FS_EXTEND_FILE endp

IOCtrl proc far
; AX = Command
; BX = Parameter

          ret
IOCtrl endp

sectorwrite proc far
; ES:BX = pRAMAddr
;    AX = StartSector
;    CX = How Many Sectors
        mov  di, cx
        call writeDisk
           ret
sectorwrite endp

sectorread proc far
; ES:BX = pRAMAddr
;    AX = StartSector
;    CX = How Many Sectors
        mov  di, cx
        call readDisk
           ret
sectorread endp

diskclose proc far
         mov  ax, FAT12_mounted
         or   ax, ax
         jz   dc_try_FAT16
         mov  dl, FS_Drive
         call FAT12_unmount
         mov  ax, 12
         clc
         jmp  diskclose1
dc_try_FAT16:
         mov  ax, 0
      ;  mov  ax, FAT16_mounted
         or   ax, ax
         jz   diskclose_Err
         mov  dl, FS_Drive
      ;  call FAT16_unmount
         mov  ax, 16
         clc
         jmp  diskclose1
diskclose_Err:
         stc
diskclose1:
         ret
           ret
diskclose endp

diskopen proc far
         push dx
         call FAT12_Mount
         pop  dx
         jc   do_try_FAT16
         mov  FS_Drive, dl
         mov  ax, 12
         clc
         jmp  diskopen1
do_try_FAT16:
       ;  call FAT16_Mount
         jc   diskopen_Err
         mov  FS_Drive, dl
         clc
         mov  ax, 16
         jmp  diskopen1
diskopen_Err:
         stc
diskopen1:
         ret
diskopen endp

driverrelease proc far

           ret
driverrelease endp

driverinit proc far

           ret
driverinit endp

; INITIALIZATION
; DIRECTORY MANAGEMENT
; HELPER FUNCTIONS
; BLOCK BUFFERING
; STRING PROCESSING




