nedoPC.org

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



Reply to topic  [ 182 posts ]  Go to page Previous  1 ... 8, 9, 10, 11, 12, 13  Next
Запустить 8086 в минимальной обвязке? 
Author Message
Doomed

Joined: 16 Dec 2014 11:58
Posts: 370
Location: Киев
Reply with quote
Post 
Я обещал верилог и схему - собственно, готово... (более или менее).
По крайней мере, в симуляторе работает. Реализованы 8284, 8288, зачаток декодера адреса и, собственно, сам перестановщик (steer).

Куда посоветуете выложить архив? Желательно, чтобы интересующиеся (если таковые будут) могли скачать без говнорекламы. Ни разу на файлопомойки ничего не клал :)

Пока результат симуляции. Читается слово из порта 0, эталон = 55AAh.
На название "поиск" просьба не обращать внимание, надо же было его как-то назвать :)
Image

Дорисовал вручную такты, чуть правее, чем следовало бы, чтобы не затирало моменты изменения сигналов.
Вверху сигналы 8288, там в общем-то все очевидно, имеем два IORD вместо одного.
С помощью STEER_RDY роняем READY проца, заставляя вставлять Tw.
SELH служит сразу нескольким целям - добавляет через внешний OR единицу к A0 и переключает коммутарторы D15:D8 / D7:D0 <-> BD7:0.
При чтении нужно запомнить младший байт - при переключении коммутаторов во втором "цикле" он с шины пропадет. Поэтому фиксируем его у себя (D_IN -> D_OUT), после чего во втором цикле выставляем на шину. Старший байт поступает прямо с коммутатора, и проц забирает целое слово.
При записи таких проблем нет (проц держит данные на обеих половинках).
Сигнал EXT_DEV эмулирует IO16/MEM16 у ISA-16, т.е. сообщает нам, работаем мы с 8- или 16-битным девайсом (определяется по адресу).

Как выложу архив, напишу описание поподробнее.


22 Dec 2014 04:13
Profile
Devil

Joined: 30 Nov 2013 11:08
Posts: 706
Location: WWW
Reply with quote
Post 
8284 и 8288 насколько полно реализованы ?

Если достаточно полно, откуда брали информацию насчет внутренних деталей работы - что-то помимо datasheets ?


22 Dec 2014 07:40
Profile
Doomed

Joined: 16 Dec 2014 11:58
Posts: 370
Location: Киев
Reply with quote
Post 
Кроме даташитов - ничем, ну разве что Казаринов (МП комплект 1810), но он почти слово в слово повторяет даташит. Ну и гугл, да...
Реализация:
8284 в рамках необходимого - т.е. по эквивалентной схеме (из даташита) сделан канал RDY1 (AEN1, второй канал, F/C, EFI выкинуты за ненадобностью), двойная синхра по READY (фронт/спад), нет генерации PCLK - так и не понял, на кой оно надо. Реализуется, при необходимости, имхо, элементарно. Reset, CLK из OSC - все по даташиту.
8288 - опять же, 1:1 тайминги даташита. В качестве сигналов записи взял AMWTC/AIOWC, так проще было :) Не делал AEN/CEN, точнее, AEN есть, но он внутренний, т.е. не вход, а выход схемы захвата шины от DMA, он же HLDA. Что касается CEN - DT/R при захвате шины DMA не выключаю - смысла нет, DEN все равно буфера задавит. Если очень надо 1:1 с оригиналом - выключить очень легко. DEN, разумеется, отключается, как и командные линии.
PDEN/MCE - выкинуты за ненадобностью.

Собственно, DMA уже почти есть, захват шины отрабатывается, регистры пишутся/читаются, но цикл работы не написан, зацепился за этот перестановщик.

Что касается внутренних деталей - а зачем? Есть ЧЯ, есть тайминги работы. Конечно, интересно было бы посмотреть на работу в нештатных ситуевинах, но я же не космический корабль делаю :) Так - ДОС погрузить, нортоном побаловаться.

Я прошу заметить, что это все исключительно в симуляторе, так что особых надежд не возлагайте :) Железки у меня попросту нету, ни альтеры, ни проца. Буду у китайцев брать в скором времени.


22 Dec 2014 08:11
Profile
Devil

Joined: 30 Nov 2013 11:08
Posts: 706
Location: WWW
Reply with quote
Post 
Наверное, я плохо смотрел, но мне datasheet 8288 не хватило для точной (на мой взгляд) реализации, поэтому плюнул и сделал железно - http://www.nedopc.org/forum/viewtopic.p ... c&start=15

Кстати, с Нортоном у меня какой-то затык - после загрузки ДОС думал, что все автоматом получится, но не тут то было. Пишет нормально copyright, доходит до вывода нижней строчки, а потом улетает в никуда очень странным образом... Учитывая, что у меня еще и BIOS свой, не до конца написанный, разобраться сходу не получилось. Возиться пока прекратил - времени не хватает...


22 Dec 2014 08:33
Profile
Doomed

Joined: 25 Aug 2009 07:02
Posts: 459
Location: Москва
Reply with quote
Post 
Vic3Dexe wrote:
... AEN1, второй канал, F/C, EFI выкинуты за ненадобностью...
... PCLK - так и не понял, на кой оно надо ...
... взял AMWTC/AIOWC, так проще было :)
... Не делал AEN/CEN ...
... PDEN/MCE - выкинуты за ненадобностью.

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


22 Dec 2014 13:08
Profile
Doomed

Joined: 16 Dec 2014 11:58
Posts: 370
Location: Киев
Reply with quote
Post 
http://my-files.ru/6exwbt
Собсна, вот. Внутри схема минимальной обвязки в DipTrace + проект под квартус.

О схеме
Не надо это собирать :) Схема более эскиз, нежели принципиальная - просто чтобы было понятно, какой сигнал чем рулит.
RAM нет, она для запуска не нужна. ROM 2 штуки по 32к, на младший и старший байт ШД. Можно обойтись одной 16-битной.
Разъем ISA условен, опять же, чтобы было понятно, что туда выводится.
Генератор OSC - KXO-97 на 30 МГц.

Нет ни защитных буферов, ни согласования 3.3V <-> 5V, ни блокирующих кондеров. Короче, голая логика.

О проекте
В качестве тэзэ я принял 8086-1 в максимальном режиме с возможностью обмена с 8-битной внешней шиной.

"Чипсет" сначала планировал на MAX V (CPLD), но отсутствие встроенной RAM хотя бы байт на 100-200 убило. Регистры DMA превратились в монстрообразную кашу из D-триггеров и коммутаторов, сожрав порядка 300 LE из 1500 доступных в топовом MAX V.
Поэтому переехал на циклон 4, меньшие последний квартус выбрать не дает. Да, из пушки по воробьям. Но это решаемо, я думаю.

Блок 8284 состоит из счетчика, который формирует CLK из OSC, двойной синхронизации READY и синхронизации RESET.
Входов READY три штуки - IORDY (сигнал с шины), DMARDY, его может ронять DMA, когда занимается своими делами, и STEER_RDY, который роняет перестановщик байтов, удлинняя цикл для обмена двумя байтами вместо одного. На вход синхронизатора в 8284 это все заведено через AND.
Вход RESET также является AND 2 входов - от кнопки и PWRGOOD от ATX БП.

Блок 8288.
Главной проблемой, как ни странно, стал момент определения начала цикла. Согласно спецификациям, S0-S2 могут упасть как до начала Т1, так и после. Соотв., ALE начинается от момента "кто позже упадет" - S или CLK. Вроде просто, но объяснить это квартусу я толком не сумел. Надо будет переделать, то, что есть, мне не нравится, хотя и работает.
Для DT_R фактически делается 2 одинаковых по длительности сигнала - один сам DT_R (т.е. падающий в 0 при чтении), второй - DT_R_POS, всегда =1, для формирования сигналов чтения-записи. Есть соблазн получать DT_R из DT_R_POS и сэкономить регистр, но не выйдет, пробовал.
DEN я сразу делаю инверсным (DEN_INV), так как для чтения и записи у него разная длительность, соотв. реально формируются 2 сигнала DEN_R и DEN_W, а результат суммируем по AND.
Отдельная тема INTA. Проц генерит их 2 штуки подряд, выставляя LOCK, дабы чего не вышло. Согласно спекам, DT_R/DEN нужно формировать только для второго INTA, поэтому введен счетчик таковых и учтен.
AEN_INV разрешает работу регистров адреса проца (которые по АЛЕ), встает в 1 только при захвате шины DMA. Для простоты будем считать, что AEN_INV всегда =0, т.е. DMA никогда не получит шину.

Перестановщик (bus steering, далее ПС). Собственно, зачем он нужен - примерно понятно, у проца ШД 16 бит, а на внешней шине - только 8.
Первоначальной идеей было просто генерить 2 полноценных цикла, т.е. ПС перехватывает S0-S2 между процом и 8288, после чего в "T3" на некоторое время подпирает их единицей и через такт снимает, имитируя начало нового цикла. Одновременно с подпиранием меняем A0 шине 0->1 и подсовываем ей старшую половину шины проца.
Сделал так, потом сунул нос в ISA bus architecture, а в 286 чипсете, оказывается, попросту дергают MRD/MWR/IORD/IOWR. Поэтому переделал именно в такой вид, экономия - аж 1 такт.
Попутно наткнулся на проблему: шина проца физически сводится к 8-битной двумя коммутаторами, переключаются которые по SELH. При записи все в порядке - источник (проц) предоставляет данные для обеих половин шины. Однако, при чтении, у нас так или иначе будет источник только для какой-то одной половины шины. Т.е. мы-то прочитаем с шины младший байт, но после переключения коммутаторов на старшую половину, он потеряется. Поэтому просто запоминаем его в FPGA, после чего подсовываем процу во 2 "цикле".

Работа перестановщика основана на счетчике тактов, он считает фронты CLK, как только упали S0-S2, доходит до 11b и более не меняется, обрано в 0 - по фронту S0-S2 либо если отработал "подпиратель" командных сигналов, т.е. мы начали 2 "цикл".
По этому счетчику ориентируется STEER_RDY, пока у нас первый такт, надо что-то быстро предпринять, иначе двойная синхра в 8284 растянет цикл. Поэтому, пока счетчик в 00b, по спаду CLK роняем этот сигнал в первом цикле (SELH = 0) или поднимаем в 1 во втором (SELH = 1). Далее, по следующему спаду, принимаем решение - формировать второй цикл или нет. Почему не сразу? Потому что только здесь A0 и BHE валидны, т.е., проц выставил их на ноги, и они по ALE попали в фиксаторы.
В остальном все просто. Так как адресный декодер работает только с командными сигналами, а не с сырыми S0-S2, он к моменту принятия решения еще не знает, адресуется внешнее устройство (т.е. 8-битное) или нет. Поэтому он исключительно по адресам формирует 2 предположения - EXT_MEM и EXT_IO (пока прибито в 1). Ну а ПС уже учитывает MEM_OP и IO_OP от 8288, т.е. если адрес является внешним для ИО, но не является таковым для памяти, а операция именно с памятью, то ничего не делаем. Результатом всех этих комбинаций является сигнал EXT_DEV, который и пишется с инверсией в STEER_RDY при принятии решения.
Мелочь, а важно. Если проц выполняет 8-битный цикл по старшему байту, нам тоже нужно переключить коммутаторы, что учтено в конечной формуле для SELH.

Разумеется, это все черновик. Но это то, что есть на данный момент, может кому будет интересно.

Как-то так. Извините, если невнятно изъясняюсь, комментарии в коде есть. Если чего - спрашивайте. :)


23 Dec 2014 01:29
Profile
Devil

Joined: 30 Nov 2013 11:08
Posts: 706
Location: WWW
Reply with quote
Post 
Тут интересную особенность обнаружил... Пока не разбирался детально, поэтому причина может быть в чем-то другом, но вроде все просто.

В моем компьютере есть возможность в отладочных целях вызывать NMI при обращении к заданному порту. При очередных разборках поставил команду HLT перед чтением из такого порта, но к моему великому удивлению, NMI все-равно возникает !

Я знал, что HLT не вешает процессор намертво, прерывания (как минимум) остаются, но каким боком процессор читает порт уже ПОСЛЕ выполнения HLT, я пока не понимаю. Ладно бы в "ковейерных" целях он просто прочитал бы код самой команды из памяти, но он ее реально выполняет - как минимум, выставляется адрес порта и формируется /IORC...


22 Feb 2015 23:33
Profile
God

Joined: 02 Jan 2006 02:28
Posts: 1390
Location: Abakan
Reply with quote
Post 
Для интел не подскажу, а для z80: NMI - не маскируемое прерывание, а HALT - ожидание любого прерывания. Т.е. описанная выше ситуация - норма. Возможно для интел тоже.


23 Feb 2015 02:08
Profile
Devil

Joined: 30 Nov 2013 11:08
Posts: 706
Location: WWW
Reply with quote
Post 
Да с обработкой прерывания вопросов нет, есть вопрос, откуда это прерывание взялось ???

У меня оно возникает при обращении к определенному порту, но это обращение в программе находится ПОСЛЕ команды HLT, т.е. до обращения (и, соответственно, прерывания) доходить не должно...

Хотя, пока это писал, вдруг сообразил, что у меня есть еще один источник (уже других) прерываний (таймер), так что, похоже, процессор просто проснулся от них и двинулся дальше к обращению к порту... Чуда не случилось :)


23 Feb 2015 02:23
Profile
God
User avatar

Joined: 13 Nov 2010 04:06
Posts: 1345
Reply with quote
Post 
Разве после обработки прерывания от таймера проц не должен снова вздремнуть на том же месте, где и был? Или ПП обработки прерывания от таймера завершается некорректно?


23 Feb 2015 11:40
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
VituZz wrote:
Разве после обработки прерывания от таймера проц не должен снова вздремнуть на том же месте, где и был?

Мне думается, что нет:
Quote:
В результате выполнения команды HLT микропроцессор переходит в состояние остановки. Из этого состояния его можно вывести сигналами на входах RESET, NMI, INTR. Если для возобновления работы микропроцессора используется прерывание, то сохраненное значение пары cs:ip указывает на команду, следующую за HLT.

По идее там нужен jmp обратно на hlt, чтобы процессор смог "вздремнуть на том же месте, где и был".

_________________
iLavr


23 Feb 2015 12:23
Profile
Devil

Joined: 30 Nov 2013 11:08
Posts: 706
Location: WWW
Reply with quote
Post 
Lavr wrote:
По идее там нужен jmp обратно на hlt, чтобы процессор смог "вздремнуть на том же месте, где и был".


Именно так. На всякий случай, убрал таймер и проверил - естественно, никаких NMI больше не возникло, так что обнаружение недокументированной особенности 8088 откладываем до следующего раза :)


23 Feb 2015 12:31
Profile
God

Joined: 02 Jan 2006 02:28
Posts: 1390
Location: Abakan
Reply with quote
Post 
Quote:
В результате выполнения команды HLT микропроцессор переходит в состояние остановки. Из этого состояния его можно вывести сигналами на входах RESET, NMI, INTR. Если для возобновления работы микропроцессора используется прерывание, то сохраненное значение пары cs:ip указывает на команду, следующую за HLT.


Собственно как я предположил - интел работает также как и z80.


23 Feb 2015 23:25
Profile
God
User avatar

Joined: 13 Nov 2010 04:06
Posts: 1345
Reply with quote
Post 
Lavr wrote:
Quote:
В результате выполнения команды HLT микропроцессор переходит в состояние остановки. Из этого состояния его можно вывести сигналами на входах RESET, NMI, INTR. Если для возобновления работы микропроцессора используется прерывание, то сохраненное значение пары cs:ip указывает на команду, следующую за HLT.

По идее там нужен jmp обратно на hlt, чтобы процессор смог "вздремнуть на том же месте, где и был".

Но разве после простого выполнения HLT cs:ip не указывает на команду, следующую за HLT? Мне кажется странным такое поведение, когда действие HLT может быть отменено прерыванием после его завершения.


24 Feb 2015 09:43
Profile
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Post 
VituZz wrote:
Но разве после простого выполнения HLT cs:ip не указывает на команду, следующую за HLT?

Ну я не знаю "сложного" выполнения HLT, он, собственно, ничем не отличается от других команд.
Любая команда, во время которой возникло прерывание, сначала заканчивается;
cs:ip, указывающий на команду, следующую за ней, запоминается в стеке, как
адрес возврата из прерывания.
HLT отличается только тем, что останавливает ЦПУ до прерывания или ресета, а в остальном -
он как и все команды.

VituZz wrote:
Мне кажется странным такое поведение, когда действие HLT может быть отменено прерыванием после его завершения.

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

_________________
iLavr


24 Feb 2015 10:04
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 182 posts ]  Go to page Previous  1 ... 8, 9, 10, 11, 12, 13  Next

Who is online

Users browsing this forum: No registered users and 7 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.