Esempio n. 1
0
    def _write_entry(self, entry, write_refs, show_text):
        has_end_directive = False
        for directive, value in entry.asm_directives:
            if directive == AD_END:
                has_end_directive = True
            else:
                self.write_asm_directive(directive, value)
        if entry.has_ignoreua_directive(TITLE):
            self.write_asm_directive(AD_IGNOREUA)

        if entry.ctl == 'i' and entry.blocks[-1].end >= 65536 and not entry.title and all([b.ctl == 'i' for b in entry.blocks]):
            return

        for block in entry.bad_blocks:
            warn('Code block at {} overlaps the following block at {}'.format(self.address_str(block.start, False), self.address_str(block.end, False)))

        if entry.title:
            self.write_comment(entry.title)
            wrote_desc = self._write_entry_description(entry, write_refs)
            if entry.registers:
                if not wrote_desc:
                    self._write_empty_paragraph()
                    wrote_desc = True
                self._write_registers(entry)
        else:
            wrote_desc = False

        self._write_body(entry, wrote_desc, write_refs, show_text)

        if entry.has_ignoreua_directive(END):
            self.write_asm_directive(AD_IGNOREUA)
        self.write_paragraphs(entry.end_comment)
        if has_end_directive:
            self.write_asm_directive(AD_END)
Esempio n. 2
0
    def _write_entry(self, entry, write_refs, show_text):
        if entry.header:
            for line in entry.header:
                write_line(line)
            write_line('')

        self.write_asm_directives(*entry.asm_directives)
        self.write_asm_directives(entry.get_ignoreua_directive(TITLE))

        if entry.ctl == 'i' and entry.blocks[-1].end >= 65536 and not entry.has_title and all([b.ctl == 'i' for b in entry.blocks]):
            return

        for block in entry.bad_blocks:
            addr1 = self.address_str(block.instructions[-1].address, False)
            addr2 = self.address_str(block.end, False)
            warn('Instruction at {} overlaps the following instruction at {}'.format(addr1, addr2))

        if entry.has_title:
            self.write_comment(entry.title)
            wrote_desc = self._write_entry_description(entry, write_refs)
            wrote_desc = self._write_registers(entry, wrote_desc)
        else:
            wrote_desc = False

        self._write_body(entry, wrote_desc, write_refs, show_text and entry.ctl != 't')

        self.write_asm_directives(entry.get_ignoreua_directive(END))
        self.write_paragraphs(entry.end_comment)

        if entry.footer:
            write_line('')
            for line in entry.footer:
                write_line(line)
Esempio n. 3
0
    def _write_entry(self, entry, write_refs, show_text):
        self.write_asm_directives(*entry.asm_directives)
        if entry.has_ignoreua_directive(TITLE):
            self.write_asm_directives(AD_IGNOREUA)

        if entry.ctl == 'i' and entry.blocks[
                -1].end >= 65536 and not entry.title and all(
                    [b.ctl == 'i' for b in entry.blocks]):
            return

        for block in entry.bad_blocks:
            warn('Code block at {} overlaps the following block at {}'.format(
                self.address_str(block.start, False),
                self.address_str(block.end, False)))

        if entry.title:
            self.write_comment(entry.title)
            wrote_desc = self._write_entry_description(entry, write_refs)
            if entry.registers:
                if not wrote_desc:
                    self._write_empty_paragraph()
                    wrote_desc = True
                self._write_registers(entry)
        else:
            wrote_desc = False

        self._write_body(entry, wrote_desc, write_refs, show_text)

        if entry.has_ignoreua_directive(END):
            self.write_asm_directives(AD_IGNOREUA)
        self.write_paragraphs(entry.end_comment)
Esempio n. 4
0
    def _write_entry(self, entry, write_refs, show_text):
        if entry.header:
            for line in entry.header:
                write_line(line)
            write_line('')

        self.write_asm_directives(*entry.asm_directives)
        if entry.has_ignoreua_directive(TITLE):
            self.write_asm_directives(AD_IGNOREUA)

        if entry.ctl == 'i' and entry.blocks[-1].end >= 65536 and not entry.has_title and all([b.ctl == 'i' for b in entry.blocks]):
            return

        for block in entry.bad_blocks:
            addr1 = self.address_str(block.instructions[-1].address, False)
            addr2 = self.address_str(block.end, False)
            warn('Instruction at {} overlaps the following instruction at {}'.format(addr1, addr2))

        if entry.has_title:
            self.write_comment(entry.title)
            wrote_desc = self._write_entry_description(entry, write_refs)
            wrote_desc = self._write_registers(entry, wrote_desc)
        else:
            wrote_desc = False

        self._write_body(entry, wrote_desc, write_refs, show_text and entry.ctl != 't')

        if entry.has_ignoreua_directive(END):
            self.write_asm_directives(AD_IGNOREUA)
        self.write_paragraphs(entry.end_comment)

        if entry.footer:
            write_line('')
            for line in entry.footer:
                write_line(line)
Esempio n. 5
0
 def _parse_instruction(self, line, removed):
     try:
         address = get_int_param(line[1:6])
     except ValueError:
         raise SkoolParsingError("Invalid address ({}):\n{}".format(
             line[1:6], line.rstrip()))
     original_op = partition_unquoted(line[6:], ';')[0].strip()
     subbed = max(self.subs)
     if subbed:
         operations = [
             partition_unquoted(s, ';') for s in self.subs[subbed]
         ]
     else:
         operations = [(original_op, '', '')]
     self.subs = defaultdict(list, {0: []})
     for op, sep, comment in operations:
         operation = op.strip() or original_op
         if operation:
             data = assemble(operation, address)
             if data:
                 end_address = address + len(data)
                 if address not in removed:
                     self.snapshot[address:end_address] = data
                     self.base_address = min(self.base_address, address)
                     self.end_address = max(self.end_address, end_address)
                 if subbed:
                     removed.update(range(address, end_address))
                 address = end_address
             else:
                 warn("Failed to assemble:\n {} {}".format(
                     address, operation))
                 break
         original_op = None
Esempio n. 6
0
 def _parse_instruction(self, line):
     try:
         address = get_int_param(line[1:6])
     except ValueError:
         raise SkoolParsingError("Invalid address ({}):\n{}".format(line[1:6], line.rstrip()))
     for sub in self.subs:
         if sub is not None:
             operation = sub
             self.subs = [None] * 4
             break
     else:
         comment_index = find_unquoted(line, ';', 6)
         operation = line[7:comment_index].strip()
     data = assemble(operation, address)
     if data:
         end_address = address + len(data)
         self.snapshot[address:end_address] = data
         self.base_address = min(self.base_address, address)
         self.end_address = max(self.end_address, end_address)
     else:
         warn("Failed to assemble:\n {} {}".format(address, operation))
Esempio n. 7
0
 def _parse_instruction(self, line):
     try:
         address = get_int_param(line[1:6])
     except ValueError:
         raise SkoolParsingError("Invalid address ({}):\n{}".format(line[1:6], line.rstrip()))
     for sub in self.subs:
         if sub is not None:
             operation = sub
             self.subs = [None] * 4
             break
     else:
         comment_index = find_unquoted(line, ';', 6)
         operation = line[7:comment_index].strip()
     data = assemble(operation, address)
     if data:
         end_address = address + len(data)
         self.snapshot[address:end_address] = data
         self.base_address = min(self.base_address, address)
         self.end_address = max(self.end_address, end_address)
     else:
         warn("Failed to assemble:\n {} {}".format(address, operation))
Esempio n. 8
0
 def warn(self, s):
     if self.mode.warn:
         warn(s)
Esempio n. 9
0
    def parse_ctl(self, ctlfile, min_address=0, max_address=65536):
        entry_ctl = None
        f = open_file(ctlfile)
        for line_no, line in enumerate(f, 1):
            s_line = line.rstrip()
            if not s_line:
                continue
            try:
                ctl, start, end, text, lengths, asm_directive = self._parse_ctl_line(s_line, entry_ctl)
            except CtlParserError as e:
                warn('Ignoring line {} in {} ({}):\n{}'.format(line_no, ctlfile, e.args[0], s_line))
                continue
            if ctl:
                ctl = ctl.strip()
                if ctl.islower():
                    entry_ctl = ctl
                if not min_address <= start < max_address:
                    continue
                if ctl.islower():
                    self._ctls[start] = ctl
                    self._titles[start] = text
                elif ctl in 'D':
                    self._descriptions.setdefault(start, []).append(text)
                    self._subctls.setdefault(start, None)
                elif ctl in 'N':
                    self._mid_block_comments.setdefault(start, []).append(text)
                    self._subctls.setdefault(start, None)
                elif ctl == 'E':
                    self._end_comments.setdefault(start, []).append(text)
                elif ctl == 'R':
                    if text:
                        fields = text.split(' ', 1)
                        if len(fields) == 1:
                            fields.append('')
                        self._registers.setdefault(start, []).append(fields)
                elif ctl == 'M':
                    self._multiline_comments[start] = (end, text)
                    self._subctls.setdefault(start, None)
                elif ctl == 'L':
                    count = lengths[0][0]
                    if count > 1:
                        if len(lengths) > 1:
                            repeat_entries = lengths[1][0]
                        else:
                            repeat_entries = 0
                        loop_end = start + count * (end - start)
                        if loop_end > 65536:
                            warn('Loop crosses 64K boundary:\n{}'.format(s_line))
                        self._loops.append((start, end, count, repeat_entries))
                        self._subctls[loop_end] = None
                else:
                    self._subctls[start] = ctl.lower()
                    self._instruction_comments[start] = text
                    if end:
                        self._subctls[end] = None
                if ctl != 'L' and lengths:
                    self._lengths[start] = lengths[0][1]
                    if len(lengths) > 1:
                        address = start + lengths[0][0]
                        subctl = self._subctls[start]
                        for length, sublengths in lengths[1:]:
                            self._lengths[address] = sublengths
                            self._subctls[address] = subctl
                            address += length
                        if text:
                            self._multiline_comments[start] = (address, text)
            elif asm_directive:
                directive, address = asm_directive
                self._asm_directives.setdefault(address, []).append(directive)
        f.close()

        self._terminate_multiline_comments()
        self._unroll_loops(max_address)
        self._ctls[max_address] = 'i'
Esempio n. 10
0
    def parse_ctl(self, ctlfile, min_address=0, max_address=65536):
        ctl_lines = []
        with open_file(ctlfile) as f:
            for line in f:
                s_line = line.rstrip()
                if s_line:
                    ctl_lines.append(s_line)
                    if s_line.startswith(
                        ('b', 'c', 'g', 'i', 's', 't', 'u', 'w')):
                        try:
                            address = get_int_param(s_line[1:].lstrip().split(
                                ' ', 1)[0])
                            if min_address <= address < max_address:
                                self._ctls[address] = s_line[0]
                        except ValueError:
                            pass
        entry_addresses = sorted(self._ctls)

        for line_no, s_line in enumerate(ctl_lines, 1):
            try:
                ctl, start, end, text, lengths, asm_directive = self._parse_ctl_line(
                    s_line, entry_addresses)
            except CtlParserError as e:
                warn('Ignoring line {} in {} ({}):\n{}'.format(
                    line_no, ctlfile, e.args[0], s_line))
                continue
            if ctl:
                if not min_address <= start < max_address:
                    continue
                if ctl == '>':
                    if end:
                        self._footers[start].append(text or '')
                    else:
                        self._headers[start].append(text or '')
                elif ctl.islower():
                    self._titles[start] = text
                elif ctl == 'D':
                    self._descriptions.setdefault(start, []).append(text)
                    self._subctls.setdefault(start, None)
                elif ctl == 'N':
                    self._mid_block_comments.setdefault(start, []).append(text)
                    self._subctls.setdefault(start, None)
                elif ctl == 'E':
                    self._end_comments.setdefault(start, []).append(text)
                elif ctl == 'R':
                    if text:
                        fields = text.split(' ', 1)
                        if len(fields) == 1:
                            fields.append('')
                        self._registers.setdefault(start, []).append(fields)
                elif ctl == 'M':
                    self._multiline_comments[start] = (end, text)
                    self._subctls.setdefault(start, None)
                elif ctl == 'L':
                    count = lengths[0][0]
                    if count > 1:
                        if len(lengths) > 1:
                            repeat_entries = lengths[1][0]
                        else:
                            repeat_entries = 0
                        loop_end = start + count * (end - start)
                        if loop_end > 65536:
                            warn('Loop crosses 64K boundary:\n{}'.format(
                                s_line))
                        self._loops.append((start, end, count, repeat_entries))
                        self._subctls[loop_end] = None
                else:
                    self._subctls[start] = ctl.lower()
                    self._instruction_comments[start] = text
                    if end:
                        self._subctls[end] = None
                if ctl != 'L' and lengths:
                    self._lengths[start] = lengths[0][1]
                    if len(lengths) > 1:
                        address = start + lengths[0][0]
                        subctl = self._subctls[start]
                        for length, sublengths in lengths[1:]:
                            self._lengths[address] = sublengths
                            self._subctls[address] = subctl
                            address += length
                        if text:
                            self._multiline_comments[start] = (address, text)
            elif asm_directive:
                directive, address = asm_directive
                self._asm_directives.setdefault(address, []).append(directive)

        self._terminate_multiline_comments()
        self._unroll_loops(max_address)
        self._ctls[max_address] = 'i'
Esempio n. 11
0
 def _warn(self, message, instruction):
     if self.warn:
         warn('{}:\n  {}'.format(message, instruction))
Esempio n. 12
0
 def warn(self, s):
     if self.show_warnings:
         warn(s)
Esempio n. 13
0
 def warn(self, s):
     if self.show_warnings:
         warn(s)
Esempio n. 14
0
    def parse_ctls(self, ctlfiles, min_address=0, max_address=65536):
        ctl_lines = []
        for ctlfile in ctlfiles:
            self._parse_ctl_file(ctlfile, ctl_lines, min_address, max_address)

        entry_addresses = sorted(self._ctls)

        ctl_addr = None
        comment = []
        for line_no, s_line in enumerate(ctl_lines, 1):
            try:
                ctl, start, end, text, lengths, asm_directive = self._parse_ctl_line(s_line, entry_addresses)
            except CtlParserError as e:
                warn('Ignoring line {} in {} ({}):\n{}'.format(line_no, ctlfile, e.args[0], s_line))
                continue
            if ctl:
                if ctl in '.:':
                    if ctl_addr is not None and min_address <= ctl_addr < max_address:
                        comment.append(('.:'.index(ctl), text))
                    continue
                ctl_addr = start
                if not min_address <= start < max_address:
                    continue
                comment = [(0, text or '')]
                if ctl == '>':
                    if end:
                        self._footers[start].append(text or '')
                    else:
                        self._headers[start].append(text or '')
                    if text and text.startswith(('@defb=', '@defs=', '@defw=')):
                        self._asm_data_directives[start].append(text[1:])
                elif ctl.islower():
                    self._titles[start] = comment
                elif ctl == 'D':
                    self._descriptions[start].append(comment)
                    self._subctls.setdefault(start, None)
                elif ctl == 'N':
                    self._mid_block_comments[start].append(comment)
                    self._subctls.setdefault(start, None)
                elif ctl == 'E':
                    self._end_comments[start].append(comment)
                elif ctl == 'R':
                    self._registers[start].append(comment)
                elif ctl == 'M':
                    self._multiline_comments[start] = (end, comment)
                    self._subctls.setdefault(start, None)
                elif ctl == 'L':
                    count = lengths[0][0]
                    if count > 1:
                        if len(lengths) > 1:
                            repeat_entries = lengths[1][0]
                        else:
                            repeat_entries = 0
                        loop_end = start + count * (end - start)
                        if loop_end > 65536:
                            warn('Loop crosses 64K boundary:\n{}'.format(s_line))
                        self._loops.append((start, end, count, repeat_entries))
                        self._subctls[loop_end] = None
                else:
                    self._subctls[start] = ctl.lower()
                    self._instruction_comments[start] = comment
                    if end:
                        self._subctls[end] = None
                if ctl != 'L' and lengths:
                    self._lengths[start] = lengths[0][1]
                    if len(lengths) > 1:
                        address = start + lengths[0][0]
                        subctl = self._subctls[start]
                        for length, sublengths in lengths[1:]:
                            self._lengths[address] = sublengths
                            self._subctls[address] = subctl
                            address += length
                        self._multiline_comments.setdefault(start, (address, comment))
            elif asm_directive:
                directive, address = asm_directive
                self._asm_directives[address].append(directive)

        self._terminate_multiline_comments()
        self._unroll_loops(max_address)
        self._ctls[max_address] = 'i'
Esempio n. 15
0
    def parse_ctls(self, ctlfiles, min_address=0, max_address=65536):
        ctl_lines = []
        for ctlfile in ctlfiles:
            self._parse_ctl_file(ctlfile, ctl_lines, min_address, max_address)

        entry_addresses = sorted(self._ctls)

        comment = []
        for line_no, s_line in enumerate(ctl_lines, 1):
            try:
                ctl, start, end, text, lengths, asm_directive = self._parse_ctl_line(s_line, entry_addresses)
            except CtlParserError as e:
                warn('Ignoring line {} in {} ({}):\n{}'.format(line_no, ctlfile, e.args[0], s_line))
                continue
            if ctl:
                if ctl in '.:':
                    comment.append(('.:'.index(ctl), text))
                    continue
                if not min_address <= start < max_address:
                    continue
                comment = [(0, text or '')]
                if ctl == '>':
                    if end:
                        self._footers[start].append(text or '')
                    else:
                        self._headers[start].append(text or '')
                elif ctl.islower():
                    self._titles[start] = comment
                elif ctl == 'D':
                    self._descriptions[start].append(comment)
                    self._subctls.setdefault(start, None)
                elif ctl == 'N':
                    self._mid_block_comments[start].append(comment)
                    self._subctls.setdefault(start, None)
                elif ctl == 'E':
                    self._end_comments[start].append(comment)
                elif ctl == 'R':
                    self._registers[start].append(comment)
                elif ctl == 'M':
                    self._multiline_comments[start] = (end, comment)
                    self._subctls.setdefault(start, None)
                elif ctl == 'L':
                    count = lengths[0][0]
                    if count > 1:
                        if len(lengths) > 1:
                            repeat_entries = lengths[1][0]
                        else:
                            repeat_entries = 0
                        loop_end = start + count * (end - start)
                        if loop_end > 65536:
                            warn('Loop crosses 64K boundary:\n{}'.format(s_line))
                        self._loops.append((start, end, count, repeat_entries))
                        self._subctls[loop_end] = None
                else:
                    self._subctls[start] = ctl.lower()
                    self._instruction_comments[start] = comment
                    if end:
                        self._subctls[end] = None
                if ctl != 'L' and lengths:
                    self._lengths[start] = lengths[0][1]
                    if len(lengths) > 1:
                        address = start + lengths[0][0]
                        subctl = self._subctls[start]
                        for length, sublengths in lengths[1:]:
                            self._lengths[address] = sublengths
                            self._subctls[address] = subctl
                            address += length
                        self._multiline_comments[start] = (address, comment)
            elif asm_directive:
                directive, address = asm_directive
                self._asm_directives[address].append(directive)

        self._terminate_multiline_comments()
        self._unroll_loops(max_address)
        self._ctls[max_address] = 'i'
Esempio n. 16
0
 def warn(self, s):
     if self.mode.warn:
         warn(s)