def printstate(self): # Display registers self.writedebug(str(self.step_cnt) + '\n') self.writedebug( "R0 " + ostr(self.R[0]) + " " + \ "R1 " + ostr(self.R[1]) + " " + \ "R2 " + ostr(self.R[2]) + " " + \ "R3 " + ostr(self.R[3]) + " " + \ "R4 " + ostr(self.R[4]) + " " + \ "R5 " + ostr(self.R[5]) + " " + \ "R6 " + ostr(self.R[6]) + " " + \ "R7 " + ostr(self.R[7]) + "\n" ) self.writedebug( "[" + \ ("u" if self.prevuser else "k") + \ ("U" if self.curuser else "K") + \ ("N" if (self.PS & PDP11.FLAGN) else " ") + \ ("Z" if (self.PS & PDP11.FLAGZ) else " ") + \ ("V" if (self.PS & PDP11.FLAGV) else " ") + \ ("C" if (self.PS & PDP11.FLAGC) else " ") + \ "] instr " + ostr(self.curPC) + ": " + ostr(self.instr) + " " ) try: decoded = self.decode(self.curPC, False, self.curuser) self.writedebug(self.disasm(decoded) + "\n") except Exception: pass
def decode(self, a, w, m): #var p, user, block, disp if not (self.SR0 & 1): if a >= 0o170000: a += 0o600000 return a user = 8 if m else 0 p = self.pages[(a >> 13) + user] if w and not p.write: self.SR0 = (1 << 13) | 1 self.SR0 |= (a >> 12) & ~1 if user: self.SR0 |= (1 << 5) | (1 << 6) self.SR2 = self.curPC raise (Trap(INT.FAULT, "write to read-only page " + ostr(a, 6))) if not p.read: self.SR0 = (1 << 15) | 1 self.SR0 |= (a >> 12) & ~1 if user: self.SR0 |= (1 << 5) | (1 << 6) self.SR2 = self.curPC raise (Trap(INT.FAULT, "read from no-access page " + ostr(a, 6))) block = (a >> 6) & 0o177 disp = a & 0o77 if (p.ed and (block < p.len)) or (not p.ed and (block > p.len)): self.SR0 = (1 << 14) | 1 self.SR0 |= (a >> 12) & ~1 if user: self.SR0 |= (1 << 5) | (1 << 6) self.SR2 = self.curPC raise(Trap(INT.FAULT, "page length exceeded, address " + ostr(a,6) + " (block " + \ ostr(block,3) + ") is beyond length " + ostr(p.len,3))) if w: p.pdr |= 1 << 6 return ((block + p.addr) << 6) + disp
def trapat(self, vec, msg): #var prev; if vec & 1: self.panic( "Thou darst calling trapat() with an odd vector number?") self.writedebug("trap " + ostr(vec) + " occurred: " + msg + "\n") self.printstate() try: prev = self.PS self.switchmode(False) self.push(prev) self.push(self.R[7]) except Exception as e: if 'num' in e.__dir__: self.writedebug("red stack trap!\n") self.memory[0] = self.R[7] self.memory[1] = prev vec = 4 else: raise (e) self.R[7] = self.memory[vec >> 1] self.PS = self.memory[(vec >> 1) + 1] if self.prevuser: self.PS |= (1 << 13) | (1 << 12) self.running.set()
def physwrite16(self, a, v): if a % 1: raise (Trap(INT.BUS, "write to odd address " + ostr(a, 6))) if a < 0o760000: try: self.memory[a >> 1] = v except OverflowError as e: # dirty fix of a problem if v < 0: #self.writedebug("warning: negative value @ physwrite16\n") # TODO: clean it up so that it doesn happen self.memory[a >> 1] = v & 0xFFFF elif v > 0xFFFF: #self.writedebug("warning: short overflow @ physwrite16\n") # TODO: clean it up so that it doesn happen self.memory[a >> 1] = v & 0xFFFF else: raise e elif a == 0o777776: bits = (v >> 14) & 3 if bits == 0: self.switchmode(False) elif bits == 3: self.switchmode(True) else: self.panic("invalid mode") bits = (v >> 12) & 3 if bits == 0: self.prevuser = False elif bits == 3: self.prevuser = True else: self.panic("invalid mode") self.PS = v elif a == 0o777546: self.LKS = v elif a == 0o777572: self.SR0 = v elif (a & 0o777770) == 0o777560: self.terminal.conswrite16(a, v) elif (a & 0o777700) == 0o777400: self.rk.write16(a, v) elif (a & 0o777600) == 0o772200 or (a & 0o777600) == 0o777600: self.mmuwrite16(a, v) else: raise (Trap(INT.BUS, "write to invalid address " + ostr(a, 6)))
def mmuread16(self, a): i = (a & 0o17) >> 1 if (a >= 0o772300) and (a < 0o772320): return self.pages[i].pdr if (a >= 0o772340) and (a < 0o772360): return self.pages[i].par if (a >= 0o777600) and (a < 0o777620): return self.pages[i + 8].pdr if (a >= 0o777640) and (a < 0o777660): return self.pages[i + 8].par raise (Trap(INT.BUS, "invalid read from " + ostr(a, 6)))
def mmuwrite16(self, a, v): i = (a & 0o17) >> 1 if (a >= 0o772300) and (a < 0o772320): self.pages[i] = Page(self.pages[i].par, v) elif (a >= 0o772340) and (a < 0o772360): self.pages[i] = Page(v, self.pages[i].pdr) elif (a >= 0o777600) and (a < 0o777620): self.pages[i + 8] = Page(self.pages[i + 8].par, v) elif (a >= 0o777640) and (a < 0o777660): self.pages[i + 8] = Page(v, self.pages[i + 8].pdr) else: raise (Trap(INT.BUS, "write to invalid address " + ostr(a, 6)))
def physread16(self, addr): if addr & 1: raise (Trap(INT.BUS, 'read from odd address ' + ostr(addr, 6))) if addr < 0o760000: return self.memory[addr >> 1] if addr == 0o777546: return self.LKS if addr == 0o777570: # what does this do? 0o173030 = 63000 return 0o173030 if addr == 0o777572: return self.SR0 if addr == 0o777576: return self.SR2 if addr == 0o777776: return self.PS if (addr & 0o777770) == 0o777560: return self.terminal.consread16(addr) if (addr & 0o777760) == 0o777400: return self.rk.read16(addr) if (addr & 0o777600) == 0o772200 or (addr & 0o777600) == 0o777600: return self.mmuread16(addr) if addr == 0o776000: self.panic('lolwut') raise (Trap(INT.BUS, 'read from invalid address ' + ostr(addr, 6)))