User Tag List

Страница 1 из 4 1234 ПоследняяПоследняя
Показано с 1 по 10 из 42

Тема: x80: CISC - уже не i8080, ещё не i8086

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    Регистрация
    05.03.2010
    Адрес
    Ташкент
    Сообщений
    160
    Спасибо Благодарностей отдано 
    25
    Спасибо Благодарностей получено 
    66
    Поблагодарили
    41 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Lightbulb x80: CISC - уже не i8080, ещё не i8086

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

    Идеология
    Опыт коллег (PICO-8, MegaProcessor, MyCPU, Gigatron и т.д…) вдохновляет меня и собственными окольными путями пытаюсь построить собственный процессор без предрассудков: Мне не нужно экономить на простоте, чтобы где-то какой-то проводочек стал короче на миллиметр. И я не тороплюсь запустить архитектуру с колена, чтобы состряпать хоть что-нибудь и это поехало лампочками мигать или фракталы Мандельброта строить…

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

    Ошибки Intel прослеживаются с самого начала:
    • На уровне машинного кода i8080 и i8086 абсолютно несовместимы
    • На уровне ассемблера совместимость частичная, хоть и заявлялось о ней
    • Поддерживаются рудиментарные команды (i8080: 32/3A - STA/LDA; i8086: A0/A1/A2/A3), которые все не перечислишь, но в современном защищённом режиме их наличие - бессмысленно
    • Гибриды типа 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» не нужна. Чем я убил двух зайцев:
    1. Нету никаких привилегированных команд, которые приложению нельзя использовать. Тем самым, все коды таблицы команд приложение может использовать
    2. Только в «режиме ядра» этот «супер-префикс» доступен и не болтается мусорным защищённым кодом в системе команд у приложений


    Архитектура
    Хоть процессор и походит на продвинутый вариант 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-величиной.
    1. Обращение к INT 0-79
    2. Переключение памяти
    3. Переключение задач
    4. Запрос к устройству ввода-вывода
    5. Внешние маскируемые прерывания
    6. Сигнал немаскируемых прерываний
    7. Запуск ядра по сигналу 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
    Эмуляция
    • Одна из первых версий эмулятора с Монитором в стиле РАДИО-86РК. Автоматически выводится дамп, прыгает шарик с очищением поля и построением рамки, после чего выводится фигурка Тетриса, управляемая клавиатурой
    • Другая версия эмулятора. Клавиша 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-модель, выполняющая несколько команд.
    Но, из-за плохого владения принципами Verilog, эскиз модели получился тупиковым и всё нужно переписывать с нуля…

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

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

Название:	x86-table.jpg 
Просмотров:	115 
Размер:	21.1 Кб 
ID:	72597  
    Последний раз редактировалось Радио-86РК; 16.05.2020 в 23:34.

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2

    Регистрация
    08.09.2005
    Адрес
    Воронеж
    Сообщений
    4,963
    Записей в дневнике
    3
    Спасибо Благодарностей отдано 
    319
    Спасибо Благодарностей получено 
    312
    Поблагодарили
    236 сообщений
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

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

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

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

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

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

  4. #3

    Регистрация
    15.02.2015
    Адрес
    г. Могилёв, Беларусь
    Сообщений
    928
    Спасибо Благодарностей отдано 
    15
    Спасибо Благодарностей получено 
    119
    Поблагодарили
    73 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Lethargeek Посмотреть сообщение
    MIPS - уныл
    Mi amigo, ¿tienes algo contra MIPS?
    ¡Un momento, señor fiscal!


  5. #4
    HardWareMan
    Гость

    По умолчанию


    Эм...

  6. #5

    Регистрация
    05.03.2010
    Адрес
    Ташкент
    Сообщений
    160
    Спасибо Благодарностей отдано 
    25
    Спасибо Благодарностей получено 
    66
    Поблагодарили
    41 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Post Инструментальный Эмулятор x80 - alpha

    Цитата Сообщение от HardWareMan Посмотреть сообщение
    Эм...
    Всe инструкции видеть можно только в эмуляторе.

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

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

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

  7. #6

    Регистрация
    30.11.2015
    Адрес
    г. Самара
    Сообщений
    7,505
    Спасибо Благодарностей отдано 
    344
    Спасибо Благодарностей получено 
    712
    Поблагодарили
    594 сообщений
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    если вздумаете вникнуть в этот исходник, то ничего не поймёте, так как и сам уже в нём теряюсь и правлю с опаской по принципу «работает - не трожь!»
    Ч.И.Т.Д.

  8. #7

    Регистрация
    30.11.2015
    Адрес
    г. Самара
    Сообщений
    7,505
    Спасибо Благодарностей отдано 
    344
    Спасибо Благодарностей получено 
    712
    Поблагодарили
    594 сообщений
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    ИМХО

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

    В данном случае, очевидно, предполагается программирование на ассемблере, но дружелюбности - не наблюдается. Болеe того, несмотря на фразу:
    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    тактические экономические трюки инженеров в 70-х просто навсегда изувечили всю систему команд!
    автор и сам попал в эту ловушку

    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    Нету никаких привилегированных команд, которые приложению нельзя использовать.
    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    Приложения не могут напрямую обращаться к устройствам и операции «WAIT+IN/OUT» генерируют событие #4 ядру, которое уже само должно разбираться.
    Это называется скрытый запрет. Например, в PDP-11 в пользовательском режиме команда HALT запрещена и генерирует событие (прерывание), которое обрабатывает ядро и должно уже само разбираться. Слова другие, смысл тот же.


    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    Для супервизора имеется «супер-префикс» с кодом «00», так как в «режиме ядра» операция «HLT» не нужна.
    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    То есть, «Ребусная Система Команд», так как комбинации префиксов достигают уровня головоломки, которую тяжело переварить ассемблером и дизассемблером.
    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    Потому, если Вы любитель простоты, то Вам моя технология не понравится и её можете игнорировать.
    С другой стороны, если Вы - любитель головоломок и не прочь сломать мозг машинным кодом, то Вам может понравится сахар…
    А теперь подумайте о том - сколько будет ОШИБОК в программе из за СЛОМАННОГО МОЗГА программиста?
    Или может всё таки стоит облегчить написание программ человеку?

    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    В данный период дорабатывается версия эмулятора с путаницей переключения контекстов, так как я занимался внедрением «супер-префикса». Пустяковая доработка заняла три дня отладки и доработок алгоритмов ассемблера, дизассемблера и эмулятора. Но сама проблема пока не решена. Лишь упростились некоторые команды…
    Ч.И.Т.Д. Это называется - сломать МОЗГ, только не человек, а ПРОЦЕССОРУ. Хотя нет, человеку тут мозг тоже уже вынесли. Вам.

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

  9. #8

    Регистрация
    05.03.2010
    Адрес
    Ташкент
    Сообщений
    160
    Спасибо Благодарностей отдано 
    25
    Спасибо Благодарностей получено 
    66
    Поблагодарили
    41 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Hunta Посмотреть сообщение
    В данном случае, очевидно, предполагается программирование на ассемблере, но дружелюбности - не наблюдается. Болеe того, автор и сам попал в эту ловушку
    Системa команд того же z80 полна всяких исключений. Например, «LD A,[IX±d8]» неочевидным образом удлиняет команду на 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 можно описать шаблоном…

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

  10. #9

    Регистрация
    30.11.2015
    Адрес
    г. Самара
    Сообщений
    7,505
    Спасибо Благодарностей отдано 
    344
    Спасибо Благодарностей получено 
    712
    Поблагодарили
    594 сообщений
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    Системa команд того же z80 полна всяких исключений
    Я сказал, что она замечательная? Или что надо ей следовать?

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

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

    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    Потому я и уверенно говорю, что код - дружелюбный! Конечно, если Вы решите программировать прямо дампом.
    Цитата Сообщение от Радио-86РК Посмотреть сообщение
    Где «A4»
    ADD 4
    Вот и вся дружелюбность.

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

    MOV R0, R1
    ADD R0, R1

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

  11. #10

    Регистрация
    05.03.2010
    Адрес
    Ташкент
    Сообщений
    160
    Спасибо Благодарностей отдано 
    25
    Спасибо Благодарностей получено 
    66
    Поблагодарили
    41 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Arrow RISC'ов много, а x80 - один

    Цитата Сообщение от Hunta Посмотреть сообщение
    Можете не отвечать, это было моё последнее сообщение здесь.
    Тeм не менее, я отвечу, как минимум для тех, кто думает так же, но не ставит крест на интересе к данной теме…
    Цитата Сообщение от Hunta Посмотреть сообщение
    Поэтому это Вам привычно. А другим сходу будет нихера не понятно.
    Пример понятного
    Здесь критикуете именно синтаксис, так как в 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 всё же на порядок дружелюбнее!

    Кстати, сейчас добавил пару строчек для экспорта шаблона…
    Как результат, вот дешифратор всех команд на:

    C/JavaScript: if…else

    Код:
    	// 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:

    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/ТТЛ. Хоть и реализация на ТТЛ-рассыпухие в перспективе и предусматривается…)
    Последний раз редактировалось Радио-86РК; 15.05.2020 в 21:12.

Страница 1 из 4 1234 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Програмная эмуляция i8086 в ДВК
    от MM в разделе ДВК, УКНЦ
    Ответов: 21
    Последнее: 06.03.2019, 13:04
  2. Мнемоники i8080 vs Z80
    от Vladimir_S в разделе Разное
    Ответов: 153
    Последнее: 20.12.2016, 13:02
  3. Квадратный корень на i8080
    от shoorick в разделе Разное
    Ответов: 31
    Последнее: 25.08.2016, 14:04
  4. Код эмуляции i8080 на С
    от medvdv в разделе Эмуляторы отечественных компьютеров
    Ответов: 15
    Последнее: 27.03.2015, 03:43
  5. Эмулятор i8080
    от Higgins в разделе Разное
    Ответов: 2
    Последнее: 20.05.2011, 11:43

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •