add support for the possible viewport colour tags (%Vf and %Vb). use -c to disable...
[kugel-rb.git] / flash / extract / extract.c
blobe6ea2efdc11dcd9c4a046c2527a6a3d2ff75bafe
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2003 by Jörg Hohensohn
12 * Tool to extract the scrambled image out of an Archos flash ROM dump
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <memory.h>
28 #define UINT8 unsigned char
29 #define UINT16 unsigned short
30 #define UINT32 unsigned long
32 #define IMAGE_HEADER 0x6000 // a 32 byte header in front of the software image
33 #define IMAGE_START 0x6020 // software image position in Flash
36 // place a 32 bit value into memory, big endian
37 void Write32(UINT8* pByte, UINT32 value)
39 pByte[0] = (UINT8)(value >> 24);
40 pByte[1] = (UINT8)(value >> 16);
41 pByte[2] = (UINT8)(value >> 8);
42 pByte[3] = (UINT8)(value);
46 // read a 32 bit value from memory, big endian
47 UINT32 Read32(UINT8* pByte)
49 UINT32 value = 0;
51 value |= (UINT32)pByte[0] << 24;
52 value |= (UINT32)pByte[1] << 16;
53 value |= (UINT32)pByte[2] << 8;
54 value |= (UINT32)pByte[3];
56 return value;
60 // entry point
61 int main(int argc, char* argv[])
63 FILE* pInFile;
64 FILE* pOutFile;
65 UINT8 aHeader[6];
66 UINT8 aImage[256*1024];
67 UINT32 i;
68 UINT32 uiSize, uiStart;
69 UINT16 usChecksum = 0;
71 if (argc < 2)
73 printf("Extract the software image out of an original Archos Flash ROM dump.\n");
74 printf("Result is a scrambled file, use the descramble tool to get the binary,\n");
75 printf(" always without the -fm option, even if processing an FM software.\n\n");
76 printf("Usage: extract <flash dump file> <output file>\n");
77 printf("Example: extract internal_rom_2000000-203FFFF.bin archos.ajz\n");
78 exit(0);
81 pInFile = fopen(argv[1], "rb");
82 if (pInFile == NULL)
84 printf("Error opening input file %s\n", argv[1]);
85 exit(1);
88 if (fread(aImage, 1, sizeof(aImage), pInFile) != sizeof(aImage))
90 printf("Error reading input file %s, must be 256kB in size.\n", argv[1]);
91 fclose(pInFile);
92 exit(2);
94 fclose(pInFile);
96 // find out about the type
97 uiStart = Read32(aImage + 8);
98 uiSize = Read32(aImage + 12); // booted ROM image
99 if (uiStart == 0x02000100 && uiSize > 20000)
100 { // Player has no loader, starts directly with the image
101 uiStart = 0x0100;
103 else
104 { // Recorder / FM / V2 Recorder
105 uiStart = IMAGE_START;
106 uiSize = Read32(aImage + IMAGE_HEADER + 4); // size record of header
109 // sanity check
110 if (uiSize > sizeof(aImage) - uiStart || uiSize < 40000)
112 printf("Error: Impossible image size &d bytes.\n", uiSize);
113 exit(3);
116 // generate checksum
117 for (i=0; i<uiSize; i++)
119 UINT8 byte;
120 byte = aImage[uiStart + i];
121 byte = ~((byte >> 1) | ((byte << 7) & 0x80)); /* poor man's ROR */
122 usChecksum += byte;
125 // make header
126 Write32(aHeader + 2, usChecksum); // checksum in 5th and 6th byte
127 Write32(aHeader, uiSize); // size in first 4 bytes
129 pOutFile = fopen(argv[2], "wb");
130 if (pOutFile == NULL)
132 printf("Error opening output file %s\n", argv[2]);
133 exit(4);
136 if (fwrite(aHeader, 1, sizeof(aHeader), pOutFile) != sizeof(aHeader)
137 || fwrite(aImage + uiStart, 1, uiSize, pOutFile) != uiSize)
139 printf("Write error\n");
140 fclose(pOutFile);
141 exit(5);
144 fclose(pOutFile);
146 return 0;