def effective_address(self, mode: str, length: int, *args): if mode in {"Rm" , "Rn" }: # the effective address is the register assert False, mode if mode in {"@Rm" , "@Rn" }: n_m, = args return self.reg[n_m] if mode in {"@Rm+", "@Rn+"}: n_m, = args value = self.reg[n_m] self.reg[n_m] += length return value if mode in {"@-Rm-", "@-Rn"}: n_m, = args self.reg[n_m] -= length return self.reg[n_m] if mode in {"@(disp,Rn)", "@(disp,Rm)"}: disp, n_m = args return self.reg[n_m] + (disp * length) if mode in {"@(R0,Rn)" , "@(R0,Rm)" }: n_m, = args return self.reg[n_m] + self.reg[0] if mode in {"@(disp,GBR)"}: disp, = args assert length in {1, 2, 4}, length return self.gbr + (disp * length) if mode in {"@(R0,GBR)"}: assert args == [], args return self.regs[0] + self.gbr if mode in {"@(disp,PC)"}: disp, = args assert length in {2, 4}, length mask = 0xffffffff & (~((2 ** length) - 1)) return (self.pc & mask) + (disp * length) if mode in {"label"}: disp, = args assert length == 2, length return self.pc + (disp * length) if mode in {"#imm"}: # immediate should be calculated in another function assert False, mode # otherwise, assert False assert False, mode