uses
  HwSyst,
  NumToStr,
 {$ifdef Kit188}
  Crt2Mem, {obsluhy Video a Keyboard BIOSu pro komunikaci na KitXxx}
  ChnVirt, {knihovna virtualniho komunikacniho kanalu}
  Chn188,  {knihovna vlastniho komunikacniho kanalu pro systemovy COM Kit188}
  ChnCrt,  {komunikacni protokol pro prenos Video a Keyboard}
  CrtComSl,{komunikacni automat pro prenos Video a Keyboard}
 {$endif}
  Crt,
  CFlash,
  CrtWin2;

const
  RectWInfo : TRect   = (X:  2; Y:  3; W: 45; H: 13);
  RectWEdit : TRect   = (X: 49; Y:  3; W: 31; H: 13);
  RectWData : TRect   = (X:  2; Y: 18; W: 78; H: 32);
  WinInfo   : PCrtWin = nil;
  WinEdit   : PCrtWin = nil;
  WinData   : PCrtWin = nil;
  Key       : char    = #0;

type
  pAByte = ^tAByte;
  tAByte = array[0..16383]of byte;
const
  CFObj     : tCFlash = ();   {objekt pro pristup k jednomu souboru CF}
  AddrForRW : longint = 0;    {linearni adresa pro cteni/zapis z/do CF}
  LenForRW  : word    = 512;  {delka ctenych/zapisovanych dat}
  DataBuff  : pAByte  = nil;  {buffer pro ctena/zapisovana data}

  AsciiView : boolean = False;{priznak ASCII zobrazitelnych znaku}
  Res       : word    = 0;    {pro navratovy kod chyby CF operaci}

var
 {pomocne}
  I         : word;
  B         : byte;
  S         : tString24;

const
  ResCF_Str : array[0..10] of string[15] =
        {123456789012345}
   ({ 0}'Ok',
    { 1}'NoCF       ',
    { 2}'FormatCFErr',
    { 3}'NoLinFile  ',
    { 4}'LinFileErr ',
    { 5}'RWOverflow ',
    { 6}'ReadErr    ',
    { 7}'WriteErr   ',
    { 8}'VerifyErr  ',
    { 9}'???',
    {10}'Busy');

procedure WriteInfo;
begin
  with WinInfo^ do
  begin
   LockWin;
    ClrScr;
    HiddenCursor;
    writeln('Compact Flash size: ',CFSize,'B = (',CFSize shr 20,'MB)');
    writeln('Lin.space max.size: ',CFObj.CFGetFileSize,'B = (',CFObj.CFGetFileSize shr 20,'MB)');
    writeln;
    writeln('Commands:');
    writeln(' <A> Address for R/W = $',LongintStrHex(AddrForRW));
    writeln(' <L> Length  for R/W = $',WordStrHex(LenForRW),' = ',LenForRW:4,'B');
    writeln(' <V> Verify after write= ',CFObj.CF_VerifyWr:5);
    write  (' <H> Hex/Ascii data view= ');if AsciiView then writeln('ASCII') else writeln('HEX  ');
    writeln(' <R> Read from CF');
    writeln(' <1> Write to CF "$00 $00 $00 ... $00"');
    writeln(' <2> Write to CF "$00 $01 $02 ... $FF"');
    writeln(' <3> Write to CF "$00 $11 $22 ... $FF"');
    write  (' <Esc> Exit');
   UnLockWin;
  end;
end;

function ReadStr:tString24;
var Key:char;
    S:tString24;
    X:byte;
begin
  S:='';
  X:=WhereX;
  repeat
    if keypressed then
    begin
      Key:=UpCase(Readkey);
      if Key in ['0'..'9','A'..'F','$'] then S:=S+Key;
      if Key=#$8{BackSpace} then Delete(S,Length(S),1);
      gotoxy(X,WhereY);
      write(S);
    end
    else
    begin
      Key:=#0;
    end;
   {$ifdef Kit188}
    CrtComMake;
   {$endif}
  until (Key=#$1B{Esc})or
        (Key=#$0D{Enter});
  if Key=#$1B then
       ReadStr:=''
  else ReadStr:=S;
end;

var
  SaveExit:pointer;
procedure MyExitProc; far;
begin
  ExitProc:=SaveExit;
  if ExitCode<>0 then
  begin
    write('RunTime Error ',ExitCode,' on addr ',PtrToStr(ErrorAddr));
   {$ifdef Kit188}
    CrtComAllChanges;
   {$endif}
  end;
end;

Begin
 {$ifdef Kit188}
  if InitCrtCom('NAM=CRT MAS=SLAVE LSB=400 '+
                'NAM=188 BD=115200 PAR=E STO=1 LRB=500') <> res_Ok then RunError(10);
 {$endif}

  SaveExit:=ExitProc;
  ExitProc:=@MyExitProc;


  New(DataBuff);
  TextMode(CO80+Font8x8);
  TextAttr:=White;
  CrtInit;
  MainWin^.HiddenCursor;
  write('                   * * *  Test knihovny CFlash  * * *');
  WinInfo:=New(PCrtWin,Init(RectWInfo,' CF Info ',FrameD,
               LightGray, LightGray, LightGray, $20, 0));
  Res:=CFObj.CFInit('linear.dat');
  if Res<>resCF_Ok then
    writeln('File Init Error: ',ResCF_Str[Res]);
  WriteInfo;
  WinEdit:=New(PCrtWin,Init(RectWEdit,' Edit ',FrameD,
               LightGray, LightGray, LightGray, $20, 0));
  with WinEdit^ do
  begin
   LockWin;
   ClrScr;
   SetCursor(7,8);
   UnLockWin;
  end;
  WinData:=New(PCrtWin,Init(RectWData,' CF R/W Data ',FrameD,
               LightGray, LightGray, LightGray, $20, 0));
  with WinData^ do
  begin
   LockWin;
    ClrScr;
    HiddenCursor;
   UnLockWin;
  end;

  repeat
    if keypressed then
    begin
      Key:=UpCase(Readkey);
      case Key of
        'A':with WinEdit^ do
            begin
             LockWin;
              writeln('Enter address [0..',High(longint) div 512,']: ');
              S:=ReadStr;
              writeln;
              if S<>'' then
                Val(S,AddrForRW,I);
             UnLockWin;
            end;
        'L':with WinEdit^ do
            begin
             LockWin;
              writeln('Enter length [1..768]: ');
              S:=ReadStr;
              writeln;
              if S<>'' then
                Val(S,LenForRW,I);
             UnLockWin;
            end;
        'V':begin
              with CFObj do
              CFSetVerify(not CF_VerifyWr);
            end;
        'H':begin
              AsciiView:=not AsciiView;
            end;
        'R':begin
             WinData^.LockWin;
              Res:=CFObj.CFRead(AddrForRW,DataBuff,LenForRW);
              writeln;
              writeln;
              if Res<>resCF_Ok then
                writeln('Read Error: ',ResCF_Str[Res])
              else
              begin
                ClrScr;
                writeln('Read Ok');
                writeln;
                for I:=0 to LenForRW-1 do
                  if I>=768 then Break
                  else
                    if AsciiView and
                       (DataBuff^[I] in [$20..$7F])then
                    begin
                      TextAttr:=LightRed;
                      write(' ',Chr(DataBuff^[I]),' ');
                      TextAttr:=LightGray;
                    end
                    else
                      write(' ',ByteStrHex(DataBuff^[I]));
              end;
             WinData^.UnLockWin;
            end;
        '1':begin
              FillChar(DataBuff^,SizeOf(DataBuff^),$00);
             WinData^.LockWin;
              Res:=CFObj.CFWrite(DataBuff,AddrForRW,LenForRW);
              writeln;
              writeln;
              if Res<>resCF_Ok then
                writeln('Write Error: ',ResCF_Str[Res])
              else
                writeln('Write Ok');
             WinData^.UnLockWin;
            end;
        '2':begin
              for I:=0 to SizeOf(DataBuff^)-1 do
                DataBuff^[I]:=Lo(I);
             WinData^.LockWin;
              Res:=CFObj.CFWrite(DataBuff,AddrForRW,LenForRW);
              writeln;
              writeln;
              if Res<>resCF_Ok then
                writeln('Write Error: ',ResCF_Str[Res])
              else
                writeln('Write Ok');
             WinData^.UnLockWin;
            end;
        '3':begin
              B:=$00;
              for I:=0 to SizeOf(DataBuff^)-1 do
              begin
                DataBuff^[I]:=B;
                if B<>$FF then
                     Inc(B,$11)
                else B:=$00;
              end;
             WinData^.LockWin;
              Res:=CFObj.CFWrite(DataBuff,AddrForRW,LenForRW);
              writeln;
              writeln;
              if Res<>resCF_Ok then
                writeln('Write Error: ',ResCF_Str[Res])
              else
                writeln('Write Ok');
             WinData^.UnLockWin;
            end;
      end; {case Key}
      WriteInfo;
    end
    else
    begin
      Key:=#0;
    end;
   {$ifdef Kit188}
    CrtComMake;
   {$endif}
  until Key=#$1B{Esc};
  Dispose(DataBuff);
End.
