def next(self):
        if not self._machine_code:
            raise StopIteration
        else:
            self._current_oprt = self._machine_code.next()
            if self._current_oprt in self.OPRT_R_R:
                regs = self._machine_code.next()

                return InstRR(self._current_oprt,
                              hn(regs), ln(regs))

            elif self._current_oprt in self.OPRT_R_IMM:
                reg = self._machine_code.next()
                imm = mkw(self._machine_code.next(),
                          self._machine_code.next())

                return InstRImm(self._current_oprt,
                                hn(reg), i_2c(imm))

            elif self._current_oprt in self.OPRT_R:
                reg = self._machine_code.next()

                return InstR(self._current_oprt,
                             hn(reg))

            elif self._current_oprt in self.OPRT_IMM_1_BYTE:
                imm = self._machine_code.next()

                return InstImm(self._current_oprt,
                               i_2c(imm, size=8))

            elif self._current_oprt in self.OPRT_IMM_2_BYTE:
                # operators with one 2-byte imm arg are always 2-byte long
                self._current_oprt = mkw(self._current_oprt,
                                         self._machine_code.next())
                imm = mkw(self._machine_code.next(),
                          self._machine_code.next())

                return InstImm(self._current_oprt,
                               i_2c(imm))

            elif self._current_oprt in self.OPRT_NO_ARG:
                return InstNoArg(self._current_oprt)
Example #2
0
    def _ins_decode(self):
        self._d_dr, self._d_sr = (self._reg_mux(self._ir[1] >> 4),
                                  self._reg_mux(self._ir[1] & 0x0f))
        # both of _d_xr are str

        op_code = self._ir[0] & 0x1f

        if self._ir[0] & 0xe0 == 0:
            # arithmetic instruction

            self.__f_single = False
            self.__f_modify = False
            self.__f_z = False
            self.__f_c = False

            if op_code in self._op_code_z_c_binary_table:
                self.__f_modify = True
                self.__f_z = True
                self.__f_c = True
            elif op_code in self._op_code_z_c_binary_n_table:
                self.__f_z = True
                self.__f_c = True
            elif op_code in self._op_code_z_binary_table:
                self.__f_modify = True
                self.__f_z = True
            elif op_code in self._op_code_z_binary_n_table:
                self.__f_z = True
            elif op_code in self._op_code_z_c_unary_table:
                self.__f_single = True
                self.__f_modify = True
                self.__f_z = True
                self.__f_c = True
            elif op_code in self._op_code_z_unary_table:
                self.__f_single = True
                self.__f_modify = True
                self.__f_z = True
            elif op_code in self._op_code_binary_table:
                self.__f_modify = True

            self._alu_func = self._op_codes[op_code]
            result, carry, zero = self._alu_proc()

            if self.__f_modify:
                self.__setattr__(self._d_dr, result)
            if self.__f_c:
                self._c_flag = carry
            if self.__f_z:
                self._z_flag = zero
        elif self._ir[0] & 0xe0 == 0x40:
            # jump instruction

            absolute, jump = False, False
            if op_code == 0:            # jr
                jump = True
            elif op_code == 0x04:       # jrc
                jump = self._c_flag
            elif op_code == 0x05:
                jump = not self._c_flag # jrnc
            elif op_code == 0x02:
                jump = self._z_flag     # jrz
            elif op_code == 0x03:
                jump = not self._z_flag # jrnz
            elif op_code == 0x0f:       # jmpa
                jump = True
                absolute = True

            if not absolute:
                if jump:
                    self._pc += i_2c(self._ir[1], size=8)
            if absolute:
                self._pc = i_2c(mkw(*self._next_word()))
        elif self._ir[0] & 0xe0 == 0x80:
            # memory instruction

            if op_code == 0x01:
                self.__setattr__(self._d_dr,
                                 i_2c(mkw(*self._next_word()),
                                      size=16))