comparison vmcmd.c @ 0:3ddf0eaece51 src

Initial revision
author richwareham
date Tue, 12 Mar 2002 19:45:53 +0000
parents
children 6f0fb88d1463
comparison
equal deleted inserted replaced
-1:000000000000 0:3ddf0eaece51
1 /*
2 * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort
3 *
4 * This file is part of libdvdnav, a DVD navigation library. It is modified
5 * from a file originally part of the Ogle DVD player.
6 *
7 * libdvdnav is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * libdvdnav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 *
21 * $Id$
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <inttypes.h>
32
33 #include "vmcmd.h"
34
35
36 /* freebsd compatibility */
37 #ifndef PRIu8
38 #define PRIu8 "d"
39 #endif
40
41 /* freebsd compatibility */
42 #ifndef PRIu16
43 #define PRIu16 "d"
44 #endif
45
46
47 typedef struct
48 {
49 uint8_t bits[8];
50 uint8_t examined[8];
51 } cmd_t;
52
53 /* Fix this.. pass as parameters instead. */
54 static cmd_t cmd;
55
56 static const char *cmp_op_table[] = {
57 NULL, "&", "==", "!=", ">=", ">", "<=", "<"
58 };
59 static const char *set_op_table[] = {
60 NULL, "=", "<->", "+=", "-=", "*=", "/=", "%=", "rnd", "&=", "|=", "^="
61 };
62
63 static const char *link_table[] = {
64 "LinkNoLink", "LinkTopC", "LinkNextC", "LinkPrevC",
65 NULL, "LinkTopPG", "LinkNextPG", "LinkPrevPG",
66 NULL, "LinkTopPGC", "LinkNextPGC", "LinkPrevPGC",
67 "LinkGoUpPGC", "LinkTailPGC", NULL, NULL,
68 "RSM"
69 };
70
71 static const char *system_reg_table[] = {
72 "Menu Description Language Code",
73 "Audio Stream Number",
74 "Sub-picture Stream Number",
75 "Angle Number",
76 "Title Track Number",
77 "VTS Title Track Number",
78 "VTS PGC Number",
79 "PTT Number for One_Sequential_PGC_Title",
80 "Highlighted Button Number",
81 "Navigation Timer",
82 "Title PGC Number for Navigation Timer",
83 "Audio Mixing Mode for Karaoke",
84 "Country Code for Parental Management",
85 "Parental Level",
86 "Player Configurations for Video",
87 "Player Configurations for Audio",
88 "Initial Language Code for Audio",
89 "Initial Language Code Extension for Audio",
90 "Initial Language Code for Sub-picture",
91 "Initial Language Code Extension for Sub-picture",
92 "Player Regional Code",
93 "Reserved 21",
94 "Reserved 22",
95 "Reserved 23"
96 };
97
98 static const char *system_reg_abbr_table[] = {
99 NULL,
100 "ASTN",
101 "SPSTN",
102 "AGLN",
103 "TTN",
104 "VTS_TTN",
105 "TT_PGCN",
106 "PTTN",
107 "HL_BTNN",
108 "NVTMR",
109 "NV_PGCN",
110 NULL,
111 "CC_PLT",
112 "PLT",
113 NULL,
114 NULL,
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 NULL,
121 NULL,
122 NULL,
123 };
124
125
126
127 static uint32_t bits(int byte, int bit, int count) {
128 uint32_t val = 0;
129 int bit_mask;
130
131 while(count--) {
132 if(bit > 7) {
133 bit = 0;
134 byte++;
135 }
136 bit_mask = 0x01 << (7-bit);
137 val <<= 1;
138 if((cmd.bits[byte]) & bit_mask)
139 val |= 1;
140 cmd.examined[byte] |= bit_mask;
141 bit++;
142 }
143 return val;
144 }
145
146
147 static void print_system_reg(uint16_t reg) {
148 if(reg < sizeof(system_reg_abbr_table) / sizeof(char *))
149 fprintf(stderr, system_reg_table[reg]);
150 else
151 fprintf(stderr, " WARNING: Unknown system register ");
152 }
153
154 static void print_reg(uint8_t reg) {
155 if(reg & 0x80)
156 print_system_reg(reg & 0x7f);
157 else
158 if(reg < 16)
159 fprintf(stderr, "g[%" PRIu8 "]", reg);
160 else
161 fprintf(stderr, " WARNING: Unknown general register ");
162 }
163
164 static void print_cmp_op(uint8_t op) {
165 if(op < sizeof(cmp_op_table) / sizeof(char *) && cmp_op_table[op] != NULL)
166 fprintf(stderr, " %s ", cmp_op_table[op]);
167 else
168 fprintf(stderr, " WARNING: Unknown compare op ");
169 }
170
171 static void print_set_op(uint8_t op) {
172 if(op < sizeof(set_op_table) / sizeof(char *) && set_op_table[op] != NULL)
173 fprintf(stderr, " %s ", set_op_table[op]);
174 else
175 fprintf(stderr, " WARNING: Unknown set op ");
176 }
177
178 static void print_reg_or_data(int immediate, int byte) {
179 if(immediate) {
180 int i = bits(byte,0,16);
181
182 fprintf(stderr, "0x%x", i);
183 if(isprint(i & 0xff) && isprint((i>>8) & 0xff))
184 fprintf(stderr, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff));
185 } else {
186 print_reg(bits(byte + 1,0,8));
187 }
188 }
189
190 static void print_reg_or_data_2(int immediate, int byte) {
191 if(immediate)
192 fprintf(stderr, "0x%x", bits(byte,1,7));
193 else
194 fprintf(stderr, "g[%" PRIu8 "]", bits(byte,4,4));
195 }
196
197 static void print_if_version_1(void) {
198 uint8_t op = bits(1,1,3);
199
200 if(op) {
201 fprintf(stderr, "if (");
202 print_reg(bits(3,0,8));
203 print_cmp_op(op);
204 print_reg_or_data(bits(1,0,1), 4);
205 fprintf(stderr, ") ");
206 }
207 }
208
209 static void print_if_version_2(void) {
210 uint8_t op = bits(1,1,3);
211
212 if(op) {
213 fprintf(stderr, "if (");
214 print_reg(bits(6,0,8));
215 print_cmp_op(op);
216 print_reg(bits(7,0,8));
217 fprintf(stderr, ") ");
218 }
219 }
220
221 static void print_if_version_3(void) {
222 uint8_t op = bits(1,1,3);
223
224 if(op) {
225 fprintf(stderr, "if (");
226 print_reg(bits(2,4,4));
227 print_cmp_op(op);
228 print_reg_or_data(bits(1,0,1), 6);
229 fprintf(stderr, ") ");
230 }
231 }
232
233 static void print_if_version_4(void) {
234 uint8_t op = bits(1,1,3);
235
236 if(op) {
237 fprintf(stderr, "if (");
238 print_reg(bits(1,4,4));
239 print_cmp_op(op);
240 print_reg_or_data(bits(1,0,1), 4);
241 fprintf(stderr, ") ");
242 }
243 }
244
245 static void print_special_instruction(void) {
246 uint8_t op = bits(1,4,4);
247
248 switch(op) {
249 case 0: /* NOP */
250 fprintf(stderr, "Nop");
251 break;
252 case 1: /* Goto line */
253 fprintf(stderr, "Goto %" PRIu8, bits(7,0,8));
254 break;
255 case 2: /* Break */
256 fprintf(stderr, "Break");
257 break;
258 case 3: /* Parental level */
259 fprintf(stderr, "SetTmpPML %" PRIu8 ", Goto %" PRIu8,
260 bits(6,4,4), bits(7,0,8));
261 break;
262 default:
263 fprintf(stderr, "WARNING: Unknown special instruction (%i)",
264 bits(1,4,4));
265 }
266 }
267
268 static void print_linksub_instruction(void) {
269 int linkop = bits(7,3,5);
270 int button = bits(6,0,6);
271
272 if(linkop < sizeof(link_table)/sizeof(char *) && link_table[linkop] != NULL)
273 fprintf(stderr, "%s (button %" PRIu8 ")", link_table[linkop], button);
274 else
275 fprintf(stderr, "WARNING: Unknown linksub instruction (%i)", linkop);
276 }
277
278 static void print_link_instruction(int optional) {
279 uint8_t op = bits(1,4,4);
280
281 if(optional && op)
282 fprintf(stderr, ", ");
283
284 switch(op) {
285 case 0:
286 if(!optional)
287 fprintf(stderr, "WARNING: NOP (link)!");
288 break;
289 case 1:
290 print_linksub_instruction();
291 break;
292 case 4:
293 fprintf(stderr, "LinkPGCN %" PRIu16, bits(6,1,15));
294 break;
295 case 5:
296 fprintf(stderr, "LinkPTT %" PRIu16 " (button %" PRIu8 ")",
297 bits(6,6,10), bits(6,0,6));
298 break;
299 case 6:
300 fprintf(stderr, "LinkPGN %" PRIu8 " (button %" PRIu8 ")",
301 bits(7,1,7), bits(6,0,6));
302 break;
303 case 7:
304 fprintf(stderr, "LinkCN %" PRIu8 " (button %" PRIu8 ")",
305 bits(7,0,8), bits(6,0,6));
306 break;
307 default:
308 fprintf(stderr, "WARNING: Unknown link instruction");
309 }
310 }
311
312 static void print_jump_instruction(void) {
313 switch(bits(1,4,4)) {
314 case 1:
315 fprintf(stderr, "Exit");
316 break;
317 case 2:
318 fprintf(stderr, "JumpTT %" PRIu8, bits(5,1,7));
319 break;
320 case 3:
321 fprintf(stderr, "JumpVTS_TT %" PRIu8, bits(5,1,7));
322 break;
323 case 5:
324 fprintf(stderr, "JumpVTS_PTT %" PRIu8 ":%" PRIu16,
325 bits(5,1,7), bits(2,6,10));
326 break;
327 case 6:
328 switch(bits(5,0,2)) {
329 case 0:
330 fprintf(stderr, "JumpSS FP");
331 break;
332 case 1:
333 fprintf(stderr, "JumpSS VMGM (menu %" PRIu8 ")", bits(5,4,4));
334 break;
335 case 2:
336 fprintf(stderr, "JumpSS VTSM (vts %" PRIu8 ", title %" PRIu8
337 ", menu %" PRIu8 ")", bits(4,0,8), bits(3,0,8), bits(5,4,4));
338 break;
339 case 3:
340 fprintf(stderr, "JumpSS VMGM (pgc %" PRIu8 ")", bits(2,1,15));
341 break;
342 }
343 break;
344 case 8:
345 switch(bits(5,0,2)) {
346 case 0:
347 fprintf(stderr, "CallSS FP (rsm_cell %" PRIu8 ")",
348 bits(4,0,8));
349 break;
350 case 1:
351 fprintf(stderr, "CallSS VMGM (menu %" PRIu8
352 ", rsm_cell %" PRIu8 ")", bits(5,4,4), bits(4,0,8));
353 break;
354 case 2:
355 fprintf(stderr, "CallSS VTSM (menu %" PRIu8
356 ", rsm_cell %" PRIu8 ")", bits(5,4,4), bits(4,0,8));
357 break;
358 case 3:
359 fprintf(stderr, "CallSS VMGM (pgc %" PRIu8 ", rsm_cell %" PRIu8 ")",
360 bits(2,1,15), bits(4,0,8));
361 break;
362 }
363 break;
364 default:
365 fprintf(stderr, "WARNING: Unknown Jump/Call instruction");
366 }
367 }
368
369 static void print_system_set(void) {
370 int i;
371
372 switch(bits(0,4,4)) {
373 case 1: /* Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */
374 for(i = 1; i <= 3; i++) {
375 if(bits(2+i,0,1)) {
376 print_system_reg(i);
377 fprintf(stderr, " = ");
378 print_reg_or_data_2(bits(0,3,1), 2 + i);
379 fprintf(stderr, " ");
380 }
381 }
382 break;
383 case 2: /* Set system reg 9 & 10 (Navigation timer, Title PGC number) */
384 print_system_reg(9);
385 fprintf(stderr, " = ");
386 print_reg_or_data(bits(0,3,1), 2);
387 fprintf(stderr, " ");
388 print_system_reg(10);
389 fprintf(stderr, " = %" PRIu8, bits(5,0,8)); /* ?? */
390 break;
391 case 3: /* Mode: Counter / Register + Set */
392 fprintf(stderr, "SetMode ");
393 if(bits(5,0,1))
394 fprintf(stderr, "Counter ");
395 else
396 fprintf(stderr, "Register ");
397 print_reg(bits(5,4,4));
398 print_set_op(0x1); /* '=' */
399 print_reg_or_data(bits(0,3,1), 2);
400 break;
401 case 6: /* Set system reg 8 (Highlighted button) */
402 print_system_reg(8);
403 if(bits(0,3,1)) /* immediate */
404 fprintf(stderr, " = 0x%x (button no %d)", bits(4,0,16), bits(4,0,6));
405 else
406 fprintf(stderr, " = g[%" PRIu8 "]", bits(5,4,4));
407 break;
408 default:
409 fprintf(stderr, "WARNING: Unknown system set instruction (%i)",
410 bits(0,4,4));
411 }
412 }
413
414 static void print_set_version_1(void) {
415 uint8_t set_op = bits(0,4,4);
416
417 if(set_op) {
418 print_reg(bits(3,0,8));
419 print_set_op(set_op);
420 print_reg_or_data(bits(0,3,1), 4);
421 } else {
422 fprintf(stderr, "NOP");
423 }
424 }
425
426 static void print_set_version_2(void) {
427 uint8_t set_op = bits(0,4,4);
428
429 if(set_op) {
430 print_reg(bits(1,4,4));
431 print_set_op(set_op);
432 print_reg_or_data(bits(0,3,1), 2);
433 } else {
434 fprintf(stderr, "NOP");
435 }
436 }
437
438 void vmPrint_mnemonic(vm_cmd_t *command) {
439 int i, extra_bits;
440
441 for(i = 0; i < 8; i++) {
442 cmd.bits[i] = command->bytes[i];
443 cmd.examined[i] = 0;
444 }
445
446 switch(bits(0,0,3)) { /* three first bits */
447 case 0: /* Special instructions */
448 print_if_version_1();
449 print_special_instruction();
450 break;
451 case 1: /* Jump/Call or Link instructions */
452 if(bits(0,3,1)) {
453 print_if_version_2();
454 print_jump_instruction();
455 } else {
456 print_if_version_1();
457 print_link_instruction(0); /* must be pressent */
458 }
459 break;
460 case 2: /* Set System Parameters instructions */
461 print_if_version_2();
462 print_system_set();
463 print_link_instruction(1); /* either 'if' or 'link' */
464 break;
465 case 3: /* Set General Parameters instructions */
466 print_if_version_3();
467 print_set_version_1();
468 print_link_instruction(1); /* either 'if' or 'link' */
469 break;
470 case 4: /* Set, Compare -> LinkSub instructions */
471 print_set_version_2();
472 fprintf(stderr, ", ");
473 print_if_version_4();
474 print_linksub_instruction();
475 break;
476 case 5: /* Compare -> (Set and LinkSub) instructions */
477 print_if_version_4();
478 fprintf(stderr, "{ ");
479 print_set_version_2();
480 fprintf(stderr, ", ");
481 print_linksub_instruction();
482 fprintf(stderr, " }");
483 break;
484 case 6: /* Compare -> Set, always LinkSub instructions */
485 print_if_version_4();
486 fprintf(stderr, "{ ");
487 print_set_version_2();
488 fprintf(stderr, " } ");
489 print_linksub_instruction();
490 break;
491 default:
492 fprintf(stderr, "WARNING: Unknown instruction type (%i)", bits(0,0,3));
493 }
494 /* Check if there still are bits set that were not examined */
495
496 extra_bits = 0;
497 for(i = 0; i < 8; i++)
498 if(cmd.bits[i] & ~ cmd.examined[i]) {
499 extra_bits = 1;
500 break;
501 }
502 if(extra_bits) {
503 fprintf(stderr, " [WARNING, unknown bits:");
504 for(i = 0; i < 8; i++)
505 fprintf(stderr, " %02x", cmd.bits[i] & ~ cmd.examined[i]);
506 fprintf(stderr, "]");
507 }
508 }
509
510 void vmPrint_CMD(int row, vm_cmd_t *command) {
511 int i;
512
513 fprintf(stderr, "(%03d) ", row + 1);
514 for(i = 0; i < 8; i++)
515 fprintf(stderr, "%02x ", command->bytes[i]);
516 fprintf(stderr, "| ");
517
518 vmPrint_mnemonic(command);
519 fprintf(stderr, "\n");
520 }