Example #1
0
 def RTS(self, address: int, mode: str):
     cpu = self.cpu
     vl = cpu.pop()
     vh = cpu.pop()
     v = utils.number_from_bytes([vl, vh])
     pc = v + 1
     cpu.pc = pc
Example #2
0
 def SBC(self, address: int, mode: str):
     cpu = self.cpu
     mvalue = self.value_from_address(address, mode)
     v = mvalue
     r = cpu.a
     c = cpu.status.carry
     v = r - v - (1 - c)
     # C flag: clear if overflow
     if v < 0:
         v += 256
         cpu.status.carry = 0
     else:
         cpu.status.carry = 1
     cpu.a = v
     cpu.status.set_negative(v)
     cpu.status.set_zero(v)
     # 处理 v flag
     v = utils.number_from_bytes([mvalue], signed=True)
     r = utils.number_from_bytes([r], signed=True)
     v = r - v - (1 - c)
     cpu.status.overflow = int(v > 128 or v < -127)
Example #3
0
 def ADC(self, address: int, mode: str):
     cpu = self.cpu
     mvalue = self.value_from_address(address, mode)
     v = mvalue
     r = cpu.a
     c = cpu.status.carry
     v = r + v + c
     # C flag: set if overflow
     if v > 255:
         v -= 256
         cpu.status.carry = 1
     else:
         cpu.status.carry = 0
     cpu.a = v
     cpu.status.set_negative(v)
     cpu.status.set_zero(v)
     # 处理 v flag
     v = utils.number_from_bytes([mvalue], signed=True)
     r = utils.number_from_bytes([r], signed=True)
     v = r + v + c
     cpu.status.overflow = int(v > 128 or v < -127)
Example #4
0
    def RTI(self, address: int, mode: str):
        cpu = self.cpu
        v = cpu.pop()
        s = _Status(v)
        # 从栈里弹出的值,外面不会作用到 P 的 B flag 上
        s.break_command = cpu.status.break_command
        cpu.status = s

        vl = cpu.pop()
        vh = cpu.pop()
        v = utils.number_from_bytes([vl, vh])
        # 这里不需要像 RTS 一样 +1
        pc = v
        cpu.pc = pc
Example #5
0
def test_number_from_bytes():
    test_cases = [
        (dict(byte_list=[1]), 1),
        (dict(byte_list=[1, 0]), 1),
        (dict(byte_list=[0, 1]), 256),
        (dict(byte_list=[255]), 255),
        (dict(byte_list=[255], signed=True), -1),
        (dict(byte_list=[255, 255], signed=True), -1),
        (dict(byte_list=[0, 255], signed=True), -256),
    ]
    for case in test_cases:
        input = case[0]
        expected = case[1]
        result = utils.number_from_bytes(**input)
        assert expected == result, (case, result)
Example #6
0
    def interrupt(self, name: str):
        if name == 'NMI':
            # 将 pc 和 p 压栈
            pc = self.pc
            v = pc
            self.push((v & 0xff00) >> 8)
            self.push(v & 0x00ff)
            # 只有「被压入栈」的 status 的 B flag 被置为 1
            s = copy.copy(self.status)
            s.break_command = 1
            self.push(s.value)
            al_pos = 0xfffa
        elif name == 'RESET':
            al_pos = 0xfffc
        else:
            raise ValueError('错误的 interrupt: <{}>'.format(name))

        al = self.memory[al_pos]
        ah = self.memory[al_pos + 1]
        addr = utils.number_from_bytes([al, ah])
        self.pc = addr
Example #7
0
    def _execute(self, op: str, addr: Optional[int], mode: str):
        if op == 'JMP':
            self.set_reg_value('pc', addr)
        elif op == 'LDX':
            v = self._value_from_address(addr, mode)
            self.set_reg_value('x', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'STX':
            v = self.reg_value('x')
            self.set_mem_value(addr, v)
        elif op == 'JSR':
            pc = self.reg_value('pc')
            v = pc - 1
            self.push((v & 0xff00) >> 8)
            self.push(v & 0x00ff)
            self.set_reg_value('pc', addr)
        elif op == 'NOP':
            # do nothing
            pass
        elif op == 'SEC':
            self.set_flag('c', True)
        elif op == 'BCS':
            f = self.flag('c')
            if f:
                self.set_reg_value('pc', addr)
        elif op == 'CLC':
            self.set_flag('c', False)
        elif op == 'BCC':
            f = self.flag('c')
            if not f:
                self.set_reg_value('pc', addr)
        elif op == 'LDA':
            v = self._value_from_address(addr, mode)
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'BEQ':
            f = self.flag('z')
            if f:
                self.set_reg_value('pc', addr)
        elif op == 'BNE':
            f = self.flag('z')
            if not f:
                self.set_reg_value('pc', addr)
        elif op == 'STA':
            v = self.reg_value('a')
            self.set_mem_value(addr, v)
        elif op == 'BIT':
            v = self._value_from_address(addr, mode)
            a = self.reg_value('a')
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('v', v & 0b01000000 != 0)
            self.set_flag('z', v & a == 0)
        elif op == 'BVS':
            f = self.flag('v')
            if f:
                self.set_reg_value('pc', addr)
        elif op == 'BVC':
            f = self.flag('v')
            if not f:
                self.set_reg_value('pc', addr)
        elif op == 'BPL':
            f = self.flag('n')
            if not f:
                self.set_reg_value('pc', addr)
        elif op == 'RTS':
            vl = self.pop()
            vh = self.pop()
            v = number_from_bytes([vl, vh])
            pc = v + 1
            self.set_reg_value('pc', pc)
        elif op == 'SEI':
            self.set_flag('i', True)
        elif op == 'SED':
            self.set_flag('d', True)
        elif op == 'PHP':
            # 在这条指令中,只有「被压入栈」的 P 的 B flag 被置为 True
            bv = self.reg_value('p')

            self.set_flag('b', True)
            v = self.reg_value('p')
            self.push(v)

            self.set_reg_value('p', bv)
        elif op == 'PLA':
            v = self.pop()
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'AND':
            v = self._value_from_address(addr, mode)
            r = self.reg_value('a')
            v = r & v
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'CMP':
            v = self._value_from_address(addr, mode)
            r = self.reg_value('a')
            v = r - v
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            self.set_flag('c', v >= 0)
        elif op == 'CLD':
            self.set_flag('d', False)
        elif op == 'PHA':
            v = self.reg_value('a')
            self.push(v)
        elif op == 'PLP':
            v = self.pop()
            # 从栈里弹出的值,外面不会作用到 P 的 B flag 上
            for b in 'NVDIZC':
                m = self.p_masks[b]
                f = v & m != 0
                self.set_flag(b, f)
        elif op == 'BMI':
            f = self.flag('n')
            if f:
                self.set_reg_value('pc', addr)
        elif op == 'ORA':
            v = self._value_from_address(addr, mode)
            r = self.reg_value('a')
            v = r | v
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'CLV':
            self.set_flag('v', False)
        elif op == 'EOR':
            v = self._value_from_address(addr, mode)
            r = self.reg_value('a')
            v = r ^ v
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'ADC':
            mvalue = self._value_from_address(addr, mode)
            v = mvalue
            r = self.reg_value('a')
            c = int(self.flag('c'))
            v = r + v + c
            # C flag: set if overflow
            if v > 255:
                v -= 256
                self.set_flag('c', True)
            else:
                self.set_flag('c', False)
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            # 处理 v flag
            v = number_from_bytes([mvalue], signed=True)
            r = number_from_bytes([r], signed=True)
            v = r + v + c
            self.set_flag('v', v > 128 or v < -127)
        elif op == 'LDY':
            v = self._value_from_address(addr, mode)
            self.set_reg_value('y', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'CPY':
            v = self._value_from_address(addr, mode)
            r = self.reg_value('y')
            v = r - v
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            self.set_flag('c', v >= 0)
        elif op == 'CPX':
            v = self._value_from_address(addr, mode)
            r = self.reg_value('x')
            v = r - v
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            self.set_flag('c', v >= 0)
        elif op == 'SBC':
            mvalue = self._value_from_address(addr, mode)
            v = mvalue
            r = self.reg_value('a')
            c = int(self.flag('c'))
            v = r - v - (1 - c)
            # C flag: clear if overflow
            if v < 0:
                v += 256
                self.set_flag('c', False)
            else:
                self.set_flag('c', True)
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            # 处理 v flag
            v = number_from_bytes([mvalue], signed=True)
            r = number_from_bytes([r], signed=True)
            v = r - v - (1 - c)
            self.set_flag('v', v > 128 or v < -127)
        elif op == 'INY':
            v = self.reg_value('y')
            v += 1
            v %= 256
            self.set_reg_value('y', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'INX':
            v = self.reg_value('x')
            v += 1
            v %= 256
            self.set_reg_value('x', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'DEY':
            v = self.reg_value('y')
            v -= 1
            v %= 256
            self.set_reg_value('y', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'DEX':
            v = self.reg_value('x')
            v -= 1
            v %= 256
            self.set_reg_value('x', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'TAY':
            v = self.reg_value('a')
            self.set_reg_value('y', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'TAX':
            v = self.reg_value('a')
            self.set_reg_value('x', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'TYA':
            v = self.reg_value('y')
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'TXA':
            v = self.reg_value('x')
            self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'TSX':
            v = self.reg_value('s')
            self.set_reg_value('x', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'TXS':
            v = self.reg_value('x')
            self.set_reg_value('s', v)
        elif op == 'RTI':
            v = self.pop()
            # 从栈里弹出的值,外面不会作用到 P 的 B flag 上
            for b in 'NVDIZC':
                m = self.p_masks[b]
                f = v & m != 0
                self.set_flag(b, f)
            vl = self.pop()
            vh = self.pop()
            v = number_from_bytes([vl, vh])
            # 这里不需要像 RTS 一样 +1
            pc = v
            self.set_reg_value('pc', pc)
        elif op == 'LSR':
            if addr is not None:
                old_v = self._value_from_address(addr, mode)
                v = old_v >> 1
                self.set_mem_value(addr, v)
            else:
                old_v = self.reg_value('a')
                v = old_v >> 1
                self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            self.set_flag('c', old_v & 0b00000001 != 0)
        elif op == 'ASL':
            if addr is not None:
                old_v = self._value_from_address(addr, mode)
                v = old_v << 1
                v %= 256
                self.set_mem_value(addr, v)
            else:
                old_v = self.reg_value('a')
                v = old_v << 1
                v %= 256
                self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            self.set_flag('c', old_v & 0b10000000 != 0)
        elif op == 'ROR':
            c = int(self.flag('c'))
            if addr is not None:
                old_v = self._value_from_address(addr, mode)
                v = (old_v >> 1) + (c * 128)
                self.set_mem_value(addr, v)
            else:
                old_v = self.reg_value('a')
                v = (old_v >> 1) + (c * 128)
                self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            self.set_flag('c', old_v & 0b00000001 != 0)
        elif op == 'ROL':
            c = int(self.flag('c'))
            if addr is not None:
                old_v = self._value_from_address(addr, mode)
                v = (old_v << 1) + c
                v %= 256
                self.set_mem_value(addr, v)
            else:
                old_v = self.reg_value('a')
                v = (old_v << 1) + c
                v %= 256
                self.set_reg_value('a', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
            self.set_flag('c', old_v & 0b10000000 != 0)
        elif op == 'STY':
            v = self.reg_value('y')
            self.set_mem_value(addr, v)
        elif op == 'INC':
            v = self._value_from_address(addr, mode)
            v += 1
            v %= 256
            self.set_mem_value(addr, v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'DEC':
            v = self._value_from_address(addr, mode)
            v -= 1
            v %= 256
            self.set_mem_value(addr, v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'LAX':
            v = self._value_from_address(addr, mode)
            self.set_reg_value('a', v)
            self.set_reg_value('x', v)
            self.set_flag('n', v & 0b10000000 != 0)
            self.set_flag('z', v == 0)
        elif op == 'SAX':
            v1 = self.reg_value('a')
            v2 = self.reg_value('x')
            v = v1 & v2
            self.set_mem_value(addr, v)
        elif op == 'DCP':
            self._execute('DEC', addr, mode)
            self._execute('CMP', addr, mode)
        elif op == 'ISB':
            self._execute('ISC', addr, mode)
        elif op == 'ISC':
            self._execute('INC', addr, mode)
            self._execute('SBC', addr, mode)
        elif op == 'SLO':
            self._execute('ASL', addr, mode)
            self._execute('ORA', addr, mode)
        elif op == 'RLA':
            self._execute('ROL', addr, mode)
            self._execute('AND', addr, mode)
        elif op == 'SRE':
            self._execute('LSR', addr, mode)
            self._execute('EOR', addr, mode)
        elif op == 'RRA':
            self._execute('ROR', addr, mode)
            self._execute('ADC', addr, mode)
        elif op == 'BRK':
            # pc 压栈
            # 这里不需要 pc - 1
            pc = self.reg_value('pc')
            v = pc
            self.push((v & 0xff00) >> 8)
            self.push(v & 0x00ff)

            # p 压栈
            # 在这条指令中,只有「被压入栈」的 P 的 B flag 被置为 True
            bv = self.reg_value('p')
            self.set_flag('b', True)
            v = self.reg_value('p')
            self.push(v)
            self.set_reg_value('p', bv)

            # 设置中断跳转
            vl = self.mem_value(0xfffe)
            vh = self.mem_value(0xffff)
            v = number_from_bytes([vl, vh])
            self.set_reg_value('pc', v)

            self.set_flag('i', True)
            self.set_flag('b', True)
        else:
            raise ValueError('错误的 op: <{}>'.format(op))
Example #8
0
    def address(self, mode: str):
        if mode == 'IMP':
            return None
        elif mode == 'IMM':
            a = self.next_mem_value()
            return a
        elif mode == 'ABS':
            al = self.next_mem_value()
            ah = self.next_mem_value()
            a = number_from_bytes([al, ah])
            return a
        elif mode == 'ZPG':
            a = self.next_mem_value()
            return a
        elif mode == 'ABX':
            al = self.next_mem_value()
            ah = self.next_mem_value()
            a = number_from_bytes([al, ah])
            i = self.reg_value('x')
            return (a + i) % 0x10000
        elif mode == 'ABY':
            al = self.next_mem_value()
            ah = self.next_mem_value()
            a = number_from_bytes([al, ah])
            i = self.reg_value('y')
            return (a + i) % 0x10000
        elif mode == 'ZPX':
            a = self.next_mem_value()
            i = self.reg_value('x')
            return (a + i) % 0x100
        elif mode == 'ZPY':
            a = self.next_mem_value()
            i = self.reg_value('y')
            return (a + i) % 0x100
        elif mode == 'IND':
            tal = self.next_mem_value()
            tah = self.next_mem_value()
            ta = number_from_bytes([tal, tah])
            # 模拟 6502 的 BUG
            ta2 = (ta & 0xFF00) | ((ta + 1) & 0x00FF)

            al = self.mem_value(ta)
            ah = self.mem_value(ta2)
            a = number_from_bytes([al, ah])

            return a
        elif mode == 'INX':
            t = self.next_mem_value()
            i = self.reg_value('x')
            ta = (t + i) % 0x100
            ta2 = (ta + 1) % 0x100

            al = self.mem_value(ta)
            ah = self.mem_value(ta2)
            a = number_from_bytes([al, ah])

            return a
        elif mode == 'INY':
            ta = self.next_mem_value()
            ta2 = (ta + 1) % 0x100

            al = self.mem_value(ta)
            ah = self.mem_value(ta2)
            a = number_from_bytes([al, ah])

            i = self.reg_value('y')
            return (a + i) % 0x10000
        elif mode == 'REL':
            diff = self.next_mem_value()
            diff = number_from_bytes([diff], signed=True)
            pc = self.reg_value('pc')
            return (pc + diff) % 0x10000
        else:
            raise ValueError('错误的寻址模式:<{}>'.format(mode))
Example #9
0
def test_ppu():
    nes = nft.prepared_nes()
    cpu = nc.NesCPU()
    cpu.load_nes(nes)

    rl = cpu.mem_value(0xfffc)
    rh = cpu.mem_value(0xfffd)
    reset = number_from_bytes([rl, rh])
    cpu.set_reg_value('pc', reset)

    for _ in range(20000):
        cpu.execute()

    expected = [
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        82,
        117,
        110,
        32,
        97,
        108,
        108,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        66,
        114,
        97,
        110,
        99,
        104,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        70,
        108,
        97,
        103,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        73,
        109,
        109,
        101,
        100,
        105,
        97,
        116,
        101,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        73,
        109,
        112,
        108,
        105,
        101,
        100,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        83,
        116,
        97,
        99,
        107,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        65,
        99,
        99,
        117,
        109,
        117,
        108,
        97,
        116,
        111,
        114,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        40,
        73,
        110,
        100,
        105,
        114,
        101,
        99,
        116,
        44,
        88,
        41,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        90,
        101,
        114,
        111,
        112,
        97,
        103,
        101,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        65,
        98,
        115,
        111,
        108,
        117,
        116,
        101,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        40,
        73,
        110,
        100,
        105,
        114,
        101,
        99,
        116,
        41,
        44,
        89,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        65,
        98,
        115,
        111,
        108,
        117,
        116,
        101,
        44,
        89,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        90,
        101,
        114,
        111,
        112,
        97,
        103,
        101,
        44,
        88,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        45,
        45,
        32,
        65,
        98,
        115,
        111,
        108,
        117,
        116,
        101,
        44,
        88,
        32,
        116,
        101,
        115,
        116,
        115,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        85,
        112,
        47,
        68,
        111,
        119,
        110,
        58,
        32,
        115,
        101,
        108,
        101,
        99,
        116,
        32,
        116,
        101,
        115,
        116,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        83,
        116,
        97,
        114,
        116,
        58,
        32,
        114,
        117,
        110,
        32,
        116,
        101,
        115,
        116,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        83,
        101,
        108,
        101,
        99,
        116,
        58,
        32,
        73,
        110,
        118,
        97,
        108,
        105,
        100,
        32,
        111,
        112,
        115,
        33,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        32,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
    ]
    result = cpu.ppu.memory[0x2000:0x2400]
    assert expected == result, result