summaryrefslogtreecommitdiff
path: root/tools/scramble.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/scramble.c')
-rw-r--r--tools/scramble.c157
1 files changed, 6 insertions, 151 deletions
diff --git a/tools/scramble.c b/tools/scramble.c
index 7aa468ebaa..3b9497186d 100644
--- a/tools/scramble.c
+++ b/tools/scramble.c
@@ -36,24 +36,6 @@ static int iaudio_encode(char *iname, char *oname, char *idstring);
36static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc); 36static int ipod_encode(char *iname, char *oname, int fw_ver, bool fake_rsrc);
37static int ccpmp_encode(char *iname, char *oname); 37static int ccpmp_encode(char *iname, char *oname);
38 38
39enum
40{
41 ARCHOS_PLAYER, /* and V1 recorder */
42 ARCHOS_V2RECORDER,
43 ARCHOS_FMRECORDER,
44 ARCHOS_ONDIO_SP,
45 ARCHOS_ONDIO_FM
46};
47
48static unsigned int size_limit[] =
49{
50 0x32000, /* ARCHOS_PLAYER */
51 0x64000, /* ARCHOS_V2RECORDER */
52 0x64000, /* ARCHOS_FMRECORDER */
53 0x64000, /* ARCHOS_ONDIO_SP */
54 0x64000 /* ARCHOS_ONDIO_FM */
55};
56
57void short2le(unsigned short val, unsigned char* addr) 39void short2le(unsigned short val, unsigned char* addr)
58{ 40{
59 addr[0] = val & 0xFF; 41 addr[0] = val & 0xFF;
@@ -91,14 +73,9 @@ void short2be(unsigned short val, unsigned char* addr)
91 73
92void usage(void) 74void usage(void)
93{ 75{
94 printf("usage: scramble [options] <input file> <output file> [xor string]\n"); 76 printf("usage: scramble [options] <input file> <output file>\n");
95 printf("options:\n" 77 printf("options:\n"
96 "\t-fm Archos FM recorder format\n"
97 "\t-v2 Archos V2 recorder format\n"
98 "\t-ofm Archos Ondio FM recorder format\n"
99 "\t-osp Archos Ondio SP format\n"
100 "\t-neo SSI Neo format\n" 78 "\t-neo SSI Neo format\n"
101 "\t-mm=X Archos Multimedia format (X values: A=JBMM, B=AV1xx, C=AV3xx)\n"
102 "\t-iriver iRiver format\n" 79 "\t-iriver iRiver format\n"
103 "\t-iaudiox5 iAudio X5 format\n" 80 "\t-iaudiox5 iAudio X5 format\n"
104 "\t-iaudiox5v iAudio X5V format\n" 81 "\t-iaudiox5v iAudio X5V format\n"
@@ -131,87 +108,38 @@ void usage(void)
131 "\t ip6g, rk27, clzp, zxf2, zxf3, fuz+, e370, e360,\n" 108 "\t ip6g, rk27, clzp, zxf2, zxf3, fuz+, e370, e360,\n"
132 "\t zxfi, zmoz, zen, zenv, ypz5, zxfs, e450, e460,\n" 109 "\t zxfi, zmoz, zen, zenv, ypz5, zxfs, e450, e460,\n"
133 "\t e470, e580, a10, a20, a860, s750, e350, xdx3)\n"); 110 "\t e470, e580, a10, a20, a860, s750, e350, xdx3)\n");
134 printf("\nNo option results in Archos standard player/recorder format.\n"); 111 printf("\nNo option results in nothing being done.\n");
135 112
136 exit(1); 113 exit(1);
137} 114}
138 115
139int main (int argc, char** argv) 116int main (int argc, char** argv)
140{ 117{
141 unsigned long length,i,slen=0; 118 unsigned long length,i;
142 unsigned char *inbuf,*outbuf; 119 unsigned char *inbuf,*outbuf;
143 unsigned short crc=0; 120 unsigned short crc=0;
144 unsigned long chksum=0; /* 32 bit checksum */ 121 unsigned long chksum=0; /* 32 bit checksum */
145 unsigned char header[24]; 122 unsigned char header[24];
146 char *iname = argv[1]; 123 char *iname = argv[1];
147 char *oname = argv[2]; 124 char *oname = argv[2];
148 char *xorstring=NULL;
149 int headerlen = 6; 125 int headerlen = 6;
150 FILE* file; 126 FILE* file;
151 int version=0; 127 int version=0;
152 unsigned long modelnum; 128 unsigned long modelnum;
153 char modelname[5]; 129 char modelname[5];
154 int model_id; 130 enum { none, tcc_sum, tcc_crc, rkw, add } method = none;
155 enum { none, scramble, xor, tcc_sum, tcc_crc, rkw, add } method = scramble;
156 bool creative_enable_ciff; 131 bool creative_enable_ciff;
157 132
158 model_id = ARCHOS_PLAYER;
159
160 if (argc < 3) { 133 if (argc < 3) {
161 usage(); 134 usage();
162 } 135 }
163 136
164 if(!strcmp(argv[1], "-fm")) {
165 headerlen = 24;
166 iname = argv[2];
167 oname = argv[3];
168 version = 4;
169 model_id = ARCHOS_FMRECORDER;
170 }
171
172 else if(!strcmp(argv[1], "-v2")) {
173 headerlen = 24;
174 iname = argv[2];
175 oname = argv[3];
176 version = 2;
177 model_id = ARCHOS_V2RECORDER;
178 }
179
180 else if(!strcmp(argv[1], "-ofm")) {
181 headerlen = 24;
182 iname = argv[2];
183 oname = argv[3];
184 version = 8;
185 model_id = ARCHOS_ONDIO_FM;
186 }
187
188 else if(!strcmp(argv[1], "-osp")) {
189 headerlen = 24;
190 iname = argv[2];
191 oname = argv[3];
192 version = 16;
193 model_id = ARCHOS_ONDIO_SP;
194 }
195
196 else if(!strcmp(argv[1], "-neo")) { 137 else if(!strcmp(argv[1], "-neo")) {
197 headerlen = 17; 138 headerlen = 17;
198 iname = argv[2]; 139 iname = argv[2];
199 oname = argv[3]; 140 oname = argv[3];
200 method = none; 141 method = none;
201 } 142 }
202 else if(!strncmp(argv[1], "-mm=", 4)) {
203 headerlen = 16;
204 iname = argv[2];
205 oname = argv[3];
206 method = xor;
207 version = argv[1][4];
208 if (argc > 4)
209 xorstring = argv[4];
210 else {
211 printf("Multimedia needs an xor string\n");
212 return -1;
213 }
214 }
215 else if(!strncmp(argv[1], "-tcc=", 4)) { 143 else if(!strncmp(argv[1], "-tcc=", 4)) {
216 headerlen = 0; 144 headerlen = 0;
217 iname = argv[2]; 145 iname = argv[2];
@@ -554,20 +482,10 @@ int main (int argc, char** argv)
554 length = ftell(file); 482 length = ftell(file);
555 length = (length + 3) & ~3; /* Round up to nearest 4 byte boundary */ 483 length = (length + 3) & ~3; /* Round up to nearest 4 byte boundary */
556 484
557 if ((method == scramble) &&
558 ((length + headerlen) >= size_limit[model_id])) {
559 printf("error: firmware image is %ld bytes while max size is %u!\n",
560 length + headerlen,
561 size_limit[model_id]);
562 fclose(file);
563 return -1;
564 }
565 485
566 fseek(file,0,SEEK_SET); 486 fseek(file,0,SEEK_SET);
567 inbuf = malloc(length); 487 inbuf = malloc(length);
568 if (method == xor) 488 if(method == add)
569 outbuf = malloc(length*2);
570 else if(method == add)
571 outbuf = malloc(length + 8); 489 outbuf = malloc(length + 8);
572 else 490 else
573 outbuf = malloc(length); 491 outbuf = malloc(length);
@@ -597,32 +515,13 @@ int main (int argc, char** argv)
597 chksum += inbuf[i]; 515 chksum += inbuf[i];
598 } 516 }
599 break; 517 break;
600 case scramble:
601 slen = length/4;
602 for (i = 0; i < length; i++) {
603 unsigned long addr = (i >> 2) + ((i % 4) * slen);
604 unsigned char data = inbuf[i];
605 data = ~((data << 1) | ((data >> 7) & 1)); /* poor man's ROL */
606 outbuf[addr] = data;
607 }
608 break;
609
610 case xor:
611 /* "compress" */
612 slen = 0;
613 for (i=0; i<length; i++) {
614 if (!(i&7))
615 outbuf[slen++] = 0xff; /* all data is uncompressed */
616 outbuf[slen++] = inbuf[i];
617 }
618 break;
619 case none: 518 case none:
620 default: 519 default:
621 /* dummy case just to silence picky compilers */ 520 /* dummy case just to silence picky compilers */
622 break; 521 break;
623 } 522 }
624 523
625 if((method == none) || (method == scramble) || (method == xor)) { 524 if(method == none) {
626 /* calculate checksum */ 525 /* calculate checksum */
627 for (i=0;i<length;i++) 526 for (i=0;i<length;i++)
628 crc += inbuf[i]; 527 crc += inbuf[i];
@@ -650,50 +549,6 @@ int main (int argc, char** argv)
650 telechips_encode_crc(outbuf, length); 549 telechips_encode_crc(outbuf, length);
651 break; 550 break;
652 551
653 case scramble:
654 if (headerlen == 6) {
655 int2be(length, header);
656 header[4] = (crc >> 8) & 0xff;
657 header[5] = crc & 0xff;
658 }
659 else {
660 header[0] =
661 header[1] =
662 header[2] =
663 header[3] = 0xff; /* ??? */
664
665 header[6] = (crc >> 8) & 0xff;
666 header[7] = crc & 0xff;
667
668 header[11] = version;
669
670 header[15] = headerlen; /* really? */
671
672 int2be(length, &header[20]);
673 }
674 break;
675
676 case xor:
677 {
678 int xorlen = strlen(xorstring);
679
680 /* xor data */
681 for (i=0; i<slen; i++)
682 outbuf[i] ^= xorstring[i & (xorlen-1)];
683
684 /* calculate checksum */
685 for (i=0; i<slen; i++)
686 crc += outbuf[i];
687
688 header[0] = header[2] = 'Z';
689 header[1] = header[3] = version;
690 int2le(length, &header[4]);
691 int2le(slen, &header[8]);
692 int2le(crc, &header[12]);
693 length = slen;
694 break;
695 }
696
697#define MY_FIRMWARE_TYPE "Rockbox" 552#define MY_FIRMWARE_TYPE "Rockbox"
698#define MY_HEADER_VERSION 1 553#define MY_HEADER_VERSION 1
699 default: 554 default: