예제 #1
0
def assem_conv(op, words, line):
    logging.debug("Conv %s words:%s" % (op, hl_parser.format_word_list(words)))

    token = tokens.Token("conv", err, line)

    if (op == "cmptime"):
        if (len(words) != 1):
            err.report_error("Cmptime needs one arguement")
            return
        else:
            token.add_bits(0,6, 3, 2)
            token.add_bits(0, 3, 1, 0)
            token.add_bits(0, 0, 7, 7)
            if (words[0].type() == "arg"):
                token.add_byte(1, words[0].num())
            elif (words[0].type() == "var"):
                token.add_byte(1, 0)
                token.add_vname(1, 0, words[0].val())
            else:
                err.report_error("Cmptime takes a variable as it's argument")
                return
    else:
        if (len(words) != 0):
            err.report_error("Conversions don't that arguments")
            return
        else:
            token.add_bits(0,6, 3, 2)
            token.add_bits(0, 0, 7, 3)
            if (op == "convm"):
                token.add_bits(0, 3, 1, 1)

    token.finish(token_stream)
예제 #2
0
def assem_basic_math(op, size, words, line):
    logging.debug("Mathb %s size:%s, words:%s" % (op, size, hl_parser.format_word_list(words)))
    if (len(words) != 1):
        err.report_error("Basic Math needs one argument")
        return

    token = tokens.Token("basic-math", err, line)
    token.add_bits(0, 6, 3, 2)
    token.add_bits(0, 4, 3, 1)
    token.add_bits(0, 3, 1, size)
    token.add_bits(0, 0, 3, basic_assem_map[op])

    if (words[0].type() in ["var", "arg"]):
        # math with a variable
        token.add_bits(0, 2, 1, 0)
        if (words[0].type() == "arg"):
            token.add_byte(1, words[0].num())
        else:
            token.add_byte(1, 0)
            token.add_vname(1, size, words[0].val())
        token.finish(token_stream)
    elif (words[0].type() == "const"):
        token.add_bits(0, 2, 1, 1)
        if (size == 0):
            token.add_byte(1, words[0].val())
        else:
            token.add_word(1, words[0].val())

        token.finish(token_stream)
    else:
        err.report_error("Basic Math - invalid argument type")
        return
예제 #3
0
def assem_spec_finish(words, line):
    logging.debug("Spec_finish words:%s" % (hl_parser.format_word_list(words)))
    if (len(words) != 0):
        err.report_error("FINISH doesn't have any arguments")
        return

    token_stream.finish_tokens()
예제 #4
0
def assem_uni_math(op, size, words, line):
    logging.debug("Mathu %s size:%d, words:%s" % (op, size, hl_parser.format_word_list(words)))
    if (len(words) > 1):
        err.report_error("Unary Math has at most one argument")
        return

    token = tokens.Token("uni-math", err, line)
    token.add_bits(0, 6, 3, 2)
    token.add_bits(0, 3, 1, size)
    token.add_bits(0, 0, 3, uni_assem_map[op])

    if (not words or
        (words[0].type() == "modreg" and words[0].val() == hl_parser.modreg_names["acc"])):
        token.add_bits(0, 2, 1, 0)
        token.finish(token_stream)
    elif (words[0].type() in ["var", "arg"]):
        token.add_bits(0, 2, 1, 1)
        if (words[0].type() == "arg"):
            token.add_byte(1, words[0].num())
        else:
            token.add_byte(1, 0)
            token.add_vname(1, size, words[0].val())
        token.finish(token_stream)
    else:
        err.report_error("Unary Math - invalid argument type")
        return
예제 #5
0
def assem_spec_reserve(which, words, line):
    logging.debug("Spec_reserve which:%s words:%s" % (which, hl_parser.format_word_list(words)))
    if (len(words) != 2):
        err.report_error("RESERV[ABW] needs 2 arguments: start, length")
        return

    token_stream.reserve_name_space(tokens.space_types[which], words[0].anum(), words[1].anum())
예제 #6
0
def assem_spec_insert(words, line):
    logging.debug("Spec_insert words:%s" % (hl_parser.format_word_list(words)))
    if (len(words) != 2):
        err.report_error("INSERT needs type and filename arguments")
        return

    type = words[0].astr()
    f_name = words[1].astr()

    if (type.lower() not in ['tokens', 'binary']):
        err.report_error("INSERT type must be one of: 'tokens', 'binary'")
        return

    if (type.lower() == 'tokens'):
        err.report_error("INSERT TOKENS should have been consumed higher up! Eek!");
        return

    # we have an insert binary special to deal with
    if (not os.path.isfile(f_name) or not os.access(f_name, os.R_OK)):
        err.report_error("INSERT BINARY file:%s doesn't exist or isn't readable")
        return

    token = tokens.Token("binary", err, line)
    token.add_binary_file(f_name)
    token.finish(token_stream)
예제 #7
0
def assem_other_math(op, size, words, line):
    logging.debug("Matho %s size:%d, words:%s" % (op, size, hl_parser.format_word_list(words)))

    if (len(words) != 1):
        err.report_error("Logic Math needs one arguement")
        return

    token = tokens.Token("log-math", err, line)
    token.add_bits(0, 6, 3, 2)
    token.add_bits(0, 3, 1, size)

    if (op in other1_assem_map.keys()):
        token.add_bits(0,4,3,2)
        token.add_bits(0,0,3, other1_assem_map[op])
    else:
        token.add_bits(0,4,3,3)
        token.add_bits(0,0,3, other2_assem_map[op])

    if (words[0].type() in ["var", "arg"]):
        # math with a variable
        token.add_bits(0, 2, 1, 0)
        if (words[0].type() == "arg"):
            token.add_byte(1, words[0].val())
        else:
            token.add_byte(1, 0)
            token.add_vname(1, size, words[0].val())
        token.finish(token_stream)
    elif (words[0].type() == "const"):
        token.add_bits(0, 2, 1, 1)
        token.add_byte(1, words[0].val())

        token.finish(token_stream)
    else:
        err.report_error("Logic Math - invalid argument type")
        return
예제 #8
0
def assem_jump(op, cond, words, line):
    logging.debug("Jump %s cond:%s, words:%s" %
                  (op, cond, hl_parser.format_word_list(words)))
    # ops is one of: branch, sub, ret, dbnz, dsnz
    # cond is one of: a, e, ne, g, l, le, lg or empty for ret, d?nz
    token = tokens.Token("jump", err, line)
    token.add_bits(0, 6, 3, 3)

    if (op == "ret"):
        if (len(words) != 0):
            err.report_error("Ret don't take an argument")
            return
        else:
            token.add_bits(0, 0, 0x3f, 0x28)
    elif (len(words) != 1):
        err.report_error("Jumps need a target to jump to")
        return
    else:
        if (op[:2] in ['su', 'ds']):
            # a call to a subroutine - push a frame
            token.add_bits(0, 3, 1, 1)
        else:
            token.add_bits(0, 3, 1, 0)

        if (not cond):
            # one of dbnz or dsnz
            token.add_bits(0, 0, 7, 7)
        else:
            token.add_bits(0, 0, 7, jcond_assem_map[cond])

        # now the target
        if (words[0].type() == "const"):
            offset = words[0].val()
            if (offset >= tokens.MIN_SBYTE and offset <= tokens.MAX_SBYTE):
                if (offset < 0):
                    # convert to a signed offset
                    offset += 256
                token.add_byte(1, offset)
            elif (offset >= tokens.MIN_WORD and offsec <= tokens.MAX_WORD):
                token.add_bits(0, 4, 1, 1)
                token.add_word(1, offset)

        elif (words[0].type() == "label"):
            if (words[0].val().startswith(':')):
                # globals are always long jumps
                token.add_bits(0, 4, 1, 1)
                token.set_jump_label(1, words[0].val(), True)
                token.add_word(1, 0)  # A placeholder
            else:
                token.set_jump_label(1, words[0].val())
                token.add_byte(1, 0)  # A placeholder

        else:
            err.report_error(
                "Jumps need either a constant or a label as argument, not a: "
                + words[0].type())
            return

    token.finish(token_stream)
예제 #9
0
def assem_jump(op, cond, words, line):
    logging.debug("Jump %s cond:%s, words:%s" % (op, cond, hl_parser.format_word_list(words)))
    # ops is one of: branch, sub, ret, dbnz, dsnz
    # cond is one of: a, e, ne, g, l, le, lg or empty for ret, d?nz
    token = tokens.Token("jump", err, line)
    token.add_bits(0, 6, 3, 3)

    if (op == "ret"):
        if (len(words) != 0):
            err.report_error("Ret don't take an argument")
            return
        else:
            token.add_bits(0, 0, 0x3f, 0x28)
    elif (len(words) != 1):
        err.report_error("Jumps need a target to jump to")
        return
    else:
        if (op[:2] in ['su', 'ds']):
            # a call to a subroutine - push a frame
            token.add_bits(0, 3, 1, 1)
        else:
            token.add_bits(0, 3, 1, 0)

        if (not cond):
            # one of dbnz or dsnz
            token.add_bits(0, 0, 7, 7)
        else:
            token.add_bits(0, 0, 7, jcond_assem_map[cond])

        # now the target
        if (words[0].type() == "const"):
            offset = words[0].val()
            if (offset >= tokens.MIN_SBYTE and offset <= tokens.MAX_SBYTE):
                if (offset < 0):
                    # convert to a signed offset
                    offset += 256
                token.add_byte(1, offset)
            elif (offset >= tokens.MIN_WORD and offsec <= tokens.MAX_WORD):
                token.add_bits(0, 4, 1, 1)
                token.add_word(1, offset)

        elif (words[0].type() == "label"):
            if (words[0].val().startswith(':')):
                # globals are always long jumps
                token.add_bits(0, 4, 1, 1)
                token.set_jump_label(1, words[0].val(), True)
                token.add_word(1, 0)    # A placeholder
            else:
                token.set_jump_label(1, words[0].val())
                token.add_byte(1, 0)    # A placeholder

        else:
            err.report_error("Jumps need either a constant or a label as argument, not a: "+words[0].type())
            return

    token.finish(token_stream)
예제 #10
0
def assem_stack(op, size, words, line):
    logging.debug("Stack %s size:%d, words:%s" % (op, size, hl_parser.format_word_list(words)))
    # op in ['push', 'pop'], size in [0, 1], one word
    if (len(words) != 1):
        err.report_error("Stack ops need 1 argument")
        return

    token = tokens.Token("stack", err, line)
    token.add_bits(0, 6, 3, 3)
    token.add_bits(0, 5, 1, 1)
    token.add_bits(0, 4, 1, size)

    if (op == "push"):
        if (words[0].type() == 'const'):
            if (size == 0):
                token.add_byte(1, words[0].val())
            else:
                token.add_word(1, words[0].val())
        elif (words[0].type() == 'modreg'):
            if (words[0].val() == hl_parser.modreg_names["acc"]):
                token.add_bits(0, 0, 0xf, 0x3)
            else:
                token.add_bits(0, 0, 0xf, 2)
                token.add_byte(1, words[0].val())
        elif (words[0].type() in  ["var", "arg"]):
            token.add_bits(0, 0, 0xf, 1)
            if (words[0].type() == "arg"):
                token.add_byte(1, words[0].num())
            else:
                token.add_byte(1, 0)
                token.add_vname(1, size, words[0].val())
        else:
            err.report_error("Push - invalid operand: %s" % (words[0].type()))
            return

    else: # pop
        if (words[0].type() == 'modreg'):
            if (words[0].val() == hl_parser.modreg_names["acc"]):
                token.add_bits(0, 0, 0xf, 0x4)
            else:
                token.add_bits(0, 0, 0xf, 6)
                token.add_byte(1, words[0].val())
        elif (words[0].type() in ["var", "arg"]):
            token.add_bits(0, 0, 0xf, 5)
            if (words[0].type() == "arg"):
                token.add_byte(1, words[0].num())
            else:
                token.add_byte(1, 0)
                token.add_vname(1, size, words[0].val())
        else:
            err.report_error("Pop - invalid operand: %s" % (words[0].type()))
            return


    token.finish(token_stream)
예제 #11
0
def assem_spec_comms(words, line):
    logging.debug("Spec_comms words:%s" % (hl_parser.format_word_list(words)))
    if (len(words) != 1):
        err.report_error("COMMS needs exactly 1 argument")
        return

    token = tokens.Token("comms", err, line)
    token.add_bits(0, 0, 0xf, 0x8)

    token.add_uword(1, words[0].anum())
    token.finish(token_stream)

    token_stream.set_comms(words[0].anum())
예제 #12
0
def assem_spec_limits(words, line):
    logging.debug("Spec_limits words:%s" % (hl_parser.format_word_list(words)))
    if (len(words) != 5):
        err.report_error("LIMITS needs exactly 5 arguments")
        return

    b_limit = words[0].anum()
    w_limit = words[1].anum()
    l_limit = words[2].anum()
    e_handlers = words[3].anum()
    t_bytes_limit = words[4].anum()

    token_stream.set_limits(b_limit, w_limit, l_limit, e_handlers, t_bytes_limit)
예제 #13
0
def assem_spec_version(words, line):
    logging.debug("Spec_version words:%s" % (hl_parser.format_word_list(words)))
    if (len(words) != 2):
        err.report_error("VERSION needs 2 arguments: major, minor")
        return
    major = words[0].anum()
    minor = words[1].anum()

    if (major < 0 or major > 15):
        err.report_error("major version must be between 0 and 15 (not %d)" % major)

    if (minor < 0 or minor > 15):
        err.report_error("minor version must be between 0 and 15 (not %d)" % major)

    token_stream.add_version(major, minor)
예제 #14
0
def assem_spec_device(words, line):
    logging.debug("Spec_device words:%s" % (hl_parser.format_word_list(words)))
    if (len(words) == 2):
        name = ""
    elif (len(words) == 3):
        name = words[2].astr()
    else:
        err.report_error("DEVICE needs 2 or 3 arguments")
        return

    device_type = words[0].astr()
    location = words[1].anum()

    # error checking is done in the hl_parser
    # add the device to the high_level parser for parsing of subsequent names
    if (hl_parser.add_device(location, device_type, name)):
        token_stream.add_device(hl_parser.device_types[device_type], location,
                                hl_parser.device_storage[device_type])
예제 #15
0
def assem_event(op, words, line):
    logging.debug("Event %s words:%s" % (op, hl_parser.format_word_list(words)))
    # op is one of: enable, disable, no words
    if (len(words) != 0):
        err.report_error("Enable/disable don't take arguments")
        return

    token = tokens.Token("event", err, line)
    token.add_bits(0, 6, 3, 2)
    token.add_bits(0, 4, 3, 3)
    token.add_bits(0, 0, 3, 3)

    if (op == 'enable'):
        token.add_bits(0, 2, 1, 1)
    else: #(op == 'disable')
        token.add_bits(0, 2, 1, 0)

    token.finish(token_stream)
예제 #16
0
def assem_spec_begin_end(op, words, line):
    logging.debug("Spec_begin_end op:%s words:%s" %
                  (op, hl_parser.format_word_list(words)))
    if (len(words) < 1):
        err.report_error("BEGIN/END need a type argument")
        return

    if (words[0].astr() == "FIRMWARE"):
        if (op == "BEGIN"):
            if (len(words) != 1):
                err.report_error("FIRMWARE doesn't take any arguments.")
                return
            token_stream.add_begin("firmware")
        else:
            # END MAIN
            token_stream.add_end("firmware")
    elif (words[0].astr() == "EVENT"):
        if (op == "BEGIN"):
            if (len(words) != 4):
                err.report_error(
                    "EVENT needs 3 arguments: mod/reg, mask, value")
                return
            modreg = words[1].amodreg()
            mask = words[2].anum()
            value = words[3].anum()
            token_stream.add_begin("event", modreg, mask, value)
        else:
            # END EVENT
            token_stream.add_end("event")

    elif (words[0].astr() == "MAIN"):
        if (op == "BEGIN"):
            if (len(words) != 1):
                err.report_error("MAIN doesn't take any arguments.")
                return
            token_stream.add_begin("main")
        else:
            # END MAIN
            token_stream.add_end("main")

    else:
        err.report_error("BEGIN/END needs one of: MAIN, EVENT, FIRMWARE")
        return
예제 #17
0
def assem_spec_begin_end(op, words, line):
    logging.debug("Spec_begin_end op:%s words:%s" % (op, hl_parser.format_word_list(words)))
    if (len(words) < 1):
        err.report_error("BEGIN/END need a type argument")
        return

    if (words[0].astr() == "FIRMWARE"):
        if (op == "BEGIN"):
            if (len(words) != 1):
                err.report_error("FIRMWARE doesn't take any arguments.")
                return
            token_stream.add_begin("firmware")
        else:
            # END MAIN
            token_stream.add_end("firmware")
    elif (words[0].astr() == "EVENT"):
        if (op == "BEGIN"):
            if (len(words) != 4):
                err.report_error("EVENT needs 3 arguments: mod/reg, mask, value")
                return
            modreg = words[1].amodreg()
            mask = words[2].anum()
            value = words[3].anum()
            token_stream.add_begin("event", modreg, mask, value)
        else:
            # END EVENT
            token_stream.add_end("event")

    elif (words[0].astr() == "MAIN"):
        if (op == "BEGIN"):
            if (len(words) != 1):
                err.report_error("MAIN doesn't take any arguments.")
                return
            token_stream.add_begin("main")
        else:
            # END MAIN
            token_stream.add_end("main")

    else:
        err.report_error("BEGIN/END needs one of: MAIN, EVENT, FIRMWARE")
        return
예제 #18
0
def assem_misc(op, words, line):
    logging.debug("Misc op:%s words:%s" %
                  (op, hl_parser.format_word_list(words)))
    if (op == "stop"):
        if (len(words) != 0):
            err.report_error("Stop doesn't take arguments")
            return

        token = tokens.Token("misc", err, line)
        token.add_bits(0, 0, 0xff, 0xff)
        token.finish(token_stream)

    elif (op in ["bitset", "bitclr"]):
        if (len(words) != 2):
            err.report_error(
                "Bitset/bitclr needs 2 arguments: bit and mod/reg")
            return

        bit = words[0].anum()
        if (bit < 0 or bit > 7):
            err.report_error(
                "Bitset/bitclr bit must be between 0 and 7 (not %d)" % (bit))
            return

        modreg = words[1].amodreg()

        token = tokens.Token("misc", err, line)
        token.add_bits(0, 4, 0x0f, 0x00)
        if (op == "bitset"):
            token.add_bits(0, 3, 0x1, 0x1)
        else:
            token.add_bits(0, 3, 0x1, 0x0)

        token.add_bits(0, 0, 0x7, bit)
        token.add_byte(1, modreg)
        token.finish(token_stream)

    else:
        err.report_error("Unknown misc operator: " + op)
        return
예제 #19
0
def assem_spec_binary(which, words, line):
    logging.debug("Spec_binary which:%s words:%s" % (which, hl_parser.format_word_list(words)))

    token = tokens.Token("binary", err, line)
    token_index = 0

    # now words are the values
    for w in words:
        if (w.type() not in ["arg", "string", "const"]):
            err.report_error("Word should have been an argument or string!")
            return
        else:

            if (w.type() == "string"):
                for c in w.val():
                    token.add_byte(token_index, ord(c))
                    token_index += 1
            else:
                token.add_byte(token_index, w.anum())
                token_index += 1

    token.finish(token_stream)
예제 #20
0
def assem_misc(op, words, line):
    logging.debug("Misc op:%s words:%s" % (op, hl_parser.format_word_list(words)))
    if (op == "stop"):
        if (len(words) != 0):
            err.report_error("Stop doesn't take arguments")
            return

        token = tokens.Token("misc", err, line)
        token.add_bits(0, 0, 0xff, 0xff)
        token.finish(token_stream)

    elif (op in ["bitset", "bitclr"]):
        if (len(words) != 2):
            err.report_error("Bitset/bitclr needs 2 arguments: bit and mod/reg")
            return

        bit = words[0].anum()
        if (bit < 0 or bit > 7):
            err.report_error("Bitset/bitclr bit must be between 0 and 7 (not %d)" % (bit))
            return

        modreg = words[1].amodreg()

        token = tokens.Token("misc", err, line)
        token.add_bits(0, 4, 0x0f, 0x00)
        if (op == "bitset"):
            token.add_bits(0, 3, 0x1, 0x1)
        else:
            token.add_bits(0, 3, 0x1, 0x0)

        token.add_bits(0, 0, 0x7, bit)
        token.add_byte(1, modreg)
        token.finish(token_stream)

    else:
        err.report_error("Unknown misc operator: " + op)
        return
예제 #21
0
def assem_line(line):
    """First scan of the operator to see which function to call"""

    err.set_context(3, line)

    words = hl_parser.chop_line(line)

    if (not words):
        return

    t1 = words[0]

    err.set_context(4, hl_parser.format_word_list(words))

    if (t1.type() == "label"):
      assem_spec_label(t1, words[1:], line=line)

    elif (t1.type() == "op"):
        op = t1.val()
        words = words[1:]

        if (op.endswith('b') or op.endswith('w')):
            size = 0
            if (op.endswith('w')):
                size = 1

            op = op[:-1]
            if (op == "mov"):
                assem_move(size, words, "", line=line)
            elif (op == "dat"):
                assem_data(size, words, line=line)
            elif (op in ["not", "dec", "inc"]):
                assem_uni_math(op, size, words, line=line)
            elif (op in ["add", "sub", "mul", "cmp"]):
                assem_basic_math(op, size, words, line=line)
            elif (op in ["shl", "shr", "div", "mod"]):
                assem_other_math(op, size, words, line=line)
            elif (op in ["push", "pop"]):
                assem_stack(op, size, words, line=line)
            elif (op in ["or", "and", "xor"]):
                assem_other_math(op, size, words, line=line)
            else:
                pass
        else:
            if (op == "mova"):
                assem_move(0, words, "lcd", line=line)
            elif (op == "movtime"):
                assem_move(1, words, "time", line=line)
            elif (op in ["conv", "convl", "convm", "cmptime"]):
                # conv 8->16, conv 16->8 lsb, conv 16->8 msb, cmp time
                assem_conv(op, words, line=line)
            elif (op in ["disable", "enable"]):
                assem_event(op, words, line=line)
            elif (op in ["ret", "dbnz", "dsnz"]):
                assem_jump(op, "", words, line=line)
            elif (op in ["bra", "bre", "brne", "brgr", "brge", "brl", "brle", "brz", "brnz"]):
                assem_jump("branch", op[2:], words, line=line)
            elif (op in ["suba", "sube", "subne", "subgr", "subge", "subl", "suble", "subz", "subnz"]):
                assem_jump("sub", op[3:], words, line=line)
            elif (op in ["stop", "bitset", "bitclr"]):
                assem_misc(op, words, line=line)
            elif (op in ["or", "and", "xor"]):
                # if there is no size after the op (which is now depricated) then treat it like a 'b'
                assem_other_math(op, 0, words, line=line)
            elif (op in ["DATB", "DATW"]):
                assem_spec_data(op[3], words, line=line)
            elif (op == "DATA"):
                assem_spec_data_lcd(op[3], words, line=line)
            elif (op in ["BINB"]):
                assem_spec_binary(op[3], words, line=line)
            elif (len(op) == 7 and op[:6] == "RESERV"):
                assem_spec_reserve(op[6], words, line=line)
            elif (op in ["BEGIN", "END"]):
                assem_spec_begin_end(op, words, line=line)
            elif (op == "VERSION"):
                assem_spec_version(words, line=line)
            elif (op == "LIMITS"):
                assem_spec_limits(words, line=line)
            elif (op == "DEVICE"):
                assem_spec_device(words, line=line)
            elif (op == "INSERT"):
                assem_spec_insert(words, line=line)
##            elif (op == "COMMS"):
##                assem_spec_comms(words, line=line)
            elif (op == "FINISH"):
                assem_spec_finish(words, line=line)
            else:
                err.report_error("Unknown operator:%s" % (op))
                return
예제 #22
0
def assem_move(size, words, special, line):
    logging.debug("Move size:%d, words:%s" % (size, hl_parser.format_word_list(words)))
    if (len(words) != 2):
        err.report_error("Move needs 2 arguments")
        return

    token = tokens.Token("move", err, line)
    token.add_bits(0, 6, 3, 1)
    sdindex = 1

    # source
    if (words[0].type() == "const"):
        if (not special and words[0].val() >= 0 and words[0].val() <= 3):
            token.add_bits(0, 3, 0x3, words[0].val())
            token.add_bits(0, 2, 0x1, size)
        else:
            if (size == 0):
                token.add_bits(0, 2, 0xf, 0xa)
                token.add_byte(sdindex, words[0].val())
                sdindex += 1
            else:
                if (not special):
                    token.add_bits(0, 2, 0xf, 0xb)
                elif (special == "time"):
                    token.add_bits(0, 2, 0xf, 0xf)
                else:
                    err.report_error("Source for lcd moves must be byte sized")
                    return

                token.add_word(sdindex, words[0].val())
                sdindex += 2
    elif (words[0].type() == "modreg"):
        if (size == 0):
            token.add_bits(0, 2, 0xf, 0x8)
        else:
            token.add_bits(0, 2, 0xf, 0x9)
        token.add_byte(sdindex, words[0].val())
        sdindex += 1

    elif (words[0].type() in ["var", "arg"]):
        if (size == 0):
            token.add_bits(0, 2, 0xf, 0xc)
        else:
            if (not special):
                token.add_bits(0, 2, 0xf, 0xd)
            elif (special == "time"):
                token.add_bits(0, 2, 0xf, 0xe)
            else:
                err.report_error("Source for lcd moves must be byte sized")
                return

        if (words[0].type() == "arg"):
            token.add_byte(sdindex, words[0].num())
        else:
            token.add_byte(sdindex, 0)
            token.add_vname(sdindex, size, words[0].val())
        sdindex += 1

    # if this is a time chkpt then the destination must be in 8bit space
    if (special == "time"):
        size = 0

    # destination
    if (words[1].type() == "modreg"):
        if (special):
            err.report_error("Destination for lcd and time moves can NOT be mod/reg")
            return

        token.add_bits(0, 0, 0x3, 0x0)
        token.add_byte(sdindex, words[1].val())
        sdindex += 1


    elif (words[1].type() in ["var", "arg"]):
        if (size == 0):
            if (special != "lcd"):
                token.add_bits(0, 0, 0x3, 0x1)
            else:
                token.add_bits(0, 0, 0x3, 0x3)
        else:
            if (special):
                err.report_error("Desination for lcd and time moves can not be in word variables")
                return

            token.add_bits(0, 0, 0x3, 0x2)

        if (words[1].type() == "arg"):
            token.add_byte(sdindex, words[1].num())
        else:
            token.add_byte(sdindex, 0)
            if (special == "lcd"):
                token.add_vname(sdindex, 2, words[1].val())
            else:
                token.add_vname(sdindex, size, words[1].val())
        sdindex += 1

    logging_utils.dump_object(token, "move")
    token.finish(token_stream)
예제 #23
0
def assem_spec_data_lcd(which, words, line):
    logging.debug("Spec_data_lcd which:%s words:%s" % (which, hl_parser.format_word_list(words)))

    if (len(words) < 4):
        err.report_error("DATA needs at least 4 arguments: row, col, len, val1")
        return

    if (words[0].val() == '*'):
        err.report_error("DATA needs a real row")
        return
    else:
        row = words[0].anum()

    if (words[1].val() == '*'):
        err.report_error("DATA needs a real column")
        return
    else:
        column = words[1].anum()

    start = row * ROW_LENGTH + column

    if (words[2].val() == '*'):
        length = -1
    else:
        length = words[2].anum()

    words = words[3:]

    values = []
    # now words are the values
    for w in words:
        if (w.type() not in ["arg", "string"]):
            err.report_error("Word should have been an argument or string!")
            return
        else:
            if (w.type() == "string"):
                for c in w.val():
                    values.append(ord(c))
            else:
                values.append(w.anum())

    # Do space sanity checks
    if (length > 0 and len(values) > length):
        err.report_error("Data has length of %d but more values (%d) then length" % \
                                   (length, len(values)))
        return

    if (length > 0):
        real_length = length
    else:
        real_length = len(values)

    if (start+real_length > ROW_LENGTH * COL_LENGTH):
        err.report_error("Data has overflowed the space")
        return

    # Add spaces if needed
    if ((length > 0) and (length > len(values))):
        while (len(values) < length):
            values.append(' ')

    # Make the tokens
    if (len(values)):

        tokens_to_create = (len(values)+14)/15
        last = len(values) % 15

        #print tokens_to_create, last
        val_index = 0
        for i in range(tokens_to_create):
            token = tokens.Token("data", err, line)
            token.add_bits(0, 4, 3, 3)
            if ((i < (tokens_to_create-1)) or (last == 0)):
                val_count = 15
            else:
                val_count = last

            token.add_bits(0, 0, 0xf, val_count)

            # add the row/column
            loc = start + i * 15
            token.add_byte(1, loc / ROW_LENGTH)
            token.add_byte(2, loc % ROW_LENGTH)

            token_index = 3
            # add the data
            for j in range(val_count):
                #print val_index
                token.add_byte(token_index, values[val_index])
                token_index += 1
                val_index += 1

            token.finish(token_stream)
예제 #24
0
def assem_spec_data(which, words, line):
    logging.debug("Spec_data which:%s words:%s" % (which, hl_parser.format_word_list(words)))

    if (len(words) < 2):
        err.report_error("DAT[BW] needs at least 2 arguments: name, start")
        return

    space = tokens.space_types[which]

    if (words[0].val() == '*'):
        name = '*'
    else:
        name = words[0].astr()

    if (words[1].val() == '*'):
        start = -1
        if (name == '*'):
            err.report_error("DAT[BW] both name and loc can't both be '*'")
            return
    else:
        start = words[1].anum()

    words = words[2:]

    length = 1
    if (len(words) >= 1):
        if (words[0].val() == '*'):
            length = -1
        else:
            length = words[0].anum()
        words = words[1:]

    values = []
    # now words are the values
    for w in words:
        if (w.type() not in ["arg", "string"]):
            err.report_error("Word should have been an argument or string!")
            return
        else:
            if (w.type() == "string"):
                for c in w.val():
                    values.append(ord(c))
            else:
                values.append(w.anum())

    # Do space sanity checks
    if (length > 0 and len(values) > length):
        err.report_error("Data has length of %d but more values (%d) then length" % \
                                   (length, len(values)))
        return

    if (length > 0):
        real_length = length
    else:
        real_length = len(values)

    if (start > 0):
        test = start + real_length
    else:
        # don't know where it will start so can't know if it will fit yet
        test = real_length

    if (test <= 0):
        err.report_error("There is no data for the space")
        return
    elif (test >= 255):
        err.report_error("Data has overflowed the space")
        return

    # special case where we have an UNNAMED area with a length - zero beyond the values up to length
    if ((name == '*') and (length > 0) and (length > len(values))):
        while (len(values) < length):
            values.append(0)
        #print values

    # Make the tokens
    if (len(values)):

        tokens_to_create = (len(values)+14)/15
        last = len(values) % 15

        #print tokens_to_create, last
        val_index = 0
        for i in range(tokens_to_create):
            token = tokens.Token("data", err, line)
            token.add_bits(0, 4, 3, space+1)
            if ((i < (tokens_to_create-1)) or (last == 0)):
                val_count = 15
            else:
                val_count = last

            token.add_bits(0, 0, 0xf, val_count)

            # add the location
            if (name != '*'):
                token.add_byte(1, i*15)
                token.add_vname(1, space, name)
            else:
                token.add_byte(1, start + (i*15))

            token_index = 2
            # add the data
            if (which == "B"):
                for j in range(val_count):
                    #print val_index
                    token.add_byte(token_index, values[val_index])
                    token_index += 1
                    val_index += 1
            else:
                for j in range(val_count):
                    #print val_index
                    token.add_word(token_index, values[val_index])
                    token_index += 2
                    val_index += 1

            token.finish(token_stream)

    # Add the info about the variable to the token_stream
    if (name != '*'):
        token_stream.add_variable(space, name, start, real_length)
예제 #25
0
def assem_data(size, words, line):
    logging.debug("data size:%s words:%s" % (size, hl_parser.format_word_list(words)))

    if (len(words) < 3):
        err.report_error("dat[bw] needs at least 3 arguments: var, len and value1")
        return

    if (words[0].type() not in ["arg", "var"]):
        err.report_error("dat[bw] first argument must be a variable or location")
        return
    elif (words[0].type() == "arg"):
        start = words[0].anum()
        name = '*'
    else:
        start = 0
        name = words[0].val()

    length = 1
    if (words[1].val() == '*'):
        length = -1
    else:
        length = words[1].anum()

    words = words[2:]
    values = []
    # now words are the values
    for w in words:
        if (w.type() not in ["arg", "string"]):
            err.report_error("Word should have been an argument or string!")
            return
        else:
            if (w.type() == "string"):
                for c in w.val():
                    values.append(ord(c))
            else:
                values.append(w.anum())

    # Do space sanity checks
    if (length > 0 and len(values) > length):
        err.report_error("Data has length of %d but more values (%d) then length" % \
                                   (length, len(values)))
        return

    if (length > 0):
        real_length = length
    else:
        real_length = len(values)

    # zero up to the named length
    if (length > len(values)):
        while (len(values) < length):
            values.append(0)

    # Make the tokens
    if (len(values)):

        tokens_to_create = (len(values)+14)/15
        last = len(values) % 15

        #print tokens_to_create, last
        val_index = 0
        for i in range(tokens_to_create):
            token = tokens.Token("data", err, line)
            token.add_bits(0, 4, 3, size+1)
            if ((i < (tokens_to_create-1)) or (last == 0)):
                val_count = 15
            else:
                val_count = last

            token.add_bits(0, 0, 0xf, val_count)

            # add the location
            if (name != '*'):
                token.add_byte(1, i*15)
                token.add_vname(1, size, name)
            else:
                token.add_byte(1, start + (i*15))

            token_index = 2
            # add the data
            if (size == 0):
                for j in range(val_count):
                    #print val_index
                    token.add_byte(token_index, values[val_index])
                    token_index += 1
                    val_index += 1
            else:
                for j in range(val_count):
                    #print val_index
                    token.add_word(token_index, values[val_index])
                    token_index += 2
                    val_index += 1

            token.finish(token_stream)