Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

1509 lines
50 KiB
Plaintext

1File: CCP.C Page 1
1 /*--------------------------------------------------------------*\
2 | ccp.c CONSOLE COMMAND PROCESSOR v1.1 |
3 | ========================= |
4 | |
5 | CP/M 68k: A CP/M derived operating system |
6 | |
7 | *==================================================* |
8 | *==================================================* |
9 | *THIS IS THE DUAL PROCESSOR,ROMABLE CP/M-68K SYSTEM* |
10 | *==================================================* |
11 | *==================================================* |
12 | |
13 | Description: |
14 | ----------- |
15 | The Console Command Processor is a |
16 | distinct program which references |
17 | the BDOS to provide a human-oriented |
18 | interface for the console user to the |
19 | information maintained by the BDOS on |
20 | disk storage. |
21 | |
22 | created by : Tom Saulpaugh Date created: 7/13/82 |
23 | ---------- ------------ |
24 | last modified: 03/17/83 St. Patrick's Day!!! |
25 | ------------- -------------------- |
26 | |
27 | (c) COPYRIGHT Digital Research 1983 |
28 | all rights reserved |
29 | |
30 \*--------------------------------------------------------------*/
31
1File: CCP.C Page 2
32
33 /*--------------------------------------------------------------*\
34 | CCP Macro Definitions |
35 \*--------------------------------------------------------------*/
36 #include "ccpdef.h" /* include CCP defines */
37
38
39 /*--------------------------------------------------------------*\
40 | CP/M Builtin Command Table |
41 \*--------------------------------------------------------------*/
42 struct _cmd_tbl
43 {
44 BYTE *ident; /* command identifer field */
45 UWORD cmd_code; /* command code field */
46 }
47 cmd_tbl[8] = /* declare CP/M built-in table */
48 {
49 "DIR",DIRCMD,
50 "DIRS",DIRSCMD,
51 "TYPE",TYPECMD,
52 "REN",RENCMD,
53 "ERA",ERACMD,
54 "USER",UCMD,
55 "SUBMIT",SUBCMD,
56 NULL,-1
57 };
58 /*--------------------------------------------------------------*\
59 | CP/M-68K COMMAND FILE LOADER TABLE |
60 \*--------------------------------------------------------------*/
61 extern struct _filetyps
62 {
63 BYTE *typ;
64 UWORD (*loader) ();
65 BYTE user_c;
66 BYTE user_0;
67 }
68 load_tbl[];
69
70
71
72
1File: CCP.C Page 3
73 /*--------------------------------------------------------------*\
74 | Table of User Prompts and Messages |
75 \*--------------------------------------------------------------*/
76 BYTE msg[] = "NON-SYSTEM FILE(S) EXIST$";
77 BYTE msg2[] = "Enter Filename: $";
78 BYTE msg3[] = "Enter Old Name: $";
79 BYTE msg4[] = "Enter New Name: $";
80 BYTE msg5[] = "File already exists$";
81 BYTE msg6[] = "No file$";
82 BYTE msg7[] = "No wildcard filenames$";
83 BYTE msg8[] = "Syntax: REN Newfile=Oldfile$";
84 BYTE msg9[] = "Confirm(Y/N)? $";
85 BYTE msg10[] = "Enter User No: $";
86 BYTE msg11[] = ".SUB file not found$";
87 BYTE msg12[] = "User # range is [0-15]$";
88 BYTE msg13[] = "Too many arguments: $";
89 BYTE lderr1[] = "insufficient memory or bad file header$";
90 BYTE lderr2[] = "read error on program load$";
91 BYTE lderr3[] = "bad relocation information bits$";
92 BYTE lderror[] = "program load error$";
93 /*--------------------------------------------------------------*\
94 | Global Arrays & Variables |
95 \*--------------------------------------------------------------*/
96
97 /********************************/
98 BYTE load_try; /* flag to mark a load try */
99 BYTE first_sub; /* flag to save current cmd ptr */
100 BYTE chain_sub; /* submit chaining flag */
101 extern BYTE submit; /* submit file flag */
102 BYTE end_of_file; /* submit end of file flag */
103 BYTE dirflag; /* used by fill_fcb(? or blanks)*/
104 BYTE subprompt; /* submit file was prompted for */
105 extern BYTE morecmds; /* command after warmboot flag */
106 UWORD sub_index; /* index for subdma buffer */
107 UWORD index; /* index into cmd argument array*/
108 UWORD sub_user; /* submit file user number */
109 UWORD user; /* current default user number */
110 UWORD cur_disk; /* current default disk drive */
111 BYTE subcom[CMD_LEN+1]; /* submit command buffer */
112 BYTE subdma[CMD_LEN]; /* buffer to fill from sub file */
113 extern BYTE usercmd[CMD_LEN+2]; /* user command buffer */
114 BYTE *user_ptr; /* next user command to execute */
115 BYTE *glb_index; /* points to current command */
116 BYTE save_sub[CMD_LEN+1]; /* saves cur cmd line for submit*/
117 BYTE subfcb[FCB_LEN]; /* global fcb for sub files */
118 BYTE cmdfcb[FCB_LEN]; /* global fcb for 68k files */
119 BYTE *tail; /* pointer to command tail */
120 extern BYTE autost; /* autostart flag */
121 BYTE autorom; /* needed for ROM system autost */
122 BYTE dma[DMA_LEN+3]; /* 128 byte dma buffer */
123 BYTE parm[MAX_ARGS][ARG_LEN]; /* cmd argument array */
124 BYTE del[] = /* CP/M-68K set of delimeters */
125 {'>','<','.',',','=','[',']',';','|','&','/','(',')','+','-','\\'};
126 /********************************/
127
128
1File: CCP.C Page 4
129
130 /*--------------------------------------------------------------*\
131 | Function Definitions |
132 \*--------------------------------------------------------------*/
133
134 /********************************/
135 extern UWORD bdos(); /* this returns a word */
136 extern UWORD load68k(); /* this returns a word(1-3) */
137 BYTE *scan_cmd(); /* this returns a ptr to a byte */
138 UWORD strcmp(); /* this returns a word */
139 UWORD decode(); /* this returns a word */
140 UWORD delim(); /* this returns a word */
141 BYTE true_char(); /* this returns a byte */
142 UWORD fill_fcb(); /* this returns a word */
143 UWORD too_many(); /* this returns a word */
144 UWORD find_colon(); /* this returns a word */
145 UWORD chk_colon(); /* this returns a word */
146 UWORD user_cmd(); /* this returns a word */
147 UWORD cmd_file(); /* this returns a word */
148 UWORD sub_read(); /* this returns a word */
149 UWORD dollar(); /* this returns a word */
150 UWORD comments(); /* this returns a word */
151 UWORD submit_cmd(); /* this returns a word */
152 /********************************/
153
1File: CCP.C Page 5
154 /********************************/
155 VOID cr_lf() /* print a CR and a Linefeed */
156 /********************************/
157 {
158 bdos(CONSOLE_OUTPUT,CR);
159 bdos(CONSOLE_OUTPUT,LF);
160 }
161 /********************************/
162 VOID cpy(source,dest) /* copy source to destination */
163 /********************************/
164 REG BYTE *source;
165 REG BYTE *dest;
166 {
167 while(*dest++ = *source++);
168 }
169
170
171 /********************************/
172 UWORD strcmp(s1,s2) /* compare 2 char strings */
173 /********************************/
174 REG BYTE *s1,*s2;
175 {
176 while(*s1)
177 {
178 if(*s1 > *s2)
179 return(1);
180 if(*s1 < *s2)
181 return(-1);
182 s1++; s2++;
183 }
184 return((*s2 == NULL) ? 0 : -1);
185 }
186 /********************************/
187 VOID copy_cmd(com_index) /* Save the command which */
188 /* started a submit file */
189 /* Parameter substituion will */
190 /* need this command tail. */
191 /* The buffer save_sub is used */
192 /* to store the command. */
193 /********************************/
194 REG BYTE *com_index;
195 {
196 REG BYTE *t1,*temp;
197
198 temp = save_sub;
199 if(subprompt)
200 {
201 t1 = parm;
202 while(*t1)
203 *temp++ = *t1++;
204 *temp++ = ' ';
205 subprompt = FALSE;
206 }
207 while(*com_index && *com_index != EXLIMPT)
208 *temp++ = *com_index++;
209 *temp = NULL;
210 }
211
212
1File: CCP.C Page 6
213
214 /********************************/
215 VOID prompt() /* print the CCP prompt */
216 /********************************/
217 {
218 REG UWORD cur_drive,cur_user_no;
219 BYTE buffer[3];
220
221 cur_user_no = bdos(GET_USER_NO,(long)255);
222 cur_drive = bdos(RET_CUR_DISK,(long)0);
223 cur_drive += 'A';
224 cr_lf();
225 if(cur_user_no)
226 {
227 if(cur_user_no >= 10)
228 {
229 buffer[0] = '1';
230 buffer[1] = ((cur_user_no-10) + '0');
231 buffer[2] = '$';
232 }
233 else
234 {
235 buffer[0] = (cur_user_no + '0');
236 buffer[1] = '$';
237 }
238 bdos(PRINT_STRING,buffer);
239 }
240 bdos(CONSOLE_OUTPUT,(long)cur_drive);
241 bdos(CONSOLE_OUTPUT,ARROW);
242 }
243
244
245
246 /********************************/
247 VOID echo_cmd(cmd,mode) /* echo any multiple commands */
248 /* or any illegal commands */
249 /********************************/
250 REG BYTE *cmd;
251 REG UWORD mode;
252 {
253 if(mode == GOOD && (!(autost && autorom)))
254 prompt();
255 while(*cmd && *cmd != EXLIMPT)
256 bdos(CONSOLE_OUTPUT,(long)*cmd++);
257 if(mode == BAD)
258 bdos(CONSOLE_OUTPUT,(long)'?');
259 else
260 cr_lf();
261 }
262
1File: CCP.C Page 7
263
264 /********************************/
265 UWORD decode(cmd) /* Recognize the command as: */
266 /* --------- */
267 /* 1. Builtin */
268 /* 2. File */
269 /********************************/
270 REG BYTE *cmd;
271 {
272 REG UWORD i,n;
273
274
275 /****************************************/
276 /* Check for a CP/M builtin command */
277 /****************************************/
278 for(i = 0; i < 7;i++)
279 if (strcmp(cmd,cmd_tbl[i].ident) == MATCH)
280 return(cmd_tbl[i].cmd_code);
281 /********************************************************/
282 /* Check for a change of disk drive command */
283 /********************************************************/
284 i = 0;
285 while(i < (ARG_LEN-1) && parm[0][i] != ':')
286 i++;
287 if(i == 1 && parm[0][2] == NULL && parm[1][0] == NULL)
288 if((parm[0][0] >= 'A') && (parm[0][0] <= 'P'))
289 return(CH_DISK);
290 if(i == 1 && ((parm[0][0] < 'A') || (parm[0][0] > 'P')))
291 return(-1);
292 if(i != 1 && parm[0][i] == ':')
293 return(-1);
294 /*****************************************************/
295 /* Check for Wildcard Filenames */
296 /* Check Filename for a Delimeter */
297 /*****************************************************/
298 if(fill_fcb(0,cmdfcb) > 0)
299 return(-1);
300 if(i == 1)
301 i = 2;
302 else
303 i = 0;
304 if(delim(&parm[0][i]))
305 return(-1);
306 for(n = 0;n < ARG_LEN-1 && parm[0][n];n++)
307 if(parm[0][n] < ' ')
308 return(-1);
309 return(FILE);
310 }
311
1File: CCP.C Page 8
312 /************************/
313 VOID check_cmd(tcmd) /* Check end of cmd */
314 /* for an '!' which */
315 /* starts another cmd */
316 REG BYTE *tcmd; /************************/
317 {
318 while(*tcmd && *tcmd != EXLIMPT)
319 tcmd++;
320 /*----------------------------*/
321 /* check for multiple command */
322 /* in case of a warmboot */
323 /*----------------------------*/
324 if(*tcmd++ == EXLIMPT && *tcmd)
325 {
326 morecmds = TRUE;
327 while(*tcmd == ' ')
328 tcmd++;
329 user_ptr = tcmd;
330 }
331 else
332 if(submit) /* check original cmd line */
333 {
334 if(!(end_of_file))
335 morecmds = TRUE;
336 /*--------------------------*/
337 else /* restore cmd to where user*/
338 /* ptr points to. User_ptr */
339 /* always points to next */
340 /* console command to exec */
341 { /*--------------------------*/
342 submit = FALSE;
343 if(*user_ptr)
344 morecmds = TRUE;
345 }
346 }
347 else
348 morecmds = FALSE;
349 }
350
1File: CCP.C Page 9
351 /************************/
352 VOID get_cmd(cmd,max_chars) /* Read in a command */
353 /*Strip off extra blanks*/
354 /************************/
355 REG BYTE *cmd;
356 REG long max_chars;
357 {
358 REG BYTE *c;
359
360 max_chars += (cmd - 1);
361 dma[0] = CMD_LEN; /* set maximum chars to read */
362 bdos(READ_CONS_BUF,dma); /* then read console */
363 if(dma[1] != 0 && dma[2] != ';')
364 cr_lf();
365 dma[((UWORD)dma[1] & 0xFF)+2] = '\n'; /* tack on end of line char */
366 if(dma[2] == ';') /* ';' denotes a comment */
367 dma[2] = '\n';
368 c = &dma[2];
369 while(*c == ' ' || *c == TAB)
370 c++;
371 while(*c != '\n' && cmd < max_chars)
372 {
373 *cmd++ = toupper(*c);
374 if(*c == ' ' || *c == TAB)
375 while(*++c == ' ' || *c == TAB);
376 else
377 c++;
378 }
379 *cmd = NULL; /* tack a null character on the end*/
380 }
381 /************************/
382 BYTE *scan_cmd(com_index) /* move ptr to next cmd */
383 /* in the command line */
384 /************************/
385 REG BYTE *com_index;
386 {
387 while((*com_index != EXLIMPT) &&
388 (*com_index))
389 com_index++;
390 while(*com_index == EXLIMPT || *com_index == ' ' ||
391 *com_index == TAB)
392 com_index++;
393 return(com_index);
394 }
395
1File: CCP.C Page 10
396
397 /************************/
398 VOID get_parms(cmd) /* extract cmd arguments*/
399 /* from command line */
400 REG BYTE *cmd; /************************/
401 {
402
403
404
405 /************************************************/
406 /* This function parses the command line */
407 /* read in by get_cmd(). The expected command */
408 /* from that line is put into parm[0]. All */
409 /* parmeters associated with the command are put*/
410 /* in in sequential order in parm[1],parm[2], */
411 /* and parm[3]. A command ends at a NULL or */
412 /* an exlimation point. */
413 /************************************************/
414
415
416 REG BYTE *line; /* pointer to parm array */
417 REG UWORD i; /* Row Index */
418 REG UWORD j; /* Column Index */
419
420 line = parm;
421 for(i = 0; i < (MAX_ARGS * ARG_LEN); i++)
422 *line++ = NULL;
423
424 i = 0;
425 /***************************************************/
426 /* separate command line at blanks,exlimation pts */
427 /***************************************************/
428
429 while(*cmd != NULL &&
430 *cmd != EXLIMPT &&
431 i < MAX_ARGS)
432 {
433 j = 0;
434 while(*cmd != EXLIMPT &&
435 *cmd != ' ' &&
436 *cmd != TAB &&
437 *cmd)
438 {
439 if(j < (ARG_LEN-1))
440 parm[i][j++] = *cmd;
441 cmd++;
442 }
443 parm[i++][j] = NULL;
444 if(*cmd == ' ' || *cmd == TAB)
445 cmd++;
446 if(i == 1)
447 tail = cmd; /* mark the beginning of the tail */
448 }
449 }
450
1File: CCP.C Page 11
451
452 /************************/
453 UWORD delim(ch) /* check ch to see */
454 /* if it's a delimeter */
455 /************************/
456 REG BYTE *ch;
457 {
458 REG UWORD i;
459
460 if(*ch <= ' ')
461 return(TRUE);
462 for(i = 0;i < sizeof (del);i++)
463 if(*ch == del[i]) return(TRUE);
464 return(FALSE);
465 }
466
467
468
469 /************************/
470 BYTE true_char(ch) /* return the desired */
471 /* character for fcb */
472 /************************/
473
474 REG BYTE *ch;
475 {
476 if(*ch == '*') return('?'); /* wildcard */
477
478 if(!delim(ch)) /* ascii character */
479 {
480 index++; /* increment cmd index */
481 return(*ch);
482 }
483
484 return(' '); /* pad field with blank */
485 }
486
1File: CCP.C Page 12
487 /************************/
488 UWORD fill_fcb(which_parm,fcb) /* fill the fields of */
489 /* the file control blk */
490 /************************/
491
492 REG UWORD which_parm;
493 REG BYTE *fcb;
494 {
495 REG BYTE *ptr;
496 REG BYTE fillch;
497 REG UWORD j,k;
498
499 *fcb = 0;
500 for(k = 12;k <= 35; k++) /* fill fcb with zero */
501 fcb[k] = ZERO;
502 for(k = 1;k <= 11;k++)
503 fcb[k] = BLANK; /* blank filename+type */
504
505 /*******************************************/
506 /* extract drivecode,filename and filetype */
507 /* from parmeter blk */
508 /*******************************************/
509
510 if(dirflag)
511 fillch = '?';
512 else
513 fillch = ' ';
514
515 index = ZERO;
516 ptr = fcb;
517 if(parm[which_parm][index] == NULL) /* no parmemters */
518 {
519 ptr++;
520 for(j = 1;j <= 11;j++)
521 *ptr++ = fillch;
522 *fcb = (bdos(RET_CUR_DISK,(long)0)+1);
523 if(dirflag)
524 return(11);
525 else
526 return(0);
527 }
528 if(parm[which_parm][index+1] == ':')
529 {
530 *ptr = parm[which_parm][index] - 'A' + 1;
531 index += 2;
532 if(parm[which_parm][index] == NULL)
533 {
534 ptr = &fcb[1];
535 for(j = 1;j <= 11;j++)
536 *ptr++ = fillch;
537 if(dirflag)
538 return(11);
539 else
540 return(0);
541 }
542 }
543 else /* fill drivecode with the default disk */
544 *fcb = (bdos(RET_CUR_DISK,(long)0) + 1);
545
1File: CCP.C Page 13
546 ptr = fcb;
547 ptr++; /* set pointer to fcb filename */
548 for(j = 1;j <= 8;j++) /* get filename */
549 *ptr++ = true_char(&parm[which_parm][index]);
550 while((!(delim(&parm[which_parm][index])))) index++;
551 if(parm[which_parm][index] == PERIOD)
552 {
553 index++;
554 for(j = 1;j <= 3;j++) /* get extension */
555 *ptr++ = true_char(&parm[which_parm][index]);
556 }
557 k = 0;
558 for(j = 1;j <= 11;j++)
559 if(fcb[j] == '?') k++;
560
561 return(k); /* return the number of question marks */
562 }
563 /************************/
564 UWORD too_many() /* too many args ? */
565 { /************************/
566 if(parm[2][0])
567 {
568 bdos(PRINT_STRING,msg13);
569 echo_cmd(&parm[2][0],BAD);
570 return(TRUE);
571 }
572 return(FALSE);
573 }
574 /************************/
575 UWORD find_colon() /* search for a colon */
576 { /************************/
577 REG UWORD i;
578
579 i = 0;
580 while(parm[1][i] && parm[1][i] != ':') i++;
581 return(i);
582 }
583 /************************/
584 UWORD chk_colon(j) /* check the position of*/
585 UWORD j; /* the colon and for */
586 { /* a legal drive letter */
587 if(parm[1][j] == ':') /************************/
588 {
589 if(j != 1 || parm[1][0] < 'A' || parm[1][0] > 'P')
590 {
591 echo_cmd(&parm[1][0],BAD);
592 return(FALSE);
593 }
594 }
595 return(TRUE);
596 }
597
598
1File: CCP.C Page 14
599
600
601 /************************/
602 VOID dir_cmd(attrib) /* print out a */
603 /* directory listing */
604 /*----------------------*/
605 /* attrib->1 (sysfiles) */
606 /* attrib->0 (dirfiles) */
607 /************************/
608 REG UWORD attrib;
609 {
610 BYTE needcr_lf;
611 REG UWORD dir_index,file_cnt;
612 REG UWORD save,j,k,curdrive,exist;
613
614 exist = FALSE; needcr_lf = FALSE;
615 if(too_many()) return;
616 j = find_colon();
617 if(!chk_colon(j)) return;
618 fill_fcb(1,cmdfcb);
619 curdrive = (cmdfcb[0] + 'A' - 1);
620 dir_index = bdos(SEARCH_FIRST,cmdfcb);
621 if(dir_index == 255)
622 bdos(PRINT_STRING,msg6);
623 save = (32 * dir_index) + 1;
624 file_cnt = 0;
625 while(dir_index != 255)
626 {
627 if(((attrib) && (dma[save+9] & 0x80)) ||
628 (!(attrib) && (!(dma[save+9] & 0x80))))
629 {
630 if(needcr_lf)
631 {
632 cr_lf();
633 needcr_lf = FALSE;
634 }
635 if(file_cnt == 0)
636 bdos(CONSOLE_OUTPUT,(long)curdrive);
637 }
638 else
639 {
640 exist = TRUE;
641 dir_index = bdos(SEARCH_NEXT);
642 save = (32 * dir_index) + 1;
643 continue;
644 }
645 dir_index = (32 * dir_index) + 1;
646 bdos(CONSOLE_OUTPUT,COLON);
647 bdos(CONSOLE_OUTPUT,BLANKS);
648 j = 1;
649 while(j <= 11)
650 {
651 if(j == 9)
652 bdos(CONSOLE_OUTPUT,BLANKS);
653 bdos(CONSOLE_OUTPUT,(long)(dma[dir_index++] & CMASK));
654 j++;
655 }
656 bdos(CONSOLE_OUTPUT,BLANKS);
657 dir_index = bdos(SEARCH_NEXT);
1File: CCP.C Page 15
658 if(dir_index == 255)
659 break;
660 file_cnt++;
661 save = (32 * dir_index) + 1;
662 if(file_cnt == 5)
663 {
664 file_cnt = 0;
665 if((attrib && (dma[save+9] & 0x80)) ||
666 (!(attrib) && (!(dma[save+9] & 0x80))))
667 cr_lf();
668 else
669 needcr_lf = TRUE;
670 }
671
672 } /*----------------------------------------*/
673 if(exist) /* if files exist that were not displayed */
674 /* print out a message to the console */
675 { /*----------------------------------------*/
676 cr_lf();
677 if(attrib)
678 bdos(PRINT_STRING,msg);
679 else
680 bdos(PRINT_STRING,&msg[4]);
681 }
682 }
683
684
685
686
1File: CCP.C Page 16
687
688 /************************/
689 VOID type_cmd() /* type out a file */
690 /* to the console */
691 /************************/
692 {
693 REG UWORD i;
694
695 if(parm[1][0] == NULL) /*prompt user for filename*/
696 {
697 bdos(PRINT_STRING,msg2);
698 get_cmd(&parm[1][0],(long)(ARG_LEN-1));
699 }
700 if(too_many())
701 return;
702 i = find_colon();
703 if(!chk_colon(i)) return;
704 i = fill_fcb(1,cmdfcb); /*fill a file control block*/
705 if(i == 0 && parm[1][0] && (bdos(OPEN_FILE,cmdfcb) <= 3))
706 {
707 while(bdos(READ_SEQ,cmdfcb) == 0)
708 {
709 for(i = 0;i <= 127;i++)
710 if(dma[i] != EOF)
711 bdos(CONSOLE_OUTPUT,(long)dma[i]);
712 else
713 break;
714 }
715 bdos(RESET_DRIVE,(long)cmdfcb[0]);
716 } else
717 if(parm[1][0])
718 {
719 if(i > 0)
720 bdos(PRINT_STRING,msg7);
721 else
722 bdos(PRINT_STRING,msg6);
723 }
724 }
725
1File: CCP.C Page 17
726
727
728 /************************/
729 VOID ren_cmd() /* rename a file */
730 /************************/
731
732 {
733 BYTE new_fcb[FCB_LEN];
734 REG UWORD i,j,k,bad_cmd;
735
736 bad_cmd = FALSE; /*-------------------------*/
737 if(parm[1][0] == NULL) /*prompt user for filenames*/
738 { /*-------------------------*/
739 bdos(PRINT_STRING,msg3);
740 get_cmd(&parm[3][0],(long)(ARG_LEN-1));
741 if(parm[3][0] == NULL)
742 return;
743 bdos(PRINT_STRING,msg4);
744 get_cmd(&parm[1][0],(long)(ARG_LEN-1));
745 parm[2][0] = '=';
746 } /*--------------------------------*/
747 else /*check for correct command syntax*/
748 { /*--------------------------------*/
749 i = 0;
750 while(parm[1][i] != '=' && parm[1][i]) i++;
751 if(parm[1][i] == '=')
752 {
753 if(!(i > 0 && parm[1][i+1] &&
754 parm[2][0] == NULL))
755 bad_cmd = TRUE;
756 }
757 else
758 if(!(parm[2][0] == '=' &&
759 parm[2][1] == NULL &&
760 parm[3][0]))
761 bad_cmd = TRUE;
762 if(!bad_cmd && parm[1][i] == '=')
763 {
764 parm[1][i] = NULL;
765 i++;
766 j = 0;
767 while((parm[3][j++] = parm[1][i++]) != NULL);
768 parm[2][0] = '=';
769 }
770 }
771 for(j = 1;j < 4;j += 2)
772 {
773 k = 0;
774 while(parm[j][k] != ':' && parm[j][k])
775 k++;
776 if(k > 1 && parm[j][k] == ':')
777 bad_cmd = TRUE;
778 for(i = 0;i < sizeof del;i++)
779 if(parm[j][0] == del[i])
780 {
781 echo_cmd(&parm[j][0],BAD);
782 return;
783 }
784 }
1File: CCP.C Page 18
785 if(!bad_cmd && parm[1][0] && parm[3][0])
786 {
787 i = fill_fcb(1,new_fcb);
788 j = fill_fcb(3,cmdfcb);
789 if(i == 0 && j == 0)
790 {
791 if(new_fcb[0] != cmdfcb[0])
792 {
793 if(parm[1][1] == ':' && parm[3][1] != ':')
794 cmdfcb[0] = new_fcb[0];
795 else
796 if(parm[1][1] != ':' && parm[3][1] == ':')
797 new_fcb[0] = cmdfcb[0];
798 else
799 bad_cmd = TRUE;
800 }
801 if(new_fcb[0] < 1 || new_fcb[0] > 16)
802 bad_cmd = TRUE;
803 if(!(bad_cmd) && bdos(SEARCH_FIRST,new_fcb) != 255)
804 bdos(PRINT_STRING,msg5);
805 else{
806 k = 0;
807 for(i = 16;i <= 35;i++)
808 cmdfcb[i] = new_fcb[k++];
809 if(cmdfcb[0] < 0 || cmdfcb[0] > 15)
810 bad_cmd = TRUE;
811 if(!(bad_cmd) &&
812 bdos(RENAME_FILE,cmdfcb) > 0)
813 bdos(PRINT_STRING,msg6);
814 }
815 }
816 else
817 bdos(PRINT_STRING,msg7);
818 }
819 if(bad_cmd)
820 bdos(PRINT_STRING,msg8);
821 }
822
1File: CCP.C Page 19
823
824 /************************/
825 VOID era_cmd() /* erase a file from */
826 /* the directory */
827 /************************/
828 {
829 REG UWORD i;
830 /*----------------------*/
831 if(parm[1][0] == NULL) /* prompt for a file */
832 { /*----------------------*/
833 bdos(PRINT_STRING,msg2);
834 get_cmd(&parm[1][0],(long)(ARG_LEN-1));
835 }
836 if(parm[1][0] == NULL)
837 return;
838 if(too_many())
839 return;
840 i = find_colon();
841 if(!chk_colon(i))
842 return;
843 else
844 if(parm[1][1] == ':' && parm[1][2] == NULL)
845 {
846 echo_cmd(&parm[1][0],BAD);
847 return;
848 }
849 i = fill_fcb(1,cmdfcb); /* fill an fcb */
850 if(i > 0 && !(submit)) /* no confirmation */
851 { /* if submit file */
852 bdos(PRINT_STRING,msg9);
853 parm[2][0] = bdos(CONIN,(long)0);
854 parm[2][0] = toupper(parm[2][0]);
855 cr_lf();
856 if(parm[2][0] != 'N' && parm[2][0] != 'Y')
857 return;
858 }
859 if(parm[2][0] != 'N')
860 if(bdos(DELETE_FILE,cmdfcb) > 0)
861 bdos(PRINT_STRING,msg6);
862 }
863
1File: CCP.C Page 20
864 /************************/
865 UWORD user_cmd() /* change user number */
866 /************************/
867
868 {
869 REG UWORD i;
870
871 if(parm[1][0] == NULL) /* prompt for a number */
872 {
873 bdos(PRINT_STRING,msg10);
874 get_cmd(&parm[1][0],(long)(ARG_LEN-1));
875 }
876 if(parm[1][0] == NULL)
877 return(TRUE);
878 if(too_many())
879 return(TRUE);
880 if(parm[1][0] < '0' || parm[1][0] > '9')
881 return(FALSE);
882 i = (parm[1][0] - '0');
883 if(i > 9)
884 return(FALSE);
885 if(parm[1][1])
886 i = ((i * 10) + (parm[1][1] - '0'));
887 if(i < 16 && parm[1][2] == NULL)
888 bdos(GET_USER_NO,(long)i);
889 else
890 return(FALSE);
891 return(TRUE);
892 }
893
894
1File: CCP.C Page 21
895 UWORD cmd_file(mode)
896 /************************/
897 /* */
898 /* SEARCH ORDER */
899 /* ============ */
900 /* */
901 /* 1. 68K type on the */
902 /* current user # */
903 /* 2. BLANK type on */
904 /* current user # */
905 /* 3. SUB type on the */
906 /* current user # */
907 /* 4. 68K type on */
908 /* user 0 */
909 /* 5. BLANK type on the */
910 /* user 0 */
911 /* 6. SUB type on */
912 /* user 0 */
913 /* */
914 /*----------------------*/
915 /* */
916 /* If a filetype is */
917 /* specified then I */
918 /* search the current */
919 /* user # then user 0 */
920 /* */
921 /************************/
922 UWORD mode;
923 {
924 BYTE done,open,sub_open;
925 BYTE found;
926 REG UWORD i,n;
927 UWORD (*ldrpgm) ();
928 REG BYTE *top;
929 REG struct _filetyps *p;
930
931 dirflag = FALSE;
932 load_try = TRUE;
933 done = FALSE;
934 found = FALSE;
935 sub_open = FALSE;
936 open = FALSE;
937
938 user = bdos(GET_USER_NO,(long)255);
939 cur_disk = bdos(RET_CUR_DISK,(long)0);
940 if(mode == SEARCH) i = 0; else i = 1;
941 i = fill_fcb(i,cmdfcb);
942 if(i > 0)
943 {
944 bdos(PRINT_STRING,msg7);
945 return(FALSE);
946 }
947 p = &load_tbl;
948 top = p->typ;
949 if(cmdfcb[9] == ' ')
950 {
951 while(*(p->typ)) /* clear flags in table */
952 {
953 p->user_c = p->user_0 = FALSE;
1File: CCP.C Page 22
954 p++;
955 }
956 bdos(SELECT_DISK,(long)(cmdfcb[0]-1));
957 cmdfcb[0] = '?'; cmdfcb[12] = NULL;
958 i = bdos(SEARCH_FIRST,cmdfcb);
959 while(i != 255 && !(done))
960 {
961 i *= 32;
962 if(dma[i] == 0 || dma[i] == user)
963 {
964 for(n = 9;n <= 11;n++) dma[i+n] &= CMASK;
965 dma[i+12] = NULL;
966 p = &load_tbl;
967 while(*(p->typ))
968 {
969 cpy(p->typ,&cmdfcb[9]);
970 if(strcmp(&cmdfcb[1],&dma[i+1]) == MATCH)
971 {
972 found = TRUE;
973 if(dma[i] == user) p->user_c = TRUE;
974 else p->user_0 = TRUE;
975 if(mode == SEARCH &&
976 strcmp(p->typ,top) == MATCH && p->user_c)
977 done = TRUE;
978 }
979 p++;
980 }
981 }
982 i = bdos(SEARCH_NEXT);
983 }
984 if(!(found))
985 {
986 if(mode == SUB_FILE) bdos(PRINT_STRING,msg11);
987 dirflag = TRUE; load_try = FALSE;
988 bdos(SELECT_DISK,(long)cur_disk); return(FALSE);
989 }
990 if(mode == SEARCH)
991 fill_fcb(0,cmdfcb);
992 else
993 fill_fcb(1,cmdfcb);
994 p = &load_tbl;
995 while(*(p->typ))
996 {
997 if(p->user_c || p->user_0)
998 {
999 if(mode == SEARCH) break;
1000 if(strcmp(p->typ,"SUB") == MATCH) break;
1001 }
1002 p++;
1003 }
1004 if(*(p->typ))
1005 {
1006 if(!(p->user_c)) bdos(GET_USER_NO,(long)0);
1007 cpy(p->typ,&cmdfcb[9]);
1008 }
1009 }
1010 bdos(SELECT_DISK,(long)cur_disk);
1011 while(1)
1012 {
1File: CCP.C Page 23
1013 if(bdos(OPEN_FILE,cmdfcb) <= 3)
1014 {
1015 for(n = 9;n <= 11;n++) cmdfcb[n] &= CMASK;
1016 if(cmdfcb[9] == 'S' && cmdfcb[10] == 'U' && cmdfcb[11] == 'B')
1017 {
1018 sub_open = TRUE;
1019 sub_user = bdos(GET_USER_NO,(long)255);
1020 if(submit) chain_sub = TRUE;
1021 else first_sub = TRUE;
1022 for(i = 0;i < FCB_LEN;i++)
1023 subfcb[i] = cmdfcb[i];
1024 if(mode == SEARCH) subprompt = FALSE;
1025 submit = TRUE;
1026 end_of_file = FALSE;
1027 }
1028 else if(mode != SUB_FILE)
1029 open = TRUE;
1030 break;
1031 }
1032 else if(bdos(GET_USER_NO,(long)255) == 0) break;
1033 else bdos(GET_USER_NO,(long)0);
1034 }
1035 if(open)
1036 {
1037 check_cmd(glb_index);
1038 if(!(found))
1039 {
1040 p = &load_tbl;
1041 while(*(p->typ))
1042 if(strcmp(p->typ,&cmdfcb[9]) == MATCH) break;
1043 else p++;
1044 }
1045 if(*(p->typ))
1046 ldrpgm = p->loader;
1047 else
1048 ldrpgm = load68k; /* default */
1049
1050 /* ATTEMPT THE PROGRAM LOAD */
1051
1052 switch( (*ldrpgm) (glb_index) )
1053 {
1054 case 1: bdos(PRINT_STRING,lderr1); break;
1055 case 2: bdos(PRINT_STRING,lderr2); break;
1056 case 3: bdos(PRINT_STRING,lderr3); break;
1057 default : bdos(PRINT_STRING,lderror);
1058 }
1059 }
1060 if(!(sub_open) && mode == SUB_FILE)
1061 bdos(PRINT_STRING,msg11);
1062 bdos(GET_USER_NO,(long)user);
1063 dirflag = TRUE;
1064 load_try = FALSE;
1065 morecmds = FALSE;
1066 return((sub_open || open));
1067 }
1068
1File: CCP.C Page 24
1069 /************************/
1070 UWORD sub_read() /* Read the submit file */
1071 { /************************/
1072 if(bdos(READ_SEQ,subfcb))
1073 {
1074 end_of_file = TRUE;
1075 return(FALSE);
1076 }
1077 return(TRUE);
1078 }
1079
1File: CCP.C Page 25
1080 /************************/
1081 UWORD dollar(k,mode,com_index) /* Translate $n to */
1082 /* nth argument on the */
1083 /* command line */
1084 /************************/
1085 REG UWORD k;
1086 REG UWORD mode;
1087 REG BYTE *com_index;
1088 {
1089 REG UWORD n,j,p_index;
1090 REG BYTE *p1;
1091
1092 j = sub_index;
1093 if(k >= CMD_LEN)
1094 {
1095 k = 0;
1096 if(!sub_read())
1097 return(k);
1098 }
1099 if((subdma[k] >= '0') && (subdma[k] <= '9'))
1100 {
1101 p_index = (subdma[k] - '0');
1102 p1 = com_index;
1103 if(*p1++ == 'S' &&
1104 *p1++ == 'U' &&
1105 *p1++ == 'B' &&
1106 *p1++ == 'M' &&
1107 *p1++ == 'I' &&
1108 *p1++ == 'T' &&
1109 *p1 == ' ')
1110 p_index++;
1111 p1 = com_index;
1112 for(n = 1; n <= p_index; n++)
1113 {
1114 while(*p1 != ' ' && *p1)
1115 p1++;
1116 if(*p1 == ' ')
1117 p1++;
1118 }
1119 while(*p1 != ' ' && *p1 && j < CMD_LEN)
1120 if(mode == FILL)
1121 subcom[j++] = *p1++;
1122 else
1123 bdos(CONSOLE_OUTPUT,(long)*p1++);
1124 k++;
1125 }
1126 else
1127 {
1128 if(mode == FILL)
1129 subcom[j++] = '$';
1130 else
1131 bdos(CONSOLE_OUTPUT,(long)'$');
1132 if(subdma[k] == '$')
1133 k++;
1134 }
1135 sub_index = j;
1136 if(k >= CMD_LEN)
1137 {
1138 k = 0;
1File: CCP.C Page 26
1139 sub_read();
1140 }
1141 return(k);
1142 }
1143 /************************/
1144 UWORD comments(k,com_index) /* Strip and echo submit*/
1145 /* file comments */
1146 /************************/
1147 REG UWORD k;
1148 REG BYTE *com_index;
1149 {
1150 REG UWORD done;
1151
1152 done = FALSE;
1153 prompt();
1154 do
1155 {
1156 while(k < CMD_LEN &&
1157 subdma[k] != EOF &&
1158 subdma[k] != Cr)
1159 {
1160 if(subdma[k] == '$')
1161 {
1162 k++;
1163 k = dollar(k,NOFILL,com_index);
1164 }
1165 else
1166 bdos(CONSOLE_OUTPUT,(long)subdma[k++]);
1167 }
1168 if(k == CMD_LEN && subdma[k] != EOF && subdma[k] != Cr)
1169 {
1170 k = 0;
1171 if(!sub_read()) done = TRUE;
1172 }
1173 else
1174 {
1175 if(subdma[k] == Cr)
1176 {
1177 k += 2;
1178 if(k >= CMD_LEN)
1179 {
1180 k = 0;
1181 sub_read();
1182 }
1183 }
1184 else
1185 end_of_file = TRUE;
1186 done = TRUE;
1187 }
1188 }while(!(done));
1189 return(k);
1190 }
1191
1File: CCP.C Page 27
1192 /************************/
1193 VOID translate(com_index) /* TRANSLATE the subfile*/
1194 /* and fill sub buffer. */
1195 /************************/
1196 REG BYTE *com_index;
1197 {
1198 REG BYTE *p1;
1199 REG UWORD j,n,k,p_index;
1200
1201 j = 0;
1202 k = sub_index;
1203 while(!(end_of_file) && j < CMD_LEN
1204 && subdma[k] != Cr && subdma[k] != EXLIMPT)
1205 {
1206 switch(subdma[k])
1207 {
1208 case ';': k = comments(k,com_index);
1209 break;
1210 case TAB:
1211 case ' ': if(j > 0)
1212 subcom[j++] = subdma[k++];
1213 blankout: while(k < CMD_LEN &&
1214 (subdma[k] == ' ' || subdma[k] == TAB))
1215 k++;
1216 if(k >= CMD_LEN)
1217 {
1218 k = 0;
1219 if(!sub_read());
1220 else
1221 goto blankout;
1222 }
1223 break;
1224 case '$': k++;
1225 sub_index = j;
1226 k = dollar(k,FILL,com_index);
1227 j = sub_index;
1228 break;
1229 case Lf: k++;
1230 if(k >= CMD_LEN)
1231 {
1232 k = 0;
1233 sub_read();
1234 }
1235 break;
1236 case EOF:
1237 end_of_file = TRUE;
1238 break;
1239 default: subcom[j++] = subdma[k++];
1240 if(k >= CMD_LEN)
1241 {
1242 k = 0;
1243 sub_read();
1244 }
1245 }
1246 }
1247 /*------------------------------------------------------------------*/
1248 /* TRANSLATION OF A COMMAND IS COMPLETE */
1249 /* -Now move sub_index to next command- */
1250 /*------------------------------------------------------------------*/
1File: CCP.C Page 28
1251
1252 if(subdma[k] == Cr || subdma[k] == EXLIMPT)
1253 do
1254 {
1255 while(k < CMD_LEN &&
1256 (subdma[k] == Cr ||
1257 subdma[k] == Lf ||
1258 subdma[k] == EXLIMPT))
1259 k++;
1260 if(k == CMD_LEN)
1261 {
1262 k = 0;
1263 if(!sub_read())
1264 break;
1265 }
1266 else
1267 {
1268 if(subdma[k] == EOF)
1269 end_of_file = TRUE;
1270 break;
1271 }
1272 }while(TRUE);
1273 sub_index = k;
1274 }
1275
1File: CCP.C Page 29
1276 /************************/
1277 UWORD submit_cmd(com_index) /* fill up the subcom */
1278 /* buffer */
1279 /************************/
1280 /*--------------------------------------------------------------*\
1281 | |
1282 | Submit_Cmd is a Procedure that returns exactly |
1283 | one command from the submit file. Submit_Cmd is |
1284 | called only when the end of file marker has not |
1285 | been read yet. Upon leaving submit_cmd,the variable |
1286 | sub_index points to the beginning of the next command |
1287 | to translate and execute. The buffer subdma is used |
1288 | to hold the UN-translated submit file contents. |
1289 | The buffer subcom holds a translated command. |
1290 | Comments are echoed to the screen by the procedure |
1291 | "comments". Parameters are substituted in comments |
1292 | as well as command lines. |
1293 | |
1294 \*--------------------------------------------------------------*/
1295
1296 REG BYTE *com_index;
1297 {
1298 REG UWORD i,cur_user;
1299
1300 for(i = 0;i <= CMD_LEN;i++)
1301 subcom[i] = NULL;
1302 cur_user = bdos(GET_USER_NO,(long)255);
1303 bdos(GET_USER_NO,(long)sub_user);
1304 bdos(SET_DMA_ADDR,subdma);
1305 if(first_sub || chain_sub)
1306 {
1307 for(i = 0;i < CMD_LEN;i++)
1308 subdma[i] = NULL;
1309 sub_read();
1310 sub_index = 0;
1311 }
1312 if(!(end_of_file))
1313 translate(com_index);
1314 for(i = 0;i < CMD_LEN;i++)
1315 subcom[i] = toupper(subcom[i]);
1316 bdos(SET_DMA_ADDR,dma);
1317 bdos(GET_USER_NO,(long)cur_user);
1318 }
1319
1File: CCP.C Page 30
1320 /************************/
1321 VOID execute_cmd(cmd) /* branch to */
1322 /* appropriate routine */
1323 /************************/
1324
1325 REG BYTE *cmd;
1326 {
1327 REG UWORD i,flag;
1328
1329 switch( decode(cmd) )
1330 {
1331 case DIRCMD: dir_cmd(0);
1332 break;
1333 case DIRSCMD: dir_cmd(1);
1334 break;
1335 case TYPECMD: type_cmd();
1336 break;
1337 case RENCMD: ren_cmd();
1338 break;
1339 case ERACMD: era_cmd();
1340 break;
1341 case UCMD: if(!(user_cmd()))
1342 bdos(PRINT_STRING,msg12);
1343 break;
1344 case CH_DISK: bdos(SELECT_DISK,(long)(parm[0][0]-'A'));
1345 break;
1346 case SUBCMD: flag = SUB_FILE;
1347 if(parm[1][0] == NULL)
1348 {
1349 bdos(PRINT_STRING,msg2);
1350 get_cmd(subdma,(long)(CMD_LEN-1));
1351 i = 0;
1352 while(subdma[i] != ' ' &&
1353 subdma[i] &&
1354 i < ARG_LEN-1 )
1355 parm[1][i] = subdma[i++];
1356 parm[1][i] = NULL;
1357 if(i != 0) subprompt = TRUE;
1358 else break;
1359 }
1360 else
1361 subprompt = FALSE;
1362 goto gosub;
1363 case FILE: flag = SEARCH;
1364 gosub: if(cmd_file(flag))
1365 break;
1366 if(flag == SUB_FILE)
1367 break;
1368 default : echo_cmd(parm,BAD);
1369 }
1370 }
1371
1File: CCP.C Page 31
1372
1373
1374
1375
1376 main()
1377 { /*---------------------*/
1378 REG BYTE *com_index; /* cmd execution ptr */
1379 /*---------------------*/
1380 dirflag = TRUE; /* init fcb fill flag */
1381 bdos(SET_DMA_ADDR,dma); /* set system dma addr */
1382 /*---------------------*/
1383 if(load_try)
1384 {
1385 bdos(SELECT_DISK,(long)cur_disk);
1386 bdos(GET_USER_NO,(long)user);
1387 load_try = FALSE;
1388 }
1389 /*---------------------*/
1390 if(morecmds) /* if a warmboot */
1391 { /* occured & there were*/
1392 /* more cmds to do */
1393 if(submit) /*---------------------*/
1394 {
1395 com_index = subcom;
1396 submit_cmd(save_sub);
1397 while(!*com_index)
1398 {
1399 if(end_of_file)
1400 {
1401 com_index = user_ptr;
1402 submit = FALSE;
1403 break;
1404 }
1405 else submit_cmd(save_sub);
1406 }
1407 }
1408 else
1409 com_index = user_ptr;
1410 morecmds = FALSE;
1411 if(*com_index)
1412 echo_cmd(com_index,GOOD);
1413 }
1414 else
1415 { /*----------------------*/
1416 prompt(); /* prompt for command */
1417 com_index = usercmd; /* set execution pointer*/
1418 if(autost && autorom) /* check for COLDBOOT cm*/
1419 { /* */
1420 echo_cmd(usercmd,GOOD); /* echo the command */
1421 autorom = FALSE; /* turn off .bss flag */
1422 } /* */
1423 else /* otherwise....... */
1424 get_cmd(usercmd,(long)(CMD_LEN));/*read a cmd */
1425 } /************************/
1426
1427 /*--------------------------------------------------------------*\
1428 | |
1429 | MAIN CCP PARSE LOOP |
1430 | =================== |
1File: CCP.C Page 32
1431 | |
1432 \*--------------------------------------------------------------*/
1433
1434
1435 while(*com_index)
1436 { /*--------------------*/
1437 glb_index = com_index; /* save for use in */
1438 /* check_cmd call */
1439 get_parms(com_index); /* parse command line */
1440 if(parm[0][0] && parm[0][0] != ';')/*-----------*/
1441 execute_cmd(parm); /* execute command */
1442 /*--------------------*/
1443 if(!(submit))
1444 com_index = scan_cmd(com_index);/* inc pointer */
1445 else
1446 {
1447 com_index = subcom;
1448 if(first_sub || chain_sub)
1449 {
1450 if(subprompt)
1451 copy_cmd(subdma);
1452 else
1453 copy_cmd(glb_index);
1454 if(first_sub)
1455 user_ptr = scan_cmd(glb_index);
1456 submit_cmd(save_sub);
1457 first_sub = chain_sub = FALSE;
1458 }
1459 else
1460 *com_index = NULL;
1461 while(*com_index == NULL)
1462 {
1463 if(end_of_file)
1464 {
1465 com_index = user_ptr;
1466 submit = FALSE;
1467 break;
1468 }
1469 else
1470 submit_cmd(save_sub);
1471 }
1472 }
1473 if(*com_index)
1474 echo_cmd(com_index,GOOD);
1475 }
1476 }