From 74d4cb08963c2ba009921e3a92c3900c889cfb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Fabre?= Date: Mon, 5 Jun 2023 22:48:38 +0200 Subject: [PATCH] added a few features to maybe run WinUAE cputest - don't crash if invalid character printed, print space instead - support for AllocAbs --- amitools/vamos/lib/ExecLibrary.py | 29 +++++++++++-- amitools/vamos/lib/dos/Printf.py | 5 ++- amitools/vamos/mem/alloc.py | 70 +++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 4 deletions(-) diff --git a/amitools/vamos/lib/ExecLibrary.py b/amitools/vamos/lib/ExecLibrary.py index 53d68fc6..868c70c1 100644 --- a/amitools/vamos/lib/ExecLibrary.py +++ b/amitools/vamos/lib/ExecLibrary.py @@ -347,8 +347,30 @@ def DeletePool(self, ctx): "DeletePooled: invalid memory pool: ptr=%06x" % poolid ) + def SuperState(self, ctx): + # not complete with stack change and all but at least allows + # to run privileged instructions + ctx.cpu.w_sr(ctx.cpu.r_sr() | 0x2000) + #ctx.cpu.w_msp(ctx.cpu.r_usp()-0x400) + + def UserState(self, ctx): + # not complete with stack change and all but at least allows + # to return to user state + ctx.cpu.w_sr(ctx.cpu.r_sr() & 0x7FF) + #ctx.cpu.w_msp(ctx.cpu.r_usp()-0x400) + # ----- Memory Handling ----- + def AllocAbs(self, ctx): + size = ctx.cpu.r_reg(REG_D0) + location = ctx.cpu.r_reg(REG_A1) + # label alloc + pc = self.get_callee_pc(ctx) + name = "AllocAbs(%06x)" % pc + mb = self.alloc.alloc_abs_memory(location, size, label=name) + log_exec.info("AllocAbs: %s -> 0x%06x %d bytes" % (mb, mb.addr, size)) + return mb.addr + def AllocMem(self, ctx): size = ctx.cpu.r_reg(REG_D0) flags = ctx.cpu.r_reg(REG_D1) @@ -370,9 +392,10 @@ def FreeMem(self, ctx): log_exec.info("FreeMem: 0x%06x %d bytes -> %s" % (addr, size, mb)) self.alloc.free_memory(mb) else: - raise VamosInternalError( - "FreeMem: Unknown memory to free: ptr=%06x size=%06x" % (addr, size) - ) + pass + #raise VamosInternalError( + # "FreeMem: Unknown memory to free: ptr=%06x size=%06x" % (addr, size) + #) def AllocVec(self, ctx): size = ctx.cpu.r_reg(REG_D0) diff --git a/amitools/vamos/lib/dos/Printf.py b/amitools/vamos/lib/dos/Printf.py index b2c48f61..e88f63af 100644 --- a/amitools/vamos/lib/dos/Printf.py +++ b/amitools/vamos/lib/dos/Printf.py @@ -160,7 +160,10 @@ def printf_read_data(state, mem_access, data_ptr): else: data = mem_access.r16(data_ptr) data_ptr += 2 - data = chr(data) + try: + data = chr(data) + except ValueError: + data = 0x20 elif t == "%": data = ord("%") e.data = data diff --git a/amitools/vamos/mem/alloc.py b/amitools/vamos/mem/alloc.py index ce95b25d..3af4dbbc 100644 --- a/amitools/vamos/mem/alloc.py +++ b/amitools/vamos/mem/alloc.py @@ -92,6 +92,28 @@ def get_free_bytes(self): def is_all_free(self): return self.size == self.free_bytes + def _find_abs_chunk(self, address, size): + """ scan chunks, see which one we can split + return: index of chunk in free list or -1 if none found + bytes left in chunk + """ + chunk = self.free_first + while chunk != None: + # size matches, now check start address + delta_address = address - chunk.addr + if delta_address >= 0 and chunk.size - delta_address >= size: + # fits, but we can't return this chunk as 1) it doesn't start at the very address + # and 2) it may end way after the required end memory. So we need to split this + # chunk in 3 + + chunk_before = MemoryChunk(chunk.addr,address-chunk.addr) + self._replace_chunk(chunk,chunk_before) + chunk_after = MemoryChunk(address+size,chunk.size-size-delta_address) + self._insert_chunk(chunk_after) + return (chunk, 0) + chunk = chunk.next + # nothing found? + return (None, -1) + def _find_best_chunk(self, size): """find best chunk that could take the given alloc return: index of chunk in free list or -1 if none found + bytes left in chunk @@ -182,6 +204,39 @@ def _stat_info(self): num_allocs, ) + def alloc_abs(self, addr, size, except_on_fail=True): + """allocate absolute memory and return addr or 0 if no more memory""" + # align size to 4 bytes + size = (size + 3) & ~3 + # align address to 4 bytes, rounded down, that's what we will return + addr &= ~3 + chunk, left = self._find_abs_chunk(addr,size) + # out of memory? + if chunk == None: + if except_on_fail: + self.dump_orphans() + log_mem_alloc.error("[alloc: NO MEMORY for %06x bytes at %08x]" % (size,addr)) + raise VamosInternalError("[alloc: NO MEMORY for %06x bytes at %08x]" % (size,addr)) + return 0 + + # add to valid allocs map + self.addrs[addr] = size + self.free_bytes -= size + # erase memory + self.mem.clear_block(addr, size, 0) + log_mem_alloc.info( + "[allocabs @%06x-%06x: %06x bytes] %s", + addr, + addr + size, + size, + self._stat_info(), + ) + if addr % 4: + raise VamosInternalError( + "Memory pool is invalid, return address not aligned by a long word" + ) + return addr + def alloc_mem(self, size, except_on_fail=True): """allocate memory and return addr or 0 if no more memory""" # align size to 4 bytes @@ -328,6 +383,21 @@ def alloc_memory(self, size, label=None, except_on_failure=True): self.mem_objs[addr] = mem return mem + # memory + def alloc_abs_memory(self, addr, size, label=None, except_on_failure=True): + addr = self.alloc_abs(addr, size, except_on_failure) + if addr == 0: + return None + if label and self.label_mgr: + label_obj = LabelRange(label, addr, size) + self.label_mgr.add_label(label_obj) + else: + label_obj = None + mem = Memory(addr, size, label_obj, self.mem) + log_mem_alloc.info("alloc abs memory: %s", mem) + self.mem_objs[addr] = mem + return mem + def free_memory(self, mem): log_mem_alloc.info("free memory: %s", mem) if mem.label != None: