Exemplo n.º 1
0
def get_operand_bases(operation, preserve_base):
    elements = split_operation(operation, True)
    if not elements:
        return ''
    if preserve_base:
        base_fmt = {'b': 'b', 'c': 'c', 'd': 'd', 'h': 'h'}
    else:
        base_fmt = {'b': 'b', 'c': 'c', 'd': 'n', 'h': 'n'}
    if elements[0] in ('BIT', 'RES', 'SET'):
        operands = elements[2:]
    else:
        operands = elements[1:]
    bases = ''
    for operand in operands:
        if operand.startswith(('(IX+', '(IX-', '(IY+', '(IY-')):
            num = operand[4:]
        elif operand.startswith('('):
            num = operand[1:]
        else:
            num = operand
        if num.startswith(('"', '%', '$', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')):
            bases += base_fmt[_get_base(num)]
    if bases in ('n', 'nn'):
        return ''
    return bases
Exemplo n.º 2
0
def get_defs_length(operation, preserve_base):
    if preserve_base:
        fmt = FORMAT_PRESERVE_BASE
    else:
        fmt = FORMAT_NO_BASE
    items = split_operation(operation)[1:3]

    try:
        size = parse_word(items[0])
    except ValueError:
        raise SkoolParsingError("Invalid integer '{}': {}".format(items[0], operation))
    size_base = _get_base(items[0], preserve_base)
    try:
        get_int_param(items[0])
        size_fmt = fmt[size_base].format(items[0])
    except ValueError:
        size_fmt = fmt[size_base].format(size)

    if len(items) == 1:
        return size, size_fmt

    value_base = _get_base(items[1], preserve_base)
    if value_base in 'dh' and not preserve_base:
        value_base = 'n'
    return size, '{}:{}'.format(size_fmt, value_base)
Exemplo n.º 3
0
def get_operand_bases(operation, preserve_base):
    elements = split_operation(operation, True)
    if not elements:
        return ''
    if preserve_base:
        base_fmt = {'b': 'b', 'c': 'c', 'd': 'd', 'h': 'h'}
    else:
        base_fmt = {'b': 'b', 'c': 'c', 'd': 'n', 'h': 'n'}
    if elements[0] in ('BIT', 'RES', 'SET'):
        operands = elements[2:]
    else:
        operands = elements[1:]
    bases = ''
    for operand in operands:
        if operand.startswith(('(IX+', '(IX-', '(IY+', '(IY-')):
            num = operand[4:]
        elif operand.startswith('('):
            num = operand[1:]
        else:
            num = operand
        if num.startswith(('"', '%', '$', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9')):
            bases += base_fmt[_get_base(num)]
    if bases in ('n', 'nn'):
        return ''
    return bases
Exemplo n.º 4
0
    def convert(self, operation):
        if operation.upper().startswith(('DEFB ', 'DEFM ', 'DEFS ', 'DEFW ')):
            elements = split_operation(operation, strip=False)
            if elements[0].upper() == 'DEFW':
                convert_method = self.replace_address
            else:
                convert_method = self.replace_byte
            items = []
            for item in elements[1:]:
                if item.lstrip().startswith('"'):
                    items.append(item)
                else:
                    items.append(convert_method(item))
            return '{} {}'.format(elements[0], ','.join(items))

        elements = split_operation(operation, tidy=True)
        op = elements[0]

        # Instructions containing '(I[XY]+d)'
        index = self.get_index(operation)
        if index:
            if len(elements) == 3:
                return self.replace_index(operation, index, parse_int(elements[2]))
            return self.replace_index(operation, index)

        if op in ('CALL', 'DJNZ', 'JP', 'JR'):
            return self.replace_address(operation)

        if op in ('AND', 'OR', 'XOR', 'SUB', 'CP', 'IN', 'OUT', 'ADD', 'ADC', 'SBC', 'RST'):
            return self.replace_byte(operation)

        if op == 'LD' and len(elements) == 3:
            operands = elements[1:]
            if operands[0] in ('A', 'B', 'C', 'D', 'E', 'H', 'L', 'IXL', 'IXH', 'IYL', 'IYH', '(HL)') and not operands[1].startswith('('):
                # LD r,n; LD (HL),n
                return self.replace_byte(operation)
            if not set(('A', 'BC', 'DE', 'HL', 'IX', 'IY', 'SP')).isdisjoint(operands):
                # LD A,(nn); LD (nn),A; LD rr,nn; LD rr,(nn); LD (nn),rr
                return self.replace_address(operation)

        return operation
Exemplo n.º 5
0
def get_defs_length(operation, preserve_base):
    if preserve_base:
        fmt = FORMAT_PRESERVE_BASE
    else:
        fmt = FORMAT_NO_BASE
    size = None
    lengths = []
    for item in split_operation(operation)[1:3]:
        if size is None:
            size = get_int_param(item)
        base = _get_base(item, preserve_base)
        lengths.append(fmt[base].format(item))
    return size, ':'.join(lengths)
Exemplo n.º 6
0
def get_defs_length(operation, preserve_base):
    if preserve_base:
        fmt = FORMAT_PRESERVE_BASE
    else:
        fmt = FORMAT_NO_BASE
    values = []
    for item in split_operation(operation)[1:3]:
        base = _get_base(item, preserve_base)
        try:
            value = get_int_param(item)
        except ValueError:
            try:
                item = value = parse_word(item)
            except ValueError:
                raise SkoolParsingError("Invalid integer '{}': {}".format(item, operation))
            if base == 'c':
                base = 'd'
        values.append((value, fmt[base].format(item)))
    return values[0][0], ':'.join([v[1] for v in values])
Exemplo n.º 7
0
def get_defw_length(operation, preserve_base):
    if preserve_base:
        word_fmt = FORMAT_PRESERVE_BASE
    else:
        word_fmt = FORMAT_NO_BASE
    full_length = 0
    lengths = []
    length = 0
    prev_base = None
    for item in split_operation(operation)[1:]:
        cur_base = _get_base(item, preserve_base)
        if prev_base != cur_base and length:
            lengths.append(word_fmt[prev_base].format(length))
            full_length += length
            length = 0
        length += 2
        prev_base = cur_base
    lengths.append(word_fmt[prev_base].format(length))
    full_length += length
    return full_length, ':'.join(lengths)
Exemplo n.º 8
0
def get_defw_length(operation, preserve_base):
    if preserve_base:
        word_fmt = FORMAT_PRESERVE_BASE
    else:
        word_fmt = FORMAT_NO_BASE
    full_length = 0
    lengths = []
    length = 0
    prev_base = None
    for item in split_operation(operation)[1:]:
        cur_base = _get_base(item, preserve_base)
        if prev_base != cur_base and length:
            lengths.append(word_fmt[prev_base].format(length))
            full_length += length
            length = 0
        length += 2
        prev_base = cur_base
    lengths.append(word_fmt[prev_base].format(length))
    full_length += length
    return full_length, ':'.join(lengths)
Exemplo n.º 9
0
def get_defb_length(operation, preserve_base):
    parts = split_operation(operation)
    if parts.pop(0).upper() == 'DEFB':
        byte_fmt = FORMAT_NO_BASE
        text_fmt = 'T{}'
    else:
        byte_fmt = {'b': 'b{}', 'd': 'B{}', 'h': 'B{}'}
        text_fmt = '{}'
    if preserve_base:
        byte_fmt = FORMAT_PRESERVE_BASE
    full_length = 0
    lengths = []
    length = 0
    prev_base = None
    for item in parts + ['""']:
        if item.startswith('"'):
            if length:
                lengths.append(byte_fmt[prev_base].format(length))
                full_length += length
                length = 0
                prev_base = None
            i = 1
            while i < len(item) - 1:
                if item[i] == '\\':
                    i += 1
                i += 1
                length += 1
            if length:
                lengths.append(text_fmt.format(length))
                full_length += length
                length = 0
        else:
            cur_base = _get_base(item, preserve_base)
            if prev_base != cur_base and length:
                lengths.append(byte_fmt[prev_base].format(length))
                full_length += length
                length = 0
            length += 1
            prev_base = cur_base
    return full_length, ':'.join(lengths)
Exemplo n.º 10
0
def get_defb_length(operation, preserve_base):
    parts = split_operation(operation)
    if parts.pop(0).upper() == 'DEFB':
        byte_fmt = FORMAT_NO_BASE
        text_fmt = 'T{}'
    else:
        byte_fmt = {'b': 'b{}', 'd': 'B{}', 'h': 'B{}'}
        text_fmt = '{}'
    if preserve_base:
        byte_fmt = FORMAT_PRESERVE_BASE
    full_length = 0
    lengths = []
    length = 0
    prev_base = None
    for item in parts + ['""']:
        c_data = parse_string(item)
        if c_data is not None:
            if length:
                lengths.append(byte_fmt[prev_base].format(length))
                full_length += length
                prev_base = None
            length = len(c_data)
            if length:
                lengths.append(text_fmt.format(length))
                full_length += length
                length = 0
        else:
            cur_base = _get_base(item, preserve_base)
            if cur_base == 'c':
                cur_base = 'd'
            if prev_base != cur_base and length:
                lengths.append(byte_fmt[prev_base].format(length))
                full_length += length
                length = 0
            length += 1
            prev_base = cur_base
    return full_length, ':'.join(lengths)
Exemplo n.º 11
0
def get_defb_length(operation, preserve_base):
    parts = split_operation(operation)
    if parts.pop(0).upper() == 'DEFB':
        byte_fmt = FORMAT_NO_BASE
        text_fmt = 'T{}'
    else:
        byte_fmt = {'b': 'b{}', 'd': 'B{}', 'h': 'B{}', 'm': 'm{}'}
        text_fmt = '{}'
    if preserve_base:
        byte_fmt = FORMAT_PRESERVE_BASE
    full_length = 0
    lengths = []
    length = 0
    prev_base = None
    for item in parts + ['""']:
        c_data = parse_string(item)
        if c_data is not None:
            if length:
                lengths.append(byte_fmt[prev_base].format(length))
                full_length += length
                prev_base = None
            length = len(c_data)
            if length:
                lengths.append(text_fmt.format(length))
                full_length += length
                length = 0
        else:
            cur_base = _get_base(item, preserve_base)
            if cur_base == 'c':
                cur_base = 'd'
            if prev_base != cur_base and length:
                lengths.append(byte_fmt[prev_base].format(length))
                full_length += length
                length = 0
            length += 1
            prev_base = cur_base
    return full_length, ':'.join(lengths)
Exemplo n.º 12
0
    def convert(self, operation, hex2fmt=None, hex4fmt=None):
        if operation.upper().startswith(('DEFB ', 'DEFM ', 'DEFS ', 'DEFW ')):
            if operation.upper().startswith('DEFW'):
                hex_fmt = hex4fmt
            else:
                hex_fmt = hex2fmt
            converted = operation[:4]
            for p in split_quoted(operation[4:]):
                if p.startswith('"'):
                    converted += p
                else:
                    converted += _replace_nums(p, hex_fmt)
            return converted

        elements = split_operation(operation, tidy=True)
        op = elements[0]

        # Instructions containing '(I[XY]+d)'
        if re.search('\(I[XY] *[+-].*\)', operation.upper()):
            return _replace_nums(operation, hex2fmt, op in ('BIT', 'RES', 'SET'))

        if op in ('CALL', 'DJNZ', 'JP', 'JR'):
            return _replace_nums(operation, hex4fmt)

        if op in ('AND', 'OR', 'XOR', 'SUB', 'CP', 'IN', 'OUT', 'ADD', 'ADC', 'SBC', 'RST'):
            return _replace_nums(operation, hex2fmt)

        if op == 'LD' and len(elements) == 3:
            operands = elements[1:]
            if operands[0] in ('A', 'B', 'C', 'D', 'E', 'H', 'L', 'IXL', 'IXH', 'IYL', 'IYH', '(HL)') and not operands[1].startswith('('):
                # LD r,n; LD (HL),n
                return _replace_nums(operation, hex2fmt)
            if not set(('A', 'BC', 'DE', 'HL', 'IX', 'IY', 'SP')).isdisjoint(operands):
                # LD A,(nn); LD (nn),A; LD rr,nn; LD rr,(nn); LD (nn),rr
                return _replace_nums(operation, hex4fmt)

        return operation