#!/usr/bin/env python

# Capstone Python bindings, by Sebastian Macke <Sebastian Macke>
from __future__ import print_function
from capstone import *
from capstone.mos65xx import *
from xprint import to_hex, to_x

MOS65XX_CODE = b"\x0d\x34\x12\x00\x81\x65\x6c\x01\x00\x85\xFF\x10\x00\x19\x42\x42\x00\x49\x42"

address_modes=[
    "No address mode",
    "implied",
    "accumulator",
    "immediate value",
    "relative",
    "interrupt signature",
    "block move",
    "zero page",
    "zero page indexed with x",
    "zero page indexed with y",
    "relative bit branch",
    "zero page indirect",
    "zero page indexed with x indirect",
    "zero page indirect indexed with y",
    "zero page indirect long",
    "zero page indirect long indexed with y",
    "absolute",
    "absolute indexed with x",
    "absolute indexed with y",
    "absolute indirect",
    "absolute indexed with x indirect",
    "absolute indirect long",
    "absolute long",
    "absolute long indexed with x",
    "stack relative",
    "stack relative indirect indexed with y",
];


def print_insn_detail(insn):
    # print address, mnemonic and operands
    print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str))

    # "data" instruction generated by SKIPDATA option has no detail
    if insn.id == 0:
        return
    print("\taddress mode: %s" % (address_modes[insn.am]))
    print("\tmodifies flags: %s" % ('true' if insn.modifies_flags != 0 else 'false'))
    if len(insn.operands) > 0:
        print("\top_count: %u" % len(insn.operands))
        c = -1
        for i in insn.operands:
            c += 1
            if i.type == MOS65XX_OP_REG:
                print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg)))
            if i.type == MOS65XX_OP_IMM:
                print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm)))
            if i.type == MOS65XX_OP_MEM:
                print("\t\toperands[%u].type: MEM = 0x%s" % (c, to_x(i.mem)))


# ## Test class Cs
def test_class():
    print("*" * 16)
    print("Platform: %s" % "MOS65XX")
    print("Code: %s" % to_hex(MOS65XX_CODE))
    print("Disasm:")

    try:
        md = Cs(CS_ARCH_MOS65XX, 0)
        md.detail = True
        for insn in md.disasm(MOS65XX_CODE, 0x1000):
            print_insn_detail(insn)
            print()

        print("0x%x:\n" % (insn.address + insn.size))
    except CsError as e:
        print("ERROR: %s" % e)


if __name__ == '__main__':
    test_class()
