Итак, я продолжаю начатую тему.

Во первых, оставлю заглушки для ALU так как есть. Их можно достаточно легко наполнять операциями по мере необходимости.
Во вторых, определимся, какие операции нужны в первую очередь и какие будут появляться в программах чаще всего.

Первая необходимая команда - загрузка литерала - LIT  - для ее выполнения нужно сделать следующее:

[code]PC[] = PC[] + 1; PC[].ena = VCC;
TR[] = DI[]; TR[].ena = VCC;
DStack.di[] = TR[];
DStack.cmd[] = push;[/code]

Замечу, что адрес загружаемых данных подготовлен предыдущей операцией NOP, а здесь вычисляется адрес сладующего за литералом слова. Если в слове окажется несколько литералов подряд, то они и загрузятся подряд за несколько тактов.

Следующая необходимая команда - CALL:

[code]PC[] = DI[]; PC[].ena = VCC;
RStack.cmd[] = push; 
RStack.di[] = PC[] + 1;[/code]

И, конечно же, команда RET:

[code]PC[] = RStack.do[]; PC[].ena = VCC; RStack.cmd[] = pop;
[/code]
помимо этих действий в командах CALL и RET необходимо сбрасывать очередь команд. Это можно сделать как программно (занулив все команды после RET и CALL) или же аппаратно, записав:

[code]RCMD[] = 0;[/code]

с точки зрения схемотехники этот вариант приведет к некоторому усложнению схемы, с другой стороны, программа может выполнить еще несколько действий после того, как изменится счетчик команд, что может оказаться довольно полезно.

Например, команда CALL-LIT-RET загрузит непосредственное данное из адреса, который попадет в PC по CALL и управление тут же вернется на следующий адрес после точки вызова. Сие полезное свойство стоит оставить, поэтому принудительное зануление команд после CALL и RET не делаю.
В случае RET сие состояние дает возможность получить непосредственную команду NEXT для адресного интерпретатора:
команду RET-CALL, которая загружает в PC адрес из стека возвратов, тут же берет из него следующий адрес для загрузки в PC, a увеличеный на единицу адрес интерпретаяции возвращает в стек возвратов.

Итак, команды:

[code]0 - NOP
1 - LIT
2 - CALL
3 - RET
[/code]

Следующая необходимая команда - условный переход - IF

[code]CASE 4=>
    IF (TR[] == 0) THEN
        PC[] = PC[] + 1;
    ELSE
        PC[] = DI[];
    END IF;
    PC[].ena = VCC;
[/code]

Здесь замечу, что PC[] изменяется сразу же при любом значении в TR[], поэтому команды, непосредственно следующие за IF, в том же слове, будут исполнены независимо от исхода сравнения. Это может быть полезно для реализации, например "правильного IF", который при исполнении удаляет верхний элемент стека, т.е. это команда IF-DROP, a команда IF-NOP - оставит верхний элемент стека без изменения.
