005. Интерфейс памяти

Ввести общий интерфейс устройства памяти.

Урок 5 из 356 · tests/chapter_01_cpu/test_005_memory_interface.py

Файл для создания

emulator/memory/memory_device.py

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

emulator/memory/ram.py

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

class MemoryDevice
class RAM(MemoryDevice)

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

Вскоре CpuBus будет направлять обращения к разным устройствам. Небольшой абстрактный интерфейс позволяет шине зависеть от поведения чтения/записи, а не от конкретного представления RAM.

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

# emulator/memory/memory_device.py
from abc import ABC, abstractmethod


class MemoryDevice(ABC):
    @abstractmethod
    def read(self, addr: int) -> int:
        ...

    @abstractmethod
    def write(self, addr: int, value: int) -> None:
        ...


# emulator/memory/ram.py
from dataclasses import dataclass, field

from emulator.memory.memory_device import MemoryDevice


@dataclass
class RAM(MemoryDevice):
    _data: bytearray = field(
        default_factory=lambda: bytearray(0x800),
        init=False,
    )

    def read(self, addr: int) -> int:
        return self._data[addr]

    def write(self, addr: int, value: int) -> None:
        self._data[addr] = value

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

MemoryDevice определяет операции, но не владеет хранилищем или отображением адресов.

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

Абстрактный базовый класс не делает содержимое RAM абстрактным. RAM по-прежнему владеет конкретным хранилищем байтов; общей является только вызываемая граница.

Вне рамок

  • FakeROM, вводимый в тесте 006
  • отображение программной ROM на шину
  • поведение картриджа только для чтения

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

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