Package PCTools \Floppy only\

Uses KbdCRT,Partition,Dir,Files

\DirPiece as Array[1..&H800/Size(DirEntry)] Of DirEntry\
NoSectDirPiece,EntriesPerDirPiece,OfsInDirPiece as Word

Def IsValid(D as @DirEntry) as Byte
Enter
  If D.Name[1]=0 Or
     D.Name[1]='ö' Or
     D.Name[1]='å'
  Then
    Result=0
  Else
    Result=1;
Leave

Sub LPrintDirEntry(Li as Word,D as @DirEntry)
Enter
  Locate Li,1
  If IsValid(D)=1 And D.Attr&8=0 Then
    PrintS "  "
    PrintDirEntry D
    PutCar ' '
    If High(D.Size)=0 Then PrintS "    ":PrintX D.Size
                      Else PrintLX D.Size;
    PutCar ' ':PrintX D.First
  Else
    PrintS "  ~"
  End
Leave

Sub PrintDirPiece(Li0,Li1 as Word)
  I as Word
Enter
  SetColor 14
  For I=Li0 To Li1 Do
     If OfsInDirPiece+I-Li0-1<EntriesPerDirPiece Then
       LPrintDirEntry I,DirPiece[OfsInDirPiece+I-Li0];
Leave

Sub ReadFirstDirClus
Enter
  EntriesPerDirPiece=SizeCluster/Size(DirEntry)
  NoSectDirPiece=CurDirBeg
  ReadDirClus DirPiece,NoSectDirPiece
  OfsInDirPiece=1
Leave

VolName as DirEntry
HasVolName as Byte
DriveName as Byte
D as @DirEntry

Sub ResetDrive(Drive as Byte)
  I as Word
Enter
  If Drive='A' Then SetDrive 0
  Else
  If Drive='B' Then SetDrive 1 Else SetDrive &H80;
  DriveName=Drive
  ReadFirstDirClus
  HasVolName=0
  For I=1 To EntriesPerDirPiece Do
     @D=@DirPiece[I]
     If IsValid(D)=1 And D.Attr&8<>0 Then
       I=EntriesPerDirPiece
       Move(D.Name,VolName.Name,8)
       Move(D.Ext,VolName.Ext,3)
       HasVolName=1
     End
  Next
Leave

LiCour,Touche,HomeLi,BottomLi as Word
Refresh,RefreshLiCour as Byte

Sub ScrollUp(Li0,Li1 as Word)
Enter
  MovSB(Pointer(High(@Screen),Low(@Screen)+Li0*2*NbCol),
        Pointer(High(@Screen),Low(@Screen)+(Li0-1)*2*NbCol),
        (Li1-Li0)*NbCol*2
       )
  StoSW(Pointer(High(@Screen),Low(@Screen)+(Li1-1)*NbCol*2),(Color,' '),NbCol)
Leave

Sub ScrollDown(Li0,Li1 as Word)
Enter
  MovSB(Pointer(High(@Screen),Low(@Screen)+(Li0-1)*2*NbCol),
        Pointer(High(@Screen),Low(@Screen)+Li0*2*NbCol),
        (Li1-Li0)*NbCol*2
       )
  StoSW(Pointer(High(@Screen),Low(@Screen)+(Li0-1)*NbCol*2),(Color,' '),NbCol)
Leave

Sub Clear(Li0,Li1 as Word)
Enter
  StoSW(Pointer(High(@Screen),Low(@Screen)+(Li0-1)*NbCol*2),
        (Color,' '),
        (Li1-Li0+1)*NbCol
       )
Leave

Const
     SizBuf=30000
Var
   Buf as Array[0..SizBuf] Of Byte

Sub TypeBuffer(Li0,Li1,Size as Word)
  I,J as Word
  YouGet as Byte
Enter
  YouGet=1
  Clear Li0,Li1
  Locate Li0,1
  Buf[Size]='ê'
  J=1:For I=0 To Size-1 Do
    If (I<>Size And Buf[I]=&H0D And Buf[I+1]=&H0A) Or Buf[I]=&H0A Or Col=NbCol
    Then
      J+=1
      If (I<>Size And Buf[I]=&H0D And Buf[I+1]=&H0A) Then I+=1;
      If Li<Li1 Then
        Locate Li+1,1
      Else
        ScrollUp Li0,Li1
        Locate Li1,1
      End
      If J=Li1-Li0+1 Then
        J=1:Locate Li1,1
        Color=10:PrintS "-- Pressez une touche --":Color=14
        If GetCar()=27 Then I=Size:YouGet=0;
        ScrollUp Li0,Li1
        Locate Li1,1
      End
    Else
      If Buf[I]='	' Then
        If Col+8>NbCol Then
        Begin
          While Col<>NbCol Do PutCar ' ';
        Else
          PrintS "        "
        End
      Else
        PutCar Buf[I]
      End
    End
  Next
  SetColor 9:PutCar Buf[I]
  If YouGet=1 Then GetCar;
Leave

F as File
N as LongWord
CurMode as Byte

Enter
  SetCRTMode CurMode=1
  ResetDrive 'A'
  Refresh=RefreshLiCour=1
  Always
    If Refresh=1 Then
      ClearScreen
      HomeLi=1:BottomLi=NbLig
      If RefreshLiCour=1 Then RefreshLiCour=0:LiCour=HomeLi+1;
      SetColor 12
      Locate HomeLi,1:PutCar 4:PrintS " Drive ":PutCar DriveName
      If HasVolName=1 Then
      Begin
        PutCar ':'
        For N=1 To 8 Do PutCar VolName.Name[Low(N)];
        For N=1 To 3 Do PutCar VolName.Ext[Low(N)];
      End
      SetColor 12
      Locate BottomLi,1:PutCar 4:PrintS " BOS disk tool, ver 1.00"
      PrintDirPiece(HomeLi+1,BottomLi-1)
      Refresh=0
    End
    Locate LiCour,1
    Touche=GetCar()
  AWhile
    Touche<>27 Do
  Begin
    If Touche=&H4800 Then \ UP \
      LiCour-=1
      If LiCour=HomeLi Then
        LiCour+=1
        If OfsInDirPiece=1 Then
          If NoSectDirPiece<>CurDirBeg Then
            N=CurDirBeg
            While NextDirSect(N)<>NoSectDirPiece Do N=NextDirSect N;
            NoSectDirPiece=N
            ReadDirClus DirPiece,NoSectDirPiece
            OfsInDirPiece=1
            Refresh=RefreshLiCour=1
          End
        Else
          OfsInDirPiece-=1
          ScrollDown(HomeLi+1,BottomLi-1)
          LPrintDirEntry LiCour,DirPiece[OfsInDirPiece]
        End
      End
    Else
    If Touche=&H5000 Then \ DOWN \
      LiCour+=1
      If LiCour=BottomLi Or OfsInDirPiece+LiCour-HomeLi-2>=EntriesPerDirPiece
      Then
        LiCour-=1
        If OfsInDirPiece+LiCour-HomeLi+1>=EntriesPerDirPiece Then
          N=NextDirSect NoSectDirPiece
          If N&FatMask<>FatMask Then
            NoSectDirPiece=N
            ReadDirClus DirPiece,NoSectDirPiece
            OfsInDirPiece=1
            Refresh=RefreshLiCour=1
          End
        Else
          OfsInDirPiece+=1
          ScrollUp(HomeLi+1,BottomLi-1)
          LPrintDirEntry LiCour,DirPiece[OfsInDirPiece+LiCour-HomeLi-1]
        End
      End
    Else
    If Touche=&H4700 Then \ HOME \
      OfsInDirPiece=1
      Refresh=RefreshLiCour=1
    Else
    If Touche=&H4F00 Then \ END \
      If EntriesPerDirPiece>BottomLi-HomeLi-2 Then
        OfsInDirPiece=EntriesPerDirPiece-BottomLi+HomeLi+2
        LiCour=BottomLi-1
        Refresh=1
      Else
        LiCour=HomeLi+EntriesPerDirPiece
      End
    Else
    If Touche=13 Then \ CR \
      @D=@DirPiece[OfsInDirPiece+LiCour-HomeLi-1]
      If IsValid(D)=1 And D.Attr&8=0 Then
        If D.Attr&&H10<>0 Then \ DIR \
          ChDir(String(@D.Name-1),String(@D.Ext-1))
          LiCour=HomeLi+1
          ReadFirstDirClus
          LiCour=HomeLi+1
          Refresh=1
        Else \ FIC \
          Open(F,String(@D.Name-1),String(@D.Ext-1),0)
          If D.Size>SizBuf Then N=SizBuf Else N=D.Size;
          Read(F,Buf,N)
          TypeBuffer(HomeLi+1,BottomLi-1,N)
          Refresh=1
        End
      End
    Else
    If Touche='A' Or Touche='a' Then
      ResetDrive 'A'
      LiCour=HomeLi+1
      Refresh=1
    Else
    If Touche='B' Or Touche='b' Then
      ResetDrive 'B'
      LiCour=HomeLi+1
      Refresh=1
    Else
    If Touche='C' Or Touche='c' Then
      ResetDrive 'C'
      LiCour=HomeLi+1
      Refresh=1
    Else
    If Touche='M' Or Touche='m' Then
    Begin
      If CurMode=2 Then CurMode=-1;
      SetCrtMode CurMode+=1
      Refresh=RefreshLiCour=1
    End;
  Wend
  Locate NbLig,1
  PrintCR
Leave