PDA

Просмотр полной версии : x80: CISC - уже не i8080, ещё не i8086



Радио-86РК
14.05.2020, 19:31
Легенда
Eщё со школы имею мечту построить собственный компьютер на собственном процессоре. Причём, архитектуру процессора 15 лет безуспешно пытался разработать с нуля. Но дальше RISC-процессора в LogiSim дело не сдвинулось.
Хотя, схему выборки CISC-команды из памяти разработать удалось.
Сейчас разрабатываю эмулятор средствами HTML5 на JavaScript, чтобы никому ничего не нужно было скачивать и работало онлайн.
Если первый эмулятор строился на «switch-case» и это значительно усложняло разработку системы команд, то потом разработал движок с использованием шаблона на принципах «casex» Verilog, где вся система команд описывается в таблице, а скрипт при инициализации парсит её и генерирует массив из тысяч комбинаций команд. Конечно, память расходуется значительно и наблюдаются существенные просадки производительности, но именно такой эмулятор удобен, когда окончательная таблица команд всё ещё не готова и постоянно модифицируется.

Идеология
Опыт коллег (PICO-8 (https://www.lexaloffle.com/pico-8.php), MegaProcessor (http://www.megaprocessor.com/), MyCPU (http://www.mycpu.eu/), Gigatron (https://gigatron.io/) и т.д…) вдохновляет меня и собственными окольными путями пытаюсь построить собственный процессор без предрассудков: Мне не нужно экономить на простоте, чтобы где-то какой-то проводочек стал короче на миллиметр. И я не тороплюсь запустить архитектуру с колена, чтобы состряпать хоть что-нибудь и это поехало лампочками мигать или фракталы Мандельброта строить…

План прост по-идее, но сложен в перспективе, так как локально планируется переразработать всю линейку архитектуры Intel с нуля. А именно, так как i8080 и i8086 программно никак не совместимы, а система команд обоих оставляет желать лучшего, то поставил план разработать 8-битную архитектуру с расширением до 16 бит или до 32, причём с программной совместимостью в обе стороны…

Ошибки Intel прослеживаются с самого начала:

На уровне машинного кода i8080 и i8086 абсолютно несовместимы
На уровне ассемблера совместимость частичная, хоть и заявлялось о ней
Поддерживаются рудиментарные команды (i8080: 32/3A - STA/LDA; i8086: A0/A1/A2/A3), которые все не перечислишь, но в современном защищённом режиме их наличие - бессмысленно
Гибриды типа NEC V20 (https://ru.wikipedia.org/wiki/NEC_V20) пытались поправить ситуацию, но всё оказалось безнадёжным


Тем самым, был просто взят процессор i8080 во всей его красе и система команд была перераспределена из восьмеричной в шестнадцатеричную и удалены команды с 16-битными константами. И даже можно увидеть ту же систему команд i8080:


Если внимательно присмотреться, то за основу я взял тактику i8080, где инструкцию «MOV M,M» превратили в «HLT»: Всю группу MOV-блока я сдвинул в начало и перегруппировал, чтобы та самая «HLT» заняла код «00». Так как в i8086 код «00» печальным образом занимает команда «ADD», что позднее в Windows разрослось в кучу ловушек, это послужило ценным опытом, как не надо делать на стадии проектирования дешифратора команд в угоду экономии проводочков, так как сейчас дешифрацией x86-кода занимается RISC-ядро и тактические экономические трюки инженеров в 70-х просто навсегда изувечили всю систему команд!
Также и имена регистров переименованы в стиль i8086, что значительно упрощает написание кода под мой процессор в стандартных отладчиках, как та же Visual Studio…

Тем самым, у меня получилось, что:
00: MOV M,M = HLT
11: MOV BH,BH = Prefix BH/BP
22:MOV CH,CH = Prefix CH/SI
33:MOV DH,DH = Prefix DH/DI
44:MOV AL,AL = Prefix SP
55:MOV BL,BL = Prefix BL/BX
66:MOV CL,CL = Prefix CL/CX
77:MOV DL,DL = Prefix DL,DX
Чем для приложения даны 7 префиксов.
Для супервизора имеется «супер-префикс» с кодом «00», так как в «режиме ядра» операция «HLT» не нужна. Чем я убил двух зайцев:
Нету никаких привилегированных команд, которые приложению нельзя использовать. Тем самым, все коды таблицы команд приложение может использовать
Только в «режиме ядра» этот «супер-префикс» доступен и не болтается мусорным защищённым кодом в системе команд у приложений


Архитектура
Хоть процессор и походит на продвинутый вариант i8080, но это не совсем так.
В режиме супервизора «супер-префикс» 00 даёт доступ к служебному регистру #0, который переключает регистровый файл процессора. Всего предусмотрено до 128 страниц регистрового файла и процессор может выполнять до 128 задач в кольце.
Регистровый файл предусмотрен как внешняя память статического ОЗУ из отдельных регистров. Можно использовать как интегральное ОЗУ одной микросхемой памяти на 32 Кб, а можно и организовать 256 отдельных регистров/ОЗУ на 128 байтов. То есть, в отладочном стенде файл контекста можно организовать из 256 регистров, чтобы в любой момент видеть его содержимое (как в Мегапроцессоре). А в практическом исполнении просто обойтись одной микросхемой памяти…
Как уже понятно, для доступа к РОН хранящихся во внешнем статическом ОЗУ требуются такты. В этом плане процессор работает как тот же 6502 и на простые операции требуется много тактов. С другой стороны, я над этим не беспокоюсь, так как систему кешов и конвейеров никто не отменял, что никак не мешает в перспективе ускорить архитектуру в разы.
(Я уже выше сказал, что не буду совершать ошибки Intel и искать оптимальные пути на этапе проектирования, так как RISC-ядро с лёгкостью может сгладить любые издержки производительности.
А так как это - CISC-процессор, то по-любому архитектура может быть довольно сложной и затратной. Оптимизировать я её не собираюсь!)

Процессор имеет несколько особенностей, которые усложняют его архитектуру, но приближает его к уровню 16-битных.
Так, используются «запретные комбинации» статуса АЛУ, которые никогда в нормальных условиях не встречаются:
ZF PF - SKIP-режим холостого чтения команд
ZF SF - LOOP-режим выполнения команды несколько раз, один из РОН используется за счётчик
ZF SF PF - WAIT-режим, тот же LOOP-режим с прерыванием
Так, операции с портами IN/OUT доступны лишь под режимом WAIT и порт, если он существует, вернёт сигнал готовности и прервёт WAIT-цикл. Если же порта аппаратно не существует и сигнала готовности нет, режимом WAIT будет использован один из РОН в качестве счётчика. Программа по обнулённому счётчику может знать, ответил порт или нет…
Так и цикл WAIT+SUB может использоваться как операция деления, так как WAIT прерывается по флагу CF. Аппаратно легко перехватить комбинацию WAIT+SUB или LOOP+ADD внешним сопроцессором и выполнить операции DIV/MUL быстро аппаратно. Тем самым, системой команд предусматривается внешний сопроцессор, но для его операций используются трюковые комбинации стандартных команд.

Режим SKIP упрощает описание «ленивых выражений» и условных кейсов. Если Вы помните DOS с его «INT 21h» с подфункцией через код в AH, то здесь SKIP работает примерно также. Например, комбинация «LOOP 5 + INT 21» не станет вызывать «INT 21» пять раз, а вызовет один раз, но переключится в режим «SKIP 5». Тем самым, если в подпрограмме имеется стопка из «JMP», то будет пропущено 5 «JMP» режимом «SKIP». Это делает решение гораздо изящнее…

Прерывания
Процессор при любом событии всегда переходит в одну заданную точку программы, но с разной SKIP-величиной.

Обращение к INT 0-79
Переключение памяти
Переключение задач
Запрос к устройству ввода-вывода
Внешние маскируемые прерывания
Сигнал немаскируемых прерываний
Запуск ядра по сигналу RESET
Тем самым, по сигналу СБРОС процессор перепрыгнет в стандартную точку входу и пропустит семь JMP'ов в режиме «SKIP 7». Причём, СБРОС происходит не сразу, а по истечению интервала в служебных регистрах с отсчётом до 65535 тактов. Тем самым, сначала RESET срабатывает как немаскируемое прерывание и управление получает ядро. Если ядро нормально функционирует, то оно предустановит служебные счётчики и предотвратит СБРОС системы. Иначе, спустя указанное число от счётов управление снова получит ядро, но через точку запуска.

Приложения не могут напрямую обращаться к устройствам и операции «WAIT+IN/OUT» генерируют событие #4 ядру, которое уже само должно разбираться.

RISC vs RISC
Хоть процессор разрабатывается по принципам CISC-технологии (городи что хочешь), но он из неё умудрился вылезти!
И я просто переименовал его в RISC, который нужно читать не как «Reduced Instruction Set Computer», а «Rebused Instruction Set Computer». То есть, «Ребусная Система Команд», так как комбинации префиксов достигают уровня головоломки, которую тяжело переварить ассемблером и дизассемблером. Хотя эмулятор их исполняет корректно.
Потому, если Вы любитель простоты, то Вам моя технология не понравится и её можете игнорировать.
С другой стороны, если Вы - любитель головоломок и не прочь сломать мозг машинным кодом, то Вам может понравится сахар…
Сахар в машинном коде

LOOP n + SKIP => SKIP n ; Цикл из n-раз превращается в игнорирование n-инструкций
LOOP n + JMP => JMP & SKIP n ; Переход на метку и игнорирование n-инструкций
LOOP n + CALL => CALL & SKIP n ; Вызов подпрограммы и игнорирование n-инструкций внутри подпрограммы
LOOP n + INT => INT & SKIP n ; Вызов программного прерывания и игнорирование n-инструкций внутри подпрограммы
LOOP n + RET => RET & SKIP n ; Возврат из подпрограммы и игнорирование n-инструкций
LOOP n + MOV R,[IX±offset] => MOV R,[IX+Rn±offset] ; Вместо цикла индексный адрес формируется в индексно-относительный
LOOP n + MOV [IX±offset],R => MOV [IX+Rn±offset],R ; Вместо цикла индексный адрес формируется в индексно-относительный
LOOP n + NOP m => NOP n×m ; Команда NOP с задержкой на m-тактов выполняется n-раз
LOOP n + ADD => MUL n ; Без сопроцессора умножение достигается сложением в цикле
WAIT n + SUB => DIV n ; Без сопроцессора деление достигается циклом вычитания с прерыванием
WAIT n + MOV => IN/OUT ; В ожидании команды межрегистровых пересылок превращаются в команды обращения к УВВ с ожиданием готовности
LOOP n + MOV => MOV ctx ; В цикле команды межрегистровых пересылок обращаются к ячейкам регистрового файла активного контекста
HLT + MOV M,R => MOV ctrl,R ; Под «супер-префиксом» можно записать регистр страницы контекста и переключить задачу
LOOP n + HLT => EXIT n ; Запрос системы с выходом и передачей кода результата
WAIT n + HLT => SYSCALL n ; Обращение к API системы
LOOP + LOOP => reserved ; Теоретически работает, но назначения и логики не имеет
LOOP + WAIT => reserved ; Теоретически работает, но назначения и логики не имеет
WAIT + LOOP => reserved ; Теоретически работает, но назначения и логики не имеет
WAIT + WAIT => reserved ; Теоретически работает, но назначения и логики не имеет
Можно видеть, что подобные трюки увели концепцию далеко от i8080/z80 и подтянули возможности до i80286…
Система команд напоминает ребус и не понравится тем, кто любит простые решения…
LOOP 3 ; Режим повтора 3 раза
CALL MyFn ; Повторить вызов нельзя - будет пропуск SubFn0, SubFn1, SubFn2
JMP Error ; Если подфункция отсутствует, RET вернётся на этот JMP
... ; Иначе - нормальное продолжение программы

MyFn:
JMP SubFn0 ; Выполнится по CALL MyFn
JMP SubFn1 ; Выполнится по LOOP 1 + CALL MyFn
JMP SubFn2 ; Выполнится по LOOP 2 + CALL MyFn
ADD AL,DL ; Выполнится по LOOP 3 + CALL MyFn
LOOP 1 ; Пропустим JMP Error
RET

Эмуляция

Одна из первых версий эмулятора (http://htmlpreview.github.io/?https://github.com/Alikberov/x80/blob/master/emulator.old.html?speed=10&reset=1000&cycle=1024&debug=FFFF) с Монитором в стиле РАДИО-86РК. Автоматически выводится дамп, прыгает шарик с очищением поля и построением рамки, после чего выводится фигурка Тетриса, управляемая клавиатурой
Другая версия (http://htmlpreview.github.io/?https://github.com/Alikberov/x80/blob/master/emulator.html?speed=10&reset=1000&cycle=1024&debug=FFFF) эмулятора. Клавиша F4 запускает эмуляцию. Сначала выводится дамп по «D000,3BF», затем выводится подсказка по директивам, а потом запускается режим эха клавиатуры, которое глючит. Баг очень сложен и связан с неполным пониманием механизма переключения контекста от Супервизора к приложению. Ядро эмуляции спланировано неверно и его нужно полностью перерабатывать. (Если буфер клавиатуры чист, чтение порта приводит к ожиданию циклом Wait без флага CF. Приложению этот флаг нужно передать в контекст, но на уровне JavaScript теряется контроль над синхронностью и приложению возвращаются неверные флаги…)
В данный период дорабатывается версия эмулятора с путаницей переключения контекстов, так как я занимался внедрением «супер-префикса». Пустяковая доработка заняла три дня отладки и доработок алгоритмов ассемблера, дизассемблера и эмулятора. Но сама проблема пока не решена. Лишь упростились некоторые команды…


Наращивание
Как выше уже сказано, процессор спланирован как восьмибитный, но с перспективой расширения до 16 и 32.
Уже на восьми битах планируются трюки, где АЛУ может работать с 16 и 32 битами. Разница лишь в том, что в 8-битном прототипе на 32-битную операцию может уйти десятки тактов, тогда как в 32-битном прототипе - один такт.
Тем самым, на 8-битном прототипе уже можно разрабатывать 32-битные приложения и запускать их. Разница будет лишь в производительности, так как размер команд останется тем же: В отличии от i8080/z80 здесь нету 16-битных операндов, типа «LD SP,addr». Всё - 8-битное. И на 32-битном прототипе все индексы операндов - один байт.

Способы адресации

07 :MOV DL,[BX] ; Косвенно-регистровая адресация
67 :MOV DL,CL ; Регистровая адресация
A7 89:MOV DL,0x89 ; Непосредственная адресация
55 A7 89:MOV DL,[BX-119] ; Относительная адресация
E4 55 A7 89:MOV DL,[BX+AL-119] ; Индексная адресация
B8 FE 55 A7 89:MOVX DL,[BX+XX-119] ; Чтение в режиме X по индексу XX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
0A :ADD AL,[BX] ; Косвенно-регистровая адресация
6A :ADD AL,CL ; Регистровая адресация
AA 89:ADD AL,0x89 ; Непосредственная адресация
55 AA 89:ADD BL,0x89 ; Непосредственная адресация
E4 55 AA 89:ADD4 BL,0x89 ; Сложение в режиме #4
B8 FE 55 AA 89:ADDX BL,0x89 ; Сложение в цикле режима X
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
81 23:PUSH 0x0123 ; Помещение константы в стек
91 23:PUSH 0xF123 ; Помещение константы в стек
55 81 23:PUSH 0x5123 ; Помещение константы в стек
55 91 23:PUSH 0xA123 ; Помещение константы в стек
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55 A0 23:PUSH [BX+35] ; Относительная адресация
55 B0 23:POP [BX+35] ; Относительная адресация
E4 55 A0 23:PUSH [BX+AL+35] ; Индексная адресация
E4 55 B0 23:POP [BX+AL+35] ; Индексная адресация
B8 FE 55 A0 23:PUSX [BX+XX+35] ; Индексная адресация X по XX
B8 FE 55 B0 23:POPX [BX+XX+35] ; Индексная адресация X по XX
FPGA
Естественно, есть и Verilog-модель (http://www.edaplayground.com/x/2pm6), выполняющая несколько команд.
Но, из-за плохого владения принципами Verilog, эскиз модели получился тупиковым и всё нужно переписывать с нуля…

Почему x80?
Почему из всего богатства архитектур я выбрал именно Intel?
Во-первых, с i8080 я знаком с самого детства через ВМ80 в любимом РАДИО-86РК.
Во-вторых, тот же ZX-Spectrum и GameBoy построены на Z80.
В-третьих, система команд CISC более дружелюбна, а i8086 намного легче реализовать, чем изучать 68000, так как с ним я никогда не работал непосредственно.
В-четвёртых, я не так силён в электронике, чтобы городить свой RISC с перспективой конвейерного исполнения 32 команд за такт.

Сотрудничество
Если Вы имеете возможность и способность управиться с Verilog/FPGA/CPLD, буду очень рад формированию хоть какого-то коллектива разработчиков линейки x80, x180, x280, x380…

Lethargeek
14.05.2020, 22:38
Тем самым, был просто взят процессор i8080 во всей его красе и система команд была перераспределена из восьмеричной в шестнадцатеричную и удалены команды с 16-битными константами. И даже можно увидеть ту же систему команд i8080:
Вложение 72596
"Вложение не существует или не указан идентификатор (номер). Если вы уверены, что использовали правильную ссылку, свяжитесь с администрацией"

но скажу сразу, восьмибитке нужно минимум два стека (или хотя бы команда быстрого обмена указателя стека с другими парами)


В-третьих, система команд CISC более дружелюбна,
вот категорически не согласен, всё зависит от конкретной реализации

приблизительная имха:
ARM - красава
6809 - красава
M68k - норм
Z80 - норм
PDP-11 - норм
MIPS - уныл
SPARC - ужос
8080 - ужос
x86 - ужос и кабздец

и это при том, что больше всего опыта ассемблерокодерства у меня как раз с x86

HardWareMan
15.05.2020, 07:07
https://jpegshare.net/images/02/57/0257b867c2266beaea019892b5ba9cf9.png
Эм...
https://s.fishki.net/upload/users/2019/05/22/703323/3f362e1677f727d447aaac7589a42022.gif

Hunta
15.05.2020, 09:11
ИМХО

Система команд процессора должна быть дружелюбна к тому языку, который будет основным для разработки под процессор.

В данном случае, очевидно, предполагается программирование на ассемблере, но дружелюбности - не наблюдается. Болеe того, несмотря на фразу:

тактические экономические трюки инженеров в 70-х просто навсегда изувечили всю систему команд!
автор и сам попал в эту ловушку


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


Приложения не могут напрямую обращаться к устройствам и операции «WAIT+IN/OUT» генерируют событие #4 ядру, которое уже само должно разбираться.

Это называется скрытый запрет. Например, в PDP-11 в пользовательском режиме команда HALT запрещена и генерирует событие (прерывание), которое обрабатывает ядро и должно уже само разбираться. Слова другие, смысл тот же.



Для супервизора имеется «супер-префикс» с кодом «00», так как в «режиме ядра» операция «HLT» не нужна.


То есть, «Ребусная Система Команд», так как комбинации префиксов достигают уровня головоломки, которую тяжело переварить ассемблером и дизассемблером.


Потому, если Вы любитель простоты, то Вам моя технология не понравится и её можете игнорировать.
С другой стороны, если Вы - любитель головоломок и не прочь сломать мозг машинным кодом, то Вам может понравится сахар…

А теперь подумайте о том - сколько будет ОШИБОК в программе из за СЛОМАННОГО МОЗГА программиста?
Или может всё таки стоит облегчить написание программ человеку?


В данный период дорабатывается версия эмулятора с путаницей переключения контекстов, так как я занимался внедрением «супер-префикса». Пустяковая доработка заняла три дня отладки и доработок алгоритмов ассемблера, дизассемблера и эмулятора. Но сама проблема пока не решена. Лишь упростились некоторые команды…

Ч.И.Т.Д. Это называется - сломать МОЗГ, только не человек, а ПРОЦЕССОРУ. Хотя нет, человеку тут мозг тоже уже вынесли. Вам.


Если Вы имеете возможность и способность

буду очень рад формированию хоть какого-то коллектива разработчиков линейки x80, x180, x280, x380…
Крик души - ХОТЬ КАКОГО-ТО КОЛЛЕКТИВА.
Но существует очень хороший шанс, что в коллективе так и останется один человек

andrews
15.05.2020, 10:03
Будущее за радиационно-стойкими микросхемами. Поэтому в проектировании архитектуры надо идти только от технологии! Чтобы при прочих равных себестоимость производства у вас была ниже, чем у конкурентов. Сегодня проектировать нечто ниже 64 бит - затрачивать усилия впустую. Еще одно перспективное направление проектирование масштабируемых вычислителей. Чтобы при прочих равных обойти конкурентов по соотношению производительность/потребление, производительность/себестоимость. Ну и совсем в десятку сочетание в одной архитектуре двух вышеперечисленных! Хотя я сам балуюсь со старыми 8 битными архитектурами, но не со столь глобальными целями как у Вас. А если исходить из удобства программиста, то ассемблер для архитектуры должен получаться максимально простым и прозрачным.

Hunta
15.05.2020, 10:49
надо идти только от технологии!

Будущее за радиационно-стойкими микросхемами.

себестоимость производства у вас была ниже, чем у конкурентов.

Аха - выберите любые две цели из трёх. Ибо что бы получить все три цели сразу - боюсь, придётся выложить, как минимум, несколько миллиардов у.е. для НИОКР на непонятно какой срок и помнить, что даже после истечения этого срока отбить вложения получится очень далеко не сразу. И отбить их получится - если вы угадали с тем, куда вложились.

И если брать деньги на это дело у какого-то инвестора, то все это время с плюсом - его придётся убеждать, что те хайпы, которые будут постоянно подниматься о всяких новых фишках в этих темах - это хайпы на предмет - выбить деньги у инвесторов и спустить их без результата - а вот ваша идея - это о-го-го и когда она, наконец, ещё при его и вашей жизни, начнёт приносить ....ллиарды - вы будете купаться в собственном озере на ранчо на спутнике Сатурна, любуюсь надписью "Самому крутому инвесторы тысячелетия" на его кольцах, отбиваясь от других инвесторов.

Радио-86РК
15.05.2020, 11:07
Эм...Всe инструкции видеть можно только в эмуляторе.

В архиве выложил скриншоты с таблицей команд, где можно чуточку посмотреть на некоторые комбинации и сочетания с префиксами.
Скриншоты, естественно, не все, так как комбинаций очень много. Некоторые инструкции я вручную перечеркнул графически, так как эмулятором они представлены как недокументированные и их нужно глушить как побочные.

Ещё в архив добавил весь файл эмулятора, где…
в строках 4160…4274 описывается вся система команд шаблоном
в строках 4276…4377 описываются регистры, флаги и АЛУ-операции
в строках 4653…4780 представлен знакогенератор РАДИО-86РК
строками 4867…6386 описывается ассемблером некий программный код, но много под комментарием, так как скопировано из прошлой версии эмулятора и сейчас может не работать
В общем, если браузер позволит использовать функциональные клавиши, то…
F1 делает один шаг в отладке
F4 запускает эмуляцию до точек отладки, помеченных розовым
F6/F7/F8 настраивают производительность эмуляции
ALT+P и ALT+T позволяет редактировать память или ячейки контекста
клавиш много, но они полезны только мне, как активному разработчику…

Думаю, если просто любопытно глянуть на всё это, то увидите, сколько вложено усилий и никаких «copy-paste» из интернета. Успел понаписать столько, что самому жутко всё это отлаживать.
А если вздумаете вникнуть в этот исходник, то ничего не поймёте, так как и сам уже в нём теряюсь и правлю с опаской по принципу «работает - не трожь!»: Написано местами изящно (парсер шаблона всех команд), но в общем - очень безобразно!

Hunta
15.05.2020, 11:10
если вздумаете вникнуть в этот исходник, то ничего не поймёте, так как и сам уже в нём теряюсь и правлю с опаской по принципу «работает - не трожь!»
Ч.И.Т.Д.

andrews
15.05.2020, 11:26
Аха - выберите любые две цели из трёх. Ибо что бы получить все три цели сразу - боюсь, придётся выложить, как минимум, несколько миллиардов у.е. для НИОКР на непонятно какой срок и помнить, что даже после истечения этого срока отбить вложения получится очень далеко не сразу. И отбить их получится - если вы угадали с тем, куда вложились.

И если брать деньги на это дело у какого-то инвестора, то все это время с плюсом - его придётся убеждать, что те хайпы, которые будут постоянно подниматься о всяких новых фишках в этих темах - это хайпы на предмет - выбить деньги у инвесторов и спустить их без результата - а вот ваша идея - это о-го-го и когда она, наконец, ещё при его и вашей жизни, начнёт приносить ....ллиарды - вы будете купаться в собственном озере на ранчо на спутнике Сатурна, любуюсь надписью "Самому крутому инвесторы тысячелетия" на его кольцах, отбиваясь от других инвесторов. А вы в курсах, что несмотря ни на какие санкции в России живет и здравствует, не взирая ни на какие санкции американская фирма Actel(Microsemi)? Знаете за сколько нашим приходится покупать у них микросхемы себестоимостью в несколько центов? Правильно, за многие сотни долларов! И хотя ракетоносители электронику эту выводят на орбиту российские, но делать свою радиационно-стойкую микроэлектронику ни-ни! Это как установка для местных аборигенов. Я уж молчу кто там директорствует, чтобы не сочли за сведение личных счетов. Поэтому Вы конечно правы, но правда эта России не сулит ничего хорошего. Стратегическая же цель легко отслеживаемая - с помощью своей мэ держать Россию "на кукане" в деле промышленного освоения Космоса.

- - - Добавлено - - -


Крик души - ХОТЬ КАКОГО-ТО КОЛЛЕКТИВА.
Но существует очень хороший шанс, что в коллективе так и останется один человек коллективу нужны финансовые перспективы. Ну хотя бы по $50 000/год на первое время, разумеется каждому :)

Hunta
15.05.2020, 11:49
А вы в курсах,
Вы даже не поняли - про что я.

Удачи.

Радио-86РК
15.05.2020, 11:51
Кстaти, если считаете, что дешифрация всех этих команд аппаратно слишком сложно реализуется и без RISC-ядра и микрокода не обойтись, то вот набросок схемы узла выборки кода команды под LogiSim и Proteus.
Узел считывает полный код команды вместе с префиксами, выдавая те же биты, что используются в шаблоне JavaScript-эмулятора.

Естественно, имеется схема (устаревшая), которая считывает из памяти команды и переводит их в текст - аппаратный дизассемблер.
Но из-за сложности работы с регистровым файлом, схемы частичного симулятора процессора пока не удалось разработать - не хватает опыта работы с кешом, чтобы расписать по тактам…

P.S.: Это чтобы не быть голословным.
Хоть какие-то наработки электронными узлами да имеются…
Но опыта в целом - нет.

andrews
15.05.2020, 11:59
Вы даже не поняли - про что я.

Удачи.

да понял я, в .опе наша российская радиационно-стойкая мэ...а сведения как её проектировать гостайна, чтобы американцам бабки на нас делать не мешать.

Hunta
15.05.2020, 12:01
да понял я, в .опе наша российская радиационно-стойкая мэ
Как я и сказал - не поняли.

Радио-86РК
15.05.2020, 14:58
В данном случае, очевидно, предполагается программирование на ассемблере, но дружелюбности - не наблюдается. Болеe того, автор и сам попал в эту ловушкуСистемa команд того же z80 полна всяких исключений. Например, «LD A,» неочевидным образом удлиняет команду на 1 байт для указания индекса смещения.
То есть, последовательнее было бы под IX-префиксом расширять не «LD r,(HL)», а «LD r,d8». Тогда бы с добавлением префикса IX перед командой её размер не увеличивался бы. Что у меня и сделано:
A4 7F|MOV AL,0x7F
44 A4 7F|MOV AL,[SP+0x7F]
E4 44 A4 7F|MOV AL,[SP+AL+0x7F]
/\ /\
|| ||
|| |+--\ Код
|| +---/ префикса SP
||
|+-----\ Код
+------/ префикса LOOP ALА так как в самом начале разработки у меня не было опыта построения ассемблера, то первые пробные программы под свой процессор я набирал голым дампом. Потому и система команд изначально у меня и сформировалась по принципу «сам код - и есть мнемоника.
Где «A4» - «LOAD R4», а «AA» - «ALU:ADD» и «AB» - «ALU:SUB».
Следовательно, «BC» - «BRANCH IF CARRY» и «BE» - «BRANCH IF EQUAL».
Потому я и уверенно говорю, что код - дружелюбный! Конечно, если Вы решите программировать прямо дампом.
А если синтаксис ассемблера не нравится, то он легко перебивается в строчках 4160…4274, где описаны все команды. То есть, под стиль z80 достаточно потратить минут 5 и перебить 95 строк из «MOV» в «LD», сменив квадратные скобки на круглые. А также и переименовать регистры. Это - дело вкуса. Я уже сказал, что вместо эмулятора у меня получился реальный движок, в котором и 68000 можно описать шаблоном…

[I]P.S.: Вы не внимательно читали: С самого начала я сказал, что решил попробовать сделать «перезагрузку процессоров Intel» и попытаться сделать так, каким мог быть сам i8080, а i8086 был бы обратно совместимым с i8080 на бинарном уровне.
Если Вы ждали чуда, то чудо здесь не найдёте: В теме я поделился опытом «перезагрузки» изначально кривой архитектуры Intel с целью 8-битное сделать 16- и 32-битным.
(Я читал документацию по z280 и ужаснулся тем же костылям, что сделали и с i8086, когда «за уши» тянули его в IA-32 и в IA-64…
В IA-32 поддержка IA-16 почти искусственна в самом ядре. В моём x80 32-бит нет технически, но они поддерживаются уже в принципе…)

Hunta
15.05.2020, 16:40
Системa команд того же z80 полна всяких исключений
Я сказал, что она замечательная? Или что надо ей следовать?


С самого начала я сказал, что решил попробовать сделать «перезагрузку процессоров Intel» и попытаться сделать так, каким мог быть сам i8080, а i8086 был бы обратно совместимым с i8080 на бинарном уровне.
Если Вы ждали чуда, то чудо здесь не найдёте: В теме я поделился опытом «перезагрузки» изначально кривой архитектуры Intel с целью 8-битное сделать 16- и 32-битным.
Я внимательно читал. И Вы сделали изначально кривое ещё более кривым.

- - - Добавлено - - -


Потому я и уверенно говорю, что код - дружелюбный! Конечно, если Вы решите программировать прямо дампом.


Где «A4»
ADD 4
Вот и вся дружелюбность.


Потому и система команд изначально у меня и сформировалась по принципу «сам код - и есть мнемоника.
Поэтому это Вам привычно. А другим сходу будет нихера не понятно.
Пример понятного

MOV R0, R1
ADD R0, R1

Можете не отвечать, это было моё последнее сообщение здесь.

Радио-86РК
15.05.2020, 20:47
Можете не отвечать, это было моё последнее сообщение здесь.Тeм не менее, я отвечу, как минимум для тех, кто думает так же, но не ставит крест на интересе к данной теме…

Поэтому это Вам привычно. А другим сходу будет нихера не понятно.
Пример понятногоЗдесь критикуете именно синтаксис, так как в RISC-архитектурах традиционно и регистры не именуются, а индексируются. Так поступили и в IA-64 вводом регистров R8…R15.
Однако, здесь важно внимательнее присмотреться к примеру:
A4 7F|MOV R4,0x7F
55 A4 7F|MOV R4,[P5+0x7F]
E6 55 A4 7F|MOV R4,[P5+R6+0x7F]Причём, в исходниках это прямо так и указано:
// Register descriptions
// Pointers
P1 BP BP BP
P2 SI SI SI
P3 DI DI DI
P4 SP SP SP
P5 BX BX DX
P6 CX CX CX
P7 DX DX DX

// Regular
R0 [BX] _BX_ [BX]
R1 BH BH BH
R2 CH CH CH
R3 DH DH DH
R4 AL AL AL
R5 BL BL BL
R6 CL CL CL
R7 DL DL DLТем самым, в эмуляторе синтаксис «ALU7 R4,R0» заменяется на «CMP AL,[BX]». И алгоритм там прорабатывался несколько лет /!\, чтобы индексы регистров привести к Intel-стилю и АЛУ-код представить именами операций.

Потому и код
MOV R0, R1
ADD R0, R1изначально генерируется, но я приложил максимум усилий и трюков JavaScript с регулярными выражениями, чтобы нигде не чувствовался привкус RISC.

В этом плане, моя система команд не хуже того же байт-кода Java-машины. Но, если Java-апплет голым дампом вручную очень сложно набить, то как виртуальная байт-машина мой x80 всё же на порядок дружелюбнее!

Кстати, сейчас добавил пару строчек для экспорта шаблона…
Как результат, вот дешифратор всех команд на:
// 18b'0XX_0XX_0000_0000_0000:
if(0x0000 == ($IC & 0x4FFF)} {
// HLT
(CR(0,CR(0)|128)),_.EV = DO_ACCLAIM;
} else
// 18b'XXX_1XX_0000_0000_0000:
if(0x4000 == ($IC & 0x4FFF)} {
// PREFIX SUPER
return 0;
} else
// 18b'1XX_XXX_0000_0XXX_0XXX:
if(0x0000 == ($IC & 0x0F88)} {
// PREFIX R$X/P$Y
return 0;
} else
// 18b'XXX_X00_0XXX_0000_0000:
if(0x0000 == ($IC & 0x38FF)} {
// HLT R$Z
FH($Z | 0);
} else
// 18b'111_X00_0XXX_0XXX_0XXX:
if(0x8000 == ($IC & 0xB888)} {
// HLT P$Z/$Z
FH($Z | 8);
} else
// 18b'XXX_X00_0100_0000_0000:
if(0x0400 == ($IC & 0x3FFF)} {
// .$Y$X
return 0;
} else
// 18b'XXX_X00_1000_0000_0000:
if(0x0800 == ($IC & 0x3FFF)} {
// .$Y$X
return 0;
} else
// 18b'XXX_X00_1000_0XXX_0000:
if(0x0800 == ($IC & 0x3F8F)} {
// MOV [0],R$Y
CR(0,R$Y())+ FL(0),_.IE=0;
} else
// 18b'XXX_X10_0100_0XXX_0000:
if(0x2400 == ($IC & 0x3F8F)} {
// .$Y$X
return 0;
} else
// 18b'XXX_X10_1000_0XXX_0000:
if(0x2800 == ($IC & 0x3F8F)} {
// .$Y$X
return 0;
} else
// 18b'XXX_X10_0100_0000_0XXX:
if(0x2400 == ($IC & 0x3FF8)} {
// MOV R$X,[$Y]
R$X(CR($Y))+ FL(0),_.IE=0;
} else
// 18b'1XX_X10_0100_0XXX_0XXX:
if(0x2400 == ($IC & 0x3F88)} {
// MOV R$X,[R$Y]
R$X(CTX(R$Y()))+ FL(0),_.IE=0;
} else
// 18b'XXX_X10_0100_0XXX_0XXX:
if(0x2400 == ($IC & 0x3F88)} {
// MOV [R$X],R$Y
CTX(R$X(), R$Y())+ FL(0),_.IE=0;
} else
// 18b'101_X00_0XXX_0XXX_0XXX:
if(0x8000 == ($IC & 0xB888)} {
// XCHG R$Z,R$Y
$1=R$Z(),R$Z(R$Y()),R$Y($1);
} else
// 18b'110_X00_0XXX_0XXX_0XXX:
if(0x0000 == ($IC & 0xB888)} {
// XCHG P$Z,P$Y
$1=P$Z(),P$Z(P$Y()),P$Y($1);
} else
// 18b'XXX_X11_X100_0XXX_0000:
if(0x3400 == ($IC & 0x378F)} {
// .$Y$X
return 0;
} else
// 18b'XXX_X11_X100_0000_0XXX:
if(0x3400 == ($IC & 0x37F8)} {
// .$Y$X
return 0;
} else
// 18b'1XX_X11_X100_0XXX_0XXX:
if(0x3400 == ($IC & 0x3788)} {
// IN R$X
R$X(PORT(R$X()));
} else
// 18b'XXX_X11_X100_0XXX_0XXX:
if(0x3400 == ($IC & 0x3788)} {
// OUT R$X,R$Y
PORT(R$X(),R$Y());
} else
// 18b'XXX_XXX_0100_0XXX_1XXX:
if(0x0408 == ($IC & 0x0F88)} {
// BIT R$X,$Y
$1=FL(),FL($1&0xFE)|((R$X()>>$Y)&1),R$X(~(~R$X()|(1<<$Y)))/*>*/;
} else
// 18b'0XX_X00_0000_0XXX_0XXX:
if(0x0000 == ($IC & 0x3F88)} {
// MOV R$X,R$Y
R$X(R$Y());
} else
// 18b'XXX_X00_0XXX_0000_0XXX:
if(0x0000 == ($IC & 0x38F8)} {
// MOV R$X,[$Z]
R$X(CR($Z));
} else
// 18b'XXX_X00_0XXX_0XXX_0000:
if(0x0000 == ($IC & 0x388F)} {
// MOV [$Z],R$Y
CR($Z,R$Y());
} else
// 18b'0XX_X00_0100_0XXX_0XXX:
if(0x0400 == ($IC & 0x3F88)} {
// MOV P$X,P$Y
P$X(P$Y());
} else
// 18b'XXX_X10_0100_0XXX_1XXX:
if(0x2408 == ($IC & 0x3F88)} {
// -- Z$Y
$1=ALU$X(DROP($Y),REG($Y)),REG($Y,$1),FL($1.hi());
} else
// 18b'XXX_XXX_0XXX_0XXX_1XXX:
if(0x0008 == ($IC & 0x0888)} {
// ALU$X Z$Z,R$Y
$1=ALU$X(Z$Z(),R$Y()),Z$Z($1),FL($1.hi());
} else
// 18b'XXX_XXX_0100_1010_1XXX:
if(0x04A8 == ($IC & 0x0FF8)} {
// ADC P$X,IB
$1=ALU$X(DROP(FH()),_.B),ACC($1),FL($1.hi());
} else
// 18b'XXX_XXX_0XXX_1010_1XXX:
if(0x00A8 == ($IC & 0x08F8)} {
// ALU$X Z$Z,IB
$1=ALU$X(Z$Z(),_.B),Z$Z($1),FL($1.hi());
} else
// 18b'XXX_X00_0XXX_100X_XXXX:
if(0x0080 == ($IC & 0x38E0)} {
// PUSH $VIB
HEAP(0x$V00 + _.B);
} else
// 18b'XXX_XXX_0000_1110_1110:
if(0x00EE == ($IC & 0x0FFF)} {
// NOP
$Z;
} else
// 18b'XXX_XXX_0XXX_1110_1110:
if(0x00EE == ($IC & 0x08FF)} {
// NOP $Z
$Z;
} else
// 18b'XXX_X0X_0000_1111_1110:
if(0x00FE == ($IC & 0x2FFF)} {
// DBG 0
HEAP(_.IP)+IP(JP(10>$T?0:1));
_.IF=true;
} else
// 18b'XXX_X0X_0000_1111_1111:
if(0x00FF == ($IC & 0x2FFF)} {
// DBG
HEAP(_.IP)+IP(JP(10>$T?0:1));
_.IF=true;
} else
// 18b'111_XXX_0000_1100_1XXX:
if(0x80C8 == ($IC & 0x8FF8)} {
// INC Q$X
Q$X(Q$X()+1);
} else
// 18b'111_XXX_0000_1101_1XXX:
if(0x80D8 == ($IC & 0x8FF8)} {
// DEC Q$X
Q$X(Q$X()-1);
} else
// 18b'XXX_X00_0000_1100_1111:
if(0x00CF == ($IC & 0x3FFF)} {
// CMC
FL(FL() ^ 2);
} else
// 18b'111_XXX_0XXX_1100_1XXX:
if(0x80C8 == ($IC & 0x88F8)} {
// ADD Q$X,P$Z
$1=Q$X()+P$Z()+(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1);
} else
// 18b'111_XXX_0XXX_1101_1XXX:
if(0x80D8 == ($IC & 0x88F8)} {
// SUB Q$X,P$Z
$1=Q$X()-P$Z()-(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1);
} else
// 18b'XXX_XXX_0000_1101_1110:
if(0x00DE == ($IC & 0x0FFF)} {
// DOZ
CND7?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
} else
// 18b'XXX_XXX_0000_1101_1111:
if(0x00DF == ($IC & 0x0FFF)} {
// DONZ
CND6?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
} else
// 18b'XXX_XXX_0XXX_1101_111X:
if(0x00DE == ($IC & 0x08FE)} {
// ---
return 0;
} else
// 18b'XXX_XXX_0100_110X_1XXX:
if(0x04C8 == ($IC & 0x0FE8)} {
// ---
$1=ACC(ALU$W(ACC())),FL($1.hi());
} else
// 18b'XXX_XXX_0XXX_1100_1110:
if(0x00CE == ($IC & 0x08FF)} {
// ALU1F Z$Z
$1=Z$Z(ALU1F(Z$Z())),FL($1.hi());
} else
// 18b'XXX_XXX_0XXX_110X_1XXX:
if(0x00C8 == ($IC & 0x08E8)} {
// ALU$W Z$Z
$1=Z$Z(ALU$W(Z$Z())),FL($1.hi());
} else
// 18b'XXX_X00_0000_1010_0XXX:
if(0x00A0 == ($IC & 0x3FF8)} {
// MOV R$X,IB
R$X(_.B);
} else
// 18b'XXX_X00_X100_1011_0000:
if(0x04B0 == ($IC & 0x37FF)} {
// PUSH $+IB
HEAP(IP()+_.A);
} else
// 18b'XXX_X0X_0000_1011_0XXX:
if(0x00B0 == ($IC & 0x2FF8)} {
// CCND$X $+IB
CND$X?HEAP(IP())+IP(IP()+_.A):0;
_.IF=true;
} else
// 18b'XXX_XXX_0000_1100_0XXX:
if(0x00C0 == ($IC & 0x0FF8)} {
// INC R$X
$1=ADD(R$X(),1),R$X($1),FL($1.hi());
} else
// 18b'XXX_XXX_0000_1101_0XXX:
if(0x00D0 == ($IC & 0x0FF8)} {
// DEC R$X
$1=SUB(R$X(),1),R$X($1),FL($1.hi());
} else
// 18b'XXX_XXX_0XXX_1100_0XXX:
if(0x00C0 == ($IC & 0x08F8)} {
// ADD P$Z,R$X
$1=(P$Z()+R$X()),P$X($1),FL($1.hi());
} else
// 18b'XXX_XXX_0XXX_1101_0XXX:
if(0x00D0 == ($IC & 0x08F8)} {
// SUB P$Z,R$X
$1=(P$Z()+R$X()),P$X($1),FL($1.hi());
} else
// 18b'XXX_XXX_0XXX_1101_0XXX:
if(0x00D0 == ($IC & 0x08F8)} {
// DEC R$X
$1=SUB(R$X(),1),R$X($1),FL($1.hi());
} else
// 18b'XXX_X00_0XXX_1010_0000:
if(0x00A0 == ($IC & 0x38FF)} {
// POP [P$Z+IB]
DW(P$Z()+_.C,HEAP());
} else
// 18b'XXX_X00_0XXX_1010_0XXX:
if(0x00A0 == ($IC & 0x38F8)} {
// MOV R$X,[P$Z+IB]
R$X(DB(P$Z()+_.C));
} else
// 18b'XXX_X00_111X_1011_0000:
if(0x0EB0 == ($IC & 0x3EFF)} {
// PUSH [P$Z+IB]
HEAP(DW(P$Z()+_.C));
} else
// 18b'XXX_X00_0XXX_1011_0000:
if(0x00B0 == ($IC & 0x38FF)} {
// PUSH [P$Z+IB]
HEAP(DW(P$Z()+_.C));
} else
// 18b'XXX_X00_0XXX_1011_0XXX:
if(0x00B0 == ($IC & 0x38F8)} {
// MOV [P$Z+IB],R$X
DB(P$Z()+_.C,R$X());
} else
// 18b'XXX_X10_0000_1010_0XXX:
if(0x20A0 == ($IC & 0x3FF8)} {
// --- IB
return 0;
} else
// 18b'XXX_X10_0000_1011_0XXX:
if(0x20B0 == ($IC & 0x3FF8)} {
// --- IB
return 0;
} else
// 18b'XXX_X10_0XXX_1010_0XXX:
if(0x20A0 == ($IC & 0x38F8)} {
// MOV R$X,[P$Z+ACC+IB]
R$X(DB(P$Z()+ACC()+_.C)),FL(0),_.IE=0;
} else
// 18b'XXX_X10_0XXX_1011_0XXX:
if(0x20B0 == ($IC & 0x38F8)} {
// MOV [P$Z+ACC+IB],R$X
DB(P$Z()+ACC()+_.C,R$X()),FL(0),_.IE=0;
} else
// 18b'XXX_XXX_X100_1011_1XXX:
if(0x04B8 == ($IC & 0x07F8)} {
// --- IB
return 0;
} else
// 18b'XXX_X00_X100_1011_1010:
if(0x04BA == ($IC & 0x37FF)} {
// LEA +IB
DST(DST()+_.B);
} else
// 18b'XXX_X00_X100_1011_1XXX:
if(0x04B8 == ($IC & 0x37F8)} {
// MOV [U$X],IB
DB(U$X(),_.B);
} else
// 18b'XXX_X00_1110_1011_1000:
if(0x0EB8 == ($IC & 0x3FFF)} {
// WAIT
FL((FL() & 0x02) | 0x0D),trace.expression=0;
} else
// 18b'XXX_X00_1111_1011_1000:
if(0x0FB8 == ($IC & 0x3FFF)} {
// RET
IP(HEAP());
} else
// 18b'XXX_X0X_0XXX_1011_1000:
if(0x00B8 == ($IC & 0x28FF)} {
// JMP $+$UIB
IP(IP()+_.A);
_.IF=true;
} else
// 18b'XXX_XXX_0XXX_1011_1XXX:
if(0x00B8 == ($IC & 0x08F8)} {
// JCND$X $+$UIB
CND$X?IP(IP()+_.A):0;
_.IF=true;
} else
// 18b'XXX_XXX_1111_1011_1XXX:
if(0x0FB8 == ($IC & 0x0FF8)} {
// RCND$X
CND$X?IP(HEAP()):0;
} else
// 18b'1X1_X00_0000_1110_1XXX:
if(0x80E8 == ($IC & 0xBFF8)} {
// PUSH U$X
HEAP(U$X());
} else
// 18b'1X1_X00_0000_1111_1XXX:
if(0x80F8 == ($IC & 0xBFF8)} {
// POP U$X
U$X(HEAP());
} else
// 18b'XXX_X00_XXXX_1110_1111:
if(0x00EF == ($IC & 0x30FF)} {
// XCHG P$Z,[SP]
$1=P$Z(),P$Z(DW(SP())), DW(SP(), $1);
} else
// 18b'XXX_X00_0000_1110_0000:
if(0x00E0 == ($IC & 0x3FFF)} {
// SKIP
FH(1 | 8), FL((FL() & 0x02) | 0x05);
} else
// 18b'XXX_X10_0000_1110_0000:
if(0x20E0 == ($IC & 0x3FFF)} {
// SKIP ACC
FH(1 | 8), FL((FL() & 0x02) | 0x05);
} else
// 18b'XXX_X00_0000_1110_0XXX:
if(0x00E0 == ($IC & 0x3FF8)} {
// LOOP $X/R$X
FH($X | 8), FL((FL() & 0x02) | 0x09);
} else
// 18b'XXX_X00_0000_1110_1000:
if(0x00E8 == ($IC & 0x3FFF)} {
// DOC
CND5?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
} else
// 18b'XXX_X00_0000_1110_1001:
if(0x00E9 == ($IC & 0x3FFF)} {
// DONC
CND4?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
} else
// 18b'XXX_X00_0XXX_1110_1011:
if(0x00EB == ($IC & 0x38FF)} {
// LOOP [R$Z]
FH(R$Z()|8),FL((FL() & 0x02) | 0x09);
} else
// 18b'XXX_X00_0XXX_1110_1100:
if(0x00EC == ($IC & 0x38FF)} {
// LOOP R$Z
FH($Z), FL((FL() & 0x02) | 0x09);
} else
// 18b'XXX_X00_0XXX_1111_1011:
if(0x00FB == ($IC & 0x38FF)} {
// SKIP [R$Z]
FH(R$Z()|8),FL((FL() & 0x02) | 0x05);
} else
// 18b'XXX_X00_0XXX_1111_1100:
if(0x00FC == ($IC & 0x38FF)} {
// SKIP R$Z
FH($Z), FL((FL() & 0x02) | 0x05);
} else
// 18b'XXX_X00_0XXX_1111_1101:
if(0x00FD == ($IC & 0x38FF)} {
// SKIP $Z
FH($Z | 8), FL((FL() & 0x02) | 0x05);
} else
// 18b'100_X0X_0XXX_1111_XXXX:
if(0x00F0 == ($IC & 0xA8F0)} {
// INT $T
HEAP(_.IP)+IP(JP(10>$T?0:1));
_.IF=true;
} else
// 18b'XXX_XXX_1000_10XX_XXXX:
if(0x0880 == ($IC & 0x0FC0)} {
// Y$Y_X$X IB
return 0;
} else
// 18b'XXX_XXX_XXXX_XXXX_XXXX:
if(0x0000 == ($IC & 0x0000)} {
// Y$Y_X$X ($M)
0;
}Или на System Verilog:
case(IC)
18b'0XX_0XX_0000_0000_0000: // HLT
//(CR(0,CR(0)|128)),_.EV = DO_ACCLAIM;
18b'XXX_1XX_0000_0000_0000: // PREFIX SUPER
//return 0;
18b'1XX_XXX_0000_0XXX_0XXX: // PREFIX R$X/P$Y
//return 0;
18b'XXX_X00_0XXX_0000_0000: // HLT R$Z
//FH($Z | 0);
18b'111_X00_0XXX_0XXX_0XXX: // HLT P$Z/$Z
//FH($Z | 8);
18b'XXX_X00_0100_0000_0000: // .$Y$X
//return 0;
18b'XXX_X00_1000_0000_0000: // .$Y$X
//return 0;
18b'XXX_X00_1000_0XXX_0000: // MOV [0],R$Y
//CR(0,R$Y())+ FL(0),_.IE=0;
18b'XXX_X10_0100_0XXX_0000: // .$Y$X
//return 0;
18b'XXX_X10_1000_0XXX_0000: // .$Y$X
//return 0;
18b'XXX_X10_0100_0000_0XXX: // MOV R$X,[$Y]
//R$X(CR($Y))+ FL(0),_.IE=0;
18b'1XX_X10_0100_0XXX_0XXX: // MOV R$X,[R$Y]
//R$X(CTX(R$Y()))+ FL(0),_.IE=0;
18b'XXX_X10_0100_0XXX_0XXX: // MOV [R$X],R$Y
//CTX(R$X(), R$Y())+ FL(0),_.IE=0;
18b'101_X00_0XXX_0XXX_0XXX: // XCHG R$Z,R$Y
//$1=R$Z(),R$Z(R$Y()),R$Y($1);
18b'110_X00_0XXX_0XXX_0XXX: // XCHG P$Z,P$Y
//$1=P$Z(),P$Z(P$Y()),P$Y($1);
18b'XXX_X11_X100_0XXX_0000: // .$Y$X
//return 0;
18b'XXX_X11_X100_0000_0XXX: // .$Y$X
//return 0;
18b'1XX_X11_X100_0XXX_0XXX: // IN R$X
//R$X(PORT(R$X()));
18b'XXX_X11_X100_0XXX_0XXX: // OUT R$X,R$Y
//PORT(R$X(),R$Y());
18b'XXX_XXX_0100_0XXX_1XXX: // BIT R$X,$Y
//$1=FL(),FL($1&0xFE)|((R$X()>>$Y)&1),R$X(~(~R$X()|(1<<$Y)))/*>*/;
18b'0XX_X00_0000_0XXX_0XXX: // MOV R$X,R$Y
//R$X(R$Y());
18b'XXX_X00_0XXX_0000_0XXX: // MOV R$X,[$Z]
//R$X(CR($Z));
18b'XXX_X00_0XXX_0XXX_0000: // MOV [$Z],R$Y
//CR($Z,R$Y());
18b'0XX_X00_0100_0XXX_0XXX: // MOV P$X,P$Y
//P$X(P$Y());
18b'XXX_X10_0100_0XXX_1XXX: // -- Z$Y
//$1=ALU$X(DROP($Y),REG($Y)),REG($Y,$1),FL($1.hi());
18b'XXX_XXX_0XXX_0XXX_1XXX: // ALU$X Z$Z,R$Y
//$1=ALU$X(Z$Z(),R$Y()),Z$Z($1),FL($1.hi());
18b'XXX_XXX_0100_1010_1XXX: // ADC P$X,IB
//$1=ALU$X(DROP(FH()),_.B),ACC($1),FL($1.hi());
18b'XXX_XXX_0XXX_1010_1XXX: // ALU$X Z$Z,IB
//$1=ALU$X(Z$Z(),_.B),Z$Z($1),FL($1.hi());
18b'XXX_X00_0XXX_100X_XXXX: // PUSH $VIB
//HEAP(0x$V00 + _.B);
18b'XXX_XXX_0000_1110_1110: // NOP
//$Z;
18b'XXX_XXX_0XXX_1110_1110: // NOP $Z
//$Z;
18b'XXX_X0X_0000_1111_1110: // DBG 0
//HEAP(_.IP)+IP(JP(10>$T?0:1));
//_.IF=true;
18b'XXX_X0X_0000_1111_1111: // DBG
//HEAP(_.IP)+IP(JP(10>$T?0:1));
//_.IF=true;
18b'111_XXX_0000_1100_1XXX: // INC Q$X
//Q$X(Q$X()+1);
18b'111_XXX_0000_1101_1XXX: // DEC Q$X
//Q$X(Q$X()-1);
18b'XXX_X00_0000_1100_1111: // CMC
//FL(FL() ^ 2);
18b'111_XXX_0XXX_1100_1XXX: // ADD Q$X,P$Z
//$1=Q$X()+P$Z()+(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1);
18b'111_XXX_0XXX_1101_1XXX: // SUB Q$X,P$Z
//$1=Q$X()-P$Z()-(_CF?0:0),$2=($1>>15)&2,FL((FL()& 0xD)|$2), Q$X($1);
18b'XXX_XXX_0000_1101_1110: // DOZ
//CND7?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
18b'XXX_XXX_0000_1101_1111: // DONZ
//CND6?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
18b'XXX_XXX_0XXX_1101_111X: // ---
//return 0;
18b'XXX_XXX_0100_110X_1XXX: // ---
//$1=ACC(ALU$W(ACC())),FL($1.hi());
18b'XXX_XXX_0XXX_1100_1110: // ALU1F Z$Z
//$1=Z$Z(ALU1F(Z$Z())),FL($1.hi());
18b'XXX_XXX_0XXX_110X_1XXX: // ALU$W Z$Z
//$1=Z$Z(ALU$W(Z$Z())),FL($1.hi());
18b'XXX_X00_0000_1010_0XXX: // MOV R$X,IB
//R$X(_.B);
18b'XXX_X00_X100_1011_0000: // PUSH $+IB
//HEAP(IP()+_.A);
18b'XXX_X0X_0000_1011_0XXX: // CCND$X $+IB
//CND$X?HEAP(IP())+IP(IP()+_.A):0;
//_.IF=true;
18b'XXX_XXX_0000_1100_0XXX: // INC R$X
//$1=ADD(R$X(),1),R$X($1),FL($1.hi());
18b'XXX_XXX_0000_1101_0XXX: // DEC R$X
//$1=SUB(R$X(),1),R$X($1),FL($1.hi());
18b'XXX_XXX_0XXX_1100_0XXX: // ADD P$Z,R$X
//$1=(P$Z()+R$X()),P$X($1),FL($1.hi());
18b'XXX_XXX_0XXX_1101_0XXX: // SUB P$Z,R$X
//$1=(P$Z()+R$X()),P$X($1),FL($1.hi());
18b'XXX_XXX_0XXX_1101_0XXX: // DEC R$X
//$1=SUB(R$X(),1),R$X($1),FL($1.hi());
18b'XXX_X00_0XXX_1010_0000: // POP [P$Z+IB]
//DW(P$Z()+_.C,HEAP());
18b'XXX_X00_0XXX_1010_0XXX: // MOV R$X,[P$Z+IB]
//R$X(DB(P$Z()+_.C));
18b'XXX_X00_111X_1011_0000: // PUSH [P$Z+IB]
//HEAP(DW(P$Z()+_.C));
18b'XXX_X00_0XXX_1011_0000: // PUSH [P$Z+IB]
//HEAP(DW(P$Z()+_.C));
18b'XXX_X00_0XXX_1011_0XXX: // MOV [P$Z+IB],R$X
//DB(P$Z()+_.C,R$X());
18b'XXX_X10_0000_1010_0XXX: // --- IB
//return 0;
18b'XXX_X10_0000_1011_0XXX: // --- IB
//return 0;
18b'XXX_X10_0XXX_1010_0XXX: // MOV R$X,[P$Z+ACC+IB]
//R$X(DB(P$Z()+ACC()+_.C)),FL(0),_.IE=0;
18b'XXX_X10_0XXX_1011_0XXX: // MOV [P$Z+ACC+IB],R$X
//DB(P$Z()+ACC()+_.C,R$X()),FL(0),_.IE=0;
18b'XXX_XXX_X100_1011_1XXX: // --- IB
//return 0;
18b'XXX_X00_X100_1011_1010: // LEA +IB
//DST(DST()+_.B);
18b'XXX_X00_X100_1011_1XXX: // MOV [U$X],IB
//DB(U$X(),_.B);
18b'XXX_X00_1110_1011_1000: // WAIT
//FL((FL() & 0x02) | 0x0D),trace.expression=0;
18b'XXX_X00_1111_1011_1000: // RET
//IP(HEAP());
18b'XXX_X0X_0XXX_1011_1000: // JMP $+$UIB
//IP(IP()+_.A);
//_.IF=true;
18b'XXX_XXX_0XXX_1011_1XXX: // JCND$X $+$UIB
//CND$X?IP(IP()+_.A):0;
//_.IF=true;
18b'XXX_XXX_1111_1011_1XXX: // RCND$X
//CND$X?IP(HEAP()):0;
18b'1X1_X00_0000_1110_1XXX: // PUSH U$X
//HEAP(U$X());
18b'1X1_X00_0000_1111_1XXX: // POP U$X
//U$X(HEAP());
18b'XXX_X00_XXXX_1110_1111: // XCHG P$Z,[SP]
//$1=P$Z(),P$Z(DW(SP())), DW(SP(), $1);
18b'XXX_X00_0000_1110_0000: // SKIP
//FH(1 | 8), FL((FL() & 0x02) | 0x05);
18b'XXX_X10_0000_1110_0000: // SKIP ACC
//FH(1 | 8), FL((FL() & 0x02) | 0x05);
18b'XXX_X00_0000_1110_0XXX: // LOOP $X/R$X
//FH($X | 8), FL((FL() & 0x02) | 0x09);
18b'XXX_X00_0000_1110_1000: // DOC
//CND5?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
18b'XXX_X00_0000_1110_1001: // DONC
//CND4?(FH(1 | 8), FL((FL() & 0x02) | 0x05)):0;
18b'XXX_X00_0XXX_1110_1011: // LOOP [R$Z]
//FH(R$Z()|8),FL((FL() & 0x02) | 0x09);
18b'XXX_X00_0XXX_1110_1100: // LOOP R$Z
//FH($Z), FL((FL() & 0x02) | 0x09);
18b'XXX_X00_0XXX_1111_1011: // SKIP [R$Z]
//FH(R$Z()|8),FL((FL() & 0x02) | 0x05);
18b'XXX_X00_0XXX_1111_1100: // SKIP R$Z
//FH($Z), FL((FL() & 0x02) | 0x05);
18b'XXX_X00_0XXX_1111_1101: // SKIP $Z
//FH($Z | 8), FL((FL() & 0x02) | 0x05);
18b'100_X0X_0XXX_1111_XXXX: // INT $T
//HEAP(_.IP)+IP(JP(10>$T?0:1));
//_.IF=true;
18b'XXX_XXX_1000_10XX_XXXX: // Y$Y_X$X IB
//return 0;
18b'XXX_XXX_XXXX_XXXX_XXXX: // Y$Y_X$X ($M)
//0;
Естественно, это лишь примерный набросок / скелет, по которому уже нужно, так или иначе, описывать алгоритм работы каждой операции.
(Хотя, знатоки JavaScript уже поняли, что «R$X(…)» синтаксически легальна и может учитывать «X» как младшие 3 бита кода инструкции. Тем самым, немного пошаманив, можно допилить эмулятор так, чтобы всё работало именно как и описано в шаблоне - без всяких конвертаций «R$X()» -> «R4()» -> «AL()», что занимает уйму времени при открытии эмулятора.
Просто многие фишки JavaScript я не знал на момент разработки эмулятора и не догадался их использовать…)

Естественно, это значительно упростит в дальнейшем разработку, так как от порядка описания команд зависит вся работа в целом и нельзя перепутать местами несколько условий из-за строжайшего мажоритарного приоритета.
(В LogiSim-модели я немало мучался с индексированием инструкций, так как вручную тяжело придерживаться нужного логического порядка кодирования их…)

P.S.: Чтобы было легче проникнуться затеей, относитесь к ней к подобию виртуальной Java-машины с дружественным байт-кодом и легко реализуемой в FPGA или ТТЛ.
(В отличии от Java-процессора, который разрабатывали монстры индустрии и так до конца не справились с изначально поставленной задачей. Хоть первоначально и нацеливались на аппаратную реализацию с конкуренцией с Intel. Здесь я ни с кем конкурировать не собираюсь и систему команд продумываю без оглядки на ограничения в FPGA/ТТЛ. Хоть и реализация на ТТЛ-рассыпухие в перспективе и предусматривается…)

b2m
16.05.2020, 13:00
Пример понятного

MOV R0, R1

Ага, очень понятно: из R1 в R0 записать, или наоборот :)

Hunta
16.05.2020, 13:14
Ага, очень понятно: из R1 в R0 записать, или наоборот
А это зависит от того, кто смотрит - пидипишник или кто другой :) Но даже в этом случае понятней, чем извращение A4 - LOAD R4
К тому же у PDP - MOV R0, R1 - move r0 to r1 выглядит логичней, чем в варианте move r1 to r0 - скользим слева направо взглядом - и всё выглядит логичным.

andrews
16.05.2020, 13:15
Тогда надо (from to) FT R1,R0 и если аккумулятор один FT R1, а указателей памяти если два FT M1,M0. Если же аккумулятором могут быть все регистры FTA R1,R0 R1+R0->R0
FTS R1,R0 R1-R0->R0 FTSJZ IF( R1-R0=0) JMP адрес.
С "аккумулятором" же дополнительно можно выполнять умножение и деление.
В общем с архитектурами 8008, 8080 можно экспериментировать сколько угодно за счет того, что не все 256 кодов операций задействовано

b2m
16.05.2020, 13:34
move r0 to r1 выглядит логичней
move to r0 from r1 тоже логично

Hunta
16.05.2020, 13:39
Не фига - придётся или запоминать - куда перемещаем, или взглядом возвращаться - прерывается плавность восприятия. Это примерно как в немецком, где отрицание ставится в конце - радостно так - Вы здоровы - а потом хлобысь - думаете вы

- - - Добавлено - - -

Логичней выглядит так R1 := R0 - куда - операция - что

b2m
16.05.2020, 13:44
Логичней выглядит так R1 := R0 - куда - операция - что
Ну или так. Главное, куда - это налево :)

Hunta
16.05.2020, 13:46
Дело, конечно, привычки, но язык ассемблера PDP-11 выглядит гораздо продуманней и дружественней для программиста. Когда я с ним столкнулся (после Фортрана) - мне хватило пяти минут, что бы въехать в принцип, а дальше было дело только в том, что бы запомнить редкие(!) команды, потому что часто использовавшиеся легли сразу. И помню, когда начал читать про язык ассемблера для XT - первая мысль - мля, как это всё в памяти удержать. В этом плане система команд 8080 (с ней столкнулся раньше XT) была даже понятней, хотя и не настолько логичней, как у PDP-11

- - - Добавлено - - -


Ну или так. Главное, куда - это налево
Главное - плавность восприятия, а не скакание по тексту вперёд назад

- - - Добавлено - - -

Именно поэтому пакет макросов для ассемблера PDP-11 воспринялся сразу, несмотря на то, что там

MOV R0, R1

выглядит как

LET R1 := R0

b2m
16.05.2020, 13:50
Когда я начинал (на 8080), я вообще без мнемоник писал - прямо кодами ;)

- - - Добавлено - - -

Пишешь процедуру в хексе, а после неё несколько нулей, на случай если её исправлять придется. Во как.

Hunta
16.05.2020, 13:58
Система команд PDP-11 тоже хорошо ложится на коды, только восьмеричные. Сейчас вожусь с отладкой FPGA части, в принципе, более сложный код можно прям в FPGA RAM|ROM загнать, но есть пульт - и не слишком сложное прям из головы в пульт, даже на бумаге не пишу. И да - шпаргалки по командам под рукой нет :)

andrews
16.05.2020, 14:05
Когда я начинал (на 8080), я вообще без мнемоник писал - прямо кодами ;)

- - - Добавлено - - -

Пишешь процедуру в хексе, а после неё несколько нулей, на случай если её исправлять придется. Во как.
а у меня на МСУВТ В7 пультовом мониторе по другому вообще никак нельзя было ввести программу при открывании из коробки с завода. Чтобы подключить кассетный магнитофон пришлось колдовать над схемой 8251, а набивать ленту на телетайпе РТА-80 тоже еще-то удовольствие. Особенно весело было перемещать код вручную с заменой всех адресов на бумаге( из головы не получалось). И еще вывод текста на семисегментном индикаторе веселое занятие.

- - - Добавлено - - -


Система команд PDP-11 тоже хорошо ложится на коды, только восьмеричные. Сейчас вожусь с отладкой FPGA части, в принципе, более сложный код можно прям в FPGA RAM|ROM загнать, но есть пульт - и не слишком сложное прям из головы в пульт, даже на бумаге не пишу. И да - шпаргалки по командам под рукой нет :)
в 23 года я запомнил все коды команд 8080 где-то через 3 месяца тырканья на пультовом мониторе( мембранная клавиатура+8 семисегментных индикаторов), но если бы и кнопок не было и пульт как у СМ-4, то точно бы пришлось голову лечить

Hunta
16.05.2020, 14:12
и пульт как у СМ-4, то точно бы пришлось голову лечить
И и щас могу с переключателей простую прогу набрать. Типа загрузчика.

andrews
16.05.2020, 15:34
Время разное. Для пульта с шестнадцатиричными цифрами на кнопках пусть даже пластиковых мембранных вертикальных(МСУВТ В7) одно нажатие -тетрада. Адрес вводится за 3 нажатия в пределах 2Кбайт, команда 3 байтная 6 нажатий(прикосновений). У клавишного пульта СМ-4 клавиши с фиксацией( и по моему даже с 3 состояниями?), 1 манипуляция - 1бит. Набрать программу даже на десять команд уже уйма времени. А с другой стороны терминалы штатно включены в заводской конфигурации, на МСУВТ В7 фрязинский дисплей приходилось подумать куда включать и как. Да и на самом терминале нужно было выставить правильные настройки для обмена, на абы каких он за комп не цеплялся. Но потом конечно небо и земля. Для МСУВТ В7 бытовой кассетный магнитофон и ввод с/на него через монитор и никаких дисков( хотя памяти можно набрать 64к озу с затеняемым пзу, но батарею твари забыли подключить( да и на 565ру3 пришлось бы большую батарею иметь), операционка только RMX-80, а в пзу только ассемблер и строчный редактор. А на СМ-4 любые носители и под каждого пользователя индивидуальный том 5 мбайтная "кастрюля". В 1982-83 гг это реально КРУТО! Ну и систем с разными ЯВУ у наших пронырливых сисадминов было любых!

Радио-86РК
16.05.2020, 15:47
Но даже в этом случае понятней, чем извращение A4 - LOAD R4Прояснитe момент?
Почему «A4» - извращение?
Если оглядеть многие архитектуры, то зубрить машинный код нужно везде.
Понимаю, если пользователь начал с Бейсика, потом перешёл на Паскаль и дальше - в Си, то машинный код - до лампочки!
А вот потом идёт Ассемблер, когда слишком узкие места.
Но здесь не надо смотреть с высока современных достижений!

Например, если забыть про файлы, дампы и даже перфоленту, а также убрать из процессора блок автоматической выборки команд, как это было в самом начале, то можно представить нечто, как пульты прошлого века:
http://informat444.narod.ru/museum/picture/ru/besm-2.jpg
Вот тут бинарное представление команды очень сильно влияет на скорость разработки кода и количество опечаток/ошибок.

Понятно, что в RISC систему команд гуманизировать сложно. А вот CISC бинарно можно за уши притянуть к человеку.
Раз критика сосредоточилась вокруг кода «A4», то разберу пример с ним.

Если в 70-х популярна было восьмеричная система счисления, то в i8080 она и прослеживается:
0000…0077 - группа загрузки и инкрементов (0000 - NOP)
0100…0177 - группа команд пересылок MOV (0166 - HLT)
0200…0277 - группа операций АЛУ
0300…0377 - группа управления ходом исполнения
Система команд i8080 достаточно проста (для детей 80-х с РАДИО-86РК / ЮТ-88) и чем-то походит даже на RISC: Бывают трюки написания алгоритмов из одних однобайтовых команд в «спортивных задачах»…

У меня ушли долгие годы на переработку команд i8080, чтобы человеком машинный код читался легче.


0x12 - загрузить R1 в R2: Варианты - «T12», «MOVE R1,R2», «LD R2,R1», «MOV CH,BH»
0x1A - сложить R1 к Аккумулятору: Варианты - «ADD R1», «ADD A,R1», «ADD AL,BH»
0x1B - Вычесть R1 из Аккумулятора: Варианты - «SUB R1», «SUB A,R1», «SUB AL,BH»
0x1C - конъюнкция R1 над Аккумулятором: Варианты - «CONJUNCT R1», «AND A,R1», «AND AL,BH»
0x1D - дизъюнкция R1 с Аккумулятором: Варианты - «DISJUNCT R1», «OR A,R1», «OR AL,BH»
0x1E - эксклюзивное ИЛИ R1 с Аккумулятором: Варианты - «EOR R1», «EOR A,R1», «XOR AL,BH»
0x1F - флаги по сравнению R1 с Аккумулятором: Варианты - «SUB F,A,R1», «FLAGS A,R1», «CMP AL,BH»
0xA2 - Аккумуляция Аргумента в R2: Варианты - «APLY R2,BYTE», «ACCUMULATE R2,BYTE», «ARGUMENT R2,BYTE», «MOV R2,ARG»
0xAA - Аргумент сложить к Аккумулятору: Варианты «ADD ARG», «ADD A,ARG», «ADD AL,ARG»
0xAB - Аргумент Вычесть из Аккумулятора: Варианты - «SUB ARG», «SUB A,ARG», «SUB AL,ARG»
0xAC - конъюнкция Аргумента над Аккумулятором: Варианты - «CONJUNCT ARG», «AND A,ARG», «AND AL,ARG»
0xAD - дизъюнкция Аргумента с Аккумулятором: Варианты - «DISJUNCT ARG», «OR A,ARG», «OR AL,ARG»
0xAE - эксклюзивное ИЛИ Аргумента с Аккумулятором: Варианты - «EOR ARG», «EOR A,ARG», «XOR AL,ARG»
0xAF - флаги по сравнению Аргумента с Аккумулятором: Варианты - «SUB F,A,ARG», «FLAGS A,ARG», «CMP AL,ARG»
0xB8 - безусловное Ветвление с 8-битным смещением: Варианты - «BRANCH $±127», «JMP $±127»
0xBC - условное Ветвление по CF: Варианты - «BRCS LABEL», «BCS LABEL», «JC LABEL»
0xBE - условное Ветвление по ZF (EF): Варианты - «BREQ LABEL», «BEQ LABEL», «JE LABEL»
0xBF - условное Ветвление по Фиктивному ZF (EF): Варианты - «[B]BRNE LABEL», «BNE LABEL», «BRFE LABEL», «JNE LABEL»
0xC1 - инкремент R1: Варианты - «INC R1», «INC BH»
0xC2 - инкремент R2: Варианты - «INC R2», «INC CH»
0xC3 - инкремент R3: Варианты - «INC R3», «INC DH»
0xCB - инкремент указателя: Варианты - «INC BX»
0xCC - инкремент указателя: Варианты - «INC CX»
0xCD - инкремент указателя: Варианты - «INC DX»
0xD4 - декремент R4: Варианты - «DEC R4», «DEC AL»
0xD5 - декремент R5: Варианты - «DEC R5», «DEC BL»
0xD6 - декремент R6: Варианты - «DEC R6», «DEC CL»
0xDB - декремент указателя: Варианты - «DEC BX»
0xDC - декремент указателя: Варианты - «DEC CX»
0xDD - декремент указателя: Варианты - «DEC DX»
0xF1 - прерывание на Функцию #1: Варианты - «RST 1», «FN 1», «INT 1»
0xF2 - прерывание на Функцию #2: Варианты - «RST 2», «FN 2», «INT 2»
0xF3 - прерывание на Функцию #3: Варианты - «RST 3», «FN 3», «INT 3»
0xF9 - прерывание на Функцию #9: Варианты - «RST 9», «FN 9», «INT 9»
Тем самым, просто прочитав этот список, Вы уже научились кодировать весь машинный код x80!
Сколько времени у человека уйдёт на заучивание машинного кода любого другого процессора?
Чтобы дампом написать свою первую программу, Вам потребуются считанные минуты!
На одном форуме задумку так и обозвали - Процессор Акына: Что вижу, то и значит…
Это ли ни тот самый WYSYWYG-Процессор?

То есть, любой из Вас с лёгкостью уже может понять, что делает этот программный код:
x80: .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
0000 A1 76 A5 D0 A4 4E CB D4 BF FC 00

Z80: .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
0000 26 76 2E D0 3E 4E 23 3D 20 FC 76
P.S.: Тем самым, в своём минимальном исполнении мой x80 - тот же i8080, но с WYSYWSYG-машинным кодом.
А с другой, как я вижу, здесь критикуете именно синтаксис Ассемблера, а не мою концепцию организации системы команд…

Hunta
16.05.2020, 15:54
Если оглядеть многие архитектуры, то зубрить машинный код нужно везде.
И нахера ориентироваться на сложности?


Это ли ни тот самый WYSYWYG-Процессор?
Это лично ваше мнение.


А с другой, как я вижу, здесь критикуете именно синтаксис Ассемблера
Синтаксиса ассемблера не бывает, ассемблер - это программа, которая понимает ЯЗЫК ассемблера.
Фиговый он потому что


не мою концепцию организации системы команд
как и система команд

Lethargeek
16.05.2020, 15:58
Понятно, что в RISC систему команд гуманизировать сложно. А вот CISC бинарно можно за уши притянуть к человеку.
Непонятно. Наоборот, в рисках меньше вариантов дешифрации, проще правила.

Радио-86РК
16.05.2020, 16:35
Напримeр, данный машинный код в 80-х любой школьник мог бы усвоить на раз-два:
x80: .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
0000 A1 76 A5 D0 A4 4E CB D4 BF FC 00
Z80: .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
0000 26 76 2E D0 3E 4E 23 3D 20 FC 76

0000 A1 76:ARG R1,0x76
0002 A5 D0:ARG R5,0xD0
0004 A4 4E:ARG R4,0x4E
0006 CB :INC BX
0007 D4 :DEC R4
0008 BF FC:BRF 0x0006
000A 00 :NUL/HLT(Всё равно, что на Z80 в цикле M1 код команды пропускать через ПЗУ с таблицей перекодировки - x80 так и планировался на первых парах…)
То есть, я как любитель дампов потратил десятилетия на проработку системы команд по принципу паззла: Смысл и логику не менял, но переставлял по ячейкам таблицы команд.
Просто, если человек не хочет ради прикола программировать дампом - это личный интерес каждого…

P.S.: Я всего лишь сделал то, как было бы в древние времена, когда микроскоп украшался узорами (пруф (https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D 0%B8%D0%B9_%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D1%81%D0 %BA%D0%BE%D0%BF#%D0%98%D1%81%D1%82%D0%BE%D1%80%D0% B8%D1%8F_%D0%BC%D0%B8%D0%BA%D1%80%D0%BE%D1%81%D0%B A%D0%BE%D0%BF%D0%B0)) и радиоприёмники были украшением (пруф (https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B4%D0%B8%D0%BE%D0%BF%D1%80%D0%B8%D 1%91%D0%BC%D0%BD%D0%B8%D0%BA#%D0%9A%D0%BB%D0%B0%D1 %81%D1%81%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B 8%D1%8F_%D1%80%D0%B0%D0%B4%D0%B8%D0%BE%D0%BF%D1%80 %D0%B8%D1%91%D0%BC%D0%BD%D0%B8%D0%BA%D0%BE%D0%B2)) .
Я подошёл к принципу реорганизации таблицы команд i8080 как эстет. Не более!
За это критикуете?
(Кто-то любит систему команд по-Пикассо, а я собрал систему команд по-Вангогу!)

andrews
16.05.2020, 17:41
Проходит ли данная архитектура по "лезвию Оккама"? Для чего создается? В чём её преимущества перед другими?

Hunta
16.05.2020, 18:06
Проходит ли данная архитектура по "лезвию Оккама"?
Набор команд - это не архитектура - ни компа ни процессора. Как максимум - часть архитектуры
Для набора команд бритва Оккама - это вопрос - под какой язык создаётся система команд (с прицелом на лёгкость написания программ на этом языке).
Пока тут лёгкостью и не пахнет

- - - Добавлено - - -

В общем - классический случай - автор придумал что то под себя (причём придумывал явно не один день), у него за это время всё это хорошо отложилось в голове и памяти - и вдруг - облом - другим это таким же лёгким не кажется. А вот убедить других - уделите этому - три месяца - и вам тоже покажется лёгким и понятным - особенно современно поколение, привыкшее тратить на освоение нового (язык С за 24 часа) минимум времени, а если не получается - нахнах - ну вот никак - все такие упёртые и не хотят увидеть Брульянт.

В целом, как я уже сказал и судя по комментам - впечатлить пока не удалось.

Радио-86РК
16.05.2020, 18:39
В чём её преимущества перед другими?Кaк выше я и сказал: x80 - архитектура i8080, но с красивой таблицей команд.
Тем самым, преимущество, в первую очередь, именно в красоте.
А так как я никаким боком не инженер, то просто реинженерю i8080. Сначала я переделал известный (http://rk86.ru/) эмулятор и переписывался с его автором. В его эмуляторе я просто добавил «case 0x40: case 0x49: case 0x52: …», то есть все холостые MOV-пересылки: mov b,b; mov c,c; mov d,d и т.д…
И эти холостые MOV я превратил в префиксы, чтобы код «40 86» работал как «add b,m» без участия аккумулятора.

Кто-то сказал, что идея - не плохая, так как куролесица с аккумуляторным АЛУ жутко напрягала. Но, на кристалле это выполнить в 70-е невозможно. Слишком дорого бы обошлось перехватывать коды холостых MOV. Потому обошлись инженеры лишь тем, что «mov m,m» превратили в «hlt».
Для чего создается?Чисто из интереса!
Сначала я пробовал накидать схему перехвата MOV-префиксов, чтобы проверить, правда ли сложно?
Потом решил причесать таблицу команд и вскоре понял, что переделывать эмулятор перебивкой сотен case каждый раз - очень тяжело.
Написал свой эмулятор с генератором команд по шаблону.
Так и «mov m,m» (hlt) переместился в позицию 00 и я начал активно прорабатывать идею уже как отдельную архитектуру.

Я выбросил все команды с адресом: «ld sp,addr», «ld hl,addr», «ld bc,addr», «ld de,addr», «ld a,addr», «ld a,(addr)», «ld hl,(addr)», «ld (addr),a», «ld (addr),hl» и «jp addr».
Если в мою таблицу вглядеться внимательнее, то по-своему - это совершенный i8080, каким он мог быть в 70-е с самого начала…
Система команд более ортогональна, чем у z80, так как префиксами там достигается вся гибкость почти уровня i8086.
Проходит ли данная архитектура по "лезвию Оккама"?С трудом догадываюсь, в чём вопрос.
Если не обращать внимания на префиксы, то x80 - тот же i8080, но, как выше сказал, без команд с кодами 01, 11, 21, 22, 2A, 31, 32, 3A, C2, C3, C4, CA, CC, D2, D4, DA, D4, E2, E4, EA, EC, F2, F4, FA, FC.
А так же и без кодов C0, C8, D0, D8, E0, E8, F0, F8 и D3, DB, F3, FB, 09, 19, 29, 39.
То есть, слишком редуцированный i8080, так как все те команды доступны уже через префикс.
Не проверял, проходит ли тест по Тьюрингу мой процессор в этом случае, так как схематически получается гораздо проще i8080 в реализации собачником.

По теме
Тему можно было назвать «i8080/8086 - перезагрузка!», так как я именно занимаюсь перезагрузкой этих архитектур, как Вы уже поняли.
Это как из i8086 вытрясти все 16-битные команды и сделать ремейк i8080, который может выполнять программы i8086.
То есть, из 16-битного i8086 сделать 8-битник (не i8088).
(А не гибрид типа NEC V20 (https://ru.wikipedia.org/wiki/NEC_V20)…)

Регистровый файл
Все регистры у аппаратного x80 должны быть во внешнем регистровом файле в виде статического ОЗУ.
Тем самым, даже команда «NOP» будет занимать десятки тактов из-за активного доступа к внешней статике.
То есть, сначала прочитать младший байт регистра адреса команды IP, затем - старший байт. Уже 4 такта.
Затем, выдать IP на шину адреса, прочитать код команды - ещё 8 тактов.
Потом выполнить инкремент IP и записать его в статику - ещё 12 тактов.

Как видите, прототип x80 в FPGA или ТТЛ будет очень медленным.
Здесь в пору заметить: Если Вы ждёте от прототипа x80 супер скорости, можете выходить из темы…

Резюме
Цель: Перезагрузить саму систему команд i8080, чтобы она могла в последствии стать 32-битной или 64-битной.
Причём, совместимость в обе стороны: 64-битные x80-программы можно запускать и на 8-битном x80, но производительность упадёт в сто раз!!!

Это сделано с той целью, что, используя современные технологии с супер-кешом, по-идее в перспективе можно будет добиться доступа к регистровому файла за 1 такт. А введя конвейер, ускорить исполнение команд в несколько раз. То есть, это уже уровень мастерства.

Сейчас главное (для меня) - просто добиться функциональной полноты системы команд, чтобы хотя бы в эмуляторе работало гладко.

b2m
16.05.2020, 20:36
Система команд PDP-11 тоже хорошо ложится на коды, только восьмеричные.
Самое прикольное, что и система команд 8080 тоже хорошо ложится на восьмеричные коды. Формат опкода побитно: ggRRRrrr, где gg - группа команд, RRR - регистр назначения, rrr - регистр источника, а в командах где в группе нет регистра источника или назначения, эта восьмиричная цифра означает код операции. Но Интел почему-то решил, что 16-ричная система лучше и всё пошло наперекосяк.

Hunta
16.05.2020, 21:00
Самое прикольное, что и система команд 8080 тоже хорошо ложится на восьмеричные коды. Формат опкода побитно: ggRRRrrr,
Вполне возможно, я уже давно не касался 8080 (хотя в загашнике лежат Радио-86 и Микроща), так что просто не помню свои разборки в то давнее время, когда Микроша стала моим первым домашним компам. Но и провозился я с ней относительно не долго - в продаже появился БК-0010.01 - и против PDP-11 совместимого я, ессссенно (первая любоф) - не устоял. После чего Микроша.. просто лежала :) А потом появился УК-НЦ (с флопами) - и стало лежать два компа :) А потом мне предложили их продать - и я не устоял :) Малолетний идиот :) Ну а теперь - лежат как ностальгия - может и повожусь :)

Микроша, кстати, была продана уже с моей доработкой - расширил ОЗУ до 48 кб и некоторые программы (точно - редактор и ассемблер) - перенес в верхние 16 кб, что дало мне аж почти 32 кб свободной памяти :) Но вот ПЗУ тогда прошивать не было на чём, поэтому монитор не умел использовать верхний блок :)


Но Интел почему-то решил, что 16-ричная система лучше и всё пошло наперекосяк.
Я так и не научился её воспринимать нормально :) В восьмеричной и складываю и вычитаю и слово делю на байты в уме, а hex - только слово на байты могу - остальное - калькулятор из Win :)

Радио-86РК
16.05.2020, 22:10
Самое прикольное, что и система команд 8080 тоже хорошо ложится на восьмеричные коды.O чём я и говорю. Когда в справочниках отца по микропроцессорам изучал комплекты серий типа 1801 и т.д…, то путался всегда в этих их восьмеричных адресах и вообще не понимал ничего.
(Вроде бы операции умножения проглядываются, но выглядело (после дампов РК) всё как-то несерьёзно: Спорное заявление, но это - дело вкуса…)

А с РАДИО-86РК и ASCII-таблицу вызубрил быстро, и в адресации стал разбираться.
Это наверное дело вкуса. Но, как я уже сказал, здесь x80 имеет редуцированную систему команд i8080, которая из восьмеричного порядка комплектации команд в таблице была приведена к шестнадцатеричному виду.

Не забывайте, что…https://img-fotki.yandex.ru/get/9816/22857638.5/0_db53b_f2b148f0_XXXL.bmp (https://zx-pk.ru/threads/22922-yut-88-faq.html?p=687663&viewfull=1#post687663)…представляла ь именно шестнадцатеричной таблицей. Да и дамп в Hex-представлении куда удобнее и компактнее на экране с 52 символами на строку.

И адрес F803 выглядит красивее и запоминается легче, чем 174003.
Человек, прежде всего, мыслит словами и звуками: F803 - Функция #8-03.

Наверное, здесь ещё играет роль особенности памяти индивидуума: Кто-то номера телефонов запоминает легко цифрами, а кто-то - буквами:
http://3.bp.blogspot.com/-EXb88SeTF-E/U7JgMhcvYYI/AAAAAAAACPM/cuGVzEMtsV0/s1600/%D0%BD%D0%BE%D0%BC%D0%B5%D1%80%D0%BE%D0%BD%D0%B0%D 0%B1%D0%B8%D1%80%D0%B0%D1%82%D0%B5%D0%BB%D1%8C+%D1 %82%D0%B0%D0%BD-6.jpgНапример, у моего знакомого номер сотового я помню только потому, что он представляется как «-BABNIK» - «-222645». А своей племяннице сим-карту покупал на «-DOLLY-» - «-36559-».
(На владельцев блатных номеров, типа 111-11-11, я смотрю как на безграмотных гопников из 90-х…)

Даже в системе команд x86 меня напрягает поле «md-reg-r/m» как восьмеричное.
Пытался делать эмулятор i8086 с шестнадцатеричным полем операндов как «h-reg-l-r/m», чтобы голым дампом не нужно было в уме индекс регистра из восьмеричной системы переводить в нормальный Hex-вид…

P.S.: Потому, как ответвление от i8080, этот x80 именно шестнадцатеричный.

HardWareMan
17.05.2020, 09:57
Например, у моего знакомого номер сотового я помню только потому, что он представляется как «-BABNIK» - «-222645». А своей племяннице сим-карту покупал на «-DOLLY-» - «-36559-».
(На владельцев блатных номеров, типа 111-11-11, я смотрю как на безграмотных гопников из 90-х…)
А мой телефонный номер состоит из полного количества строк SECAM стандарта и даты моего рождения. :)

Радио-86РК
17.05.2020, 15:08
Вчерa накидал пример всех способов адресации и расстроился.
Вот смотрите:
07 :MOV DL,[BX] ; Косвенно-регистровая адресация
67 :MOV DL,CL ; Регистровая адресация
A7 89:MOV DL,0x89 ; Непосредственная адресация
55 A7 89:MOV DL,[BX-119] ; Относительная адресация
E4 55 A7 89:MOV DL,[BX+AL-119] ; Индексная адресация
B8 FE 55 A7 89:MOVX DL,[BX+XX-119] ; Чтение в режиме X по индексу XX - ломается эстетика
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
0A :ADD AL,[BX] ; Косвенно-регистровая адресация
6A :ADD AL,CL ; Регистровая адресация
AA 89:ADD AL,0x89 ; Непосредственная адресация
55 AA 89:ADD BL,0x89 ; Непосредственная адресация
E4 55 AA 89:ADD4 BL,0x89 ; Сложение в режиме #4
B8 FE 55 AA 89:ADDX BL,0x89 ; Сложение в цикле режима X - ломается эстетика
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
81 23:PUSH 0x0123 ; Помещение константы в стек
91 23:PUSH 0xF123 ; Помещение константы в стек
55 81 23:PUSH 0x5123 ; Помещение константы в стек
55 91 23:PUSH 0xA123 ; Помещение константы в стек
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55 A0 23:PUSH [BX+35] ; Относительная адресация
55 B0 23:POP [BX+35] ; Относительная адресация
E4 55 A0 23:PUSH [BX+AL+35] ; Индексная адресация
E4 55 B0 23:POP [BX+AL+35] ; Индексная адресация
B8 FE 55 A0 23:PUSHX[BX+XX+35] ; Индексная адресация X по XX - ломается эстетика
B8 FE 55 B0 23:POPX [BX+XX+35] ; Индексная адресация X по XX - ломается эстетикаЕсли Вы не обращаете внимания на издержки технологий с уродством команд x86, то ничего не заметите и не поймёте…

А я - попал в тупик. Так как «MOV DL,[BX+AL-119]» кодируется последовательно (следите за лесенкой: Система префиксов проста), а вот закодировать «MOVW DL,[BX+AL-119]» я уже не смог - ломается эстетика!
Да, именно эстетика для ручного восприятия и набития байт-кода!

Что такое здесь за «MOVX», «PUSHX» и «POPX»?
В регистровом файле регистр BL имеет адрес 0x00B0, регистр BH - адрес 0x00B8, где BX - соответственно 0x00B8:0x00B0.
Промежутки 0x00B1…0x00B7 и 0x00B9…0x00BF не используются, но подразумеваются.
То есть:
В 8-битном x80 регистр BL - ячейка 0x00B0
В 16-битном x80 регистр BL - ячейки 0x00B0 и 0x00B1
В 24-битном x80 регистр BL - ячейки 0x00B0, 0x00B1 и 0x00B2
В 32-битном x80 регистр BL - ячейки 0x00B0, 0x00B1, 0x00B2 и 0x00B3
В 64-битном x80 регистр BL - ячейки 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6 и 0x00B7
То есть, в отличии от x86 с именами «BX», «EBX» и «RBX», здесь у меня «BX» - всегда «BX».
А вот «ADD», «PUSH» или «MOV» может меняться на «ADD8», «ADD16», «ADD32» или «ADD64».

То есть 8-битный x80 будет исполнять 32-битное x80-приложение очень медленно, последовательно читая и перезаписывая аккумулятор AL по ячейкам 0x00A0, 0x00A1, 0x00A2 и 0x00A3 с затратой кучи тактов (эффект бутылочного горлышка).
Тогда как 32-битный x80 сразу прочтёт целое слово 0x00A0…0x00A3 за такт, выполнит АЛУ-операцию и за такт перезапишет слово.
То есть, формально в эмуляторе я уже могу написать и запустить 64-битный код, но не хочу.

На счёт остального…
Читаем VLIW (https://ru.wikipedia.org/wiki/VLIW):
Преимущества и недостатки (https://ru.wikipedia.org/wiki/VLIW#%D0%9F%D1%80%D0%B5%D0%B8%D0%BC%D1%83%D1%89%D0 %B5%D1%81%D1%82%D0%B2%D0%B0_%D0%B8_%D0%BD%D0%B5%D0 %B4%D0%BE%D1%81%D1%82%D0%B0%D1%82%D0%BA%D0%B8)
Архитектура VLIW выглядит довольно экзотической и непривычной для программиста. Из-за сложных внутренних зависимостей кода программирование вручную, на уровне машинных кодов для VLIW-архитектур, является достаточно сложным. Приходится полагаться на оптимизацию компилятора.Ясно, что ничего общего у моего x80 не имеется ни с RISC, ни с VLIW.
Но, из «Из-за сложных внутренних зависимостей кода программирование вручную, на уровне машинных кодов для VLIW-архитектур, является достаточно сложным. Приходится полагаться на оптимизацию компилятора» видно, что программиста всё-таки нельзя оставлять в изоляции от машинного кода с барьером в лице компилятора!
Тем самым, так как изначально мною курс был взят за «Даёшь байт-код народу», то любое отклонение от него - крах всего концептульного плана.

P.S.: Не смотря на возмущения и критику многих, в данной теме нужно просто принять за де-факто то, что здесь обсуждаются проблемы разработки процессора с прозрачным байт-кодом так, как видит его автор. То есть - я…
Вам выбирать, подключаться ли к проекту или игнорировать - архитектура моего процессора от этого не изменится. Вы и сами это понимаете, так как форум для того и существует.
Как «художник-технарь», я вижу идеальный процессор именно так!
Если видите иначе - откройте другую ветку.

Smalovsky
17.05.2020, 15:18
MIPS - уныл
Mi amigo, ¿tienes algo contra MIPS?

Радио-86РК
18.05.2020, 21:41
Кстaти, так как x80 задумывался в идеале как CISC-процессор на ТТЛ, в силу своей сложности рассматривался вариант с RISC-ядром, как это сделали с i486.
(Если помните, то i486 в сравнении с i386 стал чуточку медленнее (уже забыл, где, но по-моему, команды LOOP, IN, OUT пострадали). Но здесь я не буду вкапываться в историю Intel…)
А чтобы не зависеть от топовых решений индустрии, ядром x80 я решил сделать собственную архитектуру (https://zx-pk.ru/threads/31817-x80-risc-yadro-s-intuitivnoj-sistemoj-komand-dlya-x80-cisc.html) со сквозным кодированием команд методом акына: Что вижу, то и кодирую.

Тем самым, так как в эмуляторе используются 18 бит кодируемой команды и схема узла выборки команды (https://zx-pk.ru/threads/31789-x80-cisc-uzhe-ne-i8080-eshchjo-ne-i8086.html?p=1063185&viewfull=1#post1063185) выдаёт эти биты, то прямым кодированием можно закодировать в лоб 262144 микропрограмм.
Например:
; Код B8 FF - Команда RET
;
; 18-битный внутренний бинарный индекс подпрограммы:
; 0x00FB8
; 0x04FB8
; 0x08FB8
; 0x0CFB8
; 0x10FB8
; 0x14FB8
; 0x18FB8
; 0x1CFB8
; 0x20FB8
; 0x24FB8
; 0x28FB8
; 0x2CFB8
; 0x30FB8
; 0x34FB8
; 0x38FB8
; 0x3CFB8
;
; Примерный дамп микропрограммы команды RET
000FB800 A9 AA 01 - A9 = 1
000FB803 CB C4 B4 AD - AD = B4:C4
000FB807 CA 0A - C4 += A9
000FB809 BA DC 0A - DC B4 += A9
000FB80B CC C9 BE - C9 = [AD]
000FB80E CB C4 B4 AD - AD = B4:C4
000FB812 CA 0A - C4 += A9
000FB814 BA DC 0A - DC B4 += A9
000FB817 BB B9 BE - B9 = [AD]
000FB81A CB C9 B9 AD EBТо есть, тем самым, x80-команда RET разворачивается всего в 31 RISC-команду по 2 такта на каждую и требует 62 такта!
Это - чудовищный результат!
Не смотря на чудовищное обилие микропрограмм в четверть миллиона, каждая микропрограмма будет жрать по несколько десятков тактов!

P.S.: Вот так я стараюсь не ограничиваться одним JavaScript-эмулятором, а прощупываю более-менее приемлемые способы реализации не отступая от курса концепции: Не искажая общую таблицу всех команд.
Мне ведь не дипломную работу защищать, где худо-бедно хоть какой-то процессор пинком запустить лампочками моргать.
Потому и не торопясь десятилетиями двигаюсь крайне медленно к реализации всей концепции в целом, чтобы x80-Linux запустить в перспективе.
(Это для тех, кто хотел бы увидеть результат и прототип хотя бы к 2038 году: Не дождётесь!)