1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

Поиграем?

Тема в разделе "WASM.PROJECTS", создана пользователем Paguo_86PK, 22 дек 2008.

  1. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    904
    Адрес:
    Ташкент
    Итaк, скачал LogiSim Evolution и обнаружил, что он не читает корректно файлы оригинального LogiSim. Но сам Evolution поддерживает модули с VHDL и прошивку FPGA, что демонстрируется на видео:
    Правда, у меня всё это дело не пошло, так как кроме Icarus Verilog пока ничего не имеется.

    А так как схемы приходится перерисовывать вновь, то я блок выборки команд («Читалку») перерисовал и закончил…
    Было это:
    x80-reader.png
    Стало это:
    x80-reader-full.png
    Если раньше для пробы в регистр IA я просто записывал биты с компаратора, то теперь в IA записывается маска с комплексной комбинаторики и с помощью этого возможна поддержка практически всех команд x80. При этом, обошлось без ПЗУ.
    Полноценный эмулятор x80 я пишу который год. Но проблема в том, что в один прекрасный момент он перестал нормально работать. И одним только откатом обойтись нельзя было, так как дело в самой концепции.
    Эмулятор управляется так:
    • F1 - один шаг отладчика
    • F4 - пуск на всю скорость
    • Alt+1…7 - выбор префикса для переключения таблицы команд и изучения её в деталях
    • Alt+8/9/0 - выбор префикса режима (Micro/Loop/Wait)
    • Alt-P/T - переход к полям Pointer/Translator для ввода инструкций ассемблера. При этом отображается и дамп регистрового файла
    Основная проблема в том, что эмулятор не поддерживает префикс с кодом «00» в режиме Ядра…
    Дело в том, что архитектура x80 задумана так, чтобы единственной привелегированной инструкцией была команда/префикс HLT: Для приложений код 00 - HLT, а для Системного Ядра - Префикс №0. И вот эмулятор этот префикс, оказывается, не поддерживает и так просто ввести его поддержку, как оказалось, нельзя! Падает вся система команд.

    Однако, вернёмся к схемам…
    После замены компаратора на комбинаторику видно, что получается строго три ступени вентилей на пути к регистрам и примерные задержки можно относительно легко оценить для пиковой производительности.
    Получается целых 19 бит на схему дешифратора команд, так как помимо 12 от IC и IB, идут ещё 3 от IA и 4 от регистра состояния:
    • SKIP - режим префикса SKIP для пропуска команд. Да, в x80 предусмотрены команды, которые исполняются иначе, когда их надо просто пропустить
    • EACH - режим префикса LOOP для повтора одной команды n раз. Так, «LOOP ADD» работает как умножение… Префикс работает и с RET, и с JMP, и с CALL, переключаясь в SKIP, чтобы после входа/выхода из подпрограммы пропустить n подметок для выбора подфункций. То есть, если в MS-DOS вызов «INT 21h» был кучей проверок AH через CMP-JZ, то в x80 «LOOP CALL» сам пропускает n команд JMP неявным префиксом SKIP (просто «LOOP+CALL» обрабатывается как «CALL+SKIIP»)
    • DLY - режим префикса WAIT. Тот же LOOP, но цикл прерывается флагом CF. Только из-под Wait можно обратиться к медленным устройствам ввода/вывода и узнать точное значение задержки. А «WAIT SUB» работает как деление…
    • SYS - признак Ring #0 для кода ядра операционной системы
    Тем самым, узел выборки команды делает практически всё, чтобы выполнить любые экзотические сочетания кодов.
    Так, для x86 коды «EB FE» и «EB FF» являются экзотикой с замыканием «JMP» на себя. А в x80 это просто префикс «WAIT» и команда «RET» соответственно, так как в прикладном коде они обильно не используются и отдельно не засоряют таблицу команд. И уже на стадии выборки команды из памяти вылавливаются случаи замыкания и превращаются в особые префиксы регистра IB, условно названными постфиксами…

    Удивительно, но в эмуляторе логику этой схемки повторить, оказалось, не так легко. Это обрушивается, буквально, всю систему команд! То есть, из таблицы исчезли все команды, так как генератор массива не был рассчитан на то, что код 00 будет тоже префиксом, но в режиме ядра. Через него индексная адресация памяти превращается в адресацию ячеек регистрового файла.
    Если раньше, на стадии дизайна эмулятора, я код 00 под ядром задумывал как единственную команду доступа к регистровому файлу, то после дизайна схемы выборки команд понял, что можно 00 оформить под супер-префикс. Поэтому в эмуляторе это всё и обрушило! Хотя на уровне схемы всё упростилось и появилась дополнительная гибкость для работы с регистровым файлом…

    P.S.: Короче, такие вот дела…
     
    Последнее редактирование: 31 окт 2019
  2. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    904
    Адрес:
    Ташкент
    Вчерa весь вечер потратил на перенос схемы с LogiSim в Proteus…
    Так как многие логические элементы изображаются фигурными и слишком крупно, пришлось изрядно потрудиться и над IEC-дизайном. Почему-то в LogiSim с этим особых проблем не возникало, тогда как в OrCAD и Proteus дефолтная графика слишком по-детсадовски огромна! :bad:

    Не удалось применить микросхемы одной серии и пришлось смешивать S/ALS/F/HC/HCT, что уже довольно не хорошо! А когда почти закончил, ахнул от величины схемы в корпусах: 20 микросхем! :swoon:
    Почему почти? Один бит (самый старший в ID на LogiSim-дизайне) не смог никуда разместить! Отдельно ТМ2 добавлять - тоже не очень красиво, так как помимо тактового входа требуется ещё разрешающий. А это требует вентилей опять же…
    И U19/U20 корпусами выдались как знаменитый ИД3! :wacko:

    В общем, теперь сижу и думаю…
    По-своему красиво было бы процессор свой живьём собирать отдельными платками-модулями для каскадной сборки.
    А с другой стороны - никак не ожидал, что модуль выборки команд получится таким концентрированным, объёмным и сложным… :black_eye:

    P.S.: Два месяца прошло, а чем серьёзнее я хватаюсь за идею, тем больше разочарования и ошеломительных подробностей… :heat:
     

    Вложения:

  3. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    5.064
    Практика -- еть такая тварь, губит столько хороших затей :)
     
  4. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    904
    Адрес:
    Ташкент
    Подогнaл эмулятор под новые реалии…

    Идеология
    Напомню, что опираясь на опыт коллег (PICO-8, MegaProcessor, MyCPU, Gigatron и т.д…), собственными окольными путями пытаюсь построить собственный процессор без предрассудков: Мне не нужно запустить архитектуру с колена, чтобы состряпать хоть что-нибудь и это поехало лампочками мигать и фракталы Мандельброта строить…
    План прост по-идее, но сложен в перспективе, так как локально планируется переразработать всю линейку архитектуры Intel с нуля. А именно, так как i8080 и i8086 программно никак не совместимы, а система команд обоих оставляет желать лучшего, то поставил план разработать 8-битную архитектуру с расширением до 16 бит или до 32, причём с программной совместимостью в обе стороны…

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

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

    Система команд прорабатывалась в гуманитарном русле так, чтобы дампом байт-кодом можно было легко как прочитать алгоритм, так и набить его. А это значит, что никакой аппаратной экономии на реализации дешифрации команд не соблюдается, чтобы сам код команды в большинстве своём являлся и смысловой мнемоникой.
    • Код BC -> логика «Branch by Carry» -> команда «JC»
    • Код BE -> логика «Branch by Equal» -> команда «JZ»
    • Код CF -> команда инверсии флага CF -> команда « CMC»…
    Так как в перспективе, если ядро строить на RISC-процессоре, нету абсолютно никакого смысла портить стройную таблицу команд в угоду тактического упрощения схемы декодирования кода команд.

    Перезагрузка
    В связи с карантином я всё-таки взялся за доработку своего JS-эмулятора в HTML и подогнал его под новый план.
    А именно…
    Чтобы в процессоре поддерживалась многозадачность на уровне регистрового файла с переключаемыми контекстами, необходимо иметь команды для управления служебными регистрами. В IA-32 для этого ввели привилегированные команды в общую систему команд.
    В моём процессоре код 00 в приложении является командой останова «HLT». Но на уровне супервизора останов, как таковой, не требуется. Тем самым, код 00 в режиме ядра является «супер-префиксом», через который можно программировать критические регистры.

    И разработанный мною эмулятор под этот «супер-префикс» оказалось не так просто переделать, на что ушло трое суток!
    Тем не менее, эмулятор заработал, но минимальный BIOS под него не готов, чтобы запустить тот же Тетрис…

    Скрепя сердце, добавил однобайтовые LOOP/SKIP-команды.
    Теперь кодом «E4 DA» работает как «RAR AL,4» в цикле.
    Но, если команде «MOV AL,[SI+7]» добавить цикл, то цикл превращается в префикс и команду «MOV AL,[SI+reg+7]», чем достигается уже значительная гибкость.
    Тем самым, команда, с учётом всех префиксов, может достигать длины до четырёх байтов.

    Аппаратная реализация
    Как программисты-электронщики, можете понимать, что порою программная реализация несколько сложнее аппаратной.
    К примеру, буфер экрана ZX-Spectrum с его нелинейной адресацией массива пикселей программно требует кучи сдвигов, тогда как в FPGA это вопрос перенаправления сигналов на уровне переназначения проводов шин.
    Правда, представленная выше схема выборки команды уже требует доработки, так как без выборки префикса она даёт код 8, а с «супер-префиксом» - код 0. Это сильно путает таблицу истинности casex дешифратора команд, потому необходимо просто поменять местами коды 0 и 8 добавлением вентилей.

    Но, в целом, эскиз схемы, выполненный средствами JavaScript, вполне оправдал себя и показал свою работоспособность.
    Что я записал, ради прикола, в видео с аппаратным дизассемблером.
     
  5. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    904
    Адрес:
    Ташкент
    Думaю, за неделю мне удалось продвинуться вперёд к реализации своей мечты.

    Если помните, я крайне критически отношусь к инженерам в плане их художественных чувств: Мне не нравится эстетическая сторона таблиц команд многих процессоров, так как инженеры вообще не думают об эстетике машинного кода, который потом будет использоваться многими десятилетиями.
    А так как мой CISC x80 продумывается именно с позиции эстетики, таблица команд у него интуитивно понятная и прозрачна, хотя и имеет некоторые нюансы и исключения. И было бы проще пытаться реализовать его на RISC-ядре, чтобы любой код можно было прошить легко.
    Но какой процессор тогда использовать за ядро? Ведь предлагаемые процессоры нужно ещё и научиться программировать! Тем более, их система команд никак не интуитивно понятная. А значит, идеологически это будет уже минусом!

    Задался я вопросом разработки своего RISC-процессора с интуитивно ясной системой команд, где отдельные нибблы байт-кода обозначают аббревиатуру закодированной инструкции. Дело это оказалось не очень простым и я удалил всему этому более года…

    Основное положение
    Процессор задумывался таким, чтобы для написания программы не требовался никакой транслятор типа ассемблера. А опытный программист мог бы в любом редакторе дампа как написать свой код, так и понять уже написанное в русле WYSIWYG - что видится, то и означает.
    Тем самым, сначала был построен регистровый файл из четырёх групп, по 10 регистров в каждой.
    • A0…A9 - десять регистров аккумуляторов (A0 - статус АЛУ с флажками)
    • B0…B9 - десять регистров указателей базы для доступа к ячейкам памяти
    • C0…C9 - десять регистров счётчиков байтов в памяти по указанным базам
    • D0…D9 - десять внешних устройств со скоростным непосредственным доступом
    Первая схема не позволяла обратиться одновременно к значениям двух регистров одной группы и это значительно усложняло программирование, снижая производительность и гибкость. Потому я занялся разработкой двухпортовых групп.

    Узел управления шинами и выборки команд из памяти я долго отлаживал отдельно. В конце-концов обошёлся лаконичным решением на сдвиговом регистре и мудрёной комбинаторики.
    Дешифратор команд я сначала рассчитывал на большее количество - до 28. Потому сейчас он выглядит у меня несколько странным и избыточным. Теперь я понял, что достаточно обойтись одним дешифратором без ИЛИ-НЕ вентилей. Но переделывать пока не хочется, так как потребуется перебивать таблицу прошивки ПЗУ с определением команд.

    Система команд управляет всем процессом в машинном коде на понятном для оператора WYSIWYG-языке и составляет следующие команды:
    • 00 - HLT (команда останова упразднена, но работает как расширенный код)
    • 01…99 - BCD-код десятичных чисел 1…99 приращиваемый к активному аккумулятору
    • 0A…9F - АЛУ-операция над активным аккумулятором и вторым аргументом с индексом 0…9
    • A0…A9; B0…B9; C0…C9; D0…D9 - переключения индекса в заданной группе регистров
    • AA…AD; BA…BD; CA…CD; DA…DD - выбор состава операндов для АЛУ-операций
    • AE / BE / CE / DE - экстракция данных из ОЗУ в заданную группу
    • AF / BF / CF / DF - фиксация данных из регистра указанной группы в ОЗУ
    • E8…EF - условное выполнение следующей операции (execute by: Carry, Equal, Fiction…)
    • F0 - завершение текущей подпрограммы (Function Over)
    • E0…E7 и F1…FF - переход на адрес E000…E700 или F100…FF00 соответственно
    Тем самым, это - и есть вся система команд!

    Например, вот чуточку кода для прояснения кодирования алгоритмов:
    Код (Text):
    1. ; Инкремент регистра A7 на единицу
    2. AA            |USE A,A     ; Группа операндов A,A
    3.    A7         |USE A7      ; Индекс аккумулятора - A7
    4.       01      |ADD A7,1    ; Прибавляем BCD-константу
    5.  
    6. ; Декремент регистра C9 на единицу
    7. CC            |USE C,C     ; Группа операндов C,C
    8.    C9         |USE C9      ; Индекс аккумулятора - C9
    9.       85      |ADD C9,85   ; Прибавляем BCD-константу (+85)
    10.          85   |ADD C9,85   ; Прибавляем BCD-константу (+170)
    11.             85|ADD C9,85   ; Прибавляем BCD-константу (+255)
    12.  
    13. ; Копирование значения из B0 в A9
    14. AA            |USE A,A     ; Группа операндов A,A
    15.    A9         |USE A9      ; Индекс аккумулятора - A9
    16.       9E      |EOR A9,A9   ; Очищаем A9
    17.          AB   |USE A,B     ; Группа операндов A,B
    18.             0D|OR  A9,B0   ; Дизъюнкция A9 и B0 (старший ниббл - 0)
    19.  
    20. ; Те же операции, но в более краткой форме ассемблера
    21. AA A7 01      |INC A7
    22. CC C9 85 85 85|DEC C9
    23. AA A9 9E AB 0D|MOV A9,B0
    24.  
    25. ; Пример вызова подпрограммы и возврата из неё
    26. F012 F1       |F1          ; Вызов Функции по 0xF100: B0 <= 0xF0; C0 <= 0x12
    27. F013 00       |HLT         ; Останов: Переход на 0x0000; B0 <= 0xF0; C0 <= 0x13
    28. .... ..        ............
    29. F100 CC C0 01 |INC C0      ; Теперь в B0:C0 будет значение 0xF013
    30. F103 B0 F0    |JMP B0:C0   ; Переход по B0:C0, а в B0:C0 помещается адрес 0xF104
    Ниже в архиве файл с HTML-дизассемблером (эмулятор не написал, так как работы схемы интереснее выглядит), который поможет вникнуть в систему команд. А так же в архиве имеется сама схема для LogiSim с прошивками ПЗУ и ОЗУ.
    Пока сложную программу я ещё не написал, так как оттачивал и упрощал всю систему команд в целом. Дешифрация команд производится на элементах ИЛИ-НЕ по матрице в ПЗУ и изначально рассчитывалось всё 24 группы команд. Однако, практика показала, что достаточно иметь и 10 групп.

    P.S.: Тем самым, я убедился, что и RISC-архитектуру можно спроектировать с красивой и прозрачной системой команд!
     

    Вложения:

    • x80_RISC.zip
      Размер файла:
      25,3 КБ
      Просмотров:
      3
    • x80_RISC.png
      x80_RISC.png
      Размер файла:
      166,8 КБ
      Просмотров:
      4
  6. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.147
    Может быть набор команд красив и прозрачен, но ужасно перегружен избыточной информацией. У тебя 4 группы операндов, это кодируется 2мя битами, ты используешь 8, 10 номеров регистров (странный выбор), это кодируется 4мя, но ты используешь все 8. В итоге всего лишь инкремент регистра занимает 24 бита. Если так прямо хочется без ассемблера писать, тот же нибл, то есть один шестнадцатиричный разряд, вполне себе нагляден и удобен в этом плане.