comparison dvdread/cmd_print.c @ 24048:fe3043a8552c

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