-hms_resume (step, sig)
- int step, sig;
-{
- dcache_flush ();
-
- if (step)
- {
- hms_write_cr ("s");
- expect ("Step>");
-
- /* Force the next hms_wait to return a trap. Not doing anything
- about I/O from the target means that the user has to type
- "continue" to see any. FIXME, this should be fixed. */
- need_artificial_trap = 1;
- }
- else
- {
- hms_write_cr ("g");
- expect ("g");
- }
-}
-
-/* Wait until the remote machine stops, then return,
- storing status in STATUS just as `wait' would. */
-
-int
-hms_wait (status)
- WAITTYPE *status;
-{
- /* Strings to look for. '?' means match any single character.
- Note that with the algorithm we use, the initial character
- of the string cannot recur in the string, or we will not
- find some cases of the string in the input. */
-
- static char bpt[] = "At breakpoint:";
-
- /* It would be tempting to look for "\n[__exit + 0x8]\n"
- but that requires loading symbols with "yc i" and even if
- we did do that we don't know that the file has symbols. */
- static char exitmsg[] = "HMS>";
- char *bp = bpt;
- char *ep = exitmsg;
-
- /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
- char swallowed[50];
-
- /* Current position in swallowed. */
- char *swallowed_p = swallowed;
-
- int ch;
- int ch_handled;
- int old_timeout = timeout;
- int old_immediate_quit = immediate_quit;
- int swallowed_cr = 0;
-
- WSETEXIT ((*status), 0);
-
- if (need_artificial_trap != 0)
- {
- WSETSTOP ((*status), SIGTRAP);
- need_artificial_trap--;
- return 0;
- }
-
- timeout = 99999; /* Don't time out -- user program is running. */
- immediate_quit = 1; /* Helps ability to QUIT */
- while (1)
- {
- QUIT; /* Let user quit and leave process running */
- ch_handled = 0;
- ch = readchar ();
- if (ch == *bp)
- {
- bp++;
- if (*bp == '\0')
- break;
- ch_handled = 1;
-
- *swallowed_p++ = ch;
- }
- else
- {
- bp = bpt;
- }
- if (ch == *ep || *ep == '?')
- {
- ep++;
- if (*ep == '\0')
- break;
-
- if (!ch_handled)
- *swallowed_p++ = ch;
- ch_handled = 1;
- }
- else
- {
- ep = exitmsg;
- }
-
- if (!ch_handled)
- {
- char *p;
-
- /* Print out any characters which have been swallowed. */
- for (p = swallowed; p < swallowed_p; ++p)
- putc (*p, stdout);
- swallowed_p = swallowed;
-
- if ((ch != '\r' && ch != '\n') || swallowed_cr > 10)
- {
- putc (ch, stdout);
- swallowed_cr = 10;
- }
- swallowed_cr++;
-
- }
- }
- if (*bp == '\0')
- {
- WSETSTOP ((*status), SIGTRAP);
- expect_prompt ();
- }
- else
- {
- WSETEXIT ((*status), 0);
- }
-
- timeout = old_timeout;
- immediate_quit = old_immediate_quit;
- return 0;
-}
-
-/* Return the name of register number REGNO
- in the form input and output by hms.
-
- Returns a pointer to a static buffer containing the answer. */
-static char *
-get_reg_name (regno)
- int regno;
-{
- static char *rn[] = REGISTER_NAMES;
-
- return rn[regno];
-}
-
-/* Read the remote registers. */
-static int
-gethex (length, start, ok)
- unsigned int length;
- char *start;
- int *ok;
-{
- int result = 0;
-
- while (length--)
- {
- result <<= 4;
- if (*start >= 'a' && *start <= 'f')
- {
- result += *start - 'a' + 10;
- }
- else if (*start >= 'A' && *start <= 'F')
- {
- result += *start - 'A' + 10;
- }
- else if (*start >= '0' && *start <= '9')
- {
- result += *start - '0';
- }
- else
- *ok = 0;
- start++;
-
- }
- return result;
-}
-static int
-timed_read (buf, n, timeout)
- char *buf;
-
-{
- int i;
- char c;
-
- i = 0;
- while (i < n)
- {
- c = readchar ();
-
- if (c == 0)
- return i;
- buf[i] = c;
- i++;
-
- }
- return i;
-}
-
-hms_write (a, l)
- char *a;
-{
- int i;
-
- SERIAL_WRITE (desc, a, l);
-
- if (!quiet)
- for (i = 0; i < l; i++)
- {
- printf ("%c", a[i]);
- }
-}
-
-hms_write_cr (s)
- char *s;
-{
- hms_write (s, strlen (s));
- hms_write ("\r", 1);
-}
-
-static void
-hms_fetch_register (dummy)
- int dummy;
-{
-#define REGREPLY_SIZE 79
- char linebuf[REGREPLY_SIZE + 1];
- int i;
- int s;
- int gottok;
-
- REGISTER_TYPE reg[NUM_REGS];
- int foo[8];
-
- check_open ();
-
- do
- {
-
- hms_write_cr ("r");
- s = timed_read (linebuf, REGREPLY_SIZE, 1);
-
- linebuf[REGREPLY_SIZE] = 0;
- gottok = 0;
- if (linebuf[0] == 'r' &&
- linebuf[3] == 'P' &&
- linebuf[4] == 'C' &&
- linebuf[5] == '=' &&
- linebuf[75] == 'H' &&
- linebuf[76] == 'M' &&
- linebuf[77] == 'S')
- {
- /*
- PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
- 5436789012345678901234567890123456789012345678901234567890123456789012
- 0 1 2 3 4 5 6
- */
- gottok = 1;
-
- reg[PC_REGNUM] = gethex (4, linebuf + 6, &gottok);
- reg[CCR_REGNUM] = gethex (2, linebuf + 15, &gottok);
- for (i = 0; i < 8; i++)
- {
- reg[i] = gethex (4, linebuf + 34 + 5 * i, &gottok);
- }
- }
- }
- while (!gottok);
- for (i = 0; i < NUM_REGS; i++)
- {
- char swapped[2];
-
- swapped[1] = reg[i];
- swapped[0] = (reg[i]) >> 8;
-
- supply_register (i, swapped);
- }
-}
-
-/* Store register REGNO, or all if REGNO == -1.
- Return errno value. */
-static void
-hms_store_register (regno)
- int regno;
-{
- if (regno == -1)
- {
- for (regno = 0; regno < NUM_REGS; regno++)
- {
- hms_store_register (regno);
- }
- }
- else
- {
- char *name = get_reg_name (regno);
- char buffer[100];
-
- sprintf (buffer, "r %s=%x", name, read_register (regno));
- hms_write_cr (buffer);
- expect_prompt ();
- }
-}
-
-/* Get ready to modify the registers array. On machines which store
- individual registers, this doesn't need to do anything. On machines
- which store all the registers in one fell swoop, this makes sure
- that registers contains all the registers from the program being
- debugged. */
-
-void
-hms_prepare_to_store ()
-{
- /* Do nothing, since we can store individual regs */
-}
-
-static CORE_ADDR
-translate_addr (addr)
- CORE_ADDR addr;
-{
-
- return (addr);
-
-}
-
-/* Read a word from remote address ADDR and return it.
- * This goes through the data cache.
- */
-int
-hms_fetch_word (addr)
- CORE_ADDR addr;
-{
- return dcache_fetch (addr);
-}
-
-/* Write a word WORD into remote address ADDR.
- This goes through the data cache. */
-
-void
-hms_store_word (addr, word)
- CORE_ADDR addr;
- int word;
-{
- dcache_poke (addr, word);
-}
-
-int
-hms_xfer_inferior_memory (memaddr, myaddr, len, write, target)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
- int write;
- struct target_ops *target; /* ignored */
-{
- register int i;
-
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr;
-
- /* Round ending address up; get number of longwords that makes. */
- register int count;
-
- /* Allocate buffer of that many longwords. */
- register int *buffer;
-
- memaddr &= 0xffff;
- addr = memaddr & -sizeof (int);
- count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
-
- buffer = (int *) alloca (count * sizeof (int));
-
- if (write)
- {
- /* Fill start and end extra bytes of buffer with existing memory data. */
-
- if (addr != memaddr || len < (int) sizeof (int))
- {
- /* Need part of initial word -- fetch it. */
- buffer[0] = hms_fetch_word (addr);
- }
-
- if (count > 1) /* FIXME, avoid if even boundary */
- {
- buffer[count - 1]
- = hms_fetch_word (addr + (count - 1) * sizeof (int));
- }
-
- /* Copy data to be written over corresponding part of buffer */
-
- bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
-
- /* Write the entire buffer. */
-
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- hms_store_word (addr, buffer[i]);
- if (errno)
- {
-
- return 0;
- }
-
- }
- }
- else
- {
- /* Read all the longwords */
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- buffer[i] = hms_fetch_word (addr);
- if (errno)
- {
- return 0;
- }
- QUIT;
- }
-
- /* Copy appropriate bytes out of the buffer. */
- bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
- }
-
- return len;
-}
-
-int
-hms_write_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- unsigned char *myaddr;
- int len;
-{
- bfd_vma addr;
- int done;
- int todo;
-
- done = 0;
- while (done < len)
- {
- char buffer[20];
- int thisgo;
- int idx;
-
- thisgo = len - done;
- if (thisgo > 20)
- thisgo = 20;
-
- sprintf (buffer, "M.B %4x =", memaddr + done);
- hms_write (buffer, 10);
- for (idx = 0; idx < thisgo; idx++)
- {
- char buf[20];
-
- sprintf (buf, "%2x ", myaddr[idx + done]);
- hms_write (buf, 3);
- }
- hms_write_cr ("");
- expect_prompt ();
- done += thisgo;
- }
-
-}
-
-void
-hms_files_info ()
-{
- char *file = "nothing";
-
- if (exec_bfd)
- file = bfd_get_filename (exec_bfd);
-
- if (exec_bfd)
-#ifdef __GO32__
- printf_filtered ("\tAttached to DOS asynctsr and running program %s\n", file);
-#else
- printf_filtered ("\tAttached to %s at %d baud and running program %s\n", file);
-#endif
- printf_filtered ("\ton an H8/300 processor.\n");
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
- to inferior's memory at MEMADDR. Returns errno value.
- * sb/sh instructions don't work on unaligned addresses, when TU=1.
- */
-
-/* Read LEN bytes from inferior memory at MEMADDR. Put the result
- at debugger address MYADDR. Returns errno value. */
-int
-hms_read_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- /* Align to nearest low 16 bits */
- int i;
-
-#if 0
- CORE_ADDR start = memaddr & ~0xf;
- CORE_ADDR end = ((memaddr + len + 16) & ~0xf) - 1;
-
-#endif
- CORE_ADDR start = memaddr;
- CORE_ADDR end = memaddr + len - 1;
-
- int ok = 1;
-
- /*
- AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
- 012345678901234567890123456789012345678901234567890123456789012345
- 0 1 2 3 4 5 6
- */
- char buffer[66];
-
- if (memaddr & 0xf)
- abort ();
- if (len != 16)
- abort ();
-
- sprintf (buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
- hms_write_cr (buffer);
- /* drop the echo and newline*/
- for (i = 0; i < 13; i++)
- readchar ();
-
- /* Grab the lines as they come out and fill the area */
- /* Skip over cr */
- while (1)
- {
- int p;
- int i;
- int addr;
- size_t idx;
-
- char byte[16];
-
- buffer[0] = readchar ();
- if (buffer[0] == 'M')
- break;
- for (i = 1; i < 66; i++)
- buffer[i] = readchar ();
-
- /* Now parse the line */
-
- addr = gethex (4, buffer, &ok);
- idx = 6;
- for (p = 0; p < 16; p += 2)
- {
- byte[p] = gethex (2, buffer + idx, &ok);
- byte[p + 1] = gethex (2, buffer + idx + 2, &ok);
- idx += 5;
-
- }
-
- for (p = 0; p < 16; p++)
- {
- if (addr + p >= memaddr &&
- addr + p < memaddr + len)
- {
- myaddr[(addr + p) - memaddr] = byte[p];
-
- }
-
- }
- }
- expect ("emory>");
- hms_write_cr (" ");
- expect_prompt ();
- return len;
-}
-
-/* This routine is run as a hook, just before the main command loop is
- entered. If gdb is configured for the H8, but has not had its
- target specified yet, this will loop prompting the user to do so.
-*/
-
-hms_before_main_loop ()
-{
- char ttyname[100];
- char *p, *p2;
- extern FILE *instream;
-
- push_target (&hms_ops);
-}
-
-#define MAX_BREAKS 16
-static int num_brkpts = 0;
-static int
-hms_insert_breakpoint (addr, save)
- CORE_ADDR addr;
- char *save; /* Throw away, let hms save instructions */
-{
- check_open ();
-
- if (num_brkpts < MAX_BREAKS)
- {
- char buffer[100];
-
- num_brkpts++;
- sprintf (buffer, "b %x", addr & 0xffff);
- hms_write_cr (buffer);
- expect_prompt ();
- return (0);
- }
- else
- {
- fprintf_filtered (stderr,
- "Too many break points, break point not installed\n");
- return (1);
- }
-
-}
-static int
-hms_remove_breakpoint (addr, save)
- CORE_ADDR addr;
- char *save; /* Throw away, let hms save instructions */
-{
- if (num_brkpts > 0)
- {
- char buffer[100];
-
- num_brkpts--;
- sprintf (buffer, "b - %x", addr & 0xffff);
- hms_write_cr (buffer);
- expect_prompt ();
-
- }
- return (0);
-}
-
-/* Clear the hmss notion of what the break points are */
-static int
-hms_clear_breakpoints ()
-{
-
- if (is_open)
- {
- hms_write_cr ("b -");
- expect_prompt ();
- }
- num_brkpts = 0;
-}
-static void
-hms_mourn ()
-{
- hms_clear_breakpoints ();
- unpush_target (&hms_ops);
- generic_mourn_inferior ();
-}
-
-/* Put a command string, in args, out to the hms. The hms is assumed to
- be in raw mode, all writing/reading done through desc.
- Ouput from the hms is placed on the users terminal until the
- prompt from the hms is seen.
- FIXME: Can't handle commands that take input. */
-
-void
-hms_com (args, fromtty)
- char *args;
- int fromtty;
-{
- check_open ();
-
- if (!args)
- return;
-
- /* Clear all input so only command relative output is displayed */
-
- hms_write_cr (args);
- hms_write ("\030", 1);
- expect_prompt ();
-}
-
-/* Define the target subroutine names */
-
-struct target_ops hms_ops =
-{
- "hms", "Remote HMS monitor",
- "Use the H8 evaluation board running the HMS monitor connected\n\
-by a serial line.",
-
- hms_open, hms_close,
- 0, hms_detach, hms_resume, hms_wait, /* attach */
- hms_fetch_register, hms_store_register,
- hms_prepare_to_store,
- hms_xfer_inferior_memory,
- hms_files_info,
- hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
- 0, 0, 0, 0, 0, /* Terminal handling */
- hms_kill, /* FIXME, kill */
- hms_load,
- 0, /* lookup_symbol */
- hms_create_inferior, /* create_inferior */
- hms_mourn, /* mourn_inferior FIXME */
- 0, /* can_run */
- 0, /* notice_signals */
- process_stratum, 0, /* next */
- 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
- 0, 0, /* Section pointers */
- OPS_MAGIC, /* Always the last thing */
-};
-
-hms_quiet ()
-{
- quiet = !quiet;
- if (quiet)
- printf_filtered ("Snoop disabled\n");
- else
- printf_filtered ("Snoop enabled\n");
-
-}
-
-hms_device (s)
- char *s;
-{
- if (s)
- {
- dev_name = get_word (&s);
- }
-}
-
-static
-hms_speed (s)
- char *s;
-{
- check_open ();
-
- if (s)
- {
- char buffer[100];
- int newrate = atoi (s);
- int which = 0;
-
- if (SERIAL_SETBAUDRATE (desc, newrate))
- error ("Can't use %d baud\n", newrate);
-
- printf_filtered ("Checking target is in sync\n");
-
- printf_filtered ("Sending commands to set target to %d\n",
- baudrate);
-
- sprintf (buffer, "tm %d. N 8 1", baudrate);
- hms_write_cr (buffer);
- }
-}
-
-/***********************************************************************/
-
-void
-_initialize_remote_hms ()
-{