1 (************************************************************************
2  *  Copyright (C) 2014-2017, 2019  Paul Petrov                          *
3  *                                                                      *
4  *  This file is part of eMKatic.                                       *
5  *                                                                      *
6  *  eMKatic is free software: you can redistribute it and/or modify     *
7  *  it under the terms of the GNU General Public License as published   *
8  *  by the Free Software Foundation, either version 3 of the License,   *
9  *  or (at your option) any later version.                              *
10  *                                                                      *
11  *  eMKatic is distributed in the hope that it will be useful,          *
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty         *
13  *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.             *
14  *  See the GNU General Public License for more details.                *
15  *                                                                      *
16  *  You should have received a copy of the GNU General Public License   *
17  *  along with eMKatic.  If not, see <http://www.gnu.org/licenses/>.    *
18  *                                                                      *
19  ************************************************************************)
20 
21 unit SysGUI;
22 
23 {$mode objfpc}{$H+}
24 
25 interface
26 
27 uses Classes,SysUtils,Forms,Math,Serial,Display,MK_DOS,eMKaticIPC,Globe,ResStr;
28 
29 type
30   TFormID = (fiMain,fiDOS,fiCalc,fiViewClr,fiOther,
31    fiOperDisk,fiNotebookOper,fiMemTest,fiTextEditor,fiVersion,
32    fiDiskOper,fiDiskInfo,fiCheckDisk,fiFormatDisk,fiCopyDisk,
33    fiCheckNotebook,fiNotebookToB,fiNotebookFromB,
34    fiDir,fiFileOper,fiMakeFile,fiStartPage,fiPages,fiDupeDir,fiDupeFile,
35    fiFileInfo,fiViewFile,fiLoadFile,fiLoadPackage,fiCopy,fiReplace,fiDelFile,
36    fiDelDir,fiProgFile,fiDecFile,fiBinFile,fiTextFile,
37    fiProg,fiDec,fiBin,fiText,fiNotebook,fiSaveText,
38    fiEditorTable,fiDiskName,fiDirName,fiFileName,fiProgStartPage,fiProgPages,
39    fiNotebookGroup,fiProgCnt,fiProgAddr,fiDecAddr,fiBinAddr,
40    fiClrProg,fiClrDec,fiClrBin,fiClrText,fiClrNotebook,
41    fiNoDisk,fiNotebookDisk,fiNoEmptyDir,fiOutOfDir,fiOutOfDisk,fiBufEmpty);
42 
43 var MenuWidth:integer;
44 
45 procedure GoToForm(FormID:TFormID; Item:integer);
46 procedure DrawCurForm;
47 procedure FormButton(Code:integer);
48 procedure PkgProgress;
49 procedure PasteProgress;
50 procedure SetImportImgMode;
51 
52 implementation
53 
54 uses EmuKbd;
55 
56 var
57   CurForm,SavedCurForm:TFormID;
58   CurItem,SavedCurItem,MaxItem,TopItem,VisLine,TextLim,
59    ProgStartPage,ProgPages,PackageItem,ProgressI:integer;
60   CurFileRec:TDirRec;
61   TextModified:boolean;
62   AddrStr:string[5];
63   SavedWorkMode:TWorkMode;
64   TextTmp:array[0..3071] of byte;
65   Symbols:array[0..32] of byte;
66 
67 procedure LoadDir(Item:integer);
68 begin
69   TopItem:=IfThen(Item>5,Item); VisLine:=Item-TopItem; GoToForm(fiDir,0);
70 end;
71 
72 procedure ScrProgress(const Title,Message:CP866str; MsgY:integer=16);
73 begin
74   ClearScr(dcSys,0); DrawStrC(0,Title); DrawStrC(MsgY,Message);
75   SetX0Y0(dcSys,29,27); DrawFrame(dcSys,70,10); ProgressX:=32; ProgressY:=30;
76   ProgressTimerEnabled:=true; DrawSysScr;
77 end;
78 
79 procedure WinProgress(const Message:CP866str);
80 begin
81   DrawWindow(13,9,102,37); DrawStrC(16,Message);
82   SetX0Y0(dcSys,29,27); DrawFrame(dcSys,70,10); ProgressX:=32; ProgressY:=30;
83   ProgressTimerEnabled:=true; DrawSysScr;
84 end;
85 
86 procedure PkgProgress;
87 begin
88   DrawWindow(7,10,114,42); DrawStrC(13,rsLoadingPackage);
89   case ProgressI of
90     idProgFile: DrawStrC(23,rsProgram);
91     idDecFile: DrawStrC(23,rsDecData);
92     idTextFile: DrawStrC(23,rsText);
93     idBinFile: DrawStrC(23,rsBinData);
94   end;
95   SetX0Y0(dcSys,29,34); DrawFrame(dcSys,70,10); ProgressX:=32; ProgressY:=37;
96   ProgressTimerEnabled:=true; DrawSysScr;
97   if PkgLoading then begin
98     PackageItem:=FindFile(ProgressI,CurFileRec.Name);
99     if PackageItem>0 then if ProgressI=idProgFile then begin
100       ProgressTimerEnabled:=false; GoToForm(fiStartPage,0); exit;
101     end else LoadDirFile(PackageItem) else ProgressX:=99;
102     if ProgressI=idProgFile then begin
103       PkgLoading:=false; GoToForm(fiFileOper,3);
104     end else dec(ProgressI);
105   end;
106 end;
107 
108 procedure PasteProgress;
109 begin
110   if ProgressI=FileBufCnt then LoadDir(LastDirItem) else begin
111     inc(ProgressI); PasteFile(ProgressI);
112     case DiskError of
113       deSuccess: if FileBufCnt=1 then LoadDir(LastDirItem) else begin
114         WinProgress(rsPastingFile); exit;
115       end;
116       deOutOfDisk: GoToForm(fiOutOfDisk,0);
117       deOutOfDir: GoToForm(fiOutOfDir,0);
118       deNameError: GoToForm(fiDupeFile,0);
119     end;
120   end;
121   Pasting:=false; ProgressTimerEnabled:=false;
122 end;
123 
124 procedure Enter(const IDs:array of TFormID; Item:integer=0);
125 begin
126   GoToForm(IDs[CurItem],Item);
127 end;
128 
129 procedure GoToForm(FormID:TFormID; Item:integer);
130 begin
131   if not(FormID in [fiStartPage,fiPages]) then begin
132     SavedCurForm:=CurForm; SavedCurItem:=CurItem;
133   end;
134   if WorkMode<>wmSysGUI then SavedWorkMode:=WorkMode;
135   CurForm:=FormID; CurItem:=Item; AddrStr:=''; WorkMode:=wmSysGUI;
136   case FormID of
137     fiDOS,fiOperDisk: begin MaxItem:=1; LockDiskB end;
138     fiFormatDisk,fiSaveText,fiDelDir,
139      fiLoadFile,fiLoadPackage,fiCopy,fiReplace,fiDelFile,
140      fiClrProg,fiClrDec,fiClrBin,fiClrText,fiClrNotebook: MaxItem:=1;
141     fiNotebookOper,fiStartPage: begin MaxItem:=2; LockDiskB end;
142     fiDecAddr,fiPages: MaxItem:=3;
143     fiViewClr,fiDiskOper,fiMakeFile,fiProgCnt,fiProgAddr,fiBinAddr: MaxItem:=4;
144     fiOther: begin MaxItem:=4; UnlockDiskB end;
145     fiNotebookGroup: MaxItem:=5;
146     fiFileOper: begin
147       GetDirRec(TopItem+VisLine,CurFileRec); MaxItem:=6;
148     end;
149     fiViewFile: with CurFileRec do case ID of
150       idProgFile: begin
151         CurForm:=fiProgFile; ProgAddr:=0; fillchar(ProgMem,10000,255);
152         move(CurDrive^[Cluster,0],ProgMem,ProgPages*100);
153       end;
154       idDecFile: begin CurForm:=fiDecFile; DecAddr:=0 end;
155       idTextFile: begin CurForm:=fiTextFile; TextLine:=0 end;
156       idBinFile: begin CurForm:=fiBinFile; BinAddr:=1000 end;
157     end;
158     fiCopyDisk,fiNotebookToB,fiNotebookFromB: if (length(DiskB[0])=0) and
159      not NotebookDisk then CurForm:=fiNoDisk else MaxItem:=1;
160     fiMain: begin
161       MaxItem:=3; Com.Mode:=cmOff; DiskEnabled:=0; ClrFileBuf; UnlockDiskB;
162       if spSlavePlugged then spSlaveRxStop else spMasterRxStop;
163     end;
164     fiTextEditor: if SavedCurForm=fiOther then begin
165       move(ByteMemF[5096],ByteMem[5096],3072);
166       move(ByteMem[5096],TextTmp,3072); TextModified:=false; TextLim:=3072;
167     end;
168     fiDiskName,fiDirName,fiFileName:
169      if SavedCurForm in [fiDiskOper,fiDir,fiMakeFile] then begin
170       fillchar(TextTmp,25,32); TextPos:=0; TextCase:=0;
171       TextLim:=IfThen(FormID=fiDiskName,24,20); CurItem:=0;
172     end;
173     fiCalc: begin
174       if RealCom then begin
175         SerFlushInput(hComPort); SerFlushOutput(hComPort);
176       end;
177       WorkMode:=SavedWorkMode; SetComParamsRA;
178       if WorkMode=wmAutoGr then WorkMode:=wmAuto;
179     end;
180   end;
181 end;
182 
183 procedure DrawDir;
184  var i:integer; Rec:TDirRec;
185 begin
186   SetX0Y0(dcSys,2,0); DrawChar(dcSys,IfThen(CurDrive=@DiskA,65,66));
187   GetDirRec(0,Rec); DrawStr(dcSys,': '); DrawStr(dcSys,Rec.Name);
188   DrawBox(dcSys,0,9,128,1);
189   for i:=0 to min(5,LastDirItem-TopItem) do begin
190     GetDirRec(TopItem+i,Rec); SetX0Y0(dcSys,1,11+i*9);
191     case Rec.ID of
192       idProgFile: DrawChar(dcSys,ord('P'));
193       idDecFile: DrawChar(dcSys,ord('D'));
194       idBinFile: DrawChar(dcSys,ord('B'));
195       idTextFile: DrawChar(dcSys,ord('T'));
196     end;
197     DrawContext[dcSys].X0:=14;
198     if Rec.ID=idDirHeader then DrawStr(dcSys,'..') else DrawStr(dcSys,Rec.Name);
199   end;
200   DrawCursor(12,10+VisLine*9,116);
201 end;
202 
203 procedure DrawText(Index:integer; const Data);
204  var i,j:integer;
205 begin
206   for i:=max(-1,-Index) to IfThen(CurForm in [fiText,fiTextEditor,fiTextFile],
207    min(6,127-Index)) do begin
208     SetX0Y0(dcSys,1,i*8+8);
209     for j:=0 to 23 do begin
210       if (i=0) and (j=TextPos) and not(CurForm in [fiText,fiTextFile]) then
211        DrawBox(dcSys,DrawContext[dcSys].X0-1,8,1,8);
212       DrawChar(dcSys,TBytes(Data)[(Index+i)*24+j]);
213     end;
214     if (i=0) and (TextPos=24) and not(CurForm in [fiText,fiTextFile]) then
215      DrawBox(dcSys,DrawContext[dcSys].X0-1,8,1,8);
216   end;
217   DrawContext[dcSys].Attr:=DrawContext[dcSys].Attr xor 4;
218   DrawBox(dcSys,126,0,1,64);
219   DrawContext[dcSys].Attr:=DrawContext[dcSys].Attr xor 4;
220   DrawBox(dcSys,127,0,1,64); DrawBox(dcSys,126,Index shr 1,1,4);
221 end;
222 
223 procedure DrawSymbols;
224  const Ctrl:array[0..10] of byte=(200,194,196,198,199,197,195,201,202,193,192);
225  var i,j:integer;
226 begin
227   case TextCase of
228     0: begin
229       for i:=0 to 5 do Symbols[i]:=i+128; Symbols[6]:=240;
230       for i:=7 to 32 do Symbols[i]:=i+127;
231     end;
232     1: begin
233       for i:=0 to 31 do Symbols[i]:=i+64; Symbols[32]:=32;
234     end;
235     2: begin
236       for i:=0 to 5 do Symbols[i]:=i+160; Symbols[6]:=241;
237       for i:=7 to 16 do Symbols[i]:=i+159;
238       for i:=17 to 32 do Symbols[i]:=i+207;
239     end;
240     3: begin
241       for i:=0 to 31 do Symbols[i]:=i+96; Symbols[32]:=32;
242     end;
243     4,5: begin
244       for i:=0 to 15 do Symbols[i]:=i+48;
245       for i:=16 to 31 do Symbols[i]:=i+16; Symbols[32]:=0;
246     end;
247   end;
248   DrawBox(dcSys,3,18,122,1); DrawBox(dcSys,3,28,122,1);
249   for i:=0 to 3 do DrawBox(dcSys,3,30+i*11,122,1);
250   for i:=0 to 11 do begin
251     DrawBox(dcSys,3+i*11,19,1,9); DrawBox(dcSys,3+i*11,31,1,32);
252   end;
253   for i:=0 to 10 do if (CurForm=fiEditorTable) or
254    not InRange(Ctrl[i],198,201) then begin
255     SetX0Y0(dcSys,5+i*11,19); DrawChar(dcSys,Ctrl[i]);
256   end;
257   for j:=0 to 2 do for i:=0 to 10 do begin
258     SetX0Y0(dcSys,5+i*11,32+j*11); DrawChar(dcSys,Symbols[i+j*11]);
259   end;
260   if CurItem<11 then DrawCursor(4+CurItem*11,19,10,9)
261    else DrawCursor(4+(CurItem mod 11)*11,20+(CurItem div 11)*11,10);
262 end;
263 
264 procedure DrawName(const Obj:string);
265  var i:integer;
266 begin
267   DrawStrC(0,rsEnterNameOf+' '+Obj); SetX0Y0(dcSys,3,9);
268   for i:=0 to 24 do begin
269     if i=TextPos then DrawBox(dcSys,DrawContext[dcSys].X0-1,9,1,8);
270     DrawChar(dcSys,TextTmp[i]);
271   end;
272   SetX0Y0(dcSys,0,8); DrawFrame(dcSys,128,11); DrawSymbols;
273 end;
274 
275 procedure DrawCurForm;
276  var i:integer;
277  procedure YN(const L:array of string; Y:integer=-1);
278   var i,w:integer;
279  begin
280    if Y<0 then Y:=(46-length(L)*11) shr 1;
281    w:=80;
282    for i:=0 to high(L) do w:=max(w,StrWidth(L[i]));
283    w:=min(128,w+12-DrawContext[dcSys].Inter);
284    DrawWindow((128-w) shr 1,Y,w,length(L)*11+18);
285    for i:=0 to high(L) do DrawStrC(Y+i*11+4,L[i]);
286    w:=StrWidth(rsSysYes);
287    SetX0Y0(dcSys,42-(w shr 1),Y+length(L)*11+4); DrawStr(dcSys,rsSysYes);
288    if CurItem=0 then DrawCursor(40-(w shr 1),Y+length(L)*11+3,w+3);
289    w:=StrWidth(rsSysNo);
290    SetX0Y0(dcSys,86-(w shr 1),Y+length(L)*11+4); DrawStr(dcSys,rsSysNo);
291    if CurItem=1 then DrawCursor(84-(w shr 1),Y+length(L)*11+3,w+3);
292  end;
293 begin
294   if ProgressTimerEnabled then exit;
295   if CurForm in [fiMain,fiDOS,fiViewClr,fiOther,fiCopyDisk,fiNotebookToB,
296    fiOperDisk,fiDiskOper,fiNotebookOper,fiTextEditor,fiVersion,fiDiskInfo,
297    fiFormatDisk,fiEditorTable,fiDiskName,fiDirName,fiFileName,fiDir,
298    fiProg,fiDec,fiBin,fiText,fiNotebook,fiProgFile,fiDecFile,fiBinFile,
299    fiTextFile] then ClearScr(dcSys,0);
300   case CurForm of
301     fiMain: begin
302       DrawStrC(0,rsMainMenu);
303       DrawStrs(3,16,12,[rsDOS,rsCalc,rsViewClear,rsOtherFunc]);
304       DrawCursor(0,15+CurItem*12,MenuWidth+5);
305     end;
306     fiDOS: begin
307       DrawStrC(0,rsDOS); DrawStrs(3,20,13,[rsDiskA,rsDiskB]);
308       DrawCursor(0,19+CurItem*13,MenuWidth+5);
309     end;
310     fiViewClr: begin
311       DrawStrC(0,rsCapViewClear);
312       DrawStrs(3,14,10,[rsProgMemItem,rsDecData,rsBinData,rsText,rsNotebook]);
313       DrawCursor(0,13+CurItem*10,MenuWidth+5);
314     end;
315     fiOther: begin
316       DrawStrC(0,rsCapOtherFunc);
317       DrawStrs(3,14,10,[rsDiskOper,rsNotebookOper,rsMemTest,
318        rsTextEditor,rsProgVersion]);
319       DrawCursor(0,13+CurItem*10,MenuWidth+5);
320     end;
321     fiOperDisk: begin
322       DrawStrC(0,rsCapDiskOper); DrawStrs(3,20,13,[rsDiskA,rsDiskB]);
323       DrawCursor(0,19+CurItem*13,MenuWidth+5);
324     end;
325     fiDiskOper: begin
326       if CurDrive=@DiskA then
327        DrawStrC(0,rsCapDiskA) else DrawStrC(0,rsCapDiskB);
328       DrawStrs(3,14,10,[rsViewInfo,rsCheck,rsFormatDisk,rsRenameDisk,
329        rsCopyTo+' '+char(IfThen(CurDrive=@DiskA,66,65))]);
330       DrawCursor(0,13+CurItem*10,MenuWidth+5);
331     end;
332     fiNotebookOper: begin
333       DrawStrC(0,rsCapNotebook);
334       DrawStrs(3,16,12,[rsCheck,rsCopyTo+' B',rsLoadFrom+' B']);
335       DrawCursor(0,15+CurItem*12,MenuWidth+5);
336     end;
337     fiMemTest: begin
338       DrawWindow(16,16,96,28); DrawStrC(20,rsNoMemTest_1);
339       DrawStrC(31,rsNoMemTest_2);
340     end;
341     fiTextEditor: DrawText(TextLine,TextTmp);
342     fiEditorTable: begin DrawText(TextLine,TextTmp); DrawSymbols end;
343     fiSaveText: YN([rsSaveTextQ]);
344     fiVersion: begin
345       DrawStrC(0,'eMKatic - эмулятор ЭКВМ');
346       DrawStrC(10,'серии "Электроника"');
347       DrawStrC(23,'Версия '+Version+' от '+VersionDate);
348       DrawStrC(36,'Автор: Павел Петров');
349       DrawStrC(46,'AKA WindSoft  AKA cekmsu');
350       SetX0Y0(dcSys,14,56); DrawStr(dcSys,'E-mail: ws-pp@ngs.ru');
351     end;
352     fiDir: DrawDir;
353     fiMakeFile: begin
354       DrawWindow(2,10,124,52);
355       DrawStrs(8,14,9,[rsCreateProg,rsCreateDec,rsCreateText,
356        rsCreateBin,rsPasteFile]);
357       DrawCursor(6,13+CurItem*9,116);
358     end;
359     fiDupeDir: begin
360       DrawWindow(5,25,118,29); DrawStrC(30,rsDirExists_1);
361       DrawStrC(40,rsDirExists_2);
362     end;
363     fiDupeFile: begin
364       DrawWindow(5,25,118,29); DrawStrC(30,rsFileExists_1);
365       DrawStrC(40,rsFileExists_2);
366     end;
367     fiFileOper: begin
368       DrawWindow(1,1,126,62);
369       DrawStrs(8,4,8,[rsViewInfo,rsViewContent,rsLoad,rsLoadPackage,
370        rsCopyToClipboard,rsOverwrite,rsDelete]);
371       DrawCursor(5,4+CurItem*8,118,8);
372     end;
373     fiFileInfo: with CurFileRec,TimeStamp do begin
374       DrawWindow(1,19,126,44); SetX0Y0(dcSys,4,43); DrawStr(dcSys,rsDate);
375       SetX0Y0(dcSys,44,43);
376       DrawStr(dcSys,format(rsDateFormat,[IntToHex(Year,2),IntToHex(Mon,2),
377        IntToHex(Day,2)])+#31+IntToHex(Hour,2)+':'+IntToHex(Min,2));
378       SetX0Y0(dcSys,4,32); DrawStr(dcSys,Name);
379       case ID of
380         idProgFile: begin
381           DrawStrC(21,rsProgram);
382           SetX0Y0(dcSys,4,52); DrawStr(dcSys,rsPages);
383           SetX0Y0(dcSys,62-length(IntToStr(ProgPages))*6,52);
384           DrawStr(dcSys,IntToStr(ProgPages));
385         end;
386         idDecFile: DrawStrC(21,rsDecData);
387         idTextFile: DrawStrC(21,rsText);
388         idBinFile: DrawStrC(21,rsBinData);
389       end;
390     end;
391     fiLoadFile: YN([rsLoadFileQ]);
392     fiLoadPackage: YN([rsLoadPackageQ]);
393     fiCopy: begin
394       DrawWindow(16,15,96,25);
395       DrawStrs(20,18,10,[rsCopyOne,rsCopyAll]);
396       DrawCursor(19,28-CurItem*10,90,8);
397     end;
398     fiReplace: YN([rsOverwriteQ]);
399     fiNoEmptyDir: begin
400       DrawWindow(5,25,118,29); DrawStrC(30,rsCantDelete);
401       DrawStrC(40,rsDirNotEmpty);
402     end;
403     fiProg: DrawProg(8,8,ProgAddr,ProgMem);
404     fiProgFile: DrawProg(8,8,ProgAddr,ProgMem);
405     fiDec,fiDecFile: for i:=0 to 7 do begin
406       SetX0Y0(dcSys,0,i*8); DrawStr(dcSys,Int2Str0((DecAddr+i) mod 1000,3));
407       DrawContext[dcSys].X0:=32;
408       if CurForm=fiDec then
409        DrawStr(dcSys,Real2Str(DecMem[(DecAddr+i) mod 1000],false))
410        else DrawStr(dcSys,Real2Str(DecodeBCD(CurDrive^[CurFileRec.Cluster],
411        ((DecAddr+i) mod 1000)*8),false));
412     end;
413     fiBin: DrawBin(BinAddr,ByteMem);
414     fiBinFile: DrawBin(BinAddr,CurDrive^[CurFileRec.Cluster]);
415     fiText: DrawText(TextLine,ByteMem[5096]);
416     fiTextFile: DrawText(TextLine,CurDrive^[CurFileRec.Cluster,0]);
417     fiNotebook: begin
418       DrawStrC(0,rsGroup+'  '+Int2Str0(NotebookGroup,5));
419       for i:=0 to 3 do begin
420         SetX0Y0(dcSys,10,20+i*10);
421         DrawStr(dcSys,Real2Str(Notebook[NotebookGroup*4+i],false));
422       end;
423     end;
424     fiNotebookGroup: begin
425       DrawWindow(6,14,115,22);
426       SetX0Y0(dcSys,64-StrWidth(rsGroup),21); DrawStr(dcSys,rsGroup);
427       SetX0Y0(dcSys,69,21); DrawStr(dcSys,AddrStr);
428       SetX0Y0(dcSys,66,19); DrawFrame(dcSys,35,12);
429     end;
430     fiProgCnt,fiProgAddr,fiBinAddr: begin
431       DrawWindow(8,14,111,22);
432       SetX0Y0(dcSys,64-StrWidth(rsAddress),21); DrawStr(dcSys,rsAddress);
433       SetX0Y0(dcSys,69,21); DrawStr(dcSys,AddrStr);
434       SetX0Y0(dcSys,66,19); DrawFrame(dcSys,29,12);
435     end;
436     fiDecAddr: begin
437       DrawWindow(8,14,111,22);
438       SetX0Y0(dcSys,64-StrWidth(rsAddress),21); DrawStr(dcSys,rsAddress);
439       SetX0Y0(dcSys,69,21); DrawStr(dcSys,AddrStr);
440       SetX0Y0(dcSys,66,19); DrawFrame(dcSys,23,12);
441     end;
442     fiStartPage: begin
443       DrawWindow(2,18+IfThen(PkgLoading,15),124,18);
444       SetX0Y0(dcSys,7,23+IfThen(PkgLoading,15));
445       DrawStr(dcSys,rsStartPage);
446       SetX0Y0(dcSys,109,23+IfThen(PkgLoading,15)); DrawStr(dcSys,AddrStr);
447       SetX0Y0(dcSys,106,21+IfThen(PkgLoading,15)); DrawFrame(dcSys,17,12);
448     end;
449     fiPages: begin
450       DrawWindow(2,40,124,18);
451       SetX0Y0(dcSys,7,45); DrawStr(dcSys,rsPagesCount);
452       SetX0Y0(dcSys,103,45); DrawStr(dcSys,AddrStr);
453       SetX0Y0(dcSys,100,43); DrawFrame(dcSys,23,12);
454     end;
455     fiClrProg: YN([rsClearProgQ]);
456     fiClrDec,fiClrBin: YN([rsClearDataQ]);
457     fiClrText: YN([rsClearTextQ]);
458     fiClrNotebook: YN([rsClearNotebookQ]);
459     fiNoDisk: begin
460       DrawWindow(20,43,89,19); DrawStrC(48,rsNoDisk);
461     end;
462     fiNotebookDisk: begin
463       DrawWindow(20,43,89,19); DrawStrC(48,rsNotebookData);
464     end;
465     fiOutOfDir:begin
466       DrawWindow(16,23,96,18); DrawStrC(28,rsOutOfDir);
467     end;
468     fiOutOfDisk: begin
469       DrawWindow(16,23,96,18); DrawStrC(28,rsOutOfDisk);
470     end;
471     fiBufEmpty: begin
472       DrawWindow(16,23,96,18); DrawStrC(28,rsClipboardIsEmpty);
473     end;
474     fiDiskInfo: with PDiskSysRec(@CurDrive^[0,0])^ do begin
475       if CurDrive=@DiskA then
476        DrawStrC(0,rsCapDiskA) else DrawStrC(0,rsCapDiskB);
477       SetX0Y0(dcSys,1,11); DrawStr(dcSys,Name);
478       DrawStrs(0,20,9,[rsDate,rsTotalClusters,rsFrees,rsOcupied,rsBads]);
479       SetX0Y0(dcSys,111-StrWidth(IntToStr(FreeClusters)),38);
480       DrawStr(dcSys,IntToStr(FreeClusters));
481       SetX0Y0(dcSys,111-StrWidth(IntToStr(BusyClusters)),47);
482       DrawStr(dcSys,IntToStr(BusyClusters)); SetX0Y0(dcSys,105,56);
483       DrawChar(dcSys,48); SetX0Y0(dcSys,44,20);
484       with TimeStamp do DrawStr(dcSys,format(rsDateFormat,[IntToHex(Year,2),
485        IntToHex(Mon,2),IntToHex(Day,2)])+#31+IntToHex(Hour,2)+':'+IntToHex(Min,2));
486     end;
487     fiFormatDisk: begin
488       if CurDrive=@DiskA then
489        DrawStrC(0,rsCapDiskA) else DrawStrC(0,rsCapDiskB);
490       DrawStrC(13,rsFormatting);
491       YN([rsFilesWillDeleted,rsContinueQ],23);
492     end;
493     fiCopyDisk: begin
494       if CurDrive=@DiskA then
495        DrawStrC(0,rsCapDiskA) else DrawStrC(0,rsCapDiskB);
496       DrawStrC(13,rsCopyingTo+' '+char(IfThen(CurDrive=@DiskA,66,65)));
497       YN([rsFilesWillDeleted,rsContinueQ],23);
498     end;
499     fiNotebookToB: begin
500       DrawStrC(0,rsCapNotebook); DrawStrC(13,rsCopyingTo+' B');
501       YN([rsFilesWillDeleted,rsContinueQ],23);
502     end;
503     fiNotebookFromB: if NotebookDisk then YN([rsLoadNotebookQ]) else begin
504       DrawWindow(30,43,69,19); DrawStrC(48,rsNoData);
505     end;
506     fiDiskName: DrawName(rsOfDisk);
507     fiDirName: DrawName(rsOfDir);
508     fiFileName: DrawName(rsOfFile);
509     fiDelDir: YN([rsDeleteDirQ]);
510     fiDelFile: YN([rsDeleteFileQ]);
511     fiCheckDisk,fiCheckNotebook: begin
512       DrawWindow(13,21,103,17); DrawStrC(25,rsWithoutThis);
513     end;
514   end;
515 end;
516 
SetAddrnull517 function SetAddr(ID:TFormID; MinVal,MaxVal:integer; out Addr:integer):boolean;
518 begin
519   if length(AddrStr)=0 then AddrStr:='0';
520   result:=InRange(StrToInt(AddrStr),MinVal,MaxVal);
521   if result then begin
522     Addr:=StrToInt(AddrStr); GoToForm(ID,SavedCurItem);
523   end else AddrStr:='';
524 end;
525 
526 procedure InsertSymbol(Code:byte);
527  var i,InsPos,EoP:integer; b:boolean;
528 begin
529   InsPos:=IfThen(CurForm in [fiTextEditor,fiEditorTable],TextLine*24)+TextPos;
530   if InsPos>=TextLim then exit;
531   EoP:=IfThen(TextPos=24,InsPos,(InsPos div 24)*24+24);
532   while EoP<TextLim do begin
533     b:=true;
534     for i:=0 to 23 do b:=b and (TextTmp[EoP+i]=32);
535     if b then break;
536     inc(EoP,24);
537   end;
538   EoP:=min(EoP,TextLim);
539   if (TextTmp[EoP-1]=32) and (InsPos<EoP) then
540    move(TextTmp[InsPos],TextTmp[InsPos+1],EoP-InsPos-1) else begin
541     if EoP=TextLim then exit;
542     b:=true;
543     for i:=-24 to -1 do b:=b and (TextTmp[TextLim+i]=32);
544     if not b then exit;
545     move(TextTmp[EoP],TextTmp[EoP+24],TextLim-EoP-24);
546     fillchar(TextTmp[EoP],24,32);
547     move(TextTmp[InsPos],TextTmp[InsPos+1],EoP-InsPos);
548   end;
549   TextTmp[InsPos]:=Code; TextModified:=true; inc(TextPos);
550   if TextPos>24 then begin dec(TextPos,24); inc(TextLine) end;
551 end;
552 
553 procedure DeleteSymbol;
554  var i,DelPos,DelCnt,EoP:integer; b:boolean;
555 begin
556   DelPos:=IfThen(CurForm in [fiTextEditor,fiEditorTable],TextLine*24)+TextPos-1;
557   if (DelPos<0) or (DelPos>=TextLim) then exit;
558   EoP:=(DelPos div 24)*24+24;
559   while EoP<TextLim do begin
560     b:=true;
561     for i:=0 to 23 do b:=b and (TextTmp[EoP+i]=32);
562     if b then break;
563     inc(EoP,24);
564   end;
565   EoP:=min(EoP,TextLim); DelCnt:=1;
566   if (TextPos=0) and (TextTmp[DelPos]=32) then
567    while (DelCnt<24) and (TextTmp[DelPos-DelCnt]=32) do inc(DelCnt);
568   move(TextTmp[DelPos+1],TextTmp[DelPos-DelCnt+1],EoP-DelPos-1);
569   fillchar(TextTmp[EoP-DelCnt],DelCnt,32); TextModified:=true;
570   b:=(TextLine*24+24<EoP) or (DelCnt=24);
571   for i:=EoP-24 to EoP-1 do b:=b and (TextTmp[i]=32);
572   if b then begin
573     move(TextTmp[EoP],TextTmp[EoP-24],TextLim-EoP);
574     fillchar(TextTmp[TextLim-24],24,32);
575   end;
576   dec(TextPos,DelCnt);
577   if TextPos<0 then begin inc(TextPos,24); dec(TextLine) end;
578 end;
579 
580 procedure BreakLine;
581  var i:integer;
582 begin
583   if TextLine=127 then exit;
584   for i:=TextLim-24 to TextLim-1 do if TextTmp[i]<>32 then exit;
585   move(TextTmp[TextLine*24+24],TextTmp[TextLine*24+48],TextLim-TextLine*24-48);
586   move(TextTmp[TextLine*24+TextPos],TextTmp[TextLine*24+24],24-TextPos);
587   fillchar(TextTmp[TextLine*24+TextPos],24-TextPos,32);
588   fillchar(TextTmp[TextLine*24-TextPos+48],TextPos,32);
589   inc(TextLine); TextPos:=0; TextModified:=true;
590 end;
591 
592 procedure FormButton(Code:integer);
593  const Ctrl:array[0..10] of byte=(18,28,24,16,15,23,27,17,19,13,14);
594  var i:integer;
595 begin
596   if ProgressTimerEnabled then exit;
597   case Code of
598     0..9: case CurForm of
599       fiProgCnt,fiProgAddr,fiDecAddr,fiBinAddr,fiNotebookGroup,
600        fiStartPage,fiPages: if length(AddrStr)<MaxItem then
601        AddrStr:=AddrStr+char(Code+48);
602       fiTextEditor,fiEditorTable,
603        fiDiskName,fiDirName,fiFileName: InsertSymbol(48+Code);
604     end;
605     10: if CurForm in [fiTextEditor,fiEditorTable,
606      fiDiskName,fiDirName,fiFileName] then InsertSymbol(44);
607     11: if CurForm in [fiTextEditor,fiEditorTable,
608      fiDiskName,fiDirName,fiFileName] then InsertSymbol(45);
609     12: if CurForm in [fiTextEditor,fiEditorTable,
610      fiDiskName,fiDirName,fiFileName] then InsertSymbol(32);
611     13: case CurForm of
612       fiProg: GoToForm(fiClrProg,1);
613       fiDec: GoToForm(fiClrDec,1);
614       fiBin: GoToForm(fiClrBin,1);
615       fiText: GoToForm(fiClrText,1);
616       fiNotebook: GoToForm(fiClrNotebook,1);
617       fiProgCnt,fiProgAddr,fiDecAddr,fiBinAddr,fiNotebookGroup,
618        fiStartPage,fiPages: AddrStr:='';
619       fiTextEditor,fiEditorTable,fiDiskName,fiDirName,fiFileName: DeleteSymbol;
620       fiDir: if TopItem+VisLine<=LastDirItem then
621        case CurDrive^[CurDirCluster,(TopItem+VisLine)*32] of
622         idSubdir: GoToForm(fiDelDir,1);
623         idProgFile..idBinFile: GoToForm(fiDelFile,1);
624       end;
625     end;
626     14: case CurForm of
627       fiTextEditor,fiEditorTable: BreakLine;
628       fiDiskName: begin
629         move(TextTmp,PDiskSysRec(@CurDrive^[0,0])^.Name,24);
630         GoToForm(fiDiskOper,3);
631       end;
632       fiDirName: if TextTmp[0]<>32 then begin
633         move(TextTmp,CurFileRec.Name,20);
634         i:=MakeDirFile(idSubdir,CurFileRec.Name);
635         case DiskError of
636           deSuccess: LoadDir(i);
637           deNameError: GoToForm(fiDupeDir,0);
638         end;
639       end;
640       fiFileName: if TextTmp[0]<>32 then begin
641         move(TextTmp,CurFileRec.Name,20);
642         i:=MakeDirFile(CurFileRec.ID,CurFileRec.Name);
643         case DiskError of
644           deSuccess: begin WinProgress(rsCreatingFile); LoadDir(i) end;
645           deNameError: GoToForm(fiDupeFile,0);
646           deStartPageRequired: GoToForm(fiStartPage,0);
647         end;
648       end;
649       fiStartPage,fiPages: FormButton(33);
650     end;
651     15: case CurForm of
652       fiText,fiTextEditor,fiEditorTable,fiTextFile:
653        if TextLine<127 then inc(TextLine);
654       fiDir: if VisLine<5 then inc(VisLine) else
655        if TopItem<LastDirItem-5 then inc(TopItem);
656     end;
657     16: case CurForm of
658       fiText,fiTextEditor,fiEditorTable,fiTextFile:
659        if TextLine>0 then dec(TextLine);
660       fiDir: if VisLine>0 then dec(VisLine) else
661        if TopItem>0 then dec(TopItem);
662     end;
663     17: case CurForm of
664       fiText,fiTextEditor,fiEditorTable,fiTextFile: begin
665         TextLine:=127; TextPos:=24;
666       end;
667       fiDir: begin TopItem:=LastDirItem; VisLine:=0 end;
668     end;
669     18: case CurForm of
670       fiText,fiTextEditor,fiEditorTable,fiTextFile: begin
671         TextLine:=0; TextPos:=0;
672       end;
673       fiDir: begin TopItem:=0; VisLine:=0 end;
674     end;
675     19: case CurForm of
676       fiTextEditor,fiEditorTable,fiDiskName:
677        TextPos:=((TextPos div 6)*6+6) mod 30;
678       fiDirName,fiFileName:
679        TextPos:=IfThen(TextPos<20,min(20,(TextPos div 6)*6+6));
680     end;
681     20: if CurForm=fiDir then if LastDirItem<63 then GoToForm(fiMakeFile,0);
682     21: if CurForm=fiDir then if LastDirItem<63 then GoToForm(fiDirName,0);
683     22: if CurForm in [fiTextEditor,fiEditorTable,
684      fiDiskName,fiDirName,fiFileName] then TextCase:=(TextCase+2) mod 6;
685     23: case CurForm of
686       fiTextEditor,fiEditorTable,fiDiskName: if TextPos<24 then inc(TextPos);
687       fiDirName,fiFileName: if TextPos<20 then inc(TextPos);
688     end;
689     24: if CurForm in [fiTextEditor,fiEditorTable,
690      fiDiskName,fiDirName,fiFileName] then if TextPos>0 then dec(TextPos);
691     25: case CurForm of
692       fiDiskName: move(PDiskSysRec(@CurDrive^[0,0])^.Name,TextTmp,24);
693     end;
694     27: case CurForm of
695       fiTextEditor,fiEditorTable,fiDiskName: TextPos:=24;
696       fiDirName,fiFileName: TextPos:=20;
697     end;
698     28: if CurForm in [fiTextEditor,fiEditorTable,
699      fiDiskName,fiDirName,fiFileName] then TextPos:=0;
700     31: if CurForm in [fiTextEditor,fiEditorTable,
701      fiDiskName,fiDirName,fiFileName] then TextCase:=TextCase xor 1 else
702      if CurForm in [fiProg,fiProgFile] then RGrdG;
703     32: case CurForm of
704       fiDOS: begin
705         move(ProgMemF,ProgMem,10000); move(ProgMarkF,ProgMark,10000);
706         move(DecMemF,DecMem,sizeof(DecMem));
707         move(ByteMemF,ByteMem,sizeof(ByteMem));
708         ScrProgress(rsDOS,rsExit); GoToForm(fiMain,0);
709       end;
710       fiViewClr: GoToForm(fiMain,2);
711       fiOther: GoToForm(fiMain,3);
712       fiOperDisk: GoToForm(fiOther,0);
713       fiNotebookOper: GoToForm(fiOther,1);
714       fiTextEditor: if TextModified then GoToForm(fiSaveText,0)
715        else GoToForm(fiOther,3);
716       fiEditorTable: GoToForm(fiTextEditor,0);
717       fiDiskOper: GoToForm(fiOperDisk,IfThen(CurDrive=@DiskB,1));
718       fiDiskName: GoToForm(fiDiskOper,3);
719       fiFileName: GoToForm(fiMakeFile,CurFileRec.ID-idProgFile);
720       fiDir: if CurDirCluster=1 then
721        GoToForm(fiDOS,IfThen(CurDrive=@DiskB,1)) else begin
722         i:=CurDirCluster; LoadDirFile(0); LoadDir(IndexByCluster(i));
723       end;
724       fiDirName,fiMakeFile,fiFileOper,fiNoEmptyDir: GoToForm(fiDir,0);
725       fiProgFile,fiDecFile,fiBinFile,fiTextFile: GoToForm(fiFileOper,1);
726       fiProg: GoToForm(fiViewClr,0);
727       fiDec: GoToForm(fiViewClr,1);
728       fiBin: GoToForm(fiViewClr,2);
729       fiText: GoToForm(fiViewClr,3);
730       fiNotebook: GoToForm(fiViewClr,4);
731       fiProgCnt: WorkMode:=SavedWorkMode;
732       fiOutOfDir,fiOutOfDisk,fiDupeFile: if SavedCurForm=fiMakeFile then
733        GoToForm(fiDir,0) else GoToForm(SavedCurForm,SavedCurItem);
734       fiStartPage: if not PkgLoading then GoToForm(SavedCurForm,SavedCurItem);
735       fiProgAddr,fiClrProg,fiDecAddr,fiNotebookGroup,fiClrDec,fiBinAddr,
736        fiClrBin,fiClrText,fiClrNotebook,fiMemTest,fiVersion,fiSaveText,
737        fiDiskInfo,fiFormatDisk,fiCheckDisk,fiCopyDisk,fiCheckNotebook,
738        fiNotebookToB,fiNotebookFromB,fiNoDisk,fiNotebookDisk,fiDupeDir,
739        fiFileInfo,fiLoadFile,fiLoadPackage,fiCopy,fiReplace,fiDelFile,
740        fiDelDir,fiPages,fiBufEmpty: GoToForm(SavedCurForm,SavedCurItem);
741     end;
742     33: case CurForm of
743       fiMain: Enter([fiDOS,fiCalc,fiViewClr,fiOther]);
744       fiDOS: begin
745         SelectDrive(CurItem);
746         if CurDirCluster=0 then
747          if NotebookDisk then GoToForm(fiNotebookDisk,0)
748          else GoToForm(fiNoDisk,0) else LoadDir(0);
749       end;
750       fiViewClr: Enter([fiProg,fiDec,fiBin,fiText,fiNotebook]);
751       fiOther: Enter([fiOperDisk,fiNotebookOper,fiMemTest,fiTextEditor,fiVersion]);
752       fiOperDisk: begin
753         SelectDrive(CurItem);
754         if CurDirCluster=0 then
755          if NotebookDisk then GoToForm(fiNotebookDisk,0)
756          else GoToForm(fiNoDisk,0) else GoToForm(fiDiskOper,0);
757       end;
758       fiDiskOper: Enter([fiDiskInfo,fiCheckDisk,fiFormatDisk,fiDiskName,
759        fiCopyDisk],1);
760       fiNotebookOper: Enter([fiCheckNotebook,fiNotebookToB,fiNotebookFromB],1);
761       fiTextEditor: GoToForm(fiEditorTable,0);
762       fiSaveText: begin
763         if CurItem=0 then begin
764           move(TextTmp,ByteMem[5096],3072); move(TextTmp,ByteMemF[5096],3072);
765           include(UpdReq,idByteMem); ScrProgress(rsCapText,rsSavingToMem);
766         end;
767         GoToForm(fiOther,3);
768       end;
769       fiEditorTable,fiDiskName,fiDirName,fiFileName: if CurItem<11 then
770        FormButton(Ctrl[CurItem]) else InsertSymbol(Symbols[CurItem-11]);
771       fiDir: if TopItem+VisLine=0 then FormButton(32) else
772        if TopItem+VisLine<=LastDirItem then
773        if CurDrive^[CurDirCluster,(TopItem+VisLine)*32]=idSubdir then begin
774         LoadDirFile(TopItem+VisLine); LoadDir(0);
775       end else begin ClrFileBuf; GoToForm(fiFileOper,1) end;
776       fiMakeFile: if CurItem<4 then begin
777         CurFileRec.ID:=CurItem+idProgFile; ClrFileBuf; GoToForm(fiFileName,0);
778       end else if FileBufCnt=0 then GoToForm(fiBufEmpty,0) else begin
779         ProgressI:=0; Pasting:=true; WinProgress(rsPastingFile);
780       end;
781       fiFileOper: Enter([fiFileInfo,fiViewFile,fiLoadFile,fiLoadPackage,
782        fiCopy,fiReplace,fiDelFile],1);
783       fiLoadFile: begin
784         if CurItem=0 then if CurFileRec.ID=idProgFile then begin
785           GoToForm(fiStartPage,0); exit;
786         end else begin
787           LoadDirFile(TopItem+VisLine); WinProgress(rsLoadingFile);
788         end;
789         GoToForm(fiFileOper,2);
790       end;
791       fiLoadPackage: if CurItem=0 then begin
792         ProgressI:=idBinFile; PkgLoading:=true; PkgProgress;
793       end else GoToForm(fiFileOper,3);
794       fiCopy: begin
795         if CurItem=0 then WinProgress(rsCopyingAll)
796          else WinProgress(rsCopyingFile);
797         SetFileBuf((TopItem+VisLine)*CurItem); GoToForm(fiFileOper,4);
798       end;
799       fiReplace: begin
800         if CurItem=0 then if CurFileRec.ID=idProgFile then begin
801           GoToForm(fiStartPage,0); exit;
802         end else begin
803           ReplaceFile(TopItem+VisLine); WinProgress(rsOwerwritingFile);
804         end;
805         GoToForm(fiFileOper,5);
806       end;
807       fiProg,fiProgFile: GoToForm(fiProgAddr,0);
808       fiDec,fiDecFile: GoToForm(fiDecAddr,0);
809       fiBin,fiBinFile: GoToForm(fiBinAddr,0);
810       fiNotebook: GoToForm(fiNotebookGroup,0);
811       fiNotebookGroup: SetAddr(fiNotebook,0,16383,NotebookGroup);
812       fiProgCnt: begin
813         SetAddr(fiCalc,0,9999,ProgCnt); include(UpdReq,idProgMem);
814       end;
815       fiProgAddr: SetAddr(SavedCurForm,0,9999,ProgAddr);
816       fiDecAddr: SetAddr(SavedCurForm,0,999,DecAddr);
817       fiBinAddr: SetAddr(SavedCurForm,1000,5095,BinAddr);
818       fiStartPage: if (SavedCurForm=fiMakeFile) or (SavedCurItem=5) then
819        SetAddr(fiPages,0,99,ProgStartPage) else if PkgLoading then
820        if SetAddr(SavedCurForm,0,99,ProgStartPage) then begin
821         LoadDirFile(PackageItem,ProgStartPage);
822         PkgLoading:=false; PkgProgress;
823       end else else if SetAddr(SavedCurForm,0,99,ProgStartPage) then begin
824         LoadDirFile(TopItem+VisLine,ProgStartPage);
825         WinProgress(rsLoadingFile);
826       end;
827       fiPages: if SavedCurForm=fiMakeFile then
828        if SetAddr(fiDir,1,100-ProgStartPage,ProgPages) then begin
829         move(TextTmp,CurFileRec.Name,20);
830         LoadDir(MakeDirFile(idProgFile,CurFileRec.Name,ProgStartPage,ProgPages));
831         WinProgress(rsCreatingFile);
832       end else else if SetAddr(fiFileOper,1,100-ProgStartPage,ProgPages) then begin
833         ReplaceFile(TopItem+VisLine,ProgStartPage,ProgPages);
834         GetDirRec(TopItem+VisLine,CurFileRec);
835         WinProgress(rsOwerwritingFile);
836       end;
837       fiClrProg: begin
838         if CurItem=0 then begin
839           fillchar(ProgMem,10000,255); fillchar(ProgMark,10000,0);
840           fillchar(ProgMemF,10000,255); fillchar(ProgMarkF,10000,0);
841           fillchar(ProgReadCnt,sizeof(ProgReadCnt),0);
842           fillchar(ExecCnt,sizeof(ExecCnt),0); include(UpdReq,idProgMem);
843           ScrProgress(rsCapProgMem,rsClearing);
844         end;
845         GoToForm(fiProg,0);
846       end;
847       fiClrDec: begin
848         if CurItem=0 then begin
849           fillchar(DecMem,sizeof(DecMem),0);
850           fillchar(DecMemF,sizeof(DecMem),0); include(UpdReq,idDecMem);
851           fillchar(DataReadCnt[0],sizeof(DataReadCnt[0])*1000,0);
852           fillchar(WriteCnt[0],sizeof(WriteCnt[0])*1000,0);
853           ScrProgress(rsCapDecData,rsClearing);
854         end;
855         GoToForm(fiDec,0);
856       end;
857       fiClrBin: begin
858         if CurItem=0 then begin
859           fillchar(ByteMem[1000],4096,0); fillchar(ByteMemF[1000],4096,0);
860           include(UpdReq,idByteMem);
861           fillchar(DataReadCnt[1000],sizeof(DataReadCnt[0])*4096,0);
862           fillchar(WriteCnt[1000],sizeof(WriteCnt[0])*4096,0);
863           ScrProgress(rsCapBinData,rsClearing);
864         end;
865         GoToForm(fiBin,0);
866       end;
867       fiClrText: begin
868         if CurItem=0 then begin
869           fillchar(ByteMem[5096],3072,32); fillchar(ByteMemF[5096],3072,32);
870           include(UpdReq,idByteMem);
871           fillchar(DataReadCnt[5096],sizeof(DataReadCnt[0])*3072,0);
872           fillchar(WriteCnt[5096],sizeof(WriteCnt[0])*3072,0);
873           ScrProgress(rsCapText,rsClearing);
874         end;
875         GoToForm(fiText,0);
876       end;
877       fiClrNotebook: begin
878         if CurItem=0 then begin
879           fillchar(Notebook,sizeof(Notebook),0); include(UpdReq,idNotebook);
880           ScrProgress(rsCapNotebook,rsClearing);
881         end;
882         GoToForm(fiNotebook,0);
883       end;
884       fiFormatDisk: begin
885         if CurItem=0 then begin
886           FormatDisk(CurDrive^);
887           if CurDrive=@DiskA then ScrProgress(rsCapDiskA,rsFormatting,13)
888            else ScrProgress(rsCapDiskB,rsFormatting,13);
889         end;
890         GoToForm(fiDiskOper,2);
891       end;
892       fiCopyDisk: begin
893         if CurItem=0 then begin
894           if CurDrive=@DiskA then begin
895             for i:=0 to high(DiskA) do DiskB[i]:=copy(DiskA[i]);
896             ScrProgress(rsCapDiskA,rsCopyingTo+' B',13);
897           end else begin
898             for i:=0 to high(DiskA) do DiskA[i]:=copy(DiskB[i]);
899             ScrProgress(rsCapDiskB,rsCopyingTo+' A',13);
900           end;
901           NotebookDisk:=false;
902         end;
903         GoToForm(fiDiskOper,4);
904       end;
905       fiNotebookToB: begin
906         if CurItem=0 then begin
907           ScrProgress(rsCapNotebook,rsCopyingTo+' B',13);
908           Application.ProcessMessages; SaveNotebook;
909         end;
910         GoToForm(fiNotebookOper,1);
911       end;
912       fiNotebookFromB: if NotebookDisk then begin
913         if CurItem=0 then begin
914           ScrProgress(rsCapNotebook,rsLoadingFrom+' B',13);
915           Application.ProcessMessages; LoadNotebook;
916         end;
917         GoToForm(fiNotebookOper,2);
918       end;
919       fiDelDir,fiDelFile: if CurItem=0 then begin
920         DelDirFile(TopItem+VisLine);
921         if DiskError=deFileError then  GoToForm(fiNoEmptyDir,0)
922          else GoToForm(fiDir,0);
923       end else GoToForm(SavedCurForm,SavedCurItem);
924     end;
925     34: case CurForm of
926       fiDir: if VisLine<5 then VisLine:=5 else
927        TopItem:=max(0,min(TopItem+5,LastDirItem-5));
928       fiProg,fiProgFile: ProgAddr:=(ProgAddr+7) mod 10000;
929       fiDec,fiDecFile: DecAddr:=(DecAddr+7) mod 1000;
930       fiBin,fiBinFile: BinAddr:=((BinAddr-993) and 4095)+1000;
931       fiText,fiTextEditor,fiTextFile: TextLine:=min(127,TextLine+7);
932       fiNotebook: NotebookGroup:=(NotebookGroup+10) and 16383;
933       fiEditorTable,fiDiskName,fiDirName,fiFileName:
934        CurItem:=(CurItem div 11)*11+((CurItem+1) mod 11);
935       else if CurItem=MaxItem then CurItem:=0 else inc(CurItem);
936     end;
937     35: case CurForm of
938       fiDir: if VisLine>0 then VisLine:=0 else TopItem:=max(0,TopItem-5);
939       fiProg,fiProgFile: ProgAddr:=(ProgAddr+9993) mod 10000;
940       fiDec,fiDecFile: DecAddr:=(DecAddr+993) mod 1000;
941       fiBin,fiBinFile: BinAddr:=((BinAddr-1007) and 4095)+1000;
942       fiText,fiTextEditor,fiTextFile: TextLine:=max(0,TextLine-7);
943       fiNotebook: NotebookGroup:=(NotebookGroup-10) and 16383;
944       fiEditorTable,fiDiskName,fiDirName,fiFileName:
945        CurItem:=(CurItem div 11)*11+((CurItem+10) mod 11);
946       else if CurItem=0 then CurItem:=MaxItem else dec(CurItem);
947     end;
948     36: case CurForm of
949       fiProg,fiProgFile: ProgAddr:=(ProgAddr+9999) mod 10000;
950       fiDec,fiDecFile: DecAddr:=(DecAddr+999) mod 1000;
951       fiBin,fiBinFile: BinAddr:=((BinAddr-1001) and 4095)+1000;
952       fiText,fiTextEditor,fiTextFile,fiDir: FormButton(16);
953       fiNotebook: NotebookGroup:=(NotebookGroup-1) and 16383;
954       fiEditorTable,fiDiskName,fiDirName,fiFileName:
955        CurItem:=(CurItem+33) mod 44;
956       else if CurItem=0 then CurItem:=MaxItem else dec(CurItem);
957     end;
958     37: case CurForm of
959       fiProg,fiProgFile: ProgAddr:=(ProgAddr+1) mod 10000;
960       fiDec,fiDecFile: DecAddr:=(DecAddr+1) mod 1000;
961       fiBin,fiBinFile: BinAddr:=((BinAddr-999) and 4095)+1000;
962       fiText,fiTextEditor,fiTextFile,fiDir: FormButton(15);
963       fiNotebook: NotebookGroup:=(NotebookGroup+1) and 16383;
964       fiEditorTable,fiDiskName,fiDirName,fiFileName:
965        CurItem:=(CurItem+11) mod 44;
966       else if CurItem=MaxItem then CurItem:=0 else inc(CurItem);
967     end;
968   end;
969 end;
970 
971 procedure SetImportImgMode;
972 begin
973   case WorkMode of
974     wmAuto,wmAutoGr: ImportImgMode:=iimScreen;
975     wmProg,wmProgHex: begin
976       ImportImgMode:=iimProgMem; ImportImgPtr:=@ProgCnt;
977     end;
978     wmSysGUI: case CurForm of
979       fiProg: begin
980         ImportImgMode:=iimProgMem; ImportImgPtr:=@ProgAddr;
981       end;
982       fiBin: begin
983         ImportImgMode:=iimBinMem; ImportImgPtr:=@BinAddr;
984       end;
985       else ImportImgMode:=iimWrongMode;
986     end;
987     else ImportImgMode:=iimWrongMode;
988   end;
989 end;
990 
991 end.
992 
993