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