Copyright update for 2011
[bcusdk.git] / bcugen / lib / addrtab.cpp
blobac8d4d597de888fce875ff30cb5e4a04bace6082
1 /*
2 BCU SDK bcu development enviroment
3 Copyright (C) 2005-2011 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 "addrtab.h"
22 int
23 GroupObjectFlag (GroupObject & o, BCUType b)
25 int flag;
26 if (o.ObjAddress () == 0)
28 if (b == BCU_bcu12)
29 return 0x80;
30 else
31 return 0x00;
33 switch (o.Priority)
35 case PRIO_SYSTEM:
36 flag = 0;
37 break;
38 case PRIO_URGENT:
39 flag = 1;
40 break;
41 case PRIO_NORMAL:
42 flag = 2;
43 break;
44 default:
45 flag = 3;
47 flag |= 4;
48 if (o.ReadAddress ())
49 flag |= 8;
50 if (o.ReceiveAddress ())
51 flag |= 0x10;
52 if (o.eeprom)
53 flag |= 0x20;
54 if (o.SendAddress_lineno || o.ReadRequestAddress_lineno)
55 flag |= 0x40;
56 if (o.UpdateAddress () || b == BCU_bcu12)
57 flag |= 0x80;
58 return flag;
61 static int
62 hasAddress (Array < eibgaddr_t > &a, eibgaddr_t addr)
64 int i;
65 for (i = 0; i < a (); i++)
66 if (a[i] == addr)
67 return 1;
68 return 0;
71 static int
72 addAddress (Array < eibgaddr_t > &a, eibgaddr_t addr)
74 if (hasAddress (a, addr))
75 return 0;
76 a.resize (a () + 1);
77 a[a () - 1] = addr;
78 return 1;
81 void
82 BuildObjAddress (GroupObject & o, BCUType b)
84 int i, j;
85 int first = 1;
86 o.ObjAddress.resize (0);
87 for (i = 0; i < o.ReceiveAddress (); i++)
89 if (o.ReceiveAddress[i] < 0 || o.ReceiveAddress[i] > 0xffff)
90 die (_("line %d: invalid group address %X"), o.lineno,
91 o.ReceiveAddress[i]);
92 if (addAddress (o.ObjAddress, o.ReceiveAddress[i]))
93 if (!first)
94 warn (_
95 ("line %d: unsupported combination of group addresses, merging them"),
96 o.lineno);
98 if (o.ObjAddress ())
99 first = 0;
100 for (i = 0; i < o.ReadAddress (); i++)
102 if (o.ReadAddress[i] < 0 || o.ReadAddress[i] > 0xffff)
103 die (_("line %d: invalid group address %X"), o.lineno,
104 o.ReadAddress[i]);
105 if (addAddress (o.ObjAddress, o.ReadAddress[i]))
106 if (!first)
107 warn (_
108 ("line %d: unsupported combination of group addresses, merging them"),
109 o.lineno);
111 if (o.ObjAddress ())
112 first = 0;
113 if (o.UpdateAddress () && b == BCU_bcu12)
114 die (_("line %d: UpdateAddress not supported"), o.lineno);
115 for (i = 0; i < o.UpdateAddress (); i++)
117 if (o.UpdateAddress[i] < 0 || o.UpdateAddress[i] > 0xffff)
118 die (_("line %d: invalid group address %X"), o.lineno,
119 o.UpdateAddress[i]);
120 if (addAddress (o.ObjAddress, o.UpdateAddress[i]))
121 if (!first)
122 warn (_
123 ("line %d: unsupported combination of group addresses, merging them"),
124 o.lineno);
126 if (o.ObjAddress ())
127 first = 0;
128 if (o.SendAddress_lineno)
130 if (o.SendAddress < 0 || o.SendAddress > 0xffff)
131 die (_("line %d: invalid group address %X"), o.lineno, o.SendAddress);
132 if (addAddress (o.ObjAddress, o.SendAddress))
133 if (!first)
134 warn (_
135 ("line %d: unsupported combination of group addresses, merging them"),
136 o.lineno);
138 if (o.ObjAddress ())
139 first = 0;
140 if (o.ReadRequestAddress_lineno)
142 if (o.ReadRequestAddress < 0 || o.ReadRequestAddress > 0xffff)
143 die (_("line %d: invalid group address %X"), o.lineno,
144 o.ReadRequestAddress);
145 if (addAddress (o.ObjAddress, o.ReadRequestAddress))
146 if (!first)
147 warn (_
148 ("line %d: unsupported combination of group addresses, merging them"),
149 o.lineno);
151 if (o.ReadRequestAddress_lineno && o.SendAddress_lineno)
152 if (o.ReadRequestAddress != o.SendAddress)
153 warn (_("line %d: different outgoing addresses, only one is used"),
154 o.lineno);
157 void
158 BuildObjNo (GroupObject & o, int &objno)
160 if (o.ObjAddress ())
161 o.ObjNo = objno++;
162 else
163 o.ObjNo = -1;
166 static int
167 AddrNo (Array < eibgaddr_t > a, eibgaddr_t ga)
169 int i;
170 for (i = 0; i < a (); i++)
171 if (a[i] == ga)
172 return i;
173 die (_("internal error"));
176 void
177 BuildAddrTable (AddrTable & t, Device & d)
179 Array < bool > used;
180 int maxs = 0;
181 int i, j, fn;
182 t.addr.resize (0);
183 for (i = 0; i < d.GroupObjects (); i++)
184 for (j = 0; j < d.GroupObjects[i].ObjAddress (); j++)
185 addAddress (t.addr, d.GroupObjects[i].ObjAddress[j]);
186 t.addr.sort ();
188 for (i = 0; i < d.GroupObjects (); i++)
189 maxs += d.GroupObjects[i].ObjAddress ();
190 used.resize (maxs);
191 t.ObjNo.resize (maxs);
192 t.Addr.resize (maxs);
193 for (i = 0; i < maxs; i++)
194 used[i] = 0;
195 for (i = 0; i < d.GroupObjects (); i++)
196 if (d.GroupObjects[i].SendAddress_lineno)
198 used[i] = 1;
199 t.ObjNo[i] = d.GroupObjects[i].ObjNo;
200 t.Addr[i] = AddrNo (t.addr, d.GroupObjects[i].SendAddress);
202 else if (d.GroupObjects[i].ReadRequestAddress_lineno)
204 used[i] = 1;
205 t.ObjNo[i] = d.GroupObjects[i].ObjNo;
206 t.Addr[i] = AddrNo (t.addr, d.GroupObjects[i].ReadRequestAddress);
208 fn = 0;
209 while (fn < maxs && used[fn])
210 fn++;
211 for (i = 0; i < d.GroupObjects (); i++)
212 for (j = 0; j < d.GroupObjects[i].ObjAddress (); j++)
213 if ((!d.GroupObjects[i].SendAddress_lineno &&
214 (!d.GroupObjects[i].ReadRequestAddress_lineno ||
215 d.GroupObjects[i].ReadRequestAddress !=
216 d.GroupObjects[i].ObjAddress[j]))
217 || (d.GroupObjects[i].SendAddress_lineno
218 && d.GroupObjects[i].SendAddress !=
219 d.GroupObjects[i].ObjAddress[j]))
221 used[fn] = 1;
222 t.ObjNo[fn] = d.GroupObjects[i].ObjNo;
223 t.Addr[fn] = AddrNo (t.addr, d.GroupObjects[i].ObjAddress[j]);
224 fn++;
225 while (fn < maxs && used[fn])
226 fn++;
230 void
231 printAddrTab (FILE * f, Device & d)
233 int objno = 0, i;
234 int maxs = 0;
235 AddrTable t;
236 for (i = 0; i < d.GroupObjects (); i++)
237 BuildObjAddress (d.GroupObjects[i], d.BCU);
238 for (i = 0; i < d.GroupObjects (); i++)
239 BuildObjNo (d.GroupObjects[i], objno);
241 BuildAddrTable (t, d);
242 maxs = t.addr ();
244 fprintf (f, "\t.section .addrtab\n");
245 fprintf (f, "addrtab:\n");
246 fprintf (f, "\t.byte %d\n", t.addr () + 1);
247 fprintf (f, "\t.hword 0x%04X # physical address\n", d.PhysicalAddress);
248 for (i = 0; i < t.addr (); i++)
249 fprintf (f, "\t.hword 0x%04X\n", t.addr[i]);
250 if (d.BCU != BCU_bcu12)
251 fprintf (f, "\t.byte 0 #Checksum\n");
252 fprintf (f, "addrtab_end:\n");
253 fprintf (f, "\t.section .assoctab\n");
254 fprintf (f, "assoctab:\n");
255 fprintf (f, "\t.byte %d\n", maxs);
256 for (i = 0; i < maxs; i++)
257 fprintf (f, "\t.byte %d, %d\n", t.Addr[i] + 1, t.ObjNo[i]);
258 if (d.BCU != BCU_bcu12)
259 fprintf (f, "\t.byte 0 #Checksum\n");
260 fprintf (f, "assoctab_end:\n");
261 d.ObjCount = objno;
262 if (d.ObjCount > 85)
263 die (_("to many communication objectes"));
266 void
267 printPseudoAddrTab (FILE * f, Device & d)
269 int i;
270 if (!d.Test_Addr_Count_lineno)
272 d.Test_Addr_Count = d.GroupObjects ();
274 if (d.Test_Addr_Count < 0 || d.Test_Addr_Count > 0x7e)
275 die (_("invalid value %d for Test_Addr_Count"), d.Test_Addr_Count);
276 if (d.Test_Assoc_Count < 0 || d.Test_Assoc_Count > 0xff)
277 die (_("invalid value %d for Test_Assoc_Count"), d.Test_Assoc_Count);
278 if (!d.Test_Assoc_Count_lineno)
280 d.Test_Assoc_Count = d.GroupObjects ();
282 fprintf (f, "\t.section .addrtab\n");
283 fprintf (f, "addrtab:\n");
284 fprintf (f, "\t.byte %d\n", d.Test_Addr_Count + 1);
285 fprintf (f, "\t.hword 0x0000 # physical address\n");
286 for (i = 0; i < d.Test_Addr_Count; i++)
287 fprintf (f, "\t.hword 0x0000\n");
288 if (d.BCU != BCU_bcu12)
289 fprintf (f, "\t.byte 0 #Checksum\n");
290 fprintf (f, "addrtab_end:\n");
292 fprintf (f, "\t.section .assoctab\n");
293 fprintf (f, "assoctab:\n");
294 fprintf (f, "\t.byte %d\n", d.Test_Assoc_Count);
295 for (i = 0; i < d.Test_Assoc_Count; i++)
296 fprintf (f, "\t.byte 0, 0\n");
297 if (d.BCU != BCU_bcu12)
298 fprintf (f, "\t.byte 0 #Checksum\n");
299 fprintf (f, "assoctab_end:\n");
301 for (i = 0; i < d.GroupObjects (); i++)
302 d.GroupObjects[i].ObjNo = i;
303 d.ObjCount = d.GroupObjects ();
304 if (d.ObjCount > 85)
305 die (_("to many communication objectes"));