gdb/
authorTristan Gingold <gingold@adacore.com>
Thu, 8 Mar 2012 14:43:24 +0000 (14:43 +0000)
committerTristan Gingold <gingold@adacore.com>
Thu, 8 Mar 2012 14:43:24 +0000 (14:43 +0000)
2012-03-08  Tristan Gingold  <gingold@adacore.com>

* sparc-stub.c: Move to stubs/
* sh-stub.c: Likewise.
* m68k-stub.c: Likewise.
* m32r-stub.c: Likewise.
* i386-stub.c: Likewise.

gdb/stubs/
2012-03-08  Tristan Gingold  <gingold@adacore.com>

* sparc-stub.c: Move from ..
* sh-stub.c: Likewise.
* m68k-stub.c: Likewise.
* m32r-stub.c: Likewise.
* i386-stub.c: Likewise.

12 files changed:
gdb/ChangeLog
gdb/i386-stub.c [deleted file]
gdb/m32r-stub.c [deleted file]
gdb/m68k-stub.c [deleted file]
gdb/sh-stub.c [deleted file]
gdb/sparc-stub.c [deleted file]
gdb/stubs/ChangeLog
gdb/stubs/i386-stub.c [new file with mode: 0644]
gdb/stubs/m32r-stub.c [new file with mode: 0644]
gdb/stubs/m68k-stub.c [new file with mode: 0644]
gdb/stubs/sh-stub.c [new file with mode: 0644]
gdb/stubs/sparc-stub.c [new file with mode: 0644]

index 711b8d2fd7f448f470933d72bfa2353c6ca0f5c5..0964c5fcdc8a415275180f15a00e4928751868d7 100644 (file)
@@ -1,3 +1,11 @@
+2012-03-08  Tristan Gingold  <gingold@adacore.com>
+
+       * sparc-stub.c: Move to stubs/
+       * sh-stub.c: Likewise.
+       * m68k-stub.c: Likewise.
+       * m32r-stub.c: Likewise.
+       * i386-stub.c: Likewise.
+
 2012-03-08  Andreas Schwab  <schwab@linux-m68k.org>
 
        * m68klinux-tdep.c (m68k_linux_init_abi): Register
diff --git a/gdb/i386-stub.c b/gdb/i386-stub.c
deleted file mode 100644 (file)
index 04996b7..0000000
+++ /dev/null
@@ -1,952 +0,0 @@
-/****************************************************************************
-
-               THIS SOFTWARE IS NOT COPYRIGHTED
-
-   HP offers the following for use in the public domain.  HP makes no
-   warranty with regard to the software or it's performance and the
-   user accepts the software "AS IS" with all faults.
-
-   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
-   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-/****************************************************************************
- *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
- *
- *  Module name: remcom.c $
- *  Revision: 1.34 $
- *  Date: 91/03/09 12:29:49 $
- *  Contributor:     Lake Stevens Instrument Division$
- *
- *  Description:     low level support for gdb debugger. $
- *
- *  Considerations:  only works on target hardware $
- *
- *  Written by:      Glenn Engel $
- *  ModuleState:     Experimental $
- *
- *  NOTES:           See Below $
- *
- *  Modified for 386 by Jim Kingdon, Cygnus Support.
- *
- *  To enable debugger support, two things need to happen.  One, a
- *  call to set_debug_traps() is necessary in order to allow any breakpoints
- *  or error conditions to be properly intercepted and reported to gdb.
- *  Two, a breakpoint needs to be generated to begin communication.  This
- *  is most easily accomplished by a call to breakpoint().  Breakpoint()
- *  simulates a breakpoint by executing a trap #1.
- *
- *  The external function exceptionHandler() is
- *  used to attach a specific handler to a specific 386 vector number.
- *  It should use the same privilege level it runs at.  It should
- *  install it as an interrupt gate so that interrupts are masked
- *  while the handler runs.
- *
- *  Because gdb will sometimes write to the stack area to execute function
- *  calls, this program cannot rely on using the supervisor stack so it
- *  uses it's own stack area reserved in the int array remcomStack.
- *
- *************
- *
- *    The following gdb commands are supported:
- *
- * command          function                               Return value
- *
- *    g             return the value of the CPU registers  hex data or ENN
- *    G             set the value of the CPU registers     OK or ENN
- *
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
- *
- *    c             Resume at current address              SNN   ( signal NN)
- *    cAA..AA       Continue at address AA..AA             SNN
- *
- *    s             Step one instruction                   SNN
- *    sAA..AA       Step one instruction from AA..AA       SNN
- *
- *    k             kill
- *
- *    ?             What was the last sigval ?             SNN   (signal NN)
- *
- * All commands and responses are sent with a packet which includes a
- * checksum.  A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer.  '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host:                  Reply:
- * $m0,10#2a               +$00010203040506070809101112131415#42
- *
- ****************************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-
-/************************************************************************
- *
- * external low-level support routines
- */
-
-extern void putDebugChar();    /* write a single character      */
-extern int getDebugChar();     /* read and return a single char */
-extern void exceptionHandler();        /* assign an exception handler   */
-
-/************************************************************************/
-/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-/* at least NUMREGBYTES*2 are needed for register packets */
-#define BUFMAX 400
-
-static char initialized;  /* boolean flag. != 0 means we've been initialized */
-
-int     remote_debug;
-/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
-
-static const char hexchars[]="0123456789abcdef";
-
-/* Number of registers.  */
-#define NUMREGS        16
-
-/* Number of bytes of registers.  */
-#define NUMREGBYTES (NUMREGS * 4)
-
-enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
-              PC /* also known as eip */,
-              PS /* also known as eflags */,
-              CS, SS, DS, ES, FS, GS};
-
-/*
- * these should not be static cuz they can be used outside this module
- */
-int registers[NUMREGS];
-
-#define STACKSIZE 10000
-int remcomStack[STACKSIZE/sizeof(int)];
-static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
-
-/***************************  ASSEMBLY CODE MACROS *************************/
-/*                                                                        */
-
-extern void
-return_to_prog ();
-
-/* Restore the program's registers (including the stack pointer, which
-   means we get the right stack and don't have to worry about popping our
-   return address and any stack frames and so on) and return.  */
-asm(".text");
-asm(".globl _return_to_prog");
-asm("_return_to_prog:");
-asm("        movw _registers+44, %ss");
-asm("        movl _registers+16, %esp");
-asm("        movl _registers+4, %ecx");
-asm("        movl _registers+8, %edx");
-asm("        movl _registers+12, %ebx");
-asm("        movl _registers+20, %ebp");
-asm("        movl _registers+24, %esi");
-asm("        movl _registers+28, %edi");
-asm("        movw _registers+48, %ds");
-asm("        movw _registers+52, %es");
-asm("        movw _registers+56, %fs");
-asm("        movw _registers+60, %gs");
-asm("        movl _registers+36, %eax");
-asm("        pushl %eax");  /* saved eflags */
-asm("        movl _registers+40, %eax");
-asm("        pushl %eax");  /* saved cs */
-asm("        movl _registers+32, %eax");
-asm("        pushl %eax");  /* saved eip */
-asm("        movl _registers, %eax");
-/* use iret to restore pc and flags together so
-   that trace flag works right.  */
-asm("        iret");
-
-#define BREAKPOINT() asm("   int $3");
-
-/* Put the error code here just in case the user cares.  */
-int gdb_i386errcode;
-/* Likewise, the vector number here (since GDB only gets the signal
-   number through the usual means, and that's not very specific).  */
-int gdb_i386vector = -1;
-
-/* GDB stores segment registers in 32-bit words (that's just the way
-   m-i386v.h is written).  So zero the appropriate areas in registers.  */
-#define SAVE_REGISTERS1() \
-  asm ("movl %eax, _registers");                                         \
-  asm ("movl %ecx, _registers+4");                                          \
-  asm ("movl %edx, _registers+8");                                          \
-  asm ("movl %ebx, _registers+12");                                         \
-  asm ("movl %ebp, _registers+20");                                         \
-  asm ("movl %esi, _registers+24");                                         \
-  asm ("movl %edi, _registers+28");                                         \
-  asm ("movw $0, %ax");                                                             \
-  asm ("movw %ds, _registers+48");                                          \
-  asm ("movw %ax, _registers+50");                                          \
-  asm ("movw %es, _registers+52");                                          \
-  asm ("movw %ax, _registers+54");                                          \
-  asm ("movw %fs, _registers+56");                                          \
-  asm ("movw %ax, _registers+58");                                          \
-  asm ("movw %gs, _registers+60");                                          \
-  asm ("movw %ax, _registers+62");
-#define SAVE_ERRCODE() \
-  asm ("popl %ebx");                                  \
-  asm ("movl %ebx, _gdb_i386errcode");
-#define SAVE_REGISTERS2() \
-  asm ("popl %ebx"); /* old eip */                                          \
-  asm ("movl %ebx, _registers+32");                                         \
-  asm ("popl %ebx");    /* old cs */                                        \
-  asm ("movl %ebx, _registers+40");                                         \
-  asm ("movw %ax, _registers+42");                                           \
-  asm ("popl %ebx");    /* old eflags */                                    \
-  asm ("movl %ebx, _registers+36");                                         \
-  /* Now that we've done the pops, we can save the stack pointer.");  */   \
-  asm ("movw %ss, _registers+44");                                          \
-  asm ("movw %ax, _registers+46");                                                  \
-  asm ("movl %esp, _registers+16");
-
-/* See if mem_fault_routine is set, if so just IRET to that address.  */
-#define CHECK_FAULT() \
-  asm ("cmpl $0, _mem_fault_routine");                                    \
-  asm ("jne mem_fault");
-
-asm (".text");
-asm ("mem_fault:");
-/* OK to clobber temp registers; we're just going to end up in set_mem_err.  */
-/* Pop error code from the stack and save it.  */
-asm ("     popl %eax");
-asm ("     movl %eax, _gdb_i386errcode");
-
-asm ("     popl %eax"); /* eip */
-/* We don't want to return there, we want to return to the function
-   pointed to by mem_fault_routine instead.  */
-asm ("     movl _mem_fault_routine, %eax");
-asm ("     popl %ecx"); /* cs (low 16 bits; junk in hi 16 bits).  */
-asm ("     popl %edx"); /* eflags */
-
-/* Remove this stack frame; when we do the iret, we will be going to
-   the start of a function, so we want the stack to look just like it
-   would after a "call" instruction.  */
-asm ("     leave");
-
-/* Push the stuff that iret wants.  */
-asm ("     pushl %edx"); /* eflags */
-asm ("     pushl %ecx"); /* cs */
-asm ("     pushl %eax"); /* eip */
-
-/* Zero mem_fault_routine.  */
-asm ("     movl $0, %eax");
-asm ("     movl %eax, _mem_fault_routine");
-
-asm ("iret");
-
-#define CALL_HOOK() asm("call _remcomHandler");
-
-/* This function is called when a i386 exception occurs.  It saves
- * all the cpu regs in the _registers array, munges the stack a bit,
- * and invokes an exception handler (remcom_handler).
- *
- * stack on entry:                       stack on exit:
- *   old eflags                          vector number
- *   old cs (zero-filled to 32 bits)
- *   old eip
- *
- */
-extern void _catchException3();
-asm(".text");
-asm(".globl __catchException3");
-asm("__catchException3:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $3");
-CALL_HOOK();
-
-/* Same thing for exception 1.  */
-extern void _catchException1();
-asm(".text");
-asm(".globl __catchException1");
-asm("__catchException1:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $1");
-CALL_HOOK();
-
-/* Same thing for exception 0.  */
-extern void _catchException0();
-asm(".text");
-asm(".globl __catchException0");
-asm("__catchException0:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $0");
-CALL_HOOK();
-
-/* Same thing for exception 4.  */
-extern void _catchException4();
-asm(".text");
-asm(".globl __catchException4");
-asm("__catchException4:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $4");
-CALL_HOOK();
-
-/* Same thing for exception 5.  */
-extern void _catchException5();
-asm(".text");
-asm(".globl __catchException5");
-asm("__catchException5:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $5");
-CALL_HOOK();
-
-/* Same thing for exception 6.  */
-extern void _catchException6();
-asm(".text");
-asm(".globl __catchException6");
-asm("__catchException6:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $6");
-CALL_HOOK();
-
-/* Same thing for exception 7.  */
-extern void _catchException7();
-asm(".text");
-asm(".globl __catchException7");
-asm("__catchException7:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $7");
-CALL_HOOK();
-
-/* Same thing for exception 8.  */
-extern void _catchException8();
-asm(".text");
-asm(".globl __catchException8");
-asm("__catchException8:");
-SAVE_REGISTERS1();
-SAVE_ERRCODE();
-SAVE_REGISTERS2();
-asm ("pushl $8");
-CALL_HOOK();
-
-/* Same thing for exception 9.  */
-extern void _catchException9();
-asm(".text");
-asm(".globl __catchException9");
-asm("__catchException9:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $9");
-CALL_HOOK();
-
-/* Same thing for exception 10.  */
-extern void _catchException10();
-asm(".text");
-asm(".globl __catchException10");
-asm("__catchException10:");
-SAVE_REGISTERS1();
-SAVE_ERRCODE();
-SAVE_REGISTERS2();
-asm ("pushl $10");
-CALL_HOOK();
-
-/* Same thing for exception 12.  */
-extern void _catchException12();
-asm(".text");
-asm(".globl __catchException12");
-asm("__catchException12:");
-SAVE_REGISTERS1();
-SAVE_ERRCODE();
-SAVE_REGISTERS2();
-asm ("pushl $12");
-CALL_HOOK();
-
-/* Same thing for exception 16.  */
-extern void _catchException16();
-asm(".text");
-asm(".globl __catchException16");
-asm("__catchException16:");
-SAVE_REGISTERS1();
-SAVE_REGISTERS2();
-asm ("pushl $16");
-CALL_HOOK();
-
-/* For 13, 11, and 14 we have to deal with the CHECK_FAULT stuff.  */
-
-/* Same thing for exception 13.  */
-extern void _catchException13 ();
-asm (".text");
-asm (".globl __catchException13");
-asm ("__catchException13:");
-CHECK_FAULT();
-SAVE_REGISTERS1();
-SAVE_ERRCODE();
-SAVE_REGISTERS2();
-asm ("pushl $13");
-CALL_HOOK();
-
-/* Same thing for exception 11.  */
-extern void _catchException11 ();
-asm (".text");
-asm (".globl __catchException11");
-asm ("__catchException11:");
-CHECK_FAULT();
-SAVE_REGISTERS1();
-SAVE_ERRCODE();
-SAVE_REGISTERS2();
-asm ("pushl $11");
-CALL_HOOK();
-
-/* Same thing for exception 14.  */
-extern void _catchException14 ();
-asm (".text");
-asm (".globl __catchException14");
-asm ("__catchException14:");
-CHECK_FAULT();
-SAVE_REGISTERS1();
-SAVE_ERRCODE();
-SAVE_REGISTERS2();
-asm ("pushl $14");
-CALL_HOOK();
-
-/*
- * remcomHandler is a front end for handle_exception.  It moves the
- * stack pointer into an area reserved for debugger use.
- */
-asm("_remcomHandler:");
-asm("           popl %eax");        /* pop off return address     */
-asm("           popl %eax");      /* get the exception number   */
-asm("          movl _stackPtr, %esp"); /* move to remcom stack area  */
-asm("          pushl %eax");   /* push exception onto stack  */
-asm("          call  _handle_exception");    /* this never returns */
-
-void
-_returnFromException ()
-{
-  return_to_prog ();
-}
-
-int
-hex (ch)
-     char ch;
-{
-  if ((ch >= 'a') && (ch <= 'f'))
-    return (ch - 'a' + 10);
-  if ((ch >= '0') && (ch <= '9'))
-    return (ch - '0');
-  if ((ch >= 'A') && (ch <= 'F'))
-    return (ch - 'A' + 10);
-  return (-1);
-}
-
-static char remcomInBuffer[BUFMAX];
-static char remcomOutBuffer[BUFMAX];
-
-/* scan for the sequence $<data>#<checksum>     */
-
-unsigned char *
-getpacket (void)
-{
-  unsigned char *buffer = &remcomInBuffer[0];
-  unsigned char checksum;
-  unsigned char xmitcsum;
-  int count;
-  char ch;
-
-  while (1)
-    {
-      /* wait around for the start character, ignore all other characters */
-      while ((ch = getDebugChar ()) != '$')
-       ;
-
-    retry:
-      checksum = 0;
-      xmitcsum = -1;
-      count = 0;
-
-      /* now, read until a # or end of buffer is found */
-      while (count < BUFMAX - 1)
-       {
-         ch = getDebugChar ();
-         if (ch == '$')
-           goto retry;
-         if (ch == '#')
-           break;
-         checksum = checksum + ch;
-         buffer[count] = ch;
-         count = count + 1;
-       }
-      buffer[count] = 0;
-
-      if (ch == '#')
-       {
-         ch = getDebugChar ();
-         xmitcsum = hex (ch) << 4;
-         ch = getDebugChar ();
-         xmitcsum += hex (ch);
-
-         if (checksum != xmitcsum)
-           {
-             if (remote_debug)
-               {
-                 fprintf (stderr,
-                          "bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
-                          checksum, xmitcsum, buffer);
-               }
-             putDebugChar ('-');       /* failed checksum */
-           }
-         else
-           {
-             putDebugChar ('+');       /* successful transfer */
-
-             /* if a sequence char is present, reply the sequence ID */
-             if (buffer[2] == ':')
-               {
-                 putDebugChar (buffer[0]);
-                 putDebugChar (buffer[1]);
-
-                 return &buffer[3];
-               }
-
-             return &buffer[0];
-           }
-       }
-    }
-}
-
-/* send the packet in buffer.  */
-
-void
-putpacket (unsigned char *buffer)
-{
-  unsigned char checksum;
-  int count;
-  char ch;
-
-  /*  $<packet info>#<checksum>.  */
-  do
-    {
-      putDebugChar ('$');
-      checksum = 0;
-      count = 0;
-
-      while (ch = buffer[count])
-       {
-         putDebugChar (ch);
-         checksum += ch;
-         count += 1;
-       }
-
-      putDebugChar ('#');
-      putDebugChar (hexchars[checksum >> 4]);
-      putDebugChar (hexchars[checksum % 16]);
-
-    }
-  while (getDebugChar () != '+');
-}
-
-void
-debug_error (format, parm)
-     char *format;
-     char *parm;
-{
-  if (remote_debug)
-    fprintf (stderr, format, parm);
-}
-
-/* Address of a routine to RTE to if we get a memory fault.  */
-static void (*volatile mem_fault_routine) () = NULL;
-
-/* Indicate to caller of mem2hex or hex2mem that there has been an
-   error.  */
-static volatile int mem_err = 0;
-
-void
-set_mem_err (void)
-{
-  mem_err = 1;
-}
-
-/* These are separate functions so that they are so short and sweet
-   that the compiler won't save any registers (if there is a fault
-   to mem_fault, they won't get restored, so there better not be any
-   saved).  */
-int
-get_char (char *addr)
-{
-  return *addr;
-}
-
-void
-set_char (char *addr, int val)
-{
-  *addr = val;
-}
-
-/* convert the memory pointed to by mem into hex, placing result in buf */
-/* return a pointer to the last char put in buf (null) */
-/* If MAY_FAULT is non-zero, then we should set mem_err in response to
-   a fault; if zero treat a fault like any other fault in the stub.  */
-char *
-mem2hex (mem, buf, count, may_fault)
-     char *mem;
-     char *buf;
-     int count;
-     int may_fault;
-{
-  int i;
-  unsigned char ch;
-
-  if (may_fault)
-    mem_fault_routine = set_mem_err;
-  for (i = 0; i < count; i++)
-    {
-      ch = get_char (mem++);
-      if (may_fault && mem_err)
-       return (buf);
-      *buf++ = hexchars[ch >> 4];
-      *buf++ = hexchars[ch % 16];
-    }
-  *buf = 0;
-  if (may_fault)
-    mem_fault_routine = NULL;
-  return (buf);
-}
-
-/* convert the hex array pointed to by buf into binary to be placed in mem */
-/* return a pointer to the character AFTER the last byte written */
-char *
-hex2mem (buf, mem, count, may_fault)
-     char *buf;
-     char *mem;
-     int count;
-     int may_fault;
-{
-  int i;
-  unsigned char ch;
-
-  if (may_fault)
-    mem_fault_routine = set_mem_err;
-  for (i = 0; i < count; i++)
-    {
-      ch = hex (*buf++) << 4;
-      ch = ch + hex (*buf++);
-      set_char (mem++, ch);
-      if (may_fault && mem_err)
-       return (mem);
-    }
-  if (may_fault)
-    mem_fault_routine = NULL;
-  return (mem);
-}
-
-/* this function takes the 386 exception vector and attempts to
-   translate this number into a unix compatible signal value */
-int
-computeSignal (int exceptionVector)
-{
-  int sigval;
-  switch (exceptionVector)
-    {
-    case 0:
-      sigval = 8;
-      break;                   /* divide by zero */
-    case 1:
-      sigval = 5;
-      break;                   /* debug exception */
-    case 3:
-      sigval = 5;
-      break;                   /* breakpoint */
-    case 4:
-      sigval = 16;
-      break;                   /* into instruction (overflow) */
-    case 5:
-      sigval = 16;
-      break;                   /* bound instruction */
-    case 6:
-      sigval = 4;
-      break;                   /* Invalid opcode */
-    case 7:
-      sigval = 8;
-      break;                   /* coprocessor not available */
-    case 8:
-      sigval = 7;
-      break;                   /* double fault */
-    case 9:
-      sigval = 11;
-      break;                   /* coprocessor segment overrun */
-    case 10:
-      sigval = 11;
-      break;                   /* Invalid TSS */
-    case 11:
-      sigval = 11;
-      break;                   /* Segment not present */
-    case 12:
-      sigval = 11;
-      break;                   /* stack exception */
-    case 13:
-      sigval = 11;
-      break;                   /* general protection */
-    case 14:
-      sigval = 11;
-      break;                   /* page fault */
-    case 16:
-      sigval = 7;
-      break;                   /* coprocessor error */
-    default:
-      sigval = 7;              /* "software generated" */
-    }
-  return (sigval);
-}
-
-/**********************************************/
-/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-/* RETURN NUMBER OF CHARS PROCESSED           */
-/**********************************************/
-int
-hexToInt (char **ptr, int *intValue)
-{
-  int numChars = 0;
-  int hexValue;
-
-  *intValue = 0;
-
-  while (**ptr)
-    {
-      hexValue = hex (**ptr);
-      if (hexValue >= 0)
-       {
-         *intValue = (*intValue << 4) | hexValue;
-         numChars++;
-       }
-      else
-       break;
-
-      (*ptr)++;
-    }
-
-  return (numChars);
-}
-
-/*
- * This function does all command procesing for interfacing to gdb.
- */
-void
-handle_exception (int exceptionVector)
-{
-  int sigval, stepping;
-  int addr, length;
-  char *ptr;
-  int newPC;
-
-  gdb_i386vector = exceptionVector;
-
-  if (remote_debug)
-    {
-      printf ("vector=%d, sr=0x%x, pc=0x%x\n",
-             exceptionVector, registers[PS], registers[PC]);
-    }
-
-  /* reply to host that an exception has occurred */
-  sigval = computeSignal (exceptionVector);
-
-  ptr = remcomOutBuffer;
-
-  *ptr++ = 'T';                        /* notify gdb with signo, PC, FP and SP */
-  *ptr++ = hexchars[sigval >> 4];
-  *ptr++ = hexchars[sigval & 0xf];
-
-  *ptr++ = hexchars[ESP]; 
-  *ptr++ = ':';
-  ptr = mem2hex((char *)&registers[ESP], ptr, 4, 0);   /* SP */
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[EBP]; 
-  *ptr++ = ':';
-  ptr = mem2hex((char *)&registers[EBP], ptr, 4, 0);   /* FP */
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[PC]; 
-  *ptr++ = ':';
-  ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);    /* PC */
-  *ptr++ = ';';
-
-  *ptr = '\0'
-
-  putpacket (remcomOutBuffer);
-
-  stepping = 0;
-
-  while (1 == 1)
-    {
-      remcomOutBuffer[0] = 0;
-      ptr = getpacket ();
-
-      switch (*ptr++)
-       {
-       case '?':
-         remcomOutBuffer[0] = 'S';
-         remcomOutBuffer[1] = hexchars[sigval >> 4];
-         remcomOutBuffer[2] = hexchars[sigval % 16];
-         remcomOutBuffer[3] = 0;
-         break;
-       case 'd':
-         remote_debug = !(remote_debug);       /* toggle debug flag */
-         break;
-       case 'g':               /* return the value of the CPU registers */
-         mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
-         break;
-       case 'G':               /* set the value of the CPU registers - return OK */
-         hex2mem (ptr, (char *) registers, NUMREGBYTES, 0);
-         strcpy (remcomOutBuffer, "OK");
-         break;
-       case 'P':               /* set the value of a single CPU register - return OK */
-         {
-           int regno;
-
-           if (hexToInt (&ptr, &regno) && *ptr++ == '=')
-             if (regno >= 0 && regno < NUMREGS)
-               {
-                 hex2mem (ptr, (char *) &registers[regno], 4, 0);
-                 strcpy (remcomOutBuffer, "OK");
-                 break;
-               }
-
-           strcpy (remcomOutBuffer, "E01");
-           break;
-         }
-
-         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
-       case 'm':
-         /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
-         if (hexToInt (&ptr, &addr))
-           if (*(ptr++) == ',')
-             if (hexToInt (&ptr, &length))
-               {
-                 ptr = 0;
-                 mem_err = 0;
-                 mem2hex ((char *) addr, remcomOutBuffer, length, 1);
-                 if (mem_err)
-                   {
-                     strcpy (remcomOutBuffer, "E03");
-                     debug_error ("memory fault");
-                   }
-               }
-
-         if (ptr)
-           {
-             strcpy (remcomOutBuffer, "E01");
-           }
-         break;
-
-         /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
-       case 'M':
-         /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
-         if (hexToInt (&ptr, &addr))
-           if (*(ptr++) == ',')
-             if (hexToInt (&ptr, &length))
-               if (*(ptr++) == ':')
-                 {
-                   mem_err = 0;
-                   hex2mem (ptr, (char *) addr, length, 1);
-
-                   if (mem_err)
-                     {
-                       strcpy (remcomOutBuffer, "E03");
-                       debug_error ("memory fault");
-                     }
-                   else
-                     {
-                       strcpy (remcomOutBuffer, "OK");
-                     }
-
-                   ptr = 0;
-                 }
-         if (ptr)
-           {
-             strcpy (remcomOutBuffer, "E02");
-           }
-         break;
-
-         /* cAA..AA    Continue at address AA..AA(optional) */
-         /* sAA..AA   Step one instruction from AA..AA(optional) */
-       case 's':
-         stepping = 1;
-       case 'c':
-         /* try to read optional parameter, pc unchanged if no parm */
-         if (hexToInt (&ptr, &addr))
-           registers[PC] = addr;
-
-         newPC = registers[PC];
-
-         /* clear the trace bit */
-         registers[PS] &= 0xfffffeff;
-
-         /* set the trace bit if we're stepping */
-         if (stepping)
-           registers[PS] |= 0x100;
-
-         _returnFromException ();      /* this is a jump */
-         break;
-
-         /* kill the program */
-       case 'k':               /* do nothing */
-#if 0
-         /* Huh? This doesn't look like "nothing".
-            m68k-stub.c and sparc-stub.c don't have it.  */
-         BREAKPOINT ();
-#endif
-         break;
-       }                       /* switch */
-
-      /* reply to the request */
-      putpacket (remcomOutBuffer);
-    }
-}
-
-/* this function is used to set up exception handlers for tracing and
-   breakpoints */
-void
-set_debug_traps (void)
-{
-  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
-
-  exceptionHandler (0, _catchException0);
-  exceptionHandler (1, _catchException1);
-  exceptionHandler (3, _catchException3);
-  exceptionHandler (4, _catchException4);
-  exceptionHandler (5, _catchException5);
-  exceptionHandler (6, _catchException6);
-  exceptionHandler (7, _catchException7);
-  exceptionHandler (8, _catchException8);
-  exceptionHandler (9, _catchException9);
-  exceptionHandler (10, _catchException10);
-  exceptionHandler (11, _catchException11);
-  exceptionHandler (12, _catchException12);
-  exceptionHandler (13, _catchException13);
-  exceptionHandler (14, _catchException14);
-  exceptionHandler (16, _catchException16);
-
-  initialized = 1;
-}
-
-/* This function will generate a breakpoint exception.  It is used at the
-   beginning of a program to sync up with a debugger and can be used
-   otherwise as a quick means to stop program execution and "break" into
-   the debugger.  */
-
-void
-breakpoint (void)
-{
-  if (initialized)
-    BREAKPOINT ();
-}
diff --git a/gdb/m32r-stub.c b/gdb/m32r-stub.c
deleted file mode 100644 (file)
index 4d54f72..0000000
+++ /dev/null
@@ -1,1779 +0,0 @@
-/****************************************************************************
-
-               THIS SOFTWARE IS NOT COPYRIGHTED
-
-   HP offers the following for use in the public domain.  HP makes no
-   warranty with regard to the software or it's performance and the
-   user accepts the software "AS IS" with all faults.
-
-   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
-   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-/****************************************************************************
- *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
- *
- *  Module name: remcom.c $
- *  Revision: 1.34 $
- *  Date: 91/03/09 12:29:49 $
- *  Contributor:     Lake Stevens Instrument Division$
- *
- *  Description:     low level support for gdb debugger. $
- *
- *  Considerations:  only works on target hardware $
- *
- *  Written by:      Glenn Engel $
- *  ModuleState:     Experimental $
- *
- *  NOTES:           See Below $
- *
- *  Modified for M32R by Michael Snyder, Cygnus Support.
- *
- *  To enable debugger support, two things need to happen.  One, a
- *  call to set_debug_traps() is necessary in order to allow any breakpoints
- *  or error conditions to be properly intercepted and reported to gdb.
- *  Two, a breakpoint needs to be generated to begin communication.  This
- *  is most easily accomplished by a call to breakpoint().  Breakpoint()
- *  simulates a breakpoint by executing a trap #1.
- *
- *  The external function exceptionHandler() is
- *  used to attach a specific handler to a specific M32R vector number.
- *  It should use the same privilege level it runs at.  It should
- *  install it as an interrupt gate so that interrupts are masked
- *  while the handler runs.
- *
- *  Because gdb will sometimes write to the stack area to execute function
- *  calls, this program cannot rely on using the supervisor stack so it
- *  uses it's own stack area reserved in the int array remcomStack.
- *
- *************
- *
- *    The following gdb commands are supported:
- *
- * command          function                               Return value
- *
- *    g             return the value of the CPU registers  hex data or ENN
- *    G             set the value of the CPU registers     OK or ENN
- *
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
- *    XAA..AA,LLLL: Write LLLL binary bytes at address     OK or ENN
- *                  AA..AA
- *
- *    c             Resume at current address              SNN   ( signal NN)
- *    cAA..AA       Continue at address AA..AA             SNN
- *
- *    s             Step one instruction                   SNN
- *    sAA..AA       Step one instruction from AA..AA       SNN
- *
- *    k             kill
- *
- *    ?             What was the last sigval ?             SNN   (signal NN)
- *
- * All commands and responses are sent with a packet which includes a
- * checksum.  A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum>    :: <two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer.  '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host:                  Reply:
- * $m0,10#2a               +$00010203040506070809101112131415#42
- *
- ****************************************************************************/
-
-
-/************************************************************************
- *
- * external low-level support routines
- */
-extern void putDebugChar ();   /* write a single character      */
-extern int getDebugChar ();    /* read and return a single char */
-extern void exceptionHandler ();       /* assign an exception handler   */
-
-/*****************************************************************************
- * BUFMAX defines the maximum number of characters in inbound/outbound buffers
- * at least NUMREGBYTES*2 are needed for register packets 
- */
-#define BUFMAX 400
-
-static char initialized;       /* boolean flag. != 0 means we've been initialized */
-
-int remote_debug;
-/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
-
-static const unsigned char hexchars[] = "0123456789abcdef";
-
-#define NUMREGS 24
-
-/* Number of bytes of registers.  */
-#define NUMREGBYTES (NUMREGS * 4)
-enum regnames
-{ R0, R1, R2, R3, R4, R5, R6, R7,
-  R8, R9, R10, R11, R12, R13, R14, R15,
-  PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH
-};
-
-enum SYS_calls
-{
-  SYS_null,
-  SYS_exit,
-  SYS_open,
-  SYS_close,
-  SYS_read,
-  SYS_write,
-  SYS_lseek,
-  SYS_unlink,
-  SYS_getpid,
-  SYS_kill,
-  SYS_fstat,
-  SYS_sbrk,
-  SYS_fork,
-  SYS_execve,
-  SYS_wait4,
-  SYS_link,
-  SYS_chdir,
-  SYS_stat,
-  SYS_utime,
-  SYS_chown,
-  SYS_chmod,
-  SYS_time,
-  SYS_pipe
-};
-
-static int registers[NUMREGS];
-
-#define STACKSIZE 8096
-static unsigned char remcomInBuffer[BUFMAX];
-static unsigned char remcomOutBuffer[BUFMAX];
-static int remcomStack[STACKSIZE / sizeof (int)];
-static int *stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
-
-static unsigned int save_vectors[18];  /* previous exception vectors */
-
-/* Indicate to caller of mem2hex or hex2mem that there has been an error. */
-static volatile int mem_err = 0;
-
-/* Store the vector number here (since GDB only gets the signal
-   number through the usual means, and that's not very specific).  */
-int gdb_m32r_vector = -1;
-
-#if 0
-#include "syscall.h"           /* for SYS_exit, SYS_write etc. */
-#endif
-
-/* Global entry points:
- */
-
-extern void handle_exception (int);
-extern void set_debug_traps (void);
-extern void breakpoint (void);
-
-/* Local functions:
- */
-
-static int computeSignal (int);
-static void putpacket (unsigned char *);
-static unsigned char *getpacket (void);
-
-static unsigned char *mem2hex (unsigned char *, unsigned char *, int, int);
-static unsigned char *hex2mem (unsigned char *, unsigned char *, int, int);
-static int hexToInt (unsigned char **, int *);
-static unsigned char *bin2mem (unsigned char *, unsigned char *, int, int);
-static void stash_registers (void);
-static void restore_registers (void);
-static int prepare_to_step (int);
-static int finish_from_step (void);
-static unsigned long crc32 (unsigned char *, int, unsigned long);
-
-static void gdb_error (char *, char *);
-static int gdb_putchar (int), gdb_puts (char *), gdb_write (char *, int);
-
-static unsigned char *strcpy (unsigned char *, const unsigned char *);
-static int strlen (const unsigned char *);
-
-/*
- * This function does all command procesing for interfacing to gdb.
- */
-
-void
-handle_exception (int exceptionVector)
-{
-  int sigval, stepping;
-  int addr, length, i;
-  unsigned char *ptr;
-  unsigned char buf[16];
-  int binary;
-
-  if (!finish_from_step ())
-    return;                    /* "false step": let the target continue */
-
-  gdb_m32r_vector = exceptionVector;
-
-  if (remote_debug)
-    {
-      mem2hex ((unsigned char *) &exceptionVector, buf, 4, 0);
-      gdb_error ("Handle exception %s, ", buf);
-      mem2hex ((unsigned char *) &registers[PC], buf, 4, 0);
-      gdb_error ("PC == 0x%s\n", buf);
-    }
-
-  /* reply to host that an exception has occurred */
-  sigval = computeSignal (exceptionVector);
-
-  ptr = remcomOutBuffer;
-
-  *ptr++ = 'T';                        /* notify gdb with signo, PC, FP and SP */
-  *ptr++ = hexchars[sigval >> 4];
-  *ptr++ = hexchars[sigval & 0xf];
-
-  *ptr++ = hexchars[PC >> 4];
-  *ptr++ = hexchars[PC & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex ((unsigned char *) &registers[PC], ptr, 4, 0); /* PC */
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[R13 >> 4];
-  *ptr++ = hexchars[R13 & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex ((unsigned char *) &registers[R13], ptr, 4, 0);        /* FP */
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[R15 >> 4];
-  *ptr++ = hexchars[R15 & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex ((unsigned char *) &registers[R15], ptr, 4, 0);        /* SP */
-  *ptr++ = ';';
-  *ptr++ = 0;
-
-  if (exceptionVector == 0)    /* simulated SYS call stuff */
-    {
-      mem2hex ((unsigned char *) &registers[PC], buf, 4, 0);
-      switch (registers[R0])
-       {
-       case SYS_exit:
-         gdb_error ("Target program has exited at %s\n", buf);
-         ptr = remcomOutBuffer;
-         *ptr++ = 'W';
-         sigval = registers[R1] & 0xff;
-         *ptr++ = hexchars[sigval >> 4];
-         *ptr++ = hexchars[sigval & 0xf];
-         *ptr++ = 0;
-         break;
-       case SYS_open:
-         gdb_error ("Target attempts SYS_open call at %s\n", buf);
-         break;
-       case SYS_close:
-         gdb_error ("Target attempts SYS_close call at %s\n", buf);
-         break;
-       case SYS_read:
-         gdb_error ("Target attempts SYS_read call at %s\n", buf);
-         break;
-       case SYS_write:
-         if (registers[R1] == 1 ||     /* write to stdout  */
-             registers[R1] == 2)       /* write to stderr  */
-           {                   /* (we can do that) */
-             registers[R0] =
-               gdb_write ((void *) registers[R2], registers[R3]);
-             return;
-           }
-         else
-           gdb_error ("Target attempts SYS_write call at %s\n", buf);
-         break;
-       case SYS_lseek:
-         gdb_error ("Target attempts SYS_lseek call at %s\n", buf);
-         break;
-       case SYS_unlink:
-         gdb_error ("Target attempts SYS_unlink call at %s\n", buf);
-         break;
-       case SYS_getpid:
-         gdb_error ("Target attempts SYS_getpid call at %s\n", buf);
-         break;
-       case SYS_kill:
-         gdb_error ("Target attempts SYS_kill call at %s\n", buf);
-         break;
-       case SYS_fstat:
-         gdb_error ("Target attempts SYS_fstat call at %s\n", buf);
-         break;
-       default:
-         gdb_error ("Target attempts unknown SYS call at %s\n", buf);
-         break;
-       }
-    }
-
-  putpacket (remcomOutBuffer);
-
-  stepping = 0;
-
-  while (1 == 1)
-    {
-      remcomOutBuffer[0] = 0;
-      ptr = getpacket ();
-      binary = 0;
-      switch (*ptr++)
-       {
-       default:                /* Unknown code.  Return an empty reply message. */
-         break;
-       case 'R':
-         if (hexToInt (&ptr, &addr))
-           registers[PC] = addr;
-         strcpy (remcomOutBuffer, "OK");
-         break;
-       case '!':
-         strcpy (remcomOutBuffer, "OK");
-         break;
-       case 'X':               /* XAA..AA,LLLL:<binary data>#cs */
-         binary = 1;
-       case 'M':               /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
-         /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
-         {
-           if (hexToInt (&ptr, &addr))
-             if (*(ptr++) == ',')
-               if (hexToInt (&ptr, &length))
-                 if (*(ptr++) == ':')
-                   {
-                     mem_err = 0;
-                     if (binary)
-                       bin2mem (ptr, (unsigned char *) addr, length, 1);
-                     else
-                       hex2mem (ptr, (unsigned char *) addr, length, 1);
-                     if (mem_err)
-                       {
-                         strcpy (remcomOutBuffer, "E03");
-                         gdb_error ("memory fault", "");
-                       }
-                     else
-                       {
-                         strcpy (remcomOutBuffer, "OK");
-                       }
-                     ptr = 0;
-                   }
-           if (ptr)
-             {
-               strcpy (remcomOutBuffer, "E02");
-             }
-         }
-         break;
-       case 'm':               /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
-         /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
-         if (hexToInt (&ptr, &addr))
-           if (*(ptr++) == ',')
-             if (hexToInt (&ptr, &length))
-               {
-                 ptr = 0;
-                 mem_err = 0;
-                 mem2hex ((unsigned char *) addr, remcomOutBuffer, length,
-                          1);
-                 if (mem_err)
-                   {
-                     strcpy (remcomOutBuffer, "E03");
-                     gdb_error ("memory fault", "");
-                   }
-               }
-         if (ptr)
-           {
-             strcpy (remcomOutBuffer, "E01");
-           }
-         break;
-       case '?':
-         remcomOutBuffer[0] = 'S';
-         remcomOutBuffer[1] = hexchars[sigval >> 4];
-         remcomOutBuffer[2] = hexchars[sigval % 16];
-         remcomOutBuffer[3] = 0;
-         break;
-       case 'd':
-         remote_debug = !(remote_debug);       /* toggle debug flag */
-         break;
-       case 'g':               /* return the value of the CPU registers */
-         mem2hex ((unsigned char *) registers, remcomOutBuffer, NUMREGBYTES,
-                  0);
-         break;
-       case 'P':               /* set the value of a single CPU register - return OK */
-         {
-           int regno;
-
-           if (hexToInt (&ptr, &regno) && *ptr++ == '=')
-             if (regno >= 0 && regno < NUMREGS)
-               {
-                 int stackmode;
-
-                 hex2mem (ptr, (unsigned char *) &registers[regno], 4, 0);
-                 /*
-                  * Since we just changed a single CPU register, let's
-                  * make sure to keep the several stack pointers consistant.
-                  */
-                 stackmode = registers[PSW] & 0x80;
-                 if (regno == R15)     /* stack pointer changed */
-                   {           /* need to change SPI or SPU */
-                     if (stackmode == 0)
-                       registers[SPI] = registers[R15];
-                     else
-                       registers[SPU] = registers[R15];
-                   }
-                 else if (regno == SPU)        /* "user" stack pointer changed */
-                   {
-                     if (stackmode != 0)       /* stack in user mode: copy SP */
-                       registers[R15] = registers[SPU];
-                   }
-                 else if (regno == SPI)        /* "interrupt" stack pointer changed */
-                   {
-                     if (stackmode == 0)       /* stack in interrupt mode: copy SP */
-                       registers[R15] = registers[SPI];
-                   }
-                 else if (regno == PSW)        /* stack mode may have changed! */
-                   {           /* force SP to either SPU or SPI */
-                     if (stackmode == 0)       /* stack in user mode */
-                       registers[R15] = registers[SPI];
-                     else      /* stack in interrupt mode */
-                       registers[R15] = registers[SPU];
-                   }
-                 strcpy (remcomOutBuffer, "OK");
-                 break;
-               }
-           strcpy (remcomOutBuffer, "E01");
-           break;
-         }
-       case 'G':               /* set the value of the CPU registers - return OK */
-         hex2mem (ptr, (unsigned char *) registers, NUMREGBYTES, 0);
-         strcpy (remcomOutBuffer, "OK");
-         break;
-       case 's':               /* sAA..AA      Step one instruction from AA..AA(optional) */
-         stepping = 1;
-       case 'c':               /* cAA..AA      Continue from address AA..AA(optional) */
-         /* try to read optional parameter, pc unchanged if no parm */
-         if (hexToInt (&ptr, &addr))
-           registers[PC] = addr;
-
-         if (stepping)         /* single-stepping */
-           {
-             if (!prepare_to_step (0)) /* set up for single-step */
-               {
-                 /* prepare_to_step has already emulated the target insn:
-                    Send SIGTRAP to gdb, don't resume the target at all.  */
-                 ptr = remcomOutBuffer;
-                 *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */
-                 *ptr++ = '0';
-                 *ptr++ = '5';
-
-                 *ptr++ = hexchars[PC >> 4];   /* send PC */
-                 *ptr++ = hexchars[PC & 0xf];
-                 *ptr++ = ':';
-                 ptr = mem2hex ((unsigned char *) &registers[PC], ptr, 4, 0);
-                 *ptr++ = ';';
-
-                 *ptr++ = hexchars[R13 >> 4];  /* send FP */
-                 *ptr++ = hexchars[R13 & 0xf];
-                 *ptr++ = ':';
-                 ptr =
-                   mem2hex ((unsigned char *) &registers[R13], ptr, 4, 0);
-                 *ptr++ = ';';
-
-                 *ptr++ = hexchars[R15 >> 4];  /* send SP */
-                 *ptr++ = hexchars[R15 & 0xf];
-                 *ptr++ = ':';
-                 ptr =
-                   mem2hex ((unsigned char *) &registers[R15], ptr, 4, 0);
-                 *ptr++ = ';';
-                 *ptr++ = 0;
-
-                 break;
-               }
-           }
-         else                  /* continuing, not single-stepping */
-           {
-             /* OK, about to do a "continue".  First check to see if the 
-                target pc is on an odd boundary (second instruction in the 
-                word).  If so, we must do a single-step first, because 
-                ya can't jump or return back to an odd boundary!  */
-             if ((registers[PC] & 2) != 0)
-               prepare_to_step (1);
-           }
-
-         return;
-
-       case 'D':               /* Detach */
-#if 0
-         /* I am interpreting this to mean, release the board from control 
-            by the remote stub.  To do this, I am restoring the original
-            (or at least previous) exception vectors.
-          */
-         for (i = 0; i < 18; i++)
-           exceptionHandler (i, save_vectors[i]);
-         putpacket ("OK");
-         return;               /* continue the inferior */
-#else
-         strcpy (remcomOutBuffer, "OK");
-         break;
-#endif
-       case 'q':
-         if (*ptr++ == 'C' &&
-             *ptr++ == 'R' && *ptr++ == 'C' && *ptr++ == ':')
-           {
-             unsigned long start, len, our_crc;
-
-             if (hexToInt (&ptr, (int *) &start) &&
-                 *ptr++ == ',' && hexToInt (&ptr, (int *) &len))
-               {
-                 remcomOutBuffer[0] = 'C';
-                 our_crc = crc32 ((unsigned char *) start, len, 0xffffffff);
-                 mem2hex ((char *) &our_crc,
-                          &remcomOutBuffer[1], sizeof (long), 0);
-               }               /* else do nothing */
-           }                   /* else do nothing */
-         break;
-
-       case 'k':               /* kill the program */
-         continue;
-       }                       /* switch */
-
-      /* reply to the request */
-      putpacket (remcomOutBuffer);
-    }
-}
-
-/* qCRC support */
-
-/* Table used by the crc32 function to calcuate the checksum. */
-static unsigned long crc32_table[256] = { 0, 0 };
-
-static unsigned long
-crc32 (unsigned char *buf, int len, unsigned long crc)
-{
-  if (!crc32_table[1])
-    {
-      /* Initialize the CRC table and the decoding table. */
-      int i, j;
-      unsigned long c;
-
-      for (i = 0; i < 256; i++)
-       {
-         for (c = i << 24, j = 8; j > 0; --j)
-           c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
-         crc32_table[i] = c;
-       }
-    }
-
-  while (len--)
-    {
-      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
-      buf++;
-    }
-  return crc;
-}
-
-static int
-hex (unsigned char ch)
-{
-  if ((ch >= 'a') && (ch <= 'f'))
-    return (ch - 'a' + 10);
-  if ((ch >= '0') && (ch <= '9'))
-    return (ch - '0');
-  if ((ch >= 'A') && (ch <= 'F'))
-    return (ch - 'A' + 10);
-  return (-1);
-}
-
-/* scan for the sequence $<data>#<checksum>     */
-
-unsigned char *
-getpacket (void)
-{
-  unsigned char *buffer = &remcomInBuffer[0];
-  unsigned char checksum;
-  unsigned char xmitcsum;
-  int count;
-  char ch;
-
-  while (1)
-    {
-      /* wait around for the start character, ignore all other characters */
-      while ((ch = getDebugChar ()) != '$')
-       ;
-
-    retry:
-      checksum = 0;
-      xmitcsum = -1;
-      count = 0;
-
-      /* now, read until a # or end of buffer is found */
-      while (count < BUFMAX - 1)
-       {
-         ch = getDebugChar ();
-         if (ch == '$')
-           goto retry;
-         if (ch == '#')
-           break;
-         checksum = checksum + ch;
-         buffer[count] = ch;
-         count = count + 1;
-       }
-      buffer[count] = 0;
-
-      if (ch == '#')
-       {
-         ch = getDebugChar ();
-         xmitcsum = hex (ch) << 4;
-         ch = getDebugChar ();
-         xmitcsum += hex (ch);
-
-         if (checksum != xmitcsum)
-           {
-             if (remote_debug)
-               {
-                 unsigned char buf[16];
-
-                 mem2hex ((unsigned char *) &checksum, buf, 4, 0);
-                 gdb_error ("Bad checksum: my count = %s, ", buf);
-                 mem2hex ((unsigned char *) &xmitcsum, buf, 4, 0);
-                 gdb_error ("sent count = %s\n", buf);
-                 gdb_error (" -- Bad buffer: \"%s\"\n", buffer);
-               }
-             putDebugChar ('-');       /* failed checksum */
-           }
-         else
-           {
-             putDebugChar ('+');       /* successful transfer */
-
-             /* if a sequence char is present, reply the sequence ID */
-             if (buffer[2] == ':')
-               {
-                 putDebugChar (buffer[0]);
-                 putDebugChar (buffer[1]);
-
-                 return &buffer[3];
-               }
-
-             return &buffer[0];
-           }
-       }
-    }
-}
-
-/* send the packet in buffer.  */
-
-static void
-putpacket (unsigned char *buffer)
-{
-  unsigned char checksum;
-  int count;
-  char ch;
-
-  /*  $<packet info>#<checksum>. */
-  do
-    {
-      putDebugChar ('$');
-      checksum = 0;
-      count = 0;
-
-      while (ch = buffer[count])
-       {
-         putDebugChar (ch);
-         checksum += ch;
-         count += 1;
-       }
-      putDebugChar ('#');
-      putDebugChar (hexchars[checksum >> 4]);
-      putDebugChar (hexchars[checksum % 16]);
-    }
-  while (getDebugChar () != '+');
-}
-
-/* Address of a routine to RTE to if we get a memory fault.  */
-
-static void (*volatile mem_fault_routine) () = 0;
-
-static void
-set_mem_err (void)
-{
-  mem_err = 1;
-}
-
-/* Check the address for safe access ranges.  As currently defined,
-   this routine will reject the "expansion bus" address range(s).
-   To make those ranges useable, someone must implement code to detect
-   whether there's anything connected to the expansion bus. */
-
-static int
-mem_safe (unsigned char *addr)
-{
-#define BAD_RANGE_ONE_START    ((unsigned char *) 0x600000)
-#define BAD_RANGE_ONE_END      ((unsigned char *) 0xa00000)
-#define BAD_RANGE_TWO_START    ((unsigned char *) 0xff680000)
-#define BAD_RANGE_TWO_END      ((unsigned char *) 0xff800000)
-
-  if (addr < BAD_RANGE_ONE_START)
-    return 1;                  /* safe */
-  if (addr < BAD_RANGE_ONE_END)
-    return 0;                  /* unsafe */
-  if (addr < BAD_RANGE_TWO_START)
-    return 1;                  /* safe */
-  if (addr < BAD_RANGE_TWO_END)
-    return 0;                  /* unsafe */
-}
-
-/* These are separate functions so that they are so short and sweet
-   that the compiler won't save any registers (if there is a fault
-   to mem_fault, they won't get restored, so there better not be any
-   saved).  */
-static int
-get_char (unsigned char *addr)
-{
-#if 1
-  if (mem_fault_routine && !mem_safe (addr))
-    {
-      mem_fault_routine ();
-      return 0;
-    }
-#endif
-  return *addr;
-}
-
-static void
-set_char (unsigned char *addr, unsigned char val)
-{
-#if 1
-  if (mem_fault_routine && !mem_safe (addr))
-    {
-      mem_fault_routine ();
-      return;
-    }
-#endif
-  *addr = val;
-}
-
-/* Convert the memory pointed to by mem into hex, placing result in buf.
-   Return a pointer to the last char put in buf (null).
-   If MAY_FAULT is non-zero, then we should set mem_err in response to
-   a fault; if zero treat a fault like any other fault in the stub.  */
-
-static unsigned char *
-mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
-{
-  int i;
-  unsigned char ch;
-
-  if (may_fault)
-    mem_fault_routine = set_mem_err;
-  for (i = 0; i < count; i++)
-    {
-      ch = get_char (mem++);
-      if (may_fault && mem_err)
-       return (buf);
-      *buf++ = hexchars[ch >> 4];
-      *buf++ = hexchars[ch % 16];
-    }
-  *buf = 0;
-  if (may_fault)
-    mem_fault_routine = 0;
-  return (buf);
-}
-
-/* Convert the hex array pointed to by buf into binary to be placed in mem.
-   Return a pointer to the character AFTER the last byte written. */
-
-static unsigned char *
-hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
-{
-  int i;
-  unsigned char ch;
-
-  if (may_fault)
-    mem_fault_routine = set_mem_err;
-  for (i = 0; i < count; i++)
-    {
-      ch = hex (*buf++) << 4;
-      ch = ch + hex (*buf++);
-      set_char (mem++, ch);
-      if (may_fault && mem_err)
-       return (mem);
-    }
-  if (may_fault)
-    mem_fault_routine = 0;
-  return (mem);
-}
-
-/* Convert the binary stream in BUF to memory.
-
-   Gdb will escape $, #, and the escape char (0x7d).
-   COUNT is the total number of bytes to write into
-   memory. */
-static unsigned char *
-bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
-{
-  int i;
-  unsigned char ch;
-
-  if (may_fault)
-    mem_fault_routine = set_mem_err;
-  for (i = 0; i < count; i++)
-    {
-      /* Check for any escaped characters. Be paranoid and
-         only unescape chars that should be escaped. */
-      if (*buf == 0x7d)
-       {
-         switch (*(buf + 1))
-           {
-           case 0x3:           /* # */
-           case 0x4:           /* $ */
-           case 0x5d:          /* escape char */
-             buf++;
-             *buf |= 0x20;
-             break;
-           default:
-             /* nothing */
-             break;
-           }
-       }
-
-      set_char (mem++, *buf++);
-
-      if (may_fault && mem_err)
-       return mem;
-    }
-
-  if (may_fault)
-    mem_fault_routine = 0;
-  return mem;
-}
-
-/* this function takes the m32r exception vector and attempts to
-   translate this number into a unix compatible signal value */
-
-static int
-computeSignal (int exceptionVector)
-{
-  int sigval;
-  switch (exceptionVector)
-    {
-    case 0:
-      sigval = 23;
-      break;                   /* I/O trap                    */
-    case 1:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 2:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 3:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 4:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 5:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 6:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 7:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 8:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 9:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 10:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 11:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 12:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 13:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 14:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 15:
-      sigval = 5;
-      break;                   /* breakpoint                  */
-    case 16:
-      sigval = 10;
-      break;                   /* BUS ERROR (alignment)       */
-    case 17:
-      sigval = 2;
-      break;                   /* INTerrupt                   */
-    default:
-      sigval = 7;
-      break;                   /* "software generated"        */
-    }
-  return (sigval);
-}
-
-/**********************************************/
-/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-/* RETURN NUMBER OF CHARS PROCESSED           */
-/**********************************************/
-static int
-hexToInt (unsigned char **ptr, int *intValue)
-{
-  int numChars = 0;
-  int hexValue;
-
-  *intValue = 0;
-  while (**ptr)
-    {
-      hexValue = hex (**ptr);
-      if (hexValue >= 0)
-       {
-         *intValue = (*intValue << 4) | hexValue;
-         numChars++;
-       }
-      else
-       break;
-      (*ptr)++;
-    }
-  return (numChars);
-}
-
-/*
-  Table of branch instructions:
-  
-  10B6         RTE     return from trap or exception
-  1FCr         JMP     jump
-  1ECr         JL      jump and link
-  7Fxx         BRA     branch
-  FFxxxxxx     BRA     branch (long)
-  B09rxxxx     BNEZ    branch not-equal-zero
-  Br1rxxxx     BNE     branch not-equal
-  7Dxx         BNC     branch not-condition
-  FDxxxxxx     BNC     branch not-condition (long)
-  B0Arxxxx     BLTZ    branch less-than-zero
-  B0Crxxxx     BLEZ    branch less-equal-zero
-  7Exx         BL      branch and link
-  FExxxxxx     BL      branch and link (long)
-  B0Drxxxx     BGTZ    branch greater-than-zero
-  B0Brxxxx     BGEZ    branch greater-equal-zero
-  B08rxxxx     BEQZ    branch equal-zero
-  Br0rxxxx     BEQ     branch equal
-  7Cxx         BC      branch condition
-  FCxxxxxx     BC      branch condition (long)
-  */
-
-static int
-isShortBranch (unsigned char *instr)
-{
-  unsigned char instr0 = instr[0] & 0x7F;      /* mask off high bit */
-
-  if (instr0 == 0x10 && instr[1] == 0xB6)      /* RTE */
-    return 1;                  /* return from trap or exception */
-
-  if (instr0 == 0x1E || instr0 == 0x1F)        /* JL or JMP */
-    if ((instr[1] & 0xF0) == 0xC0)
-      return 2;                        /* jump thru a register */
-
-  if (instr0 == 0x7C || instr0 == 0x7D ||      /* BC, BNC, BL, BRA */
-      instr0 == 0x7E || instr0 == 0x7F)
-    return 3;                  /* eight bit PC offset */
-
-  return 0;
-}
-
-static int
-isLongBranch (unsigned char *instr)
-{
-  if (instr[0] == 0xFC || instr[0] == 0xFD ||  /* BRA, BNC, BL, BC */
-      instr[0] == 0xFE || instr[0] == 0xFF)    /* 24 bit relative */
-    return 4;
-  if ((instr[0] & 0xF0) == 0xB0)       /* 16 bit relative */
-    {
-      if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */
-         (instr[1] & 0xF0) == 0x10)
-       return 5;
-      if (instr[0] == 0xB0)    /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */
-       if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 ||
-           (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 ||
-           (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0)
-         return 6;
-    }
-  return 0;
-}
-
-/* if address is NOT on a 4-byte boundary, or high-bit of instr is zero, 
-   then it's a 2-byte instruction, else it's a 4-byte instruction.  */
-
-#define INSTRUCTION_SIZE(addr) \
-    ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
-
-static int
-isBranch (unsigned char *instr)
-{
-  if (INSTRUCTION_SIZE (instr) == 2)
-    return isShortBranch (instr);
-  else
-    return isLongBranch (instr);
-}
-
-static int
-willBranch (unsigned char *instr, int branchCode)
-{
-  switch (branchCode)
-    {
-    case 0:
-      return 0;                        /* not a branch */
-    case 1:
-      return 1;                        /* RTE */
-    case 2:
-      return 1;                        /* JL or JMP    */
-    case 3:                    /* BC, BNC, BL, BRA (short) */
-    case 4:                    /* BC, BNC, BL, BRA (long) */
-      switch (instr[0] & 0x0F)
-       {
-       case 0xC:               /* Branch if Condition Register */
-         return (registers[CBR] != 0);
-       case 0xD:               /* Branch if NOT Condition Register */
-         return (registers[CBR] == 0);
-       case 0xE:               /* Branch and Link */
-       case 0xF:               /* Branch (unconditional) */
-         return 1;
-       default:                /* oops? */
-         return 0;
-       }
-    case 5:                    /* BNE, BEQ */
-      switch (instr[1] & 0xF0)
-       {
-       case 0x00:              /* Branch if r1 equal to r2 */
-         return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]);
-       case 0x10:              /* Branch if r1 NOT equal to r2 */
-         return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]);
-       default:                /* oops? */
-         return 0;
-       }
-    case 6:                    /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */
-      switch (instr[1] & 0xF0)
-       {
-       case 0x80:              /* Branch if reg equal to zero */
-         return (registers[instr[1] & 0x0F] == 0);
-       case 0x90:              /* Branch if reg NOT equal to zero */
-         return (registers[instr[1] & 0x0F] != 0);
-       case 0xA0:              /* Branch if reg less than zero */
-         return (registers[instr[1] & 0x0F] < 0);
-       case 0xB0:              /* Branch if reg greater or equal to zero */
-         return (registers[instr[1] & 0x0F] >= 0);
-       case 0xC0:              /* Branch if reg less than or equal to zero */
-         return (registers[instr[1] & 0x0F] <= 0);
-       case 0xD0:              /* Branch if reg greater than zero */
-         return (registers[instr[1] & 0x0F] > 0);
-       default:                /* oops? */
-         return 0;
-       }
-    default:                   /* oops? */
-      return 0;
-    }
-}
-
-static int
-branchDestination (unsigned char *instr, int branchCode)
-{
-  switch (branchCode)
-    {
-    default:
-    case 0:                    /* not a branch */
-      return 0;
-    case 1:                    /* RTE */
-      return registers[BPC] & ~3;      /* pop BPC into PC */
-    case 2:                    /* JL or JMP */
-      return registers[instr[1] & 0x0F] & ~3;  /* jump thru a register */
-    case 3:                    /* BC, BNC, BL, BRA (short, 8-bit relative offset) */
-      return (((int) instr) & ~3) + ((char) instr[1] << 2);
-    case 4:                    /* BC, BNC, BL, BRA (long, 24-bit relative offset) */
-      return ((int) instr +
-             ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) <<
-              2));
-    case 5:                    /* BNE, BEQ (16-bit relative offset) */
-    case 6:                    /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
-      return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2));
-    }
-
-  /* An explanatory note: in the last three return expressions, I have
-     cast the most-significant byte of the return offset to char.
-     What this accomplishes is sign extension.  If the other
-     less-significant bytes were signed as well, they would get sign
-     extended too and, if negative, their leading bits would clobber
-     the bits of the more-significant bytes ahead of them.  There are
-     other ways I could have done this, but sign extension from
-     odd-sized integers is always a pain. */
-}
-
-static void
-branchSideEffects (unsigned char *instr, int branchCode)
-{
-  switch (branchCode)
-    {
-    case 1:                    /* RTE */
-      return;                  /* I <THINK> this is already handled... */
-    case 2:                    /* JL (or JMP) */
-    case 3:                    /* BL (or BC, BNC, BRA) */
-    case 4:
-      if ((instr[0] & 0x0F) == 0x0E)   /* branch/jump and link */
-       registers[R14] = (registers[PC] & ~3) + 4;
-      return;
-    default:                   /* any other branch has no side effects */
-      return;
-    }
-}
-
-static struct STEPPING_CONTEXT
-{
-  int stepping;                        /* true when we've started a single-step */
-  unsigned long target_addr;   /* the instr we're trying to execute */
-  unsigned long target_size;   /* the size of the target instr */
-  unsigned long noop_addr;     /* where we've inserted a no-op, if any */
-  unsigned long trap1_addr;    /* the trap following the target instr */
-  unsigned long trap2_addr;    /* the trap at a branch destination, if any */
-  unsigned short noop_save;    /* instruction overwritten by our no-op */
-  unsigned short trap1_save;   /* instruction overwritten by trap1 */
-  unsigned short trap2_save;   /* instruction overwritten by trap2 */
-  unsigned short continue_p;   /* true if NOT returning to gdb after step */
-} stepping;
-
-/* Function: prepare_to_step
-   Called from handle_exception to prepare the user program to single-step.
-   Places a trap instruction after the target instruction, with special 
-   extra handling for branch instructions and for instructions in the 
-   second half-word of a word.  
-
-   Returns: True  if we should actually execute the instruction; 
-           False if we are going to emulate executing the instruction,
-           in which case we simply report to GDB that the instruction 
-           has already been executed.  */
-
-#define TRAP1  0x10f1;         /* trap #1 instruction */
-#define NOOP   0x7000;         /* noop    instruction */
-
-static unsigned short trap1 = TRAP1;
-static unsigned short noop = NOOP;
-
-static int
-prepare_to_step (continue_p)
-     int continue_p;           /* if this isn't REALLY a single-step (see below) */
-{
-  unsigned long pc = registers[PC];
-  int branchCode = isBranch ((unsigned char *) pc);
-  unsigned char *p;
-
-  /* zero out the stepping context 
-     (paranoia -- it should already be zeroed) */
-  for (p = (unsigned char *) &stepping;
-       p < ((unsigned char *) &stepping) + sizeof (stepping); p++)
-    *p = 0;
-
-  if (branchCode != 0)         /* next instruction is a branch */
-    {
-      branchSideEffects ((unsigned char *) pc, branchCode);
-      if (willBranch ((unsigned char *) pc, branchCode))
-       registers[PC] = branchDestination ((unsigned char *) pc, branchCode);
-      else
-       registers[PC] = pc + INSTRUCTION_SIZE (pc);
-      return 0;                        /* branch "executed" -- just notify GDB */
-    }
-  else if (((int) pc & 2) != 0)        /* "second-slot" instruction */
-    {
-      /* insert no-op before pc */
-      stepping.noop_addr = pc - 2;
-      stepping.noop_save = *(unsigned short *) stepping.noop_addr;
-      *(unsigned short *) stepping.noop_addr = noop;
-      /* insert trap  after  pc */
-      stepping.trap1_addr = pc + 2;
-      stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
-      *(unsigned short *) stepping.trap1_addr = trap1;
-    }
-  else                         /* "first-slot" instruction */
-    {
-      /* insert trap  after  pc */
-      stepping.trap1_addr = pc + INSTRUCTION_SIZE (pc);
-      stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
-      *(unsigned short *) stepping.trap1_addr = trap1;
-    }
-  /* "continue_p" means that we are actually doing a continue, and not 
-     being requested to single-step by GDB.  Sometimes we have to do
-     one single-step before continuing, because the PC is on a half-word
-     boundary.  There's no way to simply resume at such an address.  */
-  stepping.continue_p = continue_p;
-  stepping.stepping = 1;       /* starting a single-step */
-  return 1;
-}
-
-/* Function: finish_from_step
-   Called from handle_exception to finish up when the user program 
-   returns from a single-step.  Replaces the instructions that had
-   been overwritten by traps or no-ops, 
-
-   Returns: True  if we should notify GDB that the target stopped.
-           False if we only single-stepped because we had to before we
-           could continue (ie. we were trying to continue at a 
-           half-word boundary).  In that case don't notify GDB:
-           just "continue continuing".  */
-
-static int
-finish_from_step (void)
-{
-  if (stepping.stepping)       /* anything to do? */
-    {
-      int continue_p = stepping.continue_p;
-      unsigned char *p;
-
-      if (stepping.noop_addr)  /* replace instr "under" our no-op */
-       *(unsigned short *) stepping.noop_addr = stepping.noop_save;
-      if (stepping.trap1_addr) /* replace instr "under" our trap  */
-       *(unsigned short *) stepping.trap1_addr = stepping.trap1_save;
-      if (stepping.trap2_addr) /* ditto our other trap, if any    */
-       *(unsigned short *) stepping.trap2_addr = stepping.trap2_save;
-
-      for (p = (unsigned char *) &stepping;    /* zero out the stepping context */
-          p < ((unsigned char *) &stepping) + sizeof (stepping); p++)
-       *p = 0;
-
-      return !(continue_p);
-    }
-  else                         /* we didn't single-step, therefore this must be a legitimate stop */
-    return 1;
-}
-
-struct PSWreg
-{                              /* separate out the bit flags in the PSW register */
-  int pad1:16;
-  int bsm:1;
-  int bie:1;
-  int pad2:5;
-  int bc:1;
-  int sm:1;
-  int ie:1;
-  int pad3:5;
-  int c:1;
-} *psw;
-
-/* Upon entry the value for LR to save has been pushed.
-   We unpush that so that the value for the stack pointer saved is correct.
-   Upon entry, all other registers are assumed to have not been modified
-   since the interrupt/trap occured.  */
-
-asm ("\n\
-stash_registers:\n\
-       push r0\n\
-       push r1\n\
-       seth r1, #shigh(registers)\n\
-       add3 r1, r1, #low(registers)\n\
-       pop r0          ; r1\n\
-       st r0, @(4,r1)\n\
-       pop r0          ; r0\n\
-       st r0, @r1\n\
-       addi r1, #4     ; only add 4 as subsequent saves are `pre inc'\n\
-       st r2, @+r1\n\
-       st r3, @+r1\n\
-       st r4, @+r1\n\
-       st r5, @+r1\n\
-       st r6, @+r1\n\
-       st r7, @+r1\n\
-       st r8, @+r1\n\
-       st r9, @+r1\n\
-       st r10, @+r1\n\
-       st r11, @+r1\n\
-       st r12, @+r1\n\
-       st r13, @+r1    ; fp\n\
-       pop r0          ; lr (r14)\n\
-       st r0, @+r1\n\
-       st sp, @+r1     ; sp contains right value at this point\n\
-       mvfc r0, cr0\n\
-       st r0, @+r1     ; cr0 == PSW\n\
-       mvfc r0, cr1\n\
-       st r0, @+r1     ; cr1 == CBR\n\
-       mvfc r0, cr2\n\
-       st r0, @+r1     ; cr2 == SPI\n\
-       mvfc r0, cr3\n\
-       st r0, @+r1     ; cr3 == SPU\n\
-       mvfc r0, cr6\n\
-       st r0, @+r1     ; cr6 == BPC\n\
-       st r0, @+r1     ; PC  == BPC\n\
-       mvfaclo r0\n\
-       st r0, @+r1     ; ACCL\n\
-       mvfachi r0\n\
-       st r0, @+r1     ; ACCH\n\
-       jmp lr");
-
-/* C routine to clean up what stash_registers did.
-   It is called after calling stash_registers.
-   This is separate from stash_registers as we want to do this in C
-   but doing stash_registers in C isn't straightforward.  */
-
-static void
-cleanup_stash (void)
-{
-  psw = (struct PSWreg *) &registers[PSW];     /* fields of PSW register */
-  psw->sm = psw->bsm;          /* fix up pre-trap values of psw fields */
-  psw->ie = psw->bie;
-  psw->c = psw->bc;
-  registers[CBR] = psw->bc;    /* fix up pre-trap "C" register */
-
-#if 0                          /* FIXME: Was in previous version.  Necessary?
-                                  (Remember that we use the "rte" insn to return from the
-                                  trap/interrupt so the values of bsm, bie, bc are important.  */
-  psw->bsm = psw->bie = psw->bc = 0;   /* zero post-trap values */
-#endif
-
-  /* FIXME: Copied from previous version.  This can probably be deleted
-     since methinks stash_registers has already done this.  */
-  registers[PC] = registers[BPC];      /* pre-trap PC */
-
-  /* FIXME: Copied from previous version.  Necessary?  */
-  if (psw->sm)                 /* copy R15 into (psw->sm ? SPU : SPI) */
-    registers[SPU] = registers[R15];
-  else
-    registers[SPI] = registers[R15];
-}
-
-asm ("\n\
-restore_and_return:\n\
-       seth r0, #shigh(registers+8)\n\
-       add3 r0, r0, #low(registers+8)\n\
-       ld r2, @r0+     ; restore r2\n\
-       ld r3, @r0+     ; restore r3\n\
-       ld r4, @r0+     ; restore r4\n\
-       ld r5, @r0+     ; restore r5\n\
-       ld r6, @r0+     ; restore r6\n\
-       ld r7, @r0+     ; restore r7\n\
-       ld r8, @r0+     ; restore r8\n\
-       ld r9, @r0+     ; restore r9\n\
-       ld r10, @r0+    ; restore r10\n\
-       ld r11, @r0+    ; restore r11\n\
-       ld r12, @r0+    ; restore r12\n\
-       ld r13, @r0+    ; restore r13\n\
-       ld r14, @r0+    ; restore r14\n\
-       ld r15, @r0+    ; restore r15\n\
-       ld r1, @r0+     ; restore cr0 == PSW\n\
-       mvtc r1, cr0\n\
-       ld r1, @r0+     ; restore cr1 == CBR (no-op, because it's read only)\n\
-       mvtc r1, cr1\n\
-       ld r1, @r0+     ; restore cr2 == SPI\n\
-       mvtc r1, cr2\n\
-       ld r1, @r0+     ; restore cr3 == SPU\n\
-       mvtc r1, cr3\n\
-       addi r0, #4     ; skip BPC\n\
-       ld r1, @r0+     ; restore cr6 (BPC) == PC\n\
-       mvtc r1, cr6\n\
-       ld r1, @r0+     ; restore ACCL\n\
-       mvtaclo r1\n\
-       ld r1, @r0+     ; restore ACCH\n\
-       mvtachi r1\n\
-       seth r0, #shigh(registers)\n\
-       add3 r0, r0, #low(registers)\n\
-       ld r1, @(4,r0)  ; restore r1\n\
-       ld r0, @r0      ; restore r0\n\
-       rte");
-
-/* General trap handler, called after the registers have been stashed.
-   NUM is the trap/exception number.  */
-
-static void
-process_exception (int num)
-{
-  cleanup_stash ();
-  asm volatile ("\n\
-       seth r1, #shigh(stackPtr)\n\
-       add3 r1, r1, #low(stackPtr)\n\
-       ld r15, @r1             ; setup local stack (protect user stack)\n\
-       mv r0, %0\n\
-       bl handle_exception\n\
-       bl restore_and_return"::"r" (num):"r0", "r1");
-}
-
-void _catchException0 ();
-
-asm ("\n\
-_catchException0:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #0\n\
-       bl process_exception");
-
-void _catchException1 ();
-
-asm ("\n\
-_catchException1:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       bl cleanup_stash\n\
-       seth r1, #shigh(stackPtr)\n\
-       add3 r1, r1, #low(stackPtr)\n\
-       ld r15, @r1             ; setup local stack (protect user stack)\n\
-       seth r1, #shigh(registers + 21*4) ; PC\n\
-       add3 r1, r1, #low(registers + 21*4)\n\
-       ld r0, @r1\n\
-       addi r0, #-4            ; back up PC for breakpoint trap.\n\
-       st r0, @r1              ; FIXME: what about bp in right slot?\n\
-       ldi r0, #1\n\
-       bl handle_exception\n\
-       bl restore_and_return");
-
-void _catchException2 ();
-
-asm ("\n\
-_catchException2:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #2\n\
-       bl process_exception");
-
-void _catchException3 ();
-
-asm ("\n\
-_catchException3:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #3\n\
-       bl process_exception");
-
-void _catchException4 ();
-
-asm ("\n\
-_catchException4:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #4\n\
-       bl process_exception");
-
-void _catchException5 ();
-
-asm ("\n\
-_catchException5:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #5\n\
-       bl process_exception");
-
-void _catchException6 ();
-
-asm ("\n\
-_catchException6:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #6\n\
-       bl process_exception");
-
-void _catchException7 ();
-
-asm ("\n\
-_catchException7:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #7\n\
-       bl process_exception");
-
-void _catchException8 ();
-
-asm ("\n\
-_catchException8:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #8\n\
-       bl process_exception");
-
-void _catchException9 ();
-
-asm ("\n\
-_catchException9:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #9\n\
-       bl process_exception");
-
-void _catchException10 ();
-
-asm ("\n\
-_catchException10:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #10\n\
-       bl process_exception");
-
-void _catchException11 ();
-
-asm ("\n\
-_catchException11:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #11\n\
-       bl process_exception");
-
-void _catchException12 ();
-
-asm ("\n\
-_catchException12:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #12\n\
-       bl process_exception");
-
-void _catchException13 ();
-
-asm ("\n\
-_catchException13:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #13\n\
-       bl process_exception");
-
-void _catchException14 ();
-
-asm ("\n\
-_catchException14:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #14\n\
-       bl process_exception");
-
-void _catchException15 ();
-
-asm ("\n\
-_catchException15:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #15\n\
-       bl process_exception");
-
-void _catchException16 ();
-
-asm ("\n\
-_catchException16:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #16\n\
-       bl process_exception");
-
-void _catchException17 ();
-
-asm ("\n\
-_catchException17:\n\
-       push lr\n\
-       bl stash_registers\n\
-       ; Note that at this point the pushed value of `lr' has been popped\n\
-       ldi r0, #17\n\
-       bl process_exception");
-
-
-/* this function is used to set up exception handlers for tracing and
-   breakpoints */
-void
-set_debug_traps (void)
-{
-  /*  extern void remcomHandler(); */
-  int i;
-
-  for (i = 0; i < 18; i++)     /* keep a copy of old vectors */
-    if (save_vectors[i] == 0)  /* only copy them the first time */
-      save_vectors[i] = getExceptionHandler (i);
-
-  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
-
-  exceptionHandler (0, _catchException0);
-  exceptionHandler (1, _catchException1);
-  exceptionHandler (2, _catchException2);
-  exceptionHandler (3, _catchException3);
-  exceptionHandler (4, _catchException4);
-  exceptionHandler (5, _catchException5);
-  exceptionHandler (6, _catchException6);
-  exceptionHandler (7, _catchException7);
-  exceptionHandler (8, _catchException8);
-  exceptionHandler (9, _catchException9);
-  exceptionHandler (10, _catchException10);
-  exceptionHandler (11, _catchException11);
-  exceptionHandler (12, _catchException12);
-  exceptionHandler (13, _catchException13);
-  exceptionHandler (14, _catchException14);
-  exceptionHandler (15, _catchException15);
-  exceptionHandler (16, _catchException16);
-  /*  exceptionHandler (17, _catchException17); */
-
-  initialized = 1;
-}
-
-/* This function will generate a breakpoint exception.  It is used at the
-   beginning of a program to sync up with a debugger and can be used
-   otherwise as a quick means to stop program execution and "break" into
-   the debugger. */
-
-#define BREAKPOINT() asm volatile ("   trap #2");
-
-void
-breakpoint (void)
-{
-  if (initialized)
-    BREAKPOINT ();
-}
-
-/* STDOUT section:
-   Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
-   Functions: gdb_putchar(char ch)
-              gdb_puts(char *str)
-              gdb_write(char *str, int len)
-              gdb_error(char *format, char *parm)
-             */
-
-/* Function: gdb_putchar(int)
-   Make gdb write a char to stdout.
-   Returns: the char */
-
-static int
-gdb_putchar (int ch)
-{
-  char buf[4];
-
-  buf[0] = 'O';
-  buf[1] = hexchars[ch >> 4];
-  buf[2] = hexchars[ch & 0x0F];
-  buf[3] = 0;
-  putpacket (buf);
-  return ch;
-}
-
-/* Function: gdb_write(char *, int)
-   Make gdb write n bytes to stdout (not assumed to be null-terminated).
-   Returns: number of bytes written */
-
-static int
-gdb_write (char *data, int len)
-{
-  char *buf, *cpy;
-  int i;
-
-  buf = remcomOutBuffer;
-  buf[0] = 'O';
-  i = 0;
-  while (i < len)
-    {
-      for (cpy = buf + 1;
-          i < len && cpy < buf + sizeof (remcomOutBuffer) - 3; i++)
-       {
-         *cpy++ = hexchars[data[i] >> 4];
-         *cpy++ = hexchars[data[i] & 0x0F];
-       }
-      *cpy = 0;
-      putpacket (buf);
-    }
-  return len;
-}
-
-/* Function: gdb_puts(char *)
-   Make gdb write a null-terminated string to stdout.
-   Returns: the length of the string */
-
-static int
-gdb_puts (char *str)
-{
-  return gdb_write (str, strlen (str));
-}
-
-/* Function: gdb_error(char *, char *)
-   Send an error message to gdb's stdout.
-   First string may have 1 (one) optional "%s" in it, which
-   will cause the optional second string to be inserted.  */
-
-static void
-gdb_error (char *format, char *parm)
-{
-  char buf[400], *cpy;
-  int len;
-
-  if (remote_debug)
-    {
-      if (format && *format)
-       len = strlen (format);
-      else
-       return;                 /* empty input */
-
-      if (parm && *parm)
-       len += strlen (parm);
-
-      for (cpy = buf; *format;)
-       {
-         if (format[0] == '%' && format[1] == 's')     /* include second string */
-           {
-             format += 2;      /* advance two chars instead of just one */
-             while (parm && *parm)
-               *cpy++ = *parm++;
-           }
-         else
-           *cpy++ = *format++;
-       }
-      *cpy = '\0';
-      gdb_puts (buf);
-    }
-}
-
-static unsigned char *
-strcpy (unsigned char *dest, const unsigned char *src)
-{
-  unsigned char *ret = dest;
-
-  if (dest && src)
-    {
-      while (*src)
-       *dest++ = *src++;
-      *dest = 0;
-    }
-  return ret;
-}
-
-static int
-strlen (const unsigned char *src)
-{
-  int ret;
-
-  for (ret = 0; *src; src++)
-    ret++;
-
-  return ret;
-}
-
-#if 0
-void
-exit (code)
-     int code;
-{
-  _exit (code);
-}
-
-int
-atexit (void *p)
-{
-  return 0;
-}
-
-void
-abort (void)
-{
-  _exit (1);
-}
-#endif
diff --git a/gdb/m68k-stub.c b/gdb/m68k-stub.c
deleted file mode 100644 (file)
index 4ef4069..0000000
+++ /dev/null
@@ -1,1098 +0,0 @@
-/****************************************************************************
-
-               THIS SOFTWARE IS NOT COPYRIGHTED  
-   
-   HP offers the following for use in the public domain.  HP makes no
-   warranty with regard to the software or it's performance and the 
-   user accepts the software "AS IS" with all faults.
-
-   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
-   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-/****************************************************************************
- *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $                   
- *
- *  Module name: remcom.c $  
- *  Revision: 1.34 $
- *  Date: 91/03/09 12:29:49 $
- *  Contributor:     Lake Stevens Instrument Division$
- *  
- *  Description:     low level support for gdb debugger. $
- *
- *  Considerations:  only works on target hardware $
- *
- *  Written by:      Glenn Engel $
- *  ModuleState:     Experimental $ 
- *
- *  NOTES:           See Below $
- * 
- *  To enable debugger support, two things need to happen.  One, a
- *  call to set_debug_traps() is necessary in order to allow any breakpoints
- *  or error conditions to be properly intercepted and reported to gdb.
- *  Two, a breakpoint needs to be generated to begin communication.  This
- *  is most easily accomplished by a call to breakpoint().  Breakpoint()
- *  simulates a breakpoint by executing a trap #1.  The breakpoint instruction
- *  is hardwired to trap #1 because not to do so is a compatibility problem--
- *  there either should be a standard breakpoint instruction, or the protocol
- *  should be extended to provide some means to communicate which breakpoint
- *  instruction is in use (or have the stub insert the breakpoint).
- *  
- *  Some explanation is probably necessary to explain how exceptions are
- *  handled.  When an exception is encountered the 68000 pushes the current
- *  program counter and status register onto the supervisor stack and then
- *  transfers execution to a location specified in it's vector table.
- *  The handlers for the exception vectors are hardwired to jmp to an address
- *  given by the relation:  (exception - 256) * 6.  These are decending 
- *  addresses starting from -6, -12, -18, ...  By allowing 6 bytes for
- *  each entry, a jsr, jmp, bsr, ... can be used to enter the exception 
- *  handler.  Using a jsr to handle an exception has an added benefit of
- *  allowing a single handler to service several exceptions and use the
- *  return address as the key differentiation.  The vector number can be
- *  computed from the return address by [ exception = (addr + 1530) / 6 ].
- *  The sole purpose of the routine _catchException is to compute the
- *  exception number and push it on the stack in place of the return address.
- *  The external function exceptionHandler() is
- *  used to attach a specific handler to a specific m68k exception.
- *  For 68020 machines, the ability to have a return address around just
- *  so the vector can be determined is not necessary because the '020 pushes an
- *  extra word onto the stack containing the vector offset
- * 
- *  Because gdb will sometimes write to the stack area to execute function
- *  calls, this program cannot rely on using the supervisor stack so it
- *  uses it's own stack area reserved in the int array remcomStack.  
- * 
- *************
- *
- *    The following gdb commands are supported:
- * 
- * command          function                               Return value
- * 
- *    g             return the value of the CPU registers  hex data or ENN
- *    G             set the value of the CPU registers     OK or ENN
- * 
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
- * 
- *    c             Resume at current address              SNN   ( signal NN)
- *    cAA..AA       Continue at address AA..AA             SNN
- * 
- *    s             Step one instruction                   SNN
- *    sAA..AA       Step one instruction from AA..AA       SNN
- * 
- *    k             kill
- *
- *    ?             What was the last sigval ?             SNN   (signal NN)
- * 
- * All commands and responses are sent with a packet which includes a 
- * checksum.  A packet consists of 
- * 
- * $<packet info>#<checksum>.
- * 
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- * 
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer.  '-' indicates a failed transfer.
- * 
- * Example:
- * 
- * Host:                  Reply:
- * $m0,10#2a               +$00010203040506070809101112131415#42
- * 
- ****************************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-#include <setjmp.h>
-
-/************************************************************************
- *
- * external low-level support routines 
- */
-typedef void (*ExceptionHook)(int);   /* pointer to function with int parm */
-typedef void (*Function)();           /* pointer to a function */
-
-extern void putDebugChar();    /* write a single character      */
-extern int getDebugChar();     /* read and return a single char */
-
-extern Function exceptionHandler();  /* assign an exception handler */
-extern ExceptionHook exceptionHook;  /* hook variable for errors/exceptions */
-
-/************************/
-/* FORWARD DECLARATIONS */
-/************************/
-static void
-initializeRemcomErrorFrame ();
-
-/************************************************************************/
-/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-/* at least NUMREGBYTES*2 are needed for register packets */
-#define BUFMAX 400
-
-static char initialized;  /* boolean flag. != 0 means we've been initialized */
-
-int     remote_debug;
-/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */ 
-
-static const char hexchars[]="0123456789abcdef";
-
-/* there are 180 bytes of registers on a 68020 w/68881      */
-/* many of the fpa registers are 12 byte (96 bit) registers */
-#define NUMREGBYTES 180
-enum regnames {D0,D1,D2,D3,D4,D5,D6,D7, 
-               A0,A1,A2,A3,A4,A5,A6,A7, 
-               PS,PC,
-               FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
-               FPCONTROL,FPSTATUS,FPIADDR
-              };
-
-\f
-/* We keep a whole frame cache here.  "Why?", I hear you cry, "doesn't
-   GDB handle that sort of thing?"  Well, yes, I believe the only
-   reason for this cache is to save and restore floating point state
-   (fsave/frestore).  A cleaner way to do this would be to make the
- fsave data part of the registers which GDB deals with like any
-   other registers.  This should not be a performance problem if the
-   ability to read individual registers is added to the protocol.  */
-
-typedef struct FrameStruct
-{
-    struct FrameStruct  *previous;
-    int       exceptionPC;      /* pc value when this frame created */
-    int       exceptionVector;  /* cpu vector causing exception     */
-    short     frameSize;        /* size of cpu frame in words       */
-    short     sr;               /* for 68000, this not always sr    */
-    int       pc;
-    short     format;
-    int       fsaveHeader;
-    int       morejunk[0];        /* exception frame, fp save... */
-} Frame;
-
-#define FRAMESIZE 500
-int   gdbFrameStack[FRAMESIZE];
-static Frame *lastFrame;
-
-/*
- * these should not be static cuz they can be used outside this module
- */
-int registers[NUMREGBYTES/4];
-int superStack;
-
-#define STACKSIZE 10000
-int remcomStack[STACKSIZE/sizeof(int)];
-static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
-
-/*
- * In many cases, the system will want to continue exception processing
- * when a continue command is given.  
- * oldExceptionHook is a function to invoke in this case.
- */
-
-static ExceptionHook oldExceptionHook;
-
-#ifdef mc68020
-/* the size of the exception stack on the 68020 varies with the type of
- * exception.  The following table is the number of WORDS used
- * for each exception format.
- */
-const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
-#endif
-
-#ifdef mc68332
-static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 };
-#endif
-
-/************* jump buffer used for setjmp/longjmp **************************/
-jmp_buf remcomEnv;
-
-/***************************  ASSEMBLY CODE MACROS *************************/
-/*                                                                        */
-
-#ifdef __HAVE_68881__
-/* do an fsave, then remember the address to begin a restore from */
-#define SAVE_FP_REGS()    asm(" fsave   a0@-");                \
-                         asm(" fmovemx fp0-fp7,_registers+72");        \
-                         asm(" fmoveml fpcr/fpsr/fpi,_registers+168"); 
-#define RESTORE_FP_REGS()                              \
-asm("                                                \n\
-    fmoveml  _registers+168,fpcr/fpsr/fpi            \n\
-    fmovemx  _registers+72,fp0-fp7                   \n\
-    cmpl     #-1,a0@     |  skip frestore flag set ? \n\
-    beq      skip_frestore                           \n\
-    frestore a0@+                                    \n\
-skip_frestore:                                       \n\
-");
-
-#else
-#define SAVE_FP_REGS()
-#define RESTORE_FP_REGS()
-#endif /* __HAVE_68881__ */
-
-void return_to_super();
-void return_to_user();
-
-asm("
-.text
-.globl _return_to_super
-_return_to_super:
-        movel   _registers+60,sp /* get new stack pointer */        
-        movel   _lastFrame,a0   /* get last frame info  */              
-        bra     return_to_any
-
-.globl _return_to_user
-_return_to_user:
-        movel   _registers+60,a0 /* get usp */                          
-        movel   a0,usp           /* set usp */                         
-        movel   _superStack,sp  /* get original stack pointer */        
-
-return_to_any:
-        movel   _lastFrame,a0   /* get last frame info  */              
-        movel   a0@+,_lastFrame /* link in previous frame     */        
-        addql   #8,a0           /* skip over pc, vector#*/              
-        movew   a0@+,d0         /* get # of words in cpu frame */       
-        addw    d0,a0           /* point to end of data        */       
-        addw    d0,a0           /* point to end of data        */       
-        movel   a0,a1                                                   
-#                                                                       
-# copy the stack frame                                                  
-        subql   #1,d0                                                   
-copyUserLoop:                                                               
-        movew   a1@-,sp@-                                               
-        dbf     d0,copyUserLoop                                             
-");                                                                     
-        RESTORE_FP_REGS()                                              
-   asm("   moveml  _registers,d0-d7/a0-a6");                           
-   asm("   rte");  /* pop and go! */                                    
-
-#define DISABLE_INTERRUPTS()   asm("         oriw   #0x0700,sr");
-#define BREAKPOINT() asm("   trap #1");
-
-/* this function is called immediately when a level 7 interrupt occurs */
-/* if the previous interrupt level was 7 then we're already servicing  */
-/* this interrupt and an rte is in order to return to the debugger.    */
-/* For the 68000, the offset for sr is 6 due to the jsr return address */
-asm("
-.text
-.globl __debug_level7
-__debug_level7:
-       movew   d0,sp@-");
-#if defined (mc68020) || defined (mc68332)
-asm("  movew   sp@(2),d0");
-#else
-asm("  movew   sp@(6),d0");
-#endif
-asm("  andiw   #0x700,d0
-       cmpiw   #0x700,d0
-       beq     _already7
-        movew   sp@+,d0        
-        bra     __catchException
-_already7:
-       movew   sp@+,d0");
-#if !defined (mc68020) && !defined (mc68332)
-asm("  lea     sp@(4),sp");     /* pull off 68000 return address */
-#endif
-asm("  rte");
-
-extern void _catchException ();
-
-#if defined (mc68020) || defined (mc68332)
-/* This function is called when a 68020 exception occurs.  It saves
- * all the cpu and fpcp regs in the _registers array, creates a frame on a
- * linked list of frames which has the cpu and fpcp stack frames needed
- * to properly restore the context of these processors, and invokes
- * an exception handler (remcom_handler).
- *
- * stack on entry:                       stack on exit:
- *   N bytes of junk                     exception # MSWord
- *   Exception Format Word               exception # MSWord
- *   Program counter LSWord              
- *   Program counter MSWord             
- *   Status Register                    
- *                                       
- *                                       
- */
-asm(" 
-.text
-.globl __catchException
-__catchException:");
-DISABLE_INTERRUPTS();
-asm("
-        moveml  d0-d7/a0-a6,_registers /* save registers        */
-       movel   _lastFrame,a0   /* last frame pointer */
-");
-SAVE_FP_REGS();        
-asm("
-       lea     _registers,a5   /* get address of registers     */
-        movew   sp@,d1          /* get status register          */
-        movew   d1,a5@(66)      /* save sr                     */      
-       movel   sp@(2),a4       /* save pc in a4 for later use  */
-        movel   a4,a5@(68)      /* save pc in _regisers[]              */
-
-#
-# figure out how many bytes in the stack frame
-       movew   sp@(6),d0       /* get '020 exception format    */
-        movew   d0,d2           /* make a copy of format word   */
-        andiw   #0xf000,d0      /* mask off format type         */
-        rolw    #5,d0           /* rotate into the low byte *2  */
-        lea     _exceptionSize,a1   
-        addw    d0,a1           /* index into the table         */
-       movew   a1@,d0          /* get number of words in frame */
-        movew   d0,d3           /* save it                      */
-        subw    d0,a0          /* adjust save pointer          */
-        subw    d0,a0          /* adjust save pointer(bytes)   */
-       movel   a0,a1           /* copy save pointer            */
-       subql   #1,d0           /* predecrement loop counter    */
-#
-# copy the frame
-saveFrameLoop:
-       movew   sp@+,a1@+
-       dbf     d0,saveFrameLoop
-#
-# now that the stack has been clenaed,
-# save the a7 in use at time of exception
-        movel   sp,_superStack  /* save supervisor sp           */
-        andiw   #0x2000,d1      /* were we in supervisor mode ? */
-        beq     userMode       
-        movel   a7,a5@(60)      /* save a7                  */
-        bra     a7saveDone
-userMode:  
-       movel   usp,a1          
-        movel   a1,a5@(60)      /* save user stack pointer     */
-a7saveDone:
-
-#
-# save size of frame
-        movew   d3,a0@-
-
-#
-# compute exception number
-       andl    #0xfff,d2       /* mask off vector offset       */
-       lsrw    #2,d2           /* divide by 4 to get vect num  */
-        movel   d2,a0@-         /* save it                      */
-#
-# save pc causing exception
-        movel   a4,a0@-
-#
-# save old frame link and set the new value
-       movel   _lastFrame,a1   /* last frame pointer */
-       movel   a1,a0@-         /* save pointer to prev frame   */
-        movel   a0,_lastFrame
-
-        movel   d2,sp@-                /* push exception num           */
-       movel   _exceptionHook,a0  /* get address of handler */
-        jbsr    a0@             /* and call it */
-        clrl    sp@             /* replace exception num parm with frame ptr */
-        jbsr     __returnFromException   /* jbsr, but never returns */
-");
-#else /* mc68000 */
-/* This function is called when an exception occurs.  It translates the
- * return address found on the stack into an exception vector # which
- * is then handled by either handle_exception or a system handler.
- * _catchException provides a front end for both.  
- *
- * stack on entry:                       stack on exit:
- *   Program counter MSWord              exception # MSWord 
- *   Program counter LSWord              exception # MSWord
- *   Status Register                     
- *   Return Address  MSWord              
- *   Return Address  LSWord             
- */
-asm("
-.text
-.globl __catchException
-__catchException:");
-DISABLE_INTERRUPTS();
-asm("
-        moveml d0-d7/a0-a6,_registers  /* save registers               */
-       movel   _lastFrame,a0   /* last frame pointer */
-");
-SAVE_FP_REGS();        
-asm("
-        lea     _registers,a5   /* get address of registers     */
-        movel   sp@+,d2         /* pop return address           */
-       addl    #1530,d2        /* convert return addr to       */
-       divs    #6,d2           /*  exception number            */
-       extl    d2   
-
-        moveql  #3,d3           /* assume a three word frame     */
-
-        cmpiw   #3,d2           /* bus error or address error ? */
-        bgt     normal          /* if >3 then normal error      */
-        movel   sp@+,a0@-       /* copy error info to frame buff*/
-        movel   sp@+,a0@-       /* these are never used         */
-        moveql  #7,d3           /* this is a 7 word frame       */
-     
-normal:   
-       movew   sp@+,d1         /* pop status register          */
-        movel   sp@+,a4         /* pop program counter          */
-        movew   d1,a5@(66)      /* save sr                     */      
-        movel   a4,a5@(68)      /* save pc in _regisers[]              */
-        movel   a4,a0@-         /* copy pc to frame buffer      */
-       movew   d1,a0@-         /* copy sr to frame buffer      */
-
-        movel   sp,_superStack  /* save supervisor sp          */
-
-        andiw   #0x2000,d1      /* were we in supervisor mode ? */
-        beq     userMode       
-        movel   a7,a5@(60)      /* save a7                  */
-        bra     saveDone             
-userMode:
-        movel   usp,a1         /* save user stack pointer      */
-        movel   a1,a5@(60)      /* save user stack pointer     */
-saveDone:
-
-        movew   d3,a0@-         /* push frame size in words     */
-        movel   d2,a0@-         /* push vector number           */
-        movel   a4,a0@-         /* push exception pc            */
-
-#
-# save old frame link and set the new value
-       movel   _lastFrame,a1   /* last frame pointer */
-       movel   a1,a0@-         /* save pointer to prev frame   */
-        movel   a0,_lastFrame
-
-        movel   d2,sp@-                /* push exception num           */
-       movel   _exceptionHook,a0  /* get address of handler */
-        jbsr    a0@             /* and call it */
-        clrl    sp@             /* replace exception num parm with frame ptr */
-        jbsr     __returnFromException   /* jbsr, but never returns */
-");
-#endif
-
-
-/*
- * remcomHandler is a front end for handle_exception.  It moves the
- * stack pointer into an area reserved for debugger use in case the
- * breakpoint happened in supervisor mode.
- */
-asm("_remcomHandler:");
-asm("           addl    #4,sp");        /* pop off return address     */
-asm("           movel   sp@+,d0");      /* get the exception number   */
-asm("          movel   _stackPtr,sp"); /* move to remcom stack area  */
-asm("          movel   d0,sp@-");      /* push exception onto stack  */
-asm("          jbsr    _handle_exception");    /* this never returns */
-asm("           rts");                  /* return */
-
-void
-_returnFromException (Frame * frame)
-{
-  /* if no passed in frame, use the last one */
-  if (!frame)
-    {
-      frame = lastFrame;
-      frame->frameSize = 4;
-      frame->format = 0;
-      frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info */
-    }
-
-#if !defined (mc68020) && !defined (mc68332)
-  /* a 68000 cannot use the internal info pushed onto a bus error
-   * or address error frame when doing an RTE so don't put this info
-   * onto the stack or the stack will creep every time this happens.
-   */
-  frame->frameSize = 3;
-#endif
-
-  /* throw away any frames in the list after this frame */
-  lastFrame = frame;
-
-  frame->sr = registers[(int) PS];
-  frame->pc = registers[(int) PC];
-
-  if (registers[(int) PS] & 0x2000)
-    {
-      /* return to supervisor mode... */
-      return_to_super ();
-    }
-  else
-    {                          /* return to user mode */
-      return_to_user ();
-    }
-}
-
-int
-hex (ch)
-     char ch;
-{
-  if ((ch >= 'a') && (ch <= 'f'))
-    return (ch - 'a' + 10);
-  if ((ch >= '0') && (ch <= '9'))
-    return (ch - '0');
-  if ((ch >= 'A') && (ch <= 'F'))
-    return (ch - 'A' + 10);
-  return (-1);
-}
-
-static char remcomInBuffer[BUFMAX];
-static char remcomOutBuffer[BUFMAX];
-
-/* scan for the sequence $<data>#<checksum>     */
-
-unsigned char *
-getpacket (void)
-{
-  unsigned char *buffer = &remcomInBuffer[0];
-  unsigned char checksum;
-  unsigned char xmitcsum;
-  int count;
-  char ch;
-
-  while (1)
-    {
-      /* wait around for the start character, ignore all other characters */
-      while ((ch = getDebugChar ()) != '$')
-       ;
-
-    retry:
-      checksum = 0;
-      xmitcsum = -1;
-      count = 0;
-
-      /* now, read until a # or end of buffer is found */
-      while (count < BUFMAX - 1)
-       {
-         ch = getDebugChar ();
-         if (ch == '$')
-           goto retry;
-         if (ch == '#')
-           break;
-         checksum = checksum + ch;
-         buffer[count] = ch;
-         count = count + 1;
-       }
-      buffer[count] = 0;
-
-      if (ch == '#')
-       {
-         ch = getDebugChar ();
-         xmitcsum = hex (ch) << 4;
-         ch = getDebugChar ();
-         xmitcsum += hex (ch);
-
-         if (checksum != xmitcsum)
-           {
-             if (remote_debug)
-               {
-                 fprintf (stderr,
-                          "bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
-                          checksum, xmitcsum, buffer);
-               }
-             putDebugChar ('-');       /* failed checksum */
-           }
-         else
-           {
-             putDebugChar ('+');       /* successful transfer */
-
-             /* if a sequence char is present, reply the sequence ID */
-             if (buffer[2] == ':')
-               {
-                 putDebugChar (buffer[0]);
-                 putDebugChar (buffer[1]);
-
-                 return &buffer[3];
-               }
-
-             return &buffer[0];
-           }
-       }
-    }
-}
-
-/* send the packet in buffer. */
-
-void
-putpacket (buffer)
-     char *buffer;
-{
-  unsigned char checksum;
-  int count;
-  char ch;
-
-  /*  $<packet info>#<checksum>. */
-  do
-    {
-      putDebugChar ('$');
-      checksum = 0;
-      count = 0;
-
-      while (ch = buffer[count])
-       {
-         putDebugChar (ch);
-         checksum += ch;
-         count += 1;
-       }
-
-      putDebugChar ('#');
-      putDebugChar (hexchars[checksum >> 4]);
-      putDebugChar (hexchars[checksum % 16]);
-
-    }
-  while (getDebugChar () != '+');
-
-}
-
-void
-debug_error (format, parm)
-     char *format;
-     char *parm;
-{
-  if (remote_debug)
-    fprintf (stderr, format, parm);
-}
-
-/* convert the memory pointed to by mem into hex, placing result in buf */
-/* return a pointer to the last char put in buf (null) */
-char *
-mem2hex (mem, buf, count)
-     char *mem;
-     char *buf;
-     int count;
-{
-  int i;
-  unsigned char ch;
-  for (i = 0; i < count; i++)
-    {
-      ch = *mem++;
-      *buf++ = hexchars[ch >> 4];
-      *buf++ = hexchars[ch % 16];
-    }
-  *buf = 0;
-  return (buf);
-}
-
-/* convert the hex array pointed to by buf into binary to be placed in mem */
-/* return a pointer to the character AFTER the last byte written */
-char *
-hex2mem (buf, mem, count)
-     char *buf;
-     char *mem;
-     int count;
-{
-  int i;
-  unsigned char ch;
-  for (i = 0; i < count; i++)
-    {
-      ch = hex (*buf++) << 4;
-      ch = ch + hex (*buf++);
-      *mem++ = ch;
-    }
-  return (mem);
-}
-
-/* a bus error has occurred, perform a longjmp
-   to return execution and allow handling of the error */
-
-void
-handle_buserror ()
-{
-  longjmp (remcomEnv, 1);
-}
-
-/* this function takes the 68000 exception number and attempts to 
-   translate this number into a unix compatible signal value */
-int
-computeSignal (exceptionVector)
-     int exceptionVector;
-{
-  int sigval;
-  switch (exceptionVector)
-    {
-    case 2:
-      sigval = 10;
-      break;                   /* bus error           */
-    case 3:
-      sigval = 10;
-      break;                   /* address error       */
-    case 4:
-      sigval = 4;
-      break;                   /* illegal instruction */
-    case 5:
-      sigval = 8;
-      break;                   /* zero divide         */
-    case 6:
-      sigval = 8;
-      break;                   /* chk instruction     */
-    case 7:
-      sigval = 8;
-      break;                   /* trapv instruction   */
-    case 8:
-      sigval = 11;
-      break;                   /* privilege violation */
-    case 9:
-      sigval = 5;
-      break;                   /* trace trap          */
-    case 10:
-      sigval = 4;
-      break;                   /* line 1010 emulator  */
-    case 11:
-      sigval = 4;
-      break;                   /* line 1111 emulator  */
-
-      /* Coprocessor protocol violation.  Using a standard MMU or FPU
-         this cannot be triggered by software.  Call it a SIGBUS.  */
-    case 13:
-      sigval = 10;
-      break;
-
-    case 31:
-      sigval = 2;
-      break;                   /* interrupt           */
-    case 33:
-      sigval = 5;
-      break;                   /* breakpoint          */
-
-      /* This is a trap #8 instruction.  Apparently it is someone's software
-         convention for some sort of SIGFPE condition.  Whose?  How many
-         people are being screwed by having this code the way it is?
-         Is there a clean solution?  */
-    case 40:
-      sigval = 8;
-      break;                   /* floating point err  */
-
-    case 48:
-      sigval = 8;
-      break;                   /* floating point err  */
-    case 49:
-      sigval = 8;
-      break;                   /* floating point err  */
-    case 50:
-      sigval = 8;
-      break;                   /* zero divide         */
-    case 51:
-      sigval = 8;
-      break;                   /* underflow           */
-    case 52:
-      sigval = 8;
-      break;                   /* operand error       */
-    case 53:
-      sigval = 8;
-      break;                   /* overflow            */
-    case 54:
-      sigval = 8;
-      break;                   /* NAN                 */
-    default:
-      sigval = 7;              /* "software generated" */
-    }
-  return (sigval);
-}
-
-/**********************************************/
-/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-/* RETURN NUMBER OF CHARS PROCESSED           */
-/**********************************************/
-int
-hexToInt (char **ptr, int *intValue)
-{
-  int numChars = 0;
-  int hexValue;
-
-  *intValue = 0;
-
-  while (**ptr)
-    {
-      hexValue = hex (**ptr);
-      if (hexValue >= 0)
-       {
-         *intValue = (*intValue << 4) | hexValue;
-         numChars++;
-       }
-      else
-       break;
-
-      (*ptr)++;
-    }
-
-  return (numChars);
-}
-
-/*
- * This function does all command procesing for interfacing to gdb.
- */
-void
-handle_exception (int exceptionVector)
-{
-  int sigval, stepping;
-  int addr, length;
-  char *ptr;
-  int newPC;
-  Frame *frame;
-
-  if (remote_debug)
-    printf ("vector=%d, sr=0x%x, pc=0x%x\n",
-           exceptionVector, registers[PS], registers[PC]);
-
-  /* reply to host that an exception has occurred */
-  sigval = computeSignal (exceptionVector);
-  remcomOutBuffer[0] = 'S';
-  remcomOutBuffer[1] = hexchars[sigval >> 4];
-  remcomOutBuffer[2] = hexchars[sigval % 16];
-  remcomOutBuffer[3] = 0;
-
-  putpacket (remcomOutBuffer);
-
-  stepping = 0;
-
-  while (1 == 1)
-    {
-      remcomOutBuffer[0] = 0;
-      ptr = getpacket ();
-      switch (*ptr++)
-       {
-       case '?':
-         remcomOutBuffer[0] = 'S';
-         remcomOutBuffer[1] = hexchars[sigval >> 4];
-         remcomOutBuffer[2] = hexchars[sigval % 16];
-         remcomOutBuffer[3] = 0;
-         break;
-       case 'd':
-         remote_debug = !(remote_debug);       /* toggle debug flag */
-         break;
-       case 'g':               /* return the value of the CPU registers */
-         mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
-         break;
-       case 'G':               /* set the value of the CPU registers - return OK */
-         hex2mem (ptr, (char *) registers, NUMREGBYTES);
-         strcpy (remcomOutBuffer, "OK");
-         break;
-
-         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
-       case 'm':
-         if (setjmp (remcomEnv) == 0)
-           {
-             exceptionHandler (2, handle_buserror);
-
-             /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
-             if (hexToInt (&ptr, &addr))
-               if (*(ptr++) == ',')
-                 if (hexToInt (&ptr, &length))
-                   {
-                     ptr = 0;
-                     mem2hex ((char *) addr, remcomOutBuffer, length);
-                   }
-
-             if (ptr)
-               {
-                 strcpy (remcomOutBuffer, "E01");
-               }
-           }
-         else
-           {
-             exceptionHandler (2, _catchException);
-             strcpy (remcomOutBuffer, "E03");
-             debug_error ("bus error");
-           }
-
-         /* restore handler for bus error */
-         exceptionHandler (2, _catchException);
-         break;
-
-         /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
-       case 'M':
-         if (setjmp (remcomEnv) == 0)
-           {
-             exceptionHandler (2, handle_buserror);
-
-             /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
-             if (hexToInt (&ptr, &addr))
-               if (*(ptr++) == ',')
-                 if (hexToInt (&ptr, &length))
-                   if (*(ptr++) == ':')
-                     {
-                       hex2mem (ptr, (char *) addr, length);
-                       ptr = 0;
-                       strcpy (remcomOutBuffer, "OK");
-                     }
-             if (ptr)
-               {
-                 strcpy (remcomOutBuffer, "E02");
-               }
-           }
-         else
-           {
-             exceptionHandler (2, _catchException);
-             strcpy (remcomOutBuffer, "E03");
-             debug_error ("bus error");
-           }
-
-         /* restore handler for bus error */
-         exceptionHandler (2, _catchException);
-         break;
-
-         /* cAA..AA    Continue at address AA..AA(optional) */
-         /* sAA..AA   Step one instruction from AA..AA(optional) */
-       case 's':
-         stepping = 1;
-       case 'c':
-         /* try to read optional parameter, pc unchanged if no parm */
-         if (hexToInt (&ptr, &addr))
-           registers[PC] = addr;
-
-         newPC = registers[PC];
-
-         /* clear the trace bit */
-         registers[PS] &= 0x7fff;
-
-         /* set the trace bit if we're stepping */
-         if (stepping)
-           registers[PS] |= 0x8000;
-
-         /*
-          * look for newPC in the linked list of exception frames.
-          * if it is found, use the old frame it.  otherwise,
-          * fake up a dummy frame in returnFromException().
-          */
-         if (remote_debug)
-           printf ("new pc = 0x%x\n", newPC);
-         frame = lastFrame;
-         while (frame)
-           {
-             if (remote_debug)
-               printf ("frame at 0x%x has pc=0x%x, except#=%d\n",
-                       frame, frame->exceptionPC, frame->exceptionVector);
-             if (frame->exceptionPC == newPC)
-               break;          /* bingo! a match */
-             /*
-              * for a breakpoint instruction, the saved pc may
-              * be off by two due to re-executing the instruction
-              * replaced by the trap instruction.  Check for this.
-              */
-             if ((frame->exceptionVector == 33) &&
-                 (frame->exceptionPC == (newPC + 2)))
-               break;
-             if (frame == frame->previous)
-               {
-                 frame = 0;    /* no match found */
-                 break;
-               }
-             frame = frame->previous;
-           }
-
-         /*
-          * If we found a match for the PC AND we are not returning
-          * as a result of a breakpoint (33),
-          * trace exception (9), nmi (31), jmp to
-          * the old exception handler as if this code never ran.
-          */
-         if (frame)
-           {
-             if ((frame->exceptionVector != 9) &&
-                 (frame->exceptionVector != 31) &&
-                 (frame->exceptionVector != 33))
-               {
-                 /*
-                  * invoke the previous handler.
-                  */
-                 if (oldExceptionHook)
-                   (*oldExceptionHook) (frame->exceptionVector);
-                 newPC = registers[PC];        /* pc may have changed  */
-                 if (newPC != frame->exceptionPC)
-                   {
-                     if (remote_debug)
-                       printf ("frame at 0x%x has pc=0x%x, except#=%d\n",
-                               frame, frame->exceptionPC,
-                               frame->exceptionVector);
-                     /* re-use the last frame, we're skipping it (longjump?) */
-                     frame = (Frame *) 0;
-                     _returnFromException (frame);     /* this is a jump */
-                   }
-               }
-           }
-
-         /* if we couldn't find a frame, create one */
-         if (frame == 0)
-           {
-             frame = lastFrame - 1;
-
-             /* by using a bunch of print commands with breakpoints,
-                it's possible for the frame stack to creep down.  If it creeps
-                too far, give up and reset it to the top.  Normal use should
-                not see this happen.
-              */
-             if ((unsigned int) (frame - 2) < (unsigned int) &gdbFrameStack)
-               {
-                 initializeRemcomErrorFrame ();
-                 frame = lastFrame;
-               }
-             frame->previous = lastFrame;
-             lastFrame = frame;
-             frame = 0;        /* null so _return... will properly initialize it */
-           }
-
-         _returnFromException (frame); /* this is a jump */
-
-         break;
-
-         /* kill the program */
-       case 'k':               /* do nothing */
-         break;
-       }                       /* switch */
-
-      /* reply to the request */
-      putpacket (remcomOutBuffer);
-    }
-}
-
-
-void
-initializeRemcomErrorFrame (void)
-{
-  lastFrame = ((Frame *) & gdbFrameStack[FRAMESIZE - 1]) - 1;
-  lastFrame->previous = lastFrame;
-}
-
-/* this function is used to set up exception handlers for tracing and 
-   breakpoints */
-void
-set_debug_traps ()
-{
-  extern void _debug_level7 ();
-  extern void remcomHandler ();
-  int exception;
-
-  initializeRemcomErrorFrame ();
-  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
-
-  for (exception = 2; exception <= 23; exception++)
-    exceptionHandler (exception, _catchException);
-
-  /* level 7 interrupt              */
-  exceptionHandler (31, _debug_level7);
-
-  /* breakpoint exception (trap #1) */
-  exceptionHandler (33, _catchException);
-
-  /* This is a trap #8 instruction.  Apparently it is someone's software
-     convention for some sort of SIGFPE condition.  Whose?  How many
-     people are being screwed by having this code the way it is?
-     Is there a clean solution?  */
-  exceptionHandler (40, _catchException);
-
-  /* 48 to 54 are floating point coprocessor errors */
-  for (exception = 48; exception <= 54; exception++)
-    exceptionHandler (exception, _catchException);
-
-  if (oldExceptionHook != remcomHandler)
-    {
-      oldExceptionHook = exceptionHook;
-      exceptionHook = remcomHandler;
-    }
-
-  initialized = 1;
-
-}
-
-/* This function will generate a breakpoint exception.  It is used at the
-   beginning of a program to sync up with a debugger and can be used
-   otherwise as a quick means to stop program execution and "break" into
-   the debugger. */
-
-void
-breakpoint ()
-{
-  if (initialized)
-    BREAKPOINT ();
-}
diff --git a/gdb/sh-stub.c b/gdb/sh-stub.c
deleted file mode 100644 (file)
index 76c98a5..0000000
+++ /dev/null
@@ -1,1583 +0,0 @@
-/* sh-stub.c -- debugging stub for the Renesas-SH.
-
- NOTE!! This code has to be compiled with optimization, otherwise the 
- function inlining which generates the exception handlers won't work.
-
-*/
-
-/*   This is originally based on an m68k software stub written by Glenn
-     Engel at HP, but has changed quite a bit. 
-
-     Modifications for the SH by Ben Lee and Steve Chamberlain
-
-*/
-
-/****************************************************************************
-
-               THIS SOFTWARE IS NOT COPYRIGHTED
-
-   HP offers the following for use in the public domain.  HP makes no
-   warranty with regard to the software or it's performance and the
-   user accepts the software "AS IS" with all faults.
-
-   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
-   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-
-/* Remote communication protocol.
-
-   A debug packet whose contents are <data>
-   is encapsulated for transmission in the form:
-
-       $ <data> # CSUM1 CSUM2
-
-       <data> must be ASCII alphanumeric and cannot include characters
-       '$' or '#'.  If <data> starts with two characters followed by
-       ':', then the existing stubs interpret this as a sequence number.
-
-       CSUM1 and CSUM2 are ascii hex representation of an 8-bit 
-       checksum of <data>, the most significant nibble is sent first.
-       the hex digits 0-9,a-f are used.
-
-   Receiver responds with:
-
-       +       - if CSUM is correct and ready for next packet
-       -       - if CSUM is incorrect
-
-   <data> is as follows:
-   All values are encoded in ascii hex digits.
-
-       Request         Packet
-
-       read registers  g
-       reply           XX....X         Each byte of register data
-                                       is described by two hex digits.
-                                       Registers are in the internal order
-                                       for GDB, and the bytes in a register
-                                       are in the same order the machine uses.
-                       or ENN          for an error.
-
-       write regs      GXX..XX         Each byte of register data
-                                       is described by two hex digits.
-       reply           OK              for success
-                       ENN             for an error
-
-        write reg      Pn...=r...      Write register n... with value r...,
-                                       which contains two hex digits for each
-                                       byte in the register (target byte
-                                       order).
-       reply           OK              for success
-                       ENN             for an error
-       (not supported by all stubs).
-
-       read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.
-       reply           XX..XX          XX..XX is mem contents
-                                       Can be fewer bytes than requested
-                                       if able to read only part of the data.
-                       or ENN          NN is errno
-
-       write mem       MAA..AA,LLLL:XX..XX
-                                       AA..AA is address,
-                                       LLLL is number of bytes,
-                                       XX..XX is data
-       reply           OK              for success
-                       ENN             for an error (this includes the case
-                                       where only part of the data was
-                                       written).
-
-       cont            cAA..AA         AA..AA is address to resume
-                                       If AA..AA is omitted,
-                                       resume at same address.
-
-       step            sAA..AA         AA..AA is address to resume
-                                       If AA..AA is omitted,
-                                       resume at same address.
-
-       last signal     ?               Reply the current reason for stopping.
-                                        This is the same reply as is generated
-                                       for step or cont : SAA where AA is the
-                                       signal number.
-
-       There is no immediate reply to step or cont.
-       The reply comes when the machine stops.
-       It is           SAA             AA is the "signal number"
-
-       or...           TAAn...:r...;n:r...;n...:r...;
-                                       AA = signal number
-                                       n... = register number
-                                       r... = register contents
-       or...           WAA             The process exited, and AA is
-                                       the exit status.  This is only
-                                       applicable for certains sorts of
-                                       targets.
-       kill request    k
-
-       toggle debug    d               toggle debug flag (see 386 & 68k stubs)
-       reset           r               reset -- see sparc stub.
-       reserved        <other>         On other requests, the stub should
-                                       ignore the request and send an empty
-                                       response ($#<checksum>).  This way
-                                       we can extend the protocol and GDB
-                                       can tell whether the stub it is
-                                       talking to uses the old or the new.
-       search          tAA:PP,MM       Search backwards starting at address
-                                       AA for a match with pattern PP and
-                                       mask MM.  PP and MM are 4 bytes.
-                                       Not supported by all stubs.
-
-       general query   qXXXX           Request info about XXXX.
-       general set     QXXXX=yyyy      Set value of XXXX to yyyy.
-       query sect offs qOffsets        Get section offsets.  Reply is
-                                       Text=xxx;Data=yyy;Bss=zzz
-       console output  Otext           Send text to stdout.  Only comes from
-                                       remote target.
-
-       Responses can be run-length encoded to save space.  A '*' means that
-       the next character is an ASCII encoding giving a repeat count which
-       stands for that many repititions of the character preceding the '*'.
-       The encoding is n+29, yielding a printable character where n >=3 
-       (which is where rle starts to win).  Don't use an n > 126. 
-
-       So 
-       "0* " means the same as "0000".  */
-
-#include <string.h>
-#include <setjmp.h>
-
-/* Renesas SH architecture instruction encoding masks */
-
-#define COND_BR_MASK   0xff00
-#define UCOND_DBR_MASK 0xe000
-#define UCOND_RBR_MASK 0xf0df
-#define TRAPA_MASK     0xff00
-
-#define COND_DISP      0x00ff
-#define UCOND_DISP     0x0fff
-#define UCOND_REG      0x0f00
-
-/* Renesas SH instruction opcodes */
-
-#define BF_INSTR       0x8b00
-#define BT_INSTR       0x8900
-#define BRA_INSTR      0xa000
-#define BSR_INSTR      0xb000
-#define JMP_INSTR      0x402b
-#define JSR_INSTR      0x400b
-#define RTS_INSTR      0x000b
-#define RTE_INSTR      0x002b
-#define TRAPA_INSTR    0xc300
-#define SSTEP_INSTR    0xc3ff
-
-/* Renesas SH processor register masks */
-
-#define T_BIT_MASK     0x0001
-
-/*
- * BUFMAX defines the maximum number of characters in inbound/outbound
- * buffers. At least NUMREGBYTES*2 are needed for register packets.
- */
-#define BUFMAX 1024
-
-/*
- * Number of bytes for registers
- */
-#define NUMREGBYTES 112                /* 92 */
-
-/*
- * typedef
- */
-typedef void (*Function) ();
-
-/*
- * Forward declarations
- */
-
-static int hex (char);
-static char *mem2hex (char *, char *, int);
-static char *hex2mem (char *, char *, int);
-static int hexToInt (char **, int *);
-static unsigned char *getpacket (void);
-static void putpacket (char *);
-static void handle_buserror (void);
-static int computeSignal (int exceptionVector);
-static void handle_exception (int exceptionVector);
-void init_serial();
-
-void putDebugChar (char);
-char getDebugChar (void);
-
-/* These are in the file but in asm statements so the compiler can't see them */
-void catch_exception_4 (void);
-void catch_exception_6 (void);
-void catch_exception_9 (void);
-void catch_exception_10 (void);
-void catch_exception_11 (void);
-void catch_exception_32 (void);
-void catch_exception_33 (void);
-void catch_exception_255 (void);
-
-
-
-#define catch_exception_random catch_exception_255 /* Treat all odd ones like 255 */
-
-void breakpoint (void);
-
-
-#define init_stack_size 8*1024  /* if you change this you should also modify BINIT */
-#define stub_stack_size 8*1024
-
-int init_stack[init_stack_size] __attribute__ ((section ("stack"))) = {0};
-int stub_stack[stub_stack_size] __attribute__ ((section ("stack"))) = {0};
-
-
-void INIT ();
-void BINIT ();
-
-#define CPU_BUS_ERROR_VEC  9
-#define DMA_BUS_ERROR_VEC 10
-#define NMI_VEC           11
-#define INVALID_INSN_VEC   4
-#define INVALID_SLOT_VEC   6
-#define TRAP_VEC          32
-#define IO_VEC            33
-#define USER_VEC         255
-
-
-
-char in_nmi;   /* Set when handling an NMI, so we don't reenter */
-int dofault;  /* Non zero, bus errors will raise exception */
-
-int *stub_sp;
-
-/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
-int remote_debug;
-
-/* jump buffer used for setjmp/longjmp */
-jmp_buf remcomEnv;
-
-enum regnames
-  {
-    R0, R1, R2, R3, R4, R5, R6, R7,
-    R8, R9, R10, R11, R12, R13, R14,
-    R15, PC, PR, GBR, VBR, MACH, MACL, SR,
-    TICKS, STALLS, CYCLES, INSTS, PLR
-  };
-
-typedef struct
-  {
-    short *memAddr;
-    short oldInstr;
-  }
-stepData;
-
-int registers[NUMREGBYTES / 4];
-stepData instrBuffer;
-char stepped;
-static const char hexchars[] = "0123456789abcdef";
-static char remcomInBuffer[BUFMAX];
-static char remcomOutBuffer[BUFMAX];
-
-char highhex(int  x)
-{
-  return hexchars[(x >> 4) & 0xf];
-}
-
-char lowhex(int  x)
-{
-  return hexchars[x & 0xf];
-}
-
-/*
- * Assembly macros
- */
-
-#define BREAKPOINT()   asm("trapa      #0x20"::);
-
-
-/*
- * Routines to handle hex data
- */
-
-static int
-hex (char ch)
-{
-  if ((ch >= 'a') && (ch <= 'f'))
-    return (ch - 'a' + 10);
-  if ((ch >= '0') && (ch <= '9'))
-    return (ch - '0');
-  if ((ch >= 'A') && (ch <= 'F'))
-    return (ch - 'A' + 10);
-  return (-1);
-}
-
-/* convert the memory, pointed to by mem into hex, placing result in buf */
-/* return a pointer to the last char put in buf (null) */
-static char *
-mem2hex (char *mem, char *buf, int count)
-{
-  int i;
-  int ch;
-  for (i = 0; i < count; i++)
-    {
-      ch = *mem++;
-      *buf++ = highhex (ch);
-      *buf++ = lowhex (ch);
-    }
-  *buf = 0;
-  return (buf);
-}
-
-/* convert the hex array pointed to by buf into binary, to be placed in mem */
-/* return a pointer to the character after the last byte written */
-
-static char *
-hex2mem (char *buf, char *mem, int count)
-{
-  int i;
-  unsigned char ch;
-  for (i = 0; i < count; i++)
-    {
-      ch = hex (*buf++) << 4;
-      ch = ch + hex (*buf++);
-      *mem++ = ch;
-    }
-  return (mem);
-}
-
-/**********************************************/
-/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-/* RETURN NUMBER OF CHARS PROCESSED           */
-/**********************************************/
-static int
-hexToInt (char **ptr, int *intValue)
-{
-  int numChars = 0;
-  int hexValue;
-
-  *intValue = 0;
-
-  while (**ptr)
-    {
-      hexValue = hex (**ptr);
-      if (hexValue >= 0)
-       {
-         *intValue = (*intValue << 4) | hexValue;
-         numChars++;
-       }
-      else
-       break;
-
-      (*ptr)++;
-    }
-
-  return (numChars);
-}
-
-/*
- * Routines to get and put packets
- */
-
-/* scan for the sequence $<data>#<checksum>     */
-
-char *
-getpacket (void)
-{
-  unsigned char *buffer = &remcomInBuffer[0];
-  unsigned char checksum;
-  unsigned char xmitcsum;
-  int count;
-  char ch;
-
-  while (1)
-    {
-      /* wait around for the start character, ignore all other characters */
-      while ((ch = getDebugChar ()) != '$')
-       ;
-
-retry:
-      checksum = 0;
-      xmitcsum = -1;
-      count = 0;
-
-      /* now, read until a # or end of buffer is found */
-      while (count < BUFMAX - 1)
-       {
-         ch = getDebugChar ();
-          if (ch == '$')
-            goto retry;
-         if (ch == '#')
-           break;
-         checksum = checksum + ch;
-         buffer[count] = ch;
-         count = count + 1;
-       }
-      buffer[count] = 0;
-
-      if (ch == '#')
-       {
-         ch = getDebugChar ();
-         xmitcsum = hex (ch) << 4;
-         ch = getDebugChar ();
-         xmitcsum += hex (ch);
-
-         if (checksum != xmitcsum)
-           {
-             putDebugChar ('-');       /* failed checksum */
-           }
-         else
-           {
-             putDebugChar ('+');       /* successful transfer */
-
-             /* if a sequence char is present, reply the sequence ID */
-             if (buffer[2] == ':')
-               {
-                 putDebugChar (buffer[0]);
-                 putDebugChar (buffer[1]);
-
-                 return &buffer[3];
-               }
-
-             return &buffer[0];
-           }
-       }
-    }
-}
-
-
-/* send the packet in buffer. */
-
-static void
-putpacket (char *buffer)
-{
-  int checksum;
-  int count;
-
-  /*  $<packet info>#<checksum>. */
-  do
-    {
-      char *src = buffer;
-      putDebugChar ('$');
-      checksum = 0;
-
-      while (*src)
-       {
-         int runlen;
-
-         /* Do run length encoding */
-         for (runlen = 0; runlen < 100; runlen ++) 
-           {
-             if (src[0] != src[runlen]) 
-               {
-                 if (runlen > 3) 
-                   {
-                     int encode;
-                     /* Got a useful amount */
-                     putDebugChar (*src);
-                     checksum += *src;
-                     putDebugChar ('*');
-                     checksum += '*';
-                     checksum += (encode = runlen + ' ' - 4);
-                     putDebugChar (encode);
-                     src += runlen;
-                   }
-                 else
-                   {
-                     putDebugChar (*src);
-                     checksum += *src;
-                     src++;
-                   }
-                 break;
-               }
-           }
-       }
-
-
-      putDebugChar ('#');
-      putDebugChar (highhex(checksum));
-      putDebugChar (lowhex(checksum));
-    }
-  while  (getDebugChar() != '+');
-}
-
-
-/* a bus error has occurred, perform a longjmp
-   to return execution and allow handling of the error */
-
-void
-handle_buserror (void)
-{
-  longjmp (remcomEnv, 1);
-}
-
-/*
- * this function takes the SH-1 exception number and attempts to
- * translate this number into a unix compatible signal value
- */
-static int
-computeSignal (int exceptionVector)
-{
-  int sigval;
-  switch (exceptionVector)
-    {
-    case INVALID_INSN_VEC:
-      sigval = 4;
-      break;                   
-    case INVALID_SLOT_VEC:
-      sigval = 4;
-      break;                   
-    case CPU_BUS_ERROR_VEC:
-      sigval = 10;
-      break;                   
-    case DMA_BUS_ERROR_VEC:
-      sigval = 10;
-      break;   
-    case NMI_VEC:
-      sigval = 2;
-      break;   
-
-    case TRAP_VEC:
-    case USER_VEC:
-      sigval = 5;
-      break;
-
-    default:
-      sigval = 7;              /* "software generated"*/
-      break;
-    }
-  return (sigval);
-}
-
-void
-doSStep (void)
-{
-  short *instrMem;
-  int displacement;
-  int reg;
-  unsigned short opcode;
-
-  instrMem = (short *) registers[PC];
-
-  opcode = *instrMem;
-  stepped = 1;
-
-  if ((opcode & COND_BR_MASK) == BT_INSTR)
-    {
-      if (registers[SR] & T_BIT_MASK)
-       {
-         displacement = (opcode & COND_DISP) << 1;
-         if (displacement & 0x80)
-           displacement |= 0xffffff00;
-         /*
-                  * Remember PC points to second instr.
-                  * after PC of branch ... so add 4
-                  */
-         instrMem = (short *) (registers[PC] + displacement + 4);
-       }
-      else
-       instrMem += 1;
-    }
-  else if ((opcode & COND_BR_MASK) == BF_INSTR)
-    {
-      if (registers[SR] & T_BIT_MASK)
-       instrMem += 1;
-      else
-       {
-         displacement = (opcode & COND_DISP) << 1;
-         if (displacement & 0x80)
-           displacement |= 0xffffff00;
-         /*
-                  * Remember PC points to second instr.
-                  * after PC of branch ... so add 4
-                  */
-         instrMem = (short *) (registers[PC] + displacement + 4);
-       }
-    }
-  else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
-    {
-      displacement = (opcode & UCOND_DISP) << 1;
-      if (displacement & 0x0800)
-       displacement |= 0xfffff000;
-
-      /*
-          * Remember PC points to second instr.
-          * after PC of branch ... so add 4
-          */
-      instrMem = (short *) (registers[PC] + displacement + 4);
-    }
-  else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
-    {
-      reg = (char) ((opcode & UCOND_REG) >> 8);
-
-      instrMem = (short *) registers[reg];
-    }
-  else if (opcode == RTS_INSTR)
-    instrMem = (short *) registers[PR];
-  else if (opcode == RTE_INSTR)
-    instrMem = (short *) registers[15];
-  else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
-    instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
-  else
-    instrMem += 1;
-
-  instrBuffer.memAddr = instrMem;
-  instrBuffer.oldInstr = *instrMem;
-  *instrMem = SSTEP_INSTR;
-}
-
-
-/* Undo the effect of a previous doSStep.  If we single stepped,
-   restore the old instruction. */
-
-void
-undoSStep (void)
-{
-  if (stepped)
-    {  short *instrMem;
-      instrMem = instrBuffer.memAddr;
-      *instrMem = instrBuffer.oldInstr;
-    }
-  stepped = 0;
-}
-
-/*
-This function does all exception handling.  It only does two things -
-it figures out why it was called and tells gdb, and then it reacts
-to gdb's requests.
-
-When in the monitor mode we talk a human on the serial line rather than gdb.
-
-*/
-
-
-void
-gdb_handle_exception (int exceptionVector)
-{
-  int sigval, stepping;
-  int addr, length;
-  char *ptr;
-
-  /* reply to host that an exception has occurred */
-  sigval = computeSignal (exceptionVector);
-  remcomOutBuffer[0] = 'S';
-  remcomOutBuffer[1] = highhex(sigval);
-  remcomOutBuffer[2] = lowhex (sigval);
-  remcomOutBuffer[3] = 0;
-
-  putpacket (remcomOutBuffer);
-
-  /*
-   * exception 255 indicates a software trap
-   * inserted in place of code ... so back up
-   * PC by one instruction, since this instruction
-   * will later be replaced by its original one!
-   */
-  if (exceptionVector == 0xff
-      || exceptionVector == 0x20)
-    registers[PC] -= 2;
-
-  /*
-   * Do the thangs needed to undo
-   * any stepping we may have done!
-   */
-  undoSStep ();
-
-  stepping = 0;
-
-  while (1)
-    {
-      remcomOutBuffer[0] = 0;
-      ptr = getpacket ();
-
-      switch (*ptr++)
-       {
-       case '?':
-         remcomOutBuffer[0] = 'S';
-         remcomOutBuffer[1] = highhex (sigval);
-         remcomOutBuffer[2] = lowhex (sigval);
-         remcomOutBuffer[3] = 0;
-         break;
-       case 'd':
-         remote_debug = !(remote_debug);       /* toggle debug flag */
-         break;
-       case 'g':               /* return the value of the CPU registers */
-         mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
-         break;
-       case 'G':               /* set the value of the CPU registers - return OK */
-         hex2mem (ptr, (char *) registers, NUMREGBYTES);
-         strcpy (remcomOutBuffer, "OK");
-         break;
-
-         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
-       case 'm':
-         if (setjmp (remcomEnv) == 0)
-           {
-             dofault = 0;
-             /* TRY, TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
-             if (hexToInt (&ptr, &addr))
-               if (*(ptr++) == ',')
-                 if (hexToInt (&ptr, &length))
-                   {
-                     ptr = 0;
-                     mem2hex ((char *) addr, remcomOutBuffer, length);
-                   }
-             if (ptr)
-               strcpy (remcomOutBuffer, "E01");
-           }
-         else
-           strcpy (remcomOutBuffer, "E03");
-
-         /* restore handler for bus error */
-         dofault = 1;
-         break;
-
-         /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
-       case 'M':
-         if (setjmp (remcomEnv) == 0)
-           {
-             dofault = 0;
-
-             /* TRY, TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
-             if (hexToInt (&ptr, &addr))
-               if (*(ptr++) == ',')
-                 if (hexToInt (&ptr, &length))
-                   if (*(ptr++) == ':')
-                     {
-                       hex2mem (ptr, (char *) addr, length);
-                       ptr = 0;
-                       strcpy (remcomOutBuffer, "OK");
-                     }
-             if (ptr)
-               strcpy (remcomOutBuffer, "E02");
-           }
-         else
-           strcpy (remcomOutBuffer, "E03");
-
-         /* restore handler for bus error */
-         dofault = 1;
-         break;
-
-         /* cAA..AA    Continue at address AA..AA(optional) */
-         /* sAA..AA   Step one instruction from AA..AA(optional) */
-       case 's':
-         stepping = 1;
-       case 'c':
-         {
-           /* tRY, to read optional parameter, pc unchanged if no parm */
-           if (hexToInt (&ptr, &addr))
-             registers[PC] = addr;
-
-           if (stepping)
-             doSStep ();
-         }
-         return;
-         break;
-
-         /* kill the program */
-       case 'k':               /* do nothing */
-         break;
-       }                       /* switch */
-
-      /* reply to the request */
-      putpacket (remcomOutBuffer);
-    }
-}
-
-
-#define GDBCOOKIE 0x5ac 
-static int ingdbmode;
-/* We've had an exception - choose to go into the monitor or
-   the gdb stub */
-void handle_exception(int exceptionVector)
-{
-#ifdef MONITOR
-    if (ingdbmode != GDBCOOKIE)
-      monitor_handle_exception (exceptionVector);
-    else 
-#endif
-      gdb_handle_exception (exceptionVector);
-
-}
-
-void
-gdb_mode (void)
-{
-  ingdbmode = GDBCOOKIE;
-  breakpoint();
-}
-/* This function will generate a breakpoint exception.  It is used at the
-   beginning of a program to sync up with a debugger and can be used
-   otherwise as a quick means to stop program execution and "break" into
-   the debugger. */
-
-void
-breakpoint (void)
-{
-      BREAKPOINT ();
-}
-
-/**** Processor-specific routines start here ****/
-/**** Processor-specific routines start here ****/
-/**** Processor-specific routines start here ****/
-
-/* Note:
-
-   The Renesas SH family uses two exception architectures:
-
-   SH1 & SH2:
-
-       These processors utilize an exception vector table.
-       Exceptions are vectored to the address stored at VBR + (exception_num * 4)
-
-  SH3, SH3E, & SH4:
-
-       These processors have fixed entry points relative to the VBR for
-       various exception classes.
-*/
-
-#if defined(__sh1__) || defined(__sh2__)
-
-/* SH1/SH2 exception vector table format */
-
-typedef struct
-  {
-    void (*func_cold) ();
-    int *stack_cold;
-    void (*func_warm) ();
-    int *stack_warm;
-    void (*(handler[256 - 4])) ();
-  }
-vec_type;
-
-/* vectable is the SH1/SH2 vector table. It must be at address 0
-   or wherever your vbr points. */
-
-const vec_type vectable =
-{ 
-  &BINIT,                      /* 0: Power-on reset PC */
-  init_stack + init_stack_size, /* 1: Power-on reset SP */
-  &BINIT,                      /* 2: Manual reset PC */
-  init_stack + init_stack_size, /* 3: Manual reset SP */
-{
-  &catch_exception_4,          /* 4: General invalid instruction */
-  &catch_exception_random,     /* 5: Reserved for system */
-  &catch_exception_6,          /* 6: Invalid slot instruction */
-  &catch_exception_random,     /* 7: Reserved for system */
-  &catch_exception_random,     /* 8: Reserved for system */
-  &catch_exception_9,          /* 9: CPU bus error */
-  &catch_exception_10,         /* 10: DMA bus error */
-  &catch_exception_11,         /* 11: NMI */
-  &catch_exception_random,     /* 12: User break */
-  &catch_exception_random,     /* 13: Reserved for system */
-  &catch_exception_random,     /* 14: Reserved for system */
-  &catch_exception_random,     /* 15: Reserved for system */
-  &catch_exception_random,     /* 16: Reserved for system */
-  &catch_exception_random,     /* 17: Reserved for system */
-  &catch_exception_random,     /* 18: Reserved for system */
-  &catch_exception_random,     /* 19: Reserved for system */
-  &catch_exception_random,     /* 20: Reserved for system */
-  &catch_exception_random,     /* 21: Reserved for system */
-  &catch_exception_random,     /* 22: Reserved for system */
-  &catch_exception_random,     /* 23: Reserved for system */
-  &catch_exception_random,     /* 24: Reserved for system */
-  &catch_exception_random,     /* 25: Reserved for system */
-  &catch_exception_random,     /* 26: Reserved for system */
-  &catch_exception_random,     /* 27: Reserved for system */
-  &catch_exception_random,     /* 28: Reserved for system */
-  &catch_exception_random,     /* 29: Reserved for system */
-  &catch_exception_random,     /* 30: Reserved for system */
-  &catch_exception_random,     /* 31: Reserved for system */
-  &catch_exception_32,         /* 32: Trap instr (user vectors) */
-  &catch_exception_33,         /* 33: Trap instr (user vectors) */
-  &catch_exception_random,     /* 34: Trap instr (user vectors) */
-  &catch_exception_random,     /* 35: Trap instr (user vectors) */
-  &catch_exception_random,     /* 36: Trap instr (user vectors) */
-  &catch_exception_random,     /* 37: Trap instr (user vectors) */
-  &catch_exception_random,     /* 38: Trap instr (user vectors) */
-  &catch_exception_random,     /* 39: Trap instr (user vectors) */
-  &catch_exception_random,     /* 40: Trap instr (user vectors) */
-  &catch_exception_random,     /* 41: Trap instr (user vectors) */
-  &catch_exception_random,     /* 42: Trap instr (user vectors) */
-  &catch_exception_random,     /* 43: Trap instr (user vectors) */
-  &catch_exception_random,     /* 44: Trap instr (user vectors) */
-  &catch_exception_random,     /* 45: Trap instr (user vectors) */
-  &catch_exception_random,     /* 46: Trap instr (user vectors) */
-  &catch_exception_random,     /* 47: Trap instr (user vectors) */
-  &catch_exception_random,     /* 48: Trap instr (user vectors) */
-  &catch_exception_random,     /* 49: Trap instr (user vectors) */
-  &catch_exception_random,     /* 50: Trap instr (user vectors) */
-  &catch_exception_random,     /* 51: Trap instr (user vectors) */
-  &catch_exception_random,     /* 52: Trap instr (user vectors) */
-  &catch_exception_random,     /* 53: Trap instr (user vectors) */
-  &catch_exception_random,     /* 54: Trap instr (user vectors) */
-  &catch_exception_random,     /* 55: Trap instr (user vectors) */
-  &catch_exception_random,     /* 56: Trap instr (user vectors) */
-  &catch_exception_random,     /* 57: Trap instr (user vectors) */
-  &catch_exception_random,     /* 58: Trap instr (user vectors) */
-  &catch_exception_random,     /* 59: Trap instr (user vectors) */
-  &catch_exception_random,     /* 60: Trap instr (user vectors) */
-  &catch_exception_random,     /* 61: Trap instr (user vectors) */
-  &catch_exception_random,     /* 62: Trap instr (user vectors) */
-  &catch_exception_random,     /* 63: Trap instr (user vectors) */
-  &catch_exception_random,     /* 64: IRQ0 */
-  &catch_exception_random,     /* 65: IRQ1 */
-  &catch_exception_random,     /* 66: IRQ2 */
-  &catch_exception_random,     /* 67: IRQ3 */
-  &catch_exception_random,     /* 68: IRQ4 */
-  &catch_exception_random,     /* 69: IRQ5 */
-  &catch_exception_random,     /* 70: IRQ6 */
-  &catch_exception_random,     /* 71: IRQ7 */
-  &catch_exception_random,
-  &catch_exception_random,
-  &catch_exception_random,
-  &catch_exception_random,
-  &catch_exception_random,
-  &catch_exception_random,
-  &catch_exception_random,
-  &catch_exception_random,
-  &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_random,
-     &catch_exception_255}};
-
-#define BCR  (*(volatile short *)(0x05FFFFA0)) /* Bus control register */
-#define BAS  (0x800)                           /* Byte access select */
-#define WCR1 (*(volatile short *)(0x05ffffA2)) /* Wait state control register */
-
-asm ("_BINIT: mov.l  L1,r15");
-asm ("bra _INIT");
-asm ("nop");
-asm ("L1: .long _init_stack + 8*1024*4");
-void
-INIT (void)
-{
-  /* First turn on the ram */
-  WCR1  = 0;    /* Never sample wait */
-  BCR = BAS;    /* use lowbyte/high byte */
-
-  init_serial();
-
-#ifdef MONITOR
-  reset_hook ();
-#endif
-
-
-  in_nmi = 0;
-  dofault = 1;
-  stepped = 0;
-
-  stub_sp = stub_stack + stub_stack_size;
-  breakpoint ();
-
-  while (1)
-    ;
-}
-
-
-static void sr()
-{
-
-
-  /* Calling Reset does the same as pressing the button */
-  asm (".global _Reset
-        .global _WarmReset
-_Reset:
-_WarmReset:
-         mov.l L_sp,r15
-         bra   _INIT
-         nop
-         .align 2
-L_sp:    .long _init_stack + 8000");
-
-  asm("saveRegisters:
-       mov.l   @(L_reg, pc), r0
-       mov.l   @r15+, r1                               ! pop R0
-       mov.l   r2, @(0x08, r0)                         ! save R2
-       mov.l   r1, @r0                                 ! save R0
-       mov.l   @r15+, r1                               ! pop R1
-       mov.l   r3, @(0x0c, r0)                         ! save R3
-       mov.l   r1, @(0x04, r0)                         ! save R1
-       mov.l   r4, @(0x10, r0)                         ! save R4
-       mov.l   r5, @(0x14, r0)                         ! save R5
-       mov.l   r6, @(0x18, r0)                         ! save R6
-       mov.l   r7, @(0x1c, r0)                         ! save R7
-       mov.l   r8, @(0x20, r0)                         ! save R8
-       mov.l   r9, @(0x24, r0)                         ! save R9
-       mov.l   r10, @(0x28, r0)                        ! save R10
-       mov.l   r11, @(0x2c, r0)                        ! save R11
-       mov.l   r12, @(0x30, r0)                        ! save R12
-       mov.l   r13, @(0x34, r0)                        ! save R13
-       mov.l   r14, @(0x38, r0)                        ! save R14
-       mov.l   @r15+, r4                               ! save arg to handleException
-       add     #8, r15                                 ! hide PC/SR values on stack
-       mov.l   r15, @(0x3c, r0)                        ! save R15
-       add     #-8, r15                                ! save still needs old SP value
-       add     #92, r0                                 ! readjust register pointer
-       mov     r15, r2
-       add     #4, r2
-       mov.l   @r2, r2                                 ! R2 has SR
-       mov.l   @r15, r1                                ! R1 has PC
-       mov.l   r2, @-r0                                ! save SR
-       sts.l   macl, @-r0                              ! save MACL
-       sts.l   mach, @-r0                              ! save MACH
-       stc.l   vbr, @-r0                               ! save VBR
-       stc.l   gbr, @-r0                               ! save GBR
-       sts.l   pr, @-r0                                ! save PR
-       mov.l   @(L_stubstack, pc), r2
-       mov.l   @(L_hdl_except, pc), r3
-       mov.l   @r2, r15
-       jsr     @r3
-       mov.l   r1, @-r0                                ! save PC
-       mov.l   @(L_stubstack, pc), r0
-       mov.l   @(L_reg, pc), r1
-       bra     restoreRegisters
-       mov.l   r15, @r0                                ! save __stub_stack
-       
-       .align 2
-L_reg:
-       .long   _registers
-L_stubstack:
-       .long   _stub_sp
-L_hdl_except:
-       .long   _handle_exception");
-
-}
-
-static void rr()
-{
-asm("
-       .align 2        
-        .global _resume
-_resume:
-       mov     r4,r1
-restoreRegisters:
-       add     #8, r1                                          ! skip to R2
-       mov.l   @r1+, r2                                        ! restore R2
-       mov.l   @r1+, r3                                        ! restore R3
-       mov.l   @r1+, r4                                        ! restore R4
-       mov.l   @r1+, r5                                        ! restore R5
-       mov.l   @r1+, r6                                        ! restore R6
-       mov.l   @r1+, r7                                        ! restore R7
-       mov.l   @r1+, r8                                        ! restore R8
-       mov.l   @r1+, r9                                        ! restore R9
-       mov.l   @r1+, r10                                       ! restore R10
-       mov.l   @r1+, r11                                       ! restore R11
-       mov.l   @r1+, r12                                       ! restore R12
-       mov.l   @r1+, r13                                       ! restore R13
-       mov.l   @r1+, r14                                       ! restore R14
-       mov.l   @r1+, r15                                       ! restore programs stack
-       mov.l   @r1+, r0
-       add     #-8, r15                                        ! uncover PC/SR on stack 
-       mov.l   r0, @r15                                        ! restore PC onto stack
-       lds.l   @r1+, pr                                        ! restore PR
-       ldc.l   @r1+, gbr                                       ! restore GBR           
-       ldc.l   @r1+, vbr                                       ! restore VBR
-       lds.l   @r1+, mach                                      ! restore MACH
-       lds.l   @r1+, macl                                      ! restore MACL
-       mov.l   @r1, r0 
-       add     #-88, r1                                        ! readjust reg pointer to R1
-       mov.l   r0, @(4, r15)                                   ! restore SR onto stack+4
-       mov.l   r2, @-r15
-       mov.l   L_in_nmi, r0
-       mov             #0, r2
-       mov.b   r2, @r0
-       mov.l   @r15+, r2
-       mov.l   @r1+, r0                                        ! restore R0
-       rte
-       mov.l   @r1, r1                                         ! restore R1
-
-");
-}
-
-
-static __inline__ void code_for_catch_exception(int n) 
-{
-  asm("                .globl  _catch_exception_%O0" : : "i" (n)                               ); 
-  asm("        _catch_exception_%O0:" :: "i" (n)                                               );
-
-  asm("                add     #-4, r15                                ! reserve spot on stack ");
-  asm("                mov.l   r1, @-r15                               ! push R1               ");
-
-  if (n == NMI_VEC) 
-    {
-      /* Special case for NMI - make sure that they don't nest */
-      asm("    mov.l   r0, @-r15                                       ! push R0");
-      asm("    mov.l   L_in_nmi, r0");
-      asm("    tas.b   @r0                                             ! Fend off against addtnl NMIs");
-      asm("    bt              noNMI");
-      asm("    mov.l   @r15+, r0");
-      asm("    mov.l   @r15+, r1");
-      asm("    add             #4, r15");
-      asm("    rte");
-      asm("    nop");
-      asm(".align 2");
-      asm("L_in_nmi: .long     _in_nmi");
-      asm("noNMI:");
-    }
-  else
-    {
-
-      if (n == CPU_BUS_ERROR_VEC)
-       {
-         /* Exception 9 (bus errors) are disasbleable - so that you
-            can probe memory and get zero instead of a fault.
-            Because the vector table may be in ROM we don't revector
-            the interrupt like all the other stubs, we check in here
-            */
-         asm("mov.l    L_dofault,r1");
-         asm("mov.l    @r1,r1");
-         asm("tst      r1,r1");
-         asm("bf       faultaway");
-         asm("bsr      _handle_buserror");
-         asm(".align   2");
-         asm("L_dofault: .long _dofault");
-         asm("faultaway:");
-       }
-      asm("            mov     #15<<4, r1                                                      ");
-      asm("            ldc     r1, sr                                  ! disable interrupts    ");
-      asm("            mov.l   r0, @-r15                               ! push R0               ");
-    }
-
-  /* Prepare for saving context, we've already pushed r0 and r1, stick exception number
-     into the frame */
-  asm("                mov     r15, r0                                                         ");
-  asm("                add     #8, r0                                                          ");
-  asm("                mov     %0,r1" :: "i" (n)                                               );
-  asm("                extu.b  r1,r1                                                           ");
-  asm("                bra     saveRegisters                           ! save register values  ");
-  asm("                mov.l   r1, @r0                                 ! save exception #      ");
-}
-
-
-static  void
-exceptions (void)
-{
-  code_for_catch_exception (CPU_BUS_ERROR_VEC);
-  code_for_catch_exception (DMA_BUS_ERROR_VEC);
-  code_for_catch_exception (INVALID_INSN_VEC);
-  code_for_catch_exception (INVALID_SLOT_VEC);
-  code_for_catch_exception (NMI_VEC);
-  code_for_catch_exception (TRAP_VEC);
-  code_for_catch_exception (USER_VEC);
-  code_for_catch_exception (IO_VEC);
-}
-
-
-
-
-
-
-/* Support for Serial I/O using on chip uart */
-
-#define SMR0 (*(volatile char *)(0x05FFFEC0)) /* Channel 0  serial mode register */
-#define BRR0 (*(volatile char *)(0x05FFFEC1)) /* Channel 0  bit rate register */
-#define SCR0 (*(volatile char *)(0x05FFFEC2)) /* Channel 0  serial control register */
-#define TDR0 (*(volatile char *)(0x05FFFEC3)) /* Channel 0  transmit data register */
-#define SSR0 (*(volatile char *)(0x05FFFEC4)) /* Channel 0  serial status register */
-#define RDR0 (*(volatile char *)(0x05FFFEC5)) /* Channel 0  receive data register */
-
-#define SMR1 (*(volatile char *)(0x05FFFEC8)) /* Channel 1  serial mode register */
-#define BRR1 (*(volatile char *)(0x05FFFEC9)) /* Channel 1  bit rate register */
-#define SCR1 (*(volatile char *)(0x05FFFECA)) /* Channel 1  serial control register */
-#define TDR1 (*(volatile char *)(0x05FFFECB)) /* Channel 1  transmit data register */
-#define SSR1 (*(volatile char *)(0x05FFFECC)) /* Channel 1  serial status register */
-#define RDR1 (*(volatile char *)(0x05FFFECD)) /* Channel 1  receive data register */
-
-/*
- * Serial mode register bits
- */
-
-#define SYNC_MODE              0x80
-#define SEVEN_BIT_DATA                 0x40
-#define PARITY_ON              0x20
-#define ODD_PARITY             0x10
-#define STOP_BITS_2            0x08
-#define ENABLE_MULTIP          0x04
-#define PHI_64                 0x03
-#define PHI_16                 0x02
-#define PHI_4                  0x01
-
-/*
- * Serial control register bits
- */
-#define SCI_TIE                                0x80    /* Transmit interrupt enable */
-#define SCI_RIE                                0x40    /* Receive interrupt enable */
-#define SCI_TE                         0x20    /* Transmit enable */
-#define SCI_RE                         0x10    /* Receive enable */
-#define SCI_MPIE                       0x08    /* Multiprocessor interrupt enable */
-#define SCI_TEIE                       0x04    /* Transmit end interrupt enable */
-#define SCI_CKE1                       0x02    /* Clock enable 1 */
-#define SCI_CKE0                       0x01    /* Clock enable 0 */
-
-/*
- * Serial status register bits
- */
-#define SCI_TDRE                       0x80    /* Transmit data register empty */
-#define SCI_RDRF                       0x40    /* Receive data register full */
-#define SCI_ORER                       0x20    /* Overrun error */
-#define SCI_FER                                0x10    /* Framing error */
-#define SCI_PER                                0x08    /* Parity error */
-#define SCI_TEND                       0x04    /* Transmit end */
-#define SCI_MPB                                0x02    /* Multiprocessor bit */
-#define SCI_MPBT                       0x01    /* Multiprocessor bit transfer */
-
-
-/*
- * Port B IO Register (PBIOR)
- */
-#define        PBIOR           (*(volatile char *)(0x05FFFFC6))
-#define        PB15IOR         0x8000
-#define        PB14IOR         0x4000
-#define        PB13IOR         0x2000
-#define        PB12IOR         0x1000
-#define        PB11IOR         0x0800
-#define        PB10IOR         0x0400
-#define        PB9IOR          0x0200
-#define        PB8IOR          0x0100
-#define        PB7IOR          0x0080
-#define        PB6IOR          0x0040
-#define        PB5IOR          0x0020
-#define        PB4IOR          0x0010
-#define        PB3IOR          0x0008
-#define        PB2IOR          0x0004
-#define        PB1IOR          0x0002
-#define        PB0IOR          0x0001
-
-/*
- * Port B Control Register (PBCR1)
- */
-#define        PBCR1           (*(volatile short *)(0x05FFFFCC))
-#define        PB15MD1         0x8000
-#define        PB15MD0         0x4000
-#define        PB14MD1         0x2000
-#define        PB14MD0         0x1000
-#define        PB13MD1         0x0800
-#define        PB13MD0         0x0400
-#define        PB12MD1         0x0200
-#define        PB12MD0         0x0100
-#define        PB11MD1         0x0080
-#define        PB11MD0         0x0040
-#define        PB10MD1         0x0020
-#define        PB10MD0         0x0010
-#define        PB9MD1          0x0008
-#define        PB9MD0          0x0004
-#define        PB8MD1          0x0002
-#define        PB8MD0          0x0001
-
-#define        PB15MD          PB15MD1|PB14MD0
-#define        PB14MD          PB14MD1|PB14MD0
-#define        PB13MD          PB13MD1|PB13MD0
-#define        PB12MD          PB12MD1|PB12MD0
-#define        PB11MD          PB11MD1|PB11MD0
-#define        PB10MD          PB10MD1|PB10MD0
-#define        PB9MD           PB9MD1|PB9MD0
-#define        PB8MD           PB8MD1|PB8MD0
-
-#define PB_TXD1        PB11MD1
-#define PB_RXD1        PB10MD1
-#define PB_TXD0        PB9MD1
-#define PB_RXD0        PB8MD1
-
-/*
- * Port B Control Register (PBCR2)
- */
-#define        PBCR2   0x05FFFFCE
-#define        PB7MD1  0x8000
-#define        PB7MD0  0x4000
-#define        PB6MD1  0x2000
-#define        PB6MD0  0x1000
-#define        PB5MD1  0x0800
-#define        PB5MD0  0x0400
-#define        PB4MD1  0x0200
-#define        PB4MD0  0x0100
-#define        PB3MD1  0x0080
-#define        PB3MD0  0x0040
-#define        PB2MD1  0x0020
-#define        PB2MD0  0x0010
-#define        PB1MD1  0x0008
-#define        PB1MD0  0x0004
-#define        PB0MD1  0x0002
-#define        PB0MD0  0x0001
-       
-#define        PB7MD   PB7MD1|PB7MD0
-#define        PB6MD   PB6MD1|PB6MD0
-#define        PB5MD   PB5MD1|PB5MD0
-#define        PB4MD   PB4MD1|PB4MD0
-#define        PB3MD   PB3MD1|PB3MD0
-#define        PB2MD   PB2MD1|PB2MD0
-#define        PB1MD   PB1MD1|PB1MD0
-#define        PB0MD   PB0MD1|PB0MD0
-
-
-#ifdef MHZ
-#define BPS                    32 * 9600 * MHZ / ( BAUD * 10)
-#else
-#define BPS                    32      /* 9600 for 10 Mhz */
-#endif
-
-void handleError (char theSSR);
-
-void
-nop (void)
-{
-
-}
-void 
-init_serial (void)
-{
-  int i;
-
-  /* Clear TE and RE in Channel 1's SCR   */
-  SCR1 &= ~(SCI_TE | SCI_RE);
-
-  /* Set communication to be async, 8-bit data, no parity, 1 stop bit and use internal clock */
-
-  SMR1 = 0;
-  BRR1 = BPS;
-
-  SCR1 &= ~(SCI_CKE1 | SCI_CKE0);
-
-  /* let the hardware settle */
-
-  for (i = 0; i < 1000; i++)
-    nop ();
-
-  /* Turn on in and out */
-  SCR1 |= SCI_RE | SCI_TE;
-
-  /* Set the PFC to make RXD1 (pin PB8) an input pin and TXD1 (pin PB9) an output pin */
-  PBCR1 &= ~(PB_TXD1 | PB_RXD1);
-  PBCR1 |= PB_TXD1 | PB_RXD1;
-}
-
-
-int
-getDebugCharReady (void)
-{
-  char mySSR;
-  mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
-  if ( mySSR )
-    handleError ( mySSR );
-  return SSR1 & SCI_RDRF ;
-}
-
-char 
-getDebugChar (void)
-{
-  char ch;
-  char mySSR;
-
-  while ( ! getDebugCharReady())
-    ;
-
-  ch = RDR1;
-  SSR1 &= ~SCI_RDRF;
-
-  mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
-
-  if (mySSR)
-    handleError (mySSR);
-
-  return ch;
-}
-
-int 
-putDebugCharReady (void)
-{
-  return (SSR1 & SCI_TDRE);
-}
-
-void
-putDebugChar (char ch)
-{
-  while (!putDebugCharReady())
-    ;
-
-  /*
-   * Write data into TDR and clear TDRE
-   */
-  TDR1 = ch;
-  SSR1 &= ~SCI_TDRE;
-}
-
-void 
-handleError (char theSSR)
-{
-  SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
-}
-
-#endif
diff --git a/gdb/sparc-stub.c b/gdb/sparc-stub.c
deleted file mode 100644 (file)
index c12d436..0000000
+++ /dev/null
@@ -1,778 +0,0 @@
-/****************************************************************************
-
-               THIS SOFTWARE IS NOT COPYRIGHTED
-
-   HP offers the following for use in the public domain.  HP makes no
-   warranty with regard to the software or it's performance and the
-   user accepts the software "AS IS" with all faults.
-
-   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
-   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-****************************************************************************/
-
-/****************************************************************************
- *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
- *
- *  Module name: remcom.c $
- *  Revision: 1.34 $
- *  Date: 91/03/09 12:29:49 $
- *  Contributor:     Lake Stevens Instrument Division$
- *
- *  Description:     low level support for gdb debugger. $
- *
- *  Considerations:  only works on target hardware $
- *
- *  Written by:      Glenn Engel $
- *  ModuleState:     Experimental $
- *
- *  NOTES:           See Below $
- *
- *  Modified for SPARC by Stu Grossman, Cygnus Support.
- *
- *  This code has been extensively tested on the Fujitsu SPARClite demo board.
- *
- *  To enable debugger support, two things need to happen.  One, a
- *  call to set_debug_traps() is necessary in order to allow any breakpoints
- *  or error conditions to be properly intercepted and reported to gdb.
- *  Two, a breakpoint needs to be generated to begin communication.  This
- *  is most easily accomplished by a call to breakpoint().  Breakpoint()
- *  simulates a breakpoint by executing a trap #1.
- *
- *************
- *
- *    The following gdb commands are supported:
- *
- * command          function                               Return value
- *
- *    g             return the value of the CPU registers  hex data or ENN
- *    G             set the value of the CPU registers     OK or ENN
- *
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
- *
- *    c             Resume at current address              SNN   ( signal NN)
- *    cAA..AA       Continue at address AA..AA             SNN
- *
- *    s             Step one instruction                   SNN
- *    sAA..AA       Step one instruction from AA..AA       SNN
- *
- *    k             kill
- *
- *    ?             What was the last sigval ?             SNN   (signal NN)
- *
- * All commands and responses are sent with a packet which includes a
- * checksum.  A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer.  '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host:                  Reply:
- * $m0,10#2a               +$00010203040506070809101112131415#42
- *
- ****************************************************************************/
-
-#include <string.h>
-#include <signal.h>
-
-/************************************************************************
- *
- * external low-level support routines
- */
-
-extern void putDebugChar();    /* write a single character      */
-extern int getDebugChar();     /* read and return a single char */
-
-/************************************************************************/
-/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-/* at least NUMREGBYTES*2 are needed for register packets */
-#define BUFMAX 2048
-
-static int initialized = 0;    /* !0 means we've been initialized */
-
-static void set_mem_fault_trap();
-
-static const char hexchars[]="0123456789abcdef";
-
-#define NUMREGS 72
-
-/* Number of bytes of registers.  */
-#define NUMREGBYTES (NUMREGS * 4)
-enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
-                O0, O1, O2, O3, O4, O5, SP, O7,
-                L0, L1, L2, L3, L4, L5, L6, L7,
-                I0, I1, I2, I3, I4, I5, FP, I7,
-
-                F0, F1, F2, F3, F4, F5, F6, F7,
-                F8, F9, F10, F11, F12, F13, F14, F15,
-                F16, F17, F18, F19, F20, F21, F22, F23,
-                F24, F25, F26, F27, F28, F29, F30, F31,
-                Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
-
-/***************************  ASSEMBLY CODE MACROS *************************/
-/*                                                                        */
-
-extern void trap_low();
-
-asm("
-       .reserve trapstack, 1000 * 4, \"bss\", 8
-
-       .data
-       .align  4
-
-in_trap_handler:
-       .word   0
-
-       .text
-       .align 4
-
-! This function is called when any SPARC trap (except window overflow or
-! underflow) occurs.  It makes sure that the invalid register window is still
-! available before jumping into C code.  It will also restore the world if you
-! return from handle_exception.
-
-       .globl _trap_low
-_trap_low:
-       mov     %psr, %l0
-       mov     %wim, %l3
-
-       srl     %l3, %l0, %l4           ! wim >> cwp
-       cmp     %l4, 1
-       bne     window_fine             ! Branch if not in the invalid window
-       nop
-
-! Handle window overflow
-
-       mov     %g1, %l4                ! Save g1, we use it to hold the wim
-       srl     %l3, 1, %g1             ! Rotate wim right
-       tst     %g1
-       bg      good_wim                ! Branch if new wim is non-zero
-       nop
-
-! At this point, we need to bring a 1 into the high order bit of the wim.
-! Since we don't want to make any assumptions about the number of register
-! windows, we figure it out dynamically so as to setup the wim correctly.
-
-       not     %g1                     ! Fill g1 with ones
-       mov     %g1, %wim               ! Fill the wim with ones
-       nop
-       nop
-       nop
-       mov     %wim, %g1               ! Read back the wim
-       inc     %g1                     ! Now g1 has 1 just to left of wim
-       srl     %g1, 1, %g1             ! Now put 1 at top of wim
-       mov     %g0, %wim               ! Clear wim so that subsequent save
-       nop                             !  won't trap
-       nop
-       nop
-
-good_wim:
-       save    %g0, %g0, %g0           ! Slip into next window
-       mov     %g1, %wim               ! Install the new wim
-
-       std     %l0, [%sp + 0 * 4]      ! save L & I registers
-       std     %l2, [%sp + 2 * 4]
-       std     %l4, [%sp + 4 * 4]
-       std     %l6, [%sp + 6 * 4]
-
-       std     %i0, [%sp + 8 * 4]
-       std     %i2, [%sp + 10 * 4]
-       std     %i4, [%sp + 12 * 4]
-       std     %i6, [%sp + 14 * 4]
-
-       restore                         ! Go back to trap window.
-       mov     %l4, %g1                ! Restore %g1
-
-window_fine:
-       sethi   %hi(in_trap_handler), %l4
-       ld      [%lo(in_trap_handler) + %l4], %l5
-       tst     %l5
-       bg      recursive_trap
-       inc     %l5
-
-       set     trapstack+1000*4, %sp   ! Switch to trap stack
-
-recursive_trap:
-       st      %l5, [%lo(in_trap_handler) + %l4]
-       sub     %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
-                                       ! + hidden arg + arg spill
-                                       ! + doubleword alignment
-                                       ! + registers[72] local var
-
-       std     %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
-       std     %g2, [%sp + (24 + 2) * 4]
-       std     %g4, [%sp + (24 + 4) * 4]
-       std     %g6, [%sp + (24 + 6) * 4]
-
-       std     %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
-       std     %i2, [%sp + (24 + 10) * 4]
-       std     %i4, [%sp + (24 + 12) * 4]
-       std     %i6, [%sp + (24 + 14) * 4]
-                                       ! F0->F31 not implemented
-       mov     %y, %l4
-       mov     %tbr, %l5
-       st      %l4, [%sp + (24 + 64) * 4] ! Y
-       st      %l0, [%sp + (24 + 65) * 4] ! PSR
-       st      %l3, [%sp + (24 + 66) * 4] ! WIM
-       st      %l5, [%sp + (24 + 67) * 4] ! TBR
-       st      %l1, [%sp + (24 + 68) * 4] ! PC
-       st      %l2, [%sp + (24 + 69) * 4] ! NPC
-
-                                       ! CPSR and FPSR not impl
-
-       or      %l0, 0xf20, %l4
-       mov     %l4, %psr               ! Turn on traps, disable interrupts
-
-       call    _handle_exception
-       add     %sp, 24 * 4, %o0        ! Pass address of registers
-
-! Reload all of the registers that aren't on the stack
-
-       ld      [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
-       ldd     [%sp + (24 + 2) * 4], %g2
-       ldd     [%sp + (24 + 4) * 4], %g4
-       ldd     [%sp + (24 + 6) * 4], %g6
-
-       ldd     [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
-       ldd     [%sp + (24 + 10) * 4], %i2
-       ldd     [%sp + (24 + 12) * 4], %i4
-       ldd     [%sp + (24 + 14) * 4], %i6
-
-       ldd     [%sp + (24 + 64) * 4], %l0 ! Y & PSR
-       ldd     [%sp + (24 + 68) * 4], %l2 ! PC & NPC
-
-       restore                         ! Ensure that previous window is valid
-       save    %g0, %g0, %g0           !  by causing a window_underflow trap
-
-       mov     %l0, %y
-       mov     %l1, %psr               ! Make sure that traps are disabled
-                                       ! for rett
-
-       sethi   %hi(in_trap_handler), %l4
-       ld      [%lo(in_trap_handler) + %l4], %l5
-       dec     %l5
-       st      %l5, [%lo(in_trap_handler) + %l4]
-
-       jmpl    %l2, %g0                ! Restore old PC
-       rett    %l3                     ! Restore old nPC
-");
-
-/* Convert ch from a hex digit to an int */
-
-static int
-hex (unsigned char ch)
-{
-  if (ch >= 'a' && ch <= 'f')
-    return ch-'a'+10;
-  if (ch >= '0' && ch <= '9')
-    return ch-'0';
-  if (ch >= 'A' && ch <= 'F')
-    return ch-'A'+10;
-  return -1;
-}
-
-static char remcomInBuffer[BUFMAX];
-static char remcomOutBuffer[BUFMAX];
-
-/* scan for the sequence $<data>#<checksum>     */
-
-unsigned char *
-getpacket (void)
-{
-  unsigned char *buffer = &remcomInBuffer[0];
-  unsigned char checksum;
-  unsigned char xmitcsum;
-  int count;
-  char ch;
-
-  while (1)
-    {
-      /* wait around for the start character, ignore all other characters */
-      while ((ch = getDebugChar ()) != '$')
-       ;
-
-retry:
-      checksum = 0;
-      xmitcsum = -1;
-      count = 0;
-
-      /* now, read until a # or end of buffer is found */
-      while (count < BUFMAX - 1)
-       {
-         ch = getDebugChar ();
-          if (ch == '$')
-            goto retry;
-         if (ch == '#')
-           break;
-         checksum = checksum + ch;
-         buffer[count] = ch;
-         count = count + 1;
-       }
-      buffer[count] = 0;
-
-      if (ch == '#')
-       {
-         ch = getDebugChar ();
-         xmitcsum = hex (ch) << 4;
-         ch = getDebugChar ();
-         xmitcsum += hex (ch);
-
-         if (checksum != xmitcsum)
-           {
-             putDebugChar ('-');       /* failed checksum */
-           }
-         else
-           {
-             putDebugChar ('+');       /* successful transfer */
-
-             /* if a sequence char is present, reply the sequence ID */
-             if (buffer[2] == ':')
-               {
-                 putDebugChar (buffer[0]);
-                 putDebugChar (buffer[1]);
-
-                 return &buffer[3];
-               }
-
-             return &buffer[0];
-           }
-       }
-    }
-}
-
-/* send the packet in buffer.  */
-
-static void
-putpacket (unsigned char *buffer)
-{
-  unsigned char checksum;
-  int count;
-  unsigned char ch;
-
-  /*  $<packet info>#<checksum>. */
-  do
-    {
-      putDebugChar('$');
-      checksum = 0;
-      count = 0;
-
-      while (ch = buffer[count])
-       {
-         putDebugChar(ch);
-         checksum += ch;
-         count += 1;
-       }
-
-      putDebugChar('#');
-      putDebugChar(hexchars[checksum >> 4]);
-      putDebugChar(hexchars[checksum & 0xf]);
-
-    }
-  while (getDebugChar() != '+');
-}
-
-/* Indicate to caller of mem2hex or hex2mem that there has been an
-   error.  */
-static volatile int mem_err = 0;
-
-/* Convert the memory pointed to by mem into hex, placing result in buf.
- * Return a pointer to the last char put in buf (null), in case of mem fault,
- * return 0.
- * If MAY_FAULT is non-zero, then we will handle memory faults by returning
- * a 0, else treat a fault like any other fault in the stub.
- */
-
-static unsigned char *
-mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
-{
-  unsigned char ch;
-
-  set_mem_fault_trap(may_fault);
-
-  while (count-- > 0)
-    {
-      ch = *mem++;
-      if (mem_err)
-       return 0;
-      *buf++ = hexchars[ch >> 4];
-      *buf++ = hexchars[ch & 0xf];
-    }
-
-  *buf = 0;
-
-  set_mem_fault_trap(0);
-
-  return buf;
-}
-
-/* convert the hex array pointed to by buf into binary to be placed in mem
- * return a pointer to the character AFTER the last byte written */
-
-static char *
-hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
-{
-  int i;
-  unsigned char ch;
-
-  set_mem_fault_trap(may_fault);
-
-  for (i=0; i<count; i++)
-    {
-      ch = hex(*buf++) << 4;
-      ch |= hex(*buf++);
-      *mem++ = ch;
-      if (mem_err)
-       return 0;
-    }
-
-  set_mem_fault_trap(0);
-
-  return mem;
-}
-
-/* This table contains the mapping between SPARC hardware trap types, and
-   signals, which are primarily what GDB understands.  It also indicates
-   which hardware traps we need to commandeer when initializing the stub. */
-
-static struct hard_trap_info
-{
-  unsigned char tt;            /* Trap type code for SPARClite */
-  unsigned char signo;         /* Signal that we map this trap into */
-} hard_trap_info[] = {
-  {1, SIGSEGV},                        /* instruction access error */
-  {2, SIGILL},                 /* privileged instruction */
-  {3, SIGILL},                 /* illegal instruction */
-  {4, SIGEMT},                 /* fp disabled */
-  {36, SIGEMT},                        /* cp disabled */
-  {7, SIGBUS},                 /* mem address not aligned */
-  {9, SIGSEGV},                        /* data access exception */
-  {10, SIGEMT},                        /* tag overflow */
-  {128+1, SIGTRAP},            /* ta 1 - normal breakpoint instruction */
-  {0, 0}                       /* Must be last */
-};
-
-/* Set up exception handlers for tracing and breakpoints */
-
-void
-set_debug_traps (void)
-{
-  struct hard_trap_info *ht;
-
-  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
-    exceptionHandler(ht->tt, trap_low);
-
-  initialized = 1;
-}
-
-asm ("
-! Trap handler for memory errors.  This just sets mem_err to be non-zero.  It
-! assumes that %l1 is non-zero.  This should be safe, as it is doubtful that
-! 0 would ever contain code that could mem fault.  This routine will skip
-! past the faulting instruction after setting mem_err.
-
-       .text
-       .align 4
-
-_fltr_set_mem_err:
-       sethi %hi(_mem_err), %l0
-       st %l1, [%l0 + %lo(_mem_err)]
-       jmpl %l2, %g0
-       rett %l2+4
-");
-
-static void
-set_mem_fault_trap (int enable)
-{
-  extern void fltr_set_mem_err();
-  mem_err = 0;
-
-  if (enable)
-    exceptionHandler(9, fltr_set_mem_err);
-  else
-    exceptionHandler(9, trap_low);
-}
-
-/* Convert the SPARC hardware trap type code to a unix signal number. */
-
-static int
-computeSignal (int tt)
-{
-  struct hard_trap_info *ht;
-
-  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
-    if (ht->tt == tt)
-      return ht->signo;
-
-  return SIGHUP;               /* default for things we don't know about */
-}
-
-/*
- * While we find nice hex chars, build an int.
- * Return number of chars processed.
- */
-
-static int
-hexToInt(char **ptr, int *intValue)
-{
-  int numChars = 0;
-  int hexValue;
-
-  *intValue = 0;
-
-  while (**ptr)
-    {
-      hexValue = hex(**ptr);
-      if (hexValue < 0)
-       break;
-
-      *intValue = (*intValue << 4) | hexValue;
-      numChars ++;
-
-      (*ptr)++;
-    }
-
-  return (numChars);
-}
-
-/*
- * This function does all command procesing for interfacing to gdb.  It
- * returns 1 if you should skip the instruction at the trap address, 0
- * otherwise.
- */
-
-extern void breakinst();
-
-static void
-handle_exception (unsigned long *registers)
-{
-  int tt;                      /* Trap type */
-  int sigval;
-  int addr;
-  int length;
-  char *ptr;
-  unsigned long *sp;
-
-/* First, we must force all of the windows to be spilled out */
-
-  asm("        save %sp, -64, %sp
-       save %sp, -64, %sp
-       save %sp, -64, %sp
-       save %sp, -64, %sp
-       save %sp, -64, %sp
-       save %sp, -64, %sp
-       save %sp, -64, %sp
-       save %sp, -64, %sp
-       restore
-       restore
-       restore
-       restore
-       restore
-       restore
-       restore
-       restore
-");
-
-  if (registers[PC] == (unsigned long)breakinst)
-    {
-      registers[PC] = registers[NPC];
-      registers[NPC] += 4;
-    }
-
-  sp = (unsigned long *)registers[SP];
-
-  tt = (registers[TBR] >> 4) & 0xff;
-
-  /* reply to host that an exception has occurred */
-  sigval = computeSignal(tt);
-  ptr = remcomOutBuffer;
-
-  *ptr++ = 'T';
-  *ptr++ = hexchars[sigval >> 4];
-  *ptr++ = hexchars[sigval & 0xf];
-
-  *ptr++ = hexchars[PC >> 4];
-  *ptr++ = hexchars[PC & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[FP >> 4];
-  *ptr++ = hexchars[FP & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[SP >> 4];
-  *ptr++ = hexchars[SP & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex((char *)&sp, ptr, 4, 0);
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[NPC >> 4];
-  *ptr++ = hexchars[NPC & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
-  *ptr++ = ';';
-
-  *ptr++ = hexchars[O7 >> 4];
-  *ptr++ = hexchars[O7 & 0xf];
-  *ptr++ = ':';
-  ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
-  *ptr++ = ';';
-
-  *ptr++ = 0;
-
-  putpacket(remcomOutBuffer);
-
-  while (1)
-    {
-      remcomOutBuffer[0] = 0;
-
-      ptr = getpacket();
-      switch (*ptr++)
-       {
-       case '?':
-         remcomOutBuffer[0] = 'S';
-         remcomOutBuffer[1] = hexchars[sigval >> 4];
-         remcomOutBuffer[2] = hexchars[sigval & 0xf];
-         remcomOutBuffer[3] = 0;
-         break;
-
-       case 'd':               /* toggle debug flag */
-         break;
-
-       case 'g':               /* return the value of the CPU registers */
-         {
-           ptr = remcomOutBuffer;
-           ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
-           ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */
-           memset(ptr, '0', 32 * 8); /* Floating point */
-           mem2hex((char *)&registers[Y],
-                   ptr + 32 * 4 * 2,
-                   8 * 4,
-                   0);         /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-         }
-         break;
-
-       case 'G':          /* set the value of the CPU registers - return OK */
-         {
-           unsigned long *newsp, psr;
-
-           psr = registers[PSR];
-
-           hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
-           hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
-           hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
-                   8 * 4, 0);  /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-
-           /* See if the stack pointer has moved.  If so, then copy the saved
-              locals and ins to the new location.  This keeps the window
-              overflow and underflow routines happy.  */
-
-           newsp = (unsigned long *)registers[SP];
-           if (sp != newsp)
-             sp = memcpy(newsp, sp, 16 * 4);
-
-           /* Don't allow CWP to be modified. */
-
-           if (psr != registers[PSR])
-             registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
-
-           strcpy(remcomOutBuffer,"OK");
-         }
-         break;
-
-       case 'm':         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
-         /* Try to read %x,%x.  */
-
-         if (hexToInt(&ptr, &addr)
-             && *ptr++ == ','
-             && hexToInt(&ptr, &length))
-           {
-             if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
-               break;
-
-             strcpy (remcomOutBuffer, "E03");
-           }
-         else
-           strcpy(remcomOutBuffer,"E01");
-         break;
-
-       case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
-         /* Try to read '%x,%x:'.  */
-
-         if (hexToInt(&ptr, &addr)
-             && *ptr++ == ','
-             && hexToInt(&ptr, &length)
-             && *ptr++ == ':')
-           {
-             if (hex2mem(ptr, (char *)addr, length, 1))
-               strcpy(remcomOutBuffer, "OK");
-             else
-               strcpy(remcomOutBuffer, "E03");
-           }
-         else
-           strcpy(remcomOutBuffer, "E02");
-         break;
-
-       case 'c':    /* cAA..AA    Continue at address AA..AA(optional) */
-         /* try to read optional parameter, pc unchanged if no parm */
-
-         if (hexToInt(&ptr, &addr))
-           {
-             registers[PC] = addr;
-             registers[NPC] = addr + 4;
-           }
-
-/* Need to flush the instruction cache here, as we may have deposited a
-   breakpoint, and the icache probably has no way of knowing that a data ref to
-   some location may have changed something that is in the instruction cache.
- */
-
-         flush_i_cache();
-         return;
-
-         /* kill the program */
-       case 'k' :              /* do nothing */
-         break;
-#if 0
-       case 't':               /* Test feature */
-         asm (" std %f30,[%sp]");
-         break;
-#endif
-       case 'r':               /* Reset */
-         asm ("call 0
-               nop ");
-         break;
-       }                       /* switch */
-
-      /* reply to the request */
-      putpacket(remcomOutBuffer);
-    }
-}
-
-/* This function will generate a breakpoint exception.  It is used at the
-   beginning of a program to sync up with a debugger and can be used
-   otherwise as a quick means to stop program execution and "break" into
-   the debugger. */
-
-void
-breakpoint (void)
-{
-  if (!initialized)
-    return;
-
-  asm("        .globl _breakinst
-
-       _breakinst: ta 1
-      ");
-}
index 1a8b2b702b31e6a009b42ee74060e04ddd96c5a5..a0f175e30df19949ae1b500beefd9fd8cc01b180 100644 (file)
@@ -1,3 +1,11 @@
+2012-03-08  Tristan Gingold  <gingold@adacore.com>
+
+       * sparc-stub.c: Move from ..
+       * sh-stub.c: Likewise.
+       * m68k-stub.c: Likewise.
+       * m32r-stub.c: Likewise.
+       * i386-stub.c: Likewise.
+
 2012-03-05  Tristan Gingold  <gingold@adacore.com>
 
        * buildvms.com: New file.
diff --git a/gdb/stubs/i386-stub.c b/gdb/stubs/i386-stub.c
new file mode 100644 (file)
index 0000000..04996b7
--- /dev/null
@@ -0,0 +1,952 @@
+/****************************************************************************
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ *  Module name: remcom.c $
+ *  Revision: 1.34 $
+ *  Date: 91/03/09 12:29:49 $
+ *  Contributor:     Lake Stevens Instrument Division$
+ *
+ *  Description:     low level support for gdb debugger. $
+ *
+ *  Considerations:  only works on target hardware $
+ *
+ *  Written by:      Glenn Engel $
+ *  ModuleState:     Experimental $
+ *
+ *  NOTES:           See Below $
+ *
+ *  Modified for 386 by Jim Kingdon, Cygnus Support.
+ *
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a trap #1.
+ *
+ *  The external function exceptionHandler() is
+ *  used to attach a specific handler to a specific 386 vector number.
+ *  It should use the same privilege level it runs at.  It should
+ *  install it as an interrupt gate so that interrupts are masked
+ *  while the handler runs.
+ *
+ *  Because gdb will sometimes write to the stack area to execute function
+ *  calls, this program cannot rely on using the supervisor stack so it
+ *  uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern void putDebugChar();    /* write a single character      */
+extern int getDebugChar();     /* read and return a single char */
+extern void exceptionHandler();        /* assign an exception handler   */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized;  /* boolean flag. != 0 means we've been initialized */
+
+int     remote_debug;
+/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
+
+static const char hexchars[]="0123456789abcdef";
+
+/* Number of registers.  */
+#define NUMREGS        16
+
+/* Number of bytes of registers.  */
+#define NUMREGBYTES (NUMREGS * 4)
+
+enum regnames {EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
+              PC /* also known as eip */,
+              PS /* also known as eflags */,
+              CS, SS, DS, ES, FS, GS};
+
+/*
+ * these should not be static cuz they can be used outside this module
+ */
+int registers[NUMREGS];
+
+#define STACKSIZE 10000
+int remcomStack[STACKSIZE/sizeof(int)];
+static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+/***************************  ASSEMBLY CODE MACROS *************************/
+/*                                                                        */
+
+extern void
+return_to_prog ();
+
+/* Restore the program's registers (including the stack pointer, which
+   means we get the right stack and don't have to worry about popping our
+   return address and any stack frames and so on) and return.  */
+asm(".text");
+asm(".globl _return_to_prog");
+asm("_return_to_prog:");
+asm("        movw _registers+44, %ss");
+asm("        movl _registers+16, %esp");
+asm("        movl _registers+4, %ecx");
+asm("        movl _registers+8, %edx");
+asm("        movl _registers+12, %ebx");
+asm("        movl _registers+20, %ebp");
+asm("        movl _registers+24, %esi");
+asm("        movl _registers+28, %edi");
+asm("        movw _registers+48, %ds");
+asm("        movw _registers+52, %es");
+asm("        movw _registers+56, %fs");
+asm("        movw _registers+60, %gs");
+asm("        movl _registers+36, %eax");
+asm("        pushl %eax");  /* saved eflags */
+asm("        movl _registers+40, %eax");
+asm("        pushl %eax");  /* saved cs */
+asm("        movl _registers+32, %eax");
+asm("        pushl %eax");  /* saved eip */
+asm("        movl _registers, %eax");
+/* use iret to restore pc and flags together so
+   that trace flag works right.  */
+asm("        iret");
+
+#define BREAKPOINT() asm("   int $3");
+
+/* Put the error code here just in case the user cares.  */
+int gdb_i386errcode;
+/* Likewise, the vector number here (since GDB only gets the signal
+   number through the usual means, and that's not very specific).  */
+int gdb_i386vector = -1;
+
+/* GDB stores segment registers in 32-bit words (that's just the way
+   m-i386v.h is written).  So zero the appropriate areas in registers.  */
+#define SAVE_REGISTERS1() \
+  asm ("movl %eax, _registers");                                         \
+  asm ("movl %ecx, _registers+4");                                          \
+  asm ("movl %edx, _registers+8");                                          \
+  asm ("movl %ebx, _registers+12");                                         \
+  asm ("movl %ebp, _registers+20");                                         \
+  asm ("movl %esi, _registers+24");                                         \
+  asm ("movl %edi, _registers+28");                                         \
+  asm ("movw $0, %ax");                                                             \
+  asm ("movw %ds, _registers+48");                                          \
+  asm ("movw %ax, _registers+50");                                          \
+  asm ("movw %es, _registers+52");                                          \
+  asm ("movw %ax, _registers+54");                                          \
+  asm ("movw %fs, _registers+56");                                          \
+  asm ("movw %ax, _registers+58");                                          \
+  asm ("movw %gs, _registers+60");                                          \
+  asm ("movw %ax, _registers+62");
+#define SAVE_ERRCODE() \
+  asm ("popl %ebx");                                  \
+  asm ("movl %ebx, _gdb_i386errcode");
+#define SAVE_REGISTERS2() \
+  asm ("popl %ebx"); /* old eip */                                          \
+  asm ("movl %ebx, _registers+32");                                         \
+  asm ("popl %ebx");    /* old cs */                                        \
+  asm ("movl %ebx, _registers+40");                                         \
+  asm ("movw %ax, _registers+42");                                           \
+  asm ("popl %ebx");    /* old eflags */                                    \
+  asm ("movl %ebx, _registers+36");                                         \
+  /* Now that we've done the pops, we can save the stack pointer.");  */   \
+  asm ("movw %ss, _registers+44");                                          \
+  asm ("movw %ax, _registers+46");                                                  \
+  asm ("movl %esp, _registers+16");
+
+/* See if mem_fault_routine is set, if so just IRET to that address.  */
+#define CHECK_FAULT() \
+  asm ("cmpl $0, _mem_fault_routine");                                    \
+  asm ("jne mem_fault");
+
+asm (".text");
+asm ("mem_fault:");
+/* OK to clobber temp registers; we're just going to end up in set_mem_err.  */
+/* Pop error code from the stack and save it.  */
+asm ("     popl %eax");
+asm ("     movl %eax, _gdb_i386errcode");
+
+asm ("     popl %eax"); /* eip */
+/* We don't want to return there, we want to return to the function
+   pointed to by mem_fault_routine instead.  */
+asm ("     movl _mem_fault_routine, %eax");
+asm ("     popl %ecx"); /* cs (low 16 bits; junk in hi 16 bits).  */
+asm ("     popl %edx"); /* eflags */
+
+/* Remove this stack frame; when we do the iret, we will be going to
+   the start of a function, so we want the stack to look just like it
+   would after a "call" instruction.  */
+asm ("     leave");
+
+/* Push the stuff that iret wants.  */
+asm ("     pushl %edx"); /* eflags */
+asm ("     pushl %ecx"); /* cs */
+asm ("     pushl %eax"); /* eip */
+
+/* Zero mem_fault_routine.  */
+asm ("     movl $0, %eax");
+asm ("     movl %eax, _mem_fault_routine");
+
+asm ("iret");
+
+#define CALL_HOOK() asm("call _remcomHandler");
+
+/* This function is called when a i386 exception occurs.  It saves
+ * all the cpu regs in the _registers array, munges the stack a bit,
+ * and invokes an exception handler (remcom_handler).
+ *
+ * stack on entry:                       stack on exit:
+ *   old eflags                          vector number
+ *   old cs (zero-filled to 32 bits)
+ *   old eip
+ *
+ */
+extern void _catchException3();
+asm(".text");
+asm(".globl __catchException3");
+asm("__catchException3:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $3");
+CALL_HOOK();
+
+/* Same thing for exception 1.  */
+extern void _catchException1();
+asm(".text");
+asm(".globl __catchException1");
+asm("__catchException1:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $1");
+CALL_HOOK();
+
+/* Same thing for exception 0.  */
+extern void _catchException0();
+asm(".text");
+asm(".globl __catchException0");
+asm("__catchException0:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $0");
+CALL_HOOK();
+
+/* Same thing for exception 4.  */
+extern void _catchException4();
+asm(".text");
+asm(".globl __catchException4");
+asm("__catchException4:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $4");
+CALL_HOOK();
+
+/* Same thing for exception 5.  */
+extern void _catchException5();
+asm(".text");
+asm(".globl __catchException5");
+asm("__catchException5:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $5");
+CALL_HOOK();
+
+/* Same thing for exception 6.  */
+extern void _catchException6();
+asm(".text");
+asm(".globl __catchException6");
+asm("__catchException6:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $6");
+CALL_HOOK();
+
+/* Same thing for exception 7.  */
+extern void _catchException7();
+asm(".text");
+asm(".globl __catchException7");
+asm("__catchException7:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $7");
+CALL_HOOK();
+
+/* Same thing for exception 8.  */
+extern void _catchException8();
+asm(".text");
+asm(".globl __catchException8");
+asm("__catchException8:");
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $8");
+CALL_HOOK();
+
+/* Same thing for exception 9.  */
+extern void _catchException9();
+asm(".text");
+asm(".globl __catchException9");
+asm("__catchException9:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $9");
+CALL_HOOK();
+
+/* Same thing for exception 10.  */
+extern void _catchException10();
+asm(".text");
+asm(".globl __catchException10");
+asm("__catchException10:");
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $10");
+CALL_HOOK();
+
+/* Same thing for exception 12.  */
+extern void _catchException12();
+asm(".text");
+asm(".globl __catchException12");
+asm("__catchException12:");
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $12");
+CALL_HOOK();
+
+/* Same thing for exception 16.  */
+extern void _catchException16();
+asm(".text");
+asm(".globl __catchException16");
+asm("__catchException16:");
+SAVE_REGISTERS1();
+SAVE_REGISTERS2();
+asm ("pushl $16");
+CALL_HOOK();
+
+/* For 13, 11, and 14 we have to deal with the CHECK_FAULT stuff.  */
+
+/* Same thing for exception 13.  */
+extern void _catchException13 ();
+asm (".text");
+asm (".globl __catchException13");
+asm ("__catchException13:");
+CHECK_FAULT();
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $13");
+CALL_HOOK();
+
+/* Same thing for exception 11.  */
+extern void _catchException11 ();
+asm (".text");
+asm (".globl __catchException11");
+asm ("__catchException11:");
+CHECK_FAULT();
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $11");
+CALL_HOOK();
+
+/* Same thing for exception 14.  */
+extern void _catchException14 ();
+asm (".text");
+asm (".globl __catchException14");
+asm ("__catchException14:");
+CHECK_FAULT();
+SAVE_REGISTERS1();
+SAVE_ERRCODE();
+SAVE_REGISTERS2();
+asm ("pushl $14");
+CALL_HOOK();
+
+/*
+ * remcomHandler is a front end for handle_exception.  It moves the
+ * stack pointer into an area reserved for debugger use.
+ */
+asm("_remcomHandler:");
+asm("           popl %eax");        /* pop off return address     */
+asm("           popl %eax");      /* get the exception number   */
+asm("          movl _stackPtr, %esp"); /* move to remcom stack area  */
+asm("          pushl %eax");   /* push exception onto stack  */
+asm("          call  _handle_exception");    /* this never returns */
+
+void
+_returnFromException ()
+{
+  return_to_prog ();
+}
+
+int
+hex (ch)
+     char ch;
+{
+  if ((ch >= 'a') && (ch <= 'f'))
+    return (ch - 'a' + 10);
+  if ((ch >= '0') && (ch <= '9'))
+    return (ch - '0');
+  if ((ch >= 'A') && (ch <= 'F'))
+    return (ch - 'A' + 10);
+  return (-1);
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum>     */
+
+unsigned char *
+getpacket (void)
+{
+  unsigned char *buffer = &remcomInBuffer[0];
+  unsigned char checksum;
+  unsigned char xmitcsum;
+  int count;
+  char ch;
+
+  while (1)
+    {
+      /* wait around for the start character, ignore all other characters */
+      while ((ch = getDebugChar ()) != '$')
+       ;
+
+    retry:
+      checksum = 0;
+      xmitcsum = -1;
+      count = 0;
+
+      /* now, read until a # or end of buffer is found */
+      while (count < BUFMAX - 1)
+       {
+         ch = getDebugChar ();
+         if (ch == '$')
+           goto retry;
+         if (ch == '#')
+           break;
+         checksum = checksum + ch;
+         buffer[count] = ch;
+         count = count + 1;
+       }
+      buffer[count] = 0;
+
+      if (ch == '#')
+       {
+         ch = getDebugChar ();
+         xmitcsum = hex (ch) << 4;
+         ch = getDebugChar ();
+         xmitcsum += hex (ch);
+
+         if (checksum != xmitcsum)
+           {
+             if (remote_debug)
+               {
+                 fprintf (stderr,
+                          "bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
+                          checksum, xmitcsum, buffer);
+               }
+             putDebugChar ('-');       /* failed checksum */
+           }
+         else
+           {
+             putDebugChar ('+');       /* successful transfer */
+
+             /* if a sequence char is present, reply the sequence ID */
+             if (buffer[2] == ':')
+               {
+                 putDebugChar (buffer[0]);
+                 putDebugChar (buffer[1]);
+
+                 return &buffer[3];
+               }
+
+             return &buffer[0];
+           }
+       }
+    }
+}
+
+/* send the packet in buffer.  */
+
+void
+putpacket (unsigned char *buffer)
+{
+  unsigned char checksum;
+  int count;
+  char ch;
+
+  /*  $<packet info>#<checksum>.  */
+  do
+    {
+      putDebugChar ('$');
+      checksum = 0;
+      count = 0;
+
+      while (ch = buffer[count])
+       {
+         putDebugChar (ch);
+         checksum += ch;
+         count += 1;
+       }
+
+      putDebugChar ('#');
+      putDebugChar (hexchars[checksum >> 4]);
+      putDebugChar (hexchars[checksum % 16]);
+
+    }
+  while (getDebugChar () != '+');
+}
+
+void
+debug_error (format, parm)
+     char *format;
+     char *parm;
+{
+  if (remote_debug)
+    fprintf (stderr, format, parm);
+}
+
+/* Address of a routine to RTE to if we get a memory fault.  */
+static void (*volatile mem_fault_routine) () = NULL;
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+   error.  */
+static volatile int mem_err = 0;
+
+void
+set_mem_err (void)
+{
+  mem_err = 1;
+}
+
+/* These are separate functions so that they are so short and sweet
+   that the compiler won't save any registers (if there is a fault
+   to mem_fault, they won't get restored, so there better not be any
+   saved).  */
+int
+get_char (char *addr)
+{
+  return *addr;
+}
+
+void
+set_char (char *addr, int val)
+{
+  *addr = val;
+}
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+/* If MAY_FAULT is non-zero, then we should set mem_err in response to
+   a fault; if zero treat a fault like any other fault in the stub.  */
+char *
+mem2hex (mem, buf, count, may_fault)
+     char *mem;
+     char *buf;
+     int count;
+     int may_fault;
+{
+  int i;
+  unsigned char ch;
+
+  if (may_fault)
+    mem_fault_routine = set_mem_err;
+  for (i = 0; i < count; i++)
+    {
+      ch = get_char (mem++);
+      if (may_fault && mem_err)
+       return (buf);
+      *buf++ = hexchars[ch >> 4];
+      *buf++ = hexchars[ch % 16];
+    }
+  *buf = 0;
+  if (may_fault)
+    mem_fault_routine = NULL;
+  return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+char *
+hex2mem (buf, mem, count, may_fault)
+     char *buf;
+     char *mem;
+     int count;
+     int may_fault;
+{
+  int i;
+  unsigned char ch;
+
+  if (may_fault)
+    mem_fault_routine = set_mem_err;
+  for (i = 0; i < count; i++)
+    {
+      ch = hex (*buf++) << 4;
+      ch = ch + hex (*buf++);
+      set_char (mem++, ch);
+      if (may_fault && mem_err)
+       return (mem);
+    }
+  if (may_fault)
+    mem_fault_routine = NULL;
+  return (mem);
+}
+
+/* this function takes the 386 exception vector and attempts to
+   translate this number into a unix compatible signal value */
+int
+computeSignal (int exceptionVector)
+{
+  int sigval;
+  switch (exceptionVector)
+    {
+    case 0:
+      sigval = 8;
+      break;                   /* divide by zero */
+    case 1:
+      sigval = 5;
+      break;                   /* debug exception */
+    case 3:
+      sigval = 5;
+      break;                   /* breakpoint */
+    case 4:
+      sigval = 16;
+      break;                   /* into instruction (overflow) */
+    case 5:
+      sigval = 16;
+      break;                   /* bound instruction */
+    case 6:
+      sigval = 4;
+      break;                   /* Invalid opcode */
+    case 7:
+      sigval = 8;
+      break;                   /* coprocessor not available */
+    case 8:
+      sigval = 7;
+      break;                   /* double fault */
+    case 9:
+      sigval = 11;
+      break;                   /* coprocessor segment overrun */
+    case 10:
+      sigval = 11;
+      break;                   /* Invalid TSS */
+    case 11:
+      sigval = 11;
+      break;                   /* Segment not present */
+    case 12:
+      sigval = 11;
+      break;                   /* stack exception */
+    case 13:
+      sigval = 11;
+      break;                   /* general protection */
+    case 14:
+      sigval = 11;
+      break;                   /* page fault */
+    case 16:
+      sigval = 7;
+      break;                   /* coprocessor error */
+    default:
+      sigval = 7;              /* "software generated" */
+    }
+  return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED           */
+/**********************************************/
+int
+hexToInt (char **ptr, int *intValue)
+{
+  int numChars = 0;
+  int hexValue;
+
+  *intValue = 0;
+
+  while (**ptr)
+    {
+      hexValue = hex (**ptr);
+      if (hexValue >= 0)
+       {
+         *intValue = (*intValue << 4) | hexValue;
+         numChars++;
+       }
+      else
+       break;
+
+      (*ptr)++;
+    }
+
+  return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void
+handle_exception (int exceptionVector)
+{
+  int sigval, stepping;
+  int addr, length;
+  char *ptr;
+  int newPC;
+
+  gdb_i386vector = exceptionVector;
+
+  if (remote_debug)
+    {
+      printf ("vector=%d, sr=0x%x, pc=0x%x\n",
+             exceptionVector, registers[PS], registers[PC]);
+    }
+
+  /* reply to host that an exception has occurred */
+  sigval = computeSignal (exceptionVector);
+
+  ptr = remcomOutBuffer;
+
+  *ptr++ = 'T';                        /* notify gdb with signo, PC, FP and SP */
+  *ptr++ = hexchars[sigval >> 4];
+  *ptr++ = hexchars[sigval & 0xf];
+
+  *ptr++ = hexchars[ESP]; 
+  *ptr++ = ':';
+  ptr = mem2hex((char *)&registers[ESP], ptr, 4, 0);   /* SP */
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[EBP]; 
+  *ptr++ = ':';
+  ptr = mem2hex((char *)&registers[EBP], ptr, 4, 0);   /* FP */
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[PC]; 
+  *ptr++ = ':';
+  ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);    /* PC */
+  *ptr++ = ';';
+
+  *ptr = '\0'
+
+  putpacket (remcomOutBuffer);
+
+  stepping = 0;
+
+  while (1 == 1)
+    {
+      remcomOutBuffer[0] = 0;
+      ptr = getpacket ();
+
+      switch (*ptr++)
+       {
+       case '?':
+         remcomOutBuffer[0] = 'S';
+         remcomOutBuffer[1] = hexchars[sigval >> 4];
+         remcomOutBuffer[2] = hexchars[sigval % 16];
+         remcomOutBuffer[3] = 0;
+         break;
+       case 'd':
+         remote_debug = !(remote_debug);       /* toggle debug flag */
+         break;
+       case 'g':               /* return the value of the CPU registers */
+         mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES, 0);
+         break;
+       case 'G':               /* set the value of the CPU registers - return OK */
+         hex2mem (ptr, (char *) registers, NUMREGBYTES, 0);
+         strcpy (remcomOutBuffer, "OK");
+         break;
+       case 'P':               /* set the value of a single CPU register - return OK */
+         {
+           int regno;
+
+           if (hexToInt (&ptr, &regno) && *ptr++ == '=')
+             if (regno >= 0 && regno < NUMREGS)
+               {
+                 hex2mem (ptr, (char *) &registers[regno], 4, 0);
+                 strcpy (remcomOutBuffer, "OK");
+                 break;
+               }
+
+           strcpy (remcomOutBuffer, "E01");
+           break;
+         }
+
+         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+       case 'm':
+         /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
+         if (hexToInt (&ptr, &addr))
+           if (*(ptr++) == ',')
+             if (hexToInt (&ptr, &length))
+               {
+                 ptr = 0;
+                 mem_err = 0;
+                 mem2hex ((char *) addr, remcomOutBuffer, length, 1);
+                 if (mem_err)
+                   {
+                     strcpy (remcomOutBuffer, "E03");
+                     debug_error ("memory fault");
+                   }
+               }
+
+         if (ptr)
+           {
+             strcpy (remcomOutBuffer, "E01");
+           }
+         break;
+
+         /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+       case 'M':
+         /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
+         if (hexToInt (&ptr, &addr))
+           if (*(ptr++) == ',')
+             if (hexToInt (&ptr, &length))
+               if (*(ptr++) == ':')
+                 {
+                   mem_err = 0;
+                   hex2mem (ptr, (char *) addr, length, 1);
+
+                   if (mem_err)
+                     {
+                       strcpy (remcomOutBuffer, "E03");
+                       debug_error ("memory fault");
+                     }
+                   else
+                     {
+                       strcpy (remcomOutBuffer, "OK");
+                     }
+
+                   ptr = 0;
+                 }
+         if (ptr)
+           {
+             strcpy (remcomOutBuffer, "E02");
+           }
+         break;
+
+         /* cAA..AA    Continue at address AA..AA(optional) */
+         /* sAA..AA   Step one instruction from AA..AA(optional) */
+       case 's':
+         stepping = 1;
+       case 'c':
+         /* try to read optional parameter, pc unchanged if no parm */
+         if (hexToInt (&ptr, &addr))
+           registers[PC] = addr;
+
+         newPC = registers[PC];
+
+         /* clear the trace bit */
+         registers[PS] &= 0xfffffeff;
+
+         /* set the trace bit if we're stepping */
+         if (stepping)
+           registers[PS] |= 0x100;
+
+         _returnFromException ();      /* this is a jump */
+         break;
+
+         /* kill the program */
+       case 'k':               /* do nothing */
+#if 0
+         /* Huh? This doesn't look like "nothing".
+            m68k-stub.c and sparc-stub.c don't have it.  */
+         BREAKPOINT ();
+#endif
+         break;
+       }                       /* switch */
+
+      /* reply to the request */
+      putpacket (remcomOutBuffer);
+    }
+}
+
+/* this function is used to set up exception handlers for tracing and
+   breakpoints */
+void
+set_debug_traps (void)
+{
+  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+  exceptionHandler (0, _catchException0);
+  exceptionHandler (1, _catchException1);
+  exceptionHandler (3, _catchException3);
+  exceptionHandler (4, _catchException4);
+  exceptionHandler (5, _catchException5);
+  exceptionHandler (6, _catchException6);
+  exceptionHandler (7, _catchException7);
+  exceptionHandler (8, _catchException8);
+  exceptionHandler (9, _catchException9);
+  exceptionHandler (10, _catchException10);
+  exceptionHandler (11, _catchException11);
+  exceptionHandler (12, _catchException12);
+  exceptionHandler (13, _catchException13);
+  exceptionHandler (14, _catchException14);
+  exceptionHandler (16, _catchException16);
+
+  initialized = 1;
+}
+
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger.  */
+
+void
+breakpoint (void)
+{
+  if (initialized)
+    BREAKPOINT ();
+}
diff --git a/gdb/stubs/m32r-stub.c b/gdb/stubs/m32r-stub.c
new file mode 100644 (file)
index 0000000..4d54f72
--- /dev/null
@@ -0,0 +1,1779 @@
+/****************************************************************************
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ *  Module name: remcom.c $
+ *  Revision: 1.34 $
+ *  Date: 91/03/09 12:29:49 $
+ *  Contributor:     Lake Stevens Instrument Division$
+ *
+ *  Description:     low level support for gdb debugger. $
+ *
+ *  Considerations:  only works on target hardware $
+ *
+ *  Written by:      Glenn Engel $
+ *  ModuleState:     Experimental $
+ *
+ *  NOTES:           See Below $
+ *
+ *  Modified for M32R by Michael Snyder, Cygnus Support.
+ *
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a trap #1.
+ *
+ *  The external function exceptionHandler() is
+ *  used to attach a specific handler to a specific M32R vector number.
+ *  It should use the same privilege level it runs at.  It should
+ *  install it as an interrupt gate so that interrupts are masked
+ *  while the handler runs.
+ *
+ *  Because gdb will sometimes write to the stack area to execute function
+ *  calls, this program cannot rely on using the supervisor stack so it
+ *  uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *    XAA..AA,LLLL: Write LLLL binary bytes at address     OK or ENN
+ *                  AA..AA
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: <two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+extern void putDebugChar ();   /* write a single character      */
+extern int getDebugChar ();    /* read and return a single char */
+extern void exceptionHandler ();       /* assign an exception handler   */
+
+/*****************************************************************************
+ * BUFMAX defines the maximum number of characters in inbound/outbound buffers
+ * at least NUMREGBYTES*2 are needed for register packets 
+ */
+#define BUFMAX 400
+
+static char initialized;       /* boolean flag. != 0 means we've been initialized */
+
+int remote_debug;
+/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
+
+static const unsigned char hexchars[] = "0123456789abcdef";
+
+#define NUMREGS 24
+
+/* Number of bytes of registers.  */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames
+{ R0, R1, R2, R3, R4, R5, R6, R7,
+  R8, R9, R10, R11, R12, R13, R14, R15,
+  PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH
+};
+
+enum SYS_calls
+{
+  SYS_null,
+  SYS_exit,
+  SYS_open,
+  SYS_close,
+  SYS_read,
+  SYS_write,
+  SYS_lseek,
+  SYS_unlink,
+  SYS_getpid,
+  SYS_kill,
+  SYS_fstat,
+  SYS_sbrk,
+  SYS_fork,
+  SYS_execve,
+  SYS_wait4,
+  SYS_link,
+  SYS_chdir,
+  SYS_stat,
+  SYS_utime,
+  SYS_chown,
+  SYS_chmod,
+  SYS_time,
+  SYS_pipe
+};
+
+static int registers[NUMREGS];
+
+#define STACKSIZE 8096
+static unsigned char remcomInBuffer[BUFMAX];
+static unsigned char remcomOutBuffer[BUFMAX];
+static int remcomStack[STACKSIZE / sizeof (int)];
+static int *stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+static unsigned int save_vectors[18];  /* previous exception vectors */
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an error. */
+static volatile int mem_err = 0;
+
+/* Store the vector number here (since GDB only gets the signal
+   number through the usual means, and that's not very specific).  */
+int gdb_m32r_vector = -1;
+
+#if 0
+#include "syscall.h"           /* for SYS_exit, SYS_write etc. */
+#endif
+
+/* Global entry points:
+ */
+
+extern void handle_exception (int);
+extern void set_debug_traps (void);
+extern void breakpoint (void);
+
+/* Local functions:
+ */
+
+static int computeSignal (int);
+static void putpacket (unsigned char *);
+static unsigned char *getpacket (void);
+
+static unsigned char *mem2hex (unsigned char *, unsigned char *, int, int);
+static unsigned char *hex2mem (unsigned char *, unsigned char *, int, int);
+static int hexToInt (unsigned char **, int *);
+static unsigned char *bin2mem (unsigned char *, unsigned char *, int, int);
+static void stash_registers (void);
+static void restore_registers (void);
+static int prepare_to_step (int);
+static int finish_from_step (void);
+static unsigned long crc32 (unsigned char *, int, unsigned long);
+
+static void gdb_error (char *, char *);
+static int gdb_putchar (int), gdb_puts (char *), gdb_write (char *, int);
+
+static unsigned char *strcpy (unsigned char *, const unsigned char *);
+static int strlen (const unsigned char *);
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+
+void
+handle_exception (int exceptionVector)
+{
+  int sigval, stepping;
+  int addr, length, i;
+  unsigned char *ptr;
+  unsigned char buf[16];
+  int binary;
+
+  if (!finish_from_step ())
+    return;                    /* "false step": let the target continue */
+
+  gdb_m32r_vector = exceptionVector;
+
+  if (remote_debug)
+    {
+      mem2hex ((unsigned char *) &exceptionVector, buf, 4, 0);
+      gdb_error ("Handle exception %s, ", buf);
+      mem2hex ((unsigned char *) &registers[PC], buf, 4, 0);
+      gdb_error ("PC == 0x%s\n", buf);
+    }
+
+  /* reply to host that an exception has occurred */
+  sigval = computeSignal (exceptionVector);
+
+  ptr = remcomOutBuffer;
+
+  *ptr++ = 'T';                        /* notify gdb with signo, PC, FP and SP */
+  *ptr++ = hexchars[sigval >> 4];
+  *ptr++ = hexchars[sigval & 0xf];
+
+  *ptr++ = hexchars[PC >> 4];
+  *ptr++ = hexchars[PC & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex ((unsigned char *) &registers[PC], ptr, 4, 0); /* PC */
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[R13 >> 4];
+  *ptr++ = hexchars[R13 & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex ((unsigned char *) &registers[R13], ptr, 4, 0);        /* FP */
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[R15 >> 4];
+  *ptr++ = hexchars[R15 & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex ((unsigned char *) &registers[R15], ptr, 4, 0);        /* SP */
+  *ptr++ = ';';
+  *ptr++ = 0;
+
+  if (exceptionVector == 0)    /* simulated SYS call stuff */
+    {
+      mem2hex ((unsigned char *) &registers[PC], buf, 4, 0);
+      switch (registers[R0])
+       {
+       case SYS_exit:
+         gdb_error ("Target program has exited at %s\n", buf);
+         ptr = remcomOutBuffer;
+         *ptr++ = 'W';
+         sigval = registers[R1] & 0xff;
+         *ptr++ = hexchars[sigval >> 4];
+         *ptr++ = hexchars[sigval & 0xf];
+         *ptr++ = 0;
+         break;
+       case SYS_open:
+         gdb_error ("Target attempts SYS_open call at %s\n", buf);
+         break;
+       case SYS_close:
+         gdb_error ("Target attempts SYS_close call at %s\n", buf);
+         break;
+       case SYS_read:
+         gdb_error ("Target attempts SYS_read call at %s\n", buf);
+         break;
+       case SYS_write:
+         if (registers[R1] == 1 ||     /* write to stdout  */
+             registers[R1] == 2)       /* write to stderr  */
+           {                   /* (we can do that) */
+             registers[R0] =
+               gdb_write ((void *) registers[R2], registers[R3]);
+             return;
+           }
+         else
+           gdb_error ("Target attempts SYS_write call at %s\n", buf);
+         break;
+       case SYS_lseek:
+         gdb_error ("Target attempts SYS_lseek call at %s\n", buf);
+         break;
+       case SYS_unlink:
+         gdb_error ("Target attempts SYS_unlink call at %s\n", buf);
+         break;
+       case SYS_getpid:
+         gdb_error ("Target attempts SYS_getpid call at %s\n", buf);
+         break;
+       case SYS_kill:
+         gdb_error ("Target attempts SYS_kill call at %s\n", buf);
+         break;
+       case SYS_fstat:
+         gdb_error ("Target attempts SYS_fstat call at %s\n", buf);
+         break;
+       default:
+         gdb_error ("Target attempts unknown SYS call at %s\n", buf);
+         break;
+       }
+    }
+
+  putpacket (remcomOutBuffer);
+
+  stepping = 0;
+
+  while (1 == 1)
+    {
+      remcomOutBuffer[0] = 0;
+      ptr = getpacket ();
+      binary = 0;
+      switch (*ptr++)
+       {
+       default:                /* Unknown code.  Return an empty reply message. */
+         break;
+       case 'R':
+         if (hexToInt (&ptr, &addr))
+           registers[PC] = addr;
+         strcpy (remcomOutBuffer, "OK");
+         break;
+       case '!':
+         strcpy (remcomOutBuffer, "OK");
+         break;
+       case 'X':               /* XAA..AA,LLLL:<binary data>#cs */
+         binary = 1;
+       case 'M':               /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+         /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
+         {
+           if (hexToInt (&ptr, &addr))
+             if (*(ptr++) == ',')
+               if (hexToInt (&ptr, &length))
+                 if (*(ptr++) == ':')
+                   {
+                     mem_err = 0;
+                     if (binary)
+                       bin2mem (ptr, (unsigned char *) addr, length, 1);
+                     else
+                       hex2mem (ptr, (unsigned char *) addr, length, 1);
+                     if (mem_err)
+                       {
+                         strcpy (remcomOutBuffer, "E03");
+                         gdb_error ("memory fault", "");
+                       }
+                     else
+                       {
+                         strcpy (remcomOutBuffer, "OK");
+                       }
+                     ptr = 0;
+                   }
+           if (ptr)
+             {
+               strcpy (remcomOutBuffer, "E02");
+             }
+         }
+         break;
+       case 'm':               /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+         /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
+         if (hexToInt (&ptr, &addr))
+           if (*(ptr++) == ',')
+             if (hexToInt (&ptr, &length))
+               {
+                 ptr = 0;
+                 mem_err = 0;
+                 mem2hex ((unsigned char *) addr, remcomOutBuffer, length,
+                          1);
+                 if (mem_err)
+                   {
+                     strcpy (remcomOutBuffer, "E03");
+                     gdb_error ("memory fault", "");
+                   }
+               }
+         if (ptr)
+           {
+             strcpy (remcomOutBuffer, "E01");
+           }
+         break;
+       case '?':
+         remcomOutBuffer[0] = 'S';
+         remcomOutBuffer[1] = hexchars[sigval >> 4];
+         remcomOutBuffer[2] = hexchars[sigval % 16];
+         remcomOutBuffer[3] = 0;
+         break;
+       case 'd':
+         remote_debug = !(remote_debug);       /* toggle debug flag */
+         break;
+       case 'g':               /* return the value of the CPU registers */
+         mem2hex ((unsigned char *) registers, remcomOutBuffer, NUMREGBYTES,
+                  0);
+         break;
+       case 'P':               /* set the value of a single CPU register - return OK */
+         {
+           int regno;
+
+           if (hexToInt (&ptr, &regno) && *ptr++ == '=')
+             if (regno >= 0 && regno < NUMREGS)
+               {
+                 int stackmode;
+
+                 hex2mem (ptr, (unsigned char *) &registers[regno], 4, 0);
+                 /*
+                  * Since we just changed a single CPU register, let's
+                  * make sure to keep the several stack pointers consistant.
+                  */
+                 stackmode = registers[PSW] & 0x80;
+                 if (regno == R15)     /* stack pointer changed */
+                   {           /* need to change SPI or SPU */
+                     if (stackmode == 0)
+                       registers[SPI] = registers[R15];
+                     else
+                       registers[SPU] = registers[R15];
+                   }
+                 else if (regno == SPU)        /* "user" stack pointer changed */
+                   {
+                     if (stackmode != 0)       /* stack in user mode: copy SP */
+                       registers[R15] = registers[SPU];
+                   }
+                 else if (regno == SPI)        /* "interrupt" stack pointer changed */
+                   {
+                     if (stackmode == 0)       /* stack in interrupt mode: copy SP */
+                       registers[R15] = registers[SPI];
+                   }
+                 else if (regno == PSW)        /* stack mode may have changed! */
+                   {           /* force SP to either SPU or SPI */
+                     if (stackmode == 0)       /* stack in user mode */
+                       registers[R15] = registers[SPI];
+                     else      /* stack in interrupt mode */
+                       registers[R15] = registers[SPU];
+                   }
+                 strcpy (remcomOutBuffer, "OK");
+                 break;
+               }
+           strcpy (remcomOutBuffer, "E01");
+           break;
+         }
+       case 'G':               /* set the value of the CPU registers - return OK */
+         hex2mem (ptr, (unsigned char *) registers, NUMREGBYTES, 0);
+         strcpy (remcomOutBuffer, "OK");
+         break;
+       case 's':               /* sAA..AA      Step one instruction from AA..AA(optional) */
+         stepping = 1;
+       case 'c':               /* cAA..AA      Continue from address AA..AA(optional) */
+         /* try to read optional parameter, pc unchanged if no parm */
+         if (hexToInt (&ptr, &addr))
+           registers[PC] = addr;
+
+         if (stepping)         /* single-stepping */
+           {
+             if (!prepare_to_step (0)) /* set up for single-step */
+               {
+                 /* prepare_to_step has already emulated the target insn:
+                    Send SIGTRAP to gdb, don't resume the target at all.  */
+                 ptr = remcomOutBuffer;
+                 *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */
+                 *ptr++ = '0';
+                 *ptr++ = '5';
+
+                 *ptr++ = hexchars[PC >> 4];   /* send PC */
+                 *ptr++ = hexchars[PC & 0xf];
+                 *ptr++ = ':';
+                 ptr = mem2hex ((unsigned char *) &registers[PC], ptr, 4, 0);
+                 *ptr++ = ';';
+
+                 *ptr++ = hexchars[R13 >> 4];  /* send FP */
+                 *ptr++ = hexchars[R13 & 0xf];
+                 *ptr++ = ':';
+                 ptr =
+                   mem2hex ((unsigned char *) &registers[R13], ptr, 4, 0);
+                 *ptr++ = ';';
+
+                 *ptr++ = hexchars[R15 >> 4];  /* send SP */
+                 *ptr++ = hexchars[R15 & 0xf];
+                 *ptr++ = ':';
+                 ptr =
+                   mem2hex ((unsigned char *) &registers[R15], ptr, 4, 0);
+                 *ptr++ = ';';
+                 *ptr++ = 0;
+
+                 break;
+               }
+           }
+         else                  /* continuing, not single-stepping */
+           {
+             /* OK, about to do a "continue".  First check to see if the 
+                target pc is on an odd boundary (second instruction in the 
+                word).  If so, we must do a single-step first, because 
+                ya can't jump or return back to an odd boundary!  */
+             if ((registers[PC] & 2) != 0)
+               prepare_to_step (1);
+           }
+
+         return;
+
+       case 'D':               /* Detach */
+#if 0
+         /* I am interpreting this to mean, release the board from control 
+            by the remote stub.  To do this, I am restoring the original
+            (or at least previous) exception vectors.
+          */
+         for (i = 0; i < 18; i++)
+           exceptionHandler (i, save_vectors[i]);
+         putpacket ("OK");
+         return;               /* continue the inferior */
+#else
+         strcpy (remcomOutBuffer, "OK");
+         break;
+#endif
+       case 'q':
+         if (*ptr++ == 'C' &&
+             *ptr++ == 'R' && *ptr++ == 'C' && *ptr++ == ':')
+           {
+             unsigned long start, len, our_crc;
+
+             if (hexToInt (&ptr, (int *) &start) &&
+                 *ptr++ == ',' && hexToInt (&ptr, (int *) &len))
+               {
+                 remcomOutBuffer[0] = 'C';
+                 our_crc = crc32 ((unsigned char *) start, len, 0xffffffff);
+                 mem2hex ((char *) &our_crc,
+                          &remcomOutBuffer[1], sizeof (long), 0);
+               }               /* else do nothing */
+           }                   /* else do nothing */
+         break;
+
+       case 'k':               /* kill the program */
+         continue;
+       }                       /* switch */
+
+      /* reply to the request */
+      putpacket (remcomOutBuffer);
+    }
+}
+
+/* qCRC support */
+
+/* Table used by the crc32 function to calcuate the checksum. */
+static unsigned long crc32_table[256] = { 0, 0 };
+
+static unsigned long
+crc32 (unsigned char *buf, int len, unsigned long crc)
+{
+  if (!crc32_table[1])
+    {
+      /* Initialize the CRC table and the decoding table. */
+      int i, j;
+      unsigned long c;
+
+      for (i = 0; i < 256; i++)
+       {
+         for (c = i << 24, j = 8; j > 0; --j)
+           c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+         crc32_table[i] = c;
+       }
+    }
+
+  while (len--)
+    {
+      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+      buf++;
+    }
+  return crc;
+}
+
+static int
+hex (unsigned char ch)
+{
+  if ((ch >= 'a') && (ch <= 'f'))
+    return (ch - 'a' + 10);
+  if ((ch >= '0') && (ch <= '9'))
+    return (ch - '0');
+  if ((ch >= 'A') && (ch <= 'F'))
+    return (ch - 'A' + 10);
+  return (-1);
+}
+
+/* scan for the sequence $<data>#<checksum>     */
+
+unsigned char *
+getpacket (void)
+{
+  unsigned char *buffer = &remcomInBuffer[0];
+  unsigned char checksum;
+  unsigned char xmitcsum;
+  int count;
+  char ch;
+
+  while (1)
+    {
+      /* wait around for the start character, ignore all other characters */
+      while ((ch = getDebugChar ()) != '$')
+       ;
+
+    retry:
+      checksum = 0;
+      xmitcsum = -1;
+      count = 0;
+
+      /* now, read until a # or end of buffer is found */
+      while (count < BUFMAX - 1)
+       {
+         ch = getDebugChar ();
+         if (ch == '$')
+           goto retry;
+         if (ch == '#')
+           break;
+         checksum = checksum + ch;
+         buffer[count] = ch;
+         count = count + 1;
+       }
+      buffer[count] = 0;
+
+      if (ch == '#')
+       {
+         ch = getDebugChar ();
+         xmitcsum = hex (ch) << 4;
+         ch = getDebugChar ();
+         xmitcsum += hex (ch);
+
+         if (checksum != xmitcsum)
+           {
+             if (remote_debug)
+               {
+                 unsigned char buf[16];
+
+                 mem2hex ((unsigned char *) &checksum, buf, 4, 0);
+                 gdb_error ("Bad checksum: my count = %s, ", buf);
+                 mem2hex ((unsigned char *) &xmitcsum, buf, 4, 0);
+                 gdb_error ("sent count = %s\n", buf);
+                 gdb_error (" -- Bad buffer: \"%s\"\n", buffer);
+               }
+             putDebugChar ('-');       /* failed checksum */
+           }
+         else
+           {
+             putDebugChar ('+');       /* successful transfer */
+
+             /* if a sequence char is present, reply the sequence ID */
+             if (buffer[2] == ':')
+               {
+                 putDebugChar (buffer[0]);
+                 putDebugChar (buffer[1]);
+
+                 return &buffer[3];
+               }
+
+             return &buffer[0];
+           }
+       }
+    }
+}
+
+/* send the packet in buffer.  */
+
+static void
+putpacket (unsigned char *buffer)
+{
+  unsigned char checksum;
+  int count;
+  char ch;
+
+  /*  $<packet info>#<checksum>. */
+  do
+    {
+      putDebugChar ('$');
+      checksum = 0;
+      count = 0;
+
+      while (ch = buffer[count])
+       {
+         putDebugChar (ch);
+         checksum += ch;
+         count += 1;
+       }
+      putDebugChar ('#');
+      putDebugChar (hexchars[checksum >> 4]);
+      putDebugChar (hexchars[checksum % 16]);
+    }
+  while (getDebugChar () != '+');
+}
+
+/* Address of a routine to RTE to if we get a memory fault.  */
+
+static void (*volatile mem_fault_routine) () = 0;
+
+static void
+set_mem_err (void)
+{
+  mem_err = 1;
+}
+
+/* Check the address for safe access ranges.  As currently defined,
+   this routine will reject the "expansion bus" address range(s).
+   To make those ranges useable, someone must implement code to detect
+   whether there's anything connected to the expansion bus. */
+
+static int
+mem_safe (unsigned char *addr)
+{
+#define BAD_RANGE_ONE_START    ((unsigned char *) 0x600000)
+#define BAD_RANGE_ONE_END      ((unsigned char *) 0xa00000)
+#define BAD_RANGE_TWO_START    ((unsigned char *) 0xff680000)
+#define BAD_RANGE_TWO_END      ((unsigned char *) 0xff800000)
+
+  if (addr < BAD_RANGE_ONE_START)
+    return 1;                  /* safe */
+  if (addr < BAD_RANGE_ONE_END)
+    return 0;                  /* unsafe */
+  if (addr < BAD_RANGE_TWO_START)
+    return 1;                  /* safe */
+  if (addr < BAD_RANGE_TWO_END)
+    return 0;                  /* unsafe */
+}
+
+/* These are separate functions so that they are so short and sweet
+   that the compiler won't save any registers (if there is a fault
+   to mem_fault, they won't get restored, so there better not be any
+   saved).  */
+static int
+get_char (unsigned char *addr)
+{
+#if 1
+  if (mem_fault_routine && !mem_safe (addr))
+    {
+      mem_fault_routine ();
+      return 0;
+    }
+#endif
+  return *addr;
+}
+
+static void
+set_char (unsigned char *addr, unsigned char val)
+{
+#if 1
+  if (mem_fault_routine && !mem_safe (addr))
+    {
+      mem_fault_routine ();
+      return;
+    }
+#endif
+  *addr = val;
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+   Return a pointer to the last char put in buf (null).
+   If MAY_FAULT is non-zero, then we should set mem_err in response to
+   a fault; if zero treat a fault like any other fault in the stub.  */
+
+static unsigned char *
+mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
+{
+  int i;
+  unsigned char ch;
+
+  if (may_fault)
+    mem_fault_routine = set_mem_err;
+  for (i = 0; i < count; i++)
+    {
+      ch = get_char (mem++);
+      if (may_fault && mem_err)
+       return (buf);
+      *buf++ = hexchars[ch >> 4];
+      *buf++ = hexchars[ch % 16];
+    }
+  *buf = 0;
+  if (may_fault)
+    mem_fault_routine = 0;
+  return (buf);
+}
+
+/* Convert the hex array pointed to by buf into binary to be placed in mem.
+   Return a pointer to the character AFTER the last byte written. */
+
+static unsigned char *
+hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+  int i;
+  unsigned char ch;
+
+  if (may_fault)
+    mem_fault_routine = set_mem_err;
+  for (i = 0; i < count; i++)
+    {
+      ch = hex (*buf++) << 4;
+      ch = ch + hex (*buf++);
+      set_char (mem++, ch);
+      if (may_fault && mem_err)
+       return (mem);
+    }
+  if (may_fault)
+    mem_fault_routine = 0;
+  return (mem);
+}
+
+/* Convert the binary stream in BUF to memory.
+
+   Gdb will escape $, #, and the escape char (0x7d).
+   COUNT is the total number of bytes to write into
+   memory. */
+static unsigned char *
+bin2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+  int i;
+  unsigned char ch;
+
+  if (may_fault)
+    mem_fault_routine = set_mem_err;
+  for (i = 0; i < count; i++)
+    {
+      /* Check for any escaped characters. Be paranoid and
+         only unescape chars that should be escaped. */
+      if (*buf == 0x7d)
+       {
+         switch (*(buf + 1))
+           {
+           case 0x3:           /* # */
+           case 0x4:           /* $ */
+           case 0x5d:          /* escape char */
+             buf++;
+             *buf |= 0x20;
+             break;
+           default:
+             /* nothing */
+             break;
+           }
+       }
+
+      set_char (mem++, *buf++);
+
+      if (may_fault && mem_err)
+       return mem;
+    }
+
+  if (may_fault)
+    mem_fault_routine = 0;
+  return mem;
+}
+
+/* this function takes the m32r exception vector and attempts to
+   translate this number into a unix compatible signal value */
+
+static int
+computeSignal (int exceptionVector)
+{
+  int sigval;
+  switch (exceptionVector)
+    {
+    case 0:
+      sigval = 23;
+      break;                   /* I/O trap                    */
+    case 1:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 2:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 3:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 4:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 5:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 6:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 7:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 8:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 9:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 10:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 11:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 12:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 13:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 14:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 15:
+      sigval = 5;
+      break;                   /* breakpoint                  */
+    case 16:
+      sigval = 10;
+      break;                   /* BUS ERROR (alignment)       */
+    case 17:
+      sigval = 2;
+      break;                   /* INTerrupt                   */
+    default:
+      sigval = 7;
+      break;                   /* "software generated"        */
+    }
+  return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED           */
+/**********************************************/
+static int
+hexToInt (unsigned char **ptr, int *intValue)
+{
+  int numChars = 0;
+  int hexValue;
+
+  *intValue = 0;
+  while (**ptr)
+    {
+      hexValue = hex (**ptr);
+      if (hexValue >= 0)
+       {
+         *intValue = (*intValue << 4) | hexValue;
+         numChars++;
+       }
+      else
+       break;
+      (*ptr)++;
+    }
+  return (numChars);
+}
+
+/*
+  Table of branch instructions:
+  
+  10B6         RTE     return from trap or exception
+  1FCr         JMP     jump
+  1ECr         JL      jump and link
+  7Fxx         BRA     branch
+  FFxxxxxx     BRA     branch (long)
+  B09rxxxx     BNEZ    branch not-equal-zero
+  Br1rxxxx     BNE     branch not-equal
+  7Dxx         BNC     branch not-condition
+  FDxxxxxx     BNC     branch not-condition (long)
+  B0Arxxxx     BLTZ    branch less-than-zero
+  B0Crxxxx     BLEZ    branch less-equal-zero
+  7Exx         BL      branch and link
+  FExxxxxx     BL      branch and link (long)
+  B0Drxxxx     BGTZ    branch greater-than-zero
+  B0Brxxxx     BGEZ    branch greater-equal-zero
+  B08rxxxx     BEQZ    branch equal-zero
+  Br0rxxxx     BEQ     branch equal
+  7Cxx         BC      branch condition
+  FCxxxxxx     BC      branch condition (long)
+  */
+
+static int
+isShortBranch (unsigned char *instr)
+{
+  unsigned char instr0 = instr[0] & 0x7F;      /* mask off high bit */
+
+  if (instr0 == 0x10 && instr[1] == 0xB6)      /* RTE */
+    return 1;                  /* return from trap or exception */
+
+  if (instr0 == 0x1E || instr0 == 0x1F)        /* JL or JMP */
+    if ((instr[1] & 0xF0) == 0xC0)
+      return 2;                        /* jump thru a register */
+
+  if (instr0 == 0x7C || instr0 == 0x7D ||      /* BC, BNC, BL, BRA */
+      instr0 == 0x7E || instr0 == 0x7F)
+    return 3;                  /* eight bit PC offset */
+
+  return 0;
+}
+
+static int
+isLongBranch (unsigned char *instr)
+{
+  if (instr[0] == 0xFC || instr[0] == 0xFD ||  /* BRA, BNC, BL, BC */
+      instr[0] == 0xFE || instr[0] == 0xFF)    /* 24 bit relative */
+    return 4;
+  if ((instr[0] & 0xF0) == 0xB0)       /* 16 bit relative */
+    {
+      if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */
+         (instr[1] & 0xF0) == 0x10)
+       return 5;
+      if (instr[0] == 0xB0)    /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */
+       if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 ||
+           (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 ||
+           (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0)
+         return 6;
+    }
+  return 0;
+}
+
+/* if address is NOT on a 4-byte boundary, or high-bit of instr is zero, 
+   then it's a 2-byte instruction, else it's a 4-byte instruction.  */
+
+#define INSTRUCTION_SIZE(addr) \
+    ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4)
+
+static int
+isBranch (unsigned char *instr)
+{
+  if (INSTRUCTION_SIZE (instr) == 2)
+    return isShortBranch (instr);
+  else
+    return isLongBranch (instr);
+}
+
+static int
+willBranch (unsigned char *instr, int branchCode)
+{
+  switch (branchCode)
+    {
+    case 0:
+      return 0;                        /* not a branch */
+    case 1:
+      return 1;                        /* RTE */
+    case 2:
+      return 1;                        /* JL or JMP    */
+    case 3:                    /* BC, BNC, BL, BRA (short) */
+    case 4:                    /* BC, BNC, BL, BRA (long) */
+      switch (instr[0] & 0x0F)
+       {
+       case 0xC:               /* Branch if Condition Register */
+         return (registers[CBR] != 0);
+       case 0xD:               /* Branch if NOT Condition Register */
+         return (registers[CBR] == 0);
+       case 0xE:               /* Branch and Link */
+       case 0xF:               /* Branch (unconditional) */
+         return 1;
+       default:                /* oops? */
+         return 0;
+       }
+    case 5:                    /* BNE, BEQ */
+      switch (instr[1] & 0xF0)
+       {
+       case 0x00:              /* Branch if r1 equal to r2 */
+         return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]);
+       case 0x10:              /* Branch if r1 NOT equal to r2 */
+         return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]);
+       default:                /* oops? */
+         return 0;
+       }
+    case 6:                    /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */
+      switch (instr[1] & 0xF0)
+       {
+       case 0x80:              /* Branch if reg equal to zero */
+         return (registers[instr[1] & 0x0F] == 0);
+       case 0x90:              /* Branch if reg NOT equal to zero */
+         return (registers[instr[1] & 0x0F] != 0);
+       case 0xA0:              /* Branch if reg less than zero */
+         return (registers[instr[1] & 0x0F] < 0);
+       case 0xB0:              /* Branch if reg greater or equal to zero */
+         return (registers[instr[1] & 0x0F] >= 0);
+       case 0xC0:              /* Branch if reg less than or equal to zero */
+         return (registers[instr[1] & 0x0F] <= 0);
+       case 0xD0:              /* Branch if reg greater than zero */
+         return (registers[instr[1] & 0x0F] > 0);
+       default:                /* oops? */
+         return 0;
+       }
+    default:                   /* oops? */
+      return 0;
+    }
+}
+
+static int
+branchDestination (unsigned char *instr, int branchCode)
+{
+  switch (branchCode)
+    {
+    default:
+    case 0:                    /* not a branch */
+      return 0;
+    case 1:                    /* RTE */
+      return registers[BPC] & ~3;      /* pop BPC into PC */
+    case 2:                    /* JL or JMP */
+      return registers[instr[1] & 0x0F] & ~3;  /* jump thru a register */
+    case 3:                    /* BC, BNC, BL, BRA (short, 8-bit relative offset) */
+      return (((int) instr) & ~3) + ((char) instr[1] << 2);
+    case 4:                    /* BC, BNC, BL, BRA (long, 24-bit relative offset) */
+      return ((int) instr +
+             ((((char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) <<
+              2));
+    case 5:                    /* BNE, BEQ (16-bit relative offset) */
+    case 6:                    /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */
+      return ((int) instr + ((((char) instr[2] << 8) | (instr[3])) << 2));
+    }
+
+  /* An explanatory note: in the last three return expressions, I have
+     cast the most-significant byte of the return offset to char.
+     What this accomplishes is sign extension.  If the other
+     less-significant bytes were signed as well, they would get sign
+     extended too and, if negative, their leading bits would clobber
+     the bits of the more-significant bytes ahead of them.  There are
+     other ways I could have done this, but sign extension from
+     odd-sized integers is always a pain. */
+}
+
+static void
+branchSideEffects (unsigned char *instr, int branchCode)
+{
+  switch (branchCode)
+    {
+    case 1:                    /* RTE */
+      return;                  /* I <THINK> this is already handled... */
+    case 2:                    /* JL (or JMP) */
+    case 3:                    /* BL (or BC, BNC, BRA) */
+    case 4:
+      if ((instr[0] & 0x0F) == 0x0E)   /* branch/jump and link */
+       registers[R14] = (registers[PC] & ~3) + 4;
+      return;
+    default:                   /* any other branch has no side effects */
+      return;
+    }
+}
+
+static struct STEPPING_CONTEXT
+{
+  int stepping;                        /* true when we've started a single-step */
+  unsigned long target_addr;   /* the instr we're trying to execute */
+  unsigned long target_size;   /* the size of the target instr */
+  unsigned long noop_addr;     /* where we've inserted a no-op, if any */
+  unsigned long trap1_addr;    /* the trap following the target instr */
+  unsigned long trap2_addr;    /* the trap at a branch destination, if any */
+  unsigned short noop_save;    /* instruction overwritten by our no-op */
+  unsigned short trap1_save;   /* instruction overwritten by trap1 */
+  unsigned short trap2_save;   /* instruction overwritten by trap2 */
+  unsigned short continue_p;   /* true if NOT returning to gdb after step */
+} stepping;
+
+/* Function: prepare_to_step
+   Called from handle_exception to prepare the user program to single-step.
+   Places a trap instruction after the target instruction, with special 
+   extra handling for branch instructions and for instructions in the 
+   second half-word of a word.  
+
+   Returns: True  if we should actually execute the instruction; 
+           False if we are going to emulate executing the instruction,
+           in which case we simply report to GDB that the instruction 
+           has already been executed.  */
+
+#define TRAP1  0x10f1;         /* trap #1 instruction */
+#define NOOP   0x7000;         /* noop    instruction */
+
+static unsigned short trap1 = TRAP1;
+static unsigned short noop = NOOP;
+
+static int
+prepare_to_step (continue_p)
+     int continue_p;           /* if this isn't REALLY a single-step (see below) */
+{
+  unsigned long pc = registers[PC];
+  int branchCode = isBranch ((unsigned char *) pc);
+  unsigned char *p;
+
+  /* zero out the stepping context 
+     (paranoia -- it should already be zeroed) */
+  for (p = (unsigned char *) &stepping;
+       p < ((unsigned char *) &stepping) + sizeof (stepping); p++)
+    *p = 0;
+
+  if (branchCode != 0)         /* next instruction is a branch */
+    {
+      branchSideEffects ((unsigned char *) pc, branchCode);
+      if (willBranch ((unsigned char *) pc, branchCode))
+       registers[PC] = branchDestination ((unsigned char *) pc, branchCode);
+      else
+       registers[PC] = pc + INSTRUCTION_SIZE (pc);
+      return 0;                        /* branch "executed" -- just notify GDB */
+    }
+  else if (((int) pc & 2) != 0)        /* "second-slot" instruction */
+    {
+      /* insert no-op before pc */
+      stepping.noop_addr = pc - 2;
+      stepping.noop_save = *(unsigned short *) stepping.noop_addr;
+      *(unsigned short *) stepping.noop_addr = noop;
+      /* insert trap  after  pc */
+      stepping.trap1_addr = pc + 2;
+      stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
+      *(unsigned short *) stepping.trap1_addr = trap1;
+    }
+  else                         /* "first-slot" instruction */
+    {
+      /* insert trap  after  pc */
+      stepping.trap1_addr = pc + INSTRUCTION_SIZE (pc);
+      stepping.trap1_save = *(unsigned short *) stepping.trap1_addr;
+      *(unsigned short *) stepping.trap1_addr = trap1;
+    }
+  /* "continue_p" means that we are actually doing a continue, and not 
+     being requested to single-step by GDB.  Sometimes we have to do
+     one single-step before continuing, because the PC is on a half-word
+     boundary.  There's no way to simply resume at such an address.  */
+  stepping.continue_p = continue_p;
+  stepping.stepping = 1;       /* starting a single-step */
+  return 1;
+}
+
+/* Function: finish_from_step
+   Called from handle_exception to finish up when the user program 
+   returns from a single-step.  Replaces the instructions that had
+   been overwritten by traps or no-ops, 
+
+   Returns: True  if we should notify GDB that the target stopped.
+           False if we only single-stepped because we had to before we
+           could continue (ie. we were trying to continue at a 
+           half-word boundary).  In that case don't notify GDB:
+           just "continue continuing".  */
+
+static int
+finish_from_step (void)
+{
+  if (stepping.stepping)       /* anything to do? */
+    {
+      int continue_p = stepping.continue_p;
+      unsigned char *p;
+
+      if (stepping.noop_addr)  /* replace instr "under" our no-op */
+       *(unsigned short *) stepping.noop_addr = stepping.noop_save;
+      if (stepping.trap1_addr) /* replace instr "under" our trap  */
+       *(unsigned short *) stepping.trap1_addr = stepping.trap1_save;
+      if (stepping.trap2_addr) /* ditto our other trap, if any    */
+       *(unsigned short *) stepping.trap2_addr = stepping.trap2_save;
+
+      for (p = (unsigned char *) &stepping;    /* zero out the stepping context */
+          p < ((unsigned char *) &stepping) + sizeof (stepping); p++)
+       *p = 0;
+
+      return !(continue_p);
+    }
+  else                         /* we didn't single-step, therefore this must be a legitimate stop */
+    return 1;
+}
+
+struct PSWreg
+{                              /* separate out the bit flags in the PSW register */
+  int pad1:16;
+  int bsm:1;
+  int bie:1;
+  int pad2:5;
+  int bc:1;
+  int sm:1;
+  int ie:1;
+  int pad3:5;
+  int c:1;
+} *psw;
+
+/* Upon entry the value for LR to save has been pushed.
+   We unpush that so that the value for the stack pointer saved is correct.
+   Upon entry, all other registers are assumed to have not been modified
+   since the interrupt/trap occured.  */
+
+asm ("\n\
+stash_registers:\n\
+       push r0\n\
+       push r1\n\
+       seth r1, #shigh(registers)\n\
+       add3 r1, r1, #low(registers)\n\
+       pop r0          ; r1\n\
+       st r0, @(4,r1)\n\
+       pop r0          ; r0\n\
+       st r0, @r1\n\
+       addi r1, #4     ; only add 4 as subsequent saves are `pre inc'\n\
+       st r2, @+r1\n\
+       st r3, @+r1\n\
+       st r4, @+r1\n\
+       st r5, @+r1\n\
+       st r6, @+r1\n\
+       st r7, @+r1\n\
+       st r8, @+r1\n\
+       st r9, @+r1\n\
+       st r10, @+r1\n\
+       st r11, @+r1\n\
+       st r12, @+r1\n\
+       st r13, @+r1    ; fp\n\
+       pop r0          ; lr (r14)\n\
+       st r0, @+r1\n\
+       st sp, @+r1     ; sp contains right value at this point\n\
+       mvfc r0, cr0\n\
+       st r0, @+r1     ; cr0 == PSW\n\
+       mvfc r0, cr1\n\
+       st r0, @+r1     ; cr1 == CBR\n\
+       mvfc r0, cr2\n\
+       st r0, @+r1     ; cr2 == SPI\n\
+       mvfc r0, cr3\n\
+       st r0, @+r1     ; cr3 == SPU\n\
+       mvfc r0, cr6\n\
+       st r0, @+r1     ; cr6 == BPC\n\
+       st r0, @+r1     ; PC  == BPC\n\
+       mvfaclo r0\n\
+       st r0, @+r1     ; ACCL\n\
+       mvfachi r0\n\
+       st r0, @+r1     ; ACCH\n\
+       jmp lr");
+
+/* C routine to clean up what stash_registers did.
+   It is called after calling stash_registers.
+   This is separate from stash_registers as we want to do this in C
+   but doing stash_registers in C isn't straightforward.  */
+
+static void
+cleanup_stash (void)
+{
+  psw = (struct PSWreg *) &registers[PSW];     /* fields of PSW register */
+  psw->sm = psw->bsm;          /* fix up pre-trap values of psw fields */
+  psw->ie = psw->bie;
+  psw->c = psw->bc;
+  registers[CBR] = psw->bc;    /* fix up pre-trap "C" register */
+
+#if 0                          /* FIXME: Was in previous version.  Necessary?
+                                  (Remember that we use the "rte" insn to return from the
+                                  trap/interrupt so the values of bsm, bie, bc are important.  */
+  psw->bsm = psw->bie = psw->bc = 0;   /* zero post-trap values */
+#endif
+
+  /* FIXME: Copied from previous version.  This can probably be deleted
+     since methinks stash_registers has already done this.  */
+  registers[PC] = registers[BPC];      /* pre-trap PC */
+
+  /* FIXME: Copied from previous version.  Necessary?  */
+  if (psw->sm)                 /* copy R15 into (psw->sm ? SPU : SPI) */
+    registers[SPU] = registers[R15];
+  else
+    registers[SPI] = registers[R15];
+}
+
+asm ("\n\
+restore_and_return:\n\
+       seth r0, #shigh(registers+8)\n\
+       add3 r0, r0, #low(registers+8)\n\
+       ld r2, @r0+     ; restore r2\n\
+       ld r3, @r0+     ; restore r3\n\
+       ld r4, @r0+     ; restore r4\n\
+       ld r5, @r0+     ; restore r5\n\
+       ld r6, @r0+     ; restore r6\n\
+       ld r7, @r0+     ; restore r7\n\
+       ld r8, @r0+     ; restore r8\n\
+       ld r9, @r0+     ; restore r9\n\
+       ld r10, @r0+    ; restore r10\n\
+       ld r11, @r0+    ; restore r11\n\
+       ld r12, @r0+    ; restore r12\n\
+       ld r13, @r0+    ; restore r13\n\
+       ld r14, @r0+    ; restore r14\n\
+       ld r15, @r0+    ; restore r15\n\
+       ld r1, @r0+     ; restore cr0 == PSW\n\
+       mvtc r1, cr0\n\
+       ld r1, @r0+     ; restore cr1 == CBR (no-op, because it's read only)\n\
+       mvtc r1, cr1\n\
+       ld r1, @r0+     ; restore cr2 == SPI\n\
+       mvtc r1, cr2\n\
+       ld r1, @r0+     ; restore cr3 == SPU\n\
+       mvtc r1, cr3\n\
+       addi r0, #4     ; skip BPC\n\
+       ld r1, @r0+     ; restore cr6 (BPC) == PC\n\
+       mvtc r1, cr6\n\
+       ld r1, @r0+     ; restore ACCL\n\
+       mvtaclo r1\n\
+       ld r1, @r0+     ; restore ACCH\n\
+       mvtachi r1\n\
+       seth r0, #shigh(registers)\n\
+       add3 r0, r0, #low(registers)\n\
+       ld r1, @(4,r0)  ; restore r1\n\
+       ld r0, @r0      ; restore r0\n\
+       rte");
+
+/* General trap handler, called after the registers have been stashed.
+   NUM is the trap/exception number.  */
+
+static void
+process_exception (int num)
+{
+  cleanup_stash ();
+  asm volatile ("\n\
+       seth r1, #shigh(stackPtr)\n\
+       add3 r1, r1, #low(stackPtr)\n\
+       ld r15, @r1             ; setup local stack (protect user stack)\n\
+       mv r0, %0\n\
+       bl handle_exception\n\
+       bl restore_and_return"::"r" (num):"r0", "r1");
+}
+
+void _catchException0 ();
+
+asm ("\n\
+_catchException0:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #0\n\
+       bl process_exception");
+
+void _catchException1 ();
+
+asm ("\n\
+_catchException1:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       bl cleanup_stash\n\
+       seth r1, #shigh(stackPtr)\n\
+       add3 r1, r1, #low(stackPtr)\n\
+       ld r15, @r1             ; setup local stack (protect user stack)\n\
+       seth r1, #shigh(registers + 21*4) ; PC\n\
+       add3 r1, r1, #low(registers + 21*4)\n\
+       ld r0, @r1\n\
+       addi r0, #-4            ; back up PC for breakpoint trap.\n\
+       st r0, @r1              ; FIXME: what about bp in right slot?\n\
+       ldi r0, #1\n\
+       bl handle_exception\n\
+       bl restore_and_return");
+
+void _catchException2 ();
+
+asm ("\n\
+_catchException2:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #2\n\
+       bl process_exception");
+
+void _catchException3 ();
+
+asm ("\n\
+_catchException3:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #3\n\
+       bl process_exception");
+
+void _catchException4 ();
+
+asm ("\n\
+_catchException4:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #4\n\
+       bl process_exception");
+
+void _catchException5 ();
+
+asm ("\n\
+_catchException5:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #5\n\
+       bl process_exception");
+
+void _catchException6 ();
+
+asm ("\n\
+_catchException6:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #6\n\
+       bl process_exception");
+
+void _catchException7 ();
+
+asm ("\n\
+_catchException7:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #7\n\
+       bl process_exception");
+
+void _catchException8 ();
+
+asm ("\n\
+_catchException8:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #8\n\
+       bl process_exception");
+
+void _catchException9 ();
+
+asm ("\n\
+_catchException9:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #9\n\
+       bl process_exception");
+
+void _catchException10 ();
+
+asm ("\n\
+_catchException10:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #10\n\
+       bl process_exception");
+
+void _catchException11 ();
+
+asm ("\n\
+_catchException11:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #11\n\
+       bl process_exception");
+
+void _catchException12 ();
+
+asm ("\n\
+_catchException12:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #12\n\
+       bl process_exception");
+
+void _catchException13 ();
+
+asm ("\n\
+_catchException13:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #13\n\
+       bl process_exception");
+
+void _catchException14 ();
+
+asm ("\n\
+_catchException14:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #14\n\
+       bl process_exception");
+
+void _catchException15 ();
+
+asm ("\n\
+_catchException15:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #15\n\
+       bl process_exception");
+
+void _catchException16 ();
+
+asm ("\n\
+_catchException16:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #16\n\
+       bl process_exception");
+
+void _catchException17 ();
+
+asm ("\n\
+_catchException17:\n\
+       push lr\n\
+       bl stash_registers\n\
+       ; Note that at this point the pushed value of `lr' has been popped\n\
+       ldi r0, #17\n\
+       bl process_exception");
+
+
+/* this function is used to set up exception handlers for tracing and
+   breakpoints */
+void
+set_debug_traps (void)
+{
+  /*  extern void remcomHandler(); */
+  int i;
+
+  for (i = 0; i < 18; i++)     /* keep a copy of old vectors */
+    if (save_vectors[i] == 0)  /* only copy them the first time */
+      save_vectors[i] = getExceptionHandler (i);
+
+  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+  exceptionHandler (0, _catchException0);
+  exceptionHandler (1, _catchException1);
+  exceptionHandler (2, _catchException2);
+  exceptionHandler (3, _catchException3);
+  exceptionHandler (4, _catchException4);
+  exceptionHandler (5, _catchException5);
+  exceptionHandler (6, _catchException6);
+  exceptionHandler (7, _catchException7);
+  exceptionHandler (8, _catchException8);
+  exceptionHandler (9, _catchException9);
+  exceptionHandler (10, _catchException10);
+  exceptionHandler (11, _catchException11);
+  exceptionHandler (12, _catchException12);
+  exceptionHandler (13, _catchException13);
+  exceptionHandler (14, _catchException14);
+  exceptionHandler (15, _catchException15);
+  exceptionHandler (16, _catchException16);
+  /*  exceptionHandler (17, _catchException17); */
+
+  initialized = 1;
+}
+
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger. */
+
+#define BREAKPOINT() asm volatile ("   trap #2");
+
+void
+breakpoint (void)
+{
+  if (initialized)
+    BREAKPOINT ();
+}
+
+/* STDOUT section:
+   Stuff pertaining to simulating stdout by sending chars to gdb to be echoed.
+   Functions: gdb_putchar(char ch)
+              gdb_puts(char *str)
+              gdb_write(char *str, int len)
+              gdb_error(char *format, char *parm)
+             */
+
+/* Function: gdb_putchar(int)
+   Make gdb write a char to stdout.
+   Returns: the char */
+
+static int
+gdb_putchar (int ch)
+{
+  char buf[4];
+
+  buf[0] = 'O';
+  buf[1] = hexchars[ch >> 4];
+  buf[2] = hexchars[ch & 0x0F];
+  buf[3] = 0;
+  putpacket (buf);
+  return ch;
+}
+
+/* Function: gdb_write(char *, int)
+   Make gdb write n bytes to stdout (not assumed to be null-terminated).
+   Returns: number of bytes written */
+
+static int
+gdb_write (char *data, int len)
+{
+  char *buf, *cpy;
+  int i;
+
+  buf = remcomOutBuffer;
+  buf[0] = 'O';
+  i = 0;
+  while (i < len)
+    {
+      for (cpy = buf + 1;
+          i < len && cpy < buf + sizeof (remcomOutBuffer) - 3; i++)
+       {
+         *cpy++ = hexchars[data[i] >> 4];
+         *cpy++ = hexchars[data[i] & 0x0F];
+       }
+      *cpy = 0;
+      putpacket (buf);
+    }
+  return len;
+}
+
+/* Function: gdb_puts(char *)
+   Make gdb write a null-terminated string to stdout.
+   Returns: the length of the string */
+
+static int
+gdb_puts (char *str)
+{
+  return gdb_write (str, strlen (str));
+}
+
+/* Function: gdb_error(char *, char *)
+   Send an error message to gdb's stdout.
+   First string may have 1 (one) optional "%s" in it, which
+   will cause the optional second string to be inserted.  */
+
+static void
+gdb_error (char *format, char *parm)
+{
+  char buf[400], *cpy;
+  int len;
+
+  if (remote_debug)
+    {
+      if (format && *format)
+       len = strlen (format);
+      else
+       return;                 /* empty input */
+
+      if (parm && *parm)
+       len += strlen (parm);
+
+      for (cpy = buf; *format;)
+       {
+         if (format[0] == '%' && format[1] == 's')     /* include second string */
+           {
+             format += 2;      /* advance two chars instead of just one */
+             while (parm && *parm)
+               *cpy++ = *parm++;
+           }
+         else
+           *cpy++ = *format++;
+       }
+      *cpy = '\0';
+      gdb_puts (buf);
+    }
+}
+
+static unsigned char *
+strcpy (unsigned char *dest, const unsigned char *src)
+{
+  unsigned char *ret = dest;
+
+  if (dest && src)
+    {
+      while (*src)
+       *dest++ = *src++;
+      *dest = 0;
+    }
+  return ret;
+}
+
+static int
+strlen (const unsigned char *src)
+{
+  int ret;
+
+  for (ret = 0; *src; src++)
+    ret++;
+
+  return ret;
+}
+
+#if 0
+void
+exit (code)
+     int code;
+{
+  _exit (code);
+}
+
+int
+atexit (void *p)
+{
+  return 0;
+}
+
+void
+abort (void)
+{
+  _exit (1);
+}
+#endif
diff --git a/gdb/stubs/m68k-stub.c b/gdb/stubs/m68k-stub.c
new file mode 100644 (file)
index 0000000..4ef4069
--- /dev/null
@@ -0,0 +1,1098 @@
+/****************************************************************************
+
+               THIS SOFTWARE IS NOT COPYRIGHTED  
+   
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the 
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $                   
+ *
+ *  Module name: remcom.c $  
+ *  Revision: 1.34 $
+ *  Date: 91/03/09 12:29:49 $
+ *  Contributor:     Lake Stevens Instrument Division$
+ *  
+ *  Description:     low level support for gdb debugger. $
+ *
+ *  Considerations:  only works on target hardware $
+ *
+ *  Written by:      Glenn Engel $
+ *  ModuleState:     Experimental $ 
+ *
+ *  NOTES:           See Below $
+ * 
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a trap #1.  The breakpoint instruction
+ *  is hardwired to trap #1 because not to do so is a compatibility problem--
+ *  there either should be a standard breakpoint instruction, or the protocol
+ *  should be extended to provide some means to communicate which breakpoint
+ *  instruction is in use (or have the stub insert the breakpoint).
+ *  
+ *  Some explanation is probably necessary to explain how exceptions are
+ *  handled.  When an exception is encountered the 68000 pushes the current
+ *  program counter and status register onto the supervisor stack and then
+ *  transfers execution to a location specified in it's vector table.
+ *  The handlers for the exception vectors are hardwired to jmp to an address
+ *  given by the relation:  (exception - 256) * 6.  These are decending 
+ *  addresses starting from -6, -12, -18, ...  By allowing 6 bytes for
+ *  each entry, a jsr, jmp, bsr, ... can be used to enter the exception 
+ *  handler.  Using a jsr to handle an exception has an added benefit of
+ *  allowing a single handler to service several exceptions and use the
+ *  return address as the key differentiation.  The vector number can be
+ *  computed from the return address by [ exception = (addr + 1530) / 6 ].
+ *  The sole purpose of the routine _catchException is to compute the
+ *  exception number and push it on the stack in place of the return address.
+ *  The external function exceptionHandler() is
+ *  used to attach a specific handler to a specific m68k exception.
+ *  For 68020 machines, the ability to have a return address around just
+ *  so the vector can be determined is not necessary because the '020 pushes an
+ *  extra word onto the stack containing the vector offset
+ * 
+ *  Because gdb will sometimes write to the stack area to execute function
+ *  calls, this program cannot rely on using the supervisor stack so it
+ *  uses it's own stack area reserved in the int array remcomStack.  
+ * 
+ *************
+ *
+ *    The following gdb commands are supported:
+ * 
+ * command          function                               Return value
+ * 
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ * 
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ * 
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ * 
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ * 
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ * 
+ * All commands and responses are sent with a packet which includes a 
+ * checksum.  A packet consists of 
+ * 
+ * $<packet info>#<checksum>.
+ * 
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ * 
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ * 
+ * Example:
+ * 
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ * 
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+
+/************************************************************************
+ *
+ * external low-level support routines 
+ */
+typedef void (*ExceptionHook)(int);   /* pointer to function with int parm */
+typedef void (*Function)();           /* pointer to a function */
+
+extern void putDebugChar();    /* write a single character      */
+extern int getDebugChar();     /* read and return a single char */
+
+extern Function exceptionHandler();  /* assign an exception handler */
+extern ExceptionHook exceptionHook;  /* hook variable for errors/exceptions */
+
+/************************/
+/* FORWARD DECLARATIONS */
+/************************/
+static void
+initializeRemcomErrorFrame ();
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized;  /* boolean flag. != 0 means we've been initialized */
+
+int     remote_debug;
+/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */ 
+
+static const char hexchars[]="0123456789abcdef";
+
+/* there are 180 bytes of registers on a 68020 w/68881      */
+/* many of the fpa registers are 12 byte (96 bit) registers */
+#define NUMREGBYTES 180
+enum regnames {D0,D1,D2,D3,D4,D5,D6,D7, 
+               A0,A1,A2,A3,A4,A5,A6,A7, 
+               PS,PC,
+               FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
+               FPCONTROL,FPSTATUS,FPIADDR
+              };
+
+\f
+/* We keep a whole frame cache here.  "Why?", I hear you cry, "doesn't
+   GDB handle that sort of thing?"  Well, yes, I believe the only
+   reason for this cache is to save and restore floating point state
+   (fsave/frestore).  A cleaner way to do this would be to make the
+ fsave data part of the registers which GDB deals with like any
+   other registers.  This should not be a performance problem if the
+   ability to read individual registers is added to the protocol.  */
+
+typedef struct FrameStruct
+{
+    struct FrameStruct  *previous;
+    int       exceptionPC;      /* pc value when this frame created */
+    int       exceptionVector;  /* cpu vector causing exception     */
+    short     frameSize;        /* size of cpu frame in words       */
+    short     sr;               /* for 68000, this not always sr    */
+    int       pc;
+    short     format;
+    int       fsaveHeader;
+    int       morejunk[0];        /* exception frame, fp save... */
+} Frame;
+
+#define FRAMESIZE 500
+int   gdbFrameStack[FRAMESIZE];
+static Frame *lastFrame;
+
+/*
+ * these should not be static cuz they can be used outside this module
+ */
+int registers[NUMREGBYTES/4];
+int superStack;
+
+#define STACKSIZE 10000
+int remcomStack[STACKSIZE/sizeof(int)];
+static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+/*
+ * In many cases, the system will want to continue exception processing
+ * when a continue command is given.  
+ * oldExceptionHook is a function to invoke in this case.
+ */
+
+static ExceptionHook oldExceptionHook;
+
+#ifdef mc68020
+/* the size of the exception stack on the 68020 varies with the type of
+ * exception.  The following table is the number of WORDS used
+ * for each exception format.
+ */
+const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
+#endif
+
+#ifdef mc68332
+static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 };
+#endif
+
+/************* jump buffer used for setjmp/longjmp **************************/
+jmp_buf remcomEnv;
+
+/***************************  ASSEMBLY CODE MACROS *************************/
+/*                                                                        */
+
+#ifdef __HAVE_68881__
+/* do an fsave, then remember the address to begin a restore from */
+#define SAVE_FP_REGS()    asm(" fsave   a0@-");                \
+                         asm(" fmovemx fp0-fp7,_registers+72");        \
+                         asm(" fmoveml fpcr/fpsr/fpi,_registers+168"); 
+#define RESTORE_FP_REGS()                              \
+asm("                                                \n\
+    fmoveml  _registers+168,fpcr/fpsr/fpi            \n\
+    fmovemx  _registers+72,fp0-fp7                   \n\
+    cmpl     #-1,a0@     |  skip frestore flag set ? \n\
+    beq      skip_frestore                           \n\
+    frestore a0@+                                    \n\
+skip_frestore:                                       \n\
+");
+
+#else
+#define SAVE_FP_REGS()
+#define RESTORE_FP_REGS()
+#endif /* __HAVE_68881__ */
+
+void return_to_super();
+void return_to_user();
+
+asm("
+.text
+.globl _return_to_super
+_return_to_super:
+        movel   _registers+60,sp /* get new stack pointer */        
+        movel   _lastFrame,a0   /* get last frame info  */              
+        bra     return_to_any
+
+.globl _return_to_user
+_return_to_user:
+        movel   _registers+60,a0 /* get usp */                          
+        movel   a0,usp           /* set usp */                         
+        movel   _superStack,sp  /* get original stack pointer */        
+
+return_to_any:
+        movel   _lastFrame,a0   /* get last frame info  */              
+        movel   a0@+,_lastFrame /* link in previous frame     */        
+        addql   #8,a0           /* skip over pc, vector#*/              
+        movew   a0@+,d0         /* get # of words in cpu frame */       
+        addw    d0,a0           /* point to end of data        */       
+        addw    d0,a0           /* point to end of data        */       
+        movel   a0,a1                                                   
+#                                                                       
+# copy the stack frame                                                  
+        subql   #1,d0                                                   
+copyUserLoop:                                                               
+        movew   a1@-,sp@-                                               
+        dbf     d0,copyUserLoop                                             
+");                                                                     
+        RESTORE_FP_REGS()                                              
+   asm("   moveml  _registers,d0-d7/a0-a6");                           
+   asm("   rte");  /* pop and go! */                                    
+
+#define DISABLE_INTERRUPTS()   asm("         oriw   #0x0700,sr");
+#define BREAKPOINT() asm("   trap #1");
+
+/* this function is called immediately when a level 7 interrupt occurs */
+/* if the previous interrupt level was 7 then we're already servicing  */
+/* this interrupt and an rte is in order to return to the debugger.    */
+/* For the 68000, the offset for sr is 6 due to the jsr return address */
+asm("
+.text
+.globl __debug_level7
+__debug_level7:
+       movew   d0,sp@-");
+#if defined (mc68020) || defined (mc68332)
+asm("  movew   sp@(2),d0");
+#else
+asm("  movew   sp@(6),d0");
+#endif
+asm("  andiw   #0x700,d0
+       cmpiw   #0x700,d0
+       beq     _already7
+        movew   sp@+,d0        
+        bra     __catchException
+_already7:
+       movew   sp@+,d0");
+#if !defined (mc68020) && !defined (mc68332)
+asm("  lea     sp@(4),sp");     /* pull off 68000 return address */
+#endif
+asm("  rte");
+
+extern void _catchException ();
+
+#if defined (mc68020) || defined (mc68332)
+/* This function is called when a 68020 exception occurs.  It saves
+ * all the cpu and fpcp regs in the _registers array, creates a frame on a
+ * linked list of frames which has the cpu and fpcp stack frames needed
+ * to properly restore the context of these processors, and invokes
+ * an exception handler (remcom_handler).
+ *
+ * stack on entry:                       stack on exit:
+ *   N bytes of junk                     exception # MSWord
+ *   Exception Format Word               exception # MSWord
+ *   Program counter LSWord              
+ *   Program counter MSWord             
+ *   Status Register                    
+ *                                       
+ *                                       
+ */
+asm(" 
+.text
+.globl __catchException
+__catchException:");
+DISABLE_INTERRUPTS();
+asm("
+        moveml  d0-d7/a0-a6,_registers /* save registers        */
+       movel   _lastFrame,a0   /* last frame pointer */
+");
+SAVE_FP_REGS();        
+asm("
+       lea     _registers,a5   /* get address of registers     */
+        movew   sp@,d1          /* get status register          */
+        movew   d1,a5@(66)      /* save sr                     */      
+       movel   sp@(2),a4       /* save pc in a4 for later use  */
+        movel   a4,a5@(68)      /* save pc in _regisers[]              */
+
+#
+# figure out how many bytes in the stack frame
+       movew   sp@(6),d0       /* get '020 exception format    */
+        movew   d0,d2           /* make a copy of format word   */
+        andiw   #0xf000,d0      /* mask off format type         */
+        rolw    #5,d0           /* rotate into the low byte *2  */
+        lea     _exceptionSize,a1   
+        addw    d0,a1           /* index into the table         */
+       movew   a1@,d0          /* get number of words in frame */
+        movew   d0,d3           /* save it                      */
+        subw    d0,a0          /* adjust save pointer          */
+        subw    d0,a0          /* adjust save pointer(bytes)   */
+       movel   a0,a1           /* copy save pointer            */
+       subql   #1,d0           /* predecrement loop counter    */
+#
+# copy the frame
+saveFrameLoop:
+       movew   sp@+,a1@+
+       dbf     d0,saveFrameLoop
+#
+# now that the stack has been clenaed,
+# save the a7 in use at time of exception
+        movel   sp,_superStack  /* save supervisor sp           */
+        andiw   #0x2000,d1      /* were we in supervisor mode ? */
+        beq     userMode       
+        movel   a7,a5@(60)      /* save a7                  */
+        bra     a7saveDone
+userMode:  
+       movel   usp,a1          
+        movel   a1,a5@(60)      /* save user stack pointer     */
+a7saveDone:
+
+#
+# save size of frame
+        movew   d3,a0@-
+
+#
+# compute exception number
+       andl    #0xfff,d2       /* mask off vector offset       */
+       lsrw    #2,d2           /* divide by 4 to get vect num  */
+        movel   d2,a0@-         /* save it                      */
+#
+# save pc causing exception
+        movel   a4,a0@-
+#
+# save old frame link and set the new value
+       movel   _lastFrame,a1   /* last frame pointer */
+       movel   a1,a0@-         /* save pointer to prev frame   */
+        movel   a0,_lastFrame
+
+        movel   d2,sp@-                /* push exception num           */
+       movel   _exceptionHook,a0  /* get address of handler */
+        jbsr    a0@             /* and call it */
+        clrl    sp@             /* replace exception num parm with frame ptr */
+        jbsr     __returnFromException   /* jbsr, but never returns */
+");
+#else /* mc68000 */
+/* This function is called when an exception occurs.  It translates the
+ * return address found on the stack into an exception vector # which
+ * is then handled by either handle_exception or a system handler.
+ * _catchException provides a front end for both.  
+ *
+ * stack on entry:                       stack on exit:
+ *   Program counter MSWord              exception # MSWord 
+ *   Program counter LSWord              exception # MSWord
+ *   Status Register                     
+ *   Return Address  MSWord              
+ *   Return Address  LSWord             
+ */
+asm("
+.text
+.globl __catchException
+__catchException:");
+DISABLE_INTERRUPTS();
+asm("
+        moveml d0-d7/a0-a6,_registers  /* save registers               */
+       movel   _lastFrame,a0   /* last frame pointer */
+");
+SAVE_FP_REGS();        
+asm("
+        lea     _registers,a5   /* get address of registers     */
+        movel   sp@+,d2         /* pop return address           */
+       addl    #1530,d2        /* convert return addr to       */
+       divs    #6,d2           /*  exception number            */
+       extl    d2   
+
+        moveql  #3,d3           /* assume a three word frame     */
+
+        cmpiw   #3,d2           /* bus error or address error ? */
+        bgt     normal          /* if >3 then normal error      */
+        movel   sp@+,a0@-       /* copy error info to frame buff*/
+        movel   sp@+,a0@-       /* these are never used         */
+        moveql  #7,d3           /* this is a 7 word frame       */
+     
+normal:   
+       movew   sp@+,d1         /* pop status register          */
+        movel   sp@+,a4         /* pop program counter          */
+        movew   d1,a5@(66)      /* save sr                     */      
+        movel   a4,a5@(68)      /* save pc in _regisers[]              */
+        movel   a4,a0@-         /* copy pc to frame buffer      */
+       movew   d1,a0@-         /* copy sr to frame buffer      */
+
+        movel   sp,_superStack  /* save supervisor sp          */
+
+        andiw   #0x2000,d1      /* were we in supervisor mode ? */
+        beq     userMode       
+        movel   a7,a5@(60)      /* save a7                  */
+        bra     saveDone             
+userMode:
+        movel   usp,a1         /* save user stack pointer      */
+        movel   a1,a5@(60)      /* save user stack pointer     */
+saveDone:
+
+        movew   d3,a0@-         /* push frame size in words     */
+        movel   d2,a0@-         /* push vector number           */
+        movel   a4,a0@-         /* push exception pc            */
+
+#
+# save old frame link and set the new value
+       movel   _lastFrame,a1   /* last frame pointer */
+       movel   a1,a0@-         /* save pointer to prev frame   */
+        movel   a0,_lastFrame
+
+        movel   d2,sp@-                /* push exception num           */
+       movel   _exceptionHook,a0  /* get address of handler */
+        jbsr    a0@             /* and call it */
+        clrl    sp@             /* replace exception num parm with frame ptr */
+        jbsr     __returnFromException   /* jbsr, but never returns */
+");
+#endif
+
+
+/*
+ * remcomHandler is a front end for handle_exception.  It moves the
+ * stack pointer into an area reserved for debugger use in case the
+ * breakpoint happened in supervisor mode.
+ */
+asm("_remcomHandler:");
+asm("           addl    #4,sp");        /* pop off return address     */
+asm("           movel   sp@+,d0");      /* get the exception number   */
+asm("          movel   _stackPtr,sp"); /* move to remcom stack area  */
+asm("          movel   d0,sp@-");      /* push exception onto stack  */
+asm("          jbsr    _handle_exception");    /* this never returns */
+asm("           rts");                  /* return */
+
+void
+_returnFromException (Frame * frame)
+{
+  /* if no passed in frame, use the last one */
+  if (!frame)
+    {
+      frame = lastFrame;
+      frame->frameSize = 4;
+      frame->format = 0;
+      frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info */
+    }
+
+#if !defined (mc68020) && !defined (mc68332)
+  /* a 68000 cannot use the internal info pushed onto a bus error
+   * or address error frame when doing an RTE so don't put this info
+   * onto the stack or the stack will creep every time this happens.
+   */
+  frame->frameSize = 3;
+#endif
+
+  /* throw away any frames in the list after this frame */
+  lastFrame = frame;
+
+  frame->sr = registers[(int) PS];
+  frame->pc = registers[(int) PC];
+
+  if (registers[(int) PS] & 0x2000)
+    {
+      /* return to supervisor mode... */
+      return_to_super ();
+    }
+  else
+    {                          /* return to user mode */
+      return_to_user ();
+    }
+}
+
+int
+hex (ch)
+     char ch;
+{
+  if ((ch >= 'a') && (ch <= 'f'))
+    return (ch - 'a' + 10);
+  if ((ch >= '0') && (ch <= '9'))
+    return (ch - '0');
+  if ((ch >= 'A') && (ch <= 'F'))
+    return (ch - 'A' + 10);
+  return (-1);
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum>     */
+
+unsigned char *
+getpacket (void)
+{
+  unsigned char *buffer = &remcomInBuffer[0];
+  unsigned char checksum;
+  unsigned char xmitcsum;
+  int count;
+  char ch;
+
+  while (1)
+    {
+      /* wait around for the start character, ignore all other characters */
+      while ((ch = getDebugChar ()) != '$')
+       ;
+
+    retry:
+      checksum = 0;
+      xmitcsum = -1;
+      count = 0;
+
+      /* now, read until a # or end of buffer is found */
+      while (count < BUFMAX - 1)
+       {
+         ch = getDebugChar ();
+         if (ch == '$')
+           goto retry;
+         if (ch == '#')
+           break;
+         checksum = checksum + ch;
+         buffer[count] = ch;
+         count = count + 1;
+       }
+      buffer[count] = 0;
+
+      if (ch == '#')
+       {
+         ch = getDebugChar ();
+         xmitcsum = hex (ch) << 4;
+         ch = getDebugChar ();
+         xmitcsum += hex (ch);
+
+         if (checksum != xmitcsum)
+           {
+             if (remote_debug)
+               {
+                 fprintf (stderr,
+                          "bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
+                          checksum, xmitcsum, buffer);
+               }
+             putDebugChar ('-');       /* failed checksum */
+           }
+         else
+           {
+             putDebugChar ('+');       /* successful transfer */
+
+             /* if a sequence char is present, reply the sequence ID */
+             if (buffer[2] == ':')
+               {
+                 putDebugChar (buffer[0]);
+                 putDebugChar (buffer[1]);
+
+                 return &buffer[3];
+               }
+
+             return &buffer[0];
+           }
+       }
+    }
+}
+
+/* send the packet in buffer. */
+
+void
+putpacket (buffer)
+     char *buffer;
+{
+  unsigned char checksum;
+  int count;
+  char ch;
+
+  /*  $<packet info>#<checksum>. */
+  do
+    {
+      putDebugChar ('$');
+      checksum = 0;
+      count = 0;
+
+      while (ch = buffer[count])
+       {
+         putDebugChar (ch);
+         checksum += ch;
+         count += 1;
+       }
+
+      putDebugChar ('#');
+      putDebugChar (hexchars[checksum >> 4]);
+      putDebugChar (hexchars[checksum % 16]);
+
+    }
+  while (getDebugChar () != '+');
+
+}
+
+void
+debug_error (format, parm)
+     char *format;
+     char *parm;
+{
+  if (remote_debug)
+    fprintf (stderr, format, parm);
+}
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+char *
+mem2hex (mem, buf, count)
+     char *mem;
+     char *buf;
+     int count;
+{
+  int i;
+  unsigned char ch;
+  for (i = 0; i < count; i++)
+    {
+      ch = *mem++;
+      *buf++ = hexchars[ch >> 4];
+      *buf++ = hexchars[ch % 16];
+    }
+  *buf = 0;
+  return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+char *
+hex2mem (buf, mem, count)
+     char *buf;
+     char *mem;
+     int count;
+{
+  int i;
+  unsigned char ch;
+  for (i = 0; i < count; i++)
+    {
+      ch = hex (*buf++) << 4;
+      ch = ch + hex (*buf++);
+      *mem++ = ch;
+    }
+  return (mem);
+}
+
+/* a bus error has occurred, perform a longjmp
+   to return execution and allow handling of the error */
+
+void
+handle_buserror ()
+{
+  longjmp (remcomEnv, 1);
+}
+
+/* this function takes the 68000 exception number and attempts to 
+   translate this number into a unix compatible signal value */
+int
+computeSignal (exceptionVector)
+     int exceptionVector;
+{
+  int sigval;
+  switch (exceptionVector)
+    {
+    case 2:
+      sigval = 10;
+      break;                   /* bus error           */
+    case 3:
+      sigval = 10;
+      break;                   /* address error       */
+    case 4:
+      sigval = 4;
+      break;                   /* illegal instruction */
+    case 5:
+      sigval = 8;
+      break;                   /* zero divide         */
+    case 6:
+      sigval = 8;
+      break;                   /* chk instruction     */
+    case 7:
+      sigval = 8;
+      break;                   /* trapv instruction   */
+    case 8:
+      sigval = 11;
+      break;                   /* privilege violation */
+    case 9:
+      sigval = 5;
+      break;                   /* trace trap          */
+    case 10:
+      sigval = 4;
+      break;                   /* line 1010 emulator  */
+    case 11:
+      sigval = 4;
+      break;                   /* line 1111 emulator  */
+
+      /* Coprocessor protocol violation.  Using a standard MMU or FPU
+         this cannot be triggered by software.  Call it a SIGBUS.  */
+    case 13:
+      sigval = 10;
+      break;
+
+    case 31:
+      sigval = 2;
+      break;                   /* interrupt           */
+    case 33:
+      sigval = 5;
+      break;                   /* breakpoint          */
+
+      /* This is a trap #8 instruction.  Apparently it is someone's software
+         convention for some sort of SIGFPE condition.  Whose?  How many
+         people are being screwed by having this code the way it is?
+         Is there a clean solution?  */
+    case 40:
+      sigval = 8;
+      break;                   /* floating point err  */
+
+    case 48:
+      sigval = 8;
+      break;                   /* floating point err  */
+    case 49:
+      sigval = 8;
+      break;                   /* floating point err  */
+    case 50:
+      sigval = 8;
+      break;                   /* zero divide         */
+    case 51:
+      sigval = 8;
+      break;                   /* underflow           */
+    case 52:
+      sigval = 8;
+      break;                   /* operand error       */
+    case 53:
+      sigval = 8;
+      break;                   /* overflow            */
+    case 54:
+      sigval = 8;
+      break;                   /* NAN                 */
+    default:
+      sigval = 7;              /* "software generated" */
+    }
+  return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED           */
+/**********************************************/
+int
+hexToInt (char **ptr, int *intValue)
+{
+  int numChars = 0;
+  int hexValue;
+
+  *intValue = 0;
+
+  while (**ptr)
+    {
+      hexValue = hex (**ptr);
+      if (hexValue >= 0)
+       {
+         *intValue = (*intValue << 4) | hexValue;
+         numChars++;
+       }
+      else
+       break;
+
+      (*ptr)++;
+    }
+
+  return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void
+handle_exception (int exceptionVector)
+{
+  int sigval, stepping;
+  int addr, length;
+  char *ptr;
+  int newPC;
+  Frame *frame;
+
+  if (remote_debug)
+    printf ("vector=%d, sr=0x%x, pc=0x%x\n",
+           exceptionVector, registers[PS], registers[PC]);
+
+  /* reply to host that an exception has occurred */
+  sigval = computeSignal (exceptionVector);
+  remcomOutBuffer[0] = 'S';
+  remcomOutBuffer[1] = hexchars[sigval >> 4];
+  remcomOutBuffer[2] = hexchars[sigval % 16];
+  remcomOutBuffer[3] = 0;
+
+  putpacket (remcomOutBuffer);
+
+  stepping = 0;
+
+  while (1 == 1)
+    {
+      remcomOutBuffer[0] = 0;
+      ptr = getpacket ();
+      switch (*ptr++)
+       {
+       case '?':
+         remcomOutBuffer[0] = 'S';
+         remcomOutBuffer[1] = hexchars[sigval >> 4];
+         remcomOutBuffer[2] = hexchars[sigval % 16];
+         remcomOutBuffer[3] = 0;
+         break;
+       case 'd':
+         remote_debug = !(remote_debug);       /* toggle debug flag */
+         break;
+       case 'g':               /* return the value of the CPU registers */
+         mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
+         break;
+       case 'G':               /* set the value of the CPU registers - return OK */
+         hex2mem (ptr, (char *) registers, NUMREGBYTES);
+         strcpy (remcomOutBuffer, "OK");
+         break;
+
+         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+       case 'm':
+         if (setjmp (remcomEnv) == 0)
+           {
+             exceptionHandler (2, handle_buserror);
+
+             /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
+             if (hexToInt (&ptr, &addr))
+               if (*(ptr++) == ',')
+                 if (hexToInt (&ptr, &length))
+                   {
+                     ptr = 0;
+                     mem2hex ((char *) addr, remcomOutBuffer, length);
+                   }
+
+             if (ptr)
+               {
+                 strcpy (remcomOutBuffer, "E01");
+               }
+           }
+         else
+           {
+             exceptionHandler (2, _catchException);
+             strcpy (remcomOutBuffer, "E03");
+             debug_error ("bus error");
+           }
+
+         /* restore handler for bus error */
+         exceptionHandler (2, _catchException);
+         break;
+
+         /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+       case 'M':
+         if (setjmp (remcomEnv) == 0)
+           {
+             exceptionHandler (2, handle_buserror);
+
+             /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
+             if (hexToInt (&ptr, &addr))
+               if (*(ptr++) == ',')
+                 if (hexToInt (&ptr, &length))
+                   if (*(ptr++) == ':')
+                     {
+                       hex2mem (ptr, (char *) addr, length);
+                       ptr = 0;
+                       strcpy (remcomOutBuffer, "OK");
+                     }
+             if (ptr)
+               {
+                 strcpy (remcomOutBuffer, "E02");
+               }
+           }
+         else
+           {
+             exceptionHandler (2, _catchException);
+             strcpy (remcomOutBuffer, "E03");
+             debug_error ("bus error");
+           }
+
+         /* restore handler for bus error */
+         exceptionHandler (2, _catchException);
+         break;
+
+         /* cAA..AA    Continue at address AA..AA(optional) */
+         /* sAA..AA   Step one instruction from AA..AA(optional) */
+       case 's':
+         stepping = 1;
+       case 'c':
+         /* try to read optional parameter, pc unchanged if no parm */
+         if (hexToInt (&ptr, &addr))
+           registers[PC] = addr;
+
+         newPC = registers[PC];
+
+         /* clear the trace bit */
+         registers[PS] &= 0x7fff;
+
+         /* set the trace bit if we're stepping */
+         if (stepping)
+           registers[PS] |= 0x8000;
+
+         /*
+          * look for newPC in the linked list of exception frames.
+          * if it is found, use the old frame it.  otherwise,
+          * fake up a dummy frame in returnFromException().
+          */
+         if (remote_debug)
+           printf ("new pc = 0x%x\n", newPC);
+         frame = lastFrame;
+         while (frame)
+           {
+             if (remote_debug)
+               printf ("frame at 0x%x has pc=0x%x, except#=%d\n",
+                       frame, frame->exceptionPC, frame->exceptionVector);
+             if (frame->exceptionPC == newPC)
+               break;          /* bingo! a match */
+             /*
+              * for a breakpoint instruction, the saved pc may
+              * be off by two due to re-executing the instruction
+              * replaced by the trap instruction.  Check for this.
+              */
+             if ((frame->exceptionVector == 33) &&
+                 (frame->exceptionPC == (newPC + 2)))
+               break;
+             if (frame == frame->previous)
+               {
+                 frame = 0;    /* no match found */
+                 break;
+               }
+             frame = frame->previous;
+           }
+
+         /*
+          * If we found a match for the PC AND we are not returning
+          * as a result of a breakpoint (33),
+          * trace exception (9), nmi (31), jmp to
+          * the old exception handler as if this code never ran.
+          */
+         if (frame)
+           {
+             if ((frame->exceptionVector != 9) &&
+                 (frame->exceptionVector != 31) &&
+                 (frame->exceptionVector != 33))
+               {
+                 /*
+                  * invoke the previous handler.
+                  */
+                 if (oldExceptionHook)
+                   (*oldExceptionHook) (frame->exceptionVector);
+                 newPC = registers[PC];        /* pc may have changed  */
+                 if (newPC != frame->exceptionPC)
+                   {
+                     if (remote_debug)
+                       printf ("frame at 0x%x has pc=0x%x, except#=%d\n",
+                               frame, frame->exceptionPC,
+                               frame->exceptionVector);
+                     /* re-use the last frame, we're skipping it (longjump?) */
+                     frame = (Frame *) 0;
+                     _returnFromException (frame);     /* this is a jump */
+                   }
+               }
+           }
+
+         /* if we couldn't find a frame, create one */
+         if (frame == 0)
+           {
+             frame = lastFrame - 1;
+
+             /* by using a bunch of print commands with breakpoints,
+                it's possible for the frame stack to creep down.  If it creeps
+                too far, give up and reset it to the top.  Normal use should
+                not see this happen.
+              */
+             if ((unsigned int) (frame - 2) < (unsigned int) &gdbFrameStack)
+               {
+                 initializeRemcomErrorFrame ();
+                 frame = lastFrame;
+               }
+             frame->previous = lastFrame;
+             lastFrame = frame;
+             frame = 0;        /* null so _return... will properly initialize it */
+           }
+
+         _returnFromException (frame); /* this is a jump */
+
+         break;
+
+         /* kill the program */
+       case 'k':               /* do nothing */
+         break;
+       }                       /* switch */
+
+      /* reply to the request */
+      putpacket (remcomOutBuffer);
+    }
+}
+
+
+void
+initializeRemcomErrorFrame (void)
+{
+  lastFrame = ((Frame *) & gdbFrameStack[FRAMESIZE - 1]) - 1;
+  lastFrame->previous = lastFrame;
+}
+
+/* this function is used to set up exception handlers for tracing and 
+   breakpoints */
+void
+set_debug_traps ()
+{
+  extern void _debug_level7 ();
+  extern void remcomHandler ();
+  int exception;
+
+  initializeRemcomErrorFrame ();
+  stackPtr = &remcomStack[STACKSIZE / sizeof (int) - 1];
+
+  for (exception = 2; exception <= 23; exception++)
+    exceptionHandler (exception, _catchException);
+
+  /* level 7 interrupt              */
+  exceptionHandler (31, _debug_level7);
+
+  /* breakpoint exception (trap #1) */
+  exceptionHandler (33, _catchException);
+
+  /* This is a trap #8 instruction.  Apparently it is someone's software
+     convention for some sort of SIGFPE condition.  Whose?  How many
+     people are being screwed by having this code the way it is?
+     Is there a clean solution?  */
+  exceptionHandler (40, _catchException);
+
+  /* 48 to 54 are floating point coprocessor errors */
+  for (exception = 48; exception <= 54; exception++)
+    exceptionHandler (exception, _catchException);
+
+  if (oldExceptionHook != remcomHandler)
+    {
+      oldExceptionHook = exceptionHook;
+      exceptionHook = remcomHandler;
+    }
+
+  initialized = 1;
+
+}
+
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger. */
+
+void
+breakpoint ()
+{
+  if (initialized)
+    BREAKPOINT ();
+}
diff --git a/gdb/stubs/sh-stub.c b/gdb/stubs/sh-stub.c
new file mode 100644 (file)
index 0000000..76c98a5
--- /dev/null
@@ -0,0 +1,1583 @@
+/* sh-stub.c -- debugging stub for the Renesas-SH.
+
+ NOTE!! This code has to be compiled with optimization, otherwise the 
+ function inlining which generates the exception handlers won't work.
+
+*/
+
+/*   This is originally based on an m68k software stub written by Glenn
+     Engel at HP, but has changed quite a bit. 
+
+     Modifications for the SH by Ben Lee and Steve Chamberlain
+
+*/
+
+/****************************************************************************
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+
+/* Remote communication protocol.
+
+   A debug packet whose contents are <data>
+   is encapsulated for transmission in the form:
+
+       $ <data> # CSUM1 CSUM2
+
+       <data> must be ASCII alphanumeric and cannot include characters
+       '$' or '#'.  If <data> starts with two characters followed by
+       ':', then the existing stubs interpret this as a sequence number.
+
+       CSUM1 and CSUM2 are ascii hex representation of an 8-bit 
+       checksum of <data>, the most significant nibble is sent first.
+       the hex digits 0-9,a-f are used.
+
+   Receiver responds with:
+
+       +       - if CSUM is correct and ready for next packet
+       -       - if CSUM is incorrect
+
+   <data> is as follows:
+   All values are encoded in ascii hex digits.
+
+       Request         Packet
+
+       read registers  g
+       reply           XX....X         Each byte of register data
+                                       is described by two hex digits.
+                                       Registers are in the internal order
+                                       for GDB, and the bytes in a register
+                                       are in the same order the machine uses.
+                       or ENN          for an error.
+
+       write regs      GXX..XX         Each byte of register data
+                                       is described by two hex digits.
+       reply           OK              for success
+                       ENN             for an error
+
+        write reg      Pn...=r...      Write register n... with value r...,
+                                       which contains two hex digits for each
+                                       byte in the register (target byte
+                                       order).
+       reply           OK              for success
+                       ENN             for an error
+       (not supported by all stubs).
+
+       read mem        mAA..AA,LLLL    AA..AA is address, LLLL is length.
+       reply           XX..XX          XX..XX is mem contents
+                                       Can be fewer bytes than requested
+                                       if able to read only part of the data.
+                       or ENN          NN is errno
+
+       write mem       MAA..AA,LLLL:XX..XX
+                                       AA..AA is address,
+                                       LLLL is number of bytes,
+                                       XX..XX is data
+       reply           OK              for success
+                       ENN             for an error (this includes the case
+                                       where only part of the data was
+                                       written).
+
+       cont            cAA..AA         AA..AA is address to resume
+                                       If AA..AA is omitted,
+                                       resume at same address.
+
+       step            sAA..AA         AA..AA is address to resume
+                                       If AA..AA is omitted,
+                                       resume at same address.
+
+       last signal     ?               Reply the current reason for stopping.
+                                        This is the same reply as is generated
+                                       for step or cont : SAA where AA is the
+                                       signal number.
+
+       There is no immediate reply to step or cont.
+       The reply comes when the machine stops.
+       It is           SAA             AA is the "signal number"
+
+       or...           TAAn...:r...;n:r...;n...:r...;
+                                       AA = signal number
+                                       n... = register number
+                                       r... = register contents
+       or...           WAA             The process exited, and AA is
+                                       the exit status.  This is only
+                                       applicable for certains sorts of
+                                       targets.
+       kill request    k
+
+       toggle debug    d               toggle debug flag (see 386 & 68k stubs)
+       reset           r               reset -- see sparc stub.
+       reserved        <other>         On other requests, the stub should
+                                       ignore the request and send an empty
+                                       response ($#<checksum>).  This way
+                                       we can extend the protocol and GDB
+                                       can tell whether the stub it is
+                                       talking to uses the old or the new.
+       search          tAA:PP,MM       Search backwards starting at address
+                                       AA for a match with pattern PP and
+                                       mask MM.  PP and MM are 4 bytes.
+                                       Not supported by all stubs.
+
+       general query   qXXXX           Request info about XXXX.
+       general set     QXXXX=yyyy      Set value of XXXX to yyyy.
+       query sect offs qOffsets        Get section offsets.  Reply is
+                                       Text=xxx;Data=yyy;Bss=zzz
+       console output  Otext           Send text to stdout.  Only comes from
+                                       remote target.
+
+       Responses can be run-length encoded to save space.  A '*' means that
+       the next character is an ASCII encoding giving a repeat count which
+       stands for that many repititions of the character preceding the '*'.
+       The encoding is n+29, yielding a printable character where n >=3 
+       (which is where rle starts to win).  Don't use an n > 126. 
+
+       So 
+       "0* " means the same as "0000".  */
+
+#include <string.h>
+#include <setjmp.h>
+
+/* Renesas SH architecture instruction encoding masks */
+
+#define COND_BR_MASK   0xff00
+#define UCOND_DBR_MASK 0xe000
+#define UCOND_RBR_MASK 0xf0df
+#define TRAPA_MASK     0xff00
+
+#define COND_DISP      0x00ff
+#define UCOND_DISP     0x0fff
+#define UCOND_REG      0x0f00
+
+/* Renesas SH instruction opcodes */
+
+#define BF_INSTR       0x8b00
+#define BT_INSTR       0x8900
+#define BRA_INSTR      0xa000
+#define BSR_INSTR      0xb000
+#define JMP_INSTR      0x402b
+#define JSR_INSTR      0x400b
+#define RTS_INSTR      0x000b
+#define RTE_INSTR      0x002b
+#define TRAPA_INSTR    0xc300
+#define SSTEP_INSTR    0xc3ff
+
+/* Renesas SH processor register masks */
+
+#define T_BIT_MASK     0x0001
+
+/*
+ * BUFMAX defines the maximum number of characters in inbound/outbound
+ * buffers. At least NUMREGBYTES*2 are needed for register packets.
+ */
+#define BUFMAX 1024
+
+/*
+ * Number of bytes for registers
+ */
+#define NUMREGBYTES 112                /* 92 */
+
+/*
+ * typedef
+ */
+typedef void (*Function) ();
+
+/*
+ * Forward declarations
+ */
+
+static int hex (char);
+static char *mem2hex (char *, char *, int);
+static char *hex2mem (char *, char *, int);
+static int hexToInt (char **, int *);
+static unsigned char *getpacket (void);
+static void putpacket (char *);
+static void handle_buserror (void);
+static int computeSignal (int exceptionVector);
+static void handle_exception (int exceptionVector);
+void init_serial();
+
+void putDebugChar (char);
+char getDebugChar (void);
+
+/* These are in the file but in asm statements so the compiler can't see them */
+void catch_exception_4 (void);
+void catch_exception_6 (void);
+void catch_exception_9 (void);
+void catch_exception_10 (void);
+void catch_exception_11 (void);
+void catch_exception_32 (void);
+void catch_exception_33 (void);
+void catch_exception_255 (void);
+
+
+
+#define catch_exception_random catch_exception_255 /* Treat all odd ones like 255 */
+
+void breakpoint (void);
+
+
+#define init_stack_size 8*1024  /* if you change this you should also modify BINIT */
+#define stub_stack_size 8*1024
+
+int init_stack[init_stack_size] __attribute__ ((section ("stack"))) = {0};
+int stub_stack[stub_stack_size] __attribute__ ((section ("stack"))) = {0};
+
+
+void INIT ();
+void BINIT ();
+
+#define CPU_BUS_ERROR_VEC  9
+#define DMA_BUS_ERROR_VEC 10
+#define NMI_VEC           11
+#define INVALID_INSN_VEC   4
+#define INVALID_SLOT_VEC   6
+#define TRAP_VEC          32
+#define IO_VEC            33
+#define USER_VEC         255
+
+
+
+char in_nmi;   /* Set when handling an NMI, so we don't reenter */
+int dofault;  /* Non zero, bus errors will raise exception */
+
+int *stub_sp;
+
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+int remote_debug;
+
+/* jump buffer used for setjmp/longjmp */
+jmp_buf remcomEnv;
+
+enum regnames
+  {
+    R0, R1, R2, R3, R4, R5, R6, R7,
+    R8, R9, R10, R11, R12, R13, R14,
+    R15, PC, PR, GBR, VBR, MACH, MACL, SR,
+    TICKS, STALLS, CYCLES, INSTS, PLR
+  };
+
+typedef struct
+  {
+    short *memAddr;
+    short oldInstr;
+  }
+stepData;
+
+int registers[NUMREGBYTES / 4];
+stepData instrBuffer;
+char stepped;
+static const char hexchars[] = "0123456789abcdef";
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+char highhex(int  x)
+{
+  return hexchars[(x >> 4) & 0xf];
+}
+
+char lowhex(int  x)
+{
+  return hexchars[x & 0xf];
+}
+
+/*
+ * Assembly macros
+ */
+
+#define BREAKPOINT()   asm("trapa      #0x20"::);
+
+
+/*
+ * Routines to handle hex data
+ */
+
+static int
+hex (char ch)
+{
+  if ((ch >= 'a') && (ch <= 'f'))
+    return (ch - 'a' + 10);
+  if ((ch >= '0') && (ch <= '9'))
+    return (ch - '0');
+  if ((ch >= 'A') && (ch <= 'F'))
+    return (ch - 'A' + 10);
+  return (-1);
+}
+
+/* convert the memory, pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+static char *
+mem2hex (char *mem, char *buf, int count)
+{
+  int i;
+  int ch;
+  for (i = 0; i < count; i++)
+    {
+      ch = *mem++;
+      *buf++ = highhex (ch);
+      *buf++ = lowhex (ch);
+    }
+  *buf = 0;
+  return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary, to be placed in mem */
+/* return a pointer to the character after the last byte written */
+
+static char *
+hex2mem (char *buf, char *mem, int count)
+{
+  int i;
+  unsigned char ch;
+  for (i = 0; i < count; i++)
+    {
+      ch = hex (*buf++) << 4;
+      ch = ch + hex (*buf++);
+      *mem++ = ch;
+    }
+  return (mem);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED           */
+/**********************************************/
+static int
+hexToInt (char **ptr, int *intValue)
+{
+  int numChars = 0;
+  int hexValue;
+
+  *intValue = 0;
+
+  while (**ptr)
+    {
+      hexValue = hex (**ptr);
+      if (hexValue >= 0)
+       {
+         *intValue = (*intValue << 4) | hexValue;
+         numChars++;
+       }
+      else
+       break;
+
+      (*ptr)++;
+    }
+
+  return (numChars);
+}
+
+/*
+ * Routines to get and put packets
+ */
+
+/* scan for the sequence $<data>#<checksum>     */
+
+char *
+getpacket (void)
+{
+  unsigned char *buffer = &remcomInBuffer[0];
+  unsigned char checksum;
+  unsigned char xmitcsum;
+  int count;
+  char ch;
+
+  while (1)
+    {
+      /* wait around for the start character, ignore all other characters */
+      while ((ch = getDebugChar ()) != '$')
+       ;
+
+retry:
+      checksum = 0;
+      xmitcsum = -1;
+      count = 0;
+
+      /* now, read until a # or end of buffer is found */
+      while (count < BUFMAX - 1)
+       {
+         ch = getDebugChar ();
+          if (ch == '$')
+            goto retry;
+         if (ch == '#')
+           break;
+         checksum = checksum + ch;
+         buffer[count] = ch;
+         count = count + 1;
+       }
+      buffer[count] = 0;
+
+      if (ch == '#')
+       {
+         ch = getDebugChar ();
+         xmitcsum = hex (ch) << 4;
+         ch = getDebugChar ();
+         xmitcsum += hex (ch);
+
+         if (checksum != xmitcsum)
+           {
+             putDebugChar ('-');       /* failed checksum */
+           }
+         else
+           {
+             putDebugChar ('+');       /* successful transfer */
+
+             /* if a sequence char is present, reply the sequence ID */
+             if (buffer[2] == ':')
+               {
+                 putDebugChar (buffer[0]);
+                 putDebugChar (buffer[1]);
+
+                 return &buffer[3];
+               }
+
+             return &buffer[0];
+           }
+       }
+    }
+}
+
+
+/* send the packet in buffer. */
+
+static void
+putpacket (char *buffer)
+{
+  int checksum;
+  int count;
+
+  /*  $<packet info>#<checksum>. */
+  do
+    {
+      char *src = buffer;
+      putDebugChar ('$');
+      checksum = 0;
+
+      while (*src)
+       {
+         int runlen;
+
+         /* Do run length encoding */
+         for (runlen = 0; runlen < 100; runlen ++) 
+           {
+             if (src[0] != src[runlen]) 
+               {
+                 if (runlen > 3) 
+                   {
+                     int encode;
+                     /* Got a useful amount */
+                     putDebugChar (*src);
+                     checksum += *src;
+                     putDebugChar ('*');
+                     checksum += '*';
+                     checksum += (encode = runlen + ' ' - 4);
+                     putDebugChar (encode);
+                     src += runlen;
+                   }
+                 else
+                   {
+                     putDebugChar (*src);
+                     checksum += *src;
+                     src++;
+                   }
+                 break;
+               }
+           }
+       }
+
+
+      putDebugChar ('#');
+      putDebugChar (highhex(checksum));
+      putDebugChar (lowhex(checksum));
+    }
+  while  (getDebugChar() != '+');
+}
+
+
+/* a bus error has occurred, perform a longjmp
+   to return execution and allow handling of the error */
+
+void
+handle_buserror (void)
+{
+  longjmp (remcomEnv, 1);
+}
+
+/*
+ * this function takes the SH-1 exception number and attempts to
+ * translate this number into a unix compatible signal value
+ */
+static int
+computeSignal (int exceptionVector)
+{
+  int sigval;
+  switch (exceptionVector)
+    {
+    case INVALID_INSN_VEC:
+      sigval = 4;
+      break;                   
+    case INVALID_SLOT_VEC:
+      sigval = 4;
+      break;                   
+    case CPU_BUS_ERROR_VEC:
+      sigval = 10;
+      break;                   
+    case DMA_BUS_ERROR_VEC:
+      sigval = 10;
+      break;   
+    case NMI_VEC:
+      sigval = 2;
+      break;   
+
+    case TRAP_VEC:
+    case USER_VEC:
+      sigval = 5;
+      break;
+
+    default:
+      sigval = 7;              /* "software generated"*/
+      break;
+    }
+  return (sigval);
+}
+
+void
+doSStep (void)
+{
+  short *instrMem;
+  int displacement;
+  int reg;
+  unsigned short opcode;
+
+  instrMem = (short *) registers[PC];
+
+  opcode = *instrMem;
+  stepped = 1;
+
+  if ((opcode & COND_BR_MASK) == BT_INSTR)
+    {
+      if (registers[SR] & T_BIT_MASK)
+       {
+         displacement = (opcode & COND_DISP) << 1;
+         if (displacement & 0x80)
+           displacement |= 0xffffff00;
+         /*
+                  * Remember PC points to second instr.
+                  * after PC of branch ... so add 4
+                  */
+         instrMem = (short *) (registers[PC] + displacement + 4);
+       }
+      else
+       instrMem += 1;
+    }
+  else if ((opcode & COND_BR_MASK) == BF_INSTR)
+    {
+      if (registers[SR] & T_BIT_MASK)
+       instrMem += 1;
+      else
+       {
+         displacement = (opcode & COND_DISP) << 1;
+         if (displacement & 0x80)
+           displacement |= 0xffffff00;
+         /*
+                  * Remember PC points to second instr.
+                  * after PC of branch ... so add 4
+                  */
+         instrMem = (short *) (registers[PC] + displacement + 4);
+       }
+    }
+  else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
+    {
+      displacement = (opcode & UCOND_DISP) << 1;
+      if (displacement & 0x0800)
+       displacement |= 0xfffff000;
+
+      /*
+          * Remember PC points to second instr.
+          * after PC of branch ... so add 4
+          */
+      instrMem = (short *) (registers[PC] + displacement + 4);
+    }
+  else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
+    {
+      reg = (char) ((opcode & UCOND_REG) >> 8);
+
+      instrMem = (short *) registers[reg];
+    }
+  else if (opcode == RTS_INSTR)
+    instrMem = (short *) registers[PR];
+  else if (opcode == RTE_INSTR)
+    instrMem = (short *) registers[15];
+  else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
+    instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
+  else
+    instrMem += 1;
+
+  instrBuffer.memAddr = instrMem;
+  instrBuffer.oldInstr = *instrMem;
+  *instrMem = SSTEP_INSTR;
+}
+
+
+/* Undo the effect of a previous doSStep.  If we single stepped,
+   restore the old instruction. */
+
+void
+undoSStep (void)
+{
+  if (stepped)
+    {  short *instrMem;
+      instrMem = instrBuffer.memAddr;
+      *instrMem = instrBuffer.oldInstr;
+    }
+  stepped = 0;
+}
+
+/*
+This function does all exception handling.  It only does two things -
+it figures out why it was called and tells gdb, and then it reacts
+to gdb's requests.
+
+When in the monitor mode we talk a human on the serial line rather than gdb.
+
+*/
+
+
+void
+gdb_handle_exception (int exceptionVector)
+{
+  int sigval, stepping;
+  int addr, length;
+  char *ptr;
+
+  /* reply to host that an exception has occurred */
+  sigval = computeSignal (exceptionVector);
+  remcomOutBuffer[0] = 'S';
+  remcomOutBuffer[1] = highhex(sigval);
+  remcomOutBuffer[2] = lowhex (sigval);
+  remcomOutBuffer[3] = 0;
+
+  putpacket (remcomOutBuffer);
+
+  /*
+   * exception 255 indicates a software trap
+   * inserted in place of code ... so back up
+   * PC by one instruction, since this instruction
+   * will later be replaced by its original one!
+   */
+  if (exceptionVector == 0xff
+      || exceptionVector == 0x20)
+    registers[PC] -= 2;
+
+  /*
+   * Do the thangs needed to undo
+   * any stepping we may have done!
+   */
+  undoSStep ();
+
+  stepping = 0;
+
+  while (1)
+    {
+      remcomOutBuffer[0] = 0;
+      ptr = getpacket ();
+
+      switch (*ptr++)
+       {
+       case '?':
+         remcomOutBuffer[0] = 'S';
+         remcomOutBuffer[1] = highhex (sigval);
+         remcomOutBuffer[2] = lowhex (sigval);
+         remcomOutBuffer[3] = 0;
+         break;
+       case 'd':
+         remote_debug = !(remote_debug);       /* toggle debug flag */
+         break;
+       case 'g':               /* return the value of the CPU registers */
+         mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
+         break;
+       case 'G':               /* set the value of the CPU registers - return OK */
+         hex2mem (ptr, (char *) registers, NUMREGBYTES);
+         strcpy (remcomOutBuffer, "OK");
+         break;
+
+         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+       case 'm':
+         if (setjmp (remcomEnv) == 0)
+           {
+             dofault = 0;
+             /* TRY, TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
+             if (hexToInt (&ptr, &addr))
+               if (*(ptr++) == ',')
+                 if (hexToInt (&ptr, &length))
+                   {
+                     ptr = 0;
+                     mem2hex ((char *) addr, remcomOutBuffer, length);
+                   }
+             if (ptr)
+               strcpy (remcomOutBuffer, "E01");
+           }
+         else
+           strcpy (remcomOutBuffer, "E03");
+
+         /* restore handler for bus error */
+         dofault = 1;
+         break;
+
+         /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+       case 'M':
+         if (setjmp (remcomEnv) == 0)
+           {
+             dofault = 0;
+
+             /* TRY, TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
+             if (hexToInt (&ptr, &addr))
+               if (*(ptr++) == ',')
+                 if (hexToInt (&ptr, &length))
+                   if (*(ptr++) == ':')
+                     {
+                       hex2mem (ptr, (char *) addr, length);
+                       ptr = 0;
+                       strcpy (remcomOutBuffer, "OK");
+                     }
+             if (ptr)
+               strcpy (remcomOutBuffer, "E02");
+           }
+         else
+           strcpy (remcomOutBuffer, "E03");
+
+         /* restore handler for bus error */
+         dofault = 1;
+         break;
+
+         /* cAA..AA    Continue at address AA..AA(optional) */
+         /* sAA..AA   Step one instruction from AA..AA(optional) */
+       case 's':
+         stepping = 1;
+       case 'c':
+         {
+           /* tRY, to read optional parameter, pc unchanged if no parm */
+           if (hexToInt (&ptr, &addr))
+             registers[PC] = addr;
+
+           if (stepping)
+             doSStep ();
+         }
+         return;
+         break;
+
+         /* kill the program */
+       case 'k':               /* do nothing */
+         break;
+       }                       /* switch */
+
+      /* reply to the request */
+      putpacket (remcomOutBuffer);
+    }
+}
+
+
+#define GDBCOOKIE 0x5ac 
+static int ingdbmode;
+/* We've had an exception - choose to go into the monitor or
+   the gdb stub */
+void handle_exception(int exceptionVector)
+{
+#ifdef MONITOR
+    if (ingdbmode != GDBCOOKIE)
+      monitor_handle_exception (exceptionVector);
+    else 
+#endif
+      gdb_handle_exception (exceptionVector);
+
+}
+
+void
+gdb_mode (void)
+{
+  ingdbmode = GDBCOOKIE;
+  breakpoint();
+}
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger. */
+
+void
+breakpoint (void)
+{
+      BREAKPOINT ();
+}
+
+/**** Processor-specific routines start here ****/
+/**** Processor-specific routines start here ****/
+/**** Processor-specific routines start here ****/
+
+/* Note:
+
+   The Renesas SH family uses two exception architectures:
+
+   SH1 & SH2:
+
+       These processors utilize an exception vector table.
+       Exceptions are vectored to the address stored at VBR + (exception_num * 4)
+
+  SH3, SH3E, & SH4:
+
+       These processors have fixed entry points relative to the VBR for
+       various exception classes.
+*/
+
+#if defined(__sh1__) || defined(__sh2__)
+
+/* SH1/SH2 exception vector table format */
+
+typedef struct
+  {
+    void (*func_cold) ();
+    int *stack_cold;
+    void (*func_warm) ();
+    int *stack_warm;
+    void (*(handler[256 - 4])) ();
+  }
+vec_type;
+
+/* vectable is the SH1/SH2 vector table. It must be at address 0
+   or wherever your vbr points. */
+
+const vec_type vectable =
+{ 
+  &BINIT,                      /* 0: Power-on reset PC */
+  init_stack + init_stack_size, /* 1: Power-on reset SP */
+  &BINIT,                      /* 2: Manual reset PC */
+  init_stack + init_stack_size, /* 3: Manual reset SP */
+{
+  &catch_exception_4,          /* 4: General invalid instruction */
+  &catch_exception_random,     /* 5: Reserved for system */
+  &catch_exception_6,          /* 6: Invalid slot instruction */
+  &catch_exception_random,     /* 7: Reserved for system */
+  &catch_exception_random,     /* 8: Reserved for system */
+  &catch_exception_9,          /* 9: CPU bus error */
+  &catch_exception_10,         /* 10: DMA bus error */
+  &catch_exception_11,         /* 11: NMI */
+  &catch_exception_random,     /* 12: User break */
+  &catch_exception_random,     /* 13: Reserved for system */
+  &catch_exception_random,     /* 14: Reserved for system */
+  &catch_exception_random,     /* 15: Reserved for system */
+  &catch_exception_random,     /* 16: Reserved for system */
+  &catch_exception_random,     /* 17: Reserved for system */
+  &catch_exception_random,     /* 18: Reserved for system */
+  &catch_exception_random,     /* 19: Reserved for system */
+  &catch_exception_random,     /* 20: Reserved for system */
+  &catch_exception_random,     /* 21: Reserved for system */
+  &catch_exception_random,     /* 22: Reserved for system */
+  &catch_exception_random,     /* 23: Reserved for system */
+  &catch_exception_random,     /* 24: Reserved for system */
+  &catch_exception_random,     /* 25: Reserved for system */
+  &catch_exception_random,     /* 26: Reserved for system */
+  &catch_exception_random,     /* 27: Reserved for system */
+  &catch_exception_random,     /* 28: Reserved for system */
+  &catch_exception_random,     /* 29: Reserved for system */
+  &catch_exception_random,     /* 30: Reserved for system */
+  &catch_exception_random,     /* 31: Reserved for system */
+  &catch_exception_32,         /* 32: Trap instr (user vectors) */
+  &catch_exception_33,         /* 33: Trap instr (user vectors) */
+  &catch_exception_random,     /* 34: Trap instr (user vectors) */
+  &catch_exception_random,     /* 35: Trap instr (user vectors) */
+  &catch_exception_random,     /* 36: Trap instr (user vectors) */
+  &catch_exception_random,     /* 37: Trap instr (user vectors) */
+  &catch_exception_random,     /* 38: Trap instr (user vectors) */
+  &catch_exception_random,     /* 39: Trap instr (user vectors) */
+  &catch_exception_random,     /* 40: Trap instr (user vectors) */
+  &catch_exception_random,     /* 41: Trap instr (user vectors) */
+  &catch_exception_random,     /* 42: Trap instr (user vectors) */
+  &catch_exception_random,     /* 43: Trap instr (user vectors) */
+  &catch_exception_random,     /* 44: Trap instr (user vectors) */
+  &catch_exception_random,     /* 45: Trap instr (user vectors) */
+  &catch_exception_random,     /* 46: Trap instr (user vectors) */
+  &catch_exception_random,     /* 47: Trap instr (user vectors) */
+  &catch_exception_random,     /* 48: Trap instr (user vectors) */
+  &catch_exception_random,     /* 49: Trap instr (user vectors) */
+  &catch_exception_random,     /* 50: Trap instr (user vectors) */
+  &catch_exception_random,     /* 51: Trap instr (user vectors) */
+  &catch_exception_random,     /* 52: Trap instr (user vectors) */
+  &catch_exception_random,     /* 53: Trap instr (user vectors) */
+  &catch_exception_random,     /* 54: Trap instr (user vectors) */
+  &catch_exception_random,     /* 55: Trap instr (user vectors) */
+  &catch_exception_random,     /* 56: Trap instr (user vectors) */
+  &catch_exception_random,     /* 57: Trap instr (user vectors) */
+  &catch_exception_random,     /* 58: Trap instr (user vectors) */
+  &catch_exception_random,     /* 59: Trap instr (user vectors) */
+  &catch_exception_random,     /* 60: Trap instr (user vectors) */
+  &catch_exception_random,     /* 61: Trap instr (user vectors) */
+  &catch_exception_random,     /* 62: Trap instr (user vectors) */
+  &catch_exception_random,     /* 63: Trap instr (user vectors) */
+  &catch_exception_random,     /* 64: IRQ0 */
+  &catch_exception_random,     /* 65: IRQ1 */
+  &catch_exception_random,     /* 66: IRQ2 */
+  &catch_exception_random,     /* 67: IRQ3 */
+  &catch_exception_random,     /* 68: IRQ4 */
+  &catch_exception_random,     /* 69: IRQ5 */
+  &catch_exception_random,     /* 70: IRQ6 */
+  &catch_exception_random,     /* 71: IRQ7 */
+  &catch_exception_random,
+  &catch_exception_random,
+  &catch_exception_random,
+  &catch_exception_random,
+  &catch_exception_random,
+  &catch_exception_random,
+  &catch_exception_random,
+  &catch_exception_random,
+  &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_random,
+     &catch_exception_255}};
+
+#define BCR  (*(volatile short *)(0x05FFFFA0)) /* Bus control register */
+#define BAS  (0x800)                           /* Byte access select */
+#define WCR1 (*(volatile short *)(0x05ffffA2)) /* Wait state control register */
+
+asm ("_BINIT: mov.l  L1,r15");
+asm ("bra _INIT");
+asm ("nop");
+asm ("L1: .long _init_stack + 8*1024*4");
+void
+INIT (void)
+{
+  /* First turn on the ram */
+  WCR1  = 0;    /* Never sample wait */
+  BCR = BAS;    /* use lowbyte/high byte */
+
+  init_serial();
+
+#ifdef MONITOR
+  reset_hook ();
+#endif
+
+
+  in_nmi = 0;
+  dofault = 1;
+  stepped = 0;
+
+  stub_sp = stub_stack + stub_stack_size;
+  breakpoint ();
+
+  while (1)
+    ;
+}
+
+
+static void sr()
+{
+
+
+  /* Calling Reset does the same as pressing the button */
+  asm (".global _Reset
+        .global _WarmReset
+_Reset:
+_WarmReset:
+         mov.l L_sp,r15
+         bra   _INIT
+         nop
+         .align 2
+L_sp:    .long _init_stack + 8000");
+
+  asm("saveRegisters:
+       mov.l   @(L_reg, pc), r0
+       mov.l   @r15+, r1                               ! pop R0
+       mov.l   r2, @(0x08, r0)                         ! save R2
+       mov.l   r1, @r0                                 ! save R0
+       mov.l   @r15+, r1                               ! pop R1
+       mov.l   r3, @(0x0c, r0)                         ! save R3
+       mov.l   r1, @(0x04, r0)                         ! save R1
+       mov.l   r4, @(0x10, r0)                         ! save R4
+       mov.l   r5, @(0x14, r0)                         ! save R5
+       mov.l   r6, @(0x18, r0)                         ! save R6
+       mov.l   r7, @(0x1c, r0)                         ! save R7
+       mov.l   r8, @(0x20, r0)                         ! save R8
+       mov.l   r9, @(0x24, r0)                         ! save R9
+       mov.l   r10, @(0x28, r0)                        ! save R10
+       mov.l   r11, @(0x2c, r0)                        ! save R11
+       mov.l   r12, @(0x30, r0)                        ! save R12
+       mov.l   r13, @(0x34, r0)                        ! save R13
+       mov.l   r14, @(0x38, r0)                        ! save R14
+       mov.l   @r15+, r4                               ! save arg to handleException
+       add     #8, r15                                 ! hide PC/SR values on stack
+       mov.l   r15, @(0x3c, r0)                        ! save R15
+       add     #-8, r15                                ! save still needs old SP value
+       add     #92, r0                                 ! readjust register pointer
+       mov     r15, r2
+       add     #4, r2
+       mov.l   @r2, r2                                 ! R2 has SR
+       mov.l   @r15, r1                                ! R1 has PC
+       mov.l   r2, @-r0                                ! save SR
+       sts.l   macl, @-r0                              ! save MACL
+       sts.l   mach, @-r0                              ! save MACH
+       stc.l   vbr, @-r0                               ! save VBR
+       stc.l   gbr, @-r0                               ! save GBR
+       sts.l   pr, @-r0                                ! save PR
+       mov.l   @(L_stubstack, pc), r2
+       mov.l   @(L_hdl_except, pc), r3
+       mov.l   @r2, r15
+       jsr     @r3
+       mov.l   r1, @-r0                                ! save PC
+       mov.l   @(L_stubstack, pc), r0
+       mov.l   @(L_reg, pc), r1
+       bra     restoreRegisters
+       mov.l   r15, @r0                                ! save __stub_stack
+       
+       .align 2
+L_reg:
+       .long   _registers
+L_stubstack:
+       .long   _stub_sp
+L_hdl_except:
+       .long   _handle_exception");
+
+}
+
+static void rr()
+{
+asm("
+       .align 2        
+        .global _resume
+_resume:
+       mov     r4,r1
+restoreRegisters:
+       add     #8, r1                                          ! skip to R2
+       mov.l   @r1+, r2                                        ! restore R2
+       mov.l   @r1+, r3                                        ! restore R3
+       mov.l   @r1+, r4                                        ! restore R4
+       mov.l   @r1+, r5                                        ! restore R5
+       mov.l   @r1+, r6                                        ! restore R6
+       mov.l   @r1+, r7                                        ! restore R7
+       mov.l   @r1+, r8                                        ! restore R8
+       mov.l   @r1+, r9                                        ! restore R9
+       mov.l   @r1+, r10                                       ! restore R10
+       mov.l   @r1+, r11                                       ! restore R11
+       mov.l   @r1+, r12                                       ! restore R12
+       mov.l   @r1+, r13                                       ! restore R13
+       mov.l   @r1+, r14                                       ! restore R14
+       mov.l   @r1+, r15                                       ! restore programs stack
+       mov.l   @r1+, r0
+       add     #-8, r15                                        ! uncover PC/SR on stack 
+       mov.l   r0, @r15                                        ! restore PC onto stack
+       lds.l   @r1+, pr                                        ! restore PR
+       ldc.l   @r1+, gbr                                       ! restore GBR           
+       ldc.l   @r1+, vbr                                       ! restore VBR
+       lds.l   @r1+, mach                                      ! restore MACH
+       lds.l   @r1+, macl                                      ! restore MACL
+       mov.l   @r1, r0 
+       add     #-88, r1                                        ! readjust reg pointer to R1
+       mov.l   r0, @(4, r15)                                   ! restore SR onto stack+4
+       mov.l   r2, @-r15
+       mov.l   L_in_nmi, r0
+       mov             #0, r2
+       mov.b   r2, @r0
+       mov.l   @r15+, r2
+       mov.l   @r1+, r0                                        ! restore R0
+       rte
+       mov.l   @r1, r1                                         ! restore R1
+
+");
+}
+
+
+static __inline__ void code_for_catch_exception(int n) 
+{
+  asm("                .globl  _catch_exception_%O0" : : "i" (n)                               ); 
+  asm("        _catch_exception_%O0:" :: "i" (n)                                               );
+
+  asm("                add     #-4, r15                                ! reserve spot on stack ");
+  asm("                mov.l   r1, @-r15                               ! push R1               ");
+
+  if (n == NMI_VEC) 
+    {
+      /* Special case for NMI - make sure that they don't nest */
+      asm("    mov.l   r0, @-r15                                       ! push R0");
+      asm("    mov.l   L_in_nmi, r0");
+      asm("    tas.b   @r0                                             ! Fend off against addtnl NMIs");
+      asm("    bt              noNMI");
+      asm("    mov.l   @r15+, r0");
+      asm("    mov.l   @r15+, r1");
+      asm("    add             #4, r15");
+      asm("    rte");
+      asm("    nop");
+      asm(".align 2");
+      asm("L_in_nmi: .long     _in_nmi");
+      asm("noNMI:");
+    }
+  else
+    {
+
+      if (n == CPU_BUS_ERROR_VEC)
+       {
+         /* Exception 9 (bus errors) are disasbleable - so that you
+            can probe memory and get zero instead of a fault.
+            Because the vector table may be in ROM we don't revector
+            the interrupt like all the other stubs, we check in here
+            */
+         asm("mov.l    L_dofault,r1");
+         asm("mov.l    @r1,r1");
+         asm("tst      r1,r1");
+         asm("bf       faultaway");
+         asm("bsr      _handle_buserror");
+         asm(".align   2");
+         asm("L_dofault: .long _dofault");
+         asm("faultaway:");
+       }
+      asm("            mov     #15<<4, r1                                                      ");
+      asm("            ldc     r1, sr                                  ! disable interrupts    ");
+      asm("            mov.l   r0, @-r15                               ! push R0               ");
+    }
+
+  /* Prepare for saving context, we've already pushed r0 and r1, stick exception number
+     into the frame */
+  asm("                mov     r15, r0                                                         ");
+  asm("                add     #8, r0                                                          ");
+  asm("                mov     %0,r1" :: "i" (n)                                               );
+  asm("                extu.b  r1,r1                                                           ");
+  asm("                bra     saveRegisters                           ! save register values  ");
+  asm("                mov.l   r1, @r0                                 ! save exception #      ");
+}
+
+
+static  void
+exceptions (void)
+{
+  code_for_catch_exception (CPU_BUS_ERROR_VEC);
+  code_for_catch_exception (DMA_BUS_ERROR_VEC);
+  code_for_catch_exception (INVALID_INSN_VEC);
+  code_for_catch_exception (INVALID_SLOT_VEC);
+  code_for_catch_exception (NMI_VEC);
+  code_for_catch_exception (TRAP_VEC);
+  code_for_catch_exception (USER_VEC);
+  code_for_catch_exception (IO_VEC);
+}
+
+
+
+
+
+
+/* Support for Serial I/O using on chip uart */
+
+#define SMR0 (*(volatile char *)(0x05FFFEC0)) /* Channel 0  serial mode register */
+#define BRR0 (*(volatile char *)(0x05FFFEC1)) /* Channel 0  bit rate register */
+#define SCR0 (*(volatile char *)(0x05FFFEC2)) /* Channel 0  serial control register */
+#define TDR0 (*(volatile char *)(0x05FFFEC3)) /* Channel 0  transmit data register */
+#define SSR0 (*(volatile char *)(0x05FFFEC4)) /* Channel 0  serial status register */
+#define RDR0 (*(volatile char *)(0x05FFFEC5)) /* Channel 0  receive data register */
+
+#define SMR1 (*(volatile char *)(0x05FFFEC8)) /* Channel 1  serial mode register */
+#define BRR1 (*(volatile char *)(0x05FFFEC9)) /* Channel 1  bit rate register */
+#define SCR1 (*(volatile char *)(0x05FFFECA)) /* Channel 1  serial control register */
+#define TDR1 (*(volatile char *)(0x05FFFECB)) /* Channel 1  transmit data register */
+#define SSR1 (*(volatile char *)(0x05FFFECC)) /* Channel 1  serial status register */
+#define RDR1 (*(volatile char *)(0x05FFFECD)) /* Channel 1  receive data register */
+
+/*
+ * Serial mode register bits
+ */
+
+#define SYNC_MODE              0x80
+#define SEVEN_BIT_DATA                 0x40
+#define PARITY_ON              0x20
+#define ODD_PARITY             0x10
+#define STOP_BITS_2            0x08
+#define ENABLE_MULTIP          0x04
+#define PHI_64                 0x03
+#define PHI_16                 0x02
+#define PHI_4                  0x01
+
+/*
+ * Serial control register bits
+ */
+#define SCI_TIE                                0x80    /* Transmit interrupt enable */
+#define SCI_RIE                                0x40    /* Receive interrupt enable */
+#define SCI_TE                         0x20    /* Transmit enable */
+#define SCI_RE                         0x10    /* Receive enable */
+#define SCI_MPIE                       0x08    /* Multiprocessor interrupt enable */
+#define SCI_TEIE                       0x04    /* Transmit end interrupt enable */
+#define SCI_CKE1                       0x02    /* Clock enable 1 */
+#define SCI_CKE0                       0x01    /* Clock enable 0 */
+
+/*
+ * Serial status register bits
+ */
+#define SCI_TDRE                       0x80    /* Transmit data register empty */
+#define SCI_RDRF                       0x40    /* Receive data register full */
+#define SCI_ORER                       0x20    /* Overrun error */
+#define SCI_FER                                0x10    /* Framing error */
+#define SCI_PER                                0x08    /* Parity error */
+#define SCI_TEND                       0x04    /* Transmit end */
+#define SCI_MPB                                0x02    /* Multiprocessor bit */
+#define SCI_MPBT                       0x01    /* Multiprocessor bit transfer */
+
+
+/*
+ * Port B IO Register (PBIOR)
+ */
+#define        PBIOR           (*(volatile char *)(0x05FFFFC6))
+#define        PB15IOR         0x8000
+#define        PB14IOR         0x4000
+#define        PB13IOR         0x2000
+#define        PB12IOR         0x1000
+#define        PB11IOR         0x0800
+#define        PB10IOR         0x0400
+#define        PB9IOR          0x0200
+#define        PB8IOR          0x0100
+#define        PB7IOR          0x0080
+#define        PB6IOR          0x0040
+#define        PB5IOR          0x0020
+#define        PB4IOR          0x0010
+#define        PB3IOR          0x0008
+#define        PB2IOR          0x0004
+#define        PB1IOR          0x0002
+#define        PB0IOR          0x0001
+
+/*
+ * Port B Control Register (PBCR1)
+ */
+#define        PBCR1           (*(volatile short *)(0x05FFFFCC))
+#define        PB15MD1         0x8000
+#define        PB15MD0         0x4000
+#define        PB14MD1         0x2000
+#define        PB14MD0         0x1000
+#define        PB13MD1         0x0800
+#define        PB13MD0         0x0400
+#define        PB12MD1         0x0200
+#define        PB12MD0         0x0100
+#define        PB11MD1         0x0080
+#define        PB11MD0         0x0040
+#define        PB10MD1         0x0020
+#define        PB10MD0         0x0010
+#define        PB9MD1          0x0008
+#define        PB9MD0          0x0004
+#define        PB8MD1          0x0002
+#define        PB8MD0          0x0001
+
+#define        PB15MD          PB15MD1|PB14MD0
+#define        PB14MD          PB14MD1|PB14MD0
+#define        PB13MD          PB13MD1|PB13MD0
+#define        PB12MD          PB12MD1|PB12MD0
+#define        PB11MD          PB11MD1|PB11MD0
+#define        PB10MD          PB10MD1|PB10MD0
+#define        PB9MD           PB9MD1|PB9MD0
+#define        PB8MD           PB8MD1|PB8MD0
+
+#define PB_TXD1        PB11MD1
+#define PB_RXD1        PB10MD1
+#define PB_TXD0        PB9MD1
+#define PB_RXD0        PB8MD1
+
+/*
+ * Port B Control Register (PBCR2)
+ */
+#define        PBCR2   0x05FFFFCE
+#define        PB7MD1  0x8000
+#define        PB7MD0  0x4000
+#define        PB6MD1  0x2000
+#define        PB6MD0  0x1000
+#define        PB5MD1  0x0800
+#define        PB5MD0  0x0400
+#define        PB4MD1  0x0200
+#define        PB4MD0  0x0100
+#define        PB3MD1  0x0080
+#define        PB3MD0  0x0040
+#define        PB2MD1  0x0020
+#define        PB2MD0  0x0010
+#define        PB1MD1  0x0008
+#define        PB1MD0  0x0004
+#define        PB0MD1  0x0002
+#define        PB0MD0  0x0001
+       
+#define        PB7MD   PB7MD1|PB7MD0
+#define        PB6MD   PB6MD1|PB6MD0
+#define        PB5MD   PB5MD1|PB5MD0
+#define        PB4MD   PB4MD1|PB4MD0
+#define        PB3MD   PB3MD1|PB3MD0
+#define        PB2MD   PB2MD1|PB2MD0
+#define        PB1MD   PB1MD1|PB1MD0
+#define        PB0MD   PB0MD1|PB0MD0
+
+
+#ifdef MHZ
+#define BPS                    32 * 9600 * MHZ / ( BAUD * 10)
+#else
+#define BPS                    32      /* 9600 for 10 Mhz */
+#endif
+
+void handleError (char theSSR);
+
+void
+nop (void)
+{
+
+}
+void 
+init_serial (void)
+{
+  int i;
+
+  /* Clear TE and RE in Channel 1's SCR   */
+  SCR1 &= ~(SCI_TE | SCI_RE);
+
+  /* Set communication to be async, 8-bit data, no parity, 1 stop bit and use internal clock */
+
+  SMR1 = 0;
+  BRR1 = BPS;
+
+  SCR1 &= ~(SCI_CKE1 | SCI_CKE0);
+
+  /* let the hardware settle */
+
+  for (i = 0; i < 1000; i++)
+    nop ();
+
+  /* Turn on in and out */
+  SCR1 |= SCI_RE | SCI_TE;
+
+  /* Set the PFC to make RXD1 (pin PB8) an input pin and TXD1 (pin PB9) an output pin */
+  PBCR1 &= ~(PB_TXD1 | PB_RXD1);
+  PBCR1 |= PB_TXD1 | PB_RXD1;
+}
+
+
+int
+getDebugCharReady (void)
+{
+  char mySSR;
+  mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
+  if ( mySSR )
+    handleError ( mySSR );
+  return SSR1 & SCI_RDRF ;
+}
+
+char 
+getDebugChar (void)
+{
+  char ch;
+  char mySSR;
+
+  while ( ! getDebugCharReady())
+    ;
+
+  ch = RDR1;
+  SSR1 &= ~SCI_RDRF;
+
+  mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
+
+  if (mySSR)
+    handleError (mySSR);
+
+  return ch;
+}
+
+int 
+putDebugCharReady (void)
+{
+  return (SSR1 & SCI_TDRE);
+}
+
+void
+putDebugChar (char ch)
+{
+  while (!putDebugCharReady())
+    ;
+
+  /*
+   * Write data into TDR and clear TDRE
+   */
+  TDR1 = ch;
+  SSR1 &= ~SCI_TDRE;
+}
+
+void 
+handleError (char theSSR)
+{
+  SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
+}
+
+#endif
diff --git a/gdb/stubs/sparc-stub.c b/gdb/stubs/sparc-stub.c
new file mode 100644 (file)
index 0000000..c12d436
--- /dev/null
@@ -0,0 +1,778 @@
+/****************************************************************************
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ *  Module name: remcom.c $
+ *  Revision: 1.34 $
+ *  Date: 91/03/09 12:29:49 $
+ *  Contributor:     Lake Stevens Instrument Division$
+ *
+ *  Description:     low level support for gdb debugger. $
+ *
+ *  Considerations:  only works on target hardware $
+ *
+ *  Written by:      Glenn Engel $
+ *  ModuleState:     Experimental $
+ *
+ *  NOTES:           See Below $
+ *
+ *  Modified for SPARC by Stu Grossman, Cygnus Support.
+ *
+ *  This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <signal.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern void putDebugChar();    /* write a single character      */
+extern int getDebugChar();     /* read and return a single char */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 2048
+
+static int initialized = 0;    /* !0 means we've been initialized */
+
+static void set_mem_fault_trap();
+
+static const char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 72
+
+/* Number of bytes of registers.  */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
+                O0, O1, O2, O3, O4, O5, SP, O7,
+                L0, L1, L2, L3, L4, L5, L6, L7,
+                I0, I1, I2, I3, I4, I5, FP, I7,
+
+                F0, F1, F2, F3, F4, F5, F6, F7,
+                F8, F9, F10, F11, F12, F13, F14, F15,
+                F16, F17, F18, F19, F20, F21, F22, F23,
+                F24, F25, F26, F27, F28, F29, F30, F31,
+                Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
+
+/***************************  ASSEMBLY CODE MACROS *************************/
+/*                                                                        */
+
+extern void trap_low();
+
+asm("
+       .reserve trapstack, 1000 * 4, \"bss\", 8
+
+       .data
+       .align  4
+
+in_trap_handler:
+       .word   0
+
+       .text
+       .align 4
+
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs.  It makes sure that the invalid register window is still
+! available before jumping into C code.  It will also restore the world if you
+! return from handle_exception.
+
+       .globl _trap_low
+_trap_low:
+       mov     %psr, %l0
+       mov     %wim, %l3
+
+       srl     %l3, %l0, %l4           ! wim >> cwp
+       cmp     %l4, 1
+       bne     window_fine             ! Branch if not in the invalid window
+       nop
+
+! Handle window overflow
+
+       mov     %g1, %l4                ! Save g1, we use it to hold the wim
+       srl     %l3, 1, %g1             ! Rotate wim right
+       tst     %g1
+       bg      good_wim                ! Branch if new wim is non-zero
+       nop
+
+! At this point, we need to bring a 1 into the high order bit of the wim.
+! Since we don't want to make any assumptions about the number of register
+! windows, we figure it out dynamically so as to setup the wim correctly.
+
+       not     %g1                     ! Fill g1 with ones
+       mov     %g1, %wim               ! Fill the wim with ones
+       nop
+       nop
+       nop
+       mov     %wim, %g1               ! Read back the wim
+       inc     %g1                     ! Now g1 has 1 just to left of wim
+       srl     %g1, 1, %g1             ! Now put 1 at top of wim
+       mov     %g0, %wim               ! Clear wim so that subsequent save
+       nop                             !  won't trap
+       nop
+       nop
+
+good_wim:
+       save    %g0, %g0, %g0           ! Slip into next window
+       mov     %g1, %wim               ! Install the new wim
+
+       std     %l0, [%sp + 0 * 4]      ! save L & I registers
+       std     %l2, [%sp + 2 * 4]
+       std     %l4, [%sp + 4 * 4]
+       std     %l6, [%sp + 6 * 4]
+
+       std     %i0, [%sp + 8 * 4]
+       std     %i2, [%sp + 10 * 4]
+       std     %i4, [%sp + 12 * 4]
+       std     %i6, [%sp + 14 * 4]
+
+       restore                         ! Go back to trap window.
+       mov     %l4, %g1                ! Restore %g1
+
+window_fine:
+       sethi   %hi(in_trap_handler), %l4
+       ld      [%lo(in_trap_handler) + %l4], %l5
+       tst     %l5
+       bg      recursive_trap
+       inc     %l5
+
+       set     trapstack+1000*4, %sp   ! Switch to trap stack
+
+recursive_trap:
+       st      %l5, [%lo(in_trap_handler) + %l4]
+       sub     %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
+                                       ! + hidden arg + arg spill
+                                       ! + doubleword alignment
+                                       ! + registers[72] local var
+
+       std     %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+       std     %g2, [%sp + (24 + 2) * 4]
+       std     %g4, [%sp + (24 + 4) * 4]
+       std     %g6, [%sp + (24 + 6) * 4]
+
+       std     %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+       std     %i2, [%sp + (24 + 10) * 4]
+       std     %i4, [%sp + (24 + 12) * 4]
+       std     %i6, [%sp + (24 + 14) * 4]
+                                       ! F0->F31 not implemented
+       mov     %y, %l4
+       mov     %tbr, %l5
+       st      %l4, [%sp + (24 + 64) * 4] ! Y
+       st      %l0, [%sp + (24 + 65) * 4] ! PSR
+       st      %l3, [%sp + (24 + 66) * 4] ! WIM
+       st      %l5, [%sp + (24 + 67) * 4] ! TBR
+       st      %l1, [%sp + (24 + 68) * 4] ! PC
+       st      %l2, [%sp + (24 + 69) * 4] ! NPC
+
+                                       ! CPSR and FPSR not impl
+
+       or      %l0, 0xf20, %l4
+       mov     %l4, %psr               ! Turn on traps, disable interrupts
+
+       call    _handle_exception
+       add     %sp, 24 * 4, %o0        ! Pass address of registers
+
+! Reload all of the registers that aren't on the stack
+
+       ld      [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+       ldd     [%sp + (24 + 2) * 4], %g2
+       ldd     [%sp + (24 + 4) * 4], %g4
+       ldd     [%sp + (24 + 6) * 4], %g6
+
+       ldd     [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+       ldd     [%sp + (24 + 10) * 4], %i2
+       ldd     [%sp + (24 + 12) * 4], %i4
+       ldd     [%sp + (24 + 14) * 4], %i6
+
+       ldd     [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+       ldd     [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+       restore                         ! Ensure that previous window is valid
+       save    %g0, %g0, %g0           !  by causing a window_underflow trap
+
+       mov     %l0, %y
+       mov     %l1, %psr               ! Make sure that traps are disabled
+                                       ! for rett
+
+       sethi   %hi(in_trap_handler), %l4
+       ld      [%lo(in_trap_handler) + %l4], %l5
+       dec     %l5
+       st      %l5, [%lo(in_trap_handler) + %l4]
+
+       jmpl    %l2, %g0                ! Restore old PC
+       rett    %l3                     ! Restore old nPC
+");
+
+/* Convert ch from a hex digit to an int */
+
+static int
+hex (unsigned char ch)
+{
+  if (ch >= 'a' && ch <= 'f')
+    return ch-'a'+10;
+  if (ch >= '0' && ch <= '9')
+    return ch-'0';
+  if (ch >= 'A' && ch <= 'F')
+    return ch-'A'+10;
+  return -1;
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* scan for the sequence $<data>#<checksum>     */
+
+unsigned char *
+getpacket (void)
+{
+  unsigned char *buffer = &remcomInBuffer[0];
+  unsigned char checksum;
+  unsigned char xmitcsum;
+  int count;
+  char ch;
+
+  while (1)
+    {
+      /* wait around for the start character, ignore all other characters */
+      while ((ch = getDebugChar ()) != '$')
+       ;
+
+retry:
+      checksum = 0;
+      xmitcsum = -1;
+      count = 0;
+
+      /* now, read until a # or end of buffer is found */
+      while (count < BUFMAX - 1)
+       {
+         ch = getDebugChar ();
+          if (ch == '$')
+            goto retry;
+         if (ch == '#')
+           break;
+         checksum = checksum + ch;
+         buffer[count] = ch;
+         count = count + 1;
+       }
+      buffer[count] = 0;
+
+      if (ch == '#')
+       {
+         ch = getDebugChar ();
+         xmitcsum = hex (ch) << 4;
+         ch = getDebugChar ();
+         xmitcsum += hex (ch);
+
+         if (checksum != xmitcsum)
+           {
+             putDebugChar ('-');       /* failed checksum */
+           }
+         else
+           {
+             putDebugChar ('+');       /* successful transfer */
+
+             /* if a sequence char is present, reply the sequence ID */
+             if (buffer[2] == ':')
+               {
+                 putDebugChar (buffer[0]);
+                 putDebugChar (buffer[1]);
+
+                 return &buffer[3];
+               }
+
+             return &buffer[0];
+           }
+       }
+    }
+}
+
+/* send the packet in buffer.  */
+
+static void
+putpacket (unsigned char *buffer)
+{
+  unsigned char checksum;
+  int count;
+  unsigned char ch;
+
+  /*  $<packet info>#<checksum>. */
+  do
+    {
+      putDebugChar('$');
+      checksum = 0;
+      count = 0;
+
+      while (ch = buffer[count])
+       {
+         putDebugChar(ch);
+         checksum += ch;
+         count += 1;
+       }
+
+      putDebugChar('#');
+      putDebugChar(hexchars[checksum >> 4]);
+      putDebugChar(hexchars[checksum & 0xf]);
+
+    }
+  while (getDebugChar() != '+');
+}
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+   error.  */
+static volatile int mem_err = 0;
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0, else treat a fault like any other fault in the stub.
+ */
+
+static unsigned char *
+mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
+{
+  unsigned char ch;
+
+  set_mem_fault_trap(may_fault);
+
+  while (count-- > 0)
+    {
+      ch = *mem++;
+      if (mem_err)
+       return 0;
+      *buf++ = hexchars[ch >> 4];
+      *buf++ = hexchars[ch & 0xf];
+    }
+
+  *buf = 0;
+
+  set_mem_fault_trap(0);
+
+  return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written */
+
+static char *
+hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
+{
+  int i;
+  unsigned char ch;
+
+  set_mem_fault_trap(may_fault);
+
+  for (i=0; i<count; i++)
+    {
+      ch = hex(*buf++) << 4;
+      ch |= hex(*buf++);
+      *mem++ = ch;
+      if (mem_err)
+       return 0;
+    }
+
+  set_mem_fault_trap(0);
+
+  return mem;
+}
+
+/* This table contains the mapping between SPARC hardware trap types, and
+   signals, which are primarily what GDB understands.  It also indicates
+   which hardware traps we need to commandeer when initializing the stub. */
+
+static struct hard_trap_info
+{
+  unsigned char tt;            /* Trap type code for SPARClite */
+  unsigned char signo;         /* Signal that we map this trap into */
+} hard_trap_info[] = {
+  {1, SIGSEGV},                        /* instruction access error */
+  {2, SIGILL},                 /* privileged instruction */
+  {3, SIGILL},                 /* illegal instruction */
+  {4, SIGEMT},                 /* fp disabled */
+  {36, SIGEMT},                        /* cp disabled */
+  {7, SIGBUS},                 /* mem address not aligned */
+  {9, SIGSEGV},                        /* data access exception */
+  {10, SIGEMT},                        /* tag overflow */
+  {128+1, SIGTRAP},            /* ta 1 - normal breakpoint instruction */
+  {0, 0}                       /* Must be last */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps (void)
+{
+  struct hard_trap_info *ht;
+
+  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+    exceptionHandler(ht->tt, trap_low);
+
+  initialized = 1;
+}
+
+asm ("
+! Trap handler for memory errors.  This just sets mem_err to be non-zero.  It
+! assumes that %l1 is non-zero.  This should be safe, as it is doubtful that
+! 0 would ever contain code that could mem fault.  This routine will skip
+! past the faulting instruction after setting mem_err.
+
+       .text
+       .align 4
+
+_fltr_set_mem_err:
+       sethi %hi(_mem_err), %l0
+       st %l1, [%l0 + %lo(_mem_err)]
+       jmpl %l2, %g0
+       rett %l2+4
+");
+
+static void
+set_mem_fault_trap (int enable)
+{
+  extern void fltr_set_mem_err();
+  mem_err = 0;
+
+  if (enable)
+    exceptionHandler(9, fltr_set_mem_err);
+  else
+    exceptionHandler(9, trap_low);
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+
+static int
+computeSignal (int tt)
+{
+  struct hard_trap_info *ht;
+
+  for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+    if (ht->tt == tt)
+      return ht->signo;
+
+  return SIGHUP;               /* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+static int
+hexToInt(char **ptr, int *intValue)
+{
+  int numChars = 0;
+  int hexValue;
+
+  *intValue = 0;
+
+  while (**ptr)
+    {
+      hexValue = hex(**ptr);
+      if (hexValue < 0)
+       break;
+
+      *intValue = (*intValue << 4) | hexValue;
+      numChars ++;
+
+      (*ptr)++;
+    }
+
+  return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.  It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+
+extern void breakinst();
+
+static void
+handle_exception (unsigned long *registers)
+{
+  int tt;                      /* Trap type */
+  int sigval;
+  int addr;
+  int length;
+  char *ptr;
+  unsigned long *sp;
+
+/* First, we must force all of the windows to be spilled out */
+
+  asm("        save %sp, -64, %sp
+       save %sp, -64, %sp
+       save %sp, -64, %sp
+       save %sp, -64, %sp
+       save %sp, -64, %sp
+       save %sp, -64, %sp
+       save %sp, -64, %sp
+       save %sp, -64, %sp
+       restore
+       restore
+       restore
+       restore
+       restore
+       restore
+       restore
+       restore
+");
+
+  if (registers[PC] == (unsigned long)breakinst)
+    {
+      registers[PC] = registers[NPC];
+      registers[NPC] += 4;
+    }
+
+  sp = (unsigned long *)registers[SP];
+
+  tt = (registers[TBR] >> 4) & 0xff;
+
+  /* reply to host that an exception has occurred */
+  sigval = computeSignal(tt);
+  ptr = remcomOutBuffer;
+
+  *ptr++ = 'T';
+  *ptr++ = hexchars[sigval >> 4];
+  *ptr++ = hexchars[sigval & 0xf];
+
+  *ptr++ = hexchars[PC >> 4];
+  *ptr++ = hexchars[PC & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[FP >> 4];
+  *ptr++ = hexchars[FP & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[SP >> 4];
+  *ptr++ = hexchars[SP & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex((char *)&sp, ptr, 4, 0);
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[NPC >> 4];
+  *ptr++ = hexchars[NPC & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
+  *ptr++ = ';';
+
+  *ptr++ = hexchars[O7 >> 4];
+  *ptr++ = hexchars[O7 & 0xf];
+  *ptr++ = ':';
+  ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
+  *ptr++ = ';';
+
+  *ptr++ = 0;
+
+  putpacket(remcomOutBuffer);
+
+  while (1)
+    {
+      remcomOutBuffer[0] = 0;
+
+      ptr = getpacket();
+      switch (*ptr++)
+       {
+       case '?':
+         remcomOutBuffer[0] = 'S';
+         remcomOutBuffer[1] = hexchars[sigval >> 4];
+         remcomOutBuffer[2] = hexchars[sigval & 0xf];
+         remcomOutBuffer[3] = 0;
+         break;
+
+       case 'd':               /* toggle debug flag */
+         break;
+
+       case 'g':               /* return the value of the CPU registers */
+         {
+           ptr = remcomOutBuffer;
+           ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
+           ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */
+           memset(ptr, '0', 32 * 8); /* Floating point */
+           mem2hex((char *)&registers[Y],
+                   ptr + 32 * 4 * 2,
+                   8 * 4,
+                   0);         /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+         }
+         break;
+
+       case 'G':          /* set the value of the CPU registers - return OK */
+         {
+           unsigned long *newsp, psr;
+
+           psr = registers[PSR];
+
+           hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+           hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
+           hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
+                   8 * 4, 0);  /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+
+           /* See if the stack pointer has moved.  If so, then copy the saved
+              locals and ins to the new location.  This keeps the window
+              overflow and underflow routines happy.  */
+
+           newsp = (unsigned long *)registers[SP];
+           if (sp != newsp)
+             sp = memcpy(newsp, sp, 16 * 4);
+
+           /* Don't allow CWP to be modified. */
+
+           if (psr != registers[PSR])
+             registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+           strcpy(remcomOutBuffer,"OK");
+         }
+         break;
+
+       case 'm':         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
+         /* Try to read %x,%x.  */
+
+         if (hexToInt(&ptr, &addr)
+             && *ptr++ == ','
+             && hexToInt(&ptr, &length))
+           {
+             if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
+               break;
+
+             strcpy (remcomOutBuffer, "E03");
+           }
+         else
+           strcpy(remcomOutBuffer,"E01");
+         break;
+
+       case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+         /* Try to read '%x,%x:'.  */
+
+         if (hexToInt(&ptr, &addr)
+             && *ptr++ == ','
+             && hexToInt(&ptr, &length)
+             && *ptr++ == ':')
+           {
+             if (hex2mem(ptr, (char *)addr, length, 1))
+               strcpy(remcomOutBuffer, "OK");
+             else
+               strcpy(remcomOutBuffer, "E03");
+           }
+         else
+           strcpy(remcomOutBuffer, "E02");
+         break;
+
+       case 'c':    /* cAA..AA    Continue at address AA..AA(optional) */
+         /* try to read optional parameter, pc unchanged if no parm */
+
+         if (hexToInt(&ptr, &addr))
+           {
+             registers[PC] = addr;
+             registers[NPC] = addr + 4;
+           }
+
+/* Need to flush the instruction cache here, as we may have deposited a
+   breakpoint, and the icache probably has no way of knowing that a data ref to
+   some location may have changed something that is in the instruction cache.
+ */
+
+         flush_i_cache();
+         return;
+
+         /* kill the program */
+       case 'k' :              /* do nothing */
+         break;
+#if 0
+       case 't':               /* Test feature */
+         asm (" std %f30,[%sp]");
+         break;
+#endif
+       case 'r':               /* Reset */
+         asm ("call 0
+               nop ");
+         break;
+       }                       /* switch */
+
+      /* reply to the request */
+      putpacket(remcomOutBuffer);
+    }
+}
+
+/* This function will generate a breakpoint exception.  It is used at the
+   beginning of a program to sync up with a debugger and can be used
+   otherwise as a quick means to stop program execution and "break" into
+   the debugger. */
+
+void
+breakpoint (void)
+{
+  if (!initialized)
+    return;
+
+  asm("        .globl _breakinst
+
+       _breakinst: ta 1
+      ");
+}