nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 05:50



Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
Набросок РЛК на собственном процессоре. 
Author Message
Banned
User avatar

Joined: 04 Jan 2013 10:09
Posts: 397
Location: 95.24.178.158
Reply with quote
viv-pm wrote:
Речь идёт о том, разделялись ли аппаратно в какой-нибудь машине на ВМ80 эти пространства?

Речь ещё идёт о том, что разделить аппаратно эти пространства в машине на ВМ80 задача чисто техническая и вполне осуществимая.
И этот вопрос, действительно, подробно обсуждался здесь на форуме и даже не один раз:
http://www.nedopc.org/forum/viewtopic.php?f=91&t=10007

Резюме таково, что аппаратные затраты на это разделение существенно превышают мифический выигрыш от оного.

Нет - если Вы ставите вопрос так, что:"До меня их не разделяли, а я их разделю!" - никто не возражает.
Но надо посмотреть на предполагаемый результат - а какой выигрыш мы получим?
Если никакого преимущества от разделения нет, то это и будет техническим онанизмом в смысле "самоудовлетворения".


20 Mar 2015 08:12
Profile
Banned
User avatar

Joined: 04 Jan 2013 10:09
Posts: 397
Location: 95.24.178.158
Reply with quote
Paguo-86PK wrote:
Ну, если Вы меня внимательно читали, я бы хотел ...

Дело в том, что я не только Вас внимательно читаю, но внимательно прочитал и весь этот форум и не только его.
И 80% моих сообщений, собственно, и составляет тот факт, что я пишу посетителям о том, что горячо
интересующий их вопрос уже обсуждался по конкретному адресу и имеет решение, порой, с перспективами
далеко не радужными... :(

Но я бы посоветовал и Вам внимательно читать свой текст, ибо Вы в своем тексте противоречите сами себе.
Вот, к примеру:
Paguo-86PK wrote:
На сколько я понял из справочников, процессор периодически в шину данных посылает слово статуса: Цикл M1; Чтение/запись данных; Обращение к стеку. Тем самым, это уже не 64кб, а 192кб памяти, без всяких переключений страниц.

А теперь прикиньте аппаратные затраты на всю Вашу затею и сравните с аппаратными затратами на упомянутый "переключатель страниц".

Ну ладно бы в результате воплощения всех Ваших задумок мы получили что-то экстра-ординарное!
Но нет же - Вы сами далее пишите:
Paguo-86PK wrote:
Конечно, всё станет работать медленнее. Но, так можно достигнуть как в x86 виртуализацию. Убрать программу "Монитор" из адресного пространства вовсе. И включать код "Монитора" лишь на время обработки IN/OUT...

А я Вам говорю, что всех этих целей можно добиться и более скромными аппаратными средствами, да ещё и быстро!

То есть при нескромных аппаратных затратах, где уже звучат ПЗУ и ПЛИС мы не получаем зримого выигрыша в итоге!
Это я и назвал:"Гора родила мышь!"

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

А вообще один классик, которого звали И. Ньютон сказал:"Я видел дальше других только потому, что стоял на плечах гигантов".
Это я к тому, что в любой привлекательной идее, какой бы красивой она не казалась, надо бы посмотреть, а что сделали до Вас на этом поприще.
Тогда и не придется ломиться с усилиями в порой совершенно открытую дверь...


20 Mar 2015 08:46
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Хм, я всё понял. Меня критикуют всегда. Нет, я не говорю, что я такой хороший, а все кругом - редиски...
Например, у меня был такой прожект:
 "x86-скрипты"
Image

Суть следующая: Разработать виртуальную машину для внутренних проектов с минимум затрат (компилятор, транслятор, среда исполнения).
Я взял x86-команды, набил транслятор с фильтром, который исключает все опасные команды:
1. CALL, INT, JMP, Jxx, LOOP, RET - нарушают линейность потока;
2. STOS, MOVS, MOV R,[M], PUSP/POP - обращение к памяти с риском исключения...
Взамен, ввёл блочные конструкции:
1. JMP $-128 / $+0 - открыть/закрыть новый блок - {...};
2. JMP $+1..127 - повторить нужный по вложенности блок - continue;
3. JMP $-1..127 - выйти из n-вложенных блоков - break.
Включая условные - Jcnd/LOOP.
Все работают как условные блочные скобки - do/while/if(cnd) {...} while(cnd).

Также, вычислительные операции расширяются. Так как префикс 066h расширяет 16-битные регистры (ax/cx/dx/bx...) до 32-битных (eax/ecx/edx/ebx...), но на 8-битные не влияет, я решил это реализовать:
1. 66 B4 34 12 - MOV EAH,0x1234 - занести значение в старшие 16 бит
1.1. BSWAP EAX - переворачиваем байты
1.2. MOV AX,0x1234 - присваиваем значение
1.3. XCHG AH,AL - необходимо скорректировать порядок байтов
1.4. BSWAP EAX - теперь старшие 16 бит регистра EAX хранят новое значение.
Конечно, можно было обойтись сдвигом или маскированием. Но тогда бы флаги АЛУ были бы задеты.
2. 66 8A C4 - MOV EAL,EAH - присвоить младшим 16-битам старшие 16 бит
2.1. LEA ESP,[ESP-2] - спускаем стек
2.2. PUSH EAX - заносим значение
2.3. LEA ESP,[ESP+6] - поднимаем стек
2.4. PUSH EAX
2.5. LEA ESP,[ESP-2]
2.6. POP EAX
2.7. LEA ESP,[ESP+2]

Я получил уйму критики в свой адрес за такую свистопляску. На Си, однако, имелась готовая реализация. Работала в паре с HIEW: Как только в Hiew жал на F9, изменения в файле отслеживались и сразу же транслировались заново. Т.е. в "горячую" я мог видеть результат работы скрипта...
Удалось заполнить брешь кода: Префикс 66 расширяет 8-битные операции до 16-битных.
Конечно, тормоза, раздутость кода и т.д...

Вот и с ВМ80 я, в силу особенностей своего хобби, я решил поступить также... Превратить его в нечто и не новое, и не привычное...


20 Mar 2015 10:22
Profile WWW
Maniac

Joined: 18 Nov 2013 15:15
Posts: 209
Location: все оттуда ;)
Reply with quote
Paguo-86PK wrote:
Превратить его в нечто и не новое, и не привычное...

Что курит товарисч из Ташкента ?!?!?! :rotate:


20 Mar 2015 11:35
Profile
Banned
User avatar

Joined: 04 Jan 2013 10:09
Posts: 397
Location: 95.24.178.158
Reply with quote
Paguo-86PK wrote:
Хм, я всё понял. Меня критикуют всегда. Нет, я не говорю, что я такой хороший, а все кругом - редиски...

Вы, я полагаю, и выносите свои мысли на обсуждение, чтобы услышать им оценку со стороны?
Если бы от проекта был зримый эффект - хоть какой-то явный пусть даже при замедлении работы
CPU - Вас бы поддержали!
Здесь люди достаточно компетентные и копья над аналогичным вопросом здесь уже поломали...

Я думаю, если Вы себе четко распишете, что и с какой целью мы вводим в конструкцию ПК на ВМ80
и какой эффект мы в результате этого нововведения получим, Вы и сами увидите и узкие места, и
то, что критика не беспочвенна.


20 Mar 2015 13:47
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Stan wrote:
Я думаю, если Вы себе четко распишете, что и с какой целью мы вводим в конструкцию ПК на ВМ80
и какой эффект мы в результате этого нововведения получим, Вы и сами увидите и узкие места, и
то, что критика не беспочвенна.
В плане руководства - руководитель я никакой.
Ведь "допилил" тогда эмулятор и добавил к набору i8080-команд ещё и свои с префиксами, появился "защищённый" режим. Однако, как это дальше развивать - не понял.

Был ещё эмулятор чисто собственного процессора - одна команда=один байт. Со стеком, но не Форт, работает чуточку иначе. Написал демку - пахало. Но, сильно достало писать без регистров и т.д.

Сейчас на Verilog писал процессор-парсер. Листинг текстового формата обрабатывает аппаратно. Используются ПЗУ для дешифровки ASCII. На одну операцию уходит (в симуляторе) от десятка тактов до сотен - это без АЛУ, чисто чтение имени регистра и оператора.
Что интересно, занимаюсь им с 2008 года. А прогресса - никакого!

Нет, не скажу, что технически - нереализуемо. Просто, из меня "сам себе директор" - никакой... Чёткого плана нет.
Так:
Все 4Гб пространства процессора адресуются через имена переменных. Если "X" - 24 буква алфавита, то доступ к 26 ячейке ОЗУ происходит через "X". Длинные имена - сдвигаются и накапливаются. Адресуют остальные 4Гб памяти.
Например, "1debug = 4keybd >> 24" означает "считать 4 байта из вектора клавиатуры, сдвинуть, отправить как один байт в отладку. Число тактов - около 85...

И лишь в этом году догадался цифрами 1 и 4 в этой записи адресовать не число байтов, а указывать способ доступа. Т.е. 7 лет ушло на то, чтобы додуматься до элементарного...
А вот verilog-модель процессора в связи с этим доработать не смог: Листинг без комментариев, корявый и неизвестно, как именно вносить эту новость.
(спустя годы свой код легче переписать, чем корректировать. где-то что-то не то - читает листинг с ошибками)

Главное: Один человек процессором был заинтересован, так как сам пытался когда-то разработать нечто подобное. Но, помочь не может ничем - дальше идеи до теории дело не дошло. А у меня на практике - скупой опыт verilog и OrCAD...


20 Mar 2015 16:38
Profile WWW
God

Joined: 02 Jan 2006 02:28
Posts: 1390
Location: Abakan
Reply with quote
Paguo-86PK wrote:
А вот verilog-модель процессора в связи с этим доработать не смог: Листинг без комментариев, корявый и неизвестно, как именно вносить эту новость.
(спустя годы свой код легче переписать, чем корректировать. где-то что-то не то - читает листинг с ошибками)
[offtop]Я лет десять писал почти без комментариев, а потом пришёл к выводу, что это путь в никуда. Пришлось перестраивать ся. Теперь стараюсь комментировать избыточно, особенно замудрёные участки. Есть в этом действе как минимум два положительного аспекта:
- код из вида "чёрный ящик" превращается в знание, доступное в любое время;
- в процессе написания комментария структурируется собственное понимание описываемого процесса, со всеми вытекающими из этого выводами.
[/offtop]


20 Mar 2015 20:19
Profile
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
jdigreze wrote:
Я лет десять писал почти без комментариев, а потом пришёл к выводу, что это путь в никуда. Пришлось перестраивать ся. Теперь стараюсь комментировать избыточно, особенно замудрёные участки. Есть в этом действе как минимум два положительного аспекта:
- код из вида "чёрный ящик" превращается в знание, доступное в любое время;
- в процессе написания комментария структурируется собственное понимание описываемого процесса, со всеми вытекающими из этого выводами.
ПроЖекты я как-то не комментирую. Бью как попало на авось. К моему сожалению, эта идея за 7 лет так и стоит в статусе прожекта...
Версий процессоров (за 20 лет) было уйма. Большинство даже до тетрадки не доходило. Так в уме как появлялись, так и испарялись...

Есть любопытная идея процессора (идея 1997 года!), которую можно реализовать как OS (MenuetOS/KolibriOS). Она тоже сильно критикуется сообществом программистов. Но, нашёлся один гражданин, кто некогда тоже о таком думал. И всё! Глухо, как в танке...

Сейчас запустил свой проц в Icarus Verilog. Глянул... Короче, всё с нуля писать придётся:
 "Скриншот"
Attachment:
File comment: Процессор
cpu.jpg
cpu.jpg [ 272.03 KiB | Viewed 11104 times ]

А прошивку ПЗУ не помню, где генерировал (был html-файл с js-генератором - потерялся) :rotate:
Attachment:
File comment: ПЗУ декодера листинга
cpu_rom.zip [1.14 KiB]
Downloaded 444 times


P.S: Кстати, Maximite-таки и подталкивал, т.к. там встроенный Бейсик. Естественно, тысячи тактов на оператор. Вот и подумал, что аппаратно по сотне тактов у меня - не катастрофично...

P.P.S.: Написал набросок дизассемблера. Алгоритм "подгонял" под Verilog. Можно заметить достаточную простоту дешифрации, т.к. система команд распределена оптимально...
 "особенности"
Code:
00: hlt - если указатель команд будет сбит и прыгнет в нулевую область, сразу произойдёт исключение по останову;
FF: ret - в комбинациях с командами короткого условного перехода с неполным замыканием образуются 8 команд rcnd;
CC: cmc - в комбинациях с командами короткого условного перехода с полным замыканием образует 2 команды clc/stc;

Так уж получилось, что у меня в привычку вошло бить дампы инструкций с девизом
"сам себе ассемблер". Тем самым, во всех моих попытках проработать процессор я
всегда преследовал цель расставить команды по таблице максимально удобно как с
организации дешифратора, так и с чисто субъективной стороны с её ассоциативным
подходом. Просто взять и "размазать" команды по таблице я не мог, соблюдая при
этом чисто интуитивно ясную логику. Вот некоторые пояснения:
xA - Add
xB - suB
xC - and (Conjunction)
xD - or (Disjunction)
xE - xor (Exclusive or)
Bx - jmp/call (Branching)
Cx - inc (inCrement)
CC - cmc (Complement Carry)
Dx - dec (Decrement)
Fx - int (Function n)
FF - ret (Function Final)
Таким образом, можно не зазубривать команды, так как легко помнить логику всей
расстановки. При этом я старался экономить всё пространство команд и некоторым
командам присвоил длинные коды, так как частота их использования обычно бывает
достаточно низкой:
B0 FF - rz
B1 FF - rnz
B2 FF - rc
B3 FF - rnc
и т.д.
Получилось так, словно команды условного перехода служат префиксами перед ret.
При этом, дешифратор имеет некоторые механизма защиты от зацикливания. Скажем,
нельзя команды jmp/call полностью замыкать на самих себя. Но, таким замыканием
можно обращаться к скрытым ресурсам процессора. Так:
B8 FE - call $+0 - вызвала бы переполнение стека
B9 FF - call $+1 - ссылается на ret внутри себя же
и т.д.
Получилось 16 исключительных вызовов, куда можно включить некоторые команды, с
которыми программа медленно или редко работает: daa, das, mul, div.
Указатель стека имеет интересное свойство: Выравниваться по модулю 2. Обычно в
целях оптимизации программистам советуют выравнивать данные в памяти. И первый
бит указателя стека практически не используется. И появилась идея использовать
этот бит за флаг готовности/срыва стека. Например, команда ret "срывает" стек,
делая указатель "нечётным" установкой этого бита. При этом, любые операции для
работы со стеком (push, pop, call, ret) могут генерировать исключение, И когда
стек сбит, если код прыгает по нему командами ret, дальше второй команды здесь
процессор не сдвинется.


21 Mar 2015 04:42
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Итак, как я уже сказал, взял за основу процессор i8080 и полностью реорганизовал таблицу команд.
Написал дизассемблер. Но, как оказалось, дешифратор команд довольно просто доработать от показа мнемоники к непосредственному описанию алгоритма эмуляции каждой из команд.
Хотя, на данный момент многие команд недописаны или глючат. Но, "приветствие" уже пишет адаптированный фрагмент "оконной" печати текста от "РК".

Файл содержит всего 782 строки. Дешифратор работает в "духе" Verilog: Бит 0, бит 1, неопределённость X.(зачем именно так: планирую отладить в js и перенести в Verilog)
Можно убедиться, что всё написал как попало и очень быстро. Однако, работает...
Расчитан под экран 1280x1024.
(ассемблер ещё не делал, но существующий собственный x80-ассемблер легко перестроить под него)

Процессор реально 8-битный: Команды с 16-битными операндами исключены (jmp/call/lxi).

С нуля переписал основные части. Все команды описываются на одной странице на уровне макро-записей. Эмуляция оптимизирована: Все комбинации команд заранее заносятся в массив и готовы к исполнению непосредственно через eval().
Текущая версия


04 Apr 2015 11:56
Profile WWW
Writer

Joined: 19 May 2014 03:47
Posts: 17
Location: Челябинск
Reply with quote
Paguo-86PK wrote:
Эм-ммм...
1. Когда я изучал работу ВН59 (Микропроцессоры и микропроцессорные системы), если я не ошибся, понял, что ВМ80 настолько прост, что ВН59 сама ему отсылает команду call (CD xx xx). Разница в том, что счётчик команд PC при этом стоит на месте. Тем самым, в режиме генерации прерывания можно отправить не только одну команду call, но и десятки других арифметических, не двигая PC. Так ли?
Если так, значит, можно реализовать кучу возможностей.

Нет, не так. PC всегда либо инкрементируется, либо подменяется, либо сохраняется. ВМ80 действительно очень простой, но не тупой.
Когда ВН59 подсовывает код вызова подпрограммы, процессор её выполняет - со всеми вытекающими последствиями - т.е. инкрементирует сч.команд, сохраняет его в стек (2 байта) далее принимает новый адрес от ВН59 (2 байта) загружает его в счётчик команд, и приступает к выполению по новому адресу. Если знать адрес верхушки стека, можно адрес возврата подменить и выполнять другой код, т.е. не возвращаться в то место, где возникло прерывание, по команде RET ))
Насчёт коротких команд 8086 - если их собрать в кучу и выполнять только их - то будет РИСК процессор )), тут где-то ветка была про это для 8080.


15 Apr 2015 04:56
Profile
Devil

Joined: 26 May 2003 06:57
Posts: 859
Reply with quote
Bronto wrote:
Когда ВН59 подсовывает код вызова подпрограммы, процессор её выполняет - со всеми вытекающими последствиями - т.е. инкрементирует сч.команд, сохраняет его в стек (2 байта) далее принимает новый адрес от ВН59 (2 байта) загружает его в счётчик команд, и приступает к выполению по новому адресу.

В цикле обработки прерывания счётчик команд не увеличивается. Т.е. каким был счётчик команд до приёма от ВН59 команды CD xx xx, такой адрес возврата он и положит в стек.

А вот по поводу "несколько других команд, вместо CALL" - как Paguo-86PK задумывал не получится. В процессе приёма команды в цикле прерывания, прерывания запрещаются, таким образом запустить ещё один цикл прерывания не получится.

_________________
Страничка эмулятора наших компьютеров
http://bashkiria-2m.narod.ru/


16 Apr 2015 11:39
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Тихонечко допиливаю свою идею.
в демке: пассивный Ксоникс (тупо чистит экран) и интерактивный Тетрис (реагирует на клавиши курсора)
Так как племянница сравнила таблицу команд с таблицей умножения, пришла мысль навесить на разработку ярлык RISC-процессора, но с поправкой - Rebused Instruction Set Computer. Так как MISC'и тоже имеют несколько понятий. И звучит несколько эзотерично: Компьютер с $ системой команд.

На днях нашёл способ организации портов ввода-вывода без ввода специальных команд. Просто взять и все попытки доступа к ячейкам памяти за пределами 64кб обрабатывать за порты.
Помните, проблема x86 с выходом за границы пространства сегмента за 1Мб была решена расширением до 1088Кб. Здесь же похожая ситуация.
На примере Z80 это представляется так: Если IX=0FFFFh, индексная операция LD (IX+$01),A с перескоком на 0000h выставит флаг (в моём случае) переполнения и обеспечит доступ к порту #00.
Особенно со стеком: Если SP=0FFFFh, тот любой POP вернёт не содержимое памяти, а внутреннее состояние (аналог CPUID) с запоминанием позиции. Т.е. 10 POP вернёт 10 служебных слов. При SP=0 команды PUSH также управляют служебными регистрами.
Почему я иду таким путём? Помните, я высказывал собственное недовольство, что некоторые рудиментные x86-операции (AAA, AAS, AAD, AAM и т.д.) практически не используются, а сожрали драгоценные байты системы команд (в x64 всё зачистили, выбросив и INC/DEC)? И многие команды тоже нельзя использовать (CLI, STI, HLT и остальные) прикладному коду. Потому я решил пойти этим путём: Выход к портам доступен через "визовую систему бюрократии" (как в жизни). Доступ к служебным данным (счётчик тактов, регистр отладки, режим "реального i8080" - как в x86) - всё через переполнение стека...

Так же ввёл обратные операции АЛУ:
Code:
   6B|SUB AL,CL ; AL = AL - CL
44 6B|SUB    CL ; AL = CL - AL

Но пока это ещё всё сыро, так как реверсные SUB, SBB и CMP ещё нормально. А вот ADD, ADC, AND, OR, XOR - без эффекта. Пустая трата длины кода. Думаю, ввести на их место в случае реверса команды NXOR, NOR, NAND или такие же операции, но без возврата результата (как в x86 AND и TEST).
Code:
   6C|AND AL,CL ; AL = AL & CL
44 6C|AND    CL ; Flags of (AL & CL) (like x86-TEST)
   6A|ADD AL,CL ; AL = AL + CL
44 6A|ADD    CL ; Flags of (AL + CL) (vs CMP-action)


P.S.: Кстати, я не случайно задумку назвал "x80": Аналог линейки x86.
Отличие лишь в том, что имеется некая мысль воспроизвести подобие линейки. Так:
  • 080-ый процессор: 0-е расширение 8-битного с модификацией 0
  • 180-ый процессор: 1-е расширение 8-битного (8 << 1 == 16) - 16-битный
  • 286-ой процессор: 2-е расширение 8-битного (8 << 2 == 32) - 32-битный с модификацией 6
  • и т.д.
 "Пример"
Зачем же это надо? Чисто, ради любопытства.
Так, если 080-ый аккумулятор AL имеет 8 бит, то 180-ый будет иметь 16 бит, хотя в системе команд будет всё также (в отличие от x86, где есть AH и AL в паре AX). А в 280-м AL должен иметь 32 бита:
Code:
; 080-processor
   AC 7E         |AND AL,0x7E
33 AD EC         |OR  DH,0xEC
   BC 78         |JC  $+0x78
; 180-processor
   AC 7E 3F      |AND AL,0x3F7E
33 AD EC 76      |OR  DH,0x76EC
   BC 78 56      |JC  $+0x5678
; 280-processor
   AC 7E 3F 9F CF|AND AL,0xCF9F3F7E
33 AD EC 76 3B 9D|OR  DH,0x9D3B76EC
   BC 78 56 34 12|JC  $+0x12345678

Т.е. никаких AX, EAX и всяких RAX. И совместимость кода обеспечит в обе стороны. Теоретически... На практике - любопытно будет узнать о подводных камнях...
Можно подметить, что если в 180 используется 16-битный DH, то в паре с DL - DX будет иметь 32 бита. Как указатель - это уже 4Гб памяти. Соответственно, в 280 - 32-битные DH и DL - DX с 64 битами... Косяки идеи?


P.P.S.: С Праздником Победы, Товарищи!
Сделал поправку:
  • 080-й процессор: 0-е расширение 8-битного с модификацией 0
  • 189-й процессор: 1-е расширение 8-битного (1*8 = 8 бит аккумулятора) (16-бит адреса) с модификацией 9
  • 287-й процессор: 2-е расширение 8-битного (2*8 = 16 бит аккумулятора) (24-бита адреса) с модификацией 7
  • 386-й процессор: 2-е расширение + 1 ядро-помощник (16 бит и 2 ядра) (24-бита адреса) с модификацией 6
  • 485-й процессор: 4-е расширение 8-битного (4*8 = 32 бит аккумулятора) (32-бита адреса) с модификацией 5
  • 583-й процессор: 4-е расширение + 1 ядро-помощник (32 бита и 2 ядра) (32-бита адреса) с модификацией 3
  • 682-й процессор: 4-е расширение + 2 ядра-помощника (32 бита и 3 ядра) (32-бита адреса) с модификацией 2
  • 781-й процессор: 4-е расширение + 3 ядра-помощника (32 бита и 4 ядра) (32-бита адреса) с модификацией 1
Гуглил, наткнулся:
http://comp-science.narod.ru/E97/e97-1.htm
http://educomp.runnet.ru/mmix/mmixart.html (00 - STOP / HALT / HLT)
http://itc.ua/news/c-h-p-mikrokompyuter-stoimostyu-vsego-9/
программы могут быть изящными, даже очаровательными (к чему я стремлюсь в таблице команд)
Перечитав статьи, понял, что нужно жёстко придерживаться выбранного курса.
Эмулятор переписываю с нуля. Изменений - никаких. Только устраняю излишки дешифратора и пользовательского интерфейса.
Только надо вводную информацию написать нормальным языком...


23 Apr 2015 15:38
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Чтo бывает, когда на месяц исчезает полноценный доступ в интернет?

x80-CPU - доработка:
Взялся допиливать свой x80-эмулятор спустя год. С неделю ушло на вникание в суть собственного JS-листинга.
За месяц доработал концепцию системы команд, устранил множество тупейщих глюков (вылавливал некоторые до 3-5 часов, топчась на месте всю ночь).

Что хочу сказать по поводу внесённых доработок и нововведений…
  1. У флагового регистра обычно возможны невозможные комбинации. Например, когда SF и ZF установлены, получается, что результат равен НУЛЮ и так же имеет знак МИНУС. Всего насчитывается 6 подобных нереальных комбинаций. Они используются для особых случаев. Таких, как повтор следующей инструкции n-раз или пропуск n-ого числа инструкций. Чем управляют инструкции SKIP/LOOP;
  2. Префиксированные инструкции HLT оформились в опции регистра или числа для разных операций. Так, перед CALL/INT можно указать, какой именно регистр нужно использовать, например, в печати символа, числа, адреса или сообщения;
  3. Инструкции PUSH/POP могут использовать и 8-битные РОН в рамках внутреннего мизерного стека / регистрового файла* (здесь пока всё сыро и требует много переработок исходника эмулятора).
 "* - детальнее"
Code:
EX-Register
__ .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
00:Ячейки управления распределением страниц памяти|RAM Dispatcher
10:Ячейки управления распределением страниц памяти|RAM Dispatcher
20:Ячейки управления ловушками в процессе отладки-|Debug Managing
30:Счётчики тактов, циклов, прерываний и т.д.-- --|Process Counters
40:JP>>LO>> ++ .. -- -- -- JP>>HI>> ++ .. -- -- --|JP-File
50:SP>>LO>> ++ .. -- -- -- SP>>HI>> ++ .. -- -- --|SP-File
60:BP>>LO>> ++ .. -- -- -- BP>>HI>> ++ .. -- -- --|BP-File
70:IP>>LO>> ++ .. -- -- -- IP>>HI>> ++ .. -- -- --|IP-File
80:SI>>LO>> ++ .. -- -- -- SI>>HI>> ++ .. -- -- --|SI-File
90:DI>>LO>> ++ .. -- -- -- DI>>HI>> ++ .. -- -- --|DI-File
A0:AL>>LO>>Стек истории -- AH>>HI>> ++ .. -- -- --|AX-File
B0:BL>>LO>>модификации- -- BH>>HI>> ++ .. -- -- --|BX-File
C0:CL>>LO>>всех РОН- -- -- CH>>HI>> ++ .. -- -- --|CX-File
D0:DL>>LO>> ++ .. -- -- -- DH>>HI>> ++ .. -- -- --|DX-File
E0:Стек конвейера с историей исполненных операций-|Execution Pipeline
F0:-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --|Execution Pipeline
+0:Зона особого назначения ???????????????????????|Service context
EX-Регистр - хранит контекст процессора.
Ячейками с 50h по DFh непосредственно связаны все РОН в режиме стекового файла с
глубиной до 8 уровней. Тем самым, когда какой-либо регистр изменяется, автоматом
история его изменений циклически сдвигается от ячейки с x0h/x8h к ячейке x7h/xFh
соответственно. Это позволяет в отладчике частично прокрутить историю исполнения
кода в обратном направлении. Так, ячейки 0-FFh доступны программе в произвольном
доступе. Ячейка +0 - это 256 управляющая ячейка управления переключением страниц
контекста, доступная только операционной системе, хранящая маску доступности для
остальных ячеек +1..+7 (257..263).
Битами этих сервисных ячеек можно "заморозить" историю контекста, чтобы получить
произвольный и точный доступ ко всем доступным моментам или сохранить контекст и
подготовить его для переключения к следующей задаче.


Подробнее:
HLT R/P: Фиксирует индекс РОН или регистровой пары в флаговом регистре для особых операций или управления повтором/пропуском/трюков;
HLT N: Фиксирует число 1-7 в флаговом регистре для особых операций или управления повтором/пропуском/трюков;
LOOP R: Управляющая инструкция LOOP CL выставляет флаги SF PF ZF, что фиксирует указатель инструкций IP на месте до автоматического обнуления CL. Так можно выполнить, например, инструкцию RCL AL нужное число раз, указываемым через CL;
LOOP N: Управляющая инструкция LOOP 5 выставляет флаги SF PF ZF, что фиксирует указатель инструкций IP на месте на период до 5 циклов. Всё это время, например, следующая инструкция RCL AL будет исполняться;
LOOP [R]: Управляющая инструкция LOOP [CL] выставляет флаги SF PF ZF, что фиксирует указатель инструкций IP на месте на период до 7 циклов, указаных тремя битами регистра. Так можно выполнить, например, инструкцию RCL AL нужное число раз, указываемым через CL;
SKIP R: Управляющая инструкция SKIP DL выставляет флаги SF ZF и сбрасывает PF, что блокирует шину фиксации результата на период до автоматического обнуления DL. Тем самым, все следующие операции продолжат дешифровываться, но не будут результативными;
SKIP N: Управляющая инструкция SKIP 7 выставляет флаги SF ZF и сбрасывает PF, что блокирует шину фиксации результата на период до 7 циклов. Тем самым, все следующие 7 операций дешифруются, но не будут результативными;
SKIP [R]: Управляющая инструкция SKIP [DL] выставляет флаги SF ZF и сбрасывает PF, что блокирует шину фиксации результата на период до 7 циклов, указаных тремя битами регистра. Тем самым, все следующие операции продолжат дешифровываться, но не будут результативными;
NOP N: Холостая операция с длительностью до 7 дополнительных тактов;
XCHG: Трюковая инструкция зеркального обмена всех битов в регистре, указаном через HLT R;
XCHG R: Трюковая инструкция обмена значениями указанного регистра с регистром, выбранном через HLT R;
XCHG P: Трюковая инструкция обмена значениями указанной регистровой пары с парой, выбранной через HLT P;
PUSH/POP: Трюковые операции (регистр не указан) используют регистровую пару, выбранную через HLT P;
INT 0-9: Обращение к функции прикладной программы. Используется общий регистр указателя на обработчик;
INT 10-79: Обращение к функциям системного API. Используется системный регистр указателя на BIOS-обработчик.
CALL/Ccnd: Замыкание вызова на саму себя изменяет флаги SF PF ZF, подобно трюковым SKIP/LOOP без указания регистра. Комбинация HLT R/P и CALL-замыкания - длинное подобие LOOP/SKIP.

Период тестирования:
На данный момент более-менее отладил дизассемблер, ассемблер и сам дешифратор команд.
Пока написал жалкое подобие BIOS с несколькими крошечными библиотеками:
INT 10-19 - функции работы с памятью (пока 0% написано);
INT 20-29 - функции работы с текстом (5%);
INT 30-39 - функции работы со звуком (1% - Beep);
INT 40-49 - функции работы с данными/математикой (0%);
INT 50-59 - функции работы оборудованием (0%);
INT 60-69 - функции работы с потоками/файлами (1% - GetChar/Inkey/IsPressed);
INT 70-79 - функции работы с дисплеем/окнами (10%).

В целом, проделанный труд доставляет некоторое удовольствие своей работой.
В самой BIOS работают несколько директив: (D)ump / (G)oto / (I)dle.
Idle просто дублирует поток с клавиатуры/буфера в окно собственного дисплея - тестирую производительность скроллинга и т.д.
 "Напомнить, про что шла речь давным-давно"
Система команд i8080 была мнемонически подогнана под стиль x86 (MVI A,3 -> MOV AL,3; DAD D -> ADD BX,DX; XTHL -> XCHG IP,[SP] и т.д.) и пересортирована:
Code:
   00    - HLT (0 - завершает текстовые строки, заполняет значительную часть памяти и т.д.);
   tr    - MOV r,t (если t и r умещаются в восьмиричный диапазон, то t индексует регистр-транслятор данных в регистр-приёмник r: 40 - MOV [BX],AL / 04 - MOV AL,[BX]);
   nn    - prefix n (если младшая тетрада кода команды и старшая - равны и умещаются в восьмиричный диапазон, то это - префикс: 11 - Prefix BH/BP / 77 - Prefix DL/DX);
   rC    - AND AL,r (Conjunction - конъюнкция аккумулятора с регистром: 5C - AND AL,BL);
   rD    - OR AL,r (Disjunction - дизъюнкция аккумулятора с регистром: 6D - OR AL,CL);
   Ar nn - MOV r,nn (загрузка байта в регистр: A7 34 - MOV DL,0x34);
   Bc nn - Jc/Cc $+nn (Branch - условное ветвление: BC 09 - JC $+9 / BE FD - JE $-3);
   Ep    - PUSH ptr (Enter ptr to stack - код явно указывает на имя регистровой пары: EB - PUSH BX / EC - PUSH CX / ED - PUSH DX);
   Fp    - POP ptr (Fix ptr from stack: FC - POP CX);
   Fn    - INT n (Function 0-9 - прерывание на функцию n: F1 - INT 1 / F9 - INT 9);
   FE    - NOP (Fictive Execution - фиктивная холостая операция);
   FF    - RET (Function Final - завершение функции).
Если перед командой стоит префикс, она несколько изменяется:
Code:
22 00    - HLT CH/SI (Hold CH/SI - захват регистра перед обращением к функции);
55 55    - HLT 5 (четыре одинаковые цифры - захват этой цифры для передачи функции);
22 5C    - AND CH,BL (префикс подменяет аккумулятор нужным регистром);
11 6D    - OR BH,CL;
77 A7 34 - MOV DL,[DX+0x34] (загрузка байта в регистр из памяти со смещением);
33 F5    - INT 35 (прерывание расширяется до индекса с десятками);
44 FE    - NOP 4 (холостая операция продливается на 4 такта);
66 ED    - SKIP 6 (Exclude by Data 6 - исключение результативности до 6 инструкций);
55 EC    - SKIP BL (Exclude by Counter BL - используется регистр за счётчик);
33 EB    - SKIP [DH] (Exclude by Buffered DH - значение счёта берётся из регистра);
77 FD    - LOOP 7 (Force til Data 7 - форсировать инструкцию на 7 циклов);
B9 FE    - WAIT (CALL замкнутая на себя - выполнение следующей инструкции в цикле (с декрементом регистра/счётчика) до прихода сигнала от внешнего устройства).


Тем самым, ассемблерно система команд сходится с i8086, что упростит перенос некоторых алгоритмов. А по режимам адресации почти не уступает i8086, что предлагает дополнительную гибкость кода, почти как у Z80.
Например, чтобы получить доступ к портам ввода/вывода, необходимо регистр BP выровнять под IP. Так как считывать/записывать данные косвенно по BP вблизи исполняемого кода нельзя, открывается окно на 256 портов.
Code:
EB EC    PortIn:PUSH BX,CX     ; Запоминаем регистры
66 CF           XCHG CL        ; Узнаём предельный интервал ожидания
B1 +9 FB        LEA  BX,.input ; Выравниваемся по указателю команд
45              MOV  BL,AL     ; Устанавливаем индекс порта
11 55           XCHG BP,BX     ; Открываем портовое окно через BP
4B              SUB  AL,AL     ; Сбрасываем флаг переноса CF
66 00           HLT  CL        ; В ожидании используется CL
B9 FE           WAIT           ; Перевод процессора в цикл ожидания
11 A4 00 .input:MOV  AL,[BP+0] ; Читаем порт до тех пор, пока CL > 0 и флаг CF равен внешнему сигналу
66 AA FF        ADD  CL,0xFF   ; Если CL обнулён, значит готовности порта не дождались и CF обнуляем
11 55           XCHG BP,BX     ; Восстанавливаем указатель
FC FB           POP  CX,BX     ; А также все регистры
FF              RET            ; Возвращаемся
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EC       GetKey:PUSH CX        ; Процедура ожидания и ввода с клавиатуры
A5 21           MOV  CL,0x21   ; Длительность ожидания - до 33
A4 60    .loop: MOV  AL,0x60   ; Индекс порта клавиатуры
66 00           HLT  CL        ; Счётчик ожидания - CL
B9 DD           CALL PortIn    ; Вызываем процедуру чтения с порта
BD F8           JNC  .loop     ; Зацикливаемя до первого ввода с клавиатуры
FC              POP  CX        ; Восстанавливаем регистр
FF              RET            ; Возвращаем код клавиши

Имеется ещё одна любопытная особенность: Так как я своими силами не могу реализовать полноценный конвейер с распараллеливанием под Verilog, концепция процессора подразумевает явный параллелизм и ускорение некоторых фрагментов алгоритмов.
Так как в файле контекста текущей задачи процессора всегда хранятся значения всех регистров и цепочки последних выполненных инструкций, то некоторые из цепочек можно объединить в одну инструкцию и выполнять в рамках статического доступа к файлу контекста. Тем самым, на каждую инструкцию будет затрачен всего 1 такт. Всего можно выполнить цепочку до 7 инструкций.
Никакой особой инструкции в системе команд для этого не предусматривается.
Сначала следует команда SKIP 1-7, которая пропустить даром следующие инструкции до 7 штук. Во время пропуска, все их коды сжимаются и попадают в отведённый буфер контекста.
Затем, после заполнения буфера нужными инструкциями, переходим к команде HLT 1-7/REG, чтобы зафиксировать продолжительность цикла.
После всего, следует операция WAIT для запуска цикла ожидания. За которой нужно обязательно указать префиксированную холостую операцию NOP 1-7.
Только в этом случае, после всех шагов, индекс операции NOP укажет, цепочку какой длины нужно выполнить в буфере контекста.
А так как операция цикла WAIT очень строгая и капризная, цикл в любой момент может прерваться, если флажки неправильно выставятся экспресс-операциями. За чем нужно строго следить.
Например, рассмотрим пример со скроллингом экрана вверх:
Code:
; Исходный фрагмент кода скроллинга буфера экрана без оптимизации
;;;;;;;;;;;;;;;;;;;;;;;;;
...rows:ADD     BX,CX   ; Движемся циклом снизу вверх по экрану
        MOV     DL,AL   ; Берём код затёртого символа строкой ниже
        MOV     AL,[BX] ; Считываем код затираемого символа
        MOV     [BX],DL ; Записываем затёртый ниже символ сюда
        DEC     DH      ; Считаем число смещаемых символов в столбце
        JNZ     ...rows ; И циклом заставляем ползти символы вверх
Код специально построен так, чтобы в оконном режиме прокручивать произвольный прямоугольник. Как видно, код ничем не отличается и выглядит привычно. Правда, работает значительно медленнее, чем хотелось бы. Поэтому, переходим к рассмотрению следующего кода с оптимизацией:
Code:
; Тот же фрагмент кода, но с оптимизацией
;;;;;;;;;;;;;;;;;;;;;;;;;
        SKIP    4       ; Следующие 4 инструкции сейчас проигнорируются
        ADD     BX,CX   ; 1.Движемся циклом снизу вверх по экрану
        MOV     DL,AL   ; 2.Берём код затёртого символа строкой ниже
        MOV     AL,[BX] ; 3.Считываем код затираемого символа
        MOV     [BX],DL ; 4.Записываем затёртый ниже символ сюда
        HLT     DH      ; Захват регистра за счётчик строк столбца
        WAIT    ; Активация режима ожидания с ограничением по времени - DH
        NOP     4       ; Теперь пропущенные выше 4 инструкции из буфера
                        ; будут выполняться циклом в турбо-режиме
Первое, на что можно обратить внимание - отсутствие метки и команды ветвления. Бинарно размер кода увеличился с 8 байтов до 13. Однако, так как теперь выполняется лишь одна операция NOP 4, прирост в скорости на экрана виден сразу примерно на 20%.
Естественно, имеются сильные ограничения. Например, в экспресс-цепочке нельзя использовать команды ветвления, программных прерываний, управления сменой режима.
Ограничения имеются и на константные операнды команд - они усекаются до 5 бит. Т.е. операнд 0x7C станет 0x0C, 0x82 - 0xF2. Что требует выносить все константы за границы самих инструкций, заранее загружая их в регистры.
А ограничение на цепочку до 7 инструкций - не такое уж существенное. Так как в ряде случаев достаточно обойтись и парой инструкций.
Так, аналог команды REP MOVSB от x86:
Code:
    SKIP    4       ; Следующие 4 инструкции пропускаем и помещаем в экспресс-буфер
    MOV     AL,[BX] ; 1.Читаем байт источника
    INC     BX      ; 2.Двигаемся к следующему
    MOV     [DX],AL ; 3.Записываем байт в приёмник
    INC     DX      ; 4.Подготавливаемся принимать дальше
    HLT     CL      ; Счётчик количества копируемых данных - CL
    WAIT            ; Всё готово к началу цикла
    NOP     4       ; Теперь данные скопируются несколько скорее


На скриншоте в архиве можно увидеть систему команд в действии эмуляции под Chrome.
Ниже - вся система команд (в левом верхнем углу числа +11..+77 означают код префикса перед этими командами:
Attachment:
File comment: Система команд x80 и их 7 префикс-расширений
0_7x80.gif
0_7x80.gif [ 177.97 KiB | Viewed 9939 times ]

P.S.: К своей идее отношусь как к хитрой головоломке:
Когда вокруг меня все тычат пальцами в экраны своих андроидов с цветными камнями или монстрами, свои мозги тренирую в проработке собственного процессора и архитектуры :roll:
Скоро выложу эту текущую версию в свой GitHub (когда набросаю заготовку Тетриса или Ксоникса :wink: ).
1 декабря 2016

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

Многие из интересных тем этого ресурса, как например "Троичный компьютер" или заказные троичные чипы, довольно интересны…
Но, как мне видится, главный недостаток многих тем в том, что основное большинство просто следит за продвижением идей или наблюдает за попытками их реализации. В подавляющем большинстве случаев - совершенно пассивно. Иначе, например, могли бы вместе сложиться копеичками и собрать на партию заказных микросхем. Правда, при условии, что кто-то их протестирует заранее в симуляторах и устранит очевидные ошибки…
Ну, да ладно, не мне вмешиваться в чужие дела…
По другому поводу я решил здесь изложить некоторые дополнения.
Дело в том, что в очередной раз пересматривая схему РЛК с попыткой внесения незначительных изменений, заметил одну интересную вещь. Читал, что производство микросхем с цоколовкой, отличной от DIP-14 или DIP-40 в те времена было достаточно проблематичными. Хотя у M68000 насчитывалось целых 64 вывода… Ведь, например, встроить ПДП в сам процессор, как это было в Денди на 6502, было бы вполне реально, так как внутренние шины процессора и ПДП во многом идентичны, да и позволило бы избавиться от глупого захвата шин с их задержками во времени.

Как я выше уже писал, в своих набросках процессора я возложил рутину ПДП на сам процессор. Причём, не простым набором счётчиков, а отдельным служебным процессом…
Вот с чем идёт битва и сложный стратегический процесс - так это порты! Ладно, многие предлагают устройствам отводить часть общего адресного пространства, как в РЛК, не заморачиваясь. Но, у Intel была одна любопытная идея, однако, реализованная крайне безобразно.
Речь идёт про Esc-инструкции. В документации процессора i8086 про Esc-инструкции говорится как об универсальных, которые могут применяться и математическим сопроцессором в частности. Хотя, из документации предполагалось менее конкретное их назначение. Но, как я понял, решение окончательно определить их за арифметику - просто загубило их изначальную универсальность.

Таким образом, на данный момент я работаю над тем, чтобы избавиться от рудиментов портового доступа к УВВ и приблизиться к неким Esc-аналогам.
Выше я уже писал, что испытывал сложности с операциями повтора инструкций присвоения, как loop 7 + mov al,bl… Понятно, что бессмысленно много раз производить пересылку из регистра в регистр. И выход был найден.
Так, циклические LOOP-операции с MOV-пересылками работают подобно Esc-операциям из x86. Тем самым, если нужно передать или принять данные через регистры с УВВ, нужно просто указать в LOOP число параметров и разместить далее MOV-команды. Чем будет достигаться внедрение УВВ в саму систему команд процессора…


Attachments:
File comment: 99 кадров эмуляции под Chrome
100x80.rar [1.87 MiB]
Downloaded 402 times
01 Dec 2016 11:20
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Набросoк Verilog-модели
Криво, но немного работает.


29 Aug 2018 20:03
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 29 posts ]  Go to page Previous  1, 2

Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.