The Esoteric CPU
In contrast to the well-known «Intel» processors, whose brand name is quite easy to remember and pronounce, Koyaanisqatsi was conceived as a processor whose name is more difficult to pronounce than to understand its architecture and learn how to program it at the most elementary level of machine code by dump editors to check Is it really worth bending under the amateur radio-technical specifications and it is impossible to form a beautiful command system, understandable at the level of intuition? It doesn’t mean the code in style like "O'Key, calculate me the factorial average", but I planned a machine code with a minimum level of getting into the basics of the art of programming it, which does not require hard cramming and memorizing all the commands.
В противоположность известных всем процессоров «Intel», марку которых довольно легко запоминать и выговоривать, «Койяанискаци» задумывался как процессор, имя которого сложнее произнести, чем разобраться в его архитектуре и научиться его программировать на самом элементарном уровне машинного кода редакторами дампа, чтобы проверить, действительно ли стоит прогибаться под радиолюбительские ТУ и невозможно сфомироваться красивую систему команд, понятную на уровне интуиции? Не имеется ввиду код стиля «O'Kей, процик, вычисли мне среднее факториальное», а планировался машинный код с минимальным уровнем вхождения в основы искусства его программирования, не требующего жёсткой зубрёжки и заучивания всех команд.
Система команд процессорного устройства разрабатывалась максимально прозрачной для понимания на уровне машинного кода в своём шестнадцатеричном представлении как есть визуальным сочетанием своих нибблов в форме элементарных аббревиатур. Кодирование алгоритма малой степени сложности доступно пользователю с базовыми навыками редактирования таблиц дампа и не представляет особой сложности в силу максимально осмысленного кодирования всех инструкций в шестнадцатеричном виде.
(В противоположность Befunge, BrainF*ck, WhiteSpace и прочему озорству!)
Весь процессор основан на регистровом файле из четырёх функциональных групп по десять ячеек в каждой. Хотя операции АЛУ возможны над любыми ячейками, правила корректного оперирования с ними соблюдать необходимо более-менее строго. Здесь стоит просто запомнить логику и назначение этих функциональных групп:
- A₀…₉: Accumulators/Аккумуляторная группа (A₀ - ALU-status: хранит флажки статуса АЛУ)
- B₀…₉: Base/База доступа к памяти (B₀ - return Base: хранит Базу возврата из подпрограммы)
- C₀…₉: Counter/Счётчик (C₀ - return Code: хранит Смещение возврата из подпрограммы на код вызова)
- D₀…₉: Device/Устройство (Devices/Cache: Можно организовать кеш)
Так как процессор достаточно прост и не имеет встроенных аппаратных механизмов организации стековых операций, регистры B₀:C₀ сохраняют адрес, на котором была размещена операция обращения к подпрограмме. Программист при необходимости сам обязан позаботиться о всех операциях работы со стеком и описать их алгоритмом. Для облегчения разработки алгоритма, следует использовать небольшую библиотеку кратких подфункций, выполняющих необходимые операции ветвления и вызова всяких пользовательских подпрограмм, реализующие механизмы стека программным уровнем. При доступе к внешней памяти нужная ячейка адресуется парой активных регистров Bi и Cj, где Bi указывает на Базу Блока по 256 ячеек и Cj указывает в блоке на конкретную ячейку. Медленная память может удлинить цикл доступа сигналом Wait. Регистры D₀…₉ не следует использовать в активных вычислительных процессах, так как они управляют периферией непосредственного доступа с мгновенным откликом и пригодны для организации процессорного кеша и контекстного регистрового файла.
Практически все команды кодируются WYSIWYG стилем акына:«Что вижу, то значит». Шестнадцатеричная кодировка отчасти является аббревиатурой самой команды и всё задумывалось так, чтобы большинство команд просто совершали понятные действия.
- 00: HLT (останов программы) - крайне логичный и гармоничный код!
- 20…90: Префикс повтора операции от 2 до 9 раз или пропуск группы операций по условию
- 11…99: Используется BCD-код приращения к активному регистру-приёмнику - код 56 означает именно 56₁₀, а не 0x56₁₆
- A0…A9, B0…B9, C0…C9: Безвременные префиксы выбора активного регистра указанной группы - A₀…A₉, B₀…B₉, C₀…C₉ соответственно
- D0…D9: Выбор активного устройства группы Devices - D₀…D₉
- AA…AD, BA…BD, CA…CD, DA…DD: Безвременные префиксы выбора сочетания операндов для АЛУ-операций - A,A…D,D соответственно
- E0: Завершение текущей функции (Execution Over - как Game Over)
- E1…E7: Обращение к расширению (Extension) через подпрограмму - CALL 0xE100…0xE700
- F0…F9: Обращение к функции (Function) с указанным индексом - CALL 0xF000…0xF900
- E8…EF: Условный префикс к исполнению кода следующей операции - Enable if SF/PF/CF/ZF
- AE/BE/CE/DE: Извлечение (Extract) данных из памяти в указанный регистр - MOV Ri,[Bm:Cn]
- AF/BF/CF/DF: Запись/фиксация (Fix) данных указанного регистра в память - MOV [Bm:Cn]:Ri
- FA…FF: Вызов прочих функций - CALL 0xFA00…0xFF00
- 0A/1A/2A…9A: АЛУ-операция "Сумма" (Add) над группой операндов - индекс правого операнда указывается явно 0…9
- 0B/1B/2B…9B: АЛУ-операция "Вычитание" (suB) над группой операндов - индекс правого операнда указывается явно 0…9
- 0C/1C/2C…9C: АЛУ-операция "Конъюнкция" (Conjunct/and) над группой операндов - индекс правого операнда указывается явно 0…9
- 0D/1D/2D…9D: АЛУ-операция "Дизъюнкция" (Disjunct/or) над группой операндов - индекс правого операнда указывается явно 0…9
- 0E/1E/2E…9E: АЛУ-операция "Исключающее ИЛИ" (Exclusive or/Eor/xor) над группой операндов - индекс правого операнда указывается явно 0…9
- 0F/1F/2F 9F: операция межрегистровой пересылки MOV Ri,T₀…₉ - индекс регистра-источника указывается явно 0…9
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| …0 | …1 | …2 | …3 | …4 | …5 | …6 | …7 | …8 | …9 | …A | …B | …C | …D | …E | …F |
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 0…| HLT | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |Ri,T₀|Ri,T₀|Ri,T₀|Ri,T₀|Ri,T₀|Ri,T₀|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 1…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 1() | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |Ri,T₁|Ri,T₁|Ri,T₁|Ri,T₁|Ri,T₁|Ri,T₁|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 2…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 2() | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |Ri,T₂|Ri,T₂|Ri,T₂|Ri,T₂|Ri,T₂|Ri,T₂|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 3…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 3() | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |Ri,T₃|Ri,T₃|Ri,T₃|Ri,T₃|Ri,T₃|Ri,T₃|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 4…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 4() | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |Ri,T₄|Ri,T₄|Ri,T₄|Ri,T₄|Ri,T₄|Ri,T₄|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 5…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 5() | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |Ri,T₅|Ri,T₅|Ri,T₅|Ri,T₅|Ri,T₅|Ri,T₅|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 6…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 6() | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |Ri,T₆|Ri,T₆|Ri,T₆|Ri,T₆|Ri,T₆|Ri,T₆|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 7…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 7() | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |Ri,T₇|Ri,T₇|Ri,T₇|Ri,T₇|Ri,T₇|Ri,T₇|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 8…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 8() | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |Ri,T₈|Ri,T₈|Ri,T₈|Ri,T₈|Ri,T₈|Ri,T₈|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 9…| REP | | | | | | | | | | ADD | SUB | AND | OR | EOR | MOV |
| | 9() | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |Ri,T₉|Ri,T₉|Ri,T₉|Ri,T₉|Ri,T₉|Ri,T₉|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| A…| | | | | | | | | | | | | | | EXT | EXT |
| | A₀ | A₁ | A₂ | A₃ | A₄ | A₅ | A₆ | A₇ | A₈ | A₉ |Ai,Ai|Ai,Bj|Ai,Cj|Ai,Dj| Ai | Ai |
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| B…| | | | | | | | | | | | | | | EXT | EXT |
| | B₀ | B₁ | B₂ | B₃ | B₄ | B₅ | B₆ | B₇ | B₈ | B₉ |Bi,Aj|Bi,Bi|Bi,Cj|Bi,Dj| Bi | Bi |
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| C…| | | | | | | | | | | | | | | EXT | FIX |
| | C₀ | C₁ | C₂ | C₃ | C₄ | C₅ | C₆ | C₇ | C₈ | C₉ |Ci,Aj|Ci,Bj|Ci,Ci|Ci,Dj| Ci | Ci |
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| D…| | | | | | | | | | | | | | | EXT | FIX |
| | D₀ | D₁ | D₂ | D₃ | D₄ | D₅ | D₆ | D₇ | D₈ | D₉ |Di,Aj|Di,Bj|Di,Cj|Di,Di| Di | Di |
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| E…| E0/ |CALL |CALL |CALL |CALL |CALL |CALL |CALL | EPO | EPE | ES | ENS | EC | ENC | EZ | ENZ |
| | RET | E1₀0| E2₀0| E3₀0| E4₀0| E5₀0| E6₀0| E7₀0| | | | | | | | |
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| F…|CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |CALL |
| | F0₀0| F1₀0| F2₀0| F3₀0| F4₀0| F5₀0| F6₀0| F7₀0| F8₀0| F9₀0| FA₀0| FB₀0| FC₀0| FD₀0| FE₀0| FF₀0|
+---+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
Однако, тут не стоит думать, что «процессор акына» совсем ничего не требует от продвинутого пользователя-программиста: Минимальный порог вхождения преодолеть всё-таки придётся… А значит, придётся чуточку поднапрячься и преодолеть порог! (Здесь подразумевается, что читатель уже имеет все базовые понятия и принципы, позволяющие ориентироваться в синтаксической конструкции и строить выражения…)
Сложение величин из регистров A₁ и B₂ традиционно можно представить выражением «A1 += B2» или мнемонической записью «ADD A1,B2», которую и следует оформить в машинный код. Так как архитектура процессора предельно проста и организовалась на польской записи, буквально необходимо сначала предопределить используемые в операции операнды, чтобы потом произвести саму конкретную операцию вычисления. Так как используется сочетание регистров «A1» и «B2» в порядке «An,Bn», то под их определение следует указать машинный код AB₁₆. Выбор индексов на конкретных операндах выполняется кодами A1₁₆ и B2₁₆, что указывает на буквальность кодов. Так как индекс правого операнда равен двум, то в коде АЛУ-операции «Сумма» его следует указать явно в левой тетраде как 2A₁₆. Тем самым, становится очевидным размещения кода всего выражения как «A1 AB B2 2A». Но так как индекс B₂ указан явно в АЛУ-операции, байт команды «B2» можно исключить из цепочки, так как сам регистр B₂ не является приёмником результата и код сократится до одной из двух комбинаций записи «A1 AB 2A» или «AB A1 2B», так как от расположения префиксов перед операциями результат не изменяется и всё зависит от стиля программиста. Выражение «A1 = A1 + B2 - B3 & B4 | B5 ^ B6» можно описать последовательностью «A1 AB 2A 3B 4C 5D 6E», так как в каждом следующем коде операции явно указан и индекс правого операнда, что позволяет писать код компактно и производительно.
0000 A1 |----vv ;A1 выбирает регистр A₁
0001 AB |------v ;AB задаёт порядок: Ai - слева (приёмник), Bn - справа (источник)
0002 2A |ADD A1,B2 ;2A: Правая тетрада - Add, левая тетрада - индекс источника
0003 3B |SUB A1,B3 ;3B: Правая тетрада - suB, левая тетрада - индекс источника
0004 4C |AND A1,B4 ;4C: Правая тетрада - and, левая тетрада - индекс источника
0005 5D |OR A1,B5 ;5D: Правая тетрада - or, левая тетрада - индекс источника
0006 6E |EOR A1,B6 ;6E: Правая тетрада - Eor, левая тетрада - индекс источника
^-----------^
0007 30 |REP 3 ;Префикс репетиции 3 раза
0008 7A |ADD A1,B7 ;7A: Правая тетрада - Add, левая тетрада - индекс источника
0008 7A |ADD A1,B7 ;Из-за префикса перед операцией, процессор застрянет по
0008 7A |ADD A1,B7 ;этому адресу ровно на 3 такта
===========|===========
0007 30 7A |ADD A1,B7*3;Более краткая ассемблерная форма
0007 30 7A |ADD'3 A1,B7;Другое представление ассемблером
0009 EC |EC ;Аббревиатура "Enable by Carry" - разрешить операцию по переносу
000A 8A |ADD A1,B8 ;Код команды будет пропущен, если нет переноса
===========|===========
0009 EC 8A |ADD'C A1,B8;Краткая форма, типа "IF CARRY THEN ADD A1,B8"
000B 30 |REP 3 ;Префикс репетиции 3 раза
000C EC |EC ;Аббревиатура "Enable by Carry" - разрешить операции по переносу
000D 3B |SUB A1,B3 ;Код команды будет пропущен, если переноса не было
000E 4B |SUB A1,B4 ;Код команды будет пропущен, если переноса не было
000F 5B |SUB A1,B5 ;Операция будет исполнена в любом случае, так как она - третья в блоке
===========|===========
000B 30EC3B|SUB'C A1,B3;Апостроф привязывает команду к условию по состоянию флажков
000E 4B|SUB'' A1,B4;Здесь двойной апостроф указывает на принадлежность к группе
000F 5B |SUB A1,B5;Инструкция вне условной группы
Так как Logisim куда доступнее и проще того же Proteus и компактнее KiCAD, вся схема процессора разрабатывалась в рамках проекта именно Logisim, чтобы проект был по-детски прост и лёгок для использовании заинтересованными любителями. По предварительным подсчётам, если схему проекта попытаться собирать микросхемами серии 74xx или отечественной номенклатуры, понадобится порядка 250 корпусов... Если смущает использование ПЗУ для дешифрации команд, имеется набросок схемы с использованием уровня комбинаторики, по которой можно осознать, что и красивую систему команд можно декодировать простейшим способом логических вентилей, без ущерба концептуальной задумки!
HABR…