def t(self): pos = self.cpu.sp + 1 stack = self.cpu.stack_contents address = self.cpu.pc + 1 routine = '<current>' items = 0 while pos < len(stack): if stack[pos] == x6502.STACK_VALUE: items += 1 pos += 1 elif stack[pos] == x6502.STACK_ADDRESS: print '{} {:2d} {}'.format(vm.hex16(address), items, routine) return_address = self.mem[memmap.STACK_PAGE + pos::2] if return_address + 1 == self.meta['MONITOR']: break address = return_address - 2 jsr_to = self.mem[address + 1::2] routine = self.meta.get_argument(address) if routine is None: routine = 'jsr ' + vm.hex16(jsr_to) else: routine = 'jsr ' + routine pos += 2 items = 0 else: raise x6502.StackError('Corrupt stack')
def w(self, location=None): if location is None: for address in sorted(self.watches): print vm.hex16(address) + self._labels_at_address(address) else: address = self.meta[location] if address == 0: self.watches.clear() elif address in self.watches: self.watches.remove(address) else: self.watches.add(address)
def __str__(self): b = self._format_bytes() i = self._format_instruction() lines = [] for label in self.labels: lines += [label + ':'] for remark in self.remarks: lines += [' ; ' + remark] if self.data is not None and self.data.valid: lines += [' {}: data {}'.format(vm.hex16(self.data.address), self.data.text)] else: lines += [" {}: {} {}".format(vm.hex16(self.address), b, i)] return '\n'.join(lines)
def f(self, pattern=None): if pattern is None: pattern = '.*' symbols = sorted(list(self.meta.labels.keys())) lines = list() for symbol in symbols: if not re.search(pattern, symbol) is None: lines.append(vm.hex16(vm.mask16(self.meta[symbol])) + " = " + symbol) print '\n'.join(lines)
def _find_block(self, address): """ Given an address, find the block it is mapped to and the index into that block. """ for block, start_address in self._blocks: if (address >= start_address and address < start_address + len(block)): return block, address - start_address raise AddressBusError('No such address: {}'.format(vm.hex16(address)))
def v(self): reference_lists = self.meta.get_unresolved().values() if len(reference_lists) == 0: return results = [] for reference_list in reference_lists: results += [r for r in reference_list] for r in sorted(results, key=lambda x: x.address): expr_str = '' if r.expr is None else ': ' + str(r.expr) print '{} {:3s} {:s}{:s}'.format(vm.hex16(r.address), r.type, r.ref, expr_str)
def _find_page(self, index): """ Given an index, find the page that index belongs to and the offset into that page. """ page = index / vm.PAGE_SIZE offset = index % vm.PAGE_SIZE if page < 0 or page >= self._page_count: raise IndexError('Invalid page for index: {}' .format(vm.hex16(index))) return page, offset
def _setitem_single(self, index, value): """ Notifies listeners for each byte store and calls abstract _load. Emits warning if read only. """ if self.read_only: raise ReadOnlyError('Write {} to read-only location {}' .format(vm.hex8(value), vm.hex16(index))) else: self._store(vm.size16(index), value) [listener(index, value) for listener in self.store_listeners]
def _format_instruction(self): """ Formats the instruction name and arguments. """ i = self.instruction try: formatter, has_argument = FORMAT_TABLE[i.addressing_mode] except KeyError: raise ValueError('Invalid addressing mode: ' + str(i.addressing_mode)) if not has_argument: return formatter.format(i.operation) if self.argument is None: # Format the raw bytes if len(self.bytes) == 2: arg = vm.hex8(self.bytes[1]) else: arg = vm.hex16(vm.to_words(self.bytes[1:3])[0]) else: arg = self.argument return formatter.format(i.operation, arg)
def next(self): """ Description """ d = Disassembled() d.address = vm.size16(self.position) d.labels = self.meta.get_labels(d.address) d.remarks = self.meta.get_remarks(d.address) d.argument = self.meta.get_argument(d.address) d.data = self.meta.get_data(d.address) if d.data is not None: self.position = d.data.address + d.data.length return d opcode = self.pc.load() if opcode in self._opcodes: i = self._opcodes[opcode] else: op = '?{:02X}'.format(opcode) i = x6502.Instruction(opcode, op, am.IMP, None) d.instruction = i if i.addressing_mode in AM_ADDRESS_16: arg = self.pc.load2() d.bytes = [opcode, vm.lb(arg), vm.hb(arg)] elif (i.addressing_mode in AM_ADDRESS_8 or i.addressing_mode in (am.REL, am.IMM)): arg = self.pc.load() if i.addressing_mode == am.REL and d.argument is None: # Branch is displacement after consuming bytes, therefore # add two. d.argument = vm.hex16(d.address + vm.twos_inverse(arg) + 2) d.bytes = [opcode, arg] elif i.addressing_mode in AM_NO_ARGUMENT: d.bytes = [opcode] else: assert False return d
def add_reference(self, ref, address, type, expr=None): """ Adds a reference to *ref* from *address*. Value for *ref* can be either a symbol or an address. The *type* of reference is one of the following: ============================= ========================================= Constant Description ============================= ========================================= ``tools.REFERENCE_ABSOLUTE`` A 16-bit absolute address. ``tools.REFERENCE_RELATIVE`` An 8-bit address displacement. ``tools.REFERENCE_ZERO_PAGE`` An 8-bit absolute zero page address. ``tools.REFERENCE_VALUE`` An 8-bit value from an expression which must be deferred. ============================= ========================================= If *ref* is a symbol that does not exist, an unresolved reference entry is created and can be retrieved via :meth:`get_unresolved`. If *expr* is specified, this :ref:`expression <code_expression>` should be reevaluated once all references are resolved. If resolved, returns the value of the reference, otherwise returns zero. """ if isinstance(ref, int): referenced_address = ref # The actual address should be displayed, not the displacement if type == REFERENCE_RELATIVE: self.set_argument(address, vm.hex16(referenced_address)) return referenced_address elif isinstance(ref, expression.Expression): expr = ref return self._expression_reference(expr, address, type) else: name = ref return self._symbol_reference(name, address, type, expr)
def _memory_watcher(self, address, value): if address in self.watches: print 'mem {} <-= {}{}'.format(vm.hex16(address), vm.hex8(value), self._labels_at_address(address))
def memory_store_listener(self, address, value): if not self.logging_run: suite.log.info('mem {} <-= {}'.format(vm.hex16(address), vm.hex8(value)))
def test_hex16(self): self.assertEquals('$0abc', vm.hex16(0x0abc))