# This code is Public Domain
# It was written by Stephen Warren <s-t-dvd_vmi_dis_code@wwwdotorg.org>
# Feedback is welcome.

def version():
    return "1.0.5"
#

COMPARE_OPTION_BC = 0x1
COMPARE_OPTION_EQ = 0x2
COMPARE_OPTION_NE = 0x3
COMPARE_OPTION_GE = 0x4
COMPARE_OPTION_GT = 0x5
COMPARE_OPTION_LE = 0x6
COMPARE_OPTION_LT = 0x7

compare_option_str_table = {
    COMPARE_OPTION_BC: "BitCompare",
    COMPARE_OPTION_EQ: "EQ",
    COMPARE_OPTION_NE: "NE",
    COMPARE_OPTION_GE: "GE",
    COMPARE_OPTION_GT: "GT",
    COMPARE_OPTION_LE: "LE",
    COMPARE_OPTION_LT: "LT"
}

def compare_option_str(compare_option):
    return compare_option_str_table.setdefault(compare_option, "ERROR")
#

GOTO_OPTION_GOTO      = 0x1
GOTO_OPTION_BREAK     = 0x2
GOTO_OPTION_SETTMPPML = 0x3

goto_option_str_table = {
    GOTO_OPTION_GOTO:      "GoTo",
    GOTO_OPTION_BREAK:     "Break",
    GOTO_OPTION_SETTMPPML: "SetTmpPML"
}

def goto_option_str(goto_option):
    return goto_option_str_table.setdefault(goto_option, "ERROR")
#

LINK_OPTION_LINKSINS     = 0x1
LINK_OPTION_LINKTKN      = 0x2
LINK_OPTION_LINKDLISTN   = 0x3
LINK_OPTION_LINKPGCN     = 0x4
LINK_OPTION_LINKPTTN     = 0x5
LINK_OPTION_LINKPGN      = 0x6
LINK_OPTION_LINKCN       = 0x7
LINK_OPTION_LINKTKNGP    = 0xA
LINK_OPTION_LINKDLISTNGP = 0xB
LINK_OPTION_LINKPGCNGP   = 0xC
LINK_OPTION_LINKPGNGP    = 0xE
LINK_OPTION_LINKCNGP     = 0xF

link_option_str_table = {
    LINK_OPTION_LINKSINS:     "LinkSIns",
    LINK_OPTION_LINKTKN:      "LinkTkN",
    LINK_OPTION_LINKDLISTN:   "LinkDListN",
    LINK_OPTION_LINKPGCN:     "LinkPGCN",
    LINK_OPTION_LINKPTTN:     "LinkPTTN",
    LINK_OPTION_LINKPGN:      "LinkPGN",
    LINK_OPTION_LINKCN:       "LinkCN",
    LINK_OPTION_LINKTKNGP:    "LinkTknGP",
    LINK_OPTION_LINKDLISTNGP: "LinkDListNGP",
    LINK_OPTION_LINKPGCNGP:   "LinkPGCNGP",
    LINK_OPTION_LINKPGNGP:    "LinkPGNGP",
    LINK_OPTION_LINKCNGP:     "LinkCNGP"
}

def link_option_str(link_option):
    return link_option_str_table.setdefault(link_option, "ERROR")
#

JUMP_OPTION_EXIT        = 0x1
JUMP_OPTION_JUMPTT      = 0x2
JUMP_OPTION_JUMPVTS_TT  = 0x3
JUMP_OPTION_JUMPVTS_PTT = 0x5
JUMP_OPTION_JUMPSS      = 0x6
JUMP_OPTION_CALLSS      = 0x8
JUMP_OPTION_JUMPTT_GR   = 0x9
JUMP_OPTION_JUMPTK      = 0xA
JUMP_OPTION_AMGM_RSM    = 0xB

jump_option_str_table = {
    JUMP_OPTION_EXIT:        "Exit",
    JUMP_OPTION_JUMPTT:      "JumpTT",
    JUMP_OPTION_JUMPVTS_TT:  "JumpVTS_TT",
    JUMP_OPTION_JUMPVTS_PTT: "JumpVTS_PTT",
    JUMP_OPTION_JUMPSS:      "JumpSS",
    JUMP_OPTION_CALLSS:      "CallSS",
    JUMP_OPTION_JUMPTT_GR:   "JumpTT_GR",
    JUMP_OPTION_JUMPTK:      "JumpTK",
    JUMP_OPTION_AMGM_RSM:    "AMGM_Rsm"
}

def jump_option_str(jump_option):
    return jump_option_str_table.setdefault(jump_option, "ERROR")
#

SETSYS_OPTION_SETSTN     = 0x1
SETSYS_OPTION_SETNVTMR   = 0x2
SETSYS_OPTION_SETGPRMMD  = 0x3
SETSYS_OPTION_SETAMXMD   = 0x4
SETSYS_OPTION_SETHL_BTNN = 0x6

setsys_option_str_table = {
    SETSYS_OPTION_SETSTN:     "SetSTN",
    SETSYS_OPTION_SETNVTMR:   "SetNVTMR",
    SETSYS_OPTION_SETGPRMMD:  "SetGPRMMD",
    SETSYS_OPTION_SETAMXMD:   "SetAMXMD",
    SETSYS_OPTION_SETHL_BTNN: "SetHL_BTNN"
}

def setsys_option_str(setsys_option):
    return setsys_option_str_table.setdefault(setsys_option, "ERROR")
#

SET_OPTION_MOV = 0x1
SET_OPTION_SWP = 0x2
SET_OPTION_ADD = 0x3
SET_OPTION_SUB = 0x4
SET_OPTION_MUL = 0x5
SET_OPTION_DIV = 0x6
SET_OPTION_MOD = 0x7
SET_OPTION_RND = 0x8
SET_OPTION_AND = 0x9
SET_OPTION_OR  = 0xA
SET_OPTION_XOR = 0xB

set_option_str_table = {
    SET_OPTION_MOV: "Mov",
    SET_OPTION_SWP: "Swp",
    SET_OPTION_ADD: "Add",
    SET_OPTION_SUB: "Sub",
    SET_OPTION_MUL: "Mul",
    SET_OPTION_DIV: "Div",
    SET_OPTION_MOD: "Mod",
    SET_OPTION_RND: "Rnd",
    SET_OPTION_AND: "And",
    SET_OPTION_OR:  "Or",
    SET_OPTION_XOR: "Xor"
}

def set_option_str(set_option):
    return set_option_str_table.setdefault(set_option, "ERROR")
#

LINKINS_LINKNOLINK    = 0x00
LINKINS_LINKTOPC      = 0x01
LINKINS_LINKNEXTC     = 0x02
LINKINS_LINKPREVC     = 0x03
LINKINS_LINKTOPPG     = 0x05
LINKINS_LINKNEXTPG    = 0x06
LINKINS_LINKPREVPG    = 0x07
LINKINS_LINKTOPPGC    = 0x09
LINKINS_LINKNEXTPGC   = 0x0A
LINKINS_LINKPREVPGC   = 0x0B
LINKINS_LINKGOUPPGC   = 0x0C
LINKINS_LINKTAILPGC   = 0x0D
LINKINS_RSM           = 0x10
LINKINS_LINKNEXTDLIST = 0x12
LINKINS_LINKPREVDLIST = 0x13

linkins_str_table = {
    LINKINS_LINKNOLINK:    "NoLink",
    LINKINS_LINKTOPC:      "LinkTopC",
    LINKINS_LINKNEXTC:     "LinkNextC",
    LINKINS_LINKPREVC:     "LinkPrevC",
    LINKINS_LINKTOPPG:     "LinkTopPG",
    LINKINS_LINKNEXTPG:    "LinkNextPG",
    LINKINS_LINKPREVPG:    "LinkPrevPG",
    LINKINS_LINKTOPPGC:    "LinkTopPGC",
    LINKINS_LINKNEXTPGC:   "LinkNextPGC",
    LINKINS_LINKPREVPGC:   "LinkPrevPGC",
    LINKINS_LINKGOUPPGC:   "LinkGoUpPGC",
    LINKINS_LINKTAILPGC:   "LinkTailPGC",
    LINKINS_RSM:           "Rsm",
    LINKINS_LINKNEXTDLIST: "LinkNextDList",
    LINKINS_LINKPREVDLIST: "LinkPrevDList"
}

def linkins_str(linkins):
    return linkins_str_table.setdefault(linkins, "ERROR")
#

MENU_TITLE       = 0x2
MENU_ROOT        = 0x3
MENU_SUB_PICTURE = 0x4
MENU_AUDIO       = 0x5
MENU_ANGLE       = 0x6
MENU_PTT         = 0x7

menu_str_table = {
    MENU_TITLE:       "Title",
    MENU_ROOT:        "Root",
    MENU_SUB_PICTURE: "Subpicture",
    MENU_AUDIO:       "Audio",
    MENU_ANGLE:       "Angle",
    MENU_PTT:         "Ptt"
}

def menu_str(menu):
    return menu_str_table.setdefault(menu, "ERROR")
#

DOMAIN_FP_PGC    = 0
DOMAIN_VMGM_ROOT = 1
DOMAIN_VTSM      = 2
DOMAIN_VMGM      = 3

domain_str_table = {
    DOMAIN_FP_PGC:    "FP_PGC",
    DOMAIN_VMGM_ROOT: "VMGM_ROOT",
    DOMAIN_VTSM:      "VTSM",
    DOMAIN_VMGM:      "VMGM"
}

def domain_str(domain):
    return domain_str_table.setdefault(domain, "ERROR")
#

def decode_cp1(cp1):
    gprmn = cp1 & 0xf
    return "GPRM" + str(gprmn)
#

def decode_c2(c2, i_flag_comp):
    if i_flag_comp:
        return str(c2 & 0xffff)
    else:
        prm_flag = (c2 >> 7) & 1
        prmn = c2 & 0x1f
        if prm_flag:
            return "SPRM" + str(prmn)
        else:
            return "GPRM" + str(prmn)
        #
    #
#

def decode_cp2(cp2):
    return decode_c2(cp2 & 0xff, False)
#

def decode_compare(compare_option, arg1_txt, arg2_txt):
    compare_option_txt = compare_option_str(compare_option)
    return "If (%s %s %s) Then" % (arg1_txt, compare_option_txt, arg2_txt)
#

def decode_goto(goto_option, goto_params):
    goto_option_txt = goto_option_str(goto_option)
    ptl_lvl = (goto_params >> 8) & 0xf
    pc = goto_params & 0xff

    if goto_option == GOTO_OPTION_GOTO:
        return goto_option_txt + "(PC=" + str(pc) + ")"
    elif goto_option == GOTO_OPTION_SETTMPPML:
        return goto_option_txt + "(PTL_LVL=" + str(ptl_lvl) + "); GoTo(PC=" + str(pc) + ")"
    else:
        return goto_option_txt
    #
#

def decode_link(link_option, link_params):
    ret = ""

    hl_btnn = (link_params >> 10) & 0x3f

    if link_option == LINK_OPTION_LINKSINS:
        linkins = link_params & 0xff
        linkins_txt = linkins_str(linkins)
        ret += linkins_txt

        if linkins == LINKINS_RSM:
            hl_btnn = None
        #
    else:
        link_option_txt = link_option_str(link_option)

        param = None
        if link_option == LINK_OPTION_LINKTKN:
            param = "TKN=" + str(link_params & 0xff)
        elif link_option == LINK_OPTION_LINKDLISTN:
            param = "DLISTN=" + str(link_params & 0x7f)
        elif link_option == LINK_OPTION_LINKPGCN:
            param = "PGCN=" + str(link_params & 0x7fff)
        elif link_option == LINK_OPTION_LINKPTTN:
            param = "PTTN=" + str(link_params & 0x3ff)
        elif link_option == LINK_OPTION_LINKPGN:
            param = "PGN=" + str(link_params & 0x7f)
        elif link_option == LINK_OPTION_LINKCN:
            param = "CN=" + str(link_params & 0xff)
        else:
            param = "GPRMN=GPRM" + str(link_params & 0xf)
        #

        ret += link_option_txt + "(" + param + ")"

        if link_option in [LINK_OPTION_LINKPGCN, LINK_OPTION_LINKPGCNGP]:
            hl_btnn = None
        #
    #

    if hl_btnn:
        ret += "; SetHL_Btn(HL_BTNN=" + str(hl_btnn) + ")"
    #

    return ret
#

def decode_jump(jump_option, jump_params):
    jump_option_txt = jump_option_str(jump_option)

    params = []
    if jump_option == JUMP_OPTION_EXIT:
        params = []
    elif jump_option == JUMP_OPTION_JUMPTT:
        ttn = jump_options & 0x7f
        params = ["TTN=" + str(ttn)]
    elif jump_option == JUMP_OPTION_JUMPVTS_TT:
        vts_ttn = jump_options & 0x7f
        params = ["VTS_TTN=" + str(vts_ttn)]
    elif jump_option == JUMP_OPTION_JUMPVTS_PTT:
        vts_ttn = jump_params & 0x7f
        pttn = (jump_params >> 16) & 0x3ff
        params = ["VTS=" + str(vts_ttn), "PTTN=" + str(pttn)]
    elif jump_option == JUMP_OPTION_JUMPSS:
        domain = (jump_params >> 6) & 3
        domain_txt = domain_str(domain)
        params = ["DOMAIN=" + domain_txt]
        if domain == DOMAIN_VTSM:
            vtsn = (jump_params >> 8) & 0x7f
            vts_ttn = (jump_params >> 16) & 0x7f
            menu = jump_params & 0xf
            params.extend(["VTSN=" + str(vtsn), "VTS_TTN=" + str(vts_ttn), "MENU=" + menu_str(menu)])
        elif domain == DOMAIN_VMGM:
            pgcn = (jump_params >> 16) & 0x7fff
            params = params.extend(["PGCN=" + str(pgcn)])
        #
    elif jump_option == JUMP_OPTION_CALLSS:
        domain = (jump_params >> 6) & 3
        domain_txt = domain_str(domain)
        rsm_cn = (jump_params >> 8) & 0xff
        params = ["DOMAIN=" + domain_txt]
        if domain == DOMAIN_VTSM:
            menu = jump_params & 0xf
            params.extend(["MENU=" + menu_str(menu)])
        elif domain == DOMAIN_VMGM:
            pgcn = (jump_params >> 16) & 0x7fff
            params.extend(["PGCN=" + std(pgcn)])
        #
        params.extend(["RSM_CN=" + str(rsm_cn)])
    elif jump_option == JUMP_OPTION_JUMPTT_GR:
        att_grn = jump_params & 0xf
        params = ["ATT_GRN=" + str(att_grn)]
    elif jump_option == JUMP_OPTION_JUMPTK:
        att_grn = (jump_params >> 16) & 0xf
        tkn = (jump_params & 0x7f)
        params = ["ATT_GRN=" + str(att_grn), "TKN=" + str(tkn)]
    elif jump_option == JUMP_OPTION_AMGM_RSM:
        params = []
    #

    return jump_option_txt + "(" + ",".join(params) + ")"
#

def decode_setsys(i_flag_set, setsys_option, setsys_params):
    setsys_option_txt = setsys_option_str(setsys_option)

    params = []
    if setsys_option == SETSYS_OPTION_SETSTN:
        set_astn = (setsys_params >> 23) & 1
        set_spstn = (setsys_params >> 15) & 1
        set_agln = (setsys_params >> 7) & 1

        params.extend(["SET_ASTN=" + str(set_astn)])
        if set_astn:
            astn = (setsys_params >> 16) & 0xf
            if i_flag_set:
                pref = ""
            else:
                pref = "GPRM"
            #
            params.extend(["ASTN=" + pref + str(astn)])
        #

        params.extend(["SET_SPSTN=" + str(set_spstn)])
        if set_spstn:
            if i_flag_set:
                sp_disp_flag = (setsys_params >> 14) & 1
                spstn = (setsys_params >> 8) & 0x7f
                params.extend(["SP_DISP_FLAG=" + str(sp_disp_flag), "SPSTN=" + str(spstn)])
            else:
                spstn_gprmn = (setsys_params >> 8) & 0xf
                params.extend(["SPSTN=GPRM" + str(astn)])
            #
        #

        params.extend(["SET_AGLN=" + str(set_agln)])
        if set_agln:
            agln = setsys_params & 0xf
            if i_flag_set:
                pref = ""
            else:
                pref = "GPRM"
            #
            params.extend(["AGLN=" + pref + str(astn)])
        #
    elif setsys_option == SETSYS_OPTION_SETNVTMR:
        if i_flag_set:
            nv_tmr = (setsys_params >> 16) & 0xffff
            opt1 = "NV_TMR=" + str(nv_tmr)
        else:
            gprmn = (setsys_params >> 16) & 0xf
            opt1 = "NV_TMR=GPRM" + str(gprmn)
        #
        tt_pgcn = setsys_params & 0x7fff
        params.extend([opt1, "TT_PGCN=" + str(tt_pgcn)])
    elif setsys_option == SETSYS_OPTION_SETGPRMMD:
        if i_flag_set:
            gprm_val = (setsys_params >> 16) & 0xffff
            val_str = str(gprm_val)
        else:
            gprmn = (setsys_params >> 16) & 0xf
            val_str = "GPRM" + str(gprmn)
        #
        mode = (setsys_params >> 7) & 1
        gprm_num = setsys_params & 0xf
        params.extend(["GPRM" + str(gprm_num), "MODE=" + str(mode), "VALUE=" + val_str])
    elif setsys_option == SETSYS_OPTION_SETAMXMD:
        if i_flag_set:
            ach4_mix_ach0 = (setsys_params >> 12) & 1
            ach3_mix_ach0 = (setsys_params >> 11) & 1
            ach2_mix_ach0 = (setsys_params >> 10) & 1
            ach4_mix_ach1 = (setsys_params >> 4) & 1
            ach3_mix_ach1 = (setsys_params >> 3) & 1
            ach2_mix_ach1 = (setsys_params >> 2) & 1
            params.extend(["HL_BTNN=GPRM" + str(gprmn)])
        else:
            gprmn = setsys_params & 0xf
            params.extend([
                "ACH4_MIX_ACH0=" + str(ach4_mix_ach0),
                "ACH3_MIX_ACH0=" + str(ach3_mix_ach0),
                "ACH2_MIX_ACH0=" + str(ach2_mix_ach0),
                "ACH4_MIX_ACH1=" + str(ach4_mix_ach1),
                "ACH3_MIX_ACH1=" + str(ach3_mix_ach1),
                "ACH2_MIX_ACH1=" + str(ach2_mix_ach1)
            ])
        #
    elif setsys_option == SETSYS_OPTION_SETHL_BTNN:
        if i_flag_set:
            hl_btnn = (setsys_params >> 10) & 0x3f
            opt = str(hl_btnn)
        else:
            gprmn = setsys_params & 0xf
            opt = "GPRM" + str(gprmn)
        #
        params.extend(["HL_BTNN=" + opt])
    #

    return setsys_option_txt + "(" + ",".join(params) + ")"
#

def decode_set(i_flag_set, set_option, parm_n, i_val, parm_flag, parm_m):
    set_option_txt = set_option_str(set_option)
    if i_flag_set:
        rhs = str(i_val)
    elif parm_flag:
        rhs = "SPRM" + str(parm_m)
    else:
        rhs = "GPRM" + str(parm_m)
    #

    return set_option_txt + "(GPRM" + str(parm_n) + ", " + rhs + ")"
#

def decode_command(cmd):
    ret = ""

    cmd0 = cmd[0]
    cmd1 = cmd[1]

    cmd_type = (cmd0 >> 29) & 7
    if cmd_type == 0:
        i_flag_comp = (cmd0 >> 23) & 1
        compare_option = (cmd0 >> 20) & 7
        goto_option = (cmd0 >> 16) & 0xf

        if compare_option:
            cp1_txt = decode_cp1(cmd0 & 0xff)
            c2_txt = decode_c2((cmd1 >> 16) & 0xffff, i_flag_comp)
            ret += decode_compare(compare_option, cp1_txt, c2_txt)
            ret += " { "
        #

        if goto_option:
            ret += decode_goto(goto_option, cmd1 & 0xffff)
        else:
            ret += "Nop"
        #

        if compare_option:
            ret += " }"
        #
    elif cmd_type == 1:
        jump_flag = (cmd0 >> 28) & 1
        i_flag_comp = (cmd0 >> 23) & 1
        compare_option = (cmd0 >> 20) & 7
        link_option = (cmd0 >> 16) & 0xf

        if jump_flag:
            if compare_option:
                cp1_txt = decode_cp1((cmd1 >> 8) & 0xff)
                cp2_txt = decode_cp2(cmd1 & 0xff)
                ret += decode_compare(compare_option, cp1_txt, cp2_txt)
                ret += " { "
            #

            jump_params = ((cmd0 & 0xffff) << 16) | ((cmd1 >> 16) & 0xffff)
            ret += decode_jump(link_option, jump_params)
        else:
            if compare_option:
                cp1_txt = decode_cp1(cmd0 & 0xff)
                c2_txt = decode_c2((cmd1 >> 16) & 0xffff, i_flag_comp)
                ret += decode_compare(compare_option, cp1_txt, c2_txt)
                ret += " { "
            #

            link_params = cmd1 & 0xffff
            ret += decode_link(link_option, link_params)
        #

        if compare_option:
            ret += " }"
        #
    elif cmd_type == 2:
        i_flag_set = (cmd0 >> 28) & 1
        setsys_option = (cmd0 >> 24) & 0xf
        compare_option = (cmd0 >> 20) & 7
        link_option = (cmd0 >> 16) & 0xf
        setsys_params = ((cmd0 & 0xffff) << 16) | ((cmd1 >> 16) & 0xffff)

        if compare_option:
            cp1_txt = decode_cp1((cmd1 >> 8) & 0xff)
            cp2_txt = decode_cp2(cmd1 & 0xff)
            ret += decode_compare(compare_option, cp1_txt, cp2_txt)
            ret += " { "
        #

        ret += decode_setsys(i_flag_set, setsys_option, setsys_params)

        if link_option and (not compare_option):
            link_params = cmd1 & 0xffff
            ret += "; "
            ret += decode_link(link_option, link_params)
        #

        if compare_option:
            ret += " }"
        #
    elif cmd_type == 3:
        i_flag_set = (cmd0 >> 28) & 1
        set_option = (cmd0 >> 24) & 0xf
        i_flag_comp = (cmd0 >> 23) & 1
        compare_option = (cmd0 >> 20) & 7
        link_option = (cmd0 >> 16) & 0xf
        parm_n = cmd0 & 0xf

        # FIXME: Factor this next block
        i_val = 0
        parm_flag = 0
        parm_m = 0
        if i_flag_set:
            i_val = (cmd1 >> 16) & 0xffff
        else:
            parm_flag = (cmd1 >> 23) & 1
            parm_m = (cmd1 >> 16) & 0x1f
        #

        if compare_option:
            cp1_txt = decode_cp1((cmd0 >> 8) & 0xff)
            c2_txt = decode_c2(cmd1 & 0xffff, i_flag_comp)
            ret += decode_compare(compare_option, cp1_txt, c2_txt)
            ret += " { "
        #

        ret += decode_set(i_flag_set, set_option, parm_n, i_val, parm_flag, parm_m)

        if (not compare_option) and link_option:
            link_params = cmd1 & 0xffff
            ret += "; "
            ret += decode_link(link_option, link_params)
        #

        if compare_option:
            ret += " }"
        #
    elif cmd_type == 4:
        i_flag_set = (cmd0 >> 28) & 1
        set_option = (cmd0 >> 24) & 0xf
        i_flag_comp = (cmd0 >> 23) & 1
        compare_option = (cmd0 >> 20) & 7
        parm_n = (cmd0 >> 16) & 0xf

        # FIXME: Factor this next block
        i_val = 0
        parm_flag = 0
        parm_m = 0
        if i_flag_set:
            i_val = cmd0 & 0xffff
        else:
            parm_flag = (cmd0 >> 7) & 1
            parm_m = cmd0 & 0x1f
        #

        c2_txt = decode_c2((cmd1 >> 16) & 0xffff, i_flag_comp)
        link_params = cmd1 & 0xffff

        ret += decode_set(i_flag_set, set_option, parm_n, i_val, parm_flag, parm_m)
        ret += "; "
        ret += decode_compare(compare_option, "GPRM" + str(parm_n), c2_txt)
        ret += " { "
        ret += decode_link(LINK_OPTION_LINKSINS, link_params)
        ret += " }"
    elif (cmd_type == 5) or (cmd_type == 6):
        # FIXME: Factor all this parsing

        i_flag_set = (cmd0 >> 28) & 1
        set_option = (cmd0 >> 24) & 0xf
        i_flag_comp = (cmd0 >> 23) & 1
        compare_option = (cmd0 >> 20) & 7
        parm_n = (cmd0 >> 16) & 0xf

        # FIXME: Factor this next block
        i_val = 0
        parm_flag = 0
        parm_m = 0
        if i_flag_set:
            i_val = cmd0 & 0xffff
            cp1_txt = decode_cp1((cmd1 >> 24) & 0xff)
            cp2_txt = decode_cp2((cmd1 >> 16) & 0xff)
            rhs_txt = cp2_txt
        else:
            parm_flag = (cmd0 >> 15) & 1
            parm_m = (cmd0 >> 8) & 0x1f
            cp1_txt = decode_cp1(cmd0 & 0xff)
            c2_txt = decode_c2((cmd1 >> 16) & 0xffff, i_flag_comp)
            rhs_txt = c2_txt
        #

        link_params = cmd1 & 0xffff

        ret += decode_compare(compare_option, cp1_txt, rhs_txt)
        ret +=  " { "
        ret += decode_set(i_flag_set, set_option, parm_n, i_val, parm_flag, parm_m)
        if cmd_type == 5:
            ret +=  "; "
        else:
            ret +=  " }; "
        #
        ret += decode_link(LINK_OPTION_LINKSINS, link_params)
        if cmd_type == 5:
            ret +=  " }"
        #
    else:
        ret += "ERROR"
    #

    return ret
#
