burner.c00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00074 #include <sys/ports.h>
00075
00076 typedef void __attribute__ ((noreturn)) (* func)();
00077
00078 static unsigned short get_char (void);
00079 static unsigned char* get_addr (void);
00080 volatile int __attribute__((noreturn)) main ();
00081 static void flush (void);
00082 void eeprom_write_byte (unsigned char *p, const unsigned char value);
00083 void udelay_10ms (void);
00084 void _start (void);
00085
00086 void
00087 _start()
00088 {
00089 __asm__ __volatile__ ("bra main");
00090
00091 }
00092
00093 static void
00094 flush ()
00095 {
00096 while (!(_io_ports[M6811_SCSR] & M6811_TDRE))
00097 continue;
00098 }
00099
00100 static void
00101 put_char (unsigned char c)
00102 {
00103 flush ();
00104 _io_ports[M6811_SCDR] = c;
00105 _io_ports[M6811_SCCR2] |= M6811_TE;
00106 }
00107
00108 volatile int
00109 main ()
00110 {
00111 unsigned char* addr;
00112 unsigned char c;
00113
00114 while (1)
00115 {
00116
00117 put_char ('\n');
00118 put_char ('>');
00119
00120
00121 c = get_char ();
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 if (c == 'M')
00135 {
00136 unsigned char size;
00137
00138 addr = get_addr ();
00139 size = get_char ();
00140 do
00141 {
00142 *addr = get_char ();
00143 eeprom_write_byte (addr, get_char ());
00144 put_char (*addr);
00145 }
00146 while (--size != 0);
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 else if (c == 'G')
00156 {
00157 func handler;
00158
00159 addr = get_addr ();
00160 put_char ('G');
00161 put_char ('\n');
00162 flush ();
00163
00164 handler = (func) addr;
00165 handler ();
00166 }
00167
00168
00169 else
00170 {
00171 put_char ('?');
00172 }
00173 }
00174 }
00175
00176 void
00177 udelay_10ms ()
00178 {
00179 unsigned short tmp = 40000;
00180
00181 __asm__ __volatile__ ("1: subd #1\n"
00182 " bne 1b" : "=d"(tmp) : "d"(tmp));
00183 }
00184
00194 void
00195 eeprom_write_byte (unsigned char *p, const unsigned char value)
00196 {
00197 unsigned char diff;
00198
00199 diff = *p ^ value;
00200 if (diff)
00201 {
00202 if (diff & value)
00203 {
00204
00205 diff = *p ^ value;
00206 if (diff == 0)
00207 return;
00208
00209 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_ERASE | M6811_BYTE;
00210 *p = value;
00211 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_ERASE
00212 | M6811_BYTE | M6811_EEPGM;
00213
00214
00215 udelay_10ms ();
00216 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_ERASE | M6811_BYTE;
00217 }
00218
00219
00220 _io_ports[M6811_PPROG] = M6811_EELAT;
00221 *p = value;
00222 _io_ports[M6811_PPROG] = M6811_EELAT | M6811_EEPGM;
00223
00224
00225 udelay_10ms ();
00226 _io_ports[M6811_PPROG] = M6811_EELAT;
00227 _io_ports[M6811_PPROG] = 0;
00228 }
00229 }
00230
00231 static unsigned char*
00232 get_addr ()
00233 {
00234 unsigned short c1, c2;
00235
00236 c1 = get_char ();
00237 c2 = get_char ();
00238 return (unsigned char*) (((unsigned short) c1 << 8) | ((unsigned short) c2));
00239 }
00240
00241 static unsigned short
00242 get_char ()
00243 {
00244 unsigned char c;
00245 volatile unsigned char* ports = &_io_ports[0];
00246
00247 while (1)
00248 {
00249 c = ports[M6811_SCSR];
00250
00251 if (c & M6811_RDRF)
00252 break;
00253 }
00254 return ports[M6811_SCDR];
00255 }
|