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