Esempio n. 1
0
 def PPUADDR_INC(self, value=1):
     v = FlagByte(0x0)
     v[0:8] = self._PPUADDR[0]
     v[8:16] = self._PPUADDR[1]
     v.value += value
     self._PPUADDR[0] = v[0:8]
     self._PPUADDR[1] = v[8:16]
Esempio n. 2
0
 def set_overflow(self, data):
     data = FlagByte(data)
     overflow = data[6]
     self._registers.overflow = overflow
Esempio n. 3
0
 def set_negative(self, data):
     data = FlagByte(data)
     negative = data[7]
     self._registers.negative = negative
Esempio n. 4
0
    def habdle_ins(self, ins, address, data):
        if ins == 'JMP':
            self._registers.PC = address
        elif ins == 'BRK':
            self._running = False
            return
        elif ins == 'LDX':
            self._registers.X = data
            self.set_zero_negative(data)
        elif ins == 'STX':
            self.write_address(address, self._registers.X)
        elif ins == 'JSR':
            pc = self._registers.PC - 1
            self.push_stack(pc, hex_digit=True)
            self._registers.PC = address
        elif ins == 'SEC':
            self._registers.carry = 1
        elif ins == 'SEI':
            self._registers.interrupt_disable = 1
        elif ins == 'SED':
            self._registers.decimal = 1
        elif ins == 'BCS':
            if self._registers.carry == 1:
                self._registers.PC = address
        elif ins == 'CLC':
            self._registers.carry = 0
        elif ins == 'BCC':
            if self._registers.carry == 0:
                self._registers.PC = address
        elif ins == 'LDA':
            self._registers.A = data
            self.set_zero_negative(data)
        elif ins == 'BEQ':
            if self._registers.zero == 1:
                self._registers.PC = address
        elif ins == 'BNE':
            if self._registers.zero == 0:
                self._registers.PC = address
        elif ins == 'STA':
            self.write_address(address, self._registers.A)
        elif ins == 'STY':
            self.write_address(address, self._registers.Y)
        elif ins == 'BIT':
            zf = 0 if self._registers.A & data else 1
            self._registers.zero = zf
            self.set_negative(data)
            self.set_overflow(data)
        elif ins == 'BVS':
            if self._registers.overflow == 1:
                self._registers.PC = address
        elif ins == 'BVC':
            if self._registers.overflow == 0:
                self._registers.PC = address
        elif ins == 'BPL':
            if self._registers.negative == 0:
                self._registers.PC = address
        elif ins == 'RTS':
            pc = self.pop_stack(hex_digit=True)
            self._registers.PC = pc + 1
        elif ins == 'PHP':
            p = FlagByte(self._registers.P)
            p[4] = 1  # 当 P 被 指令 PHP BRK 压入栈时, 压入的 P 的第 4 位被设置成 1
            self.push_stack(p.value)
        elif ins == 'PLA':
            data_ = self.pop_stack()
            self.set_zero_negative(data_)
            self._registers.A = data_
        elif ins == 'PLP':
            data_ = FlagByte(self.pop_stack())
            # 用弹出的值的 第 0 1 2 3 6 7 位 来设置 P 的 第 0 1 2 3 6 7 位 的值
            pre_p = self._registers.P
            pre_p = FlagByte(pre_p)
            data_[4] = pre_p[4]
            data_[5] = pre_p[5]
            self._registers.P = data_.value
        elif ins == 'AND':
            a = self._registers.A
            a &= data
            self.set_zero_negative(a)
            self._registers.A = a
        elif ins == 'CMP':
            result = self._registers.A - data
            self.set_zero_negative(result)
            self.set_negative(result)
            self.set_carry(result >= 0)
        elif ins == 'CLD':
            self._registers.decimal = 0
        elif ins == 'PHA':
            self.push_stack(self._registers.A)
        elif ins == 'ORA':
            self._registers.A |= data
            self.set_zero_negative(self._registers.A)
        elif ins == 'CLV':
            self._registers.overflow = 0
        elif ins == 'EOR':
            self._registers.A ^= data
            self.set_zero_negative(self._registers.A)
        elif ins == 'ADC':
            a = self._registers.A
            result = self._registers.A + data + self._registers.carry
            self.set_carry(result >> 8)
            low, high = self.split_number(result)
            self._registers.A = low
            self.set_overflow_by_expression(not ((a ^ data) & 0x80)
                                            and ((a ^ low) & 0x80))
            self.set_zero_negative(low)
        elif ins == 'LDY':
            self._registers.Y = data
            self.set_zero_negative(data)
        elif ins == 'CPY':
            res = self._registers.Y - data
            self.set_carry(self._registers.Y >= data)
            self.set_zero_negative(res)
        elif ins == 'CPX':
            res = self._registers.X - data
            self.set_carry(self._registers.X >= data)
            self.set_zero_negative(res)
        elif ins == 'SBC':
            res = self._registers.A - data - (0
                                              if self._registers.carry else 1)
            low, high = self.split_number(res)
            self.set_carry(not high)
            self.set_overflow_by_expression(((self._registers.A ^ data) & 0x80)
                                            & ((self._registers.A ^ high)
                                               & 0x80))
            self._registers.A = low
            self.set_zero_negative(low)
        elif ins == 'INY':
            res = self._registers.Y + 1
            res = self.eight_digit(res)
            self.set_zero_negative(res)
            self._registers.Y = res
        elif ins == 'INX':
            res = self._registers.X + 1
            res = self.eight_digit(res)
            self.set_zero_negative(res)
            self._registers.X = res
        elif ins == 'DEY':
            res = self._registers.Y - 1
            res = self.eight_digit(res)
            self.set_zero_negative(res)
            self._registers.Y = res
        elif ins == 'DEX':
            res = self._registers.X - 1
            res = self.eight_digit(res)
            self.set_zero_negative(res)
            self._registers.X = res
        elif ins == 'TAY':
            res = self._registers.A
            self.set_zero_negative(res)
            self._registers.Y = res
        elif ins == 'TAX':
            res = self._registers.A
            self.set_zero_negative(res)
            self._registers.X = res
        elif ins == 'TYA':
            res = self._registers.Y
            self.set_zero_negative(res)
            self._registers.A = res
        elif ins == 'TXA':
            res = self._registers.X
            self.set_zero_negative(res)
            self._registers.A = res
        elif ins == 'TSX':
            res = self._registers.S
            self.set_zero_negative(res)
            self._registers.X = res
        elif ins == 'TXS':
            res = self._registers.X
            self._registers.S = res
        elif ins == 'RTI':
            p = self.pop_stack()
            p = FlagByte(p)
            p[4] = self._registers.b_flag
            p[5] = 1
            self._registers.P = p.value
            self._registers.PC = self.pop_stack(hex_digit=True)
        elif ins == 'LSR':
            if address != -1:
                a = data
            else:
                a = self._registers.A
            self._registers.carry = a & 1
            a >>= 1
            a = self.eight_digit(a)
            self.set_zero_negative(a)
            if address != -1:
                self.write_address(address, a)
            else:
                self._registers.A = a
        elif ins == 'ASL':
            if address != -1:
                a = data
            else:
                a = self._registers.A
            self._registers.carry = a >> 7
            a <<= 1
            a = self.eight_digit(a)
            self.set_zero_negative(a)
            if address != -1:
                self.write_address(address, a)
            else:
                self._registers.A = a
        elif ins == 'ROR':
            if address != -1:
                a = data
            else:
                a = self._registers.A
            zero = a & 1
            a >>= 1
            a ^= self._registers.carry << 7
            self._registers.carry = zero
            a = self.eight_digit(a)
            self.set_zero_negative(a)
            if address != -1:
                self.write_address(address, a)
            else:
                self._registers.A = a
        elif ins == 'ROL':
            if address != -1:
                a = data
            else:
                a = self._registers.A
            seven = (a & 1 << 7) >> 7
            a <<= 1
            a ^= self._registers.carry
            self._registers.carry = seven
            a = self.eight_digit(a)
            self.set_zero_negative(a)
            if address != -1:
                self.write_address(address, a)
            else:
                self._registers.A = a
        elif ins == 'NOP':
            pass
        elif ins == 'BMI':
            if self._registers.negative == 1:
                self._registers.PC = address
        elif ins == "INC":
            d = self.eight_digit(data + 1)
            self.set_zero_negative(d)
            self.write_address(address, d)
        elif ins == "DEC":
            d = self.eight_digit(data - 1)
            self.set_zero_negative(d)
            self.write_address(address, d)
        elif ins == 'LAX':
            self._registers.X = self._registers.A = data
            self.set_zero_negative(data)
        elif ins == 'SAX':
            self.write_address(address, self._registers.A & self._registers.X)
        elif ins == 'DCP':
            data -= 1
            data = self.eight_digit(data)
            self.write_address(address, data)
            result = self.hex_digit(self._registers.A - data)
            self.set_carry(result < 0x100)
            self.set_zero_negative(self.eight_digit(result))
        elif ins == 'ISB':
            data += 1
            data = self.eight_digit(data)
            self.write_address(address, data)

            resul16 = self.hex_digit(self._registers.A - data -
                                     (0 if self._registers.carry else 1))
            self.set_carry(not resul16 >> 8)
            result8 = self.eight_digit(resul16)
            A = self._registers.A
            self.set_overflow_by_expression(((A ^ result8) & 0x80)
                                            and ((A ^ data) & 0x80))
            self._registers.A = result8
            self.set_zero_negative(result8)
        elif ins == 'SLO':
            self.set_carry(data >> 7)
            data <<= 1
            data = self.eight_digit(data)
            self.write_address(address, data)
            self._registers.A |= data
            self.set_zero_negative(self._registers.A)
        elif ins == 'RLA':
            data <<= 1
            data = self.hex_digit(data)
            if self._registers.carry:
                data |= 0x1
            self.set_carry(data > 0xff)
            result8 = self.eight_digit(data)
            self.write_address(address, result8)
            a = self._registers.A & result8
            self.set_zero_negative(a)
            self._registers.A = a
        elif ins == 'SRE':
            self.set_carry(data & 1)
            data >>= 1
            data = self.eight_digit(data)
            self.write_address(address, data)
            a = self._registers.A
            a ^= data
            self.set_zero_negative(a)
            self._registers.A = a
        elif ins == 'RRA':
            if self._registers.carry:
                data |= 0x100
            self._registers.carry = data & 1
            data >>= 1
            self.write_address(address, self.eight_digit(data))

            a = self._registers.A
            resul16 = a + data + (1 if self._registers.carry else 0)
            self.set_carry(resul16 >> 8)
            result8 = self.eight_digit(resul16)
            self.set_overflow_by_expression(not ((a ^ data) & 0x80)
                                            and ((a ^ result8) & 0x80))
            self._registers.A = result8
            self.set_zero_negative(result8)
        else:
            raise NotImplementedError("稍等一下, {} 指令还没实现".format(ins))
Esempio n. 5
0
class Registers:
    PC = 0  # Program Counter

    # A = 0  # Accumulator
    # X = 0  # Indexes
    # Y = 0  # Indexes
    # S = 0xFD  # Stack Pointer
    _INNER = bytearray([0, 0, 0, 0xFD])
    _P = FlagByte(0x24)  # Status Register
    r'''
    7  bit  0
    ---- ----
    NVss DIZC
    |||| ||||
    |||| |||+- Carry
    |||| ||+-- Zero
    |||| |+--- Interrupt Disable
    |||| +---- Decimal
    ||++------ No CPU effect, see: the B flag
    |+-------- Overflow
    +--------- Negative
    
    关于 B flag
    注意:第几位 是从 第 0 位 开始数的
    
    第 5 位永远为 1
    当 P 被 指令 PHP BRK 压入栈时, 压入的 P 的第 4 位被设置成 1
    当 P 由于 中断 \IRQ \NMI 被压入栈时, 压入的 P 的第 4 位被设置成 0
    当 P 被指令 PLP RTI 设置为栈中弹出的值时,不影响 第 4 5 位
    '''
    @property
    def A(self):
        return self._INNER[0]

    @A.setter
    def A(self, value):
        self._INNER[0] = value

    @property
    def X(self):
        return self._INNER[1]

    @X.setter
    def X(self, value):
        self._INNER[1] = value

    @property
    def Y(self):
        return self._INNER[2]

    @Y.setter
    def Y(self, value):
        self._INNER[2] = value

    @property
    def S(self):
        return self._INNER[3]

    @S.setter
    def S(self, value):
        self._INNER[3] = value

    @property
    def carry(self):
        return self._P[0]

    @carry.setter
    def carry(self, value):
        self._P[0] = value

    @property
    def zero(self):
        return self._P[1]

    @zero.setter
    def zero(self, value):
        self._P[1] = value

    @property
    def interrupt_disable(self):
        return self._P[2]

    @interrupt_disable.setter
    def interrupt_disable(self, value):
        self._P[2] = value

    @property
    def decimal(self):
        return self._P[3]

    @decimal.setter
    def decimal(self, value):
        self._P[3] = value

    @property
    def b_flag(self):
        return self._P[4]

    @b_flag.setter
    def b_flag(self, value):
        self._P[4] = value

    @property
    def overflow(self):
        return self._P[6]

    @overflow.setter
    def overflow(self, value):
        self._P[6] = value

    @property
    def negative(self):
        return self._P[7]

    @negative.setter
    def negative(self, value):
        self._P[7] = value

    @property
    def P(self):
        return self._P.value

    @P.setter
    def P(self, value):
        self._P = FlagByte(value)

    @classmethod
    def to_real_address(cls, sp):
        return sp | (0x01 << 8)
Esempio n. 6
0
 def P(self, value):
     self._P = FlagByte(value)
Esempio n. 7
0
 def PPUADDR(self):
     v = FlagByte(0x0)
     v[0:8] = self._PPUADDR[0]
     v[8:16] = self._PPUADDR[1]
     return v.value
Esempio n. 8
0
 def split_number(cls, num: int):
     n = FlagByte(num)
     low, high = n[0:8], n[8:16]
     return low, high
Esempio n. 9
0
 def from_low_high_to_int(cls, low: int or bytes, high: int or bytes):
     v = FlagByte(0x0)
     v[0:8] = low
     v[8:16] = high
     return v.value
Esempio n. 10
0
 def low_high(cls, val):
     pc = FlagByte(val)
     return pc[0:8], pc[8:16]