Add new USB IDs
[bcusdk.git] / bcugen / imageedit.cpp
blobce100509553297a9fa734d40496adc49566b573d
1 /*
2 BCU SDK bcu development enviroment
3 Copyright (C) 2005-2010 Martin Koegler <mkoegler@auto.tuwien.ac.at>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "image.h"
21 #include "common.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "loadimage.h"
25 #include "classes.h"
26 #include "xmlreadconfig.h"
27 #include "addrtab.h"
29 void
30 ToTargetFloat (uchar v[4], float f)
32 memcpy (v, &f, 4); /* TODO: conversation */
35 void
36 ImageToDevice (Image & i, Device & d)
38 int j;
39 for (j = 0; j < i.str (); j++)
41 switch (i.str[j]->getType ())
43 case S_StringParameter:
45 StringParameter p;
46 STR_StringParameter *l = ((STR_StringParameter *) i.str[j]);
47 p.ID = l->name;
48 p.ID_lineno = 1;
49 d.StringParameters.add (p);
51 break;
52 case S_IntParameter:
54 IntParameter p;
55 STR_IntParameter *l = ((STR_IntParameter *) i.str[j]);
56 p.ID = l->name;
57 p.ID_lineno = 1;
58 d.IntParameters.add (p);
60 break;
61 case S_FloatParameter:
63 FloatParameter p;
64 STR_FloatParameter *l = ((STR_FloatParameter *) i.str[j]);
65 p.ID = l->name;
66 p.ID_lineno = 1;
67 d.FloatParameters.add (p);
69 break;
70 case S_ListParameter:
72 ListParameter p;
73 STR_ListParameter *l = ((STR_ListParameter *) i.str[j]);
74 p.ID = l->name;
75 p.ID_lineno = 1;
76 for (int k = 0; k < l->elements (); k++)
78 Map m;
79 m.Value = l->elements[k];
80 p.Elements.add (m);
82 d.ListParameters.add (p);
84 break;
85 case S_GroupObject:
87 GroupObject p;
88 STR_GroupObject *l = ((STR_GroupObject *) i.str[j]);
89 p.ID = l->name;
90 p.ID_lineno = 1;
91 p.ObjNo = l->no;
92 d.GroupObjects.add (p);
94 break;
95 case S_BCUType:
96 d.BCU = (BCUType) ((STR_BCUType *) i.str[j])->bcutype;
97 break;
102 void
103 PatchImage (Image & i, Device & d)
105 int j, k;
106 STR_Code *co = (STR_Code *) i.findStream (S_Code);
107 uchar *c = (uchar *) co->code.array ();
108 for (j = 0; j < i.str (); j++)
110 switch (i.str[j]->getType ())
112 case S_StringParameter:
114 STR_StringParameter *l = ((STR_StringParameter *) i.str[j]);
115 for (k = 0; k < d.StringParameters (); k++)
116 if (d.StringParameters[k].ID == l->name)
117 break;
118 const StringParameter & p = d.StringParameters[k];
119 if (!p.Value_lineno)
120 die (_("missing parameter value for %s"), p.ID ());
121 if (strlen (p.Value ()) + 1 > l->length)
122 die (_("string value for %s too long"), p.ID ());
123 strcpy ((char *) c + l->addr - 0x100, p.Value ());
125 break;
126 case S_IntParameter:
128 STR_IntParameter *l = ((STR_IntParameter *) i.str[j]);
129 for (k = 0; k < d.IntParameters (); k++)
130 if (d.IntParameters[k].ID == l->name)
131 break;
132 const IntParameter & p = d.IntParameters[k];
133 if (!p.Value_lineno)
134 die (_("missing parameter value for %s"), p.ID ());
135 switch (l->type)
137 case 1:
138 case -1:
139 c[l->addr - 0x100] = p.Value & 0xff;
140 break;
141 case 2:
142 case -2:
143 c[l->addr + 0 - 0x100] = (p.Value >> 8) & 0xff;
144 c[l->addr + 1 - 0x100] = p.Value & 0xff;
145 break;
146 case 3:
147 case -3:
148 c[l->addr + 0 - 0x100] = (p.Value >> 24) & 0xff;
149 c[l->addr + 1 - 0x100] = (p.Value >> 16) & 0xff;
150 c[l->addr + 2 - 0x100] = (p.Value >> 8) & 0xff;
151 c[l->addr + 3 - 0x100] = p.Value & 0xff;
152 break;
153 case 4:
154 case -4:
155 c[l->addr + 0 - 0x100] = (p.Value >> 56) & 0xff;
156 c[l->addr + 1 - 0x100] = (p.Value >> 48) & 0xff;
157 c[l->addr + 2 - 0x100] = (p.Value >> 40) & 0xff;
158 c[l->addr + 3 - 0x100] = (p.Value >> 32) & 0xff;
159 c[l->addr + 4 - 0x100] = (p.Value >> 24) & 0xff;
160 c[l->addr + 5 - 0x100] = (p.Value >> 16) & 0xff;
161 c[l->addr + 6 - 0x100] = (p.Value >> 8) & 0xff;
162 c[l->addr + 7 - 0x100] = p.Value & 0xff;
163 break;
164 default:
165 die (_("unknown type %d for parameter %s"), l->type, p.ID ());
168 break;
169 case S_FloatParameter:
171 STR_FloatParameter *l = ((STR_FloatParameter *) i.str[j]);
172 for (k = 0; k < d.FloatParameters (); k++)
173 if (d.FloatParameters[k].ID == l->name)
174 break;
175 const FloatParameter & p = d.FloatParameters[k];
176 if (!p.Value_lineno)
177 die (_("missing parameter value for %s"), p.ID ());
178 float f = p.Value;
179 uchar v[4];
180 ToTargetFloat (v, f);
181 memcpy (c + l->addr - 0x100, v, 4);
183 break;
184 case S_ListParameter:
186 STR_ListParameter *l = ((STR_ListParameter *) i.str[j]);
187 for (k = 0; k < d.ListParameters (); k++)
188 if (d.ListParameters[k].ID == l->name)
189 break;
190 const ListParameter & p = d.ListParameters[k];
191 if (!p.Value_lineno)
192 die (_("missing parameter value for %s"), p.ID ());
193 int i;
194 for (i = 0; i < l->elements (); i++)
195 if (l->elements[i] == p.Value)
196 break;
197 if (i == l->elements ())
198 die (_("unknown element %s for parameter %s"), p.Value (),
199 p.ID ());
200 if (i < 0x100)
202 c[l->addr - 0x100] = i & 0xff;
204 else
206 c[l->addr + 0 - 0x100] = (i >> 8) & 0xff;
207 c[l->addr + 1 - 0x100] = i & 0xff;
210 break;
213 /*Addresstable */
214 int addrtab_start;
215 int assoctab_start;
216 int groupobj_start;
217 if (d.BCU == BCU_bcu12)
219 addrtab_start = 0x16;
220 assoctab_start = c[0x11];
221 groupobj_start = c[0x12];
223 else
225 STR_BCU2Start *s = (STR_BCU2Start *) i.findStream (S_BCU2Start);
226 addrtab_start = s->addrtab_start - 0x100;
227 assoctab_start = s->assoctab_start - 0x100;
228 groupobj_start = s->groupobj_ptr - 0x100;
231 AddrTable t;
232 int i;
233 int maxs = 0;
234 for (i = 0; i < d.GroupObjects (); i++)
235 BuildObjAddress (d.GroupObjects[i], d.BCU);
237 BuildAddrTable (t, d);
239 maxs = t.Addr ();
241 if (t.addr () + 1 > c[addrtab_start])
242 die (_("need %d addresses, only space for %d addresses"), t.addr () + 1,
243 c[addrtab_start]);
244 c[addrtab_start] = t.addr () + 1;
245 c[addrtab_start + 1] = (d.PhysicalAddress >> 8) & 0xff;
246 c[addrtab_start + 2] = (d.PhysicalAddress) & 0xff;
247 for (i = 0; i < t.addr (); i++)
249 c[addrtab_start + i * 2 + 3] = (t.addr[i] >> 8) & 0xff;
250 c[addrtab_start + i * 2 + 4] = (t.addr[i]) & 0xff;
252 if (maxs > c[addrtab_start])
253 die (_("need %d associations, only space for %d assocations"), maxs,
254 c[assoctab_start]);
255 c[assoctab_start] = maxs;
256 for (i = 0; i < maxs; i++)
258 c[assoctab_start + i * 2 + 1] = t.Addr[i] + 1;
259 c[assoctab_start + i * 2 + 2] = t.ObjNo[i];
261 for (i = 0; i < d.GroupObjects (); i++)
263 uchar f = GroupObjectFlag (d.GroupObjects[i], d.BCU);
264 c[groupobj_start + 2 + 3 * d.GroupObjects[i].ObjNo + 1] = f;
267 /*Key handling */
269 STR_BCU2Key *k = (STR_BCU2Key *) i.findStream (S_BCU2Key);
270 if (!k)
272 k = new STR_BCU2Key;
273 i.str.add (k);
275 if (d.InstallKey_lineno)
276 k->installkey = d.InstallKey;
277 k->keys.resize (3);
278 int i;
279 for (i = 0; i < 3; i++)
280 k->keys[i] = 0xffffffff;
281 for (i = 0; i < d.Keys (); i++)
283 if (d.Keys[i].level < 0 || d.Keys[i].level > 2)
284 die (_("unsupported key level %d"), d.Keys[i].level);
285 k->keys[d.Keys[i].level] = d.Keys[i].key;
291 main (int ac, char *ag[])
293 CArray p;
294 uchar buf[200];
295 int dump = 0;
296 Device d;
298 if (ac != 4)
299 die (_("%s image config output"), ag[0]);
301 FILE *f = fopen (ag[1], "r");
302 if (!f)
303 die (_("open of %s failed"), ag[1]);
305 while (!feof (f))
307 int i = fread (buf, 1, sizeof (buf), f);
308 p.setpart (buf, p (), i);
310 fclose (f);
312 if (dump)
313 printf ("%s", HexDump (p) ());
315 Image *i = Image::fromArray (p);
316 if (!i)
317 die (_("not a image"));
319 if (!i->isValid ())
320 die (_("not a valid image\n"));
322 printf ("%s\n", i->decode ()());
324 BCUImage *im;
326 BCU_LOAD_RESULT r = PrepareLoadImage (p, im);
327 if (r != IMG_IMAGE_LOADABLE)
328 die (_("%s"), decodeBCULoadResult (r) ());
330 ImageToDevice (*i, d);
332 xmlReadConfigInformation (d, ag[2]);
334 PatchImage (*i, d);
336 printf ("%s\n", i->decode ()());
338 f = fopen (ag[3], "w");
339 if (!f)
340 die (_("can not write to %s"), ag[3]);
341 p = i->toArray ();
342 if (dump)
343 printf ("%s", HexDump (p) ());
344 fwrite (p.array (), 1, p (), f);
345 fclose (f);