def update_memory(self): memory = [] for i in range(self.rm.cpu.ptr[1]): for j in range(constants.PAGE_SIZE): address = util.to_byte_address(i, j) memory.append(self.rm.memory.read_word(address, virtual=True)) for i in range(len(memory)): self.memory_frame.cells[i].delete(0, 'end') self.memory_frame.cells[i].insert(0, memory[i].hex())
def write_byte(self, byte_address, data, virtual=False): page, word, byte = util.to_relative_address(byte_address) if virtual: if page not in range(self._cpu.ptr[1]): raise PageFaultError() byte_address = util.to_byte_address(self._cpu.ptr[2], page) page = int.from_bytes(self.read_word(byte_address, virtual=False), byteorder=constants.BYTE_ORDER) self._pages[page][word][byte] = data
def shread(real_machine): word_count = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) dst_word = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) dst_block = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) shared_word = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) shared_block = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) dst_address = util.to_byte_address(dst_block, dst_word) shared_address = util.to_byte_address( real_machine.shared_memory[shared_block], shared_word) for i in range(word_count): word = real_machine.memory.read_word(shared_address + (i * constants.WORD_SIZE)) real_machine.memory.write_word(dst_address + (i * constants.WORD_SIZE), word, virtual=True)
def read_byte(self, byte_address, virtual=False): page, word, byte = util.to_relative_address(byte_address) if virtual: if page not in range(self._cpu.ptr[1]): raise PageFaultError() byte_address = util.to_byte_address(self._cpu.ptr[2], page) # Calling read_word() without enabling identity paging # would cause an infinite loop. page = int.from_bytes(self.read_word(byte_address, virtual=False), byteorder=constants.BYTE_ORDER) return self._pages[page][word][byte]
def out(real_machine): block = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) word = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) character_count = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) address = real_machine.current_vm.cpu.ds + \ util.to_byte_address(block, word) string = '' for i in range(character_count): string += chr(real_machine.memory.read_byte(address + i, virtual=True)) real_machine.channel_device.write_stdoutput(string)
def load(self, program): # TODO: This really doesn’t belong here. self.cpu.reset_registers() program = Assembler( self.cpu).assemble_from_data( self.program_text(program)) data_size, code_size = program.size() page_count = util.to_page_count(data_size + code_size) self._current_vm = VirtualMachine(program, self) ptr = bytearray(4) ptr[0] = data_size + code_size ptr[1] = page_count + 2 ptr[2] = self.memory.allocate(1)[0] ptr[3] = 0 self.cpu.ptr = ptr vm_allocation = self.memory.allocate(page_count + 2) for i, page in enumerate(vm_allocation): word = page.to_bytes( constants.WORD_SIZE, byteorder=constants.BYTE_ORDER ) self.memory.write_word( util.to_byte_address(self.cpu.ptr[2], i), word ) data_bytes, code_bytes = program.as_bytes() ds = 0 cs = data_size ss = cs + code_size for i in range(data_size): self.memory.write_byte(i, data_bytes[i], virtual=True) for i in range(code_size): self.memory.write_byte(i + data_size, code_bytes[i], virtual=True) self._current_vm.cpu.pc = cs self._current_vm.cpu.sp = ss self._current_vm.cpu.ds = ds self._vms.append((self._current_vm, ptr))
def in_(real_machine): block = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) word = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) character_count = int.from_bytes(real_machine.current_vm.stack_pop(), byteorder=constants.BYTE_ORDER) address = real_machine.current_vm.cpu.ds + \ util.to_byte_address(block, word) data = real_machine.channel_device.read_stdinput() for i, byte in enumerate(data): real_machine.memory.write_byte(address + i, int.from_bytes( byte, byteorder=constants.BYTE_ORDER), virtual=True)