Ejemplo n.º 1
0
def semantic(ast, iNES=False, cart=None):
    if cart == None:
        cart = Cartridge()
    labels = get_labels(ast)
    address = 0
    # translate statments to opcode
    for leaf in ast:
        if leaf["type"] == "S_RS":
            labels[leaf["children"][0]["value"]] = cart.rs
            cart.rs += get_value(leaf["children"][2])
        elif leaf["type"] == "S_DIRECTIVE":
            directive = leaf["children"][0]["value"]
            if len(leaf["children"]) == 2:
                argument = get_value(leaf["children"][1], labels)
            else:
                argument = leaf["children"][1:]
            if directive in directive_list:
                directive_list[directive](argument, cart)
            else:
                raise Exception("UNKNOW DIRECTIVE")
        else:
            if leaf["type"] in ["S_IMPLIED", "S_ACCUMULATOR"]:
                instruction = leaf["children"][0]["value"]
                address = False
            elif leaf["type"] == "S_RELATIVE":
                instruction = leaf["children"][0]["value"]
                address = get_value(leaf["children"][1], labels)
            elif leaf["type"] == "S_IMMEDIATE_WITH_MODIFIER":
                instruction = leaf["children"][0]["value"]
                modifier = leaf["children"][1]["value"]
                address = get_value(leaf["children"][3], labels)
                if modifier == "#LOW":
                    address = address & 0x00FF
                elif modifier == "#HIGH":
                    address = (address & 0xFF00) >> 8
            elif leaf["type"] in [
                "S_RELATIVE",
                "S_IMMEDIATE",
                "S_ZEROPAGE",
                "S_ABSOLUTE",
                "S_ZEROPAGE_X",
                "S_ZEROPAGE_Y",
                "S_ABSOLUTE_X",
                "S_ABSOLUTE_Y",
            ]:
                instruction = leaf["children"][0]["value"]
                address = get_value(leaf["children"][1], labels)
            elif leaf["type"] in ["S_INDIRECT_X", "S_INDIRECT_Y"]:
                instruction = leaf["children"][0]["value"]
                address = get_value(leaf["children"][2], labels)

            address_mode = address_mode_def[leaf["type"]]["short"]
            opcode = opcodes[instruction][address_mode]
            if address_mode != "sngl":
                if "rel" == address_mode:
                    address = 126 + (address - cart.pc)
                    if address == 128:
                        address = 0
                    elif address < 128:
                        address = address | 0b10000000
                    elif address > 128:
                        address = address & 0b01111111

                if address_mode_def[leaf["type"]]["size"] == 2:
                    cart.append_code([opcode, address])
                else:
                    arg1 = address & 0x00FF
                    arg2 = (address & 0xFF00) >> 8
                    cart.append_code([opcode, arg1, arg2])
            else:
                cart.append_code([opcode])
    nes_code = []
    if iNES:
        return cart.get_ines_code()
    else:
        return cart.get_code()