Человек, признающий свою ошибку, когда он не прав – мудрец.
Человек, признающий свою ошибку, когда он прав – женат.

Меню навигации для мобильных

Последние сообщения

#1
Цифровая техника / Re: Запустить 8086
Последний ответ от Slabovik - Вчера в 23:35
Есть конечно некоторые сомнения. Чисто с эстетической точки зрения очень хочется, чтобы на модуле памяти не было вот этого дешифратора сигналов записи. 120 контактов (треть земляные - это надо, чтобы обеспечить скорость) тоже слегка смущают. Казалось бы, что выход в динамической RAM, но... это уполовинит лишь 20 контактов адреса, что на фоне общего количества будет незаметно, но нужно будет вводить схему мультиплексирования и регенерации, что очень и очень не хочется. Поэтому наверное можно оставить так. Разъём скорее всего типа PBD/PLD. Прямые штыри PLD отлично запаиваются на торец текстолита - расстояние между рядами как раз равно его толщине. Но вставлять будет трудно.

Ладно. Надо посмотреть, что можно сделать с процессором. Пока рассматриваем Minimum Mode, т.е. работу без сопроцессора. В Maximum Mode обвязка несколько сложнее из-за необходимости декодировать больше сигналов.

В очень далёком приближении процессор необходимо обвязать шинами: данных и адреса. Это потому что изначально она у него мультиплексированная и разные данные поставляются на одни и те же выводы, но в разное время.

8086_CPU_BUS.png

Здесь просто обзначены сигналы. Казалось бы, что регистры хранения адреса могли бы работать гейтами, но есть проблема - адресные данные ещё и в других местах используются для дешифрации. Так получается проще. Хотя можно пробовать обойтись дешифрацией во время активного ALE с запоминанием результата. Надо попробовать и такой вариант, но он мне не нравится т.к. ещё есть порты, которым уже самостоятельно придётся делать это.

А так получается, что во время ALE адрес отправляется в регистры и там хранится прям вот до следующего ALE - пользуйтесь.

Когда CPU обращается к памяти, в определённое время (см.ниже) открываются гейты АП5, выдающие на шину памяти адрес.

Вот циклограмма, описывающая две операции: чтение памяти процессором и запись.

8086_CPU&RAM_timings.png

Большая картинка, да. Но не полная, т.к. есть ещё порты (но они работают аналогично), прерывания, освобождение шины. Но это всё потом.

Тут видно, что циклы памяти по длительности равны одному такте процессора, но цикл процессора - это минимум его четыре такта (часто более). К памяти процессор обращается только один раз в цикл.
Всё начинается с выставления сигнала ALE, сопровождаемого выдачей адреса. Также уже сразу известны сигналы Mem/IO и DT/R (Data Translate/Read). Эти два сигнала единственные не меняющиеся в течение цикла.

В центре ALE, по восходящему такту процессора CT1 ловим признак обращения к памяти и вынужденно тащим его при помощи пары триггеров (хочу память и хочу ОЗУ) до начала такта T3, в самом начале которого при помощи схемы обеспечения приоритета (пока не показывал - потом) триггерами выставляем "Цикл CPU-RAM". А в такте T3 получаем данные от RAM, ну или пишем в неё.

Но я обещал схемы выборки ПЗУ. Она отличается от RAM. Во-первых, ПЗУ как правило медленнее. Если RAM обеспечивает 70нс на выдачу данных, по ПЗУ надо 120. Более быстрые ПЗУ есть, но их ещё надо искать.

8086_CPU_BUSRAM_Gates.png

Поскольку по ALE у нас уже известно, что ЦП хочет память, а адрес у нас уже есть, то уже можно начать читать ПЗУ не дожидаясь такта T3.
Адрес на ПЗУ подаётся прямо с процессора (регистров), не через гейт. И благодаря триггеру, первым в течение примерно 4/3 такта читается младшный байт. Затем, уже в такте T2 по подъёму CT1 триггер переключается, чем защёлкивается первый байт в ИР37, младший разряд адреса становится '1' и ПЗУ через какое-то время на выходе даёт уже второй байт. ИР33 в это время прозрачна дляданных, и обе микросхемы по сигналу DEN выдают байты на шину данных процессора. В конце такта T3 он их и заберёт.

Оба байта читаются всегда - это потому что сигналы S3, S4, по которым можно определить, какой сегмент запрашивает данные, ещё не выставлены на шину, а селекция делается позже сигналами OE регистров.

Схемы пока прикидочные, в них могут быть косяки и явные неоптимальности. Но вдруг кто-чего подскажетумное. Например меня интересует вопрос: при чтении процессором одного байта (младшего или старшего) что происходит со второй половиной шины? Вдруг туда можно подавать второй байт? Это упростило бы коммутацию - можно было бы забить на сигналы A0 и BHE в этом случае. Или так нельзя?
#2
Цифровая техника / Re: Запустить 8086
Последний ответ от Slabovik - 09 Май, 2024, 17:30
Думаю, надо пока закончить с генератором. Вот три варианта

Первый - делитель на три на основе JK-триггеров

8086_Gena_TB15_24MHz.png

Сигнал MASTB вспомогательный, по его восходящему фронту и до конца цикла формируется сигнал MADROE (Memory ADdR Output Enable) - строб, подаваемый на регистры, содержащие адрес, подаваемый на шину RAM

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

8086-MADROE_и_др.png

И самое главное - диаграмма работы

8086_Gena_TB15_24MHz_timings.png

Тут самое интересное.
CT1 - это такт процессора. Процессору данные нужны по спаду такта. Посему такая логическая разбивка времени.

ReadRAM и WriteRAM - это сигналы, формируемые диспетчером доступа, означают, что происходит с памятью.
RamOE - подаётся на чипы памяти для включения их выхода, активируется только в цикле чтения.
В цикле записи активируется другой сигнал RegOE, формируемый на основе MADROE - включает выходы регистров данных с байтами для записи в память.

По окончании цикла все сигналы с шины памяти снимаются на 20-25 нс, до фронта сигнала MADROE (MASTB) - это обеспечивает гарантию отсутствия перекрытия циклов. Оставшееся время порядка 100 нс вполне достаточно для нормальной работы памяти.

Сам модуль памяти планируется 64-разрядным. Это накладывает некоторые особенности

8086_Memory.png

Процессору 64 разряда не нужны, но нужны для видеоадаптера, чтобы за раз он мог забирать данные для 256-цветных 8 пикселей, иначе ему придётся обращаться к памяти намного чаще.

Слегка чуждый для памяти сигнал CT2 всё-же необходим. С его помощью формируется сигнал WR, который должен подниматься никак не позже окончания цикла и съёма данных и адреса. Данная схема это гарантирует, хотя есть скользкое место, заключающееся в том, что скорость работы ИД14 не бесконечно большая и есть опасения, что могут быть ложные "пички" уже после прихода CT. Хотя в принципе, порядка 15-20 нс на дешифрацию есть.
Как выход из ситуации можно предложить замеc сигнала CT2 с сигналами RAMA0 и BHE - это гарантирует отсутствие "пичек" при любых обстроятельствах, но скорее всего задержит WR. Возможно, что это не критично т.к. по даташиту длительность WR должна быть не менее 50нс, что даёт достаточно времени.

Такой сложный декодер для WR нужен потому что процессор может писать как байтами, так и словами, а память в сумме 64 бита. Поэтому надо выбрать конкретные чипы для записи, а не во все подряд.

А вот чтение с этого модуля всегда происходит на всю ширину. Для процессора далее из 8 регистров, предназначенных для гейта данных RAM-CPU, будут выбраны один или два, с которых чтение и произойдёт. Видеоадаптер же всегда читает 64 бита. DMA - пока вопрос открытый, но по умолчанию работает аналогично процессору, однако задел на 64 бита сделан в виде вывода WR64 - при его активации сигнал записи активируется на всех чипах, независимо от BHE, RAMA0~RAMA2

Память наверное лучше оформить отдельным модулем. Там где-то в районе 400 пинов.

Делитель на 3 можно сделать на D-триггерах (flip-flop) ТМ2. Сигналы получаются такие же.

8086_Gena_TM2_24MHz.png

Здесь нижняя ТМ2 уже относится к селектору, его посмотрим позже. Остальные сигналы такие же. Но не полностью показа формирователь стробов.

У делителей на 3 плохо то, что второй полупериод таковой процессора не получается сделать 50 нс, получается только 41. Понятия не имею, может ли это привести к проблемам. Возможно, нет. Однако унифицирование диаграмм позволит попробовать оба варианта генераторов.

Делитель на 5 даёт точные временнЫе соотношения 75 и 50нс (без учёта фронтов). Его можно сделать на трёх D-триггерах (ТМ2 или ТМ8). Один свободный триггер можно использовать для чего-нибудь ещё, ну или просто для разветвления сигнала, например CT2 - он много где потребуется.

8086_Gena_TM2_40MHz.png

Сигналы те же. Из-за чуть другого количества фронтов временнЫе характеристики слегка другие, но это не принципиально.

То же на ТМ8

8086_Gena_TM8_40MHz.png

На ТМ8 четвёртым триггером можно сформировать сигнал, аналогичный MADROE, но идущий на несколько нс раньше. К сожалению, сделать так, чтобы он начинался чуть ранее MADROE, а заканчивался так же, у меня не получается. Как уже говорил, наверное MADROE будет достаточно, но пока не сделаешь в железе - не узнаешь.

Диаграммы выглядят так

8086_Gena_TM8_40MHz_timings.png

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

Да, про BHE - Byte High Enable. Немного недоумеваю, почему ADR0 не называется BLE - Byte Low Enable. Ну да ладно.
Суть в том, что эти два сигнала ADR0 и BHE индицируют, с какими линиями данных сейчас работает процессор. Лучше всего это отображает табличка

8086_A0_BHE.png

При этом A0, как и BHE как бы не являются адресными сигналами памяти, а только указывают на конкретные байты (младший и/или старший) в слове. Но скорее всего название A0 оставлено для логической совместимости с 8-разрядной адресацией.

Да, даже в Minimum Mode процессор при обращении с данными указывает, какому сегменту (CS, DS, ES, SS) они принадлежат. После сигнала ALE, защёлкивающего адрес  в регистрах, на шину поставляются сигналы S3 и S4, указывающие на конкретный сегмент. Если их использовать, то появляется возможность хоть для каждого сегмента выделить свой собственный мегабайт памяти, что в сумме составит 4 мегабайта максивально возможной памяти, с которой может работать процессор, но на деле такое разбиение неудобно. Однако, если учесть то, что в адресном пространстве всегда есть ПЗУ и видеопамять, мне видится интересным сделать такое разбиение: сегменты CS и DS всегда обращаются к области ПЗУ, где оно перекрывает ОЗУ. А сегменты ES и SS всегда обращаются только к ОЗУ. Это позволит использовать перекрытую ПЗУ память для данных и стека.

Вот табличка

8086_S3_S4_Segment_selector.png

Интресно, ПЗУ сколько по объём надо? 64кБ поди хватит... Накидаем схемку выборки ПЗУ, она будет странная, если не хотим использовать 16-битное ПЗУ (такие тоже есть, ну или две микросхемы можно поставить, но это мне не нравится, одна лучше даже с точки зрения программирования).
#3
Цифровая техника / Re: Запустить 8086
Последний ответ от Slabovik - 06 Май, 2024, 13:34
Что-то трудно с этим генератором. Не, на 3 делит чётко. Но задержками играть получается только на TTL сериях, у которых переход от 1 к 0  и от 0 к 1 происходит за разное время. У серии 74AC разница весьма незначительна, поэтому растянуть второй полупериод так просто не получается.

8086_24MHz_to_8_JK_divider.png

Слегка изменил положение строба шины

8086_24MHz_to_8_JK_divider_timings.png

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

Но с другой стороны я смотрю даташит на его родной геренатор. Там делитель на 3, вот в чём прикол!

82c84A_internal.png
ЦитатаThe CLK output is a 33% duty cycle clock driver designed to
drive the 80C86, 80C88 processors directly.
И, как такое бывает?

#4
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от Slabovik - 06 Май, 2024, 11:39
Смотрю, озадачил я тебя   ::) Но увы, такова цена многозадачности. Мы ещё реентерабельность ни разу не рассматривали  ;) Впрочем, здесь она не нужна, я полагаю...
#5
Цифровая техника / Re: Запустить 8086
Последний ответ от Slabovik - 04 Май, 2024, 18:12
Продолжим. 40МГц тактирования позволяет удобно определить цикл шины памяти с 25-наносекундным дедтаймом. Он нужен изза того, что память не очень быстро снимает данные со своего выхода после цикла чтения, и если следующим будет идти цикл записи, там целых полтора-два десятка наносекунд может быть игра "перетяни шину". Чтобы этого не было, данные нужно выставлять слегка позже, чем начинается цикл.

Слегка изменил схему генератора

8086_Gena_TM8_40MHz.png

По-идее, можно обойтись без  четвёртого (D3/Q3) триггера, но его девать некуда - пусть стробирует гейт на выводы 'L' триггеров ИР22, которые забирают данные из памяти.

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

8086_Gena_TM8_40MHz_timings.png

Можно частоту делить на 3, взяв в качестве опорной 24МГц. Это проще. Но поделив на D-триггерах, получим ровно 1/3, получим 41нс  полутакта, а по документам надо 50.

Можно попробовать посчитать делитель на 3 на JK-триггерах. Это асинхронные триггеры и фронты будут за счёт задержек смещены, возможно, в нужную сторону. Посмотрим. Вот схема делителя

8086_Gena_TB15_24MHz.png

Пойду тайминги рисовать :)
#6
Цифровая техника / Re: Re: Орион-128 возрождение ...
Последний ответ от matrixplus - 04 Май, 2024, 13:15
запись на проект  плат SVGA  https://zx-pk.com/forum/viewtopic.php?f=7&t=23750

Орион-128 плата SVGA проект (улучшение изображения) http://rdk.regionsv.ru/orion128-super-42-turbo.htm

Принимаются заявки:  цена приблизительно озвучена на   https://zx-pk.com/forum/viewtopic.php?f=7&t=23750


информация http://rdk.regionsv.ru/orion128-super-42-turbo.htm
фото платы http://rdk.regionsv.ru/orion128svga/svga-015.jpg



в ней предусмотрены раьемы для платки расширения которая уже есть (в принципе разведена но ее бум делать позже)
#7
Фото, видео, аудио / Re: Коротко о погоде
Последний ответ от Slabovik - 03 Май, 2024, 22:13
Целый день пасмурно и прохладно, что даже до +4 еле-еле прогрело. Но с обеда зарядил дождь, который к вечеру превратился в мокрый снег, а потом в сильный мокрый снег. Ладно, что деревья ещё сильно лист не выпустили, даже вишни со сливами бутоны только-только приготовили, но тополя в городе поломало конечно... Полагаю, обойдётся  :)

TJM-2024-05-03.jpg
#8
Цифровая техника / Запустить 8086
Последний ответ от Slabovik - 03 Май, 2024, 16:43
Давно колупаюсь, когда время есть, но до практики так и не добрался ввиду объёмных затрат на хардварь. Тем не менее, давно хотел сделать какой-нибудь контроллер на базе этого проца. Да, есть NEC V40, но это уже перебор :)

Итак, имеем i8086 либо подобный. Задача-минимум - запустить. Задача-максимум - с прозрачным режимом работы с памятью и собственным видеоконтроллером, дающим картинку на телевизор либо LCD. 256 цветов достаточно. 16 - минималка.

8086 есть в нескольких вариантах. 8086 - базовый с тактовой 5МГц. 8086-2 имеет тактовую 8МГц. И есть редкий 8086-1 с тактовой 10МГц. Базовый купить полный кулёк не проблема, их много продают с разборок. 8086-2 надо поискать. 10-мегагерцовый вариант я не находил. А есть ещё вариант 80С86 - то же самое, только по КМОП-технологии.

Для начала надо разобраться с тактированием. Оно по-интеловски слегка странное - соотношение полупериодов должно быть 3/5 и 2/5

8086_timing_diagram.png

8086_timing_table.png

Тайминги версии 80C86 идентичны таймингам оригинала

Да, я видел варианты, где делают 2/3 и 1/3 и даже 3/4 и 1/4, но это с пониженными частотами, 4 а не 5, 6 а не 8...
Для 8-мегагерцового 1/3 при 125нс периоде получается только 41нс, а не 50, требуемых по даташиту (45+фронт)

3/5 и 2/5 можно чётко получить при 40-мегагерцовом осцилляторе

8086_40MHz_to_8_divider.png

Здесь подаваемая на процессор частота CT1, другие сигналы полезные для синхронизации узлов.

уфф, оказалось, у меня потерялась циклограмма. Потребуется время нарисовать по-новой... продолжу...
#9
Путешествия / Re: Из кабины машиниста
Последний ответ от Slabovik - 03 Май, 2024, 13:37
Снег идёт и поезд идёт. Зимняя Швейцария
St.Moritz - Chur with heavy snowfall
[свернуть]
#10
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от zenon - 02 Май, 2024, 21:53
Случайно удалил свой пост.
Предделитель для 1Гц будет такой:
72000000/7200 = 10000Гц
Предзагрузка 10000.
Прерывание по переполнению счётчика:

↓ спойлер ↓
void TIM13_init(void){
  RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // разрешить тактирование таймера
  TIM3->PSC = 7200 - 1; // предделитель
  TIM3->ARR = 10000 - 1; // предзагрузка
  TIM3->DIER |= TIM_DIER_UIE; // прерывания будем ловить по переполнению счетчика
  TIM3->CR1 |= TIM_CR1_CEN;
  NVIC_EnableIRQ(TIM3_IRQn);
}

void TIM3_IRQHandler (void) {
  if ((TIM3->SR & TIM_SR_UIF) == TIM_SR_UIF) { //  проверяем, что прерывание произошло по событию переполнения счетчика stm32f10x.h
    TIM3->SR &= ~TIM_SR_UIF; // флаг сбросить, иначе при выходе из обработчика прерываний мы тут же попадем туда снова
    LEDTOGGLE; // моргаем
  }
}
[свернуть]
---
Но, у нас ещё есть собственное прерывание на SPI: void SPI1_IRQHandler() :)