Z80-MBC2
Как все начиналось
Периодически захожу на сайт hackaday.io и вот однажды, больше года назад, наткнулся на этот девайс.
Заинтересовала схема, всего 4 микросхемы: z80, atmega32, sram на 128 кБ и 74HC00. И что интересно, к микроконтроллеру подключен только самый младший бит шины адреса.
Автор проекта проделал большую работу адаптировав код CP/M 2.2, CP/M 3.0 и др. И применил классный хак выполняя на z80 пошагово небольшую программу и выставляя опкоды и данные на шину данных. А адреса z80 выставляет сам.
В основном цикле заливки данных в память выполняются эти инструкции
Ранее у меня возникала идея управлять z80 с помощью микроконтроллера, хотелось попробовать эмулировать работу ZX-Spectrum. И еще было интересно сделать какую-нибудь плату на заказ. В общем все сложилось, скачал гербер файлы, загрузил их на JLCPCB.com, оплатил и стал ждать. Примерно через 2-3 недели приехали 5 платок - качество отличное!Код:LD(HL), n INC HL
Жизненные обстоятельства
Но тут вдруг откуда ни возьмись появился коронавирус. Меня перевели на удаленку. А жена стала нервничать, бегать по квартире и собирать вещи. Тогда мы жили в Москве на съемной квартире. Я не думал что это продлится долго, поэтому вещи собирать не стал. Но в какой-то день, может 21 марта, жене позвонила знакомая, сказала что Москву закрывают на карантин, едут БТРы. Супруга сразу же вызвала "Грузовичкофф" дав мне на сборы 2 часа. Ох, как же я на нее орал. Говорил что мне мало 2 часа, что уйду и сама разбирайся с грузчиками. У меня еще на почту должны были несколько посылок прийти. Но смирился, собрал что смог: одежду, рабочий ноут, а свои железяки оставил. Я все еще думал что это не надолго, и ничего страшного, буду продолжать платить за квартиру. Сами мы из Твери, у нас здесь родственники. Всю историю пересказывать не буду. Коронавирус не обошел нас стороной, похоронили дедушку жены, потом узнали что к нему заходили люди без нюха. А после похорон и сами переболели, сначала жена, она навещала дедушку в его последние часы, а потом и я.
Удаленку у меня не отменили по сих пор. За лето мы вполне привыкли жить в Твери. И когда я порывался съездить в Москву, забрать посылки с почты и кое-какие вещи из квартиры жена каждый раз меня отговаривала. Но осенью когда заболеваемость снова стала расти и перекрыла летние показатели мы решили что платить за квартиру где не живешь накладно, и не ясно когда вернемся. Надо съезжать. Приехали в Москву, стали собирать вещи. Никогда бы не подумал что у нас столько вещей. Никогда бы не подумал что столько вещей может влезть в однушку.
Собрались, переехали. Но вещи разгребали еще очень долго. Только недавно, может месяц назад я добрался до этой платки.
Мои доработки
Спаял, запустил. И заметил несколько странностей. Схема рабочая, но зачем там RS-триггер на WAIT сигнал? Я собирал контроллер клавиатуры и эмулятор контроллера дисковода для спектрума и там нормально работал элемент OR.
Микросхемы 74hc32 (4 OR элемента) у меня наличии не было. Так что я поступил по другому.
Разорвал обратную связь в RS-триггере и переключил вывод микроконтроллера на выход /IORQ микропроцессора.
Прошивка
Редактировать прошивку очень просто из среды разработки Arduino, заливается так же просто как и с платами arduino через COM порт.
Но в первый раз все же нужен программатор чтобы записать загрузчик.
Я уже несколько изменил прошивку, но родная прошивка все еще продолжает работать и на модифицированной плате.
В своей версии я заменил функции digitalWrite и digitalRead своими макросами, которые компилируются в одну инструкцию и работают значительно быстрее. Не применяйте без изменений эти макросы к другим микроконтроллерам, у них скорее всего другие маппинги.
Замерял время загрузки CP/M 3, с родной прошивкой: 12 секунд, а с моей 8.Код:#define SETBIT(PORT, BIT) (PORT |= (1<<(BIT))) #define CLRBIT(PORT, BIT) (PORT &= ~(1<<(BIT))) #define _WRITE(PORT, BIT, LEVEL) ((LEVEL) != LOW ? SETBIT(PORT, BIT) : CLRBIT(PORT, BIT)) #define digitalWrite(PIN, LEVEL) (PIN>=32 ? 0 : \ (PIN>=24 ? _WRITE(PORTA, (PIN)-24, LEVEL) : \ (PIN>=16 ? _WRITE(PORTC, (PIN)-16, LEVEL) : \ (PIN>=8 ? _WRITE(PORTD, (PIN)-8, LEVEL) : _WRITE(PORTB, PIN, LEVEL))))) #define GETBIT(PORT, BIT) (PORT & (1<<(BIT)) ? HIGH : LOW) #define digitalRead(PIN) (PIN>=32 ? 0 : \ (PIN>=24 ? GETBIT(PINA, (PIN)-24) : \ (PIN>=16 ? GETBIT(PINC, (PIN)-16) : \ (PIN>=8 ? GETBIT(PIND, (PIN)-8) : GETBIT(PINB, PIN)))))
Автор девайса зачем-то запрашивает шину (BUSREQ) в цикле ввода-вывода. Я удалил эти строки и все сломалось
Вообще-то сломался только режим 8 МГц (в моей прошивке, родная работает). Не знаю в чем дело, но при работе на частоте 8 МГц процессор периодически шлет в порты ввода-вывода какую-то дичь. Может это связано с синхронизацией, может еще с чем. Менял кварц, ставил на 12 МГц, все тоже самое. Добавлял задержку после получения запроса IORQ. Не помогает - сбоит подлец. На меньших частотах работает нормально. Добавил дополнительные тактовые частоты z80, 2.6 МГц и 2 МГц. Можно и больше в сторону уменьшения.
Добавил простой тест памяти, проверяет переключение банков, заливку данных в память.
Поставил RTC модуль на ds1307 вместо ds3231, время заработало из коробки. Даты создания и изменения файлов устанавливаются в CP/M 3.
В планах еще добавить поддержку таймера, чтобы z80 мог читать значения таймера, управлять его частотой и назначать прерывания.
Комментарии
Трекбэков
Всего трекбэков 0
Ссылка трекбэка: