示例#1
0
    def test_word_formats_hex(self):
        snapshot = [240] * 8
        ctl = '\n'.join((
            'w 00000',
            '  00000,8,b2,d2,h2,2',
            'i 00008'
        ))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(self.write_text_file(ctl))
        disassembly = Disassembly(snapshot, ctl_parser, True, asm_hex=True)

        entries = disassembly.entries
        self.assertEqual(len(entries), 2)

        entry = entries[0]
        self.assertEqual(entry.address, 0)
        instructions = entry.instructions
        actual_instructions = [(i.address, i.operation) for i in instructions]
        exp_instructions = [
            (0, 'DEFW %1111000011110000'),
            (2, 'DEFW 61680'),
            (4, 'DEFW $F0F0'),
            (6, 'DEFW $F0F0')
        ]
        self.assertEqual(exp_instructions, actual_instructions)
示例#2
0
 def test_invalid_lines(self):
     ctl_specs = [
         ('  30000,1',        'blank directive with no containing block'),
         ('B 30745,15,5:X10', 'invalid integer'),
         ('T 30760,5,2:Y3',   'invalid integer'),
         ('W 30765,5,1:B4',   'invalid integer'),
         ('S 30770,10,T8:2',  'invalid integer'),
         ('C 40000,Q',        'invalid integer'),
         ('; @label:EDCBA=Z', 'invalid ASM directive address'),
         ('; @label=Z',       'invalid ASM directive declaration'),
         ('b 50000,20',       'extra parameters after address'),
         ('d 50020',          'invalid directive'),
         ('! 50030',          'invalid directive')
     ]
     ctls = [spec[0] for spec in ctl_specs]
     ctl_parser = CtlParser()
     ctlfile = self.write_text_file('\n'.join(ctls))
     ctl_parser.parse_ctl(ctlfile)
     exp_warnings = []
     for line_no, (ctl, error_msg) in enumerate(ctl_specs, 1):
         if error_msg:
             exp_warnings.append('WARNING: Ignoring line {} in {} ({}):'.format(line_no, ctlfile, error_msg))
     warnings = self.err.getvalue().split('\n')[:-1]
     self.assertEqual(exp_warnings, warnings[0::2])
     invalid_ctls = [spec[0] for spec in ctl_specs if spec[1]]
     self.assertEqual(invalid_ctls, warnings[1::2])
示例#3
0
    def test_word_formats(self):
        ctl = '\n'.join((
            'w 40000 Test word formats',
            '  40000,10 5 default',
            '  40010,b10 5 words in binary format',
            'W 40020,b10,6,d2,h2 3 binary, 1 decimal, 1 hex',
            'W 40030,b10,4:d4:h2 2 binary, 2 decimal, 1 hex, one line',
            '  40040,10,b2,4,h4 1 binary, 2 default, 2 hex',
            '  40050,10,b2:6:h2 1 binary, 3 default, 1 hex, one line',
        ))
        ctl_parser = CtlParser()
        ctlfile = self.write_text_file(ctl)
        ctl_parser.parse_ctl(ctlfile)

        exp_lengths = {
            40010: [(None, [(None, 'b')])],
            40020: [
                (6, [(6, 'b')]),
                (2, [(2, 'd')]),
                (2, [(2, 'h')])
            ],
            40030: [(10, [(4, 'b'), (4, 'd'), (2, 'h')])],
            40040: [
                (2, [(2, 'b')]),
                (4, None),
                (4, [(4, 'h')])
            ],
            40050: [(10, [(2, 'b'), (6, None), (2, 'h')])]
        }
        self.assertEqual(exp_lengths, ctl_parser.lengths)
示例#4
0
    def test_s_directives(self):
        snapshot = []
        ctl = '\n'.join((
            's 00000',
            '  00000,4',
            '  00004,b4',
            'S 00008,d4',
            '  00012,h8',
            '  00020,40,b10,10,h10',
            'S 00060,b40,10,d10,h10',
            '  00100,d40,b10,10,h10',
            '  00140,h60,b10,d10,40',
            'S 00200,768,b256,d256,h256',
            '  00968,56,16:b%10101010,40:h17',
            'i 01024'
        ))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(self.write_text_file(ctl))
        disassembly = Disassembly(snapshot, ctl_parser, True)

        entries = disassembly.entries
        self.assertEqual(len(entries), 2)

        entry = entries[0]
        self.assertEqual(entry.address, 0)
        instructions = entry.instructions
        actual_instructions = [(i.address, i.operation) for i in instructions]
        exp_instructions = [
            (  0, 'DEFS 4'),
            (  4, 'DEFS %00000100'),
            (  8, 'DEFS 4'),
            ( 12, 'DEFS 8'),
            ( 20, 'DEFS %00001010'),
            ( 30, 'DEFS 10'),
            ( 40, 'DEFS $0A'),
            ( 50, 'DEFS $0A'),
            ( 60, 'DEFS %00001010'),
            ( 70, 'DEFS 10'),
            ( 80, 'DEFS $0A'),
            ( 90, 'DEFS $0A'),
            (100, 'DEFS %00001010'),
            (110, 'DEFS 10'),
            (120, 'DEFS $0A'),
            (130, 'DEFS $0A'),
            (140, 'DEFS %00001010'),
            (150, 'DEFS 10'),
            (160, 'DEFS $28'),
            (200, 'DEFS %0000000100000000'),
            (456, 'DEFS 256'),
            (712, 'DEFS $0100'),
            (968, 'DEFS 16,%10101010'),
            (984, 'DEFS 40,$11')
        ]
        self.assertEqual(exp_instructions, actual_instructions)
示例#5
0
    def test_byte_formats(self):
        snapshot = [42] * 75
        ctl = '\n'.join((
            'b 00000',
            '  00000,b5',
            '  00005,b15',
            '  00020,b5,2,d2,h1',
            'B 00025,b5,2:d2:h1',
            '  00030,h10,5:d3:b2',
            'B 00040,5,b1,h2',
            '  00045,5,h1,T4',
            '  00050,5,b2:T3',
            'T 00055,5,h2,3',
            'T 00060,5,2:d3',
            'T 00065,5,3,B1',
            'T 00070,5,B2:h3',
            'i 00075'
        ))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(self.write_text_file(ctl))
        disassembly = Disassembly(snapshot, ctl_parser, True)

        entries = disassembly.entries
        self.assertEqual(len(entries), 2)

        entry = entries[0]
        self.assertEqual(entry.address, 0)
        instructions = entry.instructions
        actual_instructions = [(i.address, i.operation) for i in instructions]
        exp_instructions = [
            ( 0, 'DEFB %00101010,%00101010,%00101010,%00101010,%00101010'),
            ( 5, 'DEFB %00101010,%00101010,%00101010,%00101010,%00101010,%00101010,%00101010,%00101010'),
            (13, 'DEFB %00101010,%00101010,%00101010,%00101010,%00101010,%00101010,%00101010'),
            (20, 'DEFB %00101010,%00101010'),
            (22, 'DEFB 42,42'),
            (24, 'DEFB $2A'),
            (25, 'DEFB %00101010,%00101010,42,42,$2A'),
            (30, 'DEFB $2A,$2A,$2A,$2A,$2A,42,42,42,%00101010,%00101010'),
            (40, 'DEFB %00101010'),
            (41, 'DEFB $2A,$2A'),
            (43, 'DEFB $2A,$2A'),
            (45, 'DEFB $2A'),
            (46, 'DEFB "****"'),
            (50, 'DEFB %00101010,%00101010,"***"'),
            (55, 'DEFM $2A,$2A'),
            (57, 'DEFM "***"'),
            (60, 'DEFM "**",42,42,42'),
            (65, 'DEFM "***"'),
            (68, 'DEFM 42'),
            (69, 'DEFM 42'),
            (70, 'DEFM 42,42,$2A,$2A,$2A')
        ]
        self.assertEqual(actual_instructions, exp_instructions)
示例#6
0
    def test_s_directives(self):
        ctl = '\n'.join((
            's 50000 Test s/S directives',
            '  50000,10',
            '  50010,b10',
            '  50020,d10',
            '  50030,h10',
            'S 50040,b20,5,d5,h5',
            'S 50060,d20,b5,5,h5',
            'S 50080,h20,b5,d5,5',
            '  50100,20,b5,d5,5',
            '  50120,20,d20:b%10001000',
            '  50140,20,20:h$44',
            '  50160,12,10:h10,h2:2'
        ))
        ctl_parser = CtlParser()
        ctlfile = self.write_text_file(ctl)
        ctl_parser.parse_ctl(ctlfile)

        exp_lengths = {
            50010: [(None, [(None, 'b')])],
            50020: [(None, [(None, 'd')])],
            50030: [(None, [(None, 'h')])],
            50040: [
                (5, [(5, 'b')]),
                (5, [(5, 'd')]),
                (5, [(5, 'h')])
            ],
            50060: [
                (5, [(5, 'b')]),
                (5, [(5, 'd')]),
                (5, [(5, 'h')])
            ],
            50080: [
                (5, [(5, 'b')]),
                (5, [(5, 'd')]),
                (5, [(5, 'h')])
            ],
            50100: [
                (5, [(5, 'b')]),
                (5, [(5, 'd')]),
                (5, None)
            ],
            50120: [(20, [(20, 'd'), (136, 'b')])],
            50140: [(20, [(20, None), (68, 'h')])],
            50160: [
                (10, [(10, None), (10, 'h')]),
                (2, [(2, 'h'), (2, None)]),
            ]
        }
        self.assertEqual(exp_lengths, ctl_parser.lengths)
示例#7
0
    def test_comments(self):
        ctl = '\n'.join((
            '# This is a comment',
            'b 32768',
            '% This is also a comment',
            'w 32769',
            '; This is a comment too'
        ))
        ctl_parser = CtlParser()
        ctlfile = self.write_text_file(ctl)
        ctl_parser.parse_ctl(ctlfile)

        self.assertEqual(self.err.getvalue(), '')
        self.assertEqual({32768: 'b', 32769: 'w'}, ctl_parser.ctls)
示例#8
0
    def test_word_formats(self):
        snapshot = [170, 53] * 32
        ctl = '\n'.join((
            'w 00000',
            '  00000,4',
            '  00004,b4',
            '  00008,d4',
            'W 00012,h4',
            'W 00016,b8,2,d2,h4',
            '  00024,d8,b4:2:h2',
            '  00032,h8,b2:d4:2',
            '  00040,8,b2,4,h2',
            'W 00048,8,b2:2:h4',
            '  00056,8,4',
            'i 00064'
        ))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(self.write_text_file(ctl))
        disassembly = Disassembly(snapshot, ctl_parser, True)

        entries = disassembly.entries
        self.assertEqual(len(entries), 2)

        entry = entries[0]
        self.assertEqual(entry.address, 0)
        instructions = entry.instructions
        actual_instructions = [(i.address, i.operation) for i in instructions]
        exp_instructions = [
            ( 0, 'DEFW 13738'),
            ( 2, 'DEFW 13738'),
            ( 4, 'DEFW %0011010110101010'),
            ( 6, 'DEFW %0011010110101010'),
            ( 8, 'DEFW 13738'),
            (10, 'DEFW 13738'),
            (12, 'DEFW $35AA'),
            (14, 'DEFW $35AA'),
            (16, 'DEFW %0011010110101010'),
            (18, 'DEFW 13738'),
            (20, 'DEFW $35AA,$35AA'),
            (24, 'DEFW %0011010110101010,%0011010110101010,13738,$35AA'),
            (32, 'DEFW %0011010110101010,13738,13738,$35AA'),
            (40, 'DEFW %0011010110101010'),
            (42, 'DEFW 13738,13738'),
            (46, 'DEFW $35AA'),
            (48, 'DEFW %0011010110101010,13738,$35AA,$35AA'),
            (56, 'DEFW 13738,13738'),
            (60, 'DEFW 13738,13738')
        ]
        self.assertEqual(actual_instructions, exp_instructions)
示例#9
0
    def test_byte_formats(self):
        ctl = '\n'.join((
            'b 40000 Test byte formats',
            '  40000,b10 10 bytes in binary format',
            'B 40010,b10,5,d3,h2 5 binary, 3 decimal, 2 hex',
            'B 40020,b10,2:d3:h5 2 binary, 3 decimal, 5 hex, one line',
            '  40030,10,b6,3,h1 6 binary, 3 default, 1 hex',
            '  40040,10,b5:2:h3 5 binary, 2 default, 3 hex, one line',
            '  40050,10,1,T9 1 default, 9 text',
            '  40060,10,h4:T6 4 hex, 6 text, one line',
            'T 40070,10,3,b7 3 text, 7 binary',
            'T 40080,10,2:h8 2 text, 8 hex, one line',
            'T 40090,10,5,B5 5 text, 5 default'
        ))
        ctl_parser = CtlParser()
        ctlfile = self.write_text_file(ctl)
        ctl_parser.parse_ctl(ctlfile)

        exp_lengths = {
            40000: [(None, [(None, 'b')])],
            40010: [
                (5, [(5, 'b')]),
                (3, [(3, 'd')]),
                (2, [(2, 'h')])
            ],
            40020: [(10, [(2, 'b'), (3, 'd'), (5, 'h')])],
            40030: [
                (6, [(6, 'b')]),
                (3, None),
                (1, [(1, 'h')])
            ],
            40040: [(10, [(5, 'b'), (2, None), (3, 'h')])],
            40050: [
                (1, None),
                (9, [(9, 'T')])
            ],
            40060: [(10, [(4, 'h'), (6, 'T')])],
            40070: [
                (3, None),
                (7, [(7, 'b')])
            ],
            40080: [(10, [(2, None), (8, 'h')])],
            40090: [
                (5, None),
                (5, [(5, 'B')])
            ],
        }
        self.assertEqual(exp_lengths, ctl_parser.lengths)
示例#10
0
 def test_invalid_lines(self):
     ctl_specs = [
         ('  30000,1',           'blank directive with no containing block'),
         ('B 30745,15,5:X10',    'invalid integer'),
         ('T 30760,5,2:Y3',      'invalid integer'),
         ('W 30765,5,1:B4',      'invalid integer'),
         ('S 30770,10,T8:2',     'invalid integer'),
         ('B 30780,10,h,5',      'invalid integer'),
         ('C 40000,Q',           'invalid integer'),
         ('@ FEDCB label=Z',     'invalid ASM directive address'),
         ('@ 49152',             'invalid ASM directive declaration'),
         ('b 50000,20',          'extra parameters after address'),
         ('c 50000,20',          'extra parameters after address'),
         ('g 50000,20',          'extra parameters after address'),
         ('i 50000,20',          'extra parameters after address'),
         ('s 50000,20',          'extra parameters after address'),
         ('t 50000,20',          'extra parameters after address'),
         ('u 50000,20',          'extra parameters after address'),
         ('w 50000,20',          'extra parameters after address'),
         ('D 50000,20 Desc.',    'extra parameters after address'),
         ('E 50000,20 End.',     'extra parameters after address'),
         ('N 50000,20 Note.',    'extra parameters after address'),
         ('R 50000,20 A 10',     'extra parameters after address'),
         ('b b50010',            'invalid address'),
         ('d 50020',             'invalid directive'),
         ('! 50030',             'invalid directive'),
         ('@ 50000 ignoreua:g',  "invalid @ignoreua directive suffix: 'g'"),
         ('L 51000',             'loop length not specified'),
         ('L 51000,10',          'loop count not specified')
     ]
     ctls = [spec[0] for spec in ctl_specs]
     ctl_parser = CtlParser()
     ctlfile = self.write_text_file('\n'.join(ctls))
     ctl_parser.parse_ctl(ctlfile)
     exp_warnings = []
     for line_no, (ctl, error_msg) in enumerate(ctl_specs, 1):
         if error_msg:
             exp_warnings.append('WARNING: Ignoring line {} in {} ({}):'.format(line_no, ctlfile, error_msg))
     warnings = self.err.getvalue().split('\n')[:-1]
     self.assertEqual(exp_warnings, warnings[0::2])
     invalid_ctls = [spec[0] for spec in ctl_specs if spec[1]]
     self.assertEqual(invalid_ctls, warnings[1::2])
示例#11
0
    def test_byte_formats_hex(self):
        snapshot = [85] * 4
        ctl = '\n'.join((
            'b 00000',
            '  00000,4,b1:d1:h1:1',
            'i 00004'
        ))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(self.write_text_file(ctl))
        disassembly = Disassembly(snapshot, ctl_parser, True, asm_hex=True)

        entries = disassembly.entries
        self.assertEqual(len(entries), 2)

        entry = entries[0]
        self.assertEqual(entry.address, 0)
        instructions = entry.instructions
        self.assertEqual(len(instructions), 1)
        defb = instructions[0]
        self.assertEqual(defb.operation, 'DEFB %01010101,85,$55,$55')
示例#12
0
def run(snafile, options):
    # Read the snapshot file
    if snafile[-4:].lower() in ('.sna', '.szx', '.z80'):
        snapshot = get_snapshot(snafile, options.page)
        start = max(START, options.start)
    else:
        ram = read_bin_file(snafile)
        if options.org is None:
            org = 65536 - len(ram)
        else:
            org = options.org
        snapshot = [0] * org
        snapshot.extend(ram)
        start = max(org, options.start)
    end = min(options.end, len(snapshot))

    # Pad out the end of the snapshot to avoid disassembly errors when an
    # instruction crosses the 64K boundary
    snapshot += [0] * (65539 - len(snapshot))

    if options.sftfile:
        # Use a skool file template
        info('Using skool file template: {}'.format(options.sftfile))
        writer = SftParser(snapshot, options.sftfile, options.zfill, options.asm_hex, options.asm_lower)
        writer.write_skool(options.start, options.end)
        return

    if options.genctlfile:
        # Generate a control file
        ctls = generate_ctls(snapshot, start, end, options.code_map)
        write_ctl(options.genctlfile, ctls, options.ctl_hex)
        ctl_parser = CtlParser(ctls)
    elif options.ctlfile:
        # Use a control file
        info('Using control file: {}'.format(options.ctlfile))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(options.ctlfile, options.start, options.end)
    else:
        ctl_parser = CtlParser({start: 'c', end: 'i'})
    writer = SkoolWriter(snapshot, ctl_parser, options)
    writer.write_skool(options.write_refs, options.text)
示例#13
0
def run(snafile, options, config):
    # Read the snapshot file
    if snafile[-4:].lower() in ('.sna', '.szx', '.z80'):
        snapshot = get_snapshot(snafile, options.page)
        start = max(START, options.start)
    else:
        ram = read_bin_file(snafile, 65536)
        if options.org is None:
            org = 65536 - len(ram)
        else:
            org = options.org
        snapshot = [0] * org
        snapshot.extend(ram)
        start = max(org, options.start)
    end = min(options.end, len(snapshot))

    snapshot += [0] * (65536 - len(snapshot))

    if options.sftfile:
        # Use a skool file template
        info('Using skool file template: {}'.format(options.sftfile))
        writer = SftParser(snapshot, options.sftfile, options.zfill,
                           options.base == 16, options.case == 1)
        writer.write_skool(options.start, options.end)
        return

    if options.genctlfile:
        # Generate a control file
        ctls = generate_ctls(snapshot, start, end, options.code_map)
        write_ctl(options.genctlfile, ctls, options.ctl_hex)
        ctl_parser = CtlParser(ctls)
    elif options.ctlfile:
        # Use a control file
        info('Using control file: {}'.format(options.ctlfile))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(options.ctlfile, options.start, options.end)
    else:
        ctl_parser = CtlParser({start: 'c', end: 'i'})
    writer = SkoolWriter(snapshot, ctl_parser, options, config)
    writer.write_skool(options.write_refs, options.text)
示例#14
0
    def test_s_directives_hex(self):
        snapshot = []
        ctl = '\n'.join((
            's 00000',
            '  00000,14,d2:b1,h2:128,h10:2',
            'i 00014'
        ))
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(self.write_text_file(ctl))
        disassembly = Disassembly(snapshot, ctl_parser, True, asm_hex=True)

        entries = disassembly.entries
        self.assertEqual(len(entries), 2)

        entry = entries[0]
        self.assertEqual(entry.address, 0)
        instructions = entry.instructions
        actual_instructions = [(i.address, i.operation) for i in instructions]
        exp_instructions = [
            (0, 'DEFS 2,%00000001'),
            (2, 'DEFS 2,$80'),
            (4, 'DEFS $0A,2')
        ]
        self.assertEqual(exp_instructions, actual_instructions)
示例#15
0
    def test_parse_ctl(self):
        ctl_parser = CtlParser()
        ctlfile = self.write_text_file(CTL)
        ctl_parser.parse_ctl(ctlfile)

        exp_ctls = {
            30000: 'b',
            30100: 'c',
            30200: 'g',
            30300: 'i',
            30400: 't',
            30500: 'u',
            30600: 'w',
            30700: 's'
        }
        self.assertEqual(exp_ctls, ctl_parser.ctls)

        exp_subctls = {
            30002: 't',
            30012: 'w',
            30020: 'c',
            30027: None,
            30050: 'b',
            30055: None,
            30100: None,
            30200: 'b',
            30210: None,
            30450: 't',
            30457: None,
            30500: 'b',
            30502: 'b',
            30505: None,
            30510: 'b',
            30522: None,
            30530: 'b',
            30550: None,
            30560: 'b',
            30581: None,
            30620: 's',
            30627: None,
            30720: 'b',
            30730: 't',
            30745: None
        }
        self.assertEqual(exp_subctls, ctl_parser.subctls)

        exp_titles = {
            30000: 'Data at 30000',
            30100: 'Routine at 30100',
            30200: 'Game status buffer entry at 30200',
            30300: 'Ignored block at 30300',
            30400: 'Message at 30400',
            30500: 'Unused block at 30500',
            30600: 'Words at 30600',
            30700: 'Zeroes at 30700'
        }
        self.assertEqual(exp_titles, ctl_parser.titles)

        exp_instruction_comments = {
            30002: 'Message in the data block',
            30012: None,
            30020: None,
            30050: 'Complex DEFB with a blank directive',
            30200: "Blank directive in a 'g' block",
            30450: 'Complex DEFM with a blank directive',
            30500: "Blank directive in a 'u' block",
            30502: None,
            30510: None,
            30530: None,
            30560: None,
            30620: None,
            30720: None,
            30730: None
        }
        self.assertEqual(exp_instruction_comments, ctl_parser.instruction_comments)

        exp_comments = {
            30100: ['Description of routine at 30100']
        }
        self.assertEqual(exp_comments, ctl_parser.comments)

        exp_registers = {
            30100: [['A', 'Some value'], ['BC', 'Some other value']]
        }
        self.assertEqual(exp_registers, ctl_parser.registers)

        exp_end_comments = {
            30100: ['First paragraph of the end comment for the routine at 30100',
                    'Second paragraph of the end comment for the routine at 30100']
        }
        self.assertEqual(exp_end_comments, ctl_parser.end_comments)

        exp_lengths = {
            30050: [(5, [(3, None), (2, 'T')])],
            30200: [(1, None)],
            30450: [(7, [(4, None), (3, 'B')])],
            30510: [(3, None)],
            30530: list(zip([2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3], [None] * 11)),
            30560: list(zip([6, 5, 4, 3, 2, 1], [None] * 6)),
            30720: [
                (1, None),
                (5, [(3, 'T'), (2, None)]),
                (2, [(1, None), (1, 'T')]),
                (2, [(1, None), (1, 'T')])
            ],
            30730: [(15, [(10, None), (5, 'B')])]
        }
        self.assertEqual(exp_lengths, ctl_parser.lengths)

        exp_multiline_comments = {
            30012: (30026, 'This comment covers the following two sub-blocks')
        }
        self.assertEqual(exp_multiline_comments, ctl_parser.multiline_comments)

        exp_entry_asm_directives = {
            30000: [('start', None)]
        }
        self.assertEqual(exp_entry_asm_directives, ctl_parser.entry_asm_directives)

        exp_instruction_asm_directives = {
            30101: [('label', 'LOOP')]
        }
        self.assertEqual(exp_instruction_asm_directives, ctl_parser.instruction_asm_directives)
示例#16
0
 def _get_writer(self, snapshot, ctl, defb_size=8, defb_mod=1, zfill=False, defm_width=66, asm_hex=False, asm_lower=False):
     ctl_parser = CtlParser()
     ctl_parser.parse_ctl(self.write_text_file(ctl))
     return SkoolWriter(snapshot, ctl_parser, defb_size, defb_mod, zfill, defm_width, asm_hex, asm_lower)
示例#17
0
    def test_disassembly(self):
        ctl_parser = CtlParser()
        ctl_parser.parse_ctl(self.write_text_file(DISASSEMBLY_CTL))
        disassembly = Disassembly(DISASSEMBLY_SNAPSHOT, ctl_parser, True)

        entries = disassembly.entries
        self.assertEqual(len(entries), 16)

        # Entry #1 (32768)
        entry = entries[0]
        self.assertEqual(entry.address, 32768)
        self.assertEqual(entry.title, 'Routine at 32768')
        self.assertEqual(entry.description, ['Routine description paragraph 1.', 'Routine description paragraph 2.'])
        self.assertEqual(entry.ctl, 'c')
        self.assertEqual(entry.registers, [['A', 'Some value'], ['B', 'Some other value']])
        self.assertEqual(entry.end_comment, ['Routine end comment.'])
        self.assertEqual(entry.start, True)
        self.assertEqual(entry.end, True)
        self.assertEqual(entry.writer, 'skoolkit.game.GameAsmWriter')
        self.assertEqual(entry.org, '32768')

        blocks = entry.blocks
        self.assertEqual(len(blocks), 1)
        block = blocks[0]
        self.assertEqual(block.header, None)
        self.assertEqual(block.comment, 'This is an instruction-level comment that spans two instructions')
        self.assertEqual(block.instructions, entry.instructions)
        self.assertEqual(block.end, 32770)

        instructions = entry.instructions
        self.assertEqual(len(instructions), 2)
        instruction = instructions[0]
        self.assertEqual(instruction.address, 32768)
        self.assertEqual(instruction.operation, 'XOR A')
        self.assertEqual(instruction.bytes, [175])
        self.assertEqual(instruction.referrers, [entries[13]])
        self.assertEqual(instruction.entry, entry)
        self.assertEqual(instruction.ctl, 'c')
        self.assertEqual(instruction.comment, None)
        self.assertEqual(instruction.asm_directives, [('label', 'START')])

        # Entry #2 (32770)
        entry = entries[1]
        self.assertEqual(entry.address, 32770)
        self.assertEqual(entry.title, 'Message at {0}'.format(entry.address))
        instructions = entry.instructions
        self.assertEqual(len(instructions), 2)
        self.assertEqual(instructions[0].operation, 'DEFM "Hi"')
        self.assertEqual(instructions[1].operation, 'DEFM "Lo"')

        # Entry #3 (32774)
        entry = entries[2]
        self.assertEqual(entry.address, 32774)
        self.assertEqual(entry.title, 'Yo')

        # Entry #4 (32776)
        entry = entries[3]
        self.assertEqual(entry.address, 32776)
        self.assertEqual(entry.title, 'Data block at {0}'.format(entry.address))
        instructions = entry.instructions
        self.assertEqual(len(instructions), 4)
        self.assertEqual(instructions[0].operation, 'DEFB 0,0,0')
        self.assertEqual(instructions[3].operation, 'DEFB 0,0,0')

        # Entry #5 (32788)
        entry = entries[4]
        self.assertEqual(entry.address, 32788)
        self.assertEqual(entry.title, 'Important byte')

        # Entry #6 (32789)
        entry = entries[5]
        self.assertEqual(entry.address, 32789)
        self.assertEqual(entry.title, 'Data block at {0}'.format(entry.address))
        instructions = entry.instructions
        self.assertEqual(len(instructions), 1)
        self.assertEqual(instructions[0].operation, 'DEFW 0,0')

        # Entry #7 (32793)
        entry = entries[6]
        self.assertEqual(entry.address, 32793)
        self.assertEqual(entry.title, 'Important word')

        # Entry #8 (32795)
        entry = entries[7]
        self.assertEqual(entry.address, 32795)
        self.assertEqual(entry.title, 'Game status buffer entry at {0}'.format(entry.address))

        # Entry #9 (32796)
        entry = entries[8]
        self.assertEqual(entry.address, 32796)
        self.assertEqual(entry.title, 'Important game status buffer byte')

        # Entry #10 (32797)
        entry = entries[9]
        self.assertEqual(entry.address, 32797)
        self.assertEqual(entry.title, 'Unused')

        # Entry #11 (32798)
        entry = entries[10]
        self.assertEqual(entry.address, 32798)
        self.assertEqual(entry.title, 'Unimportant unused byte')

        # Entry #12 (32799)
        entry = entries[11]
        self.assertEqual(entry.address, 32799)
        self.assertEqual(entry.title, 'Unused')
        instructions = entry.instructions
        self.assertEqual(len(instructions), 2)
        self.assertEqual(instructions[0].operation, 'DEFS 5')
        self.assertEqual(instructions[1].operation, 'DEFS 5')

        # Entry #13 (32809)
        entry = entries[12]
        self.assertEqual(entry.address, 32809)
        self.assertEqual(entry.title, 'Block of zeroes')
        instructions = entry.instructions
        self.assertEqual(len(instructions), 3)
        self.assertEqual(instructions[0].operation, 'DEFS 3')
        self.assertEqual(instructions[1].operation, 'NOP')
        self.assertEqual(instructions[2].operation, 'NOP')
        blocks = entry.blocks
        self.assertEqual(len(blocks), 1)
        block = blocks[0]
        self.assertEqual(block.comment, 'A DEFS followed by two NOPs')

        # Entry #14 (32814)
        entry = entries[13]
        self.assertEqual(entry.address, 32814)
        self.assertEqual(entry.title, 'Refers to the routine at 32768')

        # Entry #15 (32817)
        entry = entries[14]
        self.assertEqual(entry.address, 32817)
        instructions = entry.instructions
        self.assertEqual(len(instructions), 6)
        self.assertEqual(instructions[0].operation, 'DEFM "Hi",1,2,3')
        self.assertEqual(instructions[1].operation, 'DEFB 4,5,"Lo",6')
        self.assertEqual(instructions[2].operation, 'DEFM "ab",1')
        self.assertEqual(instructions[3].operation, 'DEFM "cd",2')
        self.assertEqual(instructions[4].operation, 'DEFM "e",3')
        self.assertEqual(instructions[5].operation, 'DEFM "f",4')

        # Entry #16 (32837)
        entry = entries[15]
        self.assertEqual(entry.address, 32837)
示例#18
0
 def _get_ctl_parser(self, ctl, min_address=0, max_address=65536):
     ctl_parser = CtlParser()
     ctlfile = self.write_text_file(ctl)
     ctl_parser.parse_ctl(ctlfile, min_address, max_address)
     return ctl_parser