]> pd.if.org Git - mmurtl/blob - msamples/editor/edit.c
autocommit for file dated 1995-02-09 15:56:34
[mmurtl] / msamples / editor / edit.c
1 /* Edit.c  A simple editor using MMURTL file system and keyboard services\r
2    Use MakeIT.Bat to build this MMURTL samples application, or\r
3    use CM32 and DASM spearately:\r
4    CM32 Edit.c\r
5    DASM Edit.bat\r
6 */\r
7 \r
8 #define U32 unsigned long\r
9 #define S32 long\r
10 #define U16 unsigned int\r
11 #define S16 int\r
12 #define U8 unsigned char\r
13 #define S8 char\r
14 \r
15 #define TRUE 1\r
16 #define FALSE 0\r
17 \r
18 #include <stdio.h>\r
19 #include <string.h>\r
20 #include <ctype.h>\r
21 \r
22 /* Includes for OS public calls and structures */\r
23 \r
24 #include "\OSSOURCE\MKernel.h"\r
25 #include "\OSSOURCE\MMemory.h"\r
26 #include "\OSSOURCE\MData.h"\r
27 #include "\OSSOURCE\MTimer.h"\r
28 #include "\OSSOURCE\MVid.h"\r
29 #include "\OSSOURCE\MKbd.h"\r
30 #include "\OSSOURCE\MJob.h"\r
31 #include "\OSSOURCE\MFiles.h"\r
32 \r
33 #define EDVID   BRITEWHITE|BGBLUE\r
34 #define NORMVID WHITE|BGBLACK\r
35 #define MARKVID WHITE|BGRED\r
36 #define STATVID BLACK|BGCYAN\r
37 \r
38 #define EMPTY   99999\r
39 #define NLINESMAX 26\r
40 \r
41 struct EditRecType {\r
42         U8      *pBuf;\r
43     U8          *pBufWork;                      /* For copy and move */\r
44         U32             Line[NLINESMAX];        /* Offset in buf for 1st char in line */\r
45         U32     iBufMax;                        /* sBuf - 1 */\r
46         U32     iColMin;                        /* Screen coords */\r
47         U32     iRowMin;\r
48         U32     iColMax;\r
49         U32     iRowMax;\r
50         U32     sLine;\r
51         U8      bSpace;\r
52         U8              fVisible;\r
53         U32     iAttrMark;\r
54         U32     iAttrNorm;\r
55         U32     iTabNorm;\r
56     U32     oBufLine0   /* oBufLine0 */\r
57         U32     iCol;           /* cursor, 0..sLine-1 */\r
58         U32     iLine;      /* cursor, 0..cLines-1 */\r
59         U32     oBufInsert; /* offset of next char in */\r
60         U32     oBufLast;   /* offset+1 of last char */\r
61         U32     oBufMark;\r
62         U32     oBufBound;\r
63         };\r
64 \r
65 struct EditRecType  EdRec;\r
66 struct EditRecType  *pEdit;\r
67 char *pBuf1, *pBuf2;\r
68 unsigned char b, b1;\r
69 long  erc, fh;\r
70 char fModified;\r
71 char fOvertype;\r
72 char aStat[80];\r
73 char aStat1[80];\r
74 char aCmd[80];                  /* Get our command line */\r
75 long cbCmd = 0;\r
76 char *apParam[13];              /* Param 0 is cmd name */\r
77 long acbParam[13];\r
78 #define nParamsMax 13\r
79 char Filename[60];\r
80 long cbFilename;\r
81 unsigned char filler[100];\r
82 \r
83 \r
84 void clearbuf(void);    /* prototype for forward usage */\r
85 \r
86 /*********************************************************\r
87   Displays errors if they occur for certain file operations.\r
88 *********************************************************/\r
89 \r
90 long CheckErc(long call, long erc)\r
91 {\r
92 char st[40];\r
93 long i;\r
94 \r
95         if (erc) {\r
96                 FillData(st, 40, 0);\r
97                 Beep();\r
98                 switch (call) {\r
99                 case 1:\r
100                         sprintf(st, "Error %05d occurred on OpenFile", erc);\r
101                         break;\r
102                 case 2:\r
103                         sprintf(st, "Error %05d occurred on ReadBytes", erc);\r
104                         break;\r
105                 case 3:\r
106                         sprintf(st, "Error %05d occurred on WriteBytes", erc);\r
107                         break;\r
108                 case 4:\r
109                         sprintf(st, "Error %05d occurred on CreateFile", erc);\r
110                         break;\r
111                 case 5:\r
112                         sprintf(st, "Error %05d occurred on SetFileSize", erc);\r
113                         break;\r
114                 case 6:\r
115                         sprintf(st, "Error %05d occurred on SetFileLFA", erc);\r
116                         break;\r
117                 case 7:\r
118                         sprintf(st, "Error %05d occurred on ReadKbd", erc);\r
119                         break;\r
120                 default:\r
121                         sprintf(st, "Error %05d occurred on last command", erc);\r
122                         break;\r
123                 }\r
124                 for (i=0; i<40; i++)\r
125                         if (!st[i])\r
126                                 st[i] = ' ';\r
127 \r
128             PutVidChars (40, 24, st, 39, STATVID);\r
129         }\r
130     return (erc);\r
131 }\r
132 \r
133 /*********************************************************\r
134   Clears the status line with 80 blank chars.\r
135 *********************************************************/\r
136 void ClearStatus(void)\r
137 {\r
138 char st[80];\r
139         FillData(st, 80, 0);\r
140     PutVidChars (0, 24, st, 80, NORMVID);\r
141 }\r
142 \r
143 \r
144 /*************************************************************\r
145    Saves a file you are editing. If fPrompt is true, this\r
146    will prompt you to save. If fClose is true, the file will be \r
147    closed and the buffer will be closed.\r
148 **************************************************************/\r
149 \r
150 void SaveFile(int fPrompt, int fClose)\r
151 {\r
152 U32 i, keycode, fYes;\r
153 unsigned char  *pBuff;\r
154 \r
155   pBuff = pEdit->pBuf;\r
156 \r
157         if ((fh) && (fModified))\r
158         {\r
159                 if (pEdit->fVisible)\r
160                 {    /* fix visible characters */\r
161                      for (i=0; i <=pEdit->iBufMax; i++)\r
162                          if (pBuff[i] == 0x07)\r
163                                   pBuff[i] = 0x20;\r
164                  pEdit->fVisible = FALSE;\r
165             }\r
166         fYes = 1;\r
167                 if (fPrompt)\r
168                 {\r
169                         ClearStatus();\r
170                         SetXY(0, 24);\r
171                     TTYOut("This file has been modified. SAVE IT? (Y/N)", 43, BLACK|BGCYAN);\r
172                         ReadKbd(&keycode, 1);\r
173                         if (((keycode & 0xff) == 'N') || ((keycode & 0xff) == 'n'))\r
174                         {\r
175                                 fYes = 0;\r
176                                 ClearStatus();\r
177                         }\r
178                 }\r
179 \r
180                 if (fYes)\r
181                 {\r
182                         erc = CheckErc(6, SetFileLFA(fh, 0));\r
183                         if (!erc)\r
184                                 erc = CheckErc(5, SetFileSize(fh,\r
185                                                         pEdit->oBufLast));\r
186                         if (!erc)\r
187                                 erc = CheckErc(3, WriteBytes (fh, pBuf1,\r
188                                                            pEdit->oBufLast, &i));\r
189                         fModified = 0;\r
190                         ClearStatus();\r
191                     PutVidChars (0, 24, "DONE...   ", 10, STATVID);\r
192                         Sleep(150);\r
193                         ClearStatus();\r
194                 }\r
195 \r
196         }\r
197 \r
198         if (fh && fClose)\r
199         {\r
200                 CloseFile(fh);\r
201                 fh = 0;\r
202                 cbFilename = 0;\r
203                 clearbuf();\r
204         }\r
205 }\r
206 \r
207 /*************************************************************\r
208    This prompts for a filename to open and opens it if it\r
209    exists. If not, it will prompts to create.\r
210 **************************************************************/\r
211 \r
212 void OpenAFile(char *name)\r
213 {\r
214 U32 filesize, dret, keycode;\r
215 \r
216         erc = 0;\r
217         cbFilename = 0;\r
218         if (!name)\r
219         {\r
220                 SetXY(0,24);\r
221             PutVidChars (0,24, "Filename: ", 10, BLACK|BGWHITE);\r
222                 SetXY(10,24);\r
223                 EditLine(Filename, 0, 60, &cbFilename, &b1, BLACK|BGCYAN);\r
224                 SetXY(0,0);\r
225         }\r
226         else\r
227         {\r
228             b1=0x0d;\r
229             strncpy(Filename, name, 13);\r
230             cbFilename = strlen(Filename);\r
231         }\r
232         if ((b1==0x0d) && (cbFilename)) {\r
233                 erc = OpenFile(Filename, cbFilename, ModeModify, 1, &fh);\r
234                 if (!erc) {\r
235                         GetFileSize(fh, &filesize);\r
236                         if (filesize < 131000)  /* Buf is 131071 */\r
237                         {\r
238                                 erc = ReadBytes (fh, pBuf1, filesize, &dret);\r
239                                 if (erc > 1)\r
240                                         erc = CheckErc(2, erc);\r
241                                 else erc = 0;\r
242                             pEdit->oBufLast     = dret;      /* offset+1 of last char  */\r
243                                 pBuf1[pEdit->oBufLast] = 0x0F;          /* the SUN */\r
244                         }\r
245                         else\r
246                         {\r
247                                 CloseFile(fh);\r
248                                 fh = 0;\r
249                                 Beep();\r
250                                 SetXY(50, 24);\r
251                             TTYOut("File is too large to edit.", 26, BLACK|BGCYAN);\r
252                                 ReadKbd(&keycode, 1);\r
253                         }\r
254                 }\r
255                 else if (erc == 203) {  /* no such file */\r
256                         Beep();\r
257                         SetXY(50, 24);\r
258                     TTYOut("Doesn't exist. Create?? (Y/N)", 29, BLACK|BGCYAN);\r
259                         ReadKbd(&keycode, 1);\r
260                         if (((keycode & 0xff) == 'Y') || ((keycode & 0xff) == 'y')) {\r
261                                 erc = CheckErc(4, CreateFile(Filename, cbFilename, 0));\r
262 \r
263                                 if (!erc)\r
264                                         erc = CheckErc(1, OpenFile(Filename, cbFilename,\r
265                                                                         ModeModify, 1, &fh));\r
266 \r
267                                 if (erc) {\r
268                                         fh = 0;\r
269                                         cbFilename = 0;\r
270                                 }\r
271 \r
272                         }\r
273                         else {\r
274                                 cbFilename = 0;\r
275                                 ClearStatus();\r
276                         }\r
277                 }\r
278                 else\r
279                         CheckErc(1, erc);\r
280         }\r
281 \r
282         if (!erc)\r
283                 ClearStatus();\r
284 }\r
285 \r
286 /************************************************************\r
287    This counts ABSOLUTE LINES from the begining of the buffer\r
288    up to point of oBufLine0 (which is the first char displayed\r
289    in the window. ABSOLUTE means LFs were found, even though\r
290    we word wrap always.\r
291 *************************************************************/\r
292 \r
293 unsigned long CountEols (void)\r
294 {\r
295 unsigned long  nEols, i;\r
296 unsigned char  *pBuff;\r
297 \r
298   pBuff = pEdit->pBuf;\r
299   nEols = 0;\r
300   i = 0;\r
301 \r
302   while (i < pEdit->oBufLine0) /* count LFs */\r
303         if (pBuff[i++] == 0x0A)\r
304                 nEols++;\r
305 \r
306   return(nEols);\r
307 }\r
308 \r
309 \r
310 \r
311 /************************************************************\r
312    This returns the index to the the last character in a line\r
313    upto a maximum of sLine-1. iBuf points to the beginning\r
314    point in the buffer to find the end of line for.\r
315 *************************************************************/\r
316 \r
317 unsigned long findEol (unsigned long iBuf)\r
318 {\r
319 \r
320 unsigned long  iEol, iEolMax;\r
321 unsigned char  *pBuff;\r
322 \r
323   pBuff = pEdit->pBuf;\r
324 \r
325         /* Calculate the most it could be */\r
326 \r
327   iEolMax = iBuf + pEdit->sLine-1;\r
328 \r
329         /* Fix it if EOL is past end of data */\r
330 \r
331   if (iEolMax > pEdit->oBufLast)\r
332      iEolMax = pEdit->oBufLast;\r
333 \r
334   iEol = iBuf;\r
335   while ((pBuff[iEol] != 0x0A) && (iEol < iEolMax)) /* Find CR */\r
336     iEol++;\r
337   if ((iEol == iEolMax) && (pBuff[iEol] != 0x0A)) {  /* if no CR... */\r
338     iEol = iEolMax;\r
339     if (iEolMax < pEdit->oBufLast) {\r
340 \r
341       /* now work back to last space */\r
342       while ((pBuff[iEol] != pEdit->bSpace) && (iEol > iBuf))\r
343          iEol--;\r
344 \r
345       /*  now find first non-space - allows */\r
346       if ((iEol > iBuf) &&\r
347           (pBuff[iEol] == pEdit->bSpace) &&  /* wrap-around w/ double space */\r
348           (iEol == iEolMax)) {\r
349 \r
350         if ((pBuff[iEol-1] == pEdit->bSpace) ||\r
351             ((iEol == iEolMax) && (pBuff[iEol+1] == pEdit->bSpace))) {\r
352                 while ((pBuff[iEol] == pEdit->bSpace) && (iEol > iBuf))\r
353                 iEol--;\r
354                 while ((pBuff[iEol] != pEdit->bSpace) && (iEol > iBuf))\r
355                 iEol--;\r
356         }\r
357           }\r
358       if ((iEol == iBuf) &&\r
359           (pBuff[iBuf] > 0) &&\r
360           (pBuff[iEolMax] > 0))        /* handles "all-char" of full line */\r
361         iEol = iEolMax;\r
362     }\r
363   }\r
364   return(iEol);\r
365 }\r
366 \r
367 /************************************************************\r
368    This walks back through the buffer looking for the\r
369    logical end of a line.\r
370 *************************************************************/\r
371 \r
372 \r
373 unsigned long findPrevLine (unsigned long oBufStart)\r
374 {\r
375 unsigned long  i, j;\r
376 char *pBuff;\r
377 \r
378   pBuff = pEdit->pBuf;\r
379 \r
380   i = 0;\r
381   if (oBufStart)\r
382          i = oBufStart - 1;\r
383   while ((i) && (pBuff[i] != 0x0A))\r
384          i--;\r
385   if (i > 0)\r
386         i--;\r
387   while ((i > 0) && (pBuff[i] != 0x0A))\r
388          i--;\r
389   if (i)\r
390         i++;                    /*  Get to known start of line */\r
391   do {\r
392         j = i;\r
393         i = (findEol (j)) + 1;\r
394   }\r
395   while (i < oBufStart);\r
396   return(j);\r
397 }\r
398 \r
399 /************************************************************\r
400    This executes the BEGIN BLOCK (Mark) command.\r
401 *************************************************************/\r
402 \r
403 \r
404 void doMark (unsigned long iLn)\r
405 {\r
406 unsigned long  iColStart, iColFinish, iMarkLoc, iBoundLoc;\r
407 \r
408   if (pEdit->oBufMark < EMPTY) {\r
409       if (pEdit->oBufMark <= pEdit->oBufBound) {\r
410       iMarkLoc = pEdit->oBufMark;\r
411       iBoundLoc = pEdit->oBufBound;\r
412         }\r
413         else {\r
414       iMarkLoc = pEdit->oBufBound;\r
415       iBoundLoc = pEdit->oBufMark;\r
416         }\r
417     if ( ((iMarkLoc >= pEdit->Line[iLn]) && (iMarkLoc < pEdit->Line[iLn+1]))   ||\r
418          ((iBoundLoc >= pEdit->Line[iLn]) && (iBoundLoc < pEdit->Line[iLn+1])) ||\r
419          ((iMarkLoc < pEdit->Line[iLn]) && (iBoundLoc >= pEdit->Line[iLn+1])) )\r
420         {\r
421       if (iMarkLoc >= pEdit->Line[iLn])\r
422         iColStart = pEdit->iColMin + iMarkLoc - pEdit->Line[iLn];\r
423       else\r
424         iColStart = pEdit->iColMin;\r
425 \r
426       if (iBoundLoc < pEdit->Line[iLn+1])\r
427          iColFinish = pEdit->iColMin + iBoundLoc - pEdit->Line[iLn];\r
428       else\r
429          iColFinish = pEdit->iColMin + pEdit->Line[iLn+1] - pEdit->Line[iLn] - 1;\r
430 \r
431       if (iColStart > pEdit->iColMin)\r
432           PutVidAttrs (pEdit->iColMin,\r
433                                 iLn,\r
434                                 iColStart-pEdit->iColMin,\r
435                                 pEdit->iAttrNorm);\r
436       PutVidAttrs (iColStart, iLn,      iColFinish - iColStart +1, pEdit->iAttrMark);\r
437 \r
438       if (iColFinish < pEdit->iColMax)\r
439         PutVidAttrs (iColFinish+1,\r
440                           iLn,\r
441                           pEdit->iColMax - iColFinish,\r
442                           pEdit->iAttrNorm);\r
443     }\r
444     else   /*buf col*/\r
445       PutVidAttrs (pEdit->iColMin,\r
446                         iLn,\r
447                         pEdit->sLine,\r
448                         pEdit->iAttrNorm);\r
449   }\r
450 }\r
451 \r
452 \r
453 /************************************************************\r
454    This inserts data into the main editing buffer.\r
455 *************************************************************/\r
456 \r
457 \r
458 char putInBuf(  unsigned char bPutIn,\r
459                                 char fOvertype,\r
460                 char fSpecInsert)\r
461 {\r
462 unsigned long  cb;\r
463 char  fOK, *pBuff;\r
464 \r
465         fModified = 1;\r
466         pBuff = pEdit->pBuf;\r
467 \r
468   if ((pEdit->oBufInsert < pEdit->iBufMax) &&\r
469     ((pEdit->oBufLast < pEdit->iBufMax) ||\r
470      ((fOvertype) && (!fSpecInsert))))\r
471   {\r
472     fOK = 1;\r
473     if ((fOvertype) && (!fSpecInsert)) {\r
474       pBuff[pEdit->oBufInsert] = bPutIn;\r
475       if (pEdit->oBufLast == pEdit->oBufInsert)\r
476          pEdit->oBufLast++;\r
477       pEdit->oBufInsert++;\r
478     }\r
479     else {\r
480       cb = pEdit->oBufLast - pEdit->oBufInsert + 1;\r
481       CopyData (&pBuff[pEdit->oBufInsert], pEdit->pBufWork, cb);\r
482       pBuff[pEdit->oBufInsert] = bPutIn;\r
483       CopyData (pEdit->pBufWork, &pBuff[pEdit->oBufInsert+1], cb);\r
484       pEdit->oBufLast++;\r
485       pEdit->oBufInsert++;\r
486       if (pEdit->oBufMark < EMPTY) {\r
487         if (pEdit->oBufInsert-1 < pEdit->oBufMark)\r
488           pEdit->oBufMark++;\r
489         if (pEdit->oBufInsert-1 <= pEdit->oBufBound)\r
490           pEdit->oBufBound++;\r
491       }\r
492     }\r
493   }\r
494   else {\r
495         fOK = 0;\r
496     Beep();\r
497     erc = 40400;\r
498   }\r
499   return (fOK);\r
500 }\r
501 \r
502 /************************************************************\r
503    This executes the MOVE command which moves a marked\r
504    block to the cursor's current location in the file.\r
505 *************************************************************/\r
506 \r
507 void moveData (void)\r
508 {\r
509 unsigned long  i, iMk, iBd;\r
510 char *pBuff, *pBuffWork;\r
511 \r
512         pBuff = pEdit->pBuf;\r
513         pBuffWork = pEdit->pBufWork;\r
514 \r
515 if (pEdit->oBufMark < EMPTY) {\r
516         fModified = 1;\r
517         if (pEdit->oBufMark <= pEdit->oBufBound) {\r
518             iMk = pEdit->oBufMark;\r
519             iBd = pEdit->oBufBound;\r
520         }\r
521         else {\r
522             iBd = pEdit->oBufMark;\r
523             iMk = pEdit->oBufBound;\r
524         }\r
525         if ((pEdit->oBufInsert < iMk) || (pEdit->oBufInsert > iBd)) {\r
526                 for (i=0; i <= pEdit->oBufLast; i++)\r
527                 pBuffWork[i] = pBuff[i];\r
528             if (pEdit->oBufInsert < iMk) {\r
529           for (i=0; i<=iBd-iMk; i++)                /* Move mk/bd */\r
530                  pBuff[pEdit->oBufInsert+i] = pBuffWork[iMk+i];\r
531           for (i=0; i<=iMk - pEdit->oBufInsert - 1; i++) /* Shift overwritten ahead */\r
532                 pBuff[pEdit->oBufInsert+iBd-iMk+1+i] =\r
533                 pBuffWork[pEdit->oBufInsert+i];\r
534         }\r
535         if (pEdit->oBufInsert > iBd) {\r
536                 for (i=0; pEdit->oBufInsert - iBd - 1; i++)\r
537                         pBuff[iMk+i] = pBuffWork[iBd+1+i];\r
538                 pEdit->oBufInsert = pEdit->oBufInsert - iBd + iMk - 1;\r
539                 for (i=0; i <=iBd-iMk; i++)\r
540                         pBuff[pEdit->oBufInsert+i] = pBuffWork[iMk+i];\r
541         }\r
542         iBd = pEdit->oBufInsert + iBd - iMk;\r
543         iMk = pEdit->oBufInsert;\r
544         if (pEdit->oBufBound > pEdit->oBufMark) {\r
545                 pEdit->oBufBound = iBd;\r
546                 pEdit->oBufMark = iMk;\r
547         }\r
548         else {\r
549                 pEdit->oBufMark = iBd;\r
550                 pEdit->oBufBound = iMk;\r
551         }\r
552         }\r
553 }\r
554  else Beep();\r
555 }\r
556 \r
557 /************************************************************\r
558    This executes the COPY command which copies a marked\r
559    block to the cursor's current location in the file.\r
560 *************************************************************/\r
561 \r
562 void CopyIt (void)\r
563 {\r
564 unsigned long iMk, iBd;\r
565 char *pBuff, *pBuffWork;\r
566 \r
567         pBuff = pEdit->pBuf;\r
568         pBuffWork = pEdit->pBufWork;\r
569 \r
570 if (pEdit->oBufMark < EMPTY) {\r
571         fModified = 1;\r
572 \r
573   if (pEdit->oBufMark <= pEdit->oBufBound) {\r
574     iMk = pEdit->oBufMark;\r
575     iBd = pEdit->oBufBound;\r
576   } else {\r
577     iBd = pEdit->oBufMark;\r
578     iMk = pEdit->oBufBound;\r
579   }\r
580   if (pEdit->oBufLast+iBd-iMk+1 < pEdit->iBufMax) {\r
581         CopyData(pBuff, pBuffWork, pEdit->oBufLast+1);\r
582         CopyData(&pBuffWork[iMk], &pBuff[pEdit->oBufInsert], iBd-iMk+1);\r
583     if (pEdit->oBufLast >= pEdit->oBufInsert)\r
584         CopyData(&pBuffWork[pEdit->oBufInsert],\r
585                 &pBuff[pEdit->oBufInsert+iBd-iMk+1],\r
586                 pEdit->oBufLast - pEdit->oBufInsert+1);\r
587     iBd = pEdit->oBufInsert + iBd - iMk;\r
588     iMk = pEdit->oBufInsert;\r
589     pEdit->oBufInsert = pEdit->oBufInsert + iBd - iMk + 1;\r
590     pEdit->oBufLast = pEdit->oBufLast + iBd - iMk + 1;\r
591     if (pEdit->oBufBound > pEdit->oBufMark) {\r
592       pEdit->oBufBound = iBd;\r
593       pEdit->oBufMark = iMk;\r
594     }\r
595     else {\r
596       pEdit->oBufMark = iBd;\r
597       pEdit->oBufBound = iMk;\r
598     }\r
599   }\r
600 }\r
601 else Beep();\r
602 }\r
603 \r
604 /************************************************************\r
605   This sets the characters on the screen to normal attributes\r
606 *************************************************************/\r
607 \r
608 void normAttr (void)\r
609 {\r
610 unsigned long  i;\r
611 \r
612   for (i = pEdit->iRowMin; i <= pEdit->iRowMax; i++)\r
613      PutVidAttrs (pEdit->iColMin, i, pEdit->sLine, pEdit->iAttrNorm);\r
614 }\r
615 \r
616 /************************************************************\r
617    This unmarks a selected block. (hides it).\r
618 *************************************************************/\r
619 \r
620 void nullMarkBound (void)\r
621 {\r
622   pEdit->oBufMark = EMPTY;\r
623   pEdit->oBufBound = EMPTY;\r
624   normAttr ();\r
625 }\r
626 \r
627 /************************************************************\r
628    This DELETES a selected block.\r
629 *************************************************************/\r
630 \r
631 void deleteData (void)\r
632 {\r
633 unsigned long  i, iMk, iBd;\r
634 char  fProb;\r
635 char *pBuff, *pBuffWork;\r
636 \r
637   pBuff = pEdit->pBuf;\r
638   pBuffWork = pEdit->pBufWork;\r
639 \r
640 if (pEdit->oBufMark < EMPTY) {\r
641   fModified = 1;\r
642   if (pEdit->oBufMark <= pEdit->oBufBound)  {\r
643     iMk = pEdit->oBufMark;\r
644     iBd = pEdit->oBufBound;\r
645   } else {\r
646     iBd = pEdit->oBufMark;\r
647     iMk = pEdit->oBufBound;\r
648   }\r
649   if ((pEdit->oBufLine0 >= iMk) && (pEdit->oBufLine0 <= iBd))\r
650      fProb = TRUE;\r
651   else fProb = FALSE;\r
652   CopyData(&pBuff[iBd+1], &pBuff[iMk], pEdit->oBufLast-iBd);\r
653   pEdit->oBufLast = pEdit->oBufLast - iBd + iMk - 1;\r
654   if (pEdit->oBufInsert > iBd)\r
655           pEdit->oBufInsert = pEdit->oBufInsert - iBd + iMk;\r
656   else if ((pEdit->oBufInsert > iMk) && (pEdit->oBufInsert <= iBd))\r
657       pEdit->oBufInsert = iMk;\r
658   if (pEdit->oBufInsert > pEdit->oBufLast)\r
659      pEdit->oBufInsert = pEdit->oBufLast;\r
660   if (fProb)  {\r
661     i = findPrevLine (pEdit->oBufInsert);\r
662     pEdit->oBufLine0 = i;\r
663   }\r
664   nullMarkBound ();\r
665 }\r
666 }\r
667 \r
668 /************************************************************\r
669    After screen movement (such as scrolling), this\r
670    finds the proper location of the cursor in relationship\r
671    to the portion of the file currently displayed.\r
672 *************************************************************/\r
673 \r
674 void findCursor (void)\r
675 {\r
676         /* locates cursor based on oBufInsert\r
677            - might be off screen - if it is, this\r
678        will adjust screen */\r
679 \r
680 unsigned long  i, j;\r
681 \r
682   i = pEdit->iRowMin;\r
683   while ((i <= pEdit->iRowMax) && (pEdit->oBufInsert >= pEdit->Line[i]))\r
684        i++;\r
685   pEdit->iLine = i - 1;\r
686   if (pEdit->iLine < pEdit->iRowMin)\r
687      pEdit->iLine = pEdit->iRowMin;\r
688 \r
689   j = pEdit->iLine;\r
690   if ((pEdit->Line[j+1] < EMPTY) &&\r
691       (pEdit->oBufInsert >= pEdit->Line[j+1]))\r
692         pEdit->iLine = pEdit->iLine + 1;\r
693   j = pEdit->iLine;\r
694   pEdit->iCol = pEdit->oBufInsert - pEdit->Line[j] + pEdit->iColMin;\r
695   if (pEdit->iLine > pEdit->iRowMax + 1)\r
696      pEdit->iLine = pEdit->iRowMax;\r
697 }\r
698 \r
699 /************************************************************\r
700    This readjusts iCol & iLine to get them back in sync with\r
701    oBufInsert if oBufInsert is on screen.  If oBufInsert is\r
702    not onscreen, this makes it so it is!\r
703 *************************************************************/\r
704 \r
705 void coordCursor_oBuf (void)\r
706 {\r
707 unsigned long  oBuf, i;\r
708 \r
709   i = pEdit->iRowMax+1;\r
710   if ((pEdit->oBufInsert >= pEdit->oBufLine0) &&\r
711       (pEdit->oBufInsert < pEdit->Line[i]))  {\r
712 \r
713     /* if bogus line, guarantee end of good */\r
714 \r
715         i = pEdit->iLine;\r
716     if (pEdit->Line[i] == EMPTY)\r
717        pEdit->iCol = pEdit->iColMax;\r
718 \r
719      /* if bogus line, find last good line */\r
720 \r
721     while ((pEdit->Line[i] == EMPTY) &&\r
722            (i > pEdit->iRowMin)) {\r
723         pEdit->iLine--;\r
724                 i = pEdit->iLine;\r
725         }\r
726 \r
727         i = pEdit->iLine;\r
728     pEdit->oBufInsert =\r
729         pEdit->Line[i] + pEdit->iCol - pEdit->iColMin;\r
730     if (pEdit->oBufInsert > pEdit->oBufLast)\r
731        pEdit->oBufInsert = pEdit->oBufLast;\r
732     oBuf = pEdit->Line[i+1];\r
733     if (pEdit->oBufInsert > oBuf)\r
734        pEdit->oBufInsert = oBuf;   /* get to potential insert - is, if\r
735                                            prev char <> CR, is not if prev = CR */\r
736     if (pEdit->oBufInsert == oBuf)            /* if at EOL */\r
737        if (pEdit->pBuf[oBuf-1] == 0x0A)\r
738          pEdit->oBufInsert--;\r
739     pEdit->iCol = pEdit->oBufInsert + pEdit->iColMin -\r
740                           pEdit->Line[i];\r
741   }\r
742 }\r
743 \r
744 \r
745 /************************************************************\r
746  Adjusts oBufLine0 to make sure that oBufInsert is on the screen.\r
747  This also sets all of the Line array values (Line[n])\r
748 *************************************************************/\r
749 \r
750 void makeOnScreen (void)\r
751 {\r
752 unsigned long  i, j, k;\r
753 \r
754   /* If oBufInsert is not on screen (above current display)\r
755      then find the previous line beginning and make that\r
756      the new first line 1 until it is!\r
757   */\r
758 \r
759   while (pEdit->oBufInsert < pEdit->oBufLine0)\r
760         pEdit->oBufLine0 = findPrevLine (pEdit->oBufLine0);\r
761 \r
762   /* Set Line[iRowMin] to match oBufLine0 */\r
763 \r
764   k = pEdit->iRowMin;\r
765   pEdit->Line[k] = pEdit->oBufLine0;\r
766 \r
767   /* Set all subsequent Line[s] by calling findEol for each. */\r
768 \r
769   for (i = k; i <= pEdit->iRowMax; i++) {\r
770     if (pEdit->Line[i] < EMPTY) {\r
771       j = findEol (pEdit->Line[i]);\r
772       if (j < pEdit->oBufLast)       /* j = offset of last char of line */\r
773         pEdit->Line[i+1] = j + 1;\r
774       else\r
775         for (j=i+1; j<NLINESMAX; j++)\r
776                         pEdit->Line[j] = EMPTY;\r
777         }\r
778   }\r
779 \r
780         /* If the InsertPoint (your cursor position) is past\r
781         the last line then do this junk to fix it */\r
782 \r
783   j = pEdit->iRowMin;\r
784   k = pEdit->iRowMax;\r
785   while (pEdit->oBufInsert >= pEdit->Line[k+1]) {\r
786     for (i=j; i<=k; i++)\r
787       pEdit->Line[i] = pEdit->Line[i+1];\r
788     pEdit->oBufLine0 = pEdit->Line[j];\r
789 \r
790     i = findEol (pEdit->Line[k]);                 /* EOL of iRowMax */\r
791     if (i < pEdit->oBufLast)              /* i = offset of last char of line */\r
792         pEdit->Line[k+1] = i + 1;\r
793     else pEdit->Line[k+1] = EMPTY;\r
794   }\r
795 }\r
796 \r
797 /************************************************************\r
798  Redisplay all data on the screen.\r
799 *************************************************************/\r
800 \r
801 void showScreen (char *pFiller)\r
802 {\r
803 unsigned long i, iLn, cb, oBuf;\r
804 char *pBuff;\r
805 \r
806         pBuff = pEdit->pBuf;\r
807 \r
808         makeOnScreen ();    /* oBufInsert on screen - Line correct */\r
809 \r
810         for (iLn = pEdit->iRowMin; iLn <= pEdit->iRowMax; iLn++) {\r
811 \r
812                 /* i = offset in buf of last char on line */\r
813                 /* cb = nchars in line */\r
814 \r
815                 cb = 0;\r
816                 oBuf = pEdit->Line[iLn];\r
817                 if (oBuf < EMPTY) {\r
818                         if (pEdit->Line[iLn+1] < EMPTY)\r
819                                 i = pEdit->Line[iLn+1] - 1;\r
820                         else\r
821                         i = pEdit->oBufLast;\r
822                     cb = i - oBuf + 1;          /* Make size, not offset */\r
823 \r
824 \r
825                     if ((!pEdit->fVisible) &&\r
826                         (pBuff[i] == 0x0A) &&\r
827                         (cb))\r
828                                 cb--;\r
829                 }\r
830 \r
831                 if ((cb) && (oBuf < EMPTY))\r
832                         PutVidChars (pEdit->iColMin, iLn, pBuff+oBuf, cb,\r
833                                           pEdit->iAttrNorm);\r
834 \r
835                 if (cb < pEdit->sLine)\r
836                         PutVidChars (pEdit->iColMin+cb, iLn, pFiller, pEdit->sLine-cb,\r
837                                           pEdit->iAttrNorm);\r
838 \r
839                 doMark (iLn);\r
840         }\r
841 }\r
842 \r
843 /************************************************************\r
844  Resets all variables for the editor and clears the\r
845  buffers. Called before use and after closure.\r
846 *************************************************************/\r
847 \r
848 void clearbuf (void)\r
849 {\r
850 unsigned long i;\r
851 char *pBuff;\r
852 \r
853         pBuff = pEdit->pBuf;\r
854         FillData(filler, 80, 0x20);\r
855         for (i=0; i<NLINESMAX; i++)\r
856        pEdit->Line[i] = EMPTY;\r
857         i = pEdit->iRowMin;\r
858         pEdit->Line[i] = 0;\r
859 \r
860     pEdit->iCol = pEdit->iColMin;\r
861     pEdit->iLine = pEdit->iRowMin;\r
862         pEdit->bSpace = 0x20;\r
863         pEdit->fVisible = FALSE;\r
864         fModified = 0;\r
865         fOvertype = FALSE;\r
866         pEdit->oBufLast  = 0;\r
867     pEdit->oBufInsert = 0;\r
868     pEdit->oBufLine0 = 0;\r
869         pBuff[pEdit->oBufLast] = 0x0F;          /* the SUN */\r
870         nullMarkBound();\r
871         normAttr ();\r
872 }\r
873 \r
874 /************************************************************\r
875  This is the main editing function. It is a HUGE while\r
876  loop which reads keystrokes and processes them.\r
877 *************************************************************/\r
878 \r
879 void Editor(char *pbExitRet)\r
880 {\r
881 unsigned long  i, j, k, key;\r
882 char  fSpecInsert;     /* TRUE = insert no matter what fOvertype is */\r
883 char  fScreen;             /* TRUE = display entire screen */\r
884 char  fDone;\r
885 unsigned char b;\r
886 char *pBuff, *pBuffWork;\r
887 long exch;\r
888 \r
889 char testkey[10];\r
890 \r
891   pBuff = pEdit->pBuf;\r
892   pBuffWork = pEdit->pBufWork;\r
893   fDone = FALSE;\r
894 \r
895   if (pEdit->fVisible)\r
896   {\r
897     pEdit->bSpace = 0x07;\r
898     for (i=0; i <=pEdit->oBufLast; i++)\r
899       if (pBuff[i] == 0x20)\r
900          pBuff[i] = pEdit->bSpace;\r
901   } else\r
902         pEdit->bSpace = 0x20;\r
903 \r
904 \r
905   normAttr ();\r
906   fScreen = TRUE;\r
907 \r
908   pBuff[pEdit->oBufLast] = 0x0F;                /* the SUN */\r
909 \r
910   erc = AllocExch(&exch);\r
911 \r
912   while (!fDone)\r
913   {\r
914     if (fScreen)\r
915     {\r
916       showScreen (filler);    /* we know oBufInsert on screen */\r
917       findCursor ();\r
918       fScreen = FALSE;\r
919     }\r
920     SetXY (pEdit->iCol, pEdit->iLine);\r
921         FillData(aStat, 80, 0x20);\r
922         i= CountEols() + pEdit->iLine;\r
923         sprintf(aStat,"C: %02d  L: %05d  nChars: %05d",\r
924                         pEdit->iCol, i, pEdit->oBufLast);\r
925         if (cbFilename)\r
926                 CopyData(Filename, &aStat[40], cbFilename);\r
927         if (fOvertype)\r
928                 CopyData("OVR", &aStat[77], 3);\r
929         else\r
930                 CopyData("INS", &aStat[77], 3);\r
931     PutVidChars (0, 0, aStat, 80, STATVID);\r
932 \r
933     fSpecInsert = FALSE;  /* True if char should be inserted even if fOver */\r
934 \r
935     CheckErc(7, ReadKbd (&key, 1));       /* Wait for char */\r
936 \r
937     b = key & 0xff;\r
938 \r
939         if (key & 0x3000)               /* ALT key is down */\r
940         {\r
941                 switch (b)\r
942                 {\r
943 \r
944                 case 0x42:              /* ALT-B -- Beginning of Text */\r
945                 case 0x62:              /* ALT-b  */\r
946                    pEdit->oBufLine0 = 0;\r
947                    pEdit->oBufInsert = 0;\r
948                    pEdit->iCol = pEdit->iColMin;\r
949                    pEdit->iLine = pEdit->iRowMin;\r
950                    fScreen = TRUE;\r
951                                  break;\r
952 \r
953                 case 0x43:              /* ALT-C -- CloseFile */\r
954                 case 0x63:              /* ALT-c  */\r
955                 SaveFile(TRUE, TRUE);\r
956                         fScreen = TRUE;\r
957                                 break;\r
958                 case 0x45:              /* ALT-E -- End of Text */\r
959                 case 0x65:              /* ALT-e  */\r
960                    pEdit->oBufInsert = pEdit->oBufLast;\r
961                    coordCursor_oBuf ();\r
962                                    fScreen = TRUE;\r
963                                  break;\r
964                 case 0x01:              /* ALT-UP Arrow - Cursor to top of screen */\r
965                    pEdit->iLine = pEdit->iRowMin;\r
966                    pEdit->iCol = pEdit->iColMin;\r
967                                  break;\r
968                 case 0x02:      /* ALT Down Arrow - Cursor to bottom of screen */\r
969                    pEdit->iLine = pEdit->iRowMin;\r
970                                    i = pEdit->iLine;\r
971                    while ((pEdit->Line[i+1] < EMPTY) &&\r
972                           (i < pEdit->iRowMax)) {\r
973                        pEdit->iLine++;\r
974                                            i = pEdit->iLine;\r
975                                    }\r
976                    pEdit->iCol = pEdit->iColMax;\r
977                    coordCursor_oBuf ();\r
978                                  break;\r
979                 case 0x03:              /* ALT-Left Arrow - Cursor to BOL */\r
980                    pEdit->iCol = pEdit->iColMin;\r
981                                  break;\r
982                 case 0x04:              /* ALT-Right Arrow - Cursor to EOL */\r
983                                    i = pEdit->iLine;\r
984                    if (pEdit->Line[i+1] < EMPTY) {\r
985                       pEdit->iCol =\r
986                         pEdit->iColMin +\r
987                         pEdit->Line[i+1] -\r
988                         pEdit->Line[i];\r
989                         i = pEdit->iLine+1;\r
990                       if ((pBuff[pEdit->Line[i]-1] == 0x0A)\r
991                          && (pEdit->iCol > pEdit->iColMin))\r
992                        pEdit->iCol--;\r
993                    }\r
994                    else pEdit->iCol = pEdit->iColMin +\r
995                                 pEdit->oBufLast - pEdit->Line[i];\r
996                                  break;\r
997 \r
998                 case 0x56:              /* ALT-V   Make nontext chars Visible/Invisible */\r
999                 case 0x76:              /* ALT-v  */\r
1000                    if (pEdit->fVisible)  {\r
1001                      for (i=0; i <= pEdit->oBufLast; i++)\r
1002                           if (pBuff[i] == 0x07)\r
1003                                 pBuff[i] = 0x20;\r
1004                      pEdit->fVisible = FALSE;\r
1005                      pEdit->bSpace = 0x20;\r
1006                    } else {\r
1007                      for (i=0; i<=pEdit->oBufLast; i++)\r
1008                           if (pBuff[i] == 0x20)\r
1009                                 pBuff[i] = 0x07;\r
1010                      pEdit->fVisible = TRUE;\r
1011                      pEdit->bSpace = 0x07;\r
1012                    }\r
1013                    fScreen = TRUE;\r
1014                                 break;\r
1015                 case 0x4F:              /* ALT-O   OpenFile */\r
1016                 case 0x6F:              /* ALT-o  */\r
1017                                 if (!fh) {\r
1018                                         clearbuf();\r
1019                                         OpenAFile(0);\r
1020                     fScreen = TRUE;\r
1021                                 }\r
1022                                 break;\r
1023                 case 0x51:      /* ALT Q - Quit */\r
1024                 case 0x71:\r
1025                 SaveFile(TRUE, TRUE);\r
1026                 fDone = TRUE;\r
1027                                 break;\r
1028                 case 0x53:              /* ALT S - SaveFile */\r
1029                 case 0x73:              /* ALT s  */\r
1030                 SaveFile(FALSE, FALSE);\r
1031                         fScreen = TRUE;\r
1032                                 break;\r
1033                 case 0x7F:              /* ALT Delete (Delete Marked Block)  */\r
1034                         if (pEdit->oBufMark < EMPTY)  {\r
1035                    deleteData ();\r
1036                    fScreen = TRUE;\r
1037                  }\r
1038                                  break;\r
1039                         default:\r
1040                                 break;\r
1041                 }\r
1042         }\r
1043 \r
1044         else if (key & 0x0300)          /* CTRL key is down */\r
1045         {\r
1046 \r
1047 \r
1048         }\r
1049 \r
1050         /* Standard editing keys including LF */\r
1051 \r
1052         else if (((b >= 0x20) && (b <= 0x7E)) || (b == 0x0D))\r
1053         {\r
1054                 coordCursor_oBuf ();\r
1055                         if (b == 0x20)\r
1056                 b = pEdit->bSpace;\r
1057                         if (b == 0x0D)\r
1058                 b = 0x0A;\r
1059                              /* Don't overwrite CR */\r
1060             if (pBuff[pEdit->oBufInsert] == 0x0A)\r
1061               fSpecInsert = TRUE;\r
1062             if (!(putInBuf (b, fOvertype, fSpecInsert)))\r
1063                 Beep();\r
1064                 findCursor ();\r
1065             fScreen = TRUE;\r
1066 \r
1067         }\r
1068 \r
1069         else if (key & 0x0C00) {        /* SHIFT key is down & NOT letter keys */\r
1070                 switch (b)\r
1071                 {\r
1072                         case 0x03:      /* SHIFT Left */\r
1073                      if (pEdit->iCol > pEdit->iColMin + 5)\r
1074                         pEdit->iCol -= 5;\r
1075                  else\r
1076                         if (pEdit->iCol > pEdit->iColMin)\r
1077                                 pEdit->iCol--;\r
1078                                  break;\r
1079                         case 0x04:      /* SHIFT Right */\r
1080                      if (pEdit->iCol < pEdit->iColMax - 5)\r
1081                         pEdit->iCol += 5;\r
1082                  else\r
1083                         if (pEdit->iCol < pEdit->iColMax)\r
1084                                 pEdit->iCol++;\r
1085                                  break;\r
1086                          default:\r
1087                                 break;\r
1088                 }\r
1089     }\r
1090 \r
1091         else {                  /* Unshifted editing keys */\r
1092                 switch (b) {\r
1093                 case 0x08:      /* Backspace */\r
1094                         if (pEdit->oBufLast)  {\r
1095                    coordCursor_oBuf ();\r
1096                    if (pEdit->oBufInsert)  {\r
1097                      pEdit->oBufInsert = pEdit->oBufInsert - 1;\r
1098                      if (!fOvertype)  {\r
1099                        CopyData(pBuff,\r
1100                                         pBuffWork,\r
1101                                         pEdit->oBufLast+1);\r
1102                        CopyData(&pBuffWork[pEdit->oBufInsert+1],\r
1103                                         &pBuff[pEdit->oBufInsert],\r
1104                                         pEdit->oBufLast-pEdit->oBufInsert);\r
1105                        pBuff[pEdit->oBufLast] = 0;\r
1106                        pEdit->oBufLast = pEdit->oBufLast - 1;\r
1107                        if ((pEdit->oBufMark == pEdit->oBufBound) &&\r
1108                            (pEdit->oBufMark == pEdit->oBufInsert))\r
1109                           nullMarkBound ();\r
1110                        if (pEdit->oBufMark < EMPTY)  {\r
1111                          if (pEdit->oBufInsert <= pEdit->oBufMark)\r
1112                             pEdit->oBufMark--;\r
1113                          if (pEdit->oBufInsert <= pEdit->oBufBound)\r
1114                             pEdit->oBufBound--;\r
1115                        }\r
1116                      }\r
1117                    }\r
1118                    if (pEdit->oBufInsert < pEdit->oBufLine0)\r
1119                       pEdit->oBufLine0 = findPrevLine (pEdit->oBufLine0);\r
1120                    fScreen = TRUE;\r
1121                                    fModified = TRUE;\r
1122                 }\r
1123                                 break;\r
1124                 case 0x06:              /* Home - Cursor to BOL */\r
1125                 pEdit->iCol = pEdit->iColMin;\r
1126                                 break;\r
1127                 case 0x09:              /* Tab */\r
1128                         if (pEdit->oBufLast + pEdit->iTabNorm < pEdit->iBufMax)\r
1129                         {\r
1130                    coordCursor_oBuf();\r
1131                    j = pEdit->iTabNorm - (pEdit->iCol % pEdit->iTabNorm);\r
1132                    for (i=1; i <=j; i++)\r
1133                         putInBuf (pEdit->bSpace, FALSE, FALSE);\r
1134                    fScreen = TRUE;\r
1135                 }\r
1136                                 break;\r
1137                 case 0x10:   /* F2 -- UNMARK BLOCK */\r
1138                                 nullMarkBound ();\r
1139                                  break;\r
1140                 case 0x11:              /* F3 -- Begin Block */\r
1141                          if (pEdit->oBufLast > 0)  {\r
1142                    coordCursor_oBuf ();\r
1143                    pEdit->oBufMark = pEdit->oBufInsert;\r
1144                    i = pEdit->iLine;\r
1145                    if (pEdit->oBufMark >= pEdit->Line[i+1])\r
1146                       pEdit->oBufMark = pEdit->oBufMark - 1;\r
1147                    if (pEdit->oBufMark == pEdit->oBufLast)\r
1148                       pEdit->oBufMark = pEdit->oBufLast - 1;\r
1149                    pEdit->oBufBound = pEdit->oBufMark;\r
1150                    fScreen = TRUE;\r
1151                  }\r
1152                  break;\r
1153                 case 0x12:              /* F4 -- End Block */\r
1154                         if (pEdit->oBufMark < EMPTY)  {\r
1155                    coordCursor_oBuf ();\r
1156                    pEdit->oBufBound = pEdit->oBufInsert;\r
1157                    i = pEdit->iLine;\r
1158                    if (pEdit->oBufBound >= pEdit->Line[i+1])\r
1159                       pEdit->oBufBound--;\r
1160                    if (pEdit->oBufBound == pEdit->oBufLast)\r
1161                       pEdit->oBufBound = pEdit->oBufLast - 1;\r
1162                    fScreen = TRUE;\r
1163                  }\r
1164                  break;\r
1165                 case 0x17:      /* F9 - MOVE */\r
1166                    coordCursor_oBuf ();\r
1167                    moveData ();\r
1168                    if (pEdit->oBufInsert < pEdit->oBufLine0)\r
1169                       pEdit->oBufLine0 = pEdit->oBufInsert;\r
1170                    fScreen = TRUE;\r
1171                                  break;\r
1172                 case 0x18:      /* F10 - COPY */\r
1173                    coordCursor_oBuf ();\r
1174                    CopyIt ();\r
1175                    coordCursor_oBuf ();\r
1176                    fScreen = TRUE;\r
1177                                  break;\r
1178                 case 0x0C:      /* Page Down */\r
1179                    coordCursor_oBuf ();\r
1180                    i = pEdit->iRowMax;\r
1181                    while ((pEdit->Line[i] == EMPTY) && (i > pEdit->iRowMin))\r
1182                         i--;\r
1183                    pEdit->oBufLine0 = pEdit->Line[i];\r
1184                                  /*always keep onScreen*/\r
1185                    if (pEdit->oBufInsert < pEdit->oBufLine0)\r
1186                       pEdit->oBufInsert = pEdit->oBufLine0;\r
1187                    pEdit->iLine = pEdit->iRowMin;\r
1188                    pEdit->iCol = pEdit->iColMin;\r
1189                    fScreen = TRUE;\r
1190                                  break;\r
1191                 case 0x05:      /* Page Up */\r
1192                          if (pEdit->oBufLine0)  {\r
1193                    coordCursor_oBuf ();\r
1194                    j = pEdit->iRowMax - pEdit->iRowMin;\r
1195                    i = pEdit->oBufLine0;\r
1196                    k = pEdit->iLine;   /*fix for scrolling when iLine=iRowMax */\r
1197                    do {\r
1198                      i = findPrevLine (i);\r
1199                      j--;\r
1200                      k--;\r
1201                                    }\r
1202                    while ((j > 0) && (i > 0));\r
1203                    pEdit->oBufLine0 = i;\r
1204                            /*fix for scroll when iLine=iRowMax*/\r
1205                    if (pEdit->iLine == pEdit->iRowMax)\r
1206                       pEdit->oBufInsert = pEdit->Line[k];\r
1207                              /*keep on screen*/\r
1208                                    i = pEdit->iRowMax;\r
1209                    if (pEdit->oBufInsert >= pEdit->Line[i+1])\r
1210                       pEdit->oBufInsert = pEdit->Line[i];\r
1211                    fScreen = TRUE;\r
1212                  }\r
1213                                  break;\r
1214                 case 0x01:      /* Up */\r
1215                         if (pEdit->iLine > pEdit->iRowMin)  {\r
1216                    pEdit->iLine--;\r
1217                  } else {               /* scroll screen down if we can */\r
1218                                         i = pEdit->oBufLine0;\r
1219                                 if (i > 0)  {\r
1220                                 i = findPrevLine (i);\r
1221                                 pEdit->oBufLine0 = i;\r
1222                         pEdit->oBufInsert = i;\r
1223                                 fScreen = TRUE;\r
1224                                     }\r
1225                  }\r
1226                                  break;\r
1227                 case 0x02:      /* Down */\r
1228                         i = pEdit->iLine;\r
1229                         if ((pEdit->Line[i+1] < EMPTY) &&   /*Down Arrow*/\r
1230                         (i < pEdit->iRowMax))  {\r
1231                    pEdit->iLine++;\r
1232                 }\r
1233                                 else {                  /* ELSE scroll screen UP if we can */\r
1234                                         i = pEdit->iRowMax;\r
1235                                 if (pEdit->Line[i+1] < EMPTY)  {\r
1236                                 pEdit->oBufInsert = pEdit->Line[i+1];\r
1237                                                 i = pEdit->iCol;\r
1238                                                 j = pEdit->iLine;\r
1239                                                 coordCursor_oBuf ();\r
1240                                                 pEdit->iCol = i;\r
1241                                                 pEdit->iLine = j;\r
1242                                 fScreen = TRUE;\r
1243                                         }\r
1244                 }\r
1245                                 break;\r
1246                 case 0x03:      /* Left */\r
1247                         if (pEdit->iCol > pEdit->iColMin)  {          /*Left Arrow*/\r
1248                    pEdit->iCol--;\r
1249                  }\r
1250                                  break;\r
1251                 case 0x04:      /* Right */\r
1252                         if (pEdit->iCol < pEdit->iColMax)  {\r
1253                    pEdit->iCol++;\r
1254                  }\r
1255                                  break;\r
1256                 case 0x0E:      /* Insert */\r
1257                    if (fOvertype)\r
1258                       fOvertype = FALSE;\r
1259                      else fOvertype = TRUE;\r
1260                                  break;\r
1261                 case 0x7F:      /* Delete */\r
1262                    coordCursor_oBuf ();\r
1263                    if ((pEdit->oBufLast) &&\r
1264                        (pEdit->oBufLast > pEdit->oBufInsert))  {\r
1265                      CopyData(pBuff,\r
1266                               pBuffWork,\r
1267                               pEdit->oBufLast+1);\r
1268                      CopyData(&pBuffWork[pEdit->oBufInsert+1],\r
1269                               &pBuff[pEdit->oBufInsert],\r
1270                               pEdit->oBufLast-pEdit->oBufInsert);\r
1271                      pBuff[pEdit->oBufLast] = 0;\r
1272                      pEdit->oBufLast--;\r
1273                      if ((pEdit->oBufInsert == pEdit->oBufMark) &&\r
1274                          (pEdit->oBufMark == pEdit->oBufBound))\r
1275                         nullMarkBound ();\r
1276                      if (pEdit->oBufMark < EMPTY)  {\r
1277                        if (pEdit->oBufInsert < pEdit->oBufMark)\r
1278                           pEdit->oBufMark--;\r
1279                        if (pEdit->oBufInsert < pEdit->oBufBound)\r
1280                           pEdit->oBufBound--;\r
1281                        if (pEdit->oBufMark == pEdit->oBufLast)\r
1282                           pEdit->oBufMark--;\r
1283                        if (pEdit->oBufBound == pEdit->oBufLast)\r
1284                           pEdit->oBufBound--;\r
1285                      }\r
1286                      fScreen = TRUE;\r
1287                      fModified = TRUE;\r
1288                    }\r
1289                                    break;\r
1290                         default:\r
1291                                 break;\r
1292                 }\r
1293         }\r
1294   } /* Not fDone */\r
1295 \r
1296 \r
1297   for (i=pEdit->iRowMin; i <=pEdit->iRowMax; i++)\r
1298     PutVidAttrs (pEdit->iColMin, i, pEdit->sLine+1, 0); /* REM buffer column */\r
1299 \r
1300   if (fh) {\r
1301         if (pEdit->fVisible)     /* fix visible characters */\r
1302              for (i=0; i <=pEdit->iBufMax; i++)\r
1303                  if (pBuff[i] == 0x07)\r
1304                           pBuff[i] = 0x20;\r
1305         pBuff[pEdit->oBufLast] = 0;\r
1306         if (fModified) {\r
1307                         erc = CheckErc(6, SetFileLFA(fh, 0));\r
1308                         if (!erc)\r
1309                                 erc = CheckErc(5, SetFileSize(fh,pEdit->oBufLast));\r
1310                         if (!erc)\r
1311                                 erc = CheckErc(3, WriteBytes (fh, pBuf1, pEdit->oBufLast, &i));\r
1312                         fModified = 0;\r
1313         }\r
1314         CloseFile(fh);\r
1315         cbFilename = 0;\r
1316   }\r
1317 \r
1318   *pbExitRet = b;\r
1319   return;\r
1320 }\r
1321 \r
1322 /************************************************************\r
1323  This is the main entry point for the editor. It aloocates\r
1324  two buffers of equal size(a main and a working buffer),\r
1325  and then checks for a single parameter which should be the\r
1326  name of the file to edit.\r
1327 *************************************************************/\r
1328 \r
1329 void main(U32 argc, U8 *argv[])\r
1330 {\r
1331 long i;\r
1332 \r
1333         ClrScr();\r
1334         SetJobName("Editor", 6);\r
1335         fh = 0;\r
1336 \r
1337     pEdit = &EdRec;\r
1338         erc = AllocPage(32, &pBuf1);    /* 32 pages = 128K */\r
1339     erc = AllocPage(32, &pBuf2);\r
1340 \r
1341     pEdit->pBuf                 = pBuf1;\r
1342     pEdit->pBufWork             = pBuf2;\r
1343     pEdit->iBufMax              = 131071;    /*sBuf - 1 */\r
1344     pEdit->iColMin      = 0;        /*Screen coordinates*/\r
1345     pEdit->iColMax      = 79;\r
1346     pEdit->iRowMin      = 1;\r
1347     pEdit->iRowMax      = 23;\r
1348     pEdit->sLine        = 80;       /* iColMax-iColMin+1 */\r
1349     pEdit->bSpace       = 0x20;\r
1350     pEdit->fVisible     = FALSE;\r
1351     pEdit->iAttrMark    = MARKVID;  /* Rev Vid*/\r
1352     pEdit->iAttrNorm    = EDVID;    /* Rev Vid Half Bright    */\r
1353     pEdit->iTabNorm     = 4;        /* Tabs every 4th column  */\r
1354     pEdit->oBufLine0    = 0;        /* oBufLine0 */\r
1355     pEdit->iCol         = 0;        /* cursor, 0..sLine-1  */\r
1356     pEdit->iLine        = 0;        /* cursor, 0..cLines-1    */\r
1357     pEdit->oBufInsert   = 0;        /* offset of next char in */\r
1358     pEdit->oBufLast     = 0;        /* offset+1 of last char  */\r
1359     pEdit->oBufMark     = EMPTY;\r
1360     pEdit->oBufBound    = EMPTY;\r
1361 \r
1362         SetNormVid(NORMVID);\r
1363 \r
1364         FillData(filler, 80, 0x20);\r
1365         for (i=0; i<NLINESMAX; i++)\r
1366        pEdit->Line[i] = EMPTY;\r
1367         i = pEdit->iRowMin;\r
1368         pEdit->Line[i] = 0;\r
1369 \r
1370         fModified = 0;\r
1371         fOvertype = FALSE;    /* Set Overtype OFF */\r
1372 \r
1373         if (argc > 1)\r
1374         {\r
1375                 OpenAFile(argv[1]);\r
1376         }\r
1377 \r
1378         Editor(&b);\r
1379         ExitJob(0);\r
1380 }\r