dumper.c

Description | Download | Table of Contents | Modules | Compound List | File List | Functions


Overview
Compiler
Documentation
Examples
Misc
Help
IDE & Tools

Download
Install

Links
Projects






00001 /* dumper.c -- Dump content of memory.
00002    Copyright 2000, 2001 Free Software Foundation, Inc.
00003    Written by Stephane Carrez (stcarrez@worldnet.fr)
00004 
00005 This file is part of GTAM.
00006 
00007 GTAM is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GTAM is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GTAM; see the file COPYING.  If not, write to
00019 the Free Software Foundation, 59 Temple Place - Suite 330,
00020 Boston, MA 02111-1307, USA.  */
00021 
00074 #include <sys/ports.h>
00075 
00076 int __attribute__((noreturn)) main ();
00077 static unsigned short get_char ();
00078 
00079 void
00080 _start()
00081 {
00082   set_bus_expanded ();
00083 
00084   main ();
00085 }
00086 
00087 /* Write a character on the serial line.  */
00088 static void
00089 put_char (unsigned char c)
00090 {
00091   while (!(_io_ports[M6811_SCSR] & M6811_TDRE))
00092     continue;
00093 
00094   _io_ports[M6811_SCDR] = c;
00095   _io_ports[M6811_SCCR2] |= M6811_TE;
00096 }
00097 
00098 /* Write an escaped byte on the serial line.  */
00099 static void
00100 put_byte (unsigned char c)
00101 {
00102   /* Don't send \n and escape directly as they may confuse some
00103      synchronisation.  */
00104   if (c == '\n' || c == '\033')
00105     {
00106       put_char ('\033');
00107       c ^= 0x20;
00108     }
00109   put_char (c);
00110 }
00111 
00112 static inline void
00113 reboot()
00114 {
00115 #ifndef NO_REBOOT
00116   /* The 'func' type is marked as 'noreturn' to optimize the
00117      generated code.  */
00118   typedef void __attribute__ ((noreturn)) (* func)();
00119 
00120   func handler;
00121 
00122   set_bus_single_chip ();
00123 
00124   /* To reboot, get the reset vector and go to the start of the ROM.  */
00125   handler = *((func*) 0xbffe);
00126   handler ();
00127 #endif
00128 }
00129 
00130 int
00131 main ()
00132 {
00133   unsigned char* addr;
00134   unsigned char c;
00135   
00136   while (1)
00137     {
00138       /* Print banner for synchronization.  */
00139       put_char ('\n');
00140       put_char ('>');
00141 
00142       /* Wait for command.  */
00143       c = get_char ();
00144 
00145       /* Read memory command.  Command format is:
00146 
00147          R<ADDR-HIGH><ADDR-LOW><SIZE>
00148 
00149          Address and size are passed in binary form.
00150          A size of 0 corresponds to 256 bytes.
00151 
00152          We reply with:
00153 
00154          <SIZE><DATA><CRC>
00155 
00156          where size, data and crc are returned in binary form.  */
00157       if (c == 'R')
00158         {
00159           unsigned char size;
00160           unsigned char crc;
00161           
00162           c = get_char ();
00163           addr = (unsigned char*) ((c << 8) | get_char ());
00164           size = get_char ();
00165 
00166           /* Give a feedback about what we are going to send.  */
00167           put_byte (size);
00168 
00169           crc = 0;
00170           do
00171             {
00172               c = *addr++;
00173               crc ^= c;
00174               put_byte (c);
00175             }
00176           while (--size != 0);
00177           put_byte (crc);
00178         }
00179 
00180       /* Reboot command.  Command format is:
00181 
00182          Z
00183 
00184          We reply with a Z.  The final \n is not seen because it is
00185          clobbered during the reboot.  */
00186       else if (c == 'Z')
00187         {
00188           put_char (c);
00189           put_char ('\n');
00190 
00191           reboot ();
00192         }
00193 
00194       /* For others, emit something to tell we are alive.  */
00195       else
00196         {
00197           put_char ('?');
00198         }
00199     }
00200 }
00201 
00202 #ifndef NO_BREAK
00203 static inline void
00204 restart ()
00205 {
00206   unsigned short i;
00207   volatile unsigned char* ports = &_io_ports[0];
00208 
00209   /* Wait for the transmitter to be ready.  */
00210   while (!(ports[M6811_SCSR] & M6811_TDRE))
00211     continue;
00212   
00213   /* Send a break.  */
00214   ports[M6811_SCCR2] |= M6811_SBK;
00215 
00216   /* Wait some time (??? is it necessary ???).  */
00217   for (i = 1000; --i != 0;)
00218     (void) ports[M6811_TCTN];
00219 
00220   ports[M6811_SCCR2] &= ~M6811_SBK;
00221 
00222   /* Go back to the main with some longjump.  We can't go to _start()
00223      because it was clobbered by the ZTMP and ZREG registers.  */
00224   __asm__ __volatile__ ("lds #0x0ff");
00225   __asm__ __volatile__ ("bra main");
00226 }
00227 #endif
00228 
00229 static unsigned short
00230 get_char ()
00231 {
00232   unsigned char c;
00233   volatile unsigned char* ports = &_io_ports[0];
00234   
00235   while (1)
00236     {
00237       c = ports[M6811_SCSR];
00238 
00239 #ifndef NO_BREAK
00240       /* If there is a read error or a break, abort everything and
00241          restart.  When restarting we send a break so that the host
00242          knows we are restarting.  */
00243       if (c & M6811_FE)
00244         restart ();
00245 #endif
00246 
00247       if (c & M6811_RDRF)
00248         break;
00249     }
00250   return ports[M6811_SCDR];
00251 }

Description | Download | Table of Contents | Modules | Compound List | File List | Functions

    Last modified,
    Apr 16, 2001
[ Copying ]     [ Feedback to Stephane.Carrez@worldnet.fr ]