* rom68k-rom.c: New file. Replaces the old remote-mon.c and uses
authorRob Savoye <rob@cygnus>
Thu, 10 Nov 1994 23:20:03 +0000 (23:20 +0000)
committerRob Savoye <rob@cygnus>
Thu, 10 Nov 1994 23:20:03 +0000 (23:20 +0000)
the new generic ROM interface in monitor.c.
* config/m68k/monitor.mt: Use new ROM support.
* monitor.c: Add support for xmodem download protocol.

gdb/ChangeLog
gdb/monitor.c
gdb/rom68k-rom.c [new file with mode: 0644]

index 7fd120803ec4d9072a69d29b9f4d81d19faa190e..4aa00f5418fae040e3ba866523d8882117535782 100644 (file)
@@ -1,3 +1,10 @@
+Thu Nov 10 15:16:21 1994  Rob Savoye  <rob@rtl.cygnus.com>
+
+       * rom68k-rom.c: New file. Replaces the old remote-mon.c and uses
+       the new generic ROM interface in monitor.c.
+       * config/m68k/monitor.mt: Use new ROM support.
+       * monitor.c: Add support for xmodem download protocol.
+
 Wed Nov  9 18:46:24 1994  Stan Shebs  (shebs@andros.cygnus.com)
 
        * findvar.c (find_saved_register): Fix a frame variable name.
index 0113a057873d93e673191b0408cc21450ab2883e..0eaf2938b3f368c7fbc8955359b7bc4c931ed810 100644 (file)
@@ -48,6 +48,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #  define TERMINAL struct sgttyb
 #endif
 
+extern void make_xmodem_packet();
+extern void print_xmodem_packet();
+
 struct monitor_ops *current_monitor;
 extern struct cmd_list_element *setlist;
 extern struct cmd_list_element *unsetlist;
@@ -58,7 +61,6 @@ extern char *target_name;
 
 static int hashmark;                           /* flag set by "set hash" */
 
-/* FIXME: Replace with sr_get_debug ().  */
 #define LOG_FILE "monitor.log"
 #if defined (LOG_FILE)
 FILE *log_file;
@@ -66,9 +68,10 @@ FILE *log_file;
 
 static int timeout = 24;
 
-/* Descriptor for I/O to remote machine.  Initialize it to NULL so that
-   monitor_open knows that we don't have a file open when the program starts.
-   */
+/* 
+ * Descriptor for I/O to remote machine.  Initialize it to NULL so that
+ * monitor_open knows that we don't have a file open when the program starts.
+ */
 static serial_t monitor_desc = NULL;
 
 /* sets the download protocol, choices are srec, generic, boot */
@@ -78,6 +81,20 @@ static void set_loadtype_command();
 static void monitor_load_srec();
 static int monitor_write_srec();
 
+/*
+ * these definitions are for xmodem protocol
+ */
+#define SOH    0x01
+#define ACK    0x06
+#define NAK    0x15
+#define EOT    0x04
+#define CANCEL 0x18
+#define GETACK         getacknak(ACK)
+#define GETNAK         getacknak(NAK)
+#define XMODEM_DATASIZE        128             /* the data   size is ALWAYS 128 */
+#define XMODEM_PACKETSIZE      131     /* the packet size is ALWAYS 132 (zero based) */
+#define XMODEM         1
+
 /*
  * set_loadtype_command -- set the type for downloading. Check to make
  *     sure you have a support protocol for this target.
@@ -134,6 +151,21 @@ printf_monitor(va_alist)
   if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
     fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
 }
+/*
+ * write_monitor -- send raw data to monitor.
+ */
+static void
+write_monitor(data, len)
+     char data[];
+     int len;
+{
+  if (SERIAL_WRITE(monitor_desc, data, len))
+    fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
+  *(data + len+1) = '\0';
+  debuglogs (1, "write_monitor(), Sending: \"%s\".", data);
+
+}
 
 /*
  * debuglogs -- deal with debugging info to multiple sources. This takes
@@ -155,7 +187,7 @@ debuglogs(va_alist)
 
   level = va_arg(args, int);                   /* get the debug level */
   if ((level <0) || (level > 100)) {
-    error ("Bad argument passed to debuglogs()");
+    error ("Bad argument passed to debuglogs(), needs debug level");
     return;
   }
       
@@ -222,7 +254,7 @@ readchar(timeout)
 
   c = SERIAL_READCHAR(monitor_desc, timeout);
 
-  if (sr_get_debug() > 4)
+  if (sr_get_debug() > 5)
     putchar(c & 0x7f);
 
 #ifdef LOG_FILE
@@ -238,7 +270,7 @@ readchar(timeout)
       return c;                /* Polls shouldn't generate timeout errors */
     error("Timeout reading from remote system.");
 #ifdef LOG_FILE
-      fputc ("ERROR: Timeout reading from remote system", log_file);
+      fputs ("ERROR: Timeout reading from remote system", log_file);
 #endif
   }
   perror_with_name("remote-monitor");
@@ -300,11 +332,6 @@ static void
 expect_prompt(discard)
      int discard;
 {
-#if defined (LOG_FILE)
-  /* This is a convenient place to do this.  The idea is to do it often
-     enough that we never lose much data if we terminate abnormally.  */
-  fflush(log_file);
-#endif
   expect (PROMPT, discard);
 }
 
@@ -316,6 +343,7 @@ junk(ch)
      char ch;
 {
   switch (ch) {
+  case '\0':
   case ' ':
   case '-':
   case '\t':
@@ -357,7 +385,7 @@ get_hex_digit(ignore)
       ;
     else {
       expect_prompt(1);
-      error("Invalid hex digit from remote system.");
+      error("Invalid hex digit from remote system. (0x%x)", ch);
     }
   }
 }
@@ -963,7 +991,8 @@ monitor_remove_breakpoint (addr, shadow)
 /* monitor_load -- load a file. This file determines which of the
  *     supported formats to use. The current types are:
  *     FIXME: not all types supported yet.
- *     default - reads any file using bfd and writes it to memory.
+ *     default - reads any file using bfd and writes it to memory. This
+ *             is really slow.
  *     srec    - reads binary file using bfd and writes it as an
  *             ascii srecord.
  *     xmodem-bin - reads a binary file using bfd, and  downloads it
@@ -990,7 +1019,7 @@ monitor_load (file, fromtty)
   }
 
   if (STREQ (loadtype_str, "srec")) {          /* load an srecord by converting */
-    monitor_load_srec(file, fromtty);          /* if from a binary */
+    monitor_load_srec(file, 0);                        /* if from a binary */
   }
 
   if (STREQ (loadtype_str, "ascii-srec")) {    /* load an srecord file */
@@ -998,7 +1027,7 @@ monitor_load (file, fromtty)
   }
 
   if (STREQ (loadtype_str, "xmodem-srec")) {   /* load an srecord using the */
-   error ("This protocol is not implemented yet.");    /* xmodem protocol */
+    monitor_load_srec(file, XMODEM);
   }
 }
 
@@ -1024,7 +1053,7 @@ monitor_load_ascii_srec (file, fromtty)
   }
 
   printf_monitor (LOAD_CMD);
-
+  sleep(1);
   while (!feof (download)) {
     bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
     if (hashmark) {
@@ -1083,17 +1112,41 @@ monitor_command (args, fromtty)
 }
 
 /*
- * monitor_load_srec -- download a binary file by converting it to srecords.
+ * monitor_load_srec -- download a binary file by converting it to srecords. This
+ *     will also use xmodem to download the resulting file.
+ *
+ *     A download goes like this when using xmodem:
+ *     Receiver:               Sender
+ *     NAK ---------->
+ *             <-------- (packet)      [SOH|1|1|data|SUM]
+ *     ACK ---------->
+ *             <-------- (packet)      [SOH|2|2|data|SUM]
+ *     ACK ---------->
+ *             <-------- EOT
+ *     ACK ---------->
+ *
+ *     ACK = 0x06
+ *     NAK = 0x15
+ *     EOT = 0x04
+ *
  */
 static void
-monitor_load_srec (args, fromtty)
+monitor_load_srec (args, protocol)
      char *args;
-     int fromtty;
+     int protocol;
 {
   bfd *abfd;
   asection *s;
   char buffer[1024];
-  int srec_frame = SREC_SIZE;
+  char srec[1024];
+  char packet[XMODEM_PACKETSIZE];
+  int i;
+  int retries;
+  int type = 0;                                        /* default to a type 0, header record */
+  int srec_frame = 57;                         /* FIXME: this must be 57 There is 12 bytes
+                                                of header, and 2 bytes of checksum at the end.
+                                                The problem is an xmodem packet holds exactly
+                                                128 bytes. */
 
   abfd = bfd_openr (args, 0);
   if (!abfd) {
@@ -1106,174 +1159,309 @@ monitor_load_srec (args, fromtty)
     return;
   }
   
+  printf_monitor (LOAD_CMD);                   /* tell the monitor to load */
+  if (protocol == XMODEM) {                    /* get the NAK from the target */
+    if (GETNAK) {
+      debuglogs (3, "Got the NAK to start loading");
+    } else {
+      printf_monitor ("%c", EOT);
+      debuglogs (3, "Never got the NAK to start loading");
+      error ("Never got the NAK to start loading");
+    }
+  }
+  
   s = abfd->sections;
   while (s != (asection *) NULL) {
-    srec_frame = SREC_SIZE;
     if (s->flags & SEC_LOAD) {
-      int i;
       char *buffer = xmalloc (srec_frame);
-      printf_filtered ("%s\t: 0x%4x .. 0x%4x  ", s->name, s->vma, s->vma + s
-                      ->_raw_size);
+      printf_filtered ("%s\t: 0x%4x .. 0x%4x  ", s->name, s->vma, s->vma + s->_raw_size);
       fflush (stdout);
       for (i = 0; i < s->_raw_size; i += srec_frame) {
        if (srec_frame > s->_raw_size - i)
          srec_frame = s->_raw_size - i;
        
        bfd_get_section_contents (abfd, s, buffer, i, srec_frame);
-       monitor_write_srec (s->vma + i, buffer, srec_frame);
-       printf_filtered ("*");
+       monitor_make_srec (srec, type, s->vma + i, buffer, srec_frame);
+       if (protocol == XMODEM) {               /* send a packet using xmodem */
+         make_xmodem_packet (packet, srec, XMODEM_DATASIZE);
+         write_monitor (packet, XMODEM_PACKETSIZE+1);
+         retries = 0;
+         while (retries++ <= 3) {
+           if (GETNAK) {                       /* Resend packet */
+             debuglogs (3, "Got a NAK, resending packet");
+             sleep(1);
+             write_monitor (packet, XMODEM_PACKETSIZE+1); /* send it again */
+             if (GETACK)                       /* ACKnowledged, get next data chunk */
+               break;
+           }
+         }
+         if (retries >= 4) {           /* too many tries, must be hosed */
+           printf_monitor ("%c", EOT);
+           error ("Never got a ACK after sending an xmodem packet");
+         }
+       } else {                                /* no protocols at all */
+         printf_monitor ("%s\n", srec);
+       }
+       if (hashmark)
+         printf_filtered ("#");
+       type = 3;                               /* switch to a 4 byte address record */
        fflush (stdout);
       }
       printf_filtered ("\n");
       free (buffer);
+    } else {
+      debuglogs (3, "%s doesn't need to be loaded", s->name);
     }
     s = s->next;
   }
-  sprintf (buffer, "rs ip %lx", (unsigned long) abfd->start_address);
-  printf_monitor (buffer);
+  
+  /*
+     write a type 7 terminator record. no data for a type 7,
+     and there is no data, so len is 0. 
+   */
+  monitor_make_srec (srec, 7, abfd->start_address, "", 0);
+  printf_monitor ("%s\n", srec);
+  if (protocol == XMODEM) {
+    printf_monitor ("%c", EOT);
+    if (!GETACK)
+      error ("Never got ACK after sending EOT");
+  }
+
+  if (hashmark) 
+    putchar ('\n');
+  
   expect_prompt ();
 }
 
+/*
+ * getacknak -- get an ACK or a NAK from the target.
+ *             returns 1 (true) or 0 (false) This is
+ *             for xmodem. ANy string starting with "***"
+ *             is an error message from the target.
+ *     Here's a few from the WinBond w89k "Cougar" PA board.
+ *             *** Too many errors found.
+ *             *** Bad command
+ *             *** Command syntax error
+ */
+int
+getacknak (byte)
+     int byte;
+{
+  char character;
+  int i;
+  
+  i = 0;
+  while (i++ < 60) {
+    character = (char)readchar (0);
+    if (character == 0xfffffffe) {             /* empty uart */
+      if (sr_get_debug() > 3)
+       putchar ('.');
+      fflush (stdout);
+      sleep (1);
+      continue;
+    }
+    if (character == CANCEL) {                 /* target aborted load */
+      expect_prompt (0);
+      error ("Got a CANCEL from the target.");
+    }
+    if (character == '*') {                    /* look for missed error message */
+      expect_prompt (0);
+      error ("Got an error message from the target");
+    }
+    debuglogs (3, "Got a %s (0x%x or \'%c\'), expecting a %s.\n",
+              (character == ACK) ? "ACK" : (character == NAK) ? "NAK" : "BOGUS",
+              character,  character, (byte == ACK) ? "ACK" : "NAK");
+    if (character == byte)                     /* got what we wanted */
+      return 1;
+    if (character == ((byte == ACK) ? NAK : ACK)) {    /* got the opposite */
+      debuglogs (3, "Got the opposite, wanted 0x%x, got a 0x%x", byte, character);
+      return 0;
+    }
+    sleep (1); 
+  }
+  return 0;
+}
 
-static int
-monitor_write_srec (memaddr, myaddr, len)
+/*
+ * monitor_make_srec -- make an srecord. This writes each line, one at a
+ *     time, each with it's own header and trailer line.
+ *     An srecord looks like this:
+ *
+ * byte count-+     address
+ * start ---+ |        |       data        +- checksum
+ *         | |        |                   |
+ *       S01000006F6B692D746573742E73726563E4
+ *       S315000448600000000000000000FC00005900000000E9
+ *       S31A0004000023C1400037DE00F023604000377B009020825000348D
+ *       S30B0004485A0000000000004E
+ *       S70500040000F6
+ *
+ *     S<type><length><address><data><checksum>
+ *
+ *      Where
+ *      - length
+ *        is the number of bytes following upto the checksum. Note that
+ *        this is not the number of chars following, since it takes two
+ *        chars to represent a byte.
+ *      - type
+ *        is one of:
+ *        0) header record
+ *        1) two byte address data record
+ *        2) three byte address data record
+ *        3) four byte address data record
+ *        7) four byte address termination record
+ *        8) three byte address termination record
+ *        9) two byte address termination record
+ *       
+ *      - address
+ *        is the start address of the data following, or in the case of
+ *        a termination record, the start address of the image
+ *      - data
+ *        is the data.
+ *      - checksum
+ *       is the sum of all the raw byte data in the record, from the length
+ *        upwards, modulo 256 and subtracted from 255.
+ */
+int
+monitor_make_srec (buffer, type, memaddr, myaddr, len)
+     char *buffer;
+     int type;
      CORE_ADDR memaddr;
      unsigned char *myaddr;
      int len;
 {
-  int done;
   int checksum;
-  int x;
-  int retries;
-  int srec_bytes = 40;
-  int srec_max_retries = 3;
-  int srec_echo_pace = 0;
-  int srec_sleep = 0;
-  int srec_noise = 0;
-  char *buffer = alloca ((srec_bytes + 8) << 1);
+  int i;
+  char *buf;
 
-  retries = 0;
+  buf = buffer;
+  debuglogs (4, "monitor_make_srec (buffer=0x%x, type=%d, memaddr=0x%x, len=%d",
+                                   buffer, type, memaddr, len); 
+  checksum = 0;
+  
+  /*
+     create the header for the srec. 4 is the number of bytes in the address,
+     and 1 is the number of bytes in the count.
+   */
+  if (type == 0)                               /* FIXME: type 0 is optional */
+    type = 3;                                  /* so use data as it works */
+  sprintf (buf, "S%d%02X%08X", type, len + 4 + 1, memaddr);
+  buf += 12;
+  
+  checksum += (len + 4 + 1                     /* calculate the checksum */
+              + (memaddr & 0xff)
+              + ((memaddr >>  8) & 0xff)
+              + ((memaddr >> 16) & 0xff)
+              + ((memaddr >> 24) & 0xff));
+  
+  for (i = 0; i < len; i++) {          /* build the srecord */
+    sprintf (buf, "%02X", myaddr[i]);
+    checksum += myaddr[i];
+    buf += 2;
+  }
 
-  while (1) {                                  /* FIXME !!! */
-    done = 0;
-    
-    if (retries > srec_max_retries)
-      return(-1);
-    
-      if (retries > 0) {
-       if (sr_get_debug() > 0)
-         printf("\n<retrying...>\n");
-       
-          /* This gr_expect_prompt call is extremely important.  Without
-             it, we will tend to resend our packet so fast that it
-             will arrive before the bug monitor is ready to receive
-             it.  This would lead to a very ugly resend loop.  */
-       
-       gr_expect_prompt();
-      }
-    
-    /* FIXME: this is just start_load pasted in... */
-    { char *command;
-    command = (srec_echo_pace ? "lo 0 ;x" : "lo 0");
-    sr_write_cr (command);
-    sr_expect (command);
-    sr_expect ("\r\n");
-#if 0
-    bug_srec_write_cr ("S0030000FC");
-#endif
-    }
-    /* end of hack */
+  sprintf(buf, "%02X", ~checksum & 0xff);      /* add the checksum */
+  debuglogs (3, "srec is \"%s\"", buffer);
+  
+  return(0);
+}
 
-      while (done < len) {
-       int thisgo;
-       int idx;
-       char *buf = buffer;
-       CORE_ADDR address;
-       
-       checksum = 0;
-       thisgo = len - done;
-       if (thisgo > srec_bytes)
-         thisgo = srec_bytes;
-       
-       address = memaddr + done;
-       sprintf (buf, "S3%02X%08X", thisgo + 4 + 1, address);
-       buf += 12;
-       
-       checksum += (thisgo + 4 + 1
-                    + (address & 0xff)
-                    + ((address >>  8) & 0xff)
-                    + ((address >> 16) & 0xff)
-                    + ((address >> 24) & 0xff));
-       
-       for (idx = 0; idx < thisgo; idx++) {
-         sprintf (buf, "%02X", myaddr[idx + done]);
-         checksum += myaddr[idx + done];
-         buf += 2;
-       }
-       
-       if (srec_noise > 0) {
-         /* FIXME-NOW: insert a deliberate error every now and then.
-            This is intended for testing/debugging the error handling
-            stuff.  */
-         static int counter = 0;
-         if (++counter > srec_noise) {
-           counter = 0;
-           ++checksum;
-         }
-       }
-       
-       sprintf(buf, "%02X", ~checksum & 0xff);
+/*
+ * make_xmodem_packet -- this takes a 128 bytes of data and makes a packet
+ *     out of it.
+ *
+ *     Each packet looks like this:
+ *     +-----+-------+-------+------+-----+
+ *     | SOH | Seq1. | Seq2. | data | SUM |
+ *     +-----+-------+-------+------+-----+
+ *     SOH  = 0x01
+ *     Seq1 = The sequence number.
+ *     Seq2 = The complement of the sequence number.
+ *     Data = A 128 bytes of data.
+ *     SUM  = Add the contents of the 128 bytes and use the low-order
+ *            8 bits of the result.
+ */
+void
+make_xmodem_packet (packet, data, len)
+     unsigned char packet[];
+     unsigned char *data;
+     int len;
+{
+  static int sequence = 1;
+  int i, sum;
+  unsigned char *buf;
+  
+  buf = data;
+  /* build the packet header */
+  packet[0] = SOH;
+  packet[1] = sequence;
+  packet[2] = 255 - sequence;
+  sequence++;
 #if 0
-       bug_srec_write_cr (buffer);
+  packet[2] = ~sequence++;                     /* the complement is the sequence checksum */
 #endif
-       
-       if (srec_sleep != 0)
-         sleep(srec_sleep);
-       
-       /* This pollchar is probably redundant to the gr_multi_scan
-          below.  Trouble is, we can't be sure when or where an
-          error message will appear.  Apparently, when running at
-          full speed from a typical sun4, error messages tend to
-          appear to arrive only *after* the s7 record.   */
-       
-       if ((x = sr_pollchar()) != 0) {
-         if (sr_get_debug() > 0)
-           printf("\n<retrying...>\n");
-
-         ++retries;
-         
-         /* flush any remaining input and verify that we are back
-            at the prompt level. */
-         gr_expect_prompt();
-         /* start all over again. */
-    /* FIXME: this is just start_load pasted in... */
-    { char *command;
-    command = (srec_echo_pace ? "lo 0 ;x" : "lo 0");
-    sr_write_cr (command);
-    sr_expect (command);
-    sr_expect ("\r\n");
+  
+  sum = 0;                                     /* calculate the data checksum */
+  for (i = 3; i <= len + 2; i++) {
+    packet[i] = *buf;
+    sum += *buf;
+    buf++;
+  }
+
+  for (i = len+1 ; i <= XMODEM_DATASIZE ; i++) {       /* add padding for the rest of the packet */
+    packet[i] = '0';
+  }
+
+  packet[XMODEM_PACKETSIZE] = sum & 0xff;      /* add the checksum */
+
+  if (sr_get_debug() > 4)
+    debuglogs (4, "The xmodem checksum is %d (0x%x)\n", sum & 0xff, sum & 0xff);
+    print_xmodem_packet (packet);
+}
+
+/*
+ * print_xmodem_packet -- print the packet as a debug check
+ */
+void
+print_xmodem_packet(packet)
+     char packet[];
+{
+  int i;
+  static int lastseq;
+  int sum;
+
+  /* take apart the packet header the packet header */
+  if (packet[0] == SOH) {
+     ("SOH");
+  } else {
+    error ("xmodem: SOH is wrong");
+  }
+  
+  /* check the sequence */
+  if (packet[1] != 0) {
+    lastseq = packet[1];
+    if (packet[2] != ~lastseq)
+      error ("xmodem: Sequence checksum is wrong");
+    else
+      printf_filtered (" %d %d", lastseq, ~lastseq);
+  }
+  
+  /* check the data checksum */
+  sum = 0;
+  for (i = 3; i <= XMODEM_DATASIZE; i++) {
+    sum += packet[i];
+  }
+
+  /* ignore the data */
 #if 0
-    bug_srec_write_cr ("S0030000FC");
+  printf (" [128 bytes of data] %d\n", sum & 0xff);
 #endif
-    }
-    /* end of hack */
+  printf_filtered (" [%s] %d\n", packet, sum & 0xff);
 
-         done = 0;
-         continue;
-       }
-       
-       done += thisgo;
-      }
-#if 0    
-    bug_srec_write_cr("S7060000000000F9");
-#endif
-    ++retries;
-    
-    /* Having finished the load, we need to figure out whether we
-       had any errors.  */
+  if ((packet[XMODEM_PACKETSIZE] & 0xff) != (sum & 0xff)) {
+    debuglogs (4, "xmodem: data checksum wrong, got a %d", packet[XMODEM_PACKETSIZE] & 0xff);
   }
-  
-  return(0);
+  putchar ('\n');
 }
 
 /*
diff --git a/gdb/rom68k-rom.c b/gdb/rom68k-rom.c
new file mode 100644 (file)
index 0000000..719cb4d
--- /dev/null
@@ -0,0 +1,143 @@
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+
+extern int baud_rate;
+
+void rom68k_open();
+void monitor_open();
+
+/*
+ * this array of registers need to match the indexes used by GDB. The
+ * whole reason this exists is cause the various ROM monitors use
+ * different strings than GDB does, and doesn't support all the
+ * registers either. So, typing "info reg sp" becomes a "r30".
+ */
+static char *rom68k_regnames[] = {
+  "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0", "a1",
+  "a2", "a3", "a4", "a5", "a6", "usp", "ssp","pc",   "",   "",
+  "",   "",   "",   "",   "",   "",   "",   "",   "",   "",
+  "",   "",   "",   "",   "",   "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",  "",  "",
+  "",   "",   "",   "",   "",   "",    "",    "",  "",  "",
+  "",   "",   "",   "",   "",   "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",
+  "",   "",   "",   "",   "",   "",    "",    "",
+  "",   "",   "",   "",   "",   "",    "",    ""
+};
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+
+struct target_ops rom68k_ops = {
+  "rom68k",
+  "WinBond's debug monitor for the Rom68k Eval board",
+  "Debug on a Motorola IDP eval board running the ROM68K monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+  rom68k_open,
+  monitor_close, 
+  monitor_attach,
+  monitor_detach,
+  monitor_resume,
+  monitor_wait,
+  monitor_fetch_register,
+  monitor_store_register,
+  monitor_prepare_to_store,
+  monitor_xfer_inferior_memory,
+  monitor_files_info,
+  monitor_insert_breakpoint,
+  monitor_remove_breakpoint,   /* Breakpoints */
+  0,
+  0,
+  0,
+  0,
+  0,                           /* Terminal handling */
+  monitor_kill,
+  monitor_load,                        /* load */
+  0,                           /* lookup_symbol */
+  monitor_create_inferior,
+  monitor_mourn_inferior,
+  0,                           /* can_run */
+  0,                           /* notice_signals */
+  process_stratum,
+  0,                           /* next */
+  1,
+  1,
+  1,
+  1,
+  1,                           /* all mem, mem, stack, regs, exec */
+  0,
+  0,                           /* Section pointers */
+  OPS_MAGIC,                   /* Always the last thing */
+};
+
+struct monitor_ops rom68k_cmds = {
+  1,                                   /* 1 for ASCII, 0 for binary */
+  "\n",                                        /* monitor init string */
+  "go \n",                             /* execute or usually GO command */
+  "go \n",                             /* continue command */
+  "st \n",                             /* single step */
+  "db %x\n",                           /* set a breakpoint */
+  "cb %x\r",                           /* clear a breakpoint */
+  0,                                   /* 0 for number, 1 for address */
+  {
+    "pm %x %x\r",                      /* set memory */
+    "=",                               /* delimiter */
+    "",                                        /* the result */
+  },
+  {
+    "dm %x 1\r",                       /* get memory */
+    "",                                        /* delimiter */
+    "",                                        /* the result */
+  },
+  {
+    "pr %s %x\r",                      /* set a register */
+    "",                                        /* delimiter between registers */
+    "",                                        /* the result */
+  },
+  {
+    "pr %s\n",                         /* get a register */
+    ":",                               /* delimiter between registers */
+    "",                                        /* the result */
+  },
+  "dc\n",                              /* download command */
+  "ROM68K :->",                                /* monitor command prompt */
+  "=",                                 /* end-of-command delimitor */
+  ".\n",                               /* optional command terminator */
+  &rom68k_ops,                         /* target operations */
+  "srec,xmodem-ascii,xmodem-srec,default",/* load types */
+  rom68k_regnames                      /* registers names */
+};
+
+void
+rom68k_open(args, from_tty)
+     char *args;
+     int from_tty;
+{
+  target_preopen(from_tty);
+  push_target  (&rom68k_ops);
+  push_monitor (&rom68k_cmds);
+  monitor_open (args, "rom68k", from_tty);
+}
+
+void
+_initialize_rom68k ()
+{
+  add_target (&rom68k_ops);
+
+  /* this is the default, since it's the only baud rate supported by the hardware */
+  baud_rate = 9600;
+}
+
+
+
+