Теперь работает LOOP 2…9 и GOTO 3…9
Цитата:
Сообщение от
hitomi2500
Идея сама по себе интересная, но в вашей реализации непрактичная. Запоминать каждую контекстную расшифровку первых 6 букв алфавита - это не сильно проще чем учить опкоды классических восьмибитников (для B у вас уже в первом посте SUB, Bigger и Buffer).
Этo издержки языковых барьеров и технологий.
А правило довольно простое и описывается в несколько строчек:
Код:
00 HLT - Формальный останов: Переход на 0000
nn ADD Ri,BCD - Приращение двоично-десятичной константы
na alu Ri,Tn - Операция АЛУ над Приёмником с Источником
Ri USE Ri - Выбор Индекса в группе Регистров
RT USE Ri,Tj - Выбор операндов для АЛУ-операций
RE EXT Ri - Экстракция (чтение) данных из памяти
RF FIX Ri - Фиксация (запись) результата в память
Eo Eo - Переход на адрес Eo00: E000..E700
Ec Ecnd - Условное выполнение: Execute by condition
F0 FO - Завершение Функции: Function Over
Fh Fh - Вызов Функции по адресу Fh00: F100..FF00
где
Код:
R - Приёмник (Receiver)
T - Источник (Translator)
c - Индекс условия
h - Шестнадцатеричная тетрада, отличная от нуля
i - Десятичный индекс регистра. Если является частью кода - обновляется
j - Десятичный индекс регистра-источника, выбранный раннее
n - Десятичный индекс регистра-источника, используемый временно на период операции
o - Восьмеричный индекс
cnd=F - False / NE / NZ - Фальш, не Ноль
cnd=E - Equal / E / Z - Истина или Ноль
cnd=D - Dry / NC - Сухой результат без Переноса
cnd=C - Carry / C - Перенос
cnd=B - Bigger / NS - Бит Знака сброшен, результат Больше нуля
cnd=A - Among / S - Число было среди интервала
cnd=9 - / PE - Чётный паритет (просто запомнить, так как операция редко используется)
cnd=8 - / PO - Нечётный паритет (просто запомнить, так как операция редко используется)
alu=A - Add
alu=B - suB
alu=C - Conjunct (and)
alu=D - Disjunct (or)
alu=E - Exclusive or (Eor / xor)
Просто, документации нормальной я не составил, так как у меня туго с изложением технических тонкостей в гуманитарном стиле.
(Я ни раз здесь подчёркивал, что процессор этот именно для хардкоршика и фаната дампов, но система команд - гуманитарно-интуитивная. Не стоит думать, что система команд для гуманитариев. Просто она такая, как именно мне удобна. Я её за уши подтягивал к гуманитарному виду, при этом оставаясь в нище хардкорщика. И она выглядит так, как представляется мною в идеале…)
Цитата:
Сообщение от
hitomi2500
Плюс резервировать опкоды под десятичные константы тоже странно - самые часто используемые константы это 0, +1 и -1, остальные излишни мне кажется.
А Befunge/BrainF*ck мало? Ещё и WhiteSpace есть, который аппаратно тоже можно реализовать как процессор для блондинок: Каждая строчка - стих!
Цитата:
Сообщение от
hitomi2500
Поэтому надо смотреть на более серьёзные синтетические языки с коротким словом и малым числом букв.
И это я делал, даже в Verilog'е описывал что-то. Процессор использует ПЗУ на 2 Кб, где закодировано, как реагировать на ASCII-символ.
Например, «1scrn = 1keybd + (128 - 0x80)» аппаратно переваривает как «1 байт ячейки scrn загрузить 1 байтом ячейки keybd с выражением».
То есть, первые цифры формируют режим доступа, буквами кодируется адрес, а знаками - управляется АЛУ и пр…
Можете не верить, но я занимался вопросом аппаратной реализации такого процессора.
Причём, даже находил способ чтения имени ячейки «keybd» за 1 такт через чтение 64-битного слова и каскадом ПЗУ с обратной связью, чтобы сформировать цепь букв и определить длину.
В LogiSim такое будет слишком сложно строить!
Цитата:
Сообщение от
Lethargeek
эээ, зачем вообще 7 одинаковых сложений за 7 (на самом деле больше) тактов? это сдвиг младшего бита в старшую позицию штоле? вместо and + одна прокрутка вправо...
Реализовал, но схема получилась чуть путанее…
Нужно ещё перераспределить блоки графически, так как я ошибочно расположил АЛУ у выхода с регистрового файла чисто из соображений «два операнда входит - один результат выходит».
На деле же это оказалось большой ошибкой, так как именно из регистрового файла выходит несколько каналов с данными, но на входе - очень много управляющих сигналов!
Теперь коды 02…09 загружают регистр повтора. Сдвиговый регистр пропускает первый цикл и несколько раз начинает со второго цикла. Тем самым, операции с доступом к памяти с циклами 3 и 4 работают.
Интересно получилось с инструкциями E8…EF - условным выполнением: В таком режиме цикла разрешается счёт указателя команд, но не происходит выборки. Тем самым, по условию можно пропустить несколько инструкций. Например:
Код:
0000 AA A1 1E |EOR A1,A1 ; Очистить A1
0003 05 EF |EF 5 ; Условное исполнение инструкций до пятой, как «IF !ZF THEN ON N GOTO 5,6,7,8,9»
0005 A1 A2 A3 A4 | - - - ; Эти инструкции игнорируются
0009 A5 |USE A5 ; Здесь счётчик игнора очищается
000A 03 85 |REP3(A5+85) ; Здесь три раза прибавится 85
Тем самым, появились такие трюки, как «ленивое выражение».
Даже если сейчас на меня обрушится куча критики, скажу, что в схеме это почти ничем существенным не усложнилось. За то программный уровень намного упростился!
Вложений: 2
Нормализованный Эскиз Схемы
Цитата:
Сообщение от
Lethargeek
кароч, понял, что еще мне напоминает необходимость помнить контекст при кодинге - программирование эффективных вычислений на форте
https://www.youtube.com/watch?v=5hhbGBlP3_4
Очень долго провозился с перераспределением функциональных блоков.
Теперь схема графически выглядит менее путаней и более последовательной.
А в маленькой масштабе напоминает кристалл микросхемы.
Кое-где даёт сбой…
При манипуляции джойстиком симуляция может прерваться (глюк LogiSim?).
А при печати на клавиатуре может улететь в режим останова с перемигиванием лампочек для без нажатия на Забой…
Почему-то даже в ручном шаговом режиме часть шин уходит в неопределённость (я не про АЛУ). Думаю, LogiSim не тянет…
Подправил схему и чуточку дописал описание:
Код:
Кодирование алгоритма малой степени сложности доступно пользователю с базовыми
навыками редактирования таблиц дампа и не представляет особой сложности в силу
максимально осмысленного кодирования всех инструкций в шестнадцатеричном виде.
------------------------------------------------------------------------------
|Код команд / диапазоны|Группа |Описания, замечания, комментарий
-----------------------|----------|-------------------------------------------
00 |HLT |Прекращение счёта указателем команд IP
02-09 |REP 2-9 |Префикс повтора/пропуска операции n-раз
10-99 01 |ADD Ri,BCD|Двоично-десятичное накопление в регистр
0A-9F |ALU Ri,Tk |Операция АЛУ с комбинацией аргументов
A0-A9 B0-B9 C0-C9 D0-D9|REG Rn |Установка индекса активного регистра группы
AA-AD BA-BD CA-CD DA-DD|ARG Ri,Tj |Выбор комбинации аргументов операциям АЛУ
AE BE CE DE |EXT Ri |Экстракция данных из внешнего ОЗУ в регистр
AF BF CF DF |FIX Ri |Фиксация значения регистра во внешнее ОЗУ
E0-E7 |EX0-7 |Переход на адрес 0xE000-0xE700
E8-EF |Ecnd |Выполнение следующей команды по условию
F0 |FIN |Завершение с переходом на адрес Базы:Счёта
F1-FF |FN1-15 |Переход на адрес 0xF000-0xFF00
------------------------------------------------------------------------------
(n - устанавливаемый индекс, указанный битами команды)
(i или j - индекс, установленный раннее)
(k - индекс регистра временно берётся из старшего ниббла кода команды)
Группы регистров A0-A9, B0-B9 и C0-C9 составляют внутренний регистровый файл с
безусловным доступом к ним на программном уровне. Регистры B0-B9 хранят "Базу"
для обращения к памяти блоком в 256 байт, а регистры C0-C9 - счёт байта блока.
Инструкция с кодом F0 помещает текущий адрес указателя инструкций из IP в B0 и
C0, а значения из Bi и Cj помещает в IP, производя переход на адрес Bi:Cj. Тем
самым, можно обращаться к коду подпрограмм и знать адрес возврата через B0:C0.
Группу регистров D0-D9 составляют внешние Device-устройства с непосредственным
использованием в качестве операндов. Не рекомендуется активно использовать эту
группу в любых вычислительных действиях, так как нет гарантии работы программ.
Префикс REP используется для повтора любой операции на нужные n-тактов дольше.
Исключение представляет условная группа Ecnd, которая исполняет n-ую команду в
очереди, если условие ЛОЖНО.
******************************************************************************
* Примеры *
******************************************************************************
AA A1 1E |EOR A1,A1 ;Очистка по Исключающему Или (sf pf cf ZF)
AA A1 2E |EOR A1,A2 ;Исключающее Или A1 с A2 (?? ?? ?? ??)
AB A1 1A |EOR A1,B1 ;Исключающее Или A1 с B1 (?? ?? ?? ??)
AB A1 2A |EOR A1,B2 ;Исключающее Или A1 с B2 (?? ?? ?? ??)
AA A1 1E AB 2A |MOV A1,B2 ;Присвоение Исключающим Или (sf pf cf ZF)
AA A1 34 |SUM A1,34 ;Инкремент на константу (-- -- -- --)
AA A1 02 34 |SUM A1,2*34;Расширенный инкремент (-- -- -- --)
F8 |CALL 0xF800 ;Вызов подпрограммы
03 F8 |CALL 0xF803 ;Вызов подпрограммы с пропуском команд
F0 |RET ;Возврат из подпрограммы
03 F0 |RET 3 ;Возврат с переходом на команду #3
03 EC |EC 3 ;Условное выполнение по CF по команду #3
******************************************************************************
0000 03 EE A1 A2 A3 |IF ZF THEN {A1 A2 A3} ELSE A3
0005 03 EF A1 A2 A3 |IF ZF THEN A3 ELSE {A1 A2 A3}
000A 03 E0 A1 A2 A3 |GOSUB E003:A1:A2:A3
E003 03 F0 |RETURN TO A3
******************************************************************************