< Z-FRAME SEG 0003 · 27.08.2026
; ──────────────────────────────────────────── ; Z-FRAME · DEVLOG ENTRY 0003 ; ──────────────────────────────────────────── 0000 31 FF 7F LD SP, 7FFFh ; init 0003 21 03 00 LD HL, ENTRY ; this post 0006 CD 20 00 CALL RENDER

Z-Frame: Старт/инициализация процессора

Почему процессору нужен загрузчик

PC 27.08.2026
BC $1C6D
HL Z-Frame · architecture · Z80 · FPGA · SRAM · STM32

Старт/инициализация процессора

Процессоры разных семейств и/или архитектуры (Z80, MOS 6502, Motorola 68000, x86) инициализацию организовывали по-разному. Это поведение уже "зашито" в сам процессор.

Важно: кроме упоминаемых регистров часто при сбросе обнуляются или выставляются с особыми значениями дополнительные регистры (например, указатель стека - Stack Pointer), которые я не упоминаю для простоты. При проектировании систем, конечно, это учитывается тоже.

По поведению на старте процессоры можно разделить на два типа.

Первый тип. Исполняем с этого места

По стартовому адресу лежит первая инструкция, и процессор просто начинает её выполнять.

Z80 - самый простой. После сброса счётчик команд PC (Program Counter) выставляется на адрес 0x0000, и процессор исполняет то, что лежит с нулевого адреса.

8086 - та же идея, только стартовый адрес находится почти в самом конце адресного пространства. У первых 8086 это 0xFFFF0 (16 байт до конца мегабайта), у современных x86 (начиная с 386) - 0xFFFFFFF0 (16 байт до конца уже 4-гигабайтного пространства). Но принцип тот же: по этому адресу лежит инструкция (как правило - сразу переход куда надо), и процессор её исполняет.

Классический ARM (ARM7/ARM9) - по адресу 0x00000000 лежит таблица векторов, и первая её ячейка (вектор сброса) - это тоже инструкция, обычно переход на настоящий стартовый код (он же - reset_handler). При этом, расположение таблицы можно переключить на high vectors по адресу 0xFFFF0000 - но это опция конфигурации.

Второй тип. Читаем, с какого места исполнять

По стартовому адресу лежит не инструкция, а указатель - адрес, по которому уже находится настоящий код. Процессор сначала читает этот указатель, а потом переходит (или, как говорят, "прыгает") по нему. Дополнительный шаг, который даёт возможность менять точку входа.

MOS 6502 (в Famicom/NES/"Денди", кстати, стояла его версия - Ricoh 2A03, тот же 6502, но с отключённым десятичным режимом (не работает коррекция BCD) и со встроенным звуком) - при сбросе читает 16-битный указатель (он же - вектор сброса), из адресов 0xFFFC–0xFFFD, и переходит по нему - то есть по вектору лежит адрес, ведущий к коду. То есть в конце памяти лежит не код, а "адрес, где лежит код".

Motorola 68000 (центральный процессор Sega Mega Drive/Genesis) - читает при сбросе два 32-битных значения: из 0x000000 - начальное значение указателя стека, из 0x000004 - стартовый адрес программы. Вычитав оба, процессор начинает работу.

ARM Cortex-M - устроен "идейно" так же, как 68000: из 0x00000000 читает начальный SP (он же - указатель стека, Stack Pointer), из 0x00000004 - начальный PC. Это отличие от классического ARM (ARM7/ARM9): там по вектору лежала инструкция, а у Cortex-M - адрес.

То есть, разница сводится к одному вопросу: что находится по стартовому адресу - код, который сразу исполняют, или адрес, по которому этот код искать.

Первая программа

В обоих случаях возникает одна и та же проблема-рекурсия: при старте процессор так или иначе узнает, как и откуда ему выполнять программу, но самой программы ещё нет. И загрузить её может только какая-то другая программа, которая сама должна быть тоже уже загружена. То есть, как-то нужно сделать так, чтобы минимальная программа в памяти была уже при включении - в самом начале, которая будет работать автономно "сама по себе" и (или) позволит загрузиться, например, с дискеты, жёсткого (или твёрдотельного) диска и так далее.

В основе своей эта идея существует и применяется и сейчас, например, во всех современных x86-совместимых компьютерах.

Времена ZX Spectrum, C64 и других подобных домашних компьютеров

В основе использовалась память из комбинации двух типов (и, соответственно, микросхем): ROM (ПЗУ) + RAM ( ОЗУ).

Процессор и память (ROM + RAM)
Процессор и память (ROM + RAM)

Идея: ROM (ПЗУ, постоянное запоминающее устройство, read-only memory) записывается ещё при изготовлении на заводе (масочное ПЗУ - то есть, на этапе изготовления кремния) или отдельным программатором один раз после изготовления - на другом компьютере. В самом ZX Spectrum ROM-микросхема была как раз масочная.

Чтобы не углубляться в схемотехнические детали, управляющие линии на рисунке остались без изменений (хотя в реальном ZX Spectrum, конечно, теперь появляется зависимость от того, какой адрес выставлен на шине адреса). Также от ROM -микросхемы шина данных - однонаправленная, то есть, только чтение из памяти (что логично, ведь она уже записана и данные стереть нельзя) и сама микросхема не имеет управляющего вывода для записи данных.

Ещё добавился декодер адреса (Address Decoder), который, в зависимости от того, к какому адресу происходит обращение к памяти, перенаправляет обращение на ROM или RAM так, что первые 16КБ адресного пространства отводятся под ROM (диапазон адресов 0x0000-0x3FFF). В саму же ROM записывают (или "прошивают") какую-то управляющую программу.

В ZX Spectrum 48K памяти поделены на 16КБ ROM и 32КБ RAM. В ROM содержится полноценный интерпретатор языка BASIC (диалект Sinclair BASIC) и встроенные процедуры загрузки и сохранения (на ZX Spectrum - на обычнуюаудиокассету), то есть, ROM выполняет роль своего рода "прошивки" (firmware) или операционной системы и среды разработки.

Теперь, при включении процессор сразу начинает выполнять программу с адреса 0x0000 - она записана в ROM. Оставшиеся 32КБ оперативной памяти используются под нужды программы.

В Z-Frame

Такой подход с использованием ROM накладывает сразу несколько ограничений как на функциональность, так и на удобство разработки и программ, и самого "железа". Во-первых, программа всегда должна начинаться с того же адреса 0x0000 для старта. Во-вторых, чтобы отладить программу "вживую", нужно использовать перепрограммируемую ROM (ведь обычная ROM, напомню, записывается только один раз), то есть, нужна EEPROM (электрически стираемое перепрограммируемое запоминающее устройство, electrically erasable programmable ROM) - с возможностью стереть то, что было записано до этого, записать программатором новую программу (или новую версию), посмотреть, как она себя ведёт и повторять до достижения результата. В-третьих, всегда нужно будет учитывать, даже если пойти по примеру ZX Spectrum, что стартовый диапазон адресов (необязательно 16К) всегда будет фиксированным. Во всех случаях для компьютера с произвольным набором программного обеспечения (ПО), такой вариант реализации - крайне неудобен.

Поэтому нужно устройство, которое при включении, во-первых, запускается первым и может работать автономно само (без внешних процессора и оперативной памяти), во-вторых, сможет загрузить уже в эту внешнюю (по отношению к себе) память нужную программу, которую уже будет исполнять центральный процессор.

С такой задачей справится отдельный микроконтроллер, как обособленный вычислитель содержащий внутри себя и "процессор", и свою память и "прошивку" - свою программу, которая уже сможет загрузить нужную программу в RAM, например, прочитав её с подключённой SD-карты. Я выбрал для этой цели микроконтроллер STM32F407VGT6. Достаточное количество внутренней памяти для программы-"прошивки" (1МБ, flash-память), оперативной памяти (192КБ) и скорости (168МГц) позволят получить, забегая вперёд, много удобств и возможностей в дальнейшем.

FFFF  76        HALT