📘 Разработка для ZX Spectrum на Windows

Полная инструкция по настройке профессиональной среды разработки

🎮 48K / 128K / Next ⚡ SjASMPlus 🐞 CSpect + DeZog 🎨 Unreal Speccy 📦 GitHub Ready 🐙 Git + Merge

📁 Структура папок

Вся работа будет происходить в C:\Dev\ZX\ (создайте эту папку). Такая структура обеспечивает переносимость между компьютерами без необходимости настраивать PATH.

C:\Dev\ZX\

├── tools\ # Инструменты (общие для всех проектов)
│ ├── sjasmplus\
│ │ └── sjasmplus.exe
│ ├── CSpect\
│ │ ├── CSpect.exe
│ │ ├── DeZogPlugin.dll
│ │ └── RomFiles\
│ │ ├── spectrum.rom
│ │ ├── spectrum128.rom
│ │ ├── disk.rom
│ │ └── tr-dos.rom
│ └── UnrealSpeccy\
│ └── UnrealSpeccy.exe

└── projects\
└── mygame\
├── .vscode\
│ ├── tasks.json
│ └── launch.json
├── src\
│ └── main.asm
├── build\
│ └── (сюда будут попадать собранные файлы)
├── .gitignore
└── README.md

🛠️ Установка инструментов

1. Visual Studio Code

2. Git для Windows

💡 Git обязателен! Без него не будут работать команды git в терминале. После установки перезагрузите компьютер.

3. SjASMPlus (ассемблер)

⚠️ Важно: НЕ добавляйте в PATH! Будем вызывать через относительный путь ../../tools/sjasmplus/sjasmplus.exe.

4. Эмулятор CSpect (для отладки)

ℹ️ Где взять ROM-файлы? Они защищены авторскими правами, но есть в открытом доступе (например, в архивах с эмуляторами или ретро-сообществах).

5. Эмулятор Unreal Speccy (для быстрых тестов)

🔌 Установка расширений VSCode

  1. Запустите VSCode
  2. Нажмите Ctrl+Shift+X
  3. Установите:
    • Z80 Macro Assembler (mborland) — подсветка синтаксиса Z80/sjasmplus
    • DeZog (maziac) — отладчик с поддержкой CSpect и ZX Next
    • GitLens (опционально) — удобная работа с Git из VSCode
    • Git Graph (опционально) — визуализация веток

🆕 Создание проекта

  1. Создайте папку: C:\Dev\ZX\projects\mygame\
  2. Внутри создайте папки:
    • .vscode\ — для настроек редактора
    • src\ — для исходных кодов
    • build\ — для собранных файлов
  3. Откройте папку mygame в VSCode: File → Open Folder...

⚙️ Настройка VSCode — tasks.json

Создайте файл .vscode/tasks.json с таким содержимым:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Clean Build Folder",
            "type": "shell",
            "command": "if not exist \"${workspaceFolder}\\build\" mkdir \"${workspaceFolder}\\build\" & if exist \"${workspaceFolder}\\build\\*.*\" del /Q \"${workspaceFolder}\\build\\*.*\"",
            "group": "none",
            "presentation": {
                "reveal": "silent",
                "clear": false
            }
        },
        {
            "label": "Build All",
            "type": "shell",
            "command": "${workspaceFolder}/../../tools/sjasmplus/sjasmplus.exe",
            "args": [
                "${workspaceFolder}/src/main.asm",
                "--syntax=abf",
                "--lst=${workspaceFolder}/build/listing.lst",
                "--sym=${workspaceFolder}/build/symbols.sym"
            ],
            "dependsOn": ["Clean Build Folder"],
            "dependsOrder": "sequence",
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "owner": "sjasmplus",
                "fileLocation": "relative",
                "pattern": {
                    "regexp": "^(.*?)\\(([0-9]+)\\): (.*?): (.*)$",
                    "file": 1,
                    "line": 2,
                    "severity": 3,
                    "message": 4
                }
            },
            "options": {
                "cwd": "${workspaceFolder}"
            }
        },
        {
            "label": "Run CSpect 48K",
            "type": "process",
            "command": "${workspaceFolder}/../../tools/CSpect/CSpect.exe",
            "args": [
                "-remote",
                "-brk",
                "-mmc=${workspaceFolder}/build",
                "${workspaceFolder}/build/test.sna"
            ],
            "dependsOn": ["Build All"],
            "dependsOrder": "sequence",
            "presentation": {
                "reveal": "never"
            },
            "problemMatcher": []
        },
        {
            "label": "Run CSpect 128K",
            "type": "process",
            "command": "${workspaceFolder}/../../tools/CSpect/CSpect.exe",
            "args": [
                "-remote",
                "-brk",
                "-128k",
                "-mmc=${workspaceFolder}/build",
                "${workspaceFolder}/build/test.sna"
            ],
            "dependsOn": ["Build All"],
            "dependsOrder": "sequence",
            "presentation": {
                "reveal": "never"
            },
            "problemMatcher": []
        },
        {
            "label": "Run CSpect Next",
            "type": "process",
            "command": "${workspaceFolder}/../../tools/CSpect/CSpect.exe",
            "args": [
                "-remote",
                "-brk",
                "-zxnext",
                "-nextrom",
                "-mmc=${workspaceFolder}/build",
                "${workspaceFolder}/build/test.nex"
            ],
            "dependsOn": ["Build All"],
            "dependsOrder": "sequence",
            "presentation": {
                "reveal": "never"
            },
            "problemMatcher": []
        },
        {
            "label": "Run Unreal Speccy",
            "type": "process",
            "command": "${workspaceFolder}/../../tools/UnrealSpeccy/UnrealSpeccy.exe",
            "args": [
                "\"${workspaceFolder}/build/test.sna\""
            ],
            "dependsOn": ["Build All"],
            "dependsOrder": "sequence",
            "presentation": {
                "reveal": "never"
            },
            "problemMatcher": []
        }
    ]
}

🐛 Настройка отладки — launch.json

Создайте файл .vscode/launch.json для поддержки отладки всех трёх моделей:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "dezog",
            "request": "launch",
            "name": "🎮 48K (CSpect)",
            "remoteType": "cspect",
            "preLaunchTask": "Run CSpect 48K",
            "load": "${workspaceFolder}/build/test.sna",
            "startAutomatically": true,
            "rootFolder": "${workspaceFolder}",
            "cspect": {
                "pathToCSpectExe": "${workspaceFolder}/../../tools/CSpect/CSpect.exe",
                "instance": "0"
            },
            "sjasmplus": [
                {
                    "path": "${workspaceFolder}/build/symbols.sym",
                    "srcDirs": ["${workspaceFolder}/src"]
                }
            ]
        },
        {
            "type": "dezog",
            "request": "launch",
            "name": "🎵 128K (CSpect)",
            "remoteType": "cspect",
            "preLaunchTask": "Run CSpect 128K",
            "load": "${workspaceFolder}/build/test.sna",
            "startAutomatically": true,
            "rootFolder": "${workspaceFolder}",
            "cspect": {
                "pathToCSpectExe": "${workspaceFolder}/../../tools/CSpect/CSpect.exe",
                "instance": "0"
            },
            "sjasmplus": [
                {
                    "path": "${workspaceFolder}/build/symbols.sym",
                    "srcDirs": ["${workspaceFolder}/src"]
                }
            ]
        },
        {
            "type": "dezog",
            "request": "launch",
            "name": "⚡ ZX Next (CSpect)",
            "remoteType": "cspect",
            "preLaunchTask": "Run CSpect Next",
            "load": "${workspaceFolder}/build/test.nex",
            "startAutomatically": true,
            "rootFolder": "${workspaceFolder}",
            "cspect": {
                "pathToCSpectExe": "${workspaceFolder}/../../tools/CSpect/CSpect.exe",
                "instance": "0"
            },
            "sjasmplus": [
                {
                    "path": "${workspaceFolder}/build/symbols.sym",
                    "srcDirs": ["${workspaceFolder}/src"]
                }
            ]
        },
        {
            "type": "dezog",
            "request": "launch",
            "name": "🖥️ ZX Next (Serial/Real HW)",
            "remoteType": "zxnext",
            "zxnext": {
                "serial": "COM3"
            },
            "load": "${workspaceFolder}/build/test.nex",
            "startAutomatically": true,
            "rootFolder": "${workspaceFolder}",
            "sjasmplus": [
                {
                    "path": "${workspaceFolder}/build/symbols.sym",
                    "srcDirs": ["${workspaceFolder}/src"]
                }
            ]
        }
    ]
}
💡 Примечание: Для отладки на реальном ZX Spectrum Next через USB укажите правильный COM-порт (в примере COM3). Также необходимо загрузить специальный Debug ROM на устройство.

📝 Код программы — src/main.asm

Универсальный шаблон с поддержкой всех форматов и моделей:

; ============================================================
;   Универсальный проект для ZX Spectrum
;   Поддерживает: 48K, 128K, Next
;   Форматы: SNA, TAP, TRD, NEX
; ============================================================

    ; Раскомментируйте нужную строку для целевой модели:
    device ZXSPECTRUM48      ; для 48K и 128K
    ; device ZXSPECTRUM128   ; для 128K с банками
    ; device ZXSPECTRUMNEXT  ; для ZX Spectrum Next

    org $8000

Start:
    di
    ld sp, $FF00
    
    ; Очищаем экран
    call Cls
    
    ; Бесконечный цикл
    jr $

; ------------------------------------------------------------
;  Очистка экрана
; ------------------------------------------------------------
Cls:
    ld hl, $4000
    ld de, $4001
    ld bc, $1800
    ld (hl), 0
    ldir
    
    ld hl, $5800
    ld de, $5801
    ld bc, $0300
    ld (hl), $47
    ldir
    ret

; ------------------------------------------------------------
;  Конец программы — выбор форматов
; ------------------------------------------------------------
EndOfProgram:

    ; === Для 48K/128K ===
    savesna "build/test.sna", Start           ; Быстрое тестирование
    ; savetap "build/test.tap", Start, EndOfProgram-Start   ; Лента
    ; emptytrd "build/test.trd", "MYGAME"    ; Диск TR-DOS
    ; savetrd "build/test.trd", "CODE", Start, EndOfProgram-Start, "TEST.BIN"

    ; === Для ZX Spectrum Next ===
    ; savenex open "build/test.nex", 0
    ; savenex auto
    ; savenex entry Start
    ; savenex close

🎯 Форматы сборки

SjASMPlus поддерживает несколько форматов выходных файлов для ZX Spectrum:

ФорматДирективаДля чегоСкорость загрузки
SNASAVESNAБыстрое тестирование и отладка⚡ Мгновенно
TAPSAVETAPРелиз на ленте🎵 Реалистичная
TRDSAVETRD / EMPTYTRDРелиз на дискете (TR-DOS)⚡ Мгновенно
NEXSAVENEXZX Spectrum Next⚡ Мгновенно
💡 Рекомендация: Для разработки используйте .sna. Для релиза на классике — .tap (лента) или .trd (диск). Для ZX Spectrum Next — .nex.

🎮 ZX Spectrum Next

ZX Spectrum Next — это современное переосмысление классики!
28 МГц, 1-2 МБ RAM, аппаратные спрайты, слои (Layer2), цифровой звук, SD-карта.

📦 Формат NEX

Официальный формат программ для Next. Поддерживает:

Пример кода для Next

    DEVICE ZXSPECTRUMNEXT
    
    ; Настройка банков памяти
    MMU 6, 0        ; слот 6 ($C000) -> страница 0
    ORG $C000
    
Start:
    di
    ld sp, $FF00
    call Cls
    jr $

Cls:
    ld hl, $4000
    ld de, $4001
    ld bc, $1800
    ld (hl), 0
    ldir
    ret

    SAVENEX OPEN "build/demo.nex", 0
    SAVENEX AUTO
    SAVENEX SCREEN ULA, $4000, 6912
    SAVENEX ENTRY Start
    SAVENEX CLOSE

🚀 Запуск и отладка

Способ 1: Быстрый запуск в Unreal Speccy

Первый раз (настройка быстрой загрузки):

  1. Соберите проект: Ctrl+Shift+B
  2. Откройте UnrealSpeccy.exe
  3. Нажмите F3, выберите build/test.sna
  4. Нажмите Alt+F2 — сохраните в qsave1.sna

После каждого изменения:

  1. Ctrl+Shift+B (сборка)
  2. Переключитесь в Unreal Speccy
  3. Alt+F3 — мгновенная загрузка

Способ 2: Отладка в CSpect (48K / 128K / Next)

  1. Убедитесь, что DeZogPlugin.dll лежит рядом с CSpect.exe
  2. В VSCode: Ctrl+Shift+D
  3. Выберите нужную конфигурацию в выпадающем меню:
    • 🎮 48K (CSpect) — для классических программ
    • 🎵 128K (CSpect) — для AY-музыки и банков
    • ⚡ ZX Next (CSpect) — для Next в эмуляторе
    • 🖥️ ZX Next (Serial/Real HW) — для отладки на реальном устройстве
  4. Нажмите F5
Что произойдёт: Автоматически соберётся проект, запустится CSpect с нужными параметрами, программа остановится на первой инструкции. Вы можете ставить брейкпоинты (F9) и смотреть регистры.

📦 GitHub и .gitignore

Файл .gitignore в корне проекта:

# Собранные файлы
build/*.sna
build/*.tap
build/*.trd
build/*.nex
build/*.bin
build/*.lst
build/*.sym

# Настройки VSCode (опционально)
# .vscode/

# Системный мусор
.DS_Store
Thumbs.db
*.tmp
*.log

Пример README.md для репозитория:

# MyGame for ZX Spectrum

## Совместимость
- ✅ ZX Spectrum 48K
- ✅ ZX Spectrum 128K
- ✅ ZX Spectrum Next

## Сборка
1. Установите SjASMPlus, CSpect, Unreal Speccy
2. Откройте проект в VSCode
3. Нажмите Ctrl+Shift+B

## Отладка
- 48K: "🎮 48K (CSpect)" → F5
- 128K: "🎵 128K (CSpect)" → F5
- Next: "⚡ ZX Next (CSpect)" → F5

## Форматы
- `.sna` — для разработки
- `.tap` — для ленты
- `.trd` — для tr-dos
- `.nex` — для Next

🐙 GitHub и работа с Git

💡 Git — это система контроля версий. GitHub — облачный сервис для хранения репозиториев. Все команды выполняются в терминале VSCode (Ctrl+`).

📦 Первоначальная настройка Git

Выполните один раз после установки Git:

$ git config --global user.name "Your Name"
$ git config --global user.email "your.email@example.com"
📝 Важно: Используйте ту же почту, что и в аккаунте GitHub.

🚀 Публикация проекта на GitHub (пошагово)

Шаг 1: Инициализация репозитория в папке проекта

$ cd C:\Dev\ZX\projects\mygame
$ git init

Шаг 2: Добавление всех файлов в Git

$ git add . # добавляем все файлы
$ git status # проверяем, что добавилось

Шаг 3: Создание первого коммита

$ git commit -m "Initial commit: ZX Spectrum project setup"

Шаг 4: Создание репозитория на GitHub

Шаг 5: Связывание локального репозитория с GitHub

$ git remote add origin https://github.com/ВАШ_ЛОГИН/mygame.git
$ git branch -M main
$ git push -u origin main
Готово! Проект опубликован. Откройте https://github.com/ВАШ_ЛОГИН/mygame

🔄 Повседневные команды Git

КомандаЧто делает
git statusПоказывает изменённые файлы
git add src/main.asmДобавляет конкретный файл
git add . Добавляет все изменённые файлы
git commit -m "Описание" Создаёт коммит
git push Отправляет коммиты на GitHub
git pull Забирает изменения с GitHub
git log --oneline Показывает историю коммитов
git diff Показывает изменения в файлах

🔀 Продвинутые команды Git: ветки, merge, конфликты, теги

🌿 Работа с ветками (branches)

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

Основные команды для веток

КомандаЧто делает
git branchПоказывает список веток (* — текущая ветка)
git branch new-featureСоздаёт новую ветку с именем new-feature
git checkout new-featureПереключается на ветку new-feature
git checkout -b new-featureСоздаёт и сразу переключается на новую ветку
git branch -d new-featureУдаляет ветку new-feature
$ git branch # * main
$ git checkout -b feature/sprite # создаём ветку для спрайтов
$ git branch # * feature/sprite, main

🔗 Слияние веток (merge)

Когда функция готова, нужно влить её обратно в основную ветку (main).

Пошаговый процесс merge

$ git checkout main # переключаемся на основную ветку
$ git merge feature/sprite # сливаем ветку feature/sprite в main
$ git branch -d feature/sprite # удаляем слитую ветку
✅ Если конфликтов нет — код объединится автоматически.

⚠️ Разрешение конфликтов (conflicts)

Конфликт возникает, когда две ветки меняют одни и те же строки кода. Git не может автоматически выбрать правильный вариант.

Как разрешить конфликт:

  1. Откройте файл с конфликтом — увидите маркеры:
<<<<<<< HEAD
    ld a, 10        # ваш код в main
=======
    ld a, 20        # код из ветки feature
>>>>>>> feature/sprite
  1. Отредактируйте файл, оставив нужный код (или объединив оба варианта).
  2. Удалите маркеры <<<<<<<, =======, >>>>>>>.
  3. Сохраните файл.
  4. Добавьте исправленный файл в Git:
$ git add src/main.asm
$ git commit -m "Resolved merge conflict"
💡 Совет: В VSCode конфликты отображаются наглядно: есть кнопки "Accept Current Change", "Accept Incoming Change", "Accept Both Changes".

🏷️ Теги (tags) — создание версий релиза

Теги фиксируют состояние кода в определённый момент (например, версия 1.0).

Основные команды для тегов

КомандаЧто делает
git tagПоказывает список тегов
git tag v1.0.0Создаёт лёгкий тег (lightweight)
git tag -a v1.0.0 -m "First release"Создаёт аннотированный тег с сообщением
git push origin v1.0.0Отправляет тег на GitHub
git push --tagsОтправляет все теги на GitHub
git tag -d v1.0.0Удаляет тег локально
$ git tag -a v1.0.0 -m "Release version 1.0.0"
$ git push origin v1.0.0
$ git push --tags # если много тегов

📥 Клонирование чужого проекта

$ git clone https://github.com/username/project.git
$ cd project
$ code . # открыть в VSCode

📤 Pull Request (PR) — предложение изменений

Если вы хотите внести изменения в чужой проект (форк), алгоритм такой:

  1. Сделайте Fork репозитория на GitHub (кнопка "Fork").
  2. Склонируйте форк к себе: git clone https://github.com/ВАШ_ЛОГИН/project.git
  3. Создайте ветку: git checkout -b my-fix
  4. Внесите изменения, сделайте коммит и пуш: git push origin my-fix
  5. На GitHub нажмите "Compare & pull request" → создайте PR.
  6. Дождитесь, пока автор проекта примет или отклонит изменения.

📋 Полезные команды для работы с удалённым репозиторием

КомандаЧто делает
git remote -vПоказывает список удалённых репозиториев
git remote add upstream URLДобавляет оригинальный репозиторий как upstream
git fetch upstreamЗабирает изменения из upstream
git merge upstream/mainСливает изменения из upstream в свою ветку
💡 Совет: Используйте git fetch вместо git pull, если хотите сначала посмотреть изменения без автоматического слияния.

🎯 Типичный рабочий цикл с ветками

$ git checkout -b feature/new-graphics
$ git add src/sprites.asm
$ git commit -m "Добавил новые спрайты"
$ git push origin feature/new-graphics
$ git checkout main
$ git merge feature/new-graphics
$ git branch -d feature/new-graphics
$ git push origin main # отправляем изменения на GitHub

⌨️ Быстрые команды

VSCode и сборка

ДействиеКоманда
Собрать проектCtrl+Shift+B
Открыть терминалCtrl+`
Перейти к отладкеCtrl+Shift+D
Запустить отладкуF5 (с выбранной конфигурацией)
Установить брейкпоинтF9 (на строке кода)
Шаг с обходомF10
Шаг с заходомF11

Git (базовые)

КомандаДействие git statusУзнать состояние git add .Добавить все изменения git commit -m "msg"Создать коммит git pushОтправить на GitHub git pullЗабрать с GitHub git log --onelineИстория коммитов

Git (продвинутые)

КомандаДействие
git branchСписок веток
git checkout -b newСоздать и переключиться на ветку new
git merge branchСлить ветку branch в текущую
git tag v1.0.0Создать тег v1.0.0
git push --tagsОтправить все теги на GitHub
git clone URLСклонировать репозиторий

В Unreal Speccy:

Горячая клавишаДействие
Alt+F3Быстрая загрузка
Alt+F2Быстрое сохранение

🐛 Устранение проблем

ПроблемаРешение
sjasmplus.exe not foundПроверьте путь в tasks.json. Убедитесь, что папка tools на два уровня выше проекта.
CSpect.exe not foundАналогично — проверьте количество ../.
DeZogPlugin.dll not foundПоложите файл рядом с CSpect.exe.
CSpect запускается, но не подключаетсяУбедитесь, что в аргументах есть -remote. Закройте CSpect вручную, нажмите F5 заново.
Ошибка "Cannot find ROM files"Создайте папку RomFiles\ рядом с CSpect.exe и положите туда прошивки.
SAVETRD не работаетОбновите sjasmplus до версии 1.15.0 или выше.
Ошибки при сборке .nexДобавьте DEVICE ZXSPECTRUMNEXT в начало файла. Заполните банки через MMU.
git не распознаётсяПереустановите Git для Windows, отметьте "Add to PATH". Перезагрузите компьютер.
Ошибка при push: "failed to push"Сначала сделайте git pull --rebase, потом git push.
Merge conflictОтредактируйте файл с маркерами <<<<<<<, сделайте git add и git commit.
Как удалить файл из Git?git rm --cached файл.asm (оставить локально) или git rm файл.asm (удалить везде).
Как отменить последний коммит?git reset --soft HEAD~1 (оставить изменения) или git reset --hard HEAD~1 (удалить изменения).

🎉 Поздравляем! Ваша профессиональная среда для разработки под ZX Spectrum полностью настроена!
Теперь вы можете писать код для 48K, 128K и Next, собирать в любых форматах (.sna, .tap, .trd, .nex), отлаживать прямо в VSCode,
управлять версиями через Git, публиковать проекты на GitHub и работать с ветками и пул-реквестами.