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
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)
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
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
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)
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])
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)
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)
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)
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)
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)
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