Каллисто-2: разработка быстродействующего Форта для МК-161

Каллисто-2 будет написана на SP-Forth! Подробнее см. соответствующую тему В Контакте.

Кусочек исходного кода — чтобы было понятно, как это сейчас выглядит:

0xD0 COP КИП0  0xD1 COP КИП1    0xD2 COP КИП2    0xD3 COP КИП3   0xD4 COP КИП4  0xD5 COP КИП5  0xD6 COP КИП6  0xD7 COP КИП7
0xD8 COP КИП8  0xD9 COP КИП9    0xDA COP КИПА    0xDB COP КИПВ   0xDC COP КИПС  0xDD COP КИПД  0xDE COP КИПЕ  0xDF 2OP РКИП
0xE0 COP Кx=00 0xE1 COP Кx=01   0xE2 COP Кx=02   0xE3 COP Кx=03  0xE4 COP Кx=04 0xE5 COP Кx=05 0xE6 COP Кx=06 0xE7 COP Кx=07
0xE8 COP Кx=08 0xE9 COP Кx=09   0xEA COP Кx=0А   0xEB COP Кx=0В  0xEC COP Кx=0С 0xED COP Кx=0Д 0xEE COP Кx=0Е 0xEF 2OP РКx=0

0xF2 COP РРВ/О
0xF4 3OP РРП
0xF6 3OP РРИП

\ -------------------------
\ Исходный код Каллисто-2

\ Инициализация
Cx
9 5 0 0 РРП 9042    \ Адрес таблицы свёрток
1 0 9 9 П6          \ RI := Начало шитого кода - 1
1 6 П9              \ Занесём в R9 адрес NEXT

A: NEXT
КИП6 ВП 2 КИП6 + П7 \ W := REGW[RI++], считываем CFA в R7
КИП7 РРП 9210       \ Находим по CFA адрес обработчика
П8 КБП8             \ Передаём на него управление

ORG 100             \ Обработчик 000
2 РРП 9010          \ Инициализация графического экрана
1 2 8               \ Код буквы "А"
РРП 9020            \ Вывод символа на графический экран
КГРФ                \ Обновляем индикатор
КБП9                \ NEXT

ORG 200             \ Обработчик 001
РРИП 9029           \ Чтение кода нажатой клавиши
КNOT                \ Проверка на 255
Fx≠0 00             \ Дождёмся чего-нибудь, отличного от 255
КБП9                \ NEXT

Полностью исходный код + результат качать отсюда: http://the-hacker.ru/2016/Callisto2-d4.zip

Черновик 4 выводит на экран букву, ждёт нажатия клавиши и выходит по С/П. Работает NEXT (адресный интерпретатор), но пока нет ни меток, ни имён слов. Использование SP Forth позволяет не только избежать ручной компиляции кода МК-161, но также автоматизировать множество вещей, которые в Каллисто Классик, написанной на MK.EXE, приходилось делать вручную.

Каллисто-2, черновик 5: http://the-hacker.ru/2016/Callisto2-d5.zip

Теперь шитый код генерируется SP-Forth, в полном соответствии с требованиями нового адресного интерпретатора. «Ассемблер» ЯМК вынесен в отдельный список слов. Определения примитивов выглядят весьма красиво:

code w1               \ === Обработчик 000 ===
  2 РРП 9010          \ Инициализация графического экрана
  1 2 9               \ Код буквы "Б"
  РРП 9020            \ Вывод символа на графический экран
  КГРФ                \ Обновляем индикатор
  КБП9                \ NEXT
end-code

Каллисто-2, черновик 6: http://the-hacker.ru/2016/Callisto-d6.zip

Заработали определения высокого уровня, то есть стек возвратов и CALL/EXIT. Производительность не мерил, но должно работать ощутимо быстрей Каллисто Классик.

Также добавлены циклы begin/until и begin/again для примитивов — слов на языке МК-161. Этот типично фортовский приём позволяет обходиться без меток в БП и условных переходах назад.

Каллисто-2, черновик 7: http://the-hacker.ru/2016/Callisto2-d7.zip

Начал писать терминал. Теперь после запуска Каллисто-2 выводит на индикатор нажимаемые клавиши. Раскладка примерно соответствует цифровой клавиатуре Каллисто Классик и пока не переключается в русский и латинский режимы.

На этот раз я не спешу и делаю всё, как надо. Ввод реализован с помощью прерываний. Вводимые литеры ставятся в очередь длиной 8 литер. Реализован автоповтор, впервые на «Электронике МК-161».

В метаязыке произошёл переход от 2 РРП 9010 к каллистянскому 2 9010 РРП — есть и другие изменения, которые позволят написать такую крупную программу, как транслятор Каллисто-2.

Каллисто-2, черновик 8: http://the-hacker.ru/2017/Callisto2-d8.zip

Внешне изменений нет — Каллисто-2 отображает нажатые клавиши, как и раньше. Внутри существенные изменения. Например, появился стек данных. Вершина стека теперь всегда хранится в регистре C.

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

Ассемблер языка МК теперь поддерживает все коды операций МК-161. Он ещё не умеет ссылаться на метки вперёд, но уже позволил реализовать десятки примитивов Каллисто, включая арифметические операции и операции со стеком. Практически каждое определение удалось записать в одну строчку. Вот некоторые из тех определений, где регистр С дал выигрыш и по размеру кода, и по скорости:

code dup ИПС КП3 КБП9 end-code
code 1+ 1 ИПС + ПС КБП9 end-code
code 2+ 2 ИПС + ПС КБП9 end-code
code 10ˣ ИПС F10ˣ ПС КБП9 end-code
code eˣ ИПС Feˣ ПС КБП9 end-code
code lg ИПС Flg ПС КБП9 end-code
code ln ИПС Fln ПС КБП9 end-code
code x² ИПС Fx² ПС КБП9 end-code
code √ ИПС F√ ПС КБП9 end-code

Команды ИП П БП ПП и несколько других стали «умными». Зная, к какому регистру или шагу происходит обращение, они сами выбирают нужный код операции — либо двухшаговой/внутристраничной, либо трёхшаговой/межстраничной команды.

Например РРИП 9000 теперь записывается в ассемблере, как 9000 ИП — ровно также, как в Каллисто. Переходы также стали использовать обратную польскую нотацию. Сперва пишем, куда. Потом пишем БП или Fx=0

При компиляции Каллисто-2 SP Forth выдаёт предупреждения о переопределении ряда слов. Это нормально. В конце-концов, мы и заняты определением слов Каллисто на Форте. Арифметические и другие операции получают новое определение.

Конечно, работы предстоит ещё очень много. Клавиатура и терминальный вывод станут куда умней. Устройство словаря Каллисто-2 пока очень примитивно, многим задумкам реализация только предстоит. Нет стековых диаграмм и другого само-документирования, хотя многое и повторяет Каллисто Классик.

Каллисто-2, черновик 9:
http://the-hacker.ru/2017/Callisto2-d9.zip

Как я уже писал в Контакте, верхние два элемента стека данных Каллисто теперь совпадают с регистрами стека X и Y. Поэтому многие примитивы упрощаются до предела, например:

code 1+ 1 + next; 
code 2+ 2 + next; 
code + + jdrop2 БП; 
code - - jdrop2 БП; 
code × × jdrop2 БП; 
code ÷ ÷ jdrop2 БП; 
code / ÷ К[x] jdrop2 БП;
code min Кmax ↔ jdrop2 БП; 
code max Кmax jdrop2 БП; 
code 10ˣ F10ˣ next; 
code eˣ Feˣ next; 
code lg Flg next; 
code ln Fln next; 
code x² Fx² next; 
code √ F√ next; 
code 1/x F1/x next; 

Также Каллисто-2 теперь состоит из трёх файлов (mkp, mkb и mkd) — все три надо передать в МК-161 или эмулятор, чтобы проверить работоспособность. В файле десятичных данных пока передаются лишь два десятичных регистра (R9 и R16), но это только начало. Больше размер исполняемого кода увеличиваться не будет, ибо уже некуда. Но с тремя файлами придётся смириться. Лучше их сохранять на внутренний диск под одним именем. Тогда они образуют «пакет» и загружать транслятор становится проще и быстрее.

Каллисто-2 (черновик 9) сперва выводит на экран приглашение, символ "@", после чего отображает по символу на каждую нажатую клавишу.

Брать здесь:
http://the-hacker.ru/2017/Callisto2-d10.zip

Клавиатура становится серьёзней — в Каллисто-2 заработал цифровой режим. Теперь кнопка "3" даёт литеру "3", а последовательное нажатие кнопок "F 3" даёт литеру "#". Разумеется, это совместимо с автоповтором и очередью клавиатуры, важными нововведениями Каллисто-2. Нажав кнопку "F" и удерживая кнопку "3", мы получим автоповтор литеры "#".

Раскладка практически повторяет Каллисто Классик. Небольшие отличия вызваны лучшей продуманностью второй реализации алфавитно-цифровой клавиатуры для «Электроники МК-161». Например, "П" даёт "!", а "F П" даёт "?" — это освободило кнопку "К" для будущих применений.

Литера "|" теперь вводится "F В↑", а литера "↵" переехала на "F ВВОД". Клавиши выбора сейчас дают свои «старшие» коды, а «младшие» коды получаются при использовании префикса "F".

Пока в качестве префиксной клавиши "F" можно использовать любую другую спецкнопку — РУС/ЛАТ и т.п. Но это ненадолго, алфавитные режимы на подходе. Тестовое приложение осталось нетронутым. Хотя драйвер клавиатуры выдаёт правильные коды "Cx" и "F Cx", для редактирования строки их пока никто не использует.

Напомню, что для запуска Каллисто-2 в «Электронику» надо передать три файла — mkp, mkb и mkd.

Каллисто-2, черновик 11: http://the-hacker.ru/2017/Callisto2-d11.zip

Тестовая программа теперь выводит приглашение ">", в остальном без изменений. Зато драйвер клавиатуры завершён. В-основном он повторяет клавиатуру Каллисто Классик, но удалось воплотить две мои древние задумки. В цифровом режиме клавиша "K" работает, как Control — например "K S" вводит ^S, управляющий символ с кодом 19 и графическим изображением «знак паузы».

Также в цифровом режиме комбинация префиксных клавиш "F K" позволяет ввести любой символ по его шестнадцатеричному коду. Например, "F K 1 3" это ещё один способ ввести тот же самый «знак паузы». Клавиши выбора (и они же с клавишей "F") в цифровом и латинском режимах дают одинаковые служебные коды. Это позволит использовать их, например, для перемещения курсора.

Чтобы реализовать всё это богатство, в ассемблере МК-161 введены метки с возможностью ссылок вперёд. Подробней я объяснял эту тему в Контакте. Над метками я ещё немного поработаю напильником, но они уже вполне работоспособны.