* h8500-tdep.c (initialize_h8500_tdep, large_command):
[deliverable/binutils-gdb.git] / gdb / remote-hms.c
CommitLineData
1f46923f 1/* Remote debugging interface for Hitachi HMS Monitor Version 1.0
3b5442f9 2 Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
e17960fb
JG
3 Contributed by Cygnus Support. Written by Steve Chamberlain
4 (sac@cygnus.com).
fa4b55a1
SC
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
fa4b55a1
SC
22#include "defs.h"
23#include "inferior.h"
24#include "wait.h"
25#include "value.h"
e17960fb 26#include <string.h>
fa4b55a1
SC
27#include <ctype.h>
28#include <fcntl.h>
29#include <signal.h>
30#include <setjmp.h>
31#include <errno.h>
32#include "terminal.h"
33#include "target.h"
34#include "gdbcore.h"
a493d9a6 35#include "serial.h"
fa4b55a1
SC
36
37/* External data declarations */
ec25d19b 38extern int stop_soon_quietly; /* for wait_for_inferior */
fa4b55a1 39
fa4b55a1 40/* Forward data declarations */
ec25d19b 41extern struct target_ops hms_ops; /* Forward declaration */
fa4b55a1
SC
42
43/* Forward function declarations */
44static void hms_fetch_registers ();
ec25d19b 45static int hms_store_registers ();
fa4b55a1 46static void hms_close ();
ec25d19b 47static int hms_clear_breakpoints ();
fa4b55a1
SC
48
49extern struct target_ops hms_ops;
3b5442f9
SC
50static void hms_drain ();
51static void add_commands ();
52static void remove_commands ();
fa4b55a1 53
1f46923f
SC
54static int quiet = 1;
55
a493d9a6
SC
56
57serial_t desc;
58
1f46923f
SC
59/***********************************************************************/
60/* Caching stuff stolen from remote-nindy.c */
61
62/* The data cache records all the data read from the remote machine
63 since the last time it stopped.
64
65 Each cache block holds LINE_SIZE bytes of data
66 starting at a multiple-of-LINE_SIZE address. */
67
1f46923f 68#define LINE_SIZE_POWER 4
ec25d19b
SC
69#define LINE_SIZE (1<<LINE_SIZE_POWER) /* eg 1<<3 == 8 */
70#define LINE_SIZE_MASK ((LINE_SIZE-1)) /* eg 7*2+1= 111*/
1f46923f
SC
71#define DCACHE_SIZE 64 /* Number of cache blocks */
72#define XFORM(x) ((x&LINE_SIZE_MASK)>>2)
ec25d19b
SC
73struct dcache_block
74 {
75 struct dcache_block *next, *last;
76 unsigned int addr; /* Address for which data is recorded. */
77 int data[LINE_SIZE / sizeof (int)];
78 };
1f46923f
SC
79
80struct dcache_block dcache_free, dcache_valid;
81
ec25d19b 82/* Free all the data cache blocks, thus discarding all cached data. */
1f46923f
SC
83static
84void
85dcache_flush ()
86{
87 register struct dcache_block *db;
88
89 while ((db = dcache_valid.next) != &dcache_valid)
90 {
91 remque (db);
92 insque (db, &dcache_free);
93 }
94}
95
96/*
97 * If addr is present in the dcache, return the address of the block
98 * containing it.
99 */
100static
101struct dcache_block *
102dcache_hit (addr)
103 unsigned int addr;
104{
105 register struct dcache_block *db;
106
107 if (addr & 3)
108 abort ();
109
110 /* Search all cache blocks for one that is at this address. */
111 db = dcache_valid.next;
112 while (db != &dcache_valid)
113 {
ec25d19b 114 if ((addr & ~LINE_SIZE_MASK) == db->addr)
1f46923f
SC
115 return db;
116 db = db->next;
117 }
118 return NULL;
119}
120
121/* Return the int data at address ADDR in dcache block DC. */
122static
123int
124dcache_value (db, addr)
125 struct dcache_block *db;
126 unsigned int addr;
127{
128 if (addr & 3)
129 abort ();
ec25d19b 130 return (db->data[XFORM (addr)]);
1f46923f
SC
131}
132
133/* Get a free cache block, put or keep it on the valid list,
134 and return its address. The caller should store into the block
135 the address and data that it describes, then remque it from the
136 free list and insert it into the valid list. This procedure
137 prevents errors from creeping in if a ninMemGet is interrupted
138 (which used to put garbage blocks in the valid list...). */
139static
140struct dcache_block *
141dcache_alloc ()
142{
143 register struct dcache_block *db;
144
145 if ((db = dcache_free.next) == &dcache_free)
146 {
147 /* If we can't get one from the free list, take last valid and put
148 it on the free list. */
149 db = dcache_valid.last;
150 remque (db);
151 insque (db, &dcache_free);
152 }
153
154 remque (db);
155 insque (db, &dcache_valid);
156 return (db);
157}
158
159/* Return the contents of the word at address ADDR in the remote machine,
160 using the data cache. */
161static
162int
163dcache_fetch (addr)
164 CORE_ADDR addr;
165{
166 register struct dcache_block *db;
167
168 db = dcache_hit (addr);
169 if (db == 0)
170 {
171 db = dcache_alloc ();
172 immediate_quit++;
ec25d19b 173 hms_read_inferior_memory (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
1f46923f
SC
174 immediate_quit--;
175 db->addr = addr & ~LINE_SIZE_MASK;
ec25d19b 176 remque (db); /* Off the free list */
1f46923f
SC
177 insque (db, &dcache_valid); /* On the valid list */
178 }
179 return (dcache_value (db, addr));
180}
181
182/* Write the word at ADDR both in the data cache and in the remote machine. */
183static void
184dcache_poke (addr, data)
185 CORE_ADDR addr;
186 int data;
187{
188 register struct dcache_block *db;
189
190 /* First make sure the word is IN the cache. DB is its cache block. */
191 db = dcache_hit (addr);
192 if (db == 0)
ec25d19b
SC
193 {
194 db = dcache_alloc ();
195 immediate_quit++;
196 hms_write_inferior_memory (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
197 immediate_quit--;
198 db->addr = addr & ~LINE_SIZE_MASK;
199 remque (db); /* Off the free list */
200 insque (db, &dcache_valid); /* On the valid list */
201 }
1f46923f
SC
202
203 /* Modify the word in the cache. */
ec25d19b 204 db->data[XFORM (addr)] = data;
1f46923f
SC
205
206 /* Send the changed word. */
207 immediate_quit++;
ec25d19b 208 hms_write_inferior_memory (addr, (unsigned char *) &data, 4);
1f46923f
SC
209 immediate_quit--;
210}
211
212/* The cache itself. */
213struct dcache_block the_cache[DCACHE_SIZE];
214
215/* Initialize the data cache. */
216static void
217dcache_init ()
218{
219 register i;
220 register struct dcache_block *db;
221
222 db = the_cache;
223 dcache_free.next = dcache_free.last = &dcache_free;
224 dcache_valid.next = dcache_valid.last = &dcache_valid;
ec25d19b 225 for (i = 0; i < DCACHE_SIZE; i++, db++)
1f46923f
SC
226 insque (db, &dcache_free);
227}
fa4b55a1 228
1f46923f
SC
229/***********************************************************************
230 * I/O stuff stolen from remote-eb.c
231 ***********************************************************************/
232
233static int timeout = 2;
fa4b55a1 234
b52373a2 235static const char *dev_name;
1f46923f 236
fa4b55a1
SC
237/* Descriptor for I/O to remote machine. Initialize it to -1 so that
238 hms_open knows that we don't have a file open when the program
239 starts. */
fa4b55a1 240
ae0ea72e 241int is_open = 0;
a493d9a6 242int
ec25d19b 243check_open ()
fa4b55a1 244{
ae0ea72e 245 if (!is_open)
ec25d19b
SC
246 {
247 error ("remote device not open");
248 }
fa4b55a1
SC
249}
250
ae0ea72e
SC
251#define ON 1
252#define OFF 0
1f46923f
SC
253
254/* Read a character from the remote system, doing all the fancy
255 timeout stuff. */
256static int
257readchar ()
fa4b55a1 258{
ae0ea72e 259 int buf;
ec25d19b 260
a493d9a6 261 buf = SERIAL_READCHAR (desc, timeout);
1f46923f 262
a493d9a6 263 if (buf == SERIAL_TIMEOUT)
3b5442f9
SC
264 {
265 hms_write (".\r\n", 3);
266 error ("Timeout reading from remote system.");
267 }
268 if (buf == SERIAL_ERROR)
269 {
270 error ("Serial port error!");
271 }
1f46923f
SC
272
273 if (!quiet)
199b2450 274 printf_unfiltered ("%c", buf);
ec25d19b 275
1f46923f 276 return buf & 0x7f;
fa4b55a1
SC
277}
278
fa4b55a1 279static int
1f46923f 280readchar_nofail ()
fa4b55a1 281{
ae0ea72e 282 int buf;
ec25d19b 283
a493d9a6
SC
284 buf = SERIAL_READCHAR (desc, timeout);
285 if (buf == SERIAL_TIMEOUT)
ec25d19b 286 buf = 0;
ae0ea72e 287 if (!quiet)
199b2450 288 printf_unfiltered ("%c", buf);
ec25d19b 289
fa4b55a1 290 return buf & 0x7f;
ae0ea72e 291
fa4b55a1
SC
292}
293
ec25d19b 294/* Keep discarding input from the remote system, until STRING is found.
fa4b55a1
SC
295 Let the user break out immediately. */
296static void
297expect (string)
298 char *string;
299{
300 char *p = string;
301
fa4b55a1
SC
302 immediate_quit = 1;
303 while (1)
304 {
ec25d19b 305 if (readchar () == *p)
fa4b55a1
SC
306 {
307 p++;
308 if (*p == '\0')
309 {
310 immediate_quit = 0;
311 return;
312 }
313 }
314 else
315 p = string;
316 }
317}
318
319/* Keep discarding input until we see the hms prompt.
320
321 The convention for dealing with the prompt is that you
322 o give your command
323 o *then* wait for the prompt.
324
325 Thus the last thing that a procedure does with the serial line
326 will be an expect_prompt(). Exception: hms_resume does not
327 wait for the prompt, because the terminal is being handed over
328 to the inferior. However, the next thing which happens after that
329 is a hms_wait which does wait for the prompt.
330 Note that this includes abnormal exit, e.g. error(). This is
331 necessary to prevent getting into states from which we can't
332 recover. */
333static void
334expect_prompt ()
335{
fa4b55a1
SC
336 expect ("HMS>");
337}
338
339/* Get a hex digit from the remote system & return its value.
340 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
341static int
342get_hex_digit (ignore_space)
343 int ignore_space;
344{
345 int ch;
ec25d19b 346
fa4b55a1
SC
347 while (1)
348 {
349 ch = readchar ();
350 if (ch >= '0' && ch <= '9')
351 return ch - '0';
352 else if (ch >= 'A' && ch <= 'F')
353 return ch - 'A' + 10;
354 else if (ch >= 'a' && ch <= 'f')
355 return ch - 'a' + 10;
356 else if (ch == ' ' && ignore_space)
357 ;
358 else
359 {
360 expect_prompt ();
361 error ("Invalid hex digit from remote system.");
362 }
363 }
364}
365
366/* Get a byte from hms_desc and put it in *BYT. Accept any number
367 leading spaces. */
368static void
369get_hex_byte (byt)
370 char *byt;
371{
372 int val;
373
374 val = get_hex_digit (1) << 4;
375 val |= get_hex_digit (0);
376 *byt = val;
377}
378
379/* Read a 32-bit hex word from the hms, preceded by a space */
ec25d19b
SC
380static long
381get_hex_word ()
fa4b55a1
SC
382{
383 long val;
384 int j;
ec25d19b 385
fa4b55a1
SC
386 val = 0;
387 for (j = 0; j < 8; j++)
ec25d19b 388 val = (val << 4) + get_hex_digit (j == 0);
fa4b55a1
SC
389 return val;
390}
fa4b55a1 391
ec25d19b 392/* Called when SIGALRM signal sent due to alarm() timeout. */
fa4b55a1
SC
393
394/* Number of SIGTRAPs we need to simulate. That is, the next
395 NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
396 SIGTRAP without actually waiting for anything. */
397
398static int need_artificial_trap = 0;
399
400void
ec25d19b
SC
401hms_kill (arg, from_tty)
402 char *arg;
403 int from_tty;
fa4b55a1 404{
fa4b55a1 405
fa4b55a1 406}
1f46923f 407
fa4b55a1 408/*
ec25d19b 409 * Download a file specified in 'args', to the hms.
fa4b55a1
SC
410 */
411static void
ec25d19b
SC
412hms_load (args, fromtty)
413 char *args;
414 int fromtty;
fa4b55a1 415{
ec25d19b 416 bfd *abfd;
fa4b55a1 417 asection *s;
ec25d19b
SC
418 int n;
419 char buffer[1024];
ae0ea72e 420
ec25d19b 421 check_open ();
1f46923f 422
ec25d19b
SC
423 dcache_flush ();
424 inferior_pid = 0;
0685d95f 425 abfd = bfd_openr (args, gnutarget);
ec25d19b
SC
426 if (!abfd)
427 {
428 printf_filtered ("Unable to open file %s\n", args);
429 return;
430 }
fa4b55a1 431
ec25d19b
SC
432 if (bfd_check_format (abfd, bfd_object) == 0)
433 {
434 printf_filtered ("File is not an object file\n");
435 return;
436 }
fa4b55a1
SC
437
438 s = abfd->sections;
ec25d19b 439 while (s != (asection *) NULL)
fa4b55a1 440 {
ec25d19b
SC
441 if (s->flags & SEC_LOAD)
442 {
443 int i;
fa4b55a1 444
ae0ea72e 445#define DELTA 1024
ec25d19b
SC
446 char *buffer = xmalloc (DELTA);
447
448 printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s->_raw_size);
449 for (i = 0; i < s->_raw_size; i += DELTA)
450 {
451 int delta = DELTA;
452
453 if (delta > s->_raw_size - i)
454 delta = s->_raw_size - i;
455
456 bfd_get_section_contents (abfd, s, buffer, i, delta);
457 hms_write_inferior_memory (s->vma + i, buffer, delta);
458 printf_filtered ("*");
199b2450 459 gdb_flush (gdb_stdout);
ec25d19b
SC
460 }
461 printf_filtered ("\n");
462 free (buffer);
463 }
464 s = s->next;
fa4b55a1 465 }
ec25d19b
SC
466 sprintf (buffer, "r PC=%x", abfd->start_address);
467 hms_write_cr (buffer);
468 expect_prompt ();
edd01519
SC
469 /* Turn off all breakpoints */
470 hms_write_cr ("b -");
471 expect_prompt ();
fa4b55a1
SC
472}
473
474/* This is called not only when we first attach, but also when the
475 user types "run" after having attached. */
476void
477hms_create_inferior (execfile, args, env)
478 char *execfile;
479 char *args;
480 char **env;
481{
482 int entry_pt;
ec25d19b 483 char buffer[100];
fa4b55a1
SC
484
485 if (args && *args)
ec25d19b 486 error ("Can't pass arguments to remote hms process.");
fa4b55a1
SC
487
488 if (execfile == 0 || exec_bfd == 0)
ec25d19b 489 error ("No exec file specified");
fa4b55a1
SC
490
491 entry_pt = (int) bfd_get_start_address (exec_bfd);
ec25d19b 492 check_open ();
1f46923f 493
ec25d19b
SC
494 hms_kill (NULL, NULL);
495 hms_clear_breakpoints ();
ae0ea72e 496 init_wait_for_inferior ();
ec25d19b
SC
497 hms_write_cr ("");
498 expect_prompt ();
fa4b55a1 499
ae0ea72e 500 insert_breakpoints (); /* Needed to get correct instruction in cache */
45dc9be3 501 proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
fa4b55a1
SC
502}
503
fa4b55a1
SC
504/* Open a connection to a remote debugger.
505 NAME is the filename used for communication, then a space,
506 then the baud rate.
507 */
508
509static char *
ec25d19b
SC
510find_end_of_word (s)
511 char *s;
fa4b55a1 512{
ec25d19b
SC
513 while (*s && !isspace (*s))
514 s++;
fa4b55a1
SC
515 return s;
516}
517
ec25d19b
SC
518static char *
519get_word (p)
520 char **p;
fa4b55a1
SC
521{
522 char *s = *p;
ec25d19b 523 char *word;
fa4b55a1
SC
524 char *copy;
525 size_t len;
526
ec25d19b
SC
527 while (isspace (*s))
528 s++;
fa4b55a1
SC
529
530 word = s;
531
532 len = 0;
533
ec25d19b
SC
534 while (*s && !isspace (*s))
535 {
536 s++;
537 len++;
538
539 }
540 copy = xmalloc (len + 1);
541 memcpy (copy, word, len);
fa4b55a1
SC
542 copy[len] = 0;
543 *p = s;
544 return copy;
545}
546
547static int baudrate = 9600;
1f46923f
SC
548
549static int
ec25d19b 550is_baudrate_right ()
1f46923f 551{
ae0ea72e 552 int ok;
ec25d19b 553
1f46923f 554 /* Put this port into NORMAL mode, send the 'normal' character */
ae0ea72e 555
ec25d19b 556 hms_write ("\001", 1); /* Control A */
3b5442f9 557 hms_write ("\r\n", 2); /* Cr */
ae0ea72e 558
ec25d19b
SC
559 while (1)
560 {
a493d9a6 561 ok = SERIAL_READCHAR (desc, timeout);
ec25d19b
SC
562 if (ok < 0)
563 break;
564 }
ae0ea72e 565
ec25d19b
SC
566 hms_write ("r", 1);
567
568 if (readchar_nofail () == 'r')
569 return 1;
1f46923f
SC
570
571 /* Not the right baudrate, or the board's not on */
572 return 0;
1f46923f
SC
573}
574static void
ec25d19b 575set_rate ()
1f46923f 576{
a493d9a6 577 if (!SERIAL_SETBAUDRATE (desc, baudrate))
ec25d19b 578 error ("Can't set baudrate");
1f46923f
SC
579}
580
1f46923f 581
fa4b55a1
SC
582static void
583hms_open (name, from_tty)
584 char *name;
585 int from_tty;
586{
fa4b55a1
SC
587 unsigned int prl;
588 char *p;
ec25d19b
SC
589
590 if (name == 0)
591 {
592 name = "";
593 }
594 if (is_open)
836e343b 595 hms_close (0);
a493d9a6
SC
596 dev_name = strdup (name);
597
598 if (!(desc = SERIAL_OPEN (dev_name)))
ec25d19b 599 perror_with_name ((char *) dev_name);
a493d9a6
SC
600
601 SERIAL_RAW (desc);
ae0ea72e 602 is_open = 1;
edd01519 603 push_target (&hms_ops);
ec25d19b
SC
604 dcache_init ();
605
fa4b55a1 606 /* Hello? Are you there? */
3b5442f9 607 SERIAL_WRITE (desc, "\r\n", 2);
fa4b55a1
SC
608 expect_prompt ();
609
610 /* Clear any break points */
ec25d19b 611 hms_clear_breakpoints ();
fa4b55a1 612
edd01519 613 printf_filtered ("Connected to remote board running HMS monitor.\n");
3b5442f9
SC
614 add_commands ();
615 hms_drain ();
fa4b55a1
SC
616}
617
618/* Close out all files and local state before this target loses control. */
619
620static void
621hms_close (quitting)
622 int quitting;
623{
fa4b55a1 624 /* Clear any break points */
3b5442f9 625 remove_commands ();
ec25d19b 626 hms_clear_breakpoints ();
ec25d19b 627 sleep (1); /* Let any output make it all the way back */
a493d9a6
SC
628 if (is_open)
629 {
3b5442f9 630 SERIAL_WRITE (desc, "R\r\n", 3);
a493d9a6
SC
631 SERIAL_CLOSE (desc);
632 }
ae0ea72e 633 is_open = 0;
fa4b55a1
SC
634}
635
3b5442f9
SC
636/* Terminate the open connection to the remote debugger. Use this
637when you want to detach and do something else with your gdb. */ void
ec25d19b 638hms_detach (args, from_tty)
fa4b55a1
SC
639 char *args;
640 int from_tty;
641{
ae0ea72e 642 if (is_open)
ec25d19b
SC
643 {
644 hms_clear_breakpoints ();
645 }
646
3b5442f9
SC
647 pop_target (); /* calls hms_close to do the real work
648*/
fa4b55a1 649 if (from_tty)
3b5442f9
SC
650 printf_filtered ("Ending remote %s debugging\n",
651 target_shortname);
fa4b55a1 652}
ec25d19b 653
fa4b55a1
SC
654/* Tell the remote machine to resume. */
655
656void
25286543 657hms_resume (pid, step, sig)
67ac9759 658 int pid, step;
3b5442f9
SC
659 enum target_signal
660 sig;
fa4b55a1 661{
ec25d19b
SC
662 dcache_flush ();
663
664 if (step)
665 {
666 hms_write_cr ("s");
667 expect ("Step>");
668
669 /* Force the next hms_wait to return a trap. Not doing anything
3b5442f9
SC
670 about I/O from the target means that the user has to type "continue"
671 to see any. FIXME, this should be fixed. */
ec25d19b
SC
672 need_artificial_trap = 1;
673 }
fa4b55a1 674 else
ec25d19b
SC
675 {
676 hms_write_cr ("g");
677 expect ("g");
678 }
fa4b55a1
SC
679}
680
3b5442f9
SC
681/* Wait until the remote machine stops, then return, storing status in
682STATUS just as `wait' would. */
fa4b55a1
SC
683
684int
de43d7d0
SG
685hms_wait (pid, status)
686 int pid;
67ac9759 687 struct target_waitstatus *status;
fa4b55a1 688{
3b5442f9
SC
689 /* Strings to look for. '?' means match any single character. Note
690 that with the algorithm we use, the initial character of the string
691 cannot recur in the string, or we will not find some cases of the
692 string in the input. */
ec25d19b 693
96743d3c 694 static char bpt[] = "At breakpoint:";
ec25d19b 695
3b5442f9
SC
696 /* It would be tempting to look for "\n[__exit + 0x8]\n" but that
697 requires loading symbols with "yc i" and even if we did do that we
698 don't know that the file has symbols. */
699 static char exitmsg[] = "HMS>";
fa4b55a1
SC
700 char *bp = bpt;
701 char *ep = exitmsg;
702
3b5442f9
SC
703 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.
704 */
fa4b55a1 705 char swallowed[50];
ec25d19b 706
fa4b55a1
SC
707 /* Current position in swallowed. */
708 char *swallowed_p = swallowed;
709
710 int ch;
711 int ch_handled;
712 int old_timeout = timeout;
3b5442f9
SC
713 int
714 old_immediate_quit = immediate_quit;
1f46923f 715 int swallowed_cr = 0;
ec25d19b 716
67ac9759
JK
717 status->kind = TARGET_WAITKIND_EXITED;
718 status->value.integer = 0;
fa4b55a1
SC
719
720 if (need_artificial_trap != 0)
ec25d19b 721 {
3b5442f9
SC
722 status->kind =
723 TARGET_WAITKIND_STOPPED;
67ac9759 724 status->value.sig = TARGET_SIGNAL_TRAP;
ec25d19b
SC
725 need_artificial_trap--;
726 return 0;
727 }
fa4b55a1 728
63eef03a 729 timeout = 5; /* Don't time out for a while - user program is running.
3b5442f9 730 */
1f46923f 731 immediate_quit = 1; /* Helps ability to QUIT */
ec25d19b 732 while (1)
96743d3c 733 {
ec25d19b
SC
734 QUIT; /* Let user quit and leave process running */
735 ch_handled = 0;
736 ch = readchar ();
737 if (ch == *bp)
738 {
739 bp++;
740 if (*bp == '\0')
741 break;
742 ch_handled = 1;
743
744 *swallowed_p++ = ch;
745 }
746 else
747 {
748 bp = bpt;
749 }
3b5442f9
SC
750 if
751 (ch == *ep || *ep == '?')
752 {
753 ep++;
754 if (*ep == '\0')
755 break;
756
757 if (!ch_handled)
758 *swallowed_p++ = ch;
759 ch_handled =
760 1;
761 }
ec25d19b
SC
762 else
763 {
764 ep = exitmsg;
765 }
766
767 if (!ch_handled)
768 {
769 char *p;
770
771 /* Print out any characters which have been swallowed. */
772 for (p = swallowed; p < swallowed_p; ++p)
753a74d9 773 putc_unfiltered (*p);
ec25d19b
SC
774 swallowed_p = swallowed;
775
776 if ((ch != '\r' && ch != '\n') || swallowed_cr > 10)
777 {
753a74d9 778 putc_unfiltered (ch);
ec25d19b
SC
779 swallowed_cr = 10;
780 }
781 swallowed_cr++;
782
783 }
96743d3c 784 }
ec25d19b 785 if (*bp == '\0')
96743d3c 786 {
67ac9759
JK
787 status->kind = TARGET_WAITKIND_STOPPED;
788 status->value.sig = TARGET_SIGNAL_TRAP;
ec25d19b
SC
789 expect_prompt ();
790 }
791 else
96743d3c 792 {
67ac9759 793 status->kind = TARGET_WAITKIND_EXITED;
3b5442f9
SC
794 status->value.integer =
795 TARGET_SIGNAL_STOP;
96743d3c 796 }
ec25d19b 797
fa4b55a1
SC
798 timeout = old_timeout;
799 immediate_quit = old_immediate_quit;
3b5442f9
SC
800 return
801 0;
fa4b55a1
SC
802}
803
3b5442f9
SC
804/* Return the name of register number REGNO in the form input and
805output by hms.
fa4b55a1
SC
806
807 Returns a pointer to a static buffer containing the answer. */
808static char *
809get_reg_name (regno)
810 int regno;
811{
3b5442f9
SC
812 static char *rn[] =
813 REGISTER_NAMES;
ec25d19b 814
fa4b55a1 815 return rn[regno];
fa4b55a1
SC
816}
817
3b5442f9
SC
818/* Read the remote registers. */
819
a493d9a6 820static int
ec25d19b
SC
821gethex (length, start, ok)
822 unsigned int length;
823 char *start;
824 int *ok;
fa4b55a1
SC
825{
826 int result = 0;
ec25d19b
SC
827
828 while (length--)
fa4b55a1 829 {
ec25d19b
SC
830 result <<= 4;
831 if (*start >= 'a' && *start <= 'f')
832 {
833 result += *start - 'a' + 10;
834 }
3b5442f9
SC
835 else if (*start >= 'A' &&
836 *start <= 'F')
ec25d19b
SC
837 {
838 result += *start - 'A' + 10;
839 }
3b5442f9
SC
840 else if
841 (*start >= '0' && *start <= '9')
842 {
843 result += *start - '0';
844 }
ec25d19b
SC
845 else
846 *ok = 0;
847 start++;
848
fa4b55a1 849 }
fa4b55a1
SC
850 return result;
851}
ec25d19b
SC
852static int
853timed_read (buf, n, timeout)
3b5442f9
SC
854 char
855 *buf;
fa4b55a1
SC
856
857{
858 int i;
859 char c;
ec25d19b 860
fa4b55a1 861 i = 0;
ec25d19b
SC
862 while (i < n)
863 {
864 c = readchar ();
865
866 if (c == 0)
867 return i;
868 buf[i] = c;
869 i++;
870
871 }
872 return i;
fa4b55a1 873}
ec25d19b
SC
874
875hms_write (a, l)
876 char *a;
fa4b55a1
SC
877{
878 int i;
ec25d19b 879
a493d9a6 880 SERIAL_WRITE (desc, a, l);
ae0ea72e 881
96743d3c 882 if (!quiet)
3b5442f9
SC
883 {
884 printf_unfiltered ("<");
885 for (i = 0; i < l; i++)
886 {
887 printf_unfiltered ("%c", a[i]);
888 }
889 printf_unfiltered (">");
890 }
fa4b55a1
SC
891}
892
ec25d19b
SC
893hms_write_cr (s)
894 char *s;
fa4b55a1 895{
ec25d19b 896 hms_write (s, strlen (s));
3b5442f9 897 hms_write ("\r\n", 2);
1f46923f
SC
898}
899
edd01519
SC
900#ifdef GDB_TARGET_IS_H8500
901
902/* H8/500 monitor reg dump looks like:
903
904HMS>r
905PC:8000 SR:070C .7NZ.. CP:00 DP:00 EP:00 TP:00 BR:00
906R0-R7: FF5A 0001 F4FE F500 0000 F528 F528 F4EE
907HMS>
908
909
910*/
911
3b5442f9
SC
912supply_val (n, size, ptr, segptr)
913 int n;
914 int size;
915 char *ptr;
916 char *segptr;
edd01519
SC
917{
918 int ok;
919 char raw[4];
3b5442f9 920 switch (size)
edd01519
SC
921 {
922 case 2:
3b5442f9
SC
923 raw[0] = gethex (2, ptr, &ok);
924 raw[1] = gethex (2, ptr + 2, &ok);
edd01519
SC
925 supply_register (n, raw);
926 break;
927 case 1:
3b5442f9 928 raw[0] = gethex (2, ptr, &ok);
edd01519
SC
929 supply_register (n, raw);
930 break;
931 case 4:
932 {
933 int v = gethex (4, ptr, &ok);
934 v |= gethex (2, segptr, &ok) << 16;
935 raw[0] = 0;
3b5442f9
SC
936 raw[1] = (v >> 16) & 0xff;
937 raw[2] = (v >> 8) & 0xff;
938 raw[3] = (v >> 0) & 0xff;
edd01519
SC
939 supply_register (n, raw);
940 }
941 }
942
943}
944static void
945hms_fetch_register (dummy)
946 int dummy;
947{
948#define REGREPLY_SIZE 108
949 char linebuf[REGREPLY_SIZE + 1];
950 int i;
951 int s;
952 int gottok;
953
678ee700 954 LONGEST reg[NUM_REGS];
edd01519
SC
955 check_open ();
956
957 do
958 {
959
960 hms_write_cr ("r");
3b5442f9
SC
961 expect ("r");
962 s = timed_read (linebuf + 1, REGREPLY_SIZE, 1);
edd01519
SC
963
964 linebuf[REGREPLY_SIZE] = 0;
965 gottok = 0;
966 if (linebuf[3] == 'P' &&
967 linebuf[4] == 'C' &&
968 linebuf[5] == ':' &&
969 linebuf[105] == 'H' &&
970 linebuf[106] == 'M' &&
971 linebuf[107] == 'S')
972 {
973
974 /*
975 012
976 r**
977 -------1---------2---------3---------4---------5-----
978 345678901234567890123456789012345678901234567890123456
979 PC:8000 SR:070C .7NZ.. CP:00 DP:00 EP:00 TP:00 BR:00**
980 ---6---------7---------8---------9--------10----
981 789012345678901234567890123456789012345678901234
982 R0-R7: FF5A 0001 F4FE F500 0000 F528 F528 F4EE**
3b5442f9 983
edd01519
SC
984 56789
985 HMS>
986 */
987 gottok = 1;
988
edd01519 989
3b5442f9
SC
990 supply_val (PC_REGNUM, 4, linebuf + 6, linebuf + 29);
991
992 supply_val (CCR_REGNUM, 2, linebuf + 14);
993 supply_val (SEG_C_REGNUM, 1, linebuf + 29);
994 supply_val (SEG_D_REGNUM, 1, linebuf + 35);
995 supply_val (SEG_E_REGNUM, 1, linebuf + 41);
996 supply_val (SEG_T_REGNUM, 1, linebuf + 47);
edd01519
SC
997 for (i = 0; i < 8; i++)
998 {
3b5442f9
SC
999 static int sr[8] =
1000 {35, 35, 35, 35,
1001 41, 41, 47, 47};
edd01519
SC
1002
1003 char raw[4];
1004 char *src = linebuf + 64 + 5 * i;
1005 char *segsrc = linebuf + sr[i];
3b5442f9
SC
1006 supply_val (R0_REGNUM + i, 2, src);
1007 supply_val (PR0_REGNUM + i, 4, src, segsrc);
edd01519
SC
1008 }
1009 }
1010 if (!gottok)
1011 {
3b5442f9
SC
1012 hms_write_cr ("");
1013 expect ("HMS>");
edd01519
SC
1014 }
1015 }
1016 while (!gottok);
1017}
1018#endif
1019
1020#ifdef GDB_TARGET_IS_H8300
1f46923f 1021static void
ae0ea72e 1022hms_fetch_register (dummy)
ec25d19b 1023 int dummy;
fa4b55a1
SC
1024{
1025#define REGREPLY_SIZE 79
ec25d19b 1026 char linebuf[REGREPLY_SIZE + 1];
fa4b55a1 1027 int i;
ec25d19b 1028 int s;
fa4b55a1 1029 int gottok;
ec25d19b 1030
f4f0d174 1031 unsigned LONGEST reg[NUM_REGS];
ec25d19b
SC
1032
1033 check_open ();
1034
1035 do
fa4b55a1 1036 {
ec25d19b 1037 hms_write_cr ("r");
3b5442f9
SC
1038
1039 s = timed_read (linebuf, 1, 1);
1040
1041 while (linebuf[0] != 'r')
1042 s = timed_read (linebuf, 1, 1);
1043
1044 s = timed_read (linebuf + 1, REGREPLY_SIZE - 1, 1);
ec25d19b
SC
1045
1046 linebuf[REGREPLY_SIZE] = 0;
1047 gottok = 0;
1048 if (linebuf[0] == 'r' &&
1049 linebuf[3] == 'P' &&
1050 linebuf[4] == 'C' &&
1051 linebuf[5] == '=' &&
1052 linebuf[75] == 'H' &&
1053 linebuf[76] == 'M' &&
1054 linebuf[77] == 'S')
1055 {
1056 /*
fa4b55a1
SC
1057 PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
1058 5436789012345678901234567890123456789012345678901234567890123456789012
ec25d19b 1059 0 1 2 3 4 5 6
fa4b55a1 1060 */
ec25d19b
SC
1061 gottok = 1;
1062
1063 reg[PC_REGNUM] = gethex (4, linebuf + 6, &gottok);
1064 reg[CCR_REGNUM] = gethex (2, linebuf + 15, &gottok);
1065 for (i = 0; i < 8; i++)
1066 {
1067 reg[i] = gethex (4, linebuf + 34 + 5 * i, &gottok);
1068 }
1069 }
fa4b55a1 1070 }
fa4b55a1 1071 while (!gottok);
ec25d19b
SC
1072 for (i = 0; i < NUM_REGS; i++)
1073 {
1074 char swapped[2];
fa4b55a1 1075
ec25d19b
SC
1076 swapped[1] = reg[i];
1077 swapped[0] = (reg[i]) >> 8;
fa4b55a1 1078
ec25d19b
SC
1079 supply_register (i, swapped);
1080 }
1081}
edd01519 1082#endif
fa4b55a1
SC
1083/* Store register REGNO, or all if REGNO == -1.
1084 Return errno value. */
ae0ea72e 1085static void
fa4b55a1
SC
1086hms_store_register (regno)
1087 int regno;
1088{
ec25d19b 1089 if (regno == -1)
ae0ea72e 1090 {
ec25d19b
SC
1091 for (regno = 0; regno < NUM_REGS; regno++)
1092 {
1093 hms_store_register (regno);
1094 }
ae0ea72e 1095 }
fa4b55a1 1096 else
ec25d19b
SC
1097 {
1098 char *name = get_reg_name (regno);
1099 char buffer[100];
3b5442f9
SC
1100 /* Some regs dont really exist */
1101 if (!(name[0] == 'p' && name[1] == 'r')
1102 && !(name[0] == 'c' && name[1] == 'y')
1103 && !(name[0] == 't' && name[1] == 'i')
1104 && !(name[0] == 'i' && name[1] == 'n'))
1105 {
1106 sprintf (buffer, "r %s=%x", name, read_register (regno));
1107 hms_write_cr (buffer);
1108 expect_prompt ();
1109 }
edd01519 1110 }
ec25d19b 1111}
ae0ea72e 1112
edd01519 1113
fa4b55a1
SC
1114/* Get ready to modify the registers array. On machines which store
1115 individual registers, this doesn't need to do anything. On machines
1116 which store all the registers in one fell swoop, this makes sure
1117 that registers contains all the registers from the program being
1118 debugged. */
1119
1120void
1121hms_prepare_to_store ()
1122{
1123 /* Do nothing, since we can store individual regs */
1124}
1125
ec25d19b
SC
1126static CORE_ADDR
1127translate_addr (addr)
1128 CORE_ADDR addr;
fa4b55a1
SC
1129{
1130
ec25d19b 1131 return (addr);
fa4b55a1
SC
1132
1133}
1134
1135/* Read a word from remote address ADDR and return it.
1136 * This goes through the data cache.
1137 */
1138int
1139hms_fetch_word (addr)
1140 CORE_ADDR addr;
1141{
ec25d19b 1142 return dcache_fetch (addr);
fa4b55a1
SC
1143}
1144
1145/* Write a word WORD into remote address ADDR.
1146 This goes through the data cache. */
1147
1148void
1149hms_store_word (addr, word)
1150 CORE_ADDR addr;
1151 int word;
1152{
ec25d19b 1153 dcache_poke (addr, word);
fa4b55a1
SC
1154}
1155
1156int
ec25d19b 1157hms_xfer_inferior_memory (memaddr, myaddr, len, write, target)
fa4b55a1
SC
1158 CORE_ADDR memaddr;
1159 char *myaddr;
1160 int len;
1161 int write;
ec25d19b 1162 struct target_ops *target; /* ignored */
fa4b55a1
SC
1163{
1164 register int i;
ec25d19b 1165
fa4b55a1 1166 /* Round starting address down to longword boundary. */
ec25d19b
SC
1167 register CORE_ADDR addr;
1168
fa4b55a1
SC
1169 /* Round ending address up; get number of longwords that makes. */
1170 register int count;
ec25d19b 1171
fa4b55a1 1172 /* Allocate buffer of that many longwords. */
ec25d19b 1173 register int *buffer;
fa4b55a1
SC
1174
1175 memaddr &= 0xffff;
ec25d19b
SC
1176 addr = memaddr & -sizeof (int);
1177 count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
fa4b55a1 1178
ec25d19b 1179 buffer = (int *) alloca (count * sizeof (int));
1f46923f 1180
fa4b55a1 1181 if (write)
ec25d19b
SC
1182 {
1183 /* Fill start and end extra bytes of buffer with existing memory data. */
fa4b55a1 1184
ec25d19b
SC
1185 if (addr != memaddr || len < (int) sizeof (int))
1186 {
1187 /* Need part of initial word -- fetch it. */
1188 buffer[0] = hms_fetch_word (addr);
1189 }
fa4b55a1 1190
ec25d19b
SC
1191 if (count > 1) /* FIXME, avoid if even boundary */
1192 {
1193 buffer[count - 1]
1194 = hms_fetch_word (addr + (count - 1) * sizeof (int));
1195 }
fa4b55a1 1196
ec25d19b 1197 /* Copy data to be written over corresponding part of buffer */
fa4b55a1 1198
ade40d31 1199 memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
fa4b55a1 1200
ec25d19b 1201 /* Write the entire buffer. */
fa4b55a1 1202
ec25d19b
SC
1203 for (i = 0; i < count; i++, addr += sizeof (int))
1204 {
1205 errno = 0;
1206 hms_store_word (addr, buffer[i]);
1207 if (errno)
1208 {
ec25d19b
SC
1209 return 0;
1210 }
1211
1212 }
fa4b55a1 1213 }
fa4b55a1 1214 else
fa4b55a1 1215 {
ec25d19b
SC
1216 /* Read all the longwords */
1217 for (i = 0; i < count; i++, addr += sizeof (int))
1218 {
1219 errno = 0;
1220 buffer[i] = hms_fetch_word (addr);
1221 if (errno)
1222 {
1223 return 0;
1224 }
1225 QUIT;
1226 }
fa4b55a1 1227
ec25d19b 1228 /* Copy appropriate bytes out of the buffer. */
ade40d31 1229 memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
ec25d19b 1230 }
fa4b55a1 1231
fa4b55a1
SC
1232 return len;
1233}
1234
fa4b55a1
SC
1235int
1236hms_write_inferior_memory (memaddr, myaddr, len)
1237 CORE_ADDR memaddr;
ae0ea72e 1238 unsigned char *myaddr;
fa4b55a1
SC
1239 int len;
1240{
ae0ea72e
SC
1241 bfd_vma addr;
1242 int done;
ec25d19b 1243 int todo;
3b5442f9 1244 char buffer[100];
ae0ea72e 1245 done = 0;
3b5442f9
SC
1246 hms_write_cr (".");
1247 expect_prompt ();
ec25d19b 1248 while (done < len)
ae0ea72e 1249 {
3b5442f9 1250 char *ptr = buffer;
ec25d19b
SC
1251 int thisgo;
1252 int idx;
1253
1254 thisgo = len - done;
1255 if (thisgo > 20)
1256 thisgo = 20;
ae0ea72e 1257
3b5442f9
SC
1258 sprintf (ptr, "M.B %4x =", memaddr + done);
1259 ptr += 10;
ec25d19b
SC
1260 for (idx = 0; idx < thisgo; idx++)
1261 {
3b5442f9
SC
1262 sprintf (ptr, "%2x ", myaddr[idx + done]);
1263 ptr += 3;
ec25d19b 1264 }
3b5442f9 1265 hms_write_cr (buffer);
ec25d19b
SC
1266 expect_prompt ();
1267 done += thisgo;
1268 }
fa4b55a1
SC
1269}
1270
1271void
1272hms_files_info ()
1273{
ec25d19b
SC
1274 char *file = "nothing";
1275
1276 if (exec_bfd)
1277 file = bfd_get_filename (exec_bfd);
ae0ea72e 1278
ec25d19b 1279 if (exec_bfd)
ae0ea72e 1280#ifdef __GO32__
ec25d19b 1281 printf_filtered ("\tAttached to DOS asynctsr and running program %s\n", file);
ae0ea72e 1282#else
5905161c 1283 printf_filtered ("\tAttached to %s at %d baud and running program %s\n", dev_name, baudrate, file);
ae0ea72e 1284#endif
ec25d19b 1285 printf_filtered ("\ton an H8/300 processor.\n");
fa4b55a1
SC
1286}
1287
1288/* Copy LEN bytes of data from debugger memory at MYADDR
ec25d19b
SC
1289 to inferior's memory at MEMADDR. Returns errno value.
1290 * sb/sh instructions don't work on unaligned addresses, when TU=1.
fa4b55a1
SC
1291 */
1292
fa4b55a1
SC
1293/* Read LEN bytes from inferior memory at MEMADDR. Put the result
1294 at debugger address MYADDR. Returns errno value. */
1295int
ec25d19b 1296hms_read_inferior_memory (memaddr, myaddr, len)
fa4b55a1
SC
1297 CORE_ADDR memaddr;
1298 char *myaddr;
1299 int len;
1300{
1301 /* Align to nearest low 16 bits */
1302 int i;
ec25d19b 1303
fa4b55a1 1304 CORE_ADDR start = memaddr;
ec25d19b
SC
1305 CORE_ADDR end = memaddr + len - 1;
1306
1307 int ok = 1;
1308
fa4b55a1
SC
1309 /*
1310 AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1311 012345678901234567890123456789012345678901234567890123456789012345
1312 0 1 2 3 4 5 6
1313 */
1314 char buffer[66];
ec25d19b
SC
1315
1316 if (memaddr & 0xf)
1317 abort ();
1318 if (len != 16)
1319 abort ();
1320
1321 sprintf (buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
1322 hms_write_cr (buffer);
fa4b55a1
SC
1323 /* drop the echo and newline*/
1324 for (i = 0; i < 13; i++)
ec25d19b 1325 readchar ();
fa4b55a1 1326
fa4b55a1
SC
1327 /* Grab the lines as they come out and fill the area */
1328 /* Skip over cr */
ec25d19b 1329 while (1)
fa4b55a1 1330 {
ec25d19b
SC
1331 int p;
1332 int i;
1333 int addr;
1334 size_t idx;
fa4b55a1 1335
ec25d19b
SC
1336 char byte[16];
1337
1338 buffer[0] = readchar ();
1339 if (buffer[0] == 'M')
1340 break;
1341 for (i = 1; i < 66; i++)
1342 buffer[i] = readchar ();
1343
1344 /* Now parse the line */
1345
1346 addr = gethex (4, buffer, &ok);
1347 idx = 6;
1348 for (p = 0; p < 16; p += 2)
1349 {
1350 byte[p] = gethex (2, buffer + idx, &ok);
1351 byte[p + 1] = gethex (2, buffer + idx + 2, &ok);
1352 idx += 5;
1353
1354 }
1355
1356 for (p = 0; p < 16; p++)
1357 {
1358 if (addr + p >= memaddr &&
1359 addr + p < memaddr + len)
1360 {
1361 myaddr[(addr + p) - memaddr] = byte[p];
1362
1363 }
1364
1365 }
fa4b55a1 1366 }
3b5442f9
SC
1367#ifdef GDB_TARGET_IS_H8500
1368 expect ("ore>");
edd01519 1369#endif
3b5442f9 1370#ifdef GDB_TARGET_IS_H8300
a493d9a6 1371 expect ("emory>");
edd01519 1372#endif
3b5442f9
SC
1373 hms_write_cr (".");
1374
ec25d19b 1375 expect_prompt ();
fa4b55a1 1376 return len;
fa4b55a1
SC
1377}
1378
edd01519 1379
fa4b55a1 1380
fa4b55a1 1381#define MAX_BREAKS 16
ec25d19b 1382static int num_brkpts = 0;
fa4b55a1 1383static int
ec25d19b
SC
1384hms_insert_breakpoint (addr, save)
1385 CORE_ADDR addr;
1386 char *save; /* Throw away, let hms save instructions */
fa4b55a1 1387{
ec25d19b
SC
1388 check_open ();
1389
1390 if (num_brkpts < MAX_BREAKS)
1391 {
1392 char buffer[100];
fa4b55a1 1393
ec25d19b
SC
1394 num_brkpts++;
1395 sprintf (buffer, "b %x", addr & 0xffff);
1396 hms_write_cr (buffer);
1397 expect_prompt ();
1398 return (0);
1399 }
1400 else
1401 {
199b2450 1402 fprintf_filtered (gdb_stderr,
ec25d19b
SC
1403 "Too many break points, break point not installed\n");
1404 return (1);
1405 }
fa4b55a1
SC
1406
1407}
1408static int
ec25d19b
SC
1409hms_remove_breakpoint (addr, save)
1410 CORE_ADDR addr;
1411 char *save; /* Throw away, let hms save instructions */
fa4b55a1 1412{
ec25d19b
SC
1413 if (num_brkpts > 0)
1414 {
1415 char buffer[100];
1416
1417 num_brkpts--;
1418 sprintf (buffer, "b - %x", addr & 0xffff);
1419 hms_write_cr (buffer);
1420 expect_prompt ();
1421
1422 }
1423 return (0);
fa4b55a1
SC
1424}
1425
1426/* Clear the hmss notion of what the break points are */
1427static int
ec25d19b
SC
1428hms_clear_breakpoints ()
1429{
fa4b55a1 1430
ec25d19b
SC
1431 if (is_open)
1432 {
1433 hms_write_cr ("b -");
1434 expect_prompt ();
1435 }
fa4b55a1 1436 num_brkpts = 0;
fa4b55a1
SC
1437}
1438static void
ec25d19b
SC
1439hms_mourn ()
1440{
1441 hms_clear_breakpoints ();
71607f9d 1442 unpush_target (&hms_ops);
fa4b55a1 1443 generic_mourn_inferior ();
fa4b55a1
SC
1444}
1445
fa4b55a1 1446/* Put a command string, in args, out to the hms. The hms is assumed to
ae0ea72e 1447 be in raw mode, all writing/reading done through desc.
fa4b55a1
SC
1448 Ouput from the hms is placed on the users terminal until the
1449 prompt from the hms is seen.
1450 FIXME: Can't handle commands that take input. */
1451
1452void
1453hms_com (args, fromtty)
ec25d19b
SC
1454 char *args;
1455 int fromtty;
fa4b55a1 1456{
ec25d19b
SC
1457 check_open ();
1458
1459 if (!args)
1460 return;
1461
fa4b55a1
SC
1462 /* Clear all input so only command relative output is displayed */
1463
ec25d19b 1464 hms_write_cr (args);
3b5442f9 1465/* hms_write ("\030", 1);*/
ec25d19b 1466 expect_prompt ();
fa4b55a1
SC
1467}
1468
1469/* Define the target subroutine names */
1470
ec25d19b
SC
1471struct target_ops hms_ops =
1472{
1473 "hms", "Remote HMS monitor",
1474 "Use the H8 evaluation board running the HMS monitor connected\n\
fa4b55a1
SC
1475by a serial line.",
1476
ec25d19b
SC
1477 hms_open, hms_close,
1478 0, hms_detach, hms_resume, hms_wait, /* attach */
1479 hms_fetch_register, hms_store_register,
1480 hms_prepare_to_store,
1481 hms_xfer_inferior_memory,
1482 hms_files_info,
1483 hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1484 0, 0, 0, 0, 0, /* Terminal handling */
1485 hms_kill, /* FIXME, kill */
1486 hms_load,
1487 0, /* lookup_symbol */
1488 hms_create_inferior, /* create_inferior */
1489 hms_mourn, /* mourn_inferior FIXME */
1490 0, /* can_run */
1491 0, /* notice_signals */
1492 process_stratum, 0, /* next */
1493 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1494 0, 0, /* Section pointers */
1495 OPS_MAGIC, /* Always the last thing */
fa4b55a1
SC
1496};
1497
ec25d19b 1498hms_quiet ()
fa4b55a1 1499{
ec25d19b
SC
1500 quiet = !quiet;
1501 if (quiet)
1502 printf_filtered ("Snoop disabled\n");
1503 else
1504 printf_filtered ("Snoop enabled\n");
ae0ea72e 1505
fa4b55a1
SC
1506}
1507
ec25d19b
SC
1508hms_device (s)
1509 char *s;
fa4b55a1 1510{
ec25d19b
SC
1511 if (s)
1512 {
1513 dev_name = get_word (&s);
1514 }
fa4b55a1
SC
1515}
1516
ec25d19b
SC
1517static
1518hms_speed (s)
1519 char *s;
fa4b55a1 1520{
ec25d19b
SC
1521 check_open ();
1522
1523 if (s)
1524 {
1525 char buffer[100];
1526 int newrate = atoi (s);
1527 int which = 0;
1528
a493d9a6 1529 if (SERIAL_SETBAUDRATE (desc, newrate))
ec25d19b
SC
1530 error ("Can't use %d baud\n", newrate);
1531
1532 printf_filtered ("Checking target is in sync\n");
1533
ec25d19b
SC
1534 printf_filtered ("Sending commands to set target to %d\n",
1535 baudrate);
1536
1537 sprintf (buffer, "tm %d. N 8 1", baudrate);
1538 hms_write_cr (buffer);
1539 }
fa4b55a1
SC
1540}
1541
1542/***********************************************************************/
1543
3b5442f9
SC
1544static void
1545hms_drain (args, fromtty)
1546 char *args;
1547 int fromtty;
1548
1549{
1550 int c;
1551 while (1)
1552 {
1553 c = SERIAL_READCHAR (desc, 1);
1554 if (c == SERIAL_TIMEOUT)
1555 break;
1556 if (c == SERIAL_ERROR)
1557 break;
1558 if (c > ' ' && c < 127)
1559 printf ("%c", c & 0xff);
1560 else
1561 printf ("<%x>", c & 0xff);
1562 }
1563}
1564
1565static void
1566add_commands ()
1567{
1568
1569 add_com ("hmsdrain", class_obscure, hms_drain,
1570 "Drain pending hms text buffers.");
1571}
1572
1573static void
1574remove_commands ()
1575{
1576 extern struct cmd_list_element *cmdlist;
1577 delete_cmd ("hms-drain", &cmdlist);
1578}
1579
fa4b55a1
SC
1580void
1581_initialize_remote_hms ()
1582{
1583 add_target (&hms_ops);
ec25d19b 1584
fa4b55a1 1585 add_com ("hms <command>", class_obscure, hms_com,
ec25d19b 1586 "Send a command to the HMS monitor.");
fa4b55a1
SC
1587 add_com ("snoop", class_obscure, hms_quiet,
1588 "Show what commands are going to the monitor");
ae0ea72e 1589
fa4b55a1
SC
1590 add_com ("device", class_obscure, hms_device,
1591 "Set the terminal line for HMS communications");
1592
1593 add_com ("speed", class_obscure, hms_speed,
1594 "Set the terminal line speed for HMS communications");
ec25d19b 1595
3ec5a74b 1596 dev_name = NULL;
fa4b55a1 1597}
This page took 0.228354 seconds and 4 git commands to generate.