def run(self, cycles_per_run=1000, max_cycles=0): """main run loop of vamos""" log_main.info("start cpu: %06x", self.ctx.process.prog_start) total_cycles = 0 start_time = time.clock() # main loop try: while self.stay: total_cycles += self.cpu.execute(cycles_per_run) # end after enough cycles if max_cycles > 0 and total_cycles >= max_cycles: break # some error fored a quit? if self.et.has_errors: break except Exception as e: self.et.report_error(e) end_time = time.clock() # calc benchmark values if self.benchmark: self._calc_benchmark(total_cycles, end_time - start_time) # if errors happened then report them now if self.et.has_errors: exit_code = 1 else: # get exit code from CPU exit_code = int(self.cpu.r_reg(REG_D0)) log_main.info("exit code=%d", exit_code) return exit_code
def init_cpu(self): # prepare m68k log_main.info("setting up m68k") # setup stack & first PC self.mem.access.w32(0, self.ctx.process.stack_initial) self.mem.access.w32(4, self.ctx.process.prog_start) self.cpu.pulse_reset() # set end RESET opcode at 0 and execbase at 4 op_reset = 0x04e70 self.mem.access.w16(0, op_reset) self.mem.access.w32(4, self.ctx.exec_lib.addr_base) # setup arg in D0/A0 self.cpu.w_reg(REG_D0, self.ctx.process.arg_len) self.cpu.w_reg(REG_A0, self.ctx.process.arg_base) # d2=stack_size. this value is also in 4(sp) (see Process.init_stack), but # various C programs rely on it being present (1.3-3.1 at least have it). self.cpu.w_reg(REG_D2, self.ctx.process.stack_size) # to track old dos values self.cpu.w_reg(REG_A2, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A5, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A6, self.ctx.dos_guard_base)
def _init_cpu(self): # prepare m68k log_main.info("setting up m68k") # setup stack & first PC self.mem.access.w32(0, self.ctx.process.stack_initial) self.mem.access.w32(4, self.ctx.process.prog_start) self.cpu.pulse_reset() # set end RESET opcode at 0 and execbase at 4 op_reset = 0x04e70 self.mem.access.w16(0, op_reset) self.mem.access.w32(4, self.ctx.exec_lib.addr_base) # setup arg in D0/A0 if self.shell: # thor: If we run a shell through vamos, then # BPCL places the BPTR to the parameter packet into # d1. The default shell can work without ParmPkt # thus leave this at zero for this time. self.cpu.w_reg(REG_D1, 0) else: self.cpu.w_reg(REG_D0, self.ctx.process.arg_len) self.cpu.w_reg(REG_A0, self.ctx.process.arg_base) # d2=stack_size. this value is also in 4(sp) (see Process.init_stack), but # various C programs rely on it being present (1.3-3.1 at least have it). self.cpu.w_reg(REG_D2, self.ctx.process.stack_size) # to track old dos values self.cpu.w_reg(REG_A2, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A5, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A6, self.ctx.dos_guard_base)
def run(self, cycles_per_run=1000, max_cycles=0): """main run loop of vamos""" log_main.info("start cpu: %06x", self.ctx.process.prog_start) total_cycles = 0 start_time = time.clock() # main loop while self.stay: total_cycles += self.cpu.execute(cycles_per_run) # end after enough cycles if max_cycles > 0 and total_cycles >= max_cycles: break # some error fored a quit? if self.et.has_errors: break end_time = time.clock() # calc benchmark values if self.benchmark: self._calc_benchmark( total_cycles, end_time - start_time ) # if errors happened then report them now if self.et.has_errors: log_main.error("After %d cycles:", total_cycles) self.et.dump() exit_code = 1 else: # get exit code from CPU exit_code = int(self.cpu.r_reg(REG_D0)) log_main.info("exit code=%d", exit_code) return exit_code
def _calc_benchmark(self, total_cycles, delta_time): python_time = self.ctx.lib_mgr.bench_total cpu_time = delta_time - python_time mhz = total_cycles / (1000000.0 * delta_time) cpu_percent = cpu_time * 100.0 / delta_time python_percent = 100.0 - cpu_percent log_main.info("done %d cycles in host time %.4fs -> %5.2f MHz m68k CPU", total_cycles, cpu_time, mhz) log_main.info("code time %.4fs (%.2f %%), python time %.4fs (%.2f %%) -> total time %.4fs", \ cpu_time, cpu_percent, python_time, python_percent, delta_time)
def _init_cpu(self): # prepare m68k log_main.info("setting up m68k") # setup stack & first PC self.mem.w32(0, self.ctx.process.stack_initial) self.mem.w32(4, self.ctx.process.prog_start) self.cpu.pulse_reset() # clear long at 0 and set execbase at 4 self.mem.w32(0, 0) self.mem.w32(4, self.ctx.exec_addr) # at exit_addr (0x400) we setup the return actions after process end: # we want to call a shutdown trap that is able to setup some cleanup # trampoline if necessary. This requires that the trap is called via # jsr so the auto_rts of the trap can be delayed by the stack entry # the trampoline prepared... # alloc trap tid = self.ctx.traps.setup(self.shutdown_trap, auto_rts=True) addr = self.exit_addr # place the following code: # 0x400: bsr.b 4 # 0x402: reset -> triggers end of CPU emu # 0x404: trap (with auto_rts) op_bsr = 0x6102 op_reset = 0x04e70 op_trap = 0xa000 + tid self.mem.w16(addr, op_bsr) self.mem.w16(addr + 2, op_reset) self.mem.w16(addr + 4, op_trap) # store location of reset opcode so reset handler knows what the final reset it self.reset_addr = addr + 2 # setup arg in D0/A0 if self.shell: # thor: If we run a shell through vamos, then # BPCL places the BPTR to the parameter packet into # d1. The default shell can work without ParmPkt # thus leave this at zero for this time. self.cpu.w_reg(REG_D1, 0) else: self.cpu.w_reg(REG_D0, self.ctx.process.arg_len) self.cpu.w_reg(REG_A0, self.ctx.process.arg_base) # d2=stack_size. this value is also in 4(sp) (see Process.init_stack), but # various C programs rely on it being present (1.3-3.1 at least have it). self.cpu.w_reg(REG_D2, self.ctx.process.stack_size) # to track old dos values self.cpu.w_reg(REG_A2, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A5, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A6, self.ctx.dos_guard_base)
def log(self): """after logging is setup dump info and other remarks""" if len(self.found_files) == 0: log_main.info("no config file found: %s" % ",".join(self.files)) else: log_main.info("read config file: %s" % ",".join(self.found_files)) # dump config self._dump() # print recorded errors if len(self.errors) > 0: for e in self.errors: log_main.error("config error: " + e)
def init_cpu(self): # prepare m68k log_main.info("setting up m68k") # setup stack & first PC self.mem.access.w32(0, self.ctx.process.stack_initial) self.mem.access.w32(4, self.ctx.process.prog_start) self.cpu.pulse_reset() # set end RESET opcode at 0 and execbase at 4 op_reset = 0x04e70 self.mem.access.w16(0, op_reset) self.mem.access.w32(4, self.ctx.exec_lib.lib_base) # setup arg in D0/A0 self.cpu.w_reg(REG_D0, self.ctx.process.arg_len) self.cpu.w_reg(REG_A0, self.ctx.process.arg_base) # to track old dos values self.cpu.w_reg(REG_A2, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A5, self.ctx.dos_guard_base) self.cpu.w_reg(REG_A6, self.ctx.dos_guard_base)
def run(self, cycles_per_run=1000, max_cycles=0): """main run loop of vamos""" log_main.info("start cpu: %06x", self.ctx.process.prog_start) total_cycles = 0 start_time = time.clock() # main loop while self.stay: total_cycles += self.cpu.execute(cycles_per_run) # end after enough cycles if max_cycles > 0 and total_cycles >= max_cycles: break # some error fored a quit? if self.et.has_errors: break end_time = time.clock() delta_time = end_time - start_time cpu_time = delta_time - self.trap_time mhz = total_cycles / (1000000.0 * delta_time) cpu_percent = cpu_time * 100.0 / delta_time trap_percent = 100.0 - cpu_percent log_main.info( "done %d cycles in host time %.4fs -> %5.2f MHz m68k CPU", total_cycles, cpu_time, mhz) log_main.info("code time %.4fs (%.2f %%), trap time %.4fs (%.2f %%) -> total time %.4fs", \ cpu_time, cpu_percent, self.trap_time, trap_percent, delta_time) # if errors happened then report them now if self.et.has_errors: log_main.error("After %d cycles:", total_cycles) self.et.dump() exit_code = 1 else: # get exit code from CPU exit_code = int(self.cpu.r_reg(REG_D0)) log_main.info("exit code=%d", exit_code) return exit_code
def run(self, cycles_per_run=1000, max_cycles=0): """main run loop of vamos""" log_main.info("start cpu: %06x", self.ctx.process.prog_start) total_cycles = 0 start_time = time.clock() # main loop while self.stay: total_cycles += self.cpu.execute(cycles_per_run) # end after enough cycles if max_cycles > 0 and total_cycles >= max_cycles: break # some error fored a quit? if self.et.has_errors: break end_time = time.clock() delta_time = end_time - start_time cpu_time = delta_time - self.trap_time mhz = total_cycles / (1000000.0 * delta_time) cpu_percent = cpu_time * 100.0 / delta_time trap_percent = 100.0 - cpu_percent log_main.info("done %d cycles in host time %.4fs -> %5.2f MHz m68k CPU", total_cycles, cpu_time, mhz) log_main.info("code time %.4fs (%.2f %%), trap time %.4fs (%.2f %%) -> total time %.4fs", \ cpu_time, cpu_percent, self.trap_time, trap_percent, delta_time) # if errors happened then report them now if self.et.has_errors: log_main.error("After %d cycles:", total_cycles) self.et.dump() exit_code = 1 else: # get exit code from CPU exit_code = int(self.cpu.r_reg(REG_D0)) log_main.info("exit code=%d", exit_code) return exit_code
def shutdown_trap(self, op, pc): log_main.info("shutdown trap") # trigger lib manager to shutdown libs self.ctx.lib_mgr.shutdown()
def log(self): if len(self.found_files) == 0: log_main.info("no config file found: %s" % ",".join(self.files)) else: log_main.info("read config file: %s" % ",".join(self.found_files))