Package Dir

Uses KbdCRT,Error,Partition

Interface

Type
    NameType is Array[1..8] Of Byte
    ExtType is Array[1..3] Of Byte
    Record DirEntry is
      Name as NameType
      Ext as ExtType
      Attr as Byte
      Reserved as Array[1..10] Of Byte
      Time,Date as Word
      First as Word \ 1st cluster du file \
      Size as LongWord
    End

Const
     AttrDir=&H10

Sub PrintMask(M as Byte)
Sub PrintDirEntry(D as @DirEntry)
Def NextDirSect(No as Word) as Word
Sub ReadDirClus(B as Reference,No as Word)
Sub WriteDirClus(B as Reference,No as Word)
Var
   DirPiece as Array[1..&H800/Size(DirEntry)] Of DirEntry
   NoDirPieceSect,IndLastFile as Word
Def FindFile(D as @DirEntry; Name,Ext as String) as Word
Def CreateFile(D as @DirEntry; Name,Ext as String) as Word
Sub ChDir(Name,Ext as String)

Implementation

Var
   Mask as Array[0..&HF] Of Word
   CharTag as Array[0..&H7] Of Byte

Sub PrintMask(M as Byte)
Var
   B as Byte
Enter
  For B=0 To 5 Do
     If M & Mask[5-B]<>0 Then PutCar CharTag[5-B] Else PutCar ' ';
Leave

Sub PrintDirEntry(D as @DirEntry)
  I as Word
Enter
  For I=1 To 8 Do PutCar D.Name[I];:PutCar ' '
  For I=1 To 3 Do PutCar D.Ext[I];:PutCar ' '
  PrintMask(D.Attr)
Leave

Def StrNCmp(A,B as Pointer; N as Word) as Byte
  S1,S2 as String
  I as Word
Enter
  @S1=A:@S2=B
  Result=1
  For I=0 To N-1 Do If S1[I]<>S2[I] Then Result=0;
Leave

Sub StrNCpy(A,B as Pointer; N as Word)
  S1,S2 as String
  I as Word
Enter
  @S1=A:@S2=B
  For I=0 To N-1 Do S1[I]=S2[I];
Leave

Def NextDirSect(No as Word) as Word
Enter
  If CurDirBeg=0 Then
    If No+SectPerClus>=(NbEntriesRootDir*Size(DirEntry))/SizeSector Then
      Result=FATMask
    Else
      Result=No+SectPerClus
    End
  Else
    Result=FATNext(No)
  End
Leave

Sub ReadDirClus(B as Reference,No as Word)
Enter
  If B=@DirPiece Then NoDirPieceSect=No:IndLastFile=0;
  If CurDirBeg=0 Then
    ReadAbsSect(B,RootDirBeg+No,SectPerClus)
  Else
    ReadCluster(B,No-2)
  End
Leave

Sub WriteDirClus(B as Reference,No as Word)
Enter
  If CurDirBeg=0 Then
    WriteAbsSect(B,RootDirBeg+No,SectPerClus)
  Else
    WriteCluster(B,No-2)
  End
Leave

Def FindFile(D as @DirEntry; Name,Ext as String) as Word
  SectNo as Word
  I as Int
Enter
  Result=0
  SectNo=CurDirBeg
  While SectNo&FATMask<>FATMask Do
    ReadDirClus(DirPiece,SectNo)
    NoDirPieceSect=SectNo
    SectNo=NextDirSect(SectNo)
    For I=1 To SizeCluster/Size(DirEntry) Do
      If DirPiece[I].Name[1]=0 Or DirPiece[I].Name[1]='ö' Then
        IndLastFile=0
        I=SizeCluster/Size(DirEntry)
        SectNo=FATMask
      Else
        If DirPiece[I].Name[1]<>'å' And
           StrNCmp(@DirPiece[I].Name,@Name+1,8)<>0 And
           StrNCmp(@DirPiece[I].Ext,@Ext+1,3)<>0
        Then
          Result=1
          MovSB0(@DirPiece[I],@D,Size(DirEntry))
          IndLastFile=I
          I=SizeCluster/Size(DirEntry)
          SectNo=FATMask
        End
      End
    Next
  Wend
Leave

Def CreateFile(D as @DirEntry; Name,Ext as String) as Word
  SectNo as Word
  I as Int
Enter
  Result=0
  SectNo=CurDirBeg
  While SectNo&FATMask<>FATMask Do
    ReadDirClus(DirPiece,SectNo)
    NoDirPieceSect=SectNo
    SectNo=NextDirSect(SectNo)
    For I=1 To SizeCluster/Size(DirEntry) Do
      If DirPiece[I].Name[1]=0 Or
         DirPiece[I].Name[1]='ö' Or
         DirPiece[I].Name[1]='å'
      Then
        StrNCpy(@DirPiece[I].Name,@Name+1,8)
        StrNCpy(@DirPiece[I].Ext,@Ext+1,3)
        DirPiece[I].Size=0
        DirPiece[I].Attr=&H20
        DirPiece[I].Time=0
        DirPiece[I].Date=0
        DirPiece[I].First=0
        Result=1
        WriteDirClus(DirPiece,NoDirPieceSect)
        MovSB0(@DirPiece[I],@D,Size(DirEntry))
        IndLastFile=I
        I=SizeCluster/Size(DirEntry)
        SectNo=FATMask
      End
    Next
  Wend
Leave

Sub ChDir(Name,Ext as String)
Var
   D as DirEntry
   W,Result as Word
Enter
  Result=FindFile(D,Name,Ext)
  If Result=1 Then
    If D.Attr&AttrDir<>0 Then
      CurDirBeg=D.First
    Else
      Result=0
    End
  End
  If Result=0 Then Error "ChDir";
Leave

I,J as Word

Enter
\ Init CharTag \
  CharTag[0]='r':CharTag[1]='h':CharTag[2]='å':CharTag[3]='V'
  CharTag[4]='ë':CharTag[5]='à':CharTag[6]='_':CharTag[7]='_'
\ Init Mask \
  J=1:For I=0 To &HF Do Mask[I]=J<<I;
  PrintS "Dir start done":PrintCR
Leave