Сообщение от
alone
Трезвой форт-машины для Z80 не знаю. Покажите процедуру NEXT.
Есть одна идея, как можно реализовать наиболее быстрый вариант виртуальной машины на Z80 — может и не по всем пунктам, обозначенным топикстартером, но вариант интересный. Судите сами.
Это аналог Форт-машины с прямым шитым кодом. Подпрограммный шитый код мы не рассматриваем, потому что это фактически подмножество машинного кода, просто организованный массив подпрограмм со своей логикой.
1. Код плотнее, чем на Z80.
Отчасти, да. Интересные вещи писали авторы отечественных Форт-систем о компактности фортовского шитого кода, который превосходил реализации с машинным кодом.
2. Перемещаемость (помогло бы для ОС с одним окном памяти, где код лежит внизу).
Нет, потому что код шитый. Или разве что да, но будет требоваться простая настройка адресов, что не должно вызвать проблем.
3. Реентерабельность (опять-таки для ОС).
Вероятно, это можно реализовать.
4. Возможность использования ассемблерных вставок с ограничениями.
Безусловно.
Прямой шитый код Форт-машины — это последовательность адресов вызываемых подпрограмм на Форте или в машинном коде. Для Z80 может выглядеть примерно так:
Код:
DW LITERAL_BYTE ; Заносим на стек
DB 5 ; число 5
DW DUP ; Дублируем значение на стеке
DW MULT ; Умножаем само на себя (возводим в квадрат)
DW EMIT ; Печать числа
Вероятно, большой проблемой будет слово NEXT, от которого сильно зависит скорость работы всей машины. (NEXT передаёт управление следующему за текущим словом. Вероятно, имеет смысл модифицировать шитый код для большей производительности слова NEXT, если это вообще возможно. Моё предложение имеет один минус, который многим покажется критичным. Тем не менее, всё-таки посмотрите, что предлагается.
Код:
DI
LD SP, ExecThread
RET
DW EMIT ; Адреса слов потока исполнения, но в обратном порядке
DW MULT
DW DUP
DB 5
DW LITERAL_BYTE
ExecThread: ; Сюда устанавливается верхушка стека
В такой реализации словом NEXT в шитом коде будет адрес, указывающий на RET (и обычный RET в машинных подпрограммах). Не все проблемы решены. Остаются трудности с вложенными вызовами шитого кода из шитого кода (или из машинной подпрограммы) — нужно куда-то сохранить адреса возврата. Значит нужен стек, притом не SP, ибо он активно занят другими делами. Если вложенность гарантированно будет одинарная (ну, такой гипотетический случай), должно хватить одного регистра под это. Например, IY.
Теперь о самом главном минусе. Это конечно запрещённые прерывания. Не вижу способа их разрешить. Полумерой предлагаю лёгкую подпрограмму, которую можно будет вручную вызывать время от времени из своих подпрограмм.
Плюсы решения: при запрещённых прерываниях не нужно на них отвлекаться процу — код будет работать быстрее. Второй плюс — такая машина может быть регистровой, а не стековой, как Форт. И параметры будут передаваться в регистрах.
Практическое применение этой идее наверно найти трудно, но вдруг у кого-то появится мысль как её усовершенствовать.
P.S. На законченность концепции не претендую — так, сырая идея.