diff --git a/emulator/firmware-decomp/emu_main.py b/emulator/firmware-decomp/emu_main.py index de0a025..adb8d8f 100644 --- a/emulator/firmware-decomp/emu_main.py +++ b/emulator/firmware-decomp/emu_main.py @@ -56,6 +56,7 @@ MAPS = { alloc=0xf042c628, v2p=0xf042c300, lockacq=0xf0423360, lockrel=0xf04233b8, chain=None, chain_tbl=None, chain_tail=None, + intdiv=0xf042ee00, # runtime int divide (r22 = r22/r23) seeds=[ (0x1000, 0), # _processorId ], @@ -101,6 +102,20 @@ class MainRunner: if m['sendprim']: self.hooks[m['sendprim']] = self.h_ret if m['putchar']: self.hooks[m['putchar']] = self.h_console if m['chain']: self.hooks[m['chain']] = self.h_chainfix + if m.get('intdiv'): self.hooks[m['intdiv']] = self.h_intdiv + + def h_intdiv(self, cpu): + # Runtime integer divide (r22 = r22/r23, result via ftrunc+fxfr): the + # compiled Newton-Raphson relies on exact dual-op pipeline timing our + # functional FP model doesn't reproduce yet -- compute exactly instead. + a = cpu.rd(22); b = cpu.rd(23) + if a & 0x80000000: a -= 1 << 32 + if b & 0x80000000: b -= 1 << 32 + q = abs(a) // abs(b) if b else 0 + if (a < 0) != (b < 0): q = -q + cpu.wr(22, q & 0xffffffff) + cpu.pc = cpu.rd(1) + return True self.heap = [0x08010000, 0x0c010000] # bump allocator over the DRAM banks # ---- hook helpers: emulate a called function returning ----