def _install_mpu_observers(self,getc_addr,putc_addr,fsio_addr): def putc(address, value): try: self.stdout.write(chr(value)) except UnicodeEncodeError: # Python 3 self.stdout.write("?") self.stdout.flush() def getc(address): char = console.getch_noblock(self.stdin) if char: byte = ord(char) else: byte = 0 return byte m = ObservableMemory(addrWidth=self.addrWidth) m.subscribe_to_write([self.putc_addr], putc) m.subscribe_to_read([self.getc_addr], getc) fs = FileSystem() fsio_range = range(fsio_addr, fsio_addr+fs.registers) m.subscribe_to_write(fsio_range, fs.write_mem) m.subscribe_to_read(fsio_range, fs.read_mem) self._mpu.memory = m
def test__subscribe_to_read_does_not_register_same_listener_twice(self): subject = self._make_subject() mem = ObservableMemory(subject=subject) calls = [] def read_subscriber(address): calls.append('read_subscriber') mem.subscribe_to_read([0xC000], read_subscriber) mem.subscribe_to_read([0xC000], read_subscriber) value = mem[0xC000] self.assertEqual(['read_subscriber'], calls)
def test_subscribe_to_read_covers_all_addresses_in_range(self): subject = self._make_subject() mem = ObservableMemory(subject=subject) def read_subscriber(address, value): return 0xAB mem.subscribe_to_read(xrange(0xC000, 0xC001+1), read_subscriber) mem[0xC000] = 0xAB mem[0xC001] = 0xAB self.assertEqual(0xAB, subject[0xC001]) self.assertEqual(0xAB, subject[0xC001])
def test_subscribe_to_read_covers_all_addresses_in_range(self): subject = self._make_subject() mem = ObservableMemory(subject=subject) def read_subscriber(address, value): return 0xAB mem.subscribe_to_read(range(0xC000, 0xC001 + 1), read_subscriber) mem[0xC000] = 0xAB mem[0xC001] = 0xAB self.assertEqual(0xAB, subject[0xC001]) self.assertEqual(0xAB, subject[0xC001])
def test___getitem__ignores_read_subscribers_returning_none(self): subject = self._make_subject() mem = ObservableMemory(subject=subject) def read_subscriber_1(address): return None def read_subscriber_2(address): return None mem.subscribe_to_read([0xC000], read_subscriber_1) mem.subscribe_to_read([0xC000], read_subscriber_2) mem[0xC000] = 0xAB self.assertEqual(0xAB, subject[0xC000])
def _install_mpu_observers(self): def putc(address, value): self.stdout.write(chr(value)) self.stdout.flush() def getc(address): char = console.getch_noblock(self.stdin) if char: byte = ord(char) else: byte = 0 return byte m = ObservableMemory(addrWidth=self.addrWidth) m.subscribe_to_write([0xF001], putc) m.subscribe_to_read([0xF004], getc) self._mpu.memory = m
def _install_mpu_observers(self, getc_addr, putc_addr): def putc(address, value): try: self.stdout.write(chr(value)) except UnicodeEncodeError: # Python 3 self.stdout.write("?") self.stdout.flush() def getc(address): char = console.getch_noblock(self.stdin) if char: byte = ord(char) else: byte = 0 return byte m = ObservableMemory(subject=self.memory, addrWidth=self.addrWidth) m.subscribe_to_write([self.putc_addr], putc) m.subscribe_to_read([self.getc_addr], getc) self._mpu.memory = m
def test___getitem__calls_all_read_subscribers_uses_last_result(self): subject = self._make_subject() mem = ObservableMemory(subject=subject) calls = [] def read_subscriber_1(address): calls.append('read_subscriber_1') return 0x01 def read_subscriber_2(address): calls.append('read_subscriber_2') return 0x02 mem.subscribe_to_read([0xC000], read_subscriber_1) mem.subscribe_to_read([0xC000], read_subscriber_2) subject[0xC000] = 0xAB self.assertEqual(0x02, mem[0xC000]) expected_calls = ['read_subscriber_1', 'read_subscriber_2'] self.assertEqual(expected_calls, calls)
def _install_mpu_observers(self,getc_addr,putc_addr): def putc(address, value): try: self.stdout.write(chr(value)) except UnicodeEncodeError: # Python 3 self.stdout.write("?") self.stdout.flush() def getc(address): char = console.getch_noblock(self.stdin) if char: byte = ord(char) else: byte = 0 return byte m = ObservableMemory(addrWidth=self.addrWidth) m.subscribe_to_write([self.putc_addr], putc) m.subscribe_to_read([self.getc_addr], getc) self._mpu.memory = m
def _install_io(self): def getc_from_test(_): """Parameter (originally "address") required by py65mon but unused here as "_" """ global test_string, test_index test_index = test_index + 1 if test_index < len(test_string): result = ord(test_string[test_index]) else: result = 0 return result def putc_results(_, value): """First parameter (originally "address") required by py65mon but unused here as "_" """ global fout # Save results to file. if value != 0: if not args.suppress_tester or \ test_index > end_of_tester: fout.write(chr(value).encode()) # Print to the screen if we are not muted. if not args.mute: if not args.suppress_tester or \ test_index > end_of_tester: sys.stdout.write(chr(value)) sys.stdout.flush() # Install the above handlers for I/O mem = ObservableMemory(subject=self.memory) mem.subscribe_to_write([0xF001], putc_results) mem.subscribe_to_read([0xF004], getc_from_test) self._mpu.memory = mem
def _install_io(self): def getc_from_test(_): """Parameter (originally "address") required by py65mon but unused here as "_" """ global test_string, test_index test_index = test_index + 1 if test_index < len(test_string): result = ord(test_string[test_index]) else: result = 0 return result def putc_results(_, value): """First parameter (originally "address") required by py65mon but unused here as "_" """ global fout # Save results to file. if value != 0: fout.write(chr(value).encode()) # Print to the screen if we are not muted. if not args.mute: sys.stdout.write(chr(value)) sys.stdout.flush() def update_cycle_start(_): """Parameter (originally "address") required by py65mon but unused here as "_" """ # When this address is read from, note the cycle time. self.cycle_start = self._mpu.processorCycles return 0 def update_cycle_end(_): """Parameter (originally "address") required by py65mon but unused here as "_" """ # When this address is read from, note the cycle time. self.cycle_end = self._mpu.processorCycles # # Compute the elapsed time (in CPU cycles). # # With a 1MHz clock, this will also be in microseconds. # fout.write((" CYCLES: "+str(self.cycle_end-self.cycle_start)+" ").encode()) # # # Print to the screen if we are not muted. # if not args.mute: # sys.stdout.write((" CYCLES: "+str(self.cycle_end-self.cycle_start)+" ")) # sys.stdout.flush() return 0 def read_cycle_count(address): """Break up the 32-bit result into bytes for Tali to read out of virtual memory. Note that the hex value 12345678 is stored in memory as bytes 34 12 78 56. The value will be read (as a double) starting at memory address 0xFF00 """ if address == 0xFF00: return ((self.cycle_end-self.cycle_start)&0x00FF0000)>>16 elif address == 0xFF01: return ((self.cycle_end-self.cycle_start)&0xFF000000)>>24 elif address == 0xFF02: return ((self.cycle_end-self.cycle_start)&0x000000FF) elif address == 0xFF03: return ((self.cycle_end-self.cycle_start)&0x0000FF00)>>8 else: return 0 # Install the above handlers for I/O mem = ObservableMemory(subject=self.memory) mem.subscribe_to_write([0xF001], putc_results) mem.subscribe_to_read([0xF004], getc_from_test) # Install the handlers for timing cycles. mem.subscribe_to_read([0xF002], update_cycle_start) mem.subscribe_to_read([0xF003], update_cycle_end) mem.subscribe_to_read([0xFF00, 0xFF01, 0xFF02, 0xFF03], read_cycle_count) self._mpu.memory = mem