Mercurial > mplayer.hg
changeset 24048:fe3043a8552c
1000l: Forgot to add new files, *sigh*.
author | diego |
---|---|
date | Wed, 15 Aug 2007 11:48:23 +0000 |
parents | de28f9e8cb00 |
children | 39b8ccb91251 |
files | dvdread/cmd_print.c dvdread/cmd_print.h |
diffstat | 2 files changed, 601 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dvdread/cmd_print.c Wed Aug 15 11:48:23 2007 +0000 @@ -0,0 +1,550 @@ +/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2000, 2001, 2002, 2003 Martin Norbäck, Håkan Hjort + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include <stdio.h> +#include <ctype.h> + +#if defined(HAVE_INTTYPES_H) +#include <inttypes.h> +#elif defined(HAVE_STDINT_H) +#include <stdint.h> +#endif + +#include "cmd_print.h" + + +typedef struct +{ + uint8_t bits[8]; + uint8_t examined[8]; +} cmd_t; + + +static const char *cmp_op_table[] = { + NULL, "&", "==", "!=", ">=", ">", "<=", "<" +}; +static const char *set_op_table[] = { + NULL, "=", "<->", "+=", "-=", "*=", "/=", "%=", "rnd", "&=", "|=", "^=" +}; + +static const char *link_table[] = { + "LinkNoLink", "LinkTopC", "LinkNextC", "LinkPrevC", + NULL, "LinkTopPG", "LinkNextPG", "LinkPrevPG", + NULL, "LinkTopPGC", "LinkNextPGC", "LinkPrevPGC", + "LinkGoUpPGC", "LinkTailPGC", NULL, NULL, + "RSM" +}; + +static const char *system_reg_table[] = { + "Menu Description Language Code", + "Audio Stream Number", + "Sub-picture Stream Number", + "Angle Number", + "Title Track Number", + "VTS Title Track Number", + "VTS PGC Number", + "PTT Number for One_Sequential_PGC_Title", + "Highlighted Button Number", + "Navigation Timer", + "Title PGC Number for Navigation Timer", + "Audio Mixing Mode for Karaoke", + "Country Code for Parental Management", + "Parental Level", + "Player Configurations for Video", + "Player Configurations for Audio", + "Initial Language Code for Audio", + "Initial Language Code Extension for Audio", + "Initial Language Code for Sub-picture", + "Initial Language Code Extension for Sub-picture", + "Player Regional Code", + "Reserved 21", + "Reserved 22", + "Reserved 23" +}; + +static const char *system_reg_abbr_table[] = { + NULL, + "ASTN", + "SPSTN", + "AGLN", + "TTN", + "VTS_TTN", + "TT_PGCN", + "PTTN", + "HL_BTNN", + "NVTMR", + "NV_PGCN", + NULL, + "CC_PLT", + "PLT", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + + + +static unsigned int bits(cmd_t *cmd, int byte, int bit, int count) { + unsigned int val = 0; + unsigned int bit_mask; + + while(count--) { + if(bit > 7) { + bit = 0; + byte++; + } + bit_mask = 0x01 << (7-bit); + val <<= 1; + if((cmd->bits[byte]) & bit_mask) + val |= 1; + cmd->examined[byte] |= bit_mask; + bit++; + } + return val; +} + + +static void print_system_reg(unsigned int reg) { + if(reg < sizeof(system_reg_abbr_table) / sizeof(char *)) + fprintf(stdout, system_reg_table[reg]); + else + fprintf(stdout, " WARNING: Unknown system register "); +} + +static void print_reg(unsigned int reg) { + if(reg & 0x80) + print_system_reg(reg & 0x7f); + else + if(reg < 16) + fprintf(stdout, "g[%u]", reg); + else + fprintf(stdout, " WARNING: Unknown general register "); +} + +static void print_cmp_op(unsigned int op) { + if(op < sizeof(cmp_op_table) / sizeof(char *) && cmp_op_table[op] != NULL) + fprintf(stdout, " %s ", cmp_op_table[op]); + else + fprintf(stdout, " WARNING: Unknown compare op "); +} + +static void print_set_op(unsigned int op) { + if(op < sizeof(set_op_table) / sizeof(char *) && set_op_table[op] != NULL) + fprintf(stdout, " %s ", set_op_table[op]); + else + fprintf(stdout, " WARNING: Unknown set op "); +} + +static void print_reg_or_data(cmd_t *cmd, unsigned int immediate, int byte) { + if(immediate) { + int i = bits(cmd,byte,0,16); + + fprintf(stdout, "0x%x", i); + if(isprint(i & 0xff) && isprint((i>>8) & 0xff)) + fprintf(stdout, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff)); + } else { + print_reg(bits(cmd,byte + 1,0,8)); + } +} + +static void print_reg_or_data_2(cmd_t *cmd, unsigned int immediate, int byte) { + if(immediate) + fprintf(stdout, "0x%x", bits(cmd,byte,1,7)); + else + fprintf(stdout, "g[%u]", bits(cmd,byte,4,4)); +} + +static void print_if_version_1(cmd_t *cmd) { + unsigned int op = bits(cmd,1,1,3); + + if(op) { + fprintf(stdout, "if ("); + print_reg(bits(cmd,3,0,8)); + print_cmp_op(op); + print_reg_or_data(cmd,bits(cmd,1,0,1), 4); + fprintf(stdout, ") "); + } +} + +static void print_if_version_2(cmd_t *cmd) { + unsigned int op = bits(cmd,1,1,3); + + if(op) { + fprintf(stdout, "if ("); + print_reg(bits(cmd,6,0,8)); + print_cmp_op(op); + print_reg(bits(cmd,7,0,8)); + fprintf(stdout, ") "); + } +} + +static void print_if_version_3(cmd_t *cmd) { + unsigned int op = bits(cmd,1,1,3); + + if(op) { + fprintf(stdout, "if ("); + print_reg(bits(cmd,2,0,8)); + print_cmp_op(op); + print_reg_or_data(cmd,bits(cmd,1,0,1), 6); + fprintf(stdout, ") "); + } +} + +static void print_if_version_4(cmd_t *cmd) { + unsigned int op = bits(cmd,1,1,3); + + if(op) { + fprintf(stdout, "if ("); + print_reg(bits(cmd,1,4,4)); + print_cmp_op(op); + print_reg_or_data(cmd,bits(cmd,1,0,1), 4); + fprintf(stdout, ") "); + } +} + +static void print_if_version_5(cmd_t *cmd) { + unsigned int op = bits(cmd,1,1,3); + + if(op) { + fprintf(stdout, "if ("); + print_reg(bits(cmd,4,0,8)); + print_cmp_op(op); + print_reg(bits(cmd,5,0,8)); + fprintf(stdout, ") "); + } +} + +static void print_special_instruction(cmd_t *cmd) { + unsigned int op = bits(cmd,1,4,4); + + switch(op) { + case 0: // NOP + fprintf(stdout, "Nop"); + break; + case 1: // Goto line + fprintf(stdout, "Goto %u", bits(cmd,7,0,8)); + break; + case 2: // Break + fprintf(stdout, "Break"); + break; + case 3: // Parental level + fprintf(stdout, "SetTmpPML %u, Goto %u", + bits(cmd,6,4,4), bits(cmd,7,0,8)); + break; + default: + fprintf(stdout, "WARNING: Unknown special instruction (%u)", + bits(cmd,1,4,4)); + } +} + +static void print_linksub_instruction(cmd_t *cmd) { + unsigned int linkop = bits(cmd,7,3,5); + unsigned int button = bits(cmd,6,0,6); + + if(linkop < sizeof(link_table)/sizeof(char *) && link_table[linkop] != NULL) + fprintf(stdout, "%s (button %u)", link_table[linkop], button); + else + fprintf(stdout, "WARNING: Unknown linksub instruction (%u)", linkop); +} + +static void print_link_instruction(cmd_t *cmd, int optional) { + unsigned int op = bits(cmd,1,4,4); + + if(optional && op) + fprintf(stdout, ", "); + + switch(op) { + case 0: + if(!optional) + fprintf(stdout, "WARNING: NOP (link)!"); + break; + case 1: + print_linksub_instruction(cmd); + break; + case 4: + fprintf(stdout, "LinkPGCN %u", bits(cmd,6,1,15)); + break; + case 5: + fprintf(stdout, "LinkPTT %u (button %u)", + bits(cmd,6,6,10), bits(cmd,6,0,6)); + break; + case 6: + fprintf(stdout, "LinkPGN %u (button %u)", + bits(cmd,7,1,7), bits(cmd,6,0,6)); + break; + case 7: + fprintf(stdout, "LinkCN %u (button %u)", + bits(cmd,7,0,8), bits(cmd,6,0,6)); + break; + default: + fprintf(stdout, "WARNING: Unknown link instruction"); + } +} + +static void print_jump_instruction(cmd_t *cmd) { + switch(bits(cmd,1,4,4)) { + case 1: + fprintf(stdout, "Exit"); + break; + case 2: + fprintf(stdout, "JumpTT %u", bits(cmd,5,1,7)); + break; + case 3: + fprintf(stdout, "JumpVTS_TT %u", bits(cmd,5,1,7)); + break; + case 5: + fprintf(stdout, "JumpVTS_PTT %u:%u", bits(cmd,5,1,7), bits(cmd,2,6,10)); + break; + case 6: + switch(bits(cmd,5,0,2)) { + case 0: + fprintf(stdout, "JumpSS FP"); + break; + case 1: + fprintf(stdout, "JumpSS VMGM (menu %u)", bits(cmd,5,4,4)); + break; + case 2: + fprintf(stdout, "JumpSS VTSM (vts %u, title %u, menu %u)", + bits(cmd,4,0,8), bits(cmd,3,0,8), bits(cmd,5,4,4)); + break; + case 3: + fprintf(stdout, "JumpSS VMGM (pgc %u)", bits(cmd,2,1,15)); + break; + } + break; + case 8: + switch(bits(cmd,5,0,2)) { + case 0: + fprintf(stdout, "CallSS FP (rsm_cell %u)", + bits(cmd,4,0,8)); + break; + case 1: + fprintf(stdout, "CallSS VMGM (menu %u, rsm_cell %u)", + bits(cmd,5,4,4), bits(cmd,4,0,8)); + break; + case 2: + fprintf(stdout, "CallSS VTSM (menu %u, rsm_cell %u)", + bits(cmd,5,4,4), bits(cmd,4,0,8)); + break; + case 3: + fprintf(stdout, "CallSS VMGM (pgc %u, rsm_cell %u)", + bits(cmd,2,1,15), bits(cmd,4,0,8)); + break; + } + break; + default: + fprintf(stdout, "WARNING: Unknown Jump/Call instruction"); + } +} + +static void print_system_set(cmd_t *cmd) { + int i; + + switch(bits(cmd,0,4,4)) { + case 1: // Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) + for(i = 1; i <= 3; i++) { + if(bits(cmd,2+i,0,1)) { + print_system_reg((unsigned int)i); + fprintf(stdout, " = "); + print_reg_or_data_2(cmd,bits(cmd,0,3,1), 2 + i); + fprintf(stdout, " "); + } + } + break; + case 2: // Set system reg 9 & 10 (Navigation timer, Title PGC number) + print_system_reg(9); + fprintf(stdout, " = "); + print_reg_or_data(cmd,bits(cmd,0,3,1), 2); + fprintf(stdout, " "); + print_system_reg(10); + fprintf(stdout, " = %u", bits(cmd,5,0,8)); // ?? + break; + case 3: // Mode: Counter / Register + Set + fprintf(stdout, "SetMode "); + if(bits(cmd,5,0,1)) + fprintf(stdout, "Counter "); + else + fprintf(stdout, "Register "); + print_reg(bits(cmd,5,4,4)); + print_set_op(0x1); // '=' + print_reg_or_data(cmd,bits(cmd,0,3,1), 2); + break; + case 6: // Set system reg 8 (Highlighted button) + print_system_reg(8); + if(bits(cmd,0,3,1)) // immediate + fprintf(stdout, " = 0x%x (button no %u)", + bits(cmd,4,0,16), bits(cmd,4,0,6)); + else + fprintf(stdout, " = g[%u]", bits(cmd,5,4,4)); + break; + default: + fprintf(stdout, "WARNING: Unknown system set instruction (%u)", + bits(cmd,0,4,4)); + } +} + +static void print_set_version_1(cmd_t *cmd) { + unsigned int set_op = bits(cmd,0,4,4); + + if(set_op) { + print_reg(bits(cmd,3,0,8)); + print_set_op(set_op); + print_reg_or_data(cmd,bits(cmd,0,3,1), 4); + } else { + fprintf(stdout, "NOP"); + } +} + +static void print_set_version_2(cmd_t *cmd) { + unsigned int set_op = bits(cmd,0,4,4); + + if(set_op) { + print_reg(bits(cmd,1,4,4)); + print_set_op(set_op); + print_reg_or_data(cmd,bits(cmd,0,3,1), 2); + } else { + fprintf(stdout, "NOP"); + } +} + +static void print_set_version_3(cmd_t *cmd) { + unsigned int set_op = bits(cmd,0,4,4); + + if(set_op) { + print_reg(bits(cmd,1,4,4)); + print_set_op(set_op); + if(bits(cmd,0,3,1)) { // print_reg_or_data + unsigned int i = bits(cmd,2,0,16); + + fprintf(stdout, "0x%x", i); + if(isprint(i & 0xff) && isprint((i>>8) & 0xff)) + fprintf(stdout, " (\"%c%c\")", + (char)((i>>8) & 0xff), (char)(i & 0xff)); + } else { + print_reg(bits(cmd,2,0,8)); + } + } else { + fprintf(stdout, "NOP"); + } +} + +static void print_command(cmd_t *cmd) { + switch(bits(cmd,0,0,3)) { /* three first bits */ + case 0: // Special instructions + print_if_version_1(cmd); + print_special_instruction(cmd); + break; + case 1: // Jump/Call or Link instructions + if(bits(cmd,0,3,1)) { + print_if_version_2(cmd); + print_jump_instruction(cmd); + } else { + print_if_version_1(cmd); + print_link_instruction(cmd,0); // must be pressent + } + break; + case 2: // Set System Parameters instructions + print_if_version_2(cmd); + print_system_set(cmd); + print_link_instruction(cmd,1); // either 'if' or 'link' + break; + case 3: // Set General Parameters instructions + print_if_version_3(cmd); + print_set_version_1(cmd); + print_link_instruction(cmd,1); // either 'if' or 'link' + break; + case 4: // Set, Compare -> LinkSub instructions + print_set_version_2(cmd); + fprintf(stdout, ", "); + print_if_version_4(cmd); + print_linksub_instruction(cmd); + break; + case 5: // Compare -> (Set and LinkSub) instructions + if(bits(cmd,0,3,1)) + print_if_version_5(cmd); + else + print_if_version_1(cmd); + fprintf(stdout, "{ "); + print_set_version_3(cmd); + fprintf(stdout, ", "); + print_linksub_instruction(cmd); + fprintf(stdout, " }"); + break; + case 6: // Compare -> Set, always LinkSub instructions + if(bits(cmd,0,3,1)) + print_if_version_5(cmd); + else + print_if_version_1(cmd); + fprintf(stdout, "{ "); + print_set_version_3(cmd); + fprintf(stdout, " } "); + print_linksub_instruction(cmd); + break; + default: + fprintf(stdout, "WARNING: Unknown instruction type (%i)", + bits(cmd,0,0,3)); + } +} + +void cmdPrint_mnemonic(vm_cmd_t *command) { + int i, extra_bits; + cmd_t cmd; + + for(i = 0; i < 8; i++) { + cmd.bits[i] = command->bytes[i]; + cmd.examined[i] = 0; + } + + print_command(&cmd); + + // Check if there still are bits set that were not examined + extra_bits = 0; + for(i = 0; i < 8; i++) + if(cmd.bits[i] & ~ cmd.examined[i]) { + extra_bits = 1; + break; + } + if(extra_bits) { + fprintf(stdout, " [WARNING, unknown bits:"); + for(i = 0; i < 8; i++) + fprintf(stdout, " %02x", cmd.bits[i] & ~ cmd.examined[i]); + fprintf(stdout, "]"); + } +} + +void cmdPrint_CMD(int row, vm_cmd_t *command) { + int i; + + fprintf(stdout, "(%03d) ", row + 1); + for(i = 0; i < 8; i++) + fprintf(stdout, "%02x ", command->bytes[i]); + fprintf(stdout, "| "); + + cmdPrint_mnemonic(command); + fprintf(stdout, "\n"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dvdread/cmd_print.h Wed Aug 15 11:48:23 2007 +0000 @@ -0,0 +1,51 @@ +/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */ +#ifndef CMD_PRINT_H_INCLUDED +#define CMD_PRINT_H_INCLUDED + +/* + * Copyright (C) 2000, 2001, 2002, 2003 Martin Norbäck, Håkan Hjort + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <dvdread/ifo_types.h> + +/** + * Pretty printing of the DVD commands (vm instructions). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Prints a text representation of the commands to stdout. + * + * @param command Pointer to the DVD command to be printed. + */ +void cmdPrint_mnemonic(vm_cmd_t *command); + +/** + * Prints row, then a hex dump of the command followed by the text + * representation of the commands, as given by cmdPrint_mnemonic to + * stdout. + * + * @param command Pointer to the DVD command to be printed. */ +void cmdPrint_CMD(int row, vm_cmd_t *command); + +#ifdef __cplusplus +}; +#endif +#endif /* CMD_PRINT_H_INCLUDED */