004. Инициализация CPU

Создать базовое состояние CPU и вспомогательные функции выборки.

Урок 4 из 356 · tests/chapter_01_cpu/test_004_cpu_init.py

Файл для обновления

emulator/cpu/cpu.py

Расположение

class CPU

Ссылка

https://www.nesdev.org/wiki/CPU_registers

Почему этот шаг существует

Прежде чем CPU сможет выбирать или выполнять инструкции, ему нужны явные регистры и зависимость от шины. Выборка продвигает счётчик команд, поскольку байты инструкции считываются последовательно.

Полная эталонная реализация

from dataclasses import dataclass

from emulator.bus.cpu_bus import CpuBus


@dataclass
class CPU:
    bus: CpuBus
    a: int = 0
    x: int = 0
    y: int = 0
    pc: int = 0
    s: int = 0
    p: int = 0

    def fetch_byte(self) -> int:
        value = self.bus.read(self.pc)
        self.pc += 1
        return value

    def fetch_word(self) -> int:
        low = self.fetch_byte()
        high = self.fetch_byte()
        return low | (high << 8)

Важные инварианты

  • CPU сохраняет именно тот объект шины, что передал вызывающий код
  • fetch_byte продвигает PC на единицу
  • fetch_word сначала считывает младший байт и продвигает PC на два

Распространённое заблуждение

Хранение little-endian меняет порядок байтов в памяти, а не числовой результат. Байты $34, затем $12 дают целое число $1234.

Вне рамок

  • поведение вектора сброса
  • декодирование опкодов
  • точные аппаратные значения регистров при включении питания

Запустить этот урок

uv run pytest tests/chapter_01_cpu/test_004_cpu_init.py -v