Files
CBE/MANUAL.md
T
2026-06-04 03:22:17 +00:00

1043 lines
36 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CBE Platform — Полное руководство по созданию плагинов и систем
## Содержание
1. [Введение](#1-введение)
2. [Архитектура CBE](#2-архитектура-cbe)
3. [Формат плагина (.cbeplugin)](#3-формат-плагина-cbeplugin)
4. [Создание модуля CPU](#4-создание-модуля-cpu)
5. [Создание модуля RAM](#5-создание-модуля-ram)
6. [Создание модуля GPU](#6-создание-модуля-gpu)
7. [Создание модуля KBD (клавиатура)](#7-создание-модуля-kbd)
8. [Создание модуля SND (звук)](#8-создание-модуля-snd)
9. [Создание модуля BIOS](#9-создание-модуля-bios)
10. [Создание модуля DISK](#10-создание-модуля-disk)
11. [Семантические операции инструкций](#11-семантические-операции)
12. [Написание программ на ассемблере](#12-написание-программ-на-ассемблере)
13. [Написание программ на C/C++](#13-написание-программ-на-cc)
14. [Написание программ на Python](#14-написание-программ-на-python)
15. [Hex-машинный код](#15-hex-машинный-код)
16. [Сборка плагинов (cbecc)](#16-сборка-плагинов-cbecc)
17. [Тулчейн: компиляция из разных языков](#17-тулчейн-компиляция-из-разных-языков)
18. [Система POST-диагностики](#18-система-post-диагностики)
19. [Memory-mapped I/O](#19-memory-mapped-io)
20. [Бесконечные шаги и детектор циклов](#20-бесконечные-шаги-и-детектор-циклов)
21. [Тёмная тема GUI](#21-тёмная-тема-gui)
22. [Примеры](#22-примеры)
23. [Устранение неполадок](#23-устранение-неполадок)
24. [Справочник команд](#24-справочник-команд)
---
## 1. Введение
**CBE (Create. Build. Execute.)** — платформа для эмуляции и создания собственных компьютерных компонентов: процессоров, оперативной памяти, видеокарт, дисков, BIOS, клавиатур и звуковых карт. Всё это собирается в единую архитектуру и запускается через эмулятор с графическим интерфейсом.
Основная идея: вы описываете поведение компонента через JSON-конфигурацию и/или бинарные данные, а платформа предоставляет среду выполнения с:
- Эмулятором на Java с GUI (Swing)
- Компилятором .cbeplugin
- Тулчейном для ассемблера, C/C++, Python, hex
- Системой POST-диагностики
- Детектором бесконечных циклов
- Тёмной темой
### Ключевые концепции
- **Plugin** — модуль в формате `.cbeplugin`, содержащий метаданные, инструкции, микрокод и данные
- **ModuleInstance** — экземпляр загруженного модуля в эмуляторе
- **Engine** — оркестратор, управляющий всеми модулями и циклом выполнения CPU
- **Bus** — системная шина, связывающая модули
- **Registers** — регистры CPU
- **POST** — Power-On Self-Test, система самодиагностики при старте
- **Memory-mapped I/O** — регистры ввода-вывода, отображённые на адресное пространство
---
## 2. Архитектура CBE
```
┌─────────────────────────────────────────────────────────────┐
│ CBE Emulator │
├─────────────────────────────────────────────────────────────┤
│ ┌───────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │ CPU │ │ RAM │ │ GPU │ │ KBD │ │
│ │ (плагин) │ │ (плагин) │ │ (плагин) │ │ (плагин) │ │
│ └─────┬─────┘ └────┬─────┘ └────┬─────┘ └─────┬─────┘ │
│ │ │ │ │ │
│ ┌─────┴──────────────┴─────────────┴───────────────┴─────┐ │
│ │ System Bus (шина) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │ │ │ │
│ ┌─────┴─────┐ ┌────┴────┐ ┌─────┴─────┐ ┌──────┴─────┐ │
│ │ SND/Sound│ │ BIOS │ │ DISK │ │ POST │ │
│ │ (плагин) │ │ (плагин)│ │ (плагин) │ │ (встроено) │ │
│ └───────────┘ └─────────┘ └───────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### Модули (ModuleType)
| Тип | ID | Описание |
|---------|----|--------------------------------------------------------------|
| CPU | 0 | Процессор. Определяет регистры, набор инструкций, микрокод |
| RAM | 1 | Оперативная память с банками данных |
| DISK | 2 | Диск с секторной адресацией (512 байт/сектор) |
| GPU | 3 | Видеокарта. 80x25 текстовый режим, VRAM, курсор |
| BIOS | 4 | BIOS с информацией о системе |
| KBD | 5 | Клавиатура с буфером клавиш, handshake-протокол |
| SND | 6 | Звуковая карта (PC Speaker beep) |
| DATA_ONLY | 7 | Только данные, без логики |
### CompileMode
| Режим | ID | Описание |
|------------|----|------------------------------------|
| FULL | 0 | Только логика (инструкции + микрокод) |
| HYBRID | 1 | Логика + данные |
| PACK_ONLY | 2 | Только данные |
---
## 3. Формат плагина (.cbeplugin)
### Структура файла
Бинарный формат с little-endian числами:
```
Смещение Размер Поле
-------- ------ ------------------------------------
0 8 Магическая строка: "CBE_PLUG\0"
8 4 Версия (int32 LE)
12 4 Размер заголовка (int32 LE, всегда 62)
16 1 ModuleType (byte)
17 1 CompileMode (byte)
18 4 Смещение секции метаданных (int32 LE)
22 4 Длина секции метаданных
26 4 Смещение таблицы опкодов
30 4 Длина таблицы опкодов
34 4 Смещение таблицы микрокода
38 4 Длина таблицы микрокода
42 4 Смещение байткода обработчика
46 4 Длина байткода обработчика
50 4 Смещение секции данных
54 4 Длина секции данных
58 4 CRC32 (покрывает байты 0..57)
```
### Секции после заголовка
- **Метаданные:** JSON-строка с name, arch, module_type, version, tdp, frequency
- **Таблица опкодов:** JSON-массив объектов инструкций
- **Микрокод:** JSON-объект { command: [byte, ...] }
- **Байткод обработчика:** зарезервировано (raw bytecode)
- **Секция данных:** [bank_count:4][bank0_size:4][bank0_data...][bank1_size:4]...
---
## 4. Создание модуля CPU
### Структура директории
```
my-cpu.cpu/
├── module.json # Метаданные модуля
├── registers.json # Определения регистров
├── instructions/ # Определения инструкций
│ ├── 0x00.json # NOP
│ ├── 0x01.json # MOV
│ └── ...
├── microcode/
│ └── bus.json # Сигналы шины
├── roms/
│ └── boot.bin # Boot ROM (исполняемый код)
├── banks/ # Банки данных (опционально)
│ └── bank_0.bin
├── program.asm # Исходник программы (альтернатива boot.bin)
├── program.c # Исходник на C
├── program.py # Исходник на Python
└── program.hex # Hex-машинный код
```
### module.json
```json
{
"name": "MyCPU",
"arch": "my-8bit",
"module_type": "cpu",
"version": 1,
"tdp": 5.0,
"memory_size": 65536,
"frequency": 1000000
}
```
Поля:
- `name` — название процессора
- `arch` — архитектура (строка)
- `module_type` — "cpu"
- `tdp` — тепловыделение (W)
- `memory_size` — размер адресного пространства (байт)
- `frequency` — частота в Hz
### registers.json
```json
{
"a": 0,
"b": 0,
"c": 0,
"d": 0,
"pc": 0,
"sp": 0,
"carry": 0,
"zero": 0
}
```
Каждый регистр — ключ с начальным значением. `pc` (program counter) и `sp` (stack pointer) обязательны.
### Определение инструкции
Файл `instructions/0x00.json`:
```json
{
"opcode": 0,
"mnemonic": "NOP",
"args": [],
"cycles": 1,
"semantics": [
{"op": "nop"}
]
}
```
Инструкция с аргументами:
```json
{
"opcode": 2,
"mnemonic": "MOV_IMM_A",
"args": [
{"name": "value", "type": "imm"}
],
"cycles": 2,
"semantics": [
{"op": "load_imm", "to": "a", "value": "$next"}
]
}
```
- `opcode` — числовой код операции (0-255)
- `mnemonic` — мнемоника для ассемблера
- `args` — список аргументов (name + type: "reg", "imm", "address")
- `cycles` — тактов на выполнение
- `semantics` — список семантических операций (см. раздел 11)
### Микрокод (bus.json)
```json
{
"memory_read": [0x01, 0x00],
"memory_write": [0x02, 0x00],
"io_read": [0x03],
"io_write": [0x04]
}
```
Каждый сигнал — имя и массив байт.
### Boot ROM
Файл `roms/boot.bin` содержит исполняемый код, который загружается в начало адресного пространства CPU при старте. Максимальный размер — 64KB. Можно создать:
- через ассемблер (program.asm)
- через компилятор C (program.c)
- через Python-транслятор (program.py)
- как hex-дамп (program.hex)
---
## 5. Создание модуля RAM
```
my-ram.ram/
├── module.json
├── banks/
│ └── bank_0.bin # Начальные данные RAM
└── controller/ # Опциональный контроллер
└── microcode/
└── bus.json
```
### module.json
```json
{
"name": "MyRAM",
"arch": "generic-ram",
"module_type": "ram",
"version": 1,
"tdp": 2.0,
"bank_size": 256,
"bank_count": 1
}
```
Поля:
- `bank_size` — размер банка в байтах
- `bank_count` — количество банков
---
## 6. Создание модуля GPU
```
my-gpu.gpu/
├── module.json
├── banks/
│ └── bank_0.bin # VRAM (2000 байт для 80x25)
└── microcode/
└── bus.json
```
### module.json
```json
{
"name": "MyGPU",
"arch": "vga-text-80x25",
"module_type": "gpu",
"version": 1,
"tdp": 10.0,
"vram_size": 2000,
"rows": 25,
"cols": 80
}
```
Поля:
- `vram_size` — размер видеопамяти (80x25 = 2000)
- `rows` — количество строк
- `cols` — количество колонок
GPU отображается как 80x25 текстовый терминал (а-ля QEMU). Вывод символов осуществляется записью в порт 0xC0.
---
## 7. Создание модуля KBD
```
my-kbd.kbd/
└── module.json
```
### module.json
```json
{
"name": "MyKeyboard",
"arch": "ps2-like",
"module_type": "kbd",
"version": 1,
"tdp": 0.5,
"buffer_size": 32
}
```
Поля:
- `buffer_size` — размер буфера клавиш
Клавиатура работает через memory-mapped I/O:
- Чтение `0xFB` — данные клавиши (peek, не удаляет)
- Чтение `0xFA` — статус (0 = нет клавиши, 1 = есть)
- Запись `0xFA = 0` — acknowledge (удаляет клавишу из буфера)
---
## 8. Создание модуля SND
```
my-snd.snd/
└── module.json
```
### module.json
```json
{
"name": "MySound",
"arch": "pc-speaker",
"module_type": "snd",
"version": 1,
"tdp": 1.0
}
```
Любая запись в порт `0xF9` вызывает системный звуковой сигнал (beep). Частота ограничена 10 beep/сек.
---
## 9. Создание модуля BIOS
```
my-bios.bios/
└── module.json
```
### module.json
```json
{
"name": "MyBIOS",
"arch": "generic-bios",
"module_type": "bios",
"version": 1,
"tdp": 1.0
}
```
BIOS хранит строку информации о системе, доступную через `engine.getSystemInfo()`. Триггер перезапуска диагностики — запись в порт `0xF7`.
---
## 10. Создание модуля DISK
```
my-disk.disk/
├── module.json
└── banks/
└── bank_0.bin # Данные диска
```
### module.json
```json
{
"name": "MyDisk",
"arch": "ata-like",
"module_type": "disk",
"version": 1,
"tdp": 5.0,
"sector_size": 512
}
```
Диск работает через порты:
- `0xB0` — запись LBA сектора (инициирует чтение)
- `0xB1` — статус готовности (1 = готов)
- `0xB2+` — данные сектора (512 байт)
Если последние 2 байта сектора 0 равны `0x55 0xAA`, диск считается загрузочным.
### Загрузка с диска (Boot flow)
При старте эмулятор выполняет POST-диагностику, которая:
1. Пишет BIOS-программу в память CPU (адреса `0x00..0x15`)
2. Строит POST-текст и размещает его в буфере display (`0x16+`)
3. Если диск загрузочный (сектор 0 содержит `0x55 0xAA`):
- Копирует сектор 0 в память CPU по адресу `0x80`
- Заменяет idle-цикл BIOS (`0x14..0x15`) на `JMP_IMM 0x80`
4. CPU начинает выполнение с `PC=0`:
- Исполняет BIOS-программу, которая выводит POST-текст на GPU
- После вывода POST-текста переходит к `0x14` → прыжок на `0x80`
- CPU выполняет загрузочный код из сектора 0
Пример создания загрузочного диска (Python):
```python
# TinyCPU bytecode for boot sector at address 0x80
# Prints "BOOT OK!" to GPU via port 0xC0, then halts
program = bytes([
0x02, 0x42, # MOV_IMM_A 'B'
0x0A, 0xC0, # STORE_A 0xC0
0x02, 0x4F, # MOV_IMM_A 'O'
0x0A, 0xC0, # STORE_A 0xC0
0x02, 0x4F, # MOV_IMM_A 'O'
0x0A, 0xC0, # STORE_A 0xC0
0x02, 0x54, # MOV_IMM_A 'T'
0x0A, 0xC0, # STORE_A 0xC0
0x02, 0x20, # MOV_IMM_A ' '
0x0A, 0xC0, # STORE_A 0xC0
0x02, 0x4F, # MOV_IMM_A 'O'
0x0A, 0xC0, # STORE_A 0xC0
0x02, 0x4B, # MOV_IMM_A 'K'
0x0A, 0xC0, # STORE_A 0xC0
0x02, 0x21, # MOV_IMM_A '!'
0x0A, 0xC0, # STORE_A 0xC0
0xFF, # HLT
])
sector = program + b'\x00' * (510 - len(program)) + b'\x55\xAA'
```
Готовый пример: `examples/system-disk/disk.img/`.
---
## 11. Семантические операции
| Операция | Описание |
|-------------|--------------------------------------------------------------|
| `copy` | Копирует значение из `from` в `to` |
| `load_imm` | Загружает непосредственное значение (literal или `$next`) |
| `add` | Складывает `from` + `to`, сохраняет в `result`, обновляет флаги carry/zero |
| `sub` | Вычитает `to` из `from`, обновляет флаги borrow/zero |
| `cmp` | Сравнивает `from` - `to`, обновляет флаги |
| `store` | Записывает значение в память `mem[address]` |
| `load` | Читает из памяти `mem[address]` в регистр |
| `jmp` | Безусловный переход на адрес в `to` |
| `jcc` | Условный переход, если флаг равен ожидаемому |
| `jmp_imm` | Переход на байт, следующий за опкодом |
| `jcc_imm` | Условный переход на байт за опкодом |
| `call` | Push адреса возврата в стек, прыжок |
| `ret` | Pop адреса из стека, прыжок |
| `push` | Push значения в стек |
| `pop` | Pop значения из стека |
| `inc` | Инкремент значения |
| `nop` | Нет операции |
### Специальные значения
- `$next` — следующий байт в памяти (используется для immediate значений)
- `arg.X` — ссылка на аргумент инструкции по имени
- `mem[N]` — прямая ссылка на память по адресу N
- `mem[arg.X]` — косвенная адресация через аргумент
### Условные переходы
```json
{
"op": "jcc_imm",
"condition": "zero,1",
"to": "$next"
}
```
Формат условия: `"имя_флага,ожидаемое_значение"`. Например `"zero,1"`, `"carry,0"`.
---
## 12. Написание программ на ассемблере
Ассемблер CBE поддерживает мнемоники, определённые в инструкциях CPU.
### Синтаксис
```asm
; комментарий
label: ; определение метки
MNEMONIC ; инструкция без аргументов
MNEMONIC arg1, arg2 ; инструкция с аргументами
.org 0x100 ; установка адреса
.byte 0xAB ; эмит байта
.db "hello", 0 ; эмит строки с нулевым терминатором
```
### Адресация
- Числа: `0x10` (hex), `10` (dec), `0b1010` (bin), `$10` (hex)
- Метки: `loop_start`, `loop_start+5`
- Символы: `'A'` (ASCII код)
### Пример
```asm
; Программа Hello World
.org 0x00
start:
MOV_IMM_A 0x48 ; 'H'
STORE_A 0xC0 ; вывод на GPU
MOV_IMM_A 0x65 ; 'e'
STORE_A 0xC0
MOV_IMM_A 0x6C ; 'l'
STORE_A 0xC0
MOV_IMM_A 0x6C ; 'l'
STORE_A 0xC0
MOV_IMM_A 0x6F ; 'o'
STORE_A 0xC0
HLT
```
### Сборка
```bash
# Собрать .asm в .bin с архитектурой TinyCPU
cbecc asm program.asm -o roms/boot.bin --arch examples/tiny-cpu.cpu
# Или собрать весь плагин (авто-детекция program.asm)
cbecc build my-cpu.cpu -o build/my-cpu.cbeplugin
```
---
## 13. Написание программ на C/C++
### Поддержка
Транслятор C → TinyCPU поддерживает:
- Объявление переменных: `int x = 5;`, `char c;`
- Присваивание: `x = expr;`
- Вывод на GPU: `write_gpu('A');`
- Вывод в порт: `outb(addr, value);`
- Циклы: `while`, `for` (ограниченно)
- Условные операторы: `if` (ограниченно)
- `return 0` → HLT
### Пример
```c
void write_gpu(char c) {
// Транслируется в MOV_IMM_A c; STORE_A 0xC0
}
int main() {
write_gpu('H');
write_gpu('e');
write_gpu('l');
write_gpu('l');
write_gpu('o');
write_gpu('\n');
return 0;
}
```
### Компиляция
```bash
# Для TinyCPU (встроенный транслятор)
cbecc ccompile program.c -o roms/boot.bin --arch tinycpu
# Для нативной архитектуры (x86_64 через gcc)
cbecc ccompile program.c -o program.bin --arch x86_64
# C++
cbecc ccompile program.cpp -o roms/boot.bin --arch tinycpu
```
### Для реальных архитектур
Для не-tinycpu архитектур `cbecc ccompile` использует:
1. `gcc` для компиляции в объектный файл
2. `ld` или `objcopy` для извлечения flat binary
Убедитесь, что установлены `gcc`, `binutils`.
---
## 14. Написание программ на Python
### Поддержка
Транслятор Python → TinyCPU поддерживает упрощённый синтаксис:
- Присваивание: `x = 5`
- Вывод: `print(x)` → GPU (0xC0)
- Циклы: `for i in range(n):`, `while condition:`
- Условные операторы: `if x == 5:`
- Комментарии: `# comment`
### Пример
```python
# Hello World для TinyCPU
print("Hello from Python!")
# Счётчик
count = 0
while count < 5:
print(count)
count = count + 1
```
### Трансляция
```bash
cbecc py program.py -o roms/boot.bin
# Или в составе сборки плагина (auto-detect)
cbecc build my-cpu.cpu -o build/my-cpu.cbeplugin
```
---
## 15. Hex-машинный код
Hex-загрузчик поддерживает форматы:
- Простые hex-байты: `02 48 0A C0 FF`
- C-стиль: `{0x02, 0x48, 0x0A, 0xC0, 0xFF}`
- Intel HEX (.hex): `:1000000002480AC0FF...`
- Один байт на строку
- Разделители: пробелы, запятые, новые строки
### Пример
```
; boot.bin в hex-формате
; MOV_IMM_A 'H' ; STORE_A 0xC0 ; HLT
02 48 0A C0 FF
```
### Конвертация
```bash
cbecc hex program.hex -o roms/boot.bin
```
---
## 16. Сборка плагинов (cbecc)
### Основные команды
```bash
# Сборка из source-директории (авто-детекция program.*)
cbecc build my-plugin.cpu -o build/my-plugin.cbeplugin
# Сборка с указанием бинарника программы
cbecc plugin my-plugin.cpu --program build/program.bin -o build/my-plugin.cbeplugin
# Сборка стандартная (без авто-детекции)
java -cp modules/cbecc/build/libs/cbecc-0.1.0.jar:modules/loader/build/libs/loader-0.1.0.jar:modules/core/build/libs/core-0.1.0.jar com.cbe.cbecc.Main build my-plugin.cpu -o build/my-plugin.cbeplugin
```
### Процесс сборки
1. Чтение `module.json`
2. Определение ModuleType
3. Парсинг метаданных
4. Если есть `program.asm/py/c/cpp/hex` — компиляция в `roms/boot.bin`
5. Построение секции метаданных (JSON)
6. Построение таблицы опкодов (JSON-массив из инструкций)
7. Построение таблицы микрокода (JSON)
8. Построение секции данных (банки + ROMs)
9. Вычисление CRC32
10. Запись .cbeplugin файла
---
## 17. Тулчейн: компиляция из разных языков
### Общая схема
```
program.asm ──→ Assembler ──→ boot.bin
program.c ──→ CCompiler ──→ boot.bin (gcc + objcopy или встроенный транслятор)
program.py ──→ PythonTranslator ──→ boot.bin
program.hex ──→ HexLoader ──→ boot.bin
module.json + registers.json + instructions/ + microcode/
Compiler (.cbeplugin)
my-plugin.cbeplugin ←── run.sh/gradle
```
### Авто-детекция
При запуске `cbecc build <dir>`, тулчейн проверяет файлы в порядке приоритета:
1. `program.asm` → Assembler
2. `program.py` → PythonTranslator
3. `program.c` → CCompiler
4. `program.cpp` → CCompiler
5. `program.hex` → HexLoader
Если ни один не найден, ищет `roms/boot.bin`.
---
## 18. Система POST-диагностики
POST (Power-On Self-Test) автоматически выполняется при первом шаге CPU.
### Коды POST
| Код | Описание |
|-----|---------------------------------------|
| 0x12| CPU не обнаружен |
| 0x61| Диск обнаружен |
| 0x73| CPU обнаружен |
| 0x74| RAM обнаружена |
| 0x75| GPU обнаружен |
| 0x76| KBD обнаружена |
| 0x77| SND обнаружена |
| 0x78| Все устройства проверены |
| 0x00| BOOT_OK — система готова |
| 0xFF| WARNING — не все компоненты найдены |
### LED индикаторы
- PWR — питание
- CPU — процессор
- MEM — память
- VID — видео
- KBD — клавиатура
- SND — звук
- DSK — диск
- CLK — тактовый генератор
Адреса memory-mapped I/O для POST:
- `0xFE` — POST code
- `0xFD` — Error code
- `0xFC` — LED status
---
## 19. Memory-mapped I/O
| Адрес | Размер | Назначение |
|-------|--------|-------------------------------------|
| 0xB0 | 1 | DISK_SECTOR_ADDR (LBA сектора) |
| 0xB1 | 1 | DISK_READY_ADDR (1 = готов) |
| 0xB2 | 512 | DISK_DATA_BASE (данные сектора) |
| 0xC0 | 1 | GPU_OUT_CHAR (вывод символа) |
| 0xD0 | 16 | DEVICE_TABLE_BASE (таблица устройств)|
| 0xE0 | 16 | BIOS_INFO_BASE (информация BIOS) |
| 0xF7 | 1 | BIOS_TRIGGER (перезапуск диагностики)|
| 0xF9 | 1 | SND_BEEP_ADDR (звуковой сигнал) |
| 0xFA | 1 | KBD_STATUS_ADDR (0 = нет, 1 = есть) |
| 0xFB | 1 | KBD_DATA_ADDR (код клавиши) |
| 0xFC | 1 | LED_STATUS_ADDR (LED индикаторы) |
| 0xFD | 1 | ERROR_CODE_ADDR (код ошибки) |
| 0xFE | 1 | POST_CODE_ADDR (POST код) |
---
## 20. Бесконечные шаги и детектор циклов
### Бесконечное выполнение
В CBE нет максимального лимита шагов. CPU выполняется:
- **В GUI:** пока не нажата кнопка Stop или CPU не выполнит HLT (0xFF)
- **В консоли:** пока CPU не выполнит HLT или процесс не будет прерван
### Детектор бесконечных циклов
В Engine встроен `LoopDetector`, который:
1. Записывает последние 64 значения PC
2. Анализирует повторяющиеся паттерны (длиной 1-8)
3. При обнаружении цикла выводит сообщение в консоль
4. **НЕ останавливает выполнение** — циклы не прерываются
Пример сообщения:
```
[LoopDetector] Infinite loop detected: jump pattern [0x14, 0x06] repeats indefinitely. Execution continues.
```
---
## 21. Тёмная тема GUI
Эмулятор CBE использует тёмную тему по умолчанию.
### Цветовая схема
| Элемент | Цвет |
|------------------|------------------------|
| Фон | #1E1E24 |
| Панели | #26262E |
| Границы | #32323C |
| Текст основной | #C8C8D2 |
| Текст яркий | #DCDCF0 |
| Акцент (синий) | #50A0FF |
| Зелёный (терминал)| #50DC78 |
| Оранжевый (7-seg) | #FF6414 |
### Компоненты
Все панели, текстовые поля, списки, скроллы, кнопки и рамки используют тёмную тему, настроенную через UIManager и явные цвета компонентов.
### Изменение темы
Для возврата к системной теме, закомментируйте `applyDarkUIManager()` в `EmulatorWindow.java` и раскомментируйте:
```java
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
```
---
## 22. Примеры
### Полный пример плагина
Структура:
```
examples/tiny-cpu.cpu/
├── module.json
├── registers.json
├── instructions/ (18 инструкций)
│ ├── 0x00.json NOP
│ ├── 0x01.json MOV_A_B
│ ├── 0x02.json MOV_IMM_A
│ ├── 0x03.json ADD
│ ├── 0x04.json SUB
│ ├── 0x05.json CMP_A_B
│ ├── 0x06.json JMP
│ ├── 0x07.json JC
│ ├── 0x08.json CMP_A_B (reuse)
│ ├── 0x09.json MOV_IMM_B
│ ├── 0x0A.json STORE_A
│ ├── 0x0B.json LOAD_A
│ ├── 0x0C.json JMP_IMM
│ ├── 0x0D.json JZ_IMM
│ ├── 0x0E.json RET
│ ├── 0x0F.json INC_A
│ ├── 0x10.json CALL
│ └── 0x11.json (stack ops)
├── microcode/
│ └── bus.json
└── roms/
└── boot.bin
```
### Запуск эмулятора
```bash
# Сборка + запуск с GUI
./run.sh
# Только сборка
./run.sh build
# Без GUI (консоль)
./run.sh nogui
# Прямой запуск с кастомными плагинами
java -cp modules/gui/build/libs/gui-0.1.0.jar:modules/loader/build/libs/loader-0.1.0.jar:modules/core/build/libs/core-0.1.0.jar com.cbe.gui.Main \
--cpu build/tiny-cpu.cbeplugin \
--ram build/basic-ram.cbeplugin \
--gpu build/vga-display.cbeplugin
# Собрать fat-jar
./run.sh jar
```
---
## 23. Устранение неполадок
### "Invalid magic: expected CBEPLUGIN"
Файл .cbeplugin повреждён или это не валидный плагин. Пересоберите:
```bash
./run.sh build
```
### "Missing module.json"
Убедитесь, что source-директория содержит `module.json`.
### "No CPU loaded"
Используйте флаг `--cpu`:
```bash
# По директории
--cpu examples/tiny-cpu.cpu
# По .cbeplugin
--cpu build/tiny-cpu.cbeplugin
```
### "Checksum mismatch"
Файл .cbeplugin повреждён. Пересоберите.
### "Unknown opcode: 0xNN"
Инструкция с данным опкодом не определена в вашем CPU. Проверьте `instructions/`.
### GPU не отображает ничего
1. Убедитесь, что GPU загружен (`--gpu examples/vga-display.gpu`)
2. CPU должен писать в порт `0xC0`
3. Проверьте, что boot ROM содержит валидный код
4. После HLT (0xFF) CPU останавливается — новые символы не выводятся
### Клавиатура не реагирует
1. Убедитесь, что KBD модуль загружен
2. CPU должен читать статус (`0xFA`) и данные (`0xFB`)
3. После чтения данных CPU должен записать `0` в статус (`0xFA`) для acknowledge
---
## 24. Справочник команд
### cbecc
```bash
# Сборка плагина из директории
cbecc build <source-dir> -o <output.cbeplugin>
# Ассемблирование .asm → .bin
cbecc asm <input.asm> -o <output.bin> --arch <cpu-dir>
# Конвертация hex → .bin
cbecc hex <input.hex> -o <output.bin>
# Компиляция C/C++ → .bin
cbecc ccompile <input.c> -o <output.bin> --arch <arch>
# Трансляция Python → .bin
cbecc py <input.py> -o <output.bin>
# Сборка плагина с готовой программой
cbecc plugin <source-dir> --program <binary> -o <output.cbeplugin>
```
### cbe-emu
```bash
# Запуск с GUI
./run.sh
# Запуск без GUI
./run.sh nogui
# Прямой запуск Java
java -cp <classpath> com.cbe.gui.Main \
--cpu <path> --ram <path> --gpu <path> \
[--kbd <path>] [--snd <path>] [--bios <path>] [--disk <path>] \
[--program <text>] [--nogui]
# Параметры RAM
--ram <path> --ram-base <addr> --ram-size <bytes>
```
### Gradle
```bash
# Полная сборка всех модулей
./gradlew build
# Сборка fat-jar
./gradlew :modules:gui:stage
# Сборка native-образа (jpackage)
./gradlew :modules:gui:packageImage
# Сборка Windows portable
./gradlew :modules:gui:portableWindowsZip
```
### run.sh
```bash
./run.sh build # пересобрать все jar
./run.sh compile # скомпилировать example-плагины
./run.sh nogui # запуск без GUI
./run.sh disk # загрузка с диска (nogui)
./run.sh # запуск с GUI
./run.sh jar # fat-jar
./run.sh image # native-образ
./run.sh windows # Windows portable
```