def __init__(self, cpu_type=M68K_CPU_TYPE_68000, ram_size_kib=1024, use_labels=True, raise_on_main_run=True, cycles_per_run=1000, max_cycles=0, cpu_name=None): if cpu_name is None: cpu_name = self._get_cpu_name(cpu_type) # setup musashi components self.cpu_type = cpu_type self.cpu_name = cpu_name self.cpu = emu.CPU(cpu_type) self.mem = emu.Memory(ram_size_kib) self.traps = emu.Traps() # internal state if use_labels: self.label_mgr = LabelManager() else: self.label_mgr = None self.raise_on_main_run = raise_on_main_run self.ram_total = ram_size_kib * 1024 self.ram_bytes = self.ram_total - self.ram_begin self.error_reporter = ErrorReporter(self) self.run_states = [] self.instr_hook = None self.cycles_per_run = cycles_per_run self.max_cycles = max_cycles self.bail_out = False # call init self._setup_handler() self._setup_quick_traps() self._init_cpu() self._init_base_mem()
def __init__(self, cpu_type=M68K_CPU_TYPE_68000, ram_size_kib=1024, use_labels=True, raise_on_main_run=True): # setup musashi components self.cpu_type = cpu_type self.cpu = emu.CPU(cpu_type) self.mem = emu.Memory(ram_size_kib) self.traps = emu.Traps() self.raise_on_main_run = raise_on_main_run # internal state if use_labels: self.label_mgr = LabelManager() else: self.label_mgr = None self.ram_total = ram_size_kib * 1024 self.ram_bytes = self.ram_total - self.ram_begin self.error_reporter = ErrorReporter(self) self.run_states = [] self.mem0 = 0 self.mem4 = 0 self.shutdown_func = None self.instr_hook = None self.cycles_per_run = 1000 self.bail_out = False # call init self._alloc_trap() self._init_base_mem() self._setup_handler()
def musashi_mem_bstr_test(): mem = emu.Memory(16) data = "hello, world" mem.w_bstr(0, data) assert mem.r_bstr(0) == data empty = "" mem.w_bstr(100, empty) assert mem.r_bstr(100) == empty
def musashi_mem_cpu_rws_test(): mem = emu.Memory(16) mem.cpu_w8s(0x100, 42) assert mem.cpu_r8s(0x100) == 42 mem.cpu_w8s(0x100, -23) assert mem.cpu_r8s(0x100) == -23 mem.cpu_w16s(0x200, 0x7ead) assert mem.cpu_r16s(0x200) == 0x7ead mem.cpu_w16s(0x200, -0x1000) assert mem.cpu_r16s(0x200) == -0x1000 mem.cpu_w32s(0x300, 0x1afebabe) assert mem.cpu_r32s(0x300) == 0x1afebabe mem.cpu_w32s(0x300, -0xafebabe) assert mem.cpu_r32s(0x300) == -0xafebabe # invalid values with pytest.raises(OverflowError): mem.cpu_w8s(0x100, 0x80) with pytest.raises(OverflowError): mem.cpu_w8s(0x100, -0x81) # invalid values with pytest.raises(OverflowError): mem.cpu_w16s(0x100, 0x8000) with pytest.raises(OverflowError): mem.cpu_w16s(0x100, -0x8001) # invalid values with pytest.raises(OverflowError): mem.cpu_w32s(0x100, 0x80000000) with pytest.raises(OverflowError): mem.cpu_w32s(0x100, -0x80000001) # invalid type with pytest.raises(TypeError): mem.cpu_w8s(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.cpu_w16s(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.cpu_w32s(0x100, 'hello') # out of range with InvalidMemAccess(mem, 'W', 0, 0x10000): mem.cpu_w8s(0x10000, 0) with InvalidMemAccess(mem, 'W', 1, 0x10000): mem.cpu_w16s(0x10000, 0) with InvalidMemAccess(mem, 'W', 2, 0x10000): mem.cpu_w32s(0x10000, 0) with InvalidMemAccess(mem, 'R', 0, 0x10000): mem.cpu_r8s(0x10000) with InvalidMemAccess(mem, 'R', 1, 0x10000): mem.cpu_r16s(0x10000) with InvalidMemAccess(mem, 'R', 2, 0x10000): mem.cpu_r32s(0x10000)
def musashi_mem_cpu_rws_test(): mem = emu.Memory(16) mem.cpu_w8s(0x100, 42) assert mem.cpu_r8s(0x100) == 42 mem.cpu_w8s(0x100, -23) assert mem.cpu_r8s(0x100) == -23 mem.cpu_w16s(0x200, 0x7EAD) assert mem.cpu_r16s(0x200) == 0x7EAD mem.cpu_w16s(0x200, -0x1000) assert mem.cpu_r16s(0x200) == -0x1000 mem.cpu_w32s(0x300, 0x1AFEBABE) assert mem.cpu_r32s(0x300) == 0x1AFEBABE mem.cpu_w32s(0x300, -0xAFEBABE) assert mem.cpu_r32s(0x300) == -0xAFEBABE # invalid values with pytest.raises(OverflowError): mem.cpu_w8s(0x100, 0x80) with pytest.raises(OverflowError): mem.cpu_w8s(0x100, -0x81) # invalid values with pytest.raises(OverflowError): mem.cpu_w16s(0x100, 0x8000) with pytest.raises(OverflowError): mem.cpu_w16s(0x100, -0x8001) # invalid values with pytest.raises(OverflowError): mem.cpu_w32s(0x100, 0x80000000) with pytest.raises(OverflowError): mem.cpu_w32s(0x100, -0x80000001) # invalid type with pytest.raises(TypeError): mem.cpu_w8s(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.cpu_w16s(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.cpu_w32s(0x100, "hello") # out of range with InvalidMemAccess(mem, "W", 0, 0x10000): mem.cpu_w8s(0x10000, 0) with InvalidMemAccess(mem, "W", 1, 0x10000): mem.cpu_w16s(0x10000, 0) with InvalidMemAccess(mem, "W", 2, 0x10000): mem.cpu_w32s(0x10000, 0) with InvalidMemAccess(mem, "R", 0, 0x10000): mem.cpu_r8s(0x10000) with InvalidMemAccess(mem, "R", 1, 0x10000): mem.cpu_r16s(0x10000) with InvalidMemAccess(mem, "R", 2, 0x10000): mem.cpu_r32s(0x10000)
def musashi_mem_rws_test(): mem = emu.Memory(16) mem.w8s(0x100, 42) assert mem.r8s(0x100) == 42 mem.w8s(0x100, -23) assert mem.r8s(0x100) == -23 mem.w16s(0x200, 0x7ead) assert mem.r16s(0x200) == 0x7ead mem.w16s(0x200, -0x1000) assert mem.r16s(0x200) == -0x1000 mem.w32s(0x300, 0x1afebabe) assert mem.r32s(0x300) == 0x1afebabe mem.w32s(0x300, -0xafebabe) assert mem.r32s(0x300) == -0xafebabe mem.writes(0, 0x101, -43) assert mem.reads(0, 0x101) == -43 mem.writes(1, 0x202, -0x1234) assert mem.reads(1, 0x202) == -0x1234 mem.writes(2, 0x304, -0x11223344) assert mem.reads(2, 0x304) == -0x11223344 # invalid values with pytest.raises(OverflowError): mem.w8s(0x100, 0x80) with pytest.raises(OverflowError): mem.w8s(0x100, -0x81) # invalid values with pytest.raises(OverflowError): mem.w16s(0x100, 0x8000) with pytest.raises(OverflowError): mem.w16s(0x100, -0x8001) # invalid values with pytest.raises(OverflowError): mem.w32s(0x100, 0x80000000) with pytest.raises(OverflowError): mem.w32s(0x100, -0x80000001) # invalid type with pytest.raises(TypeError): mem.w8s(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.w16s(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.w32s(0x100, 'hello') # invalid width with pytest.raises(ValueError): mem.writes(7, 0x202, 12) with pytest.raises(ValueError): mem.reads(7, 0x202)
def musashi_mem_invalid_access_error_test(): mem = emu.Memory(16) def invalid_func(mode, width, addr): raise ValueError("bonk!") mem.set_invalid_func(invalid_func) with pytest.raises(ValueError): mem.cpu_r8(0x100000) with pytest.raises(ValueError): mem.cpu_w8(0x100000, 0) mem.set_invalid_func(None)
def musashi_mem_block_test(): mem = emu.Memory(16) data = b"hello, world!" mem.w_block(0, data) assert mem.r_block(0, len(data)) == data bdata = bytearray(data) mem.w_block(0x100, bdata) assert mem.r_block(0x100, len(bdata)) == bdata mem.clear_block(0x200, 100, 42) assert mem.r_block(0x200, 100) == bytes([42] * 100) mem.copy_block(0x200, 0x300, 20) assert mem.r_block(0x300, 21) == bytes([42] * 20) + b'\0'
def musashi_mem_cpu_rw_test(): mem = emu.Memory(16) assert mem.get_ram_size_kib() == 16 mem.cpu_w8(0x100, 42) assert mem.cpu_r8(0x100) == 42 mem.cpu_w16(0x200, 0xDEAD) assert mem.cpu_r16(0x200) == 0xDEAD mem.cpu_w32(0x300, 0xCAFEBABE) assert mem.cpu_r32(0x300) == 0xCAFEBABE # invalid values with pytest.raises(OverflowError): mem.cpu_w8(0x100, 0x100) with pytest.raises(OverflowError): mem.cpu_w8(0x100, -1) # invalid values with pytest.raises(OverflowError): mem.cpu_w16(0x100, 0x10000) with pytest.raises(OverflowError): mem.cpu_w16(0x100, -2) # invalid values with pytest.raises(OverflowError): mem.cpu_w32(0x100, 0x100000000) with pytest.raises(OverflowError): mem.cpu_w32(0x100, -3) # invalid type with pytest.raises(TypeError): mem.cpu_w8(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.cpu_w16(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.cpu_w32(0x100, "hello") # out of range with InvalidMemAccess(mem, "W", 0, 0x10000): mem.cpu_w8(0x10000, 0) with InvalidMemAccess(mem, "W", 1, 0x10000): mem.cpu_w16(0x10000, 0) with InvalidMemAccess(mem, "W", 2, 0x10000): mem.cpu_w32(0x10000, 0) with InvalidMemAccess(mem, "R", 0, 0x10000): mem.cpu_r8(0x10000) with InvalidMemAccess(mem, "R", 1, 0x10000): mem.cpu_r16(0x10000) with InvalidMemAccess(mem, "R", 2, 0x10000): mem.cpu_r32(0x10000)
def musashi_mem_cpu_rw_test(): mem = emu.Memory(16) assert mem.get_ram_size_kib() == 16 mem.cpu_w8(0x100, 42) assert mem.cpu_r8(0x100) == 42 mem.cpu_w16(0x200, 0xdead) assert mem.cpu_r16(0x200) == 0xdead mem.cpu_w32(0x300, 0xcafebabe) assert mem.cpu_r32(0x300) == 0xcafebabe # invalid values with pytest.raises(OverflowError): mem.cpu_w8(0x100, 0x100) with pytest.raises(OverflowError): mem.cpu_w8(0x100, -1) # invalid values with pytest.raises(OverflowError): mem.cpu_w16(0x100, 0x10000) with pytest.raises(OverflowError): mem.cpu_w16(0x100, -2) # invalid values with pytest.raises(OverflowError): mem.cpu_w32(0x100, 0x100000000) with pytest.raises(OverflowError): mem.cpu_w32(0x100, -3) # invalid type with pytest.raises(TypeError): mem.cpu_w8(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.cpu_w16(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.cpu_w32(0x100, 'hello') # out of range with InvalidMemAccess(mem, 'W', 0, 0x10000): mem.cpu_w8(0x10000, 0) with InvalidMemAccess(mem, 'W', 1, 0x10000): mem.cpu_w16(0x10000, 0) with InvalidMemAccess(mem, 'W', 2, 0x10000): mem.cpu_w32(0x10000, 0) with InvalidMemAccess(mem, 'R', 0, 0x10000): mem.cpu_r8(0x10000) with InvalidMemAccess(mem, 'R', 1, 0x10000): mem.cpu_r16(0x10000) with InvalidMemAccess(mem, 'R', 2, 0x10000): mem.cpu_r32(0x10000)
def musashi_mem_rw_test(): mem = emu.Memory(16) assert mem.get_ram_size_kib() == 16 mem.w8(0x100, 42) assert mem.r8(0x100) == 42 mem.w16(0x200, 0xdead) assert mem.r16(0x200) == 0xdead mem.w32(0x300, 0xcafebabe) assert mem.r32(0x300) == 0xcafebabe mem.write(0, 0x101, 43) assert mem.read(0, 0x101) == 43 mem.write(1, 0x202, 0x1234) assert mem.read(1, 0x202) == 0x1234 mem.write(2, 0x304, 0x11223344) assert mem.read(2, 0x304) == 0x11223344 # invalid values with pytest.raises(OverflowError): mem.w8(0x100, 0x100) with pytest.raises(OverflowError): mem.w8(0x100, -1) # invalid values with pytest.raises(OverflowError): mem.w16(0x100, 0x10000) with pytest.raises(OverflowError): mem.w16(0x100, -2) # invalid values with pytest.raises(OverflowError): mem.w32(0x100, 0x100000000) with pytest.raises(OverflowError): mem.w32(0x100, -3) # invalid type with pytest.raises(TypeError): mem.w8(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.w16(0x100, 'hello') # invalid type with pytest.raises(TypeError): mem.w32(0x100, 'hello') # invalid width with pytest.raises(ValueError): mem.write(7, 0x202, 12) with pytest.raises(ValueError): mem.read(7, 0x202)
def musashi_mem_trace_test(): mem = emu.Memory(16) with TraceAssert(mem, "R", 0, 0x100, 0): mem.cpu_r8(0x100) with TraceAssert(mem, "R", 1, 0x100, 0): mem.cpu_r16(0x100) with TraceAssert(mem, "R", 2, 0x100, 0): mem.cpu_r32(0x100) with TraceAssert(mem, "W", 0, 0x100, 0x42): mem.cpu_w8(0x100, 0x42) with TraceAssert(mem, "W", 1, 0x100, 0xDEAD): mem.cpu_w16(0x100, 0xDEAD) with TraceAssert(mem, "W", 2, 0x100, 0xCAFEBABE): mem.cpu_w32(0x100, 0xCAFEBABE)
def musashi_mem_trace_error_test(): mem = emu.Memory(16) def trace_func(mode, width, addr, value): raise ValueError("bonk!") mem.set_trace_mode(True) mem.set_trace_func(trace_func) with pytest.raises(ValueError): mem.cpu_r8(0x100) with pytest.raises(ValueError): mem.cpu_w8(0x100, 0) mem.set_trace_mode(False) mem.set_trace_func(None)
def musashi_mem_trace_test(): mem = emu.Memory(16) with TraceAssert(mem, 'R', 0, 0x100, 0): mem.cpu_r8(0x100) with TraceAssert(mem, 'R', 1, 0x100, 0): mem.cpu_r16(0x100) with TraceAssert(mem, 'R', 2, 0x100, 0): mem.cpu_r32(0x100) with TraceAssert(mem, 'W', 0, 0x100, 0x42): mem.cpu_w8(0x100, 0x42) with TraceAssert(mem, 'W', 1, 0x100, 0xdead): mem.cpu_w16(0x100, 0xdead) with TraceAssert(mem, 'W', 2, 0x100, 0xcafebabe): mem.cpu_w32(0x100, 0xcafebabe)
def musashi_mem_special_rw_error_test(): mem = emu.Memory(16) def read(addr): raise ValueError("blonk!") def write(addr, val): raise ValueError("blonk!") mem.set_special_range_read_funcs(0xbf0000, 1, read, None, None) mem.set_special_range_write_funcs(0xbf0000, 1, write, None, None) with pytest.raises(ValueError): mem.cpu_r8(0xbf0000) with pytest.raises(ValueError): mem.cpu_w8(0xbf0000, 42)
def main(): # retrieve vamos home and data dir home_dir = os.path.dirname(amitools.__file__) data_dir = os.path.join(home_dir, "data") # --- args -- parser = argparse.ArgumentParser() parser.add_argument('bin', help="AmigaOS binary to run") parser.add_argument('args', nargs='*', help="AmigaOS binary arguments") # config options parser.add_argument('-c', '--config-file', action='store', default=None, help="vamos config file") parser.add_argument('-S', '--skip-default-configs', action='store_true', default=False, help="do not read ~/.vamosrc or ./vamosrc") # logging config parser.add_argument('-l', '--logging', action='store', default=None, help="logging settings: <chan>:<level>,*:<level>,...") parser.add_argument('-v', '--verbose', action='store_true', default=None, help="be more verbos") parser.add_argument('-q', '--quiet', action='store_true', default=None, help="do not output any logging") parser.add_argument('-b', '--benchmark', action='store_true', default=None, help="enable benchmarking") parser.add_argument('-L', '--log-file', action='store', default=None, help="write all log messages to a file") parser.add_argument('--no-ts', action='store_true', default=False, help="do not log with timestamp") # low-level tracing parser.add_argument('-I', '--instr-trace', action='store_true', default=None, help="enable instruction trace") parser.add_argument('-t', '--memory-trace', action='store_true', default=None, help="enable memory tracing (slower)") parser.add_argument('-T', '--internal-memory-trace', action='store_true', default=None, help="enable internal memory tracing (slow)") parser.add_argument('-r', '--reg-dump', action='store_true', default=None, help="add register dump to instruction trace") # cpu emu parser.add_argument('-C', '--cpu', action='store', default=None, help="Set type of CPU to emulate (68000 or 68020)") parser.add_argument('-y', '--max-cycles', action='store', type=int, default=None, help="maximum number of cycles to execute") parser.add_argument('-B', '--cycles-per-block', action='store', type=int, default=None, help="cycles per block") # system parser.add_argument('-m', '--ram-size', action='store', default=None, type=int, help="set RAM size in KiB") parser.add_argument('-s', '--stack-size', action='store', default=None, help="set stack size in KiB") parser.add_argument('-H', '--hw-access', action='store', default=None, help="What to do on direct HW access? (emu,ignore,abort,disable)") parser.add_argument('-x', '--shell',action='store_true', default=None, help="run an AmigaOs shell instead of a binary") # dirs parser.add_argument('-D', '--data-dir', action='store', default=None, help="set vamos data directory (default: %s)" % data_dir) # lib config parser.add_argument('-O', '--lib-options', action='append', default=None, help="set lib options: <lib>+<key>=<value>,...") # path config parser.add_argument('-a', '--assign', action='append', default=None, help="add AmigaOS assign: name:[+]/sys/path[,/more/path]") parser.add_argument('-V', '--volume', action='append', default=None, help="define AmigaOS volume: name:/abs/sys/path") parser.add_argument('-A', '--auto-assign', action='store', default=None, help="define auto assign ami path, e.g. vol:/ami/path") parser.add_argument('-p', '--path', action='append', default=None, help="define command search ami path, e.g. c:") parser.add_argument('-d', '--cwd', action='store', default=None, help="set current working directory") # arg handling parser.add_argument('-P', '--pure-ami-paths', action='store_true', default=None, help="do not allow sys paths for binary") parser.add_argument('-R', '--raw-arg', action='store_true', default=None, help="pass a single unmodified argument string") args = parser.parse_args() # --- init config --- cfg = VamosConfig(extra_file=args.config_file, skip_defaults=args.skip_default_configs, args=args, def_data_dir=data_dir) # --- init logging --- if not log_setup(cfg.logging, cfg.verbose, cfg.quiet, cfg.log_file, args.no_ts): log_help() sys.exit(1) cfg.log() # ----- vamos! --------------------------------------------------------------- # setup CPU if cfg.cpu in ('68000', '000', '00'): cpu_type = m68k.M68K_CPU_TYPE_68000 cfg.cpu = '68000' elif cfg.cpu in ('68020', '020', '20'): cpu_type = m68k.M68K_CPU_TYPE_68020 cfg.cpu = '68020' elif cfg.cpu in ('68030', '030', '30'): # fake 030 CPU only to set AttnFlags accordingly cpu_type = m68k.M68K_CPU_TYPE_68020 cfg.cpu = '68030' log_main.info("fake 68030 CPU selected") else: log_main.error("Invalid CPU type: %s" % cfg.cpu) sys.exit(1) log_main.info("setting up CPU: %s = %d" % (cfg.cpu, cpu_type)) cpu = emu.CPU(cpu_type) # setup memory if cfg.hw_access != "disable": max_mem = 0xbf0000 / 1024 if cfg.ram_size >= max_mem: log_main.error("too much RAM requested. max allowed KiB: %d", max_mem) sys.exit(1) mem = emu.Memory(cfg.ram_size) log_main.info("setting up main memory with %s KiB RAM: top=%06x" % (cfg.ram_size, cfg.ram_size * 1024)) # setup traps traps = emu.Traps() # setup current working dir cwd = cfg.cwd if cwd is None: cwd = 'root:' + os.getcwd() # --- binary and arg_str --- # a single Amiga-like raw arg was passed if args.raw_arg: # check args if len(args.args) > 0: log_main.error("raw arg only allows a single argument!") sys.exit(1) # parse raw arg cl = CommandLine() res = cl.parse_line(args.bin) if res != cl.LINE_OK: log_main.error("raw arg is invalid! (error %d)", res) sys.exit(1) binary = cl.get_cmd() arg_str = cl.get_arg_str() else: # setup binary binary = args.bin if not cfg.pure_ami_paths: # if path exists on host system then make a root path if os.path.exists(binary): binary = "root:" + os.path.abspath(binary) # combine remaining args to arg_str arg_str = sys_args_to_ami_arg_str(args.args) # where does the process return? exit_addr = VamosRun.exit_addr # summary log_main.info("bin='%s', arg_str='%s', cwd='%s', shell='%s', stack=%d, exit_addr=%08x", binary, arg_str[:-1], cwd, args.shell, cfg.stack_size, exit_addr) stack_size=cfg.stack_size * 1024 # combine to vamos instance vamos = Vamos(mem, cpu, traps, cfg) vamos.init(binary, arg_str, stack_size, args.shell, cwd, exit_addr) # ------ main loop ------ # init cpu and initial registers run = VamosRun(vamos, args.benchmark, args.shell) run.init() # main loop exit_code = run.run(cfg.cycles_per_block, cfg.max_cycles) # shutdown vamos vamos.cleanup() # exit log_main.info("vamos is exiting") return exit_code
def musashi_mem_rw_test(): mem = emu.Memory(16) assert mem.get_ram_size_kib() == 16 mem.w8(0x100, 42) assert mem.r8(0x100) == 42 mem.w16(0x200, 0xDEAD) assert mem.r16(0x200) == 0xDEAD mem.w32(0x300, 0xCAFEBABE) assert mem.r32(0x300) == 0xCAFEBABE mem.write(0, 0x101, 43) assert mem.read(0, 0x101) == 43 mem.write(1, 0x202, 0x1234) assert mem.read(1, 0x202) == 0x1234 mem.write(2, 0x304, 0x11223344) assert mem.read(2, 0x304) == 0x11223344 # invalid values with pytest.raises(OverflowError): mem.w8(0x100, 0x100) with pytest.raises(OverflowError): mem.w8(0x100, -1) # invalid values with pytest.raises(OverflowError): mem.w16(0x100, 0x10000) with pytest.raises(OverflowError): mem.w16(0x100, -2) # invalid values with pytest.raises(OverflowError): mem.w32(0x100, 0x100000000) with pytest.raises(OverflowError): mem.w32(0x100, -3) # invalid type with pytest.raises(TypeError): mem.w8(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.w16(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.w32(0x100, "hello") # invalid width with pytest.raises(ValueError): mem.write(7, 0x202, 12) with pytest.raises(ValueError): mem.read(7, 0x202) # out of range with pytest.raises(emu.MemoryError): mem.w8(0x10000, 0) with pytest.raises(emu.MemoryError): mem.w16(0x10000, 0) with pytest.raises(emu.MemoryError): mem.w32(0x10000, 0) with pytest.raises(emu.MemoryError): mem.write(0, 0x10000, 0) with pytest.raises(emu.MemoryError): mem.r8(0x10000) with pytest.raises(emu.MemoryError): mem.r16(0x10000) with pytest.raises(emu.MemoryError): mem.r32(0x10000) with pytest.raises(emu.MemoryError): mem.read(0, 0x10000)
def main(): # retrieve vamos home and data dir home_dir = os.path.dirname(amitools.__file__) data_dir = os.path.join(home_dir, "data") # --- args -- parser = argparse.ArgumentParser() parser.add_argument('bin', help="AmigaOS binary to run") parser.add_argument('args', nargs='*', help="AmigaOS binary arguments") # config options parser.add_argument('-c', '--config-file', action='store', default=None, help="vamos config file") parser.add_argument('-S', '--skip-default-configs', action='store_true', default=False, help="do not read ~/.vamosrc or ./vamosrc") # logging config parser.add_argument('-l', '--logging', action='store', default=None, help="logging settings: <chan>:<level>,*:<level>,...") parser.add_argument('-v', '--verbose', action='store_true', default=None, help="be more verbos") parser.add_argument('-q', '--quiet', action='store_true', default=None, help="do not output any logging") parser.add_argument('-b', '--benchmark', action='store_true', default=None, help="enable benchmarking") parser.add_argument('-L', '--log-file', action='store', default=None, help="write all log messages to a file") # low-level tracing parser.add_argument('-I', '--instr-trace', action='store_true', default=None, help="enable instruction trace") parser.add_argument('-t', '--memory-trace', action='store_true', default=None, help="enable memory tracing (slower)") parser.add_argument('-T', '--internal-memory-trace', action='store_true', default=None, help="enable internal memory tracing (slow)") parser.add_argument('-r', '--reg-dump', action='store_true', default=None, help="add register dump to instruction trace") # cpu emu parser.add_argument('-C', '--cpu', action='store', default=None, help="Set type of CPU to emulate (68000 or 68020)") parser.add_argument('-y', '--max-cycles', action='store', type=int, default=None, help="maximum number of cycles to execute") parser.add_argument('-B', '--cycles-per-block', action='store', type=int, default=None, help="cycles per block") # system parser.add_argument('-m', '--ram-size', action='store', default=None, type=int, help="set RAM size in KiB") parser.add_argument('-s', '--stack-size', action='store', default=None, help="set stack size in KiB") parser.add_argument( '-H', '--hw-access', action='store', default=None, help="What to do on direct HW access? (emu,ignore,abort,disable)") parser.add_argument('-x', '--shell', action='store_true', default=None, help="run an AmigaOs shell instead of a binary") # dirs parser.add_argument('-D', '--data-dir', action='store', default=None, help="set vamos data directory (default: %s)" % data_dir) # lib config parser.add_argument('-O', '--lib-options', action='append', default=None, help="set lib options: <lib>:<key>=<value>,...") # path config parser.add_argument( '-a', '--assign', action='append', default=None, help="add AmigaOS assign: name:[+]/sys/path[,/more/path]") parser.add_argument('-V', '--volume', action='append', default=None, help="define AmigaOS volume: name:/abs/sys/path") parser.add_argument('-A', '--auto-assign', action='store', default=None, help="define auto assign ami path, e.g. vol:/ami/path") parser.add_argument('-p', '--path', action='append', default=None, help="define command search ami path, e.g. c:") parser.add_argument('-d', '--cwd', action='store', default=None, help="set current working directory") args = parser.parse_args() # --- init config --- cfg = VamosConfig(extra_file=args.config_file, skip_defaults=args.skip_default_configs, args=args, def_data_dir=data_dir) # --- init logging --- if not log_setup(cfg.logging, cfg.verbose, cfg.quiet, cfg.log_file): log_help() sys.exit(1) cfg.log() # ----- vamos! --------------------------------------------------------------- # setup CPU if cfg.cpu in ('68000', '000', '00'): cpu_type = m68k.M68K_CPU_TYPE_68000 elif cfg.cpu in ('68020', '020', '20'): cpu_type = m68k.M68K_CPU_TYPE_68020 else: log_main.error("Invalid CPU type: %s" % cfg.cpu) sys.exit(1) log_main.info("setting up CPU: %s = %d" % (cfg.cpu, cpu_type)) cpu = emu.CPU(cpu_type) # setup memory if cfg.hw_access != "disable": max_mem = 0xbf0000 / 1024 if cfg.ram_size >= max_mem: log_main.error("too much RAM requested. max allowed KiB: %d", max_mem) sys.exit(1) mem = emu.Memory(cfg.ram_size) log_main.info("setting up main memory with %s KiB RAM: top=%06x" % (cfg.ram_size, cfg.ram_size * 1024)) # setup traps traps = emu.Traps() # combine to vamos instance vamos = Vamos(mem, cpu, traps, cfg) vamos.init() # --- create main process --- # setup current working dir cwd = args.cwd if cwd is None: cwd = 'root:' + os.getcwd() proc = Process(vamos, args.bin, args.args, stack_size=cfg.stack_size * 1024, shell=args.shell, cwd=cwd) if not proc.ok: sys.exit(1) vamos.set_main_process(proc) # ------ main loop ------ # init cpu and initial registers run = VamosRun(vamos, args.benchmark, args.shell) run.init() # main loop exit_code = run.run(cfg.cycles_per_block, cfg.max_cycles) # free process proc.free() # shutdown vamos vamos.cleanup() # exit log_main.info("vamos is exiting") return exit_code
def musashi_mem_rws_test(): mem = emu.Memory(16) mem.w8s(0x100, 42) assert mem.r8s(0x100) == 42 mem.w8s(0x100, -23) assert mem.r8s(0x100) == -23 mem.w16s(0x200, 0x7EAD) assert mem.r16s(0x200) == 0x7EAD mem.w16s(0x200, -0x1000) assert mem.r16s(0x200) == -0x1000 mem.w32s(0x300, 0x1AFEBABE) assert mem.r32s(0x300) == 0x1AFEBABE mem.w32s(0x300, -0xAFEBABE) assert mem.r32s(0x300) == -0xAFEBABE mem.writes(0, 0x101, -43) assert mem.reads(0, 0x101) == -43 mem.writes(1, 0x202, -0x1234) assert mem.reads(1, 0x202) == -0x1234 mem.writes(2, 0x304, -0x11223344) assert mem.reads(2, 0x304) == -0x11223344 # invalid values with pytest.raises(OverflowError): mem.w8s(0x100, 0x80) with pytest.raises(OverflowError): mem.w8s(0x100, -0x81) # invalid values with pytest.raises(OverflowError): mem.w16s(0x100, 0x8000) with pytest.raises(OverflowError): mem.w16s(0x100, -0x8001) # invalid values with pytest.raises(OverflowError): mem.w32s(0x100, 0x80000000) with pytest.raises(OverflowError): mem.w32s(0x100, -0x80000001) # invalid type with pytest.raises(TypeError): mem.w8s(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.w16s(0x100, "hello") # invalid type with pytest.raises(TypeError): mem.w32s(0x100, "hello") # invalid width with pytest.raises(ValueError): mem.writes(7, 0x202, 12) with pytest.raises(ValueError): mem.reads(7, 0x202) # out of range with pytest.raises(emu.MemoryError): mem.w8s(0x10000, 0) with pytest.raises(emu.MemoryError): mem.w16s(0x10000, 0) with pytest.raises(emu.MemoryError): mem.w32s(0x10000, 0) with pytest.raises(emu.MemoryError): mem.writes(0, 0x10000, 0) with pytest.raises(emu.MemoryError): mem.r8s(0x10000) with pytest.raises(emu.MemoryError): mem.r16s(0x10000) with pytest.raises(emu.MemoryError): mem.r32s(0x10000) with pytest.raises(emu.MemoryError): mem.reads(0, 0x10000)