blob: ca3cea5a5896c783aa8dac7ead4a90ed25c9b525 [file] [log] [blame]
Björn Stenberge1715c22002-03-28 14:34:13 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <stdio.h>
21#include <stdlib.h>
22
23int main (int argc, char** argv)
24{
25 unsigned long length,i,slen;
26 unsigned char *inbuf,*outbuf;
27 unsigned short crc=0;
Björn Stenberg323f2972002-12-19 15:00:40 +000028 unsigned char header[24];
29 unsigned char *iname = argv[1];
30 unsigned char *oname = argv[2];
31 int headerlen = 6;
Björn Stenberge1715c22002-03-28 14:34:13 +000032 FILE* file;
33
34 if (argc < 3) {
Björn Stenberg323f2972002-12-19 15:00:40 +000035 printf("usage: %s [-fm] <input file> <output file>\n",argv[0]);
Björn Stenberge1715c22002-03-28 14:34:13 +000036 return -1;
37 }
Björn Stenberg323f2972002-12-19 15:00:40 +000038
39 if (argv[1][0] == '-') { /* assume any parameter is -fm :-) */
40 headerlen = 24;
41 iname = argv[2];
42 oname = argv[3];
43 }
Björn Stenberge1715c22002-03-28 14:34:13 +000044
45 /* open file */
Björn Stenberg323f2972002-12-19 15:00:40 +000046 file = fopen(iname,"rb");
Björn Stenberge1715c22002-03-28 14:34:13 +000047 if (!file) {
Björn Stenberg323f2972002-12-19 15:00:40 +000048 perror(iname);
Björn Stenberge1715c22002-03-28 14:34:13 +000049 return -1;
50 }
51 fseek(file,0,SEEK_END);
52 length = ftell(file);
Linus Nielsen Feltzing1326f662003-04-12 21:17:47 +000053 length = (length + 3) & ~3; /* Round up to nearest 4 byte boundary */
54
Linus Nielsen Feltzing6a429972003-04-14 09:59:47 +000055 if ((length + headerlen) >= 0x32000) {
56 printf("error: max firmware size is 200KB!\n");
57 fclose(file);
58 return -1;
59 }
60
Björn Stenberge1715c22002-03-28 14:34:13 +000061 fseek(file,0,SEEK_SET);
62 inbuf = malloc(length);
63 outbuf = malloc(length);
64 if ( !inbuf || !outbuf ) {
65 printf("out of memory!\n");
66 return -1;
67 }
68
69 /* read file */
70 i=fread(inbuf,1,length,file);
71 if ( !i ) {
Björn Stenberg323f2972002-12-19 15:00:40 +000072 perror(iname);
Björn Stenberge1715c22002-03-28 14:34:13 +000073 return -1;
74 }
75 fclose(file);
76
77 /* scramble */
78 slen = length/4;
79 for (i = 0; i < length; i++) {
80 unsigned long addr = (i >> 2) + ((i % 4) * slen);
81 unsigned char data = inbuf[i];
82 data = ~((data << 1) | ((data >> 7) & 1)); /* poor man's ROL */
83 outbuf[addr] = data;
84 }
85
86 /* calculate checksum */
87 for (i=0;i<length;i++)
88 crc += inbuf[i];
89
90 /* make header */
Björn Stenberg323f2972002-12-19 15:00:40 +000091 memset(header, 0, sizeof header);
92 if (headerlen == 6) {
93 header[0] = (length >> 24) & 0xff;
94 header[1] = (length >> 16) & 0xff;
95 header[2] = (length >> 8) & 0xff;
96 header[3] = length & 0xff;
97 header[4] = (crc >> 8) & 0xff;
98 header[5] = crc & 0xff;
99 }
100 else {
101 header[0] =
102 header[1] =
103 header[2] =
104 header[3] = 0xff; /* ??? */
105
106 header[6] = (crc >> 8) & 0xff;
107 header[7] = crc & 0xff;
108
109 header[11] = 4; /* ??? */
110
111 header[15] = headerlen; /* really? */
112
113 header[20] = (length >> 24) & 0xff;
114 header[21] = (length >> 16) & 0xff;
115 header[22] = (length >> 8) & 0xff;
116 header[23] = length & 0xff;
117 }
Björn Stenberge1715c22002-03-28 14:34:13 +0000118
119 /* write file */
Björn Stenberg323f2972002-12-19 15:00:40 +0000120 file = fopen(oname,"wb");
Björn Stenberge1715c22002-03-28 14:34:13 +0000121 if ( !file ) {
Björn Stenberg323f2972002-12-19 15:00:40 +0000122 perror(oname);
Björn Stenberge1715c22002-03-28 14:34:13 +0000123 return -1;
124 }
Björn Stenberg323f2972002-12-19 15:00:40 +0000125 if ( !fwrite(header,headerlen,1,file) ) {
126 perror(oname);
Björn Stenberge1715c22002-03-28 14:34:13 +0000127 return -1;
128 }
129 if ( !fwrite(outbuf,length,1,file) ) {
Björn Stenberg323f2972002-12-19 15:00:40 +0000130 perror(oname);
Björn Stenberge1715c22002-03-28 14:34:13 +0000131 return -1;
132 }
133 fclose(file);
134
135 free(inbuf);
136 free(outbuf);
137
Linus Nielsen Feltzing6a429972003-04-14 09:59:47 +0000138 return 0;
Björn Stenberge1715c22002-03-28 14:34:13 +0000139}