1#[derive(Debug, Clone, PartialEq)]
4pub struct DeviceField {
5 pub name: String,
6 pub size: u8,
7}
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct Device {
11 pub address: u16,
12 pub name: String,
13 pub fields: Vec<DeviceField>,
14}
15
16impl Device {
17 pub fn extend_fields(&mut self, other: Vec<DeviceField>) {
19 self.fields.extend(other);
20 }
21 pub fn get_field_address(&self, field_name: &str) -> Option<u16> {
23 let mut offset = 0u16;
24 for field in &self.fields {
25 if field.name == field_name {
26 return Some(self.address + offset);
27 }
28 offset += field.size as u16;
29 }
30 None
31 }
32}
33
34pub fn parse_device_map_line(line: &str) -> Option<Device> {
37 let mut tokens = line.split_whitespace();
38 let addr_token = tokens.next()?;
39 if !addr_token.starts_with('|') {
40 return None;
41 }
42 let address = u16::from_str_radix(&addr_token[1..], 16).ok()?;
43 let name_token = tokens.next()?;
44 let name = if let Some(stripped) = name_token.strip_prefix('@') {
45 stripped.to_string()
46 } else {
47 return None;
48 };
49 let mut fields = Vec::new();
50 while let Some(field_token) = tokens.next() {
51 if let Some(stripped) = field_token.strip_prefix('&') {
52 let field_name = stripped.to_string();
53 if let Some(size_token) = tokens.next() {
54 if let Some(stripped) = size_token.strip_prefix('$') {
55 if let Ok(size) = u8::from_str_radix(stripped, 16) {
56 fields.push(DeviceField {
57 name: field_name,
58 size,
59 });
60 }
61 }
62 }
63 }
64 }
65 Some(Device {
66 address,
67 name,
68 fields,
69 })
70}
71
72pub fn parse_device_maps(source: &str) -> Vec<Device> {
74 source.lines().filter_map(parse_device_map_line).collect()
75}
76
77use once_cell::sync::Lazy;
78
79pub static DEVICES_DEFAULT: Lazy<Vec<Device>> = Lazy::new(|| {
80 vec![
81 Device {
82 address: 0x00,
83 name: "System".into(),
84 fields: vec![
85 DeviceField {
86 name: "vector".into(),
87 size: 2,
88 },
89 DeviceField {
90 name: "wst".into(),
91 size: 1,
92 },
93 DeviceField {
94 name: "rst".into(),
95 size: 1,
96 },
97 DeviceField {
98 name: "eaddr".into(),
99 size: 2,
100 },
101 DeviceField {
102 name: "ecode".into(),
103 size: 1,
104 },
105 DeviceField {
106 name: "pad".into(),
107 size: 1,
108 },
109 DeviceField {
110 name: "r".into(),
111 size: 2,
112 },
113 DeviceField {
114 name: "g".into(),
115 size: 2,
116 },
117 DeviceField {
118 name: "b".into(),
119 size: 2,
120 },
121 DeviceField {
122 name: "debug".into(),
123 size: 1,
124 },
125 DeviceField {
126 name: "halt".into(),
127 size: 1,
128 },
129 DeviceField {
130 name: "state".into(),
131 size: 1,
132 },
133 ],
134 },
135 Device {
136 address: 0x10,
137 name: "Console".into(),
138 fields: vec![
139 DeviceField {
140 name: "vector".into(),
141 size: 2,
142 },
143 DeviceField {
144 name: "read".into(),
145 size: 1,
146 },
147 DeviceField {
148 name: "pad".into(),
149 size: 5,
150 },
151 DeviceField {
152 name: "write".into(),
153 size: 1,
154 },
155 DeviceField {
156 name: "error".into(),
157 size: 1,
158 },
159 ],
160 },
161 Device {
162 address: 0x20,
163 name: "Screen".into(),
164 fields: vec![
165 DeviceField {
166 name: "vector".into(),
167 size: 2,
168 },
169 DeviceField {
170 name: "width".into(),
171 size: 2,
172 },
173 DeviceField {
174 name: "height".into(),
175 size: 2,
176 },
177 DeviceField {
178 name: "auto".into(),
179 size: 1,
180 },
181 DeviceField {
182 name: "pad".into(),
183 size: 1,
184 },
185 DeviceField {
186 name: "x".into(),
187 size: 2,
188 },
189 DeviceField {
190 name: "y".into(),
191 size: 2,
192 },
193 DeviceField {
194 name: "addr".into(),
195 size: 2,
196 },
197 DeviceField {
198 name: "pixel".into(),
199 size: 1,
200 },
201 DeviceField {
202 name: "sprite".into(),
203 size: 1,
204 },
205 ],
206 },
207 Device {
208 address: 0x30,
209 name: "Audio0".into(),
210 fields: vec![
211 DeviceField {
212 name: "vector".into(),
213 size: 2,
214 },
215 DeviceField {
216 name: "position".into(),
217 size: 2,
218 },
219 DeviceField {
220 name: "output".into(),
221 size: 1,
222 },
223 DeviceField {
224 name: "pad".into(),
225 size: 3,
226 },
227 DeviceField {
228 name: "adsr".into(),
229 size: 2,
230 },
231 DeviceField {
232 name: "length".into(),
233 size: 2,
234 },
235 DeviceField {
236 name: "addr".into(),
237 size: 2,
238 },
239 DeviceField {
240 name: "volume".into(),
241 size: 1,
242 },
243 DeviceField {
244 name: "pitch".into(),
245 size: 1,
246 },
247 ],
248 },
249 Device {
250 address: 0x40,
251 name: "Audio1".into(),
252 fields: vec![
253 DeviceField {
254 name: "vector".into(),
255 size: 2,
256 },
257 DeviceField {
258 name: "position".into(),
259 size: 2,
260 },
261 DeviceField {
262 name: "output".into(),
263 size: 1,
264 },
265 DeviceField {
266 name: "pad".into(),
267 size: 3,
268 },
269 DeviceField {
270 name: "adsr".into(),
271 size: 2,
272 },
273 DeviceField {
274 name: "length".into(),
275 size: 2,
276 },
277 DeviceField {
278 name: "addr".into(),
279 size: 2,
280 },
281 DeviceField {
282 name: "volume".into(),
283 size: 1,
284 },
285 DeviceField {
286 name: "pitch".into(),
287 size: 1,
288 },
289 ],
290 },
291 Device {
292 address: 0x50,
293 name: "Audio2".into(),
294 fields: vec![
295 DeviceField {
296 name: "vector".into(),
297 size: 2,
298 },
299 DeviceField {
300 name: "position".into(),
301 size: 2,
302 },
303 DeviceField {
304 name: "output".into(),
305 size: 1,
306 },
307 DeviceField {
308 name: "pad".into(),
309 size: 3,
310 },
311 DeviceField {
312 name: "adsr".into(),
313 size: 2,
314 },
315 DeviceField {
316 name: "length".into(),
317 size: 2,
318 },
319 DeviceField {
320 name: "addr".into(),
321 size: 2,
322 },
323 DeviceField {
324 name: "volume".into(),
325 size: 1,
326 },
327 DeviceField {
328 name: "pitch".into(),
329 size: 1,
330 },
331 ],
332 },
333 Device {
334 address: 0x60,
335 name: "Audio3".into(),
336 fields: vec![
337 DeviceField {
338 name: "vector".into(),
339 size: 2,
340 },
341 DeviceField {
342 name: "position".into(),
343 size: 2,
344 },
345 DeviceField {
346 name: "output".into(),
347 size: 1,
348 },
349 DeviceField {
350 name: "pad".into(),
351 size: 3,
352 },
353 DeviceField {
354 name: "adsr".into(),
355 size: 2,
356 },
357 DeviceField {
358 name: "length".into(),
359 size: 2,
360 },
361 DeviceField {
362 name: "addr".into(),
363 size: 2,
364 },
365 DeviceField {
366 name: "volume".into(),
367 size: 1,
368 },
369 DeviceField {
370 name: "pitch".into(),
371 size: 1,
372 },
373 ],
374 },
375 Device {
376 address: 0x80,
377 name: "Controller".into(),
378 fields: vec![
379 DeviceField {
380 name: "vector".into(),
381 size: 2,
382 },
383 DeviceField {
384 name: "button".into(),
385 size: 1,
386 },
387 DeviceField {
388 name: "key".into(),
389 size: 1,
390 },
391 DeviceField {
392 name: "func".into(),
393 size: 1,
394 },
395 ],
396 },
397 Device {
398 address: 0x90,
399 name: "Mouse".into(),
400 fields: vec![
401 DeviceField {
402 name: "vector".into(),
403 size: 2,
404 },
405 DeviceField {
406 name: "x".into(),
407 size: 2,
408 },
409 DeviceField {
410 name: "y".into(),
411 size: 2,
412 },
413 DeviceField {
414 name: "state".into(),
415 size: 1,
416 },
417 DeviceField {
418 name: "pad".into(),
419 size: 3,
420 },
421 DeviceField {
422 name: "scrollx".into(),
423 size: 2,
424 },
425 DeviceField {
426 name: "scrolly".into(),
427 size: 2,
428 },
429 ],
430 },
431 Device {
432 address: 0xa0,
433 name: "File".into(),
434 fields: vec![
435 DeviceField {
436 name: "vector".into(),
437 size: 2,
438 },
439 DeviceField {
440 name: "success".into(),
441 size: 2,
442 },
443 DeviceField {
444 name: "stat".into(),
445 size: 2,
446 },
447 DeviceField {
448 name: "delete".into(),
449 size: 1,
450 },
451 DeviceField {
452 name: "append".into(),
453 size: 1,
454 },
455 DeviceField {
456 name: "name".into(),
457 size: 2,
458 },
459 DeviceField {
460 name: "length".into(),
461 size: 2,
462 },
463 DeviceField {
464 name: "read".into(),
465 size: 2,
466 },
467 DeviceField {
468 name: "write".into(),
469 size: 2,
470 },
471 ],
472 },
473 Device {
474 address: 0xb0,
475 name: "File1".into(),
476 fields: vec![
477 DeviceField {
478 name: "vector".into(),
479 size: 2,
480 },
481 DeviceField {
482 name: "success".into(),
483 size: 2,
484 },
485 DeviceField {
486 name: "stat".into(),
487 size: 2,
488 },
489 DeviceField {
490 name: "delete".into(),
491 size: 1,
492 },
493 DeviceField {
494 name: "append".into(),
495 size: 1,
496 },
497 DeviceField {
498 name: "name".into(),
499 size: 2,
500 },
501 DeviceField {
502 name: "length".into(),
503 size: 2,
504 },
505 DeviceField {
506 name: "read".into(),
507 size: 2,
508 },
509 DeviceField {
510 name: "write".into(),
511 size: 2,
512 },
513 ],
514 },
515 Device {
516 address: 0xc0,
517 name: "DateTime".into(),
518 fields: vec![
519 DeviceField {
520 name: "year".into(),
521 size: 2,
522 },
523 DeviceField {
524 name: "month".into(),
525 size: 1,
526 },
527 DeviceField {
528 name: "day".into(),
529 size: 1,
530 },
531 DeviceField {
532 name: "hour".into(),
533 size: 1,
534 },
535 DeviceField {
536 name: "minute".into(),
537 size: 1,
538 },
539 DeviceField {
540 name: "second".into(),
541 size: 1,
542 },
543 DeviceField {
544 name: "dotw".into(),
545 size: 1,
546 },
547 DeviceField {
548 name: "doty".into(),
549 size: 2,
550 },
551 DeviceField {
552 name: "isdst".into(),
553 size: 1,
554 },
555 ],
556 },
557 ]
558});