CVS: htdocs/cgi-bin disassemble.py,1.8,1.9 test-disassemble.py,1.1,1.2

Chris Liechti <[email protected]>
Newsgroups gmane.comp.hardware.texas-instruments.msp430.gcc.cvs
Message-ID <[email protected]>
Update of /cvsroot/mspgcc/htdocs/cgi-bin
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19021/htdocs/cgi-bin

Modified Files:
	disassemble.py test-disassemble.py 
Log Message:
disassembler update:
- support for emulated instructions
- make labels for jump targets
- build code blocks by inserting newlines after unconditional jumps (jmp, be, ret, reti)
- support for symbol file (definitions for peripheral register names and their bits)

Index: disassemble.py
===================================================================
RCS file: /cvsroot/mspgcc/htdocs/cgi-bin/disassemble.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -w -d -r1.8 -r1.9
--- disassemble.py	3 Aug 2004 13:17:12 -0000	1.8
+++ disassemble.py	3 May 2005 16:40:20 -0000	1.9
@@ -52,15 +52,15 @@
                 #x = RegisterArgument(core,reg=core.R[src], bytemode=bytemode, am=as)
             elif as == 1:   #pc rel
                 if src == 0:
-                    x = '%(x)s'
+                    x = '0x%(x)04x'
                     #x = IndexedRegisterArgument(core, reg=core.PC, offset=pc.next(), bytemode=bytemode)
                     c = c + 2  #fetch+read
                 elif src == 2: #abs
-                    x = '&%(x)s'
+                    x = '&0x%(x)04x'
                     #x = MemoryArgument(core, address=pc.next(), bytemode=bytemode)
                     c = c + 2  #fetch+read
                 else:           #indexed
-                    x = '%%(x)s(%s)' % regnames[src]
+                    x = '0x%%(x)04x(%s)' % regnames[src]
                     #x = IndexedRegisterArgument(core, reg=core.R[src], offset=pc.next(), bytemode=bytemode)
                     c = c + 2  #fetch+read
             elif as == 2:   #indirect
@@ -69,7 +69,7 @@
                 c = c + 1  #target mem read
             elif as == 3:
                 if src == 0:    #immediate
-                    x = '#%(x)s'
+                    x = bytemode and '#0x%(x)02x' or '#0x%(x)04x'
                     #x = ImmediateArgument(core, value=pc.next(), bytemode=bytemode)
                     c = c + 1  #fetch
                 else:           #indirect autoincrement
@@ -87,15 +87,15 @@
                 c = c + 1  #modifying PC gives one cycle penalty
         else:
             if dest == 0:   #PC relative
-                y = '%(y)s'
+                y = '0x%(y)04x'
                 #y = IndexedRegisterArgument(core, reg=core.PC, offset=pc.next(), bytemode=bytemode)
                 c = c + 3  #fetch + read modify write
             elif dest == 2: #abs
-                y = '&%(y)s'
+                y = '&0x%(y)04x'
                 #y = MemoryArgument(core, address=pc.next(), bytemode=bytemode)
                 c = c + 3  #fetch + read modify write
             else:           #indexed
-                y = '%%(y)s(%s)' % regnames[dest]
+                y = '0x%%(y)04x(%s)' % regnames[dest]
                 #y = IndexedRegisterArgument(core, reg=core.R[dest], offset=pc.next(), bytemode=bytemode)
                 c = c + 3  #fetch + read modify write
 
@@ -138,7 +138,195 @@
     0x7: ('jmp',  1),
 }
 
+INSN_WIDTH = 7          #instruction width (args follow)
+symbols = {}            #address -> label
+bits = {}               #label -> list of (bits, shift, width)
+bits_speacial = {}      #label -> dict: value -> name
+
+def symbol_from_adr(opt):
+    """try to find a symbolname if the argument points to an absolute address"""
+    if opt[0:1] == '&':
+        adr = int(opt[1:], 0)
+        if adr in symbols:
+            return '&%s' % (symbols[adr], )
+    return opt
+    
+def symbols_for_bits(arg, opt):
+    """for known targets, convert immediate values to a list of or'ed bits"""
+    if opt[0:1] == '&':
+        reg = opt[1:]
+        if arg[0:1] == '#' and reg in bits:
+            value = int(arg[1:], 0)
+            result = []
+            for names, shift, width in bits[reg]:
+                mask = ((1<<width) - 1) << shift
+                x = (value & mask) >> shift
+                if x and names[x]:
+                    value &= ~mask  #clear these bits
+                    result.append(names[x])
+            #if there are bits left, append them to the result, so that nothing gets lost
+            if value:
+                if value in bits_speacial[reg]:
+                    result.append(bits_speacial[reg][value])
+                else:
+                    result.append('0x%x' % value)
+            return '#%s' % '|'.join(result)
+    return arg
+
+class Instruction:
+    """this class s used to represent an MSP430 assembler instruction.
+        emulated instructions are handled on class instantiation."""
+    def __init__(self, name, bytemode=0, src=None, dst=None, usedwords=0, cycles=0):
+        self.name = name
+        self.bytemode = bytemode
+        self.src = src
+        self.dst = dst
+        self.usedwords = usedwords
+        self.cycles = cycles
+        
+        #transformations of emulated instructions
+        new_name = None
+        if self.name == 'add':
+            if self.src == '#1':
+                new_name = 'inc'
+            elif self.src == '#2':
+                new_name = 'incd'
+            elif self.src == self.dst:
+                new_name = 'rla'
+        elif self.name == 'addc':
+            if self.src == '#0':
+                new_name = 'adc'
+            elif self.src == self.dst:
+                new_name = 'rlc'
+        elif self.name == 'dadd' and self.src == '#0':
+            new_name = 'dadc'
+        elif self.name == 'sub':
+            if self.src == '#1':
+                new_name = 'dec'
+            elif self.src == '#2':
+                new_name = 'decd'
+        elif self.name == 'subc' and self.src == '#0':
+            new_name = 'sbc'
+        elif self.name == 'xor' and self.src == '#-1':
+            new_name = 'inv'
+        elif self.name == 'mov':
+            if self.src == '#0':
+                if self.dst == 'CG2':
+                    new_name = 'nop'
+                    self.dst = None
+                else:
+                    new_name = 'clr'
+            elif self.src == '@SP+':
+                if self.dst == 'PC':
+                    new_name = 'ret'
+                    self.dst = None
+                else:
+                    new_name = 'pop'
+            elif self.dst == 'PC':
+                new_name = 'br'
+                self.dst = self.src
+        elif self.name == 'bic' and self.dst == 'SR':
+            if self.src == '#8':
+                new_name = 'dint'
+                self.dst = None
+            elif self.src == '#1':
+                new_name = 'clrc'
+                self.dst = None
+            elif self.src == '#4':
+                new_name = 'clrn'
+                self.dst = None
+            elif self.src == '#2':
+                new_name = 'clrz'
+                self.dst = None
+        elif self.name == 'bis' and self.dst == 'SR':
+            if self.src == '#8':
+                new_name = 'eint'
+                self.dst = None
+            elif self.src == '#1':
+                new_name = 'setc'
+                self.dst = None
+            elif self.src == '#4':
+                new_name = 'setn'
+                self.dst = None
+            elif self.src == '#2':
+                new_name = 'setz'
+                self.dst = None
+        elif self.name == 'cmp' and self.src == '#0':
+            new_name = 'tst'
+        #emulated insns have no src
+        if new_name is not None:
+            self.name = new_name
+            self.src = None
+
+        #try to replace values by symbols
+        if self.dst: self.dst = symbol_from_adr(self.dst)
+        if self.src:
+                self.src = symbol_from_adr(self.src)
+                self.src = symbols_for_bits(self.src, self.dst)
+
+    def __str__(self):
+        if self.src is not None and self.dst is not None:
+            return ("%%-%ds %%s, %%s" % INSN_WIDTH) % ("%s%s" % (self.name, (self.bytemode and '.b' or '')), self.src, self.dst)
+        elif self.dst is not None:
+            return ("%%-%ds %%s" % INSN_WIDTH) % ( "%s%s" % (self.name, (self.bytemode and '.b' or '')), self.dst)
+        else:
+            return ("%%-%ds" % INSN_WIDTH) % (self.name,)
+
+    def str_width_label(self, label):
+        if not self.jumps(): raise ValueError('only possible with jump insns')
+        if self.dst is not None and self.dst[0:1] == '#' and self.src is None:
+            return ("%%-%ds #%%s" % INSN_WIDTH) % (self.name, label)
+        raise ValueError('only possible with dst only insns')
+
+    def jumps(self):
+        """return true if this instructions jumps (modifies the PC)"""
+        return (self.name == 'call' or self.dst == 'PC') and (self.dst[0] == '#')       #XXX relative address mode missing
+    
+    def targetAddress(self, address):
+        """only valid for instructions that jump; return the target address of the jump"""
+        if self.name == 'call' or self.name == 'br':
+            if self.dst[0] == '#':
+                return int(self.dst[1:], 0)
+            else:
+                return address + int(self.dst, 0)
+        else:
+            raise ValueError('not a branching instruction')
+
+    def ends_a_block(self):
+        """helper for a nice output. return true if execution does not continue
+        after this instruction."""
+        return self.name in ('ret', 'reti', 'br')
+
+
+class JumpInstruction(Instruction):
+    """represent jump instructions"""
+    def __init__(self, name, offset, usedwords=0, cycles=0):
+        Instruction.__init__(self, name, 0, None, None, usedwords, cycles)
+        self.offset = offset
+    
+    def jumps(self):
+        """return true because this instructions jumps (modifies the PC)"""
+        return 1
+    
+    def targetAddress(self, address):
+        """return the target address of the jump"""
+        return address + self.offset
+    
+    def __str__(self):
+        return ("%%-%ds %%+d" % INSN_WIDTH) % (self.name, self.offset)
+
+    def str_width_label(self, label):
+        return ("%%-%ds %%s" % INSN_WIDTH) % (self.name, label)
+
+    def ends_a_block(self):
+        """helper for a nice output. return true if execution does not continue
+        after this instruction."""
+        return self.name == 'jmp'
+
 def disassemble(words):
+        """disassembler one instruction from a stream of words. returns an
+        instance of Instruction. that class has informationa bout how many
+        wwords have been consumed and more."""
         cycles = 1              #count cycles, start with insn fetch
         usedwords = 1
         x = y = None
@@ -172,10 +360,10 @@
             if '%' in x:
                 x = x % {'x':words[0]}
                 usedwords = usedwords + 1
-            if name != 'reti':
-                return "%s%s %s" % (name, (bytemode and '.b' or ''), x), usedwords, cycles
+            if name == 'reti':
+                return Instruction(name, usedwords=usedwords, cycles=cycles)
             else:
-                return "reti", usedwords, cycles
+                return Instruction(name, bytemode, dst=x, usedwords=usedwords, cycles=cycles)
 
         #double operand
         elif (opcode>>12)&0xf in doubleOperandInstructions.keys():
@@ -195,7 +383,7 @@
             if '%' in y:
                 y = y % {'y':words[0]}
                 usedwords = usedwords + 1
-            return "%s%s %s, %s" % (name, (bytemode and '.b' or ''), x, y), usedwords, cycles
+            return Instruction(name, bytemode, src=x, dst=y, usedwords=usedwords, cycles=cycles)
 
         #jump instructions
         elif ((opcode & 0xe000) == 0x2000 and
@@ -206,11 +394,11 @@
             if offset & 0x400:  #negative?
                 offset = -((~offset + 1) & 0x7ff)
             cycles = cycles + addcyles #jumps allways have 2 cycles
-            return "%s %s" % (name, offset), usedwords, cycles
+            return JumpInstruction(name, offset, usedwords=usedwords, cycles=cycles)
 
         #unkown instruction
         else:
-            return 'illegal insn 0x%04x' % opcode, usedwords, cycles
+            return Instruction('illegal-insn-0x%04x' % opcode, usedwords=usedwords, cycles=cycles)
 
 if __name__ == '__main__':
     if len(sys.argv) > 1:
@@ -234,6 +422,8 @@
         parser = OptionParser(option_class=MyOption)
         parser.add_option("-b", "--bin", dest="binary",
                           help="read data from a binary file", metavar="FILE")
+        parser.add_option("", "--symbols", dest="symbols",
+                          help="read symbol addresses from a text file", metavar="FILE")
         parser.add_option("-s", "--startadr", dest="startadr",
                           help="startoffset for binary input", type="intautobase", default=0)
         
@@ -244,37 +434,103 @@
             sys.stdout.write("Parameter disassemble: %s  (%d words %d cycles)\n" % (insn, words, cycles))
             
         if options.binary is not None:
+            #symbol file provided?
+            if options.symbols is not None:
+                #parse symbol file
+                for line in file(options.symbols):
+                    #skip comment lines
+                    if line.strip()[0:1] == '#': continue
+                    #break the line in elements (whitespace separated)
+                    els = line.split()
+                    if len(els) >= 2:
+                        adr = els.pop(0)        #1st column -> address
+                        name = els.pop(0)       #2nd column -> name
+                        symbols[int(adr, 0)] = name
+                        #the optional third column defines names for the bits
+                        if els:
+                            bitstring = els.pop(0)
+                            bits[name] = []
+                            b = bitstring.split('|')
+                            b.reverse()
+                            for n, bit in enumerate(b):
+                                if bit != '?':
+                                    bits[name].append((['', bit], n, 1))     #name, shift, width
+                            bits[name].reverse()
+                        #the optional fourth column defines names for special values
+                        if els:
+                            bits_speacial[name] = {}
+                            consts = els.pop(0).split(',')
+                            for const in consts:
+                                cname, cvalue = const.split('=')
+                                bits_speacial[name][int(cvalue, 0)] = cname
             sys.stderr.write("---- file: %s ----\n" % options.binary)
-            if options.binary:
                 import msp430, msp430.memory, msp430.elf
                 data = msp430.memory.Memory()
                 try:
+                #try to load elf, IntelHex or TI-Text
                     data.loadFile(options.binary)
                 except msp430.elf.ELFException:
+                #failed, treat it as binary file
                     sys.stderr.write("Attention: parsing binary file\n")
                     memory = file(options.binary, 'rb').read()
                     if len(memory) & 1: 
                         sys.stderr.write("odd length!!, cutting off last byte\n")
                         memory = memory[:-1]
-                    memwords = [struct.unpack("<H", memory[x:x+2])[0] for x in range(0, len(memory), 2) ]
-                    offset = 0
-                    while offset < len(memwords):
-                        insn, words, cycles = disassemble(memwords[offset:])
-                        bytes = ' '.join(['%04x' % x for x in memwords[offset:offset+words]])
-                        sys.stdout.write("0x%04x:  %-16s %-36s  (%d cycles)\n" % (options.startadr+offset*2, bytes, insn, cycles))
-                        offset += words
-                else:
+                #can't know startaddress, use cmdline option
+                data.append(msp430.memory.Segment(options.startadr, memory))
+            #disassemble memory
                     memwords = []
+            labels = {}
+            label_num = 1
                     for seg in data:
                         memwords = [struct.unpack("<H", seg.data[x:x+2])[0] for x in range(0, len(seg.data), 2) ]
-                        sys.stdout.write("----- Address 0x%04x:\n" % seg.startaddress)
+                sys.stdout.write("; Address 0x%04x:\n" % seg.startaddress)
                         options.startadr = seg.startaddress
                         offset = 0
+                lines = []
                         while offset < len(memwords):
-                            insn, words, cycles = disassemble(memwords[offset:])
-                            bytes = ' '.join(['%04x' % x for x in memwords[offset:offset+words]])
-                            sys.stdout.write("0x%04x:  %-16s %-36s  (%d cycles)\n" % (options.startadr+offset*2, bytes, insn, cycles))
-                            offset += words
+                    address = options.startadr+offset*2
+                    insn = disassemble(memwords[offset:])
+                    bytes = ' '.join(['%04x' % x for x in memwords[offset:offset+insn.usedwords]])
+                    instext = str(insn)
+                    #does this instruction jump? if so, get a label for the jump target
+                    if insn.jumps():
+                        l_adr = insn.targetAddress(options.startadr+offset*2+2)
+                        if l_adr not in labels:
+                            #create a new label
+                            label = '.L%04d' % label_num
+                            label_num = label_num + 1
+                            labels[l_adr] = label
+                        #update note with information about the values
+                        if isinstance(insn, JumpInstruction):
+                            instext = insn.str_width_label(labels[l_adr])
+                            note = ' %+d --> 0x%04x' % (insn.offset, l_adr)
+                        else:
+                            instext = insn.str_width_label(labels[l_adr])
+                            note = ' --> 0x%04x' % (l_adr, )
+                    else:
+                        note = ''
+                    #save generated line
+                    lines.append((address, "0x%04x:  %-16s" % (address, bytes), "%-36s ;%d cycles%s\n" % (instext, insn.cycles, note)))
+                    #after unconditional jumps, make an empty line
+                    if insn.ends_a_block():
+                        lines.append((None, '', '\n'))
+                    offset += insn.usedwords
+                #now output all the lines, put the labels where they belong
+                unused_labels = dict(labels)        #work on a copy
+                for address, prefix, suffix in lines:
+                    if address in labels:
+                        label = "%s:" % labels[address]
+                        del unused_labels[address]  #remove used label
+                    else:
+                        label = ''
+                    #render lines with labels
+                    sys.stdout.write("%s %-7s %s" % (prefix, label, suffix))
+                #if there are labels left, print them in a list
+                if unused_labels:
+                    sys.stdout.write("\nLabels that could not be placed:\n")
+                    for address, label in unused_labels.items():
+                        sys.stdout.write("    %s = 0x%04x\n" % (label, address))
     else:
         import cgi, os
         #cgitb is not available in py 1.5.2
@@ -291,7 +547,8 @@
                 print "<pre>", values, "</pre>"
                 print "<H3>Results in the following assembler instruction:</H3>"
                 print "<pre>"
-                insn, words, cycles = disassemble(map(myint, string.split(values)))
+                insn = disassemble(map(myint, string.split(values)))
+                words, cycles = insn.usedwords, insn.cycles
                 print "%s  (%d cycles, %d words)" % (insn, cycles, words)
                 print "</pre>"
             else:

Index: test-disassemble.py
===================================================================
RCS file: /cvsroot/mspgcc/htdocs/cgi-bin/test-disassemble.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -d -r1.1 -r1.2
--- test-disassemble.py	13 Jun 2003 02:23:31 -0000	1.1
+++ test-disassemble.py	3 May 2005 16:40:20 -0000	1.2
@@ -1,76 +1,70 @@
 import unittest
 import disassemble
 
+
 formatItests = [
     #input,         iop,                             cycles
     ('mov R5, R8',      [['OPC', 0x4508]], 1),
-    #~ ('br  R9',          [['OPC', 0x4900]], 2), #emulated insn see next line
-    ('mov R9, PC',          [['OPC', 0x4900]], 2),
-    ('add R5, 3(R6)',   [['OPC', 0x5586], ['DW', 0x0003]], 4),
-    ('xor R8, 1234',    [['OPC', 0xe880], ['PCREL', 0x04d2]], 4),
-    ('mov R5, &1234',   [['OPC', 0x4582], ['DW', 0x04d2]], 4),
+    ('br R9',                   [['OPC', 0x4900]], 2), #emulated insn see next line
+    ('add R5, 0x0003(R6)',      [['OPC', 0x5586], ['DW', 0x0003]], 4),
+    ('xor R8, 0x04d2',          [['OPC', 0xe880], ['PCREL', 0x04d2]], 4),
+    ('mov R5, &0x04d2',         [['OPC', 0x4582], ['DW', 0x04d2]], 4),
     
     ('and @R4, R5',     [['OPC', 0xf425]], 2),
-    #~ ('br @R8',          [['OPC', 0x4820]], 3), #emulated insn see next line
-    ('mov @R8, PC',          [['OPC', 0x4820]], 3),
-    ('xor @R5, 8(R6)',  [['OPC', 0xe5a6], ['DW', 0x0008]], 5),
-    ('mov @R5, 1234',   [['OPC', 0x45a0], ['PCREL', 0x04d2]], 5),
-    ('xor @R5, &1234',  [['OPC', 0xe5a2], ['DW', 0x04d2]], 5),
+    ('br @R8',                  [['OPC', 0x4820]], 3), #emulated insn see next line
+    ('xor @R5, 0x0008(R6)',     [['OPC', 0xe5a6], ['DW', 0x0008]], 5),
+    ('mov @R5, 0x04d2',         [['OPC', 0x45a0], ['PCREL', 0x04d2]], 5),
+    ('xor @R5, &0x04d2',        [['OPC', 0xe5a2], ['DW', 0x04d2]], 5),
     
     ('add @R5+, R6',    [['OPC', 0x5536]], 2),
-    #~ ('br  @R9+',        [['OPC', 0x4930]], 3), #emulated insn see next line
-    ('mov @R9+, PC',        [['OPC', 0x4930]], 3),
-    ('xor @R5+, 8(R6)', [['OPC', 0xe5b6], ['DW', 0x0008]], 5),
-    ('mov @R9+, 1234',  [['OPC', 0x49b0], ['PCREL', 0x04d2]], 5),
-    ('mov @R9+, &1234', [['OPC', 0x49b2], ['DW', 0x04d2]], 5),
+    ('br @R9+',                 [['OPC', 0x4930]], 3), #emulated insn see next line
+    ('xor @R5+, 0x0008(R6)',    [['OPC', 0xe5b6], ['DW', 0x0008]], 5),
+    ('mov @R9+, 0x04d2',        [['OPC', 0x49b0], ['PCREL', 0x04d2]], 5),
+    ('mov @R9+, &0x04d2',       [['OPC', 0x49b2], ['DW', 0x04d2]], 5),
     
-    ('mov #20, R9',     [['OPC', 0x4039], ['DW', 0x0014]], 2),
-    #~ ('br  #0x02ae',     [['OPC', 0x4030], ['DW', 0x02ae]], 3),  #emulated insn see next line
-    #~ ('mov #0x02ae, PC',     [['OPC', 0x4030], ['DW', 0x02ae]], 3),
-    ('mov #686, PC',     [['OPC', 0x4030], ['DW', 0x02ae]], 3),
-    ('mov #768, 0(SP)', [['OPC', 0x40b1], ['DW', 0x0300], ['DW', 0x0000]], 5),
-    ('add #33, 1234',   [['OPC', 0x50b0], ['DW', 0x0021], ['PCREL', 0x04d2]], 5),
-    ('add #33, &1234',  [['OPC', 0x50b2], ['DW', 0x0021], ['DW', 0x04d2]], 5),
+    ('mov #0x0014, R9',         [['OPC', 0x4039], ['DW', 0x0014]], 2),
+    ('br #0x02ae',              [['OPC', 0x4030], ['DW', 0x02ae]], 3),  #emulated insn see next line
+    ('mov #0x0300, 0x0000(SP)', [['OPC', 0x40b1], ['DW', 0x0300], ['DW', 0x0000]], 5),
+    ('add #0x0021, 0x04d2',     [['OPC', 0x50b0], ['DW', 0x0021], ['PCREL', 0x04d2]], 5),
+    ('add #0x0021, &0x04d2',    [['OPC', 0x50b2], ['DW', 0x0021], ['DW', 0x04d2]], 5),
 
-    ('mov 2(R5), R7',   [['OPC', 0x4517], ['DW', 0x0002]], 3),
-    #~ ('br 2(R6)',        [['OPC', 0x4610], ['DW', 0x0002]], 3), #emulated insn see next line
-    ('mov 2(R6), PC',        [['OPC', 0x4610], ['DW', 0x0002]], 3),
-    ('mov 4(R7), 1234', [['OPC', 0x4790], ['DW', 0x0004], ['PCREL', 0x04d2]], 6),
-    ('add 3(R4), 6(R9)',[['OPC', 0x5499], ['DW', 0x0003], ['DW', 0x0006]], 6),
-    ('mov 2(R5), &1234',[['OPC', 0x4592], ['DW', 0x0002], ['DW', 0x04d2]], 6),
+    ('mov 0x0002(R5), R7',      [['OPC', 0x4517], ['DW', 0x0002]], 3),
+    ('br 0x0002(R6)',           [['OPC', 0x4610], ['DW', 0x0002]], 3), #emulated insn see next line
+    ('mov 0x0004(R7), 0x04d2',  [['OPC', 0x4790], ['DW', 0x0004], ['PCREL', 0x04d2]], 6),
+    ('add 0x0003(R4), 0x0006(R9)',[['OPC', 0x5499], ['DW', 0x0003], ['DW', 0x0006]], 6),
+    ('mov 0x0002(R5), &0x04d2', [['OPC', 0x4592], ['DW', 0x0002], ['DW', 0x04d2]], 6),
     
-    ('and 1234, R6',    [['OPC', 0xf016], ['PCREL', 0x04d2]], 3),
-    #~ ('br  1234',        [['OPC', 0x4010], ['PCREL', 0x04d2]], 3), #emulated insn see next line
-    ('mov 1234, PC',        [['OPC', 0x4010], ['PCREL', 0x04d2]], 3),
-    ('cmp 1234, 5678',  [['OPC', 0x9090], ['PCREL', 0x04d2], ['PCREL', 0x162e]], 6),
-    ('mov 1234, 0(SP)', [['OPC', 0x4091], ['PCREL', 0x04d2], ['DW', 0x0000]], 6),
-    ('mov 1234, &5678', [['OPC', 0x4092], ['PCREL', 0x04d2], ['DW', 0x162e]], 6),
+    ('and 0x04d2, R6',          [['OPC', 0xf016], ['PCREL', 0x04d2]], 3),
+    ('br 0x04d2',               [['OPC', 0x4010], ['PCREL', 0x04d2]], 3), #emulated insn see next line
+    ('cmp 0x04d2, 0x162e',      [['OPC', 0x9090], ['PCREL', 0x04d2], ['PCREL', 0x162e]], 6),
+    ('mov 0x04d2, 0x0000(SP)',  [['OPC', 0x4091], ['PCREL', 0x04d2], ['DW', 0x0000]], 6),
+    ('mov 0x04d2, &0x162e',     [['OPC', 0x4092], ['PCREL', 0x04d2], ['DW', 0x162e]], 6),
     
     
-    ('mov &1234, R8',   [['OPC', 0x4218], ['DW', 0x04d2]], 3),
-    #~ ('br &1234',        [['OPC', 0x4210], ['DW', 0x04d2]], 3),
-    ('mov &1234, PC',        [['OPC', 0x4210], ['DW', 0x04d2]], 3),
-    ('mov &1234, 5678', [['OPC', 0x4290], ['DW', 0x04d2], ['PCREL', 0x162e]], 6),
-    ('mov &1234, 0(SP)',[['OPC', 0x4291], ['DW', 0x04d2], ['DW', 0x0000]], 6),
-    ('mov &1234, &5678',[['OPC', 0x4292], ['DW', 0x04d2], ['DW', 0x162e]], 6),
+    ('mov &0x04d2, R8',         [['OPC', 0x4218], ['DW', 0x04d2]], 3),
+    ('br &0x04d2',              [['OPC', 0x4210], ['DW', 0x04d2]], 3),
+    ('mov &0x04d2, 0x162e',     [['OPC', 0x4290], ['DW', 0x04d2], ['PCREL', 0x162e]], 6),
+    ('mov &0x04d2, 0x0000(SP)', [['OPC', 0x4291], ['DW', 0x04d2], ['DW', 0x0000]], 6),
+    ('mov &0x04d2, &0x162e',    [['OPC', 0x4292], ['DW', 0x04d2], ['DW', 0x162e]], 6),
 ]
 
 class TestFormatI(unittest.TestCase):
     def testFormatI(self):
         for line, iop, desired_cylces in formatItests:
-            insn, words, cycles = disassemble.disassemble([w for m,w in iop])
+            insn = disassemble.disassemble([w for m,w in iop])
+            words, cycles = insn.usedwords, insn.cycles
             #~ print
             #~ print iop, cycles 
             #~ print desired_iop, desired_cylces
-            self.failUnless(insn == line, '%r failed, wrong output (%r)' % (line, insn))
+            self.failUnless(str(insn).split() == line.split(), '%r failed, wrong output (%s)' % (line, insn))
             self.failUnless(desired_cylces == cycles, '%r failed, wrong number of cycles' % line)
 
 
 formatIItests = [
     #input,         iop,                             cycles
-    ('push #8',     [['OPC', 0x1230], ['DW', 0x0008]], 4),
-    ('push #7',     [['OPC', 0x1230], ['DW', 0x0007]], 4),
-    ('push #4',     [['OPC', 0x1230], ['DW', 0x0004]], 4),
+    ('push #0x0008',    [['OPC', 0x1230], ['DW', 0x0008]], 4),
+    ('push #0x0007',    [['OPC', 0x1230], ['DW', 0x0007]], 4),
+    ('push #0x0004',    [['OPC', 0x1230], ['DW', 0x0004]], 4),
     ('push #0',     [['OPC', 0x1203]], 3),
     ('push #1',     [['OPC', 0x1213]], 3),
     ('push #2',     [['OPC', 0x1223]], 3),
@@ -79,57 +73,59 @@
     ('push @R4',    [['OPC', 0x1224]], 4),
     ('push @R4+',   [['OPC', 0x1234]], 4),
     
-    ('push 0(R4)',  [['OPC', 0x1214], ['DW', 0x0000]], 5),
-    ('push 1234',   [['OPC', 0x1210], ['PCREL', 0x04d2]], 5),
-    ('push &1234',  [['OPC', 0x1212], ['DW', 0x04d2]], 5),
+    ('push 0x0000(R4)', [['OPC', 0x1214], ['DW', 0x0000]], 5),
+    ('push 0x04d2',     [['OPC', 0x1210], ['PCREL', 0x04d2]], 5),
+    ('push &0x04d2',    [['OPC', 0x1212], ['DW', 0x04d2]], 5),
     
     ('call R4',     [['OPC', 0x1284]], 4),
-    ('call 1234',   [['OPC', 0x1290], ['PCREL', 0x04d2]], 5),
+    ('call 0x04d2',     [['OPC', 0x1290], ['PCREL', 0x04d2]], 5),
     ('call @R4',    [['OPC', 0x12a4]], 4),
-    ('call #1234',  [['OPC', 0x12b0], ['DW', 0x04d2]], 5),
+    ('call #0x04d2',    [['OPC', 0x12b0], ['DW', 0x04d2]], 5),
 
     ('swpb R4',     [['OPC', 0x1084]], 1),
-    ('rra 1234',    [['OPC', 0x1110], ['PCREL', 0x04d2]], 4),
+    ('rra 0x04d2',      [['OPC', 0x1110], ['PCREL', 0x04d2]], 4),
     ('rrc @R4',     [['OPC', 0x1024]], 3),
-    ('rra #1234',   [['OPC', 0x1130], ['DW', 0x04d2]], 3),
+    ('rra #0x04d2',     [['OPC', 0x1130], ['DW', 0x04d2]], 3),
 ]
 
 class TestFormatII(unittest.TestCase):
     def testFormatII(self):
         for line, iop, desired_cylces in formatIItests:
-            insn, words, cycles = disassemble.disassemble([w for m,w in iop])
+            insn = disassemble.disassemble([w for m,w in iop])
+            words, cycles = insn.usedwords, insn.cycles
             #~ print
             #~ print insn, words, cycles 
             #~ print line, desired_cylces
-            self.failUnless(insn == line, '%r failed, wrong output (%r)' % (line, insn))
+            self.failUnless(str(insn).split() == line.split(), '%r failed, wrong output (%s)' % (line, insn))
             self.failUnless(desired_cylces == cycles, '%r failed, wrong number of cycles' % line)
 
 formatIIItests = [
     #input,         iop,               cycles
-    ('jnz 8',       [['OPC', 0x2004]], 2),
-    ('jz 4',        [['OPC', 0x2402]], 2),
-    ('jnc 4',       [['OPC', 0x2802]], 2),
-    ('jc 4',        [['OPC', 0x2c02]], 2),
+    ('jnz +8',       [['OPC', 0x2004]], 2),
+    ('jz +4',        [['OPC', 0x2402]], 2),
+    ('jnc +4',       [['OPC', 0x2802]], 2),
+    ('jc +4',        [['OPC', 0x2c02]], 2),
     #~ ('jhs -8',      [['OPC', 0x2ffc]], 2), #alias for jc
-    ('jn 4',        [['OPC', 0x3002]], 2),
-    ('jge 4',       [['OPC', 0x3402]], 2),
-    ('jl 4',        [['OPC', 0x3802]], 2),
-    ('jmp 4',       [['OPC', 0x3c02]], 2),
+    ('jn +4',        [['OPC', 0x3002]], 2),
+    ('jge +4',       [['OPC', 0x3402]], 2),
+    ('jl +4',        [['OPC', 0x3802]], 2),
+    ('jmp +4',       [['OPC', 0x3c02]], 2),
     ('jmp -2',      [['OPC', 0x3fff]], 2),
     #~ ('jmp $',       [['OPC', 0x3fff]], 2), #alias for -2
     #~ ('jmp .',       [['OPC', 0x3fff]], 2), #alias for -2
     ('jmp -1024',   [['OPC', 0x3e00]], 2),
-    ('jmp 1022',    [['OPC', 0x3dff]], 2),
+    ('jmp +1022',    [['OPC', 0x3dff]], 2),
 ]
 
 class TestFormatIII(unittest.TestCase):
     def testFormatIII(self):
         for line, iop, desired_cylces in formatIIItests:
-            insn, words, cycles = disassemble.disassemble([w for m,w in iop])
+            insn = disassemble.disassemble([w for m,w in iop])
+            words, cycles = insn.usedwords, insn.cycles
             #~ print
             #~ print insn, words, cycles 
             #~ print line, desired_cylces
-            self.failUnless(insn == line, '%r failed, wrong output (%r)' % (line, insn))
+            self.failUnless(str(insn).split() == line.split(), '%r failed, wrong output (%s)' % (line, insn))
             self.failUnless(desired_cylces == cycles, '%r failed, wrong number of cycles' % line)
 
     #~ def testOutOfRangeError(self):
@@ -142,8 +138,9 @@
         
 class TestFormatMisc(unittest.TestCase):
     def testMiscInsns(self):
-        insn, words, cycles = disassemble.disassemble([0x1300])
-        self.failUnless(insn == 'reti')
+        insn = disassemble.disassemble([0x1300])
+        words, cycles = insn.usedwords, insn.cycles
+        self.failUnless(str(insn).strip() == 'reti')
         self.failUnless(cycles == 5)
 
         



-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.
Get your fingers limbered up and give it your best shot. 4 great events, 4
opportunities to win big! Highest score wins.NEC IT Guy Games. Play to
win an NEC 61 plasma display. Visit http://www.necitguy.com/?r=20
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.