Конечнo, Спасибо за советы…
В самом начале темы я пост поправил. Вы запускали пример в нём?
Имеется конкретный
эмулятор (нажмите кнопку V между Console и Full Screen, чтобы увидеть таблицу команд), который расписан
классически, как можете убедиться, без выкрутасов (древом switch(код_команды) case код_nn: ействие_nn…).
Когда переписывался с его автором и пытался чуточку подогнать его под свои фантазии, приходилось модифицировать и древо ассемблера, и древо дизассемблера, и саму визуальную таблицу, и ядро эмуляции. Что крайне сложно для отладки.
Тогда появилась мысль, разработать некий автоматический конструктор для эмуляции. Из справочника по конкретному процессору переводишь таблицу в некоторый шаблон, а библиотека сама его "переварит" и всё сделает без особого напряга со стороны пользователя. Если что-то не так работает, правится только шаблон…
В детстве изучил кучу советской справочной литературы отца на темы ПЛ/1, ПЛ/М, Ада, Фортран, Лисп, Пролог, Паскаль, Форт, Си, АПЛ и т.д. Т.е. когда сел за
более-менее приветливый терминал, имел некоторые представления о том, как заставить машину делать что-то именно моё уникальное. Ассемблер был роскошью и команды писал
прямо дампом.
Сейчас задуманное работает. До 512 срабатываний таймера в секунду с обработкой до 2048 инструкций (512*2048=до миллиона команд в секунду). И всё держится на eval, а разумно бы в new Function завернуть. В функцию нельзя передавать аргументы. Вернее, можно, но их будет с несколько десятков, что расходно и бессмысленно.
Тем более, на выходе - ничего нет. Процесс игнорирует результат eval и не принимает значения от function-return. Т.е. оперирование идёт со всеми окружающими структурами и массивами. Понимаете?
P.S.: Когда впервые пересел с IBM-PC/XT - DOS 3.11 за Pentium-I под Windows'98, через год изучения Visual Basic 4 написал свой первый эмулятор с кучей if-then-else/switch-case и т.д.
Теперь хочу автоматизировать всё это дело…
P.P.S.: Несколько слов о принципах шаблона и его "разворачивания"…
Аналогично оператору
casex в шаблоне перечисляются все возможные комбинации битов кода для каждой операции:
Код:
|
1X0X - Бинарная маска шаблона: Здесь X указывает на биты с произвольным линейным содержимым
==== - Разворачивается в 2²=4 (двойка в степени количества X в строке) комбинации:
1000 - Базовая комбинация
1001 - Первая комбинация
1100 - Вторая комбинация
1101 - Третья комбинация |
В шаблоне указываются также битовые поля операционных констант, закреплённых за конкретным кодом:
Код:
|
?XYX? - Здесь за X берутся биты 3 и 1 соответственно. Только за Y берётся бит 2,
Y???? - Затем и бит 4 - в обратном порядке. Знак вопроса в конце (?) обязателен
----- - Все перечисленные имена констант далее действуют в целом шаблоне
XXXX - Всё это дело разворачивается в
==== - следующую таблицу бинарной маски:
0000 - $X = 00, $Y = 00
0001 - $X = 01, $Y = 00
0010 - $X = 00, $Y = 10
0011 - $X = 01, $Y = 10
0100 - $X = 10, $Y = 00
0101 - $X = 11, $Y = 00
0110 - $X = 10, $Y = 10
0111 - $X = 11, $Y = 10
1000 - $X = 00, $Y = 01
1001 - $X = 01, $Y = 01
1010 - $X = 00, $Y = 11
1011 - $X = 01, $Y = 11
1100 - $X = 10, $Y = 01
1101 - $X = 11, $Y = 01
1110 - $X = 10, $Y = 11
1111 - $X = 11, $Y = 11 |
Тем самым, в строке конкретной операции все операционные константы при разборе шаблона подменяются на конкретные значения:
Код:
|
0XX1 DO R$Y+=R$X
==== - Данная выше строчка развернётся в 4:
0001 DO R0+=R1
0011 DO R2+=R1
0101 DO R0+=R3
0111 DO R2+=R3 |
Что значительно облегчает описание всех возможных комбинаций конкретного набора однотипных инструкций.
В шаблоне также можно описать псевдонимы для операций и регистров, закрепив за ними конкретные действия:
Код:
|
R0 Door Open_Door
R1 Desk Wash_Desk
R2 Cat Make_Purr
R3 Dog Keep_Home |
Тем самым, представленный выше шаблон совсем изменится в развёртке:
Код:
|
0XX1 DO R$Y+=R$X :R$Y(R$X)
==== - Данная выше строчка развернётся в 4:
0001 DO Door+=Desk :Open_Door(Wash_Desk)
0011 DO Cat+=Desk :Make_Purr(Wash_Desk)
0101 DO Door+=Dog :Open_Door(Keep_Home)
0111 DO Cat+=Dog :Make_Purr(Keep_Home) |
Чем достигается описывание довольно сложных алгоритмических выражений с шаблонной подстановкой конкретных комбинаций за конкретными кодами.
Разрабатываемая маленькая библиотека делает всё сама. При этом, когда Вы опишете шаблон абсолютно корректно, на выходе получите полноценный функциональный инструмент:
- Эмулятор: Берёт последовательно коды команд из таблицы и вызывает их как конкретные функции
- Дизассемблер: Читает коды операций и преобразует их в колонку символьного представления
- Ассемблер: Читает Ваш текст программы символьных команд и преобразует их в совокупность бинарных кодов тех команд
Так, например, мы напишем следующие строчки:
Код:
|
DO Door+=Dog
DO Cat+=Desk
DO Cat+=Dog |
В таблицу памяти он упакуется кодами 0101, 0011, 0111.
Запустив данную "программу" мы заставим цикл эмуляции выполнить следующую последовательность операций:
Open_Door(Keep_Home); Make_Purr(Wash_Desk); Make_Purr(Keep_Home);