OSDN Git Service

* ps.cc (prog_name): New global variable.
[pf3gnuchains/pf3gnuchains4x.git] / utils / amd-udi / mondfe / monitor.c
1 static char _[] = "@(#)monitor.c        5.28 93/11/02 11:46:54, Srini, AMD.";
2 /******************************************************************************
3  * Copyright 1991 Advanced Micro Devices, Inc.
4  *
5  * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
6  * specifically  grants the user the right to modify, use and distribute this
7  * software provided this notice is not removed or altered.  All other rights
8  * are reserved by AMD.
9  *
10  * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
11  * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
12  * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
13  * USE OF THIS SOFTWARE.
14  *
15  * So that all may benefit from your experience, please report  any  problems
16  * or  suggestions about this software to the 29K Technical Support Center at
17  * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
18  * 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
19  *
20  * Advanced Micro Devices, Inc.
21  * 29K Support Products
22  * Mail Stop 573
23  * 5900 E. Ben White Blvd.
24  * Austin, TX 78741
25  * 800-292-9263
26  *****************************************************************************
27  *      Engineer: Srini Subramanian.
28  *****************************************************************************
29  * This module implements the monitor command interpreter.
30  *****************************************************************************
31  */
32
33 #include  <stdio.h>
34 #include  <string.h>
35 #include  <ctype.h>
36 #include  <signal.h>
37 #ifdef  MSDOS
38 #include  <stdlib.h>
39 #include  <conio.h>
40 #include  <io.h>
41 #else
42 #include  <fcntl.h>
43 #include  <termio.h>
44 /* #include   <sys/ioctl.h> */
45 #endif
46 #include  "monitor.h"
47 #include  "main.h"
48 #include  "memspcs.h"
49 #include  "error.h"
50 #include  "miniint.h"
51
52 /* Function declarations */
53 extern  void    Mini_Ctrl_C_Handler PARAMS((int));
54 extern  void    Mini_loop PARAMS((void));
55 extern  INT32   Mini_go_forever PARAMS((void));
56 extern  void    Mini_poll_kbd PARAMS((char  *cmd_buffer, int size, int mode));
57 extern  int     Mini_cmdfile_input PARAMS((char  *cmd_buffer, int size));
58 extern  int     tokenize_cmd PARAMS((char *, char **));
59 extern  void    lcase_tokens PARAMS((char **, int));
60 extern  int     get_word PARAMS((char *, INT32 *));
61 extern  void    PrintTrapMsg PARAMS((int trapnum));
62 extern  void    display_msg PARAMS((void));
63 extern  void    display_termuser PARAMS((void));
64 extern  void    display_term29k PARAMS((void));
65 extern  INT32   get_pc_addrs PARAMS((ADDR32 *pc1, ADDR32 *cps));
66 extern  INT32   get_pc1_inst PARAMS((ADDR32 cps, ADDR32 pc1, BYTE *inst));
67 extern  void    dasm_instr PARAMS((ADDR32, struct instr_t *));
68 extern  void    convert32 PARAMS((BYTE *));
69 extern  INT32   Mini_send_init_info PARAMS((INIT_INFO *init));
70
71 static  int     FindCmdIndx PARAMS((char *string));
72
73 /* Globals */
74 GLOBAL  struct bkpt_t   *bkpt_table;
75
76 GLOBAL  char            cmd_buffer[BUFFER_SIZE];
77 GLOBAL  char            tip_cmd_buffer[256];
78 GLOBAL  int             GoCmdFlag=0;
79
80 #define TOGGLE_CHAR     (io_config.io_toggle_char)
81
82 /* Following three vars to be used in stdin/stdout/stderr funcs */
83 #define IO_BUFSIZE      1024
84 static  char            io_buffer[IO_BUFSIZE]; 
85 static  INT32           io_bufsize;
86 static  INT32           io_count_done;
87
88 static  INT32           ProcessorState;
89 static  int             GrossState;
90 static  INT32           exit_loop;
91 static  int             CtrlCHit=0;
92 static  int             BlockMode;
93 /* These modes are defined in montip, udi2mtip.c file */
94 #define TIP_COOKED      0x0
95 #define TIP_RAW         0x1
96 #define TIP_CBREAK      0x2
97 #define TIP_ECHO        0x4
98 #define TIP_ASYNC       0x8
99 #define TIP_NBLOCK      0x10
100 static  INT32           TipStdinMode = TIP_COOKED;      /* initial */
101 #ifndef MSDOS
102 struct termio OldTermbuf, NewTermbuf;   /* STDIN, Channel0 */
103 #endif /* MSDOS */
104
105 /* Monitor command table */
106 struct  MonitorCommands_t {
107   char          *CmdString; /* Maximum length */
108   INT32         (*CmdFn) PARAMS((char **, int));
109 };
110
111 static  struct MonitorCommands_t MonitorCommands[] = {
112 "a", asm_cmd,
113 "attach", set_sessionid_cmd,
114 "b", bkpt_cmd,
115 "bc", bkpt_cmd,
116 "b050", bkpt_cmd,
117 "b050v", bkpt_cmd,
118 "b050p", bkpt_cmd,
119 "c", config_cmd,
120 "caps", capab_cmd,
121 "cp", create_proc_cmd,
122 "con", connect_cmd,
123 "ch0", channel0_cmd,
124 "d", dump_cmd,
125 "ex", exit_conn_cmd,
126 "dw", dump_cmd,
127 "dh", dump_cmd,
128 "db", dump_cmd,
129 "df", dump_cmd,
130 "dd", dump_cmd,
131 "dp", destroy_proc_cmd,
132 "disc", disconnect_cmd,
133 "detach", disconnect_cmd,
134 "esc", escape_cmd,
135 "eon", echomode_on,
136 "eoff", echomode_off,
137 "f", fill_cmd,
138 "fw", fill_cmd,
139 "fh", fill_cmd,
140 "fb", fill_cmd,
141 "ff", fill_cmd,
142 "fd", fill_cmd,
143 "fs", fill_cmd,
144 "g", go_cmd,
145 "h", help_cmd,
146 "ix", ix_cmd,
147 "il", il_cmd,
148 "init", init_proc_cmd,
149 "k", kill_cmd,
150 "l", dasm_cmd,
151 "logon", logon_cmd,
152 "logoff", logoff_cmd,
153 "m", move_cmd,
154 "pid", set_pid_cmd,
155 "q", quit_cmd,
156 "qoff", quietmode_off,
157 "qon", quietmode_on,
158 "r", reset_cmd,
159 "s", set_cmd,
160 "sw", set_cmd,
161 "sh", set_cmd,
162 "sb", set_cmd,
163 "sf", set_cmd,
164 "sd", set_cmd,
165 "sid", set_sessionid_cmd,
166 "t", trace_cmd,
167 "target", connect_cmd,
168 "tip", tip_cmd,
169 "ver", version_cmd,
170 "xp", xp_cmd,
171 "xc", xc_cmd,
172 "y", yank_cmd,
173 "zc", cmdfile_cmd,
174 "ze", echofile_cmd,
175 "zl", set_logfile,
176 "?", help_cmd,
177 "|", dummy_cmd,
178 "", dummy_cmd,
179 NULL
180 };
181
182 /* Trap Messages */
183 static char     *TrapMsg[] = {
184 "Illegal Opcode",
185 "Unaligned Access",
186 "Out of Range",
187 "Coprocessor Not Present",
188 "Coprocessor Exception",
189 "Protection Violation",
190 "Instruction Access Exception",
191 "Data Access Exception",
192 "User-Mode Instruction TLB Miss",
193 "User-Mode Data TLB Miss",
194 "Supervisor-Mode Instruction TLB Miss",
195 "Supervisor-Mode Data TLB Miss",
196 "Instruction TLB Protection Violation",
197 "Data TLB Protection Violation",
198 "Timer",
199 "Trace",
200 "INTR0",
201 "INTR1",
202 "INTR2",
203 "INTR3",
204 "TRAP0",
205 "TRAP1",
206 "Floating-Point Exception"
207 };
208
209 void
210 Mini_monitor()
211 {
212
213   /* Initialize breakpoint table */
214
215   bkpt_table = NULL;
216   GrossState = NOTEXECUTING;
217
218    /*
219     * Start with the user being the terminal controller.
220     */
221     io_config.io_control = TERM_USER;
222     io_config.target_running = FALSE;
223
224 #ifndef MSDOS
225    ioctl (fileno(stdin), TCGETA, &OldTermbuf);  /* Initial settings */
226 #endif
227
228    /*
229     * Define Ctrl-U as the io_toggle_char as default.
230     */
231     io_config.io_toggle_char = (BYTE) 21;
232
233    /*
234    ** Open cmd file (if necessary)
235    */
236
237    if (io_config.cmd_file_io == TRUE) {  /* TRUE if -c option given */
238       io_config.cmd_file = fopen(io_config.cmd_filename, "r");
239         if (io_config.cmd_file == NULL) {
240             warning (EMCMDOPEN);
241             io_config.cmd_file_io = FALSE;
242         } else {
243           /* MON_STDIN is command file */
244           MON_STDIN = fileno(io_config.cmd_file); /* set MON_STDIN */
245         };
246    }
247
248    /*
249    ** Open log file, if no command file given.
250    */
251
252    if (io_config.log_mode == (INT32) TRUE) { /* -log option given */
253      if (io_config.log_filename) {
254        io_config.log_file = fopen(io_config.log_filename, "w");
255        if (io_config.log_file == NULL) {
256           io_config.log_mode = (INT32) FALSE;
257           warning(EMLOGOPEN);
258        }
259      } else {
260        io_config.log_mode = (INT32) FALSE;
261        warning(EMLOGOPEN);
262      }
263    }
264
265    /* Install ctrl-C handler */
266
267    if (signal (SIGINT, Mini_Ctrl_C_Handler) == SIG_ERR) {
268      fprintf(stderr, "Ctrl-C handler not installed.\n"); /* warning */
269      if (io_config.echo_mode == (INT32) TRUE)
270         fprintf(io_config.echo_file, "Ctrl-C handler not installed.\n"); /* warning */
271    }
272   /* Get into monitor loop */
273
274   Mini_loop();
275
276 }
277
278 void
279 Mini_loop()
280 {
281    INT32        retval;
282    int          token_count;
283    char         *token[MAX_TOKENS];
284    int          Indx;
285  
286    exit_loop = FALSE;
287    CtrlCHit = 0;
288    /*
289    ** Enter command interpreter loop
290    */
291
292    fprintf(stderr, "%s>", ProgramName);
293    if (io_config.echo_mode == (INT32) TRUE)
294       fprintf(io_config.echo_file, "%s>", ProgramName);
295
296    BlockMode = BLOCK;   /* wait for a user command */
297    do {
298
299       if (CtrlCHit) {
300         CtrlCHit = 0;
301         /* Print a prompt */
302         fprintf(stderr, "\n%s>", ProgramName);
303         if (io_config.echo_mode == (INT32) TRUE)
304           fprintf(io_config.echo_file, "\n%s>", ProgramName);
305       }
306       /*
307       ** If the target was set to run, get its current status.
308       */
309       if (Mini_get_target_stats((INT32) udi_waittime, &ProcessorState) != SUCCESS) {
310          Mini_TIP_DestroyProc();
311          Mini_TIP_exit();
312          fatal_error(EMFATAL);
313       };
314       GrossState = (int) (ProcessorState & 0xFF);
315       switch (GrossState) {
316         case    NOTEXECUTING:  /* do nothing */
317                 io_config.io_control=TERM_USER;
318                 io_config.target_running = FALSE;
319                 BlockMode = BLOCK;      /* wait for a user command */
320                 break;
321         case    EXITED:  /* do nothing */
322                 if (GoCmdFlag) {
323                  GoCmdFlag = 0;
324 #ifndef MSDOS
325                  ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
326 #endif
327                  if (!QuietMode) {
328                     fprintf (stderr, "Process exited with 0x%lx\n", 
329                                         (ProcessorState >> 8));
330                     if (io_config.echo_mode == (INT32) TRUE)
331                        fprintf (io_config.echo_file, "Process exited with 0x%lx\n", 
332                                         (ProcessorState >> 8));
333                  }
334                  fprintf (stderr, "%s>", ProgramName);
335                  if (io_config.echo_mode == (INT32) TRUE)
336                     fprintf (io_config.echo_file, "%s> ", ProgramName);
337                 }
338                 io_config.io_control=TERM_USER;
339                 io_config.target_running = FALSE;
340                 BlockMode = BLOCK; /* wait for a user command */
341                 break;
342         case    RUNNING:        /* any request from target? */
343                 io_config.target_running = TRUE;
344                 BlockMode = NONBLOCK; /* return immediately */
345                 break;
346         case    STOPPED:
347                 io_config.io_control=TERM_USER;
348                 io_config.target_running = TRUE;
349                 if (GoCmdFlag) {
350                    GoCmdFlag = 0;
351 #ifndef MSDOS
352                    ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
353 #endif
354                    fprintf(stderr, "Execution stopped at ");
355                    if (io_config.echo_mode == (INT32) TRUE)
356                       fprintf(io_config.echo_file, "Execution stopped at ");
357                    display_msg();
358                 }
359                 BlockMode = BLOCK; /* wait for next user command */
360                 break;
361         case    BREAK:
362                 io_config.io_control=TERM_USER;
363                 io_config.target_running = FALSE;
364                 if (GoCmdFlag) {
365                    GoCmdFlag = 0;
366 #ifndef MSDOS
367                    ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
368 #endif
369                    fprintf(stderr, "Breakpoint hit at ");
370                    if (io_config.echo_mode == (INT32) TRUE)
371                       fprintf(io_config.echo_file, "Breakpoint hit at ");
372                    display_msg();
373                 }
374                 BlockMode = BLOCK; /* wait for next user command */
375                 break;
376         case    STEPPED:
377                 io_config.io_control=TERM_USER;
378                 io_config.target_running = FALSE;
379                 if (GoCmdFlag) {
380                    GoCmdFlag = 0;
381 #ifndef MSDOS
382                    ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
383 #endif
384                    fprintf(stderr, "Stepping... Execution stopped at ");
385                    if (io_config.echo_mode == (INT32) TRUE)
386                       fprintf(io_config.echo_file, "Stepping...Execution stopped at ");
387                    display_msg();
388                 }
389                 BlockMode = BLOCK; /* wait for next user command */
390                 break;
391         case    WAITING:
392                 io_config.io_control=TERM_USER;
393                 io_config.target_running = FALSE;
394                 break;
395         case    HALTED:
396                 io_config.io_control=TERM_USER;
397                 io_config.target_running = FALSE;
398                 if (GoCmdFlag) {
399                    GoCmdFlag = 0;
400 #ifndef MSDOS
401                    ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
402 #endif
403                    fprintf(stderr, "Execution halted at ");
404                    if (io_config.echo_mode == (INT32) TRUE)
405                       fprintf(io_config.echo_file, "Execution halted at ");
406                    display_msg();
407                 }
408                 BlockMode = BLOCK; /* wait for next user command */
409                 break;
410         case    WARNED:
411                 io_config.io_control=TERM_USER;
412                 io_config.target_running = FALSE;
413                 break;
414         case    TRAPPED:
415                 io_config.io_control=TERM_USER;
416                 io_config.target_running = FALSE;
417                 if (GoCmdFlag) {
418                    GoCmdFlag = 0;
419 #ifndef MSDOS
420                    ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
421 #endif
422                    PrintTrapMsg((int) (ProcessorState >> 8));
423                    display_msg();
424                 }
425                 BlockMode = BLOCK; /* wait for next user command */
426                 break;
427         case    STDOUT_READY:
428                 io_bufsize = 0;
429                 io_count_done = (INT32) 0;
430                 do {
431                   Mini_get_stdout(io_buffer, IO_BUFSIZE, &io_count_done);
432                   write(MON_STDOUT, &io_buffer[0], (int) io_count_done);
433                   if (io_config.echo_mode == (INT32) TRUE) {
434                    fflush (io_config.echo_file);
435                    write (fileno(io_config.echo_file), &io_buffer[0], (int) io_count_done);
436                   }
437                 } while (io_count_done == (INT32) IO_BUFSIZE);
438                 break;
439         case    STDERR_READY:
440                 io_bufsize = 0;
441                 io_count_done = (INT32) 0;
442                 do {
443                   Mini_get_stderr(io_buffer, IO_BUFSIZE, &io_count_done);
444                   write(MON_STDERR, &io_buffer[0], (int) io_count_done);
445                   if (io_config.echo_mode == (INT32) TRUE) {
446                      fflush (io_config.echo_file);
447                      write (fileno(io_config.echo_file), &io_buffer[0], (int) io_count_done);
448                   }
449                 } while (io_count_done == (INT32) IO_BUFSIZE);
450                 break;
451         case    STDIN_NEEDED:
452                 /* Line buffered reads only */
453                 if (io_config.cmd_file_io == TRUE) { /* read from command file */
454                    if (Mini_cmdfile_input(io_buffer, IO_BUFSIZE) == SUCCESS) {
455                       io_bufsize = strlen(io_buffer);
456                       fprintf(stderr, "%s", io_buffer); /* echo */
457                       if (io_config.echo_mode == (INT32) TRUE)
458                           fprintf(io_config.echo_file, "%s", io_buffer); /* echo */
459                    } else { /* read from terminal */
460                      io_bufsize = read( fileno(stdin), io_buffer, IO_BUFSIZE );
461                    }
462                 } else {
463                    io_bufsize = read( fileno(stdin), io_buffer, IO_BUFSIZE );
464                 };
465                 if (io_bufsize < 0)
466                 {
467                    fprintf(stderr, "fatal error reading from stdin\n");
468                    if (io_config.echo_mode == (INT32) TRUE)
469                       fprintf(io_config.echo_file, "fatal error reading from stdin\n");
470                 }
471                 if (io_config.echo_mode == (INT32) TRUE) {
472                   write (fileno(io_config.echo_file), &io_buffer[0], (int) io_bufsize);
473                   fflush (io_config.echo_file);
474                 }
475                 Mini_put_stdin(io_buffer, io_bufsize, &io_count_done);
476                 break;
477         case    STDINMODEX:
478                 /* call TIP to get StdinMode */
479                 Mini_stdin_mode_x((INT32 *)&TipStdinMode);
480                 if (TipStdinMode & TIP_NBLOCK) 
481                   io_config.io_control = TERM_29K;
482                 else if (TipStdinMode & TIP_ASYNC)
483                   io_config.io_control = TERM_29K;
484                 else if (TipStdinMode == TIP_COOKED)
485                   io_config.io_control = TERM_USER;
486                 else {
487                   fprintf(stderr, "DFEWARNING: TIP Requested Stdin Mode Not Supported.\n");
488                   fprintf(stderr, "DFEWARNING: Using default mode.\n");
489                   TipStdinMode = TIP_COOKED;
490                   io_config.io_control = TERM_USER;
491                 }
492
493                 if (io_config.io_control == TERM_29K)
494                   display_term29k();
495                 break;
496
497         default:
498                 break;
499       }; /* end switch */
500
501
502       /*
503       ** Check for keyboard input from command file first, then keyboard.
504       */
505       if (io_config.io_control == TERM_USER)  {
506         if (io_config.target_running == FALSE) {
507           if (io_config.cmd_ready == FALSE) { /* Get a new user command */
508              if (io_config.cmd_file_io == TRUE) { /* try command file first*/
509                 if (Mini_cmdfile_input(cmd_buffer, BUFFER_SIZE) == SUCCESS) {
510                    fprintf(stderr, "%s", cmd_buffer); 
511                    io_config.cmd_ready = TRUE;
512                 } else {
513                    Mini_poll_kbd(cmd_buffer, BUFFER_SIZE, BlockMode);
514                 }
515              } else { /* keyboard */
516                 /* Mini_poll_kbd function sets io_config.cmd_ready */
517                 Mini_poll_kbd(cmd_buffer, BUFFER_SIZE, BlockMode);
518              }
519           }
520         } else {
521                 Mini_poll_kbd(cmd_buffer, BUFFER_SIZE, BlockMode);
522         }
523       } else if (io_config.io_control == TERM_29K) {
524         if ((GrossState == RUNNING) || GoCmdFlag)
525            Mini_poll_channel0();        /* non-blocking */
526       } else {
527         fprintf(stderr, "fatal error: Don't know who is controlling the terminal!\n");
528         return;
529       }
530
531
532       if (io_config.cmd_ready == TRUE) { /* if there is a command in buffer */
533 #ifdef  MSDOS
534              if (io_config.log_mode == (INT32) TRUE)  /* make a log file */
535                 fprintf(io_config.log_file, "%s\n", cmd_buffer);
536              if (io_config.echo_mode == (INT32) TRUE)
537                 fprintf(io_config.echo_file, "%s\n", cmd_buffer);
538 #else
539              if (io_config.log_mode == (INT32) TRUE)  /* make a log file */
540                 fprintf(io_config.log_file, "%s", cmd_buffer);
541              if (io_config.echo_mode == (INT32) TRUE)
542                 fprintf(io_config.echo_file, "%s", cmd_buffer);
543 #endif
544              /*
545              ** Parse command
546              */
547
548              token_count = tokenize_cmd(cmd_buffer, token);
549              /* Convert first character (command) to lcase */
550              if (isupper(*token[0]))
551                 (*token[0]) = (char) tolower(*token[0]);
552
553              /* If anything but a y or z command, convert to lower case */
554              if ( ((*token[0]) != 'y') &&
555                   ((*token[0]) != 'z') )
556                 lcase_tokens(token, token_count);
557
558              if ((Indx = FindCmdIndx(token[0])) != (int) FAILURE)
559                io_config.cmd_ready = TRUE;
560              else {
561                warning(EMNOSUCHCMD);
562                /* Print a prompt */
563                fprintf(stderr, "\n%s>", ProgramName);
564                if (io_config.echo_mode == (INT32) TRUE)
565                   fprintf(io_config.echo_file, "\n%s>", ProgramName);
566                io_config.cmd_ready = FALSE; /* nothing to execute */
567              }
568       }
569
570       /*
571       ** Execute command
572       */
573
574       if (io_config.cmd_ready == TRUE) {
575          retval = MonitorCommands[Indx].CmdFn(token, token_count);
576          io_config.cmd_ready = FALSE;
577          if (retval == FAILURE) {
578             fprintf(stderr, "Command failed\n");
579             if (io_config.echo_mode == (INT32) TRUE)
580                fprintf(io_config.echo_file, "Command failed\n");
581          } else if (retval != SUCCESS) {
582             warning(retval);
583          };
584          /* Print a prompt */
585          if (io_config.io_control == TERM_USER) {
586            fprintf(stderr, "%s>", ProgramName);
587            if (io_config.echo_mode == (INT32) TRUE)
588               fprintf(io_config.echo_file, "%s>", ProgramName);
589          } else {
590                   display_term29k();
591          }
592       }  /* if cmd ready */
593
594    } while (exit_loop != TRUE);  /* end of do-while */
595
596    /* Close log file */
597    if (io_config.log_mode == (INT32) TRUE)
598       (void) fclose(io_config.log_file);
599
600    if (bkpt_table != NULL)
601        (void) free((char *) bkpt_table);
602 }
603
604 /*
605 ** This function takes in a string and produces a lower case,
606 ** " argv - argc" style array.  Then number of elements in the
607 ** array is returned.
608 */
609
610 int
611 tokenize_cmd(cmd, token)
612    char  *cmd;
613    char  *token[];
614    {
615    int  token_count;
616
617    /* Break input into tokens */
618    token_count = 0;
619    token[0] = cmd;
620
621    if (cmd[0] != '\0') {
622       token[token_count] = strtok(cmd, " \t,;\n\r");
623
624       if (token[token_count] != NULL) {
625          do {
626             token_count = token_count + 1;
627             token[token_count] = strtok((char *) NULL, " \t,;\n\r");
628             } while ((token[token_count] != NULL) &&
629                      (token_count < MAX_TOKENS));
630          }
631       else {
632          token[0] = cmd;
633          *token[0] = '\0';
634          }
635       }
636
637    return (token_count);
638
639    }  /* end tokenize_cmd() */
640
641
642
643 /*
644 ** This function is used to convert a list of tokens
645 ** to all lower case letters.
646 */
647
648 void
649 lcase_tokens(token, token_count)
650    char *token[MAX_TOKENS];
651    int   token_count;
652    {
653    int   i;
654    char *temp_str;
655
656    for (i=0; i<token_count; i=i+1) {
657       temp_str = token[i];
658       while (*temp_str != '\0') {
659          if (isupper(*temp_str))
660             *temp_str = (char) tolower(*temp_str);
661          temp_str++;
662          }
663       }  /* end for() */
664    }  /* end lcase_string() */
665
666
667 INT32
668 Mini_go_forever()
669 {
670   static  int   complete=0;
671
672    /* Terminal control initialization. */
673    io_config.io_control = TERM_USER;    /* 3.1-7 */
674    io_config.target_running = TRUE;
675
676 #ifndef MSDOS
677    ioctl (fileno(stdin), TCGETA, &OldTermbuf);  /* Initial settings */
678 #endif
679
680    /* Install ctrl-C handler */
681
682    if (signal (SIGINT, Mini_Ctrl_C_Handler) == SIG_ERR) {
683      fprintf(stderr, "Ctrl-C handler not installed.\n"); /* warning */
684      if (io_config.echo_mode == (INT32) TRUE)
685         fprintf(io_config.echo_file, "Ctrl-C handler not installed.\n"); /* warning */
686    }
687    /*
688    ** Open cmd file (if necessary)
689    */
690
691    if (io_config.cmd_file_io == TRUE) {  /* TRUE if -c option given */
692       io_config.cmd_file = fopen(io_config.cmd_filename, "r");
693         if (io_config.cmd_file == NULL) {
694             warning (EMCMDOPEN);
695             io_config.cmd_file_io = FALSE;
696         } else {
697           /* MON_STDIN is command file */
698           MON_STDIN = fileno(io_config.cmd_file); /* set MON_STDIN */
699         };
700    }
701
702    Mini_go();  /* set target running */
703
704    do {
705
706       /*
707       ** If the target was set to run, get its current status.
708       */
709       if (Mini_get_target_stats((INT32) udi_waittime, &ProcessorState) != SUCCESS) {
710          Mini_TIP_DestroyProc();
711          Mini_TIP_exit();
712          fatal_error(EMFATAL);
713       }
714       GrossState = (int) (ProcessorState & 0xFF);
715       switch (GrossState) {
716         case    NOTEXECUTING:  /* do nothing */
717                 io_config.io_control = TERM_USER;
718                 io_config.target_running = FALSE;
719                 break;
720         case    EXITED:  /* do nothing */
721                  if (!QuietMode) {
722                  fprintf (stderr, "Process exited with 0x%lx\n",
723                                                    (ProcessorState >> 8));
724                  if (io_config.echo_mode == (INT32) TRUE)
725                     fprintf (io_config.echo_file, "Process exited with 0x%lx\n",
726                                                    (ProcessorState >> 8));
727                  }
728                 io_config.io_control = TERM_USER;
729                 io_config.target_running = FALSE;
730                 complete=1;
731                 break;
732         case    RUNNING:        /* any request from target? */
733                 break;
734         case    STOPPED:
735                 complete=1;
736                 io_config.io_control = TERM_USER;
737                 io_config.target_running = FALSE;
738                 fprintf(stderr, "Execution stopped at ");
739                 if (io_config.echo_mode == (INT32) TRUE)
740                    fprintf(io_config.echo_file, "Execution stopped at ");
741                 display_msg();
742                 break;
743         case    BREAK:
744                 complete=1;
745                 io_config.io_control = TERM_USER;
746                 io_config.target_running = FALSE;
747                 fprintf(stderr, "Breakpoint hit at ");
748                 if (io_config.echo_mode == (INT32) TRUE)
749                    fprintf(io_config.echo_file, "Breakpoint hit at ");
750                 display_msg();
751                 break;
752         case    STEPPED:
753                 complete=1;
754                 io_config.io_control = TERM_USER;
755                 io_config.target_running = FALSE;
756                 fprintf(stderr, "Stepping...Execution stopped at ");
757                 if (io_config.echo_mode == (INT32) TRUE)
758                    fprintf(io_config.echo_file, "Stepping...Execution stopped at ");
759                 display_msg();
760                 break;
761         case    WAITING:
762                 complete=1;
763                 io_config.io_control = TERM_USER;
764                 io_config.target_running = FALSE;
765                 break;
766         case    HALTED:
767                 complete=1;
768                 io_config.io_control = TERM_USER;
769                 io_config.target_running = FALSE;
770                 fprintf(stderr, "Execution halted at ");
771                 if (io_config.echo_mode == (INT32) TRUE)
772                    fprintf(io_config.echo_file, "Execution halted at ");
773                 display_msg();
774                 break;
775         case    WARNED:
776                 complete=1;
777                 io_config.io_control = TERM_USER;
778                 io_config.target_running = FALSE;
779                 break;
780         case    TRAPPED:
781                 complete=1;
782                 io_config.io_control = TERM_USER;
783                 io_config.target_running = FALSE;
784                 PrintTrapMsg((int) (ProcessorState >> 8));
785                 display_msg();
786                 break;
787         case    STDOUT_READY:
788                 io_bufsize = 0;
789                 io_count_done = (INT32) 0;
790                 do {
791                   Mini_get_stdout(io_buffer, IO_BUFSIZE, &io_count_done);
792                   write(MON_STDOUT, &io_buffer[0], (int) io_count_done);
793                   if (io_config.echo_mode == (INT32) TRUE) {
794                      fflush (io_config.echo_file);
795                      write (fileno(io_config.echo_file), &io_buffer[0], (int) io_count_done);
796                   }
797                 } while (io_count_done == (INT32) IO_BUFSIZE);
798                 break;
799         case    STDERR_READY:
800                 io_bufsize = 0;
801                 io_count_done = (INT32) 0;
802                 do {
803                   Mini_get_stderr(io_buffer, IO_BUFSIZE, &io_count_done);
804                   write(MON_STDERR, &io_buffer[0], (int) io_count_done);
805                   if (io_config.echo_mode == (INT32) TRUE) {
806                      fflush (io_config.echo_file);
807                      write (fileno(io_config.echo_file), &io_buffer[0], (int) io_count_done);
808                   }
809                 } while (io_count_done == (INT32) IO_BUFSIZE);
810                 break;
811         case    STDIN_NEEDED:
812                 /* Line buffered reads only */
813                 if (io_config.cmd_file_io == TRUE) { /* read from command file */
814                    if (Mini_cmdfile_input(io_buffer, IO_BUFSIZE) == SUCCESS) {
815                       io_bufsize = strlen(io_buffer);
816                       fprintf(stderr, "%s", io_buffer); /* echo */
817                       if (io_config.echo_mode == (INT32) TRUE)
818                           fprintf(io_config.echo_file, "%s", io_buffer); /* echo */
819                    } else { /* read from terminal */
820                      io_bufsize = read( fileno(stdin), io_buffer, IO_BUFSIZE );
821                    }
822                 } else {
823                    io_bufsize = read( fileno(stdin), io_buffer, IO_BUFSIZE );
824                 };
825                 if (io_bufsize < 0)
826                 {
827                    fprintf(stderr, "fatal error reading from stdin\n");
828                    if (io_config.echo_mode == (INT32) TRUE)
829                        fprintf(io_config.echo_file, "fatal error reading from stdin\n");
830                 }
831                 if (io_config.echo_mode == (INT32) TRUE) {
832                   fflush (io_config.echo_file);
833                   write (fileno(io_config.echo_file), &io_buffer[0], (int) io_bufsize);
834                 }
835                 Mini_put_stdin(io_buffer, io_bufsize, &io_count_done);
836                 break;
837         case    STDINMODEX:
838                 /* call TIP to get StdinMode */
839                 Mini_stdin_mode_x((INT32 *)&TipStdinMode);
840                 if (TipStdinMode & TIP_NBLOCK)
841                   io_config.io_control = TERM_29K;
842                 else if (TipStdinMode & TIP_ASYNC)
843                   io_config.io_control = TERM_29K;
844                 else if (TipStdinMode == TIP_COOKED)
845                   io_config.io_control = TERM_USER;
846                 else {
847                   fprintf(stderr, "DFEWARNING: TIP Requested Stdin Mode Not Supported.\n");
848                   fprintf(stderr, "DFEWARNING: Using default mode.\n");
849                   TipStdinMode = TIP_COOKED;
850                   io_config.io_control = TERM_USER;
851                 }
852                 if (io_config.io_control == TERM_29K)
853                   display_term29k();
854                 break;
855
856         default:
857                 complete=1;
858                 io_config.io_control = TERM_USER;
859                 io_config.target_running = FALSE;
860                 break;
861       }; /* end switch */
862 #ifdef  MSDOS
863       if (!complete)
864         kbhit();        /* Poll for Ctrl-C */
865 #endif
866       if (CtrlCHit) {
867          CtrlCHit = 0;
868          complete = 1;
869       }
870
871       if (io_config.io_control == TERM_29K)
872         if (GrossState == RUNNING)
873           Mini_poll_channel0(); /* non-blocking */
874       else
875         TipStdinMode = TIP_COOKED;
876
877    } while (!complete);
878 #ifndef MSDOS
879    ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
880 #endif
881
882    fflush(stdout);
883    fflush(stderr);
884
885    Mini_TIP_DestroyProc();
886    Mini_TIP_exit();
887
888    NumberOfConnections=0;
889    return (SUCCESS);
890 }
891
892
893 INT32
894 get_pc_addrs(pc1, cps)
895 ADDR32  *pc1;
896 ADDR32  *cps;
897 {
898    ADDR32       pc_1;
899    ADDR32       cps_b;
900    INT32        hostendian;
901    INT32        bytes_ret;
902    INT32        retval;
903
904    hostendian = FALSE;
905    if ((retval = Mini_read_req (PC_SPACE,
906                                 (ADDR32) 0, /* doesn't matter */
907                                 (INT32) 1,
908                                 (INT16) 4, /* size */
909                                 &bytes_ret,
910                                 (BYTE *) &pc_1,
911                                 hostendian)) != SUCCESS) {
912         return(FAILURE);
913    };
914
915    *pc1 = (ADDR32) pc_1;
916    if (host_config.host_endian != host_config.target_endian)  {
917       convert32((BYTE *)pc1);
918    }
919
920    /* get cps */
921    hostendian = FALSE;
922    if ((retval = Mini_read_req (SPECIAL_REG,
923                                 (ADDR32) 2,
924                                 (INT32) 1,
925                                 (INT16) 4, /* size */
926                                 &bytes_ret,
927                                 (BYTE *) &cps_b,
928                                 hostendian)) != SUCCESS) {
929         return(FAILURE);
930    };
931    *cps = (ADDR32) cps_b;
932    if (host_config.host_endian != host_config.target_endian)  {
933       convert32((BYTE *)cps);
934    }
935
936    return (SUCCESS);
937 }
938
939 INT32
940 get_pc1_inst(cps, pc1, inst)
941 ADDR32  cps;
942 ADDR32  pc1;
943 BYTE    *inst;
944 {
945    INT32        bytes_ret;
946    INT32        hostendian;
947    INT32        retval;
948    INT32        memory_space;
949
950    hostendian = FALSE;
951
952    if (cps & 0x100L) /* RE bit */
953      memory_space = I_ROM;
954    else
955      memory_space = I_MEM;
956
957    if ((retval = Mini_read_req(memory_space,
958                                pc1,
959                                (INT32) 1,
960                                (INT16) sizeof(INST32),  /* size */
961                                &bytes_ret,
962                                (BYTE *) inst,
963                                hostendian)) != SUCCESS) {
964         return(FAILURE);
965    };
966    return (SUCCESS);
967 }
968
969 void
970 display_msg()
971 {
972                 ADDR32  c_pc1;
973                 ADDR32  c_cps;
974
975                 union instruction_t {
976                   BYTE  buf[sizeof(struct instr_t)];
977                   struct instr_t  instr;
978                 };
979                 union instruction_t instruction;
980                 struct  instr_t         temp;
981
982                 (void) get_pc_addrs(&c_pc1, &c_cps);
983                 (void) get_pc1_inst(c_cps, c_pc1, instruction.buf);
984                 fprintf(stderr, " %08lx\n", c_pc1);
985                 if (io_config.echo_mode == (INT32) TRUE)
986                     fprintf(io_config.echo_file, " %08lx\n", c_pc1);
987                 if (host_config.target_endian == LITTLE) {
988                   temp.op = instruction.instr.b;
989                   temp.c = instruction.instr.a;
990                   temp.a = instruction.instr.c;
991                   temp.b = instruction.instr.op;
992                 } else { /* default BIG endian */
993                   temp.op = instruction.instr.op;
994                   temp.c = instruction.instr.c;
995                   temp.a = instruction.instr.a;
996                   temp.b = instruction.instr.b;
997                 }
998                 fprintf(stderr, "%08lx\t %02x%02x%02x%02x\t", c_pc1,
999                                      temp.op,
1000                                      temp.c,
1001                                      temp.a,
1002                                      temp.b);
1003                 if (io_config.echo_mode == (INT32) TRUE)
1004                    fprintf(io_config.echo_file, "%08lx\t %02x%02x%02x%02x\t", c_pc1,
1005                                      temp.op,
1006                                      temp.c,
1007                                      temp.a,
1008                                      temp.b);
1009                 (void) dasm_instr(c_pc1, &(temp));
1010           if (io_config.io_control == TERM_USER) {
1011             fprintf(stderr, "\n%s>", ProgramName);
1012             fflush(stderr);
1013             if (io_config.echo_mode == (INT32) TRUE)
1014                    fprintf(io_config.echo_file, "\n%s>", ProgramName);
1015           }
1016 }
1017
1018 int
1019 Mini_cmdfile_input(cmd_buffer, size)
1020 char    *cmd_buffer;
1021 int     size;
1022 {
1023  if (fgets(cmd_buffer, size, io_config.cmd_file) == NULL) {
1024    io_config.cmd_file_io = FALSE;
1025    (void) fclose(io_config.cmd_file);
1026    MON_STDIN = fileno (stdin); /* reset to terminal after EOF */
1027    return (FAILURE);
1028  } else {
1029    return (SUCCESS);
1030  }
1031 }
1032
1033 void
1034 Mini_Ctrl_C_Handler(num)
1035 int     num;
1036 {
1037    CtrlCHit = 1;  /* used for run-only mode, no debugging */
1038    if (io_config.io_control == TERM_29K) {
1039 #ifndef MSDOS
1040      ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
1041 #endif
1042    }
1043    if (io_config.target_running == TRUE)
1044       Mini_break();
1045    io_config.cmd_ready == FALSE;
1046 #ifdef MSDOS
1047   if (signal (SIGINT, Mini_Ctrl_C_Handler) == SIG_ERR) {
1048      fprintf(stderr, "Ctrl-C handler not installed.\n"); /* warning */
1049      if (io_config.echo_mode == (INT32) TRUE)
1050         fprintf(io_config.echo_file, "Ctrl-C handler not installed.\n"); /* warning */
1051   }
1052 #endif
1053   return;
1054 }
1055
1056 static  int
1057 FindCmdIndx(CmdString)
1058 char    *CmdString;
1059 {
1060   int   i;
1061
1062   i = 0;
1063   while (MonitorCommands[i].CmdString) {
1064     if (strcmp(CmdString, MonitorCommands[i].CmdString))
1065       i++;
1066     else
1067       return (i);
1068   };
1069   return (-1);
1070 }
1071
1072 INT32
1073 escape_cmd(token, tokencnt)
1074 char    **token;
1075 int     tokencnt;
1076 {
1077   int   retval;
1078 #ifdef  MSDOS
1079   if ((retval = system ((char *) getenv("COMSPEC"))) != 0)
1080      return ((INT32) EMDOSERR);
1081   return ((INT32) SUCCESS);
1082 #else
1083   if ((retval = system ((char *) getenv("SHELL"))) != 0)
1084     return ((INT32) EMSYSERR);
1085   return ((INT32) SUCCESS);
1086 #endif
1087 }
1088
1089 INT32
1090 dummy_cmd(token, tokencnt)
1091 char    **token;
1092 int     tokencnt;
1093 {
1094   return ((INT32) 0);
1095 }
1096
1097 INT32
1098 quit_cmd(token, tokencnt)
1099 char    **token;
1100 int     tokencnt;
1101 {
1102    int  i;
1103
1104    for (i =0; i < NumberOfConnections; i++) {
1105       Mini_TIP_SetCurrSession(Session_ids[i]);
1106       Mini_TIP_DestroyProc();
1107       Mini_TIP_exit();
1108    };
1109    fflush(stdout);
1110    fflush(stderr);
1111    exit_loop = TRUE;
1112    NumberOfConnections=0;
1113    return ((INT32) 0);
1114 }
1115
1116 INT32
1117 connect_cmd(token, tokencnt)
1118 char    **token;
1119 int     tokencnt;
1120 {
1121   INT32         retval;
1122
1123   if (tokencnt < 2)
1124     return (EMSYNTAX);
1125
1126   if ((retval = Mini_TIP_init(token[1], &Session_ids[NumberOfConnections]))
1127                                        == SUCCESS) {
1128       NumberOfConnections=NumberOfConnections+1;
1129   };
1130
1131   return ((INT32) retval);
1132 }
1133
1134 INT32
1135 disconnect_cmd(token, tokencnt)
1136 char    **token;
1137 int     tokencnt;
1138 {
1139   INT32         retval;
1140   int           i;
1141
1142   if ((retval = Mini_TIP_disc()) != SUCCESS)
1143      return ((INT32) retval);
1144   else { /* find some other session */
1145      NumberOfConnections=NumberOfConnections - 1;
1146      for (i = 0; i < NumberOfConnections; i++) {
1147         if ((retval = Mini_TIP_SetCurrSession(Session_ids[i])) == SUCCESS) 
1148             return (retval);
1149      }
1150      if (i >= NumberOfConnections)  { /* exit DFE */
1151          exit_loop = TRUE;
1152      }
1153   }
1154
1155   return ((INT32) retval);
1156 }
1157
1158 INT32
1159 create_proc_cmd(token, tokencnt)
1160 char    **token;
1161 int     tokencnt;
1162 {
1163   INT32         retval;
1164
1165   retval = Mini_TIP_CreateProc();
1166
1167   return ((INT32) retval);
1168 }
1169
1170 INT32
1171 capab_cmd(token, tokencnt)
1172 char    **token;
1173 int     tokencnt;
1174 {
1175   INT32         retval;
1176
1177   retval = Mini_TIP_Capabilities();
1178
1179   return ((INT32) retval);
1180 }
1181
1182 INT32
1183 exit_conn_cmd(token, tokencnt)
1184 char    **token;
1185 int     tokencnt;
1186 {
1187   INT32         retval;
1188   int           i;
1189
1190   if ((retval = Mini_TIP_exit()) != SUCCESS) {;
1191      return (retval);
1192   } else { /* find some other session */
1193      NumberOfConnections=NumberOfConnections - 1;
1194      for (i = 0; i < NumberOfConnections; i++) {
1195         if ((retval = Mini_TIP_SetCurrSession(Session_ids[i])) == SUCCESS) 
1196             return (retval);
1197      }
1198      if (i >= NumberOfConnections)  { /* exit DFE */
1199          exit_loop = TRUE;
1200      }
1201   }
1202
1203
1204   return ((INT32) retval);
1205 }
1206
1207 INT32
1208 init_proc_cmd(token, tokencnt)
1209 char    **token;
1210 int     tokencnt;
1211 {
1212   INT32         retval;
1213
1214   retval = Mini_send_init_info(&init_info);
1215
1216   return ((INT32) retval);
1217 }
1218
1219 INT32
1220 destroy_proc_cmd(token, tokencnt)
1221 char    **token;
1222 int     tokencnt;
1223 {
1224   INT32         retval;
1225
1226   retval = Mini_TIP_DestroyProc();
1227
1228   return ((INT32) retval);
1229 }
1230
1231 INT32
1232 set_sessionid_cmd(token, tokencnt)
1233 char    **token;
1234 int     tokencnt;
1235 {
1236   INT32         retval;
1237   int           sid;
1238
1239   if (tokencnt < 2)
1240     return (EMSYNTAX);
1241
1242   if (sscanf(token[1],"%d",&sid) != 1)
1243     return (EMSYNTAX);
1244
1245   retval = Mini_TIP_SetCurrSession(sid);
1246
1247   return ((INT32) retval);
1248 }
1249
1250 INT32
1251 set_pid_cmd(token, tokencnt)
1252 char    **token;
1253 int     tokencnt;
1254 {
1255   INT32         retval;
1256   int           pid;
1257
1258   if (tokencnt < 2)
1259     return (EMSYNTAX);
1260
1261   if (sscanf(token[1],"%d",&pid) != 1)
1262     return (EMSYNTAX);
1263
1264   retval = Mini_TIP_SetPID(pid);
1265
1266   return ((INT32) retval);
1267 }
1268
1269
1270 INT32
1271 go_cmd(token, token_count)
1272    char   *token[];
1273    int     token_count;
1274    {
1275
1276    INT32        retval;
1277
1278    if ((retval = Mini_go()) != SUCCESS) {
1279      return(FAILURE);
1280    } else {
1281      GoCmdFlag = 1;
1282      BlockMode = NONBLOCK;
1283      if (TipStdinMode & TIP_NBLOCK) 
1284           io_config.io_control = TERM_29K;
1285      else if (TipStdinMode & TIP_ASYNC)
1286           io_config.io_control = TERM_29K;
1287      else if (TipStdinMode == TIP_COOKED)
1288           io_config.io_control = TERM_USER;
1289      else {
1290           TipStdinMode = TIP_COOKED;
1291           io_config.io_control = TERM_USER;
1292      }
1293      io_config.target_running = TRUE;
1294      return(SUCCESS);
1295    };
1296
1297 }  /* end go_cmd() */
1298
1299 /*
1300 ** This command is used to "trace" or step through code.
1301 ** A "t" command with no parameters defaults to a single.
1302 ** step.  A "t" command with an integer value following
1303 ** steps for as many instructions as is specified by
1304 ** that integer.
1305 */
1306
1307 INT32
1308 trace_cmd(token, token_count)
1309    char   *token[];
1310    int     token_count;
1311    {
1312    int    result;
1313    INT32  count;
1314    INT32        retval;
1315
1316    if (token_count == 1) {
1317       count = 1; 
1318       }
1319    else
1320    if (token_count >= 2) {
1321       result = get_word(token[1], &count);
1322       if (result != 0)
1323          return (EMSYNTAX);
1324       }
1325
1326    if ((retval = Mini_step(count)) != SUCCESS) {
1327      return(FAILURE);
1328    } else {
1329      GoCmdFlag = 1;
1330      BlockMode = NONBLOCK;
1331      if (TipStdinMode & TIP_NBLOCK) 
1332           io_config.io_control = TERM_29K;
1333      else if (TipStdinMode & TIP_ASYNC)
1334           io_config.io_control = TERM_29K;
1335      else if (TipStdinMode == TIP_COOKED)
1336           io_config.io_control = TERM_USER;
1337      else {
1338           TipStdinMode = TIP_COOKED;
1339           io_config.io_control = TERM_USER;
1340      }
1341      io_config.target_running = TRUE;
1342      return(SUCCESS);
1343    }
1344
1345    }  /* end trace_cmd() */
1346
1347 /*
1348  * The "ch0" command is used to send characters (input) to the application
1349  * program asynchronously. This command deinstalls the control-C handler,
1350  * sets up input to raw mode, polls the keyboard, sends the bytes to the
1351  * TIP. The command is exited when Ctrl-U is typed.
1352  */
1353
1354 INT32
1355 channel0_cmd(token, token_count)
1356    char   *token[];
1357    int     token_count;
1358 {
1359       io_config.io_control = TERM_29K;
1360 #ifndef MSDOS
1361       ioctl (fileno(stdin), TCGETA, &NewTermbuf);       /* New settings */
1362       NewTermbuf.c_lflag &= ~(ICANON);
1363       NewTermbuf.c_cc[4] = 0;           /* MIN */
1364       NewTermbuf.c_cc[5] = 0;           /* TIME */
1365       ioctl (fileno(stdin), TCSETA, &NewTermbuf); /* Set new settings */
1366 #endif
1367   return (0);
1368 }
1369
1370 /*
1371  * Only for stdin, not for command file input 
1372  */
1373 INT32
1374 Mini_poll_channel0()
1375 {
1376   BYTE  ch;
1377
1378     /* read from terminal */
1379 #ifdef MSDOS
1380       /* CBREAK mode */
1381       if (kbhit()) {
1382          ch = (unsigned char) getche();
1383          if (io_config.echo_mode == (INT32) TRUE) {
1384            putc (ch, io_config.echo_file);
1385            fflush (io_config.echo_file);
1386          }
1387          if (ch == (BYTE) TOGGLE_CHAR) { /* Ctrl-U typed, give control back to User */
1388            io_config.io_control = TERM_USER;
1389            display_termuser();
1390            return (0);
1391          } else {
1392            if (ch == (unsigned char) 13) { /* \r, insert \n */
1393              putchar(10);       /* line feed */
1394              if (io_config.echo_mode == (INT32) TRUE) {
1395                putc (ch, io_config.echo_file);
1396                fflush (io_config.echo_file);
1397              }
1398            }
1399 #ifdef MSDOS
1400            if (ch == (unsigned char) 10) { /* \n, ignore \n */
1401              return (0);
1402            }
1403 #endif
1404            Mini_put_stdin((char *)&ch, 1, &io_count_done);
1405            return (0);
1406          }
1407        }
1408        return(0);
1409 #else   /* Unix */
1410      /* 
1411       * Set STDIN to CBREAK mode. For each character read() send it
1412       * to TIP using Mini_put_stdin(). This is done only if the
1413       * terminal is controlled by the 29K Target System, i.e. when
1414       * io_config.io_control == TERM_29K. Otherwise, this function should
1415       * not be called as it would affect the command-line processing.
1416       */
1417       /* while ((io_bufsize = read (fileno(stdin), &ch, 1)) == 1) { */
1418       if ((io_bufsize = read (fileno(stdin), &ch, 1)) == 1) { 
1419         if (io_config.echo_mode == (INT32) TRUE) {
1420           putc (ch, io_config.echo_file);
1421           fflush (io_config.echo_file);
1422         }
1423         if (ch == (BYTE) TOGGLE_CHAR) { /* process ctrl-U */
1424          ioctl (fileno(stdin), TCSETA, &OldTermbuf); /* reset old settings */
1425          io_config.io_control = TERM_USER;
1426          display_termuser();
1427          return (0);
1428         } else { /* send it to TIP */
1429          Mini_put_stdin((char *)&ch, 1, &io_count_done);
1430         }
1431       }
1432      return (0);
1433 #endif
1434 } /* end Mini_poll_channel0() */
1435
1436 void
1437 PrintTrapMsg(num)
1438 int     num;
1439 {
1440   if ((num >= 0) && (num <= 22)) {
1441     fprintf(stderr, "%s Trap occurred at ", TrapMsg[num]);
1442     if (io_config.echo_mode == (INT32) TRUE)
1443        fprintf(io_config.echo_file, "%s Trap occurred at ", TrapMsg[num]);
1444   } else {
1445     fprintf(stderr, "Trap %d occurred at ");
1446     if (io_config.echo_mode == (INT32) TRUE)
1447        fprintf(io_config.echo_file, "Trap %d occurred at ");
1448   }
1449 }
1450
1451 void
1452 display_term29k()
1453 {
1454     fprintf(stderr,"\nTerminal controlled 29K target...Type Ctrl-U <ret> for mondfe prompt\n");
1455     fflush (stderr);
1456     if (io_config.echo_mode == (INT32) TRUE)
1457        fprintf(stderr,"\nTerminal controlled 29K target...Type Ctrl-U <ret> for mondfe prompt\n");
1458 #ifndef MSDOS
1459       ioctl (fileno(stdin), TCGETA, &NewTermbuf);       /* New settings */
1460       NewTermbuf.c_lflag &= ~(ICANON);
1461       NewTermbuf.c_cc[4] = 0;           /* MIN */
1462       NewTermbuf.c_cc[5] = 0;           /* TIME */
1463       ioctl (fileno(stdin), TCSETA, &NewTermbuf); /* Set new settings */
1464 #endif
1465 }
1466
1467 void
1468 display_termuser()
1469 {
1470 #ifndef MSDOS
1471     ioctl (fileno(stdin), TCSETA, &OldTermbuf); /*reset settings */
1472 #endif
1473    /* Print a prompt */
1474   fprintf(stderr, "\n%s>", ProgramName);
1475   if (io_config.echo_mode == (INT32) TRUE)
1476     fprintf(io_config.echo_file, "\n%s>", ProgramName);
1477 }
1478
1479 INT32
1480 quietmode_off(token, token_count)
1481    char   *token[];
1482    int     token_count;
1483 {
1484   QuietMode = 0;
1485   return (0);
1486 }
1487
1488 INT32
1489 quietmode_on(token, token_count)
1490    char   *token[];
1491    int     token_count;
1492 {
1493   QuietMode = 1;
1494   return (0);
1495 }
1496
1497 INT32
1498 logoff_cmd(token, token_count)
1499    char   *token[];
1500    int     token_count;
1501 {
1502    if (io_config.log_mode == (INT32) TRUE) { 
1503      io_config.log_mode = (INT32) FALSE;
1504      (void) fclose(io_config.log_file);
1505    }
1506    return (0);
1507 }
1508
1509 INT32
1510 logon_cmd(token, token_count)
1511    char   *token[];
1512    int     token_count;
1513 {
1514    if (io_config.log_mode == (INT32) FALSE) { 
1515      if (strcmp(io_config.log_filename, "\0") != 0) {/* valid file */
1516        io_config.log_mode = (INT32) TRUE;
1517        if ((io_config.log_file = fopen(io_config.log_filename, "a")) == NULL)
1518        {
1519           io_config.log_mode = (INT32) FALSE;
1520           warning(EMLOGOPEN);
1521        };
1522      } else {
1523        warning(EMLOGOPEN);
1524      }
1525    }
1526    return (0);
1527 }
1528
1529 INT32
1530 set_logfile(token, token_count)
1531    char   *token[];
1532    int     token_count;
1533 {
1534   if (token_count < 2) /* insufficient number of args */
1535     return (EMSYNTAX);
1536
1537   (void) strcpy ((char *)(&(io_config.log_filename[0])),token[1]);
1538
1539   if (io_config.log_mode == (INT32) TRUE) { /* replace log file used */
1540          if ((io_config.log_file = 
1541                       fopen (io_config.log_filename, "w")) == NULL) {
1542             warning (EMLOGOPEN);
1543             io_config.log_mode = (INT32) FALSE;
1544          }
1545   } else {
1546          io_config.log_mode = (INT32) TRUE;
1547          if ((io_config.log_file = 
1548                       fopen (io_config.log_filename, "w")) == NULL) {
1549             warning (EMLOGOPEN);
1550             io_config.log_mode = (INT32) FALSE;
1551          } 
1552   }
1553   return (0);
1554
1555 }
1556
1557 INT32
1558 echomode_on(token, token_count)
1559    char   *token[];
1560    int     token_count;
1561 {
1562   if (io_config.echo_mode == (INT32) FALSE) {
1563     if (strcmp(io_config.echo_filename, "\0") != 0) { /* if valid file in effect */
1564        io_config.echo_mode = (INT32) TRUE;
1565        if ((io_config.echo_file = fopen (io_config.echo_filename, "a")) == NULL)
1566        {
1567          warning (EMECHOPEN);
1568          io_config.echo_mode = (INT32) FALSE;
1569        }
1570     } else
1571        warning(EMINVECHOFILE);
1572   }
1573   return (0);
1574 }
1575
1576 INT32
1577 echomode_off(token, token_count)
1578    char   *token[];
1579    int     token_count;
1580 {
1581   if (io_config.echo_mode == (INT32) TRUE)  {
1582     io_config.echo_mode = (INT32) FALSE;
1583     (void) fclose(io_config.echo_file);
1584   }
1585   return (0);
1586 }
1587
1588 INT32
1589 echofile_cmd(token, token_count)
1590    char   *token[];
1591    int     token_count;
1592 {
1593   if (token_count < 2) /* insufficient number of args */
1594     return (EMSYNTAX);
1595
1596   (void) strcpy ((char *)(&(io_config.echo_filename[0])),token[1]);
1597
1598   if (io_config.echo_mode == (INT32) TRUE) { /* replace echo file used */
1599          if ((io_config.echo_file = 
1600                       fopen (io_config.echo_filename, "w")) == NULL) {
1601             warning (EMECHOPEN);
1602             io_config.echo_mode = (INT32) FALSE;
1603          }
1604   } else {
1605          io_config.echo_mode = (INT32) TRUE;
1606          if ((io_config.echo_file = 
1607                       fopen (io_config.echo_filename, "w")) == NULL) {
1608             warning (EMECHOPEN);
1609             io_config.echo_mode = (INT32) FALSE;
1610          } 
1611   }
1612   return (0);
1613 }
1614
1615 INT32
1616 cmdfile_cmd(token, token_count)
1617    char   *token[];
1618    int     token_count;
1619 {
1620   if (token_count < 2)
1621      return (EMSYNTAX);
1622
1623   (void) strcpy((char *)(&(io_config.cmd_filename[0])),token[1]);
1624
1625   if (io_config.cmd_file_io == (INT32) TRUE) {
1626     warning (EMCMDFILENEST); /* command file nesting not allowed */
1627   } else {
1628     io_config.cmd_file_io = (INT32) TRUE;
1629     if ((io_config.cmd_file = fopen (io_config.cmd_filename,"r")) == NULL) {
1630       warning (EMCMDOPEN);
1631       io_config.cmd_file_io = (INT32) FALSE;
1632     } else {
1633        /* MON_STDIN is command file */
1634        MON_STDIN = fileno(io_config.cmd_file); /* set MON_STDIN */
1635     }
1636   }
1637
1638   return (0);
1639 }
1640
1641 INT32
1642 tip_cmd(token, token_count)
1643    char   *token[];
1644    int     token_count;
1645 {
1646   if (token_count < 2)
1647     return (EMSYNTAX);
1648
1649   sprintf(tip_cmd_buffer, "%s %s\0", token[0], token[1]);
1650
1651   Mini_put_trans(tip_cmd_buffer);
1652
1653   return (0);
1654 }