Удалoсь заняться попытками реализации задуманного…
Благо, Icarus Verilog компактен и быстр для симуляции + облачные технологии доступны для демонстрации.
Облачная Verilog-версия.
Написано, в основном, как попало, лишь бы убедиться, что я способен заставить это выполнять мой код.
Но, это - работает… Крайне примитивно, но работает.
А именно: «HLT», «MOV [BX],R», «MOV R,R1», «MOV R,ID», «INC BX», «PUSH n», «JMP $+ID», «RET»…
Вывод «WAIT» позволяет удлинять циклы чтения/записи медленных устройств… Сделал просто, но не знаю, верно ли?
(Работает так: По-фронту шина данных считывается во временный регистр. По-срезу - проверяется «WAIT» и снимается сигнал «READ»…
То есть, если «WAIT» изменялся между этими событиями, то факт игнорируется… Ввёл триггер на такой случай, но потом решил, что это - излишества.)
В «i8080»/«Z80» всё завязано на машинных циклах. В частности, «M1» - считывает код очередной инструкции…
Когда я начинаю так делать, на «NOP» требуется 4 такта…
Когда иду «окольным» путём - уходит 3 такта…
А если иду своим путём - вообще 2 такта требуется. В чём дело?
Мой путь (я его забраковал и удалил, так как пытаюсь находиться в рамках традиционных машинных циклов):
Регистры IC (Instruction Code) и ID (Immediate Data) - 9-битные, где «лишний» бит - «признак сбоя»…
Перед чтением очередной команды «признаки сбоя» устанавливаются… Тем самым, к шине адреса «подтягивается» счётчик инструкций и при считывании данные непосредственно фиксируются в «сбитых регистрах»… И если «WAIT»-сигнал «даёт добро», бит «сбоя» сбрасывается…
Реализация проста, но не «красива», так как нужно оставаться в рамках битов машинных циклов, а они у меня, получается, хранятся прямо в «девятых» битах…
При этом, промежуточные регистры адреса и данных имеют также «лишние биты». Так, если 17-й бит адреса установлен, его надо очистить, предварительно выдав адрес/данные на шины для цикла записи в память. А если установлен 9-й бит данных, то они считываются…
То есть, «по-хорошему» это надо вынести в отдельные циклы. Тогда как у меня всё получается через «лишние биты», разбросанные по разным регистрам… Что, с одной стороны, даёт «интуитвную» модель поведения системы и ускоряет процесс. А с другой - «портит» архитектуру, так как уходит строгость и формальность завязанности на машинных циклах…
Проблемы:
Во-первых, «файл контекста» (для страничной памяти и многозадачности) не задействован…
Во-вторых, «АЛУ» не задействованно…
В-третьих, реализация чтения/записи стека заметно кривая…
В-четвёртых, элементарные операции реализовал с трудом. Не знаю, что будет дальше…
В-пятых, «LOOP/SKIP/WAIT» режимы реализовать относительно легко, но пока не понятно, как…
P.S.: Что получилось, то получилось…
На «NOP» уходит 3 такта… Не мало ли для «
устойчивой работы»?