Pull to refresh

Микроша. Глава первая. Контроллер SD карты

Reading time 7 min
Views 17K


Многие помнят эту замечательную ПЭВМ. У меня такая появилась, когда мне было 11. Прошло 28 лет и сейчас я решил в порядке хобби сделать устройства расширения, которых мне так не хватало тогда.

Идея


В сети я видел несколько вариантов SD загрузчиков для подобных ПЭВМок, мне не нравилось наличие в них микроконтроллеров, хотелось сделать по «винтажной, теплой DIPовой» схемотехнике, именно поэтому я решил делать на отечественной логике «КР1533».

В качестве доп. ОЗУ я применил UT62256. Это единственная импортная микросхема в проекте. Конечно, можно было поставить КР537РУ10 или КР537РУ25А, но во-первых, их бы пришлось ставить не одну, а две (я планировал 4 кБ доп. ОЗУ), а во-вторых UT62256 у меня была, а КР537 не было, и заказывать не хотелось. Поэтому я позволил себе вольность поставить импорт, и тогда пришла идея использовать все 32кБ доп.ОЗУ, со страничным переключением.


Для ПЗУ выбрал КР573РФ5, как раз было две чистых.

Блок-схема


Посидев за чашкой чая, я нарисовал вот такую блок-схему.



Здесь микросхема ОЗУ, микросхема ПЗУ, и блок «ПОРТ». Блок «ПОРТ» есть параллельный интерфейс, имеющий 8 входов и 8 выходов. При записи по адресу EFFF, записываемый код выставляется на выходах, а при чтении из этого же адреса, прочитанное значение соответствует состоянию входов. Три из выходов и один из входов подключены к SD карте через преобразователь уровней.

ОЗУ представлено микросхемой UT62256 и имеет 32кБ памяти. Поскольку диапазон адресов E000-EFFE есть почти 4кБ (4095 байт), то получается 8 страниц, которые выбираются блоком «ПОРТ», битами 1,2 и 3. То есть запись по адресу EFFF приводит к установке страницы в соответствии с этими тремя битами. Также чтение из этого порта показывает какая страница сейчас выбрана (в этих же битах). Итого, мы имеем 32760 байт дополнительного ОЗУ (4095x8стр).

Микросхема ПЗУ есть КР573РФ5. Она подключена в адресное пространство F000-F7FF, и содержит код БСВВ (BIOS), задача этого кода инициализировать SD карту, загрузить с нее OS и передать ей управление.

Соответственно после включения ПЭВМ, набираем в Системном Мониторе GF000 и нажимаем ВК.

В дальнейшем есть идея доработать родное ПЗУ Системного Монитора, для автоматической загрузки OS с SD карты, и ПЭВМ выходит в стандартное приглашение Монитора если загрузка не удалась или была прервана, например, нажатием какой-то клавиши.
Об этом еще подумаю.

Схема


Примерно 2-3 часа за компьютером, и я нарисовал в EAGLE следующую схему.


Увеличить

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

Низкоуровневый разбор схемы…

...убрал под спойлер, думаю мало кому интересны эти дебри.
Посмотрим на ячейку И V3/1, к ней подключены линии A14 и A15 шины адреса, значит на выводе N3 появится логическая единица, когда эти оба сигнала адреса находятся в лог.1. Через инвертор V1/2 формируется сигнал с условным названием G, который приходит на дешифратор IC2. Входы этого дешифратора A и B, подключены к линиям A12 и A13 соответственно. Значит, получается, что дешифратор активируется от наличия единиц на A14 и A15, а его выходы показывают код на линиях A12 и A13. Нас интересует только один вариант — 1110,
то есть A15-1; A14-1; A13-1; A12-0. Такой сигнал получается на выходе дешифратора N2. Поскольку ячеек дешифратора две, то этот сигнал должен появляться на выводах 5 и 11, но из-за того, что каждая из ячеек имеет еще один вход С, то от состояния этого входа будет зависеть какая из ячеек будет активна. Вход 1С активирует выход 5, а вход 2С активирует выход 11. Эти входы спаралелены, но вход 1C прямой, а вход 2C инверсный, значит при наличии лог.1 на них активируется вывод 5, а при лог.0 — вывод 11.

Подытожим: При наличии на шине адреса кода Exxx и С=1, формируется сигнал «PORT», а при наличии на шине адреса кода Exxx и C=0, формируется сигнал «RAM».

Сигнал «C» образуется за счет функции логического И, из всех младших адресов (A0-A11). Когда на шине выставлен код xFFF, то С=1, а иначе С=0. Итого: сигнал «PORT» вызывается адресом EFFF, а сигнал «RAM» адресами E000-EFFE.

Сигнал «RAM» приходит на вход CS микросхемы IC3, это микросхема ОЗУ, и значит, что запись по адресам E000-EFFE приведет к записи в эту микросхему. Также чтение по адресам E000-EFFE приведет к чтению из этой микросхемы. При записи по адресу EFFF код будет записан в регистр IC4, и защелкнется на его выходах. Сигнал записи формируется из сигналов «PORT» и «WR» c помощью элементов V1/5, V1/6 и V3/4.

Чтение по адресу EFFF приведет к считыванию данных из буфера IC5, и код будет зависеть
от состояния входов B0-B7.

Микросхема ПЗУ включена в адресное пространство ПЭВМ с помощью штатного адресного дешифратора. Для этого из порта «Внутренний Интерфейс» берется сигнал CS3 и он подключен к линии CS микросхемы ПЗУ.

Сборка макета


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

Этот прямоугольник плотно вставлялся в слот «внутренний интерфейс» ПЭВМ, не болтался и не сдвигался. Далее я процарапал контактные площадки с задней и передней сторон. Получилось неплохо. Затем грубая расстановка микросхем и сверлежка отверстий. С лицевой стороны рассверлил крупным сверлом, чтобы выводы микросхем не контактировали с лицевой фольгой. С обратной стороны отцарапал периметр каждого контактного ряда и разделил на контактные площадки.

Следующим этапом поставил все микросхемы (и панельку) и пропаял с обратной стороны. Много времени отнял монтаж, который я вел тонким МГТФом. Вел проводки с обоих сторон, с лицевой подпаивал прямо к ножкам микросхем, с обратной к площадкам.



Когда процесс пайки был окончен, я решил уделить внимание преобразователю уровней сигналов. Дело в том, что SD карта работает с напряжением 3,3в., а микросхемы КР1533АП6 и КР1533ИР22 ТТЛ 5в. Поэтому пришлось сделать небольшую платку переходника, на котором уровни ограничивались стабилитронами.

Сигнал идущий от SD карты к контроллеру я просто подтянул к источнику 3,3в. резистором 10к. Как показала практика, этот сигнал в преобразовании не нуждается.



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

В качестве держателя карты использовал переходник microSD в SD.

В общем, проблем особых в сборке макета не возникло, хотя я боялся, что некоторые из микросхем могут быть неисправны.

Тесты макета


Первым делом я проверил работу ОЗУ, записал в область E000-EFFE с помощью директивы «F» Системного Монитора паттерны «AA», «55», «F0» и «0F» и проверил их с помощью директивы «D». Все оказалось в норме.

Далее директивой «M» начал записывать в адрес EFFF разные значения, и смотреть мультиметром изменения на ножках регистра КР1533ИР22, состояния соответствовали записаным кодам. Также при чтении из этого порта в коде содержалась выбранная страница, в соответствии с задуманным, и еще при замыкании MISO сигнала на землю в младшем бите оказывался 0, а при размыкании 1.

Даже было как-то подозрительно, что все микросхемы исправны и монтаж удался без ошибок.

БСВВ


Конечно никаких специальных инструментов для написания программ под КР580ВМ80А у меня не было. Пришлось писать программу в блокноте (notepad), затем переводить в коды вручную.
Создал файл в редакторе под DOS «HIEW» и начал заполнять кодами. Для основы взял свой проект под AVR, в котором имелась стандартная инициализация SD карты. Проект был старый, и в нем не использовалось никакой файловой системы, просто логгер.

Сначала написал низкоуровневую функцию программного интерфейса SPI, а потом высокоуровневую подпрограмму инициализации SD карты.

Получился примерно такой алгоритм…

...который убран под спойлер, думаю, он и так всем известен.
1. Взвести счетчик попыток (СП) на 90;
2. Выставить CS в лог.1 и отправить 10 раз FF;
3. Выставить CS в лог.0;
4. Отправить CMD0;
5. Если читается 01, тогда переход на 7;
6. Уменьшить СП. Если СП=0, то выход с ошибкой, иначе переход на 2;
7. Отправить CMD8;
8. Отправить ACMD41;
9. Если читается 00, тогда переход 11
10. Уменьшить СП. Если СП=0, то выход с ошибкой, иначе переход на 8;
11. Отправить CMD58.
12. Прочитать 2й байт ответа и записать по адресу EFFE.
13. Инициализация закончена.

В подпрограмме инициализации также читался регистр OCR карты, и 2й байт в нем записывался по адресу EFFE. Это было нужно для определения типа карты.

В случае SDSC — 80h, а в случае SDHC — C0h.

Если инициализация не проходила, то выводилось сообщение «ОШИБКА SD КАРТЫ» и затем происходил выход в Монитор без сброса.

Такую БСВВ я конвертировал в WAV и загружал в ПЭВМ через магнитофонный вход, затем отлаживал, правил исходник и снова загружал.

Мосты


Теперь у меня есть дополнительное ОЗУ, размером 32760 байт, разделенное на 8 страниц. Но как осуществлять переход между страницами? Как программа, выполняющаяся в первой странице, может вызвать подпрограмму, находящуюся в четвертой?

Для решения этой задачи я предусмотрел программные мосты. Мост — это небольшая область в ПЗУ, которая является посредником при передаче управления.

Например, выполняющийся код должен передать управление на страницу номер 3, в адрес E4B5. Тогда, выполняющийся код помещает младшие 12 бит (4B5) в регистровую пару HL процессора, а в старшие четыре бита помещает значение 3 — номер страницы. Теперь в регистровой паре HL записано значение 34B5. И код делает прыжок (JMP) в область ПЗУ, которая называется JMP-Bridge, это просто переход по фиксированному адресу в ПЗУ. Код в этой области извлекает номер страницы из старших битов регистровой пары HL и записывает их в регистр блока «ПОРТ» по адресу EFFF. Теперь в область E000-EFFE отображается третья страница ОЗУ. Программа JMP-Bridge обнуляет четыре старших бита регистровой пары HL и записывает туда «E». Теперь в регистровой паре HL находится уже физический адрес E4B5, и вот на него программа JMP-Bridge передает управление.

Таким образом передается управление между страницами.

Есть мост CALL-Bridge, он нужен для вызова подпрограммы с возвратом, и отличается от JMP-Bridge сохранением текущей страницы в стеке, и обратной процедуры для возврата.

Следующие два моста STA-Bridge и LDA-Bridge. Как следует из названий, первый записывает регистр Аккумулятор по логическому адресу (в HL), а второй читает в этот регистр данные из логического адреса.

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

Загрузка ОS


Если взглянуть на загрузочный сектор SD карты, то можно заметить, что по адресам 1AC-1D4 расположен текст «Disk error, press any key to restart».



Да, так странно как на фото он выглядит, потому-что кодировка символов Микроши не совпадает с ASCII.

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

Первым делом я поставил код 00 в позицию 1BA, и тем самым урезал запись. Теперь, должно выводиться просто «Disk error» и все. Остальные байты мои. Принцип простой, 6 байт сигнатура «MicrOS», и 4 байта адрес на SD карте начала файла с OS. В БСВВ я записал, после получения загрузочного сектора с SD карты, проверяется сигнатура, и если она есть, то взять 4 следующих байта и использовать в качестве адреса сектора для загрузки OS.

Если сигнатура отсутствует, то выводится сообщение «ОШИБКА ЗАГРУЗКИ OS» и происходит выход в Системный Монитор без сброса.

Итог


И вот, наконец-то все, работает. БСВВ написана, но мне еще требуется записать ее в ПЗУ.



А для этого мне нужно отредактировать все адреса вызовов подпрограмм и переходов, так-как в этом процессоре абсолютная адресация. А я писал БСВВ для области 6000-67FF, чтобы грузить в ОЗУ. Но теперь надо поменять все 6xxx на Fxxx.

Кроме того, я в «попаданецких» условиях. Программатор ПЗУ у меня есть, но он старенький, под LPT порт. И нет ни одного компьютера с LPT. Но есть пара Atmega32A, в PDIP40 корпусе и макетная плата. Возможно придется эмулировать LPT с помощью AVR. Но может все обойдется…

На этом, пока, все. Спасибо за внимание! Продолжение следует…

Update: Продолжение
Tags:
Hubs:
+80
Comments 63
Comments Comments 63

Articles