Skip to content
drew.po28@gmail.com edited this page Jun 27, 2026 · 3 revisions

Debug — Отладка

Путь в меню: Debug · Платы: все · Требует: SD-карту (только для «Сохранить дамп в файл» и лога на SD)

Что это

Под словом «отладка» в pico-spec живут две разные вещи, и их полезно различать:

  1. Меню Debug (OSD, во время работы) — встроенный отладчик Z80, который открывается из меню (или по горячим клавишам) прямо во время эмуляции: пошаговый просмотр кода/памяти/регистров, точки останова (по PC, по портам и по памяти), Переход / Poke / NMI, дамп памяти на экран или в файл на SD и runtime- переключатель лога на SD. Это пользовательская часть, она описана ниже.

  2. Журналирование для разработчика (на этапе сборки / в исходниках) — Debug::log в консольный UART, Debug::log2SD в debug.log на SD и набор пер-подсистемных verbose-логов *_TRACE, которые являются опциями CMake (в релизных сборках выключены). См. Журналирование для разработчика.

Меню Debug — для исследования гостевого (ZX-Spectrum) кода во время работы. Опции трассировки — для разработчиков, отлаживающих сам эмулятор; их нет ни в одном меню.

Структура меню

Debug
├── Debug dialog      (Alt+F5)   открыть полноэкранный отладчик Z80
├── BreakPoint        (Alt+F7)   добавить точку останова (тип → адрес)
├── BP List                      список точек останова, переход отладчика к одной
├── Jump to                      установить PC по адресу (без выполнения)
├── Input Poke        (Alt+F9)   записать байт в память (адрес/значение, опц. банк)
├── Trigger NMI       (Alt+F10)  выдать NMI процессору Z80
└── Debug Log ▸                  Write debug.log  [Yes/No]  — runtime-лог на SD

(Показаны клавиши по умолчанию — все они переназначаются в Options → Host keys.)

У BP List и Jump to больше нет выделенных горячих клавиш — оба действия по-прежнему доступны из меню Debug. Освободившаяся Alt+F8 теперь по умолчанию переключает экранные индикаторы LED (новая переназначаемая клавиша).

Пункты меню Debug

Пункт Клавиша Что делает
Debug dialog Alt+F5 Открывает полноэкранный отладчик (osdDebug): дизассемблер + панель регистров + панель памяти, пошаговое выполнение, точки останова, поиск, предпросмотр экрана. Клавиши — ниже
BreakPoint Alt+F7 Выбрать тип (адрес PC / чтение порта / запись порта / запись памяти / чтение памяти), затем ввести адрес. До 20 точек, сохраняются в NVS
BP List — Список активных точек (тип + адрес), удаление по Del; Enter открывает отладчик по этому адресу
Jump to — Установить PC Z80 по введённому адресу. Меняет точку возобновления выполнения; не делает шаг
Input Poke Alt+F9 Записать один байт: ввести Адрес + Значение (и опционально банк RAM 0–7). Полезно для читов/патчей
Trigger NMI Alt+F10 Выдать немаскируемое прерывание Z80 (Z80::triggerNMI). При активном DivMMC это NMI-automap esxDOS; ZX-Byte показывает своё NMI-меню
Debug Log — Подменю Write debug.log [Yes/No] — включает/выключает лог на SD во время работы (см. ниже). Сохраняется в NVS (debug_log)

Часть этих действий привязана и к горячим клавишам, поэтому отладчик, добавление точки останова, poke и NMI можно вызвать без захода в меню. BP List и Jump to доступны только из меню (их прежние клавиши Alt+F7 / Alt+F8 удалены).

Типы точек останова

Тип Код Срабатывает, когда…
Адрес PC PC счётчик команд достигает адреса
Чтение порта PR гость читает из порта ввода-вывода
Запись порта PW гость пишет в порт ввода-вывода
Запись памяти MW гость пишет по адресу памяти
Чтение памяти MR гость читает по адресу памяти

При срабатывании точки текущий кадр завершается и открывается отладчик. В строке статистики работающей машины при заданных точках показывается BP(s):N.

Полноэкранный отладчик

В отладчике (Debug dialog) три секции, переключаемые по Tab: Code (дизассемблер вокруг PC), Memory (панель hex/ASCII) и Regs. Нажмите F1 внутри для встроенной справки. Клавиши:

Клавиша Действие
Space Шаг на одну инструкцию CPU
Alt+Space Шаг через CALL (временная точка останова на адресе возврата)
Enter Перейти к адресу (просмотр; в панели — инлайн-правка hex)
Tab Сменить секцию: Code / Memory / Regs
F5 Переключить PC-точку останова на строке курсора
F7 Добавить точку останова (выбор типа)
Alt+F7 Список точек останова
F8 Установить PC по адресу под курсором
F2 Показать экран гостя (наложение дампа памяти)
Alt+F2 Сохранить дамп в файл → dump.log на SD (сначала выбор диапазона)
Alt+F1 Поиск в памяти по последовательности hex-байтов
F3 Найти далее
Alt+T Переключить панель памяти HEX ↔ ASCII
Alt+F9 Показать экран гостя на весь экран
F11 / F12 Загрузить / сохранить снапшот
+ / − / 0 Сдвиг предпросмотра экрана вверх / вниз / по умолчанию
PageUp/Down, стрелки Прокрутка кода / перемещение курсора в памяти
Esc Выйти из отладчика

Дамп памяти на SD (dump.log)

Alt+F2 в отладчике запрашивает диапазон адресов, затем пишет полный дамп состояния в /.config/pico-spec/dump.log (создаётся заново каждый раз, CREATE_ALWAYS). Дамп содержит по порядку:

Раздел Содержимое
Заголовок Диапазон дампа #xxxx – #xxxx
Машина Arch + RomSet
Состояние ROM/страниц romInUse, romLatch, bankLatch, videoLatch, pagingLock, page0ram, newSRAM, divmmc
TR-DOS вкл/выкл + версия TR-DOS BIOS
Регистры AF BC DE HL (+ альт. AF' BC' DE' HL'), IX IY SP PC, I R IM IFF1 IFF2 Halted
Флаги S Z H P N C, раскодированные из F
Стек верхние 8 слов (SP+00 … SP+0E)
CPU T-states + statesInFrame
TR-DOS / WD1793 состояние TR-DOS, защита записи FDD A–D и FDC: cmd status track sector data drive side dsr led retry state stepState control, плюс по дискам tracks / sides / wp / имя файла
Дамп памяти hex + ASCII по выбранному диапазону

Это эффективный способ снять полный срез состояния для офлайн-анализа — в отличие от ручного пошагового выполнения.

Журналирование для разработчика

Этот раздел — на этапе сборки / в исходниках; ничего из него нет в меню, кроме runtime-переключателя debug.log выше.

Debug::log() — консольный UART (всегда включён)

Debug::log(fmt, …) печатает в консольный UART (или printf, где debug-UART нет). Он всегда скомпилирован и всегда срабатывает — без флага. Работа «по возможности» и теряет данные при флуде: пишет, только пока в TX-FIFO UART есть место, и отбрасывает остаток, а не блокируется (иначе зависание логирования в горячем пути — например в ZiFi net-pump или загрузчике ленты — заморозило бы главный цикл или сломало тайминги).

⚠️ Никогда не логируйте внутри плотного цикла загрузчика / горячего цикла. Даже одна запись на IN A,(0xFE) добавляет тысячи T-состояний и ломает турбо-загрузчики ленты.

Debug::log2SD() — debug.log на SD (runtime-переключатель)

Debug::log2SD(fmt, …) дописывает строки с метками времени в /.config/pico-spec/debug.log на SD. Гейтится runtime-флагом Debug::log_enabled, который управляется пунктом меню Debug → Debug Log → Write debug.log [Yes/No] (сохраняется в NVS как debug_log). Когда флаг выключен, вызов сворачивается в одну проверку и ничего не пишет. Лог ограничен 200 КБ и перезаписывается с начала при переполнении; каждая сессия начинается с заголовка --- BOOT (POWER-ON | WATCHDOG) ---.

Замечание: это runtime-переключатель, а не старый compile-define DEBUG=1. Включите его из меню, воспроизведите проблему, затем прочитайте debug.log с SD.

Пер-подсистемные опции *_TRACE (CMake, по умолчанию OFF)

Подробные трассировки каждого доступа есть в исходниках, но выключены при компиляции, если не собрать с соответствующей опцией CMake. Они задаются в одном месте (CMakeLists.txt) как option(... OFF) → -DXXX_TRACE=1/0; в коде просто #if XXX_TRACE … #endif. Когда выключено — это настоящие no-op (ни кода, ни RAM). Включить, например: cmake -B build -DFDD_PORT_TRACE=ON.

Опция Что трассирует
IDE_PORT_TRACE доступ к портам IDE/HDD PROFI (Ports.cpp, IDE.cpp)
FDD_PORT_TRACE команды/порты WD1793 (ВГ93) FDD
RTC_PORT_TRACE доступ к портам ..F7 RTC MC146818 (Mr Gluk)
PROFI_PORT_TRACE записи в порты страничной памяти 0x7FFD / 0xDFFD
SND_PORT_TRACE гистограмма ввода-вывода по портам (поиск звукового ЦАП)
PERF_TRACE производительность CPU / HDMI / FPS раз в 60 кадров
GS_PERF_TRACE счётчики производительности General Sound (раз в секунду)
GS_DEBUG_TRACE кольцевой трейс портов General Sound + авто-дампы (~50 КБ SRAM)
ZIFI_TRACE трафик портов / UART ZiFi (ESP-01S NIC)
ZIFI_NET_VERBOSE пакетный трейс net-клиента ZiFi (флудит лог)

⚠️ Они затапливают консольный UART и могут сломать тайминг-чувствительные пути (скан WiFi, FTP/передачи, загрузчики ленты). Держите их OFF, кроме случаев активной отладки именно этой подсистемы, и никогда не выпускайте сборку с ними.

Debug Probe UART (*_DBG_UART, CMake)

Отдельные пер-платные ключи CMake (MURM1_DBG_UART, PICO_PC_DBG_UART, PICO_DV_DBG_UART, ZERO_DBG_UART, ZERO2_DBG_UART, по умолчанию все OFF) выводят консольный UART на разъём для отладочного зонда / монитора порта. Включение забирает GPIO у других периферий (например, переносит клавиатуру и отключает NESPAD на MURM1) — см. Платы и распиновка.

Файлы на SD

Путь Назначение
/.config/pico-spec/debug.log вывод Debug::log2SD (≤ 200 КБ, циклически). Активен при Debug Log = Yes
/.config/pico-spec/dump.log один дамп состояния+памяти на каждое Alt+F2 в отладчике (перезаписывается)

Как проверить

Действие Что проверяет Ожидаемый результат
Поставить PC-точку, прогнать гостевой код мимо неё Движок точек останова Кадр завершается, отладчик открывается на адресе; в статистике BP(s):1
В отладчике Alt+F2 при наличии SD Дамп в файл Создаётся dump.log с регистрами/стеком/WD1793/памятью; уведомление «Dump saved»
Debug Log → Yes, воспроизвести, прочитать SD runtime-гейт log2SD debug.log растёт строками с метками времени + заголовок --- BOOT … ---
Input Poke по адресу, продолжить Poke Байт меняется в памяти (и в панели Memory отладчика)

См. тестовые образы.

Ссылки

Clone this wiki locally