Blame src/libbluray/hdmv/mobj_print.c

Packit 5e46da
/*
Packit 5e46da
 * This file is part of libbluray
Packit 5e46da
 * Copyright (C) 2009-2017  Petri Hintukainen <phintuka@users.sourceforge.net>
Packit 5e46da
 *
Packit 5e46da
 * This library is free software; you can redistribute it and/or
Packit 5e46da
 * modify it under the terms of the GNU Lesser General Public
Packit 5e46da
 * License as published by the Free Software Foundation; either
Packit 5e46da
 * version 2.1 of the License, or (at your option) any later version.
Packit 5e46da
 *
Packit 5e46da
 * This library is distributed in the hope that it will be useful,
Packit 5e46da
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5e46da
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 5e46da
 * Lesser General Public License for more details.
Packit 5e46da
 *
Packit 5e46da
 * You should have received a copy of the GNU Lesser General Public
Packit 5e46da
 * License along with this library. If not, see
Packit 5e46da
 * <http://www.gnu.org/licenses/>.
Packit 5e46da
 */
Packit 5e46da
Packit 5e46da
#if HAVE_CONFIG_H
Packit 5e46da
#include "config.h"
Packit 5e46da
#endif
Packit 5e46da
Packit 5e46da
#include "mobj_print.h"
Packit 5e46da
Packit 5e46da
#include "mobj_data.h"
Packit 5e46da
#include "hdmv_insn.h"
Packit 5e46da
Packit 5e46da
#include <stdio.h>
Packit 5e46da
Packit 5e46da
static const char * const psr_info[128] = {
Packit 5e46da
    "/*     PSR0:  Interactive graphics stream number */",
Packit 5e46da
    "/*     PSR1:  Primary audio stream number */",
Packit 5e46da
    "/*     PSR2:  PG TextST stream number and PiP PG stream number */",
Packit 5e46da
    "/*     PSR3:  Angle number */",
Packit 5e46da
    "/*     PSR4:  Title number */",
Packit 5e46da
    "/*     PSR5:  Chapter number */",
Packit 5e46da
    "/*     PSR6:  PlayList ID */",
Packit 5e46da
    "/*     PSR7:  PlayItem ID */",
Packit 5e46da
    "/*     PSR8:  Presentation time */",
Packit 5e46da
    "/*     PSR9:  Navigation timer */",
Packit 5e46da
    "/*     PSR10: Selected button ID */",
Packit 5e46da
    "/*     PSR11: Page ID */",
Packit 5e46da
    "/*     PSR12: User style number */",
Packit 5e46da
    "/* RO: PSR13: User age */",
Packit 5e46da
    "/*     PSR14: Secondary audio stream number and secondary video stream number */",
Packit 5e46da
    "/* RO: PSR15: player capability for audio */",
Packit 5e46da
    "/* RO: PSR16: Language code for audio */",
Packit 5e46da
    "/* RO: PSR17: Language code for PG and Text subtitles */",
Packit 5e46da
    "/* RO: PSR18: Menu description language code */",
Packit 5e46da
    "/* RO: PSR19: Country code */",
Packit 5e46da
    "/* RO: PSR20: Region code */ /* 1 - A, 2 - B, 4 - C */",
Packit 5e46da
    "/* RO: PSR21: Output Mode Preference */ /* 0 - 2D, 1 - 3D */",
Packit 5e46da
    "/*     PSR22: Stereoscopic status */ /* 2D / 3D */ ",
Packit 5e46da
    "/* RO: PSR23: display capablity */",
Packit 5e46da
    "/* RO: PSR24: 3D capability */",
Packit 5e46da
    "/* RO: PSR25: UHD capability */",
Packit 5e46da
    "/* RO: PSR26: UHD display capability */",
Packit 5e46da
    "/* RO: PSR27: HDR preference */",
Packit 5e46da
    "/* RO: PSR28: SDR conversion preference */",
Packit 5e46da
    "/* RO: PSR29: player capability for video */",
Packit 5e46da
    "/* RO: PSR30: player capability for text subtitle */",
Packit 5e46da
    "/* RO: PSR31: Player profile and version */",
Packit 5e46da
    "/*     PSR32 */",
Packit 5e46da
    "/*     PSR33 */",
Packit 5e46da
    "/*     PSR34 */",
Packit 5e46da
    "/*     PSR35 */",
Packit 5e46da
    "/*     PSR36: backup PSR4 */",
Packit 5e46da
    "/*     PSR37: backup PSR5 */",
Packit 5e46da
    "/*     PSR38: backup PSR6 */",
Packit 5e46da
    "/*     PSR39: backup PSR7 */",
Packit 5e46da
    "/*     PSR40: backup PSR8 */",
Packit 5e46da
    "/*     PSR41: */",
Packit 5e46da
    "/*     PSR42: backup PSR10 */",
Packit 5e46da
    "/*     PSR43: backup PSR11 */",
Packit 5e46da
    "/*     PSR44: backup PSR12 */",
Packit 5e46da
    "/*     PSR45: */",
Packit 5e46da
    "/*     PSR46: */",
Packit 5e46da
    "/*     PSR47: */",
Packit 5e46da
    "/* RO: PSR48: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR49: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR50: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR51: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR52: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR53: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR54: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR55: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR56: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR57: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR58: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR59: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR60: Characteristic text caps */",
Packit 5e46da
    "/* RO: PSR61: Characteristic text caps */",
Packit 5e46da
    /* PSR62 */ NULL,
Packit 5e46da
    /* PSR63 */ NULL,
Packit 5e46da
    /* PSR64 */ NULL,
Packit 5e46da
    /* PSR65 */ NULL,
Packit 5e46da
    /* PSR66 */ NULL,
Packit 5e46da
    /* PSR67 */ NULL,
Packit 5e46da
    /* PSR68 */ NULL,
Packit 5e46da
    /* PSR69 */ NULL,
Packit 5e46da
    /* PSR70 */ NULL,
Packit 5e46da
    /* PSR71 */ NULL,
Packit 5e46da
    /* PSR72 */ NULL,
Packit 5e46da
    /* PSR73 */ NULL,
Packit 5e46da
    /* PSR74 */ NULL,
Packit 5e46da
    /* PSR75 */ NULL,
Packit 5e46da
    /* PSR76 */ NULL,
Packit 5e46da
    /* PSR77 */ NULL,
Packit 5e46da
    /* PSR78 */ NULL,
Packit 5e46da
    /* PSR79 */ NULL,
Packit 5e46da
    /* PSR80 */ NULL,
Packit 5e46da
    /* PSR81 */ NULL,
Packit 5e46da
    /* PSR82 */ NULL,
Packit 5e46da
    /* PSR83 */ NULL,
Packit 5e46da
    /* PSR84 */ NULL,
Packit 5e46da
    /* PSR85 */ NULL,
Packit 5e46da
    /* PSR86 */ NULL,
Packit 5e46da
    /* PSR87 */ NULL,
Packit 5e46da
    /* PSR88 */ NULL,
Packit 5e46da
    /* PSR89 */ NULL,
Packit 5e46da
    /* PSR90 */ NULL,
Packit 5e46da
    /* PSR91 */ NULL,
Packit 5e46da
    /* PSR92 */ NULL,
Packit 5e46da
    /* PSR93 */ NULL,
Packit 5e46da
    /* PSR94 */ NULL,
Packit 5e46da
    /* PSR95 */ NULL,
Packit 5e46da
    /* PSR96 */ NULL,
Packit 5e46da
    /* PSR97 */ NULL,
Packit 5e46da
    /* PSR98 */ NULL,
Packit 5e46da
    /* PSR99 */ NULL,
Packit 5e46da
    /* PSR100 */ NULL,
Packit 5e46da
    /* PSR101 */ NULL,
Packit 5e46da
    "/*     PSR102: BD+ receive */",
Packit 5e46da
    "/*     PSR103: BD+ send */",
Packit 5e46da
    "/*     PSR104: BD+ shared */",
Packit 5e46da
    /* PSR105 */ NULL,
Packit 5e46da
    /* PSR106 */ NULL,
Packit 5e46da
    /* PSR107 */ NULL,
Packit 5e46da
    /* PSR108 */ NULL,
Packit 5e46da
    /* PSR109 */ NULL,
Packit 5e46da
    /* PSR110 */ NULL,
Packit 5e46da
    /* PSR111 */ NULL,
Packit 5e46da
    /* PSR112 */ NULL,
Packit 5e46da
    /* PSR113 */ NULL,
Packit 5e46da
    /* PSR114 */ NULL,
Packit 5e46da
    /* PSR115 */ NULL,
Packit 5e46da
    /* PSR116 */ NULL,
Packit 5e46da
    /* PSR117 */ NULL,
Packit 5e46da
    /* PSR118 */ NULL,
Packit 5e46da
    /* PSR119 */ NULL,
Packit 5e46da
    /* PSR120 */ NULL,
Packit 5e46da
    /* PSR121 */ NULL,
Packit 5e46da
    /* PSR122 */ NULL,
Packit 5e46da
    /* PSR123 */ NULL,
Packit 5e46da
    /* PSR124 */ NULL,
Packit 5e46da
    /* PSR125 */ NULL,
Packit 5e46da
    /* PSR126 */ NULL,
Packit 5e46da
    /* PSR127 */ NULL,
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
#if 0
Packit 5e46da
static const char * const insn_groups[4] = {
Packit 5e46da
    "BRANCH",
Packit 5e46da
    "COMPARE",
Packit 5e46da
    "SET",
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static const char * const insn_group_branch[8] = {
Packit 5e46da
    "GOTO",
Packit 5e46da
    "JUMP",
Packit 5e46da
    "PLAY",
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static const char * const insn_group_set[8] = {
Packit 5e46da
    "SET",
Packit 5e46da
    "SETSYSTEM",
Packit 5e46da
};
Packit 5e46da
#endif
Packit 5e46da
Packit 5e46da
static const char * const insn_opt_set[32] = {
Packit 5e46da
    NULL,
Packit 5e46da
    "move",
Packit 5e46da
    "swap",
Packit 5e46da
    "add",
Packit 5e46da
    "sub",
Packit 5e46da
    "mul",
Packit 5e46da
    "div",
Packit 5e46da
    "mod",
Packit 5e46da
    "rnd",
Packit 5e46da
    "and",
Packit 5e46da
    "or",
Packit 5e46da
    "xor",
Packit 5e46da
    "bset",
Packit 5e46da
    "bclr",
Packit 5e46da
    "shl",
Packit 5e46da
    "shr",
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static const char * const insn_opt_setsys[32] = {
Packit 5e46da
    NULL,
Packit 5e46da
    "SET_STREAM",
Packit 5e46da
    "SET_NV_TIMER",
Packit 5e46da
    "SET_BUTTON_PAGE",
Packit 5e46da
    "ENABLE_BUTTON",
Packit 5e46da
    "DISABLE_BUTTON",
Packit 5e46da
    "SET_SEC_STREAM",
Packit 5e46da
    "POPUP_OFF",
Packit 5e46da
    "STILL_ON",
Packit 5e46da
    "STILL_OFF",
Packit 5e46da
    "SET_OUTPUT_MODE",
Packit 5e46da
    "SET_STREAM_SS",
Packit 5e46da
    NULL,
Packit 5e46da
    NULL,
Packit 5e46da
    NULL,
Packit 5e46da
    NULL,
Packit 5e46da
    "[SETSYSTEM_0x10]",
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static const char * const insn_opt_cmp[16] = {
Packit 5e46da
    NULL,
Packit 5e46da
    "bc",
Packit 5e46da
    "eq",
Packit 5e46da
    "ne",
Packit 5e46da
    "ge",
Packit 5e46da
    "gt",
Packit 5e46da
    "le",
Packit 5e46da
    "lt",
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static const char * const insn_opt_goto[16] = {
Packit 5e46da
    "nop",
Packit 5e46da
    "goto",
Packit 5e46da
    "break",
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static const char * const insn_opt_jump[16] = {
Packit 5e46da
    "JUMP_OBJECT",
Packit 5e46da
    "JUMP_TITLE",
Packit 5e46da
    "CALL_OBJECT",
Packit 5e46da
    "CALL_TITLE",
Packit 5e46da
    "RESUME"
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static const char * const insn_opt_play[16] = {
Packit 5e46da
    "PLAY_PL",
Packit 5e46da
    "PLAY_PL_PI",
Packit 5e46da
    "PLAY_PL_MK",
Packit 5e46da
    "TERMINATE_PL",
Packit 5e46da
    "LINK_PI",
Packit 5e46da
    "LINK_MK"
Packit 5e46da
};
Packit 5e46da
Packit 5e46da
static int _sprint_operand(char *buf, int imm, uint32_t op, int *psr)
Packit 5e46da
{
Packit 5e46da
    char *start = buf;
Packit 5e46da
Packit 5e46da
    if (!imm) {
Packit 5e46da
        if (op & 0x80000000) {
Packit 5e46da
            buf += sprintf(buf, "PSR%-3u", op & 0x7f);
Packit 5e46da
            *psr = op & 0x7f;
Packit 5e46da
        } else {
Packit 5e46da
            buf += sprintf(buf, "r%-5u", op & 0xfff);
Packit 5e46da
        }
Packit 5e46da
    } else {
Packit 5e46da
        if (op < 99999)
Packit 5e46da
            buf += sprintf(buf, "%-6u", op);
Packit 5e46da
        else
Packit 5e46da
            buf += sprintf(buf, "0x%-4x", op);
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    return buf - start;
Packit 5e46da
}
Packit 5e46da
Packit 5e46da
static int _sprint_operands(char *buf, MOBJ_CMD *cmd)
Packit 5e46da
{
Packit 5e46da
    char      *start = buf;
Packit 5e46da
    HDMV_INSN *insn  = &cmd->insn;
Packit 5e46da
    int psr1 = -1, psr2 = -1;
Packit 5e46da
Packit 5e46da
    if (insn->op_cnt > 0) {
Packit 5e46da
        buf += _sprint_operand(buf, insn->imm_op1, cmd->dst, &psr1);
Packit 5e46da
Packit 5e46da
        if (insn->op_cnt > 1) {
Packit 5e46da
            buf += sprintf(buf, ",\t");
Packit 5e46da
            buf += _sprint_operand(buf, insn->imm_op2, cmd->src, &psr2);
Packit 5e46da
        } else {
Packit 5e46da
            buf += sprintf(buf, " \t      ");
Packit 5e46da
        }
Packit 5e46da
    } else {
Packit 5e46da
        buf += sprintf(buf, "       \t      ");
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    if (psr1 >= 0 && psr1 < 128 && psr_info[psr1])
Packit 5e46da
        buf += sprintf(buf, " %s", psr_info[psr1]);
Packit 5e46da
    if (psr2 >= 0 && psr2 < 128 && psr2 != psr1 && psr_info[psr2])
Packit 5e46da
        buf += sprintf(buf, " %s", psr_info[psr2]);
Packit 5e46da
Packit 5e46da
    return buf - start;
Packit 5e46da
}
Packit 5e46da
Packit 5e46da
static int _sprint_operands_hex(char *buf, MOBJ_CMD *cmd)
Packit 5e46da
{
Packit 5e46da
    char      *start = buf;
Packit 5e46da
    HDMV_INSN *insn  = &cmd->insn;
Packit 5e46da
Packit 5e46da
    if (insn->op_cnt > 0) {
Packit 5e46da
        buf += sprintf(buf, "0x%-4x", cmd->dst);
Packit 5e46da
    }
Packit 5e46da
    if (insn->op_cnt > 1) {
Packit 5e46da
        buf += sprintf(buf,  ",\t0x%-4x", cmd->src);
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    return buf - start;
Packit 5e46da
}
Packit 5e46da
Packit 5e46da
static uint32_t _cmd_to_u32(HDMV_INSN *insn)
Packit 5e46da
{
Packit 5e46da
    union {
Packit 5e46da
        HDMV_INSN insn;
Packit 5e46da
        uint8_t u8[4];
Packit 5e46da
    } tmp;
Packit 5e46da
    tmp.insn = *insn;
Packit 5e46da
    return ((unsigned)tmp.u8[0] << 24) | (tmp.u8[1] << 16) | (tmp.u8[2] << 8) | tmp.u8[3];
Packit 5e46da
}
Packit 5e46da
Packit 5e46da
int mobj_sprint_cmd(char *buf, MOBJ_CMD *cmd)
Packit 5e46da
{
Packit 5e46da
    char *start = buf;
Packit 5e46da
    HDMV_INSN *insn = &cmd->insn;
Packit 5e46da
Packit 5e46da
    buf += sprintf(buf, "%08x %08x,%08x  ", _cmd_to_u32(&cmd->insn), cmd->dst, cmd->src);
Packit 5e46da
Packit 5e46da
    switch(insn->grp) {
Packit 5e46da
        case INSN_GROUP_BRANCH:
Packit 5e46da
            switch(insn->sub_grp) {
Packit 5e46da
                case BRANCH_GOTO:
Packit 5e46da
                    if (insn_opt_goto[insn->branch_opt]) {
Packit 5e46da
                        buf += sprintf(buf, "%-10s ", insn_opt_goto[insn->branch_opt]);
Packit 5e46da
                        buf += _sprint_operands(buf, cmd);
Packit 5e46da
                    } else {
Packit 5e46da
                      buf += sprintf(buf, "[unknown BRANCH/GOTO option in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
                    }
Packit 5e46da
                    break;
Packit 5e46da
            case BRANCH_JUMP:
Packit 5e46da
                if (insn_opt_jump[insn->branch_opt]) {
Packit 5e46da
                    buf += sprintf(buf, "%-10s ", insn_opt_jump[insn->branch_opt]);
Packit 5e46da
                    buf += _sprint_operands(buf, cmd);
Packit 5e46da
                } else {
Packit 5e46da
                    buf += sprintf(buf, "[unknown BRANCH/JUMP option in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
                }
Packit 5e46da
                break;
Packit 5e46da
            case BRANCH_PLAY:
Packit 5e46da
                if (insn_opt_play[insn->branch_opt]) {
Packit 5e46da
                    buf += sprintf(buf, "%-10s ", insn_opt_play[insn->branch_opt]);
Packit 5e46da
                    buf += _sprint_operands(buf, cmd);
Packit 5e46da
                } else {
Packit 5e46da
                    buf += sprintf(buf, "[unknown BRANCH/PLAY option in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
                }
Packit 5e46da
                break;
Packit 5e46da
            default:
Packit 5e46da
                buf += sprintf(buf, "[unknown BRANCH subgroup in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
                break;
Packit 5e46da
            }
Packit 5e46da
            break;
Packit 5e46da
Packit 5e46da
        case INSN_GROUP_CMP:
Packit 5e46da
            if (insn_opt_cmp[insn->cmp_opt]) {
Packit 5e46da
                buf += sprintf(buf, "%-10s ", insn_opt_cmp[insn->cmp_opt]);
Packit 5e46da
                buf += _sprint_operands(buf, cmd);
Packit 5e46da
            } else {
Packit 5e46da
                buf += sprintf(buf, "[unknown COMPARE option in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
            }
Packit 5e46da
            break;
Packit 5e46da
Packit 5e46da
        case INSN_GROUP_SET:
Packit 5e46da
            switch (insn->sub_grp) {
Packit 5e46da
                case SET_SET:
Packit 5e46da
                    if (insn_opt_set[insn->set_opt]) {
Packit 5e46da
                        buf += sprintf(buf, "%-10s ", insn_opt_set[insn->set_opt]);
Packit 5e46da
                        buf += _sprint_operands(buf, cmd);
Packit 5e46da
                    } else {
Packit 5e46da
                        buf += sprintf(buf, "[unknown SET option in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
                    }
Packit 5e46da
                    break;
Packit 5e46da
            case SET_SETSYSTEM:
Packit 5e46da
                if (insn_opt_setsys[insn->set_opt]) {
Packit 5e46da
Packit 5e46da
                    buf += sprintf(buf, "%-10s ", insn_opt_setsys[insn->set_opt]);
Packit 5e46da
                    if (insn->set_opt == INSN_SET_STREAM ||
Packit 5e46da
                        insn->set_opt == INSN_SET_SEC_STREAM ||
Packit 5e46da
                        insn->set_opt == INSN_SET_BUTTON_PAGE) {
Packit 5e46da
                        buf += _sprint_operands_hex(buf, cmd);
Packit 5e46da
                    } else {
Packit 5e46da
                        buf += _sprint_operands(buf, cmd);
Packit 5e46da
                    }
Packit 5e46da
                } else {
Packit 5e46da
                    buf += sprintf(buf, "[unknown SETSYSTEM option in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
                }
Packit 5e46da
                break;
Packit 5e46da
            default:
Packit 5e46da
                buf += sprintf(buf, "[unknown SET subgroup in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
                break;
Packit 5e46da
            }
Packit 5e46da
            break;
Packit 5e46da
Packit 5e46da
        default:
Packit 5e46da
            buf += sprintf(buf, "[unknown group in opcode 0x%08x] ", *(uint32_t*)insn);
Packit 5e46da
            break;
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    return buf - start;
Packit 5e46da
}
Packit 5e46da