home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / tpdoskermit.zip / kermit.inc < prev    next >
Text File  |  1991-04-18  |  15KB  |  644 lines

  1. (******************* KERMIT.INC ************************)
  2.  
  3. CONST
  4.   MaxY = 25;
  5.   LenModulo = 95;
  6.  
  7. CONST
  8.  
  9.     ErrorLevel : WORD = 0;
  10.     SendDelay : WORD = 0;
  11.     FileNameSet : SET OF CHAR =
  12.       ['!','#'..')','-','.','0'..':','@'..'Z','\','^'..'z','~'];
  13.  
  14. VAR
  15.     InnConvert, UtConvert : ARRAY [CHAR] OF CHAR;
  16.  
  17. VAR t2, MaxServer : TimerTableRec;           {Br vre global!}
  18.     DTA : SearchRec;
  19.     FTime : DateTime;
  20.     MaxPrTick : WORD;
  21.  
  22. CONST
  23.     KermitBufSize : WORD = $F000;
  24.  
  25. CONST
  26.   Qrep        : BOOLEAN = TRUE;
  27.   Q8Bit       : BOOLEAN = TRUE;
  28.   ServerTimeOut : BOOLEAN = FALSE;
  29.   RetryLimit  : BYTE =  10;
  30.   YourTimeOut : BYTE =  15;
  31.   SendTimeOut : BYTE =   5;
  32.   MyPad      : BYTE = 0;
  33.   MyPadChar  : CHAR = ^@;
  34.   YourPad    : BYTE = 0;
  35.   YourPadChar: CHAR = ^@;
  36.  
  37. TYPE
  38.   CharArray = ARRAY [1..9040] OF CHAR;
  39.   CarNum    = 0..222;
  40.   IBM_Type  = 0..2;
  41.   UnCarCh   = ' '..#254;
  42.   PakkeCh   = '@'..'Z';
  43.   PakkeType = RECORD
  44.     TotLen: WORD;
  45.     long  : BOOLEAN;
  46.     plen  : CHAR;
  47.     pnr   : UnCarCh;
  48.     ptype : PakkeCh;
  49.     CASE BOOLEAN OF
  50.        TRUE : (plen1,
  51.               plen2,
  52.               hchk  : CHAR);
  53.       FALSE : (pdata : CharArray);
  54.     END;
  55.   PakkeTypePtr = ^PakkeType;
  56.  
  57. TYPE
  58.   PacketWindow = RECORD
  59.     retry : WORD;
  60.     dptr  : ^PakkeType;
  61.     CASE BYTE OF
  62.       0 : (acked, nacked : BOOLEAN);
  63.       1 : (acknack : WORD);
  64.     END;
  65.  
  66.   FilBuffer = ARRAY [0..$F000] OF CHAR;
  67.   BufferPtr = ^FilBuffer;
  68.  
  69. VAR
  70.   nr, i, n, ninn, nut : WORD;
  71.   pw : ARRAY [0..63] OF PacketWindow;
  72.   LongReply, DiskError : BOOLEAN;
  73.  
  74.   StopFile, AttrPakke : BOOLEAN;
  75.   fil   : FILE;
  76.   YourMaxLength, RetryNr, LastNr, PakkeNr,
  77.   CheckType, FeilNr, PacketDelay : WORD;
  78.   BufSize, BufCount, MaxRep : WORD;
  79.   Bytes : LongInt;
  80.   buffer : BufferPtr;
  81.   BufPtr : ^CHAR;
  82.   FileMax, TotalNr : LongInt;
  83.   ShowTimeOut, EndOfFile : BOOLEAN;
  84.   OriginalName, FileName, ErrorString, DownLoadPath,
  85.   StatusString : String[80];
  86.   RX_Pac, TX_Pac, Next_Pac : PakkeTypePtr;
  87.   Next_Data_OK : BOOLEAN;
  88.   RepQ, Bit8Q : CHAR;
  89.   st : String;
  90.  
  91. TYPE DupHandleType = (RenameFile, OverWriteFile, SkipFile);
  92.  
  93. (**********************************************************************)
  94. (*         Here are all variables that can be stored on disk:         *)
  95. (**********************************************************************)
  96.  
  97. CONST
  98.   Versjon : String[4] = 'V0.1';
  99.  
  100.   DupHandle : DupHandleType = RenameFile;
  101.   OldDupHandle : DupHandleType = SkipFile;
  102.   NewDupHandle : DupHandleType = OverWriteFile;
  103.  
  104.   CurBaud      : LongInt       =115200;
  105.   CurBits      : WORD          =     8;
  106.   CurStop      : WORD          =     1;
  107.   CurParity    : ParityType    = No_Parity;
  108.   CurComPort   : WORD          =     1;
  109.  
  110.   LongMaxLength: WORD          =  9020;
  111.   WinSize      : WORD          =    31;
  112.   MyTimeOut    : WORD          =    12;
  113.   ServerTime   : WORD          =     0;
  114.  
  115.   LongPakke    : BOOLEAN       =  TRUE;
  116.   WindowData   : BOOLEAN       = FALSE;
  117.   TextFile     : BOOLEAN       = FALSE;
  118.   IBM_Mode     : IBM_Type      =     0;
  119.   BinaryData   : BOOLEAN       =  TRUE;
  120.   FileCheck    : BYTE          =     2;
  121.  
  122.   MySOH        : CHAR          =    #1;
  123.   YourSOH      : CHAR          =    #1;
  124.   MyCR         : CHAR          =   #13;
  125.   YourCR       : CHAR          =   #13;
  126.   MyQCtrlChar  : CHAR          =   '#';
  127.   YourQCtrlChar: CHAR          =   '#';
  128.   Q8bitChar    : CHAR          =   '&';
  129.   QrepChar     : CHAR          =   '~';
  130.  
  131.   KermitAttr   : BYTE          =     0;
  132.   MenuAttr     : BYTE          =     0;
  133.   FieldAttr    : BYTE          =     0;
  134.   SaveEdit     : BYTE          =     0;
  135.   DirVideo     : BOOLEAN       =  TRUE;
  136.  
  137.   Marker_Byte  : BYTE          =     0;
  138.  
  139. (**********************************************************************)
  140. (*             Slutt p setup-variable!                               *)
  141. (**********************************************************************)
  142.  
  143.   DupString : ARRAY[DupHandleType] OF FeltStr =
  144.        ('Rename','OverWrite','Skip');
  145.   BinText : ARRAY [BOOLEAN] OF FeltStr = ('BIN','TEXT');
  146.   Std_IBM : ARRAY [IBM_Type] OF FeltStr = ('Std','I-E','IBM');
  147.   ParityStr : ARRAY [ParityType] OF FeltStr =
  148.       ('NONE','EVEN','ODD','MARK','SPACE');
  149.  
  150. PROCEDURE SplitFileName(fn : String; VAR drive,path,name,ext : String);
  151. VAR e : WORD;
  152. BEGIN
  153.   e := Pos(':',fn);
  154.   drive := '';
  155.   IF e > 0 THEN BEGIN
  156.     IF e = 2 THEN drive := Copy(fn,1,2);
  157.     Delete(fn,1,e);
  158.   END;
  159.  
  160.   e := Length(fn);
  161.   ext := '';
  162.   WHILE (e > 0) AND (fn[e] <> '.') AND (fn[e] <> '\') DO Dec(e);
  163.   IF (e > 0) AND (fn[e] = '.') THEN BEGIN
  164.     ext := Copy(fn,e,4);
  165.     fn[0] := Chr(e-1);
  166.   END;
  167.  
  168.   e := Length(fn);
  169.   path := '';
  170.   WHILE (e > 0) AND (fn[e] <> '\') DO Dec(e);
  171.   IF e > 0 THEN path := Copy(fn,1,e);
  172.   name := Copy(fn,e+1,8);
  173. END;
  174.  
  175. FUNCTION Exist(fn : String): BOOLEAN;
  176. VAR f : FILE;
  177.     at : WORD;
  178. BEGIN
  179.   Assign(f,fn);
  180.   GetFAttr(f,at);
  181.   Exist := DosError = 0;
  182. END;
  183.  
  184. PROCEDURE MoveW(VAR fra, til; len : WORD); BEGIN Move(fra,til,len*2); END;
  185.  
  186. PROCEDURE Bell; BEGIN Sound(1000); Delay(150); NoSound; END;
  187.  
  188. PROCEDURE ByteToDigits(by : BYTE; VAR buf);
  189. VAR b : ARRAY [1..2] OF BYTE ABSOLUTE buf;
  190. BEGIN
  191.   b[1] := by DIV 10 + 48;
  192.   b[2] := by MOD 10 + 48;
  193. END;
  194.  
  195. FUNCTION Pad(st : String; len : INTEGER): String;
  196. BEGIN
  197.   WHILE len > Length(st) DO st := st + ' ';
  198.   Pad := st;
  199. END;
  200.  
  201. PROCEDURE SetCursor(mode : WORD);
  202. BEGIN
  203. Inline(
  204.   $B4/$01                {mov ah,1}
  205.   /$8B/$4E/<MODE         {mov cx,[bp<mode]}
  206.   /$CD/$10               {int $10}
  207. );
  208. END;
  209.  
  210. PROCEDURE CursorOn;
  211. BEGIN
  212.   IF LastMode = 7 THEN
  213.     SetCursor($C0D)
  214.   ELSE
  215.     SetCursor($607);
  216. END;
  217.  
  218. PROCEDURE CursorOff;
  219. BEGIN
  220.   SetCursor($2000);
  221. END;
  222.  
  223. PROCEDURE ClrAll; BEGIN ClrScr; END;
  224.  
  225. PROCEDURE ClrLast; BEGIN GotoXY(1,25); ClrEol; END;
  226.  
  227. PROCEDURE WriteStr(st : String);
  228. BEGIN
  229.   Write(st);
  230. END;
  231.  
  232. PROCEDURE Error(msg : String);
  233. BEGIN
  234.   ClrLast;
  235.   Write(msg,'  Hit Esc!');
  236.   CursorOn;
  237.   REPEAT UNTIL ReadKey = #27;
  238.   CursorOff;
  239.   ClrLast;
  240. END;
  241.  
  242. (*
  243. PROCEDURE ReadString(help : INTEGER; prompt : String; len : BYTE;
  244.                      VAR st : String; VAR ok : BOOLEAN);
  245. VAR xpos : BYTE;
  246. BEGIN
  247.   WriteStr(prompt);
  248.   st := '';
  249.   xpos := 1;
  250.   ok := EditStr(st,xpos,len,0,NIL,LeftJ);
  251. END;
  252.  
  253. PROCEDURE ReadString(help : INTEGER; prompt : String;
  254.           maxlen : INTEGER;VAR st : String;VAR ok: BOOLEAN);
  255. VAR key : WORD;
  256.     ch : CHAR;
  257. BEGIN
  258.   ClrLast;
  259.   CursorOn;
  260.   Write(prompt);
  261.   st := '';
  262.   REPEAT
  263.     key := ReadKey;
  264.     IF key = $4400 THEN BEGIN
  265.       st := '';
  266.       ok := FALSE;
  267.       CursorOff;
  268.       Exit;
  269.     END
  270.     ELSE IF Lo(key) <> 0 THEN BEGIN
  271.       ch := Chr(Lo(key));
  272.       CASE ch OF
  273.         ^H : IF Length(st) > 0 THEN BEGIN
  274.                Dec(st[0]);
  275.                Write(^H' '^H);
  276.              END;
  277.         ^M : BEGIN
  278.                ok := TRUE;
  279.                CursorOff;
  280.                Exit;
  281.              END;
  282.         ELSE IF Length(st) < MaxLen THEN BEGIN
  283.           st := st + ch;
  284.           Write(ch);
  285.         END;
  286.       END;
  287.     END;
  288.   UNTIL FALSE;
  289. END;
  290.  
  291. PROCEDURE ReadNum(help : INTEGER;prompt : String;min, max : WORD;
  292.                   VAR svar : WORD);
  293. VAR st : String;
  294.     n, feil : INTEGER;
  295.     ok : BOOLEAN;
  296. BEGIN
  297.   REPEAT
  298.     ClrLast;
  299.     ReadString(help,prompt,10,st,ok);
  300.     IF st = '' THEN Exit;
  301.     Val(st,n,feil);
  302.   UNTIL (feil = 0) AND (n >= min) AND (n <= max);
  303.   svar := n;
  304. END;
  305. *)
  306.  
  307. PROCEDURE ReadFileName(prompt : String; VAR fil : String);
  308. VAR e : EditRecord;
  309.     ok : CharSet;
  310. BEGIN
  311.   fil := '';
  312.   ok := FileNameSet + ['*','?'];
  313.  
  314.   e.x := 1; e.y := 25; e.len := 53; e.prompt := prompt;
  315.   e.ftype := StrT; e.xpos := 1; e.just := LeftJ;
  316.   e.StrP := Addr(fil);
  317.   e.okSetS := Addr(ok);
  318.   e.ModeS := ToUpper;
  319.   CursorOn;
  320.   REPEAT
  321.     EditOne(e);
  322.   UNTIL EditChar IN [^M,#68,^[];
  323.   CursorOff;
  324. END;
  325.  
  326. FUNCTION Tstr(n, len : WORD): String;
  327. VAR st : STRING[20];
  328. BEGIN
  329.   Str(n:len,st);
  330.   Tstr := st;
  331. END;
  332.  
  333. PROCEDURE StartTimerSek(VAR t : TimerTableRec; sek : WORD);
  334. BEGIN
  335.   t.count := sek *18;
  336.   t.UserInt := FALSE;
  337.   StartTimer(t);
  338. END;
  339.  
  340. PROCEDURE BIOSKbd(help : INTEGER; expand : BOOLEAN; VAR ch : CHAR;
  341.                   VAR scan : INTEGER);
  342. BEGIN
  343.   ch := ReadKey;
  344.   IF ch = #0 THEN scan := Ord(ReadKey) ELSE scan := 2;
  345. END;
  346.  
  347. FUNCTION KeyPress : BOOLEAN;
  348. BEGIN
  349.   KeyPress := KeyPressed;
  350. END;
  351.  
  352. PROCEDURE ScrollWin(x0,y0,x1,y1,lines,attr : INTEGER);
  353. VAR sx, sy : WORD;
  354. BEGIN
  355.   sx := WhereX; sy := WhereY;
  356.   Window(x0,y0,x1,y1);
  357.   GotoXY(1,1);
  358.   IF lines = 0 THEN ClrScr
  359.   ELSE IF lines > 0 THEN DelLine
  360.   ELSE InsLine;
  361.   Window(1,1,80,25);
  362.   GotoXY(sx,sy);
  363. END;
  364.  
  365. PROCEDURE GetF10;
  366. BEGIN
  367.   IF TotalBytes = 0 THEN Exit;
  368.   ClrLast;
  369.   WriteStr('File transfer completed!  Hit any key to continue ... ');
  370.   IF ReadKey = #0 THEN IF ReadKey = #0 THEN;
  371. END;
  372.  
  373. PROCEDURE UpperStr(VAR st : String);
  374. VAR i : INTEGER;
  375. BEGIN
  376.   FOR i := 1 TO Length(st) DO st[i] := UpCase(st[i]);
  377. END;
  378.  
  379. CONST MaxArgC = 2;
  380.       MaxOptC = 1;
  381.  
  382. VAR InitFileName : STRING[80];
  383.     ArgV : ARRAY [1..2] OF String[64];
  384.     ArgC, OptC : BYTE;
  385.     OptV : ARRAY [1..1] OF String[64];
  386.  
  387. PROCEDURE ParseCmd;
  388. VAR i : INTEGER;
  389.     st : String;
  390. BEGIN
  391.   ArgC := 0;
  392.   OptC := 0;
  393.   FOR i := 1 TO ParamCount DO BEGIN
  394.     st := ParamStr(i);
  395.     UpperStr(st);
  396.     IF st[1] = '/' THEN BEGIN
  397.       Inc(OptC);
  398.       OptV[OptC] := st;
  399.     END
  400.     ELSE BEGIN
  401.       Inc(ArgC);
  402.       ArgV[ArgC] := st;
  403.     END;
  404.   END;
  405. END;
  406.  
  407. PROCEDURE GetInitFileName;
  408. VAR env_ptr : ^WORD;
  409.     i : INTEGER;
  410.     drive, path, name, ext, od, op, on, oe : String[80];
  411. BEGIN
  412.   ParseCmd;
  413.   IF Hi(DosVersion) >= 3 THEN BEGIN
  414.     env_ptr := Ptr(MemW[PrefixSeg:$2C],0);
  415.     WHILE env_ptr^ <> 0 DO Inc(Word(env_ptr));
  416.     Inc(Word(env_ptr),4);
  417.     InitFileName := '';
  418.     REPEAT
  419.       InitFileName := InitFileName + CHAR(env_ptr^);
  420.       Inc(Word(env_ptr));
  421.     UNTIL CHAR(env_ptr^) = #0;
  422.   END
  423.   ELSE
  424.     InitFileName := 'KERMIT';
  425.  
  426.   SplitFileName(InitFileName,drive,path,name,ext);
  427.   ext := '.INI';
  428.  
  429.   IF (OptC >= 1) AND (Copy(OptV[1],1,3) = '/I=') THEN BEGIN
  430.     SplitFileName(Copy(OptV[1],4,80),od,op,on,oe);
  431.     IF (od <> '') OR (op <> '') THEN BEGIN
  432.       drive := od;
  433.       path := op;
  434.     END;
  435.     IF on <> '' THEN name := on;
  436.     IF oe <> '' THEN ext := oe;
  437.   END;
  438.   InitFileName := drive+path+name+ext;
  439. END;                                   {GetInitFileName}
  440.  
  441. PROCEDURE SaveParam;
  442. VAR f : FILE;
  443. BEGIN
  444.   Assign(f,InitFileName);
  445.   ReWrite(f,1);
  446.   BlockWrite(f,Versjon,Ofs(Marker_Byte)-Ofs(Versjon));
  447.   Close(f);
  448.   IF IOresult <> 0 THEN Error('Save error!');
  449. END;
  450.  
  451. FUNCTION GetParam : BOOLEAN;
  452. VAR f : FILE;
  453.     v : String[4];
  454.     bytes : WORD;
  455.     ok : BOOLEAN;
  456. BEGIN
  457.   GetParam := FALSE;
  458.   GetInitFileName;
  459.  
  460.   IF Exist(InitFileName) THEN BEGIN
  461.     Assign(f,InitFileName);
  462.     Reset(f,1);
  463.     v := '';
  464.     BlockRead(f,v,SizeOf(v));
  465.     bytes := Ofs(Marker_Byte)-Ofs(Versjon);
  466.     ok := FALSE;
  467.     IF (v <> Versjon) OR (FileSize(f) <> bytes) THEN Exit;
  468.     Seek(f,0);
  469.     BlockRead(f,Versjon,bytes);
  470.     ok := IOresult = 0;
  471.     Close(f);
  472.     IF NOT ok OR (IOresult <> 0) THEN BEGIN
  473.       Error('Get .INI error!');
  474.       Exit;
  475.     END;
  476.     IF KermitAttr <> 0 THEN TextAttr := KermitAttr;
  477.     IF SaveEdit <> 0 THEN EditAttr := SaveEdit;
  478.   END;
  479.   GetParam := TRUE;
  480. END;
  481.  
  482. PROCEDURE StartLink;
  483. BEGIN
  484.   IF NOT DiskStopInt OR BinaryData THEN Exit;
  485.   RS_Enable(CurComPort);
  486.   RS_WriteFirst(^Q,CurComPort);
  487. END;
  488.  
  489. PROCEDURE StopLink;
  490. BEGIN
  491.   IF DiskStopInt AND NOT BinaryData THEN RS_WriteFirst(^S,CurComPort);
  492. END;
  493.  
  494. (******************** Statistics **********************)
  495.  
  496. FUNCTION DOS_Time : LongInt;
  497. VAR h, m, s, s100 : WORD;
  498. BEGIN
  499.   GetTime(h,m,s,s100);
  500.   DOS_Time := h * 36000 + m * 600 + s * 10 + (s100+5) DIV 10;
  501. END;
  502.  
  503. PROCEDURE InitStat;
  504. BEGIN
  505.   TotalTime := DOS_Time; TotalBytes := 0; SendBytes := 0; ReceiveBytes := 0;
  506.   FileNr := 0;
  507. END;
  508.  
  509. PROCEDURE ShowStat;
  510. VAR ch : CHAR;
  511.     t  : REAL;
  512. BEGIN
  513.   IF TotalBytes+SendBytes+ReceiveBytes > 0 THEN BEGIN
  514.     TotalTime := DOS_Time - TotalTime;
  515.     Window(22,5,80,10);
  516.     ClrScr;
  517.     WriteLn('      Total bytes: ',TotalBytes);
  518.     WriteLn('      Total files: ',FileNr);
  519.     WriteLn('       Bytes sent: ',SendBytes);
  520.     WriteLn('   Bytes received: ',ReceiveBytes);
  521.     WriteLn('       Total time: ',TotalTime DIV 10,'.',TotalTime MOD 10);
  522.     Write  ('   Effective Baud: ',TotalBytes * 100 DIV TotalTime);
  523.     Window(1,1,80,25);
  524.   END;
  525. END;
  526.  
  527. TYPE
  528.   KeyType = 0..40;
  529.   KeySet = SET OF KeyType;
  530.  
  531. VAR OrigText, OrigMenu, OrigField, OrigEdit : BYTE;
  532.  
  533. PROCEDURE Init_Params;
  534. VAR ok : BOOLEAN;
  535.     temp : LongInt;
  536. BEGIN
  537.   RS_Init(CurBaud,CurBits,CurStop,CurParity,ok,CurComPort);
  538.  
  539.   temp := 115200 DIV ((115200 + (CurBaud Shr 1)) DIV CurBaud);
  540.   IF temp <> CurBaud THEN BEGIN CurBaud := temp; ok := FALSE; END;
  541.  
  542.   MaxPrTick := CurBaud DIV 250;
  543.  
  544.   IF CurBaud > 30000 THEN BEGIN
  545.     DiskStopInt := TRUE;
  546.     WindowData := FALSE;
  547.     RS_Buffer[CurComPort].AutoXoff := FALSE;
  548.   END;
  549.  
  550.   IF IBM_Mode > 0 THEN BEGIN
  551.     MySOH := '%';
  552.     YourSOH := '%';
  553.     BinaryData := FALSE;
  554.   END;
  555.  
  556.   IF BinaryData THEN BEGIN
  557.     CurBits := 8;
  558.     CurParity := No_Parity;
  559.     RS_Buffer[CurComPort].AutoXoff := FALSE;
  560.   END;
  561. {
  562.     IF (CurBaud <= 2400) AND WindowData THEN
  563.       RS_Start(RX_Int+TX_Int+RLS_int,CurComPort)
  564.     ELSE
  565. }
  566.     RS_Start(RX_Int+RLS_int,CurComPort);
  567.  
  568.   YourQCtrlChar := MyQCtrlChar;
  569.   YourSOH := MySOH;
  570.   YourCR := MyCR;
  571. END;
  572.  
  573. PROCEDURE Meny(VAR k : KeyType);
  574. VAR
  575.   temp : LongInt;
  576.   st, keyset : String;
  577.   ch : CHAR;
  578.   OldPath : String[64];
  579.   OldMenu, OldAttr : BYTE;
  580.   dta : SearchRec;
  581.  
  582. PROCEDURE ShowMeny;
  583. BEGIN
  584.   IF MenuAttr = 0 THEN MenuAttr := OrigMenu;
  585.   IF FieldAttr = 0 THEN FieldAttr := OrigField;
  586.   FeltAttr := FieldAttr;
  587.   IF KermitAttr = 0 THEN KermitAttr := OrigText;
  588.   TextAttr := KermitAttr;
  589.   IF SaveEdit = 0 THEN SaveEdit := OrigEdit;
  590.   EditAttr := SaveEdit;
  591.  
  592.   ClrScr;
  593.  
  594.   GotoXY(22,3); Write(CpRt);
  595.  
  596.   GotoXY(34,14); WriteStr('Duplicate File Names');
  597.  
  598.   OldAttr := TextAttr;
  599.   TextAttr := MenuAttr;
  600.   GotoXY(1,25);
  601.   WriteStr('F1-Send F2-Receive F3-Get F4-Server F5-Save   F7-DOS F8-Term F9-Logout F10-Exit');
  602.   TextAttr := OldAttr;
  603.   OldMenu := MenuAttr;
  604. END;
  605.  
  606. BEGIN
  607.   ShowMeny;
  608.   CursorOn;
  609.  
  610.   REPEAT
  611.  
  612.     OldPath := DownLoadPath; OldAttr := KermitAttr;
  613.  
  614.     RS_Stop(CurComPort);
  615.  
  616.     ShowAll;
  617.     EditAllRecords;                    {EditChar inneholder siste tast}
  618.  
  619.     IF (KermitAttr <> OldAttr) OR (FieldAttr <> FeltAttr) OR
  620.        (MenuAttr <> OldMenu) THEN BEGIN
  621.       ShowMeny;
  622.       ShowAll;
  623.     END;
  624.     SaveEdit := EditAttr;
  625.  
  626.     Init_Params;
  627.  
  628.     IF DownLoadPath <> OldPath THEN BEGIN
  629.       ChDir(DownLoadPath);
  630.       IF IOresult = 0 THEN
  631.         GetDir(0,DownLoadPath)
  632.       ELSE BEGIN
  633.         DownLoadPath := OldPath;
  634.         ShowAll;
  635.       END;
  636.     END;
  637.     DirectVideo := DirVideo;
  638.   UNTIL EditChar IN [#59..#68];
  639.   CursorOff;
  640.  
  641.   k := Ord(EditChar) - 58;
  642. END;                                   {Meny}
  643.  
  644.